lua-cli 3.23.0 → 3.23.1

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
@@ -896,9 +896,13 @@ function isMcpDraftCreateTool(tool) {
896
896
  return tokens[0] === "draft" || tokens.some((t) => MCP_DRAFT_CREATE_VERBS.has(t));
897
897
  }
898
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;
899
+ const candidates = [
900
+ ...availableToolIds
901
+ ].filter((id) => id.endsWith(REVIEWABLE_MCP_SEND_TOOL_SUFFIX)).map((id) => ({
902
+ id,
903
+ serverName: id.slice(0, -REVIEWABLE_MCP_SEND_TOOL_SUFFIX.length)
904
+ })).filter(({ serverName }) => tool.startsWith(`${serverName}_`)).sort((a, b) => b.serverName.length - a.serverName.length);
905
+ return candidates[0]?.id;
902
906
  }
903
907
  function isReviewableExecuteTool(tool) {
904
908
  return isAllowedReviewableExecuteTool(tool) || isReviewableMcpSendTool(tool);
@@ -1136,6 +1140,20 @@ function foldRichPartsIntoMessages(messages, records, makeMessage, sameTurnGroup
1136
1140
  while (next < synthetic.length) combined.push(synthetic[next++].message);
1137
1141
  return mergeRichPartMirrorMessages(combined, sameTurnGroup);
1138
1142
  }
1143
+ function isDesktopFileCommandName(value) {
1144
+ return typeof value === "string" && DESKTOP_FILE_COMMAND_SET.has(value);
1145
+ }
1146
+ function isDesktopFileSessionId(value) {
1147
+ return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
1148
+ }
1149
+ function resolveRequireToolApproval(rules) {
1150
+ const raw = rules?.requireToolApproval ?? rules?.requireApproval;
1151
+ if (raw === void 0 || raw === null) return void 0;
1152
+ const list = Array.isArray(raw) ? raw : [
1153
+ raw
1154
+ ];
1155
+ return list.filter((t) => typeof t === "string");
1156
+ }
1139
1157
  function buildDefaultPersona(agentName) {
1140
1158
  return DEFAULT_PERSONA_GUIDE.replace(AGENT_NAME_TOKEN, () => agentName || "My Agent");
1141
1159
  }
@@ -1155,7 +1173,7 @@ function normalizeLuaJobExecutionTimeoutSeconds(timeout) {
1155
1173
  }
1156
1174
  return Math.min(Math.max(timeout, LUA_JOB_MIN_TIMEOUT_SECONDS), LUA_JOB_MAX_TIMEOUT_SECONDS);
1157
1175
  }
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;
1176
+ 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, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, 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;
1159
1177
  var init_dist = __esm({
1160
1178
  "../shared-types/dist/index.mjs"() {
1161
1179
  "use strict";
@@ -1189,7 +1207,7 @@ var init_dist = __esm({
1189
1207
  REVIEWABLE_MCP_SEND_TOOL_SUFFIX = "_create_messaging_message";
1190
1208
  __name(isReviewableMcpSendTool, "isReviewableMcpSendTool");
1191
1209
  __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]|$)/;
1210
+ MCP_TOOL_READ_VERB_RE = /(?:^|_)(list|get|search|read|fetch|find|query|describe|count|retrieve|lookup|show|view)(_|[A-Z0-9]|$)/;
1193
1211
  __name(mcpActionTokens, "mcpActionTokens");
1194
1212
  __name2(mcpActionTokens, "mcpActionTokens");
1195
1213
  __name(isReviewableMcpDraftTool, "isReviewableMcpDraftTool");
@@ -1440,6 +1458,27 @@ var init_dist = __esm({
1440
1458
  }
1441
1459
  ];
1442
1460
  BROWSER_COMMAND_NAMES = BROWSER_COMMANDS.map((c) => c.name);
1461
+ DESKTOP_FILE_COMMANDS = [
1462
+ "files_roots",
1463
+ "files_stat",
1464
+ "files_list",
1465
+ "files_read",
1466
+ "files_search",
1467
+ "files_write",
1468
+ "files_mkdir",
1469
+ "files_move",
1470
+ "files_delete",
1471
+ "files_undo",
1472
+ "files_transfer_prepare",
1473
+ "files_transfer_upload",
1474
+ "files_watch_start",
1475
+ "files_watch_cancel"
1476
+ ];
1477
+ DESKTOP_FILE_COMMAND_SET = new Set(DESKTOP_FILE_COMMANDS);
1478
+ __name(isDesktopFileCommandName, "isDesktopFileCommandName");
1479
+ __name2(isDesktopFileCommandName, "isDesktopFileCommandName");
1480
+ __name(isDesktopFileSessionId, "isDesktopFileSessionId");
1481
+ __name2(isDesktopFileSessionId, "isDesktopFileSessionId");
1443
1482
  REASONING_EFFORT_VALUES = [
1444
1483
  "off",
1445
1484
  "minimal",
@@ -1448,6 +1487,8 @@ var init_dist = __esm({
1448
1487
  "high",
1449
1488
  "max"
1450
1489
  ];
1490
+ __name(resolveRequireToolApproval, "resolveRequireToolApproval");
1491
+ __name2(resolveRequireToolApproval, "resolveRequireToolApproval");
1451
1492
  AGENT_NAME_TOKEN = "[Your Agent Name]";
1452
1493
  DEFAULT_PERSONA_GUIDE = `# ${AGENT_NAME_TOKEN} - Persona
1453
1494
 
@@ -15051,7 +15092,7 @@ export const governance = {
15051
15092
  }
15052
15093
  if (setup.requireApproval && setup.requireApproval.length > 0) {
15053
15094
  const list = setup.requireApproval.map((t) => `'${t}'`).join(", ");
15054
- ruleLines.push(` requireApproval: [${list}],`);
15095
+ ruleLines.push(` requireToolApproval: [${list}],`);
15055
15096
  }
15056
15097
  if (setup.tokenLimit && setup.tokenLimit > 0) {
15057
15098
  ruleLines.push(` tokenBudget: ${setup.tokenLimit},`);
@@ -19962,6 +20003,15 @@ var DeviceTriggerApi = class extends HttpClient {
19962
20003
 
19963
20004
  // src/primitives/device-trigger.handler.ts
19964
20005
  init_base_handler();
20006
+
20007
+ // src/primitives/device-trigger.response.ts
20008
+ function parseDeviceTriggerList(data) {
20009
+ const triggers = data?.triggers ?? data?.deviceTriggers;
20010
+ return Array.isArray(triggers) ? triggers : null;
20011
+ }
20012
+ __name(parseDeviceTriggerList, "parseDeviceTriggerList");
20013
+
20014
+ // src/primitives/device-trigger.handler.ts
19965
20015
  var DeviceTriggerHandler = class extends BaseVersionedHandler {
19966
20016
  static {
19967
20017
  __name(this, "DeviceTriggerHandler");
@@ -20001,10 +20051,10 @@ var DeviceTriggerHandler = class extends BaseVersionedHandler {
20001
20051
  }
20002
20052
  async fetchFromServer(api) {
20003
20053
  const response = await api.getDeviceTriggers();
20004
- if (!response.success || !response.data?.deviceTriggers) {
20054
+ if (!response.success) {
20005
20055
  return null;
20006
20056
  }
20007
- return response.data.deviceTriggers;
20057
+ return parseDeviceTriggerList(response.data);
20008
20058
  }
20009
20059
  async createOnServer(api, primitive) {
20010
20060
  const response = await api.createDeviceTrigger({
@@ -29787,13 +29837,47 @@ init_cli();
29787
29837
  init_command_utils();
29788
29838
  init_analytics();
29789
29839
  import open from "open";
29840
+
29841
+ // src/utils/auth-handoff.ts
29842
+ init_constants();
29843
+ async function issueAdminHandoff(apiKey) {
29844
+ const response = await fetch(`${BASE_URLS.AUTH}/auth/handoff`, {
29845
+ method: "POST",
29846
+ headers: {
29847
+ Authorization: `Bearer ${apiKey}`,
29848
+ "Content-Type": "application/json"
29849
+ },
29850
+ body: JSON.stringify({
29851
+ audience: "admin"
29852
+ })
29853
+ });
29854
+ if (!response.ok) throw new Error("Could not create a secure dashboard sign-in handoff");
29855
+ const body = await response.json();
29856
+ if (typeof body.code !== "string" || !body.code) {
29857
+ throw new Error("Lua Auth returned an invalid dashboard sign-in handoff");
29858
+ }
29859
+ return body.code;
29860
+ }
29861
+ __name(issueAdminHandoff, "issueAdminHandoff");
29862
+ function buildAdminHandoffUrl(code, agentId, orgId) {
29863
+ const url = new URL("/auth-handoff", "https://admin.heylua.ai");
29864
+ url.searchParams.set("code", code);
29865
+ url.searchParams.set("redirect", "/admin/usage");
29866
+ url.searchParams.set("agentId", agentId);
29867
+ url.searchParams.set("orgId", orgId);
29868
+ return url.toString();
29869
+ }
29870
+ __name(buildAdminHandoffUrl, "buildAdminHandoffUrl");
29871
+
29872
+ // src/commands/admin.ts
29790
29873
  async function adminCommand() {
29791
29874
  return withErrorHandling(async () => {
29792
29875
  writeProgress("Opening Lua Admin Dashboard...");
29793
29876
  const { agentId, orgId, apiKey } = await initializeCommand({
29794
29877
  showProgress: false
29795
29878
  });
29796
- const adminUrl = `https://admin.heylua.ai/validate-token/${apiKey}?redirect=/admin/usage?&agentId=${agentId}&orgId=${orgId}`;
29879
+ const handoffCode = await issueAdminHandoff(apiKey);
29880
+ const adminUrl = buildAdminHandoffUrl(handoffCode, agentId, orgId);
29797
29881
  await open(adminUrl);
29798
29882
  writeSuccess("Lua Admin Dashboard opened in your browser");
29799
29883
  console.log(`
@@ -29848,10 +29932,10 @@ async function docsCommand() {
29848
29932
  __name(docsCommand, "docsCommand");
29849
29933
 
29850
29934
  // src/commands/channels.ts
29851
- init_cli();
29852
- init_command_utils();
29853
29935
  import inquirer12 from "inquirer";
29854
29936
  import open4 from "open";
29937
+ init_cli();
29938
+ init_command_utils();
29855
29939
 
29856
29940
  // src/api/channels.api.service.ts
29857
29941
  init_http_client();
@@ -30419,7 +30503,8 @@ async function openAdminDashboard(apiKey, config) {
30419
30503
  if (!orgId) {
30420
30504
  throw new Error("No orgId found in lua.skill.yaml. Please ensure your configuration is valid.");
30421
30505
  }
30422
- const adminUrl = `https://admin.heylua.ai/validate-token/${apiKey}?redirect=/admin/usage?&agentId=${agentId}&orgId=${orgId}`;
30506
+ const handoffCode = await issueAdminHandoff(apiKey);
30507
+ const adminUrl = buildAdminHandoffUrl(handoffCode, agentId, orgId);
30423
30508
  await open4(adminUrl);
30424
30509
  writeSuccess("\u2705 Lua Admin Dashboard opened in your browser");
30425
30510
  console.log(`
@@ -41158,6 +41243,7 @@ async function executeNonInteractive12(context, action, cmdOptions) {
41158
41243
  authMethod: cmdOptions?.authMethod,
41159
41244
  scopes: cmdOptions?.scopes,
41160
41245
  hideSensitive: cmdOptions?.hideSensitive === "true",
41246
+ accountLabel: cmdOptions?.accountLabel,
41161
41247
  // Trigger options
41162
41248
  triggers: cmdOptions?.triggers,
41163
41249
  customWebhook: cmdOptions?.customWebhook === true,
@@ -41834,7 +41920,7 @@ Integration: ${selectedIntegration.name}`);
41834
41920
  triggers: selectedTriggers,
41835
41921
  webhookUrl,
41836
41922
  isCustomWebhook
41837
- });
41923
+ }, options.accountLabel);
41838
41924
  } else {
41839
41925
  writeError(`
41840
41926
  \u274C Authorization failed: ${result.error || "Unknown error"}`);
@@ -41857,8 +41943,22 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
41857
41943
  triggers: [],
41858
41944
  webhookUrl: "",
41859
41945
  isCustomWebhook: false
41860
- }) {
41946
+ }, requestedAccountLabel) {
41861
41947
  writeProgress(`\u{1F504} Setting up ${integration.name} connection...`);
41948
+ let displayName = requestedAccountLabel?.trim();
41949
+ if (!displayName) {
41950
+ const labelAnswer = await safePrompt([
41951
+ {
41952
+ type: "input",
41953
+ name: "displayName",
41954
+ message: "Account label (used to distinguish this connection):",
41955
+ default: integration.name,
41956
+ validate: /* @__PURE__ */ __name((value) => value.trim().length > 0 || "Account label is required", "validate")
41957
+ }
41958
+ ]);
41959
+ if (!labelAnswer) return;
41960
+ displayName = labelAnswer.displayName.trim();
41961
+ }
41862
41962
  const triggers = webhookConfig.triggers.map((t) => ({
41863
41963
  objectType: t.objectType,
41864
41964
  event: t.event,
@@ -41868,6 +41968,7 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
41868
41968
  const result = await context.unifiedToApi.finalizeConnection(context.agentId, {
41869
41969
  connectionId,
41870
41970
  integrationType: integration.value,
41971
+ displayName,
41871
41972
  scopes: scopes.length > 0 ? scopes : void 0,
41872
41973
  hideSensitive,
41873
41974
  triggers: triggers.length > 0 ? triggers : void 0
@@ -42276,7 +42377,7 @@ Available scopes for ${selectedIntegration.name}:`);
42276
42377
  triggers: triggersToRestore,
42277
42378
  webhookUrl: AGENT_WEBHOOK_URL,
42278
42379
  isCustomWebhook: hasCustomWebhook
42279
- });
42380
+ }, options.accountLabel);
42280
42381
  if (triggersToRestore.length > 0) {
42281
42382
  writeSuccess(`Restored ${triggersToRestore.length} trigger(s) from previous connection`);
42282
42383
  }
@@ -46539,7 +46640,7 @@ Examples:
46539
46640
  $ lua mcp deactivate --server-name api-server Deactivate a server
46540
46641
  $ lua mcp delete --server-name old-server Delete a server
46541
46642
  `).action(mcpCommand);
46542
- program2.command("integrations [action] [subaction]").description("\u{1F517} Connect third-party integrations via Unified.to").option("--integration <type>", "Integration type (e.g., linear, googlecalendar)").option("--auth-method <method>", "Authentication method: 'oauth' or 'token'").option("--scopes <scopes>", "Comma-separated OAuth scopes (or 'all' for all scopes)").option("--hide-sensitive <bool>", "Hide sensitive data from MCP tools (default: true)").option("--connection-id <id>", "Connection ID to disconnect or pause/resume").option("--connection <id>", "Connection ID for trigger").option("--webhook-id <id>", "Trigger ID to delete/pause/resume").option("--object <type>", "Object type for webhook (e.g., task_task, calendar_event)").option("--event <type>", "Event type for webhook: created, updated, or deleted").option("--hook-url <url>", "Custom webhook URL (default: agent trigger)").option("--interval <minutes>", "Polling interval for virtual webhooks (60, 120, 240, 480, 720, 1440, 2880)").option("--triggers <events>", "Comma-separated triggers (e.g., task_task.created,task_task.updated)").option("--custom-webhook", "Use custom webhook URL instead of agent trigger").option("--json", "Output as JSON (for info and webhooks events commands)").option("--reason <text>", "Optional reason for pausing a trigger").addHelpText("after", `
46643
+ program2.command("integrations [action] [subaction]").description("\u{1F517} Connect third-party integrations via Unified.to").option("--integration <type>", "Integration type (e.g., linear, googlecalendar)").option("--auth-method <method>", "Authentication method: 'oauth' or 'token'").option("--scopes <scopes>", "Comma-separated OAuth scopes (or 'all' for all scopes)").option("--hide-sensitive <bool>", "Hide sensitive data from MCP tools (default: true)").option("--account-label <label>", "Account label used to distinguish multiple connected accounts").option("--connection-id <id>", "Connection ID to disconnect or pause/resume").option("--connection <id>", "Connection ID for trigger").option("--webhook-id <id>", "Trigger ID to delete/pause/resume").option("--object <type>", "Object type for webhook (e.g., task_task, calendar_event)").option("--event <type>", "Event type for webhook: created, updated, or deleted").option("--hook-url <url>", "Custom webhook URL (default: agent trigger)").option("--interval <minutes>", "Polling interval for virtual webhooks (60, 120, 240, 480, 720, 1440, 2880)").option("--triggers <events>", "Comma-separated triggers (e.g., task_task.created,task_task.updated)").option("--custom-webhook", "Use custom webhook URL instead of agent trigger").option("--json", "Output as JSON (for info and webhooks events commands)").option("--reason <text>", "Optional reason for pausing a trigger").addHelpText("after", `
46543
46644
  Arguments:
46544
46645
  action Optional: 'connect', 'update', 'list', 'available', 'info', 'disconnect', 'webhooks'
46545
46646
  (alias: 'triggers'), or 'mcp'