Commit graph

191 commits

Author SHA1 Message Date
AgentSeal
6358100d3d fix(extensions): period switching and currency conversion on GNOME
Period bug:
_refresh() returned early when a previous fetch was still in flight, so
clicking a new period tab while the initial load was running silently
dropped the second click. Swap the loading-guard for a generation counter:
every refresh increments a counter, and only the callback whose generation
matches the latest value applies the result. Older responses are dropped,
newer ones win.

Currency bug:
codeburn status --format menubar-json is a raw USD payload; the CLI does
not convert it. The popup was only changing the symbol prefix, not the
values. Fetch the USD->target rate from Frankfurter via Soup and apply it
in formatCost(). Rate is cached per-session so tab switches don't hit the
network; on currency change we kick off a fresh fetch (or reuse the cached
rate) and re-render with the new multiplier.

Other small fixes:
* Show a single-provider tab row (when exactly one provider is installed)
  instead of hiding it, so the user still sees which agent the numbers
  are for.
* Activity bar chart track is now a BoxLayout so the fill width takes
  effect; previously every bar rendered as 100% because the St.Widget
  track stretched its only child.
* Findings CTA no longer runs labels together ("findingssave"). Adds
  8px spacing between count and savings.
2026-04-18 05:21:09 -07:00
AgentSeal
ce94786185 feat(extensions): detect Pi and OpenCode in GNOME agent tab filter
Mirror the Mac ProviderFilter expansion by letting the GNOME popup
surface Pi and OpenCode tabs when their session stores are present.
Extends the provider detection paths with:

  opencode: $XDG_DATA_HOME/opencode (defaults to ~/.local/share/opencode)
  pi:       ~/.pi/agent/sessions

When two or more providers are detected the agent tab row renders with
All plus the detected providers; otherwise the row stays hidden so the
popup doesn't show a filter UI with nothing to filter against.
2026-04-18 05:10:29 -07:00
AgentSeal
6e354c17ed feat(extensions): hide agent tabs for providers with no data
The All / Claude / Codex / Cursor / Copilot tab row was fixed regardless of
which providers the user actually had installed, which made most of the
tabs render as $0 for people who only run one tool. Scan the expected
session directories on startup and only build tabs for providers that are
present. If two or more are detected, show "All" plus those providers;
if fewer than two are detected, skip the row entirely since there is
nothing to filter.

Paths checked:
  $HOME/.claude/projects         (Claude Code)
  $HOME/.codex/sessions          (Codex CLI)
  $HOME/.config/Cursor/User/globalStorage/state.vscdb (Cursor IDE)
  $HOME/.copilot/session-state   (GitHub Copilot)
2026-04-18 04:59:45 -07:00
AgentSeal
d47658c91d feat(extensions): rebuild GNOME popup with native widgets for Mac parity
Replace the PopupMenu text-item list with a custom St.Widget tree that
mirrors the macOS popover pixel for pixel. Same layout the native Quick
Settings panel uses: horizontal tab rows, branded header, hero
typography, inline bar-chart activity rows, and a pill-styled footer.

Structure:
  * Branded header with Code + Burn typography and subhead
  * Agent tab row (All / Claude / Codex / Cursor / Copilot) with active
    pill state and hover feedback
  * Hero block with period dot, label, large cost figure, calls and
    sessions meta
  * Period tab row (Today / 7 Days / 30 Days / Month / All) with same
    active-pill treatment
  * Activity section: bar chart per row scaled to the top cost,
    one-shot rate in brand green, cache and session numbers inline
  * Findings CTA as a full-width branded button, hidden when
    findingCount is zero
  * Footer with currency pill (cycles through 17 ISO codes), Refresh,
    Open Full Report, and an Updated timestamp

