@meridiona/meridian-darwin-arm64 1.23.11 → 1.24.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/VERSION +1 -1
- package/bin/meridian +0 -0
- package/package.json +1 -1
- package/scripts/install-from-bundle.sh +9 -0
- package/scripts/meridian-cli.sh +169 -4
- package/services/pyproject.toml +1 -1
- package/ui.tar.gz +0 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.24.0
|
package/bin/meridian
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meridiona/meridian-darwin-arm64",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
4
4
|
"description": "Prebuilt Meridian app for macOS arm64 (daemon binary + dashboard + Python services). Installed via @meridiona/meridian.",
|
|
5
5
|
"homepage": "https://github.com/Meridiona/meridian",
|
|
6
6
|
"repository": {
|
|
@@ -563,6 +563,15 @@ _final_ui_hash="${_new_ui_hash:-${_OLD_UI_HASH}}"
|
|
|
563
563
|
|
|
564
564
|
ok "all daemons installed"
|
|
565
565
|
|
|
566
|
+
# Pipeline smoke test — verify both LLM stages return valid output (no DB writes).
|
|
567
|
+
echo ""
|
|
568
|
+
info "Running pipeline smoke test (this exercises the model — may take ~30s)…"
|
|
569
|
+
if bash "${APP_ROOT}/scripts/meridian-cli.sh" smoke; then
|
|
570
|
+
ok "pipeline smoke passed — classification and worklog synthesis are working"
|
|
571
|
+
else
|
|
572
|
+
warn "pipeline smoke found issues — run 'meridian doctor' for remedies"
|
|
573
|
+
fi
|
|
574
|
+
|
|
566
575
|
echo ""
|
|
567
576
|
echo "✓ Meridian installed at ${APP_ROOT}"
|
|
568
577
|
echo " meridian status # check the daemons"
|
package/scripts/meridian-cli.sh
CHANGED
|
@@ -43,7 +43,8 @@ Commands:
|
|
|
43
43
|
target: daemon|daemon-error|screenpipe|screenpipe-error|ui|ui-error|mlx-server|mlx-server-error
|
|
44
44
|
-f Follow (stream)
|
|
45
45
|
-n N Last N lines (default 100)
|
|
46
|
-
doctor Run environment health checks
|
|
46
|
+
doctor Run environment health checks (includes pipeline smoke)
|
|
47
|
+
smoke Dry-run both LLM pipeline stages — no DB writes
|
|
47
48
|
worklog-status Show today's PM worklogs (done/pending/drafted/posted + comments)
|
|
48
49
|
[--day YYYY-MM-DD]
|
|
49
50
|
config edit Open the repo-root .env in $EDITOR
|
|
@@ -227,26 +228,34 @@ _daemon_bin() {
|
|
|
227
228
|
}
|
|
228
229
|
|
|
229
230
|
cmd_doctor() {
|
|
230
|
-
local bin
|
|
231
|
+
local bin rc=0
|
|
231
232
|
if bin="$(_daemon_bin)"; then
|
|
232
233
|
set +e
|
|
233
234
|
if [[ "$*" == *--fix* ]]; then
|
|
234
235
|
# --fix has interactive guided prompts — the user is present, so run
|
|
235
236
|
# without the alarm (which would kill a prompt waiting for input).
|
|
236
237
|
"$bin" doctor "$@"
|
|
238
|
+
rc=$?
|
|
237
239
|
else
|
|
238
240
|
# Guard with a perl alarm so a stale binary (one that predates
|
|
239
241
|
# `doctor` and would fall through to starting the daemon) can never
|
|
240
242
|
# hang the terminal. The Rust report colourises itself on a tty.
|
|
241
243
|
perl -e 'alarm shift @ARGV; exec @ARGV' 30 "$bin" doctor "$@"
|
|
244
|
+
rc=$?
|
|
242
245
|
fi
|
|
243
|
-
local rc=$?
|
|
244
246
|
set -e
|
|
245
247
|
# 0 = healthy, 1 = critical issues found — both are real doctor runs.
|
|
246
|
-
if [[ $rc -eq 0 || $rc -eq 1 ]]; then
|
|
248
|
+
if [[ $rc -eq 0 || $rc -eq 1 ]]; then
|
|
249
|
+
# Append classification smoke (fast path, ~30s max). Failures are
|
|
250
|
+
# informational — they don't override the doctor exit code, since the
|
|
251
|
+
# doctor already surfaces the MLX health state.
|
|
252
|
+
cmd_smoke --classify-only || true
|
|
253
|
+
return $rc
|
|
254
|
+
fi
|
|
247
255
|
warn "health engine timed out or is stale — rebuild: cargo build --release"
|
|
248
256
|
fi
|
|
249
257
|
_doctor_fallback
|
|
258
|
+
cmd_smoke --classify-only || true
|
|
250
259
|
}
|
|
251
260
|
|
|
252
261
|
# Minimal bash-only checks for when the daemon binary is unavailable.
|
|
@@ -270,6 +279,161 @@ _doctor_fallback() {
|
|
|
270
279
|
[[ $DOCTOR_FAILURES -eq 0 ]]
|
|
271
280
|
}
|
|
272
281
|
|
|
282
|
+
# --- smoke (pipeline dry run) ---
|
|
283
|
+
# Sends synthetic requests (no DB writes) to both LLM stages:
|
|
284
|
+
# --classify-only fast path (~30s max) called automatically from cmd_doctor
|
|
285
|
+
# (no flag) full run: classification + worklog synthesis
|
|
286
|
+
|
|
287
|
+
_smoke_read_env() {
|
|
288
|
+
local key="$1" env_file="${REPO_ROOT}/.env"
|
|
289
|
+
[[ -f "$env_file" ]] || return 0
|
|
290
|
+
grep -E "^${key}=" "$env_file" 2>/dev/null | tail -1 | cut -d= -f2- || true
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
_smoke_row() { # glyph ansi-color label detail
|
|
294
|
+
local glyph="$1" color="$2" label="$3" detail="${4:-}"
|
|
295
|
+
if [[ -t 1 ]]; then
|
|
296
|
+
printf " \033[%sm%s\033[0m %-26s \033[2m%s\033[0m\n" "$color" "$glyph" "$label" "$detail"
|
|
297
|
+
else
|
|
298
|
+
printf " %s %-26s %s\n" "$glyph" "$label" "$detail"
|
|
299
|
+
fi
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
_smoke_remedy() {
|
|
303
|
+
local msg="$1"
|
|
304
|
+
if [[ -t 1 ]]; then printf " \033[2m→ %s\033[0m\n" "$msg"
|
|
305
|
+
else printf " → %s\n" "$msg"; fi
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
cmd_smoke() {
|
|
309
|
+
local classify_only=0
|
|
310
|
+
[[ "${1:-}" == "--classify-only" ]] && classify_only=1
|
|
311
|
+
|
|
312
|
+
local mlx_port
|
|
313
|
+
mlx_port="$(_smoke_read_env MLX_SERVER_PORT)"
|
|
314
|
+
mlx_port="${mlx_port:-7823}"
|
|
315
|
+
local base="http://127.0.0.1:${mlx_port}"
|
|
316
|
+
local classify_timeout=60
|
|
317
|
+
[[ $classify_only -eq 1 ]] && classify_timeout=30
|
|
318
|
+
local all_ok=1
|
|
319
|
+
|
|
320
|
+
if [[ -t 1 ]]; then
|
|
321
|
+
printf "\n \033[36m▸ smoke (pipeline dry run)\033[0m\n"
|
|
322
|
+
printf " \033[2m%s\033[0m\n" "════════════════════════════════════════════════════════"
|
|
323
|
+
else
|
|
324
|
+
printf "\n ▸ smoke (pipeline dry run)\n"
|
|
325
|
+
printf " %s\n" "════════════════════════════════════════════════════════"
|
|
326
|
+
fi
|
|
327
|
+
|
|
328
|
+
# Quick reachability probe — if the server isn't up, nothing else can run.
|
|
329
|
+
local reach_ok=0
|
|
330
|
+
set +e
|
|
331
|
+
curl -sf --max-time 5 "${base}/health" >/dev/null 2>&1 && reach_ok=1
|
|
332
|
+
set -e
|
|
333
|
+
if [[ $reach_ok -eq 0 ]]; then
|
|
334
|
+
_smoke_row "✗" "31" "mlx reachable" "server not responding at ${base}"
|
|
335
|
+
_smoke_remedy "meridian start (or: meridian logs mlx-server)"
|
|
336
|
+
echo ""
|
|
337
|
+
return 1
|
|
338
|
+
fi
|
|
339
|
+
|
|
340
|
+
# Stage 1: classification smoke.
|
|
341
|
+
# POST /classify takes {"input":"..."} — pure model inference, zero DB access.
|
|
342
|
+
local t0 classify_resp classify_ok=0
|
|
343
|
+
t0=$SECONDS
|
|
344
|
+
set +e
|
|
345
|
+
classify_resp="$(curl -sf --max-time "${classify_timeout}" \
|
|
346
|
+
-X POST "${base}/classify" \
|
|
347
|
+
-H "Content-Type: application/json" \
|
|
348
|
+
-d '{"input":"App: Xcode\nWindow: ContentView.swift — MyApp\nOCR: func body: some View { Text(\"Hello World\") }\nDuration: 600s"}' \
|
|
349
|
+
2>/dev/null)"
|
|
350
|
+
local classify_curl_rc=$?
|
|
351
|
+
set -e
|
|
352
|
+
local classify_elapsed=$(( SECONDS - t0 ))
|
|
353
|
+
|
|
354
|
+
if [[ $classify_curl_rc -ne 0 || -z "$classify_resp" ]]; then
|
|
355
|
+
_smoke_row "✗" "31" "classification" "no response from /classify (timeout or error)"
|
|
356
|
+
_smoke_remedy "check: meridian logs mlx-server"
|
|
357
|
+
all_ok=0
|
|
358
|
+
else
|
|
359
|
+
local stype conf
|
|
360
|
+
stype="$(printf '%s' "$classify_resp" | grep -o '"session_type":"[^"]*"' | cut -d'"' -f4)" || stype=""
|
|
361
|
+
conf="$(printf '%s' "$classify_resp" | grep -o '"confidence":[0-9.]*' | cut -d: -f2)" || conf="?"
|
|
362
|
+
if [[ -n "$stype" ]]; then
|
|
363
|
+
_smoke_row "✓" "32" "classification" "${classify_elapsed}s session_type=${stype} conf=${conf}"
|
|
364
|
+
classify_ok=1
|
|
365
|
+
else
|
|
366
|
+
_smoke_row "✗" "31" "classification" "response did not parse — got: ${classify_resp:0:80}"
|
|
367
|
+
_smoke_remedy "restart MLX server: meridian dev mlx (or: meridian restart)"
|
|
368
|
+
all_ok=0
|
|
369
|
+
fi
|
|
370
|
+
fi
|
|
371
|
+
|
|
372
|
+
# Fast path (called from cmd_doctor): stop here.
|
|
373
|
+
if [[ $classify_only -eq 1 ]]; then
|
|
374
|
+
echo ""
|
|
375
|
+
[[ $classify_ok -eq 1 ]]
|
|
376
|
+
return
|
|
377
|
+
fi
|
|
378
|
+
|
|
379
|
+
# Stage 2: worklog synthesis smoke.
|
|
380
|
+
# POST /synthesise_worklog with a synthetic bundle — the agno agent runs the model
|
|
381
|
+
# and returns a JiraUpdate. Nothing is written to the DB; Rust never sees this call.
|
|
382
|
+
local jira_url jira_token linear_key github_token has_pm=0
|
|
383
|
+
jira_url="$(_smoke_read_env JIRA_BASE_URL)"
|
|
384
|
+
[[ -z "$jira_url" ]] && jira_url="$(_smoke_read_env JIRA_URL)"
|
|
385
|
+
jira_token="$(_smoke_read_env JIRA_API_TOKEN)"
|
|
386
|
+
linear_key="$(_smoke_read_env LINEAR_API_KEY)"
|
|
387
|
+
github_token="$(_smoke_read_env GITHUB_TOKEN)"
|
|
388
|
+
[[ -n "$jira_url" && -n "$jira_token" ]] && has_pm=1
|
|
389
|
+
[[ -n "$linear_key" ]] && has_pm=1
|
|
390
|
+
[[ -n "$github_token" ]] && has_pm=1
|
|
391
|
+
|
|
392
|
+
if [[ $has_pm -eq 0 ]]; then
|
|
393
|
+
_smoke_row "·" "2" "worklog synthesis" "skipped — no PM credentials in .env"
|
|
394
|
+
echo ""
|
|
395
|
+
[[ $all_ok -eq 1 ]]
|
|
396
|
+
return
|
|
397
|
+
fi
|
|
398
|
+
|
|
399
|
+
# Dates are fixed to 2024-01-01 so the output is obviously synthetic.
|
|
400
|
+
local synth_bundle
|
|
401
|
+
synth_bundle='{"bundle":{"task_key":"SMOKE-1","window_start":"2024-01-01T09:00:00","window_end":"2024-01-01T09:30:00","cycle_index":0,"sessions":[{"id":1,"app_name":"Xcode","started_at":"2024-01-01T09:00:00","ended_at":"2024-01-01T09:30:00","duration_s":1800,"idle_frame_s":0,"top_titles":["ContentView.swift — MyApp"],"excerpt":"Implementing SwiftUI body layout. func body: some View { Text(\"Hello World\") }","category":"coding"}],"total_seconds":1800,"real_seconds":1800,"pm_task_title":"Implement ContentView layout"}}'
|
|
402
|
+
|
|
403
|
+
local t1 synth_resp synth_ok=0
|
|
404
|
+
t1=$SECONDS
|
|
405
|
+
set +e
|
|
406
|
+
synth_resp="$(curl -sf --max-time 120 \
|
|
407
|
+
-X POST "${base}/synthesise_worklog" \
|
|
408
|
+
-H "Content-Type: application/json" \
|
|
409
|
+
-d "$synth_bundle" \
|
|
410
|
+
2>/dev/null)"
|
|
411
|
+
local synth_curl_rc=$?
|
|
412
|
+
set -e
|
|
413
|
+
local synth_elapsed=$(( SECONDS - t1 ))
|
|
414
|
+
|
|
415
|
+
if [[ $synth_curl_rc -ne 0 || -z "$synth_resp" ]]; then
|
|
416
|
+
_smoke_row "✗" "31" "worklog synthesis" "no response from /synthesise_worklog (timeout or error)"
|
|
417
|
+
_smoke_remedy "check: meridian logs mlx-server"
|
|
418
|
+
all_ok=0
|
|
419
|
+
elif printf '%s' "$synth_resp" | grep -q '"summary"'; then
|
|
420
|
+
local bullets conf2
|
|
421
|
+
bullets="$(printf '%s' "$synth_resp" | grep -o '"text":' | wc -l | tr -d ' ')" || bullets="?"
|
|
422
|
+
conf2="$(printf '%s' "$synth_resp" | grep -o '"confidence":[0-9.]*' | cut -d: -f2)" || conf2="?"
|
|
423
|
+
_smoke_row "✓" "32" "worklog synthesis" "${synth_elapsed}s bullets=${bullets} conf=${conf2}"
|
|
424
|
+
synth_ok=1
|
|
425
|
+
else
|
|
426
|
+
_smoke_row "✗" "31" "worklog synthesis" "response missing summary — got: ${synth_resp:0:80}"
|
|
427
|
+
_smoke_remedy "restart MLX server: meridian dev mlx (or: meridian restart)"
|
|
428
|
+
all_ok=0
|
|
429
|
+
synth_ok=0 # explicitly mark unused var for clarity
|
|
430
|
+
: "$synth_ok"
|
|
431
|
+
fi
|
|
432
|
+
|
|
433
|
+
echo ""
|
|
434
|
+
[[ $all_ok -eq 1 ]]
|
|
435
|
+
}
|
|
436
|
+
|
|
273
437
|
# --- config ---
|
|
274
438
|
cmd_config() {
|
|
275
439
|
local subcmd="${1:-}"
|
|
@@ -478,6 +642,7 @@ case "$CMD" in
|
|
|
478
642
|
status) cmd_status ;;
|
|
479
643
|
logs) cmd_logs "$@" ;;
|
|
480
644
|
doctor) cmd_doctor "$@" ;;
|
|
645
|
+
smoke) cmd_smoke "$@" ;;
|
|
481
646
|
config) cmd_config "$@" ;;
|
|
482
647
|
dev) cmd_dev "$@" ;;
|
|
483
648
|
uninstall) cmd_uninstall ;;
|
package/services/pyproject.toml
CHANGED
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "meridian-agents"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.24.0"
|
|
8
8
|
description = "Meridian agents — hermes task linking and Jira progress updates for meridian.db"
|
|
9
9
|
requires-python = ">=3.11"
|
|
10
10
|
authors = [{ name = "Meridiona" }]
|
package/ui.tar.gz
DELETED
|
Binary file
|