@pushary/codex-app-server 0.1.0 → 0.2.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/COMPATIBILITY.md +29 -2
- package/NOTICE +3 -2
- package/README.md +7 -3
- package/dist/index.cjs +5 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/examples/README.md +1 -1
- package/examples/simulated-host.mjs +1 -1
- package/package.json +2 -2
package/COMPATIBILITY.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Compatibility evidence
|
|
2
2
|
|
|
3
|
-
Status: experimental 0.
|
|
3
|
+
Status: experimental 0.2.0 release; certified for Codex 0.160.1 and 0.167.0.
|
|
4
4
|
|
|
5
5
|
| Boundary | Evidence |
|
|
6
6
|
| --- | --- |
|
|
7
|
-
| Codex | npm `@openai/codex@0.160.1`; generated schemas and SHA-256 provenance under `test/fixtures
|
|
7
|
+
| Codex | npm `@openai/codex@0.160.1` and `@openai/codex@0.167.0`; generated schemas and SHA-256 provenance under `test/fixtures/<version>` |
|
|
8
8
|
| Transport | newline JSON over stdio; 1 MiB frame cap, bounded FIFO, separate host RPC IDs |
|
|
9
9
|
| Thread policy | real initialize/start response; user reviewer and read-only sandbox |
|
|
10
10
|
| Command | real `exec_command` request, accept/deny, absent side effect before approval, file written only after accept |
|
|
@@ -82,3 +82,30 @@ All contents are present, but multiline review is less readable. The display fix
|
|
|
82
82
|
is deferred; this release preserves the certified presentation. Native Codex
|
|
83
83
|
questions, restart recovery and exactly-once execution remain unsupported as
|
|
84
84
|
specified above. No real model-provider behavior was certified by this fixture.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
## Codex 0.167.0 certification, 2026-11-07
|
|
88
|
+
|
|
89
|
+
The weekly protocol check found Codex 0.167.0 differs from 0.160.1 in two of the
|
|
90
|
+
eleven certified schemas:
|
|
91
|
+
|
|
92
|
+
- `CommandExecutionRequestApprovalParams`: the approval kind adds `humanCommand`, a
|
|
93
|
+
managed checkpoint that Codex sends only to a host declaring the
|
|
94
|
+
`requiredHumanApproval` initialize capability. The example host doesn't declare it,
|
|
95
|
+
and the adapter refuses any kind other than `command`, so such a request goes to
|
|
96
|
+
native review. A unit test covers it.
|
|
97
|
+
- `ThreadStartResponse`: new optional fields and changed unions inside turn, item, user
|
|
98
|
+
input, error and message-phase definitions. `certifiedThread` reads none of them; the
|
|
99
|
+
thread ID, status, approval policy, reviewer and sandbox it reads are unchanged.
|
|
100
|
+
|
|
101
|
+
The other nine schemas are byte-identical.
|
|
102
|
+
|
|
103
|
+
On Node 24.3.0/macOS, with `@openai/codex@0.167.0` installed and verified through
|
|
104
|
+
`codex --version`:
|
|
105
|
+
- 112 unit and race tests passed;
|
|
106
|
+
- the 8 real-binary scenarios passed, with requests validated against the 0.167.0 schemas: command approve, deny, privacy refusal and disconnect; file approve, deny and disconnect; and the native question fallback;
|
|
107
|
+
- the 7 host lifecycle checks passed.
|
|
108
|
+
|
|
109
|
+
The physical-phone certification above was not repeated. Partner delivery, answers,
|
|
110
|
+
expiry and recipient enforcement run through code this release does not change; the
|
|
111
|
+
Codex side of those paths is what the real-binary scenarios re-verify.
|
package/NOTICE
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
Pushary Codex app-server adapter: MIT (see LICENSE).
|
|
2
2
|
|
|
3
3
|
Generated test schema fixtures are derived without manual edits from OpenAI Codex
|
|
4
|
-
0.160.1, https://github.com/openai/codex/tree/rust-v0.160.1
|
|
4
|
+
0.160.1 and 0.167.0, https://github.com/openai/codex/tree/rust-v0.160.1 and
|
|
5
|
+
https://github.com/openai/codex/tree/rust-v0.167.0.
|
|
5
6
|
Copyright OpenAI. Licensed under the Apache License, Version 2.0.
|
|
6
7
|
The source checkout includes the complete upstream license at
|
|
7
|
-
test/fixtures
|
|
8
|
+
test/fixtures/<version>/LICENSE. Published npm artifacts contain no schema fixtures.
|
|
8
9
|
The upstream CLI is a development dependency, not bundled in this package.
|
package/README.md
CHANGED
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Route live Codex app-server command and file approvals to an enrolled Pushary Partner customer. The host keeps control of Codex authentication, process lifetime, native UI, and response delivery. This MIT package uses only the public `@pushary/server` SDK.
|
|
4
4
|
|
|
5
|
-
Experimental release:
|
|
5
|
+
Experimental release: certified for **Codex 0.160.1 and 0.167.0**, Node 22/24, and **@pushary/server >=2.3.0**. See [compatibility and verification](COMPATIBILITY.md).
|
|
6
|
+
|
|
7
|
+
[Connect a test customer](https://pushary.com/sign-up?from=agent&plan=partner&utm_source=github&utm_medium=oss-adapter&utm_campaign=pushary-codex-app-server&utm_content=partner-start) · [Partner setup guide](https://pushary.com/docs/agents/build/quickstart?utm_source=github&utm_medium=oss-adapter&utm_campaign=pushary-codex-app-server&utm_content=guide)
|
|
8
|
+
|
|
9
|
+
Live delivery requires a Pushary Partner workspace and an enrolled customer. The compatibility limits above still apply.
|
|
6
10
|
|
|
7
11
|
## Install and enroll
|
|
8
12
|
|
|
@@ -31,7 +35,7 @@ const approvals = createPusharyCodexHandler({
|
|
|
31
35
|
apiKey: partnerApiKey,
|
|
32
36
|
tenantId: authenticatedTenantId,
|
|
33
37
|
externalId: authenticatedCustomerId,
|
|
34
|
-
codexVersion: '0.
|
|
38
|
+
codexVersion: '0.167.0',
|
|
35
39
|
agentName: 'My coding assistant',
|
|
36
40
|
maySendSubject: subject => customerPrivacyPolicy.allows(subject),
|
|
37
41
|
sendResponse: reply => connection.enqueue(reply),
|
|
@@ -60,7 +64,7 @@ Register the effective **result**, not the parameters you requested. Only `on-re
|
|
|
60
64
|
|
|
61
65
|
- Full command, working directory and reason. Only one-request `accept`, `decline` or `cancel` is emitted. Known optional exec-policy suggestions do not grant a standing rule. Network, remote environments, stdin, additional permissions and unknown decision options require native handling.
|
|
62
66
|
- Complete file patches cached from `item/started` and `item/fileChange/patchUpdated`. A changed patch invalidates an outstanding approval. Missing or ambiguous patches and `grantRoot` are refused. Every path, operation, rename and diff is presented; nothing is truncated.
|
|
63
|
-
- Optional `experimentalQuestions: true` accepts a bounded protocol subset: 1
|
|
67
|
+
- Optional `experimentalQuestions: true` accepts a bounded protocol subset: 1 to 3 blocking, nonsecret questions with `isOther:false`. **The built-in question tool in Codex 0.160.1 and 0.167.0 always sets `isOther:true`, so its questions need native UI.** The included headless host interrupts them. Synthetic protocol tests cover the smaller subset; they are not evidence of native phone-question support.
|
|
64
68
|
|
|
65
69
|
MCP elicitation, permissions, dynamic tools, account/auth callbacks and legacy v1 approvals remain host responsibilities. The [example host](examples/stdio-host.mjs) has explicit fail-closed fallbacks.
|
|
66
70
|
|
package/dist/index.cjs
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
+
CERTIFIED_CODEX_VERSIONS: () => CERTIFIED_CODEX_VERSIONS,
|
|
23
24
|
connect: () => connect,
|
|
24
25
|
createPusharyCodexHandler: () => createPusharyCodexHandler
|
|
25
26
|
});
|
|
@@ -35,6 +36,8 @@ var import_adapters = require("@pushary/server/adapters");
|
|
|
35
36
|
var COMMAND = "item/commandExecution/requestApproval";
|
|
36
37
|
var FILES = "item/fileChange/requestApproval";
|
|
37
38
|
var QUESTIONS = "item/tool/requestUserInput";
|
|
39
|
+
var CERTIFIED_CODEX_VERSIONS = ["0.160.1", "0.167.0"];
|
|
40
|
+
var isCertifiedCodexVersion = (value) => CERTIFIED_CODEX_VERSIONS.some((version) => version === value);
|
|
38
41
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
39
42
|
var isId = (value) => typeof value === "string" || typeof value === "number" && Number.isSafeInteger(value);
|
|
40
43
|
var isText = (value) => typeof value === "string" && value.length > 0;
|
|
@@ -209,7 +212,7 @@ var rpcKey = (id) => JSON.stringify([typeof id, id]);
|
|
|
209
212
|
var createPusharyCodexHandler = (configuration) => {
|
|
210
213
|
const config = Object.freeze({ ...configuration });
|
|
211
214
|
const timeoutMs = config.timeoutMs ?? 3e5;
|
|
212
|
-
if (config.codexVersion
|
|
215
|
+
if (!isCertifiedCodexVersion(config.codexVersion) || !Number.isInteger(timeoutMs) || timeoutMs < 6e4 || timeoutMs > 6e5 || !config.tenantId?.trim() || !config.externalId?.trim()) throw new TypeError("Invalid Codex adapter configuration");
|
|
213
216
|
if ([config.sendResponse, config.requestTurnInterrupt, config.onEvent, config.maySendSubject].some((callback) => typeof callback !== "function")) throw new TypeError("All host callbacks are required");
|
|
214
217
|
const decisions = (0, import_server2.createPusharyServer)({ apiKey: config.apiKey, baseUrl: config.baseUrl, requestTimeoutMs: 1e4 }).decisions;
|
|
215
218
|
const generation = (0, import_node_crypto.randomUUID)();
|
|
@@ -618,6 +621,7 @@ var createPusharyCodexHandler = (configuration) => {
|
|
|
618
621
|
var connect = (0, import_adapters2.createAdapterKernel)("Codex app-server").connect;
|
|
619
622
|
// Annotate the CommonJS export names for ESM import in node:
|
|
620
623
|
0 && (module.exports = {
|
|
624
|
+
CERTIFIED_CODEX_VERSIONS,
|
|
621
625
|
connect,
|
|
622
626
|
createPusharyCodexHandler
|
|
623
627
|
});
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/handler.ts","../src/protocol.ts","../src/presentation.ts","../src/partner-decisions.ts","../src/request-lifecycle.ts"],"sourcesContent":["import { createAdapterKernel } from '@pushary/server/adapters'\nexport { createPusharyCodexHandler } from './handler'\nexport type { CodexRequestId, CodexReply, CodexDispatchResult, CodexReviewSubject, PusharyCodexConfig, PusharyCodexEvent, PusharyCodexHandler } from './types'\nexport const connect = createAdapterKernel('Codex app-server').connect\n","import { randomUUID } from 'node:crypto'\nimport { createPusharyServer, isApproved, type CreateDecision } from '@pushary/server'\nimport { decisionFingerprint } from '@pushary/server/adapters'\nimport { COMMAND, FILES, QUESTIONS, certifiedThread, fileChangesOf, identityOf, isId, isRecord, isText, subjectOf } from './protocol'\nimport { presentSubject, type PhoneQuestion } from './presentation'\nimport { decisionFailureReason, decisionSnapshot, delay, isRetryable, withRetry, type DecisionSnapshot } from './partner-decisions'\nimport { transitionRequest, type RequestCompletion, type RequestState } from './request-lifecycle'\nimport type { CodexDispatchResult, CodexReviewSubject, FileChange, PusharyCodexConfig, PusharyCodexEvent, PusharyCodexHandler, RequestIdentity } from './types'\n\nconst MAX_PENDING = 8\nconst MAX_THREADS = 32\nconst MAX_ITEMS = 128\nconst MAX_CACHE_BYTES = 4 * 1024 * 1024\nconst MAX_REQUESTS = 4096\nconst CLEANUP_MS = 5000\nconst MIN_QUESTION_BUDGET_MS = 10_000\ninterface OwnedRequest {\n readonly identity: RequestIdentity\n readonly declineDecision: 'decline' | 'cancel'\n readonly digest: string\n readonly envelopeDigest: string\n readonly subject: CodexReviewSubject\n readonly controller: AbortController\n readonly deadline: number\n readonly timer: ReturnType<typeof setTimeout>\n readonly decisionIds: Set<string>\n readonly cleanupIds: Set<string>\n state: RequestState\n cleanupDeadline: number\n}\ninterface CachedPatch { readonly changes: readonly FileChange[] | null; readonly digest: string; readonly bytes: number }\nconst itemKey = (threadId: string, turnId: string, itemId: string): string => JSON.stringify([threadId, turnId, itemId])\nconst turnKey = (threadId: string, turnId: string): string => JSON.stringify([threadId, turnId])\nconst rpcKey = (id: string | number): string => JSON.stringify([typeof id, id])\n\nexport const createPusharyCodexHandler = (configuration: PusharyCodexConfig): PusharyCodexHandler => {\n const config = Object.freeze({ ...configuration })\n const timeoutMs = config.timeoutMs ?? 300_000\n if (config.codexVersion !== '0.160.1' || !Number.isInteger(timeoutMs) || timeoutMs < 60_000 || timeoutMs > 600_000 || !config.tenantId?.trim() || !config.externalId?.trim()) throw new TypeError('Invalid Codex adapter configuration')\n if ([config.sendResponse, config.requestTurnInterrupt, config.onEvent, config.maySendSubject].some(callback => typeof callback !== 'function')) throw new TypeError('All host callbacks are required')\n const decisions = createPusharyServer({ apiKey: config.apiKey, baseUrl: config.baseUrl, requestTimeoutMs: 10_000 }).decisions\n const generation = randomUUID()\n const threads = new Set<string>()\n const requests = new Map<string, OwnedRequest>()\n const closedRequestIds = new Set<string>()\n const turns = new Map<string, { readonly threadId: string; readonly turnId: string; terminal: boolean }>()\n const completedItems = new Set<string>()\n const patches = new Map<string, CachedPatch>()\n const jobs = new Set<Promise<void>>()\n const cleanupFailures: string[] = []\n const cleanupControllers = new Set<AbortController>()\n let cacheBytes = 0\n let disposed = false\n let disposal: Promise<{ readonly cleanupFailures: readonly string[] }> | undefined\n let disposalDeadline = Infinity\n const emit = (event: PusharyCodexEvent): void => {\n try { config.onEvent(event) } catch { console.error('Pushary Codex onEvent callback failed') }\n }\n const eventFor = (request: OwnedRequest, type: PusharyCodexEvent['type'], reason?: string, decisionId?: string): void => emit({ type, requestId: request.identity.id, threadId: request.identity.threadId, turnId: request.identity.turnId, subjectDigest: request.digest, decisionId, reason })\n const track = (job: Promise<void>): void => { jobs.add(job); void job.finally(() => jobs.delete(job)).catch(() => undefined) }\n const cleanupFailed = (request: OwnedRequest, id: string): void => {\n cleanupFailures.push(id)\n eventFor(request, 'cleanup_failed', 'Decision cleanup not confirmed before deadline', id)\n }\n const cleanup = async (request: OwnedRequest, id: string): Promise<void> => {\n if (request.cleanupIds.has(id)) return\n request.cleanupIds.add(id)\n const remaining = Math.min(request.cleanupDeadline, disposalDeadline) - performance.now()\n if (remaining <= 0) { cleanupFailed(request, id); return }\n const controller = new AbortController()\n cleanupControllers.add(controller)\n const timer = setTimeout(() => controller.abort(), remaining)\n try {\n for (let attempt = 0; attempt < 3; attempt += 1) {\n try {\n const result: unknown = await decisions.cancel(id, { signal: controller.signal })\n if (!isRecord(result) || result.decisionId !== id || typeof result.cancelled !== 'boolean') throw new Error('Invalid cancellation result')\n if (result.cancelled) return\n const latest: unknown = await decisions.get(id, { signal: controller.signal })\n if (isRecord(latest) && (latest.type === 'confirm' || latest.type === 'select' || latest.type === 'input')) {\n const snapshot = decisionSnapshot(latest, latest.type, id)\n if (snapshot.status !== 'pending') return\n }\n throw new TypeError('Cancellation still pending')\n } catch (error) {\n if (controller.signal.aborted || attempt === 2 || !isRetryable(error)) throw error\n await delay(attempt === 0 ? 100 : 300, controller.signal)\n }\n }\n } catch { cleanupFailed(request, id) } finally { clearTimeout(timer); cleanupControllers.delete(controller) }\n }\n const beginCleanup = (request: OwnedRequest): void => {\n clearTimeout(request.timer)\n request.cleanupDeadline = Math.min(performance.now() + CLEANUP_MS, disposalDeadline)\n request.controller.abort()\n for (const id of request.decisionIds) track(cleanup(request, id))\n }\n const completeRequest = (request: OwnedRequest, completion: RequestCompletion): void => {\n const transition = transitionRequest(request.state, completion, {\n id: request.identity.id,\n isQuestion: request.subject.kind === 'questions',\n replyAllowed: contextLive(request),\n deadlineElapsed: performance.now() >= request.deadline,\n })\n if (!transition) return\n request.state = transition.state\n beginCleanup(request)\n if (transition.reply && contextLive(request)) {\n const interrupted = transition.interruption === null || interrupt(request.identity, transition.interruption)\n if (interrupted && contextLive(request)) {\n try { config.sendResponse(transition.reply) } catch { fatal('Response enqueue failed; close connection') }\n }\n }\n if (transition.abandonment !== null) eventFor(request, 'request_abandoned', transition.abandonment)\n }\n const dispose = (): Promise<{ readonly cleanupFailures: readonly string[] }> => {\n if (disposal) return disposal\n disposed = true\n disposalDeadline = performance.now() + CLEANUP_MS\n config.signal?.removeEventListener('abort', onAbort)\n let resolveDisposal: (value: { readonly cleanupFailures: readonly string[] }) => void = () => undefined\n disposal = new Promise(resolve => { resolveDisposal = resolve })\n threads.clear()\n patches.clear()\n cacheBytes = 0\n for (const request of requests.values()) completeRequest(request, { kind: 'abandon', reason: 'Connection disposed' })\n const finish = async (): Promise<void> => {\n const controller = new AbortController()\n const drain = async (): Promise<void> => { while (jobs.size > 0 && performance.now() < disposalDeadline) await Promise.allSettled([...jobs]) }\n await Promise.race([drain(), delay(CLEANUP_MS, controller.signal)]).catch(() => undefined)\n controller.abort()\n for (const cleanupController of cleanupControllers) cleanupController.abort()\n await Promise.resolve()\n resolveDisposal({ cleanupFailures: [...cleanupFailures] })\n }\n void finish()\n return disposal\n }\n const fatal = (reason: string): void => {\n void dispose()\n emit({ type: 'reply_failed', reason })\n }\n const overflow = (): void => { void dispose(); emit({ type: 'capacity_exceeded', reason: 'Connection must close; bounded adapter capacity exceeded' }) }\n const stateCount = (): number => requests.size + closedRequestIds.size + turns.size + completedItems.size\n const rememberTurn = (threadId: string, turnId: string, terminal: boolean): boolean => {\n const key = turnKey(threadId, turnId)\n const previous = turns.get(key)\n if (previous) { previous.terminal ||= terminal; return true }\n if (stateCount() >= MAX_REQUESTS) { overflow(); return false }\n turns.set(key, { threadId, turnId, terminal })\n return true\n }\n const contextEnded = (identity: RequestIdentity): boolean => turns.get(turnKey(identity.threadId, identity.turnId))?.terminal === true || completedItems.has(itemKey(identity.threadId, identity.turnId, identity.itemId))\n const contextLive = (request: OwnedRequest): boolean => !disposed && !contextEnded(request.identity) && threads.has(request.identity.threadId)\n const live = (request: OwnedRequest): boolean => request.state === 'pending' && contextLive(request) && performance.now() < request.deadline\n const interrupt = (identity: RequestIdentity, reason: string): boolean => {\n try { config.requestTurnInterrupt(identity.threadId, identity.turnId, reason); return !disposed } catch { fatal('Turn interrupt enqueue failed; close connection'); return false }\n }\n const fenceTurn = (threadId: string, turnId: string, reason: string): void => {\n if (!rememberTurn(threadId, turnId, true)) return\n for (const request of requests.values()) if (request.identity.threadId === threadId && request.identity.turnId === turnId) completeRequest(request, { kind: 'abandon', reason })\n for (const key of patches.keys()) {\n if (key.startsWith(JSON.stringify([threadId, turnId]).slice(0, -1) + ',')) { cacheBytes -= patches.get(key)?.bytes ?? 0; patches.delete(key) }\n }\n }\n const invalidateTurn = (threadId: string, turnId: string, reason: string): void => {\n const accepted = [...requests.values()].find(request => request.identity.threadId === threadId && request.identity.turnId === turnId && request.state === 'accepted' && !contextEnded(request.identity))\n fenceTurn(threadId, turnId, reason)\n if (accepted) {\n if (!disposed) interrupt(accepted.identity, reason)\n eventFor(accepted, 'request_abandoned', 'Invalidated after acceptance enqueue; execution outcome unknown')\n }\n }\n const unregisterThread = (threadId: string): void => {\n threads.delete(threadId)\n for (const turn of turns.values()) if (turn.threadId === threadId) invalidateTurn(threadId, turn.turnId, 'Thread unregistered')\n for (const key of patches.keys()) if (key.startsWith(JSON.stringify([threadId]).slice(0, -1) + ',')) { cacheBytes -= patches.get(key)?.bytes ?? 0; patches.delete(key) }\n }\n const createAndWait = async (request: OwnedRequest, phone: PhoneQuestion, ordinal: number): Promise<DecisionSnapshot> => {\n const payload: CreateDecision = { question: phone.question, type: phone.type, options: phone.options, context: phone.context, externalId: config.externalId, agentName: config.agentName ?? 'Codex', wait: false, requireReachable: true, expiresInSeconds: Math.ceil(timeoutMs / 1000), idempotencyKey: decisionFingerprint({ tenantId: config.tenantId, externalId: config.externalId, generation, ...request.identity, subjectDigest: request.digest, ordinal, questionId: phone.questionId ?? null }) }\n let raw: unknown\n try { raw = await withRetry(() => decisions.create(payload, { signal: request.controller.signal }), request.controller.signal) } catch (error) {\n if (request.controller.signal.aborted || isRetryable(error)) eventFor(request, 'create_outcome_unknown', 'Create may have reached server; TTL bounds residual prompt')\n throw error\n }\n if (isRecord(raw) && isText(raw.decisionId)) {\n request.decisionIds.add(raw.decisionId)\n if (!live(request)) { track(cleanup(request, raw.decisionId)); throw new Error('Request no longer live') }\n }\n if (!isRecord(raw) || !isText(raw.decisionId)) eventFor(request, 'create_outcome_unknown', 'Create returned no usable decision ID')\n let snapshot = decisionSnapshot(raw, phone.type)\n eventFor(request, 'decision_created', undefined, snapshot.decisionId)\n while (snapshot.status === 'pending') {\n if (!live(request)) throw new Error('Request no longer live')\n const next: unknown = await withRetry(() => decisions.get(snapshot.decisionId, { wait: 5, signal: request.controller.signal }), request.controller.signal)\n snapshot = decisionSnapshot(next, phone.type, snapshot.decisionId)\n if (snapshot.status === 'pending') await delay(50, request.controller.signal)\n }\n request.decisionIds.delete(snapshot.decisionId)\n eventFor(request, 'decision_settled', snapshot.status, snapshot.decisionId)\n return snapshot\n }\n const runRequest = async (request: OwnedRequest, phones: readonly PhoneQuestion[]): Promise<void> => {\n try {\n const answers: Record<string, { answers: readonly string[] }> = Object.create(null)\n for (const [ordinal, phone] of phones.entries()) {\n if (!live(request)) return\n if (ordinal > 0 && request.deadline - performance.now() < MIN_QUESTION_BUDGET_MS) { completeRequest(request, { kind: 'refuse', reason: 'Insufficient time for another question' }); return }\n const result = await createAndWait(request, phone, ordinal)\n if (!live(request)) return\n if (request.subject.kind !== 'questions') {\n const approved = result.type === 'confirm' && result.status === 'answered' && isApproved({ status: result.status, type: result.type, value: result.value })\n completeRequest(request, { kind: 'reply', reply: { id: request.identity.id, result: { decision: approved ? 'accept' : request.declineDecision } } })\n return\n }\n if (!result.answered || !result.value?.trim() || result.value.length > 2000 || (phone.options && !phone.options.includes(result.value))) { completeRequest(request, { kind: 'refuse', reason: 'Question did not receive a valid answer' }); return }\n const question = request.subject.questions[ordinal]\n if (!question || !phone.questionId) throw new Error('Question identity missing')\n const selectedIndex = phone.options?.indexOf(result.value)\n const answer = selectedIndex !== undefined ? question.options?.[selectedIndex]?.label : result.value\n if (answer === undefined) throw new Error('Question option missing')\n answers[phone.questionId] = { answers: [answer] }\n }\n completeRequest(request, { kind: 'reply', reply: { id: request.identity.id, result: { answers } } })\n } catch (error) { if (live(request)) completeRequest(request, { kind: 'refuse', reason: decisionFailureReason(error) }) }\n }\n const observe = (method: string, params: Record<string, unknown>): CodexDispatchResult => {\n if (method === 'serverRequest/resolved' && isId(params.requestId)) {\n const request = requests.get(rpcKey(params.requestId))\n if (request && params.threadId === request.identity.threadId) completeRequest(request, { kind: 'abandon', reason: 'Server request resolved' })\n }\n if (isText(params.threadId)) {\n if (threads.has(params.threadId) && isRecord(params.turn) && isText(params.turn.id) && method === 'turn/started') rememberTurn(params.threadId, params.turn.id, false)\n if (['thread/closed', 'thread/archived', 'thread/settings/updated'].includes(method)) unregisterThread(params.threadId)\n if (isText(params.turnId) && ['turn/completed', 'turn/interrupted', 'turn/failed'].includes(method)) fenceTurn(params.threadId, params.turnId, method)\n if (isRecord(params.turn) && isText(params.turn.id) && method === 'turn/completed') fenceTurn(params.threadId, params.turn.id, method)\n const itemId = isRecord(params.item) && isText(params.item.id) ? params.item.id : params.itemId\n if (isText(params.turnId) && isText(itemId)) {\n const key = itemKey(params.threadId, params.turnId, itemId)\n if (method === 'item/completed') {\n if (!completedItems.has(key) && stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Terminal item capacity exceeded' } }\n completedItems.add(key)\n for (const request of requests.values()) if (itemKey(request.identity.threadId, request.identity.turnId, request.identity.itemId) === key) completeRequest(request, { kind: 'abandon', reason: 'Item completed' })\n cacheBytes -= patches.get(key)?.bytes ?? 0\n patches.delete(key)\n }\n if (threads.has(params.threadId) && !completedItems.has(key) && turns.get(turnKey(params.threadId, params.turnId))?.terminal !== true && (method === 'item/fileChange/patchUpdated' || (method === 'item/started' && isRecord(params.item) && params.item.type === 'fileChange'))) {\n if (!rememberTurn(params.threadId, params.turnId, false)) return { kind: 'invalid', reason: 'Turn capacity exceeded' }\n const raw = method === 'item/started' && isRecord(params.item) ? params.item.changes : params.changes\n const previous = patches.get(key)\n const parsed = fileChangesOf(raw)\n const digest = decisionFingerprint(parsed)\n const conflict = previous !== undefined && previous.digest !== digest\n const changes = (method === 'item/fileChange/patchUpdated' && !previous) || (method === 'item/started' && conflict) || previous?.changes === null ? null : parsed\n const bytes = Buffer.byteLength(JSON.stringify(changes))\n if ((!previous && patches.size >= MAX_ITEMS) || cacheBytes - (previous?.bytes ?? 0) + bytes > MAX_CACHE_BYTES) { overflow(); return { kind: 'invalid', reason: 'Patch capacity exceeded' } }\n patches.set(key, { changes, digest, bytes })\n cacheBytes += bytes - (previous?.bytes ?? 0)\n if (conflict || changes === null) for (const request of requests.values()) if (itemKey(request.identity.threadId, request.identity.turnId, request.identity.itemId) === key) {\n if (request.state === 'accepted' && !contextEnded(request.identity)) invalidateTurn(request.identity.threadId, request.identity.turnId, 'Reviewed patch changed after acceptance')\n else completeRequest(request, { kind: 'refuse', reason: 'Reviewed patch changed' })\n }\n }\n }\n }\n return { kind: 'observed' }\n }\n const delegateToNative = (id: string | number, reason: string): CodexDispatchResult => {\n if (stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n closedRequestIds.add(rpcKey(id))\n emit({ type: 'native_review_required', requestId: id, reason })\n return disposed ? { kind: 'invalid', reason: 'Disposed during native handoff' } : { kind: 'unhandled', reason }\n }\n const dispatch = (message: unknown): CodexDispatchResult => {\n if (disposed) return { kind: 'invalid', reason: 'Adapter disposed' }\n if (!isRecord(message) || !isText(message.method) || !isRecord(message.params)) return { kind: 'invalid', reason: 'Invalid server envelope' }\n if (message.id === undefined) return observe(message.method, message.params)\n if (!isId(message.id)) return { kind: 'invalid', reason: 'Invalid RPC ID' }\n if (closedRequestIds.has(rpcKey(message.id))) return { kind: 'claimed' }\n const previous = requests.get(rpcKey(message.id))\n if (previous) {\n if (previous.envelopeDigest !== decisionFingerprint({ method: message.method, params: message.params })) {\n if (previous.state === 'accepted') invalidateTurn(previous.identity.threadId, previous.identity.turnId, 'Conflicting duplicate request')\n else completeRequest(previous, { kind: 'conflict', reason: 'Conflicting duplicate request' })\n }\n return { kind: 'claimed' }\n }\n if (![COMMAND, FILES, QUESTIONS].includes(message.method)) return delegateToNative(message.id, 'Unsupported server method')\n const identity = identityOf(message.id, message.method, message.params)\n if (!identity) return { kind: 'invalid', reason: 'Malformed request identity; close connection' }\n if (contextEnded(identity)) {\n if (stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n closedRequestIds.add(rpcKey(identity.id))\n if (identity.method === QUESTIONS && !interrupt(identity, 'Request context has ended')) return { kind: 'invalid', reason: 'Interrupt failed' }\n if (!disposed) config.sendResponse(identity.method === QUESTIONS ? { id: identity.id, error: { code: -32000, message: 'Request context has ended' } } : { id: identity.id, result: { decision: 'cancel' } })\n return { kind: 'claimed' }\n }\n if (!threads.has(identity.threadId)) return delegateToNative(message.id, 'Unregistered request context')\n if (!rememberTurn(identity.threadId, identity.turnId, false)) return { kind: 'invalid', reason: 'Turn capacity exceeded' }\n const subject = subjectOf(message.method, message.params, patches.get(itemKey(identity.threadId, identity.turnId, identity.itemId))?.changes ?? null, config.experimentalQuestions === true)\n if (subject.kind === 'malformed') {\n if (stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n closedRequestIds.add(rpcKey(message.id))\n if (message.method === QUESTIONS && !interrupt(identity, subject.reason)) return { kind: 'invalid', reason: 'Interrupt failed' }\n try { config.sendResponse({ id: message.id, error: { code: -32602, message: subject.reason } }) } catch { fatal('Invalid-params response enqueue failed') }\n return { kind: 'claimed' }\n }\n if (subject.kind === 'unsupported') return delegateToNative(message.id, subject.reason)\n const digest = decisionFingerprint(subject.subject)\n const phones = presentSubject(subject.subject)\n if (!phones) return delegateToNative(message.id, 'Subject exceeds presentation limits')\n if (stateCount() >= MAX_REQUESTS || [...requests.values()].filter(request => request.state === 'pending').length >= MAX_PENDING) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n const controller = new AbortController()\n const timer = setTimeout(() => { const request = requests.get(rpcKey(identity.id)); if (request) completeRequest(request, { kind: 'refuse', reason: 'Decision deadline elapsed' }) }, timeoutMs)\n const request: OwnedRequest = { identity, declineDecision: Array.isArray(message.params.availableDecisions) && !message.params.availableDecisions.includes('decline') ? 'cancel' : 'decline', digest, envelopeDigest: decisionFingerprint({ method: message.method, params: message.params }), subject: subject.subject, controller, deadline: performance.now() + timeoutMs, timer, decisionIds: new Set(), cleanupIds: new Set(), state: 'pending', cleanupDeadline: Infinity }\n requests.set(rpcKey(identity.id), request)\n let allowed = false\n try { allowed = config.maySendSubject(structuredClone(subject.subject)) === true } catch { allowed = false }\n if (disposed) return { kind: 'invalid', reason: 'Disposed during privacy review' }\n if (!live(request)) return { kind: 'claimed' }\n if (!allowed) {\n completeRequest(request, { kind: 'native' })\n requests.delete(rpcKey(identity.id))\n return delegateToNative(message.id, 'Subject rejected by privacy policy')\n }\n track(runRequest(request, phones))\n return { kind: 'claimed' }\n }\n const handle = (message: unknown): CodexDispatchResult => {\n try { return dispatch(message) } catch {\n fatal('Invalid message or host callback; close connection')\n return { kind: 'invalid', reason: 'Message could not be validated' }\n }\n }\n const registerThread = (value: unknown): void => {\n if (disposed) throw new Error('Adapter disposed')\n const id = certifiedThread(value)\n if (!id) throw new TypeError('Thread requires user approvals and a certified sandbox')\n if ([...requests.values()].some(request => request.state === 'pending' && request.identity.threadId === id)) throw new Error('Cannot replace thread policy while approval is pending')\n if (!threads.has(id) && threads.size >= MAX_THREADS) { overflow(); throw new Error('Thread capacity exceeded') }\n threads.add(id)\n }\n function onAbort(): void { void dispose() }\n config.signal?.addEventListener('abort', onAbort, { once: true })\n if (config.signal?.aborted) void dispose()\n return { registerThread, unregisterThread, handle, invalidateTurn, dispose }\n}\n","import type { CodexQuestion, CodexRequestId, CodexReviewSubject, FileChange, RequestIdentity } from './types'\n\nexport const COMMAND = 'item/commandExecution/requestApproval'\nexport const FILES = 'item/fileChange/requestApproval'\nexport const QUESTIONS = 'item/tool/requestUserInput'\nexport const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value)\nexport const isId = (value: unknown): value is CodexRequestId => typeof value === 'string' || (typeof value === 'number' && Number.isSafeInteger(value))\nexport const isText = (value: unknown): value is string => typeof value === 'string' && value.length > 0\nconst optionalText = (value: unknown): boolean => value === undefined || value === null || typeof value === 'string'\nexport const onlyKeys = (value: Record<string, unknown>, keys: readonly string[]): boolean => Object.keys(value).every(key => keys.includes(key))\nexport const identityOf = (id: CodexRequestId, method: string, params: Record<string, unknown>): RequestIdentity | null => {\n if (!isText(params.threadId) || !isText(params.turnId) || !isText(params.itemId) || !optionalText(params.approvalId)) return null\n return { id, method, threadId: params.threadId, turnId: params.turnId, itemId: params.itemId, approvalId: typeof params.approvalId === 'string' ? params.approvalId : null }\n}\nexport const certifiedThread = (value: unknown): string | null => {\n if (!isRecord(value) || !isRecord(value.thread) || !isText(value.thread.id) || !isRecord(value.thread.status) || value.thread.status.type !== 'idle') return null\n if ((value.approvalPolicy !== 'untrusted' && value.approvalPolicy !== 'on-request') || value.approvalsReviewer !== 'user' || !isRecord(value.sandbox)) return null\n const sandbox = value.sandbox\n if (sandbox.type !== 'readOnly' && sandbox.type !== 'workspaceWrite') return null\n if (!onlyKeys(sandbox, ['type', 'networkAccess', 'writableRoots', 'excludeSlashTmp', 'excludeTmpdirEnvVar'])) return null\n if (sandbox.networkAccess !== undefined && typeof sandbox.networkAccess !== 'boolean') return null\n if (sandbox.writableRoots !== undefined && (!Array.isArray(sandbox.writableRoots) || !sandbox.writableRoots.every(isText))) return null\n if (['excludeSlashTmp', 'excludeTmpdirEnvVar'].some(key => sandbox[key] !== undefined && typeof sandbox[key] !== 'boolean')) return null\n if (value.activePermissionProfile !== undefined && value.activePermissionProfile !== null) return null\n return value.thread.id\n}\nexport const fileChangesOf = (value: unknown): readonly FileChange[] | null => {\n if (!Array.isArray(value) || value.length === 0 || value.length > 128) return null\n const changes: FileChange[] = []\n for (const change of value) {\n if (!isRecord(change) || !onlyKeys(change, ['path', 'kind', 'diff']) || !isText(change.path) || typeof change.diff !== 'string' || !isRecord(change.kind)) return null\n const kind = change.kind\n if (!onlyKeys(kind, ['type', 'move_path']) || (kind.type !== 'add' && kind.type !== 'delete' && kind.type !== 'update')) return null\n if (!optionalText(kind.move_path) || (kind.type !== 'update' && kind.move_path != null)) return null\n changes.push({ path: change.path, operation: kind.type, movePath: typeof kind.move_path === 'string' ? kind.move_path : null, diff: change.diff })\n }\n return changes\n}\ntype SubjectResult = { readonly kind: 'supported'; readonly subject: CodexReviewSubject } | { readonly kind: 'unsupported'; readonly reason: string } | { readonly kind: 'malformed'; readonly reason: string }\nconst unsupported = (reason: string): SubjectResult => ({ kind: 'unsupported', reason })\nconst malformed = (reason: string): SubjectResult => ({ kind: 'malformed', reason })\nconst isKnownCommandDecision = (value: unknown): boolean => {\n if (typeof value === 'string') return ['accept', 'acceptForSession', 'decline', 'cancel'].includes(value)\n if (!isRecord(value) || !onlyKeys(value, ['acceptWithExecpolicyAmendment'])) return false\n const amendment = value.acceptWithExecpolicyAmendment\n return isRecord(amendment) && onlyKeys(amendment, ['execpolicy_amendment']) && Array.isArray(amendment.execpolicy_amendment) && amendment.execpolicy_amendment.every(isText)\n}\nexport const subjectOf = (method: string, params: Record<string, unknown>, changes: readonly FileChange[] | null, experimental: boolean): SubjectResult => {\n if (method === COMMAND) {\n if (!onlyKeys(params, ['threadId', 'turnId', 'itemId', 'approvalId', 'startedAtMs', 'kind', 'environmentId', 'command', 'cwd', 'reason', 'commandActions', 'networkApprovalContext', 'proposedExecpolicyAmendment', 'proposedNetworkPolicyAmendments', 'availableDecisions'])) return unsupported('Unknown command permission fields')\n if ((params.kind !== undefined && params.kind !== 'command') || (params.environmentId != null && params.environmentId !== 'local') || params.networkApprovalContext != null || params.proposedNetworkPolicyAmendments != null) return unsupported('Command needs native permission review')\n if (params.proposedExecpolicyAmendment != null && (!Array.isArray(params.proposedExecpolicyAmendment) || !params.proposedExecpolicyAmendment.every(isText))) return malformed('Invalid policy suggestion')\n if (params.availableDecisions != null && (!Array.isArray(params.availableDecisions) || !params.availableDecisions.includes('accept') || !params.availableDecisions.every(isKnownCommandDecision))) return unsupported('Unknown available approval decisions')\n if (!isText(params.command) || !isText(params.cwd) || !optionalText(params.reason) || !Number.isSafeInteger(params.startedAtMs)) return malformed('Incomplete command subject')\n return { kind: 'supported', subject: { kind: 'command', command: params.command, cwd: params.cwd, reason: typeof params.reason === 'string' ? params.reason : null } }\n }\n if (method === FILES) {\n if (!onlyKeys(params, ['threadId', 'turnId', 'itemId', 'startedAtMs', 'reason', 'grantRoot']) || params.grantRoot != null) return unsupported('File request widens permissions')\n if (!optionalText(params.reason) || !Number.isSafeInteger(params.startedAtMs)) return malformed('Malformed file request')\n if (!changes) return unsupported('Complete file patch unavailable')\n return { kind: 'supported', subject: { kind: 'files', changes, reason: typeof params.reason === 'string' ? params.reason : null } }\n }\n if (!experimental) return unsupported('Experimental questions disabled')\n if (!onlyKeys(params, ['threadId', 'turnId', 'itemId', 'questions', 'isBlocking', 'autoResolutionMs']) || params.isBlocking !== true || params.autoResolutionMs != null) return unsupported('Question requires native handling')\n if (!Array.isArray(params.questions) || params.questions.length < 1 || params.questions.length > 3) return malformed('Question count outside supported range')\n const questions: CodexQuestion[] = []\n for (const question of params.questions) {\n if (!isRecord(question) || !onlyKeys(question, ['id', 'header', 'question', 'isOther', 'isSecret', 'options'])) return malformed('Malformed question')\n if (question.isOther !== false || question.isSecret !== false) return unsupported('Secret or other-option question')\n if (!isText(question.id) || !isText(question.header) || !isText(question.question) || questions.some(entry => entry.id === question.id)) return malformed('Invalid question identity')\n let options: CodexQuestion['options'] = null\n if (question.options !== null) {\n if (!Array.isArray(question.options) || question.options.length < 2 || question.options.length > 20) return malformed('Invalid options')\n const validated: { label: string; description: string }[] = []\n for (const option of question.options) {\n if (!isRecord(option) || !onlyKeys(option, ['label', 'description']) || !isText(option.label) || option.label.length > 200 || typeof option.description !== 'string' || validated.some(entry => entry.label === option.label)) return malformed('Invalid option')\n validated.push({ label: option.label, description: option.description })\n }\n options = validated\n }\n questions.push({ id: question.id, header: question.header, question: question.question, options })\n }\n return { kind: 'supported', subject: { kind: 'questions', questions } }\n}\n","import type { CodexReviewSubject } from './types'\nimport type { DecisionType } from '@pushary/server'\n\nexport interface PhoneQuestion {\n readonly question: string\n readonly context: string\n readonly type: DecisionType\n readonly options?: readonly string[]\n readonly questionId?: string\n}\nexport const visibleText = (text: string): string => text.replace(/\\\\/g, '\\\\\\\\').replace(/[\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}]/gu, character => `\\\\u{${character.codePointAt(0)?.toString(16)}}`)\nconst bounded = (questions: readonly PhoneQuestion[]): readonly PhoneQuestion[] | null => questions.every(question => question.question.length <= 8000 && question.context.length <= 2000 && question.options?.some(option => option.length > 200) !== true) ? questions : null\nexport const presentSubject = (subject: CodexReviewSubject): readonly PhoneQuestion[] | null => {\n if (subject.kind === 'command') return bounded([{ type: 'confirm', question: `Approve this command once?\\n\\n${visibleText(subject.command)}\\n\\nWorking directory: ${visibleText(subject.cwd)}\\nReason: ${visibleText(subject.reason ?? '(none)')}`, context: 'Codex command approval. This approval applies only to this request.' }])\n if (subject.kind === 'files') {\n const patches = subject.changes.map(change => `${change.operation}: ${visibleText(change.path)}${change.movePath === null ? '' : ` -> ${visibleText(change.movePath)}`}\\n${visibleText(change.diff)}`).join('\\n\\n')\n return bounded([{ type: 'confirm', question: `Approve these exact file changes once?\\n\\n${patches}\\n\\nReason: ${visibleText(subject.reason ?? '(none)')}`, context: 'Codex file approval. Includes every file and the complete patch.' }])\n }\n return bounded(subject.questions.map(question => ({ questionId: question.id, type: question.options ? 'select' : 'input', question: `${visibleText(question.header)}\\n${visibleText(question.question)}${question.options ? '\\n\\n' + question.options.map(option => `${visibleText(option.label)}: ${visibleText(option.description)}`).join('\\n') : ''}`, options: question.options?.map(option => visibleText(option.label)), context: 'Answer this Codex question. This answer does not grant tool permissions.' })))\n}\n","import { PusharyApiError, type DecisionType } from '@pushary/server'\nimport { isRecord, isText } from './protocol'\n\nexport interface DecisionSnapshot {\n readonly decisionId: string\n readonly status: 'pending' | 'answered' | 'expired' | 'cancelled' | 'stopped'\n readonly answered: boolean\n readonly value: string | null\n readonly type: DecisionType\n}\nexport const decisionSnapshot = (value: unknown, type: DecisionType, expectedId?: string): DecisionSnapshot => {\n if (!isRecord(value) || !isText(value.decisionId) || (expectedId !== undefined && value.decisionId !== expectedId) || value.type !== type || typeof value.answered !== 'boolean') throw new Error('Invalid decision response')\n const status = value.status\n if (status !== 'pending' && status !== 'answered' && status !== 'expired' && status !== 'cancelled' && status !== 'stopped') throw new Error('Unknown decision status')\n if ((status === 'answered') !== value.answered || (status === 'answered' && typeof value.value !== 'string') || (status !== 'answered' && value.value != null)) throw new Error('Inconsistent decision response')\n return { decisionId: value.decisionId, status, answered: value.answered, value: typeof value.value === 'string' ? value.value : null, type }\n}\nexport const isRetryable = (error: unknown): boolean => error instanceof PusharyApiError ? error.status === 429 || error.status >= 500 : error instanceof TypeError || (error instanceof Error && error.name === 'TimeoutError')\nexport const delay = (milliseconds: number, signal: AbortSignal): Promise<void> => new Promise((resolve, reject) => {\n if (signal.aborted) { reject(signal.reason); return }\n const onAbort = (): void => { clearTimeout(timer); reject(signal.reason) }\n const timer = setTimeout(() => { signal.removeEventListener('abort', onAbort); resolve() }, milliseconds)\n signal.addEventListener('abort', onAbort, { once: true })\n})\nexport const withRetry = async <T>(operation: () => Promise<T>, signal: AbortSignal): Promise<T> => {\n for (let attempt = 0; ; attempt += 1) {\n signal.throwIfAborted()\n try { return await operation() } catch (error) {\n if (signal.aborted || attempt >= 3 || !isRetryable(error)) throw error\n await delay(250 * 2 ** attempt + Math.floor(Math.random() * 101), signal)\n }\n }\n}\n\nexport const decisionFailureReason = (error: unknown): string => {\n if (error instanceof PusharyApiError) return `Partner HTTP ${error.status}`\n if (error instanceof TypeError) return 'Decision transport unavailable'\n if (error instanceof Error && error.name === 'TimeoutError') return 'Decision HTTP deadline elapsed'\n return 'Decision response invalid or unavailable'\n}\n","import type { CodexReply, CodexRequestId } from './types'\n\nexport type RequestState = 'pending' | 'accepted' | 'closed'\nexport type RequestCompletion =\n | { readonly kind: 'reply'; readonly reply: CodexReply }\n | { readonly kind: 'refuse' | 'conflict' | 'abandon'; readonly reason: string }\n | { readonly kind: 'native' }\n\ninterface RequestContext {\n readonly id: CodexRequestId\n readonly isQuestion: boolean\n readonly replyAllowed: boolean\n readonly deadlineElapsed: boolean\n}\ninterface RequestTransition {\n readonly state: Exclude<RequestState, 'pending'>\n readonly reply: CodexReply | null\n readonly interruption: string | null\n readonly abandonment: string | null\n}\n\nexport const transitionRequest = (state: RequestState, completion: RequestCompletion, context: RequestContext): RequestTransition | null => {\n if (state !== 'pending') return null\n if (completion.kind === 'reply') {\n if (!context.replyAllowed || context.deadlineElapsed) return null\n const reply = completion.reply\n const accepted = 'result' in reply && 'decision' in reply.result && reply.result.decision === 'accept'\n return { state: accepted ? 'accepted' : 'closed', reply, interruption: null, abandonment: null }\n }\n if (completion.kind === 'native') return { state: 'closed', reply: null, interruption: null, abandonment: null }\n if (completion.kind === 'abandon' || !context.replyAllowed) return { state: 'closed', reply: null, interruption: null, abandonment: completion.reason }\n const reply: CodexReply = context.isQuestion\n ? { id: context.id, error: { code: -32000, message: completion.reason } }\n : { id: context.id, result: { decision: 'cancel' } }\n return { state: 'closed', reply, interruption: context.isQuestion || completion.kind === 'conflict' ? completion.reason : null, abandonment: completion.reason }\n}\n"],"mappings":"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","names":["import_adapters","import_server","reply","request"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/handler.ts","../src/protocol.ts","../src/presentation.ts","../src/partner-decisions.ts","../src/request-lifecycle.ts"],"sourcesContent":["import { createAdapterKernel } from '@pushary/server/adapters'\nexport { createPusharyCodexHandler } from './handler'\nexport { CERTIFIED_CODEX_VERSIONS, type CertifiedCodexVersion } from './protocol'\nexport type { CodexRequestId, CodexReply, CodexDispatchResult, CodexReviewSubject, PusharyCodexConfig, PusharyCodexEvent, PusharyCodexHandler } from './types'\nexport const connect = createAdapterKernel('Codex app-server').connect\n","import { randomUUID } from 'node:crypto'\nimport { createPusharyServer, isApproved, type CreateDecision } from '@pushary/server'\nimport { decisionFingerprint } from '@pushary/server/adapters'\nimport { COMMAND, FILES, QUESTIONS, certifiedThread, isCertifiedCodexVersion, fileChangesOf, identityOf, isId, isRecord, isText, subjectOf } from './protocol'\nimport { presentSubject, type PhoneQuestion } from './presentation'\nimport { decisionFailureReason, decisionSnapshot, delay, isRetryable, withRetry, type DecisionSnapshot } from './partner-decisions'\nimport { transitionRequest, type RequestCompletion, type RequestState } from './request-lifecycle'\nimport type { CodexDispatchResult, CodexReviewSubject, FileChange, PusharyCodexConfig, PusharyCodexEvent, PusharyCodexHandler, RequestIdentity } from './types'\n\nconst MAX_PENDING = 8\nconst MAX_THREADS = 32\nconst MAX_ITEMS = 128\nconst MAX_CACHE_BYTES = 4 * 1024 * 1024\nconst MAX_REQUESTS = 4096\nconst CLEANUP_MS = 5000\nconst MIN_QUESTION_BUDGET_MS = 10_000\ninterface OwnedRequest {\n readonly identity: RequestIdentity\n readonly declineDecision: 'decline' | 'cancel'\n readonly digest: string\n readonly envelopeDigest: string\n readonly subject: CodexReviewSubject\n readonly controller: AbortController\n readonly deadline: number\n readonly timer: ReturnType<typeof setTimeout>\n readonly decisionIds: Set<string>\n readonly cleanupIds: Set<string>\n state: RequestState\n cleanupDeadline: number\n}\ninterface CachedPatch { readonly changes: readonly FileChange[] | null; readonly digest: string; readonly bytes: number }\nconst itemKey = (threadId: string, turnId: string, itemId: string): string => JSON.stringify([threadId, turnId, itemId])\nconst turnKey = (threadId: string, turnId: string): string => JSON.stringify([threadId, turnId])\nconst rpcKey = (id: string | number): string => JSON.stringify([typeof id, id])\n\nexport const createPusharyCodexHandler = (configuration: PusharyCodexConfig): PusharyCodexHandler => {\n const config = Object.freeze({ ...configuration })\n const timeoutMs = config.timeoutMs ?? 300_000\n if (!isCertifiedCodexVersion(config.codexVersion) || !Number.isInteger(timeoutMs) || timeoutMs < 60_000 || timeoutMs > 600_000 || !config.tenantId?.trim() || !config.externalId?.trim()) throw new TypeError('Invalid Codex adapter configuration')\n if ([config.sendResponse, config.requestTurnInterrupt, config.onEvent, config.maySendSubject].some(callback => typeof callback !== 'function')) throw new TypeError('All host callbacks are required')\n const decisions = createPusharyServer({ apiKey: config.apiKey, baseUrl: config.baseUrl, requestTimeoutMs: 10_000 }).decisions\n const generation = randomUUID()\n const threads = new Set<string>()\n const requests = new Map<string, OwnedRequest>()\n const closedRequestIds = new Set<string>()\n const turns = new Map<string, { readonly threadId: string; readonly turnId: string; terminal: boolean }>()\n const completedItems = new Set<string>()\n const patches = new Map<string, CachedPatch>()\n const jobs = new Set<Promise<void>>()\n const cleanupFailures: string[] = []\n const cleanupControllers = new Set<AbortController>()\n let cacheBytes = 0\n let disposed = false\n let disposal: Promise<{ readonly cleanupFailures: readonly string[] }> | undefined\n let disposalDeadline = Infinity\n const emit = (event: PusharyCodexEvent): void => {\n try { config.onEvent(event) } catch { console.error('Pushary Codex onEvent callback failed') }\n }\n const eventFor = (request: OwnedRequest, type: PusharyCodexEvent['type'], reason?: string, decisionId?: string): void => emit({ type, requestId: request.identity.id, threadId: request.identity.threadId, turnId: request.identity.turnId, subjectDigest: request.digest, decisionId, reason })\n const track = (job: Promise<void>): void => { jobs.add(job); void job.finally(() => jobs.delete(job)).catch(() => undefined) }\n const cleanupFailed = (request: OwnedRequest, id: string): void => {\n cleanupFailures.push(id)\n eventFor(request, 'cleanup_failed', 'Decision cleanup not confirmed before deadline', id)\n }\n const cleanup = async (request: OwnedRequest, id: string): Promise<void> => {\n if (request.cleanupIds.has(id)) return\n request.cleanupIds.add(id)\n const remaining = Math.min(request.cleanupDeadline, disposalDeadline) - performance.now()\n if (remaining <= 0) { cleanupFailed(request, id); return }\n const controller = new AbortController()\n cleanupControllers.add(controller)\n const timer = setTimeout(() => controller.abort(), remaining)\n try {\n for (let attempt = 0; attempt < 3; attempt += 1) {\n try {\n const result: unknown = await decisions.cancel(id, { signal: controller.signal })\n if (!isRecord(result) || result.decisionId !== id || typeof result.cancelled !== 'boolean') throw new Error('Invalid cancellation result')\n if (result.cancelled) return\n const latest: unknown = await decisions.get(id, { signal: controller.signal })\n if (isRecord(latest) && (latest.type === 'confirm' || latest.type === 'select' || latest.type === 'input')) {\n const snapshot = decisionSnapshot(latest, latest.type, id)\n if (snapshot.status !== 'pending') return\n }\n throw new TypeError('Cancellation still pending')\n } catch (error) {\n if (controller.signal.aborted || attempt === 2 || !isRetryable(error)) throw error\n await delay(attempt === 0 ? 100 : 300, controller.signal)\n }\n }\n } catch { cleanupFailed(request, id) } finally { clearTimeout(timer); cleanupControllers.delete(controller) }\n }\n const beginCleanup = (request: OwnedRequest): void => {\n clearTimeout(request.timer)\n request.cleanupDeadline = Math.min(performance.now() + CLEANUP_MS, disposalDeadline)\n request.controller.abort()\n for (const id of request.decisionIds) track(cleanup(request, id))\n }\n const completeRequest = (request: OwnedRequest, completion: RequestCompletion): void => {\n const transition = transitionRequest(request.state, completion, {\n id: request.identity.id,\n isQuestion: request.subject.kind === 'questions',\n replyAllowed: contextLive(request),\n deadlineElapsed: performance.now() >= request.deadline,\n })\n if (!transition) return\n request.state = transition.state\n beginCleanup(request)\n if (transition.reply && contextLive(request)) {\n const interrupted = transition.interruption === null || interrupt(request.identity, transition.interruption)\n if (interrupted && contextLive(request)) {\n try { config.sendResponse(transition.reply) } catch { fatal('Response enqueue failed; close connection') }\n }\n }\n if (transition.abandonment !== null) eventFor(request, 'request_abandoned', transition.abandonment)\n }\n const dispose = (): Promise<{ readonly cleanupFailures: readonly string[] }> => {\n if (disposal) return disposal\n disposed = true\n disposalDeadline = performance.now() + CLEANUP_MS\n config.signal?.removeEventListener('abort', onAbort)\n let resolveDisposal: (value: { readonly cleanupFailures: readonly string[] }) => void = () => undefined\n disposal = new Promise(resolve => { resolveDisposal = resolve })\n threads.clear()\n patches.clear()\n cacheBytes = 0\n for (const request of requests.values()) completeRequest(request, { kind: 'abandon', reason: 'Connection disposed' })\n const finish = async (): Promise<void> => {\n const controller = new AbortController()\n const drain = async (): Promise<void> => { while (jobs.size > 0 && performance.now() < disposalDeadline) await Promise.allSettled([...jobs]) }\n await Promise.race([drain(), delay(CLEANUP_MS, controller.signal)]).catch(() => undefined)\n controller.abort()\n for (const cleanupController of cleanupControllers) cleanupController.abort()\n await Promise.resolve()\n resolveDisposal({ cleanupFailures: [...cleanupFailures] })\n }\n void finish()\n return disposal\n }\n const fatal = (reason: string): void => {\n void dispose()\n emit({ type: 'reply_failed', reason })\n }\n const overflow = (): void => { void dispose(); emit({ type: 'capacity_exceeded', reason: 'Connection must close; bounded adapter capacity exceeded' }) }\n const stateCount = (): number => requests.size + closedRequestIds.size + turns.size + completedItems.size\n const rememberTurn = (threadId: string, turnId: string, terminal: boolean): boolean => {\n const key = turnKey(threadId, turnId)\n const previous = turns.get(key)\n if (previous) { previous.terminal ||= terminal; return true }\n if (stateCount() >= MAX_REQUESTS) { overflow(); return false }\n turns.set(key, { threadId, turnId, terminal })\n return true\n }\n const contextEnded = (identity: RequestIdentity): boolean => turns.get(turnKey(identity.threadId, identity.turnId))?.terminal === true || completedItems.has(itemKey(identity.threadId, identity.turnId, identity.itemId))\n const contextLive = (request: OwnedRequest): boolean => !disposed && !contextEnded(request.identity) && threads.has(request.identity.threadId)\n const live = (request: OwnedRequest): boolean => request.state === 'pending' && contextLive(request) && performance.now() < request.deadline\n const interrupt = (identity: RequestIdentity, reason: string): boolean => {\n try { config.requestTurnInterrupt(identity.threadId, identity.turnId, reason); return !disposed } catch { fatal('Turn interrupt enqueue failed; close connection'); return false }\n }\n const fenceTurn = (threadId: string, turnId: string, reason: string): void => {\n if (!rememberTurn(threadId, turnId, true)) return\n for (const request of requests.values()) if (request.identity.threadId === threadId && request.identity.turnId === turnId) completeRequest(request, { kind: 'abandon', reason })\n for (const key of patches.keys()) {\n if (key.startsWith(JSON.stringify([threadId, turnId]).slice(0, -1) + ',')) { cacheBytes -= patches.get(key)?.bytes ?? 0; patches.delete(key) }\n }\n }\n const invalidateTurn = (threadId: string, turnId: string, reason: string): void => {\n const accepted = [...requests.values()].find(request => request.identity.threadId === threadId && request.identity.turnId === turnId && request.state === 'accepted' && !contextEnded(request.identity))\n fenceTurn(threadId, turnId, reason)\n if (accepted) {\n if (!disposed) interrupt(accepted.identity, reason)\n eventFor(accepted, 'request_abandoned', 'Invalidated after acceptance enqueue; execution outcome unknown')\n }\n }\n const unregisterThread = (threadId: string): void => {\n threads.delete(threadId)\n for (const turn of turns.values()) if (turn.threadId === threadId) invalidateTurn(threadId, turn.turnId, 'Thread unregistered')\n for (const key of patches.keys()) if (key.startsWith(JSON.stringify([threadId]).slice(0, -1) + ',')) { cacheBytes -= patches.get(key)?.bytes ?? 0; patches.delete(key) }\n }\n const createAndWait = async (request: OwnedRequest, phone: PhoneQuestion, ordinal: number): Promise<DecisionSnapshot> => {\n const payload: CreateDecision = { question: phone.question, type: phone.type, options: phone.options, context: phone.context, externalId: config.externalId, agentName: config.agentName ?? 'Codex', wait: false, requireReachable: true, expiresInSeconds: Math.ceil(timeoutMs / 1000), idempotencyKey: decisionFingerprint({ tenantId: config.tenantId, externalId: config.externalId, generation, ...request.identity, subjectDigest: request.digest, ordinal, questionId: phone.questionId ?? null }) }\n let raw: unknown\n try { raw = await withRetry(() => decisions.create(payload, { signal: request.controller.signal }), request.controller.signal) } catch (error) {\n if (request.controller.signal.aborted || isRetryable(error)) eventFor(request, 'create_outcome_unknown', 'Create may have reached server; TTL bounds residual prompt')\n throw error\n }\n if (isRecord(raw) && isText(raw.decisionId)) {\n request.decisionIds.add(raw.decisionId)\n if (!live(request)) { track(cleanup(request, raw.decisionId)); throw new Error('Request no longer live') }\n }\n if (!isRecord(raw) || !isText(raw.decisionId)) eventFor(request, 'create_outcome_unknown', 'Create returned no usable decision ID')\n let snapshot = decisionSnapshot(raw, phone.type)\n eventFor(request, 'decision_created', undefined, snapshot.decisionId)\n while (snapshot.status === 'pending') {\n if (!live(request)) throw new Error('Request no longer live')\n const next: unknown = await withRetry(() => decisions.get(snapshot.decisionId, { wait: 5, signal: request.controller.signal }), request.controller.signal)\n snapshot = decisionSnapshot(next, phone.type, snapshot.decisionId)\n if (snapshot.status === 'pending') await delay(50, request.controller.signal)\n }\n request.decisionIds.delete(snapshot.decisionId)\n eventFor(request, 'decision_settled', snapshot.status, snapshot.decisionId)\n return snapshot\n }\n const runRequest = async (request: OwnedRequest, phones: readonly PhoneQuestion[]): Promise<void> => {\n try {\n const answers: Record<string, { answers: readonly string[] }> = Object.create(null)\n for (const [ordinal, phone] of phones.entries()) {\n if (!live(request)) return\n if (ordinal > 0 && request.deadline - performance.now() < MIN_QUESTION_BUDGET_MS) { completeRequest(request, { kind: 'refuse', reason: 'Insufficient time for another question' }); return }\n const result = await createAndWait(request, phone, ordinal)\n if (!live(request)) return\n if (request.subject.kind !== 'questions') {\n const approved = result.type === 'confirm' && result.status === 'answered' && isApproved({ status: result.status, type: result.type, value: result.value })\n completeRequest(request, { kind: 'reply', reply: { id: request.identity.id, result: { decision: approved ? 'accept' : request.declineDecision } } })\n return\n }\n if (!result.answered || !result.value?.trim() || result.value.length > 2000 || (phone.options && !phone.options.includes(result.value))) { completeRequest(request, { kind: 'refuse', reason: 'Question did not receive a valid answer' }); return }\n const question = request.subject.questions[ordinal]\n if (!question || !phone.questionId) throw new Error('Question identity missing')\n const selectedIndex = phone.options?.indexOf(result.value)\n const answer = selectedIndex !== undefined ? question.options?.[selectedIndex]?.label : result.value\n if (answer === undefined) throw new Error('Question option missing')\n answers[phone.questionId] = { answers: [answer] }\n }\n completeRequest(request, { kind: 'reply', reply: { id: request.identity.id, result: { answers } } })\n } catch (error) { if (live(request)) completeRequest(request, { kind: 'refuse', reason: decisionFailureReason(error) }) }\n }\n const observe = (method: string, params: Record<string, unknown>): CodexDispatchResult => {\n if (method === 'serverRequest/resolved' && isId(params.requestId)) {\n const request = requests.get(rpcKey(params.requestId))\n if (request && params.threadId === request.identity.threadId) completeRequest(request, { kind: 'abandon', reason: 'Server request resolved' })\n }\n if (isText(params.threadId)) {\n if (threads.has(params.threadId) && isRecord(params.turn) && isText(params.turn.id) && method === 'turn/started') rememberTurn(params.threadId, params.turn.id, false)\n if (['thread/closed', 'thread/archived', 'thread/settings/updated'].includes(method)) unregisterThread(params.threadId)\n if (isText(params.turnId) && ['turn/completed', 'turn/interrupted', 'turn/failed'].includes(method)) fenceTurn(params.threadId, params.turnId, method)\n if (isRecord(params.turn) && isText(params.turn.id) && method === 'turn/completed') fenceTurn(params.threadId, params.turn.id, method)\n const itemId = isRecord(params.item) && isText(params.item.id) ? params.item.id : params.itemId\n if (isText(params.turnId) && isText(itemId)) {\n const key = itemKey(params.threadId, params.turnId, itemId)\n if (method === 'item/completed') {\n if (!completedItems.has(key) && stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Terminal item capacity exceeded' } }\n completedItems.add(key)\n for (const request of requests.values()) if (itemKey(request.identity.threadId, request.identity.turnId, request.identity.itemId) === key) completeRequest(request, { kind: 'abandon', reason: 'Item completed' })\n cacheBytes -= patches.get(key)?.bytes ?? 0\n patches.delete(key)\n }\n if (threads.has(params.threadId) && !completedItems.has(key) && turns.get(turnKey(params.threadId, params.turnId))?.terminal !== true && (method === 'item/fileChange/patchUpdated' || (method === 'item/started' && isRecord(params.item) && params.item.type === 'fileChange'))) {\n if (!rememberTurn(params.threadId, params.turnId, false)) return { kind: 'invalid', reason: 'Turn capacity exceeded' }\n const raw = method === 'item/started' && isRecord(params.item) ? params.item.changes : params.changes\n const previous = patches.get(key)\n const parsed = fileChangesOf(raw)\n const digest = decisionFingerprint(parsed)\n const conflict = previous !== undefined && previous.digest !== digest\n const changes = (method === 'item/fileChange/patchUpdated' && !previous) || (method === 'item/started' && conflict) || previous?.changes === null ? null : parsed\n const bytes = Buffer.byteLength(JSON.stringify(changes))\n if ((!previous && patches.size >= MAX_ITEMS) || cacheBytes - (previous?.bytes ?? 0) + bytes > MAX_CACHE_BYTES) { overflow(); return { kind: 'invalid', reason: 'Patch capacity exceeded' } }\n patches.set(key, { changes, digest, bytes })\n cacheBytes += bytes - (previous?.bytes ?? 0)\n if (conflict || changes === null) for (const request of requests.values()) if (itemKey(request.identity.threadId, request.identity.turnId, request.identity.itemId) === key) {\n if (request.state === 'accepted' && !contextEnded(request.identity)) invalidateTurn(request.identity.threadId, request.identity.turnId, 'Reviewed patch changed after acceptance')\n else completeRequest(request, { kind: 'refuse', reason: 'Reviewed patch changed' })\n }\n }\n }\n }\n return { kind: 'observed' }\n }\n const delegateToNative = (id: string | number, reason: string): CodexDispatchResult => {\n if (stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n closedRequestIds.add(rpcKey(id))\n emit({ type: 'native_review_required', requestId: id, reason })\n return disposed ? { kind: 'invalid', reason: 'Disposed during native handoff' } : { kind: 'unhandled', reason }\n }\n const dispatch = (message: unknown): CodexDispatchResult => {\n if (disposed) return { kind: 'invalid', reason: 'Adapter disposed' }\n if (!isRecord(message) || !isText(message.method) || !isRecord(message.params)) return { kind: 'invalid', reason: 'Invalid server envelope' }\n if (message.id === undefined) return observe(message.method, message.params)\n if (!isId(message.id)) return { kind: 'invalid', reason: 'Invalid RPC ID' }\n if (closedRequestIds.has(rpcKey(message.id))) return { kind: 'claimed' }\n const previous = requests.get(rpcKey(message.id))\n if (previous) {\n if (previous.envelopeDigest !== decisionFingerprint({ method: message.method, params: message.params })) {\n if (previous.state === 'accepted') invalidateTurn(previous.identity.threadId, previous.identity.turnId, 'Conflicting duplicate request')\n else completeRequest(previous, { kind: 'conflict', reason: 'Conflicting duplicate request' })\n }\n return { kind: 'claimed' }\n }\n if (![COMMAND, FILES, QUESTIONS].includes(message.method)) return delegateToNative(message.id, 'Unsupported server method')\n const identity = identityOf(message.id, message.method, message.params)\n if (!identity) return { kind: 'invalid', reason: 'Malformed request identity; close connection' }\n if (contextEnded(identity)) {\n if (stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n closedRequestIds.add(rpcKey(identity.id))\n if (identity.method === QUESTIONS && !interrupt(identity, 'Request context has ended')) return { kind: 'invalid', reason: 'Interrupt failed' }\n if (!disposed) config.sendResponse(identity.method === QUESTIONS ? { id: identity.id, error: { code: -32000, message: 'Request context has ended' } } : { id: identity.id, result: { decision: 'cancel' } })\n return { kind: 'claimed' }\n }\n if (!threads.has(identity.threadId)) return delegateToNative(message.id, 'Unregistered request context')\n if (!rememberTurn(identity.threadId, identity.turnId, false)) return { kind: 'invalid', reason: 'Turn capacity exceeded' }\n const subject = subjectOf(message.method, message.params, patches.get(itemKey(identity.threadId, identity.turnId, identity.itemId))?.changes ?? null, config.experimentalQuestions === true)\n if (subject.kind === 'malformed') {\n if (stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n closedRequestIds.add(rpcKey(message.id))\n if (message.method === QUESTIONS && !interrupt(identity, subject.reason)) return { kind: 'invalid', reason: 'Interrupt failed' }\n try { config.sendResponse({ id: message.id, error: { code: -32602, message: subject.reason } }) } catch { fatal('Invalid-params response enqueue failed') }\n return { kind: 'claimed' }\n }\n if (subject.kind === 'unsupported') return delegateToNative(message.id, subject.reason)\n const digest = decisionFingerprint(subject.subject)\n const phones = presentSubject(subject.subject)\n if (!phones) return delegateToNative(message.id, 'Subject exceeds presentation limits')\n if (stateCount() >= MAX_REQUESTS || [...requests.values()].filter(request => request.state === 'pending').length >= MAX_PENDING) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n const controller = new AbortController()\n const timer = setTimeout(() => { const request = requests.get(rpcKey(identity.id)); if (request) completeRequest(request, { kind: 'refuse', reason: 'Decision deadline elapsed' }) }, timeoutMs)\n const request: OwnedRequest = { identity, declineDecision: Array.isArray(message.params.availableDecisions) && !message.params.availableDecisions.includes('decline') ? 'cancel' : 'decline', digest, envelopeDigest: decisionFingerprint({ method: message.method, params: message.params }), subject: subject.subject, controller, deadline: performance.now() + timeoutMs, timer, decisionIds: new Set(), cleanupIds: new Set(), state: 'pending', cleanupDeadline: Infinity }\n requests.set(rpcKey(identity.id), request)\n let allowed = false\n try { allowed = config.maySendSubject(structuredClone(subject.subject)) === true } catch { allowed = false }\n if (disposed) return { kind: 'invalid', reason: 'Disposed during privacy review' }\n if (!live(request)) return { kind: 'claimed' }\n if (!allowed) {\n completeRequest(request, { kind: 'native' })\n requests.delete(rpcKey(identity.id))\n return delegateToNative(message.id, 'Subject rejected by privacy policy')\n }\n track(runRequest(request, phones))\n return { kind: 'claimed' }\n }\n const handle = (message: unknown): CodexDispatchResult => {\n try { return dispatch(message) } catch {\n fatal('Invalid message or host callback; close connection')\n return { kind: 'invalid', reason: 'Message could not be validated' }\n }\n }\n const registerThread = (value: unknown): void => {\n if (disposed) throw new Error('Adapter disposed')\n const id = certifiedThread(value)\n if (!id) throw new TypeError('Thread requires user approvals and a certified sandbox')\n if ([...requests.values()].some(request => request.state === 'pending' && request.identity.threadId === id)) throw new Error('Cannot replace thread policy while approval is pending')\n if (!threads.has(id) && threads.size >= MAX_THREADS) { overflow(); throw new Error('Thread capacity exceeded') }\n threads.add(id)\n }\n function onAbort(): void { void dispose() }\n config.signal?.addEventListener('abort', onAbort, { once: true })\n if (config.signal?.aborted) void dispose()\n return { registerThread, unregisterThread, handle, invalidateTurn, dispose }\n}\n","import type { CodexQuestion, CodexRequestId, CodexReviewSubject, FileChange, RequestIdentity } from './types'\n\nexport const COMMAND = 'item/commandExecution/requestApproval'\nexport const FILES = 'item/fileChange/requestApproval'\nexport const QUESTIONS = 'item/tool/requestUserInput'\nexport const CERTIFIED_CODEX_VERSIONS = ['0.160.1', '0.167.0'] as const\nexport type CertifiedCodexVersion = (typeof CERTIFIED_CODEX_VERSIONS)[number]\nexport const isCertifiedCodexVersion = (value: unknown): value is CertifiedCodexVersion => CERTIFIED_CODEX_VERSIONS.some(version => version === value)\nexport const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value)\nexport const isId = (value: unknown): value is CodexRequestId => typeof value === 'string' || (typeof value === 'number' && Number.isSafeInteger(value))\nexport const isText = (value: unknown): value is string => typeof value === 'string' && value.length > 0\nconst optionalText = (value: unknown): boolean => value === undefined || value === null || typeof value === 'string'\nexport const onlyKeys = (value: Record<string, unknown>, keys: readonly string[]): boolean => Object.keys(value).every(key => keys.includes(key))\nexport const identityOf = (id: CodexRequestId, method: string, params: Record<string, unknown>): RequestIdentity | null => {\n if (!isText(params.threadId) || !isText(params.turnId) || !isText(params.itemId) || !optionalText(params.approvalId)) return null\n return { id, method, threadId: params.threadId, turnId: params.turnId, itemId: params.itemId, approvalId: typeof params.approvalId === 'string' ? params.approvalId : null }\n}\nexport const certifiedThread = (value: unknown): string | null => {\n if (!isRecord(value) || !isRecord(value.thread) || !isText(value.thread.id) || !isRecord(value.thread.status) || value.thread.status.type !== 'idle') return null\n if ((value.approvalPolicy !== 'untrusted' && value.approvalPolicy !== 'on-request') || value.approvalsReviewer !== 'user' || !isRecord(value.sandbox)) return null\n const sandbox = value.sandbox\n if (sandbox.type !== 'readOnly' && sandbox.type !== 'workspaceWrite') return null\n if (!onlyKeys(sandbox, ['type', 'networkAccess', 'writableRoots', 'excludeSlashTmp', 'excludeTmpdirEnvVar'])) return null\n if (sandbox.networkAccess !== undefined && typeof sandbox.networkAccess !== 'boolean') return null\n if (sandbox.writableRoots !== undefined && (!Array.isArray(sandbox.writableRoots) || !sandbox.writableRoots.every(isText))) return null\n if (['excludeSlashTmp', 'excludeTmpdirEnvVar'].some(key => sandbox[key] !== undefined && typeof sandbox[key] !== 'boolean')) return null\n if (value.activePermissionProfile !== undefined && value.activePermissionProfile !== null) return null\n return value.thread.id\n}\nexport const fileChangesOf = (value: unknown): readonly FileChange[] | null => {\n if (!Array.isArray(value) || value.length === 0 || value.length > 128) return null\n const changes: FileChange[] = []\n for (const change of value) {\n if (!isRecord(change) || !onlyKeys(change, ['path', 'kind', 'diff']) || !isText(change.path) || typeof change.diff !== 'string' || !isRecord(change.kind)) return null\n const kind = change.kind\n if (!onlyKeys(kind, ['type', 'move_path']) || (kind.type !== 'add' && kind.type !== 'delete' && kind.type !== 'update')) return null\n if (!optionalText(kind.move_path) || (kind.type !== 'update' && kind.move_path != null)) return null\n changes.push({ path: change.path, operation: kind.type, movePath: typeof kind.move_path === 'string' ? kind.move_path : null, diff: change.diff })\n }\n return changes\n}\ntype SubjectResult = { readonly kind: 'supported'; readonly subject: CodexReviewSubject } | { readonly kind: 'unsupported'; readonly reason: string } | { readonly kind: 'malformed'; readonly reason: string }\nconst unsupported = (reason: string): SubjectResult => ({ kind: 'unsupported', reason })\nconst malformed = (reason: string): SubjectResult => ({ kind: 'malformed', reason })\nconst isKnownCommandDecision = (value: unknown): boolean => {\n if (typeof value === 'string') return ['accept', 'acceptForSession', 'decline', 'cancel'].includes(value)\n if (!isRecord(value) || !onlyKeys(value, ['acceptWithExecpolicyAmendment'])) return false\n const amendment = value.acceptWithExecpolicyAmendment\n return isRecord(amendment) && onlyKeys(amendment, ['execpolicy_amendment']) && Array.isArray(amendment.execpolicy_amendment) && amendment.execpolicy_amendment.every(isText)\n}\nexport const subjectOf = (method: string, params: Record<string, unknown>, changes: readonly FileChange[] | null, experimental: boolean): SubjectResult => {\n if (method === COMMAND) {\n if (!onlyKeys(params, ['threadId', 'turnId', 'itemId', 'approvalId', 'startedAtMs', 'kind', 'environmentId', 'command', 'cwd', 'reason', 'commandActions', 'networkApprovalContext', 'proposedExecpolicyAmendment', 'proposedNetworkPolicyAmendments', 'availableDecisions'])) return unsupported('Unknown command permission fields')\n if ((params.kind !== undefined && params.kind !== 'command') || (params.environmentId != null && params.environmentId !== 'local') || params.networkApprovalContext != null || params.proposedNetworkPolicyAmendments != null) return unsupported('Command needs native permission review')\n if (params.proposedExecpolicyAmendment != null && (!Array.isArray(params.proposedExecpolicyAmendment) || !params.proposedExecpolicyAmendment.every(isText))) return malformed('Invalid policy suggestion')\n if (params.availableDecisions != null && (!Array.isArray(params.availableDecisions) || !params.availableDecisions.includes('accept') || !params.availableDecisions.every(isKnownCommandDecision))) return unsupported('Unknown available approval decisions')\n if (!isText(params.command) || !isText(params.cwd) || !optionalText(params.reason) || !Number.isSafeInteger(params.startedAtMs)) return malformed('Incomplete command subject')\n return { kind: 'supported', subject: { kind: 'command', command: params.command, cwd: params.cwd, reason: typeof params.reason === 'string' ? params.reason : null } }\n }\n if (method === FILES) {\n if (!onlyKeys(params, ['threadId', 'turnId', 'itemId', 'startedAtMs', 'reason', 'grantRoot']) || params.grantRoot != null) return unsupported('File request widens permissions')\n if (!optionalText(params.reason) || !Number.isSafeInteger(params.startedAtMs)) return malformed('Malformed file request')\n if (!changes) return unsupported('Complete file patch unavailable')\n return { kind: 'supported', subject: { kind: 'files', changes, reason: typeof params.reason === 'string' ? params.reason : null } }\n }\n if (!experimental) return unsupported('Experimental questions disabled')\n if (!onlyKeys(params, ['threadId', 'turnId', 'itemId', 'questions', 'isBlocking', 'autoResolutionMs']) || params.isBlocking !== true || params.autoResolutionMs != null) return unsupported('Question requires native handling')\n if (!Array.isArray(params.questions) || params.questions.length < 1 || params.questions.length > 3) return malformed('Question count outside supported range')\n const questions: CodexQuestion[] = []\n for (const question of params.questions) {\n if (!isRecord(question) || !onlyKeys(question, ['id', 'header', 'question', 'isOther', 'isSecret', 'options'])) return malformed('Malformed question')\n if (question.isOther !== false || question.isSecret !== false) return unsupported('Secret or other-option question')\n if (!isText(question.id) || !isText(question.header) || !isText(question.question) || questions.some(entry => entry.id === question.id)) return malformed('Invalid question identity')\n let options: CodexQuestion['options'] = null\n if (question.options !== null) {\n if (!Array.isArray(question.options) || question.options.length < 2 || question.options.length > 20) return malformed('Invalid options')\n const validated: { label: string; description: string }[] = []\n for (const option of question.options) {\n if (!isRecord(option) || !onlyKeys(option, ['label', 'description']) || !isText(option.label) || option.label.length > 200 || typeof option.description !== 'string' || validated.some(entry => entry.label === option.label)) return malformed('Invalid option')\n validated.push({ label: option.label, description: option.description })\n }\n options = validated\n }\n questions.push({ id: question.id, header: question.header, question: question.question, options })\n }\n return { kind: 'supported', subject: { kind: 'questions', questions } }\n}\n","import type { CodexReviewSubject } from './types'\nimport type { DecisionType } from '@pushary/server'\n\nexport interface PhoneQuestion {\n readonly question: string\n readonly context: string\n readonly type: DecisionType\n readonly options?: readonly string[]\n readonly questionId?: string\n}\nexport const visibleText = (text: string): string => text.replace(/\\\\/g, '\\\\\\\\').replace(/[\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}]/gu, character => `\\\\u{${character.codePointAt(0)?.toString(16)}}`)\nconst bounded = (questions: readonly PhoneQuestion[]): readonly PhoneQuestion[] | null => questions.every(question => question.question.length <= 8000 && question.context.length <= 2000 && question.options?.some(option => option.length > 200) !== true) ? questions : null\nexport const presentSubject = (subject: CodexReviewSubject): readonly PhoneQuestion[] | null => {\n if (subject.kind === 'command') return bounded([{ type: 'confirm', question: `Approve this command once?\\n\\n${visibleText(subject.command)}\\n\\nWorking directory: ${visibleText(subject.cwd)}\\nReason: ${visibleText(subject.reason ?? '(none)')}`, context: 'Codex command approval. This approval applies only to this request.' }])\n if (subject.kind === 'files') {\n const patches = subject.changes.map(change => `${change.operation}: ${visibleText(change.path)}${change.movePath === null ? '' : ` -> ${visibleText(change.movePath)}`}\\n${visibleText(change.diff)}`).join('\\n\\n')\n return bounded([{ type: 'confirm', question: `Approve these exact file changes once?\\n\\n${patches}\\n\\nReason: ${visibleText(subject.reason ?? '(none)')}`, context: 'Codex file approval. Includes every file and the complete patch.' }])\n }\n return bounded(subject.questions.map(question => ({ questionId: question.id, type: question.options ? 'select' : 'input', question: `${visibleText(question.header)}\\n${visibleText(question.question)}${question.options ? '\\n\\n' + question.options.map(option => `${visibleText(option.label)}: ${visibleText(option.description)}`).join('\\n') : ''}`, options: question.options?.map(option => visibleText(option.label)), context: 'Answer this Codex question. This answer does not grant tool permissions.' })))\n}\n","import { PusharyApiError, type DecisionType } from '@pushary/server'\nimport { isRecord, isText } from './protocol'\n\nexport interface DecisionSnapshot {\n readonly decisionId: string\n readonly status: 'pending' | 'answered' | 'expired' | 'cancelled' | 'stopped'\n readonly answered: boolean\n readonly value: string | null\n readonly type: DecisionType\n}\nexport const decisionSnapshot = (value: unknown, type: DecisionType, expectedId?: string): DecisionSnapshot => {\n if (!isRecord(value) || !isText(value.decisionId) || (expectedId !== undefined && value.decisionId !== expectedId) || value.type !== type || typeof value.answered !== 'boolean') throw new Error('Invalid decision response')\n const status = value.status\n if (status !== 'pending' && status !== 'answered' && status !== 'expired' && status !== 'cancelled' && status !== 'stopped') throw new Error('Unknown decision status')\n if ((status === 'answered') !== value.answered || (status === 'answered' && typeof value.value !== 'string') || (status !== 'answered' && value.value != null)) throw new Error('Inconsistent decision response')\n return { decisionId: value.decisionId, status, answered: value.answered, value: typeof value.value === 'string' ? value.value : null, type }\n}\nexport const isRetryable = (error: unknown): boolean => error instanceof PusharyApiError ? error.status === 429 || error.status >= 500 : error instanceof TypeError || (error instanceof Error && error.name === 'TimeoutError')\nexport const delay = (milliseconds: number, signal: AbortSignal): Promise<void> => new Promise((resolve, reject) => {\n if (signal.aborted) { reject(signal.reason); return }\n const onAbort = (): void => { clearTimeout(timer); reject(signal.reason) }\n const timer = setTimeout(() => { signal.removeEventListener('abort', onAbort); resolve() }, milliseconds)\n signal.addEventListener('abort', onAbort, { once: true })\n})\nexport const withRetry = async <T>(operation: () => Promise<T>, signal: AbortSignal): Promise<T> => {\n for (let attempt = 0; ; attempt += 1) {\n signal.throwIfAborted()\n try { return await operation() } catch (error) {\n if (signal.aborted || attempt >= 3 || !isRetryable(error)) throw error\n await delay(250 * 2 ** attempt + Math.floor(Math.random() * 101), signal)\n }\n }\n}\n\nexport const decisionFailureReason = (error: unknown): string => {\n if (error instanceof PusharyApiError) return `Partner HTTP ${error.status}`\n if (error instanceof TypeError) return 'Decision transport unavailable'\n if (error instanceof Error && error.name === 'TimeoutError') return 'Decision HTTP deadline elapsed'\n return 'Decision response invalid or unavailable'\n}\n","import type { CodexReply, CodexRequestId } from './types'\n\nexport type RequestState = 'pending' | 'accepted' | 'closed'\nexport type RequestCompletion =\n | { readonly kind: 'reply'; readonly reply: CodexReply }\n | { readonly kind: 'refuse' | 'conflict' | 'abandon'; readonly reason: string }\n | { readonly kind: 'native' }\n\ninterface RequestContext {\n readonly id: CodexRequestId\n readonly isQuestion: boolean\n readonly replyAllowed: boolean\n readonly deadlineElapsed: boolean\n}\ninterface RequestTransition {\n readonly state: Exclude<RequestState, 'pending'>\n readonly reply: CodexReply | null\n readonly interruption: string | null\n readonly abandonment: string | null\n}\n\nexport const transitionRequest = (state: RequestState, completion: RequestCompletion, context: RequestContext): RequestTransition | null => {\n if (state !== 'pending') return null\n if (completion.kind === 'reply') {\n if (!context.replyAllowed || context.deadlineElapsed) return null\n const reply = completion.reply\n const accepted = 'result' in reply && 'decision' in reply.result && reply.result.decision === 'accept'\n return { state: accepted ? 'accepted' : 'closed', reply, interruption: null, abandonment: null }\n }\n if (completion.kind === 'native') return { state: 'closed', reply: null, interruption: null, abandonment: null }\n if (completion.kind === 'abandon' || !context.replyAllowed) return { state: 'closed', reply: null, interruption: null, abandonment: completion.reason }\n const reply: CodexReply = context.isQuestion\n ? { id: context.id, error: { code: -32000, message: completion.reason } }\n : { id: context.id, result: { decision: 'cancel' } }\n return { state: 'closed', reply, interruption: context.isQuestion || completion.kind === 'conflict' ? completion.reason : null, abandonment: completion.reason }\n}\n"],"mappings":"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","names":["import_adapters","import_server","reply","request"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import * as _pushary_server from '@pushary/server';
|
|
2
2
|
import * as _pushary_server_adapters from '@pushary/server/adapters';
|
|
3
3
|
|
|
4
|
+
declare const CERTIFIED_CODEX_VERSIONS: readonly ["0.160.1", "0.167.0"];
|
|
5
|
+
type CertifiedCodexVersion = (typeof CERTIFIED_CODEX_VERSIONS)[number];
|
|
6
|
+
|
|
4
7
|
type CodexRequestId = string | number;
|
|
5
8
|
type CodexReply = {
|
|
6
9
|
readonly id: CodexRequestId;
|
|
@@ -70,7 +73,7 @@ interface PusharyCodexConfig {
|
|
|
70
73
|
readonly tenantId: string;
|
|
71
74
|
readonly agentName?: string;
|
|
72
75
|
readonly baseUrl?: string;
|
|
73
|
-
readonly codexVersion:
|
|
76
|
+
readonly codexVersion: CertifiedCodexVersion;
|
|
74
77
|
readonly experimentalQuestions?: boolean;
|
|
75
78
|
readonly timeoutMs?: number;
|
|
76
79
|
readonly signal?: AbortSignal;
|
|
@@ -93,4 +96,4 @@ declare const createPusharyCodexHandler: (configuration: PusharyCodexConfig) =>
|
|
|
93
96
|
|
|
94
97
|
declare const connect: (config: _pushary_server_adapters.PusharyAdapterConfig, externalId: string) => Promise<_pushary_server.EnrollResult>;
|
|
95
98
|
|
|
96
|
-
export { type CodexDispatchResult, type CodexReply, type CodexRequestId, type CodexReviewSubject, type PusharyCodexConfig, type PusharyCodexEvent, type PusharyCodexHandler, connect, createPusharyCodexHandler };
|
|
99
|
+
export { CERTIFIED_CODEX_VERSIONS, type CertifiedCodexVersion, type CodexDispatchResult, type CodexReply, type CodexRequestId, type CodexReviewSubject, type PusharyCodexConfig, type PusharyCodexEvent, type PusharyCodexHandler, connect, createPusharyCodexHandler };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import * as _pushary_server from '@pushary/server';
|
|
2
2
|
import * as _pushary_server_adapters from '@pushary/server/adapters';
|
|
3
3
|
|
|
4
|
+
declare const CERTIFIED_CODEX_VERSIONS: readonly ["0.160.1", "0.167.0"];
|
|
5
|
+
type CertifiedCodexVersion = (typeof CERTIFIED_CODEX_VERSIONS)[number];
|
|
6
|
+
|
|
4
7
|
type CodexRequestId = string | number;
|
|
5
8
|
type CodexReply = {
|
|
6
9
|
readonly id: CodexRequestId;
|
|
@@ -70,7 +73,7 @@ interface PusharyCodexConfig {
|
|
|
70
73
|
readonly tenantId: string;
|
|
71
74
|
readonly agentName?: string;
|
|
72
75
|
readonly baseUrl?: string;
|
|
73
|
-
readonly codexVersion:
|
|
76
|
+
readonly codexVersion: CertifiedCodexVersion;
|
|
74
77
|
readonly experimentalQuestions?: boolean;
|
|
75
78
|
readonly timeoutMs?: number;
|
|
76
79
|
readonly signal?: AbortSignal;
|
|
@@ -93,4 +96,4 @@ declare const createPusharyCodexHandler: (configuration: PusharyCodexConfig) =>
|
|
|
93
96
|
|
|
94
97
|
declare const connect: (config: _pushary_server_adapters.PusharyAdapterConfig, externalId: string) => Promise<_pushary_server.EnrollResult>;
|
|
95
98
|
|
|
96
|
-
export { type CodexDispatchResult, type CodexReply, type CodexRequestId, type CodexReviewSubject, type PusharyCodexConfig, type PusharyCodexEvent, type PusharyCodexHandler, connect, createPusharyCodexHandler };
|
|
99
|
+
export { CERTIFIED_CODEX_VERSIONS, type CertifiedCodexVersion, type CodexDispatchResult, type CodexReply, type CodexRequestId, type CodexReviewSubject, type PusharyCodexConfig, type PusharyCodexEvent, type PusharyCodexHandler, connect, createPusharyCodexHandler };
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,8 @@ import { decisionFingerprint } from "@pushary/server/adapters";
|
|
|
10
10
|
var COMMAND = "item/commandExecution/requestApproval";
|
|
11
11
|
var FILES = "item/fileChange/requestApproval";
|
|
12
12
|
var QUESTIONS = "item/tool/requestUserInput";
|
|
13
|
+
var CERTIFIED_CODEX_VERSIONS = ["0.160.1", "0.167.0"];
|
|
14
|
+
var isCertifiedCodexVersion = (value) => CERTIFIED_CODEX_VERSIONS.some((version) => version === value);
|
|
13
15
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14
16
|
var isId = (value) => typeof value === "string" || typeof value === "number" && Number.isSafeInteger(value);
|
|
15
17
|
var isText = (value) => typeof value === "string" && value.length > 0;
|
|
@@ -184,7 +186,7 @@ var rpcKey = (id) => JSON.stringify([typeof id, id]);
|
|
|
184
186
|
var createPusharyCodexHandler = (configuration) => {
|
|
185
187
|
const config = Object.freeze({ ...configuration });
|
|
186
188
|
const timeoutMs = config.timeoutMs ?? 3e5;
|
|
187
|
-
if (config.codexVersion
|
|
189
|
+
if (!isCertifiedCodexVersion(config.codexVersion) || !Number.isInteger(timeoutMs) || timeoutMs < 6e4 || timeoutMs > 6e5 || !config.tenantId?.trim() || !config.externalId?.trim()) throw new TypeError("Invalid Codex adapter configuration");
|
|
188
190
|
if ([config.sendResponse, config.requestTurnInterrupt, config.onEvent, config.maySendSubject].some((callback) => typeof callback !== "function")) throw new TypeError("All host callbacks are required");
|
|
189
191
|
const decisions = createPusharyServer({ apiKey: config.apiKey, baseUrl: config.baseUrl, requestTimeoutMs: 1e4 }).decisions;
|
|
190
192
|
const generation = randomUUID();
|
|
@@ -592,6 +594,7 @@ var createPusharyCodexHandler = (configuration) => {
|
|
|
592
594
|
// src/index.ts
|
|
593
595
|
var connect = createAdapterKernel("Codex app-server").connect;
|
|
594
596
|
export {
|
|
597
|
+
CERTIFIED_CODEX_VERSIONS,
|
|
595
598
|
connect,
|
|
596
599
|
createPusharyCodexHandler
|
|
597
600
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/handler.ts","../src/protocol.ts","../src/presentation.ts","../src/partner-decisions.ts","../src/request-lifecycle.ts"],"sourcesContent":["import { createAdapterKernel } from '@pushary/server/adapters'\nexport { createPusharyCodexHandler } from './handler'\nexport type { CodexRequestId, CodexReply, CodexDispatchResult, CodexReviewSubject, PusharyCodexConfig, PusharyCodexEvent, PusharyCodexHandler } from './types'\nexport const connect = createAdapterKernel('Codex app-server').connect\n","import { randomUUID } from 'node:crypto'\nimport { createPusharyServer, isApproved, type CreateDecision } from '@pushary/server'\nimport { decisionFingerprint } from '@pushary/server/adapters'\nimport { COMMAND, FILES, QUESTIONS, certifiedThread, fileChangesOf, identityOf, isId, isRecord, isText, subjectOf } from './protocol'\nimport { presentSubject, type PhoneQuestion } from './presentation'\nimport { decisionFailureReason, decisionSnapshot, delay, isRetryable, withRetry, type DecisionSnapshot } from './partner-decisions'\nimport { transitionRequest, type RequestCompletion, type RequestState } from './request-lifecycle'\nimport type { CodexDispatchResult, CodexReviewSubject, FileChange, PusharyCodexConfig, PusharyCodexEvent, PusharyCodexHandler, RequestIdentity } from './types'\n\nconst MAX_PENDING = 8\nconst MAX_THREADS = 32\nconst MAX_ITEMS = 128\nconst MAX_CACHE_BYTES = 4 * 1024 * 1024\nconst MAX_REQUESTS = 4096\nconst CLEANUP_MS = 5000\nconst MIN_QUESTION_BUDGET_MS = 10_000\ninterface OwnedRequest {\n readonly identity: RequestIdentity\n readonly declineDecision: 'decline' | 'cancel'\n readonly digest: string\n readonly envelopeDigest: string\n readonly subject: CodexReviewSubject\n readonly controller: AbortController\n readonly deadline: number\n readonly timer: ReturnType<typeof setTimeout>\n readonly decisionIds: Set<string>\n readonly cleanupIds: Set<string>\n state: RequestState\n cleanupDeadline: number\n}\ninterface CachedPatch { readonly changes: readonly FileChange[] | null; readonly digest: string; readonly bytes: number }\nconst itemKey = (threadId: string, turnId: string, itemId: string): string => JSON.stringify([threadId, turnId, itemId])\nconst turnKey = (threadId: string, turnId: string): string => JSON.stringify([threadId, turnId])\nconst rpcKey = (id: string | number): string => JSON.stringify([typeof id, id])\n\nexport const createPusharyCodexHandler = (configuration: PusharyCodexConfig): PusharyCodexHandler => {\n const config = Object.freeze({ ...configuration })\n const timeoutMs = config.timeoutMs ?? 300_000\n if (config.codexVersion !== '0.160.1' || !Number.isInteger(timeoutMs) || timeoutMs < 60_000 || timeoutMs > 600_000 || !config.tenantId?.trim() || !config.externalId?.trim()) throw new TypeError('Invalid Codex adapter configuration')\n if ([config.sendResponse, config.requestTurnInterrupt, config.onEvent, config.maySendSubject].some(callback => typeof callback !== 'function')) throw new TypeError('All host callbacks are required')\n const decisions = createPusharyServer({ apiKey: config.apiKey, baseUrl: config.baseUrl, requestTimeoutMs: 10_000 }).decisions\n const generation = randomUUID()\n const threads = new Set<string>()\n const requests = new Map<string, OwnedRequest>()\n const closedRequestIds = new Set<string>()\n const turns = new Map<string, { readonly threadId: string; readonly turnId: string; terminal: boolean }>()\n const completedItems = new Set<string>()\n const patches = new Map<string, CachedPatch>()\n const jobs = new Set<Promise<void>>()\n const cleanupFailures: string[] = []\n const cleanupControllers = new Set<AbortController>()\n let cacheBytes = 0\n let disposed = false\n let disposal: Promise<{ readonly cleanupFailures: readonly string[] }> | undefined\n let disposalDeadline = Infinity\n const emit = (event: PusharyCodexEvent): void => {\n try { config.onEvent(event) } catch { console.error('Pushary Codex onEvent callback failed') }\n }\n const eventFor = (request: OwnedRequest, type: PusharyCodexEvent['type'], reason?: string, decisionId?: string): void => emit({ type, requestId: request.identity.id, threadId: request.identity.threadId, turnId: request.identity.turnId, subjectDigest: request.digest, decisionId, reason })\n const track = (job: Promise<void>): void => { jobs.add(job); void job.finally(() => jobs.delete(job)).catch(() => undefined) }\n const cleanupFailed = (request: OwnedRequest, id: string): void => {\n cleanupFailures.push(id)\n eventFor(request, 'cleanup_failed', 'Decision cleanup not confirmed before deadline', id)\n }\n const cleanup = async (request: OwnedRequest, id: string): Promise<void> => {\n if (request.cleanupIds.has(id)) return\n request.cleanupIds.add(id)\n const remaining = Math.min(request.cleanupDeadline, disposalDeadline) - performance.now()\n if (remaining <= 0) { cleanupFailed(request, id); return }\n const controller = new AbortController()\n cleanupControllers.add(controller)\n const timer = setTimeout(() => controller.abort(), remaining)\n try {\n for (let attempt = 0; attempt < 3; attempt += 1) {\n try {\n const result: unknown = await decisions.cancel(id, { signal: controller.signal })\n if (!isRecord(result) || result.decisionId !== id || typeof result.cancelled !== 'boolean') throw new Error('Invalid cancellation result')\n if (result.cancelled) return\n const latest: unknown = await decisions.get(id, { signal: controller.signal })\n if (isRecord(latest) && (latest.type === 'confirm' || latest.type === 'select' || latest.type === 'input')) {\n const snapshot = decisionSnapshot(latest, latest.type, id)\n if (snapshot.status !== 'pending') return\n }\n throw new TypeError('Cancellation still pending')\n } catch (error) {\n if (controller.signal.aborted || attempt === 2 || !isRetryable(error)) throw error\n await delay(attempt === 0 ? 100 : 300, controller.signal)\n }\n }\n } catch { cleanupFailed(request, id) } finally { clearTimeout(timer); cleanupControllers.delete(controller) }\n }\n const beginCleanup = (request: OwnedRequest): void => {\n clearTimeout(request.timer)\n request.cleanupDeadline = Math.min(performance.now() + CLEANUP_MS, disposalDeadline)\n request.controller.abort()\n for (const id of request.decisionIds) track(cleanup(request, id))\n }\n const completeRequest = (request: OwnedRequest, completion: RequestCompletion): void => {\n const transition = transitionRequest(request.state, completion, {\n id: request.identity.id,\n isQuestion: request.subject.kind === 'questions',\n replyAllowed: contextLive(request),\n deadlineElapsed: performance.now() >= request.deadline,\n })\n if (!transition) return\n request.state = transition.state\n beginCleanup(request)\n if (transition.reply && contextLive(request)) {\n const interrupted = transition.interruption === null || interrupt(request.identity, transition.interruption)\n if (interrupted && contextLive(request)) {\n try { config.sendResponse(transition.reply) } catch { fatal('Response enqueue failed; close connection') }\n }\n }\n if (transition.abandonment !== null) eventFor(request, 'request_abandoned', transition.abandonment)\n }\n const dispose = (): Promise<{ readonly cleanupFailures: readonly string[] }> => {\n if (disposal) return disposal\n disposed = true\n disposalDeadline = performance.now() + CLEANUP_MS\n config.signal?.removeEventListener('abort', onAbort)\n let resolveDisposal: (value: { readonly cleanupFailures: readonly string[] }) => void = () => undefined\n disposal = new Promise(resolve => { resolveDisposal = resolve })\n threads.clear()\n patches.clear()\n cacheBytes = 0\n for (const request of requests.values()) completeRequest(request, { kind: 'abandon', reason: 'Connection disposed' })\n const finish = async (): Promise<void> => {\n const controller = new AbortController()\n const drain = async (): Promise<void> => { while (jobs.size > 0 && performance.now() < disposalDeadline) await Promise.allSettled([...jobs]) }\n await Promise.race([drain(), delay(CLEANUP_MS, controller.signal)]).catch(() => undefined)\n controller.abort()\n for (const cleanupController of cleanupControllers) cleanupController.abort()\n await Promise.resolve()\n resolveDisposal({ cleanupFailures: [...cleanupFailures] })\n }\n void finish()\n return disposal\n }\n const fatal = (reason: string): void => {\n void dispose()\n emit({ type: 'reply_failed', reason })\n }\n const overflow = (): void => { void dispose(); emit({ type: 'capacity_exceeded', reason: 'Connection must close; bounded adapter capacity exceeded' }) }\n const stateCount = (): number => requests.size + closedRequestIds.size + turns.size + completedItems.size\n const rememberTurn = (threadId: string, turnId: string, terminal: boolean): boolean => {\n const key = turnKey(threadId, turnId)\n const previous = turns.get(key)\n if (previous) { previous.terminal ||= terminal; return true }\n if (stateCount() >= MAX_REQUESTS) { overflow(); return false }\n turns.set(key, { threadId, turnId, terminal })\n return true\n }\n const contextEnded = (identity: RequestIdentity): boolean => turns.get(turnKey(identity.threadId, identity.turnId))?.terminal === true || completedItems.has(itemKey(identity.threadId, identity.turnId, identity.itemId))\n const contextLive = (request: OwnedRequest): boolean => !disposed && !contextEnded(request.identity) && threads.has(request.identity.threadId)\n const live = (request: OwnedRequest): boolean => request.state === 'pending' && contextLive(request) && performance.now() < request.deadline\n const interrupt = (identity: RequestIdentity, reason: string): boolean => {\n try { config.requestTurnInterrupt(identity.threadId, identity.turnId, reason); return !disposed } catch { fatal('Turn interrupt enqueue failed; close connection'); return false }\n }\n const fenceTurn = (threadId: string, turnId: string, reason: string): void => {\n if (!rememberTurn(threadId, turnId, true)) return\n for (const request of requests.values()) if (request.identity.threadId === threadId && request.identity.turnId === turnId) completeRequest(request, { kind: 'abandon', reason })\n for (const key of patches.keys()) {\n if (key.startsWith(JSON.stringify([threadId, turnId]).slice(0, -1) + ',')) { cacheBytes -= patches.get(key)?.bytes ?? 0; patches.delete(key) }\n }\n }\n const invalidateTurn = (threadId: string, turnId: string, reason: string): void => {\n const accepted = [...requests.values()].find(request => request.identity.threadId === threadId && request.identity.turnId === turnId && request.state === 'accepted' && !contextEnded(request.identity))\n fenceTurn(threadId, turnId, reason)\n if (accepted) {\n if (!disposed) interrupt(accepted.identity, reason)\n eventFor(accepted, 'request_abandoned', 'Invalidated after acceptance enqueue; execution outcome unknown')\n }\n }\n const unregisterThread = (threadId: string): void => {\n threads.delete(threadId)\n for (const turn of turns.values()) if (turn.threadId === threadId) invalidateTurn(threadId, turn.turnId, 'Thread unregistered')\n for (const key of patches.keys()) if (key.startsWith(JSON.stringify([threadId]).slice(0, -1) + ',')) { cacheBytes -= patches.get(key)?.bytes ?? 0; patches.delete(key) }\n }\n const createAndWait = async (request: OwnedRequest, phone: PhoneQuestion, ordinal: number): Promise<DecisionSnapshot> => {\n const payload: CreateDecision = { question: phone.question, type: phone.type, options: phone.options, context: phone.context, externalId: config.externalId, agentName: config.agentName ?? 'Codex', wait: false, requireReachable: true, expiresInSeconds: Math.ceil(timeoutMs / 1000), idempotencyKey: decisionFingerprint({ tenantId: config.tenantId, externalId: config.externalId, generation, ...request.identity, subjectDigest: request.digest, ordinal, questionId: phone.questionId ?? null }) }\n let raw: unknown\n try { raw = await withRetry(() => decisions.create(payload, { signal: request.controller.signal }), request.controller.signal) } catch (error) {\n if (request.controller.signal.aborted || isRetryable(error)) eventFor(request, 'create_outcome_unknown', 'Create may have reached server; TTL bounds residual prompt')\n throw error\n }\n if (isRecord(raw) && isText(raw.decisionId)) {\n request.decisionIds.add(raw.decisionId)\n if (!live(request)) { track(cleanup(request, raw.decisionId)); throw new Error('Request no longer live') }\n }\n if (!isRecord(raw) || !isText(raw.decisionId)) eventFor(request, 'create_outcome_unknown', 'Create returned no usable decision ID')\n let snapshot = decisionSnapshot(raw, phone.type)\n eventFor(request, 'decision_created', undefined, snapshot.decisionId)\n while (snapshot.status === 'pending') {\n if (!live(request)) throw new Error('Request no longer live')\n const next: unknown = await withRetry(() => decisions.get(snapshot.decisionId, { wait: 5, signal: request.controller.signal }), request.controller.signal)\n snapshot = decisionSnapshot(next, phone.type, snapshot.decisionId)\n if (snapshot.status === 'pending') await delay(50, request.controller.signal)\n }\n request.decisionIds.delete(snapshot.decisionId)\n eventFor(request, 'decision_settled', snapshot.status, snapshot.decisionId)\n return snapshot\n }\n const runRequest = async (request: OwnedRequest, phones: readonly PhoneQuestion[]): Promise<void> => {\n try {\n const answers: Record<string, { answers: readonly string[] }> = Object.create(null)\n for (const [ordinal, phone] of phones.entries()) {\n if (!live(request)) return\n if (ordinal > 0 && request.deadline - performance.now() < MIN_QUESTION_BUDGET_MS) { completeRequest(request, { kind: 'refuse', reason: 'Insufficient time for another question' }); return }\n const result = await createAndWait(request, phone, ordinal)\n if (!live(request)) return\n if (request.subject.kind !== 'questions') {\n const approved = result.type === 'confirm' && result.status === 'answered' && isApproved({ status: result.status, type: result.type, value: result.value })\n completeRequest(request, { kind: 'reply', reply: { id: request.identity.id, result: { decision: approved ? 'accept' : request.declineDecision } } })\n return\n }\n if (!result.answered || !result.value?.trim() || result.value.length > 2000 || (phone.options && !phone.options.includes(result.value))) { completeRequest(request, { kind: 'refuse', reason: 'Question did not receive a valid answer' }); return }\n const question = request.subject.questions[ordinal]\n if (!question || !phone.questionId) throw new Error('Question identity missing')\n const selectedIndex = phone.options?.indexOf(result.value)\n const answer = selectedIndex !== undefined ? question.options?.[selectedIndex]?.label : result.value\n if (answer === undefined) throw new Error('Question option missing')\n answers[phone.questionId] = { answers: [answer] }\n }\n completeRequest(request, { kind: 'reply', reply: { id: request.identity.id, result: { answers } } })\n } catch (error) { if (live(request)) completeRequest(request, { kind: 'refuse', reason: decisionFailureReason(error) }) }\n }\n const observe = (method: string, params: Record<string, unknown>): CodexDispatchResult => {\n if (method === 'serverRequest/resolved' && isId(params.requestId)) {\n const request = requests.get(rpcKey(params.requestId))\n if (request && params.threadId === request.identity.threadId) completeRequest(request, { kind: 'abandon', reason: 'Server request resolved' })\n }\n if (isText(params.threadId)) {\n if (threads.has(params.threadId) && isRecord(params.turn) && isText(params.turn.id) && method === 'turn/started') rememberTurn(params.threadId, params.turn.id, false)\n if (['thread/closed', 'thread/archived', 'thread/settings/updated'].includes(method)) unregisterThread(params.threadId)\n if (isText(params.turnId) && ['turn/completed', 'turn/interrupted', 'turn/failed'].includes(method)) fenceTurn(params.threadId, params.turnId, method)\n if (isRecord(params.turn) && isText(params.turn.id) && method === 'turn/completed') fenceTurn(params.threadId, params.turn.id, method)\n const itemId = isRecord(params.item) && isText(params.item.id) ? params.item.id : params.itemId\n if (isText(params.turnId) && isText(itemId)) {\n const key = itemKey(params.threadId, params.turnId, itemId)\n if (method === 'item/completed') {\n if (!completedItems.has(key) && stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Terminal item capacity exceeded' } }\n completedItems.add(key)\n for (const request of requests.values()) if (itemKey(request.identity.threadId, request.identity.turnId, request.identity.itemId) === key) completeRequest(request, { kind: 'abandon', reason: 'Item completed' })\n cacheBytes -= patches.get(key)?.bytes ?? 0\n patches.delete(key)\n }\n if (threads.has(params.threadId) && !completedItems.has(key) && turns.get(turnKey(params.threadId, params.turnId))?.terminal !== true && (method === 'item/fileChange/patchUpdated' || (method === 'item/started' && isRecord(params.item) && params.item.type === 'fileChange'))) {\n if (!rememberTurn(params.threadId, params.turnId, false)) return { kind: 'invalid', reason: 'Turn capacity exceeded' }\n const raw = method === 'item/started' && isRecord(params.item) ? params.item.changes : params.changes\n const previous = patches.get(key)\n const parsed = fileChangesOf(raw)\n const digest = decisionFingerprint(parsed)\n const conflict = previous !== undefined && previous.digest !== digest\n const changes = (method === 'item/fileChange/patchUpdated' && !previous) || (method === 'item/started' && conflict) || previous?.changes === null ? null : parsed\n const bytes = Buffer.byteLength(JSON.stringify(changes))\n if ((!previous && patches.size >= MAX_ITEMS) || cacheBytes - (previous?.bytes ?? 0) + bytes > MAX_CACHE_BYTES) { overflow(); return { kind: 'invalid', reason: 'Patch capacity exceeded' } }\n patches.set(key, { changes, digest, bytes })\n cacheBytes += bytes - (previous?.bytes ?? 0)\n if (conflict || changes === null) for (const request of requests.values()) if (itemKey(request.identity.threadId, request.identity.turnId, request.identity.itemId) === key) {\n if (request.state === 'accepted' && !contextEnded(request.identity)) invalidateTurn(request.identity.threadId, request.identity.turnId, 'Reviewed patch changed after acceptance')\n else completeRequest(request, { kind: 'refuse', reason: 'Reviewed patch changed' })\n }\n }\n }\n }\n return { kind: 'observed' }\n }\n const delegateToNative = (id: string | number, reason: string): CodexDispatchResult => {\n if (stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n closedRequestIds.add(rpcKey(id))\n emit({ type: 'native_review_required', requestId: id, reason })\n return disposed ? { kind: 'invalid', reason: 'Disposed during native handoff' } : { kind: 'unhandled', reason }\n }\n const dispatch = (message: unknown): CodexDispatchResult => {\n if (disposed) return { kind: 'invalid', reason: 'Adapter disposed' }\n if (!isRecord(message) || !isText(message.method) || !isRecord(message.params)) return { kind: 'invalid', reason: 'Invalid server envelope' }\n if (message.id === undefined) return observe(message.method, message.params)\n if (!isId(message.id)) return { kind: 'invalid', reason: 'Invalid RPC ID' }\n if (closedRequestIds.has(rpcKey(message.id))) return { kind: 'claimed' }\n const previous = requests.get(rpcKey(message.id))\n if (previous) {\n if (previous.envelopeDigest !== decisionFingerprint({ method: message.method, params: message.params })) {\n if (previous.state === 'accepted') invalidateTurn(previous.identity.threadId, previous.identity.turnId, 'Conflicting duplicate request')\n else completeRequest(previous, { kind: 'conflict', reason: 'Conflicting duplicate request' })\n }\n return { kind: 'claimed' }\n }\n if (![COMMAND, FILES, QUESTIONS].includes(message.method)) return delegateToNative(message.id, 'Unsupported server method')\n const identity = identityOf(message.id, message.method, message.params)\n if (!identity) return { kind: 'invalid', reason: 'Malformed request identity; close connection' }\n if (contextEnded(identity)) {\n if (stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n closedRequestIds.add(rpcKey(identity.id))\n if (identity.method === QUESTIONS && !interrupt(identity, 'Request context has ended')) return { kind: 'invalid', reason: 'Interrupt failed' }\n if (!disposed) config.sendResponse(identity.method === QUESTIONS ? { id: identity.id, error: { code: -32000, message: 'Request context has ended' } } : { id: identity.id, result: { decision: 'cancel' } })\n return { kind: 'claimed' }\n }\n if (!threads.has(identity.threadId)) return delegateToNative(message.id, 'Unregistered request context')\n if (!rememberTurn(identity.threadId, identity.turnId, false)) return { kind: 'invalid', reason: 'Turn capacity exceeded' }\n const subject = subjectOf(message.method, message.params, patches.get(itemKey(identity.threadId, identity.turnId, identity.itemId))?.changes ?? null, config.experimentalQuestions === true)\n if (subject.kind === 'malformed') {\n if (stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n closedRequestIds.add(rpcKey(message.id))\n if (message.method === QUESTIONS && !interrupt(identity, subject.reason)) return { kind: 'invalid', reason: 'Interrupt failed' }\n try { config.sendResponse({ id: message.id, error: { code: -32602, message: subject.reason } }) } catch { fatal('Invalid-params response enqueue failed') }\n return { kind: 'claimed' }\n }\n if (subject.kind === 'unsupported') return delegateToNative(message.id, subject.reason)\n const digest = decisionFingerprint(subject.subject)\n const phones = presentSubject(subject.subject)\n if (!phones) return delegateToNative(message.id, 'Subject exceeds presentation limits')\n if (stateCount() >= MAX_REQUESTS || [...requests.values()].filter(request => request.state === 'pending').length >= MAX_PENDING) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n const controller = new AbortController()\n const timer = setTimeout(() => { const request = requests.get(rpcKey(identity.id)); if (request) completeRequest(request, { kind: 'refuse', reason: 'Decision deadline elapsed' }) }, timeoutMs)\n const request: OwnedRequest = { identity, declineDecision: Array.isArray(message.params.availableDecisions) && !message.params.availableDecisions.includes('decline') ? 'cancel' : 'decline', digest, envelopeDigest: decisionFingerprint({ method: message.method, params: message.params }), subject: subject.subject, controller, deadline: performance.now() + timeoutMs, timer, decisionIds: new Set(), cleanupIds: new Set(), state: 'pending', cleanupDeadline: Infinity }\n requests.set(rpcKey(identity.id), request)\n let allowed = false\n try { allowed = config.maySendSubject(structuredClone(subject.subject)) === true } catch { allowed = false }\n if (disposed) return { kind: 'invalid', reason: 'Disposed during privacy review' }\n if (!live(request)) return { kind: 'claimed' }\n if (!allowed) {\n completeRequest(request, { kind: 'native' })\n requests.delete(rpcKey(identity.id))\n return delegateToNative(message.id, 'Subject rejected by privacy policy')\n }\n track(runRequest(request, phones))\n return { kind: 'claimed' }\n }\n const handle = (message: unknown): CodexDispatchResult => {\n try { return dispatch(message) } catch {\n fatal('Invalid message or host callback; close connection')\n return { kind: 'invalid', reason: 'Message could not be validated' }\n }\n }\n const registerThread = (value: unknown): void => {\n if (disposed) throw new Error('Adapter disposed')\n const id = certifiedThread(value)\n if (!id) throw new TypeError('Thread requires user approvals and a certified sandbox')\n if ([...requests.values()].some(request => request.state === 'pending' && request.identity.threadId === id)) throw new Error('Cannot replace thread policy while approval is pending')\n if (!threads.has(id) && threads.size >= MAX_THREADS) { overflow(); throw new Error('Thread capacity exceeded') }\n threads.add(id)\n }\n function onAbort(): void { void dispose() }\n config.signal?.addEventListener('abort', onAbort, { once: true })\n if (config.signal?.aborted) void dispose()\n return { registerThread, unregisterThread, handle, invalidateTurn, dispose }\n}\n","import type { CodexQuestion, CodexRequestId, CodexReviewSubject, FileChange, RequestIdentity } from './types'\n\nexport const COMMAND = 'item/commandExecution/requestApproval'\nexport const FILES = 'item/fileChange/requestApproval'\nexport const QUESTIONS = 'item/tool/requestUserInput'\nexport const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value)\nexport const isId = (value: unknown): value is CodexRequestId => typeof value === 'string' || (typeof value === 'number' && Number.isSafeInteger(value))\nexport const isText = (value: unknown): value is string => typeof value === 'string' && value.length > 0\nconst optionalText = (value: unknown): boolean => value === undefined || value === null || typeof value === 'string'\nexport const onlyKeys = (value: Record<string, unknown>, keys: readonly string[]): boolean => Object.keys(value).every(key => keys.includes(key))\nexport const identityOf = (id: CodexRequestId, method: string, params: Record<string, unknown>): RequestIdentity | null => {\n if (!isText(params.threadId) || !isText(params.turnId) || !isText(params.itemId) || !optionalText(params.approvalId)) return null\n return { id, method, threadId: params.threadId, turnId: params.turnId, itemId: params.itemId, approvalId: typeof params.approvalId === 'string' ? params.approvalId : null }\n}\nexport const certifiedThread = (value: unknown): string | null => {\n if (!isRecord(value) || !isRecord(value.thread) || !isText(value.thread.id) || !isRecord(value.thread.status) || value.thread.status.type !== 'idle') return null\n if ((value.approvalPolicy !== 'untrusted' && value.approvalPolicy !== 'on-request') || value.approvalsReviewer !== 'user' || !isRecord(value.sandbox)) return null\n const sandbox = value.sandbox\n if (sandbox.type !== 'readOnly' && sandbox.type !== 'workspaceWrite') return null\n if (!onlyKeys(sandbox, ['type', 'networkAccess', 'writableRoots', 'excludeSlashTmp', 'excludeTmpdirEnvVar'])) return null\n if (sandbox.networkAccess !== undefined && typeof sandbox.networkAccess !== 'boolean') return null\n if (sandbox.writableRoots !== undefined && (!Array.isArray(sandbox.writableRoots) || !sandbox.writableRoots.every(isText))) return null\n if (['excludeSlashTmp', 'excludeTmpdirEnvVar'].some(key => sandbox[key] !== undefined && typeof sandbox[key] !== 'boolean')) return null\n if (value.activePermissionProfile !== undefined && value.activePermissionProfile !== null) return null\n return value.thread.id\n}\nexport const fileChangesOf = (value: unknown): readonly FileChange[] | null => {\n if (!Array.isArray(value) || value.length === 0 || value.length > 128) return null\n const changes: FileChange[] = []\n for (const change of value) {\n if (!isRecord(change) || !onlyKeys(change, ['path', 'kind', 'diff']) || !isText(change.path) || typeof change.diff !== 'string' || !isRecord(change.kind)) return null\n const kind = change.kind\n if (!onlyKeys(kind, ['type', 'move_path']) || (kind.type !== 'add' && kind.type !== 'delete' && kind.type !== 'update')) return null\n if (!optionalText(kind.move_path) || (kind.type !== 'update' && kind.move_path != null)) return null\n changes.push({ path: change.path, operation: kind.type, movePath: typeof kind.move_path === 'string' ? kind.move_path : null, diff: change.diff })\n }\n return changes\n}\ntype SubjectResult = { readonly kind: 'supported'; readonly subject: CodexReviewSubject } | { readonly kind: 'unsupported'; readonly reason: string } | { readonly kind: 'malformed'; readonly reason: string }\nconst unsupported = (reason: string): SubjectResult => ({ kind: 'unsupported', reason })\nconst malformed = (reason: string): SubjectResult => ({ kind: 'malformed', reason })\nconst isKnownCommandDecision = (value: unknown): boolean => {\n if (typeof value === 'string') return ['accept', 'acceptForSession', 'decline', 'cancel'].includes(value)\n if (!isRecord(value) || !onlyKeys(value, ['acceptWithExecpolicyAmendment'])) return false\n const amendment = value.acceptWithExecpolicyAmendment\n return isRecord(amendment) && onlyKeys(amendment, ['execpolicy_amendment']) && Array.isArray(amendment.execpolicy_amendment) && amendment.execpolicy_amendment.every(isText)\n}\nexport const subjectOf = (method: string, params: Record<string, unknown>, changes: readonly FileChange[] | null, experimental: boolean): SubjectResult => {\n if (method === COMMAND) {\n if (!onlyKeys(params, ['threadId', 'turnId', 'itemId', 'approvalId', 'startedAtMs', 'kind', 'environmentId', 'command', 'cwd', 'reason', 'commandActions', 'networkApprovalContext', 'proposedExecpolicyAmendment', 'proposedNetworkPolicyAmendments', 'availableDecisions'])) return unsupported('Unknown command permission fields')\n if ((params.kind !== undefined && params.kind !== 'command') || (params.environmentId != null && params.environmentId !== 'local') || params.networkApprovalContext != null || params.proposedNetworkPolicyAmendments != null) return unsupported('Command needs native permission review')\n if (params.proposedExecpolicyAmendment != null && (!Array.isArray(params.proposedExecpolicyAmendment) || !params.proposedExecpolicyAmendment.every(isText))) return malformed('Invalid policy suggestion')\n if (params.availableDecisions != null && (!Array.isArray(params.availableDecisions) || !params.availableDecisions.includes('accept') || !params.availableDecisions.every(isKnownCommandDecision))) return unsupported('Unknown available approval decisions')\n if (!isText(params.command) || !isText(params.cwd) || !optionalText(params.reason) || !Number.isSafeInteger(params.startedAtMs)) return malformed('Incomplete command subject')\n return { kind: 'supported', subject: { kind: 'command', command: params.command, cwd: params.cwd, reason: typeof params.reason === 'string' ? params.reason : null } }\n }\n if (method === FILES) {\n if (!onlyKeys(params, ['threadId', 'turnId', 'itemId', 'startedAtMs', 'reason', 'grantRoot']) || params.grantRoot != null) return unsupported('File request widens permissions')\n if (!optionalText(params.reason) || !Number.isSafeInteger(params.startedAtMs)) return malformed('Malformed file request')\n if (!changes) return unsupported('Complete file patch unavailable')\n return { kind: 'supported', subject: { kind: 'files', changes, reason: typeof params.reason === 'string' ? params.reason : null } }\n }\n if (!experimental) return unsupported('Experimental questions disabled')\n if (!onlyKeys(params, ['threadId', 'turnId', 'itemId', 'questions', 'isBlocking', 'autoResolutionMs']) || params.isBlocking !== true || params.autoResolutionMs != null) return unsupported('Question requires native handling')\n if (!Array.isArray(params.questions) || params.questions.length < 1 || params.questions.length > 3) return malformed('Question count outside supported range')\n const questions: CodexQuestion[] = []\n for (const question of params.questions) {\n if (!isRecord(question) || !onlyKeys(question, ['id', 'header', 'question', 'isOther', 'isSecret', 'options'])) return malformed('Malformed question')\n if (question.isOther !== false || question.isSecret !== false) return unsupported('Secret or other-option question')\n if (!isText(question.id) || !isText(question.header) || !isText(question.question) || questions.some(entry => entry.id === question.id)) return malformed('Invalid question identity')\n let options: CodexQuestion['options'] = null\n if (question.options !== null) {\n if (!Array.isArray(question.options) || question.options.length < 2 || question.options.length > 20) return malformed('Invalid options')\n const validated: { label: string; description: string }[] = []\n for (const option of question.options) {\n if (!isRecord(option) || !onlyKeys(option, ['label', 'description']) || !isText(option.label) || option.label.length > 200 || typeof option.description !== 'string' || validated.some(entry => entry.label === option.label)) return malformed('Invalid option')\n validated.push({ label: option.label, description: option.description })\n }\n options = validated\n }\n questions.push({ id: question.id, header: question.header, question: question.question, options })\n }\n return { kind: 'supported', subject: { kind: 'questions', questions } }\n}\n","import type { CodexReviewSubject } from './types'\nimport type { DecisionType } from '@pushary/server'\n\nexport interface PhoneQuestion {\n readonly question: string\n readonly context: string\n readonly type: DecisionType\n readonly options?: readonly string[]\n readonly questionId?: string\n}\nexport const visibleText = (text: string): string => text.replace(/\\\\/g, '\\\\\\\\').replace(/[\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}]/gu, character => `\\\\u{${character.codePointAt(0)?.toString(16)}}`)\nconst bounded = (questions: readonly PhoneQuestion[]): readonly PhoneQuestion[] | null => questions.every(question => question.question.length <= 8000 && question.context.length <= 2000 && question.options?.some(option => option.length > 200) !== true) ? questions : null\nexport const presentSubject = (subject: CodexReviewSubject): readonly PhoneQuestion[] | null => {\n if (subject.kind === 'command') return bounded([{ type: 'confirm', question: `Approve this command once?\\n\\n${visibleText(subject.command)}\\n\\nWorking directory: ${visibleText(subject.cwd)}\\nReason: ${visibleText(subject.reason ?? '(none)')}`, context: 'Codex command approval. This approval applies only to this request.' }])\n if (subject.kind === 'files') {\n const patches = subject.changes.map(change => `${change.operation}: ${visibleText(change.path)}${change.movePath === null ? '' : ` -> ${visibleText(change.movePath)}`}\\n${visibleText(change.diff)}`).join('\\n\\n')\n return bounded([{ type: 'confirm', question: `Approve these exact file changes once?\\n\\n${patches}\\n\\nReason: ${visibleText(subject.reason ?? '(none)')}`, context: 'Codex file approval. Includes every file and the complete patch.' }])\n }\n return bounded(subject.questions.map(question => ({ questionId: question.id, type: question.options ? 'select' : 'input', question: `${visibleText(question.header)}\\n${visibleText(question.question)}${question.options ? '\\n\\n' + question.options.map(option => `${visibleText(option.label)}: ${visibleText(option.description)}`).join('\\n') : ''}`, options: question.options?.map(option => visibleText(option.label)), context: 'Answer this Codex question. This answer does not grant tool permissions.' })))\n}\n","import { PusharyApiError, type DecisionType } from '@pushary/server'\nimport { isRecord, isText } from './protocol'\n\nexport interface DecisionSnapshot {\n readonly decisionId: string\n readonly status: 'pending' | 'answered' | 'expired' | 'cancelled' | 'stopped'\n readonly answered: boolean\n readonly value: string | null\n readonly type: DecisionType\n}\nexport const decisionSnapshot = (value: unknown, type: DecisionType, expectedId?: string): DecisionSnapshot => {\n if (!isRecord(value) || !isText(value.decisionId) || (expectedId !== undefined && value.decisionId !== expectedId) || value.type !== type || typeof value.answered !== 'boolean') throw new Error('Invalid decision response')\n const status = value.status\n if (status !== 'pending' && status !== 'answered' && status !== 'expired' && status !== 'cancelled' && status !== 'stopped') throw new Error('Unknown decision status')\n if ((status === 'answered') !== value.answered || (status === 'answered' && typeof value.value !== 'string') || (status !== 'answered' && value.value != null)) throw new Error('Inconsistent decision response')\n return { decisionId: value.decisionId, status, answered: value.answered, value: typeof value.value === 'string' ? value.value : null, type }\n}\nexport const isRetryable = (error: unknown): boolean => error instanceof PusharyApiError ? error.status === 429 || error.status >= 500 : error instanceof TypeError || (error instanceof Error && error.name === 'TimeoutError')\nexport const delay = (milliseconds: number, signal: AbortSignal): Promise<void> => new Promise((resolve, reject) => {\n if (signal.aborted) { reject(signal.reason); return }\n const onAbort = (): void => { clearTimeout(timer); reject(signal.reason) }\n const timer = setTimeout(() => { signal.removeEventListener('abort', onAbort); resolve() }, milliseconds)\n signal.addEventListener('abort', onAbort, { once: true })\n})\nexport const withRetry = async <T>(operation: () => Promise<T>, signal: AbortSignal): Promise<T> => {\n for (let attempt = 0; ; attempt += 1) {\n signal.throwIfAborted()\n try { return await operation() } catch (error) {\n if (signal.aborted || attempt >= 3 || !isRetryable(error)) throw error\n await delay(250 * 2 ** attempt + Math.floor(Math.random() * 101), signal)\n }\n }\n}\n\nexport const decisionFailureReason = (error: unknown): string => {\n if (error instanceof PusharyApiError) return `Partner HTTP ${error.status}`\n if (error instanceof TypeError) return 'Decision transport unavailable'\n if (error instanceof Error && error.name === 'TimeoutError') return 'Decision HTTP deadline elapsed'\n return 'Decision response invalid or unavailable'\n}\n","import type { CodexReply, CodexRequestId } from './types'\n\nexport type RequestState = 'pending' | 'accepted' | 'closed'\nexport type RequestCompletion =\n | { readonly kind: 'reply'; readonly reply: CodexReply }\n | { readonly kind: 'refuse' | 'conflict' | 'abandon'; readonly reason: string }\n | { readonly kind: 'native' }\n\ninterface RequestContext {\n readonly id: CodexRequestId\n readonly isQuestion: boolean\n readonly replyAllowed: boolean\n readonly deadlineElapsed: boolean\n}\ninterface RequestTransition {\n readonly state: Exclude<RequestState, 'pending'>\n readonly reply: CodexReply | null\n readonly interruption: string | null\n readonly abandonment: string | null\n}\n\nexport const transitionRequest = (state: RequestState, completion: RequestCompletion, context: RequestContext): RequestTransition | null => {\n if (state !== 'pending') return null\n if (completion.kind === 'reply') {\n if (!context.replyAllowed || context.deadlineElapsed) return null\n const reply = completion.reply\n const accepted = 'result' in reply && 'decision' in reply.result && reply.result.decision === 'accept'\n return { state: accepted ? 'accepted' : 'closed', reply, interruption: null, abandonment: null }\n }\n if (completion.kind === 'native') return { state: 'closed', reply: null, interruption: null, abandonment: null }\n if (completion.kind === 'abandon' || !context.replyAllowed) return { state: 'closed', reply: null, interruption: null, abandonment: completion.reason }\n const reply: CodexReply = context.isQuestion\n ? { id: context.id, error: { code: -32000, message: completion.reason } }\n : { id: context.id, result: { decision: 'cancel' } }\n return { state: 'closed', reply, interruption: context.isQuestion || completion.kind === 'conflict' ? completion.reason : null, abandonment: completion.reason }\n}\n"],"mappings":"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","names":["reply","request"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/handler.ts","../src/protocol.ts","../src/presentation.ts","../src/partner-decisions.ts","../src/request-lifecycle.ts"],"sourcesContent":["import { createAdapterKernel } from '@pushary/server/adapters'\nexport { createPusharyCodexHandler } from './handler'\nexport { CERTIFIED_CODEX_VERSIONS, type CertifiedCodexVersion } from './protocol'\nexport type { CodexRequestId, CodexReply, CodexDispatchResult, CodexReviewSubject, PusharyCodexConfig, PusharyCodexEvent, PusharyCodexHandler } from './types'\nexport const connect = createAdapterKernel('Codex app-server').connect\n","import { randomUUID } from 'node:crypto'\nimport { createPusharyServer, isApproved, type CreateDecision } from '@pushary/server'\nimport { decisionFingerprint } from '@pushary/server/adapters'\nimport { COMMAND, FILES, QUESTIONS, certifiedThread, isCertifiedCodexVersion, fileChangesOf, identityOf, isId, isRecord, isText, subjectOf } from './protocol'\nimport { presentSubject, type PhoneQuestion } from './presentation'\nimport { decisionFailureReason, decisionSnapshot, delay, isRetryable, withRetry, type DecisionSnapshot } from './partner-decisions'\nimport { transitionRequest, type RequestCompletion, type RequestState } from './request-lifecycle'\nimport type { CodexDispatchResult, CodexReviewSubject, FileChange, PusharyCodexConfig, PusharyCodexEvent, PusharyCodexHandler, RequestIdentity } from './types'\n\nconst MAX_PENDING = 8\nconst MAX_THREADS = 32\nconst MAX_ITEMS = 128\nconst MAX_CACHE_BYTES = 4 * 1024 * 1024\nconst MAX_REQUESTS = 4096\nconst CLEANUP_MS = 5000\nconst MIN_QUESTION_BUDGET_MS = 10_000\ninterface OwnedRequest {\n readonly identity: RequestIdentity\n readonly declineDecision: 'decline' | 'cancel'\n readonly digest: string\n readonly envelopeDigest: string\n readonly subject: CodexReviewSubject\n readonly controller: AbortController\n readonly deadline: number\n readonly timer: ReturnType<typeof setTimeout>\n readonly decisionIds: Set<string>\n readonly cleanupIds: Set<string>\n state: RequestState\n cleanupDeadline: number\n}\ninterface CachedPatch { readonly changes: readonly FileChange[] | null; readonly digest: string; readonly bytes: number }\nconst itemKey = (threadId: string, turnId: string, itemId: string): string => JSON.stringify([threadId, turnId, itemId])\nconst turnKey = (threadId: string, turnId: string): string => JSON.stringify([threadId, turnId])\nconst rpcKey = (id: string | number): string => JSON.stringify([typeof id, id])\n\nexport const createPusharyCodexHandler = (configuration: PusharyCodexConfig): PusharyCodexHandler => {\n const config = Object.freeze({ ...configuration })\n const timeoutMs = config.timeoutMs ?? 300_000\n if (!isCertifiedCodexVersion(config.codexVersion) || !Number.isInteger(timeoutMs) || timeoutMs < 60_000 || timeoutMs > 600_000 || !config.tenantId?.trim() || !config.externalId?.trim()) throw new TypeError('Invalid Codex adapter configuration')\n if ([config.sendResponse, config.requestTurnInterrupt, config.onEvent, config.maySendSubject].some(callback => typeof callback !== 'function')) throw new TypeError('All host callbacks are required')\n const decisions = createPusharyServer({ apiKey: config.apiKey, baseUrl: config.baseUrl, requestTimeoutMs: 10_000 }).decisions\n const generation = randomUUID()\n const threads = new Set<string>()\n const requests = new Map<string, OwnedRequest>()\n const closedRequestIds = new Set<string>()\n const turns = new Map<string, { readonly threadId: string; readonly turnId: string; terminal: boolean }>()\n const completedItems = new Set<string>()\n const patches = new Map<string, CachedPatch>()\n const jobs = new Set<Promise<void>>()\n const cleanupFailures: string[] = []\n const cleanupControllers = new Set<AbortController>()\n let cacheBytes = 0\n let disposed = false\n let disposal: Promise<{ readonly cleanupFailures: readonly string[] }> | undefined\n let disposalDeadline = Infinity\n const emit = (event: PusharyCodexEvent): void => {\n try { config.onEvent(event) } catch { console.error('Pushary Codex onEvent callback failed') }\n }\n const eventFor = (request: OwnedRequest, type: PusharyCodexEvent['type'], reason?: string, decisionId?: string): void => emit({ type, requestId: request.identity.id, threadId: request.identity.threadId, turnId: request.identity.turnId, subjectDigest: request.digest, decisionId, reason })\n const track = (job: Promise<void>): void => { jobs.add(job); void job.finally(() => jobs.delete(job)).catch(() => undefined) }\n const cleanupFailed = (request: OwnedRequest, id: string): void => {\n cleanupFailures.push(id)\n eventFor(request, 'cleanup_failed', 'Decision cleanup not confirmed before deadline', id)\n }\n const cleanup = async (request: OwnedRequest, id: string): Promise<void> => {\n if (request.cleanupIds.has(id)) return\n request.cleanupIds.add(id)\n const remaining = Math.min(request.cleanupDeadline, disposalDeadline) - performance.now()\n if (remaining <= 0) { cleanupFailed(request, id); return }\n const controller = new AbortController()\n cleanupControllers.add(controller)\n const timer = setTimeout(() => controller.abort(), remaining)\n try {\n for (let attempt = 0; attempt < 3; attempt += 1) {\n try {\n const result: unknown = await decisions.cancel(id, { signal: controller.signal })\n if (!isRecord(result) || result.decisionId !== id || typeof result.cancelled !== 'boolean') throw new Error('Invalid cancellation result')\n if (result.cancelled) return\n const latest: unknown = await decisions.get(id, { signal: controller.signal })\n if (isRecord(latest) && (latest.type === 'confirm' || latest.type === 'select' || latest.type === 'input')) {\n const snapshot = decisionSnapshot(latest, latest.type, id)\n if (snapshot.status !== 'pending') return\n }\n throw new TypeError('Cancellation still pending')\n } catch (error) {\n if (controller.signal.aborted || attempt === 2 || !isRetryable(error)) throw error\n await delay(attempt === 0 ? 100 : 300, controller.signal)\n }\n }\n } catch { cleanupFailed(request, id) } finally { clearTimeout(timer); cleanupControllers.delete(controller) }\n }\n const beginCleanup = (request: OwnedRequest): void => {\n clearTimeout(request.timer)\n request.cleanupDeadline = Math.min(performance.now() + CLEANUP_MS, disposalDeadline)\n request.controller.abort()\n for (const id of request.decisionIds) track(cleanup(request, id))\n }\n const completeRequest = (request: OwnedRequest, completion: RequestCompletion): void => {\n const transition = transitionRequest(request.state, completion, {\n id: request.identity.id,\n isQuestion: request.subject.kind === 'questions',\n replyAllowed: contextLive(request),\n deadlineElapsed: performance.now() >= request.deadline,\n })\n if (!transition) return\n request.state = transition.state\n beginCleanup(request)\n if (transition.reply && contextLive(request)) {\n const interrupted = transition.interruption === null || interrupt(request.identity, transition.interruption)\n if (interrupted && contextLive(request)) {\n try { config.sendResponse(transition.reply) } catch { fatal('Response enqueue failed; close connection') }\n }\n }\n if (transition.abandonment !== null) eventFor(request, 'request_abandoned', transition.abandonment)\n }\n const dispose = (): Promise<{ readonly cleanupFailures: readonly string[] }> => {\n if (disposal) return disposal\n disposed = true\n disposalDeadline = performance.now() + CLEANUP_MS\n config.signal?.removeEventListener('abort', onAbort)\n let resolveDisposal: (value: { readonly cleanupFailures: readonly string[] }) => void = () => undefined\n disposal = new Promise(resolve => { resolveDisposal = resolve })\n threads.clear()\n patches.clear()\n cacheBytes = 0\n for (const request of requests.values()) completeRequest(request, { kind: 'abandon', reason: 'Connection disposed' })\n const finish = async (): Promise<void> => {\n const controller = new AbortController()\n const drain = async (): Promise<void> => { while (jobs.size > 0 && performance.now() < disposalDeadline) await Promise.allSettled([...jobs]) }\n await Promise.race([drain(), delay(CLEANUP_MS, controller.signal)]).catch(() => undefined)\n controller.abort()\n for (const cleanupController of cleanupControllers) cleanupController.abort()\n await Promise.resolve()\n resolveDisposal({ cleanupFailures: [...cleanupFailures] })\n }\n void finish()\n return disposal\n }\n const fatal = (reason: string): void => {\n void dispose()\n emit({ type: 'reply_failed', reason })\n }\n const overflow = (): void => { void dispose(); emit({ type: 'capacity_exceeded', reason: 'Connection must close; bounded adapter capacity exceeded' }) }\n const stateCount = (): number => requests.size + closedRequestIds.size + turns.size + completedItems.size\n const rememberTurn = (threadId: string, turnId: string, terminal: boolean): boolean => {\n const key = turnKey(threadId, turnId)\n const previous = turns.get(key)\n if (previous) { previous.terminal ||= terminal; return true }\n if (stateCount() >= MAX_REQUESTS) { overflow(); return false }\n turns.set(key, { threadId, turnId, terminal })\n return true\n }\n const contextEnded = (identity: RequestIdentity): boolean => turns.get(turnKey(identity.threadId, identity.turnId))?.terminal === true || completedItems.has(itemKey(identity.threadId, identity.turnId, identity.itemId))\n const contextLive = (request: OwnedRequest): boolean => !disposed && !contextEnded(request.identity) && threads.has(request.identity.threadId)\n const live = (request: OwnedRequest): boolean => request.state === 'pending' && contextLive(request) && performance.now() < request.deadline\n const interrupt = (identity: RequestIdentity, reason: string): boolean => {\n try { config.requestTurnInterrupt(identity.threadId, identity.turnId, reason); return !disposed } catch { fatal('Turn interrupt enqueue failed; close connection'); return false }\n }\n const fenceTurn = (threadId: string, turnId: string, reason: string): void => {\n if (!rememberTurn(threadId, turnId, true)) return\n for (const request of requests.values()) if (request.identity.threadId === threadId && request.identity.turnId === turnId) completeRequest(request, { kind: 'abandon', reason })\n for (const key of patches.keys()) {\n if (key.startsWith(JSON.stringify([threadId, turnId]).slice(0, -1) + ',')) { cacheBytes -= patches.get(key)?.bytes ?? 0; patches.delete(key) }\n }\n }\n const invalidateTurn = (threadId: string, turnId: string, reason: string): void => {\n const accepted = [...requests.values()].find(request => request.identity.threadId === threadId && request.identity.turnId === turnId && request.state === 'accepted' && !contextEnded(request.identity))\n fenceTurn(threadId, turnId, reason)\n if (accepted) {\n if (!disposed) interrupt(accepted.identity, reason)\n eventFor(accepted, 'request_abandoned', 'Invalidated after acceptance enqueue; execution outcome unknown')\n }\n }\n const unregisterThread = (threadId: string): void => {\n threads.delete(threadId)\n for (const turn of turns.values()) if (turn.threadId === threadId) invalidateTurn(threadId, turn.turnId, 'Thread unregistered')\n for (const key of patches.keys()) if (key.startsWith(JSON.stringify([threadId]).slice(0, -1) + ',')) { cacheBytes -= patches.get(key)?.bytes ?? 0; patches.delete(key) }\n }\n const createAndWait = async (request: OwnedRequest, phone: PhoneQuestion, ordinal: number): Promise<DecisionSnapshot> => {\n const payload: CreateDecision = { question: phone.question, type: phone.type, options: phone.options, context: phone.context, externalId: config.externalId, agentName: config.agentName ?? 'Codex', wait: false, requireReachable: true, expiresInSeconds: Math.ceil(timeoutMs / 1000), idempotencyKey: decisionFingerprint({ tenantId: config.tenantId, externalId: config.externalId, generation, ...request.identity, subjectDigest: request.digest, ordinal, questionId: phone.questionId ?? null }) }\n let raw: unknown\n try { raw = await withRetry(() => decisions.create(payload, { signal: request.controller.signal }), request.controller.signal) } catch (error) {\n if (request.controller.signal.aborted || isRetryable(error)) eventFor(request, 'create_outcome_unknown', 'Create may have reached server; TTL bounds residual prompt')\n throw error\n }\n if (isRecord(raw) && isText(raw.decisionId)) {\n request.decisionIds.add(raw.decisionId)\n if (!live(request)) { track(cleanup(request, raw.decisionId)); throw new Error('Request no longer live') }\n }\n if (!isRecord(raw) || !isText(raw.decisionId)) eventFor(request, 'create_outcome_unknown', 'Create returned no usable decision ID')\n let snapshot = decisionSnapshot(raw, phone.type)\n eventFor(request, 'decision_created', undefined, snapshot.decisionId)\n while (snapshot.status === 'pending') {\n if (!live(request)) throw new Error('Request no longer live')\n const next: unknown = await withRetry(() => decisions.get(snapshot.decisionId, { wait: 5, signal: request.controller.signal }), request.controller.signal)\n snapshot = decisionSnapshot(next, phone.type, snapshot.decisionId)\n if (snapshot.status === 'pending') await delay(50, request.controller.signal)\n }\n request.decisionIds.delete(snapshot.decisionId)\n eventFor(request, 'decision_settled', snapshot.status, snapshot.decisionId)\n return snapshot\n }\n const runRequest = async (request: OwnedRequest, phones: readonly PhoneQuestion[]): Promise<void> => {\n try {\n const answers: Record<string, { answers: readonly string[] }> = Object.create(null)\n for (const [ordinal, phone] of phones.entries()) {\n if (!live(request)) return\n if (ordinal > 0 && request.deadline - performance.now() < MIN_QUESTION_BUDGET_MS) { completeRequest(request, { kind: 'refuse', reason: 'Insufficient time for another question' }); return }\n const result = await createAndWait(request, phone, ordinal)\n if (!live(request)) return\n if (request.subject.kind !== 'questions') {\n const approved = result.type === 'confirm' && result.status === 'answered' && isApproved({ status: result.status, type: result.type, value: result.value })\n completeRequest(request, { kind: 'reply', reply: { id: request.identity.id, result: { decision: approved ? 'accept' : request.declineDecision } } })\n return\n }\n if (!result.answered || !result.value?.trim() || result.value.length > 2000 || (phone.options && !phone.options.includes(result.value))) { completeRequest(request, { kind: 'refuse', reason: 'Question did not receive a valid answer' }); return }\n const question = request.subject.questions[ordinal]\n if (!question || !phone.questionId) throw new Error('Question identity missing')\n const selectedIndex = phone.options?.indexOf(result.value)\n const answer = selectedIndex !== undefined ? question.options?.[selectedIndex]?.label : result.value\n if (answer === undefined) throw new Error('Question option missing')\n answers[phone.questionId] = { answers: [answer] }\n }\n completeRequest(request, { kind: 'reply', reply: { id: request.identity.id, result: { answers } } })\n } catch (error) { if (live(request)) completeRequest(request, { kind: 'refuse', reason: decisionFailureReason(error) }) }\n }\n const observe = (method: string, params: Record<string, unknown>): CodexDispatchResult => {\n if (method === 'serverRequest/resolved' && isId(params.requestId)) {\n const request = requests.get(rpcKey(params.requestId))\n if (request && params.threadId === request.identity.threadId) completeRequest(request, { kind: 'abandon', reason: 'Server request resolved' })\n }\n if (isText(params.threadId)) {\n if (threads.has(params.threadId) && isRecord(params.turn) && isText(params.turn.id) && method === 'turn/started') rememberTurn(params.threadId, params.turn.id, false)\n if (['thread/closed', 'thread/archived', 'thread/settings/updated'].includes(method)) unregisterThread(params.threadId)\n if (isText(params.turnId) && ['turn/completed', 'turn/interrupted', 'turn/failed'].includes(method)) fenceTurn(params.threadId, params.turnId, method)\n if (isRecord(params.turn) && isText(params.turn.id) && method === 'turn/completed') fenceTurn(params.threadId, params.turn.id, method)\n const itemId = isRecord(params.item) && isText(params.item.id) ? params.item.id : params.itemId\n if (isText(params.turnId) && isText(itemId)) {\n const key = itemKey(params.threadId, params.turnId, itemId)\n if (method === 'item/completed') {\n if (!completedItems.has(key) && stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Terminal item capacity exceeded' } }\n completedItems.add(key)\n for (const request of requests.values()) if (itemKey(request.identity.threadId, request.identity.turnId, request.identity.itemId) === key) completeRequest(request, { kind: 'abandon', reason: 'Item completed' })\n cacheBytes -= patches.get(key)?.bytes ?? 0\n patches.delete(key)\n }\n if (threads.has(params.threadId) && !completedItems.has(key) && turns.get(turnKey(params.threadId, params.turnId))?.terminal !== true && (method === 'item/fileChange/patchUpdated' || (method === 'item/started' && isRecord(params.item) && params.item.type === 'fileChange'))) {\n if (!rememberTurn(params.threadId, params.turnId, false)) return { kind: 'invalid', reason: 'Turn capacity exceeded' }\n const raw = method === 'item/started' && isRecord(params.item) ? params.item.changes : params.changes\n const previous = patches.get(key)\n const parsed = fileChangesOf(raw)\n const digest = decisionFingerprint(parsed)\n const conflict = previous !== undefined && previous.digest !== digest\n const changes = (method === 'item/fileChange/patchUpdated' && !previous) || (method === 'item/started' && conflict) || previous?.changes === null ? null : parsed\n const bytes = Buffer.byteLength(JSON.stringify(changes))\n if ((!previous && patches.size >= MAX_ITEMS) || cacheBytes - (previous?.bytes ?? 0) + bytes > MAX_CACHE_BYTES) { overflow(); return { kind: 'invalid', reason: 'Patch capacity exceeded' } }\n patches.set(key, { changes, digest, bytes })\n cacheBytes += bytes - (previous?.bytes ?? 0)\n if (conflict || changes === null) for (const request of requests.values()) if (itemKey(request.identity.threadId, request.identity.turnId, request.identity.itemId) === key) {\n if (request.state === 'accepted' && !contextEnded(request.identity)) invalidateTurn(request.identity.threadId, request.identity.turnId, 'Reviewed patch changed after acceptance')\n else completeRequest(request, { kind: 'refuse', reason: 'Reviewed patch changed' })\n }\n }\n }\n }\n return { kind: 'observed' }\n }\n const delegateToNative = (id: string | number, reason: string): CodexDispatchResult => {\n if (stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n closedRequestIds.add(rpcKey(id))\n emit({ type: 'native_review_required', requestId: id, reason })\n return disposed ? { kind: 'invalid', reason: 'Disposed during native handoff' } : { kind: 'unhandled', reason }\n }\n const dispatch = (message: unknown): CodexDispatchResult => {\n if (disposed) return { kind: 'invalid', reason: 'Adapter disposed' }\n if (!isRecord(message) || !isText(message.method) || !isRecord(message.params)) return { kind: 'invalid', reason: 'Invalid server envelope' }\n if (message.id === undefined) return observe(message.method, message.params)\n if (!isId(message.id)) return { kind: 'invalid', reason: 'Invalid RPC ID' }\n if (closedRequestIds.has(rpcKey(message.id))) return { kind: 'claimed' }\n const previous = requests.get(rpcKey(message.id))\n if (previous) {\n if (previous.envelopeDigest !== decisionFingerprint({ method: message.method, params: message.params })) {\n if (previous.state === 'accepted') invalidateTurn(previous.identity.threadId, previous.identity.turnId, 'Conflicting duplicate request')\n else completeRequest(previous, { kind: 'conflict', reason: 'Conflicting duplicate request' })\n }\n return { kind: 'claimed' }\n }\n if (![COMMAND, FILES, QUESTIONS].includes(message.method)) return delegateToNative(message.id, 'Unsupported server method')\n const identity = identityOf(message.id, message.method, message.params)\n if (!identity) return { kind: 'invalid', reason: 'Malformed request identity; close connection' }\n if (contextEnded(identity)) {\n if (stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n closedRequestIds.add(rpcKey(identity.id))\n if (identity.method === QUESTIONS && !interrupt(identity, 'Request context has ended')) return { kind: 'invalid', reason: 'Interrupt failed' }\n if (!disposed) config.sendResponse(identity.method === QUESTIONS ? { id: identity.id, error: { code: -32000, message: 'Request context has ended' } } : { id: identity.id, result: { decision: 'cancel' } })\n return { kind: 'claimed' }\n }\n if (!threads.has(identity.threadId)) return delegateToNative(message.id, 'Unregistered request context')\n if (!rememberTurn(identity.threadId, identity.turnId, false)) return { kind: 'invalid', reason: 'Turn capacity exceeded' }\n const subject = subjectOf(message.method, message.params, patches.get(itemKey(identity.threadId, identity.turnId, identity.itemId))?.changes ?? null, config.experimentalQuestions === true)\n if (subject.kind === 'malformed') {\n if (stateCount() >= MAX_REQUESTS) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n closedRequestIds.add(rpcKey(message.id))\n if (message.method === QUESTIONS && !interrupt(identity, subject.reason)) return { kind: 'invalid', reason: 'Interrupt failed' }\n try { config.sendResponse({ id: message.id, error: { code: -32602, message: subject.reason } }) } catch { fatal('Invalid-params response enqueue failed') }\n return { kind: 'claimed' }\n }\n if (subject.kind === 'unsupported') return delegateToNative(message.id, subject.reason)\n const digest = decisionFingerprint(subject.subject)\n const phones = presentSubject(subject.subject)\n if (!phones) return delegateToNative(message.id, 'Subject exceeds presentation limits')\n if (stateCount() >= MAX_REQUESTS || [...requests.values()].filter(request => request.state === 'pending').length >= MAX_PENDING) { overflow(); return { kind: 'invalid', reason: 'Request capacity exceeded' } }\n const controller = new AbortController()\n const timer = setTimeout(() => { const request = requests.get(rpcKey(identity.id)); if (request) completeRequest(request, { kind: 'refuse', reason: 'Decision deadline elapsed' }) }, timeoutMs)\n const request: OwnedRequest = { identity, declineDecision: Array.isArray(message.params.availableDecisions) && !message.params.availableDecisions.includes('decline') ? 'cancel' : 'decline', digest, envelopeDigest: decisionFingerprint({ method: message.method, params: message.params }), subject: subject.subject, controller, deadline: performance.now() + timeoutMs, timer, decisionIds: new Set(), cleanupIds: new Set(), state: 'pending', cleanupDeadline: Infinity }\n requests.set(rpcKey(identity.id), request)\n let allowed = false\n try { allowed = config.maySendSubject(structuredClone(subject.subject)) === true } catch { allowed = false }\n if (disposed) return { kind: 'invalid', reason: 'Disposed during privacy review' }\n if (!live(request)) return { kind: 'claimed' }\n if (!allowed) {\n completeRequest(request, { kind: 'native' })\n requests.delete(rpcKey(identity.id))\n return delegateToNative(message.id, 'Subject rejected by privacy policy')\n }\n track(runRequest(request, phones))\n return { kind: 'claimed' }\n }\n const handle = (message: unknown): CodexDispatchResult => {\n try { return dispatch(message) } catch {\n fatal('Invalid message or host callback; close connection')\n return { kind: 'invalid', reason: 'Message could not be validated' }\n }\n }\n const registerThread = (value: unknown): void => {\n if (disposed) throw new Error('Adapter disposed')\n const id = certifiedThread(value)\n if (!id) throw new TypeError('Thread requires user approvals and a certified sandbox')\n if ([...requests.values()].some(request => request.state === 'pending' && request.identity.threadId === id)) throw new Error('Cannot replace thread policy while approval is pending')\n if (!threads.has(id) && threads.size >= MAX_THREADS) { overflow(); throw new Error('Thread capacity exceeded') }\n threads.add(id)\n }\n function onAbort(): void { void dispose() }\n config.signal?.addEventListener('abort', onAbort, { once: true })\n if (config.signal?.aborted) void dispose()\n return { registerThread, unregisterThread, handle, invalidateTurn, dispose }\n}\n","import type { CodexQuestion, CodexRequestId, CodexReviewSubject, FileChange, RequestIdentity } from './types'\n\nexport const COMMAND = 'item/commandExecution/requestApproval'\nexport const FILES = 'item/fileChange/requestApproval'\nexport const QUESTIONS = 'item/tool/requestUserInput'\nexport const CERTIFIED_CODEX_VERSIONS = ['0.160.1', '0.167.0'] as const\nexport type CertifiedCodexVersion = (typeof CERTIFIED_CODEX_VERSIONS)[number]\nexport const isCertifiedCodexVersion = (value: unknown): value is CertifiedCodexVersion => CERTIFIED_CODEX_VERSIONS.some(version => version === value)\nexport const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value)\nexport const isId = (value: unknown): value is CodexRequestId => typeof value === 'string' || (typeof value === 'number' && Number.isSafeInteger(value))\nexport const isText = (value: unknown): value is string => typeof value === 'string' && value.length > 0\nconst optionalText = (value: unknown): boolean => value === undefined || value === null || typeof value === 'string'\nexport const onlyKeys = (value: Record<string, unknown>, keys: readonly string[]): boolean => Object.keys(value).every(key => keys.includes(key))\nexport const identityOf = (id: CodexRequestId, method: string, params: Record<string, unknown>): RequestIdentity | null => {\n if (!isText(params.threadId) || !isText(params.turnId) || !isText(params.itemId) || !optionalText(params.approvalId)) return null\n return { id, method, threadId: params.threadId, turnId: params.turnId, itemId: params.itemId, approvalId: typeof params.approvalId === 'string' ? params.approvalId : null }\n}\nexport const certifiedThread = (value: unknown): string | null => {\n if (!isRecord(value) || !isRecord(value.thread) || !isText(value.thread.id) || !isRecord(value.thread.status) || value.thread.status.type !== 'idle') return null\n if ((value.approvalPolicy !== 'untrusted' && value.approvalPolicy !== 'on-request') || value.approvalsReviewer !== 'user' || !isRecord(value.sandbox)) return null\n const sandbox = value.sandbox\n if (sandbox.type !== 'readOnly' && sandbox.type !== 'workspaceWrite') return null\n if (!onlyKeys(sandbox, ['type', 'networkAccess', 'writableRoots', 'excludeSlashTmp', 'excludeTmpdirEnvVar'])) return null\n if (sandbox.networkAccess !== undefined && typeof sandbox.networkAccess !== 'boolean') return null\n if (sandbox.writableRoots !== undefined && (!Array.isArray(sandbox.writableRoots) || !sandbox.writableRoots.every(isText))) return null\n if (['excludeSlashTmp', 'excludeTmpdirEnvVar'].some(key => sandbox[key] !== undefined && typeof sandbox[key] !== 'boolean')) return null\n if (value.activePermissionProfile !== undefined && value.activePermissionProfile !== null) return null\n return value.thread.id\n}\nexport const fileChangesOf = (value: unknown): readonly FileChange[] | null => {\n if (!Array.isArray(value) || value.length === 0 || value.length > 128) return null\n const changes: FileChange[] = []\n for (const change of value) {\n if (!isRecord(change) || !onlyKeys(change, ['path', 'kind', 'diff']) || !isText(change.path) || typeof change.diff !== 'string' || !isRecord(change.kind)) return null\n const kind = change.kind\n if (!onlyKeys(kind, ['type', 'move_path']) || (kind.type !== 'add' && kind.type !== 'delete' && kind.type !== 'update')) return null\n if (!optionalText(kind.move_path) || (kind.type !== 'update' && kind.move_path != null)) return null\n changes.push({ path: change.path, operation: kind.type, movePath: typeof kind.move_path === 'string' ? kind.move_path : null, diff: change.diff })\n }\n return changes\n}\ntype SubjectResult = { readonly kind: 'supported'; readonly subject: CodexReviewSubject } | { readonly kind: 'unsupported'; readonly reason: string } | { readonly kind: 'malformed'; readonly reason: string }\nconst unsupported = (reason: string): SubjectResult => ({ kind: 'unsupported', reason })\nconst malformed = (reason: string): SubjectResult => ({ kind: 'malformed', reason })\nconst isKnownCommandDecision = (value: unknown): boolean => {\n if (typeof value === 'string') return ['accept', 'acceptForSession', 'decline', 'cancel'].includes(value)\n if (!isRecord(value) || !onlyKeys(value, ['acceptWithExecpolicyAmendment'])) return false\n const amendment = value.acceptWithExecpolicyAmendment\n return isRecord(amendment) && onlyKeys(amendment, ['execpolicy_amendment']) && Array.isArray(amendment.execpolicy_amendment) && amendment.execpolicy_amendment.every(isText)\n}\nexport const subjectOf = (method: string, params: Record<string, unknown>, changes: readonly FileChange[] | null, experimental: boolean): SubjectResult => {\n if (method === COMMAND) {\n if (!onlyKeys(params, ['threadId', 'turnId', 'itemId', 'approvalId', 'startedAtMs', 'kind', 'environmentId', 'command', 'cwd', 'reason', 'commandActions', 'networkApprovalContext', 'proposedExecpolicyAmendment', 'proposedNetworkPolicyAmendments', 'availableDecisions'])) return unsupported('Unknown command permission fields')\n if ((params.kind !== undefined && params.kind !== 'command') || (params.environmentId != null && params.environmentId !== 'local') || params.networkApprovalContext != null || params.proposedNetworkPolicyAmendments != null) return unsupported('Command needs native permission review')\n if (params.proposedExecpolicyAmendment != null && (!Array.isArray(params.proposedExecpolicyAmendment) || !params.proposedExecpolicyAmendment.every(isText))) return malformed('Invalid policy suggestion')\n if (params.availableDecisions != null && (!Array.isArray(params.availableDecisions) || !params.availableDecisions.includes('accept') || !params.availableDecisions.every(isKnownCommandDecision))) return unsupported('Unknown available approval decisions')\n if (!isText(params.command) || !isText(params.cwd) || !optionalText(params.reason) || !Number.isSafeInteger(params.startedAtMs)) return malformed('Incomplete command subject')\n return { kind: 'supported', subject: { kind: 'command', command: params.command, cwd: params.cwd, reason: typeof params.reason === 'string' ? params.reason : null } }\n }\n if (method === FILES) {\n if (!onlyKeys(params, ['threadId', 'turnId', 'itemId', 'startedAtMs', 'reason', 'grantRoot']) || params.grantRoot != null) return unsupported('File request widens permissions')\n if (!optionalText(params.reason) || !Number.isSafeInteger(params.startedAtMs)) return malformed('Malformed file request')\n if (!changes) return unsupported('Complete file patch unavailable')\n return { kind: 'supported', subject: { kind: 'files', changes, reason: typeof params.reason === 'string' ? params.reason : null } }\n }\n if (!experimental) return unsupported('Experimental questions disabled')\n if (!onlyKeys(params, ['threadId', 'turnId', 'itemId', 'questions', 'isBlocking', 'autoResolutionMs']) || params.isBlocking !== true || params.autoResolutionMs != null) return unsupported('Question requires native handling')\n if (!Array.isArray(params.questions) || params.questions.length < 1 || params.questions.length > 3) return malformed('Question count outside supported range')\n const questions: CodexQuestion[] = []\n for (const question of params.questions) {\n if (!isRecord(question) || !onlyKeys(question, ['id', 'header', 'question', 'isOther', 'isSecret', 'options'])) return malformed('Malformed question')\n if (question.isOther !== false || question.isSecret !== false) return unsupported('Secret or other-option question')\n if (!isText(question.id) || !isText(question.header) || !isText(question.question) || questions.some(entry => entry.id === question.id)) return malformed('Invalid question identity')\n let options: CodexQuestion['options'] = null\n if (question.options !== null) {\n if (!Array.isArray(question.options) || question.options.length < 2 || question.options.length > 20) return malformed('Invalid options')\n const validated: { label: string; description: string }[] = []\n for (const option of question.options) {\n if (!isRecord(option) || !onlyKeys(option, ['label', 'description']) || !isText(option.label) || option.label.length > 200 || typeof option.description !== 'string' || validated.some(entry => entry.label === option.label)) return malformed('Invalid option')\n validated.push({ label: option.label, description: option.description })\n }\n options = validated\n }\n questions.push({ id: question.id, header: question.header, question: question.question, options })\n }\n return { kind: 'supported', subject: { kind: 'questions', questions } }\n}\n","import type { CodexReviewSubject } from './types'\nimport type { DecisionType } from '@pushary/server'\n\nexport interface PhoneQuestion {\n readonly question: string\n readonly context: string\n readonly type: DecisionType\n readonly options?: readonly string[]\n readonly questionId?: string\n}\nexport const visibleText = (text: string): string => text.replace(/\\\\/g, '\\\\\\\\').replace(/[\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}]/gu, character => `\\\\u{${character.codePointAt(0)?.toString(16)}}`)\nconst bounded = (questions: readonly PhoneQuestion[]): readonly PhoneQuestion[] | null => questions.every(question => question.question.length <= 8000 && question.context.length <= 2000 && question.options?.some(option => option.length > 200) !== true) ? questions : null\nexport const presentSubject = (subject: CodexReviewSubject): readonly PhoneQuestion[] | null => {\n if (subject.kind === 'command') return bounded([{ type: 'confirm', question: `Approve this command once?\\n\\n${visibleText(subject.command)}\\n\\nWorking directory: ${visibleText(subject.cwd)}\\nReason: ${visibleText(subject.reason ?? '(none)')}`, context: 'Codex command approval. This approval applies only to this request.' }])\n if (subject.kind === 'files') {\n const patches = subject.changes.map(change => `${change.operation}: ${visibleText(change.path)}${change.movePath === null ? '' : ` -> ${visibleText(change.movePath)}`}\\n${visibleText(change.diff)}`).join('\\n\\n')\n return bounded([{ type: 'confirm', question: `Approve these exact file changes once?\\n\\n${patches}\\n\\nReason: ${visibleText(subject.reason ?? '(none)')}`, context: 'Codex file approval. Includes every file and the complete patch.' }])\n }\n return bounded(subject.questions.map(question => ({ questionId: question.id, type: question.options ? 'select' : 'input', question: `${visibleText(question.header)}\\n${visibleText(question.question)}${question.options ? '\\n\\n' + question.options.map(option => `${visibleText(option.label)}: ${visibleText(option.description)}`).join('\\n') : ''}`, options: question.options?.map(option => visibleText(option.label)), context: 'Answer this Codex question. This answer does not grant tool permissions.' })))\n}\n","import { PusharyApiError, type DecisionType } from '@pushary/server'\nimport { isRecord, isText } from './protocol'\n\nexport interface DecisionSnapshot {\n readonly decisionId: string\n readonly status: 'pending' | 'answered' | 'expired' | 'cancelled' | 'stopped'\n readonly answered: boolean\n readonly value: string | null\n readonly type: DecisionType\n}\nexport const decisionSnapshot = (value: unknown, type: DecisionType, expectedId?: string): DecisionSnapshot => {\n if (!isRecord(value) || !isText(value.decisionId) || (expectedId !== undefined && value.decisionId !== expectedId) || value.type !== type || typeof value.answered !== 'boolean') throw new Error('Invalid decision response')\n const status = value.status\n if (status !== 'pending' && status !== 'answered' && status !== 'expired' && status !== 'cancelled' && status !== 'stopped') throw new Error('Unknown decision status')\n if ((status === 'answered') !== value.answered || (status === 'answered' && typeof value.value !== 'string') || (status !== 'answered' && value.value != null)) throw new Error('Inconsistent decision response')\n return { decisionId: value.decisionId, status, answered: value.answered, value: typeof value.value === 'string' ? value.value : null, type }\n}\nexport const isRetryable = (error: unknown): boolean => error instanceof PusharyApiError ? error.status === 429 || error.status >= 500 : error instanceof TypeError || (error instanceof Error && error.name === 'TimeoutError')\nexport const delay = (milliseconds: number, signal: AbortSignal): Promise<void> => new Promise((resolve, reject) => {\n if (signal.aborted) { reject(signal.reason); return }\n const onAbort = (): void => { clearTimeout(timer); reject(signal.reason) }\n const timer = setTimeout(() => { signal.removeEventListener('abort', onAbort); resolve() }, milliseconds)\n signal.addEventListener('abort', onAbort, { once: true })\n})\nexport const withRetry = async <T>(operation: () => Promise<T>, signal: AbortSignal): Promise<T> => {\n for (let attempt = 0; ; attempt += 1) {\n signal.throwIfAborted()\n try { return await operation() } catch (error) {\n if (signal.aborted || attempt >= 3 || !isRetryable(error)) throw error\n await delay(250 * 2 ** attempt + Math.floor(Math.random() * 101), signal)\n }\n }\n}\n\nexport const decisionFailureReason = (error: unknown): string => {\n if (error instanceof PusharyApiError) return `Partner HTTP ${error.status}`\n if (error instanceof TypeError) return 'Decision transport unavailable'\n if (error instanceof Error && error.name === 'TimeoutError') return 'Decision HTTP deadline elapsed'\n return 'Decision response invalid or unavailable'\n}\n","import type { CodexReply, CodexRequestId } from './types'\n\nexport type RequestState = 'pending' | 'accepted' | 'closed'\nexport type RequestCompletion =\n | { readonly kind: 'reply'; readonly reply: CodexReply }\n | { readonly kind: 'refuse' | 'conflict' | 'abandon'; readonly reason: string }\n | { readonly kind: 'native' }\n\ninterface RequestContext {\n readonly id: CodexRequestId\n readonly isQuestion: boolean\n readonly replyAllowed: boolean\n readonly deadlineElapsed: boolean\n}\ninterface RequestTransition {\n readonly state: Exclude<RequestState, 'pending'>\n readonly reply: CodexReply | null\n readonly interruption: string | null\n readonly abandonment: string | null\n}\n\nexport const transitionRequest = (state: RequestState, completion: RequestCompletion, context: RequestContext): RequestTransition | null => {\n if (state !== 'pending') return null\n if (completion.kind === 'reply') {\n if (!context.replyAllowed || context.deadlineElapsed) return null\n const reply = completion.reply\n const accepted = 'result' in reply && 'decision' in reply.result && reply.result.decision === 'accept'\n return { state: accepted ? 'accepted' : 'closed', reply, interruption: null, abandonment: null }\n }\n if (completion.kind === 'native') return { state: 'closed', reply: null, interruption: null, abandonment: null }\n if (completion.kind === 'abandon' || !context.replyAllowed) return { state: 'closed', reply: null, interruption: null, abandonment: completion.reason }\n const reply: CodexReply = context.isQuestion\n ? { id: context.id, error: { code: -32000, message: completion.reason } }\n : { id: context.id, result: { decision: 'cancel' } }\n return { state: 'closed', reply, interruption: context.isQuestion || completion.kind === 'conflict' ? completion.reason : null, abandonment: completion.reason }\n}\n"],"mappings":";AAAA,SAAS,2BAA2B;;;ACApC,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB,kBAAuC;AACrE,SAAS,2BAA2B;;;ACA7B,IAAM,UAAU;AAChB,IAAM,QAAQ;AACd,IAAM,YAAY;AAClB,IAAM,2BAA2B,CAAC,WAAW,SAAS;AAEtD,IAAM,0BAA0B,CAAC,UAAmD,yBAAyB,KAAK,aAAW,YAAY,KAAK;AAC9I,IAAM,WAAW,CAAC,UAAqD,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC1I,IAAM,OAAO,CAAC,UAA4C,OAAO,UAAU,YAAa,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK;AAC/I,IAAM,SAAS,CAAC,UAAoC,OAAO,UAAU,YAAY,MAAM,SAAS;AACvG,IAAM,eAAe,CAAC,UAA4B,UAAU,UAAa,UAAU,QAAQ,OAAO,UAAU;AACrG,IAAM,WAAW,CAAC,OAAgC,SAAqC,OAAO,KAAK,KAAK,EAAE,MAAM,SAAO,KAAK,SAAS,GAAG,CAAC;AACzI,IAAM,aAAa,CAAC,IAAoB,QAAgB,WAA4D;AACzH,MAAI,CAAC,OAAO,OAAO,QAAQ,KAAK,CAAC,OAAO,OAAO,MAAM,KAAK,CAAC,OAAO,OAAO,MAAM,KAAK,CAAC,aAAa,OAAO,UAAU,EAAG,QAAO;AAC7H,SAAO,EAAE,IAAI,QAAQ,UAAU,OAAO,UAAU,QAAQ,OAAO,QAAQ,QAAQ,OAAO,QAAQ,YAAY,OAAO,OAAO,eAAe,WAAW,OAAO,aAAa,KAAK;AAC7K;AACO,IAAM,kBAAkB,CAAC,UAAkC;AAChE,MAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,MAAM,MAAM,KAAK,CAAC,OAAO,MAAM,OAAO,EAAE,KAAK,CAAC,SAAS,MAAM,OAAO,MAAM,KAAK,MAAM,OAAO,OAAO,SAAS,OAAQ,QAAO;AAC7J,MAAK,MAAM,mBAAmB,eAAe,MAAM,mBAAmB,gBAAiB,MAAM,sBAAsB,UAAU,CAAC,SAAS,MAAM,OAAO,EAAG,QAAO;AAC9J,QAAM,UAAU,MAAM;AACtB,MAAI,QAAQ,SAAS,cAAc,QAAQ,SAAS,iBAAkB,QAAO;AAC7E,MAAI,CAAC,SAAS,SAAS,CAAC,QAAQ,iBAAiB,iBAAiB,mBAAmB,qBAAqB,CAAC,EAAG,QAAO;AACrH,MAAI,QAAQ,kBAAkB,UAAa,OAAO,QAAQ,kBAAkB,UAAW,QAAO;AAC9F,MAAI,QAAQ,kBAAkB,WAAc,CAAC,MAAM,QAAQ,QAAQ,aAAa,KAAK,CAAC,QAAQ,cAAc,MAAM,MAAM,GAAI,QAAO;AACnI,MAAI,CAAC,mBAAmB,qBAAqB,EAAE,KAAK,SAAO,QAAQ,GAAG,MAAM,UAAa,OAAO,QAAQ,GAAG,MAAM,SAAS,EAAG,QAAO;AACpI,MAAI,MAAM,4BAA4B,UAAa,MAAM,4BAA4B,KAAM,QAAO;AAClG,SAAO,MAAM,OAAO;AACtB;AACO,IAAM,gBAAgB,CAAC,UAAiD;AAC7E,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,KAAK,MAAM,SAAS,IAAK,QAAO;AAC9E,QAAM,UAAwB,CAAC;AAC/B,aAAW,UAAU,OAAO;AAC1B,QAAI,CAAC,SAAS,MAAM,KAAK,CAAC,SAAS,QAAQ,CAAC,QAAQ,QAAQ,MAAM,CAAC,KAAK,CAAC,OAAO,OAAO,IAAI,KAAK,OAAO,OAAO,SAAS,YAAY,CAAC,SAAS,OAAO,IAAI,EAAG,QAAO;AAClK,UAAM,OAAO,OAAO;AACpB,QAAI,CAAC,SAAS,MAAM,CAAC,QAAQ,WAAW,CAAC,KAAM,KAAK,SAAS,SAAS,KAAK,SAAS,YAAY,KAAK,SAAS,SAAW,QAAO;AAChI,QAAI,CAAC,aAAa,KAAK,SAAS,KAAM,KAAK,SAAS,YAAY,KAAK,aAAa,KAAO,QAAO;AAChG,YAAQ,KAAK,EAAE,MAAM,OAAO,MAAM,WAAW,KAAK,MAAM,UAAU,OAAO,KAAK,cAAc,WAAW,KAAK,YAAY,MAAM,MAAM,OAAO,KAAK,CAAC;AAAA,EACnJ;AACA,SAAO;AACT;AAEA,IAAM,cAAc,CAAC,YAAmC,EAAE,MAAM,eAAe,OAAO;AACtF,IAAM,YAAY,CAAC,YAAmC,EAAE,MAAM,aAAa,OAAO;AAClF,IAAM,yBAAyB,CAAC,UAA4B;AAC1D,MAAI,OAAO,UAAU,SAAU,QAAO,CAAC,UAAU,oBAAoB,WAAW,QAAQ,EAAE,SAAS,KAAK;AACxG,MAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,OAAO,CAAC,+BAA+B,CAAC,EAAG,QAAO;AACpF,QAAM,YAAY,MAAM;AACxB,SAAO,SAAS,SAAS,KAAK,SAAS,WAAW,CAAC,sBAAsB,CAAC,KAAK,MAAM,QAAQ,UAAU,oBAAoB,KAAK,UAAU,qBAAqB,MAAM,MAAM;AAC7K;AACO,IAAM,YAAY,CAAC,QAAgB,QAAiC,SAAuC,iBAAyC;AACzJ,MAAI,WAAW,SAAS;AACtB,QAAI,CAAC,SAAS,QAAQ,CAAC,YAAY,UAAU,UAAU,cAAc,eAAe,QAAQ,iBAAiB,WAAW,OAAO,UAAU,kBAAkB,0BAA0B,+BAA+B,mCAAmC,oBAAoB,CAAC,EAAG,QAAO,YAAY,mCAAmC;AACrU,QAAK,OAAO,SAAS,UAAa,OAAO,SAAS,aAAe,OAAO,iBAAiB,QAAQ,OAAO,kBAAkB,WAAY,OAAO,0BAA0B,QAAQ,OAAO,mCAAmC,KAAM,QAAO,YAAY,wCAAwC;AAC1R,QAAI,OAAO,+BAA+B,SAAS,CAAC,MAAM,QAAQ,OAAO,2BAA2B,KAAK,CAAC,OAAO,4BAA4B,MAAM,MAAM,GAAI,QAAO,UAAU,2BAA2B;AACzM,QAAI,OAAO,sBAAsB,SAAS,CAAC,MAAM,QAAQ,OAAO,kBAAkB,KAAK,CAAC,OAAO,mBAAmB,SAAS,QAAQ,KAAK,CAAC,OAAO,mBAAmB,MAAM,sBAAsB,GAAI,QAAO,YAAY,sCAAsC;AAC5P,QAAI,CAAC,OAAO,OAAO,OAAO,KAAK,CAAC,OAAO,OAAO,GAAG,KAAK,CAAC,aAAa,OAAO,MAAM,KAAK,CAAC,OAAO,cAAc,OAAO,WAAW,EAAG,QAAO,UAAU,4BAA4B;AAC9K,WAAO,EAAE,MAAM,aAAa,SAAS,EAAE,MAAM,WAAW,SAAS,OAAO,SAAS,KAAK,OAAO,KAAK,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS,KAAK,EAAE;AAAA,EACvK;AACA,MAAI,WAAW,OAAO;AACpB,QAAI,CAAC,SAAS,QAAQ,CAAC,YAAY,UAAU,UAAU,eAAe,UAAU,WAAW,CAAC,KAAK,OAAO,aAAa,KAAM,QAAO,YAAY,iCAAiC;AAC/K,QAAI,CAAC,aAAa,OAAO,MAAM,KAAK,CAAC,OAAO,cAAc,OAAO,WAAW,EAAG,QAAO,UAAU,wBAAwB;AACxH,QAAI,CAAC,QAAS,QAAO,YAAY,iCAAiC;AAClE,WAAO,EAAE,MAAM,aAAa,SAAS,EAAE,MAAM,SAAS,SAAS,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS,KAAK,EAAE;AAAA,EACpI;AACA,MAAI,CAAC,aAAc,QAAO,YAAY,iCAAiC;AACvE,MAAI,CAAC,SAAS,QAAQ,CAAC,YAAY,UAAU,UAAU,aAAa,cAAc,kBAAkB,CAAC,KAAK,OAAO,eAAe,QAAQ,OAAO,oBAAoB,KAAM,QAAO,YAAY,mCAAmC;AAC/N,MAAI,CAAC,MAAM,QAAQ,OAAO,SAAS,KAAK,OAAO,UAAU,SAAS,KAAK,OAAO,UAAU,SAAS,EAAG,QAAO,UAAU,wCAAwC;AAC7J,QAAM,YAA6B,CAAC;AACpC,aAAW,YAAY,OAAO,WAAW;AACvC,QAAI,CAAC,SAAS,QAAQ,KAAK,CAAC,SAAS,UAAU,CAAC,MAAM,UAAU,YAAY,WAAW,YAAY,SAAS,CAAC,EAAG,QAAO,UAAU,oBAAoB;AACrJ,QAAI,SAAS,YAAY,SAAS,SAAS,aAAa,MAAO,QAAO,YAAY,iCAAiC;AACnH,QAAI,CAAC,OAAO,SAAS,EAAE,KAAK,CAAC,OAAO,SAAS,MAAM,KAAK,CAAC,OAAO,SAAS,QAAQ,KAAK,UAAU,KAAK,WAAS,MAAM,OAAO,SAAS,EAAE,EAAG,QAAO,UAAU,2BAA2B;AACrL,QAAI,UAAoC;AACxC,QAAI,SAAS,YAAY,MAAM;AAC7B,UAAI,CAAC,MAAM,QAAQ,SAAS,OAAO,KAAK,SAAS,QAAQ,SAAS,KAAK,SAAS,QAAQ,SAAS,GAAI,QAAO,UAAU,iBAAiB;AACvI,YAAM,YAAsD,CAAC;AAC7D,iBAAW,UAAU,SAAS,SAAS;AACrC,YAAI,CAAC,SAAS,MAAM,KAAK,CAAC,SAAS,QAAQ,CAAC,SAAS,aAAa,CAAC,KAAK,CAAC,OAAO,OAAO,KAAK,KAAK,OAAO,MAAM,SAAS,OAAO,OAAO,OAAO,gBAAgB,YAAY,UAAU,KAAK,WAAS,MAAM,UAAU,OAAO,KAAK,EAAG,QAAO,UAAU,gBAAgB;AAChQ,kBAAU,KAAK,EAAE,OAAO,OAAO,OAAO,aAAa,OAAO,YAAY,CAAC;AAAA,MACzE;AACA,gBAAU;AAAA,IACZ;AACA,cAAU,KAAK,EAAE,IAAI,SAAS,IAAI,QAAQ,SAAS,QAAQ,UAAU,SAAS,UAAU,QAAQ,CAAC;AAAA,EACnG;AACA,SAAO,EAAE,MAAM,aAAa,SAAS,EAAE,MAAM,aAAa,UAAU,EAAE;AACxE;;;AC5EO,IAAM,cAAc,CAAC,SAAyB,KAAK,QAAQ,OAAO,MAAM,EAAE,QAAQ,gCAAgC,eAAa,OAAO,UAAU,YAAY,CAAC,GAAG,SAAS,EAAE,CAAC,GAAG;AACtL,IAAM,UAAU,CAAC,cAAyE,UAAU,MAAM,cAAY,SAAS,SAAS,UAAU,OAAQ,SAAS,QAAQ,UAAU,OAAQ,SAAS,SAAS,KAAK,YAAU,OAAO,SAAS,GAAG,MAAM,IAAI,IAAI,YAAY;AACpQ,IAAM,iBAAiB,CAAC,YAAiE;AAC9F,MAAI,QAAQ,SAAS,UAAW,QAAO,QAAQ,CAAC,EAAE,MAAM,WAAW,UAAU;AAAA;AAAA,EAAiC,YAAY,QAAQ,OAAO,CAAC;AAAA;AAAA,qBAA0B,YAAY,QAAQ,GAAG,CAAC;AAAA,UAAa,YAAY,QAAQ,UAAU,QAAQ,CAAC,IAAI,SAAS,sEAAsE,CAAC,CAAC;AACrU,MAAI,QAAQ,SAAS,SAAS;AAC5B,UAAM,UAAU,QAAQ,QAAQ,IAAI,YAAU,GAAG,OAAO,SAAS,KAAK,YAAY,OAAO,IAAI,CAAC,GAAG,OAAO,aAAa,OAAO,KAAK,OAAO,YAAY,OAAO,QAAQ,CAAC,EAAE;AAAA,EAAK,YAAY,OAAO,IAAI,CAAC,EAAE,EAAE,KAAK,MAAM;AAClN,WAAO,QAAQ,CAAC,EAAE,MAAM,WAAW,UAAU;AAAA;AAAA,EAA6C,OAAO;AAAA;AAAA,UAAe,YAAY,QAAQ,UAAU,QAAQ,CAAC,IAAI,SAAS,mEAAmE,CAAC,CAAC;AAAA,EAC3O;AACA,SAAO,QAAQ,QAAQ,UAAU,IAAI,eAAa,EAAE,YAAY,SAAS,IAAI,MAAM,SAAS,UAAU,WAAW,SAAS,UAAU,GAAG,YAAY,SAAS,MAAM,CAAC;AAAA,EAAK,YAAY,SAAS,QAAQ,CAAC,GAAG,SAAS,UAAU,SAAS,SAAS,QAAQ,IAAI,YAAU,GAAG,YAAY,OAAO,KAAK,CAAC,KAAK,YAAY,OAAO,WAAW,CAAC,EAAE,EAAE,KAAK,IAAI,IAAI,EAAE,IAAI,SAAS,SAAS,SAAS,IAAI,YAAU,YAAY,OAAO,KAAK,CAAC,GAAG,SAAS,2EAA2E,EAAE,CAAC;AACzf;;;ACnBA,SAAS,uBAA0C;AAU5C,IAAM,mBAAmB,CAAC,OAAgB,MAAoB,eAA0C;AAC7G,MAAI,CAAC,SAAS,KAAK,KAAK,CAAC,OAAO,MAAM,UAAU,KAAM,eAAe,UAAa,MAAM,eAAe,cAAe,MAAM,SAAS,QAAQ,OAAO,MAAM,aAAa,UAAW,OAAM,IAAI,MAAM,2BAA2B;AAC7N,QAAM,SAAS,MAAM;AACrB,MAAI,WAAW,aAAa,WAAW,cAAc,WAAW,aAAa,WAAW,eAAe,WAAW,UAAW,OAAM,IAAI,MAAM,yBAAyB;AACtK,MAAK,WAAW,eAAgB,MAAM,YAAa,WAAW,cAAc,OAAO,MAAM,UAAU,YAAc,WAAW,cAAc,MAAM,SAAS,KAAO,OAAM,IAAI,MAAM,gCAAgC;AAChN,SAAO,EAAE,YAAY,MAAM,YAAY,QAAQ,UAAU,MAAM,UAAU,OAAO,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,MAAM,KAAK;AAC7I;AACO,IAAM,cAAc,CAAC,UAA4B,iBAAiB,kBAAkB,MAAM,WAAW,OAAO,MAAM,UAAU,MAAM,iBAAiB,aAAc,iBAAiB,SAAS,MAAM,SAAS;AAC1M,IAAM,QAAQ,CAAC,cAAsB,WAAuC,IAAI,QAAQ,CAAC,SAAS,WAAW;AAClH,MAAI,OAAO,SAAS;AAAE,WAAO,OAAO,MAAM;AAAG;AAAA,EAAO;AACpD,QAAM,UAAU,MAAY;AAAE,iBAAa,KAAK;AAAG,WAAO,OAAO,MAAM;AAAA,EAAE;AACzE,QAAM,QAAQ,WAAW,MAAM;AAAE,WAAO,oBAAoB,SAAS,OAAO;AAAG,YAAQ;AAAA,EAAE,GAAG,YAAY;AACxG,SAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAC1D,CAAC;AACM,IAAM,YAAY,OAAU,WAA6B,WAAoC;AAClG,WAAS,UAAU,KAAK,WAAW,GAAG;AACpC,WAAO,eAAe;AACtB,QAAI;AAAE,aAAO,MAAM,UAAU;AAAA,IAAE,SAAS,OAAO;AAC7C,UAAI,OAAO,WAAW,WAAW,KAAK,CAAC,YAAY,KAAK,EAAG,OAAM;AACjE,YAAM,MAAM,MAAM,KAAK,UAAU,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG,GAAG,MAAM;AAAA,IAC1E;AAAA,EACF;AACF;AAEO,IAAM,wBAAwB,CAAC,UAA2B;AAC/D,MAAI,iBAAiB,gBAAiB,QAAO,gBAAgB,MAAM,MAAM;AACzE,MAAI,iBAAiB,UAAW,QAAO;AACvC,MAAI,iBAAiB,SAAS,MAAM,SAAS,eAAgB,QAAO;AACpE,SAAO;AACT;;;AClBO,IAAM,oBAAoB,CAAC,OAAqB,YAA+B,YAAsD;AAC1I,MAAI,UAAU,UAAW,QAAO;AAChC,MAAI,WAAW,SAAS,SAAS;AAC/B,QAAI,CAAC,QAAQ,gBAAgB,QAAQ,gBAAiB,QAAO;AAC7D,UAAMA,SAAQ,WAAW;AACzB,UAAM,WAAW,YAAYA,UAAS,cAAcA,OAAM,UAAUA,OAAM,OAAO,aAAa;AAC9F,WAAO,EAAE,OAAO,WAAW,aAAa,UAAU,OAAAA,QAAO,cAAc,MAAM,aAAa,KAAK;AAAA,EACjG;AACA,MAAI,WAAW,SAAS,SAAU,QAAO,EAAE,OAAO,UAAU,OAAO,MAAM,cAAc,MAAM,aAAa,KAAK;AAC/G,MAAI,WAAW,SAAS,aAAa,CAAC,QAAQ,aAAc,QAAO,EAAE,OAAO,UAAU,OAAO,MAAM,cAAc,MAAM,aAAa,WAAW,OAAO;AACtJ,QAAM,QAAoB,QAAQ,aAC9B,EAAE,IAAI,QAAQ,IAAI,OAAO,EAAE,MAAM,OAAQ,SAAS,WAAW,OAAO,EAAE,IACtE,EAAE,IAAI,QAAQ,IAAI,QAAQ,EAAE,UAAU,SAAS,EAAE;AACrD,SAAO,EAAE,OAAO,UAAU,OAAO,cAAc,QAAQ,cAAc,WAAW,SAAS,aAAa,WAAW,SAAS,MAAM,aAAa,WAAW,OAAO;AACjK;;;AJ1BA,IAAM,cAAc;AACpB,IAAM,cAAc;AACpB,IAAM,YAAY;AAClB,IAAM,kBAAkB,IAAI,OAAO;AACnC,IAAM,eAAe;AACrB,IAAM,aAAa;AACnB,IAAM,yBAAyB;AAgB/B,IAAM,UAAU,CAAC,UAAkB,QAAgB,WAA2B,KAAK,UAAU,CAAC,UAAU,QAAQ,MAAM,CAAC;AACvH,IAAM,UAAU,CAAC,UAAkB,WAA2B,KAAK,UAAU,CAAC,UAAU,MAAM,CAAC;AAC/F,IAAM,SAAS,CAAC,OAAgC,KAAK,UAAU,CAAC,OAAO,IAAI,EAAE,CAAC;AAEvE,IAAM,4BAA4B,CAAC,kBAA2D;AACnG,QAAM,SAAS,OAAO,OAAO,EAAE,GAAG,cAAc,CAAC;AACjD,QAAM,YAAY,OAAO,aAAa;AACtC,MAAI,CAAC,wBAAwB,OAAO,YAAY,KAAK,CAAC,OAAO,UAAU,SAAS,KAAK,YAAY,OAAU,YAAY,OAAW,CAAC,OAAO,UAAU,KAAK,KAAK,CAAC,OAAO,YAAY,KAAK,EAAG,OAAM,IAAI,UAAU,qCAAqC;AACnP,MAAI,CAAC,OAAO,cAAc,OAAO,sBAAsB,OAAO,SAAS,OAAO,cAAc,EAAE,KAAK,cAAY,OAAO,aAAa,UAAU,EAAG,OAAM,IAAI,UAAU,iCAAiC;AACrM,QAAM,YAAY,oBAAoB,EAAE,QAAQ,OAAO,QAAQ,SAAS,OAAO,SAAS,kBAAkB,IAAO,CAAC,EAAE;AACpH,QAAM,aAAa,WAAW;AAC9B,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,WAAW,oBAAI,IAA0B;AAC/C,QAAM,mBAAmB,oBAAI,IAAY;AACzC,QAAM,QAAQ,oBAAI,IAAuF;AACzG,QAAM,iBAAiB,oBAAI,IAAY;AACvC,QAAM,UAAU,oBAAI,IAAyB;AAC7C,QAAM,OAAO,oBAAI,IAAmB;AACpC,QAAM,kBAA4B,CAAC;AACnC,QAAM,qBAAqB,oBAAI,IAAqB;AACpD,MAAI,aAAa;AACjB,MAAI,WAAW;AACf,MAAI;AACJ,MAAI,mBAAmB;AACvB,QAAM,OAAO,CAAC,UAAmC;AAC/C,QAAI;AAAE,aAAO,QAAQ,KAAK;AAAA,IAAE,QAAQ;AAAE,cAAQ,MAAM,uCAAuC;AAAA,IAAE;AAAA,EAC/F;AACA,QAAM,WAAW,CAAC,SAAuB,MAAiC,QAAiB,eAA8B,KAAK,EAAE,MAAM,WAAW,QAAQ,SAAS,IAAI,UAAU,QAAQ,SAAS,UAAU,QAAQ,QAAQ,SAAS,QAAQ,eAAe,QAAQ,QAAQ,YAAY,OAAO,CAAC;AAC/R,QAAM,QAAQ,CAAC,QAA6B;AAAE,SAAK,IAAI,GAAG;AAAG,SAAK,IAAI,QAAQ,MAAM,KAAK,OAAO,GAAG,CAAC,EAAE,MAAM,MAAM,MAAS;AAAA,EAAE;AAC7H,QAAM,gBAAgB,CAAC,SAAuB,OAAqB;AACjE,oBAAgB,KAAK,EAAE;AACvB,aAAS,SAAS,kBAAkB,kDAAkD,EAAE;AAAA,EAC1F;AACA,QAAM,UAAU,OAAO,SAAuB,OAA8B;AAC1E,QAAI,QAAQ,WAAW,IAAI,EAAE,EAAG;AAChC,YAAQ,WAAW,IAAI,EAAE;AACzB,UAAM,YAAY,KAAK,IAAI,QAAQ,iBAAiB,gBAAgB,IAAI,YAAY,IAAI;AACxF,QAAI,aAAa,GAAG;AAAE,oBAAc,SAAS,EAAE;AAAG;AAAA,IAAO;AACzD,UAAM,aAAa,IAAI,gBAAgB;AACvC,uBAAmB,IAAI,UAAU;AACjC,UAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,SAAS;AAC5D,QAAI;AACF,eAAS,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG;AAC/C,YAAI;AACF,gBAAM,SAAkB,MAAM,UAAU,OAAO,IAAI,EAAE,QAAQ,WAAW,OAAO,CAAC;AAChF,cAAI,CAAC,SAAS,MAAM,KAAK,OAAO,eAAe,MAAM,OAAO,OAAO,cAAc,UAAW,OAAM,IAAI,MAAM,6BAA6B;AACzI,cAAI,OAAO,UAAW;AACtB,gBAAM,SAAkB,MAAM,UAAU,IAAI,IAAI,EAAE,QAAQ,WAAW,OAAO,CAAC;AAC7E,cAAI,SAAS,MAAM,MAAM,OAAO,SAAS,aAAa,OAAO,SAAS,YAAY,OAAO,SAAS,UAAU;AAC1G,kBAAM,WAAW,iBAAiB,QAAQ,OAAO,MAAM,EAAE;AACzD,gBAAI,SAAS,WAAW,UAAW;AAAA,UACrC;AACA,gBAAM,IAAI,UAAU,4BAA4B;AAAA,QAClD,SAAS,OAAO;AACd,cAAI,WAAW,OAAO,WAAW,YAAY,KAAK,CAAC,YAAY,KAAK,EAAG,OAAM;AAC7E,gBAAM,MAAM,YAAY,IAAI,MAAM,KAAK,WAAW,MAAM;AAAA,QAC1D;AAAA,MACF;AAAA,IACF,QAAQ;AAAE,oBAAc,SAAS,EAAE;AAAA,IAAE,UAAE;AAAU,mBAAa,KAAK;AAAG,yBAAmB,OAAO,UAAU;AAAA,IAAE;AAAA,EAC9G;AACA,QAAM,eAAe,CAAC,YAAgC;AACpD,iBAAa,QAAQ,KAAK;AAC1B,YAAQ,kBAAkB,KAAK,IAAI,YAAY,IAAI,IAAI,YAAY,gBAAgB;AACnF,YAAQ,WAAW,MAAM;AACzB,eAAW,MAAM,QAAQ,YAAa,OAAM,QAAQ,SAAS,EAAE,CAAC;AAAA,EAClE;AACA,QAAM,kBAAkB,CAAC,SAAuB,eAAwC;AACtF,UAAM,aAAa,kBAAkB,QAAQ,OAAO,YAAY;AAAA,MAC9D,IAAI,QAAQ,SAAS;AAAA,MACrB,YAAY,QAAQ,QAAQ,SAAS;AAAA,MACrC,cAAc,YAAY,OAAO;AAAA,MACjC,iBAAiB,YAAY,IAAI,KAAK,QAAQ;AAAA,IAChD,CAAC;AACD,QAAI,CAAC,WAAY;AACjB,YAAQ,QAAQ,WAAW;AAC3B,iBAAa,OAAO;AACpB,QAAI,WAAW,SAAS,YAAY,OAAO,GAAG;AAC5C,YAAM,cAAc,WAAW,iBAAiB,QAAQ,UAAU,QAAQ,UAAU,WAAW,YAAY;AAC3G,UAAI,eAAe,YAAY,OAAO,GAAG;AACvC,YAAI;AAAE,iBAAO,aAAa,WAAW,KAAK;AAAA,QAAE,QAAQ;AAAE,gBAAM,2CAA2C;AAAA,QAAE;AAAA,MAC3G;AAAA,IACF;AACA,QAAI,WAAW,gBAAgB,KAAM,UAAS,SAAS,qBAAqB,WAAW,WAAW;AAAA,EACpG;AACA,QAAM,UAAU,MAAgE;AAC9E,QAAI,SAAU,QAAO;AACrB,eAAW;AACX,uBAAmB,YAAY,IAAI,IAAI;AACvC,WAAO,QAAQ,oBAAoB,SAAS,OAAO;AACnD,QAAI,kBAAoF,MAAM;AAC9F,eAAW,IAAI,QAAQ,aAAW;AAAE,wBAAkB;AAAA,IAAQ,CAAC;AAC/D,YAAQ,MAAM;AACd,YAAQ,MAAM;AACd,iBAAa;AACb,eAAW,WAAW,SAAS,OAAO,EAAG,iBAAgB,SAAS,EAAE,MAAM,WAAW,QAAQ,sBAAsB,CAAC;AACpH,UAAM,SAAS,YAA2B;AACxC,YAAM,aAAa,IAAI,gBAAgB;AACvC,YAAM,QAAQ,YAA2B;AAAE,eAAO,KAAK,OAAO,KAAK,YAAY,IAAI,IAAI,iBAAkB,OAAM,QAAQ,WAAW,CAAC,GAAG,IAAI,CAAC;AAAA,MAAE;AAC7I,YAAM,QAAQ,KAAK,CAAC,MAAM,GAAG,MAAM,YAAY,WAAW,MAAM,CAAC,CAAC,EAAE,MAAM,MAAM,MAAS;AACzF,iBAAW,MAAM;AACjB,iBAAW,qBAAqB,mBAAoB,mBAAkB,MAAM;AAC5E,YAAM,QAAQ,QAAQ;AACtB,sBAAgB,EAAE,iBAAiB,CAAC,GAAG,eAAe,EAAE,CAAC;AAAA,IAC3D;AACA,SAAK,OAAO;AACZ,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,CAAC,WAAyB;AACtC,SAAK,QAAQ;AACb,SAAK,EAAE,MAAM,gBAAgB,OAAO,CAAC;AAAA,EACvC;AACA,QAAM,WAAW,MAAY;AAAE,SAAK,QAAQ;AAAG,SAAK,EAAE,MAAM,qBAAqB,QAAQ,2DAA2D,CAAC;AAAA,EAAE;AACvJ,QAAM,aAAa,MAAc,SAAS,OAAO,iBAAiB,OAAO,MAAM,OAAO,eAAe;AACrG,QAAM,eAAe,CAAC,UAAkB,QAAgB,aAA+B;AACrF,UAAM,MAAM,QAAQ,UAAU,MAAM;AACpC,UAAM,WAAW,MAAM,IAAI,GAAG;AAC9B,QAAI,UAAU;AAAE,eAAS,aAAT,SAAS,WAAa;AAAU,aAAO;AAAA,IAAK;AAC5D,QAAI,WAAW,KAAK,cAAc;AAAE,eAAS;AAAG,aAAO;AAAA,IAAM;AAC7D,UAAM,IAAI,KAAK,EAAE,UAAU,QAAQ,SAAS,CAAC;AAC7C,WAAO;AAAA,EACT;AACA,QAAM,eAAe,CAAC,aAAuC,MAAM,IAAI,QAAQ,SAAS,UAAU,SAAS,MAAM,CAAC,GAAG,aAAa,QAAQ,eAAe,IAAI,QAAQ,SAAS,UAAU,SAAS,QAAQ,SAAS,MAAM,CAAC;AACzN,QAAM,cAAc,CAAC,YAAmC,CAAC,YAAY,CAAC,aAAa,QAAQ,QAAQ,KAAK,QAAQ,IAAI,QAAQ,SAAS,QAAQ;AAC7I,QAAM,OAAO,CAAC,YAAmC,QAAQ,UAAU,aAAa,YAAY,OAAO,KAAK,YAAY,IAAI,IAAI,QAAQ;AACpI,QAAM,YAAY,CAAC,UAA2B,WAA4B;AACxE,QAAI;AAAE,aAAO,qBAAqB,SAAS,UAAU,SAAS,QAAQ,MAAM;AAAG,aAAO,CAAC;AAAA,IAAS,QAAQ;AAAE,YAAM,iDAAiD;AAAG,aAAO;AAAA,IAAM;AAAA,EACnL;AACA,QAAM,YAAY,CAAC,UAAkB,QAAgB,WAAyB;AAC5E,QAAI,CAAC,aAAa,UAAU,QAAQ,IAAI,EAAG;AAC3C,eAAW,WAAW,SAAS,OAAO,EAAG,KAAI,QAAQ,SAAS,aAAa,YAAY,QAAQ,SAAS,WAAW,OAAQ,iBAAgB,SAAS,EAAE,MAAM,WAAW,OAAO,CAAC;AAC/K,eAAW,OAAO,QAAQ,KAAK,GAAG;AAChC,UAAI,IAAI,WAAW,KAAK,UAAU,CAAC,UAAU,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,GAAG,GAAG;AAAE,sBAAc,QAAQ,IAAI,GAAG,GAAG,SAAS;AAAG,gBAAQ,OAAO,GAAG;AAAA,MAAE;AAAA,IAC/I;AAAA,EACF;AACA,QAAM,iBAAiB,CAAC,UAAkB,QAAgB,WAAyB;AACjF,UAAM,WAAW,CAAC,GAAG,SAAS,OAAO,CAAC,EAAE,KAAK,aAAW,QAAQ,SAAS,aAAa,YAAY,QAAQ,SAAS,WAAW,UAAU,QAAQ,UAAU,cAAc,CAAC,aAAa,QAAQ,QAAQ,CAAC;AACvM,cAAU,UAAU,QAAQ,MAAM;AAClC,QAAI,UAAU;AACZ,UAAI,CAAC,SAAU,WAAU,SAAS,UAAU,MAAM;AAClD,eAAS,UAAU,qBAAqB,iEAAiE;AAAA,IAC3G;AAAA,EACF;AACA,QAAM,mBAAmB,CAAC,aAA2B;AACnD,YAAQ,OAAO,QAAQ;AACvB,eAAW,QAAQ,MAAM,OAAO,EAAG,KAAI,KAAK,aAAa,SAAU,gBAAe,UAAU,KAAK,QAAQ,qBAAqB;AAC9H,eAAW,OAAO,QAAQ,KAAK,EAAG,KAAI,IAAI,WAAW,KAAK,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,GAAG,GAAG;AAAE,oBAAc,QAAQ,IAAI,GAAG,GAAG,SAAS;AAAG,cAAQ,OAAO,GAAG;AAAA,IAAE;AAAA,EACzK;AACA,QAAM,gBAAgB,OAAO,SAAuB,OAAsB,YAA+C;AACvH,UAAM,UAA0B,EAAE,UAAU,MAAM,UAAU,MAAM,MAAM,MAAM,SAAS,MAAM,SAAS,SAAS,MAAM,SAAS,YAAY,OAAO,YAAY,WAAW,OAAO,aAAa,SAAS,MAAM,OAAO,kBAAkB,MAAM,kBAAkB,KAAK,KAAK,YAAY,GAAI,GAAG,gBAAgB,oBAAoB,EAAE,UAAU,OAAO,UAAU,YAAY,OAAO,YAAY,YAAY,GAAG,QAAQ,UAAU,eAAe,QAAQ,QAAQ,SAAS,YAAY,MAAM,cAAc,KAAK,CAAC,EAAE;AAC1e,QAAI;AACJ,QAAI;AAAE,YAAM,MAAM,UAAU,MAAM,UAAU,OAAO,SAAS,EAAE,QAAQ,QAAQ,WAAW,OAAO,CAAC,GAAG,QAAQ,WAAW,MAAM;AAAA,IAAE,SAAS,OAAO;AAC7I,UAAI,QAAQ,WAAW,OAAO,WAAW,YAAY,KAAK,EAAG,UAAS,SAAS,0BAA0B,4DAA4D;AACrK,YAAM;AAAA,IACR;AACA,QAAI,SAAS,GAAG,KAAK,OAAO,IAAI,UAAU,GAAG;AAC3C,cAAQ,YAAY,IAAI,IAAI,UAAU;AACtC,UAAI,CAAC,KAAK,OAAO,GAAG;AAAE,cAAM,QAAQ,SAAS,IAAI,UAAU,CAAC;AAAG,cAAM,IAAI,MAAM,wBAAwB;AAAA,MAAE;AAAA,IAC3G;AACA,QAAI,CAAC,SAAS,GAAG,KAAK,CAAC,OAAO,IAAI,UAAU,EAAG,UAAS,SAAS,0BAA0B,uCAAuC;AAClI,QAAI,WAAW,iBAAiB,KAAK,MAAM,IAAI;AAC/C,aAAS,SAAS,oBAAoB,QAAW,SAAS,UAAU;AACpE,WAAO,SAAS,WAAW,WAAW;AACpC,UAAI,CAAC,KAAK,OAAO,EAAG,OAAM,IAAI,MAAM,wBAAwB;AAC5D,YAAM,OAAgB,MAAM,UAAU,MAAM,UAAU,IAAI,SAAS,YAAY,EAAE,MAAM,GAAG,QAAQ,QAAQ,WAAW,OAAO,CAAC,GAAG,QAAQ,WAAW,MAAM;AACzJ,iBAAW,iBAAiB,MAAM,MAAM,MAAM,SAAS,UAAU;AACjE,UAAI,SAAS,WAAW,UAAW,OAAM,MAAM,IAAI,QAAQ,WAAW,MAAM;AAAA,IAC9E;AACA,YAAQ,YAAY,OAAO,SAAS,UAAU;AAC9C,aAAS,SAAS,oBAAoB,SAAS,QAAQ,SAAS,UAAU;AAC1E,WAAO;AAAA,EACT;AACA,QAAM,aAAa,OAAO,SAAuB,WAAoD;AACnG,QAAI;AACF,YAAM,UAA0D,uBAAO,OAAO,IAAI;AAClF,iBAAW,CAAC,SAAS,KAAK,KAAK,OAAO,QAAQ,GAAG;AAC/C,YAAI,CAAC,KAAK,OAAO,EAAG;AACpB,YAAI,UAAU,KAAK,QAAQ,WAAW,YAAY,IAAI,IAAI,wBAAwB;AAAE,0BAAgB,SAAS,EAAE,MAAM,UAAU,QAAQ,yCAAyC,CAAC;AAAG;AAAA,QAAO;AAC3L,cAAM,SAAS,MAAM,cAAc,SAAS,OAAO,OAAO;AAC1D,YAAI,CAAC,KAAK,OAAO,EAAG;AACpB,YAAI,QAAQ,QAAQ,SAAS,aAAa;AACxC,gBAAM,WAAW,OAAO,SAAS,aAAa,OAAO,WAAW,cAAc,WAAW,EAAE,QAAQ,OAAO,QAAQ,MAAM,OAAO,MAAM,OAAO,OAAO,MAAM,CAAC;AAC1J,0BAAgB,SAAS,EAAE,MAAM,SAAS,OAAO,EAAE,IAAI,QAAQ,SAAS,IAAI,QAAQ,EAAE,UAAU,WAAW,WAAW,QAAQ,gBAAgB,EAAE,EAAE,CAAC;AACnJ;AAAA,QACF;AACA,YAAI,CAAC,OAAO,YAAY,CAAC,OAAO,OAAO,KAAK,KAAK,OAAO,MAAM,SAAS,OAAS,MAAM,WAAW,CAAC,MAAM,QAAQ,SAAS,OAAO,KAAK,GAAI;AAAE,0BAAgB,SAAS,EAAE,MAAM,UAAU,QAAQ,0CAA0C,CAAC;AAAG;AAAA,QAAO;AACnP,cAAM,WAAW,QAAQ,QAAQ,UAAU,OAAO;AAClD,YAAI,CAAC,YAAY,CAAC,MAAM,WAAY,OAAM,IAAI,MAAM,2BAA2B;AAC/E,cAAM,gBAAgB,MAAM,SAAS,QAAQ,OAAO,KAAK;AACzD,cAAM,SAAS,kBAAkB,SAAY,SAAS,UAAU,aAAa,GAAG,QAAQ,OAAO;AAC/F,YAAI,WAAW,OAAW,OAAM,IAAI,MAAM,yBAAyB;AACnE,gBAAQ,MAAM,UAAU,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE;AAAA,MAClD;AACA,sBAAgB,SAAS,EAAE,MAAM,SAAS,OAAO,EAAE,IAAI,QAAQ,SAAS,IAAI,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC;AAAA,IACrG,SAAS,OAAO;AAAE,UAAI,KAAK,OAAO,EAAG,iBAAgB,SAAS,EAAE,MAAM,UAAU,QAAQ,sBAAsB,KAAK,EAAE,CAAC;AAAA,IAAE;AAAA,EAC1H;AACA,QAAM,UAAU,CAAC,QAAgB,WAAyD;AACxF,QAAI,WAAW,4BAA4B,KAAK,OAAO,SAAS,GAAG;AACjE,YAAM,UAAU,SAAS,IAAI,OAAO,OAAO,SAAS,CAAC;AACrD,UAAI,WAAW,OAAO,aAAa,QAAQ,SAAS,SAAU,iBAAgB,SAAS,EAAE,MAAM,WAAW,QAAQ,0BAA0B,CAAC;AAAA,IAC/I;AACA,QAAI,OAAO,OAAO,QAAQ,GAAG;AAC3B,UAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,SAAS,OAAO,IAAI,KAAK,OAAO,OAAO,KAAK,EAAE,KAAK,WAAW,eAAgB,cAAa,OAAO,UAAU,OAAO,KAAK,IAAI,KAAK;AACrK,UAAI,CAAC,iBAAiB,mBAAmB,yBAAyB,EAAE,SAAS,MAAM,EAAG,kBAAiB,OAAO,QAAQ;AACtH,UAAI,OAAO,OAAO,MAAM,KAAK,CAAC,kBAAkB,oBAAoB,aAAa,EAAE,SAAS,MAAM,EAAG,WAAU,OAAO,UAAU,OAAO,QAAQ,MAAM;AACrJ,UAAI,SAAS,OAAO,IAAI,KAAK,OAAO,OAAO,KAAK,EAAE,KAAK,WAAW,iBAAkB,WAAU,OAAO,UAAU,OAAO,KAAK,IAAI,MAAM;AACrI,YAAM,SAAS,SAAS,OAAO,IAAI,KAAK,OAAO,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,KAAK,OAAO;AACzF,UAAI,OAAO,OAAO,MAAM,KAAK,OAAO,MAAM,GAAG;AAC3C,cAAM,MAAM,QAAQ,OAAO,UAAU,OAAO,QAAQ,MAAM;AAC1D,YAAI,WAAW,kBAAkB;AAC/B,cAAI,CAAC,eAAe,IAAI,GAAG,KAAK,WAAW,KAAK,cAAc;AAAE,qBAAS;AAAG,mBAAO,EAAE,MAAM,WAAW,QAAQ,kCAAkC;AAAA,UAAE;AAClJ,yBAAe,IAAI,GAAG;AACtB,qBAAW,WAAW,SAAS,OAAO,EAAG,KAAI,QAAQ,QAAQ,SAAS,UAAU,QAAQ,SAAS,QAAQ,QAAQ,SAAS,MAAM,MAAM,IAAK,iBAAgB,SAAS,EAAE,MAAM,WAAW,QAAQ,iBAAiB,CAAC;AACjN,wBAAc,QAAQ,IAAI,GAAG,GAAG,SAAS;AACzC,kBAAQ,OAAO,GAAG;AAAA,QACpB;AACA,YAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,CAAC,eAAe,IAAI,GAAG,KAAK,MAAM,IAAI,QAAQ,OAAO,UAAU,OAAO,MAAM,CAAC,GAAG,aAAa,SAAS,WAAW,kCAAmC,WAAW,kBAAkB,SAAS,OAAO,IAAI,KAAK,OAAO,KAAK,SAAS,eAAgB;AACjR,cAAI,CAAC,aAAa,OAAO,UAAU,OAAO,QAAQ,KAAK,EAAG,QAAO,EAAE,MAAM,WAAW,QAAQ,yBAAyB;AACrH,gBAAM,MAAM,WAAW,kBAAkB,SAAS,OAAO,IAAI,IAAI,OAAO,KAAK,UAAU,OAAO;AAC9F,gBAAM,WAAW,QAAQ,IAAI,GAAG;AAChC,gBAAM,SAAS,cAAc,GAAG;AAChC,gBAAM,SAAS,oBAAoB,MAAM;AACzC,gBAAM,WAAW,aAAa,UAAa,SAAS,WAAW;AAC/D,gBAAM,UAAW,WAAW,kCAAkC,CAAC,YAAc,WAAW,kBAAkB,YAAa,UAAU,YAAY,OAAO,OAAO;AAC3J,gBAAM,QAAQ,OAAO,WAAW,KAAK,UAAU,OAAO,CAAC;AACvD,cAAK,CAAC,YAAY,QAAQ,QAAQ,aAAc,cAAc,UAAU,SAAS,KAAK,QAAQ,iBAAiB;AAAE,qBAAS;AAAG,mBAAO,EAAE,MAAM,WAAW,QAAQ,0BAA0B;AAAA,UAAE;AAC3L,kBAAQ,IAAI,KAAK,EAAE,SAAS,QAAQ,MAAM,CAAC;AAC3C,wBAAc,SAAS,UAAU,SAAS;AAC1C,cAAI,YAAY,YAAY;AAAM,uBAAW,WAAW,SAAS,OAAO,EAAG,KAAI,QAAQ,QAAQ,SAAS,UAAU,QAAQ,SAAS,QAAQ,QAAQ,SAAS,MAAM,MAAM,KAAK;AAC3K,kBAAI,QAAQ,UAAU,cAAc,CAAC,aAAa,QAAQ,QAAQ,EAAG,gBAAe,QAAQ,SAAS,UAAU,QAAQ,SAAS,QAAQ,yCAAyC;AAAA,kBAC5K,iBAAgB,SAAS,EAAE,MAAM,UAAU,QAAQ,yBAAyB,CAAC;AAAA,YACpF;AAAA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO,EAAE,MAAM,WAAW;AAAA,EAC5B;AACA,QAAM,mBAAmB,CAAC,IAAqB,WAAwC;AACrF,QAAI,WAAW,KAAK,cAAc;AAAE,eAAS;AAAG,aAAO,EAAE,MAAM,WAAW,QAAQ,4BAA4B;AAAA,IAAE;AAChH,qBAAiB,IAAI,OAAO,EAAE,CAAC;AAC/B,SAAK,EAAE,MAAM,0BAA0B,WAAW,IAAI,OAAO,CAAC;AAC9D,WAAO,WAAW,EAAE,MAAM,WAAW,QAAQ,iCAAiC,IAAI,EAAE,MAAM,aAAa,OAAO;AAAA,EAChH;AACA,QAAM,WAAW,CAAC,YAA0C;AAC1D,QAAI,SAAU,QAAO,EAAE,MAAM,WAAW,QAAQ,mBAAmB;AACnE,QAAI,CAAC,SAAS,OAAO,KAAK,CAAC,OAAO,QAAQ,MAAM,KAAK,CAAC,SAAS,QAAQ,MAAM,EAAG,QAAO,EAAE,MAAM,WAAW,QAAQ,0BAA0B;AAC5I,QAAI,QAAQ,OAAO,OAAW,QAAO,QAAQ,QAAQ,QAAQ,QAAQ,MAAM;AAC3E,QAAI,CAAC,KAAK,QAAQ,EAAE,EAAG,QAAO,EAAE,MAAM,WAAW,QAAQ,iBAAiB;AAC1E,QAAI,iBAAiB,IAAI,OAAO,QAAQ,EAAE,CAAC,EAAG,QAAO,EAAE,MAAM,UAAU;AACvE,UAAM,WAAW,SAAS,IAAI,OAAO,QAAQ,EAAE,CAAC;AAChD,QAAI,UAAU;AACZ,UAAI,SAAS,mBAAmB,oBAAoB,EAAE,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,CAAC,GAAG;AACvG,YAAI,SAAS,UAAU,WAAY,gBAAe,SAAS,SAAS,UAAU,SAAS,SAAS,QAAQ,+BAA+B;AAAA,YAClI,iBAAgB,UAAU,EAAE,MAAM,YAAY,QAAQ,gCAAgC,CAAC;AAAA,MAC9F;AACA,aAAO,EAAE,MAAM,UAAU;AAAA,IAC3B;AACA,QAAI,CAAC,CAAC,SAAS,OAAO,SAAS,EAAE,SAAS,QAAQ,MAAM,EAAG,QAAO,iBAAiB,QAAQ,IAAI,2BAA2B;AAC1H,UAAM,WAAW,WAAW,QAAQ,IAAI,QAAQ,QAAQ,QAAQ,MAAM;AACtE,QAAI,CAAC,SAAU,QAAO,EAAE,MAAM,WAAW,QAAQ,+CAA+C;AAChG,QAAI,aAAa,QAAQ,GAAG;AAC1B,UAAI,WAAW,KAAK,cAAc;AAAE,iBAAS;AAAG,eAAO,EAAE,MAAM,WAAW,QAAQ,4BAA4B;AAAA,MAAE;AAChH,uBAAiB,IAAI,OAAO,SAAS,EAAE,CAAC;AACxC,UAAI,SAAS,WAAW,aAAa,CAAC,UAAU,UAAU,2BAA2B,EAAG,QAAO,EAAE,MAAM,WAAW,QAAQ,mBAAmB;AAC7I,UAAI,CAAC,SAAU,QAAO,aAAa,SAAS,WAAW,YAAY,EAAE,IAAI,SAAS,IAAI,OAAO,EAAE,MAAM,OAAQ,SAAS,4BAA4B,EAAE,IAAI,EAAE,IAAI,SAAS,IAAI,QAAQ,EAAE,UAAU,SAAS,EAAE,CAAC;AAC3M,aAAO,EAAE,MAAM,UAAU;AAAA,IAC3B;AACA,QAAI,CAAC,QAAQ,IAAI,SAAS,QAAQ,EAAG,QAAO,iBAAiB,QAAQ,IAAI,8BAA8B;AACvG,QAAI,CAAC,aAAa,SAAS,UAAU,SAAS,QAAQ,KAAK,EAAG,QAAO,EAAE,MAAM,WAAW,QAAQ,yBAAyB;AACzH,UAAM,UAAU,UAAU,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,QAAQ,SAAS,UAAU,SAAS,QAAQ,SAAS,MAAM,CAAC,GAAG,WAAW,MAAM,OAAO,0BAA0B,IAAI;AAC3L,QAAI,QAAQ,SAAS,aAAa;AAChC,UAAI,WAAW,KAAK,cAAc;AAAE,iBAAS;AAAG,eAAO,EAAE,MAAM,WAAW,QAAQ,4BAA4B;AAAA,MAAE;AAChH,uBAAiB,IAAI,OAAO,QAAQ,EAAE,CAAC;AACvC,UAAI,QAAQ,WAAW,aAAa,CAAC,UAAU,UAAU,QAAQ,MAAM,EAAG,QAAO,EAAE,MAAM,WAAW,QAAQ,mBAAmB;AAC/H,UAAI;AAAE,eAAO,aAAa,EAAE,IAAI,QAAQ,IAAI,OAAO,EAAE,MAAM,QAAQ,SAAS,QAAQ,OAAO,EAAE,CAAC;AAAA,MAAE,QAAQ;AAAE,cAAM,wCAAwC;AAAA,MAAE;AAC1J,aAAO,EAAE,MAAM,UAAU;AAAA,IAC3B;AACA,QAAI,QAAQ,SAAS,cAAe,QAAO,iBAAiB,QAAQ,IAAI,QAAQ,MAAM;AACtF,UAAM,SAAS,oBAAoB,QAAQ,OAAO;AAClD,UAAM,SAAS,eAAe,QAAQ,OAAO;AAC7C,QAAI,CAAC,OAAQ,QAAO,iBAAiB,QAAQ,IAAI,qCAAqC;AACtF,QAAI,WAAW,KAAK,gBAAgB,CAAC,GAAG,SAAS,OAAO,CAAC,EAAE,OAAO,CAAAC,aAAWA,SAAQ,UAAU,SAAS,EAAE,UAAU,aAAa;AAAE,eAAS;AAAG,aAAO,EAAE,MAAM,WAAW,QAAQ,4BAA4B;AAAA,IAAE;AAC/M,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,QAAQ,WAAW,MAAM;AAAE,YAAMA,WAAU,SAAS,IAAI,OAAO,SAAS,EAAE,CAAC;AAAG,UAAIA,SAAS,iBAAgBA,UAAS,EAAE,MAAM,UAAU,QAAQ,4BAA4B,CAAC;AAAA,IAAE,GAAG,SAAS;AAC/L,UAAM,UAAwB,EAAE,UAAU,iBAAiB,MAAM,QAAQ,QAAQ,OAAO,kBAAkB,KAAK,CAAC,QAAQ,OAAO,mBAAmB,SAAS,SAAS,IAAI,WAAW,WAAW,QAAQ,gBAAgB,oBAAoB,EAAE,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,CAAC,GAAG,SAAS,QAAQ,SAAS,YAAY,UAAU,YAAY,IAAI,IAAI,WAAW,OAAO,aAAa,oBAAI,IAAI,GAAG,YAAY,oBAAI,IAAI,GAAG,OAAO,WAAW,iBAAiB,SAAS;AAChd,aAAS,IAAI,OAAO,SAAS,EAAE,GAAG,OAAO;AACzC,QAAI,UAAU;AACd,QAAI;AAAE,gBAAU,OAAO,eAAe,gBAAgB,QAAQ,OAAO,CAAC,MAAM;AAAA,IAAK,QAAQ;AAAE,gBAAU;AAAA,IAAM;AAC3G,QAAI,SAAU,QAAO,EAAE,MAAM,WAAW,QAAQ,iCAAiC;AACjF,QAAI,CAAC,KAAK,OAAO,EAAG,QAAO,EAAE,MAAM,UAAU;AAC7C,QAAI,CAAC,SAAS;AACZ,sBAAgB,SAAS,EAAE,MAAM,SAAS,CAAC;AAC3C,eAAS,OAAO,OAAO,SAAS,EAAE,CAAC;AACnC,aAAO,iBAAiB,QAAQ,IAAI,oCAAoC;AAAA,IAC1E;AACA,UAAM,WAAW,SAAS,MAAM,CAAC;AACjC,WAAO,EAAE,MAAM,UAAU;AAAA,EAC3B;AACA,QAAM,SAAS,CAAC,YAA0C;AACxD,QAAI;AAAE,aAAO,SAAS,OAAO;AAAA,IAAE,QAAQ;AACrC,YAAM,oDAAoD;AAC1D,aAAO,EAAE,MAAM,WAAW,QAAQ,iCAAiC;AAAA,IACrE;AAAA,EACF;AACA,QAAM,iBAAiB,CAAC,UAAyB;AAC/C,QAAI,SAAU,OAAM,IAAI,MAAM,kBAAkB;AAChD,UAAM,KAAK,gBAAgB,KAAK;AAChC,QAAI,CAAC,GAAI,OAAM,IAAI,UAAU,wDAAwD;AACrF,QAAI,CAAC,GAAG,SAAS,OAAO,CAAC,EAAE,KAAK,aAAW,QAAQ,UAAU,aAAa,QAAQ,SAAS,aAAa,EAAE,EAAG,OAAM,IAAI,MAAM,wDAAwD;AACrL,QAAI,CAAC,QAAQ,IAAI,EAAE,KAAK,QAAQ,QAAQ,aAAa;AAAE,eAAS;AAAG,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAAE;AAC/G,YAAQ,IAAI,EAAE;AAAA,EAChB;AACA,WAAS,UAAgB;AAAE,SAAK,QAAQ;AAAA,EAAE;AAC1C,SAAO,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAChE,MAAI,OAAO,QAAQ,QAAS,MAAK,QAAQ;AACzC,SAAO,EAAE,gBAAgB,kBAAkB,QAAQ,gBAAgB,QAAQ;AAC7E;;;ADtVO,IAAM,UAAU,oBAAoB,kBAAkB,EAAE;","names":["reply","request"]}
|
package/examples/README.md
CHANGED
|
@@ -17,7 +17,7 @@ const host = await startStdioHost({
|
|
|
17
17
|
apiKey: partnerApiKey,
|
|
18
18
|
tenantId: authenticatedTenantId,
|
|
19
19
|
externalId: authenticatedCustomerId,
|
|
20
|
-
codexVersion: '0.
|
|
20
|
+
codexVersion: '0.167.0',
|
|
21
21
|
maySendSubject: subject => privacyPolicy.allows(subject),
|
|
22
22
|
onEvent: event => audit.write(event),
|
|
23
23
|
},
|
|
@@ -16,7 +16,7 @@ try {
|
|
|
16
16
|
if (!address || typeof address === 'string') throw new Error('No local server address')
|
|
17
17
|
let resolveReply
|
|
18
18
|
const reply = new Promise(resolve => { resolveReply = resolve })
|
|
19
|
-
handler = createPusharyCodexHandler({ apiKey: 'pk_simulated.secret', tenantId: 'simulated-tenant', externalId: 'simulated-customer', baseUrl: `http://127.0.0.1:${address.port}`, codexVersion: '0.
|
|
19
|
+
handler = createPusharyCodexHandler({ apiKey: 'pk_simulated.secret', tenantId: 'simulated-tenant', externalId: 'simulated-customer', baseUrl: `http://127.0.0.1:${address.port}`, codexVersion: '0.167.0', maySendSubject: () => true, onEvent: event => console.log(event.type), sendResponse: resolveReply, requestTurnInterrupt: () => {} })
|
|
20
20
|
handler.registerThread({ thread: { id: 'simulated-thread', status: { type: 'idle' } }, approvalPolicy: 'on-request', approvalsReviewer: 'user', sandbox: { type: 'readOnly' } })
|
|
21
21
|
handler.handle({ id: 1, method: 'item/commandExecution/requestApproval', params: { threadId: 'simulated-thread', turnId: 'simulated-turn', itemId: 'simulated-item', command: 'echo simulated', cwd: '/tmp', startedAtMs: Date.now() } })
|
|
22
22
|
assert.deepEqual(await reply, { id: 1, result: { decision: 'accept' } })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pushary/codex-app-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Partner approvals for live Codex app-server sessions",
|
|
5
5
|
"author": "Pushary <business@pushary.com>",
|
|
6
6
|
"homepage": "https://github.com/Pushary/pushary-codex-app-server#readme",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"tsup": "^8.0.0",
|
|
52
52
|
"typescript": "^5.0.0",
|
|
53
53
|
"vitest": "^2.1.0",
|
|
54
|
-
"@openai/codex": "0.
|
|
54
|
+
"@openai/codex": "0.167.0",
|
|
55
55
|
"ajv": "^8.17.1"
|
|
56
56
|
},
|
|
57
57
|
"publishConfig": {
|