You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: interactive setup command, banner footer, and TTY-gated color
Add a 'setup [shell]' command that installs shell integration for the user:
it detects the shell, then either appends a single 'shannon init' line to the
startup file (resolving the live PowerShell $PROFILE) or prints just that line
to paste — replacing the wall-of-snippet that 'init' dumped. 'init' stays the
raw eval target. The banner gains a title/version/attribution footer, and
output is colorized only when stdout is a TTY (honoring NO_COLOR/FORCE_COLOR)
so pipes, eval'd snippets, and copied text stay plain. Standalone 'use' now
points at 'setup'. Adds integration helpers + tests and documents it.
Copy file name to clipboardExpand all lines: CLAUDE.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -53,7 +53,7 @@ Profile names must match `[A-Za-z0-9_-]+` (reject empty, leading `.`, `..`, `/`,
53
53
54
54
## Command interface
55
55
56
-
`create <name> [--from <src>] [--with-credentials]`, `list`/`ls`, `default [name]`, `which [name]`, `use <name>`, `clone <src> <dst> [--with-credentials]`, `delete`/`rm <name> [--yes]`, `status`/`st`, `init<shell>`, `update`/`upgrade`, `help`, `--version`. Bare `shannon` (no args) prints profile status and never launches `claude` implicitly. `shannon run …`, `shannon -- …`, or any non-subcommand token launches `claude` with the active profile. `create --from <src>` copies an existing profile (same shared copy routine as `clone`); both omit `.credentials.json` unless `--with-credentials` is passed.
56
+
`create <name> [--from <src>] [--with-credentials]`, `list`/`ls`, `default [name]`, `which [name]`, `use <name>`, `clone <src> <dst> [--with-credentials]`, `delete`/`rm <name> [--yes]`, `status`/`st`, `setup [shell]` (interactive integration installer — adds one `init` line to the shell startup file, or shows it), `init <shell>` (raw emit, eval target), `update`/`upgrade`, `help`, `--version`. Bare `shannon` (no args) prints profile status and never launches `claude` implicitly. `shannon run …`, `shannon -- …`, or any non-subcommand token launches `claude` with the active profile. `create --from <src>` copies an existing profile (same shared copy routine as `clone`); both omit `.credentials.json` unless `--with-credentials` is passed.
57
57
58
58
## Design constraints (do not violate)
59
59
@@ -72,6 +72,7 @@ Profile names must match `[A-Za-z0-9_-]+` (reject empty, leading `.`, `..`, `/`,
72
72
-**M3 (done)** — `create <name> --from <src> [--with-credentials]`: create a profile by copying an existing one, sharing the single `copyProfile` routine behind `clone` (credentials omitted unless `--with-credentials`).
73
73
-**M4 (done)** — release CI: `.github/workflows/ci.yml` (build+test matrix) and `release.yml` (tag-triggered). On a `v*` tag it verifies the tag matches `package.json`, builds Node SEA single-file binaries for linux/macOS/Windows (esbuild bundles `build/sea-entry.ts` → CJS, `postject` injects the blob) uploaded to a GitHub Release via the `gh` CLI, then publishes to npm with provenance (`pnpm publish --provenance`, `id-token: write`, `NPM_TOKEN`). Every action is pinned by commit SHA; pnpm comes from corepack; build-only devDeps (`esbuild`, `postject`) are exact-pinned and runtime deps stay zero. See `RELEASING.md`.
74
74
-**M5 (done)** — docs polish (no analytics): self-contained README with a quickstart, a complete command reference matching the CLI help, shell-integration / per-directory `.shannon` docs, an environment-variable note, a troubleshooting/FAQ, and a short `CONTRIBUTING.md` + `SECURITY.md`. No analytics, tracking, or SEO cruft.
75
+
-**M7 (done)** — UX polish: banner gains a title/version/attribution footer; TTY-gated ANSI colour (`src/core/style.ts`, honoring `NO_COLOR`/`FORCE_COLOR`, never emitted to captured/eval'd output); and an interactive `setup [shell]` command (`src/core/integration.ts` for the pure bits) that adds a single `shannon init` line to the shell startup file for the user — or prints just that line to paste — instead of dumping the full snippet. `init` stays the raw eval target.
75
76
-**M6 (done)** — branding + self-update: a low-entropy dot-halftone portrait banner (`src/banner.ts`) on `status`/`help` with terminal Unicode detection and an ASCII fallback (`SHANNON_BANNER` to force); a passive update check (`src/core/updates.ts`) that refreshes a ≤24h npm-registry cache in a detached background process and appends a one-line CTA to ordinary commands, plus an explicit `update`/`upgrade` command. Opt-out and zero-dep (built-in `fetch`); no runtime dependency added.
Copy file name to clipboardExpand all lines: README.md
+15-3Lines changed: 15 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -102,7 +102,8 @@ A bare `shannon` (or `claudep` / `clp`) prints profile status — it never launc
102
102
|`clone <src> <dst> [--with-credentials]`| Copy a profile. Credentials are omitted unless `--with-credentials`. |
103
103
|`delete <name> [--yes]` (`rm`) | Delete a profile and its data. `--yes` (aliases `-y`, `--force`) skips the confirmation prompt. |
104
104
|`status` (`st`) | Show the active and default profile. |
105
-
|`init <bash\|zsh\|fish\|pwsh>`| Print the shell integration snippet for that shell (see below). |
105
+
|`setup [shell]`| Install shell integration interactively — adds one line to your startup file for you, or shows it to paste (see below). |
106
+
|`init <bash\|zsh\|fish\|pwsh>`| Print the raw shell integration snippet for that shell (what `setup`'s one line re-generates at startup). |
106
107
|`update` (`upgrade`) | Check the npm registry for a newer release and print how to upgrade. |
107
108
|`help` (`-h`, `--help`) | Show the command reference. |
108
109
|`--version`| Print the version. |
@@ -120,7 +121,15 @@ A bare `shannon` (or `claudep` / `clp`) prints profile status — it never launc
120
121
121
122
## Shell integration
122
123
123
-
The launcher already resolves the default profile, but two things need a shell function: making `use` switch the *live* shell, and auto-selecting a profile when you `cd` into a project. Add the line for your shell to its startup file:
124
+
The launcher already resolves the default profile, but two things need a shell function: making `use` switch the *live* shell, and auto-selecting a profile when you `cd` into a project.
125
+
126
+
The easiest way is to let Shannon set it up for you:
127
+
128
+
```sh
129
+
shannon setup # detects your shell, offers to add one line to its startup file
130
+
```
131
+
132
+
`setup` is interactive: it either adds the line for you or prints just that line to paste — your call. To do it by hand, add the line for your shell to its startup file:
(`shannon init <shell>` prints the full integration that the one line above re-generates on each shell launch — you don't paste that yourself.)
149
+
139
150
This defines `shannon` / `claudep` / `clp` as thin wrappers around the binary. With it loaded:
140
151
141
152
```sh
@@ -158,6 +169,7 @@ Leaving the directory reverts to the default profile. A manual `shannon use` ove
158
169
-**`CLAUDE_CONFIG_DIR`** — the variable Claude Code reads to find its config directory; setting it is how Shannon selects a profile. An explicit value in your environment **overrides the default profile** for that session, and that is what `status` and `list` report as *active*. `shannon use` (with shell integration) sets it for you.
159
170
-**`SHANNON_AUTO`** — internal state managed by the shell hooks to track which profile was auto-selected from a `.shannon` file. You don't set this yourself.
160
171
-**`SHANNON_BANNER`** — controls the portrait banner shown above `status` and `help` (only when stdout is a terminal — it's suppressed for pipes, scripts, and the shell-integration wrappers). By default Shannon auto-detects whether your terminal supports Unicode and falls back to an ASCII rendering otherwise; set `SHANNON_BANNER=ascii` or `SHANNON_BANNER=unicode` to force one.
172
+
-**`NO_COLOR` / `FORCE_COLOR`** — Shannon colorizes output only when stdout is a terminal; set `NO_COLOR` to force plain output or `FORCE_COLOR` to keep colors when piping. (Colors are never written to captured/eval'd output, so copied text and shell snippets stay clean regardless.)
161
173
-**`SHANNON_NO_UPDATE_CHECK`** — set to any value to disable the update check. Shannon otherwise checks the npm registry at most once a day (in a detached background process, never blocking a command) and appends a one-line notice when a newer release exists; the check sends no identifying data. `NO_UPDATE_NOTIFIER` and `CI` are also honored, and the notice is suppressed when output isn't a terminal.
162
174
163
175
## Profiles
@@ -175,7 +187,7 @@ Shannon launches the real `claude`; it doesn't bundle it. Install [Claude Code](
175
187
Your package manager's global bin directory isn't on `PATH`. Find it with `pnpm bin -g` (or `npm bin -g`) and add it to your shell's `PATH`. With pnpm, `pnpm setup` configures this for you.
176
188
177
189
**`shannon use <name>` seems to do nothing.**
178
-
A child process can't change its parent shell's environment, so on its own `use` only prints the export line for you to run. To make it switch the live shell, load [shell integration](#shell-integration) (`shannon init <shell>`) once. Until then, copy the printed `export …` / `$env:…` line.
190
+
A child process can't change its parent shell's environment, so on its own `use` only prints the export line for you to run. To make it switch the live shell, run `shannon setup` once (see [shell integration](#shell-integration)). Until then, copy the printed `export …` / `$env:…` line.
179
191
180
192
**Migrating from `claude-code-profiles`.**
181
193
Shannon's storage is byte-compatible with the original shell tool (same directory layout, same `.default` file). Your existing profiles just work — there's no migration step. Install Shannon, run `shannon list`, and they'll be there.
0 commit comments