@meridiona/meridian-darwin-arm64 1.69.0 → 1.70.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/.env.example CHANGED
@@ -8,7 +8,6 @@
8
8
  # Core (optional — defaults shown)
9
9
  # ---------------------------------------------------------------------------
10
10
 
11
- # SCREENPIPE_DB=~/.screenpipe/db.sqlite
12
11
  # MERIDIAN_DB=~/.meridian/meridian.db
13
12
  # POLL_INTERVAL_SECS=60
14
13
  # RUST_LOG=meridian=info
@@ -103,16 +102,23 @@
103
102
  # Syncs the OPEN issues assigned to you from the listed GitHub Projects v2 (read
104
103
  # via the GraphQL API); logs worklogs as structured issue comments (GitHub has no
105
104
  # native time tracking).
106
- # Token: easiest is the gh CLI`meridian setup` runs `gh auth token` and adds
107
- # the read:project scope for you (no PAT). Otherwise create a classic PAT with
108
- # the `repo`, `read:org`, `read:project` scopes (read:project reads Projects;
109
- # repo posts worklog comments).
105
+ # Token: easiest is the dashboard's "Browser" connect it runs GitHub's OAuth
106
+ # device flow (shows a one-time code, no PAT, no CLI) and writes GITHUB_TOKEN
107
+ # here for you. Otherwise create a classic PAT with the `repo`, `read:org`,
108
+ # `read:project` scopes (read:project reads Projects; repo posts worklog comments).
110
109
  # GITHUB_PROJECT_IDS: comma-separated Projects v2 node IDs (PVT_xxx). Find them:
111
110
  # gh api graphql -f query='{ viewer { projectsV2(first:10){nodes{id title}} } }'
111
+ #
112
+ # GITHUB_OAUTH_CLIENT_ID: overrides the baked-in OAuth App client id used by the
113
+ # device flow (public identifier, no secret). Only needed for a SOURCE build (a
114
+ # release bakes it in from the GH_OAUTH_CLIENT_ID repo secret via
115
+ # MERIDIAN_GITHUB_OAUTH_CLIENT_ID) or a custom OAuth App — the app must have
116
+ # "Enable Device Flow" checked.
112
117
  # ---------------------------------------------------------------------------
113
118
 
114
119
  # GITHUB_TOKEN=ghp_your_personal_access_token
115
120
  # GITHUB_PROJECT_IDS=PVT_xxx,PVT_yyy
121
+ # GITHUB_OAUTH_CLIENT_ID=Ov23li_your_oauth_app_client_id
116
122
 
117
123
  # ---------------------------------------------------------------------------
118
124
  # Linear (LINEAR_API_KEY required to enable the Linear connector)
@@ -174,8 +180,9 @@
174
180
  # set both to the same value when Jira is configured).
175
181
  # JIRA_URL=https://your-org.atlassian.net
176
182
 
177
- # Disable Python OTLP tracing regardless of OO config (1 = off).
178
- # MERIDIAN_TRACING_DISABLED=0
183
+ # Hard kill switch for local OTel capture (Rust daemon + Python agents both
184
+ # read this same variable — see CLAUDE.md's observability env var table).
185
+ # MERIDIAN_TELEMETRY_DISABLED=0
179
186
 
180
187
  # Confident AI key for the classifier eval harness (services/tests/evals only).
181
188
  # CONFIDENT_API_KEY=
package/VERSION CHANGED
@@ -1 +1 @@
1
- 1.69.0
1
+ 1.70.0
package/bin/meridian CHANGED
Binary file
package/bin/meridian-tray CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meridiona/meridian-darwin-arm64",
3
- "version": "1.69.0",
3
+ "version": "1.70.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": {
@@ -16,7 +16,6 @@
16
16
  ],
