Skip to content

deps: bump the minor-and-patch group across 1 directory with 5 updates - #238

Merged
riglar merged 1 commit into
devfrom
dependabot/npm_and_yarn/minor-and-patch-80dda54ca9
Oct 20, 2026
Merged

riglar merged 1 commit into
devfrom
dependabot/npm_and_yarn/minor-and-patch-80dda54ca9

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Bumps the minor-and-patch group with 5 updates in the / directory:

Package From To
@supabase/supabase-js 2.117.3 2.118.0
js-yaml 5.4.3 5.5.0
zod 4.6.5 4.6.7
eslint 10.12.0 10.13.0
typescript-eslint 8.71.1 8.71.2

Updates @supabase/supabase-js from 2.117.3 to 2.118.0

Release notes

Sourced from @​supabase/supabase-js's releases.

v2.118.0

2.118.0 (2026-10-15)

🚀 Features

  • postgrest: leave computed fields out of select('*') and resolve no-argument rpc overloads for postgrest-typegen output (#2730)
  • storage: add content-encoding support for uploads (#1949)

🩹 Fixes

  • ci: patch next and sharp advisories and pin node-browser playwright (#2753)

❤️ Thank You

  • Atharv Gaur @​Athaxv
  • Ferhat Elmas
  • Lukas Klingsbo

v2.118.0-canary.2

2.118.0-canary.2 (2026-10-12)

This was a version bump only, there were no code changes.

v2.118.0-canary.1

2.118.0-canary.1 (2026-10-12)

This was a version bump only, there were no code changes.

v2.118.0-canary.0

2.118.0-canary.0 (2026-10-09)

🚀 Features

  • postgrest: leave computed fields out of select('*') and resolve no-argument rpc overloads for postgrest-typegen output (#2730)

🩹 Fixes

  • ci: patch next and sharp advisories and pin node-browser playwright (#2753)

❤️ Thank You

  • Lukas Klingsbo
Changelog

Sourced from @​supabase/supabase-js's changelog.

2.118.0 (2026-10-15)

🚀 Features

  • postgrest: leave computed fields out of select('*') and resolve no-argument rpc overloads for postgrest-typegen output (#2730)

❤️ Thank You

  • Lukas Klingsbo
Commits
  • b9753a1 feat(postgrest): leave computed fields out of select('*') and resolve no-argu...
  • 88faa11 fix(ci): patch next and sharp advisories and pin node-browser playwright (#2753)
  • aac9d32 chore(release): version 2.117.3 changelogs (#2744)
  • See full diff in compare view

Updates js-yaml from 5.4.3 to 5.5.0

Changelog

Sourced from js-yaml's changelog.

[5.5.0] - 2026-10-16

Changed

  • Updated argparse to v3.
  • Updated development dependencies.

Fixed

  • Correct percent-encoding of shorthand and verbatim tags.
  • Reject ,, ], and } at the start of block plain scalars, #801.
  • Report the exact position of non-printable characters in errors, #801.
Commits
  • cb62b2d 5.5.0 released
  • 87aed90 Deps bump
  • 3aec511 Fix error positions for non-printable characters, #801
  • 11aa483 Reject flow indicators at the start of block plain scalars, #801
  • 339d8e0 Refactor tag encoder and decoder to match the YAML specification
  • See full diff in compare view

Updates zod from 4.6.5 to 4.6.7

Release notes

Sourced from zod's releases.

v4.6.7

Commits:

  • b500a2ee95134f81d74da7911d7378dd2853d042 4.6.7

v4.6.6

Six malicious commits pushed to main on September 21 with a compromised git credential were reverted the same day in #6620 and have since been removed from the history of main. None were ever published to npm. The npm provenance for 4.6.6 names 284243fb, the pre-rewrite copy of 9c219833 with identical contents.

Commits:

  • 0cd3af5e9f50ad11bbcd4407a46a21b8848ba574 docs: load the en locale directly in Zod Mini
  • 9d5e60f162997b764b40d45aa02481888db50dea docs: import locales from zod/locales, not z.locales
  • 34a626f307871ecbb0123947559328dc52ed5e3e docs: tighten the z.locales tree-shaking note
  • 74304ce5b5796b5edb9a88ceb8e170b6ea3e82df release: stage npm versions instead of publishing them (#6622)
  • b2ef983e0711ff6517d6020b021071e2e5653efa docs: add Code for Japan to bronze sponsors
  • 8fb2faf0584828a6a027d8279db36f6f52784462 docs: crop the Code for Japan logo and list it first in bronze
  • bacad518c41610d654658172d325874bf0ee6290 docs: square the Code for Japan logo to match the other bronze tiles
  • c42596bd1c87e941d7241d10e012c5c196adcc10 release: hold the run on the release-approval environment until the staged versions are approved (#6638)
  • a2ba4a67986a3e6b2b131be30084a2f460d9ea67 fix(types): declare record output and input as members, not base type arguments (#6645)
  • a0ebf970f2d752e5f58527cd2942ff48be4f46bd fix(v4): check array, set and map size bounds before parsing elements (#6652)
  • 529f78dd9431b07f49647fee3aa0819b3f8b66b7 4.6.6
  • 9c219833c3a3764fa1f1ea9c5ecec8254a63c0b1 ci: stage at verbose so a failed OIDC token exchange says why
Commits
  • b500a2e 4.6.7
  • 9c21983 ci: stage at verbose so a failed OIDC token exchange says why
  • 529f78d 4.6.6
  • a0ebf97 fix(v4): check array, set and map size bounds before parsing elements (#6652)
  • a2ba4a6 fix(types): declare record output and input as members, not base type argumen...
  • c42596b release: hold the run on the release-approval environment until the staged ve...
  • bacad51 docs: square the Code for Japan logo to match the other bronze tiles
  • 8fb2faf docs: crop the Code for Japan logo and list it first in bronze
  • b2ef983 docs: add Code for Japan to bronze sponsors
  • 74304ce release: stage npm versions instead of publishing them (#6622)
  • Additional commits viewable in compare view

Updates eslint from 10.12.0 to 10.13.0

Release notes

Sourced from eslint's releases.

v10.13.0

Features

  • 48d5cc4 feat: report references inside IIFEs in no-use-before-define (#21238) (Irfan fandi)
  • a39d9fb feat: add globalThis to no-obj-calls (#21382) (synthex-byte)
  • 66ac583 feat: check yield* expressions in no-unsafe-optional-chaining (#21399) (xbinaryx)

Bug Fixes

  • 87bd2ce fix: avoid redeclared let when no-var and one-var fix together (#21389) (Daniel Pinto)

Documentation

  • 4783a68 docs: Update README (GitHub Actions Bot)
  • 43f0ac9 docs: clarify parameter description in getText (#21287) (lumir)

Chores

  • b59d889 chore: update github/codeql-action action to v4.38.3 (#21412) (renovate[bot])
  • 95e51a0 ci: re-enable @typescript-eslint/typescript-eslint in ecosystem tests (#21410) (Francesco Trotta)
  • 317fcb3 chore: update ecosystem plugins (#21409) (ESLint Bot)
  • b92decf perf: skip no-redeclare scan for single-declaration variables (#21365) (James Ross)
  • 47b7063 chore: update dependency @​eslint/json to ^2.1.1 (#21398) (renovate[bot])
  • e5aea41 chore: update ecosystem plugins (#21390) (ESLint Bot)
Commits

Updates typescript-eslint from 8.71.1 to 8.71.2

Release notes

Sourced from typescript-eslint's releases.

v8.71.2

8.71.2 (2026-10-12)

🩹 Fixes

  • eslint-plugin: [no-unused-vars] avoid false-positives when not using our parser (#12989)
  • eslint-plugin: [no-unnecessary-type-parameters] count instantiated mapped type templates (#12974)
  • eslint-plugin: [no-unused-vars] ignore type-only refs for after-used (#12977)
  • eslint-plugin: [no-unnecessary-type-parameters] parenthesize constraint in optional tuple elements (#12995)
  • eslint-plugin: [prefer-optional-chain] safe fix when the chain ends with a strict null comparison (#12805)
  • type-utils: match linked packages and packages with missing version in TypeOrValueSpecifier (#12948)

❤️ Thank You

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

Changelog

Sourced from typescript-eslint's changelog.

8.71.2 (2026-10-12)

This was a version bump only for typescript-eslint to align it with other projects, there were no code changes.

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

Commits

@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Oct 19, 2026
Bumps the minor-and-patch group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@supabase/supabase-js](https://github.com/supabase/supabase-js/tree/HEAD/packages/core/supabase-js) | `2.117.3` | `2.118.0` |
| [js-yaml](https://github.com/nodeca/js-yaml) | `5.4.3` | `5.5.0` |
| [zod](https://github.com/colinhacks/zod) | `4.6.5` | `4.6.7` |
| [eslint](https://github.com/eslint/eslint) | `10.12.0` | `10.13.0` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.71.1` | `8.71.2` |



Updates `@supabase/supabase-js` from 2.117.3 to 2.118.0
- [Release notes](https://github.com/supabase/supabase-js/releases)
- [Changelog](https://github.com/supabase/supabase-js/blob/master/packages/core/supabase-js/CHANGELOG.md)
- [Commits](https://github.com/supabase/supabase-js/commits/v2.118.0/packages/core/supabase-js)

Updates `js-yaml` from 5.4.3 to 5.5.0
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](nodeca/js-yaml@5.4.3...5.5.0)

Updates `zod` from 4.6.5 to 4.6.7
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](colinhacks/zod@v4.6.5...v4.6.7)

Updates `eslint` from 10.12.0 to 10.13.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](eslint/eslint@v10.12.0...v10.13.0)

Updates `typescript-eslint` from 8.71.1 to 8.71.2
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.71.2/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@supabase/supabase-js"
  dependency-version: 2.118.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: eslint
  dependency-version: 10.13.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: js-yaml
  dependency-version: 5.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: typescript-eslint
  dependency-version: 8.71.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: zod
  dependency-version: 4.6.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot changed the title deps: bump the minor-and-patch group with 5 updates deps: bump the minor-and-patch group across 1 directory with 5 updates Oct 20, 2026
@dependabot
dependabot Bot force-pushed the dependabot/npm_and_yarn/minor-and-patch-80dda54ca9 branch from d5c3f35 to 5d402dd Compare October 20, 2026 11:31
@riglar
riglar merged commit 5fffd7a into dev Oct 20, 2026
8 checks passed
@riglar
riglar deleted the dependabot/npm_and_yarn/minor-and-patch-80dda54ca9 branch October 20, 2026 11:42
@riglar riglar mentioned this pull request Oct 22, 2026
riglar added a commit that referenced this pull request Oct 23, 2026
* chore: merge production into dev after 5.8.0 (#236)

* ReleaseAs: 5.8.0

* Release-As: 5.8.0

* Release-As: 5.8.0

* chore(production): release 5.8.0

---------

Co-authored-by: finalerock44 <ethan@devicecloud.dev>
Co-authored-by: finalerock44 <77282157+finalerock44@users.noreply.github.com>
Co-authored-by: dcd-release-please[bot] <296541543+dcd-release-please[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore: bump eslint-plugin-unicorn from 77.0.0 to 78.0.0 (#239)

Bumps [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) from 77.0.0 to 78.0.0.
- [Release notes](https://github.com/sindresorhus/eslint-plugin-unicorn/releases)
- [Commits](sindresorhus/eslint-plugin-unicorn@v77.0.0...v78.0.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-unicorn
  dependency-version: 78.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* deps: bump the minor-and-patch group across 1 directory with 5 updates (#238)

Bumps the minor-and-patch group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@supabase/supabase-js](https://github.com/supabase/supabase-js/tree/HEAD/packages/core/supabase-js) | `2.117.3` | `2.118.0` |
| [js-yaml](https://github.com/nodeca/js-yaml) | `5.4.3` | `5.5.0` |
| [zod](https://github.com/colinhacks/zod) | `4.6.5` | `4.6.7` |
| [eslint](https://github.com/eslint/eslint) | `10.12.0` | `10.13.0` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.71.1` | `8.71.2` |



Updates `@supabase/supabase-js` from 2.117.3 to 2.118.0
- [Release notes](https://github.com/supabase/supabase-js/releases)
- [Changelog](https://github.com/supabase/supabase-js/blob/master/packages/core/supabase-js/CHANGELOG.md)
- [Commits](https://github.com/supabase/supabase-js/commits/v2.118.0/packages/core/supabase-js)

Updates `js-yaml` from 5.4.3 to 5.5.0
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](nodeca/js-yaml@5.4.3...5.5.0)

Updates `zod` from 4.6.5 to 4.6.7
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](colinhacks/zod@v4.6.5...v4.6.7)

Updates `eslint` from 10.12.0 to 10.13.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](eslint/eslint@v10.12.0...v10.13.0)

Updates `typescript-eslint` from 8.71.1 to 8.71.2
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.71.2/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@supabase/supabase-js"
  dependency-version: 2.118.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: eslint
  dependency-version: 10.13.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: js-yaml
  dependency-version: 5.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: typescript-eslint
  dependency-version: 8.71.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: zod
  dependency-version: 4.6.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* feat(login): reuse the last org and add --org (#243)

* feat(login): reuse the last org and add --org

dcd login no longer hangs where nobody can answer a prompt, such as a
script, CI, or a shell an agent runs.

- The org picker starts on the org from the last login, so Enter keeps it.
- Without a TTY, the last login's org is used and one line says so. With
  no last org, or one that is gone, login fails with an error that names
  --org and lists the available orgs.
- --org <name|id> picks the org without the picker, and fails if the user
  isn't a member.
- Without a TTY, the "already logged in" confirm takes its default and
  signs in again. The old session stays until the new login succeeds.
- The last org only counts when the last login was to the same API,
  because org ids differ between environments.
- A bare dcd switch-org without a TTY now fails with the org names instead
  of hanging the same way.

Closes #241

* chore(deps): bump hono override to 4.13.11 to clear audit

pnpm audit flagged GHSA-5r4p-p66f-jhc7 (moderate) on hono >=4.12.4
<4.13.11, which comes in through @modelcontextprotocol/sdk. In those
versions serveStatic decodes the request path twice. The advisory was
published on 2026-10-20, after dev's last green run, so the
lint-and-test audit step now fails on every branch. Dependabot opened an
alert but no fix PR, because the exact-pin override holds hono at
4.13.7.

4.13.11 is the lowest patched version, as with the earlier pins. The
audit passes apart from the advisory that was already ignored. Lint,
typecheck, unit tests and build pass, and dcd-mcp answers initialize
and tools/list over stdio with all five tools.

* feat(auth): fetch the Supabase key from the API instead of compiling it in (#245)

Every release so far compiled the Supabase anon key in, so the key could
not be rotated without breaking pinned CLI versions (dcd#1112). The CLI
now fetches its publishable key from the API's public GET /cli-config,
once per process, so a rotation is an env change on the API.

- The key is kept in memory only. A stale on-disk copy would make a
  session refresh fail with a 4xx, which drops the user's login.
- A failed key fetch during refresh is a retryable error, never a
  definitive one, so the stored session survives.
- Supabase URLs stay pinned (prod uses the cloud.devicecloud.dev custom
  domain); only the key comes from the API.
- Raw Storage/Auth requests send an sb_publishable_ key as `apikey`
  only, and a legacy JWT key as a Bearer too.
- Realtime keeps a synchronous subscribe() and connects once the key
  arrives; until then the backstop poll covers it.
- The anon keys stay in the gitleaks allowlist, relabelled: they remain
  in history, which CI scans in full.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* ci: skip promotion-pin on release-please PRs (#249)

Release-please's release PR targets production but is not a promotion,
so the Release-As pin check always failed on it (#230, #247).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* feat(encrypt): list --encrypt in --help now encryption is on by defau… (#250)

feat(encrypt): list --encrypt in --help now encryption is on by default (dcd#1138)

The API now sends encryption.defaultOn = true for every org, not only orgs in
the client_encryption beta, so the beta-only pieces come out:

- --encrypt is listed in `dcd cloud --help` and `dcd upload --help` again,
  and its description says it is on by default and that --no-encrypt or
  DCD_ENCRYPT=0 turns it off. The hidden-arg filter (src/utils/help.ts),
  which only ever hid this flag, is removed; flags go back to citty's ArgsDef.
- The notice drops "(beta)": "Encrypting uploads; opt out with --no-encrypt"
  (and "encrypt: false" from the MCP tool). It still prints only when the
  server default turned encryption on, and --json still suppresses it.
- The KEK error messages, the MCP encrypt input and comments say "the
  default" or "the server default" instead of "the organization default".
- server.json lists DCD_ENCRYPT, so MCP users can find the opt-out.
- environments.ts no longer says the KEK is "left null until generated";
  it describes how to rotate.

resolveEncryption is unchanged: flag, then DCD_ENCRYPT, then the server
default, then off. The default stays server-side so the API's
CLIENT_ENCRYPTION_DEFAULT=off kill switch keeps working for every CLI.
src/types/generated/schema.types.ts still carries the beta wording in one
JSDoc description; a full regeneration would pull in unrelated API surface,
so it waits for the next one.

* feat: fetch the KEK public key from the API instead of pinning it (#251)

The CLI pinned one KEK public key per environment, so every KEK rotation
needed a CLI release that customers then had to pick up. GET /cli-config
now publishes the newest KEK the API holds the private half of
(binary_kek_public_key), and the CLI wraps uploads with whatever the API it
talks to serves, fetched once per process alongside the Supabase key.

DCD_BINARY_KEK_PUBLIC still overrides for an API that publishes nothing.
An API that publishes no key keeps the old behaviour (explicit --encrypt
fails, env/org-default encryption skips with a notice); an API that cannot
be asked at all fails the run rather than silently uploading plaintext.

* chore: merge production into dev after 5.9.0 (#248)

* ReleaseAs: 5.8.0

* Release-As: 5.8.0

* Release-As: 5.8.0

* chore(production): release 5.8.0

* chore: pin the 5.9.0 promotion

Release-As: 5.9.0

* chore(production): release 5.9.0

---------

Co-authored-by: finalerock44 <ethan@devicecloud.dev>
Co-authored-by: finalerock44 <77282157+finalerock44@users.noreply.github.com>
Co-authored-by: dcd-release-please[bot] <296541543+dcd-release-please[bot]@users.noreply.github.com>
Co-authored-by: Tom Riglar <tom.riglar@moropo.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* deps: patch ip-address advisory (#256)

Bump the transitive ip-address from 10.7.3 to 10.7.4 for
GHSA-rxp7-6hxx-x8q5. express-rate-limit's ^10.2.0 range already allows
it, so only the lockfile changes.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* ci: authenticate the Claude action by workload identity federation (#255)

Swap the CLAUDE_CODE_OAUTH_TOKEN secret for the action's built-in OIDC
exchange, so the workflows need no stored secret.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* chore: merge production into dev after 5.10.0 (#254)

* ReleaseAs: 5.8.0

* Release-As: 5.8.0

* Release-As: 5.8.0

* chore(production): release 5.8.0

* chore: pin the 5.9.0 promotion

Release-As: 5.9.0

* chore(production): release 5.9.0

* chore: pin the 5.10.0 promotion

Release-As: 5.10.0

* chore(production): release 5.10.0

---------

Co-authored-by: finalerock44 <ethan@devicecloud.dev>
Co-authored-by: finalerock44 <77282157+finalerock44@users.noreply.github.com>
Co-authored-by: dcd-release-please[bot] <296541543+dcd-release-please[bot]@users.noreply.github.com>
Co-authored-by: Tom Riglar <tom.riglar@moropo.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* ci: authenticate the Claude action with the org CLAUDE_CODE_OAUTH_TOKEN (#257)

Back from workload identity federation to the OAuth token, now an org-level
secret. Federation bills the Anthropic API org's purchased credit, which
promotional credit doesn't cover for Claude Code, so reviews were failing
with "Credit balance is too low".


Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* fix(auth): keep the stored session when a refresh fails

A refused refresh used to delete the session from config.json. Old
builds hit that on every refresh once Supabase turned off legacy keys
("Legacy API keys are disabled"), so the session was wiped even though
an upgrade alone would have fixed it. Now only `dcd logout` (or the
next `dcd login`) replaces the stored session. The error still tells
the user to log in again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

* fix(device): show run results as one line per flow

`dcd device run` printed the runner's raw JSON under "Output" on a pass
and under "Error" on a failed directory run, env_vars included. It now
reads that report (or `result.flows`, when the API sends it) and prints
each flow with passed or failed and the reason, plus a short summary.
The failure message names the failing flows. --json still carries the
API's full result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

* fix(device): leave session out of --json for list, models and stop --all

`dcd device list --json` printed a stray "session": null, as if the
command were about one session. Commands that are not about one session
now leave the key out. Every other command's envelope is unchanged, and
errors still carry session (null when the API sent none).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

* fix(device): infer the platform from --model

`dcd device start --model iphone-16` failed with "--platform is
required". Without --platform, start now looks the model up in
GET /device/models (by id or name) and uses its platform. It is still a
usage error when the model is unknown or exists on both platforms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

* fix(device): warn when the video and log are still uploading

Right after `dcd device stop`, `dcd device artifacts` downloaded only
the per-action screenshots; the video and device log landed about 45s
later, with no word that they were coming. It now warns "The video and
device log are still uploading. Run this again in a minute." and puts
`pending` and `warning` in --json. It reads the API's new `pending`
field. An older API gets a guess instead: an ended session missing
either file whose last activity was under three minutes ago.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

* feat(device): add request-human and human, like the MCP tools

The MCP server has request_human and get_human_status; the CLI had
nothing, though session warnings told CLI users to wait for a person.

- `dcd device request-human "<reason>" [id] [--wait]` asks a person for
  help (POST .../request-human).
- `dcd device human [id] [--wait]` shows whether the session waits for a
  person, who has control, when it ends, and the hand-back note.
- --wait checks every 5s until the person hands back or the session
  ends (exit 4). Ctrl-C stops waiting and leaves the session open.
- `dcd device status` shows the hand-back note, and --json carries it.
- A command refused with 409 LIVE_HUMAN_IN_CONTROL now says a person has
  control and to run `dcd device human <id> --wait`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dcd-release-please[bot] <296541543+dcd-release-please[bot]@users.noreply.github.com>
Co-authored-by: finalerock44 <ethan@devicecloud.dev>
Co-authored-by: finalerock44 <77282157+finalerock44@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
riglar added a commit that referenced this pull request Oct 26, 2026
* feat(device): add dcd device start, list, status, stop, install, launch and models (#231)

The first stages of the Agent Devices CLI (dcd plan 3.1 and 3.2).

- --json prints one envelope, {ok, session, data, error}, on success
  and on failure.
- Exit codes: 0 ok, 1 usage, 2 failed, 3 limit, 4 session ended or
  not found.
- The session id may be left out when exactly one session is open.
- start --app uploads a local build first; an https URL goes to the
  API's install-from-URL.
- Progress goes to stderr, with no spinner unless at a terminal.

Hidden from dcd --help until the API reaches production.


Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* feat(device): add dcd device inspect, screenshot, run, logs and open (#232)

* feat(device): add dcd device start, list, status, stop, install, launch and models

The first stages of the Agent Devices CLI (dcd plan 3.1 and 3.2).

- --json prints one envelope, {ok, session, data, error}, on success
  and on failure.
- Exit codes: 0 ok, 1 usage, 2 failed, 3 limit, 4 session ended or
  not found.
- The session id may be left out when exactly one session is open.
- start --app uploads a local build first; an https URL goes to the
  API's install-from-URL.
- Progress goes to stderr, with no spinner unless at a terminal.

Hidden from dcd --help until the API reaches production.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(device): add dcd device inspect, screenshot, run, logs and open

Stage 3.3 of the Agent Devices CLI.

- inspect prints the compact screen; screenshot saves the frame to a
  file and reports its path.
- run sends one flow (a file or --yaml) with optional --env KEY=VALUE,
  and polls a flow that outlasts the API's wait. A failed flow exits 2.
- logs prints the app's recent log lines; --follow keeps printing new
  ones until the session ends.
- open opens the monitor at a terminal, and prints its URL otherwise.

Running a directory of flows needs an API change first and is refused
for now. openBrowser moves out of login.ts so device can share it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* fix(device): renew a dcd login token while polling

logs --follow, a long run and start --wait reused the token resolved at
the start. A dcd login access token lasts about an hour, so a poll past
that failed with an auth error. Each poll now calls refreshAuth first;
an API key is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* feat(device): add dcd device artifacts (#234)

* feat(device): add dcd device start, list, status, stop, install, launch and models

The first stages of the Agent Devices CLI (dcd plan 3.1 and 3.2).

- --json prints one envelope, {ok, session, data, error}, on success
  and on failure.
- Exit codes: 0 ok, 1 usage, 2 failed, 3 limit, 4 session ended or
  not found.
- The session id may be left out when exactly one session is open.
- start --app uploads a local build first; an https URL goes to the
  API's install-from-URL.
- Progress goes to stderr, with no spinner unless at a terminal.

Hidden from dcd --help until the API reaches production.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(device): add dcd device inspect, screenshot, run, logs and open

Stage 3.3 of the Agent Devices CLI.

- inspect prints the compact screen; screenshot saves the frame to a
  file and reports its path.
- run sends one flow (a file or --yaml) with optional --env KEY=VALUE,
  and polls a flow that outlasts the API's wait. A failed flow exits 2.
- logs prints the app's recent log lines; --follow keeps printing new
  ones until the session ends.
- open opens the monitor at a terminal, and prints its URL otherwise.

Running a directory of flows needs an API change first and is refused
for now. openBrowser moves out of login.ts so device can share it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(device): add dcd device artifacts

Stage 5.3 of Agent Devices. Downloads what a session left behind into
./<session>-artifacts (or -o dir): recording.mp4, device.log, and per
action actions/NNN-screenshot.jpg and NNN-screen.json, numbered oldest
first. Follows every page. --links lists the signed links instead.
Files that cannot be fetched are reported, and the command exits 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* fix(device): renew a dcd login token while polling

logs --follow, a long run and start --wait reused the token resolved at
the start. A dcd login access token lasts about an hour, so a poll past
that failed with an auth error. Each poll now calls refreshAuth first;
an API key is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* feat(device): run a directory of flows as a bundle (#235)

* feat(device): add dcd device start, list, status, stop, install, launch and models

The first stages of the Agent Devices CLI (dcd plan 3.1 and 3.2).

- --json prints one envelope, {ok, session, data, error}, on success
  and on failure.
- Exit codes: 0 ok, 1 usage, 2 failed, 3 limit, 4 session ended or
  not found.
- The session id may be left out when exactly one session is open.
- start --app uploads a local build first; an https URL goes to the
  API's install-from-URL.
- Progress goes to stderr, with no spinner unless at a terminal.

Hidden from dcd --help until the API reaches production.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(device): add dcd device inspect, screenshot, run, logs and open

Stage 3.3 of the Agent Devices CLI.

- inspect prints the compact screen; screenshot saves the frame to a
  file and reports its path.
- run sends one flow (a file or --yaml) with optional --env KEY=VALUE,
  and polls a flow that outlasts the API's wait. A failed flow exits 2.
- logs prints the app's recent log lines; --follow keeps printing new
  ones until the session ends.
- open opens the monitor at a terminal, and prints its URL otherwise.

Running a directory of flows needs an API change first and is refused
for now. openBrowser moves out of login.ts so device can share it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(device): add dcd device artifacts

Stage 5.3 of Agent Devices. Downloads what a session left behind into
./<session>-artifacts (or -o dir): recording.mp4, device.log, and per
action actions/NNN-screenshot.jpg and NNN-screen.json, numbered oldest
first. Follows every page. --links lists the signed links instead.
Files that cannot be fetched are reported, and the command exits 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* fix(device): renew a dcd login token while polling

logs --follow, a long run and start --wait reused the token resolved at
the start. A dcd login access token lasts about an hour, so a poll past
that failed with an auth error. Each poll now calls refreshAuth first;
an API key is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(device): run a directory of flows as a bundle

dcd device run <dir> zips the directory (without dot-folders and
node_modules), uploads it to both copies through POST
/device/bundles/upload-url, registers it with its SHA-256, and runs it
by id. --entry picks one flow inside it; without it every flow runs.
The zip is encrypted when the org's default or DCD_ENCRYPT says so, as
dcd cloud's flow zips are. Needs dcd#1718.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* feat(mcp): add dcd mcp, one stdio server for cloud tests and cloud devices (#237)

* feat(device): add dcd device start, list, status, stop, install, launch and models

The first stages of the Agent Devices CLI (dcd plan 3.1 and 3.2).

- --json prints one envelope, {ok, session, data, error}, on success
  and on failure.
- Exit codes: 0 ok, 1 usage, 2 failed, 3 limit, 4 session ended or
  not found.
- The session id may be left out when exactly one session is open.
- start --app uploads a local build first; an https URL goes to the
  API's install-from-URL.
- Progress goes to stderr, with no spinner unless at a terminal.

Hidden from dcd --help until the API reaches production.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(device): add dcd device inspect, screenshot, run, logs and open

Stage 3.3 of the Agent Devices CLI.

- inspect prints the compact screen; screenshot saves the frame to a
  file and reports its path.
- run sends one flow (a file or --yaml) with optional --env KEY=VALUE,
  and polls a flow that outlasts the API's wait. A failed flow exits 2.
- logs prints the app's recent log lines; --follow keeps printing new
  ones until the session ends.
- open opens the monitor at a terminal, and prints its URL otherwise.

Running a directory of flows needs an API change first and is refused
for now. openBrowser moves out of login.ts so device can share it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(device): add dcd device artifacts

Stage 5.3 of Agent Devices. Downloads what a session left behind into
./<session>-artifacts (or -o dir): recording.mp4, device.log, and per
action actions/NNN-screenshot.jpg and NNN-screen.json, numbered oldest
first. Follows every page. --links lists the signed links instead.
Files that cannot be fetched are reported, and the command exits 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* fix(device): renew a dcd login token while polling

logs --follow, a long run and start --wait reused the token resolved at
the start. A dcd login access token lasts about an hour, so a poll past
that failed with an auth error. Each poll now calls refreshAuth first;
an API key is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(device): run a directory of flows as a bundle

dcd device run <dir> zips the directory (without dot-folders and
node_modules), uploads it to both copies through POST
/device/bundles/upload-url, registers it with its SHA-256, and runs it
by id. --entry picks one flow inside it; without it every flow runs.
The zip is encrypted when the org's default or DCD_ENCRYPT says so, as
dcd cloud's flow zips are. Needs dcd#1718.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(mcp): add dcd mcp, one stdio server for cloud tests and cloud devices

Agent Devices 4.4. dcd mcp serves the dcd_* tools (the same in-process
server dcd-mcp runs) and the device tools, proxied from the hosted
<api>/mcp so they are defined once. It adds what only a local process
can do: install_app takes app_path (uploaded first) and run takes path
(a flow file sent as yaml, or a directory uploaded as a bundle).

Uses the CLI's credentials; the hosted /mcp accepts a dcd login session
with dcd#1719. Without the hosted endpoint it serves the dcd_* tools
only. Read-only mode keeps only read-only device tools. Hidden until the
device API is live; dcd-mcp is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* fix(mcp): refuse state-changing device tools in read-only mode

Read-only mode hid them from the tool list, but a call made anyway was
still forwarded to the hosted /mcp, which knows nothing of the mode. The
bridge now refuses any device tool not annotated readOnlyHint, and the
server instructions in read-only mode name only the reading tools.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* fix(mcp): don't cut forwarded calls off at the SDK's 60s default

dcd mcp forwarded every call through an MCP Client with no request
options, so the SDK's 60s default applied: dcd_run_cloud_test with wait
(up to an hour), a large upload, or a long device run failed with
'Request timed out' while the work carried on. Both forwarded calls now
pass the caller's cancel signal and a 2h timeout that resets on progress,
so the calling client's own timeout is what limits them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* test(mcp): check the bridge's call timeout is the one applied

createBridgeServer takes callTimeoutMs (default 2h), so a test can show
a forwarded call outlasting it times out and a faster one doesn't.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* fix(device): time out stalled artifact downloads (#240)

* fix(device): install --wait waits for the install itself (#242)

install --wait returned as soon as the session was usable, but a session
stays ready while a new build installs, so it came back before the app
was there. It now also polls the session block's install.status (dcd
#1748) until the build is installed or failed. A failed install exits 2
with the reason and says the session is still open; start --app --wait
does the same. An API without install status returns as before.


Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* fix(device): QA fixes, dev sync, and request-human/human commands (#258)

* chore: merge production into dev after 5.8.0 (#236)

* ReleaseAs: 5.8.0

* Release-As: 5.8.0

* Release-As: 5.8.0

* chore(production): release 5.8.0

---------

Co-authored-by: finalerock44 <ethan@devicecloud.dev>
Co-authored-by: finalerock44 <77282157+finalerock44@users.noreply.github.com>
Co-authored-by: dcd-release-please[bot] <296541543+dcd-release-please[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore: bump eslint-plugin-unicorn from 77.0.0 to 78.0.0 (#239)

Bumps [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) from 77.0.0 to 78.0.0.
- [Release notes](https://github.com/sindresorhus/eslint-plugin-unicorn/releases)
- [Commits](sindresorhus/eslint-plugin-unicorn@v77.0.0...v78.0.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-unicorn
  dependency-version: 78.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* deps: bump the minor-and-patch group across 1 directory with 5 updates (#238)

Bumps the minor-and-patch group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@supabase/supabase-js](https://github.com/supabase/supabase-js/tree/HEAD/packages/core/supabase-js) | `2.117.3` | `2.118.0` |
| [js-yaml](https://github.com/nodeca/js-yaml) | `5.4.3` | `5.5.0` |
| [zod](https://github.com/colinhacks/zod) | `4.6.5` | `4.6.7` |
| [eslint](https://github.com/eslint/eslint) | `10.12.0` | `10.13.0` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.71.1` | `8.71.2` |



Updates `@supabase/supabase-js` from 2.117.3 to 2.118.0
- [Release notes](https://github.com/supabase/supabase-js/releases)
- [Changelog](https://github.com/supabase/supabase-js/blob/master/packages/core/supabase-js/CHANGELOG.md)
- [Commits](https://github.com/supabase/supabase-js/commits/v2.118.0/packages/core/supabase-js)

Updates `js-yaml` from 5.4.3 to 5.5.0
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](nodeca/js-yaml@5.4.3...5.5.0)

Updates `zod` from 4.6.5 to 4.6.7
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](colinhacks/zod@v4.6.5...v4.6.7)

Updates `eslint` from 10.12.0 to 10.13.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](eslint/eslint@v10.12.0...v10.13.0)

Updates `typescript-eslint` from 8.71.1 to 8.71.2
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.71.2/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@supabase/supabase-js"
  dependency-version: 2.118.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: eslint
  dependency-version: 10.13.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: js-yaml
  dependency-version: 5.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: typescript-eslint
  dependency-version: 8.71.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: zod
  dependency-version: 4.6.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* feat(login): reuse the last org and add --org (#243)

* feat(login): reuse the last org and add --org

dcd login no longer hangs where nobody can answer a prompt, such as a
script, CI, or a shell an agent runs.

- The org picker starts on the org from the last login, so Enter keeps it.
- Without a TTY, the last login's org is used and one line says so. With
  no last org, or one that is gone, login fails with an error that names
  --org and lists the available orgs.
- --org <name|id> picks the org without the picker, and fails if the user
  isn't a member.
- Without a TTY, the "already logged in" confirm takes its default and
  signs in again. The old session stays until the new login succeeds.
- The last org only counts when the last login was to the same API,
  because org ids differ between environments.
- A bare dcd switch-org without a TTY now fails with the org names instead
  of hanging the same way.

Closes #241

* chore(deps): bump hono override to 4.13.11 to clear audit

pnpm audit flagged GHSA-5r4p-p66f-jhc7 (moderate) on hono >=4.12.4
<4.13.11, which comes in through @modelcontextprotocol/sdk. In those
versions serveStatic decodes the request path twice. The advisory was
published on 2026-10-20, after dev's last green run, so the
lint-and-test audit step now fails on every branch. Dependabot opened an
alert but no fix PR, because the exact-pin override holds hono at
4.13.7.

4.13.11 is the lowest patched version, as with the earlier pins. The
audit passes apart from the advisory that was already ignored. Lint,
typecheck, unit tests and build pass, and dcd-mcp answers initialize
and tools/list over stdio with all five tools.

* feat(auth): fetch the Supabase key from the API instead of compiling it in (#245)

Every release so far compiled the Supabase anon key in, so the key could
not be rotated without breaking pinned CLI versions (dcd#1112). The CLI
now fetches its publishable key from the API's public GET /cli-config,
once per process, so a rotation is an env change on the API.

- The key is kept in memory only. A stale on-disk copy would make a
  session refresh fail with a 4xx, which drops the user's login.
- A failed key fetch during refresh is a retryable error, never a
  definitive one, so the stored session survives.
- Supabase URLs stay pinned (prod uses the cloud.devicecloud.dev custom
  domain); only the key comes from the API.
- Raw Storage/Auth requests send an sb_publishable_ key as `apikey`
  only, and a legacy JWT key as a Bearer too.
- Realtime keeps a synchronous subscribe() and connects once the key
  arrives; until then the backstop poll covers it.
- The anon keys stay in the gitleaks allowlist, relabelled: they remain
  in history, which CI scans in full.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* ci: skip promotion-pin on release-please PRs (#249)

Release-please's release PR targets production but is not a promotion,
so the Release-As pin check always failed on it (#230, #247).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* feat(encrypt): list --encrypt in --help now encryption is on by defau… (#250)

feat(encrypt): list --encrypt in --help now encryption is on by default (dcd#1138)

The API now sends encryption.defaultOn = true for every org, not only orgs in
the client_encryption beta, so the beta-only pieces come out:

- --encrypt is listed in `dcd cloud --help` and `dcd upload --help` again,
  and its description says it is on by default and that --no-encrypt or
  DCD_ENCRYPT=0 turns it off. The hidden-arg filter (src/utils/help.ts),
  which only ever hid this flag, is removed; flags go back to citty's ArgsDef.
- The notice drops "(beta)": "Encrypting uploads; opt out with --no-encrypt"
  (and "encrypt: false" from the MCP tool). It still prints only when the
  server default turned encryption on, and --json still suppresses it.
- The KEK error messages, the MCP encrypt input and comments say "the
  default" or "the server default" instead of "the organization default".
- server.json lists DCD_ENCRYPT, so MCP users can find the opt-out.
- environments.ts no longer says the KEK is "left null until generated";
  it describes how to rotate.

resolveEncryption is unchanged: flag, then DCD_ENCRYPT, then the server
default, then off. The default stays server-side so the API's
CLIENT_ENCRYPTION_DEFAULT=off kill switch keeps working for every CLI.
src/types/generated/schema.types.ts still carries the beta wording in one
JSDoc description; a full regeneration would pull in unrelated API surface,
so it waits for the next one.

* feat: fetch the KEK public key from the API instead of pinning it (#251)

The CLI pinned one KEK public key per environment, so every KEK rotation
needed a CLI release that customers then had to pick up. GET /cli-config
now publishes the newest KEK the API holds the private half of
(binary_kek_public_key), and the CLI wraps uploads with whatever the API it
talks to serves, fetched once per process alongside the Supabase key.

DCD_BINARY_KEK_PUBLIC still overrides for an API that publishes nothing.
An API that publishes no key keeps the old behaviour (explicit --encrypt
fails, env/org-default encryption skips with a notice); an API that cannot
be asked at all fails the run rather than silently uploading plaintext.

* chore: merge production into dev after 5.9.0 (#248)

* ReleaseAs: 5.8.0

* Release-As: 5.8.0

* Release-As: 5.8.0

* chore(production): release 5.8.0

* chore: pin the 5.9.0 promotion

Release-As: 5.9.0

* chore(production): release 5.9.0

---------

Co-authored-by: finalerock44 <ethan@devicecloud.dev>
Co-authored-by: finalerock44 <77282157+finalerock44@users.noreply.github.com>
Co-authored-by: dcd-release-please[bot] <296541543+dcd-release-please[bot]@users.noreply.github.com>
Co-authored-by: Tom Riglar <tom.riglar@moropo.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* deps: patch ip-address advisory (#256)

Bump the transitive ip-address from 10.7.3 to 10.7.4 for
GHSA-rxp7-6hxx-x8q5. express-rate-limit's ^10.2.0 range already allows
it, so only the lockfile changes.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* ci: authenticate the Claude action by workload identity federation (#255)

Swap the CLAUDE_CODE_OAUTH_TOKEN secret for the action's built-in OIDC
exchange, so the workflows need no stored secret.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* chore: merge production into dev after 5.10.0 (#254)

* ReleaseAs: 5.8.0

* Release-As: 5.8.0

* Release-As: 5.8.0

* chore(production): release 5.8.0

* chore: pin the 5.9.0 promotion

Release-As: 5.9.0

* chore(production): release 5.9.0

* chore: pin the 5.10.0 promotion

Release-As: 5.10.0

* chore(production): release 5.10.0

---------

Co-authored-by: finalerock44 <ethan@devicecloud.dev>
Co-authored-by: finalerock44 <77282157+finalerock44@users.noreply.github.com>
Co-authored-by: dcd-release-please[bot] <296541543+dcd-release-please[bot]@users.noreply.github.com>
Co-authored-by: Tom Riglar <tom.riglar@moropo.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* ci: authenticate the Claude action with the org CLAUDE_CODE_OAUTH_TOKEN (#257)

Back from workload identity federation to the OAuth token, now an org-level
secret. Federation bills the Anthropic API org's purchased credit, which
promotional credit doesn't cover for Claude Code, so reviews were failing
with "Credit balance is too low".


Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* fix(auth): keep the stored session when a refresh fails

A refused refresh used to delete the session from config.json. Old
builds hit that on every refresh once Supabase turned off legacy keys
("Legacy API keys are disabled"), so the session was wiped even though
an upgrade alone would have fixed it. Now only `dcd logout` (or the
next `dcd login`) replaces the stored session. The error still tells
the user to log in again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

* fix(device): show run results as one line per flow

`dcd device run` printed the runner's raw JSON under "Output" on a pass
and under "Error" on a failed directory run, env_vars included. It now
reads that report (or `result.flows`, when the API sends it) and prints
each flow with passed or failed and the reason, plus a short summary.
The failure message names the failing flows. --json still carries the
API's full result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

* fix(device): leave session out of --json for list, models and stop --all

`dcd device list --json` printed a stray "session": null, as if the
command were about one session. Commands that are not about one session
now leave the key out. Every other command's envelope is unchanged, and
errors still carry session (null when the API sent none).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

* fix(device): infer the platform from --model

`dcd device start --model iphone-16` failed with "--platform is
required". Without --platform, start now looks the model up in
GET /device/models (by id or name) and uses its platform. It is still a
usage error when the model is unknown or exists on both platforms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

* fix(device): warn when the video and log are still uploading

Right after `dcd device stop`, `dcd device artifacts` downloaded only
the per-action screenshots; the video and device log landed about 45s
later, with no word that they were coming. It now warns "The video and
device log are still uploading. Run this again in a minute." and puts
`pending` and `warning` in --json. It reads the API's new `pending`
field. An older API gets a guess instead: an ended session missing
either file whose last activity was under three minutes ago.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

* feat(device): add request-human and human, like the MCP tools

The MCP server has request_human and get_human_status; the CLI had
nothing, though session warnings told CLI users to wait for a person.

- `dcd device request-human "<reason>" [id] [--wait]` asks a person for
  help (POST .../request-human).
- `dcd device human [id] [--wait]` shows whether the session waits for a
  person, who has control, when it ends, and the hand-back note.
- --wait checks every 5s until the person hands back or the session
  ends (exit 4). Ctrl-C stops waiting and leaves the session open.
- `dcd device status` shows the hand-back note, and --json carries it.
- A command refused with 409 LIVE_HUMAN_IN_CONTROL now says a person has
  control and to run `dcd device human <id> --wait`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dcd-release-please[bot] <296541543+dcd-release-please[bot]@users.noreply.github.com>
Co-authored-by: finalerock44 <ethan@devicecloud.dev>
Co-authored-by: finalerock44 <77282157+finalerock44@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* fix(device): say a person has control once in dcd device status (#259)

The API's session warnings already say a person has control and how to
wait, so status printed the same thing twice. Print our own line only when
an older API leaves it out.


Claude-Session: https://claude.ai/code/session_016xsPHeqEEpmiNy9YvGFDwB

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* feat(device): list dcd device and dcd mcp in help, and deprecate dcd live (#233)

* feat(device): add dcd device start, list, status, stop, install, launch and models

The first stages of the Agent Devices CLI (dcd plan 3.1 and 3.2).

- --json prints one envelope, {ok, session, data, error}, on success
  and on failure.
- Exit codes: 0 ok, 1 usage, 2 failed, 3 limit, 4 session ended or
  not found.
- The session id may be left out when exactly one session is open.
- start --app uploads a local build first; an https URL goes to the
  API's install-from-URL.
- Progress goes to stderr, with no spinner unless at a terminal.

Hidden from dcd --help until the API reaches production.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(device): add dcd device inspect, screenshot, run, logs and open

Stage 3.3 of the Agent Devices CLI.

- inspect prints the compact screen; screenshot saves the frame to a
  file and reports its path.
- run sends one flow (a file or --yaml) with optional --env KEY=VALUE,
  and polls a flow that outlasts the API's wait. A failed flow exits 2.
- logs prints the app's recent log lines; --follow keeps printing new
  ones until the session ends.
- open opens the monitor at a terminal, and prints its URL otherwise.

Running a directory of flows needs an API change first and is refused
for now. openBrowser moves out of login.ts so device can share it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(device): list dcd device in help and deprecate dcd live

Stage 3.4 of the Agent Devices CLI. dcd device appears in dcd --help.
dcd live is hidden and prints a deprecation line on stderr pointing at
dcd device; it keeps working for existing scripts.

Merge only when the /device/sessions API is in production.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* fix(device): renew a dcd login token while polling

logs --follow, a long run and start --wait reused the token resolved at
the start. A dcd login access token lasts about an hour, so a poll past
that failed with an auth error. Each poll now calls refreshAuth first;
an API key is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

* feat(mcp): list dcd mcp in help at launch

Unhide dcd mcp alongside dcd device, and update CLAUDE.md to match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tQfgpTsA9UhcopKoDezUA

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* fix(device): open URLs without a shell, and keep device calls across a session renewal (#261)

openBrowser: Windows used `cmd /c start`, which parses the URL again, so the login URL's `&` split it and ran the rest as a command (CodeQL: uncontrolled command line). It now uses rundll32, and opens only http(s) URLs.

dcd mcp: renewing a `dcd login` session closed the hosted connection under calls still running, so a long `run` failed with "Connection closed" while the flow carried on. The bridge now keeps one connection and puts the current auth on each request. Calls that arrive together share one connect.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* fix(device): keep the --json envelope when request-human has no reason (#263)

The reason positional was required, so citty refused a missing one before run() and the top-level handler printed { status: 'FAILED', error } instead of { ok, session, data, error }. It is now optional to citty, like every other dcd device positional, and run() rejects it with the usual CliError.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: dcd-release-please[bot] <296541543+dcd-release-please[bot]@users.noreply.github.com>
Co-authored-by: finalerock44 <ethan@devicecloud.dev>
Co-authored-by: finalerock44 <77282157+finalerock44@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant