Commit Graph
192 Commits
Author SHA1 Message Date
Matthew Breedlove dfa009e7df Handle usage API 429 backoff
Closes #204
2026-03-08 01:11:47 -05:00
Matthew Breedlove db950f3f7a fix: install menu escape navigation 2026-03-06 17:49:58 -05:00
fe9cc15818 feat(timer): add compact time format option for timer widgets (#203)
* feat(timer): add compact time format option for timer widgets

Add an optional compact display mode (s key) to BlockTimer, BlockResetTimer,
and WeeklyResetTimer that renders durations as '5h30m' instead of '5hr 30m'.

- Add `compact` boolean parameter to `formatUsageDuration`
- Add `isUsageCompact` / `toggleUsageCompact` helpers in usage-display.ts
- Add `toggle-compact` action and `s` keybind across all three timer widgets
- Preview text reflects compact format when flag is set
- Editor modifier text shows 'compact' when flag is enabled
- Tests cover compact format output, keybind exposure, and toggle behavior

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix compact timer widget editor state

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-06 17:24:52 -05:00
34fa512778 feat(list): add custom list component (#60)
* feat(list): add custom list component

* feat(list): add sublabel and disabled options for list items

* Refactor TUI menu screens onto shared List component

Replace the remaining menu-style terminal and powerline screens with the shared List component so they share navigation, descriptions, back-row behavior, disabled states, and confirm dialog rendering.

This migrates TerminalOptionsMenu, TerminalWidthMenu, PowerlineSetup, PowerlineThemeSelector, and ConfirmDialog, and adds focused tests for the extracted menu builders and Ink-level regressions.

It also fixes two regressions uncovered during manual testing: PowerlineThemeSelector now memoizes theme data and List selection callbacks so live theme preview no longer triggers a maximum update depth loop, and TerminalWidthMenu now restores focus to the active full-until-compact row after returning from threshold entry instead of resetting to the first item.

---------

Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-06 02:19:29 -05:00
Matthew Breedlove e63591492a feat: add usage API HTTPS_PROXY support 2026-03-05 18:07:10 -05:00
Matthew Breedlove 7a0b979b01 test: isolate config test Claude config dir 2026-03-05 14:35:43 -05:00
Matthew Breedlove eaab442794 chore: standardize lint scripts and CI 2026-03-05 14:31:46 -05:00
78d6dcc28c feat: Add Skills widget with cross-platform hook framework (#201)
* feat: Add Skills widget with cross-platform hook framework

Replaces bash/jq hook with a built-in --hook CLI handler that works
on all platforms. Widgets can declare hooks via getHooks() which are
auto-synced to Claude settings when the statusline config is saved.

* feat: tighten hook lifecycle and upgrade skills widget

Notes:\n- Hook sync now follows saved-state semantics: installing statusline syncs hooks from saved ccstatusline settings on disk, and uninstall always removes all ccstatusline-managed hooks.\n- syncWidgetHooks always strips managed hooks first, including when statusline.command is missing, then persists cleanup.\n- Skills metrics storage path is now ~/.cache/ccstatusline/skills/skills-<sessionId>.jsonl.\n- Skills unique list ordering is now most-recent-first.\n- Skills widget updates: view toggle on (v), hide-when-empty toggle on (h), explicit empty outputs when not hidden, and new list-only (l)imit editor option where 0 means unlimited (default).\n- Added list-limit custom editor flow and list-only keybind visibility in ItemsEditor.\n- Maintained Node 14 compatibility by avoiding Array.prototype.at in skills metrics parsing.\n- Added/updated regression tests for hook sync/install/uninstall behavior, skills metrics path/order, Skills widget rendering/editing, and items-editor custom keybind handling.

* chore: bump version to 2.2.1 and update release notes

---------

Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-05 01:35:37 -05:00
Matthew Breedlove 53c8200c5a chore: sync available widgets list in README 2026-03-04 22:08:08 -05:00
7ca953400c feat: Add token speed widgets (InputSpeed, OutputSpeed, TotalSpeed) (#141)
* Add token speed widgets (InputSpeed, OutputSpeed, TotalSpeed)

- Add SpeedMetrics type for tracking token throughput
- Implement speed calculation utilities in speed-metrics.ts
- Add InputSpeed, OutputSpeed, TotalSpeed widgets
- Extend jsonl.ts to extract timing data for speed calculation
- Inject speedMetrics into RenderContext for widget access
- Add unit tests for speed widgets

* Add widget-gated subagent speed aggregation with parallel reads

* Fix subagent speed parsing for session-directory transcript layout

* Consolidate speed windows into core speed widgets

* Bump to v2.2.0 and document new speed widgets

---------

Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-04 20:03:36 -05:00
Matthew Breedlove 591cb60459 ci: drop invalid cache input from setup-bun v2
Remove unsupported 'cache' input from oven-sh/setup-bun@v2 steps to eliminate GitHub Actions warnings about unexpected inputs.
2026-03-04 18:15:10 -05:00
c4d0f4b5ad refactor: improve main manu option (#170)
* chore: resolve eslint error

Signed-off-by: ysknsid25 <kengo071225@gmail.com>

* refactor: improve menu value handing

Signed-off-by: ysknsid25 <kengo071225@gmail.com>

* refactor: keep minimal typed main-menu options

Co-authored-by: Kanon <kengo071225@gmail.com>

* refactor: minimize typed menu diff against main

Co-authored-by: Kanon <kengo071225@gmail.com>

---------

Signed-off-by: ysknsid25 <kengo071225@gmail.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-04 18:10:39 -05:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Matthew Breedlove
97d7491c12 chore(deps-dev): bump vitest from 3.2.4 to 4.0.18 (#198)
* chore(deps-dev): bump vitest from 3.2.4 to 4.0.18

Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 3.2.4 to 4.0.18.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.18/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-version: 4.0.18
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: type console spy in config test for vitest 4 lint

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-04 13:17:20 -05:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Matthew Breedlove
8049e28667 chore(deps-dev): bump the dev-dependencies group with 14 updates (#196)
* chore(deps-dev): bump the dev-dependencies group with 14 updates

Bumps the dev-dependencies group with 14 updates:

| Package | From | To |
| --- | --- | --- |
| [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) | `9.33.0` | `9.39.3` |
| [@stylistic/eslint-plugin](https://github.com/eslint-stylistic/eslint-stylistic/tree/HEAD/packages/eslint-plugin) | `5.2.3` | `5.9.0` |
| [chalk](https://github.com/chalk/chalk) | `5.5.0` | `5.6.2` |
| [eslint](https://github.com/eslint/eslint) | `9.33.0` | `9.39.3` |
| [eslint-plugin-import-newlines](https://github.com/SeinopSys/eslint-plugin-import-newlines) | `1.4.0` | `1.4.1` |
| [ink](https://github.com/vadimdemedes/ink) | `6.2.0` | `6.8.0` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `19.1.1` | `19.2.4` |
| [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) | `19.1.10` | `19.2.14` |
| [strip-ansi](https://github.com/chalk/strip-ansi) | `7.1.0` | `7.1.2` |
| [tinyglobby](https://github.com/SuperchupuDev/tinyglobby) | `0.2.14` | `0.2.15` |
| [typedoc](https://github.com/TypeStrong/TypeDoc) | `0.28.12` | `0.28.17` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.9.2` | `5.9.3` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.39.1` | `8.56.1` |
| [zod](https://github.com/colinhacks/zod) | `4.0.17` | `4.3.6` |


Updates `@eslint/js` from 9.33.0 to 9.39.3
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/commits/v9.39.3/packages/js)

Updates `@stylistic/eslint-plugin` from 5.2.3 to 5.9.0
- [Release notes](https://github.com/eslint-stylistic/eslint-stylistic/releases)
- [Changelog](https://github.com/eslint-stylistic/eslint-stylistic/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint-stylistic/eslint-stylistic/commits/v5.9.0/packages/eslint-plugin)

Updates `chalk` from 5.5.0 to 5.6.2
- [Release notes](https://github.com/chalk/chalk/releases)
- [Commits](https://github.com/chalk/chalk/compare/v5.5.0...v5.6.2)

Updates `eslint` from 9.33.0 to 9.39.3
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.33.0...v9.39.3)

Updates `eslint-plugin-import-newlines` from 1.4.0 to 1.4.1
- [Release notes](https://github.com/SeinopSys/eslint-plugin-import-newlines/releases)
- [Commits](https://github.com/SeinopSys/eslint-plugin-import-newlines/compare/v1.4.0...v1.4.1)

Updates `ink` from 6.2.0 to 6.8.0
- [Release notes](https://github.com/vadimdemedes/ink/releases)
- [Commits](https://github.com/vadimdemedes/ink/compare/v6.2.0...v6.8.0)

Updates `react` from 19.1.1 to 19.2.4
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.4/packages/react)

Updates `@types/react` from 19.1.10 to 19.2.14
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `strip-ansi` from 7.1.0 to 7.1.2
- [Release notes](https://github.com/chalk/strip-ansi/releases)
- [Commits](https://github.com/chalk/strip-ansi/compare/v7.1.0...v7.1.2)

Updates `tinyglobby` from 0.2.14 to 0.2.15
- [Release notes](https://github.com/SuperchupuDev/tinyglobby/releases)
- [Changelog](https://github.com/SuperchupuDev/tinyglobby/blob/main/CHANGELOG.md)
- [Commits](https://github.com/SuperchupuDev/tinyglobby/compare/0.2.14...0.2.15)

Updates `typedoc` from 0.28.12 to 0.28.17
- [Release notes](https://github.com/TypeStrong/TypeDoc/releases)
- [Changelog](https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TypeStrong/TypeDoc/compare/v0.28.12...v0.28.17)

Updates `typescript` from 5.9.2 to 5.9.3
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.9.2...v5.9.3)

Updates `typescript-eslint` from 8.39.1 to 8.56.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.56.1/packages/typescript-eslint)

Updates `zod` from 4.0.17 to 4.3.6
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v4.0.17...v4.3.6)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-version: 9.39.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: "@stylistic/eslint-plugin"
  dependency-version: 5.9.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: chalk
  dependency-version: 5.6.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: eslint
  dependency-version: 9.39.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: eslint-plugin-import-newlines
  dependency-version: 1.4.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: ink
  dependency-version: 6.8.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: react
  dependency-version: 19.2.4
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: "@types/react"
  dependency-version: 19.2.14
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: strip-ansi
  dependency-version: 7.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: tinyglobby
  dependency-version: 0.2.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: typedoc
  dependency-version: 0.28.17
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: typescript
  dependency-version: 5.9.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: typescript-eslint
  dependency-version: 8.56.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: zod
  dependency-version: 4.3.6
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: pin ink 6.2.0 and fix lint formatting

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-04 13:10:40 -05:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
a056183a67 chore(deps-dev): bump eslint-plugin-react-hooks from 5.2.0 to 7.0.1 (#199)
Bumps [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/HEAD/packages/eslint-plugin-react-hooks) from 5.2.0 to 7.0.1.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/HEAD/packages/eslint-plugin-react-hooks)

---
updated-dependencies:
- dependency-name: eslint-plugin-react-hooks
  dependency-version: 7.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-04 12:45:32 -05:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
fceab59ec6 chore(deps-dev): bump react-devtools-core from 6.1.5 to 7.0.1 (#197)
Bumps [react-devtools-core](https://github.com/facebook/react/tree/HEAD/packages/react-devtools-core) from 6.1.5 to 7.0.1.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/HEAD/packages/react-devtools-core)

---
updated-dependencies:
- dependency-name: react-devtools-core
  dependency-version: 7.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-04 12:44:28 -05:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
19eb83fb24 chore(deps): bump actions/checkout from 4 to 6 (#195)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-04 12:37:23 -05:00
f2764362fd chore: Add Dependabot for npm and GitHub Actions (#152)
* Add Dependabot configuration for npm and GitHub Actions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: use bun ecosystem and add Dependabot cooldowns

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-04 12:34:25 -05:00
990f2703b1 fix: support bare repo worktrees in GitWorktree widget (#138)
* fix: support bare repo worktrees in GitWorktree widget

The GitWorktree widget now correctly detects worktrees from bare
repositories. Previously, it only checked for `.git/worktrees/` in
the path, but bare repos store worktree metadata at
`<bare-repo>/worktrees/<name>` without the `.git` prefix.

This adds an additional check for `/worktrees/` pattern when the
`.git/worktrees/` pattern isn't found.

Fixes detection for setups like:
- Bare repo at: /path/to/repo (contains objects/, refs/, HEAD, etc.)
- Worktree at: /path/to/repo/trees/feature-x
- Git dir: /path/to/repo/worktrees/feature-x

* chore: remove accidental npm lockfile from PR branch

* chore: bump version to 2.1.10 and update recent updates

---------

Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-04 11:47:59 -05:00
Matthew Breedlove 59d43589c9 test: stabilize CI by isolating cross-file mocks
Convert module-level mocks to scoped spies and restore global stubs between tests to prevent Bun/Vitest cross-file leakage and flaky Actions failures.
2026-03-04 11:26:34 -05:00
78c7bc16f0 chore: Add CI (#151)
* Add GitHub CI workflow for lint, test, and build

Runs on push to main and PRs. Uses Bun with dependency caching.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Remove branch filter on push trigger to run CI on all branches

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Use bun test in CI test job

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-04 10:46:01 -05:00
2956842911 Attempt to add backups (#123)
* Attempt to add backups

* fix: quiet invalid claude settings parse output in TUI

---------

Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-04 10:31:30 -05:00
Matthew Breedlove 5c0d211ddf test: isolate config-path behavior across suite 2026-03-04 09:59:30 -05:00
Matthew Breedlove 9c0f5feab6 chore: bump version to 2.1.9 and update release notes 2026-03-04 09:33:47 -05:00
Matthew Breedlove 7925ec3e9a fix: support Unicode code points >4 hex digits for separators (resolves #133) 2026-03-04 09:31:53 -05:00
Matthew Breedlove 87fac953aa fix: correct ANSI reset order in applyColors (resolves #79) 2026-03-04 09:29:33 -05:00
d79eefb043 feat: Add --config flag for custom settings file path (#166)
* Add --config flag for custom settings file path

Allow users to specify an alternative settings file via `--config <path>`,
enabling distinct status line configs for different Claude Code instances.

- Add initConfigPath/getConfigPath/isCustomConfigPath to config.ts
- Fix backup path to always append .bak instead of replacing .json suffix
- Use path.dirname(SETTINGS_PATH) instead of CONFIG_DIR for mkdir
- Parse --config arg in ccstatusline.ts main() entry point
- Add tests for config path management

* Integrate --config flag with Claude Code install commands

When a custom config path is active, the install-to-Claude-Code feature
now appends --config <path> to the status line command. Also updates
isInstalled detection to recognize commands with the --config suffix.

- Add isKnownCommand() to deduplicate command-matching logic
- Add shell-safe path quoting for --config values with spaces/special chars
- Add buildCommand() to append --config when custom path is active
- Refactor isInstalled() to use isKnownCommand()
- Use isKnownCommand() in App.tsx install flow
- Add tests for isKnownCommand() and buildCommand() with CLAUDE_CONFIG_DIR safety net

* Show custom config path in TUI header

When a custom --config path is active, display it below the title bar
so users can see which settings file is being edited.

* fix: use platform-appropriate quoting for --config path

* chore: bump version to 2.1.8 and update recent updates

---------

Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-04 09:10:37 -05:00
Matthew Breedlove 79b8e4e2f5 refactor: implement phase 7 test/tooling simplification with tests 2026-03-04 01:39:48 -05:00
Matthew Breedlove fc09688879 refactor: implement phase 6 jsonl/usage modularization with async prefetch tests 2026-03-04 01:28:27 -05:00
Matthew Breedlove a34a632b82 refactor: implement phase 5 utility cleanup with tests 2026-03-04 00:43:05 -05:00
Matthew Breedlove 25b69228dd feat(usage): split reset timers into block and weekly widgets
Closes #194
2026-03-04 00:14:49 -05:00
Matthew Breedlove 7e2ad30f77 fix(context): support 1M model name formats in fallback parsing
Handle [1M], (1M), and optional context labels when inferring model context size; use model id + display_name in context widgets and add regression coverage for ctx, ctx(u), and context bar.

Closes #193
2026-03-03 21:49:49 -05:00
Matthew Breedlove b90840f68c refactor: implement phase 4 tui component simplification with tests 2026-03-03 20:14:30 -05:00
Matthew Breedlove b13ea14a8c fix: coerce status JSON numeric strings and bump version
Coerce numeric strings in StatusJSON parsing to keep status line rendering resilient with third-party payload tweaks.

Closes #192
2026-03-03 18:30:04 -05:00
Matthew Breedlove da7eaffe03 refactor: implement phase 3 widget pattern extraction with tests 2026-03-03 18:24:39 -05:00
Matthew Breedlove 9aea4c1265 refactor: implement phase 2 tui/settings simplification with tests 2026-03-03 12:53:21 -05:00
Matthew Breedlove 2d05b3b891 refactor: implement phase 1 terminal/render dedup with tests 2026-03-03 12:43:44 -05:00
Matthew Breedlove 6edc1b4277 feat: add git insertions and deletions widgets
Closes #115
2026-03-03 00:22:13 -05:00
Matthew Breedlove 0c6bf4b02c feat: add Link widget and fix ANSI/OSC truncation calculation
- add a new Link widget with OSC8 rendering, preview parity, and raw mode behavior
- fix truncation and visible-width calculation to handle ANSI/OSC sequences safely
- bump package version to 2.1.3
- update README recent updates and widget documentation

Resolves #188
2026-03-02 23:59:14 -05:00
Matthew Breedlove eff030a9d8 Add 'star us on github' menu item, version bump to 2.1.2 2026-03-02 23:21:39 -05:00
Matthew Breedlove 9ddcb0003b Version bump and readme update 2026-03-02 20:32:10 -05:00
4459379038 fix: Avoid creating an empty c:\dev\null file on windows during terminal width detection. (#132)
On Windows, the Unix-specific commands (ps, stty, tput) and shell
redirects (2>/dev/null) don't work and cause issues:
- tput doesn't exist on Windows
- 2>/dev/null creates a literal file named "null" instead of
  redirecting stderr

This fix adds a platform check at the start of getTerminalWidth()
and canDetectTerminalWidth().  We cannot rely on process.stdout.columns when run as a subprocess of claude code to tell us the actual terminal width.  By simply returning that terminal width detection is unavailable on windows, we avoid the empty file being created, and disable explicit truncation behavior since we can't detect the width.


Fixes #117

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: preserve legacy terminal width behavior on Windows

Return null/false for win32 in terminal width helpers to keep width detection disabled on Windows and avoid Unix-style fallback paths that can create C:\dev\null.

---------

Co-authored-by: ItsDaRa <ItsDaRa@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-02 20:28:11 -05:00
Matthew Breedlove 8b1ec580d9 Version bump and README update 2026-03-02 17:43:32 -05:00
a03b7c2238 feat: add API usage widgets (session, weekly, reset, context bar) (#168)
* feat: add API usage widgets (session, weekly, reset timer, context bar)

Add four new widgets that display Claude Code API usage data:
- session-usage: 5-hour session utilization with progress bar
- weekly-usage: 7-day utilization with progress bar
- reset-timer: countdown to session reset
- context-bar: context window usage with progress bar

Fetches data from /api/oauth/usage using existing OAuth credentials
(macOS Keychain + Linux file fallback). Includes 180s cache with
30s rate limiting to minimize API calls.

Also enhances ContextPercentage widget to use context_window data
from Claude Code's stdin JSON when available.

Closes #94

* fix(api-usage): zod-validate usage data and move cache to ~/.cache/ccstatusline

- parse credentials/cache/API response via zod with nullable field support\n- move usage cache+lock to ~/.cache/ccstatusline/usage.{json,lock}\n- add missing getCategory() methods on API usage widgets\n- resolve context percentage brace-style lint issue

* Refactor usage widgets and unify timer/usage display modes

Split API usage widgets into dedicated files and a shared usage utility, replacing the monolithic ApiUsage widget module.

Key changes:

- add src/utils/usage.ts for API fetch/caching, parsing, error mapping, progress-bar helpers, and shared 5-hour window math

- move widgets to standalone files: SessionUsage, WeeklyUsage, ResetTimer, ContextBar

- remove src/widgets/ApiUsage.tsx and update widget exports/registry wiring

- make BlockTimer usage-aware with usage API first and JSONL fallback via shared resolver

- make ResetTimer follow BlockTimer UX: time/progress/short-progress modes, raw value support, invert toggle, and JSONL fallback when usage timing is unavailable

- make SessionUsage and WeeklyUsage match timer interaction model: progress mode cycling, invert toggle, invert-clearing when returning to text mode, and raw-value support

- update ItemsEditor to hide/disable invert keybind when widget is in text mode

- remove eager block-metric parsing from ccstatusline render path so JSONL fallback is only invoked when usage timing is missing

- add comprehensive tests for usage window fallback behavior and widget mode/toggle/raw output behavior

Validation:

- bun test

- bun run lint

* Prefer status JSON context-window metrics with robust fallbacks

- add a shared context-window metrics utility to normalize context_window fields (window size, percentages, usage, and token snapshots)

- make context window size from status JSON authoritative for context calculations when present; derive usable limit as 80% of reported size

- keep model-id fallback behavior for missing context_window data, including case-insensitive [1m]/[1M] detection

- update Context %, Context % (usable), Context Length, and Context Bar to use status JSON first and fall back to JSONL token metrics when needed

- update Session Clock to use cost.total_duration_ms first with JSONL duration fallback

- keep Tokens Input/Output JSON-first, while reverting Tokens Cached/Total to cumulative session JSONL totals

- simplify render pipeline behavior to always parse current session JSONL token metrics when transcript_path exists

- add/expand tests for context-window parsing, denominator precedence, 1M-without-suffix scenarios, case-insensitive suffix fallback, token widget source behavior, context bar rendering, and session clock behavior

* Align Context Bar with Context Length semantics

- switch Context Bar usage basis from total current_usage (input+output+cache) to context-length usage (input+cache), matching Context Length widget

- keep statusline JSON-first behavior with JSONL/model fallbacks unchanged

- keep short-by-default progress mode and long/short toggle behavior

- update ContextBar tests for new token basis and progress-mode expectations

* usage: honor CLAUDE_CONFIG_DIR and use runtime-safe HTTPS API fetch

* Fix context bar overflow and preserve usage error states

* Group usage widgets under new Usage picker category

* Rename context remaining toggle to used/remaining shortcut

---------

Co-authored-by: Peter van Velzen <pvvelzen@emico.nl>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-03-02 17:31:12 -05:00
Matthew Breedlove 801c5f1b38 chore: Update README.md 2026-02-27 13:19:08 -05:00
Matthew Breedlove fc3934097b chore: Fix for test failures when testing with vitest, remove 'test' script from package.json, prefer running tests using 'bun test' 2026-02-27 13:19:08 -05:00
Matthew Breedlove a8122844ff Add Buy Me a Coffee funding and README support section 2026-02-24 14:50:47 -05:00
3d43476d6b Free Memory Widget (#155)
* FreeMemory widget:

  Description: Shows system memory usage (used/total) in a compact format like Mem: 12.4G/16.0G

  Features:
  - On macOS: Uses vm_stat to calculate memory like htop (Active + Wired pages)
  - On other platforms: Falls back to Node.js os.freemem()/os.totalmem()
  - Smart byte formatting (G, M, K, B)
  - Supports raw value mode (omits "Mem:" prefix)
  - Default color: cyan

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Version bump and README update

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-02-24 14:20:00 -05:00
Matthew Breedlove b6426bf707 Version bump 2026-02-21 16:12:52 -05:00
ecd8d0b6cc perf: cache block timer metrics to reduce I/O (#161)
* perf: cache block timer metrics to reduce I/O

Cache block start time to ~/.cache/ccstatusline/block-cache.json to avoid
parsing all JSONL files on every status line render. Cache is invalidated
when the 5-hour block expires.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: use hashed per-config block cache files

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
2026-02-21 16:06:27 -05:00