@pleri/olam-cli 0.1.160 → 0.1.162

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +11 -0
  2. package/dist/agent-stream/agent-sdk-to-chunks.js +20 -2
  3. package/dist/commands/bootstrap.d.ts +15 -0
  4. package/dist/commands/bootstrap.d.ts.map +1 -1
  5. package/dist/commands/bootstrap.js +58 -5
  6. package/dist/commands/bootstrap.js.map +1 -1
  7. package/dist/commands/flywheel/migrate-overlays.d.ts +1 -0
  8. package/dist/commands/flywheel/migrate-overlays.d.ts.map +1 -1
  9. package/dist/commands/flywheel/migrate-overlays.js +29 -3
  10. package/dist/commands/flywheel/migrate-overlays.js.map +1 -1
  11. package/dist/commands/skills-source.d.ts.map +1 -1
  12. package/dist/commands/skills-source.js +57 -2
  13. package/dist/commands/skills-source.js.map +1 -1
  14. package/dist/commands/skills.d.ts.map +1 -1
  15. package/dist/commands/skills.js +14 -0
  16. package/dist/commands/skills.js.map +1 -1
  17. package/dist/image-digests.json +7 -7
  18. package/dist/index.js +2424 -1781
  19. package/dist/lib/bootstrap-kubernetes.d.ts +42 -0
  20. package/dist/lib/bootstrap-kubernetes.d.ts.map +1 -0
  21. package/dist/lib/bootstrap-kubernetes.js +367 -0
  22. package/dist/lib/bootstrap-kubernetes.js.map +1 -0
  23. package/dist/lib/config.d.ts.map +1 -1
  24. package/dist/lib/config.js +6 -1
  25. package/dist/lib/config.js.map +1 -1
  26. package/dist/mcp-server.js +568 -368
  27. package/hermes-bundle/version.json +1 -1
  28. package/host-cp/k8s/manifests/50-deployment.yaml +1 -1
  29. package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
  30. package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
  31. package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
  32. package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +1 -1
  33. package/host-cp/observability/grafana-port-forward.sh +283 -0
  34. package/host-cp/observability/kyverno-cardinality-mutate.sh +462 -0
  35. package/host-cp/observability/loki-ingest.sh +253 -0
  36. package/host-cp/observability/prom-no-double-grafana.sh +311 -0
  37. package/host-cp/peripheral-services/helm-values/grafana-values.yaml +159 -0
  38. package/host-cp/peripheral-services/helm-values/kube-prom-stack-values.yaml +229 -0
  39. package/host-cp/peripheral-services/helm-values/kyverno-values.yaml +85 -0
  40. package/host-cp/peripheral-services/helm-values/loki-values.yaml +166 -0
  41. package/host-cp/peripheral-services/helm-values/promtail-staging.yaml +92 -0
  42. package/host-cp/peripheral-services/helm-values/promtail-values.yaml +102 -0
  43. package/host-cp/peripheral-services/helm-values/traefik-values.yaml +73 -0
  44. package/host-cp/peripheral-services/manifests/20-namespace.yaml +6 -0
  45. package/host-cp/peripheral-services/manifests/24-deploy-kg-service.yaml +245 -0
  46. package/host-cp/peripheral-services/manifests/30-traefik-ingressroute-host-cp.yaml +22 -0
  47. package/host-cp/peripheral-services/manifests/40-traefik-ingressroute-kg.yaml +29 -0
  48. package/host-cp/peripheral-services/manifests/50-traefik-ingressroute-agent-memory.yaml +29 -0
  49. package/host-cp/peripheral-services/manifests/60-networkpolicy-ingress.yaml +80 -0
  50. package/host-cp/peripheral-services/manifests/65-networkpolicy-loki-prom-deny.yaml +67 -0
  51. package/host-cp/peripheral-services/manifests/80-grafana-dashboard-configmap.yaml +1349 -0
  52. package/host-cp/peripheral-services/manifests/90-prom-alert-cardinality.yaml +50 -0
  53. package/host-cp/peripheral-services/manifests/91-servicemonitor-host-cp.yaml +70 -0
  54. package/host-cp/peripheral-services/manifests/92-servicemonitor-kg-service.yaml +70 -0
  55. package/host-cp/peripheral-services/manifests/93-servicemonitor-memory-service.yaml +87 -0
  56. package/host-cp/peripheral-services/manifests/95-prom-recording-rules.yaml +108 -0
  57. package/host-cp/peripheral-services/manifests/96-kyverno-cardinality-mutate.yaml +195 -0
  58. package/host-cp/src/plan-chat-service.mjs +147 -1
  59. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
