feat: fold in the portable Claude Code, zsh and git config; add a drift check

Added (all now linked from their live locations):
- home_root/.claude/settings.json. The statusLine command now uses $HOME
  instead of a Linux-only absolute path.
- home_root/.claude/bin/ratecheck and home_root/.claude/skills/australis-design.
- home_config/zsh/claude-config-dir.zsh and home_root/.local/bin/claude-config-dir-init,
  the per-repo Claude Code login helper and its seeding script.
- home_root/.gitconfig and home_config/git/ignore.
- home_root/.zshenv, with the cargo env line guarded so boxes without rust start clean.

link-dotfiles --check reports drift without changing anything: tracked files whose
live copy is no longer a link (stow dry-run conflicts) and links into this repo
that dangle. Exits 1 on drift. Verified against a clean baseline and two planted
drifts, a detached .nanorc and a dangling link.

.mailmap maps every earlier identity to Vuong Hoang: the repo-local 'Your Name'
placeholder config (now removed), host-generated emails, and aider suffixes.

CLAUDE.md: the symlink warning now lists every linked file and points at --check.
README: documents what is and isn't tracked under .claude, the edit rule, and --check.
This commit is contained in:
vh
2026-09-24 09:07:16 -07:00
parent 77225b01d6
commit 7b16be02bf
49 changed files with 2675 additions and 4 deletions
@@ -0,0 +1,45 @@
// Inline Lucide-style icons. 24×24 viewBox, 1.75 stroke, currentColor, no fill.
// Keep the set small — add icons as the kit grows.
const Icon = ({ name, size = 18, style }) => {
const props = {
width: size, height: size, viewBox: "0 0 24 24",
fill: "none", stroke: "currentColor",
strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round",
style,
};
switch (name) {
case "search": return <svg {...props}><circle cx="11" cy="11" r="7"/><path d="M21 21l-5-5"/></svg>;
case "chevron-r": return <svg {...props}><path d="M9 6l6 6-6 6"/></svg>;
case "chevron-d": return <svg {...props}><path d="M6 9l6 6 6-6"/></svg>;
case "file": return <svg {...props}><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/></svg>;
case "folder": return <svg {...props}><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>;
case "terminal": return <svg {...props}><path d="M4 17l6-6-6-6M12 19h8"/></svg>;
case "settings": return <svg {...props}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1A2 2 0 1 1 4.3 17l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1A1.7 1.7 0 0 0 4.6 9a1.7 1.7 0 0 0-.3-1.8l-.1-.1A2 2 0 1 1 7 4.3l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/></svg>;
case "git-branch": return <svg {...props}><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>;
case "play": return <svg {...props}><polygon points="5 3 19 12 5 21 5 3"/></svg>;
case "x": return <svg {...props}><path d="M18 6L6 18M6 6l12 12"/></svg>;
case "check": return <svg {...props}><path d="M3 12l6 6 12-12"/></svg>;
case "alert": return <svg {...props}><path d="M10.3 3.86a2 2 0 0 1 3.4 0l8.5 14a2 2 0 0 1-1.7 3H3.5a2 2 0 0 1-1.7-3z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>;
case "command": return <svg {...props}><path d="M18 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3H6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3V6a3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3h12a3 3 0 0 0 3-3 3 3 0 0 0-3-3z"/></svg>;
case "circle": return <svg {...props}><circle cx="12" cy="12" r="4" fill="currentColor"/></svg>;
case "plus": return <svg {...props}><path d="M3 12h18M12 3v18"/></svg>;
case "logo": return (
<svg width={size} height={size} viewBox="0 0 64 64" fill="none">
<defs>
<linearGradient id="ig" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="#a4c4ff"/>
<stop offset="45%" stopColor="#42dcd1"/>
<stop offset="100%" stopColor="#16b866"/>
</linearGradient>
</defs>
<path d="M10 48 C 14 22, 22 12, 28 8 L 30 8 C 26 18, 22 32, 22 48 Z" fill="url(#ig)" opacity="0.95"/>
<path d="M24 48 C 30 28, 36 18, 42 12 L 44 12 C 38 22, 34 34, 34 48 Z" fill="url(#ig)" opacity="0.7"/>
<path d="M38 48 C 44 32, 50 24, 56 20 L 58 20 C 52 28, 48 38, 48 48 Z" fill="url(#ig)" opacity="0.5"/>
</svg>
);
default: return null;
}
};
window.Icon = Icon;