openwolf-enhanced 1.20.9 → 1.22.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 (66) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/README.md +96 -31
  3. package/dist/dashboard/assets/{AISuggestions-0zrodHvB.js → AISuggestions-Cpup2r93.js} +1 -1
  4. package/dist/dashboard/assets/{ActivityLog-DYEe6Mh-.js → ActivityLog-vc08HmGa.js} +1 -1
  5. package/dist/dashboard/assets/{ActivityTimeline-BPomzQWf.js → ActivityTimeline-fatU3zUR.js} +1 -1
  6. package/dist/dashboard/assets/{AnatomyBrowser-D3m69d-p.js → AnatomyBrowser-CMsbTK8b.js} +1 -1
  7. package/dist/dashboard/assets/{BugLog-C44GE8m7.js → BugLog-s5Pex7fA.js} +1 -1
  8. package/dist/dashboard/assets/{CerebrumViewer-CxvLTVFs.js → CerebrumViewer-D5i0Yd88.js} +1 -1
  9. package/dist/dashboard/assets/{CronStatus-DCiCUVLZ.js → CronStatus-3S4D9sES.js} +1 -1
  10. package/dist/dashboard/assets/{DesignQC-w7X5uW1P.js → DesignQC-CeR_JqlS.js} +1 -1
  11. package/dist/dashboard/assets/LinkGraph-BTiwJzrc.js +1 -0
  12. package/dist/dashboard/assets/{MemoryViewer-CraLooQx.js → MemoryViewer-QOXI9jv8.js} +1 -1
  13. package/dist/dashboard/assets/{NativeMemory-CaYixCd2.js → NativeMemory-CoSRp5Q2.js} +1 -1
  14. package/dist/dashboard/assets/{ProjectOverview-DJacADHV.js → ProjectOverview-G0xzHTJm.js} +1 -1
  15. package/dist/dashboard/assets/{ProjectsAggregate-xpOM2n6T.js → ProjectsAggregate-BGn850vY.js} +1 -1
  16. package/dist/dashboard/assets/{StatusBadge-CzoOrUrs.js → StatusBadge-DxWVdzKK.js} +1 -1
  17. package/dist/dashboard/assets/{TokenUsage-BUL-gsby.js → TokenUsage-BTTrcgDP.js} +2 -2
  18. package/dist/dashboard/assets/{index-BZOA5m43.js → index-CCxQQi4q.js} +3 -3
  19. package/dist/dashboard/assets/index-CVfvTpSA.css +2 -0
  20. package/dist/dashboard/index.html +2 -2
  21. package/dist/hooks/session-start.js +4 -1
  22. package/dist/hooks/shared.js +103 -2
  23. package/dist/hooks/stop.js +5 -1
  24. package/dist/src/cli/find-cmd.js +163 -0
  25. package/dist/src/cli/find-cmd.js.map +1 -0
  26. package/dist/src/cli/index.js +10 -0
  27. package/dist/src/cli/index.js.map +1 -1
  28. package/dist/src/cli/recall-cmd.js +18 -1
  29. package/dist/src/cli/recall-cmd.js.map +1 -1
  30. package/dist/src/cli/report-cmd.js +20 -1
  31. package/dist/src/cli/report-cmd.js.map +1 -1
  32. package/dist/src/cli/scan.js +31 -0
  33. package/dist/src/cli/scan.js.map +1 -1
  34. package/dist/src/cli/status.js +4 -1
  35. package/dist/src/cli/status.js.map +1 -1
  36. package/dist/src/daemon/cron-engine.js +9 -1
  37. package/dist/src/daemon/cron-engine.js.map +1 -1
  38. package/dist/src/daemon/wolf-daemon.js +53 -0
  39. package/dist/src/daemon/wolf-daemon.js.map +1 -1
  40. package/dist/src/hooks/session-start.js +4 -1
  41. package/dist/src/hooks/session-start.js.map +1 -1
  42. package/dist/src/hooks/shared.js +103 -2
  43. package/dist/src/hooks/shared.js.map +1 -1
  44. package/dist/src/hooks/stop.js +5 -1
  45. package/dist/src/hooks/stop.js.map +1 -1
  46. package/dist/src/mcp/server.js +32 -0
  47. package/dist/src/mcp/server.js.map +1 -1
  48. package/dist/src/scanner/anatomy-scanner.js +29 -5
  49. package/dist/src/scanner/anatomy-scanner.js.map +1 -1
  50. package/dist/src/scanner/import-graph.js +206 -0
  51. package/dist/src/scanner/import-graph.js.map +1 -0
  52. package/dist/src/scanner/treesitter-extractor.js +226 -0
  53. package/dist/src/scanner/treesitter-extractor.js.map +1 -0
  54. package/dist/src/tracker/token-ledger.js +1 -0
  55. package/dist/src/tracker/token-ledger.js.map +1 -1
  56. package/dist/src/utils/agent-hooks.js +73 -9
  57. package/dist/src/utils/agent-hooks.js.map +1 -1
  58. package/dist/src/utils/link-graph.js +183 -0
  59. package/dist/src/utils/link-graph.js.map +1 -0
  60. package/dist/src/utils/maintenance.js +20 -0
  61. package/dist/src/utils/maintenance.js.map +1 -1
  62. package/dist/src/utils/marker-block.js +68 -0
  63. package/dist/src/utils/marker-block.js.map +1 -0
  64. package/package.json +4 -2
  65. package/src/templates/cron-manifest.json +32 -10
  66. package/dist/dashboard/assets/index-Cr3yWM5G.css +0 -2
