@autohq/cli 0.1.89 → 0.1.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -257,10 +257,10 @@ function mergeDefs(...defs) {
257
257
  function cloneDef(schema) {
258
258
  return mergeDefs(schema._zod.def);
259
259
  }
260
- function getElementAtPath(obj, path) {
261
- if (!path)
260
+ function getElementAtPath(obj, path2) {
261
+ if (!path2)
262
262
  return obj;
263
- return path.reduce((acc, key) => acc?.[key], obj);
263
+ return path2.reduce((acc, key) => acc?.[key], obj);
264
264
  }
265
265
  function promiseAllObject(promisesObj) {
266
266
  const keys = Object.keys(promisesObj);
@@ -588,11 +588,11 @@ function explicitlyAborted(x, startIndex = 0) {
588
588
  }
589
589
  return false;
590
590
  }
591
- function prefixIssues(path, issues) {
591
+ function prefixIssues(path2, issues) {
592
592
  return issues.map((iss) => {
593
593
  var _a3;
594
594
  (_a3 = iss).path ?? (_a3.path = []);
595
- iss.path.unshift(path);
595
+ iss.path.unshift(path2);
596
596
  return iss;
597
597
  });
598
598
  }
@@ -810,16 +810,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
810
810
  }
811
811
  function formatError(error51, mapper = (issue2) => issue2.message) {
812
812
  const fieldErrors = { _errors: [] };
813
- const processError = (error52, path = []) => {
813
+ const processError = (error52, path2 = []) => {
814
814
  for (const issue2 of error52.issues) {
815
815
  if (issue2.code === "invalid_union" && issue2.errors.length) {
816
- issue2.errors.map((issues) => processError({ issues }, [...path, ...issue2.path]));
816
+ issue2.errors.map((issues) => processError({ issues }, [...path2, ...issue2.path]));
817
817
  } else if (issue2.code === "invalid_key") {
818
- processError({ issues: issue2.issues }, [...path, ...issue2.path]);
818
+ processError({ issues: issue2.issues }, [...path2, ...issue2.path]);
819
819
  } else if (issue2.code === "invalid_element") {
820
- processError({ issues: issue2.issues }, [...path, ...issue2.path]);
820
+ processError({ issues: issue2.issues }, [...path2, ...issue2.path]);
821
821
  } else {
822
- const fullpath = [...path, ...issue2.path];
822
+ const fullpath = [...path2, ...issue2.path];
823
823
  if (fullpath.length === 0) {
824
824
  fieldErrors._errors.push(mapper(issue2));
825
825
  } else {
@@ -846,17 +846,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
846
846
  }
847
847
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
848
848
  const result = { errors: [] };
849
- const processError = (error52, path = []) => {
849
+ const processError = (error52, path2 = []) => {
850
850
  var _a3, _b;
851
851
  for (const issue2 of error52.issues) {
852
852
  if (issue2.code === "invalid_union" && issue2.errors.length) {
853
- issue2.errors.map((issues) => processError({ issues }, [...path, ...issue2.path]));
853
+ issue2.errors.map((issues) => processError({ issues }, [...path2, ...issue2.path]));
854
854
  } else if (issue2.code === "invalid_key") {
855
- processError({ issues: issue2.issues }, [...path, ...issue2.path]);
855
+ processError({ issues: issue2.issues }, [...path2, ...issue2.path]);
856
856
  } else if (issue2.code === "invalid_element") {
857
- processError({ issues: issue2.issues }, [...path, ...issue2.path]);
857
+ processError({ issues: issue2.issues }, [...path2, ...issue2.path]);
858
858
  } else {
859
- const fullpath = [...path, ...issue2.path];
859
+ const fullpath = [...path2, ...issue2.path];
860
860
  if (fullpath.length === 0) {
861
861
  result.errors.push(mapper(issue2));
862
862
  continue;
@@ -888,8 +888,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
888
888
  }
889
889
  function toDotPath(_path) {
890
890
  const segs = [];
891
- const path = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
892
- for (const seg of path) {
891
+ const path2 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
892
+ for (const seg of path2) {
893
893
  if (typeof seg === "number")
894
894
  segs.push(`[${seg}]`);
895
895
  else if (typeof seg === "symbol")
@@ -14392,13 +14392,13 @@ function resolveRef(ref, ctx) {
14392
14392
  if (!ref.startsWith("#")) {
14393
14393
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14394
14394
  }
14395
- const path = ref.slice(1).split("/").filter(Boolean);
14396
- if (path.length === 0) {
14395
+ const path2 = ref.slice(1).split("/").filter(Boolean);
14396
+ if (path2.length === 0) {
14397
14397
  return ctx.rootSchema;
14398
14398
  }
14399
14399
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14400
- if (path[0] === defsKey) {
14401
- const key = path[1];
14400
+ if (path2[0] === defsKey) {
14401
+ const key = path2[1];
14402
14402
  if (!key || !ctx.defs[key]) {
14403
14403
  throw new Error(`Reference not found: ${ref}`);
14404
14404
  }
@@ -15223,6 +15223,8 @@ var init_auth = __esm({
15223
15223
  "secrets:read",
15224
15224
  "secrets:write",
15225
15225
  "secrets:use",
15226
+ "github:mcp",
15227
+ "github:credentials",
15226
15228
  "projects:admin",
15227
15229
  "org:admin"
15228
15230
  ]);
@@ -16413,6 +16415,100 @@ var init_connections = __esm({
16413
16415
  }
16414
16416
  });
16415
16417
 
16418
+ // ../../packages/schemas/src/github-credentials.ts
16419
+ var CreateRunGithubCredentialRequestSchema, RunGithubCredentialResponseSchema;
16420
+ var init_github_credentials = __esm({
16421
+ "../../packages/schemas/src/github-credentials.ts"() {
16422
+ "use strict";
16423
+ init_zod();
16424
+ CreateRunGithubCredentialRequestSchema = external_exports.object({
16425
+ host: external_exports.literal("github.com"),
16426
+ path: external_exports.string().trim().min(1).optional()
16427
+ });
16428
+ RunGithubCredentialResponseSchema = external_exports.object({
16429
+ username: external_exports.literal("x-access-token"),
16430
+ password: external_exports.string().min(1),
16431
+ expiresAt: external_exports.string().datetime()
16432
+ });
16433
+ }
16434
+ });
16435
+
16436
+ // ../../packages/schemas/src/github-mcp-catalog.ts
16437
+ var GITHUB_MCP_TOOL_NAMES, GITHUB_MCP_WRITE_TOOLS, githubMcpToolNameSet, githubMcpWriteToolSet;
16438
+ var init_github_mcp_catalog = __esm({
16439
+ "../../packages/schemas/src/github-mcp-catalog.ts"() {
16440
+ "use strict";
16441
+ GITHUB_MCP_TOOL_NAMES = [
16442
+ "actions_get",
16443
+ "actions_list",
16444
+ "actions_run_trigger",
16445
+ "add_comment_to_pending_review",
16446
+ "add_issue_comment",
16447
+ "add_reply_to_pull_request_comment",
16448
+ "create_branch",
16449
+ "create_or_update_file",
16450
+ "create_pull_request",
16451
+ "create_repository",
16452
+ "delete_file",
16453
+ "fork_repository",
16454
+ "get_commit",
16455
+ "get_file_contents",
16456
+ "get_job_logs",
16457
+ "get_label",
16458
+ "get_latest_release",
16459
+ "get_release_by_tag",
16460
+ "get_tag",
16461
+ "issue_read",
16462
+ "issue_write",
16463
+ "list_branches",
16464
+ "list_commits",
16465
+ "list_issue_types",
16466
+ "list_issues",
16467
+ "list_pull_requests",
16468
+ "list_releases",
16469
+ "list_repository_collaborators",
16470
+ "list_tags",
16471
+ "merge_pull_request",
16472
+ "pull_request_read",
16473
+ "pull_request_review_write",
16474
+ "push_files",
16475
+ "search_code",
16476
+ "search_commits",
16477
+ "search_issues",
16478
+ "search_pull_requests",
16479
+ "search_repositories",
16480
+ "sub_issue_write",
16481
+ "update_pull_request",
16482
+ "update_pull_request_branch"
16483
+ ];
16484
+ GITHUB_MCP_WRITE_TOOLS = [
16485
+ "actions_run_trigger",
16486
+ "add_comment_to_pending_review",
16487
+ "add_issue_comment",
16488
+ "add_reply_to_pull_request_comment",
16489
+ "create_branch",
16490
+ "create_or_update_file",
16491
+ "create_pull_request",
16492
+ "create_repository",
16493
+ "delete_file",
16494
+ "fork_repository",
16495
+ "issue_write",
16496
+ "merge_pull_request",
16497
+ "pull_request_review_write",
16498
+ "push_files",
16499
+ "sub_issue_write",
16500
+ "update_pull_request",
16501
+ "update_pull_request_branch"
16502
+ ];
16503
+ githubMcpToolNameSet = new Set(
16504
+ GITHUB_MCP_TOOL_NAMES
16505
+ );
16506
+ githubMcpWriteToolSet = new Set(
16507
+ GITHUB_MCP_WRITE_TOOLS
16508
+ );
16509
+ }
16510
+ });
16511
+
16416
16512
  // ../../packages/schemas/src/secrets.ts
16417
16513
  var SECRET_ENCRYPTION_ALGORITHM, SecretEnvNameSchema, SecretCiphertextFieldSchema, SecretAesGcmIvSchema, SecretAesGcmAuthTagSchema, SecretEnvValueSchema, SecretEnvSchema, EncryptedSecretValueSchema, SecretSetRequestSchema, SecretMetadataSchema, SecretSetResponseSchema, SecretListResponseSchema, SecretDeleteResponseSchema;
16418
16514
  var init_secrets = __esm({
@@ -16600,7 +16696,7 @@ var init_mcp = __esm({
16600
16696
  });
16601
16697
 
16602
16698
  // ../../packages/schemas/src/mounts.ts
16603
- var AbsoluteMountPathSchema, GITHUB_MOUNT_CAPABILITY_LEVELS, GithubMountCapabilityLevelSchema, GitMountAuthSchema, GitMountSchema, SessionMountSchema;
16699
+ var AbsoluteMountPathSchema, GITHUB_MOUNT_CAPABILITY_LEVELS, GithubMountCapabilityLevelSchema, DEFAULT_GITHUB_MOUNT_CAPABILITIES, GitMountAuthSchema, GitMountSchema, SessionMountSchema;
16604
16700
  var init_mounts = __esm({
16605
16701
  "../../packages/schemas/src/mounts.ts"() {
16606
16702
  "use strict";
@@ -16616,6 +16712,14 @@ var init_mounts = __esm({
16616
16712
  GithubMountCapabilityLevelSchema = external_exports.enum(
16617
16713
  GITHUB_MOUNT_CAPABILITY_LEVELS
16618
16714
  );
16715
+ DEFAULT_GITHUB_MOUNT_CAPABILITIES = {
16716
+ contents: "write",
16717
+ pullRequests: "write",
16718
+ issues: "write",
16719
+ checks: "read",
16720
+ actions: "read",
16721
+ workflows: "none"
16722
+ };
16619
16723
  GitMountAuthSchema = external_exports.discriminatedUnion("kind", [
16620
16724
  external_exports.object({
16621
16725
  kind: external_exports.literal("none")
@@ -16636,14 +16740,7 @@ var init_mounts = __esm({
16636
16740
  checks: GithubMountCapabilityLevelSchema.default("read"),
16637
16741
  actions: GithubMountCapabilityLevelSchema.default("read"),
16638
16742
  workflows: GithubMountCapabilityLevelSchema.default("none")
16639
- }).default({
16640
- contents: "write",
16641
- pullRequests: "write",
16642
- issues: "write",
16643
- checks: "read",
16644
- actions: "read",
16645
- workflows: "none"
16646
- })
16743
+ }).default({ ...DEFAULT_GITHUB_MOUNT_CAPABILITIES })
16647
16744
  })
16648
16745
  ]);
16649
16746
  GitMountSchema = external_exports.object({
@@ -16759,12 +16856,13 @@ function remoteMcpToolSchema(input) {
16759
16856
  ]).default({ kind: "none" })
16760
16857
  });
16761
16858
  }
16762
- var RESOURCE_KIND_TOOL, REMOTE_MCP_TRANSPORTS, LOCAL_TOOL_IMPLEMENTATIONS, SecretReferenceSchema, NoToolAuthSchema, McpOAuthToolAuthSchema, ConnectionToolAuthSchema, ConnectionsToolAuthSchema, ToolAliasSchema, RemoteMcpToolSchema, LocalAutoToolSchema, LocalPingToolSchema, LocalChatToolSchema, LocalToolSchema, ToolSpecSchema, ToolResourceSchema, ToolApplyRequestSchema, ToolConnectRequestSchema, ToolConnectResponseSchema, ToolConnectCompleteResponseSchema, ReferencedSessionToolRefSchema, ReferencedSessionToolRefsSchema, InlineSessionToolSchema, SessionToolRefSchema, SessionToolsSchema;
16859
+ var RESOURCE_KIND_TOOL, REMOTE_MCP_TRANSPORTS, LOCAL_TOOL_IMPLEMENTATIONS, SecretReferenceSchema, NoToolAuthSchema, McpOAuthToolAuthSchema, ConnectionToolAuthSchema, ConnectionsToolAuthSchema, ToolAliasSchema, RemoteMcpToolSchema, LocalAutoToolSchema, LocalPingToolSchema, LocalChatToolSchema, LocalToolSchema, GithubToolSchema, ToolSpecSchema, ToolResourceSchema, ToolApplyRequestSchema, ToolConnectRequestSchema, ToolConnectResponseSchema, ToolConnectCompleteResponseSchema, ReferencedSessionToolRefSchema, ReferencedSessionToolRefsSchema, InlineSessionToolSchema, SessionToolRefSchema, SessionToolsSchema;
16763
16860
  var init_tools = __esm({
16764
16861
  "../../packages/schemas/src/tools.ts"() {
16765
16862
  "use strict";
16766
16863
  init_zod();
16767
16864
  init_connections();
16865
+ init_github_mcp_catalog();
16768
16866
  init_ids();
16769
16867
  init_resources();
16770
16868
  RESOURCE_KIND_TOOL = "tool";
@@ -16822,6 +16920,11 @@ var init_tools = __esm({
16822
16920
  error: `Unsupported local tool implementation. Supported implementations: ${LOCAL_TOOL_IMPLEMENTATIONS.join(", ")}`
16823
16921
  }
16824
16922
  );
16923
+ GithubToolSchema = external_exports.object({
16924
+ kind: external_exports.literal("github"),
16925
+ description: external_exports.string().trim().min(1).optional(),
16926
+ tools: external_exports.array(external_exports.enum(GITHUB_MCP_TOOL_NAMES)).min(1).optional()
16927
+ });
16825
16928
  ToolSpecSchema = external_exports.discriminatedUnion("kind", [
16826
16929
  RemoteMcpToolSchema,
16827
16930
  LocalToolSchema
@@ -16871,6 +16974,10 @@ var init_tools = __esm({
16871
16974
  disabled: external_exports.boolean().optional()
16872
16975
  })
16873
16976
  )
16977
+ ).or(
16978
+ GithubToolSchema.extend({
16979
+ disabled: external_exports.boolean().optional()
16980
+ })
16874
16981
  );
16875
16982
  SessionToolRefSchema = InlineSessionToolSchema.or(
16876
16983
  ReferencedSessionToolRefSchema
@@ -17133,8 +17240,8 @@ function hasAutoAttributionsExists(trigger, expected) {
17133
17240
  function isChatMessageEvent(trigger) {
17134
17241
  return trigger.event.startsWith("chat.message.");
17135
17242
  }
17136
- function hasFilterValue(trigger, path, expected) {
17137
- return trigger.where?.[path] === expected;
17243
+ function hasFilterValue(trigger, path2, expected) {
17244
+ return trigger.where?.[path2] === expected;
17138
17245
  }
17139
17246
  var RESOURCE_KIND_SESSION, TriggerFilterScalarSchema, TriggerFilterPathSchema, TriggerFilterClauseSchema, TriggerFilterSchema, SessionTriggerCheckTimeoutSchema, TriggerEventSchema, TriggerEventsSchema, SessionTriggerSharedFields, SessionTriggerEventSourceFields, SessionTriggerBaseSchema, SessionTriggerDefinitionBaseSchema, SessionTriggerSchema, SessionApplyTriggerSchema, SessionHeartbeatTriggerBaseSchema, SessionHeartbeatTriggerSchema, SessionApplyHeartbeatTriggerSchema, SessionTriggerDefinitionSchema, SessionApplyTriggerDefinitionSchema, SessionTriggersSchema, SessionApplyTriggersSchema, AVATAR_ASSET_EXTENSIONS, MAX_AVATAR_ASSET_BYTES, SESSION_IDENTITY_DESCRIPTION_MAX_LENGTH, SHA256_HEX_PATTERN, SessionIdentitySchema, SessionSpecSchema, SessionApplySpecSchema, SessionStatusSchema, SessionResourceSchema, SessionApplyRequestSchema, SessionApplyTriggerReceiptSchema, SessionApplyResponseSchema, SESSION_TELEGRAM_IDENTITY_STATUSES, SessionTelegramIdentityStatusSchema, SessionPresenceIdentitySchema, SessionPresenceResponseSchema, SessionPresenceConnectRequestSchema, SessionPresenceConnectPendingSchema, SessionPresenceConnectResponseSchema, SessionPresenceIconRequestSchema, SessionPresenceIconResponseSchema, SessionPresenceCompleteResponseSchema;
17140
17247
  var init_sessions = __esm({
@@ -17156,17 +17263,17 @@ var init_sessions = __esm({
17156
17263
  external_exports.boolean()
17157
17264
  ]);
17158
17265
  TriggerFilterPathSchema = external_exports.string().refine(
17159
- (path) => {
17160
- if (path.length === 0 || path.trim() !== path) {
17266
+ (path2) => {
17267
+ if (path2.length === 0 || path2.trim() !== path2) {
17161
17268
  return false;
17162
17269
  }
17163
- if (path.startsWith("$.")) {
17164
- const segments = path.slice(2).split(".");
17270
+ if (path2.startsWith("$.")) {
17271
+ const segments = path2.slice(2).split(".");
17165
17272
  return segments.length > 0 && segments.every(
17166
17273
  (segment) => segment.length > 0 && segment.trim() === segment
17167
17274
  );
17168
17275
  }
17169
- return !path.includes(".");
17276
+ return !path2.includes(".");
17170
17277
  },
17171
17278
  {
17172
17279
  message: "Trigger filter paths must be a single bare key or use $.path.segments"
@@ -17722,7 +17829,7 @@ var init_session_runs = __esm({
17722
17829
  external_exports.object({
17723
17830
  source: external_exports.literal("inline"),
17724
17831
  alias: ToolAliasSchema,
17725
- spec: RemoteMcpToolSchema.or(LocalToolSchema)
17832
+ spec: RemoteMcpToolSchema.or(LocalToolSchema).or(GithubToolSchema)
17726
17833
  }),
17727
17834
  external_exports.object({
17728
17835
  source: external_exports.literal("resource"),
@@ -18256,7 +18363,6 @@ var init_runtimes = __esm({
18256
18363
  RuntimeRecordSchema = external_exports.object({
18257
18364
  id: RuntimeIdSchema2,
18258
18365
  sandboxId: external_exports.string().trim().min(1).nullable(),
18259
- gitAuthExpiresAt: external_exports.string().datetime().nullable(),
18260
18366
  createdAt: external_exports.string().datetime(),
18261
18367
  updatedAt: external_exports.string().datetime()
18262
18368
  });
@@ -18294,6 +18400,8 @@ var init_src = __esm({
18294
18400
  init_conversation();
18295
18401
  init_conversation_reducer();
18296
18402
  init_connections();
18403
+ init_github_credentials();
18404
+ init_github_mcp_catalog();
18297
18405
  init_ids();
18298
18406
  init_environments();
18299
18407
  init_mcp();
@@ -18369,10 +18477,10 @@ var init_active_project = __esm({
18369
18477
 
18370
18478
  // src/lib/config/path.ts
18371
18479
  import { createHash } from "crypto";
18372
- import { homedir } from "os";
18480
+ import { homedir as homedir2 } from "os";
18373
18481
  import { join, normalize } from "path";
18374
18482
  function defaultConfigPath() {
18375
- return process.env.AUTO_CLI_CONFIG ?? join(homedir(), ".auto", "config.yaml");
18483
+ return process.env.AUTO_CLI_CONFIG ?? join(homedir2(), ".auto", "config.yaml");
18376
18484
  }
18377
18485
  function profilesDir(configPath = defaultConfigPath()) {
18378
18486
  return normalize(join(configPath, "..", PROFILES_DIR_NAME));
@@ -18404,9 +18512,9 @@ var init_path = __esm({
18404
18512
  // src/lib/config/file.ts
18405
18513
  import { chmodSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
18406
18514
  import { basename, dirname as dirname2, join as join2 } from "path";
18407
- function readConfig(path = defaultConfigPath()) {
18515
+ function readConfig(path2 = defaultConfigPath()) {
18408
18516
  try {
18409
- const text = readFileSync2(path, "utf8");
18517
+ const text = readFileSync2(path2, "utf8");
18410
18518
  const config2 = {};
18411
18519
  for (const line of text.split(/\r?\n/)) {
18412
18520
  const match = /^([A-Za-z0-9_]+):\s*(.*)$/.exec(line.trim());
@@ -18420,13 +18528,13 @@ function readConfig(path = defaultConfigPath()) {
18420
18528
  throw err;
18421
18529
  }
18422
18530
  }
18423
- function writeConfig(config2, path = defaultConfigPath()) {
18424
- writeConfigFile(config2, path);
18425
- if (config2.userEmail && config2.serverUrl && basename(dirname2(path)) !== PROFILES_DIR_NAME) {
18531
+ function writeConfig(config2, path2 = defaultConfigPath()) {
18532
+ writeConfigFile(config2, path2);
18533
+ if (config2.userEmail && config2.serverUrl && basename(dirname2(path2)) !== PROFILES_DIR_NAME) {
18426
18534
  writeConfigFile(
18427
18535
  config2,
18428
18536
  join2(
18429
- dirname2(path),
18537
+ dirname2(path2),
18430
18538
  PROFILES_DIR_NAME,
18431
18539
  profileFileName({
18432
18540
  userEmail: config2.userEmail,
@@ -18436,17 +18544,17 @@ function writeConfig(config2, path = defaultConfigPath()) {
18436
18544
  );
18437
18545
  }
18438
18546
  }
18439
- function writeConfigFile(config2, path) {
18440
- mkdirSync2(dirname2(path), { recursive: true });
18547
+ function writeConfigFile(config2, path2) {
18548
+ mkdirSync2(dirname2(path2), { recursive: true });
18441
18549
  const lines = CONFIG_KEYS.filter((key) => config2[key]).map(
18442
18550
  (key) => `${key}: ${config2[key]}`
18443
18551
  );
18444
- writeFileSync2(path, `${lines.join("\n")}
18552
+ writeFileSync2(path2, `${lines.join("\n")}
18445
18553
  `, {
18446
18554
  encoding: "utf8",
18447
18555
  mode: 384
18448
18556
  });
18449
- chmodSync(path, 384);
18557
+ chmodSync(path2, 384);
18450
18558
  }
18451
18559
  var CONFIG_KEYS;
18452
18560
  var init_file = __esm({
@@ -18604,38 +18712,38 @@ var init_http = __esm({
18604
18712
  });
18605
18713
 
18606
18714
  // src/lib/api/paths.ts
18607
- function apiPath(path = "") {
18608
- return `${API_PREFIX}${cleanSubpath(path)}`;
18715
+ function apiPath(path2 = "") {
18716
+ return `${API_PREFIX}${cleanSubpath(path2)}`;
18609
18717
  }
18610
- function orgApiPath(organizationId, path = "") {
18611
- return apiPath(orgSubpath(organizationId, path));
18718
+ function orgApiPath(organizationId, path2 = "") {
18719
+ return apiPath(orgSubpath(organizationId, path2));
18612
18720
  }
18613
- function projectApiPath(project, path = "") {
18721
+ function projectApiPath(project, path2 = "") {
18614
18722
  return apiPath(
18615
18723
  orgSubpath(
18616
18724
  project.organizationId,
18617
- `/projects/${encodeURIComponent(project.projectId)}${cleanSubpath(path)}`
18725
+ `/projects/${encodeURIComponent(project.projectId)}${cleanSubpath(path2)}`
18618
18726
  )
18619
18727
  );
18620
18728
  }
18621
- function sessionApiPath(project, sessionName, path = "") {
18729
+ function sessionApiPath(project, sessionName, path2 = "") {
18622
18730
  return projectApiPath(
18623
18731
  project,
18624
- `/sessions/${encodeURIComponent(sessionName)}${cleanSubpath(path)}`
18732
+ `/sessions/${encodeURIComponent(sessionName)}${cleanSubpath(path2)}`
18625
18733
  );
18626
18734
  }
18627
- function runApiPath(runId, path = "") {
18628
- return apiPath(`/runs/${encodeURIComponent(runId)}${cleanSubpath(path)}`);
18735
+ function runApiPath(runId, path2 = "") {
18736
+ return apiPath(`/runs/${encodeURIComponent(runId)}${cleanSubpath(path2)}`);
18629
18737
  }
18630
- function cleanSubpath(path) {
18631
- const trimmed = path.trim();
18738
+ function cleanSubpath(path2) {
18739
+ const trimmed = path2.trim();
18632
18740
  if (!trimmed) {
18633
18741
  return "";
18634
18742
  }
18635
18743
  return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
18636
18744
  }
18637
- function orgSubpath(organizationId, path = "") {
18638
- return `/orgs/${encodeURIComponent(organizationId)}${cleanSubpath(path)}`;
18745
+ function orgSubpath(organizationId, path2 = "") {
18746
+ return `/orgs/${encodeURIComponent(organizationId)}${cleanSubpath(path2)}`;
18639
18747
  }
18640
18748
  var API_PREFIX;
18641
18749
  var init_paths = __esm({
@@ -18927,9 +19035,9 @@ async function deleteProjectResource(context, request, options) {
18927
19035
  };
18928
19036
  }
18929
19037
  async function applyProjectResources(context, request, options) {
18930
- const path = projectApplyPath(context);
19038
+ const path2 = projectApplyPath(context);
18931
19039
  const response = await context.authenticatedFetch(
18932
- context.apiUrl(path, options.apiBaseUrl),
19040
+ context.apiUrl(path2, options.apiBaseUrl),
18933
19041
  {
18934
19042
  method: "POST",
18935
19043
  headers: {
@@ -19026,8 +19134,8 @@ function createApiClient(input) {
19026
19134
  explicit
19027
19135
  });
19028
19136
  }
19029
- function apiUrl(path, explicit) {
19030
- return `${apiBaseUrl(explicit)}${path}`;
19137
+ function apiUrl(path2, explicit) {
19138
+ return `${apiBaseUrl(explicit)}${path2}`;
19031
19139
  }
19032
19140
  function activeProject() {
19033
19141
  const config2 = readConfig(input.configPath);
@@ -19196,8 +19304,8 @@ function createApiClient(input) {
19196
19304
  headers: bootstrapAuthHeaders(init.headers)
19197
19305
  });
19198
19306
  }
19199
- async function requestJson(path, options = {}) {
19200
- const url2 = new URL(apiUrl(path, options.apiBaseUrl));
19307
+ async function requestJson(path2, options = {}) {
19308
+ const url2 = new URL(apiUrl(path2, options.apiBaseUrl));
19201
19309
  const searchParamEntries = Array.isArray(options.searchParams) ? options.searchParams : Object.entries(options.searchParams ?? {});
19202
19310
  for (const [name, value] of searchParamEntries) {
19203
19311
  url2.searchParams.append(name, value);
@@ -19581,7 +19689,7 @@ function createApiClient(input) {
19581
19689
  }),
19582
19690
  async setSecret(name, request, options = {}) {
19583
19691
  const organization = activeOrganization();
19584
- const path = options.projectId ? projectApiPath(
19692
+ const path2 = options.projectId ? projectApiPath(
19585
19693
  {
19586
19694
  organizationId: organization.organizationId,
19587
19695
  projectId: options.projectId
@@ -19592,7 +19700,7 @@ function createApiClient(input) {
19592
19700
  `/secrets/${encodeURIComponent(name)}`
19593
19701
  );
19594
19702
  const response = await authenticatedFetch(
19595
- apiUrl(path, options.apiBaseUrl),
19703
+ apiUrl(path2, options.apiBaseUrl),
19596
19704
  {
19597
19705
  method: "PUT",
19598
19706
  headers: {
@@ -19609,7 +19717,7 @@ function createApiClient(input) {
19609
19717
  },
19610
19718
  async listSecrets(options = {}) {
19611
19719
  const organization = activeOrganization();
19612
- const path = options.projectId ? projectApiPath(
19720
+ const path2 = options.projectId ? projectApiPath(
19613
19721
  {
19614
19722
  organizationId: organization.organizationId,
19615
19723
  projectId: options.projectId
@@ -19617,7 +19725,7 @@ function createApiClient(input) {
19617
19725
  "/secrets"
19618
19726
  ) : orgApiPath(organization.organizationId, "/secrets");
19619
19727
  const response = await authenticatedFetch(
19620
- apiUrl(path, options.apiBaseUrl),
19728
+ apiUrl(path2, options.apiBaseUrl),
19621
19729
  {},
19622
19730
  options.apiBaseUrl
19623
19731
  );
@@ -19628,7 +19736,7 @@ function createApiClient(input) {
19628
19736
  },
19629
19737
  async removeSecret(name, options = {}) {
19630
19738
  const organization = activeOrganization();
19631
- const path = options.projectId ? projectApiPath(
19739
+ const path2 = options.projectId ? projectApiPath(
19632
19740
  {
19633
19741
  organizationId: organization.organizationId,
19634
19742
  projectId: options.projectId
@@ -19639,7 +19747,7 @@ function createApiClient(input) {
19639
19747
  `/secrets/${encodeURIComponent(name)}`
19640
19748
  );
19641
19749
  const response = await authenticatedFetch(
19642
- apiUrl(path, options.apiBaseUrl),
19750
+ apiUrl(path2, options.apiBaseUrl),
19643
19751
  {
19644
19752
  method: "DELETE"
19645
19753
  },
@@ -20138,9 +20246,9 @@ var init_browser = __esm({
20138
20246
  });
20139
20247
 
20140
20248
  // src/lib/oauth/loopback.ts
20141
- import { createServer } from "http";
20249
+ import { createServer as createServer2 } from "http";
20142
20250
  async function createOAuthLoopbackCallback(input) {
20143
- const path = input?.path ?? "/callback";
20251
+ const path2 = input?.path ?? "/callback";
20144
20252
  const successHtml = input?.successHtml ?? renderOAuthLoopbackPage({
20145
20253
  status: "success",
20146
20254
  eyebrow: "Auto",
@@ -20159,9 +20267,9 @@ async function createOAuthLoopbackCallback(input) {
20159
20267
  resolveResult = resolve2;
20160
20268
  rejectResult = reject;
20161
20269
  });
20162
- const server = createServer((request, response) => {
20270
+ const server = createServer2((request, response) => {
20163
20271
  const url2 = new URL(request.url ?? "/", "http://127.0.0.1");
20164
- if (url2.pathname !== path) {
20272
+ if (url2.pathname !== path2) {
20165
20273
  response.writeHead(404).end("Not found");
20166
20274
  return;
20167
20275
  }
@@ -20203,7 +20311,7 @@ async function createOAuthLoopbackCallback(input) {
20203
20311
  const address = server.address();
20204
20312
  return {
20205
20313
  close: () => server.close(),
20206
- redirectUri: `http://127.0.0.1:${address.port}${path}`,
20314
+ redirectUri: `http://127.0.0.1:${address.port}${path2}`,
20207
20315
  result
20208
20316
  };
20209
20317
  }
@@ -20585,12 +20693,12 @@ function readProjectApplyRequest(options) {
20585
20693
  throw new Error(`No resource files found in ${directory}`);
20586
20694
  }
20587
20695
  const resources = [];
20588
- for (const { kind, path } of files) {
20589
- const request = readApplyDocumentFile(path);
20696
+ for (const { kind, path: path2 } of files) {
20697
+ const request = readApplyDocumentFile(path2);
20590
20698
  for (const resource of request.resources) {
20591
20699
  if (resource.kind !== kind) {
20592
20700
  throw new Error(
20593
- `Resource kind "${resource.kind}" in ${path} does not match .auto/${APPLY_DIRECTORIES[kind]}`
20701
+ `Resource kind "${resource.kind}" in ${path2} does not match .auto/${APPLY_DIRECTORIES[kind]}`
20594
20702
  );
20595
20703
  }
20596
20704
  resources.push(resource);
@@ -20642,15 +20750,15 @@ function applyFiles(root) {
20642
20750
  const files = [];
20643
20751
  for (const kind of APPLY_RESOURCE_ORDER) {
20644
20752
  const directory = APPLY_DIRECTORIES[kind];
20645
- const path = join3(root, directory);
20753
+ const path2 = join3(root, directory);
20646
20754
  let entries;
20647
20755
  try {
20648
- entries = readdirSync(path, { withFileTypes: true });
20756
+ entries = readdirSync(path2, { withFileTypes: true });
20649
20757
  } catch {
20650
20758
  continue;
20651
20759
  }
20652
20760
  files.push(
20653
- ...resourceApplyFiles(path, entries).map((file2) => ({
20761
+ ...resourceApplyFiles(path2, entries).map((file2) => ({
20654
20762
  kind,
20655
20763
  path: file2
20656
20764
  }))
@@ -20658,8 +20766,8 @@ function applyFiles(root) {
20658
20766
  }
20659
20767
  return files;
20660
20768
  }
20661
- function readApplyDocumentFile(path) {
20662
- const source = readFileSync3(path, "utf8");
20769
+ function readApplyDocumentFile(path2) {
20770
+ const source = readFileSync3(path2, "utf8");
20663
20771
  let documents;
20664
20772
  try {
20665
20773
  documents = parseYamlDocuments(source).filter((document) => document.contents !== null).map((document) => document.toJSON());
@@ -20669,7 +20777,7 @@ function readApplyDocumentFile(path) {
20669
20777
  );
20670
20778
  }
20671
20779
  if (documents.length === 0) {
20672
- throw new Error(`Invalid apply file: ${path} is empty`);
20780
+ throw new Error(`Invalid apply file: ${path2} is empty`);
20673
20781
  }
20674
20782
  if (documents.length === 1) {
20675
20783
  const system = ProjectApplySystemConfigSchema.safeParse(documents[0]);
@@ -20795,8 +20903,8 @@ function applyFileProjectRoot(file2) {
20795
20903
  dir = parent;
20796
20904
  }
20797
20905
  }
20798
- function isInside(path, parent) {
20799
- return path.startsWith(`${parent}/`);
20906
+ function isInside(path2, parent) {
20907
+ return path2.startsWith(`${parent}/`);
20800
20908
  }
20801
20909
  function applyCandidate(document) {
20802
20910
  if (!isRecord(document) || !("kind" in document)) {
@@ -20822,15 +20930,15 @@ function isRecord(value) {
20822
20930
  function resourceApplyFiles(directory, entries) {
20823
20931
  const files = [];
20824
20932
  for (const entry of entries) {
20825
- const path = join3(directory, entry.name);
20933
+ const path2 = join3(directory, entry.name);
20826
20934
  if (entry.isDirectory()) {
20827
20935
  files.push(
20828
- ...resourceApplyFiles(path, readdirSync(path, { withFileTypes: true }))
20936
+ ...resourceApplyFiles(path2, readdirSync(path2, { withFileTypes: true }))
20829
20937
  );
20830
20938
  continue;
20831
20939
  }
20832
20940
  if (entry.isFile() && /\.(json|ya?ml)$/i.test(entry.name)) {
20833
- files.push(path);
20941
+ files.push(path2);
20834
20942
  }
20835
20943
  }
20836
20944
  return files.sort((left, right) => left.localeCompare(right));
@@ -20984,8 +21092,8 @@ function listProfiles(configPath = defaultConfigPath()) {
20984
21092
  throw err;
20985
21093
  }
20986
21094
  return entries.filter((entry) => entry.endsWith(".yaml")).sort().map((entry) => {
20987
- const path = join4(dir, entry);
20988
- return { path, config: readConfig(path) };
21095
+ const path2 = join4(dir, entry);
21096
+ return { path: path2, config: readConfig(path2) };
20989
21097
  }).filter((profile) => profile.config.userEmail);
20990
21098
  }
20991
21099
  function findAccountProfile(input) {
@@ -21490,7 +21598,7 @@ var init_package = __esm({
21490
21598
  "package.json"() {
21491
21599
  package_default = {
21492
21600
  name: "@autohq/cli",
21493
- version: "0.1.89",
21601
+ version: "0.1.91",
21494
21602
  license: "SEE LICENSE IN README.md",
21495
21603
  publishConfig: {
21496
21604
  access: "public"
@@ -26616,6 +26724,156 @@ var init_launcher = __esm({
26616
26724
  // src/cli/program.ts
26617
26725
  import { Command, Option as Option3 } from "commander";
26618
26726
 
26727
+ // src/commands/agent-bridge/git-credentials.ts
26728
+ import { once } from "events";
26729
+ import { chmod, mkdir, readFile, writeFile } from "fs/promises";
26730
+ import { createServer } from "http";
26731
+ import { homedir } from "os";
26732
+ import path from "path";
26733
+ var RELAY_PATH = "/git-credential";
26734
+ function defaultGitCredentialPortFilePath() {
26735
+ return path.join(homedir(), ".auto", "agent-bridge", "git-credential.json");
26736
+ }
26737
+ async function startGitCredentialRelay(input) {
26738
+ const fetchImpl = input.fetchImpl ?? fetch;
26739
+ let target = { url: input.url, accessToken: input.accessToken };
26740
+ const server = createServer((request, response) => {
26741
+ if (request.method !== "POST" || request.url !== RELAY_PATH) {
26742
+ response.writeHead(404).end();
26743
+ return;
26744
+ }
26745
+ const chunks = [];
26746
+ request.on("data", (chunk) => chunks.push(chunk));
26747
+ request.on("end", () => {
26748
+ void (async () => {
26749
+ try {
26750
+ const upstream = await fetchImpl(target.url, {
26751
+ method: "POST",
26752
+ headers: {
26753
+ authorization: `Bearer ${target.accessToken}`,
26754
+ "content-type": "application/json"
26755
+ },
26756
+ body: Buffer.concat(chunks).toString("utf8") || "{}"
26757
+ });
26758
+ const body = await upstream.text();
26759
+ response.writeHead(upstream.status, {
26760
+ "content-type": upstream.headers.get("content-type") ?? "application/json"
26761
+ }).end(body);
26762
+ } catch (error51) {
26763
+ response.writeHead(502, { "content-type": "application/json" }).end(
26764
+ JSON.stringify({
26765
+ error: error51 instanceof Error ? error51.message : String(error51)
26766
+ })
26767
+ );
26768
+ }
26769
+ })();
26770
+ });
26771
+ });
26772
+ server.listen(0, "127.0.0.1");
26773
+ await once(server, "listening");
26774
+ server.unref();
26775
+ const address = server.address();
26776
+ if (!address || typeof address !== "object") {
26777
+ server.close();
26778
+ throw new Error("git credential relay failed to bind a loopback port");
26779
+ }
26780
+ const portFilePath = input.portFilePath ?? defaultGitCredentialPortFilePath();
26781
+ await mkdir(path.dirname(portFilePath), { recursive: true });
26782
+ await writeFile(portFilePath, JSON.stringify({ port: address.port }), {
26783
+ mode: 384
26784
+ });
26785
+ await chmod(portFilePath, 384);
26786
+ return {
26787
+ port: address.port,
26788
+ update: (next) => {
26789
+ target = { url: next.url, accessToken: next.accessToken };
26790
+ },
26791
+ close: () => new Promise((resolve2) => {
26792
+ server.close(() => resolve2());
26793
+ })
26794
+ };
26795
+ }
26796
+ async function runGitCredentialHelper(input) {
26797
+ if (input.args.includes("--check")) {
26798
+ return 0;
26799
+ }
26800
+ const operation = input.args.find((arg) => !arg.startsWith("-"));
26801
+ if (operation === "store" || operation === "erase") {
26802
+ return 0;
26803
+ }
26804
+ if (operation !== "get") {
26805
+ input.writeError(`unsupported git credential operation: ${operation}`);
26806
+ return 1;
26807
+ }
26808
+ try {
26809
+ const attributes = parseGitCredentialAttributes(
26810
+ await readStream(input.stdin)
26811
+ );
26812
+ if (attributes.protocol !== "https" || attributes.host !== "github.com") {
26813
+ return 1;
26814
+ }
26815
+ const portFilePath = input.portFilePath ?? defaultGitCredentialPortFilePath();
26816
+ const portFile = JSON.parse(await readFile(portFilePath, "utf8"));
26817
+ if (typeof portFile.port !== "number") {
26818
+ input.writeError("git credential relay port file is malformed");
26819
+ return 1;
26820
+ }
26821
+ const response = await (input.fetchImpl ?? fetch)(
26822
+ `http://127.0.0.1:${portFile.port}${RELAY_PATH}`,
26823
+ {
26824
+ method: "POST",
26825
+ headers: { "content-type": "application/json" },
26826
+ body: JSON.stringify({
26827
+ host: attributes.host,
26828
+ ...attributes.path ? { path: attributes.path } : {}
26829
+ })
26830
+ }
26831
+ );
26832
+ if (!response.ok) {
26833
+ input.writeError(
26834
+ `git credential broker rejected the request: ${response.status}`
26835
+ );
26836
+ return 1;
26837
+ }
26838
+ const credential = await response.json();
26839
+ if (!credential.username || !credential.password) {
26840
+ input.writeError("git credential broker returned no credential");
26841
+ return 1;
26842
+ }
26843
+ input.writeOutput(`username=${credential.username}`);
26844
+ input.writeOutput(`password=${credential.password}`);
26845
+ const expiryUtc = credential.expiresAt ? Math.floor(new Date(credential.expiresAt).getTime() / 1e3) : void 0;
26846
+ if (expiryUtc && Number.isFinite(expiryUtc)) {
26847
+ input.writeOutput(`password_expiry_utc=${expiryUtc}`);
26848
+ }
26849
+ return 0;
26850
+ } catch (error51) {
26851
+ input.writeError(error51 instanceof Error ? error51.message : String(error51));
26852
+ return 1;
26853
+ }
26854
+ }
26855
+ function parseGitCredentialAttributes(raw) {
26856
+ const attributes = {};
26857
+ for (const line of raw.split("\n")) {
26858
+ if (!line.trim()) {
26859
+ continue;
26860
+ }
26861
+ const separator = line.indexOf("=");
26862
+ if (separator <= 0) {
26863
+ continue;
26864
+ }
26865
+ attributes[line.slice(0, separator)] = line.slice(separator + 1);
26866
+ }
26867
+ return attributes;
26868
+ }
26869
+ async function readStream(stream) {
26870
+ const chunks = [];
26871
+ for await (const chunk of stream) {
26872
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
26873
+ }
26874
+ return Buffer.concat(chunks).toString("utf8");
26875
+ }
26876
+
26619
26877
  // ../../packages/protocol/src/index.ts
26620
26878
  init_zod();
26621
26879
  var OpaqueIdSchema = external_exports.string().trim().min(1);
@@ -26724,7 +26982,14 @@ var AgentBridgeClaudeConfigSchema = external_exports.object({
26724
26982
  var RuntimeBridgeBootstrapPlaintextSchema = external_exports.object({
26725
26983
  version: external_exports.literal(1),
26726
26984
  outputSeqStart: external_exports.number().int().nonnegative(),
26727
- claude: AgentBridgeClaudeConfigSchema
26985
+ claude: AgentBridgeClaudeConfigSchema,
26986
+ // Endpoint + run token for the git credential broker. Present only when
26987
+ // the run has GitHub App git mounts; rides the encrypted bootstrap so the
26988
+ // token lives in agent-bridge memory, never on disk.
26989
+ gitCredentials: external_exports.object({
26990
+ url: external_exports.string().trim().min(1),
26991
+ accessToken: external_exports.string().trim().min(1)
26992
+ }).strict().optional()
26728
26993
  }).strict();
26729
26994
  var RuntimeBridgeEncryptedBootstrapSchema = external_exports.object({
26730
26995
  version: external_exports.literal(1),
@@ -26951,6 +27216,7 @@ async function runAgentBridgeSocket(options) {
26951
27216
  RUNTIME_BRIDGE_BOOTSTRAP_EVENT,
26952
27217
  createRuntimeBridgeBootstrapListener({
26953
27218
  token: options.token,
27219
+ onBootstrap: options.onBootstrap,
26954
27220
  createHandler: (bootstrap) => options.createHandler({
26955
27221
  emitOutput: (output) => emitOutputWithAck(socket, output),
26956
27222
  claude: bootstrap.claude,
@@ -27049,6 +27315,7 @@ function createRuntimeBridgeBootstrapListener(input) {
27049
27315
  input.writeOutput?.(
27050
27316
  `agent_bridge_bootstrap_decrypted duration_ms=${Date.now() - decryptStartedAt}`
27051
27317
  );
27318
+ await input.onBootstrap?.(bootstrap);
27052
27319
  let handler = input.getHandler();
27053
27320
  if (!handler) {
27054
27321
  handler = input.createHandler(bootstrap);
@@ -27885,21 +28152,21 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
27885
28152
  import { dirname } from "path";
27886
28153
  var AGENT_BRIDGE_RUNTIME_DIR = "/tmp/auto-bridge-runtime";
27887
28154
  var CLAUDE_SESSION_RESUME_PATH = `${AGENT_BRIDGE_RUNTIME_DIR}/claude-session-id`;
27888
- function fileClaudeSessionResumeStore(path = CLAUDE_SESSION_RESUME_PATH) {
28155
+ function fileClaudeSessionResumeStore(path2 = CLAUDE_SESSION_RESUME_PATH) {
27889
28156
  return {
27890
28157
  read(runId) {
27891
- if (!existsSync(path)) {
28158
+ if (!existsSync(path2)) {
27892
28159
  return null;
27893
28160
  }
27894
- const record2 = parseResumeRecord(readFileSync(path, "utf8"));
28161
+ const record2 = parseResumeRecord(readFileSync(path2, "utf8"));
27895
28162
  if (!record2 || record2.runId !== runId) {
27896
28163
  return null;
27897
28164
  }
27898
28165
  return record2.sessionId;
27899
28166
  },
27900
28167
  write(record2) {
27901
- mkdirSync(dirname(path), { recursive: true });
27902
- writeFileSync(path, `${JSON.stringify(record2)}
28168
+ mkdirSync(dirname(path2), { recursive: true });
28169
+ writeFileSync(path2, `${JSON.stringify(record2)}
27903
28170
  `, "utf8");
27904
28171
  }
27905
28172
  };
@@ -28268,7 +28535,10 @@ function deliveryMessage(delivery) {
28268
28535
  // src/commands/agent-bridge/entrypoint.ts
28269
28536
  async function runAgentBridgeProcess(input) {
28270
28537
  const runAgentBridge = input.runAgentBridge ?? runAgentBridgeClaudeCode;
28271
- await runAgentBridge(agentBridgeOptionsFromEnv(input));
28538
+ await runAgentBridge({
28539
+ ...agentBridgeOptionsFromEnv(input),
28540
+ onBootstrap: createGitCredentialRelayStarter(input.writeOutput)
28541
+ });
28272
28542
  }
28273
28543
  function agentBridgeOptionsFromEnv(input) {
28274
28544
  return {
@@ -28277,6 +28547,37 @@ function agentBridgeOptionsFromEnv(input) {
28277
28547
  writeOutput: input.writeOutput
28278
28548
  };
28279
28549
  }
28550
+ function createGitCredentialRelayStarter(writeOutput) {
28551
+ let relay;
28552
+ let startup;
28553
+ return async (bootstrap) => {
28554
+ const gitCredentials = bootstrap.gitCredentials;
28555
+ if (!gitCredentials) {
28556
+ return;
28557
+ }
28558
+ if (relay) {
28559
+ relay.update(gitCredentials);
28560
+ return;
28561
+ }
28562
+ if (startup) {
28563
+ const started = await startup;
28564
+ started?.update(gitCredentials);
28565
+ return;
28566
+ }
28567
+ startup = startGitCredentialRelay(gitCredentials).then((started) => {
28568
+ relay = started;
28569
+ writeOutput?.(`agent_bridge_git_credential_relay port=${started.port}`);
28570
+ return started;
28571
+ }).catch((error51) => {
28572
+ startup = void 0;
28573
+ writeOutput?.(
28574
+ `agent_bridge_git_credential_relay_failed error=${error51 instanceof Error ? error51.message : String(error51)}`
28575
+ );
28576
+ return void 0;
28577
+ });
28578
+ await startup;
28579
+ };
28580
+ }
28280
28581
  function requiredEnv(env, key) {
28281
28582
  const value = env[key]?.trim();
28282
28583
  if (!value) {
@@ -28287,12 +28588,25 @@ function requiredEnv(env, key) {
28287
28588
 
28288
28589
  // src/commands/agent-bridge/commands.ts
28289
28590
  function registerAgentBridgeCommands(program, context) {
28290
- program.command("agent-bridge", { hidden: true }).description("Run the internal runtime bridge wrapper.").action(async () => {
28591
+ const agentBridge = program.command("agent-bridge", { hidden: true }).description("Run the internal runtime bridge wrapper.").action(async () => {
28291
28592
  await runAgentBridgeProcess({
28292
28593
  env: context.env,
28293
28594
  writeOutput: context.writeOutput
28294
28595
  });
28295
28596
  });
28597
+ agentBridge.command("git-credential [operation]").description("git credential helper backed by the run's broker endpoint.").option("--check", "Exit 0 when the helper is available.").allowUnknownOption(true).action(async (operation, options) => {
28598
+ const exitCode = await runGitCredentialHelper({
28599
+ args: [
28600
+ ...options.check ? ["--check"] : [],
28601
+ ...operation ? [operation] : []
28602
+ ],
28603
+ stdin: process.stdin,
28604
+ writeOutput: context.writeOutput,
28605
+ writeError: (line) => process.stderr.write(`${line}
28606
+ `)
28607
+ });
28608
+ process.exitCode = exitCode;
28609
+ });
28296
28610
  }
28297
28611
 
28298
28612
  // src/cli/options.ts
@@ -31214,7 +31528,7 @@ async function secretValue(input) {
31214
31528
  }
31215
31529
  value = envValue;
31216
31530
  } else if (input.options.stdin) {
31217
- value = await readStream(input.stdin, Boolean(input.options.raw));
31531
+ value = await readStream2(input.stdin, Boolean(input.options.raw));
31218
31532
  } else {
31219
31533
  throw new Error(
31220
31534
  "Provide the secret value with --stdin, --value, or --from-env."
@@ -31227,7 +31541,7 @@ async function secretValue(input) {
31227
31541
  }
31228
31542
  return value;
31229
31543
  }
31230
- async function readStream(stream, raw) {
31544
+ async function readStream2(stream, raw) {
31231
31545
  const chunks = [];
31232
31546
  for await (const chunk of stream) {
31233
31547
  chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
@@ -31457,7 +31771,7 @@ function withApiBaseUrl2(context, commandOptions) {
31457
31771
  init_resources2();
31458
31772
  init_browser();
31459
31773
  import { existsSync as existsSync2, mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync4 } from "fs";
31460
- import { homedir as homedir2, tmpdir as tmpdir2 } from "os";
31774
+ import { homedir as homedir3, tmpdir as tmpdir2 } from "os";
31461
31775
  import { join as join6 } from "path";
31462
31776
  var POLL_INTERVAL_MS = 2e3;
31463
31777
  var POLL_TIMEOUT_MS = 5 * 6e4;
@@ -31619,7 +31933,7 @@ async function promptForIconUploads(input, options) {
31619
31933
  }
31620
31934
  }
31621
31935
  function stagedLocationLabel(stagedPath) {
31622
- return stagedPath.startsWith(`${join6(homedir2(), "Downloads")}/`) ? "Downloads" : "the printed path";
31936
+ return stagedPath.startsWith(`${join6(homedir3(), "Downloads")}/`) ? "Downloads" : "the printed path";
31623
31937
  }
31624
31938
  async function stageAvatarImage(input) {
31625
31939
  try {
@@ -31631,11 +31945,11 @@ async function stageAvatarImage(input) {
31631
31945
  }
31632
31946
  const contentType = response.headers.get("content-type") ?? "";
31633
31947
  const extension = contentType.includes("jpeg") ? ".jpg" : ".png";
31634
- const downloads = join6(homedir2(), "Downloads");
31948
+ const downloads = join6(homedir3(), "Downloads");
31635
31949
  const directory = existsSync2(downloads) ? downloads : mkdtempSync2(join6(tmpdir2(), "auto-avatar-"));
31636
- const path = join6(directory, `${input.session}-avatar${extension}`);
31637
- writeFileSync4(path, Buffer.from(await response.arrayBuffer()));
31638
- return path;
31950
+ const path2 = join6(directory, `${input.session}-avatar${extension}`);
31951
+ writeFileSync4(path2, Buffer.from(await response.arrayBuffer()));
31952
+ return path2;
31639
31953
  } catch {
31640
31954
  return void 0;
31641
31955
  }