@jungjaehoon/mama-core 2.4.1 → 4.1.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/README.md +76 -239
- package/db/migrations/030-case-first-memory-substrate.sql +13 -98
- package/db/migrations/034-add-connector-event-scope-columns.sql +9 -13
- package/db/migrations/039-add-connector-event-operator-ingest-seq.sql +9 -95
- package/db/migrations/062-refresh-connector-event-sequences.sql +9 -113
- package/db/migrations/063-refresh-legacy-connector-event-updates.sql +9 -32
- package/db/migrations/067-add-connector-event-source-entity-id.sql +9 -13
- package/db/migrations/069-create-registry-nodes.sql +52 -0
- package/db/migrations/070-record-identity.sql +35 -0
- package/db/migrations/071-service-operation-origins.sql +187 -0
- package/db/migrations/072-observation-versions.sql +29 -0
- package/db/migrations/073-registry-corrections.sql +45 -0
- package/db/migrations/074-work-graph-ref-kinds.sql +39 -0
- package/db/migrations/075-agent-judgments.sql +58 -0
- package/db/migrations/076-scoped-checkpoint-bindings.sql +15 -0
- package/db/migrations/077-legacy-record-kind.sql +6 -0
- package/db/migrations/078-source-ingest-commands.sql +18 -0
- package/db/migrations/079-twin-edge-relations.sql +43 -0
- package/db/migrations/080-restore-duration-days.sql +7 -0
- package/db/migrations/081-mailbox.sql +61 -0
- package/db/migrations/082-commitments-row-id.sql +12 -0
- package/db/migrations/083-observation-is-the-evidence.sql +49 -0
- package/db/migrations/084-scope-kind-is-not-the-cores-to-list.sql +34 -0
- package/db/migrations/085-a-migration-has-a-source.sql +37 -0
- package/db/migrations/086-the-mailbox-is-generic.sql +110 -0
- package/db/migrations/087-mailbox-payload.sql +5 -0
- package/db/migrations/088-native-input-journal.sql +14 -0
- package/db/migrations/089-native-turn-receipt-lookup.sql +3 -0
- package/db/migrations/090-model-run-native-inputs.sql +29 -0
- package/db/migrations/091-native-turn-results.sql +11 -0
- package/db/migrations/092-restore-decision-fts.sql +34 -0
- package/db/migrations/093-native-turn-primary-kind.sql +14 -0
- package/db/migrations/094-commitment-run-provenance.sql +9 -0
- package/db/migrations/095-model-run-native-input-identity.sql +39 -0
- package/db/migrations/096-drop-connector-event-index-fts.sql +9 -0
- package/db/migrations/097-native-input-json-validity.sql +37 -0
- package/db/migrations/098-workflow-memory-kind.sql +105 -0
- package/db/migrations/099-commitment-revision-graph.sql +2 -0
- package/dist/action-contracts.d.ts +212 -0
- package/dist/action-contracts.js +10 -0
- package/dist/api/catalog.d.ts +118 -0
- package/dist/api/catalog.js +1756 -0
- package/dist/api/dispatch.d.ts +76 -0
- package/dist/api/dispatch.js +372 -0
- package/dist/canonicalize.d.ts +2 -2
- package/dist/canonicalize.js +3 -3
- package/dist/client/client.d.ts +33 -0
- package/dist/client/client.js +123 -0
- package/dist/client/ipc.d.ts +81 -0
- package/dist/client/ipc.js +314 -0
- package/dist/db-adapter/base-adapter.d.ts +6 -66
- package/dist/db-adapter/base-adapter.js +6 -6
- package/dist/db-adapter/index.d.ts +5 -5
- package/dist/db-adapter/index.js +2 -5
- package/dist/db-adapter/node-sqlite-adapter.d.ts +85 -15
- package/dist/db-adapter/node-sqlite-adapter.js +1985 -570
- package/dist/db-manager.d.ts +53 -97
- package/dist/db-manager.js +121 -603
- package/dist/embedding/embedder.d.ts +132 -0
- package/dist/embedding/embedder.js +299 -0
- package/dist/identity/principal-repository.d.ts +2 -2
- package/dist/index.d.ts +43 -58
- package/dist/index.js +97 -145
- package/dist/{context-compile/channel-grant.d.ts → knowledge/access.d.ts} +12 -17
- package/dist/knowledge/access.js +663 -0
- package/dist/knowledge/case-errors.d.ts +31 -0
- package/dist/knowledge/case-errors.js +40 -0
- package/dist/{cases/search-rollup.d.ts → knowledge/case-search-rollup.d.ts} +5 -4
- package/dist/{cases/search-rollup.js → knowledge/case-search-rollup.js} +6 -8
- package/dist/{cases/store.d.ts → knowledge/case-store.d.ts} +3 -6
- package/dist/{cases/store.js → knowledge/case-store.js} +7 -42
- package/dist/{cases/timeline-range.d.ts → knowledge/case-timeline-range.d.ts} +3 -3
- package/dist/{cases/timeline-range.js → knowledge/case-timeline-range.js} +47 -25
- package/dist/{cases/types.d.ts → knowledge/case-types.d.ts} +8 -2
- package/dist/{cases/types.js → knowledge/case-types.js} +1 -1
- package/dist/knowledge/commitment-revision-migration.d.ts +4 -0
- package/dist/knowledge/commitment-revision-migration.js +50 -0
- package/dist/knowledge/commitments.d.ts +192 -0
- package/dist/knowledge/commitments.js +386 -0
- package/dist/knowledge/decision-edges.d.ts +70 -0
- package/dist/knowledge/decision-edges.js +123 -0
- package/dist/{agent-graph/types.d.ts → knowledge/graph-query.d.ts} +80 -70
- package/dist/knowledge/graph-query.js +1585 -0
- package/dist/knowledge/identity.d.ts +16 -0
- package/dist/knowledge/identity.js +22 -0
- package/dist/knowledge/index.d.ts +47 -0
- package/dist/knowledge/index.js +90 -0
- package/dist/knowledge/judgment-edge.d.ts +6 -0
- package/dist/knowledge/judgment-edge.js +22 -0
- package/dist/knowledge/judgments.d.ts +118 -0
- package/dist/knowledge/judgments.js +802 -0
- package/dist/knowledge/observations.d.ts +160 -0
- package/dist/knowledge/observations.js +449 -0
- package/dist/knowledge/question-type.d.ts +34 -0
- package/dist/knowledge/question-type.js +70 -0
- package/dist/{search → knowledge}/ranker-features.js +1 -1
- package/dist/{search → knowledge}/search-quality.d.ts +0 -1
- package/dist/knowledge/search.d.ts +38 -0
- package/dist/knowledge/search.js +91 -0
- package/dist/knowledge/source-ingest.d.ts +65 -0
- package/dist/knowledge/source-ingest.js +174 -0
- package/dist/{edges/types.d.ts → knowledge/twin-edge-types.d.ts} +31 -4
- package/dist/{edges/types.js → knowledge/twin-edge-types.js} +13 -2
- package/dist/knowledge/work-dates.d.ts +49 -0
- package/dist/knowledge/work-dates.js +120 -0
- package/dist/mama-api.d.ts +114 -778
- package/dist/mama-api.js +313 -2461
- package/dist/memory/api.d.ts +264 -24
- package/dist/memory/api.js +1633 -843
- package/dist/memory/bootstrap-builder.d.ts +2 -1
- package/dist/memory/bootstrap-builder.js +5 -5
- package/dist/memory/channel-summary-state-store.d.ts +3 -2
- package/dist/memory/channel-summary-state-store.js +53 -51
- package/dist/memory/channel-summary-store.d.ts +5 -3
- package/dist/memory/channel-summary-store.js +3 -8
- package/dist/memory/dashboard-read.d.ts +46 -0
- package/dist/memory/dashboard-read.js +94 -0
- package/dist/memory/event-store.d.ts +3 -3
- package/dist/memory/event-store.js +3 -10
- package/dist/memory/finding-store.d.ts +3 -2
- package/dist/memory/finding-store.js +2 -7
- package/dist/memory/graph-read.d.ts +52 -0
- package/dist/memory/graph-read.js +130 -0
- package/dist/memory/judgment-types.d.ts +394 -0
- package/dist/memory/judgment-types.js +16 -0
- package/dist/memory/provenance-audit.d.ts +5 -2
- package/dist/memory/provenance-audit.js +8 -14
- package/dist/memory/provenance-live.d.ts +141 -0
- package/dist/memory/provenance-live.js +409 -0
- package/dist/memory/provenance-query.d.ts +5 -4
- package/dist/memory/provenance-query.js +21 -29
- package/dist/memory/provenance-resolver.d.ts +191 -0
- package/dist/memory/provenance-resolver.js +155 -0
- package/dist/memory/provenance.d.ts +1 -11
- package/dist/memory/provenance.js +2 -33
- package/dist/memory/recall-sanitize.d.ts +55 -0
- package/dist/memory/recall-sanitize.js +144 -0
- package/dist/memory/secret-filter.d.ts +32 -0
- package/dist/memory/secret-filter.js +126 -0
- package/dist/memory/truth-store.d.ts +2 -1
- package/dist/memory/truth-store.js +1 -4
- package/dist/memory/types.d.ts +74 -24
- package/dist/memory/types.js +75 -5
- package/dist/memory/write-adapters.d.ts +98 -0
- package/dist/memory/write-adapters.js +242 -0
- package/dist/operations/owner-action-effects.d.ts +53 -0
- package/dist/operations/owner-action-effects.js +96 -0
- package/dist/provenance/source-ref.d.ts +1 -1
- package/dist/provenance/source-ref.js +0 -2
- package/dist/registry/corrections.d.ts +31 -0
- package/dist/registry/corrections.js +332 -0
- package/dist/registry/record-identity.d.ts +49 -0
- package/dist/registry/record-identity.js +133 -0
- package/dist/registry/store.d.ts +101 -0
- package/dist/registry/store.js +395 -0
- package/dist/registry/types.d.ts +28 -0
- package/dist/registry/types.js +5 -0
- package/dist/relevance-scorer.js +2 -2
- package/dist/runtime/agent-event-bus.d.ts +50 -0
- package/dist/runtime/agent-event-bus.js +101 -0
- package/dist/runtime/drivers/claude-cli-wrapper.d.ts +152 -0
- package/dist/runtime/drivers/claude-cli-wrapper.js +375 -0
- package/dist/runtime/drivers/claude-effort.d.ts +4 -0
- package/dist/runtime/drivers/claude-effort.js +16 -0
- package/dist/runtime/drivers/cli-arg-redaction.d.ts +2 -0
- package/dist/runtime/drivers/cli-arg-redaction.js +18 -0
- package/dist/runtime/drivers/cli-secret-redaction.d.ts +17 -0
- package/dist/runtime/drivers/cli-secret-redaction.js +126 -0
- package/dist/runtime/drivers/codex-app-server-process.d.ts +277 -0
- package/dist/runtime/drivers/codex-app-server-process.js +2342 -0
- package/dist/runtime/drivers/codex-auxiliary-tools.d.ts +17 -0
- package/dist/runtime/drivers/codex-auxiliary-tools.js +267 -0
- package/dist/runtime/drivers/codex-home.d.ts +20 -0
- package/dist/runtime/drivers/codex-home.js +674 -0
- package/dist/runtime/drivers/codex-thread-registry.d.ts +63 -0
- package/dist/runtime/drivers/codex-thread-registry.js +433 -0
- package/dist/runtime/drivers/persistent-cli-adapter.d.ts +160 -0
- package/dist/runtime/drivers/persistent-cli-adapter.js +396 -0
- package/dist/runtime/drivers/persistent-cli-process.d.ts +425 -0
- package/dist/runtime/drivers/persistent-cli-process.js +1529 -0
- package/dist/runtime/drivers/types.d.ts +456 -0
- package/dist/runtime/drivers/types.js +110 -0
- package/dist/runtime/mailbox.d.ts +223 -0
- package/dist/runtime/mailbox.js +582 -0
- package/dist/runtime/model-run-store.d.ts +28 -0
- package/dist/{model-runs/store.js → runtime/model-run-store.js} +81 -41
- package/dist/{model-runs/types.d.ts → runtime/model-run-types.d.ts} +33 -4
- package/dist/{model-runs/types.js → runtime/model-run-types.js} +1 -1
- package/dist/runtime/native-effect-observer.d.ts +22 -0
- package/dist/runtime/native-effect-observer.js +103 -0
- package/dist/runtime/native-input-journal.d.ts +46 -0
- package/dist/runtime/native-input-journal.js +308 -0
- package/dist/runtime/native-prompt.d.ts +118 -0
- package/dist/runtime/native-prompt.js +496 -0
- package/dist/runtime/native-session.d.ts +10 -0
- package/dist/{agent-graph/index.js → runtime/native-session.js} +9 -6
- package/dist/runtime/native-tool-trace-observer.d.ts +5 -0
- package/dist/runtime/native-tool-trace-observer.js +65 -0
- package/dist/runtime/native-turn.d.ts +272 -0
- package/dist/runtime/native-turn.js +1041 -0
- package/dist/runtime/operations.d.ts +236 -0
- package/dist/runtime/operations.js +565 -0
- package/dist/runtime/post-tool-handler.d.ts +74 -0
- package/dist/runtime/post-tool-handler.js +137 -0
- package/dist/runtime/prompt-layers.d.ts +126 -0
- package/dist/runtime/prompt-layers.js +239 -0
- package/dist/runtime/runtime-process.d.ts +102 -0
- package/dist/runtime/runtime-process.js +206 -0
- package/dist/runtime/runtime.d.ts +278 -0
- package/dist/runtime/runtime.js +563 -0
- package/dist/runtime/session-pool.d.ts +176 -0
- package/dist/runtime/session-pool.js +369 -0
- package/dist/runtime/stimulus-payload.d.ts +5 -0
- package/dist/runtime/stimulus-payload.js +50 -0
- package/dist/runtime/subagent-bridge.d.ts +24 -0
- package/dist/{agent-graph/types.js → runtime/subagent-bridge.js} +1 -1
- package/dist/runtime/text-completion.d.ts +22 -0
- package/dist/{agent-situation/types.js → runtime/text-completion.js} +1 -1
- package/dist/runtime/token-estimator.d.ts +25 -0
- package/dist/runtime/token-estimator.js +75 -0
- package/dist/runtime/tool-trace-store.d.ts +22 -0
- package/dist/{model-runs → runtime}/tool-trace-store.js +46 -27
- package/dist/runtime/trace-summary.d.ts +5 -0
- package/dist/runtime/trace-summary.js +74 -0
- package/dist/runtime/turn-text.d.ts +23 -0
- package/dist/runtime/turn-text.js +41 -0
- package/dist/storage/database.d.ts +67 -0
- package/dist/storage/database.js +158 -0
- package/package.json +20 -34
- package/dist/agent-graph/alias-write.d.ts +0 -3
- package/dist/agent-graph/alias-write.js +0 -234
- package/dist/agent-graph/entity-resolve.d.ts +0 -3
- package/dist/agent-graph/entity-resolve.js +0 -271
- package/dist/agent-graph/errors.d.ts +0 -4
- package/dist/agent-graph/errors.js +0 -11
- package/dist/agent-graph/graph-query.d.ts +0 -5
- package/dist/agent-graph/graph-query.js +0 -360
- package/dist/agent-graph/index.d.ts +0 -6
- package/dist/agent-situation/builder.d.ts +0 -8
- package/dist/agent-situation/builder.js +0 -239
- package/dist/agent-situation/cache-key.d.ts +0 -4
- package/dist/agent-situation/cache-key.js +0 -64
- package/dist/agent-situation/index.d.ts +0 -7
- package/dist/agent-situation/index.js +0 -28
- package/dist/agent-situation/packet-store.d.ts +0 -27
- package/dist/agent-situation/packet-store.js +0 -228
- package/dist/agent-situation/ranking-policy.d.ts +0 -18
- package/dist/agent-situation/ranking-policy.js +0 -75
- package/dist/agent-situation/source-readers.d.ts +0 -52
- package/dist/agent-situation/source-readers.js +0 -300
- package/dist/agent-situation/types.d.ts +0 -195
- package/dist/cases/wiki-page-index.d.ts +0 -37
- package/dist/cases/wiki-page-index.js +0 -201
- package/dist/config-loader.d.ts +0 -68
- package/dist/config-loader.js +0 -239
- package/dist/connectors/event-index.d.ts +0 -24
- package/dist/connectors/event-index.js +0 -245
- package/dist/connectors/raw-query.d.ts +0 -40
- package/dist/connectors/raw-query.js +0 -412
- package/dist/connectors/types.d.ts +0 -117
- package/dist/connectors/types.js +0 -3
- package/dist/context-compile/boundary-defaults.d.ts +0 -12
- package/dist/context-compile/boundary-defaults.js +0 -105
- package/dist/context-compile/channel-grant.js +0 -66
- package/dist/context-compile/compiler-policy.d.ts +0 -39
- package/dist/context-compile/compiler-policy.js +0 -147
- package/dist/context-compile/compiler.d.ts +0 -18
- package/dist/context-compile/compiler.js +0 -404
- package/dist/context-compile/index.d.ts +0 -10
- package/dist/context-compile/index.js +0 -26
- package/dist/context-compile/packet-store.d.ts +0 -8
- package/dist/context-compile/packet-store.js +0 -239
- package/dist/context-compile/ref.d.ts +0 -7
- package/dist/context-compile/ref.js +0 -102
- package/dist/context-compile/source-readers.d.ts +0 -70
- package/dist/context-compile/source-readers.js +0 -840
- package/dist/context-compile/types.d.ts +0 -155
- package/dist/context-compile/types.js +0 -11
- package/dist/context-compile/visibility.d.ts +0 -21
- package/dist/context-compile/visibility.js +0 -224
- package/dist/decision-tracker.d.ts +0 -206
- package/dist/decision-tracker.js +0 -481
- package/dist/edges/ref-validation.d.ts +0 -7
- package/dist/edges/ref-validation.js +0 -321
- package/dist/edges/store.d.ts +0 -8
- package/dist/edges/store.js +0 -129
- package/dist/embedding-client.d.ts +0 -28
- package/dist/embedding-client.js +0 -53
- package/dist/embedding-server/index.d.ts +0 -67
- package/dist/embedding-server/index.js +0 -405
- package/dist/embedding-server/mobile/auth.d.ts +0 -44
- package/dist/embedding-server/mobile/auth.js +0 -150
- package/dist/embedding-server/mobile/daemon.d.ts +0 -129
- package/dist/embedding-server/mobile/daemon.js +0 -313
- package/dist/embedding-server/mobile/output-parser.d.ts +0 -115
- package/dist/embedding-server/mobile/output-parser.js +0 -241
- package/dist/embedding-server/mobile/session-api.d.ts +0 -57
- package/dist/embedding-server/mobile/session-api.js +0 -261
- package/dist/embedding-server/mobile/session-manager.d.ts +0 -138
- package/dist/embedding-server/mobile/session-manager.js +0 -378
- package/dist/embedding-server/mobile/websocket-handler.d.ts +0 -137
- package/dist/embedding-server/mobile/websocket-handler.js +0 -486
- package/dist/embeddings.d.ts +0 -68
- package/dist/embeddings.js +0 -244
- package/dist/entities/audit-metrics.d.ts +0 -68
- package/dist/entities/audit-metrics.js +0 -124
- package/dist/entities/candidate-generator.d.ts +0 -8
- package/dist/entities/candidate-generator.js +0 -24
- package/dist/entities/entity-linked-decision-counts.d.ts +0 -2
- package/dist/entities/entity-linked-decision-counts.js +0 -29
- package/dist/entities/entity-list.d.ts +0 -22
- package/dist/entities/entity-list.js +0 -3
- package/dist/entities/entity-orphan-list.d.ts +0 -17
- package/dist/entities/entity-orphan-list.js +0 -3
- package/dist/entities/entity-search.d.ts +0 -20
- package/dist/entities/entity-search.js +0 -3
- package/dist/entities/errors.d.ts +0 -55
- package/dist/entities/errors.js +0 -100
- package/dist/entities/lineage-store.d.ts +0 -28
- package/dist/entities/lineage-store.js +0 -204
- package/dist/entities/normalization.d.ts +0 -14
- package/dist/entities/normalization.js +0 -63
- package/dist/entities/policy-store.d.ts +0 -8
- package/dist/entities/policy-store.js +0 -75
- package/dist/entities/policy-types.d.ts +0 -72
- package/dist/entities/policy-types.js +0 -59
- package/dist/entities/projection.d.ts +0 -8
- package/dist/entities/projection.js +0 -82
- package/dist/entities/provenance-query.d.ts +0 -32
- package/dist/entities/provenance-query.js +0 -3
- package/dist/entities/read-identity.d.ts +0 -31
- package/dist/entities/read-identity.js +0 -264
- package/dist/entities/recall-bridge.d.ts +0 -5
- package/dist/entities/recall-bridge.js +0 -171
- package/dist/entities/resolution-engine.d.ts +0 -8
- package/dist/entities/resolution-engine.js +0 -3
- package/dist/entities/rollback-preview.d.ts +0 -35
- package/dist/entities/rollback-preview.js +0 -3
- package/dist/entities/source-locator.d.ts +0 -3
- package/dist/entities/source-locator.js +0 -32
- package/dist/entities/store.d.ts +0 -69
- package/dist/entities/store.js +0 -544
- package/dist/entities/types.d.ts +0 -166
- package/dist/entities/types.js +0 -30
- package/dist/memory/extraction-prompt.d.ts +0 -4
- package/dist/memory/extraction-prompt.js +0 -89
- package/dist/memory/scope-backfill.d.ts +0 -14
- package/dist/memory/scope-backfill.js +0 -3
- package/dist/memory/scope-store.d.ts +0 -4
- package/dist/memory/scope-store.js +0 -9
- package/dist/memory-store.d.ts +0 -87
- package/dist/memory-store.js +0 -78
- package/dist/model-runs/store.d.ts +0 -13
- package/dist/model-runs/tool-trace-store.d.ts +0 -8
- package/dist/notification-manager.d.ts +0 -7
- package/dist/notification-manager.js +0 -12
- package/dist/outcome-tracker.d.ts +0 -151
- package/dist/outcome-tracker.js +0 -271
- package/dist/query-intent.d.ts +0 -23
- package/dist/query-intent.js +0 -114
- package/dist/runtime/trusted-provenance.d.ts +0 -3
- package/dist/runtime/trusted-provenance.js +0 -6
- package/dist/search/question-type.d.ts +0 -5
- package/dist/search/question-type.js +0 -41
- package/dist/test-utils.d.ts +0 -80
- package/dist/test-utils.js +0 -218
- package/dist/tier-validator.d.ts +0 -43
- package/dist/tier-validator.js +0 -159
- package/dist/time-formatter.d.ts +0 -25
- package/dist/time-formatter.js +0 -93
- /package/dist/{search → knowledge}/feedback-store.d.ts +0 -0
- /package/dist/{search → knowledge}/feedback-store.js +0 -0
- /package/dist/{search → knowledge}/ranker-features.d.ts +0 -0
- /package/dist/{search → knowledge}/ranker-rescore.d.ts +0 -0
- /package/dist/{search → knowledge}/ranker-rescore.js +0 -0
- /package/dist/{search → knowledge}/ranker-trainer.d.ts +0 -0
- /package/dist/{search → knowledge}/ranker-trainer.js +0 -0
- /package/dist/{search → knowledge}/search-quality.js +0 -0
|
@@ -1,405 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* MAMA Embedding HTTP Server
|
|
4
|
-
*
|
|
5
|
-
* HTTP API for embedding generation, integrated with MCP server.
|
|
6
|
-
* Provides fast embedding access for Claude Code hooks.
|
|
7
|
-
*
|
|
8
|
-
* Features:
|
|
9
|
-
* - Model stays loaded in memory (singleton)
|
|
10
|
-
* - HTTP API at localhost:${MAMA_EMBEDDING_PORT || MAMA_HTTP_PORT || 3849}
|
|
11
|
-
* - Health check endpoint
|
|
12
|
-
* - Shared model with MCP server
|
|
13
|
-
*
|
|
14
|
-
* @module embedding-http-server
|
|
15
|
-
*/
|
|
16
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
-
};
|
|
19
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.PORT_FILE = exports.HOST = exports.DEFAULT_PORT = exports.SHUTDOWN_TOKEN = void 0;
|
|
21
|
-
exports.resolveEmbeddingRole = resolveEmbeddingRole;
|
|
22
|
-
exports.cleanupPortFile = cleanupPortFile;
|
|
23
|
-
exports.startEmbeddingServer = startEmbeddingServer;
|
|
24
|
-
exports.warmModel = warmModel;
|
|
25
|
-
const http_1 = __importDefault(require("http"));
|
|
26
|
-
const path_1 = __importDefault(require("path"));
|
|
27
|
-
const fs_1 = __importDefault(require("fs"));
|
|
28
|
-
const crypto_1 = __importDefault(require("crypto"));
|
|
29
|
-
// SECURITY P1: Shutdown token for authenticated takeover
|
|
30
|
-
exports.SHUTDOWN_TOKEN = process.env.MAMA_SHUTDOWN_TOKEN || crypto_1.default.randomBytes(16).toString('hex');
|
|
31
|
-
// Import embedding functions from mama-core
|
|
32
|
-
const embeddings_js_1 = require("../embeddings.js");
|
|
33
|
-
const config_loader_js_1 = require("../config-loader.js");
|
|
34
|
-
const db_manager_js_1 = require("../db-manager.js");
|
|
35
|
-
// Import Session API handler (chat session API)
|
|
36
|
-
const session_api_js_1 = require("./mobile/session-api.js");
|
|
37
|
-
// Import WebSocket handler (chat WebSocket API - V2 with MessageRouter)
|
|
38
|
-
const websocket_handler_js_1 = require("./mobile/websocket-handler.js");
|
|
39
|
-
// Import Session Manager
|
|
40
|
-
const session_manager_js_1 = require("./mobile/session-manager.js");
|
|
41
|
-
// Create session manager (shared between REST API and WebSocket)
|
|
42
|
-
const sessionManager = new session_manager_js_1.SessionManager();
|
|
43
|
-
const sessionHandler = (0, session_api_js_1.createSessionHandler)(sessionManager);
|
|
44
|
-
function resolveConfiguredPort() {
|
|
45
|
-
const rawPort = process.env.MAMA_EMBEDDING_PORT || process.env.MAMA_HTTP_PORT || '';
|
|
46
|
-
const parsedPort = parseInt(rawPort, 10);
|
|
47
|
-
if (Number.isInteger(parsedPort) && parsedPort > 0 && parsedPort < 65536) {
|
|
48
|
-
return parsedPort;
|
|
49
|
-
}
|
|
50
|
-
return 3849;
|
|
51
|
-
}
|
|
52
|
-
// Configuration
|
|
53
|
-
exports.DEFAULT_PORT = resolveConfiguredPort();
|
|
54
|
-
exports.HOST = '127.0.0.1'; // localhost only for security
|
|
55
|
-
// Port file for clients to discover the server
|
|
56
|
-
exports.PORT_FILE = path_1.default.join(process.env.HOME || '/tmp', '.mama-embedding-port');
|
|
57
|
-
// Track if model is loaded
|
|
58
|
-
let modelLoaded = false;
|
|
59
|
-
// Track server instance for shutdown
|
|
60
|
-
let _serverInstance = null;
|
|
61
|
-
let _hasChatCapability = false;
|
|
62
|
-
// Track active connections for graceful shutdown
|
|
63
|
-
const connections = new Set();
|
|
64
|
-
// Graph handler (optional, passed from standalone)
|
|
65
|
-
let graphHandler = null;
|
|
66
|
-
let _wssInstance = null;
|
|
67
|
-
// Resolve the e5 role from an HTTP body value. Absent/unknown -> passage, so old
|
|
68
|
-
// clients that never send a role keep getting passage vectors (backward compatible).
|
|
69
|
-
function resolveEmbeddingRole(raw) {
|
|
70
|
-
return raw === 'query' ? 'query' : 'passage';
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Read request body as JSON
|
|
74
|
-
*/
|
|
75
|
-
function readBody(req) {
|
|
76
|
-
return new Promise((resolve, reject) => {
|
|
77
|
-
let data = '';
|
|
78
|
-
req.on('data', (chunk) => (data += chunk));
|
|
79
|
-
req.on('end', () => {
|
|
80
|
-
try {
|
|
81
|
-
resolve(JSON.parse(data));
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
reject(new Error('Invalid JSON'));
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
req.on('error', reject);
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* HTTP request handler
|
|
92
|
-
*/
|
|
93
|
-
async function handleRequest(req, res) {
|
|
94
|
-
// CORS headers for local requests
|
|
95
|
-
// Security Note: CORS '*' is safe here because:
|
|
96
|
-
// 1. Server binds to localhost only (127.0.0.1)
|
|
97
|
-
// 2. No sensitive data exposed (user's own decisions)
|
|
98
|
-
// 3. Required for the browser-based Viewer
|
|
99
|
-
res.setHeader('Content-Type', 'application/json');
|
|
100
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
101
|
-
// Health check
|
|
102
|
-
if (req.url === '/health' && req.method === 'GET') {
|
|
103
|
-
res.writeHead(200);
|
|
104
|
-
res.end(JSON.stringify({
|
|
105
|
-
status: 'ok',
|
|
106
|
-
modelLoaded,
|
|
107
|
-
model: (0, config_loader_js_1.getModelName)(),
|
|
108
|
-
dim: (0, config_loader_js_1.getEmbeddingDim)(),
|
|
109
|
-
chatEnabled: _hasChatCapability,
|
|
110
|
-
}));
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
// SECURITY P1: Shutdown endpoint with token authentication (for Standalone takeover)
|
|
114
|
-
if (req.url === '/shutdown' && req.method === 'POST') {
|
|
115
|
-
const providedToken = req.headers['x-shutdown-token'];
|
|
116
|
-
if (providedToken !== exports.SHUTDOWN_TOKEN) {
|
|
117
|
-
console.error('[EmbeddingHTTP] SECURITY: Invalid shutdown token rejected');
|
|
118
|
-
res.writeHead(401);
|
|
119
|
-
res.end(JSON.stringify({ error: 'Invalid shutdown token' }));
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
console.error('[EmbeddingHTTP] Shutdown requested (Standalone takeover, token validated)');
|
|
123
|
-
res.writeHead(200);
|
|
124
|
-
res.end(JSON.stringify({ status: 'shutting_down' }));
|
|
125
|
-
// Graceful shutdown after response - close WebSocket first, then HTTP
|
|
126
|
-
setTimeout(() => {
|
|
127
|
-
// Close WebSocket server first to release connections
|
|
128
|
-
if (_wssInstance) {
|
|
129
|
-
_wssInstance.clients?.forEach((client) => {
|
|
130
|
-
try {
|
|
131
|
-
client.terminate();
|
|
132
|
-
}
|
|
133
|
-
catch {
|
|
134
|
-
// Ignore termination errors
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
_wssInstance.close(() => {
|
|
138
|
-
console.error('[EmbeddingHTTP] WebSocket server closed');
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
// Then close HTTP server
|
|
142
|
-
if (_serverInstance) {
|
|
143
|
-
_serverInstance.close(() => {
|
|
144
|
-
console.error('[EmbeddingHTTP] Server closed for Standalone takeover');
|
|
145
|
-
cleanupPortFile();
|
|
146
|
-
});
|
|
147
|
-
// Force close any remaining connections after a short delay
|
|
148
|
-
setTimeout(() => {
|
|
149
|
-
for (const socket of connections) {
|
|
150
|
-
socket.destroy();
|
|
151
|
-
}
|
|
152
|
-
}, 50);
|
|
153
|
-
}
|
|
154
|
-
}, 100);
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
// Embedding endpoint
|
|
158
|
-
if (req.url === '/embed' && req.method === 'POST') {
|
|
159
|
-
try {
|
|
160
|
-
const startTime = Date.now();
|
|
161
|
-
const body = await readBody(req);
|
|
162
|
-
if (!body.text || typeof body.text !== 'string') {
|
|
163
|
-
res.writeHead(400);
|
|
164
|
-
res.end(JSON.stringify({ error: 'Missing or invalid "text" field' }));
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
const role = resolveEmbeddingRole(body.role);
|
|
168
|
-
const embedding = await (0, embeddings_js_1.generateEmbedding)(body.text, role);
|
|
169
|
-
modelLoaded = true;
|
|
170
|
-
const latency = Date.now() - startTime;
|
|
171
|
-
res.writeHead(200);
|
|
172
|
-
res.end(JSON.stringify({
|
|
173
|
-
embedding: Array.from(embedding),
|
|
174
|
-
dim: embedding.length,
|
|
175
|
-
latency,
|
|
176
|
-
}));
|
|
177
|
-
}
|
|
178
|
-
catch (error) {
|
|
179
|
-
const errMsg = error instanceof Error ? error.message : String(error);
|
|
180
|
-
console.error(`[EmbeddingHTTP] Error: ${errMsg}`);
|
|
181
|
-
res.writeHead(500);
|
|
182
|
-
res.end(JSON.stringify({ error: errMsg }));
|
|
183
|
-
}
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
// Batch embedding endpoint
|
|
187
|
-
if (req.url === '/embed/batch' && req.method === 'POST') {
|
|
188
|
-
try {
|
|
189
|
-
const startTime = Date.now();
|
|
190
|
-
const body = await readBody(req);
|
|
191
|
-
if (!Array.isArray(body.texts)) {
|
|
192
|
-
res.writeHead(400);
|
|
193
|
-
res.end(JSON.stringify({ error: 'Missing or invalid "texts" array' }));
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
const role = resolveEmbeddingRole(body.role);
|
|
197
|
-
const embeddings = await Promise.all(body.texts.map((text) => (0, embeddings_js_1.generateEmbedding)(text, role).then((e) => Array.from(e))));
|
|
198
|
-
modelLoaded = true;
|
|
199
|
-
const latency = Date.now() - startTime;
|
|
200
|
-
res.writeHead(200);
|
|
201
|
-
res.end(JSON.stringify({
|
|
202
|
-
embeddings,
|
|
203
|
-
count: embeddings.length,
|
|
204
|
-
latency,
|
|
205
|
-
}));
|
|
206
|
-
}
|
|
207
|
-
catch (error) {
|
|
208
|
-
const errMsg = error instanceof Error ? error.message : String(error);
|
|
209
|
-
console.error(`[EmbeddingHTTP] Batch error: ${errMsg}`);
|
|
210
|
-
res.writeHead(500);
|
|
211
|
-
res.end(JSON.stringify({ error: errMsg }));
|
|
212
|
-
}
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
// Session API routes (chat session API)
|
|
216
|
-
try {
|
|
217
|
-
const sessionHandled = await sessionHandler(req, res);
|
|
218
|
-
if (sessionHandled) {
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
catch (error) {
|
|
223
|
-
const errMsg = error instanceof Error ? error.message : String(error);
|
|
224
|
-
console.error(`[EmbeddingHTTP] Session API error: ${errMsg}`);
|
|
225
|
-
res.writeHead(500);
|
|
226
|
-
res.end(JSON.stringify({ error: errMsg }));
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
// Graph API routes (Viewer, if graphHandler provided)
|
|
230
|
-
if (graphHandler) {
|
|
231
|
-
try {
|
|
232
|
-
const graphHandled = await graphHandler(req, res);
|
|
233
|
-
if (graphHandled) {
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
catch (error) {
|
|
238
|
-
const errMsg = error instanceof Error ? error.message : String(error);
|
|
239
|
-
console.error(`[EmbeddingHTTP] Graph API error: ${errMsg}`);
|
|
240
|
-
res.writeHead(500);
|
|
241
|
-
res.end(JSON.stringify({ error: errMsg }));
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
// Viewer fallback when graphHandler not provided (MCP-only mode)
|
|
246
|
-
const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
|
|
247
|
-
const isViewerPath = url.pathname === '/' ||
|
|
248
|
-
url.pathname === '/viewer' ||
|
|
249
|
-
url.pathname.startsWith('/viewer/') ||
|
|
250
|
-
url.pathname === '/graph' ||
|
|
251
|
-
url.pathname.startsWith('/graph/');
|
|
252
|
-
if (isViewerPath && !graphHandler) {
|
|
253
|
-
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
254
|
-
res.end(`<!DOCTYPE html>
|
|
255
|
-
<html>
|
|
256
|
-
<head><title>MAMA - Standalone Required</title></head>
|
|
257
|
-
<body style="font-family: system-ui; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #1a1a2e; color: #eee;">
|
|
258
|
-
<div style="text-align: center; padding: 2rem;">
|
|
259
|
-
<h1>🧠 MAMA Viewer</h1>
|
|
260
|
-
<p>The Viewer is only available in <strong>Standalone</strong> mode.</p>
|
|
261
|
-
<p style="color: #888; margin-top: 1rem;">Start Standalone: <code style="background: #333; padding: 0.25rem 0.5rem; border-radius: 4px;">mama start</code></p>
|
|
262
|
-
<p style="color: #666; font-size: 0.9rem; margin-top: 2rem;">Current: MCP Server (embedding only)</p>
|
|
263
|
-
</div>
|
|
264
|
-
</body>
|
|
265
|
-
</html>`);
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
// 404 for unknown routes
|
|
269
|
-
res.writeHead(404);
|
|
270
|
-
res.end(JSON.stringify({ error: 'Not found' }));
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Write port file for client discovery
|
|
274
|
-
*/
|
|
275
|
-
function writePortFile(port) {
|
|
276
|
-
try {
|
|
277
|
-
fs_1.default.writeFileSync(exports.PORT_FILE, String(port));
|
|
278
|
-
console.error(`[EmbeddingHTTP] Port file written: ${exports.PORT_FILE}`);
|
|
279
|
-
}
|
|
280
|
-
catch (e) {
|
|
281
|
-
const errMsg = e instanceof Error ? e.message : String(e);
|
|
282
|
-
console.error(`[EmbeddingHTTP] Failed to write port file: ${errMsg}`);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Clean up port file on exit
|
|
287
|
-
*/
|
|
288
|
-
function cleanupPortFile() {
|
|
289
|
-
try {
|
|
290
|
-
if (fs_1.default.existsSync(exports.PORT_FILE)) {
|
|
291
|
-
fs_1.default.unlinkSync(exports.PORT_FILE);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
catch {
|
|
295
|
-
// Ignore cleanup errors
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Start the HTTP embedding server
|
|
300
|
-
*
|
|
301
|
-
* @param port - Port to listen on (default: DEFAULT_PORT)
|
|
302
|
-
* @returns HTTP server instance
|
|
303
|
-
*/
|
|
304
|
-
async function startEmbeddingServer(port = exports.DEFAULT_PORT, options = {}) {
|
|
305
|
-
const { messageRouter, sessionStore, graphHandler: graphHandlerOption } = options;
|
|
306
|
-
// Track chat capability (Standalone provides messageRouter)
|
|
307
|
-
_hasChatCapability = !!(messageRouter && sessionStore);
|
|
308
|
-
// Store graph handler if provided
|
|
309
|
-
if (graphHandlerOption) {
|
|
310
|
-
graphHandler = graphHandlerOption;
|
|
311
|
-
console.error(`[EmbeddingHTTP] Graph handler registered (Viewer routes on port ${port})`);
|
|
312
|
-
}
|
|
313
|
-
// Check if HTTP server is disabled
|
|
314
|
-
if (process.env.MAMA_DISABLE_HTTP_SERVER === 'true') {
|
|
315
|
-
console.error('[EmbeddingHTTP] HTTP server disabled via MAMA_DISABLE_HTTP_SERVER');
|
|
316
|
-
console.error('[EmbeddingHTTP] The Viewer and the chat WebSocket API will not be available');
|
|
317
|
-
return null;
|
|
318
|
-
}
|
|
319
|
-
// Initialize database for graph API
|
|
320
|
-
await (0, db_manager_js_1.initDB)();
|
|
321
|
-
// Initialize session manager
|
|
322
|
-
await sessionManager.initDB();
|
|
323
|
-
return new Promise((resolve, reject) => {
|
|
324
|
-
const server = http_1.default.createServer(handleRequest);
|
|
325
|
-
server.on('error', (error) => {
|
|
326
|
-
if (error.code === 'EADDRINUSE') {
|
|
327
|
-
console.warn(`[EmbeddingHTTP] Port ${port} already in use, assuming another instance is running`);
|
|
328
|
-
// Not a fatal error - another server instance may be running
|
|
329
|
-
resolve(null);
|
|
330
|
-
}
|
|
331
|
-
else if (error.code === 'EPERM' || error.code === 'EACCES') {
|
|
332
|
-
console.warn(`[EmbeddingHTTP] Permission denied opening port ${port}, skipping HTTP embedding server (sandboxed environment)`);
|
|
333
|
-
// Some environments block listening on localhost; keep MCP server running without HTTP embeddings
|
|
334
|
-
resolve(null);
|
|
335
|
-
}
|
|
336
|
-
else {
|
|
337
|
-
reject(error);
|
|
338
|
-
}
|
|
339
|
-
});
|
|
340
|
-
server.listen(port, exports.HOST, () => {
|
|
341
|
-
console.warn(`[EmbeddingHTTP] Running at http://${exports.HOST}:${port}`);
|
|
342
|
-
// Note: Shutdown token not logged for security (use MAMA_DEBUG=true to enable)
|
|
343
|
-
if (process.env.MAMA_DEBUG === 'true') {
|
|
344
|
-
console.warn(`[EmbeddingHTTP] Shutdown token: ${exports.SHUTDOWN_TOKEN}`);
|
|
345
|
-
}
|
|
346
|
-
writePortFile(port);
|
|
347
|
-
// Track connections for graceful shutdown
|
|
348
|
-
server.on('connection', (socket) => {
|
|
349
|
-
connections.add(socket);
|
|
350
|
-
socket.on('close', () => connections.delete(socket));
|
|
351
|
-
});
|
|
352
|
-
// Initialize WebSocket server (unless disabled)
|
|
353
|
-
const skipWebSocket = process.env.MAMA_DISABLE_WEBSOCKET === 'true' ||
|
|
354
|
-
process.env.MAMA_DISABLE_MOBILE_CHAT === 'true';
|
|
355
|
-
if (!skipWebSocket) {
|
|
356
|
-
try {
|
|
357
|
-
if (messageRouter && sessionStore) {
|
|
358
|
-
_wssInstance = (0, websocket_handler_js_1.createWebSocketHandler)({
|
|
359
|
-
httpServer: server,
|
|
360
|
-
messageRouter: messageRouter,
|
|
361
|
-
sessionStore: sessionStore,
|
|
362
|
-
authToken: process.env.MAMA_AUTH_TOKEN,
|
|
363
|
-
});
|
|
364
|
-
console.error(`[EmbeddingHTTP] WebSocket server initialized (MessageRouter mode) at ws://${exports.HOST}:${port}/ws`);
|
|
365
|
-
}
|
|
366
|
-
else {
|
|
367
|
-
// Legacy mode without MessageRouter - skip for now
|
|
368
|
-
console.error(`[EmbeddingHTTP] WebSocket server skipped (no MessageRouter provided)`);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
catch (wsError) {
|
|
372
|
-
const errMsg = wsError instanceof Error ? wsError.message : String(wsError);
|
|
373
|
-
console.error(`[EmbeddingHTTP] WebSocket initialization failed: ${errMsg}`);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
// Track server instance for shutdown
|
|
377
|
-
_serverInstance = server;
|
|
378
|
-
resolve(server);
|
|
379
|
-
});
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* Pre-warm the embedding model
|
|
384
|
-
*/
|
|
385
|
-
async function warmModel() {
|
|
386
|
-
console.error('[EmbeddingHTTP] Pre-warming embedding model...');
|
|
387
|
-
const startTime = Date.now();
|
|
388
|
-
try {
|
|
389
|
-
await (0, embeddings_js_1.generateEmbedding)('MAMA warmup initialization');
|
|
390
|
-
modelLoaded = true;
|
|
391
|
-
const latency = Date.now() - startTime;
|
|
392
|
-
console.error(`[EmbeddingHTTP] Model warmed in ${latency}ms`);
|
|
393
|
-
return { success: true, latency };
|
|
394
|
-
}
|
|
395
|
-
catch (error) {
|
|
396
|
-
const errMsg = error instanceof Error ? error.message : String(error);
|
|
397
|
-
console.error(`[EmbeddingHTTP] Model warmup failed: ${errMsg}`);
|
|
398
|
-
return { success: false, error: errMsg };
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
// Cleanup on exit
|
|
402
|
-
process.on('exit', cleanupPortFile);
|
|
403
|
-
process.on('SIGTERM', cleanupPortFile);
|
|
404
|
-
process.on('SIGINT', cleanupPortFile);
|
|
405
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Authentication module - token-based auth for external access
|
|
3
|
-
* @module mobile/auth
|
|
4
|
-
* @version 1.5.0
|
|
5
|
-
*
|
|
6
|
-
* Provides authentication for requests from outside localhost.
|
|
7
|
-
* Uses MAMA_AUTH_TOKEN environment variable for simple token auth.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* import { authenticate, isLocalhost } from './auth';
|
|
11
|
-
* if (!authenticate(req)) {
|
|
12
|
-
* res.writeHead(401);
|
|
13
|
-
* res.end('Unauthorized');
|
|
14
|
-
* }
|
|
15
|
-
*/
|
|
16
|
-
import type { IncomingMessage } from 'http';
|
|
17
|
-
interface WebSocketLike {
|
|
18
|
-
close(code?: number, reason?: string): void;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Environment variable for auth token
|
|
22
|
-
*/
|
|
23
|
-
export declare const AUTH_TOKEN: string | undefined;
|
|
24
|
-
/**
|
|
25
|
-
* Check if request is from localhost
|
|
26
|
-
* @param req - HTTP request
|
|
27
|
-
* @returns True if from localhost
|
|
28
|
-
*/
|
|
29
|
-
export declare function isLocalhost(req: IncomingMessage): boolean;
|
|
30
|
-
/**
|
|
31
|
-
* Authenticate an HTTP request
|
|
32
|
-
* @param req - HTTP request
|
|
33
|
-
* @returns True if authenticated
|
|
34
|
-
*/
|
|
35
|
-
export declare function authenticate(req: IncomingMessage): boolean;
|
|
36
|
-
/**
|
|
37
|
-
* Authenticate a WebSocket upgrade request
|
|
38
|
-
* @param req - HTTP upgrade request
|
|
39
|
-
* @param ws - WebSocket connection
|
|
40
|
-
* @returns True if authenticated, closes ws if not
|
|
41
|
-
*/
|
|
42
|
-
export declare function authenticateWebSocket(req: IncomingMessage, ws: WebSocketLike): boolean;
|
|
43
|
-
export {};
|
|
44
|
-
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @fileoverview Authentication module - token-based auth for external access
|
|
4
|
-
* @module mobile/auth
|
|
5
|
-
* @version 1.5.0
|
|
6
|
-
*
|
|
7
|
-
* Provides authentication for requests from outside localhost.
|
|
8
|
-
* Uses MAMA_AUTH_TOKEN environment variable for simple token auth.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* import { authenticate, isLocalhost } from './auth';
|
|
12
|
-
* if (!authenticate(req)) {
|
|
13
|
-
* res.writeHead(401);
|
|
14
|
-
* res.end('Unauthorized');
|
|
15
|
-
* }
|
|
16
|
-
*/
|
|
17
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.AUTH_TOKEN = void 0;
|
|
19
|
-
exports.isLocalhost = isLocalhost;
|
|
20
|
-
exports.authenticate = authenticate;
|
|
21
|
-
exports.authenticateWebSocket = authenticateWebSocket;
|
|
22
|
-
const node_crypto_1 = require("node:crypto");
|
|
23
|
-
/**
|
|
24
|
-
* Environment variable for auth token
|
|
25
|
-
*/
|
|
26
|
-
exports.AUTH_TOKEN = process.env.MAMA_AUTH_TOKEN;
|
|
27
|
-
/**
|
|
28
|
-
* Track if we've warned about missing auth token
|
|
29
|
-
*/
|
|
30
|
-
let hasWarnedAboutToken = false;
|
|
31
|
-
/**
|
|
32
|
-
* Track if we've warned about query parameter token usage
|
|
33
|
-
*/
|
|
34
|
-
let hasWarnedAboutQueryToken = false;
|
|
35
|
-
/**
|
|
36
|
-
* HMAC key for timing-safe token comparison
|
|
37
|
-
*/
|
|
38
|
-
const hmacKey = (0, node_crypto_1.randomBytes)(32);
|
|
39
|
-
/**
|
|
40
|
-
* Timing-safe string comparison using HMAC to prevent timing attacks.
|
|
41
|
-
* Both strings are hashed with HMAC-SHA256 before comparison,
|
|
42
|
-
* ensuring constant-time evaluation regardless of input.
|
|
43
|
-
*/
|
|
44
|
-
function safeTokenEqual(a, b) {
|
|
45
|
-
const hmacA = (0, node_crypto_1.createHmac)('sha256', hmacKey).update(a).digest();
|
|
46
|
-
const hmacB = (0, node_crypto_1.createHmac)('sha256', hmacKey).update(b).digest();
|
|
47
|
-
return (0, node_crypto_1.timingSafeEqual)(hmacA, hmacB);
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Check if request is from localhost
|
|
51
|
-
* @param req - HTTP request
|
|
52
|
-
* @returns True if from localhost
|
|
53
|
-
*/
|
|
54
|
-
function isLocalhost(req) {
|
|
55
|
-
const socket = req.socket;
|
|
56
|
-
const connection = req.connection;
|
|
57
|
-
const remoteAddress = socket?.remoteAddress || connection?.remoteAddress;
|
|
58
|
-
return (remoteAddress === '127.0.0.1' || remoteAddress === '::1' || remoteAddress === '::ffff:127.0.0.1');
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Authenticate an HTTP request
|
|
62
|
-
* @param req - HTTP request
|
|
63
|
-
* @returns True if authenticated
|
|
64
|
-
*/
|
|
65
|
-
function authenticate(req) {
|
|
66
|
-
// Localhost always allowed
|
|
67
|
-
if (isLocalhost(req)) {
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
const remoteAddress = req.socket?.remoteAddress;
|
|
71
|
-
// External access detected - show security warning
|
|
72
|
-
if (!hasWarnedAboutToken) {
|
|
73
|
-
console.error('');
|
|
74
|
-
console.error('⚠️ ========================================');
|
|
75
|
-
console.error('⚠️ SECURITY WARNING: External access detected!');
|
|
76
|
-
console.error('⚠️ ========================================');
|
|
77
|
-
console.error('⚠️ ');
|
|
78
|
-
console.error('⚠️ Your MAMA server is being accessed from outside localhost.');
|
|
79
|
-
console.error('⚠️ This likely means you are using a tunnel (ngrok, Cloudflare, etc.)');
|
|
80
|
-
console.error('⚠️ ');
|
|
81
|
-
if (!exports.AUTH_TOKEN) {
|
|
82
|
-
console.error('⚠️ ❌ CRITICAL: MAMA_AUTH_TOKEN is NOT set!');
|
|
83
|
-
console.error('⚠️ Anyone with your tunnel URL can access your:');
|
|
84
|
-
console.error('⚠️ - Chat sessions with Claude Code');
|
|
85
|
-
console.error('⚠️ - Decision database (~/.claude/mama-memory.db)');
|
|
86
|
-
console.error('⚠️ - Local file system (via Claude Code)');
|
|
87
|
-
console.error('⚠️ ');
|
|
88
|
-
console.error('⚠️ To secure your server, set MAMA_AUTH_TOKEN:');
|
|
89
|
-
console.error('⚠️ export MAMA_AUTH_TOKEN="your-secret-token"');
|
|
90
|
-
console.error('⚠️ ');
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
console.error('⚠️ ✅ MAMA_AUTH_TOKEN is set (authentication enabled)');
|
|
94
|
-
console.error('⚠️ External clients must provide token in:');
|
|
95
|
-
console.error('⚠️ - Authorization: Bearer <token> header, OR');
|
|
96
|
-
console.error('⚠️ - ?token=<token> query parameter');
|
|
97
|
-
console.error('⚠️ ');
|
|
98
|
-
}
|
|
99
|
-
console.error('⚠️ To disable external access entirely:');
|
|
100
|
-
console.error('⚠️ export MAMA_DISABLE_HTTP_SERVER=true');
|
|
101
|
-
console.error('⚠️ export MAMA_DISABLE_MOBILE_CHAT=true');
|
|
102
|
-
console.error('⚠️ ');
|
|
103
|
-
console.error('⚠️ ========================================');
|
|
104
|
-
console.error('');
|
|
105
|
-
hasWarnedAboutToken = true;
|
|
106
|
-
}
|
|
107
|
-
// External access requires token
|
|
108
|
-
if (!exports.AUTH_TOKEN) {
|
|
109
|
-
console.error(`[Auth] External access denied from ${remoteAddress} (no MAMA_AUTH_TOKEN)`);
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
// Check Authorization header
|
|
113
|
-
const authHeader = req.headers['authorization'];
|
|
114
|
-
if (authHeader?.startsWith('Bearer ')) {
|
|
115
|
-
const token = authHeader.slice(7);
|
|
116
|
-
if (safeTokenEqual(token, exports.AUTH_TOKEN)) {
|
|
117
|
-
console.error(`[Auth] External access granted via Bearer token from ${remoteAddress}`);
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
// Check URL query parameter
|
|
122
|
-
const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
|
|
123
|
-
const queryToken = url.searchParams.get('token');
|
|
124
|
-
if (queryToken && safeTokenEqual(queryToken, exports.AUTH_TOKEN)) {
|
|
125
|
-
if (!hasWarnedAboutQueryToken) {
|
|
126
|
-
console.warn('[Auth] DEPRECATION WARNING: Authentication via query parameter (?token=...) is deprecated. ' +
|
|
127
|
-
'Token in URL may leak through server logs, browser history, and Referer headers. ' +
|
|
128
|
-
'Please use the Authorization header instead: "Authorization: Bearer <token>"');
|
|
129
|
-
hasWarnedAboutQueryToken = true;
|
|
130
|
-
}
|
|
131
|
-
console.error(`[Auth] External access granted via query token from ${remoteAddress}`);
|
|
132
|
-
return true;
|
|
133
|
-
}
|
|
134
|
-
console.error(`[Auth] External access denied from ${remoteAddress} (invalid token)`);
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Authenticate a WebSocket upgrade request
|
|
139
|
-
* @param req - HTTP upgrade request
|
|
140
|
-
* @param ws - WebSocket connection
|
|
141
|
-
* @returns True if authenticated, closes ws if not
|
|
142
|
-
*/
|
|
143
|
-
function authenticateWebSocket(req, ws) {
|
|
144
|
-
if (!authenticate(req)) {
|
|
145
|
-
ws.close(4001, 'Authentication required');
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
return true;
|
|
149
|
-
}
|
|
150
|
-
//# sourceMappingURL=auth.js.map
|