@cortexkit/opencode-openai-auth 0.11.1 → 1.0.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/README.md +15 -26
- package/dist/index-766sfrh5.js +1 -0
- package/dist/index-8kj7sa1p.js +12 -0
- package/dist/index-8rqfbhfw.js +221 -0
- package/dist/index-b3q3j39x.js +2 -0
- package/dist/index-bmd7x5aq.js +2 -0
- package/dist/index-eqh53k8v.js +2 -0
- package/dist/{index-sdt2d2ra.js → index-hy9030jh.js} +1 -1
- package/dist/index-jyr8y8k4.js +7 -0
- package/dist/index-rv08jmd4.js +2 -0
- package/dist/index.d.ts +578 -145
- package/dist/index.js +1 -110
- package/dist/pool-lifecycle-DbDmgabd.d.ts +2430 -0
- package/dist/port-file-Do3lQIEk.d.ts +29 -0
- package/dist/protocol-BOBdkqqm.d.ts +198 -0
- package/dist/rpc/port-file.d.ts +4 -17
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/protocol.d.ts +2 -2
- package/dist/rpc/protocol.js +1 -0
- package/dist/rpc/rpc-client.d.ts +5 -4
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.d.ts +2 -0
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/sidebar-state-D6cUKgkm.d.ts +385 -0
- package/dist/sidebar-state.d.ts +2 -2
- package/dist/sidebar-state.js +1 -1
- package/dist/token-util-wdza526f.js +1 -0
- package/dist/{token-9823y0pc.js → token-ypk61xj0.js} +1 -1
- package/dist/tui-preferences.js +5 -2
- package/dist/tui.d.ts +9 -4
- package/dist/v2/server.d.ts +54 -0
- package/dist/v2/server.js +4 -0
- package/package.json +21 -9
- package/src/tui/entry.mjs +26 -25
- package/src/tui-compiled/raw/logger.js +24 -0
- package/src/tui-compiled/raw/rpc/protocol.js +3 -0
- package/src/tui-compiled/raw/rpc/rpc-client.js +7 -0
- package/src/tui-compiled/raw/rpc/rpc-dir.js +27 -0
- package/src/tui-compiled/raw/selector.js +21 -0
- package/src/tui-compiled/raw/shared/0332701351b3eeec-format.js +138 -0
- package/src/tui-compiled/raw/shared/04a6357627de5ed0-errors.js +38 -0
- package/src/tui-compiled/raw/shared/053cc17b5419261e-codec.js +12 -0
- package/src/tui-compiled/raw/shared/0766d78c6f481f18-watcher.js +157 -0
- package/src/tui-compiled/raw/shared/08eef45626a94992-reserved.js +13 -0
- package/src/tui-compiled/raw/shared/39c3cb05738fcf6d-projection.js +134 -0
- package/src/tui-compiled/raw/shared/3c2d4169d00f907e-tui-support.js +5 -0
- package/src/tui-compiled/raw/shared/3e7d45a77c6ad4d5-index.js +4 -0
- package/src/tui-compiled/raw/shared/415792e85d80819e-capture-sink.js +13 -0
- package/src/tui-compiled/raw/shared/42ae93ab554fcec2-open-url.js +28 -0
- package/src/tui-compiled/raw/shared/43fc9e6b994519c7-refresh-lock.js +136 -0
- package/src/tui-compiled/raw/shared/458b934e92490331-mutate.js +500 -0
- package/src/tui-compiled/raw/shared/45bf5343bbbf9add-admission.js +142 -0
- package/src/tui-compiled/raw/shared/46f3dff1266160e8-client.js +2 -0
- package/src/tui-compiled/raw/shared/4825e03209d6ae3e-with-lock.js +48 -0
- package/src/tui-compiled/raw/shared/4f36d333d081d040-merge.js +162 -0
- package/src/tui-compiled/raw/shared/54eba94fd64c8c3c-index.js +7 -0
- package/src/tui-compiled/raw/shared/7211cfec06a298bc-atomic-write.js +80 -0
- package/src/tui-compiled/raw/shared/754d6017f8e419cf-builtins.js +534 -0
- package/src/tui-compiled/raw/shared/75bd8c3bd63b315f-identity.js +79 -0
- package/src/tui-compiled/raw/shared/7a91bb630e6f4804-index.js +1 -0
- package/src/tui-compiled/raw/shared/826342a4b6a8b89b-model.js +16 -0
- package/src/tui-compiled/raw/shared/83068c0dbe8a6f13-publication.js +304 -0
- package/src/tui-compiled/raw/shared/836fc615de6afbd9-settings.js +120 -0
- package/src/tui-compiled/raw/shared/83bc3ba9d0fe2761-runtime.js +68 -0
- package/src/tui-compiled/raw/shared/8a18abe4fa2977c8-menu.js +300 -0
- package/src/tui-compiled/raw/shared/901e149c5a0dbbff-sticky.js +339 -0
- package/src/tui-compiled/raw/shared/9020c407ce64f672-ordered.js +58 -0
- package/src/tui-compiled/raw/shared/905bffc0220f43d0-map.js +105 -0
- package/src/tui-compiled/raw/shared/94820e324f2b4c09-seam.js +301 -0
- package/src/tui-compiled/raw/shared/97484d9bb98c705b-provider-state.js +226 -0
- package/src/tui-compiled/raw/shared/9968e3cade6969a1-index.js +2 -0
- package/src/tui-compiled/raw/shared/9b4da614c45f9cd0-lock-constants.js +14 -0
- package/src/tui-compiled/raw/shared/9d3fc9e37456504e-refresh.js +225 -0
- package/src/tui-compiled/raw/shared/9deae3c4da4fd63b-hooks.js +34 -0
- package/src/tui-compiled/raw/shared/a09b6a533c11858f-tui-preferences.js +77 -0
- package/src/tui-compiled/raw/shared/a62a27a204266acd-attribution.js +60 -0
- package/src/tui-compiled/raw/shared/a910277ac43a8626-pull.js +143 -0
- package/src/tui-compiled/raw/shared/b85c5301fddcb98a-paths.js +5 -0
- package/src/tui-compiled/raw/shared/c14988621dc60a75-port-file.js +217 -0
- package/src/tui-compiled/raw/shared/c64d7afbc14ca125-sidebar-file.js +157 -0
- package/src/tui-compiled/raw/shared/c6b176708c446d6d-pins.js +34 -0
- package/src/tui-compiled/raw/shared/c7d252bedee01600-pi.js +206 -0
- package/src/tui-compiled/raw/shared/c852a15cfe489d12-pool.js +120 -0
- package/src/tui-compiled/raw/shared/cc9e0702a752cea7-index.js +3 -0
- package/src/tui-compiled/raw/shared/cd94316a888b0a8e-schema.js +754 -0
- package/src/tui-compiled/raw/shared/d319517e3ea6ad70-redact.js +83 -0
- package/src/tui-compiled/raw/shared/d5a8f1061ee2f114-index.js +5 -0
- package/src/tui-compiled/raw/shared/d669d72c40e9e116-logger.js +19 -0
- package/src/tui-compiled/raw/shared/d7dcba96fea1685c-engine.js +246 -0
- package/src/tui-compiled/raw/shared/dbef697d1df1cd84-index.js +5 -0
- package/src/tui-compiled/raw/shared/e4acc4cb713f300c-protocol.js +3 -0
- package/src/tui-compiled/raw/shared/e8cd4929507508d8-refresh-file-lock.js +501 -0
- package/src/tui-compiled/raw/shared/ec971142548df90e-index.js +6 -0
- package/src/tui-compiled/raw/shared/f37fcefc7aedbf25-error.js +11 -0
- package/src/tui-compiled/raw/shared/fbcdcd0f925e74c0-rpc-client.js +253 -0
- package/src/tui-compiled/raw/shared/fd45e82f2f9c0a0d-torn.js +294 -0
- package/src/tui-compiled/raw/shared/fe02abeadc535f77-rows.js +1258 -0
- package/src/tui-compiled/raw/sidebar-state.js +960 -0
- package/src/tui-compiled/raw/tui/command-dialogs.tsx +424 -0
- package/src/tui-compiled/raw/tui-preferences.js +135 -0
- package/src/tui-compiled/raw/tui.tsx +135 -143
- package/src/tui-compiled/runtime/logger.js +24 -0
- package/src/tui-compiled/runtime/rpc/protocol.js +3 -0
- package/src/tui-compiled/runtime/rpc/rpc-client.js +7 -0
- package/src/tui-compiled/runtime/rpc/rpc-dir.js +27 -0
- package/src/tui-compiled/runtime/selector.js +21 -0
- package/src/tui-compiled/runtime/shared/0332701351b3eeec-format.js +138 -0
- package/src/tui-compiled/runtime/shared/04a6357627de5ed0-errors.js +38 -0
- package/src/tui-compiled/runtime/shared/053cc17b5419261e-codec.js +12 -0
- package/src/tui-compiled/runtime/shared/0766d78c6f481f18-watcher.js +157 -0
- package/src/tui-compiled/runtime/shared/08eef45626a94992-reserved.js +13 -0
- package/src/tui-compiled/runtime/shared/39c3cb05738fcf6d-projection.js +134 -0
- package/src/tui-compiled/runtime/shared/3c2d4169d00f907e-tui-support.js +5 -0
- package/src/tui-compiled/runtime/shared/3e7d45a77c6ad4d5-index.js +4 -0
- package/src/tui-compiled/runtime/shared/415792e85d80819e-capture-sink.js +13 -0
- package/src/tui-compiled/runtime/shared/42ae93ab554fcec2-open-url.js +28 -0
- package/src/tui-compiled/runtime/shared/43fc9e6b994519c7-refresh-lock.js +136 -0
- package/src/tui-compiled/runtime/shared/458b934e92490331-mutate.js +500 -0
- package/src/tui-compiled/runtime/shared/45bf5343bbbf9add-admission.js +142 -0
- package/src/tui-compiled/runtime/shared/46f3dff1266160e8-client.js +2 -0
- package/src/tui-compiled/runtime/shared/4825e03209d6ae3e-with-lock.js +48 -0
- package/src/tui-compiled/runtime/shared/4f36d333d081d040-merge.js +162 -0
- package/src/tui-compiled/runtime/shared/54eba94fd64c8c3c-index.js +7 -0
- package/src/tui-compiled/runtime/shared/7211cfec06a298bc-atomic-write.js +80 -0
- package/src/tui-compiled/runtime/shared/754d6017f8e419cf-builtins.js +534 -0
- package/src/tui-compiled/runtime/shared/75bd8c3bd63b315f-identity.js +79 -0
- package/src/tui-compiled/runtime/shared/7a91bb630e6f4804-index.js +1 -0
- package/src/tui-compiled/runtime/shared/826342a4b6a8b89b-model.js +16 -0
- package/src/tui-compiled/runtime/shared/83068c0dbe8a6f13-publication.js +304 -0
- package/src/tui-compiled/runtime/shared/836fc615de6afbd9-settings.js +120 -0
- package/src/tui-compiled/runtime/shared/83bc3ba9d0fe2761-runtime.js +68 -0
- package/src/tui-compiled/runtime/shared/8a18abe4fa2977c8-menu.js +300 -0
- package/src/tui-compiled/runtime/shared/901e149c5a0dbbff-sticky.js +339 -0
- package/src/tui-compiled/runtime/shared/9020c407ce64f672-ordered.js +58 -0
- package/src/tui-compiled/runtime/shared/905bffc0220f43d0-map.js +105 -0
- package/src/tui-compiled/runtime/shared/94820e324f2b4c09-seam.js +301 -0
- package/src/tui-compiled/runtime/shared/97484d9bb98c705b-provider-state.js +226 -0
- package/src/tui-compiled/runtime/shared/9968e3cade6969a1-index.js +2 -0
- package/src/tui-compiled/runtime/shared/9b4da614c45f9cd0-lock-constants.js +14 -0
- package/src/tui-compiled/runtime/shared/9d3fc9e37456504e-refresh.js +225 -0
- package/src/tui-compiled/runtime/shared/9deae3c4da4fd63b-hooks.js +34 -0
- package/src/tui-compiled/runtime/shared/a09b6a533c11858f-tui-preferences.js +77 -0
- package/src/tui-compiled/runtime/shared/a62a27a204266acd-attribution.js +60 -0
- package/src/tui-compiled/runtime/shared/a910277ac43a8626-pull.js +143 -0
- package/src/tui-compiled/runtime/shared/b85c5301fddcb98a-paths.js +5 -0
- package/src/tui-compiled/runtime/shared/c14988621dc60a75-port-file.js +217 -0
- package/src/tui-compiled/runtime/shared/c64d7afbc14ca125-sidebar-file.js +157 -0
- package/src/tui-compiled/runtime/shared/c6b176708c446d6d-pins.js +34 -0
- package/src/tui-compiled/runtime/shared/c7d252bedee01600-pi.js +206 -0
- package/src/tui-compiled/runtime/shared/c852a15cfe489d12-pool.js +120 -0
- package/src/tui-compiled/runtime/shared/cc9e0702a752cea7-index.js +3 -0
- package/src/tui-compiled/runtime/shared/cd94316a888b0a8e-schema.js +754 -0
- package/src/tui-compiled/runtime/shared/d319517e3ea6ad70-redact.js +83 -0
- package/src/tui-compiled/runtime/shared/d5a8f1061ee2f114-index.js +5 -0
- package/src/tui-compiled/runtime/shared/d669d72c40e9e116-logger.js +19 -0
- package/src/tui-compiled/runtime/shared/d7dcba96fea1685c-engine.js +246 -0
- package/src/tui-compiled/runtime/shared/dbef697d1df1cd84-index.js +5 -0
- package/src/tui-compiled/runtime/shared/e4acc4cb713f300c-protocol.js +3 -0
- package/src/tui-compiled/runtime/shared/e8cd4929507508d8-refresh-file-lock.js +501 -0
- package/src/tui-compiled/runtime/shared/ec971142548df90e-index.js +6 -0
- package/src/tui-compiled/runtime/shared/f37fcefc7aedbf25-error.js +11 -0
- package/src/tui-compiled/runtime/shared/fbcdcd0f925e74c0-rpc-client.js +253 -0
- package/src/tui-compiled/runtime/shared/fd45e82f2f9c0a0d-torn.js +294 -0
- package/src/tui-compiled/runtime/shared/fe02abeadc535f77-rows.js +1258 -0
- package/src/tui-compiled/runtime/sidebar-state.js +960 -0
- package/src/tui-compiled/runtime/tui/command-dialogs.js +378 -0
- package/src/tui-compiled/runtime/tui-preferences.js +135 -0
- package/src/tui-compiled/runtime/{tui.tsx → tui.js} +288 -316
- package/dist/index-4effjmr6.js +0 -2
- package/dist/index-9ehhb051.js +0 -2
- package/dist/index-g3hsdjh4.js +0 -2
- package/dist/index-hh52v8sb.js +0 -2
- package/dist/index-jwn4r3sw.js +0 -1
- package/dist/index-sq36b120.js +0 -211
- package/dist/internal-BTndPmW2.d.ts +0 -914
- package/dist/quota-normalize-08hpp51v.js +0 -1
- package/dist/sidebar-state-CoKYKcLn.d.ts +0 -220
- package/dist/token-util-ypgz7rge.js +0 -1
- package/src/tui-compiled/raw/core-account-paths.ts +0 -114
- package/src/tui-compiled/raw/core-custody-state.ts +0 -243
- package/src/tui-compiled/raw/logger.ts +0 -53
- package/src/tui-compiled/raw/rpc-port-file.ts +0 -177
- package/src/tui-compiled/raw/rpc-protocol.ts +0 -12
- package/src/tui-compiled/raw/rpc-rpc-client.ts +0 -82
- package/src/tui-compiled/raw/rpc-rpc-dir.ts +0 -46
- package/src/tui-compiled/raw/sidebar-state.ts +0 -1659
- package/src/tui-compiled/raw/tui-command-dialogs.tsx +0 -1096
- package/src/tui-compiled/raw/tui-preferences.ts +0 -328
- package/src/tui-compiled/runtime/core-account-paths.ts +0 -114
- package/src/tui-compiled/runtime/core-custody-state.ts +0 -243
- package/src/tui-compiled/runtime/logger.ts +0 -53
- package/src/tui-compiled/runtime/rpc-port-file.ts +0 -177
- package/src/tui-compiled/runtime/rpc-protocol.ts +0 -12
- package/src/tui-compiled/runtime/rpc-rpc-client.ts +0 -82
- package/src/tui-compiled/runtime/rpc-rpc-dir.ts +0 -46
- package/src/tui-compiled/runtime/sidebar-state.ts +0 -1659
- package/src/tui-compiled/runtime/tui-command-dialogs.tsx +0 -855
- package/src/tui-compiled/runtime/tui-preferences.ts +0 -328
- package/src/tui-compiled/shared/internal.ts +0 -6
- package/src/tui-compiled/shared/logger.ts +0 -264
- package/src/tui-compiled/shared/paths.ts +0 -33
- package/src/tui-compiled/shared/refresh-file-lock.ts +0 -384
- package/src/tui-compiled/shared/util/error.ts +0 -9
- package/src/tui-compiled/shared/util/open-url.ts +0 -30
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OpenCode's log destination.
|
|
3
|
-
*
|
|
4
|
-
* The logger itself lives in the shared core so both hosts get the same
|
|
5
|
-
* redaction rules. What stays here is the part that is specific to this host:
|
|
6
|
-
* which file the lines go to, which level floor applies, and when the buffer is
|
|
7
|
-
* drained at process exit. Those are the only three things that read this
|
|
8
|
-
* host's environment variables, and the core reads none.
|
|
9
|
-
*
|
|
10
|
-
* The init runs at module load rather than from one call site because every
|
|
11
|
-
* entry point in this package — the plugin loader, the RPC server, the separate
|
|
12
|
-
* TUI process — reaches the logger through this module, and a core logger no
|
|
13
|
-
* host has initialised silently drops every line. Both values are passed as
|
|
14
|
-
* functions so the destination and level keep resolving on each write, which is
|
|
15
|
-
* what they do today.
|
|
16
|
-
*/
|
|
17
|
-
import { tmpdir } from 'node:os'
|
|
18
|
-
import { join } from 'node:path'
|
|
19
|
-
import {
|
|
20
|
-
flushLogs,
|
|
21
|
-
initLogger,
|
|
22
|
-
type Level,
|
|
23
|
-
} from '../shared/internal.ts'
|
|
24
|
-
|
|
25
|
-
export {
|
|
26
|
-
createLogger,
|
|
27
|
-
flushForTest,
|
|
28
|
-
flushLogs,
|
|
29
|
-
type Level,
|
|
30
|
-
redact,
|
|
31
|
-
redactStrings,
|
|
32
|
-
setLogLevel,
|
|
33
|
-
} from '../shared/internal.ts'
|
|
34
|
-
|
|
35
|
-
const LEVELS: readonly Level[] = ['error', 'warn', 'info', 'debug', 'trace']
|
|
36
|
-
|
|
37
|
-
export function getLogFile(): string {
|
|
38
|
-
return (
|
|
39
|
-
process.env.OPENCODE_OPENAI_AUTH_LOG_FILE ??
|
|
40
|
-
join(tmpdir(), 'opencode-openai-auth.log')
|
|
41
|
-
)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function getEnvLogLevel(): Level | undefined {
|
|
45
|
-
const env = process.env.OPENCODE_OPENAI_AUTH_LOG_LEVEL as Level | undefined
|
|
46
|
-
return env && LEVELS.includes(env) ? env : undefined
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
initLogger({ file: getLogFile, level: getEnvLogLevel })
|
|
50
|
-
|
|
51
|
-
// Under `bun test` the buffer is drained explicitly by the tests that assert on
|
|
52
|
-
// it, and registering a process-wide exit handler per test file is noise.
|
|
53
|
-
if (process.env.NODE_ENV !== 'test') process.on('exit', flushLogs)
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import type { Dirent } from 'node:fs'
|
|
2
|
-
import {
|
|
3
|
-
chmod,
|
|
4
|
-
mkdir,
|
|
5
|
-
readdir,
|
|
6
|
-
readFile,
|
|
7
|
-
rename,
|
|
8
|
-
rmdir,
|
|
9
|
-
unlink,
|
|
10
|
-
writeFile,
|
|
11
|
-
} from 'node:fs/promises'
|
|
12
|
-
import { join, resolve } from 'node:path'
|
|
13
|
-
import { createLogger } from './logger.ts'
|
|
14
|
-
|
|
15
|
-
const log = createLogger('rpc')
|
|
16
|
-
|
|
17
|
-
export interface PortFileEntry {
|
|
18
|
-
port: number
|
|
19
|
-
token: string
|
|
20
|
-
pid: number
|
|
21
|
-
startedAt: number
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function pidAlive(pid: number): boolean {
|
|
25
|
-
try {
|
|
26
|
-
process.kill(pid, 0)
|
|
27
|
-
return true
|
|
28
|
-
} catch (error) {
|
|
29
|
-
return (error as NodeJS.ErrnoException).code === 'EPERM'
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function isManagedRpcStateDir(name: string): boolean {
|
|
34
|
-
return /^(?:openai-auth-)?[0-9a-f]{16}$/.test(name)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function isUsablePortFileEntry(value: unknown): value is PortFileEntry {
|
|
38
|
-
return (
|
|
39
|
-
value !== null &&
|
|
40
|
-
typeof value === 'object' &&
|
|
41
|
-
!Array.isArray(value) &&
|
|
42
|
-
typeof (value as { pid?: unknown }).pid === 'number' &&
|
|
43
|
-
Number.isFinite((value as { pid: number }).pid) &&
|
|
44
|
-
typeof (value as { port?: unknown }).port === 'number' &&
|
|
45
|
-
Number.isFinite((value as { port: number }).port)
|
|
46
|
-
)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async function removeCorruptPortFile(portFile: string): Promise<void> {
|
|
50
|
-
log.debug('rpc corrupt port file', { pid: process.pid, portFile })
|
|
51
|
-
await unlink(portFile).catch(() => {})
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export async function writePortFile(
|
|
55
|
-
dir: string,
|
|
56
|
-
entry: { port: number; token: string; pid: number },
|
|
57
|
-
options: {
|
|
58
|
-
secureDir?: boolean
|
|
59
|
-
beforeWrite?: () => void | Promise<void>
|
|
60
|
-
} = {},
|
|
61
|
-
): Promise<string> {
|
|
62
|
-
// The directory can be removed by another project's sweep between our
|
|
63
|
-
// mkdir and the first writeFile/rename, so the whole create-then-rename
|
|
64
|
-
// unit is retried once on ENOENT. The retry recreates the directory; a
|
|
65
|
-
// persistent ENOENT (e.g. permission, read-only parent) will surface on
|
|
66
|
-
// the second attempt — failing fast beats an unbounded loop.
|
|
67
|
-
const writeOnce = async (): Promise<string> => {
|
|
68
|
-
await mkdir(dir, {
|
|
69
|
-
recursive: true,
|
|
70
|
-
mode: options.secureDir ? 0o700 : undefined,
|
|
71
|
-
})
|
|
72
|
-
if (options.secureDir) await chmod(dir, 0o700)
|
|
73
|
-
await options.beforeWrite?.()
|
|
74
|
-
const full: PortFileEntry = { ...entry, startedAt: Date.now() }
|
|
75
|
-
const target = join(dir, `port-${entry.pid}.json`)
|
|
76
|
-
const tmp = `${target}.${process.pid}.tmp`
|
|
77
|
-
await writeFile(tmp, JSON.stringify(full), {
|
|
78
|
-
encoding: 'utf8',
|
|
79
|
-
mode: 0o600,
|
|
80
|
-
})
|
|
81
|
-
await rename(tmp, target)
|
|
82
|
-
return target
|
|
83
|
-
}
|
|
84
|
-
try {
|
|
85
|
-
return await writeOnce()
|
|
86
|
-
} catch (error) {
|
|
87
|
-
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
88
|
-
return await writeOnce()
|
|
89
|
-
}
|
|
90
|
-
throw error
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export async function sweepRpcState(
|
|
95
|
-
root: string,
|
|
96
|
-
activeDir: string,
|
|
97
|
-
): Promise<void> {
|
|
98
|
-
let projectDirs: Dirent<string>[]
|
|
99
|
-
try {
|
|
100
|
-
projectDirs = await readdir(root, { withFileTypes: true })
|
|
101
|
-
} catch (error) {
|
|
102
|
-
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return
|
|
103
|
-
throw error
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const active = resolve(activeDir)
|
|
107
|
-
for (const projectDir of projectDirs) {
|
|
108
|
-
if (!projectDir.isDirectory() || !isManagedRpcStateDir(projectDir.name)) {
|
|
109
|
-
continue
|
|
110
|
-
}
|
|
111
|
-
const dir = join(root, projectDir.name)
|
|
112
|
-
let names: string[]
|
|
113
|
-
try {
|
|
114
|
-
names = await readdir(dir)
|
|
115
|
-
} catch (error) {
|
|
116
|
-
if ((error as NodeJS.ErrnoException).code === 'ENOENT') continue
|
|
117
|
-
throw error
|
|
118
|
-
}
|
|
119
|
-
for (const name of names) {
|
|
120
|
-
if (!name.startsWith('port-') || !name.endsWith('.json')) continue
|
|
121
|
-
const portFile = join(dir, name)
|
|
122
|
-
let raw: string | undefined
|
|
123
|
-
try {
|
|
124
|
-
raw = await readFile(portFile, 'utf8')
|
|
125
|
-
} catch {
|
|
126
|
-
continue
|
|
127
|
-
}
|
|
128
|
-
if (raw === undefined) continue
|
|
129
|
-
let parsed: unknown
|
|
130
|
-
try {
|
|
131
|
-
parsed = JSON.parse(raw)
|
|
132
|
-
} catch {
|
|
133
|
-
await removeCorruptPortFile(portFile)
|
|
134
|
-
continue
|
|
135
|
-
}
|
|
136
|
-
if (!isUsablePortFileEntry(parsed)) {
|
|
137
|
-
await removeCorruptPortFile(portFile)
|
|
138
|
-
continue
|
|
139
|
-
}
|
|
140
|
-
const entry = parsed
|
|
141
|
-
if (!pidAlive(entry.pid)) await unlink(portFile).catch(() => {})
|
|
142
|
-
}
|
|
143
|
-
if (resolve(dir) !== active) await rmdir(dir).catch(() => {})
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export async function discoverPortFile(
|
|
148
|
-
dir: string,
|
|
149
|
-
expectedPid?: number,
|
|
150
|
-
): Promise<PortFileEntry | null> {
|
|
151
|
-
let names: string[]
|
|
152
|
-
try {
|
|
153
|
-
names = await readdir(dir)
|
|
154
|
-
} catch {
|
|
155
|
-
return null
|
|
156
|
-
}
|
|
157
|
-
const live: PortFileEntry[] = []
|
|
158
|
-
for (const name of names) {
|
|
159
|
-
if (!name.startsWith('port-') || !name.endsWith('.json')) continue
|
|
160
|
-
try {
|
|
161
|
-
const parsed = JSON.parse(
|
|
162
|
-
await readFile(join(dir, name), 'utf8'),
|
|
163
|
-
) as PortFileEntry
|
|
164
|
-
if (Number.isFinite(parsed.port)) {
|
|
165
|
-
if (pidAlive(parsed.pid)) live.push(parsed)
|
|
166
|
-
else unlink(join(dir, name)).catch(() => {})
|
|
167
|
-
}
|
|
168
|
-
} catch {}
|
|
169
|
-
}
|
|
170
|
-
if (live.length === 0) return null
|
|
171
|
-
const candidates =
|
|
172
|
-
expectedPid !== undefined && expectedPid >= 1
|
|
173
|
-
? live.filter((entry) => entry.pid === expectedPid)
|
|
174
|
-
: []
|
|
175
|
-
const entries = candidates.length > 0 ? candidates : live
|
|
176
|
-
return entries.sort((a, b) => b.startedAt - a.startedAt)[0] ?? null
|
|
177
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The RPC payload types now live in the shared core, because both hosts build
|
|
3
|
-
* the same payloads. This file stays on disk as a re-export so the existing
|
|
4
|
-
* build entry and every importer that names `rpc/protocol` keep working.
|
|
5
|
-
*/
|
|
6
|
-
export type {
|
|
7
|
-
ApplyRequest,
|
|
8
|
-
ApplyResult,
|
|
9
|
-
CommandModalName,
|
|
10
|
-
OpenDialogPayload,
|
|
11
|
-
RpcNotification,
|
|
12
|
-
} from '../shared/internal.ts'
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { discoverPortFile, type PortFileEntry } from './rpc-port-file.ts'
|
|
2
|
-
import type { ApplyRequest, ApplyResult, RpcNotification } from './rpc-protocol.ts'
|
|
3
|
-
|
|
4
|
-
export interface RpcClient {
|
|
5
|
-
pending: (
|
|
6
|
-
lastReceivedId: number,
|
|
7
|
-
sessionId?: string,
|
|
8
|
-
) => Promise<RpcNotification[]>
|
|
9
|
-
apply: (request: ApplyRequest, timeoutMs?: number) => Promise<ApplyResult>
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const DEFAULT_RPC_TIMEOUT_MS = 2_000
|
|
13
|
-
|
|
14
|
-
async function call<T>(
|
|
15
|
-
dir: string,
|
|
16
|
-
expectedPid: number | undefined,
|
|
17
|
-
onSelected: ((entry: PortFileEntry | null) => void) | undefined,
|
|
18
|
-
method: string,
|
|
19
|
-
params: Record<string, unknown>,
|
|
20
|
-
timeoutMs = DEFAULT_RPC_TIMEOUT_MS,
|
|
21
|
-
): Promise<T | null> {
|
|
22
|
-
const entry = await discoverPortFile(dir, expectedPid)
|
|
23
|
-
onSelected?.(entry)
|
|
24
|
-
if (!entry) return null
|
|
25
|
-
const controller = new AbortController()
|
|
26
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs)
|
|
27
|
-
try {
|
|
28
|
-
const res = await fetch(`http://127.0.0.1:${entry.port}/rpc/${method}`, {
|
|
29
|
-
method: 'POST',
|
|
30
|
-
headers: {
|
|
31
|
-
'content-type': 'application/json',
|
|
32
|
-
authorization: `Bearer ${entry.token}`,
|
|
33
|
-
},
|
|
34
|
-
body: JSON.stringify(params),
|
|
35
|
-
signal: controller.signal,
|
|
36
|
-
})
|
|
37
|
-
if (!res.ok) return null
|
|
38
|
-
return (await res.json()) as T
|
|
39
|
-
} catch {
|
|
40
|
-
return null
|
|
41
|
-
} finally {
|
|
42
|
-
clearTimeout(timer)
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function createRpcClient(
|
|
47
|
-
dir: string,
|
|
48
|
-
expectedPid?: number,
|
|
49
|
-
onSelected?: (entry: PortFileEntry | null) => void,
|
|
50
|
-
): RpcClient {
|
|
51
|
-
let reportedSelection = false
|
|
52
|
-
const reportSelected = (entry: PortFileEntry | null) => {
|
|
53
|
-
if (reportedSelection) return
|
|
54
|
-
reportedSelection = true
|
|
55
|
-
onSelected?.(entry)
|
|
56
|
-
}
|
|
57
|
-
return {
|
|
58
|
-
async pending(lastReceivedId, sessionId) {
|
|
59
|
-
const out = await call<{ messages: RpcNotification[] }>(
|
|
60
|
-
dir,
|
|
61
|
-
expectedPid,
|
|
62
|
-
reportSelected,
|
|
63
|
-
'pending-notifications',
|
|
64
|
-
{ lastReceivedId, sessionId },
|
|
65
|
-
)
|
|
66
|
-
return out?.messages ?? []
|
|
67
|
-
},
|
|
68
|
-
async apply(request, timeoutMs) {
|
|
69
|
-
const out = await call<ApplyResult>(
|
|
70
|
-
dir,
|
|
71
|
-
expectedPid,
|
|
72
|
-
reportSelected,
|
|
73
|
-
'apply',
|
|
74
|
-
{
|
|
75
|
-
...request,
|
|
76
|
-
},
|
|
77
|
-
timeoutMs,
|
|
78
|
-
)
|
|
79
|
-
return out ?? { text: 'apply failed', knobs: {} }
|
|
80
|
-
},
|
|
81
|
-
}
|
|
82
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto'
|
|
2
|
-
import { homedir, tmpdir } from 'node:os'
|
|
3
|
-
import { dirname, join, resolve } from 'node:path'
|
|
4
|
-
|
|
5
|
-
const RPC_DIR_ENV = 'OPENCODE_OPENAI_AUTH_RPC_DIR'
|
|
6
|
-
|
|
7
|
-
export interface RpcDirResolution {
|
|
8
|
-
dir: string
|
|
9
|
-
secureDir: boolean
|
|
10
|
-
sweepRoot?: string
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function rpcHash(projectDirectory: string): string {
|
|
14
|
-
return createHash('sha256')
|
|
15
|
-
.update(projectDirectory)
|
|
16
|
-
.digest('hex')
|
|
17
|
-
.slice(0, 16)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function defaultRpcRoot(): string {
|
|
21
|
-
const base = process.env.XDG_STATE_HOME || join(homedir(), '.local', 'state')
|
|
22
|
-
return join(base, 'cortexkit', 'openai-auth', 'rpc')
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Both processes must resolve the SAME dir from the SAME project directory.
|
|
26
|
-
export function getRpcDir(projectDirectory: string): string {
|
|
27
|
-
const override = process.env[RPC_DIR_ENV]?.trim()
|
|
28
|
-
// A relative override is anchored to projectDirectory (shared by both processes)
|
|
29
|
-
// so server and TUI halves always resolve the same dir. An absolute override is
|
|
30
|
-
// used as-is (resolve(base, absolute) returns the absolute path unchanged).
|
|
31
|
-
if (override) return resolve(projectDirectory, override)
|
|
32
|
-
return join(defaultRpcRoot(), `openai-auth-${rpcHash(projectDirectory)}`)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export async function resolveRpcDir(
|
|
36
|
-
projectDirectory: string,
|
|
37
|
-
): Promise<RpcDirResolution> {
|
|
38
|
-
const override = process.env[RPC_DIR_ENV]?.trim()
|
|
39
|
-
if (override) {
|
|
40
|
-
return { dir: resolve(projectDirectory, override), secureDir: false }
|
|
41
|
-
}
|
|
42
|
-
const dir = getRpcDir(projectDirectory)
|
|
43
|
-
return { dir, secureDir: true, sweepRoot: dirname(dir) }
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export { tmpdir }
|