Commit Graph

19 Commits

Author SHA1 Message Date
Bastien Chanot
131d0bcb5d feat(secrets): .env source-of-truth in ~/.claude + repo symlink
Move the real secret out of the git tree: the key lives in ~/.claude/.env
(outside the repo), and link.sh symlinks repo/.env -> ~/.claude/.env so
`source "$REPO/.env"` resolves transparently. The secret never enters git —
not as content (it's a link) and not by accident (gitignored).

link.sh: add link_env() — verify ~/.claude/.env exists + has MAGIC_API_KEY
(warn, never create/copy the secret), then create repo/.env -> ~/.claude/.env.
Defensive + idempotent: links only when repo/.env is absent or already the
right symlink; a residual REAL repo/.env is left untouched with a migrate hint
(never clobbered, so the secret can't be destroyed).

.gitignore: harden .env -> .env + .env.* + !.env.example (covers .env.local,
.env.bak, .env.save; keeps the template tracked).

Messages point at ~/.claude/.env (the canonical edit location) instead of the
ambiguous $REPO/.env: design-tool-gate.sh gate output, design-gate.md
(branch 3 + IMPORTANT), toggle-external.sh, install-plugins.sh.

Verified: shellcheck clean (link.sh, toggle-external.sh, design-tool-gate.sh);
link.sh created the symlink (1 change, idempotent re-run); repo/.env absent
from git status; magic-off path still exits 10 with the ~/.claude/.env hint.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 11:44:47 +02:00
Bastien Chanot
d4a5cfec93 chore(caveman): purge plugin + always-on integration
Disable + uninstall caveman@caveman and delete every repo dependency on
it: SessionStart/UserPromptSubmit hook blocks, standalone hook files,
settings.json enabledPlugins + marketplace entries, install-plugins.sh
STEP 5.5, update-all.sh refresh step, plugins.lock.json entry, doctor.sh
checks, lib/detect-plugins.sh helpers, lib/profile.sh + plugin-advisor +
skills/profile protected-list entries, .gitignore runtime-file block,
and README/USAGE docs. Dead /caveman:compress refs replaced with
manual/claude.ai guidance. Memory-registry terse-format convention kept
(separate subsystem). Version 3.4.0 -> 3.5.0.

On a subscription plan caveman's ~75% output-token compression has no
cost benefit, and the always-on hooks added friction on validation
gates and client deliverables.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X3e8LaH2vymmxyh36h3jFU
2026-06-19 19:08:40 +02:00
Bastien Chanot
2c4c01dc3e chore(design-motion): quote SKILL.md description, gitignore local symlink
Wrap the frontmatter description in quotes (defensive valid-YAML: it contains an em-dash and an apostrophe). Add skills/design-motion-principles to the external-skill-symlink ignore allowlist so it matches its 4 siblings (emil-design-eng, frontend-design, darwin-skill, find-skills) and stops surfacing as untracked noise — consistent with the LRN-025 allowlist rule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 16:28:51 +02:00
Bastien Chanot
f928a53ed9 fix(gstack): link spec skill, complete gitignore allowlist (BLK-007)
A gstack submodule bump added `spec` (v1.47) and the iOS device-farm
5-skill set (v1.43) but gstack `./setup` was never re-run, leaving all 6
as source-only — unlinked, invisible to Claude and untouched by
reset/`gstack on`.

  - Link `spec` only, surgically: skills/spec/SKILL.md symlink matching
    gstack setup's per-skill pattern (real dir + absolute SKILL.md link).
    Platform-agnostic, useful planning skill. Added to full + web-full
    profiles (must be in the active `full` profile or `set full` would
    re-disable it).
  - iOS skills deliberately NOT linked: this is a Linux host, and the iOS
    device-farm needs a Mac daemon + Tailscale + physical iOS devices.
    Linking them would add 5 dead skills plus passive token cost.
  - Complete the .gitignore gstack allowlist: add the 12 entries missing
    from it — `spec`, the 5 `ios-*` (so they stay ignored if a future
    setup on a Mac materializes them), and 6 already-parked skills
    (document-generate, landing-report, scrape, setup-gbrain, skillify,
    sync-gbrain). The parked ones matter because `gstack on` moves parked
    skills into skills/, where any allowlist gap becomes untracked git
    noise. Also drop the stale `skills/checkpoint` entry (renamed to
    context-save).

Verified: `profile show full`/`web-full` report spec enabled; the
source-vs-allowlist drift check is now empty; profile.sh still parses.

The gstack submodule pointer bump itself is left uncommitted (separate
pending work).

Memory: BLK-007 -> resolved; LRN-025 (gitignore allowlist must cover all
toggleable skills incl. parked, else enabling one = git noise).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 18:41:43 +02:00
Bastien Chanot
0380f218c1 chore(gitignore): add .gstack/ to ignore list
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 07:20:34 +02:00
Bastien Chanot
057a5b7f5c feat(skills): add frontend-design from anthropic-agent-skills
Source: anthropic-agent-skills plugin cache → skills-external/frontend-design/
Auto-install via install-plugins.sh step 8b, auto-update via update-all.sh
step 7.1, symlinked by link.sh (refactored to loop over EXTERNAL_SKILLS).
Added to profiles: design, web, web-full, full.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-23 00:58:30 +02:00
Bastien Chanot
cb1e8cd814 feat(profile,statusline): show active profile in statusline via .active-profile cache
`bash lib/profile.sh current` is 12s+ — far too slow to call from the
statusline hook (runs on every keystroke). Add a one-line cache file at
`<repo>/.active-profile`, written by `cmd_apply` and `cmd_reset`. The
statusline reads the file directly with a single `head -n1`, no
sub-shell into `profile.sh`.

Behavior:
- `bash lib/profile.sh set <name>` (which ends in `cmd_apply`) and
  `bash lib/profile.sh apply <name>` both write `<name>` to
  `<repo>/.active-profile`.
- `bash lib/profile.sh reset` writes the literal `none`.
- Statusline inserts the cached profile name between the plan segment
  and the context-bar segment, e.g.
  `Opus 4.7 | claude (master) | Max | full | ████░░░░░░ 42% | 3m`.
- Missing or empty cache → statusline shows `?`.

Cache file is gitignored — it tracks runtime state, not source.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-21 05:14:12 +02:00
bastien
b447a892b1 fix(client-handover): PDF render bugs — marked CLI, white cover, PNG logo
Three bugs surfaced on the LIVRAISON.pdf test render:

1. **MD→HTML conversion** — host had no pandoc, no python-markdown, fell
   back to `npx marked < "$src"`. marked CLI 16.x ignores stdin and
   dumps its own cli.js source. Resulting PDF body = marked's binary
   source (`#!/usr/bin/env node`, `Marked CLI`, copyright). Fix:
   `npx --yes marked --gfm -i "$src"` (file path via -i, not stdin).

2. **Cover background** — original cream `#F5F0EB` + 8mm green stripe
   was washed out. Iterated to white-pure bg with subtle radial
   sage/forest tints, black-deep title, green-forest accents
   (eyebrow, meta labels, footer, border). Solid green-dark tried
   first then rejected (too heavy for long client-facing doc).

3. **Default logo** — SVG `logo-horizontal.svg` rendered cream-toned,
   blended into bg. Switched LOGO_URL default to
   `https://zenquality.fr/assets/logo-horizontal-1024.png`.

Also added test-artifact gitignore rules for LIVRAISON.* / HANDOVER.*
project-local renders.

Verified: regenerated LIVRAISON.pdf → 164 KB, 19 pages, full content
rendered, white cover with black title + green-forest accents +
visible PNG logo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 19:57:08 +02:00
bastien
ee00f8c32f chore(gitignore): exclude *.original.md compress backups
/caveman:compress writes a human-readable backup as <file>.original.md
before overwriting. Backups are recoverable via git history (the
pre-compression state lives in the previous commit), so committing
them duplicates content and bloats the repo.

Globbing on *.original.md catches all compressed registries plus
CLAUDE.original.md.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-05 23:46:47 +02:00
bastien
e4f4edc121 feat(caveman): full install — plugin + standalone hooks + MCP scaffold
Wires JuliusBrussee/caveman into the always-on tier alongside
security-guidance and superpowers. Caveman compresses Claude's output
tokens (~75%) by speaking like a caveman while keeping technical
substance. Three layers:

  1. Plugin (caveman@caveman, marketplace JuliusBrussee/caveman)
     — adds /caveman, /caveman-commit, /caveman-review, /caveman-stats,
       /caveman-help, /cavecrew, /compress + 3 cavecrew agents +
       SessionStart/UserPromptSubmit hooks from the plugin path.
  2. Standalone hooks (statusline + stats badge) deployed by
     caveman's own hooks/install.sh into ~/.claude/hooks/. Paths in
     settings.json normalized to ~/.claude/hooks/... so this user's
     home dir doesn't leak across machines.
  3. caveman-shrink MCP proxy — NOT auto-registered. The bare proxy
     fails health checks because it requires an upstream MCP server
     to wrap. install-plugins.sh STEP 5.5 prints a snippet showing how
     to register a wrapped entry (e.g. caveman-shrink-fs) when the user
     decides which upstream to compress.

New helper enable_plugin() for explicit always-on activation —
'claude plugin install' only copies into cache, doesn't write
enabledPlugins. Idempotent via Python json check.

doctor.sh adds detect_caveman / detect_caveman_hooks / detect_caveman_shrink
checks plus a 300t passive-cost adder. update-all.sh refreshes hook
files via the upstream installer's --force mode.

.gitignore covers caveman runtime files materialized into hooks/
because ~/.claude/hooks is symlinked to this repo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 23:02:47 +02:00
bastien
32ccceb548 fix(gitignore): un-ignore shared .claude/{tasks,memory,audits}/
Previous rule (.claude/) ignored everything under .claude/, making
the new governance files invisible to git. Switches to a wildcard
pattern with explicit negations: tasks/memory/audits/settings.json
become trackable; settings.local.json and agent-memory/ stay
per-machine. Commits existing .claude/settings.json which now falls
under the tracked scope.

Verified with git check-ignore:
- .claude/memory/decisions.md → exit 1 (not ignored) ✓
- .claude/tasks/TODO.md      → exit 1 (not ignored) ✓
- .claude/settings.local.json → exit 0 (ignored)    ✓
- .claude/agent-memory/      → exit 0 (ignored)     ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 16:06:44 +02:00
bastien
72920e032e feat(toggle-external): manage Magic MCP (21st-dev) — installed disabled by default
Add `magic` to the unified toggle-external.sh helper alongside gstack,
emil-design-eng, darwin-skill, find-skills. MCPs are toggled via
`claude mcp add|remove` instead of symlink moves.

API key loaded from $REPO/.env (gitignored) via .env.example template.
install-plugins.sh step 8.7 forces magic MCP off after each install run
so the MCP doesn't load into every session unless explicitly enabled.

Toggle: bash lib/toggle-external.sh enable|disable|status magic

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 20:28:03 +02:00
bastien
6ade88f38d chore(gitignore): ignore new gstack skills from v0.17.0 submodule bump
gstack 0.17.0 added 5 skills that land in skills/ via gstack ./setup
(benchmark-models, context-restore, context-save, make-pdf, plan-tune).
The older gstack skills are already ignored here — extend the list so
these don't show up as untracked after `make update`.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-21 15:18:43 +02:00
bastien
ec14261c82 feat(toggle): enable/disable non-marketplace tools via lib/toggle-external.sh
`claude plugin enable|disable` only toggles marketplace plugins.
Tools living as symlinks (gstack per-skill entries, emil-design-eng,
darwin-skill, find-skills) had no lever — users had to edit symlinks
by hand. The new script moves symlinks in/out of skills-disabled/
so Claude Code stops or starts scanning them.

Also removes the legacy global `skills/gstack` symlink that shadowed
per-skill entries with a duplicate top-level "gstack" skill (same
description as "browse"). gstack detection in detect-plugins.sh now
probes an individual skill instead.

plugin-advisor reads the new script's `list` command when gathering
state and emits its `enable|disable` commands in recommendations.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-21 13:50:40 +02:00
bastien
85637d83ec fix(update): pass full name@marketplace to claude plugin update
`claude plugin update` rejects a bare plugin name when multiple
marketplaces are registered — the CLI demands `name@marketplace`.
update-all.sh stripped the suffix via `${_p%%@*}`, causing every
marketplace plugin update to fail with "Plugin not found". Fixed
by passing the unmodified spec from `claude plugin list`.

Also adds install + update paths for external skills distributed
through the `npx skills` CLI (vercel-labs/skills):
  - alchaincyf/darwin-skill
  - alchaincyf/find-skills

These land in ~/.agents/skills/ and are now symlinked into
$REPO/skills/ via link.sh using absolute paths — the previous
relative `../../.agents/...` targets resolved incorrectly when
the repo is cloned below $HOME (as ~/Documents/claude/), leaving
dangling symlinks.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-21 13:47:51 +02:00
bastien
74a0901cc4 add emil-design-eng skill to install/update pipeline
- Download SKILL.md from emilkowalski/skill to skills-external/
- Symlink to ~/.claude/skills/ via link.sh
- install-plugins.sh step 9: curl download + symlink check
- update-all.sh step 8: re-fetch latest SKILL.md on update
- plugins.lock.json: add emil-design-eng entry
- .gitignore: ignore auto-created symlink in skills/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 14:31:24 +02:00
bastien
759c67339b untrack gstack skill symlinks — auto-created by install-plugins.sh
These 37 symlinks point to skills-external/gstack/ and are recreated
automatically by the gstack setup during install-plugins.sh. They
should not be versioned. Added all patterns to .gitignore.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 15:02:43 +02:00
bastien
0dac12b885 add gstack skill symlinks, graphify skill, and gitignore updates
Track all gstack-provided skill symlinks (autoplan, browse, qa, etc.)
and the graphify skill. Add .claude/, graphify-out/, .ctx7-cache/ to
gitignore to exclude local/generated files from the repo.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 14:56:03 +02:00
bastien
f8811fab37 opus version correction 2026-04-03 18:08:21 +02:00