lua-cli 3.23.0 → 3.23.2

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({
@@ -26211,15 +26261,18 @@ var ChatApi = class extends HttpClient {
26211
26261
  }
26212
26262
  }
26213
26263
  /**
26214
- * Clears the authenticated user's conversation history for an agent
26264
+ * Clears conversation history for an agent. Without targetIdentifier this is
26265
+ * self-scoped; cross-user clears require org:manage for the agent on the server.
26215
26266
  * @param agentId - The unique identifier of the agent
26216
26267
  * @param threadId - Optional thread ID to clear a specific conversation thread
26268
+ * @param targetIdentifier - Optional target user ID, email, or mobile number
26217
26269
  * @returns Promise resolving to an ApiResponse with confirmation
26218
26270
  * @throws Error if the agent is not found or the clear operation fails
26219
26271
  */
26220
- async clearHistory(agentId, threadId) {
26272
+ async clearHistory(agentId, threadId, targetIdentifier) {
26221
26273
  const params = new URLSearchParams();
26222
26274
  if (threadId) params.set("threadId", threadId);
26275
+ if (targetIdentifier !== void 0) params.set("targetIdentifier", targetIdentifier);
26223
26276
  const query = params.toString() ? `?${params.toString()}` : "";
26224
26277
  const url = `/chat/history/${agentId}${query}`;
26225
26278
  return this.httpDelete(url, {
@@ -27651,22 +27704,24 @@ init_analytics();
27651
27704
  async function chatClearCommand(options, command) {
27652
27705
  return withErrorHandling(async () => {
27653
27706
  const resolvedOptions = options ?? {};
27654
- if (resolvedOptions.user) {
27655
- throw new Error("The --user option was removed: cross-user history clear is no longer supported. This command only clears your own chat history \u2014 re-run it without --user.");
27707
+ const targetIdentifier = resolvedOptions.user?.trim();
27708
+ if (resolvedOptions.user !== void 0 && !targetIdentifier) {
27709
+ throw new Error("--user requires a non-empty user ID, email address, or mobile number.");
27656
27710
  }
27657
27711
  const { agentId, apiKey } = await initializeCommand();
27658
27712
  const threadId = resolvedOptions.thread ?? command?.parent?.opts()?.thread;
27659
27713
  const force = !!resolvedOptions.force;
27660
27714
  const threadContext = threadId ? ` in thread "${threadId}"` : "";
27715
+ const targetContext = targetIdentifier ? ` for user "${targetIdentifier}"` : "";
27661
27716
  if (!force) {
27662
27717
  console.log(`
27663
- \u26A0\uFE0F WARNING: This will clear your conversation history${threadContext}!`);
27718
+ \u26A0\uFE0F WARNING: This will clear conversation history${targetContext}${threadContext}!`);
27664
27719
  console.log("\u26A0\uFE0F This action cannot be undone.\n");
27665
27720
  const confirmAnswer = await safePrompt([
27666
27721
  {
27667
27722
  type: "confirm",
27668
27723
  name: "confirm",
27669
- message: `Are you sure you want to clear your conversation history${threadContext}?`,
27724
+ message: `Are you sure you want to clear conversation history${targetContext}${threadContext}?`,
27670
27725
  default: false
27671
27726
  }
27672
27727
  ]);
@@ -27676,16 +27731,17 @@ async function chatClearCommand(options, command) {
27676
27731
  }
27677
27732
  writeProgress("\u{1F504} Clearing conversation history...");
27678
27733
  const chatApi = new ChatApi(BASE_URLS.CHAT, apiKey);
27679
- const response = await chatApi.clearHistory(agentId, threadId);
27734
+ const response = await chatApi.clearHistory(agentId, threadId, targetIdentifier);
27680
27735
  if (!response.success) {
27681
27736
  throw new Error(response.error?.message || "Failed to clear conversation history");
27682
27737
  }
27683
- writeSuccess(`\u2705 Your conversation history has been cleared${threadContext}`);
27684
- console.log(`\u{1F4A1} Your chat history has been completely removed${threadContext}.
27738
+ writeSuccess(`\u2705 Conversation history has been cleared${targetContext}${threadContext}`);
27739
+ console.log(`\u{1F4A1} Chat history has been completely removed${targetContext}${threadContext}.
27685
27740
  `);
27686
27741
  trackEvent("cli_chat_cleared", {
27687
27742
  force_mode: force,
27688
- has_thread_target: !!threadId
27743
+ has_thread_target: !!threadId,
27744
+ has_user_target: !!targetIdentifier
27689
27745
  });
27690
27746
  }, "chat clear");
27691
27747
  }
@@ -29787,13 +29843,47 @@ init_cli();
29787
29843
  init_command_utils();
29788
29844
  init_analytics();
29789
29845
  import open from "open";
29846
+
29847
+ // src/utils/auth-handoff.ts
29848
+ init_constants();
29849
+ async function issueAdminHandoff(apiKey) {
29850
+ const response = await fetch(`${BASE_URLS.AUTH}/auth/handoff`, {
29851
+ method: "POST",
29852
+ headers: {
29853
+ Authorization: `Bearer ${apiKey}`,
29854
+ "Content-Type": "application/json"
29855
+ },
29856
+ body: JSON.stringify({
29857
+ audience: "admin"
29858
+ })
29859
+ });
29860
+ if (!response.ok) throw new Error("Could not create a secure dashboard sign-in handoff");
29861
+ const body = await response.json();
29862
+ if (typeof body.code !== "string" || !body.code) {
29863
+ throw new Error("Lua Auth returned an invalid dashboard sign-in handoff");
29864
+ }
29865
+ return body.code;
29866
+ }
29867
+ __name(issueAdminHandoff, "issueAdminHandoff");
29868
+ function buildAdminHandoffUrl(code, agentId, orgId) {
29869
+ const url = new URL("/auth-handoff", "https://admin.heylua.ai");
29870
+ url.searchParams.set("code", code);
29871
+ url.searchParams.set("redirect", "/admin/usage");
29872
+ url.searchParams.set("agentId", agentId);
29873
+ url.searchParams.set("orgId", orgId);
29874
+ return url.toString();
29875
+ }
29876
+ __name(buildAdminHandoffUrl, "buildAdminHandoffUrl");
29877
+
29878
+ // src/commands/admin.ts
29790
29879
  async function adminCommand() {
29791
29880
  return withErrorHandling(async () => {
29792
29881
  writeProgress("Opening Lua Admin Dashboard...");
29793
29882
  const { agentId, orgId, apiKey } = await initializeCommand({
29794
29883
  showProgress: false
29795
29884
  });
29796
- const adminUrl = `https://admin.heylua.ai/validate-token/${apiKey}?redirect=/admin/usage?&agentId=${agentId}&orgId=${orgId}`;
29885
+ const handoffCode = await issueAdminHandoff(apiKey);
29886
+ const adminUrl = buildAdminHandoffUrl(handoffCode, agentId, orgId);
29797
29887
  await open(adminUrl);
29798
29888
  writeSuccess("Lua Admin Dashboard opened in your browser");
29799
29889
  console.log(`
@@ -29848,10 +29938,10 @@ async function docsCommand() {
29848
29938
  __name(docsCommand, "docsCommand");
29849
29939
 
29850
29940
  // src/commands/channels.ts
29851
- init_cli();
29852
- init_command_utils();
29853
29941
  import inquirer12 from "inquirer";
29854
29942
  import open4 from "open";
29943
+ init_cli();
29944
+ init_command_utils();
29855
29945
 
29856
29946
  // src/api/channels.api.service.ts
29857
29947
  init_http_client();
@@ -30419,7 +30509,8 @@ async function openAdminDashboard(apiKey, config) {
30419
30509
  if (!orgId) {
30420
30510
  throw new Error("No orgId found in lua.skill.yaml. Please ensure your configuration is valid.");
30421
30511
  }
30422
- const adminUrl = `https://admin.heylua.ai/validate-token/${apiKey}?redirect=/admin/usage?&agentId=${agentId}&orgId=${orgId}`;
30512
+ const handoffCode = await issueAdminHandoff(apiKey);
30513
+ const adminUrl = buildAdminHandoffUrl(handoffCode, agentId, orgId);
30423
30514
  await open4(adminUrl);
30424
30515
  writeSuccess("\u2705 Lua Admin Dashboard opened in your browser");
30425
30516
  console.log(`
@@ -41158,6 +41249,7 @@ async function executeNonInteractive12(context, action, cmdOptions) {
41158
41249
  authMethod: cmdOptions?.authMethod,
41159
41250
  scopes: cmdOptions?.scopes,
41160
41251
  hideSensitive: cmdOptions?.hideSensitive === "true",
41252
+ accountLabel: cmdOptions?.accountLabel,
41161
41253
  // Trigger options
41162
41254
  triggers: cmdOptions?.triggers,
41163
41255
  customWebhook: cmdOptions?.customWebhook === true,
@@ -41834,7 +41926,7 @@ Integration: ${selectedIntegration.name}`);
41834
41926
  triggers: selectedTriggers,
41835
41927
  webhookUrl,
41836
41928
  isCustomWebhook
41837
- });
41929
+ }, options.accountLabel);
41838
41930
  } else {
41839
41931
  writeError(`
41840
41932
  \u274C Authorization failed: ${result.error || "Unknown error"}`);
@@ -41857,8 +41949,22 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
41857
41949
  triggers: [],
41858
41950
  webhookUrl: "",
41859
41951
  isCustomWebhook: false
41860
- }) {
41952
+ }, requestedAccountLabel) {
41861
41953
  writeProgress(`\u{1F504} Setting up ${integration.name} connection...`);
41954
+ let displayName = requestedAccountLabel?.trim();
41955
+ if (!displayName) {
41956
+ const labelAnswer = await safePrompt([
41957
+ {
41958
+ type: "input",
41959
+ name: "displayName",
41960
+ message: "Account label (used to distinguish this connection):",
41961
+ default: integration.name,
41962
+ validate: /* @__PURE__ */ __name((value) => value.trim().length > 0 || "Account label is required", "validate")
41963
+ }
41964
+ ]);
41965
+ if (!labelAnswer) return;
41966
+ displayName = labelAnswer.displayName.trim();
41967
+ }
41862
41968
  const triggers = webhookConfig.triggers.map((t) => ({
41863
41969
  objectType: t.objectType,
41864
41970
  event: t.event,
@@ -41868,6 +41974,7 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
41868
41974
  const result = await context.unifiedToApi.finalizeConnection(context.agentId, {
41869
41975
  connectionId,
41870
41976
  integrationType: integration.value,
41977
+ displayName,
41871
41978
  scopes: scopes.length > 0 ? scopes : void 0,
41872
41979
  hideSensitive,
41873
41980
  triggers: triggers.length > 0 ? triggers : void 0
@@ -42276,7 +42383,7 @@ Available scopes for ${selectedIntegration.name}:`);
42276
42383
  triggers: triggersToRestore,
42277
42384
  webhookUrl: AGENT_WEBHOOK_URL,
42278
42385
  isCustomWebhook: hasCustomWebhook
42279
- });
42386
+ }, options.accountLabel);
42280
42387
  if (triggersToRestore.length > 0) {
42281
42388
  writeSuccess(`Restored ${triggersToRestore.length} trigger(s) from previous connection`);
42282
42389
  }
@@ -46279,16 +46386,19 @@ Examples:
46279
46386
  $ lua chat -b "Hello" "What is the weather?" "Tell me a joke" -d 2000 -e sandbox Batch test
46280
46387
  $ lua chat --agent-version 3 -m "test" Preview agent version 3 in an isolated thread
46281
46388
  `).action(chatCommand);
46282
- chatCmd.command("clear").description("Clear your conversation history").option("--user <identifier>", "[removed] cross-user history clear is no longer supported").option("-t, --thread <id>", "Clear a specific thread's history instead of all history").option("--force", "Skip confirmation prompt").addHelpText("after", `
46389
+ chatCmd.command("clear").description("Clear your own or an administered user's conversation history").option("--user <identifier>", "Clear another user by ID, email, or mobile (requires org:manage)").option("-t, --thread <id>", "Clear a specific thread's history instead of all history").option("--force", "Skip confirmation prompt").addHelpText("after", `
46283
46390
  Examples:
46284
46391
  $ lua chat clear Clear your history
46285
46392
  $ lua chat clear --force Clear your history without confirmation
46393
+ $ lua chat clear --user user@example.com Clear another user's history (requires org:manage)
46394
+ $ lua chat clear --user +1234567890 --force Clear another user's history without confirmation
46286
46395
  $ lua chat clear --thread <threadId> Clear a specific thread's history
46287
46396
  $ lua chat clear --thread <threadId> --force Clear a specific thread's history without confirmation
46288
46397
 
46289
46398
  Notes:
46290
- - This command only clears YOUR OWN conversation history
46291
- - The --user option was removed: cross-user history clear is no longer supported
46399
+ - Without --user, this command clears only YOUR OWN conversation history
46400
+ - --user requires org:manage for the agent
46401
+ - Org-admin grants do not cascade to private agents; org owners and explicit agent grants follow shared authorization rules
46292
46402
  `).action(chatClearCommand);
46293
46403
  program2.command("env [environment]").description("\u2699\uFE0F Manage environment variables").option("-k, --key <name>", "Environment variable key").option("-v, --value <value>", "Environment variable value").option("-d, --delete", "Delete the specified key").option("--list", "List all environment variables").addHelpText("after", `
46294
46404
  Arguments:
@@ -46539,7 +46649,7 @@ Examples:
46539
46649
  $ lua mcp deactivate --server-name api-server Deactivate a server
46540
46650
  $ lua mcp delete --server-name old-server Delete a server
46541
46651
  `).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", `
46652
+ 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
46653
  Arguments:
46544
46654
  action Optional: 'connect', 'update', 'list', 'available', 'info', 'disconnect', 'webhooks'
46545
46655
  (alias: 'triggers'), or 'mcp'