Menu

#273 fix(dev): give install-dev.sh full parity with the production install

closed
nobody
released (243)
2026-06-14
2026-06-12
Anonymous
No

Originally created by: Akarsh-Hegde

Why

The dev environment should provide exactly what a production install provides — infrastructure under launchd, actively-developed services via dev-start.sh hot-reload. It didn't: install.sh --no-daemon (which install-dev.sh passes) skips the entire daemon block, and that block also carries three components unrelated to the hot-reloaded services:

Component Prod Dev before this PR
OpenObserve launchd agent ✗ — no OTLP backend for observability work
Claude Code SessionEnd hook ✗ — coding-agent sessions only sealed by the 1 h idle backstop
session-summary command
screenpipe + a11y-helper ✓ (already re-added)
daemon / MLX / UI / tray launchd dev-start.sh hot-reload (by design)

A fresh dev machine silently diverged from prod in exactly the ways that are hard to notice until something downstream misbehaves.

What

  • install-dev.sh now also registers the OpenObserve agent (behind the same binary-present guard install.sh uses), installs the Claude SessionEnd hook, and copies the session-summary command.
  • Header now states the parity rule: every production component must exist in dev — under launchd or via dev-start.sh, never neither.

All three steps reuse the existing installer scripts, so behaviour matches install.sh's daemon block exactly; re-running stays idempotent (the hook installer merges into ~/.claude/settings.json without touching other hooks).

Verification

  • bash -n install-dev.sh clean; all referenced scripts/paths exist.
  • The OpenObserve guard mirrors install.sh's _oo_installed check (command -v + ~/.openobserve/openobserve).

🤖 Generated with Claude Code