17
17
  "files": [
18
18
  "bin/",
19
- "ui.tar.gz",
20
19
  "services/",
21
20
  "scripts/",
22
21
  ".env.example",
@@ -37,8 +37,6 @@
37
37
  ahead of the system defaults. -->
38
38
  <key>PATH</key>
39
39
  <string>{{HOME}}/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
40
- <key>SCREENPIPE_DB</key>
41
- <string>{{HOME}}/.screenpipe/db.sqlite</string>
42
40
  <key>MERIDIAN_DB</key>
43
41
  <string>{{HOME}}/.meridian/meridian.db</string>
44
42
  <key>POLL_INTERVAL_SECS</key>
@@ -129,30 +129,6 @@ source "${APP_ROOT}/scripts/lib-trello-setup.sh"
129
129
  GUI_TARGET="gui/$(id -u)"
130
130
  LAUNCH_AGENTS="${HOME}/Library/LaunchAgents"
131
131
 
132
- # Retire the legacy standalone dashboard Node server. The dashboard now ships
133
- # embedded INSIDE the tray binary (static export, no Node server), so any
134
- # `com.meridiona.ui` launchd agent from a pre-fold install is a zombie — a
135
- # KeepAlive=true Node server holding the old dashboard port. Boot it out + remove
136
- # its plist, and drop the now-orphaned ABI-matched Node runtime cache. Idempotent
137
- # (no-op when absent) and non-fatal (a launchctl hiccup must not abort the
138
- # update) — but logged, never silent.
139
- retire_legacy_ui_server() {
140
- local label="com.meridiona.ui"
141
- local plist="${LAUNCH_AGENTS}/${label}.plist"
142
- if launchctl print "${GUI_TARGET}/${label}" >/dev/null 2>&1; then
143
- info "Retiring the legacy dashboard server (now bundled in the tray app)…"
144
- launchctl bootout "${GUI_TARGET}/${label}" 2>/dev/null \
145
- || warn "could not bootout ${label} (continuing)"
146
- fi
147
- if [[ -f "${plist}" ]]; then
148
- rm -f "${plist}" && ok "removed legacy ${label} launchd agent" \
149
- || warn "could not remove ${plist} (continuing)"
150
- fi
151
- # The pinned Node runtime existed only to ABI-match better-sqlite3 in the old
152
- # server; nothing uses it now.
153
- rm -rf "${HOME}/.meridian/node-runtime" 2>/dev/null || true
154
- }
155
-
156
132
  # Enable accessibility mode in VS Code / Cursor / Antigravity so screenpipe
157
133
  # captures their a11y tree instead of falling back to OCR. Chromium/Electron
158
134
  # editors only expose their AX tree when editor.accessibilitySupport = "on"
@@ -478,11 +454,6 @@ fi
478
454
  # this, screenpipe falls back to OCR for those editors instead of their a11y tree.
479
455
  configure_editor_accessibility
480
456
 
481
- # ── 5b. Retire the legacy dashboard Node server (one-time, for pre-fold installs) ─
482
- # The dashboard is now embedded in the tray binary, so an old standalone UI agent
483
- # is a zombie. This runs on every (re)install/update — idempotent + non-fatal.
484
- retire_legacy_ui_server
485
-
486
457
  # ── 6. Daemons — restart only what changed ───────────────────────────────────
487
458
  # screenpipe: external npm binary, plist may have changed → always refresh.
488
459
  info "Installing screenpipe launchd agent…"
@@ -11,7 +11,6 @@ REPO_ROOT="$(cd "$(dirname "$SELF")/.." && pwd)"
11
11
  # --- constants ---
12
12
  LABEL_SCREENPIPE="com.meridiona.screenpipe"
13
13
  LABEL_DAEMON="com.meridiona.daemon"
14
- LABEL_UI="com.meridiona.ui"
15
14
  LABEL_MLX="com.meridiona.mlx-server"
16
15
  # Capture runs in-process in the tray (no screenpipe launchd agent since Bucket-2).
17
16
  # Jira worklogs and coding-agent ingest run inside the Rust daemon — no
@@ -112,6 +111,24 @@ cmd_stop() {
112
111
  pkill -f "mlx_lm.server" 2>/dev/null || true
113
112
  info "killed orphaned mlx_lm.server process(es)"
114
113
  fi
114
+ # Kill any orphaned dev-build daemons (`cargo watch`/`cargo run --bin
115
+ # meridian` from dev-start.sh, or a bare `cargo run`) — not tracked by
116
+ # launchd, so `bootout` above never touches them. Closing the Terminal
117
+ # window a dev session runs in (instead of Ctrl-C, or re-running
118
+ # dev-start.sh, which has its own cleanup) reparents this chain to PID 1
119
+ # and it silently keeps running — including its clock-aligned worklog
120
+ # trigger, which then races the canonical daemon and double-runs every
121
+ # hour's worklog pipeline. Anchored to the debug/release binary path so
122
+ # this never matches the canonical `~/.meridian/bin/meridian` or the
123
+ # `meridian`/`meridian-daemon` CLI wrappers.
124
+ if pgrep -f "target/(debug|release)/meridian$" >/dev/null 2>&1; then
125
+ pkill -f "target/(debug|release)/meridian$" 2>/dev/null || true
126
+ info "killed orphaned dev-build daemon process(es)"
127
+ fi
128
+ if pgrep -f "cargo-watch.*--bin meridian" >/dev/null 2>&1; then
129
+ pkill -f "cargo-watch.*--bin meridian" 2>/dev/null || true
130
+ info "killed orphaned cargo-watch process(es)"
131
+ fi
115
132
  }
116
133
 
117
134
  # --- restart ---
@@ -152,52 +169,76 @@ cmd_status() {
152
169
  }
153
170
 
154
171
  # --- logs ---
155
- cmd_logs() {
156
- local target="daemon"
157
- local follow=0
158
- local lines=100
172
+ # Resolve the compiled `meridian` binary (distinct from THIS bash wrapper,
173
+ # which is what gets invoked as `meridian` on PATH). Mirrors
174
+ # tray/src-tauri/src/install.rs's `meridian_bin()`: packaged native locations
175
+ # first, a dev build only for a source checkout.
176
+ _meridian_native_bin() {
177
+ local p
178
+ for p in "${HOME}/.meridian/bin/meridian" "${HOME}/.meridian/app/bin/meridian"; do
179
+ [[ -x "$p" ]] && { echo "$p"; return 0; }
180
+ done
181
+ if _is_source_checkout; then
182
+ for p in "${REPO_ROOT}/target/release/meridian" "${REPO_ROOT}/target/debug/meridian"; do
183
+ [[ -x "$p" ]] && { echo "$p"; return 0; }
184
+ done
185
+ fi
186
+ return 1
187
+ }
159
188
 
160
- # consume target if it's not a flag
189
+ # `meridian logs [target] [-n N] [-f]` decodes the local OTel telemetry spool
190
+ # (`~/.meridian/telemetry/{pending,sent}/*.otlp`) via the compiled binary's
191
+ # `logs` subcommand (`src/telemetry_spool/render.rs`) — the OTel spool is now
192
+ # the ONLY log/trace sink (see `observability.rs`'s module doc), so this is
193
+ # the one supported way to read logs locally without OpenObserve. `target`
194
+ # maps to `--service <name>`; omit it to see every service interleaved.
195
+ cmd_logs() {
196
+ local target=""
161
197
  if [[ $# -gt 0 && "${1:-}" != -* ]]; then
162
198
  target="$1"; shift
163
199
  fi
164
200
 
165
- while [[ $# -gt 0 ]]; do
166
- case "$1" in
167
- -f) follow=1; shift ;;
168
- -n) lines="${2:?-n requires a value}"; shift 2 ;;
169
- *) err "unknown option: $1"; exit 1 ;;
170
- esac
171
- done
172
-
173
- local log_file
201
+ # `*-error` targets used to map to a distinct launchd StandardErrorPath
202
+ # file capturing WARN+ output only. The OTel spool has no such separate
203
+ # file, so these now pass `--min-severity WARN` to the decoder instead —
204
+ # same filtering intent (errors/warnings only), applied at read time.
205
+ local service_args=()
174
206
  case "$target" in
175
- daemon) log_file="${LOG_DIR}/daemon.log" ;;
176
- daemon-error) log_file="${LOG_DIR}/daemon-error.log" ;;
177
- screenpipe) log_file="${LOG_DIR}/screenpipe.log" ;;
178
- screenpipe-error) log_file="${LOG_DIR}/screenpipe-error.log" ;;
179
- ui) log_file="${LOG_DIR}/ui.log" ;;
180
- ui-error) log_file="${LOG_DIR}/ui-error.log" ;;
181
- mlx-server) log_file="${LOG_DIR}/mlx-server.log" ;;
182
- mlx-server-error) log_file="${LOG_DIR}/mlx-server-error.log" ;;
183
- tray) log_file="${LOG_DIR}/tray.log" ;;
184
- tray-error) log_file="${LOG_DIR}/tray-error.log" ;;
185
- # screenpipe/ui are retired post-v1.64.0 (capture is in-process in the
186
- # tray; the dashboard is embedded) — kept here so old log files remain
187
- # tailable, but `tray`/`tray-error` are the live targets now.
188
- *) err "unknown log target: ${target} (daemon|daemon-error|mlx-server|mlx-server-error|tray|tray-error)"; exit 1 ;;
207
+ ""|all) ;;
208
+ daemon) service_args=(--service meridian-rust) ;;
209
+ daemon-error) service_args=(--service meridian-rust --min-severity WARN) ;;
210
+ mlx-server) service_args=(--service meridian-mlx-server) ;;
211
+ mlx-server-error) service_args=(--service meridian-mlx-server --min-severity WARN) ;;
212
+ tray) service_args=(--service meridian-tray) ;;
213
+ tray-error) service_args=(--service meridian-tray --min-severity WARN) ;;
214
+ screenpipe|screenpipe-error|ui|ui-error)
215
+ # Retired pre-in-process-capture / pre-Tauri-fold services — they
216
+ # never participated in the OTel pipeline. Fall back to raw-tailing
217
+ # whatever plain-text launchd file might still exist from before.
218
+ local log_file="${LOG_DIR}/${target}.log"
219
+ [[ -f "$log_file" ]] || { err "no log file at ${log_file}"; exit 1; }
220
+ local lines=100 follow=()
221
+ while [[ $# -gt 0 ]]; do
222
+ case "$1" in
223
+ -f) follow=(-f); shift ;;
224
+ -n) lines="${2:?-n requires a value}"; shift 2 ;;
225
+ *) err "unknown option: $1"; exit 1 ;;
226
+ esac
227
+ done
228
+ # macOS ships bash 3.2 as /bin/bash — under `set -u`, expanding an
229
+ # empty array with "${arr[@]}" throws "unbound variable" (fixed
230
+ # only in bash 4.4+). The `${arr[@]+"${arr[@]}"}` guard skips
231
+ # expansion entirely when the array is empty/unset.
232
+ exec tail -n "$lines" ${follow[@]+"${follow[@]}"} "$log_file"
233
+ ;;
234
+ *) err "unknown log target: ${target} (daemon|mlx-server|tray, or omit for all)"; exit 1 ;;
189
235
  esac
