@opengeni/runtime 4.6.0 → 4.7.0-canary.37090756480001

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.
Files changed (72) hide show
  1. package/dist/agent-instructions/modules/media.d.ts +3 -0
  2. package/dist/anthropic-messages.d.ts +13 -3
  3. package/dist/anthropic-request-error.d.ts +10 -0
  4. package/dist/assets/codemode-client.json +1 -1
  5. package/dist/{chunk-A22BKN4P.js → chunk-LJNCGUMB.js} +3 -3
  6. package/dist/chunk-LJNCGUMB.js.map +1 -0
  7. package/dist/{chunk-GTWKWJ67.js → chunk-P2OVGKDG.js} +505 -100
  8. package/dist/chunk-P2OVGKDG.js.map +1 -0
  9. package/dist/{chunk-D5DPVA2C.js → chunk-R25L27T3.js} +2047 -1275
  10. package/dist/chunk-R25L27T3.js.map +1 -0
  11. package/dist/claude-subscription-usage.d.ts +14 -4
  12. package/dist/context-compaction.d.ts +7 -7
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.js +13 -3
  15. package/dist/interaction-tools.d.ts +1 -1
  16. package/dist/mcp-network.js +1 -1
  17. package/dist/runtime-skills.d.ts +1 -0
  18. package/dist/sandbox/channel-a.d.ts +3 -0
  19. package/dist/sandbox/index.d.ts +3 -1
  20. package/dist/sandbox/index.js +7 -1
  21. package/dist/sandbox/provider-command-session.d.ts +21 -0
  22. package/dist/sandbox/providers/modal-command-argv.d.ts +4 -0
  23. package/dist/sandbox/providers/modal-command-control.d.ts +17 -5
  24. package/dist/sandbox/providers/modal-command-observation-errors.d.ts +3 -0
  25. package/dist/sandbox/providers/modal-command-raw-page.d.ts +100 -0
  26. package/dist/sandbox/providers/modal-command-router-wire.d.ts +17 -0
  27. package/dist/sandbox/routing/routing-session.d.ts +10 -0
  28. package/dist/sandbox/turn-tool-cancellation.d.ts +4 -0
  29. package/dist/workspace-tool-gateway.js +3 -3
  30. package/package.json +12 -12
  31. package/src/agent-instructions/PROMPT_CHANGELOG.md +23 -1
  32. package/src/agent-instructions/compose.ts +2 -0
  33. package/src/agent-instructions/modules/media.ts +20 -0
  34. package/src/agent-instructions/runtime-mechanics.ts +8 -0
  35. package/src/anthropic-messages.ts +223 -31
  36. package/src/anthropic-request-error.ts +45 -0
  37. package/src/bundled_default_skills/opengeni-client/SKILL.md +9 -7
  38. package/src/bundled_default_skills/opengeni-client/references/agent-recipes.md +1 -1
  39. package/src/bundled_default_skills/opengeni-client/references/api-workflows.md +61 -0
  40. package/src/bundled_default_skills/opengeni-client/references/compatibility-and-troubleshooting.md +86 -0
  41. package/src/bundled_default_skills/opengeni-client/references/data-tools-and-credentials.md +82 -0
  42. package/src/bundled_default_skills/opengeni-client/references/discovery-and-autonomy.md +32 -25
  43. package/src/bundled_default_skills/opengeni-client/references/external-users-and-connect.md +17 -0
  44. package/src/bundled_default_skills/opengeni-client/references/product-shapes-and-ui.md +156 -0
  45. package/src/bundled_schedule_skills/opengeni-schedules/SKILL.md +56 -0
  46. package/src/claude-subscription-usage.ts +55 -9
  47. package/src/context-compaction.ts +16 -9
  48. package/src/index.ts +85 -18
  49. package/src/interaction-tools.ts +113 -3
  50. package/src/lazy-tool-transport.ts +26 -10
  51. package/src/mcp-network.ts +4 -2
  52. package/src/model-provider-client.ts +11 -3
  53. package/src/model-provider-routing.ts +4 -0
  54. package/src/runtime-skills.ts +8 -0
  55. package/src/sandbox/channel-a.ts +3 -0
  56. package/src/sandbox/index.ts +11 -1
  57. package/src/sandbox/provider-command-session.ts +58 -0
  58. package/src/sandbox/provider-errors.ts +43 -9
  59. package/src/sandbox/providers/modal-command-argv.ts +20 -0
  60. package/src/sandbox/providers/modal-command-control.ts +422 -116
  61. package/src/sandbox/providers/modal-command-observation-errors.ts +65 -0
  62. package/src/sandbox/providers/modal-command-raw-page.ts +147 -0
  63. package/src/sandbox/providers/modal-command-router-wire.ts +104 -12
  64. package/src/sandbox/providers/modal-command-session.ts +26 -4
  65. package/src/sandbox/providers/modal-legacy-command-control.ts +2 -9
  66. package/src/sandbox/providers/modal-materialization-verification.ts +70 -6
  67. package/src/sandbox/routing/routing-session.ts +140 -41
  68. package/src/sandbox/run-credentials.ts +62 -19
  69. package/src/sandbox/turn-tool-cancellation.ts +159 -42
  70. package/dist/chunk-A22BKN4P.js.map +0 -1
  71. package/dist/chunk-D5DPVA2C.js.map +0 -1
  72. package/dist/chunk-GTWKWJ67.js.map +0 -1
