@@ -2,6 +2,8 @@ import { describe, expect } from "bun:test"
22import { Effect , Layer } from "effect"
33import { Auth } from "../../src/auth"
44import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
5+ import { Credential } from "@opencode-ai/core/credential"
6+ import { IntegrationSchema } from "@opencode-ai/core/integration/schema"
57import { testEffect } from "../lib/effect"
68
79const node = CrossSpawnSpawner . defaultLayer
@@ -74,4 +76,31 @@ describe("Auth", () => {
7476 expect ( after [ "anthropic" ] ) . toBeUndefined ( )
7577 } ) ,
7678 )
79+
80+ it . instance ( "set and remove synchronize with SQLite Credential.Service in real-time" , ( ) =>
81+ Effect . gen ( function * ( ) {
82+ const auth = yield * Auth . Service
83+ const credentials = yield * Credential . Service
84+
85+ // 1. Verify that 'set' on Auth also creates the credential in SQLite
86+ yield * auth . set ( "anthropic-test" , {
87+ type : "api" ,
88+ key : "sk-test-sqlite" ,
89+ metadata : { customField : "test" } ,
90+ } )
91+
92+ const list = yield * credentials . list ( IntegrationSchema . ID . make ( "anthropic-test" ) )
93+ expect ( list . length ) . toBe ( 1 )
94+ expect ( list [ 0 ] . value . type ) . toBe ( "key" )
95+ if ( list [ 0 ] . value . type === "key" ) {
96+ expect ( list [ 0 ] . value . key ) . toBe ( "sk-test-sqlite" )
97+ expect ( list [ 0 ] . value . metadata ?. customField ) . toBe ( "test" )
98+ }
99+
100+ // 2. Verify that 'remove' on Auth also deletes the credential from SQLite
101+ yield * auth . remove ( "anthropic-test" )
102+ const listAfter = yield * credentials . list ( IntegrationSchema . ID . make ( "anthropic-test" ) )
103+ expect ( listAfter . length ) . toBe ( 0 )
104+ } ) ,
105+ )
77106} )
0 commit comments