openwolf-enhanced 1.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +386 -0
- package/LICENSE +663 -0
- package/NOTICE +48 -0
- package/README.md +283 -0
- package/dist/bin/openwolf.js +10 -0
- package/dist/bin/openwolf.js.map +1 -0
- package/dist/dashboard/assets/AISuggestions-DHXOgHMM.js +9 -0
- package/dist/dashboard/assets/ActivityTimeline-BXLwacZV.js +1 -0
- package/dist/dashboard/assets/AnatomyBrowser-CUyC8M2I.js +1 -0
- package/dist/dashboard/assets/BugLog-Bxvy1sPW.js +1 -0
- package/dist/dashboard/assets/CerebrumViewer-DCySVmzA.js +1 -0
- package/dist/dashboard/assets/CronStatus-BA4fmQX3.js +1 -0
- package/dist/dashboard/assets/DesignQC-BhNEKryS.js +1 -0
- package/dist/dashboard/assets/MemoryViewer-0y9lsDUO.js +1 -0
- package/dist/dashboard/assets/ProjectOverview-CC51rVRe.js +1 -0
- package/dist/dashboard/assets/StatusBadge-4NJI_F2G.js +1 -0
- package/dist/dashboard/assets/TokenUsage-7pCxlnCX.js +55 -0
- package/dist/dashboard/assets/index-4O5rk-qB.css +2 -0
- package/dist/dashboard/assets/index-jfgWxxsn.js +13 -0
- package/dist/dashboard/assets/utils-BqE_aDxV.js +1 -0
- package/dist/dashboard/index.html +16 -0
- package/dist/hooks/post-read.js +85 -0
- package/dist/hooks/post-write.js +520 -0
- package/dist/hooks/pre-read.js +107 -0
- package/dist/hooks/pre-write.js +120 -0
- package/dist/hooks/session-start.js +76 -0
- package/dist/hooks/shared.js +0 -0
- package/dist/hooks/stop.js +219 -0
- package/dist/src/buglog/bug-matcher.js +3 -0
- package/dist/src/buglog/bug-matcher.js.map +1 -0
- package/dist/src/buglog/bug-tracker.js +89 -0
- package/dist/src/buglog/bug-tracker.js.map +1 -0
- package/dist/src/cli/bug-cmd.js +31 -0
- package/dist/src/cli/bug-cmd.js.map +1 -0
- package/dist/src/cli/cron-cmd.js +107 -0
- package/dist/src/cli/cron-cmd.js.map +1 -0
- package/dist/src/cli/daemon-cmd.js +180 -0
- package/dist/src/cli/daemon-cmd.js.map +1 -0
- package/dist/src/cli/dashboard.js +88 -0
- package/dist/src/cli/dashboard.js.map +1 -0
- package/dist/src/cli/designqc-cmd.js +31 -0
- package/dist/src/cli/designqc-cmd.js.map +1 -0
- package/dist/src/cli/doctor-cmd.js +94 -0
- package/dist/src/cli/doctor-cmd.js.map +1 -0
- package/dist/src/cli/index.js +158 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/init.js +493 -0
- package/dist/src/cli/init.js.map +1 -0
- package/dist/src/cli/registry.js +93 -0
- package/dist/src/cli/registry.js.map +1 -0
- package/dist/src/cli/scan.js +39 -0
- package/dist/src/cli/scan.js.map +1 -0
- package/dist/src/cli/status.js +98 -0
- package/dist/src/cli/status.js.map +1 -0
- package/dist/src/cli/update.js +435 -0
- package/dist/src/cli/update.js.map +1 -0
- package/dist/src/daemon/cron-engine.js +321 -0
- package/dist/src/daemon/cron-engine.js.map +1 -0
- package/dist/src/daemon/file-watcher.js +64 -0
- package/dist/src/daemon/file-watcher.js.map +1 -0
- package/dist/src/daemon/health.js +23 -0
- package/dist/src/daemon/health.js.map +1 -0
- package/dist/src/daemon/wolf-daemon.js +440 -0
- package/dist/src/daemon/wolf-daemon.js.map +1 -0
- package/dist/src/designqc/designqc-capture.js +278 -0
- package/dist/src/designqc/designqc-capture.js.map +1 -0
- package/dist/src/designqc/designqc-engine.js +159 -0
- package/dist/src/designqc/designqc-engine.js.map +1 -0
- package/dist/src/designqc/designqc-types.js +5 -0
- package/dist/src/designqc/designqc-types.js.map +1 -0
- package/dist/src/hooks/post-read.js +86 -0
- package/dist/src/hooks/post-read.js.map +1 -0
- package/dist/src/hooks/post-write.js +521 -0
- package/dist/src/hooks/post-write.js.map +1 -0
- package/dist/src/hooks/pre-read.js +108 -0
- package/dist/src/hooks/pre-read.js.map +1 -0
- package/dist/src/hooks/pre-write.js +121 -0
- package/dist/src/hooks/pre-write.js.map +1 -0
- package/dist/src/hooks/session-start.js +77 -0
- package/dist/src/hooks/session-start.js.map +1 -0
- package/dist/src/hooks/shared.js +0 -0
- package/dist/src/hooks/shared.js.map +1 -0
- package/dist/src/hooks/stop.js +220 -0
- package/dist/src/hooks/stop.js.map +1 -0
- package/dist/src/scanner/anatomy-scanner.js +278 -0
- package/dist/src/scanner/anatomy-scanner.js.map +1 -0
- package/dist/src/scanner/description-extractor.js +1007 -0
- package/dist/src/scanner/description-extractor.js.map +1 -0
- package/dist/src/scanner/project-root.js +52 -0
- package/dist/src/scanner/project-root.js.map +1 -0
- package/dist/src/tracker/token-estimator.js +20 -0
- package/dist/src/tracker/token-estimator.js.map +1 -0
- package/dist/src/tracker/token-ledger.js +55 -0
- package/dist/src/tracker/token-ledger.js.map +1 -0
- package/dist/src/tracker/waste-detector.js +101 -0
- package/dist/src/tracker/waste-detector.js.map +1 -0
- package/dist/src/utils/dashboard-auth.js +50 -0
- package/dist/src/utils/dashboard-auth.js.map +1 -0
- package/dist/src/utils/fs-safe.js +135 -0
- package/dist/src/utils/fs-safe.js.map +1 -0
- package/dist/src/utils/hooks-deploy.js +70 -0
- package/dist/src/utils/hooks-deploy.js.map +1 -0
- package/dist/src/utils/logger.js +48 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/maintenance.js +385 -0
- package/dist/src/utils/maintenance.js.map +1 -0
- package/dist/src/utils/paths.js +23 -0
- package/dist/src/utils/paths.js.map +1 -0
- package/dist/src/utils/platform.js +14 -0
- package/dist/src/utils/platform.js.map +1 -0
- package/dist/src/utils/seed.js +61 -0
- package/dist/src/utils/seed.js.map +1 -0
- package/package.json +82 -0
- package/src/templates/OPENWOLF.md +147 -0
- package/src/templates/STATUS.md +48 -0
- package/src/templates/anatomy.md +5 -0
- package/src/templates/buglog.json +4 -0
- package/src/templates/cerebrum.md +22 -0
- package/src/templates/claude-md-snippet.md +5 -0
- package/src/templates/claude-rules-openwolf.md +17 -0
- package/src/templates/config.json +83 -0
- package/src/templates/cron-manifest.json +97 -0
- package/src/templates/cron-state.json +7 -0
- package/src/templates/identity.md +9 -0
- package/src/templates/memory.md +4 -0
- package/src/templates/reframe-frameworks.md +597 -0
- package/src/templates/token-ledger.json +21 -0
package/NOTICE
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
OpenWolf Enhanced
|
|
2
|
+
=================
|
|
3
|
+
|
|
4
|
+
This project is a fork of OpenWolf, a token-conscious context manager for
|
|
5
|
+
Claude Code projects.
|
|
6
|
+
|
|
7
|
+
Original work:
|
|
8
|
+
OpenWolf
|
|
9
|
+
Copyright (c) 2026 Cytostack Pvt Ltd
|
|
10
|
+
https://github.com/cytostack/openwolf
|
|
11
|
+
Licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
|
|
12
|
+
|
|
13
|
+
This fork:
|
|
14
|
+
OpenWolf Enhanced
|
|
15
|
+
Copyright (c) 2026 Krynex Labs
|
|
16
|
+
https://github.com/bassprofressor-lab/openwolf-enhanced
|
|
17
|
+
Also licensed under the GNU Affero General Public License v3.0 (AGPL-3.0),
|
|
18
|
+
as required by the license of the original work.
|
|
19
|
+
|
|
20
|
+
The full license text is in the LICENSE file. Per the AGPL, the copyright and
|
|
21
|
+
license of the original work are preserved, and this NOTICE documents the
|
|
22
|
+
modifications made in this fork.
|
|
23
|
+
|
|
24
|
+
Summary of modifications relative to the upstream 1.0.4 baseline
|
|
25
|
+
----------------------------------------------------------------
|
|
26
|
+
- Bounded storage growth: token-ledger.json (sessions and per-session I/O),
|
|
27
|
+
buglog.json, cron dead-letter queue, and waste_flags are all capped.
|
|
28
|
+
- Tamed auto bug-detection: removed the noisy "significant diff" catch-all,
|
|
29
|
+
widened the de-duplication window, and made buglog IDs collision-free.
|
|
30
|
+
- anatomy.md is no longer rewritten when a file's entry is unchanged, and the
|
|
31
|
+
edited file is read only once per write.
|
|
32
|
+
- Daemon no longer re-reads/broadcasts large files on every change; large
|
|
33
|
+
files are trimmed for dashboard delivery.
|
|
34
|
+
- New `openwolf doctor` command: daemon-independent .wolf/ health report and
|
|
35
|
+
compaction (ledger, memory consolidation, buglog de-dup, backup pruning,
|
|
36
|
+
log rotation, tmp cleanup).
|
|
37
|
+
- New `.wolfignore` support: gitignore-style scoping for anatomy scanning and
|
|
38
|
+
hook tracking.
|
|
39
|
+
- New `openwolf.retention` config block: all limits are user-tunable.
|
|
40
|
+
- `openwolf update` now deep-merges config.json instead of overwriting it, so
|
|
41
|
+
user settings survive updates.
|
|
42
|
+
- `openwolf status` now reports the .wolf/ footprint and size warnings.
|
|
43
|
+
- Stop hook opportunistically consolidates memory.md when it grows too large,
|
|
44
|
+
so maintenance works even when the daemon is not running.
|
|
45
|
+
- Legacy bare-array buglog.json files are read tolerantly and migrated to the
|
|
46
|
+
{ version, bugs } schema without data loss.
|
|
47
|
+
|
|
48
|
+
See CHANGELOG.md for details.
|
package/README.md
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="openwolf-icon.png" alt="OpenWolf Enhanced" width="120" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">OpenWolf Enhanced</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>A second brain for Claude Code — now with bounded storage and self-maintenance.</strong><br />
|
|
9
|
+
Project intelligence, token tracking, and invisible enforcement through 6 hook scripts. Zero workflow changes.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-AGPL--3.0-blue.svg" alt="License: AGPL-3.0" /></a>
|
|
14
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node.js-20%2B-green.svg" alt="Node.js" /></a>
|
|
15
|
+
<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>
|
|
16
|
+
<a href="https://www.krynexlabs.de/en/openwolf-enhanced"><img src="https://img.shields.io/badge/by-Krynex%20Labs-6D28D9.svg" alt="by Krynex Labs" /></a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
> **This is an enhanced fork of [OpenWolf](https://github.com/cytostack/openwolf)** by Cytostack Pvt Ltd.
|
|
22
|
+
> The original is a great idea; in long-lived projects its `.wolf/` directory could grow
|
|
23
|
+
> without bound (multi-megabyte token ledgers, an ever-growing bug log, full-file rewrites
|
|
24
|
+
> on every edit). This fork keeps everything the original does and makes storage **bounded,
|
|
25
|
+
> self-maintaining, and scopeable**. The CLI is still `openwolf`, so it's a drop-in replacement.
|
|
26
|
+
> See [what's enhanced](#whats-enhanced) and the [CHANGELOG](CHANGELOG.md).
|
|
27
|
+
|
|
28
|
+
## Why OpenWolf Exists
|
|
29
|
+
|
|
30
|
+
Claude Code is powerful but it works blind. It doesn't know what a file contains until it opens it. It can't tell a 50-token config from a 2,000-token module. It reads the same file multiple times in one session without noticing. It has no index of your project, no memory of your corrections, and no awareness of what it already tried.
|
|
31
|
+
|
|
32
|
+
OpenWolf gives Claude a second brain: a file index so it knows what files contain before reading them, a learning memory that accumulates your preferences and past mistakes, and a token ledger that tracks everything. All through 6 invisible hook scripts that fire on every Claude action.
|
|
33
|
+
|
|
34
|
+
## What's Enhanced
|
|
35
|
+
|
|
36
|
+
Everything from upstream still works. On top of that:
|
|
37
|
+
|
|
38
|
+
| Area | Enhancement |
|
|
39
|
+
|------|-------------|
|
|
40
|
+
| 🩺 **Self-maintenance** | New `openwolf doctor` — a daemon-independent command that reports the `.wolf/` footprint and compacts everything (ledger, memory, bug log, backups, logs, tmp), and flags cross-project registry issues (dead entries, dashboard-port collisions). `--dry-run` to preview. |
|
|
41
|
+
| 📊 **Dashboard upgrades** | A daemon-down banner (no more empty panels that look like an empty project), a Design QC thumbnail grid + lightbox (was filenames only), and theme-aware chart tooltips. |
|
|
42
|
+
| 📦 **Bounded storage** | `token-ledger.json`, `buglog.json`, cron dead-letter queue and waste flags are all capped. No more runaway multi-MB files. |
|
|
43
|
+
| 🎯 **`.wolfignore`** | gitignore-style scoping for anatomy scanning **and** hook tracking. Stop indexing `vendor/`, generated code, or `*.log`. |
|
|
44
|
+
| ⚙️ **Tunable retention** | New `openwolf.retention` config block — every limit is user-adjustable. |
|
|
45
|
+
| 🔁 **Non-destructive updates** | `openwolf update` now **deep-merges** `config.json` instead of overwriting it, so your settings survive. |
|
|
46
|
+
| 🧹 **Less churn** | `anatomy.md` isn't rewritten when nothing changed; the daemon no longer re-broadcasts large files on every write; auto bug-detection no longer flags ordinary refactors. |
|
|
47
|
+
| 📏 **Visibility** | `openwolf status` now shows the `.wolf/` footprint and size warnings. |
|
|
48
|
+
|
|
49
|
+
### Security & correctness hardening (1.2.0)
|
|
50
|
+
|
|
51
|
+
This fork also adopts security and bug fixes that were reported/proposed upstream but never
|
|
52
|
+
merged (the upstream repo has been inactive since March 2026):
|
|
53
|
+
|
|
54
|
+
- 🔒 **Dashboard is no longer network-exposed** — binds to `127.0.0.1` (was `0.0.0.0`) and
|
|
55
|
+
requires a per-project token on every API request and WebSocket connection, closing an
|
|
56
|
+
unauthenticated path to trigger cron tasks. *(upstream #30, #34)*
|
|
57
|
+
- 🔒 **No command injection** — shell command strings replaced with argument arrays
|
|
58
|
+
(`execFileSync`); the PM2 process name is sanitized. *(upstream #34)*
|
|
59
|
+
- 🔒 **No path traversal** — cron AI tasks can't read files outside the project root. *(upstream #34)*
|
|
60
|
+
- 🛡 **No secret leakage** — private keys, certs and keystores (`.pem`, `.key`, `.p8`,
|
|
61
|
+
`.keystore`, `id_rsa`, `credentials`…) are excluded from the brain, not just `.env`. *(upstream #54)*
|
|
62
|
+
- 🐛 **CRLF no longer wipes `anatomy.md`** — the entry parser tolerates `\r\n`, so Windows /
|
|
63
|
+
`git autocrlf` repos don't get their file map truncated. *(upstream #50)*
|
|
64
|
+
- 🐛 **`bug search` won't crash** on entries with missing fields or a `files[]` array. *(upstream #44)*
|
|
65
|
+
- 🐛 **Re-reads after edits aren't flagged** — a file that changed during the session can be
|
|
66
|
+
re-read without a "already read" warning. *(upstream #41)*
|
|
67
|
+
- 🐛 **No off-project tracking** — files outside the project root never enter anatomy/memory. *(upstream #56)*
|
|
68
|
+
- 🐛 **Saner auto bug-detection** — the noisy "any big diff is a bug" heuristic was removed. *(upstream #28)*
|
|
69
|
+
- 🐛 **`.gitignore` is respected** — anatomy scanning and hook tracking honor `.gitignore` (not just `.wolfignore`), so ignored/build files aren't indexed. *(upstream #15)*
|
|
70
|
+
- 🐛 **`init` won't scaffold `$HOME`** — `findProjectRoot` stops at the home directory, and multi-project port collisions are avoided. *(upstream #20)*
|
|
71
|
+
|
|
72
|
+
### Adopted upstream PRs (1.3.x)
|
|
73
|
+
|
|
74
|
+
Useful upstream pull requests that were never merged, adapted to this fork:
|
|
75
|
+
|
|
76
|
+
- 💬 **End-of-turn reminders actually reach Claude** — the stop hook's reminders (unlogged bug
|
|
77
|
+
fixes, stale `cerebrum.md`, missing session summary) were written to stderr, which the model
|
|
78
|
+
never sees; they now use the `additionalContext` stdout channel, and each fires **at most
|
|
79
|
+
once per session** instead of nagging every turn. *(upstream #55)*
|
|
80
|
+
- 🖥 **Works on WSL2 / EFS** — file copies use a read+write shim, fixing `EPERM` on WSL2 mounts
|
|
81
|
+
under EFS-encrypted directories. *(upstream #33)*
|
|
82
|
+
- 🏷 **Cleaner hook management** — `.claude/settings.json` entries are tagged `_managedBy:
|
|
83
|
+
"openwolf"`, so `init`/`update` can replace/remove only their own hooks. *(upstream #32)*
|
|
84
|
+
- 🎯 **Dart support** — `.dart` files are recognized for token estimation. *(upstream #10)*
|
|
85
|
+
|
|
86
|
+
### Reliability, dependencies & dashboard (1.6–1.9)
|
|
87
|
+
|
|
88
|
+
Ongoing hardening and modernization beyond the upstream backlog:
|
|
89
|
+
|
|
90
|
+
- 🔒 **Zero known vulnerabilities** — a self-audit fixed 11 transitive advisories; `pnpm audit --prod` is clean, kept current with a dependency pass (all dev **and** runtime majors upgraded: TypeScript 7, Vite 8, recharts 3, chokidar 5, commander 15, node-cron 4…). *(1.6.1, 1.8.0)*
|
|
91
|
+
- 🔐 **Safe concurrent sessions** — the token-ledger read-modify-write is wrapped in a best-effort file lock, so two sessions ending at once (or a session plus the cron report) can't clobber each other. It never blocks a hook for long. *(1.7.0)*
|
|
92
|
+
- 🧪 **Test suite** — `pnpm test` covers the core logic (retention/ledger caps, buglog migration, ignore matcher, secret detection, CRLF parsing). *(1.7.0)*
|
|
93
|
+
- 🔒 **`/api/switch` is allow-listed** — the daemon only switches to projects in the registry, not arbitrary directories. *(1.7.0)*
|
|
94
|
+
- 🐛 **File-watcher exclusions actually fire** — a latent bug (glob strings silently stopped matching under chokidar 4+) meant the daemon was re-reading and broadcasting `token-ledger.json`/`buglog.json` on every write; fixed with a predicate matcher. *(1.8.0)*
|
|
95
|
+
- 📊 **Dashboard quick wins** — daemon-down banner with retry, Design QC thumbnails + lightbox (new path-safe token-gated image route), theme-aware tooltips. *(1.9.0)*
|
|
96
|
+
- 💾 **Backups stay small** — `update` no longer snapshots the regenerable `token-ledger.json` into every backup, and `createBackup()` now enforces `retention.backups_keep` on the write path instead of only when `doctor` happened to run. One project went from 41 MB to 9 MB of `.wolf/` with no loss of restorable state. *(1.9.1)*
|
|
97
|
+
- 🌱 **`update` seeds files a project never received** — user-data files are never overwritten, but that was implemented as *never touched*, so a project initialised before a file existed never got one. `STATUS.md` was the casualty. Missing files are now created from the templates; existing ones are still left alone. *(1.9.2)*
|
|
98
|
+
- 🪝 **The hooks we test are the hooks we ship** — hook deployment and the test suite pointed at two different `tsc` outputs of the same sources, free to diverge. One artifact now, deployed from one shared `hooks-deploy` module. *(1.9.2)*
|
|
99
|
+
|
|
100
|
+
Full details in the [CHANGELOG](CHANGELOG.md) and [NOTICE](NOTICE).
|
|
101
|
+
|
|
102
|
+
## Quick Start
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npm install -g openwolf-enhanced
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
> **Note:** this is the maintained fork. `npm install -g openwolf` installs the
|
|
109
|
+
> original `openwolf` (last released 1.0.4, March 2026, unmaintained) — a different
|
|
110
|
+
> package. Install `openwolf-enhanced` for the bounded-storage, self-maintenance and
|
|
111
|
+
> security work described above. Both provide the same `openwolf` command.
|
|
112
|
+
|
|
113
|
+
<details>
|
|
114
|
+
<summary>Install from source instead</summary>
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
git clone https://github.com/bassprofressor-lab/openwolf-enhanced.git
|
|
118
|
+
cd openwolf-enhanced
|
|
119
|
+
pnpm install
|
|
120
|
+
pnpm build # builds CLI, hooks, and dashboard
|
|
121
|
+
npm install -g . # installs the `openwolf` command globally
|
|
122
|
+
```
|
|
123
|
+
</details>
|
|
124
|
+
|
|
125
|
+
Then, in any project:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
cd your-project
|
|
129
|
+
openwolf init
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
That's it. Use `claude` normally. OpenWolf is watching.
|
|
133
|
+
|
|
134
|
+
### Rebuilding an installed copy
|
|
135
|
+
|
|
136
|
+
Two things to know before you re-run `pnpm build` on a copy you have already installed globally:
|
|
137
|
+
|
|
138
|
+
- **`prebuild` deletes `dist/` before compiling**, and the global `openwolf` command is a symlink
|
|
139
|
+
into `dist/bin/openwolf.js`. If the build then fails, the CLI is gone until you build again. Back
|
|
140
|
+
`dist/` up first if you are mid-change, or build in a clean checkout.
|
|
141
|
+
- **A rebuild does not deploy anything.** The hooks that actually run are per-project copies under
|
|
142
|
+
`<project>/.wolf/hooks/`, invoked by `.claude/settings.json` — not the installed package. Run
|
|
143
|
+
`openwolf update` afterwards to push new hooks into your projects (it touches *every* registered
|
|
144
|
+
project; scope it with `--project <name>`).
|
|
145
|
+
|
|
146
|
+
> **Upgrading the tool?** The hooks that actually run are **per-project copies** in
|
|
147
|
+
> `<project>/.wolf/hooks/`, not the global package. After rebuilding/reinstalling, run
|
|
148
|
+
> `openwolf update` (or `openwolf update --project <name>`) to copy the new hooks into your
|
|
149
|
+
> projects — a global reinstall alone does not update them. `openwolf update` with no
|
|
150
|
+
> `--project` updates **all** registered projects.
|
|
151
|
+
|
|
152
|
+
## What It Creates
|
|
153
|
+
|
|
154
|
+
`openwolf init` creates a `.wolf/` directory in your project:
|
|
155
|
+
|
|
156
|
+
| File | Purpose |
|
|
157
|
+
|------|---------|
|
|
158
|
+
| `anatomy.md` | Project file map with descriptions and token estimates |
|
|
159
|
+
| `cerebrum.md` | Learned preferences, corrections, Do-Not-Repeat list |
|
|
160
|
+
| `memory.md` | Chronological action log with token estimates |
|
|
161
|
+
| `buglog.json` | Bug fix memory, searchable, prevents re-discovery |
|
|
162
|
+
| `token-ledger.json` | Lifetime token tracking and session history |
|
|
163
|
+
| `hooks/` | 6 Claude Code lifecycle hooks (pure Node.js) |
|
|
164
|
+
| `config.json` | Configuration with sensible defaults (incl. `retention`) |
|
|
165
|
+
| `identity.md` | Agent persona for this project |
|
|
166
|
+
| `OPENWOLF.md` | Instructions Claude follows every session |
|
|
167
|
+
|
|
168
|
+
## How It Works
|
|
169
|
+
|
|
170
|
+
Before Claude reads a file, OpenWolf tells it what the file contains and how large it is. If Claude already read that file this session, OpenWolf warns it. Before Claude writes code, OpenWolf checks your `cerebrum.md` for known mistakes. After every write, it auto-updates the project map and logs token usage. You see none of this. It just happens.
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
You type a message
|
|
174
|
+
↓
|
|
175
|
+
Claude decides to read a file
|
|
176
|
+
↓
|
|
177
|
+
OpenWolf: "anatomy.md says this file is ~380 tokens. Description: Main entry point."
|
|
178
|
+
↓
|
|
179
|
+
Claude reads the file → OpenWolf logs the read, checks for repeated reads
|
|
180
|
+
↓
|
|
181
|
+
Claude writes code → OpenWolf checks cerebrum.md for known mistakes
|
|
182
|
+
↓
|
|
183
|
+
Claude finishes → OpenWolf updates anatomy.md, appends to memory.md, updates the ledger
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Keeping `.wolf/` Healthy
|
|
187
|
+
|
|
188
|
+
The `.wolf/` directory is designed to stay small, but on very active projects you can compact it any time — no daemon required:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
openwolf doctor --dry-run # report footprint + warnings, change nothing
|
|
192
|
+
openwolf doctor # compact ledger, consolidate memory, dedup buglog,
|
|
193
|
+
# prune backups, rotate logs, clear tmp
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`openwolf status` shows the current footprint and warns before anything gets large.
|
|
197
|
+
|
|
198
|
+
### Tuning limits
|
|
199
|
+
|
|
200
|
+
Edit the `openwolf.retention` block in `.wolf/config.json` (defaults shown):
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"openwolf": {
|
|
205
|
+
"retention": {
|
|
206
|
+
"token_ledger_max_sessions": 200,
|
|
207
|
+
"session_io_max": 100,
|
|
208
|
+
"buglog_max_entries": 200,
|
|
209
|
+
"backups_keep": 10,
|
|
210
|
+
"memory_consolidate_after_days": 7,
|
|
211
|
+
"memory_max_bytes": 262144,
|
|
212
|
+
"daemon_log_max_bytes": 524288
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
These survive `openwolf update` (config is deep-merged, not overwritten).
|
|
219
|
+
|
|
220
|
+
### Scoping with `.wolfignore`
|
|
221
|
+
|
|
222
|
+
Create a `.wolfignore` at your project root to exclude paths from anatomy scanning and hook tracking (gitignore-style):
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
vendor/
|
|
226
|
+
dist/
|
|
227
|
+
**/*.generated.ts
|
|
228
|
+
*.log
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Commands
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
openwolf init Initialize .wolf/ and register hooks
|
|
235
|
+
openwolf status Show health, stats, .wolf/ footprint, size warnings
|
|
236
|
+
openwolf doctor Report + compact .wolf/ (daemon-independent) [--dry-run]
|
|
237
|
+
openwolf scan Refresh the project structure map
|
|
238
|
+
openwolf scan --check Verify anatomy matches filesystem (exits 1 if stale)
|
|
239
|
+
openwolf dashboard Open the real-time web dashboard
|
|
240
|
+
openwolf daemon start Start background task scheduler
|
|
241
|
+
openwolf daemon stop Stop the scheduler
|
|
242
|
+
openwolf daemon restart Restart the scheduler
|
|
243
|
+
openwolf daemon logs View scheduler logs
|
|
244
|
+
openwolf cron list Show all scheduled tasks
|
|
245
|
+
openwolf cron run <id> Trigger a task manually
|
|
246
|
+
openwolf cron retry <id> Retry a dead-lettered task
|
|
247
|
+
openwolf designqc Capture full-page screenshots for design evaluation
|
|
248
|
+
openwolf bug search <term> Search bug memory for known fixes
|
|
249
|
+
openwolf update Update registered projects (deep-merges config)
|
|
250
|
+
openwolf restore [backup] Restore .wolf/ from a timestamped backup
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Design QC
|
|
254
|
+
|
|
255
|
+
Capture full-page screenshots of your running app and let Claude evaluate the design.
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
openwolf designqc
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Auto-detects your dev server, captures viewport-height JPEG sections of every route, and saves them to `.wolf/designqc-captures/`. Then tell Claude to read the screenshots and evaluate. Requires `puppeteer-core`.
|
|
262
|
+
|
|
263
|
+
## Requirements
|
|
264
|
+
|
|
265
|
+
- Node.js 20+
|
|
266
|
+
- Claude Code CLI
|
|
267
|
+
- Windows, macOS, or Linux
|
|
268
|
+
- Optional: PM2 for persistent background tasks
|
|
269
|
+
- Optional: `puppeteer-core` for Design QC screenshots
|
|
270
|
+
|
|
271
|
+
## Limitations
|
|
272
|
+
|
|
273
|
+
- Claude Code hooks are a relatively new feature. OpenWolf falls back to `CLAUDE.md` instructions when hooks don't fire.
|
|
274
|
+
- Token tracking is estimation-based (character-to-token ratio), not exact API counts. Accurate to within ~15%.
|
|
275
|
+
- `cerebrum.md` depends on Claude following instructions to update it after corrections. Compliance is ~85–90%, not 100%.
|
|
276
|
+
|
|
277
|
+
## Credits
|
|
278
|
+
|
|
279
|
+
OpenWolf was created by [Cytostack Pvt Ltd](https://github.com/cytostack/openwolf) (Farhan Palathinkal Afsal). This enhanced fork is maintained by **[Krynex Labs](https://krynexlabs.de)** — AI engineering & automation. Huge thanks to the original authors for the design and the idea.
|
|
280
|
+
|
|
281
|
+
## License
|
|
282
|
+
|
|
283
|
+
**AGPL-3.0** — same as the original. See [LICENSE](LICENSE) and [NOTICE](NOTICE). As a derivative work under the AGPL, this fork preserves the original copyright and remains AGPL-3.0; if you run a modified version as a network service, you must make your source available to its users.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const major = parseInt(process.versions.node.split(".")[0], 10);
|
|
3
|
+
if (major < 20) {
|
|
4
|
+
console.error(`OpenWolf requires Node.js 20 or higher. You are running ${process.version}.`);
|
|
5
|
+
process.exit(1);
|
|
6
|
+
}
|
|
7
|
+
import { createProgram } from "../src/cli/index.js";
|
|
8
|
+
const program = createProgram();
|
|
9
|
+
program.parse(process.argv);
|
|
10
|
+
//# sourceMappingURL=openwolf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openwolf.js","sourceRoot":"","sources":["../../bin/openwolf.ts"],"names":[],"mappings":";AAEA,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAChE,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,2DAA2D,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC;IAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;AAChC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{a as e,c as t,r as n}from"./index-jfgWxxsn.js";import{i as r}from"./utils-BqE_aDxV.js";var i=t(e(),1),a=n(),o=[{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`}],s=`Analyze this project and write a JSON file to .wolf/suggestions.json with this exact structure:
|
|
2
|
+
{
|
|
3
|
+
"generated_at": "<ISO timestamp>",
|
|
4
|
+
"achievements": ["..."],
|
|
5
|
+
"improvements": ["..."],
|
|
6
|
+
"next_tasks": ["..."],
|
|
7
|
+
"risks": ["..."]
|
|
8
|
+
}
|
|
9
|
+
Base it on the recent memory, anatomy, and current project state. Be specific and actionable.`;function c({data:e}){let{suggestions:t}=e,[n,c]=(0,i.useState)(!1),l=()=>{navigator.clipboard.writeText(s).then(()=>{c(!0),setTimeout(()=>c(!1),2e3)})};return t?(0,a.jsxs)(`div`,{children:[(0,a.jsxs)(`div`,{className:`flex items-center justify-between mb-6`,children:[(0,a.jsxs)(`span`,{className:`text-sm`,style:{color:`var(--text-faint)`},children:[`Generated: `,t.generated_at?r(t.generated_at):`unknown`]}),(0,a.jsx)(`button`,{onClick:l,className:`px-3 py-1.5 text-xs rounded-lg transition-colors`,style:{background:`var(--bg-surface-hover)`,border:`1px solid var(--border-subtle)`,color:n?`var(--accent)`:`var(--text-secondary)`},children:n?`Copied!`:`Regenerate via Claude`})]}),(0,a.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:o.map(({key:e,title:n,icon:r,color:i})=>{let o=t[e]||[];return(0,a.jsxs)(`div`,{className:`rounded-xl p-5`,style:{background:`${i}08`,border:`1px solid ${i}33`},children:[(0,a.jsxs)(`div`,{className:`flex items-center gap-2 mb-3`,children:[(0,a.jsx)(`span`,{className:`text-lg`,children:r}),(0,a.jsx)(`h3`,{className:`font-medium`,style:{color:i},children:n})]}),o.length===0?(0,a.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`None reported.`}):(0,a.jsx)(`ul`,{className:`space-y-2`,children:o.map((e,t)=>(0,a.jsxs)(`li`,{className:`text-sm flex items-start gap-2`,style:{color:`var(--text-secondary)`},children:[(0,a.jsx)(`span`,{className:`mt-1 shrink-0`,style:{color:`var(--text-faint)`},children:`•`}),(0,a.jsx)(`span`,{children:e})]},t))})]},e)})})]}):(0,a.jsxs)(`div`,{className:`flex flex-col items-center justify-center py-12 text-center`,children:[(0,a.jsx)(`div`,{className:`text-4xl mb-3`,children:`✦`}),(0,a.jsx)(`h3`,{className:`font-medium mb-2`,style:{color:`var(--text-secondary)`},children:`No AI suggestions yet`}),(0,a.jsx)(`p`,{className:`text-sm max-w-sm mb-6`,style:{color:`var(--text-muted)`},children:`Suggestions are generated by Claude during your sessions. Paste this prompt into your next Claude Code conversation:`}),(0,a.jsxs)(`div`,{className:`w-full max-w-lg text-left rounded-xl overflow-hidden`,style:{border:`1px solid var(--border-subtle)`},children:[(0,a.jsxs)(`div`,{className:`flex items-center justify-between px-4 py-2`,style:{background:`var(--bg-surface-hover)`,borderBottom:`1px solid var(--border-subtle)`},children:[(0,a.jsx)(`span`,{className:`text-xs font-medium`,style:{color:`var(--text-muted)`},children:`Prompt for Claude`}),(0,a.jsx)(`button`,{onClick:l,className:`text-xs px-3 py-1 rounded-md transition-colors`,style:{background:n?`var(--accent-subtle)`:`var(--bg-surface)`,border:`1px solid var(--border-subtle)`,color:n?`var(--accent)`:`var(--text-secondary)`},children:n?`Copied!`:`Copy`})]}),(0,a.jsx)(`pre`,{className:`text-xs px-4 py-3 whitespace-pre-wrap`,style:{background:`var(--bg-code)`,color:`var(--text-secondary)`},children:s})]}),(0,a.jsx)(`p`,{className:`text-xs mt-4`,style:{color:`var(--text-faint)`},children:`Claude will write the results here automatically. They update live.`})]})}export{c as AISuggestions};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,c as t,r as n}from"./index-jfgWxxsn.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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,c as t,r as n}from"./index-jfgWxxsn.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}){let{anatomy:t}=e,[n,r]=(0,a.useState)(``),[i,s]=(0,a.useState)(!1),u=(0,a.useMemo)(()=>c(t.entries),[t.entries]),d=(0,a.useMemo)(()=>{let e=t.entries.map(e=>e.tokens);return{total:t.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}},[t.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:n,onChange:e=>r(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:()=>s(!i),className:`px-3 py-2 text-xs rounded-lg`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`,color:`var(--text-muted)`},children:i?`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:[d.total,` files tracked`]}),(0,o.jsxs)(`span`,{children:[`Avg: `,d.avg,` tok/file`]}),(0,o.jsxs)(`span`,{children:[`Largest: `,d.largest,` tok`]})]}),(0,o.jsx)(`div`,{className:`rounded-xl p-4`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:t.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:u,search:n})})]})}export{f as AnatomyBrowser};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,c as t,r as n}from"./index-jfgWxxsn.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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,c as t,r as n}from"./index-jfgWxxsn.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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,c as t,r as n,t as r}from"./index-jfgWxxsn.js";import{i,n as a}from"./utils-BqE_aDxV.js";import{t as o}from"./StatusBadge-4NJI_F2G.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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,c as t,n,r,t as i}from"./index-jfgWxxsn.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}from"./index-jfgWxxsn.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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,r as t}from"./index-jfgWxxsn.js";import{i as n,r}from"./utils-BqE_aDxV.js";import{t as i}from"./StatusBadge-4NJI_F2G.js";e();var a=t();function o({data:e}){let{identity:t,health:o,cronState:s,tokenLedger:c,anatomy:l,memory:u,project:d}=e,f=c.lifetime,p=d.name||t.name,m=d.description||``;return(0,a.jsxs)(`div`,{children:[(0,a.jsxs)(`div`,{className:`rounded-xl p-6 mb-6`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,a.jsx)(`h2`,{className:`text-3xl font-bold`,style:{color:`var(--text-primary)`},children:p}),m&&(0,a.jsx)(`p`,{className:`mt-1`,style:{color:`var(--text-muted)`},children:m}),(0,a.jsxs)(`div`,{className:`flex items-center gap-4 mt-3`,children:[(0,a.jsx)(i,{status:s.engine_status}),o.uptime_seconds>0&&(0,a.jsxs)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:[`Uptime: `,Math.floor(o.uptime_seconds/3600),`h `,Math.floor(o.uptime_seconds%3600/60),`m`]}),s.last_heartbeat&&(0,a.jsxs)(`span`,{className:`text-xs`,style:{color:`var(--text-faint)`},children:[`Last heartbeat: `,n(s.last_heartbeat)]})]})]}),(0,a.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-3 gap-4 mb-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)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`Files Tracked`}),(0,a.jsx)(`p`,{className:`text-2xl font-bold mt-1`,style:{color:`var(--text-primary)`},children:l.metadata.files})]}),(0,a.jsxs)(`div`,{className:`rounded-xl p-5`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,a.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`Sessions`}),(0,a.jsx)(`p`,{className:`text-2xl font-bold mt-1`,style:{color:`var(--text-primary)`},children:f.total_sessions})]}),(0,a.jsxs)(`div`,{className:`rounded-xl p-5`,style:{background:`var(--bg-surface)`,border:`1px solid var(--border)`},children:[(0,a.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`Tokens Saved`}),(0,a.jsxs)(`p`,{className:`text-2xl font-bold mt-1`,style:{color:`var(--accent)`},children:[`~`,r(f.estimated_savings_vs_bare_cli)]}),f.total_tokens_estimated>0&&(0,a.jsxs)(`p`,{className:`text-xs mt-1`,style:{color:`var(--text-faint)`},children:[Math.round(f.estimated_savings_vs_bare_cli/(f.total_tokens_estimated+f.estimated_savings_vs_bare_cli)*100),`% savings`]})]})]}),(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:`font-medium mb-3`,style:{color:`var(--text-secondary)`},children:`Recent Activity`}),u.length===0?(0,a.jsx)(`p`,{className:`text-sm`,style:{color:`var(--text-muted)`},children:`No activity yet. Start a Claude Code session to see activity here.`}):(0,a.jsx)(`div`,{className:`space-y-2`,children:u.slice(0,3).flatMap(e=>e.entries.slice(0,5).map((t,n)=>(0,a.jsxs)(`div`,{className:`flex items-center gap-3 py-2`,style:{borderBottom:`1px solid var(--border)`},children:[(0,a.jsx)(`span`,{className:`text-xs font-mono w-12`,style:{color:`var(--text-faint)`},children:t.time}),(0,a.jsx)(`span`,{className:`text-sm flex-1`,style:{color:`var(--text-secondary)`},children:t.action}),(0,a.jsx)(`span`,{className:`text-xs font-mono`,style:{color:`var(--text-faint)`},children:t.tokens})]},`${e.date}-${n}`))).slice(0,5)})]})]})}export{o as ProjectOverview};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,r as t}from"./index-jfgWxxsn.js";import{t as n}from"./utils-BqE_aDxV.js";e();var r=t(),i={healthy:`bg-emerald-500/20 text-emerald-400 border-emerald-500/30`,running:`bg-emerald-500/20 text-emerald-400 border-emerald-500/30`,success:`bg-emerald-500/20 text-emerald-400 border-emerald-500/30`,ok:`bg-emerald-500/20 text-emerald-400 border-emerald-500/30`,enabled:`bg-emerald-500/20 text-emerald-400 border-emerald-500/30`,warning:`bg-amber-500/20 text-amber-400 border-amber-500/30`,retrying:`bg-amber-500/20 text-amber-400 border-amber-500/30`,degraded:`bg-amber-500/20 text-amber-400 border-amber-500/30`,error:`bg-red-500/20 text-red-400 border-red-500/30`,failed:`bg-red-500/20 text-red-400 border-red-500/30`,stopped:`bg-red-500/20 text-red-400 border-red-500/30`,disabled:`bg-zinc-500/20 text-zinc-400 border-zinc-500/30`,unknown:`bg-zinc-500/20 text-zinc-400 border-zinc-500/30`,initialized:`bg-blue-500/20 text-blue-400 border-blue-500/30`};function a({status:e,className:t}){return(0,r.jsxs)(`span`,{className:n(`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium border`,i[e.toLowerCase()]||i.unknown,t),children:[e===`running`||e===`healthy`?(0,r.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-emerald-400 mr-1.5 pulse-green`}):null,e.charAt(0).toUpperCase()+e.slice(1)]})}export{a as t};
|