lua-cli 3.21.0 → 3.23.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.js CHANGED
@@ -879,6 +879,27 @@ function isAllowedReviewableExecuteTool(tool) {
879
879
  function isReviewableMcpSendTool(tool) {
880
880
  return tool.length > REVIEWABLE_MCP_SEND_TOOL_SUFFIX.length && tool.endsWith(REVIEWABLE_MCP_SEND_TOOL_SUFFIX);
881
881
  }
882
+ function mcpActionTokens(action) {
883
+ return action.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
884
+ }
885
+ function isReviewableMcpDraftTool(tool) {
886
+ const sep4 = tool.indexOf("_");
887
+ if (sep4 <= 0 || sep4 >= tool.length - 1) return false;
888
+ const action = tool.slice(sep4 + 1);
889
+ const tokens = mcpActionTokens(action);
890
+ if (!tokens.includes("draft") && !tokens.includes("drafts")) return false;
891
+ return !MCP_TOOL_READ_VERB_RE.test(action);
892
+ }
893
+ function isMcpDraftCreateTool(tool) {
894
+ if (!isReviewableMcpDraftTool(tool)) return false;
895
+ const tokens = mcpActionTokens(tool.slice(tool.indexOf("_") + 1));
896
+ return tokens[0] === "draft" || tokens.some((t) => MCP_DRAFT_CREATE_VERBS.has(t));
897
+ }
898
+ function mcpSendSiblingForDraftTool(tool, availableToolIds) {
899
+ const sibling = `${tool.split("_")[0]}${REVIEWABLE_MCP_SEND_TOOL_SUFFIX}`;
900
+ for (const id of availableToolIds) if (id === sibling) return sibling;
901
+ return void 0;
902
+ }
882
903
  function isReviewableExecuteTool(tool) {
883
904
  return isAllowedReviewableExecuteTool(tool) || isReviewableMcpSendTool(tool);
884
905
  }
@@ -1118,7 +1139,23 @@ function foldRichPartsIntoMessages(messages, records, makeMessage, sameTurnGroup
1118
1139
  function buildDefaultPersona(agentName) {
1119
1140
  return DEFAULT_PERSONA_GUIDE.replace(AGENT_NAME_TOKEN, () => agentName || "My Agent");
1120
1141
  }
1121
- var __defProp2, __name2, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, REASONING_EFFORT_VALUES, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, AGENT_LOG_SOURCES, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema;
1142
+ function resolveLuaJobTimeoutSeconds(timeout) {
1143
+ const resolved = timeout ?? LUA_JOB_DEFAULT_TIMEOUT_SECONDS;
1144
+ if (!Number.isInteger(resolved)) {
1145
+ throw new TypeError("LuaJob `timeout` must be an integer number of seconds.");
1146
+ }
1147
+ if (resolved < LUA_JOB_MIN_TIMEOUT_SECONDS || resolved > LUA_JOB_MAX_TIMEOUT_SECONDS) {
1148
+ throw new RangeError(`LuaJob \`timeout\` must be between ${LUA_JOB_MIN_TIMEOUT_SECONDS} and ${LUA_JOB_MAX_TIMEOUT_SECONDS} seconds.`);
1149
+ }
1150
+ return resolved;
1151
+ }
1152
+ function normalizeLuaJobExecutionTimeoutSeconds(timeout) {
1153
+ if (typeof timeout !== "number" || !Number.isFinite(timeout)) {
1154
+ return LUA_JOB_DEFAULT_TIMEOUT_SECONDS;
1155
+ }
1156
+ return Math.min(Math.max(timeout, LUA_JOB_MIN_TIMEOUT_SECONDS), LUA_JOB_MAX_TIMEOUT_SECONDS);
1157
+ }
1158
+ var __defProp2, __name2, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, MCP_TOOL_READ_VERB_RE, MCP_DRAFT_CREATE_VERBS, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, REASONING_EFFORT_VALUES, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, AGENT_LOG_SOURCES, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS;
1122
1159
  var init_dist = __esm({
1123
1160
  "../shared-types/dist/index.mjs"() {
1124
1161
  "use strict";
@@ -1152,6 +1189,26 @@ var init_dist = __esm({
1152
1189
  REVIEWABLE_MCP_SEND_TOOL_SUFFIX = "_create_messaging_message";
1153
1190
  __name(isReviewableMcpSendTool, "isReviewableMcpSendTool");
1154
1191
  __name2(isReviewableMcpSendTool, "isReviewableMcpSendTool");
1192
+ MCP_TOOL_READ_VERB_RE = /^(list|get|search|read|fetch|find|query|describe|count|retrieve|lookup|show|view)(_|[A-Z0-9]|$)/;
1193
+ __name(mcpActionTokens, "mcpActionTokens");
1194
+ __name2(mcpActionTokens, "mcpActionTokens");
1195
+ __name(isReviewableMcpDraftTool, "isReviewableMcpDraftTool");
1196
+ __name2(isReviewableMcpDraftTool, "isReviewableMcpDraftTool");
1197
+ MCP_DRAFT_CREATE_VERBS = /* @__PURE__ */ new Set([
1198
+ "create",
1199
+ "compose",
1200
+ "make",
1201
+ "new",
1202
+ "save",
1203
+ "add",
1204
+ "write",
1205
+ "stage",
1206
+ "prepare"
1207
+ ]);
1208
+ __name(isMcpDraftCreateTool, "isMcpDraftCreateTool");
1209
+ __name2(isMcpDraftCreateTool, "isMcpDraftCreateTool");
1210
+ __name(mcpSendSiblingForDraftTool, "mcpSendSiblingForDraftTool");
1211
+ __name2(mcpSendSiblingForDraftTool, "mcpSendSiblingForDraftTool");
1155
1212
  __name(isReviewableExecuteTool, "isReviewableExecuteTool");
1156
1213
  __name2(isReviewableExecuteTool, "isReviewableExecuteTool");
1157
1214
  NON_INTERACTIVE_CHANNELS = [
@@ -1184,11 +1241,11 @@ var init_dist = __esm({
1184
1241
  },
1185
1242
  {
1186
1243
  name: "session_open",
1187
- description: "Open/attach a browser session (its own cookies/auth). Args: url?, headed?, profile?, confirmActions?."
1244
+ description: "Open/attach a browser session (its own cookies/auth). Args: url?, headed?, profile?, confirmActions?. Only use the browser when the user explicitly asked for it, or said yes when you asked. For reading a page's content use fetchUrl first."
1188
1245
  },
1189
1246
  {
1190
1247
  name: "navigate",
1191
- description: "Navigate the session to a URL. Args: url, waitUntil?."
1248
+ description: "Navigate the session to a URL. Args: url, waitUntil?. Only use the browser when the user explicitly asked for it, or said yes when you asked. For reading a page's content use fetchUrl first."
1192
1249
  },
1193
1250
  {
1194
1251
  name: "back",
@@ -1701,6 +1758,13 @@ Feel free to add, remove, or rename sections. Your persona can be a single parag
1701
1758
  voiceId: z.string().min(1),
1702
1759
  version: z.string().optional()
1703
1760
  });
1761
+ LUA_JOB_DEFAULT_TIMEOUT_SECONDS = 300;
1762
+ LUA_JOB_MIN_TIMEOUT_SECONDS = 1;
1763
+ LUA_JOB_MAX_TIMEOUT_SECONDS = 600;
1764
+ __name(resolveLuaJobTimeoutSeconds, "resolveLuaJobTimeoutSeconds");
1765
+ __name2(resolveLuaJobTimeoutSeconds, "resolveLuaJobTimeoutSeconds");
1766
+ __name(normalizeLuaJobExecutionTimeoutSeconds, "normalizeLuaJobExecutionTimeoutSeconds");
1767
+ __name2(normalizeLuaJobExecutionTimeoutSeconds, "normalizeLuaJobExecutionTimeoutSeconds");
1704
1768
  }
1705
1769
  });
1706
1770
 
@@ -3012,6 +3076,18 @@ var init_skill_handler = __esm({
3012
3076
  return toolData;
3013
3077
  }).filter(Boolean);
3014
3078
  const sourceArchive = buildSourceArchive(archiveEntries);
3079
+ let condition;
3080
+ let conditionS3Hash;
3081
+ if (skill.hasCondition) {
3082
+ const skillCode = loadArtifact(skill, projectPath);
3083
+ if (bundleAccumulator) {
3084
+ const rawGzip = compressForPushRaw(skillCode);
3085
+ conditionS3Hash = hashBundle(rawGzip);
3086
+ bundleAccumulator.set(conditionS3Hash, rawGzip);
3087
+ } else {
3088
+ condition = compressForPush(skillCode);
3089
+ }
3090
+ }
3015
3091
  return {
3016
3092
  name: skill.name,
3017
3093
  description: skill.description,
@@ -3020,6 +3096,12 @@ var init_skill_handler = __esm({
3020
3096
  context: skill.context
3021
3097
  } : {},
3022
3098
  tools,
3099
+ ...condition ? {
3100
+ condition
3101
+ } : {},
3102
+ ...conditionS3Hash ? {
3103
+ conditionS3Hash
3104
+ } : {},
3023
3105
  ...sourceArchive ? {
3024
3106
  sourceArchive,
3025
3107
  archiveSchemaVersion: SOURCE_ARCHIVE_SCHEMA_VERSION
@@ -6934,14 +7016,24 @@ var init_skill_plugin = __esm({
6934
7016
  // 2. Residual super-edge cases — `stripSuperCallsInConstructors` covers
6935
7017
  // top-level `super(...)` only; `super.method()` mid-constructor and
6936
7018
  // `field = super.x` survive a strip and explode at runtime.
6937
- // MAINTENANCE: this whitelist also assumes skills are JSON-only artifacts (via
6938
- // `buildArtifact`). If skills ever migrate to bundled JS, this drop will silently
6939
- // lose `tools` from skill bundlesre-evaluate.
7019
+ // MAINTENANCE: a skill WITH a `condition` is bundled through esbuild (see
7020
+ // `buildArtifact`), so every field the runtime needs off the bundle must be
7021
+ // listed here or it is silently dropped. `tools` stays out by design the
7022
+ // compiler resolves tool refs separately via `resolveArrayRefs`. The
7023
+ // whitelist only governs config literals; `dropClassMembers` is the same
7024
+ // drop for the class-definition shape, where a `tools = [...]` field or a
7025
+ // `this.addTool(...)` call would otherwise keep the tool imports live.
6940
7026
  crossFileRewrite = {
6941
7027
  fields: [
6942
7028
  "name",
6943
7029
  "description",
6944
- "context"
7030
+ "context",
7031
+ "condition"
7032
+ ],
7033
+ dropClassMembers: [
7034
+ "tools",
7035
+ "addTool",
7036
+ "addTools"
6945
7037
  ]
6946
7038
  };
6947
7039
  supportsClassDefinition = true;
@@ -6998,7 +7090,12 @@ var init_skill_plugin = __esm({
6998
7090
  pattern: "class-definition",
6999
7091
  context,
7000
7092
  toolRefs,
7001
- toolRefSourcePaths: Object.keys(toolRefSourcePaths).length > 0 ? toolRefSourcePaths : void 0
7093
+ toolRefSourcePaths: Object.keys(toolRefSourcePaths).length > 0 ? toolRefSourcePaths : void 0,
7094
+ // Emitted only when present so a condition-less skill's JSON artifact
7095
+ // stays byte-identical to pre-feature output.
7096
+ ...findClassMember(classDecl, "condition", "either") !== void 0 ? {
7097
+ hasCondition: true
7098
+ } : {}
7002
7099
  }
7003
7100
  };
7004
7101
  }
@@ -7054,7 +7151,10 @@ var init_skill_plugin = __esm({
7054
7151
  pattern,
7055
7152
  context,
7056
7153
  toolRefs,
7057
- toolRefSourcePaths: Object.keys(toolRefSourcePaths).length > 0 ? toolRefSourcePaths : void 0
7154
+ toolRefSourcePaths: Object.keys(toolRefSourcePaths).length > 0 ? toolRefSourcePaths : void 0,
7155
+ ...config.getProperty("condition") !== void 0 ? {
7156
+ hasCondition: true
7157
+ } : {}
7058
7158
  }
7059
7159
  };
7060
7160
  }
@@ -7199,13 +7299,19 @@ var init_skill_plugin = __esm({
7199
7299
  return rest;
7200
7300
  }
7201
7301
  /**
7202
- * Skills have no executable code and their artifact is never loaded at
7203
- * runtime (see `SkillHandler.prepareForPush` — it loads tool artifacts
7204
- * but never the skill's own). Emit a JSON metadata artifact instead of
7205
- * running esbuild on `new LuaSkill({...})`, which would otherwise bundle
7206
- * a non-executable shell (LuaSkill is stripped as an external import).
7302
+ * A skill without a `condition` has no executable code and its artifact is
7303
+ * never loaded at runtime (see `SkillHandler.prepareForPush` — it loads tool
7304
+ * artifacts, plus the skill's own only when it has a condition). Emit a JSON
7305
+ * metadata artifact instead of running esbuild on `new LuaSkill({...})`,
7306
+ * which would otherwise bundle a non-executable shell (LuaSkill is stripped
7307
+ * as an external import).
7308
+ *
7309
+ * A skill WITH a condition returns undefined to fall through to the standard
7310
+ * `generateEntryPoint → bundler.bundle → postProcess` esbuild path, same as
7311
+ * `AgentPlugin` with a model resolver.
7207
7312
  */
7208
7313
  async buildArtifact(metadata) {
7314
+ if (metadata.metadata.hasCondition) return void 0;
7209
7315
  const code = JSON.stringify({
7210
7316
  kind: metadata.kind,
7211
7317
  name: metadata.name,
@@ -7222,6 +7328,32 @@ var init_skill_plugin = __esm({
7222
7328
  };
7223
7329
  }
7224
7330
  /**
7331
+ * Project the class instance onto the skill primitive shape. Binds
7332
+ * `condition` to the instance so `this` references resolve correctly,
7333
+ * mirroring `ToolPlugin`. Skills have no `execute`, so the base shape
7334
+ * doesn't apply.
7335
+ */
7336
+ getClassDefinitionPrimitiveShape(metadata) {
7337
+ return `{
7338
+ kind: 'skill',
7339
+ name: __lua_instance__.name ?? ${JSON.stringify(metadata.name)},
7340
+ description: __lua_instance__.description ?? ${JSON.stringify(metadata.description)},
7341
+ context: __lua_instance__.context,
7342
+ condition: typeof __lua_instance__.condition === 'function' ? __lua_instance__.condition.bind(__lua_instance__) : undefined,
7343
+ }`;
7344
+ }
7345
+ /**
7346
+ * Runtime validation — a skill only reaches the bundled path when it
7347
+ * declares a condition, so the bundle must expose a callable one.
7348
+ */
7349
+ getRuntimeValidation(metadata) {
7350
+ if (!metadata.metadata.hasCondition) return "";
7351
+ return `
7352
+ if (typeof primitive.primitive?.condition !== 'function') {
7353
+ throw new Error('[Lua] Invalid skill artifact: condition is not a function');
7354
+ }`;
7355
+ }
7356
+ /**
7225
7357
  * Resolve tool references from this skill.
7226
7358
  *
7227
7359
  * Skills reference tools by class/variable name. This method:
@@ -7305,7 +7437,8 @@ var init_skill_plugin = __esm({
7305
7437
  return {
7306
7438
  ...this.baseManifestFields(compiled),
7307
7439
  context: skillMetadata.context,
7308
- tools: toolNames
7440
+ tools: toolNames,
7441
+ hasCondition: skillMetadata.hasCondition || false
7309
7442
  };
7310
7443
  }
7311
7444
  };
@@ -8121,7 +8254,7 @@ function rewriteCrossFileCallsInSourceFile(sf, specs, sdkBaseClassNames) {
8121
8254
  node.replaceWithText(buildBareObjectLiteral(spec, objArg));
8122
8255
  progressed = true;
8123
8256
  }
8124
- stripSdkExtendsClauses(sf, sdkBaseClassNames, aliasMap);
8257
+ stripSdkExtendsClauses(sf, sdkBaseClassNames, aliasMap, specs);
8125
8258
  }
8126
8259
  function warnUnsupportedNamespaceImports(sf) {
8127
8260
  for (const imp of sf.getImportDeclarations()) {
@@ -8141,20 +8274,29 @@ function warnUnsupportedNamespaceImports(sf) {
8141
8274
  }));
8142
8275
  }
8143
8276
  }
8144
- function stripSdkExtendsClauses(sf, sdkBaseClassNames, aliasMap) {
8145
- const matchesSdkClass = /* @__PURE__ */ __name((text) => {
8277
+ function stripSdkExtendsClauses(sf, sdkBaseClassNames, aliasMap, specs) {
8278
+ const matchSdkClass = /* @__PURE__ */ __name((text) => {
8146
8279
  const canonical = aliasMap.get(text) ?? text;
8147
- return sdkBaseClassNames.has(canonical);
8148
- }, "matchesSdkClass");
8280
+ return sdkBaseClassNames.has(canonical) ? canonical : void 0;
8281
+ }, "matchSdkClass");
8282
+ const dropNamesFor = /* @__PURE__ */ __name((canonical) => {
8283
+ const spec = specs.find((s) => s.classNames.includes(canonical));
8284
+ if (!spec?.dropClassMembers?.length) return void 0;
8285
+ return new Set(spec.dropClassMembers);
8286
+ }, "dropNamesFor");
8287
+ const strip = /* @__PURE__ */ __name((classNode, canonical) => {
8288
+ classNode.removeExtends();
8289
+ const dropNames = dropNamesFor(canonical);
8290
+ if (dropNames) stripDroppedClassMembers(classNode, dropNames);
8291
+ stripSuperCallsInConstructors(classNode);
8292
+ }, "strip");
8149
8293
  for (const classDecl of sf.getClasses()) {
8150
8294
  const ext = classDecl.getExtends();
8151
8295
  if (!ext) continue;
8152
8296
  const expr = ext.getExpression();
8153
8297
  if (!Node15.isIdentifier(expr)) continue;
8154
- if (matchesSdkClass(expr.getText())) {
8155
- classDecl.removeExtends();
8156
- stripSuperCallsInConstructors(classDecl);
8157
- }
8298
+ const canonical = matchSdkClass(expr.getText());
8299
+ if (canonical) strip(classDecl, canonical);
8158
8300
  }
8159
8301
  sf.forEachDescendant((n) => {
8160
8302
  if (!Node15.isClassExpression(n)) return;
@@ -8162,11 +8304,31 @@ function stripSdkExtendsClauses(sf, sdkBaseClassNames, aliasMap) {
8162
8304
  if (!ext) return;
8163
8305
  const expr = ext.getExpression();
8164
8306
  if (!Node15.isIdentifier(expr)) return;
8165
- if (matchesSdkClass(expr.getText())) {
8166
- n.removeExtends();
8167
- stripSuperCallsInConstructors(n);
8168
- }
8307
+ const canonical = matchSdkClass(expr.getText());
8308
+ if (canonical) strip(n, canonical);
8309
+ });
8310
+ }
8311
+ function stripDroppedClassMembers(classNode, dropNames) {
8312
+ for (const prop of classNode.getProperties()) {
8313
+ if (dropNames.has(prop.getName())) prop.remove();
8314
+ }
8315
+ const statements = [];
8316
+ classNode.forEachDescendant((n) => {
8317
+ if (!Node15.isExpressionStatement(n)) return;
8318
+ if (isThisRootedCallTo(n.getExpression(), dropNames)) statements.push(n);
8169
8319
  });
8320
+ for (const stmt of statements) stmt.remove();
8321
+ }
8322
+ function isThisRootedCallTo(expression, dropNames) {
8323
+ let current = expression;
8324
+ let matched = false;
8325
+ while (Node15.isCallExpression(current)) {
8326
+ const callee = current.getExpression();
8327
+ if (!Node15.isPropertyAccessExpression(callee)) return false;
8328
+ if (dropNames.has(callee.getName())) matched = true;
8329
+ current = callee.getExpression();
8330
+ }
8331
+ return matched && current.getKind() === ts3.SyntaxKind.ThisKeyword;
8170
8332
  }
8171
8333
  function stripSuperCallsInConstructors(classNode) {
8172
8334
  for (const ctor of classNode.getConstructors()) {
@@ -8273,6 +8435,8 @@ function buildBareObjectLiteral(spec, arg) {
8273
8435
  if (init) parts.push(`${f}: ${init.getText()}`);
8274
8436
  } else if (prop && Node15.isShorthandPropertyAssignment(prop)) {
8275
8437
  parts.push(`${f}: ${prop.getName()}`);
8438
+ } else if (prop && Node15.isMethodDeclaration(prop)) {
8439
+ parts.push(prop.getText());
8276
8440
  }
8277
8441
  }
8278
8442
  return `{ ${parts.join(", ")} }`;
@@ -8342,6 +8506,8 @@ var init_primitive_rewrite = __esm({
8342
8506
  __name(rewriteCrossFileCallsInSourceFile, "rewriteCrossFileCallsInSourceFile");
8343
8507
  __name(warnUnsupportedNamespaceImports, "warnUnsupportedNamespaceImports");
8344
8508
  __name(stripSdkExtendsClauses, "stripSdkExtendsClauses");
8509
+ __name(stripDroppedClassMembers, "stripDroppedClassMembers");
8510
+ __name(isThisRootedCallTo, "isThisRootedCallTo");
8345
8511
  __name(stripSuperCallsInConstructors, "stripSuperCallsInConstructors");
8346
8512
  __name(warnRemainingSuperReferences, "warnRemainingSuperReferences");
8347
8513
  __name(buildSdkAliasMap, "buildSdkAliasMap");
@@ -8364,16 +8530,19 @@ function buildCrossFileSpecs(plugins = pluginRegistry.getAll()) {
8364
8530
  ...plugin.legacyClassNames
8365
8531
  ];
8366
8532
  const defineFunction = plugin.defineFunction || void 0;
8533
+ const dropClassMembers = plugin.crossFileRewrite.dropClassMembers;
8367
8534
  if ("copyAllFields" in plugin.crossFileRewrite && plugin.crossFileRewrite.copyAllFields) {
8368
8535
  specs.push({
8369
8536
  classNames,
8370
8537
  defineFunction,
8538
+ dropClassMembers,
8371
8539
  mode: "copyAllFields"
8372
8540
  });
8373
8541
  } else if ("fields" in plugin.crossFileRewrite) {
8374
8542
  specs.push({
8375
8543
  classNames,
8376
8544
  defineFunction,
8545
+ dropClassMembers,
8377
8546
  mode: "whitelist",
8378
8547
  fields: plugin.crossFileRewrite.fields
8379
8548
  });
@@ -10929,6 +11098,8 @@ var init_user_instance = __esm({
10929
11098
  "data",
10930
11099
  "userAPI",
10931
11100
  "update",
11101
+ "patch",
11102
+ "unset",
10932
11103
  "clear",
10933
11104
  "toJSON",
10934
11105
  "_luaProfile"
@@ -11007,9 +11178,27 @@ var init_user_instance = __esm({
11007
11178
  this.data = response;
11008
11179
  return this.data;
11009
11180
  } catch (error) {
11010
- throw new Error("Failed to update user data");
11181
+ throw new Error("Failed to update user data", {
11182
+ cause: error
11183
+ });
11011
11184
  }
11012
11185
  }
11186
+ async patch(mutation) {
11187
+ try {
11188
+ const response = await this.userAPI.patch(mutation);
11189
+ this.data = response;
11190
+ return this.data;
11191
+ } catch (error) {
11192
+ throw new Error("Failed to patch user data", {
11193
+ cause: error
11194
+ });
11195
+ }
11196
+ }
11197
+ async unset(...fields) {
11198
+ return this.patch({
11199
+ unset: fields
11200
+ });
11201
+ }
11013
11202
  /**
11014
11203
  * Clears all user data for the current user
11015
11204
  * @returns Promise resolving to true if clearing was successful
@@ -11018,9 +11207,12 @@ var init_user_instance = __esm({
11018
11207
  async clear() {
11019
11208
  try {
11020
11209
  await this.userAPI.clear();
11210
+ this.data = {};
11021
11211
  return true;
11022
11212
  } catch (error) {
11023
- throw new Error("Failed to clear user data");
11213
+ throw new Error("Failed to clear user data", {
11214
+ cause: error
11215
+ });
11024
11216
  }
11025
11217
  }
11026
11218
  /**
@@ -11033,7 +11225,9 @@ var init_user_instance = __esm({
11033
11225
  await this.userAPI.update(this.data);
11034
11226
  return true;
11035
11227
  } catch (error) {
11036
- throw new Error("Failed to save user data");
11228
+ throw new Error("Failed to save user data", {
11229
+ cause: error
11230
+ });
11037
11231
  }
11038
11232
  }
11039
11233
  /**
@@ -11047,7 +11241,9 @@ var init_user_instance = __esm({
11047
11241
  await this.userAPI.sendMessage(messages);
11048
11242
  return true;
11049
11243
  } catch (error) {
11050
- throw new Error("Failed to send message");
11244
+ throw new Error("Failed to send message", {
11245
+ cause: error
11246
+ });
11051
11247
  }
11052
11248
  }
11053
11249
  //get chat history
@@ -11055,7 +11251,9 @@ var init_user_instance = __esm({
11055
11251
  try {
11056
11252
  return await this.userAPI.getChatHistory();
11057
11253
  } catch (error) {
11058
- throw new Error("Failed to get chat history");
11254
+ throw new Error("Failed to get chat history", {
11255
+ cause: error
11256
+ });
11059
11257
  }
11060
11258
  }
11061
11259
  };
@@ -12471,6 +12669,8 @@ var init_data_entry_instance = __esm({
12471
12669
  "score",
12472
12670
  "customDataAPI",
12473
12671
  "update",
12672
+ "patch",
12673
+ "unset",
12474
12674
  "delete",
12475
12675
  "toJSON"
12476
12676
  ];
@@ -12562,9 +12762,33 @@ var init_data_entry_instance = __esm({
12562
12762
  };
12563
12763
  return this.data;
12564
12764
  } catch (error) {
12565
- throw new Error("Failed to update custom data entry");
12765
+ throw new Error("Failed to update custom data entry", {
12766
+ cause: error
12767
+ });
12566
12768
  }
12567
12769
  }
12770
+ async patch(mutation) {
12771
+ try {
12772
+ await this.customDataAPI.patch(this.collectionName, this.id, mutation);
12773
+ this.data = {
12774
+ ...this.data,
12775
+ ...mutation.set ?? {}
12776
+ };
12777
+ for (const field of mutation.unset ?? []) {
12778
+ delete this.data[field];
12779
+ }
12780
+ return this.data;
12781
+ } catch (error) {
12782
+ throw new Error("Failed to patch custom data entry", {
12783
+ cause: error
12784
+ });
12785
+ }
12786
+ }
12787
+ async unset(...fields) {
12788
+ return this.patch({
12789
+ unset: fields
12790
+ });
12791
+ }
12568
12792
  /**
12569
12793
  * Deletes the custom data entry
12570
12794
  * @returns Promise resolving to true if deletion was successful
@@ -12575,7 +12799,9 @@ var init_data_entry_instance = __esm({
12575
12799
  await this.customDataAPI.delete(this.collectionName, this.id);
12576
12800
  return true;
12577
12801
  } catch (error) {
12578
- throw new Error("Failed to delete custom data entry");
12802
+ throw new Error("Failed to delete custom data entry", {
12803
+ cause: error
12804
+ });
12579
12805
  }
12580
12806
  }
12581
12807
  /**
@@ -12589,7 +12815,9 @@ var init_data_entry_instance = __esm({
12589
12815
  await this.customDataAPI.update(this.collectionName, this.id, this.data, searchText);
12590
12816
  return true;
12591
12817
  } catch (error) {
12592
- throw new Error("Failed to save data entry");
12818
+ throw new Error("Failed to save data entry", {
12819
+ cause: error
12820
+ });
12593
12821
  }
12594
12822
  }
12595
12823
  };
@@ -12700,6 +12928,15 @@ var init_custom_data_api_service = __esm({
12700
12928
  }
12701
12929
  throw new Error(response.error?.message || "Failed to update custom data entry");
12702
12930
  }
12931
+ async patch(collectionName, entryId, mutation) {
12932
+ const response = await this.httpPatch(`/developer/agents/${this.agentId}/custom-data/${collectionName}/${entryId}`, mutation, {
12933
+ Authorization: `Bearer ${this.apiKey}`
12934
+ });
12935
+ if (response.success && response.data) {
12936
+ return response.data;
12937
+ }
12938
+ throw new Error(response.error?.message || "Failed to patch custom data entry");
12939
+ }
12703
12940
  /**
12704
12941
  * Performs semantic search on custom data entries using text similarity
12705
12942
  * @param collectionName - The name of the collection to search within
@@ -13156,8 +13393,10 @@ var init_developer_api_service = __esm({
13156
13393
  * @param email - The email address to look up
13157
13394
  * @returns Promise resolving to an ApiResponse containing the profile, or null if not found
13158
13395
  */
13159
- async getUserProfileByEmail(email) {
13160
- return this.httpGet(`/developer/user/profile/email/${encodeURIComponent(email)}`, {
13396
+ async getUserProfileByEmail(email, agentId) {
13397
+ const path18 = `/developer/user/profile/email/${encodeURIComponent(email)}`;
13398
+ const scopedPath = agentId ? `${path18}?agentId=${encodeURIComponent(agentId)}` : path18;
13399
+ return this.httpGet(scopedPath, {
13161
13400
  Authorization: `Bearer ${this.apiKey}`
13162
13401
  });
13163
13402
  }
@@ -13166,9 +13405,11 @@ var init_developer_api_service = __esm({
13166
13405
  * @param phone - The phone number to look up (with or without + prefix)
13167
13406
  * @returns Promise resolving to an ApiResponse containing the profile, or null if not found
13168
13407
  */
13169
- async getUserProfileByPhone(phone) {
13408
+ async getUserProfileByPhone(phone, agentId) {
13170
13409
  const normalizedPhone = phone.replace(/^\+/, "");
13171
- return this.httpGet(`/developer/user/profile/phone/${normalizedPhone}`, {
13410
+ const path18 = `/developer/user/profile/phone/${normalizedPhone}`;
13411
+ const scopedPath = agentId ? `${path18}?agentId=${encodeURIComponent(agentId)}` : path18;
13412
+ return this.httpGet(scopedPath, {
13172
13413
  Authorization: `Bearer ${this.apiKey}`
13173
13414
  });
13174
13415
  }
@@ -13708,22 +13949,28 @@ var init_user_data_api_service = __esm({
13708
13949
  init_http_client();
13709
13950
  init_user_instance();
13710
13951
  init_lazy_instances();
13711
- UserDataApi = class extends HttpClient {
13952
+ UserDataApi = class _UserDataApi extends HttpClient {
13712
13953
  static {
13713
13954
  __name(this, "UserDataApi");
13714
13955
  }
13715
13956
  apiKey;
13716
13957
  agentId;
13958
+ targetUserId;
13717
13959
  /**
13718
13960
  * Creates an instance of UserDataApi
13719
13961
  * @param baseUrl - The base URL for the API
13720
13962
  * @param apiKey - The API key for authentication
13721
13963
  * @param agentId - The unique identifier of the agent
13722
13964
  */
13723
- constructor(baseUrl, apiKey, agentId) {
13965
+ constructor(baseUrl, apiKey, agentId, targetUserId) {
13724
13966
  super(baseUrl);
13725
13967
  this.apiKey = apiKey;
13726
13968
  this.agentId = agentId;
13969
+ this.targetUserId = targetUserId;
13970
+ }
13971
+ get dataPath() {
13972
+ const base = `/developer/user/data/agent/${this.agentId}`;
13973
+ return this.targetUserId ? `${base}/user/${encodeURIComponent(this.targetUserId)}` : base;
13727
13974
  }
13728
13975
  /**
13729
13976
  * Retrieves user data by userId, email, or phone.
@@ -13742,7 +13989,7 @@ var init_user_data_api_service = __esm({
13742
13989
  }
13743
13990
  let url = `/developer/user/data/agent/${this.agentId}`;
13744
13991
  if (userId) {
13745
- url += `/user/${userId}`;
13992
+ url += `/user/${encodeURIComponent(userId)}`;
13746
13993
  }
13747
13994
  const response = await this.httpGet(url, {
13748
13995
  Authorization: `Bearer ${this.apiKey}`
@@ -13752,7 +13999,8 @@ var init_user_data_api_service = __esm({
13752
13999
  }
13753
14000
  const profile = response.data?._luaProfile;
13754
14001
  const { _luaProfile, ...data } = response.data || {};
13755
- return new UserDataInstance(this, data, profile);
14002
+ const scopedApi = userId ? new _UserDataApi(this.baseUrl, this.apiKey, this.agentId, userId) : this;
14003
+ return new UserDataInstance(scopedApi, data, profile);
13756
14004
  }
13757
14005
  /**
13758
14006
  * Resolves email or phone to user profile via DeveloperApi
@@ -13763,11 +14011,11 @@ var init_user_data_api_service = __esm({
13763
14011
  try {
13764
14012
  const developerApi = await getDeveloperInstance();
13765
14013
  if (options.email) {
13766
- const response = await developerApi.getUserProfileByEmail(options.email);
14014
+ const response = await developerApi.getUserProfileByEmail(options.email, this.agentId);
13767
14015
  return response.success ? response.data ?? null : null;
13768
14016
  }
13769
14017
  if (options.phone) {
13770
- const response = await developerApi.getUserProfileByPhone(options.phone);
14018
+ const response = await developerApi.getUserProfileByPhone(options.phone, this.agentId);
13771
14019
  return response.success ? response.data ?? null : null;
13772
14020
  }
13773
14021
  } catch (error) {
@@ -13785,7 +14033,7 @@ var init_user_data_api_service = __esm({
13785
14033
  * @throws Error if the update fails or the request is unsuccessful
13786
14034
  */
13787
14035
  async update(data) {
13788
- const response = await this.httpPut(`/developer/user/data/agent/${this.agentId}`, data, {
14036
+ const response = await this.httpPut(this.dataPath, data, {
13789
14037
  Authorization: `Bearer ${this.apiKey}`
13790
14038
  });
13791
14039
  if (!response.success) {
@@ -13794,13 +14042,23 @@ var init_user_data_api_service = __esm({
13794
14042
  const { _luaProfile, ...cleanData } = response.data || {};
13795
14043
  return cleanData;
13796
14044
  }
14045
+ async patch(mutation) {
14046
+ const response = await this.httpPatch(this.dataPath, mutation, {
14047
+ Authorization: `Bearer ${this.apiKey}`
14048
+ });
14049
+ if (!response.success) {
14050
+ throw new Error(response.error?.message || "Failed to patch user data");
14051
+ }
14052
+ const { _luaProfile, ...cleanData } = response.data || {};
14053
+ return cleanData;
14054
+ }
13797
14055
  /**
13798
14056
  * Clears all user data for the current user and specific agent
13799
14057
  * @returns Promise resolving to an empty object upon successful deletion
13800
14058
  * @throws Error if the clear operation fails or the request is unsuccessful
13801
14059
  */
13802
14060
  async clear() {
13803
- const response = await this.httpDelete(`/developer/user/data/agent/${this.agentId}`, {
14061
+ const response = await this.httpDelete(this.dataPath, {
13804
14062
  Authorization: `Bearer ${this.apiKey}`
13805
14063
  });
13806
14064
  if (!response.success) {
@@ -20203,6 +20461,22 @@ function buildSandboxProcess(opts) {
20203
20461
  const nextTickFn = /* @__PURE__ */ __name4((cb, ...args2) => {
20204
20462
  process.nextTick(cb, ...args2);
20205
20463
  }, "nextTickFn");
20464
+ const buildStdioStub = /* @__PURE__ */ __name4((fd) => {
20465
+ const stub = {
20466
+ fd,
20467
+ isTTY: false,
20468
+ write: /* @__PURE__ */ __name4(() => true, "write"),
20469
+ end: /* @__PURE__ */ __name4(() => stub, "end"),
20470
+ on: /* @__PURE__ */ __name4(() => stub, "on"),
20471
+ once: /* @__PURE__ */ __name4(() => stub, "once"),
20472
+ removeListener: /* @__PURE__ */ __name4(() => stub, "removeListener"),
20473
+ cork: /* @__PURE__ */ __name4(() => {
20474
+ }, "cork"),
20475
+ uncork: /* @__PURE__ */ __name4(() => {
20476
+ }, "uncork")
20477
+ };
20478
+ return stub;
20479
+ }, "buildStdioStub");
20206
20480
  const proc = {
20207
20481
  env: opts.envVars,
20208
20482
  version: process.version,
@@ -20212,6 +20486,8 @@ function buildSandboxProcess(opts) {
20212
20486
  platform: process.platform,
20213
20487
  arch: process.arch,
20214
20488
  pid: process.pid,
20489
+ stdout: buildStdioStub(1),
20490
+ stderr: buildStdioStub(2),
20215
20491
  nextTick: nextTickFn,
20216
20492
  hrtime: hrtimeFn,
20217
20493
  // Lie — don't leak host filesystem layout. Skills should not depend on
@@ -40502,6 +40778,7 @@ __name(deleteServerInteractive, "deleteServerInteractive");
40502
40778
  init_cli();
40503
40779
  init_constants();
40504
40780
  import http from "http";
40781
+ import { randomBytes } from "crypto";
40505
40782
  import { URL as URL2 } from "url";
40506
40783
  import open5 from "open";
40507
40784
  init_command_utils();
@@ -40543,18 +40820,14 @@ var UnifiedToApi = class extends HttpClient {
40543
40820
  async getAuthUrl(integrationType, options) {
40544
40821
  const params = new URLSearchParams();
40545
40822
  params.append("integrationType", integrationType);
40823
+ params.append("agentId", options.agentId);
40546
40824
  params.append("successRedirect", options.successRedirect);
40547
40825
  params.append("failureRedirect", options.failureRedirect);
40548
40826
  if (options.scopes && options.scopes.length > 0) {
40549
40827
  params.append("scopes", options.scopes.join(","));
40550
40828
  }
40551
- if (options.state) {
40552
- params.append("state", options.state);
40553
- }
40554
- if (options.externalXref) {
40555
- params.append("externalXref", options.externalXref);
40556
- }
40557
- return this.httpGet(`/developer/unifiedto/auth-url?${params.toString()}`, {
40829
+ params.append("state", options.state);
40830
+ return this.httpGet(`/developer/unifiedto/auth-url/v2?${params.toString()}`, {
40558
40831
  Authorization: `Bearer ${this.apiKey}`
40559
40832
  });
40560
40833
  }
@@ -40700,7 +40973,8 @@ var UnifiedToApi = class extends HttpClient {
40700
40973
  // src/commands/integrations.ts
40701
40974
  init_analytics();
40702
40975
  var CALLBACK_PORT = 19837;
40703
- var CALLBACK_URL = `http://localhost:${CALLBACK_PORT}/callback`;
40976
+ var CALLBACK_HOST = "127.0.0.1";
40977
+ var CALLBACK_URL = `http://${CALLBACK_HOST}:${CALLBACK_PORT}/callback`;
40704
40978
  var AGENT_WEBHOOK_URL = `${BASE_URLS.API}/webhook/unifiedto/data`;
40705
40979
  var DEFAULT_VIRTUAL_WEBHOOK_INTERVAL = 1;
40706
40980
  async function fetchAvailableIntegrations(unifiedToApi, agentId) {
@@ -40719,22 +40993,50 @@ async function fetchAvailableIntegrations(unifiedToApi, agentId) {
40719
40993
  }));
40720
40994
  }
40721
40995
  __name(fetchAvailableIntegrations, "fetchAvailableIntegrations");
40722
- function startCallbackServer(timeoutMs = 3e5) {
40996
+ function createOAuthState() {
40997
+ return randomBytes(32).toString("base64url");
40998
+ }
40999
+ __name(createOAuthState, "createOAuthState");
41000
+ function escapeHtml(value) {
41001
+ return value.replace(/[&<>"']/g, (character) => {
41002
+ const escaped = {
41003
+ "&": "&amp;",
41004
+ "<": "&lt;",
41005
+ ">": "&gt;",
41006
+ '"': "&quot;",
41007
+ "'": "&#039;"
41008
+ };
41009
+ return escaped[character];
41010
+ });
41011
+ }
41012
+ __name(escapeHtml, "escapeHtml");
41013
+ function startCallbackServer(expectedState, timeoutMs = 3e5) {
40723
41014
  return new Promise((resolve6) => {
40724
41015
  let resolved = false;
40725
41016
  const server = http.createServer((req, res) => {
40726
41017
  if (resolved) return;
40727
41018
  const reqUrl = new URL2(req.url || "/", `http://localhost:${CALLBACK_PORT}`);
40728
41019
  if (reqUrl.pathname === "/callback") {
41020
+ const returnedState = reqUrl.searchParams.get("state");
41021
+ if (returnedState !== expectedState) {
41022
+ res.writeHead(400, {
41023
+ "Content-Type": "text/plain; charset=utf-8",
41024
+ "Cache-Control": "no-store",
41025
+ "X-Content-Type-Options": "nosniff"
41026
+ });
41027
+ res.end("Invalid OAuth state");
41028
+ return;
41029
+ }
40729
41030
  const connectionId = reqUrl.searchParams.get("id");
40730
41031
  const error = reqUrl.searchParams.get("error");
40731
41032
  const logId = reqUrl.searchParams.get("log_id");
40732
41033
  const integrationType = reqUrl.searchParams.get("type");
40733
41034
  resolved = true;
40734
41035
  if (error) {
40735
- const logIdHtml = logId ? `<p style="color: #888; font-size: 0.85em;">Log ID: <code>${logId}</code></p>` : "";
41036
+ const logIdHtml = logId ? `<p style="color: #888; font-size: 0.85em;">Log ID: <code>${escapeHtml(logId)}</code></p>` : "";
40736
41037
  res.writeHead(200, {
40737
- "Content-Type": "text/html"
41038
+ "Content-Type": "text/html; charset=utf-8",
41039
+ "Cache-Control": "no-store"
40738
41040
  });
40739
41041
  res.end(`
40740
41042
  <!DOCTYPE html>
@@ -40743,7 +41045,7 @@ function startCallbackServer(timeoutMs = 3e5) {
40743
41045
  <body style="font-family: system-ui; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #1a1a2e;">
40744
41046
  <div style="text-align: center; color: white; max-width: 500px; padding: 0 20px;">
40745
41047
  <h1 style="color: #ff6b6b;">Connection Failed</h1>
40746
- <p style="color: #ccc;">Error: ${error}</p>
41048
+ <p style="color: #ccc;">Authentication failed. Return to the terminal for details.</p>
40747
41049
  ${logIdHtml}
40748
41050
  <p style="color: #888;">You can close this window and try again.</p>
40749
41051
  </div>
@@ -40758,7 +41060,8 @@ function startCallbackServer(timeoutMs = 3e5) {
40758
41060
  });
40759
41061
  } else if (connectionId) {
40760
41062
  res.writeHead(200, {
40761
- "Content-Type": "text/html"
41063
+ "Content-Type": "text/html; charset=utf-8",
41064
+ "Cache-Control": "no-store"
40762
41065
  });
40763
41066
  res.end(`
40764
41067
  <!DOCTYPE html>
@@ -40792,7 +41095,7 @@ function startCallbackServer(timeoutMs = 3e5) {
40792
41095
  res.end("Not found");
40793
41096
  }
40794
41097
  });
40795
- server.listen(CALLBACK_PORT, () => {
41098
+ server.listen(CALLBACK_PORT, CALLBACK_HOST, () => {
40796
41099
  });
40797
41100
  setTimeout(() => {
40798
41101
  if (!resolved) {
@@ -41493,22 +41796,13 @@ Available triggers for ${selectedIntegration.name}:`);
41493
41796
  writeInfo(`Note: Could not fetch available triggers (${error.message})`);
41494
41797
  }
41495
41798
  writeProgress("\u{1F504} Preparing authorization...");
41496
- const state = Buffer.from(JSON.stringify({
41497
- agentId: context.agentId,
41498
- integration: selectedIntegration.value,
41499
- authMethod,
41500
- timestamp: Date.now()
41501
- })).toString("base64");
41502
- const externalXref = JSON.stringify({
41503
- agentId: context.agentId,
41504
- userId: context.userId
41505
- });
41799
+ const state = createOAuthState();
41506
41800
  const authUrlResult = await context.unifiedToApi.getAuthUrl(selectedIntegration.value, {
41801
+ agentId: context.agentId,
41507
41802
  successRedirect: CALLBACK_URL,
41508
41803
  failureRedirect: CALLBACK_URL,
41509
41804
  scopes: authMethod === "oauth" ? selectedScopes : void 0,
41510
- state,
41511
- externalXref
41805
+ state
41512
41806
  });
41513
41807
  if (!authUrlResult.success || !authUrlResult.data) {
41514
41808
  writeError(`\u274C Failed to get authorization URL: ${authUrlResult.error?.message || "Unknown error"}`);
@@ -41524,7 +41818,7 @@ Integration: ${selectedIntegration.name}`);
41524
41818
  \u{1F4CB} Authorization URL (copy if browser doesn't open):
41525
41819
  ${authUrl}
41526
41820
  `);
41527
- const callbackPromise = startCallbackServer(3e5);
41821
+ const callbackPromise = startCallbackServer(state, 3e5);
41528
41822
  try {
41529
41823
  await open5(authUrl);
41530
41824
  writeInfo("\u{1F310} Browser opened - please complete the authorization");
@@ -41926,22 +42220,13 @@ Available scopes for ${selectedIntegration.name}:`);
41926
42220
  writeError(`\u274C Failed to remove old connection: ${error.message}`);
41927
42221
  return;
41928
42222
  }
41929
- const state = Buffer.from(JSON.stringify({
41930
- agentId: context.agentId,
41931
- integration: selectedIntegration.value,
41932
- authMethod: "oauth",
41933
- timestamp: Date.now()
41934
- })).toString("base64");
41935
- const externalXref = JSON.stringify({
41936
- agentId: context.agentId,
41937
- userId: context.userId
41938
- });
42223
+ const state = createOAuthState();
41939
42224
  const authUrlResult = await context.unifiedToApi.getAuthUrl(selectedIntegration.value, {
42225
+ agentId: context.agentId,
41940
42226
  successRedirect: CALLBACK_URL,
41941
42227
  failureRedirect: CALLBACK_URL,
41942
42228
  scopes: selectedScopes,
41943
- state,
41944
- externalXref
42229
+ state
41945
42230
  });
41946
42231
  if (!authUrlResult.success || !authUrlResult.data) {
41947
42232
  writeError(`\u274C Failed to get authorization URL: ${authUrlResult.error?.message || "Unknown error"}`);
@@ -41955,7 +42240,7 @@ Available scopes for ${selectedIntegration.name}:`);
41955
42240
  \u{1F4CB} Authorization URL (copy if browser doesn't open):
41956
42241
  ${authUrl}
41957
42242
  `);
41958
- const callbackPromise = startCallbackServer(3e5);
42243
+ const callbackPromise = startCallbackServer(state, 3e5);
41959
42244
  try {
41960
42245
  await open5(authUrl);
41961
42246
  writeInfo("\u{1F310} Browser opened - please complete the authorization");