190
236
 
191
- if [[ ! -f "$log_file" ]]; then
192
- err "no log file at ${log_file}"
193
- exit 1
194
- fi
195
-
196
- if [[ $follow -eq 1 ]]; then
197
- tail -n "$lines" -f "$log_file"
198
- else
199
- tail -n "$lines" "$log_file"
200
- fi
237
+ local bin
238
+ bin="$(_meridian_native_bin)" || { err "meridian binary not found — run ./install.sh"; exit 1; }
239
+ # Same bash-3.2-unbound-variable guard as above — service_args is empty
240
+ # for the ""/all case, which is the most common invocation.
241
+ exec "$bin" logs ${service_args[@]+"${service_args[@]}"} "$@"
201
242
  }
202
243
 
203
244
  # --- doctor ---
@@ -279,7 +320,6 @@ _doctor_fallback() {
279
320
  _plist_row "$LABEL_DAEMON" "daemon plist"
280
321
  _plist_row "$LABEL_SCREENPIPE" "screenpipe plist"
281
322
  _plist_row "$LABEL_MLX" "mlx plist"
282
- _plist_row "$LABEL_UI" "ui plist"
283
323
  _group "builds"
284
324
  _row "$([[ -f "${REPO_ROOT}/packages/meridian-mcp/dist/index.js" ]] && echo ok || echo fail)" "mcp built" ""
285
325
  _row "$([[ -d "${REPO_ROOT}/ui/.next" ]] && echo ok || echo fail)" "ui built" ""
@@ -691,24 +731,10 @@ _dev_wait_mlx() {
691
731
  _dev_build_daemon() { info "building daemon (cargo --release)…"; ( cd "${REPO_ROOT}" && cargo build --release ); }
692
732
  _dev_build_ui() { info "building UI (npm run build)…"; ( cd "${REPO_ROOT}/ui" && npm run build ); }
693
733
 
694
- # Stop the launchd (production) dashboard so `next dev` can bind its port.
695
- # Disable too, so KeepAlive doesn't race to relaunch the prod server.
696
- _dev_stop_prod_ui() {
697
- if launchctl print "${GUI_TARGET}/${LABEL_UI}" >/dev/null 2>&1; then
698
- set +e
699
- launchctl disable "${GUI_TARGET}/${LABEL_UI}" 2>/dev/null
700
- launchctl bootout "${GUI_TARGET}/${LABEL_UI}" 2>/dev/null
701
- set -e
702
- info "stopped launchd dashboard (freeing the port for the dev server)"
703
- fi
704
- }
705
-
706
734
  # Run the Next.js dev server in the FOREGROUND (hot reload). Replaces this shell
707
735
  # (exec), so Ctrl-C stops just the UI server — backing services keep running.
708
- # Re-enable the prod dashboard later with `meridian start`.
709
736
  _dev_ui_server() {
710
737
  local port="${MERIDIAN_UI_PORT:-3939}"
711
- _dev_stop_prod_ui
712
738
  echo
713
739
  info "UI dev server (hot reload) → http://localhost:${port} · Ctrl-C to stop"
714
740
  info "edit-and-save reflects instantly; backing services keep running in the background"