1
  {
2
- "bundledAt": "2026-05-22T05:49:33.599Z",
2
+ "bundledAt": "2026-05-22T10:22:35.652Z",
3
3
  "kgFirstSha": "29a9ccce1b115d049e375c4a90eb5cf7c123e610e2d0590270a4db2cdbc64a28"
4
4
  }
@@ -111,7 +111,7 @@ spec:
111
111
  # k3d), started by `olam upgrade` Step 0.7 — not inside this Pod.
112
112
  containers:
113
113
  - name: olam-host-cp
114
- image: ghcr.io/pleri/olam-host-cp@sha256:3bf4a89af3544e382bf2d708ff73baa6704cf91a0b509f8b1a153fbe603a4223
114
+ image: ghcr.io/pleri/olam-host-cp@sha256:dbb84fdfd63e7a928f166f4b65ae681cef7c6eb79cedf70cdba865b3151dfb71
115
115
  imagePullPolicy: IfNotPresent
116
116
  securityContext:
117
117
  runAsNonRoot: true
@@ -70,7 +70,7 @@ spec:
70
70
  mountPath: /data
71
71
  containers:
72
72
  - name: olam-auth-service
73
- image: ghcr.io/pleri/olam-auth@sha256:a7b1e4c0ddee4fc6bfb2689c4d23d8bc0fcc95bc7b42a28d977b990f1408505b
73
+ image: ghcr.io/pleri/olam-auth@sha256:13a4a2dd2993fa597fd29a739a87771502f687cf9729aaaf52c85d9ff3b4b0ae
74
74
  imagePullPolicy: IfNotPresent
75
75
  securityContext:
76
76
  runAsNonRoot: true
@@ -61,7 +61,7 @@ spec:
61
61
  mountPath: /data
62
62
  containers:
63
63
  - name: olam-kg-service
64
- image: ghcr.io/pleri/olam-kg-service@sha256:72fdfb96981903cd83d0b6ad997985bad86a7892c0d1ec7c5dcc9b4d9f8f44db
64
+ image: ghcr.io/pleri/olam-kg-service@sha256:66cde72b67bb2bcfffb1a344d7d57769e5ec292bad1493596c166b053b4c7b0e
65
65
  imagePullPolicy: IfNotPresent
66
66
  securityContext:
67
67
  runAsNonRoot: true
@@ -68,7 +68,7 @@ spec:
68
68
  mountPath: /data
69
69
  containers:
70
70
  - name: olam-mcp-auth-service
71
- image: ghcr.io/pleri/olam-mcp-auth@sha256:d8fb62e437142bf352e0d6f637c2b912baa592f25f4abbac1acc2c8cced976c2
71
+ image: ghcr.io/pleri/olam-mcp-auth@sha256:8304039ed42843fb9da63690e603a03b7ab16592d73761fb8eb15cc6196543ce
72
72
  imagePullPolicy: IfNotPresent
73
73
  securityContext:
74
74
  runAsNonRoot: true
@@ -70,7 +70,7 @@ spec:
70
70
  # bootstrap-placeholder comment + run `npm run refresh:manifest-digests`
71
71
  # once ghcr.io/pleri/olam-memory-service has a real published digest.
72
72
  # bootstrap-placeholder: pre-publish; refresh after first release
73
- image: ghcr.io/pleri/olam-memory-service@sha256:bc377f94911baff74f7b91c44ea471580fdfdc1947e757dd6f550675084312d6
73
+ image: ghcr.io/pleri/olam-memory-service@sha256:f0f7d975d23895e136327e7b593bb16acda5e24183d4455b15c6404de7caab42
74
74
  imagePullPolicy: IfNotPresent
