Skip to content

fix: pick single-file targets in interactive mode - #77

Open
Dhirenderchoudhary wants to merge 1 commit into
nrjdalal:mainfrom
Dhirenderchoudhary:fix/interactive-single-file-pick
Open

fix: pick single-file targets in interactive mode#77
Dhirenderchoudhary wants to merge 1 commit into
nrjdalal:mainfrom
Dhirenderchoudhary:fix/interactive-single-file-pick

Conversation

@Dhirenderchoudhary

@Dhirenderchoudhary Dhirenderchoudhary commented Aug 16, 2026

Copy link
Copy Markdown

The bug

gitpick <file-url> -i died before copying anything:

✔ elayadesign/ai-design-skills blob:main skills/landing-page-design/SKILL.md > ~/.agents/skills/landing-page-design/SKILL.md
⠇ Fetching elayadesign/ai-design-skills...
Error: ENOTDIR: not a directory, scandir '/var/folders/.../SKILL.md'

Fixes #75

Interactive mode scopes its walk to config.path and readdirs it unconditionally, so a pick that resolves to a file gets read as a directory.

It isn't only blob: URLs

A tree: pick crashes identically when the path names a file and that's the normal shape on Bitbucket and Codeberg, whose src/<ref>/<path> URLs look the same for files and folders (transform-url.ts types both as tree). Reproduced on codeberg.org/Codeberg/avatars/src/branch/main/README.md and nrjdalal/picksuite/tree/main/file.txt. So the decision is made on the checkout, not on the URL type — one check covers every host.

What changed

  • bin/index.ts: when the picked root isn't a directory there is nothing to browse, so gitpick says so and copies the file the way the plain pick does. --dry-run, the file overwrite guard, --init/--commit, --tree, -q and temp-dir cleanup all behave exactly as they do without -i.
  • renderTree hoisted above the interactive block so both paths share it instead of duplicating the file-target rendering.
  • Two things the new branch surfaced in the same block: -f never worked in remote interactive mode (only -o did, though the warning names both), and the spinner ignored -q/--tree.
  • README.md: one line under Interactive Mode.

Result:

✔ nrjdalal/picksuite blob:main file.txt > out/file.txt
✔ Fetched nrjdalal/picksuite (1 entry)

Note: file.txt is a single file - -i has nothing to browse.
✔ Copied 1 file to out/file.txt

Tests

Six cases in tests/cli.test.ts: blob URL picks the file, tree: URL that resolves to a file, --dry-run copies nothing, refuse-then-overwrite (-o, -f), --tree, -q. All six fail on the unfixed bin/index.ts and pass with it.

-i refuses to start outside a TTY, so the cases run through a small shim that marks stdout as a TTY and hands over to the built CLI. A single-file pick never opens the picker, so nothing reads keys that keeps the tests portable to the Linux/macOS/Windows matrix, unlike allocating a real pty.

  • bun run test: 284 pass, 0 fail
  • oxfmt --check and oxlint clean

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.

Interactive mode throws ENOTDIR for GitHub blob/file URLs

1 participant