* docs: add SDK v1.17.12 migration plan — phase 4 (session.permission) * feat(permissions): verify pending permission before auto-accept via SDK v1.17.12 Adds createPermission() and fetchPermission() wrappers on OpencodeService for the new v2.session.permission endpoints (OpenCode SDK 1.17.12). fetchPermission() is used by the auto-accept sweep in resyncBlockingRequestsForDirectory to verify a permission is still pending before replying. The auto-accept flow now skips permissions that are already resolved, returning a null from fetchPermission() rather than blindly calling respondToPermission on a stale entry. createPermission() is exposed for future programmatic permission creation; the V1 list/reply path used by the UI is unchanged. The plan doc at plans/opencode-v1.17.12-sdk/ was rebased onto origin/main in the prior commit to keep the PR diff focused on this change. Closes #1972 * fix(permissions): drop confirmed-resolved permissions from auto-accept resync fetchPermission() now returns a tagged FetchPermissionResult so the auto-accept loop can distinguish a server-confirmed 404 (the permission is no longer pending) from a fetch failure (network error or pre-v1.17.12 server). Previously both cases collapsed to null, so a permission the server had already answered would still appear in the resync output and trigger a spurious 'Permission needed' toast. The auto-accept loop in resyncBlockingRequestsForDirectory now tracks both accepted and resolved permissions, then drops both from the 'grouped' map before it falls through to the toast path. On a pre-v1.17.12 server (no V2 endpoint) the call still returns 'unknown' and the permission stays in the resync output so the user can answer manually — fail-closed, no false-resolved signals. Adds a focused unit test for fetchPermission (4 cases: 200 ok, 404 resolved, 500 unknown, network throw) mocking the V2 SDK client shape. --------- Co-authored-by: bashrusakh <bashrusakh@users.noreply.github.com>
3.0 KiB
3.0 KiB
Todo — OpenCode v1.17.12 SDK Migration
Phase 1: session.interrupt() — server-side abort propagation
- Bump
@opencode-ai/sdkto^1.17.12in allpackage.jsonfiles - Add
session.interrupt()mock tosession-actions.test.ts - Replace
session.abort()→session.interrupt()inabortCurrentOperation()(line 717) - Replace
session.abort()→session.interrupt()inrevertToMessage()(line 910) - Replace
session.abort()→session.interrupt()inunrevertSession()(line 1042) - Add
interruptSession()wrapper toclient.ts(optional) - Run
bun run type-checkinpackages/ui - Run
bun test packages/ui/src/sync/session-actions.test.ts - Manual: verify STOP button aborts session and propagates to provider
Phase 2: session.events() — per-session event stream
- Verify
session.events()exists in SDK v1.17.12 types - Add
subscribeSessionEvents()toclient.ts - Use per-session stream in ChatContainer (reduce global firehose routing)
- Keep global pipeline as fallback for non-active sessions
- Run
bun run type-checkinpackages/ui - Manual: verify events arrive for active session only
Phase 3: Migrate all message operations to Session3 API
Step 1: Switch session.messages() calls from Session2 to Session3 API
- Pass
cursorparam infetchMessages()(use-sync.tsline 326) - Pass
cursorparam inmaterializeSessionFromServer()(sync-context.tsxline 240) - Pass
cursorparam inresyncDirectoryAfterReconnect()(sync-context.tsxline 1207) - Pass
cursorparam inrefetchSessionMessages()(session-actions.tsline 1010) - Pass
cursorparam infetchMessagesForSession()(session-actions.tsline 1147) - Pass
cursorparam ingetSessionMessages()(client.tsline 547) - Remove
directoryparam from per-call args (set at client creation via scoped client) - Replace
beforeparam withcursor
Step 2: Add session.message() on the same Session3 API
- Add
getMessage()wrapper toclient.tsusingSession3.message() - Use in
revertToMessage()as fallback when message not in store - Use in
forkFromMessage()as fallback when message not in store
Validation
- Run
bun run type-checkinpackages/ui - Manual: load a session with 100+ messages, scroll up — smooth, no jank
- Manual: revert an evicted session — works without full history load
Phase 4: session.permission — programmatic endpoints
- Verify
session.permission.create/fetchexist in SDK v1.17.12 - Add wrappers to
client.ts - Use in permission auto-accept flow (
sync-context.tsxline 1118-1143) - Run
bun run type-checkinpackages/ui - Manual: verify permission create/fetch flow
Blockers
- SDK v1.17.12 must be published and installable
session.events()andsession.permissionmust be confirmed in SDK typesSession3API compatibility with currentSession2usage must be verified