run402-mcp 3.5.3 → 3.5.5

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 (62) hide show
  1. package/README.md +13 -3
  2. package/core/dist/config.d.ts +19 -0
  3. package/core/dist/config.d.ts.map +1 -1
  4. package/core/dist/config.js +86 -4
  5. package/core/dist/config.js.map +1 -1
  6. package/dist/config.d.ts +1 -1
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +1 -1
  9. package/dist/config.js.map +1 -1
  10. package/dist/index.js +5 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/sdk.d.ts.map +1 -1
  13. package/dist/sdk.js +2 -1
  14. package/dist/sdk.js.map +1 -1
  15. package/dist/tools/project-archives.d.ts +62 -0
  16. package/dist/tools/project-archives.d.ts.map +1 -0
  17. package/dist/tools/project-archives.js +127 -0
  18. package/dist/tools/project-archives.js.map +1 -0
  19. package/package.json +3 -3
  20. package/sdk/README.md +3 -1
  21. package/sdk/core-dist/config.d.ts +19 -0
  22. package/sdk/core-dist/config.js +86 -4
  23. package/sdk/dist/credentials.d.ts +1 -1
  24. package/sdk/dist/credentials.d.ts.map +1 -1
  25. package/sdk/dist/index.d.ts +4 -0
  26. package/sdk/dist/index.d.ts.map +1 -1
  27. package/sdk/dist/index.js +4 -0
  28. package/sdk/dist/index.js.map +1 -1
  29. package/sdk/dist/namespaces/archives.d.ts +12 -0
  30. package/sdk/dist/namespaces/archives.d.ts.map +1 -0
  31. package/sdk/dist/namespaces/archives.js +202 -0
  32. package/sdk/dist/namespaces/archives.js.map +1 -0
  33. package/sdk/dist/namespaces/archives.types.d.ts +163 -0
  34. package/sdk/dist/namespaces/archives.types.d.ts.map +1 -0
  35. package/sdk/dist/namespaces/archives.types.js +2 -0
  36. package/sdk/dist/namespaces/archives.types.js.map +1 -0
  37. package/sdk/dist/namespaces/deploy.d.ts.map +1 -1
  38. package/sdk/dist/namespaces/deploy.js +173 -15
  39. package/sdk/dist/namespaces/deploy.js.map +1 -1
  40. package/sdk/dist/namespaces/deploy.types.d.ts +16 -1
  41. package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -1
  42. package/sdk/dist/namespaces/deploy.types.js.map +1 -1
  43. package/sdk/dist/namespaces/projects.d.ts.map +1 -1
  44. package/sdk/dist/namespaces/projects.js +1 -0
  45. package/sdk/dist/namespaces/projects.js.map +1 -1
  46. package/sdk/dist/namespaces/projects.types.d.ts +7 -0
  47. package/sdk/dist/namespaces/projects.types.d.ts.map +1 -1
  48. package/sdk/dist/node/archives-node.d.ts +14 -0
  49. package/sdk/dist/node/archives-node.d.ts.map +1 -0
  50. package/sdk/dist/node/archives-node.js +715 -0
  51. package/sdk/dist/node/archives-node.js.map +1 -0
  52. package/sdk/dist/node/deploy-manifest.d.ts.map +1 -1
  53. package/sdk/dist/node/deploy-manifest.js +15 -2
  54. package/sdk/dist/node/deploy-manifest.js.map +1 -1
  55. package/sdk/dist/node/index.d.ts +4 -1
  56. package/sdk/dist/node/index.d.ts.map +1 -1
  57. package/sdk/dist/node/index.js +3 -0
  58. package/sdk/dist/node/index.js.map +1 -1
  59. package/sdk/dist/scoped.d.ts +12 -0
  60. package/sdk/dist/scoped.d.ts.map +1 -1
  61. package/sdk/dist/scoped.js +25 -0
  62. package/sdk/dist/scoped.js.map +1 -1
