@jungjaehoon/mama-os 0.53.0 → 0.57.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.
- package/CHANGELOG.md +64 -0
- package/README.md +62 -259
- package/db/migrations/001-connector-event-index.sql +251 -0
- package/dist/agent/claude-native-tool-policy.d.ts +17 -0
- package/dist/agent/claude-native-tool-policy.d.ts.map +1 -0
- package/dist/agent/claude-native-tool-policy.js +88 -0
- package/dist/agent/claude-native-tool-policy.js.map +1 -0
- package/dist/api/attachment-actions.d.ts +16 -0
- package/dist/api/attachment-actions.d.ts.map +1 -0
- package/dist/api/attachment-actions.js +278 -0
- package/dist/api/attachment-actions.js.map +1 -0
- package/dist/api/auth-middleware.d.ts +15 -55
- package/dist/api/auth-middleware.d.ts.map +1 -1
- package/dist/api/auth-middleware.js +56 -233
- package/dist/api/auth-middleware.js.map +1 -1
- package/dist/api/cf-access.d.ts +6 -0
- package/dist/api/cf-access.d.ts.map +1 -0
- package/dist/api/cf-access.js +121 -0
- package/dist/api/cf-access.js.map +1 -0
- package/dist/api/file-delivery.d.ts +29 -0
- package/dist/api/file-delivery.d.ts.map +1 -0
- package/dist/api/file-delivery.js +90 -0
- package/dist/api/file-delivery.js.map +1 -0
- package/dist/api/owner-timezone-actions.d.ts +10 -0
- package/dist/api/owner-timezone-actions.d.ts.map +1 -0
- package/dist/api/owner-timezone-actions.js +73 -0
- package/dist/api/owner-timezone-actions.js.map +1 -0
- package/dist/api/report-actions.d.ts +22 -0
- package/dist/api/report-actions.d.ts.map +1 -0
- package/dist/api/report-actions.js +137 -0
- package/dist/api/report-actions.js.map +1 -0
- package/dist/api/report-handler.d.ts +15 -11
- package/dist/api/report-handler.d.ts.map +1 -1
- package/dist/api/report-handler.js +48 -120
- package/dist/api/report-handler.js.map +1 -1
- package/dist/api/report-persistence.d.ts +3 -3
- package/dist/api/report-persistence.d.ts.map +1 -1
- package/dist/api/report-persistence.js +35 -10
- package/dist/api/report-persistence.js.map +1 -1
- package/dist/api/report-source-actions.d.ts +11 -0
- package/dist/api/report-source-actions.d.ts.map +1 -0
- package/dist/api/report-source-actions.js +309 -0
- package/dist/api/report-source-actions.js.map +1 -0
- package/dist/api/security-events.d.ts +23 -0
- package/dist/api/security-events.d.ts.map +1 -0
- package/dist/api/security-events.js +71 -0
- package/dist/api/security-events.js.map +1 -0
- package/dist/api/source-actions.d.ts +9 -0
- package/dist/api/source-actions.d.ts.map +1 -0
- package/dist/api/source-actions.js +274 -0
- package/dist/api/source-actions.js.map +1 -0
- package/dist/api/stored-source-reader.d.ts +21 -0
- package/dist/api/stored-source-reader.d.ts.map +1 -0
- package/dist/api/stored-source-reader.js +269 -0
- package/dist/api/stored-source-reader.js.map +1 -0
- package/dist/api/viewer-data.d.ts +143 -0
- package/dist/api/viewer-data.d.ts.map +1 -0
- package/dist/api/viewer-data.js +518 -0
- package/dist/api/viewer-data.js.map +1 -0
- package/dist/api/viewer-request-security.d.ts +12 -0
- package/dist/api/viewer-request-security.d.ts.map +1 -0
- package/dist/api/viewer-request-security.js +217 -0
- package/dist/api/viewer-request-security.js.map +1 -0
- package/dist/api/viewer-server.d.ts +55 -0
- package/dist/api/viewer-server.d.ts.map +1 -0
- package/dist/api/viewer-server.js +933 -0
- package/dist/api/viewer-server.js.map +1 -0
- package/dist/api/wiki-actions.d.ts +20 -0
- package/dist/api/wiki-actions.d.ts.map +1 -0
- package/dist/api/wiki-actions.js +296 -0
- package/dist/api/wiki-actions.js.map +1 -0
- package/dist/api/work-actions.d.ts +109 -0
- package/dist/api/work-actions.d.ts.map +1 -0
- package/dist/api/work-actions.js +987 -0
- package/dist/api/work-actions.js.map +1 -0
- package/dist/cli/commands/daemon.d.ts +90 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -0
- package/dist/cli/commands/daemon.js +620 -0
- package/dist/cli/commands/daemon.js.map +1 -0
- package/dist/cli/commands/init.d.ts +7 -18
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +357 -273
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/replay.d.ts +12 -0
- package/dist/cli/commands/replay.d.ts.map +1 -0
- package/dist/cli/commands/replay.js +145 -0
- package/dist/cli/commands/replay.js.map +1 -0
- package/dist/cli/commands/secret.d.ts +6 -0
- package/dist/cli/commands/secret.d.ts.map +1 -0
- package/dist/cli/commands/secret.js +24 -0
- package/dist/cli/commands/secret.js.map +1 -0
- package/dist/cli/index.d.ts +0 -5
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +52 -95
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/launch-files.d.ts +10 -0
- package/dist/cli/launch-files.d.ts.map +1 -0
- package/dist/cli/launch-files.js +74 -0
- package/dist/cli/launch-files.js.map +1 -0
- package/dist/cli/prompt.d.ts +15 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +64 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/runtime/action-mcp-config.d.ts +15 -0
- package/dist/cli/runtime/action-mcp-config.d.ts.map +1 -0
- package/dist/cli/runtime/action-mcp-config.js +56 -0
- package/dist/cli/runtime/action-mcp-config.js.map +1 -0
- package/dist/cli/runtime/claude-caller-config.d.ts +4 -0
- package/dist/cli/runtime/claude-caller-config.d.ts.map +1 -0
- package/dist/cli/runtime/claude-caller-config.js +46 -0
- package/dist/cli/runtime/claude-caller-config.js.map +1 -0
- package/dist/cli/secrets.d.ts +9 -0
- package/dist/cli/secrets.d.ts.map +1 -0
- package/dist/cli/secrets.js +94 -0
- package/dist/cli/secrets.js.map +1 -0
- package/dist/connectors/calendar/index.d.ts +11 -10
- package/dist/connectors/calendar/index.d.ts.map +1 -1
- package/dist/connectors/calendar/index.js +171 -97
- package/dist/connectors/calendar/index.js.map +1 -1
- package/dist/connectors/chatwork/index.d.ts +31 -5
- package/dist/connectors/chatwork/index.d.ts.map +1 -1
- package/dist/connectors/chatwork/index.js +184 -20
- package/dist/connectors/chatwork/index.js.map +1 -1
- package/dist/connectors/claude-code/index.d.ts +0 -2
- package/dist/connectors/claude-code/index.d.ts.map +1 -1
- package/dist/connectors/claude-code/index.js +94 -70
- package/dist/connectors/claude-code/index.js.map +1 -1
- package/dist/connectors/config-loader.d.ts +1 -6
- package/dist/connectors/config-loader.d.ts.map +1 -1
- package/dist/connectors/config-loader.js +154 -134
- package/dist/connectors/config-loader.js.map +1 -1
- package/dist/connectors/discord/index.d.ts +8 -1
- package/dist/connectors/discord/index.d.ts.map +1 -1
- package/dist/connectors/discord/index.js +110 -32
- package/dist/connectors/discord/index.js.map +1 -1
- package/dist/connectors/drive/index.d.ts +10 -5
- package/dist/connectors/drive/index.d.ts.map +1 -1
- package/dist/connectors/drive/index.js +145 -88
- package/dist/connectors/drive/index.js.map +1 -1
- package/dist/connectors/framework/attachment-io.d.ts +5 -0
- package/dist/connectors/framework/attachment-io.d.ts.map +1 -0
- package/dist/connectors/framework/attachment-io.js +72 -0
- package/dist/connectors/framework/attachment-io.js.map +1 -0
- package/dist/connectors/framework/attachments.d.ts +32 -0
- package/dist/connectors/framework/attachments.d.ts.map +1 -0
- package/dist/connectors/framework/attachments.js +14 -0
- package/dist/connectors/framework/attachments.js.map +1 -0
- package/dist/connectors/framework/connector-event-types.d.ts +136 -0
- package/dist/connectors/framework/connector-event-types.d.ts.map +1 -0
- package/dist/connectors/framework/connector-event-types.js +3 -0
- package/dist/connectors/framework/connector-event-types.js.map +1 -0
- package/dist/connectors/framework/connector-state.d.ts +3 -0
- package/dist/connectors/framework/connector-state.d.ts.map +1 -0
- package/dist/connectors/framework/connector-state.js +47 -0
- package/dist/connectors/framework/connector-state.js.map +1 -0
- package/dist/connectors/framework/event-index.d.ts +28 -0
- package/dist/connectors/framework/event-index.d.ts.map +1 -0
- package/dist/connectors/framework/event-index.js +354 -0
- package/dist/connectors/framework/event-index.js.map +1 -0
- package/dist/connectors/framework/gws-utils.d.ts +3 -8
- package/dist/connectors/framework/gws-utils.d.ts.map +1 -1
- package/dist/connectors/framework/gws-utils.js +23 -30
- package/dist/connectors/framework/gws-utils.js.map +1 -1
- package/dist/connectors/framework/index.d.ts +4 -2
- package/dist/connectors/framework/index.d.ts.map +1 -1
- package/dist/connectors/framework/index.js +8 -6
- package/dist/connectors/framework/index.js.map +1 -1
- package/dist/connectors/framework/polling-scheduler.d.ts +71 -52
- package/dist/connectors/framework/polling-scheduler.d.ts.map +1 -1
- package/dist/connectors/framework/polling-scheduler.js +227 -168
- package/dist/connectors/framework/polling-scheduler.js.map +1 -1
- package/dist/connectors/framework/raw-query.d.ts +44 -0
- package/dist/connectors/framework/raw-query.d.ts.map +1 -0
- package/dist/connectors/framework/raw-query.js +584 -0
- package/dist/connectors/framework/raw-query.js.map +1 -0
- package/dist/connectors/framework/stored-index-read.d.ts +16 -0
- package/dist/connectors/framework/stored-index-read.d.ts.map +1 -0
- package/dist/connectors/framework/stored-index-read.js +66 -0
- package/dist/connectors/framework/stored-index-read.js.map +1 -0
- package/dist/connectors/framework/types.d.ts +17 -61
- package/dist/connectors/framework/types.d.ts.map +1 -1
- package/dist/connectors/framework/types.js +0 -4
- package/dist/connectors/framework/types.js.map +1 -1
- package/dist/connectors/gmail/index.d.ts +3 -2
- package/dist/connectors/gmail/index.d.ts.map +1 -1
- package/dist/connectors/gmail/index.js +74 -27
- package/dist/connectors/gmail/index.js.map +1 -1
- package/dist/connectors/ical/index.d.ts +29 -0
- package/dist/connectors/ical/index.d.ts.map +1 -0
- package/dist/connectors/ical/index.js +220 -0
- package/dist/connectors/ical/index.js.map +1 -0
- package/dist/connectors/ical/parser.d.ts +13 -0
- package/dist/connectors/ical/parser.d.ts.map +1 -0
- package/dist/connectors/ical/parser.js +117 -0
- package/dist/connectors/ical/parser.js.map +1 -0
- package/dist/connectors/imessage/index.d.ts +3 -1
- package/dist/connectors/imessage/index.d.ts.map +1 -1
- package/dist/connectors/imessage/index.js +31 -16
- package/dist/connectors/imessage/index.js.map +1 -1
- package/dist/connectors/index.d.ts +12 -5
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/index.js +67 -18
- package/dist/connectors/index.js.map +1 -1
- package/dist/connectors/kagemusha/index.d.ts +7 -19
- package/dist/connectors/kagemusha/index.d.ts.map +1 -1
- package/dist/connectors/kagemusha/index.js +123 -173
- package/dist/connectors/kagemusha/index.js.map +1 -1
- package/dist/connectors/notion/index.d.ts.map +1 -1
- package/dist/connectors/notion/index.js +79 -36
- package/dist/connectors/notion/index.js.map +1 -1
- package/dist/connectors/obsidian/index.d.ts +1 -1
- package/dist/connectors/obsidian/index.d.ts.map +1 -1
- package/dist/connectors/obsidian/index.js +59 -57
- package/dist/connectors/obsidian/index.js.map +1 -1
- package/dist/connectors/sheets/index.d.ts +8 -4
- package/dist/connectors/sheets/index.d.ts.map +1 -1
- package/dist/connectors/sheets/index.js +155 -143
- package/dist/connectors/sheets/index.js.map +1 -1
- package/dist/connectors/slack/index.d.ts +24 -5
- package/dist/connectors/slack/index.d.ts.map +1 -1
- package/dist/connectors/slack/index.js +177 -39
- package/dist/connectors/slack/index.js.map +1 -1
- package/dist/connectors/telegram/index.d.ts +9 -2
- package/dist/connectors/telegram/index.d.ts.map +1 -1
- package/dist/connectors/telegram/index.js +119 -70
- package/dist/connectors/telegram/index.js.map +1 -1
- package/dist/connectors/trello/index.d.ts +10 -3
- package/dist/connectors/trello/index.d.ts.map +1 -1
- package/dist/connectors/trello/index.js +88 -39
- package/dist/connectors/trello/index.js.map +1 -1
- package/dist/gateways/base-gateway.d.ts +9 -33
- package/dist/gateways/base-gateway.d.ts.map +1 -1
- package/dist/gateways/base-gateway.js +7 -28
- package/dist/gateways/base-gateway.js.map +1 -1
- package/dist/gateways/conversation-record.d.ts +52 -0
- package/dist/gateways/conversation-record.d.ts.map +1 -0
- package/dist/gateways/conversation-record.js +220 -0
- package/dist/gateways/conversation-record.js.map +1 -0
- package/dist/gateways/discord.d.ts +33 -135
- package/dist/gateways/discord.d.ts.map +1 -1
- package/dist/gateways/discord.js +258 -778
- package/dist/gateways/discord.js.map +1 -1
- package/dist/gateways/session-store.d.ts +28 -9
- package/dist/gateways/session-store.d.ts.map +1 -1
- package/dist/gateways/session-store.js +192 -60
- package/dist/gateways/session-store.js.map +1 -1
- package/dist/gateways/slack.d.ts +35 -105
- package/dist/gateways/slack.d.ts.map +1 -1
- package/dist/gateways/slack.js +282 -440
- package/dist/gateways/slack.js.map +1 -1
- package/dist/gateways/telegram-attachments.d.ts +32 -0
- package/dist/gateways/telegram-attachments.d.ts.map +1 -0
- package/dist/gateways/telegram-attachments.js +113 -0
- package/dist/gateways/telegram-attachments.js.map +1 -0
- package/dist/gateways/telegram-errors.d.ts +3 -0
- package/dist/gateways/telegram-errors.d.ts.map +1 -0
- package/dist/gateways/telegram-errors.js +10 -0
- package/dist/gateways/telegram-errors.js.map +1 -0
- package/dist/gateways/telegram-format.d.ts.map +1 -1
- package/dist/gateways/telegram-format.js +9 -1
- package/dist/gateways/telegram-format.js.map +1 -1
- package/dist/gateways/telegram-message-ledger.d.ts +31 -25
- package/dist/gateways/telegram-message-ledger.d.ts.map +1 -1
- package/dist/gateways/telegram-message-ledger.js +122 -146
- package/dist/gateways/telegram-message-ledger.js.map +1 -1
- package/dist/gateways/telegram-response-presenter.d.ts +3 -1
- package/dist/gateways/telegram-response-presenter.d.ts.map +1 -1
- package/dist/gateways/telegram-response-presenter.js +14 -0
- package/dist/gateways/telegram-response-presenter.js.map +1 -1
- package/dist/gateways/telegram-text-entities.d.ts +2 -3
- package/dist/gateways/telegram-text-entities.d.ts.map +1 -1
- package/dist/gateways/telegram-text-entities.js +4 -5
- package/dist/gateways/telegram-text-entities.js.map +1 -1
- package/dist/gateways/telegram.d.ts +39 -101
- package/dist/gateways/telegram.d.ts.map +1 -1
- package/dist/gateways/telegram.js +406 -919
- package/dist/gateways/telegram.js.map +1 -1
- package/dist/gateways/turn-contract.d.ts +27 -87
- package/dist/gateways/turn-contract.d.ts.map +1 -1
- package/dist/gateways/types.d.ts +14 -299
- package/dist/gateways/types.d.ts.map +1 -1
- package/dist/gateways/types.js +0 -3
- package/dist/gateways/types.js.map +1 -1
- package/dist/index.d.ts +1 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -23
- package/dist/index.js.map +1 -1
- package/dist/operator/board-read-views.d.ts +8 -10
- package/dist/operator/board-read-views.d.ts.map +1 -1
- package/dist/operator/board-read-views.js +4 -13
- package/dist/operator/board-read-views.js.map +1 -1
- package/dist/operator/board-slot-instructions.d.ts +10 -11
- package/dist/operator/board-slot-instructions.d.ts.map +1 -1
- package/dist/operator/board-slot-instructions.js +22 -21
- package/dist/operator/board-slot-instructions.js.map +1 -1
- package/dist/replay/import-manifest.d.ts +21 -0
- package/dist/replay/import-manifest.d.ts.map +1 -0
- package/dist/replay/import-manifest.js +157 -0
- package/dist/replay/import-manifest.js.map +1 -0
- package/dist/replay/jev-client.d.ts +35 -0
- package/dist/replay/jev-client.d.ts.map +1 -0
- package/dist/replay/jev-client.js +141 -0
- package/dist/replay/jev-client.js.map +1 -0
- package/dist/replay/kagemusha-import.d.ts +35 -0
- package/dist/replay/kagemusha-import.d.ts.map +1 -0
- package/dist/replay/kagemusha-import.js +543 -0
- package/dist/replay/kagemusha-import.js.map +1 -0
- package/dist/replay/replay-cursor.d.ts +31 -0
- package/dist/replay/replay-cursor.d.ts.map +1 -0
- package/dist/replay/replay-cursor.js +189 -0
- package/dist/replay/replay-cursor.js.map +1 -0
- package/dist/replay/replay-feeder.d.ts +55 -0
- package/dist/replay/replay-feeder.d.ts.map +1 -0
- package/dist/replay/replay-feeder.js +214 -0
- package/dist/replay/replay-feeder.js.map +1 -0
- package/dist/replay/replay-ledger.d.ts +32 -0
- package/dist/replay/replay-ledger.d.ts.map +1 -0
- package/dist/replay/replay-ledger.js +91 -0
- package/dist/replay/replay-ledger.js.map +1 -0
- package/dist/replay/replay-source-catalog.d.ts +66 -0
- package/dist/replay/replay-source-catalog.d.ts.map +1 -0
- package/dist/replay/replay-source-catalog.js +332 -0
- package/dist/replay/replay-source-catalog.js.map +1 -0
- package/dist/replay/trello-import.d.ts +33 -0
- package/dist/replay/trello-import.d.ts.map +1 -0
- package/dist/replay/trello-import.js +204 -0
- package/dist/replay/trello-import.js.map +1 -0
- package/dist/replay/window-queue.d.ts +116 -0
- package/dist/replay/window-queue.d.ts.map +1 -0
- package/dist/replay/window-queue.js +497 -0
- package/dist/replay/window-queue.js.map +1 -0
- package/dist/runtime/action-mcp-server.d.ts +30 -0
- package/dist/runtime/action-mcp-server.d.ts.map +1 -0
- package/dist/runtime/action-mcp-server.js +179 -0
- package/dist/runtime/action-mcp-server.js.map +1 -0
- package/dist/runtime/action-surface.d.ts +47 -0
- package/dist/runtime/action-surface.d.ts.map +1 -0
- package/dist/runtime/action-surface.js +182 -0
- package/dist/runtime/action-surface.js.map +1 -0
- package/dist/runtime/backend-security.d.ts +7 -0
- package/dist/runtime/backend-security.d.ts.map +1 -0
- package/dist/runtime/backend-security.js +28 -0
- package/dist/runtime/backend-security.js.map +1 -0
- package/dist/runtime/claude-caller-hook.d.ts +20 -0
- package/dist/runtime/claude-caller-hook.d.ts.map +1 -0
- package/dist/runtime/claude-caller-hook.js +41 -0
- package/dist/runtime/claude-caller-hook.js.map +1 -0
- package/dist/runtime/config.d.ts +84 -0
- package/dist/runtime/config.d.ts.map +1 -0
- package/dist/runtime/config.js +361 -0
- package/dist/runtime/config.js.map +1 -0
- package/dist/runtime/connectors.d.ts +41 -0
- package/dist/runtime/connectors.d.ts.map +1 -0
- package/dist/runtime/connectors.js +187 -0
- package/dist/runtime/connectors.js.map +1 -0
- package/dist/runtime/core-db.d.ts +8 -0
- package/dist/runtime/core-db.d.ts.map +1 -0
- package/dist/runtime/core-db.js +19 -0
- package/dist/runtime/core-db.js.map +1 -0
- package/dist/runtime/model-cache.d.ts +9 -0
- package/dist/runtime/model-cache.d.ts.map +1 -0
- package/dist/runtime/model-cache.js +22 -0
- package/dist/runtime/model-cache.js.map +1 -0
- package/dist/runtime/native-session.d.ts +80 -0
- package/dist/runtime/native-session.d.ts.map +1 -0
- package/dist/runtime/native-session.js +284 -0
- package/dist/runtime/native-session.js.map +1 -0
- package/dist/runtime/owner-policy.d.ts +10 -0
- package/dist/runtime/owner-policy.d.ts.map +1 -0
- package/dist/runtime/owner-policy.js +35 -0
- package/dist/runtime/owner-policy.js.map +1 -0
- package/dist/runtime/owner-runtime.d.ts +78 -0
- package/dist/runtime/owner-runtime.d.ts.map +1 -0
- package/dist/runtime/owner-runtime.js +255 -0
- package/dist/runtime/owner-runtime.js.map +1 -0
- package/dist/runtime/owner-system-prompt.d.ts +17 -0
- package/dist/runtime/owner-system-prompt.d.ts.map +1 -0
- package/dist/runtime/owner-system-prompt.js +122 -0
- package/dist/runtime/owner-system-prompt.js.map +1 -0
- package/dist/runtime/recent-owner-exchanges.d.ts +10 -0
- package/dist/runtime/recent-owner-exchanges.d.ts.map +1 -0
- package/dist/runtime/recent-owner-exchanges.js +53 -0
- package/dist/runtime/recent-owner-exchanges.js.map +1 -0
- package/dist/runtime/report-prompts.d.ts +14 -0
- package/dist/runtime/report-prompts.d.ts.map +1 -0
- package/dist/runtime/report-prompts.js +69 -0
- package/dist/runtime/report-prompts.js.map +1 -0
- package/dist/runtime/report-scheduler.d.ts +24 -0
- package/dist/runtime/report-scheduler.d.ts.map +1 -0
- package/dist/runtime/report-scheduler.js +97 -0
- package/dist/runtime/report-scheduler.js.map +1 -0
- package/dist/runtime/session-credential.d.ts +5 -0
- package/dist/runtime/session-credential.d.ts.map +1 -0
- package/dist/runtime/session-credential.js +19 -0
- package/dist/runtime/session-credential.js.map +1 -0
- package/dist/runtime/stimulus-delivery.d.ts +85 -0
- package/dist/runtime/stimulus-delivery.d.ts.map +1 -0
- package/dist/runtime/stimulus-delivery.js +590 -0
- package/dist/runtime/stimulus-delivery.js.map +1 -0
- package/dist/runtime/timezone.d.ts +13 -0
- package/dist/runtime/timezone.d.ts.map +1 -0
- package/dist/runtime/timezone.js +119 -0
- package/dist/runtime/timezone.js.map +1 -0
- package/dist/sqlite.d.ts +7 -32
- package/dist/sqlite.d.ts.map +1 -1
- package/dist/sqlite.js +10 -48
- package/dist/sqlite.js.map +1 -1
- package/dist/storage/migrations/raw-item-revisions.d.ts +6 -0
- package/dist/storage/migrations/raw-item-revisions.d.ts.map +1 -0
- package/dist/storage/migrations/raw-item-revisions.js +109 -0
- package/dist/storage/migrations/raw-item-revisions.js.map +1 -0
- package/dist/storage/migrations-source.d.ts +5 -0
- package/dist/storage/migrations-source.d.ts.map +1 -0
- package/dist/storage/migrations-source.js +24 -0
- package/dist/storage/migrations-source.js.map +1 -0
- package/dist/storage/source-archive.d.ts +123 -0
- package/dist/storage/source-archive.d.ts.map +1 -0
- package/dist/storage/source-archive.js +595 -0
- package/dist/storage/source-archive.js.map +1 -0
- package/dist/storage-sqlite.d.ts +59 -0
- package/dist/storage-sqlite.d.ts.map +1 -0
- package/dist/storage-sqlite.js +75 -0
- package/dist/storage-sqlite.js.map +1 -0
- package/dist/utils/untrusted-content.d.ts +5 -35
- package/dist/utils/untrusted-content.d.ts.map +1 -1
- package/dist/utils/untrusted-content.js +16 -75
- package/dist/utils/untrusted-content.js.map +1 -1
- package/dist/wiki/obsidian-writer.d.ts +4 -2
- package/dist/wiki/obsidian-writer.d.ts.map +1 -1
- package/dist/wiki/obsidian-writer.js +85 -4
- package/dist/wiki/obsidian-writer.js.map +1 -1
- package/dist/wiki/path-safety.d.ts +2 -0
- package/dist/wiki/path-safety.d.ts.map +1 -1
- package/dist/wiki/path-safety.js +11 -3
- package/dist/wiki/path-safety.js.map +1 -1
- package/dist/wiki/wiki-edits.d.ts +17 -0
- package/dist/wiki/wiki-edits.d.ts.map +1 -0
- package/dist/wiki/wiki-edits.js +75 -0
- package/dist/wiki/wiki-edits.js.map +1 -0
- package/dist/wiki/wiki-read.d.ts +20 -11
- package/dist/wiki/wiki-read.d.ts.map +1 -1
- package/dist/wiki/wiki-read.js +87 -89
- package/dist/wiki/wiki-read.js.map +1 -1
- package/dist/wiki-artifacts/types.d.ts +1 -1
- package/dist/wiki-artifacts/types.d.ts.map +1 -1
- package/dist/wiki-artifacts/wiki-publish-adapter.d.ts.map +1 -1
- package/dist/wiki-artifacts/wiki-publish-adapter.js +13 -9
- package/dist/wiki-artifacts/wiki-publish-adapter.js.map +1 -1
- package/package.json +11 -41
- package/public/viewer/js/modules/graph.js +111 -41
- package/public/viewer/js/modules/memory.js +4 -31
- package/public/viewer/js/modules/wiki.js +0 -37
- package/public/viewer/js/utils/api.js +4 -50
- package/public/viewer/log-viewer.html +46 -0
- package/public/viewer/operator/operator.css +1 -1
- package/public/viewer/operator/operator.js +10835 -8211
- package/public/viewer/src/modules/graph.ts +133 -41
- package/public/viewer/src/modules/memory.ts +4 -31
- package/public/viewer/src/modules/wiki.ts +0 -42
- package/public/viewer/src/types/global.d.ts +1 -1
- package/public/viewer/src/utils/api.ts +7 -83
- package/public/viewer/viewer.html +7 -96
- package/dist/agent/agent-loop.d.ts +0 -289
- package/dist/agent/agent-loop.d.ts.map +0 -1
- package/dist/agent/agent-loop.js +0 -2842
- package/dist/agent/agent-loop.js.map +0 -1
- package/dist/agent/attachment-text-extractor.d.ts +0 -2
- package/dist/agent/attachment-text-extractor.d.ts.map +0 -1
- package/dist/agent/attachment-text-extractor.js +0 -128
- package/dist/agent/attachment-text-extractor.js.map +0 -1
- package/dist/agent/backend-model-policy.d.ts +0 -58
- package/dist/agent/backend-model-policy.d.ts.map +0 -1
- package/dist/agent/backend-model-policy.js +0 -167
- package/dist/agent/backend-model-policy.js.map +0 -1
- package/dist/agent/backend-model-runner-factory.d.ts +0 -27
- package/dist/agent/backend-model-runner-factory.d.ts.map +0 -1
- package/dist/agent/backend-model-runner-factory.js +0 -88
- package/dist/agent/backend-model-runner-factory.js.map +0 -1
- package/dist/agent/claude-cli-wrapper.d.ts +0 -144
- package/dist/agent/claude-cli-wrapper.d.ts.map +0 -1
- package/dist/agent/claude-cli-wrapper.js +0 -382
- package/dist/agent/claude-cli-wrapper.js.map +0 -1
- package/dist/agent/cli-arg-redaction.d.ts +0 -2
- package/dist/agent/cli-arg-redaction.d.ts.map +0 -1
- package/dist/agent/cli-arg-redaction.js +0 -18
- package/dist/agent/cli-arg-redaction.js.map +0 -1
- package/dist/agent/cline-cli-adapter.d.ts +0 -126
- package/dist/agent/cline-cli-adapter.d.ts.map +0 -1
- package/dist/agent/cline-cli-adapter.js +0 -1042
- package/dist/agent/cline-cli-adapter.js.map +0 -1
- package/dist/agent/cline-native-tool-policy.d.ts +0 -9
- package/dist/agent/cline-native-tool-policy.d.ts.map +0 -1
- package/dist/agent/cline-native-tool-policy.js +0 -61
- package/dist/agent/cline-native-tool-policy.js.map +0 -1
- package/dist/agent/code-act/completed-terminal-result.d.ts +0 -5
- package/dist/agent/code-act/completed-terminal-result.d.ts.map +0 -1
- package/dist/agent/code-act/completed-terminal-result.js +0 -83
- package/dist/agent/code-act/completed-terminal-result.js.map +0 -1
- package/dist/agent/code-act/constants.d.ts +0 -11
- package/dist/agent/code-act/constants.d.ts.map +0 -1
- package/dist/agent/code-act/constants.js +0 -64
- package/dist/agent/code-act/constants.js.map +0 -1
- package/dist/agent/code-act/host-bridge.d.ts +0 -50
- package/dist/agent/code-act/host-bridge.d.ts.map +0 -1
- package/dist/agent/code-act/host-bridge.js +0 -1405
- package/dist/agent/code-act/host-bridge.js.map +0 -1
- package/dist/agent/code-act/index.d.ts +0 -10
- package/dist/agent/code-act/index.d.ts.map +0 -1
- package/dist/agent/code-act/index.js +0 -22
- package/dist/agent/code-act/index.js.map +0 -1
- package/dist/agent/code-act/run-context-registry.d.ts +0 -36
- package/dist/agent/code-act/run-context-registry.d.ts.map +0 -1
- package/dist/agent/code-act/run-context-registry.js +0 -143
- package/dist/agent/code-act/run-context-registry.js.map +0 -1
- package/dist/agent/code-act/sandbox.d.ts +0 -25
- package/dist/agent/code-act/sandbox.d.ts.map +0 -1
- package/dist/agent/code-act/sandbox.js +0 -494
- package/dist/agent/code-act/sandbox.js.map +0 -1
- package/dist/agent/code-act/tool-catalog.d.ts +0 -30
- package/dist/agent/code-act/tool-catalog.d.ts.map +0 -1
- package/dist/agent/code-act/tool-catalog.js +0 -185
- package/dist/agent/code-act/tool-catalog.js.map +0 -1
- package/dist/agent/code-act/tool-policy.d.ts +0 -51
- package/dist/agent/code-act/tool-policy.d.ts.map +0 -1
- package/dist/agent/code-act/tool-policy.js +0 -160
- package/dist/agent/code-act/tool-policy.js.map +0 -1
- package/dist/agent/code-act/type-definition-generator.d.ts +0 -19
- package/dist/agent/code-act/type-definition-generator.d.ts.map +0 -1
- package/dist/agent/code-act/type-definition-generator.js +0 -73
- package/dist/agent/code-act/type-definition-generator.js.map +0 -1
- package/dist/agent/code-act/types.d.ts +0 -57
- package/dist/agent/code-act/types.d.ts.map +0 -1
- package/dist/agent/code-act/types.js +0 -14
- package/dist/agent/code-act/types.js.map +0 -1
- package/dist/agent/codex-app-server-process.d.ts +0 -257
- package/dist/agent/codex-app-server-process.d.ts.map +0 -1
- package/dist/agent/codex-app-server-process.js +0 -2084
- package/dist/agent/codex-app-server-process.js.map +0 -1
- package/dist/agent/codex-auth.d.ts +0 -2
- package/dist/agent/codex-auth.d.ts.map +0 -1
- package/dist/agent/codex-auth.js +0 -17
- package/dist/agent/codex-auth.js.map +0 -1
- package/dist/agent/codex-auxiliary-tools.d.ts +0 -17
- package/dist/agent/codex-auxiliary-tools.d.ts.map +0 -1
- package/dist/agent/codex-auxiliary-tools.js +0 -267
- package/dist/agent/codex-auxiliary-tools.js.map +0 -1
- package/dist/agent/codex-home.d.ts +0 -13
- package/dist/agent/codex-home.d.ts.map +0 -1
- package/dist/agent/codex-home.js +0 -644
- package/dist/agent/codex-home.js.map +0 -1
- package/dist/agent/codex-thread-registry.d.ts +0 -63
- package/dist/agent/codex-thread-registry.d.ts.map +0 -1
- package/dist/agent/codex-thread-registry.js +0 -433
- package/dist/agent/codex-thread-registry.js.map +0 -1
- package/dist/agent/content-dedup.d.ts +0 -86
- package/dist/agent/content-dedup.d.ts.map +0 -1
- package/dist/agent/content-dedup.js +0 -114
- package/dist/agent/content-dedup.js.map +0 -1
- package/dist/agent/context-compile-contract.d.ts +0 -5
- package/dist/agent/context-compile-contract.d.ts.map +0 -1
- package/dist/agent/context-compile-contract.js +0 -8
- package/dist/agent/context-compile-contract.js.map +0 -1
- package/dist/agent/context-compile-service.d.ts +0 -60
- package/dist/agent/context-compile-service.d.ts.map +0 -1
- package/dist/agent/context-compile-service.js +0 -481
- package/dist/agent/context-compile-service.js.map +0 -1
- package/dist/agent/context-prompt-builder.d.ts +0 -24
- package/dist/agent/context-prompt-builder.d.ts.map +0 -1
- package/dist/agent/context-prompt-builder.js +0 -61
- package/dist/agent/context-prompt-builder.js.map +0 -1
- package/dist/agent/contract-extractor.d.ts +0 -124
- package/dist/agent/contract-extractor.d.ts.map +0 -1
- package/dist/agent/contract-extractor.js +0 -465
- package/dist/agent/contract-extractor.js.map +0 -1
- package/dist/agent/drive-tools.d.ts +0 -83
- package/dist/agent/drive-tools.d.ts.map +0 -1
- package/dist/agent/drive-tools.js +0 -338
- package/dist/agent/drive-tools.js.map +0 -1
- package/dist/agent/gateway-tool-catalog.d.ts +0 -14
- package/dist/agent/gateway-tool-catalog.d.ts.map +0 -1
- package/dist/agent/gateway-tool-catalog.js +0 -41
- package/dist/agent/gateway-tool-catalog.js.map +0 -1
- package/dist/agent/gateway-tool-executor.d.ts +0 -353
- package/dist/agent/gateway-tool-executor.d.ts.map +0 -1
- package/dist/agent/gateway-tool-executor.js +0 -5448
- package/dist/agent/gateway-tool-executor.js.map +0 -1
- package/dist/agent/gateway-tools.md +0 -166
- package/dist/agent/image-translation-tools.d.ts +0 -48
- package/dist/agent/image-translation-tools.d.ts.map +0 -1
- package/dist/agent/image-translation-tools.js +0 -274
- package/dist/agent/image-translation-tools.js.map +0 -1
- package/dist/agent/index.d.ts +0 -13
- package/dist/agent/index.d.ts.map +0 -1
- package/dist/agent/index.js +0 -18
- package/dist/agent/index.js.map +0 -1
- package/dist/agent/mama-tool-handlers.d.ts +0 -11
- package/dist/agent/mama-tool-handlers.d.ts.map +0 -1
- package/dist/agent/mama-tool-handlers.js +0 -220
- package/dist/agent/mama-tool-handlers.js.map +0 -1
- package/dist/agent/managed-agent-runtime-sync.d.ts +0 -36
- package/dist/agent/managed-agent-runtime-sync.d.ts.map +0 -1
- package/dist/agent/managed-agent-runtime-sync.js +0 -245
- package/dist/agent/managed-agent-runtime-sync.js.map +0 -1
- package/dist/agent/managed-agent-validation.d.ts +0 -4
- package/dist/agent/managed-agent-validation.d.ts.map +0 -1
- package/dist/agent/managed-agent-validation.js +0 -85
- package/dist/agent/managed-agent-validation.js.map +0 -1
- package/dist/agent/model-runner.d.ts +0 -180
- package/dist/agent/model-runner.d.ts.map +0 -1
- package/dist/agent/model-runner.js +0 -54
- package/dist/agent/model-runner.js.map +0 -1
- package/dist/agent/native-effect-observer.d.ts +0 -20
- package/dist/agent/native-effect-observer.d.ts.map +0 -1
- package/dist/agent/native-effect-observer.js +0 -86
- package/dist/agent/native-effect-observer.js.map +0 -1
- package/dist/agent/obsidian-cli-args.d.ts +0 -14
- package/dist/agent/obsidian-cli-args.d.ts.map +0 -1
- package/dist/agent/obsidian-cli-args.js +0 -57
- package/dist/agent/obsidian-cli-args.js.map +0 -1
- package/dist/agent/os-agent-capabilities.md +0 -367
- package/dist/agent/persistent-cli-adapter.d.ts +0 -173
- package/dist/agent/persistent-cli-adapter.d.ts.map +0 -1
- package/dist/agent/persistent-cli-adapter.js +0 -467
- package/dist/agent/persistent-cli-adapter.js.map +0 -1
- package/dist/agent/persistent-cli-process.d.ts +0 -392
- package/dist/agent/persistent-cli-process.d.ts.map +0 -1
- package/dist/agent/persistent-cli-process.js +0 -1568
- package/dist/agent/persistent-cli-process.js.map +0 -1
- package/dist/agent/post-tool-handler.d.ts +0 -27
- package/dist/agent/post-tool-handler.d.ts.map +0 -1
- package/dist/agent/post-tool-handler.js +0 -194
- package/dist/agent/post-tool-handler.js.map +0 -1
- package/dist/agent/pre-compact-handler.d.ts +0 -36
- package/dist/agent/pre-compact-handler.d.ts.map +0 -1
- package/dist/agent/pre-compact-handler.js +0 -162
- package/dist/agent/pre-compact-handler.js.map +0 -1
- package/dist/agent/prompt-enhancer.d.ts +0 -33
- package/dist/agent/prompt-enhancer.d.ts.map +0 -1
- package/dist/agent/prompt-enhancer.js +0 -811
- package/dist/agent/prompt-enhancer.js.map +0 -1
- package/dist/agent/prompt-size-monitor.d.ts +0 -104
- package/dist/agent/prompt-size-monitor.d.ts.map +0 -1
- package/dist/agent/prompt-size-monitor.js +0 -192
- package/dist/agent/prompt-size-monitor.js.map +0 -1
- package/dist/agent/role-manager.d.ts +0 -122
- package/dist/agent/role-manager.d.ts.map +0 -1
- package/dist/agent/role-manager.js +0 -300
- package/dist/agent/role-manager.js.map +0 -1
- package/dist/agent/session-pool.d.ts +0 -176
- package/dist/agent/session-pool.d.ts.map +0 -1
- package/dist/agent/session-pool.js +0 -368
- package/dist/agent/session-pool.js.map +0 -1
- package/dist/agent/skill-loader.d.ts +0 -87
- package/dist/agent/skill-loader.d.ts.map +0 -1
- package/dist/agent/skill-loader.js +0 -461
- package/dist/agent/skill-loader.js.map +0 -1
- package/dist/agent/stop-continuation-handler.d.ts +0 -106
- package/dist/agent/stop-continuation-handler.d.ts.map +0 -1
- package/dist/agent/stop-continuation-handler.js +0 -230
- package/dist/agent/stop-continuation-handler.js.map +0 -1
- package/dist/agent/subagent-run-reconcile.d.ts +0 -23
- package/dist/agent/subagent-run-reconcile.d.ts.map +0 -1
- package/dist/agent/subagent-run-reconcile.js +0 -56
- package/dist/agent/subagent-run-reconcile.js.map +0 -1
- package/dist/agent/temporal-code-act-breaker.d.ts +0 -26
- package/dist/agent/temporal-code-act-breaker.d.ts.map +0 -1
- package/dist/agent/temporal-code-act-breaker.js +0 -94
- package/dist/agent/temporal-code-act-breaker.js.map +0 -1
- package/dist/agent/token-estimator.d.ts +0 -25
- package/dist/agent/token-estimator.d.ts.map +0 -1
- package/dist/agent/token-estimator.js +0 -75
- package/dist/agent/token-estimator.js.map +0 -1
- package/dist/agent/tool-registry.d.ts +0 -81
- package/dist/agent/tool-registry.d.ts.map +0 -1
- package/dist/agent/tool-registry.js +0 -876
- package/dist/agent/tool-registry.js.map +0 -1
- package/dist/agent/types.d.ts +0 -1261
- package/dist/agent/types.d.ts.map +0 -1
- package/dist/agent/types.js +0 -60
- package/dist/agent/types.js.map +0 -1
- package/dist/agent/yaml-frontmatter.d.ts +0 -75
- package/dist/agent/yaml-frontmatter.d.ts.map +0 -1
- package/dist/agent/yaml-frontmatter.js +0 -166
- package/dist/agent/yaml-frontmatter.js.map +0 -1
- package/dist/api/agent-context-handler.d.ts +0 -10
- package/dist/api/agent-context-handler.d.ts.map +0 -1
- package/dist/api/agent-context-handler.js +0 -216
- package/dist/api/agent-context-handler.js.map +0 -1
- package/dist/api/agent-graph-handler.d.ts +0 -18
- package/dist/api/agent-graph-handler.d.ts.map +0 -1
- package/dist/api/agent-graph-handler.js +0 -569
- package/dist/api/agent-graph-handler.js.map +0 -1
- package/dist/api/agent-handler.d.ts +0 -36
- package/dist/api/agent-handler.d.ts.map +0 -1
- package/dist/api/agent-handler.js +0 -223
- package/dist/api/agent-handler.js.map +0 -1
- package/dist/api/agent-raw-handler.d.ts +0 -70
- package/dist/api/agent-raw-handler.d.ts.map +0 -1
- package/dist/api/agent-raw-handler.js +0 -262
- package/dist/api/agent-raw-handler.js.map +0 -1
- package/dist/api/agent-situation-handler.d.ts +0 -14
- package/dist/api/agent-situation-handler.d.ts.map +0 -1
- package/dist/api/agent-situation-handler.js +0 -383
- package/dist/api/agent-situation-handler.js.map +0 -1
- package/dist/api/connector-feed-handler.d.ts +0 -42
- package/dist/api/connector-feed-handler.d.ts.map +0 -1
- package/dist/api/connector-feed-handler.js +0 -180
- package/dist/api/connector-feed-handler.js.map +0 -1
- package/dist/api/cron-handler.d.ts +0 -44
- package/dist/api/cron-handler.d.ts.map +0 -1
- package/dist/api/cron-handler.js +0 -261
- package/dist/api/cron-handler.js.map +0 -1
- package/dist/api/entity-audit-handler.d.ts +0 -12
- package/dist/api/entity-audit-handler.d.ts.map +0 -1
- package/dist/api/entity-audit-handler.js +0 -119
- package/dist/api/entity-audit-handler.js.map +0 -1
- package/dist/api/entity-audit-queue.d.ts +0 -74
- package/dist/api/entity-audit-queue.d.ts.map +0 -1
- package/dist/api/entity-audit-queue.js +0 -123
- package/dist/api/entity-audit-queue.js.map +0 -1
- package/dist/api/entity-audit-runner.d.ts +0 -9
- package/dist/api/entity-audit-runner.d.ts.map +0 -1
- package/dist/api/entity-audit-runner.js +0 -240
- package/dist/api/entity-audit-runner.js.map +0 -1
- package/dist/api/entity-review-handler.d.ts +0 -18
- package/dist/api/entity-review-handler.d.ts.map +0 -1
- package/dist/api/entity-review-handler.js +0 -521
- package/dist/api/entity-review-handler.js.map +0 -1
- package/dist/api/error-handler.d.ts +0 -22
- package/dist/api/error-handler.d.ts.map +0 -1
- package/dist/api/error-handler.js +0 -104
- package/dist/api/error-handler.js.map +0 -1
- package/dist/api/graph-api-types.d.ts +0 -105
- package/dist/api/graph-api-types.d.ts.map +0 -1
- package/dist/api/graph-api-types.js +0 -6
- package/dist/api/graph-api-types.js.map +0 -1
- package/dist/api/graph-api.d.ts +0 -42
- package/dist/api/graph-api.d.ts.map +0 -1
- package/dist/api/graph-api.js +0 -3460
- package/dist/api/graph-api.js.map +0 -1
- package/dist/api/heartbeat-handler.d.ts +0 -49
- package/dist/api/heartbeat-handler.d.ts.map +0 -1
- package/dist/api/heartbeat-handler.js +0 -106
- package/dist/api/heartbeat-handler.js.map +0 -1
- package/dist/api/index.d.ts +0 -145
- package/dist/api/index.d.ts.map +0 -1
- package/dist/api/index.js +0 -448
- package/dist/api/index.js.map +0 -1
- package/dist/api/intelligence-handler.d.ts +0 -116
- package/dist/api/intelligence-handler.d.ts.map +0 -1
- package/dist/api/intelligence-handler.js +0 -280
- package/dist/api/intelligence-handler.js.map +0 -1
- package/dist/api/memory-provenance-handler.d.ts +0 -3
- package/dist/api/memory-provenance-handler.d.ts.map +0 -1
- package/dist/api/memory-provenance-handler.js +0 -120
- package/dist/api/memory-provenance-handler.js.map +0 -1
- package/dist/api/operator-handler.d.ts +0 -19
- package/dist/api/operator-handler.d.ts.map +0 -1
- package/dist/api/operator-handler.js +0 -106
- package/dist/api/operator-handler.js.map +0 -1
- package/dist/api/operator-summary.d.ts +0 -3
- package/dist/api/operator-summary.d.ts.map +0 -1
- package/dist/api/operator-summary.js +0 -72
- package/dist/api/operator-summary.js.map +0 -1
- package/dist/api/operator-tasks-handler.d.ts +0 -7
- package/dist/api/operator-tasks-handler.d.ts.map +0 -1
- package/dist/api/operator-tasks-handler.js +0 -192
- package/dist/api/operator-tasks-handler.js.map +0 -1
- package/dist/api/runtime-status-handler.d.ts +0 -42
- package/dist/api/runtime-status-handler.d.ts.map +0 -1
- package/dist/api/runtime-status-handler.js +0 -56
- package/dist/api/runtime-status-handler.js.map +0 -1
- package/dist/api/skills-handler.d.ts +0 -12
- package/dist/api/skills-handler.d.ts.map +0 -1
- package/dist/api/skills-handler.js +0 -156
- package/dist/api/skills-handler.js.map +0 -1
- package/dist/api/token-handler.d.ts +0 -33
- package/dist/api/token-handler.d.ts.map +0 -1
- package/dist/api/token-handler.js +0 -118
- package/dist/api/token-handler.js.map +0 -1
- package/dist/api/types.d.ts +0 -155
- package/dist/api/types.d.ts.map +0 -1
- package/dist/api/types.js +0 -49
- package/dist/api/types.js.map +0 -1
- package/dist/api/ui-command-handler.d.ts +0 -48
- package/dist/api/ui-command-handler.d.ts.map +0 -1
- package/dist/api/ui-command-handler.js +0 -160
- package/dist/api/ui-command-handler.js.map +0 -1
- package/dist/api/upload-handler.d.ts +0 -12
- package/dist/api/upload-handler.d.ts.map +0 -1
- package/dist/api/upload-handler.js +0 -321
- package/dist/api/upload-handler.js.map +0 -1
- package/dist/api/wiki-handler.d.ts +0 -19
- package/dist/api/wiki-handler.d.ts.map +0 -1
- package/dist/api/wiki-handler.js +0 -136
- package/dist/api/wiki-handler.js.map +0 -1
- package/dist/api/worker-envelope.d.ts +0 -26
- package/dist/api/worker-envelope.d.ts.map +0 -1
- package/dist/api/worker-envelope.js +0 -176
- package/dist/api/worker-envelope.js.map +0 -1
- package/dist/auth/claude-client.d.ts +0 -12
- package/dist/auth/claude-client.d.ts.map +0 -1
- package/dist/auth/claude-client.js +0 -36
- package/dist/auth/claude-client.js.map +0 -1
- package/dist/auth/claude-code-auth.d.ts +0 -12
- package/dist/auth/claude-code-auth.d.ts.map +0 -1
- package/dist/auth/claude-code-auth.js +0 -85
- package/dist/auth/claude-code-auth.js.map +0 -1
- package/dist/auth/index.d.ts +0 -9
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/index.js +0 -13
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/oauth-manager.d.ts +0 -59
- package/dist/auth/oauth-manager.d.ts.map +0 -1
- package/dist/auth/oauth-manager.js +0 -252
- package/dist/auth/oauth-manager.js.map +0 -1
- package/dist/auth/types.d.ts +0 -92
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js +0 -23
- package/dist/auth/types.js.map +0 -1
- package/dist/cli/commands/connector.d.ts +0 -14
- package/dist/cli/commands/connector.d.ts.map +0 -1
- package/dist/cli/commands/connector.js +0 -174
- package/dist/cli/commands/connector.js.map +0 -1
- package/dist/cli/commands/gateway.d.ts +0 -18
- package/dist/cli/commands/gateway.d.ts.map +0 -1
- package/dist/cli/commands/gateway.js +0 -144
- package/dist/cli/commands/gateway.js.map +0 -1
- package/dist/cli/commands/report.d.ts +0 -14
- package/dist/cli/commands/report.d.ts.map +0 -1
- package/dist/cli/commands/report.js +0 -102
- package/dist/cli/commands/report.js.map +0 -1
- package/dist/cli/commands/run.d.ts +0 -19
- package/dist/cli/commands/run.d.ts.map +0 -1
- package/dist/cli/commands/run.js +0 -123
- package/dist/cli/commands/run.js.map +0 -1
- package/dist/cli/commands/setup.d.ts +0 -3
- package/dist/cli/commands/setup.d.ts.map +0 -1
- package/dist/cli/commands/setup.js +0 -9
- package/dist/cli/commands/setup.js.map +0 -1
- package/dist/cli/commands/start.d.ts +0 -263
- package/dist/cli/commands/start.d.ts.map +0 -1
- package/dist/cli/commands/start.js +0 -2230
- package/dist/cli/commands/start.js.map +0 -1
- package/dist/cli/commands/status.d.ts +0 -18
- package/dist/cli/commands/status.d.ts.map +0 -1
- package/dist/cli/commands/status.js +0 -326
- package/dist/cli/commands/status.js.map +0 -1
- package/dist/cli/commands/stop.d.ts +0 -28
- package/dist/cli/commands/stop.d.ts.map +0 -1
- package/dist/cli/commands/stop.js +0 -597
- package/dist/cli/commands/stop.js.map +0 -1
- package/dist/cli/config/config-manager.d.ts +0 -84
- package/dist/cli/config/config-manager.d.ts.map +0 -1
- package/dist/cli/config/config-manager.js +0 -886
- package/dist/cli/config/config-manager.js.map +0 -1
- package/dist/cli/config/types.d.ts +0 -633
- package/dist/cli/config/types.d.ts.map +0 -1
- package/dist/cli/config/types.js +0 -247
- package/dist/cli/config/types.js.map +0 -1
- package/dist/cli/runtime/agent-loop-init.d.ts +0 -53
- package/dist/cli/runtime/agent-loop-init.d.ts.map +0 -1
- package/dist/cli/runtime/agent-loop-init.js +0 -368
- package/dist/cli/runtime/agent-loop-init.js.map +0 -1
- package/dist/cli/runtime/api-routes-init.d.ts +0 -84
- package/dist/cli/runtime/api-routes-init.d.ts.map +0 -1
- package/dist/cli/runtime/api-routes-init.js +0 -1542
- package/dist/cli/runtime/api-routes-init.js.map +0 -1
- package/dist/cli/runtime/api-server-init.d.ts +0 -59
- package/dist/cli/runtime/api-server-init.d.ts.map +0 -1
- package/dist/cli/runtime/api-server-init.js +0 -159
- package/dist/cli/runtime/api-server-init.js.map +0 -1
- package/dist/cli/runtime/code-act-executor.d.ts +0 -14
- package/dist/cli/runtime/code-act-executor.d.ts.map +0 -1
- package/dist/cli/runtime/code-act-executor.js +0 -108
- package/dist/cli/runtime/code-act-executor.js.map +0 -1
- package/dist/cli/runtime/connector-bootstrap.d.ts +0 -8
- package/dist/cli/runtime/connector-bootstrap.d.ts.map +0 -1
- package/dist/cli/runtime/connector-bootstrap.js +0 -14
- package/dist/cli/runtime/connector-bootstrap.js.map +0 -1
- package/dist/cli/runtime/connector-init.d.ts +0 -64
- package/dist/cli/runtime/connector-init.d.ts.map +0 -1
- package/dist/cli/runtime/connector-init.js +0 -237
- package/dist/cli/runtime/connector-init.js.map +0 -1
- package/dist/cli/runtime/daemon.d.ts +0 -38
- package/dist/cli/runtime/daemon.d.ts.map +0 -1
- package/dist/cli/runtime/daemon.js +0 -263
- package/dist/cli/runtime/daemon.js.map +0 -1
- package/dist/cli/runtime/envelope-bootstrap.d.ts +0 -17
- package/dist/cli/runtime/envelope-bootstrap.d.ts.map +0 -1
- package/dist/cli/runtime/envelope-bootstrap.js +0 -56
- package/dist/cli/runtime/envelope-bootstrap.js.map +0 -1
- package/dist/cli/runtime/gateway-init.d.ts +0 -55
- package/dist/cli/runtime/gateway-init.d.ts.map +0 -1
- package/dist/cli/runtime/gateway-init.js +0 -196
- package/dist/cli/runtime/gateway-init.js.map +0 -1
- package/dist/cli/runtime/gateway-wiring.d.ts +0 -51
- package/dist/cli/runtime/gateway-wiring.d.ts.map +0 -1
- package/dist/cli/runtime/gateway-wiring.js +0 -215
- package/dist/cli/runtime/gateway-wiring.js.map +0 -1
- package/dist/cli/runtime/mama-core-init.d.ts +0 -42
- package/dist/cli/runtime/mama-core-init.d.ts.map +0 -1
- package/dist/cli/runtime/mama-core-init.js +0 -211
- package/dist/cli/runtime/mama-core-init.js.map +0 -1
- package/dist/cli/runtime/message-router-config.d.ts +0 -4
- package/dist/cli/runtime/message-router-config.d.ts.map +0 -1
- package/dist/cli/runtime/message-router-config.js +0 -11
- package/dist/cli/runtime/message-router-config.js.map +0 -1
- package/dist/cli/runtime/metrics-init.d.ts +0 -28
- package/dist/cli/runtime/metrics-init.d.ts.map +0 -1
- package/dist/cli/runtime/metrics-init.js +0 -131
- package/dist/cli/runtime/metrics-init.js.map +0 -1
- package/dist/cli/runtime/owner-backfill.d.ts +0 -24
- package/dist/cli/runtime/owner-backfill.d.ts.map +0 -1
- package/dist/cli/runtime/owner-backfill.js +0 -24
- package/dist/cli/runtime/owner-backfill.js.map +0 -1
- package/dist/cli/runtime/scheduler-init.d.ts +0 -60
- package/dist/cli/runtime/scheduler-init.d.ts.map +0 -1
- package/dist/cli/runtime/scheduler-init.js +0 -173
- package/dist/cli/runtime/scheduler-init.js.map +0 -1
- package/dist/cli/runtime/server-start.d.ts +0 -23
- package/dist/cli/runtime/server-start.d.ts.map +0 -1
- package/dist/cli/runtime/server-start.js +0 -174
- package/dist/cli/runtime/server-start.js.map +0 -1
- package/dist/cli/runtime/shutdown.d.ts +0 -46
- package/dist/cli/runtime/shutdown.d.ts.map +0 -1
- package/dist/cli/runtime/shutdown.js +0 -240
- package/dist/cli/runtime/shutdown.js.map +0 -1
- package/dist/cli/runtime/temporal-init.d.ts +0 -26
- package/dist/cli/runtime/temporal-init.d.ts.map +0 -1
- package/dist/cli/runtime/temporal-init.js +0 -57
- package/dist/cli/runtime/temporal-init.js.map +0 -1
- package/dist/cli/runtime/types.d.ts +0 -127
- package/dist/cli/runtime/types.d.ts.map +0 -1
- package/dist/cli/runtime/types.js +0 -12
- package/dist/cli/runtime/types.js.map +0 -1
- package/dist/cli/runtime/utilities.d.ts +0 -72
- package/dist/cli/runtime/utilities.d.ts.map +0 -1
- package/dist/cli/runtime/utilities.js +0 -472
- package/dist/cli/runtime/utilities.js.map +0 -1
- package/dist/cli/shutdown-utils.d.ts +0 -6
- package/dist/cli/shutdown-utils.d.ts.map +0 -1
- package/dist/cli/shutdown-utils.js +0 -11
- package/dist/cli/shutdown-utils.js.map +0 -1
- package/dist/cli/utils/pid-manager.d.ts +0 -56
- package/dist/cli/utils/pid-manager.d.ts.map +0 -1
- package/dist/cli/utils/pid-manager.js +0 -141
- package/dist/cli/utils/pid-manager.js.map +0 -1
- package/dist/concurrency/index.d.ts +0 -13
- package/dist/concurrency/index.d.ts.map +0 -1
- package/dist/concurrency/index.js +0 -22
- package/dist/concurrency/index.js.map +0 -1
- package/dist/concurrency/lane-manager.d.ts +0 -113
- package/dist/concurrency/lane-manager.d.ts.map +0 -1
- package/dist/concurrency/lane-manager.js +0 -248
- package/dist/concurrency/lane-manager.js.map +0 -1
- package/dist/concurrency/session-key.d.ts +0 -41
- package/dist/concurrency/session-key.d.ts.map +0 -1
- package/dist/concurrency/session-key.js +0 -61
- package/dist/concurrency/session-key.js.map +0 -1
- package/dist/concurrency/types.d.ts +0 -73
- package/dist/concurrency/types.d.ts.map +0 -1
- package/dist/concurrency/types.js +0 -16
- package/dist/concurrency/types.js.map +0 -1
- package/dist/connectors/framework/raw-store.d.ts +0 -63
- package/dist/connectors/framework/raw-store.d.ts.map +0 -1
- package/dist/connectors/framework/raw-store.js +0 -356
- package/dist/connectors/framework/raw-store.js.map +0 -1
- package/dist/connectors/kagemusha/query-tools.d.ts +0 -146
- package/dist/connectors/kagemusha/query-tools.d.ts.map +0 -1
- package/dist/connectors/kagemusha/query-tools.js +0 -467
- package/dist/connectors/kagemusha/query-tools.js.map +0 -1
- package/dist/connectors/private-connector-policy.d.ts +0 -174
- package/dist/connectors/private-connector-policy.d.ts.map +0 -1
- package/dist/connectors/private-connector-policy.js +0 -299
- package/dist/connectors/private-connector-policy.js.map +0 -1
- package/dist/connectors/private-prompt-overlay.d.ts +0 -17
- package/dist/connectors/private-prompt-overlay.d.ts.map +0 -1
- package/dist/connectors/private-prompt-overlay.js +0 -156
- package/dist/connectors/private-prompt-overlay.js.map +0 -1
- package/dist/connectors/trello/query-tools.d.ts +0 -243
- package/dist/connectors/trello/query-tools.d.ts.map +0 -1
- package/dist/connectors/trello/query-tools.js +0 -661
- package/dist/connectors/trello/query-tools.js.map +0 -1
- package/dist/db/agent-store.d.ts +0 -145
- package/dist/db/agent-store.d.ts.map +0 -1
- package/dist/db/agent-store.js +0 -279
- package/dist/db/agent-store.js.map +0 -1
- package/dist/db/migrations/agent-activity-envelope-hash.d.ts +0 -3
- package/dist/db/migrations/agent-activity-envelope-hash.d.ts.map +0 -1
- package/dist/db/migrations/agent-activity-envelope-hash.js +0 -29
- package/dist/db/migrations/agent-activity-envelope-hash.js.map +0 -1
- package/dist/db/migrations/agent-activity-gateway-call-id.d.ts +0 -3
- package/dist/db/migrations/agent-activity-gateway-call-id.d.ts.map +0 -1
- package/dist/db/migrations/agent-activity-gateway-call-id.js +0 -17
- package/dist/db/migrations/agent-activity-gateway-call-id.js.map +0 -1
- package/dist/db/migrations/agent-activity-tool-name.d.ts +0 -8
- package/dist/db/migrations/agent-activity-tool-name.d.ts.map +0 -1
- package/dist/db/migrations/agent-activity-tool-name.js +0 -24
- package/dist/db/migrations/agent-activity-tool-name.js.map +0 -1
- package/dist/db/migrations/agent-activity-validation-columns.d.ts +0 -3
- package/dist/db/migrations/agent-activity-validation-columns.d.ts.map +0 -1
- package/dist/db/migrations/agent-activity-validation-columns.js +0 -22
- package/dist/db/migrations/agent-activity-validation-columns.js.map +0 -1
- package/dist/db/migrations/agent-metrics-response-avg.d.ts +0 -3
- package/dist/db/migrations/agent-metrics-response-avg.d.ts.map +0 -1
- package/dist/db/migrations/agent-metrics-response-avg.js +0 -19
- package/dist/db/migrations/agent-metrics-response-avg.js.map +0 -1
- package/dist/db/migrations/agent-store-tables.d.ts +0 -3
- package/dist/db/migrations/agent-store-tables.d.ts.map +0 -1
- package/dist/db/migrations/agent-store-tables.js +0 -64
- package/dist/db/migrations/agent-store-tables.js.map +0 -1
- package/dist/db/migrations/envelope-tables.d.ts +0 -3
- package/dist/db/migrations/envelope-tables.d.ts.map +0 -1
- package/dist/db/migrations/envelope-tables.js +0 -38
- package/dist/db/migrations/envelope-tables.js.map +0 -1
- package/dist/db/migrations/operator-owner-action-candidates.d.ts +0 -19
- package/dist/db/migrations/operator-owner-action-candidates.d.ts.map +0 -1
- package/dist/db/migrations/operator-owner-action-candidates.js +0 -254
- package/dist/db/migrations/operator-owner-action-candidates.js.map +0 -1
- package/dist/db/migrations/operator-procedures.d.ts +0 -4
- package/dist/db/migrations/operator-procedures.d.ts.map +0 -1
- package/dist/db/migrations/operator-procedures.js +0 -63
- package/dist/db/migrations/operator-procedures.js.map +0 -1
- package/dist/db/migrations/operator-task-classification.d.ts +0 -15
- package/dist/db/migrations/operator-task-classification.d.ts.map +0 -1
- package/dist/db/migrations/operator-task-classification.js +0 -25
- package/dist/db/migrations/operator-task-classification.js.map +0 -1
- package/dist/db/migrations/operator-task-external-lifecycle.d.ts +0 -17
- package/dist/db/migrations/operator-task-external-lifecycle.d.ts.map +0 -1
- package/dist/db/migrations/operator-task-external-lifecycle.js +0 -199
- package/dist/db/migrations/operator-task-external-lifecycle.js.map +0 -1
- package/dist/db/migrations/operator-task-review-lifecycle.d.ts +0 -4
- package/dist/db/migrations/operator-task-review-lifecycle.d.ts.map +0 -1
- package/dist/db/migrations/operator-task-review-lifecycle.js +0 -17
- package/dist/db/migrations/operator-task-review-lifecycle.js.map +0 -1
- package/dist/db/migrations/operator-task-temporal.d.ts +0 -8
- package/dist/db/migrations/operator-task-temporal.d.ts.map +0 -1
- package/dist/db/migrations/operator-task-temporal.js +0 -214
- package/dist/db/migrations/operator-task-temporal.js.map +0 -1
- package/dist/db/migrations/owner-action-effects.d.ts +0 -18
- package/dist/db/migrations/owner-action-effects.d.ts.map +0 -1
- package/dist/db/migrations/owner-action-effects.js +0 -111
- package/dist/db/migrations/owner-action-effects.js.map +0 -1
- package/dist/db/migrations/raw-item-revisions.d.ts +0 -4
- package/dist/db/migrations/raw-item-revisions.d.ts.map +0 -1
- package/dist/db/migrations/raw-item-revisions.js +0 -29
- package/dist/db/migrations/raw-item-revisions.js.map +0 -1
- package/dist/db/migrations/token-usage-agent-version.d.ts +0 -3
- package/dist/db/migrations/token-usage-agent-version.d.ts.map +0 -1
- package/dist/db/migrations/token-usage-agent-version.js +0 -16
- package/dist/db/migrations/token-usage-agent-version.js.map +0 -1
- package/dist/db/migrations/validation-session-tables.d.ts +0 -3
- package/dist/db/migrations/validation-session-tables.d.ts.map +0 -1
- package/dist/db/migrations/validation-session-tables.js +0 -59
- package/dist/db/migrations/validation-session-tables.js.map +0 -1
- package/dist/envelope/authority.d.ts +0 -15
- package/dist/envelope/authority.d.ts.map +0 -1
- package/dist/envelope/authority.js +0 -95
- package/dist/envelope/authority.js.map +0 -1
- package/dist/envelope/canonical.d.ts +0 -14
- package/dist/envelope/canonical.d.ts.map +0 -1
- package/dist/envelope/canonical.js +0 -68
- package/dist/envelope/canonical.js.map +0 -1
- package/dist/envelope/enforcer.d.ts +0 -30
- package/dist/envelope/enforcer.d.ts.map +0 -1
- package/dist/envelope/enforcer.js +0 -286
- package/dist/envelope/enforcer.js.map +0 -1
- package/dist/envelope/expiry.d.ts +0 -2
- package/dist/envelope/expiry.d.ts.map +0 -1
- package/dist/envelope/expiry.js +0 -15
- package/dist/envelope/expiry.js.map +0 -1
- package/dist/envelope/index.d.ts +0 -9
- package/dist/envelope/index.d.ts.map +0 -1
- package/dist/envelope/index.js +0 -25
- package/dist/envelope/index.js.map +0 -1
- package/dist/envelope/key-provider.d.ts +0 -7
- package/dist/envelope/key-provider.d.ts.map +0 -1
- package/dist/envelope/key-provider.js +0 -137
- package/dist/envelope/key-provider.js.map +0 -1
- package/dist/envelope/reactive-config.d.ts +0 -24
- package/dist/envelope/reactive-config.d.ts.map +0 -1
- package/dist/envelope/reactive-config.js +0 -198
- package/dist/envelope/reactive-config.js.map +0 -1
- package/dist/envelope/run-guard.d.ts +0 -10
- package/dist/envelope/run-guard.d.ts.map +0 -1
- package/dist/envelope/run-guard.js +0 -19
- package/dist/envelope/run-guard.js.map +0 -1
- package/dist/envelope/signature.d.ts +0 -15
- package/dist/envelope/signature.d.ts.map +0 -1
- package/dist/envelope/signature.js +0 -75
- package/dist/envelope/signature.js.map +0 -1
- package/dist/envelope/store.d.ts +0 -16
- package/dist/envelope/store.d.ts.map +0 -1
- package/dist/envelope/store.js +0 -118
- package/dist/envelope/store.js.map +0 -1
- package/dist/envelope/tool-connector-scope.d.ts +0 -35
- package/dist/envelope/tool-connector-scope.d.ts.map +0 -1
- package/dist/envelope/tool-connector-scope.js +0 -61
- package/dist/envelope/tool-connector-scope.js.map +0 -1
- package/dist/envelope/types.d.ts +0 -60
- package/dist/envelope/types.d.ts.map +0 -1
- package/dist/envelope/types.js +0 -9
- package/dist/envelope/types.js.map +0 -1
- package/dist/evidence/effects.d.ts +0 -125
- package/dist/evidence/effects.d.ts.map +0 -1
- package/dist/evidence/effects.js +0 -409
- package/dist/evidence/effects.js.map +0 -1
- package/dist/evidence/read.d.ts +0 -130
- package/dist/evidence/read.d.ts.map +0 -1
- package/dist/evidence/read.js +0 -167
- package/dist/evidence/read.js.map +0 -1
- package/dist/gateways/attachment-utils.d.ts +0 -28
- package/dist/gateways/attachment-utils.d.ts.map +0 -1
- package/dist/gateways/attachment-utils.js +0 -489
- package/dist/gateways/attachment-utils.js.map +0 -1
- package/dist/gateways/channel-history.d.ts +0 -148
- package/dist/gateways/channel-history.d.ts.map +0 -1
- package/dist/gateways/channel-history.js +0 -385
- package/dist/gateways/channel-history.js.map +0 -1
- package/dist/gateways/context-injector.d.ts +0 -255
- package/dist/gateways/context-injector.d.ts.map +0 -1
- package/dist/gateways/context-injector.js +0 -285
- package/dist/gateways/context-injector.js.map +0 -1
- package/dist/gateways/image-analyzer.d.ts +0 -28
- package/dist/gateways/image-analyzer.d.ts.map +0 -1
- package/dist/gateways/image-analyzer.js +0 -154
- package/dist/gateways/image-analyzer.js.map +0 -1
- package/dist/gateways/index.d.ts +0 -35
- package/dist/gateways/index.d.ts.map +0 -1
- package/dist/gateways/index.js +0 -55
- package/dist/gateways/index.js.map +0 -1
- package/dist/gateways/member-candidate-store.d.ts +0 -26
- package/dist/gateways/member-candidate-store.d.ts.map +0 -1
- package/dist/gateways/member-candidate-store.js +0 -90
- package/dist/gateways/member-candidate-store.js.map +0 -1
- package/dist/gateways/member-effective-scope.d.ts +0 -25
- package/dist/gateways/member-effective-scope.d.ts.map +0 -1
- package/dist/gateways/member-effective-scope.js +0 -323
- package/dist/gateways/member-effective-scope.js.map +0 -1
- package/dist/gateways/message-router.d.ts +0 -239
- package/dist/gateways/message-router.d.ts.map +0 -1
- package/dist/gateways/message-router.js +0 -1714
- package/dist/gateways/message-router.js.map +0 -1
- package/dist/gateways/plugin-loader.d.ts +0 -80
- package/dist/gateways/plugin-loader.d.ts.map +0 -1
- package/dist/gateways/plugin-loader.js +0 -299
- package/dist/gateways/plugin-loader.js.map +0 -1
- package/dist/gateways/principal.d.ts +0 -37
- package/dist/gateways/principal.d.ts.map +0 -1
- package/dist/gateways/principal.js +0 -95
- package/dist/gateways/principal.js.map +0 -1
- package/dist/gateways/report-projection-v1.d.ts +0 -41
- package/dist/gateways/report-projection-v1.d.ts.map +0 -1
- package/dist/gateways/report-projection-v1.js +0 -160
- package/dist/gateways/report-projection-v1.js.map +0 -1
- package/dist/gateways/telegram-media.d.ts +0 -41
- package/dist/gateways/telegram-media.d.ts.map +0 -1
- package/dist/gateways/telegram-media.js +0 -242
- package/dist/gateways/telegram-media.js.map +0 -1
- package/dist/gateways/telegram-report-context-store.d.ts +0 -131
- package/dist/gateways/telegram-report-context-store.d.ts.map +0 -1
- package/dist/gateways/telegram-report-context-store.js +0 -388
- package/dist/gateways/telegram-report-context-store.js.map +0 -1
- package/dist/gateways/tool-status-tracker.d.ts +0 -87
- package/dist/gateways/tool-status-tracker.d.ts.map +0 -1
- package/dist/gateways/tool-status-tracker.js +0 -284
- package/dist/gateways/tool-status-tracker.js.map +0 -1
- package/dist/mcp/code-act-api-client.d.ts +0 -32
- package/dist/mcp/code-act-api-client.d.ts.map +0 -1
- package/dist/mcp/code-act-api-client.js +0 -80
- package/dist/mcp/code-act-api-client.js.map +0 -1
- package/dist/mcp/code-act-mcp-config.d.ts +0 -49
- package/dist/mcp/code-act-mcp-config.d.ts.map +0 -1
- package/dist/mcp/code-act-mcp-config.js +0 -124
- package/dist/mcp/code-act-mcp-config.js.map +0 -1
- package/dist/mcp/code-act-server.d.ts +0 -14
- package/dist/mcp/code-act-server.d.ts.map +0 -1
- package/dist/mcp/code-act-server.js +0 -204
- package/dist/mcp/code-act-server.js.map +0 -1
- package/dist/mcp/code-act-terminal-transport.d.ts +0 -64
- package/dist/mcp/code-act-terminal-transport.d.ts.map +0 -1
- package/dist/mcp/code-act-terminal-transport.js +0 -176
- package/dist/mcp/code-act-terminal-transport.js.map +0 -1
- package/dist/memory/agent-notice-queue.d.ts +0 -24
- package/dist/memory/agent-notice-queue.d.ts.map +0 -1
- package/dist/memory/agent-notice-queue.js +0 -40
- package/dist/memory/agent-notice-queue.js.map +0 -1
- package/dist/memory/audit-task-queue.d.ts +0 -28
- package/dist/memory/audit-task-queue.d.ts.map +0 -1
- package/dist/memory/audit-task-queue.js +0 -29
- package/dist/memory/audit-task-queue.js.map +0 -1
- package/dist/memory/bootstrap-context.d.ts +0 -12
- package/dist/memory/bootstrap-context.d.ts.map +0 -1
- package/dist/memory/bootstrap-context.js +0 -68
- package/dist/memory/bootstrap-context.js.map +0 -1
- package/dist/memory/history-extractor.d.ts +0 -69
- package/dist/memory/history-extractor.d.ts.map +0 -1
- package/dist/memory/history-extractor.js +0 -210
- package/dist/memory/history-extractor.js.map +0 -1
- package/dist/memory/memory-agent-ack.d.ts +0 -4
- package/dist/memory/memory-agent-ack.d.ts.map +0 -1
- package/dist/memory/memory-agent-ack.js +0 -54
- package/dist/memory/memory-agent-ack.js.map +0 -1
- package/dist/memory/memory-agent-dashboard.d.ts +0 -35
- package/dist/memory/memory-agent-dashboard.d.ts.map +0 -1
- package/dist/memory/memory-agent-dashboard.js +0 -116
- package/dist/memory/memory-agent-dashboard.js.map +0 -1
- package/dist/memory/memory-logger.d.ts +0 -47
- package/dist/memory/memory-logger.d.ts.map +0 -1
- package/dist/memory/memory-logger.js +0 -126
- package/dist/memory/memory-logger.js.map +0 -1
- package/dist/memory/provenance-live.d.ts +0 -111
- package/dist/memory/provenance-live.d.ts.map +0 -1
- package/dist/memory/provenance-live.js +0 -381
- package/dist/memory/provenance-live.js.map +0 -1
- package/dist/memory/provenance-resolver.d.ts +0 -184
- package/dist/memory/provenance-resolver.d.ts.map +0 -1
- package/dist/memory/provenance-resolver.js +0 -152
- package/dist/memory/provenance-resolver.js.map +0 -1
- package/dist/memory/raw-backed-memory-ingest.d.ts +0 -26
- package/dist/memory/raw-backed-memory-ingest.d.ts.map +0 -1
- package/dist/memory/raw-backed-memory-ingest.js +0 -214
- package/dist/memory/raw-backed-memory-ingest.js.map +0 -1
- package/dist/memory/recall-bundle-formatter.d.ts +0 -26
- package/dist/memory/recall-bundle-formatter.d.ts.map +0 -1
- package/dist/memory/recall-bundle-formatter.js +0 -53
- package/dist/memory/recall-bundle-formatter.js.map +0 -1
- package/dist/memory/save-candidate-extractor.d.ts +0 -16
- package/dist/memory/save-candidate-extractor.d.ts.map +0 -1
- package/dist/memory/save-candidate-extractor.js +0 -127
- package/dist/memory/save-candidate-extractor.js.map +0 -1
- package/dist/memory/save-candidate-types.d.ts +0 -16
- package/dist/memory/save-candidate-types.d.ts.map +0 -1
- package/dist/memory/save-candidate-types.js +0 -3
- package/dist/memory/save-candidate-types.js.map +0 -1
- package/dist/memory/scope-context.d.ts +0 -12
- package/dist/memory/scope-context.d.ts.map +0 -1
- package/dist/memory/scope-context.js +0 -18
- package/dist/memory/scope-context.js.map +0 -1
- package/dist/memory/secret-filter.d.ts +0 -23
- package/dist/memory/secret-filter.d.ts.map +0 -1
- package/dist/memory/secret-filter.js +0 -90
- package/dist/memory/secret-filter.js.map +0 -1
- package/dist/multi-agent/agent-event-bus.d.ts +0 -50
- package/dist/multi-agent/agent-event-bus.d.ts.map +0 -1
- package/dist/multi-agent/agent-event-bus.js +0 -101
- package/dist/multi-agent/agent-event-bus.js.map +0 -1
- package/dist/multi-agent/agent-process-manager.d.ts +0 -205
- package/dist/multi-agent/agent-process-manager.d.ts.map +0 -1
- package/dist/multi-agent/agent-process-manager.js +0 -1191
- package/dist/multi-agent/agent-process-manager.js.map +0 -1
- package/dist/multi-agent/bmad-templates.d.ts +0 -49
- package/dist/multi-agent/bmad-templates.d.ts.map +0 -1
- package/dist/multi-agent/bmad-templates.js +0 -121
- package/dist/multi-agent/bmad-templates.js.map +0 -1
- package/dist/multi-agent/runtime-process.d.ts +0 -74
- package/dist/multi-agent/runtime-process.d.ts.map +0 -1
- package/dist/multi-agent/runtime-process.js +0 -160
- package/dist/multi-agent/runtime-process.js.map +0 -1
- package/dist/multi-agent/tool-permission-manager.d.ts +0 -70
- package/dist/multi-agent/tool-permission-manager.d.ts.map +0 -1
- package/dist/multi-agent/tool-permission-manager.js +0 -195
- package/dist/multi-agent/tool-permission-manager.js.map +0 -1
- package/dist/multi-agent/types.d.ts +0 -438
- package/dist/multi-agent/types.d.ts.map +0 -1
- package/dist/multi-agent/types.js +0 -27
- package/dist/multi-agent/types.js.map +0 -1
- package/dist/multi-agent/wiki-agent-persona.d.ts +0 -16
- package/dist/multi-agent/wiki-agent-persona.d.ts.map +0 -1
- package/dist/multi-agent/wiki-agent-persona.js +0 -23
- package/dist/multi-agent/wiki-agent-persona.js.map +0 -1
- package/dist/multi-agent/workflow-types.d.ts +0 -186
- package/dist/multi-agent/workflow-types.d.ts.map +0 -1
- package/dist/multi-agent/workflow-types.js +0 -9
- package/dist/multi-agent/workflow-types.js.map +0 -1
- package/dist/observability/code-audit.d.ts +0 -87
- package/dist/observability/code-audit.d.ts.map +0 -1
- package/dist/observability/code-audit.js +0 -414
- package/dist/observability/code-audit.js.map +0 -1
- package/dist/observability/health-check.d.ts +0 -102
- package/dist/observability/health-check.d.ts.map +0 -1
- package/dist/observability/health-check.js +0 -422
- package/dist/observability/health-check.js.map +0 -1
- package/dist/observability/health-score.d.ts +0 -29
- package/dist/observability/health-score.d.ts.map +0 -1
- package/dist/observability/health-score.js +0 -83
- package/dist/observability/health-score.js.map +0 -1
- package/dist/observability/metrics-cleanup.d.ts +0 -24
- package/dist/observability/metrics-cleanup.d.ts.map +0 -1
- package/dist/observability/metrics-cleanup.js +0 -51
- package/dist/observability/metrics-cleanup.js.map +0 -1
- package/dist/observability/metrics-store.d.ts +0 -52
- package/dist/observability/metrics-store.d.ts.map +0 -1
- package/dist/observability/metrics-store.js +0 -186
- package/dist/observability/metrics-store.js.map +0 -1
- package/dist/observability/operational-issues.d.ts +0 -55
- package/dist/observability/operational-issues.d.ts.map +0 -1
- package/dist/observability/operational-issues.js +0 -170
- package/dist/observability/operational-issues.js.map +0 -1
- package/dist/onboarding/agent-contract.d.ts +0 -42
- package/dist/onboarding/agent-contract.d.ts.map +0 -1
- package/dist/onboarding/agent-contract.js +0 -129
- package/dist/onboarding/agent-contract.js.map +0 -1
- package/dist/onboarding/assess-live.d.ts +0 -22
- package/dist/onboarding/assess-live.d.ts.map +0 -1
- package/dist/onboarding/assess-live.js +0 -200
- package/dist/onboarding/assess-live.js.map +0 -1
- package/dist/onboarding/bootstrap-template.d.ts +0 -5
- package/dist/onboarding/bootstrap-template.d.ts.map +0 -1
- package/dist/onboarding/bootstrap-template.js +0 -34
- package/dist/onboarding/bootstrap-template.js.map +0 -1
- package/dist/operator/action-verifier.d.ts +0 -75
- package/dist/operator/action-verifier.d.ts.map +0 -1
- package/dist/operator/action-verifier.js +0 -149
- package/dist/operator/action-verifier.js.map +0 -1
- package/dist/operator/board-delta-gate.d.ts +0 -131
- package/dist/operator/board-delta-gate.d.ts.map +0 -1
- package/dist/operator/board-delta-gate.js +0 -181
- package/dist/operator/board-delta-gate.js.map +0 -1
- package/dist/operator/board-pipeline-render.d.ts +0 -16
- package/dist/operator/board-pipeline-render.d.ts.map +0 -1
- package/dist/operator/board-pipeline-render.js +0 -69
- package/dist/operator/board-pipeline-render.js.map +0 -1
- package/dist/operator/board-reconcile.d.ts +0 -61
- package/dist/operator/board-reconcile.d.ts.map +0 -1
- package/dist/operator/board-reconcile.js +0 -157
- package/dist/operator/board-reconcile.js.map +0 -1
- package/dist/operator/board-refresh-gate.d.ts +0 -39
- package/dist/operator/board-refresh-gate.d.ts.map +0 -1
- package/dist/operator/board-refresh-gate.js +0 -83
- package/dist/operator/board-refresh-gate.js.map +0 -1
- package/dist/operator/changes-projection.d.ts +0 -72
- package/dist/operator/changes-projection.d.ts.map +0 -1
- package/dist/operator/changes-projection.js +0 -110
- package/dist/operator/changes-projection.js.map +0 -1
- package/dist/operator/connector-delta-repo.d.ts +0 -33
- package/dist/operator/connector-delta-repo.d.ts.map +0 -1
- package/dist/operator/connector-delta-repo.js +0 -0
- package/dist/operator/connector-delta-repo.js.map +0 -1
- package/dist/operator/console-brief.d.ts +0 -40
- package/dist/operator/console-brief.d.ts.map +0 -1
- package/dist/operator/console-brief.js +0 -246
- package/dist/operator/console-brief.js.map +0 -1
- package/dist/operator/experience-evidence.d.ts +0 -18
- package/dist/operator/experience-evidence.d.ts.map +0 -1
- package/dist/operator/experience-evidence.js +0 -82
- package/dist/operator/experience-evidence.js.map +0 -1
- package/dist/operator/experience-hints.d.ts +0 -44
- package/dist/operator/experience-hints.d.ts.map +0 -1
- package/dist/operator/experience-hints.js +0 -98
- package/dist/operator/experience-hints.js.map +0 -1
- package/dist/operator/external-correlation.d.ts +0 -94
- package/dist/operator/external-correlation.d.ts.map +0 -1
- package/dist/operator/external-correlation.js +0 -177
- package/dist/operator/external-correlation.js.map +0 -1
- package/dist/operator/external-lifecycle-candidates.d.ts +0 -70
- package/dist/operator/external-lifecycle-candidates.d.ts.map +0 -1
- package/dist/operator/external-lifecycle-candidates.js +0 -579
- package/dist/operator/external-lifecycle-candidates.js.map +0 -1
- package/dist/operator/external-lifecycle-discovery.d.ts +0 -61
- package/dist/operator/external-lifecycle-discovery.d.ts.map +0 -1
- package/dist/operator/external-lifecycle-discovery.js +0 -103
- package/dist/operator/external-lifecycle-discovery.js.map +0 -1
- package/dist/operator/external-lifecycle.d.ts +0 -105
- package/dist/operator/external-lifecycle.d.ts.map +0 -1
- package/dist/operator/external-lifecycle.js +0 -27
- package/dist/operator/external-lifecycle.js.map +0 -1
- package/dist/operator/file-coordination.d.ts +0 -7
- package/dist/operator/file-coordination.d.ts.map +0 -1
- package/dist/operator/file-coordination.js +0 -84
- package/dist/operator/file-coordination.js.map +0 -1
- package/dist/operator/file-export.d.ts +0 -22
- package/dist/operator/file-export.d.ts.map +0 -1
- package/dist/operator/file-export.js +0 -115
- package/dist/operator/file-export.js.map +0 -1
- package/dist/operator/leg-cadence.d.ts +0 -72
- package/dist/operator/leg-cadence.d.ts.map +0 -1
- package/dist/operator/leg-cadence.js +0 -122
- package/dist/operator/leg-cadence.js.map +0 -1
- package/dist/operator/mama-memory-port.d.ts +0 -13
- package/dist/operator/mama-memory-port.d.ts.map +0 -1
- package/dist/operator/mama-memory-port.js +0 -33
- package/dist/operator/mama-memory-port.js.map +0 -1
- package/dist/operator/operator-interfaces.d.ts +0 -136
- package/dist/operator/operator-interfaces.d.ts.map +0 -1
- package/dist/operator/operator-interfaces.js +0 -15
- package/dist/operator/operator-interfaces.js.map +0 -1
- package/dist/operator/operator-trigger-loop.d.ts +0 -203
- package/dist/operator/operator-trigger-loop.d.ts.map +0 -1
- package/dist/operator/operator-trigger-loop.js +0 -827
- package/dist/operator/operator-trigger-loop.js.map +0 -1
- package/dist/operator/owner-action-effects.d.ts +0 -112
- package/dist/operator/owner-action-effects.d.ts.map +0 -1
- package/dist/operator/owner-action-effects.js +0 -375
- package/dist/operator/owner-action-effects.js.map +0 -1
- package/dist/operator/owner-event-effects.d.ts +0 -65
- package/dist/operator/owner-event-effects.d.ts.map +0 -1
- package/dist/operator/owner-event-effects.js +0 -249
- package/dist/operator/owner-event-effects.js.map +0 -1
- package/dist/operator/owner-event-inbox.d.ts +0 -124
- package/dist/operator/owner-event-inbox.d.ts.map +0 -1
- package/dist/operator/owner-event-inbox.js +0 -440
- package/dist/operator/owner-event-inbox.js.map +0 -1
- package/dist/operator/owner-event-loop.d.ts +0 -99
- package/dist/operator/owner-event-loop.d.ts.map +0 -1
- package/dist/operator/owner-event-loop.js +0 -253
- package/dist/operator/owner-event-loop.js.map +0 -1
- package/dist/operator/owner-event-outcome.d.ts +0 -36
- package/dist/operator/owner-event-outcome.d.ts.map +0 -1
- package/dist/operator/owner-event-outcome.js +0 -174
- package/dist/operator/owner-event-outcome.js.map +0 -1
- package/dist/operator/owner-event-policy.d.ts +0 -40
- package/dist/operator/owner-event-policy.d.ts.map +0 -1
- package/dist/operator/owner-event-policy.js +0 -75
- package/dist/operator/owner-event-policy.js.map +0 -1
- package/dist/operator/owner-event-prompt.d.ts +0 -21
- package/dist/operator/owner-event-prompt.d.ts.map +0 -1
- package/dist/operator/owner-event-prompt.js +0 -69
- package/dist/operator/owner-event-prompt.js.map +0 -1
- package/dist/operator/owner-runtime-journal.d.ts +0 -21
- package/dist/operator/owner-runtime-journal.d.ts.map +0 -1
- package/dist/operator/owner-runtime-journal.js +0 -135
- package/dist/operator/owner-runtime-journal.js.map +0 -1
- package/dist/operator/owner-runtime.d.ts +0 -48
- package/dist/operator/owner-runtime.d.ts.map +0 -1
- package/dist/operator/owner-runtime.js +0 -99
- package/dist/operator/owner-runtime.js.map +0 -1
- package/dist/operator/pending-report-store.d.ts +0 -99
- package/dist/operator/pending-report-store.d.ts.map +0 -1
- package/dist/operator/pending-report-store.js +0 -554
- package/dist/operator/pending-report-store.js.map +0 -1
- package/dist/operator/procedure-activation.d.ts +0 -7
- package/dist/operator/procedure-activation.d.ts.map +0 -1
- package/dist/operator/procedure-activation.js +0 -132
- package/dist/operator/procedure-activation.js.map +0 -1
- package/dist/operator/procedure-projection.d.ts +0 -25
- package/dist/operator/procedure-projection.d.ts.map +0 -1
- package/dist/operator/procedure-projection.js +0 -80
- package/dist/operator/procedure-projection.js.map +0 -1
- package/dist/operator/procedure-runtime.d.ts +0 -45
- package/dist/operator/procedure-runtime.d.ts.map +0 -1
- package/dist/operator/procedure-runtime.js +0 -496
- package/dist/operator/procedure-runtime.js.map +0 -1
- package/dist/operator/procedure-store.d.ts +0 -97
- package/dist/operator/procedure-store.d.ts.map +0 -1
- package/dist/operator/procedure-store.js +0 -368
- package/dist/operator/procedure-store.js.map +0 -1
- package/dist/operator/provenance-lookup.d.ts +0 -18
- package/dist/operator/provenance-lookup.d.ts.map +0 -1
- package/dist/operator/provenance-lookup.js +0 -54
- package/dist/operator/provenance-lookup.js.map +0 -1
- package/dist/operator/repair-request.d.ts +0 -29
- package/dist/operator/repair-request.d.ts.map +0 -1
- package/dist/operator/repair-request.js +0 -115
- package/dist/operator/repair-request.js.map +0 -1
- package/dist/operator/report-carry-delivery.d.ts +0 -35
- package/dist/operator/report-carry-delivery.d.ts.map +0 -1
- package/dist/operator/report-carry-delivery.js +0 -55
- package/dist/operator/report-carry-delivery.js.map +0 -1
- package/dist/operator/report-carry.d.ts +0 -66
- package/dist/operator/report-carry.d.ts.map +0 -1
- package/dist/operator/report-carry.js +0 -352
- package/dist/operator/report-carry.js.map +0 -1
- package/dist/operator/report-delivery-coordinator.d.ts +0 -84
- package/dist/operator/report-delivery-coordinator.d.ts.map +0 -1
- package/dist/operator/report-delivery-coordinator.js +0 -146
- package/dist/operator/report-delivery-coordinator.js.map +0 -1
- package/dist/operator/report-run.d.ts +0 -52
- package/dist/operator/report-run.d.ts.map +0 -1
- package/dist/operator/report-run.js +0 -32
- package/dist/operator/report-run.js.map +0 -1
- package/dist/operator/report-scheduler.d.ts +0 -66
- package/dist/operator/report-scheduler.d.ts.map +0 -1
- package/dist/operator/report-scheduler.js +0 -135
- package/dist/operator/report-scheduler.js.map +0 -1
- package/dist/operator/runtime-config.d.ts +0 -10
- package/dist/operator/runtime-config.d.ts.map +0 -1
- package/dist/operator/runtime-config.js +0 -21
- package/dist/operator/runtime-config.js.map +0 -1
- package/dist/operator/situation-report.d.ts +0 -197
- package/dist/operator/situation-report.d.ts.map +0 -1
- package/dist/operator/situation-report.js +0 -462
- package/dist/operator/situation-report.js.map +0 -1
- package/dist/operator/subagent-stimulus.d.ts +0 -34
- package/dist/operator/subagent-stimulus.d.ts.map +0 -1
- package/dist/operator/subagent-stimulus.js +0 -145
- package/dist/operator/subagent-stimulus.js.map +0 -1
- package/dist/operator/task-ledger.d.ts +0 -879
- package/dist/operator/task-ledger.d.ts.map +0 -1
- package/dist/operator/task-ledger.js +0 -3601
- package/dist/operator/task-ledger.js.map +0 -1
- package/dist/operator/task-list-views.d.ts +0 -91
- package/dist/operator/task-list-views.d.ts.map +0 -1
- package/dist/operator/task-list-views.js +0 -532
- package/dist/operator/task-list-views.js.map +0 -1
- package/dist/operator/task-temporal.d.ts +0 -24
- package/dist/operator/task-temporal.d.ts.map +0 -1
- package/dist/operator/task-temporal.js +0 -123
- package/dist/operator/task-temporal.js.map +0 -1
- package/dist/operator/temporal-effect.d.ts +0 -65
- package/dist/operator/temporal-effect.d.ts.map +0 -1
- package/dist/operator/temporal-effect.js +0 -71
- package/dist/operator/temporal-effect.js.map +0 -1
- package/dist/operator/temporal-reconcile.d.ts +0 -49
- package/dist/operator/temporal-reconcile.d.ts.map +0 -1
- package/dist/operator/temporal-reconcile.js +0 -231
- package/dist/operator/temporal-reconcile.js.map +0 -1
- package/dist/operator/temporal-runtime.d.ts +0 -51
- package/dist/operator/temporal-runtime.d.ts.map +0 -1
- package/dist/operator/temporal-runtime.js +0 -104
- package/dist/operator/temporal-runtime.js.map +0 -1
- package/dist/operator/temporal-worker.d.ts +0 -18
- package/dist/operator/temporal-worker.d.ts.map +0 -1
- package/dist/operator/temporal-worker.js +0 -82
- package/dist/operator/temporal-worker.js.map +0 -1
- package/dist/operator/thread-brief-memory.d.ts +0 -29
- package/dist/operator/thread-brief-memory.d.ts.map +0 -1
- package/dist/operator/thread-brief-memory.js +0 -61
- package/dist/operator/thread-brief-memory.js.map +0 -1
- package/dist/operator/trigger-author.d.ts +0 -63
- package/dist/operator/trigger-author.d.ts.map +0 -1
- package/dist/operator/trigger-author.js +0 -384
- package/dist/operator/trigger-author.js.map +0 -1
- package/dist/operator/trigger-evolve.d.ts +0 -31
- package/dist/operator/trigger-evolve.d.ts.map +0 -1
- package/dist/operator/trigger-evolve.js +0 -51
- package/dist/operator/trigger-evolve.js.map +0 -1
- package/dist/operator/trigger-fire.d.ts +0 -29
- package/dist/operator/trigger-fire.d.ts.map +0 -1
- package/dist/operator/trigger-fire.js +0 -41
- package/dist/operator/trigger-fire.js.map +0 -1
- package/dist/operator/trigger-matcher.d.ts +0 -19
- package/dist/operator/trigger-matcher.d.ts.map +0 -1
- package/dist/operator/trigger-matcher.js +0 -65
- package/dist/operator/trigger-matcher.js.map +0 -1
- package/dist/operator/trigger-registry.d.ts +0 -58
- package/dist/operator/trigger-registry.d.ts.map +0 -1
- package/dist/operator/trigger-registry.js +0 -349
- package/dist/operator/trigger-registry.js.map +0 -1
- package/dist/operator/trigger-review.d.ts +0 -23
- package/dist/operator/trigger-review.d.ts.map +0 -1
- package/dist/operator/trigger-review.js +0 -193
- package/dist/operator/trigger-review.js.map +0 -1
- package/dist/operator/trigger-types.d.ts +0 -95
- package/dist/operator/trigger-types.d.ts.map +0 -1
- package/dist/operator/trigger-types.js +0 -14
- package/dist/operator/trigger-types.js.map +0 -1
- package/dist/operator/wiki-continuity.d.ts +0 -153
- package/dist/operator/wiki-continuity.d.ts.map +0 -1
- package/dist/operator/wiki-continuity.js +0 -221
- package/dist/operator/wiki-continuity.js.map +0 -1
- package/dist/operator/worker-run.d.ts +0 -109
- package/dist/operator/worker-run.d.ts.map +0 -1
- package/dist/operator/worker-run.js +0 -131
- package/dist/operator/worker-run.js.map +0 -1
- package/dist/operator/workorder-consumer.d.ts +0 -294
- package/dist/operator/workorder-consumer.d.ts.map +0 -1
- package/dist/operator/workorder-consumer.js +0 -1108
- package/dist/operator/workorder-consumer.js.map +0 -1
- package/dist/operator/workorder-hooks.d.ts +0 -162
- package/dist/operator/workorder-hooks.d.ts.map +0 -1
- package/dist/operator/workorder-hooks.js +0 -342
- package/dist/operator/workorder-hooks.js.map +0 -1
- package/dist/operator/workorder-publishers.d.ts +0 -117
- package/dist/operator/workorder-publishers.d.ts.map +0 -1
- package/dist/operator/workorder-publishers.js +0 -544
- package/dist/operator/workorder-publishers.js.map +0 -1
- package/dist/runners/cli-runner.d.ts +0 -59
- package/dist/runners/cli-runner.d.ts.map +0 -1
- package/dist/runners/cli-runner.js +0 -191
- package/dist/runners/cli-runner.js.map +0 -1
- package/dist/runners/index.d.ts +0 -11
- package/dist/runners/index.d.ts.map +0 -1
- package/dist/runners/index.js +0 -15
- package/dist/runners/index.js.map +0 -1
- package/dist/runners/types.d.ts +0 -81
- package/dist/runners/types.d.ts.map +0 -1
- package/dist/runners/types.js +0 -31
- package/dist/runners/types.js.map +0 -1
- package/dist/scheduler/cron-result-router.d.ts +0 -24
- package/dist/scheduler/cron-result-router.d.ts.map +0 -1
- package/dist/scheduler/cron-result-router.js +0 -63
- package/dist/scheduler/cron-result-router.js.map +0 -1
- package/dist/scheduler/cron-scheduler.d.ts +0 -115
- package/dist/scheduler/cron-scheduler.d.ts.map +0 -1
- package/dist/scheduler/cron-scheduler.js +0 -336
- package/dist/scheduler/cron-scheduler.js.map +0 -1
- package/dist/scheduler/cron-worker.d.ts +0 -39
- package/dist/scheduler/cron-worker.d.ts.map +0 -1
- package/dist/scheduler/cron-worker.js +0 -94
- package/dist/scheduler/cron-worker.js.map +0 -1
- package/dist/scheduler/heartbeat.d.ts +0 -64
- package/dist/scheduler/heartbeat.d.ts.map +0 -1
- package/dist/scheduler/heartbeat.js +0 -197
- package/dist/scheduler/heartbeat.js.map +0 -1
- package/dist/scheduler/index.d.ts +0 -26
- package/dist/scheduler/index.d.ts.map +0 -1
- package/dist/scheduler/index.js +0 -37
- package/dist/scheduler/index.js.map +0 -1
- package/dist/scheduler/job-lock.d.ts +0 -85
- package/dist/scheduler/job-lock.d.ts.map +0 -1
- package/dist/scheduler/job-lock.js +0 -137
- package/dist/scheduler/job-lock.js.map +0 -1
- package/dist/scheduler/recovery.d.ts +0 -78
- package/dist/scheduler/recovery.d.ts.map +0 -1
- package/dist/scheduler/recovery.js +0 -124
- package/dist/scheduler/recovery.js.map +0 -1
- package/dist/scheduler/schedule-store.d.ts +0 -112
- package/dist/scheduler/schedule-store.d.ts.map +0 -1
- package/dist/scheduler/schedule-store.js +0 -259
- package/dist/scheduler/schedule-store.js.map +0 -1
- package/dist/scheduler/token-keep-alive.d.ts +0 -49
- package/dist/scheduler/token-keep-alive.d.ts.map +0 -1
- package/dist/scheduler/token-keep-alive.js +0 -102
- package/dist/scheduler/token-keep-alive.js.map +0 -1
- package/dist/scheduler/types.d.ts +0 -98
- package/dist/scheduler/types.d.ts.map +0 -1
- package/dist/scheduler/types.js +0 -21
- package/dist/scheduler/types.js.map +0 -1
- package/dist/security/security-monitor.d.ts +0 -56
- package/dist/security/security-monitor.d.ts.map +0 -1
- package/dist/security/security-monitor.js +0 -779
- package/dist/security/security-monitor.js.map +0 -1
- package/dist/security/trusted-proxy.d.ts +0 -9
- package/dist/security/trusted-proxy.d.ts.map +0 -1
- package/dist/security/trusted-proxy.js +0 -36
- package/dist/security/trusted-proxy.js.map +0 -1
- package/dist/skills/index.d.ts +0 -10
- package/dist/skills/index.d.ts.map +0 -1
- package/dist/skills/index.js +0 -26
- package/dist/skills/index.js.map +0 -1
- package/dist/skills/skill-executor.d.ts +0 -48
- package/dist/skills/skill-executor.d.ts.map +0 -1
- package/dist/skills/skill-executor.js +0 -483
- package/dist/skills/skill-executor.js.map +0 -1
- package/dist/skills/skill-loader.d.ts +0 -40
- package/dist/skills/skill-loader.d.ts.map +0 -1
- package/dist/skills/skill-loader.js +0 -233
- package/dist/skills/skill-loader.js.map +0 -1
- package/dist/skills/skill-matcher.d.ts +0 -33
- package/dist/skills/skill-matcher.d.ts.map +0 -1
- package/dist/skills/skill-matcher.js +0 -190
- package/dist/skills/skill-matcher.js.map +0 -1
- package/dist/skills/skill-registry.d.ts +0 -117
- package/dist/skills/skill-registry.d.ts.map +0 -1
- package/dist/skills/skill-registry.js +0 -627
- package/dist/skills/skill-registry.js.map +0 -1
- package/dist/skills/types.d.ts +0 -131
- package/dist/skills/types.d.ts.map +0 -1
- package/dist/skills/types.js +0 -12
- package/dist/skills/types.js.map +0 -1
- package/dist/utils/log-sanitizer.d.ts +0 -79
- package/dist/utils/log-sanitizer.d.ts.map +0 -1
- package/dist/utils/log-sanitizer.js +0 -215
- package/dist/utils/log-sanitizer.js.map +0 -1
- package/dist/validation/session-service.d.ts +0 -72
- package/dist/validation/session-service.d.ts.map +0 -1
- package/dist/validation/session-service.js +0 -298
- package/dist/validation/session-service.js.map +0 -1
- package/dist/validation/store.d.ts +0 -25
- package/dist/validation/store.d.ts.map +0 -1
- package/dist/validation/store.js +0 -200
- package/dist/validation/store.js.map +0 -1
- package/dist/validation/types.d.ts +0 -119
- package/dist/validation/types.d.ts.map +0 -1
- package/dist/validation/types.js +0 -57
- package/dist/validation/types.js.map +0 -1
- package/dist/wiki/wiki-turn-contract.d.ts +0 -19
- package/dist/wiki/wiki-turn-contract.d.ts.map +0 -1
- package/dist/wiki/wiki-turn-contract.js +0 -60
- package/dist/wiki/wiki-turn-contract.js.map +0 -1
- package/public/viewer/js/utils/ui-commands.js +0 -88
- package/public/viewer/src/utils/ui-commands.ts +0 -114
- package/scripts/attachment/extract-office-text.js +0 -179
- package/scripts/attachment/extract-pdf-text.swift +0 -36
- package/scripts/backfill-channel-keys.ts +0 -509
- package/scripts/crack-failure-digests.ts +0 -55
- package/scripts/generate-gateway-tools.ts +0 -131
- package/scripts/image/fb-overlay.py +0 -128
- package/scripts/image/ocr-image.py +0 -38
- package/scripts/postinstall.js +0 -161
- package/scripts/setup-ocr.js +0 -120
- package/templates/AGENTS.claude.md +0 -23
- package/templates/AGENTS.codex.md +0 -11
- package/templates/bmad/LICENSE +0 -28
- package/templates/bmad/architecture.md +0 -343
- package/templates/bmad/bmm-workflow-status.template.yaml +0 -66
- package/templates/bmad/prd.md +0 -198
- package/templates/bmad/product-brief.md +0 -149
- package/templates/bmad/sprint-status.template.yaml +0 -35
- package/templates/bmad/tech-spec.md +0 -151
- package/templates/entity-audit-fixtures/cross-language-aliases.json +0 -28
- package/templates/entity-audit-fixtures/gold-canonical-identities.json +0 -46
- package/templates/skills/danggeun-monitor.md +0 -88
- package/templates/skills/document-analyze.md +0 -63
- package/templates/skills/frontend-design.md +0 -71
- package/templates/skills/image-translate.md +0 -62
- package/templates/skills/multi-agent-collab.md +0 -145
- package/templates/skills/scheduling.md +0 -107
- package/templates/workspace/skill-forge/DESIGN.md +0 -115
- package/templates/workspace/skill-forge/agents/architect.ts +0 -295
- package/templates/workspace/skill-forge/agents/developer.ts +0 -364
- package/templates/workspace/skill-forge/agents/qa.ts +0 -313
- package/templates/workspace/skill-forge/claude-api.ts +0 -353
- package/templates/workspace/skill-forge/discord-ui.ts +0 -580
- package/templates/workspace/skill-forge/error-handler.ts +0 -354
- package/templates/workspace/skill-forge/mama-integration.ts +0 -357
- package/templates/workspace/skill-forge/orchestrator.ts +0 -495
- package/templates/workspace/skill-forge/output/generated-skills/skills/hello-world/README.md +0 -24
- package/templates/workspace/skill-forge/output/generated-skills/skills/hello-world/index.ts +0 -79
- package/templates/workspace/skill-forge/output/generated-skills/skills/hello-world/types.ts +0 -17
- package/templates/workspace/skill-forge/package.json +0 -21
- package/templates/workspace/skill-forge/state/session.json +0 -132
- package/templates/workspace/skill-forge/test-e2e.ts +0 -139
- package/templates/workspace/skill-forge/tsconfig.json +0 -20
- package/templates/workspace/skill-forge/types.ts +0 -159
package/dist/api/graph-api.js
DELETED
|
@@ -1,3460 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* MAMA Graph API
|
|
4
|
-
*
|
|
5
|
-
* HTTP API endpoints for the Viewer.
|
|
6
|
-
* Provides /graph endpoint for fetching decisions and edges data.
|
|
7
|
-
* Provides /viewer endpoint for serving HTML viewer.
|
|
8
|
-
*/
|
|
9
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
-
};
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.viewerCssPath = exports.viewerHtmlPath = exports.DEFAULT_GRAPH_LIMIT = void 0;
|
|
14
|
-
exports.createGraphHandler = createGraphHandler;
|
|
15
|
-
exports.mapDecisionRowToGraphNode = mapDecisionRowToGraphNode;
|
|
16
|
-
exports.parseGraphLimit = parseGraphLimit;
|
|
17
|
-
exports.buildGraphMeta = buildGraphMeta;
|
|
18
|
-
exports.validateConfigUpdate = validateConfigUpdate;
|
|
19
|
-
exports.migrateLegacyManagedBackends = migrateLegacyManagedBackends;
|
|
20
|
-
exports.getAllNodes = getAllNodes;
|
|
21
|
-
exports.getAllEdges = getAllEdges;
|
|
22
|
-
exports.getAllCheckpoints = getAllCheckpoints;
|
|
23
|
-
exports.getUniqueTopics = getUniqueTopics;
|
|
24
|
-
exports.filterNodesByTopic = filterNodesByTopic;
|
|
25
|
-
exports.filterEdgesByNodes = filterEdgesByNodes;
|
|
26
|
-
const fs_1 = __importDefault(require("fs"));
|
|
27
|
-
const path_1 = __importDefault(require("path"));
|
|
28
|
-
const os_1 = __importDefault(require("os"));
|
|
29
|
-
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
30
|
-
const auth_middleware_js_1 = require("./auth-middleware.js");
|
|
31
|
-
const trusted_proxy_js_1 = require("../security/trusted-proxy.js");
|
|
32
|
-
const run_context_registry_js_1 = require("../agent/code-act/run-context-registry.js");
|
|
33
|
-
const backend_model_policy_js_1 = require("../agent/backend-model-policy.js");
|
|
34
|
-
const types_js_1 = require("../cli/config/types.js");
|
|
35
|
-
const agent_handler_js_1 = require("./agent-handler.js");
|
|
36
|
-
const ui_command_handler_js_1 = require("./ui-command-handler.js");
|
|
37
|
-
const entity_review_handler_js_1 = require("./entity-review-handler.js");
|
|
38
|
-
const entity_audit_handler_js_1 = require("./entity-audit-handler.js");
|
|
39
|
-
const entity_audit_queue_js_1 = require("./entity-audit-queue.js");
|
|
40
|
-
const entity_audit_runner_js_1 = require("./entity-audit-runner.js");
|
|
41
|
-
const store_js_1 = require("../validation/store.js");
|
|
42
|
-
// mama-core is pure JS with no .d.ts — require + any is intentional
|
|
43
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
44
|
-
const { getAdapter, initDB, vectorSearch } = require('@jungjaehoon/mama-core/memory-store');
|
|
45
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
46
|
-
const { DebugLogger } = require('@jungjaehoon/mama-core/debug-logger');
|
|
47
|
-
const logger = new DebugLogger('GraphAPI');
|
|
48
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
49
|
-
const { generateEmbedding } = require('@jungjaehoon/mama-core/embeddings');
|
|
50
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
51
|
-
const mama = require('@jungjaehoon/mama-core/mama-api');
|
|
52
|
-
// Config paths
|
|
53
|
-
const MAMA_CONFIG_PATH = path_1.default.join(os_1.default.homedir(), '.mama', 'config.yaml');
|
|
54
|
-
const PACKAGE_ROOT_DIR = path_1.default.resolve(__dirname, '../..');
|
|
55
|
-
// Paths to viewer files (now in public/viewer/). Resolved per request so the
|
|
56
|
-
// MAMA_VIEWER_DIR override works for tests without module-load ordering games.
|
|
57
|
-
function getViewerDirectory() {
|
|
58
|
-
if (process.env.MAMA_VIEWER_DIR) {
|
|
59
|
-
// resolve() drops trailing slashes; without it the `operatorRoot + path.sep`
|
|
60
|
-
// traversal guard in the /viewer/operator route would 404 every request for
|
|
61
|
-
// '/foo/bar/'-style values.
|
|
62
|
-
return path_1.default.resolve(process.env.MAMA_VIEWER_DIR);
|
|
63
|
-
}
|
|
64
|
-
const packagePublicViewer = path_1.default.join(PACKAGE_ROOT_DIR, 'public', 'viewer');
|
|
65
|
-
const candidateDirs = [
|
|
66
|
-
path_1.default.join(process.cwd(), 'public', 'viewer'),
|
|
67
|
-
packagePublicViewer,
|
|
68
|
-
path_1.default.join(__dirname, '../../public/viewer'),
|
|
69
|
-
path_1.default.join(__dirname, '../../../public/viewer'),
|
|
70
|
-
path_1.default.join(process.cwd(), 'packages', 'standalone', 'public', 'viewer'),
|
|
71
|
-
];
|
|
72
|
-
for (const candidate of candidateDirs) {
|
|
73
|
-
if (fs_1.default.existsSync(candidate) && fs_1.default.statSync(candidate).isDirectory()) {
|
|
74
|
-
return candidate;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
// Fallback for unusual launch locations.
|
|
78
|
-
return path_1.default.join(process.cwd(), 'public', 'viewer');
|
|
79
|
-
}
|
|
80
|
-
const viewerHtmlPath = () => path_1.default.join(getViewerDirectory(), 'viewer.html');
|
|
81
|
-
exports.viewerHtmlPath = viewerHtmlPath;
|
|
82
|
-
const viewerCssPath = () => path_1.default.join(getViewerDirectory(), 'viewer.css');
|
|
83
|
-
exports.viewerCssPath = viewerCssPath;
|
|
84
|
-
const swJsPath = () => path_1.default.join(getViewerDirectory(), 'sw.js');
|
|
85
|
-
const manifestJsonPath = () => path_1.default.join(getViewerDirectory(), 'manifest.json');
|
|
86
|
-
const viewerIconDir = () => path_1.default.join(getViewerDirectory(), 'icons');
|
|
87
|
-
const viewerFaviconPath = () => path_1.default.join(getViewerDirectory(), '..', 'favicon.ico');
|
|
88
|
-
const viewerOperatorDir = () => path_1.default.join(getViewerDirectory(), 'operator');
|
|
89
|
-
// Operator bundle assets live under public/viewer/operator/ and are the only
|
|
90
|
-
// extensions that route serves.
|
|
91
|
-
const VIEWER_OPERATOR_MIME = {
|
|
92
|
-
'.js': 'application/javascript',
|
|
93
|
-
'.css': 'text/css',
|
|
94
|
-
};
|
|
95
|
-
const DEFAULT_GRAPH_LIMIT = 300;
|
|
96
|
-
exports.DEFAULT_GRAPH_LIMIT = DEFAULT_GRAPH_LIMIT;
|
|
97
|
-
const MAX_GRAPH_LIMIT = 2000;
|
|
98
|
-
const GRAPH_PREVIEW_CHARS = 220;
|
|
99
|
-
const SIMILAR_QUERY_DECISION_CHARS = 400;
|
|
100
|
-
const CODE_ACT_RATE_LIMIT_WINDOW_MS = 60_000;
|
|
101
|
-
const CODE_ACT_RATE_LIMIT_TTL_MS = CODE_ACT_RATE_LIMIT_WINDOW_MS * 5;
|
|
102
|
-
const CODE_ACT_RATE_LIMIT_DEFAULT_MAX = 30;
|
|
103
|
-
const codeActRateBuckets = new Map();
|
|
104
|
-
// Model pattern helpers (used in multiple validation functions)
|
|
105
|
-
const isClaudeModel = (model) => /^claude-/i.test(model);
|
|
106
|
-
const isCodexModel = (model) => /^(gpt-|o\d|codex)/i.test(model);
|
|
107
|
-
const supportedManagedBackends = ['claude', 'codex', 'cline'];
|
|
108
|
-
const isCodexFamilyBackend = (backend) => backend === 'codex';
|
|
109
|
-
const VALIDATION_TRIGGER_TYPES = new Set([
|
|
110
|
-
'agent_test',
|
|
111
|
-
'delegate_run',
|
|
112
|
-
'system_run',
|
|
113
|
-
'audit',
|
|
114
|
-
]);
|
|
115
|
-
const isOpus46Model = (model) => /^claude-opus-4-6(?:$|-)/i.test(model) || model.toLowerCase() === 'claude-opus-4-latest';
|
|
116
|
-
const VALID_EFFORT_LEVELS = new Set(['low', 'medium', 'high', 'max']);
|
|
117
|
-
function normalizeLegacyManagedBackend(backend, configPath) {
|
|
118
|
-
if (typeof backend === 'string' && backend.toLowerCase() === 'codex-mcp') {
|
|
119
|
-
console.warn(`[GraphAPI] Deprecated backend "codex-mcp" at ${configPath}; using "codex" app-server for compatibility.`);
|
|
120
|
-
return 'codex';
|
|
121
|
-
}
|
|
122
|
-
if (typeof backend === 'string' && backend.toLowerCase() === 'gemini') {
|
|
123
|
-
console.warn(`[GraphAPI] Deprecated backend "gemini" at ${configPath}; using "claude" for compatibility.`);
|
|
124
|
-
return 'claude';
|
|
125
|
-
}
|
|
126
|
-
return backend;
|
|
127
|
-
}
|
|
128
|
-
function normalizeLegacyManagedModel(agent, configPath) {
|
|
129
|
-
if (typeof agent.model === 'string' && !isClaudeModel(agent.model)) {
|
|
130
|
-
console.warn(`[GraphAPI] Deprecated Gemini model at ${configPath}; using "claude-sonnet-4-6" for compatibility.`);
|
|
131
|
-
agent.model = 'claude-sonnet-4-6';
|
|
132
|
-
return true;
|
|
133
|
-
}
|
|
134
|
-
return false;
|
|
135
|
-
}
|
|
136
|
-
function isLegacyGeminiBackend(backend) {
|
|
137
|
-
return typeof backend === 'string' && backend.toLowerCase() === 'gemini';
|
|
138
|
-
}
|
|
139
|
-
function isRecord(value) {
|
|
140
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
141
|
-
}
|
|
142
|
-
function migrateLegacyManagedBackends(config) {
|
|
143
|
-
let migrated = false;
|
|
144
|
-
const next = { ...config };
|
|
145
|
-
const originalAgent = isRecord(config.agent) ? config.agent : undefined;
|
|
146
|
-
const originalAgentBackend = originalAgent?.backend;
|
|
147
|
-
if (isRecord(next.agent)) {
|
|
148
|
-
const agent = { ...next.agent };
|
|
149
|
-
const backend = normalizeLegacyManagedBackend(agent.backend, 'agent.backend');
|
|
150
|
-
if (backend !== agent.backend) {
|
|
151
|
-
const migrateModel = isLegacyGeminiBackend(agent.backend);
|
|
152
|
-
agent.backend = backend;
|
|
153
|
-
if (migrateModel) {
|
|
154
|
-
normalizeLegacyManagedModel(agent, 'agent.model');
|
|
155
|
-
}
|
|
156
|
-
next.agent = agent;
|
|
157
|
-
migrated = true;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
if (isRecord(next.multi_agent)) {
|
|
161
|
-
const multiAgent = { ...next.multi_agent };
|
|
162
|
-
const originalMultiAgent = isRecord(config.multi_agent) ? config.multi_agent : {};
|
|
163
|
-
const originalMultiAgentBackend = originalMultiAgent.backend;
|
|
164
|
-
const normalizedMultiAgentBackend = normalizeLegacyManagedBackend(originalMultiAgentBackend, 'multi_agent.backend');
|
|
165
|
-
if (normalizedMultiAgentBackend !== originalMultiAgentBackend) {
|
|
166
|
-
multiAgent.backend = normalizedMultiAgentBackend;
|
|
167
|
-
migrated = true;
|
|
168
|
-
}
|
|
169
|
-
const inheritedBackend = originalMultiAgentBackend ?? originalAgentBackend;
|
|
170
|
-
const normalizedInheritedBackend = normalizeLegacyManagedBackend(inheritedBackend, originalMultiAgentBackend !== undefined ? 'multi_agent.backend' : 'agent.backend');
|
|
171
|
-
if (isRecord(multiAgent.agents)) {
|
|
172
|
-
const agents = { ...multiAgent.agents };
|
|
173
|
-
let agentsMigrated = false;
|
|
174
|
-
for (const [agentId, agentConfig] of Object.entries(agents)) {
|
|
175
|
-
if (!isRecord(agentConfig)) {
|
|
176
|
-
continue;
|
|
177
|
-
}
|
|
178
|
-
const agent = { ...agentConfig };
|
|
179
|
-
const hasExplicitBackend = Object.prototype.hasOwnProperty.call(agent, 'backend');
|
|
180
|
-
const priorEffectiveBackend = hasExplicitBackend ? agent.backend : inheritedBackend;
|
|
181
|
-
const normalizedBackend = normalizeLegacyManagedBackend(priorEffectiveBackend, `multi_agent.agents.${agentId}.backend`);
|
|
182
|
-
const inheritedBackendWasNormalized = !hasExplicitBackend && normalizedInheritedBackend !== inheritedBackend;
|
|
183
|
-
if (normalizedBackend !== priorEffectiveBackend || inheritedBackendWasNormalized) {
|
|
184
|
-
agent.backend = normalizedBackend;
|
|
185
|
-
if (isLegacyGeminiBackend(priorEffectiveBackend)) {
|
|
186
|
-
normalizeLegacyManagedModel(agent, `multi_agent.agents.${agentId}.model`);
|
|
187
|
-
}
|
|
188
|
-
agents[agentId] = agent;
|
|
189
|
-
agentsMigrated = true;
|
|
190
|
-
migrated = true;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
if (agentsMigrated) {
|
|
194
|
-
multiAgent.agents = agents;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
if (migrated) {
|
|
198
|
-
next.multi_agent = multiAgent;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
return (migrated ? next : config);
|
|
202
|
-
}
|
|
203
|
-
function getCodeActRateLimitMax() {
|
|
204
|
-
const raw = process.env.MAMA_CODE_ACT_RATE_LIMIT_PER_MINUTE;
|
|
205
|
-
if (!raw) {
|
|
206
|
-
return CODE_ACT_RATE_LIMIT_DEFAULT_MAX;
|
|
207
|
-
}
|
|
208
|
-
const parsed = Number.parseInt(raw, 10);
|
|
209
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : CODE_ACT_RATE_LIMIT_DEFAULT_MAX;
|
|
210
|
-
}
|
|
211
|
-
function getCodeActClientKey(req) {
|
|
212
|
-
return (0, trusted_proxy_js_1.getForwardedClientAddress)(req);
|
|
213
|
-
}
|
|
214
|
-
function pruneCodeActRateBuckets(now) {
|
|
215
|
-
for (const [clientKey, bucket] of codeActRateBuckets.entries()) {
|
|
216
|
-
if (now - bucket.lastSeenMs > CODE_ACT_RATE_LIMIT_TTL_MS) {
|
|
217
|
-
codeActRateBuckets.delete(clientKey);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
function checkCodeActRateLimit(req) {
|
|
222
|
-
const now = Date.now();
|
|
223
|
-
pruneCodeActRateBuckets(now);
|
|
224
|
-
const clientKey = getCodeActClientKey(req);
|
|
225
|
-
const limit = getCodeActRateLimitMax();
|
|
226
|
-
const existing = codeActRateBuckets.get(clientKey);
|
|
227
|
-
if (!existing || now - existing.windowStartMs >= CODE_ACT_RATE_LIMIT_WINDOW_MS) {
|
|
228
|
-
codeActRateBuckets.set(clientKey, { windowStartMs: now, count: 1, lastSeenMs: now });
|
|
229
|
-
return { allowed: true, clientKey };
|
|
230
|
-
}
|
|
231
|
-
existing.lastSeenMs = now;
|
|
232
|
-
if (existing.count >= limit) {
|
|
233
|
-
return {
|
|
234
|
-
allowed: false,
|
|
235
|
-
clientKey,
|
|
236
|
-
retryAfterSeconds: Math.max(1, Math.ceil((CODE_ACT_RATE_LIMIT_WINDOW_MS - (now - existing.windowStartMs)) / 1000)),
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
existing.count++;
|
|
240
|
-
return { allowed: true, clientKey };
|
|
241
|
-
}
|
|
242
|
-
// Allowed directories for persona files (security: prevent arbitrary file read)
|
|
243
|
-
const ALLOWED_PERSONA_DIRS = [
|
|
244
|
-
path_1.default.join(os_1.default.homedir(), '.mama', 'personas'),
|
|
245
|
-
path_1.default.join(os_1.default.homedir(), '.mama', 'workspace'),
|
|
246
|
-
];
|
|
247
|
-
/**
|
|
248
|
-
* Validate persona_file path to prevent arbitrary file read attacks.
|
|
249
|
-
* Only allows paths within ~/.mama/personas/ or ~/.mama/workspace/.
|
|
250
|
-
* Uses fs.realpathSync to resolve symlinks and prevent symlink escape attacks.
|
|
251
|
-
*/
|
|
252
|
-
function isValidPersonaPath(filePath) {
|
|
253
|
-
if (!filePath) {
|
|
254
|
-
return false;
|
|
255
|
-
}
|
|
256
|
-
const expandedPath = filePath.startsWith('~/')
|
|
257
|
-
? path_1.default.join(os_1.default.homedir(), filePath.slice(2))
|
|
258
|
-
: path_1.default.resolve(filePath);
|
|
259
|
-
const normalizedPath = path_1.default.normalize(expandedPath);
|
|
260
|
-
let resolvedPath;
|
|
261
|
-
try {
|
|
262
|
-
resolvedPath = fs_1.default.realpathSync(normalizedPath);
|
|
263
|
-
}
|
|
264
|
-
catch {
|
|
265
|
-
// File doesn't exist or can't be resolved - reject
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
return ALLOWED_PERSONA_DIRS.some((dir) => resolvedPath.startsWith(dir + path_1.default.sep));
|
|
269
|
-
}
|
|
270
|
-
function buildDecisionPreview(decision) {
|
|
271
|
-
const normalized = decision.replace(/\s+/g, ' ').trim();
|
|
272
|
-
if (normalized.length <= GRAPH_PREVIEW_CHARS) {
|
|
273
|
-
return normalized;
|
|
274
|
-
}
|
|
275
|
-
return `${normalized.slice(0, GRAPH_PREVIEW_CHARS)}...`;
|
|
276
|
-
}
|
|
277
|
-
function mapDecisionRowToGraphNode(row) {
|
|
278
|
-
return {
|
|
279
|
-
id: row.id,
|
|
280
|
-
topic: row.topic,
|
|
281
|
-
decision_preview: buildDecisionPreview(row.decision),
|
|
282
|
-
outcome: row.outcome,
|
|
283
|
-
confidence: row.confidence,
|
|
284
|
-
created_at: row.created_at,
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
function parseGraphLimit(params) {
|
|
288
|
-
if (params.get('full') === 'true') {
|
|
289
|
-
return null;
|
|
290
|
-
}
|
|
291
|
-
const rawLimit = params.get('limit');
|
|
292
|
-
if (!rawLimit) {
|
|
293
|
-
return DEFAULT_GRAPH_LIMIT;
|
|
294
|
-
}
|
|
295
|
-
const parsed = parseInt(rawLimit, 10);
|
|
296
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
297
|
-
return DEFAULT_GRAPH_LIMIT;
|
|
298
|
-
}
|
|
299
|
-
return Math.min(parsed, MAX_GRAPH_LIMIT);
|
|
300
|
-
}
|
|
301
|
-
function buildGraphMeta(input) {
|
|
302
|
-
return {
|
|
303
|
-
total_nodes: input.returnedNodes,
|
|
304
|
-
total_edges: input.returnedEdges,
|
|
305
|
-
similarity_edges: input.similarityEdges,
|
|
306
|
-
partial: input.isPartial,
|
|
307
|
-
total_available_nodes: input.totalNodes,
|
|
308
|
-
total_available_edges: input.totalEdges,
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
async function getAllNodes(limit) {
|
|
312
|
-
const adapter = getAdapter();
|
|
313
|
-
const sql = `
|
|
314
|
-
SELECT
|
|
315
|
-
id,
|
|
316
|
-
topic,
|
|
317
|
-
decision,
|
|
318
|
-
outcome,
|
|
319
|
-
confidence,
|
|
320
|
-
created_at
|
|
321
|
-
FROM decisions
|
|
322
|
-
ORDER BY created_at DESC
|
|
323
|
-
`;
|
|
324
|
-
const stmt = adapter.prepare(limit ? `${sql}\nLIMIT ?` : sql);
|
|
325
|
-
const rows = (limit ? stmt.all(limit) : stmt.all());
|
|
326
|
-
return rows.map(mapDecisionRowToGraphNode);
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
|
-
* Fetch nodes by their IDs (for neighbor expansion).
|
|
330
|
-
* Returns only nodes whose IDs are in the given set.
|
|
331
|
-
*/
|
|
332
|
-
async function getNodesByIds(ids) {
|
|
333
|
-
if (ids.size === 0)
|
|
334
|
-
return [];
|
|
335
|
-
const adapter = getAdapter();
|
|
336
|
-
const placeholders = Array.from(ids)
|
|
337
|
-
.map(() => '?')
|
|
338
|
-
.join(',');
|
|
339
|
-
const stmt = adapter.prepare(`
|
|
340
|
-
SELECT id, topic, decision, outcome, confidence, created_at
|
|
341
|
-
FROM decisions
|
|
342
|
-
WHERE id IN (${placeholders})
|
|
343
|
-
`);
|
|
344
|
-
const rows = stmt.all(...Array.from(ids));
|
|
345
|
-
return rows.map(mapDecisionRowToGraphNode);
|
|
346
|
-
}
|
|
347
|
-
async function getDecisionDetail(id) {
|
|
348
|
-
const adapter = getAdapter();
|
|
349
|
-
const stmt = adapter.prepare(`
|
|
350
|
-
SELECT
|
|
351
|
-
id,
|
|
352
|
-
topic,
|
|
353
|
-
decision,
|
|
354
|
-
reasoning,
|
|
355
|
-
outcome,
|
|
356
|
-
confidence,
|
|
357
|
-
created_at
|
|
358
|
-
FROM decisions
|
|
359
|
-
WHERE id = ?
|
|
360
|
-
`);
|
|
361
|
-
const row = stmt.get(id);
|
|
362
|
-
if (!row) {
|
|
363
|
-
return null;
|
|
364
|
-
}
|
|
365
|
-
return {
|
|
366
|
-
id: row.id,
|
|
367
|
-
topic: row.topic,
|
|
368
|
-
decision: row.decision,
|
|
369
|
-
reasoning: row.reasoning,
|
|
370
|
-
outcome: row.outcome,
|
|
371
|
-
confidence: row.confidence,
|
|
372
|
-
created_at: row.created_at,
|
|
373
|
-
decision_preview: buildDecisionPreview(row.decision),
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
async function getAllEdges() {
|
|
377
|
-
const adapter = getAdapter();
|
|
378
|
-
const stmt = adapter.prepare(`
|
|
379
|
-
SELECT
|
|
380
|
-
from_id,
|
|
381
|
-
to_id,
|
|
382
|
-
relationship,
|
|
383
|
-
reason
|
|
384
|
-
FROM decision_edges
|
|
385
|
-
ORDER BY created_at DESC
|
|
386
|
-
`);
|
|
387
|
-
const rows = stmt.all();
|
|
388
|
-
return rows.map((row) => ({
|
|
389
|
-
from: row.from_id,
|
|
390
|
-
to: row.to_id,
|
|
391
|
-
relationship: row.relationship,
|
|
392
|
-
reason: row.reason,
|
|
393
|
-
}));
|
|
394
|
-
}
|
|
395
|
-
function safeParseJsonArray(value) {
|
|
396
|
-
try {
|
|
397
|
-
const parsed = JSON.parse(value);
|
|
398
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
399
|
-
}
|
|
400
|
-
catch {
|
|
401
|
-
return [];
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
async function getAllCheckpoints() {
|
|
405
|
-
const adapter = getAdapter();
|
|
406
|
-
const stmt = adapter.prepare(`
|
|
407
|
-
SELECT
|
|
408
|
-
id,
|
|
409
|
-
timestamp,
|
|
410
|
-
summary,
|
|
411
|
-
open_files,
|
|
412
|
-
next_steps,
|
|
413
|
-
status
|
|
414
|
-
FROM checkpoints
|
|
415
|
-
ORDER BY timestamp DESC
|
|
416
|
-
LIMIT 50
|
|
417
|
-
`);
|
|
418
|
-
const rows = stmt.all();
|
|
419
|
-
return rows.map((row) => ({
|
|
420
|
-
id: row.id,
|
|
421
|
-
timestamp: row.timestamp,
|
|
422
|
-
summary: row.summary,
|
|
423
|
-
open_files: row.open_files ? safeParseJsonArray(row.open_files) : [],
|
|
424
|
-
next_steps: row.next_steps,
|
|
425
|
-
status: row.status,
|
|
426
|
-
}));
|
|
427
|
-
}
|
|
428
|
-
function getUniqueTopics(nodes) {
|
|
429
|
-
const topicSet = new Set(nodes.map((n) => n.topic));
|
|
430
|
-
return Array.from(topicSet).sort();
|
|
431
|
-
}
|
|
432
|
-
function filterNodesByTopic(nodes, topic) {
|
|
433
|
-
return nodes.filter((n) => n.topic === topic);
|
|
434
|
-
}
|
|
435
|
-
function filterEdgesByNodes(edges, nodes) {
|
|
436
|
-
const nodeIds = new Set(nodes.map((n) => n.id));
|
|
437
|
-
return edges.filter((e) => nodeIds.has(e.from) || nodeIds.has(e.to));
|
|
438
|
-
}
|
|
439
|
-
function serveStaticFile(res, filePath, contentType, extraHeaders = {}) {
|
|
440
|
-
try {
|
|
441
|
-
const stats = fs_1.default.statSync(filePath);
|
|
442
|
-
if (!stats.isFile()) {
|
|
443
|
-
throw new Error('Requested path is not a file');
|
|
444
|
-
}
|
|
445
|
-
const isBinary = contentType.startsWith('image/') || contentType === 'application/octet-stream';
|
|
446
|
-
const content = isBinary ? fs_1.default.readFileSync(filePath) : fs_1.default.readFileSync(filePath, 'utf8');
|
|
447
|
-
const etag = `"${Date.now()}"`;
|
|
448
|
-
const fullContentType = isBinary ? contentType : `${contentType}; charset=utf-8`;
|
|
449
|
-
res.writeHead(200, {
|
|
450
|
-
'Content-Type': fullContentType,
|
|
451
|
-
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
|
452
|
-
Pragma: 'no-cache',
|
|
453
|
-
Expires: '0',
|
|
454
|
-
ETag: etag,
|
|
455
|
-
...extraHeaders,
|
|
456
|
-
});
|
|
457
|
-
res.end(content);
|
|
458
|
-
}
|
|
459
|
-
catch (error) {
|
|
460
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
461
|
-
console.error(`[GraphAPI] Static file error: ${message}`);
|
|
462
|
-
const err = error;
|
|
463
|
-
if (err?.code === 'ENOENT' || err?.code === 'EISDIR' || /not a file/i.test(message)) {
|
|
464
|
-
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
465
|
-
res.end('Not found');
|
|
466
|
-
return;
|
|
467
|
-
}
|
|
468
|
-
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
469
|
-
res.end('Internal server error');
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
function handleViewerRequest(_req, res) {
|
|
473
|
-
serveStaticFile(res, viewerHtmlPath(), 'text/html');
|
|
474
|
-
}
|
|
475
|
-
function handleCssRequest(_req, res) {
|
|
476
|
-
serveStaticFile(res, viewerCssPath(), 'text/css');
|
|
477
|
-
}
|
|
478
|
-
async function handleGraphRequest(_req, res, params) {
|
|
479
|
-
const startTime = Date.now();
|
|
480
|
-
try {
|
|
481
|
-
await initDB();
|
|
482
|
-
const limit = parseGraphLimit(params);
|
|
483
|
-
const allEdges = await getAllEdges();
|
|
484
|
-
const topicFilter = params.get('topic');
|
|
485
|
-
// When topic filter is active, fetch all nodes first so the filter
|
|
486
|
-
// sees every matching node — then apply limit. Without this, SQL
|
|
487
|
-
// LIMIT could exclude matching nodes that appear later in the table.
|
|
488
|
-
let nodes = await getAllNodes(topicFilter ? null : limit);
|
|
489
|
-
let edges = allEdges;
|
|
490
|
-
if (topicFilter) {
|
|
491
|
-
nodes = filterNodesByTopic(nodes, topicFilter);
|
|
492
|
-
if (limit !== null) {
|
|
493
|
-
nodes = nodes.slice(0, limit);
|
|
494
|
-
}
|
|
495
|
-
edges = filterEdgesByNodes(edges, nodes);
|
|
496
|
-
}
|
|
497
|
-
else if (limit !== null) {
|
|
498
|
-
edges = filterEdgesByNodes(edges, nodes);
|
|
499
|
-
}
|
|
500
|
-
// Expand: fetch neighbor nodes connected via edges but outside the LIMIT
|
|
501
|
-
const nodeIdSet = new Set(nodes.map((n) => n.id));
|
|
502
|
-
const missingIds = new Set();
|
|
503
|
-
for (const e of edges) {
|
|
504
|
-
if (!nodeIdSet.has(e.from))
|
|
505
|
-
missingIds.add(e.from);
|
|
506
|
-
if (!nodeIdSet.has(e.to))
|
|
507
|
-
missingIds.add(e.to);
|
|
508
|
-
}
|
|
509
|
-
if (missingIds.size > 0) {
|
|
510
|
-
const neighborNodes = await getNodesByIds(missingIds);
|
|
511
|
-
nodes = [...nodes, ...neighborNodes];
|
|
512
|
-
// Re-filter edges now that we have the full node set
|
|
513
|
-
edges = filterEdgesByNodes(allEdges, nodes);
|
|
514
|
-
}
|
|
515
|
-
const includeCluster = params.get('cluster') === 'true';
|
|
516
|
-
let similarityEdges = [];
|
|
517
|
-
if (includeCluster) {
|
|
518
|
-
similarityEdges = await getSimilarityEdges();
|
|
519
|
-
const nodeIds = new Set(nodes.map((n) => n.id));
|
|
520
|
-
similarityEdges = similarityEdges.filter((e) => nodeIds.has(e.from) && nodeIds.has(e.to));
|
|
521
|
-
}
|
|
522
|
-
const latency = Date.now() - startTime;
|
|
523
|
-
const meta = buildGraphMeta({
|
|
524
|
-
totalNodes: limit ? await getDecisionCount() : nodes.length,
|
|
525
|
-
totalEdges: allEdges.length,
|
|
526
|
-
similarityEdges: similarityEdges.length,
|
|
527
|
-
isPartial: !topicFilter && limit !== null,
|
|
528
|
-
returnedNodes: nodes.length,
|
|
529
|
-
returnedEdges: edges.length,
|
|
530
|
-
});
|
|
531
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
532
|
-
res.end(JSON.stringify({
|
|
533
|
-
nodes,
|
|
534
|
-
edges,
|
|
535
|
-
similarityEdges,
|
|
536
|
-
meta,
|
|
537
|
-
latency,
|
|
538
|
-
}));
|
|
539
|
-
}
|
|
540
|
-
catch (error) {
|
|
541
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
542
|
-
console.error(`[GraphAPI] Error: ${message}`);
|
|
543
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
544
|
-
res.end(JSON.stringify({
|
|
545
|
-
error: true,
|
|
546
|
-
code: 'INTERNAL_ERROR',
|
|
547
|
-
message,
|
|
548
|
-
}));
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
async function getDecisionCount() {
|
|
552
|
-
const adapter = getAdapter();
|
|
553
|
-
const row = adapter.prepare('SELECT COUNT(*) as count FROM decisions').get();
|
|
554
|
-
return row?.count ?? 0;
|
|
555
|
-
}
|
|
556
|
-
async function handleGraphDetailRequest(_req, res, params) {
|
|
557
|
-
try {
|
|
558
|
-
const decisionId = params.get('id');
|
|
559
|
-
if (!decisionId) {
|
|
560
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
561
|
-
res.end(JSON.stringify({
|
|
562
|
-
error: true,
|
|
563
|
-
code: 'MISSING_ID',
|
|
564
|
-
message: 'Missing required parameter: id',
|
|
565
|
-
}));
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
await initDB();
|
|
569
|
-
const detail = await getDecisionDetail(decisionId);
|
|
570
|
-
if (!detail) {
|
|
571
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
572
|
-
res.end(JSON.stringify({ error: true, code: 'NOT_FOUND', message: 'Decision not found' }));
|
|
573
|
-
return;
|
|
574
|
-
}
|
|
575
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
576
|
-
res.end(JSON.stringify({ node: detail }));
|
|
577
|
-
}
|
|
578
|
-
catch (error) {
|
|
579
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
580
|
-
logger.error('Graph detail error:', message);
|
|
581
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
582
|
-
res.end(JSON.stringify({ error: true, code: 'INTERNAL_ERROR', message }));
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
function readBody(req) {
|
|
586
|
-
// When mounted as Express middleware, body is already parsed by express.json()
|
|
587
|
-
const expressBody = req.body;
|
|
588
|
-
if (expressBody && typeof expressBody === 'object') {
|
|
589
|
-
return Promise.resolve(expressBody);
|
|
590
|
-
}
|
|
591
|
-
return new Promise((resolve, reject) => {
|
|
592
|
-
let data = '';
|
|
593
|
-
req.on('data', (chunk) => {
|
|
594
|
-
data += chunk;
|
|
595
|
-
if (data.length > 1_048_576) {
|
|
596
|
-
req.destroy();
|
|
597
|
-
reject(new Error('Request body too large (max 1MB)'));
|
|
598
|
-
return;
|
|
599
|
-
}
|
|
600
|
-
});
|
|
601
|
-
req.on('end', () => {
|
|
602
|
-
try {
|
|
603
|
-
resolve(JSON.parse(data));
|
|
604
|
-
}
|
|
605
|
-
catch {
|
|
606
|
-
reject(new Error('Invalid JSON'));
|
|
607
|
-
}
|
|
608
|
-
});
|
|
609
|
-
req.on('error', reject);
|
|
610
|
-
});
|
|
611
|
-
}
|
|
612
|
-
async function readBodyOrRespond(req, res) {
|
|
613
|
-
try {
|
|
614
|
-
return await readBody(req);
|
|
615
|
-
}
|
|
616
|
-
catch (error) {
|
|
617
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
618
|
-
const statusCode = message === 'Invalid JSON'
|
|
619
|
-
? 400
|
|
620
|
-
: message.includes('Request body too large (max 1MB)')
|
|
621
|
-
? 413
|
|
622
|
-
: 500;
|
|
623
|
-
res.writeHead(statusCode, { 'Content-Type': 'application/json' });
|
|
624
|
-
res.end(JSON.stringify({
|
|
625
|
-
error: message === 'Invalid JSON'
|
|
626
|
-
? 'Invalid JSON'
|
|
627
|
-
: message.includes('Request body too large (max 1MB)')
|
|
628
|
-
? 'Request body too large (max 1MB)'
|
|
629
|
-
: message,
|
|
630
|
-
}));
|
|
631
|
-
return null;
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
async function handleUpdateRequest(req, res) {
|
|
635
|
-
try {
|
|
636
|
-
const body = await readBody(req);
|
|
637
|
-
if (!body.id || !body.outcome) {
|
|
638
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
639
|
-
res.end(JSON.stringify({
|
|
640
|
-
error: true,
|
|
641
|
-
code: 'INVALID_REQUEST',
|
|
642
|
-
message: 'Missing required fields: id, outcome',
|
|
643
|
-
}));
|
|
644
|
-
return;
|
|
645
|
-
}
|
|
646
|
-
await initDB();
|
|
647
|
-
await mama.updateOutcome(body.id, {
|
|
648
|
-
outcome: body.outcome,
|
|
649
|
-
failure_reason: body.reason,
|
|
650
|
-
});
|
|
651
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
652
|
-
res.end(JSON.stringify({
|
|
653
|
-
success: true,
|
|
654
|
-
id: body.id,
|
|
655
|
-
outcome: String(body.outcome).toUpperCase(),
|
|
656
|
-
}));
|
|
657
|
-
}
|
|
658
|
-
catch (error) {
|
|
659
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
660
|
-
console.error(`[GraphAPI] Update error: ${message}`);
|
|
661
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
662
|
-
res.end(JSON.stringify({
|
|
663
|
-
error: true,
|
|
664
|
-
code: 'UPDATE_FAILED',
|
|
665
|
-
message,
|
|
666
|
-
}));
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
async function getSimilarityEdges() {
|
|
670
|
-
const adapter = getAdapter();
|
|
671
|
-
const stmt = adapter.prepare(`
|
|
672
|
-
SELECT id, topic, decision FROM decisions
|
|
673
|
-
ORDER BY created_at DESC
|
|
674
|
-
LIMIT 100
|
|
675
|
-
`);
|
|
676
|
-
const decisions = stmt.all();
|
|
677
|
-
if (decisions.length < 2) {
|
|
678
|
-
return [];
|
|
679
|
-
}
|
|
680
|
-
const similarityEdges = [];
|
|
681
|
-
const similarityEdgeKeys = new Set();
|
|
682
|
-
for (const decision of decisions.slice(0, 50)) {
|
|
683
|
-
try {
|
|
684
|
-
const query = `${decision.topic} ${decision.decision}`;
|
|
685
|
-
const embedding = await generateEmbedding(query, 'query');
|
|
686
|
-
const similar = (await vectorSearch(embedding, 3, 0.7));
|
|
687
|
-
for (const s of similar) {
|
|
688
|
-
if (s.id !== decision.id && s.similarity > 0.7) {
|
|
689
|
-
const edgeKey = [decision.id, s.id].sort().join('|');
|
|
690
|
-
if (!similarityEdgeKeys.has(edgeKey)) {
|
|
691
|
-
similarityEdges.push({
|
|
692
|
-
from: decision.id,
|
|
693
|
-
to: s.id,
|
|
694
|
-
relationship: 'similar',
|
|
695
|
-
similarity: s.similarity,
|
|
696
|
-
});
|
|
697
|
-
similarityEdgeKeys.add(edgeKey);
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
catch (e) {
|
|
703
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
704
|
-
console.error(`[GraphAPI] Similarity search error for ${decision.id}:`, msg);
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
return similarityEdges;
|
|
708
|
-
}
|
|
709
|
-
async function handleSimilarRequest(_req, res, params) {
|
|
710
|
-
const startTime = Date.now();
|
|
711
|
-
try {
|
|
712
|
-
const decisionId = params.get('id');
|
|
713
|
-
console.log(`[GraphAPI] Similar request for decision: ${decisionId}`);
|
|
714
|
-
if (!decisionId) {
|
|
715
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
716
|
-
res.end(JSON.stringify({
|
|
717
|
-
error: true,
|
|
718
|
-
code: 'MISSING_ID',
|
|
719
|
-
message: 'Missing required parameter: id',
|
|
720
|
-
}));
|
|
721
|
-
return;
|
|
722
|
-
}
|
|
723
|
-
console.log(`[GraphAPI] Initializing DB...`);
|
|
724
|
-
await initDB();
|
|
725
|
-
console.log(`[GraphAPI] Fetching decision ${decisionId}...`);
|
|
726
|
-
const adapter = getAdapter();
|
|
727
|
-
const stmt = adapter.prepare(`
|
|
728
|
-
SELECT topic, decision, reasoning FROM decisions WHERE id = ?
|
|
729
|
-
`);
|
|
730
|
-
const decision = stmt.get(decisionId);
|
|
731
|
-
if (!decision) {
|
|
732
|
-
console.log(`[GraphAPI] Decision ${decisionId} not found`);
|
|
733
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
734
|
-
res.end(JSON.stringify({
|
|
735
|
-
error: true,
|
|
736
|
-
code: 'NOT_FOUND',
|
|
737
|
-
message: 'Decision not found',
|
|
738
|
-
}));
|
|
739
|
-
return;
|
|
740
|
-
}
|
|
741
|
-
const searchQuery = `${decision.topic} ${decision.decision.slice(0, SIMILAR_QUERY_DECISION_CHARS)}`;
|
|
742
|
-
console.log(`[GraphAPI] Searching for similar decisions with query: "${searchQuery.substring(0, 50)}..."`);
|
|
743
|
-
const searchStart = Date.now();
|
|
744
|
-
const results = await mama.suggest(searchQuery, {
|
|
745
|
-
limit: 6,
|
|
746
|
-
threshold: 0.5,
|
|
747
|
-
});
|
|
748
|
-
console.log(`[GraphAPI] Semantic search completed in ${Date.now() - searchStart}ms`);
|
|
749
|
-
let similar = [];
|
|
750
|
-
if (results && results.results) {
|
|
751
|
-
similar = results.results
|
|
752
|
-
.filter((r) => r.id !== decisionId)
|
|
753
|
-
.slice(0, 5)
|
|
754
|
-
.map((r) => ({
|
|
755
|
-
id: r.id,
|
|
756
|
-
topic: r.topic,
|
|
757
|
-
decision: r.decision,
|
|
758
|
-
similarity: (r.similarity ?? r.final_score ?? 0.5),
|
|
759
|
-
outcome: (r.outcome ?? null),
|
|
760
|
-
}));
|
|
761
|
-
}
|
|
762
|
-
console.log(`[GraphAPI] Found ${similar.length} similar decisions (total time: ${Date.now() - startTime}ms)`);
|
|
763
|
-
res.writeHead(200, {
|
|
764
|
-
'Content-Type': 'application/json',
|
|
765
|
-
});
|
|
766
|
-
res.end(JSON.stringify({
|
|
767
|
-
id: decisionId,
|
|
768
|
-
similar,
|
|
769
|
-
count: similar.length,
|
|
770
|
-
}));
|
|
771
|
-
console.log(`[GraphAPI] Response sent for ${decisionId}`);
|
|
772
|
-
}
|
|
773
|
-
catch (error) {
|
|
774
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
775
|
-
const stack = error instanceof Error ? error.stack : undefined;
|
|
776
|
-
console.error(`[GraphAPI] Similar error: ${message}`);
|
|
777
|
-
console.error(`[GraphAPI] Similar error stack:`, stack);
|
|
778
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
779
|
-
res.end(JSON.stringify({
|
|
780
|
-
error: true,
|
|
781
|
-
code: 'SEARCH_FAILED',
|
|
782
|
-
message,
|
|
783
|
-
}));
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
async function handleMamaSearchRequest(_req, res, params) {
|
|
787
|
-
try {
|
|
788
|
-
const query = params.get('q');
|
|
789
|
-
const rawLimit = parseInt(params.get('limit') || '10', 10);
|
|
790
|
-
const limit = Number.isFinite(rawLimit) && rawLimit > 0 ? Math.min(rawLimit, 500) : 10;
|
|
791
|
-
if (!query) {
|
|
792
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
793
|
-
res.end(JSON.stringify({
|
|
794
|
-
error: true,
|
|
795
|
-
code: 'MISSING_QUERY',
|
|
796
|
-
message: 'Missing required parameter: q',
|
|
797
|
-
}));
|
|
798
|
-
return;
|
|
799
|
-
}
|
|
800
|
-
await initDB();
|
|
801
|
-
const topicPrefix = params.get('topicPrefix') || '';
|
|
802
|
-
const fetchLimit = topicPrefix ? Math.max(limit * 5, 100) : limit;
|
|
803
|
-
const searchResults = await mama.suggest(query, {
|
|
804
|
-
limit: fetchLimit,
|
|
805
|
-
threshold: 0.3,
|
|
806
|
-
topicPrefix: topicPrefix || undefined,
|
|
807
|
-
});
|
|
808
|
-
let results = [];
|
|
809
|
-
if (searchResults && searchResults.results) {
|
|
810
|
-
let rawResults = searchResults.results;
|
|
811
|
-
if (topicPrefix) {
|
|
812
|
-
rawResults = rawResults.filter((r) => String(r.topic || '').startsWith(topicPrefix));
|
|
813
|
-
}
|
|
814
|
-
results = rawResults.slice(0, limit).map((r) => ({
|
|
815
|
-
id: r.id,
|
|
816
|
-
topic: r.topic,
|
|
817
|
-
decision: r.decision,
|
|
818
|
-
reasoning: r.reasoning,
|
|
819
|
-
outcome: (r.outcome ?? null),
|
|
820
|
-
confidence: (r.confidence ?? null),
|
|
821
|
-
similarity: (r.similarity ?? r.final_score ?? 0.5),
|
|
822
|
-
created_at: r.created_at,
|
|
823
|
-
event_date: r.event_date ?? null,
|
|
824
|
-
}));
|
|
825
|
-
}
|
|
826
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
827
|
-
res.end(JSON.stringify({
|
|
828
|
-
query,
|
|
829
|
-
results,
|
|
830
|
-
count: results.length,
|
|
831
|
-
}));
|
|
832
|
-
}
|
|
833
|
-
catch (error) {
|
|
834
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
835
|
-
console.error(`[GraphAPI] MAMA search error: ${message}`);
|
|
836
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
837
|
-
res.end(JSON.stringify({
|
|
838
|
-
error: true,
|
|
839
|
-
code: 'SEARCH_FAILED',
|
|
840
|
-
message,
|
|
841
|
-
}));
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
async function handleMamaSaveRequest(req, res) {
|
|
845
|
-
try {
|
|
846
|
-
const body = await readBody(req);
|
|
847
|
-
if (!body.topic || !body.decision || !body.reasoning) {
|
|
848
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
849
|
-
res.end(JSON.stringify({
|
|
850
|
-
error: true,
|
|
851
|
-
code: 'MISSING_FIELDS',
|
|
852
|
-
message: 'Missing required fields: topic, decision, reasoning',
|
|
853
|
-
}));
|
|
854
|
-
return;
|
|
855
|
-
}
|
|
856
|
-
await initDB();
|
|
857
|
-
const result = await mama.save({
|
|
858
|
-
type: 'user_decision',
|
|
859
|
-
topic: body.topic,
|
|
860
|
-
decision: body.decision,
|
|
861
|
-
reasoning: body.reasoning,
|
|
862
|
-
confidence: body.confidence ?? 0.8,
|
|
863
|
-
...(body.event_date ? { event_date: body.event_date } : {}),
|
|
864
|
-
});
|
|
865
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
866
|
-
res.end(JSON.stringify({
|
|
867
|
-
success: true,
|
|
868
|
-
id: result.id,
|
|
869
|
-
message: 'Decision saved successfully',
|
|
870
|
-
}));
|
|
871
|
-
}
|
|
872
|
-
catch (error) {
|
|
873
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
874
|
-
console.error(`[GraphAPI] MAMA save error: ${message}`);
|
|
875
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
876
|
-
res.end(JSON.stringify({
|
|
877
|
-
error: true,
|
|
878
|
-
code: 'SAVE_FAILED',
|
|
879
|
-
message,
|
|
880
|
-
}));
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
async function handleCheckpointSaveRequest(req, res) {
|
|
884
|
-
try {
|
|
885
|
-
const body = await readBody(req);
|
|
886
|
-
if (!body.summary) {
|
|
887
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
888
|
-
res.end(JSON.stringify({
|
|
889
|
-
error: true,
|
|
890
|
-
code: 'MISSING_FIELDS',
|
|
891
|
-
message: 'Missing required field: summary',
|
|
892
|
-
}));
|
|
893
|
-
return;
|
|
894
|
-
}
|
|
895
|
-
await initDB();
|
|
896
|
-
const checkpointId = await mama.saveCheckpoint(body.summary, body.open_files || [], body.next_steps || '');
|
|
897
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
898
|
-
res.end(JSON.stringify({
|
|
899
|
-
success: true,
|
|
900
|
-
id: checkpointId,
|
|
901
|
-
message: 'Checkpoint saved successfully',
|
|
902
|
-
}));
|
|
903
|
-
}
|
|
904
|
-
catch (error) {
|
|
905
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
906
|
-
console.error(`[GraphAPI] Checkpoint save error: ${message}`);
|
|
907
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
908
|
-
res.end(JSON.stringify({
|
|
909
|
-
error: true,
|
|
910
|
-
code: 'SAVE_FAILED',
|
|
911
|
-
message,
|
|
912
|
-
}));
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
async function handleCheckpointLoadRequest(_req, res) {
|
|
916
|
-
try {
|
|
917
|
-
await initDB();
|
|
918
|
-
const checkpoint = await mama.loadCheckpoint();
|
|
919
|
-
if (!checkpoint) {
|
|
920
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
921
|
-
res.end(JSON.stringify({
|
|
922
|
-
error: true,
|
|
923
|
-
code: 'NO_CHECKPOINT',
|
|
924
|
-
message: 'No checkpoint found',
|
|
925
|
-
}));
|
|
926
|
-
return;
|
|
927
|
-
}
|
|
928
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
929
|
-
res.end(JSON.stringify({
|
|
930
|
-
success: true,
|
|
931
|
-
checkpoint,
|
|
932
|
-
}));
|
|
933
|
-
}
|
|
934
|
-
catch (error) {
|
|
935
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
936
|
-
console.error(`[GraphAPI] Checkpoint load error: ${message}`);
|
|
937
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
938
|
-
res.end(JSON.stringify({
|
|
939
|
-
error: true,
|
|
940
|
-
code: 'LOAD_FAILED',
|
|
941
|
-
message,
|
|
942
|
-
}));
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
async function handleCheckpointsRequest(_req, res) {
|
|
946
|
-
try {
|
|
947
|
-
await initDB();
|
|
948
|
-
const checkpoints = await getAllCheckpoints();
|
|
949
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
950
|
-
res.end(JSON.stringify({
|
|
951
|
-
checkpoints,
|
|
952
|
-
count: checkpoints.length,
|
|
953
|
-
}));
|
|
954
|
-
}
|
|
955
|
-
catch (error) {
|
|
956
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
957
|
-
console.error(`[GraphAPI] Checkpoints error: ${message}`);
|
|
958
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
959
|
-
res.end(JSON.stringify({
|
|
960
|
-
error: true,
|
|
961
|
-
code: 'CHECKPOINTS_FAILED',
|
|
962
|
-
message,
|
|
963
|
-
}));
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
function createGraphHandler(options = {}) {
|
|
967
|
-
let entityAuditQueue = null;
|
|
968
|
-
let entityAuditQueuePromise = null;
|
|
969
|
-
const getEntityAuditQueue = async () => {
|
|
970
|
-
if (entityAuditQueue) {
|
|
971
|
-
return entityAuditQueue;
|
|
972
|
-
}
|
|
973
|
-
if (entityAuditQueuePromise) {
|
|
974
|
-
return entityAuditQueuePromise;
|
|
975
|
-
}
|
|
976
|
-
entityAuditQueuePromise = (async () => {
|
|
977
|
-
await initDB();
|
|
978
|
-
const queue = new entity_audit_queue_js_1.EntityAuditRunQueue({ adapter: getAdapter() });
|
|
979
|
-
const recovered = queue.recoverOrphans();
|
|
980
|
-
if (recovered > 0) {
|
|
981
|
-
logger.warn('[entity-audit] Recovered orphaned audit runs on boot', { recovered });
|
|
982
|
-
}
|
|
983
|
-
entityAuditQueue = queue;
|
|
984
|
-
return queue;
|
|
985
|
-
})();
|
|
986
|
-
return entityAuditQueuePromise;
|
|
987
|
-
};
|
|
988
|
-
const parsePositiveInt = (value, fallback, max) => {
|
|
989
|
-
const parsed = Number.parseInt(value ?? '', 10);
|
|
990
|
-
if (!Number.isFinite(parsed) || parsed < 1) {
|
|
991
|
-
return fallback;
|
|
992
|
-
}
|
|
993
|
-
return Math.min(parsed, max);
|
|
994
|
-
};
|
|
995
|
-
const parseValidationTriggerType = (value) => {
|
|
996
|
-
if (!value) {
|
|
997
|
-
return null;
|
|
998
|
-
}
|
|
999
|
-
const normalized = value.trim().toLowerCase();
|
|
1000
|
-
return VALIDATION_TRIGGER_TYPES.has(normalized) ? normalized : null;
|
|
1001
|
-
};
|
|
1002
|
-
return async function graphHandler(req, res) {
|
|
1003
|
-
if (!req.url) {
|
|
1004
|
-
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
1005
|
-
res.end('Bad Request');
|
|
1006
|
-
return true;
|
|
1007
|
-
}
|
|
1008
|
-
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
1009
|
-
const pathname = url.pathname;
|
|
1010
|
-
const params = url.searchParams;
|
|
1011
|
-
console.log('[GraphHandler] Request:', req.method, pathname);
|
|
1012
|
-
// Set CORS headers — restrict to localhost origins only
|
|
1013
|
-
const origin = req.headers.origin || '';
|
|
1014
|
-
const isLocalhost = /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(origin);
|
|
1015
|
-
if (isLocalhost) {
|
|
1016
|
-
res.setHeader('Access-Control-Allow-Origin', origin);
|
|
1017
|
-
}
|
|
1018
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
1019
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
1020
|
-
// Handle preflight OPTIONS requests
|
|
1021
|
-
if (req.method === 'OPTIONS') {
|
|
1022
|
-
res.writeHead(204);
|
|
1023
|
-
res.end();
|
|
1024
|
-
return true;
|
|
1025
|
-
}
|
|
1026
|
-
// Route: GET / - redirect to /viewer, the ONE public shell. The temporary
|
|
1027
|
-
// /ui SPA route was retired; there is no second face to fall back to.
|
|
1028
|
-
if (pathname === '/' && req.method === 'GET') {
|
|
1029
|
-
console.log('[GraphHandler] Redirecting / to /viewer');
|
|
1030
|
-
res.writeHead(302, { Location: '/viewer' });
|
|
1031
|
-
res.end();
|
|
1032
|
-
return true;
|
|
1033
|
-
}
|
|
1034
|
-
// Route: GET/HEAD /viewer or /viewer/ - serve HTML viewer
|
|
1035
|
-
if ((pathname === '/viewer' || pathname === '/viewer/') &&
|
|
1036
|
-
(req.method === 'GET' || req.method === 'HEAD')) {
|
|
1037
|
-
console.log('[GraphHandler] Serving viewer.html');
|
|
1038
|
-
handleViewerRequest(req, res);
|
|
1039
|
-
return true;
|
|
1040
|
-
}
|
|
1041
|
-
// Route: GET/HEAD /viewer/viewer.css - serve stylesheet
|
|
1042
|
-
if (pathname === '/viewer/viewer.css' && (req.method === 'GET' || req.method === 'HEAD')) {
|
|
1043
|
-
handleCssRequest(req, res);
|
|
1044
|
-
return true;
|
|
1045
|
-
}
|
|
1046
|
-
// Route: GET/HEAD /sw.js - serve Service Worker
|
|
1047
|
-
if (pathname === '/sw.js' && (req.method === 'GET' || req.method === 'HEAD')) {
|
|
1048
|
-
serveStaticFile(res, swJsPath(), 'application/javascript');
|
|
1049
|
-
return true;
|
|
1050
|
-
}
|
|
1051
|
-
// Route: GET/HEAD /viewer/sw.js - serve Service Worker (alternative path)
|
|
1052
|
-
if (pathname === '/viewer/sw.js' && (req.method === 'GET' || req.method === 'HEAD')) {
|
|
1053
|
-
serveStaticFile(res, swJsPath(), 'application/javascript');
|
|
1054
|
-
return true;
|
|
1055
|
-
}
|
|
1056
|
-
// Route: GET/HEAD /viewer/manifest.json - serve PWA manifest
|
|
1057
|
-
if (pathname === '/viewer/manifest.json' && (req.method === 'GET' || req.method === 'HEAD')) {
|
|
1058
|
-
serveStaticFile(res, manifestJsonPath(), 'application/json');
|
|
1059
|
-
return true;
|
|
1060
|
-
}
|
|
1061
|
-
// Route: GET/HEAD /favicon.ico - serve favicon
|
|
1062
|
-
if (pathname === '/favicon.ico' && (req.method === 'GET' || req.method === 'HEAD')) {
|
|
1063
|
-
serveStaticFile(res, viewerFaviconPath(), 'image/x-icon');
|
|
1064
|
-
return true;
|
|
1065
|
-
}
|
|
1066
|
-
// Route: GET/HEAD /viewer/operator/*.{js,css} - operator bundle assets.
|
|
1067
|
-
// Traversal-safe and extension-allowlisted: this route must never become a
|
|
1068
|
-
// generic file server rooted at the viewer directory.
|
|
1069
|
-
if (pathname.startsWith('/viewer/operator/') &&
|
|
1070
|
-
(req.method === 'GET' || req.method === 'HEAD')) {
|
|
1071
|
-
const operatorRoot = viewerOperatorDir();
|
|
1072
|
-
const resolved = path_1.default.resolve(operatorRoot, pathname.slice('/viewer/operator/'.length));
|
|
1073
|
-
const contentType = VIEWER_OPERATOR_MIME[path_1.default.extname(resolved)];
|
|
1074
|
-
if (!resolved.startsWith(operatorRoot + path_1.default.sep) || !contentType) {
|
|
1075
|
-
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
1076
|
-
res.end('Not found');
|
|
1077
|
-
return true;
|
|
1078
|
-
}
|
|
1079
|
-
serveStaticFile(res, resolved, contentType);
|
|
1080
|
-
return true;
|
|
1081
|
-
}
|
|
1082
|
-
// Route: GET/HEAD /viewer/icons/*.png - serve PWA icons
|
|
1083
|
-
if (pathname.startsWith('/viewer/icons/') &&
|
|
1084
|
-
pathname.endsWith('.png') &&
|
|
1085
|
-
(req.method === 'GET' || req.method === 'HEAD')) {
|
|
1086
|
-
const fileName = path_1.default.basename(pathname.split('/').pop() || '');
|
|
1087
|
-
const filePath = path_1.default.join(viewerIconDir(), fileName);
|
|
1088
|
-
serveStaticFile(res, filePath, 'image/png');
|
|
1089
|
-
return true;
|
|
1090
|
-
}
|
|
1091
|
-
// Route: GET/HEAD /viewer/icons/*.svg - serve SVG icons
|
|
1092
|
-
if (pathname.startsWith('/viewer/icons/') &&
|
|
1093
|
-
pathname.endsWith('.svg') &&
|
|
1094
|
-
(req.method === 'GET' || req.method === 'HEAD')) {
|
|
1095
|
-
const fileName = path_1.default.basename(pathname.split('/').pop() || '');
|
|
1096
|
-
const filePath = path_1.default.join(viewerIconDir(), fileName);
|
|
1097
|
-
serveStaticFile(res, filePath, 'image/svg+xml');
|
|
1098
|
-
return true;
|
|
1099
|
-
}
|
|
1100
|
-
// Route: GET/HEAD /viewer/js/utils/*.js - serve utility modules
|
|
1101
|
-
if (pathname.startsWith('/viewer/js/utils/') &&
|
|
1102
|
-
pathname.endsWith('.js') &&
|
|
1103
|
-
(req.method === 'GET' || req.method === 'HEAD')) {
|
|
1104
|
-
const fileName = pathname.split('/').pop();
|
|
1105
|
-
const filePath = path_1.default.join(getViewerDirectory(), 'js', 'utils', fileName);
|
|
1106
|
-
serveStaticFile(res, filePath, 'application/javascript');
|
|
1107
|
-
return true;
|
|
1108
|
-
}
|
|
1109
|
-
// Route: GET/HEAD /viewer/js/*.js - serve first-party viewer entry modules
|
|
1110
|
-
if (pathname.startsWith('/viewer/js/') &&
|
|
1111
|
-
!pathname.includes('/modules/') &&
|
|
1112
|
-
!pathname.includes('/utils/') &&
|
|
1113
|
-
pathname.endsWith('.js') &&
|
|
1114
|
-
(req.method === 'GET' || req.method === 'HEAD')) {
|
|
1115
|
-
const fileName = pathname.split('/').pop();
|
|
1116
|
-
const filePath = path_1.default.join(getViewerDirectory(), 'js', fileName);
|
|
1117
|
-
serveStaticFile(res, filePath, 'application/javascript');
|
|
1118
|
-
return true;
|
|
1119
|
-
}
|
|
1120
|
-
// Route: GET/HEAD /viewer/js/modules/*.js - serve feature modules
|
|
1121
|
-
if (pathname.startsWith('/viewer/js/modules/') &&
|
|
1122
|
-
pathname.endsWith('.js') &&
|
|
1123
|
-
(req.method === 'GET' || req.method === 'HEAD')) {
|
|
1124
|
-
const fileName = pathname.split('/').pop();
|
|
1125
|
-
const filePath = path_1.default.join(getViewerDirectory(), 'js', 'modules', fileName);
|
|
1126
|
-
serveStaticFile(res, filePath, 'application/javascript');
|
|
1127
|
-
return true;
|
|
1128
|
-
}
|
|
1129
|
-
// ── Auth gate: all routes below require authentication ──
|
|
1130
|
-
// Static assets (viewer, css, js, icons) are served above without auth.
|
|
1131
|
-
// All data API routes below must pass isAuthenticated().
|
|
1132
|
-
// Note: /graph/* write endpoints are also gated in start.ts for defense-in-depth.
|
|
1133
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
1134
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
1135
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
1136
|
-
res.end(JSON.stringify({ error: true, code: 'UNAUTHORIZED', message: 'Authentication required.' }));
|
|
1137
|
-
return true;
|
|
1138
|
-
}
|
|
1139
|
-
// Route: GET /graph/similar - find similar decisions (check before /graph)
|
|
1140
|
-
if (pathname === '/graph/similar' && req.method === 'GET') {
|
|
1141
|
-
console.log('[GraphHandler] Routing to handleSimilarRequest');
|
|
1142
|
-
await handleSimilarRequest(req, res, params);
|
|
1143
|
-
return true;
|
|
1144
|
-
}
|
|
1145
|
-
// Route: GET /graph/detail - fetch full node detail lazily
|
|
1146
|
-
if (pathname === '/graph/detail' && req.method === 'GET') {
|
|
1147
|
-
await handleGraphDetailRequest(req, res, params);
|
|
1148
|
-
return true;
|
|
1149
|
-
}
|
|
1150
|
-
// Route: POST /graph/update - update decision outcome
|
|
1151
|
-
if (pathname === '/graph/update' && req.method === 'POST') {
|
|
1152
|
-
await handleUpdateRequest(req, res);
|
|
1153
|
-
return true;
|
|
1154
|
-
}
|
|
1155
|
-
// Route: GET /graph - API endpoint
|
|
1156
|
-
if (pathname === '/graph' && req.method === 'GET') {
|
|
1157
|
-
await handleGraphRequest(req, res, params);
|
|
1158
|
-
return true;
|
|
1159
|
-
}
|
|
1160
|
-
// Alias: GET /api/graph -> /graph
|
|
1161
|
-
if (pathname === '/api/graph' && req.method === 'GET') {
|
|
1162
|
-
await handleGraphRequest(req, res, params);
|
|
1163
|
-
return true;
|
|
1164
|
-
}
|
|
1165
|
-
// Alias: GET /api/graph/detail -> /graph/detail
|
|
1166
|
-
if (pathname === '/api/graph/detail' && req.method === 'GET') {
|
|
1167
|
-
await handleGraphDetailRequest(req, res, params);
|
|
1168
|
-
return true;
|
|
1169
|
-
}
|
|
1170
|
-
// Route: GET /checkpoints - list all checkpoints
|
|
1171
|
-
if (pathname === '/checkpoints' && req.method === 'GET') {
|
|
1172
|
-
await handleCheckpointsRequest(req, res);
|
|
1173
|
-
return true;
|
|
1174
|
-
}
|
|
1175
|
-
// Alias: GET /api/checkpoints -> /checkpoints
|
|
1176
|
-
if (pathname === '/api/checkpoints' && req.method === 'GET') {
|
|
1177
|
-
await handleCheckpointsRequest(req, res);
|
|
1178
|
-
return true;
|
|
1179
|
-
}
|
|
1180
|
-
// Route: GET /api/mama/search - semantic search for decisions
|
|
1181
|
-
if (pathname === '/api/mama/search' && req.method === 'GET') {
|
|
1182
|
-
await handleMamaSearchRequest(req, res, params);
|
|
1183
|
-
return true;
|
|
1184
|
-
}
|
|
1185
|
-
// Alias: GET /api/search -> /api/mama/search (with query param conversion)
|
|
1186
|
-
if (pathname === '/api/search' && req.method === 'GET') {
|
|
1187
|
-
const query = params.get('query');
|
|
1188
|
-
if (query) {
|
|
1189
|
-
params.set('q', query);
|
|
1190
|
-
}
|
|
1191
|
-
await handleMamaSearchRequest(req, res, params);
|
|
1192
|
-
return true;
|
|
1193
|
-
}
|
|
1194
|
-
// Route: POST /api/mama/save - save a new decision
|
|
1195
|
-
if (pathname === '/api/mama/save' && req.method === 'POST') {
|
|
1196
|
-
await handleMamaSaveRequest(req, res);
|
|
1197
|
-
return true;
|
|
1198
|
-
}
|
|
1199
|
-
// Alias: POST /api/save -> /api/mama/save
|
|
1200
|
-
if (pathname === '/api/save' && req.method === 'POST') {
|
|
1201
|
-
await handleMamaSaveRequest(req, res);
|
|
1202
|
-
return true;
|
|
1203
|
-
}
|
|
1204
|
-
// Route: POST /api/mama/ingest-conversation - ingest conversation with LLM extraction
|
|
1205
|
-
if (pathname === '/api/mama/ingest-conversation' && req.method === 'POST') {
|
|
1206
|
-
try {
|
|
1207
|
-
const body = await readBody(req);
|
|
1208
|
-
// Validate payload at HTTP boundary
|
|
1209
|
-
if (!Array.isArray(body.messages) || body.messages.length === 0) {
|
|
1210
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1211
|
-
res.end(JSON.stringify({ error: true, message: 'messages must be a non-empty array' }));
|
|
1212
|
-
return true;
|
|
1213
|
-
}
|
|
1214
|
-
const validRoles = new Set(['user', 'assistant']);
|
|
1215
|
-
for (const msg of body.messages) {
|
|
1216
|
-
if (typeof msg !== 'object' ||
|
|
1217
|
-
msg === null ||
|
|
1218
|
-
typeof msg.role !== 'string' ||
|
|
1219
|
-
typeof msg.content !== 'string') {
|
|
1220
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1221
|
-
res.end(JSON.stringify({
|
|
1222
|
-
error: true,
|
|
1223
|
-
message: 'Each message must have string "role" and "content" fields',
|
|
1224
|
-
}));
|
|
1225
|
-
return true;
|
|
1226
|
-
}
|
|
1227
|
-
if (!validRoles.has(msg.role)) {
|
|
1228
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1229
|
-
res.end(JSON.stringify({
|
|
1230
|
-
error: true,
|
|
1231
|
-
message: `Invalid role "${msg.role}". Must be "user" or "assistant"`,
|
|
1232
|
-
}));
|
|
1233
|
-
return true;
|
|
1234
|
-
}
|
|
1235
|
-
}
|
|
1236
|
-
if (body.scopes && !Array.isArray(body.scopes)) {
|
|
1237
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1238
|
-
res.end(JSON.stringify({ error: true, message: 'scopes must be an array' }));
|
|
1239
|
-
return true;
|
|
1240
|
-
}
|
|
1241
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
1242
|
-
const { ingestConversation } = require('@jungjaehoon/mama-core');
|
|
1243
|
-
const source = body.source || {
|
|
1244
|
-
package: 'standalone',
|
|
1245
|
-
source_type: 'api',
|
|
1246
|
-
};
|
|
1247
|
-
const result = await ingestConversation({
|
|
1248
|
-
messages: (body.messages || []),
|
|
1249
|
-
scopes: (body.scopes || []),
|
|
1250
|
-
source: { package: source.package, source_type: source.source_type },
|
|
1251
|
-
extract: body.extract,
|
|
1252
|
-
topicPrefix: body.topicPrefix || undefined,
|
|
1253
|
-
sessionDate: body.sessionDate || undefined,
|
|
1254
|
-
});
|
|
1255
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1256
|
-
res.end(JSON.stringify({ success: true, ...result }));
|
|
1257
|
-
}
|
|
1258
|
-
catch (error) {
|
|
1259
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1260
|
-
// Use 400 for client errors (validation), 500 for unexpected server failures
|
|
1261
|
-
const isClientError = error instanceof Error &&
|
|
1262
|
-
(error.message.includes('required') ||
|
|
1263
|
-
error.message.includes('invalid') ||
|
|
1264
|
-
error.message.includes('missing'));
|
|
1265
|
-
const statusCode = isClientError ? 400 : 500;
|
|
1266
|
-
res.writeHead(statusCode, { 'Content-Type': 'application/json' });
|
|
1267
|
-
res.end(JSON.stringify({ error: true, message }));
|
|
1268
|
-
}
|
|
1269
|
-
return true;
|
|
1270
|
-
}
|
|
1271
|
-
// Retired model-as-function endpoints fail explicitly. Conversation memory
|
|
1272
|
-
// is handled by the standing owner through mama_save, not a hidden agent.
|
|
1273
|
-
if ((pathname === '/api/memory-agent/ingest' || pathname === '/api/mama/audit-conversation') &&
|
|
1274
|
-
req.method === 'POST') {
|
|
1275
|
-
res.writeHead(410, { 'Content-Type': 'application/json' });
|
|
1276
|
-
res.end(JSON.stringify({
|
|
1277
|
-
error: true,
|
|
1278
|
-
message: 'Separate memory-agent ingestion was retired; use the One MAMA owner runtime',
|
|
1279
|
-
}));
|
|
1280
|
-
return true;
|
|
1281
|
-
}
|
|
1282
|
-
// Alias: POST /api/update -> /graph/update
|
|
1283
|
-
if (pathname === '/api/update' && req.method === 'POST') {
|
|
1284
|
-
await handleUpdateRequest(req, res);
|
|
1285
|
-
return true;
|
|
1286
|
-
}
|
|
1287
|
-
// Route: POST /api/checkpoint/save - save session checkpoint
|
|
1288
|
-
if (pathname === '/api/checkpoint/save' && req.method === 'POST') {
|
|
1289
|
-
await handleCheckpointSaveRequest(req, res);
|
|
1290
|
-
return true;
|
|
1291
|
-
}
|
|
1292
|
-
// Route: GET /api/checkpoint/load - load latest checkpoint
|
|
1293
|
-
if (pathname === '/api/checkpoint/load' && req.method === 'GET') {
|
|
1294
|
-
await handleCheckpointLoadRequest(req, res);
|
|
1295
|
-
return true;
|
|
1296
|
-
}
|
|
1297
|
-
// Route: GET /api/health - health check
|
|
1298
|
-
if (pathname === '/api/health' && req.method === 'GET') {
|
|
1299
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1300
|
-
res.end(JSON.stringify({ status: 'ok', service: 'MAMA Graph API' }));
|
|
1301
|
-
return true;
|
|
1302
|
-
}
|
|
1303
|
-
// Route: GET /api/metrics/health - system health report
|
|
1304
|
-
if (pathname === '/api/metrics/health' && req.method === 'GET') {
|
|
1305
|
-
// Prefer HealthCheckService (connection-based) over legacy stats-only service
|
|
1306
|
-
if (options.healthCheckService) {
|
|
1307
|
-
try {
|
|
1308
|
-
const report = await options.healthCheckService.check();
|
|
1309
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1310
|
-
res.end(JSON.stringify(report));
|
|
1311
|
-
}
|
|
1312
|
-
catch (e) {
|
|
1313
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
1314
|
-
res.end(JSON.stringify({ error: String(e) }));
|
|
1315
|
-
}
|
|
1316
|
-
return true;
|
|
1317
|
-
}
|
|
1318
|
-
// Fallback to legacy HealthScoreService
|
|
1319
|
-
if (!options.healthService) {
|
|
1320
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1321
|
-
res.end(JSON.stringify({ error: 'Metrics disabled' }));
|
|
1322
|
-
return true;
|
|
1323
|
-
}
|
|
1324
|
-
try {
|
|
1325
|
-
const report = options.healthService.compute();
|
|
1326
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1327
|
-
res.end(JSON.stringify(report));
|
|
1328
|
-
}
|
|
1329
|
-
catch (e) {
|
|
1330
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
1331
|
-
res.end(JSON.stringify({ error: String(e) }));
|
|
1332
|
-
}
|
|
1333
|
-
return true;
|
|
1334
|
-
}
|
|
1335
|
-
// Route: GET /api/dashboard/status - dashboard status
|
|
1336
|
-
if (pathname === '/api/dashboard/status' && req.method === 'GET') {
|
|
1337
|
-
await handleDashboardStatusRequest(req, res);
|
|
1338
|
-
return true;
|
|
1339
|
-
}
|
|
1340
|
-
// Route: GET /api/config - get current config
|
|
1341
|
-
if (pathname === '/api/config' && req.method === 'GET') {
|
|
1342
|
-
await handleGetConfigRequest(req, res);
|
|
1343
|
-
return true;
|
|
1344
|
-
}
|
|
1345
|
-
// Route: PUT /api/config - update config
|
|
1346
|
-
if (pathname === '/api/config' && req.method === 'PUT') {
|
|
1347
|
-
await handleUpdateConfigRequest(req, res, options);
|
|
1348
|
-
return true;
|
|
1349
|
-
}
|
|
1350
|
-
// Route: POST /api/restart - graceful restart via mama CLI
|
|
1351
|
-
if (pathname === '/api/restart' && req.method === 'POST') {
|
|
1352
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
1353
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
1354
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
1355
|
-
res.end(JSON.stringify({ error: true, code: 'UNAUTHORIZED', message: 'Authentication required' }));
|
|
1356
|
-
return true;
|
|
1357
|
-
}
|
|
1358
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1359
|
-
res.end(JSON.stringify({ success: true, message: 'Restarting...' }));
|
|
1360
|
-
// Prefer systemd restart when running as a service; otherwise spawn detached daemon.
|
|
1361
|
-
setTimeout(() => {
|
|
1362
|
-
console.log('[API] Restart requested via API — spawning new daemon');
|
|
1363
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
1364
|
-
const { spawn: spawnChild } = require('node:child_process');
|
|
1365
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
1366
|
-
const { openSync } = require('node:fs');
|
|
1367
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
1368
|
-
const { join: joinPath, dirname: dirnamePath } = require('node:path');
|
|
1369
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
1370
|
-
const { homedir: getHome } = require('node:os');
|
|
1371
|
-
const isSystemd = Boolean(process.env.INVOCATION_ID) || Boolean(process.env.SYSTEMD_EXEC_PID);
|
|
1372
|
-
if (isSystemd) {
|
|
1373
|
-
spawnChild('systemctl', ['--user', 'restart', 'mama-os'], {
|
|
1374
|
-
detached: true,
|
|
1375
|
-
stdio: 'ignore',
|
|
1376
|
-
}).unref();
|
|
1377
|
-
process.exit(0);
|
|
1378
|
-
}
|
|
1379
|
-
const script = process.argv[1];
|
|
1380
|
-
if (!script) {
|
|
1381
|
-
throw new Error('Unable to determine executable script path');
|
|
1382
|
-
}
|
|
1383
|
-
const logDir = joinPath(getHome(), '.mama', 'logs');
|
|
1384
|
-
const logFile = joinPath(logDir, 'daemon.log');
|
|
1385
|
-
const out = openSync(logFile, 'a');
|
|
1386
|
-
const runCli = (cmd) => {
|
|
1387
|
-
const child = spawnChild(process.execPath, [script, cmd], {
|
|
1388
|
-
detached: true,
|
|
1389
|
-
stdio: ['ignore', out, out],
|
|
1390
|
-
cwd: dirnamePath(script),
|
|
1391
|
-
env: { ...process.env, MAMA_DAEMON: '1' },
|
|
1392
|
-
});
|
|
1393
|
-
child.unref();
|
|
1394
|
-
};
|
|
1395
|
-
// Wait for port to be released after stop (2s delay between stop and start)
|
|
1396
|
-
setTimeout(() => {
|
|
1397
|
-
runCli('stop');
|
|
1398
|
-
setTimeout(() => {
|
|
1399
|
-
runCli('start');
|
|
1400
|
-
process.exit(0);
|
|
1401
|
-
}, 2000);
|
|
1402
|
-
}, 1000);
|
|
1403
|
-
}, 500);
|
|
1404
|
-
return true;
|
|
1405
|
-
}
|
|
1406
|
-
// Route: GET /api/memory/export - export decisions
|
|
1407
|
-
if (pathname === '/api/memory/export' && req.method === 'GET') {
|
|
1408
|
-
await handleExportRequest(req, res, params);
|
|
1409
|
-
return true;
|
|
1410
|
-
}
|
|
1411
|
-
// ── UI Command API (SmartStore bidirectional communication) ──
|
|
1412
|
-
// Route: GET /api/ui/commands — viewer polls for pending commands
|
|
1413
|
-
if (pathname === '/api/ui/commands' && req.method === 'GET') {
|
|
1414
|
-
if (options.uiCommandQueue) {
|
|
1415
|
-
(0, ui_command_handler_js_1.handleGetUICommands)(res, options.uiCommandQueue);
|
|
1416
|
-
}
|
|
1417
|
-
else {
|
|
1418
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1419
|
-
res.end(JSON.stringify({ commands: [] }));
|
|
1420
|
-
}
|
|
1421
|
-
return true;
|
|
1422
|
-
}
|
|
1423
|
-
// Route: GET /api/ui/page-context — agent reads current viewer state
|
|
1424
|
-
if (pathname === '/api/ui/page-context' && req.method === 'GET') {
|
|
1425
|
-
if (options.uiCommandQueue) {
|
|
1426
|
-
const { handleGetPageContext } = await import('./ui-command-handler.js');
|
|
1427
|
-
handleGetPageContext(res, options.uiCommandQueue);
|
|
1428
|
-
}
|
|
1429
|
-
else {
|
|
1430
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1431
|
-
res.end(JSON.stringify({ success: true, context: null }));
|
|
1432
|
-
}
|
|
1433
|
-
return true;
|
|
1434
|
-
}
|
|
1435
|
-
// Route: POST /api/ui/page-context — viewer reports current page state
|
|
1436
|
-
if (pathname === '/api/ui/page-context' && req.method === 'POST') {
|
|
1437
|
-
if (options.uiCommandQueue) {
|
|
1438
|
-
const body = await readBodyOrRespond(req, res);
|
|
1439
|
-
if (!body) {
|
|
1440
|
-
return true;
|
|
1441
|
-
}
|
|
1442
|
-
(0, ui_command_handler_js_1.handlePostPageContext)(res, body, options.uiCommandQueue);
|
|
1443
|
-
}
|
|
1444
|
-
else {
|
|
1445
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1446
|
-
res.end(JSON.stringify({ success: true }));
|
|
1447
|
-
}
|
|
1448
|
-
return true;
|
|
1449
|
-
}
|
|
1450
|
-
// Route: POST /api/ui/commands — agent pushes UI commands
|
|
1451
|
-
if (pathname === '/api/ui/commands' && req.method === 'POST') {
|
|
1452
|
-
if (options.uiCommandQueue) {
|
|
1453
|
-
const body = await readBodyOrRespond(req, res);
|
|
1454
|
-
if (!body) {
|
|
1455
|
-
return true;
|
|
1456
|
-
}
|
|
1457
|
-
(0, ui_command_handler_js_1.handlePostUICommand)(res, body, options.uiCommandQueue);
|
|
1458
|
-
}
|
|
1459
|
-
else {
|
|
1460
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1461
|
-
res.end(JSON.stringify({ success: true }));
|
|
1462
|
-
}
|
|
1463
|
-
return true;
|
|
1464
|
-
}
|
|
1465
|
-
// Route: POST /api/ui/commands/ack — viewer acknowledges applied commands
|
|
1466
|
-
if (pathname === '/api/ui/commands/ack' && req.method === 'POST') {
|
|
1467
|
-
if (options.uiCommandQueue) {
|
|
1468
|
-
const body = await readBodyOrRespond(req, res);
|
|
1469
|
-
if (!body) {
|
|
1470
|
-
return true;
|
|
1471
|
-
}
|
|
1472
|
-
const { handlePostUICommandAck } = await import('./ui-command-handler.js');
|
|
1473
|
-
handlePostUICommandAck(res, body, options.uiCommandQueue);
|
|
1474
|
-
}
|
|
1475
|
-
else {
|
|
1476
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1477
|
-
res.end(JSON.stringify({ success: true, acknowledged: 0 }));
|
|
1478
|
-
}
|
|
1479
|
-
return true;
|
|
1480
|
-
}
|
|
1481
|
-
// ── Agent Management API (Managed Agents pattern) ──
|
|
1482
|
-
// Route: GET /api/agents/:id/versions/:v1/compare/:v2 — before/after (must be before /api/agents/:id)
|
|
1483
|
-
if (pathname.match(/^\/api\/agents\/[^/]+\/versions\/\d+\/compare\/\d+$/) &&
|
|
1484
|
-
req.method === 'GET') {
|
|
1485
|
-
const parts = pathname.split('/');
|
|
1486
|
-
const agentId = decodeURIComponent(parts[3]);
|
|
1487
|
-
const v1 = parseInt(parts[5], 10);
|
|
1488
|
-
const v2 = parseInt(parts[7], 10);
|
|
1489
|
-
if (options.sessionsDb) {
|
|
1490
|
-
(0, agent_handler_js_1.handleCompareVersions)(res, agentId, v1, v2, options.sessionsDb);
|
|
1491
|
-
}
|
|
1492
|
-
else {
|
|
1493
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1494
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1495
|
-
}
|
|
1496
|
-
return true;
|
|
1497
|
-
}
|
|
1498
|
-
// Route: GET /api/agents/:id/versions — version history
|
|
1499
|
-
if (pathname.match(/^\/api\/agents\/[^/]+\/versions$/) && req.method === 'GET') {
|
|
1500
|
-
const agentId = decodeURIComponent(pathname.split('/')[3]);
|
|
1501
|
-
if (options.sessionsDb) {
|
|
1502
|
-
(0, agent_handler_js_1.handleListVersions)(res, agentId, options.sessionsDb);
|
|
1503
|
-
}
|
|
1504
|
-
else {
|
|
1505
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1506
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1507
|
-
}
|
|
1508
|
-
return true;
|
|
1509
|
-
}
|
|
1510
|
-
// Route: GET /api/agents/:id/metrics?from=&to= — metrics for period
|
|
1511
|
-
if (pathname.match(/^\/api\/agents\/[^/]+\/metrics$/) && req.method === 'GET') {
|
|
1512
|
-
const agentId = decodeURIComponent(pathname.split('/')[3]);
|
|
1513
|
-
// Parse query params from raw URL
|
|
1514
|
-
const rawUrl = req.url || pathname;
|
|
1515
|
-
const qIdx = rawUrl.indexOf('?');
|
|
1516
|
-
const params = qIdx >= 0 ? new URLSearchParams(rawUrl.slice(qIdx)) : new URLSearchParams();
|
|
1517
|
-
const from = params.get('from') || '2020-01-01';
|
|
1518
|
-
const to = params.get('to') || '2099-12-31';
|
|
1519
|
-
if (options.sessionsDb) {
|
|
1520
|
-
(0, agent_handler_js_1.handleGetAgentMetrics)(res, agentId, from, to, options.sessionsDb);
|
|
1521
|
-
}
|
|
1522
|
-
else {
|
|
1523
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1524
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1525
|
-
}
|
|
1526
|
-
return true;
|
|
1527
|
-
}
|
|
1528
|
-
// Route: GET /api/agents/:id/activity?limit= — activity log
|
|
1529
|
-
if (pathname.match(/^\/api\/agents\/[^/]+\/activity$/) && req.method === 'GET') {
|
|
1530
|
-
const agentId = decodeURIComponent(pathname.split('/')[3]);
|
|
1531
|
-
const rawUrl = req.url || pathname;
|
|
1532
|
-
const qIdx = rawUrl.indexOf('?');
|
|
1533
|
-
const params = qIdx >= 0 ? new URLSearchParams(rawUrl.slice(qIdx)) : new URLSearchParams();
|
|
1534
|
-
const limit = parsePositiveInt(params.get('limit'), 20, 100);
|
|
1535
|
-
if (options.sessionsDb) {
|
|
1536
|
-
(0, agent_handler_js_1.handleGetAgentActivity)(res, agentId, options.sessionsDb, limit);
|
|
1537
|
-
}
|
|
1538
|
-
else {
|
|
1539
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1540
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1541
|
-
}
|
|
1542
|
-
return true;
|
|
1543
|
-
}
|
|
1544
|
-
// Route: POST /api/agents/:id/archive — archive agent
|
|
1545
|
-
if (pathname.match(/^\/api\/agents\/[^/]+\/archive$/) && req.method === 'POST') {
|
|
1546
|
-
const agentId = decodeURIComponent(pathname.split('/')[3]);
|
|
1547
|
-
if (options.sessionsDb) {
|
|
1548
|
-
(0, agent_handler_js_1.handleArchiveAgent)(res, agentId, options.sessionsDb);
|
|
1549
|
-
}
|
|
1550
|
-
else {
|
|
1551
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1552
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1553
|
-
}
|
|
1554
|
-
return true;
|
|
1555
|
-
}
|
|
1556
|
-
// ── Validation API ──────────────────────────────────────────────────
|
|
1557
|
-
// Route: GET /api/agents/:id/validation/summary?trigger_type=
|
|
1558
|
-
if (pathname.match(/^\/api\/agents\/[^/]+\/validation\/summary$/) && req.method === 'GET') {
|
|
1559
|
-
const agentId = decodeURIComponent(pathname.split('/')[3]);
|
|
1560
|
-
if (options.sessionsDb) {
|
|
1561
|
-
const triggerType = parseValidationTriggerType(params.get('trigger_type'));
|
|
1562
|
-
if (!triggerType) {
|
|
1563
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1564
|
-
res.end(JSON.stringify({ error: 'trigger_type required' }));
|
|
1565
|
-
return true;
|
|
1566
|
-
}
|
|
1567
|
-
const summary = (0, store_js_1.getValidationSummary)(options.sessionsDb, agentId, triggerType);
|
|
1568
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1569
|
-
res.end(JSON.stringify({ summary }));
|
|
1570
|
-
}
|
|
1571
|
-
else {
|
|
1572
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1573
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1574
|
-
}
|
|
1575
|
-
return true;
|
|
1576
|
-
}
|
|
1577
|
-
// Route: GET /api/agents/:id/validation/history?trigger_type=
|
|
1578
|
-
if (pathname.match(/^\/api\/agents\/[^/]+\/validation\/history$/) && req.method === 'GET') {
|
|
1579
|
-
const agentId = decodeURIComponent(pathname.split('/')[3]);
|
|
1580
|
-
if (options.sessionsDb) {
|
|
1581
|
-
const rawUrl = req.url || pathname;
|
|
1582
|
-
const qIdx = rawUrl.indexOf('?');
|
|
1583
|
-
const params = qIdx >= 0 ? new URLSearchParams(rawUrl.slice(qIdx)) : new URLSearchParams();
|
|
1584
|
-
const limit = parsePositiveInt(params.get('limit'), 50, 200);
|
|
1585
|
-
const triggerType = parseValidationTriggerType(params.get('trigger_type'));
|
|
1586
|
-
if (!triggerType) {
|
|
1587
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1588
|
-
res.end(JSON.stringify({ error: 'trigger_type required' }));
|
|
1589
|
-
return true;
|
|
1590
|
-
}
|
|
1591
|
-
const history = (0, store_js_1.listValidationHistory)(options.sessionsDb, agentId, limit, triggerType);
|
|
1592
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1593
|
-
res.end(JSON.stringify({ history }));
|
|
1594
|
-
}
|
|
1595
|
-
else {
|
|
1596
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1597
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1598
|
-
}
|
|
1599
|
-
return true;
|
|
1600
|
-
}
|
|
1601
|
-
// Route: GET /api/validation-sessions/:id
|
|
1602
|
-
if (pathname.match(/^\/api\/validation-sessions\/[^/]+$/) && req.method === 'GET') {
|
|
1603
|
-
const sessionId = decodeURIComponent(pathname.split('/')[3]);
|
|
1604
|
-
if (options.sessionsDb) {
|
|
1605
|
-
const detail = (0, store_js_1.getValidationSessionDetail)(options.sessionsDb, sessionId);
|
|
1606
|
-
if (!detail) {
|
|
1607
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
1608
|
-
res.end(JSON.stringify({ error: 'Session not found' }));
|
|
1609
|
-
}
|
|
1610
|
-
else {
|
|
1611
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1612
|
-
res.end(JSON.stringify(detail));
|
|
1613
|
-
}
|
|
1614
|
-
}
|
|
1615
|
-
else {
|
|
1616
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1617
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1618
|
-
}
|
|
1619
|
-
return true;
|
|
1620
|
-
}
|
|
1621
|
-
// Route: POST /api/agents/:id/validation/approve
|
|
1622
|
-
if (pathname.match(/^\/api\/agents\/[^/]+\/validation\/approve$/) && req.method === 'POST') {
|
|
1623
|
-
const agentId = decodeURIComponent(pathname.split('/')[3]);
|
|
1624
|
-
if (options.sessionsDb) {
|
|
1625
|
-
const rawUrl = req.url || pathname;
|
|
1626
|
-
const qIdx = rawUrl.indexOf('?');
|
|
1627
|
-
const params = qIdx >= 0 ? new URLSearchParams(rawUrl.slice(qIdx)) : new URLSearchParams();
|
|
1628
|
-
let sessionId = params.get('session_id');
|
|
1629
|
-
if (!sessionId) {
|
|
1630
|
-
const body = await readBodyOrRespond(req, res);
|
|
1631
|
-
if (!body) {
|
|
1632
|
-
return true;
|
|
1633
|
-
}
|
|
1634
|
-
sessionId = body?.session_id;
|
|
1635
|
-
}
|
|
1636
|
-
if (!sessionId) {
|
|
1637
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1638
|
-
res.end(JSON.stringify({ error: 'session_id required' }));
|
|
1639
|
-
}
|
|
1640
|
-
else {
|
|
1641
|
-
const detail = (0, store_js_1.getValidationSessionDetail)(options.sessionsDb, sessionId);
|
|
1642
|
-
if (!detail) {
|
|
1643
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
1644
|
-
res.end(JSON.stringify({ error: 'Session not found' }));
|
|
1645
|
-
return true;
|
|
1646
|
-
}
|
|
1647
|
-
if (detail.session.agent_id !== agentId) {
|
|
1648
|
-
res.writeHead(403, { 'Content-Type': 'application/json' });
|
|
1649
|
-
res.end(JSON.stringify({ error: 'session does not belong to requested agent' }));
|
|
1650
|
-
return true;
|
|
1651
|
-
}
|
|
1652
|
-
try {
|
|
1653
|
-
(0, store_js_1.approveValidationSession)(options.sessionsDb, sessionId);
|
|
1654
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1655
|
-
res.end(JSON.stringify({ success: true, approved_session: sessionId }));
|
|
1656
|
-
}
|
|
1657
|
-
catch (error) {
|
|
1658
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1659
|
-
const statusCode = /not found|required|invalid/i.test(message) ? 400 : 500;
|
|
1660
|
-
res.writeHead(statusCode, { 'Content-Type': 'application/json' });
|
|
1661
|
-
res.end(JSON.stringify({ error: message }));
|
|
1662
|
-
}
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
else {
|
|
1666
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1667
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1668
|
-
}
|
|
1669
|
-
return true;
|
|
1670
|
-
}
|
|
1671
|
-
// Route: GET /api/agents/:id/validation/compare?session=X&baseline=approved
|
|
1672
|
-
if (pathname.match(/^\/api\/agents\/[^/]+\/validation\/compare$/) && req.method === 'GET') {
|
|
1673
|
-
const agentId = decodeURIComponent(pathname.split('/')[3]);
|
|
1674
|
-
if (options.sessionsDb) {
|
|
1675
|
-
const rawUrl = req.url || pathname;
|
|
1676
|
-
const qIdx = rawUrl.indexOf('?');
|
|
1677
|
-
const params = qIdx >= 0 ? new URLSearchParams(rawUrl.slice(qIdx)) : new URLSearchParams();
|
|
1678
|
-
const sessionId = params.get('session');
|
|
1679
|
-
const baselineMode = params.get('baseline') || 'approved';
|
|
1680
|
-
if (!sessionId) {
|
|
1681
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1682
|
-
res.end(JSON.stringify({ error: 'session query parameter required' }));
|
|
1683
|
-
}
|
|
1684
|
-
else {
|
|
1685
|
-
const current = (0, store_js_1.getValidationSessionDetail)(options.sessionsDb, sessionId);
|
|
1686
|
-
if (!current) {
|
|
1687
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
1688
|
-
res.end(JSON.stringify({ error: 'Session not found' }));
|
|
1689
|
-
}
|
|
1690
|
-
else if (current.session.agent_id !== agentId) {
|
|
1691
|
-
res.writeHead(403, { 'Content-Type': 'application/json' });
|
|
1692
|
-
res.end(JSON.stringify({ error: 'session does not belong to requested agent' }));
|
|
1693
|
-
}
|
|
1694
|
-
else {
|
|
1695
|
-
let baselineSessionId = null;
|
|
1696
|
-
if (baselineMode === 'approved') {
|
|
1697
|
-
const state = (0, store_js_1.getAgentValidationState)(options.sessionsDb, agentId, current.session.trigger_type);
|
|
1698
|
-
baselineSessionId = state?.approved_session_id ?? null;
|
|
1699
|
-
}
|
|
1700
|
-
else {
|
|
1701
|
-
baselineSessionId = baselineMode;
|
|
1702
|
-
}
|
|
1703
|
-
const baseline = baselineSessionId
|
|
1704
|
-
? (0, store_js_1.getValidationSessionDetail)(options.sessionsDb, baselineSessionId)
|
|
1705
|
-
: null;
|
|
1706
|
-
if (baselineMode !== 'approved' && baselineSessionId && !baseline) {
|
|
1707
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
1708
|
-
res.end(JSON.stringify({ error: 'baseline session not found' }));
|
|
1709
|
-
return true;
|
|
1710
|
-
}
|
|
1711
|
-
if (baseline && baseline.session.agent_id !== agentId) {
|
|
1712
|
-
res.writeHead(403, { 'Content-Type': 'application/json' });
|
|
1713
|
-
res.end(JSON.stringify({ error: 'baseline session does not belong to requested agent' }));
|
|
1714
|
-
return true;
|
|
1715
|
-
}
|
|
1716
|
-
if (baseline && baseline.session.trigger_type !== current.session.trigger_type) {
|
|
1717
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1718
|
-
res.end(JSON.stringify({
|
|
1719
|
-
error: 'baseline session trigger_type does not match current session',
|
|
1720
|
-
}));
|
|
1721
|
-
return true;
|
|
1722
|
-
}
|
|
1723
|
-
const baselineMetrics = new Map((baseline?.metrics ?? []).map((m) => [
|
|
1724
|
-
m.name,
|
|
1725
|
-
m.value,
|
|
1726
|
-
]));
|
|
1727
|
-
const deltas = current.metrics.map((m) => {
|
|
1728
|
-
const bVal = baselineMetrics.get(m.name);
|
|
1729
|
-
return {
|
|
1730
|
-
name: m.name,
|
|
1731
|
-
current: m.value,
|
|
1732
|
-
baseline: bVal ?? null,
|
|
1733
|
-
delta: bVal !== undefined ? m.value - bVal : null,
|
|
1734
|
-
direction: m.direction,
|
|
1735
|
-
};
|
|
1736
|
-
});
|
|
1737
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1738
|
-
res.end(JSON.stringify({ current, baseline, deltas }));
|
|
1739
|
-
}
|
|
1740
|
-
}
|
|
1741
|
-
}
|
|
1742
|
-
else {
|
|
1743
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1744
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1745
|
-
}
|
|
1746
|
-
return true;
|
|
1747
|
-
}
|
|
1748
|
-
// Route: GET /api/agents/activity-summary — aggregated activity with alerts
|
|
1749
|
-
if (pathname === '/api/agents/activity-summary' && req.method === 'GET') {
|
|
1750
|
-
const rawUrl = req.url || pathname;
|
|
1751
|
-
const qIdx = rawUrl.indexOf('?');
|
|
1752
|
-
const params = qIdx >= 0 ? new URLSearchParams(rawUrl.slice(qIdx)) : new URLSearchParams();
|
|
1753
|
-
const since = params.get('since') || new Date(Date.now() - 86400000).toISOString().slice(0, 10);
|
|
1754
|
-
if (options.sessionsDb) {
|
|
1755
|
-
(0, agent_handler_js_1.handleGetActivitySummary)(res, options.sessionsDb, since);
|
|
1756
|
-
}
|
|
1757
|
-
else {
|
|
1758
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1759
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1760
|
-
}
|
|
1761
|
-
return true;
|
|
1762
|
-
}
|
|
1763
|
-
// Route: GET /api/agents — list all agents
|
|
1764
|
-
if (pathname === '/api/agents' && req.method === 'GET') {
|
|
1765
|
-
const config = loadMAMAConfig();
|
|
1766
|
-
if (options.sessionsDb) {
|
|
1767
|
-
(0, agent_handler_js_1.handleGetAgents)(res, config, options.sessionsDb);
|
|
1768
|
-
}
|
|
1769
|
-
else {
|
|
1770
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1771
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1772
|
-
}
|
|
1773
|
-
return true;
|
|
1774
|
-
}
|
|
1775
|
-
// Route: POST /api/agents — create new agent
|
|
1776
|
-
if (pathname === '/api/agents' && req.method === 'POST') {
|
|
1777
|
-
const body = await readBodyOrRespond(req, res);
|
|
1778
|
-
if (!body) {
|
|
1779
|
-
return true;
|
|
1780
|
-
}
|
|
1781
|
-
if (options.sessionsDb) {
|
|
1782
|
-
await (0, agent_handler_js_1.handleCreateAgent)(res, body, options.sessionsDb, {
|
|
1783
|
-
loadConfig: async () => loadMAMAConfig(),
|
|
1784
|
-
saveConfig: async (config) => saveMAMAConfig(config),
|
|
1785
|
-
applyMultiAgentConfig: options.applyMultiAgentConfig ?? null,
|
|
1786
|
-
restartMultiAgentAgent: options.restartMultiAgentAgent ?? null,
|
|
1787
|
-
});
|
|
1788
|
-
}
|
|
1789
|
-
else {
|
|
1790
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1791
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1792
|
-
}
|
|
1793
|
-
return true;
|
|
1794
|
-
}
|
|
1795
|
-
// Route: GET /api/agents/:id — single agent detail (must be after /api/agents/:id/*)
|
|
1796
|
-
if (pathname.match(/^\/api\/agents\/[^/]+$/) && req.method === 'GET') {
|
|
1797
|
-
const agentId = decodeURIComponent(pathname.split('/')[3]);
|
|
1798
|
-
const config = loadMAMAConfig();
|
|
1799
|
-
if (options.sessionsDb) {
|
|
1800
|
-
(0, agent_handler_js_1.handleGetAgent)(res, agentId, config, options.sessionsDb);
|
|
1801
|
-
}
|
|
1802
|
-
else {
|
|
1803
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1804
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1805
|
-
}
|
|
1806
|
-
return true;
|
|
1807
|
-
}
|
|
1808
|
-
// Route: POST /api/agents/:id — update agent (Managed Agents: version required)
|
|
1809
|
-
if (pathname.match(/^\/api\/agents\/[^/]+$/) && req.method === 'POST') {
|
|
1810
|
-
const agentId = decodeURIComponent(pathname.split('/')[3]);
|
|
1811
|
-
const body = await readBodyOrRespond(req, res);
|
|
1812
|
-
if (!body) {
|
|
1813
|
-
return true;
|
|
1814
|
-
}
|
|
1815
|
-
if (options.sessionsDb) {
|
|
1816
|
-
await (0, agent_handler_js_1.handleUpdateAgent)(res, agentId, body, options.sessionsDb, {
|
|
1817
|
-
loadConfig: async () => loadMAMAConfig(),
|
|
1818
|
-
saveConfig: async (config) => saveMAMAConfig(config),
|
|
1819
|
-
applyMultiAgentConfig: options.applyMultiAgentConfig ?? null,
|
|
1820
|
-
restartMultiAgentAgent: options.restartMultiAgentAgent ?? null,
|
|
1821
|
-
});
|
|
1822
|
-
}
|
|
1823
|
-
else {
|
|
1824
|
-
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1825
|
-
res.end(JSON.stringify({ error: 'Sessions DB not available' }));
|
|
1826
|
-
}
|
|
1827
|
-
return true;
|
|
1828
|
-
}
|
|
1829
|
-
// ── Legacy Multi-Agent API (redirect-compatible) ──
|
|
1830
|
-
// Route: GET /api/multi-agent/status - get multi-agent system status
|
|
1831
|
-
if (pathname === '/api/multi-agent/status' && req.method === 'GET') {
|
|
1832
|
-
await handleMultiAgentStatusRequest(req, res, options);
|
|
1833
|
-
return true;
|
|
1834
|
-
}
|
|
1835
|
-
// Route: GET /api/multi-agent/agents - get all agents config
|
|
1836
|
-
if (pathname === '/api/multi-agent/agents' && req.method === 'GET') {
|
|
1837
|
-
await handleMultiAgentAgentsRequest(req, res);
|
|
1838
|
-
return true;
|
|
1839
|
-
}
|
|
1840
|
-
// Route: PUT /api/multi-agent/agents/:id - update agent config
|
|
1841
|
-
if (pathname.startsWith('/api/multi-agent/agents/') && req.method === 'PUT') {
|
|
1842
|
-
await handleMultiAgentUpdateAgentRequest(req, res, pathname, options);
|
|
1843
|
-
return true;
|
|
1844
|
-
}
|
|
1845
|
-
// Route: POST /api/multi-agent/agents/:id/restart - restart a single agent
|
|
1846
|
-
if (pathname.match(/^\/api\/multi-agent\/agents\/[^/]+\/restart$/) && req.method === 'POST') {
|
|
1847
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
1848
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
1849
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
1850
|
-
res.end(JSON.stringify({ success: false, error: 'Authentication required' }));
|
|
1851
|
-
return true;
|
|
1852
|
-
}
|
|
1853
|
-
const agentId = decodeURIComponent(pathname.split('/')[4]);
|
|
1854
|
-
if (!options.restartMultiAgentAgent) {
|
|
1855
|
-
res.writeHead(501, { 'Content-Type': 'application/json' });
|
|
1856
|
-
res.end(JSON.stringify({ success: false, error: 'Restart callback not configured' }));
|
|
1857
|
-
return true;
|
|
1858
|
-
}
|
|
1859
|
-
try {
|
|
1860
|
-
await options.restartMultiAgentAgent(agentId);
|
|
1861
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1862
|
-
res.end(JSON.stringify({ success: true, message: `Agent ${agentId} restarted` }));
|
|
1863
|
-
}
|
|
1864
|
-
catch (err) {
|
|
1865
|
-
logger.error(`Agent restart failed for ${agentId}:`, err);
|
|
1866
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
1867
|
-
res.end(JSON.stringify({
|
|
1868
|
-
success: false,
|
|
1869
|
-
error: err instanceof Error ? err.message : String(err),
|
|
1870
|
-
}));
|
|
1871
|
-
}
|
|
1872
|
-
return true;
|
|
1873
|
-
}
|
|
1874
|
-
// Route: POST /api/multi-agent/agents/:id/stop - stop a single agent
|
|
1875
|
-
if (pathname.match(/^\/api\/multi-agent\/agents\/[^/]+\/stop$/) && req.method === 'POST') {
|
|
1876
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
1877
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
1878
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
1879
|
-
res.end(JSON.stringify({ success: false, error: 'Authentication required' }));
|
|
1880
|
-
return true;
|
|
1881
|
-
}
|
|
1882
|
-
const agentId = decodeURIComponent(pathname.split('/')[4]);
|
|
1883
|
-
if (!options.stopMultiAgentAgent) {
|
|
1884
|
-
res.writeHead(501, { 'Content-Type': 'application/json' });
|
|
1885
|
-
res.end(JSON.stringify({ success: false, error: 'Stop callback not configured' }));
|
|
1886
|
-
return true;
|
|
1887
|
-
}
|
|
1888
|
-
try {
|
|
1889
|
-
await options.stopMultiAgentAgent(agentId);
|
|
1890
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1891
|
-
res.end(JSON.stringify({ success: true, message: `Agent ${agentId} stopped` }));
|
|
1892
|
-
}
|
|
1893
|
-
catch (err) {
|
|
1894
|
-
logger.error(`Agent stop failed for ${agentId}:`, err);
|
|
1895
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
1896
|
-
res.end(JSON.stringify({
|
|
1897
|
-
success: false,
|
|
1898
|
-
error: err instanceof Error ? err.message : String(err),
|
|
1899
|
-
}));
|
|
1900
|
-
}
|
|
1901
|
-
return true;
|
|
1902
|
-
}
|
|
1903
|
-
// Route: GET /api/mcp-servers - get available MCP servers from config
|
|
1904
|
-
if (pathname === '/api/mcp-servers' && req.method === 'GET') {
|
|
1905
|
-
await handleMCPServersRequest(req, res);
|
|
1906
|
-
return true;
|
|
1907
|
-
}
|
|
1908
|
-
// Route: DELETE /api/mcp-servers/:name - remove MCP server from config
|
|
1909
|
-
if (pathname.startsWith('/api/mcp-servers/') && req.method === 'DELETE') {
|
|
1910
|
-
await handleDeleteMCPServerRequest(req, res, pathname);
|
|
1911
|
-
return true;
|
|
1912
|
-
}
|
|
1913
|
-
// Route: POST /api/code-act - execute code in Code-Act sandbox
|
|
1914
|
-
if (pathname === '/api/code-act' && req.method === 'POST') {
|
|
1915
|
-
await handleCodeActRequest(req, res, options);
|
|
1916
|
-
return true;
|
|
1917
|
-
}
|
|
1918
|
-
// Route: GET /api/entities/candidates - list pending review candidates
|
|
1919
|
-
if (pathname === '/api/entities/candidates' && req.method === 'GET') {
|
|
1920
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
1921
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
1922
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
1923
|
-
res.end(JSON.stringify({
|
|
1924
|
-
error: true,
|
|
1925
|
-
code: 'UNAUTHORIZED',
|
|
1926
|
-
message: 'Authentication required. Provide Authorization: Bearer <token> header.',
|
|
1927
|
-
}));
|
|
1928
|
-
return true;
|
|
1929
|
-
}
|
|
1930
|
-
await initDB();
|
|
1931
|
-
await (0, entity_review_handler_js_1.handleListEntityCandidates)(req, res, getAdapter());
|
|
1932
|
-
return true;
|
|
1933
|
-
}
|
|
1934
|
-
// Route: POST /api/entities/candidates/:id/{approve,reject,defer}
|
|
1935
|
-
{
|
|
1936
|
-
const reviewMatch = pathname.match(/^\/api\/entities\/candidates\/([^/]+)\/(approve|reject|defer)$/);
|
|
1937
|
-
if (reviewMatch && req.method === 'POST') {
|
|
1938
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
1939
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
1940
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
1941
|
-
res.end(JSON.stringify({
|
|
1942
|
-
error: true,
|
|
1943
|
-
code: 'UNAUTHORIZED',
|
|
1944
|
-
message: 'Authentication required. Provide Authorization: Bearer <token> header.',
|
|
1945
|
-
}));
|
|
1946
|
-
return true;
|
|
1947
|
-
}
|
|
1948
|
-
await initDB();
|
|
1949
|
-
const action = reviewMatch[2];
|
|
1950
|
-
await (0, entity_review_handler_js_1.handleReviewEntityCandidate)(req, res, getAdapter(), action);
|
|
1951
|
-
return true;
|
|
1952
|
-
}
|
|
1953
|
-
}
|
|
1954
|
-
// Route: GET /api/entities/candidates/:id - candidate detail
|
|
1955
|
-
{
|
|
1956
|
-
const detailMatch = pathname.match(/^\/api\/entities\/candidates\/([^/]+)$/);
|
|
1957
|
-
if (detailMatch && req.method === 'GET') {
|
|
1958
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
1959
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
1960
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
1961
|
-
res.end(JSON.stringify({
|
|
1962
|
-
error: true,
|
|
1963
|
-
code: 'UNAUTHORIZED',
|
|
1964
|
-
message: 'Authentication required. Provide Authorization: Bearer <token> header.',
|
|
1965
|
-
}));
|
|
1966
|
-
return true;
|
|
1967
|
-
}
|
|
1968
|
-
await initDB();
|
|
1969
|
-
await (0, entity_review_handler_js_1.handleGetEntityCandidate)(req, res, getAdapter());
|
|
1970
|
-
return true;
|
|
1971
|
-
}
|
|
1972
|
-
}
|
|
1973
|
-
// Route: POST /api/entities/audit/run - start a new audit run
|
|
1974
|
-
if (pathname === '/api/entities/audit/run' && req.method === 'POST') {
|
|
1975
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
1976
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
1977
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
1978
|
-
res.end(JSON.stringify({
|
|
1979
|
-
error: true,
|
|
1980
|
-
code: 'UNAUTHORIZED',
|
|
1981
|
-
message: 'Authentication required. Provide Authorization: Bearer <token> header.',
|
|
1982
|
-
}));
|
|
1983
|
-
return true;
|
|
1984
|
-
}
|
|
1985
|
-
const queue = await getEntityAuditQueue();
|
|
1986
|
-
const deps = {
|
|
1987
|
-
queue,
|
|
1988
|
-
runAuditInBackground: (runId) => {
|
|
1989
|
-
void (0, entity_audit_runner_js_1.runEntityAuditInBackground)({
|
|
1990
|
-
queue,
|
|
1991
|
-
adapter: getAdapter(),
|
|
1992
|
-
runId,
|
|
1993
|
-
});
|
|
1994
|
-
},
|
|
1995
|
-
};
|
|
1996
|
-
const handler = (0, entity_audit_handler_js_1.createEntityAuditHandler)(deps);
|
|
1997
|
-
await handler.handleStartAuditRun(req, res);
|
|
1998
|
-
return true;
|
|
1999
|
-
}
|
|
2000
|
-
// Route: GET /api/entities/audit/runs - list recent audit runs
|
|
2001
|
-
if (pathname === '/api/entities/audit/runs' && req.method === 'GET') {
|
|
2002
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
2003
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
2004
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
2005
|
-
res.end(JSON.stringify({
|
|
2006
|
-
error: true,
|
|
2007
|
-
code: 'UNAUTHORIZED',
|
|
2008
|
-
message: 'Authentication required. Provide Authorization: Bearer <token> header.',
|
|
2009
|
-
}));
|
|
2010
|
-
return true;
|
|
2011
|
-
}
|
|
2012
|
-
const queue = await getEntityAuditQueue();
|
|
2013
|
-
const handler = (0, entity_audit_handler_js_1.createEntityAuditHandler)({
|
|
2014
|
-
queue,
|
|
2015
|
-
});
|
|
2016
|
-
await handler.handleListAuditRuns(req, res);
|
|
2017
|
-
return true;
|
|
2018
|
-
}
|
|
2019
|
-
// Route: GET /api/entities/audit/runs/:id - single run detail
|
|
2020
|
-
{
|
|
2021
|
-
const runDetail = pathname.match(/^\/api\/entities\/audit\/runs\/([^/]+)$/);
|
|
2022
|
-
if (runDetail && req.method === 'GET') {
|
|
2023
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
2024
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
2025
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
2026
|
-
res.end(JSON.stringify({
|
|
2027
|
-
error: true,
|
|
2028
|
-
code: 'UNAUTHORIZED',
|
|
2029
|
-
message: 'Authentication required. Provide Authorization: Bearer <token> header.',
|
|
2030
|
-
}));
|
|
2031
|
-
return true;
|
|
2032
|
-
}
|
|
2033
|
-
const queue = await getEntityAuditQueue();
|
|
2034
|
-
const handler = (0, entity_audit_handler_js_1.createEntityAuditHandler)({
|
|
2035
|
-
queue,
|
|
2036
|
-
});
|
|
2037
|
-
await handler.handleGetAuditRun(req, res);
|
|
2038
|
-
return true;
|
|
2039
|
-
}
|
|
2040
|
-
}
|
|
2041
|
-
return false;
|
|
2042
|
-
};
|
|
2043
|
-
}
|
|
2044
|
-
async function handleDashboardStatusRequest(_req, res) {
|
|
2045
|
-
try {
|
|
2046
|
-
const config = loadMAMAConfig();
|
|
2047
|
-
await initDB();
|
|
2048
|
-
const memoryStats = await getMemoryStats();
|
|
2049
|
-
const gateways = {
|
|
2050
|
-
discord: {
|
|
2051
|
-
configured: !!config.discord?.token,
|
|
2052
|
-
enabled: config.discord?.enabled ?? false,
|
|
2053
|
-
channel: config.discord?.default_channel_id || null,
|
|
2054
|
-
},
|
|
2055
|
-
slack: {
|
|
2056
|
-
configured: !!config.slack?.bot_token,
|
|
2057
|
-
enabled: config.slack?.enabled ?? false,
|
|
2058
|
-
channel: config.slack?.default_channel || null,
|
|
2059
|
-
},
|
|
2060
|
-
telegram: {
|
|
2061
|
-
configured: !!config.telegram?.token,
|
|
2062
|
-
enabled: config.telegram?.enabled ?? false,
|
|
2063
|
-
chats: config.telegram?.allowed_chats || [],
|
|
2064
|
-
},
|
|
2065
|
-
chatwork: {
|
|
2066
|
-
configured: !!config.chatwork?.api_token,
|
|
2067
|
-
enabled: config.chatwork?.enabled ?? false,
|
|
2068
|
-
rooms: config.chatwork?.room_ids || [],
|
|
2069
|
-
},
|
|
2070
|
-
};
|
|
2071
|
-
const heartbeat = {
|
|
2072
|
-
enabled: config.heartbeat?.enabled ?? false,
|
|
2073
|
-
interval: config.heartbeat?.interval ?? 1800000,
|
|
2074
|
-
quietStart: config.heartbeat?.quiet_start ?? 23,
|
|
2075
|
-
quietEnd: config.heartbeat?.quiet_end ?? 8,
|
|
2076
|
-
};
|
|
2077
|
-
const agent = {
|
|
2078
|
-
model: config.agent?.model || 'unknown',
|
|
2079
|
-
maxTurns: config.agent?.max_turns ?? 10,
|
|
2080
|
-
timeout: config.agent?.timeout ?? 300000,
|
|
2081
|
-
tools: config.agent?.tools || { gateway: ['*'], mcp: [] },
|
|
2082
|
-
};
|
|
2083
|
-
const sessionStats = getSessionStats();
|
|
2084
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
2085
|
-
res.end(JSON.stringify({
|
|
2086
|
-
timestamp: new Date().toISOString(),
|
|
2087
|
-
gateways,
|
|
2088
|
-
heartbeat,
|
|
2089
|
-
agent,
|
|
2090
|
-
memory: memoryStats,
|
|
2091
|
-
sessions: sessionStats,
|
|
2092
|
-
database: {
|
|
2093
|
-
path: config.database?.path ?? '~/.claude/mama-memory.db',
|
|
2094
|
-
},
|
|
2095
|
-
}));
|
|
2096
|
-
}
|
|
2097
|
-
catch (error) {
|
|
2098
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2099
|
-
console.error(`[GraphAPI] Dashboard status error: ${message}`);
|
|
2100
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
2101
|
-
res.end(JSON.stringify({
|
|
2102
|
-
error: true,
|
|
2103
|
-
code: 'DASHBOARD_ERROR',
|
|
2104
|
-
message,
|
|
2105
|
-
}));
|
|
2106
|
-
}
|
|
2107
|
-
}
|
|
2108
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2109
|
-
function loadMAMAConfig() {
|
|
2110
|
-
try {
|
|
2111
|
-
if (!fs_1.default.existsSync(MAMA_CONFIG_PATH)) {
|
|
2112
|
-
console.log('[GraphAPI] Config file not found:', MAMA_CONFIG_PATH);
|
|
2113
|
-
return {};
|
|
2114
|
-
}
|
|
2115
|
-
const content = fs_1.default.readFileSync(MAMA_CONFIG_PATH, 'utf8');
|
|
2116
|
-
const config = js_yaml_1.default.load(content) || {};
|
|
2117
|
-
return migrateLegacyManagedBackends(config);
|
|
2118
|
-
}
|
|
2119
|
-
catch (error) {
|
|
2120
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2121
|
-
console.error('[GraphAPI] Config load error:', message);
|
|
2122
|
-
return {};
|
|
2123
|
-
}
|
|
2124
|
-
}
|
|
2125
|
-
async function getMemoryStats() {
|
|
2126
|
-
try {
|
|
2127
|
-
const adapter = getAdapter();
|
|
2128
|
-
const now = Date.now();
|
|
2129
|
-
const weekAgo = now - 7 * 24 * 60 * 60 * 1000;
|
|
2130
|
-
const monthAgo = now - 30 * 24 * 60 * 60 * 1000;
|
|
2131
|
-
const totalResult = adapter.prepare('SELECT COUNT(*) as count FROM decisions').get();
|
|
2132
|
-
const total = totalResult?.count ?? 0;
|
|
2133
|
-
const weekResult = adapter
|
|
2134
|
-
.prepare('SELECT COUNT(*) as count FROM decisions WHERE created_at > ?')
|
|
2135
|
-
.get(weekAgo);
|
|
2136
|
-
const thisWeek = weekResult?.count ?? 0;
|
|
2137
|
-
const monthResult = adapter
|
|
2138
|
-
.prepare('SELECT COUNT(*) as count FROM decisions WHERE created_at > ?')
|
|
2139
|
-
.get(monthAgo);
|
|
2140
|
-
const thisMonth = monthResult?.count ?? 0;
|
|
2141
|
-
const outcomeResults = adapter
|
|
2142
|
-
.prepare(`
|
|
2143
|
-
SELECT outcome, COUNT(*) as count
|
|
2144
|
-
FROM decisions
|
|
2145
|
-
WHERE outcome IS NOT NULL
|
|
2146
|
-
GROUP BY outcome
|
|
2147
|
-
`)
|
|
2148
|
-
.all();
|
|
2149
|
-
const outcomes = {};
|
|
2150
|
-
for (const row of outcomeResults) {
|
|
2151
|
-
outcomes[row.outcome?.toLowerCase() ?? 'unknown'] = row.count;
|
|
2152
|
-
}
|
|
2153
|
-
const topicResults = adapter
|
|
2154
|
-
.prepare(`
|
|
2155
|
-
SELECT topic, COUNT(*) as count
|
|
2156
|
-
FROM decisions
|
|
2157
|
-
WHERE topic IS NOT NULL
|
|
2158
|
-
GROUP BY topic
|
|
2159
|
-
ORDER BY count DESC
|
|
2160
|
-
LIMIT 5
|
|
2161
|
-
`)
|
|
2162
|
-
.all();
|
|
2163
|
-
const checkpointResult = adapter.prepare('SELECT COUNT(*) as count FROM checkpoints').get();
|
|
2164
|
-
const checkpoints = checkpointResult?.count ?? 0;
|
|
2165
|
-
return {
|
|
2166
|
-
total,
|
|
2167
|
-
thisWeek,
|
|
2168
|
-
thisMonth,
|
|
2169
|
-
checkpoints,
|
|
2170
|
-
outcomes,
|
|
2171
|
-
topTopics: topicResults,
|
|
2172
|
-
};
|
|
2173
|
-
}
|
|
2174
|
-
catch (error) {
|
|
2175
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2176
|
-
console.error('[GraphAPI] Memory stats error:', message);
|
|
2177
|
-
return {
|
|
2178
|
-
total: 0,
|
|
2179
|
-
thisWeek: 0,
|
|
2180
|
-
thisMonth: 0,
|
|
2181
|
-
checkpoints: 0,
|
|
2182
|
-
outcomes: {},
|
|
2183
|
-
topTopics: [],
|
|
2184
|
-
};
|
|
2185
|
-
}
|
|
2186
|
-
}
|
|
2187
|
-
function getSessionStats() {
|
|
2188
|
-
try {
|
|
2189
|
-
const config = loadMAMAConfig();
|
|
2190
|
-
const memoryDbPath = config.database?.path || '~/.claude/mama-memory.db';
|
|
2191
|
-
const expandedPath = memoryDbPath.startsWith('~/')
|
|
2192
|
-
? path_1.default.join(os_1.default.homedir(), memoryDbPath.slice(2))
|
|
2193
|
-
: memoryDbPath;
|
|
2194
|
-
const sessionsDbPath = expandedPath.replace('mama-memory.db', 'mama-sessions.db');
|
|
2195
|
-
if (!fs_1.default.existsSync(sessionsDbPath)) {
|
|
2196
|
-
return { total: 0, bySource: {}, channels: [] };
|
|
2197
|
-
}
|
|
2198
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
2199
|
-
const Database = require('../sqlite.js').default;
|
|
2200
|
-
const sessionsDb = new Database(sessionsDbPath);
|
|
2201
|
-
try {
|
|
2202
|
-
const bySourceRows = sessionsDb
|
|
2203
|
-
.prepare(`
|
|
2204
|
-
SELECT source, COUNT(*) as count
|
|
2205
|
-
FROM messenger_sessions
|
|
2206
|
-
GROUP BY source
|
|
2207
|
-
`)
|
|
2208
|
-
.all();
|
|
2209
|
-
const bySource = {};
|
|
2210
|
-
let total = 0;
|
|
2211
|
-
for (const row of bySourceRows) {
|
|
2212
|
-
bySource[row.source] = row.count;
|
|
2213
|
-
total += row.count;
|
|
2214
|
-
}
|
|
2215
|
-
const channelRows = sessionsDb
|
|
2216
|
-
.prepare(`
|
|
2217
|
-
SELECT
|
|
2218
|
-
source,
|
|
2219
|
-
channel_id,
|
|
2220
|
-
channel_name,
|
|
2221
|
-
last_active,
|
|
2222
|
-
json_array_length(context) as message_count
|
|
2223
|
-
FROM messenger_sessions
|
|
2224
|
-
ORDER BY last_active DESC
|
|
2225
|
-
LIMIT 10
|
|
2226
|
-
`)
|
|
2227
|
-
.all();
|
|
2228
|
-
const channels = channelRows.map((row) => ({
|
|
2229
|
-
source: row.source,
|
|
2230
|
-
channelId: row.channel_id,
|
|
2231
|
-
channelName: row.channel_name || null,
|
|
2232
|
-
lastActive: row.last_active,
|
|
2233
|
-
messageCount: row.message_count || 0,
|
|
2234
|
-
}));
|
|
2235
|
-
return { total, bySource, channels };
|
|
2236
|
-
}
|
|
2237
|
-
finally {
|
|
2238
|
-
sessionsDb.close();
|
|
2239
|
-
}
|
|
2240
|
-
}
|
|
2241
|
-
catch (error) {
|
|
2242
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2243
|
-
console.error('[GraphAPI] Session stats error:', message);
|
|
2244
|
-
return { total: 0, bySource: {}, channels: [] };
|
|
2245
|
-
}
|
|
2246
|
-
}
|
|
2247
|
-
async function handleGetConfigRequest(_req, res) {
|
|
2248
|
-
try {
|
|
2249
|
-
const config = loadMAMAConfig();
|
|
2250
|
-
const maskedConfig = {
|
|
2251
|
-
version: config.version || 1,
|
|
2252
|
-
agent: {
|
|
2253
|
-
...(config.agent || {}),
|
|
2254
|
-
tools: config.agent?.tools || {
|
|
2255
|
-
gateway: ['*'],
|
|
2256
|
-
mcp: [],
|
|
2257
|
-
mcp_config: '~/.mama/mama-mcp-config.json',
|
|
2258
|
-
},
|
|
2259
|
-
},
|
|
2260
|
-
database: config.database || {},
|
|
2261
|
-
logging: config.logging || {},
|
|
2262
|
-
discord: config.discord
|
|
2263
|
-
? {
|
|
2264
|
-
enabled: config.discord.enabled || false,
|
|
2265
|
-
token: config.discord.token ? maskToken(config.discord.token) : '',
|
|
2266
|
-
default_channel_id: config.discord.default_channel_id || '',
|
|
2267
|
-
}
|
|
2268
|
-
: { enabled: false, token: '', default_channel_id: '' },
|
|
2269
|
-
slack: config.slack
|
|
2270
|
-
? {
|
|
2271
|
-
enabled: config.slack.enabled || false,
|
|
2272
|
-
bot_token: config.slack.bot_token ? maskToken(config.slack.bot_token) : '',
|
|
2273
|
-
app_token: config.slack.app_token ? maskToken(config.slack.app_token) : '',
|
|
2274
|
-
}
|
|
2275
|
-
: { enabled: false, bot_token: '', app_token: '' },
|
|
2276
|
-
telegram: config.telegram
|
|
2277
|
-
? {
|
|
2278
|
-
enabled: config.telegram.enabled || false,
|
|
2279
|
-
token: config.telegram.token ? maskToken(config.telegram.token) : '',
|
|
2280
|
-
}
|
|
2281
|
-
: { enabled: false, token: '' },
|
|
2282
|
-
chatwork: config.chatwork
|
|
2283
|
-
? {
|
|
2284
|
-
enabled: config.chatwork.enabled || false,
|
|
2285
|
-
api_token: config.chatwork.api_token ? maskToken(config.chatwork.api_token) : '',
|
|
2286
|
-
}
|
|
2287
|
-
: { enabled: false, api_token: '' },
|
|
2288
|
-
heartbeat: config.heartbeat || {
|
|
2289
|
-
enabled: false,
|
|
2290
|
-
interval: 1800000,
|
|
2291
|
-
quiet_start: 23,
|
|
2292
|
-
quiet_end: 8,
|
|
2293
|
-
},
|
|
2294
|
-
roles: config.roles
|
|
2295
|
-
? {
|
|
2296
|
-
definitions: { ...types_js_1.DEFAULT_ROLES.definitions, ...config.roles.definitions },
|
|
2297
|
-
sourceMapping: { ...types_js_1.DEFAULT_ROLES.sourceMapping, ...config.roles.sourceMapping },
|
|
2298
|
-
}
|
|
2299
|
-
: types_js_1.DEFAULT_ROLES,
|
|
2300
|
-
multi_agent: config.multi_agent
|
|
2301
|
-
? {
|
|
2302
|
-
enabled: config.multi_agent.enabled || false,
|
|
2303
|
-
agents: maskAgentsTokens(config.multi_agent.agents || {}),
|
|
2304
|
-
loop_prevention: config.multi_agent.loop_prevention || {
|
|
2305
|
-
max_chain_length: 3,
|
|
2306
|
-
global_cooldown_ms: 2000,
|
|
2307
|
-
chain_window_ms: 60000,
|
|
2308
|
-
},
|
|
2309
|
-
free_chat: config.multi_agent.free_chat || false,
|
|
2310
|
-
default_agent: config.multi_agent.default_agent || null,
|
|
2311
|
-
mention_delegation: config.multi_agent.mention_delegation || false,
|
|
2312
|
-
max_mention_depth: config.multi_agent.max_mention_depth || 3,
|
|
2313
|
-
workflow: config.multi_agent.workflow || { enabled: true },
|
|
2314
|
-
}
|
|
2315
|
-
: undefined,
|
|
2316
|
-
prompt: config.prompt,
|
|
2317
|
-
timeouts: config.timeouts,
|
|
2318
|
-
gateway_tuning: config.gateway_tuning,
|
|
2319
|
-
io: config.io,
|
|
2320
|
-
metrics: config.metrics,
|
|
2321
|
-
};
|
|
2322
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
2323
|
-
res.end(JSON.stringify(maskedConfig));
|
|
2324
|
-
}
|
|
2325
|
-
catch (error) {
|
|
2326
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2327
|
-
console.error('[GraphAPI] Get config error:', message);
|
|
2328
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
2329
|
-
res.end(JSON.stringify({
|
|
2330
|
-
error: true,
|
|
2331
|
-
code: 'CONFIG_ERROR',
|
|
2332
|
-
message,
|
|
2333
|
-
}));
|
|
2334
|
-
}
|
|
2335
|
-
}
|
|
2336
|
-
async function handleUpdateConfigRequest(req, res, options = {}) {
|
|
2337
|
-
try {
|
|
2338
|
-
// Verify authentication for config modifications
|
|
2339
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
2340
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
2341
|
-
res.writeHead(401, {
|
|
2342
|
-
'Content-Type': 'application/json',
|
|
2343
|
-
'WWW-Authenticate': 'Bearer realm="MAMA API"',
|
|
2344
|
-
});
|
|
2345
|
-
res.end(JSON.stringify({
|
|
2346
|
-
error: true,
|
|
2347
|
-
code: 'UNAUTHORIZED',
|
|
2348
|
-
message: 'Authentication required. Set MAMA_AUTH_TOKEN or MAMA_SERVER_TOKEN environment variable ' +
|
|
2349
|
-
'and provide it in the Authorization header.',
|
|
2350
|
-
}));
|
|
2351
|
-
return;
|
|
2352
|
-
}
|
|
2353
|
-
const body = await readBody(req);
|
|
2354
|
-
const currentConfig = loadMAMAConfig();
|
|
2355
|
-
let updatedConfig;
|
|
2356
|
-
try {
|
|
2357
|
-
updatedConfig = mergeConfigUpdates(currentConfig, body);
|
|
2358
|
-
}
|
|
2359
|
-
catch (err) {
|
|
2360
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
2361
|
-
res.end(JSON.stringify({
|
|
2362
|
-
error: true,
|
|
2363
|
-
code: 'VALIDATION_ERROR',
|
|
2364
|
-
message: err instanceof Error ? err.message : String(err),
|
|
2365
|
-
}));
|
|
2366
|
-
return;
|
|
2367
|
-
}
|
|
2368
|
-
const modelPolicyEntries = rescopeModelsForConfigSave(updatedConfig);
|
|
2369
|
-
const errors = validateConfigUpdate(updatedConfig);
|
|
2370
|
-
if (errors.length > 0) {
|
|
2371
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
2372
|
-
res.end(JSON.stringify({
|
|
2373
|
-
error: true,
|
|
2374
|
-
code: 'VALIDATION_ERROR',
|
|
2375
|
-
message: errors.join(', '),
|
|
2376
|
-
}));
|
|
2377
|
-
return;
|
|
2378
|
-
}
|
|
2379
|
-
(0, backend_model_policy_js_1.emitBackendModelWarnings)([...modelPolicyEntries.changes, ...modelPolicyEntries.warnings]);
|
|
2380
|
-
saveMAMAConfig(updatedConfig);
|
|
2381
|
-
if (updatedConfig.multi_agent && options.applyMultiAgentConfig) {
|
|
2382
|
-
try {
|
|
2383
|
-
await options.applyMultiAgentConfig(updatedConfig.multi_agent);
|
|
2384
|
-
}
|
|
2385
|
-
catch (err) {
|
|
2386
|
-
logger.warn('Multi-agent hot-apply failed after config update:', err instanceof Error ? err.message : String(err));
|
|
2387
|
-
}
|
|
2388
|
-
}
|
|
2389
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
2390
|
-
res.end(JSON.stringify({
|
|
2391
|
-
success: true,
|
|
2392
|
-
message: 'Configuration saved successfully',
|
|
2393
|
-
}));
|
|
2394
|
-
}
|
|
2395
|
-
catch (error) {
|
|
2396
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2397
|
-
console.error('[GraphAPI] Update config error:', message);
|
|
2398
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
2399
|
-
res.end(JSON.stringify({
|
|
2400
|
-
error: true,
|
|
2401
|
-
code: 'CONFIG_ERROR',
|
|
2402
|
-
message,
|
|
2403
|
-
}));
|
|
2404
|
-
}
|
|
2405
|
-
}
|
|
2406
|
-
function rescopeModelsForConfigSave(config) {
|
|
2407
|
-
if (!isRecord(config.agent) || typeof config.agent.backend !== 'string') {
|
|
2408
|
-
return { changes: [], warnings: [] };
|
|
2409
|
-
}
|
|
2410
|
-
const backend = config.agent.backend.toLowerCase();
|
|
2411
|
-
if (!supportedManagedBackends.includes(backend)) {
|
|
2412
|
-
return { changes: [], warnings: [] };
|
|
2413
|
-
}
|
|
2414
|
-
const roles = isRecord(config.roles) ? config.roles : undefined;
|
|
2415
|
-
const definitions = roles && isRecord(roles.definitions) ? roles.definitions : {};
|
|
2416
|
-
const roleModels = Object.fromEntries(Object.entries(definitions)
|
|
2417
|
-
.filter((entry) => isRecord(entry[1]))
|
|
2418
|
-
.map(([name, definition]) => [
|
|
2419
|
-
name,
|
|
2420
|
-
typeof definition.model === 'string' ? definition.model : undefined,
|
|
2421
|
-
]));
|
|
2422
|
-
const scopedModels = (0, backend_model_policy_js_1.rescopeConfigModels)({
|
|
2423
|
-
backend: backend,
|
|
2424
|
-
agentModel: typeof config.agent.model === 'string' ? config.agent.model : undefined,
|
|
2425
|
-
roleModels,
|
|
2426
|
-
});
|
|
2427
|
-
config.agent.model = scopedModels.agentModel;
|
|
2428
|
-
for (const [name, model] of Object.entries(scopedModels.roleModels)) {
|
|
2429
|
-
const definition = definitions[name];
|
|
2430
|
-
if (isRecord(definition)) {
|
|
2431
|
-
definition.model = model;
|
|
2432
|
-
}
|
|
2433
|
-
}
|
|
2434
|
-
const changes = [...scopedModels.changes];
|
|
2435
|
-
const warnings = [...(scopedModels.warnings ?? [])];
|
|
2436
|
-
const multiAgent = isRecord(config.multi_agent) ? config.multi_agent : undefined;
|
|
2437
|
-
const managedAgents = multiAgent && isRecord(multiAgent.agents) ? multiAgent.agents : {};
|
|
2438
|
-
for (const [agentId, agentConfig] of Object.entries(managedAgents)) {
|
|
2439
|
-
if (!isRecord(agentConfig)) {
|
|
2440
|
-
continue;
|
|
2441
|
-
}
|
|
2442
|
-
const effectiveBackend = typeof agentConfig.backend === 'string' ? agentConfig.backend.toLowerCase() : backend;
|
|
2443
|
-
if (!supportedManagedBackends.includes(effectiveBackend)) {
|
|
2444
|
-
continue;
|
|
2445
|
-
}
|
|
2446
|
-
const configuredModel = typeof agentConfig.model === 'string' ? agentConfig.model.trim() : undefined;
|
|
2447
|
-
const target = `multi_agent.agents.${agentId}.model`;
|
|
2448
|
-
const resolvedModel = (0, backend_model_policy_js_1.resolveBackendScopedModel)({
|
|
2449
|
-
backend: effectiveBackend,
|
|
2450
|
-
model: configuredModel,
|
|
2451
|
-
inheritedBackend: backend,
|
|
2452
|
-
inheritedModel: scopedModels.agentModel,
|
|
2453
|
-
warningTarget: target,
|
|
2454
|
-
onWarning: (warning) => warnings.push(warning),
|
|
2455
|
-
});
|
|
2456
|
-
agentConfig.model = resolvedModel;
|
|
2457
|
-
if (configuredModel && configuredModel !== resolvedModel) {
|
|
2458
|
-
changes.push({ target, from: configuredModel, to: resolvedModel });
|
|
2459
|
-
}
|
|
2460
|
-
}
|
|
2461
|
-
return { changes, warnings };
|
|
2462
|
-
}
|
|
2463
|
-
function maskToken(token) {
|
|
2464
|
-
if (!token || token.length < 4) {
|
|
2465
|
-
return '***[redacted]***';
|
|
2466
|
-
}
|
|
2467
|
-
return '***[redacted]***';
|
|
2468
|
-
}
|
|
2469
|
-
// isLocalRequest and isAuthenticated imported from ./auth-middleware.js
|
|
2470
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2471
|
-
function maskAgentsTokens(agents) {
|
|
2472
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2473
|
-
const masked = {};
|
|
2474
|
-
for (const [id, agent] of Object.entries(agents)) {
|
|
2475
|
-
masked[id] = { ...agent };
|
|
2476
|
-
if (agent.bot_token) {
|
|
2477
|
-
masked[id].bot_token = maskToken(agent.bot_token);
|
|
2478
|
-
}
|
|
2479
|
-
if (agent.slack_bot_token) {
|
|
2480
|
-
masked[id].slack_bot_token = maskToken(agent.slack_bot_token);
|
|
2481
|
-
}
|
|
2482
|
-
if (agent.slack_app_token) {
|
|
2483
|
-
masked[id].slack_app_token = maskToken(agent.slack_app_token);
|
|
2484
|
-
}
|
|
2485
|
-
}
|
|
2486
|
-
return masked;
|
|
2487
|
-
}
|
|
2488
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2489
|
-
function mergeConfigUpdates(current, updates) {
|
|
2490
|
-
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
2491
|
-
const merged = { ...current };
|
|
2492
|
-
if (updates.use_claude_cli !== undefined) {
|
|
2493
|
-
if (typeof updates.use_claude_cli !== 'boolean') {
|
|
2494
|
-
throw new Error('use_claude_cli must be a boolean');
|
|
2495
|
-
}
|
|
2496
|
-
merged.use_claude_cli = updates.use_claude_cli;
|
|
2497
|
-
}
|
|
2498
|
-
const normalizeAgentNumber = (value) => {
|
|
2499
|
-
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
2500
|
-
return value;
|
|
2501
|
-
}
|
|
2502
|
-
if (typeof value === 'string' && value.trim()) {
|
|
2503
|
-
const parsed = Number(value);
|
|
2504
|
-
return Number.isFinite(parsed) ? parsed : undefined;
|
|
2505
|
-
}
|
|
2506
|
-
return undefined;
|
|
2507
|
-
};
|
|
2508
|
-
if (updates.agent && typeof updates.agent === 'object') {
|
|
2509
|
-
const agentUpdates = updates.agent;
|
|
2510
|
-
const normalizedAgent = {
|
|
2511
|
-
...current.agent,
|
|
2512
|
-
...agentUpdates,
|
|
2513
|
-
};
|
|
2514
|
-
if (agentUpdates.max_turns !== undefined) {
|
|
2515
|
-
const normalized = normalizeAgentNumber(agentUpdates.max_turns);
|
|
2516
|
-
if (normalized === undefined) {
|
|
2517
|
-
throw new Error('agent.max_turns must be a number');
|
|
2518
|
-
}
|
|
2519
|
-
normalizedAgent.max_turns = normalized;
|
|
2520
|
-
}
|
|
2521
|
-
if (agentUpdates.timeout !== undefined) {
|
|
2522
|
-
const normalized = normalizeAgentNumber(agentUpdates.timeout);
|
|
2523
|
-
if (normalized === undefined) {
|
|
2524
|
-
throw new Error('agent.timeout must be a number');
|
|
2525
|
-
}
|
|
2526
|
-
normalizedAgent.timeout = normalized;
|
|
2527
|
-
}
|
|
2528
|
-
merged.agent = normalizedAgent;
|
|
2529
|
-
}
|
|
2530
|
-
if (updates.heartbeat) {
|
|
2531
|
-
merged.heartbeat = {
|
|
2532
|
-
...current.heartbeat,
|
|
2533
|
-
...updates.heartbeat,
|
|
2534
|
-
};
|
|
2535
|
-
}
|
|
2536
|
-
if (updates.discord) {
|
|
2537
|
-
const discordUpdates = updates.discord;
|
|
2538
|
-
merged.discord = {
|
|
2539
|
-
...current.discord,
|
|
2540
|
-
enabled: discordUpdates.enabled,
|
|
2541
|
-
default_channel_id: discordUpdates.default_channel_id || current.discord?.default_channel_id,
|
|
2542
|
-
};
|
|
2543
|
-
if (discordUpdates.token && typeof discordUpdates.token === 'string') {
|
|
2544
|
-
const isMasked = discordUpdates.token === '***[redacted]***' ||
|
|
2545
|
-
(discordUpdates.token.startsWith('***[') && discordUpdates.token.endsWith(']***'));
|
|
2546
|
-
if (!isMasked) {
|
|
2547
|
-
merged.discord.token = discordUpdates.token;
|
|
2548
|
-
}
|
|
2549
|
-
}
|
|
2550
|
-
}
|
|
2551
|
-
if (updates.slack) {
|
|
2552
|
-
const slackUpdates = updates.slack;
|
|
2553
|
-
merged.slack = {
|
|
2554
|
-
...current.slack,
|
|
2555
|
-
enabled: slackUpdates.enabled,
|
|
2556
|
-
};
|
|
2557
|
-
if (slackUpdates.bot_token && typeof slackUpdates.bot_token === 'string') {
|
|
2558
|
-
const isMasked = slackUpdates.bot_token === '***[redacted]***' ||
|
|
2559
|
-
(slackUpdates.bot_token.startsWith('***[') && slackUpdates.bot_token.endsWith(']***'));
|
|
2560
|
-
if (!isMasked) {
|
|
2561
|
-
merged.slack.bot_token = slackUpdates.bot_token;
|
|
2562
|
-
}
|
|
2563
|
-
}
|
|
2564
|
-
if (slackUpdates.app_token && typeof slackUpdates.app_token === 'string') {
|
|
2565
|
-
const isMasked = slackUpdates.app_token === '***[redacted]***' ||
|
|
2566
|
-
(slackUpdates.app_token.startsWith('***[') && slackUpdates.app_token.endsWith(']***'));
|
|
2567
|
-
if (!isMasked) {
|
|
2568
|
-
merged.slack.app_token = slackUpdates.app_token;
|
|
2569
|
-
}
|
|
2570
|
-
}
|
|
2571
|
-
}
|
|
2572
|
-
if (updates.telegram) {
|
|
2573
|
-
const telegramUpdates = updates.telegram;
|
|
2574
|
-
merged.telegram = {
|
|
2575
|
-
...current.telegram,
|
|
2576
|
-
enabled: telegramUpdates.enabled,
|
|
2577
|
-
};
|
|
2578
|
-
if (telegramUpdates.token && typeof telegramUpdates.token === 'string') {
|
|
2579
|
-
const isMasked = telegramUpdates.token === '***[redacted]***' ||
|
|
2580
|
-
(telegramUpdates.token.startsWith('***[') && telegramUpdates.token.endsWith(']***'));
|
|
2581
|
-
if (!isMasked) {
|
|
2582
|
-
merged.telegram.token = telegramUpdates.token;
|
|
2583
|
-
}
|
|
2584
|
-
}
|
|
2585
|
-
}
|
|
2586
|
-
if (updates.chatwork) {
|
|
2587
|
-
const chatworkUpdates = updates.chatwork;
|
|
2588
|
-
merged.chatwork = {
|
|
2589
|
-
...current.chatwork,
|
|
2590
|
-
enabled: chatworkUpdates.enabled,
|
|
2591
|
-
};
|
|
2592
|
-
if (chatworkUpdates.api_token && typeof chatworkUpdates.api_token === 'string') {
|
|
2593
|
-
const isMasked = chatworkUpdates.api_token === '***[redacted]***' ||
|
|
2594
|
-
(chatworkUpdates.api_token.startsWith('***[') &&
|
|
2595
|
-
chatworkUpdates.api_token.endsWith(']***'));
|
|
2596
|
-
if (!isMasked) {
|
|
2597
|
-
merged.chatwork.api_token = chatworkUpdates.api_token;
|
|
2598
|
-
}
|
|
2599
|
-
}
|
|
2600
|
-
}
|
|
2601
|
-
// Tuning sections: shallow merge each
|
|
2602
|
-
for (const section of ['prompt', 'timeouts', 'gateway_tuning', 'io', 'metrics']) {
|
|
2603
|
-
if (updates[section] && typeof updates[section] === 'object') {
|
|
2604
|
-
merged[section] = {
|
|
2605
|
-
...(current[section] || {}),
|
|
2606
|
-
...updates[section],
|
|
2607
|
-
};
|
|
2608
|
-
}
|
|
2609
|
-
}
|
|
2610
|
-
if (updates.multi_agent) {
|
|
2611
|
-
const multiAgentUpdates = updates.multi_agent;
|
|
2612
|
-
merged.multi_agent = {
|
|
2613
|
-
...current.multi_agent,
|
|
2614
|
-
...multiAgentUpdates,
|
|
2615
|
-
};
|
|
2616
|
-
if (multiAgentUpdates.agents) {
|
|
2617
|
-
const agentUpdatesMap = multiAgentUpdates.agents;
|
|
2618
|
-
merged.multi_agent.agents = { ...current.multi_agent?.agents };
|
|
2619
|
-
for (const [agentId, agentUpdates] of Object.entries(agentUpdatesMap)) {
|
|
2620
|
-
const currentAgent = current.multi_agent?.agents?.[agentId] || {};
|
|
2621
|
-
merged.multi_agent.agents[agentId] = {
|
|
2622
|
-
...currentAgent,
|
|
2623
|
-
...agentUpdates,
|
|
2624
|
-
};
|
|
2625
|
-
if (agentUpdates.bot_token && typeof agentUpdates.bot_token === 'string') {
|
|
2626
|
-
const isMasked = agentUpdates.bot_token === '***[redacted]***' ||
|
|
2627
|
-
(agentUpdates.bot_token.startsWith('***[') && agentUpdates.bot_token.endsWith(']***'));
|
|
2628
|
-
if (isMasked) {
|
|
2629
|
-
merged.multi_agent.agents[agentId].bot_token = currentAgent.bot_token;
|
|
2630
|
-
}
|
|
2631
|
-
}
|
|
2632
|
-
if (agentUpdates.slack_bot_token && typeof agentUpdates.slack_bot_token === 'string') {
|
|
2633
|
-
const isMasked = agentUpdates.slack_bot_token === '***[redacted]***' ||
|
|
2634
|
-
(agentUpdates.slack_bot_token.startsWith('***[') &&
|
|
2635
|
-
agentUpdates.slack_bot_token.endsWith(']***'));
|
|
2636
|
-
if (isMasked) {
|
|
2637
|
-
merged.multi_agent.agents[agentId].slack_bot_token = currentAgent.slack_bot_token;
|
|
2638
|
-
}
|
|
2639
|
-
}
|
|
2640
|
-
if (agentUpdates.slack_app_token && typeof agentUpdates.slack_app_token === 'string') {
|
|
2641
|
-
const isMasked = agentUpdates.slack_app_token === '***[redacted]***' ||
|
|
2642
|
-
(agentUpdates.slack_app_token.startsWith('***[') &&
|
|
2643
|
-
agentUpdates.slack_app_token.endsWith(']***'));
|
|
2644
|
-
if (isMasked) {
|
|
2645
|
-
merged.multi_agent.agents[agentId].slack_app_token = currentAgent.slack_app_token;
|
|
2646
|
-
}
|
|
2647
|
-
}
|
|
2648
|
-
}
|
|
2649
|
-
}
|
|
2650
|
-
}
|
|
2651
|
-
return merged;
|
|
2652
|
-
}
|
|
2653
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2654
|
-
function validateConfigUpdate(config) {
|
|
2655
|
-
const errors = [];
|
|
2656
|
-
const normalizeNumber = (value) => {
|
|
2657
|
-
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
2658
|
-
return value;
|
|
2659
|
-
}
|
|
2660
|
-
if (typeof value === 'string' && value.trim()) {
|
|
2661
|
-
const parsed = Number(value);
|
|
2662
|
-
return Number.isFinite(parsed) ? parsed : undefined;
|
|
2663
|
-
}
|
|
2664
|
-
return undefined;
|
|
2665
|
-
};
|
|
2666
|
-
if (config.agent) {
|
|
2667
|
-
const maxTurns = normalizeNumber(config.agent.max_turns);
|
|
2668
|
-
if (config.agent.max_turns !== undefined &&
|
|
2669
|
-
(maxTurns === undefined || !Number.isInteger(maxTurns) || maxTurns < 1 || maxTurns > 100)) {
|
|
2670
|
-
errors.push('max_turns must be between 1 and 100');
|
|
2671
|
-
}
|
|
2672
|
-
const timeoutMs = normalizeNumber(config.agent.timeout);
|
|
2673
|
-
if (config.agent.timeout !== undefined &&
|
|
2674
|
-
(timeoutMs === undefined ||
|
|
2675
|
-
!Number.isFinite(timeoutMs) ||
|
|
2676
|
-
!Number.isInteger(timeoutMs) ||
|
|
2677
|
-
timeoutMs < 1000)) {
|
|
2678
|
-
errors.push('timeout must be at least 1000ms');
|
|
2679
|
-
}
|
|
2680
|
-
if (config.agent.backend &&
|
|
2681
|
-
!supportedManagedBackends.includes(String(config.agent.backend).toLowerCase())) {
|
|
2682
|
-
errors.push('agent.backend must be "claude", "codex", or "cline"');
|
|
2683
|
-
}
|
|
2684
|
-
if (config.agent.backend && config.agent.model && typeof config.agent.model === 'string') {
|
|
2685
|
-
const backend = String(config.agent.backend).toLowerCase();
|
|
2686
|
-
const model = config.agent.model;
|
|
2687
|
-
const modelBackend = (0, backend_model_policy_js_1.backendForModel)(model);
|
|
2688
|
-
if (backend === 'claude' && modelBackend !== null && modelBackend !== 'claude') {
|
|
2689
|
-
errors.push('agent.model must be a Claude model when agent.backend is "claude"');
|
|
2690
|
-
}
|
|
2691
|
-
if (isCodexFamilyBackend(backend) && modelBackend !== null && modelBackend !== 'codex') {
|
|
2692
|
-
errors.push(`agent.model must be a Codex/OpenAI model when agent.backend is "${backend}"`);
|
|
2693
|
-
}
|
|
2694
|
-
}
|
|
2695
|
-
}
|
|
2696
|
-
if (config.heartbeat) {
|
|
2697
|
-
const heartbeatIntervalMs = normalizeNumber(config.heartbeat.interval);
|
|
2698
|
-
if (config.heartbeat.interval !== undefined &&
|
|
2699
|
-
(heartbeatIntervalMs === undefined ||
|
|
2700
|
-
!Number.isFinite(heartbeatIntervalMs) ||
|
|
2701
|
-
heartbeatIntervalMs < 60000)) {
|
|
2702
|
-
errors.push('heartbeat interval must be at least 60000ms (1 minute)');
|
|
2703
|
-
}
|
|
2704
|
-
}
|
|
2705
|
-
if (config.use_claude_cli !== undefined && typeof config.use_claude_cli !== 'boolean') {
|
|
2706
|
-
errors.push('use_claude_cli must be a boolean');
|
|
2707
|
-
}
|
|
2708
|
-
const globalBackend = config.agent?.backend;
|
|
2709
|
-
if (config.multi_agent?.agents && typeof config.multi_agent.agents === 'object') {
|
|
2710
|
-
for (const [agentId, agentConfig] of Object.entries(config.multi_agent.agents)) {
|
|
2711
|
-
const cfg = agentConfig;
|
|
2712
|
-
const backendRaw = cfg.backend ?? globalBackend;
|
|
2713
|
-
const modelRaw = cfg.model;
|
|
2714
|
-
if (backendRaw !== undefined) {
|
|
2715
|
-
const backend = String(backendRaw).toLowerCase();
|
|
2716
|
-
if (!supportedManagedBackends.includes(backend)) {
|
|
2717
|
-
errors.push(`multi_agent.agents.${agentId}.backend must be "claude", "codex", or "cline"`);
|
|
2718
|
-
continue;
|
|
2719
|
-
}
|
|
2720
|
-
if (typeof modelRaw === 'string' && modelRaw.trim()) {
|
|
2721
|
-
const modelBackend = (0, backend_model_policy_js_1.backendForModel)(modelRaw);
|
|
2722
|
-
if (backend === 'claude' && modelBackend !== null && modelBackend !== 'claude') {
|
|
2723
|
-
errors.push(`multi_agent.agents.${agentId}.model must be a Claude model when backend is "claude"`);
|
|
2724
|
-
}
|
|
2725
|
-
if (isCodexFamilyBackend(backend) && modelBackend !== null && modelBackend !== 'codex') {
|
|
2726
|
-
errors.push(`multi_agent.agents.${agentId}.model must be a Codex/OpenAI model when backend is "${backend}"`);
|
|
2727
|
-
}
|
|
2728
|
-
}
|
|
2729
|
-
}
|
|
2730
|
-
}
|
|
2731
|
-
}
|
|
2732
|
-
return errors;
|
|
2733
|
-
}
|
|
2734
|
-
function canonicalRolesJson(value) {
|
|
2735
|
-
if (Array.isArray(value)) {
|
|
2736
|
-
return `[${value.map(canonicalRolesJson).join(',')}]`;
|
|
2737
|
-
}
|
|
2738
|
-
if (value && typeof value === 'object') {
|
|
2739
|
-
const entries = Object.entries(value)
|
|
2740
|
-
.sort(([a], [b]) => a.localeCompare(b))
|
|
2741
|
-
.map(([k, v]) => `${JSON.stringify(k)}:${canonicalRolesJson(v)}`);
|
|
2742
|
-
return `{${entries.join(',')}}`;
|
|
2743
|
-
}
|
|
2744
|
-
return JSON.stringify(value) ?? 'undefined';
|
|
2745
|
-
}
|
|
2746
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2747
|
-
function saveMAMAConfig(config) {
|
|
2748
|
-
const configDir = path_1.default.dirname(MAMA_CONFIG_PATH);
|
|
2749
|
-
if (!fs_1.default.existsSync(configDir)) {
|
|
2750
|
-
fs_1.default.mkdirSync(configDir, { recursive: true });
|
|
2751
|
-
}
|
|
2752
|
-
// Prune role entries identical to shipped defaults (review R3-m1): this UI
|
|
2753
|
-
// save path bypasses config-manager.saveConfig, and without the prune it
|
|
2754
|
-
// would freeze default definitions into config.yaml (B1 silent-death class).
|
|
2755
|
-
if (config.roles && types_js_1.DEFAULT_ROLES) {
|
|
2756
|
-
const definitions = {};
|
|
2757
|
-
for (const [name, def] of Object.entries(config.roles.definitions ?? {})) {
|
|
2758
|
-
const defaultDef = types_js_1.DEFAULT_ROLES.definitions[name];
|
|
2759
|
-
if (!defaultDef || canonicalRolesJson(def) !== canonicalRolesJson(defaultDef)) {
|
|
2760
|
-
definitions[name] = def;
|
|
2761
|
-
}
|
|
2762
|
-
}
|
|
2763
|
-
const sourceMapping = {};
|
|
2764
|
-
for (const [source, role] of Object.entries(config.roles.sourceMapping ?? {})) {
|
|
2765
|
-
if (types_js_1.DEFAULT_ROLES.sourceMapping[source] !== role) {
|
|
2766
|
-
sourceMapping[source] = role;
|
|
2767
|
-
}
|
|
2768
|
-
}
|
|
2769
|
-
if (Object.keys(definitions).length === 0 && Object.keys(sourceMapping).length === 0) {
|
|
2770
|
-
delete config.roles;
|
|
2771
|
-
}
|
|
2772
|
-
else {
|
|
2773
|
-
config.roles = { definitions, sourceMapping };
|
|
2774
|
-
}
|
|
2775
|
-
}
|
|
2776
|
-
const content = js_yaml_1.default.dump(config, {
|
|
2777
|
-
indent: 2,
|
|
2778
|
-
lineWidth: 120,
|
|
2779
|
-
noRefs: true,
|
|
2780
|
-
});
|
|
2781
|
-
const fileContent = `# MAMA Configuration
|
|
2782
|
-
# Updated: ${new Date().toISOString()}
|
|
2783
|
-
# Documentation: https://github.com/jungjaehoon-lifegamez/MAMA
|
|
2784
|
-
|
|
2785
|
-
${content}`;
|
|
2786
|
-
fs_1.default.writeFileSync(MAMA_CONFIG_PATH, fileContent, 'utf8');
|
|
2787
|
-
console.log('[GraphAPI] Config saved to:', MAMA_CONFIG_PATH);
|
|
2788
|
-
}
|
|
2789
|
-
/**
|
|
2790
|
-
* Fetch all decisions with full text (decision + reasoning) for export.
|
|
2791
|
-
* Unlike getAllNodes() which returns preview-truncated fields for the graph
|
|
2792
|
-
* viewer, this returns the complete text needed for Markdown/CSV/JSON export.
|
|
2793
|
-
*/
|
|
2794
|
-
async function getAllNodesForExport() {
|
|
2795
|
-
const adapter = getAdapter();
|
|
2796
|
-
const rows = adapter
|
|
2797
|
-
.prepare(`SELECT id, topic, decision, reasoning, outcome, confidence, created_at
|
|
2798
|
-
FROM decisions ORDER BY created_at DESC`)
|
|
2799
|
-
.all();
|
|
2800
|
-
return rows.map((row) => ({
|
|
2801
|
-
id: row.id,
|
|
2802
|
-
topic: row.topic,
|
|
2803
|
-
decision: row.decision,
|
|
2804
|
-
reasoning: row.reasoning,
|
|
2805
|
-
decision_preview: buildDecisionPreview(row.decision),
|
|
2806
|
-
outcome: row.outcome,
|
|
2807
|
-
confidence: row.confidence,
|
|
2808
|
-
created_at: row.created_at,
|
|
2809
|
-
}));
|
|
2810
|
-
}
|
|
2811
|
-
async function handleExportRequest(_req, res, params) {
|
|
2812
|
-
try {
|
|
2813
|
-
const format = params.get('format') || 'json';
|
|
2814
|
-
await initDB();
|
|
2815
|
-
// Use full-text query so exports include complete decision + reasoning
|
|
2816
|
-
const decisions = await getAllNodesForExport();
|
|
2817
|
-
let content;
|
|
2818
|
-
let contentType;
|
|
2819
|
-
let filename;
|
|
2820
|
-
switch (format) {
|
|
2821
|
-
case 'markdown':
|
|
2822
|
-
content = exportToMarkdown(decisions);
|
|
2823
|
-
contentType = 'text/markdown';
|
|
2824
|
-
filename = `mama-decisions-${new Date().toISOString().split('T')[0]}.md`;
|
|
2825
|
-
break;
|
|
2826
|
-
case 'csv':
|
|
2827
|
-
content = exportToCSV(decisions);
|
|
2828
|
-
contentType = 'text/csv';
|
|
2829
|
-
filename = `mama-decisions-${new Date().toISOString().split('T')[0]}.csv`;
|
|
2830
|
-
break;
|
|
2831
|
-
case 'json':
|
|
2832
|
-
default:
|
|
2833
|
-
content = JSON.stringify({ decisions, exported_at: new Date().toISOString() }, null, 2);
|
|
2834
|
-
contentType = 'application/json';
|
|
2835
|
-
filename = `mama-decisions-${new Date().toISOString().split('T')[0]}.json`;
|
|
2836
|
-
break;
|
|
2837
|
-
}
|
|
2838
|
-
res.writeHead(200, {
|
|
2839
|
-
'Content-Type': contentType,
|
|
2840
|
-
'Content-Disposition': `attachment; filename="${filename}"`,
|
|
2841
|
-
});
|
|
2842
|
-
res.end(content);
|
|
2843
|
-
}
|
|
2844
|
-
catch (error) {
|
|
2845
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2846
|
-
console.error('[GraphAPI] Export error:', message);
|
|
2847
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
2848
|
-
res.end(JSON.stringify({
|
|
2849
|
-
error: true,
|
|
2850
|
-
code: 'EXPORT_ERROR',
|
|
2851
|
-
message,
|
|
2852
|
-
}));
|
|
2853
|
-
}
|
|
2854
|
-
}
|
|
2855
|
-
function exportToMarkdown(decisions) {
|
|
2856
|
-
const lines = [
|
|
2857
|
-
'# MAMA Decisions Export',
|
|
2858
|
-
'',
|
|
2859
|
-
`Exported: ${new Date().toISOString()}`,
|
|
2860
|
-
`Total Decisions: ${decisions.length}`,
|
|
2861
|
-
'',
|
|
2862
|
-
'---',
|
|
2863
|
-
'',
|
|
2864
|
-
];
|
|
2865
|
-
for (const d of decisions) {
|
|
2866
|
-
lines.push(`## ${d.topic || 'Untitled'}`);
|
|
2867
|
-
lines.push('');
|
|
2868
|
-
lines.push(`**Decision:** ${d.decision || 'N/A'}`);
|
|
2869
|
-
lines.push('');
|
|
2870
|
-
if (d.reasoning) {
|
|
2871
|
-
lines.push(`**Reasoning:**`);
|
|
2872
|
-
lines.push('');
|
|
2873
|
-
lines.push(d.reasoning);
|
|
2874
|
-
lines.push('');
|
|
2875
|
-
}
|
|
2876
|
-
lines.push(`- **Outcome:** ${d.outcome || 'Pending'}`);
|
|
2877
|
-
lines.push(`- **Confidence:** ${d.confidence || 'N/A'}`);
|
|
2878
|
-
lines.push(`- **Created:** ${d.created_at ? new Date(d.created_at).toISOString() : 'N/A'}`);
|
|
2879
|
-
lines.push(`- **ID:** \`${d.id}\``);
|
|
2880
|
-
lines.push('');
|
|
2881
|
-
lines.push('---');
|
|
2882
|
-
lines.push('');
|
|
2883
|
-
}
|
|
2884
|
-
return lines.join('\n');
|
|
2885
|
-
}
|
|
2886
|
-
async function handleMultiAgentStatusRequest(_req, res, options = {}) {
|
|
2887
|
-
try {
|
|
2888
|
-
const config = loadMAMAConfig();
|
|
2889
|
-
const multiAgentConfig = config.multi_agent || { enabled: false, agents: {} };
|
|
2890
|
-
const agentStatesMap = options.getAgentStates ? options.getAgentStates() : null;
|
|
2891
|
-
const agents = [];
|
|
2892
|
-
const seenAgentIds = new Set();
|
|
2893
|
-
if (multiAgentConfig.enabled && multiAgentConfig.agents) {
|
|
2894
|
-
for (const [id, agentConfig] of Object.entries(multiAgentConfig.agents)) {
|
|
2895
|
-
let status = 'online';
|
|
2896
|
-
if (agentConfig.enabled === false) {
|
|
2897
|
-
status = 'disabled';
|
|
2898
|
-
}
|
|
2899
|
-
else if (agentStatesMap && agentStatesMap.has(id)) {
|
|
2900
|
-
status = agentStatesMap.get(id);
|
|
2901
|
-
}
|
|
2902
|
-
agents.push({
|
|
2903
|
-
id,
|
|
2904
|
-
name: agentConfig.name || id,
|
|
2905
|
-
tier: agentConfig.tier || 1,
|
|
2906
|
-
model: agentConfig.model || config.agent?.model || 'unknown',
|
|
2907
|
-
status,
|
|
2908
|
-
lastActivity: status === 'busy' ? new Date().toISOString() : null,
|
|
2909
|
-
});
|
|
2910
|
-
seenAgentIds.add(id);
|
|
2911
|
-
}
|
|
2912
|
-
}
|
|
2913
|
-
// Include ephemeral agents from process pool (not in config but active)
|
|
2914
|
-
if (agentStatesMap) {
|
|
2915
|
-
for (const [id, processState] of agentStatesMap) {
|
|
2916
|
-
if (!seenAgentIds.has(id)) {
|
|
2917
|
-
agents.push({
|
|
2918
|
-
id,
|
|
2919
|
-
name: id.charAt(0).toUpperCase() + id.slice(1),
|
|
2920
|
-
tier: 2,
|
|
2921
|
-
model: 'unknown',
|
|
2922
|
-
status: processState,
|
|
2923
|
-
lastActivity: processState === 'busy' ? new Date().toISOString() : null,
|
|
2924
|
-
ephemeral: true,
|
|
2925
|
-
});
|
|
2926
|
-
}
|
|
2927
|
-
}
|
|
2928
|
-
}
|
|
2929
|
-
// Count active chains (agents currently busy)
|
|
2930
|
-
const busyCount = agents.filter((a) => a.status === 'busy').length;
|
|
2931
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
2932
|
-
res.end(JSON.stringify({
|
|
2933
|
-
enabled: multiAgentConfig.enabled || false,
|
|
2934
|
-
agents,
|
|
2935
|
-
activeChains: busyCount,
|
|
2936
|
-
}));
|
|
2937
|
-
}
|
|
2938
|
-
catch (error) {
|
|
2939
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2940
|
-
console.error('[GraphAPI] Multi-agent status error:', message);
|
|
2941
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
2942
|
-
res.end(JSON.stringify({
|
|
2943
|
-
error: true,
|
|
2944
|
-
code: 'MULTI_AGENT_STATUS_ERROR',
|
|
2945
|
-
message,
|
|
2946
|
-
}));
|
|
2947
|
-
}
|
|
2948
|
-
}
|
|
2949
|
-
async function handleMultiAgentAgentsRequest(_req, res) {
|
|
2950
|
-
try {
|
|
2951
|
-
const config = loadMAMAConfig();
|
|
2952
|
-
const multiAgentConfig = config.multi_agent || { enabled: false, agents: {} };
|
|
2953
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2954
|
-
const agentsList = [];
|
|
2955
|
-
if (multiAgentConfig.agents) {
|
|
2956
|
-
for (const [id, agentConfig] of Object.entries(multiAgentConfig.agents)) {
|
|
2957
|
-
agentsList.push({
|
|
2958
|
-
id,
|
|
2959
|
-
name: agentConfig.name || id,
|
|
2960
|
-
display_name: agentConfig.display_name || agentConfig.name || id,
|
|
2961
|
-
tier: agentConfig.tier || 1,
|
|
2962
|
-
backend: agentConfig.backend || null,
|
|
2963
|
-
model: agentConfig.model || null,
|
|
2964
|
-
enabled: agentConfig.enabled !== false,
|
|
2965
|
-
persona_file: agentConfig.persona_file || null,
|
|
2966
|
-
trigger_prefix: agentConfig.trigger_prefix || null,
|
|
2967
|
-
bot_token: agentConfig.bot_token ? maskToken(agentConfig.bot_token) : null,
|
|
2968
|
-
slack_bot_token: agentConfig.slack_bot_token
|
|
2969
|
-
? maskToken(agentConfig.slack_bot_token)
|
|
2970
|
-
: null,
|
|
2971
|
-
slack_app_token: agentConfig.slack_app_token
|
|
2972
|
-
? maskToken(agentConfig.slack_app_token)
|
|
2973
|
-
: null,
|
|
2974
|
-
auto_respond_keywords: agentConfig.auto_respond_keywords || [],
|
|
2975
|
-
cooldown_ms: agentConfig.cooldown_ms || 5000,
|
|
2976
|
-
can_delegate: agentConfig.can_delegate || false,
|
|
2977
|
-
effort: agentConfig.effort || null,
|
|
2978
|
-
tool_permissions: agentConfig.tool_permissions || null,
|
|
2979
|
-
});
|
|
2980
|
-
}
|
|
2981
|
-
}
|
|
2982
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
2983
|
-
res.end(JSON.stringify({ agents: agentsList }));
|
|
2984
|
-
}
|
|
2985
|
-
catch (error) {
|
|
2986
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2987
|
-
console.error('[GraphAPI] Multi-agent agents list error:', message);
|
|
2988
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
2989
|
-
res.end(JSON.stringify({
|
|
2990
|
-
error: true,
|
|
2991
|
-
code: 'MULTI_AGENT_AGENTS_ERROR',
|
|
2992
|
-
message,
|
|
2993
|
-
}));
|
|
2994
|
-
}
|
|
2995
|
-
}
|
|
2996
|
-
async function handleMultiAgentUpdateAgentRequest(req, res, pathname, options = {}) {
|
|
2997
|
-
try {
|
|
2998
|
-
// Security: require authentication for config-writing endpoint
|
|
2999
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
3000
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
3001
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
3002
|
-
res.end(JSON.stringify({
|
|
3003
|
-
error: true,
|
|
3004
|
-
code: 'UNAUTHORIZED',
|
|
3005
|
-
message: 'Authentication required. Set Authorization header with valid token.',
|
|
3006
|
-
}));
|
|
3007
|
-
return;
|
|
3008
|
-
}
|
|
3009
|
-
const match = pathname.match(/\/api\/multi-agent\/agents\/([^/]+)/);
|
|
3010
|
-
if (!match) {
|
|
3011
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3012
|
-
res.end(JSON.stringify({
|
|
3013
|
-
error: true,
|
|
3014
|
-
code: 'INVALID_URL',
|
|
3015
|
-
message: 'Invalid agent ID in URL',
|
|
3016
|
-
}));
|
|
3017
|
-
return;
|
|
3018
|
-
}
|
|
3019
|
-
const agentId = match[1];
|
|
3020
|
-
if (!/^[a-z0-9_-]+$/i.test(agentId)) {
|
|
3021
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3022
|
-
res.end(JSON.stringify({
|
|
3023
|
-
error: true,
|
|
3024
|
-
code: 'INVALID_AGENT_ID',
|
|
3025
|
-
message: 'Invalid agent ID format',
|
|
3026
|
-
}));
|
|
3027
|
-
return;
|
|
3028
|
-
}
|
|
3029
|
-
const body = await readBody(req);
|
|
3030
|
-
const config = loadMAMAConfig();
|
|
3031
|
-
if (!config.multi_agent) {
|
|
3032
|
-
config.multi_agent = { enabled: false, agents: {} };
|
|
3033
|
-
}
|
|
3034
|
-
if (!config.multi_agent.agents) {
|
|
3035
|
-
config.multi_agent.agents = {};
|
|
3036
|
-
}
|
|
3037
|
-
if (!config.multi_agent.agents[agentId]) {
|
|
3038
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
3039
|
-
res.end(JSON.stringify({
|
|
3040
|
-
error: true,
|
|
3041
|
-
code: 'AGENT_NOT_FOUND',
|
|
3042
|
-
message: `Agent '${agentId}' not found`,
|
|
3043
|
-
}));
|
|
3044
|
-
return;
|
|
3045
|
-
}
|
|
3046
|
-
const currentAgent = config.multi_agent.agents[agentId];
|
|
3047
|
-
const updatedAgent = { ...currentAgent };
|
|
3048
|
-
// Validate critical field types before applying
|
|
3049
|
-
const validationErrors = [];
|
|
3050
|
-
if (body.tier !== undefined &&
|
|
3051
|
-
(typeof body.tier !== 'number' || body.tier < 1 || body.tier > 3)) {
|
|
3052
|
-
validationErrors.push('tier must be a number between 1 and 3');
|
|
3053
|
-
}
|
|
3054
|
-
if (body.enabled !== undefined && typeof body.enabled !== 'boolean') {
|
|
3055
|
-
validationErrors.push('enabled must be a boolean');
|
|
3056
|
-
}
|
|
3057
|
-
if (body.cooldown_ms !== undefined &&
|
|
3058
|
-
(typeof body.cooldown_ms !== 'number' || body.cooldown_ms < 0)) {
|
|
3059
|
-
validationErrors.push('cooldown_ms must be a non-negative number');
|
|
3060
|
-
}
|
|
3061
|
-
if (body.can_delegate !== undefined && typeof body.can_delegate !== 'boolean') {
|
|
3062
|
-
validationErrors.push('can_delegate must be a boolean');
|
|
3063
|
-
}
|
|
3064
|
-
if (body.backend !== undefined &&
|
|
3065
|
-
(typeof body.backend !== 'string' ||
|
|
3066
|
-
!supportedManagedBackends.includes(String(body.backend).toLowerCase()))) {
|
|
3067
|
-
validationErrors.push('backend must be "claude", "codex", or "cline"');
|
|
3068
|
-
}
|
|
3069
|
-
const nextBackend = (body.backend !== undefined ? String(body.backend).toLowerCase() : currentAgent.backend);
|
|
3070
|
-
const backendChanged = typeof body.backend === 'string' &&
|
|
3071
|
-
String(body.backend).toLowerCase() !== String(currentAgent.backend ?? config.agent.backend);
|
|
3072
|
-
const nextModel = (body.model !== undefined
|
|
3073
|
-
? body.model
|
|
3074
|
-
: backendChanged && typeof nextBackend === 'string'
|
|
3075
|
-
? (0, backend_model_policy_js_1.defaultModelForBackend)(nextBackend)
|
|
3076
|
-
: currentAgent.model);
|
|
3077
|
-
if (typeof nextBackend === 'string' && typeof nextModel === 'string' && nextModel.trim()) {
|
|
3078
|
-
if (nextBackend === 'claude' && !isClaudeModel(nextModel)) {
|
|
3079
|
-
validationErrors.push('model must be a Claude model when backend is "claude"');
|
|
3080
|
-
}
|
|
3081
|
-
if (isCodexFamilyBackend(nextBackend) && !isCodexModel(nextModel)) {
|
|
3082
|
-
validationErrors.push(`model must be a Codex/OpenAI model when backend is "${nextBackend}"`);
|
|
3083
|
-
}
|
|
3084
|
-
}
|
|
3085
|
-
if (body.effort !== undefined) {
|
|
3086
|
-
if (typeof body.effort !== 'string') {
|
|
3087
|
-
validationErrors.push('effort must be one of: low, medium, high, max');
|
|
3088
|
-
}
|
|
3089
|
-
else {
|
|
3090
|
-
const normalizedEffort = body.effort.toLowerCase();
|
|
3091
|
-
if (!VALID_EFFORT_LEVELS.has(normalizedEffort)) {
|
|
3092
|
-
validationErrors.push('effort must be one of: low, medium, high, max');
|
|
3093
|
-
}
|
|
3094
|
-
else {
|
|
3095
|
-
if (nextBackend !== 'claude') {
|
|
3096
|
-
validationErrors.push('effort is only supported when backend is "claude"');
|
|
3097
|
-
}
|
|
3098
|
-
if (normalizedEffort === 'max' &&
|
|
3099
|
-
(typeof nextModel !== 'string' || !isOpus46Model(nextModel))) {
|
|
3100
|
-
validationErrors.push('effort "max" is only supported for claude-opus-4-6 models');
|
|
3101
|
-
}
|
|
3102
|
-
}
|
|
3103
|
-
}
|
|
3104
|
-
}
|
|
3105
|
-
if (validationErrors.length > 0) {
|
|
3106
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3107
|
-
res.end(JSON.stringify({
|
|
3108
|
-
error: true,
|
|
3109
|
-
code: 'VALIDATION_ERROR',
|
|
3110
|
-
message: validationErrors.join(', '),
|
|
3111
|
-
}));
|
|
3112
|
-
return;
|
|
3113
|
-
}
|
|
3114
|
-
if (body.name !== undefined) {
|
|
3115
|
-
updatedAgent.name = body.name;
|
|
3116
|
-
}
|
|
3117
|
-
if (body.display_name !== undefined) {
|
|
3118
|
-
updatedAgent.display_name = body.display_name;
|
|
3119
|
-
}
|
|
3120
|
-
if (body.tier !== undefined) {
|
|
3121
|
-
updatedAgent.tier = body.tier;
|
|
3122
|
-
}
|
|
3123
|
-
if (body.backend !== undefined) {
|
|
3124
|
-
updatedAgent.backend = String(body.backend).toLowerCase();
|
|
3125
|
-
}
|
|
3126
|
-
if (body.model !== undefined) {
|
|
3127
|
-
updatedAgent.model = body.model;
|
|
3128
|
-
}
|
|
3129
|
-
else if (backendChanged && typeof nextModel === 'string') {
|
|
3130
|
-
updatedAgent.model = nextModel;
|
|
3131
|
-
}
|
|
3132
|
-
if (body.enabled !== undefined) {
|
|
3133
|
-
updatedAgent.enabled = body.enabled;
|
|
3134
|
-
}
|
|
3135
|
-
if (body.persona_file !== undefined && body.persona_file !== null) {
|
|
3136
|
-
if (typeof body.persona_file !== 'string' || !isValidPersonaPath(body.persona_file)) {
|
|
3137
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3138
|
-
res.end(JSON.stringify({
|
|
3139
|
-
error: 'Invalid persona_file path. Must be within ~/.mama/personas/ or ~/.mama/workspace/',
|
|
3140
|
-
}));
|
|
3141
|
-
return;
|
|
3142
|
-
}
|
|
3143
|
-
updatedAgent.persona_file = body.persona_file;
|
|
3144
|
-
}
|
|
3145
|
-
if (body.trigger_prefix !== undefined)
|
|
3146
|
-
updatedAgent.trigger_prefix = body.trigger_prefix;
|
|
3147
|
-
if (body.auto_respond_keywords !== undefined)
|
|
3148
|
-
updatedAgent.auto_respond_keywords = body.auto_respond_keywords;
|
|
3149
|
-
if (body.cooldown_ms !== undefined)
|
|
3150
|
-
updatedAgent.cooldown_ms = body.cooldown_ms;
|
|
3151
|
-
if (body.can_delegate !== undefined)
|
|
3152
|
-
updatedAgent.can_delegate = body.can_delegate;
|
|
3153
|
-
if (body.effort !== undefined) {
|
|
3154
|
-
updatedAgent.effort = String(body.effort).toLowerCase();
|
|
3155
|
-
}
|
|
3156
|
-
if (body.tool_permissions !== undefined)
|
|
3157
|
-
updatedAgent.tool_permissions = body.tool_permissions;
|
|
3158
|
-
const isMaskedToken = (token) => {
|
|
3159
|
-
if (typeof token !== 'string')
|
|
3160
|
-
return false;
|
|
3161
|
-
return token === '***[redacted]***' || (token.startsWith('***[') && token.endsWith(']***'));
|
|
3162
|
-
};
|
|
3163
|
-
if (body.bot_token && !isMaskedToken(body.bot_token)) {
|
|
3164
|
-
updatedAgent.bot_token = body.bot_token;
|
|
3165
|
-
}
|
|
3166
|
-
if (body.slack_bot_token && !isMaskedToken(body.slack_bot_token)) {
|
|
3167
|
-
updatedAgent.slack_bot_token = body.slack_bot_token;
|
|
3168
|
-
}
|
|
3169
|
-
if (body.slack_app_token && !isMaskedToken(body.slack_app_token)) {
|
|
3170
|
-
updatedAgent.slack_app_token = body.slack_app_token;
|
|
3171
|
-
}
|
|
3172
|
-
config.multi_agent.agents[agentId] = updatedAgent;
|
|
3173
|
-
saveMAMAConfig(config);
|
|
3174
|
-
let runtimeReloaded = true;
|
|
3175
|
-
if (options.applyMultiAgentConfig) {
|
|
3176
|
-
try {
|
|
3177
|
-
await options.applyMultiAgentConfig(config.multi_agent);
|
|
3178
|
-
}
|
|
3179
|
-
catch (err) {
|
|
3180
|
-
runtimeReloaded = false;
|
|
3181
|
-
logger.warn(`Multi-agent hot-apply failed for ${agentId}:`, err instanceof Error ? err.message : String(err));
|
|
3182
|
-
}
|
|
3183
|
-
}
|
|
3184
|
-
if (options.restartMultiAgentAgent) {
|
|
3185
|
-
try {
|
|
3186
|
-
await options.restartMultiAgentAgent(agentId);
|
|
3187
|
-
}
|
|
3188
|
-
catch (err) {
|
|
3189
|
-
runtimeReloaded = false;
|
|
3190
|
-
logger.warn(`Agent runtime restart failed for ${agentId}:`, err instanceof Error ? err.message : String(err));
|
|
3191
|
-
}
|
|
3192
|
-
}
|
|
3193
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
3194
|
-
res.end(JSON.stringify({
|
|
3195
|
-
success: true,
|
|
3196
|
-
message: runtimeReloaded
|
|
3197
|
-
? `Agent '${agentId}' updated successfully (runtime reloaded)`
|
|
3198
|
-
: `Agent '${agentId}' config saved (runtime reload skipped or failed)`,
|
|
3199
|
-
}));
|
|
3200
|
-
}
|
|
3201
|
-
catch (error) {
|
|
3202
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3203
|
-
console.error('[GraphAPI] Multi-agent update agent error:', message);
|
|
3204
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
3205
|
-
res.end(JSON.stringify({
|
|
3206
|
-
error: true,
|
|
3207
|
-
code: 'MULTI_AGENT_UPDATE_ERROR',
|
|
3208
|
-
message,
|
|
3209
|
-
}));
|
|
3210
|
-
}
|
|
3211
|
-
}
|
|
3212
|
-
function exportToCSV(decisions) {
|
|
3213
|
-
const escapeCSV = (str) => {
|
|
3214
|
-
if (!str) {
|
|
3215
|
-
return '';
|
|
3216
|
-
}
|
|
3217
|
-
const escaped = String(str).replace(/"/g, '""');
|
|
3218
|
-
return escaped.includes(',') || escaped.includes('\n') || escaped.includes('"')
|
|
3219
|
-
? `"${escaped}"`
|
|
3220
|
-
: escaped;
|
|
3221
|
-
};
|
|
3222
|
-
const headers = ['id', 'topic', 'decision', 'reasoning', 'outcome', 'confidence', 'created_at'];
|
|
3223
|
-
const lines = [headers.join(',')];
|
|
3224
|
-
for (const d of decisions) {
|
|
3225
|
-
const row = [
|
|
3226
|
-
escapeCSV(d.id),
|
|
3227
|
-
escapeCSV(d.topic),
|
|
3228
|
-
escapeCSV(d.decision),
|
|
3229
|
-
escapeCSV(d.reasoning),
|
|
3230
|
-
escapeCSV(d.outcome),
|
|
3231
|
-
d.confidence ?? '',
|
|
3232
|
-
d.created_at ? new Date(d.created_at).toISOString() : '',
|
|
3233
|
-
];
|
|
3234
|
-
lines.push(row.join(','));
|
|
3235
|
-
}
|
|
3236
|
-
return lines.join('\n');
|
|
3237
|
-
}
|
|
3238
|
-
/**
|
|
3239
|
-
* Handle GET /api/mcp-servers - return available MCP servers from config
|
|
3240
|
-
* Security: Requires authentication, redacts sensitive fields (command, url, configPath)
|
|
3241
|
-
*/
|
|
3242
|
-
async function handleMCPServersRequest(req, res) {
|
|
3243
|
-
try {
|
|
3244
|
-
// Security: require authentication for config endpoint
|
|
3245
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
3246
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
3247
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
3248
|
-
res.end(JSON.stringify({
|
|
3249
|
-
error: true,
|
|
3250
|
-
code: 'UNAUTHORIZED',
|
|
3251
|
-
message: 'Authentication required',
|
|
3252
|
-
}));
|
|
3253
|
-
return;
|
|
3254
|
-
}
|
|
3255
|
-
const config = loadMAMAConfig();
|
|
3256
|
-
const mcpConfigPath = config.agent?.tools?.mcp_config || '~/.mama/mama-mcp-config.json';
|
|
3257
|
-
const resolvedPath = mcpConfigPath.replace(/^~/, os_1.default.homedir());
|
|
3258
|
-
let mcpServers = {};
|
|
3259
|
-
if (fs_1.default.existsSync(resolvedPath)) {
|
|
3260
|
-
const content = fs_1.default.readFileSync(resolvedPath, 'utf8');
|
|
3261
|
-
const mcpConfig = JSON.parse(content);
|
|
3262
|
-
mcpServers = mcpConfig.mcpServers || {};
|
|
3263
|
-
}
|
|
3264
|
-
// Transform to array with server names - redact sensitive fields
|
|
3265
|
-
const servers = Object.entries(mcpServers).map(([name, serverConfig]) => {
|
|
3266
|
-
const cfg = serverConfig;
|
|
3267
|
-
return {
|
|
3268
|
-
name,
|
|
3269
|
-
type: cfg.type || 'stdio',
|
|
3270
|
-
// Redact command and url to prevent credential leakage
|
|
3271
|
-
hasCommand: !!cfg.command,
|
|
3272
|
-
hasUrl: !!cfg.url,
|
|
3273
|
-
// Mask args to prevent credential leakage (show count only)
|
|
3274
|
-
hasArgs: Array.isArray(cfg.args) && cfg.args.length > 0,
|
|
3275
|
-
argCount: Array.isArray(cfg.args) ? cfg.args.length : 0,
|
|
3276
|
-
};
|
|
3277
|
-
});
|
|
3278
|
-
// Remove configPath from response to prevent path disclosure
|
|
3279
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
3280
|
-
res.end(JSON.stringify({ servers }));
|
|
3281
|
-
}
|
|
3282
|
-
catch (error) {
|
|
3283
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3284
|
-
logger.error('MCP servers list error:', message);
|
|
3285
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
3286
|
-
res.end(JSON.stringify({
|
|
3287
|
-
error: true,
|
|
3288
|
-
code: 'MCP_SERVERS_ERROR',
|
|
3289
|
-
message,
|
|
3290
|
-
}));
|
|
3291
|
-
}
|
|
3292
|
-
}
|
|
3293
|
-
/**
|
|
3294
|
-
* Handle DELETE /api/mcp-servers/:name - remove MCP server from config
|
|
3295
|
-
*/
|
|
3296
|
-
async function handleDeleteMCPServerRequest(req, res, pathname) {
|
|
3297
|
-
try {
|
|
3298
|
-
// Security: require authentication for config-writing endpoint
|
|
3299
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
3300
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
3301
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
3302
|
-
res.end(JSON.stringify({
|
|
3303
|
-
error: true,
|
|
3304
|
-
code: 'UNAUTHORIZED',
|
|
3305
|
-
message: 'Authentication required',
|
|
3306
|
-
}));
|
|
3307
|
-
return;
|
|
3308
|
-
}
|
|
3309
|
-
const match = pathname.match(/\/api\/mcp-servers\/([^/]+)/);
|
|
3310
|
-
if (!match) {
|
|
3311
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3312
|
-
res.end(JSON.stringify({ error: true, message: 'Invalid server name' }));
|
|
3313
|
-
return;
|
|
3314
|
-
}
|
|
3315
|
-
// Safely decode URI component - malformed percent-encoding throws URIError
|
|
3316
|
-
let serverName;
|
|
3317
|
-
try {
|
|
3318
|
-
serverName = decodeURIComponent(match[1]);
|
|
3319
|
-
}
|
|
3320
|
-
catch (e) {
|
|
3321
|
-
if (e instanceof URIError) {
|
|
3322
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3323
|
-
res.end(JSON.stringify({ error: true, message: 'Invalid server name encoding' }));
|
|
3324
|
-
return;
|
|
3325
|
-
}
|
|
3326
|
-
throw e; // Re-throw non-decoding errors
|
|
3327
|
-
}
|
|
3328
|
-
// Validate serverName format (same pattern as agentId validation)
|
|
3329
|
-
const SERVER_NAME_PATTERN = /^[a-z0-9_-]+$/i;
|
|
3330
|
-
if (!SERVER_NAME_PATTERN.test(serverName)) {
|
|
3331
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3332
|
-
res.end(JSON.stringify({ error: true, message: 'Invalid server name format' }));
|
|
3333
|
-
return;
|
|
3334
|
-
}
|
|
3335
|
-
const config = loadMAMAConfig();
|
|
3336
|
-
const mcpConfigPath = config.agent?.tools?.mcp_config || '~/.mama/mama-mcp-config.json';
|
|
3337
|
-
const resolvedPath = mcpConfigPath.replace(/^~/, os_1.default.homedir());
|
|
3338
|
-
if (!fs_1.default.existsSync(resolvedPath)) {
|
|
3339
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
3340
|
-
res.end(JSON.stringify({ error: true, message: 'MCP config not found' }));
|
|
3341
|
-
return;
|
|
3342
|
-
}
|
|
3343
|
-
const content = fs_1.default.readFileSync(resolvedPath, 'utf8');
|
|
3344
|
-
const mcpConfig = JSON.parse(content);
|
|
3345
|
-
if (!mcpConfig.mcpServers || !mcpConfig.mcpServers[serverName]) {
|
|
3346
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
3347
|
-
res.end(JSON.stringify({ error: true, message: `Server "${serverName}" not found` }));
|
|
3348
|
-
return;
|
|
3349
|
-
}
|
|
3350
|
-
delete mcpConfig.mcpServers[serverName];
|
|
3351
|
-
fs_1.default.writeFileSync(resolvedPath, JSON.stringify(mcpConfig, null, 2), 'utf8');
|
|
3352
|
-
logger.info('Removed MCP server:', serverName);
|
|
3353
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
3354
|
-
res.end(JSON.stringify({ deleted: true, name: serverName }));
|
|
3355
|
-
}
|
|
3356
|
-
catch (error) {
|
|
3357
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3358
|
-
logger.error('Delete MCP server error:', message);
|
|
3359
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
3360
|
-
res.end(JSON.stringify({ error: true, message }));
|
|
3361
|
-
}
|
|
3362
|
-
}
|
|
3363
|
-
async function handleCodeActRequest(req, res, options = {}) {
|
|
3364
|
-
try {
|
|
3365
|
-
// Security: require authentication for code execution endpoint
|
|
3366
|
-
if (!(0, auth_middleware_js_1.isAuthenticated)(req)) {
|
|
3367
|
-
(0, auth_middleware_js_1.logUnauthorizedAttempt)(req);
|
|
3368
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
3369
|
-
res.end(JSON.stringify({
|
|
3370
|
-
error: true,
|
|
3371
|
-
message: 'Authentication required. Set Authorization header with valid token.',
|
|
3372
|
-
}));
|
|
3373
|
-
return;
|
|
3374
|
-
}
|
|
3375
|
-
const rateLimit = checkCodeActRateLimit(req);
|
|
3376
|
-
if (!rateLimit.allowed) {
|
|
3377
|
-
logger.warn('Code-Act rate limit exceeded', {
|
|
3378
|
-
client: rateLimit.clientKey,
|
|
3379
|
-
retryAfterSeconds: rateLimit.retryAfterSeconds,
|
|
3380
|
-
});
|
|
3381
|
-
res.writeHead(429, {
|
|
3382
|
-
'Content-Type': 'application/json',
|
|
3383
|
-
'Retry-After': String(rateLimit.retryAfterSeconds ?? 60),
|
|
3384
|
-
});
|
|
3385
|
-
res.end(JSON.stringify({
|
|
3386
|
-
error: true,
|
|
3387
|
-
message: 'Code-Act rate limit exceeded. Retry later.',
|
|
3388
|
-
retry_after_seconds: rateLimit.retryAfterSeconds ?? 60,
|
|
3389
|
-
}));
|
|
3390
|
-
return;
|
|
3391
|
-
}
|
|
3392
|
-
if (!options.executeCodeAct) {
|
|
3393
|
-
res.writeHead(501, { 'Content-Type': 'application/json' });
|
|
3394
|
-
res.end(JSON.stringify({ error: true, message: 'Code-Act executor not configured' }));
|
|
3395
|
-
return;
|
|
3396
|
-
}
|
|
3397
|
-
const body = await readBody(req);
|
|
3398
|
-
const code = body?.code;
|
|
3399
|
-
if (!code || typeof code !== 'string') {
|
|
3400
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3401
|
-
res.end(JSON.stringify({ error: true, message: 'Missing required field: code (string)' }));
|
|
3402
|
-
return;
|
|
3403
|
-
}
|
|
3404
|
-
let contextKey;
|
|
3405
|
-
if (body.context_key !== undefined) {
|
|
3406
|
-
if (!(0, run_context_registry_js_1.isProcessContextKey)(body.context_key)) {
|
|
3407
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3408
|
-
res.end(JSON.stringify({
|
|
3409
|
-
error: true,
|
|
3410
|
-
message: 'context_key must be a 32-byte base64url value without padding.',
|
|
3411
|
-
}));
|
|
3412
|
-
return;
|
|
3413
|
-
}
|
|
3414
|
-
contextKey = body.context_key;
|
|
3415
|
-
}
|
|
3416
|
-
let agentId;
|
|
3417
|
-
if (body.agent_id !== undefined) {
|
|
3418
|
-
if (typeof body.agent_id !== 'string' || body.agent_id.trim().length === 0) {
|
|
3419
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3420
|
-
res.end(JSON.stringify({ error: true, message: 'agent_id must be a non-empty string.' }));
|
|
3421
|
-
return;
|
|
3422
|
-
}
|
|
3423
|
-
agentId = body.agent_id.trim();
|
|
3424
|
-
}
|
|
3425
|
-
const allowedTools = normalizeCodeActToolList(body.allowed_tools, 'allowed_tools', res);
|
|
3426
|
-
if (allowedTools === false) {
|
|
3427
|
-
return;
|
|
3428
|
-
}
|
|
3429
|
-
const blockedTools = normalizeCodeActToolList(body.blocked_tools, 'blocked_tools', res);
|
|
3430
|
-
if (blockedTools === false) {
|
|
3431
|
-
return;
|
|
3432
|
-
}
|
|
3433
|
-
const result = await options.executeCodeAct(code, {
|
|
3434
|
-
...(contextKey ? { contextKey } : {}),
|
|
3435
|
-
...(agentId ? { agentId } : {}),
|
|
3436
|
-
...(allowedTools ? { allowedTools } : {}),
|
|
3437
|
-
...(blockedTools ? { blockedTools } : {}),
|
|
3438
|
-
});
|
|
3439
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
3440
|
-
res.end(JSON.stringify(result));
|
|
3441
|
-
}
|
|
3442
|
-
catch (error) {
|
|
3443
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3444
|
-
logger.error('Code-Act execution error:', message);
|
|
3445
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
3446
|
-
res.end(JSON.stringify({ error: true, message }));
|
|
3447
|
-
}
|
|
3448
|
-
}
|
|
3449
|
-
function normalizeCodeActToolList(value, field, res) {
|
|
3450
|
-
if (value === undefined) {
|
|
3451
|
-
return undefined;
|
|
3452
|
-
}
|
|
3453
|
-
if (!Array.isArray(value) || value.some((item) => typeof item !== 'string')) {
|
|
3454
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3455
|
-
res.end(JSON.stringify({ error: true, message: `${field} must be an array of strings.` }));
|
|
3456
|
-
return false;
|
|
3457
|
-
}
|
|
3458
|
-
return value.map((item) => item.trim()).filter((item) => item.length > 0);
|
|
3459
|
-
}
|
|
3460
|
-
//# sourceMappingURL=graph-api.js.map
|