@cybermem/cli 0.9.12 → 0.13.3
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/dist/commands/install.js +430 -0
- package/dist/commands/reset.js +18 -2
- package/dist/commands/uninstall.js +145 -0
- package/dist/commands/upgrade.js +91 -52
- package/dist/index.js +18 -5
- package/dist/templates/ansible/playbooks/deploy-cybermem.yml +201 -24
- package/dist/templates/ansible/playbooks/reset-db.yml +44 -0
- package/dist/templates/auth-sidecar/Dockerfile +2 -10
- package/dist/templates/auth-sidecar/package.json +1 -3
- package/dist/templates/auth-sidecar/server.js +149 -110
- package/dist/templates/charts/cybermem/.helmignore +13 -0
- package/dist/templates/charts/cybermem/templates/dashboard-deployment.yaml +31 -7
- package/dist/templates/charts/cybermem/templates/dashboard-service.yaml +4 -4
- package/dist/templates/charts/cybermem/templates/openmemory-deployment.yaml +14 -8
- package/dist/templates/charts/cybermem/templates/openmemory-service.yaml +3 -3
- package/dist/templates/charts/cybermem/templates/secret.yaml +9 -0
- package/dist/templates/charts/cybermem/templates/traefik-config.yaml +67 -0
- package/dist/templates/charts/cybermem/templates/traefik-deployment.yaml +53 -0
- package/dist/templates/charts/cybermem/templates/traefik-service.yaml +17 -0
- package/dist/templates/charts/cybermem/values-vps.yaml +8 -4
- package/dist/templates/charts/cybermem/values.yaml +17 -9
- package/dist/templates/docker-compose.yml +103 -78
- package/dist/templates/monitoring/log_exporter/exporter.py +22 -29
- package/dist/templates/monitoring/traefik/traefik.yml +1 -4
- package/package.json +9 -3
- package/templates/ansible/playbooks/deploy-cybermem.yml +201 -24
- package/templates/ansible/playbooks/reset-db.yml +44 -0
- package/templates/auth-sidecar/Dockerfile +2 -10
- package/templates/auth-sidecar/package.json +1 -3
- package/templates/auth-sidecar/server.js +149 -110
- package/templates/charts/cybermem/.helmignore +13 -0
- package/templates/charts/cybermem/templates/dashboard-deployment.yaml +31 -7
- package/templates/charts/cybermem/templates/dashboard-service.yaml +4 -4
- package/templates/charts/cybermem/templates/openmemory-deployment.yaml +14 -8
- package/templates/charts/cybermem/templates/openmemory-service.yaml +3 -3
- package/templates/charts/cybermem/templates/secret.yaml +9 -0
- package/templates/charts/cybermem/templates/traefik-config.yaml +67 -0
- package/templates/charts/cybermem/templates/traefik-deployment.yaml +53 -0
- package/templates/charts/cybermem/templates/traefik-service.yaml +17 -0
- package/templates/charts/cybermem/values-vps.yaml +8 -4
- package/templates/charts/cybermem/values.yaml +17 -9
- package/templates/docker-compose.yml +103 -78
- package/templates/monitoring/log_exporter/exporter.py +22 -29
- package/templates/monitoring/traefik/traefik.yml +1 -4
- package/dist/commands/__tests__/backup.test.js +0 -75
- package/dist/commands/__tests__/restore.test.js +0 -70
- package/dist/commands/deploy.js +0 -239
- package/dist/commands/init.js +0 -362
- package/dist/commands/login.js +0 -165
- package/dist/templates/envs/local.example +0 -27
- package/dist/templates/envs/rpi.example +0 -27
- package/dist/templates/envs/vps.example +0 -25
- package/dist/templates/monitoring/instructions_injector/Dockerfile +0 -15
- package/dist/templates/monitoring/instructions_injector/injector.py +0 -137
- package/dist/templates/monitoring/instructions_injector/requirements.txt +0 -3
- package/dist/templates/openmemory/Dockerfile +0 -19
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
# Default values for cybermem.
|
|
2
2
|
|
|
3
|
+
# Global settings for SSoT
|
|
4
|
+
global:
|
|
5
|
+
traefik:
|
|
6
|
+
port: 8625
|
|
7
|
+
openmemory:
|
|
8
|
+
serviceName: "openmemory"
|
|
9
|
+
port: 8080
|
|
10
|
+
dashboard:
|
|
11
|
+
serviceName: "dashboard"
|
|
12
|
+
port: 3000
|
|
13
|
+
|
|
3
14
|
openmemory:
|
|
4
15
|
image:
|
|
5
|
-
repository: cybermem-
|
|
6
|
-
pullPolicy:
|
|
16
|
+
repository: ghcr.io/mikhailkogan17/cybermem-mcp
|
|
17
|
+
pullPolicy: Always
|
|
7
18
|
tag: "latest"
|
|
8
19
|
replicaCount: 1
|
|
9
20
|
service:
|
|
10
21
|
type: ClusterIP
|
|
11
|
-
port: 8080
|
|
12
22
|
persistence:
|
|
13
23
|
enabled: true
|
|
14
24
|
size: 10Gi
|
|
@@ -20,23 +30,21 @@ openmemory:
|
|
|
20
30
|
requests:
|
|
21
31
|
cpu: 100m
|
|
22
32
|
memory: 256Mi
|
|
23
|
-
env:
|
|
24
|
-
# Passed to the container
|
|
25
|
-
OM_PORT: "8080"
|
|
33
|
+
env: {}
|
|
26
34
|
|
|
27
35
|
dashboard:
|
|
28
36
|
image:
|
|
29
|
-
repository: cybermem-dashboard
|
|
37
|
+
repository: ghcr.io/mikhailkogan17/cybermem-dashboard
|
|
30
38
|
pullPolicy: IfNotPresent
|
|
31
39
|
tag: "latest"
|
|
32
40
|
replicaCount: 1
|
|
33
41
|
service:
|
|
34
42
|
type: ClusterIP
|
|
35
|
-
port: 3000
|
|
36
43
|
nodePort: 30000 # For k3d/local access if needed
|
|
37
44
|
resources: {}
|
|
38
45
|
|
|
39
46
|
env:
|
|
40
47
|
# Shared secrets
|
|
41
|
-
OPENMEMORY_API_KEY: "
|
|
48
|
+
OPENMEMORY_API_KEY: "sk-74d94d0021f1a9a525e1c311cfd16575"
|
|
42
49
|
OPENAI_API_KEY: ""
|
|
50
|
+
CYBERMEM_ENV: "staging"
|
|
@@ -6,21 +6,28 @@
|
|
|
6
6
|
services:
|
|
7
7
|
traefik:
|
|
8
8
|
image: traefik:v3.0
|
|
9
|
-
container_name
|
|
9
|
+
# container_name removed for simultaneity
|
|
10
10
|
command:
|
|
11
|
-
- --
|
|
12
|
-
- --
|
|
13
|
-
- --
|
|
14
|
-
- --
|
|
15
|
-
- --entrypoints.web.address=:8626
|
|
11
|
+
- --entryPoints.web.address=:${TRAEFIK_PORT:-8626}
|
|
12
|
+
- --ping=true
|
|
13
|
+
- --ping.entryPoint=web
|
|
14
|
+
- --log.level=INFO
|
|
16
15
|
- --accesslog=true
|
|
17
16
|
- --accesslog.filepath=/var/log/traefik/access.log
|
|
18
17
|
- --accesslog.format=json
|
|
18
|
+
- --accesslog.fields.headers.names.X-Client-Name=keep
|
|
19
|
+
- --accesslog.fields.headers.names.X-Client-Version=keep
|
|
20
|
+
- --providers.docker=true
|
|
21
|
+
- --providers.docker.exposedbydefault=false
|
|
22
|
+
- --providers.docker.constraints=Label(`com.docker.compose.project`, `${PROJECT_NAME:-cybermem}`)
|
|
23
|
+
- --providers.file.directory=/etc/traefik/dynamic
|
|
24
|
+
- --providers.file.watch=true
|
|
25
|
+
- --api.dashboard=true
|
|
26
|
+
- --api.insecure=true
|
|
19
27
|
ports:
|
|
20
|
-
- "8626
|
|
28
|
+
- "${TRAEFIK_PORT:-8626}:${TRAEFIK_PORT:-8626}"
|
|
21
29
|
volumes:
|
|
22
30
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
23
|
-
- ./monitoring/traefik/traefik.yml:/etc/traefik/traefik.yml:ro
|
|
24
31
|
- ./monitoring/traefik/dynamic:/etc/traefik/dynamic:ro
|
|
25
32
|
- traefik-logs:/var/log/traefik
|
|
26
33
|
labels:
|
|
@@ -35,62 +42,67 @@ services:
|
|
|
35
42
|
context: ../../mcp
|
|
36
43
|
dockerfile: Dockerfile
|
|
37
44
|
image: ghcr.io/mikhailkogan17/cybermem-mcp:latest
|
|
38
|
-
|
|
45
|
+
command:
|
|
46
|
+
[
|
|
47
|
+
"node",
|
|
48
|
+
"dist/index.js",
|
|
49
|
+
"--http",
|
|
50
|
+
"--port",
|
|
51
|
+
"8080",
|
|
52
|
+
"--env",
|
|
53
|
+
"${CYBERMEM_ENV:-prod}",
|
|
54
|
+
]
|
|
39
55
|
restart: unless-stopped
|
|
40
|
-
container_name
|
|
56
|
+
# container_name removed for simultaneity
|
|
41
57
|
environment:
|
|
42
|
-
OM_TIER: "hybrid"
|
|
43
|
-
PORT: "8080"
|
|
44
|
-
OM_PORT: "0"
|
|
45
58
|
OM_DB_PATH: /data/openmemory.sqlite
|
|
59
|
+
CYBERMEM_ENV: ${CYBERMEM_ENV:-prod}
|
|
60
|
+
CYBERMEM_INSTANCE: ${CYBERMEM_INSTANCE:-local}
|
|
61
|
+
CYBERMEM_TAILSCALE: ${CYBERMEM_TAILSCALE:-false}
|
|
46
62
|
volumes:
|
|
47
63
|
- ${CYBERMEM_ENV_PATH:-${HOME}/.cybermem/.env}:/.env
|
|
48
|
-
- ${HOME}/.cybermem/data:/data
|
|
64
|
+
- ${DATA_DIR:-${HOME}/.cybermem/data}:/data
|
|
65
|
+
- ${SECRETS_DIR:-./secrets}/om_api_key:/run/secrets/om_api_key:ro
|
|
49
66
|
depends_on:
|
|
50
67
|
- traefik
|
|
51
68
|
- auth-sidecar
|
|
69
|
+
# Secrets removed to avoid CI read-only mount issues
|
|
70
|
+
# secrets:
|
|
71
|
+
# - om_api_key
|
|
52
72
|
labels:
|
|
53
73
|
- traefik.enable=true
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- traefik.http.routers
|
|
57
|
-
- traefik.http.routers.mcp
|
|
58
|
-
- traefik.http.routers
|
|
59
|
-
- traefik.http.routers
|
|
60
|
-
- traefik.http.routers
|
|
61
|
-
|
|
62
|
-
- traefik.http.routers
|
|
63
|
-
- traefik.http.
|
|
64
|
-
- traefik.http.routers
|
|
65
|
-
- traefik.http.routers
|
|
66
|
-
- traefik.http.
|
|
67
|
-
|
|
68
|
-
- traefik.http.routers
|
|
69
|
-
- traefik.http.routers.legacy-api.entrypoints=web
|
|
70
|
-
- traefik.http.routers.legacy-api.priority=100
|
|
71
|
-
- traefik.http.routers.legacy-api.service=mcp-service
|
|
72
|
-
- traefik.http.routers.legacy-api.middlewares=auth-check
|
|
74
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-mcp.rule=PathPrefix(`/mcp`) || PathPrefix(`/sse`)
|
|
75
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-mcp.entrypoints=web
|
|
76
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-mcp.priority=100
|
|
77
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-mcp.service=${PROJECT_NAME:-cybermem}-mcp-service
|
|
78
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-mcp.middlewares=auth-check
|
|
79
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-mcp-public.rule=PathPrefix(`/health`)
|
|
80
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-mcp-public.entrypoints=web
|
|
81
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-mcp-public.priority=100
|
|
82
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-mcp-public.service=${PROJECT_NAME:-cybermem}-mcp-service
|
|
83
|
+
- traefik.http.services.${PROJECT_NAME:-cybermem}-mcp-service.loadbalancer.server.port=8080
|
|
84
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-legacy-api.rule=PathPrefix(`/add`) || PathPrefix(`/query`) || PathPrefix(`/all`) || PathPrefix(`/memory`)
|
|
85
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-legacy-api.entrypoints=web
|
|
86
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-legacy-api.priority=130
|
|
87
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-legacy-api.service=${PROJECT_NAME:-cybermem}-mcp-service
|
|
88
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-legacy-api.middlewares=auth-check
|
|
73
89
|
|
|
74
|
-
# Support legacy /cybermem redirect to root
|
|
75
|
-
- traefik.http.middlewares.cybermem-redirect.redirectregex.regex=^https?://[^/]+/cybermem(/.*)?$$
|
|
76
|
-
- traefik.http.middlewares.cybermem-redirect.redirectregex.replacement=/$${1}
|
|
77
|
-
- traefik.http.middlewares.cybermem-redirect.redirectregex.permanent=false
|
|
78
|
-
- traefik.http.routers.cybermem-legacy.rule=PathPrefix(`/cybermem`)
|
|
79
|
-
- traefik.http.routers.cybermem-legacy.entrypoints=web
|
|
80
|
-
- traefik.http.routers.cybermem-legacy.middlewares=cybermem-redirect
|
|
81
|
-
- traefik.http.routers.cybermem-legacy.priority=50
|
|
82
|
-
|
|
83
|
-
# Auth sidecar for JWT/API key validation (ForwardAuth)
|
|
84
90
|
auth-sidecar:
|
|
91
|
+
build:
|
|
92
|
+
context: ./auth-sidecar
|
|
93
|
+
dockerfile: Dockerfile
|
|
85
94
|
image: ghcr.io/mikhailkogan17/cybermem-auth-sidecar:latest
|
|
86
|
-
container_name
|
|
95
|
+
# container_name removed for simultaneity
|
|
87
96
|
environment:
|
|
88
97
|
PORT: "3001"
|
|
89
98
|
OM_DB_PATH: /data/openmemory.sqlite
|
|
90
|
-
|
|
99
|
+
CYBERMEM_ENV: ${CYBERMEM_ENV:-prod}
|
|
100
|
+
CYBERMEM_INSTANCE: ${CYBERMEM_INSTANCE:-local}
|
|
101
|
+
CYBERMEM_TAILSCALE: ${CYBERMEM_TAILSCALE:-false}
|
|
91
102
|
volumes:
|
|
92
103
|
- ${CYBERMEM_ENV_PATH:-${HOME}/.cybermem/.env}:/.env:ro
|
|
93
|
-
- ${HOME}/.cybermem/data:/data
|
|
104
|
+
- ${DATA_DIR:-${HOME}/.cybermem/data}:/data
|
|
105
|
+
- ${SECRETS_DIR:-./secrets}/om_api_key:/run/secrets/om_api_key:ro
|
|
94
106
|
labels:
|
|
95
107
|
- traefik.enable=true
|
|
96
108
|
healthcheck:
|
|
@@ -107,27 +119,29 @@ services:
|
|
|
107
119
|
timeout: 5s
|
|
108
120
|
retries: 3
|
|
109
121
|
restart: unless-stopped
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
# Uses embedded SQLite stored at ~/.cybermem/data/openmemory.sqlite
|
|
122
|
+
# secrets:
|
|
123
|
+
# - om_api_key
|
|
113
124
|
|
|
114
125
|
db-exporter:
|
|
126
|
+
build:
|
|
127
|
+
context: ./monitoring/db_exporter
|
|
128
|
+
dockerfile: Dockerfile
|
|
115
129
|
image: ghcr.io/mikhailkogan17/cybermem-db_exporter:latest
|
|
116
|
-
container_name
|
|
130
|
+
# container_name removed for simultaneity
|
|
117
131
|
environment:
|
|
118
132
|
DB_PATH: /data/openmemory.sqlite
|
|
119
133
|
SCRAPE_INTERVAL: "15"
|
|
120
134
|
EXPORTER_PORT: "8000"
|
|
121
|
-
ports:
|
|
122
|
-
- "8000:8000"
|
|
123
135
|
volumes:
|
|
124
|
-
|
|
125
|
-
- ${HOME}/.cybermem/data:/data
|
|
136
|
+
- ${DATA_DIR:-${HOME}/.cybermem/data}:/data
|
|
126
137
|
restart: unless-stopped
|
|
127
138
|
|
|
128
139
|
log-exporter:
|
|
140
|
+
build:
|
|
141
|
+
context: ./monitoring/log_exporter
|
|
142
|
+
dockerfile: Dockerfile
|
|
129
143
|
image: ghcr.io/mikhailkogan17/cybermem-log_exporter:latest
|
|
130
|
-
container_name
|
|
144
|
+
# container_name removed for simultaneity
|
|
131
145
|
environment:
|
|
132
146
|
LOG_FILE: /var/log/traefik/access.log
|
|
133
147
|
SCRAPE_INTERVAL: "5"
|
|
@@ -135,7 +149,7 @@ services:
|
|
|
135
149
|
DB_PATH: /data/openmemory.sqlite
|
|
136
150
|
volumes:
|
|
137
151
|
- traefik-logs:/var/log/traefik:ro
|
|
138
|
-
- ${HOME}/.cybermem/data:/data
|
|
152
|
+
- ${DATA_DIR:-${HOME}/.cybermem/data}:/data
|
|
139
153
|
- ./monitoring/log_exporter/exporter.py:/app/exporter.py:ro
|
|
140
154
|
restart: unless-stopped
|
|
141
155
|
depends_on:
|
|
@@ -143,7 +157,7 @@ services:
|
|
|
143
157
|
|
|
144
158
|
postgres:
|
|
145
159
|
image: postgres:15-alpine
|
|
146
|
-
container_name
|
|
160
|
+
# container_name removed for simultaneity
|
|
147
161
|
environment:
|
|
148
162
|
POSTGRES_DB: ${PG_DB:-openmemory}
|
|
149
163
|
POSTGRES_USER: ${PG_USER:-openmemory}
|
|
@@ -163,7 +177,7 @@ services:
|
|
|
163
177
|
|
|
164
178
|
ollama:
|
|
165
179
|
image: ollama/ollama:latest
|
|
166
|
-
container_name
|
|
180
|
+
# container_name removed for simultaneity
|
|
167
181
|
ports:
|
|
168
182
|
- "11434:11434"
|
|
169
183
|
volumes:
|
|
@@ -173,49 +187,60 @@ services:
|
|
|
173
187
|
- ollama
|
|
174
188
|
|
|
175
189
|
dashboard:
|
|
190
|
+
build:
|
|
191
|
+
context: ../../dashboard
|
|
192
|
+
dockerfile: Dockerfile
|
|
176
193
|
image: ghcr.io/mikhailkogan17/cybermem-dashboard:latest
|
|
177
|
-
#
|
|
178
|
-
|
|
194
|
+
# container_name removed for simultaneity
|
|
195
|
+
# ports:
|
|
196
|
+
# - "${DASHBOARD_PORT:-3000}:3000"
|
|
179
197
|
environment:
|
|
180
198
|
DB_EXPORTER_URL: http://db-exporter:8000
|
|
181
|
-
|
|
182
|
-
CYBERMEM_URL: http://mcp-server:8080
|
|
199
|
+
INTERNAL_MCP_URL: http://mcp-server:8080
|
|
183
200
|
OM_DB_PATH: /data/openmemory.sqlite
|
|
184
|
-
OM_API_KEY: ${OM_API_KEY:-dev-secret-key}
|
|
185
|
-
# Tailscale domain for remote config (optional, auto-detected if not set)
|
|
186
201
|
TAILSCALE_DOMAIN: ${TAILSCALE_DOMAIN:-}
|
|
187
|
-
|
|
188
|
-
|
|
202
|
+
CYBERMEM_ENV: ${CYBERMEM_ENV:-prod}
|
|
203
|
+
CYBERMEM_INSTANCE: ${CYBERMEM_INSTANCE:-local}
|
|
204
|
+
CYBERMEM_TAILSCALE: ${CYBERMEM_TAILSCALE:-false}
|
|
189
205
|
volumes:
|
|
190
|
-
- ${HOME}/.cybermem/data:/data
|
|
206
|
+
- ${DATA_DIR:-${HOME}/.cybermem/data}:/data
|
|
191
207
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
192
208
|
- ${CYBERMEM_ENV_PATH:-${HOME}/.cybermem/.env}:/app/shared.env
|
|
193
209
|
labels:
|
|
194
210
|
- traefik.enable=true
|
|
195
|
-
|
|
196
|
-
- traefik.http.routers
|
|
197
|
-
- traefik.http.routers
|
|
198
|
-
- traefik.http.routers.dashboard
|
|
199
|
-
- traefik.http.routers
|
|
200
|
-
- traefik.http.
|
|
211
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-dashboard-public.rule=PathPrefix(`/auth`) || PathPrefix(`/_next`) || PathPrefix(`/static`) || PathPrefix(`/api/auth`)
|
|
212
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-dashboard-public.entrypoints=web
|
|
213
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-dashboard-public.priority=120
|
|
214
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-dashboard-public.service=${PROJECT_NAME:-cybermem}-dashboard
|
|
215
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-dashboard.rule=PathPrefix(`/`)
|
|
216
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-dashboard.entrypoints=web
|
|
217
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-dashboard.priority=1
|
|
218
|
+
- traefik.http.routers.${PROJECT_NAME:-cybermem}-dashboard.middlewares=auth-check
|
|
219
|
+
- traefik.http.services.${PROJECT_NAME:-cybermem}-dashboard.loadbalancer.server.port=3000
|
|
201
220
|
restart: unless-stopped
|
|
221
|
+
# secrets:
|
|
222
|
+
# - om_api_key
|
|
202
223
|
depends_on:
|
|
203
224
|
- db-exporter
|
|
204
225
|
|
|
205
226
|
volumes:
|
|
206
227
|
openmemory-data:
|
|
207
|
-
name: cybermem-data
|
|
228
|
+
name: ${PROJECT_NAME:-cybermem}-data
|
|
208
229
|
driver: local
|
|
209
230
|
postgres-data:
|
|
210
|
-
name: cybermem-postgres-data
|
|
231
|
+
name: ${PROJECT_NAME:-cybermem}-postgres-data
|
|
211
232
|
driver: local
|
|
212
233
|
ollama-models:
|
|
213
|
-
name: cybermem-ollama-models
|
|
234
|
+
name: ${PROJECT_NAME:-cybermem}-ollama-models
|
|
214
235
|
driver: local
|
|
215
236
|
traefik-logs:
|
|
216
|
-
name: cybermem-traefik-logs
|
|
237
|
+
name: ${PROJECT_NAME:-cybermem}-traefik-logs
|
|
217
238
|
driver: local
|
|
218
239
|
|
|
240
|
+
# secrets:
|
|
241
|
+
# om_api_key:
|
|
242
|
+
# file: ${SECRETS_DIR:-./secrets}/om_api_key
|
|
243
|
+
|
|
219
244
|
networks:
|
|
220
245
|
default:
|
|
221
|
-
name: cybermem-network
|
|
246
|
+
name: ${PROJECT_NAME:-cybermem}-network
|
|
@@ -190,20 +190,13 @@ def parse_and_export():
|
|
|
190
190
|
status = str(data.get("DownstreamStatus", 0))
|
|
191
191
|
|
|
192
192
|
# Extract MCP client info from custom headers
|
|
193
|
-
client_name = data.get("request_X-Client-Name", "unknown")
|
|
193
|
+
client_name = data.get("request_X-Client-Name", "unknown").lower()
|
|
194
194
|
client_version = data.get("request_X-Client-Version", "unknown")
|
|
195
195
|
|
|
196
|
-
# Fallback
|
|
196
|
+
# Fallback invalid
|
|
197
197
|
if client_name == "unknown":
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
# Simple heuristic: take the first part before '/' or space
|
|
201
|
-
# e.g. "curl/7.64.1" -> "curl", "Mozilla/5.0" -> "Mozilla"
|
|
202
|
-
parts = ua.split("/")
|
|
203
|
-
if len(parts) > 0:
|
|
204
|
-
potential_name = parts[0].split(" ")[0].strip()
|
|
205
|
-
if potential_name:
|
|
206
|
-
client_name = potential_name
|
|
198
|
+
# STRICT mode: Do NOT fallback to User-Agent
|
|
199
|
+
pass
|
|
207
200
|
|
|
208
201
|
# Remove query params first
|
|
209
202
|
endpoint = path.split("?")[0]
|
|
@@ -234,29 +227,29 @@ def parse_and_export():
|
|
|
234
227
|
):
|
|
235
228
|
endpoint = "/memory/:id"
|
|
236
229
|
|
|
237
|
-
# Only track requests to OpenMemory API (/memory/* and /mcp endpoints)
|
|
238
230
|
# Exclude /health checks - they pollute Top/Last Reader metrics
|
|
239
231
|
if endpoint.startswith("/memory") or endpoint.startswith("/mcp"):
|
|
240
232
|
# Check if it's an error (4xx or 5xx)
|
|
241
233
|
is_error = status.startswith("4") or status.startswith("5")
|
|
242
234
|
|
|
243
|
-
# Write aggregate stats
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
235
|
+
# Write aggregate stats AND audit log ONLY for known clients
|
|
236
|
+
if client_name != "unknown" and "health" not in endpoint:
|
|
237
|
+
increment_stat(client_name, operation, is_error)
|
|
238
|
+
|
|
239
|
+
# Log individual request to access_log
|
|
240
|
+
log_access(
|
|
241
|
+
client_name,
|
|
242
|
+
client_version,
|
|
243
|
+
method,
|
|
244
|
+
endpoint,
|
|
245
|
+
operation,
|
|
246
|
+
status,
|
|
247
|
+
is_error,
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
print(
|
|
251
|
+
f"[{time.strftime('%H:%M:%S')}] {client_name}/{client_version} {method} {endpoint} ({operation}) -> {status}"
|
|
252
|
+
)
|
|
260
253
|
|
|
261
254
|
except json.JSONDecodeError:
|
|
262
255
|
# Skip invalid JSON lines
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cybermem/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.3",
|
|
4
4
|
"description": "CyberMem — Universal Long-Term Memory for AI Agents",
|
|
5
5
|
"homepage": "https://cybermem.dev",
|
|
6
6
|
"repository": {
|
|
@@ -16,10 +16,15 @@
|
|
|
16
16
|
"templates"
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "tsc && cp -r templates dist/",
|
|
19
|
+
"build": "mkdir -p dist && tsc && cp -r templates dist/",
|
|
20
20
|
"lint": "eslint src/ --ext .ts",
|
|
21
21
|
"start": "ts-node src/index.ts",
|
|
22
|
-
"test:e2e": "
|
|
22
|
+
"test:e2e": "playwright test",
|
|
23
|
+
"test:e2e:mcp": "npm run test:e2e -w packages/mcp",
|
|
24
|
+
"test:e2e:dashboard": "npm run test:e2e -w packages/dashboard",
|
|
25
|
+
"test:e2e:dashboard:api": "npm run test:e2e -w packages/dashboard -- --project=api",
|
|
26
|
+
"test:e2e:dashboard:ui": "npm run test:e2e -w packages/dashboard -- --project=ui",
|
|
27
|
+
"test:e2e:cli": "playwright test --project=integration",
|
|
23
28
|
"prepublishOnly": "npm run build"
|
|
24
29
|
},
|
|
25
30
|
"keywords": [
|
|
@@ -51,6 +56,7 @@
|
|
|
51
56
|
"@typescript-eslint/parser": "^8.52.0",
|
|
52
57
|
"eslint": "^9.39.2",
|
|
53
58
|
"ts-node": "^10.9.1",
|
|
59
|
+
"@playwright/test": "^1.57.0",
|
|
54
60
|
"typescript": "^5.0.0"
|
|
55
61
|
}
|
|
56
62
|
}
|