@cloudflare/vite-plugin 1.49.1 → 1.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -31,6 +31,8 @@ import { getCloudflarePreset, nonPrefixedNodeModules } from "@cloudflare/unenv-p
31
31
  import process$1, { exit, stdin, stdout } from "node:process";
32
32
  import v8 from "node:v8";
33
33
  import { defineEnv } from "unenv";
34
+ import os$1 from "os";
35
+ import { execSync } from "child_process";
34
36
  import tty from "node:tty";
35
37
  import P from "node:readline";
36
38
  import { WebSocket, WebSocketServer } from "ws";
@@ -1487,7 +1489,7 @@ async function assertWranglerVersion() {
1487
1489
  * The default compatibility date to use when the user omits one.
1488
1490
  * This value is injected at build time and remains fixed for each release.
1489
1491
  */
1490
- const DEFAULT_COMPAT_DATE = "2026-07-31";
1492
+ const DEFAULT_COMPAT_DATE = "2026-08-05";
1491
1493
 
1492
1494
  //#endregion
1493
1495
  //#region src/build-output-env.ts
@@ -26722,7 +26724,7 @@ var require_ci_info$1 = __commonJS$1({ "../../node_modules/.pnpm/ci-info@4.4.0/n
26722
26724
  } });
26723
26725
  var require_command_exists$2 = __commonJS$1({ "../../node_modules/.pnpm/command-exists@1.2.9/node_modules/command-exists/lib/command-exists.js"(exports$2, module$1) {
26724
26726
  var exec$3 = __require$1("child_process").exec;
26725
- var execSync$1 = __require$1("child_process").execSync;
26727
+ var execSync$2 = __require$1("child_process").execSync;
26726
26728
  var fs3 = __require$1("fs");
26727
26729
  var path6 = __require$1("path");
26728
26730
  var access$1 = fs3.access;
@@ -26778,7 +26780,7 @@ var require_command_exists$2 = __commonJS$1({ "../../node_modules/.pnpm/command-
26778
26780
  }, "commandExistsWindows");
26779
26781
  var commandExistsUnixSync$1 = /* @__PURE__ */ __name$4(function(commandName, cleanedCommandName) {
26780
26782
  if (fileNotExistsSync$1(commandName)) try {
26781
- return !!execSync$1("command -v " + cleanedCommandName + " 2>/dev/null && { echo >&1 " + cleanedCommandName + "; exit 0; }");
26783
+ return !!execSync$2("command -v " + cleanedCommandName + " 2>/dev/null && { echo >&1 " + cleanedCommandName + "; exit 0; }");
26782
26784
  } catch (error51) {
26783
26785
  return false;
26784
26786
  }
@@ -26787,7 +26789,7 @@ var require_command_exists$2 = __commonJS$1({ "../../node_modules/.pnpm/command-
26787
26789
  var commandExistsWindowsSync$1 = /* @__PURE__ */ __name$4(function(commandName, cleanedCommandName, callback$1) {
26788
26790
  if (!/^(?!(?:.*\s|.*\.|\W+)$)(?:[a-zA-Z]:)?(?:(?:[^<>:"\|\?\*\n])+(?:\/\/|\/|\\\\|\\)?)+$/m.test(commandName)) return false;
26789
26791
  try {
26790
- return !!execSync$1("where " + cleanedCommandName, { stdio: [] });
26792
+ return !!execSync$2("where " + cleanedCommandName, { stdio: [] });
26791
26793
  } catch (error51) {
26792
26794
  return false;
26793
26795
  }
@@ -27620,6 +27622,17 @@ var require_update_check = __commonJS$1({ "../../node_modules/.pnpm/update-check
27620
27622
  return null;
27621
27623
  };
27622
27624
  } });
27625
+ var ARTIFACTS_EVENT_TYPES = [
27626
+ "cf.artifacts.repo.created",
27627
+ "cf.artifacts.repo.deleted",
27628
+ "cf.artifacts.repo.forked",
27629
+ "cf.artifacts.repo.imported",
27630
+ "cf.artifacts.repo.pushed",
27631
+ "cf.artifacts.repo.cloned",
27632
+ "cf.artifacts.repo.fetched",
27633
+ "cf.artifacts.repo.token.created",
27634
+ "cf.artifacts.repo.token.revoked"
27635
+ ];
27623
27636
  function getDurableObjectExports(exports$2) {
27624
27637
  return partitionExports$1(exports$2)["durable-object"];
27625
27638
  }
@@ -41617,7 +41630,7 @@ var getLocalExplorerEnabledFromEnv = getBooleanEnvironmentVariableFactory({
41617
41630
  });
41618
41631
  var getLocalObservabilityEnabledFromEnv = getBooleanEnvironmentVariableFactory({
41619
41632
  variableName: "X_LOCAL_OBSERVABILITY",
41620
- defaultValue: false
41633
+ defaultValue: true
41621
41634
  });
41622
41635
  var getBrowserRenderingHeadfulFromEnv = getBooleanEnvironmentVariableFactory({
41623
41636
  variableName: "X_BROWSER_HEADFUL",
@@ -42435,7 +42448,7 @@ function normalizeAndValidateEnvironment(diagnostics, configPath, rawEnv, isDisp
42435
42448
  exports: inheritable(diagnostics, topLevelEnv, rawEnv, "exports", validateExports, {}),
42436
42449
  kv_namespaces: notInheritable(diagnostics, topLevelEnv, rawConfig, rawEnv, envName, "kv_namespaces", validateBindingArray(envName, validateKVBinding), []),
42437
42450
  cloudchamber: notInheritable(diagnostics, topLevelEnv, rawConfig, rawEnv, envName, "cloudchamber", validateCloudchamberConfig, {}),
42438
- containers: notInheritable(diagnostics, topLevelEnv, rawConfig, rawEnv, envName, "containers", validateContainerApp(envName, rawEnv.name, configPath), void 0),
42451
+ containers: notInheritable(diagnostics, topLevelEnv, rawConfig, rawEnv, envName, "containers", validateContainerApp(envName, rawEnv.name ?? rawConfig?.name, configPath), void 0),
42439
42452
  send_email: notInheritable(diagnostics, topLevelEnv, rawConfig, rawEnv, envName, "send_email", validateBindingArray(envName, validateSendEmailBinding), []),
42440
42453
  queues: notInheritable(diagnostics, topLevelEnv, rawConfig, rawEnv, envName, "queues", validateQueues(envName), {
42441
42454
  producers: [],
@@ -42498,9 +42511,10 @@ __name$4(validateAndNormalizeTsconfig, "validateAndNormalizeTsconfig");
42498
42511
  var validateAndNormalizeRules = /* @__PURE__ */ __name$4((diagnostics, topLevelEnv, rawEnv, envName) => {
42499
42512
  return inheritable(diagnostics, topLevelEnv, rawEnv, "rules", validateRules(envName), []);
42500
42513
  }, "validateAndNormalizeRules");
42514
+ var ARTIFACTS_EVENT_TYPE_SET = new Set(ARTIFACTS_EVENT_TYPES);
42501
42515
  var validateTriggers = /* @__PURE__ */ __name$4((diagnostics, triggersFieldName, triggersValue) => {
42502
42516
  if (triggersValue === void 0 || triggersValue === null) return true;
42503
- if (typeof triggersValue !== "object") {
42517
+ if (typeof triggersValue !== "object" || Array.isArray(triggersValue)) {
42504
42518
  diagnostics.errors.push(`Expected "${triggersFieldName}" to be of type object but got ${JSON.stringify(triggersValue)}.`);
42505
42519
  return false;
42506
42520
  }
@@ -42509,7 +42523,49 @@ var validateTriggers = /* @__PURE__ */ __name$4((diagnostics, triggersFieldName,
42509
42523
  diagnostics.errors.push(`Expected "${triggersFieldName}.crons" to be of type array, but got ${JSON.stringify(triggersValue)}.`);
42510
42524
  isValid = false;
42511
42525
  }
42512
- isValid = validateAdditionalProperties(diagnostics, triggersFieldName, Object.keys(triggersValue), ["crons"]) && isValid;
42526
+ if (hasProperty(triggersValue, "events") && !Array.isArray(triggersValue.events)) {
42527
+ diagnostics.errors.push(`Expected "${triggersFieldName}.events" to be of type array, but got ${JSON.stringify(triggersValue)}.`);
42528
+ isValid = false;
42529
+ } else if (hasProperty(triggersValue, "events") && Array.isArray(triggersValue.events)) for (const [eventIndex, event] of triggersValue.events.entries()) {
42530
+ const eventFieldName = `${triggersFieldName}.events[${eventIndex}]`;
42531
+ if (typeof event !== "object" || event === null || Array.isArray(event)) {
42532
+ diagnostics.errors.push(`Expected "${eventFieldName}" to be of type object, but got ${JSON.stringify(event)}.`);
42533
+ isValid = false;
42534
+ continue;
42535
+ }
42536
+ if (!isRequiredProperty(event, "type", "string") || !ARTIFACTS_EVENT_TYPE_SET.has(event.type)) {
42537
+ diagnostics.errors.push(`Expected "${eventFieldName}.type" to be a supported Artifacts event type, but got ${JSON.stringify(event.type)}.`);
42538
+ isValid = false;
42539
+ }
42540
+ if (hasProperty(event, "filter") && event.filter !== void 0) {
42541
+ if (typeof event.filter !== "object" || event.filter === null || Array.isArray(event.filter)) {
42542
+ diagnostics.errors.push(`Expected "${eventFieldName}.filter" to be of type object, but got ${JSON.stringify(event.filter)}.`);
42543
+ isValid = false;
42544
+ } else for (const [filterName, filterValue] of Object.entries(event.filter)) if (filterName !== "namespace" && filterName !== "repo_name" || typeof filterValue !== "string") {
42545
+ diagnostics.errors.push(`Expected "${eventFieldName}.filter" to contain only string "namespace" and "repo_name" fields, but got ${JSON.stringify(event.filter)}.`);
42546
+ isValid = false;
42547
+ break;
42548
+ }
42549
+ }
42550
+ if (!Array.isArray(event.targets) || event.targets.length === 0) {
42551
+ diagnostics.errors.push(`Expected "${eventFieldName}.targets" to be a non-empty array, but got ${JSON.stringify(event.targets)}.`);
42552
+ isValid = false;
42553
+ } else for (const [targetIndex, target$1] of event.targets.entries()) {
42554
+ const targetFieldName = `${eventFieldName}.targets[${targetIndex}]`;
42555
+ if (typeof target$1 !== "object" || target$1 === null || Array.isArray(target$1) || target$1.type !== "workflow" || typeof target$1.workflow_name !== "string" || target$1.workflow_name.length === 0) {
42556
+ diagnostics.errors.push(`Expected "${targetFieldName}" to be a workflow target with a non-empty "workflow_name", but got ${JSON.stringify(target$1)}.`);
42557
+ isValid = false;
42558
+ continue;
42559
+ }
42560
+ validateAdditionalProperties(diagnostics, targetFieldName, Object.keys(target$1), ["type", "workflow_name"]);
42561
+ }
42562
+ validateAdditionalProperties(diagnostics, eventFieldName, Object.keys(event), [
42563
+ "type",
42564
+ "filter",
42565
+ "targets"
42566
+ ]);
42567
+ }
42568
+ isValid = validateAdditionalProperties(diagnostics, triggersFieldName, Object.keys(triggersValue), ["crons", "events"]) && isValid;
42513
42569
  return isValid;
42514
42570
  }, "validateTriggers");
42515
42571
  var validateRules = /* @__PURE__ */ __name$4((envName) => (diagnostics, field, envValue, config2) => {
@@ -65476,6 +65532,480 @@ function createModuleReference(type, id) {
65476
65532
  return `__CLOUDFLARE_MODULE__${type}__${id}__CLOUDFLARE_MODULE__`;
65477
65533
  }
65478
65534
 
65535
+ //#endregion
65536
+ //#region ../../node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js
65537
+ function getProcessInfo(pid) {
65538
+ try {
65539
+ const output = execSync(`ps -p ${pid} -o pid=,ppid=,command=`, {
65540
+ encoding: "utf8",
65541
+ timeout: 5e3
65542
+ }).trim();
65543
+ if (!output) return null;
65544
+ const [pidStr, ppidStr, ...commandParts] = output.split(/\s+/);
65545
+ const parsedPid = pidStr ? parseInt(pidStr, 10) : NaN;
65546
+ const parsedPpid = ppidStr ? parseInt(ppidStr, 10) : NaN;
65547
+ if (isNaN(parsedPid) || isNaN(parsedPpid)) return null;
65548
+ return {
65549
+ pid: parsedPid,
65550
+ ppid: parsedPpid,
65551
+ command: commandParts.join(" ") || void 0
65552
+ };
65553
+ } catch (error$2) {
65554
+ if (error$2 instanceof Error && error$2.message.includes("timeout")) console.warn(`Process lookup timed out for PID ${pid}`);
65555
+ return null;
65556
+ }
65557
+ }
65558
+ function getAncestryUnix(startPid) {
65559
+ const result = [];
65560
+ const visited = /* @__PURE__ */ new Set();
65561
+ let currentPid = startPid;
65562
+ let maxDepth = 1e3;
65563
+ while (currentPid && maxDepth > 0) {
65564
+ if (visited.has(currentPid)) {
65565
+ console.warn(`Detected cycle in process tree at PID ${currentPid}`);
65566
+ break;
65567
+ }
65568
+ visited.add(currentPid);
65569
+ const info$1 = getProcessInfo(currentPid);
65570
+ if (!info$1 || info$1.ppid === 0 || info$1.ppid === 1) break;
65571
+ result.push(info$1);
65572
+ currentPid = info$1.ppid;
65573
+ maxDepth--;
65574
+ }
65575
+ if (maxDepth === 0) console.warn(`Reached maximum depth limit while traversing process tree from PID ${startPid}`);
65576
+ return result;
65577
+ }
65578
+ function getProcessInfo2(pid) {
65579
+ try {
65580
+ const output = execSync(`wmic process where (ProcessId=${pid}) get ProcessId,ParentProcessId,CommandLine /format:csv`, {
65581
+ encoding: "utf8",
65582
+ timeout: 1e4
65583
+ });
65584
+ if (!output) return null;
65585
+ const fields = output.split("\n").filter((line) => line.trim() && !line.startsWith("Node")).pop()?.split(",");
65586
+ if (!fields || fields.length < 4) return null;
65587
+ const [_node, commandLine, parentPid, thisPid] = fields;
65588
+ const parsedPid = thisPid ? parseInt(thisPid.trim(), 10) : NaN;
65589
+ const parsedPpid = parentPid ? parseInt(parentPid.trim(), 10) : NaN;
65590
+ if (isNaN(parsedPid) || isNaN(parsedPpid)) return null;
65591
+ return {
65592
+ pid: parsedPid,
65593
+ ppid: parsedPpid,
65594
+ command: commandLine?.trim() || void 0
65595
+ };
65596
+ } catch (error$2) {
65597
+ if (error$2 instanceof Error && error$2.message.includes("timeout")) console.warn(`Process lookup timed out for PID ${pid}`);
65598
+ return null;
65599
+ }
65600
+ }
65601
+ function getAncestryWindows(startPid) {
65602
+ const result = [];
65603
+ const visited = /* @__PURE__ */ new Set();
65604
+ let currentPid = startPid;
65605
+ let maxDepth = 1e3;
65606
+ while (currentPid && maxDepth > 0) {
65607
+ if (visited.has(currentPid)) {
65608
+ console.warn(`Detected cycle in process tree at PID ${currentPid}`);
65609
+ break;
65610
+ }
65611
+ visited.add(currentPid);
65612
+ const info$1 = getProcessInfo2(currentPid);
65613
+ if (!info$1 || info$1.ppid === 0 || info$1.ppid === 4) break;
65614
+ result.push(info$1);
65615
+ currentPid = info$1.ppid;
65616
+ maxDepth--;
65617
+ }
65618
+ if (maxDepth === 0) console.warn(`Reached maximum depth limit while traversing process tree from PID ${startPid}`);
65619
+ return result;
65620
+ }
65621
+ function getProcessAncestry(pid = process.pid) {
65622
+ if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0) throw new Error("PID must be a positive integer");
65623
+ if (os$1.platform() === "win32") return getAncestryWindows(pid);
65624
+ else return getAncestryUnix(pid);
65625
+ }
65626
+
65627
+ //#endregion
65628
+ //#region ../../node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.mjs
65629
+ /**
65630
+ * Provider configurations for major AI coding tools
65631
+ */
65632
+ const providers = [
65633
+ {
65634
+ id: "opencode",
65635
+ name: "OpenCode",
65636
+ type: "agent",
65637
+ envVars: [{ any: [
65638
+ "OPENCODE",
65639
+ "OPENCODE_BIN_PATH",
65640
+ "OPENCODE_SERVER",
65641
+ "OPENCODE_APP_INFO",
65642
+ "OPENCODE_MODES"
65643
+ ] }]
65644
+ },
65645
+ {
65646
+ id: "jules",
65647
+ name: "Jules",
65648
+ type: "agent",
65649
+ envVars: [{ all: [["HOME", "/home/jules"], ["USER", "swebot"]] }]
65650
+ },
65651
+ {
65652
+ id: "claude-code",
65653
+ name: "Claude Code",
65654
+ type: "agent",
65655
+ envVars: ["CLAUDECODE"]
65656
+ },
65657
+ {
65658
+ id: "cursor-agent",
65659
+ name: "Cursor Agent",
65660
+ type: "agent",
65661
+ envVars: [{ all: ["CURSOR_TRACE_ID", ["PAGER", "head -n 10000 | cat"]] }]
65662
+ },
65663
+ {
65664
+ id: "cursor",
65665
+ name: "Cursor",
65666
+ type: "interactive",
65667
+ envVars: ["CURSOR_TRACE_ID"]
65668
+ },
65669
+ {
65670
+ id: "antigravity",
65671
+ name: "Antigravity",
65672
+ type: "agent",
65673
+ envVars: [{ any: ["ANTIGRAVITY_AGENT", "ANTIGRAVITY_PROJECT_ID"] }]
65674
+ },
65675
+ {
65676
+ id: "gemini-agent",
65677
+ name: "Gemini CLI",
65678
+ type: "agent",
65679
+ envVars: [["GEMINI_CLI", "1"]],
65680
+ processChecks: ["gemini"]
65681
+ },
65682
+ {
65683
+ id: "codex",
65684
+ name: "OpenAI Codex",
65685
+ type: "agent",
65686
+ envVars: ["CODEX_THREAD_ID"],
65687
+ processChecks: ["codex"]
65688
+ },
65689
+ {
65690
+ id: "replit",
65691
+ name: "Replit",
65692
+ type: "agent",
65693
+ envVars: ["REPL_ID"]
65694
+ },
65695
+ {
65696
+ id: "aider",
65697
+ name: "Aider",
65698
+ type: "agent",
65699
+ envVars: ["AIDER_API_KEY"],
65700
+ processChecks: ["aider"]
65701
+ },
65702
+ {
65703
+ id: "bolt-agent",
65704
+ name: "Bolt.new Agent",
65705
+ type: "agent",
65706
+ envVars: [{ all: [["SHELL", "/bin/jsh"], "npm_config_yes"] }]
65707
+ },
65708
+ {
65709
+ id: "bolt",
65710
+ name: "Bolt.new",
65711
+ type: "interactive",
65712
+ envVars: [{
65713
+ all: [["SHELL", "/bin/jsh"]],
65714
+ none: ["npm_config_yes"]
65715
+ }]
65716
+ },
65717
+ {
65718
+ id: "zed-agent",
65719
+ name: "Zed Agent",
65720
+ type: "agent",
65721
+ envVars: [{ all: [["TERM_PROGRAM", "zed"], ["PAGER", "cat"]] }]
65722
+ },
65723
+ {
65724
+ id: "zed",
65725
+ name: "Zed",
65726
+ type: "interactive",
65727
+ envVars: [{
65728
+ all: [["TERM_PROGRAM", "zed"]],
65729
+ none: [["PAGER", "cat"]]
65730
+ }]
65731
+ },
65732
+ {
65733
+ id: "replit-assistant",
65734
+ name: "Replit Assistant",
65735
+ type: "agent",
65736
+ envVars: [{ all: ["REPL_ID", ["REPLIT_MODE", "assistant"]] }]
65737
+ },
65738
+ {
65739
+ id: "replit",
65740
+ name: "Replit",
65741
+ type: "interactive",
65742
+ envVars: [{
65743
+ all: ["REPL_ID"],
65744
+ none: [["REPLIT_MODE", "assistant"]]
65745
+ }]
65746
+ },
65747
+ {
65748
+ id: "windsurf",
65749
+ name: "Windsurf",
65750
+ type: "agent",
65751
+ envVars: ["CODEIUM_EDITOR_APP_ROOT"]
65752
+ },
65753
+ {
65754
+ id: "crush",
65755
+ name: "Crush",
65756
+ type: "agent",
65757
+ envVars: [{ any: [
65758
+ ["CRUSH", "1"],
65759
+ ["AGENT", "crush"],
65760
+ ["AI_AGENT", "crush"]
65761
+ ] }],
65762
+ processChecks: ["crush"]
65763
+ },
65764
+ {
65765
+ id: "amp",
65766
+ name: "Amp",
65767
+ type: "agent",
65768
+ envVars: [{ any: ["AMP_CURRENT_THREAD_ID", ["AGENT", "amp"]] }]
65769
+ },
65770
+ {
65771
+ id: "auggie",
65772
+ name: "Auggie",
65773
+ type: "agent",
65774
+ envVars: [["AUGMENT_AGENT", "1"]]
65775
+ },
65776
+ {
65777
+ id: "qwen-code",
65778
+ name: "Qwen Code",
65779
+ type: "agent",
65780
+ envVars: [["QWEN_CODE", "1"]]
65781
+ },
65782
+ {
65783
+ id: "vscode-copilot-agent",
65784
+ name: "GitHub Copilot in VS Code",
65785
+ type: "agent",
65786
+ envVars: [{ all: [["TERM_PROGRAM", "vscode"], ["GIT_PAGER", "cat"]] }]
65787
+ },
65788
+ {
65789
+ id: "warp",
65790
+ name: "Warp Terminal",
65791
+ type: "hybrid",
65792
+ envVars: [{ all: [["TERM_PROGRAM", "WarpTerminal"]] }]
65793
+ },
65794
+ {
65795
+ id: "octofriend",
65796
+ name: "Octofriend",
65797
+ type: "agent",
65798
+ processChecks: ["octofriend"]
65799
+ },
65800
+ {
65801
+ id: "devin",
65802
+ name: "Devin",
65803
+ type: "agent",
65804
+ processChecks: ["devin"]
65805
+ },
65806
+ {
65807
+ id: "droid",
65808
+ name: "Factory Droid",
65809
+ type: "agent",
65810
+ processChecks: ["droid"]
65811
+ },
65812
+ {
65813
+ id: "pi",
65814
+ name: "Pi",
65815
+ type: "agent",
65816
+ envVars: [["PI_CODING_AGENT", "true"]]
65817
+ }
65818
+ ];
65819
+ /**
65820
+ * Check if a specific environment variable exists (handles both strings and tuples)
65821
+ */
65822
+ function checkEnvVar(envVarDef, env$3 = process.env) {
65823
+ const [envVar, expectedValue] = typeof envVarDef === "string" ? [envVarDef, void 0] : envVarDef;
65824
+ const actualValue = env$3[envVar];
65825
+ return Boolean(actualValue && (!expectedValue || actualValue === expectedValue));
65826
+ }
65827
+ /**
65828
+ * Check if a process is running in the process tree
65829
+ */
65830
+ function checkProcess(processName, processAncestry) {
65831
+ for (const ancestorProcess of processAncestry) if (ancestorProcess.command?.includes(processName)) return true;
65832
+ return false;
65833
+ }
65834
+ /**
65835
+ * Check if an environment variable group matches based on its properties
65836
+ */
65837
+ function checkEnvVars(definition, env$3 = process.env) {
65838
+ if (typeof definition === "string" || Array.isArray(definition)) return checkEnvVar(definition, env$3);
65839
+ const { any: any$1, all: all$1, none } = definition;
65840
+ const anyResult = !any$1?.length || any$1.some((envVar) => checkEnvVar(envVar, env$3));
65841
+ const allResult = !all$1?.length || all$1.every((envVar) => checkEnvVar(envVar, env$3));
65842
+ const noneResult = !none?.length || !none.some((envVar) => checkEnvVar(envVar, env$3));
65843
+ return anyResult && allResult && noneResult;
65844
+ }
65845
+ /**
65846
+ * Run custom detectors for a provider
65847
+ */
65848
+ function runCustomDetectors(provider) {
65849
+ return provider.customDetectors?.some((detector) => {
65850
+ try {
65851
+ return detector();
65852
+ } catch {
65853
+ return false;
65854
+ }
65855
+ }) ?? false;
65856
+ }
65857
+ /**
65858
+ * Create a positive detection result
65859
+ */
65860
+ function createDetectedResult(provider) {
65861
+ return {
65862
+ isAgentic: true,
65863
+ id: provider.id,
65864
+ name: provider.name,
65865
+ type: provider.type
65866
+ };
65867
+ }
65868
+ /**
65869
+ * Normalize the various supported argument shapes into a DetectOptions object.
65870
+ *
65871
+ * Supported shapes:
65872
+ * - detectAgenticEnvironment()
65873
+ * - detectAgenticEnvironment(options)
65874
+ * - detectAgenticEnvironment(env) // legacy
65875
+ * - detectAgenticEnvironment(env, processAncestry) // legacy
65876
+ */
65877
+ function normalizeOptions(envOrOptions, legacyAncestry) {
65878
+ if (envOrOptions != null && typeof envOrOptions === "object" && ("env" in envOrOptions || "processAncestry" in envOrOptions || "checkProcesses" in envOrOptions)) {
65879
+ const opts = envOrOptions;
65880
+ return {
65881
+ env: opts.env ?? process.env,
65882
+ processAncestry: opts.processAncestry,
65883
+ checkProcesses: opts.checkProcesses ?? opts.processAncestry !== void 0
65884
+ };
65885
+ }
65886
+ return {
65887
+ env: envOrOptions ?? process.env,
65888
+ processAncestry: legacyAncestry,
65889
+ checkProcesses: legacyAncestry !== void 0
65890
+ };
65891
+ }
65892
+ function detectAgenticEnvironment(envOrOptions, legacyAncestry) {
65893
+ const { env: env$3, processAncestry, checkProcesses } = normalizeOptions(envOrOptions, legacyAncestry);
65894
+ for (const provider of providers) if (provider.envVars?.some((group) => checkEnvVars(group, env$3))) return createDetectedResult(provider);
65895
+ for (const provider of providers) if (runCustomDetectors(provider)) return createDetectedResult(provider);
65896
+ if (checkProcesses) {
65897
+ let cachedAncestry = processAncestry;
65898
+ const getAncestry = () => {
65899
+ if (cachedAncestry === void 0) try {
65900
+ cachedAncestry = getProcessAncestry();
65901
+ } catch {
65902
+ cachedAncestry = [];
65903
+ }
65904
+ return cachedAncestry;
65905
+ };
65906
+ for (const provider of providers) if (provider.processChecks?.some((processName) => checkProcess(processName, getAncestry()))) return createDetectedResult(provider);
65907
+ }
65908
+ return {
65909
+ isAgentic: false,
65910
+ id: null,
65911
+ name: null,
65912
+ type: null
65913
+ };
65914
+ }
65915
+
65916
+ //#endregion
65917
+ //#region src/detect-agent.ts
65918
+ const NO_PROCESS_ANCESTRY = [];
65919
+ /**
65920
+ * Detects whether the current process is being driven by an AI coding agent.
65921
+ *
65922
+ * True only when the detected type is exactly `"agent"`. Hybrid terminals (Warp,
65923
+ * VS Code) embed agentic features but still have a human at the keyboard, so
65924
+ * they're treated as interactive — note `isAgent()` from the library would
65925
+ * report them as agents.
65926
+ *
65927
+ * Any error resolves to `false` rather than propagating.
65928
+ */
65929
+ function isAgentSession() {
65930
+ try {
65931
+ return detectAgenticEnvironment({
65932
+ env: process.env,
65933
+ processAncestry: NO_PROCESS_ANCESTRY
65934
+ }).type === "agent";
65935
+ } catch {
65936
+ return false;
65937
+ }
65938
+ }
65939
+
65940
+ //#endregion
65941
+ //#region src/plugins/agent-hint.ts
65942
+ /**
65943
+ * Plugin that prints the Local Explorer API URL and useful routes when
65944
+ * the dev server is started by a headless AI agent. This allows agents
65945
+ * to discover and call the Local Explorer API programmatically.
65946
+ *
65947
+ * The hint is printed by patching `server.bindCLIShortcuts` so it
65948
+ * appears after both the server URLs and the keyboard shortcut hints.
65949
+ */
65950
+ const agentHintPlugin = createPlugin("agent-hint", () => {
65951
+ return {
65952
+ configureServer(viteDevServer) {
65953
+ maybeAddAgentHint(viteDevServer, "dev");
65954
+ },
65955
+ configurePreviewServer(vitePreviewServer) {
65956
+ maybeAddAgentHint(vitePreviewServer, "preview");
65957
+ }
65958
+ };
65959
+ });
65960
+ /**
65961
+ * If the session is a headless AI agent with Local Explorer enabled,
65962
+ * patches `server.bindCLIShortcuts` to print the explorer API hint
65963
+ * after the shortcut hints have been printed.
65964
+ *
65965
+ * @param server - The Vite dev or preview server
65966
+ * @param mode - Whether this is a "dev" or "preview" session
65967
+ */
65968
+ function maybeAddAgentHint(server, mode) {
65969
+ if (process.stdin.isTTY || !getLocalExplorerEnabledFromEnv() || !isAgentSession()) return;
65970
+ const originalBindCLIShortcuts = server.bindCLIShortcuts.bind(server);
65971
+ server.bindCLIShortcuts = (options) => {
65972
+ originalBindCLIShortcuts(options);
65973
+ if (options?.print) printLocalExplorerAgentHint(server, mode);
65974
+ };
65975
+ }
65976
+ /**
65977
+ * Prints the Local Explorer API URL and useful routes to stdout so that
65978
+ * headless AI agents can discover and call them programmatically.
65979
+ *
65980
+ * Keep the message in sync with the wrangler copy in
65981
+ * packages/wrangler/src/dev/start-dev.ts.
65982
+ *
65983
+ * @param server - The Vite dev or preview server (must have `resolvedUrls` populated)
65984
+ * @param mode - Whether this is a "dev" or "preview" session
65985
+ */
65986
+ function printLocalExplorerAgentHint(server, mode) {
65987
+ const url$2 = server.resolvedUrls?.local[0];
65988
+ if (!url$2) return;
65989
+ const explorerApiUrl = new URL(`${CorePaths.EXPLORER}/api`, url$2).href;
65990
+ server.config.logger.info([
65991
+ "",
65992
+ `The Cloudflare Vite plugin detected this ${mode} session is running in an AI agent.`,
65993
+ `The Local Explorer API is available at ${explorerApiUrl}`,
65994
+ `Useful routes:`,
65995
+ ` GET ${explorerApiUrl}/local/workers - local Workers and bindings`,
65996
+ ` GET ${explorerApiUrl}/storage/kv/namespaces - KV namespaces`,
65997
+ ` GET ${explorerApiUrl}/d1/database - D1 databases`,
65998
+ ` GET ${explorerApiUrl}/r2/buckets - R2 buckets`,
65999
+ ` GET ${explorerApiUrl}/workers/durable_objects/namespaces - Durable Object namespaces`,
66000
+ ` GET ${explorerApiUrl}/workflows - Workflows`,
66001
+ ` POST ${explorerApiUrl}/local/observability/query - run a read-only SQL query (SELECT/WITH only) over captured request traces and console logs. Tables: spans, logs (read attributes via json(attributes)). Example:`,
66002
+ ` curl -X POST ${explorerApiUrl}/local/observability/query -H 'Content-Type: application/json' -d '{"sql":"SELECT service, name, outcome, duration_ms FROM spans WHERE parent_id IS NULL LIMIT 20"}'`,
66003
+ `If the routes above don't cover what you need, fetch the full OpenAPI schema (large - use only as a last resort):`,
66004
+ ` GET ${explorerApiUrl} - OpenAPI schema`,
66005
+ ""
66006
+ ].join("\n"));
66007
+ }
66008
+
65479
66009
  //#endregion
65480
66010
  //#region src/cloudflare-environment.ts
65481
66011
  const MAIN_ENTRY_NAME = "index";
@@ -72389,7 +72919,7 @@ var __name$1 = (target$1, value) => __defProp$1(target$1, "name", {
72389
72919
  });
72390
72920
 
72391
72921
  //#endregion
72392
- //#region ../workers-auth/dist/chunk-PBW6773T.mjs
72922
+ //#region ../workers-auth/dist/chunk-7AYQ2BAF.mjs
72393
72923
  var import_undici$2 = require_undici();
72394
72924
  var hasWarnedAboutDeprecatedV1ApiToken = false;
72395
72925
  function readStoredAuthState(options) {
@@ -72458,6 +72988,12 @@ function requireApiToken(options) {
72458
72988
  return credentials;
72459
72989
  }
72460
72990
  __name$1(requireApiToken, "requireApiToken");
72991
+ var ACCOUNT_ID_PATTERN = /^[A-Za-z0-9_-]+$/;
72992
+ function validateAccountId(accountId, source) {
72993
+ if (!ACCOUNT_ID_PATTERN.test(accountId)) throw new UserError(`Invalid account ID "${accountId}" ${source}. Account IDs may only contain alphanumeric characters, hyphens, and underscores.`, { telemetryMessage: "user account id invalid characters" });
72994
+ return accountId;
72995
+ }
72996
+ __name$1(validateAccountId, "validateAccountId");
72461
72997
  var getAuthDomainFromEnv = getEnvironmentVariableFactory({
72462
72998
  variableName: "WRANGLER_AUTH_DOMAIN",
72463
72999
  defaultValue: /* @__PURE__ */ __name$1(() => getCloudflareApiEnvironmentFromEnv() === "staging" ? "dash.staging.cloudflare.com" : "dash.cloudflare.com", "defaultValue")
@@ -72474,10 +73010,21 @@ var getRevokeUrlFromEnv = getEnvironmentVariableFactory({
72474
73010
  variableName: "WRANGLER_REVOKE_URL",
72475
73011
  defaultValue: /* @__PURE__ */ __name$1(() => `https://${getAuthDomainFromEnv()}/oauth2/revoke`, "defaultValue")
72476
73012
  });
72477
- var getCloudflareAccountIdFromEnv = getEnvironmentVariableFactory({
73013
+ var readCloudflareAccountIdFromEnv = getEnvironmentVariableFactory({
72478
73014
  variableName: "CLOUDFLARE_ACCOUNT_ID",
72479
73015
  deprecatedName: "CF_ACCOUNT_ID"
72480
73016
  });
73017
+ function getCloudflareAccountIdFromEnv() {
73018
+ const accountId = readCloudflareAccountIdFromEnv();
73019
+ if (!accountId) return;
73020
+ return validateAccountId(accountId, "set in the `CLOUDFLARE_ACCOUNT_ID` environment variable");
73021
+ }
73022
+ __name$1(getCloudflareAccountIdFromEnv, "getCloudflareAccountIdFromEnv");
73023
+ var DEVICE_AUTH_PATH = "/oauth2/device/auth";
73024
+ function getDeviceAuthUrl() {
73025
+ return `https://${getAuthDomainFromEnv()}${DEVICE_AUTH_PATH}`;
73026
+ }
73027
+ __name$1(getDeviceAuthUrl, "getDeviceAuthUrl");
72481
73028
  var getAccessClientIdFromEnv = getEnvironmentVariableFactory({ variableName: "CLOUDFLARE_ACCESS_CLIENT_ID" });
72482
73029
  var getAccessClientSecretFromEnv = getEnvironmentVariableFactory({ variableName: "CLOUDFLARE_ACCESS_CLIENT_SECRET" });
72483
73030
  var getCfAuthorizationTokenFromEnv = getEnvironmentVariableFactory({ variableName: "WRANGLER_CF_AUTHORIZATION_TOKEN" });
@@ -72623,6 +73170,26 @@ async function generatePKCECodes() {
72623
73170
  };
72624
73171
  }
72625
73172
  __name$1(generatePKCECodes, "generatePKCECodes");
73173
+ var generateVerificationUrl = /* @__PURE__ */ __name$1(({ verificationUri, userCode }) => {
73174
+ const url2 = new URL(verificationUri);
73175
+ url2.searchParams.set("user_code", userCode);
73176
+ return url2.toString();
73177
+ }, "generateVerificationUrl");
73178
+ function parseUrl(value) {
73179
+ try {
73180
+ return new URL(value);
73181
+ } catch {
73182
+ return;
73183
+ }
73184
+ }
73185
+ __name$1(parseUrl, "parseUrl");
73186
+ function assertTrustedVerificationUrl(verificationUrl, options) {
73187
+ const url2 = parseUrl(verificationUrl);
73188
+ const expected = parseUrl(`https://${options.authDomain}`);
73189
+ if (!(url2 !== void 0 && expected !== void 0 && url2.protocol === "https:" && url2.username === "" && url2.password === "" && url2.host === expected.host)) throw new UserError(`The authorization server returned an untrusted \`${options.field}\`: ${verificationUrl}
73190
+ Expected an \`https\` URL on \`${options.authDomain}\`. Refusing to display or open it.`, { telemetryMessage: "user device-flow untrusted verification url" });
73191
+ }
73192
+ __name$1(assertTrustedVerificationUrl, "assertTrustedVerificationUrl");
72626
73193
  var generateAuthUrl = /* @__PURE__ */ __name$1(({ authUrl, clientId, scopes, stateQueryParam, codeChallenge, redirectUri }) => {
72627
73194
  return authUrl + `?response_type=code&client_id=${encodeURIComponent(clientId)}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${encodeURIComponent([...scopes, "offline_access"].join(" "))}&state=${stateQueryParam}&code_challenge=${encodeURIComponent(codeChallenge)}&code_challenge_method=S256`;
72628
73195
  }, "generateAuthUrl");
@@ -73276,6 +73843,228 @@ If you have changed the callback host or port because you are running in a conta
73276
73843
  return Promise.race([timerPromise, loginPromise]);
73277
73844
  }
73278
73845
  __name$1(getOauthToken, "getOauthToken");
73846
+ var DEVICE_FLOW_MAX_DURATION_SECONDS = 300;
73847
+ var DEVICE_FLOW_MIN_POLL_INTERVAL_SECONDS = 1;
73848
+ function getStringMember(body, key) {
73849
+ if (typeof body !== "object" || body === null) return;
73850
+ const value = body[key];
73851
+ return typeof value === "string" && value !== "" ? value : void 0;
73852
+ }
73853
+ __name$1(getStringMember, "getStringMember");
73854
+ function getPositiveNumberMember(body, key) {
73855
+ if (typeof body !== "object" || body === null) return;
73856
+ const value = body[key];
73857
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
73858
+ }
73859
+ __name$1(getPositiveNumberMember, "getPositiveNumberMember");
73860
+ function describeUnusableResponse(response, body) {
73861
+ const status$1 = `HTTP ${response.status} ${response.statusText}`.trim();
73862
+ const description = getStringMember(body, "error_description");
73863
+ return description ? `${status$1}: ${description}` : status$1;
73864
+ }
73865
+ __name$1(describeUnusableResponse, "describeUnusableResponse");
73866
+ function isRetryableStatus(status$1) {
73867
+ return status$1 >= 500 || status$1 === 429;
73868
+ }
73869
+ __name$1(isRetryableStatus, "isRetryableStatus");
73870
+ function asDeviceAuthorizationResponse(body) {
73871
+ const deviceCode = getStringMember(body, "device_code");
73872
+ const userCode = getStringMember(body, "user_code");
73873
+ const verificationUri = getStringMember(body, "verification_uri");
73874
+ const expiresIn = getPositiveNumberMember(body, "expires_in");
73875
+ if (!deviceCode || !userCode || !verificationUri || expiresIn === void 0) return;
73876
+ return {
73877
+ device_code: deviceCode,
73878
+ user_code: userCode,
73879
+ verification_uri: verificationUri,
73880
+ verification_uri_complete: getStringMember(body, "verification_uri_complete"),
73881
+ expires_in: expiresIn,
73882
+ interval: getPositiveNumberMember(body, "interval")
73883
+ };
73884
+ }
73885
+ __name$1(asDeviceAuthorizationResponse, "asDeviceAuthorizationResponse");
73886
+ async function readJson(response, logger$1) {
73887
+ const text = await response.text();
73888
+ try {
73889
+ return JSON.parse(text);
73890
+ } catch (e) {
73891
+ if (text.match(/<!DOCTYPE html>/)) {
73892
+ logger$1.debug("The body of the response was HTML rather than JSON. Check the debug logs to see the full body of the response.");
73893
+ if (text.match(/challenge-platform/)) logger$1.debug(`It looks like you might have hit a bot challenge page. This may be transient but if not, please contact Cloudflare to find out what can be done. When you contact Cloudflare, please provide your Ray ID: ${response.headers.get("cf-ray")}`);
73894
+ }
73895
+ logger$1.debug("Full body of response\n\n", text);
73896
+ throw new Error(`Invalid JSON in response: status: ${response.status} ${response.statusText}`, { cause: e });
73897
+ }
73898
+ }
73899
+ __name$1(readJson, "readJson");
73900
+ async function buildDeviceAuthHeaders(logger$1, isNonInteractiveOrCI2) {
73901
+ const headers = { "Content-Type": "application/x-www-form-urlencoded" };
73902
+ if (await domainUsesAccess(getAuthDomainFromEnv(), logger$1)) {
73903
+ logger$1.debug("Using Cloudflare Access to get an access token for the device authorization request");
73904
+ Object.assign(headers, await getCloudflareAccessHeaders({
73905
+ logger: logger$1,
73906
+ isNonInteractiveOrCI: isNonInteractiveOrCI2
73907
+ }));
73908
+ }
73909
+ return headers;
73910
+ }
73911
+ __name$1(buildDeviceAuthHeaders, "buildDeviceAuthHeaders");
73912
+ async function requestDeviceAuthorization(scopes, clientId, logger$1, isNonInteractiveOrCI2) {
73913
+ const params = new URLSearchParams({
73914
+ client_id: clientId,
73915
+ scope: [...scopes, "offline_access"].join(" ")
73916
+ });
73917
+ const headers = await buildDeviceAuthHeaders(logger$1, isNonInteractiveOrCI2);
73918
+ const deviceAuthUrl = getDeviceAuthUrl();
73919
+ logger$1.debug("Fetching device authorization from", deviceAuthUrl);
73920
+ const response = await (0, import_undici$2.fetch)(deviceAuthUrl, {
73921
+ method: "POST",
73922
+ body: params.toString(),
73923
+ headers
73924
+ });
73925
+ if (!response.ok) {
73926
+ const body2 = await readJson(response, logger$1).catch(() => void 0);
73927
+ throw toErrorClass(body2 && typeof body2 === "object" && "error" in body2 ? String(body2.error) : `HTTP ${response.status} ${response.statusText}`);
73928
+ }
73929
+ const body = await readJson(response, logger$1);
73930
+ const deviceAuth = asDeviceAuthorizationResponse(body);
73931
+ if (deviceAuth === void 0) {
73932
+ logger$1.debug("Unusable device authorization response body:", body);
73933
+ throw new UserError(`The device authorization endpoint returned a response that could not be interpreted (${describeUnusableResponse(response, body)}).
73934
+ Enable debug logging to see the full response.`, { telemetryMessage: "user device-flow unusable device authorization response" });
73935
+ }
73936
+ return deviceAuth;
73937
+ }
73938
+ __name$1(requestDeviceAuthorization, "requestDeviceAuthorization");
73939
+ async function pollDeviceToken(deviceCode, clientId, logger$1, isNonInteractiveOrCI2) {
73940
+ const response = await fetchAuthToken(new URLSearchParams({
73941
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
73942
+ device_code: deviceCode,
73943
+ client_id: clientId
73944
+ }), logger$1, isNonInteractiveOrCI2);
73945
+ const body = await readJson(response, logger$1);
73946
+ const error$2 = getStringMember(body, "error");
73947
+ if (error$2 !== void 0) return {
73948
+ kind: "oauth-error",
73949
+ error: error$2
73950
+ };
73951
+ const accessToken = getStringMember(body, "access_token");
73952
+ const expiresIn = getPositiveNumberMember(body, "expires_in");
73953
+ if (!response.ok || accessToken === void 0 || expiresIn === void 0) {
73954
+ logger$1.debug("Unusable token response body:", body);
73955
+ return {
73956
+ kind: "unexpected",
73957
+ detail: describeUnusableResponse(response, body),
73958
+ retryable: !response.ok && isRetryableStatus(response.status)
73959
+ };
73960
+ }
73961
+ return {
73962
+ kind: "token",
73963
+ grant: {
73964
+ access_token: accessToken,
73965
+ expires_in: expiresIn,
73966
+ refresh_token: getStringMember(body, "refresh_token"),
73967
+ scope: getStringMember(body, "scope")
73968
+ }
73969
+ };
73970
+ }
73971
+ __name$1(pollDeviceToken, "pollDeviceToken");
73972
+ function sleep(seconds) {
73973
+ return new Promise((resolve$4) => setTimeout(resolve$4, seconds * 1e3));
73974
+ }
73975
+ __name$1(sleep, "sleep");
73976
+ async function getOauthTokenViaDeviceFlow(options, ctx) {
73977
+ const { logger: logger$1, openInBrowser: openInBrowser$1, isNonInteractiveOrCI: isNonInteractiveOrCI2 } = ctx;
73978
+ const deviceAuth = await requestDeviceAuthorization(options.scopes, options.clientId, logger$1, isNonInteractiveOrCI2);
73979
+ const authDomain = getAuthDomainFromEnv();
73980
+ assertTrustedVerificationUrl(deviceAuth.verification_uri, {
73981
+ field: "verification_uri",
73982
+ authDomain
73983
+ });
73984
+ if (deviceAuth.verification_uri_complete !== void 0) assertTrustedVerificationUrl(deviceAuth.verification_uri_complete, {
73985
+ field: "verification_uri_complete",
73986
+ authDomain
73987
+ });
73988
+ const verificationUrl = deviceAuth.verification_uri_complete ?? generateVerificationUrl({
73989
+ verificationUri: deviceAuth.verification_uri,
73990
+ userCode: deviceAuth.user_code
73991
+ });
73992
+ const maxDurationSeconds = Math.min(deviceAuth.expires_in, DEVICE_FLOW_MAX_DURATION_SECONDS);
73993
+ logger$1.log(esm_default`
73994
+ To authorize ${ctx.displayName}, please visit:
73995
+
73996
+ ${deviceAuth.verification_uri}
73997
+
73998
+ and enter the code:
73999
+
74000
+ ${deviceAuth.user_code}
74001
+
74002
+ You have ${toHumanPeriod(maxDurationSeconds)} to approve this request.
74003
+ `);
74004
+ if (options.browser) {
74005
+ logger$1.log(`
74006
+ Opening a link in your default browser: ${verificationUrl}`);
74007
+ await openInBrowser$1(verificationUrl);
74008
+ }
74009
+ const deadline = Date.now() + maxDurationSeconds * 1e3;
74010
+ let intervalSeconds = Math.max(deviceAuth.interval ?? DEVICE_FLOW_MIN_POLL_INTERVAL_SECONDS, DEVICE_FLOW_MIN_POLL_INTERVAL_SECONDS);
74011
+ let firstPoll = true;
74012
+ let lastPollFailure;
74013
+ while (Date.now() < deadline) {
74014
+ if (!firstPoll) await sleep(intervalSeconds);
74015
+ firstPoll = false;
74016
+ let result;
74017
+ try {
74018
+ result = await pollDeviceToken(deviceAuth.device_code, options.clientId, logger$1, isNonInteractiveOrCI2);
74019
+ } catch (e) {
74020
+ logger$1.debug("Ignoring transient error while polling for token:", e);
74021
+ lastPollFailure = e instanceof Error ? e.message : String(e);
74022
+ continue;
74023
+ }
74024
+ if (result.kind === "unexpected") {
74025
+ if (!result.retryable) throw new UserError(`The token endpoint returned a response that could not be interpreted (${result.detail}).
74026
+ Enable debug logging to see the full response.`, { telemetryMessage: "user device-flow unusable token response" });
74027
+ logger$1.debug("Ignoring transient response while polling for token:", result.detail);
74028
+ lastPollFailure = result.detail;
74029
+ continue;
74030
+ }
74031
+ lastPollFailure = void 0;
74032
+ if (result.kind === "oauth-error") switch (result.error) {
74033
+ case "authorization_pending": continue;
74034
+ case "slow_down":
74035
+ intervalSeconds += 5;
74036
+ continue;
74037
+ case "access_denied": throw new UserError(`Consent denied. You must grant consent to ${ctx.displayName} in order to login.
74038
+ If you don't want to do this consider passing an API token via the \`CLOUDFLARE_API_TOKEN\` environment variable.`, { telemetryMessage: "user device-flow consent denied" });
74039
+ case "expired_token": throw new UserError(`Device code expired before the request was approved. Please run \`${ctx.deviceLoginCommand}\` again to obtain a new code.`, { telemetryMessage: "user device-flow code expired" });
74040
+ default: throw toErrorClass(result.error);
74041
+ }
74042
+ const { grant } = result;
74043
+ return {
74044
+ token: {
74045
+ value: grant.access_token,
74046
+ expiry: new Date(Date.now() + grant.expires_in * 1e3).toISOString()
74047
+ },
74048
+ scopes: grant.scope ? grant.scope.split(" ") : [],
74049
+ refreshToken: grant.refresh_token ? { value: grant.refresh_token } : void 0
74050
+ };
74051
+ }
74052
+ if (lastPollFailure !== void 0) throw new UserError(`Gave up waiting for device authorization: the token endpoint kept returning responses that could not be interpreted (last: ${lastPollFailure}).
74053
+ Enable debug logging to see the full response, then run \`${ctx.deviceLoginCommand}\` to try again.`, { telemetryMessage: "user device-flow poll failed" });
74054
+ throw new UserError(`Device authorization timed out after ${toHumanPeriod(maxDurationSeconds)}. Please run \`${ctx.deviceLoginCommand}\` again to obtain a new code.`, { telemetryMessage: "user device-flow authorization timeout" });
74055
+ }
74056
+ __name$1(getOauthTokenViaDeviceFlow, "getOauthTokenViaDeviceFlow");
74057
+ function toHumanPeriod(seconds) {
74058
+ if (seconds < 60) return `${seconds} seconds`;
74059
+ const minutes = Math.floor(seconds / 60);
74060
+ const minutesPostfix = minutes === 1 ? "minute" : "minutes";
74061
+ const remainingSeconds = seconds % 60;
74062
+ const secondsPostfix = remainingSeconds === 1 ? "second" : "seconds";
74063
+ if (remainingSeconds === 0) return `${minutes} ${minutesPostfix}`;
74064
+ if (remainingSeconds == 59) return `${minutes + 1} ${minutesPostfix}`;
74065
+ return `${minutes} ${minutesPostfix} and ${remainingSeconds} ${secondsPostfix}`;
74066
+ }
74067
+ __name$1(toHumanPeriod, "toHumanPeriod");
73279
74068
  function createOAuthFlow(ctx) {
73280
74069
  const oauthFlowState = {};
73281
74070
  const generators = {
@@ -73304,17 +74093,27 @@ function createOAuthFlow(ctx) {
73304
74093
  OAuth login is not supported in the \`${complianceRegion}\` compliance region.
73305
74094
  Please use a Cloudflare API token (\`CLOUDFLARE_API_TOKEN\` environment variable) or remove the ${props.complianceConfig?.compliance_region ? "`compliance_region` configuration property" : "`CLOUDFLARE_API_ENVIRONMENT` environment variable"}.
73306
74095
  `, { telemetryMessage: "user login unsupported compliance region" });
73307
- ctx.logger.log("Attempting to login via OAuth...");
73308
- const oauth = await getOauthToken({
73309
- browser: props.browser ?? true,
73310
- scopes: props.scopes,
73311
- clientId: getClientId(),
73312
- redirectUri: ctx.redirectUri,
73313
- denied: consent.denied,
73314
- granted: consent.granted,
73315
- callbackHost: props.callbackHost ?? defaultCallbackHost,
73316
- callbackPort: props.callbackPort ?? defaultCallbackPort
73317
- }, oauthFlowState, ctx, generators);
74096
+ let oauth;
74097
+ if (props.device) {
74098
+ ctx.logger.log("Attempting to login via OAuth Device Authorization Grant...");
74099
+ oauth = await getOauthTokenViaDeviceFlow({
74100
+ browser: props.browser ?? true,
74101
+ scopes: props.scopes,
74102
+ clientId: getClientId()
74103
+ }, ctx);
74104
+ } else {
74105
+ ctx.logger.log("Attempting to login via OAuth...");
74106
+ oauth = await getOauthToken({
74107
+ browser: props.browser ?? true,
74108
+ scopes: props.scopes,
74109
+ clientId: getClientId(),
74110
+ redirectUri: ctx.redirectUri,
74111
+ denied: consent.denied,
74112
+ granted: consent.granted,
74113
+ callbackHost: props.callbackHost ?? defaultCallbackHost,
74114
+ callbackPort: props.callbackPort ?? defaultCallbackPort
74115
+ }, oauthFlowState, ctx, generators);
74116
+ }
73318
74117
  getStorage(props.profile).write({
73319
74118
  oauth_token: oauth.token?.value ?? "",
73320
74119
  expiration_time: oauth.token?.expiry,
@@ -75060,7 +75859,7 @@ function scrubEncryptedCredentials(options) {
75060
75859
  __name$1(scrubEncryptedCredentials, "scrubEncryptedCredentials");
75061
75860
 
75062
75861
  //#endregion
75063
- //#region ../workers-auth/dist/chunk-RTFTHYPD.mjs
75862
+ //#region ../workers-auth/dist/chunk-AEOSGWMT.mjs
75064
75863
  function createPreferences(getConfigPath) {
75065
75864
  function getUserPreferencesPath() {
75066
75865
  return path2__default.resolve(getConfigPath(), "preferences.json");
@@ -75802,6 +76601,8 @@ Run \`${descriptor.commands.whoami}\` to check your current authentication statu
75802
76601
  purgeOnLoginOrLogout: configCache.purgeConfigCaches,
75803
76602
  clientId: descriptor.clientId,
75804
76603
  consent: descriptor.consent,
76604
+ displayName: descriptor.displayName,
76605
+ deviceLoginCommand: descriptor.commands.deviceLogin,
75805
76606
  redirectUri: descriptor.redirectUri,
75806
76607
  storageFactory: credentialStorage.storageFactory,
75807
76608
  allowGlobalAuthKey,
@@ -75844,7 +76645,8 @@ Run \`${descriptor.commands.whoami}\` to check your current authentication statu
75844
76645
  browser: props?.browser ?? true,
75845
76646
  callbackHost: props?.callbackHost,
75846
76647
  callbackPort: props?.callbackPort,
75847
- profile: props?.profile
76648
+ profile: props?.profile,
76649
+ device: props?.device
75848
76650
  };
75849
76651
  }
75850
76652
  __name$1(withDefaultScopes, "withDefaultScopes");
@@ -75936,7 +76738,7 @@ Alternatively, try running \`${descriptor.commands.login}\` to re-authenticate.`
75936
76738
  function getActiveAccountId(config$2) {
75937
76739
  const temporaryAccount = oauthFlow.getActiveTemporaryAccount();
75938
76740
  if (temporaryAccount) return temporaryAccount.account.id;
75939
- if (config$2.account_id) return config$2.account_id;
76741
+ if (config$2.account_id) return validateAccountId(config$2.account_id, `set as \`account_id\` in your ${descriptor.getConfigFileLabel()} file`);
75940
76742
  const envAccountId = getCloudflareAccountIdFromEnv();
75941
76743
  if (envAccountId) return envAccountId;
75942
76744
  return getAccountFromCache()?.id;
@@ -76188,6 +76990,7 @@ __name$1(createAuthConfigFileHelpers, "createAuthConfigFileHelpers");
76188
76990
  //#region ../workers-auth/dist/cf/index.mjs
76189
76991
  var CF_KEYRING_SERVICE_NAME = "cloudflare";
76190
76992
  var CF_CLI_NAME = "cf";
76993
+ var CF_DISPLAY_NAME = "cf";
76191
76994
  var CF_OAUTH_CALLBACK_URL = "http://localhost:8877/oauth/callback";
76192
76995
  var CF_CONSENT_PAGES = {
76193
76996
  granted: { url: "https://welcome.developers.workers.dev/cf-oauth-consent-granted" },
@@ -76325,10 +77128,12 @@ var { getAuthConfigFilePath: getAuthConfigFilePath$1, getEncryptedAuthConfigFile
76325
77128
  });
76326
77129
  var CF_CLI = {
76327
77130
  cliName: CF_CLI_NAME,
77131
+ displayName: CF_DISPLAY_NAME,
76328
77132
  commands: {
76329
77133
  login: "cf auth login",
76330
77134
  whoami: "cf auth whoami",
76331
- createProfile: "cf auth create"
77135
+ createProfile: "cf auth create",
77136
+ deviceLogin: "cf auth login --device"
76332
77137
  },
76333
77138
  keyringServiceName: CF_KEYRING_SERVICE_NAME,
76334
77139
  clientId: getClientIdFromEnv$1,
@@ -76414,6 +77219,7 @@ function validateScopeKeys(scopes) {
76414
77219
  __name$1(validateScopeKeys, "validateScopeKeys");
76415
77220
  var WRANGLER_KEYRING_SERVICE_NAME = "wrangler";
76416
77221
  var WRANGLER_CLI_NAME = "wrangler";
77222
+ var WRANGLER_DISPLAY_NAME = "Wrangler";
76417
77223
  var OAUTH_CALLBACK_URL = "http://localhost:8976/oauth/callback";
76418
77224
  var WRANGLER_CONSENT_PAGES = {
76419
77225
  granted: { url: "https://welcome.developers.workers.dev/wrangler-oauth-consent-granted" },
@@ -76445,10 +77251,12 @@ var { getAuthConfigFilePath, getEncryptedAuthConfigFilePath, defaultAuthConfigSt
76445
77251
  });
76446
77252
  var WRANGLER_CLI = {
76447
77253
  cliName: WRANGLER_CLI_NAME,
77254
+ displayName: WRANGLER_DISPLAY_NAME,
76448
77255
  commands: {
76449
77256
  login: "wrangler login",
76450
77257
  whoami: "wrangler whoami",
76451
- createProfile: "wrangler auth create"
77258
+ createProfile: "wrangler auth create",
77259
+ deviceLogin: "wrangler login --device"
76452
77260
  },
76453
77261
  keyringServiceName: WRANGLER_KEYRING_SERVICE_NAME,
76454
77262
  clientId: getClientIdFromEnv,
@@ -76502,7 +77310,7 @@ var __name = (target$1, value) => __defProp(target$1, "name", {
76502
77310
  //#region ../../node_modules/.pnpm/command-exists@1.2.9/node_modules/command-exists/lib/command-exists.js
76503
77311
  var require_command_exists$1 = /* @__PURE__ */ __commonJS$2({ "../../node_modules/.pnpm/command-exists@1.2.9/node_modules/command-exists/lib/command-exists.js": ((exports, module) => {
76504
77312
  var exec = __require$2("child_process").exec;
76505
- var execSync = __require$2("child_process").execSync;
77313
+ var execSync$1 = __require$2("child_process").execSync;
76506
77314
  var fs$2 = __require$2("fs");
76507
77315
  var path = __require$2("path");
76508
77316
  var access = fs$2.access;
@@ -76558,7 +77366,7 @@ var require_command_exists$1 = /* @__PURE__ */ __commonJS$2({ "../../node_module
76558
77366
  };
76559
77367
  var commandExistsUnixSync = function(commandName, cleanedCommandName) {
76560
77368
  if (fileNotExistsSync(commandName)) try {
76561
- return !!execSync("command -v " + cleanedCommandName + " 2>/dev/null && { echo >&1 " + cleanedCommandName + "; exit 0; }");
77369
+ return !!execSync$1("command -v " + cleanedCommandName + " 2>/dev/null && { echo >&1 " + cleanedCommandName + "; exit 0; }");
76562
77370
  } catch (error$2) {
76563
77371
  return false;
76564
77372
  }
@@ -76567,7 +77375,7 @@ var require_command_exists$1 = /* @__PURE__ */ __commonJS$2({ "../../node_module
76567
77375
  var commandExistsWindowsSync = function(commandName, cleanedCommandName, callback$1) {
76568
77376
  if (!/^(?!(?:.*\s|.*\.|\W+)$)(?:[a-zA-Z]:)?(?:(?:[^<>:"\|\?\*\n])+(?:\/\/|\/|\\\\|\\)?)+$/m.test(commandName)) return false;
76569
77377
  try {
76570
- return !!execSync("where " + cleanedCommandName, { stdio: [] });
77378
+ return !!execSync$1("where " + cleanedCommandName, { stdio: [] });
76571
77379
  } catch (error$2) {
76572
77380
  return false;
76573
77381
  }
@@ -77480,7 +78288,7 @@ __name(createWorkerUploadForm, "createWorkerUploadForm");
77480
78288
  //#endregion
77481
78289
  //#region ../remote-bindings/dist/index.mjs
77482
78290
  var import_undici = require_undici();
77483
- var version$2 = "0.0.5";
78291
+ var version$2 = "0.0.7";
77484
78292
  var NoDefaultValueProvided = class extends UserError {
77485
78293
  constructor() {
77486
78294
  super("This command cannot be run in a non-interactive context", { telemetryMessage: "remote bindings prompt default missing" });
@@ -82824,6 +83632,7 @@ function cloudflare(pluginConfig = {}) {
82824
83632
  tunnelPlugin(ctx),
82825
83633
  previewPlugin(ctx),
82826
83634
  shortcutsPlugin(ctx),
83635
+ agentHintPlugin(ctx),
82827
83636
  debugPlugin(ctx),
82828
83637
  triggerHandlersPlugin(ctx),
82829
83638
  virtualModulesPlugin(ctx),