@vymalo/opencode-lightbridge 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/opencode.js +163 -12
- package/dist/opencode.js.map +1 -1
- package/dist/plugin.d.ts +33 -7
- package/dist/plugin.js +20 -5
- package/dist/plugin.js.map +1 -1
- package/dist/sign-in.d.ts +70 -0
- package/dist/sign-in.js +152 -0
- package/dist/sign-in.js.map +1 -0
- package/package.json +4 -4
package/dist/opencode.js
CHANGED
|
@@ -2,6 +2,7 @@ import { hostname } from "node:os";
|
|
|
2
2
|
import { Plugin } from "@opencode/plugin/effect";
|
|
3
3
|
import { defaultTextMapSetter } from "@opentelemetry/api";
|
|
4
4
|
import { W3CTraceContextPropagator } from "@opentelemetry/core";
|
|
5
|
+
import { isInteractiveAuthRequiredError } from "@vymalo/opencode-auth-core/lib";
|
|
5
6
|
import { buildResource, createProviders, deferredAttribute, describeError, readVcsInfo, registerExitHandlers, resolveOtelConfig, TelemetryRecorder } from "@vymalo/opencode-core-otel";
|
|
6
7
|
import { applyResponsesApiSettings, mergeDiscoveredModels, propagateCachedBearer, ProviderModelSyncEngine, resolveCachedBearer, resolveProviderPackage, upsertManagedProvider } from "@vymalo/opencode-provider-sync/lib";
|
|
7
8
|
import { Effect, Stream } from "effect";
|
|
@@ -9,6 +10,7 @@ import { hasOAuth2Conflict, needsProjectToken, parseLightbridgeOptions } from ".
|
|
|
9
10
|
import { captureHostContext, createEffectLogger, DEFAULT_LOG_LEVEL, resolveLogLevel, runInHost } from "./logging.js";
|
|
10
11
|
import { adaptContext, adaptPermission, adaptPrompt, adaptToolAfter, adaptToolBefore, OtelEventAdapter } from "./otel-adapter.js";
|
|
11
12
|
import { LightbridgeRuntime, ROOT_CACHE_NAMESPACE, ROOT_CACHE_SEGMENT, rootCacheDir, rootStateDir } from "./plugin.js";
|
|
13
|
+
import { createSignInRegistration, createSignInRequiredNotifier, signInPath } from "./sign-in.js";
|
|
12
14
|
/** Stable plugin id. v2 requires one and keys storage/registrations by it. */
|
|
13
15
|
export const PLUGIN_ID = "vymalo.lightbridge";
|
|
14
16
|
function errorMessage(error) {
|
|
@@ -36,13 +38,16 @@ function safeHostname() {
|
|
|
36
38
|
* every export attempt, a later successful login resumes exporting on the
|
|
37
39
|
* next flush with nothing to restart.
|
|
38
40
|
*/
|
|
39
|
-
function createRuntimeTokenSource(runtime) {
|
|
41
|
+
function createRuntimeTokenSource(runtime, onSignInRequired) {
|
|
40
42
|
return {
|
|
41
43
|
headers: async () => {
|
|
42
44
|
try {
|
|
43
|
-
const token = await runtime.getProjectToken(
|
|
45
|
+
const token = await runtime.getProjectToken();
|
|
44
46
|
return { Authorization: `${token.tokenType || "Bearer"} ${token.accessToken}` };
|
|
45
|
-
} catch {
|
|
47
|
+
} catch (error) {
|
|
48
|
+
if (isInteractiveAuthRequiredError(error)) {
|
|
49
|
+
onSignInRequired("otel");
|
|
50
|
+
}
|
|
46
51
|
return undefined;
|
|
47
52
|
}
|
|
48
53
|
},
|
|
@@ -128,7 +133,7 @@ function warnIfTokenCommandConfigIgnored(otel, env, logger) {
|
|
|
128
133
|
* handlers. Mirrors `@vymalo/opencode-otel`'s orchestration verbatim, minus
|
|
129
134
|
* the standalone `tokenCommand` seam.
|
|
130
135
|
*/
|
|
131
|
-
async function buildOtelModule(location, otelConfig, logger, factoryOptions, runtime) {
|
|
136
|
+
async function buildOtelModule(location, otelConfig, logger, factoryOptions, runtime, onSignInRequired) {
|
|
132
137
|
const version = deferredAttribute(factoryOptions.deferredTimeoutMs);
|
|
133
138
|
const branch = deferredAttribute(factoryOptions.deferredTimeoutMs);
|
|
134
139
|
if (factoryOptions.hostInfo?.version) {
|
|
@@ -147,7 +152,7 @@ async function buildOtelModule(location, otelConfig, logger, factoryOptions, run
|
|
|
147
152
|
branch: branch.value,
|
|
148
153
|
vcs
|
|
149
154
|
});
|
|
150
|
-
const tokenSource = runtime ? createRuntimeTokenSource(runtime) : undefined;
|
|
155
|
+
const tokenSource = runtime ? createRuntimeTokenSource(runtime, onSignInRequired) : undefined;
|
|
151
156
|
const providers = createProviders(otelConfig, resource, logger, factoryOptions.exporters, tokenSource);
|
|
152
157
|
const recorder = new TelemetryRecorder({
|
|
153
158
|
providers,
|
|
@@ -248,7 +253,10 @@ export function createLightbridgePlugin(factoryOptions = {}) {
|
|
|
248
253
|
// and the OTEL token source below. `undefined` only for a register/auth-only
|
|
249
254
|
// config.
|
|
250
255
|
const buildRuntime = factoryOptions.runtimeFactory ?? ((auth, pid, options) => new LightbridgeRuntime(auth, pid, options));
|
|
251
|
-
|
|
256
|
+
// Built whenever a module needs a token OR the user must be able to sign in
|
|
257
|
+
// (device_code, ADR-0023): the sign-in method drives this same runtime.
|
|
258
|
+
const signInEnabled = parsed.auth.authFlow === "device_code";
|
|
259
|
+
const sharedRuntime = wantsProjectToken || signInEnabled ? buildRuntime(parsed.auth, parsed.projectId, {
|
|
252
260
|
logger,
|
|
253
261
|
fetchImpl: factoryOptions.fetchImpl,
|
|
254
262
|
onAuthorizationUrl: factoryOptions.onAuthorizationUrl,
|
|
@@ -257,6 +265,16 @@ export function createLightbridgePlugin(factoryOptions = {}) {
|
|
|
257
265
|
exchange: parsed.gateway?.exchange ?? false
|
|
258
266
|
}) : undefined;
|
|
259
267
|
const reloadProviders = () => runInHost(hostContext, ctx.provider.reload());
|
|
268
|
+
const signInName = parsed.register?.name ?? parsed.auth.id;
|
|
269
|
+
const signInNotice = createSignInRequiredNotifier(logger, signInName);
|
|
270
|
+
// Only meaningful when the Connect dialog can actually be used to fix it.
|
|
271
|
+
const notifySignInRequired = (source) => {
|
|
272
|
+
if (signInEnabled) {
|
|
273
|
+
signInNotice.notify(source);
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
// Set below when sign-in is registered; the gateway hook calls it (cached).
|
|
277
|
+
let observeConnectionCached = async () => {};
|
|
260
278
|
// ---- register module (ADR-0017 requirement 1) ----
|
|
261
279
|
let engine;
|
|
262
280
|
let registerChain = Promise.resolve();
|
|
@@ -281,6 +299,9 @@ export function createLightbridgePlugin(factoryOptions = {}) {
|
|
|
281
299
|
servers: [buildRegisterServerConfig(parsed.auth, register)],
|
|
282
300
|
cacheNamespace: ROOT_CACHE_NAMESPACE
|
|
283
301
|
}, {
|
|
302
|
+
// Sign-in happens only in the host's Connect dialog (ADR-0023): the
|
|
303
|
+
// engine's warmup, scheduler and token reads are refresh-only.
|
|
304
|
+
neverInteractive: true,
|
|
284
305
|
logger,
|
|
285
306
|
fetchImpl: factoryOptions.fetchImpl,
|
|
286
307
|
onAuthorizationUrl: factoryOptions.onAuthorizationUrl,
|
|
@@ -301,6 +322,17 @@ export function createLightbridgePlugin(factoryOptions = {}) {
|
|
|
301
322
|
}
|
|
302
323
|
engine = next;
|
|
303
324
|
registerBearer = await resolveCachedBearer(parsed.auth.id, next, logger);
|
|
325
|
+
if (registerBearer === undefined && sharedRuntime) {
|
|
326
|
+
// resolveCachedBearer swallows why; ask the runtime so only a genuine
|
|
327
|
+
// "needs sign-in" (not a network/IdP outage) raises the notice.
|
|
328
|
+
try {
|
|
329
|
+
await sharedRuntime.ensureRootToken();
|
|
330
|
+
} catch (error) {
|
|
331
|
+
if (isInteractiveAuthRequiredError(error)) {
|
|
332
|
+
notifySignInRequired("register");
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
304
336
|
// Models and bearer are now known: ask the host to re-run transforms.
|
|
305
337
|
await reloadProviders();
|
|
306
338
|
};
|
|
@@ -355,6 +387,116 @@ export function createLightbridgePlugin(factoryOptions = {}) {
|
|
|
355
387
|
}
|
|
356
388
|
});
|
|
357
389
|
}
|
|
390
|
+
// ---- sign-in (ADR-0023): the ONLY place an interactive login can start ----
|
|
391
|
+
if (signInEnabled && sharedRuntime) {
|
|
392
|
+
const runtime = sharedRuntime;
|
|
393
|
+
const afterSignIn = async () => {
|
|
394
|
+
try {
|
|
395
|
+
// Pick up the new credential in the register module's engine and
|
|
396
|
+
// refresh the stamped bearer, then ask the host to re-run transforms.
|
|
397
|
+
if (engine) {
|
|
398
|
+
await engine.syncServer(parsed.auth.id);
|
|
399
|
+
registerBearer = await resolveCachedBearer(parsed.auth.id, engine, logger);
|
|
400
|
+
}
|
|
401
|
+
} catch (error) {
|
|
402
|
+
logger.warn("lightbridge_sign_in_sync_failed", { error: errorMessage(error) });
|
|
403
|
+
}
|
|
404
|
+
try {
|
|
405
|
+
await reloadProviders();
|
|
406
|
+
} catch (error) {
|
|
407
|
+
logger.warn("lightbridge_sign_in_reload_failed", { error: errorMessage(error) });
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
const registration = createSignInRegistration({
|
|
411
|
+
integrationID: parsed.auth.id,
|
|
412
|
+
runtime,
|
|
413
|
+
logger,
|
|
414
|
+
afterSignIn,
|
|
415
|
+
onSignedIn: () => signInNotice.reset(),
|
|
416
|
+
onSignInRequired: notifySignInRequired
|
|
417
|
+
});
|
|
418
|
+
// The integration id is `auth.id`, never the well-known URL's: the host
|
|
419
|
+
// loads the well-known manifest with `credentials.at(-1)` of ITS
|
|
420
|
+
// integration, and an oauth credential there would freeze it (ADR-0023).
|
|
421
|
+
yield* ctx.integration.transform((editor) => {
|
|
422
|
+
editor.update(parsed.auth.id, (integration) => {
|
|
423
|
+
integration.name = signInName;
|
|
424
|
+
});
|
|
425
|
+
editor.method.update(registration);
|
|
426
|
+
});
|
|
427
|
+
// ---- host disconnect => sign out (ADR-0023) ----
|
|
428
|
+
// TRANSITION-based: only a connection we saw present in THIS process and
|
|
429
|
+
// that is then gone signs us out. A host with no credential at startup is
|
|
430
|
+
// normal (users who signed in before sign-in moved into the dialog have a
|
|
431
|
+
// token and no host credential) and must keep working.
|
|
432
|
+
let connectionSeen = false;
|
|
433
|
+
let signingOut = false;
|
|
434
|
+
let lastObservedAt = 0;
|
|
435
|
+
const OBSERVE_CACHE_MS = 5e3;
|
|
436
|
+
const signOut = async () => {
|
|
437
|
+
logger.info("lightbridge_signed_out_by_host", { integrationID: parsed.auth.id });
|
|
438
|
+
try {
|
|
439
|
+
await runtime.reset();
|
|
440
|
+
} catch (error) {
|
|
441
|
+
logger.warn("lightbridge_sign_out_reset_failed", { error: errorMessage(error) });
|
|
442
|
+
}
|
|
443
|
+
// The engine keeps its token in memory even when the file is gone:
|
|
444
|
+
// drop it, and let the next transform build a fresh (signed-out) one.
|
|
445
|
+
stopEngine();
|
|
446
|
+
registerQueued = false;
|
|
447
|
+
signInNotice.reset();
|
|
448
|
+
notifySignInRequired("disconnect");
|
|
449
|
+
try {
|
|
450
|
+
await reloadProviders();
|
|
451
|
+
} catch (error) {
|
|
452
|
+
logger.warn("lightbridge_sign_out_reload_failed", { error: errorMessage(error) });
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
const onConnection = async (present) => {
|
|
456
|
+
if (present) {
|
|
457
|
+
connectionSeen = true;
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
if (!connectionSeen || signingOut) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
connectionSeen = false;
|
|
464
|
+
signingOut = true;
|
|
465
|
+
try {
|
|
466
|
+
await signOut();
|
|
467
|
+
} finally {
|
|
468
|
+
signingOut = false;
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
const observeConnection = (force) => {
|
|
472
|
+
if (!force && Date.now() - lastObservedAt < OBSERVE_CACHE_MS) {
|
|
473
|
+
return Promise.resolve();
|
|
474
|
+
}
|
|
475
|
+
lastObservedAt = Date.now();
|
|
476
|
+
return runInHost(hostContext, ctx.integration.connection.active(parsed.auth.id).pipe(Effect.flatMap((info) => Effect.promise(() => onConnection(info !== undefined))), Effect.ignore));
|
|
477
|
+
};
|
|
478
|
+
observeConnectionCached = () => observeConnection(false);
|
|
479
|
+
yield* Effect.forkScoped(Stream.runForEach(ctx.event.subscribe({ types: [
|
|
480
|
+
"credential.updated",
|
|
481
|
+
"credential.switched",
|
|
482
|
+
"integration.updated"
|
|
483
|
+
] }), () => Effect.promise(() => observeConnection(true))).pipe(Effect.tapError((error) => Effect.sync(() => logger.warn("lightbridge_connection_watch_failed", { error: errorMessage(error) }))), Effect.ignore));
|
|
484
|
+
void observeConnection(true);
|
|
485
|
+
// Report a missing sign-in once, up front, without any network on the
|
|
486
|
+
// signed-out path (a stored token may refresh, which is fine).
|
|
487
|
+
void runtime.ensureRootToken().catch((error) => {
|
|
488
|
+
if (isInteractiveAuthRequiredError(error)) {
|
|
489
|
+
notifySignInRequired("startup");
|
|
490
|
+
} else {
|
|
491
|
+
logger.debug("lightbridge_startup_token_check_failed", { error: errorMessage(error) });
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
} else if (parsed.auth.authFlow === "authorization_code") {
|
|
495
|
+
logger.warn("lightbridge_sign_in_unsupported_flow", {
|
|
496
|
+
authFlow: parsed.auth.authFlow,
|
|
497
|
+
message: `lightbridge signs in through the host's Connect dialog (${signInPath(signInName)}), which needs authFlow "device_code"`
|
|
498
|
+
});
|
|
499
|
+
}
|
|
358
500
|
// ---- gateway module ----
|
|
359
501
|
// `sharedRuntime` is always defined here: it is built whenever `gateway`
|
|
360
502
|
// or `otel` is configured (`wantsProjectToken`).
|
|
@@ -376,7 +518,8 @@ export function createLightbridgePlugin(factoryOptions = {}) {
|
|
|
376
518
|
}
|
|
377
519
|
return Effect.tryPromise({
|
|
378
520
|
try: async () => {
|
|
379
|
-
|
|
521
|
+
await observeConnectionCached();
|
|
522
|
+
const token = await runtime.getProjectToken();
|
|
380
523
|
// Header names are case-insensitive: drop any variant already set
|
|
381
524
|
// (a stamped record header, the placeholder key's, a lowercase copy).
|
|
382
525
|
for (const key of Object.keys(event.headers)) {
|
|
@@ -388,10 +531,18 @@ export function createLightbridgePlugin(factoryOptions = {}) {
|
|
|
388
531
|
logger.trace("lightbridge_gateway_bearer_injected", { providerId });
|
|
389
532
|
},
|
|
390
533
|
catch: (error) => error
|
|
391
|
-
}).pipe(Effect.tapError((error) => Effect.sync(() =>
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
534
|
+
}).pipe(Effect.tapError((error) => Effect.sync(() => {
|
|
535
|
+
const needsSignIn = isInteractiveAuthRequiredError(error);
|
|
536
|
+
// While signed out every request repeats this; the one-time
|
|
537
|
+
// lightbridge_sign_in_required warning already says what to do.
|
|
538
|
+
logger[needsSignIn && signInEnabled ? "debug" : "warn"]("lightbridge_gateway_no_bearer", {
|
|
539
|
+
providerId,
|
|
540
|
+
error: errorMessage(error)
|
|
541
|
+
});
|
|
542
|
+
if (needsSignIn) {
|
|
543
|
+
notifySignInRequired("gateway");
|
|
544
|
+
}
|
|
545
|
+
})), Effect.orDie);
|
|
395
546
|
});
|
|
396
547
|
}
|
|
397
548
|
// ---- otel module ----
|
|
@@ -404,7 +555,7 @@ export function createLightbridgePlugin(factoryOptions = {}) {
|
|
|
404
555
|
const built = yield* Effect.promise(() => buildOtelModule({
|
|
405
556
|
directory: ctx.location.directory,
|
|
406
557
|
projectId: ctx.location.project?.id
|
|
407
|
-
}, otelConfig, logger, factoryOptions, sharedRuntime));
|
|
558
|
+
}, otelConfig, logger, factoryOptions, sharedRuntime, notifySignInRequired));
|
|
408
559
|
otel = built;
|
|
409
560
|
const { recorder } = built;
|
|
410
561
|
const adapter = new OtelEventAdapter(recorder, factoryOptions.now);
|
package/dist/opencode.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","names":[],"sources":["../src/opencode.ts"],"version":3,"file":"opencode.js","sourceRoot":""}
|
|
1
|
+
{"mappings":"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","names":[],"sources":["../src/opencode.ts"],"version":3,"file":"opencode.js","sourceRoot":""}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AuthServerConfig, type Logger, type TokenSet } from "@vymalo/opencode-auth-core/lib";
|
|
1
|
+
import { type AuthServerConfig, type DeviceSignIn, type Logger, type TokenSet } from "@vymalo/opencode-auth-core/lib";
|
|
2
2
|
/**
|
|
3
3
|
* Identity for the exchanged project-token store. Kept as a constant, not
|
|
4
4
|
* `auth.id`, because the exchanged-token key has always been derived from this
|
|
@@ -54,10 +54,28 @@ export interface LightbridgeRuntimeOptions {
|
|
|
54
54
|
* `TokenRuntime` (no network, no disk).
|
|
55
55
|
*/
|
|
56
56
|
export interface LightbridgeRuntimeLike {
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
/**
|
|
58
|
+
* A usable gateway/OTEL bearer. NEVER interactive (ADR-0023): when no usable
|
|
59
|
+
* token exists it rejects with `InteractiveAuthRequiredError` and the caller
|
|
60
|
+
* fails closed. The only way a human signs in is `beginDeviceSignIn`, driven
|
|
61
|
+
* from the host's Connect dialog.
|
|
62
|
+
*/
|
|
63
|
+
getProjectToken(): Promise<TokenSet>;
|
|
64
|
+
/**
|
|
65
|
+
* The shared human/IdP root token, refresh-only (never interactive).
|
|
66
|
+
* `minValidityMs` forces a real refresh when the cached token has less than
|
|
67
|
+
* that left (the host's 5-minute refresh window is wider than our skew).
|
|
68
|
+
*/
|
|
69
|
+
ensureRootToken(options?: {
|
|
70
|
+
minValidityMs?: number;
|
|
59
71
|
}): Promise<TokenSet>;
|
|
60
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Request a device code for the Connect dialog; `complete` polls and stores.
|
|
74
|
+
* `signal` cancels the device-authorization request.
|
|
75
|
+
*/
|
|
76
|
+
beginDeviceSignIn(signal?: AbortSignal): Promise<DeviceSignIn>;
|
|
77
|
+
/** Drop every stored token for this identity (the host disconnected it). */
|
|
78
|
+
reset(): Promise<void>;
|
|
61
79
|
}
|
|
62
80
|
/**
|
|
63
81
|
* Builds a `LightbridgeRuntimeLike` for a given `(auth, projectId)` pair.
|
|
@@ -117,10 +135,18 @@ export declare class LightbridgeRuntime implements LightbridgeRuntimeLike {
|
|
|
117
135
|
* invents a token: a failure propagates to the caller, which is expected to
|
|
118
136
|
* fail closed (no header / empty `headers()`).
|
|
119
137
|
*/
|
|
120
|
-
getProjectToken(
|
|
121
|
-
interactive?: boolean;
|
|
122
|
-
}): Promise<TokenSet>;
|
|
138
|
+
getProjectToken(): Promise<TokenSet>;
|
|
123
139
|
private performExchange;
|
|
140
|
+
/** See {@link LightbridgeRuntimeLike.ensureRootToken}. */
|
|
141
|
+
ensureRootToken(options?: {
|
|
142
|
+
minValidityMs?: number;
|
|
143
|
+
}): Promise<TokenSet>;
|
|
144
|
+
/**
|
|
145
|
+
* The ONLY interactive entry point (ADR-0023): the root runtime requests a
|
|
146
|
+
* device code and, on `complete`, stores the result through the shared
|
|
147
|
+
* credential file's single writer (`setCached` under the refresh lock).
|
|
148
|
+
*/
|
|
149
|
+
beginDeviceSignIn(signal?: AbortSignal): Promise<DeviceSignIn>;
|
|
124
150
|
/**
|
|
125
151
|
* Drop the cached tokens for this identity: the exchanged project token
|
|
126
152
|
* entirely (its own exclusive store), and the shared root credential. The
|
package/dist/plugin.js
CHANGED
|
@@ -168,9 +168,9 @@ export class LightbridgeRuntime {
|
|
|
168
168
|
* invents a token: a failure propagates to the caller, which is expected to
|
|
169
169
|
* fail closed (no header / empty `headers()`).
|
|
170
170
|
*/
|
|
171
|
-
async getProjectToken(
|
|
171
|
+
async getProjectToken() {
|
|
172
172
|
if (!this.exchange) {
|
|
173
|
-
return this.rootRuntime.ensure({ interactive:
|
|
173
|
+
return this.rootRuntime.ensure({ interactive: false });
|
|
174
174
|
}
|
|
175
175
|
const cached = await this.getCachedProjectToken();
|
|
176
176
|
if (isProjectTokenUsable(cached, this.tokenExpirySkewMs)) {
|
|
@@ -181,7 +181,7 @@ export class LightbridgeRuntime {
|
|
|
181
181
|
if (this.inFlightExchange) {
|
|
182
182
|
return this.inFlightExchange;
|
|
183
183
|
}
|
|
184
|
-
const exchange = this.performExchange(
|
|
184
|
+
const exchange = this.performExchange();
|
|
185
185
|
this.inFlightExchange = exchange;
|
|
186
186
|
try {
|
|
187
187
|
return await exchange;
|
|
@@ -191,8 +191,8 @@ export class LightbridgeRuntime {
|
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
|
-
async performExchange(
|
|
195
|
-
const human = await this.rootRuntime.ensure({ interactive:
|
|
194
|
+
async performExchange() {
|
|
195
|
+
const human = await this.rootRuntime.ensure({ interactive: false });
|
|
196
196
|
this.logger.info("lightbridge_exchange_started", { projectId: this.projectId ?? "(default)" });
|
|
197
197
|
try {
|
|
198
198
|
// No `projectId` → send no `project_id` param; the backend mints a token
|
|
@@ -208,6 +208,21 @@ export class LightbridgeRuntime {
|
|
|
208
208
|
throw error;
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
|
+
/** See {@link LightbridgeRuntimeLike.ensureRootToken}. */
|
|
212
|
+
async ensureRootToken(options = {}) {
|
|
213
|
+
return this.rootRuntime.ensure({
|
|
214
|
+
interactive: false,
|
|
215
|
+
minValidityMs: options.minValidityMs
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* The ONLY interactive entry point (ADR-0023): the root runtime requests a
|
|
220
|
+
* device code and, on `complete`, stores the result through the shared
|
|
221
|
+
* credential file's single writer (`setCached` under the refresh lock).
|
|
222
|
+
*/
|
|
223
|
+
async beginDeviceSignIn(signal) {
|
|
224
|
+
return this.rootRuntime.beginDeviceSignIn(signal);
|
|
225
|
+
}
|
|
211
226
|
/**
|
|
212
227
|
* Drop the cached tokens for this identity: the exchanged project token
|
|
213
228
|
* entirely (its own exclusive store), and the shared root credential. The
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAAA,SAAS,YAAY;AAErB,SACE,yBACA,8BACA,kBACA,
|
|
1
|
+
{"mappings":"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","names":[],"sources":["../src/plugin.ts"],"version":3,"file":"plugin.js","sourceRoot":""}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { Credential, Plugin } from "@opencode/plugin/effect";
|
|
2
|
+
import { type TokenSet } from "@vymalo/opencode-auth-core/lib";
|
|
3
|
+
import type { Logger } from "./logging.js";
|
|
4
|
+
import type { LightbridgeRuntimeLike } from "./plugin.js";
|
|
5
|
+
type IntegrationEditor = Parameters<Parameters<Plugin.Context["integration"]["transform"]>[0]>[0];
|
|
6
|
+
/** The host's oauth-method registration shape (the package does not export it by name). */
|
|
7
|
+
export type IntegrationOAuthMethodRegistration = Extract<Parameters<IntegrationEditor["method"]["update"]>[0], {
|
|
8
|
+
method: {
|
|
9
|
+
type: "oauth";
|
|
10
|
+
};
|
|
11
|
+
}>;
|
|
12
|
+
/** Id of the one sign-in method lightbridge registers on its integration (ADR-0023). */
|
|
13
|
+
export declare const SIGN_IN_METHOD_ID = "device";
|
|
14
|
+
/** Label of the button the host renders for that method. */
|
|
15
|
+
export declare const SIGN_IN_METHOD_LABEL = "Sign in";
|
|
16
|
+
/** The host calls a method's `refresh` once the credential is within this of `expires`. */
|
|
17
|
+
export declare const HOST_REFRESH_WINDOW_MS: number;
|
|
18
|
+
/** The exact path a user follows to sign in, for the `lightbridge_sign_in_required` hint. */
|
|
19
|
+
export declare function signInPath(name: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Display-only account label (email / username) read from the access token's
|
|
22
|
+
* claims. Deliberately UNVERIFIED: nothing security-relevant ever reads it, it
|
|
23
|
+
* only decorates the host's connection row. Opaque (non-JWT) tokens and any
|
|
24
|
+
* decoding problem yield `undefined`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function accountLabel(accessToken: string): string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* The host-side projection of our token: a "connected" marker plus the current
|
|
29
|
+
* access token. CUSTODY RULE (ADR-0023): `refresh` is ALWAYS `""` — the refresh
|
|
30
|
+
* token never leaves lightbridge's own state file, so a host credential-store
|
|
31
|
+
* leak or a host-driven refresh cannot replay (and thereby rotate away) it.
|
|
32
|
+
*/
|
|
33
|
+
export declare function projectCredential(token: TokenSet, now?: number): Credential.OAuth;
|
|
34
|
+
export interface SignInDependencies {
|
|
35
|
+
integrationID: string;
|
|
36
|
+
runtime: LightbridgeRuntimeLike;
|
|
37
|
+
logger: Logger;
|
|
38
|
+
/**
|
|
39
|
+
* Runs after the projection was handed back (kick the model sync, reload the
|
|
40
|
+
* host's providers). Detached: the dialog closes without waiting for it, and
|
|
41
|
+
* a failure or a late interrupt cannot undo the sign-in.
|
|
42
|
+
*/
|
|
43
|
+
afterSignIn: () => Promise<void>;
|
|
44
|
+
/** Called synchronously on a successful sign-in (re-arms the sign-in notice). */
|
|
45
|
+
onSignedIn?: () => void;
|
|
46
|
+
/** Called when a sign-in-related call finds no usable token (refresh-only failure). */
|
|
47
|
+
onSignInRequired?: (source: string) => void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The oauth method registration behind the host's "Connect" dialog (ADR-0023).
|
|
51
|
+
* `authorize` requests a device code and hands the host the URL + code to show;
|
|
52
|
+
* `callback` awaits the user's approval (interruptible: the host closing the
|
|
53
|
+
* dialog interrupts it, which aborts the polling) and returns the projection.
|
|
54
|
+
*/
|
|
55
|
+
export declare function createSignInRegistration(deps: SignInDependencies): IntegrationOAuthMethodRegistration;
|
|
56
|
+
export interface SignInNotice {
|
|
57
|
+
/** Warn (once until re-armed) that sign-in is needed; always records the source at debug. */
|
|
58
|
+
notify(source: string): void;
|
|
59
|
+
/** Re-arm: the next `notify` warns again (after a sign-in, or a host disconnect). */
|
|
60
|
+
reset(): void;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Emit `lightbridge_sign_in_required` at most once per arming, naming the exact
|
|
64
|
+
* path to sign in. Every non-interactive caller that finds no usable token
|
|
65
|
+
* (startup check, gateway header, OTEL token source, the register sync) reports
|
|
66
|
+
* through this one latch; each call is also recorded at `debug` as
|
|
67
|
+
* `lightbridge_sign_in_required_seen` so the sources stay observable.
|
|
68
|
+
*/
|
|
69
|
+
export declare function createSignInRequiredNotifier(logger: Logger, name: string): SignInNotice;
|
|
70
|
+
export {};
|
package/dist/sign-in.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { isInteractiveAuthRequiredError } from "@vymalo/opencode-auth-core/lib";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
/** Id of the one sign-in method lightbridge registers on its integration (ADR-0023). */
|
|
4
|
+
export const SIGN_IN_METHOD_ID = "device";
|
|
5
|
+
/** Label of the button the host renders for that method. */
|
|
6
|
+
export const SIGN_IN_METHOD_LABEL = "Sign in";
|
|
7
|
+
/** Fallback lifetime for a token the IdP gave no `expires_in` for. */
|
|
8
|
+
const FALLBACK_LIFETIME_MS = 60 * 60 * 1e3;
|
|
9
|
+
const MAX_LABEL_CHARS = 80;
|
|
10
|
+
/** The host calls a method's `refresh` once the credential is within this of `expires`. */
|
|
11
|
+
export const HOST_REFRESH_WINDOW_MS = 5 * 60 * 1e3;
|
|
12
|
+
/** The exact path a user follows to sign in, for the `lightbridge_sign_in_required` hint. */
|
|
13
|
+
export function signInPath(name) {
|
|
14
|
+
return `Settings → Providers → Show more providers → (Integrations dialog) search "${name}" → Sign in`;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Display-only account label (email / username) read from the access token's
|
|
18
|
+
* claims. Deliberately UNVERIFIED: nothing security-relevant ever reads it, it
|
|
19
|
+
* only decorates the host's connection row. Opaque (non-JWT) tokens and any
|
|
20
|
+
* decoding problem yield `undefined`.
|
|
21
|
+
*/
|
|
22
|
+
export function accountLabel(accessToken) {
|
|
23
|
+
const parts = accessToken.split(".");
|
|
24
|
+
if (parts.length !== 3 || !parts[1]) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const claims = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
|
|
29
|
+
for (const key of ["email", "preferred_username"]) {
|
|
30
|
+
const value = claims[key];
|
|
31
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
32
|
+
return value.trim().slice(0, MAX_LABEL_CHARS);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
} catch {}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The host-side projection of our token: a "connected" marker plus the current
|
|
40
|
+
* access token. CUSTODY RULE (ADR-0023): `refresh` is ALWAYS `""` — the refresh
|
|
41
|
+
* token never leaves lightbridge's own state file, so a host credential-store
|
|
42
|
+
* leak or a host-driven refresh cannot replay (and thereby rotate away) it.
|
|
43
|
+
*/
|
|
44
|
+
export function projectCredential(token, now = Date.now()) {
|
|
45
|
+
const label = accountLabel(token.accessToken);
|
|
46
|
+
return {
|
|
47
|
+
type: "oauth",
|
|
48
|
+
methodID: SIGN_IN_METHOD_ID,
|
|
49
|
+
access: token.accessToken,
|
|
50
|
+
refresh: "",
|
|
51
|
+
expires: Math.floor(token.expiresAt ?? now + FALLBACK_LIFETIME_MS),
|
|
52
|
+
...label ? { metadata: { label } } : {}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The oauth method registration behind the host's "Connect" dialog (ADR-0023).
|
|
57
|
+
* `authorize` requests a device code and hands the host the URL + code to show;
|
|
58
|
+
* `callback` awaits the user's approval (interruptible: the host closing the
|
|
59
|
+
* dialog interrupts it, which aborts the polling) and returns the projection.
|
|
60
|
+
*/
|
|
61
|
+
export function createSignInRegistration(deps) {
|
|
62
|
+
const { integrationID, runtime, logger } = deps;
|
|
63
|
+
return {
|
|
64
|
+
integrationID,
|
|
65
|
+
method: {
|
|
66
|
+
id: SIGN_IN_METHOD_ID,
|
|
67
|
+
type: "oauth",
|
|
68
|
+
label: SIGN_IN_METHOD_LABEL
|
|
69
|
+
},
|
|
70
|
+
authorize: () => Effect.tryPromise({
|
|
71
|
+
// The effect's signal aborts when the host abandons the attempt, which
|
|
72
|
+
// also cancels the device-authorization request.
|
|
73
|
+
try: (signal) => runtime.beginDeviceSignIn(signal),
|
|
74
|
+
catch: (error) => error
|
|
75
|
+
}).pipe(Effect.tapError((error) => Effect.sync(() => logger.error("lightbridge_sign_in_begin_failed", errorFields(error)))), Effect.map((session) => ({
|
|
76
|
+
url: session.verificationUriComplete ?? session.verificationUri,
|
|
77
|
+
instructions: `Confirm the code ${session.userCode} on the page that opens, then approve the request.`,
|
|
78
|
+
expiresAt: session.expiresAt,
|
|
79
|
+
mode: "auto",
|
|
80
|
+
callback: Effect.tryPromise({
|
|
81
|
+
try: (signal) => session.complete(signal),
|
|
82
|
+
catch: (error) => error
|
|
83
|
+
}).pipe(Effect.tapError((error) => Effect.sync(() => logger.warn("lightbridge_sign_in_failed", errorFields(error)))), Effect.onInterrupt(() => Effect.sync(() => logger.info("lightbridge_sign_in_cancelled", { integrationID }))), Effect.map((token) => {
|
|
84
|
+
logger.info("lightbridge_sign_in_completed", { integrationID });
|
|
85
|
+
deps.onSignedIn?.();
|
|
86
|
+
// Detached on purpose (see `afterSignIn`).
|
|
87
|
+
void (async () => {
|
|
88
|
+
try {
|
|
89
|
+
await deps.afterSignIn();
|
|
90
|
+
} catch (error) {
|
|
91
|
+
logger.warn("lightbridge_sign_in_followup_failed", errorFields(error));
|
|
92
|
+
}
|
|
93
|
+
})();
|
|
94
|
+
return projectCredential(token);
|
|
95
|
+
}))
|
|
96
|
+
}))),
|
|
97
|
+
// The host calls this within HOST_REFRESH_WINDOW_MS of `expires`. Whatever it
|
|
98
|
+
// holds is ignored (it has no refresh token): the truth is our own runtime,
|
|
99
|
+
// forced to a real, non-interactive refresh through the single writer. A
|
|
100
|
+
// revoked/cleared root fails here - it never starts a flow.
|
|
101
|
+
refresh: () => Effect.tryPromise({
|
|
102
|
+
try: () => runtime.ensureRootToken({ minValidityMs: HOST_REFRESH_WINDOW_MS }),
|
|
103
|
+
catch: (error) => error
|
|
104
|
+
}).pipe(Effect.tapError((error) => Effect.sync(() => {
|
|
105
|
+
logger.warn("lightbridge_sign_in_refresh_failed", errorFields(error));
|
|
106
|
+
if (isInteractiveAuthRequiredError(error)) {
|
|
107
|
+
deps.onSignInRequired?.("refresh");
|
|
108
|
+
}
|
|
109
|
+
})), Effect.tap((token) => Effect.sync(() => {
|
|
110
|
+
// A refresh that "succeeds" with a token still inside the window means
|
|
111
|
+
// the refresh itself failed and we served what was left.
|
|
112
|
+
if (token.expiresAt !== undefined && token.expiresAt - Date.now() <= HOST_REFRESH_WINDOW_MS) {
|
|
113
|
+
logger.warn("lightbridge_sign_in_refresh_failed", { error: "refresh returned a token still inside the host refresh window" });
|
|
114
|
+
}
|
|
115
|
+
})), Effect.map((token) => projectCredential(token))),
|
|
116
|
+
label: (credential) => {
|
|
117
|
+
const label = credential.metadata?.label;
|
|
118
|
+
return typeof label === "string" ? label : undefined;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function errorFields(error) {
|
|
123
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Emit `lightbridge_sign_in_required` at most once per arming, naming the exact
|
|
127
|
+
* path to sign in. Every non-interactive caller that finds no usable token
|
|
128
|
+
* (startup check, gateway header, OTEL token source, the register sync) reports
|
|
129
|
+
* through this one latch; each call is also recorded at `debug` as
|
|
130
|
+
* `lightbridge_sign_in_required_seen` so the sources stay observable.
|
|
131
|
+
*/
|
|
132
|
+
export function createSignInRequiredNotifier(logger, name) {
|
|
133
|
+
let notified = false;
|
|
134
|
+
return {
|
|
135
|
+
notify(source) {
|
|
136
|
+
logger.debug("lightbridge_sign_in_required_seen", { source });
|
|
137
|
+
if (notified) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
notified = true;
|
|
141
|
+
logger.warn("lightbridge_sign_in_required", {
|
|
142
|
+
source,
|
|
143
|
+
message: `lightbridge is not signed in: open ${signInPath(name)}`
|
|
144
|
+
});
|
|
145
|
+
},
|
|
146
|
+
reset() {
|
|
147
|
+
notified = false;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
//# sourceMappingURL=sign-in.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","names":[],"sources":["../src/sign-in.ts"],"version":3,"file":"sign-in.js","sourceRoot":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vymalo/opencode-lightbridge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Umbrella OpenCode plugin for ADR-0012: one shared credential (TokenRuntime) drives both the LLM gateway bearer and OTEL export, so a developer authenticates once and every egress rides the same project-scoped token.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "vymalo contributors",
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"@opentelemetry/api": "^1.9.1",
|
|
55
55
|
"@opentelemetry/api-logs": "^0.222.0",
|
|
56
56
|
"@opentelemetry/core": "^2.11.0",
|
|
57
|
-
"@vymalo/opencode-auth-core": "0.
|
|
58
|
-
"@vymalo/opencode-
|
|
59
|
-
"@vymalo/opencode-
|
|
57
|
+
"@vymalo/opencode-auth-core": "0.20.0",
|
|
58
|
+
"@vymalo/opencode-provider-sync": "0.20.0",
|
|
59
|
+
"@vymalo/opencode-core-otel": "0.20.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@opentelemetry/sdk-logs": "^0.222.0",
|