lua-cli 3.22.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/api-exports.d.ts +120 -14
- package/dist/api-exports.js +220 -25
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +337 -74
- package/dist/index.js.map +1 -1
- package/docs/README.md +2 -2
- package/docs/api/Jobs.md +1 -2
- package/docs/api/LuaJob.md +1 -1
- package/package.json +3 -3
- package/template/examples/jobs/DataMigrationJob.ts +2 -2
- package/template/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -879,6 +879,31 @@ 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 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;
|
|
906
|
+
}
|
|
882
907
|
function isReviewableExecuteTool(tool) {
|
|
883
908
|
return isAllowedReviewableExecuteTool(tool) || isReviewableMcpSendTool(tool);
|
|
884
909
|
}
|
|
@@ -1115,10 +1140,40 @@ function foldRichPartsIntoMessages(messages, records, makeMessage, sameTurnGroup
|
|
|
1115
1140
|
while (next < synthetic.length) combined.push(synthetic[next++].message);
|
|
1116
1141
|
return mergeRichPartMirrorMessages(combined, sameTurnGroup);
|
|
1117
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
|
+
}
|
|
1118
1157
|
function buildDefaultPersona(agentName) {
|
|
1119
1158
|
return DEFAULT_PERSONA_GUIDE.replace(AGENT_NAME_TOKEN, () => agentName || "My Agent");
|
|
1120
1159
|
}
|
|
1121
|
-
|
|
1160
|
+
function resolveLuaJobTimeoutSeconds(timeout) {
|
|
1161
|
+
const resolved = timeout ?? LUA_JOB_DEFAULT_TIMEOUT_SECONDS;
|
|
1162
|
+
if (!Number.isInteger(resolved)) {
|
|
1163
|
+
throw new TypeError("LuaJob `timeout` must be an integer number of seconds.");
|
|
1164
|
+
}
|
|
1165
|
+
if (resolved < LUA_JOB_MIN_TIMEOUT_SECONDS || resolved > LUA_JOB_MAX_TIMEOUT_SECONDS) {
|
|
1166
|
+
throw new RangeError(`LuaJob \`timeout\` must be between ${LUA_JOB_MIN_TIMEOUT_SECONDS} and ${LUA_JOB_MAX_TIMEOUT_SECONDS} seconds.`);
|
|
1167
|
+
}
|
|
1168
|
+
return resolved;
|
|
1169
|
+
}
|
|
1170
|
+
function normalizeLuaJobExecutionTimeoutSeconds(timeout) {
|
|
1171
|
+
if (typeof timeout !== "number" || !Number.isFinite(timeout)) {
|
|
1172
|
+
return LUA_JOB_DEFAULT_TIMEOUT_SECONDS;
|
|
1173
|
+
}
|
|
1174
|
+
return Math.min(Math.max(timeout, LUA_JOB_MIN_TIMEOUT_SECONDS), LUA_JOB_MAX_TIMEOUT_SECONDS);
|
|
1175
|
+
}
|
|
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;
|
|
1122
1177
|
var init_dist = __esm({
|
|
1123
1178
|
"../shared-types/dist/index.mjs"() {
|
|
1124
1179
|
"use strict";
|
|
@@ -1152,6 +1207,26 @@ var init_dist = __esm({
|
|
|
1152
1207
|
REVIEWABLE_MCP_SEND_TOOL_SUFFIX = "_create_messaging_message";
|
|
1153
1208
|
__name(isReviewableMcpSendTool, "isReviewableMcpSendTool");
|
|
1154
1209
|
__name2(isReviewableMcpSendTool, "isReviewableMcpSendTool");
|
|
1210
|
+
MCP_TOOL_READ_VERB_RE = /(?:^|_)(list|get|search|read|fetch|find|query|describe|count|retrieve|lookup|show|view)(_|[A-Z0-9]|$)/;
|
|
1211
|
+
__name(mcpActionTokens, "mcpActionTokens");
|
|
1212
|
+
__name2(mcpActionTokens, "mcpActionTokens");
|
|
1213
|
+
__name(isReviewableMcpDraftTool, "isReviewableMcpDraftTool");
|
|
1214
|
+
__name2(isReviewableMcpDraftTool, "isReviewableMcpDraftTool");
|
|
1215
|
+
MCP_DRAFT_CREATE_VERBS = /* @__PURE__ */ new Set([
|
|
1216
|
+
"create",
|
|
1217
|
+
"compose",
|
|
1218
|
+
"make",
|
|
1219
|
+
"new",
|
|
1220
|
+
"save",
|
|
1221
|
+
"add",
|
|
1222
|
+
"write",
|
|
1223
|
+
"stage",
|
|
1224
|
+
"prepare"
|
|
1225
|
+
]);
|
|
1226
|
+
__name(isMcpDraftCreateTool, "isMcpDraftCreateTool");
|
|
1227
|
+
__name2(isMcpDraftCreateTool, "isMcpDraftCreateTool");
|
|
1228
|
+
__name(mcpSendSiblingForDraftTool, "mcpSendSiblingForDraftTool");
|
|
1229
|
+
__name2(mcpSendSiblingForDraftTool, "mcpSendSiblingForDraftTool");
|
|
1155
1230
|
__name(isReviewableExecuteTool, "isReviewableExecuteTool");
|
|
1156
1231
|
__name2(isReviewableExecuteTool, "isReviewableExecuteTool");
|
|
1157
1232
|
NON_INTERACTIVE_CHANNELS = [
|
|
@@ -1184,11 +1259,11 @@ var init_dist = __esm({
|
|
|
1184
1259
|
},
|
|
1185
1260
|
{
|
|
1186
1261
|
name: "session_open",
|
|
1187
|
-
description: "Open/attach a browser session (its own cookies/auth). Args: url?, headed?, profile?, confirmActions?."
|
|
1262
|
+
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
1263
|
},
|
|
1189
1264
|
{
|
|
1190
1265
|
name: "navigate",
|
|
1191
|
-
description: "Navigate the session to a URL. Args: url, waitUntil?."
|
|
1266
|
+
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
1267
|
},
|
|
1193
1268
|
{
|
|
1194
1269
|
name: "back",
|
|
@@ -1383,6 +1458,27 @@ var init_dist = __esm({
|
|
|
1383
1458
|
}
|
|
1384
1459
|
];
|
|
1385
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");
|
|
1386
1482
|
REASONING_EFFORT_VALUES = [
|
|
1387
1483
|
"off",
|
|
1388
1484
|
"minimal",
|
|
@@ -1391,6 +1487,8 @@ var init_dist = __esm({
|
|
|
1391
1487
|
"high",
|
|
1392
1488
|
"max"
|
|
1393
1489
|
];
|
|
1490
|
+
__name(resolveRequireToolApproval, "resolveRequireToolApproval");
|
|
1491
|
+
__name2(resolveRequireToolApproval, "resolveRequireToolApproval");
|
|
1394
1492
|
AGENT_NAME_TOKEN = "[Your Agent Name]";
|
|
1395
1493
|
DEFAULT_PERSONA_GUIDE = `# ${AGENT_NAME_TOKEN} - Persona
|
|
1396
1494
|
|
|
@@ -1701,6 +1799,13 @@ Feel free to add, remove, or rename sections. Your persona can be a single parag
|
|
|
1701
1799
|
voiceId: z.string().min(1),
|
|
1702
1800
|
version: z.string().optional()
|
|
1703
1801
|
});
|
|
1802
|
+
LUA_JOB_DEFAULT_TIMEOUT_SECONDS = 300;
|
|
1803
|
+
LUA_JOB_MIN_TIMEOUT_SECONDS = 1;
|
|
1804
|
+
LUA_JOB_MAX_TIMEOUT_SECONDS = 600;
|
|
1805
|
+
__name(resolveLuaJobTimeoutSeconds, "resolveLuaJobTimeoutSeconds");
|
|
1806
|
+
__name2(resolveLuaJobTimeoutSeconds, "resolveLuaJobTimeoutSeconds");
|
|
1807
|
+
__name(normalizeLuaJobExecutionTimeoutSeconds, "normalizeLuaJobExecutionTimeoutSeconds");
|
|
1808
|
+
__name2(normalizeLuaJobExecutionTimeoutSeconds, "normalizeLuaJobExecutionTimeoutSeconds");
|
|
1704
1809
|
}
|
|
1705
1810
|
});
|
|
1706
1811
|
|
|
@@ -11034,6 +11139,8 @@ var init_user_instance = __esm({
|
|
|
11034
11139
|
"data",
|
|
11035
11140
|
"userAPI",
|
|
11036
11141
|
"update",
|
|
11142
|
+
"patch",
|
|
11143
|
+
"unset",
|
|
11037
11144
|
"clear",
|
|
11038
11145
|
"toJSON",
|
|
11039
11146
|
"_luaProfile"
|
|
@@ -11112,9 +11219,27 @@ var init_user_instance = __esm({
|
|
|
11112
11219
|
this.data = response;
|
|
11113
11220
|
return this.data;
|
|
11114
11221
|
} catch (error) {
|
|
11115
|
-
throw new Error("Failed to update user data"
|
|
11222
|
+
throw new Error("Failed to update user data", {
|
|
11223
|
+
cause: error
|
|
11224
|
+
});
|
|
11116
11225
|
}
|
|
11117
11226
|
}
|
|
11227
|
+
async patch(mutation) {
|
|
11228
|
+
try {
|
|
11229
|
+
const response = await this.userAPI.patch(mutation);
|
|
11230
|
+
this.data = response;
|
|
11231
|
+
return this.data;
|
|
11232
|
+
} catch (error) {
|
|
11233
|
+
throw new Error("Failed to patch user data", {
|
|
11234
|
+
cause: error
|
|
11235
|
+
});
|
|
11236
|
+
}
|
|
11237
|
+
}
|
|
11238
|
+
async unset(...fields) {
|
|
11239
|
+
return this.patch({
|
|
11240
|
+
unset: fields
|
|
11241
|
+
});
|
|
11242
|
+
}
|
|
11118
11243
|
/**
|
|
11119
11244
|
* Clears all user data for the current user
|
|
11120
11245
|
* @returns Promise resolving to true if clearing was successful
|
|
@@ -11123,9 +11248,12 @@ var init_user_instance = __esm({
|
|
|
11123
11248
|
async clear() {
|
|
11124
11249
|
try {
|
|
11125
11250
|
await this.userAPI.clear();
|
|
11251
|
+
this.data = {};
|
|
11126
11252
|
return true;
|
|
11127
11253
|
} catch (error) {
|
|
11128
|
-
throw new Error("Failed to clear user data"
|
|
11254
|
+
throw new Error("Failed to clear user data", {
|
|
11255
|
+
cause: error
|
|
11256
|
+
});
|
|
11129
11257
|
}
|
|
11130
11258
|
}
|
|
11131
11259
|
/**
|
|
@@ -11138,7 +11266,9 @@ var init_user_instance = __esm({
|
|
|
11138
11266
|
await this.userAPI.update(this.data);
|
|
11139
11267
|
return true;
|
|
11140
11268
|
} catch (error) {
|
|
11141
|
-
throw new Error("Failed to save user data"
|
|
11269
|
+
throw new Error("Failed to save user data", {
|
|
11270
|
+
cause: error
|
|
11271
|
+
});
|
|
11142
11272
|
}
|
|
11143
11273
|
}
|
|
11144
11274
|
/**
|
|
@@ -11152,7 +11282,9 @@ var init_user_instance = __esm({
|
|
|
11152
11282
|
await this.userAPI.sendMessage(messages);
|
|
11153
11283
|
return true;
|
|
11154
11284
|
} catch (error) {
|
|
11155
|
-
throw new Error("Failed to send message"
|
|
11285
|
+
throw new Error("Failed to send message", {
|
|
11286
|
+
cause: error
|
|
11287
|
+
});
|
|
11156
11288
|
}
|
|
11157
11289
|
}
|
|
11158
11290
|
//get chat history
|
|
@@ -11160,7 +11292,9 @@ var init_user_instance = __esm({
|
|
|
11160
11292
|
try {
|
|
11161
11293
|
return await this.userAPI.getChatHistory();
|
|
11162
11294
|
} catch (error) {
|
|
11163
|
-
throw new Error("Failed to get chat history"
|
|
11295
|
+
throw new Error("Failed to get chat history", {
|
|
11296
|
+
cause: error
|
|
11297
|
+
});
|
|
11164
11298
|
}
|
|
11165
11299
|
}
|
|
11166
11300
|
};
|
|
@@ -12576,6 +12710,8 @@ var init_data_entry_instance = __esm({
|
|
|
12576
12710
|
"score",
|
|
12577
12711
|
"customDataAPI",
|
|
12578
12712
|
"update",
|
|
12713
|
+
"patch",
|
|
12714
|
+
"unset",
|
|
12579
12715
|
"delete",
|
|
12580
12716
|
"toJSON"
|
|
12581
12717
|
];
|
|
@@ -12667,9 +12803,33 @@ var init_data_entry_instance = __esm({
|
|
|
12667
12803
|
};
|
|
12668
12804
|
return this.data;
|
|
12669
12805
|
} catch (error) {
|
|
12670
|
-
throw new Error("Failed to update custom data entry"
|
|
12806
|
+
throw new Error("Failed to update custom data entry", {
|
|
12807
|
+
cause: error
|
|
12808
|
+
});
|
|
12809
|
+
}
|
|
12810
|
+
}
|
|
12811
|
+
async patch(mutation) {
|
|
12812
|
+
try {
|
|
12813
|
+
await this.customDataAPI.patch(this.collectionName, this.id, mutation);
|
|
12814
|
+
this.data = {
|
|
12815
|
+
...this.data,
|
|
12816
|
+
...mutation.set ?? {}
|
|
12817
|
+
};
|
|
12818
|
+
for (const field of mutation.unset ?? []) {
|
|
12819
|
+
delete this.data[field];
|
|
12820
|
+
}
|
|
12821
|
+
return this.data;
|
|
12822
|
+
} catch (error) {
|
|
12823
|
+
throw new Error("Failed to patch custom data entry", {
|
|
12824
|
+
cause: error
|
|
12825
|
+
});
|
|
12671
12826
|
}
|
|
12672
12827
|
}
|
|
12828
|
+
async unset(...fields) {
|
|
12829
|
+
return this.patch({
|
|
12830
|
+
unset: fields
|
|
12831
|
+
});
|
|
12832
|
+
}
|
|
12673
12833
|
/**
|
|
12674
12834
|
* Deletes the custom data entry
|
|
12675
12835
|
* @returns Promise resolving to true if deletion was successful
|
|
@@ -12680,7 +12840,9 @@ var init_data_entry_instance = __esm({
|
|
|
12680
12840
|
await this.customDataAPI.delete(this.collectionName, this.id);
|
|
12681
12841
|
return true;
|
|
12682
12842
|
} catch (error) {
|
|
12683
|
-
throw new Error("Failed to delete custom data entry"
|
|
12843
|
+
throw new Error("Failed to delete custom data entry", {
|
|
12844
|
+
cause: error
|
|
12845
|
+
});
|
|
12684
12846
|
}
|
|
12685
12847
|
}
|
|
12686
12848
|
/**
|
|
@@ -12694,7 +12856,9 @@ var init_data_entry_instance = __esm({
|
|
|
12694
12856
|
await this.customDataAPI.update(this.collectionName, this.id, this.data, searchText);
|
|
12695
12857
|
return true;
|
|
12696
12858
|
} catch (error) {
|
|
12697
|
-
throw new Error("Failed to save data entry"
|
|
12859
|
+
throw new Error("Failed to save data entry", {
|
|
12860
|
+
cause: error
|
|
12861
|
+
});
|
|
12698
12862
|
}
|
|
12699
12863
|
}
|
|
12700
12864
|
};
|
|
@@ -12805,6 +12969,15 @@ var init_custom_data_api_service = __esm({
|
|
|
12805
12969
|
}
|
|
12806
12970
|
throw new Error(response.error?.message || "Failed to update custom data entry");
|
|
12807
12971
|
}
|
|
12972
|
+
async patch(collectionName, entryId, mutation) {
|
|
12973
|
+
const response = await this.httpPatch(`/developer/agents/${this.agentId}/custom-data/${collectionName}/${entryId}`, mutation, {
|
|
12974
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
12975
|
+
});
|
|
12976
|
+
if (response.success && response.data) {
|
|
12977
|
+
return response.data;
|
|
12978
|
+
}
|
|
12979
|
+
throw new Error(response.error?.message || "Failed to patch custom data entry");
|
|
12980
|
+
}
|
|
12808
12981
|
/**
|
|
12809
12982
|
* Performs semantic search on custom data entries using text similarity
|
|
12810
12983
|
* @param collectionName - The name of the collection to search within
|
|
@@ -13261,8 +13434,10 @@ var init_developer_api_service = __esm({
|
|
|
13261
13434
|
* @param email - The email address to look up
|
|
13262
13435
|
* @returns Promise resolving to an ApiResponse containing the profile, or null if not found
|
|
13263
13436
|
*/
|
|
13264
|
-
async getUserProfileByEmail(email) {
|
|
13265
|
-
|
|
13437
|
+
async getUserProfileByEmail(email, agentId) {
|
|
13438
|
+
const path18 = `/developer/user/profile/email/${encodeURIComponent(email)}`;
|
|
13439
|
+
const scopedPath = agentId ? `${path18}?agentId=${encodeURIComponent(agentId)}` : path18;
|
|
13440
|
+
return this.httpGet(scopedPath, {
|
|
13266
13441
|
Authorization: `Bearer ${this.apiKey}`
|
|
13267
13442
|
});
|
|
13268
13443
|
}
|
|
@@ -13271,9 +13446,11 @@ var init_developer_api_service = __esm({
|
|
|
13271
13446
|
* @param phone - The phone number to look up (with or without + prefix)
|
|
13272
13447
|
* @returns Promise resolving to an ApiResponse containing the profile, or null if not found
|
|
13273
13448
|
*/
|
|
13274
|
-
async getUserProfileByPhone(phone) {
|
|
13449
|
+
async getUserProfileByPhone(phone, agentId) {
|
|
13275
13450
|
const normalizedPhone = phone.replace(/^\+/, "");
|
|
13276
|
-
|
|
13451
|
+
const path18 = `/developer/user/profile/phone/${normalizedPhone}`;
|
|
13452
|
+
const scopedPath = agentId ? `${path18}?agentId=${encodeURIComponent(agentId)}` : path18;
|
|
13453
|
+
return this.httpGet(scopedPath, {
|
|
13277
13454
|
Authorization: `Bearer ${this.apiKey}`
|
|
13278
13455
|
});
|
|
13279
13456
|
}
|
|
@@ -13813,22 +13990,28 @@ var init_user_data_api_service = __esm({
|
|
|
13813
13990
|
init_http_client();
|
|
13814
13991
|
init_user_instance();
|
|
13815
13992
|
init_lazy_instances();
|
|
13816
|
-
UserDataApi = class extends HttpClient {
|
|
13993
|
+
UserDataApi = class _UserDataApi extends HttpClient {
|
|
13817
13994
|
static {
|
|
13818
13995
|
__name(this, "UserDataApi");
|
|
13819
13996
|
}
|
|
13820
13997
|
apiKey;
|
|
13821
13998
|
agentId;
|
|
13999
|
+
targetUserId;
|
|
13822
14000
|
/**
|
|
13823
14001
|
* Creates an instance of UserDataApi
|
|
13824
14002
|
* @param baseUrl - The base URL for the API
|
|
13825
14003
|
* @param apiKey - The API key for authentication
|
|
13826
14004
|
* @param agentId - The unique identifier of the agent
|
|
13827
14005
|
*/
|
|
13828
|
-
constructor(baseUrl, apiKey, agentId) {
|
|
14006
|
+
constructor(baseUrl, apiKey, agentId, targetUserId) {
|
|
13829
14007
|
super(baseUrl);
|
|
13830
14008
|
this.apiKey = apiKey;
|
|
13831
14009
|
this.agentId = agentId;
|
|
14010
|
+
this.targetUserId = targetUserId;
|
|
14011
|
+
}
|
|
14012
|
+
get dataPath() {
|
|
14013
|
+
const base = `/developer/user/data/agent/${this.agentId}`;
|
|
14014
|
+
return this.targetUserId ? `${base}/user/${encodeURIComponent(this.targetUserId)}` : base;
|
|
13832
14015
|
}
|
|
13833
14016
|
/**
|
|
13834
14017
|
* Retrieves user data by userId, email, or phone.
|
|
@@ -13847,7 +14030,7 @@ var init_user_data_api_service = __esm({
|
|
|
13847
14030
|
}
|
|
13848
14031
|
let url = `/developer/user/data/agent/${this.agentId}`;
|
|
13849
14032
|
if (userId) {
|
|
13850
|
-
url += `/user/${userId}`;
|
|
14033
|
+
url += `/user/${encodeURIComponent(userId)}`;
|
|
13851
14034
|
}
|
|
13852
14035
|
const response = await this.httpGet(url, {
|
|
13853
14036
|
Authorization: `Bearer ${this.apiKey}`
|
|
@@ -13857,7 +14040,8 @@ var init_user_data_api_service = __esm({
|
|
|
13857
14040
|
}
|
|
13858
14041
|
const profile = response.data?._luaProfile;
|
|
13859
14042
|
const { _luaProfile, ...data } = response.data || {};
|
|
13860
|
-
|
|
14043
|
+
const scopedApi = userId ? new _UserDataApi(this.baseUrl, this.apiKey, this.agentId, userId) : this;
|
|
14044
|
+
return new UserDataInstance(scopedApi, data, profile);
|
|
13861
14045
|
}
|
|
13862
14046
|
/**
|
|
13863
14047
|
* Resolves email or phone to user profile via DeveloperApi
|
|
@@ -13868,11 +14052,11 @@ var init_user_data_api_service = __esm({
|
|
|
13868
14052
|
try {
|
|
13869
14053
|
const developerApi = await getDeveloperInstance();
|
|
13870
14054
|
if (options.email) {
|
|
13871
|
-
const response = await developerApi.getUserProfileByEmail(options.email);
|
|
14055
|
+
const response = await developerApi.getUserProfileByEmail(options.email, this.agentId);
|
|
13872
14056
|
return response.success ? response.data ?? null : null;
|
|
13873
14057
|
}
|
|
13874
14058
|
if (options.phone) {
|
|
13875
|
-
const response = await developerApi.getUserProfileByPhone(options.phone);
|
|
14059
|
+
const response = await developerApi.getUserProfileByPhone(options.phone, this.agentId);
|
|
13876
14060
|
return response.success ? response.data ?? null : null;
|
|
13877
14061
|
}
|
|
13878
14062
|
} catch (error) {
|
|
@@ -13890,7 +14074,7 @@ var init_user_data_api_service = __esm({
|
|
|
13890
14074
|
* @throws Error if the update fails or the request is unsuccessful
|
|
13891
14075
|
*/
|
|
13892
14076
|
async update(data) {
|
|
13893
|
-
const response = await this.httpPut(
|
|
14077
|
+
const response = await this.httpPut(this.dataPath, data, {
|
|
13894
14078
|
Authorization: `Bearer ${this.apiKey}`
|
|
13895
14079
|
});
|
|
13896
14080
|
if (!response.success) {
|
|
@@ -13899,13 +14083,23 @@ var init_user_data_api_service = __esm({
|
|
|
13899
14083
|
const { _luaProfile, ...cleanData } = response.data || {};
|
|
13900
14084
|
return cleanData;
|
|
13901
14085
|
}
|
|
14086
|
+
async patch(mutation) {
|
|
14087
|
+
const response = await this.httpPatch(this.dataPath, mutation, {
|
|
14088
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
14089
|
+
});
|
|
14090
|
+
if (!response.success) {
|
|
14091
|
+
throw new Error(response.error?.message || "Failed to patch user data");
|
|
14092
|
+
}
|
|
14093
|
+
const { _luaProfile, ...cleanData } = response.data || {};
|
|
14094
|
+
return cleanData;
|
|
14095
|
+
}
|
|
13902
14096
|
/**
|
|
13903
14097
|
* Clears all user data for the current user and specific agent
|
|
13904
14098
|
* @returns Promise resolving to an empty object upon successful deletion
|
|
13905
14099
|
* @throws Error if the clear operation fails or the request is unsuccessful
|
|
13906
14100
|
*/
|
|
13907
14101
|
async clear() {
|
|
13908
|
-
const response = await this.httpDelete(
|
|
14102
|
+
const response = await this.httpDelete(this.dataPath, {
|
|
13909
14103
|
Authorization: `Bearer ${this.apiKey}`
|
|
13910
14104
|
});
|
|
13911
14105
|
if (!response.success) {
|
|
@@ -14898,7 +15092,7 @@ export const governance = {
|
|
|
14898
15092
|
}
|
|
14899
15093
|
if (setup.requireApproval && setup.requireApproval.length > 0) {
|
|
14900
15094
|
const list = setup.requireApproval.map((t) => `'${t}'`).join(", ");
|
|
14901
|
-
ruleLines.push(`
|
|
15095
|
+
ruleLines.push(` requireToolApproval: [${list}],`);
|
|
14902
15096
|
}
|
|
14903
15097
|
if (setup.tokenLimit && setup.tokenLimit > 0) {
|
|
14904
15098
|
ruleLines.push(` tokenBudget: ${setup.tokenLimit},`);
|
|
@@ -19809,6 +20003,15 @@ var DeviceTriggerApi = class extends HttpClient {
|
|
|
19809
20003
|
|
|
19810
20004
|
// src/primitives/device-trigger.handler.ts
|
|
19811
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
|
|
19812
20015
|
var DeviceTriggerHandler = class extends BaseVersionedHandler {
|
|
19813
20016
|
static {
|
|
19814
20017
|
__name(this, "DeviceTriggerHandler");
|
|
@@ -19848,10 +20051,10 @@ var DeviceTriggerHandler = class extends BaseVersionedHandler {
|
|
|
19848
20051
|
}
|
|
19849
20052
|
async fetchFromServer(api) {
|
|
19850
20053
|
const response = await api.getDeviceTriggers();
|
|
19851
|
-
if (!response.success
|
|
20054
|
+
if (!response.success) {
|
|
19852
20055
|
return null;
|
|
19853
20056
|
}
|
|
19854
|
-
return response.data
|
|
20057
|
+
return parseDeviceTriggerList(response.data);
|
|
19855
20058
|
}
|
|
19856
20059
|
async createOnServer(api, primitive) {
|
|
19857
20060
|
const response = await api.createDeviceTrigger({
|
|
@@ -29634,13 +29837,47 @@ init_cli();
|
|
|
29634
29837
|
init_command_utils();
|
|
29635
29838
|
init_analytics();
|
|
29636
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
|
|
29637
29873
|
async function adminCommand() {
|
|
29638
29874
|
return withErrorHandling(async () => {
|
|
29639
29875
|
writeProgress("Opening Lua Admin Dashboard...");
|
|
29640
29876
|
const { agentId, orgId, apiKey } = await initializeCommand({
|
|
29641
29877
|
showProgress: false
|
|
29642
29878
|
});
|
|
29643
|
-
const
|
|
29879
|
+
const handoffCode = await issueAdminHandoff(apiKey);
|
|
29880
|
+
const adminUrl = buildAdminHandoffUrl(handoffCode, agentId, orgId);
|
|
29644
29881
|
await open(adminUrl);
|
|
29645
29882
|
writeSuccess("Lua Admin Dashboard opened in your browser");
|
|
29646
29883
|
console.log(`
|
|
@@ -29695,10 +29932,10 @@ async function docsCommand() {
|
|
|
29695
29932
|
__name(docsCommand, "docsCommand");
|
|
29696
29933
|
|
|
29697
29934
|
// src/commands/channels.ts
|
|
29698
|
-
init_cli();
|
|
29699
|
-
init_command_utils();
|
|
29700
29935
|
import inquirer12 from "inquirer";
|
|
29701
29936
|
import open4 from "open";
|
|
29937
|
+
init_cli();
|
|
29938
|
+
init_command_utils();
|
|
29702
29939
|
|
|
29703
29940
|
// src/api/channels.api.service.ts
|
|
29704
29941
|
init_http_client();
|
|
@@ -30266,7 +30503,8 @@ async function openAdminDashboard(apiKey, config) {
|
|
|
30266
30503
|
if (!orgId) {
|
|
30267
30504
|
throw new Error("No orgId found in lua.skill.yaml. Please ensure your configuration is valid.");
|
|
30268
30505
|
}
|
|
30269
|
-
const
|
|
30506
|
+
const handoffCode = await issueAdminHandoff(apiKey);
|
|
30507
|
+
const adminUrl = buildAdminHandoffUrl(handoffCode, agentId, orgId);
|
|
30270
30508
|
await open4(adminUrl);
|
|
30271
30509
|
writeSuccess("\u2705 Lua Admin Dashboard opened in your browser");
|
|
30272
30510
|
console.log(`
|
|
@@ -40625,6 +40863,7 @@ __name(deleteServerInteractive, "deleteServerInteractive");
|
|
|
40625
40863
|
init_cli();
|
|
40626
40864
|
init_constants();
|
|
40627
40865
|
import http from "http";
|
|
40866
|
+
import { randomBytes } from "crypto";
|
|
40628
40867
|
import { URL as URL2 } from "url";
|
|
40629
40868
|
import open5 from "open";
|
|
40630
40869
|
init_command_utils();
|
|
@@ -40666,18 +40905,14 @@ var UnifiedToApi = class extends HttpClient {
|
|
|
40666
40905
|
async getAuthUrl(integrationType, options) {
|
|
40667
40906
|
const params = new URLSearchParams();
|
|
40668
40907
|
params.append("integrationType", integrationType);
|
|
40908
|
+
params.append("agentId", options.agentId);
|
|
40669
40909
|
params.append("successRedirect", options.successRedirect);
|
|
40670
40910
|
params.append("failureRedirect", options.failureRedirect);
|
|
40671
40911
|
if (options.scopes && options.scopes.length > 0) {
|
|
40672
40912
|
params.append("scopes", options.scopes.join(","));
|
|
40673
40913
|
}
|
|
40674
|
-
|
|
40675
|
-
|
|
40676
|
-
}
|
|
40677
|
-
if (options.externalXref) {
|
|
40678
|
-
params.append("externalXref", options.externalXref);
|
|
40679
|
-
}
|
|
40680
|
-
return this.httpGet(`/developer/unifiedto/auth-url?${params.toString()}`, {
|
|
40914
|
+
params.append("state", options.state);
|
|
40915
|
+
return this.httpGet(`/developer/unifiedto/auth-url/v2?${params.toString()}`, {
|
|
40681
40916
|
Authorization: `Bearer ${this.apiKey}`
|
|
40682
40917
|
});
|
|
40683
40918
|
}
|
|
@@ -40823,7 +41058,8 @@ var UnifiedToApi = class extends HttpClient {
|
|
|
40823
41058
|
// src/commands/integrations.ts
|
|
40824
41059
|
init_analytics();
|
|
40825
41060
|
var CALLBACK_PORT = 19837;
|
|
40826
|
-
var
|
|
41061
|
+
var CALLBACK_HOST = "127.0.0.1";
|
|
41062
|
+
var CALLBACK_URL = `http://${CALLBACK_HOST}:${CALLBACK_PORT}/callback`;
|
|
40827
41063
|
var AGENT_WEBHOOK_URL = `${BASE_URLS.API}/webhook/unifiedto/data`;
|
|
40828
41064
|
var DEFAULT_VIRTUAL_WEBHOOK_INTERVAL = 1;
|
|
40829
41065
|
async function fetchAvailableIntegrations(unifiedToApi, agentId) {
|
|
@@ -40842,22 +41078,50 @@ async function fetchAvailableIntegrations(unifiedToApi, agentId) {
|
|
|
40842
41078
|
}));
|
|
40843
41079
|
}
|
|
40844
41080
|
__name(fetchAvailableIntegrations, "fetchAvailableIntegrations");
|
|
40845
|
-
function
|
|
41081
|
+
function createOAuthState() {
|
|
41082
|
+
return randomBytes(32).toString("base64url");
|
|
41083
|
+
}
|
|
41084
|
+
__name(createOAuthState, "createOAuthState");
|
|
41085
|
+
function escapeHtml(value) {
|
|
41086
|
+
return value.replace(/[&<>"']/g, (character) => {
|
|
41087
|
+
const escaped = {
|
|
41088
|
+
"&": "&",
|
|
41089
|
+
"<": "<",
|
|
41090
|
+
">": ">",
|
|
41091
|
+
'"': """,
|
|
41092
|
+
"'": "'"
|
|
41093
|
+
};
|
|
41094
|
+
return escaped[character];
|
|
41095
|
+
});
|
|
41096
|
+
}
|
|
41097
|
+
__name(escapeHtml, "escapeHtml");
|
|
41098
|
+
function startCallbackServer(expectedState, timeoutMs = 3e5) {
|
|
40846
41099
|
return new Promise((resolve6) => {
|
|
40847
41100
|
let resolved = false;
|
|
40848
41101
|
const server = http.createServer((req, res) => {
|
|
40849
41102
|
if (resolved) return;
|
|
40850
41103
|
const reqUrl = new URL2(req.url || "/", `http://localhost:${CALLBACK_PORT}`);
|
|
40851
41104
|
if (reqUrl.pathname === "/callback") {
|
|
41105
|
+
const returnedState = reqUrl.searchParams.get("state");
|
|
41106
|
+
if (returnedState !== expectedState) {
|
|
41107
|
+
res.writeHead(400, {
|
|
41108
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
41109
|
+
"Cache-Control": "no-store",
|
|
41110
|
+
"X-Content-Type-Options": "nosniff"
|
|
41111
|
+
});
|
|
41112
|
+
res.end("Invalid OAuth state");
|
|
41113
|
+
return;
|
|
41114
|
+
}
|
|
40852
41115
|
const connectionId = reqUrl.searchParams.get("id");
|
|
40853
41116
|
const error = reqUrl.searchParams.get("error");
|
|
40854
41117
|
const logId = reqUrl.searchParams.get("log_id");
|
|
40855
41118
|
const integrationType = reqUrl.searchParams.get("type");
|
|
40856
41119
|
resolved = true;
|
|
40857
41120
|
if (error) {
|
|
40858
|
-
const logIdHtml = logId ? `<p style="color: #888; font-size: 0.85em;">Log ID: <code>${logId}</code></p>` : "";
|
|
41121
|
+
const logIdHtml = logId ? `<p style="color: #888; font-size: 0.85em;">Log ID: <code>${escapeHtml(logId)}</code></p>` : "";
|
|
40859
41122
|
res.writeHead(200, {
|
|
40860
|
-
"Content-Type": "text/html"
|
|
41123
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
41124
|
+
"Cache-Control": "no-store"
|
|
40861
41125
|
});
|
|
40862
41126
|
res.end(`
|
|
40863
41127
|
<!DOCTYPE html>
|
|
@@ -40866,7 +41130,7 @@ function startCallbackServer(timeoutMs = 3e5) {
|
|
|
40866
41130
|
<body style="font-family: system-ui; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #1a1a2e;">
|
|
40867
41131
|
<div style="text-align: center; color: white; max-width: 500px; padding: 0 20px;">
|
|
40868
41132
|
<h1 style="color: #ff6b6b;">Connection Failed</h1>
|
|
40869
|
-
<p style="color: #ccc;">
|
|
41133
|
+
<p style="color: #ccc;">Authentication failed. Return to the terminal for details.</p>
|
|
40870
41134
|
${logIdHtml}
|
|
40871
41135
|
<p style="color: #888;">You can close this window and try again.</p>
|
|
40872
41136
|
</div>
|
|
@@ -40881,7 +41145,8 @@ function startCallbackServer(timeoutMs = 3e5) {
|
|
|
40881
41145
|
});
|
|
40882
41146
|
} else if (connectionId) {
|
|
40883
41147
|
res.writeHead(200, {
|
|
40884
|
-
"Content-Type": "text/html"
|
|
41148
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
41149
|
+
"Cache-Control": "no-store"
|
|
40885
41150
|
});
|
|
40886
41151
|
res.end(`
|
|
40887
41152
|
<!DOCTYPE html>
|
|
@@ -40915,7 +41180,7 @@ function startCallbackServer(timeoutMs = 3e5) {
|
|
|
40915
41180
|
res.end("Not found");
|
|
40916
41181
|
}
|
|
40917
41182
|
});
|
|
40918
|
-
server.listen(CALLBACK_PORT, () => {
|
|
41183
|
+
server.listen(CALLBACK_PORT, CALLBACK_HOST, () => {
|
|
40919
41184
|
});
|
|
40920
41185
|
setTimeout(() => {
|
|
40921
41186
|
if (!resolved) {
|
|
@@ -40978,6 +41243,7 @@ async function executeNonInteractive12(context, action, cmdOptions) {
|
|
|
40978
41243
|
authMethod: cmdOptions?.authMethod,
|
|
40979
41244
|
scopes: cmdOptions?.scopes,
|
|
40980
41245
|
hideSensitive: cmdOptions?.hideSensitive === "true",
|
|
41246
|
+
accountLabel: cmdOptions?.accountLabel,
|
|
40981
41247
|
// Trigger options
|
|
40982
41248
|
triggers: cmdOptions?.triggers,
|
|
40983
41249
|
customWebhook: cmdOptions?.customWebhook === true,
|
|
@@ -41616,22 +41882,13 @@ Available triggers for ${selectedIntegration.name}:`);
|
|
|
41616
41882
|
writeInfo(`Note: Could not fetch available triggers (${error.message})`);
|
|
41617
41883
|
}
|
|
41618
41884
|
writeProgress("\u{1F504} Preparing authorization...");
|
|
41619
|
-
const state =
|
|
41620
|
-
agentId: context.agentId,
|
|
41621
|
-
integration: selectedIntegration.value,
|
|
41622
|
-
authMethod,
|
|
41623
|
-
timestamp: Date.now()
|
|
41624
|
-
})).toString("base64");
|
|
41625
|
-
const externalXref = JSON.stringify({
|
|
41626
|
-
agentId: context.agentId,
|
|
41627
|
-
userId: context.userId
|
|
41628
|
-
});
|
|
41885
|
+
const state = createOAuthState();
|
|
41629
41886
|
const authUrlResult = await context.unifiedToApi.getAuthUrl(selectedIntegration.value, {
|
|
41887
|
+
agentId: context.agentId,
|
|
41630
41888
|
successRedirect: CALLBACK_URL,
|
|
41631
41889
|
failureRedirect: CALLBACK_URL,
|
|
41632
41890
|
scopes: authMethod === "oauth" ? selectedScopes : void 0,
|
|
41633
|
-
state
|
|
41634
|
-
externalXref
|
|
41891
|
+
state
|
|
41635
41892
|
});
|
|
41636
41893
|
if (!authUrlResult.success || !authUrlResult.data) {
|
|
41637
41894
|
writeError(`\u274C Failed to get authorization URL: ${authUrlResult.error?.message || "Unknown error"}`);
|
|
@@ -41647,7 +41904,7 @@ Integration: ${selectedIntegration.name}`);
|
|
|
41647
41904
|
\u{1F4CB} Authorization URL (copy if browser doesn't open):
|
|
41648
41905
|
${authUrl}
|
|
41649
41906
|
`);
|
|
41650
|
-
const callbackPromise = startCallbackServer(3e5);
|
|
41907
|
+
const callbackPromise = startCallbackServer(state, 3e5);
|
|
41651
41908
|
try {
|
|
41652
41909
|
await open5(authUrl);
|
|
41653
41910
|
writeInfo("\u{1F310} Browser opened - please complete the authorization");
|
|
@@ -41663,7 +41920,7 @@ Integration: ${selectedIntegration.name}`);
|
|
|
41663
41920
|
triggers: selectedTriggers,
|
|
41664
41921
|
webhookUrl,
|
|
41665
41922
|
isCustomWebhook
|
|
41666
|
-
});
|
|
41923
|
+
}, options.accountLabel);
|
|
41667
41924
|
} else {
|
|
41668
41925
|
writeError(`
|
|
41669
41926
|
\u274C Authorization failed: ${result.error || "Unknown error"}`);
|
|
@@ -41686,8 +41943,22 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
|
|
|
41686
41943
|
triggers: [],
|
|
41687
41944
|
webhookUrl: "",
|
|
41688
41945
|
isCustomWebhook: false
|
|
41689
|
-
}) {
|
|
41946
|
+
}, requestedAccountLabel) {
|
|
41690
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
|
+
}
|
|
41691
41962
|
const triggers = webhookConfig.triggers.map((t) => ({
|
|
41692
41963
|
objectType: t.objectType,
|
|
41693
41964
|
event: t.event,
|
|
@@ -41697,6 +41968,7 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
|
|
|
41697
41968
|
const result = await context.unifiedToApi.finalizeConnection(context.agentId, {
|
|
41698
41969
|
connectionId,
|
|
41699
41970
|
integrationType: integration.value,
|
|
41971
|
+
displayName,
|
|
41700
41972
|
scopes: scopes.length > 0 ? scopes : void 0,
|
|
41701
41973
|
hideSensitive,
|
|
41702
41974
|
triggers: triggers.length > 0 ? triggers : void 0
|
|
@@ -42049,22 +42321,13 @@ Available scopes for ${selectedIntegration.name}:`);
|
|
|
42049
42321
|
writeError(`\u274C Failed to remove old connection: ${error.message}`);
|
|
42050
42322
|
return;
|
|
42051
42323
|
}
|
|
42052
|
-
const state =
|
|
42053
|
-
agentId: context.agentId,
|
|
42054
|
-
integration: selectedIntegration.value,
|
|
42055
|
-
authMethod: "oauth",
|
|
42056
|
-
timestamp: Date.now()
|
|
42057
|
-
})).toString("base64");
|
|
42058
|
-
const externalXref = JSON.stringify({
|
|
42059
|
-
agentId: context.agentId,
|
|
42060
|
-
userId: context.userId
|
|
42061
|
-
});
|
|
42324
|
+
const state = createOAuthState();
|
|
42062
42325
|
const authUrlResult = await context.unifiedToApi.getAuthUrl(selectedIntegration.value, {
|
|
42326
|
+
agentId: context.agentId,
|
|
42063
42327
|
successRedirect: CALLBACK_URL,
|
|
42064
42328
|
failureRedirect: CALLBACK_URL,
|
|
42065
42329
|
scopes: selectedScopes,
|
|
42066
|
-
state
|
|
42067
|
-
externalXref
|
|
42330
|
+
state
|
|
42068
42331
|
});
|
|
42069
42332
|
if (!authUrlResult.success || !authUrlResult.data) {
|
|
42070
42333
|
writeError(`\u274C Failed to get authorization URL: ${authUrlResult.error?.message || "Unknown error"}`);
|
|
@@ -42078,7 +42341,7 @@ Available scopes for ${selectedIntegration.name}:`);
|
|
|
42078
42341
|
\u{1F4CB} Authorization URL (copy if browser doesn't open):
|
|
42079
42342
|
${authUrl}
|
|
42080
42343
|
`);
|
|
42081
|
-
const callbackPromise = startCallbackServer(3e5);
|
|
42344
|
+
const callbackPromise = startCallbackServer(state, 3e5);
|
|
42082
42345
|
try {
|
|
42083
42346
|
await open5(authUrl);
|
|
42084
42347
|
writeInfo("\u{1F310} Browser opened - please complete the authorization");
|
|
@@ -42114,7 +42377,7 @@ Available scopes for ${selectedIntegration.name}:`);
|
|
|
42114
42377
|
triggers: triggersToRestore,
|
|
42115
42378
|
webhookUrl: AGENT_WEBHOOK_URL,
|
|
42116
42379
|
isCustomWebhook: hasCustomWebhook
|
|
42117
|
-
});
|
|
42380
|
+
}, options.accountLabel);
|
|
42118
42381
|
if (triggersToRestore.length > 0) {
|
|
42119
42382
|
writeSuccess(`Restored ${triggersToRestore.length} trigger(s) from previous connection`);
|
|
42120
42383
|
}
|
|
@@ -46377,7 +46640,7 @@ Examples:
|
|
|
46377
46640
|
$ lua mcp deactivate --server-name api-server Deactivate a server
|
|
46378
46641
|
$ lua mcp delete --server-name old-server Delete a server
|
|
46379
46642
|
`).action(mcpCommand);
|
|
46380
|
-
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", `
|
|
46381
46644
|
Arguments:
|
|
46382
46645
|
action Optional: 'connect', 'update', 'list', 'available', 'info', 'disconnect', 'webhooks'
|
|
46383
46646
|
(alias: 'triggers'), or 'mcp'
|