Files
orca/src/main/opencode/status-plugin-endpoint-source.ts
T
Neil 48e63c015f refactor agent config and auth services (#16195)
* refactor: split agent config and auth services

* chore: repoint wsl and global-fetch guards at split module paths

* fix: restore merge-base Claude CLI error propagation

Drop the secret-redaction rewriting added to Claude CLI error paths in the
refactor: spawn errors again reject with the original Error (preserving
.code/.errno/.syscall/.stack) and command output/auth-status logs are no
longer rewritten.
2026-08-24 23:15:01 -07:00

100 lines
5.0 KiB
TypeScript

export function getStatusPluginEndpointSource(): string[] {
return [
'// Why: process-lifetime guard so a recurring parse error on a malformed',
"// endpoint file does not spam OpenCode's stderr once per hook post.",
'// This guard lives inside the plugin source because the plugin runs in',
"// OpenCode's Node process (not Orca's) and has no access to server.ts's",
'// equivalent warnedVersions / warnedEnvs Sets.',
'let warnedBadEndpoint = false;',
'',
'// Why: message.part.updated can fire many times per second during a',
'// streaming assistant reply, and each post() calls resolveHookCoords()',
'// which reads the endpoint file. The file only changes on Orca restart',
'// (rare), so a stat+mtime check is substantially cheaper than a full',
'// readFileSync+parse on every streamed part. On stat error we fall',
'// through to parse so the fail-open behavior is preserved.',
'let cachedEndpointKey = "";',
'let cachedEndpointValues = null;',
'',
'function readEndpointFile() {',
' const path = process.env.ORCA_AGENT_HOOK_ENDPOINT;',
' if (!path) return null;',
' try {',
' const fs = require("fs");',
' try {',
' const stat = fs.statSync(path);',
' // Why: cache key combines mtime + size + inode. renameSync (used by',
' // writeEndpointFile on the Orca side) allocates a fresh inode on',
' // POSIX and a new Windows file ID on NTFS, so ino changes on every',
' // legitimate rewrite even when mtimeMs resolution is coarse and size',
' // happens to match.',
' const cacheKey = stat.mtimeMs + ":" + stat.size + ":" + stat.ino;',
' if (cacheKey === cachedEndpointKey && cachedEndpointValues) {',
' return cachedEndpointValues;',
' }',
' const contents = fs.readFileSync(path, "utf8");',
' const out = {};',
' for (const line of contents.split(/\\r?\\n/)) {',
' // Why: Windows endpoint.cmd uses `set KEY=VALUE`; Unix endpoint.env',
' // uses `KEY=VALUE`. Making `set ` optional lets the same parser',
' // handle both without platform detection in the plugin. Allow',
' // digits in the key for forward-compat with future ORCA_AGENT_HOOK_*',
' // names that may contain numerics, and strip a trailing CR so',
' // mixed-EOL files with lone `\\r` do not leak CR into the value.',
' const m = line.match(/^(?:set\\s+)?([A-Z0-9_]+)=(.*)$/);',
' if (m) out[m[1]] = m[2].replace(/\\r$/, "");',
' }',
' cachedEndpointKey = cacheKey;',
' cachedEndpointValues = out;',
' return out;',
' } catch (ioErr) {',
' // Why: any stat or read failure (file yanked mid-read, permission',
' // race, unlink between stat and readFileSync) must invalidate the',
' // cache so a transient failure does not lock in a stale parse for',
' // the remaining process lifetime; rethrow to the outer catch.',
' cachedEndpointKey = "";',
' cachedEndpointValues = null;',
' throw ioErr;',
' }',
' } catch (err) {',
' // Why: warn once per process if the file exists but is unreadable or',
' // malformed — a persistent, silently-swallowed parse error would',
' // otherwise leave the plugin falling back to stale process.env on',
' // every post with no signal. ENOENT / missing env var is the normal',
' // pre-install case; stay silent for it.',
' if (err && err.code !== "ENOENT" && !warnedBadEndpoint) {',
' warnedBadEndpoint = true;',
' console.warn("[orca-hook] failed to parse endpoint file:", err.message);',
' }',
' return null;',
' }',
'}',
'',
'function resolveHookCoords() {',
' // Why: prefer the on-disk endpoint file over process.env because env was',
' // frozen when OpenCode was fork()ed — stale after an Orca restart. The',
' // file is rewritten on every Orca start(), so sourcing it per post lets',
' // a long-running OpenCode session reach the current server. Falls back',
' // to process.env when the file is absent (first-run / pre-endpoint-file / Orca',
' // never started writing the file).',
' const fileEnv = readEndpointFile() || {};',
' return {',
' port: fileEnv.ORCA_AGENT_HOOK_PORT || process.env.ORCA_AGENT_HOOK_PORT,',
' token: fileEnv.ORCA_AGENT_HOOK_TOKEN || process.env.ORCA_AGENT_HOOK_TOKEN,',
' env: fileEnv.ORCA_AGENT_HOOK_ENV || process.env.ORCA_AGENT_HOOK_ENV || "",',
' version: fileEnv.ORCA_AGENT_HOOK_VERSION || process.env.ORCA_AGENT_HOOK_VERSION || "",',
' };',
'}',
'',
'function hookEndpointKey() {',
' const coords = resolveHookCoords();',
' return [coords.port || "", coords.token || "", coords.env, coords.version].join("\\u0000");',
'}',
'',
'function getStatusType(event) {',
' return event?.properties?.status?.type ?? event?.status?.type ?? null;',
'}',
''
]
}