@@ -41,6 +41,7 @@ import {
41
41
  withSupervisedLaunchReservation,
42
42
  ProviderCommandStartRejectedError,
43
43
  ProviderCommandStartOutcomeUnknownError,
44
+ ProviderCommandInputOutcomeUnknownError,
44
45
  type ProviderCommandPersistence,
45
46
  type ProviderCommandSession,
46
47
  } from "../provider-command-session";
@@ -281,6 +282,12 @@ export interface RoutingSandboxSessionDeps {
281
282
  process: RoutingRetainedProcess;
282
283
  proof: RoutingRetainedProcessTerminalProof;
283
284
  }) => Promise<void>;
285
+ /** Read terminal truth for this exact copied process/backend. Missing rows,
286
+ * failed observations and active rows must never count as physical proof. */
287
+ isProcessSettled?: (input: {
288
+ backend: ResolvedActiveBackend;
289
+ process: RoutingRetainedProcess;
290
+ }) => Promise<boolean>;
284
291
  /** A terminal result is being returned to the model, not merely drained by
285
292
  * control/reaper work. Never invoke this for a running receipt. */
286
293
  observeProcessTerminal?: (input: {
@@ -1236,6 +1243,12 @@ export class RoutingSandboxSession implements RoutableBackendSession {
1236
1243
  write.call(record.backend.session, args),
1237
1244
  );
1238
1245
  } catch (error) {
1246
+ let inputUnknown = false;
1247
+ try {
1248
+ inputUnknown = error instanceof ProviderCommandInputOutcomeUnknownError;
1249
+ } catch {
1250
+ // An unreadable provider graph cannot manufacture typed input proof.
1251
+ }
1239
1252
  if (this.deps.afterProcessMutation) {
1240
1253
  const pending: PendingProcessMutationSettlement = {
1241
1254
  op,
@@ -1250,11 +1263,28 @@ export class RoutingSandboxSession implements RoutableBackendSession {
1250
1263
  record.pendingMutationSettlement = pending;
1251
1264
  throw new RoutingMutationOutcomeUnknownError(
1252
1265
  op,
1253
- `Retained-process stdin rejected at the provider but lost durable settlement; it was not replayed`,
1254
- { cause: settlementError },
1266
+ inputUnknown
1267
+ ? "Retained-process stdin acknowledgement and durable settlement unavailable; input may have been accepted. Do not resend stdin."
1268
+ : "Retained-process stdin rejected at the provider but lost durable settlement; it was not replayed",
1269
+ inputUnknown
1270
+ ? {
1271
+ cause: new AggregateError([error, settlementError]),
1272
+ retainedProcess: record.process,
1273
+ }
1274
+ : { cause: settlementError },
1255
1275
  );
1256
1276
  }
1257
1277
  }
1278
+ if (inputUnknown) {
1279
+ // Preserve native input proof across the retained route, including its
1280
+ // genuine byte-range cause and exact locator. Both SDK-facing rendering
1281
+ // and direct tool faults must forbid input replay.
1282
+ throw new RoutingMutationOutcomeUnknownError(
1283
+ op,
1284
+ "Provider stdin acknowledgement unavailable; input may have been accepted and was not resent. Do not resend stdin.",
1285
+ { cause: error, retainedProcess: record.process },
1286
+ );
1287
+ }
1258
1288
  throw error;
1259
1289
  }
1260
1290
  if (this.deps.afterProcessMutation) {
@@ -2131,7 +2161,17 @@ export class RoutingSandboxSession implements RoutableBackendSession {
2131
2161
  async writeStdin(args: unknown): Promise<string> {
2132
2162
  const providerSessionId = providerSessionIdFromArgs(args);
2133
2163
  if (providerSessionId !== null && this.retainedProcesses.has(providerSessionId)) {
2134
- return await this.dispatchProcessMutation(args);
2164
+ try {
2165
+ return await this.dispatchProcessMutation(args);
2166
+ } catch (error) {
2167
+ // The SDK's write_stdin tool has no configurable errorFunction. Render
2168
+ // genuine routing uncertainty here, before its generic retry advice.
2169
+ // Direct/control methods still throw; this is not an output receipt or
2170
+ // terminal proof and cannot acknowledge bytes or release the writer.
2171
+ if (isRoutingMutationOutcomeUnknownError(error))
2172
+ return renderRoutingMutationOutcomeUnknownToolResult(error);
2173
+ throw error;
2174
+ }
2135
2175
  }
2136
2176
  return this.dispatch("writeStdin", true, async (s) => {
2137
2177
  if (!s.writeStdin) {
@@ -2158,6 +2198,20 @@ export class RoutingSandboxSession implements RoutableBackendSession {
2158
2198
  );
2159
2199
  }
2160
2200
 
2201
+ /** A reaper may have settled the command while a local capture/control receipt
2202
+ * remained pending. Cleanup may consume that same durable proof without
2203
+ * replaying a provider operation or accepting pending output into the model. */
2204
+ async reconcileRetainedProcess(providerSessionId: number): Promise<boolean> {
2205
+ const record = this.retainedProcesses.get(providerSessionId);
2206
+ if (!record || !this.deps.isProcessSettled) return false;
2207
+ if (!(await this.deps.isProcessSettled({ backend: record.backend, process: record.process })))
2208
+ return false;
2209
+ // Do not erase a rival route installed while the durable read was pending.
2210
+ if (this.retainedProcesses.get(providerSessionId) !== record) return false;
2211
+ this.retainedProcesses.delete(providerSessionId);
2212
+ return true;
2213
+ }
2214
+
2161
2215
  /** Local, Docker, and OpenSandbox process ids address an in-memory table on one worker
2162
2216
  * session object. They are not valid durable locators for the independently
2163
2217
  * scheduled reaper, so their yielded handles stay turn-owned until terminal
@@ -2404,9 +2458,7 @@ export class RoutingSandboxSession implements RoutableBackendSession {
2404
2458
  async writePlacementPrivate(args: unknown): Promise<unknown> {
2405
2459
  const input = placementPrivateWrite(args);
2406
2460
  return this.dispatch("writePlacementPrivate", false, async (session, backend) => {
2407
- if (session.writePlacementPrivate) return await session.writePlacementPrivate(input);
2408
- if (session.writeFile) return await session.writeFile(input);
2409
- return await streamPlacementPrivateFile(session, input, backend.kind);
2461
+ return await writePlacementPrivateOnBackend(session, input, backend.kind);
2410
2462
  });
2411
2463
  }
2412
2464
 
@@ -2414,36 +2466,8 @@ export class RoutingSandboxSession implements RoutableBackendSession {
2414
2466
  * control operation cannot be repurposed into a generic mutation bypass. */
2415
2467
  async deletePlacementPrivate(path: string, runAs?: string): Promise<void> {
2416
2468
  const privatePath = placementPrivatePath(path);
2417
- await this.dispatch("deletePlacementPrivate", false, async (session) => {
2418
- if (session.deletePlacementPrivate) {
2419
- await session.deletePlacementPrivate(privatePath, runAs);
2420
- return;
2421
- }
2422
- const args = {
2423
- cmd: `rm -f ${shellSingleQuote(privatePath)}`,
2424
- ...(runAs ? { runAs } : {}),
2425
- };
2426
- if (session.exec) {
2427
- const result = await session.exec(args);
2428
- if (
2429
- result &&
2430
- typeof result === "object" &&
2431
- typeof (result as { exitCode?: unknown }).exitCode === "number" &&
2432
- (result as { exitCode: number }).exitCode !== 0
2433
- ) {
2434
- throw new Error("placement-private cleanup failed");
2435
- }
2436
- return;
2437
- }
2438
- if (session.execCommand) {
2439
- const result = await session.execCommand(args);
2440
- const exitCode = parseExecBannerExitCode(result);
2441
- if (exitCode !== null && exitCode !== 0) {
2442
- throw new Error("placement-private cleanup failed");
2443
- }
2444
- return;
2445
- }
2446
- throw new RoutingUnsupportedError("deletePlacementPrivate", this.cached?.kind ?? "unknown");
2469
+ await this.dispatch("deletePlacementPrivate", false, async (session, backend) => {
2470
+ await deletePlacementPrivateOnBackend(session, privatePath, runAs, backend.kind);
2447
2471
  });
2448
2472
  }
2449
2473
 
@@ -2455,7 +2479,7 @@ export class RoutingSandboxSession implements RoutableBackendSession {
2455
2479
  ): Promise<WorkspaceFileImportReceipt> {
2456
2480
  return await this.dispatch("importWorkspaceFile", true, async (session, backend) => {
2457
2481
  const channel = new SandboxChannelAService({
2458
- session: session as ChannelASession,
2482
+ session: withPlacementPrivateControl(session, backend.kind),
2459
2483
  workspaceRoot: input.workspaceRoot,
2460
2484
  ...(backend.kind === "selfhosted"
2461
2485
  ? { providerPathMode: "workspace-relative" as const }
@@ -2476,7 +2500,7 @@ export class RoutingSandboxSession implements RoutableBackendSession {
2476
2500
  ): Promise<readonly WorkspaceFileImportReceipt[]> {
2477
2501
  return await this.dispatch("importWorkspaceFiles", true, async (session, backend) => {
2478
2502
  const channel = new SandboxChannelAService({
2479
- session: session as ChannelASession,
2503
+ session: withPlacementPrivateControl(session, backend.kind),
2480
2504
  workspaceRoot: input.workspaceRoot,
2481
2505
  ...(backend.kind === "selfhosted"
2482
2506
  ? { providerPathMode: "workspace-relative" as const }
@@ -2805,12 +2829,87 @@ function placementPrivateWrite(value: unknown): {
2805
2829
  };
2806
2830
  }
2807
2831
 
2832
+ /** Preserve private staging on the already resolved provider. Calling the
2833
+ * routing proxy here would re-resolve between staging, import and cleanup. */
2834
+ function withPlacementPrivateControl(
2835
+ session: RoutableBackendSession,
2836
+ backendKind: string,
2837
+ ): ChannelASession {
2838
+ return new Proxy(session, {
2839
+ get(target, property) {
2840
+ if (property === "writePlacementPrivate") {
2841
+ return async (args: unknown) =>
2842
+ await writePlacementPrivateOnBackend(target, placementPrivateWrite(args), backendKind);
2843
+ }
2844
+ if (property === "deletePlacementPrivate") {
2845
+ return async (path: string, runAs?: string) =>
2846
+ await deletePlacementPrivateOnBackend(
2847
+ target,
2848
+ placementPrivatePath(path),
2849
+ runAs,
2850
+ backendKind,
2851
+ );
2852
+ }
2853
+ const value: unknown = Reflect.get(target, property, target);
2854
+ return typeof value === "function" ? value.bind(target) : value;
2855
+ },
2856
+ }) as ChannelASession;
2857
+ }
2858
+
2859
+ async function writePlacementPrivateOnBackend(
2860
+ session: RoutableBackendSession,
2861
+ input: ReturnType<typeof placementPrivateWrite>,
2862
+ backendKind: string,
2863
+ ): Promise<unknown> {
2864
+ if (session.writePlacementPrivate) return await session.writePlacementPrivate(input);
2865
+ if (session.writeFile) return await session.writeFile(input);
2866
+ return await streamPlacementPrivateFile(session, input, backendKind);
2867
+ }
2868
+
2869
+ async function deletePlacementPrivateOnBackend(
2870
+ session: RoutableBackendSession,
2871
+ privatePath: string,
2872
+ runAs: string | undefined,
2873
+ backendKind: string,
2874
+ ): Promise<void> {
2875
+ if (session.deletePlacementPrivate) {
2876
+ await session.deletePlacementPrivate(privatePath, runAs);
2877
+ return;
2878
+ }
2879
+ const args = {
2880
+ cmd: `rm -f ${shellSingleQuote(privatePath)}`,
2881
+ ...(runAs ? { runAs } : {}),
2882
+ };
2883
+ if (session.exec) {
2884
+ const result = await session.exec(args);
2885
+ if (
2886
+ result &&
2887
+ typeof result === "object" &&
2888
+ typeof (result as { exitCode?: unknown }).exitCode === "number" &&
2889
+ (result as { exitCode: number }).exitCode !== 0
2890
+ ) {
2891
+ throw new Error("placement-private cleanup failed");
2892
+ }
2893
+ return;
2894
+ }
2895
+ if (session.execCommand) {
2896
+ const result = await session.execCommand(args);
2897
+ const exitCode = parseExecBannerExitCode(result);
2898
+ if (exitCode !== null && exitCode !== 0) {
2899
+ throw new Error("placement-private cleanup failed");
2900
+ }
2901
+ return;
2902
+ }
2903
+ throw new RoutingUnsupportedError("deletePlacementPrivate", backendKind);
2904
+ }
2905
+
2808
2906
  async function streamPlacementPrivateFile(
2809
2907
  session: RoutableBackendSession,
2810
2908
  input: ReturnType<typeof placementPrivateWrite>,
2811
2909
  backendKind: string,
2812
2910
  ): Promise<void> {
2813
- if (!session.exec || !session.writeStdin) {
2911
+ const exec = session.exec?.bind(session) ?? session.execCommand?.bind(session);
2912
+ if (!exec || !session.writeStdin) {
2814
2913
  throw new RoutingUnsupportedError("writePlacementPrivate", backendKind);
2815
2914
  }
2816
2915
  const bytes = typeof input.content === "string" ? Buffer.from(input.content) : input.content;
@@ -2821,7 +2920,7 @@ async function streamPlacementPrivateFile(
2821
2920
  ...(input.createParents ? [`install -d -m 0700 -- ${shellSingleQuote(parent)}`] : []),
2822
2921
  ];
2823
2922
  if (bytes.byteLength === 0) {
2824
- const result = await session.exec({
2923
+ const result = await exec({
2825
2924
  cmd: [
2826
2925
  ...prelude,
2827
2926
  `: > ${shellSingleQuote(input.path)}`,
@@ -2849,7 +2948,7 @@ async function streamPlacementPrivateFile(
2849
2948
  `chmod 0600 -- ${shellSingleQuote(input.path)}`,
2850
2949
  `printf %s ${shellSingleQuote(marker)}`,
2851
2950
  ].join("; ");
2852
- const started = await session.exec({
2951
+ const started = await exec({
2853
2952
  cmd: command,
2854
2953
  ...(input.runAs ? { runAs: input.runAs } : {}),
2855
2954
  yieldTimeMs: 250,
@@ -18,7 +18,10 @@ const MAX_CREDENTIAL_FILES = 64;
18
18
  const MAX_CREDENTIAL_FILE_BYTES = 1024 * 1024;
19
19
  const MAX_TOTAL_MATERIAL_BYTES = 4 * 1024 * 1024;
20
20
  const MAX_AUTH_NEEDED_NOTICES = 32;
21
- const WRITE_CHUNK_BYTES = 24 * 1024;
21
+ // Encoded chunks must leave room for both the cancellation shell and the SDK
22
+ // run-as wrapper, each of which repeats and quotes the command. Keep chunks
23
+ // base64-aligned and bounded without dropping any credential bytes.
24
+ const WRITE_CHUNK_BYTES = 1536;
22
25
  const COMMAND_OK_MARKER = "__OPENGENI_RUN_CREDENTIAL_COMMAND_OK__";
23
26
  const AUTH_NEEDED_REASONS = new Set([
24
27
  "missing_connection",
@@ -496,27 +499,54 @@ async function runCredentialCommand(
496
499
 
497
500
  async function writeCredentialFile(
498
501
  session: RunCredentialCommandSession,
499
- path: string,
502
+ directory: string,
503
+ relativePath: string,
500
504
  content: string,
501
505
  commandRunner?: RunCredentialCommandRunner,
502
506
  ): Promise<void> {
503
- await runCredentialCommand(session, `: > ${shellQuote(path)}`, commandRunner);
507
+ await runCredentialCommand(
508
+ session,
509
+ credentialFileCommand(directory, relativePath, ': > "$_opengeni_credential_path"'),
510
+ commandRunner,
511
+ );
504
512
  const encoded = base64(content);
505
513
  for (let offset = 0; offset < encoded.length; offset += WRITE_CHUNK_BYTES) {
506
514
  const chunk = encoded.slice(offset, offset + WRITE_CHUNK_BYTES);
507
515
  await runCredentialCommand(
508
516
  session,
509
- `printf %s ${shellQuote(chunk)} | ${portableBase64DecodeCommand()} >> ${shellQuote(path)}`,
517
+ credentialFileCommand(
518
+ directory,
519
+ relativePath,
520
+ `printf %s ${shellQuote(chunk)} | ${portableBase64DecodeCommand()} >> "$_opengeni_credential_path"`,
521
+ ),
510
522
  commandRunner,
511
523
  );
512
524
  }
513
525
  await runCredentialCommand(
514
526
  session,
515
- `[ "$(wc -c < ${shellQuote(path)} | tr -d '[:space:]')" = ${shellQuote(String(byteLength(content)))} ]`,
527
+ credentialFileCommand(
528
+ directory,
529
+ relativePath,
530
+ `[ "$(wc -c < "$_opengeni_credential_path" | tr -d '[:space:]')" = ${shellQuote(String(byteLength(content)))} ]`,
531
+ ),
516
532
  commandRunner,
517
533
  );
518
534
  }
519
535
 
536
+ function credentialFileCommand(directory: string, relativePath: string, command: string): string {
537
+ // Avoid multiplying accepted path quotes through nested shell wrappers. The
538
+ // existing outer Bash decodes only literal UTF-8 bytes, including trailing
539
+ // newlines, without evaluating host-provided text or invoking a path decoder.
540
+ const escapedPath = [...Buffer.from(relativePath, "utf8")]
541
+ .map((byte) => `\\x${byte.toString(16).padStart(2, "0")}`)
542
+ .join("");
543
+ return [
544
+ `printf -v _opengeni_credential_path %b ${shellQuote(escapedPath)}`,
545
+ `_opengeni_credential_path=${shellQuote(directory)}/"$_opengeni_credential_path"`,
546
+ command,
547
+ ].join("\n");
548
+ }
549
+
520
550
  export type MaterializeRunCredentialsOptions = {
521
551
  sessionId: string;
522
552
  attemptId: string;
@@ -574,7 +604,8 @@ export async function materializeRunCredentials(
574
604
  ];
575
605
  await writeCredentialFile(
576
606
  session,
577
- `${stage}/env`,
607
+ stage,
608
+ "env",
578
609
  environmentLines.length > 0 ? `${environmentLines.join("\n")}\n` : "",
579
610
  options.commandRunner,
580
611
  );
@@ -585,13 +616,20 @@ export async function materializeRunCredentials(
585
616
  );
586
617
 
587
618
  for (const file of material.files) {
588
- const target = `${stage}/files/${file.path}`;
589
- const parent = target.slice(0, target.lastIndexOf("/"));
590
- await runCredentialCommand(session, `mkdir -p -- ${shellQuote(parent)}`, options.commandRunner);
591
- await writeCredentialFile(session, target, file.content, options.commandRunner);
619
+ const directory = `${stage}/files`;
620
+ await runCredentialCommand(
621
+ session,
622
+ credentialFileCommand(directory, file.path, 'mkdir -p -- "${_opengeni_credential_path%/*}"'),
623
+ options.commandRunner,
624
+ );
625
+ await writeCredentialFile(session, directory, file.path, file.content, options.commandRunner);
592
626
  await runCredentialCommand(
593
627
  session,
594
- `chmod -- ${shellQuote(file.mode ?? "0600")} ${shellQuote(target)}`,
628
+ credentialFileCommand(
629
+ directory,
630
+ file.path,
631
+ `chmod -- ${shellQuote(file.mode ?? "0600")} "$_opengeni_credential_path"`,
632
+ ),
595
633
  options.commandRunner,
596
634
  );
597
635
  }
@@ -599,25 +637,30 @@ export async function materializeRunCredentials(
599
637
  await runCredentialCommand(
600
638
  session,
601
639
  [
640
+ // Bind validated identifiers once rather than repeatedly expanding long
641
+ // paths through cancellation and SDK run-as shell quoting.
642
+ `_opengeni_credential_root=${shellQuote(root)}`,
643
+ `_opengeni_credential_version_name=${shellQuote(versionName)}`,
644
+ `_opengeni_credential_prefix=${shellQuote(prefix)}`,
602
645
  ...pointerLockAcquireCommands(root),
603
- `previous=$(cat -- ${shellQuote(`${root}/current`)} 2>/dev/null || :)`,
604
- `mv -- ${shellQuote(stage)} ${shellQuote(version)}`,
605
- `printf '%s\\n' ${shellQuote(versionName)} > ${shellQuote(`${root}/.next`)}`,
606
- `mv -f -- ${shellQuote(`${root}/.next`)} ${shellQuote(`${root}/current`)}`,
646
+ 'previous=$(cat -- "$_opengeni_credential_root/current" 2>/dev/null || :)',
647
+ 'mv -- "$_opengeni_credential_root/versions/.stage-$_opengeni_credential_version_name" "$_opengeni_credential_root/versions/$_opengeni_credential_version_name"',
648
+ 'printf \'%s\\n\' "$_opengeni_credential_version_name" > "$_opengeni_credential_root/.next"',
649
+ 'mv -f -- "$_opengeni_credential_root/.next" "$_opengeni_credential_root/current"',
607
650
  ...(options.prunePreviousGenerations
608
651
  ? [
609
- `find ${shellQuote(`${root}/versions`)} -mindepth 1 -maxdepth 1 ! -name ${shellQuote(versionName)} -exec rm -rf -- {} +`,
652
+ 'find "$_opengeni_credential_root/versions" -mindepth 1 -maxdepth 1 ! -name "$_opengeni_credential_version_name" -exec rm -rf -- {} +',
610
653
  ]
611
654
  : options.pruneOtherAttempts
612
655
  ? [
613
- `find ${shellQuote(`${root}/versions`)} -mindepth 1 -maxdepth 1 ! -name ${shellQuote(`${attemptId}-${options.executionGeneration}-*`)} -exec rm -rf -- {} +`,
656
+ 'find "$_opengeni_credential_root/versions" -mindepth 1 -maxdepth 1 ! -name "${_opengeni_credential_prefix}*" -exec rm -rf -- {} +',
614
657
  ]
615
658
  : options.pruneSupersededGenerations
616
659
  ? [
617
- `for candidate in ${shellQuote(`${root}/versions`)}/${prefix}*; do`,
660
+ 'for candidate in "$_opengeni_credential_root/versions/$_opengeni_credential_prefix"*; do',
618
661
  ` [ -e "$candidate" ] || continue`,
619
662
  ` name=\${candidate##*/}`,
620
- ` [ "$name" = ${shellQuote(versionName)} ] || [ "$name" = "$previous" ] || rm -rf -- "$candidate"`,
663
+ ' [ "$name" = "$_opengeni_credential_version_name" ] || [ "$name" = "$previous" ] || rm -rf -- "$candidate"',
621
664
  "done",
622
665
  ]
623
666
  : []),