@sandrobuilds/tracerney 0.9.6

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.
Files changed (138) hide show
  1. package/README.md +702 -0
  2. package/dist/application/ShieldApplicationService.d.ts +94 -0
  3. package/dist/application/ShieldApplicationService.d.ts.map +1 -0
  4. package/dist/application/ShieldApplicationService.js +223 -0
  5. package/dist/application/ShieldApplicationService.js.map +1 -0
  6. package/dist/application/ShieldBlockError.d.ts +10 -0
  7. package/dist/application/ShieldBlockError.d.ts.map +1 -0
  8. package/dist/application/ShieldBlockError.js +13 -0
  9. package/dist/application/ShieldBlockError.js.map +1 -0
  10. package/dist/application/index.d.ts +9 -0
  11. package/dist/application/index.d.ts.map +1 -0
  12. package/dist/application/index.js +8 -0
  13. package/dist/application/index.js.map +1 -0
  14. package/dist/application/ports/ILLMProvider.d.ts +71 -0
  15. package/dist/application/ports/ILLMProvider.d.ts.map +1 -0
  16. package/dist/application/ports/ILLMProvider.js +15 -0
  17. package/dist/application/ports/ILLMProvider.js.map +1 -0
  18. package/dist/application/ports/IPatternRepository.d.ts +20 -0
  19. package/dist/application/ports/IPatternRepository.d.ts.map +1 -0
  20. package/dist/application/ports/IPatternRepository.js +7 -0
  21. package/dist/application/ports/IPatternRepository.js.map +1 -0
  22. package/dist/application/ports/ISentinel.d.ts +22 -0
  23. package/dist/application/ports/ISentinel.d.ts.map +1 -0
  24. package/dist/application/ports/ISentinel.js +8 -0
  25. package/dist/application/ports/ISentinel.js.map +1 -0
  26. package/dist/application/ports/ITelemetrySink.d.ts +35 -0
  27. package/dist/application/ports/ITelemetrySink.d.ts.map +1 -0
  28. package/dist/application/ports/ITelemetrySink.js +7 -0
  29. package/dist/application/ports/ITelemetrySink.js.map +1 -0
  30. package/dist/application/ports/index.d.ts +10 -0
  31. package/dist/application/ports/index.d.ts.map +1 -0
  32. package/dist/application/ports/index.js +7 -0
  33. package/dist/application/ports/index.js.map +1 -0
  34. package/dist/application/utils/index.d.ts +6 -0
  35. package/dist/application/utils/index.d.ts.map +1 -0
  36. package/dist/application/utils/index.js +6 -0
  37. package/dist/application/utils/index.js.map +1 -0
  38. package/dist/application/utils/jitter.d.ts +10 -0
  39. package/dist/application/utils/jitter.d.ts.map +1 -0
  40. package/dist/application/utils/jitter.js +13 -0
  41. package/dist/application/utils/jitter.js.map +1 -0
  42. package/dist/application/utils/normalizePrompt.d.ts +18 -0
  43. package/dist/application/utils/normalizePrompt.d.ts.map +1 -0
  44. package/dist/application/utils/normalizePrompt.js +36 -0
  45. package/dist/application/utils/normalizePrompt.js.map +1 -0
  46. package/dist/domain/detection/InjectionThreat.d.ts +19 -0
  47. package/dist/domain/detection/InjectionThreat.d.ts.map +1 -0
  48. package/dist/domain/detection/InjectionThreat.js +18 -0
  49. package/dist/domain/detection/InjectionThreat.js.map +1 -0
  50. package/dist/domain/detection/PatternMatcher.d.ts +36 -0
  51. package/dist/domain/detection/PatternMatcher.d.ts.map +1 -0
  52. package/dist/domain/detection/PatternMatcher.js +65 -0
  53. package/dist/domain/detection/PatternMatcher.js.map +1 -0
  54. package/dist/domain/detection/VanguardPattern.d.ts +19 -0
  55. package/dist/domain/detection/VanguardPattern.d.ts.map +1 -0
  56. package/dist/domain/detection/VanguardPattern.js +21 -0
  57. package/dist/domain/detection/VanguardPattern.js.map +1 -0
  58. package/dist/domain/detection/index.d.ts +11 -0
  59. package/dist/domain/detection/index.d.ts.map +1 -0
  60. package/dist/domain/detection/index.js +8 -0
  61. package/dist/domain/detection/index.js.map +1 -0
  62. package/dist/domain/events/SecurityEvent.d.ts +30 -0
  63. package/dist/domain/events/SecurityEvent.d.ts.map +1 -0
  64. package/dist/domain/events/SecurityEvent.js +21 -0
  65. package/dist/domain/events/SecurityEvent.js.map +1 -0
  66. package/dist/domain/events/SecurityEventType.d.ts +13 -0
  67. package/dist/domain/events/SecurityEventType.d.ts.map +1 -0
  68. package/dist/domain/events/SecurityEventType.js +15 -0
  69. package/dist/domain/events/SecurityEventType.js.map +1 -0
  70. package/dist/domain/events/ThreatSeverity.d.ts +13 -0
  71. package/dist/domain/events/ThreatSeverity.d.ts.map +1 -0
  72. package/dist/domain/events/ThreatSeverity.js +15 -0
  73. package/dist/domain/events/ThreatSeverity.js.map +1 -0
  74. package/dist/domain/events/index.d.ts +11 -0
  75. package/dist/domain/events/index.d.ts.map +1 -0
  76. package/dist/domain/events/index.js +8 -0
  77. package/dist/domain/events/index.js.map +1 -0
  78. package/dist/domain/guard/ToolGuard.d.ts +35 -0
  79. package/dist/domain/guard/ToolGuard.d.ts.map +1 -0
  80. package/dist/domain/guard/ToolGuard.js +49 -0
  81. package/dist/domain/guard/ToolGuard.js.map +1 -0
  82. package/dist/domain/guard/ToolPolicy.d.ts +16 -0
  83. package/dist/domain/guard/ToolPolicy.d.ts.map +1 -0
  84. package/dist/domain/guard/ToolPolicy.js +19 -0
  85. package/dist/domain/guard/ToolPolicy.js.map +1 -0
  86. package/dist/domain/guard/ToolViolation.d.ts +14 -0
  87. package/dist/domain/guard/ToolViolation.d.ts.map +1 -0
  88. package/dist/domain/guard/ToolViolation.js +15 -0
  89. package/dist/domain/guard/ToolViolation.js.map +1 -0
  90. package/dist/domain/guard/index.d.ts +11 -0
  91. package/dist/domain/guard/index.d.ts.map +1 -0
  92. package/dist/domain/guard/index.js +8 -0
  93. package/dist/domain/guard/index.js.map +1 -0
  94. package/dist/index.d.ts +168 -0
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +173 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/infrastructure/llm/OpenRouterProvider.d.ts +32 -0
  99. package/dist/infrastructure/llm/OpenRouterProvider.d.ts.map +1 -0
  100. package/dist/infrastructure/llm/OpenRouterProvider.js +119 -0
  101. package/dist/infrastructure/llm/OpenRouterProvider.js.map +1 -0
  102. package/dist/infrastructure/llm/index.d.ts +7 -0
  103. package/dist/infrastructure/llm/index.d.ts.map +1 -0
  104. package/dist/infrastructure/llm/index.js +6 -0
  105. package/dist/infrastructure/llm/index.js.map +1 -0
  106. package/dist/infrastructure/patterns/BundledPatternRepository.d.ts +16 -0
  107. package/dist/infrastructure/patterns/BundledPatternRepository.d.ts.map +1 -0
  108. package/dist/infrastructure/patterns/BundledPatternRepository.js +19 -0
  109. package/dist/infrastructure/patterns/BundledPatternRepository.js.map +1 -0
  110. package/dist/infrastructure/patterns/RemotePatternRepository.d.ts +77 -0
  111. package/dist/infrastructure/patterns/RemotePatternRepository.d.ts.map +1 -0
  112. package/dist/infrastructure/patterns/RemotePatternRepository.js +176 -0
  113. package/dist/infrastructure/patterns/RemotePatternRepository.js.map +1 -0
  114. package/dist/infrastructure/patterns/bundled-patterns.d.ts +9 -0
  115. package/dist/infrastructure/patterns/bundled-patterns.d.ts.map +1 -0
  116. package/dist/infrastructure/patterns/bundled-patterns.js +2082 -0
  117. package/dist/infrastructure/patterns/bundled-patterns.js.map +1 -0
  118. package/dist/infrastructure/patterns/index.d.ts +9 -0
  119. package/dist/infrastructure/patterns/index.d.ts.map +1 -0
  120. package/dist/infrastructure/patterns/index.js +8 -0
  121. package/dist/infrastructure/patterns/index.js.map +1 -0
  122. package/dist/infrastructure/sentinel/LLMSentinel.d.ts +48 -0
  123. package/dist/infrastructure/sentinel/LLMSentinel.d.ts.map +1 -0
  124. package/dist/infrastructure/sentinel/LLMSentinel.js +142 -0
  125. package/dist/infrastructure/sentinel/LLMSentinel.js.map +1 -0
  126. package/dist/infrastructure/telemetry/HttpShadowLogSink.d.ts +30 -0
  127. package/dist/infrastructure/telemetry/HttpShadowLogSink.d.ts.map +1 -0
  128. package/dist/infrastructure/telemetry/HttpShadowLogSink.js +40 -0
  129. package/dist/infrastructure/telemetry/HttpShadowLogSink.js.map +1 -0
  130. package/dist/infrastructure/telemetry/HttpSignalSink.d.ts +51 -0
  131. package/dist/infrastructure/telemetry/HttpSignalSink.d.ts.map +1 -0
  132. package/dist/infrastructure/telemetry/HttpSignalSink.js +134 -0
  133. package/dist/infrastructure/telemetry/HttpSignalSink.js.map +1 -0
  134. package/dist/infrastructure/telemetry/index.d.ts +9 -0
  135. package/dist/infrastructure/telemetry/index.d.ts.map +1 -0
  136. package/dist/infrastructure/telemetry/index.js +7 -0
  137. package/dist/infrastructure/telemetry/index.js.map +1 -0
  138. package/package.json +44 -0
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Shield Application Service
3
+ * Core orchestrator: wires domain services + infrastructure adapters
4
+ * Fixes all 5 integration gaps from the original design
5
+ */
6
+ import { type ToolPolicy } from "../domain/guard/ToolPolicy";
7
+ import { ILLMProvider, type LLMResponse } from "./ports/ILLMProvider";
8
+ import { ISentinel } from "./ports/ISentinel";
9
+ import { ITelemetrySink } from "./ports/ITelemetrySink";
10
+ import { IPatternRepository } from "./ports/IPatternRepository";
11
+ import { HttpShadowLogSink } from "../infrastructure/telemetry";
12
+ export interface ShieldApplicationServiceConfig {
13
+ patternRepository: IPatternRepository;
14
+ telemetrySink?: ITelemetrySink;
15
+ toolPolicy: ToolPolicy;
16
+ sdkVersion?: string;
17
+ llmProvider?: ILLMProvider;
18
+ sentinel?: ISentinel;
19
+ shadowLogSink?: HttpShadowLogSink;
20
+ }
21
+ export interface WrapOptions {
22
+ prompt?: string;
23
+ requestId?: string;
24
+ modelName?: string;
25
+ provider?: string;
26
+ }
27
+ export interface ServiceStatus {
28
+ patternMatcher: {
29
+ ready: boolean;
30
+ stats?: unknown;
31
+ };
32
+ toolGuard: {
33
+ allowedTools: readonly string[];
34
+ };
35
+ telemetry: {
36
+ enabled: boolean;
37
+ status?: unknown;
38
+ };
39
+ }
40
+ export declare class ShieldApplicationService {
41
+ private readonly config;
42
+ private patternMatcher;
43
+ private toolGuard;
44
+ private telemetrySink?;
45
+ private llmProvider?;
46
+ private sentinel?;
47
+ private readonly sdkVersion;
48
+ constructor(config: ShieldApplicationServiceConfig);
49
+ /**
50
+ * Update patterns from remote repository in background.
51
+ * Non-blocking; fails gracefully, falling back to bundled patterns.
52
+ */
53
+ private updateRemotePatterns;
54
+ /**
55
+ * Main wrapper method for LLM calls.
56
+ * Fixes Gap 2 (latencyMs now stored) and Gap 3 (prompt parameter for pre-LLM scan)
57
+ *
58
+ * @param llmCall - The LLM function to execute
59
+ * @param options - Optional: prompt for pre-LLM scan, request context
60
+ */
61
+ wrap<T extends LLMResponse>(llmCall: () => Promise<T>, options?: WrapOptions): Promise<T>;
62
+ /**
63
+ * Scan a raw prompt pre-LLM for inline use.
64
+ * Throws if injection is detected.
65
+ *
66
+ * Hardened Middleware:
67
+ * - Normalize: Collapse homoglyphs and whitespace tricks
68
+ * - Layer 1 (Regex): Fast, pattern-based detection
69
+ * - Layer 2 (LLM Sentinel): If Layer 1 misses, use LLM to verify
70
+ * - Jitter: Add random delay to mask which layer blocked (if any)
71
+ */
72
+ scanPrompt(prompt: string, requestId?: string): Promise<void>;
73
+ /**
74
+ * Update tool policy at runtime
75
+ */
76
+ setAllowedTools(tools: readonly string[]): void;
77
+ /**
78
+ * Get service status for diagnostics
79
+ */
80
+ getStatus(): ServiceStatus;
81
+ /**
82
+ * Report a security event (non-blocking)
83
+ */
84
+ private report;
85
+ /**
86
+ * Graceful shutdown: flush telemetry, release resources
87
+ */
88
+ destroy(): void;
89
+ /**
90
+ * Generate a unique request ID
91
+ */
92
+ private generateRequestId;
93
+ }
94
+ //# sourceMappingURL=ShieldApplicationService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShieldApplicationService.d.ts","sourceRoot":"","sources":["../../src/application/ShieldApplicationService.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAO/E,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGhE,OAAO,EAAE,iBAAiB,EAAyB,MAAM,6BAA6B,CAAC;AAIvF,MAAM,WAAW,8BAA8B;IAC7C,iBAAiB,EAAE,kBAAkB,CAAC;IACtC,aAAa,CAAC,EAAE,cAAc,CAAC;IAC/B,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,aAAa,CAAC,EAAE,iBAAiB,CAAC;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE;QACd,KAAK,EAAE,OAAO,CAAC;QACf,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,SAAS,EAAE;QACT,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;KACjC,CAAC;IACF,SAAS,EAAE;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED,qBAAa,wBAAwB;IASvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IARnC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,aAAa,CAAC,CAAiB;IACvC,OAAO,CAAC,WAAW,CAAC,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,CAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAEP,MAAM,EAAE,8BAA8B;IAgBnE;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAoB5B;;;;;;OAMG;IACG,IAAI,CAAC,CAAC,SAAS,WAAW,EAC9B,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,CAAC,CAAC;IAuDb;;;;;;;;;OASG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuFnE;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IAK/C;;OAEG;IACH,SAAS,IAAI,aAAa;IAgB1B;;OAEG;IACH,OAAO,CAAC,MAAM;IAMd;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAG1B"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Shield Application Service
3
+ * Core orchestrator: wires domain services + infrastructure adapters
4
+ * Fixes all 5 integration gaps from the original design
5
+ */
6
+ import { PatternMatcher } from '../domain/detection/PatternMatcher.js';
7
+ import { ToolGuard } from '../domain/guard/ToolGuard.js';
8
+ import { createToolPolicy } from '../domain/guard/ToolPolicy.js';
9
+ import { createSecurityEvent, SecurityEventType, ThreatSeverity, } from '../domain/events/index.js';
10
+ import { ShieldBlockError } from './ShieldBlockError.js';
11
+ import { normalizePrompt, jitter } from './utils/index.js';
12
+ import { BUNDLED_PATTERNS } from '../infrastructure/patterns/bundled-patterns.js';
13
+ import { BundledPatternRepository } from '../infrastructure/patterns/BundledPatternRepository.js';
14
+ export class ShieldApplicationService {
15
+ constructor(config) {
16
+ this.config = config;
17
+ this.toolGuard = new ToolGuard(config.toolPolicy);
18
+ this.telemetrySink = config.telemetrySink;
19
+ this.llmProvider = config.llmProvider;
20
+ this.sentinel = config.sentinel; // Layer 2
21
+ // this.shadowLogSink = config.shadowLogSink; // Disabled for now
22
+ this.sdkVersion = config.sdkVersion ?? "0.2.0";
23
+ // Initialize patterns synchronously (bundled patterns always available)
24
+ this.patternMatcher = new PatternMatcher(BUNDLED_PATTERNS);
25
+ console.log(`[Tracerny] Layer 1 ready immediately with ${BUNDLED_PATTERNS.length} bundled patterns`);
26
+ // Load remote patterns in background if configured (zero-day updates)
27
+ this.updateRemotePatterns();
28
+ }
29
+ /**
30
+ * Update patterns from remote repository in background.
31
+ * Non-blocking; fails gracefully, falling back to bundled patterns.
32
+ */
33
+ updateRemotePatterns() {
34
+ // Only load remote if not using bundled repository
35
+ if (this.config.patternRepository instanceof BundledPatternRepository === false) {
36
+ this.config.patternRepository
37
+ .getPatterns()
38
+ .then((patterns) => {
39
+ if (patterns && patterns.length > 0) {
40
+ this.patternMatcher = new PatternMatcher(patterns);
41
+ console.log(`[Tracerny] Layer 1 updated with ${patterns.length} remote patterns`);
42
+ }
43
+ })
44
+ .catch((err) => {
45
+ console.warn("[Tracerny] Remote pattern load failed, using bundled patterns:", err);
46
+ });
47
+ }
48
+ }
49
+ /**
50
+ * Main wrapper method for LLM calls.
51
+ * Fixes Gap 2 (latencyMs now stored) and Gap 3 (prompt parameter for pre-LLM scan)
52
+ *
53
+ * @param llmCall - The LLM function to execute
54
+ * @param options - Optional: prompt for pre-LLM scan, request context
55
+ */
56
+ async wrap(llmCall, options) {
57
+ const requestId = options?.requestId ?? this.generateRequestId();
58
+ const startTime = Date.now();
59
+ try {
60
+ // FIX GAP 3: Pre-LLM scan if prompt is provided
61
+ // Uses both Layer 1 (Regex) and Layer 2 (LLM) to make decision
62
+ if (options?.prompt) {
63
+ await this.scanPrompt(options.prompt, requestId);
64
+ // scanPrompt throws ShieldBlockError if blocked by Layer 2
65
+ // Layer 1 just flags suspicious, doesn't block
66
+ }
67
+ // Execute the LLM call
68
+ const response = await llmCall();
69
+ // FIX GAP 2: Compute and store latencyMs in event metadata
70
+ const latencyMs = Date.now() - startTime;
71
+ // Validate tool calls against policy
72
+ const toolCalls = response.choices?.[0]?.message?.tool_calls;
73
+ const violation = this.toolGuard.validate(toolCalls, requestId);
74
+ if (violation) {
75
+ const event = createSecurityEvent(requestId, SecurityEventType.UNAUTHORIZED_TOOL, ThreatSeverity.CRITICAL, `Tool '${violation.toolName}' is not in allow list`, {
76
+ toolName: violation.toolName,
77
+ blockLatencyMs: latencyMs, // FIX GAP 2: now included
78
+ modelName: options?.modelName,
79
+ provider: options?.provider,
80
+ }, startTime);
81
+ this.report(event);
82
+ throw new ShieldBlockError(`Tracerny Block: Unauthorized tool '${violation.toolName}'`, event);
83
+ }
84
+ return response;
85
+ }
86
+ catch (error) {
87
+ // Re-throw our blocks as-is
88
+ if (error instanceof ShieldBlockError) {
89
+ throw error;
90
+ }
91
+ // Let other errors (LLM failures, network issues) propagate
92
+ throw error;
93
+ }
94
+ }
95
+ /**
96
+ * Scan a raw prompt pre-LLM for inline use.
97
+ * Throws if injection is detected.
98
+ *
99
+ * Hardened Middleware:
100
+ * - Normalize: Collapse homoglyphs and whitespace tricks
101
+ * - Layer 1 (Regex): Fast, pattern-based detection
102
+ * - Layer 2 (LLM Sentinel): If Layer 1 misses, use LLM to verify
103
+ * - Jitter: Add random delay to mask which layer blocked (if any)
104
+ */
105
+ async scanPrompt(prompt, requestId) {
106
+ if (!prompt) {
107
+ return; // No-op for empty prompt
108
+ }
109
+ const rid = requestId ?? this.generateRequestId();
110
+ const startTime = Date.now();
111
+ try {
112
+ // Normalize prompt to prevent Unicode/whitespace evasion
113
+ const normalizedPrompt = normalizePrompt(prompt);
114
+ console.log(`[Tracerny] Scanning prompt (${normalizedPrompt.length} chars), sentinel=${!!this.sentinel}`);
115
+ // Layer 1: Regex patterns (detection, NOT blocking)
116
+ // Flags suspicious content but doesn't block - Layer 2 makes the final decision
117
+ const threat = this.patternMatcher.match(normalizedPrompt);
118
+ const isSuspicious = !!threat;
119
+ console.log(`[Tracerny] Layer 1 result: ${isSuspicious ? 'SUSPICIOUS' : 'CLEAN'}`);
120
+ if (isSuspicious && threat) {
121
+ console.log(`[Tracerny] Layer 1 flagged: ${threat.patternName}`);
122
+ }
123
+ // Layer 2: LLM Sentinel ALWAYS called (makes final decision)
124
+ // Even if Layer 1 is clean, Layer 2 can catch subtle attacks
125
+ // If Layer 1 is suspicious, Layer 2 verifies context (allows educational content)
126
+ console.log(`[Tracerny] Layer 2 check: sentinel=${!!this.sentinel}`);
127
+ if (this.sentinel) {
128
+ console.log('[Tracerny] Layer 2: Calling Sentinel...');
129
+ try {
130
+ const result = await this.sentinel.check(normalizedPrompt, rid);
131
+ console.log(`[Tracerny] Layer 2 result: blocked=${result.blocked}`);
132
+ if (result.blocked) {
133
+ // Log to shadow_log for analysis
134
+ // Disabled for now - will re-enable after fixing endpoint
135
+ // if (this.shadowLogSink) {
136
+ // const shadowPayload: ShadowLogPayload = {
137
+ // id: rid,
138
+ // prompt: prompt.substring(0, 500),
139
+ // keywords: result.keywords,
140
+ // verdict: 'YES', // Detected as attack by LLM
141
+ // latencyMs: result.latencyMs || 0,
142
+ // model: result.llmModel || 'unknown',
143
+ // timestamp: new Date().toISOString(),
144
+ // };
145
+ // this.shadowLogSink.log(shadowPayload).catch(err => {
146
+ // console.warn("[Tracerny] Shadow log send failed:", err);
147
+ // });
148
+ // }
149
+ const event = createSecurityEvent(rid, SecurityEventType.PROMPT_INJECTION, ThreatSeverity.HIGH, `LLM Sentinel detected: ${result.keywords.join(", ")} (confidence: ${result.confidence})`, {
150
+ patternName: "LLM Sentinel",
151
+ requestSnippet: prompt.substring(0, 100),
152
+ blockLatencyMs: (result.latencyMs || 0) + (Date.now() - startTime),
153
+ modelName: result.llmModel,
154
+ });
155
+ this.report(event);
156
+ throw new ShieldBlockError("Tracerny Block: LLM Sentinel", event);
157
+ }
158
+ // Layer 2 passed - no shadow log entry
159
+ }
160
+ catch (error) {
161
+ // If sentinel throws (network error, etc), check if it's our block or a system error
162
+ if (error instanceof ShieldBlockError) {
163
+ throw error;
164
+ }
165
+ // Other errors are silently caught - Layer 2 is non-blocking fallback
166
+ console.warn("[Tracerny] Layer 2 sentinel error:", error);
167
+ }
168
+ }
169
+ // Both layers passed - prompt is safe
170
+ return;
171
+ }
172
+ finally {
173
+ // Jitter: Add random delay to obfuscate timing (always runs, masked from caller)
174
+ await jitter();
175
+ }
176
+ }
177
+ /**
178
+ * Update tool policy at runtime
179
+ */
180
+ setAllowedTools(tools) {
181
+ const policy = createToolPolicy(tools);
182
+ this.toolGuard.updatePolicy(policy);
183
+ }
184
+ /**
185
+ * Get service status for diagnostics
186
+ */
187
+ getStatus() {
188
+ return {
189
+ patternMatcher: {
190
+ ready: this.patternMatcher !== null,
191
+ stats: this.patternMatcher?.stats(),
192
+ },
193
+ toolGuard: {
194
+ allowedTools: this.toolGuard.getAllowedTools(),
195
+ },
196
+ telemetry: {
197
+ enabled: this.telemetrySink !== undefined,
198
+ status: this.telemetrySink?.getStatus(),
199
+ },
200
+ };
201
+ }
202
+ /**
203
+ * Report a security event (non-blocking)
204
+ */
205
+ report(event) {
206
+ if (this.telemetrySink) {
207
+ this.telemetrySink.queue(event);
208
+ }
209
+ }
210
+ /**
211
+ * Graceful shutdown: flush telemetry, release resources
212
+ */
213
+ destroy() {
214
+ this.telemetrySink?.destroy();
215
+ }
216
+ /**
217
+ * Generate a unique request ID
218
+ */
219
+ generateRequestId() {
220
+ return `req_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
221
+ }
222
+ }
223
+ //# sourceMappingURL=ShieldApplicationService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShieldApplicationService.js","sourceRoot":"","sources":["../../src/application/ShieldApplicationService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * ShieldBlockError
3
+ * Application exception: thrown when a security block occurs
4
+ */
5
+ import { SecurityEvent } from "../domain/events/SecurityEvent";
6
+ export declare class ShieldBlockError extends Error {
7
+ readonly event: SecurityEvent;
8
+ constructor(message: string, event: SecurityEvent);
9
+ }
10
+ //# sourceMappingURL=ShieldBlockError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShieldBlockError.d.ts","sourceRoot":"","sources":["../../src/application/ShieldBlockError.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,qBAAa,gBAAiB,SAAQ,KAAK;aAGvB,KAAK,EAAE,aAAa;gBADpC,OAAO,EAAE,MAAM,EACC,KAAK,EAAE,aAAa;CAMvC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * ShieldBlockError
3
+ * Application exception: thrown when a security block occurs
4
+ */
5
+ export class ShieldBlockError extends Error {
6
+ constructor(message, event) {
7
+ super(message);
8
+ this.event = event;
9
+ this.name = "ShieldBlockError";
10
+ Object.setPrototypeOf(this, ShieldBlockError.prototype);
11
+ }
12
+ }
13
+ //# sourceMappingURL=ShieldBlockError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShieldBlockError.js","sourceRoot":"","sources":["../../src/application/ShieldBlockError.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YACE,OAAe,EACC,KAAoB;QAEpC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,UAAK,GAAL,KAAK,CAAe;QAGpC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Application Layer
3
+ * Barrel export
4
+ */
5
+ export { ShieldApplicationService } from "./ShieldApplicationService";
6
+ export type { ShieldApplicationServiceConfig, WrapOptions, ServiceStatus } from "./ShieldApplicationService";
7
+ export { ShieldBlockError } from "./ShieldBlockError";
8
+ export * from "./ports";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,YAAY,EAAE,8BAA8B,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE7G,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,cAAc,SAAS,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Application Layer
3
+ * Barrel export
4
+ */
5
+ export { ShieldApplicationService } from './ShieldApplicationService.js';
6
+ export { ShieldBlockError } from './ShieldBlockError.js';
7
+ export * from './ports/index.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAGtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,cAAc,SAAS,CAAC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * ILLMProvider
3
+ * Outbound port: defines the contract for LLM calls
4
+ * Implemented by: OpenRouterProvider, OpenAI, Anthropic adapters, etc.
5
+ */
6
+ export interface LLMMessage {
7
+ readonly role: "user" | "assistant" | "system";
8
+ readonly content: string;
9
+ }
10
+ export interface LLMTool {
11
+ readonly type: "function";
12
+ readonly function: {
13
+ readonly name: string;
14
+ readonly description?: string;
15
+ readonly parameters?: Record<string, unknown>;
16
+ };
17
+ }
18
+ export interface ToolCall {
19
+ readonly id: string;
20
+ readonly function: {
21
+ readonly name: string;
22
+ readonly arguments?: string | Record<string, unknown>;
23
+ };
24
+ readonly type?: "function";
25
+ }
26
+ export interface LLMChoice {
27
+ readonly message: {
28
+ readonly content: string | null;
29
+ readonly role: "assistant";
30
+ readonly tool_calls?: readonly ToolCall[];
31
+ };
32
+ readonly finish_reason: "stop" | "tool_calls" | "length" | "content_filter" | null;
33
+ readonly index: number;
34
+ }
35
+ export interface TokenUsage {
36
+ readonly prompt_tokens: number;
37
+ readonly completion_tokens: number;
38
+ readonly total_tokens: number;
39
+ }
40
+ export interface LLMResponse {
41
+ readonly id?: string;
42
+ readonly choices: readonly LLMChoice[];
43
+ readonly usage?: TokenUsage;
44
+ readonly model?: string;
45
+ }
46
+ export interface LLMRequest {
47
+ readonly messages: readonly LLMMessage[];
48
+ readonly model: string;
49
+ readonly tools?: readonly LLMTool[];
50
+ readonly temperature?: number;
51
+ readonly maxTokens?: number;
52
+ readonly [key: string]: unknown;
53
+ }
54
+ export declare class ProviderError extends Error {
55
+ readonly providerName: string;
56
+ readonly statusCode?: number | undefined;
57
+ readonly cause?: unknown | undefined;
58
+ constructor(message: string, providerName: string, statusCode?: number | undefined, cause?: unknown | undefined);
59
+ }
60
+ export interface ILLMProvider {
61
+ /**
62
+ * The name of this provider (for telemetry)
63
+ */
64
+ readonly providerName: string;
65
+ /**
66
+ * Execute an LLM call
67
+ * Throws ProviderError on failure
68
+ */
69
+ complete(request: LLMRequest): Promise<LLMResponse>;
70
+ }
71
+ //# sourceMappingURL=ILLMProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ILLMProvider.d.ts","sourceRoot":"","sources":["../../../src/application/ports/ILLMProvider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC/C,CAAC;CACH;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACvD,CAAC;IACF,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;QAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;KAC3C,CAAC;IACF,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,YAAY,GAAG,QAAQ,GAAG,gBAAgB,GAAG,IAAI,CAAC;IACnF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC;AAED,qBAAa,aAAc,SAAQ,KAAK;aAGpB,YAAY,EAAE,MAAM;aACpB,UAAU,CAAC,EAAE,MAAM;aACnB,KAAK,CAAC,EAAE,OAAO;gBAH/B,OAAO,EAAE,MAAM,EACC,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,YAAA,EACnB,KAAK,CAAC,EAAE,OAAO,YAAA;CAKlC;AAED,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACrD"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * ILLMProvider
3
+ * Outbound port: defines the contract for LLM calls
4
+ * Implemented by: OpenRouterProvider, OpenAI, Anthropic adapters, etc.
5
+ */
6
+ export class ProviderError extends Error {
7
+ constructor(message, providerName, statusCode, cause) {
8
+ super(message);
9
+ this.providerName = providerName;
10
+ this.statusCode = statusCode;
11
+ this.cause = cause;
12
+ this.name = "ProviderError";
13
+ }
14
+ }
15
+ //# sourceMappingURL=ILLMProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ILLMProvider.js","sourceRoot":"","sources":["../../../src/application/ports/ILLMProvider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyDH,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YACE,OAAe,EACC,YAAoB,EACpB,UAAmB,EACnB,KAAe;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,iBAAY,GAAZ,YAAY,CAAQ;QACpB,eAAU,GAAV,UAAU,CAAS;QACnB,UAAK,GAAL,KAAK,CAAU;QAG/B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * IPatternRepository
3
+ * Outbound port: defines the contract for loading detection patterns
4
+ * Implemented by: BundledPatternRepository, RemotePatternRepository
5
+ */
6
+ import { VanguardPattern } from "../../domain/detection/VanguardPattern";
7
+ export interface IPatternRepository {
8
+ /**
9
+ * Load patterns.
10
+ * May be synchronous (bundled) or asynchronous (remote).
11
+ * Returns readonly array for immutability.
12
+ */
13
+ getPatterns(): Promise<readonly VanguardPattern[]>;
14
+ /**
15
+ * Source identifier for diagnostics.
16
+ * Examples: "bundled@0.1.0", "remote:https://api.tracerney.dev/manifest.json"
17
+ */
18
+ readonly sourceIdentifier: string;
19
+ }
20
+ //# sourceMappingURL=IPatternRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IPatternRepository.d.ts","sourceRoot":"","sources":["../../../src/application/ports/IPatternRepository.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AAEzE,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,WAAW,IAAI,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,CAAC;IAEnD;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * IPatternRepository
3
+ * Outbound port: defines the contract for loading detection patterns
4
+ * Implemented by: BundledPatternRepository, RemotePatternRepository
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=IPatternRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IPatternRepository.js","sourceRoot":"","sources":["../../../src/application/ports/IPatternRepository.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * ISentinel - Port for Layer 2 LLM-based attack detection
3
+ *
4
+ * Called when Layer 1 (regex) finds no match.
5
+ * Provides a second opinion via fast LLM model.
6
+ */
7
+ export interface ISentinel {
8
+ /**
9
+ * Check if a prompt contains a prompt injection attack
10
+ * @param prompt The user input to evaluate
11
+ * @param requestId Optional request ID for logging
12
+ * @returns Result with blocked flag, confidence score, and triggered keywords
13
+ */
14
+ check(prompt: string, requestId?: string): Promise<{
15
+ blocked: boolean;
16
+ confidence: number;
17
+ keywords: string[];
18
+ llmModel?: string;
19
+ latencyMs?: number;
20
+ }>;
21
+ }
22
+ //# sourceMappingURL=ISentinel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ISentinel.d.ts","sourceRoot":"","sources":["../../../src/application/ports/ISentinel.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IACH,KAAK,CACH,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * ISentinel - Port for Layer 2 LLM-based attack detection
3
+ *
4
+ * Called when Layer 1 (regex) finds no match.
5
+ * Provides a second opinion via fast LLM model.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=ISentinel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ISentinel.js","sourceRoot":"","sources":["../../../src/application/ports/ISentinel.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * ITelemetrySink
3
+ * Outbound port: defines the contract for reporting security events
4
+ * Implemented by: HttpSignalSink, NoOpSink, etc.
5
+ */
6
+ import { SecurityEvent } from "../../domain/events/SecurityEvent";
7
+ export interface TelemetrySinkStatus {
8
+ readonly enabled: boolean;
9
+ readonly queuedEvents: number;
10
+ readonly isPosting: boolean;
11
+ }
12
+ export interface ITelemetrySink {
13
+ /**
14
+ * Queue a security event for async delivery.
15
+ * Returns immediately — never throws.
16
+ * Fire-and-forget pattern.
17
+ */
18
+ queue(event: SecurityEvent): void;
19
+ /**
20
+ * Flush all queued events to the sink.
21
+ * Awaitable for graceful shutdown.
22
+ * Throws on persistent send failure (after retries).
23
+ */
24
+ flush(): Promise<void>;
25
+ /**
26
+ * Destroy the sink and release resources.
27
+ * Should attempt a final flush if possible.
28
+ */
29
+ destroy(): void;
30
+ /**
31
+ * Get sink status (for diagnostics).
32
+ */
33
+ getStatus(): TelemetrySinkStatus;
34
+ }
35
+ //# sourceMappingURL=ITelemetrySink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ITelemetrySink.d.ts","sourceRoot":"","sources":["../../../src/application/ports/ITelemetrySink.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAElE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,KAAK,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAElC;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,OAAO,IAAI,IAAI,CAAC;IAEhB;;OAEG;IACH,SAAS,IAAI,mBAAmB,CAAC;CAClC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * ITelemetrySink
3
+ * Outbound port: defines the contract for reporting security events
4
+ * Implemented by: HttpSignalSink, NoOpSink, etc.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=ITelemetrySink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ITelemetrySink.js","sourceRoot":"","sources":["../../../src/application/ports/ITelemetrySink.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Application Ports
3
+ * Outbound port interfaces for dependency injection
4
+ * Barrel export
5
+ */
6
+ export { ProviderError } from "./ILLMProvider";
7
+ export type { ILLMProvider, LLMRequest, LLMResponse, LLMMessage, LLMChoice, ToolCall, LLMTool, TokenUsage, } from "./ILLMProvider";
8
+ export type { ITelemetrySink, TelemetrySinkStatus } from "./ITelemetrySink";
9
+ export type { IPatternRepository } from "./IPatternRepository";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/application/ports/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,UAAU,EACV,SAAS,EACT,QAAQ,EACR,OAAO,EACP,UAAU,GACX,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5E,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Application Ports
3
+ * Outbound port interfaces for dependency injection
4
+ * Barrel export
5
+ */
6
+ export { ProviderError } from './ILLMProvider.js';
7
+ //# sourceMappingURL=index.js.map