Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1c9765b
feat(setup): detect macOS accessibility permissions and guide first-t…
juan294 Mar 16, 2026
f683f6b
feat: implement v1.2.0 features — theme, doctor --fix, per-pane cwd, …
juan294 Mar 16, 2026
70c6d81
refactor: extract helpers for config serialization, dry-run headers, …
juan294 Mar 16, 2026
1933f25
fix: setup.test.ts test infrastructure (#176)
juan294 Mar 16, 2026
7ed0528
chore: package.json metadata + deps (#181)
juan294 Mar 16, 2026
5f35a7e
fix: completions.ts subcommand-specific flags (#178)
juan294 Mar 16, 2026
eeb137c
fix: config.ts path traversal hardening (#179)
juan294 Mar 16, 2026
4006b09
test: coverage gaps in script and tree (#180)
juan294 Mar 16, 2026
88652bf
fix: index.ts UX fixes (#177)
juan294 Mar 16, 2026
1b0642b
fix: launcher/utils/setup refactors (#175)
juan294 Mar 16, 2026
f80991f
Merge branch 'worktree-agent-a612a1ee' into develop
juan294 Mar 16, 2026
e21fe25
Merge branch 'worktree-agent-ac3a87c2' into develop
juan294 Mar 16, 2026
0bb9d9d
Merge branch 'worktree-agent-a5ffcd5c' into develop
juan294 Mar 16, 2026
66b1aab
Merge branch 'worktree-agent-a77ba56a' into develop
juan294 Mar 16, 2026
6c605df
Merge branch 'worktree-agent-a280f71a' into develop
juan294 Mar 16, 2026
f06ced5
Merge branch 'worktree-agent-a5869d25' into develop
juan294 Mar 16, 2026
fbb4368
docs: update pre-launch audit report for v1.2.0
juan294 Mar 16, 2026
ef641d9
Merge branch 'main' into develop
juan294 Mar 16, 2026
59d80e9
fix(doctor): remove window-save-state recommendation (#183)
juan294 Mar 17, 2026
ea94b99
fix: remove broken --theme flag — Ghostty AppleScript API does not su…
juan294 Mar 17, 2026
3e508ef
refactor: add @internal JSDoc tags + cache listStarshipPresets (#186)
juan294 Mar 17, 2026
9a75c63
fix: extract ENV_KEY_RE to shared constant + show config defaults (#184)
juan294 Mar 17, 2026
f3f1916
test: strengthen assertions + cover tree+CWD merge path (#185)
juan294 Mar 17, 2026
10360b6
Merge branch 'worktree-agent-a2fab6c9' into develop
juan294 Mar 17, 2026
1e76eac
Merge branch 'worktree-agent-aebf2dc8' into develop
juan294 Mar 17, 2026
9e99b45
Merge branch 'worktree-agent-a991d9d1' into develop
juan294 Mar 17, 2026
a2e88cd
release: v1.2.1 — remove broken theme flag, doctor fixes, code quality
juan294 Mar 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.2.1] - 2026-03-17

### Removed

- `--theme` flag and `theme` config key — Ghostty's AppleScript API does not support per-surface themes (error -10006). Set themes globally in `~/.config/ghostty/config` instead.
- `window-save-state` from `doctor` recommendations — Ghostty restores split layouts but not pane commands, creating stale splits that conflict with summon's layout management.

### Fixed

- `ENV_KEY_RE` extracted to shared constant in `validation.ts` (was duplicated in index.ts and launcher.ts)
- `summon config` now shows effective defaults when no machine config is set

### Changed

- `@internal` JSDoc tags added to all test-only exports for consistency
- `listStarshipPresets()` results are now cached (avoids repeated shell-outs)
- Branch protection on `main` hardened: `enforce_admins` and `dismiss_stale_reviews` enabled

### Tests

- 958 total tests (was 955 in v1.2.0)
- 8 weak `.toBeTruthy()` assertions replaced with `.toBeTypeOf('string')`
- 4 new tests covering tree layout + project CWD merge path
- 3 new tests for starship preset caching
- 6 new tests for `ENV_KEY_RE` validation

## [1.2.0] - 2026-03-16

### Added
Expand Down Expand Up @@ -377,7 +403,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- CodeQL security scanning
- Dependabot for npm and GitHub Actions

[Unreleased]: https://github.com/juan294/summon/compare/v1.2.0...develop
[Unreleased]: https://github.com/juan294/summon/compare/v1.2.1...develop
[1.2.1]: https://github.com/juan294/summon/compare/v1.2.0...v1.2.1
[1.2.0]: https://github.com/juan294/summon/compare/v1.1.0...v1.2.0
[1.1.0]: https://github.com/juan294/summon/compare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/juan294/summon/compare/v0.8.0...v1.0.0
Expand Down
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ Drop a `.summon` file in your project root to override machine-level config:
layout=minimal
editor=vim
shell=npm run dev
theme=nord
env.PORT=3000
```

Expand Down Expand Up @@ -137,7 +136,6 @@ Config resolution order: **CLI flags > .summon > machine config > preset > defau
| `--auto-resize` | Resize sidebar to match editor-size (default: on) |
| `--no-auto-resize` | Disable auto-resize |
| `--starship-preset <preset>` | Starship prompt preset name (per-workspace) |
| `--theme <name>` | Ghostty theme for workspace |
| `--font-size <n>` | Override font size for workspace panes |
| `--env KEY=VALUE` | Set environment variable (repeatable) |
| `--on-start <cmd>` | Run a command before workspace creation |
Expand All @@ -161,7 +159,6 @@ Config resolution order: **CLI flags > .summon > machine config > preset > defau
| `layout` | | Default layout preset |
| `auto-resize` | `true` | Auto-resize sidebar to match editor-size |
| `starship-preset` | | Starship prompt theme preset (per-workspace) |
| `theme` | | Ghostty theme for workspace |
| `font-size` | | Font size for workspace panes (points) |
| `on-start` | | Command to run before workspace creation |
| `new-window` | `false` | Open workspace in a new Ghostty window |
Expand All @@ -176,7 +173,6 @@ summon set editor vim # use vim as the editor
summon set shell "npm run dev" # run a command in the shell pane
summon set layout minimal # default to minimal preset
summon set starship-preset tokyo-night # per-workspace Starship prompt theme
summon set theme nord # Ghostty theme for workspace
summon set font-size 14 # font size for workspace panes
summon set on-start "npm install" # run before workspace creation
summon set new-window true # always open in a new window
Expand Down
153 changes: 75 additions & 78 deletions docs/agents/pre-launch-report.md
Original file line number Diff line number Diff line change
@@ -1,98 +1,95 @@
# Pre-Launch Audit Report
> Generated on 2026-03-16 | Branch: `develop` | 6 parallel specialists | Pre-v1.2.0
> Generated on 2026-03-17 | Branch: `develop` | 6 parallel specialists | Pre-v1.2.1

## Verdict: CONDITIONAL

No blockers. 5 warnings across QA, Security, and UX. 27 recommendations.
One expected warning (unpushed commit awaiting release). No blockers. All systems green.

## Warnings
## Blockers (must fix before release)
None.

## Warnings
| # | Issue | Severity | Found by | Risk |
|---|-------|----------|----------|------|
| W1 | launcher.ts branch coverage at 79.59% (optsToConfigMap untested) | WARNING | qa-lead | Low |
| W2 | Polling-based test sync in setup.test.ts waitForHandler() | WARNING | qa-lead | Low |
| W3 | setTimeout(0) for keypress simulation in setup tests | WARNING | qa-lead | Low |
| W4 | `summon set env.INVALID` silently accepts invalid env var key names | WARNING | ux-reviewer | Medium |
| W5 | Layout name path traversal prevented by regex only | WARNING | security-reviewer | Low |
| W1 | 1 unpushed commit on `develop` (theme removal hotfix) | medium | devops | Must push before release PR |
| W2 | Duplicated env-var-name regex in index.ts:422 vs launcher.ts ENV_KEY_RE | low | architect, performance-eng | Logic divergence risk |
| W3 | Weak `.toBeTruthy()` assertions in setup.test.ts (8 uses) | low | qa-lead | Won't catch type regressions |
| W4 | launcher.ts branch coverage 91.91% — tree layout + project CWD merge path untested | low | qa-lead | Uncovered runtime path |
| W5 | `on-start` uses `execSync` (shell mode) — by-design but worth noting | low | security-reviewer | Same trust model as Makefile |
| W6 | Branch protection `enforce_admins: false` on main | low | devops | Admins can bypass checks |
| W7 | `--fix` and `--vim` missing from CLI_FLAGS array | low | ux-reviewer | Bash completion gap (zsh OK) |
| W8 | Unicode arrow `→` in index.ts output without fallback | low | ux-reviewer | Cosmetic; Ghostty renders fine |

## Recommendations
| # | Suggestion | Found by |
|---|-----------|----------|
| R1 | Extract ENV_KEY_RE to shared constant in utils.ts or validation.ts | architect, performance-eng |
| R2 | Strengthen `.toBeTruthy()` to `.toBeTypeOf('string')` in setup.test.ts | qa-lead |
| R3 | Add test for tree layout + project CWD merge path (launcher.ts:441-443) | qa-lead |
| R4 | Consider `--yes`/`--no-confirm` flag for CI automation use cases | security-reviewer |
| R5 | Split EDITOR validation on first space to allow `code --wait` | security-reviewer |
| R6 | Document .summon trust model in dedicated README security section | security-reviewer |
| R7 | Mark all test-only exports with consistent `@internal` JSDoc tag | architect |
| R8 | Cache `listStarshipPresets()` result for repeated calls | performance-eng |
| R9 | Enable `enforce_admins` and `dismiss_stale_reviews` on main branch protection | devops |
| R10 | Add `--fix`/`--vim` to CLI_FLAGS for bash completion consistency | ux-reviewer |
| R11 | Show effective defaults in `summon config` when no machine config set | ux-reviewer |

## Detailed Findings

### 1. Quality Assurance (qa-lead) — GREEN
- **930 tests**, 100% pass rate, 12 test files
- **97.26% stmt / 90.29% branch / 98.13% func / 98.19% line** coverage
- All configured thresholds met (95/90/95/95)
- Typecheck: PASS | Lint: PASS

| # | Finding | Severity |
|---|---------|----------|
| W1 | launcher.ts branch coverage 79.59% — optsToConfigMap 28 uncovered branches | WARNING |
| W2 | waitForHandler() polling without assertion on failure | WARNING |
| W3 | setTimeout(0) keypress simulation pattern | WARNING |
| R1 | Add direct unit tests for optsToConfigMap() | RECOMMENDATION |
| R2 | Add assertion in waitForHandler() if handler never captured | RECOMMENDATION |
| R3 | script.ts line 294 uncovered (3+ right-column editors edge case) | RECOMMENDATION |
| R4 | tree.ts line 124 uncovered (parser advance() defensive error) | RECOMMENDATION |
- **945 tests**, all passing, 0 skipped
- **Typecheck:** clean, **Lint:** clean
- **Coverage:** 98.98% statements, 94.12% branches, 98.60% functions, 99.22% lines
- Critical files all at 98-100% coverage
- Uncovered: setup.ts SIGINT handler (interactive-only), tree.ts defensive throw, launcher.ts tree+CWD merge branch
- 8 weak `.toBeTruthy()` assertions in setup.test.ts

### 2. Security (security-reviewer) — GREEN
- Zero vulnerable dependencies, zero runtime deps
- No hardcoded secrets
- Command injection guarded (execFileSync arrays, SAFE_COMMAND_RE)
- AppleScript injection prevented (escapeAppleScript on all user input)
- File permissions correct (0o600/0o700)

| # | Finding | Severity |
|---|---------|----------|
| W5 | Layout name path traversal prevented by regex only (no secondary resolve+prefix check) | WARNING |
| R5 | export command writes .summon with 0o644 — appropriate but document distinction | RECOMMENDATION |
| R6 | Env var values not checked by confirmDangerousCommands (properly escaped) | RECOMMENDATION |

### 3. Infrastructure (devops) — GREEN
- Build succeeds, CI green (4/4 completed runs)
- Node 18/20/22 matrix, CodeQL, dependency review
- Working tree clean, npm pack clean

| # | Finding | Severity |
|---|---------|----------|
| R7 | Add `main` field to package.json for legacy tooling compat | RECOMMENDATION |
| R8 | Consider `publishConfig: {"access": "public"}` | RECOMMENDATION |
- `pnpm audit`: no known vulnerabilities, zero runtime deps
- No hardcoded secrets found
- osascript execution uses stdin (`execFileSync` with `input`), not shell args — safe
- AppleScript escaping (`escapeAppleScript`, `shellQuote`) correctly implemented
- `confirmDangerousCommands` catches shell metacharacters in `.summon` files
- `SAFE_COMMAND_RE`, `SAFE_SHELL_RE`, `ENV_KEY_RE` properly guard all injection vectors
- `layoutPath()` prevents path traversal with resolve+prefix check
- File permissions: config dir 0o700, files 0o600 — correct
- All dependency licenses permissive (MIT, Apache-2.0, ISC)

### 3. Infrastructure (devops) — YELLOW
- Build succeeds (14ms, 75KB total output)
- CI: all recent runs green on develop
- CI config: Node [18, 20, 22] matrix, CodeQL, dependency review — solid
- Package metadata: correct (name, version, bin, files, engines, os, license)
- Env vars: full parity between documented (5) and used (5)
- **1 unpushed commit** (theme removal) — expected, will push with release
- Branch protection on main: required checks + 1 review, but `enforce_admins: false`

### 4. Architecture (architect) — GREEN
- Typecheck passes, no circular deps, no dead exports

| # | Finding | Severity |
|---|---------|----------|
| R9 | Remove trivial resolveCommand wrapper in launcher.ts | RECOMMENDATION |
| R10 | Extract shared isGhosttyInstalled() helper | RECOMMENDATION |
| R11 | Update typescript-eslint 8.57.0 → 8.57.1 | RECOMMENDATION |
| R12 | Consider splitting setup.ts (~1700 lines) | RECOMMENDATION |
- Typecheck: clean
- Dependencies: all up to date
- No circular dependencies — clean DAG
- No dead code (test-only exports properly annotated with `@internal`)
- Module boundaries clean: layout planning → script generation → execution
- Dynamic imports for heavy modules (setup, completions, keybindings)
- 1 duplicated regex (ENV_KEY_RE) — minor DRY violation

### 5. Performance (performance-eng) — GREEN
- Total build: ~75 KB across 12 chunks
- Largest: index.js (35.37 KB) — under 50 KB threshold
- Code splitting effective, no hot-path bloat

| # | Finding | Severity |
|---|---------|----------|
| R13 | Test-only exports inflate bundle marginally (~200 bytes) | RECOMMENDATION |
| R14 | setup.ts exports ~50 symbols, most test-only | RECOMMENDATION |
| R15 | doctor subcommand could be split out (<2 KB savings) | RECOMMENDATION |
| R16 | Monitor index.js size as features grow | RECOMMENDATION |
- Build: 14ms, 75KB total (12 chunks, code-split)
- Entry chunk: 35KB, setup lazy-loaded (22KB), completions lazy-loaded (6KB)
- All regexes compiled at module level (constants)
- String building uses array push + join — optimal
- Sync file I/O appropriate for one-shot CLI
- `resolveCommand` results cached in launcher
- Starship path cached, config dir ensured once
- No anti-patterns found

### 6. UX/Accessibility (ux-reviewer) — GREEN
- Help text comprehensive, error messages actionable
- NO_COLOR respected, non-TTY handled

| # | Finding | Severity |
|---|---------|----------|
| W4 | `summon set env.*` accepts invalid env var key names | WARNING |
| R17 | freeze usage `<layout-name>` vs help `<name>` inconsistent | RECOMMENDATION |
| R18 | btop preset description hard-codes "lazygit sidebar" | RECOMMENDATION |
| R19 | layoutNotFoundOrExit lacks `Error:` prefix | RECOMMENDATION |
| R20 | `summon doctor` exits 0 even when issues found | RECOMMENDATION |
| R21 | `summon export` drops env.* keys | RECOMMENDATION |
| R22 | Shell completions don't complete `doctor --fix` / `keybindings --vim` | RECOMMENDATION |
| R23 | `--fix`/`--vim` are global parse options but subcommand-specific | RECOMMENDATION |
| R24 | config unknown key message doesn't suggest removal | RECOMMENDATION |
| R25 | export header lacks timestamp | RECOMMENDATION |
| R26 | Ctrl+C exits with code 0 instead of 130 | RECOMMENDATION |
| R27 | Nested workspace warning "too scary" could be clearer | RECOMMENDATION |
- Help text: all 13 subcommands documented, consistent formatting, practical examples
- Error messages: consistent `Error: <description>` + actionable guidance pattern
- Exit codes: 0 (success), 1 (error), 2 (doctor issues), 130 (Ctrl+C) — all correct
- Setup wizard: handles no-Ghostty, Ctrl+C, invalid input, non-TTY, decline-and-retry
- NO_COLOR support via `useColor` flag, all ANSI output goes through `wrap()`
- True color detection with graceful fallback
- Screen reader compatible (no emoji-only messages)
- Tab completion: zsh fully working, bash minor gap for subcommand-specific flags
96 changes: 36 additions & 60 deletions docs/agents/remediation-report.md
Original file line number Diff line number Diff line change
@@ -1,73 +1,49 @@
# Remediation Report
> Generated on 2026-03-16 | Branch: `develop` | 24 findings resolved
> Generated on 2026-03-17 | Branch: `develop` | 4 issues resolved
>
> Pre-launch report: `docs/agents/pre-launch-report.md`

## Summary
- Findings processed: 32 (5 warnings + 27 recommendations)
- Issues created: 7 (#175-#181)
- Issues resolved: 7
- Tests added: ~25
- Files modified: 14
- CI status: PASSING
- Findings processed: 19 (8 warnings + 11 recommendations)
- Issues created: 4
- Issues resolved: 4
- Tests added: 13 (6 ENV_KEY_RE + 4 tree+CWD merge + 3 starship caching)
- Files modified: 12
- CI status: IN PROGRESS (pending)

## Issues Resolved

| # | Issue | Domain | Severity | Tests Added | Status |
|---|-------|--------|----------|-------------|--------|
| #175 | launcher/utils/setup refactors | architecture, qa | WARNING | 10 | Closed |
| #176 | setup.test.ts test infrastructure | qa | WARNING | 0 (infra fix) | Closed |
| #177 | index.ts UX fixes | ux | WARNING | 7 | Closed |
| #178 | completions.ts subcommand flags | ux | RECOMMENDATION | 4 | Closed |
| #179 | config.ts path traversal hardening | security | WARNING | 2 | Closed |
| #180 | test coverage gaps (script + tree) | qa | RECOMMENDATION | 2 | Closed |
| #181 | package.json metadata + deps | devops | RECOMMENDATION | 0 (config) | Closed |

## Findings Addressed (24)

| Finding | Work Unit | Fix |
|---------|-----------|-----|
| W1 | #175 | optsToConfigMap unit tests added |
| W2 | #176 | waitForHandler assertion on failure |
| W3 | #176 | setTimeout(0) patterns documented |
| W4 | #177 | env var key validation in `summon set` |
| W5 | #179 | layoutPath helper with resolve+prefix check |
| R1 | #175 | optsToConfigMap branch coverage |
| R2 | #176 | waitForHandler throw on timeout |
| R3 | #180 | 4-pane secondary editor test |
| R4 | #180 | parser truncated input test |
| R7 | #181 | package.json main field added |
| R8 | #181 | publishConfig access: public |
| R9 | #175 | Removed trivial resolveCommand wrapper |
| R10 | #175 | Extracted isGhosttyInstalled to utils.ts |
| R11 | #181 | typescript-eslint updated to 8.57.1 |
| R17 | #177 | freeze usage consistency |
| R18 | #177 | btop description fixed |
| R19 | #177 | layoutNotFoundOrExit Error: prefix |
| R20 | #177 | doctor exit code 2 on issues |
| R21 | #177 | export includes env.* keys |
| R22 | #178 | doctor --fix / keybindings --vim completions |
| R24 | #177 | config unknown key removal hint |
| R25 | #177 | export header timestamp |
| R26 | #175 | Ctrl+C exit code 130 |
| R27 | #175 | Nested warning "messy" wording |

## Informational (no code change needed)
- R5: export 0o644 permissions appropriate for project files
- R6: env var values properly escaped, not exploitable

## Deferred Items
- R12: Split setup.ts (~1700 lines) — major refactor, separate task
- R13/R14: Test-only exports (~200 bytes) — cosmetic
- R15: Doctor subcommand split — marginal savings (<2 KB)
- R16: Monitor index.js size — informational
- R23: --fix/--vim global parse scope — parseArgs architectural limitation
| #184 | Extract ENV_KEY_RE + show config defaults | architecture, ux | low | 6 | Closed |
| #185 | Strengthen test assertions + cover tree+CWD merge | qa | low | 4 | Closed |
| #186 | @internal JSDoc tags + cache listStarshipPresets | architecture, performance | low | 3 | Closed |
| #187 | Harden branch protection on main | devops | low | 0 (config) | Closed |

## Findings Disposition
| Finding | Action | Details |
|---------|--------|---------|
| W1 | Resolved | Pushed with release |
| W2/R1 | Fixed (#184) | ENV_KEY_RE extracted to validation.ts |
| W3/R2 | Fixed (#185) | 8x .toBeTruthy() → .toBeTypeOf('string') |
| W4/R3 | Fixed (#185) | 4 tests for tree+CWD merge path |
| W5 | Skipped | By design (on-start uses shell intentionally) |
| W6/R9 | Fixed (#187) | enforce_admins + dismiss_stale_reviews enabled |
| W7/R10 | Skipped | False positive (adding to CLI_FLAGS breaks completions; subcommand-specific handling is correct) |
| W8 | Skipped | Cosmetic (Ghostty renders Unicode fine) |
| R4 | Skipped | Feature request (--yes flag for CI) — future release |
| R5 | Skipped | Security design decision (strict EDITOR validation) |
| R6 | Skipped | Already implemented (README Trust Model section exists) |
| R7 | Fixed (#186) | @internal tags added to GHOSTTY_PATHS, layoutPath |
| R8 | Fixed (#186) | listStarshipPresets() now cached |
| R11 | Fixed (#184) | `summon config` shows effective defaults |

## Final Verification
- [x] All 955 tests passing
- [x] All tests passing (958)
- [x] Typecheck clean
- [x] Lint clean
- [x] Build succeeds (75 KB total)
- [x] CI green
- [x] All worktrees removed
- [x] All issues closed
- [x] Build succeeds (75KB, 14ms)
- [ ] CI green (pending)
- [x] /simplify final pass complete

## Remaining Items
None — all actionable findings resolved. Skipped items are by-design, false positives, or future feature requests.
Loading
Loading