Skip to content

Latest commit

 

History

History
115 lines (85 loc) · 6.18 KB

File metadata and controls

115 lines (85 loc) · 6.18 KB

glance — development notes

What is this?

LLM-optimized output summarizer. Pipe command output in, get token-efficient head/tail + regex-matched lines, plus an ID to drill deeper.

Design choices

  • POSIX sh, single file, works everywhere
  • Storage in XDG cache dir
  • All matchers OR together, head/tail always shown
  • Built-in presets hardcoded, user presets in config file

Progress

  • Created folder structure
  • Implemented full glance script (~350 lines POSIX sh)
  • All features: pipe mode, head/tail, -n, -f, -p, --no-store
  • Subcommands: show (full, --lines, --filter, --around), list, clean, presets, help
  • 47/47 integration tests passing
  • README.md report

Learnings

  • printf '--- ...' fails in some shells because format string starting with - gets parsed as option. Use printf '%s\n' "--- ..." instead.
  • wc -l counts newlines, so printf '%s' "text" (no trailing newline) gives count off by one. Always use printf '%s\n' when piping to wc -l.
  • POSIX sh has no arrays — used newline-separated strings with IFS manipulation for built-in presets.
  • grep -E doesn't support (?i) for case-insensitive. Used grep -iE instead.
  • Cross-platform stat for mtime: try GNU stat -c %Y first, then macOS stat -f %m, then fallback.

Issues found (subagent review, 2026-02-19)

Three subagents reviewed the project: code reviewer, new-user tester, agent needle-in-haystack.

Critical

  1. O(n²) sed loop — fixed. Replaced per-line sed -n Np with single-pass awk in do_pipe and sed range + awk in do_show --around.
  2. wc -l undercounts — fixed. Replaced wc -l with awk END { print NR } which counts records regardless of trailing newline.
  3. No -n validation — fixed. Reject non-numeric values before processing input.
  4. timing preset too broad — fixed. Removed the preset entirely; users can add their own via glance presets add.

Major

  1. [-] Partial ID matching missing — cancelled. Full IDs required by design. Updated help and README examples to use full IDs.
  2. [-] No gap indicator — cancelled. Line numbers make gaps obvious; adding ... wastes tokens, counter to design goals.

Minor

  1. "1 lines" grammar — fixed. Added plural_lines helper for singular/plural in headers.
  2. [-] Help examples use short IDs — fixed alongside #5, examples now use full IDs.
  3. [-] TOCTOU race — cancelled. Timestamp + 8-char random hex makes collisions near-impossible. Removed the unnecessary retry loop.
  4. No validation on --lines range format — fixed. Reject non-numeric values before passing to sed.

Unified sed-style preset format (2026-02-20)

Replaced pipe-delimited built-in and tab-delimited user preset formats with sed-style format where first char is delimiter. Added parse_preset_line helper, auto-delimiter selection, -d flag.

Test & feature gaps to address (TDD)

Test gaps (already passing, just needed tests)

  1. Comments and blank lines preserved through add/remove
  2. Preset update (re-add same name) replaces old entry
  3. Unknown preset with -p produces error
  4. presets add with missing args shows usage
  5. clean --all removes user presets
  6. --around near boundaries (line 1, last line)
  7. --lines and --filter long-form flags in pipe mode
  8. Description containing delimiter round-trips correctly

Feature fixes (needed code changes, TDD red-green)

  1. -n 0 should error — added 0 to rejection case pattern
  2. Missing value for -f/-p — added [ $# -ge 2 ] guards
  3. Preset name validation — added alphanumeric+hyphen+underscore check

82/82 tests passing.

Subagent review (2026-02-20)

Six agents reviewed the code: bug hunter, general reviewer, conciseness, test coverage, adversarial fuzzer, docs audit. Deduplicated findings below.

Bugs

  1. -d with delimiter present in regex silently corrupts — fixed. Added validation rejecting delimiter if present in regex.
  2. Preset names starting with - conflict with flags — fixed. Reject names starting with -.
  3. -f patterns starting with - passed as grep flags — fixed. Added -- before user patterns in grep calls.
  4. --around no validation on center/context args — fixed. Added numeric validation for both args.
  5. [-] --lines in show accepts single number — skipped. Low priority, harmless behavior.

Security

  1. Path traversal in glance show — fixed. Validate capture ID rejects / and ...

Docs

  1. Show flags mutually exclusive — fixed. Rewrote do_show to OR all flags together, matching pipe mode behavior.
  2. Case-insensitive matching undocumented — fixed. Added note to help text.
  3. Hardcoded ~/.config in glance help presets — fixed. Uses dynamic $GLANCE_CONFIG path.

Conciseness

  1. Filter accumulation verbose — fixed. Used ${var:+|} idiom, saved 8 lines.
  2. [-] Range-building in do_pipe — skipped. Already shorter after refactors; shell loops are clear enough.
  3. [-] Trap updated 3 times — already resolved. Only one trap after refactors.
  4. [-] Trivial helpers could inline — skipped. Names communicate intent, used in multiple places.

Missing tests

  1. [-] Help output — added then dropped. Smoke tests were too weak to be useful.
  2. Invalid regex — added test. awk errors on invalid regex, test confirms.
  3. Age formatting boundaries — added 7 boundary tests (0s, 59s, 60s, 3599s, 3600s, 86399s, 86400s).
  4. No subcommand for presets — added test. Confirms usage message.
  5. Delimiter exhaustion — added test. Confirms error when all candidates used.

Additional fixes

  • Built-in presets used \s — awk doesn't support Perl-style \s. Changed to POSIX [[:space:]].
  • Help text hardcoded preset list — now prints dynamically from BUILTIN_PRESETS.
  • Displaced format_age comment — moved to correct location.
  • Shared print_matched_lines function — unified pipe and show into single-pass awk.
  • Summary moved from header to footer — enables single-pass output.

109/109 tests passing.