Discussion

  • Anonymous

    Anonymous - 2026-06-13

    Originally posted by: Akarsh-Hegde

    Code review

    Solid parity fix — the three components (OpenObserve agent, Claude SessionEnd hook, session-summary command) genuinely live in install.sh's --no-daemon-skipped block, so dev installs were silently missing them. Reuses the existing installer scripts, so behaviour matches prod.

    ✅ Good

    • OpenObserve guard mirrors install.sh's _oo_installed check; failures are warned, not fatal.
    • Idempotent (the hook installer merges into ~/.claude/settings.json without clobbering other hooks).

    🟡 Notes

    • Installing the Claude SessionEnd hook in dev setup writes to the contributor's personal ~/.claude/settings.json. It matches prod and is reversible, but a one-line heads-up in the script output ("modifies ~/.claude/settings.json") would avoid surprise.
    • Ordering interaction with [#271]: once [#271] lands, install-openobserve-daemon.sh only starts OO when the toggle is on. This PR calls that script, so post-#271 a fresh dev install registers OO but leaves it stopped until enabled in Settings — which is the intended behaviour, just flagging the dependency.

    ⚠️ Blocking (not this PR)

    Red Rust check = pre-existing cargo fmt drift on main; this PR only touches install-dev.sh. Goes green on rebase once the fmt fix merges.

     

    Related

    Tickets: #271

  • Anonymous

    Anonymous - 2026-06-14

    Originally posted by: Akarsh-Hegde

    Code review (/code-review, high effort) + CI fix

    Reviewed the diff against install.sh's daemon block. The change is a faithful parity port — paths (session-summary src/dst, install-claude-hook.sh, install-openobserve-daemon.sh), the OpenObserve _oo_installed guard, and the if …; then ok; else warn structure all match prod exactly. The hook installer even prefers the dev target/release/meridian binary over the bundle path, so the SessionEnd hook resolves correctly in a dev-start.sh layout. 👍

    Findings

    1. (Fixed) Unguarded cp could abort the whole dev install — install-dev.sh
    The session-summary step ran a bare cp under set -euo pipefail, while the OpenObserve and SessionEnd-hook steps directly above it both warn-on-failure. A missing/unreadable SKILL.md (partial checkout, future rename) would exit non-zero and kill the install after the screenpipe/a11y/OpenObserve launchd agents were already registered — leaving a half-configured machine.

    Fix (commit 03b1f1d): wrapped it in the same if [[ -f … ]] warn-on-skip pattern as the neighbouring steps, so a missing source degrades to a skipped optional component instead of a hard abort. Now all three Claude-integration steps fail consistently.

    2. (Note, not fixed) OpenObserve parity is only half-achieved — install-dev.sh
    The new block registers the OpenObserve launchd agent only if the binary already exists. Unlike install.sh, dev has no download-offer step, so a fresh dev machine still won't get OpenObserve and the stated goal ("dev observability work has no OTLP backend") isn't met for the fresh-machine case. This is documented in the PR ("install.sh's prereq step offers the download") and reproducing the ~70-line downloader here is out of scope — flagging it as a known limitation rather than a fix. A dev simply needs to download the binary once, after which re-running install-dev.sh registers the agent.

    CI fix — CI / Rust (pull_request) was failing (cargo fmt --check)

    The failure was not in this PR's code. The branch was 35 commits behind main, carrying the pre-format versions of src/intelligence/providers/mod.rs, trello.rs, and main.rs (reformatted on main since this branch was cut). cargo fmt --check runs over the whole tree, so it flagged those stale files.

    Fix (merge commit e48bd6d): merged origin/main into the branch, bringing in the formatted versions. cargo fmt --check now passes locally (exit 0), and git diff origin/main...HEAD is once again only install-dev.sh — no behavioural change from the merge.

    🤖 Generated with Claude Code

     
  • Anonymous

    Anonymous - 2026-06-14

    Ticket changed by: Akarsh-Hegde

    • status: open --> closed
     
  • Anonymous

    Anonymous - 2026-06-14

    Originally posted by: adityaharishch

    🎉 This PR is included in version 1.52.3 🎉

    The release is available on:

    Your semantic-release bot 📦🚀

     
  • Anonymous

    Anonymous - 2026-06-14

    Originally posted by: Akarsh-Hegde

    Re: finding [#2] (OpenObserve parity "half-achieved") — non-issue, closing it out

    Went back and traced the control flow on main. The fresh-machine case is already covered — finding [#2]'s premise ("dev has no download-offer step") doesn't hold.

    install-dev.sh runs bash install.sh --dev --no-daemon first, and install.sh's OpenObserve download offer lives in Step 1 (prereq detection), not in the --no-daemon-skipped daemon block:

    • install.sh:415info "Checking prerequisites…" (Step 1)
    • install.sh:558-561if [[ "$_oo_installed" -eq 0 ]]; then … prompt_install "Download OpenObserve to ~/.openobserve/?"

    This block sits above the first if [[ "${DEV_MODE}" -eq 1 ]] branch (install.sh:672), and there is no --skip-prereqs-style flag — --dev and --no-daemon cannot bypass it. So on a fresh dev machine the flow is:

    install-dev.sh
      └─ install.sh --dev --no-daemon
           └─ Step 1 prereqs  "OpenObserve not found… Download to ~/.openobserve/? [Y/n]"    offered here
      └─ install-dev.sh OO block: binary now present  register launchd agent 
    

    Verified by dry-run: bash install.sh --dev --no-daemon --dry-run executes the OO prereq block and prints ✓ OpenObserve (the download prompt is skipped on my machine only because the binary is already installed; on a fresh machine line 558's guard flips and the prompt fires).

    The install-dev.sh comment is accurate as written — "install.sh's prereq step offers the download." The finding conflated "install-dev.sh's own block has no downloader" (true, and intentional — no need to duplicate ~70 lines) with "the dev install never offers the download" (not true). A dev who accepts the prereq prompt gets full parity with no manual second step.

    No code change needed. Leaving install-dev.sh as-is.

     

    Related

    Tickets: #2


Log in to post a comment.