Skip to content

Commit 4bbd9be

Browse files
niketpathakclaude
andcommitted
📝 docs: add improvement plan, AGENTS.md, .editorconfig; rewrite README
- docs/plans/2026-06-10-improvement-plan.md: findings, executed Phase 1, proposed Phase 2, decision record for de-vendoring git-prompt.sh - AGENTS.md: repo map, hard rules and verification steps for agents - README: layout table, install instructions, git-prompt update usage, CI badge and local check commands - .editorconfig: UTF-8/LF/final-newline baseline Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 57d30bd commit 4bbd9be

4 files changed

Lines changed: 271 additions & 4 deletions

File tree

.editorconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# https://editorconfig.org
2+
root = true
3+
4+
[*]
5+
charset = utf-8
6+
end_of_line = lf
7+
insert_final_newline = true
8+
trim_trailing_whitespace = true
9+
10+
[*.{yml,yaml,toml}]
11+
indent_style = space
12+
indent_size = 2
13+
14+
[*.md]
15+
# trailing double-space is meaningful in markdown
16+
trim_trailing_whitespace = false

AGENTS.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# AGENTS.md
2+
3+
Guidance for AI agents (and humans) working in this repository.
4+
5+
## What this repository is
6+
7+
Personal dotfiles / development-environment preferences. There is **no application code,
8+
no build step, and no test suite**. Every file here is configuration that gets copied or
9+
symlinked into `$HOME` on a developer machine. Mistakes ship silently — a broken
10+
`.zshrc` means a broken shell on the next machine provisioned from this repo, so treat
11+
small edits with the same care as production code.
12+
13+
## Layout
14+
15+
| Path | Maps to (typical) | Notes |
16+
|---------------------------------|--------------------------------------------|----------------------------------------------------|
17+
| `bash/.bash_profile` | `~/.bash_profile` | Login-shell setup, history, git-prompt wiring, starship |
18+
| `bash/.bash_aliases` | `~/.bash_aliases` and `$ZSH_CUSTOM/aliases.zsh` | Shared between bash and zsh — keep it polyglot (no bashisms/zshisms) |
19+
| `zsh/.zshrc` | `~/.zshrc` | Oh My Zsh, plugins, history options, starship |
20+
| `zsh/.zshenv` | `~/.zshenv` | Cargo env only |
21+
| `git/.gitconfig` | `~/.gitconfig` | Aliases + defaults; `user` section is a placeholder on purpose |
22+
| `git/.gitignore_global` | `~/.gitignore_global` | Referenced by `core.excludesfile` |
23+
| `starship/starship.toml` | `~/.config/starship.toml` | Prompt config (used by both shells) |
24+
| `terminator/config` | `~/.config/terminator/config` | Terminal emulator |
25+
| `lsd/*.yaml` | `~/.config/lsd/` | `ls` replacement config |
26+
| `scripts/update-git-prompt.sh` | run, not installed | Fetches latest upstream `git-prompt.sh` to `~/.git-prompt.sh` |
27+
| `docs/plans/` || Improvement plans / decision records |
28+
29+
## Hard rules
30+
31+
1. **Do not vendor third-party scripts.** `git-prompt.sh` was vendored once and went
32+
stale; it is now fetched by `scripts/update-git-prompt.sh`. If a new external script
33+
is needed, add a fetch/update script instead of committing the file.
34+
2. **Never commit secrets or personal data.** The `user` section of `git/.gitconfig`
35+
stays as a placeholder (`me@example.com`); real identity lives only on the machine.
36+
3. **ShellCheck must pass.** CI runs ShellCheck (bash dialect) on `bash/` and
37+
`scripts/`. Prefer fixing findings; when a finding is a false positive (e.g. a
38+
variable consumed by a sourced script), add a targeted
39+
`# shellcheck disable=SCxxxx` directive *with a comment explaining why*.
40+
4. **zsh files cannot be ShellChecked** (unsupported dialect). Validate zsh changes with
41+
`zsh -n zsh/.zshrc` instead.
42+
5. **Anything sourced at shell startup must be guarded.** Pattern:
43+
`[ -f file ] && source file`. A missing optional file must never break the shell.
44+
6. **`bash/.bash_aliases` is shared with zsh.** Only use syntax valid in both shells.
45+
46+
## Conventions
47+
48+
- **Commits:** short imperative subject, optionally prefixed with a gitmoji + type, e.g.
49+
`🔧 chore: update command timeout for starship`, `🩹 fix: pnpm path …`. Match the
50+
existing `git log` style. Commits go directly to `master` (single-maintainer repo).
51+
- **Comments:** these files double as documentation; keep the explanatory comment style
52+
(what an option does and why it is set).
53+
- **Indentation/whitespace:** governed by `.editorconfig`.
54+
55+
## Verifying changes
56+
57+
```sh
58+
# Lint bash + scripts (what CI runs)
59+
shellcheck -s bash bash/.bash_aliases bash/.bash_profile scripts/*.sh
60+
61+
# Syntax-check zsh
62+
zsh -n zsh/.zshrc
63+
64+
# Validate gitconfig parses and keys resolve
65+
git config -f git/.gitconfig --list
66+
67+
# Try the git-prompt updater against a temp path
68+
GIT_PROMPT_DEST=$(mktemp) scripts/update-git-prompt.sh
69+
```
70+
71+
## Pointers
72+
73+
- Current improvement plan: `docs/plans/2026-06-10-improvement-plan.md`
74+
- CI: `.github/workflows/shellcheck.yml`

