@telora/daemon 0.15.37 → 0.15.42

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 (47) hide show
  1. package/build-info.json +2 -2
  2. package/dist/assembly-resolvers.d.ts +1 -1
  3. package/dist/assembly-resolvers.d.ts.map +1 -1
  4. package/dist/feeds/ghsa.d.ts +97 -0
  5. package/dist/feeds/ghsa.d.ts.map +1 -0
  6. package/dist/feeds/ghsa.js +226 -0
  7. package/dist/feeds/ghsa.js.map +1 -0
  8. package/dist/feeds/local.d.ts +55 -0
  9. package/dist/feeds/local.d.ts.map +1 -0
  10. package/dist/feeds/local.js +196 -0
  11. package/dist/feeds/local.js.map +1 -0
  12. package/dist/feeds/osv.d.ts +98 -0
  13. package/dist/feeds/osv.d.ts.map +1 -0
  14. package/dist/feeds/osv.js +277 -0
  15. package/dist/feeds/osv.js.map +1 -0
  16. package/dist/focus-engine.d.ts.map +1 -1
  17. package/dist/focus-engine.js +47 -0
  18. package/dist/focus-engine.js.map +1 -1
  19. package/dist/focus-executor.d.ts +53 -0
  20. package/dist/focus-executor.d.ts.map +1 -1
  21. package/dist/focus-executor.js +41 -26
  22. package/dist/focus-executor.js.map +1 -1
  23. package/dist/scanners/deps.d.ts +101 -0
  24. package/dist/scanners/deps.d.ts.map +1 -0
  25. package/dist/scanners/deps.js +242 -0
  26. package/dist/scanners/deps.js.map +1 -0
  27. package/dist/scanners/signatures.d.ts +44 -0
  28. package/dist/scanners/signatures.d.ts.map +1 -0
  29. package/dist/scanners/signatures.js +140 -0
  30. package/dist/scanners/signatures.js.map +1 -0
  31. package/dist/scanners/workflow.d.ts +42 -0
  32. package/dist/scanners/workflow.d.ts.map +1 -0
  33. package/dist/scanners/workflow.js +325 -0
  34. package/dist/scanners/workflow.js.map +1 -0
  35. package/dist/security-auto-inject.d.ts +114 -0
  36. package/dist/security-auto-inject.d.ts.map +1 -0
  37. package/dist/security-auto-inject.js +148 -0
  38. package/dist/security-auto-inject.js.map +1 -0
  39. package/dist/security-rescan-resolution.d.ts +84 -0
  40. package/dist/security-rescan-resolution.d.ts.map +1 -0
  41. package/dist/security-rescan-resolution.js +114 -0
  42. package/dist/security-rescan-resolution.js.map +1 -0
  43. package/dist/security-scan-engine.d.ts +102 -0
  44. package/dist/security-scan-engine.d.ts.map +1 -0
  45. package/dist/security-scan-engine.js +202 -0
  46. package/dist/security-scan-engine.js.map +1 -0
  47. package/package.json +3 -2
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Security scan engine.
3
+ *
4
+ * Polls security_scan_configs for due scans (cron-due or manual_run_requested_at
5
+ * set), dispatches pluggable Scanner implementations per IOC class, writes
6
+ * one security_scan_runs row plus N security_findings rows per execution,
7
+ * and (downstream) hands findings to security-auto-inject for severity-gated
8
+ * injection materialization.
9
+ *
10
+ * Activation: gated by shouldRunLoop('TELORA_SECURITY_SCAN_LOOP') in
11
+ * unified-shell.ts. Opt-out semantics match the other daemon loop ticks
12
+ * (unset/anything-but-'0' = enabled, '0' = disabled). See
13
+ * docs/runbook-loop-activation.md.
14
+ *
15
+ * Pattern reference: verification-engine.ts (pluggable strategies + Deps).
16
+ *
17
+ * @module security-scan-engine
18
+ */
19
+ import { callApi } from './queries/shared.js';
20
+ import { configForProduct } from './config.js';
21
+ import { buildDefaultAutoInjectDeps, processNewFinding, } from './security-auto-inject.js';
22
+ import { resolveStaleFindings, buildDefaultResolutionDeps, } from './security-rescan-resolution.js';
23
+ import { clearOsvCache } from './feeds/osv.js';
24
+ import { clearGhsaCache } from './feeds/ghsa.js';
25
+ // ---------------------------------------------------------------------------
26
+ // Default registry -- scanners self-register here in their own modules
27
+ // ---------------------------------------------------------------------------
28
+ const DEFAULT_REGISTRY = new Map();
29
+ export function registerScanner(scanner) {
30
+ DEFAULT_REGISTRY.set(scanner.iocClass, scanner);
31
+ }
32
+ export function getRegisteredScanners() {
33
+ return [...DEFAULT_REGISTRY.values()];
34
+ }
35
+ export async function runScanForConfig(config, trigger, deps) {
36
+ const runId = await deps.startRun(config.id, trigger);
37
+ const startedAt = Date.now();
38
+ const coverage = {};
39
+ const warnings = [];
40
+ const counts = { low: 0, medium: 0, high: 0, critical: 0 };
41
+ let anyFailure = false;
42
+ let anySuccess = false;
43
+ // Manual triggers carry the "Refresh feeds" intent: flush the OSV/GHSA
44
+ // TTL caches so this scan pulls fresh advisory data instead of replaying
45
+ // the 15-minute window. Scheduled triggers honour the cache to keep
46
+ // upstream load proportional to scan cadence.
47
+ if (trigger === 'manual') {
48
+ deps.clearFeedCaches();
49
+ }
50
+ const enabledScanners = deps.scanners.filter((s) => config.enabledIocClasses.includes(s.iocClass));
51
+ // Per-class observed identifier sets for re-scan resolution. Only
52
+ // classes whose scanner ran without error contribute -- a failed
53
+ // scanner can't claim coverage for its class.
54
+ const observedByClass = new Map();
55
+ for (const scanner of enabledScanners) {
56
+ try {
57
+ const result = await scanner.scan({
58
+ config,
59
+ repoPath: deps.resolveCwd(config.productId),
60
+ });
61
+ coverage[scanner.iocClass] = result.coverage;
62
+ anySuccess = true;
63
+ const observed = new Set();
64
+ for (const finding of result.findings) {
65
+ const { findingId } = await deps.writeFinding(runId, config.productId, config.organizationId, finding);
66
+ counts[finding.severity] = (counts[finding.severity] ?? 0) + 1;
67
+ observed.add(finding.identifier);
68
+ // Severity-gated auto-injection. Run per-finding so a failing
69
+ // injection for one finding does not block the others.
70
+ if (deps.autoInjectDeps) {
71
+ try {
72
+ const forInjection = {
73
+ id: findingId,
74
+ organizationId: config.organizationId,
75
+ productId: config.productId,
76
+ iocClass: finding.iocClass,
77
+ severity: finding.severity,
78
+ identifier: finding.identifier,
79
+ payload: finding.payload,
80
+ status: 'open',
81
+ suppression: null,
82
+ linkedInjectionId: null,
83
+ };
84
+ const options = {
85
+ autoInjectThreshold: config.autoInjectSeverityThreshold,
86
+ };
87
+ await processNewFinding(forInjection, options, deps.autoInjectDeps);
88
+ }
89
+ catch (err) {
90
+ warnings.push(`auto-inject ${finding.identifier}: ${err.message}`);
91
+ }
92
+ }
93
+ }
94
+ observedByClass.set(scanner.iocClass, observed);
95
+ }
96
+ catch (err) {
97
+ anyFailure = true;
98
+ warnings.push(`${scanner.iocClass}: ${err.message}`);
99
+ coverage[scanner.iocClass] = { error: err.message };
100
+ }
101
+ }
102
+ // Re-scan resolution: previously-open findings whose class was
103
+ // covered by this run but whose identifier did not re-appear are
104
+ // flipped to 'resolved'. Failures here are non-fatal -- the run
105
+ // already succeeded for its primary purpose (finding fresh issues).
106
+ if (deps.resolutionDeps && observedByClass.size > 0) {
107
+ try {
108
+ const observedSets = Array.from(observedByClass.entries()).map(([iocClass, identifiers]) => ({ iocClass, identifiers }));
109
+ const resolved = await resolveStaleFindings(config.productId, observedSets, deps.resolutionDeps);
110
+ if (resolved.length > 0) {
111
+ coverage.resolved_findings = resolved.length;
112
+ }
113
+ }
114
+ catch (err) {
115
+ warnings.push(`resolution: ${err.message}`);
116
+ }
117
+ }
118
+ if (warnings.length > 0) {
119
+ coverage.warnings = warnings;
120
+ }
121
+ const status = anyFailure
122
+ ? anySuccess
123
+ ? 'partial'
124
+ : 'failed'
125
+ : 'succeeded';
126
+ await deps.finishRun(runId, {
127
+ status,
128
+ coverageSummary: coverage,
129
+ findingsCountBySeverity: counts,
130
+ durationMs: Date.now() - startedAt,
131
+ });
132
+ if (trigger === 'manual') {
133
+ await deps.clearManualRunRequest(config.id);
134
+ }
135
+ }
136
+ // ---------------------------------------------------------------------------
137
+ // Loop tick -- invoked by unified-shell on a fixed cadence
138
+ // ---------------------------------------------------------------------------
139
+ export async function runSecurityScanTick(deps) {
140
+ const configs = await deps.getDueScanConfigs();
141
+ for (const config of configs) {
142
+ if (!config.enabled)
143
+ continue;
144
+ const trigger = config.manualRunRequestedAt ? 'manual' : 'schedule';
145
+ try {
146
+ await runScanForConfig(config, trigger, deps);
147
+ }
148
+ catch {
149
+ // Per-config failures are swallowed so a single broken product
150
+ // does not stop the engine from servicing others. The run row
151
+ // already records the failure status.
152
+ }
153
+ }
154
+ }
155
+ // ---------------------------------------------------------------------------
156
+ // Default Deps -- daemon-side wiring via callApi
157
+ // ---------------------------------------------------------------------------
158
+ export function buildDefaultSecurityScanDeps(config) {
159
+ const resolveCwd = (productId) => {
160
+ const product = config.products.find((p) => p.id === productId);
161
+ if (!product)
162
+ return config.repoPath;
163
+ return configForProduct(config, product).repoPath;
164
+ };
165
+ return {
166
+ getDueScanConfigs: async () => {
167
+ const res = await callApi('daemon_get_due_security_scan_configs', {});
168
+ return res.items ?? [];
169
+ },
170
+ startRun: async (configId, trigger) => {
171
+ const res = await callApi('daemon_start_security_scan_run', {
172
+ configId,
173
+ trigger,
174
+ });
175
+ return res.runId;
176
+ },
177
+ finishRun: async (runId, update) => {
178
+ await callApi('daemon_finish_security_scan_run', { runId, ...update });
179
+ },
180
+ writeFinding: async (runId, productId, organizationId, finding) => {
181
+ const res = await callApi('daemon_write_security_finding', {
182
+ runId,
183
+ productId,
184
+ organizationId,
185
+ ...finding,
186
+ });
187
+ return { findingId: res.findingId };
188
+ },
189
+ clearManualRunRequest: async (configId) => {
190
+ await callApi('daemon_clear_manual_scan_request', { configId });
191
+ },
192
+ resolveCwd,
193
+ clearFeedCaches: () => {
194
+ clearOsvCache();
195
+ clearGhsaCache();
196
+ },
197
+ scanners: getRegisteredScanners(),
198
+ autoInjectDeps: buildDefaultAutoInjectDeps(),
199
+ resolutionDeps: buildDefaultResolutionDeps(),
200
+ };
201
+ }
202
+ //# sourceMappingURL=security-scan-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-scan-engine.js","sourceRoot":"","sources":["../src/security-scan-engine.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telora/daemon",
3
- "version": "0.15.37",
3
+ "version": "0.15.42",
4
4
  "description": "Agent orchestration daemon for Telora - spawns and manages Claude Code instances",
5
5
  "type": "module",
6
6
  "bin": {
@@ -35,9 +35,10 @@
35
35
  },
36
36
  "//testRunner": "Uses Node.js built-in test runner (node:test) via tsx for TypeScript support. The root package uses Vitest; this is a deliberate choice for the daemon package to avoid framework dependencies. See src/__tests__/ for test files.",
37
37
  "dependencies": {
38
- "@telora/daemon-core": "^0.2.17",
38
+ "@telora/daemon-core": "^0.2.18",
39
39
  "@telora/mcp-products": "^0.22.1",
40
40
  "commander": "^14.0.3",
41
+ "yaml": "^2.4.0",
41
42
  "zod": "^4.3.6"
42
43
  },
43
44
  "devDependencies": {