lua-cli 3.16.0 → 3.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4122,8 +4122,12 @@ var init_tool_plugin = __esm({
4122
4122
  displayName = "Tool";
4123
4123
  defineFunction = "defineTool";
4124
4124
  legacyClassNames = [
4125
- "LuaTool"
4125
+ "LuaTool",
4126
+ "LuaVoiceTool"
4126
4127
  ];
4128
+ crossFileRewrite = {
4129
+ copyAllFields: true
4130
+ };
4127
4131
  supportsClassDefinition = true;
4128
4132
  /**
4129
4133
  * Extract metadata from a `defineTool({...})` / `new LuaTool({...})`
@@ -4298,6 +4302,9 @@ var init_job_plugin = __esm({
4298
4302
  legacyClassNames = [
4299
4303
  "LuaJob"
4300
4304
  ];
4305
+ crossFileRewrite = {
4306
+ copyAllFields: true
4307
+ };
4301
4308
  supportsClassDefinition = true;
4302
4309
  /**
4303
4310
  * Class-definition extraction. Reads `name`/`description`/`schedule`/
@@ -4479,6 +4486,9 @@ var init_webhook_plugin = __esm({
4479
4486
  legacyClassNames = [
4480
4487
  "LuaWebhook"
4481
4488
  ];
4489
+ crossFileRewrite = {
4490
+ copyAllFields: true
4491
+ };
4482
4492
  supportsClassDefinition = true;
4483
4493
  /**
4484
4494
  * Class-definition shape: read fields off the inheritance chain
@@ -4705,6 +4715,9 @@ var init_preprocessor_plugin = __esm({
4705
4715
  "PreProcessor",
4706
4716
  "LuaPreprocessor"
4707
4717
  ];
4718
+ crossFileRewrite = {
4719
+ copyAllFields: true
4720
+ };
4708
4721
  /**
4709
4722
  * Class-definition extraction. Reads `name`/`description`/`async`/
4710
4723
  * `priority`/`execute` off the inheritance chain (most-derived wins).
@@ -4788,6 +4801,9 @@ var init_postprocessor_plugin = __esm({
4788
4801
  "PostProcessor",
4789
4802
  "LuaPostprocessor"
4790
4803
  ];
4804
+ crossFileRewrite = {
4805
+ copyAllFields: true
4806
+ };
4791
4807
  /**
4792
4808
  * Class-definition extraction. Reads `name`/`description`/`priority`/
4793
4809
  * `execute` off the inheritance chain.
@@ -4863,6 +4879,9 @@ var init_mcp_server_plugin = __esm({
4863
4879
  legacyClassNames = [
4864
4880
  "LuaMCPServer"
4865
4881
  ];
4882
+ crossFileRewrite = {
4883
+ copyAllFields: true
4884
+ };
4866
4885
  supportsClassDefinition = true;
4867
4886
  /**
4868
4887
  * Class-definition extraction. Reads `name`/`description`/`transport`/
@@ -6256,6 +6275,22 @@ var init_skill_plugin = __esm({
6256
6275
  legacyClassNames = [
6257
6276
  "LuaSkill"
6258
6277
  ];
6278
+ // Whitelist drops `tools` for the same reasons agent drops skills/webhooks/jobs:
6279
+ // 1. Bundle size — preserving class references drags tool source files into
6280
+ // the parent bundle.
6281
+ // 2. Residual super-edge cases — `stripSuperCallsInConstructors` covers
6282
+ // top-level `super(...)` only; `super.method()` mid-constructor and
6283
+ // `field = super.x` survive a strip and explode at runtime.
6284
+ // MAINTENANCE: this whitelist also assumes skills are JSON-only artifacts (via
6285
+ // `buildArtifact`). If skills ever migrate to bundled JS, this drop will silently
6286
+ // lose `tools` from skill bundles — re-evaluate.
6287
+ crossFileRewrite = {
6288
+ fields: [
6289
+ "name",
6290
+ "description",
6291
+ "context"
6292
+ ]
6293
+ };
6259
6294
  supportsClassDefinition = true;
6260
6295
  /**
6261
6296
  * Class-definition extraction. Reads `name`/`description`/`context`/
@@ -6647,6 +6682,22 @@ var init_agent_plugin = __esm({
6647
6682
  legacyClassNames = [
6648
6683
  "LuaAgent"
6649
6684
  ];
6685
+ // Whitelist (not copyAllFields). Two reasons, both real:
6686
+ // 1. Bundle size — `skills`/`webhooks`/`jobs`/etc. hold CLASS references;
6687
+ // preserving them drags every subclass source file into the agent bundle.
6688
+ // 2. Residual super-edge cases — `stripSuperCallsInConstructors` handles
6689
+ // top-level `super(...)`, but NOT `super.method()` mid-constructor or
6690
+ // `field = super.x` initializers, both of which still orphan after
6691
+ // `stripSdkExtendsClauses` runs on dragged-in files.
6692
+ // Agent runtime only needs name/persona/model; references are resolved by `resolveArrayRefs`.
6693
+ crossFileRewrite = {
6694
+ fields: [
6695
+ "name",
6696
+ "description",
6697
+ "persona",
6698
+ "model"
6699
+ ]
6700
+ };
6650
6701
  supportsClassDefinition = true;
6651
6702
  /**
6652
6703
  * Class-definition extraction. Reads the agent's own metadata
@@ -6993,6 +7044,9 @@ var init_device_plugin = __esm({
6993
7044
  legacyClassNames = [
6994
7045
  "LuaDevice"
6995
7046
  ];
7047
+ crossFileRewrite = {
7048
+ copyAllFields: true
7049
+ };
6996
7050
  supportsClassDefinition = true;
6997
7051
  /**
6998
7052
  * Class-definition extraction. Reads `name`/`description`/`group`
@@ -7115,6 +7169,9 @@ var init_device_trigger_plugin = __esm({
7115
7169
  legacyClassNames = [
7116
7170
  "LuaDeviceTrigger"
7117
7171
  ];
7172
+ crossFileRewrite = {
7173
+ copyAllFields: true
7174
+ };
7118
7175
  supportsClassDefinition = true;
7119
7176
  /**
7120
7177
  * Class-definition extraction. Reads `name`/`description`/has-flags
@@ -7255,13 +7312,355 @@ var init_device_trigger_plugin = __esm({
7255
7312
  }
7256
7313
  });
7257
7314
 
7315
+ // src/compiler/utils/primitive-rewrite.ts
7316
+ import { readFileSync as readFileSync8 } from "fs";
7317
+ import { Node as Node14, Project, ts as ts3 } from "ts-morph";
7318
+ function rewritePrimitiveSource(metadata, opts) {
7319
+ const sourceCode = readFileSync8(metadata.sourcePath, "utf-8");
7320
+ const localProject = new Project({
7321
+ useInMemoryFileSystem: true,
7322
+ compilerOptions: {
7323
+ allowJs: true,
7324
+ target: 99,
7325
+ module: 99
7326
+ }
7327
+ });
7328
+ const sf = localProject.createSourceFile(`__rewrite_${metadata.kind}_${metadata.name}.ts`, sourceCode);
7329
+ const isPrimitiveCall = /* @__PURE__ */ __name((n) => {
7330
+ if (Node14.isNewExpression(n)) {
7331
+ const callee = n.getExpression();
7332
+ return Node14.isIdentifier(callee) && opts.constructorNames.includes(callee.getText());
7333
+ }
7334
+ if (Node14.isCallExpression(n)) {
7335
+ const callee = n.getExpression();
7336
+ return Node14.isIdentifier(callee) && opts.defineFunctionName !== void 0 && callee.getText() === opts.defineFunctionName;
7337
+ }
7338
+ return false;
7339
+ }, "isPrimitiveCall");
7340
+ const callNode = findCallByExportName(sf, metadata, isPrimitiveCall);
7341
+ if (!callNode) {
7342
+ throw new Error(`Primitive call for export "${metadata.exportName}" (kind=${metadata.kind}) not found in ${metadata.sourcePath}`);
7343
+ }
7344
+ const arg = callNode.getArguments()[0];
7345
+ if (!arg || !Node14.isObjectLiteralExpression(arg)) {
7346
+ throw new Error(`Primitive config arg is not an object literal in ${metadata.sourcePath}`);
7347
+ }
7348
+ const synthesized = opts.buildLiteral(arg, {
7349
+ metadata,
7350
+ compilerVersion: COMPILER_VERSION
7351
+ });
7352
+ callNode.replaceWithText(synthesized);
7353
+ sf.forEachDescendant((n) => {
7354
+ if (n === callNode) return;
7355
+ if (isPrimitiveCall(n)) n.replaceWithText("undefined");
7356
+ });
7357
+ rewriteCrossFileCallsInSourceFile(sf, opts.crossFileSpecs, opts.sdkBaseClassNames);
7358
+ stripLuaCliImports(sf);
7359
+ ensureDefaultExport(sf, metadata);
7360
+ return sf.getText();
7361
+ }
7362
+ function rewriteCrossFileCallsInSourceFile(sf, specs, sdkBaseClassNames) {
7363
+ warnUnsupportedNamespaceImports(sf);
7364
+ const sdkIdentifiers = new Set(sdkBaseClassNames);
7365
+ for (const spec of specs) {
7366
+ if (spec.defineFunction) sdkIdentifiers.add(spec.defineFunction);
7367
+ }
7368
+ const aliasMap = buildSdkAliasMap(sf, sdkIdentifiers);
7369
+ let progressed = true;
7370
+ while (progressed) {
7371
+ progressed = false;
7372
+ const callNode = findFirstCrossFileSdkCall(sf, specs, aliasMap);
7373
+ if (!callNode) break;
7374
+ const spec = callNode.spec;
7375
+ const node = callNode.node;
7376
+ const arg = node.getArguments()[0];
7377
+ const objArg = arg && Node14.isObjectLiteralExpression(arg) ? arg : void 0;
7378
+ node.replaceWithText(buildBareObjectLiteral(spec, objArg));
7379
+ progressed = true;
7380
+ }
7381
+ stripSdkExtendsClauses(sf, sdkBaseClassNames, aliasMap);
7382
+ }
7383
+ function warnUnsupportedNamespaceImports(sf) {
7384
+ for (const imp of sf.getImportDeclarations()) {
7385
+ const spec = imp.getModuleSpecifierValue();
7386
+ if (spec !== "lua-cli" && spec !== "lua-cli/skill" && spec !== "lua-cli/voice") continue;
7387
+ const ns = imp.getNamespaceImport();
7388
+ if (!ns) continue;
7389
+ const localName = ns.getText();
7390
+ const pos = sf.getLineAndColumnAtPos(imp.getStart());
7391
+ console.warn(formatSarifWarning({
7392
+ ruleId: "lua/unsupported-namespace-import",
7393
+ filePath: sf.getFilePath(),
7394
+ line: pos.line,
7395
+ column: pos.column,
7396
+ message: `namespace import \`import * as ${localName} from '${spec}'\` is not supported by the cross-file rewrite. \`new ${localName}.X({...})\` calls will leak \`${localName}\` into the bundle as an undefined identifier.`,
7397
+ hint: `Use named imports instead: \`import { LuaTool, LuaWebhook, ... } from '${spec}'\`.`
7398
+ }));
7399
+ }
7400
+ }
7401
+ function stripSdkExtendsClauses(sf, sdkBaseClassNames, aliasMap) {
7402
+ const matchesSdkClass = /* @__PURE__ */ __name((text) => {
7403
+ const canonical = aliasMap.get(text) ?? text;
7404
+ return sdkBaseClassNames.has(canonical);
7405
+ }, "matchesSdkClass");
7406
+ for (const classDecl of sf.getClasses()) {
7407
+ const ext = classDecl.getExtends();
7408
+ if (!ext) continue;
7409
+ const expr = ext.getExpression();
7410
+ if (!Node14.isIdentifier(expr)) continue;
7411
+ if (matchesSdkClass(expr.getText())) {
7412
+ classDecl.removeExtends();
7413
+ stripSuperCallsInConstructors(classDecl);
7414
+ }
7415
+ }
7416
+ sf.forEachDescendant((n) => {
7417
+ if (!Node14.isClassExpression(n)) return;
7418
+ const ext = n.getExtends();
7419
+ if (!ext) return;
7420
+ const expr = ext.getExpression();
7421
+ if (!Node14.isIdentifier(expr)) return;
7422
+ if (matchesSdkClass(expr.getText())) {
7423
+ n.removeExtends();
7424
+ stripSuperCallsInConstructors(n);
7425
+ }
7426
+ });
7427
+ }
7428
+ function stripSuperCallsInConstructors(classNode) {
7429
+ for (const ctor of classNode.getConstructors()) {
7430
+ const body = ctor.getBody();
7431
+ if (!body || !Node14.isBlock(body)) continue;
7432
+ const toRemove = [];
7433
+ for (const stmt of body.getStatements()) {
7434
+ if (!Node14.isExpressionStatement(stmt)) continue;
7435
+ const expr = stmt.getExpression();
7436
+ if (!Node14.isCallExpression(expr)) continue;
7437
+ if (expr.getExpression().getKind() !== ts3.SyntaxKind.SuperKeyword) continue;
7438
+ toRemove.push(stmt);
7439
+ }
7440
+ for (const stmt of toRemove) stmt.remove();
7441
+ }
7442
+ warnRemainingSuperReferences(classNode);
7443
+ }
7444
+ function warnRemainingSuperReferences(classNode) {
7445
+ const sf = classNode.getSourceFile();
7446
+ classNode.forEachDescendant((n) => {
7447
+ if (n.getKind() !== ts3.SyntaxKind.SuperKeyword) return;
7448
+ const parent = n.getParent();
7449
+ if (parent && Node14.isCallExpression(parent) && parent.getExpression() === n && Node14.isExpressionStatement(parent.getParent())) {
7450
+ return;
7451
+ }
7452
+ const pos = sf.getLineAndColumnAtPos(n.getStart());
7453
+ console.warn(formatSarifWarning({
7454
+ ruleId: "lua/orphan-super-reference",
7455
+ filePath: sf.getFilePath(),
7456
+ line: pos.line,
7457
+ column: pos.column,
7458
+ message: `\`super\` reference will become orphan after the SDK base class is stripped from the bundle. The compiled artifact will throw \`SyntaxError: 'super' keyword is only allowed in a derived class\` at sandbox eval.`,
7459
+ hint: `Move the override into a class field initializer (the canonical subclass-with-field-override pattern), or stop subclassing the SDK base and use the \`defineX({...})\` / \`new LuaX({...})\` form.`
7460
+ }));
7461
+ });
7462
+ }
7463
+ function buildSdkAliasMap(sf, sdkIdentifiers) {
7464
+ const map = /* @__PURE__ */ new Map();
7465
+ for (const imp of sf.getImportDeclarations()) {
7466
+ const spec = imp.getModuleSpecifierValue();
7467
+ if (spec !== "lua-cli" && spec !== "lua-cli/skill" && spec !== "lua-cli/voice") continue;
7468
+ for (const named of imp.getNamedImports()) {
7469
+ const exported = named.getName();
7470
+ const alias = named.getAliasNode()?.getText();
7471
+ if (!sdkIdentifiers.has(exported)) continue;
7472
+ const local = alias ?? exported;
7473
+ map.set(local, exported);
7474
+ }
7475
+ }
7476
+ let progressed = true;
7477
+ while (progressed) {
7478
+ progressed = false;
7479
+ for (const vd of sf.getVariableDeclarations()) {
7480
+ const init = vd.getInitializer();
7481
+ if (!init || !Node14.isIdentifier(init)) continue;
7482
+ const name = vd.getName();
7483
+ if (map.has(name)) continue;
7484
+ const initText = init.getText();
7485
+ const canonical = map.get(initText) ?? (sdkIdentifiers.has(initText) ? initText : void 0);
7486
+ if (canonical) {
7487
+ map.set(name, canonical);
7488
+ progressed = true;
7489
+ }
7490
+ }
7491
+ }
7492
+ return map;
7493
+ }
7494
+ function findFirstCrossFileSdkCall(sf, specs, aliasMap) {
7495
+ let found;
7496
+ sf.forEachDescendant((n) => {
7497
+ if (found) return;
7498
+ if (Node14.isNewExpression(n)) {
7499
+ const callee = n.getExpression();
7500
+ if (!Node14.isIdentifier(callee)) return;
7501
+ const canonical = aliasMap.get(callee.getText()) ?? callee.getText();
7502
+ const spec = specs.find((s) => s.classNames.includes(canonical));
7503
+ if (spec) found = {
7504
+ node: n,
7505
+ spec
7506
+ };
7507
+ } else if (Node14.isCallExpression(n)) {
7508
+ const callee = n.getExpression();
7509
+ if (!Node14.isIdentifier(callee)) return;
7510
+ const canonical = aliasMap.get(callee.getText()) ?? callee.getText();
7511
+ const spec = specs.find((s) => s.defineFunction !== void 0 && s.defineFunction === canonical);
7512
+ if (spec) found = {
7513
+ node: n,
7514
+ spec
7515
+ };
7516
+ }
7517
+ });
7518
+ return found;
7519
+ }
7520
+ function buildBareObjectLiteral(spec, arg) {
7521
+ if (!arg) return "{}";
7522
+ if (spec.mode === "copyAllFields") {
7523
+ return arg.getText();
7524
+ }
7525
+ const parts = [];
7526
+ for (const f of spec.fields) {
7527
+ const prop = arg.getProperty(f);
7528
+ if (prop && Node14.isPropertyAssignment(prop)) {
7529
+ const init = prop.getInitializer();
7530
+ if (init) parts.push(`${f}: ${init.getText()}`);
7531
+ } else if (prop && Node14.isShorthandPropertyAssignment(prop)) {
7532
+ parts.push(`${f}: ${prop.getName()}`);
7533
+ }
7534
+ }
7535
+ return `{ ${parts.join(", ")} }`;
7536
+ }
7537
+ function findCallByExportName(sf, metadata, isPrimitiveCall) {
7538
+ if (metadata.isDefaultExport) {
7539
+ for (const stmt of sf.getStatements()) {
7540
+ if (!Node14.isExportAssignment(stmt)) continue;
7541
+ const expr = stmt.getExpression();
7542
+ if (isPrimitiveCall(expr)) return expr;
7543
+ if (Node14.isIdentifier(expr)) {
7544
+ const varDecl2 = sf.getVariableDeclaration(expr.getText());
7545
+ const init2 = varDecl2?.getInitializer();
7546
+ if (init2 && isPrimitiveCall(init2)) return init2;
7547
+ }
7548
+ }
7549
+ return void 0;
7550
+ }
7551
+ const varDecl = sf.getVariableDeclaration(metadata.exportName);
7552
+ const init = varDecl?.getInitializer();
7553
+ if (init && isPrimitiveCall(init)) return init;
7554
+ return void 0;
7555
+ }
7556
+ function stripLuaCliImports(sf) {
7557
+ for (const imp of sf.getImportDeclarations()) {
7558
+ const spec = imp.getModuleSpecifierValue();
7559
+ if (spec === "lua-cli" || spec === "lua-cli/skill" || spec === "lua-cli/voice") {
7560
+ imp.remove();
7561
+ }
7562
+ }
7563
+ }
7564
+ function ensureDefaultExport(sf, metadata) {
7565
+ if (metadata.isDefaultExport) return;
7566
+ const existingDefault = sf.getStatements().find(Node14.isExportAssignment);
7567
+ if (!existingDefault) {
7568
+ sf.addStatements(`
7569
+ export default ${metadata.exportName};`);
7570
+ return;
7571
+ }
7572
+ const expr = existingDefault.getExpression();
7573
+ const alreadyCorrect = Node14.isIdentifier(expr) && expr.getText() === metadata.exportName;
7574
+ if (!alreadyCorrect) {
7575
+ existingDefault.remove();
7576
+ sf.addStatements(`
7577
+ export default ${metadata.exportName};`);
7578
+ }
7579
+ }
7580
+ function getPropertyText(arg, name) {
7581
+ const prop = arg.getProperty(name);
7582
+ if (prop && Node14.isPropertyAssignment(prop)) {
7583
+ return prop.getInitializer()?.getText();
7584
+ }
7585
+ if (prop && Node14.isShorthandPropertyAssignment(prop)) {
7586
+ return prop.getName();
7587
+ }
7588
+ return void 0;
7589
+ }
7590
+ function buildLuaPrimitiveMarker(metadata, kind) {
7591
+ return `__lua_primitive__: { version: ${JSON.stringify(COMPILER_VERSION)}, kind: '${kind}', name: ${JSON.stringify(metadata.name)}, description: ${JSON.stringify(metadata.description)}, exportName: ${JSON.stringify(metadata.exportName)} }`;
7592
+ }
7593
+ var init_primitive_rewrite = __esm({
7594
+ "src/compiler/utils/primitive-rewrite.ts"() {
7595
+ "use strict";
7596
+ init_types();
7597
+ init_reference_resolver();
7598
+ __name(rewritePrimitiveSource, "rewritePrimitiveSource");
7599
+ __name(rewriteCrossFileCallsInSourceFile, "rewriteCrossFileCallsInSourceFile");
7600
+ __name(warnUnsupportedNamespaceImports, "warnUnsupportedNamespaceImports");
7601
+ __name(stripSdkExtendsClauses, "stripSdkExtendsClauses");
7602
+ __name(stripSuperCallsInConstructors, "stripSuperCallsInConstructors");
7603
+ __name(warnRemainingSuperReferences, "warnRemainingSuperReferences");
7604
+ __name(buildSdkAliasMap, "buildSdkAliasMap");
7605
+ __name(findFirstCrossFileSdkCall, "findFirstCrossFileSdkCall");
7606
+ __name(buildBareObjectLiteral, "buildBareObjectLiteral");
7607
+ __name(findCallByExportName, "findCallByExportName");
7608
+ __name(stripLuaCliImports, "stripLuaCliImports");
7609
+ __name(ensureDefaultExport, "ensureDefaultExport");
7610
+ __name(getPropertyText, "getPropertyText");
7611
+ __name(buildLuaPrimitiveMarker, "buildLuaPrimitiveMarker");
7612
+ }
7613
+ });
7614
+
7615
+ // src/compiler/utils/cross-file-specs.ts
7616
+ function buildCrossFileSpecs(plugins = pluginRegistry.getAll()) {
7617
+ const specs = [];
7618
+ for (const plugin of plugins) {
7619
+ if (!plugin.crossFileRewrite) continue;
7620
+ const classNames = [
7621
+ ...plugin.legacyClassNames
7622
+ ];
7623
+ const defineFunction = plugin.defineFunction || void 0;
7624
+ if ("copyAllFields" in plugin.crossFileRewrite && plugin.crossFileRewrite.copyAllFields) {
7625
+ specs.push({
7626
+ classNames,
7627
+ defineFunction,
7628
+ mode: "copyAllFields"
7629
+ });
7630
+ } else if ("fields" in plugin.crossFileRewrite) {
7631
+ specs.push({
7632
+ classNames,
7633
+ defineFunction,
7634
+ mode: "whitelist",
7635
+ fields: plugin.crossFileRewrite.fields
7636
+ });
7637
+ }
7638
+ }
7639
+ return specs;
7640
+ }
7641
+ function buildSdkBaseClassNames(plugins = pluginRegistry.getAll()) {
7642
+ const names = /* @__PURE__ */ new Set();
7643
+ for (const plugin of plugins) {
7644
+ for (const cls of plugin.legacyClassNames) names.add(cls);
7645
+ }
7646
+ return names;
7647
+ }
7648
+ var init_cross_file_specs = __esm({
7649
+ "src/compiler/utils/cross-file-specs.ts"() {
7650
+ "use strict";
7651
+ init_registry();
7652
+ __name(buildCrossFileSpecs, "buildCrossFileSpecs");
7653
+ __name(buildSdkBaseClassNames, "buildSdkBaseClassNames");
7654
+ }
7655
+ });
7656
+
7258
7657
  // src/compiler/plugins/voice.plugin.ts
7259
7658
  import fs5 from "fs/promises";
7260
- import { Node as Node14 } from "ts-morph";
7659
+ import { Node as Node15 } from "ts-morph";
7261
7660
  function astObjectToPlain(obj) {
7262
7661
  const result = {};
7263
7662
  for (const prop of obj.getProperties()) {
7264
- if (Node14.isSpreadAssignment(prop)) {
7663
+ if (Node15.isSpreadAssignment(prop)) {
7265
7664
  const expr = prop.getExpression();
7266
7665
  const evaluated = astValueToPlain(expr);
7267
7666
  if (evaluated && typeof evaluated === "object" && !Array.isArray(evaluated)) {
@@ -7269,14 +7668,14 @@ function astObjectToPlain(obj) {
7269
7668
  }
7270
7669
  continue;
7271
7670
  }
7272
- if (Node14.isShorthandPropertyAssignment(prop)) {
7671
+ if (Node15.isShorthandPropertyAssignment(prop)) {
7273
7672
  const key2 = prop.getName();
7274
7673
  if (!key2) continue;
7275
7674
  const v2 = astValueToPlain(prop.getNameNode());
7276
7675
  if (v2 !== void 0) result[key2] = v2;
7277
7676
  continue;
7278
7677
  }
7279
- if (!Node14.isPropertyAssignment(prop)) continue;
7678
+ if (!Node15.isPropertyAssignment(prop)) continue;
7280
7679
  const key = prop.getName();
7281
7680
  if (!key) continue;
7282
7681
  const value = prop.getInitializer();
@@ -7287,16 +7686,16 @@ function astObjectToPlain(obj) {
7287
7686
  return result;
7288
7687
  }
7289
7688
  function astValueToPlain(value) {
7290
- if (Node14.isStringLiteral(value) || Node14.isNoSubstitutionTemplateLiteral(value)) {
7689
+ if (Node15.isStringLiteral(value) || Node15.isNoSubstitutionTemplateLiteral(value)) {
7291
7690
  return value.getLiteralText();
7292
7691
  }
7293
- if (Node14.isNumericLiteral(value)) {
7692
+ if (Node15.isNumericLiteral(value)) {
7294
7693
  return Number(value.getLiteralText());
7295
7694
  }
7296
- if (Node14.isTrueLiteral(value)) return true;
7297
- if (Node14.isFalseLiteral(value)) return false;
7298
- if (Node14.isObjectLiteralExpression(value)) return astObjectToPlain(value);
7299
- if (Node14.isArrayLiteralExpression(value)) {
7695
+ if (Node15.isTrueLiteral(value)) return true;
7696
+ if (Node15.isFalseLiteral(value)) return false;
7697
+ if (Node15.isObjectLiteralExpression(value)) return astObjectToPlain(value);
7698
+ if (Node15.isArrayLiteralExpression(value)) {
7300
7699
  return value.getElements().map((el) => astValueToPlain(el)).filter((x) => x !== void 0);
7301
7700
  }
7302
7701
  return void 0;
@@ -7355,15 +7754,36 @@ function stripKeys(obj, keys) {
7355
7754
  }
7356
7755
  function leftmostIdentifierName(node) {
7357
7756
  let current = node;
7358
- while (Node14.isPropertyAccessExpression(current)) {
7757
+ while (Node15.isPropertyAccessExpression(current)) {
7359
7758
  current = current.getExpression();
7360
7759
  }
7361
- return Node14.isIdentifier(current) ? current.getText() : void 0;
7760
+ return Node15.isIdentifier(current) ? current.getText() : void 0;
7761
+ }
7762
+ function resolveProviderAlias(node, localName) {
7763
+ const sourceFile = node.getSourceFile();
7764
+ for (const imp of sourceFile.getImportDeclarations()) {
7765
+ const moduleSpec = imp.getModuleSpecifierValue();
7766
+ const livekitPlugin = moduleSpec.startsWith("@livekit/agents-plugin-");
7767
+ const isLuaCliVoice = moduleSpec === "lua-cli/voice";
7768
+ const isLivekitAgents = moduleSpec === "@livekit/agents";
7769
+ if (!isLuaCliVoice && !livekitPlugin && !isLivekitAgents) continue;
7770
+ for (const named of imp.getNamedImports()) {
7771
+ const alias = named.getAliasNode()?.getText();
7772
+ const exported = named.getName();
7773
+ const bound = alias ?? exported;
7774
+ if (bound === localName) return exported;
7775
+ }
7776
+ const ns = imp.getNamespaceImport();
7777
+ if (ns && ns.getText() === localName && livekitPlugin) {
7778
+ return moduleSpec.replace("@livekit/agents-plugin-", "");
7779
+ }
7780
+ }
7781
+ return localName;
7362
7782
  }
7363
7783
  function extractRealtimeFromNewExpression(newExpr, classExpr, field) {
7364
7784
  if (classExpr.getName() !== "RealtimeModel") return void 0;
7365
7785
  const realtimeNode = classExpr.getExpression();
7366
- if (!Node14.isPropertyAccessExpression(realtimeNode) || realtimeNode.getName() !== "realtime") {
7786
+ if (!Node15.isPropertyAccessExpression(realtimeNode) || realtimeNode.getName() !== "realtime") {
7367
7787
  return void 0;
7368
7788
  }
7369
7789
  if (field !== "llm") {
@@ -7374,7 +7794,8 @@ function extractRealtimeFromNewExpression(newExpr, classExpr, field) {
7374
7794
  }
7375
7795
  };
7376
7796
  }
7377
- const provider = leftmostIdentifierName(realtimeNode.getExpression());
7797
+ const providerLocal = leftmostIdentifierName(realtimeNode.getExpression());
7798
+ const provider = providerLocal ? resolveProviderAlias(realtimeNode, providerLocal) : void 0;
7378
7799
  if (!provider) {
7379
7800
  return {
7380
7801
  error: {
@@ -7393,7 +7814,7 @@ function extractRealtimeFromNewExpression(newExpr, classExpr, field) {
7393
7814
  }
7394
7815
  const optsArg = newExpr.getArguments()[0];
7395
7816
  let options = {};
7396
- if (optsArg && Node14.isObjectLiteralExpression(optsArg)) {
7817
+ if (optsArg && Node15.isObjectLiteralExpression(optsArg)) {
7397
7818
  options = astObjectToPlain(optsArg);
7398
7819
  }
7399
7820
  return {
@@ -7406,7 +7827,7 @@ function extractRealtimeFromNewExpression(newExpr, classExpr, field) {
7406
7827
  }
7407
7828
  function extractFromNewExpression(newExpr, field) {
7408
7829
  const expr = newExpr.getExpression();
7409
- if (!Node14.isPropertyAccessExpression(expr)) {
7830
+ if (!Node15.isPropertyAccessExpression(expr)) {
7410
7831
  return {
7411
7832
  error: {
7412
7833
  field,
@@ -7416,7 +7837,7 @@ function extractFromNewExpression(newExpr, field) {
7416
7837
  }
7417
7838
  const realtimeResult = extractRealtimeFromNewExpression(newExpr, expr, field);
7418
7839
  if (realtimeResult) return realtimeResult;
7419
- const moduleName = expr.getExpression().getText();
7840
+ const moduleName = resolveProviderAlias(expr, expr.getExpression().getText());
7420
7841
  const className = expr.getName();
7421
7842
  if (!PLUGIN_CLASSES.includes(className)) {
7422
7843
  return {
@@ -7436,7 +7857,7 @@ function extractFromNewExpression(newExpr, field) {
7436
7857
  }
7437
7858
  const optsArg = newExpr.getArguments()[0];
7438
7859
  let options = {};
7439
- if (optsArg && Node14.isObjectLiteralExpression(optsArg)) {
7860
+ if (optsArg && Node15.isObjectLiteralExpression(optsArg)) {
7440
7861
  options = astObjectToPlain(optsArg);
7441
7862
  }
7442
7863
  if (moduleName === "inference") {
@@ -7484,7 +7905,7 @@ function extractFromNewExpression(newExpr, field) {
7484
7905
  }
7485
7906
  function unwrapType(node) {
7486
7907
  let current = node;
7487
- while (Node14.isAsExpression(current) || Node14.isSatisfiesExpression(current) || Node14.isParenthesizedExpression(current)) {
7908
+ while (Node15.isAsExpression(current) || Node15.isSatisfiesExpression(current) || Node15.isParenthesizedExpression(current)) {
7488
7909
  const inner = current.getExpression?.();
7489
7910
  if (!inner) break;
7490
7911
  current = inner;
@@ -7493,11 +7914,11 @@ function unwrapType(node) {
7493
7914
  }
7494
7915
  function extractModelField(config, field) {
7495
7916
  const prop = config.getProperty(field);
7496
- if (!prop || !Node14.isPropertyAssignment(prop)) return {};
7917
+ if (!prop || !Node15.isPropertyAssignment(prop)) return {};
7497
7918
  const initializer = prop.getInitializer();
7498
7919
  if (!initializer) return {};
7499
7920
  const value = unwrapType(initializer);
7500
- if (Node14.isStringLiteral(value) || Node14.isNoSubstitutionTemplateLiteral(value)) {
7921
+ if (Node15.isStringLiteral(value) || Node15.isNoSubstitutionTemplateLiteral(value)) {
7501
7922
  const text = value.getLiteralText();
7502
7923
  if (!text) {
7503
7924
  return {
@@ -7509,7 +7930,7 @@ function extractModelField(config, field) {
7509
7930
  }
7510
7931
  return parseDescriptor(text, field);
7511
7932
  }
7512
- if (Node14.isObjectLiteralExpression(value)) {
7933
+ if (Node15.isObjectLiteralExpression(value)) {
7513
7934
  if (field !== "tts") {
7514
7935
  return {
7515
7936
  error: {
@@ -7536,7 +7957,7 @@ function extractModelField(config, field) {
7536
7957
  model: out
7537
7958
  };
7538
7959
  }
7539
- if (Node14.isNewExpression(value)) {
7960
+ if (Node15.isNewExpression(value)) {
7540
7961
  return extractFromNewExpression(value, field);
7541
7962
  }
7542
7963
  return {
@@ -7549,20 +7970,23 @@ function extractModelField(config, field) {
7549
7970
  function hasFunctionProperty(config, propertyName) {
7550
7971
  const prop = config.getProperty(propertyName);
7551
7972
  if (!prop) return false;
7552
- if (Node14.isMethodDeclaration(prop)) return true;
7553
- if (!Node14.isPropertyAssignment(prop)) return false;
7973
+ if (Node15.isMethodDeclaration(prop)) return true;
7974
+ if (!Node15.isPropertyAssignment(prop)) return false;
7554
7975
  const value = prop.getInitializer();
7555
7976
  if (!value) return false;
7556
- if (Node14.isArrowFunction(value) || Node14.isFunctionExpression(value)) return true;
7557
- if (Node14.isIdentifier(value)) return true;
7977
+ if (Node15.isArrowFunction(value) || Node15.isFunctionExpression(value)) return true;
7978
+ if (Node15.isIdentifier(value)) return true;
7558
7979
  return false;
7559
7980
  }
7560
7981
  function hasArrayProperty(config, propertyName) {
7561
7982
  const prop = config.getProperty(propertyName);
7562
- if (!prop || !Node14.isPropertyAssignment(prop)) return false;
7983
+ if (!prop || !Node15.isPropertyAssignment(prop)) return false;
7563
7984
  const value = prop.getInitializer();
7564
7985
  if (!value) return false;
7565
- return Node14.isArrayLiteralExpression(value);
7986
+ if (Node15.isArrayLiteralExpression(value)) return value.getElements().length > 0;
7987
+ if (Node15.isNullLiteral(value)) return false;
7988
+ if (Node15.isIdentifier(value) && value.getText() === "undefined") return false;
7989
+ return true;
7566
7990
  }
7567
7991
  function normalizePronunciations(raw) {
7568
7992
  if (!raw) return {
@@ -7588,6 +8012,8 @@ var init_voice_plugin = __esm({
7588
8012
  "src/compiler/plugins/voice.plugin.ts"() {
7589
8013
  "use strict";
7590
8014
  init_dist();
8015
+ init_primitive_rewrite();
8016
+ init_cross_file_specs();
7591
8017
  init_types();
7592
8018
  init_ast_helpers();
7593
8019
  init_common();
@@ -7618,6 +8044,7 @@ var init_voice_plugin = __esm({
7618
8044
  __name(parseDescriptor, "parseDescriptor");
7619
8045
  __name(stripKeys, "stripKeys");
7620
8046
  __name(leftmostIdentifierName, "leftmostIdentifierName");
8047
+ __name(resolveProviderAlias, "resolveProviderAlias");
7621
8048
  __name(extractRealtimeFromNewExpression, "extractRealtimeFromNewExpression");
7622
8049
  __name(extractFromNewExpression, "extractFromNewExpression");
7623
8050
  __name(unwrapType, "unwrapType");
@@ -7635,6 +8062,14 @@ var init_voice_plugin = __esm({
7635
8062
  legacyClassNames = [
7636
8063
  "LuaVoice"
7637
8064
  ];
8065
+ // Voice's cross-file rewrite uses a narrow whitelist because configs can
8066
+ // have nested provider SDK calls (new deepgram.STT, new elevenlabs.TTS)
8067
+ // that the top-level rewrite (in generateEntryPoint) handles separately.
8068
+ crossFileRewrite = {
8069
+ fields: [
8070
+ "name"
8071
+ ]
8072
+ };
7638
8073
  extractFromConfig(config, exportName, sourcePath, position, pattern) {
7639
8074
  const common = this.extractCommonFields(config, exportName, sourcePath, position);
7640
8075
  if (!common) return null;
@@ -7775,43 +8210,45 @@ var init_voice_plugin = __esm({
7775
8210
  };
7776
8211
  }
7777
8212
  /**
7778
- * Entry-point emitter for the bundled JS path. Imports the dev's
7779
- * LuaVoice instance and re-exports its hooks + voice-only tools in
7780
- * the flat shape the worker sandbox expects (sandbox.ts:extractExports).
8213
+ * Entry-point emitter for hook-bearing voices.
8214
+ *
8215
+ * Architecturally, the bundle must NOT re-evaluate `new LuaVoice({...})` in
8216
+ * the worker sandbox — that call's only purpose is compile-time metadata
8217
+ * extraction (provider/class/options for stt/tts/llm), and re-running it
8218
+ * with stripped SDK imports requires runtime stub injection (a Proxy that
8219
+ * covers only a fraction of the dev's possible introspection patterns).
7781
8220
  *
7782
- * Tools land as a name-keyed map; sandbox.normalizeTools also accepts
7783
- * arrays, but pre-normalizing here avoids one walk per session start
7784
- * and keeps the bundle's wire shape obvious to anyone inspecting it.
8221
+ * Instead, this method does a source-level AST rewrite:
8222
+ * 1. Parse the dev's source file
8223
+ * 2. Find the LuaVoice / defineVoice call site
8224
+ * 3. Splice the hook function-expression texts + tool entries directly
8225
+ * into a synthesized `{ __lua_primitive__, onEnter, ..., tools }`
8226
+ * object literal at the same module-scope position
8227
+ * 4. Strip the stripped lua-cli / lua-cli/voice imports
8228
+ *
8229
+ * Closure references (module-level helpers, consts, types) survive
8230
+ * because the splice happens at the same lexical position as the
8231
+ * original call site.
7785
8232
  *
7786
8233
  * Only invoked by the compiler when `buildArtifact` returns undefined
7787
- * (i.e. when the voice declares hooks or voice-only tools) — see
7788
- * the conditional in `buildArtifact` below.
8234
+ * (i.e. when the voice declares hooks or voice-only tools).
7789
8235
  */
7790
8236
  generateEntryPoint(metadata) {
7791
- const importStatement = metadata.isDefaultExport ? `import __voice__ from ${JSON.stringify(metadata.sourcePath)};` : `import { __lua_target__ as __voice__ } from ${JSON.stringify(metadata.sourcePath)};`;
7792
- return `// AUTO-GENERATED ENTRY POINT \u2014 Voice: ${metadata.name}
7793
- ${importStatement}
7794
-
7795
- const __luaTools = {};
7796
- if (__voice__ && Array.isArray(__voice__.tools)) {
7797
- for (const t of __voice__.tools) {
7798
- if (t && typeof t === 'object' && typeof t.name === 'string') {
7799
- __luaTools[t.name] = {
7800
- name: t.name,
7801
- description: t.description,
7802
- execute: t.execute,
7803
- condition: t.condition,
7804
- voice: t.voice,
7805
- };
7806
- }
7807
- }
7808
- }
7809
-
7810
- export const onEnter = __voice__ && __voice__.onEnter;
7811
- export const onUserTurnCompleted = __voice__ && __voice__.onUserTurnCompleted;
7812
- export const onExit = __voice__ && __voice__.onExit;
7813
- export const tools = __luaTools;
7814
- `;
8237
+ return rewritePrimitiveSource(metadata, {
8238
+ constructorNames: [
8239
+ "LuaVoice"
8240
+ ],
8241
+ defineFunctionName: this.defineFunction,
8242
+ buildLiteral: /* @__PURE__ */ __name((arg, ctx) => `{
8243
+ ${buildLuaPrimitiveMarker(ctx.metadata, "voice")},
8244
+ onEnter: ${getPropertyText(arg, "onEnter") ?? "undefined"},
8245
+ onUserTurnCompleted: ${getPropertyText(arg, "onUserTurnCompleted") ?? "undefined"},
8246
+ onExit: ${getPropertyText(arg, "onExit") ?? "undefined"},
8247
+ tools: ${getPropertyText(arg, "tools") ?? "[]"}
8248
+ }`, "buildLiteral"),
8249
+ crossFileSpecs: buildCrossFileSpecs(),
8250
+ sdkBaseClassNames: buildSdkBaseClassNames()
8251
+ });
7815
8252
  }
7816
8253
  /**
7817
8254
  * Emit a JSON metadata sidecar OR fall through to esbuild bundling.
@@ -8003,6 +8440,8 @@ var init_bundler = __esm({
8003
8440
  "src/compiler/bundler.ts"() {
8004
8441
  "use strict";
8005
8442
  init_types();
8443
+ init_primitive_rewrite();
8444
+ init_cross_file_specs();
8006
8445
  Bundler = class {
8007
8446
  static {
8008
8447
  __name(this, "Bundler");
@@ -8010,24 +8449,43 @@ var init_bundler = __esm({
8010
8449
  options;
8011
8450
  project;
8012
8451
  verbose;
8452
+ // Snapshotted at construction. Plugins registered after this Bundler
8453
+ // is instantiated (test fixtures, "lua-cli as a library" usage) won't appear.
8454
+ // Today the registry is module-load-time only, so this is fine.
8455
+ crossFileSpecs = buildCrossFileSpecs();
8456
+ sdkBaseClassNames = buildSdkBaseClassNames();
8013
8457
  constructor(options, project, verbose) {
8014
8458
  this.options = options;
8015
8459
  this.project = project;
8016
8460
  this.verbose = verbose;
8017
8461
  }
8018
8462
  /**
8019
- * Strip lua-cli and api-exports import statements from source code using TypeScript AST.
8020
- * This is more robust than regex and handles all edge cases (multiline, comments, etc.).
8463
+ * Strip lua-cli / lua-cli/skill / lua-cli/voice / api-exports imports from
8464
+ * a source file, then rewrite every SDK class constructor / define-function
8465
+ * call in the file to a bare object literal (`{ name, execute, ... }`).
8466
+ *
8467
+ * After this transform:
8468
+ * - SDK class identifiers (LuaTool, LuaJob, defineWebhook, ...) no longer
8469
+ * appear in the source. The call sites that used them are replaced with
8470
+ * inline object literals carrying the runtime fields. By construction,
8471
+ * the bundle has zero references to stripped SDK identifiers, so the
8472
+ * sandbox doesn't need any runtime stub for them.
8473
+ * - Platform-API identifiers (Data, User, AI, Agents, Jobs, Lua, env, ...)
8474
+ * remain as free identifiers in the dev's execute / hook bodies. esbuild
8475
+ * leaves them alone (they're not imported, not local), and at runtime
8476
+ * they resolve to the sandbox's injected globals.
8477
+ *
8478
+ * Replaces the prior `buildLuaCliStubBlock` runtime-stub approach (BAC-234).
8021
8479
  */
8022
8480
  stripLuaCliImportsAST(code, filename = "temp.ts") {
8023
8481
  try {
8024
8482
  const tempFile = this.project.createSourceFile(`__strip_${filename}`, code, {
8025
8483
  overwrite: true
8026
8484
  });
8027
- const imports = tempFile.getImportDeclarations();
8028
- imports.forEach((imp) => {
8029
- const moduleSpecifier = imp.getModuleSpecifierValue();
8030
- if (moduleSpecifier === "lua-cli" || moduleSpecifier === "lua-cli/skill" || moduleSpecifier.includes("api-exports")) {
8485
+ rewriteCrossFileCallsInSourceFile(tempFile, this.crossFileSpecs, this.sdkBaseClassNames);
8486
+ tempFile.getImportDeclarations().forEach((imp) => {
8487
+ const spec = imp.getModuleSpecifierValue();
8488
+ if (spec === "lua-cli" || spec === "lua-cli/skill" || spec === "lua-cli/voice" || spec.includes("api-exports")) {
8031
8489
  imp.remove();
8032
8490
  }
8033
8491
  });
@@ -8035,7 +8493,8 @@ var init_bundler = __esm({
8035
8493
  this.project.removeSourceFile(tempFile);
8036
8494
  return result;
8037
8495
  } catch (error) {
8038
- return code;
8496
+ const msg = error instanceof Error ? error.message : String(error);
8497
+ throw new Error(`[lua-cli] AST rewrite failed for ${filename}: ${msg}. Source: bare SDK identifiers would survive into the bundle and fail at runtime; aborting compile.`);
8039
8498
  }
8040
8499
  }
8041
8500
  /**
@@ -8143,8 +8602,6 @@ export { ${exportName} as __lua_target__ };
8143
8602
  */
8144
8603
  createLuaCliShimPlugin() {
8145
8604
  const stripImports = this.stripLuaCliImportsAST.bind(this);
8146
- const debug = this.options.debug;
8147
- const verbose = this.verbose.bind(this);
8148
8605
  return {
8149
8606
  name: "lua-cli-import-stripper",
8150
8607
  setup(build2) {
@@ -8168,14 +8625,12 @@ export { ${exportName} as __lua_target__ };
8168
8625
  }
8169
8626
  return null;
8170
8627
  } catch (error) {
8171
- if (debug) {
8172
- verbose(` Warning: Failed to parse ${args2.path} with ts-morph, using fallback`);
8173
- }
8174
- return null;
8628
+ const msg = error instanceof Error ? error.message : String(error);
8629
+ throw new Error(`[lua-cli] AST rewrite failed for ${args2.path}: ${msg}. Aborting compile (silent fallback would corrupt the bundle).`);
8175
8630
  }
8176
8631
  });
8177
8632
  build2.onResolve({
8178
- filter: /^lua-cli(\/skill)?$/
8633
+ filter: /^lua-cli(\/(skill|voice))?$/
8179
8634
  }, () => ({
8180
8635
  path: "lua-cli-empty",
8181
8636
  namespace: "lua-cli-empty"
@@ -8201,7 +8656,7 @@ export { ${exportName} as __lua_target__ };
8201
8656
  });
8202
8657
 
8203
8658
  // src/compiler/agent-traverser.ts
8204
- import { Project, Node as Node15 } from "ts-morph";
8659
+ import { Project as Project2, Node as Node16 } from "ts-morph";
8205
8660
  import path6 from "path";
8206
8661
  import fs7 from "fs";
8207
8662
  var PRIMITIVE_TYPES, AgentTraverser;
@@ -8275,7 +8730,7 @@ var init_agent_traverser = __esm({
8275
8730
  constructor(rootDir, debug = false) {
8276
8731
  this.rootDir = rootDir;
8277
8732
  this.debug = debug;
8278
- this.project = new Project({
8733
+ this.project = new Project2({
8279
8734
  tsConfigFilePath: path6.join(rootDir, "tsconfig.json"),
8280
8735
  skipAddingFilesFromTsConfig: true
8281
8736
  });
@@ -8424,7 +8879,7 @@ var init_agent_traverser = __esm({
8424
8879
  */
8425
8880
  extractArrayRefs(config, propName) {
8426
8881
  const prop = config.getProperty(propName);
8427
- if (!prop || !Node15.isPropertyAssignment(prop)) return [];
8882
+ if (!prop || !Node16.isPropertyAssignment(prop)) return [];
8428
8883
  const value = prop.getInitializer();
8429
8884
  if (!value) return [];
8430
8885
  const ctx = {
@@ -8509,7 +8964,7 @@ var init_agent_traverser = __esm({
8509
8964
  for (const assign of file.getExportAssignments()) {
8510
8965
  if (assign.isExportEquals()) continue;
8511
8966
  const expr = assign.getExpression();
8512
- if (!Node15.isIdentifier(expr)) continue;
8967
+ if (!Node16.isIdentifier(expr)) continue;
8513
8968
  const targetName = expr.getText();
8514
8969
  defaultMatch = detected.find((d) => d.exportName === targetName);
8515
8970
  if (defaultMatch) break;
@@ -8608,7 +9063,7 @@ var init_workspace = __esm({
8608
9063
  // src/compiler/compiler.ts
8609
9064
  import fs9 from "fs/promises";
8610
9065
  import path8 from "path";
8611
- import { Project as Project2 } from "ts-morph";
9066
+ import { Project as Project3 } from "ts-morph";
8612
9067
  async function compile(options) {
8613
9068
  const compiler = new Compiler(options);
8614
9069
  return compiler.compile();
@@ -8659,7 +9114,7 @@ var init_compiler = __esm({
8659
9114
  runtimeValidation: true,
8660
9115
  ...options
8661
9116
  };
8662
- this.project = new Project2({
9117
+ this.project = new Project3({
8663
9118
  tsConfigFilePath: path8.join(options.rootDir, "tsconfig.json")
8664
9119
  });
8665
9120
  registerProjectRootDir(this.project, this.options.rootDir);
@@ -9272,7 +9727,7 @@ var init_file_discovery = __esm({
9272
9727
  });
9273
9728
 
9274
9729
  // src/compiler/source-writer.ts
9275
- import { Project as Project3, Node as Node16 } from "ts-morph";
9730
+ import { Project as Project4, Node as Node17 } from "ts-morph";
9276
9731
  import fs11 from "fs";
9277
9732
  import path10 from "path";
9278
9733
  function resolveEntryPath(options) {
@@ -9315,20 +9770,20 @@ function updateAgentConfig(updates, options) {
9315
9770
  const indexPath = resolveEntryPath(options);
9316
9771
  if (!indexPath) return false;
9317
9772
  try {
9318
- const project = new Project3({
9773
+ const project = new Project4({
9319
9774
  skipAddingFilesFromTsConfig: true
9320
9775
  });
9321
9776
  const sourceFile = project.addSourceFileAtPath(indexPath);
9322
9777
  let updated = false;
9323
9778
  sourceFile.forEachDescendant((node) => {
9324
- if (Node16.isNewExpression(node) && node.getExpression().getText() === "LuaAgent") {
9779
+ if (Node17.isNewExpression(node) && node.getExpression().getText() === "LuaAgent") {
9325
9780
  const args2 = node.getArguments();
9326
- if (args2.length > 0 && Node16.isObjectLiteralExpression(args2[0])) {
9781
+ if (args2.length > 0 && Node17.isObjectLiteralExpression(args2[0])) {
9327
9782
  const configObj = args2[0];
9328
9783
  const replacedKeys = /* @__PURE__ */ new Set();
9329
9784
  let lastReplacedIndex = -1;
9330
9785
  configObj.getProperties().forEach((prop, index) => {
9331
- if (Node16.isPropertyAssignment(prop)) {
9786
+ if (Node17.isPropertyAssignment(prop)) {
9332
9787
  const propName = prop.getName();
9333
9788
  if (Object.prototype.hasOwnProperty.call(filteredUpdates, propName)) {
9334
9789
  const newValue = filteredUpdates[propName];
@@ -9384,21 +9839,21 @@ function removeAgentConfigProperty(propertyName, options) {
9384
9839
  const indexPath = resolveEntryPath(options);
9385
9840
  if (!indexPath) return false;
9386
9841
  try {
9387
- const project = new Project3({
9842
+ const project = new Project4({
9388
9843
  skipAddingFilesFromTsConfig: true
9389
9844
  });
9390
9845
  const sourceFile = project.addSourceFileAtPath(indexPath);
9391
9846
  let foundConstructor = false;
9392
9847
  let removed = false;
9393
9848
  sourceFile.forEachDescendant((node) => {
9394
- if (Node16.isNewExpression(node) && node.getExpression().getText() === "LuaAgent") {
9849
+ if (Node17.isNewExpression(node) && node.getExpression().getText() === "LuaAgent") {
9395
9850
  const args2 = node.getArguments();
9396
- if (args2.length > 0 && Node16.isObjectLiteralExpression(args2[0])) {
9851
+ if (args2.length > 0 && Node17.isObjectLiteralExpression(args2[0])) {
9397
9852
  foundConstructor = true;
9398
9853
  const configObj = args2[0];
9399
9854
  const props = configObj.getProperties();
9400
9855
  for (const prop of props) {
9401
- if (Node16.isPropertyAssignment(prop) && prop.getName() === propertyName) {
9856
+ if (Node17.isPropertyAssignment(prop) && prop.getName() === propertyName) {
9402
9857
  prop.remove();
9403
9858
  removed = true;
9404
9859
  break;
@@ -18267,7 +18722,7 @@ init_cli();
18267
18722
  init_command_utils();
18268
18723
 
18269
18724
  // src/utils/sandbox.ts
18270
- import vm2 from "vm";
18725
+ import vm3 from "vm";
18271
18726
  import path16 from "path";
18272
18727
 
18273
18728
  // ../shared-sandbox/dist/index.mjs
@@ -18278,6 +18733,7 @@ import dns from "dns";
18278
18733
  import net from "net";
18279
18734
  import { promisify } from "util";
18280
18735
  import { Agent as UndiciAgent } from "undici";
18736
+ import vm2 from "vm";
18281
18737
  var __defProp4 = Object.defineProperty;
18282
18738
  var __name4 = /* @__PURE__ */ __name((target, value) => __defProp4(target, "name", { value, configurable: true }), "__name");
18283
18739
  function buildSandboxProcess(opts) {
@@ -19088,6 +19544,28 @@ function applyGlobalSelfReference(context) {
19088
19544
  }
19089
19545
  __name(applyGlobalSelfReference, "applyGlobalSelfReference");
19090
19546
  __name4(applyGlobalSelfReference, "applyGlobalSelfReference");
19547
+ function resolveExtraAllowedCidrs() {
19548
+ const csv = process.env.LUA_ALLOWED_EGRESS_CIDRS;
19549
+ if (!csv) return [];
19550
+ return csv.split(",").map((s) => s.trim()).filter(Boolean);
19551
+ }
19552
+ __name(resolveExtraAllowedCidrs, "resolveExtraAllowedCidrs");
19553
+ __name4(resolveExtraAllowedCidrs, "resolveExtraAllowedCidrs");
19554
+ function wrapBundleAsCjsModule(source) {
19555
+ return "(function(module, exports, require) {\n" + source + "\n})(module, module.exports, require);";
19556
+ }
19557
+ __name(wrapBundleAsCjsModule, "wrapBundleAsCjsModule");
19558
+ __name4(wrapBundleAsCjsModule, "wrapBundleAsCjsModule");
19559
+ function runBundleInContext(context, source, options) {
19560
+ const wrapped = wrapBundleAsCjsModule(source);
19561
+ vm2.runInContext(wrapped, context, {
19562
+ filename: options.filename,
19563
+ timeout: options.timeoutMs ?? 1e3,
19564
+ lineOffset: -1
19565
+ });
19566
+ }
19567
+ __name(runBundleInContext, "runBundleInContext");
19568
+ __name4(runBundleInContext, "runBundleInContext");
19091
19569
 
19092
19570
  // src/utils/env-loader.utils.ts
19093
19571
  import path15 from "path";
@@ -19200,12 +19678,12 @@ function resolveEgressMode() {
19200
19678
  return "off";
19201
19679
  }
19202
19680
  __name(resolveEgressMode, "resolveEgressMode");
19203
- function resolveExtraAllowedCidrs() {
19681
+ function resolveExtraAllowedCidrs2() {
19204
19682
  const csv = process.env.LUA_ALLOWED_EGRESS_CIDRS;
19205
19683
  if (!csv) return [];
19206
19684
  return csv.split(",").map((s) => s.trim()).filter(Boolean);
19207
19685
  }
19208
- __name(resolveExtraAllowedCidrs, "resolveExtraAllowedCidrs");
19686
+ __name(resolveExtraAllowedCidrs2, "resolveExtraAllowedCidrs");
19209
19687
  function defaultSecurityEventLogger(evt) {
19210
19688
  console.warn("[sandbox]", JSON.stringify(evt));
19211
19689
  }
@@ -19353,7 +19831,7 @@ function createSandbox(options) {
19353
19831
  extraGlobals,
19354
19832
  requireMode: resolveRequireMode(),
19355
19833
  egressMode: resolveEgressMode(),
19356
- egressExtraAllowedCidrs: resolveExtraAllowedCidrs(),
19834
+ egressExtraAllowedCidrs: resolveExtraAllowedCidrs2(),
19357
19835
  onSecurityEvent: defaultSecurityEventLogger
19358
19836
  });
19359
19837
  }
@@ -19361,11 +19839,14 @@ __name(createSandbox, "createSandbox");
19361
19839
  async function executeTool(options) {
19362
19840
  const { toolCode, inputs } = options;
19363
19841
  const sandbox = createSandbox(options);
19364
- const context = vm2.createContext(sandbox);
19842
+ const context = vm3.createContext(sandbox);
19365
19843
  applyGlobalSelfReference(context);
19366
19844
  const isBundledArtifact = toolCode.includes("__lua_primitive__");
19367
19845
  if (isBundledArtifact) {
19368
- vm2.runInContext(toolCode, context);
19846
+ runBundleInContext(context, toolCode, {
19847
+ filename: "tool.bundle.js",
19848
+ timeoutMs: 18e4
19849
+ });
19369
19850
  const moduleExports = context.module.exports;
19370
19851
  const primitive = moduleExports.default?.primitive || moduleExports.primitive;
19371
19852
  if (!primitive || !primitive.execute) {
@@ -19393,7 +19874,7 @@ module.exports = async (input) => {
19393
19874
  }
19394
19875
  };
19395
19876
  `;
19396
- vm2.runInContext(commonJsWrapper, context);
19877
+ vm3.runInContext(commonJsWrapper, context);
19397
19878
  const executeFunction = context.module.exports;
19398
19879
  return await executeFunction(inputs);
19399
19880
  }
@@ -19402,7 +19883,7 @@ __name(executeTool, "executeTool");
19402
19883
  async function executeWebhook(options) {
19403
19884
  const { webhookCode, query, headers, body } = options;
19404
19885
  const sandbox = createSandbox(options);
19405
- const context = vm2.createContext(sandbox);
19886
+ const context = vm3.createContext(sandbox);
19406
19887
  applyGlobalSelfReference(context);
19407
19888
  const event = {
19408
19889
  query: query ?? {},
@@ -19412,7 +19893,10 @@ async function executeWebhook(options) {
19412
19893
  };
19413
19894
  const isBundledArtifact = webhookCode.includes("__lua_primitive__");
19414
19895
  if (isBundledArtifact) {
19415
- vm2.runInContext(webhookCode, context);
19896
+ runBundleInContext(context, webhookCode, {
19897
+ filename: "webhook.bundle.js",
19898
+ timeoutMs: 18e4
19899
+ });
19416
19900
  const moduleExports = context.module.exports;
19417
19901
  const primitive = moduleExports.default?.primitive || moduleExports.primitive;
19418
19902
  if (!primitive || !primitive.execute) {
@@ -19440,7 +19924,7 @@ module.exports = async (event) => {
19440
19924
  }
19441
19925
  };
19442
19926
  `;
19443
- vm2.runInContext(commonJsWrapper, context);
19927
+ vm3.runInContext(commonJsWrapper, context);
19444
19928
  const executeFunction = context.module.exports;
19445
19929
  return await executeFunction(event);
19446
19930
  }
@@ -19449,7 +19933,7 @@ __name(executeWebhook, "executeWebhook");
19449
19933
  async function executeJob(options) {
19450
19934
  const { jobCode, jobData, apiKey, agentId } = options;
19451
19935
  const sandbox = createSandbox(options);
19452
- const context = vm2.createContext(sandbox);
19936
+ const context = vm3.createContext(sandbox);
19453
19937
  applyGlobalSelfReference(context);
19454
19938
  let jobInstance = void 0;
19455
19939
  if (jobData) {
@@ -19475,7 +19959,10 @@ async function executeJob(options) {
19475
19959
  }
19476
19960
  const isBundledArtifact = jobCode.includes("__lua_primitive__");
19477
19961
  if (isBundledArtifact) {
19478
- vm2.runInContext(jobCode, context);
19962
+ runBundleInContext(context, jobCode, {
19963
+ filename: "job.bundle.js",
19964
+ timeoutMs: 18e4
19965
+ });
19479
19966
  const moduleExports = context.module.exports;
19480
19967
  const primitive = moduleExports.default?.primitive || moduleExports.primitive;
19481
19968
  if (!primitive || !primitive.execute) {
@@ -19503,7 +19990,7 @@ module.exports = async (job) => {
19503
19990
  }
19504
19991
  };
19505
19992
  `;
19506
- vm2.runInContext(commonJsWrapper, context);
19993
+ vm3.runInContext(commonJsWrapper, context);
19507
19994
  const executeFunction = context.module.exports;
19508
19995
  return await executeFunction(jobInstance);
19509
19996
  }
@@ -19515,11 +20002,14 @@ async function executePreProcessor(options) {
19515
20002
  const UserDataApi2 = (await Promise.resolve().then(() => (init_user_data_api_service(), user_data_api_service_exports))).default;
19516
20003
  const userService = new UserDataApi2(BASE_URLS.API, apiKey, agentId);
19517
20004
  const userInstance = await userService.get();
19518
- const context = vm2.createContext(sandbox);
20005
+ const context = vm3.createContext(sandbox);
19519
20006
  applyGlobalSelfReference(context);
19520
20007
  const isBundledArtifact = processorCode.includes("__lua_primitive__");
19521
20008
  if (isBundledArtifact) {
19522
- vm2.runInContext(processorCode, context);
20009
+ runBundleInContext(context, processorCode, {
20010
+ filename: "preprocessor.bundle.js",
20011
+ timeoutMs: 18e4
20012
+ });
19523
20013
  const moduleExports = context.module.exports;
19524
20014
  const primitive = moduleExports.default?.primitive || moduleExports.primitive;
19525
20015
  if (!primitive || !primitive.execute) {
@@ -19547,7 +20037,7 @@ module.exports = async (input) => {
19547
20037
  }
19548
20038
  };
19549
20039
  `;
19550
- vm2.runInContext(commonJsWrapper, context);
20040
+ vm3.runInContext(commonJsWrapper, context);
19551
20041
  const executeFunction = context.module.exports;
19552
20042
  return await executeFunction({
19553
20043
  user: userInstance,
@@ -19563,11 +20053,14 @@ async function executePostProcessor(options) {
19563
20053
  const UserDataApi2 = (await Promise.resolve().then(() => (init_user_data_api_service(), user_data_api_service_exports))).default;
19564
20054
  const userService = new UserDataApi2(BASE_URLS.API, apiKey, agentId);
19565
20055
  const userInstance = await userService.get();
19566
- const context = vm2.createContext(sandbox);
20056
+ const context = vm3.createContext(sandbox);
19567
20057
  applyGlobalSelfReference(context);
19568
20058
  const isBundledArtifact = processorCode.includes("__lua_primitive__");
19569
20059
  if (isBundledArtifact) {
19570
- vm2.runInContext(processorCode, context);
20060
+ runBundleInContext(context, processorCode, {
20061
+ filename: "postprocessor.bundle.js",
20062
+ timeoutMs: 18e4
20063
+ });
19571
20064
  const moduleExports = context.module.exports;
19572
20065
  const primitive = moduleExports.default?.primitive || moduleExports.primitive;
19573
20066
  if (!primitive || !primitive.execute) {
@@ -19592,7 +20085,7 @@ module.exports = async (input) => {
19592
20085
  }
19593
20086
  };
19594
20087
  `;
19595
- vm2.runInContext(commonJsWrapper, context);
20088
+ vm3.runInContext(commonJsWrapper, context);
19596
20089
  const executeFunction = context.module.exports;
19597
20090
  return await executeFunction({
19598
20091
  user: userInstance,
@@ -23176,11 +23669,11 @@ init_cli();
23176
23669
 
23177
23670
  // src/utils/sandbox-storage.ts
23178
23671
  init_constants();
23179
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6 } from "fs";
23672
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6 } from "fs";
23180
23673
  import { dirname as dirname5 } from "path";
23181
23674
  function readStore() {
23182
23675
  try {
23183
- const raw = readFileSync8(SANDBOX_STORAGE_FILE, "utf8");
23676
+ const raw = readFileSync9(SANDBOX_STORAGE_FILE, "utf8");
23184
23677
  const parsed = JSON.parse(raw);
23185
23678
  return {
23186
23679
  skills: parsed.skills ?? {},
@@ -29372,7 +29865,7 @@ init_auth();
29372
29865
  init_auth_api_service();
29373
29866
  init_files();
29374
29867
  init_artifact_loader();
29375
- import { existsSync as existsSync7, readFileSync as readFileSync9 } from "fs";
29868
+ import { existsSync as existsSync7, readFileSync as readFileSync10 } from "fs";
29376
29869
  import { join as join6 } from "path";
29377
29870
  import { performance } from "perf_hooks";
29378
29871
  import * as os from "os";
@@ -29723,7 +30216,7 @@ function gatherTelemetry() {
29723
30216
  } else {
29724
30217
  try {
29725
30218
  if (existsSync7(TELEMETRY_FILE)) {
29726
- const raw = readFileSync9(TELEMETRY_FILE, "utf8");
30219
+ const raw = readFileSync10(TELEMETRY_FILE, "utf8");
29727
30220
  const cfg = JSON.parse(raw);
29728
30221
  if (typeof cfg.enabled === "boolean") enabled = cfg.enabled;
29729
30222
  }