Dark and light theme classes drive the track and button palettes so the
popup stays legible regardless of GNOME system theme. Brand orange
(#ff8c42 to #c9521d) is the only hardcoded palette; everything else
inherits from the shell.
2026-04-18 04:52:33 -07:00
AgentSeal
e78a56b348 fix(extensions): stop truncating section titles in GNOME popup
The Activity and Models section headers were being clipped to "Activi..."
and "Mod..." because St.Label ellipsized the combination of
text-transform: uppercase plus letter-spacing in the available popup width.
Drop the uppercase transform and the letter-spacing so the labels render
in full and read consistently across themes.
2026-04-18 04:44:22 -07:00
AgentSeal
5e68981723 feat(extensions): add agent filter and currency switcher to GNOME popup
Adds two more submenus so the GNOME popup matches the agent tabs and
currency picker the Mac menubar app ships with.

* Agent submenu: All / Claude / Codex / Cursor / Copilot. Passes --provider
  through to codeburn status and codeburn report so the numbers and the
  full terminal report both follow the selected filter.
* Currency submenu: 17 ISO codes (USD, EUR, GBP, CAD, AUD, JPY, INR, BRL,
  CHF, SEK, SGD, HKD, KRW, MXN, ZAR, DKK, CNY). Selecting a code shells
  out to codeburn currency <code> and refreshes the popup with the new
  symbol. The current currency is read from ~/.config/codeburn/config.json
  on startup and after each change so all of our surfaces agree.
* formatCost takes the active currency so activity, model, provider and
  findings rows render with the right symbol instead of hardcoded $.
2026-04-18 04:35:29 -07:00
AgentSeal
4c5ec0f985 feat(extensions): polish GNOME extension and follow system theme
Expand the popup to show everything the TUI does: period switcher submenu,
top activities with one-shot rate, top models, provider breakdown when more
than one provider has data, optimize findings, and an updated-timestamp row.
Add per-period Open Full Report so the terminal view matches what the popup
was showing.

For theme compatibility, stop hardcoding colors that don't work on both
light and dark GNOME themes. Keep the brand orange (#ff8c42) for the header
and findings, let everything else inherit the shell palette, and express
dimming through opacity instead of rgba so the popup reads correctly on
Yaru Light, Yaru Dark, Adwaita, Adwaita Dark, and any other theme.

Add a listener on org.gnome.desktop.interface color-scheme so the indicator
re-applies its .codeburn-dark / .codeburn-light class when the user flips
the system theme, without waiting for a reload.
2026-04-18 04:20:14 -07:00
AgentSeal
291c376f06 feat(extensions): add GNOME Shell extension for native panel feel
Ship a GJS extension in extensions/gnome-shell/codeburn@agentseal.org so
GNOME users get the same panel-anchored popover Ubuntu's Quick Settings
uses, rather than the floating window the Tauri tray is limited to through
StatusNotifierItem.

The extension lives inside gnome-shell as a PanelMenu.Button, so it has
direct access to its own icon coordinates and can open a PopupMenu docked
under it without any IPC or DBus plumbing. The tradeoff is it only works
on GNOME 45+; the Tauri app in desktop/ stays the cross-platform option
for KDE, Unity, wlroots, and Windows users.

Data flow: the extension shells out to codeburn status --format menubar-json
every 60 seconds, parses the payload, and renders a header, top 5 activities,
and optimize findings count. Refresh and Open Full Report actions live in
the popup menu; the Open Full Report action spawns gnome-terminal with the
codeburn report TUI.
2026-04-18 04:06:44 -07:00
AgentSeal
5281a08e06 fix(desktop): fall back to top-right when tray click has no usable coords
The GNOME AppIndicator extension delivers Activate with (0, 0) instead of
real screen coordinates, which made the popover land in the top-left corner
because the centering math treated the bogus origin as a legitimate anchor.
Treat (0, 0) as no-anchor and reuse the top-right fallback the non-Linux
path already uses, so the popover lands near the StatusNotifier area on
hosts that don't pass coordinates.

Also cfg-gate the Emitter import since it is only used in the non-Linux
tray menu path.
2026-04-18 04:03:02 -07:00
AgentSeal
ea5e311d4a feat(desktop): replace Linux tray with ksni for Mac-style click UX
Tauri's Linux tray uses libappindicator, which by design never fires
left-click events to the app and exposes no icon screen position. That
forced a menu-first UX on GNOME and made anchoring the popover near the
icon impossible (tauri-apps/tauri#7283, closed not-planned).

Drop libappindicator on Linux and talk StatusNotifierItem directly via
the ksni crate:

* new src-tauri/src/tray_linux.rs implements ksni::Tray. activate(x, y)
  and secondary_activate(x, y) arrive with real screen coordinates. The
  implementation exports no menu on purpose, so SNI hosts (notably the
  gnome-shell-extension-appindicator) call Activate on left click instead
  of opening a context menu.
* LinuxTrayHandle wraps the async ksni::Handle with a sync Mutex so the
  Tauri command handler can push title updates without naming the
  generic Handle<CodeburnTray> across module boundaries.
* lib.rs gates TrayIconBuilder behind cfg(not(target_os = "linux")) and
  spawns ksni on the Tokio runtime Tauri already owns. Tray click events
  go through codeburn://tray-activate with {x, y} so the positioning logic
  can anchor the popover directly below the click, clamped to the monitor.
* new set_tray_title command pushes the hero cost to the tray label on
  every payload fetch. On Linux that's the SNI title next to the icon;
  on other platforms it's the TrayIcon::set_title.
* new quit_app command + popover-footer × button gives Linux users a way
  to exit without a tray menu.
* empty-state copy already landed in a previous commit. Combined with the
  footer Quit button, the popover is now self-contained on Linux.

Windows is unaffected: TrayIconBuilder there fires left-click events
correctly and set_title/tooltip work out of the box.

Known limitation: on vanilla GNOME without AppIndicator support, there is
no tray to click. Documentation will link to the AppIndicator extension
install, same caveat Slack, Discord and 1Password ship with.
2026-04-18 03:59:13 -07:00
AgentSeal
86bdbfcd1c fix(desktop): anchor popover to top-right using configured width
window.outer_size() returns (0, 0) on the first show, so the previous
positioning snapped to top-left when the window had not been rendered yet.
Derive the target x from the popover width declared in tauri.conf.json and
scale margins by the monitor's scale factor so HiDPI displays land in the
right spot.
2026-04-18 03:44:32 -07:00
AgentSeal
d29f2b6101 feat(desktop): anchor popover to top-right on show
Linux window managers ignore tray icon screen coordinates, so we cannot
attach the popover to the icon the way macOS does. Snap it to the top-right
of the primary monitor on every show so it feels anchored to the tray area
on GNOME, KDE and Unity, which all host StatusNotifier icons at the top
right.
2026-04-18 03:39:33 -07:00
AgentSeal
1eef50a64d feat(desktop): add Show Dashboard tray item and empty-state copy
Linux tray implementations often do not deliver a distinct left-click event
through the AppIndicator path, so the popover could not be opened on GNOME.
Add an explicit Show Dashboard menu item that calls toggle_popover so the
UI is reachable via the tray menu on every platform.

Also render a friendly empty state in the popover when no session data is
found, pointing at the supported source paths instead of showing a bare
$0 hero with an empty activity list.
2026-04-18 03:35:37 -07:00
AgentSeal
d8ff4dcca7 fix(desktop): pass extras slice to Command::args without deref
cmd.args(*extras) on &[&str] fails to compile on stable Rust because
[&str] is unsized. Drop the deref so the slice passes through.
2026-04-18 03:30:49 -07:00
Resham Joshi
9d4da7c0fd feat(desktop): Linux provisioner script + optional unattended autoinstall
desktop/Scripts/provision-linux.sh: one-shot apt + Node 20 + Rust stable
+ codeburn CLI + repo clone + npm install. Leaves the user one command
away from `npm run tauri dev`.

desktop/Scripts/autoinstall/: cloud-init user-data + meta-data plus a
README for building the CIDATA ISO. Mount that ISO alongside the Ubuntu
Server ISO in UTM and the installer runs without any prompts. Default
test credentials codeburn/codeburn; README calls out changing them for
non-throwaway VMs.
2026-04-17 18:11:03 -07:00
Resham Joshi
8590087392 feat(desktop): scaffold Tauri 2.x tray app for Linux + Windows
Adds desktop/ with a native tray app that mirrors the macOS popover via
a shared tokens.json and the same codeburn status --format menubar-json
data source. Same security posture as the Swift app: argv-validated CLI
spawn, O_NOFOLLOW cache writes, flock on config.json, FX rate clamping
to [0.0001, 1_000_000].

Stack:
- Tauri 2.x (Rust) for tray + window lifecycle, shells out to the CLI
- React + TypeScript + Vite for the popover UI
- libayatana-appindicator on Linux, system tray on Windows
- Produces .deb / .rpm / .AppImage on ubuntu-latest, .msi on
  windows-latest. Both workflows run on free GitHub Actions minutes.

Rust modules (src-tauri/src/):
- lib.rs:    tray icon, menu events, popover toggle, state wiring
- cli.rs:    CodeburnCli with argv allowlist and bounded pipe drain
             (20 MB stdout / 256 KB stderr / 60 s wall time)
- config.rs: flock-guarded read-modify-write of ~/.config/codeburn/config.json
- fx.rs:     Frankfurter fetch with 24 h disk cache, bounds check

Frontend:
- App.tsx with agent tabs, period switcher, hero cost, activity rows,
  optimize findings CTA, footer (currency picker / refresh / Open
  Full Report). Listens for `codeburn://refresh` tray events.
- lib/payload.ts mirrors the CLI's MenubarPayload shape
- lib/currency.ts mirrors the Swift Double.asCurrency helpers
- styles.css with design tokens as CSS custom properties

CLI:
- `codeburn menubar` now platform-dispatches: macOS (.app zip),
  Linux (.AppImage into ~/.local/bin), Windows (.msi via msiexec).
  macOS behaviour preserved exactly.

Release workflow:
- .github/workflows/release-desktop-linux.yml triggers on `linux-v*`
  tags, builds all three Linux formats, uploads to GitHub Releases.

Scaffold verified:
- cargo check -> clean
- tsc --noEmit -> clean
- npm run build (CLI) -> 205 KB
- Existing test suite: 230 / 230 still pass
2026-04-17 17:53:10 -07:00
AgentSeal
2b15256189 docs: actually update README to the renamed screenshot path
The prior rename commit moved the PNG but forgot to stage the matching
README edit, leaving the live image tag pointing at a path that no
longer existed. This fixes it.
2026-04-17 17:43:09 -07:00
AgentSeal
1037d2c527 docs: rename README screenshot so CDN+Camo re-fetch
The ?v=0.7.2 query bust wasn't enough; GitHub's Camo proxy was still
serving the SwiftBar-era image to viewers. Renaming the asset to a
new path forces every downstream cache to treat it as a new resource.
2026-04-17 17:41:28 -07:00
AgentSeal
feda92124d docs: bust CDN cache on menubar screenshot
Appends ?v=0.7.2 to the image URL so GitHub's Camo proxy re-fetches
the new 0.7.2 screenshot instead of serving its stale copy of the
SwiftBar-era one.
2026-04-17 17:29:16 -07:00
AgentSeal
d6381d1eeb
Merge pull request #73 from AgentSeal/feat/mac-menubar-app
Native macOS menubar app (replaces SwiftBar)
2026-04-18 02:14:10 +02:00
Resham Joshi
0b96ff182e docs: scrub private strategy notes from public text
Removes references to future signing decisions, dollar amounts, and
star thresholds from the menubar README, the CHANGELOG, the release
workflow (its YAML comments and the auto-generated release body), and
the packaging script. The technical description stays; the 'we are
not paying for X right now' framing is out.
2026-04-17 17:12:48 -07:00
AgentSeal
818a249c87 chore: release 0.7.2 native macOS menubar app
See CHANGELOG.md for the full breakdown. Highlights:

- Native Swift + SwiftUI menubar app under mac/ replaces the SwiftBar
  plugin. Install via `npx codeburn menubar`.
- `status --format menubar-json` payload builder.
- `export -f csv` now writes a folder of clean per-table CSVs; `-o`
  path guard prevents arbitrary deletion.
- `status` terminal Today/Month bucketed by local date instead of UTC.
- FX rate values clamped to sane bounds in both runtimes.
- SwiftBar plugin, install-menubar / uninstall-menubar, and
  `--format menubar` removed.
2026-04-17 17:08:24 -07:00
Resham Joshi
03f12ce81f fix(status): bucket Today/Month by local date, not UTC
renderStatusBar computed `today` via `new Date().toISOString().slice(0,10)`,
which is the UTC date. Session timestamps are also UTC ISO strings, but
the user's expectation of "today" is their wall-clock day. During the
window between local midnight and UTC midnight (e.g. 17:00 PDT on
2026-04-17, which is already 00:00 UTC on 2026-04-18), every session
bucketed under local April 17 missed the UTC-April-18 filter and the
status bar read `Today $0.00  0 calls` even while `--format json`
and the menubar app correctly showed the spend.

Both sides of the comparison now use the local date of each session
timestamp, so the terminal status and the JSON / menubar paths agree.
Verified at UTC midnight (the regression moment that surfaced the bug):

  Before: Today $0.0000  0 calls
  After:  Today $339.87  1839 calls

Caught during the fresh-clone review of the menubar PR.
2026-04-17 17:05:08 -07:00
Resham Joshi
3482478a49 fix(mac): drop empty Resources/ reference from Package.swift
Caught in a fresh-clone smoke test: SwiftPM refused to build because
.process("../../Resources") pointed at an empty directory that git
does not track. The bundle has no assets to ship yet (icon will land
with signing work), so the reference is gone. Build passes on a clean
checkout and the packaging script produces the universal .app zip as
expected.
2026-04-17 17:01:00 -07:00
Resham Joshi
495a254338 feat(mac): native Swift menubar app + one-command install
Introduces mac/ with a native SwiftUI menubar app that replaces the
previous SwiftBar plugin entirely. Install via `npx codeburn menubar`,
which downloads the .app from GitHub Releases, strips Gatekeeper
quarantine, and drops it into ~/Applications.

Highlights

- mac/ SwiftUI app: agent tabs, Today/7/30/Month/All period switcher,
  Trend/Forecast/Pulse/Stats/Plan insights, activity + model
  breakdowns, optimize findings, CSV/JSON export, Star-on-GitHub
  banner, live 60s refresh, instant currency switching with offline FX
  cache.
- Security: CodeburnCLI argv-based spawn (no shell interpretation),
  SafeFile symlink guards + O_NOFOLLOW writes, FX rate clamping to
  [0.0001, 1_000_000], keychain filtered to account == "default",
  removed byte-window credential log, in-flight refresh guard, POSIX
  flock on config.json writes, TerminalLauncher validates argv before
  AppleScript interpolation.
- Performance: shared static NumberFormatter (thousands of allocations
  per popover redraw eliminated), concurrent pipe drain with 20 MB cap
  + 60s timeout in DataClient, Observation-tracked reactive UI, 5-min
  payload cache keyed on (period, provider).
- CLI: new `codeburn menubar` subcommand that downloads + installs +
  launches the .app (no clone, no build). New `status --format
  menubar-json` payload builder. `export` rewritten to produce a
  folder of one-table-per-file CSVs with a `.codeburn-export` marker
  so arbitrary -o paths cannot be silently deleted.
- Removed: src/menubar.ts (SwiftBar plugin generator),
  install-menubar / uninstall-menubar subcommands, `status --format
  menubar` directive output, tests/menubar.test.ts,
  tests/security/menubar-injection.test.ts.
- Release: .github/workflows/release-menubar.yml builds universal
  binary, assembles .app, ad-hoc signs, zips, uploads on mac-v* tag
  push. Runs on the free macos-latest runner.

Tests

- 230 TypeScript tests pass
- 10 Swift CapacityEstimator tests pass
- TypeScript typecheck clean
- Swift release build clean
2026-04-17 16:55:56 -07:00
AgentSeal
69268a9e91 docs: remove .claudeignore references from README 2026-04-17 05:24:16 -07:00
AgentSeal
41c84b1e51
Merge pull request #66 from jeisaacs/fix/menubar-node-version-path
fix: prepend install-time node bin dir to menubar plugin PATH
2026-04-17 14:21:58 +02:00
AgentSeal
77257bcb89
Merge pull request #68 from lfl1337/fix/remove-claudeignore-references
docs(optimize): remove references to .claudeignore (#61)
2026-04-17 14:20:50 +02:00
AgentSeal
09cea9bc79 chore: release 0.7.1 security hardening 2026-04-17 05:08:37 -07:00
AgentSeal
774d1917d4
Merge pull request #67 from lfl1337/fix/security-hardening-2026-04
fix: security hardening from external audit
2026-04-17 14:06:32 +02:00
Ninym
d5ecedb188 chore(git): ignore local .claude/ directory
Prevents agent-scratchpad files under .claude/ from being accidentally
staged by tooling. Matches the existing pattern for docs/superpowers/.
2026-04-17 08:36:24 +02:00
Ninym
8f5927153e feat(cli): add --verbose flag for stderr warnings
Sets CODEBURN_VERBOSE=1 via commander preAction, which the fs-utils
helpers check before emitting stderr lines on skipped or failed reads.
Closes LOW-1 from the 2026-04-16 audit.
2026-04-17 08:32:20 +02:00
Ninym
646635c262 fix(menubar): sanitize SwiftBar labels via allowlist
Replaces any character outside [A-Za-z0-9 ._/-] with ? in model and
category labels and truncates to 14 chars before padEnd. Closes the
MEDIUM-2 finding from the 2026-04-16 audit: an attacker-controlled
JSONL with a crafted model name no longer injects SwiftBar directives
or ANSI escapes.
2026-04-17 08:32:20 +02:00
Ninym
71461fb352 test(security): add failing test for MEDIUM-2 menubar injection
Three cases (pipe-in-model, ANSI-in-model, pipe-in-category) reproduce
the audit's SwiftBar directive-separator attack. Tests fail against
current menubar.ts -- Task 13 will close with an allowlist sanitizer.
2026-04-17 08:32:20 +02:00
Ninym
216782391a fix(optimize): use bounded read helpers
All four read paths in the optimizer (async session scan + three sync
config/import/profile scans) now pass through the 128 MB-capped
helpers. JSON.parse in readJsonFile stays wrapped in try/catch.
MEDIUM-1 coverage for the optimize module.
2026-04-17 08:32:20 +02:00
Ninym
1bdbac4927 fix(context-budget): use bounded readSessionFile helper
Config JSON, CLAUDE.md scans, and session-discovery reads now pass
through the 128 MB-capped helper. JSON.parse remains wrapped in
try/catch to preserve the previous 'null on malformed JSON' contract.
MEDIUM-1 coverage for the context-budget module.
2026-04-17 08:32:19 +02:00
Ninym
716e080cb3 fix(pi): use bounded readSessionFile helper
Both Pi session read paths (first-entry meta and full-session parse)
now pass through the 128 MB-capped helper. MEDIUM-1 coverage for the
Pi provider.
2026-04-17 08:32:19 +02:00
Ninym
9f6827d528 fix(copilot): use bounded readSessionFile helper
Events JSONL and workspace.yaml reads now pass through the 128 MB-capped
helper. The workspace.yaml path stays non-fatal: a null read skips cwd
derivation but still pushes the session with sessionId as the fallback
project label. MEDIUM-1 coverage for the Copilot provider.
2026-04-17 08:32:19 +02:00
Ninym
1de0baf329 fix(codex): use bounded readSessionFile helper
Both Codex session read paths (first-line meta and full-session parse)
now pass through the 128 MB-capped helper. MEDIUM-1 coverage for the
Codex provider.
2026-04-17 08:32:19 +02:00
Ninym
ee738a1b26 fix(parser): use bounded readSessionFile helper
Replaces the unbounded readFile in parseSessionFile with the 128 MB-capped
helper from src/fs-utils. Addresses MEDIUM-1 for the Claude provider
hot path.

Verbose-mode stderr output replaces the previous silent catch,
closing LOW-1 as a side effect.
2026-04-17 08:32:19 +02:00
Ninym
82c3125638 feat(fs-utils): bounded session-file read helper
Adds readSessionFile / readSessionFileSync / readSessionLines with a
128 MB hard cap and 8 MB streaming threshold. Verbose mode
(CODEBURN_VERBOSE=1) logs skipped and failed reads to stderr.

Prepares the MEDIUM-1 migration of all provider read paths.
2026-04-17 08:32:19 +02:00
Ninym
0ab66f6fe9 test(fs-utils): add failing test for bounded read helper
Tests the to-be-built readSessionFile helper: under-cap fast path,
at-threshold stream path, over-cap null+skip, verbose stderr warning,
and stat-failure graceful fallback. Fails against missing module --
Task 5 will implement src/fs-utils.ts to flip GREEN.
2026-04-17 08:32:18 +02:00
Ninym
5b810161e7 fix(parser): block prototype pollution via Object.create(null)
Initialize the four breakdown maps (model, tool, mcp, bash) with null
prototype so attacker-controlled keys named __proto__ create own
properties on the map instead of mutating Object.prototype.

Closes the HIGH-1 finding from the 2026-04-16 external security audit.
2026-04-17 08:32:18 +02:00
Ninym
e890d9bfc3 test(security): add failing test for HIGH-1 prototype pollution
Three PoC fixtures (tool name, bash command, model name) reproduce
the audit's HIGH-1 attack. Tests assert Object.prototype.calls stays
undefined after parsing. They fail against current parser.ts -- Task 3
will close the pollution sink with Object.create(null).
2026-04-17 08:32:18 +02:00
Ninym
bd71377fdd docs(optimize): remove references to non-existent .claudeignore
Claude Code does not document or implement a .claudeignore feature.
The junk-reads detector's fix is now a CLAUDE.md instruction asking
Claude to avoid generated/dependency directories. The separate
detectMissingClaudeignore finding and its tests are removed; checking
for the presence of a non-existent file has no signal.

Closes #61.
2026-04-17 08:32:07 +02:00
Jonathan
276b14adea fix: prepend install-time node bin dir to menubar plugin PATH
SwiftBar/xbar launch plugins with a minimal environment. If an older
system Node (e.g. v18.x from Homebrew) appears earlier on PATH than the
NVM-managed Node used to install codeburn, the plugin silently fails
because string-width uses the /v regex flag (requires Node >= 20.11).

Resolve the node binary directory at install time via process.execPath
and prepend it to PATH in the generated plugin script. Also explicitly
set HOME, which SwiftBar does not always inherit.

Fixes #63
2026-04-17 07:29:14 +01:00
AgentSeal
f2d1753d3a
Merge pull request #60 from AgentSeal/feat/optimize
feat: codeburn optimize -- find waste and get copy-paste fixes
2026-04-17 01:31:52 +02:00
AgentSeal
005bdaaf07 chore: release 0.7.0 -- codeburn optimize
New top-level command plus in-TUI view for finding token waste and
getting copy-paste fixes. 11 detectors, A-F setup health grade,
recent-vs-baseline trend tracking, per-project context budget column.
198 tests.
2026-04-16 16:31:19 -07:00
AgentSeal
40b7de6841 docs: add optimize section with screenshot and command reference
Sits between 'Reading the dashboard' (what the numbers mean) and
'How it reads data' (where the data comes from) so the feature lands
as the natural next step: here is how to act on the patterns you saw.
2026-04-16 16:27:33 -07:00
AgentSeal
f958756861 chore(optimize): name preview-count literals and drop punctuation dashes
Rename slice(0, N) and length - N literals used in waste-finding
preview strings to GHOST_NAMES_PREVIEW, GHOST_CLEANUP_COMMANDS_LIMIT,
TOP_ITEMS_PREVIEW, MISSING_IGNORE_PATHS_PREVIEW, JUNK_DIRS_IGNORE_PREVIEW.
Drop the punctuation double-hyphen from the config-health header.
2026-04-16 16:20:53 -07:00