Commit graph

12 commits

Author SHA1 Message Date
iamtoruk
dc97ab4936 chore(workspace): move CLI to packages/cli, add @codeburn/core skeleton (phase 1) 2026-07-26 10:19:33 -07:00
ozymandiashh
44df547748
test(electron): make dev-resolution tests self-sufficient on fresh clones (#689)
* test(electron): isolate dev-resolution fixtures via CODEBURN_DEV_REPO_ROOT

Rework of the #681 fix per review: instead of stubbing the real repo
dist/cli.js with snapshot-restore, the Vite-dev resolution branch gains a
CODEBURN_DEV_REPO_ROOT override (matching the CODEBURN_PATH_DIRS precedent)
so the whole fixture lives in a per-test tmpdir. With the env unset the
resolution order is byte-identical to before.

- covers all three fresh-clone failures on current main, including the
  resolveTarget dev-repo-beats-bundled case
- deletes the snapshot-restore machinery, the parent-path precondition and
  the beforeAll repo-scanning guard
- tests assert both override-set (tmpdir wins) and override-unset behavior

Closes #681

* test(electron): drop environment-coupled null assertion for unset dev-root override

The override-unset case resolved <repo>/dist/cli.js whenever a build had
run, so the toBeNull() assertion depended on the absence of a gitignored
artifact. The override-set tests already prove the new branch and the
non-Vite test covers the null path.
2026-07-20 05:23:28 -07:00
iamtoruk
f26bf69f88 perf(app): cap CLI spawn concurrency, background-priority prefetch, default to today 2026-07-18 16:28:30 -07:00
iamtoruk
707d621d7a fix(app): resolve bundled CLI on Windows + enrich cli_error telemetry
path.startsWith('/') POSIX guard rejected the Windows bundled-CLI path
(C:\...\launch.js), so 100% of Windows installs got not-found
(confirmed in telemetry: 84 events, all win32/x64). Use path.isAbsolute
everywhere. cli_error now carries {cmd, kind, detail?} for
self-diagnosing errors, never paths/args/stderr.
2026-07-17 13:51:35 -07:00
iamtoruk
4a100d9d06 feat(app): bundle the CLI inside the packaged app
The packaged app resolved whatever codeburn was on PATH — for real
users the published npm release, which predates every JSON surface the
app calls. The app now ships its own CLI copy under resources/cli
(staged production node_modules tree; tsup output is not
self-contained) and spawns it with Electron's own binary via
ELECTRON_RUN_AS_NODE. No install prerequisite remains.

- resolution order: CODEBURN_BIN, dev repo CLI, bundled, persisted
  path, PATH search
- launch.js shim strips the extra argv element commander mis-slices
  under packaged Electron-as-node (process.versions.electron is set),
  which reproduced the 'too many arguments' class of error
- afterPack hook copies the staged tree (extraResources runs
  node_modules through the production-dep filter and ships it empty);
  lands before signing, signature verified intact
- packaging always restages from src via root build:cli (tsup only,
  no network); ~12MB compressed per artifact

Verified on the built app: Electron-as-node CLI emits current JSON
(providerDetails, currency), and a minimal-PATH GUI launch spawns the
bundled CLI with zero external dependencies. 290/290.
2026-07-16 09:27:46 -07:00
iamtoruk
700a52cd95 fix(app): packaged app finds node when spawning the CLI
GUI-launched apps inherit a minimal PATH without the user's node
install, so spawning the codeburn npm shim (#!/usr/bin/env node) failed
with 'env: node: No such file or directory' in packaged builds. Spawn
now augments PATH with the resolved binary's own directory (node sits
beside the shim in nvm, Homebrew, and npm-prefix layouts) plus the
resolver's search dirs. Dev never hit this because the terminal PATH
was inherited.
2026-07-16 08:39:30 -07:00
iamtoruk
916aa6430f harden(app): Electron security + spawn efficiency batch
- will-navigate/window-open denied; openExternal restricted to http(s);
  production CSP drops 'unsafe-inline' scripts (dev-only Vite plugin
  re-adds it for the Fast Refresh preamble)
- single-instance lock; before-quit reaps in-flight CLI children; 16MB
  output cap rejects with CliError 'too-large'
- read-only CLI spawns coalesce: concurrent identical calls share one
  child, a 5s result cache absorbs same-cadence pollers (six sections
  polled getOverview independently); actions bypass and flush the cache
  on completion so post-action refetches are fresh
- every renderer-supplied argv string validated (period/provider/range/
  currency allowlists, no flag-shaped tokens, absolute export path) with
  new CliError kind 'bad-args'; envelope + action stderr routed through
  sanitizeError
- quota force-refresh: manual refresh (refreshToken) passes force which
  invalidates QuotaService's cache; steady polls do not
- POSIX credential mode check gated off on win32

App suite 190/190, build green (production index.html verified strict).
2026-07-16 01:57:44 -07:00
iamtoruk
55e9fa51f6 feat(app): functional Settings — rail nav + General/Providers/Aliases/Privacy
Settings was a dead shell (rail didn't switch, all buttons disabled).
Now the rail navigates and four tabs are wired to the real CLI:
- action bridge: spawnCliAction + runAction (text output, not JSON) with
  getAliases/getProxyPaths reads and setCurrency/resetCurrency/addAlias/
  removeAlias actions
- General: theme switcher (System/Light/Dark, persisted) + live currency
  (reads status, changes via `currency`) + default-period preference
- Providers: real detected-tools list with spend
- Model aliases: full add/remove against real config
- Privacy: honest local-only info

Devices content preserved as-is; Plans/Export are placeholders for Part 2.
2026-07-11 17:24:04 -07:00
iamtoruk
ea56ed33f0 fix(app): dev CLI beats a persisted/global codeburn path
The dev-mode repo dist/cli.js fallback ran AFTER the persisted-path file,
so a stale globally-installed codeburn (e.g. a Homebrew build lacking the
new sessions/compare commands) shadowed the repo build and every Sessions
call errored. Move the Vite-dev fallback ahead of the persisted-path
lookup; CODEBURN_BIN still overrides, and production (no VITE_DEV_SERVER_URL)
is unchanged.
2026-07-11 16:48:36 -07:00
iamtoruk
6023067bdc feat(app): bridge for sessions/compare + dev-mode CLI fallback
Adds getSessions / getCompareModels / getCompare IPC channels (argv for
the new CLI JSON emitters), mirrors SessionRow + compare-stats types into
the renderer, and — in Vite dev — resolves the repo's own dist/cli.js so
newly-added commands work without setting CODEBURN_BIN.
2026-07-11 12:37:04 -07:00
iamtoruk
b36253d2e2 fix(app): resolve usePolled stale-response race + review nits
Review of T0 (Electron scaffold) approved with one Important finding + cheap
Minors. All fixes scoped to app/.

- usePolled: replace per-call cancel closure with a generation/epoch counter so
  an orphaned in-flight fetch (from refresh() or an interval tick, discarded
  cancel handle) can't resolve after a newer fetch and clobber fresh data. New
  TDD race test (slow deps-A resolves after fast deps-B; keeps B).
- cli: nvm resolution now scans version dirs descending and takes the first
  whose bin actually contains codeburn (was lexicographic max, unverified),
  matching CodeburnCLI.swift. Export nodeManagerDirs + hermetic nvm test.
- index.html: tighten CSP connect-src ws: -> ws://localhost:5173.
- preload: import type { Envelope } from main instead of redeclaring it.
- main.test: table-driven channel->argv assertion over all 9 codeburn:* channels
  plus a keys check and a non-spawning cliStatus case.
2026-07-10 15:40:11 -07:00
iamtoruk
5736c95324 feat(app): scaffold Electron+Vite package and codeburn CLI spawn
New standalone `app/` package (own package.json, like dash/) for the
CodeBurn Desktop Electron app. Adds the Vite 6 + React 19 + Vitest
toolchain, the verbatim wireframe CSS port (renderer/styles/indigo.css),
and the main-process `codeburn` CLI resolver + spawner:

- resolveCodeburnPath(): CODEBURN_BIN override → persisted-path file →
  PATH/brew/nvm/volta/asdf → null (mirrors mac/CodeburnCLI.swift).
- spawnCli(args, {timeoutMs}): plain argv (no shell), collect stdout,
  JSON.parse, structured CliError{kind: not-found|nonzero|bad-json|timeout}.
- cli.test.ts covers success / nonzero / bad-json / timeout / not-found.
2026-07-10 15:16:55 -07:00