lua-cli 3.18.0 → 3.21.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
@@ -8,8 +8,13 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
8
8
  if (typeof require !== "undefined") return require.apply(this, arguments);
9
9
  throw Error('Dynamic require of "' + x + '" is not supported');
10
10
  });
11
- var __esm = (fn, res) => function __init() {
12
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
+ var __esm = (fn, res, err) => function __init() {
12
+ if (err) throw err[0];
13
+ try {
14
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
15
+ } catch (e) {
16
+ throw err = [e], e;
17
+ }
13
18
  };
14
19
  var __export = (target, all) => {
15
20
  for (var name in all)
@@ -868,6 +873,15 @@ function aiGenerateInputFromSimplified(prompt, content) {
868
873
  ]
869
874
  };
870
875
  }
876
+ function isAllowedReviewableExecuteTool(tool) {
877
+ return REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST.includes(tool);
878
+ }
879
+ function isReviewableMcpSendTool(tool) {
880
+ return tool.length > REVIEWABLE_MCP_SEND_TOOL_SUFFIX.length && tool.endsWith(REVIEWABLE_MCP_SEND_TOOL_SUFFIX);
881
+ }
882
+ function isReviewableExecuteTool(tool) {
883
+ return isAllowedReviewableExecuteTool(tool) || isReviewableMcpSendTool(tool);
884
+ }
871
885
  function isInteractiveChannel(channel) {
872
886
  if (!channel) return true;
873
887
  return !NON_INTERACTIVE_CHANNELS.includes(channel);
@@ -883,6 +897,85 @@ function transformChatHistoryContentParts(parts) {
883
897
  const content = [];
884
898
  for (const rawPart of parts ?? []) {
885
899
  const part = rawPart;
900
+ if (part?.type === "reasoning") {
901
+ const detailsText = Array.isArray(part.details) ? part.details.filter((d) => d?.type === "text" && typeof d.text === "string").map((d) => d.text).join("") : "";
902
+ const reasoningText = [
903
+ part.reasoning,
904
+ detailsText,
905
+ part.text
906
+ ].find((v) => typeof v === "string" && v.trim().length > 0) ?? "";
907
+ if (reasoningText) content.push({
908
+ type: "reasoning",
909
+ text: reasoningText
910
+ });
911
+ continue;
912
+ }
913
+ if (part?.type === "tool-invocation") {
914
+ const inv = part.toolInvocation;
915
+ if (typeof inv?.toolName === "string" && inv.toolName.length > 0) {
916
+ content.push({
917
+ type: "tool",
918
+ toolName: inv.toolName,
919
+ toolCallId: inv.toolCallId,
920
+ input: inv.args,
921
+ output: inv.result,
922
+ toolState: inv.state
923
+ });
924
+ }
925
+ continue;
926
+ }
927
+ if (part?.type === "source") {
928
+ const src = part.source;
929
+ if (src?.sourceType === "document") {
930
+ content.push({
931
+ type: "source-document",
932
+ sourceId: src.id,
933
+ mediaType: src.mediaType,
934
+ title: src.title,
935
+ filename: src.filename,
936
+ providerMetadata: src.providerMetadata
937
+ });
938
+ } else if (typeof src?.url === "string" && src.url.length > 0) {
939
+ content.push({
940
+ type: "source-url",
941
+ sourceId: src.id,
942
+ url: src.url,
943
+ title: src.title,
944
+ providerMetadata: src.providerMetadata
945
+ });
946
+ }
947
+ continue;
948
+ }
949
+ if (part?.type === "source-url") {
950
+ if (typeof part.url === "string" && part.url.length > 0) {
951
+ content.push({
952
+ type: "source-url",
953
+ sourceId: part.sourceId,
954
+ url: part.url,
955
+ title: part.title,
956
+ providerMetadata: part.providerMetadata
957
+ });
958
+ }
959
+ continue;
960
+ }
961
+ if (part?.type === "source-document") {
962
+ content.push({
963
+ type: "source-document",
964
+ sourceId: part.sourceId,
965
+ mediaType: part.mediaType,
966
+ title: part.title,
967
+ filename: part.filename,
968
+ providerMetadata: part.providerMetadata
969
+ });
970
+ continue;
971
+ }
972
+ if (typeof part?.type === "string" && part.type.startsWith("data-lua-")) {
973
+ content.push({
974
+ type: part.type,
975
+ payload: rawPart.data
976
+ });
977
+ continue;
978
+ }
886
979
  if (part?.type !== "text" && part?.type !== "file") continue;
887
980
  if (part.type === "text" && typeof part.text === "string") {
888
981
  const rawText = part.text || "";
@@ -940,10 +1033,92 @@ function transformChatHistoryContentParts(parts) {
940
1033
  }
941
1034
  return content;
942
1035
  }
1036
+ function isSyntheticSideRow(id) {
1037
+ return id.startsWith(SCREENSHOT_MESSAGE_ID_PREFIX) || id.startsWith(RICH_PARTS_MESSAGE_ID_PREFIX);
1038
+ }
1039
+ function mergeRichPartMirrorMessages(messages, sameTurnGroup) {
1040
+ const merged = [];
1041
+ for (const message of messages) {
1042
+ if (message.role === "assistant" && message.id.startsWith(RICH_PARTS_MESSAGE_ID_PREFIX)) {
1043
+ let folded = false;
1044
+ for (let i = merged.length - 1; i >= 0; i--) {
1045
+ const target = merged[i];
1046
+ if (sameTurnGroup && !sameTurnGroup(target, message)) continue;
1047
+ if (isSyntheticSideRow(target.id)) continue;
1048
+ if (target.role !== "assistant") break;
1049
+ const seen = /* @__PURE__ */ new Set();
1050
+ for (const part of target.content) {
1051
+ for (const key of citationDedupeKeys(part)) seen.add(key);
1052
+ }
1053
+ const incoming = [];
1054
+ for (const part of message.content) {
1055
+ const keys = citationDedupeKeys(part);
1056
+ if (keys.length > 0 && keys.some((k) => seen.has(k))) continue;
1057
+ for (const key of keys) seen.add(key);
1058
+ incoming.push(part);
1059
+ }
1060
+ merged[i] = {
1061
+ ...target,
1062
+ content: [
1063
+ ...target.content,
1064
+ ...incoming
1065
+ ]
1066
+ };
1067
+ folded = true;
1068
+ break;
1069
+ }
1070
+ if (folded) continue;
1071
+ }
1072
+ merged.push(message);
1073
+ }
1074
+ return merged;
1075
+ }
1076
+ function citationDedupeKeys(part) {
1077
+ if (part.type !== "source-url" && part.type !== "source-document") return [];
1078
+ const keys = [];
1079
+ if (typeof part.sourceId === "string" && part.sourceId.length > 0) keys.push(`id:${part.sourceId}`);
1080
+ if (typeof part.url === "string" && part.url.length > 0) keys.push(`url:${part.url}`);
1081
+ return keys;
1082
+ }
1083
+ function foldRichPartsIntoMessages(messages, records, makeMessage, sameTurnGroup) {
1084
+ if (messages.length === 0 || records.length === 0) return messages;
1085
+ const messageTime = /* @__PURE__ */ __name2((m) => m.createdAt ? new Date(m.createdAt).getTime() : Number.NEGATIVE_INFINITY, "messageTime");
1086
+ const finiteTimes = messages.map(messageTime).filter(Number.isFinite);
1087
+ const oldest = finiteTimes.length > 0 ? Math.min(...finiteTimes) : Number.NEGATIVE_INFINITY;
1088
+ const synthetic = [];
1089
+ for (const record of records) {
1090
+ const time = new Date(record.createdAt).getTime();
1091
+ if (!Number.isFinite(time) || time < oldest) continue;
1092
+ const content = transformChatHistoryContentParts(record.parts);
1093
+ if (content.length === 0) continue;
1094
+ synthetic.push({
1095
+ time,
1096
+ message: makeMessage({
1097
+ id: `${RICH_PARTS_MESSAGE_ID_PREFIX}${record.threadId}:${record.messageId}`,
1098
+ role: "assistant",
1099
+ createdAt: new Date(time).toISOString(),
1100
+ content
1101
+ }, record)
1102
+ });
1103
+ }
1104
+ if (synthetic.length === 0) return messages;
1105
+ synthetic.sort((a, b) => a.time - b.time);
1106
+ const combined = [];
1107
+ let next = 0;
1108
+ for (const message of messages) {
1109
+ const time = messageTime(message);
1110
+ while (next < synthetic.length && synthetic[next].time < time) {
1111
+ combined.push(synthetic[next++].message);
1112
+ }
1113
+ combined.push(message);
1114
+ }
1115
+ while (next < synthetic.length) combined.push(synthetic[next++].message);
1116
+ return mergeRichPartMirrorMessages(combined, sameTurnGroup);
1117
+ }
943
1118
  function buildDefaultPersona(agentName) {
944
1119
  return DEFAULT_PERSONA_GUIDE.replace(AGENT_NAME_TOKEN, () => agentName || "My Agent");
945
1120
  }
946
- var __defProp2, __name2, NON_INTERACTIVE_CHANNELS, 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;
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;
947
1122
  var init_dist = __esm({
948
1123
  "../shared-types/dist/index.mjs"() {
949
1124
  "use strict";
@@ -961,6 +1136,24 @@ var init_dist = __esm({
961
1136
  __name2(personaToLiteral, "personaToLiteral");
962
1137
  __name(aiGenerateInputFromSimplified, "aiGenerateInputFromSimplified");
963
1138
  __name2(aiGenerateInputFromSimplified, "aiGenerateInputFromSimplified");
1139
+ REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST = [
1140
+ "sendChannelMessage",
1141
+ "sendWhatsappTemplate",
1142
+ "sendEmail",
1143
+ "sendWhatsappMessage",
1144
+ "sendSms",
1145
+ "sendWebchatMessage",
1146
+ "sendTeamsMessage",
1147
+ "sendInstagramMessage",
1148
+ "sendMessengerMessage"
1149
+ ];
1150
+ __name(isAllowedReviewableExecuteTool, "isAllowedReviewableExecuteTool");
1151
+ __name2(isAllowedReviewableExecuteTool, "isAllowedReviewableExecuteTool");
1152
+ REVIEWABLE_MCP_SEND_TOOL_SUFFIX = "_create_messaging_message";
1153
+ __name(isReviewableMcpSendTool, "isReviewableMcpSendTool");
1154
+ __name2(isReviewableMcpSendTool, "isReviewableMcpSendTool");
1155
+ __name(isReviewableExecuteTool, "isReviewableExecuteTool");
1156
+ __name2(isReviewableExecuteTool, "isReviewableExecuteTool");
964
1157
  NON_INTERACTIVE_CHANNELS = [
965
1158
  "trigger",
966
1159
  "agent-invocation"
@@ -973,6 +1166,231 @@ var init_dist = __esm({
973
1166
  __name2(removeNavigateBlock, "removeNavigateBlock");
974
1167
  __name(transformChatHistoryContentParts, "transformChatHistoryContentParts");
975
1168
  __name2(transformChatHistoryContentParts, "transformChatHistoryContentParts");
1169
+ RICH_PARTS_MESSAGE_ID_PREFIX = "rich-parts:";
1170
+ SCREENSHOT_MESSAGE_ID_PREFIX = "screenshot:";
1171
+ __name(isSyntheticSideRow, "isSyntheticSideRow");
1172
+ __name2(isSyntheticSideRow, "isSyntheticSideRow");
1173
+ __name(mergeRichPartMirrorMessages, "mergeRichPartMirrorMessages");
1174
+ __name2(mergeRichPartMirrorMessages, "mergeRichPartMirrorMessages");
1175
+ __name(citationDedupeKeys, "citationDedupeKeys");
1176
+ __name2(citationDedupeKeys, "citationDedupeKeys");
1177
+ __name(foldRichPartsIntoMessages, "foldRichPartsIntoMessages");
1178
+ __name2(foldRichPartsIntoMessages, "foldRichPartsIntoMessages");
1179
+ BROWSER_COMMANDS = [
1180
+ // health + lifecycle / navigation
1181
+ {
1182
+ name: "health",
1183
+ description: "Check the local browser engine is installed and responsive."
1184
+ },
1185
+ {
1186
+ name: "session_open",
1187
+ description: "Open/attach a browser session (its own cookies/auth). Args: url?, headed?, profile?, confirmActions?."
1188
+ },
1189
+ {
1190
+ name: "navigate",
1191
+ description: "Navigate the session to a URL. Args: url, waitUntil?."
1192
+ },
1193
+ {
1194
+ name: "back",
1195
+ description: "Go back in history."
1196
+ },
1197
+ {
1198
+ name: "forward",
1199
+ description: "Go forward in history."
1200
+ },
1201
+ {
1202
+ name: "reload",
1203
+ description: "Reload the current page."
1204
+ },
1205
+ {
1206
+ name: "pushstate",
1207
+ description: "SPA client-side navigation. Args: url."
1208
+ },
1209
+ {
1210
+ name: "close",
1211
+ description: "Close the session\u2019s browser."
1212
+ },
1213
+ // perception
1214
+ {
1215
+ name: "snapshot",
1216
+ description: "Accessibility-tree snapshot with element refs (@e1\u2026) \u2014 see what to click/fill. Args: interactiveOnly?, selector?, urls?, compact?, depth?."
1217
+ },
1218
+ {
1219
+ name: "get",
1220
+ description: "Read from the page. Args: what(text|html|value|attr|title|url|count|box|styles), selector?, attr?."
1221
+ },
1222
+ {
1223
+ name: "is",
1224
+ description: "Check element state. Args: check(visible|enabled|checked), selector."
1225
+ },
1226
+ // interaction
1227
+ {
1228
+ name: "click",
1229
+ description: "Click an element. Args: selector(@eN or CSS), newTab?."
1230
+ },
1231
+ {
1232
+ name: "dblclick",
1233
+ description: "Double-click an element. Args: selector."
1234
+ },
1235
+ {
1236
+ name: "fill",
1237
+ description: "Clear and fill a field. Args: selector, text."
1238
+ },
1239
+ {
1240
+ name: "type",
1241
+ description: "Type into an element. Args: selector, text."
1242
+ },
1243
+ {
1244
+ name: "press",
1245
+ description: "Press a key/chord (Enter, Control+a). Args: key."
1246
+ },
1247
+ {
1248
+ name: "hover",
1249
+ description: "Hover an element. Args: selector."
1250
+ },
1251
+ {
1252
+ name: "focus",
1253
+ description: "Focus an element. Args: selector."
1254
+ },
1255
+ {
1256
+ name: "select",
1257
+ description: "Select a dropdown option. Args: selector, value."
1258
+ },
1259
+ {
1260
+ name: "check",
1261
+ description: "Check a checkbox. Args: selector."
1262
+ },
1263
+ {
1264
+ name: "uncheck",
1265
+ description: "Uncheck a checkbox. Args: selector."
1266
+ },
1267
+ {
1268
+ name: "scroll",
1269
+ description: "Scroll. Args: direction(up|down|left|right), px?, selector?."
1270
+ },
1271
+ {
1272
+ name: "scrollintoview",
1273
+ description: "Scroll an element into view. Args: selector."
1274
+ },
1275
+ {
1276
+ name: "drag",
1277
+ description: "Drag and drop. Args: source, target."
1278
+ },
1279
+ {
1280
+ name: "upload",
1281
+ description: "Upload local file(s) to a file input. Args: selector, files[]."
1282
+ },
1283
+ {
1284
+ name: "find",
1285
+ description: "Act by semantic locator. Args: by(role|text|label|placeholder|alt|title|testid), query, action(click|fill|type|hover|focus|check|uncheck|text), value?, name?, exact?."
1286
+ },
1287
+ // AI fallbacks
1288
+ {
1289
+ name: "act",
1290
+ description: "Act on the page: ref+action (deterministic) or natural-language instruction (engine AI). Args: ref?, action?, value?, instruction?."
1291
+ },
1292
+ {
1293
+ name: "extract",
1294
+ description: "Extract data by natural-language instruction (engine AI). Args: instruction."
1295
+ },
1296
+ // wait
1297
+ {
1298
+ name: "wait",
1299
+ description: "Wait for a condition. Provide one of: selector(+state), ms, text, url, load, fn."
1300
+ },
1301
+ // tabs / frames
1302
+ {
1303
+ name: "tab",
1304
+ description: "Manage tabs. Args: action(list|new|switch|close), target?, url?, label?."
1305
+ },
1306
+ {
1307
+ name: "window_new",
1308
+ description: "Open a new browser window. Args: url?."
1309
+ },
1310
+ {
1311
+ name: "frame",
1312
+ description: 'Switch frame context. Args: target(@eN | CSS | "main").'
1313
+ },
1314
+ // capture
1315
+ {
1316
+ name: "screenshot",
1317
+ description: "Screenshot the page. Args: fullPage?, path?."
1318
+ },
1319
+ {
1320
+ name: "pdf",
1321
+ description: "Save the page as PDF. Args: path."
1322
+ },
1323
+ // state
1324
+ {
1325
+ name: "cookies",
1326
+ description: "Manage cookies. Args: action(get|set|clear), name?, value?."
1327
+ },
1328
+ {
1329
+ name: "storage",
1330
+ description: "Manage web storage. Args: area(local|session), action(get|set|clear), key?, value?."
1331
+ },
1332
+ {
1333
+ name: "set",
1334
+ description: "Configure the browser. Args: setting(viewport|device|geo|headers|credentials|media), args[]."
1335
+ },
1336
+ // files / clipboard
1337
+ {
1338
+ name: "download",
1339
+ description: "Download a file (click a selector to trigger, or wait for one). Args: selector?, path?."
1340
+ },
1341
+ {
1342
+ name: "clipboard",
1343
+ description: "Clipboard. Args: action(read|write|copy|paste), text?."
1344
+ },
1345
+ // auth (use-only)
1346
+ {
1347
+ name: "auth",
1348
+ description: "Use a saved login profile. Args: action(login|list|show), name?. (Credentials are saved via the desktop, never the agent.)"
1349
+ },
1350
+ // confirmation gate
1351
+ {
1352
+ name: "confirm",
1353
+ description: "Approve a pending confirmation_required action. Args: id."
1354
+ },
1355
+ {
1356
+ name: "deny",
1357
+ description: "Reject a pending confirmation_required action. Args: id."
1358
+ },
1359
+ // network / debug / input / state-files
1360
+ {
1361
+ name: "network",
1362
+ description: "Inspect/control network. Args: action(route|unroute|requests|har) + relevant fields."
1363
+ },
1364
+ {
1365
+ name: "console",
1366
+ description: "View browser console messages. Args: clear?."
1367
+ },
1368
+ {
1369
+ name: "errors",
1370
+ description: "View uncaught page JS errors. Args: clear?."
1371
+ },
1372
+ {
1373
+ name: "mouse",
1374
+ description: "Low-level mouse. Args: action(move|down|up|wheel), x?, y?, button?, dy?, dx?."
1375
+ },
1376
+ {
1377
+ name: "keyboard",
1378
+ description: "Low-level keyboard at focus. Args: action(type|inserttext|keydown|keyup), text?, key?."
1379
+ },
1380
+ {
1381
+ name: "state",
1382
+ description: "Persist/restore storage+auth state to a file. Args: action(save|load|list|clear), path?."
1383
+ }
1384
+ ];
1385
+ BROWSER_COMMAND_NAMES = BROWSER_COMMANDS.map((c) => c.name);
1386
+ REASONING_EFFORT_VALUES = [
1387
+ "off",
1388
+ "minimal",
1389
+ "low",
1390
+ "medium",
1391
+ "high",
1392
+ "max"
1393
+ ];
976
1394
  AGENT_NAME_TOKEN = "[Your Agent Name]";
977
1395
  DEFAULT_PERSONA_GUIDE = `# ${AGENT_NAME_TOKEN} - Persona
978
1396
 
@@ -1036,7 +1454,8 @@ Feel free to add, remove, or rename sections. Your persona can be a single parag
1036
1454
  "mcp",
1037
1455
  "rag",
1038
1456
  "device",
1039
- "device-trigger"
1457
+ "device-trigger",
1458
+ "model-resolver"
1040
1459
  ];
1041
1460
  VoiceNameSchema = z.string().regex(/^[a-zA-Z0-9_-]+$/, "Voice name must contain only alphanumeric characters, underscores, or hyphens").min(1).max(64);
1042
1461
  PluginProviderSchema = z.enum([
@@ -2542,7 +2961,8 @@ var init_skill_handler = __esm({
2542
2961
  const response = await api.publishSkillVersion(entityId, version);
2543
2962
  return {
2544
2963
  success: response.success,
2545
- error: response.error?.message
2964
+ error: response.error?.message,
2965
+ agentVersion: response.data?.agentVersion
2546
2966
  };
2547
2967
  }
2548
2968
  prepareForPush(manifest, name, projectPath = process.cwd(), bundleAccumulator) {
@@ -6896,6 +7316,18 @@ var init_skill_plugin = __esm({
6896
7316
 
6897
7317
  // src/compiler/plugins/agent.plugin.ts
6898
7318
  import { Node as Node13 } from "ts-morph";
7319
+ function shapeReasoningSetting(value) {
7320
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
7321
+ const raw = value;
7322
+ const result = {};
7323
+ if (typeof raw.effort === "string" && REASONING_EFFORT_VALUES.includes(raw.effort)) {
7324
+ result.effort = raw.effort;
7325
+ }
7326
+ if (typeof raw.show === "boolean") {
7327
+ result.show = raw.show;
7328
+ }
7329
+ return Object.keys(result).length > 0 ? result : void 0;
7330
+ }
6899
7331
  function shapeModelSettings(raw) {
6900
7332
  const KNOWN_KEYS = [
6901
7333
  "temperature",
@@ -6905,7 +7337,8 @@ function shapeModelSettings(raw) {
6905
7337
  "presencePenalty",
6906
7338
  "frequencyPenalty",
6907
7339
  "stopSequences",
6908
- "seed"
7340
+ "seed",
7341
+ "reasoning"
6909
7342
  ];
6910
7343
  const result = {};
6911
7344
  for (const key of KNOWN_KEYS) {
@@ -6915,6 +7348,9 @@ function shapeModelSettings(raw) {
6915
7348
  if (Array.isArray(value) && value.every((v) => typeof v === "string")) {
6916
7349
  result[key] = value;
6917
7350
  }
7351
+ } else if (key === "reasoning") {
7352
+ const shaped = shapeReasoningSetting(value);
7353
+ if (shaped) result[key] = shaped;
6918
7354
  } else if (typeof value === "number" && Number.isFinite(value)) {
6919
7355
  result[key] = value;
6920
7356
  }
@@ -6954,7 +7390,8 @@ var init_agent_plugin = __esm({
6954
7390
  "description",
6955
7391
  "persona",
6956
7392
  "model",
6957
- "modelSettings"
7393
+ "modelSettings",
7394
+ "browser"
6958
7395
  ]
6959
7396
  };
6960
7397
  supportsClassDefinition = true;
@@ -7011,6 +7448,8 @@ var init_agent_plugin = __esm({
7011
7448
  const governanceHit = findClassMember(classDecl, "governance", "property");
7012
7449
  const governanceObj = governanceHit && Node13.isPropertyDeclaration(governanceHit.node) ? evaluateNodeAsObject(governanceHit.node.getInitializer()) : void 0;
7013
7450
  const governance = governanceObj && typeof governanceObj.mode === "string" ? governanceObj : void 0;
7451
+ const browserHit = findClassMember(classDecl, "browser", "property");
7452
+ const browser = browserHit && Node13.isPropertyDeclaration(browserHit.node) ? this.shapeBrowserNode(browserHit.node.getInitializer()) : void 0;
7014
7453
  const modelSettingsHit = findClassMember(classDecl, "modelSettings", "property");
7015
7454
  const modelSettingsObj = modelSettingsHit && Node13.isPropertyDeclaration(modelSettingsHit.node) ? evaluateNodeAsObject(modelSettingsHit.node.getInitializer()) : void 0;
7016
7455
  const modelSettings = modelSettingsObj ? shapeModelSettings(modelSettingsObj) : void 0;
@@ -7030,7 +7469,8 @@ var init_agent_plugin = __esm({
7030
7469
  hasModelResolver,
7031
7470
  modelSettings,
7032
7471
  batching,
7033
- governance
7472
+ governance,
7473
+ browser
7034
7474
  }
7035
7475
  };
7036
7476
  }
@@ -7061,6 +7501,7 @@ var init_agent_plugin = __esm({
7061
7501
  const modelSettings = this.extractModelSettings(config);
7062
7502
  const batching = this.extractBatchingInfo(config);
7063
7503
  const governance = this.extractGovernanceInfo(config);
7504
+ const browser = this.extractBrowserInfo(config);
7064
7505
  const { voiceRefNames, voiceRefSourcePaths } = this.extractVoiceRefs(config);
7065
7506
  return {
7066
7507
  kind: this.kind,
@@ -7078,12 +7519,34 @@ var init_agent_plugin = __esm({
7078
7519
  modelSettings,
7079
7520
  batching,
7080
7521
  governance,
7522
+ browser,
7081
7523
  voiceRefNames,
7082
7524
  voiceRefSourcePaths
7083
7525
  }
7084
7526
  };
7085
7527
  }
7086
7528
  /**
7529
+ * Extract the `browser` switch (LuaBrowser). `true` → true; an object → its
7530
+ * evaluated shape; `false`/absent → undefined (off by default).
7531
+ */
7532
+ extractBrowserInfo(config) {
7533
+ const prop = config.getProperty("browser");
7534
+ if (!prop || !Node13.isPropertyAssignment(prop)) return void 0;
7535
+ return this.shapeBrowserNode(prop.getInitializer());
7536
+ }
7537
+ /**
7538
+ * Normalize a `browser` initializer (config-literal or class-member) to the
7539
+ * switch value: `true` → true; `false`/absent → undefined; an object → its
7540
+ * evaluated shape. A resolution failure leaves the switch OFF (undefined) —
7541
+ * mirroring `governance`, never silently "enabled with default policy".
7542
+ */
7543
+ shapeBrowserNode(init) {
7544
+ if (!init) return void 0;
7545
+ const obj = evaluateNodeAsObject(init);
7546
+ if (obj) return obj;
7547
+ return evaluateNodeAsBoolean(init) === true ? true : void 0;
7548
+ }
7549
+ /**
7087
7550
  * Read the `voices` array property and return both the identifiers and
7088
7551
  * the resolver-discovered source file for each.
7089
7552
  *
@@ -7241,6 +7704,7 @@ var init_agent_plugin = __esm({
7241
7704
  modelSettings: agentMeta.modelSettings,
7242
7705
  batching: agentMeta.batching,
7243
7706
  governance: agentMeta.governance,
7707
+ browser: agentMeta.browser,
7244
7708
  voiceRefs
7245
7709
  };
7246
7710
  }
@@ -7300,6 +7764,7 @@ var init_agent_plugin = __esm({
7300
7764
  return rest;
7301
7765
  }
7302
7766
  };
7767
+ __name(shapeReasoningSetting, "shapeReasoningSetting");
7303
7768
  __name(shapeModelSettings, "shapeModelSettings");
7304
7769
  agentPlugin = new AgentPlugin();
7305
7770
  }
@@ -12384,6 +12849,9 @@ var init_agents_api_service = __esm({
12384
12849
  } : {},
12385
12850
  ...body.webhookPayload !== void 0 ? {
12386
12851
  webhookPayload: body.webhookPayload
12852
+ } : {},
12853
+ ...body.clientContext !== void 0 ? {
12854
+ clientContext: body.clientContext
12387
12855
  } : {}
12388
12856
  };
12389
12857
  }
@@ -12835,6 +13303,12 @@ var init_channels_send_api_service = __esm({
12835
13303
  Authorization: `Bearer ${this.apiKey}`
12836
13304
  });
12837
13305
  }
13306
+ /** POST /developer/agents/:agentId/channels/whatsapp/reaction */
13307
+ async sendWhatsAppReaction(input) {
13308
+ return this.httpPost(`/developer/agents/${this.agentId}/channels/whatsapp/reaction`, input, {
13309
+ Authorization: `Bearer ${this.apiKey}`
13310
+ });
13311
+ }
12838
13312
  /** POST /developer/agents/:agentId/channels/email/send */
12839
13313
  async sendEmail(input) {
12840
13314
  return this.httpPost(`/developer/agents/${this.agentId}/channels/email/send`, input, {
@@ -12866,6 +13340,17 @@ var init_channels_send_api_service = __esm({
12866
13340
  }
12867
13341
  return result.data;
12868
13342
  }
13343
+ /** Sandbox helper for WhatsApp reaction sends. */
13344
+ async sendWhatsAppReactionForSandbox(input) {
13345
+ const result = await this.sendWhatsAppReaction(input);
13346
+ if (!result.success) {
13347
+ throw new Error(result.error?.message || "WhatsApp reaction send failed");
13348
+ }
13349
+ if (!result.data) {
13350
+ throw new Error("WhatsApp reaction send failed: empty response");
13351
+ }
13352
+ return result.data;
13353
+ }
12869
13354
  /** Sandbox helper for email sends. */
12870
13355
  async sendEmailForSandbox(input) {
12871
13356
  const result = await this.sendEmail(input);
@@ -12881,6 +13366,44 @@ var init_channels_send_api_service = __esm({
12881
13366
  }
12882
13367
  });
12883
13368
 
13369
+ // src/api/directory.api.service.ts
13370
+ var DirectoryApiService;
13371
+ var init_directory_api_service = __esm({
13372
+ "src/api/directory.api.service.ts"() {
13373
+ "use strict";
13374
+ init_http_client();
13375
+ DirectoryApiService = class extends HttpClient {
13376
+ static {
13377
+ __name(this, "DirectoryApiService");
13378
+ }
13379
+ apiKey;
13380
+ agentId;
13381
+ constructor(baseUrl, apiKey, agentId) {
13382
+ super(baseUrl), this.apiKey = apiKey, this.agentId = agentId;
13383
+ }
13384
+ /** POST /developer/agents/:agentId/directory/resolve */
13385
+ async resolve(name) {
13386
+ return this.httpPost(`/developer/agents/${this.agentId}/directory/resolve`, {
13387
+ name
13388
+ }, {
13389
+ Authorization: `Bearer ${this.apiKey}`
13390
+ });
13391
+ }
13392
+ /** Sandbox helper: throws on non-success, returns unwrapped result. */
13393
+ async resolveForSandbox(name) {
13394
+ const result = await this.resolve(name);
13395
+ if (!result.success) {
13396
+ throw new Error(result.error?.message || "Directory resolve failed");
13397
+ }
13398
+ if (!result.data) {
13399
+ throw new Error("Directory resolve failed: empty response");
13400
+ }
13401
+ return result.data;
13402
+ }
13403
+ };
13404
+ }
13405
+ });
13406
+
12884
13407
  // src/api/device.api.service.ts
12885
13408
  var device_api_service_exports = {};
12886
13409
  __export(device_api_service_exports, {
@@ -12977,6 +13500,7 @@ __export(lazy_instances_exports, {
12977
13500
  getDataInstance: () => getDataInstance,
12978
13501
  getDeveloperInstance: () => getDeveloperInstance,
12979
13502
  getDeviceInstance: () => getDeviceInstance,
13503
+ getDirectoryInstance: () => getDirectoryInstance,
12980
13504
  getJobInstance: () => getJobInstance,
12981
13505
  getOrderInstance: () => getOrderInstance,
12982
13506
  getProductsInstance: () => getProductsInstance,
@@ -13091,6 +13615,13 @@ async function getChannelsSendInstance() {
13091
13615
  }
13092
13616
  return _channelsSendInstance;
13093
13617
  }
13618
+ async function getDirectoryInstance() {
13619
+ if (!_directoryInstance) {
13620
+ const creds = await getCredentials();
13621
+ _directoryInstance = new DirectoryApiService(BASE_URLS.API, creds.apiKey, creds.agentId);
13622
+ }
13623
+ return _directoryInstance;
13624
+ }
13094
13625
  function clearAllInstances() {
13095
13626
  _userInstance = null;
13096
13627
  _dataInstance = null;
@@ -13106,8 +13637,9 @@ function clearAllInstances() {
13106
13637
  _developerInstance = null;
13107
13638
  _voiceInstance = null;
13108
13639
  _channelsSendInstance = null;
13640
+ _directoryInstance = null;
13109
13641
  }
13110
- var _userInstance, _dataInstance, _productsInstance, _basketsInstance, _orderInstance, _webhookInstance, _jobInstance, _aiInstance, _agentsInstance, _whatsAppTemplatesInstance, _cdnInstance, _developerInstance, _voiceInstance, _channelsSendInstance, _deviceInstance;
13642
+ var _userInstance, _dataInstance, _productsInstance, _basketsInstance, _orderInstance, _webhookInstance, _jobInstance, _aiInstance, _agentsInstance, _whatsAppTemplatesInstance, _cdnInstance, _developerInstance, _voiceInstance, _channelsSendInstance, _directoryInstance, _deviceInstance;
13111
13643
  var init_lazy_instances = __esm({
13112
13644
  "src/api/lazy-instances.ts"() {
13113
13645
  "use strict";
@@ -13127,6 +13659,7 @@ var init_lazy_instances = __esm({
13127
13659
  init_developer_api_service();
13128
13660
  init_voice_api_service();
13129
13661
  init_channels_send_api_service();
13662
+ init_directory_api_service();
13130
13663
  _userInstance = null;
13131
13664
  _dataInstance = null;
13132
13665
  _productsInstance = null;
@@ -13141,6 +13674,7 @@ var init_lazy_instances = __esm({
13141
13674
  _developerInstance = null;
13142
13675
  _voiceInstance = null;
13143
13676
  _channelsSendInstance = null;
13677
+ _directoryInstance = null;
13144
13678
  __name(getUserInstance, "getUserInstance");
13145
13679
  __name(getDataInstance, "getDataInstance");
13146
13680
  __name(getProductsInstance, "getProductsInstance");
@@ -13157,6 +13691,7 @@ var init_lazy_instances = __esm({
13157
13691
  __name(getDeveloperInstance, "getDeveloperInstance");
13158
13692
  __name(getVoiceInstance, "getVoiceInstance");
13159
13693
  __name(getChannelsSendInstance, "getChannelsSendInstance");
13694
+ __name(getDirectoryInstance, "getDirectoryInstance");
13160
13695
  __name(clearAllInstances, "clearAllInstances");
13161
13696
  }
13162
13697
  });
@@ -16216,6 +16751,28 @@ var AgentHandler = class {
16216
16751
  success: false
16217
16752
  };
16218
16753
  }
16754
+ const browser = agent?.browser ?? null;
16755
+ writeProgress("\n\u{1F310} Pushing browser switch...");
16756
+ try {
16757
+ const success2 = await this.pushBrowser({
16758
+ apiKey,
16759
+ agentId
16760
+ }, browser);
16761
+ result.browser = {
16762
+ success: success2
16763
+ };
16764
+ if (success2) {
16765
+ writeSuccess(browser ? " \u2705 Browser switch pushed" : " \u2705 Browser switch off (default)");
16766
+ } else {
16767
+ console.error(" \u274C Failed to push browser switch");
16768
+ }
16769
+ } catch (error) {
16770
+ if (AuthenticationError.isAuthenticationError(error)) throw error;
16771
+ console.error(` \u274C Failed to push browser switch: ${error.message}`);
16772
+ result.browser = {
16773
+ success: false
16774
+ };
16775
+ }
16219
16776
  const voiceRefNames = agent?.voiceRefs?.map((v) => v.name) ?? [];
16220
16777
  let voicesLinkPayload = [];
16221
16778
  let skipVoicesPush = false;
@@ -16337,6 +16894,13 @@ var AgentHandler = class {
16337
16894
  });
16338
16895
  return result.success;
16339
16896
  }
16897
+ async pushBrowser(ctx, browser) {
16898
+ const agentApi = new AgentApi(BASE_URLS.API, ctx.apiKey);
16899
+ const result = await agentApi.updateAgent(ctx.agentId, {
16900
+ browser
16901
+ });
16902
+ return result.success;
16903
+ }
16340
16904
  async pushVoices(ctx, voices) {
16341
16905
  const agentApi = new AgentApi(BASE_URLS.API, ctx.apiKey);
16342
16906
  const result = await agentApi.updateAgent(ctx.agentId, {
@@ -18403,7 +18967,8 @@ var WebhookHandler = class extends BaseVersionedHandler {
18403
18967
  const response = await api.publishWebhookVersion(entityId, version);
18404
18968
  return {
18405
18969
  success: response.success,
18406
- error: response.error?.message
18970
+ error: response.error?.message,
18971
+ agentVersion: response.data?.agentVersion
18407
18972
  };
18408
18973
  }
18409
18974
  /**
@@ -18613,7 +19178,8 @@ var TriggerHandler = class extends BaseVersionedHandler {
18613
19178
  const response = await api.publishTriggerVersion(entityId, version);
18614
19179
  return {
18615
19180
  success: response.success,
18616
- error: response.error?.message
19181
+ error: response.error?.message,
19182
+ agentVersion: response.data?.agentVersion
18617
19183
  };
18618
19184
  }
18619
19185
  /** Include the trigger's body schema (from the SDK inputSchema) in push data. */
@@ -18723,7 +19289,8 @@ var JobHandler = class extends BaseVersionedHandler {
18723
19289
  const response = await api.publishJobVersion(entityId, version);
18724
19290
  return {
18725
19291
  success: response.success,
18726
- error: response.error?.message
19292
+ error: response.error?.message,
19293
+ agentVersion: response.data?.agentVersion
18727
19294
  };
18728
19295
  }
18729
19296
  /**
@@ -18798,7 +19365,8 @@ var PreprocessorHandler = class extends BaseVersionedHandler {
18798
19365
  const response = await api.publishPreProcessorVersion(entityId, version);
18799
19366
  return {
18800
19367
  success: response.success,
18801
- error: response.error?.message
19368
+ error: response.error?.message,
19369
+ agentVersion: response.data?.agentVersion
18802
19370
  };
18803
19371
  }
18804
19372
  /**
@@ -18874,7 +19442,8 @@ var PostprocessorHandler = class extends BaseVersionedHandler {
18874
19442
  const response = await api.publishPostProcessorVersion(entityId, version);
18875
19443
  return {
18876
19444
  success: response.success,
18877
- error: response.error?.message
19445
+ error: response.error?.message,
19446
+ agentVersion: response.data?.agentVersion
18878
19447
  };
18879
19448
  }
18880
19449
  /**
@@ -20458,6 +21027,106 @@ function runBundleInContext(context, source, options) {
20458
21027
  }
20459
21028
  __name(runBundleInContext, "runBundleInContext");
20460
21029
  __name4(runBundleInContext, "runBundleInContext");
21030
+ var USER_CODE_ERROR_CODE = "USER_CODE_ERROR";
21031
+ var PLATFORM_VM_ERROR_CODE = "PLATFORM_VM_ERROR";
21032
+ var UserCodeError = class extends Error {
21033
+ static {
21034
+ __name(this, "UserCodeError");
21035
+ }
21036
+ static {
21037
+ __name4(this, "UserCodeError");
21038
+ }
21039
+ code = USER_CODE_ERROR_CODE;
21040
+ source;
21041
+ constructor(source, cause) {
21042
+ super(cause instanceof Error ? cause.message : String(cause), {
21043
+ cause
21044
+ });
21045
+ this.name = "UserCodeError";
21046
+ this.source = source;
21047
+ if (cause instanceof Error && cause.stack) {
21048
+ this.stack = cause.stack;
21049
+ }
21050
+ }
21051
+ };
21052
+ function isUserCodeError(error) {
21053
+ if (!error || typeof error !== "object") return false;
21054
+ return error.code === USER_CODE_ERROR_CODE;
21055
+ }
21056
+ __name(isUserCodeError, "isUserCodeError");
21057
+ __name4(isUserCodeError, "isUserCodeError");
21058
+ function isPlatformVmError(error) {
21059
+ if (!error || typeof error !== "object") return false;
21060
+ return error.code === PLATFORM_VM_ERROR_CODE;
21061
+ }
21062
+ __name(isPlatformVmError, "isPlatformVmError");
21063
+ __name4(isPlatformVmError, "isPlatformVmError");
21064
+ var DEFAULT_MAX_CAUSE_DEPTH = 10;
21065
+ function findUserCodeErrorInCauseChain(value, maxDepth = DEFAULT_MAX_CAUSE_DEPTH) {
21066
+ let current = value;
21067
+ for (let depth = 0; depth < maxDepth; depth++) {
21068
+ if (isUserCodeError(current)) return current;
21069
+ if (!current || typeof current !== "object") return null;
21070
+ const next = current.cause;
21071
+ if (next === current || next === value) return null;
21072
+ current = next;
21073
+ }
21074
+ return null;
21075
+ }
21076
+ __name(findUserCodeErrorInCauseChain, "findUserCodeErrorInCauseChain");
21077
+ __name4(findUserCodeErrorInCauseChain, "findUserCodeErrorInCauseChain");
21078
+ var MissingPrimitiveCodeError = class extends Error {
21079
+ static {
21080
+ __name(this, "MissingPrimitiveCodeError");
21081
+ }
21082
+ static {
21083
+ __name4(this, "MissingPrimitiveCodeError");
21084
+ }
21085
+ code = PLATFORM_VM_ERROR_CODE;
21086
+ source;
21087
+ // The message reaches the customer's vmExecutionLogs dashboard (via Mastra's
21088
+ // re-wrap → LuaMastraLogger.logToMongo), so it must be customer-safe: no
21089
+ // internal ticket refs, no jargon, and it must NOT imply the customer's code
21090
+ // is at fault (it isn't — the artifact exists; delivery failed). Internal
21091
+ // triage keys off the error NAME + PLATFORM_VM_ERROR code + ERROR level, not
21092
+ // this prose.
21093
+ constructor(source) {
21094
+ super(`This ${source}'s code could not be loaded due to a temporary platform issue and was not executed. Please try again shortly.`);
21095
+ this.name = "MissingPrimitiveCodeError";
21096
+ this.source = source;
21097
+ }
21098
+ };
21099
+ function assertPrimitiveCodePresent(code, source) {
21100
+ if (typeof code !== "string" || code.length === 0) {
21101
+ throw new MissingPrimitiveCodeError(source);
21102
+ }
21103
+ }
21104
+ __name(assertPrimitiveCodePresent, "assertPrimitiveCodePresent");
21105
+ __name4(assertPrimitiveCodePresent, "assertPrimitiveCodePresent");
21106
+ async function withUserCodeBoundary(source, fn) {
21107
+ try {
21108
+ return await fn();
21109
+ } catch (cause) {
21110
+ if (isUserCodeError(cause)) throw cause;
21111
+ if (isPlatformVmError(cause)) throw cause;
21112
+ throw new UserCodeError(source, cause);
21113
+ }
21114
+ }
21115
+ __name(withUserCodeBoundary, "withUserCodeBoundary");
21116
+ __name4(withUserCodeBoundary, "withUserCodeBoundary");
21117
+ function logUserCodeOrError(logger, message, error, context = {}) {
21118
+ if (isUserCodeError(error)) {
21119
+ logger.warn(`${message} (user code)`, {
21120
+ ...context,
21121
+ source: error.source,
21122
+ error: error.message
21123
+ });
21124
+ } else {
21125
+ logger.error(message, error, context);
21126
+ }
21127
+ }
21128
+ __name(logUserCodeOrError, "logUserCodeOrError");
21129
+ __name4(logUserCodeOrError, "logUserCodeOrError");
20461
21130
 
20462
21131
  // src/utils/env-loader.utils.ts
20463
21132
  import path15 from "path";
@@ -20730,7 +21399,12 @@ function createSandbox(options) {
20730
21399
  const { getChannelsSendInstance: getChannelsSendInstance2 } = await Promise.resolve().then(() => (init_lazy_instances(), lazy_instances_exports));
20731
21400
  const channels = await getChannelsSendInstance2();
20732
21401
  return channels.sendWhatsAppTemplateForSandbox(input);
20733
- }, "sendTemplate")
21402
+ }, "sendTemplate"),
21403
+ sendReaction: /* @__PURE__ */ __name(async (input) => {
21404
+ const { getChannelsSendInstance: getChannelsSendInstance2 } = await Promise.resolve().then(() => (init_lazy_instances(), lazy_instances_exports));
21405
+ const channels = await getChannelsSendInstance2();
21406
+ return channels.sendWhatsAppReactionForSandbox(input);
21407
+ }, "sendReaction")
20734
21408
  },
20735
21409
  email: {
20736
21410
  send: /* @__PURE__ */ __name(async (input) => {
@@ -20739,6 +21413,17 @@ function createSandbox(options) {
20739
21413
  return channels.sendEmailForSandbox(input);
20740
21414
  }, "send")
20741
21415
  }
21416
+ },
21417
+ // Workspace directory. Resolve a teammate by name within the agent's org and
21418
+ // get the channel handles they opted to share — feed the result straight into
21419
+ // `Channels.send`. Proxied via the lua-cli developer endpoint (Bearer auth),
21420
+ // byte-equivalent to the lua-core production VM.
21421
+ Team: {
21422
+ findMember: /* @__PURE__ */ __name(async (name) => {
21423
+ const { getDirectoryInstance: getDirectoryInstance2 } = await Promise.resolve().then(() => (init_lazy_instances(), lazy_instances_exports));
21424
+ const directory = await getDirectoryInstance2();
21425
+ return directory.resolveForSandbox(name);
21426
+ }, "findMember")
20742
21427
  }
20743
21428
  };
20744
21429
  return createBaseSandboxContext({
@@ -21563,66 +22248,89 @@ var ALIAS_MAP = {
21563
22248
  del: "delete"
21564
22249
  })
21565
22250
  },
21566
- "marketplace.role": {
22251
+ "marketplace.noun": {
21567
22252
  canonical: [
21568
- "create",
21569
- "install"
22253
+ "skill",
22254
+ "template"
21570
22255
  ],
21571
22256
  aliases: lowerKeys({
21572
- creator: "create",
21573
- new: "create",
21574
- publish: "create",
21575
- installer: "install",
21576
- consumer: "install",
21577
- use: "install"
22257
+ skills: "skill",
22258
+ templates: "template",
22259
+ "agent-template": "template",
22260
+ "agent-templates": "template"
21578
22261
  })
21579
22262
  },
21580
- "marketplace.action.create": {
22263
+ // Flat skill-marketplace action namespace. `list`/`publish`/`edit`/`unlist`/
22264
+ // `unpublish`/`mine` are the old creator actions; `search`/`view`/`install`/
22265
+ // `update`/`uninstall`/`installed` are the old installer actions.
22266
+ "marketplace.skill.action": {
21581
22267
  canonical: [
21582
22268
  "list",
21583
22269
  "publish",
21584
- "update",
22270
+ "edit",
21585
22271
  "unlist",
21586
22272
  "unpublish",
21587
- "view"
22273
+ "mine",
22274
+ "search",
22275
+ "view",
22276
+ "install",
22277
+ "update",
22278
+ "uninstall",
22279
+ "installed"
21588
22280
  ],
21589
22281
  aliases: lowerKeys({
21590
22282
  ls: "list",
21591
22283
  l: "list",
21592
22284
  new: "publish",
21593
22285
  submit: "publish",
21594
- edit: "update",
21595
- modify: "update",
22286
+ modify: "edit",
21596
22287
  hide: "unlist",
21597
- delete: "unpublish",
21598
- remove: "unpublish",
21599
- rm: "unpublish",
22288
+ delist: "unlist",
22289
+ retract: "unpublish",
22290
+ deprecate: "unpublish",
22291
+ my: "mine",
22292
+ "my-listings": "mine",
22293
+ listed: "mine",
22294
+ find: "search",
21600
22295
  show: "view",
21601
- info: "view"
22296
+ info: "view",
22297
+ details: "view",
22298
+ add: "install",
22299
+ upgrade: "update",
22300
+ remove: "uninstall",
22301
+ rm: "uninstall",
22302
+ delete: "uninstall"
21602
22303
  })
21603
22304
  },
21604
- "marketplace.action.install": {
22305
+ "template.action": {
21605
22306
  canonical: [
21606
- "search",
22307
+ "create",
22308
+ "publish",
21607
22309
  "view",
22310
+ "versions",
21608
22311
  "install",
21609
- "update",
21610
- "uninstall",
21611
- "installed"
22312
+ "apply",
22313
+ "status",
22314
+ "installed",
22315
+ "uninstall"
21612
22316
  ],
21613
22317
  aliases: lowerKeys({
21614
- find: "search",
22318
+ new: "create",
22319
+ publish_version: "publish",
22320
+ submit: "publish",
21615
22321
  show: "view",
21616
22322
  info: "view",
22323
+ details: "view",
22324
+ history: "versions",
21617
22325
  add: "install",
21618
- edit: "update",
21619
- upgrade: "update",
22326
+ deploy: "apply",
22327
+ "fleet-apply": "apply",
22328
+ rollout: "apply",
22329
+ ls: "installed",
22330
+ list: "installed",
21620
22331
  remove: "uninstall",
21621
22332
  rm: "uninstall",
21622
- delete: "uninstall",
21623
- list: "installed",
21624
- ls: "installed",
21625
- l: "installed"
22333
+ delete: "uninstall"
21626
22334
  })
21627
22335
  },
21628
22336
  "models.action": {
@@ -24398,6 +25106,9 @@ Until the backup catches up, \`lua init\` for this agent will restore an older s
24398
25106
  }
24399
25107
  }
24400
25108
  writeSuccess("\n\u2705 Push All Complete!\n");
25109
+ if (options.autoDeployNoopWarned) {
25110
+ writeInfo("\u26A0\uFE0F --auto-deploy was ignored (agent versioning is on). To deploy, run `lua version create` then `lua version promote <version>`.\n");
25111
+ }
24401
25112
  const byKind = /* @__PURE__ */ new Map();
24402
25113
  for (const r of allResults) {
24403
25114
  const kind = r.handler.displayNamePlural;
@@ -24560,6 +25271,14 @@ async function confirmDeployment() {
24560
25271
  return confirmed;
24561
25272
  }
24562
25273
  __name(confirmDeployment, "confirmDeployment");
25274
+ function formatDeploySuccess(params) {
25275
+ const { label, name, version, agentVersion } = params;
25276
+ if (agentVersion != null) {
25277
+ return `\u2714 deployed ${name}@${version} \u2014 agent version ${agentVersion} promoted`;
25278
+ }
25279
+ return `\u2705 ${label} "${name}" v${version} deployed successfully`;
25280
+ }
25281
+ __name(formatDeploySuccess, "formatDeploySuccess");
24563
25282
 
24564
25283
  // src/commands/deploy.ts
24565
25284
  init_constants();
@@ -24723,7 +25442,7 @@ async function deployCommand(type, cmdObj) {
24723
25442
  selectedType = answer.type;
24724
25443
  }
24725
25444
  const apiKey = await requireAuthOrExit();
24726
- writeInfo("\u26A0\uFE0F `lua deploy` is deprecated when agent versioning is on. Use `lua version promote <version>` for instant, atomic promotion.");
25445
+ writeInfo("\u2139\uFE0F For agents under versioning, `lua deploy` creates and promotes a new agent version scoped to this primitive; otherwise it goes live directly. For multi-primitive releases, `lua version promote <version>` remains the recommended flow.");
24727
25446
  let personaDeployed = false;
24728
25447
  let versionedOutcome = null;
24729
25448
  if (selectedType === "persona") {
@@ -24737,7 +25456,7 @@ async function deployCommand(type, cmdObj) {
24737
25456
  force_mode: options.force || false,
24738
25457
  entity_selected_by_name: !!options.name,
24739
25458
  version_selected_by_flag: !!options.version,
24740
- granular_deprecation_warned: true
25459
+ scoped_promote_notice: true
24741
25460
  });
24742
25461
  const deployed = selectedType === "persona" ? personaDeployed : versionedOutcome?.deployed ?? false;
24743
25462
  const hintPrintedAlready = selectedType !== "persona" && !!versionedOutcome?.hintPrinted;
@@ -24877,9 +25596,14 @@ Available ${deployConfig.label}s:`);
24877
25596
  writeProgress("\u{1F504} Publishing version...");
24878
25597
  const result = await deployConfig.handler.publishVersion(apiKey, agentId, entityId, selectedVersion);
24879
25598
  if (!result.success) {
24880
- throw new Error(`Failed to deploy: ${result.error || "Unknown error"}`);
25599
+ throw new Error(result.error || "Failed to deploy");
24881
25600
  }
24882
- writeSuccess(`\u2705 ${deployConfig.label} "${selectedEntity.name}" v${selectedVersion} deployed successfully`);
25601
+ writeSuccess(formatDeploySuccess({
25602
+ label: deployConfig.label,
25603
+ name: selectedEntity.name,
25604
+ version: selectedVersion,
25605
+ agentVersion: result.agentVersion
25606
+ }));
24883
25607
  if (selectedVersion !== selectedEntity.version) {
24884
25608
  writeInfo(`\u{1F4DD} Updating YAML with deployed version: ${selectedVersion}`);
24885
25609
  deployConfig.handler.updateVersionInYaml(selectedEntity.name, selectedVersion);
@@ -24979,6 +25703,7 @@ async function deployAllCommand(_options) {
24979
25703
  validateSkillConfig(config);
24980
25704
  const apiKey = await requireAuthOrExit();
24981
25705
  const agentId = config.agent.agentId;
25706
+ writeInfo("\u2139\uFE0F For agents under versioning, each deploy below creates and promotes an agent version scoped to that primitive. To switch everything atomically in one version instead, use `lua version create` + `lua version promote`.");
24982
25707
  let deployedCount = 0;
24983
25708
  let failedCount = 0;
24984
25709
  const failedItems = [];
@@ -25000,7 +25725,12 @@ async function deployAllCommand(_options) {
25000
25725
  const latestVersion = sortVersionsByDate(versions)[0].version;
25001
25726
  const result = await deployConfig.handler.publishVersion(apiKey, agentId, entityId, latestVersion);
25002
25727
  if (result.success) {
25003
- writeSuccess(` \u2705 ${deployConfig.label} "${entity.name}" v${latestVersion} deployed`);
25728
+ writeSuccess(` ${formatDeploySuccess({
25729
+ label: deployConfig.label,
25730
+ name: entity.name,
25731
+ version: latestVersion,
25732
+ agentVersion: result.agentVersion
25733
+ })}`);
25004
25734
  if (latestVersion !== entity.version) {
25005
25735
  deployConfig.handler.updateVersionInYaml(entity.name, latestVersion);
25006
25736
  }
@@ -25205,16 +25935,14 @@ var ChatApi = class extends HttpClient {
25205
25935
  }
25206
25936
  }
25207
25937
  /**
25208
- * Clears conversation history for an agent
25938
+ * Clears the authenticated user's conversation history for an agent
25209
25939
  * @param agentId - The unique identifier of the agent
25210
- * @param targetIdentifier - Optional user identifier to clear history for specific user
25211
25940
  * @param threadId - Optional thread ID to clear a specific conversation thread
25212
25941
  * @returns Promise resolving to an ApiResponse with confirmation
25213
25942
  * @throws Error if the agent is not found or the clear operation fails
25214
25943
  */
25215
- async clearHistory(agentId, targetIdentifier, threadId) {
25944
+ async clearHistory(agentId, threadId) {
25216
25945
  const params = new URLSearchParams();
25217
- if (targetIdentifier) params.set("targetIdentifier", targetIdentifier);
25218
25946
  if (threadId) params.set("threadId", threadId);
25219
25947
  const query = params.toString() ? `?${params.toString()}` : "";
25220
25948
  const url = `/chat/history/${agentId}${query}`;
@@ -26383,7 +27111,7 @@ __name(startChatLoop, "startChatLoop");
26383
27111
  async function clearOnExit(chatEnv) {
26384
27112
  try {
26385
27113
  const chatApi = new ChatApi(BASE_URLS.CHAT, chatEnv.apiKey);
26386
- const response = await chatApi.clearHistory(chatEnv.agentId, void 0, chatEnv.threadId);
27114
+ const response = await chatApi.clearHistory(chatEnv.agentId, chatEnv.threadId);
26387
27115
  if (response.success) {
26388
27116
  const scope = chatEnv.threadId ? ` for thread "${chatEnv.threadId}"` : "";
26389
27117
  console.log(`
@@ -26414,6 +27142,10 @@ function stopTypingIndicator(interval) {
26414
27142
  process.stdout.write("\r\x1B[K");
26415
27143
  }
26416
27144
  __name(stopTypingIndicator, "stopTypingIndicator");
27145
+ function getClientTimeZone() {
27146
+ return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
27147
+ }
27148
+ __name(getClientTimeZone, "getClientTimeZone");
26417
27149
  async function sendSandboxMessageStream(chatEnv, messages, callbacks) {
26418
27150
  if (!chatEnv.yamlConfig) {
26419
27151
  throw new Error("Sandbox environment not properly initialized.");
@@ -26424,7 +27156,10 @@ async function sendSandboxMessageStream(chatEnv, messages, callbacks) {
26424
27156
  navigate: true,
26425
27157
  skillOverride: allSkillOverrides,
26426
27158
  preprocessorOverride: chatEnv.preprocessorOverrides || [],
26427
- postprocessorOverride: chatEnv.postprocessorOverrides || []
27159
+ postprocessorOverride: chatEnv.postprocessorOverrides || [],
27160
+ clientContext: {
27161
+ timezone: getClientTimeZone()
27162
+ }
26428
27163
  };
26429
27164
  if (chatEnv.persona) {
26430
27165
  chatRequest.personaOverride = chatEnv.persona;
@@ -26445,7 +27180,10 @@ async function sendProductionMessageStream(chatEnv, messages, callbacks) {
26445
27180
  navigate: true,
26446
27181
  skillOverride: [],
26447
27182
  preprocessorOverride: [],
26448
- postprocessorOverride: []
27183
+ postprocessorOverride: [],
27184
+ clientContext: {
27185
+ timezone: getClientTimeZone()
27186
+ }
26449
27187
  };
26450
27188
  if (chatEnv.threadId) {
26451
27189
  chatRequest.threadId = chatEnv.threadId;
@@ -26637,22 +27375,22 @@ init_analytics();
26637
27375
  async function chatClearCommand(options, command) {
26638
27376
  return withErrorHandling(async () => {
26639
27377
  const resolvedOptions = options ?? {};
27378
+ if (resolvedOptions.user) {
27379
+ 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.");
27380
+ }
26640
27381
  const { agentId, apiKey } = await initializeCommand();
26641
- const targetIdentifier = resolvedOptions.user;
26642
27382
  const threadId = resolvedOptions.thread ?? command?.parent?.opts()?.thread;
26643
27383
  const force = !!resolvedOptions.force;
26644
- const userContext = targetIdentifier ? `for user ${targetIdentifier}` : "for your current user";
26645
27384
  const threadContext = threadId ? ` in thread "${threadId}"` : "";
26646
- const context = `${userContext}${threadContext}`;
26647
27385
  if (!force) {
26648
27386
  console.log(`
26649
- \u26A0\uFE0F WARNING: This will clear conversation history ${context}!`);
27387
+ \u26A0\uFE0F WARNING: This will clear your conversation history${threadContext}!`);
26650
27388
  console.log("\u26A0\uFE0F This action cannot be undone.\n");
26651
27389
  const confirmAnswer = await safePrompt([
26652
27390
  {
26653
27391
  type: "confirm",
26654
27392
  name: "confirm",
26655
- message: `Are you sure you want to clear the conversation history ${context}?`,
27393
+ message: `Are you sure you want to clear your conversation history${threadContext}?`,
26656
27394
  default: false
26657
27395
  }
26658
27396
  ]);
@@ -26662,16 +27400,15 @@ async function chatClearCommand(options, command) {
26662
27400
  }
26663
27401
  writeProgress("\u{1F504} Clearing conversation history...");
26664
27402
  const chatApi = new ChatApi(BASE_URLS.CHAT, apiKey);
26665
- const response = await chatApi.clearHistory(agentId, targetIdentifier, threadId);
27403
+ const response = await chatApi.clearHistory(agentId, threadId);
26666
27404
  if (!response.success) {
26667
27405
  throw new Error(response.error?.message || "Failed to clear conversation history");
26668
27406
  }
26669
- writeSuccess(`\u2705 Conversation history cleared successfully ${context}`);
26670
- console.log(`\u{1F4A1} The chat history has been completely removed ${context}.
27407
+ writeSuccess(`\u2705 Your conversation history has been cleared${threadContext}`);
27408
+ console.log(`\u{1F4A1} Your chat history has been completely removed${threadContext}.
26671
27409
  `);
26672
27410
  trackEvent("cli_chat_cleared", {
26673
27411
  force_mode: force,
26674
- has_user_target: !!targetIdentifier,
26675
27412
  has_thread_target: !!threadId
26676
27413
  });
26677
27414
  }, "chat clear");
@@ -36622,48 +37359,828 @@ init_developer_api_service();
36622
37359
  init_semver();
36623
37360
  init_analytics();
36624
37361
  import inquirer14 from "inquirer";
36625
- async function marketplaceCommand(role, action, options) {
36626
- return withErrorHandling(async () => {
36627
- const { config, apiKey } = await initializeCommand();
36628
- const marketplaceApi = new MarketplaceApiService(apiKey);
36629
- let selectedRole = null;
36630
- if (role) {
36631
- const normalizedRole = validateOrSuggest("marketplace.role", role);
36632
- selectedRole = normalizedRole === "create" ? "creator" : "installer";
36633
- }
36634
- if (selectedRole && action) {
36635
- if (selectedRole === "creator") {
36636
- const normalizedAction = validateOrSuggest("marketplace.action.create", action);
36637
- await executeCreatorActionNonInteractive(marketplaceApi, config, apiKey, normalizedAction, options || {});
36638
- } else {
36639
- const normalizedAction = validateOrSuggest("marketplace.action.install", action);
36640
- await executeInstallerActionNonInteractive(marketplaceApi, config, apiKey, normalizedAction, options || {});
37362
+
37363
+ // src/commands/template.ts
37364
+ init_cli();
37365
+ import { readFileSync as readFileSync13 } from "fs";
37366
+
37367
+ // src/api/template.api.service.ts
37368
+ init_constants();
37369
+ var TemplateApiService = class {
37370
+ static {
37371
+ __name(this, "TemplateApiService");
37372
+ }
37373
+ apiKey;
37374
+ baseUrl = BASE_URLS.API;
37375
+ constructor(apiKey) {
37376
+ this.apiKey = apiKey;
37377
+ }
37378
+ async _fetch(endpoint, options = {}) {
37379
+ const url = `${this.baseUrl}${endpoint}`;
37380
+ const headers = {
37381
+ Authorization: `Bearer ${this.apiKey}`,
37382
+ "Content-Type": "application/json",
37383
+ ...options.headers
37384
+ };
37385
+ const response = await fetch(url, {
37386
+ ...options,
37387
+ headers
37388
+ });
37389
+ if (!response.ok) {
37390
+ const errorText = await response.text();
37391
+ throw new Error(`API Error: ${response.status} ${response.statusText} - ${errorText}`);
37392
+ }
37393
+ if (response.status === 204) {
37394
+ return null;
37395
+ }
37396
+ return response.json();
37397
+ }
37398
+ async createTemplate(data) {
37399
+ return this._fetch("/marketplace/templates", {
37400
+ method: "POST",
37401
+ body: JSON.stringify(data)
37402
+ });
37403
+ }
37404
+ async createVersion(templateId, data) {
37405
+ return this._fetch(`/marketplace/templates/${templateId}/versions`, {
37406
+ method: "POST",
37407
+ body: JSON.stringify(data)
37408
+ });
37409
+ }
37410
+ async listTemplates() {
37411
+ return this._fetch("/marketplace/templates");
37412
+ }
37413
+ async getTemplate(templateId) {
37414
+ return this._fetch(`/marketplace/templates/${templateId}`);
37415
+ }
37416
+ async getVersions(templateId) {
37417
+ return this._fetch(`/marketplace/templates/${templateId}/versions`);
37418
+ }
37419
+ async getVersion(templateId, version) {
37420
+ return this._fetch(`/marketplace/templates/${templateId}/versions/${version}`);
37421
+ }
37422
+ async install(templateId, agentId, data) {
37423
+ return this._fetch(`/marketplace/templates/${templateId}/install/${agentId}`, {
37424
+ method: "POST",
37425
+ body: JSON.stringify(data)
37426
+ });
37427
+ }
37428
+ async apply(templateId, data) {
37429
+ return this._fetch(`/marketplace/templates/${templateId}/apply`, {
37430
+ method: "POST",
37431
+ body: JSON.stringify(data)
37432
+ });
37433
+ }
37434
+ async getApplyRun(templateId, runId) {
37435
+ return this._fetch(`/marketplace/templates/${templateId}/apply-runs/${runId}`);
37436
+ }
37437
+ async getInstalls(templateId, page, limit) {
37438
+ const params = new URLSearchParams();
37439
+ if (page !== void 0) params.set("page", String(page));
37440
+ if (limit !== void 0) params.set("limit", String(limit));
37441
+ const query = params.toString();
37442
+ return this._fetch(`/marketplace/templates/${templateId}/installs${query ? `?${query}` : ""}`);
37443
+ }
37444
+ async getAllInstalls(templateId) {
37445
+ const pageSize = 1e3;
37446
+ const all = [];
37447
+ for (let page = 1; ; page++) {
37448
+ const batch = await this.getInstalls(templateId, page, pageSize);
37449
+ all.push(...batch);
37450
+ if (batch.length < pageSize) return all;
37451
+ }
37452
+ }
37453
+ async getAgentTemplates(agentId) {
37454
+ return this._fetch(`/marketplace/templates/agent/${agentId}`);
37455
+ }
37456
+ async uninstall(templateId, agentId) {
37457
+ return this._fetch(`/marketplace/templates/${templateId}/installs/${agentId}`, {
37458
+ method: "DELETE"
37459
+ });
37460
+ }
37461
+ };
37462
+
37463
+ // src/commands/template.ts
37464
+ init_command_utils();
37465
+ init_analytics();
37466
+ function showTemplateUsage() {
37467
+ console.log("\nUsage:");
37468
+ console.log(" lua marketplace template Interactive mode");
37469
+ console.log(" lua marketplace template <action> [options] Non-interactive mode");
37470
+ console.log("\nActions:");
37471
+ console.log(" create --name <n> --display-name <n> [--description <text>] [--visibility public|private]");
37472
+ console.log(" publish --template-id <id> [--source-version <n>] [--changelog <text>] [--env-contract KEY=desc,...]");
37473
+ console.log(" view --template-id <id> [--version <n>] [--json]");
37474
+ console.log(" versions --template-id <id> [--json]");
37475
+ console.log(" install --template-id <id> [--version <n>] [--env-vars k=v,...] --force");
37476
+ console.log(" apply --template-id <id> [--version <n>] (--agents a,b | --file <path> | --all-installed) --force [--no-wait]");
37477
+ console.log(" status --template-id <id> [--json]");
37478
+ console.log(" installed [--json]");
37479
+ console.log(" uninstall --template-id <id> --force");
37480
+ }
37481
+ __name(showTemplateUsage, "showTemplateUsage");
37482
+ async function templateCommand(action, options = {}) {
37483
+ const { config, apiKey } = await initializeCommand();
37484
+ const templateApi = new TemplateApiService(apiKey);
37485
+ let selectedAction;
37486
+ if (action) {
37487
+ selectedAction = validateOrSuggest("template.action", action);
37488
+ } else {
37489
+ const answer = await safePrompt([
37490
+ {
37491
+ type: "list",
37492
+ name: "action",
37493
+ message: "What would you like to do?",
37494
+ choices: [
37495
+ {
37496
+ name: "Create a template from this agent",
37497
+ value: "create"
37498
+ },
37499
+ {
37500
+ name: "Publish a new template version",
37501
+ value: "publish"
37502
+ },
37503
+ {
37504
+ name: "View a template",
37505
+ value: "view"
37506
+ },
37507
+ {
37508
+ name: "List a template\u2019s versions",
37509
+ value: "versions"
37510
+ },
37511
+ {
37512
+ name: "Install a template onto this agent",
37513
+ value: "install"
37514
+ },
37515
+ {
37516
+ name: "Apply a template to a fleet of agents",
37517
+ value: "apply"
37518
+ },
37519
+ {
37520
+ name: "View a template\u2019s fleet install status",
37521
+ value: "status"
37522
+ },
37523
+ {
37524
+ name: "List templates installed on this agent",
37525
+ value: "installed"
37526
+ },
37527
+ {
37528
+ name: "Uninstall a template from this agent",
37529
+ value: "uninstall"
37530
+ },
37531
+ {
37532
+ name: "Exit",
37533
+ value: "exit"
37534
+ }
37535
+ ]
36641
37536
  }
37537
+ ]);
37538
+ if (!answer || answer.action === "exit") {
37539
+ console.log("\n\u{1F44B} Goodbye!\n");
36642
37540
  return;
36643
37541
  }
36644
- if (selectedRole) {
36645
- if (selectedRole === "creator") {
36646
- await handleCreatorActions(marketplaceApi, config, apiKey);
36647
- } else {
36648
- await handleInstallerActions(marketplaceApi, config, apiKey);
37542
+ selectedAction = answer.action;
37543
+ }
37544
+ switch (selectedAction) {
37545
+ case "create":
37546
+ await templateCreateAction(templateApi, config, options);
37547
+ break;
37548
+ case "publish":
37549
+ await templatePublishAction(templateApi, options);
37550
+ break;
37551
+ case "view":
37552
+ await templateViewAction(templateApi, options);
37553
+ break;
37554
+ case "versions":
37555
+ await templateVersionsAction(templateApi, options);
37556
+ break;
37557
+ case "install":
37558
+ await templateInstallAction(templateApi, config, options);
37559
+ break;
37560
+ case "apply":
37561
+ await templateApplyAction(templateApi, options);
37562
+ break;
37563
+ case "status":
37564
+ await templateStatusAction(templateApi, options);
37565
+ break;
37566
+ case "installed":
37567
+ await templateInstalledAction(templateApi, config, options);
37568
+ break;
37569
+ case "uninstall":
37570
+ await templateUninstallAction(templateApi, config, options);
37571
+ break;
37572
+ default:
37573
+ showTemplateUsage();
37574
+ }
37575
+ trackEvent("cli_template_action", {
37576
+ action: selectedAction,
37577
+ non_interactive: !!action
37578
+ });
37579
+ }
37580
+ __name(templateCommand, "templateCommand");
37581
+ function sleep2(ms) {
37582
+ return new Promise((resolve6) => setTimeout(resolve6, ms));
37583
+ }
37584
+ __name(sleep2, "sleep");
37585
+ async function resolveTemplateId(templateApi, options, message) {
37586
+ if (options.templateId) return options.templateId;
37587
+ writeProgress("\u{1F504} Loading your templates...");
37588
+ const { templates } = await templateApi.listTemplates();
37589
+ if (!templates.length) {
37590
+ throw new Error("You haven't created any templates yet. Run `lua marketplace template create` first.");
37591
+ }
37592
+ const answer = await safePrompt([
37593
+ {
37594
+ type: "list",
37595
+ name: "template",
37596
+ message,
37597
+ choices: templates.map((t) => ({
37598
+ name: `${t.displayName} (${t.name})`,
37599
+ value: t
37600
+ }))
37601
+ }
37602
+ ]);
37603
+ if (!answer) throw new Error("Cancelled.");
37604
+ return answer.template.id;
37605
+ }
37606
+ __name(resolveTemplateId, "resolveTemplateId");
37607
+ function parseKeyValuePairs(raw) {
37608
+ const result = {};
37609
+ for (const pair of raw.split(",")) {
37610
+ const [key, ...valueParts] = pair.split("=");
37611
+ if (key && valueParts.length > 0) {
37612
+ result[key.trim()] = valueParts.join("=").trim();
37613
+ }
37614
+ }
37615
+ return result;
37616
+ }
37617
+ __name(parseKeyValuePairs, "parseKeyValuePairs");
37618
+ function parseEnvContract(raw) {
37619
+ if (!raw || raw.length === 0) return void 0;
37620
+ const result = {};
37621
+ for (const entry of raw) {
37622
+ for (const pair of entry.split(",")) {
37623
+ const trimmed = pair.trim();
37624
+ if (!trimmed) continue;
37625
+ const eqIdx = trimmed.indexOf("=");
37626
+ if (eqIdx === -1) continue;
37627
+ let key = trimmed.slice(0, eqIdx).trim();
37628
+ const description = trimmed.slice(eqIdx + 1).trim();
37629
+ let required = true;
37630
+ if (key.endsWith("?")) {
37631
+ required = false;
37632
+ key = key.slice(0, -1).trim();
37633
+ }
37634
+ if (!key) continue;
37635
+ result[key] = {
37636
+ description,
37637
+ required
37638
+ };
37639
+ }
37640
+ }
37641
+ return Object.keys(result).length > 0 ? result : void 0;
37642
+ }
37643
+ __name(parseEnvContract, "parseEnvContract");
37644
+ function printManifestSummary(content) {
37645
+ console.log(` Skills: ${content.skills.length}`);
37646
+ console.log(` Webhooks: ${content.webhooks.length}`);
37647
+ console.log(` Jobs: ${content.jobs.length}`);
37648
+ console.log(` Preprocessors: ${content.preprocessors.length}`);
37649
+ console.log(` Postprocessors: ${content.postprocessors.length}`);
37650
+ console.log(` Triggers: ${content.triggers.length}`);
37651
+ console.log(` Model: ${content.model ?? "(unchanged)"}`);
37652
+ }
37653
+ __name(printManifestSummary, "printManifestSummary");
37654
+ function printManifestDetail(content, envContract) {
37655
+ const sections = [
37656
+ {
37657
+ name: "Skills",
37658
+ items: content.skills
37659
+ },
37660
+ {
37661
+ name: "Webhooks",
37662
+ items: content.webhooks
37663
+ },
37664
+ {
37665
+ name: "Jobs",
37666
+ items: content.jobs
37667
+ },
37668
+ {
37669
+ name: "Preprocessors",
37670
+ items: content.preprocessors
37671
+ },
37672
+ {
37673
+ name: "Postprocessors",
37674
+ items: content.postprocessors
37675
+ },
37676
+ {
37677
+ name: "Triggers",
37678
+ items: content.triggers
37679
+ }
37680
+ ];
37681
+ for (const { name, items } of sections) {
37682
+ console.log(`
37683
+ ${name}:`);
37684
+ if (items.length === 0) {
37685
+ console.log(" (none)");
37686
+ continue;
37687
+ }
37688
+ for (const item of items) {
37689
+ console.log(` ${item.name ?? item.key} \u2014 v${item.version} (${item.key})`);
37690
+ }
37691
+ }
37692
+ console.log(`
37693
+ Model: ${content.model ?? "(none)"}`);
37694
+ console.log(`
37695
+ Env contract:`);
37696
+ const entries = envContract ? Object.entries(envContract) : [];
37697
+ if (entries.length === 0) {
37698
+ console.log(" (none)");
37699
+ } else {
37700
+ for (const [key, meta] of entries) {
37701
+ const optionalTag = meta.required ? "" : " (optional)";
37702
+ const example = meta.example ? ` \u2014 e.g. ${meta.example}` : "";
37703
+ console.log(` ${key}${optionalTag}: ${meta.description}${example}`);
37704
+ }
37705
+ }
37706
+ }
37707
+ __name(printManifestDetail, "printManifestDetail");
37708
+ async function templateCreateAction(templateApi, config, options) {
37709
+ const agentId = config.agent?.agentId;
37710
+ if (!agentId) throw new Error("Agent ID not found in configuration.");
37711
+ let { name, displayName, description, visibility } = options;
37712
+ if (visibility && visibility !== "public" && visibility !== "private") {
37713
+ throw new Error('Invalid --visibility: must be "public" or "private"');
37714
+ }
37715
+ const questions = [];
37716
+ if (!name) {
37717
+ questions.push({
37718
+ type: "input",
37719
+ name: "name",
37720
+ message: "Template name (internal identifier):",
37721
+ validate: /* @__PURE__ */ __name((input) => input && input.trim().length > 0 ? true : "Name cannot be empty.", "validate")
37722
+ });
37723
+ }
37724
+ if (!displayName) {
37725
+ questions.push({
37726
+ type: "input",
37727
+ name: "displayName",
37728
+ message: "Display name:",
37729
+ validate: /* @__PURE__ */ __name((input) => input && input.trim().length > 0 ? true : "Display name cannot be empty.", "validate")
37730
+ });
37731
+ }
37732
+ if (description === void 0) {
37733
+ questions.push({
37734
+ type: "input",
37735
+ name: "description",
37736
+ message: "Description (optional):"
37737
+ });
37738
+ }
37739
+ if (!visibility) {
37740
+ questions.push({
37741
+ type: "list",
37742
+ name: "visibility",
37743
+ message: "Who can see and install this template?",
37744
+ choices: [
37745
+ {
37746
+ name: "Private \u2014 only your org can find and install it",
37747
+ value: "private"
37748
+ },
37749
+ {
37750
+ name: "Public \u2014 anyone can find and install it",
37751
+ value: "public"
37752
+ }
37753
+ ],
37754
+ default: "private"
37755
+ });
37756
+ }
37757
+ if (questions.length > 0) {
37758
+ const answers = await safePrompt(questions);
37759
+ if (!answers) throw new Error("Cancelled.");
37760
+ name = name ?? answers.name;
37761
+ displayName = displayName ?? answers.displayName;
37762
+ description = description ?? answers.description;
37763
+ visibility = visibility ?? answers.visibility;
37764
+ }
37765
+ if (!name || !displayName) {
37766
+ throw new Error("Missing required options: --name and --display-name");
37767
+ }
37768
+ writeProgress("\u{1F504} Creating template...");
37769
+ const template = await templateApi.createTemplate({
37770
+ sourceAgentId: agentId,
37771
+ name,
37772
+ displayName,
37773
+ description: description || void 0,
37774
+ visibility
37775
+ });
37776
+ if (options.json) {
37777
+ console.log(JSON.stringify(template, null, 2));
37778
+ return;
37779
+ }
37780
+ writeSuccess(`\u2705 Template "${template.displayName}" created!`);
37781
+ writeInfo(`Template ID: ${template.id}`);
37782
+ writeInfo(`Visibility: ${template.visibility === "private" ? "\u{1F512} Private" : "\u{1F310} Public"}`);
37783
+ writeHintBlock({
37784
+ headline: "Publish a version to make it installable:",
37785
+ lines: [
37786
+ {
37787
+ label: "Publish:",
37788
+ command: `lua marketplace template publish --template-id ${template.id}`
36649
37789
  }
37790
+ ],
37791
+ when: "success"
37792
+ });
37793
+ }
37794
+ __name(templateCreateAction, "templateCreateAction");
37795
+ async function templatePublishAction(templateApi, options) {
37796
+ const templateId = await resolveTemplateId(templateApi, options, "Which template would you like to publish a version for?");
37797
+ const sourceAgentVersion = options.sourceVersion ? Number.parseInt(options.sourceVersion, 10) : void 0;
37798
+ if (options.sourceVersion && (!Number.isFinite(sourceAgentVersion) || sourceAgentVersion <= 0)) {
37799
+ throw new Error(`Invalid --source-version "${options.sourceVersion}": must be a positive integer.`);
37800
+ }
37801
+ const envContract = parseEnvContract(options.envContract);
37802
+ writeProgress("\u{1F504} Publishing template version...");
37803
+ const version = await templateApi.createVersion(templateId, {
37804
+ sourceAgentVersion,
37805
+ changelog: options.changelog || void 0,
37806
+ envContract
37807
+ });
37808
+ if (options.json) {
37809
+ console.log(JSON.stringify(version, null, 2));
37810
+ return;
37811
+ }
37812
+ writeSuccess(`\u2705 Published v${version.version}`);
37813
+ writeInfo(`Frozen from agent version v${version.sourceAgentVersion}`);
37814
+ console.log("\nManifest:");
37815
+ printManifestSummary(version.content);
37816
+ const envCount = version.envContract ? Object.keys(version.envContract).length : 0;
37817
+ console.log(` Env contract: ${envCount} var(s)`);
37818
+ }
37819
+ __name(templatePublishAction, "templatePublishAction");
37820
+ async function templateViewAction(templateApi, options) {
37821
+ const templateId = await resolveTemplateId(templateApi, options, "Which template would you like to view?");
37822
+ if (options.version) {
37823
+ const versionNum = Number.parseInt(options.version, 10);
37824
+ if (!Number.isFinite(versionNum) || versionNum <= 0) {
37825
+ throw new Error(`Invalid --version "${options.version}": must be a positive integer.`);
37826
+ }
37827
+ const version = await templateApi.getVersion(templateId, versionNum).catch(() => null);
37828
+ if (!version) throw new Error(`Version v${versionNum} not found for this template.`);
37829
+ if (options.json) {
37830
+ console.log(JSON.stringify(version, null, 2));
36650
37831
  return;
36651
37832
  }
36652
- let exit = false;
36653
- while (!exit) {
36654
- const roleAnswer = await safePrompt([
37833
+ console.log(`
37834
+ ${"=".repeat(60)}`);
37835
+ console.log(`Template v${version.version} \u2014 ${templateId}`);
37836
+ console.log(`${"=".repeat(60)}`);
37837
+ if (version.changelog) console.log(`
37838
+ Changelog: ${version.changelog}`);
37839
+ printManifestDetail(version.content, version.envContract);
37840
+ return;
37841
+ }
37842
+ const template = await templateApi.getTemplate(templateId);
37843
+ if (options.json) {
37844
+ console.log(JSON.stringify(template, null, 2));
37845
+ return;
37846
+ }
37847
+ console.log(`
37848
+ ${"=".repeat(60)}`);
37849
+ console.log(`\u{1F4E6} ${template.displayName}`);
37850
+ console.log(`${"=".repeat(60)}
37851
+ `);
37852
+ console.log(`ID: ${template.id}`);
37853
+ console.log(`Name: ${template.name}`);
37854
+ if (template.description) console.log(`Description: ${template.description}`);
37855
+ console.log(`Visibility: ${template.visibility === "private" ? "\u{1F512} Private" : "\u{1F310} Public"}`);
37856
+ console.log(`Listed: ${template.listed ? "Yes" : "No"}`);
37857
+ console.log(`Installs: ${template.installCount}`);
37858
+ if (template.latestVersion != null) console.log(`Latest version: v${template.latestVersion}`);
37859
+ console.log(`Created: ${new Date(template.createdAt).toLocaleDateString()}`);
37860
+ console.log(`
37861
+ ${"=".repeat(60)}
37862
+ `);
37863
+ }
37864
+ __name(templateViewAction, "templateViewAction");
37865
+ async function templateVersionsAction(templateApi, options) {
37866
+ const templateId = await resolveTemplateId(templateApi, options, "Which template\u2019s versions would you like to see?");
37867
+ const versions = await templateApi.getVersions(templateId);
37868
+ if (options.json) {
37869
+ console.log(JSON.stringify(versions, null, 2));
37870
+ return;
37871
+ }
37872
+ if (versions.length === 0) {
37873
+ writeInfo("(no versions yet \u2014 run `lua marketplace template publish` to make one)");
37874
+ return;
37875
+ }
37876
+ const sorted = [
37877
+ ...versions
37878
+ ].sort((a, b) => b.version - a.version);
37879
+ for (const v of sorted) {
37880
+ console.log(`v${v.version} \u2014 from agent v${v.sourceAgentVersion} \u2014 ${new Date(v.createdAt).toLocaleString()}`);
37881
+ if (v.changelog) console.log(` ${v.changelog}`);
37882
+ }
37883
+ }
37884
+ __name(templateVersionsAction, "templateVersionsAction");
37885
+ async function templateInstallAction(templateApi, config, options) {
37886
+ const agentId = config.agent?.agentId;
37887
+ if (!agentId) throw new Error("Agent ID not found in configuration.");
37888
+ const templateId = await resolveTemplateId(templateApi, options, "Which template would you like to install?");
37889
+ const version = options.version ? Number.parseInt(options.version, 10) : void 0;
37890
+ const envValues = options.envVars ? parseKeyValuePairs(options.envVars) : void 0;
37891
+ if (!options.force) {
37892
+ writeInfo("\n\u{1F4CB} Install Summary:");
37893
+ writeInfo(` Template: ${templateId}`);
37894
+ writeInfo(` Version: ${version ?? "(latest)"}`);
37895
+ writeInfo(` Agent: ${agentId}`);
37896
+ if (envValues && Object.keys(envValues).length > 0) {
37897
+ writeInfo(` Env values: ${Object.keys(envValues).length} configured`);
37898
+ }
37899
+ console.error("\n\u274C Use --force to confirm installation");
37900
+ throw new Error("This action requires --force to confirm");
37901
+ }
37902
+ writeProgress("\u{1F504} Installing template...");
37903
+ const install = await templateApi.install(templateId, agentId, {
37904
+ version,
37905
+ envValues,
37906
+ allowCreatorUpdates: options.allowCreatorUpdates,
37907
+ skipEnvCheck: options.skipEnvCheck
37908
+ });
37909
+ if (options.json) {
37910
+ console.log(JSON.stringify(install, null, 2));
37911
+ return;
37912
+ }
37913
+ writeSuccess(`\u2705 Template installed! (v${install.installedVersion})`);
37914
+ if (install.appliedAgentVersion != null) {
37915
+ writeInfo(`Applied as agent version v${install.appliedAgentVersion}.`);
37916
+ }
37917
+ writeHintBlock({
37918
+ headline: "Roll back this agent to a prior state anytime:",
37919
+ lines: [
37920
+ {
37921
+ label: "Rollback:",
37922
+ command: "lua version promote <n>"
37923
+ }
37924
+ ],
37925
+ when: "success"
37926
+ });
37927
+ }
37928
+ __name(templateInstallAction, "templateInstallAction");
37929
+ function formatApplyResultTable(targets) {
37930
+ const header = {
37931
+ agentId: "AGENT ID",
37932
+ status: "STATUS",
37933
+ localAgentVersion: "LOCAL VERSION",
37934
+ error: "ERROR"
37935
+ };
37936
+ const rows = targets.map((t) => ({
37937
+ agentId: t.agentId,
37938
+ status: t.status,
37939
+ localAgentVersion: t.localAgentVersion != null ? `v${t.localAgentVersion}` : "\u2014",
37940
+ error: t.error ?? ""
37941
+ }));
37942
+ const cols = [
37943
+ "agentId",
37944
+ "status",
37945
+ "localAgentVersion",
37946
+ "error"
37947
+ ];
37948
+ const widths = {};
37949
+ for (const c of cols) {
37950
+ widths[c] = Math.max(header[c].length, ...rows.map((r) => r[c].length));
37951
+ }
37952
+ const fmt = /* @__PURE__ */ __name((r) => cols.map((c) => r[c].padEnd(widths[c])).join(" ").trimEnd(), "fmt");
37953
+ return [
37954
+ fmt(header),
37955
+ ...rows.map(fmt)
37956
+ ];
37957
+ }
37958
+ __name(formatApplyResultTable, "formatApplyResultTable");
37959
+ function resolveApplyTargets(options) {
37960
+ if (options.agents) {
37961
+ return options.agents.split(",").map((s) => s.trim()).filter(Boolean);
37962
+ }
37963
+ if (options.file) {
37964
+ const contents = readFileSync13(options.file, "utf-8");
37965
+ return contents.split("\n").map((s) => s.trim()).filter(Boolean);
37966
+ }
37967
+ return null;
37968
+ }
37969
+ __name(resolveApplyTargets, "resolveApplyTargets");
37970
+ async function templateApplyAction(templateApi, options) {
37971
+ const templateId = await resolveTemplateId(templateApi, options, "Which template would you like to apply?");
37972
+ let targets = resolveApplyTargets(options);
37973
+ if (!targets && options.allInstalled) {
37974
+ writeProgress("\u{1F504} Loading install ledger...");
37975
+ const installs = await templateApi.getAllInstalls(templateId);
37976
+ targets = installs.map((i) => i.agentId);
37977
+ }
37978
+ if (!targets) {
37979
+ throw new Error("Provide targets via --agents <a,b,c>, --file <path>, or --all-installed");
37980
+ }
37981
+ if (targets.length === 0) {
37982
+ writeInfo("No target agents resolved \u2014 nothing to apply.");
37983
+ return;
37984
+ }
37985
+ writeInfo(`Resolved ${targets.length} target agent(s): ${targets.join(", ")}`);
37986
+ const template = await templateApi.getTemplate(templateId);
37987
+ if (!template.latestVersion) {
37988
+ throw new Error("This template has no published versions. Run `lua marketplace template publish` first.");
37989
+ }
37990
+ const versionNum = options.version ? Number.parseInt(options.version, 10) : template.latestVersion;
37991
+ const versionObj = await templateApi.getVersion(templateId, versionNum).catch(() => null);
37992
+ if (!versionObj) throw new Error(`Version v${versionNum} not found for this template.`);
37993
+ if (!options.force) {
37994
+ console.log(`
37995
+ Apply plan:`);
37996
+ console.log(` Template: ${template.displayName} (${templateId})`);
37997
+ console.log(` Version: v${versionObj.version}`);
37998
+ console.log(` Targets: ${targets.length}`);
37999
+ console.log("\nManifest:");
38000
+ printManifestSummary(versionObj.content);
38001
+ const isTTY = Boolean(process.stdin.isTTY && process.stdout.isTTY);
38002
+ const isCi = isCiModeEnabled();
38003
+ if (isTTY && !isCi) {
38004
+ const confirmed = await confirmAction(`
38005
+ Apply v${versionObj.version} to ${targets.length} agent(s)?`);
38006
+ if (!confirmed) {
38007
+ writeInfo("Aborted.");
38008
+ return;
38009
+ }
38010
+ } else {
38011
+ throw new Error("This action requires --force to confirm (non-interactive mode)");
38012
+ }
38013
+ }
38014
+ writeProgress("\u{1F504} Starting apply run...");
38015
+ const { runId } = await templateApi.apply(templateId, {
38016
+ version: versionObj.version,
38017
+ targets,
38018
+ skipEnvCheck: options.skipEnvCheck
38019
+ });
38020
+ if (options.wait === false) {
38021
+ if (options.json) {
38022
+ console.log(JSON.stringify({
38023
+ runId
38024
+ }, null, 2));
38025
+ } else {
38026
+ writeSuccess(`\u2705 Apply run started: ${runId}`);
38027
+ }
38028
+ return;
38029
+ }
38030
+ writeProgress("\u{1F504} Waiting for apply run to complete...");
38031
+ const waitDeadline = Date.now() + 30 * 60 * 1e3;
38032
+ let run = await templateApi.getApplyRun(templateId, runId);
38033
+ while (run.status === "running") {
38034
+ if (Date.now() > waitDeadline) {
38035
+ throw new Error(`Apply run ${runId} still running after 30 minutes \u2014 a crashed worker can leave a run stuck. Check later with: lua marketplace template status --template-id ${templateId}`);
38036
+ }
38037
+ await sleep2(3e3);
38038
+ run = await templateApi.getApplyRun(templateId, runId);
38039
+ }
38040
+ if (options.json) {
38041
+ console.log(JSON.stringify(run, null, 2));
38042
+ } else {
38043
+ console.log(`
38044
+ Apply run ${run.status} (${run.id})`);
38045
+ for (const line of formatApplyResultTable(run.targets)) {
38046
+ console.log(line);
38047
+ }
38048
+ }
38049
+ const failedCount = run.targets.filter((t) => t.status === "failed").length;
38050
+ if (failedCount > 0) {
38051
+ throw new Error(`Apply run finished with ${failedCount} failed target(s).`);
38052
+ }
38053
+ }
38054
+ __name(templateApplyAction, "templateApplyAction");
38055
+ async function templateStatusAction(templateApi, options) {
38056
+ const templateId = await resolveTemplateId(templateApi, options, "Which template\u2019s fleet status would you like to see?");
38057
+ const installs = await templateApi.getAllInstalls(templateId);
38058
+ if (options.json) {
38059
+ console.log(JSON.stringify(installs, null, 2));
38060
+ return;
38061
+ }
38062
+ if (installs.length === 0) {
38063
+ writeInfo("No agents have installed this template yet.");
38064
+ return;
38065
+ }
38066
+ const header = {
38067
+ agentId: "AGENT ID",
38068
+ installedVersion: "TEMPLATE VERSION",
38069
+ appliedAgentVersion: "AGENT VERSION",
38070
+ status: "STATUS",
38071
+ appliedAt: "APPLIED AT"
38072
+ };
38073
+ const rows = installs.map((i) => ({
38074
+ agentId: i.agentId,
38075
+ installedVersion: `v${i.installedVersion}`,
38076
+ appliedAgentVersion: i.appliedAgentVersion != null ? `v${i.appliedAgentVersion}` : "\u2014",
38077
+ status: i.status,
38078
+ appliedAt: new Date(i.appliedAt).toISOString().slice(0, 16).replace("T", " ")
38079
+ }));
38080
+ const cols = [
38081
+ "agentId",
38082
+ "installedVersion",
38083
+ "appliedAgentVersion",
38084
+ "status",
38085
+ "appliedAt"
38086
+ ];
38087
+ const widths = {};
38088
+ for (const c of cols) {
38089
+ widths[c] = Math.max(header[c].length, ...rows.map((r) => r[c].length));
38090
+ }
38091
+ const fmt = /* @__PURE__ */ __name((r) => cols.map((c) => r[c].padEnd(widths[c])).join(" ").trimEnd(), "fmt");
38092
+ console.log(fmt(header));
38093
+ for (const r of rows) console.log(fmt(r));
38094
+ writeInfo("\n\u{1F4A1} Per-agent rollback: run `lua version promote <n>` directly on that agent.");
38095
+ }
38096
+ __name(templateStatusAction, "templateStatusAction");
38097
+ async function templateInstalledAction(templateApi, config, options) {
38098
+ const agentId = config.agent?.agentId;
38099
+ if (!agentId) throw new Error("Agent ID not found in configuration.");
38100
+ const summaries = await templateApi.getAgentTemplates(agentId);
38101
+ if (options.json) {
38102
+ console.log(JSON.stringify(summaries, null, 2));
38103
+ return;
38104
+ }
38105
+ if (summaries.length === 0) {
38106
+ writeInfo("\u{1F4E6} No templates installed on this agent.");
38107
+ return;
38108
+ }
38109
+ console.log(`
38110
+ \u{1F4CA} ${summaries.length} template(s) installed on this agent:
38111
+ `);
38112
+ for (const s of summaries) {
38113
+ console.log(`\u{1F4E6} ${s.displayName} (${s.templateId})`);
38114
+ console.log(` Installed version: v${s.installedVersion}`);
38115
+ console.log(` Status: ${s.status}`);
38116
+ console.log(` Applied: ${new Date(s.appliedAt).toLocaleString()}`);
38117
+ console.log("");
38118
+ }
38119
+ }
38120
+ __name(templateInstalledAction, "templateInstalledAction");
38121
+ async function templateUninstallAction(templateApi, config, options) {
38122
+ const agentId = config.agent?.agentId;
38123
+ if (!agentId) throw new Error("Agent ID not found in configuration.");
38124
+ const templateId = await resolveTemplateId(templateApi, options, "Which template would you like to uninstall?");
38125
+ if (!options.force) {
38126
+ console.error(`
38127
+ \u274C Use --force to confirm uninstalling template ${templateId} from this agent`);
38128
+ throw new Error("This action requires --force to confirm");
38129
+ }
38130
+ writeProgress("\u{1F504} Uninstalling template...");
38131
+ await templateApi.uninstall(templateId, agentId);
38132
+ writeSuccess("\u2705 Template uninstalled from this agent.");
38133
+ }
38134
+ __name(templateUninstallAction, "templateUninstallAction");
38135
+
38136
+ // src/commands/marketplace.ts
38137
+ var SKILL_ACTIONS = [
38138
+ "list",
38139
+ "publish",
38140
+ "edit",
38141
+ "unlist",
38142
+ "unpublish",
38143
+ "mine",
38144
+ "search",
38145
+ "view",
38146
+ "install",
38147
+ "update",
38148
+ "uninstall",
38149
+ "installed"
38150
+ ];
38151
+ var INTERACTIVE_SKILL_ACTIONS = SKILL_ACTIONS.filter((a) => a !== "view");
38152
+ var SKILL_ACTION_LABELS = {
38153
+ search: "Browse & search for skills",
38154
+ install: "Install a skill",
38155
+ update: "Update an installed skill",
38156
+ uninstall: "Uninstall a skill",
38157
+ installed: "List installed skills",
38158
+ list: "List a new skill on the Marketplace",
38159
+ publish: "Publish a new version of a skill",
38160
+ edit: "Edit metadata for a listed skill",
38161
+ unlist: "Unlist a skill from the Marketplace",
38162
+ unpublish: "Unpublish a skill version",
38163
+ mine: "View my listed skills"
38164
+ };
38165
+ async function marketplaceCommand(noun, action, options = {}) {
38166
+ return withErrorHandling(async () => {
38167
+ let domain;
38168
+ if (noun) {
38169
+ domain = validateOrSuggest("marketplace.noun", noun);
38170
+ } else {
38171
+ const domainAnswer = await safePrompt([
36655
38172
  {
36656
38173
  type: "list",
36657
- name: "role",
36658
- message: "What would you like to do?",
38174
+ name: "domain",
38175
+ message: "What would you like to browse?",
36659
38176
  choices: [
36660
38177
  {
36661
- name: "As a Creator (Publish & Manage your skills)",
36662
- value: "creator"
38178
+ name: "Skills",
38179
+ value: "skill"
36663
38180
  },
36664
38181
  {
36665
- name: "As an Installer (Find & Install skills)",
36666
- value: "installer"
38182
+ name: "Agent templates",
38183
+ value: "template"
36667
38184
  },
36668
38185
  {
36669
38186
  name: "Exit",
@@ -36672,26 +38189,67 @@ async function marketplaceCommand(role, action, options) {
36672
38189
  ]
36673
38190
  }
36674
38191
  ]);
36675
- if (!roleAnswer || roleAnswer.role === "exit") {
36676
- exit = true;
38192
+ if (!domainAnswer || domainAnswer.domain === "exit") {
36677
38193
  console.log("\n\u{1F44B} Goodbye!\n");
36678
- continue;
38194
+ return;
36679
38195
  }
36680
- if (roleAnswer.role === "creator") {
36681
- await handleCreatorActions(marketplaceApi, config, apiKey);
36682
- } else if (roleAnswer.role === "installer") {
36683
- await handleInstallerActions(marketplaceApi, config, apiKey);
38196
+ domain = domainAnswer.domain;
38197
+ }
38198
+ if (domain === "template") {
38199
+ return templateCommand(action, options);
38200
+ }
38201
+ return skillMarketplaceCommand(action, options);
38202
+ }, "marketplace");
38203
+ }
38204
+ __name(marketplaceCommand, "marketplaceCommand");
38205
+ async function skillMarketplaceCommand(action, options = {}) {
38206
+ const { config, apiKey } = await initializeCommand();
38207
+ const marketplaceApi = new MarketplaceApiService(apiKey);
38208
+ if (action) {
38209
+ const selectedAction = validateOrSuggest("marketplace.skill.action", action);
38210
+ await executeSkillActionNonInteractive(marketplaceApi, config, apiKey, selectedAction, options);
38211
+ trackEvent("cli_marketplace_action", {
38212
+ domain: "skill",
38213
+ action: selectedAction,
38214
+ non_interactive: true
38215
+ });
38216
+ return;
38217
+ }
38218
+ let exit = false;
38219
+ while (!exit) {
38220
+ const answer = await safePrompt([
38221
+ {
38222
+ type: "list",
38223
+ name: "action",
38224
+ message: "What would you like to do?",
38225
+ choices: [
38226
+ ...INTERACTIVE_SKILL_ACTIONS.map((a) => ({
38227
+ name: SKILL_ACTION_LABELS[a],
38228
+ value: a
38229
+ })),
38230
+ {
38231
+ name: "Exit",
38232
+ value: "exit"
38233
+ }
38234
+ ]
36684
38235
  }
38236
+ ]);
38237
+ if (!answer || answer.action === "exit") {
38238
+ exit = true;
38239
+ console.log("\n\u{1F44B} Goodbye!\n");
38240
+ continue;
36685
38241
  }
38242
+ const selectedAction = answer.action;
38243
+ await executeSkillActionInteractive(marketplaceApi, config, apiKey, selectedAction);
36686
38244
  trackEvent("cli_marketplace_action", {
36687
- role: role || "interactive",
36688
- action: action || null,
36689
- non_interactive: !!(selectedRole && action)
38245
+ domain: "skill",
38246
+ action: selectedAction,
38247
+ non_interactive: false
36690
38248
  });
36691
- }, "marketplace");
38249
+ }
36692
38250
  }
36693
- __name(marketplaceCommand, "marketplaceCommand");
36694
- async function executeCreatorActionNonInteractive(marketplaceApi, config, apiKey, action, options) {
38251
+ __name(skillMarketplaceCommand, "skillMarketplaceCommand");
38252
+ async function executeSkillActionNonInteractive(marketplaceApi, config, apiKey, action, options) {
36695
38253
  switch (action) {
36696
38254
  case "list":
36697
38255
  await listSkillNonInteractive(marketplaceApi, config, apiKey, options);
@@ -36699,7 +38257,7 @@ async function executeCreatorActionNonInteractive(marketplaceApi, config, apiKey
36699
38257
  case "publish":
36700
38258
  await publishVersionNonInteractive(marketplaceApi, config, apiKey, options);
36701
38259
  break;
36702
- case "update":
38260
+ case "edit":
36703
38261
  await updateMetadataNonInteractive(marketplaceApi, options);
36704
38262
  break;
36705
38263
  case "unlist":
@@ -36708,14 +38266,9 @@ async function executeCreatorActionNonInteractive(marketplaceApi, config, apiKey
36708
38266
  case "unpublish":
36709
38267
  await unpublishVersionNonInteractive(marketplaceApi, options);
36710
38268
  break;
36711
- case "view":
38269
+ case "mine":
36712
38270
  await viewMyListedSkillsNonInteractive(marketplaceApi, options);
36713
38271
  break;
36714
- }
36715
- }
36716
- __name(executeCreatorActionNonInteractive, "executeCreatorActionNonInteractive");
36717
- async function executeInstallerActionNonInteractive(marketplaceApi, config, apiKey, action, options) {
36718
- switch (action) {
36719
38272
  case "search":
36720
38273
  await searchSkillsNonInteractive(marketplaceApi, options);
36721
38274
  break;
@@ -36736,14 +38289,58 @@ async function executeInstallerActionNonInteractive(marketplaceApi, config, apiK
36736
38289
  break;
36737
38290
  }
36738
38291
  }
36739
- __name(executeInstallerActionNonInteractive, "executeInstallerActionNonInteractive");
38292
+ __name(executeSkillActionNonInteractive, "executeSkillActionNonInteractive");
38293
+ async function executeSkillActionInteractive(marketplaceApi, config, apiKey, action) {
38294
+ switch (action) {
38295
+ case "list":
38296
+ await listSkillOnMarketplace(marketplaceApi, config, apiKey);
38297
+ break;
38298
+ case "publish":
38299
+ await publishSkillVersion(marketplaceApi, config, apiKey);
38300
+ break;
38301
+ case "edit":
38302
+ await updateSkillMetadata(marketplaceApi, config);
38303
+ break;
38304
+ case "unlist":
38305
+ await unlistSkillFromMarketplace(marketplaceApi);
38306
+ break;
38307
+ case "unpublish":
38308
+ await unpublishSkillVersion(marketplaceApi);
38309
+ break;
38310
+ case "mine":
38311
+ await viewMyListedSkills(marketplaceApi);
38312
+ break;
38313
+ case "search":
38314
+ await searchMarketplaceSkills(marketplaceApi);
38315
+ break;
38316
+ case "install":
38317
+ await installMarketplaceSkill(marketplaceApi, config, apiKey);
38318
+ break;
38319
+ case "update":
38320
+ await updateInstalledSkill(marketplaceApi, config, apiKey);
38321
+ break;
38322
+ case "uninstall":
38323
+ await uninstallMarketplaceSkill(marketplaceApi, config);
38324
+ break;
38325
+ case "installed":
38326
+ await listInstalledSkills(marketplaceApi, config);
38327
+ break;
38328
+ case "view":
38329
+ break;
38330
+ }
38331
+ }
38332
+ __name(executeSkillActionInteractive, "executeSkillActionInteractive");
36740
38333
  async function listSkillNonInteractive(marketplaceApi, config, apiKey, options) {
36741
- const { skillName, displayName } = options;
38334
+ const { skillName, displayName, visibility } = options;
36742
38335
  if (!skillName || !displayName) {
36743
38336
  console.error("\u274C Missing required options");
36744
- console.log("\nUsage: lua marketplace create list --skill-name <name> --display-name <name>");
38337
+ console.log("\nUsage: lua marketplace skill list --skill-name <name> --display-name <name>");
36745
38338
  throw new Error("Missing required options");
36746
38339
  }
38340
+ if (visibility && visibility !== "public" && visibility !== "private") {
38341
+ console.error('\u274C Invalid --visibility: must be "public" or "private"');
38342
+ throw new Error('Invalid --visibility: must be "public" or "private"');
38343
+ }
36747
38344
  const agentId = config.agent?.agentId;
36748
38345
  if (!agentId) {
36749
38346
  console.error("\u274C Agent ID not found in configuration.");
@@ -36774,10 +38371,12 @@ async function listSkillNonInteractive(marketplaceApi, config, apiKey, options)
36774
38371
  writeProgress("\u{1F504} Listing skill on marketplace...");
36775
38372
  const marketplaceSkill = await marketplaceApi.listSkill({
36776
38373
  skillId: skill.id,
36777
- displayName
38374
+ displayName,
38375
+ visibility
36778
38376
  });
36779
38377
  writeSuccess(`\u2705 Skill "${marketplaceSkill.displayName}" listed successfully!`);
36780
38378
  writeInfo(`Marketplace Skill ID: ${marketplaceSkill.id}`);
38379
+ writeInfo(`Visibility: ${marketplaceSkill.visibility === "private" ? "\u{1F512} Private" : "\u{1F310} Public"}`);
36781
38380
  writeInfo("\u{1F4A1} You can now publish a version to make it installable.");
36782
38381
  }
36783
38382
  __name(listSkillNonInteractive, "listSkillNonInteractive");
@@ -36785,7 +38384,7 @@ async function publishVersionNonInteractive(marketplaceApi, config, apiKey, opti
36785
38384
  const { marketplaceId, versionId, changelog, envVarsJson } = options;
36786
38385
  if (!marketplaceId || !versionId) {
36787
38386
  console.error("\u274C Missing required options");
36788
- console.log("\nUsage: lua marketplace create publish --marketplace-id <id> --version-id <id> [--changelog <text>]");
38387
+ console.log("\nUsage: lua marketplace skill publish --marketplace-id <id> --version-id <id> [--changelog <text>]");
36789
38388
  throw new Error("Missing required options");
36790
38389
  }
36791
38390
  let envVars;
@@ -36812,7 +38411,7 @@ async function updateMetadataNonInteractive(marketplaceApi, options) {
36812
38411
  const { marketplaceId, displayName } = options;
36813
38412
  if (!marketplaceId) {
36814
38413
  console.error("\u274C Missing required option: --marketplace-id");
36815
- console.log("\nUsage: lua marketplace create update --marketplace-id <id> --display-name <name>");
38414
+ console.log("\nUsage: lua marketplace skill edit --marketplace-id <id> --display-name <name>");
36816
38415
  throw new Error("Missing required option: --marketplace-id");
36817
38416
  }
36818
38417
  if (!displayName) {
@@ -36830,12 +38429,12 @@ async function unlistSkillNonInteractive(marketplaceApi, options) {
36830
38429
  const { marketplaceId, force } = options;
36831
38430
  if (!marketplaceId) {
36832
38431
  console.error("\u274C Missing required option: --marketplace-id");
36833
- console.log("\nUsage: lua marketplace create unlist --marketplace-id <id> [--force]");
38432
+ console.log("\nUsage: lua marketplace skill unlist --marketplace-id <id> [--force]");
36834
38433
  throw new Error("Missing required option: --marketplace-id");
36835
38434
  }
36836
38435
  if (!force) {
36837
38436
  console.error("\u274C This action requires --force to confirm");
36838
- console.log("\nUsage: lua marketplace create unlist --marketplace-id <id> --force");
38437
+ console.log("\nUsage: lua marketplace skill unlist --marketplace-id <id> --force");
36839
38438
  throw new Error("This action requires --force to confirm");
36840
38439
  }
36841
38440
  writeProgress("\u{1F504} Unlisting skill...");
@@ -36848,7 +38447,7 @@ async function unpublishVersionNonInteractive(marketplaceApi, options) {
36848
38447
  const { marketplaceId, versionId, force } = options;
36849
38448
  if (!marketplaceId || !versionId) {
36850
38449
  console.error("\u274C Missing required options");
36851
- console.log("\nUsage: lua marketplace create unpublish --marketplace-id <id> --version-id <id> [--force]");
38450
+ console.log("\nUsage: lua marketplace skill unpublish --marketplace-id <id> --version-id <id> [--force]");
36852
38451
  throw new Error("Missing required options");
36853
38452
  }
36854
38453
  if (!force) {
@@ -36881,6 +38480,7 @@ async function viewMyListedSkillsNonInteractive(marketplaceApi, options) {
36881
38480
  console.log(`${statusIcon} ${skill.displayName} (${skill.name})`);
36882
38481
  console.log(` ID: ${skill.id}`);
36883
38482
  console.log(` Status: ${statusText}`);
38483
+ console.log(` Visibility: ${skill.visibility === "private" ? "\u{1F512} Private" : "\u{1F310} Public"}`);
36884
38484
  if (skill.versions && skill.versions.length > 0) {
36885
38485
  const publishedVersions = skill.versions.filter((v) => v.published);
36886
38486
  console.log(` Versions: ${publishedVersions.length} published / ${skill.versions.length} total`);
@@ -36929,7 +38529,7 @@ async function viewSkillNonInteractive(marketplaceApi, options) {
36929
38529
  const { marketplaceId } = options;
36930
38530
  if (!marketplaceId) {
36931
38531
  console.error("\u274C Missing required option: --marketplace-id");
36932
- console.log("\nUsage: lua marketplace install view --marketplace-id <id>");
38532
+ console.log("\nUsage: lua marketplace skill view --marketplace-id <id>");
36933
38533
  throw new Error("Missing required option: --marketplace-id");
36934
38534
  }
36935
38535
  writeProgress("\u{1F504} Loading skill details...");
@@ -36973,7 +38573,7 @@ async function installSkillNonInteractive(marketplaceApi, config, options) {
36973
38573
  const { marketplaceId, versionId, envVars, force } = options;
36974
38574
  if (!marketplaceId || !versionId) {
36975
38575
  console.error("\u274C Missing required options");
36976
- console.log("\nUsage: lua marketplace install install --marketplace-id <id> --version-id <id> [--env-vars <k=v,...>]");
38576
+ console.log("\nUsage: lua marketplace skill install --marketplace-id <id> --version-id <id> [--env-vars <k=v,...>]");
36977
38577
  throw new Error("Missing required options");
36978
38578
  }
36979
38579
  const agentId = config.agent?.agentId;
@@ -37030,7 +38630,7 @@ async function updateInstalledSkillNonInteractive(marketplaceApi, config, apiKey
37030
38630
  const { skillName, versionId, envVars } = options;
37031
38631
  if (!skillName) {
37032
38632
  console.error("\u274C Missing required option: --skill-name");
37033
- console.log("\nUsage: lua marketplace install update --skill-name <name> [--version-id <id>] [--env-vars <k=v,...>]");
38633
+ console.log("\nUsage: lua marketplace skill update --skill-name <name> [--version-id <id>] [--env-vars <k=v,...>]");
37034
38634
  throw new Error("Missing required option: --skill-name");
37035
38635
  }
37036
38636
  const agentId = config.agent?.agentId;
@@ -37082,7 +38682,7 @@ async function uninstallSkillNonInteractive(marketplaceApi, config, options) {
37082
38682
  const { skillName, force } = options;
37083
38683
  if (!skillName) {
37084
38684
  console.error("\u274C Missing required option: --skill-name");
37085
- console.log("\nUsage: lua marketplace install uninstall --skill-name <name> [--force]");
38685
+ console.log("\nUsage: lua marketplace skill uninstall --skill-name <name> [--force]");
37086
38686
  throw new Error("Missing required option: --skill-name");
37087
38687
  }
37088
38688
  const agentId = config.agent?.agentId;
@@ -37145,86 +38745,6 @@ async function listInstalledSkillsNonInteractive(marketplaceApi, config, options
37145
38745
  }
37146
38746
  }
37147
38747
  __name(listInstalledSkillsNonInteractive, "listInstalledSkillsNonInteractive");
37148
- async function handleCreatorActions(marketplaceApi, config, apiKey) {
37149
- let back = false;
37150
- while (!back) {
37151
- const creatorAnswer = await safePrompt([
37152
- {
37153
- type: "list",
37154
- name: "action",
37155
- message: "Creator Menu:",
37156
- choices: [
37157
- {
37158
- name: "List a new skill on the Marketplace",
37159
- value: "list"
37160
- },
37161
- {
37162
- name: "Publish a new version of a skill",
37163
- value: "publish"
37164
- },
37165
- {
37166
- name: "Update metadata for a listed skill",
37167
- value: "update"
37168
- },
37169
- {
37170
- name: "Unlist a skill from the Marketplace",
37171
- value: "unlist"
37172
- },
37173
- {
37174
- name: "Unpublish a skill version",
37175
- value: "unpublish"
37176
- },
37177
- {
37178
- name: "View my listed skills",
37179
- value: "view"
37180
- },
37181
- {
37182
- name: "Back",
37183
- value: "back"
37184
- }
37185
- ]
37186
- }
37187
- ]);
37188
- if (!creatorAnswer || creatorAnswer.action === "back") {
37189
- back = true;
37190
- continue;
37191
- }
37192
- switch (creatorAnswer.action) {
37193
- case "list":
37194
- await listSkillOnMarketplace(marketplaceApi, config, apiKey);
37195
- continue;
37196
- case "publish":
37197
- await publishSkillVersion(marketplaceApi, config, apiKey);
37198
- continue;
37199
- case "update":
37200
- await updateSkillMetadata(marketplaceApi, config);
37201
- continue;
37202
- case "unlist":
37203
- await unlistSkillFromMarketplace(marketplaceApi);
37204
- continue;
37205
- case "unpublish":
37206
- await unpublishSkillVersion(marketplaceApi);
37207
- continue;
37208
- case "view":
37209
- await viewMyListedSkills(marketplaceApi);
37210
- continue;
37211
- // Other cases will be added here
37212
- default:
37213
- console.log(`
37214
- Action '${creatorAnswer.action}' is not implemented yet.
37215
- `);
37216
- await safePrompt([
37217
- {
37218
- type: "input",
37219
- name: "continue",
37220
- message: "Press Enter to continue..."
37221
- }
37222
- ]);
37223
- continue;
37224
- }
37225
- }
37226
- }
37227
- __name(handleCreatorActions, "handleCreatorActions");
37228
38748
  async function listSkillOnMarketplace(marketplaceApi, config, apiKey) {
37229
38749
  const agentId = config.agent?.agentId;
37230
38750
  if (!agentId) {
@@ -37287,9 +38807,29 @@ async function listSkillOnMarketplace(marketplaceApi, config, apiKey) {
37287
38807
  }
37288
38808
  ]);
37289
38809
  if (!metadata) return;
38810
+ const visibilityAnswer = await safePrompt([
38811
+ {
38812
+ type: "list",
38813
+ name: "visibility",
38814
+ message: "Who can see and install this skill?",
38815
+ choices: [
38816
+ {
38817
+ name: "Public \u2014 anyone can find and install it",
38818
+ value: "public"
38819
+ },
38820
+ {
38821
+ name: "Private \u2014 only you (and your org) can find and install it",
38822
+ value: "private"
38823
+ }
38824
+ ],
38825
+ default: "public"
38826
+ }
38827
+ ]);
38828
+ if (!visibilityAnswer) return;
37290
38829
  const payload = {
37291
38830
  skillId: skillToList.id,
37292
- displayName: metadata.displayName
38831
+ displayName: metadata.displayName,
38832
+ visibility: visibilityAnswer.visibility
37293
38833
  };
37294
38834
  try {
37295
38835
  writeProgress("\nListing skill on the marketplace...");
@@ -37297,6 +38837,7 @@ async function listSkillOnMarketplace(marketplaceApi, config, apiKey) {
37297
38837
  writeSuccess(`
37298
38838
  \u2705 Skill "${marketplaceSkill.displayName}" listed successfully!`);
37299
38839
  writeInfo(`Marketplace Skill ID: ${marketplaceSkill.id}`);
38840
+ writeInfo(`Visibility: ${marketplaceSkill.visibility === "private" ? "\u{1F512} Private" : "\u{1F310} Public"}`);
37300
38841
  writeInfo("\u{1F4A1} You can now publish a version to make it installable.\n");
37301
38842
  } catch (error) {
37302
38843
  console.error(`
@@ -37667,6 +39208,7 @@ async function viewMyListedSkills(marketplaceApi) {
37667
39208
  const statusText = skill.listed ? "Listed" : "Unlisted";
37668
39209
  console.log(`${statusIcon} ${skill.displayName} (${skill.name})`);
37669
39210
  console.log(` Status: ${statusText}`);
39211
+ console.log(` Visibility: ${skill.visibility === "private" ? "\u{1F512} Private" : "\u{1F310} Public"}`);
37670
39212
  if (skill.description) {
37671
39213
  console.log(` Description: ${skill.description}`);
37672
39214
  }
@@ -37898,79 +39440,6 @@ async function configureEnvVar(varName, envVars) {
37898
39440
  `);
37899
39441
  }
37900
39442
  __name(configureEnvVar, "configureEnvVar");
37901
- async function handleInstallerActions(marketplaceApi, config, apiKey) {
37902
- let back = false;
37903
- while (!back) {
37904
- const installerAnswer = await safePrompt([
37905
- {
37906
- type: "list",
37907
- name: "action",
37908
- message: "Installer Menu:",
37909
- choices: [
37910
- {
37911
- name: "Browse & Search for skills",
37912
- value: "search"
37913
- },
37914
- {
37915
- name: "Install a skill from the Marketplace",
37916
- value: "install"
37917
- },
37918
- {
37919
- name: "Update an installed skill",
37920
- value: "update"
37921
- },
37922
- {
37923
- name: "Uninstall a skill",
37924
- value: "uninstall"
37925
- },
37926
- {
37927
- name: "List my currently installed skills",
37928
- value: "installed"
37929
- },
37930
- {
37931
- name: "Back",
37932
- value: "back"
37933
- }
37934
- ]
37935
- }
37936
- ]);
37937
- if (!installerAnswer || installerAnswer.action === "back") {
37938
- back = true;
37939
- continue;
37940
- }
37941
- switch (installerAnswer.action) {
37942
- case "search":
37943
- await searchMarketplaceSkills(marketplaceApi);
37944
- continue;
37945
- case "install":
37946
- await installMarketplaceSkill(marketplaceApi, config, apiKey);
37947
- continue;
37948
- case "update":
37949
- await updateInstalledSkill(marketplaceApi, config, apiKey);
37950
- continue;
37951
- case "uninstall":
37952
- await uninstallMarketplaceSkill(marketplaceApi, config);
37953
- continue;
37954
- case "installed":
37955
- await listInstalledSkills(marketplaceApi, config);
37956
- continue;
37957
- // Other cases will be added here
37958
- default:
37959
- console.log(`
37960
- Action '${installerAnswer.action}' is not implemented yet.
37961
- `);
37962
- await safePrompt([
37963
- {
37964
- type: "input",
37965
- name: "continue",
37966
- message: "Press Enter to continue..."
37967
- }
37968
- ]);
37969
- continue;
37970
- }
37971
- }
37972
- }
37973
- __name(handleInstallerActions, "handleInstallerActions");
37974
39443
  var MARKETPLACE_PAGE_SIZE = 10;
37975
39444
  async function browseAndSelectSkill(marketplaceApi, purpose, publishedVersionsOnly) {
37976
39445
  try {
@@ -43416,6 +44885,7 @@ init_cli();
43416
44885
  init_command_utils();
43417
44886
  init_analytics();
43418
44887
  init_files();
44888
+ init_semver();
43419
44889
  init_constants();
43420
44890
 
43421
44891
  // src/utils/parse-version.ts
@@ -43471,6 +44941,11 @@ async function versionCreateCommand(options = {}) {
43471
44941
  commitHash: options.commitHash
43472
44942
  });
43473
44943
  if (!result.success || !result.data) {
44944
+ const errCode = result.error?.code;
44945
+ if (errCode === "NO_STAGED_CHANGES") {
44946
+ writeInfo("\u2139\uFE0F No changes since the latest version, so there is nothing to snapshot. Make and push your changes (`lua push`), then run `lua version create`.");
44947
+ return;
44948
+ }
43474
44949
  throw new Error(result.error?.message ?? "Failed to create version");
43475
44950
  }
43476
44951
  writeInfo(`\u2713 Created v${result.data.version} (staged). Run \`lua version promote v${result.data.version}\` to deploy.`);
@@ -43692,6 +45167,7 @@ async function versionDiffCommand(fromArg, toArg, options = {}) {
43692
45167
  console.log(`Persona: ${diff.persona.from} \u2192 ${diff.persona.to}`);
43693
45168
  }
43694
45169
  console.log(`Model: ${diff.model ? `${diff.model.from} \u2192 ${diff.model.to}` : "(unchanged)"}`);
45170
+ console.log(`Voice: ${diff.voice ? `${diff.voice.from ?? "(none)"} \u2192 ${diff.voice.to ?? "(none)"}` : "(unchanged)"}`);
43695
45171
  }
43696
45172
  trackEvent("cli_version_diff_completed", {
43697
45173
  from_to_distance: Math.abs(to - from)
@@ -43790,6 +45266,202 @@ async function versionDeleteCommand(versionArg, options = {}) {
43790
45266
  }, "version delete");
43791
45267
  }
43792
45268
  __name(versionDeleteCommand, "versionDeleteCommand");
45269
+ function buildVersionStatusRows(inputs) {
45270
+ const rows = [];
45271
+ for (const { type, localItems, pinned } of inputs) {
45272
+ for (const item of localItems) {
45273
+ const match = (item.id ? pinned.find((p) => p.id === item.id) : void 0) ?? pinned.find((p) => p.name != null && p.name === item.name);
45274
+ const pinnedVersion = match ? match.version : null;
45275
+ const mismatch = pinnedVersion == null || pinnedVersion !== item.version;
45276
+ const localBehind = pinnedVersion != null && mismatch && compareVersions(item.version, pinnedVersion) < 0;
45277
+ rows.push({
45278
+ type,
45279
+ name: item.name,
45280
+ pinnedVersion,
45281
+ localVersion: item.version,
45282
+ mismatch,
45283
+ localBehind
45284
+ });
45285
+ }
45286
+ }
45287
+ return rows;
45288
+ }
45289
+ __name(buildVersionStatusRows, "buildVersionStatusRows");
45290
+ function formatVersionStatusTable(rows) {
45291
+ const header = {
45292
+ flag: " ",
45293
+ type: "TYPE",
45294
+ name: "NAME",
45295
+ active: "ACTIVE VERSION",
45296
+ local: "LOCAL"
45297
+ };
45298
+ const display = rows.map((r) => ({
45299
+ flag: r.mismatch ? "\u26A0" : " ",
45300
+ type: r.type,
45301
+ name: r.name,
45302
+ active: r.pinnedVersion != null ? `v${r.pinnedVersion}` : "\u2014 not in active version",
45303
+ local: `v${r.localVersion}`
45304
+ }));
45305
+ const cols = [
45306
+ "flag",
45307
+ "type",
45308
+ "name",
45309
+ "active",
45310
+ "local"
45311
+ ];
45312
+ const widths = {};
45313
+ for (const c of cols) {
45314
+ widths[c] = Math.max(header[c].length, ...display.map((r) => r[c].length));
45315
+ }
45316
+ const fmt = /* @__PURE__ */ __name((r) => cols.map((c) => r[c].padEnd(widths[c])).join(" ").trimEnd(), "fmt");
45317
+ return [
45318
+ fmt(header),
45319
+ ...display.map(fmt)
45320
+ ];
45321
+ }
45322
+ __name(formatVersionStatusTable, "formatVersionStatusTable");
45323
+ async function versionStatusCommand() {
45324
+ return withErrorHandling(async () => {
45325
+ const { apiKey, agentId } = await initializeCommand();
45326
+ const config = readYamlConfig();
45327
+ const api = new AgentVersionApi(BASE_URLS.API, apiKey, agentId);
45328
+ const listResponse = await api.listVersions({
45329
+ all: true
45330
+ });
45331
+ if (!listResponse.success || !listResponse.data) {
45332
+ throw new Error(listResponse.error?.message ?? "Failed to fetch versions");
45333
+ }
45334
+ const versions = listResponse.data;
45335
+ if (versions.length === 0) {
45336
+ writeInfo("This agent has no versions. Per-primitive deploys (`lua deploy`) go live immediately for agents that are not under versioning.");
45337
+ trackEvent("cli_version_status_completed", {
45338
+ has_versions: false,
45339
+ has_active: false,
45340
+ mismatches: 0
45341
+ });
45342
+ return;
45343
+ }
45344
+ const active = versions.find((v) => v.status === "active");
45345
+ if (!active) {
45346
+ writeInfo("This agent has versions but none is active yet. Run `lua version promote <version>` to make one live.");
45347
+ trackEvent("cli_version_status_completed", {
45348
+ has_versions: true,
45349
+ has_active: false,
45350
+ mismatches: 0
45351
+ });
45352
+ return;
45353
+ }
45354
+ const versionResponse = await api.getVersion(active.version);
45355
+ if (!versionResponse.success || !versionResponse.data) {
45356
+ throw new Error(versionResponse.error?.message ?? `Failed to fetch v${active.version}`);
45357
+ }
45358
+ const snapshot = versionResponse.data.snapshot;
45359
+ const inputs = [
45360
+ {
45361
+ type: "skill",
45362
+ localItems: skillHandler.getFromYaml(config).map((i) => ({
45363
+ name: i.name,
45364
+ version: i.version,
45365
+ id: i.skillId
45366
+ })),
45367
+ pinned: snapshot.skills.map((p) => ({
45368
+ id: p.skillId,
45369
+ version: p.version,
45370
+ name: p.name
45371
+ }))
45372
+ },
45373
+ {
45374
+ type: "webhook",
45375
+ localItems: webhookHandler.getFromYaml(config).map((i) => ({
45376
+ name: i.name,
45377
+ version: i.version,
45378
+ id: i.webhookId
45379
+ })),
45380
+ pinned: snapshot.webhooks.map((p) => ({
45381
+ id: p.webhookId,
45382
+ version: p.version,
45383
+ name: p.name
45384
+ }))
45385
+ },
45386
+ {
45387
+ type: "job",
45388
+ localItems: jobHandler.getFromYaml(config).map((i) => ({
45389
+ name: i.name,
45390
+ version: i.version,
45391
+ id: i.jobId
45392
+ })),
45393
+ pinned: snapshot.jobs.map((p) => ({
45394
+ id: p.jobId,
45395
+ version: p.version,
45396
+ name: p.name
45397
+ }))
45398
+ },
45399
+ {
45400
+ type: "preprocessor",
45401
+ localItems: preprocessorHandler.getFromYaml(config).map((i) => ({
45402
+ name: i.name,
45403
+ version: i.version,
45404
+ id: i.preprocessorId
45405
+ })),
45406
+ pinned: snapshot.preprocessors.map((p) => ({
45407
+ id: p.id,
45408
+ version: p.version,
45409
+ name: p.name
45410
+ }))
45411
+ },
45412
+ {
45413
+ type: "postprocessor",
45414
+ localItems: postprocessorHandler.getFromYaml(config).map((i) => ({
45415
+ name: i.name,
45416
+ version: i.version,
45417
+ id: i.postprocessorId
45418
+ })),
45419
+ pinned: snapshot.postprocessors.map((p) => ({
45420
+ id: p.id,
45421
+ version: p.version,
45422
+ name: p.name
45423
+ }))
45424
+ },
45425
+ {
45426
+ type: "trigger",
45427
+ localItems: triggerHandler.getFromYaml(config).map((i) => ({
45428
+ name: i.name,
45429
+ version: i.version,
45430
+ id: i.triggerId
45431
+ })),
45432
+ pinned: (snapshot.triggers ?? []).map((p) => ({
45433
+ id: p.triggerId,
45434
+ version: p.version,
45435
+ name: p.name
45436
+ }))
45437
+ }
45438
+ ];
45439
+ const rows = buildVersionStatusRows(inputs);
45440
+ const mismatches = rows.filter((r) => r.mismatch).length;
45441
+ console.log(`Active agent version: v${active.version}`);
45442
+ if (rows.length === 0) {
45443
+ writeInfo("(no local primitives found in lua.skill.yaml)");
45444
+ } else {
45445
+ for (const line of formatVersionStatusTable(rows)) {
45446
+ console.log(line);
45447
+ }
45448
+ const behind = rows.filter((r) => r.localBehind).length;
45449
+ const ahead = mismatches - behind;
45450
+ if (ahead > 0) {
45451
+ writeInfo(`\u26A0 ${ahead} primitive(s) are ahead of the active version (see rows marked above). Run \`lua version create\` then \`lua version promote\` to make them live, or \`lua deploy <type>\` for a single primitive.`);
45452
+ }
45453
+ if (behind > 0) {
45454
+ writeInfo(`\u26A0 ${behind} primitive(s) have a local version OLDER than what's live \u2014 deploying them would roll production back. Run \`lua sync\` to update your local files instead.`);
45455
+ }
45456
+ }
45457
+ trackEvent("cli_version_status_completed", {
45458
+ has_versions: true,
45459
+ has_active: true,
45460
+ mismatches
45461
+ });
45462
+ }, "version status");
45463
+ }
45464
+ __name(versionStatusCommand, "versionStatusCommand");
43793
45465
 
43794
45466
  // src/commands/git.ts
43795
45467
  init_cli();
@@ -44132,20 +45804,21 @@ Examples:
44132
45804
  }
44133
45805
  __name(setupAuthCommands, "setupAuthCommands");
44134
45806
  function setupMarketplaceCommands(program2) {
44135
- program2.command("marketplace [role] [action]").description("\u{1F6CD}\uFE0F Browse, install, and manage marketplace skills").option("--skill-name <name>", "Skill name (for creator list, installer update/uninstall)").option("--display-name <name>", "Display name (for creator list/update)").option("--marketplace-id <id>", "Marketplace skill ID").option("--version-id <id>", "Version ID (for publish/install)").option("--changelog <text>", "Changelog for version (for publish)").option("--env-vars-json <json>", "JSON string with env var metadata (for creator publish)").option("--env-vars <pairs>", "Comma-separated key=value pairs (for installer)").option("--query <text>", "Search query (for search)").option("--page <n>", "Page number (for search)").option("--limit <n>", "Results per page (for search)").option("--json", "Output as JSON").option("--force", "Skip confirmation prompts").addHelpText("after", `
45807
+ program2.command("marketplace [noun] [action]").description("\u{1F6CD}\uFE0F Browse, install, and manage marketplace skills and agent templates").option("--skill-name <name>", "Skill name (for skill list/update/uninstall)").option("--marketplace-id <id>", "Marketplace skill ID").option("--version-id <id>", "Version ID (for skill publish/install)").option("--env-vars-json <json>", "JSON string with env var metadata (for skill publish)").option("--query <text>", "Search query (for skill search)").option("--page <n>", "Page number (for skill search)").option("--limit <n>", "Results per page (for skill search)").option("--name <name>", "Template name, an internal identifier (for template create)").option("--description <text>", "Description (for template create)").option("--template-id <id>", "Template ID").option("--source-version <n>", "Agent version to freeze into this template version (default: active) (for template publish)").option("--env-contract <pair>", "KEY=description env contract entry, repeatable; use KEY?=description for optional (for template publish)", (val, previous) => [
45808
+ ...previous,
45809
+ val
45810
+ ], []).option("--version <n>", "Template version (for template view/install/apply)").option("--allow-creator-updates", "Allow the template creator to push future updates onto this install").option("--skip-env-check", "Skip env-contract validation (for template install/apply)").option("--agents <ids>", "Comma-separated target agent IDs (for template apply)").option("--file <path>", "Path to a file with one target agent ID per line (for template apply)").option("--all-installed", "Target every agent that already has this template installed (for template apply)").option("--no-wait", "Print the apply runId immediately instead of polling for completion (for template apply)").option("--display-name <name>", "Display name (for skill list/edit, template create)").option("--visibility <visibility>", "Who can see and install it: public or private (for skill list, template create)").option("--changelog <text>", "Changelog for this version (for skill/template publish)").option("--env-vars <pairs>", "Comma-separated key=value pairs (for skill/template install/update)").option("--json", "Output as JSON").option("--force", "Skip confirmation prompts").addHelpText("after", `
44136
45811
  Arguments:
44137
- role Optional: 'create' or 'install' (prompts if not provided)
45812
+ noun Optional: 'skill' or 'template' (prompts if not provided)
44138
45813
  action Optional: specific action for non-interactive mode
44139
45814
 
44140
- Creator Actions:
44141
- list --skill-name <name> --display-name <name>
45815
+ Skill Actions:
45816
+ list --skill-name <name> --display-name <name> [--visibility public|private]
44142
45817
  publish --marketplace-id <id> --version-id <id> [--changelog <text>] [--env-vars-json <json>]
44143
- update --marketplace-id <id> --display-name <name>
45818
+ edit --marketplace-id <id> --display-name <name>
44144
45819
  unlist --marketplace-id <id> --force
44145
45820
  unpublish --marketplace-id <id> --version-id <id> --force
44146
- view [--json]
44147
-
44148
- Installer Actions:
45821
+ mine [--json]
44149
45822
  search [--query <text>] [--page <n>] [--limit <n>] [--json]
44150
45823
  view --marketplace-id <id> [--json]
44151
45824
  install --marketplace-id <id> --version-id <id> [--env-vars <k=v,...>] --force
@@ -44153,18 +45826,32 @@ Installer Actions:
44153
45826
  uninstall --skill-name <name> --force
44154
45827
  installed [--json]
44155
45828
 
45829
+ Template Actions:
45830
+ create --name <n> --display-name <n> [--description <text>] [--visibility public|private]
45831
+ publish --template-id <id> [--source-version <n>] [--changelog <text>] [--env-contract KEY=desc,...]
45832
+ view --template-id <id> [--version <n>] [--json]
45833
+ versions --template-id <id> [--json]
45834
+ install --template-id <id> [--version <n>] [--env-vars <k=v,...>] --force
45835
+ apply --template-id <id> [--version <n>] (--agents <a,b,c> | --file <path> | --all-installed) --force [--no-wait]
45836
+ status --template-id <id> [--json]
45837
+ installed [--json]
45838
+ uninstall --template-id <id> --force
45839
+
44156
45840
  Examples:
44157
- $ lua marketplace Interactive selection
44158
- $ lua marketplace create Creator menu
44159
- $ lua marketplace install Installer menu
44160
- $ lua marketplace create view View my listed skills
44161
- $ lua marketplace create list --skill-name mySkill --display-name "My Skill"
44162
- $ lua marketplace create publish --marketplace-id xyz --version-id v1
44163
- $ lua marketplace create unlist --marketplace-id xyz --force
44164
- $ lua marketplace install search --query "CRM"
44165
- $ lua marketplace install view --marketplace-id xyz --json
44166
- $ lua marketplace install install --marketplace-id xyz --version-id v1 --force
44167
- $ lua marketplace install installed --json
45841
+ $ lua marketplace Interactive domain selection
45842
+ $ lua marketplace skill Skill action menu
45843
+ $ lua marketplace skill mine View my listed skills
45844
+ $ lua marketplace skill list --skill-name mySkill --display-name "My Skill"
45845
+ $ lua marketplace skill publish --marketplace-id xyz --version-id v1
45846
+ $ lua marketplace skill unlist --marketplace-id xyz --force
45847
+ $ lua marketplace skill search --query "CRM"
45848
+ $ lua marketplace skill view --marketplace-id xyz --json
45849
+ $ lua marketplace skill install --marketplace-id xyz --version-id v1 --force
45850
+ $ lua marketplace skill installed --json
45851
+ $ lua marketplace template Template action menu
45852
+ $ lua marketplace template create --name support-bot --display-name "Support Bot"
45853
+ $ lua marketplace template publish --template-id xyz --changelog "Add refund skill"
45854
+ $ lua marketplace template apply --template-id xyz --all-installed --force
44168
45855
  `).action(marketplaceCommand);
44169
45856
  }
44170
45857
  __name(setupMarketplaceCommands, "setupMarketplaceCommands");
@@ -44307,20 +45994,16 @@ Examples:
44307
45994
  $ lua chat -b "Hello" "What is the weather?" "Tell me a joke" -d 2000 -e sandbox Batch test
44308
45995
  $ lua chat --agent-version 3 -m "test" Preview agent version 3 in an isolated thread
44309
45996
  `).action(chatCommand);
44310
- chatCmd.command("clear").description("Clear conversation history").option("--user <identifier>", "User ID, email, or mobile number of the user whose history to clear").option("-t, --thread <id>", "Clear a specific thread's history instead of all history").option("--force", "Skip confirmation prompt").addHelpText("after", `
45997
+ 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", `
44311
45998
  Examples:
44312
- $ lua chat clear Clear history
44313
- $ lua chat clear --force Clear history without confirmation
44314
- $ lua chat clear --user <userId> Clear user's history by user ID
44315
- $ lua chat clear --user <email> Clear user's history by email
44316
- $ lua chat clear --user <mobile> Clear user's history by mobile number
44317
- $ lua chat clear --user <userId> --force Clear user's history without confirmation
45999
+ $ lua chat clear Clear your history
46000
+ $ lua chat clear --force Clear your history without confirmation
44318
46001
  $ lua chat clear --thread <threadId> Clear a specific thread's history
44319
46002
  $ lua chat clear --thread <threadId> --force Clear a specific thread's history without confirmation
44320
46003
 
44321
46004
  Notes:
44322
- - User identifier can be UUID, email address, or mobile number
44323
- - Mobile numbers should be in international format without + (e.g., 919876543210)
46005
+ - This command only clears YOUR OWN conversation history
46006
+ - The --user option was removed: cross-user history clear is no longer supported
44324
46007
  `).action(chatClearCommand);
44325
46008
  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", `
44326
46009
  Arguments:
@@ -44773,6 +46456,10 @@ Examples:
44773
46456
  $ lua version promote 3 Promote v3 to the active version
44774
46457
  $ lua version promote v3 Same (v-prefix accepted)
44775
46458
  `).action((version) => versionPromoteCommand(version));
46459
+ versionGroup.command("status").description("Compare local primitives against the active agent version (what is pushed vs. live)").addHelpText("after", `
46460
+ Examples:
46461
+ $ lua version status Show which local primitives differ from the active version
46462
+ `).action(() => versionStatusCommand());
44776
46463
  versionGroup.command("delete <version>").description("Soft-delete a version").option("--force", "Skip confirmation prompt").addHelpText("after", `
44777
46464
  Examples:
44778
46465
  $ lua version delete 3 Delete v3 (confirms first)
@@ -44871,7 +46558,7 @@ if (isBareInvocation || isHelpInvocation) {
44871
46558
  });
44872
46559
  }
44873
46560
  var program = new Command();
44874
- program.showSuggestionAfterError().name("lua").description("Lua AI - Build and deploy AI agents with superpowers").version(CLI_VERSION).option("--ci", "CI/CD mode: fail loudly on missing required flags instead of prompting").addHelpText("after", `
46561
+ program.showSuggestionAfterError().name("lua").description("Lua AI - Build and deploy AI agents with superpowers").version(CLI_VERSION, "-V, --cli-version").option("--ci", "CI/CD mode: fail loudly on missing required flags instead of prompting").addHelpText("after", `
44875
46562
  Categories:
44876
46563
  \u{1F510} Authentication Manage API keys and authentication
44877
46564
  \u{1F680} Project Setup Initialize and configure projects
@@ -44913,7 +46600,8 @@ Examples:
44913
46600
  $ lua evals \u{1F4CA} Open evaluations dashboard
44914
46601
  $ lua docs \u{1F4D6} Open documentation
44915
46602
  $ lua completion \u{1F3AF} Enable shell autocomplete
44916
- $ lua marketplace \u{1F6CD}\uFE0F Interact with the Lua Marketplace
46603
+ $ lua marketplace \u{1F6CD}\uFE0F Interact with the Lua Marketplace (skills & agent templates)
46604
+ $ lua marketplace template \u{1F9E9} Create, publish, and apply marketplace agent templates
44917
46605
 
44918
46606
  \u{1F319} Documentation: https://docs.heylua.ai
44919
46607
  \u{1F319} Support: https://heylua.ai/support
@@ -44927,5 +46615,10 @@ program.hook("preAction", (thisCommand) => {
44927
46615
  setupAuthCommands(program);
44928
46616
  setupSkillCommands(program);
44929
46617
  setupMarketplaceCommands(program);
46618
+ var rawArgs = process.argv.slice(2);
46619
+ if (rawArgs.length === 1 && rawArgs[0] === "--version") {
46620
+ console.log(CLI_VERSION);
46621
+ process.exit(0);
46622
+ }
44930
46623
  program.parse(process.argv);
44931
46624
  //# sourceMappingURL=index.js.map