@upx-us/shield 0.2.16-beta → 0.3.5

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 (57) hide show
  1. package/README.md +178 -53
  2. package/dist/index.d.ts +13 -15
  3. package/dist/index.js +593 -245
  4. package/dist/src/config.d.ts +1 -15
  5. package/dist/src/config.js +3 -39
  6. package/dist/src/counters.d.ts +14 -0
  7. package/dist/src/counters.js +96 -0
  8. package/dist/src/events/base.d.ts +0 -25
  9. package/dist/src/events/base.js +0 -15
  10. package/dist/src/events/browser/enrich.js +1 -1
  11. package/dist/src/events/exec/enrich.js +0 -2
  12. package/dist/src/events/exec/redactions.d.ts +0 -1
  13. package/dist/src/events/exec/redactions.js +0 -1
  14. package/dist/src/events/file/enrich.js +0 -3
  15. package/dist/src/events/generic/index.d.ts +0 -1
  16. package/dist/src/events/generic/index.js +0 -1
  17. package/dist/src/events/index.d.ts +0 -13
  18. package/dist/src/events/index.js +1 -13
  19. package/dist/src/events/message/validations.js +0 -3
  20. package/dist/src/events/sessions-spawn/enrich.js +0 -1
  21. package/dist/src/events/sessions-spawn/event.d.ts +0 -1
  22. package/dist/src/events/tool-result/enrich.js +0 -1
  23. package/dist/src/events/tool-result/redactions.js +0 -1
  24. package/dist/src/events/web/enrich.d.ts +0 -4
  25. package/dist/src/events/web/enrich.js +6 -14
  26. package/dist/src/events/web/redactions.js +1 -3
  27. package/dist/src/fetcher.d.ts +1 -0
  28. package/dist/src/fetcher.js +28 -19
  29. package/dist/src/index.js +51 -16
  30. package/dist/src/log.d.ts +0 -26
  31. package/dist/src/log.js +1 -27
  32. package/dist/src/redactor/base.d.ts +0 -23
  33. package/dist/src/redactor/base.js +0 -7
  34. package/dist/src/redactor/index.d.ts +0 -15
  35. package/dist/src/redactor/index.js +8 -27
  36. package/dist/src/redactor/strategies/command.js +0 -3
  37. package/dist/src/redactor/strategies/hostname.js +0 -1
  38. package/dist/src/redactor/strategies/index.d.ts +0 -5
  39. package/dist/src/redactor/strategies/index.js +0 -5
  40. package/dist/src/redactor/strategies/path.js +3 -3
  41. package/dist/src/redactor/strategies/secret-key.js +33 -9
  42. package/dist/src/redactor/vault.d.ts +0 -19
  43. package/dist/src/redactor/vault.js +7 -35
  44. package/dist/src/sender.d.ts +12 -20
  45. package/dist/src/sender.js +40 -36
  46. package/dist/src/setup.d.ts +11 -9
  47. package/dist/src/setup.js +33 -32
  48. package/dist/src/transformer.d.ts +1 -12
  49. package/dist/src/transformer.js +73 -48
  50. package/dist/src/validator.d.ts +0 -11
  51. package/dist/src/validator.js +19 -25
  52. package/dist/src/version.js +1 -2
  53. package/openclaw.plugin.json +10 -2
  54. package/package.json +8 -3
  55. package/dist/src/host-collector.d.ts +0 -1
  56. package/dist/src/host-collector.js +0 -200
  57. package/skills/shield/SKILL.md +0 -38
@@ -15,24 +15,10 @@ export interface Config {
15
15
  redactionEnabled: boolean;
16
16
  credentials: ShieldCredentials;
17
17
  }
18
- /** Canonical config location — shared by setup, bridge, and plugin entry. */
19
18
  export declare const SHIELD_CONFIG_PATH: string;
20
- /**
21
- * Inject config file values into process.env so the standalone bridge
22
- * (sender, fetcher, etc.) can read credentials via env vars.
23
- * Values already set in the environment take precedence (allows override).
24
- */
25
19
  export declare function injectConfigEnv(): void;
26
- /**
27
- * Load credentials from config.env file and environment variables.
28
- * Supports new env var names with backward compat for the old names.
29
- */
30
20
  export declare function loadCredentials(): ShieldCredentials;
31
- /**
32
- * Build credentials from a plugin config object (openclaw.json).
33
- * Falls back to config.env / env vars for any missing values.
34
- */
35
- export declare function loadCredentialsFromPluginConfig(pluginConfig: Record<string, unknown>): ShieldCredentials;
21
+ export declare function loadCredentialsFromPluginConfig(_pluginConfig: Record<string, unknown>): ShieldCredentials;
36
22
  export interface ConfigOverrides {
37
23
  credentials?: ShieldCredentials;
38
24
  dryRun?: boolean;
@@ -42,7 +42,6 @@ const os_1 = require("os");
42
42
  const path_1 = require("path");
43
43
  const fs_1 = require("fs");
44
44
  const log = __importStar(require("./log"));
45
- /** Default OpenClaw agents directory */
46
45
  const OPENCLAW_AGENTS_DIR = (0, path_1.join)((0, os_1.homedir)(), '.openclaw/agents');
47
46
  function safeParseInt(value, fallback) {
48
47
  if (!value)
@@ -50,13 +49,6 @@ function safeParseInt(value, fallback) {
50
49
  const parsed = parseInt(value, 10);
51
50
  return isNaN(parsed) ? fallback : parsed;
52
51
  }
53
- function optString(val) {
54
- return val != null ? String(val) : '';
55
- }
56
- /**
57
- * Auto-discover all agent session directories.
58
- * Scans ~/.openclaw/agents/{agent}/sessions for directories that exist.
59
- */
60
52
  function discoverSessionDirs() {
61
53
  const dirs = [];
62
54
  if (!(0, fs_1.existsSync)(OPENCLAW_AGENTS_DIR))
@@ -74,15 +66,7 @@ function discoverSessionDirs() {
74
66
  }
75
67
  return dirs;
76
68
  }
77
- /** Canonical config location — shared by setup, bridge, and plugin entry. */
78
69
  exports.SHIELD_CONFIG_PATH = (0, path_1.join)((0, os_1.homedir)(), '.openclaw', 'shield', 'config.env');
79
- /**
80
- * Load config file if it exists (~/.openclaw/shield/config.env).
81
- * Parses KEY=VALUE lines into a flat record. Lines starting with # are ignored.
82
- *
83
- * The path can be overridden by SHIELD_CONFIG_PATH env var — used in tests
84
- * to isolate from real credentials on the developer machine.
85
- */
86
70
  function loadConfigFile() {
87
71
  const configPath = process.env.SHIELD_CONFIG_PATH || exports.SHIELD_CONFIG_PATH;
88
72
  if (!(0, fs_1.existsSync)(configPath))
@@ -103,14 +87,9 @@ function loadConfigFile() {
103
87
  }
104
88
  return result;
105
89
  }
106
- catch { /* corrupt config — use defaults */ }
90
+ catch { }
107
91
  return {};
108
92
  }
109
- /**
110
- * Inject config file values into process.env so the standalone bridge
111
- * (sender, fetcher, etc.) can read credentials via env vars.
112
- * Values already set in the environment take precedence (allows override).
113
- */
114
93
  function injectConfigEnv() {
115
94
  const file = loadConfigFile();
116
95
  for (const [key, val] of Object.entries(file)) {
@@ -118,10 +97,6 @@ function injectConfigEnv() {
118
97
  process.env[key] = val;
119
98
  }
120
99
  }
121
- /**
122
- * Load credentials from config.env file and environment variables.
123
- * Supports new env var names with backward compat for the old names.
124
- */
125
100
  function loadCredentials() {
126
101
  const file = loadConfigFile();
127
102
  function resolve(newName, oldName) {
@@ -138,19 +113,8 @@ function loadCredentials() {
138
113
  shieldEnv: process.env.SHIELD_ENV || file.SHIELD_ENV || '',
139
114
  };
140
115
  }
141
- /**
142
- * Build credentials from a plugin config object (openclaw.json).
143
- * Falls back to config.env / env vars for any missing values.
144
- */
145
- function loadCredentialsFromPluginConfig(pluginConfig) {
146
- const fileCreds = loadCredentials();
147
- return {
148
- apiUrl: optString(pluginConfig.apiUrl) || fileCreds.apiUrl,
149
- hmacSecret: optString(pluginConfig.registrationKey) || fileCreds.hmacSecret,
150
- instanceId: optString(pluginConfig.instanceId) || fileCreds.instanceId,
151
- // shieldEnv is internal — not exposed in plugin config (customers only see PROD)
152
- shieldEnv: fileCreds.shieldEnv,
153
- };
116
+ function loadCredentialsFromPluginConfig(_pluginConfig) {
117
+ return loadCredentials();
154
118
  }
155
119
  function loadConfig(overrides) {
156
120
  if (!overrides?.credentials) {
@@ -0,0 +1,14 @@
1
+ export declare function recordEventType(eventType: string): void;
2
+ export declare function getEventTypeCounts(): Array<{
3
+ type: string;
4
+ count: number;
5
+ }>;
6
+ export declare function getTotalEventCount(): number;
7
+ export declare function recordRedaction(category: string): void;
8
+ export declare function getRedactionCounts(): Array<{
9
+ category: string;
10
+ count: number;
11
+ }>;
12
+ export declare function getTotalRedactionCount(): number;
13
+ export declare function formatStats(): string;
14
+ export declare function _resetCountersForTesting(): void;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.recordEventType = recordEventType;
4
+ exports.getEventTypeCounts = getEventTypeCounts;
5
+ exports.getTotalEventCount = getTotalEventCount;
6
+ exports.recordRedaction = recordRedaction;
7
+ exports.getRedactionCounts = getRedactionCounts;
8
+ exports.getTotalRedactionCount = getTotalRedactionCount;
9
+ exports.formatStats = formatStats;
10
+ exports._resetCountersForTesting = _resetCountersForTesting;
11
+ const eventTypeCounts = new Map();
12
+ let sessionStartedAt = Date.now();
13
+ function recordEventType(eventType) {
14
+ if (!eventType)
15
+ return;
16
+ eventTypeCounts.set(eventType, (eventTypeCounts.get(eventType) ?? 0) + 1);
17
+ }
18
+ function getEventTypeCounts() {
19
+ return Array.from(eventTypeCounts.entries())
20
+ .map(([type, count]) => ({ type, count }))
21
+ .sort((a, b) => b.count - a.count);
22
+ }
23
+ function getTotalEventCount() {
24
+ let total = 0;
25
+ for (const v of eventTypeCounts.values())
26
+ total += v;
27
+ return total;
28
+ }
29
+ const redactionCounts = new Map();
30
+ function recordRedaction(category) {
31
+ if (!category)
32
+ return;
33
+ redactionCounts.set(category, (redactionCounts.get(category) ?? 0) + 1);
34
+ }
35
+ function getRedactionCounts() {
36
+ return Array.from(redactionCounts.entries())
37
+ .map(([category, count]) => ({ category, count }))
38
+ .sort((a, b) => b.count - a.count);
39
+ }
40
+ function getTotalRedactionCount() {
41
+ let total = 0;
42
+ for (const v of redactionCounts.values())
43
+ total += v;
44
+ return total;
45
+ }
46
+ const BAR_CHARS = '████████████████████';
47
+ const BAR_MAX_WIDTH = 8;
48
+ function bar(count, max) {
49
+ if (max === 0)
50
+ return '';
51
+ const filled = Math.max(1, Math.round((count / max) * BAR_MAX_WIDTH));
52
+ return BAR_CHARS.slice(0, filled);
53
+ }
54
+ function formatStats() {
55
+ const totalEvents = getTotalEventCount();
56
+ const eventRows = getEventTypeCounts();
57
+ const maxEventCount = eventRows[0]?.count ?? 0;
58
+ const totalRedactions = getTotalRedactionCount();
59
+ const redactionRows = getRedactionCounts();
60
+ const uptimeSec = Math.round((Date.now() - sessionStartedAt) / 1000);
61
+ const uptimeLabel = uptimeSec < 60
62
+ ? `${uptimeSec}s`
63
+ : uptimeSec < 3600
64
+ ? `${Math.floor(uptimeSec / 60)}m`
65
+ : `${(uptimeSec / 3600).toFixed(1)}h`;
66
+ const lines = [];
67
+ lines.push(`🛡️ Shield Stats (session uptime: ${uptimeLabel})`);
68
+ lines.push('');
69
+ lines.push(`📊 Events transmitted: ${totalEvents}`);
70
+ if (eventRows.length === 0) {
71
+ lines.push(' (no events yet)');
72
+ }
73
+ else {
74
+ for (const { type, count } of eventRows) {
75
+ const b = bar(count, maxEventCount);
76
+ lines.push(` ${type.padEnd(20)} ${b.padEnd(BAR_MAX_WIDTH + 1)} ${count}`);
77
+ }
78
+ }
79
+ lines.push('');
80
+ lines.push(`🔒 Redactions applied: ${totalRedactions}`);
81
+ if (redactionRows.length === 0) {
82
+ lines.push(' (none)');
83
+ }
84
+ else {
85
+ for (const { category, count } of redactionRows) {
86
+ lines.push(` ${category.padEnd(20)} ${count}`);
87
+ }
88
+ lines.push(' (values never stored or transmitted)');
89
+ }
90
+ return lines.join('\n');
91
+ }
92
+ function _resetCountersForTesting() {
93
+ eventTypeCounts.clear();
94
+ redactionCounts.clear();
95
+ sessionStartedAt = Date.now();
96
+ }
@@ -1,14 +1,7 @@
1
- /**
2
- * base.ts — Core types, composable blocks, and generic engine for the Shield event model.
3
- *
4
- * All event types extend BaseEvent. The engine composes base rules with type-specific rules.
5
- * Individual event types never redeclare base-level concerns.
6
- */
7
1
  export interface BaseEvent {
8
2
  timestamp: string;
9
3
  event_type: 'TOOL_CALL' | 'TOOL_RESULT';
10
4
  tool_name: string;
11
- /** Discriminator — lets the parser know the shape of each event */
12
5
  tool_category: string;
13
6
  session_id: string;
14
7
  model?: string;
@@ -22,7 +15,6 @@ export interface BaseEvent {
22
15
  };
23
16
  tool_metadata?: Record<string, string | null>;
24
17
  }
25
- /** Attach to any event type when network context is relevant (SSH, HTTP, etc.) */
26
18
  export interface NetworkBlock {
27
19
  network: {
28
20
  session_id: string;
@@ -30,11 +22,6 @@ export interface NetworkBlock {
30
22
  direction: string;
31
23
  };
32
24
  }
33
- /**
34
- * Attach to any event type when a security-relevant finding is detected.
35
- * NOTE: `target` is NOT a composable block — each event type owns its `target` shape
36
- * to avoid property collisions across types.
37
- */
38
25
  export interface SecurityResultBlock {
39
26
  security_result: {
40
27
  severity: string;
@@ -42,10 +29,8 @@ export interface SecurityResultBlock {
42
29
  category: string;
43
30
  };
44
31
  }
45
- /** Dot-notation path to a field in an event, plus the redaction strategy to apply */
46
32
  export interface FieldRedaction {
47
33
  path: string;
48
- /** Strategy key — must match a registered RedactionStrategy in src/redactor/strategies/ */
49
34
  strategy: string;
50
35
  }
51
36
  export interface ValidationResult {
@@ -53,13 +38,11 @@ export interface ValidationResult {
53
38
  field?: string;
54
39
  error?: string;
55
40
  }
56
- /** Raw tool call from the JSONL session file */
57
41
  export interface RawToolCall {
58
42
  name: string;
59
43
  id?: string;
60
44
  arguments: Record<string, any>;
61
45
  }
62
- /** Context passed to every enrich() function */
63
46
  export interface EnrichmentContext {
64
47
  sessionId: string;
65
48
  agentId: string;
@@ -86,10 +69,8 @@ export interface SourceInfo {
86
69
  transport: string;
87
70
  };
88
71
  }
89
- /** Schema descriptor — one per event type */
90
72
  export interface EventSchema<T extends BaseEvent = BaseEvent> {
91
73
  category: string;
92
- /** Pure, fast matcher. First match wins. GenericSchema must be last. */
93
74
  match: (tool: RawToolCall) => boolean;
94
75
  enrich: (tool: RawToolCall, context: EnrichmentContext) => T;
95
76
  redactions: FieldRedaction[];
@@ -98,13 +79,7 @@ export interface EventSchema<T extends BaseEvent = BaseEvent> {
98
79
  export declare const baseValidations: {
99
80
  validate(event: BaseEvent): ValidationResult;
100
81
  };
101
- /** Applied to every event, regardless of type */
102
82
  export declare const baseRedactions: FieldRedaction[];
103
- /**
104
- * Run base validations first, then type-specific validations.
105
- * Returns the first failure encountered.
106
- */
107
83
  export declare function validateEvent(event: BaseEvent, schema: EventSchema): ValidationResult;
108
- /** Convert all values in a metadata object to strings (Chronicle CBN can't extract booleans/integers) */
109
84
  export declare function stringifyMetadata(meta: Record<string, any>): Record<string, string | null>;
110
85
  export declare function truncate(s: string, max?: number): string;
@@ -1,16 +1,9 @@
1
1
  "use strict";
2
- /**
3
- * base.ts — Core types, composable blocks, and generic engine for the Shield event model.
4
- *
5
- * All event types extend BaseEvent. The engine composes base rules with type-specific rules.
6
- * Individual event types never redeclare base-level concerns.
7
- */
8
2
  Object.defineProperty(exports, "__esModule", { value: true });
9
3
  exports.baseRedactions = exports.baseValidations = void 0;
10
4
  exports.validateEvent = validateEvent;
11
5
  exports.stringifyMetadata = stringifyMetadata;
12
6
  exports.truncate = truncate;
13
- // ─── Base Validations ─────────────────────────────────────────────────────────
14
7
  exports.baseValidations = {
15
8
  validate(event) {
16
9
  if (!event.timestamp)
@@ -26,24 +19,16 @@ exports.baseValidations = {
26
19
  return { valid: true };
27
20
  },
28
21
  };
29
- // ─── Base Redactions ──────────────────────────────────────────────────────────
30
- /** Applied to every event, regardless of type */
31
22
  exports.baseRedactions = [
32
23
  { path: 'principal.hostname', strategy: 'hostname' },
33
24
  { path: 'principal.user', strategy: 'username' },
34
25
  ];
35
- // ─── Generic Engine ───────────────────────────────────────────────────────────
36
- /**
37
- * Run base validations first, then type-specific validations.
38
- * Returns the first failure encountered.
39
- */
40
26
  function validateEvent(event, schema) {
41
27
  const baseResult = exports.baseValidations.validate(event);
42
28
  if (!baseResult.valid)
43
29
  return baseResult;
44
30
  return schema.validate(event);
45
31
  }
46
- /** Convert all values in a metadata object to strings (Chronicle CBN can't extract booleans/integers) */
47
32
  function stringifyMetadata(meta) {
48
33
  const result = {};
49
34
  for (const [k, v] of Object.entries(meta)) {
@@ -41,6 +41,6 @@ function enrich(tool, ctx) {
41
41
  event.network = { session_id: ctx.sessionId, protocol: 'HTTPS', direction: 'OUTBOUND' };
42
42
  event.tool_metadata = (0, base_1.stringifyMetadata)(meta);
43
43
  }
44
- catch { /* no valid URL */ }
44
+ catch { }
45
45
  return event;
46
46
  }
@@ -14,7 +14,6 @@ function enrich(tool, ctx) {
14
14
  cmd_has_sudo: /\bsudo\b/.test(cmd),
15
15
  cmd_has_pipe: /\|/.test(cmd),
16
16
  };
17
- // Process scope escape detection (kill/pkill/killall)
18
17
  if (/^(kill|pkill|killall)$/.test(rootCmd)) {
19
18
  const pidMatch = cmd.match(/\bkill\s+(?:-\d+\s+)?(\d+)/);
20
19
  if (pidMatch) {
@@ -42,7 +41,6 @@ function enrich(tool, ctx) {
42
41
  target: { command_line: (0, base_1.truncate)(cmd) },
43
42
  tool_metadata: (0, base_1.stringifyMetadata)(meta),
44
43
  };
45
- // SSH / SCP / rsync detection
46
44
  if (/^(ssh|scp|rsync)\b/.test(rootCmd)) {
47
45
  const stripped = cmd.replace(/\s-[ipoFlJWbDeLRw]\s+\S+/g, ' ').replace(/\s-[^\s]+/g, ' ');
48
46
  const parts = stripped.trim().split(/\s+/).slice(1);
@@ -1,3 +1,2 @@
1
1
  import { FieldRedaction } from '../base';
2
- /** Exec-specific redaction rules. Base redactions (principal.hostname, principal.user) are applied automatically. */
3
2
  export declare const redactions: FieldRedaction[];
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.redactions = void 0;
4
- /** Exec-specific redaction rules. Base redactions (principal.hostname, principal.user) are applied automatically. */
5
4
  exports.redactions = [
6
5
  { path: 'command', strategy: 'command' },
7
6
  { path: 'command', strategy: 'secret-key' },
@@ -9,9 +9,6 @@ function enrich(tool, ctx) {
9
9
  const ext = (0, path_1.extname)(fp) || null;
10
10
  const isSystem = /^\/(etc|usr|var|sys|proc)(\/|$)/.test(fp);
11
11
  const configExts = ['.json', '.yaml', '.yml', '.toml', '.env', '.conf', '.cfg', '.ini'];
12
- // Note: extname('.env') returns '' in Node (dotfiles treated as no extension).
13
- // file_is_config uses extension-based detection only. Dotfile detection is a known
14
- // limitation (issue #6) — tracked for a future dedicated dotfile enrichment rule.
15
12
  const isMemoryFile = /\/(MEMORY\.md|memory\/.*\.md)$/.test(fp);
16
13
  const toolName = tool.name;
17
14
  const meta = {
@@ -1,5 +1,4 @@
1
1
  import { EventSchema } from '../base';
2
2
  import { GenericEvent } from './event';
3
3
  export type { GenericEvent };
4
- /** Fallback schema — always matches. MUST be last in the registry. */
5
4
  export declare const GenericSchema: EventSchema<GenericEvent>;
@@ -4,7 +4,6 @@ exports.GenericSchema = void 0;
4
4
  const enrich_1 = require("./enrich");
5
5
  const redactions_1 = require("./redactions");
6
6
  const validations_1 = require("./validations");
7
- /** Fallback schema — always matches. MUST be last in the registry. */
8
7
  exports.GenericSchema = {
9
8
  category: 'generic',
10
9
  match: (_tool) => true,
@@ -1,10 +1,3 @@
1
- /**
2
- * src/events/index.ts — Shield Event Registry
3
- *
4
- * Imports all schemas and builds the ordered lookup array.
5
- * GenericSchema is always last — it matches everything and acts as the fallback.
6
- * First match wins; schemas are evaluated in order.
7
- */
8
1
  import { EventSchema } from './base';
9
2
  export type { ExecEvent } from './exec';
10
3
  export type { FileEvent } from './file';
@@ -30,11 +23,5 @@ import type { GatewayEvent } from './gateway';
30
23
  import type { HostTelemetryEvent } from './host-telemetry';
31
24
  import type { ToolResultEvent } from './tool-result';
32
25
  import type { GenericEvent } from './generic';
33
- /** Discriminated union of all Shield event types */
34
26
  export type ShieldEvent = ExecEvent | FileEvent | WebEvent | BrowserEvent | MessageEvent | SessionsSpawnEvent | CronEvent | GatewayEvent | HostTelemetryEvent | ToolResultEvent | GenericEvent;
35
- /**
36
- * Ordered registry of all event schemas.
37
- * GenericSchema MUST remain last.
38
- * eslint-disable-next-line @typescript-eslint/no-explicit-any
39
- */
40
27
  export declare const schemas: EventSchema<any>[];
@@ -1,11 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * src/events/index.ts — Shield Event Registry
4
- *
5
- * Imports all schemas and builds the ordered lookup array.
6
- * GenericSchema is always last — it matches everything and acts as the fallback.
7
- * First match wins; schemas are evaluated in order.
8
- */
9
2
  Object.defineProperty(exports, "__esModule", { value: true });
10
3
  exports.schemas = exports.buildToolResult = void 0;
11
4
  const exec_1 = require("./exec");
@@ -20,11 +13,6 @@ const host_telemetry_1 = require("./host-telemetry");
20
13
  const generic_1 = require("./generic");
21
14
  var tool_result_1 = require("./tool-result");
22
15
  Object.defineProperty(exports, "buildToolResult", { enumerable: true, get: function () { return tool_result_1.buildToolResult; } });
23
- /**
24
- * Ordered registry of all event schemas.
25
- * GenericSchema MUST remain last.
26
- * eslint-disable-next-line @typescript-eslint/no-explicit-any
27
- */
28
16
  exports.schemas = [
29
17
  exec_1.ExecSchema,
30
18
  file_1.FileSchema,
@@ -35,5 +23,5 @@ exports.schemas = [
35
23
  cron_1.CronSchema,
36
24
  gateway_1.GatewaySchema,
37
25
  host_telemetry_1.HostTelemetrySchema,
38
- generic_1.GenericSchema, // always last
26
+ generic_1.GenericSchema,
39
27
  ];
@@ -1,7 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validate = validate;
4
- // MessageEvent has no required type-specific fields beyond BaseEvent.
5
- // Base validations (timestamp, session_id, tool_name, principal.hostname) run
6
- // automatically before this function — no additional checks needed here.
7
4
  function validate(_event) { return { valid: true }; }
@@ -33,7 +33,6 @@ function enrich(tool, ctx) {
33
33
  user: ctx.agentId,
34
34
  },
35
35
  arguments_summary: (0, base_1.truncate)(task),
36
- // target.command_line required by parser for PROCESS_LAUNCH mapping
37
36
  target: { command_line: (0, base_1.truncate)(task) },
38
37
  tool_metadata: (0, base_1.stringifyMetadata)(meta),
39
38
  };
@@ -2,7 +2,6 @@ import { BaseEvent } from '../base';
2
2
  export interface SessionsSpawnEvent extends BaseEvent {
3
3
  tool_category: 'sessions_spawn';
4
4
  arguments_summary?: string;
5
- /** target.command_line = task description — required by parser for PROCESS_LAUNCH mapping */
6
5
  target?: {
7
6
  command_line?: string;
8
7
  };
@@ -15,7 +15,6 @@ function buildToolResult(raw, ctx) {
15
15
  result_size_bytes: String(resultText.length),
16
16
  result_is_large: resultText.length > 50000,
17
17
  };
18
- // ANSI injection detection
19
18
  const ansiMatches = resultText.match(/\x1b\[[0-9;]*[a-zA-Z]|\x1b\]|\x07|\x1b\(B/g);
20
19
  if (ansiMatches && ansiMatches.length > 0) {
21
20
  meta['ansi_content_detected'] = 'true';
@@ -2,6 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.redactions = void 0;
4
4
  exports.redactions = [
5
- // result_summary may contain API keys or tokens in command output — scrub them
6
5
  { path: 'result_summary', strategy: 'secret-key' },
7
6
  ];
@@ -1,8 +1,4 @@
1
1
  import { RawToolCall, EnrichmentContext } from '../base';
2
2
  import { WebEvent } from './event';
3
- /**
4
- * Returns true for loopback, RFC 1918, link-local, and cloud metadata endpoints.
5
- * 169.254.169.254 is the AWS/GCP/Azure instance metadata endpoint — a critical IoC.
6
- */
7
3
  export declare function isInternalUrl(u: URL): boolean;
8
4
  export declare function enrich(tool: RawToolCall, ctx: EnrichmentContext): WebEvent;
@@ -3,32 +3,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isInternalUrl = isInternalUrl;
4
4
  exports.enrich = enrich;
5
5
  const base_1 = require("../base");
6
- /**
7
- * Returns true for loopback, RFC 1918, link-local, and cloud metadata endpoints.
8
- * 169.254.169.254 is the AWS/GCP/Azure instance metadata endpoint — a critical IoC.
9
- */
10
6
  function isInternalUrl(u) {
11
- // Node.js URL parser wraps IPv6 in brackets: [::1] — strip them for comparison
12
7
  const h = u.hostname;
13
8
  const bare = h.startsWith('[') && h.endsWith(']') ? h.slice(1, -1) : h;
14
9
  if (bare === 'localhost' || bare === '127.0.0.1' || bare === '::1')
15
10
  return true;
16
11
  if (/^169\.254\./.test(bare))
17
- return true; // link-local / cloud metadata
12
+ return true;
18
13
  if (/^10\./.test(bare))
19
- return true; // RFC 1918 Class A
14
+ return true;
20
15
  if (/^192\.168\./.test(bare))
21
- return true; // RFC 1918 Class C
16
+ return true;
22
17
  if (/^172\.(1[6-9]|2\d|3[01])\./.test(bare))
23
- return true; // RFC 1918 Class B
18
+ return true;
24
19
  if (/\.(local|internal|localhost)$/.test(bare))
25
- return true; // internal hostnames
20
+ return true;
26
21
  return false;
27
22
  }
28
23
  function enrich(tool, ctx) {
29
24
  const args = tool.arguments;
30
- // web_search args have `query` but no `url` — synthesise a canonical search URL
31
- // so the parser gets a valid target hostname for NETWORK_HTTP mapping
32
25
  const rawUrl = args.url || args.targetUrl || '';
33
26
  const url = rawUrl || (tool.name === 'web_search' && args.query
34
27
  ? `https://search.brave.com/search?q=${encodeURIComponent(String(args.query).slice(0, 200))}`
@@ -61,7 +54,6 @@ function enrich(tool, ctx) {
61
54
  const u = new URL(url);
62
55
  event.target.hostname = u.hostname;
63
56
  event.target.url_domain = u.hostname;
64
- // Reflect actual protocol (HTTP vs HTTPS) in the network block
65
57
  if (event.network) {
66
58
  event.network.protocol = u.protocol === 'http:' ? 'HTTP' : 'HTTPS';
67
59
  }
@@ -73,6 +65,6 @@ function enrich(tool, ctx) {
73
65
  url_is_internal: isInternalUrl(u),
74
66
  });
75
67
  }
76
- catch { /* malformed URL — keep defaults */ }
68
+ catch { }
77
69
  return event;
78
70
  }
@@ -1,6 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.redactions = void 0;
4
- exports.redactions = [
5
- // URLs are kept as-is for detection value; no PII expected in URLs at this layer
6
- ];
4
+ exports.redactions = [];
@@ -8,5 +8,6 @@ export interface RawEntry {
8
8
  _sessionId: string;
9
9
  _agentId: string;
10
10
  }
11
+ export declare const MAX_ENTRIES_PER_POLL = 5000;
11
12
  export declare function fetchNewEntries(config: Config): Promise<RawEntry[]>;
12
13
  export declare function commitCursors(config: Config, _entries: RawEntry[]): void;