75
75
  securityContext:
76
76
  runAsNonRoot: true
@@ -0,0 +1,283 @@
1
+ #!/usr/bin/env bash
2
+ # grafana-port-forward.sh — e2e smoke test: Grafana installs via Helm,
3
+ # port-forward is accessible, Loki datasource
4
+ # is pre-wired and reachable.
5
+ #
6
+ # Usage: scripts/e2e/grafana-port-forward.sh
7
+ #
8
+ # Pre-conditions:
9
+ # - kubectl context is set to a live k8s cluster (does NOT spin up k3d)
10
+ # - helm binary available
11
+ # - jq binary available
12
+ # - grafana Helm repo added (helm repo add grafana https://grafana.github.io/helm-charts)
13
+ # - Loki is already installed (scripts/e2e/loki-ingest.sh ran successfully
14
+ # OR `helm status olam-loki -n monitoring` is healthy)
15
+ #
16
+ # Idempotency: `helm upgrade --install` is idempotent; re-runs succeed on an
17
+ # existing cluster. The Secret is applied via --dry-run | kubectl apply
18
+ # so re-runs update the password (useful for rotation testing).
19
+ # The olam-dashboards ConfigMap is applied before helm install so
20
+ # Grafana's volume mount finds the ConfigMap on first boot.
21
+ #
22
+ # Cleanup: port-forward is killed on exit; Helm release is left in place so
23
+ # downstream tasks can reuse the same cluster.
24
+ #
25
+ # Refs: docs/plans/k3s-ingress-observability/phase-b-tasks.md — Task B2, B3
26
+ # Chart: grafana/grafana 8.5.2 (pinned; latest stable 2026-05-20)
27
+
28
+ set -euo pipefail
29
+
30
+ NAMESPACE="monitoring"
31
+ GRAFANA_RELEASE="olam-grafana"
32
+ GRAFANA_CHART_VERSION="8.5.2"
33
+ LOCAL_PORT="3000"
34
+ GRAFANA_SVC_PORT="80"
35
+ PF_BIND_SECONDS=5
36
+
37
+ log() { printf '[grafana-port-forward] %s\n' "$*" >&2; }
38
+ fail() { printf '[grafana-port-forward] FAIL: %s\n' "$*" >&2; exit 1; }
39
+
40
+ # -------------------------------------------------------------------------
41
+ # Cleanup trap — kill port-forward on exit; leave Helm release in place
42
+ # -------------------------------------------------------------------------
43
+ PF_PID=""
44
+ cleanup() {
45
+ if [[ -n "$PF_PID" ]] && kill -0 "$PF_PID" 2>/dev/null; then
46
+ kill "$PF_PID" 2>/dev/null || true
47
+ fi
48
+ }
49
+ trap cleanup EXIT
50
+
51
+ # -------------------------------------------------------------------------
52
+ # Pre-flight
53
+ # -------------------------------------------------------------------------
54
+ command -v helm >/dev/null 2>&1 || fail "helm not installed"
55
+ command -v kubectl >/dev/null 2>&1 || fail "kubectl not installed"
56
+ command -v curl >/dev/null 2>&1 || fail "curl not installed"
57
+ command -v openssl >/dev/null 2>&1 || fail "openssl not installed"
58
+ command -v jq >/dev/null 2>&1 || fail "jq not installed (required for B3 dashboard assertion)"
59
+ kubectl cluster-info >/dev/null 2>&1 || fail "kubectl: no reachable cluster; set KUBECONFIG"
60
+
61
+ log "pre-flight checks passed"
62
+
63
+ # -------------------------------------------------------------------------
64
+ # Ensure grafana Helm repo is present (idempotent — safe to re-run)
65
+ # -------------------------------------------------------------------------
66
+ helm repo add grafana https://grafana.github.io/helm-charts 2>/dev/null || true
67
+ helm repo update grafana
68
+
69
+ # Verify Loki is already installed (B2 depends on B1)
70
+ if ! helm status "olam-loki" -n "$NAMESPACE" >/dev/null 2>&1; then
71
+ fail "olam-loki Helm release not found in namespace $NAMESPACE — run scripts/e2e/loki-ingest.sh first"
72
+ fi
73
+ log "Loki pre-condition satisfied (olam-loki release found)"
74
+
75
+ # -------------------------------------------------------------------------
76
+ # Step 1: Resolve admin password (preserve existing on idempotent re-run)
77
+ # -------------------------------------------------------------------------
78
+ # Grafana persists the admin password in its internal SQLite on first
79
+ # deploy. Subsequent helm upgrades do NOT re-read GF_SECURITY_ADMIN_PASSWORD
80
+ # from the env (env value is set once at pod-start and not refreshed). So
81
+ # on a re-run, rotating the Secret leaves the in-Grafana password stale
82
+ # and breaks API auth.
83
+ #
84
+ # Idempotency contract: if the Secret already exists, reuse its current
85
+ # password. The Secret's value matches Grafana's stored value (set in
86
+ # concert on first install). Only generate a new password when the
87
+ # Secret doesn't exist yet — i.e. true first deploy.
88
+ if kubectl get secret olam-grafana-admin -n "$NAMESPACE" >/dev/null 2>&1; then
89
+ log "reusing existing admin password from Secret olam-grafana-admin"
90
+ GRAFANA_ADMIN_PW=$(kubectl get secret olam-grafana-admin -n "$NAMESPACE" \
91
+ -o jsonpath='{.data.admin-password}' | base64 -d)
92
+ else
93
+ log "generating fresh admin password (first deploy)"
94
+ GRAFANA_ADMIN_PW=$(openssl rand -base64 24)
95
+ fi
96
+ export GRAFANA_ADMIN_PW
97
+
98
+ # -------------------------------------------------------------------------
99
+ # Step 2: Create / update the admin Secret idempotently
100
+ # -------------------------------------------------------------------------
101
+ log "applying Secret olam-grafana-admin in namespace $NAMESPACE"
102
+ kubectl create secret generic olam-grafana-admin \
103
+ --from-literal=admin-user=admin \
104
+ --from-literal=admin-password="$GRAFANA_ADMIN_PW" \
105
+ -n "$NAMESPACE" \
106
+ --dry-run=client -o yaml \
107
+ | kubectl apply -f -
108
+
109
+ log "Secret applied"
110
+
111
+ # -------------------------------------------------------------------------
112
+ # Step 3a: Apply olam-dashboards ConfigMap BEFORE helm install
113
+ # so Grafana's volume mount finds it on first boot (B3).
114
+ # The ConfigMap is generated from grafana-dashboards/*.json by
115
+ # packages/peripheral-services/scripts/sync-grafana-dashboards.sh.
116
+ # -------------------------------------------------------------------------
117
+ REPO_ROOT="$(git -C "$(dirname "$0")" rev-parse --show-toplevel 2>/dev/null || pwd)"
118
+ # When invoked from a published @pleri/olam-cli install (no monorepo), `olam
119
+ # setup` exports OLAM_BUNDLE_ROOT=<install>/host-cp so the bundled
120
+ # peripheral-services/{helm-values,manifests} directory is reachable.
121
+ # Monorepo callers leave it unset; the script falls back to the source dir
122
+ # under packages/peripheral-services/.
123
+ if [[ -n "${OLAM_BUNDLE_ROOT:-}" ]]; then
124
+ PERIPHERAL_SERVICES_DIR="$OLAM_BUNDLE_ROOT/peripheral-services"
125
+ else
126
+ PERIPHERAL_SERVICES_DIR="$REPO_ROOT/packages/peripheral-services"
127
+ fi
128
+ CONFIGMAP_MANIFEST="$PERIPHERAL_SERVICES_DIR/manifests/80-grafana-dashboard-configmap.yaml"
129
+
130
+ if [[ -f "$CONFIGMAP_MANIFEST" ]]; then
131
+ log "applying olam-dashboards ConfigMap from $CONFIGMAP_MANIFEST"
132
+ kubectl apply -f "$CONFIGMAP_MANIFEST"
133
+ log "ConfigMap applied"
134
+ else
135
+ log "WARN: $CONFIGMAP_MANIFEST not found — Grafana will warn 'ConfigMap not found' until B3 is deployed"
136
+ fi
137
+
138
+ # -------------------------------------------------------------------------
139
+ # Step 3: Helm upgrade --install
140
+ # -------------------------------------------------------------------------
141
+ log "installing grafana/grafana ($GRAFANA_RELEASE) in namespace $NAMESPACE"
142
+ helm upgrade --install "$GRAFANA_RELEASE" grafana/grafana \
143
+ --version "$GRAFANA_CHART_VERSION" \
144
+ --namespace "$NAMESPACE" \
145
+ --create-namespace \
146
+ -f "$PERIPHERAL_SERVICES_DIR/helm-values/grafana-values.yaml" \
147
+ --wait \
148
+ --timeout 300s
149
+
150
+ log "Grafana Helm install complete"
151
+
152
+ # -------------------------------------------------------------------------
153
+ # Step 4: Wait for Grafana pod Ready
154
+ # -------------------------------------------------------------------------
155
+ log "waiting for Grafana pod Ready (120s)"
156
+ kubectl wait \
157
+ --for=condition=ready pod \
158
+ -l "app.kubernetes.io/name=grafana" \
159
+ -n "$NAMESPACE" \
160
+ --timeout=120s
161
+
162
+ log "Grafana pod Ready"
163
+
164
+ # -------------------------------------------------------------------------
165
+ # Step 5: Start port-forward in background
166
+ # -------------------------------------------------------------------------
167
+ log "port-forwarding svc/$GRAFANA_RELEASE $LOCAL_PORT:$GRAFANA_SVC_PORT in namespace $NAMESPACE"
168
+ kubectl port-forward \
169
+ -n "$NAMESPACE" \
170
+ "svc/$GRAFANA_RELEASE" \
171
+ "${LOCAL_PORT}:${GRAFANA_SVC_PORT}" &
172
+ PF_PID=$!
173
+
174
+ log "port-forward PID $PF_PID; waiting ${PF_BIND_SECONDS}s for bind"
175
+ sleep "$PF_BIND_SECONDS"
176
+
177
+ # Verify the port-forward process is still alive after sleep
178
+ kill -0 "$PF_PID" 2>/dev/null || fail "port-forward process exited prematurely"
179
+
180
+ # -------------------------------------------------------------------------
181
+ # Diagnostic helper — called on assertion failure
182
+ # -------------------------------------------------------------------------
183
+ dump_diagnostics() {
184
+ log "DIAGNOSTIC: last 50 lines of Grafana pod logs:"
185
+ kubectl logs -n "$NAMESPACE" \
186
+ -l "app.kubernetes.io/name=grafana" \
187
+ --tail=50 2>&1 >&2 || true
188
+ }
189
+
190
+ # -------------------------------------------------------------------------
191
+ # Step 6: Assertion 1 — /api/health returns 200 with database: ok
192
+ # -------------------------------------------------------------------------
193
+ log "asserting Grafana health (GET /api/health)"
194
+ HEALTH_RESPONSE=$(
195
+ curl -sf \
196
+ -u "admin:${GRAFANA_ADMIN_PW}" \
197
+ "http://localhost:${LOCAL_PORT}/api/health" \
198
+ || { dump_diagnostics; fail "GET /api/health failed — Grafana not reachable on port $LOCAL_PORT"; }
199
+ )
200
+
201
+ if ! echo "$HEALTH_RESPONSE" | jq -e '.database == "ok"' >/dev/null 2>&1; then
202
+ log "DIAGNOSTIC: /api/health response:"
203
+ echo "$HEALTH_RESPONSE" >&2
204
+ dump_diagnostics
205
+ fail '/api/health returned database != "ok" — Grafana DB layer not healthy'
206
+ fi
207
+
208
+ log "PASS: /api/health → database: ok"
209
+
210
+ # -------------------------------------------------------------------------
211
+ # Step 7: Assertion 2 — /api/datasources includes Loki entry with cluster URL
212
+ # -------------------------------------------------------------------------
213
+ log "asserting Loki datasource pre-wired (GET /api/datasources)"
214
+ DS_RESPONSE=$(
215
+ curl -sf \
216
+ -u "admin:${GRAFANA_ADMIN_PW}" \
217
+ "http://localhost:${LOCAL_PORT}/api/datasources" \
218
+ || { dump_diagnostics; fail "GET /api/datasources failed"; }
219
+ )
220
+
221
+ EXPECTED_URL="olam-loki.monitoring.svc.cluster.local:3100"
222
+
223
+ if ! echo "$DS_RESPONSE" | jq -e 'map(select(.type == "loki")) | length >= 1' >/dev/null 2>&1; then
224
+ log "DIAGNOSTIC: /api/datasources response:"
225
+ echo "$DS_RESPONSE" >&2
226
+ dump_diagnostics
227
+ fail "datasources response contains no 'loki' type entry — datasource not provisioned"
228
+ fi
229
+
230
+ if ! echo "$DS_RESPONSE" | jq -e --arg url "$EXPECTED_URL" 'map(select(.type == "loki" and (.url | contains($url)))) | length >= 1' >/dev/null 2>&1; then
231
+ log "DIAGNOSTIC: /api/datasources response:"
232
+ echo "$DS_RESPONSE" >&2
233
+ dump_diagnostics
234
+ fail "Loki datasource URL does not contain '$EXPECTED_URL' — check grafana-values.yaml datasources block"
235
+ fi
236
+
237
+ log "PASS: Loki datasource found with cluster-local URL $EXPECTED_URL"
238
+
239
+ # -------------------------------------------------------------------------
240
+ # Step 7b: Assertion 2b — dashboard provider loaded olam-home (catches mount-path bugs)
241
+ # -------------------------------------------------------------------------
242
+ log "asserting olam-home dashboard visible in /api/search (catches ConfigMap mount failures)"
243
+ DASHBOARDS=$(
244
+ curl -sf \
245
+ -u "admin:${GRAFANA_ADMIN_PW}" \
246
+ "http://localhost:${LOCAL_PORT}/api/search?type=dash-db&query=olam" \
247
+ || true
248
+ )
249
+
250
+ if ! echo "$DASHBOARDS" | jq -e 'map(select(.uid == "olam-home")) | length == 1' >/dev/null 2>&1; then
251
+ log "DIAGNOSTIC: /api/search response:"
252
+ echo "$DASHBOARDS" >&2
253
+ dump_diagnostics
254
+ fail "olam-home dashboard not found in /api/search — check ConfigMap mount path and dashboard provider config"
255
+ fi
256
+
257
+ log "PASS: olam-home dashboard found via /api/search"
258
+
259
+ # -------------------------------------------------------------------------
260
+ # Step 8: Assertion 3 — olam-home dashboard present (B3)
261
+ # -------------------------------------------------------------------------
262
+ log "asserting olam-home dashboard present (GET /api/dashboards/uid/olam-home)"
263
+ DASHBOARD_RESPONSE=$(
264
+ curl -sf \
265
+ -u "admin:${GRAFANA_ADMIN_PW}" \
266
+ "http://localhost:${LOCAL_PORT}/api/dashboards/uid/olam-home" \
267
+ || { dump_diagnostics; fail "GET /api/dashboards/uid/olam-home failed — dashboard not found or Grafana unreachable"; }
268
+ )
269
+
270
+ if ! echo "$DASHBOARD_RESPONSE" | jq -e '.dashboard.uid == "olam-home"' >/dev/null 2>&1; then
271
+ log "DIAGNOSTIC: /api/dashboards/uid/olam-home response:"
272
+ echo "$DASHBOARD_RESPONSE" >&2
273
+ dump_diagnostics
274
+ fail "olam-home dashboard uid mismatch or missing — check ConfigMap provisioning and Grafana provider config"
275
+ fi
276
+
277
+ log "PASS: olam-home dashboard present with uid=olam-home"
278
+
279
+ # -------------------------------------------------------------------------
280
+ # Final
281
+ # -------------------------------------------------------------------------
282
+ log "PASS: Grafana port-forward accessible; Loki datasource pre-wired; olam-home dashboard provisioned — Tasks B2+B3 verified"
283
+ exit 0