@meridiona/meridian-darwin-arm64 1.43.0 → 1.46.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 +1 -1
- package/VERSION +1 -1
- package/bin/meridian +0 -0
- package/bin/meridian-tray +0 -0
- package/package.json +1 -1
- package/scripts/bootstrap.sh +1 -1
- package/scripts/install-a11y-helper-daemon.sh +1 -1
- package/scripts/install-daemon.sh +1 -1
- package/scripts/install-from-bundle.sh +1 -1
- package/scripts/install-screenpipe-daemon.sh +1 -1
- package/scripts/install-tray-daemon.sh +1 -1
- package/scripts/install-ui-daemon.sh +1 -1
- package/scripts/lib-azure-setup.sh +1 -1
- package/scripts/lib-github-setup.sh +1 -1
- package/scripts/lib-jira-setup.sh +1 -1
- package/scripts/lib-trello-setup.sh +1 -1
- package/scripts/meridian-cli.sh +1 -1
- package/scripts/meridian-npm-setup.sh +1 -1
- package/scripts/ui-start.sh +1 -1
- package/scripts/uninstall-daemon.sh +1 -1
- package/scripts/uninstall-screenpipe-daemon.sh +1 -1
- package/scripts/uninstall-tray-daemon.sh +1 -1
- package/scripts/uninstall-ui-daemon.sh +1 -1
- package/services/agents/_prompts.py +2 -1
- package/services/agents/_system_context.py +6 -5
- package/services/agents/llm_selector.py +1 -1
- package/services/agents/pm_worklog_update/models.py +1 -1
- package/services/agents/pm_worklog_update/workflow.py +1 -3
- package/services/agents/run_task_linker_mlx.py +5 -4
- package/services/agents/server.py +1 -1
- package/services/agents/tests/__init__.py +1 -1
- package/services/agents/tests/conftest.py +1 -1
- package/services/agents/tests/test_config.py +1 -1
- package/services/agents/tests/test_llm_selector.py +1 -1
- package/services/agents/tests/test_parser.py +1 -1
- package/services/agents/tests/test_run_task_linker_mlx.py +1 -1
- package/services/pyproject.toml +1 -1
- package/services/skills/activity/pm-worklog-synth/SKILL.md +7 -7
- package/services/skills/activity/task-classifier/SKILL.applefm.md +1 -1
- package/services/skills/activity/task-classifier/SKILL.md +10 -10
- package/services/tests/evals/data/seeds/sessions_a_meridian.json +2 -2
- package/ui.tar.gz +0 -0
package/.env.example
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
2
2
|
#
|
|
3
3
|
# Copy this file to ~/.meridian/.env and fill in your credentials.
|
|
4
4
|
# The daemon loads ~/.meridian/.env automatically at startup.
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.46.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.
|
|
3
|
+
"version": "1.46.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": {
|
package/scripts/bootstrap.sh
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
#
|
|
4
4
|
# Bootstrap installer. Fixes the npm global prefix when it is root-owned (the
|
|
5
5
|
# most common reason `npm install -g` fails with EACCES on a stock macOS Node
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
# Install meridian-a11y-helper as a launchd LaunchAgent under the current user.
|
|
4
4
|
# The helper enables macOS accessibility on Electron/Chromium apps so
|
|
5
5
|
# screenpipe can capture them — see scripts/a11y-helper/main.swift.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
# Install the meridian Rust daemon as a launchd LaunchAgent under the
|
|
4
4
|
# current user. The daemon runs continuously, polling screenpipe every
|
|
5
5
|
# POLL_INTERVAL_SECS seconds (default 60).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
#
|
|
4
4
|
# Install a PREBUILT release bundle (no cargo/npm build). Run from inside an
|
|
5
5
|
# unpacked bundle at ~/.meridian/app — bootstrap.sh downloads + unpacks the
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
# Install screenpipe as a launchd LaunchAgent under the current user.
|
|
4
4
|
# screenpipe runs continuously, recording the screen (audio disabled via
|
|
5
5
|
# --disable-audio) on its default port 3030 with data stored in ~/.screenpipe.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
# Install the tray app as a launchd agent to start on login
|
|
4
4
|
|
|
5
5
|
set -euo pipefail
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
# Install the meridian Next.js dashboard as a launchd LaunchAgent under the
|
|
4
4
|
# current user. Serves on http://localhost:3939. Built artifact must exist
|
|
5
5
|
# at ui/.next/ before this script runs (install.sh handles that).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
#
|
|
4
4
|
# Shared Azure DevOps setup helpers, sourced by both install.sh (source installs)
|
|
5
5
|
# and scripts/install-from-bundle.sh (bundle installs). The sourcing script must
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
#
|
|
4
4
|
# Shared GitHub setup helpers, sourced by both install.sh (source installs) and
|
|
5
5
|
# scripts/install-from-bundle.sh (bundle installs). The sourcing script must
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
2
2
|
#
|
|
3
3
|
# Shared Jira credential-collection helper for install.sh + install-from-bundle.sh.
|
|
4
4
|
# OAuth-first: when a runnable meridian binary is available, connect Jira in the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
2
2
|
#
|
|
3
3
|
# Shared Trello credential-collection helper for install-from-bundle.sh.
|
|
4
4
|
# Trello uses a legacy token grant delivered via URL fragment — the daemon
|
package/scripts/meridian-cli.sh
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
#
|
|
4
4
|
# Bridge from the npm install to the real install. Assembles the prebuilt bundle
|
|
5
5
|
# (the @meridiona/meridian-darwin-arm64 package contents) into ~/.meridian/app
|
package/scripts/ui-start.sh
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
#
|
|
4
4
|
# Startup wrapper for the Next.js UI daemon.
|
|
5
5
|
#
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
# Stop and remove the meridian Rust daemon launchd agent.
|
|
4
4
|
set -euo pipefail
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
# Stop and remove the screenpipe launchd agent.
|
|
4
4
|
set -euo pipefail
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
# Remove the Meridian Tray launchd agent.
|
|
4
4
|
set -euo pipefail
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
3
3
|
# Stop and remove the meridian UI launchd agent.
|
|
4
4
|
|
|
5
5
|
set -euo pipefail
|
|
@@ -101,9 +101,10 @@ def _format_candidates(tasks: list[dict]) -> str:
|
|
|
101
101
|
issue_type = (task.get("issue_type") or "").strip()
|
|
102
102
|
epic_title = (task.get("epic_title") or "").strip()
|
|
103
103
|
sprint_name = (task.get("sprint_name") or "").strip()
|
|
104
|
+
tags = (task.get("tags") or "").strip()
|
|
104
105
|
if len(desc) > 240:
|
|
105
106
|
desc = desc[:240] + "…"
|
|
106
|
-
meta_parts = [p for p in [issue_type, f"Epic: {epic_title}" if epic_title else "", sprint_name] if p]
|
|
107
|
+
meta_parts = [p for p in [issue_type, f"Epic: {epic_title}" if epic_title else "", sprint_name, f"tags: {tags}" if tags else ""] if p]
|
|
107
108
|
meta = " [" + " · ".join(meta_parts) + "]" if meta_parts else ""
|
|
108
109
|
rows.append(
|
|
109
110
|
f"{i}. {task['task_key']}{meta}\n"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
2
2
|
"""Shared system context for all agent entry points (task-linker, server).
|
|
3
3
|
|
|
4
4
|
This module defines the single source of truth for the AI agent's system prompt,
|
|
@@ -33,15 +33,16 @@ Meridian monitors a developer's screen and builds a structured record of their w
|
|
|
33
33
|
|
|
34
34
|
CURRENT CAPABILITY — session classification
|
|
35
35
|
Given a work session (app, duration, screen content, recent history, open tickets), decide:
|
|
36
|
-
· which
|
|
36
|
+
· which tracked ticket the session belongs to ("task"), or
|
|
37
37
|
· that it is overhead or untracked work.
|
|
38
|
+
Tickets may come from Jira, Linear, GitHub, Trello, or Azure DevOps — treat them uniformly.
|
|
38
39
|
Use the task-classifier skill when asked to classify. Session data and candidate tickets are
|
|
39
40
|
passed directly in the message — no need to query unless verifying a detail.
|
|
40
41
|
Always return a single bare JSON object. No preamble, no markdown fences, no explanation.
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
Given classified sessions,
|
|
44
|
-
|
|
43
|
+
CURRENT CAPABILITY — PM worklog updates
|
|
44
|
+
Given classified sessions, writes a verified worklog comment and posts it to the
|
|
45
|
+
connected PM tool (Jira, Linear, GitHub, etc.) without manual developer input.
|
|
45
46
|
|
|
46
47
|
DATABASE (for verification and ad-hoc queries)
|
|
47
48
|
Path: {_DB_PATH}
|
|
@@ -19,7 +19,7 @@ conservative estimate). M4 Ultra is omitted — it was cancelled; Mac Pro was
|
|
|
19
19
|
discontinued March 2026 without an M4 Ultra update. M5 Ultra is omitted — not
|
|
20
20
|
yet shipped as of mid-2026.
|
|
21
21
|
"""
|
|
22
|
-
#
|
|
22
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
23
23
|
from __future__ import annotations
|
|
24
24
|
|
|
25
25
|
import ctypes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
2
2
|
"""Pydantic models for the pm_worklog_update workflow."""
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -111,11 +111,9 @@ def _coerce_jira(raw) -> JiraUpdate | None:
|
|
|
111
111
|
|
|
112
112
|
|
|
113
113
|
def _decide_state(update: JiraUpdate, coverage: float, bundle: SessionBundle) -> UpdateState:
|
|
114
|
-
"""
|
|
114
|
+
"""All worklogs are DRAFTED until a human approves via the UI — never auto-posted."""
|
|
115
115
|
if not update.summary.strip():
|
|
116
116
|
return UpdateState.SKIPPED
|
|
117
|
-
if update.confidence < config.PM_WORKLOG_MIN_CONFIDENCE:
|
|
118
|
-
return UpdateState.DRAFTED
|
|
119
117
|
return UpdateState.DRAFTED
|
|
120
118
|
|
|
121
119
|
|
|
@@ -187,7 +187,7 @@ class SessionClassification(BaseModel):
|
|
|
187
187
|
),
|
|
188
188
|
)
|
|
189
189
|
session_summary: str = Field(
|
|
190
|
-
..., min_length=100,
|
|
190
|
+
..., min_length=100,
|
|
191
191
|
description=(
|
|
192
192
|
"A factual prose summary of EVERYTHING the user did in this "
|
|
193
193
|
"session, written for downstream project-management updates. "
|
|
@@ -342,7 +342,7 @@ def _coerce_apple_fm_result(data: dict) -> dict:
|
|
|
342
342
|
if not data.get("reasoning"):
|
|
343
343
|
data["reasoning"] = "Classified via Apple Foundation Models."
|
|
344
344
|
|
|
345
|
-
# session_summary: must be 100
|
|
345
|
+
# session_summary: must be at least 100 chars
|
|
346
346
|
summary = str(data.get("session_summary", ""))
|
|
347
347
|
if len(summary) < 100:
|
|
348
348
|
# Pad from reasoning
|
|
@@ -350,7 +350,7 @@ def _coerce_apple_fm_result(data: dict) -> dict:
|
|
|
350
350
|
summary = (summary + " " + reasoning).strip()
|
|
351
351
|
if len(summary) < 100:
|
|
352
352
|
summary = summary + " The session was processed by Apple Foundation Models."
|
|
353
|
-
data["session_summary"] = summary
|
|
353
|
+
data["session_summary"] = summary
|
|
354
354
|
|
|
355
355
|
# dimensions: must be dict[str, list[str]]
|
|
356
356
|
dims = data.get("dimensions", {})
|
|
@@ -491,7 +491,8 @@ def _fetch_pm_tasks(con: _sqlite3.Connection) -> list[dict[str, Any]]:
|
|
|
491
491
|
" COALESCE(issue_type,'') AS issue_type,"
|
|
492
492
|
" COALESCE(parent_key,'') AS parent_key,"
|
|
493
493
|
" COALESCE(epic_title,'') AS epic_title,"
|
|
494
|
-
" COALESCE(sprint_name,'') AS sprint_name"
|
|
494
|
+
" COALESCE(sprint_name,'') AS sprint_name,"
|
|
495
|
+
" COALESCE(tags,'') AS tags"
|
|
495
496
|
" FROM pm_tasks",
|
|
496
497
|
).fetchall()
|
|
497
498
|
return [dict(r) for r in rows]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
2
2
|
"""Shared pytest fixtures and sys.path setup for the agents test suite.
|
|
3
3
|
|
|
4
4
|
The tests are written so they can be invoked from `services/` with:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
2
2
|
"""Unit tests for agents.config helpers (_env_bool)."""
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
2
2
|
"""Unit tests for agents.llm_selector — model selection and server management.
|
|
3
3
|
|
|
4
4
|
All external I/O (subprocess, socket, HTTP, platform, psutil, mlx) is patched
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
2
2
|
"""Tests for agents._parser — parse_response and extract_json."""
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity
|
|
2
2
|
"""Tests for run_task_linker_mlx — outlines-based MLX in-process classification.
|
|
3
3
|
|
|
4
4
|
Run from services/:
|
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.46.0"
|
|
8
8
|
description = "Meridian agents — MLX classifier server and Jira worklog synthesis for meridian.db"
|
|
9
9
|
requires-python = ">=3.11"
|
|
10
10
|
authors = [{ name = "Meridiona" }]
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pm-worklog-synth
|
|
3
|
-
description: Verify classified work sessions belong to a
|
|
3
|
+
description: Verify classified work sessions belong to a tracked ticket and write a brief worklog comment.
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
version: "2.0.0"
|
|
7
7
|
meridian:
|
|
8
8
|
role: synth
|
|
9
|
-
tags: [pm-worklog,
|
|
9
|
+
tags: [pm-worklog, sdlc]
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# PM Worklog Synthesiser
|
|
13
13
|
|
|
14
14
|
You are Meridian's worklog writer. Your job is to look at a window of screen-capture sessions
|
|
15
|
-
that were automatically classified to a
|
|
16
|
-
a brief, honest
|
|
15
|
+
that were automatically classified to a tracked ticket, verify they actually belong, and write
|
|
16
|
+
a brief, honest worklog comment summarising what was done.
|
|
17
17
|
|
|
18
|
-
You are **writing the developer's
|
|
18
|
+
You are **writing the developer's work log entry**. The bar is: would the ticket owner
|
|
19
19
|
reading this understand what work happened, how long it took, and whether it genuinely
|
|
20
20
|
relates to this ticket?
|
|
21
21
|
|
|
@@ -77,7 +77,7 @@ your `confidence`.
|
|
|
77
77
|
### Step 3 — Write the worklog comment
|
|
78
78
|
|
|
79
79
|
From the verified sessions, write a **2-4 line worklog comment** in `summary`. This is what
|
|
80
|
-
gets posted to
|
|
80
|
+
gets posted to the ticket tracker. Rules:
|
|
81
81
|
|
|
82
82
|
- Be factual and specific — mention the actual files, functions, commands, or outcomes visible
|
|
83
83
|
in the session summaries. No vague claims like "made progress" or "worked on the feature".
|
|
@@ -108,7 +108,7 @@ gets posted to Jira. Rules:
|
|
|
108
108
|
|
|
109
109
|
## Output format
|
|
110
110
|
|
|
111
|
-
Reply with ONE valid `
|
|
111
|
+
Reply with ONE valid `WorklogUpdate` JSON object. No preamble, no markdown fences, no follow-up
|
|
112
112
|
text. The primary fields that matter are `summary`, `time_spent_seconds`, and `confidence`.
|
|
113
113
|
The bullet arrays (`what_shipped`, `in_progress`, `blockers`, `decisions`) are optional —
|
|
114
114
|
leave them empty unless you have a very clear signal worth surfacing.
|
|
@@ -10,7 +10,7 @@ metadata:
|
|
|
10
10
|
# Session Task Classifier — Apple Intelligence tier (compact)
|
|
11
11
|
|
|
12
12
|
You are Meridian's session classifier. Classify ONE work session captured from the
|
|
13
|
-
user's screen against the open
|
|
13
|
+
user's screen against the open tracked tickets (Jira, Linear, GitHub, Trello, Azure DevOps), and return a single JSON object.
|
|
14
14
|
|
|
15
15
|
## Decide in order
|
|
16
16
|
1. **Overhead** — idle, music, system settings, clearly personal/unrelated browsing →
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: task-classifier
|
|
3
|
-
description: Classify a user work session against open
|
|
3
|
+
description: Classify a user work session against open tracked tickets — pick the best match (or null) using session evidence, and infer dimension tags.
|
|
4
4
|
version: 2.0.0
|
|
5
5
|
metadata:
|
|
6
6
|
meridian:
|
|
@@ -9,7 +9,7 @@ metadata:
|
|
|
9
9
|
|
|
10
10
|
# Session Task Classifier
|
|
11
11
|
|
|
12
|
-
You are Meridian's AI classifier. Your job is to classify work sessions captured from the user's screen and match them to open
|
|
12
|
+
You are Meridian's AI classifier. Your job is to classify work sessions captured from the user's screen and match them to open tracked tickets (Jira, Linear, GitHub, Trello, Azure DevOps) when appropriate and return response in structured json output.
|
|
13
13
|
|
|
14
14
|
## Purpose
|
|
15
15
|
|
|
@@ -19,8 +19,8 @@ The task classifier sits at the center of Meridian's workflow understanding:
|
|
|
19
19
|
2. **Sessions** → **task classification** (you classify each session)
|
|
20
20
|
3. **Classification outcome** dictates downstream usage:
|
|
21
21
|
- Sessions marked as **overhead** → completely discarded. Never surfaced in the UI, never used for inference, never used to create tasks. Treat as throwaway. Examples: music players, system settings, idle browsing, etc.
|
|
22
|
-
- Sessions marked as **untracked** → retained and used downstream. Fed into workload analysis
|
|
23
|
-
- Sessions with **task matches** → linked to
|
|
22
|
+
- Sessions marked as **untracked** → retained and used downstream. Fed into workload analysis and task inference. These are real work signals the user performed that just didn't match an open ticket. Examples: standup meetings, config housekeeping, repo exploration, general research.
|
|
23
|
+
- Sessions with **task matches** → linked to the matched ticket, routing=auto for time-tracking and progress.
|
|
24
24
|
|
|
25
25
|
## Classification Decision Tree
|
|
26
26
|
|
|
@@ -38,9 +38,9 @@ If the session shows **any real work signal** (coding, research, meetings, writi
|
|
|
38
38
|
```json
|
|
39
39
|
{"task_key": null, "confidence": 0.6-0.8, "session_type": "untracked", "routing": "queue"}
|
|
40
40
|
```
|
|
41
|
-
**This is the important, common case — and it is what `untracked` MEANS: the user genuinely did this work, but there is no
|
|
41
|
+
**This is the important, common case — and it is what `untracked` MEANS: the user genuinely did this work, but there is no tracked ticket for it.** It is critical that you do **not** shoehorn this work into an unrelated existing ticket just because it is the only candidate available, or because recent sessions were on it. **A wrong task link is worse than `untracked`** — it pollutes a real ticket's worklog and hides the genuine untracked work. When the evidence doesn't clearly fit a candidate, choose `untracked`.
|
|
42
42
|
|
|
43
|
-
`untracked` sessions are kept and used downstream (workload analysis, capacity reporting
|
|
43
|
+
`untracked` sessions are kept and used downstream (workload analysis, capacity reporting). Mark dimensions to capture *what* the work was. Examples that must be `untracked` (not `overhead`): standups, retros, code reviews on untracked PRs, config/infra housekeeping, general repo exploration, general research, **and any work on a feature/bug/chore that has no matching candidate ticket**.
|
|
44
44
|
|
|
45
45
|
### 3. Does it CLEARLY map to one specific candidate ticket? → task
|
|
46
46
|
Assign a `task_key` **only** when the session's own evidence (window titles, OCR, file/branch names, an explicit ticket-key mention) directly matches the **scope described in that ticket's title/description** → return:
|
|
@@ -54,7 +54,7 @@ Recent-session continuity may *support* a match, but **continuity alone is never
|
|
|
54
54
|
The user message contains:
|
|
55
55
|
|
|
56
56
|
- **SESSION** — app, duration, top window titles, and the screen content (OCR / a11y). Decide the category yourself from this evidence; no category is provided.
|
|
57
|
-
- **CANDIDATE TICKETS** — all open Jira
|
|
57
|
+
- **CANDIDATE TICKETS** — all open tracked tickets (Jira, Linear, GitHub, Trello, Azure DevOps). These are the only tickets you may choose from.
|
|
58
58
|
- **RECENT SESSIONS** (previous 5) — app / time / duration / which ticket each mapped to (no screen text). A **weak disambiguation hint only**: it can support a match when the current session ALSO has matching evidence, but it must never override what the current session itself shows. Recent activity on a ticket does not make the current session that ticket.
|
|
59
59
|
|
|
60
60
|
## Available capabilities
|
|
@@ -66,7 +66,7 @@ sqlite3 "~/.meridian/meridian.db" "<SQL>"
|
|
|
66
66
|
|
|
67
67
|
Available tables:
|
|
68
68
|
- `app_sessions` — all captured work sessions (id, app_name, duration_s, session_text, task_key, task_routing, etc.)
|
|
69
|
-
- `pm_tasks` — open
|
|
69
|
+
- `pm_tasks` — open tracked tickets (task_key, provider, title, description_text, issue_type, status, epic_title, sprint_name, tags)
|
|
70
70
|
|
|
71
71
|
Use database queries sparingly — session data and candidate tickets are already provided in the message. Only query if you need to verify a detail or look up historical context not included in the current inputs.
|
|
72
72
|
|
|
@@ -103,7 +103,7 @@ Reply with ONE valid JSON object — no preamble, no markdown fences, no follow-
|
|
|
103
103
|
- `category` — the single best activity category (see taxonomy below). Derive it yourself from the evidence (app, window titles, screen content); no category is provided in the input.
|
|
104
104
|
- `category_confidence` — how certain you are about `category`, `0.0`–`1.0`.
|
|
105
105
|
- `category_explanation` — ONE concise sentence justifying the category, citing the app / window titles / OCR evidence. Shown in the dashboard next to the category.
|
|
106
|
-
- `session_type` — `"task"` links to
|
|
106
|
+
- `session_type` — `"task"` links to the matched ticket; `"overhead"` is thrown away; `"untracked"` is kept for workload analysis.
|
|
107
107
|
- `reasoning` — must cite specific window titles, OCR snippets, or context clues.
|
|
108
108
|
- `dimensions` — omit keys with no evidence; return `{}` if no clear signals.
|
|
109
109
|
- `session_summary` — see the dedicated section below. This is the SINGLE most important field for downstream PM updates.
|
|
@@ -129,7 +129,7 @@ Choose exactly ONE `category` from this fixed set. Pick the dominant activity by
|
|
|
129
129
|
|
|
130
130
|
## session_summary — THE PM-update payload
|
|
131
131
|
|
|
132
|
-
This field is what the PM-update workflow consumes to write
|
|
132
|
+
This field is what the PM-update workflow consumes to write worklog comments. It REPLACES the raw OCR text downstream — the PM agent will not see the original session_text unless it explicitly asks. So **every SDLC-relevant detail you observe must be captured here, written so a tech-lead reading it understands exactly what happened.**
|
|
133
133
|
|
|
134
134
|
### Length
|
|
135
135
|
|
|
@@ -1130,7 +1130,7 @@
|
|
|
1130
1130
|
"count": 3
|
|
1131
1131
|
}
|
|
1132
1132
|
],
|
|
1133
|
-
"session_text": "[09:46:35]\nFile Edit Selection View Go Run Terminal Window Help\nExplorer (⇧⌘E) · feat/golden-dataset-kan-139\nEXPLORER\nMERIDIAN\n .githooks/\n .github/\n packages/\n meridian-mcp/\n scripts/\n services/\n agents/\n observability.py ←\n tests/\n evals/\n golden_seed/\n candidates_meridian.json\n dev_a_sessions.json M\n .dataset.json\n build_synthetic_dataset.py\n render_seeds.py\n smoke_run.py\n test_mlx_classifier.py\n src/\n db/\n meridian.rs\n screenpipe.rs\n etl/\n extractor.rs\n runner.rs\n config.rs\n lib.rs\n main.rs\n observability.rs ← ACTIVE\n tests/\n common/\n mod.rs\n integration_etl.rs\n .env\n Cargo.toml\n CLAUDE.md\n TESTING.md\n rust-toolchain.toml\nOUTLINE\n setup()\n shutdown()\nSOURCE CONTROL: 0 unstaged\nfeat/golden-dataset-kan-139 ⇣ 0 ⇡ 0 Rust 1.93.1\n\n[09:46:40]\nsrc/observability.rs — meridian — Rust\n 1 | // meridian — normalises screenpipe activity into structured app sessions\n 2 | use anyhow::Context as _;\n 3 | use opentelemetry::global;\n 4 | use opentelemetry::trace::TracerProvider as _;\n 5 | use opentelemetry_otlp::WithExportConfig;\n 6 | use opentelemetry_sdk::{\n 7 | propagation::TraceContextPropagator,\n 8 | runtime,\n 9 | trace::{self as sdktrace, Sampler},\n 10 | };\n 11 | use tracing_opentelemetry::OpenTelemetryLayer;\n 12 | use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};\n 13 |\n 14 | pub fn setup(service_name: &'static str) -> anyhow::Result<()> {\n 15 | let otlp_endpoint = std::env::var(\"MERIDIAN_OTLP_ENDPOINT\").ok();\n 16 | let oo_auth = std::env::var(\"MERIDIAN_OO_AUTH\").ok();\n 17 |\n 18 | if otlp_endpoint.is_none() {\n 19 | // No endpoint configured — install a no-op subscriber only.\n 20 | tracing_subscriber::registry()\n 21 | .with(EnvFilter::from_default_env())\n 22 | .with(tracing_subscriber::fmt::layer())\n 23 | .init();\n 24 | return Ok(());\n 25 | }\n 26 |\n 27 | let endpoint = otlp_endpoint.unwrap();\n 28 | let mut headers = std::collections::HashMap::new();\n 29 | if let Some(auth) = oo_auth {\n 30 | headers.insert(\"Authorization\".to_string(), format!(\"Basic {auth}\"));\n 31 | }\n 32 |\n 33 | let tracer = opentelemetry_otlp::new_pipeline()\n 34 | .tracing()\n 35 | .with_exporter(\n 36 | opentelemetry_otlp::new_exporter()\n 37 | .http()\n 38 | .with_endpoint(&endpoint)\n 39 | .with_headers(headers),\n 40 | )\n 41 | .with_trace_config(\n 42 | sdktrace::config()\n 43 | .with_sampler(Sampler::AlwaysOn)\n 44 | .with_resource(opentelemetry_sdk::Resource::new(vec![\n 45 | opentelemetry::KeyValue::new(\"service.name\", service_name),\n 46 | ])),\n 47 | )\n 48 | .install_batch(runtime::Tokio)\n 49 | .context(\"failed to install OTLP tracer\")?;\n 50 |\n 51 | global::set_text_map_propagator(TraceContextPropagator::new());\n 52 | global::set_tracer_provider(tracer.provider().unwrap());\n 53 |\n 54 | tracing_subscriber::registry()\n 55 | .with(EnvFilter::from_default_env())\n 55 | .with(tracing_subscriber::fmt::layer())\n 56 | .with(OpenTelemetryLayer::new(tracer))\n 57 | .init();\n 58 |\n 59 | Ok(())\n 60 | }\n 61 |\n 62 | pub fn shutdown() {\n 63 | global::shutdown_tracer_provider();\n 64 | }\nRust 1.93.1 | LF | UTF-8 | Ln 14, Col 1\nfeat/golden-dataset-kan-139 ⇣ 0 ⇡ 0 Rust 1.93.1 (via rust-toolchain.toml)\n\n[09:47:08]\nsrc/observability.rs — meridian — Rust\n(developer scrolled to line 33 — the OTLP pipeline setup)\n 33 | let tracer = opentelemetry_otlp::new_pipeline()\n 34 | .tracing()\n 35 | .with_exporter(\n 36 | opentelemetry_otlp::new_exporter()\n 37 | .http()\n 38 | .with_endpoint(&endpoint)\n 39 | .with_headers(headers),\n 40 | )\n 41 | .with_trace_config(\n 42 | sdktrace::config()\n 43 | .with_sampler(Sampler::AlwaysOn)\n 44 | .with_resource(opentelemetry_sdk::Resource::new(vec![\n 45 | opentelemetry::KeyValue::new(\"service.name\", service_name),\n 46 | ])),\n 47 | )\n 48 | .install_batch(runtime::Tokio)\n 49 | .context(\"failed to install OTLP tracer\")?;\n 50 |\n 51 | global::set_text_map_propagator(TraceContextPropagator::new());\n 52 | global::set_tracer_provider(tracer.provider().unwrap());\n(developer hovers over line 48 — tooltip appears)\nTOOLTIP: install_batch(runtime::Tokio)\n pub fn install_batch<R: RuntimeChannel>(self, runtime: R) -> Result<sdk::trace::Tracer, TraceError>\n Install the configured pipeline as a batch OTLP exporter using the given runtime.\n Returns the configured Tracer.\nRust 1.93.1 | LF | UTF-8 | Ln 48, Col 28\n\n[09:47:31]\nsrc/observability.rs — meridian — Rust\n(developer adds a comment above the run_etl span emission section — cross-referencing KAN-136)\n 62 | pub fn shutdown() {\n 63 | global::shutdown_tracer_provider();\n 64 | }\n(cursor moves to end of file — developer considers adding a new helper)\n(types, then deletes)\n+65 | \n+66 | /// Returns a named tracer scoped to the ETL pipeline.\n+67 | /// Each run_etl() call should request this tracer to parent batch spans.\n+68 | pub fn etl_tracer() -> opentelemetry::global::BoxedTracer {\n(backspace × 4 lines — removed)\nRust 1.93.1 | LF | UTF-8 | Ln 64, Col 2\nfeat/golden-dataset-kan-139 ⇣ 0 ⇡ 0\n\n[09:47:55]\nzsh — meridian — TERMINAL\nakarsh@MacBook-Pro meridian % cargo clippy --lib 2>&1\n Compiling meridian v0.6.2 (/Users/akarsh/Documents/Meridiona/meridian)\nwarning: unused import: `global`\n --> src/observability.rs:3:22\n |\n 3 | use opentelemetry::global;\n | ^^^^^^\n |\n = note: `#[warn(unused_imports)]` on by default\n\nwarning: unused variable: `tracer`\n --> src/main.rs:47:9\n |\n47 | let tracer = trace::get_tracer(\"meridian.etl\");\n | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_tracer`\n |\n = note: `#[warn(unused_variables)]` on by default\n\nwarning: `meridian` (lib) generated 2 warnings\nerror[E0599]: no method named `force_flush` found for type `opentelemetry_sdk::trace::TracerProvider` in the current scope\n --> src/observability.rs:63:14\n |\n63 | global::shutdown_tracer_provider();\n |\n note: method `force_flush` exists on `opentelemetry_sdk::trace::TracerProvider`\n help: consider calling `as_any()` first\nerror: could not compile `meridian` (lib) due to 1 previous error; 2 warnings\nakarsh@MacBook-Pro meridian %\n\n[09:48:22]\nzsh — meridian — TERMINAL\n(developer stares at the error — force_flush not found on the global provider)\nakarsh@MacBook-Pro meridian % grep -rn \"force_flush\" src/\nsrc/observability.rs:63: global::shutdown_tracer_provider();\nakarsh@MacBook-Pro meridian % grep -rn \"force_flush\" services/agents/observability.py\nservices/agents/observability.py:38: _provider = trace.get_tracer_provider()\nservices/agents/observability.py:39: if hasattr(_provider, 'force_flush'):\nservices/agents/observability.py:40: _provider.force_flush(timeout_millis=5000)\nservices/agents/observability.py:41: opentelemetry.sdk.trace.export.shutdown()\nakarsh@MacBook-Pro meridian %\n(developer opens the Python observability.py in a split pane to compare)\n\n[09:48:50]\nsrc/observability.rs | services/agents/observability.py (split)\nLEFT PANE — src/observability.rs\n 62 | pub fn shutdown() {\n 63 | global::shutdown_tracer_provider();\n 64 | }\n\nRIGHT PANE — services/agents/observability.py\n 1 | \"\"\"OTel setup and teardown for the Python agent services.\"\"\"\n 2 | from __future__ import annotations\n 3 | import os\n 4 | from opentelemetry import trace\n 5 | from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter\n 6 | from opentelemetry.sdk.trace import TracerProvider\n 7 | from opentelemetry.sdk.trace.export import BatchSpanProcessor\n 8 |\n 9 | _provider: TracerProvider | None = None\n 10 |\n 11 | def setup(service_name: str) -> None:\n 12 | global _provider\n 13 | endpoint = os.environ.get(\"MERIDIAN_OTLP_ENDPOINT\")\n 14 | auth = os.environ.get(\"MERIDIAN_OO_AUTH\")\n 15 | if not endpoint:\n 16 | return # no-op if OTLP not configured\n 17 | exporter = OTLPSpanExporter(\n 18 | endpoint=endpoint,\n 19 | headers={\"Authorization\": f\"Basic {auth}\"} if auth else {},\n 20 | )\n 21 | _provider = TracerProvider(\n 22 | resource=Resource.create({\"service.name\": service_name})\n 23 | )\n 24 | _provider.add_span_processor(BatchSpanProcessor(exporter))\n 25 | trace.set_tracer_provider(_provider)\n 26 |\n 27 | def shutdown() -> None:\n 28 | global _provider\n 29 | if _provider:\n 30 | _provider.force_flush(timeout_millis=5_000)\n 31 | _provider.shutdown()\n 32 |\n(developer comparing both shutdown() implementations side by side)\nRust 1.93.1 | LF | UTF-8 | Ln 63, Col 5 | Python 3.11\n\n[09:49:18]\nsrc/observability.rs — meridian — Rust\n(developer returns to Rust file — edits shutdown() to call force_flush before shutdown)\n 62 | pub fn shutdown() {\n-63 | global::shutdown_tracer_provider();\n+63 | if let Some(provider) = global::tracer_provider()\n+64 | .as_any()\n+65 | .downcast_ref::<opentelemetry_sdk::trace::TracerProvider>()\n+66 | {\n+67 | let _ = provider.force_flush();\n+68 | }\n+69 | global::shutdown_tracer_provider();\n 70 | }\n(status bar: 1 unsaved change)\nRust 1.93.1 | LF | UTF-8 | Ln 70, Col 2\nfeat/golden-dataset-kan-139* ⇣ 0 ⇡ 0 1 unsaved change\n\n[09:49:40]\nzsh — meridian — TERMINAL\nakarsh@MacBook-Pro meridian % cargo clippy --lib 2>&1\n Compiling meridian v0.6.2 (/Users/akarsh/Documents/Meridiona/meridian)\nwarning: unused import: `global`\n --> src/observability.rs:3:22\n |\n 3 | use opentelemetry::global;\n | ^^^^^^\n |\n = note: `#[warn(unused_imports)]` on by default\n\nwarning: `meridian` (lib) generated 1 warning\nerror[E0308]: mismatched types\n --> src/observability.rs:64:10\n |\n63 | if let Some(provider) = global::tracer_provider()\n64 | .as_any()\n | ^^^^^^ method not found in `GlobalTracerProvider`\nerror: could not compile `meridian` (lib) due to 1 previous error; 1 warning\nakarsh@MacBook-Pro meridian %\n(developer frowns — as_any() not available on GlobalTracerProvider directly)\n\n[09:50:05]\nzsh — meridian — TERMINAL\nakarsh@MacBook-Pro meridian % cargo doc --open --package opentelemetry_sdk 2>&1 | tail -5\n Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.43s\n Opening /Users/akarsh/Documents/Meridiona/meridian/target/doc/opentelemetry_sdk/trace/struct.TracerProvider.html\nakarsh@MacBook-Pro meridian %\n(browser opens in background — docs page)\n\nakarsh@MacBook-Pro meridian % grep -rn \"shutdown_tracer_provider\\|force_flush\" \\\n ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/opentelemetry-0.22.0/src/global/trace.rs \\\n 2>/dev/null | head -20\n 44: pub fn shutdown_tracer_provider() {\n 45: let mut tracer_provider = GLOBAL_TRACER_PROVIDER\n 46: .write()\n 47: .expect(\"GLOBAL_TRACER_PROVIDER RwLock poisoned\");\n 48: let _ = tracer_provider.shutdown();\n 49: }\nakarsh@MacBook-Pro meridian %\n(developer sees shutdown_tracer_provider() already calls .shutdown() internally — force_flush is separate on the SDK type)\n\n[09:50:35]\nsrc/observability.rs — meridian — Rust\n(developer reverts the force_flush attempt — goes back to the simpler form, adds a TODO comment)\n 62 | pub fn shutdown() {\n+63 | // TODO(KAN-136): add explicit force_flush before shutdown — requires holding\n+64 | // a reference to the SDK provider, not the global wrapper. See:\n+65 | // opentelemetry_sdk::trace::TracerProvider::force_flush()\n 66 | global::shutdown_tracer_provider();\n 67 | }\n(saves file — Cmd+S)\n(status bar: no unsaved changes)\nRust 1.93.1 | LF | UTF-8 | Ln 67, Col 2\nfeat/golden-dataset-kan-139* ⇣ 0 ⇡ 0 Rust 1.93.1\n\n[09:50:42]\nzsh — meridian — TERMINAL\nakarsh@MacBook-Pro meridian % cargo test --test integration_etl 2>&1 | tail -12\nrunning 6 tests\ntest etl_basic ... ok\ntest etl_gap_detection ... ok\ntest etl_cursor_advance ... ok\ntest etl_cleanup_stale_runs ... ok\ntest etl_concurrent_writes ... ok\ntest etl_observability ... ok (142ms)\ntest result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out\nakarsh@MacBook-Pro meridian %\n(developer closes terminal, does not commit — the TODO comment is the deliverable for now)\nfeat/golden-dataset-kan-139* ⇣ 0 ⇡ 0 1 uncommitted change",
|
|
1133
|
+
"session_text": "[09:46:35]\nFile Edit Selection View Go Run Terminal Window Help\nExplorer (⇧⌘E) · feat/golden-dataset-kan-139\nEXPLORER\nMERIDIAN\n .githooks/\n .github/\n packages/\n meridian-mcp/\n scripts/\n services/\n agents/\n observability.py ←\n tests/\n evals/\n golden_seed/\n candidates_meridian.json\n dev_a_sessions.json M\n .dataset.json\n build_synthetic_dataset.py\n render_seeds.py\n smoke_run.py\n test_mlx_classifier.py\n src/\n db/\n meridian.rs\n screenpipe.rs\n etl/\n extractor.rs\n runner.rs\n config.rs\n lib.rs\n main.rs\n observability.rs ← ACTIVE\n tests/\n common/\n mod.rs\n integration_etl.rs\n .env\n Cargo.toml\n CLAUDE.md\n TESTING.md\n rust-toolchain.toml\nOUTLINE\n setup()\n shutdown()\nSOURCE CONTROL: 0 unstaged\nfeat/golden-dataset-kan-139 ⇣ 0 ⇡ 0 Rust 1.93.1\n\n[09:46:40]\nsrc/observability.rs — meridian — Rust\n 1 | //ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity\n 2 | use anyhow::Context as _;\n 3 | use opentelemetry::global;\n 4 | use opentelemetry::trace::TracerProvider as _;\n 5 | use opentelemetry_otlp::WithExportConfig;\n 6 | use opentelemetry_sdk::{\n 7 | propagation::TraceContextPropagator,\n 8 | runtime,\n 9 | trace::{self as sdktrace, Sampler},\n 10 | };\n 11 | use tracing_opentelemetry::OpenTelemetryLayer;\n 12 | use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};\n 13 |\n 14 | pub fn setup(service_name: &'static str) -> anyhow::Result<()> {\n 15 | let otlp_endpoint = std::env::var(\"MERIDIAN_OTLP_ENDPOINT\").ok();\n 16 | let oo_auth = std::env::var(\"MERIDIAN_OO_AUTH\").ok();\n 17 |\n 18 | if otlp_endpoint.is_none() {\n 19 | // No endpoint configured — install a no-op subscriber only.\n 20 | tracing_subscriber::registry()\n 21 | .with(EnvFilter::from_default_env())\n 22 | .with(tracing_subscriber::fmt::layer())\n 23 | .init();\n 24 | return Ok(());\n 25 | }\n 26 |\n 27 | let endpoint = otlp_endpoint.unwrap();\n 28 | let mut headers = std::collections::HashMap::new();\n 29 | if let Some(auth) = oo_auth {\n 30 | headers.insert(\"Authorization\".to_string(), format!(\"Basic {auth}\"));\n 31 | }\n 32 |\n 33 | let tracer = opentelemetry_otlp::new_pipeline()\n 34 | .tracing()\n 35 | .with_exporter(\n 36 | opentelemetry_otlp::new_exporter()\n 37 | .http()\n 38 | .with_endpoint(&endpoint)\n 39 | .with_headers(headers),\n 40 | )\n 41 | .with_trace_config(\n 42 | sdktrace::config()\n 43 | .with_sampler(Sampler::AlwaysOn)\n 44 | .with_resource(opentelemetry_sdk::Resource::new(vec![\n 45 | opentelemetry::KeyValue::new(\"service.name\", service_name),\n 46 | ])),\n 47 | )\n 48 | .install_batch(runtime::Tokio)\n 49 | .context(\"failed to install OTLP tracer\")?;\n 50 |\n 51 | global::set_text_map_propagator(TraceContextPropagator::new());\n 52 | global::set_tracer_provider(tracer.provider().unwrap());\n 53 |\n 54 | tracing_subscriber::registry()\n 55 | .with(EnvFilter::from_default_env())\n 55 | .with(tracing_subscriber::fmt::layer())\n 56 | .with(OpenTelemetryLayer::new(tracer))\n 57 | .init();\n 58 |\n 59 | Ok(())\n 60 | }\n 61 |\n 62 | pub fn shutdown() {\n 63 | global::shutdown_tracer_provider();\n 64 | }\nRust 1.93.1 | LF | UTF-8 | Ln 14, Col 1\nfeat/golden-dataset-kan-139 ⇣ 0 ⇡ 0 Rust 1.93.1 (via rust-toolchain.toml)\n\n[09:47:08]\nsrc/observability.rs — meridian — Rust\n(developer scrolled to line 33 — the OTLP pipeline setup)\n 33 | let tracer = opentelemetry_otlp::new_pipeline()\n 34 | .tracing()\n 35 | .with_exporter(\n 36 | opentelemetry_otlp::new_exporter()\n 37 | .http()\n 38 | .with_endpoint(&endpoint)\n 39 | .with_headers(headers),\n 40 | )\n 41 | .with_trace_config(\n 42 | sdktrace::config()\n 43 | .with_sampler(Sampler::AlwaysOn)\n 44 | .with_resource(opentelemetry_sdk::Resource::new(vec![\n 45 | opentelemetry::KeyValue::new(\"service.name\", service_name),\n 46 | ])),\n 47 | )\n 48 | .install_batch(runtime::Tokio)\n 49 | .context(\"failed to install OTLP tracer\")?;\n 50 |\n 51 | global::set_text_map_propagator(TraceContextPropagator::new());\n 52 | global::set_tracer_provider(tracer.provider().unwrap());\n(developer hovers over line 48 — tooltip appears)\nTOOLTIP: install_batch(runtime::Tokio)\n pub fn install_batch<R: RuntimeChannel>(self, runtime: R) -> Result<sdk::trace::Tracer, TraceError>\n Install the configured pipeline as a batch OTLP exporter using the given runtime.\n Returns the configured Tracer.\nRust 1.93.1 | LF | UTF-8 | Ln 48, Col 28\n\n[09:47:31]\nsrc/observability.rs — meridian — Rust\n(developer adds a comment above the run_etl span emission section — cross-referencing KAN-136)\n 62 | pub fn shutdown() {\n 63 | global::shutdown_tracer_provider();\n 64 | }\n(cursor moves to end of file — developer considers adding a new helper)\n(types, then deletes)\n+65 | \n+66 | /// Returns a named tracer scoped to the ETL pipeline.\n+67 | /// Each run_etl() call should request this tracer to parent batch spans.\n+68 | pub fn etl_tracer() -> opentelemetry::global::BoxedTracer {\n(backspace × 4 lines — removed)\nRust 1.93.1 | LF | UTF-8 | Ln 64, Col 2\nfeat/golden-dataset-kan-139 ⇣ 0 ⇡ 0\n\n[09:47:55]\nzsh — meridian — TERMINAL\nakarsh@MacBook-Pro meridian % cargo clippy --lib 2>&1\n Compiling meridian v0.6.2 (/Users/akarsh/Documents/Meridiona/meridian)\nwarning: unused import: `global`\n --> src/observability.rs:3:22\n |\n 3 | use opentelemetry::global;\n | ^^^^^^\n |\n = note: `#[warn(unused_imports)]` on by default\n\nwarning: unused variable: `tracer`\n --> src/main.rs:47:9\n |\n47 | let tracer = trace::get_tracer(\"meridian.etl\");\n | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_tracer`\n |\n = note: `#[warn(unused_variables)]` on by default\n\nwarning: `meridian` (lib) generated 2 warnings\nerror[E0599]: no method named `force_flush` found for type `opentelemetry_sdk::trace::TracerProvider` in the current scope\n --> src/observability.rs:63:14\n |\n63 | global::shutdown_tracer_provider();\n |\n note: method `force_flush` exists on `opentelemetry_sdk::trace::TracerProvider`\n help: consider calling `as_any()` first\nerror: could not compile `meridian` (lib) due to 1 previous error; 2 warnings\nakarsh@MacBook-Pro meridian %\n\n[09:48:22]\nzsh — meridian — TERMINAL\n(developer stares at the error — force_flush not found on the global provider)\nakarsh@MacBook-Pro meridian % grep -rn \"force_flush\" src/\nsrc/observability.rs:63: global::shutdown_tracer_provider();\nakarsh@MacBook-Pro meridian % grep -rn \"force_flush\" services/agents/observability.py\nservices/agents/observability.py:38: _provider = trace.get_tracer_provider()\nservices/agents/observability.py:39: if hasattr(_provider, 'force_flush'):\nservices/agents/observability.py:40: _provider.force_flush(timeout_millis=5000)\nservices/agents/observability.py:41: opentelemetry.sdk.trace.export.shutdown()\nakarsh@MacBook-Pro meridian %\n(developer opens the Python observability.py in a split pane to compare)\n\n[09:48:50]\nsrc/observability.rs | services/agents/observability.py (split)\nLEFT PANE — src/observability.rs\n 62 | pub fn shutdown() {\n 63 | global::shutdown_tracer_provider();\n 64 | }\n\nRIGHT PANE — services/agents/observability.py\n 1 | \"\"\"OTel setup and teardown for the Python agent services.\"\"\"\n 2 | from __future__ import annotations\n 3 | import os\n 4 | from opentelemetry import trace\n 5 | from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter\n 6 | from opentelemetry.sdk.trace import TracerProvider\n 7 | from opentelemetry.sdk.trace.export import BatchSpanProcessor\n 8 |\n 9 | _provider: TracerProvider | None = None\n 10 |\n 11 | def setup(service_name: str) -> None:\n 12 | global _provider\n 13 | endpoint = os.environ.get(\"MERIDIAN_OTLP_ENDPOINT\")\n 14 | auth = os.environ.get(\"MERIDIAN_OO_AUTH\")\n 15 | if not endpoint:\n 16 | return # no-op if OTLP not configured\n 17 | exporter = OTLPSpanExporter(\n 18 | endpoint=endpoint,\n 19 | headers={\"Authorization\": f\"Basic {auth}\"} if auth else {},\n 20 | )\n 21 | _provider = TracerProvider(\n 22 | resource=Resource.create({\"service.name\": service_name})\n 23 | )\n 24 | _provider.add_span_processor(BatchSpanProcessor(exporter))\n 25 | trace.set_tracer_provider(_provider)\n 26 |\n 27 | def shutdown() -> None:\n 28 | global _provider\n 29 | if _provider:\n 30 | _provider.force_flush(timeout_millis=5_000)\n 31 | _provider.shutdown()\n 32 |\n(developer comparing both shutdown() implementations side by side)\nRust 1.93.1 | LF | UTF-8 | Ln 63, Col 5 | Python 3.11\n\n[09:49:18]\nsrc/observability.rs — meridian — Rust\n(developer returns to Rust file — edits shutdown() to call force_flush before shutdown)\n 62 | pub fn shutdown() {\n-63 | global::shutdown_tracer_provider();\n+63 | if let Some(provider) = global::tracer_provider()\n+64 | .as_any()\n+65 | .downcast_ref::<opentelemetry_sdk::trace::TracerProvider>()\n+66 | {\n+67 | let _ = provider.force_flush();\n+68 | }\n+69 | global::shutdown_tracer_provider();\n 70 | }\n(status bar: 1 unsaved change)\nRust 1.93.1 | LF | UTF-8 | Ln 70, Col 2\nfeat/golden-dataset-kan-139* ⇣ 0 ⇡ 0 1 unsaved change\n\n[09:49:40]\nzsh — meridian — TERMINAL\nakarsh@MacBook-Pro meridian % cargo clippy --lib 2>&1\n Compiling meridian v0.6.2 (/Users/akarsh/Documents/Meridiona/meridian)\nwarning: unused import: `global`\n --> src/observability.rs:3:22\n |\n 3 | use opentelemetry::global;\n | ^^^^^^\n |\n = note: `#[warn(unused_imports)]` on by default\n\nwarning: `meridian` (lib) generated 1 warning\nerror[E0308]: mismatched types\n --> src/observability.rs:64:10\n |\n63 | if let Some(provider) = global::tracer_provider()\n64 | .as_any()\n | ^^^^^^ method not found in `GlobalTracerProvider`\nerror: could not compile `meridian` (lib) due to 1 previous error; 1 warning\nakarsh@MacBook-Pro meridian %\n(developer frowns — as_any() not available on GlobalTracerProvider directly)\n\n[09:50:05]\nzsh — meridian — TERMINAL\nakarsh@MacBook-Pro meridian % cargo doc --open --package opentelemetry_sdk 2>&1 | tail -5\n Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.43s\n Opening /Users/akarsh/Documents/Meridiona/meridian/target/doc/opentelemetry_sdk/trace/struct.TracerProvider.html\nakarsh@MacBook-Pro meridian %\n(browser opens in background — docs page)\n\nakarsh@MacBook-Pro meridian % grep -rn \"shutdown_tracer_provider\\|force_flush\" \\\n ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/opentelemetry-0.22.0/src/global/trace.rs \\\n 2>/dev/null | head -20\n 44: pub fn shutdown_tracer_provider() {\n 45: let mut tracer_provider = GLOBAL_TRACER_PROVIDER\n 46: .write()\n 47: .expect(\"GLOBAL_TRACER_PROVIDER RwLock poisoned\");\n 48: let _ = tracer_provider.shutdown();\n 49: }\nakarsh@MacBook-Pro meridian %\n(developer sees shutdown_tracer_provider() already calls .shutdown() internally — force_flush is separate on the SDK type)\n\n[09:50:35]\nsrc/observability.rs — meridian — Rust\n(developer reverts the force_flush attempt — goes back to the simpler form, adds a TODO comment)\n 62 | pub fn shutdown() {\n+63 | // TODO(KAN-136): add explicit force_flush before shutdown — requires holding\n+64 | // a reference to the SDK provider, not the global wrapper. See:\n+65 | // opentelemetry_sdk::trace::TracerProvider::force_flush()\n 66 | global::shutdown_tracer_provider();\n 67 | }\n(saves file — Cmd+S)\n(status bar: no unsaved changes)\nRust 1.93.1 | LF | UTF-8 | Ln 67, Col 2\nfeat/golden-dataset-kan-139* ⇣ 0 ⇡ 0 Rust 1.93.1\n\n[09:50:42]\nzsh — meridian — TERMINAL\nakarsh@MacBook-Pro meridian % cargo test --test integration_etl 2>&1 | tail -12\nrunning 6 tests\ntest etl_basic ... ok\ntest etl_gap_detection ... ok\ntest etl_cursor_advance ... ok\ntest etl_cleanup_stale_runs ... ok\ntest etl_concurrent_writes ... ok\ntest etl_observability ... ok (142ms)\ntest result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out\nakarsh@MacBook-Pro meridian %\n(developer closes terminal, does not commit — the TODO comment is the deliverable for now)\nfeat/golden-dataset-kan-139* ⇣ 0 ⇡ 0 1 uncommitted change",
|
|
1134
1134
|
"audio_snippets": [
|
|
1135
1135
|
{
|
|
1136
1136
|
"timestamp": "2026-05-25T09:47:20+05:30",
|
|
@@ -1185,7 +1185,7 @@
|
|
|
1185
1185
|
"count": 3
|
|
1186
1186
|
}
|
|
1187
1187
|
],
|
|
1188
|
-
"session_text": "[09:51:05]\nFile Edit Selection View Go Run Terminal Window Help\nExplorer (⇧⌘E) · feat/golden-dataset-kan-139\nEXPLORER\nMERIDIAN\n scripts/\n install-mlx-server-daemon.sh ← ACTIVE\n setup-services.sh\n uninstall-tagger-daemon.sh\n install-tagger-daemon.sh\n services/\n scripts/\n com.meridiona.mlx-server.plist\n install-mlx-server-daemon.sh\n uninstall-mlx-server-daemon.sh\n src/\n .github/\n workflows/\n ci.yml\n Cargo.toml\n CLAUDE.md\nOUTLINE\n (no outline — shell script)\nSOURCE CONTROL: 2 modified\nfeat/golden-dataset-kan-139 ⇣ 0 ⇡ 0 Shell Script\n\n[09:51:12]\ninstall-mlx-server-daemon.sh — meridian — Shell Script\n 1 | #!/usr/bin/env bash\n 2 | #
|
|
1188
|
+
"session_text": "[09:51:05]\nFile Edit Selection View Go Run Terminal Window Help\nExplorer (⇧⌘E) · feat/golden-dataset-kan-139\nEXPLORER\nMERIDIAN\n scripts/\n install-mlx-server-daemon.sh ← ACTIVE\n setup-services.sh\n uninstall-tagger-daemon.sh\n install-tagger-daemon.sh\n services/\n scripts/\n com.meridiona.mlx-server.plist\n install-mlx-server-daemon.sh\n uninstall-mlx-server-daemon.sh\n src/\n .github/\n workflows/\n ci.yml\n Cargo.toml\n CLAUDE.md\nOUTLINE\n (no outline — shell script)\nSOURCE CONTROL: 2 modified\nfeat/golden-dataset-kan-139 ⇣ 0 ⇡ 0 Shell Script\n\n[09:51:12]\ninstall-mlx-server-daemon.sh — meridian — Shell Script\n 1 | #!/usr/bin/env bash\n 2 | # ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity\n 3 | # Installs the MLX persistent server as a launchd daemon on macOS.\n 4 | # Usage: bash scripts/install-mlx-server-daemon.sh\n 5 | set -euo pipefail\n 6 |\n 7 | PLIST_SRC=\"services/scripts/com.meridiona.mlx-server.plist\"\n 8 | PLIST_DEST=\"$HOME/Library/LaunchAgents/com.meridiona.mlx-server.plist\"\n 9 | LOG_DIR=\"$HOME/.meridian/logs\"\n 10 | VENV=\"$HOME/.meridian/.venv\"\n 11 |\n 12 | if [ ! -f \"$PLIST_SRC\" ]; then\n 13 | echo \"Error: $PLIST_SRC not found. Run from repo root.\"\n 14 | exit 1\n 15 | fi\n 16 |\n 17 | # Ensure log directory exists\n 18 | mkdir -p \"$LOG_DIR\"\n 19 |\n 20 | # Stop existing daemon if running\n 21 | if launchctl list | grep -q \"com.meridiona.mlx-server\"; then\n 22 | echo \"Stopping existing mlx-server daemon...\"\n 23 | launchctl unload \"$PLIST_DEST\" 2>/dev/null || true\n 24 | fi\n 25 |\n 26 | # Expand tilde in plist WorkingDirectory before copying\n 27 | sed -i '' \"s|~|$HOME|g\" \"$PLIST_SRC\"\n 28 |\n 29 | cp \"$PLIST_SRC\" \"$PLIST_DEST\"\n 30 | chmod 644 \"$PLIST_DEST\"\n 31 |\n 32 | launchctl load -w \"$PLIST_DEST\"\n 33 |\n 34 | echo \"mlx-server daemon installed. Check status with:\"\n 35 | echo \" launchctl list | grep com.meridiona.mlx-server\"\n 36 | echo \" tail -f $LOG_DIR/mlx-server.log\"\nShell Script | LF | UTF-8 | Ln 1, Col 1\nfeat/golden-dataset-kan-139 ⇣ 0 ⇡ 0\n\n[09:51:50]\ninstall-mlx-server-daemon.sh — meridian — Shell Script\n(developer notices line 27 — sed -i '' modifies the source plist in-place before copying)\n(adds a comment + fixes the pattern: should copy first, then expand in the copy)\n-27 | sed -i '' \"s|~|$HOME|g\" \"$PLIST_SRC\"\n-29 | cp \"$PLIST_SRC\" \"$PLIST_DEST\"\n+27 | # Copy first, then expand — avoids mutating the source plist\n+28 | cp \"$PLIST_SRC\" \"$PLIST_DEST\"\n+29 | sed -i '' \"s|~|$HOME|g\" \"$PLIST_DEST\"\n(saves — Cmd+S)\nShell Script | LF | UTF-8 | Ln 29, Col 42\nfeat/golden-dataset-kan-139* ⇣ 0 ⇡ 0 1 unsaved change → saved\n\n[09:52:15]\ncom.meridiona.mlx-server.plist — meridian\n 1 | <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n 2 | <!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\"\n 3 | \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n 4 | <plist version=\"1.0\">\n 5 | <dict>\n 6 | <key>Label</key>\n 7 | <string>com.meridiona.mlx-server</string>\n 8 | <key>ProgramArguments</key>\n 9 | <array>\n 10 | <string>~/.meridian/.venv/bin/python</string>\n 11 | <string>-m</string>\n 12 | <string>agents.server</string>\n 13 | </array>\n 14 | <key>WorkingDirectory</key>\n 15 | <string>~/Documents/Meridiona/meridian</string>\n 16 | <key>StandardOutPath</key>\n 17 | <string>~/.meridian/logs/mlx-server.log</string>\n 18 | <key>StandardErrorPath</key>\n 19 | <string>~/.meridian/logs/mlx-server-error.log</string>\n 20 | <key>RunAtLoad</key>\n 21 | <true/>\n 22 | <key>KeepAlive</key>\n 23 | <true/>\n 24 | <key>EnvironmentVariables</key>\n 25 | <dict>\n 26 | <key>MLX_MODEL_ID</key>\n 27 | <string>mlx-community/Phi-4-mini-instruct-4bit</string>\n 28 | <key>MLX_SERVER_PORT</key>\n 29 | <string>7823</string>\n 30 | </dict>\n 31 | </dict>\n 32 | </plist>\n(developer notes: line 10/15 still have ~ — not yet expanded, correct since install script handles that)\nXML | LF | UTF-8 | Ln 10, Col 40\n\n[09:52:50]\nzsh — meridian — TERMINAL\nakarsh@MacBook-Pro meridian % bash scripts/install-mlx-server-daemon.sh\nmkdir: /Users/akarsh/.meridian/logs: File exists\nStopping existing mlx-server daemon...\nmlx-server daemon installed. Check status with:\n launchctl list | grep com.meridiona.mlx-server\n tail -f /Users/akarsh/.meridian/logs/mlx-server.log\nakarsh@MacBook-Pro meridian % launchctl list | grep com.meridiona.mlx-server\n-\t0\tcom.meridiona.mlx-server\nakarsh@MacBook-Pro meridian % sleep 3 && curl -s http://localhost:7823/health | python3 -m json.tool\n{\n \"status\": \"ok\",\n \"model\": \"mlx-community/Phi-4-mini-instruct-4bit\",\n \"port\": 7823\n}\nakarsh@MacBook-Pro meridian %\n(daemon is running — health check passes)\n\n[09:53:20]\nzsh — meridian — TERMINAL\nakarsh@MacBook-Pro meridian % cat ~/.meridian/logs/mlx-server.log | tail -20\n2026-05-25 09:52:48 INFO [agents.server] loading model mlx-community/Phi-4-mini-instruct-4bit\n2026-05-25 09:52:53 INFO [agents.server] model loaded in 4.8s, 4-bit quantized, 3.8 GB\n2026-05-25 09:52:53 INFO [agents.server] MLX server ready on :7823\n2026-05-25 09:52:54 INFO [agents.server] GET /health → 200 (2ms)\nakarsh@MacBook-Pro meridian %\n\nakarsh@MacBook-Pro meridian % git diff scripts/install-mlx-server-daemon.sh\ndiff --git a/scripts/install-mlx-server-daemon.sh b/scripts/install-mlx-server-daemon.sh\nindex 8a3c2d1..f4e9b20 100755\n--- a/scripts/install-mlx-server-daemon.sh\n+++ b/scripts/install-mlx-server-daemon.sh\n@@ -24,8 +24,9 @@ fi\n \n-# Expand tilde in plist WorkingDirectory before copying\n-sed -i '' \"s|~|$HOME|g\" \"$PLIST_SRC\"\n-\n-cp \"$PLIST_SRC\" \"$PLIST_DEST\"\n+# Copy first, then expand — avoids mutating the source plist\n+cp \"$PLIST_SRC\" \"$PLIST_DEST\"\n+sed -i '' \"s|~|$HOME|g\" \"$PLIST_DEST\"\nakarsh@MacBook-Pro meridian %\n\n[09:54:00]\ninstall-mlx-server-daemon.sh — meridian — Shell Script\n(developer opens setup-services.sh to see if it has the same sed pattern)\nsetup-services.sh — meridian — Shell Script\n 1 | #!/usr/bin/env bash\n 2 | # ambient dev tool that watches what you do and updates your PM tickets automatically, boosting developer productivity\n 3 | # Master installer: sets up Rust daemon + MLX server + tagger daemon in sequence.\n 4 | set -euo pipefail\n 5 |\n 6 | echo \"=== Meridian one-click install ===\"\n 7 | echo \"This will install:\"\n 8 | echo \" 1. Meridian Rust daemon (launchd)\"\n 9 | echo \" 2. MLX classification server (launchd)\"\n 10 | echo \" 3. Tagger daemon (launchd)\"\n 11 |\n 12 | # Step 1 — build the Rust binary\n 13 | cargo build --release\n 14 |\n 15 | # Step 2 — install launchd agents\n 16 | bash scripts/install-mlx-server-daemon.sh\n 17 | bash scripts/install-tagger-daemon.sh\n 18 |\n 19 | # Step 3 — run the Rust daemon directly to check it starts clean\n 20 | RUST_LOG=meridian=info ./target/release/meridian &\n 21 | DAEMON_PID=$!\n 22 | sleep 5\n 23 | kill $DAEMON_PID\n 24 |\n 25 | echo \"=== Install complete ===\"\nShell Script | LF | UTF-8 | Ln 16, Col 40\n(no sed pattern in setup-services.sh — the plist expansion only in install-mlx-server-daemon.sh)\n\n[09:54:40]\ninstall-mlx-server-daemon.sh — meridian — Shell Script\n(developer adds a --dry-run flag to the install script)\n 35 | launchctl load -w \"$PLIST_DEST\"\n+36 |\n+37 | # Print final status\n 38 | echo \"mlx-server daemon installed. Check status with:\"\n 39 | echo \" launchctl list | grep com.meridiona.mlx-server\"\n 40 | echo \" tail -f $LOG_DIR/mlx-server.log\"\n(adds DRY_RUN support above line 21)\n+21 | DRY_RUN=\"${DRY_RUN:-0}\"\n+22 | if [ \"$DRY_RUN\" = \"1\" ]; then\n+23 | echo \"[dry-run] would install $PLIST_SRC → $PLIST_DEST\"\n+24 | exit 0\n+25 | fi\nShell Script | LF | UTF-8 | Ln 25, Col 10\nfeat/golden-dataset-kan-139* ⇣ 0 ⇡ 0 1 unsaved change\n\n[09:55:10]\nzsh — meridian — TERMINAL\nakarsh@MacBook-Pro meridian % DRY_RUN=1 bash scripts/install-mlx-server-daemon.sh\n[dry-run] would install services/scripts/com.meridiona.mlx-server.plist → /Users/akarsh/Library/LaunchAgents/com.meridiona.mlx-server.plist\nakarsh@MacBook-Pro meridian %\n(dry-run works — saves and stages)\nakarsh@MacBook-Pro meridian % git add scripts/install-mlx-server-daemon.sh\nakarsh@MacBook-Pro meridian % git status\nOn branch feat/golden-dataset-kan-139\nChanges to be committed:\n (use \"git restore --staged <file>...\" to unstage)\n modified: scripts/install-mlx-server-daemon.sh\nfeat/golden-dataset-kan-139* ⇣ 0 ⇡ 1 1 staged change",
|
|
1189
1189
|
"audio_snippets": [
|
|
1190
1190
|
{
|
|
1191
1191
|
"timestamp": "2026-05-25T09:51:45+05:30",
|
package/ui.tar.gz
CHANGED
|
Binary file
|