package/CHANGELOG.md CHANGED
@@ -6,6 +6,122 @@ This is a fork of [OpenWolf](https://github.com/cytostack/openwolf) by Cytostack
6
6
  Pvt Ltd. Versions ≤ 1.0.4 refer to the upstream project; `1.1.0` is the first
7
7
  release of this fork.
8
8
 
9
+ ## [1.22.0] — 2026-08-20
10
+
11
+ **Contains a privacy fix. If you run the background daemon with an API key exported, read the
12
+ first entry.**
13
+
14
+ ### Fixed
15
+
16
+ - 🔒 **The scheduled AI tasks sent `<private>` content to an LLM API.** Two tasks ship in the
17
+ manifest — `cerebrum-reflection` (Sundays, reads `cerebrum.md`) and `project-suggestions`
18
+ (Mondays, reads `memory.md` and `anatomy.md`) — and until now the cron engine read those files
19
+ **raw**. Every other path that leaves the machine strips private regions first: `push`, `recall`
20
+ and `consolidate` all route through `blocksFor()`. This one did not, which made the README's
21
+ promise ("kept out of anything OpenWolf sends elsewhere") untrue once a week.
22
+
23
+ **Who was affected:** anyone whose daemon was running (`openwolf init` starts it automatically
24
+ when pm2 is installed), with the cron engine enabled, an API key exported in the daemon's
25
+ environment, and `<private>` blocks in `cerebrum.md`, `memory.md` or `anatomy.md`. If any of
26
+ those four is missing, nothing private was sent.
27
+
28
+ The fix strips at the read, and a regression test anchors on the read itself rather than on a
29
+ nearby symbol — so a second, unstripped context path fails the suite instead of shipping.
30
+
31
+ - 🔒 **A `<private>` written *about* disabled the knowledge base.** Matching is fail-closed by
32
+ design (1.20.5): an opening tag with no closing tag redacts to end of file, because a forgotten
33
+ tag must never mean "not private". But the match did not distinguish a marker from a mention.
34
+ This project's own `MEMORY.md` describes a bug using the words `` `<private>` `` in backticks —
35
+ and that one mention silently hid **104 of its 114 lines** from `recall`, from the resume digest,
36
+ from the semantic index. Code spans and fences are now masked before tags are located. The
37
+ security property is unchanged and covered by four tests, including that a fenced mention does
38
+ not disarm a real marker later in the same file.
39
+
40
+ ### Changed
41
+
42
+ - **The two AI cron tasks now ship disabled.** Something that sends project knowledge to a third
43
+ party should require a deliberate switch-on, not a deliberate switch-off. ⚠️ This only affects
44
+ **new** projects: `cron-manifest.json` is user data and `openwolf update` never rewrites it.
45
+ - **`openwolf doctor` now warns an existing install** when scheduled tasks would send files and an
46
+ API key is present, naming the tasks and the files. That is how projects created before this
47
+ release find out.
48
+ - **Corrected the upstream claims in the README.** It stated that `cytostack/openwolf` was
49
+ unmaintained and last released 1.0.4 in March 2026. That is false: upstream shipped a 2.x line
50
+ and is actively developed. The two are separate lineages — this package forked 1.x and never
51
+ adopted the 2.x rewrite — and the README now says so, in both languages.
52
+
53
+ ### Added
54
+
55
+ - **Backlinks and a link graph.** Citations were one-way: you could open an entry by id but not ask
56
+ who leans on it. `recall --id` now lists "Referenced by", and a new **Links** panel in the
57
+ dashboard draws the graph, ranks notes by how often they are referenced, and names dead
58
+ references instead of swallowing them. The graph shows the 90 best-connected notes on purpose —
59
+ drawing all 324 produced a hairball, and the caption says what is not drawn.
60
+ - The graph reads citation ids, `[[wikilinks]]` and markdown index links. Three calibration bugs
61
+ were found and fixed while building it: bracket patterns inside code were counted as links (10 of
62
+ 17 reported dead links were Odoo array literals), the link-text bound was 160 characters against
63
+ a measured 473, and file keys collided between `.wolf/memory.md` and `native/MEMORY.md`.
64
+
65
+ ## [1.21.0] — 2026-08-20
66
+
67
+ The honest-ledger release. Three additions, and one number that stops flattering itself.
68
+
69
+ ### Added
70
+
71
+ - **Injection accounting.** The savings figure counted only what OpenWolf avoided and never what
72
+ it costs. Every resume digest and every reminder block is context the model pays for, and none
73
+ of it appeared anywhere — a ledger with one side is how "898 million tokens saved" stayed
74
+ plausible for months (see 1.20.8). There are exactly two injection points, and both now book
75
+ into `lifetime.injection_tokens_estimated`. `report`, `status` and the dashboard show
76
+ reads-avoided, injected, and the net. **The net may go negative on purpose**: a metric that
77
+ cannot look bad measures nothing.
78
+ - **`openwolf find <query>`.** Locates a symbol or file without a repo-wide grep, ranked from the
79
+ index the scanner already writes — no second index that can go stale unnoticed. Symbol hits carry
80
+ exact line ranges, so the next step is a targeted `offset`/`limit` read instead of loading the
81
+ file. Also available as `--json` and as the MCP tool **`openwolf_find`**, which is the point: an
82
+ agent can ask where something lives instead of reading a file to find out.
83
+ - **Import-graph importance.** Ties in `find` break on PageRank over the project's own import graph.
84
+ Only project-internal relative imports count, and an unresolvable specifier creates no edge —
85
+ invented edges skew importance invisibly. Stored as a **rank percentile**, not the raw score:
86
+ measured on this repo the raw distribution was so skewed (median 0.058 against a maximum of 1.0)
87
+ that 118 of 158 files collapsed into the lowest bar.
88
+ - **tree-sitter symbol ranges (optional).** The regex extractor guesses a symbol's end as "the line
89
+ before the next one"; of 487 shared symbols, **472 (97 %) had an end line that was too far**, so
90
+ an `offset`/`limit` hint almost always pulled in something else. tree-sitter gives the real end
91
+ from the syntax tree and finds methods inside classes. It is an `optionalDependency` — 52 MB of
92
+ grammars is the wrong trade to force on everyone — falls back cleanly, and says why when it
93
+ cannot run. `web-tree-sitter` is pinned to `^0.24.7`: 0.26 is ABI-incompatible with the 0.1.13
94
+ grammars and fails with an *empty* error message.
95
+ - **`AGENTS.md` protocol block.** Codex and OpenCode read `AGENTS.md`, not `CLAUDE.md`, and this
96
+ fork never wrote it — their hooks fired while the protocol never reached the model. One delimited
97
+ block is now maintained there; everything outside it is left byte for byte alone, and broken
98
+ markers cause a refusal rather than a guessed repair.
99
+
100
+ ### Fixed
101
+
102
+ - **Codex only ever got 4 of the 8 hooks.** `pre-read`, `pre-write`, `post-read` and `precompact`
103
+ were missing — exactly the ones carrying read avoidance, the do-not-repeat warning and the
104
+ compaction snapshot. OpenWolf ran there at half strength without anything ever failing.
105
+ - **The Codex tool matchers were too narrow.** `^apply_patch$` would never have seen a write
106
+ reported as `Write`, and a matcher that misses fails silently. They are a union of Claude and
107
+ Codex tool names now, and `SessionStart` deliberately carries no matcher so a compaction still
108
+ gets its digest.
109
+ - **Codex ignores hooks without `hooks = true` under `[features]`.** Without that switch a
110
+ perfectly fine-looking `hooks.json` sits there and none of it fires. `config.toml` is created
111
+ when missing and warned about otherwise — table-scoped, so the same key under another table does
112
+ not suppress the warning.
113
+ - **A partial `config.json` crashed `openwolf scan`.** `readJSON` returns the file's content when
114
+ the file exists, so the defaults never applied; a config holding only `openwolf.remote` died with
115
+ a raw `TypeError`.
116
+ - **`--limit` with a non-number reported "no match".** `parseInt("abc")` is `NaN` and
117
+ `slice(0, NaN)` is empty, so `find <symbol> --limit abc` claimed nothing was found for a symbol
118
+ that is indexed. A silent wrong answer is worse than a rejected flag.
119
+ - **`anatomy-symbols.json` was written non-atomically**, unlike every other `.wolf` file. A
120
+ `pre-read` hook firing mid-write read truncated JSON and lost all symbol hints for that turn.
121
+
122
+ Eight findings from the pre-release review are folded into these commits rather than left for a
123
+ follow-up; the review was run against the finished branch before anything was pushed.
124
+
9
125
  ## [1.20.9] — 2026-08-16
10
126
 
11
127
  ### Fixed
package/README.md CHANGED
@@ -5,8 +5,10 @@
5
5
  <h1 align="center">OpenWolf Enhanced</h1>
6
6
 
7
7
  <p align="center">
8
- <strong>A second brain for Claude Code — bounded, self-maintaining, and now reachable from Claude Desktop.</strong><br />
9
- Project intelligence, token tracking, and invisible enforcement through 7 hook scripts — plus a read-only MCP server that carries your knowledge into Claude Desktop and any MCP client. Zero workflow changes.
8
+ <strong>A second brain for your coding agent.</strong><br />
9
+ A file index it consults before opening anything, a memory of your corrections that survives
10
+ <code>/clear</code>, and a token ledger that counts <em>both</em> sides. Through invisible hooks —
11
+ no workflow changes.
10
12
  </p>
11
13
 
12
14
  <p align="center">
@@ -14,6 +16,8 @@
14
16
  </p>
15
17
 
16
18
  <p align="center">
19
+ <a href="https://www.npmjs.com/package/openwolf-enhanced"><img src="https://img.shields.io/npm/v/openwolf-enhanced?color=CB3837&logo=npm&label=npm" alt="npm version" /></a>
20
+ <a href="https://www.npmjs.com/package/openwolf-enhanced"><img src="https://img.shields.io/npm/dm/openwolf-enhanced?color=CB3837&label=downloads" alt="npm downloads" /></a>
17
21
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-AGPL--3.0-blue.svg" alt="License: AGPL-3.0" /></a>
18
22
  <a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node.js-20%2B-green.svg" alt="Node.js" /></a>
19
23
  <a href="https://github.com/cytostack/openwolf"><img src="https://img.shields.io/badge/fork%20of-cytostack%2Fopenwolf-lightgrey.svg" alt="Fork of cytostack/openwolf" /></a>
@@ -31,7 +35,36 @@
31
35
 
32
36
  **Works with [Claude Code](https://claude.com/claude-code), [OpenAI Codex CLI](https://github.com/openai/codex), [Gemini CLI](https://github.com/google-gemini/gemini-cli) and [OpenCode](https://github.com/sst/opencode)** — plus Claude Desktop and any MCP client. Persistent project memory, searchable citations, and context injection through invisible hooks. Git-native, no database, no cloud.
33
37
 
34
- **Contents:** [Why](#why-openwolf-exists) · [What's Enhanced](#whats-enhanced) · [Quick Start](#quick-start) · [How It Works](#how-it-works) · [Commands](#commands) · [Claude Desktop / MCP](#use-in-claude-desktop-mcp) · [FAQ](#faq)
38
+ **Contents:** [See it](#see-it) · [Why](#why-openwolf-exists) · [What's Enhanced](#whats-enhanced) · [Quick Start](#quick-start) · [How It Works](#how-it-works) · [Commands](#commands) · [Claude Desktop / MCP](#use-in-claude-desktop-mcp) · [FAQ](#faq)
39
+
40
+ ## See it
41
+
42
+ Find where something lives, without a repo-wide grep — and read only that slice:
43
+
44
+ ```console
45
+ $ openwolf find pageRank
46
+
47
+ 1 hit(s) for "pageRank"
48
+
49
+ ▆ src/scanner/import-graph.ts:106-147
50
+ fn pageRank · ~380 tok
51
+
52
+ ▁…█ = importance in the import graph (how often, and from how central a file).
53
+ ```
54
+
55
+ Ask what it actually cost you — including what OpenWolf itself put into the context:
56
+
57
+ ```console
58
+ $ openwolf report
59
+
60
+ Estimated (char-ratio heuristic)
61
+ Total tokens: 1,204,880
62
+ Reads avoided: 412,300
63
+ OpenWolf injected: 88,140 (resume digests, reminders)
64
+ Net savings: 324,160
65
+ ```
66
+
67
+ That third line is the one most tools leave out. It can go negative, and it is meant to.
35
68
 
36
69
  ## Why OpenWolf Exists
37
70
 
@@ -41,27 +74,53 @@ OpenWolf gives Claude a second brain: a file index so it knows what files contai
41
74
 
42
75
  ## What's Enhanced
43
76
 
44
- Everything upstream does, plus grouped by what it gives you:
45
-
46
- | Area | Enhancement |
47
- |------|-------------|
48
- | 🩺 **Self-maintenance** | `openwolf doctor` reports the `.wolf/` footprint and compacts everything (ledger, memory, bug log, backups, logs, tmp), flags cross-project registry issues, suggests `.wolfignore` entries for noisy dirs, and hints at near-duplicate cerebrum entries to merge — and `openwolf consolidate` LLM-merges them. `--dry-run` previews. |
49
- | 📦 **Bounded, tunable storage** | Ledger, bug log, cron queues and waste flags are all capped — no runaway multi-MB files. Every limit lives in `openwolf.retention` and survives updates (config is deep-merged, not overwritten). |
50
- | 🧭 **Smart session resume** | On session start a compact, token-bounded digest is injected — STATUS + Do-Not-Repeat inline, recent activity as a one-line headline, the rest as an *"Available on demand"* index — so the model continues without re-reading. |
51
- | 📓 **Passive activity capture** *(opt-in)* | File edits are always journaled; enable `openwolf.capture` and a `PostToolUse:Bash` hook also appends notable commands (commits, installs, tests, builds, deploys) **and failures** to a size-capped `.wolf/activity.log` that feeds the next session's resume digest. Secrets are redacted; trivial read-only commands are dropped. Off by default. |
52
- | 🔎 **Searchable memory + citations** | `openwolf recall <query>` keyword-searches STATUS / cerebrum / memory / buglog **and Claude's native Auto Memory**, **BM25-ranked** (rare terms weighted, length-normalized), returning a compact index where each hit has a stable citation id like `[c-3f9a]`. Expand one with `recall --id <id>` (or all inline with `--full`) — progressive disclosure, no database. Cite ids in notes to re-open them later; `recall --all` searches every registered project. |
53
- | 🧲 **Semantic & hybrid recall** | `recall --semantic` ranks by *meaning* via local embeddings (any OpenAI-compatible `/embeddings` endpoint; defaults to keyless **LM Studio**, so memory stays local)it finds paraphrases and crosses languages where keywords fail. `--hybrid` fuses BM25 + semantic with Reciprocal Rank Fusion; measured on a 22k-unit knowledge base it beats both alone. The vector index is two flat cache files in `.wolf/` — checkpointed, resumable, only changed entries re-embed; unreachable endpoint → clean fallback to keyword search. |
54
- | 🧠 **Native-memory interop** | Reads Claude Code's own Auto Memory (read-only): `doctor` flags its blind spots (files the `MEMORY.md` index never loads, the 200-line cutoff, dead links), a dashboard panel browses it, and an **MCP server** (`openwolf mcp`) exposes recall/resume to **Claude Desktop** and other MCP clients — so OpenWolf works beyond Claude Code. |
55
- | 🐝 **Beyond Claude Code** | `init`/`update` auto-detect **Codex CLI**, **Gemini CLI** and **OpenCode** and register OpenWolf's hooks there too. Codex & Gemini share Claude's hook model, so the session-start resume digest is injected and activity captured; OpenCode gets a JS-plugin adapter (compaction-time inject). Claude stays the primary target, unchanged. |
56
- | 🔌 **Model-agnostic AI tasks** | The background cron engine's AI tasks default to the Anthropic API but can point at **any OpenAI-compatible endpoint** (OpenAI, Groq, Cerebras, Mistral, Qwen, a local server) via `openwolf.cron` config — `llm_provider` / `llm_base_url` / `llm_model` / `api_key_env`. No code change; existing setups keep running on Claude unchanged. |
57
- | 🌍 **Localized digest** | The injected session-start resume digest can render in German — set `openwolf.lang` or `OPENWOLF_LANG`. English is the default. |
58
- | 🔒 **Privacy** | `<private>…</private>` content in any `.wolf` file is kept out of the injected context and out of search. |
59
- | 🗒 **Structured summaries** | Each session gets a `Did / Learned / Next / Files` scaffold, keeping memory consistent and greppable. |
60
- | 📤 **Export** | `openwolf export <sessions\|bugs>` to JSON or CSV (RFC 4180). |
61
- | 🎯 **`.wolfignore`** | gitignore-style scoping for anatomy scanning **and** hook tracking; `doctor` suggests what to add. |
62
- | 📊 **Dashboard** | Deep-linkable panels, a cross-project **All Projects** view, a **Command Log** for the opt-in Bash capture, jump-to-file from AI insights, a Design QC thumbnail grid + lightbox, and a daemon-down banner. |
63
- | 🔒 **Security & correctness** | Dashboard bound to loopback and token-gated, no command injection / path traversal, secret-file exclusion (`.pem`/`.key`/`id_rsa`…), plus ~15 adopted upstream security & bug fixes the inactive upstream never merged. |
64
- | 🚀 **Trusted releases** | Published to npm via GitHub OIDC — no long-lived token — with SLSA provenance; CI builds and tests on every push. |
77
+ Everything upstream does, plus the following. Details for each live in the
78
+ [docs](docs/index.md) and the [CHANGELOG](CHANGELOG.md).
79
+
80
+ **Finding things**
81
+
82
+ | | |
83
+ |---|---|
84
+ | 🔎 **`openwolf find`** | Symbol and file lookup from the existing index with exact line ranges, so you read one function instead of the file. Also `--json` and the MCP tool `openwolf_find`. |
85
+ | 🧭 **Import-graph importance** | Ties break on PageRank over your own imports, stored as a rank percentile. The biggest file is rarely the most important one. |
86
+ | 🌳 **tree-sitter ranges** *(optional)* | Real symbol boundaries from the syntax tree instead of "the line before the next one"which was wrong for 97 % of symbols. Optional dependency; falls back cleanly and says why. |
87
+ | 🧠 **Searchable memory** | `recall <query>` over STATUS / cerebrum / memory / buglog **and** Claude's native Auto Memory, BM25-ranked, each hit with a stable citation id. `--semantic` ranks by meaning via local embeddings; `--hybrid` fuses both. |
88
+
89
+ **Knowing what it costs**
90
+
91
+ | | |
92
+ |---|---|
93
+ | 📊 **Both sides of the ledger** | `report` shows reads avoided, **what OpenWolf itself injected**, and the net. The net may go negative — a metric that cannot look bad measures nothing. |
94
+ | 📦 **Bounded storage** | Ledger, bug log, cron queues and waste flags are all capped. No runaway multi-MB files. Every limit lives in `openwolf.retention` and survives updates. |
95
+ | 🩺 **Self-maintenance** | `doctor` reports the `.wolf/` footprint and compacts it, flags registry issues, suggests `.wolfignore` entries, and hints at near-duplicate cerebrum entries `consolidate` LLM-merges them. |
96
+ | 📤 **Export** | `export <sessions\|bugs>` to JSON or CSV (RFC 4180). |
97
+
98
+ **Working across agents**
99
+
100
+ | | |
101
+ |---|---|
102
+ | 🐝 **Codex, Gemini, OpenCode** | `init`/`update` detect them and register the hooks there too, including the `AGENTS.md` protocol block they actually read — one delimited block, everything outside it untouched. |
103
+ | 🔌 **Claude Desktop / MCP** | `openwolf mcp` exposes recall, resume, find and memory-health to any MCP client. |
104
+ | 🔌 **Model-agnostic AI tasks** | The cron engine's AI tasks point at any OpenAI-compatible endpoint — OpenAI, Groq, Cerebras, Mistral, a local server. No code change. |
105
+
106
+ **Session hygiene**
107
+
108
+ | | |
109
+ |---|---|
110
+ | 🧭 **Smart resume** | A token-bounded digest on session start: STATUS and Do-Not-Repeat inline, the rest as an *"available on demand"* index — so the model continues without re-reading. |
111
+ | 📓 **Activity capture** *(opt-in)* | Notable shell commands **and failures** appended to a capped log that feeds the next resume. Secrets redacted, trivial reads dropped. Off by default. |
112
+ | 🗒 **Structured summaries** | Each session gets a `Did / Learned / Next / Files` scaffold, so memory stays greppable. |
113
+ | 🎯 **`.wolfignore`** | gitignore-style scoping for both anatomy scanning and hook tracking. |
114
+ | 🌍 **Localized digest** | The resume digest can render in German via `openwolf.lang`. |
115
+
116
+ **Trust**
117
+
118
+ | | |
119
+ |---|---|
120
+ | 🔒 **Privacy** | `<private>…</private>` in any `.wolf` file stays out of the injected context, out of search, and out of anything sent elsewhere. |
121
+ | 🛡 **Security & correctness** | Dashboard on loopback and token-gated, no command injection or path traversal, secret-file exclusion — plus ~15 security fixes from upstream pull requests that were never merged into the 1.x line this fork is based on. |
122
+ | 🚀 **Trusted releases** | Published to npm via GitHub OIDC — no long-lived token — with SLSA provenance. CI builds and tests on every push. |
123
+ | 📈 **Dashboard** | Deep-linkable panels, a cross-project view, a command log, Design QC grid, and a daemon-down banner. |
65
124
 
66
125
  Every change is versioned in the [CHANGELOG](CHANGELOG.md); attribution is in the [NOTICE](NOTICE).
67
126
 
@@ -71,10 +130,13 @@ Every change is versioned in the [CHANGELOG](CHANGELOG.md); attribution is in th
71
130
  npm install -g openwolf-enhanced
72
131
  ```
73
132
 
74
- > **Note:** this is the maintained fork. `npm install -g openwolf` installs the
75
- > original `openwolf` (last released 1.0.4, March 2026, unmaintained) — a different
76
- > package. Install `openwolf-enhanced` for the bounded-storage, self-maintenance and
77
- > security work described above. Both provide the same `openwolf` command.
133
+ > **Note two different packages.** `npm install -g openwolf` installs
134
+ > [cytostack/openwolf](https://github.com/cytostack/openwolf), which is **actively developed**
135
+ > (2.x line, current as of August 2026). This package is a **separate lineage**: it forked the
136
+ > 1.x codebase in 2026 and never adopted the 2.x rewrite, so the two have diverged in
137
+ > architecture as well as features. Both still provide the same `openwolf` command, which means
138
+ > they cannot be installed side by side. Pick this one for the bounded-storage, self-maintenance
139
+ > and security work described above; pick upstream for the 2.x feature line.
78
140
 
79
141
  <details>
80
142
  <summary>Install from source instead</summary>
@@ -127,7 +189,9 @@ Two things to know before you re-run `pnpm build` on a copy you have already ins
127
189
  | `memory.md` | Chronological action log with token estimates |
128
190
  | `buglog.json` | Bug fix memory, searchable, prevents re-discovery |
129
191
  | `token-ledger.json` | Lifetime token tracking and session history |
130
- | `hooks/` | 7 Claude Code lifecycle hooks (pure Node.js) |
192
+ | `hooks/` | 8 lifecycle hooks (pure Node.js), deployed to every detected agent |
193
+ | `anatomy-symbols.json` | Symbol line ranges for larger files — what `find` returns and what turns a read into a slice |
194
+ | `anatomy-graph.json` | Import-graph importance per file, used to order otherwise equal hits |
131
195
  | `config.json` | Configuration with sensible defaults (incl. `retention`) |
132
196
  | `identity.md` | Agent persona for this project |
133
197
  | `OPENWOLF.md` | Instructions Claude follows every session |
@@ -205,10 +269,11 @@ openwolf consolidate LLM-merge near-duplicate cerebrum entries [--dry-r
205
269
  openwolf recall <query> Keyword-search .wolf + native memory; ids per hit [--limit N] [--full] [--all] [--json]
206
270
  [--semantic] rank by meaning (local embeddings) · [--hybrid] fuse keyword + semantic
207
271
  openwolf recall --id <id> Expand a citation id to its full entry (second disclosure layer)
272
+ openwolf find <query> Locate a symbol or file — ranked, with exact line ranges [--limit N] [--json]
208
273
  openwolf link Link to a remote workspace [--url URL --token TOKEN] [--status] [--unlink]
209
274
  openwolf push Offer learnings, decisions and bugs to the linked workspace [--dry-run]
210
275
  openwolf export <what> Export sessions|bugs as JSON or CSV [--format csv] [--out FILE]
211
- openwolf mcp Run an MCP server (recall/resume/memory-health) [--project DIR]
276
+ openwolf mcp Run an MCP server (recall/resume/find/memory-health) [--project DIR]
212
277
  openwolf scan Refresh the project structure map [--check]
213
278
  openwolf dashboard Open the real-time web dashboard
214
279
  openwolf daemon <cmd> start | stop | restart | logs — background task scheduler
@@ -297,7 +362,7 @@ explicitly. OpenWolf never writes to Claude's native memory — it reads and sur
297
362
  No. Everything lives in a local `.wolf/` directory in your project — plain Markdown and JSON, git-native, no database and no cloud. Nothing leaves your machine. (The only outbound calls are optional: the background cron AI tasks and `openwolf consolidate`, which you point at a provider of your choice.)
298
363
 
299
364
  **How is this different from the original `openwolf`?**
300
- This is a maintained fork. The original (npm `openwolf`, last released March 2026) is unmaintained. This fork adds bounded/self-maintaining storage, BM25 memory search with citations, an MCP server, model-agnostic AI tasks, multi-agent support, and ~15 security fixes — while staying a drop-in replacement for the same `openwolf` command.
365
+ They are separate lineages now, not a maintained fork of an abandoned project. This package forked upstream's **1.x** code in 2026; upstream has since shipped a **2.x rewrite** and is actively developed. Neither tracks the other. What this fork adds on top of the 1.x base: bounded/self-maintaining storage, BM25 memory search with citations, an MCP server, model-agnostic AI tasks, multi-agent support, and ~15 security fixes — while staying a drop-in replacement for the same `openwolf` command. If you want upstream's 2.x work, install `openwolf`.
301
366
 
302
367
  **Does it work with anything other than Claude Code?**
303
368
  Yes. `init`/`update` auto-detect **Codex CLI**, **Gemini CLI** and **OpenCode** and register the same hooks there. The `openwolf mcp` server also exposes recall/resume to **Claude Desktop** and any MCP client.
@@ -1,4 +1,4 @@
1
- import{a as e,c as t,r as n}from"./index-BZOA5m43.js";import{i as r}from"./utils-BqE_aDxV.js";var i=t(e(),1),a=n(),o=new Set(`ts.tsx.js.jsx.mjs.cjs.py.rs.go.java.rb.php.cs.cpp.cc.c.h.hpp.swift.kt.vue.svelte.json.md.mdx.yml.yaml.toml.css.scss.html.sh.sql.prisma.graphql`.split(`.`)),s=/([A-Za-z0-9_.\-/]+\.[A-Za-z][A-Za-z0-9]{0,7})/g;function c(e,t){if(!t)return e;let n=[],r=0,i;for(s.lastIndex=0;(i=s.exec(e))!==null;){let s=i[1],c=s.slice(s.lastIndexOf(`.`)+1).toLowerCase();(s.includes(`/`)||o.has(c))&&(i.index>r&&n.push(e.slice(r,i.index)),n.push((0,a.jsx)(`button`,{onClick:()=>t(s),className:`font-mono underline decoration-dotted underline-offset-2`,style:{color:`var(--accent)`},title:`Jump to ${s} in Anatomy`,children:s},`${i.index}-${s}`)),r=i.index+s.length)}return r<e.length&&n.push(e.slice(r)),n.length?n:e}var l=[{key:`achievements`,title:`Achievements`,icon:`🏆`,color:`#059669`},{key:`improvements`,title:`Improvements`,icon:`✨`,color:`#3b82f6`},{key:`next_tasks`,title:`Next Tasks`,icon:`📋`,color:`#d97706`},{key:`risks`,title:`Risks & Tech Debt`,icon:`🛡`,color:`#dc2626`}],u=`Analyze this project and write a JSON file to .wolf/suggestions.json with this exact structure:
1
+ import{a as e,c as t,r as n}from"./index-CCxQQi4q.js";import{i as r}from"./utils-BqE_aDxV.js";var i=t(e(),1),a=n(),o=new Set(`ts.tsx.js.jsx.mjs.cjs.py.rs.go.java.rb.php.cs.cpp.cc.c.h.hpp.swift.kt.vue.svelte.json.md.mdx.yml.yaml.toml.css.scss.html.sh.sql.prisma.graphql`.split(`.`)),s=/([A-Za-z0-9_.\-/]+\.[A-Za-z][A-Za-z0-9]{0,7})/g;function c(e,t){if(!t)return e;let n=[],r=0,i;for(s.lastIndex=0;(i=s.exec(e))!==null;){let s=i[1],c=s.slice(s.lastIndexOf(`.`)+1).toLowerCase();(s.includes(`/`)||o.has(c))&&(i.index>r&&n.push(e.slice(r,i.index)),n.push((0,a.jsx)(`button`,{onClick:()=>t(s),className:`font-mono underline decoration-dotted underline-offset-2`,style:{color:`var(--accent)`},title:`Jump to ${s} in Anatomy`,children:s},`${i.index}-${s}`)),r=i.index+s.length)}return r<e.length&&n.push(e.slice(r)),n.length?n:e}var l=[{key:`achievements`,title:`Achievements`,icon:`🏆`,color:`#059669`},{key:`improvements`,title:`Improvements`,icon:`✨`,color:`#3b82f6`},{key:`next_tasks`,title:`Next Tasks`,icon:`📋`,color:`#d97706`},{key:`risks`,title:`Risks & Tech Debt`,icon:`🛡`,color:`#dc2626`}],u=`Analyze this project and write a JSON file to .wolf/suggestions.json with this exact structure:
2
2
  {
3
3
  "generated_at": "<ISO timestamp>",
4
4
  "achievements": ["..."],
@@ -1,2 +1,2 @@
1
- import{a as e,c as t,r as n}from"./index-BZOA5m43.js";var r=t(e(),1),i=n();function a(e){return e.split(`
1
+ import{a as e,c as t,r as n}from"./index-CCxQQi4q.js";var r=t(e(),1),i=n();function a(e){return e.split(`
2
2
  `).filter(e=>e.trim().length>0).map(e=>{let t=/ → error$/.test(e),n=e.replace(/ → error$/,``),r=n.match(/^(\d{1,2}:\d{2})\s+(.*)$/);return r?{time:r[1],cmd:r[2],failed:t}:{time:``,cmd:n,failed:t}}).reverse()}function o({label:e,value:t,accent:n}){return(0,i.jsxs)(`div`,{className:`rounded-xl p-5`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,i.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:e}),(0,i.jsx)(`p`,{className:`text-2xl font-bold mt-1`,style:{color:n?`var(--danger)`:`var(--text-primary)`},children:t})]})}function s({data:e}){let[t,n]=(0,r.useState)(``),[s,c]=(0,r.useState)(!1),l=(0,r.useMemo)(()=>a(e.activityLog||``),[e.activityLog]),u=l.filter(e=>e.failed).length,d=l.filter(e=>(!s||e.failed)&&(!t||e.cmd.toLowerCase().includes(t.toLowerCase())));if(l.length===0)return(0,i.jsxs)(`div`,{className:`rounded-xl p-6`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,i.jsx)(`h3`,{className:`font-medium mb-2`,style:{color:`var(--text-secondary)`},children:`No shell activity captured`}),(0,i.jsxs)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:[`Passive Bash capture is `,(0,i.jsx)(`strong`,{children:`opt-in`}),`. Enable it in `,(0,i.jsx)(`code`,{className:`px-1 rounded text-xs`,style:{background:`var(--bg-base)`},children:`.wolf/config.json`}),` — set `,(0,i.jsx)(`code`,{className:`px-1 rounded text-xs`,style:{background:`var(--bg-base)`},children:`openwolf.capture.enabled = true`}),` — and notable commands (commits, installs, tests, builds) plus any failures land in `,(0,i.jsx)(`code`,{children:`.wolf/activity.log`}),`, redacted, and feed the next session's resume digest.`]})]});let f={color:`var(--text-secondary)`,padding:`0.5rem 0.75rem`,borderTop:`1px solid var(--border)`},p={color:`var(--text-muted)`,fontWeight:500,textAlign:`left`,padding:`0.5rem 0.75rem`};return(0,i.jsxs)(`div`,{children:[(0,i.jsxs)(`div`,{className:`grid grid-cols-2 md:grid-cols-3 gap-4 mb-4`,children:[(0,i.jsx)(o,{label:`Captured commands`,value:String(l.length)}),(0,i.jsx)(o,{label:`Failures`,value:String(u),accent:u>0}),(0,i.jsx)(o,{label:`Showing`,value:String(d.length)})]}),(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 mb-3`,children:[(0,i.jsx)(`input`,{type:`text`,placeholder:`Filter commands…`,value:t,onChange:e=>n(e.target.value),className:`rounded-lg px-3 py-2 text-sm flex-1 min-w-[200px] focus:outline-none`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`}}),(0,i.jsx)(`button`,{onClick:()=>c(e=>!e),className:`px-3 py-2 text-xs rounded-lg transition-colors`,style:{background:s?`var(--danger-subtle)`:`var(--bg-surface)`,border:`1px solid var(--border)`,color:s?`var(--danger)`:`var(--text-muted)`},children:s?`Showing failures only`:`Failures only`})]}),(0,i.jsx)(`div`,{className:`rounded-xl overflow-hidden`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:(0,i.jsx)(`div`,{className:`overflow-x-auto`,style:{maxHeight:520},children:(0,i.jsxs)(`table`,{className:`w-full text-sm`,style:{borderCollapse:`collapse`},children:[(0,i.jsx)(`thead`,{children:(0,i.jsxs)(`tr`,{children:[(0,i.jsx)(`th`,{style:{...p,width:64},children:`Time`}),(0,i.jsxs)(`th`,{style:p,children:[`Command (`,d.length,`)`]})]})}),(0,i.jsx)(`tbody`,{children:d.map((e,t)=>(0,i.jsxs)(`tr`,{style:{background:e.failed?`var(--danger-subtle)`:`transparent`},children:[(0,i.jsx)(`td`,{style:{...f,color:`var(--text-faint)`,whiteSpace:`nowrap`},children:e.time||`—`}),(0,i.jsxs)(`td`,{style:{...f,color:e.failed?`var(--danger)`:`var(--text-primary)`},className:`font-mono`,children:[e.cmd,e.failed&&(0,i.jsx)(`span`,{className:`text-xs ml-2`,style:{color:`var(--danger)`},children:`error`})]})]},t))})]})})}),(0,i.jsxs)(`p`,{className:`text-xs mt-3`,style:{color:`var(--text-faint)`},children:[`Secrets are redacted before capture; the newest commands feed the resume digest. Read-only view of `,(0,i.jsx)(`code`,{children:`.wolf/activity.log`}),`.`]})]})}export{s as ActivityLog};