@@ -166,7 +166,7 @@ export class Deploy {
166
166
  */
167
167
  async commit(planId, opts = {}) {
168
168
  const emit = makeEmitter(opts.onEvent);
169
- const commit = await commitInternal(this.client, planId, opts.idempotencyKey, opts.project);
169
+ const commit = requireCloudCommitResponse(await commitInternal(this.client, planId, opts.idempotencyKey, opts.project), "committing deploy");
170
170
  return await pollUntilReady(this.client, commit, {}, [], emit, opts.project);
171
171
  }
172
172
  /**
@@ -452,9 +452,10 @@ function deriveSliceKinds(spec) {
452
452
  }
453
453
  async function applyOnce(client, spec, opts, emit) {
454
454
  const allowWarningCodes = normalizeAllowWarningCodes(opts.allowWarningCodes);
455
+ const target = opts.target === "core" ? "core" : "cloud";
455
456
  const sliceKinds = deriveSliceKinds(spec);
456
457
  emit({ type: "plan.started" });
457
- const { plan, byteReaders } = await planInternal(client, spec, opts.idempotencyKey);
458
+ const { plan, byteReaders } = await planInternal(client, spec, opts.idempotencyKey, false, target);
458
459
  emit({ type: "plan.diff", diff: plan.diff });
459
460
  emitPlanWarnings(plan, emit);
460
461
  abortOnConfirmationWarnings(plan, opts, allowWarningCodes);
@@ -471,6 +472,21 @@ async function applyOnce(client, spec, opts, emit) {
471
472
  // sandbox provider without payment auto-handling can intercept the
472
473
  // event and resolve before we hit upload.
473
474
  }
475
+ if (target === "core") {
476
+ await uploadCoreContent(client, spec.project, byteReaders, emit);
477
+ emit({
478
+ type: "commit.phase",
479
+ phase: "validate",
480
+ status: "started",
481
+ ...(sliceKinds.length > 0 ? { slice_kinds: sliceKinds } : {}),
482
+ });
483
+ const planId = requirePlanId(plan, "applying deploy to Core");
484
+ const commit = await commitInternal(client, planId, opts.idempotencyKey, spec.project);
485
+ if (!isCoreCommitResponse(commit)) {
486
+ return await pollUntilReady(client, commit, plan.diff, plan.warnings, emit, spec.project, sliceKinds);
487
+ }
488
+ return await coreDeployResult(client, commit, plan.diff, plan.warnings, emit, spec.project, sliceKinds);
489
+ }
474
490
  await uploadMissing(client, spec.project, plan.missing_content, byteReaders, emit);
475
491
  emit({
476
492
  type: "commit.phase",
@@ -479,7 +495,7 @@ async function applyOnce(client, spec, opts, emit) {
479
495
  ...(sliceKinds.length > 0 ? { slice_kinds: sliceKinds } : {}),
480
496
  });
481
497
  const { planId } = requirePersistedPlan(plan, "applying deploy");
482
- const commit = await commitInternal(client, planId, opts.idempotencyKey, spec.project);
498
+ const commit = requireCloudCommitResponse(await commitInternal(client, planId, opts.idempotencyKey, spec.project), "applying deploy");
483
499
  const result = await pollUntilReady(client, commit, plan.diff, plan.warnings, emit, spec.project, sliceKinds);
484
500
  // v1.48 unified-apply: thread the plan response's `asset_entries[]` back
485
501
  // into DeployResult.assets so callers reading `result.assets.byKey[key]`
@@ -642,6 +658,17 @@ function contentRefToWire(ref) {
642
658
  ...(ref.integrity ? { integrity: ref.integrity } : {}),
643
659
  };
644
660
  }
661
+ function requireContentRef(ref, resource) {
662
+ if (ref)
663
+ return ref;
664
+ throw new Run402DeployError(`Missing content ref for ${resource}`, {
665
+ code: "INTERNAL_ERROR",
666
+ phase: "validate",
667
+ resource,
668
+ retryable: false,
669
+ context: "serializing deploy spec",
670
+ });
671
+ }
645
672
  function fileSetToWire(map) {
646
673
  const out = {};
647
674
  for (const [path, ref] of Object.entries(map))
@@ -680,6 +707,7 @@ function functionToWire(fn) {
680
707
  ? { require_role: fn.requireRole === null ? null : requireRoleToWire(fn.requireRole) }
681
708
  : {}),
682
709
  ...(fn.class !== undefined ? { class: fn.class } : {}),
710
+ ...(fn.capabilities !== undefined ? { capabilities: fn.capabilities } : {}),
683
711
  };
684
712
  }
685
713
  function functionMapToWire(map) {
@@ -697,7 +725,9 @@ function databaseToWire(database) {
697
725
  migrations: database.migrations.map((m) => ({
698
726
  id: m.id,
699
727
  checksum: m.checksum,
700
- sql_ref: contentRefToWire(m.sql_ref),
728
+ ...(m.sql !== undefined
729
+ ? { sql: m.sql }
730
+ : { sql_ref: contentRefToWire(requireContentRef(m.sql_ref, `database.migrations.${m.id}.sql_ref`)) }),
701
731
  ...(m.transaction !== undefined ? { transaction: m.transaction } : {}),
702
732
  })),
703
733
  }
@@ -758,13 +788,17 @@ function releaseSpecToWire(spec) {
758
788
  ...(spec.i18n !== undefined ? { i18n: spec.i18n === null ? null : i18nToWire(spec.i18n) } : {}),
759
789
  };
760
790
  }
761
- async function planInternal(client, spec, idempotencyKey, dryRun = false) {
791
+ async function planInternal(client, spec, idempotencyKey, dryRun = false, target = "cloud") {
762
792
  const ciCredentials = isCiClient(client);
763
793
  validateSpec(spec);
764
794
  if (ciCredentials)
765
795
  assertCiDeployableSpec(spec);
766
- const { normalized, byteReaders } = await normalizeReleaseSpec(client, spec);
767
- await preflightTierFunctionLimits(client, normalized, ciCredentials);
796
+ const isCore = target === "core";
797
+ const { normalized, byteReaders } = await normalizeReleaseSpec(client, spec, {
798
+ inlineMigrationSql: isCore,
799
+ });
800
+ if (!isCore)
801
+ await preflightTierFunctionLimits(client, normalized, ciCredentials);
768
802
  const wireSpec = releaseSpecToWire(normalized);
769
803
  // The gateway expects { spec, manifest_ref?, idempotency_key? } with
770
804
  // snake_case ReleaseSpec wire JSON. For oversized specs the SDK uploads
@@ -779,6 +813,15 @@ async function planInternal(client, spec, idempotencyKey, dryRun = false) {
779
813
  if (inlineBytes <= PLAN_BODY_LIMIT_BYTES) {
780
814
  body = inlineBody;
781
815
  }
816
+ else if (isCore) {
817
+ throw new Run402DeployError("Core deploy planning requires an inline spec under the gateway body cap; manifest_ref is not supported by Core Developer Preview yet.", {
818
+ code: "DRY_RUN_REQUIRES_INLINE_SPEC",
819
+ phase: "validate",
820
+ resource: "manifest_ref",
821
+ retryable: false,
822
+ context: "planning Core deploy",
823
+ });
824
+ }
782
825
  else {
783
826
  if (dryRun) {
784
827
  throw new Run402DeployError("Dry-run deploy planning requires an inline spec under the gateway body cap; the normalized deploy plan would require manifest_ref.", {
@@ -1250,6 +1293,33 @@ async function uploadMissing(client, projectId, presence, byteReaders, emit) {
1250
1293
  // above; this call is the plan-level idempotency anchor.
1251
1294
  await client.request(`/content/v1/plans/${encodeURIComponent(planRes.plan_id)}/commit`, { method: "POST", headers, body: {}, context: "committing content upload" });
1252
1295
  }
1296
+ async function uploadCoreContent(client, projectId, byteReaders, emit) {
1297
+ const entries = [...byteReaders.entries()].sort(([a], [b]) => a.localeCompare(b));
1298
+ const total = entries.length;
1299
+ let done = 0;
1300
+ for (const [sha256, reader] of entries) {
1301
+ const bytes = await reader();
1302
+ await client.request(`/projects/v1/${encodeURIComponent(projectId)}/content`, {
1303
+ method: "POST",
1304
+ body: {
1305
+ sha256,
1306
+ size: bytes.byteLength,
1307
+ content_type: reader.contentType ?? "application/octet-stream",
1308
+ bytes_base64: base64FromBytes(bytes),
1309
+ },
1310
+ context: "staging Core deploy content",
1311
+ });
1312
+ done += 1;
1313
+ emit({
1314
+ type: "content.upload.progress",
1315
+ label: reader.label ?? sha256,
1316
+ sha256,
1317
+ done,
1318
+ total,
1319
+ ...(reader.slice ? { slice_kind: reader.slice } : {}),
1320
+ });
1321
+ }
1322
+ }
1253
1323
  async function uploadOneWithRetry(fetchFn, session, bytes) {
1254
1324
  const MAX_ATTEMPTS = 3;
1255
1325
  for (let attempt = 1;; attempt++) {
@@ -1555,7 +1625,7 @@ async function startInternal(client, spec, opts) {
1555
1625
  ...(sliceKinds.length > 0 ? { slice_kinds: sliceKinds } : {}),
1556
1626
  });
1557
1627
  const { planId } = requirePersistedPlan(plan, "starting deploy");
1558
- const commit = await commitInternal(client, planId, opts.idempotencyKey, spec.project);
1628
+ const commit = requireCloudCommitResponse(await commitInternal(client, planId, opts.idempotencyKey, spec.project), "starting deploy");
1559
1629
  return await pollUntilReady(client, commit, plan.diff, plan.warnings, emit, spec.project, sliceKinds);
1560
1630
  })();
1561
1631
  // Avoid an unhandled-rejection at construction time. Consumers must call
@@ -1693,6 +1763,7 @@ const FUNCTION_SPEC_FIELDS = new Set([
1693
1763
  "requireAuth",
1694
1764
  "requireRole",
1695
1765
  "class",
1766
+ "capabilities",
1696
1767
  ]);
1697
1768
  const FUNCTION_CONFIG_FIELDS = new Set(["timeoutSeconds", "memoryMb"]);
1698
1769
  const SITE_SPEC_FIELDS = new Set(["replace", "patch", "public_paths"]);
@@ -2316,6 +2387,7 @@ function invalidRouteSpec(message, resource) {
2316
2387
  function normalizePlanResponse(plan) {
2317
2388
  const raw = plan;
2318
2389
  const warnings = Array.isArray(raw.warnings) ? raw.warnings : [];
2390
+ const missingContent = Array.isArray(raw.missing_content) ? raw.missing_content : [];
2319
2391
  if (raw.kind === "plan_response") {
2320
2392
  const diff = {
2321
2393
  is_noop: raw.is_noop,
@@ -2332,6 +2404,7 @@ function normalizePlanResponse(plan) {
2332
2404
  return {
2333
2405
  ...plan,
2334
2406
  warnings,
2407
+ missing_content: missingContent,
2335
2408
  diff,
2336
2409
  payment_required: raw.payment_required ?? null,
2337
2410
  };
@@ -2339,6 +2412,8 @@ function normalizePlanResponse(plan) {
2339
2412
  return {
2340
2413
  ...plan,
2341
2414
  warnings,
2415
+ missing_content: missingContent,
2416
+ diff: plan.diff ?? {},
2342
2417
  };
2343
2418
  }
2344
2419
  function requirePersistedPlan(plan, context) {
@@ -2353,6 +2428,77 @@ function requirePersistedPlan(plan, context) {
2353
2428
  context,
2354
2429
  });
2355
2430
  }
2431
+ function requirePlanId(plan, context) {
2432
+ if (plan.plan_id)
2433
+ return plan.plan_id;
2434
+ throw new Run402DeployError("Plan response cannot be committed because it does not include plan_id.", {
2435
+ code: "DRY_RUN_PLAN_NOT_COMMITTABLE",
2436
+ phase: "plan",
2437
+ resource: "plan_id",
2438
+ retryable: false,
2439
+ context,
2440
+ });
2441
+ }
2442
+ function isCoreCommitResponse(commit) {
2443
+ return (typeof commit.plan_id === "string" &&
2444
+ typeof commit.project_id === "string" &&
2445
+ typeof commit.release_digest === "string" &&
2446
+ (commit.status === "committed" ||
2447
+ commit.status === "noop" ||
2448
+ commit.status === "deferred"));
2449
+ }
2450
+ function requireCloudCommitResponse(commit, context) {
2451
+ if (!isCoreCommitResponse(commit))
2452
+ return commit;
2453
+ throw new Run402DeployError("Core commit response reached a Cloud operation-polling path.", {
2454
+ code: "INTERNAL_ERROR",
2455
+ phase: "commit",
2456
+ retryable: false,
2457
+ context,
2458
+ });
2459
+ }
2460
+ async function coreDeployResult(client, commit, diff, warnings, emit, projectId, sliceKinds = []) {
2461
+ if (commit.status === "deferred") {
2462
+ throw new Run402DeployError(commit.deferred_reason ?? "Core deploy commit deferred.", {
2463
+ code: "INTERNAL_ERROR",
2464
+ phase: commit.deferred_phase ?? "commit",
2465
+ retryable: true,
2466
+ context: "committing Core deploy",
2467
+ });
2468
+ }
2469
+ const urls = await coreProjectUrls(client, projectId);
2470
+ emit({
2471
+ type: "ready",
2472
+ releaseId: commit.release_id,
2473
+ urls,
2474
+ ...(sliceKinds.length > 0 ? { slice_kinds: sliceKinds } : {}),
2475
+ });
2476
+ return {
2477
+ release_id: commit.release_id,
2478
+ operation_id: `core:${commit.plan_id}`,
2479
+ urls,
2480
+ diff,
2481
+ warnings,
2482
+ };
2483
+ }
2484
+ async function coreProjectUrls(client, projectId) {
2485
+ try {
2486
+ const project = await client.request(`/projects/v1/${encodeURIComponent(projectId)}`, {
2487
+ method: "GET",
2488
+ context: "fetching Core project endpoints",
2489
+ });
2490
+ const staticUrl = project.endpoints?.static_base_url;
2491
+ return {
2492
+ ...(staticUrl ? { site: staticUrl, static: staticUrl } : {}),
2493
+ ...(project.endpoints?.rest_url ? { rest: project.endpoints.rest_url } : {}),
2494
+ ...(project.endpoints?.storage_base_url ? { storage: project.endpoints.storage_base_url } : {}),
2495
+ };
2496
+ }
2497
+ catch {
2498
+ const staticUrl = `${client.apiBase.replace(/\/+$/, "")}/projects/v1/${encodeURIComponent(projectId)}/static`;
2499
+ return { site: staticUrl, static: staticUrl };
2500
+ }
2501
+ }
2356
2502
  function emitPlanWarnings(plan, emit) {
2357
2503
  if (plan.warnings.length > 0) {
2358
2504
  emit({ type: "plan.warnings", warnings: plan.warnings });
@@ -2526,7 +2672,7 @@ function invalidSecretSpec(message, resource) {
2526
2672
  context: "validating spec",
2527
2673
  });
2528
2674
  }
2529
- async function normalizeReleaseSpec(client, spec) {
2675
+ async function normalizeReleaseSpec(client, spec, opts = {}) {
2530
2676
  const byteReaders = new Map();
2531
2677
  // Slice-tagged `remember`. Each slice category creates its own remember
2532
2678
  // closure so the registered reader carries `reader.slice = "release" |
@@ -2585,7 +2731,7 @@ async function normalizeReleaseSpec(client, spec) {
2585
2731
  db.zero_downtime = spec.database.zero_downtime;
2586
2732
  }
2587
2733
  if (spec.database.migrations && spec.database.migrations.length > 0) {
2588
- db.migrations = await Promise.all(spec.database.migrations.map(async (m) => normalizeMigration(client, spec.project, m, rememberRelease)));
2734
+ db.migrations = await Promise.all(spec.database.migrations.map(async (m) => normalizeMigration(client, spec.project, m, rememberRelease, opts)));
2589
2735
  }
2590
2736
  normalized.database = db;
2591
2737
  }
@@ -2667,6 +2813,8 @@ async function normalizeFunction(fn, remember) {
2667
2813
  out.requireRole = fn.requireRole;
2668
2814
  if (fn.class !== undefined)
2669
2815
  out.class = fn.class;
2816
+ if (fn.capabilities !== undefined)
2817
+ out.capabilities = [...fn.capabilities];
2670
2818
  if (fn.source !== undefined) {
2671
2819
  const resolved = await resolveContent(fn.source, "function source");
2672
2820
  out.source = remember(resolved);
@@ -2966,7 +3114,7 @@ async function normalizeAssetSlice(slice, remember) {
2966
3114
  }
2967
3115
  return out;
2968
3116
  }
2969
- async function normalizeMigration(client, projectId, m, remember) {
3117
+ async function normalizeMigration(client, projectId, m, remember, opts = {}) {
2970
3118
  if (!m.id) {
2971
3119
  throw new Run402DeployError("MigrationSpec.id is required", {
2972
3120
  code: "INVALID_SPEC",
@@ -2978,6 +3126,7 @@ async function normalizeMigration(client, projectId, m, remember) {
2978
3126
  });
2979
3127
  }
2980
3128
  let sql_ref;
3129
+ let sql;
2981
3130
  let checksum;
2982
3131
  if (m.sql_ref) {
2983
3132
  sql_ref = m.sql_ref;
@@ -2986,9 +3135,14 @@ async function normalizeMigration(client, projectId, m, remember) {
2986
3135
  else if (m.sql !== undefined) {
2987
3136
  const bytes = new TextEncoder().encode(m.sql);
2988
3137
  const sha256 = await sha256Hex(bytes);
2989
- const ref = { sha256, size: bytes.byteLength, contentType: "application/sql" };
2990
- remember({ ref, reader: makeBytesReader(bytes, `migration:${m.id}`) });
2991
- sql_ref = ref;
3138
+ if (opts.inlineMigrationSql) {
3139
+ sql = m.sql;
3140
+ }
3141
+ else {
3142
+ const ref = { sha256, size: bytes.byteLength, contentType: "application/sql" };
3143
+ remember({ ref, reader: makeBytesReader(bytes, `migration:${m.id}`) });
3144
+ sql_ref = ref;
3145
+ }
2992
3146
  checksum = m.checksum ?? sha256;
2993
3147
  }
2994
3148
  else {
@@ -3004,7 +3158,11 @@ async function normalizeMigration(client, projectId, m, remember) {
3004
3158
  context: "validating spec",
3005
3159
  });
3006
3160
  }
3007
- const out = { id: m.id, checksum, sql_ref };
3161
+ const out = { id: m.id, checksum };
3162
+ if (sql_ref)
3163
+ out.sql_ref = sql_ref;
3164
+ if (sql !== undefined)
3165
+ out.sql = sql;
3008
3166
  if (m.transaction)
3009
3167
  out.transaction = m.transaction;
3010
3168
  return out;