mirror of
https://github.com/Fission-AI/OpenSpec.git
synced 2026-10-02 05:24:34 +08:00
* fix(archive): stop non-TTY confirm prompts from writing ANSI escapes to stdout `openspec archive` asks up to three yes/no questions through @inquirer's `confirm`, which renders by writing ANSI cursor-movement escape sequences — and emits them even when stdout is not a TTY. When archive runs with its output captured to a file or pipe (an agent's background task, CI), those escapes are noise, and in some non-TTY hosts the render loop never settles and repeats `ESC[NNG` moves until the disk fills (reporter hit 19.8 GB). Add `confirmPrompt` in interactive.ts: a real terminal (stdin AND stdout TTY) still gets @inquirer's rich prompt; every other case reads one plain line via node:readline with `terminal:false`, emitting no escapes. Parsing mirrors @inquirer/confirm exactly (prefix match on y/yes and n/no, else the default), and an unreadable stdin rejects with an ExitPromptError-shaped error so the existing #1479 "rerun with --yes" guidance is unchanged. archive's confirmOrBlock now calls confirmPrompt. Closes #1526 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(interactive): cover Windows CRLF and drained-stdin paths; doc note Adds two regression tests surfaced by adversarial review of the #1526 fix: - Windows CRLF piped input (`y\r\n`) parses as a clean yes with no ANSI — the reporter's platform, previously untested (all inputs used `\n`). - A second prompt after stdin was already drained blocks with an ExitPromptError instead of hanging, exercising the readableEnded guard. Also documents in troubleshooting.md that a redirected/agent archive run that pipes an answer no longer writes terminal escape codes into the capture. Refs #1526 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(interactive): align non-interactive classification and handle readline errors Addresses two review findings on the #1526 confirm-prompt fix: - confirmPrompt drops to the plain reader whenever either stream is not a TTY, but isNonInteractivePromptError only checked stdin. A stdin-TTY / stdout-redirected run that hit EOF leaked the raw ExitPromptError instead of the #1479 "rerun with --yes" guidance. Classification now also counts a redirected stdout, matching how the prompt mode is chosen. (isInteractive, used broadly elsewhere, is left untouched.) - readYesNo never listened for the readline/input 'error' event, so a stdin error would hang the promise (and go unhandled). It now settles with the underlying fault, guarded so the promise resolves or rejects exactly once. Tests: TTY-stdin/redirected-stdout EOF is classified non-interactive; an erroring input stream rejects instead of hanging; the archive usable-terminal test now models a full terminal (both streams TTY). Refs #1526 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(archive): gate the change picker on a TTY and tidy the reader Follow-ups from a second review round: - selectChange (the no-argument change picker) called @inquirer's `select` unconditionally. `select` writes ANSI escapes to stdout even when redirected — the same #1526 mechanism the confirm prompts were fixed for — so `openspec archive > log.txt` with no change name still spewed cursor moves into the capture before blocking. Refuse before rendering when either stream is not a TTY, with the same "pass a change name / --yes" guidance the caught ExitPromptError already gives. A new test asserts the picker is never reached in a non-terminal run. - readYesNo now removes its input-stream 'error' listener on every settle path (it lives on the long-lived process.stdin) and closes the readline interface on error too, so nothing accumulates across archive's sequential prompts. - troubleshooting.md now notes the picker also stays clean. Refs #1526 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(changeset): add patch changeset for the archive non-TTY fix (#1526) User-facing patch note for the archive ANSI/disk-fill fix. Also drops an unnecessary optional-chain on the non-nullable readline handle in readYesNo (the listener is only attached after the interface exists). Refs #1526 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Changesets
This directory is managed by Changesets.
Quick Start
pnpm changeset
Follow the prompts to select version bump type and describe your changes.
Workflow
- Choose the release path: Maintainers decide whether a PR follows the normal release cadence or gets dedicated release tracking.
- Add dedicated release tracking: When a maintainer asks for a changeset, run
pnpm changesetlocally before or after your PR. - Version PR: CI opens/updates a "Version Packages" PR when changesets merge to main.
- Release: Merging the Version PR triggers npm publish and GitHub Release.
Note: The default path is the normal release cadence. Add a changeset when a maintainer or release owner wants dedicated release notes and version tracking for the PR. Versioning (
changeset version) and publishing happen automatically in CI.
Template
Use this structure for your changeset content:
---
"@fission-ai/openspec": patch
---
### New Features
- **Feature name** — What users can now do
### Bug Fixes
- Fixed issue where X happened when Y
### Breaking Changes
- `oldMethod()` has been removed, use `newMethod()` instead
### Deprecations
- `legacyOption` is deprecated and will be removed in v2.0
### Other
- Internal refactoring of X for better performance
Include only the sections relevant to your change.
Version Bump Guide
| Type | When to use | Example |
|---|---|---|
patch |
Release-tracked bug fixes, small improvements | Fixed crash when config missing |
minor |
New features, non-breaking additions | Added --verbose flag |
major |
Breaking changes, removed features | Renamed init to setup |
When to Create a Changeset
Use dedicated release tracking for:
- New features or commands selected for release
- Notable bug fixes or hotfixes requested by a maintainer/release owner
- Breaking changes or deprecations
- Performance improvements users would notice and that are planned for release
Use the normal release cadence for:
- Routine bug fixes that fit the normal release cadence
- Documentation-only changes
- Test additions/fixes
- Internal refactoring that preserves user behavior
- CI/tooling changes
Writing Good Descriptions
Do: Write for users, not developers
- **Shell completions** — Tab completion now available for Bash, Fish, and PowerShell
Don't: Write implementation details
- Added ShellCompletionGenerator class with Bash/Fish/PowerShell subclasses
Do: Explain the impact
- Fixed config loading to respect `XDG_CONFIG_HOME` on Linux
Don't: Just reference the fix
- Fixed #123