patchwarden 1.1.0 → 1.5.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/README.en.md +83 -8
- package/README.md +78 -10
- package/dist/assessments/agentAssessor.d.ts +1 -1
- package/dist/assessments/agentAssessor.js +3 -3
- package/dist/assessments/assessmentStore.d.ts +1 -1
- package/dist/assessments/assessmentStore.js +2 -2
- package/dist/assessments/confirmCli.js +5 -4
- package/dist/config.d.ts +7 -0
- package/dist/config.js +34 -0
- package/dist/control/middleware/auth.d.ts +10 -0
- package/dist/control/middleware/auth.js +8 -0
- package/dist/control/middleware/static.d.ts +3 -0
- package/dist/control/middleware/static.js +65 -0
- package/dist/control/routes/audit.d.ts +15 -0
- package/dist/control/routes/audit.js +277 -0
- package/dist/control/routes/evidence.d.ts +4 -0
- package/dist/control/routes/evidence.js +96 -0
- package/dist/control/routes/lineage.d.ts +3 -0
- package/dist/control/routes/lineage.js +71 -0
- package/dist/control/routes/policy.d.ts +3 -0
- package/dist/control/routes/policy.js +81 -0
- package/dist/control/routes/process.d.ts +5 -0
- package/dist/control/routes/process.js +200 -0
- package/dist/control/routes/sessions.d.ts +22 -0
- package/dist/control/routes/sessions.js +224 -0
- package/dist/control/routes/status.d.ts +6 -0
- package/dist/control/routes/status.js +250 -0
- package/dist/control/routes/taskActions.d.ts +21 -0
- package/dist/control/routes/taskActions.js +233 -0
- package/dist/control/routes/tasks.d.ts +20 -0
- package/dist/control/routes/tasks.js +310 -0
- package/dist/control/routes/workspace.d.ts +15 -0
- package/dist/control/routes/workspace.js +193 -0
- package/dist/control/runtime.d.ts +91 -0
- package/dist/control/runtime.js +392 -0
- package/dist/control/server.d.ts +13 -0
- package/dist/control/server.js +479 -0
- package/dist/control/shared.d.ts +35 -0
- package/dist/control/shared.js +288 -0
- package/dist/controlCenter.d.ts +6 -0
- package/dist/controlCenter.js +7 -2001
- package/dist/direct/directGuards.js +30 -8
- package/dist/direct/directSessionStore.d.ts +2 -0
- package/dist/direct/directVerification.js +7 -0
- package/dist/doctor.d.ts +18 -1
- package/dist/doctor.js +579 -348
- package/dist/goal/goalReport.d.ts +54 -0
- package/dist/goal/goalReport.js +204 -0
- package/dist/goal/goalStatus.d.ts +6 -0
- package/dist/goal/specKitImport.d.ts +63 -0
- package/dist/goal/specKitImport.js +220 -0
- package/dist/goal/subgoalSync.js +2 -1
- package/dist/httpServer.js +15 -12
- package/dist/index.js +7 -4
- package/dist/logging.d.ts +7 -1
- package/dist/logging.js +8 -0
- package/dist/policy/projectPolicy.d.ts +55 -0
- package/dist/policy/projectPolicy.js +286 -0
- package/dist/runner/changeCapture.d.ts +3 -3
- package/dist/runner/changeCapture.js +63 -39
- package/dist/runner/cli.js +7 -6
- package/dist/runner/postTaskCleanup.js +26 -2
- package/dist/runner/runTask.js +245 -221
- package/dist/runner/simpleProcess.js +4 -4
- package/dist/runner/watch.js +17 -14
- package/dist/security/contentRedaction.d.ts +6 -0
- package/dist/security/contentRedaction.js +22 -0
- package/dist/smoke-test.js +261 -255
- package/dist/test/unit/apply-patch.test.d.ts +1 -0
- package/dist/test/unit/apply-patch.test.js +225 -0
- package/dist/test/unit/create-task.test.d.ts +1 -0
- package/dist/test/unit/create-task.test.js +197 -0
- package/dist/test/unit/direct-guards.test.js +124 -9
- package/dist/test/unit/evidence-pack.test.d.ts +1 -0
- package/dist/test/unit/evidence-pack.test.js +224 -0
- package/dist/test/unit/get-task-status.test.d.ts +1 -0
- package/dist/test/unit/get-task-status.test.js +174 -0
- package/dist/test/unit/get-task-summary.test.d.ts +1 -0
- package/dist/test/unit/get-task-summary.test.js +146 -0
- package/dist/test/unit/goal-report.test.d.ts +1 -0
- package/dist/test/unit/goal-report.test.js +159 -0
- package/dist/test/unit/goal-subgoal-task.test.js +6 -6
- package/dist/test/unit/goal-tools-registry.test.js +6 -4
- package/dist/test/unit/path-guard.test.js +24 -0
- package/dist/test/unit/project-policy-release-mode.test.d.ts +1 -0
- package/dist/test/unit/project-policy-release-mode.test.js +125 -0
- package/dist/test/unit/run-task-loop.test.d.ts +1 -0
- package/dist/test/unit/run-task-loop.test.js +380 -0
- package/dist/test/unit/schema-drift-check.test.js +10 -9
- package/dist/test/unit/spec-kit-import.test.d.ts +1 -0
- package/dist/test/unit/spec-kit-import.test.js +341 -0
- package/dist/test/unit/wait-for-task.test.d.ts +1 -0
- package/dist/test/unit/wait-for-task.test.js +144 -0
- package/dist/tools/auditTask.d.ts +8 -63
- package/dist/tools/auditTask.js +12 -8
- package/dist/tools/createDirectSession.d.ts +1 -1
- package/dist/tools/createDirectSession.js +2 -2
- package/dist/tools/createTask.d.ts +2 -2
- package/dist/tools/createTask.js +4 -4
- package/dist/tools/dispatch/coreDispatch.d.ts +9 -0
- package/dist/tools/dispatch/coreDispatch.js +282 -0
- package/dist/tools/dispatch/diagnosticDispatch.d.ts +14 -0
- package/dist/tools/dispatch/diagnosticDispatch.js +78 -0
- package/dist/tools/dispatch/directDispatch.d.ts +8 -0
- package/dist/tools/dispatch/directDispatch.js +115 -0
- package/dist/tools/dispatch/goalDispatch.d.ts +8 -0
- package/dist/tools/dispatch/goalDispatch.js +91 -0
- package/dist/tools/dispatch/releaseDispatch.d.ts +8 -0
- package/dist/tools/dispatch/releaseDispatch.js +45 -0
- package/dist/tools/dispatch/types.d.ts +23 -0
- package/dist/tools/dispatch/types.js +15 -0
- package/dist/tools/evidencePack.d.ts +45 -0
- package/dist/tools/evidencePack.js +375 -0
- package/dist/tools/finalizeDirectSession.d.ts +1 -1
- package/dist/tools/finalizeDirectSession.js +3 -3
- package/dist/tools/goalSubgoalTask.d.ts +1 -1
- package/dist/tools/goalSubgoalTask.js +2 -2
- package/dist/tools/healthCheck.js +3 -3
- package/dist/tools/recommendAgentForTask.d.ts +19 -0
- package/dist/tools/recommendAgentForTask.js +56 -0
- package/dist/tools/registry.d.ts +3 -3
- package/dist/tools/registry.js +333 -402
- package/dist/tools/releaseMode.d.ts +50 -0
- package/dist/tools/releaseMode.js +370 -0
- package/dist/tools/retryTask.d.ts +2 -2
- package/dist/tools/retryTask.js +2 -2
- package/dist/tools/runDirectVerificationBundle.d.ts +26 -0
- package/dist/tools/runDirectVerificationBundle.js +64 -0
- package/dist/tools/runTaskLoop.d.ts +57 -0
- package/dist/tools/runTaskLoop.js +417 -0
- package/dist/tools/runVerification.d.ts +4 -0
- package/dist/tools/runVerification.js +4 -0
- package/dist/tools/safeViews.d.ts +8 -2
- package/dist/tools/safeViews.js +4 -2
- package/dist/tools/taskLineage.d.ts +91 -0
- package/dist/tools/taskLineage.js +175 -0
- package/dist/tools/toolCatalog.d.ts +2 -2
- package/dist/tools/toolCatalog.js +6 -0
- package/dist/tools/toolRegistry.js +132 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/docs/CODE_WIKI.md +983 -0
- package/docs/agentseal-integration.md +150 -0
- package/docs/architecture.md +63 -0
- package/docs/assets/patchwarden-oss-demo.gif +0 -0
- package/docs/chatgpt-usage.md +31 -0
- package/docs/control-center/README.md +9 -0
- package/docs/dashboard-overview.md +86 -0
- package/docs/demo.md +8 -0
- package/docs/direct-session-workflow.md +98 -0
- package/docs/evidence-pack-schema.md +215 -0
- package/docs/execution-plan-2026-07-09.md +315 -0
- package/docs/lineage-evidence-pack-workflow.md +127 -0
- package/docs/mcp-inspector-testing.md +200 -0
- package/docs/open-source-application.md +162 -0
- package/docs/opencode-worker.md +151 -0
- package/docs/openhands-worker.md +181 -0
- package/docs/release-evidence.md +72 -0
- package/docs/roadmap-execution-and-acceptance.md +365 -0
- package/docs/spec-kit-integration.md +131 -0
- package/docs/task-safe-review-workflow.md +98 -0
- package/docs/threat-model.md +79 -0
- package/docs/user-feedback.md +40 -0
- package/docs/why-patchwarden.md +110 -0
- package/package.json +3 -3
- package/scripts/checks/control-center-smoke.js +443 -0
- package/scripts/checks/control-smoke.js +2 -2
- package/scripts/checks/lifecycle-smoke.js +29 -23
- package/scripts/checks/mcp-manifest-check.js +12 -0
- package/scripts/checks/mcp-smoke.js +33 -7
- package/scripts/checks/watcher-supervisor-smoke.js +1 -1
- package/scripts/generate-demo-gif.py +320 -0
- package/src/assessments/agentAssessor.ts +3 -3
- package/src/assessments/assessmentStore.ts +2 -2
- package/src/assessments/confirmCli.ts +5 -4
- package/src/config.ts +37 -0
- package/src/control/middleware/auth.ts +17 -0
- package/src/control/middleware/static.ts +71 -0
- package/src/control/routes/audit.ts +321 -0
- package/src/control/routes/evidence.ts +107 -0
- package/src/control/routes/lineage.ts +92 -0
- package/src/control/routes/policy.ts +81 -0
- package/src/control/routes/process.ts +204 -0
- package/src/control/routes/sessions.ts +251 -0
- package/src/control/routes/status.ts +325 -0
- package/src/control/routes/taskActions.ts +248 -0
- package/src/control/routes/tasks.ts +323 -0
- package/src/control/routes/workspace.ts +203 -0
- package/src/control/runtime.ts +472 -0
- package/src/control/server.ts +471 -0
- package/src/control/shared.ts +294 -0
- package/src/controlCenter.ts +7 -2150
- package/src/direct/directGuards.ts +28 -7
- package/src/direct/directSessionStore.ts +2 -0
- package/src/direct/directVerification.ts +7 -0
- package/src/doctor.ts +741 -481
- package/src/goal/goalReport.ts +271 -0
- package/src/goal/goalStatus.ts +6 -0
- package/src/goal/specKitImport.ts +355 -0
- package/src/goal/subgoalSync.ts +4 -2
- package/src/httpServer.ts +17 -14
- package/src/index.ts +7 -4
- package/src/logging.ts +10 -1
- package/src/policy/projectPolicy.ts +344 -0
- package/src/runner/changeCapture.ts +70 -42
- package/src/runner/cli.ts +7 -6
- package/src/runner/postTaskCleanup.ts +26 -2
- package/src/runner/runTask.ts +325 -223
- package/src/runner/simpleProcess.ts +4 -4
- package/src/runner/watch.ts +17 -14
- package/src/security/contentRedaction.ts +29 -0
- package/src/smoke-test.ts +254 -252
- package/src/test/unit/apply-patch.test.ts +293 -0
- package/src/test/unit/create-task.test.ts +255 -0
- package/src/test/unit/direct-guards.test.ts +178 -8
- package/src/test/unit/evidence-pack.test.ts +251 -0
- package/src/test/unit/get-task-status.test.ts +203 -0
- package/src/test/unit/get-task-summary.test.ts +173 -0
- package/src/test/unit/goal-report.test.ts +189 -0
- package/src/test/unit/goal-subgoal-task.test.ts +6 -6
- package/src/test/unit/goal-tools-registry.test.ts +7 -5
- package/src/test/unit/path-guard.test.ts +30 -0
- package/src/test/unit/project-policy-release-mode.test.ts +156 -0
- package/src/test/unit/run-task-loop.test.ts +425 -0
- package/src/test/unit/schema-drift-check.test.ts +11 -9
- package/src/test/unit/spec-kit-import.test.ts +429 -0
- package/src/test/unit/wait-for-task.test.ts +176 -0
- package/src/tools/auditTask.ts +99 -59
- package/src/tools/createDirectSession.ts +3 -3
- package/src/tools/createTask.ts +7 -7
- package/src/tools/dispatch/coreDispatch.ts +374 -0
- package/src/tools/dispatch/diagnosticDispatch.ts +101 -0
- package/src/tools/dispatch/directDispatch.ts +167 -0
- package/src/tools/dispatch/goalDispatch.ts +127 -0
- package/src/tools/dispatch/releaseDispatch.ts +65 -0
- package/src/tools/dispatch/types.ts +24 -0
- package/src/tools/evidencePack.ts +490 -0
- package/src/tools/finalizeDirectSession.ts +4 -4
- package/src/tools/goalSubgoalTask.ts +2 -2
- package/src/tools/healthCheck.ts +3 -3
- package/src/tools/listWorkspace.ts +71 -71
- package/src/tools/recommendAgentForTask.ts +79 -0
- package/src/tools/registry.ts +352 -509
- package/src/tools/releaseMode.ts +450 -0
- package/src/tools/retryTask.ts +2 -2
- package/src/tools/runDirectVerificationBundle.ts +98 -0
- package/src/tools/runTaskLoop.ts +526 -0
- package/src/tools/runVerification.ts +8 -0
- package/src/tools/safeViews.ts +4 -2
- package/src/tools/taskLineage.ts +300 -0
- package/src/tools/toolCatalog.ts +6 -0
- package/src/tools/toolRegistry.ts +132 -0
- package/src/version.ts +2 -2
- package/ui/pages/audit.html +192 -3
- package/ui/pages/dashboard.html +1070 -14
- package/ui/pages/direct-sessions.html +505 -53
- package/ui/pages/task-detail.html +456 -438
- package/ui/pages/tasks.html +598 -61
|
@@ -62,10 +62,10 @@ export function runSimpleProcessSync(options: SimpleProcessOptions): SimpleProce
|
|
|
62
62
|
);
|
|
63
63
|
|
|
64
64
|
if (options.stdoutPath && stdout) {
|
|
65
|
-
try { writeFileSyncAppend(options.stdoutPath, stdout); } catch {}
|
|
65
|
+
try { writeFileSyncAppend(options.stdoutPath, stdout); } catch {} // best-effort log write; failure doesn't affect result
|
|
66
66
|
}
|
|
67
67
|
if (options.stderrPath && stderr) {
|
|
68
|
-
try { writeFileSyncAppend(options.stderrPath, stderr); } catch {}
|
|
68
|
+
try { writeFileSyncAppend(options.stderrPath, stderr); } catch {} // best-effort log write; failure doesn't affect result
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
return {
|
|
@@ -196,7 +196,7 @@ function gracefulKill(child: ChildProcess): void {
|
|
|
196
196
|
try {
|
|
197
197
|
if (process.platform !== "win32" && child.pid) process.kill(-child.pid, "SIGTERM");
|
|
198
198
|
else child.kill("SIGTERM");
|
|
199
|
-
} catch {}
|
|
199
|
+
} catch {} // cleanup failure is safe to ignore
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
function forceKill(child: ChildProcess): void {
|
|
@@ -213,7 +213,7 @@ function forceKill(child: ChildProcess): void {
|
|
|
213
213
|
process.kill(-child.pid, "SIGKILL");
|
|
214
214
|
}
|
|
215
215
|
} catch {
|
|
216
|
-
try { child.kill("SIGKILL"); } catch {}
|
|
216
|
+
try { child.kill("SIGKILL"); } catch {} // cleanup failure is safe to ignore
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
219
|
|
package/src/runner/watch.ts
CHANGED
|
@@ -25,6 +25,7 @@ import { guardAgentCommand, guardTestCommand } from "../security/commandGuard.js
|
|
|
25
25
|
import { validateAssessmentFreshness } from "../assessments/assessmentStore.js";
|
|
26
26
|
import { captureRepoSnapshot } from "./changeCapture.js";
|
|
27
27
|
import { runTask } from "./runTask.js";
|
|
28
|
+
import { logger } from "../logging.js";
|
|
28
29
|
|
|
29
30
|
// ── Bootstrap ─────────────────────────────────────────────────────
|
|
30
31
|
|
|
@@ -42,10 +43,10 @@ const WATCHER_LAUNCHER_PID = Number.isInteger(Number(process.env.PATCHWARDEN_WAT
|
|
|
42
43
|
: null;
|
|
43
44
|
mkdirSync(dirname(WATCHER_HEARTBEAT_FILE), { recursive: true });
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
logger.info(`[watcher] Workspace: ${wsRoot}`);
|
|
47
|
+
logger.info(`[watcher] Tasks: ${tasksDir}`);
|
|
48
|
+
logger.info(`[watcher] Polling every ${POLL_INTERVAL_MS / 1000}s`);
|
|
49
|
+
logger.info(`[watcher] Press Ctrl+C to stop`);
|
|
49
50
|
|
|
50
51
|
// Track executed tasks to prevent re-execution
|
|
51
52
|
const executedTasks = new Set<string>();
|
|
@@ -110,7 +111,7 @@ async function tick() {
|
|
|
110
111
|
|
|
111
112
|
// Assessment freshness revalidation
|
|
112
113
|
if (statusData.assessment_id) {
|
|
113
|
-
const preExecSnapshot = captureRepoSnapshot(resolvedRepoPath);
|
|
114
|
+
const preExecSnapshot = await captureRepoSnapshot(resolvedRepoPath);
|
|
114
115
|
const validation = validateAssessmentFreshness(String(statusData.assessment_id), preExecSnapshot);
|
|
115
116
|
if (!validation.valid) {
|
|
116
117
|
throw new Error(`assessment validation failed: ${validation.failure_reason}`);
|
|
@@ -118,7 +119,7 @@ async function tick() {
|
|
|
118
119
|
}
|
|
119
120
|
} catch (err) {
|
|
120
121
|
const errMsg = `[watcher] Safety check failed for ${taskId}: ${err instanceof Error ? err.message : String(err)}`;
|
|
121
|
-
|
|
122
|
+
logger.error(errMsg);
|
|
122
123
|
|
|
123
124
|
// Write error and mark as failed so it doesn't get re-picked
|
|
124
125
|
try {
|
|
@@ -128,30 +129,32 @@ async function tick() {
|
|
|
128
129
|
data.error = errMsg;
|
|
129
130
|
data.updated_at = new Date().toISOString();
|
|
130
131
|
writeFileSync(statusFile, JSON.stringify(data, null, 2), "utf-8");
|
|
131
|
-
} catch {
|
|
132
|
+
} catch (err) {
|
|
133
|
+
logger.warn("watcher error-log write failed", { error: err instanceof Error ? err.message : String(err) });
|
|
134
|
+
}
|
|
132
135
|
executedTasks.add(taskId);
|
|
133
136
|
continue;
|
|
134
137
|
}
|
|
135
138
|
|
|
136
139
|
// ── Execute ──
|
|
137
|
-
|
|
140
|
+
logger.info(`[watcher] Executing: ${taskId}`);
|
|
138
141
|
executedTasks.add(taskId);
|
|
139
142
|
|
|
140
143
|
try {
|
|
141
144
|
const result = await runTask(taskId);
|
|
142
|
-
|
|
145
|
+
logger.info(`[watcher] ${taskId} → ${result.status}`);
|
|
143
146
|
} catch (err) {
|
|
144
|
-
|
|
147
|
+
logger.error(`[watcher] ${taskId} → error: ${err instanceof Error ? err.message : String(err)}`);
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
} catch (err) {
|
|
148
|
-
|
|
151
|
+
logger.error(`[watcher] Tick error: ${err instanceof Error ? err.message : String(err)}`);
|
|
149
152
|
}
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
// ── Start ─────────────────────────────────────────────────────────
|
|
153
156
|
|
|
154
|
-
|
|
157
|
+
logger.info("[watcher] Started");
|
|
155
158
|
setInterval(tick, POLL_INTERVAL_MS);
|
|
156
159
|
|
|
157
160
|
// Run first tick immediately
|
|
@@ -159,10 +162,10 @@ tick();
|
|
|
159
162
|
|
|
160
163
|
// Graceful shutdown
|
|
161
164
|
process.on("SIGINT", () => {
|
|
162
|
-
|
|
165
|
+
logger.info("[watcher] Stopped");
|
|
163
166
|
process.exit(0);
|
|
164
167
|
});
|
|
165
168
|
process.on("SIGTERM", () => {
|
|
166
|
-
|
|
169
|
+
logger.info("[watcher] Stopped");
|
|
167
170
|
process.exit(0);
|
|
168
171
|
});
|
|
@@ -12,6 +12,7 @@ export interface StructuredRedactionResult<T> {
|
|
|
12
12
|
|
|
13
13
|
interface RedactionRule {
|
|
14
14
|
category: string;
|
|
15
|
+
reason: string;
|
|
15
16
|
pattern: RegExp;
|
|
16
17
|
replace: string;
|
|
17
18
|
}
|
|
@@ -19,31 +20,59 @@ interface RedactionRule {
|
|
|
19
20
|
const RULES: RedactionRule[] = [
|
|
20
21
|
{
|
|
21
22
|
category: "private_key",
|
|
23
|
+
reason: "matched private key block",
|
|
22
24
|
pattern: /-----BEGIN [^-\r\n]*PRIVATE KEY-----[\s\S]*?-----END [^-\r\n]*PRIVATE KEY-----/gi,
|
|
23
25
|
replace: "[REDACTED PRIVATE KEY]",
|
|
24
26
|
},
|
|
25
27
|
{
|
|
26
28
|
category: "bearer_token",
|
|
29
|
+
reason: "matched bearer token",
|
|
27
30
|
pattern: /\bBearer\s+[A-Za-z0-9._~+\/-]{12,}={0,2}/gi,
|
|
28
31
|
replace: "Bearer [REDACTED]",
|
|
29
32
|
},
|
|
30
33
|
{
|
|
31
34
|
category: "npm_token",
|
|
35
|
+
reason: "matched npm auth token",
|
|
32
36
|
pattern: /(\b_?authToken\s*=\s*)[^\s\r\n]+/gi,
|
|
33
37
|
replace: "$1[REDACTED]",
|
|
34
38
|
},
|
|
35
39
|
{
|
|
36
40
|
category: "credential_assignment",
|
|
41
|
+
reason: "matched credential assignment",
|
|
37
42
|
pattern: /\b((?:access[_ -]?token|api[_ -]?key|secret|password|credential|token)\s*[:=]\s*)(["']?)([^\s,"'\]}]{8,})(["']?)/gi,
|
|
38
43
|
replace: "$1$2[REDACTED]$4",
|
|
39
44
|
},
|
|
40
45
|
{
|
|
41
46
|
category: "known_token_format",
|
|
47
|
+
reason: "matched known token format",
|
|
42
48
|
pattern: /\b(?:sk|ghp|github_pat)_[A-Za-z0-9_-]{16,}\b/g,
|
|
43
49
|
replace: "[REDACTED TOKEN]",
|
|
44
50
|
},
|
|
45
51
|
];
|
|
46
52
|
|
|
53
|
+
export interface RedactionCategoryCount {
|
|
54
|
+
category: string;
|
|
55
|
+
reason: string;
|
|
56
|
+
count: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function countRedactionsByCategory(input: string): RedactionCategoryCount[] {
|
|
60
|
+
const counts = new Map<string, number>();
|
|
61
|
+
for (const rule of RULES) {
|
|
62
|
+
rule.pattern.lastIndex = 0;
|
|
63
|
+
const matches = input.match(rule.pattern);
|
|
64
|
+
if (matches && matches.length > 0) {
|
|
65
|
+
counts.set(rule.category, (counts.get(rule.category) || 0) + matches.length);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const result: RedactionCategoryCount[] = [];
|
|
69
|
+
for (const rule of RULES) {
|
|
70
|
+
const count = counts.get(rule.category);
|
|
71
|
+
if (count) result.push({ category: rule.category, reason: rule.reason, count });
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
47
76
|
export function redactSensitiveContent(input: string): RedactionResult {
|
|
48
77
|
let content = input;
|
|
49
78
|
const categories: string[] = [];
|