Skip to content

Promote develop to main for the SDK publish path - #57

Merged
its-janghoon merged 8 commits into
mainfrom
develop
Sep 22, 2026
Merged

its-janghoon merged 8 commits into
mainfrom
develop

Conversation

@its-janghoon

Copy link
Copy Markdown
Contributor

Four PRs, all about getting @redrob-labs/sdk onto the registry. No shipped CLI behaviour changes — the binaries in v0.4.1 are unaffected.

  • #53 — a publish path, deliberately separate from release.yml. That workflow reaches the Apple and Windows signing credentials; a token problem there would turn a signed binary release red after the artifacts are out. It happened twice here and the releases were untouched.
  • #54 — the dry run was packing 0.0.0 because it invoked bun pm pack directly and skipped the script holding the version injection. A rehearsal that bypasses the code it rehearses is not one.
  • #55 — records that EOTP means the token authenticated but is not 2FA-exempt, and upgrades the pre-flight check from "non-empty string" to npm whoami. The old check passed and was followed by a publish that failed on auth policy, which is worse than no check.
  • #56 — the package is @redrob-labs/sdk. @redrob-code is not an npm organisation; @redrob-labs is. An npm name is its registry identity, and a workspace link resolves by name, so 121 files moved with it. The eighteen private siblings keep @redrob-code/* — they never face the registry.

@redrob-labs/sdk@0.4.1 is published and consumed by cowork #59.

typecheck        0 errors across the monorepo
packages/core    974 pass / 0 fail
packages/redrob  3380 pass / 0 fail
httpapi gate     pass=210 fail=0 skip=0 missing=0

its-janghoon and others added 8 commits September 22, 2026 01:37
…e signing release

The SDK has never been published. `publish.ts` was already written and complete;
nothing called it, and `release.yml` mentions npm nowhere. So a consumer outside
this repository cannot depend on the fork's own SDK at all -- which is why the
desktop app still consumes the upstream `@opencode-ai/sdk` and cannot see types
added here.

A separate workflow rather than a step in `release.yml`, deliberately. That
workflow reaches the Apple and Windows signing credentials, and bolting an npm
publish onto it means a missing or expired token turns a signed binary release red
AFTER the artifacts are already out. Here a token problem fails one run that has
published nothing else.

`workflow_dispatch` only, dry-run by default. The first publish of a public
package under this scope is not reversible: npm allows unpublishing a new version
only within 72 hours, and a name once taken stays taken.

The version comes from the release, not from `package.json`, which holds `0.0.0`
on purpose. This package is generated from the CLI's own API surface, so a version
committed beside it would be a second number to bump and would drift from the CLI
it describes. Taking it from the release tag also makes an SDK build answerable --
a consumer can tell which CLI generated it -- and `publish.ts` restores the file
afterwards, so a release leaves no diff behind.

The repository-id guard matches `release.yml`: a fork must never publish under
this scope, and a rename must not silently switch the guard off.
Add a publish path for @redrob-code/sdk, separate from the signing release
The first dry run proved the build and the pack and nothing about the version,
which is the part most likely to be wrong. It invoked `bun pm pack` directly and
so skipped `publish.ts` entirely -- where the version injection lives -- and packed
the committed `0.0.0`. The tarball said `redrob-code-sdk-0.0.0.tgz` and the run was
green.

A rehearsal that bypasses the code it is rehearsing is not one. Both modes now run
the same script, which stops only at the registry call.

Verified locally: `REDROB_VERSION=0.4.1` with the dry-run flag packs
`redrob-code-sdk-0.4.1.tgz`, restores `package.json` to `0.0.0` afterwards, and the
tarball's `dist/v2/gen/types.gen.d.ts` carries the `blocked` session status -- which
is the variant the desktop app currently has to declare structurally because no
published package contains it.
…-real-path

Make the publish dry run walk the real path
…uthenticates

The first real run got as far as "Publishing to registry.npmjs.org" and then failed
with `EOTP: This operation requires a one-time password`. So the token authenticated
fine; what it is not is exempt from the two-factor requirement npm enforces on
publish. Only a classic AUTOMATION token or a granular access token with write on
the scope is -- a classic "Publish" token still prompts.

There is no workflow-side fix, which is the point of the exemption: CI cannot supply
an interactive one-time password. Recorded at the top of the workflow so the next
person does not spend a run discovering it.

The pre-flight check now runs `npm whoami` rather than testing for a non-empty
string. The old check passed and was followed by a publish that failed on auth --
worse than no check, because a green step implied the credential was good. `whoami`
still cannot prove 2FA exemption, so the message says so instead of claiming the
credential is fine.
…uirements

Record why the first SDK publish failed, and check the token authenticates
…ctually owns

The first real publish authenticated, reached "Publishing to registry.npmjs.org"
and failed with `404 Not Found - PUT ... @redrob-code%2fsdk - Scope not found`.
`@redrob-code` is not an npm organisation; `@redrob-labs` is, and it is the one
this repository belongs to.

An npm package's name IS its registry identity, so there is no way to publish
under a scope while calling it something else -- the name has to change, and a
workspace link resolves by name, so every importer changes with it.

Only this package is constrained. The eighteen sibling workspace packages keep
`@redrob-code/*`: they are private and never face the registry, so their scope is
unconstrained and renaming them would be churn for no gain. `@redrob-code/sdk-next`
in particular is a DIFFERENT package and deliberately untouched, which is why the
replacement carries a negative lookahead rather than matching a prefix.

Scoped to `git ls-files` rather than a directory. A first pass covered `packages/`
only and `bun install` then failed with `Workspace dependency "@redrob-code/sdk"
not found`, because the root `package.json`, the separate `github/` workspace and
both lockfiles sit outside it.

Verified end to end: install relinks the workspace, the monorepo typechecks at 0,
core is 974/974, redrob is 3380/3380, the HttpApi exerciser is 210/210, and a dry
run packs `redrob-labs-sdk-0.4.1.tgz` and restores `package.json` to `0.0.0`.
…labs-scope

Publish as @redrob-labs/sdk, the scope the organisation actually owns
@its-janghoon
its-janghoon merged commit 64abeb0 into main Sep 22, 2026
29 checks passed
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.

1 participant