@gh-symphony/cli 0.0.20 → 0.0.21

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.
@@ -0,0 +1,684 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ buildAgentInputRequiredReason,
4
+ createGitHubGraphQLMcpServerEntry,
5
+ extractEnvForCodex,
6
+ readAgentCredentialCache,
7
+ readEnvFile,
8
+ resolveGitHubGraphQLToken,
9
+ shouldReuseAgentCredentialCache,
10
+ writeAgentCredentialCache
11
+ } from "./chunk-QEONJ5DZ.js";
12
+
13
+ // ../runtime-codex/src/runtime.ts
14
+ import { spawn } from "child_process";
15
+ import { copyFile, mkdir, readFile, writeFile } from "fs/promises";
16
+ import { join } from "path";
17
+ import { homedir } from "os";
18
+ import { fileURLToPath } from "url";
19
+ var DEFAULT_GITHUB_GIT_HOST = "github.com";
20
+ var DEFAULT_GITHUB_GIT_USERNAME = "x-access-token";
21
+ var STAGED_CODEX_HOME_DIRNAME = ".codex-agent";
22
+ var DIRECT_AGENT_ENV_KEYS = [
23
+ "OPENAI_API_KEY",
24
+ "OPENAI_BASE_URL",
25
+ "OPENAI_ORG_ID",
26
+ "OPENAI_PROJECT"
27
+ ];
28
+ var AgentRuntimeResolutionError = class extends Error {
29
+ };
30
+ var CODEX_PROTOCOL_EVENT_NAMES = {
31
+ turnStarted: "turn/started",
32
+ turnCompleted: "turn/completed",
33
+ turnFailed: "turn/failed",
34
+ turnCancelled: "turn/cancelled",
35
+ toolCallRequested: "dynamic_tool_call_request",
36
+ inputRequired: "item/tool/requestUserInput",
37
+ rateLimit: "turn/rate_limit",
38
+ messageDelta: "item/message/delta"
39
+ };
40
+ var CODEX_MESSAGE_DELTA_METHODS = /* @__PURE__ */ new Set([
41
+ CODEX_PROTOCOL_EVENT_NAMES.messageDelta,
42
+ "codex/event/agent_message_content_delta",
43
+ "codex/event/agent_message_delta",
44
+ "item/agentMessage/delta"
45
+ ]);
46
+ var CODEX_TOKEN_USAGE_METHODS = /* @__PURE__ */ new Set([
47
+ "thread/tokenUsage/updated",
48
+ "total_token_usage",
49
+ "codex/event/token_count"
50
+ ]);
51
+ function createGitHubGraphQLToolDefinition(config) {
52
+ const entry = createGitHubGraphQLMcpServerEntry(config);
53
+ return {
54
+ name: "github_graphql",
55
+ description: "Execute GitHub GraphQL queries for the active workspace so the agent can mutate project and issue state directly.",
56
+ command: entry.command,
57
+ args: entry.args,
58
+ env: entry.env,
59
+ inputSchema: {
60
+ type: "object",
61
+ properties: {
62
+ query: {
63
+ type: "string",
64
+ description: "GraphQL query or mutation document."
65
+ },
66
+ variables: {
67
+ type: "object",
68
+ description: "Variables for the GraphQL document."
69
+ },
70
+ operationName: {
71
+ type: "string",
72
+ description: "Optional GraphQL operation name."
73
+ }
74
+ },
75
+ required: ["query"],
76
+ additionalProperties: false
77
+ }
78
+ };
79
+ }
80
+ function asRecord(value) {
81
+ return value != null && typeof value === "object" ? value : {};
82
+ }
83
+ function hasOwn(record, key) {
84
+ return Object.prototype.hasOwnProperty.call(record, key);
85
+ }
86
+ function hasNestedRateLimitPayload(value) {
87
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
88
+ return false;
89
+ }
90
+ const record = value;
91
+ const directKeys = [
92
+ "limit",
93
+ "remaining",
94
+ "used",
95
+ "reset",
96
+ "resetAt",
97
+ "resets_at",
98
+ "reset_at"
99
+ ];
100
+ if (directKeys.some((key) => hasOwn(record, key))) {
101
+ return true;
102
+ }
103
+ const preferredKeys = [
104
+ "rate_limits",
105
+ "rateLimits",
106
+ "rate_limit",
107
+ "rateLimit",
108
+ "result"
109
+ ];
110
+ for (const key of preferredKeys) {
111
+ if (hasOwn(record, key) && hasNestedRateLimitPayload(record[key])) {
112
+ return true;
113
+ }
114
+ }
115
+ return false;
116
+ }
117
+ function getCodexObservabilityEventName(event) {
118
+ return event.payload.observabilityEvent;
119
+ }
120
+ function normalizeCodexRuntimeEvents(message) {
121
+ const method = typeof message.method === "string" ? message.method : void 0;
122
+ if (!method) {
123
+ return [];
124
+ }
125
+ const params = asRecord(message.params);
126
+ const events = [];
127
+ if (method === CODEX_PROTOCOL_EVENT_NAMES.turnStarted) {
128
+ events.push({
129
+ name: "agent.turnStarted",
130
+ payload: {
131
+ observabilityEvent: method,
132
+ params
133
+ }
134
+ });
135
+ return events;
136
+ }
137
+ if (method === CODEX_PROTOCOL_EVENT_NAMES.toolCallRequested) {
138
+ events.push({
139
+ name: "agent.toolCallRequested",
140
+ payload: {
141
+ observabilityEvent: method,
142
+ params,
143
+ callId: typeof params.callId === "string" ? params.callId : "",
144
+ toolName: typeof params.tool === "string" ? params.tool : "",
145
+ threadId: typeof params.threadId === "string" ? params.threadId : "",
146
+ turnId: typeof params.turnId === "string" ? params.turnId : "",
147
+ arguments: params.arguments
148
+ }
149
+ });
150
+ return events;
151
+ }
152
+ if (method === CODEX_PROTOCOL_EVENT_NAMES.inputRequired) {
153
+ events.push({
154
+ name: "agent.inputRequired",
155
+ payload: {
156
+ observabilityEvent: method,
157
+ params,
158
+ reason: buildAgentInputRequiredReason(params.prompt)
159
+ }
160
+ });
161
+ return events;
162
+ }
163
+ if (CODEX_TOKEN_USAGE_METHODS.has(method)) {
164
+ events.push({
165
+ name: "agent.tokenUsageUpdated",
166
+ payload: {
167
+ observabilityEvent: method,
168
+ params
169
+ }
170
+ });
171
+ return events;
172
+ }
173
+ if (CODEX_MESSAGE_DELTA_METHODS.has(method)) {
174
+ events.push({
175
+ name: "agent.messageDelta",
176
+ payload: {
177
+ observabilityEvent: method,
178
+ params,
179
+ delta: typeof params.delta === "string" ? params.delta : "",
180
+ itemId: typeof params.item_id === "string" ? params.item_id : ""
181
+ }
182
+ });
183
+ return events;
184
+ }
185
+ if (method === CODEX_PROTOCOL_EVENT_NAMES.rateLimit) {
186
+ events.push({
187
+ name: "agent.rateLimit",
188
+ payload: {
189
+ observabilityEvent: method,
190
+ params
191
+ }
192
+ });
193
+ return events;
194
+ }
195
+ if (method === CODEX_PROTOCOL_EVENT_NAMES.turnCompleted) {
196
+ if (hasOwn(params, "usage")) {
197
+ events.push({
198
+ name: "agent.tokenUsageUpdated",
199
+ payload: {
200
+ observabilityEvent: method,
201
+ params: asRecord(params.usage),
202
+ suppressUpdate: true
203
+ }
204
+ });
205
+ }
206
+ if (hasNestedRateLimitPayload(params)) {
207
+ events.push({
208
+ name: "agent.rateLimit",
209
+ payload: {
210
+ observabilityEvent: method,
211
+ params,
212
+ suppressUpdate: true
213
+ }
214
+ });
215
+ }
216
+ events.push({
217
+ name: "agent.turnCompleted",
218
+ payload: {
219
+ observabilityEvent: method,
220
+ params,
221
+ inputRequired: params.inputRequired === true
222
+ }
223
+ });
224
+ return events;
225
+ }
226
+ if (method === CODEX_PROTOCOL_EVENT_NAMES.turnFailed) {
227
+ events.push({
228
+ name: "agent.turnFailed",
229
+ payload: {
230
+ observabilityEvent: method,
231
+ params
232
+ }
233
+ });
234
+ return events;
235
+ }
236
+ if (method === CODEX_PROTOCOL_EVENT_NAMES.turnCancelled) {
237
+ events.push({
238
+ name: "agent.turnCancelled",
239
+ payload: {
240
+ observabilityEvent: method,
241
+ params
242
+ }
243
+ });
244
+ return events;
245
+ }
246
+ if (method === "error") {
247
+ events.push({
248
+ name: "agent.error",
249
+ payload: {
250
+ observabilityEvent: method,
251
+ params,
252
+ error: JSON.stringify(params)
253
+ }
254
+ });
255
+ return events;
256
+ }
257
+ return events;
258
+ }
259
+ function resolveStagedCodexHome(workingDirectory) {
260
+ return join(workingDirectory, STAGED_CODEX_HOME_DIRNAME);
261
+ }
262
+ function resolvePreparedAgentEnvironment(workingDirectory, env) {
263
+ const preparedEnv = Object.fromEntries(
264
+ DIRECT_AGENT_ENV_KEYS.flatMap((key) => {
265
+ const value = env?.[key];
266
+ return typeof value === "string" && value.length > 0 ? [[key, value]] : [];
267
+ })
268
+ );
269
+ return {
270
+ ...preparedEnv,
271
+ CODEX_HOME: resolveStagedCodexHome(workingDirectory)
272
+ };
273
+ }
274
+ function buildCodexRuntimePlan(config) {
275
+ const tool = createGitHubGraphQLToolDefinition(config);
276
+ const gitCredentialHelper = createGitCredentialHelperEnvironment(config);
277
+ const shellCmd = (() => {
278
+ const cmd = config.agentCommand ?? "codex app-server";
279
+ return cmd.startsWith("bash -lc ") ? cmd.slice("bash -lc ".length) : cmd;
280
+ })();
281
+ const agentEnv = resolvePreparedAgentEnvironment(
282
+ config.workingDirectory,
283
+ config.agentEnv
284
+ );
285
+ return {
286
+ cwd: config.workingDirectory,
287
+ command: "bash",
288
+ args: ["-lc", shellCmd],
289
+ env: {
290
+ ...process.env,
291
+ ...config.extraEnv,
292
+ ...config.agentEnv,
293
+ CODEX_PROJECT_ID: config.projectId,
294
+ GITHUB_PROJECT_ID: config.githubProjectId ?? "",
295
+ GITHUB_GRAPHQL_TOOL_NAME: tool.name,
296
+ GITHUB_GRAPHQL_TOOL_COMMAND: [tool.command, ...tool.args].join(" "),
297
+ ...agentEnv,
298
+ ...gitCredentialHelper,
299
+ ...tool.env
300
+ },
301
+ tools: [tool]
302
+ };
303
+ }
304
+ function launchCodexAppServer(plan, spawnImpl = spawn) {
305
+ return spawnImpl(plan.command, plan.args, {
306
+ cwd: plan.cwd,
307
+ env: plan.env,
308
+ stdio: "pipe"
309
+ });
310
+ }
311
+ var CodexRuntimeAdapter = class {
312
+ constructor(config, dependencies = {}) {
313
+ this.config = config;
314
+ this.dependencies = dependencies;
315
+ }
316
+ // Event emission is intentionally deferred until the worker-owned loop is
317
+ // neutralized in #4. Until then, keep handler registration compatible.
318
+ handlers = /* @__PURE__ */ new Set();
319
+ plan = null;
320
+ child = null;
321
+ async prepare(_context) {
322
+ if (this.plan) {
323
+ return;
324
+ }
325
+ const agentEnv = await resolveAgentRuntimeEnvironment(
326
+ this.config,
327
+ this.dependencies,
328
+ this
329
+ );
330
+ await stageCodexHome(this.config, this.dependencies);
331
+ this.plan = buildCodexRuntimePlan({
332
+ ...this.config,
333
+ agentEnv
334
+ });
335
+ }
336
+ async spawnTurn(_input) {
337
+ if (!this.plan) {
338
+ await this.prepare();
339
+ }
340
+ if (!this.plan) {
341
+ throw new AgentRuntimeResolutionError(
342
+ "Codex runtime plan was not prepared before spawnTurn."
343
+ );
344
+ }
345
+ if (!hasRunningChild(this.child)) {
346
+ this.child = launchCodexAppServer(
347
+ this.plan,
348
+ this.dependencies.spawnImpl ?? spawn
349
+ );
350
+ }
351
+ return {
352
+ plan: this.plan,
353
+ child: this.child
354
+ };
355
+ }
356
+ onEvent(handler) {
357
+ this.handlers.add(handler);
358
+ return () => {
359
+ this.handlers.delete(handler);
360
+ };
361
+ }
362
+ resolveCredentials(brokerResponse) {
363
+ return resolvePreparedAgentEnvironment(
364
+ this.config.workingDirectory,
365
+ brokerResponse.env
366
+ );
367
+ }
368
+ async shutdown() {
369
+ terminateChildProcess(this.child);
370
+ this.child = null;
371
+ this.handlers.clear();
372
+ }
373
+ async cancel(_reason) {
374
+ terminateChildProcess(this.child);
375
+ this.child = null;
376
+ this.handlers.clear();
377
+ }
378
+ getPreparedPlan() {
379
+ return this.plan;
380
+ }
381
+ };
382
+ function createCodexRuntimeAdapter(config, dependencies = {}) {
383
+ return new CodexRuntimeAdapter(config, dependencies);
384
+ }
385
+ async function prepareCodexRuntimePlan(config, dependencies = {}) {
386
+ const adapter = createCodexRuntimeAdapter(config, dependencies);
387
+ await adapter.prepare();
388
+ const plan = adapter.getPreparedPlan();
389
+ if (!plan) {
390
+ throw new AgentRuntimeResolutionError(
391
+ "Codex runtime plan was not prepared."
392
+ );
393
+ }
394
+ return plan;
395
+ }
396
+ function createGitCredentialHelperEnvironment(config) {
397
+ return {
398
+ GITHUB_GIT_HOST: DEFAULT_GITHUB_GIT_HOST,
399
+ GITHUB_GIT_USERNAME: DEFAULT_GITHUB_GIT_USERNAME,
400
+ GIT_TERMINAL_PROMPT: "0",
401
+ GIT_CONFIG_COUNT: "1",
402
+ GIT_CONFIG_KEY_0: "credential.helper",
403
+ GIT_CONFIG_VALUE_0: `!node ${fileURLToPath(
404
+ new URL("./git-credential-helper.js", import.meta.url)
405
+ )}`,
406
+ ...config.githubToken ? {
407
+ GITHUB_GRAPHQL_TOKEN: config.githubToken
408
+ } : {},
409
+ ...config.githubTokenBrokerUrl ? {
410
+ GITHUB_TOKEN_BROKER_URL: config.githubTokenBrokerUrl
411
+ } : {},
412
+ ...config.githubTokenBrokerSecret ? {
413
+ GITHUB_TOKEN_BROKER_SECRET: config.githubTokenBrokerSecret
414
+ } : {},
415
+ ...config.githubTokenCachePath ? {
416
+ GITHUB_TOKEN_CACHE_PATH: config.githubTokenCachePath
417
+ } : {}
418
+ };
419
+ }
420
+ async function resolveAgentRuntimeEnvironment(config, dependencies = {}, adapter) {
421
+ if (config.agentEnv) {
422
+ return resolveRuntimeCredentials(config, { env: config.agentEnv }, adapter);
423
+ }
424
+ if (!config.agentCredentialBrokerUrl || !config.agentCredentialBrokerSecret) {
425
+ return resolvePreparedAgentEnvironment(config.workingDirectory);
426
+ }
427
+ const now = dependencies.now ?? /* @__PURE__ */ new Date();
428
+ const readFileImpl = dependencies.readFileImpl ?? readFile;
429
+ const cachedCredentials = config.agentCredentialCachePath ? await readAgentCredentialCache(config.agentCredentialCachePath, readFileImpl) : null;
430
+ if (cachedCredentials && shouldReuseAgentCredentialCache(cachedCredentials, now)) {
431
+ return resolveRuntimeCredentials(config, cachedCredentials, adapter);
432
+ }
433
+ const fetchImpl = dependencies.fetchImpl ?? fetch;
434
+ const response = await fetchImpl(config.agentCredentialBrokerUrl, {
435
+ method: "POST",
436
+ headers: {
437
+ accept: "application/json",
438
+ authorization: `Bearer ${config.agentCredentialBrokerSecret}`
439
+ }
440
+ });
441
+ const payload = await response.json();
442
+ const resolvedEnv = payload.env && response.ok ? adapter ? adapter.resolveCredentials({
443
+ env: payload.env,
444
+ expires_at: payload.expires_at
445
+ }) : resolvePreparedAgentEnvironment(config.workingDirectory, payload.env) : null;
446
+ if (!response.ok || !payload.env || Object.keys(payload.env).length === 0 || !resolvedEnv) {
447
+ throw new AgentRuntimeResolutionError(
448
+ payload.error ?? `Agent credential broker request failed with status ${response.status}.`
449
+ );
450
+ }
451
+ if (config.agentCredentialCachePath) {
452
+ const writeFileImpl = dependencies.writeFileImpl ?? writeFile;
453
+ await writeAgentCredentialCache(
454
+ config.agentCredentialCachePath,
455
+ payload,
456
+ writeFileImpl,
457
+ now
458
+ );
459
+ }
460
+ return resolvedEnv;
461
+ }
462
+ function resolveRuntimeCredentials(config, brokerResponse, adapter) {
463
+ return adapter ? adapter.resolveCredentials(brokerResponse) : resolvePreparedAgentEnvironment(config.workingDirectory, brokerResponse.env);
464
+ }
465
+ async function stageCodexHome(config, dependencies = {}) {
466
+ const codexHomeDir = resolveStagedCodexHome(config.workingDirectory);
467
+ const mkdirImpl = dependencies.mkdirImpl ?? mkdir;
468
+ await mkdirImpl(codexHomeDir, { recursive: true });
469
+ const writeFileImpl = dependencies.writeFileImpl ?? writeFile;
470
+ await writeFileImpl(
471
+ join(codexHomeDir, "config.toml"),
472
+ "# Isolated agent config \u2014 no personal MCP servers\n",
473
+ "utf8"
474
+ );
475
+ const realCodexHome = process.env.CODEX_HOME ?? join(homedir(), ".codex");
476
+ const copyFileImpl = dependencies.copyFileImpl ?? copyFile;
477
+ try {
478
+ await copyFileImpl(
479
+ join(realCodexHome, "auth.json"),
480
+ join(codexHomeDir, "auth.json")
481
+ );
482
+ } catch {
483
+ }
484
+ }
485
+ function hasRunningChild(child) {
486
+ return child !== null && child.exitCode === null && child.signalCode === null;
487
+ }
488
+ function terminateChildProcess(child) {
489
+ if (!hasRunningChild(child) || !child.pid) {
490
+ return;
491
+ }
492
+ try {
493
+ child.kill("SIGTERM");
494
+ } catch {
495
+ }
496
+ }
497
+
498
+ // ../runtime-codex/src/launcher.ts
499
+ import { dirname, resolve } from "path";
500
+ import { fileURLToPath as fileURLToPath2 } from "url";
501
+ var LocalRuntimeLauncherError = class extends Error {
502
+ };
503
+ function resolveLocalRuntimeLaunchConfig(env = process.env) {
504
+ const projectId = env.PROJECT_ID ?? env.CODEX_PROJECT_ID;
505
+ const workingDirectory = env.WORKING_DIRECTORY;
506
+ if (!projectId) {
507
+ throw new LocalRuntimeLauncherError(
508
+ "PROJECT_ID or CODEX_PROJECT_ID is required."
509
+ );
510
+ }
511
+ if (!workingDirectory) {
512
+ throw new LocalRuntimeLauncherError("WORKING_DIRECTORY is required.");
513
+ }
514
+ return {
515
+ projectId,
516
+ workingDirectory,
517
+ githubToken: env.GITHUB_GRAPHQL_TOKEN,
518
+ githubTokenBrokerUrl: env.GITHUB_TOKEN_BROKER_URL,
519
+ githubTokenBrokerSecret: env.GITHUB_TOKEN_BROKER_SECRET,
520
+ githubTokenCachePath: env.GITHUB_TOKEN_CACHE_PATH,
521
+ agentEnv: readDirectAgentEnvironment(env),
522
+ agentCredentialBrokerUrl: env.AGENT_CREDENTIAL_BROKER_URL,
523
+ agentCredentialBrokerSecret: env.AGENT_CREDENTIAL_BROKER_SECRET,
524
+ agentCredentialCachePath: env.AGENT_CREDENTIAL_CACHE_PATH,
525
+ githubProjectId: env.GITHUB_PROJECT_ID,
526
+ githubGraphqlApiUrl: env.GITHUB_GRAPHQL_API_URL,
527
+ agentCommand: env.SYMPHONY_AGENT_COMMAND
528
+ };
529
+ }
530
+ async function runLocalRuntimeLauncher(env = process.env) {
531
+ const launcherEnv = loadLauncherEnvironment(env);
532
+ const config = resolveLocalRuntimeLaunchConfig(launcherEnv);
533
+ const plan = await prepareCodexRuntimePlan(config);
534
+ emitLaunchSummary(config);
535
+ const child = launchCodexAppServer(plan);
536
+ process.stdout.write(
537
+ `[worker] codex app-server started (pid: ${child.pid ?? "unknown"})
538
+ `
539
+ );
540
+ child.stdout?.pipe(process.stdout);
541
+ child.stderr?.pipe(process.stderr);
542
+ return await waitForChildProcess(child);
543
+ }
544
+ function loadLauncherEnvironment(env = process.env, cwd = process.cwd()) {
545
+ const mergedEnv = {
546
+ ...readEnvFile(
547
+ resolve(dirname(fileURLToPath2(import.meta.url)), "..", ".env")
548
+ ),
549
+ ...readEnvFile(resolve(cwd, ".env")),
550
+ ...env
551
+ };
552
+ return mergedEnv;
553
+ }
554
+ function readDirectAgentEnvironment(env) {
555
+ const agentEnv = extractEnvForCodex(env);
556
+ return Object.keys(agentEnv).length ? agentEnv : void 0;
557
+ }
558
+ function waitForChildProcess(child) {
559
+ return new Promise((resolve2, reject) => {
560
+ child.once("error", reject);
561
+ child.once("exit", (code, signal) => {
562
+ if (signal) {
563
+ reject(
564
+ new LocalRuntimeLauncherError(`codex app-server exited on ${signal}.`)
565
+ );
566
+ return;
567
+ }
568
+ resolve2(code ?? 0);
569
+ });
570
+ });
571
+ }
572
+ async function main() {
573
+ const exitCode = await runLocalRuntimeLauncher(process.env);
574
+ process.exitCode = exitCode;
575
+ }
576
+ if (import.meta.url === new URL(process.argv[1] ?? "", "file:").href) {
577
+ main().catch((error) => {
578
+ const message = error instanceof Error ? error.message : "Unknown error";
579
+ process.stderr.write(`${message}
580
+ `);
581
+ process.exitCode = 1;
582
+ });
583
+ }
584
+ function emitLaunchSummary(config) {
585
+ const githubAuthMode = config.githubToken ? "direct token" : config.githubTokenBrokerUrl && config.githubTokenBrokerSecret ? "broker" : "missing";
586
+ const agentAuthMode = config.agentEnv?.OPENAI_API_KEY ? "direct env" : config.agentCredentialBrokerUrl && config.agentCredentialBrokerSecret ? "broker" : "local codex auth or inherited environment";
587
+ process.stdout.write(
588
+ [
589
+ "[worker] starting local codex runtime",
590
+ `[worker] project: ${config.projectId}`,
591
+ `[worker] cwd: ${config.workingDirectory}`,
592
+ `[worker] github project: ${config.githubProjectId ?? "(unset)"}`,
593
+ `[worker] github auth: ${githubAuthMode}`,
594
+ `[worker] agent auth: ${agentAuthMode}`,
595
+ "[worker] note: codex app-server does not proactively read GitHub issues.",
596
+ "[worker] note: it waits for a client request or tool invocation."
597
+ ].join("\n") + "\n"
598
+ );
599
+ }
600
+
601
+ // ../runtime-codex/src/git-credential-helper.ts
602
+ var DEFAULT_GITHUB_GIT_HOST2 = "github.com";
603
+ var DEFAULT_GITHUB_GIT_USERNAME2 = "x-access-token";
604
+ async function resolveGitCredential(request, config, fetchImpl = fetch) {
605
+ const requestHost = request.host?.trim();
606
+ const requestProtocol = request.protocol?.trim();
607
+ if (!requestHost || requestProtocol && requestProtocol !== "https") {
608
+ return "";
609
+ }
610
+ const expectedHost = normalizeGitHost(
611
+ config.gitHost ?? DEFAULT_GITHUB_GIT_HOST2
612
+ );
613
+ if (normalizeGitHost(requestHost) !== expectedHost) {
614
+ return "";
615
+ }
616
+ const token = await resolveGitHubGraphQLToken(config, {
617
+ fetchImpl
618
+ });
619
+ return formatGitCredentialResponse({
620
+ protocol: requestProtocol || "https",
621
+ host: requestHost,
622
+ username: config.gitUsername ?? DEFAULT_GITHUB_GIT_USERNAME2,
623
+ password: token
624
+ });
625
+ }
626
+ function parseGitCredentialRequest(rawInput) {
627
+ return rawInput.split("\n").map((line) => line.trim()).filter(Boolean).reduce((request, line) => {
628
+ const separatorIndex = line.indexOf("=");
629
+ if (separatorIndex === -1) {
630
+ return request;
631
+ }
632
+ const key = line.slice(0, separatorIndex);
633
+ const value = line.slice(separatorIndex + 1);
634
+ request[key] = value;
635
+ return request;
636
+ }, {});
637
+ }
638
+ function formatGitCredentialResponse(value) {
639
+ return `${Object.entries(value).map(([key, entry]) => `${key}=${entry}`).join("\n")}
640
+
641
+ `;
642
+ }
643
+ async function readStdin() {
644
+ const chunks = [];
645
+ for await (const chunk of process.stdin) {
646
+ chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
647
+ }
648
+ return Buffer.concat(chunks).toString("utf8");
649
+ }
650
+ async function main2() {
651
+ const request = parseGitCredentialRequest(await readStdin());
652
+ const response = await resolveGitCredential(request, {
653
+ token: process.env.GITHUB_GRAPHQL_TOKEN,
654
+ tokenBrokerUrl: process.env.GITHUB_TOKEN_BROKER_URL,
655
+ tokenBrokerSecret: process.env.GITHUB_TOKEN_BROKER_SECRET,
656
+ tokenCachePath: process.env.GITHUB_TOKEN_CACHE_PATH,
657
+ gitHost: process.env.GITHUB_GIT_HOST,
658
+ gitUsername: process.env.GITHUB_GIT_USERNAME
659
+ });
660
+ process.stdout.write(response);
661
+ }
662
+ if (import.meta.url === new URL(process.argv[1] ?? "", "file:").href) {
663
+ main2().catch((error) => {
664
+ const message = error instanceof Error ? error.message : "Unknown error";
665
+ process.stderr.write(`${message}
666
+ `);
667
+ process.exitCode = 1;
668
+ });
669
+ }
670
+ function normalizeGitHost(host) {
671
+ return host.trim().toLowerCase();
672
+ }
673
+
674
+ // ../runtime-codex/src/convergence-detection.ts
675
+ import { spawnSync } from "child_process";
676
+
677
+ export {
678
+ getCodexObservabilityEventName,
679
+ normalizeCodexRuntimeEvents,
680
+ launchCodexAppServer,
681
+ prepareCodexRuntimePlan,
682
+ resolveLocalRuntimeLaunchConfig,
683
+ loadLauncherEnvironment
684
+ };