Skip to content

Consolidate all YAS files under ~/.claude/yas/ - #120

Merged
tmck-code merged 4 commits into
mainfrom
spec/consolidate-claude-dir-layout
Aug 20, 2026
Merged

Consolidate all YAS files under ~/.claude/yas/#120
tmck-code merged 4 commits into
mainfrom
spec/consolidate-claude-dir-layout

Conversation

@tmck-code

@tmck-code tmck-code commented Aug 16, 2026

Copy link
Copy Markdown
Owner

Context

Implements the consolidate-claude-dir-layout OpenSpec change (openspec/changes/consolidate-claude-dir-layout/). YAS scattered seven files and one directory across the top level of ~/.claude/ (statusline-*.log, statusline-output/, yas-last-prompt.json, terminal-width, …) with no cache/state distinction, no uninstall cleanup, and path constants copy-pasted across four places. This consolidates everything YAS owns — except the user's yas.toml — into a single ~/.claude/yas/ subtree, with an automatic migration so existing users keep their state. Bumps the version to 0.8.0.

Changes

Layout: before

classDiagram
    direction LR
    class ClaudeDir["~/.claude/"] {
        +yas.toml
        +yas.toml.cache
        +statusline-theme
        +statusline-tokens.log
        +statusline-token-rate.log
        +statusline-render.log
        +yas-last-prompt.json
        +terminal-width
    }
    class StatuslineOutput["statusline-output/"] {
        +statusline.~sid~.json
    }
    ClaudeDir *-- StatuslineOutput
Loading

Layout: after

classDiagram
    direction LR
    class ClaudeDir["~/.claude/"] {
        +yas.toml
    }
    class Yas["yas/"]
    class Cache["cache/"] {
        +config.toml.cache
    }
    class State["state/"] {
        +version.json
    }
    class Runtime["runtime/"] {
        +tokens.log
        +token-rate.log
        +render.log
    }
    class Signals["signals/"] {
        +last-prompt.json
        +terminal-width
    }
    class Sessions["sessions/"] {
        +~sid~.json
    }
    ClaudeDir *-- Yas
    Yas *-- Cache
    Yas *-- State
    State *-- Runtime
    State *-- Signals
    State *-- Sessions
Loading

Per-file dispositions: tokens.log, last-prompt.json, and terminal-width are moved (contents preserved); the rolling logs, yas.toml.cache, and statusline-output/ are deleted (regenerable); statusline-theme is folded into yas.toml by the installer, then deleted.

Automatic migration (runtime + installer)

  • New claude/yas/migrate.py: lazy, idempotent, lock-free migration guarded by a single version.json stat per render; durable files are moved via no-clobber atomic renames; marker written last, atomically. Marked # REMOVE AFTER 0.11.0.
  • ops/install.sh runs the same migration eagerly, folds a legacy statusline-theme value into yas.toml (validated before replacing), and uninstall now sweeps the whole yas/ subtree plus legacy files, preserving yas.toml.
  • The deprecated statusline-theme read path is removed from config.py.

Centralized path API

  • All paths are call-time functions in constants.py; no module outside it imports CLAUDE_DIR (grep-audited). session.py's duplicate constant is gone; test/conftest.py patches one place instead of eight modules.
  • ops/alacritty.py now honours CLAUDE_CONFIG_DIR (previously hardcoded $HOME, a latent bug) and writes the new signals path.

Tests

  • +13 tests: migration behaviour, the render-path guard, a layout-containment test asserting nothing writes outside yas/ + yas.toml, and prompt-hook path coverage; 34 existing tests adapted to the new paths. Suite: 1523 passed.
  • Demo visual gate: zero diff — rendered output is byte-identical.

Checklist

  • Tests added or updated for new/changed behaviour
  • (bug fixes) a regression test now covers the situation so it can't come back
  • N/A — no behaviour change, because:

Screenshots / recording

Before After
  • N/A — no visible change

Benchmark

Command Mean [ms] Min [ms] Max [ms] Relative
main 44.8 ± 1.3 42.9 49.0 1.00
PR 47.0 ± 5.3 43.1 71.4 1.05 ± 0.12

System info

Key Value
OS Linux archlinux 7.1.8-arch1-3 #1 SMP PREEMPT_DYNAMIC Tue, 11 Aug 2026 09:16:08 +0000 x86_64 GNU/Linux
Claude Code 2.1.233 (Claude Code)
Terminal TERM=tmux-256color TERM_PROGRAM=tmux SHELL=/bin/bash COLORTERM=truecolor
Locale LANG=en_AU.UTF-8 LC_ALL=
Python Python 3.13.13
uv uv 0.12.3 (507230998 2026-08-07 x86_64-unknown-linux-gnu)

🤖 Generated with Claude Code

Test and others added 3 commits August 16, 2026 23:25
Implements the consolidate-claude-dir-layout OpenSpec change: every
YAS-owned file except yas.toml now lives under $CLAUDE_DIR/yas/, split
into cache/ (regenerable), state/runtime/ (internal), state/signals/
(inbound), and state/sessions/ (mon handoff), with a version.json
schema stamp. Paths are centralized as call-time functions in
constants.py; a lazy idempotent runtime migration plus an eager
installer migration move users automatically, the deprecated
statusline-theme file is retired (folded into yas.toml by the
installer), and uninstall now sweeps the whole subtree while
preserving yas.toml.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- fold_legacy_theme: insert theme into an existing [appearance] table
  instead of appending a duplicate header (a TOML parse error), and
  fall back to tomli when tomllib is missing (Python 3.10)
- migrate(): only delete statusline-theme once yas.toml actually
  contains a theme= line, so a failed fold can't lose the value; move
  mkstemp inside the OSError guard so migrate() never raises
- config: derive the TOML cache path from the passed config_dir so
  sandboxed callers (tests) no longer write to the real ~/.claude
- demo: seed logs at the new yas/state/runtime paths and pre-stamp
  version.json so the lazy migration can't eat the seeded rate log
- sync skills/uninstall/SKILL.md with the extended do_uninstall sweep

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@tmck-code
tmck-code marked this pull request as ready for review August 20, 2026 11:24
Users running ops/install.sh want visibility into what migrate() is
doing to their config dir. Add an opt-in verbose mode that logs each
move/delete as it happens; the lazy render-time migration path stays
silent so normal statusline renders aren't spammed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@tmck-code
tmck-code merged commit 64ca55e into main Aug 20, 2026
6 checks passed
@tmck-code
tmck-code deleted the spec/consolidate-claude-dir-layout branch August 20, 2026 12:56
tmck-code pushed a commit that referenced this pull request Aug 20, 2026
…/ path consolidation

Resolves conflicts between the #120 path-consolidation (all YAS files moved
under ~/.claude/yas/) and the transcript-parse-cache feature by routing the
transcript cache path through a new transcript_cache_path() helper in
constants.py, matching the consolidated cache_dir() convention.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant