daimon 0.7.0 → 0.8.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/cli.js +178 -74
  3. package/dist/dashboard/browser/{chunk-YNCTXEXX.js → chunk-2BXIFQGQ.js} +1 -1
  4. package/dist/dashboard/browser/{chunk-6BDWIJ3G.js → chunk-3WKRVGPT.js} +1 -1
  5. package/dist/dashboard/browser/chunk-44JIQO3X.js +1 -0
  6. package/dist/dashboard/browser/chunk-4BAKWDAV.js +1 -0
  7. package/dist/dashboard/browser/chunk-4OCNYL7T.js +1 -0
  8. package/dist/dashboard/browser/chunk-6WZJCF24.js +1 -0
  9. package/dist/dashboard/browser/chunk-7C772RJ3.js +3 -0
  10. package/dist/dashboard/browser/{chunk-25VLDASM.js → chunk-7NPLP3QD.js} +1 -1
  11. package/dist/dashboard/browser/chunk-A4BNXJUT.js +1 -0
  12. package/dist/dashboard/browser/{chunk-YA4AZONZ.js → chunk-CM4RQF3A.js} +1 -1
  13. package/dist/dashboard/browser/chunk-CNSXWFDX.js +1 -0
  14. package/dist/dashboard/browser/chunk-CY5YRTQK.js +1 -0
  15. package/dist/dashboard/browser/{chunk-5PAHWCG5.js → chunk-EIWOTZT3.js} +1 -1
  16. package/dist/dashboard/browser/{chunk-ZEO5YLWG.js → chunk-GYWEXV2L.js} +1 -1
  17. package/dist/dashboard/browser/chunk-H2N3RBHF.js +1 -0
  18. package/dist/dashboard/browser/{chunk-RIDV4B55.js → chunk-H3L4MTG4.js} +1 -1
  19. package/dist/dashboard/browser/{chunk-ZVUH3ISD.js → chunk-I65I7J5Q.js} +1 -1
  20. package/dist/dashboard/browser/chunk-K7S4ITPJ.js +2 -0
  21. package/dist/dashboard/browser/chunk-KL6X73FV.js +1 -0
  22. package/dist/dashboard/browser/{chunk-Q3N4MMWW.js → chunk-LBL7Z5BE.js} +4 -4
  23. package/dist/dashboard/browser/chunk-LHAMBNO6.js +1 -0
  24. package/dist/dashboard/browser/chunk-NX6DTO32.js +1 -0
  25. package/dist/dashboard/browser/chunk-P5IE6DI6.js +2 -0
  26. package/dist/dashboard/browser/{chunk-SR5JAOLW.js → chunk-Q772THBA.js} +1 -1
  27. package/dist/dashboard/browser/{chunk-OUXULJ3Z.js → chunk-QSBOKS53.js} +1 -1
  28. package/dist/dashboard/browser/{chunk-HYGMRGYR.js → chunk-V2KNRAE4.js} +1 -1
  29. package/dist/dashboard/browser/{chunk-GDJOSLWM.js → chunk-VM2FOT77.js} +1 -1
  30. package/dist/dashboard/browser/index.html +1 -1
  31. package/dist/dashboard/browser/main-4CQTBXSB.js +1 -0
  32. package/dist/main.js +58 -48
  33. package/dist/mcp.js +3 -3
  34. package/package.json +2 -2
  35. package/src/templates/claude/skill.md.tmpl +4 -1
  36. package/src/templates/plugins/example-doctor.mjs +45 -0
  37. package/dist/dashboard/browser/chunk-6C6GHU3A.js +0 -1
  38. package/dist/dashboard/browser/chunk-BDYOKQF3.js +0 -1
  39. package/dist/dashboard/browser/chunk-HYIZMKSF.js +0 -1
  40. package/dist/dashboard/browser/chunk-IQZZO5IM.js +0 -3
  41. package/dist/dashboard/browser/chunk-J5UK77OJ.js +0 -1
  42. package/dist/dashboard/browser/chunk-JI63U3KC.js +0 -2
  43. package/dist/dashboard/browser/chunk-L2PHC6DL.js +0 -1
  44. package/dist/dashboard/browser/chunk-MHYQENOC.js +0 -1
  45. package/dist/dashboard/browser/chunk-UU5K6ZPO.js +0 -1
  46. package/dist/dashboard/browser/chunk-XXIJQBCQ.js +0 -2
  47. package/dist/dashboard/browser/chunk-ZDNBWNU5.js +0 -1
  48. package/dist/dashboard/browser/main-IDF27PFI.js +0 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,63 @@ All notable changes to Daimon are documented here. The format follows [Keep a Ch
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.8.0] — 2026-05-20
8
+
9
+ Strategic theme: **Mature daimon.** v0.5–v0.7 added enormous surface; v0.8 turns inward to polish the surface and harden the internals — a big CLI polish, a reliability pass, self-observability, and a plug-in surface for doctor rules, plus a first-class Tests page that finally lands part of the v0.7.1 dashboard-test debt (H3 contrast audit deferred again to v0.8.1).
10
+
11
+ ### Added (M45) — Tests dashboard + H1 carry-over
12
+
13
+ - **T1 — Structured `test`-target summaries.** `parseTaskSummary` (in `src/taskRunner.ts`) now recognizes seven runners: Jest, Vitest, Karma, Playwright, pytest, RSpec, `cargo test`, and `go test` (the last sums multi-package `ok|FAIL pkg D.DDDs` lines). Output shape is now `{ passed, failed, total, suites?, durationMs?, framework, failedTests? }`. `failedTests` captures `{ name, file, line }` from the per-runner failure formatting and is the source of the dashboard's failed-test jumper. `task_runs.summary` continues to be a JSON blob — the new fields are additive.
14
+ - **T2 — `Tests` dashboard route (`/tests`).** New lazy-loaded route. One expansion-panel per app with at least one `test`-named run in the last 30 days. Title row carries an OK / FAIL pill + `passed/total · N failed` label + framework + duration + "<N>m ago" + run count. Body shows a 30-row pass/fail trend ribbon (one tick per run) and, when the most-recent run failed, an inline list of failed tests.
15
+ - **T3 — Failed-test jumper.** Each failed-test row that carries a `{ file, line? }` payload renders a clickable `vscode://file/<path>:<line>` link, identical scheme to the M22 errors panel.
16
+ - **T4 — Nav + shortcut.** New `/tests` entry on the nav rail (`science` icon) and `g x` keyboard chord, alongside the existing `g t`/`g h`/etc. shortcuts.
17
+ - **H1 (carry-over — third schedule slot, partial).** Vitest harness shipped at `dashboard/vitest.config.ts`. Five specs in `dashboard/src/app/tests-page.spec.ts` cover the pure signal-bearing logic — `parseSummary`, `vscodeUri`, `summaryLabel`, `pillKindFor` — extracted into `tests-page-helpers.ts` to keep them runtime-independent. `dashboard/package.json` `test` script is now `vitest run` (no `ng test --watch=false` blocker). The deeper per-component render coverage requires an Angular-linker preset (e.g. `@analogjs/vitest-angular`) — that preset has been moved to v0.9 to keep M45 inside one weekend. Playwright smoke similarly deferred. See `PLAN-v0.8.md` Status section for the trade-off.
18
+ - **H3 — WCAG AA contrast audit.** Deferred to v0.8.1 per the locked descope path (`"If M45 grows, drop H3 first"`). M3 surface-tonal defaults from v0.7 still apply; the dedicated AA sweep across light + dark + reduced-motion remains a focused future pass.
19
+ - **Test surface.** New `test/task-summary.test.mjs` asserts the parser for jest / vitest / pytest / rspec / cargo / go / playwright / null. `dashboard/src/app/tests-page.spec.ts` exercises the five tests-page helpers under Vitest.
20
+
21
+ ### Added (M44) — Plug-in surface for doctor rules
22
+
23
+ - **P1 — Plug-in loader.** New `src/plugins.ts`. On daemon start, daimon scans `~/.daimon/plugins/doctor-*.mjs` (configurable via `plugins.dir` in `daimon.config.json`). Each file is dynamically imported with a cache-busting query string so plug-ins can be hot-edited and reloaded by restarting the daemon. Files that fail to import (or fail shape validation) are logged as `[daimon] plug-in skipped: <file> — <reason>` and never crash the daemon.
24
+ - **P2 — Typed `DoctorPlugin` interface.** Defaults to a read-only `scan(ctx)`. Optional `fix(finding, ctx)` and `undo(finding, ctx)`. `DoctorContext` exposes `{ config, apps, history.querySelfMetrics, mutations }` — the `mutations` surface is intentionally narrow and re-uses the M36 mutation primitives (no shell-out, no package-manager calls, no edits to user source).
25
+ - **P3 — Permission gating is fully opt-in.** No plug-in's `fix` ever runs unless its `name` is in `doctor.autoFix.permitted` — the same gate built-in rules use. This applies uniformly to the bundled sample (`src/templates/plugins/example-doctor.mjs`) and to any user-authored plug-in. The loader does **not** track plug-in origin; there is no "bundled / trusted" branch. The loader also rejects names that collide with built-in rules or with another plug-in already loaded in the same pass.
26
+ - **P4 — `daimon plugin list|show <name>|validate <path>`.** New CLI subcommands. `list` returns installed plug-ins with `{name, description, file, status, error, findings}`. `show <name>` prints one plug-in's manifest + last-run findings. `validate <path>` sanity-checks a plug-in file *without* loading it into the running daemon (useful during development). New HTTP endpoints: `GET /api/plugins`, `POST /api/plugins/scan`.
27
+ - **P5 — Sample plug-in template.** `src/templates/plugins/example-doctor.mjs` ships in the tarball (~1.8 KB). Demonstrates a complete `scan` + `fix` cycle with the one-line opt-in instruction. Used as the on-ramp for the permission model — the comment block documents the exact `permitted: [..., 'example-doctor']` line a user must add to enable the `fix`.
28
+ - **P6 — Dashboard surfacing.** Doctor page gains a "Custom rules" section. One card per plug-in with a status chip (`ok` / `failed`), description, file path, error detail (when failed), and per-finding rows with severity chips. Errors surface in the card header. Reuses existing M3 token styling — no new tokens.
29
+ - **P7 — Skill text update.** `~/.claude/skills/daimon/SKILL.md` now lists `daimon plugin list|show|validate`, `daimon self`, `daimon doctor --self`, and `daimon completion` so agents can document a workspace's plug-in surface when asked.
30
+ - **Decisions locked in.** Plug-in surface in v0.8 is **doctor-only** — parser-hint and event-hook plug-ins are deferred to v0.9+ until real-world plug-ins inform the right shape.
31
+ - **Test surface.** New `test/plugins.test.mjs` asserts (1) only `doctor-*.mjs` files are picked up, (2) malformed plug-ins are reported as failed without crashing the loader, (3) names that collide with built-ins are rejected, (4) `runPluginScans` populates `lastFindings` and survives a throwing scan by quarantining the plug-in, and (5) `validatePluginFile` works standalone.
32
+
33
+ ### Added (M43) — Self-observability
34
+
35
+ - **O1 — `GET /api/self`.** New endpoint returning daimon's own metrics: `{ pid, version, uptimeMs, rssMB, heapUsedMB, heapTotalMB, eventLoopLagMs, eventLoopLagP95Ms, historyDbQueryMs:{p50,p95,p99}, lockContentionCount, tickIntervalMs, lastTickAt }`. Backed by a new `SelfMetricsCollector` (in `src/selfMetrics.ts`) that probes event-loop lag with a 1s `setInterval` delta and rolls a 60-sample sliding window. `lockContentionCount` and the `historyDbQueryMs` percentiles are wired through call-site instrumentation (additive).
36
+ - **O2 — `daimon doctor --self`.** New `--self` flag on `daimon doctor` runs self-checks: heap above 256 MB, event-loop lag p95 above 100 ms, history-db query p95 above 50 ms. Reports findings in the same `{ok, checks, metrics}` shape as the existing F58 doctor rules. Read-only by design (no auto-fix — self issues require a daemon restart or config tuning).
37
+ - **O3 — `self_metrics` table in history.db.** New `self_metrics(id, ts, rssMB, heapUsedMB, eventLoopLagMs, historyQueryP95Ms)` table created by the existing `CREATE TABLE IF NOT EXISTS` migration — v0.7 databases upgrade in place. The daemon persists one row per minute via the new `History.recordSelfMetric`. Retention follows the existing `history.retentionDays` policy. `daimon snapshot <name>` carries the last 60 rows as `payload.selfMetrics` for diagnostic context.
38
+ - **O4 — Self chart on the Trends dashboard route.** New "Apps / Self" toggle on `/trends`. When **Self** is selected, an additional `dm-trend-chart` card renders rssMB / heapUsedMB / eventLoopLagMs as line series from `/api/self/history`. Reuses the existing chart.js lazy chunk — initial-route gzip stays at **126.46 KB** (v0.7 baseline 126.45 KB, ceiling 130 KB).
39
+ - **O5 — Self-warn events.** When the event-loop lag exceeds 100 ms for ≥5 consecutive ticks, `SelfMetricsCollector` emits a synthetic `{ app:'__daemon__', type:'self-warn', message:'event loop lag sustained: <N>ms (<K> consecutive ticks)' }` event. Surfaces on the existing Events feed alongside per-app events. New `'self-warn'` value in `AppEventType`; the loader only re-fires on rising-edge transitions to avoid flooding.
40
+ - **Test surface.** New `test/self-metrics.test.mjs` asserts (1) `snapshot()` returns plausible pid/version/rss/heap/uptime/lag numbers, (2) `recordQueryMs` correctly feeds the p50/p95/p99 percentile estimates, and (3) the self-warn setter is wired without throwing.
41
+
42
+ ### Added (M42) — Reliability pass
43
+
44
+ - **F1 — Parser fuzz tests.** New `test/parser-fuzz.test.mjs` feeds 2,000 deterministically-random mixed-ANSI / multibyte / lone-surrogate / multiline-fragment lines into `parseLine`. Asserts no exceptions, no >10ms slow tail above 2% of iterations, and total time <10s per run. Two regression cases cover empty / whitespace / ANSI-only input and lone surrogate halves.
45
+ - **F2 — History.db stress test.** New `test/history-stress.test.mjs` inserts 100,000 events + 50,000 compile rows + 10,000 bundle rows into a temp sqlite (flushing in 5k-row batches via a new `History._flushForTest()` escape hatch), then queries `/api/history/trends` for every (metric × window × app) combination across three passes. Asserts trends p95 <50ms, p99 <200ms, db size <50MB.
46
+ - **F4 — Lock-file contention.** New `test/lock-contention.test.mjs` isolates `~/.daimon` via temp `HOME`/`USERPROFILE`, then asserts (1) `readLock` tolerates missing/corrupt files, (2) it prunes stale locks pointing at dead PIDs, and (3) parallel `writeLock` calls leave exactly one parseable JSON lock — atomic rename never produces a partial payload.
47
+ - **F5 — Error-map TTL.** New optional `errorRetention.maxAgeMs` config (default `86400000` — 24h) prunes `AppState.errors` entries older than `maxAgeMs` and not seen since. A new `Registry.pruneOldErrors()` walks every app's error map; the daemon wires it on an hourly tick in `main.ts`. Prevents unbounded growth in long-running daemons.
48
+ - **F6 — Log buffer cap audit.** New regression in `test/reliability.test.mjs` exercises the per-app `logBuffer` with a 10,000-line burst and asserts the rolling window stays at `LOG_BUFFER_MAX` and contains exactly the latest 500 lines.
49
+ - **F3 — Daemon crash auto-recovery soak (manual).** Documented in `test/SOAK.md` — 30-iteration kill-and-respawn loop with assertions on orphan PIDs and stale-lock pruning. Not run in CI (would dominate suite budget).
50
+ - **F7 — Memory soak (manual).** Documented in `test/SOAK.md` — 24h procedure with 5 simulated apps, capturing baseline RSS via `daimon self` and the new M43 `self_metrics` table. Acceptance: <10% RSS growth over 24h.
51
+
52
+ ### Added (M41) — CLI polish
53
+
54
+ - **C1 — Unified help system.** `daimon --help` now groups commands by category (lifecycle / queries / agent verbs / introspection / config / claude / plugin). Per-command help is available as `daimon <verb> --help` (or `daimon help <verb>`) and follows a single template — synopsis, description, options table, examples, exit codes — driven entirely by `cliSurface.ts` so help, completion, and skill text cannot drift.
55
+ - **C2 — Shell completions.** New `daimon completion <bash|zsh|fish|powershell>` emits a completion script to stdout for the chosen shell. All four shells supported at launch. Completions cover verbs, aliases, and common flags; the bash/PowerShell scripts also auto-complete app names by querying a running daemon (`--no-spawn` is used to avoid starting one for completion).
56
+ - **C3 — Color and TTY awareness.** New `--no-color` flag and `NO_COLOR` env var disable ANSI coloring. When stdout is **not** a TTY (the agent / piped case), output is **never** colored — compact JSON default from M26 is preserved unchanged. TTY mode colors errors red, hints dim, headings bold, keywords cyan. `FORCE_COLOR=1` honored as the per-CI override.
57
+ - **C4 — Levenshtein "did-you-mean" suggestions.** Unknown commands and unknown apps now emit a `did you mean '<X>'?` hint. Tuned to a 2-edit-distance threshold to avoid noise. Apps lookup polls the running daemon.
58
+ - **C5 — Flag convention block in `--help`.** A new "flag conventions" section in the main help documents the canonical flag vocabulary (`--timeout`, `--since`, `--budget`, `--until`, `--app`, `--profile`, `--full/--compact`, `--stream`, `--explain`, `--dry-run`, `--yes`). No flag renames — convergence is documented.
59
+ - **C6 — Muscle-memory aliases.** New aliases: `daimon ls` → `list`, `daimon ps` → `status`, `daimon log` → `logs`. Aliases are documented in `--help` but not duplicated in the main verb list and do not conflict with existing verbs.
60
+ - **C7 — Error message rewrite.** CLI errors now carry a `{ "error": "<short>", "hint": "<actionable next step>", "exit": <code> }` shape in JSON (piped) mode. TTY mode renders the one-line human variant (`error: …` + dim `hint: …`). The "daimon is not running" error nudges the user to `daimon daemon start --detach`. Unknown command / unknown app errors carry suggestions.
61
+ - **C8 — `daimon --version` / `daimon --about`.** `--version` now prints the bare SemVer string (was `{"version":"..."}`). `--about` prints `{version, nodeVersion, platform, configPath, lockPath, running, runningPid, runningPort, claudeArtifacts}` — useful for bug reports. `daimon self` (new lightweight verb) reaches the daemon's `/api/self` endpoint introduced in M43.
62
+ - **Test surface.** New `test/cli-surface.test.mjs` asserts every subcommand has the full help template, aliases resolve to canonical verbs, did-you-mean returns sensible candidates within 2 edits, and the completion script generator produces non-empty output for all four shells.
63
+
7
64
  ## [0.7.0] — 2026-05-20
8
65
 
9
66
  Strategic theme: **Memory and reach.** v0.7 makes the *past* actionable (history surfaces) and broadens *what* daimon can manage (polyglot dev servers, whole-workspace orchestration, refreshed TUI).