Skip to content

feat: Add WizardAdapter for mounting on CLI - #11

Merged
razor-x merged 6 commits into
mainfrom
claude/wizard-host-interface-4njgxv
Aug 12, 2026
Merged

feat: Add WizardAdapter for mounting on CLI#11
razor-x merged 6 commits into
mainfrom
claude/wizard-host-interface-4njgxv

Conversation

@razor-x

@razor-x razor-x commented Aug 12, 2026

Copy link
Copy Markdown
Member

Summary

The wizard needs two things it cannot decide for itself: the developer's Seam login, and somewhere to keep what it learns about a project. Both belong to whoever mounts it — the Seam CLI owns the login and owns where files go.

This states the shape of that answer and accepts it, and does nothing else. Split out of #7 so that seamapi/cli#614 can be built and released against it without waiting on the change that puts it to use.

The contract

export interface WizardAuth {
  endpoint: string
  apiKey: string | null
  workspaceId: string | null
}

export interface StorageAdapter {
  get: (key: string) => Promise[unknown]
  set: (key: string, value: unknown) => Promise[void]
}

export interface WizardAdapter {
  getAuth: () => Promise[WizardAuth]
  config: StorageAdapter
  state: StorageAdapter
}

await wizard({ argv, commandName: 'seam wizard', adapter })

The wizard picks the keys, the adapter picks the files. Values are plain JSON and hold no secrets.

apiKey is a workspace API key or null: it is the only credential the wizard uses, and the only kind a project's SEAM_API_KEY may be, so a personal access token is never passed at all.

Given no adapter, an in-memory one is used: every step works and nothing outlives the run.

Nothing reads it yet

Deliberately additive. Behaviour is unchanged: .seam/onboarding.json is still written, and an adapter passed in is accepted, its auth loaded once, and otherwise unused until #7 lands. So this can be released on its own, and the CLI can depend on it, before anything about the wizard's storage moves.

Changed

  • New lib/adapter.ts — the interfaces, the in-memory default, and the run's adapter.
  • lib/wizard.ts — an adapter option, installed before the run and asked for its auth once. --help and --version ask it nothing.
  • lib/index.ts — exports the three types. Nothing else is added to the package surface.

78 tests, 16 of them new: the in-memory default, replacing the adapter, the auth being asked for exactly once, and it being forgotten when the adapter changes.

The wizard needs two things it cannot decide for itself: the developer's
Seam login, and somewhere to keep what it learns about a project. Both
belong to whoever mounts it — the Seam CLI owns the login, and owns where
files go — so this is the shape of the answer.

Nothing reads the host yet. It is stated and accepted here on its own, so
that the CLI can be built against it without waiting on the change that
puts it to use.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCJ1v1NFc6b43GooAhij2c
claude added 2 commits August 12, 2026 00:42
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCJ1v1NFc6b43GooAhij2c
'Host' reads as a URL, which is the one thing it is not: it is whoever
mounts the wizard, answering for what the wizard cannot decide. And the
Seam API address is an endpoint everywhere else, including the environment
variable that overrides it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCJ1v1NFc6b43GooAhij2c
@razor-x razor-x changed the title Take a host, for whoever mounts the wizard to answer with Take an adapter, for whoever mounts the wizard to answer with Aug 12, 2026
claude added 2 commits August 12, 2026 04:04
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCJ1v1NFc6b43GooAhij2c
The adapter reported which kind of credential the CLI held so the wizard
could decide what to do with it. The wizard only ever uses an API key, so
the CLI hands over one or hands over nothing, and the enum goes with it.

endpointSource goes the same way, and WizardValues is named for what it is.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCJ1v1NFc6b43GooAhij2c
@razor-x razor-x changed the title Take an adapter, for whoever mounts the wizard to answer with feat: Add WizardAdapter for mounting on CLI Aug 12, 2026
It is the default the wizard falls back to and the one its own tests set.
Nothing outside imports it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCJ1v1NFc6b43GooAhij2c
@razor-x
razor-x merged commit 630e105 into main Aug 12, 2026
11 checks passed
@razor-x
razor-x deleted the claude/wizard-host-interface-4njgxv branch August 12, 2026 04:18
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.

2 participants