Skip to content

Improve novice UX: help, errors, colors, and actionable hints#27

Merged
sjquant merged 8 commits into
mainfrom
claude/improve-novice-ux-viEEY
Apr 30, 2026
Merged

Improve novice UX: help, errors, colors, and actionable hints#27
sjquant merged 8 commits into
mainfrom
claude/improve-novice-ux-viEEY

Conversation

@sjquant

@sjquant sjquant commented Apr 29, 2026

Copy link
Copy Markdown
Owner

Summary

Across-the-board novice UX improvements to the CLI. All changes follow established patterns from well-known CLIs (gh, cargo, npm).

Help

  • skul add --help (and any skul <cmd> --help) now returns command-specific help text instead of erroring
  • CliParseResult help variant carries an optional command field so the right subcommand help is returned end-to-end

Typo correction

  • Unknown commands now suggest the closest match via Levenshtein distance
    e.g. skul adddUnknown command: "addd", did you mean "add"?

Colorized output

  • Added picocolors (zero deps, 1.4 KB): bold headers, cyan bundle names, green for success actions (Applied / Updated / Removed / Reset), yellow for DRY RUN: prefix, dim for hints and Cloned lines
  • Colors are disabled automatically when stdout is not a TTY, when NO_COLOR is set, or when SKUL_NO_TUI=1 is active — --json paths return before any color calls and are unaffected

Actionable error and empty-state messages

Every dead-end message now includes a next-step hint:

Situation Before After
No bundles cached, lookup fails Bundle not found: foo Bundle not found: foo + how to add one
skul list with empty library No cached bundles found. + Add one with: skul add …
skul status unconfigured Configured: no + Run "skul add <bundle>" to get started
skul remove unknown bundle Bundle not found in active set: foo + lists what IS configured
skul check with updates available bare status lines + Run "skul update" to apply available updates
skul update all local-only All selected bundles are already up to date No remote-backed bundles to update (foo is local-only)
No git repo skul <cmd> requires a Git repository + Run "git init" to initialize one
No bundles configured No bundles configured for this repository + Run "skul add <bundle>" to add one

Conflict resolution prompts

Labels rewritten to describe consequences rather than actions:

  • "Rename incoming file""Save with a different name (you choose)"
  • "Apply prefix (…)""Add a prefix to avoid the conflict (saves as …)"
  • "Skip file""Skip this file (won't be written)"

Test plan

  • skul add --help prints add-command help; skul --help prints global help
  • Typo near a known command shows suggestion; distant input shows none
  • Colors visible in a real terminal; absent when piped or NO_COLOR=1
  • skul list with no bundles shows the add hint
  • skul remove nonexistent when bundles exist shows configured bundle names
  • skul update with only local-only bundles shows specific message
  • skul check with updates available appends the update hint
  • All 279 tests pass

https://claude.ai/code/session_01MHwWwPGhz5gQo4EWJzoAW7

@sjquant sjquant changed the title Improve novice UX: per-command help, getting-started section, empty-library guidance Improve novice UX: help, errors, colors, and actionable hints Apr 30, 2026
claude added 8 commits April 30, 2026 14:54
…ibrary guidance

- `skul add --help` (and any `skul <cmd> --help`) now returns command-specific
  help text showing the command's arguments and options, instead of erroring
- Global `skul --help` appends a Getting Started workflow and copy-paste examples
- When no bundles are cached and a bundle lookup fails, the error message now
  tells the user exactly how to add their first bundle from a Git source

https://claude.ai/code/session_01MHwWwPGhz5gQo4EWJzoAW7
- Unknown commands now suggest the closest match via Levenshtein distance
  (e.g. "skul sts" → Did you mean "status"?)
- skul list with no cached bundles now shows how to add one
- All dead-end messages (no bundles configured, bundle not found in active set,
  requires a Git repository) now include a follow-up action hint

https://claude.ai/code/session_01MHwWwPGhz5gQo4EWJzoAW7
- Add picocolors: bold headers, cyan bundle names, green for success
  actions (Applied/Updated/Removed/Reset), yellow for DRY RUN prefix,
  dim for hints and Cloned lines
- skul status: add "Run skul add <bundle> to get started" hint when
  nothing is configured; color Materialized and Git Exclude fields
- skul remove: when bundle not found, show what IS configured instead
  of a generic "run skul status" pointer
- skul update: distinguish "all local-only" from "all up to date" with
  a specific message naming the local-only bundles
- Conflict resolution prompts: replace terse labels with consequence-
  oriented descriptions ("Save with a different name", "Add a prefix
  to avoid the conflict", "Skip this file")

https://claude.ai/code/session_01MHwWwPGhz5gQo4EWJzoAW7
picocolors already disables colors when stdout is not a TTY or NO_COLOR
is set. Also disable when SKUL_NO_TUI=1 since that signals an agent or
scripting context where ANSI codes are noise.

JSON output paths were already safe — they return before any pc.* calls.

https://claude.ai/code/session_01MHwWwPGhz5gQo4EWJzoAW7
When any bundle reports update-available, append:
  Run "skul update" to apply available updates.

Also color bundle names cyan in check output, consistent with status.

https://claude.ai/code/session_01MHwWwPGhz5gQo4EWJzoAW7
- Move const pc after all imports (was incorrectly mid-import block)
- Make pc a Proxy so isHeadlessMode() is evaluated lazily at call time
  rather than once at module load, fixing potential stale state in tests
- Remove redundant localOnly.length > 0 guard (=== entries.length implies it)
- Fix did-you-mean punctuation: Unknown command: "x", did you mean "y"?
- Remove trailing periods added to new messages to match existing convention
- Add writeBundleManifest/writeBundleFile helpers that accept undefined source
- Add 5 new tests: per-command --help routing, typo suggestion (present and
  absent), local-only update message, remove hint listing configured bundles

https://claude.ai/code/session_01MHwWwPGhz5gQo4EWJzoAW7
…t helper

- Remove trailing period from "Bundle not found in active set" hint in
  selectDesiredEntries to match the no-period convention across all messages
- Remove writeBundleManifest from cli.test.ts — it was added but all callers
  were switched to writeManifest before merging, leaving it unused

https://claude.ai/code/session_01MHwWwPGhz5gQo4EWJzoAW7
@sjquant sjquant force-pushed the claude/improve-novice-ux-viEEY branch from a4e65b9 to a09693a Compare April 30, 2026 16:11
@sjquant sjquant merged commit 851dc01 into main Apr 30, 2026
@sjquant sjquant deleted the claude/improve-novice-ux-viEEY branch May 3, 2026 08:10
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.

2 participants