README.md

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,81 @@
11
# Development Preferences
22

3-
These are my personal preferences while doing development.
3+
[![ShellCheck](https://github.com/niketpathak/devpreferences/actions/workflows/shellcheck.yml/badge.svg)](https://github.com/niketpathak/devpreferences/actions/workflows/shellcheck.yml)
44

5-
### [Reference article](http://digitalfortress.tech/tricks/creating-a-global-gitignore/) to setup a **global .gitignore** file
5+
Personal development environment preferences (dotfiles), organised per tool.
66

7-
### [Reference article](https://digitalfortress.tech/tutorial/create-global-gitconfig-git-alias/) to setup a **global .gitconfig** file as well as **git alias**
7+
## Layout
88

9+
| Path | Installs to (typical) | Purpose |
10+
|--------------------------------|--------------------------------------------------|------------------------------------------|
11+
| `bash/.bash_profile` | `~/.bash_profile` | Bash login shell: history, git prompt, starship |
12+
| `bash/.bash_aliases` | `~/.bash_aliases` **and** `$ZSH_CUSTOM/aliases.zsh` | Aliases shared between bash and zsh |
13+
| `zsh/.zshrc` | `~/.zshrc` | Oh My Zsh, plugins, history, starship |
14+
| `zsh/.zshenv` | `~/.zshenv` | Cargo environment |
15+
| `git/.gitconfig` | `~/.gitconfig` | Git aliases and sensible defaults |
16+
| `git/.gitignore_global` | `~/.gitignore_global` | Global gitignore (wired via `core.excludesfile`) |
17+
| `starship/starship.toml` | `~/.config/starship.toml` | [Starship](https://starship.rs) prompt |
18+
| `terminator/config` | `~/.config/terminator/config` | Terminator terminal |
19+
| `lsd/config.yaml`, `lsd/icons.yaml` | `~/.config/lsd/` | [lsd](https://github.com/lsd-rs/lsd) (`ls` replacement) |
20+
| `scripts/update-git-prompt.sh` | — (run it, don't install it) | Fetches the latest upstream `git-prompt.sh` |
921

10-
#### The default .gitconfig file is located at *~/.gitconfig* (For Unix systems alone. See above article for other OS's).
22+
## Installation
23+
24+
Symlink (preferred — edits in the repo apply immediately) or copy the files to the
25+
locations above. Example:
26+
27+
```sh
28+
ln -s "$PWD/git/.gitconfig" ~/.gitconfig
29+
ln -s "$PWD/git/.gitignore_global" ~/.gitignore_global
30+
ln -s "$PWD/zsh/.zshrc" ~/.zshrc
31+
ln -s "$PWD/bash/.bash_aliases" ~/.bash_aliases
32+
ln -s "$PWD/bash/.bash_aliases" "$HOME/.oh-my-zsh/custom/aliases.zsh"
33+
ln -s "$PWD/starship/starship.toml" ~/.config/starship.toml
34+
```
35+
36+
Then set your identity locally (the committed `.gitconfig` ships a placeholder):
37+
38+
```sh
39+
git config --global user.name "Your Name"
40+
git config --global user.email "you@example.com"
41+
```
42+
43+
> Note: `git config --global` writes through the symlink into this repo's
44+
> `git/.gitconfig` — if you symlinked it, set your identity by hand in a separate
45+
> machine-local file instead, e.g. keep `~/.gitconfig` as a 3-line file that sets
46+
> `user.*` and uses `[include] path = /path/to/devpreferences/git/.gitconfig`.
47+
48+
## git-prompt.sh
49+
50+
`~/.git-prompt.sh` (used by `bash/.bash_profile` for `__git_ps1`) is **not vendored in
51+
this repo** — it used to be, and went stale. Install or update it with:
52+
53+
```sh
54+
scripts/update-git-prompt.sh
55+
```
56+
57+
This downloads the canonical version from
58+
[git/git `contrib/completion/git-prompt.sh`](https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh)
59+
to `~/.git-prompt.sh` (override the destination with `GIT_PROMPT_DEST=/path`).
60+
Re-run it whenever you want to pick up upstream changes. The decision record is in
61+
[docs/plans/2026-06-10-improvement-plan.md](docs/plans/2026-06-10-improvement-plan.md).
62+
63+
## Quality checks
64+
65+
CI runs ShellCheck on the bash files and `scripts/`, plus a `zsh -n` syntax check on the
66+
zsh files (see `.github/workflows/shellcheck.yml`). Run locally:
67+
68+
```sh
69+
shellcheck -s bash bash/.bash_aliases bash/.bash_profile
70+
shellcheck scripts/*.sh
71+
zsh -n zsh/.zshrc
72+
```
73+
74+
Contributor/agent conventions live in [AGENTS.md](AGENTS.md); improvement plans live in
75+
[docs/plans/](docs/plans/).
76+
77+
## References
78+
79+
- [Reference article](https://digitalfortress.tech/tricks/creating-a-global-gitignore/) to setup a **global .gitignore** file
80+
- [Reference article](https://digitalfortress.tech/tutorial/create-global-gitconfig-git-alias/) to setup a **global .gitconfig** file as well as **git alias**
81+
- The default `.gitconfig` file is located at `~/.gitconfig` (for Unix systems; see the article above for other OSes)
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Improvement Plan — devpreferences
2+
3+
**Date:** 2026-06-10
4+
**Status:** Phase 1 executed; Phase 2 proposed
5+
**Scope:** Repository hygiene, CI, dependency management for vendored scripts, documentation, and shell-config correctness.
6+
7+
## 1. Repository overview
8+
9+
This repository holds personal development environment preferences (dotfiles), organised by tool:
10+
11+
| Directory | Contents |
12+
|---------------|-----------------------------------------------------------------|
13+
| `bash/` | `.bash_profile`, `.bash_aliases` (aliases shared with zsh) |
14+
| `zsh/` | `.zshrc` (Oh My Zsh + starship), `.zshenv` (cargo env) |
15+
| `git/` | `.gitconfig` (aliases + sensible defaults), `.gitignore_global` |
16+
| `starship/` | `starship.toml` prompt configuration |
17+
| `terminator/` | Terminator terminal emulator configuration |
18+
| `lsd/` | `config.yaml`, `icons.yaml` for lsd (ls replacement) |
19+
20+
There is no build system, no tests, and (before this plan) no CI. Files are consumed by manually copying or symlinking them into `$HOME`.
21+
22+
## 2. Findings
23+
24+
### 2.1 Bugs / correctness
25+
26+
1. **`git/.gitconfig` — invalid config key (silent failure).**
27+
`[core] excludefile = ~/.gitignore_global` uses a non-existent key. The correct key is
28+
`excludesfile` (`core.excludesFile`). Git ignores unknown keys silently, so the global
29+
gitignore referenced by the README has never actually been active through this file.
30+
31+
2. **`git/.git-prompt.sh` is a stale vendored copy.**
32+
The header claims "Aug 2024", but comparison of git blob SHAs against
33+
`git/git@master:contrib/completion/git-prompt.sh` shows the local copy
34+
(blob `a187b63…` after stripping the two local header lines) differs from upstream
35+
(blob `6186c47…`, 21,338 bytes vs ~18,660 locally). The local copy predates the
36+
2024-08-20 upstream batch which added custom 0-width PS1 marker support and several
37+
portability/quoting fixes (`fbcdfab`, `0dbe3d3`, `29bcec8`, `b732e08`, `fe445a1`).
38+
Vendoring third-party scripts with no update mechanism guarantees this kind of drift.
39+
40+
3. **`zsh/.zshrc` — unguarded source.**
41+
`source $ZSH_CUSTOM/aliases.zsh` aborts with an error on any machine where that file
42+
has not been symlinked yet, producing a noisy (and partially broken) shell startup.
43+
44+
### 2.2 Hygiene / industry standards gaps
45+
46+
4. **No CI.** Shell config files are exactly the kind of artifact that benefits from
47+
ShellCheck: errors are silent and only discovered on the next machine you provision.
48+
5. **No agent/contributor entry point.** No `AGENTS.md`; the README does not describe
49+
the repo layout, installation, or conventions (e.g. gitmoji-style commit subjects).
50+
6. **No `.editorconfig`.** Mixed editors across machines can introduce whitespace drift.
51+
7. **ShellCheck findings in `bash/.bash_profile`.** A mix of false positives
52+
(`GIT_PS1_*` variables consumed by the sourced `git-prompt.sh`; color variables used
53+
by the deprecated-but-kept `color_my_prompt`) and one legitimate style issue
54+
(`SC2155` declare-and-assign). These need inline directives with justification so CI
55+
can run at default severity instead of being watered down globally.
56+
8. **No automated update for GitHub Actions versions.** Once CI exists, action versions
57+
should be kept current (Dependabot).
58+
59+
## 3. Plan
60+
61+
### Phase 1 — executed now
62+
63+
| # | Action | Details |
64+
|---|--------|---------|
65+
| 1 | **Fix `core.excludesfile` typo** | `excludefile``excludesfile` in `git/.gitconfig`. |
66+
| 2 | **De-vendor `git-prompt.sh`** | Delete `git/.git-prompt.sh`. Add `scripts/update-git-prompt.sh` which downloads the latest upstream version from `git/git@master` to `~/.git-prompt.sh` (configurable destination, fails loudly, validates the download looks like the real script before installing). `bash/.bash_profile` already sources `~/.git-prompt.sh` only if present, so no change needed there. |
67+
| 3 | **Add ShellCheck CI** | `.github/workflows/shellcheck.yml`: runs on push/PR, checks `bash/` dotfiles and `scripts/*.sh` with bash dialect. zsh files are excluded (ShellCheck does not support zsh). |
68+
| 4 | **Make bash files ShellCheck-clean** | Add `# shellcheck shell=bash` headers, targeted `disable` directives with reasons (SC2034 for externally-consumed vars, SC1090/SC1091 for runtime sources), and fix the real SC2155 finding. |
69+
| 5 | **Guard zsh alias sourcing** | `[ -f "$ZSH_CUSTOM/aliases.zsh" ] && source …` so a fresh machine still gets a working shell. |
70+
| 6 | **Add `AGENTS.md`** | Repo map, conventions, what is safe to change, how files map to `$HOME`, CI expectations. |
71+
| 7 | **Add `.editorconfig`** | UTF-8, LF, final newline, 2-space indent for YAML/TOML, tabs preserved where files already use them. |
72+
| 8 | **Add Dependabot config** | Weekly updates for GitHub Actions. |
73+
| 9 | **Rewrite `README.md`** | Layout table, installation/symlink instructions, git-prompt update script usage, link to plans and AGENTS.md. Keep the existing reference-article links. |
74+
75+
### Phase 2 — proposed (not executed)
76+
77+
| # | Action | Rationale |
78+
|---|--------|-----------|
79+
| 1 | **`install.sh` or GNU Stow adoption** | Symlinking by hand is error-prone. GNU Stow is the de-facto standard for dotfiles (`stow bash git zsh …`); the current per-tool directory layout is almost Stow-compatible already (files would need to mirror `$HOME`-relative paths, e.g. `lsd/.config/lsd/config.yaml`). Decide between Stow and a small idempotent `install.sh`; either should back up existing files before linking. |
80+
| 2 | **Add a LICENSE** | The repo is public; without a license it is "all rights reserved" by default. MIT is typical for dotfiles. Left as a deliberate owner decision. |
81+
| 3 | **zsh syntax check in CI** | ShellCheck cannot lint zsh; a cheap `zsh -n zsh/.zshrc` job catches syntax errors. |
82+
| 4 | **Scheduled CI freshness check for git-prompt** | A monthly workflow comparing upstream blob SHA against a recorded one, opening an issue when upstream moves. Complements the update script. |
83+
| 5 | **Pre-commit hooks** | `pre-commit` with `shellcheck` + whitespace hooks for local feedback before CI. |
84+
| 6 | **Retire deprecated prompt code** | `color_my_prompt` and the color variables in `bash/.bash_profile` are dead since starship took over the prompt; once confident, delete them (they are the main source of ShellCheck noise). |
85+
| 7 | **Pin starship/lsd minimum versions in docs** | Configs assume features of specific tool versions; documenting them avoids surprises on older distros. |
86+
87+
## 4. git-prompt.sh strategy (decision record)
88+
89+
**Options considered:**
90+
91+
- **A. Keep vendoring, update manually** — status quo; proven to drift (header said
92+
"Aug 2024" yet was already behind other Aug 2024 commits).
93+
- **B. Git submodule of `git/git`** — pulls a ~250 MB repository for one 21 KB file;
94+
rejected.
95+
- **C. Fetch-on-demand script (chosen)**`scripts/update-git-prompt.sh` downloads the
96+
canonical file from `https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh`
97+
into `~/.git-prompt.sh`. Pros: always current on demand, removes 612 lines of
98+
third-party code from the repo, no merge noise on updates. Cons: requires network on
99+
first setup; mitigated by clear error messages. The script validates the downloaded
100+
content (shebang-less but must contain `__git_ps1`) and is atomic (temp file + `mv`).
101+
102+
## 5. Verification
103+
104+
- `shellcheck` (v0.9.0, bash dialect) passes locally on all checked files at default severity.
105+
- `scripts/update-git-prompt.sh` exercised locally against a temp destination.
106+
- `git -c include.path=… config core.excludesfile` resolves after the typo fix.

0 commit comments

Comments
 (0)