@@ -1 +1 @@
1
- import{a as e,c as t,r as n}from"./index-BZOA5m43.js";var r=t(e(),1),i=n();function a({data:e}){let{memory:t}=e,[n,a]=(0,r.useState)(`all`),[o,s]=(0,r.useState)(``),[c,l]=(0,r.useState)(!0),u=(0,r.useMemo)(()=>{let e=t;if(n===`today`){let t=new Date().toISOString().slice(0,10);e=e.filter(e=>e.date===t)}else if(n===`week`){let t=new Date(Date.now()-7*864e5).toISOString().slice(0,10);e=e.filter(e=>e.date>=t)}if(o){let t=o.toLowerCase();e=e.map(e=>({...e,entries:e.entries.filter(e=>e.action.toLowerCase().includes(t)||e.files.toLowerCase().includes(t))})).filter(e=>e.entries.length>0)}return e},[t,n,o]);return(0,i.jsxs)(`div`,{children:[(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 mb-4`,children:[(0,i.jsx)(`div`,{className:`flex gap-1 rounded-lg p-1`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[`all`,`today`,`week`].map(e=>(0,i.jsx)(`button`,{onClick:()=>a(e),className:`px-3 py-1 text-xs rounded-md transition-colors`,style:{background:n===e?`var(--bg-surface-hover)`:`transparent`,color:n===e?`var(--text-primary)`:`var(--text-muted)`},children:e===`all`?`All`:e===`today`?`Today`:`This Week`},e))}),(0,i.jsx)(`input`,{type:`text`,placeholder:`Search actions...`,value:o,onChange:e=>s(e.target.value),className:`rounded-lg px-3 py-1.5 text-sm flex-1 min-w-[200px] focus:outline-none`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`}}),(0,i.jsx)(`button`,{onClick:()=>l(!c),className:`px-3 py-1.5 text-xs rounded-lg`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-muted)`},children:c?`Flat view`:`Group by session`})]}),u.length===0?(0,i.jsx)(`div`,{className:`text-center py-12`,style:{color:`var(--text-muted)`},children:`No activity found.`}):c?u.map((e,t)=>(0,i.jsxs)(`div`,{className:`mb-4`,children:[(0,i.jsxs)(`div`,{className:`text-sm font-medium mb-2`,style:{color:`var(--text-muted)`},children:[e.date,` `,e.time,` — `,e.entries.length,` actions`]}),(0,i.jsx)(`div`,{className:`rounded-xl`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:e.entries.map((t,n)=>(0,i.jsxs)(`div`,{className:`flex items-center gap-4 px-4 py-3`,style:{borderBottom:n<e.entries.length-1?`1px solid var(--border)`:`none`},children:[(0,i.jsx)(`span`,{className:`text-xs font-mono w-12 shrink-0`,style:{color:`var(--text-faint)`},children:t.time}),(0,i.jsx)(`span`,{className:`w-2 h-2 rounded-full shrink-0 ${t.action.includes(`Created`)?`bg-emerald-500`:t.action.includes(`Edited`)?`bg-blue-500`:``}`,style:{background:!t.action.includes(`Created`)&&!t.action.includes(`Edited`)?`var(--text-faint)`:void 0}}),(0,i.jsx)(`span`,{className:`text-sm flex-1`,style:{color:`var(--text-secondary)`},children:t.action}),(0,i.jsx)(`span`,{className:`text-xs font-mono`,style:{color:`var(--text-faint)`},children:t.tokens})]},n))})]},t)):(0,i.jsx)(`div`,{className:`rounded-xl`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:u.flatMap(e=>e.entries.map((t,n)=>(0,i.jsxs)(`div`,{className:`flex items-center gap-4 px-4 py-3`,style:{borderBottom:`1px solid var(--border)`},children:[(0,i.jsx)(`span`,{className:`text-xs font-mono w-20 shrink-0`,style:{color:`var(--text-faint)`},children:e.date}),(0,i.jsx)(`span`,{className:`text-xs font-mono w-12 shrink-0`,style:{color:`var(--text-faint)`},children:t.time}),(0,i.jsx)(`span`,{className:`text-sm flex-1`,style:{color:`var(--text-secondary)`},children:t.action}),(0,i.jsx)(`span`,{className:`text-xs font-mono`,style:{color:`var(--text-faint)`},children:t.tokens})]},`${e.date}-${n}`)))})]})}export{a as ActivityTimeline};
1
+ import{a as e,c as t,r as n}from"./index-CCxQQi4q.js";var r=t(e(),1),i=n();function a({data:e}){let{memory:t}=e,[n,a]=(0,r.useState)(`all`),[o,s]=(0,r.useState)(``),[c,l]=(0,r.useState)(!0),u=(0,r.useMemo)(()=>{let e=t;if(n===`today`){let t=new Date().toISOString().slice(0,10);e=e.filter(e=>e.date===t)}else if(n===`week`){let t=new Date(Date.now()-7*864e5).toISOString().slice(0,10);e=e.filter(e=>e.date>=t)}if(o){let t=o.toLowerCase();e=e.map(e=>({...e,entries:e.entries.filter(e=>e.action.toLowerCase().includes(t)||e.files.toLowerCase().includes(t))})).filter(e=>e.entries.length>0)}return e},[t,n,o]);return(0,i.jsxs)(`div`,{children:[(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 mb-4`,children:[(0,i.jsx)(`div`,{className:`flex gap-1 rounded-lg p-1`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[`all`,`today`,`week`].map(e=>(0,i.jsx)(`button`,{onClick:()=>a(e),className:`px-3 py-1 text-xs rounded-md transition-colors`,style:{background:n===e?`var(--bg-surface-hover)`:`transparent`,color:n===e?`var(--text-primary)`:`var(--text-muted)`},children:e===`all`?`All`:e===`today`?`Today`:`This Week`},e))}),(0,i.jsx)(`input`,{type:`text`,placeholder:`Search actions...`,value:o,onChange:e=>s(e.target.value),className:`rounded-lg px-3 py-1.5 text-sm flex-1 min-w-[200px] focus:outline-none`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`}}),(0,i.jsx)(`button`,{onClick:()=>l(!c),className:`px-3 py-1.5 text-xs rounded-lg`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-muted)`},children:c?`Flat view`:`Group by session`})]}),u.length===0?(0,i.jsx)(`div`,{className:`text-center py-12`,style:{color:`var(--text-muted)`},children:`No activity found.`}):c?u.map((e,t)=>(0,i.jsxs)(`div`,{className:`mb-4`,children:[(0,i.jsxs)(`div`,{className:`text-sm font-medium mb-2`,style:{color:`var(--text-muted)`},children:[e.date,` `,e.time,` — `,e.entries.length,` actions`]}),(0,i.jsx)(`div`,{className:`rounded-xl`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:e.entries.map((t,n)=>(0,i.jsxs)(`div`,{className:`flex items-center gap-4 px-4 py-3`,style:{borderBottom:n<e.entries.length-1?`1px solid var(--border)`:`none`},children:[(0,i.jsx)(`span`,{className:`text-xs font-mono w-12 shrink-0`,style:{color:`var(--text-faint)`},children:t.time}),(0,i.jsx)(`span`,{className:`w-2 h-2 rounded-full shrink-0 ${t.action.includes(`Created`)?`bg-emerald-500`:t.action.includes(`Edited`)?`bg-blue-500`:``}`,style:{background:!t.action.includes(`Created`)&&!t.action.includes(`Edited`)?`var(--text-faint)`:void 0}}),(0,i.jsx)(`span`,{className:`text-sm flex-1`,style:{color:`var(--text-secondary)`},children:t.action}),(0,i.jsx)(`span`,{className:`text-xs font-mono`,style:{color:`var(--text-faint)`},children:t.tokens})]},n))})]},t)):(0,i.jsx)(`div`,{className:`rounded-xl`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:u.flatMap(e=>e.entries.map((t,n)=>(0,i.jsxs)(`div`,{className:`flex items-center gap-4 px-4 py-3`,style:{borderBottom:`1px solid var(--border)`},children:[(0,i.jsx)(`span`,{className:`text-xs font-mono w-20 shrink-0`,style:{color:`var(--text-faint)`},children:e.date}),(0,i.jsx)(`span`,{className:`text-xs font-mono w-12 shrink-0`,style:{color:`var(--text-faint)`},children:t.time}),(0,i.jsx)(`span`,{className:`text-sm flex-1`,style:{color:`var(--text-secondary)`},children:t.action}),(0,i.jsx)(`span`,{className:`text-xs font-mono`,style:{color:`var(--text-faint)`},children:t.tokens})]},`${e.date}-${n}`)))})]})}export{a as ActivityTimeline};
@@ -1 +1 @@
1
- import{a as e,c as t,r as n}from"./index-BZOA5m43.js";import{r,t as i}from"./utils-BqE_aDxV.js";var a=t(e(),1),o=n();function s({tokens:e,className:t}){return(0,o.jsxs)(`span`,{className:i(`font-mono text-xs`,e<200?`text-emerald-400`:e<1e3?`text-amber-400`:`text-red-400`,t),children:[`~`,r(e),` tok`]})}function c(e){let t={name:`.`,path:`.`,children:[],files:[]},n=new Map;n.set(`./`,t);for(let r of e){let e=r.section;if(!n.has(e)){let r=e.replace(/\/$/,``).split(`/`),i=t,a=``;for(let e of r){a=a?`${a}/${e}`:e;let t=`${a}/`;if(!n.has(t)){let r={name:e,path:t,children:[],files:[]};i.children.push(r),n.set(t,r)}i=n.get(t)}}n.get(e).files.push({file:r.file,description:r.description,tokens:r.tokens})}return t}function l({node:e,search:t,depth:n=0}){let[r,i]=(0,a.useState)(n<2),c=t.toLowerCase(),f=e.files.filter(e=>!t||e.file.toLowerCase().includes(c)||e.description.toLowerCase().includes(c)),p=e.children.some(e=>d(e,c));return t&&f.length===0&&!p?null:(0,o.jsxs)(`div`,{className:`ml-3`,children:[e.name!==`.`&&(0,o.jsxs)(`button`,{onClick:()=>i(!r),className:`flex items-center gap-1.5 py-1 text-sm transition-colors`,style:{color:`var(--text-secondary)`},children:[(0,o.jsx)(`span`,{className:`w-4 text-center`,style:{color:`var(--text-faint)`},children:r?`▼`:`▶`}),(0,o.jsx)(`span`,{className:`text-amber-400`,children:`📁`}),(0,o.jsxs)(`span`,{children:[e.name,`/`]}),(0,o.jsxs)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:[u(e),` files`]})]}),(r||e.name===`.`)&&(0,o.jsxs)(`div`,{className:e.name===`.`?``:`ml-4`,children:[f.sort((e,t)=>e.file.localeCompare(t.file)).map(e=>(0,o.jsxs)(`div`,{className:`flex items-center gap-2 py-1 pl-5`,children:[(0,o.jsx)(`span`,{style:{color:`var(--text-faint)`},children:`📄`}),(0,o.jsx)(`span`,{className:`text-sm font-mono`,style:{color:`var(--text-primary)`},children:e.file}),e.description&&(0,o.jsxs)(`span`,{className:`text-xs truncate max-w-xs`,style:{color:`var(--text-faint)`},children:[`— `,e.description]}),(0,o.jsx)(s,{tokens:e.tokens,className:`ml-auto shrink-0`})]},e.file)),e.children.sort((e,t)=>e.name.localeCompare(t.name)).map(e=>(0,o.jsx)(l,{node:e,search:t,depth:n+1},e.path))]})]})}function u(e){return e.files.length+e.children.reduce((e,t)=>e+u(t),0)}function d(e,t){return e.files.some(e=>e.file.toLowerCase().includes(t)||e.description.toLowerCase().includes(t))?!0:e.children.some(e=>d(e,t))}function f({data:e,initialFile:t}){let{anatomy:n}=e,[r,i]=(0,a.useState)(t??``),[s,u]=(0,a.useState)(!1);(0,a.useEffect)(()=>{t&&i(t)},[t]);let d=(0,a.useMemo)(()=>c(n.entries),[n.entries]),f=(0,a.useMemo)(()=>{let e=n.entries.map(e=>e.tokens);return{total:n.entries.length,avg:e.length>0?Math.round(e.reduce((e,t)=>e+t,0)/e.length):0,largest:e.length>0?Math.max(...e):0}},[n.entries]);return(0,o.jsxs)(`div`,{children:[(0,o.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 mb-4`,children:[(0,o.jsx)(`input`,{type:`text`,placeholder:`Search files...`,value:r,onChange:e=>i(e.target.value),className:`flex-1 min-w-[200px] rounded-lg px-3 py-2 text-sm focus:outline-none`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`}}),(0,o.jsx)(`button`,{onClick:()=>u(!s),className:`px-3 py-2 text-xs rounded-lg`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-muted)`},children:s?`Sort: Size`:`Sort: A-Z`})]}),(0,o.jsxs)(`div`,{className:`flex gap-4 mb-4 text-sm`,style:{color:`var(--text-muted)`},children:[(0,o.jsxs)(`span`,{children:[f.total,` files tracked`]}),(0,o.jsxs)(`span`,{children:[`Avg: `,f.avg,` tok/file`]}),(0,o.jsxs)(`span`,{children:[`Largest: `,f.largest,` tok`]})]}),(0,o.jsx)(`div`,{className:`rounded-xl p-4`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:n.entries.length===0?(0,o.jsxs)(`div`,{className:`text-center py-12`,style:{color:`var(--text-muted)`},children:[(0,o.jsx)(`p`,{className:`text-2xl mb-2`,children:`📂`}),(0,o.jsxs)(`p`,{children:[`No anatomy data. Run `,(0,o.jsx)(`code`,{style:{color:`var(--text-secondary)`},children:`openwolf scan`}),` to index your project.`]})]}):(0,o.jsx)(l,{node:d,search:r})})]})}export{f as AnatomyBrowser};
1
+ import{a as e,c as t,r as n}from"./index-CCxQQi4q.js";import{r,t as i}from"./utils-BqE_aDxV.js";var a=t(e(),1),o=n();function s({tokens:e,className:t}){return(0,o.jsxs)(`span`,{className:i(`font-mono text-xs`,e<200?`text-emerald-400`:e<1e3?`text-amber-400`:`text-red-400`,t),children:[`~`,r(e),` tok`]})}function c(e){let t={name:`.`,path:`.`,children:[],files:[]},n=new Map;n.set(`./`,t);for(let r of e){let e=r.section;if(!n.has(e)){let r=e.replace(/\/$/,``).split(`/`),i=t,a=``;for(let e of r){a=a?`${a}/${e}`:e;let t=`${a}/`;if(!n.has(t)){let r={name:e,path:t,children:[],files:[]};i.children.push(r),n.set(t,r)}i=n.get(t)}}n.get(e).files.push({file:r.file,description:r.description,tokens:r.tokens})}return t}function l({node:e,search:t,depth:n=0}){let[r,i]=(0,a.useState)(n<2),c=t.toLowerCase(),f=e.files.filter(e=>!t||e.file.toLowerCase().includes(c)||e.description.toLowerCase().includes(c)),p=e.children.some(e=>d(e,c));return t&&f.length===0&&!p?null:(0,o.jsxs)(`div`,{className:`ml-3`,children:[e.name!==`.`&&(0,o.jsxs)(`button`,{onClick:()=>i(!r),className:`flex items-center gap-1.5 py-1 text-sm transition-colors`,style:{color:`var(--text-secondary)`},children:[(0,o.jsx)(`span`,{className:`w-4 text-center`,style:{color:`var(--text-faint)`},children:r?`▼`:`▶`}),(0,o.jsx)(`span`,{className:`text-amber-400`,children:`📁`}),(0,o.jsxs)(`span`,{children:[e.name,`/`]}),(0,o.jsxs)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:[u(e),` files`]})]}),(r||e.name===`.`)&&(0,o.jsxs)(`div`,{className:e.name===`.`?``:`ml-4`,children:[f.sort((e,t)=>e.file.localeCompare(t.file)).map(e=>(0,o.jsxs)(`div`,{className:`flex items-center gap-2 py-1 pl-5`,children:[(0,o.jsx)(`span`,{style:{color:`var(--text-faint)`},children:`📄`}),(0,o.jsx)(`span`,{className:`text-sm font-mono`,style:{color:`var(--text-primary)`},children:e.file}),e.description&&(0,o.jsxs)(`span`,{className:`text-xs truncate max-w-xs`,style:{color:`var(--text-faint)`},children:[`— `,e.description]}),(0,o.jsx)(s,{tokens:e.tokens,className:`ml-auto shrink-0`})]},e.file)),e.children.sort((e,t)=>e.name.localeCompare(t.name)).map(e=>(0,o.jsx)(l,{node:e,search:t,depth:n+1},e.path))]})]})}function u(e){return e.files.length+e.children.reduce((e,t)=>e+u(t),0)}function d(e,t){return e.files.some(e=>e.file.toLowerCase().includes(t)||e.description.toLowerCase().includes(t))?!0:e.children.some(e=>d(e,t))}function f({data:e,initialFile:t}){let{anatomy:n}=e,[r,i]=(0,a.useState)(t??``),[s,u]=(0,a.useState)(!1);(0,a.useEffect)(()=>{t&&i(t)},[t]);let d=(0,a.useMemo)(()=>c(n.entries),[n.entries]),f=(0,a.useMemo)(()=>{let e=n.entries.map(e=>e.tokens);return{total:n.entries.length,avg:e.length>0?Math.round(e.reduce((e,t)=>e+t,0)/e.length):0,largest:e.length>0?Math.max(...e):0}},[n.entries]);return(0,o.jsxs)(`div`,{children:[(0,o.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 mb-4`,children:[(0,o.jsx)(`input`,{type:`text`,placeholder:`Search files...`,value:r,onChange:e=>i(e.target.value),className:`flex-1 min-w-[200px] rounded-lg px-3 py-2 text-sm focus:outline-none`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`}}),(0,o.jsx)(`button`,{onClick:()=>u(!s),className:`px-3 py-2 text-xs rounded-lg`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-muted)`},children:s?`Sort: Size`:`Sort: A-Z`})]}),(0,o.jsxs)(`div`,{className:`flex gap-4 mb-4 text-sm`,style:{color:`var(--text-muted)`},children:[(0,o.jsxs)(`span`,{children:[f.total,` files tracked`]}),(0,o.jsxs)(`span`,{children:[`Avg: `,f.avg,` tok/file`]}),(0,o.jsxs)(`span`,{children:[`Largest: `,f.largest,` tok`]})]}),(0,o.jsx)(`div`,{className:`rounded-xl p-4`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:n.entries.length===0?(0,o.jsxs)(`div`,{className:`text-center py-12`,style:{color:`var(--text-muted)`},children:[(0,o.jsx)(`p`,{className:`text-2xl mb-2`,children:`📂`}),(0,o.jsxs)(`p`,{children:[`No anatomy data. Run `,(0,o.jsx)(`code`,{style:{color:`var(--text-secondary)`},children:`openwolf scan`}),` to index your project.`]})]}):(0,o.jsx)(l,{node:d,search:r})})]})}export{f as AnatomyBrowser};
@@ -1 +1 @@
1
- import{a as e,c as t,r as n}from"./index-BZOA5m43.js";var r=t(e(),1),i=n();function a({data:e}){let{buglog:t}=e,[n,a]=(0,r.useState)(``),[o,s]=(0,r.useState)(null),c=n?t.bugs.filter(e=>e.error_message.toLowerCase().includes(n.toLowerCase())||e.root_cause.toLowerCase().includes(n.toLowerCase())||e.fix.toLowerCase().includes(n.toLowerCase())||e.tags.some(e=>e.toLowerCase().includes(n.toLowerCase()))):t.bugs;if(t.bugs.length===0)return(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center py-16 text-center`,children:[(0,i.jsx)(`div`,{className:`text-4xl mb-3`,children:`🐛`}),(0,i.jsx)(`h3`,{className:`font-medium mb-1`,style:{color:`var(--text-secondary)`},children:`No bugs logged yet`}),(0,i.jsx)(`p`,{className:`text-sm max-w-sm`,style:{color:`var(--text-muted)`},children:`When you encounter and fix bugs, they'll appear here for future reference.`})]});let l=t.bugs.flatMap(e=>e.tags),u=new Map;for(let e of l)u.set(e,(u.get(e)||0)+1);let d=[...u.entries()].sort((e,t)=>t[1]-e[1]).slice(0,5);return(0,i.jsxs)(`div`,{children:[(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4 mb-4`,children:[(0,i.jsx)(`input`,{type:`text`,placeholder:`Search bugs...`,value:n,onChange:e=>a(e.target.value),className:`flex-1 min-w-[200px] rounded-lg px-3 py-2 text-sm focus:outline-none`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`}}),(0,i.jsxs)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:[t.bugs.length,` bugs logged`]})]}),d.length>0&&(0,i.jsx)(`div`,{className:`flex flex-wrap gap-2 mb-4`,children:d.map(([e,t])=>(0,i.jsxs)(`button`,{onClick:()=>a(e),className:`px-2 py-1 text-xs rounded-full`,style:{background:`var(--bg-surface-hover)`,border:`1px solid var(--border-subtle)`,color:`var(--text-muted)`},children:[e,` (`,t,`)`]},e))}),(0,i.jsx)(`div`,{className:`space-y-3`,children:c.map(e=>{let t=o===e.id;return(0,i.jsxs)(`div`,{className:`rounded-xl overflow-hidden`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,i.jsxs)(`button`,{onClick:()=>s(t?null:e.id),className:`w-full flex items-start gap-3 px-5 py-3 transition-colors text-left`,onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsx)(`span`,{className:`text-sm mt-0.5`,style:{color:`var(--text-faint)`},children:t?`▼`:`▶`}),(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`p`,{className:`text-sm truncate`,style:{color:`var(--text-primary)`},children:e.error_message}),(0,i.jsxs)(`div`,{className:`flex items-center gap-3 mt-1`,children:[(0,i.jsx)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:e.file}),(0,i.jsx)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:e.timestamp?.slice(0,10)})]})]}),e.occurrences>1&&(0,i.jsxs)(`span`,{className:`shrink-0 px-2 py-0.5 rounded-full text-xs`,style:{background:`var(--warning-subtle)`,color:`var(--warning)`},children:[`Seen `,e.occurrences,`x`]})]}),t&&(0,i.jsxs)(`div`,{className:`px-5 py-4 space-y-3`,style:{borderTop:`1px solid var(--border)`},children:[(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`p`,{className:`text-xs uppercase mb-1`,style:{color:`var(--text-faint)`},children:`Error Message`}),(0,i.jsx)(`pre`,{className:`text-sm rounded-lg p-3 overflow-x-auto font-mono`,style:{color:`var(--danger)`,background:`var(--danger-subtle)`},children:e.error_message})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`p`,{className:`text-xs uppercase mb-1`,style:{color:`var(--text-faint)`},children:`Root Cause`}),(0,i.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-secondary)`},children:e.root_cause})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`p`,{className:`text-xs uppercase mb-1`,style:{color:`var(--text-faint)`},children:`Fix`}),(0,i.jsx)(`pre`,{className:`text-sm rounded-lg p-3 overflow-x-auto font-mono`,style:{color:`var(--accent)`,background:`var(--accent-subtle)`},children:e.fix})]}),(0,i.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:e.tags.map(e=>(0,i.jsx)(`span`,{className:`px-2 py-0.5 text-xs rounded-full`,style:{background:`var(--bg-surface-hover)`,border:`1px solid var(--border-subtle)`,color:`var(--text-muted)`},children:e},e))})]})]},e.id)})})]})}export{a as BugLog};
1
+ import{a as e,c as t,r as n}from"./index-CCxQQi4q.js";var r=t(e(),1),i=n();function a({data:e}){let{buglog:t}=e,[n,a]=(0,r.useState)(``),[o,s]=(0,r.useState)(null),c=n?t.bugs.filter(e=>e.error_message.toLowerCase().includes(n.toLowerCase())||e.root_cause.toLowerCase().includes(n.toLowerCase())||e.fix.toLowerCase().includes(n.toLowerCase())||e.tags.some(e=>e.toLowerCase().includes(n.toLowerCase()))):t.bugs;if(t.bugs.length===0)return(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center py-16 text-center`,children:[(0,i.jsx)(`div`,{className:`text-4xl mb-3`,children:`🐛`}),(0,i.jsx)(`h3`,{className:`font-medium mb-1`,style:{color:`var(--text-secondary)`},children:`No bugs logged yet`}),(0,i.jsx)(`p`,{className:`text-sm max-w-sm`,style:{color:`var(--text-muted)`},children:`When you encounter and fix bugs, they'll appear here for future reference.`})]});let l=t.bugs.flatMap(e=>e.tags),u=new Map;for(let e of l)u.set(e,(u.get(e)||0)+1);let d=[...u.entries()].sort((e,t)=>t[1]-e[1]).slice(0,5);return(0,i.jsxs)(`div`,{children:[(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4 mb-4`,children:[(0,i.jsx)(`input`,{type:`text`,placeholder:`Search bugs...`,value:n,onChange:e=>a(e.target.value),className:`flex-1 min-w-[200px] rounded-lg px-3 py-2 text-sm focus:outline-none`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`}}),(0,i.jsxs)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:[t.bugs.length,` bugs logged`]})]}),d.length>0&&(0,i.jsx)(`div`,{className:`flex flex-wrap gap-2 mb-4`,children:d.map(([e,t])=>(0,i.jsxs)(`button`,{onClick:()=>a(e),className:`px-2 py-1 text-xs rounded-full`,style:{background:`var(--bg-surface-hover)`,border:`1px solid var(--border-subtle)`,color:`var(--text-muted)`},children:[e,` (`,t,`)`]},e))}),(0,i.jsx)(`div`,{className:`space-y-3`,children:c.map(e=>{let t=o===e.id;return(0,i.jsxs)(`div`,{className:`rounded-xl overflow-hidden`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,i.jsxs)(`button`,{onClick:()=>s(t?null:e.id),className:`w-full flex items-start gap-3 px-5 py-3 transition-colors text-left`,onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsx)(`span`,{className:`text-sm mt-0.5`,style:{color:`var(--text-faint)`},children:t?`▼`:`▶`}),(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`p`,{className:`text-sm truncate`,style:{color:`var(--text-primary)`},children:e.error_message}),(0,i.jsxs)(`div`,{className:`flex items-center gap-3 mt-1`,children:[(0,i.jsx)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:e.file}),(0,i.jsx)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:e.timestamp?.slice(0,10)})]})]}),e.occurrences>1&&(0,i.jsxs)(`span`,{className:`shrink-0 px-2 py-0.5 rounded-full text-xs`,style:{background:`var(--warning-subtle)`,color:`var(--warning)`},children:[`Seen `,e.occurrences,`x`]})]}),t&&(0,i.jsxs)(`div`,{className:`px-5 py-4 space-y-3`,style:{borderTop:`1px solid var(--border)`},children:[(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`p`,{className:`text-xs uppercase mb-1`,style:{color:`var(--text-faint)`},children:`Error Message`}),(0,i.jsx)(`pre`,{className:`text-sm rounded-lg p-3 overflow-x-auto font-mono`,style:{color:`var(--danger)`,background:`var(--danger-subtle)`},children:e.error_message})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`p`,{className:`text-xs uppercase mb-1`,style:{color:`var(--text-faint)`},children:`Root Cause`}),(0,i.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-secondary)`},children:e.root_cause})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`p`,{className:`text-xs uppercase mb-1`,style:{color:`var(--text-faint)`},children:`Fix`}),(0,i.jsx)(`pre`,{className:`text-sm rounded-lg p-3 overflow-x-auto font-mono`,style:{color:`var(--accent)`,background:`var(--accent-subtle)`},children:e.fix})]}),(0,i.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:e.tags.map(e=>(0,i.jsx)(`span`,{className:`px-2 py-0.5 text-xs rounded-full`,style:{background:`var(--bg-surface-hover)`,border:`1px solid var(--border-subtle)`,color:`var(--text-muted)`},children:e},e))})]})]},e.id)})})]})}export{a as BugLog};
@@ -1 +1 @@
1
- import{a as e,c as t,r as n}from"./index-BZOA5m43.js";var r=t(e(),1),i=n();function a({data:e}){let{cerebrum:t}=e,[n,a]=(0,r.useState)(``),[o,s]=(0,r.useState)({preferences:!0,learnings:!0,doNotRepeat:!0,decisions:!1}),c=e=>s(t=>({...t,[e]:!t[e]})),l=e=>!n||e.toLowerCase().includes(n.toLowerCase());return(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`div`,{className:`flex items-center justify-between mb-4`,children:(0,i.jsxs)(`div`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:[`Last updated: `,t.lastUpdated||`—`,` ·`,t.preferences.length+t.learnings.length+t.doNotRepeat.length+t.decisions.length,` entries`]})}),(0,i.jsx)(`input`,{type:`text`,placeholder:`Search cerebrum...`,value:n,onChange:e=>a(e.target.value),className:`w-full rounded-lg px-3 py-2 text-sm mb-4 focus:outline-none`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`}}),(0,i.jsxs)(`div`,{className:`rounded-xl mb-4 overflow-hidden`,style:{background:`var(--danger-subtle)`,border:`1px solid rgba(220, 38, 38, 0.2)`},children:[(0,i.jsxs)(`button`,{onClick:()=>c(`doNotRepeat`),className:`w-full flex items-center justify-between px-5 py-3 transition-colors`,onMouseEnter:e=>e.currentTarget.style.background=`rgba(220, 38, 38, 0.08)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{style:{color:`var(--danger)`},children:`⊘`}),(0,i.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--danger)`},children:`Do-Not-Repeat`}),(0,i.jsx)(`span`,{className:`text-xs px-2 py-0.5 rounded-full`,style:{background:`rgba(220, 38, 38, 0.1)`,color:`var(--danger)`},children:t.doNotRepeat.length})]}),(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:o.doNotRepeat?`▼`:`▶`})]}),o.doNotRepeat&&(0,i.jsxs)(`div`,{className:`px-5 pb-4 space-y-2`,children:[t.doNotRepeat.filter(e=>l(e.text)).map((e,t)=>(0,i.jsxs)(`div`,{className:`rounded-lg p-3`,style:{background:`rgba(220, 38, 38, 0.05)`,border:`1px solid rgba(220, 38, 38, 0.1)`},children:[e.date&&(0,i.jsxs)(`span`,{className:`text-xs font-mono mr-2`,style:{color:`rgba(220, 38, 38, 0.6)`},children:[`[`,e.date,`]`]}),(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-secondary)`},children:e.text})]},t)),t.doNotRepeat.length===0&&(0,i.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`No entries yet.`})]})]}),(0,i.jsxs)(`div`,{className:`rounded-xl mb-4 overflow-hidden`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,i.jsxs)(`button`,{onClick:()=>c(`preferences`),className:`w-full flex items-center justify-between px-5 py-3 transition-colors`,onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{className:`text-blue-400`,children:`◈`}),(0,i.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`User Preferences`}),(0,i.jsx)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:t.preferences.length})]}),(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:o.preferences?`▼`:`▶`})]}),o.preferences&&(0,i.jsxs)(`div`,{className:`px-5 pb-4`,children:[t.preferences.filter(l).map((e,t)=>(0,i.jsxs)(`div`,{className:`flex items-start gap-2 py-1.5`,children:[(0,i.jsx)(`span`,{className:`mt-1`,style:{color:`var(--text-faint)`},children:`•`}),(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-secondary)`},children:e})]},t)),t.preferences.length===0&&(0,i.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`No preferences recorded yet.`})]})]}),(0,i.jsxs)(`div`,{className:`rounded-xl mb-4 overflow-hidden`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,i.jsxs)(`button`,{onClick:()=>c(`learnings`),className:`w-full flex items-center justify-between px-5 py-3 transition-colors`,onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{style:{color:`var(--accent)`},children:`◎`}),(0,i.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`Key Learnings`}),(0,i.jsx)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:t.learnings.length})]}),(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:o.learnings?`▼`:`▶`})]}),o.learnings&&(0,i.jsxs)(`div`,{className:`px-5 pb-4 space-y-2`,children:[t.learnings.filter(l).map((e,t)=>(0,i.jsx)(`div`,{className:`rounded-lg p-3 text-sm`,style:{background:`var(--bg-surface-hover)`,color:`var(--text-secondary)`},children:e},t)),t.learnings.length===0&&(0,i.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`No learnings recorded yet.`})]})]}),(0,i.jsxs)(`div`,{className:`rounded-xl overflow-hidden`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,i.jsxs)(`button`,{onClick:()=>c(`decisions`),className:`w-full flex items-center justify-between px-5 py-3 transition-colors`,onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{className:`text-amber-400`,children:`⚖`}),(0,i.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`Decision Log`}),(0,i.jsx)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:t.decisions.length})]}),(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:o.decisions?`▼`:`▶`})]}),o.decisions&&(0,i.jsxs)(`div`,{className:`px-5 pb-4 space-y-2`,children:[t.decisions.filter(l).map((e,t)=>(0,i.jsx)(`div`,{className:`rounded-lg p-3 text-sm`,style:{background:`var(--bg-surface-hover)`,color:`var(--text-secondary)`},children:e},t)),t.decisions.length===0&&(0,i.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`No decisions logged yet.`})]})]})]})}export{a as CerebrumViewer};
1
+ import{a as e,c as t,r as n}from"./index-CCxQQi4q.js";var r=t(e(),1),i=n();function a({data:e}){let{cerebrum:t}=e,[n,a]=(0,r.useState)(``),[o,s]=(0,r.useState)({preferences:!0,learnings:!0,doNotRepeat:!0,decisions:!1}),c=e=>s(t=>({...t,[e]:!t[e]})),l=e=>!n||e.toLowerCase().includes(n.toLowerCase());return(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`div`,{className:`flex items-center justify-between mb-4`,children:(0,i.jsxs)(`div`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:[`Last updated: `,t.lastUpdated||`—`,` ·`,t.preferences.length+t.learnings.length+t.doNotRepeat.length+t.decisions.length,` entries`]})}),(0,i.jsx)(`input`,{type:`text`,placeholder:`Search cerebrum...`,value:n,onChange:e=>a(e.target.value),className:`w-full rounded-lg px-3 py-2 text-sm mb-4 focus:outline-none`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`}}),(0,i.jsxs)(`div`,{className:`rounded-xl mb-4 overflow-hidden`,style:{background:`var(--danger-subtle)`,border:`1px solid rgba(220, 38, 38, 0.2)`},children:[(0,i.jsxs)(`button`,{onClick:()=>c(`doNotRepeat`),className:`w-full flex items-center justify-between px-5 py-3 transition-colors`,onMouseEnter:e=>e.currentTarget.style.background=`rgba(220, 38, 38, 0.08)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{style:{color:`var(--danger)`},children:`⊘`}),(0,i.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--danger)`},children:`Do-Not-Repeat`}),(0,i.jsx)(`span`,{className:`text-xs px-2 py-0.5 rounded-full`,style:{background:`rgba(220, 38, 38, 0.1)`,color:`var(--danger)`},children:t.doNotRepeat.length})]}),(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:o.doNotRepeat?`▼`:`▶`})]}),o.doNotRepeat&&(0,i.jsxs)(`div`,{className:`px-5 pb-4 space-y-2`,children:[t.doNotRepeat.filter(e=>l(e.text)).map((e,t)=>(0,i.jsxs)(`div`,{className:`rounded-lg p-3`,style:{background:`rgba(220, 38, 38, 0.05)`,border:`1px solid rgba(220, 38, 38, 0.1)`},children:[e.date&&(0,i.jsxs)(`span`,{className:`text-xs font-mono mr-2`,style:{color:`rgba(220, 38, 38, 0.6)`},children:[`[`,e.date,`]`]}),(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-secondary)`},children:e.text})]},t)),t.doNotRepeat.length===0&&(0,i.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`No entries yet.`})]})]}),(0,i.jsxs)(`div`,{className:`rounded-xl mb-4 overflow-hidden`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,i.jsxs)(`button`,{onClick:()=>c(`preferences`),className:`w-full flex items-center justify-between px-5 py-3 transition-colors`,onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{className:`text-blue-400`,children:`◈`}),(0,i.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`User Preferences`}),(0,i.jsx)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:t.preferences.length})]}),(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:o.preferences?`▼`:`▶`})]}),o.preferences&&(0,i.jsxs)(`div`,{className:`px-5 pb-4`,children:[t.preferences.filter(l).map((e,t)=>(0,i.jsxs)(`div`,{className:`flex items-start gap-2 py-1.5`,children:[(0,i.jsx)(`span`,{className:`mt-1`,style:{color:`var(--text-faint)`},children:`•`}),(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-secondary)`},children:e})]},t)),t.preferences.length===0&&(0,i.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`No preferences recorded yet.`})]})]}),(0,i.jsxs)(`div`,{className:`rounded-xl mb-4 overflow-hidden`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,i.jsxs)(`button`,{onClick:()=>c(`learnings`),className:`w-full flex items-center justify-between px-5 py-3 transition-colors`,onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{style:{color:`var(--accent)`},children:`◎`}),(0,i.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`Key Learnings`}),(0,i.jsx)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:t.learnings.length})]}),(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:o.learnings?`▼`:`▶`})]}),o.learnings&&(0,i.jsxs)(`div`,{className:`px-5 pb-4 space-y-2`,children:[t.learnings.filter(l).map((e,t)=>(0,i.jsx)(`div`,{className:`rounded-lg p-3 text-sm`,style:{background:`var(--bg-surface-hover)`,color:`var(--text-secondary)`},children:e},t)),t.learnings.length===0&&(0,i.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`No learnings recorded yet.`})]})]}),(0,i.jsxs)(`div`,{className:`rounded-xl overflow-hidden`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,i.jsxs)(`button`,{onClick:()=>c(`decisions`),className:`w-full flex items-center justify-between px-5 py-3 transition-colors`,onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{className:`text-amber-400`,children:`⚖`}),(0,i.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`Decision Log`}),(0,i.jsx)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:t.decisions.length})]}),(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:o.decisions?`▼`:`▶`})]}),o.decisions&&(0,i.jsxs)(`div`,{className:`px-5 pb-4 space-y-2`,children:[t.decisions.filter(l).map((e,t)=>(0,i.jsx)(`div`,{className:`rounded-lg p-3 text-sm`,style:{background:`var(--bg-surface-hover)`,color:`var(--text-secondary)`},children:e},t)),t.decisions.length===0&&(0,i.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`No decisions logged yet.`})]})]})]})}export{a as CerebrumViewer};
@@ -1 +1 @@
1
- import{a as e,c as t,r as n,t as r}from"./index-BZOA5m43.js";import{i,n as a}from"./utils-BqE_aDxV.js";import{t as o}from"./StatusBadge-CzoOrUrs.js";var s=t(e(),1),c=n();function l({data:e}){let{cronManifest:t,cronState:n,client:l}=e,[u,d]=(0,s.useState)(!0),[f,p]=(0,s.useState)(!1),[m,h]=(0,s.useState)({}),g=e=>n.dead_letter_queue.some(t=>t.task_id===e)?`failed`:n.execution_log.filter(t=>t.task_id===e).sort((e,t)=>t.timestamp.localeCompare(e.timestamp))[0]?.status||`ok`,_=e=>{let t=n.execution_log.filter(t=>t.task_id===e).sort((e,t)=>t.timestamp.localeCompare(e.timestamp))[0];return t?i(t.timestamp):`never`},v=e=>{h(t=>({...t,[e]:`running`})),r(`/api/cron/run/${encodeURIComponent(e)}`,{method:`POST`}).then(t=>{h(n=>({...n,[e]:t.ok?`ok`:`error`})),setTimeout(()=>h(t=>{let n={...t};return delete n[e],n}),3e3)}).catch(()=>{h(t=>({...t,[e]:`error`})),setTimeout(()=>h(t=>{let n={...t};return delete n[e],n}),3e3)})},y=e=>{l?.send({type:`retry_dead_letter`,task_id:e})};return(0,c.jsxs)(`div`,{children:[(0,c.jsx)(`div`,{className:`rounded-xl overflow-hidden mb-6`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:(0,c.jsxs)(`table`,{className:`w-full`,children:[(0,c.jsx)(`thead`,{children:(0,c.jsxs)(`tr`,{style:{borderBottom:`1px solid var(--border)`},children:[(0,c.jsx)(`th`,{className:`text-left px-4 py-3 text-xs font-medium uppercase`,style:{color:`var(--text-faint)`},children:`Status`}),(0,c.jsx)(`th`,{className:`text-left px-4 py-3 text-xs font-medium uppercase`,style:{color:`var(--text-faint)`},children:`Task`}),(0,c.jsx)(`th`,{className:`text-left px-4 py-3 text-xs font-medium uppercase hidden md:table-cell`,style:{color:`var(--text-faint)`},children:`Schedule`}),(0,c.jsx)(`th`,{className:`text-left px-4 py-3 text-xs font-medium uppercase hidden md:table-cell`,style:{color:`var(--text-faint)`},children:`Last Run`}),(0,c.jsx)(`th`,{className:`text-right px-4 py-3 text-xs font-medium uppercase`,style:{color:`var(--text-faint)`},children:`Actions`})]})}),(0,c.jsx)(`tbody`,{children:t.tasks.map(e=>(0,c.jsxs)(`tr`,{className:`transition-colors`,style:{borderBottom:`1px solid var(--border)`},onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,c.jsx)(`td`,{className:`px-4 py-3`,children:(0,c.jsx)(o,{status:e.enabled?g(e.id):`disabled`})}),(0,c.jsxs)(`td`,{className:`px-4 py-3`,children:[(0,c.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-primary)`},children:e.name}),(0,c.jsx)(`p`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:e.description})]}),(0,c.jsx)(`td`,{className:`px-4 py-3 hidden md:table-cell text-sm`,style:{color:`var(--text-muted)`},children:a(e.schedule)}),(0,c.jsx)(`td`,{className:`px-4 py-3 hidden md:table-cell text-sm`,style:{color:`var(--text-faint)`},children:_(e.id)}),(0,c.jsx)(`td`,{className:`px-4 py-3 text-right`,children:(()=>{let t=m[e.id];return(0,c.jsx)(`button`,{onClick:()=>v(e.id),disabled:t===`running`,className:`px-3 py-1 text-xs rounded-md transition-colors`,style:{background:`var(--bg-surface-hover)`,border:`1px solid var(--border-subtle)`,color:t===`ok`?`var(--accent)`:t===`error`?`var(--danger)`:`var(--text-secondary)`,opacity:t===`running`?.6:1},children:t===`running`?`Running…`:t===`ok`?`Triggered ✓`:t===`error`?`Failed ✗`:`Run Now`})})()})]},e.id))})]})}),(0,c.jsxs)(`div`,{className:`rounded-xl p-5 mb-6`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,c.jsxs)(`button`,{onClick:()=>d(!u),className:`flex items-center gap-2 w-full text-left`,children:[(0,c.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:u?`▼`:`▶`}),(0,c.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`Dead Letter Queue`}),(0,c.jsxs)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:[`(`,n.dead_letter_queue.length,`)`]})]}),u&&(n.dead_letter_queue.length===0?(0,c.jsx)(`div`,{className:`text-center py-6 text-sm mt-2`,style:{color:`var(--text-muted)`},children:`No dead letters — all systems healthy`}):(0,c.jsx)(`div`,{className:`space-y-3 mt-3`,children:n.dead_letter_queue.map((e,t)=>(0,c.jsx)(`div`,{className:`rounded-lg p-4`,style:{background:`var(--danger-subtle)`,border:`1px solid rgba(220, 38, 38, 0.2)`},children:(0,c.jsxs)(`div`,{className:`flex items-start justify-between`,children:[(0,c.jsxs)(`div`,{children:[(0,c.jsx)(`p`,{className:`text-sm font-medium`,style:{color:`var(--danger)`},children:e.task_id}),(0,c.jsx)(`p`,{className:`text-xs mt-1`,style:{color:`var(--text-muted)`},children:e.error}),(0,c.jsxs)(`p`,{className:`text-xs mt-1`,style:{color:`var(--text-faint)`},children:[i(e.timestamp),` · `,e.attempts,` attempts`]})]}),(0,c.jsx)(`button`,{onClick:()=>y(e.task_id),className:`px-3 py-1 text-xs rounded-md`,style:{background:`var(--bg-surface-hover)`,border:`1px solid var(--border-subtle)`,color:`var(--text-secondary)`},children:`Retry`})]})},t))}))]}),(0,c.jsxs)(`div`,{className:`rounded-xl p-5`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,c.jsxs)(`button`,{onClick:()=>p(!f),className:`flex items-center gap-2 w-full text-left`,children:[(0,c.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:f?`▼`:`▶`}),(0,c.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`Execution History`})]}),f&&(0,c.jsxs)(`div`,{className:`mt-3`,children:[n.execution_log.slice(-30).reverse().map((e,t)=>(0,c.jsxs)(`div`,{className:`flex items-center gap-4 py-2`,style:{borderBottom:`1px solid var(--border)`},children:[(0,c.jsx)(`span`,{className:`text-xs font-mono`,style:{color:`var(--text-faint)`},children:e.timestamp?.slice(11,16)}),(0,c.jsx)(`span`,{className:`text-sm flex-1`,style:{color:`var(--text-secondary)`},children:e.task_id}),(0,c.jsxs)(`span`,{className:`text-xs font-mono`,style:{color:`var(--text-faint)`},children:[e.duration_ms,`ms`]}),(0,c.jsx)(o,{status:e.status})]},t)),n.execution_log.length===0&&(0,c.jsx)(`p`,{className:`text-sm py-4 text-center`,style:{color:`var(--text-muted)`},children:`No executions yet.`})]})]})]})}export{l as CronStatus};
1
+ import{a as e,c as t,r as n,t as r}from"./index-CCxQQi4q.js";import{i,n as a}from"./utils-BqE_aDxV.js";import{t as o}from"./StatusBadge-DxWVdzKK.js";var s=t(e(),1),c=n();function l({data:e}){let{cronManifest:t,cronState:n,client:l}=e,[u,d]=(0,s.useState)(!0),[f,p]=(0,s.useState)(!1),[m,h]=(0,s.useState)({}),g=e=>n.dead_letter_queue.some(t=>t.task_id===e)?`failed`:n.execution_log.filter(t=>t.task_id===e).sort((e,t)=>t.timestamp.localeCompare(e.timestamp))[0]?.status||`ok`,_=e=>{let t=n.execution_log.filter(t=>t.task_id===e).sort((e,t)=>t.timestamp.localeCompare(e.timestamp))[0];return t?i(t.timestamp):`never`},v=e=>{h(t=>({...t,[e]:`running`})),r(`/api/cron/run/${encodeURIComponent(e)}`,{method:`POST`}).then(t=>{h(n=>({...n,[e]:t.ok?`ok`:`error`})),setTimeout(()=>h(t=>{let n={...t};return delete n[e],n}),3e3)}).catch(()=>{h(t=>({...t,[e]:`error`})),setTimeout(()=>h(t=>{let n={...t};return delete n[e],n}),3e3)})},y=e=>{l?.send({type:`retry_dead_letter`,task_id:e})};return(0,c.jsxs)(`div`,{children:[(0,c.jsx)(`div`,{className:`rounded-xl overflow-hidden mb-6`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:(0,c.jsxs)(`table`,{className:`w-full`,children:[(0,c.jsx)(`thead`,{children:(0,c.jsxs)(`tr`,{style:{borderBottom:`1px solid var(--border)`},children:[(0,c.jsx)(`th`,{className:`text-left px-4 py-3 text-xs font-medium uppercase`,style:{color:`var(--text-faint)`},children:`Status`}),(0,c.jsx)(`th`,{className:`text-left px-4 py-3 text-xs font-medium uppercase`,style:{color:`var(--text-faint)`},children:`Task`}),(0,c.jsx)(`th`,{className:`text-left px-4 py-3 text-xs font-medium uppercase hidden md:table-cell`,style:{color:`var(--text-faint)`},children:`Schedule`}),(0,c.jsx)(`th`,{className:`text-left px-4 py-3 text-xs font-medium uppercase hidden md:table-cell`,style:{color:`var(--text-faint)`},children:`Last Run`}),(0,c.jsx)(`th`,{className:`text-right px-4 py-3 text-xs font-medium uppercase`,style:{color:`var(--text-faint)`},children:`Actions`})]})}),(0,c.jsx)(`tbody`,{children:t.tasks.map(e=>(0,c.jsxs)(`tr`,{className:`transition-colors`,style:{borderBottom:`1px solid var(--border)`},onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,c.jsx)(`td`,{className:`px-4 py-3`,children:(0,c.jsx)(o,{status:e.enabled?g(e.id):`disabled`})}),(0,c.jsxs)(`td`,{className:`px-4 py-3`,children:[(0,c.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-primary)`},children:e.name}),(0,c.jsx)(`p`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:e.description})]}),(0,c.jsx)(`td`,{className:`px-4 py-3 hidden md:table-cell text-sm`,style:{color:`var(--text-muted)`},children:a(e.schedule)}),(0,c.jsx)(`td`,{className:`px-4 py-3 hidden md:table-cell text-sm`,style:{color:`var(--text-faint)`},children:_(e.id)}),(0,c.jsx)(`td`,{className:`px-4 py-3 text-right`,children:(()=>{let t=m[e.id];return(0,c.jsx)(`button`,{onClick:()=>v(e.id),disabled:t===`running`,className:`px-3 py-1 text-xs rounded-md transition-colors`,style:{background:`var(--bg-surface-hover)`,border:`1px solid var(--border-subtle)`,color:t===`ok`?`var(--accent)`:t===`error`?`var(--danger)`:`var(--text-secondary)`,opacity:t===`running`?.6:1},children:t===`running`?`Running…`:t===`ok`?`Triggered ✓`:t===`error`?`Failed ✗`:`Run Now`})})()})]},e.id))})]})}),(0,c.jsxs)(`div`,{className:`rounded-xl p-5 mb-6`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,c.jsxs)(`button`,{onClick:()=>d(!u),className:`flex items-center gap-2 w-full text-left`,children:[(0,c.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:u?`▼`:`▶`}),(0,c.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`Dead Letter Queue`}),(0,c.jsxs)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:[`(`,n.dead_letter_queue.length,`)`]})]}),u&&(n.dead_letter_queue.length===0?(0,c.jsx)(`div`,{className:`text-center py-6 text-sm mt-2`,style:{color:`var(--text-muted)`},children:`No dead letters — all systems healthy`}):(0,c.jsx)(`div`,{className:`space-y-3 mt-3`,children:n.dead_letter_queue.map((e,t)=>(0,c.jsx)(`div`,{className:`rounded-lg p-4`,style:{background:`var(--danger-subtle)`,border:`1px solid rgba(220, 38, 38, 0.2)`},children:(0,c.jsxs)(`div`,{className:`flex items-start justify-between`,children:[(0,c.jsxs)(`div`,{children:[(0,c.jsx)(`p`,{className:`text-sm font-medium`,style:{color:`var(--danger)`},children:e.task_id}),(0,c.jsx)(`p`,{className:`text-xs mt-1`,style:{color:`var(--text-muted)`},children:e.error}),(0,c.jsxs)(`p`,{className:`text-xs mt-1`,style:{color:`var(--text-faint)`},children:[i(e.timestamp),` · `,e.attempts,` attempts`]})]}),(0,c.jsx)(`button`,{onClick:()=>y(e.task_id),className:`px-3 py-1 text-xs rounded-md`,style:{background:`var(--bg-surface-hover)`,border:`1px solid var(--border-subtle)`,color:`var(--text-secondary)`},children:`Retry`})]})},t))}))]}),(0,c.jsxs)(`div`,{className:`rounded-xl p-5`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,c.jsxs)(`button`,{onClick:()=>p(!f),className:`flex items-center gap-2 w-full text-left`,children:[(0,c.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:f?`▼`:`▶`}),(0,c.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`Execution History`})]}),f&&(0,c.jsxs)(`div`,{className:`mt-3`,children:[n.execution_log.slice(-30).reverse().map((e,t)=>(0,c.jsxs)(`div`,{className:`flex items-center gap-4 py-2`,style:{borderBottom:`1px solid var(--border)`},children:[(0,c.jsx)(`span`,{className:`text-xs font-mono`,style:{color:`var(--text-faint)`},children:e.timestamp?.slice(11,16)}),(0,c.jsx)(`span`,{className:`text-sm flex-1`,style:{color:`var(--text-secondary)`},children:e.task_id}),(0,c.jsxs)(`span`,{className:`text-xs font-mono`,style:{color:`var(--text-faint)`},children:[e.duration_ms,`ms`]}),(0,c.jsx)(o,{status:e.status})]},t)),n.execution_log.length===0&&(0,c.jsx)(`p`,{className:`text-sm py-4 text-center`,style:{color:`var(--text-muted)`},children:`No executions yet.`})]})]})]})}export{l as CronStatus};
@@ -1 +1 @@
1
- import{a as e,c as t,n,r,t as i}from"./index-BZOA5m43.js";var a=t(e(),1),o=r(),s=e=>n(`/api/designqc/capture/${encodeURIComponent(e)}`);function c({data:e}){let{designqcReport:t,project:n}=e,[r,c]=(0,a.useState)(`idle`),[l,u]=(0,a.useState)(null),[d,f]=(0,a.useState)(null),p=t&&t.captures&&t.captures.length>0;return(0,o.jsxs)(`div`,{children:[(0,o.jsxs)(`div`,{className:`rounded-xl px-4 py-3 mb-6 flex items-start gap-3`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,o.jsx)(`span`,{style:{color:`var(--text-faint)`,marginTop:1},children:`ℹ`}),(0,o.jsxs)(`div`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:[`Works with `,(0,o.jsx)(`span`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`any accessible URL`}),` — local or deployed. The URL is auto-detected from `,(0,o.jsx)(`code`,{className:`px-1 rounded text-xs`,style:{background:`var(--bg-base)`},children:`package.json`}),` homepage, env files, or a running dev server.`,n?.root&&(0,o.jsxs)(`span`,{children:[` Scanning `,(0,o.jsx)(`code`,{className:`px-1 rounded text-xs`,style:{background:`var(--bg-base)`},children:n.root}),`.`]})]})]}),(0,o.jsxs)(`div`,{className:`rounded-xl p-5 mb-6`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,o.jsxs)(`div`,{className:`flex items-center justify-between mb-3`,children:[(0,o.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`Capture Screenshots`}),(0,o.jsx)(`button`,{onClick:()=>{c(`running`),u(null),i(`/api/designqc/run`,{method:`POST`,headers:{"Content-Type":`application/json`},body:`{}`}).then(async e=>{if(!e.ok){let t=await e.json().catch(()=>({error:e.statusText}));throw Error(t.error||e.statusText)}c(`idle`)}).catch(e=>{c(`error`),u(e.message)})},disabled:r===`running`,className:`px-4 py-1.5 text-sm rounded-lg transition-colors`,style:{background:r===`error`?`var(--danger-subtle)`:`var(--accent-subtle)`,border:`1px solid ${r===`error`?`rgba(220,38,38,0.3)`:`var(--accent)`}`,color:r===`error`?`var(--danger)`:`var(--accent)`,opacity:r===`running`?.6:1},children:r===`running`?`Capturing…`:r===`error`?`Retry Capture`:`Run Capture`})]}),r===`running`&&(0,o.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`Auto-detecting URL, launching browser, capturing screenshots… this takes ~15–30s.`}),r===`error`&&l&&(0,o.jsx)(`p`,{className:`text-sm`,style:{color:`var(--danger)`},children:l}),r===`idle`&&(0,o.jsxs)(`div`,{className:`space-y-1.5 text-sm`,style:{color:`var(--text-muted)`},children:[(0,o.jsxs)(`p`,{children:[`Detects your URL automatically from `,(0,o.jsx)(`code`,{className:`px-1 rounded text-xs`,style:{background:`var(--bg-base)`},children:`package.json`}),`, env files, or a running dev server.`]}),(0,o.jsxs)(`p`,{children:[`After capture, ask Claude: `,(0,o.jsx)(`span`,{className:`italic`,children:`"Read .wolf/designqc-captures/ and evaluate the design"`})]})]})]}),(0,o.jsxs)(`div`,{className:`rounded-xl p-5`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,o.jsx)(`h3`,{className:`font-medium mb-3`,style:{color:`var(--text-secondary)`},children:`Last Capture`}),p?(0,o.jsxs)(`div`,{children:[(0,o.jsxs)(`div`,{className:`flex gap-4 text-sm mb-4`,children:[(0,o.jsxs)(`span`,{style:{color:`var(--text-faint)`},children:[`Captured: `,t.captured_at||`—`]}),(0,o.jsxs)(`span`,{style:{color:`var(--text-faint)`},children:[`Size: `,t.total_size_kb||0,`KB`]}),(0,o.jsxs)(`span`,{style:{color:`var(--text-faint)`},children:[`Est. tokens: ~`,t.estimated_tokens||0]})]}),(0,o.jsx)(`div`,{className:`grid grid-cols-2 md:grid-cols-3 gap-4`,children:t.captures.map((e,t)=>(0,o.jsxs)(`button`,{onClick:()=>f(e.file),className:`text-left rounded-lg overflow-hidden transition-transform hover:-translate-y-0.5`,style:{background:`var(--bg-base)`,border:`1px solid var(--border)`},title:`Klicken zum Vergrößern`,children:[(0,o.jsx)(`img`,{src:s(e.file),alt:`${e.viewport} · ${e.route}`,loading:`lazy`,className:`w-full block`,style:{maxHeight:200,objectFit:`cover`,objectPosition:`top`,background:`var(--bg-surface)`}}),(0,o.jsxs)(`div`,{className:`px-3 py-2`,children:[(0,o.jsx)(`div`,{className:`text-sm truncate`,style:{color:`var(--text-primary)`},children:e.file}),(0,o.jsxs)(`div`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:[e.viewport,` · `,e.route]})]})]},t))})]}):(0,o.jsx)(`div`,{className:`text-center py-8`,children:(0,o.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`No screenshots captured yet.`})})]}),d&&(0,o.jsxs)(`div`,{onClick:()=>f(null),className:`fixed inset-0 z-50 flex items-center justify-center p-6`,style:{background:`rgba(0,0,0,0.8)`},children:[(0,o.jsx)(`div`,{className:`relative max-w-6xl max-h-[90vh] overflow-auto rounded-lg`,onClick:e=>e.stopPropagation(),children:(0,o.jsx)(`img`,{src:s(d),alt:d,className:`block`,style:{maxWidth:`100%`}})}),(0,o.jsx)(`button`,{onClick:()=>f(null),className:`absolute top-4 right-4 w-9 h-9 rounded-full flex items-center justify-center text-lg`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`},"aria-label":`Schließen`,children:`✕`})]})]})}export{c as DesignQC};
1
+ import{a as e,c as t,n,r,t as i}from"./index-CCxQQi4q.js";var a=t(e(),1),o=r(),s=e=>n(`/api/designqc/capture/${encodeURIComponent(e)}`);function c({data:e}){let{designqcReport:t,project:n}=e,[r,c]=(0,a.useState)(`idle`),[l,u]=(0,a.useState)(null),[d,f]=(0,a.useState)(null),p=t&&t.captures&&t.captures.length>0;return(0,o.jsxs)(`div`,{children:[(0,o.jsxs)(`div`,{className:`rounded-xl px-4 py-3 mb-6 flex items-start gap-3`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,o.jsx)(`span`,{style:{color:`var(--text-faint)`,marginTop:1},children:`ℹ`}),(0,o.jsxs)(`div`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:[`Works with `,(0,o.jsx)(`span`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`any accessible URL`}),` — local or deployed. The URL is auto-detected from `,(0,o.jsx)(`code`,{className:`px-1 rounded text-xs`,style:{background:`var(--bg-base)`},children:`package.json`}),` homepage, env files, or a running dev server.`,n?.root&&(0,o.jsxs)(`span`,{children:[` Scanning `,(0,o.jsx)(`code`,{className:`px-1 rounded text-xs`,style:{background:`var(--bg-base)`},children:n.root}),`.`]})]})]}),(0,o.jsxs)(`div`,{className:`rounded-xl p-5 mb-6`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,o.jsxs)(`div`,{className:`flex items-center justify-between mb-3`,children:[(0,o.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`Capture Screenshots`}),(0,o.jsx)(`button`,{onClick:()=>{c(`running`),u(null),i(`/api/designqc/run`,{method:`POST`,headers:{"Content-Type":`application/json`},body:`{}`}).then(async e=>{if(!e.ok){let t=await e.json().catch(()=>({error:e.statusText}));throw Error(t.error||e.statusText)}c(`idle`)}).catch(e=>{c(`error`),u(e.message)})},disabled:r===`running`,className:`px-4 py-1.5 text-sm rounded-lg transition-colors`,style:{background:r===`error`?`var(--danger-subtle)`:`var(--accent-subtle)`,border:`1px solid ${r===`error`?`rgba(220,38,38,0.3)`:`var(--accent)`}`,color:r===`error`?`var(--danger)`:`var(--accent)`,opacity:r===`running`?.6:1},children:r===`running`?`Capturing…`:r===`error`?`Retry Capture`:`Run Capture`})]}),r===`running`&&(0,o.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`Auto-detecting URL, launching browser, capturing screenshots… this takes ~15–30s.`}),r===`error`&&l&&(0,o.jsx)(`p`,{className:`text-sm`,style:{color:`var(--danger)`},children:l}),r===`idle`&&(0,o.jsxs)(`div`,{className:`space-y-1.5 text-sm`,style:{color:`var(--text-muted)`},children:[(0,o.jsxs)(`p`,{children:[`Detects your URL automatically from `,(0,o.jsx)(`code`,{className:`px-1 rounded text-xs`,style:{background:`var(--bg-base)`},children:`package.json`}),`, env files, or a running dev server.`]}),(0,o.jsxs)(`p`,{children:[`After capture, ask Claude: `,(0,o.jsx)(`span`,{className:`italic`,children:`"Read .wolf/designqc-captures/ and evaluate the design"`})]})]})]}),(0,o.jsxs)(`div`,{className:`rounded-xl p-5`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,o.jsx)(`h3`,{className:`font-medium mb-3`,style:{color:`var(--text-secondary)`},children:`Last Capture`}),p?(0,o.jsxs)(`div`,{children:[(0,o.jsxs)(`div`,{className:`flex gap-4 text-sm mb-4`,children:[(0,o.jsxs)(`span`,{style:{color:`var(--text-faint)`},children:[`Captured: `,t.captured_at||`—`]}),(0,o.jsxs)(`span`,{style:{color:`var(--text-faint)`},children:[`Size: `,t.total_size_kb||0,`KB`]}),(0,o.jsxs)(`span`,{style:{color:`var(--text-faint)`},children:[`Est. tokens: ~`,t.estimated_tokens||0]})]}),(0,o.jsx)(`div`,{className:`grid grid-cols-2 md:grid-cols-3 gap-4`,children:t.captures.map((e,t)=>(0,o.jsxs)(`button`,{onClick:()=>f(e.file),className:`text-left rounded-lg overflow-hidden transition-transform hover:-translate-y-0.5`,style:{background:`var(--bg-base)`,border:`1px solid var(--border)`},title:`Klicken zum Vergrößern`,children:[(0,o.jsx)(`img`,{src:s(e.file),alt:`${e.viewport} · ${e.route}`,loading:`lazy`,className:`w-full block`,style:{maxHeight:200,objectFit:`cover`,objectPosition:`top`,background:`var(--bg-surface)`}}),(0,o.jsxs)(`div`,{className:`px-3 py-2`,children:[(0,o.jsx)(`div`,{className:`text-sm truncate`,style:{color:`var(--text-primary)`},children:e.file}),(0,o.jsxs)(`div`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:[e.viewport,` · `,e.route]})]})]},t))})]}):(0,o.jsx)(`div`,{className:`text-center py-8`,children:(0,o.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`No screenshots captured yet.`})})]}),d&&(0,o.jsxs)(`div`,{onClick:()=>f(null),className:`fixed inset-0 z-50 flex items-center justify-center p-6`,style:{background:`rgba(0,0,0,0.8)`},children:[(0,o.jsx)(`div`,{className:`relative max-w-6xl max-h-[90vh] overflow-auto rounded-lg`,onClick:e=>e.stopPropagation(),children:(0,o.jsx)(`img`,{src:s(d),alt:d,className:`block`,style:{maxWidth:`100%`}})}),(0,o.jsx)(`button`,{onClick:()=>f(null),className:`absolute top-4 right-4 w-9 h-9 rounded-full flex items-center justify-center text-lg`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`},"aria-label":`Schließen`,children:`✕`})]})]})}export{c as DesignQC};
@@ -0,0 +1 @@
1
+ import{a as e,c as t,r as n,t as r}from"./index-CCxQQi4q.js";var i=t(e(),1),a=n();function o(e,t,n,r){let i=new Map(e.map((e,t)=>[e.key,t])),a=e.length,o=new Float64Array(a),s=new Float64Array(a);for(let e=0;e<a;e++){let t=e*2.399963%(Math.PI*2),i=Math.sqrt((e+.5)/a)*Math.min(n,r)*.42;o[e]=n/2+Math.cos(t)*i,s[e]=r/2+Math.sin(t)*i}let c=t.map(e=>[i.get(e.from),i.get(e.to)]).filter(e=>e[0]!==void 0&&e[1]!==void 0);for(let e=0;e<220;e++){let t=1-e/220;for(let e=0;e<a;e++)for(let n=e+1;n<a;n++){let r=o[e]-o[n],i=s[e]-s[n],a=r*r+i*i;if(a<1&&(a=1,r=e-n||1,i=1),a>9e4)continue;let c=420/a*t,l=Math.sqrt(a);o[e]+=r/l*c,s[e]+=i/l*c,o[n]-=r/l*c,s[n]-=i/l*c}for(let[e,n]of c){let r=o[n]-o[e],i=s[n]-s[e],a=Math.max(1,Math.hypot(r,i)),c=(a-72)*.02*t;o[e]+=r/a*c,s[e]+=i/a*c,o[n]-=r/a*c,s[n]-=i/a*c}for(let e=0;e<a;e++)o[e]=Math.max(14,Math.min(n-14,o[e])),s[e]=Math.max(14,Math.min(r-14,s[e]))}return{x:o,y:s,idx:i}}function s(){let[e,t]=(0,i.useState)(null),[n,s]=(0,i.useState)(null),c=(0,i.useRef)(null);(0,i.useEffect)(()=>{r(`/api/link-graph`).then(e=>e.json()).then(t).catch(()=>t({available:!1,error:`not reachable`}))},[]);let l=(0,i.useMemo)(()=>(e?.nodes??[]).filter(e=>e.in+e.out>0),[e]),u=(0,i.useMemo)(()=>[...l].sort((e,t)=>t.in+t.out-(e.in+e.out)).slice(0,90),[l]),d=(0,i.useMemo)(()=>new Set(u.map(e=>e.key)),[u]),f=(0,i.useMemo)(()=>(e?.edges??[]).filter(e=>d.has(e.from)&&d.has(e.to)),[e,d]),p=(e?.nodes?.length??0)-l.length;if((0,i.useEffect)(()=>{let t=c.current;if(!t||!e?.available||u.length===0)return;let r=t.width,i=t.height,{x:a,y:s,idx:l}=o(u,f,r,i),d=t.getContext(`2d`);if(!d)return;d.clearRect(0,0,r,i),d.strokeStyle=`rgba(148,163,184,0.22)`,d.lineWidth=1;for(let e of f){let t=l.get(e.from),n=l.get(e.to);t===void 0||n===void 0||(d.beginPath(),d.moveTo(a[t],s[t]),d.lineTo(a[n],s[n]),d.stroke())}let p=Math.max(1,...u.map(e=>e.in));u.forEach((e,t)=>{let r=3+Math.sqrt(e.in/p)*9;d.beginPath(),d.arc(a[t],s[t],r,0,Math.PI*2),d.fillStyle=e.key===n?`#fbbf24`:e.in>0?`#34d399`:`#64748b`,d.fill()}),d.fillStyle=`rgba(226,232,240,0.85)`,d.font=`11px ui-monospace, monospace`,[...u].sort((e,t)=>t.in-e.in).slice(0,8).forEach(e=>{let t=l.get(e.key);d.fillText(e.title.replace(/\.md$/,``).slice(0,26),a[t]+10,s[t]+4)})},[e,u,f,n]),!e)return(0,a.jsx)(`div`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`Loading…`});if(!e.available)return(0,a.jsxs)(`div`,{className:`rounded-xl p-5 text-sm`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-muted)`},children:[`No link graph available`,e.error?` — ${e.error}`:``,`.`]});let m=[...e.nodes??[]].sort((e,t)=>t.in-e.in).filter(e=>e.in>0).slice(0,12);return(0,a.jsxs)(`div`,{className:`grid gap-6 lg:grid-cols-[1.4fr_1fr]`,children:[(0,a.jsxs)(`div`,{className:`rounded-xl p-5`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,a.jsxs)(`div`,{className:`mb-3 flex items-baseline justify-between`,children:[(0,a.jsx)(`h3`,{className:`font-medium`,style:{color:`var(--text-secondary)`},children:`Link graph`}),(0,a.jsxs)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:[u.length,` of `,l.length,` linked shown · `,p,` isolated · `,e.edges?.length??0,` links`]})]}),(0,a.jsx)(`canvas`,{ref:c,width:760,height:460,className:`w-full rounded-lg`,style:{background:`var(--bg-base)`,border:`1px solid var(--border)`}}),(0,a.jsxs)(`p`,{className:`mt-3 text-xs`,style:{color:`var(--text-faint)`},children:[`The `,90,` best-connected notes; dot size follows how often a note is referenced. Drawing all `,l.length,` produced a hairball, so the rest is counted rather than drawn —`,e.stats?.blocks.toLocaleString(`en-US`),` blocks sit behind these `,e.stats?.files,` files.`]})]}),(0,a.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,a.jsxs)(`div`,{className:`rounded-xl p-5`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,a.jsx)(`h3`,{className:`mb-3 font-medium`,style:{color:`var(--text-secondary)`},children:`Most referenced`}),m.length===0?(0,a.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`Nothing links to anything yet.`}):(0,a.jsx)(`ul`,{className:`flex flex-col gap-1.5 text-sm`,children:m.map(e=>(0,a.jsx)(`li`,{children:(0,a.jsxs)(`button`,{onClick:()=>s(e.key===n?null:e.key),className:`flex w-full items-center gap-2 rounded px-1.5 py-1 text-left hover:bg-white/5`,style:{color:e.key===n?`var(--accent)`:`var(--text-primary)`},children:[(0,a.jsx)(`span`,{className:`font-mono text-xs tabular-nums`,style:{color:`var(--text-faint)`},children:String(e.in).padStart(2,` `)}),(0,a.jsx)(`span`,{className:`truncate`,children:e.title.replace(/\.md$/,``)})]})},e.key))})]}),(0,a.jsxs)(`div`,{className:`rounded-xl p-5`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,a.jsxs)(`h3`,{className:`mb-1 font-medium`,style:{color:`var(--text-secondary)`},children:[`Dead references `,e.dangling?.length?`(${e.dangling.length})`:``]}),(0,a.jsx)(`p`,{className:`mb-3 text-xs`,style:{color:`var(--text-faint)`},children:`A link whose target does not exist. Named rather than swallowed — each one is a note that was meant to be written, or a link that was mistyped.`}),(e.dangling?.length??0)===0?(0,a.jsx)(`p`,{className:`text-sm`,style:{color:`var(--accent)`},children:`None. Every reference resolves.`}):(0,a.jsx)(`ul`,{className:`flex flex-col gap-2 text-sm`,children:e.dangling.slice(0,12).map((e,t)=>(0,a.jsxs)(`li`,{className:`leading-snug`,children:[(0,a.jsx)(`code`,{className:`text-xs`,style:{color:`#f87171`},children:e.target}),(0,a.jsxs)(`div`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:[`from `,e.fromSrc.replace(/^native\//,``)]})]},t))})]})]})]})}export{s as LinkGraph};
@@ -1 +1 @@
1
- import{a as e,c as t,r as n}from"./index-BZOA5m43.js";var r=t(e(),1),i=n();function a({data:e}){let{memory:t}=e,[n,a]=(0,r.useState)(0),[o,s]=(0,r.useState)(``),c=o?t.filter(e=>e.entries.some(e=>e.action.toLowerCase().includes(o.toLowerCase())||e.files.toLowerCase().includes(o.toLowerCase()))):t;return(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`div`,{className:`flex items-center gap-3 mb-4`,children:(0,i.jsx)(`input`,{type:`text`,placeholder:`Search memory...`,value:o,onChange:e=>s(e.target.value),className:`flex-1 rounded-lg px-3 py-2 text-sm focus:outline-none`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`}})}),c.length===0?(0,i.jsx)(`div`,{className:`text-center py-12`,style:{color:`var(--text-muted)`},children:`No sessions found.`}):(0,i.jsx)(`div`,{className:`space-y-3`,children:c.map((e,t)=>{let r=n===t,o=e.entries.reduce((e,t)=>e+(parseInt(t.tokens.replace(/[^0-9]/g,``))||0),0);return(0,i.jsxs)(`div`,{className:`rounded-xl overflow-hidden`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,i.jsxs)(`button`,{onClick:()=>a(r?-1:t),className:`w-full flex items-center justify-between px-5 py-3 transition-colors`,onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:r?`▼`:`▶`}),(0,i.jsxs)(`span`,{className:`text-sm font-medium`,style:{color:`var(--text-primary)`},children:[e.date,` `,e.time]}),(0,i.jsxs)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:[e.entries.length,` actions`]})]}),o>0&&(0,i.jsxs)(`span`,{className:`text-xs font-mono`,style:{color:`var(--text-faint)`},children:[`~`,o,` tok`]})]}),r&&e.entries.length>0&&(0,i.jsx)(`div`,{style:{borderTop:`1px solid var(--border)`},children:(0,i.jsxs)(`table`,{className:`w-full`,children:[(0,i.jsx)(`thead`,{children:(0,i.jsxs)(`tr`,{className:`text-xs uppercase`,style:{color:`var(--text-faint)`},children:[(0,i.jsx)(`th`,{className:`text-left px-4 py-2 w-16`,children:`Time`}),(0,i.jsx)(`th`,{className:`text-left px-4 py-2`,children:`Action`}),(0,i.jsx)(`th`,{className:`text-left px-4 py-2 hidden md:table-cell`,children:`Files`}),(0,i.jsx)(`th`,{className:`text-left px-4 py-2 hidden md:table-cell`,children:`Outcome`}),(0,i.jsx)(`th`,{className:`text-right px-4 py-2 w-20`,children:`Tokens`})]})}),(0,i.jsx)(`tbody`,{children:e.entries.map((e,t)=>(0,i.jsxs)(`tr`,{style:{borderBottom:`1px solid var(--border)`},onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsx)(`td`,{className:`px-4 py-2 text-xs font-mono`,style:{color:`var(--text-faint)`},children:e.time}),(0,i.jsx)(`td`,{className:`px-4 py-2 text-sm`,style:{color:`var(--text-secondary)`},children:e.action}),(0,i.jsx)(`td`,{className:`px-4 py-2 text-sm hidden md:table-cell`,style:{color:`var(--text-muted)`},children:e.files}),(0,i.jsx)(`td`,{className:`px-4 py-2 text-sm hidden md:table-cell`,style:{color:`var(--text-muted)`},children:e.outcome}),(0,i.jsx)(`td`,{className:`px-4 py-2 text-xs font-mono text-right`,style:{color:`var(--text-faint)`},children:e.tokens})]},t))})]})})]},t)})})]})}export{a as MemoryViewer};
1
+ import{a as e,c as t,r as n}from"./index-CCxQQi4q.js";var r=t(e(),1),i=n();function a({data:e}){let{memory:t}=e,[n,a]=(0,r.useState)(0),[o,s]=(0,r.useState)(``),c=o?t.filter(e=>e.entries.some(e=>e.action.toLowerCase().includes(o.toLowerCase())||e.files.toLowerCase().includes(o.toLowerCase()))):t;return(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`div`,{className:`flex items-center gap-3 mb-4`,children:(0,i.jsx)(`input`,{type:`text`,placeholder:`Search memory...`,value:o,onChange:e=>s(e.target.value),className:`flex-1 rounded-lg px-3 py-2 text-sm focus:outline-none`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-primary)`}})}),c.length===0?(0,i.jsx)(`div`,{className:`text-center py-12`,style:{color:`var(--text-muted)`},children:`No sessions found.`}):(0,i.jsx)(`div`,{className:`space-y-3`,children:c.map((e,t)=>{let r=n===t,o=e.entries.reduce((e,t)=>e+(parseInt(t.tokens.replace(/[^0-9]/g,``))||0),0);return(0,i.jsxs)(`div`,{className:`rounded-xl overflow-hidden`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,i.jsxs)(`button`,{onClick:()=>a(r?-1:t),className:`w-full flex items-center justify-between px-5 py-3 transition-colors`,onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,i.jsx)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:r?`▼`:`▶`}),(0,i.jsxs)(`span`,{className:`text-sm font-medium`,style:{color:`var(--text-primary)`},children:[e.date,` `,e.time]}),(0,i.jsxs)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:[e.entries.length,` actions`]})]}),o>0&&(0,i.jsxs)(`span`,{className:`text-xs font-mono`,style:{color:`var(--text-faint)`},children:[`~`,o,` tok`]})]}),r&&e.entries.length>0&&(0,i.jsx)(`div`,{style:{borderTop:`1px solid var(--border)`},children:(0,i.jsxs)(`table`,{className:`w-full`,children:[(0,i.jsx)(`thead`,{children:(0,i.jsxs)(`tr`,{className:`text-xs uppercase`,style:{color:`var(--text-faint)`},children:[(0,i.jsx)(`th`,{className:`text-left px-4 py-2 w-16`,children:`Time`}),(0,i.jsx)(`th`,{className:`text-left px-4 py-2`,children:`Action`}),(0,i.jsx)(`th`,{className:`text-left px-4 py-2 hidden md:table-cell`,children:`Files`}),(0,i.jsx)(`th`,{className:`text-left px-4 py-2 hidden md:table-cell`,children:`Outcome`}),(0,i.jsx)(`th`,{className:`text-right px-4 py-2 w-20`,children:`Tokens`})]})}),(0,i.jsx)(`tbody`,{children:e.entries.map((e,t)=>(0,i.jsxs)(`tr`,{style:{borderBottom:`1px solid var(--border)`},onMouseEnter:e=>e.currentTarget.style.background=`var(--bg-surface-hover)`,onMouseLeave:e=>e.currentTarget.style.background=`transparent`,children:[(0,i.jsx)(`td`,{className:`px-4 py-2 text-xs font-mono`,style:{color:`var(--text-faint)`},children:e.time}),(0,i.jsx)(`td`,{className:`px-4 py-2 text-sm`,style:{color:`var(--text-secondary)`},children:e.action}),(0,i.jsx)(`td`,{className:`px-4 py-2 text-sm hidden md:table-cell`,style:{color:`var(--text-muted)`},children:e.files}),(0,i.jsx)(`td`,{className:`px-4 py-2 text-sm hidden md:table-cell`,style:{color:`var(--text-muted)`},children:e.outcome}),(0,i.jsx)(`td`,{className:`px-4 py-2 text-xs font-mono text-right`,style:{color:`var(--text-faint)`},children:e.tokens})]},t))})]})})]},t)})})]})}export{a as MemoryViewer};