* chore(deps): bump dependencies (combined dependabot updates)
Combines the safe dependabot dependency bumps into a single change:
- @modelcontextprotocol/sdk 1.25.2 -> 1.29.0 (mcp)
- undici 6.26.0 -> 8.3.0 (mcp)
- zod 4.3.5 -> 4.4.3 (mcp, tools-ai-sdk)
- commander 13.1.0 -> 15.0.0 (cli)
- ora 9.0.0 -> 9.4.0 (cli)
- dotenv 17.2.3 -> 17.4.2 (sdk, tools-ai-sdk, pi)
- @earendil-works/pi-coding-agent 0.75.5 -> 0.78.0 (pi)
eslint 9 -> 10 (#2703) is excluded: it is incompatible with the
pinned typescript-eslint v8 and breaks lint.
Verified: build, typecheck, lint, and tests pass.
* chore: add changesets for runtime dependency bumps
* fix(deps): pin undici to 7.x for Node 20 compatibility
undici 8 requires Node >=22.19.0 (it calls worker_threads.markAsUncloneable
unconditionally at module load), but CI and the release pipeline run Node 20,
which crashed the mcp test suite with 'markAsUncloneable is not a function'.
undici 7.27.0 guards that call and supports Node >=20.18.1.
* feat(cli): OAuth 2.0 device authorization flow
Adds RFC 8628 device-code login for headless / remote hosts (SSH,
Codespaces, Docker, CI) where the existing localhost-callback flow
can't work — the browser opens on the user's laptop while the
callback listener runs on the remote host, so the redirect target
is unreachable.
Device flow prints a verification URL and short code, then polls the
new /api/oauth/device/token endpoint. The user visits the URL on any
device, signs in, and approves; the CLI receives the same ctx7sk- API
key it would have gotten from the legacy flow.
- shouldUseDeviceFlow() auto-detects via SSH_CONNECTION /
SSH_CLIENT / SSH_TTY and missing $DISPLAY on Linux.
- ctx7 login --device forces it. ctx7 setup picks it up
automatically when resolveCliAuth needs to authenticate.
- pollDeviceToken returns a "transient" status for network errors
and 5xx responses so a flaky backend or Upstash blip doesn't end
the session — keeps polling until the device_code TTL elapses.
* polish(cli): boxed device-code prompt, Press-Enter, whoami success line
Tightens up the device-flow UX so it matches the patterns from gh /
stripe / wrangler:
- Wrap the user_code + verification URL in a boxen rounded box with
a title, gray border, and the code as the visual headline (green
bold, indented on its own line).
- Add a "Press Enter to open the browser, or Ctrl-C to quit..."
confirmation step in TTY mode so the user can read the code before
the browser steals focus. Skipped under --no-browser or non-TTY.
- Replace the generic "Login successful!" line with
"Logged in as <email> (<team>)" by fetching /api/dashboard/whoami
with the freshly minted token. Falls back to the old text if the
call fails.
- Tighten the mockShouldUseDeviceFlow signature in the test mock so
the spread-into-mock pattern typechecks.
No behavior change to the localhost-callback flow.
* test(cli): cover shouldUseDeviceFlow + start/poll + performDeviceLogin
auth-utils: SSH/$DISPLAY heuristics for shouldUseDeviceFlow; the
form-encoded start-device-authorization request shape and error
propagation; pollDeviceToken status mapping for each RFC 8628 code,
5xx -> transient, network error -> transient, and unknown 4xx ->
throw.
auth-commands: performDeviceLogin happy path (approved -> saveTokens
called), denied/expired return null and don't save, transient errors
keep polling instead of bailing, slow_down bumps the interval
(verified with fake timers), startDeviceAuthorization throwing exits
without polling, browser-open behavior under openBrowser=true/false.
Also covers the performLogin selector: forceDevice=true and
shouldUseDeviceFlow=true both route through performDeviceLogin
without hitting the localhost callback path.
28 new tests; suite is 235/235.
* docs(cli): tighten device-flow comments
Drop restatement; keep only WHY-bearing notes.
* fix(cli): default poll interval to 5s per RFC 8628 §3.2
The CLI was treating `interval` as required and would NaN-crash if
a future server omitted it. Spec requires clients to default to 5
when absent.
DeviceAuthorizationResponse.interval is now optional, and
performDeviceLogin uses DEFAULT_DEVICE_POLL_INTERVAL_SECONDS (5) as
the fallback. Test covers the missing-interval path.
* fix(cli): rfc 8628 spec gaps — backoff, hostname, bare verification_uri
Three small spec-compliance fixes from the §3.5 / §3.3 / §5.4 audit:
- §3.5: poll loop now bumps intervalMs by 5s on `transient` results
(network errors and 5xx) — the RFC requires unilateral backoff on
connection timeouts, and mirroring the slow_down handler is the
simplest correct response.
- §3.3: the boxed prompt now prints the bare verification_uri
alongside verification_uri_complete so screen readers / paper /
another device can still type the short form.
- §5.4: startDeviceAuthorization sends `os.hostname()` so the server
can show it on the verification page; the user can confirm the
device they're authorizing matches the one running the CLI.
Transient-backoff test rewritten with fake timers (the new +5s wait
made the old real-timer assertion blow past the 5s default timeout).
* fix(cli): declare @inquirer/core as direct dependency
selectOrInput.ts imports from @inquirer/core directly, but the package
was only resolvable as a transitive of @inquirer/prompts. Under pnpm's
isolated linker this fails with ERR_MODULE_NOT_FOUND at startup.
Fixes#2651
* chore: add changeset
* fix(cli): add token refresh support and centralize auth constants
Expired OAuth tokens are now automatically refreshed via getValidAccessToken()
instead of silently failing. CLI_CLIENT_ID moved to constants.ts to avoid
duplication across auth.ts and setup.ts.
* refactor(cli): internalize baseUrl and clientId in refreshAccessToken
Make refreshAccessToken a private function that resolves getBaseUrl()
and CLI_CLIENT_ID internally instead of requiring them as parameters.
* test(cli): add unit tests for auth utilities and commands
Add comprehensive vitest test suite covering OAuth PKCE flow, token
persistence, token refresh, and CLI auth commands (login/logout/whoami).
* chore: add changeset for CLI auth improvements
* refactor: move CLI auth tests to src/__tests__/
Move auth test files from colocated __tests__ directories to a
centralized src/__tests__/ directory, adjusting mock import paths
accordingly.
* feat: add oauth 2.0 support with login,whoami and logout commands
* ci: lockfile
* fix: address security and port issues in OAuth flow
- Fix XSS vulnerability by escaping HTML in error page messages
- Change callback port from 9876 to 52417 (high ephemeral range, less likely to conflict)
* refactor: clean up auth code and remove unnecessary comments
- Remove obvious comments that duplicate function names
- Extract duplicate expiration display logic into printTokenExpiration helper
- Simplify logoutCommand (remove async, inline condition)
- Remove unused saved_at field from token storage
* fix: address auth bugs and remove unused code
Bug fixes:
- whoami now shows "Session expired" instead of misleading "Logged in" when token is invalid
- expires_at calculation preserves existing value instead of overwriting
- Login check now allows re-login when tokens are expired with no refresh token
Simplifications:
- Remove unused getAccessToken and refreshAccessToken functions
- Simplify printTokenExpiration (remove unused showExpired parameter)
* refactor: improve whoami output formatting
- Align labels using padEnd for consistent output
- Remove expiration time display from whoami
- Show login status first, then fetch user details
* chore: add changeset for OAuth feature
* feat: enumerate search results
* feat: select hovered item on Enter in checkbox prompts
* refactor: improve types in prompts.ts
* feat: improve skill list UI with metadata panel and install counts
* chore: update version and changelog
* feat: add consistent green highlighting to IDE/scope prompts
Apply green highlight theme to all selection prompts in ide.ts
for visual consistency with skill selection prompts.
* feat: add skills cli
* chore: cleanup comments
* feat: update commands with new apis
* chore: remove unnecessary deps
* chore: update aliases and package name
* feat: remove /owner/repo/skill convention
* fix: cleanup, path and param handling
* feat(cli): multi-keyword search and Claude symlink priority
- Support multi-keyword search: `ctx7 skills search react hooks`
- Prioritize Claude to receive original files when installing to multiple IDEs
* refactor(cli): rename project to repository, reorder options
- Rename "project" argument to "repository" in help text
- Reorder options: --all and --global first, then IDE options
- Simplify IDE option descriptions to show client name and path
- Update internal variable names (project → repo)
* refactor(cli): flatten search results display
- Remove grouping by repository in search results
- Remove "Select all from repo" option
- Show each skill on single line with repo name in parentheses
- Simplify selection handling
* docs(cli): improve main help output with detailed examples
- Add section headers for commands and examples
- Include npx prefix in all example commands
- Group examples by use case (search, install, manage)
- Add comments explaining each example group
- Add link to context7.com
* refactor(cli): simplify banner, add examples to --help
Move detailed examples to --help output using addHelpText().
Simplify the no-argument banner to show only quick start examples.
* chore: remove unnecessary package