@frontmcp/plugin-codecall 1.7.2 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -38,6 +38,8 @@ var __decorateClass = (decorators, target, key, kind) => {
38
38
  // plugins/plugin-codecall/src/index.ts
39
39
  var index_exports = {};
40
40
  __export(index_exports, {
41
+ AUDIT_EVENT_TYPES: () => AUDIT_EVENT_TYPES,
42
+ AuditLoggerService: () => AuditLoggerService,
41
43
  CodeCallPlugin: () => CodeCallPlugin,
42
44
  codeCallDirectCallsOptionsSchema: () => codeCallDirectCallsOptionsSchema,
43
45
  codeCallEmbeddingOptionsSchema: () => codeCallEmbeddingOptionsSchema,
@@ -54,7 +56,7 @@ module.exports = __toCommonJS(index_exports);
54
56
 
55
57
  // plugins/plugin-codecall/src/codecall.plugin.ts
56
58
  var import_plugin_cache = __toESM(require("@frontmcp/plugin-cache"));
57
- var import_sdk9 = require("@frontmcp/sdk");
59
+ var import_sdk10 = require("@frontmcp/sdk");
58
60
 
59
61
  // plugins/plugin-codecall/src/codecall.types.ts
60
62
  var import_lazy_zod = require("@frontmcp/lazy-zod");
@@ -409,9 +411,434 @@ function presetDefaults(preset) {
409
411
  }
410
412
  }
411
413
 
414
+ // plugins/plugin-codecall/src/services/audit-logger.service.ts
415
+ var import_sdk2 = require("@frontmcp/sdk");
416
+ var AUDIT_EVENT_TYPES = {
417
+ /** Script execution started */
418
+ EXECUTION_START: "codecall:execution:start",
419
+ /** Script execution completed successfully */
420
+ EXECUTION_SUCCESS: "codecall:execution:success",
421
+ /** Script execution failed */
422
+ EXECUTION_FAILURE: "codecall:execution:failure",
423
+ /** Script execution timed out */
424
+ EXECUTION_TIMEOUT: "codecall:execution:timeout",
425
+ /** Tool call initiated from script */
426
+ TOOL_CALL_START: "codecall:tool:call:start",
427
+ /** Tool call completed successfully */
428
+ TOOL_CALL_SUCCESS: "codecall:tool:call:success",
429
+ /** Tool call failed */
430
+ TOOL_CALL_FAILURE: "codecall:tool:call:failure",
431
+ /** Self-reference attack blocked */
432
+ SECURITY_SELF_REFERENCE: "codecall:security:self-reference",
433
+ /** Tool access denied */
434
+ SECURITY_ACCESS_DENIED: "codecall:security:access-denied",
435
+ /** AST validation failed (blocked code pattern) */
436
+ SECURITY_AST_BLOCKED: "codecall:security:ast-blocked",
437
+ /** Search performed */
438
+ SEARCH_PERFORMED: "codecall:search:performed",
439
+ /** Tool described */
440
+ DESCRIBE_PERFORMED: "codecall:describe:performed",
441
+ /** Direct invoke performed */
442
+ INVOKE_PERFORMED: "codecall:invoke:performed"
443
+ };
444
+ var AuditLoggerService = class {
445
+ listeners = /* @__PURE__ */ new Set();
446
+ executionCounter = 0;
447
+ /**
448
+ * Subscribe to audit events.
449
+ *
450
+ * @param listener - Function to call when events occur
451
+ * @returns Unsubscribe function
452
+ */
453
+ subscribe(listener) {
454
+ this.listeners.add(listener);
455
+ return () => {
456
+ this.listeners.delete(listener);
457
+ };
458
+ }
459
+ /**
460
+ * Generate a unique execution ID.
461
+ */
462
+ generateExecutionId() {
463
+ const timestamp = Date.now().toString(36);
464
+ const counter = (++this.executionCounter).toString(36).padStart(4, "0");
465
+ const random = Math.random().toString(36).substring(2, 8);
466
+ return `exec_${timestamp}_${counter}_${random}`;
467
+ }
468
+ /**
469
+ * Log execution start.
470
+ */
471
+ logExecutionStart(executionId, script) {
472
+ this.emit({
473
+ type: AUDIT_EVENT_TYPES.EXECUTION_START,
474
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
475
+ executionId,
476
+ data: {
477
+ scriptHash: this.hashScript(script),
478
+ scriptLength: script.length
479
+ }
480
+ });
481
+ }
482
+ /**
483
+ * Log execution success.
484
+ */
485
+ logExecutionSuccess(executionId, script, durationMs, toolCallCount) {
486
+ this.emit({
487
+ type: AUDIT_EVENT_TYPES.EXECUTION_SUCCESS,
488
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
489
+ executionId,
490
+ durationMs,
491
+ data: {
492
+ scriptHash: this.hashScript(script),
493
+ scriptLength: script.length,
494
+ toolCallCount
495
+ }
496
+ });
497
+ }
498
+ /**
499
+ * Log execution failure.
500
+ */
501
+ logExecutionFailure(executionId, script, durationMs, error) {
502
+ this.emit({
503
+ type: AUDIT_EVENT_TYPES.EXECUTION_FAILURE,
504
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
505
+ executionId,
506
+ durationMs,
507
+ data: {
508
+ scriptHash: this.hashScript(script),
509
+ scriptLength: script.length,
510
+ error: this.sanitizeError(error)
511
+ }
512
+ });
513
+ }
514
+ /**
515
+ * Log execution timeout.
516
+ */
517
+ logExecutionTimeout(executionId, script, durationMs) {
518
+ this.emit({
519
+ type: AUDIT_EVENT_TYPES.EXECUTION_TIMEOUT,
520
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
521
+ executionId,
522
+ durationMs,
523
+ data: {
524
+ scriptHash: this.hashScript(script),
525
+ scriptLength: script.length
526
+ }
527
+ });
528
+ }
529
+ /**
530
+ * Log tool call start.
531
+ */
532
+ logToolCallStart(executionId, toolName, callDepth) {
533
+ this.emit({
534
+ type: AUDIT_EVENT_TYPES.TOOL_CALL_START,
535
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
536
+ executionId,
537
+ data: {
538
+ toolName,
539
+ callDepth
540
+ }
541
+ });
542
+ }
543
+ /**
544
+ * Log tool call success.
545
+ */
546
+ logToolCallSuccess(executionId, toolName, callDepth, durationMs) {
547
+ this.emit({
548
+ type: AUDIT_EVENT_TYPES.TOOL_CALL_SUCCESS,
549
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
550
+ executionId,
551
+ durationMs,
552
+ data: {
553
+ toolName,
554
+ callDepth
555
+ }
556
+ });
557
+ }
558
+ /**
559
+ * Log tool call failure.
560
+ */
561
+ logToolCallFailure(executionId, toolName, callDepth, durationMs, errorCode) {
562
+ this.emit({
563
+ type: AUDIT_EVENT_TYPES.TOOL_CALL_FAILURE,
564
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
565
+ executionId,
566
+ durationMs,
567
+ data: {
568
+ toolName,
569
+ callDepth,
570
+ errorCode
571
+ }
572
+ });
573
+ }
574
+ /**
575
+ * Log security event: self-reference blocked.
576
+ */
577
+ logSecuritySelfReference(executionId, toolName) {
578
+ this.emit({
579
+ type: AUDIT_EVENT_TYPES.SECURITY_SELF_REFERENCE,
580
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
581
+ executionId,
582
+ data: {
583
+ blocked: toolName,
584
+ reason: "Self-reference attack: attempted to call CodeCall tool from within AgentScript"
585
+ }
586
+ });
587
+ }
588
+ /**
589
+ * Log security event: access denied.
590
+ */
591
+ logSecurityAccessDenied(executionId, toolName, reason) {
592
+ this.emit({
593
+ type: AUDIT_EVENT_TYPES.SECURITY_ACCESS_DENIED,
594
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
595
+ executionId,
596
+ data: {
597
+ blocked: toolName,
598
+ reason: this.sanitizeError(reason)
599
+ }
600
+ });
601
+ }
602
+ /**
603
+ * Log security event: AST validation blocked.
604
+ */
605
+ logSecurityAstBlocked(executionId, pattern, reason) {
606
+ this.emit({
607
+ type: AUDIT_EVENT_TYPES.SECURITY_AST_BLOCKED,
608
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
609
+ executionId,
610
+ data: {
611
+ blocked: pattern,
612
+ reason: this.sanitizeError(reason)
613
+ }
614
+ });
615
+ }
616
+ /**
617
+ * Log search operation.
618
+ */
619
+ logSearch(executionId, query, resultCount, durationMs) {
620
+ this.emit({
621
+ type: AUDIT_EVENT_TYPES.SEARCH_PERFORMED,
622
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
623
+ executionId,
624
+ durationMs,
625
+ data: {
626
+ queryLength: query.length,
627
+ resultCount
628
+ }
629
+ });
630
+ }
631
+ /**
632
+ * Log describe operation.
633
+ */
634
+ logDescribe(executionId, toolNames, durationMs) {
635
+ this.emit({
636
+ type: AUDIT_EVENT_TYPES.DESCRIBE_PERFORMED,
637
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
638
+ executionId,
639
+ durationMs,
640
+ data: {
641
+ toolCount: toolNames.length,
642
+ toolNames: toolNames.slice(0, 10)
643
+ // Limit to first 10 for audit
644
+ }
645
+ });
646
+ }
647
+ /**
648
+ * Log invoke operation.
649
+ */
650
+ logInvoke(executionId, toolName, success, durationMs) {
651
+ this.emit({
652
+ type: AUDIT_EVENT_TYPES.INVOKE_PERFORMED,
653
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
654
+ executionId,
655
+ durationMs,
656
+ data: {
657
+ toolName,
658
+ success
659
+ }
660
+ });
661
+ }
662
+ /**
663
+ * Emit an audit event to all listeners.
664
+ */
665
+ emit(event) {
666
+ const frozenEvent = Object.freeze({ ...event, data: Object.freeze({ ...event.data }) });
667
+ for (const listener of this.listeners) {
668
+ try {
669
+ listener(frozenEvent);
670
+ } catch {
671
+ }
672
+ }
673
+ }
674
+ /**
675
+ * Create a simple hash of the script for identification.
676
+ * Uses a fast, non-cryptographic hash for performance.
677
+ */
678
+ hashScript(script) {
679
+ let hash = 0;
680
+ for (let i = 0; i < script.length; i++) {
681
+ const char = script.charCodeAt(i);
682
+ hash = (hash << 5) - hash + char;
683
+ hash = hash & hash;
684
+ }
685
+ return `sh_${(hash >>> 0).toString(16).padStart(8, "0")}`;
686
+ }
687
+ /**
688
+ * Sanitize error messages to remove sensitive information.
689
+ */
690
+ sanitizeError(error) {
691
+ if (!error) return "Unknown error";
692
+ let sanitized = error.replace(/(?:\/[\w.-]+)+|(?:[A-Za-z]:\\[\w\\.-]+)+/g, "[path]");
693
+ sanitized = sanitized.replace(/:\d+:\d+/g, "");
694
+ sanitized = sanitized.replace(/\n\s*at .*/g, "");
695
+ if (sanitized.length > 200) {
696
+ sanitized = sanitized.substring(0, 200) + "...";
697
+ }
698
+ return sanitized.trim();
699
+ }
700
+ };
701
+ AuditLoggerService = __decorateClass([
702
+ (0, import_sdk2.Provider)({
703
+ name: "codecall:audit-logger",
704
+ scope: import_sdk2.ProviderScope.GLOBAL
705
+ })
706
+ ], AuditLoggerService);
707
+
412
708
  // plugins/plugin-codecall/src/services/tool-search.service.ts
413
709
  var import_vectoriadb = require("vectoriadb");
414
710
 
711
+ // plugins/plugin-codecall/src/security/codecall-tool-policy.ts
712
+ var BLOCKED_NAMESPACE_PATTERNS = Object.freeze([/^system:/, /^internal:/, /^__/]);
713
+ var ALLOWED = { allowed: true };
714
+ function deny(reason) {
715
+ return { allowed: false, reason };
716
+ }
717
+ function codeCallAppIdOf(scope, entry) {
718
+ const lineage = scope?.tools?.lineageOf?.(entry) ?? [];
719
+ const owners = entry.owner ? [...lineage, entry.owner] : lineage;
720
+ return owners.find((owner) => owner.kind === "app")?.id;
721
+ }
722
+ function toCodeCallPolicyTool(entry, requestedName, scope) {
723
+ const { metadata } = entry;
724
+ return {
725
+ name: entry.name || entry.fullName,
726
+ fullName: entry.fullName,
727
+ aliases: requestedName ? [requestedName] : void 0,
728
+ appId: codeCallAppIdOf(scope, entry),
729
+ description: metadata?.description,
730
+ tags: metadata?.tags,
731
+ // `internal` tools refuse every external tools/call, CodeCall's included, so no surface may offer them.
732
+ hidden: metadata?.hideFromDiscovery === true || metadata?.visibility === "hidden" || metadata?.visibility === "internal",
733
+ codecall: metadata?.codecall
734
+ };
735
+ }
736
+ function toToolFilterInfo(tool) {
737
+ return {
738
+ name: tool.name,
739
+ appId: tool.appId,
740
+ source: tool.codecall?.source,
741
+ description: tool.description,
742
+ tags: tool.codecall?.tags ?? tool.tags
743
+ };
744
+ }
745
+ function ownNamesOf(tool) {
746
+ return [tool.name, tool.fullName].filter((candidate) => !!candidate);
747
+ }
748
+ function checkCodeCallToolPolicy(tool, config) {
749
+ const { name } = tool;
750
+ const spellings = [...ownNamesOf(tool), ...tool.aliases ?? []];
751
+ if (spellings.some((candidate) => candidate.startsWith("codecall:"))) {
752
+ return deny("CodeCall meta-tools are not callable from CodeCall");
753
+ }
754
+ for (const candidate of spellings) {
755
+ if (BLOCKED_NAMESPACE_PATTERNS.some((pattern) => pattern.test(candidate))) {
756
+ return deny(`Tool "${candidate}" is in a namespace CodeCall never calls`);
757
+ }
758
+ }
759
+ if (tool.hidden === true) {
760
+ return deny(`Tool "${name}" is hidden from discovery`);
761
+ }
762
+ const enabled = tool.codecall?.enabledInCodeCall;
763
+ switch (config.mode) {
764
+ case "codecall_only":
765
+ case "metadata_driven":
766
+ if (enabled === false) {
767
+ return deny(`Tool "${name}" sets enabledInCodeCall: false`);
768
+ }
769
+ break;
770
+ case "codecall_opt_in":
771
+ if (enabled !== true) {
772
+ return deny(`Tool "${name}" has not opted in to CodeCall`);
773
+ }
774
+ break;
775
+ default:
776
+ return deny(`Unknown CodeCall mode: ${String(config.mode)}`);
777
+ }
778
+ if (config.includeTools && !config.includeTools(toToolFilterInfo(tool))) {
779
+ return deny(`Tool "${name}" is excluded by the includeTools filter`);
780
+ }
781
+ return ALLOWED;
782
+ }
783
+ function denyUnknownTool(name) {
784
+ return deny(`Tool "${name}" is not available through CodeCall`);
785
+ }
786
+ function resolveCodeCallTool(scope, name) {
787
+ const typedScope = scope;
788
+ const alias = /[-_]/.test(name) ? name.includes("_") ? name.replace(/_/g, "-") : name.replace(/-/g, "_") : void 0;
789
+ const candidates = alias ? [name, alias] : [name];
790
+ const matches = (entry) => candidates.includes(entry.fullName) || candidates.includes(entry.name);
791
+ const local = typedScope.tools?.getTools(true)?.find(matches);
792
+ if (local) return local;
793
+ const registries = typedScope.providers?.getRegistries?.("AppRegistry") ?? [];
794
+ for (const registry of registries) {
795
+ for (const app of registry.getApps()) {
796
+ if (!app.isRemote) continue;
797
+ const remote = app.tools.getTools(true).find(matches);
798
+ if (remote) return remote;
799
+ }
800
+ }
801
+ return void 0;
802
+ }
803
+ function checkDirectCallPolicy(tool, directCalls) {
804
+ if (!directCalls) return ALLOWED;
805
+ if (directCalls.enabled === false) {
806
+ return deny("Direct tool invocation is disabled");
807
+ }
808
+ const { allowedTools } = directCalls;
809
+ if (allowedTools && !ownNamesOf(tool).some((ownName) => allowedTools.includes(ownName))) {
810
+ return deny(`Tool "${tool.name}" is not in the direct-call allowlist`);
811
+ }
812
+ if (directCalls.filter && !directCalls.filter(toToolFilterInfo(tool))) {
813
+ return deny(`Tool "${tool.name}" is excluded by the directCalls filter`);
814
+ }
815
+ return ALLOWED;
816
+ }
817
+ function readCodeCallPolicyConfig(config) {
818
+ return {
819
+ // An absent mode means an unparsed/partial config, not a hostile one: fall back to the
820
+ // schema's own documented default rather than denying every call. An unrecognised mode
821
+ // still fails closed inside the policy's switch.
822
+ mode: config.get("mode") ?? "codecall_only",
823
+ includeTools: config.get("includeTools")
824
+ };
825
+ }
826
+ function checkCodeCallToolAccess(scope, config, name, options = {}) {
827
+ const entry = resolveCodeCallTool(scope, name);
828
+ if (!entry) return denyUnknownTool(name);
829
+ const policyTool = toCodeCallPolicyTool(entry, name, scope);
830
+ const baseDecision = checkCodeCallToolPolicy(policyTool, readCodeCallPolicyConfig(config));
831
+ if (!baseDecision.allowed) return baseDecision;
832
+ if (options.directCall) {
833
+ const directDecision = checkDirectCallPolicy(
834
+ policyTool,
835
+ config.get("directCalls")
836
+ );
837
+ if (!directDecision.allowed) return directDecision;
838
+ }
839
+ return { allowed: true, entry };
840
+ }
841
+
415
842
  // plugins/plugin-codecall/src/services/synonym-expansion.service.ts
416
843
  var DEFAULT_SYNONYM_GROUPS = [
417
844
  // ===========================================================================
@@ -1080,62 +1507,12 @@ var ToolSearchService = class _ToolSearchService {
1080
1507
  this.initialized = true;
1081
1508
  }
1082
1509
  /**
1083
- * Determines if a tool should be indexed in the search database.
1084
- * Filters based on:
1085
- * - Excludes codecall:* meta-tools (they should not be searchable)
1086
- * - Excludes tools with hideFromDiscovery: true (system tools like sendElicitationResult)
1087
- * - Mode-based filtering (codecall_only, codecall_opt_in, metadata_driven)
1088
- * - Per-tool metadata.codecall.enabledInCodeCall
1089
- * - Custom includeTools filter function
1510
+ * Whether a tool belongs in the search index: exactly when CodeCall may execute it.
1511
+ * The decision is `codecall:execute`'s own, so search cannot show a tool execution refuses
1512
+ * or hide one it runs (GHSA-6w3j-82v5-6qrr).
1090
1513
  */
1091
1514
  shouldIndexTool(tool) {
1092
- const toolName = tool.name || tool.fullName;
1093
- if (toolName.startsWith("codecall:")) {
1094
- return false;
1095
- }
1096
- if (tool.metadata.hideFromDiscovery === true) {
1097
- return false;
1098
- }
1099
- const codecallMeta = this.getCodeCallMetadata(tool);
1100
- switch (this.config.mode) {
1101
- case "codecall_only":
1102
- if (codecallMeta?.enabledInCodeCall === false) {
1103
- return false;
1104
- }
1105
- break;
1106
- case "codecall_opt_in":
1107
- if (codecallMeta?.enabledInCodeCall !== true) {
1108
- return false;
1109
- }
1110
- break;
1111
- case "metadata_driven":
1112
- if (codecallMeta?.enabledInCodeCall === false) {
1113
- return false;
1114
- }
1115
- break;
1116
- default:
1117
- throw new Error(`Unknown CodeCall mode: ${this.config.mode}`);
1118
- }
1119
- if (this.config.includeTools) {
1120
- const appId = this.extractAppId(tool);
1121
- const filterInfo = {
1122
- name: toolName,
1123
- appId,
1124
- source: codecallMeta?.source,
1125
- description: tool.metadata.description,
1126
- tags: codecallMeta?.tags || tool.metadata.tags
1127
- };
1128
- if (!this.config.includeTools(filterInfo)) {
1129
- return false;
1130
- }
1131
- }
1132
- return true;
1133
- }
1134
- /**
1135
- * Extract CodeCall-specific metadata from a tool.
1136
- */
1137
- getCodeCallMetadata(tool) {
1138
- return tool.metadata?.codecall;
1515
+ return checkCodeCallToolPolicy(toCodeCallPolicyTool(tool, void 0, this.scope), this.config).allowed;
1139
1516
  }
1140
1517
  /**
1141
1518
  * Initializes the search service by indexing all tools from the registry.
@@ -1225,11 +1602,7 @@ var ToolSearchService = class _ToolSearchService {
1225
1602
  * Extracts app ID from tool's owner lineage
1226
1603
  */
1227
1604
  extractAppId(tool) {
1228
- if (!tool.owner) return void 0;
1229
- if (tool.owner.kind === "app") {
1230
- return tool.owner.id;
1231
- }
1232
- return void 0;
1605
+ return codeCallAppIdOf(this.scope, tool);
1233
1606
  }
1234
1607
  /**
1235
1608
  * Searches for tools matching the query
@@ -1316,7 +1689,7 @@ var ToolSearchService = class _ToolSearchService {
1316
1689
 
1317
1690
  // plugins/plugin-codecall/src/services/enclave.service.ts
1318
1691
  var import_core = require("@enclave-vm/core");
1319
- var import_sdk2 = require("@frontmcp/sdk");
1692
+ var import_sdk3 = require("@frontmcp/sdk");
1320
1693
  var ScriptTooLargeError = class extends Error {
1321
1694
  code = "SCRIPT_TOO_LARGE";
1322
1695
  scriptLength;
@@ -1435,15 +1808,23 @@ var EnclaveService = class {
1435
1808
  const error = result.error;
1436
1809
  const timedOut = error.message?.includes("timed out") || error.code === "TIMEOUT";
1437
1810
  if (error.code === "VALIDATION_ERROR") {
1811
+ const issues = error.data?.issues ?? [];
1812
+ const blockedPatterns = [...new Set(issues.map((issue) => issue.code).filter((code) => !!code))];
1438
1813
  return {
1439
1814
  success: false,
1440
1815
  error: {
1441
1816
  message: error.message,
1442
1817
  name: "ValidationError",
1443
- code: error.code
1818
+ code: error.code,
1819
+ ...blockedPatterns.length > 0 ? { blockedPatterns } : {}
1444
1820
  },
1445
1821
  logs,
1446
- timedOut: false
1822
+ timedOut: false,
1823
+ stats: {
1824
+ duration: result.stats.duration,
1825
+ toolCallCount: result.stats.toolCallCount,
1826
+ iterationCount: result.stats.iterationCount
1827
+ }
1447
1828
  };
1448
1829
  }
1449
1830
  const errorData = error.data;
@@ -1483,15 +1864,15 @@ var EnclaveService = class {
1483
1864
  }
1484
1865
  };
1485
1866
  EnclaveService = __decorateClass([
1486
- (0, import_sdk2.Provider)({
1867
+ (0, import_sdk3.Provider)({
1487
1868
  name: "codecall:enclave",
1488
1869
  description: "Executes AgentScript code in a secure enclave",
1489
- scope: import_sdk2.ProviderScope.GLOBAL
1870
+ scope: import_sdk3.ProviderScope.GLOBAL
1490
1871
  })
1491
1872
  ], EnclaveService);
1492
1873
 
1493
1874
  // plugins/plugin-codecall/src/tools/search.tool.ts
1494
- var import_sdk3 = require("@frontmcp/sdk");
1875
+ var import_sdk4 = require("@frontmcp/sdk");
1495
1876
 
1496
1877
  // plugins/plugin-codecall/src/tools/search.schema.ts
1497
1878
  var import_lazy_zod2 = require("@frontmcp/lazy-zod");
@@ -1541,11 +1922,14 @@ var searchToolOutputSchema = import_lazy_zod2.z.object({
1541
1922
  });
1542
1923
 
1543
1924
  // plugins/plugin-codecall/src/tools/search.tool.ts
1544
- var SearchTool = class extends import_sdk3.ToolContext {
1925
+ var SearchTool = class extends import_sdk4.ToolContext {
1545
1926
  async execute(input) {
1546
1927
  const { queries, appIds, excludeToolNames = [], topK = 5, minRelevanceScore = 0.3 } = input;
1547
1928
  const searchService = this.get(ToolSearchService);
1548
1929
  const warnings = [];
1930
+ const audit = this.tryGet(AuditLoggerService);
1931
+ const executionId = audit ? audit.generateExecutionId() : "";
1932
+ const startedAt = Date.now();
1549
1933
  const nonExistentExcludedTools = excludeToolNames.filter((toolName) => !searchService.hasTool(toolName));
1550
1934
  if (nonExistentExcludedTools.length > 0) {
1551
1935
  warnings.push({
@@ -1601,6 +1985,7 @@ var SearchTool = class extends import_sdk3.ToolContext {
1601
1985
  message: `${lowRelevanceCount} result(s) filtered due to relevance below ${minRelevanceScore}`
1602
1986
  });
1603
1987
  }
1988
+ audit?.logSearch(executionId, queries.join(" "), tools.length, Date.now() - startedAt);
1604
1989
  return {
1605
1990
  tools,
1606
1991
  warnings,
@@ -1609,7 +1994,7 @@ var SearchTool = class extends import_sdk3.ToolContext {
1609
1994
  }
1610
1995
  };
1611
1996
  SearchTool = __decorateClass([
1612
- (0, import_sdk3.Tool)({
1997
+ (0, import_sdk4.Tool)({
1613
1998
  name: "codecall:search",
1614
1999
  cache: {
1615
2000
  ttl: 60,
@@ -1631,7 +2016,7 @@ SearchTool = __decorateClass([
1631
2016
  ], SearchTool);
1632
2017
 
1633
2018
  // plugins/plugin-codecall/src/tools/search-skills.tool.ts
1634
- var import_sdk4 = require("@frontmcp/sdk");
2019
+ var import_sdk5 = require("@frontmcp/sdk");
1635
2020
 
1636
2021
  // plugins/plugin-codecall/src/tools/search-skills.schema.ts
1637
2022
  var import_lazy_zod3 = require("@frontmcp/lazy-zod");
@@ -1688,11 +2073,11 @@ var searchSkillsToolOutputSchema = import_lazy_zod3.z.object({
1688
2073
  });
1689
2074
 
1690
2075
  // plugins/plugin-codecall/src/tools/search-skills.tool.ts
1691
- var SearchSkillsTool = class extends import_sdk4.ToolContext {
2076
+ var SearchSkillsTool = class extends import_sdk5.ToolContext {
1692
2077
  async execute(input) {
1693
2078
  const { queries, tags, excludeSkillNames = [], topK = 5, minRelevanceScore = 0.1 } = input;
1694
2079
  const skillRegistry = this.scope.skills;
1695
- const executableSkills = skillRegistry.getExecutableSkills();
2080
+ const executableSkills = await (0, import_sdk5.filterServableSkills)(this.scope, skillRegistry.getExecutableSkills());
1696
2081
  const executableSet = new Set(executableSkills.map((s) => s.name));
1697
2082
  const totalExecutableSkills = executableSkills.length;
1698
2083
  const warnings = [];
@@ -1762,7 +2147,7 @@ var SearchSkillsTool = class extends import_sdk4.ToolContext {
1762
2147
  }
1763
2148
  };
1764
2149
  SearchSkillsTool = __decorateClass([
1765
- (0, import_sdk4.Tool)({
2150
+ (0, import_sdk5.Tool)({
1766
2151
  name: "codecall:searchSkills",
1767
2152
  cache: {
1768
2153
  ttl: 60,
@@ -1783,7 +2168,7 @@ SearchSkillsTool = __decorateClass([
1783
2168
  ], SearchSkillsTool);
1784
2169
 
1785
2170
  // plugins/plugin-codecall/src/tools/search-knowledge.tool.ts
1786
- var import_sdk5 = require("@frontmcp/sdk");
2171
+ var import_sdk6 = require("@frontmcp/sdk");
1787
2172
 
1788
2173
  // plugins/plugin-codecall/src/tools/search-knowledge.schema.ts
1789
2174
  var import_lazy_zod4 = require("@frontmcp/lazy-zod");
@@ -1829,11 +2214,11 @@ var searchKnowledgeToolOutputSchema = import_lazy_zod4.z.object({
1829
2214
  });
1830
2215
 
1831
2216
  // plugins/plugin-codecall/src/tools/search-knowledge.tool.ts
1832
- var SearchKnowledgeTool = class extends import_sdk5.ToolContext {
2217
+ var SearchKnowledgeTool = class extends import_sdk6.ToolContext {
1833
2218
  async execute(input) {
1834
2219
  const { queries, tags, excludeSkillNames = [], topK = 5, minRelevanceScore = 0.1 } = input;
1835
2220
  const skillRegistry = this.scope.skills;
1836
- const knowledgeSkills = skillRegistry.getKnowledgeOnlySkills();
2221
+ const knowledgeSkills = await (0, import_sdk6.filterServableSkills)(this.scope, skillRegistry.getKnowledgeOnlySkills());
1837
2222
  const knowledgeSet = new Set(knowledgeSkills.map((s) => s.name));
1838
2223
  const totalKnowledgeSkills = knowledgeSkills.length;
1839
2224
  const warnings = [];
@@ -1895,7 +2280,7 @@ var SearchKnowledgeTool = class extends import_sdk5.ToolContext {
1895
2280
  }
1896
2281
  };
1897
2282
  SearchKnowledgeTool = __decorateClass([
1898
- (0, import_sdk5.Tool)({
2283
+ (0, import_sdk6.Tool)({
1899
2284
  name: "codecall:searchKnowledge",
1900
2285
  cache: {
1901
2286
  ttl: 60,
@@ -1917,7 +2302,7 @@ SearchKnowledgeTool = __decorateClass([
1917
2302
 
1918
2303
  // plugins/plugin-codecall/src/tools/describe.tool.ts
1919
2304
  var import_lazy_zod6 = require("@frontmcp/lazy-zod");
1920
- var import_sdk6 = require("@frontmcp/sdk");
2305
+ var import_sdk7 = require("@frontmcp/sdk");
1921
2306
 
1922
2307
  // plugins/plugin-codecall/src/errors/tool-call.errors.ts
1923
2308
  var TOOL_CALL_ERROR_CODES = {
@@ -2418,24 +2803,27 @@ var describeToolOutputSchema = import_lazy_zod5.z.object({
2418
2803
  });
2419
2804
 
2420
2805
  // plugins/plugin-codecall/src/tools/describe.tool.ts
2421
- var DescribeTool = class extends import_sdk6.ToolContext {
2806
+ var DescribeTool = class extends import_sdk7.ToolContext {
2422
2807
  async execute(input) {
2423
2808
  const { toolNames } = input;
2809
+ const audit = this.tryGet(AuditLoggerService);
2810
+ const executionId = audit ? audit.generateExecutionId() : "";
2811
+ const startedAt = Date.now();
2424
2812
  const tools = [];
2425
2813
  const notFound = [];
2426
- const allTools = this.scope.tools.getTools(true);
2427
- const toolMap = new Map(allTools.map((t) => [t.name, t]));
2428
- const fullNameMap = new Map(allTools.map((t) => [t.fullName, t]));
2814
+ const config = this.get(CodeCallConfig);
2429
2815
  for (const toolName of toolNames) {
2430
2816
  if (isBlockedSelfReference(toolName)) {
2431
2817
  notFound.push(toolName);
2432
2818
  continue;
2433
2819
  }
2434
- const tool = toolMap.get(toolName) || fullNameMap.get(toolName);
2435
- if (!tool) {
2820
+ const access = checkCodeCallToolAccess(this.scope, config, toolName);
2821
+ if (!access.allowed) {
2822
+ audit?.logSecurityAccessDenied(executionId, toolName, access.reason);
2436
2823
  notFound.push(toolName);
2437
2824
  continue;
2438
2825
  }
2826
+ const tool = access.entry;
2439
2827
  const appId = this.extractAppId(tool);
2440
2828
  const inputSchema = this.getInputSchema(tool);
2441
2829
  const outputSchema = this.toJsonSchema(tool.rawOutputSchema ?? tool.outputSchema);
@@ -2450,6 +2838,7 @@ var DescribeTool = class extends import_sdk6.ToolContext {
2450
2838
  usageExamples
2451
2839
  });
2452
2840
  }
2841
+ audit?.logDescribe(executionId, toolNames, Date.now() - startedAt);
2453
2842
  return {
2454
2843
  tools,
2455
2844
  notFound: notFound.length > 0 ? notFound : void 0
@@ -2564,7 +2953,7 @@ return result;`
2564
2953
  }
2565
2954
  };
2566
2955
  DescribeTool = __decorateClass([
2567
- (0, import_sdk6.Tool)({
2956
+ (0, import_sdk7.Tool)({
2568
2957
  name: "codecall:describe",
2569
2958
  cache: {
2570
2959
  ttl: 60,
@@ -2586,7 +2975,7 @@ DescribeTool = __decorateClass([
2586
2975
  ], DescribeTool);
2587
2976
 
2588
2977
  // plugins/plugin-codecall/src/tools/execute.tool.ts
2589
- var import_sdk7 = require("@frontmcp/sdk");
2978
+ var import_sdk8 = require("@frontmcp/sdk");
2590
2979
 
2591
2980
  // plugins/plugin-codecall/src/tools/execute.schema.ts
2592
2981
  var import_lazy_zod7 = require("@frontmcp/lazy-zod");
@@ -2703,21 +3092,52 @@ function getErrorCode(error) {
2703
3092
  }
2704
3093
  return TOOL_CALL_ERROR_CODES.EXECUTION;
2705
3094
  }
2706
- var ExecuteTool = class extends import_sdk7.ToolContext {
3095
+ var ExecuteTool = class extends import_sdk8.ToolContext {
3096
+ /**
3097
+ * Resolve the server-side CodeCall policy for a tool name (GHSA-6w3j-82v5-6qrr).
3098
+ *
3099
+ * Shares its decision with discovery and with `codecall:invoke`, so the three cannot
3100
+ * diverge. A name matching no registered tool is denied rather than passed through —
3101
+ * otherwise it would skip every metadata-driven check and reach `tools:call-tool`
3102
+ * unexamined.
3103
+ */
3104
+ checkToolPolicy(name) {
3105
+ return checkCodeCallToolAccess(this.scope, this.get(CodeCallConfig), name);
3106
+ }
2707
3107
  async execute(input) {
2708
3108
  const { script, allowedTools } = input;
3109
+ const audit = this.tryGet(AuditLoggerService);
3110
+ const executionId = audit ? audit.generateExecutionId() : "";
3111
+ const callDepth = 1;
3112
+ let toolCallCount = 0;
2709
3113
  const allowedToolSet = allowedTools ? new Set(allowedTools) : null;
2710
3114
  const environment = {
2711
3115
  callTool: async (name, toolInput, options) => {
2712
3116
  const throwOnError = options?.throwOnError !== false;
3117
+ if (isBlockedSelfReference(name)) {
3118
+ audit?.logSecuritySelfReference(executionId, name);
3119
+ }
2713
3120
  assertNotSelfReference(name);
3121
+ const decision = this.checkToolPolicy(name);
3122
+ if (!decision.allowed) {
3123
+ audit?.logSecurityAccessDenied(executionId, name, decision.reason);
3124
+ const error = createToolCallError(TOOL_CALL_ERROR_CODES.ACCESS_DENIED, name, decision.reason);
3125
+ if (throwOnError) {
3126
+ throw error;
3127
+ }
3128
+ return { success: false, error };
3129
+ }
2714
3130
  if (allowedToolSet && !allowedToolSet.has(name)) {
3131
+ audit?.logSecurityAccessDenied(executionId, name, "not in the caller-supplied allowedTools list");
2715
3132
  const error = createToolCallError(TOOL_CALL_ERROR_CODES.ACCESS_DENIED, name);
2716
3133
  if (throwOnError) {
2717
3134
  throw error;
2718
3135
  }
2719
3136
  return { success: false, error };
2720
3137
  }
3138
+ toolCallCount += 1;
3139
+ audit?.logToolCallStart(executionId, name, callDepth);
3140
+ const toolCallStartedAt = Date.now();
2721
3141
  try {
2722
3142
  const request = {
2723
3143
  method: "tools/call",
@@ -2731,6 +3151,13 @@ var ExecuteTool = class extends import_sdk7.ToolContext {
2731
3151
  };
2732
3152
  const mcpResult = await this.scope.runFlow("tools:call-tool", { request, ctx });
2733
3153
  if (!mcpResult) {
3154
+ audit?.logToolCallFailure(
3155
+ executionId,
3156
+ name,
3157
+ callDepth,
3158
+ Date.now() - toolCallStartedAt,
3159
+ TOOL_CALL_ERROR_CODES.EXECUTION
3160
+ );
2734
3161
  const error = createToolCallError(TOOL_CALL_ERROR_CODES.EXECUTION, name, "Flow returned no result");
2735
3162
  if (throwOnError) {
2736
3163
  throw error;
@@ -2738,6 +3165,7 @@ var ExecuteTool = class extends import_sdk7.ToolContext {
2738
3165
  return { success: false, error };
2739
3166
  }
2740
3167
  const result = extractResultFromCallToolResult(mcpResult);
3168
+ audit?.logToolCallSuccess(executionId, name, callDepth, Date.now() - toolCallStartedAt);
2741
3169
  if (throwOnError) {
2742
3170
  return result;
2743
3171
  }
@@ -2745,6 +3173,7 @@ var ExecuteTool = class extends import_sdk7.ToolContext {
2745
3173
  } catch (error) {
2746
3174
  const errorCode = getErrorCode(error);
2747
3175
  const rawMessage = error instanceof Error ? error.message : void 0;
3176
+ audit?.logToolCallFailure(executionId, name, callDepth, Date.now() - toolCallStartedAt, errorCode);
2748
3177
  const sanitizedError = createToolCallError(errorCode, name, rawMessage);
2749
3178
  if (throwOnError) {
2750
3179
  throw sanitizedError;
@@ -2754,11 +3183,17 @@ var ExecuteTool = class extends import_sdk7.ToolContext {
2754
3183
  },
2755
3184
  getTool: (name) => {
2756
3185
  try {
2757
- if (isBlockedSelfReference(name)) return void 0;
3186
+ if (isBlockedSelfReference(name)) {
3187
+ audit?.logSecuritySelfReference(executionId, name);
3188
+ return void 0;
3189
+ }
3190
+ const introspectionAccess = this.checkToolPolicy(name);
3191
+ if (!introspectionAccess.allowed) {
3192
+ audit?.logSecurityAccessDenied(executionId, name, introspectionAccess.reason);
3193
+ return void 0;
3194
+ }
2758
3195
  if (allowedToolSet && !allowedToolSet.has(name)) return void 0;
2759
- const tools = this.scope.tools.getTools(true);
2760
- const tool = tools.find((t) => t.name === name || t.fullName === name);
2761
- if (!tool) return void 0;
3196
+ const tool = introspectionAccess.entry;
2762
3197
  return toPlainJson({
2763
3198
  name: tool.name,
2764
3199
  description: tool.metadata?.description,
@@ -2778,8 +3213,11 @@ var ExecuteTool = class extends import_sdk7.ToolContext {
2778
3213
  }
2779
3214
  };
2780
3215
  try {
2781
- const registeredTools = this.scope.tools.getTools(true);
2782
- const { namespaces, skipped } = buildToolNamespaces(registeredTools, environment.callTool);
3216
+ const policyConfig = readCodeCallPolicyConfig(this.get(CodeCallConfig));
3217
+ const callableTools = this.scope.tools.getTools(true).filter(
3218
+ (tool) => checkCodeCallToolPolicy(toCodeCallPolicyTool(tool, void 0, this.scope), policyConfig).allowed
3219
+ );
3220
+ const { namespaces, skipped } = buildToolNamespaces(callableTools, environment.callTool);
2783
3221
  environment.namespaces = namespaces;
2784
3222
  if (skipped.length > 0) {
2785
3223
  this.logger?.debug?.("codecall: tools skipped during namespace generation", {
@@ -2795,9 +3233,14 @@ var ExecuteTool = class extends import_sdk7.ToolContext {
2795
3233
  }
2796
3234
  const enclaveService = this.get(EnclaveService);
2797
3235
  const config = this.get(CodeCallConfig);
3236
+ const startedAt = Date.now();
3237
+ const elapsed = (reported) => reported ?? Date.now() - startedAt;
3238
+ audit?.logExecutionStart(executionId, script);
2798
3239
  try {
2799
3240
  const executionResult = await enclaveService.execute(script, environment);
3241
+ const durationMs = elapsed(executionResult.stats?.duration);
2800
3242
  if (executionResult.timedOut) {
3243
+ audit?.logExecutionTimeout(executionId, script, durationMs);
2801
3244
  return {
2802
3245
  status: "timeout",
2803
3246
  error: {
@@ -2808,6 +3251,8 @@ var ExecuteTool = class extends import_sdk7.ToolContext {
2808
3251
  if (!executionResult.success) {
2809
3252
  const error = executionResult.error;
2810
3253
  if (error.code === "VALIDATION_ERROR" || error.name === "ValidationError") {
3254
+ audit?.logSecurityAstBlocked(executionId, error.blockedPatterns?.join(", ") ?? "UNKNOWN", error.message);
3255
+ audit?.logExecutionFailure(executionId, script, durationMs, error.message);
2811
3256
  return {
2812
3257
  status: "illegal_access",
2813
3258
  error: {
@@ -2817,6 +3262,7 @@ var ExecuteTool = class extends import_sdk7.ToolContext {
2817
3262
  };
2818
3263
  }
2819
3264
  if (error.toolName) {
3265
+ audit?.logExecutionFailure(executionId, script, durationMs, error.message);
2820
3266
  return {
2821
3267
  status: "tool_error",
2822
3268
  error: {
@@ -2829,6 +3275,7 @@ var ExecuteTool = class extends import_sdk7.ToolContext {
2829
3275
  }
2830
3276
  };
2831
3277
  }
3278
+ audit?.logExecutionFailure(executionId, script, durationMs, error.message);
2832
3279
  return {
2833
3280
  status: "runtime_error",
2834
3281
  error: {
@@ -2839,6 +3286,7 @@ var ExecuteTool = class extends import_sdk7.ToolContext {
2839
3286
  }
2840
3287
  };
2841
3288
  }
3289
+ audit?.logExecutionSuccess(executionId, script, durationMs, toolCallCount);
2842
3290
  return {
2843
3291
  status: "ok",
2844
3292
  result: executionResult.result,
@@ -2847,6 +3295,7 @@ var ExecuteTool = class extends import_sdk7.ToolContext {
2847
3295
  } catch (error) {
2848
3296
  const errorName = error instanceof Error ? error.name : "Error";
2849
3297
  const errorMessage = error instanceof Error ? error.message : String(error);
3298
+ audit?.logExecutionFailure(executionId, script, elapsed(), errorMessage);
2850
3299
  const errorStack = error instanceof Error ? error.stack : void 0;
2851
3300
  const errorLoc = error.loc;
2852
3301
  if (errorName === "SyntaxError" || errorMessage?.includes("syntax")) {
@@ -2871,7 +3320,7 @@ var ExecuteTool = class extends import_sdk7.ToolContext {
2871
3320
  }
2872
3321
  };
2873
3322
  ExecuteTool = __decorateClass([
2874
- (0, import_sdk7.Tool)({
3323
+ (0, import_sdk8.Tool)({
2875
3324
  name: "codecall:execute",
2876
3325
  cache: {
2877
3326
  ttl: 0,
@@ -2889,7 +3338,7 @@ ExecuteTool = __decorateClass([
2889
3338
  ], ExecuteTool);
2890
3339
 
2891
3340
  // plugins/plugin-codecall/src/tools/invoke.tool.ts
2892
- var import_sdk8 = require("@frontmcp/sdk");
3341
+ var import_sdk9 = require("@frontmcp/sdk");
2893
3342
 
2894
3343
  // plugins/plugin-codecall/src/tools/invoke.schema.ts
2895
3344
  var import_lazy_zod8 = require("@frontmcp/lazy-zod");
@@ -2921,14 +3370,23 @@ function buildErrorResult(message) {
2921
3370
  isError: true
2922
3371
  };
2923
3372
  }
2924
- var InvokeTool = class extends import_sdk8.ToolContext {
3373
+ var InvokeTool = class extends import_sdk9.ToolContext {
2925
3374
  async execute(input) {
2926
3375
  const { tool: toolName, input: toolInput } = input;
3376
+ const audit = this.tryGet(AuditLoggerService);
3377
+ const executionId = audit ? audit.generateExecutionId() : "";
3378
+ const startedAt = Date.now();
2927
3379
  if (isBlockedSelfReference(toolName)) {
3380
+ audit?.logSecuritySelfReference(executionId, toolName);
2928
3381
  return buildErrorResult(
2929
3382
  `Tool "${toolName}" cannot be invoked directly. CodeCall tools are internal and not accessible via codecall:invoke.`
2930
3383
  );
2931
3384
  }
3385
+ const decision = checkCodeCallToolAccess(this.scope, this.get(CodeCallConfig), toolName, { directCall: true });
3386
+ if (!decision.allowed) {
3387
+ audit?.logSecurityAccessDenied(executionId, toolName, decision.reason);
3388
+ return buildErrorResult(`Tool "${toolName}" is not available. Use codecall:search to discover available tools.`);
3389
+ }
2932
3390
  const request = {
2933
3391
  method: "tools/call",
2934
3392
  params: {
@@ -2941,13 +3399,15 @@ var InvokeTool = class extends import_sdk8.ToolContext {
2941
3399
  };
2942
3400
  const result = await this.scope.runFlow("tools:call-tool", { request, ctx });
2943
3401
  if (!result) {
3402
+ audit?.logInvoke(executionId, toolName, false, Date.now() - startedAt);
2944
3403
  return buildErrorResult(`Tool "${toolName}" not found. Use codecall:search to discover available tools.`);
2945
3404
  }
3405
+ audit?.logInvoke(executionId, toolName, true, Date.now() - startedAt);
2946
3406
  return result;
2947
3407
  }
2948
3408
  };
2949
3409
  InvokeTool = __decorateClass([
2950
- (0, import_sdk8.Tool)({
3410
+ (0, import_sdk9.Tool)({
2951
3411
  name: "codecall:invoke",
2952
3412
  cache: {
2953
3413
  ttl: 0,
@@ -2965,12 +3425,16 @@ InvokeTool = __decorateClass([
2965
3425
  ], InvokeTool);
2966
3426
 
2967
3427
  // plugins/plugin-codecall/src/codecall.plugin.ts
2968
- var CodeCallPlugin = class extends import_sdk9.DynamicPlugin {
3428
+ function auditLogFields(event) {
3429
+ const { executionId, durationMs, data } = event;
3430
+ return durationMs === void 0 ? { executionId, ...data } : { executionId, durationMs, ...data };
3431
+ }
3432
+ var CodeCallPlugin = class extends import_sdk10.DynamicPlugin {
2969
3433
  options;
2970
3434
  cachedLogger;
2971
3435
  getLogger() {
2972
3436
  if (!this.cachedLogger) {
2973
- this.cachedLogger = this.get(import_sdk9.FrontMcpLogger).child("CodeCall");
3437
+ this.cachedLogger = this.get(import_sdk10.FrontMcpLogger).child("CodeCall");
2974
3438
  }
2975
3439
  return this.cachedLogger;
2976
3440
  }
@@ -2999,10 +3463,25 @@ var CodeCallPlugin = class extends import_sdk9.DynamicPlugin {
2999
3463
  return new EnclaveService(cfg);
3000
3464
  }
3001
3465
  },
3466
+ {
3467
+ // GHSA-adjacent: production.mdx promised operators these events and nothing emitted them,
3468
+ // because the service was never registered. The subscription lives here, in the factory,
3469
+ // for a reason: there is no provider teardown hook in the SDK, so subscribing anywhere
3470
+ // per-request would grow the listener Set for the life of the process.
3471
+ name: "codecall:audit-logger",
3472
+ provide: AuditLoggerService,
3473
+ inject: () => [import_sdk10.ScopeEntry],
3474
+ useFactory: (scope) => {
3475
+ const audit = new AuditLoggerService();
3476
+ const logger = scope.logger.child("codecall:audit");
3477
+ audit.subscribe((event) => logger.info(event.type, auditLogFields(event)));
3478
+ return audit;
3479
+ }
3480
+ },
3002
3481
  {
3003
3482
  name: "codecall:tool-search",
3004
3483
  provide: ToolSearchService,
3005
- inject: () => [import_sdk9.ScopeEntry],
3484
+ inject: () => [import_sdk10.ScopeEntry],
3006
3485
  useFactory: async (scope) => {
3007
3486
  return new ToolSearchService(
3008
3487
  {
@@ -3084,10 +3563,10 @@ var CodeCallPlugin = class extends import_sdk9.DynamicPlugin {
3084
3563
  }
3085
3564
  };
3086
3565
  __decorateClass([
3087
- import_sdk9.ListToolsHook.Did("resolveConflicts", { priority: 1e3 })
3566
+ import_sdk10.ListToolsHook.Did("resolveConflicts", { priority: 1e3 })
3088
3567
  ], CodeCallPlugin.prototype, "adjustListTools", 1);
3089
3568
  CodeCallPlugin = __decorateClass([
3090
- (0, import_sdk9.Plugin)({
3569
+ (0, import_sdk10.Plugin)({
3091
3570
  name: "codecall",
3092
3571
  description: "CodeCall plugin: AgentScript-based meta-tools for orchestrating MCP tools",
3093
3572
  providers: [],
@@ -3097,6 +3576,8 @@ CodeCallPlugin = __decorateClass([
3097
3576
  ], CodeCallPlugin);
3098
3577
  // Annotate the CommonJS export names for ESM import in node:
3099
3578
  0 && (module.exports = {
3579
+ AUDIT_EVENT_TYPES,
3580
+ AuditLoggerService,
3100
3581
  CodeCallPlugin,
3101
3582
  codeCallDirectCallsOptionsSchema,
3102
3583
  codeCallEmbeddingOptionsSchema,