@vymalo/opencode-oauth2 0.11.0 → 0.14.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/cache.d.ts +6 -6
- package/dist/cache.js +100 -104
- package/dist/cache.js.map +1 -1
- package/dist/config.d.ts +107 -107
- package/dist/config.js +173 -182
- package/dist/config.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib.js +1 -0
- package/dist/lib.js.map +1 -1
- package/dist/logging.d.ts +6 -6
- package/dist/logging.js +57 -56
- package/dist/logging.js.map +1 -1
- package/dist/model-discovery.d.ts +3 -3
- package/dist/model-discovery.js +61 -66
- package/dist/model-discovery.js.map +1 -1
- package/dist/model-normalization.js +84 -73
- package/dist/model-normalization.js.map +1 -1
- package/dist/oauth/browser.js +29 -25
- package/dist/oauth/browser.js.map +1 -1
- package/dist/oauth/client.d.ts +46 -46
- package/dist/oauth/client.js +411 -430
- package/dist/oauth/client.js.map +1 -1
- package/dist/oauth/device-code.d.ts +23 -23
- package/dist/oauth/device-code.js +225 -235
- package/dist/oauth/device-code.js.map +1 -1
- package/dist/oauth/discovery.d.ts +5 -5
- package/dist/oauth/discovery.js +34 -34
- package/dist/oauth/discovery.js.map +1 -1
- package/dist/oauth/http-utils.d.ts +27 -27
- package/dist/oauth/http-utils.js +96 -107
- package/dist/oauth/http-utils.js.map +1 -1
- package/dist/oauth/local-callback.d.ts +5 -5
- package/dist/oauth/local-callback.js +76 -74
- package/dist/oauth/local-callback.js.map +1 -1
- package/dist/oauth/pkce.d.ts +2 -2
- package/dist/oauth/pkce.js +9 -5
- package/dist/oauth/pkce.js.map +1 -1
- package/dist/oauth/subject-token.d.ts +15 -15
- package/dist/oauth/subject-token.js +68 -73
- package/dist/oauth/subject-token.js.map +1 -1
- package/dist/opencode.d.ts +15 -15
- package/dist/opencode.js +477 -497
- package/dist/opencode.js.map +1 -1
- package/dist/plugin.d.ts +39 -39
- package/dist/plugin.js +270 -277
- package/dist/plugin.js.map +1 -1
- package/dist/responses-repair.d.ts +12 -35
- package/dist/responses-repair.js +119 -125
- package/dist/responses-repair.js.map +1 -1
- package/dist/scheduler.d.ts +5 -5
- package/dist/scheduler.js +43 -45
- package/dist/scheduler.js.map +1 -1
- package/dist/types.d.ts +25 -25
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/package.json +3 -3
package/dist/cache.d.ts
CHANGED
|
@@ -2,10 +2,10 @@ import type { Logger } from "./logging.js";
|
|
|
2
2
|
import type { CachedServerState } from "./types.js";
|
|
3
3
|
export declare function resolveCacheDir(namespace: string): string;
|
|
4
4
|
export declare class FileCacheStore {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
private readonly baseDir;
|
|
6
|
+
private readonly logger?;
|
|
7
|
+
constructor(baseDir: string, logger?: Logger | undefined);
|
|
8
|
+
ensureReady(): Promise<void>;
|
|
9
|
+
loadServerState(serverId: string): Promise<CachedServerState | undefined>;
|
|
10
|
+
saveServerState(state: CachedServerState): Promise<void>;
|
|
11
11
|
}
|
package/dist/cache.js
CHANGED
|
@@ -4,117 +4,113 @@ import { randomUUID } from "node:crypto";
|
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
function resolveDefaultCacheRoot() {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
if (process.platform === "win32") {
|
|
8
|
+
return process.env.LOCALAPPDATA ?? join(homedir(), "AppData", "Local");
|
|
9
|
+
}
|
|
10
|
+
if (process.platform === "darwin") {
|
|
11
|
+
return join(homedir(), "Library", "Caches");
|
|
12
|
+
}
|
|
13
|
+
return process.env.XDG_CACHE_HOME ?? join(homedir(), ".cache");
|
|
14
14
|
}
|
|
15
15
|
export function resolveCacheDir(namespace) {
|
|
16
|
-
|
|
16
|
+
return join(resolveDefaultCacheRoot(), "opencode-oauth2", namespace);
|
|
17
17
|
}
|
|
18
18
|
function statePath(baseDir, serverId) {
|
|
19
|
-
|
|
19
|
+
return join(baseDir, `${serverId}.json`);
|
|
20
20
|
}
|
|
21
21
|
function hasValidTokenShape(token) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return typeof candidate.refreshToken === "string" && candidate.refreshToken.length > 0;
|
|
36
|
-
}
|
|
37
|
-
return true;
|
|
22
|
+
if (!token || typeof token !== "object" || Array.isArray(token)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const candidate = token;
|
|
26
|
+
if (typeof candidate.accessToken !== "string" || candidate.accessToken.length === 0 || typeof candidate.tokenType !== "string" || candidate.tokenType.length === 0) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
// refreshToken is optional: client_credentials grant never returns one.
|
|
30
|
+
// When present, it must be a non-empty string.
|
|
31
|
+
if (candidate.refreshToken !== undefined) {
|
|
32
|
+
return typeof candidate.refreshToken === "string" && candidate.refreshToken.length > 0;
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
38
35
|
}
|
|
39
36
|
export class FileCacheStore {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
}
|
|
37
|
+
baseDir;
|
|
38
|
+
logger;
|
|
39
|
+
constructor(baseDir, logger) {
|
|
40
|
+
this.baseDir = baseDir;
|
|
41
|
+
this.logger = logger;
|
|
42
|
+
}
|
|
43
|
+
async ensureReady() {
|
|
44
|
+
await mkdir(this.baseDir, {
|
|
45
|
+
recursive: true,
|
|
46
|
+
mode: 448
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async loadServerState(serverId) {
|
|
50
|
+
const filePath = statePath(this.baseDir, serverId);
|
|
51
|
+
try {
|
|
52
|
+
const content = await readFile(filePath, "utf8");
|
|
53
|
+
const parsed = JSON.parse(content);
|
|
54
|
+
if (!parsed || parsed.serverId !== serverId) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
if (!Array.isArray(parsed.models) || !Array.isArray(parsed.rawModels)) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
if (parsed.token && !hasValidTokenShape(parsed.token)) {
|
|
61
|
+
this.logger?.trace("oauth2_cache_token_dropped_invalid_shape", { serverId });
|
|
62
|
+
parsed.token = undefined;
|
|
63
|
+
}
|
|
64
|
+
this.logger?.trace("oauth2_cache_file_read", {
|
|
65
|
+
serverId,
|
|
66
|
+
modelCount: Array.isArray(parsed.models) ? parsed.models.length : 0,
|
|
67
|
+
hasToken: Boolean(parsed.token)
|
|
68
|
+
});
|
|
69
|
+
return parsed;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (typeof error === "object" && error && "code" in error && error.code === "ENOENT") {
|
|
72
|
+
this.logger?.trace("oauth2_cache_file_missing", { serverId });
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async saveServerState(state) {
|
|
79
|
+
const filePath = statePath(this.baseDir, state.serverId);
|
|
80
|
+
// Unique per-write temp name. A shared `${filePath}.tmp` collides when
|
|
81
|
+
// several opencode instances boot at once (the desktop app restores every
|
|
82
|
+
// project window in parallel) and all sync the same provider: one process'
|
|
83
|
+
// rename consumes the temp file the other is about to rename, surfacing as
|
|
84
|
+
// `sync_failed … ENOENT … rename '<serverId>.json.tmp' -> '<serverId>.json'`.
|
|
85
|
+
// pid + uuid makes each writer's temp file private; rename stays atomic so
|
|
86
|
+
// last-writer-wins on the final path. See docs/troubleshooting.md.
|
|
87
|
+
const tempPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
|
|
88
|
+
await mkdir(dirname(filePath), {
|
|
89
|
+
recursive: true,
|
|
90
|
+
mode: 448
|
|
91
|
+
});
|
|
92
|
+
const serialized = JSON.stringify(state, null, 2);
|
|
93
|
+
try {
|
|
94
|
+
await writeFile(tempPath, serialized, {
|
|
95
|
+
encoding: "utf8",
|
|
96
|
+
mode: 384,
|
|
97
|
+
flag: fsConstants.O_CREAT | fsConstants.O_TRUNC | fsConstants.O_WRONLY
|
|
98
|
+
});
|
|
99
|
+
await rename(tempPath, filePath);
|
|
100
|
+
this.logger?.trace("oauth2_cache_file_written", {
|
|
101
|
+
serverId: state.serverId,
|
|
102
|
+
modelCount: Array.isArray(state.models) ? state.models.length : 0,
|
|
103
|
+
hasToken: Boolean(state.token)
|
|
104
|
+
});
|
|
105
|
+
} catch (error) {
|
|
106
|
+
// Best-effort cleanup so a failed write never strands an orphan temp file.
|
|
107
|
+
await unlink(tempPath).catch(() => {});
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
await chmod(filePath, 384);
|
|
112
|
+
} catch {}
|
|
113
|
+
}
|
|
119
114
|
}
|
|
115
|
+
|
|
120
116
|
//# sourceMappingURL=cache.js.map
|
package/dist/cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"
|
|
1
|
+
{"mappings":"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","names":[],"sources":["../src/cache.ts"],"version":3,"file":"cache.js","sourceRoot":""}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,128 +1,128 @@
|
|
|
1
1
|
import type { LogLevel } from "./logging.js";
|
|
2
2
|
export declare const DEFAULT_SYNC_INTERVAL_MINUTES = 60;
|
|
3
|
-
export declare const DEFAULT_HTTP_TIMEOUT_MS =
|
|
4
|
-
export declare const DEFAULT_TOKEN_EXPIRY_SKEW_MS =
|
|
3
|
+
export declare const DEFAULT_HTTP_TIMEOUT_MS = 15e3;
|
|
4
|
+
export declare const DEFAULT_TOKEN_EXPIRY_SKEW_MS = 3e4;
|
|
5
5
|
export declare const DEFAULT_LOG_LEVEL: LogLevel;
|
|
6
6
|
export type OAuthAuthFlow = "authorization_code" | "device_code" | "client_credentials" | "jwt_bearer" | "token_exchange";
|
|
7
7
|
export declare const DEFAULT_AUTH_FLOW: OAuthAuthFlow;
|
|
8
8
|
/**
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
9
|
+
* Where to read the platform-supplied JWT that the plugin presents as the
|
|
10
|
+
* subject token / assertion for the `jwt_bearer` and `token_exchange` flows.
|
|
11
|
+
*
|
|
12
|
+
* - `github_actions` — fetches the OIDC token from the GitHub Actions runtime
|
|
13
|
+
* via `ACTIONS_ID_TOKEN_REQUEST_URL` + `ACTIONS_ID_TOKEN_REQUEST_TOKEN`,
|
|
14
|
+
* with the workflow-declared `audience`. The `id-token: write` permission
|
|
15
|
+
* is required on the job.
|
|
16
|
+
* - `kubernetes_sa` — reads a projected service-account token from the pod
|
|
17
|
+
* filesystem. Default path `/var/run/secrets/tokens/oauth2/token`; mount a
|
|
18
|
+
* `projected.sources.serviceAccountToken` volume with the OIDC issuer as
|
|
19
|
+
* the audience.
|
|
20
|
+
* - `file` — reads any JWT from disk. Useful when an external sidecar
|
|
21
|
+
* refreshes the token to a fixed path.
|
|
22
|
+
* - `env` — reads the JWT from a named environment variable. Mostly useful
|
|
23
|
+
* for tests and ad-hoc shells.
|
|
24
|
+
*/
|
|
25
25
|
export type SubjectTokenSource = {
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
type: "github_actions";
|
|
27
|
+
audience: string;
|
|
28
28
|
} | {
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
type: "kubernetes_sa";
|
|
30
|
+
tokenPath?: string;
|
|
31
31
|
} | {
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
type: "file";
|
|
33
|
+
path: string;
|
|
34
34
|
} | {
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
type: "env";
|
|
36
|
+
var: string;
|
|
37
37
|
};
|
|
38
38
|
export declare const DEFAULT_K8S_SA_TOKEN_PATH = "/var/run/secrets/tokens/oauth2/token";
|
|
39
39
|
export interface OAuthServerConfigInput {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
40
|
+
id: string;
|
|
41
|
+
name?: string;
|
|
42
|
+
issuer: string;
|
|
43
|
+
baseURL: string;
|
|
44
|
+
clientId: string;
|
|
45
|
+
clientSecret?: string;
|
|
46
|
+
scopes: string[];
|
|
47
|
+
syncIntervalMinutes?: number;
|
|
48
|
+
nameOverrides?: Record<string, string>;
|
|
49
|
+
authorizationEndpoint?: string;
|
|
50
|
+
tokenEndpoint?: string;
|
|
51
|
+
deviceAuthorizationEndpoint?: string;
|
|
52
|
+
jwksUri?: string;
|
|
53
|
+
redirectPort?: number;
|
|
54
|
+
authFlow?: OAuthAuthFlow;
|
|
55
|
+
/**
|
|
56
|
+
* Send PKCE (RFC 7636) on the interactive `authorization_code` and
|
|
57
|
+
* `device_code` flows: `code_challenge` + `code_challenge_method=S256` on the
|
|
58
|
+
* authorization/device request, and the matching `code_verifier` on the token
|
|
59
|
+
* exchange. Defaults to `true` — PKCE is recommended for public clients and
|
|
60
|
+
* is silently ignored by servers that don't require it, so leave it on unless
|
|
61
|
+
* a non-compliant IdP rejects the extra parameters. Has no effect on the
|
|
62
|
+
* machine flows (`client_credentials`, `jwt_bearer`, `token_exchange`).
|
|
63
|
+
*/
|
|
64
|
+
pkce?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Required for `jwt_bearer` and `token_exchange`. Tells the plugin where to
|
|
67
|
+
* read the platform JWT it should present as the subject token.
|
|
68
|
+
*/
|
|
69
|
+
subjectTokenSource?: SubjectTokenSource;
|
|
70
|
+
/**
|
|
71
|
+
* Optional `audience` parameter for the `token_exchange` grant — the
|
|
72
|
+
* intended recipient of the resulting access token. Set this when the
|
|
73
|
+
* OAuth server expects an explicit audience claim distinct from the
|
|
74
|
+
* issuer.
|
|
75
|
+
*/
|
|
76
|
+
tokenExchangeAudience?: string;
|
|
77
|
+
/**
|
|
78
|
+
* Route inference through the OpenAI **Responses API** (`/v1/responses`)
|
|
79
|
+
* instead of Chat Completions (`/v1/chat/completions`). When `true` the
|
|
80
|
+
* managed provider is registered with `npm: "@ai-sdk/openai"` (whose default
|
|
81
|
+
* `languageModel()` targets Responses since AI SDK v5) rather than
|
|
82
|
+
* `@ai-sdk/openai-compatible`. Only enable it when the gateway implements the
|
|
83
|
+
* OpenAI Responses contract. Defaults to `false`. This flag affects provider
|
|
84
|
+
* registration only — it never touches the token lifecycle, so it is read at
|
|
85
|
+
* the config-synthesis layer and not part of the validated runtime config.
|
|
86
|
+
*/
|
|
87
|
+
responseApi?: boolean;
|
|
88
88
|
}
|
|
89
89
|
export interface OAuth2ModelSyncConfigInput {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
90
|
+
servers: OAuthServerConfigInput[];
|
|
91
|
+
cacheNamespace?: string;
|
|
92
|
+
httpTimeoutMs?: number;
|
|
93
|
+
tokenExpirySkewMs?: number;
|
|
94
|
+
/**
|
|
95
|
+
* Minimum log level the plugin emits. Lower-priority records are dropped.
|
|
96
|
+
* One of `"trace" | "debug" | "info" | "warn" | "error"`. Defaults to
|
|
97
|
+
* `"info"`. `"trace"` is the most-verbose tier (host `--log-level DEBUG`).
|
|
98
|
+
*/
|
|
99
|
+
logLevel?: LogLevel;
|
|
100
100
|
}
|
|
101
101
|
export interface OAuthServerConfig {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
102
|
+
id: string;
|
|
103
|
+
name: string;
|
|
104
|
+
issuer: string;
|
|
105
|
+
baseURL: string;
|
|
106
|
+
clientId: string;
|
|
107
|
+
clientSecret?: string;
|
|
108
|
+
scopes: string[];
|
|
109
|
+
syncIntervalMinutes: number;
|
|
110
|
+
nameOverrides: Record<string, string>;
|
|
111
|
+
authorizationEndpoint?: string;
|
|
112
|
+
tokenEndpoint?: string;
|
|
113
|
+
deviceAuthorizationEndpoint?: string;
|
|
114
|
+
jwksUri?: string;
|
|
115
|
+
redirectPort?: number;
|
|
116
|
+
authFlow: OAuthAuthFlow;
|
|
117
|
+
pkce: boolean;
|
|
118
|
+
subjectTokenSource?: SubjectTokenSource;
|
|
119
|
+
tokenExchangeAudience?: string;
|
|
120
120
|
}
|
|
121
121
|
export interface OAuth2ModelSyncConfig {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
servers: OAuthServerConfig[];
|
|
123
|
+
cacheNamespace: string;
|
|
124
|
+
httpTimeoutMs: number;
|
|
125
|
+
tokenExpirySkewMs: number;
|
|
126
|
+
logLevel: LogLevel;
|
|
127
127
|
}
|
|
128
128
|
export declare function validateConfig(input: OAuth2ModelSyncConfigInput): OAuth2ModelSyncConfig;
|