Archived
Relay issue-62-authstorage: leg 4 handoff (slice 3 complete)
This commit is contained in:
@@ -213,3 +213,53 @@ ts`(6) slice 4; test/support files slice 5.
|
|||||||
|
|
||||||
**Handoff:** spawning leg 4 (slice 3, oauthLoginFlowService.ts). Sessiond
|
**Handoff:** spawning leg 4 (slice 3, oauthLoginFlowService.ts). Sessiond
|
||||||
restart from leg 2 still pending — carried forward, not cleared.
|
restart from leg 2 still pending — carried forward, not cleared.
|
||||||
|
|
||||||
|
## Leg 4 — slice 3: oauthLoginFlowService.ts migration (commit `1c3d6db`)
|
||||||
|
|
||||||
|
**What:** Reimplemented `OAuthLoginFlowService` against the pi-ai
|
||||||
|
`AuthInteraction` contract and rewrote its test.
|
||||||
|
|
||||||
|
- `start()` now takes `runtime: Pick<ModelRuntime, "login">` instead of
|
||||||
|
`authStorage: Pick<AuthStorage, "login">`; login driven via
|
||||||
|
`runtime.login(providerId, "oauth", interaction)`. Resolves the
|
||||||
|
`authService.ts` line-83 tsc error (authService.ts now at 0 errors).
|
||||||
|
- Built a single `AuthInteraction` adapter (`{ signal, prompt, notify }`)
|
||||||
|
replacing the six `OAuthLoginCallbacks` (`onAuth`/`onDeviceCode`/`onPrompt`/
|
||||||
|
`onManualCodeInput`/`onSelect`/`onProgress`).
|
||||||
|
- **Mapping decisions (verified carefully — riskiest slice):**
|
||||||
|
- `prompt(AuthPrompt)` dispatches on `type`: `select` → `waitForSelect`
|
||||||
|
(options `{id,label,description?}` → CommandOption `{value:id,label}`,
|
||||||
|
resolves chosen id); `manual_code` → web-UI prompt kind `manual`;
|
||||||
|
`text`/`secret` → web-UI prompt kind `prompt`. Old code special-cased
|
||||||
|
`onManualCodeInput` with a hardcoded message; now the provider supplies the
|
||||||
|
`manual_code` message, which is more correct.
|
||||||
|
- `notify(AuthEvent)`: `auth_url` → `auth:{url,instructions?}`; `device_code`
|
||||||
|
→ reuse `auth` field (`url: verificationUri`, instructions
|
||||||
|
`"Enter code: <userCode>"`) exactly as the old `onDeviceCode` did;
|
||||||
|
`info`+`progress` → append `message` to `progress` (old code only had
|
||||||
|
`onProgress`; `info` folds in naturally).
|
||||||
|
- Old `OAuthPrompt.allowEmpty`/`placeholder` handling: the new `AuthPrompt`
|
||||||
|
has no `allowEmpty`, so interactive prompts are always required
|
||||||
|
(`allowEmpty:false`); `select` keeps `allowEmpty:true`. Placeholder still
|
||||||
|
forwarded when present.
|
||||||
|
- **New behavior:** per-prompt `AuthPrompt.signal` now aborts just that pending
|
||||||
|
request (rejects `"Prompt cancelled"`, clears the interaction from state)
|
||||||
|
without ending the overall flow — the documented `manual_code`-vs-callback
|
||||||
|
race. Added `bindPromptSignal` + a dedicated test for it.
|
||||||
|
- **Test:** rewrote `oauthLoginFlowService.test.ts` with a `fakeRuntime`
|
||||||
|
`login` double (returns a stub oauth credential). Replaced the old
|
||||||
|
device-code-via-onDeviceCode coverage with an explicit `notify` device_code
|
||||||
|
test and a per-prompt-signal-abort test. 9 tests pass; both files lint clean.
|
||||||
|
|
||||||
|
**tsc:** 28 → 26 errors. `authService.ts` = 0. Remaining: slice 4
|
||||||
|
(`sessiond.ts` 1, `piSessionService.ts` 6) and slice 5 test/support files
|
||||||
|
(`authService.test.ts` 10, `.testSupport.ts` 3, `.promptQueue.test.ts` 2,
|
||||||
|
`.warnings.test.ts` 4).
|
||||||
|
|
||||||
|
**Status:** updated (current position, leg tracking → last leg 4 / next leg 5,
|
||||||
|
next task = slice 4). Committed with `--no-verify` (migration not yet
|
||||||
|
verify-green, per charter).
|
||||||
|
|
||||||
|
**Blockers:** none. Sessiond-restart-pending note still ACTIVE (unchanged;
|
||||||
|
this slice did not touch the daemon path, but slice 1 did). Handing off to
|
||||||
|
leg 5 (slice 4).
|
||||||
|
|||||||
@@ -1,6 +1,31 @@
|
|||||||
# Relay status — issue-62-authstorage
|
# Relay status — issue-62-authstorage
|
||||||
|
|
||||||
## Current position
|
## Current position
|
||||||
|
Slice 3 (`oauthLoginFlowService.ts` migration) complete and committed (`1c3d6db`).
|
||||||
|
`OAuthLoginFlowService` is reimplemented against the pi-ai `AuthInteraction`
|
||||||
|
contract (`{ signal?, prompt(AuthPrompt), notify(AuthEvent) }`); the old
|
||||||
|
`OAuthLoginCallbacks`/`AuthStorage` imports are gone. `start()` now takes a
|
||||||
|
`ModelRuntime` (narrowed to `Pick<ModelRuntime, "login">`) instead of
|
||||||
|
`authStorage`, and drives login via `runtime.login(providerId, "oauth",
|
||||||
|
interaction)`. Mapping: `AuthPrompt` `text`/`secret`/`manual_code` → web-UI
|
||||||
|
`prompt` (kind `prompt`, `manual_code` → kind `manual`); `select` → web-UI
|
||||||
|
`select` (options `{id,label}` → `{value,label}`, returns chosen id);
|
||||||
|
`AuthEvent` `auth_url` → `auth: {url, instructions?}`; `device_code` → reuse
|
||||||
|
`auth` field (`url: verificationUri`, `instructions: "Enter code: <userCode>"`);
|
||||||
|
`info`/`progress` → append `message` to `progress`. Per-prompt
|
||||||
|
`AuthPrompt.signal` now aborts just that pending request (rejects
|
||||||
|
`"Prompt cancelled"`) without ending the overall flow — needed because a
|
||||||
|
`manual_code` prompt can race a callback server. `oauthLoginFlowService.test.ts`
|
||||||
|
rewritten to the new contract via a `fakeRuntime` login double; **9 tests pass**,
|
||||||
|
files lint clean.
|
||||||
|
|
||||||
|
`npx tsc --noEmit` now reports **26 errors** (down from 28). `authService.ts`
|
||||||
|
is now at **0 errors** (as predicted). Remaining errors are all slice 4/5:
|
||||||
|
`sessiond.ts` (1) + `piSessionService.ts` (6) = slice 4;
|
||||||
|
`authService.test.ts` (10), `piSessionService.testSupport.ts` (3),
|
||||||
|
`.promptQueue.test.ts` (2), `.warnings.test.ts` (4) = slice 5.
|
||||||
|
|
||||||
|
### Prior position (slice 2, leg 3, commit `d09d7cc`)
|
||||||
Slice 2 (`authProviderOptions.ts` migration) complete and committed (`d09d7cc`).
|
Slice 2 (`authProviderOptions.ts` migration) complete and committed (`d09d7cc`).
|
||||||
`authProviderOptions.ts` now derives options from a runtime-shaped
|
`authProviderOptions.ts` now derives options from a runtime-shaped
|
||||||
`AuthProviderRuntime` interface (`getProviders()` + `listCredentials()` +
|
`AuthProviderRuntime` interface (`getProviders()` + `listCredentials()` +
|
||||||
@@ -51,40 +76,34 @@ Remaining errors otherwise live in slices 2/3/4 files and all test/support
|
|||||||
files (slice 5).
|
files (slice 5).
|
||||||
|
|
||||||
## Leg tracking
|
## Leg tracking
|
||||||
- **Last completed leg:** 3 (slice 2 — authProviderOptions.ts migration).
|
- **Last completed leg:** 4 (slice 3 — oauthLoginFlowService.ts migration).
|
||||||
- **Next leg to run:** 4.
|
- **Next leg to run:** 5.
|
||||||
|
|
||||||
## Next task
|
## Next task
|
||||||
Run **charter slice 3 (`oauthLoginFlowService.ts` migration)** as leg 4. This
|
Run **charter slice 4 (`piSessionService.ts` migration)** as leg 5. Concretely
|
||||||
is the riskiest slice — verify the prompt/select/device-code/auth_url mapping
|
(see assessment §5.4 and §3.3):
|
||||||
carefully. Concretely:
|
- Pass `modelRuntime` to `createAgentSessionServices` (instead of the old
|
||||||
- Reimplement `oauthLoginFlowService.ts` against the pi-ai `AuthInteraction`
|
`modelRegistry`); update the `PiAgentSession` type accordingly.
|
||||||
contract (`{ signal?, prompt(prompt: AuthPrompt): Promise<string>,
|
- `sessiond.ts` already passes `modelRuntime: auth.runtime` into
|
||||||
notify(event: AuthEvent): void }`) instead of the removed
|
`PiSessionService` (from slice 1) but `PiSessionServiceDependencies` still
|
||||||
`OAuthLoginCallbacks` shape (`onAuth`/`onDeviceCode`/`onPrompt`/
|
declares `modelRegistry` — reconcile the dependency shape so the sessiond
|
||||||
`onManualCodeInput`/`onSelect`/`onProgress`). Types live in
|
wiring typechecks (this is the remaining `sessiond.ts` error).
|
||||||
`node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts`.
|
- Switch `anthropicSubscriptionWarning` to `readStoredCredential(providerId,
|
||||||
- `AuthPrompt` is a discriminated union: `text` / `secret` / `select`
|
authPath?)` (the sync credential read replacing the old AuthStorage-based
|
||||||
(`options: { id, label, description? }[]`, returns the chosen option id) /
|
read).
|
||||||
`manual_code`. `AuthEvent` is `info` / `auth_url` (`{ url, instructions? }`)
|
- Target: after slice 4, `sessiond.ts` and `piSessionService.ts` reach 0
|
||||||
/ `device_code` (`{ userCode, verificationUri, intervalSeconds?,
|
errors; only the test/support files (slice 5) remain.
|
||||||
expiresInSeconds? }`) / `progress`. Map these onto the existing web-UI flow
|
- **Note:** `piSessionService.ts` is a session-daemon path — keep the
|
||||||
state fields (see the current `oauthLoginFlowService.ts` prompt/select/
|
sessiond-restart-pending note current (it is already active from slice 1).
|
||||||
device-code/auth_url handling).
|
|
||||||
- Change `OAuthLoginFlowService.start` to accept `runtime` (the
|
|
||||||
`ModelRuntime`) instead of `authStorage`, and drive login via
|
|
||||||
`runtime.login(providerId, "oauth", interaction)` where `interaction` is the
|
|
||||||
adapter you build. `authService.ts` already calls
|
|
||||||
`OAuthLoginFlowService.start({ ..., runtime: this.runtime })` (this is the
|
|
||||||
line-83 tsc error). Also update `oauthLoginFlowService.test.ts`.
|
|
||||||
- After slice 3, `authService.ts` should reach 0 errors. `sessiond.ts` +
|
|
||||||
`piSessionService.ts` (slice 4) and the remaining test/support files
|
|
||||||
(slice 5) stay until their slices.
|
|
||||||
|
|
||||||
If slice 3 is already done when you arrive, apply the charter's task-selection
|
Then slice 5 migrates all test doubles to `InMemoryCredentialStore` +
|
||||||
policy: pick the lowest-numbered incomplete slice (4 → 6). Slice 4 unblocks the
|
`ModelRuntime.create` and gets `npm run verify` green (currently the failing
|
||||||
remaining `sessiond.ts` / `piSessionService.ts` cross-slice errors; slice 5
|
test/support files are `authService.test.ts` (10), `piSessionService.testSupport.ts`
|
||||||
finalizes tests; slice 6 adds the changeset + final verify.
|
(3), `.promptQueue.test.ts` (2), `.warnings.test.ts` (4)); slice 6 adds the
|
||||||
|
changeset + final verify + cleanup.
|
||||||
|
|
||||||
|
If slice 4 is already done when you arrive, apply the charter's task-selection
|
||||||
|
policy: pick the lowest-numbered incomplete slice (5 → 6).
|
||||||
|
|
||||||
### Build/tooling note (important for every leg)
|
### Build/tooling note (important for every leg)
|
||||||
**Update (leg 2):** the human reports `/tmp` is now fully usable again, so the
|
**Update (leg 2):** the human reports `/tmp` is now fully usable again, so the
|
||||||
|
|||||||
Reference in New Issue
Block a user