@openagentsy/hooks 0.0.0-stage → 0.2.0
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/LICENSE +674 -0
- package/README.md +32 -2
- package/dist/accountability.d.ts +29 -0
- package/dist/accountability.d.ts.map +1 -0
- package/dist/accountability.js +21 -0
- package/dist/accountability.js.map +1 -0
- package/dist/accountability.test.d.ts +2 -0
- package/dist/accountability.test.d.ts.map +1 -0
- package/dist/accountability.test.js +42 -0
- package/dist/accountability.test.js.map +1 -0
- package/dist/approvals.d.ts +110 -0
- package/dist/approvals.d.ts.map +1 -0
- package/dist/approvals.js +464 -0
- package/dist/approvals.js.map +1 -0
- package/dist/approvals.test.d.ts +2 -0
- package/dist/approvals.test.d.ts.map +1 -0
- package/dist/approvals.test.js +307 -0
- package/dist/approvals.test.js.map +1 -0
- package/dist/base-tool.d.ts +26 -0
- package/dist/base-tool.d.ts.map +1 -0
- package/dist/base-tool.js +37 -0
- package/dist/base-tool.js.map +1 -0
- package/dist/base-tool.test.d.ts +2 -0
- package/dist/base-tool.test.d.ts.map +1 -0
- package/dist/base-tool.test.js +34 -0
- package/dist/base-tool.test.js.map +1 -0
- package/dist/eval/index.d.ts +3 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +3 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/runner.d.ts +179 -0
- package/dist/eval/runner.d.ts.map +1 -0
- package/dist/eval/runner.js +616 -0
- package/dist/eval/runner.js.map +1 -0
- package/dist/eval/runner.test.d.ts +2 -0
- package/dist/eval/runner.test.d.ts.map +1 -0
- package/dist/eval/runner.test.js +431 -0
- package/dist/eval/runner.test.js.map +1 -0
- package/dist/eval/types.d.ts +173 -0
- package/dist/eval/types.d.ts.map +1 -0
- package/dist/eval/types.js +104 -0
- package/dist/eval/types.js.map +1 -0
- package/dist/event.d.ts +59 -0
- package/dist/event.d.ts.map +1 -0
- package/dist/event.js +178 -0
- package/dist/event.js.map +1 -0
- package/dist/event.test.d.ts +2 -0
- package/dist/event.test.d.ts.map +1 -0
- package/dist/event.test.js +49 -0
- package/dist/event.test.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/lessons/capture.d.ts +66 -0
- package/dist/lessons/capture.d.ts.map +1 -0
- package/dist/lessons/capture.js +166 -0
- package/dist/lessons/capture.js.map +1 -0
- package/dist/lessons/capture.test.d.ts +2 -0
- package/dist/lessons/capture.test.d.ts.map +1 -0
- package/dist/lessons/capture.test.js +200 -0
- package/dist/lessons/capture.test.js.map +1 -0
- package/dist/lessons/decide.d.ts +90 -0
- package/dist/lessons/decide.d.ts.map +1 -0
- package/dist/lessons/decide.js +334 -0
- package/dist/lessons/decide.js.map +1 -0
- package/dist/lessons/decide.test.d.ts +2 -0
- package/dist/lessons/decide.test.d.ts.map +1 -0
- package/dist/lessons/decide.test.js +527 -0
- package/dist/lessons/decide.test.js.map +1 -0
- package/dist/lessons/id.d.ts +5 -0
- package/dist/lessons/id.d.ts.map +1 -0
- package/dist/lessons/id.js +20 -0
- package/dist/lessons/id.js.map +1 -0
- package/dist/lessons/index.d.ts +5 -0
- package/dist/lessons/index.d.ts.map +1 -0
- package/dist/lessons/index.js +5 -0
- package/dist/lessons/index.js.map +1 -0
- package/dist/lessons/model.d.ts +163 -0
- package/dist/lessons/model.d.ts.map +1 -0
- package/dist/lessons/model.js +181 -0
- package/dist/lessons/model.js.map +1 -0
- package/dist/lessons/model.test.d.ts +2 -0
- package/dist/lessons/model.test.d.ts.map +1 -0
- package/dist/lessons/model.test.js +178 -0
- package/dist/lessons/model.test.js.map +1 -0
- package/dist/lessons/permissions.test.d.ts +2 -0
- package/dist/lessons/permissions.test.d.ts.map +1 -0
- package/dist/lessons/permissions.test.js +88 -0
- package/dist/lessons/permissions.test.js.map +1 -0
- package/dist/lessons/store.d.ts +74 -0
- package/dist/lessons/store.d.ts.map +1 -0
- package/dist/lessons/store.js +231 -0
- package/dist/lessons/store.js.map +1 -0
- package/dist/output-checks.d.ts +64 -0
- package/dist/output-checks.d.ts.map +1 -0
- package/dist/output-checks.js +248 -0
- package/dist/output-checks.js.map +1 -0
- package/dist/output-checks.test.d.ts +2 -0
- package/dist/output-checks.test.d.ts.map +1 -0
- package/dist/output-checks.test.js +58 -0
- package/dist/output-checks.test.js.map +1 -0
- package/dist/paths.d.ts +37 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +70 -0
- package/dist/paths.js.map +1 -0
- package/dist/paths.test.d.ts +2 -0
- package/dist/paths.test.d.ts.map +1 -0
- package/dist/paths.test.js +36 -0
- package/dist/paths.test.js.map +1 -0
- package/dist/policies/agi-framing.d.ts +12 -0
- package/dist/policies/agi-framing.d.ts.map +1 -0
- package/dist/policies/agi-framing.js +33 -0
- package/dist/policies/agi-framing.js.map +1 -0
- package/dist/policies/anti-anthropomorphism.d.ts +13 -0
- package/dist/policies/anti-anthropomorphism.d.ts.map +1 -0
- package/dist/policies/anti-anthropomorphism.js +34 -0
- package/dist/policies/anti-anthropomorphism.js.map +1 -0
- package/dist/policies/anti-dependence.d.ts +12 -0
- package/dist/policies/anti-dependence.d.ts.map +1 -0
- package/dist/policies/anti-dependence.js +33 -0
- package/dist/policies/anti-dependence.js.map +1 -0
- package/dist/policies/anti-sycophancy.d.ts +13 -0
- package/dist/policies/anti-sycophancy.d.ts.map +1 -0
- package/dist/policies/anti-sycophancy.js +34 -0
- package/dist/policies/anti-sycophancy.js.map +1 -0
- package/dist/policies/dark-pattern.d.ts +14 -0
- package/dist/policies/dark-pattern.d.ts.map +1 -0
- package/dist/policies/dark-pattern.js +44 -0
- package/dist/policies/dark-pattern.js.map +1 -0
- package/dist/policies/destructive-needs-approval.d.ts +14 -0
- package/dist/policies/destructive-needs-approval.d.ts.map +1 -0
- package/dist/policies/destructive-needs-approval.js +31 -0
- package/dist/policies/destructive-needs-approval.js.map +1 -0
- package/dist/policies/discovery.d.ts +12 -0
- package/dist/policies/discovery.d.ts.map +1 -0
- package/dist/policies/discovery.js +130 -0
- package/dist/policies/discovery.js.map +1 -0
- package/dist/policies/high-risk.d.ts +25 -0
- package/dist/policies/high-risk.d.ts.map +1 -0
- package/dist/policies/high-risk.js +105 -0
- package/dist/policies/high-risk.js.map +1 -0
- package/dist/policies/human-only-decisions.d.ts +14 -0
- package/dist/policies/human-only-decisions.d.ts.map +1 -0
- package/dist/policies/human-only-decisions.js +33 -0
- package/dist/policies/human-only-decisions.js.map +1 -0
- package/dist/policies/index.d.ts +29 -0
- package/dist/policies/index.d.ts.map +1 -0
- package/dist/policies/index.js +82 -0
- package/dist/policies/index.js.map +1 -0
- package/dist/policies/no-skip-git-hooks.d.ts +14 -0
- package/dist/policies/no-skip-git-hooks.d.ts.map +1 -0
- package/dist/policies/no-skip-git-hooks.js +31 -0
- package/dist/policies/no-skip-git-hooks.js.map +1 -0
- package/dist/policies/package-manager.d.ts +12 -0
- package/dist/policies/package-manager.d.ts.map +1 -0
- package/dist/policies/package-manager.js +29 -0
- package/dist/policies/package-manager.js.map +1 -0
- package/dist/policies/patterns.d.ts +17 -0
- package/dist/policies/patterns.d.ts.map +1 -0
- package/dist/policies/patterns.js +30 -0
- package/dist/policies/patterns.js.map +1 -0
- package/dist/policies/policies.test.d.ts +2 -0
- package/dist/policies/policies.test.d.ts.map +1 -0
- package/dist/policies/policies.test.js +210 -0
- package/dist/policies/policies.test.js.map +1 -0
- package/dist/policies/privacy-transparency.d.ts +14 -0
- package/dist/policies/privacy-transparency.d.ts.map +1 -0
- package/dist/policies/privacy-transparency.js +50 -0
- package/dist/policies/privacy-transparency.js.map +1 -0
- package/dist/policies/professional-displacement.d.ts +15 -0
- package/dist/policies/professional-displacement.d.ts.map +1 -0
- package/dist/policies/professional-displacement.js +45 -0
- package/dist/policies/professional-displacement.js.map +1 -0
- package/dist/policies/protect-policy.d.ts +14 -0
- package/dist/policies/protect-policy.d.ts.map +1 -0
- package/dist/policies/protect-policy.js +35 -0
- package/dist/policies/protect-policy.js.map +1 -0
- package/dist/policies/scope-enforcement.d.ts +14 -0
- package/dist/policies/scope-enforcement.d.ts.map +1 -0
- package/dist/policies/scope-enforcement.js +34 -0
- package/dist/policies/scope-enforcement.js.map +1 -0
- package/dist/policies/secret-scan-writes.d.ts +13 -0
- package/dist/policies/secret-scan-writes.d.ts.map +1 -0
- package/dist/policies/secret-scan-writes.js +38 -0
- package/dist/policies/secret-scan-writes.js.map +1 -0
- package/dist/policies/selection.d.ts +20 -0
- package/dist/policies/selection.d.ts.map +1 -0
- package/dist/policies/selection.js +93 -0
- package/dist/policies/selection.js.map +1 -0
- package/dist/policies/structural-bias.d.ts +14 -0
- package/dist/policies/structural-bias.d.ts.map +1 -0
- package/dist/policies/structural-bias.js +41 -0
- package/dist/policies/structural-bias.js.map +1 -0
- package/dist/policies/third-party-impact.d.ts +13 -0
- package/dist/policies/third-party-impact.d.ts.map +1 -0
- package/dist/policies/third-party-impact.js +38 -0
- package/dist/policies/third-party-impact.js.map +1 -0
- package/dist/policies/tool-call.d.ts +38 -0
- package/dist/policies/tool-call.d.ts.map +1 -0
- package/dist/policies/tool-call.js +53 -0
- package/dist/policies/tool-call.js.map +1 -0
- package/dist/policies/truthfulness-uncertainty.d.ts +13 -0
- package/dist/policies/truthfulness-uncertainty.d.ts.map +1 -0
- package/dist/policies/truthfulness-uncertainty.js +45 -0
- package/dist/policies/truthfulness-uncertainty.js.map +1 -0
- package/dist/policies/workspace-writes-only.d.ts +25 -0
- package/dist/policies/workspace-writes-only.d.ts.map +1 -0
- package/dist/policies/workspace-writes-only.js +54 -0
- package/dist/policies/workspace-writes-only.js.map +1 -0
- package/dist/policy-engine.d.ts +69 -0
- package/dist/policy-engine.d.ts.map +1 -0
- package/dist/policy-engine.js +145 -0
- package/dist/policy-engine.js.map +1 -0
- package/dist/policy-registry.d.ts +62 -0
- package/dist/policy-registry.d.ts.map +1 -0
- package/dist/policy-registry.js +63 -0
- package/dist/policy-registry.js.map +1 -0
- package/dist/policy-registry.test.d.ts +2 -0
- package/dist/policy-registry.test.d.ts.map +1 -0
- package/dist/policy-registry.test.js +79 -0
- package/dist/policy-registry.test.js.map +1 -0
- package/dist/policy-release.d.ts +44 -0
- package/dist/policy-release.d.ts.map +1 -0
- package/dist/policy-release.js +65 -0
- package/dist/policy-release.js.map +1 -0
- package/dist/policy.d.ts +141 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +22 -0
- package/dist/policy.js.map +1 -0
- package/dist/quality/audit.d.ts +56 -0
- package/dist/quality/audit.d.ts.map +1 -0
- package/dist/quality/audit.js +52 -0
- package/dist/quality/audit.js.map +1 -0
- package/dist/quality/findings.d.ts +34 -0
- package/dist/quality/findings.d.ts.map +1 -0
- package/dist/quality/findings.js +121 -0
- package/dist/quality/findings.js.map +1 -0
- package/dist/quality/findings.test.d.ts +2 -0
- package/dist/quality/findings.test.d.ts.map +1 -0
- package/dist/quality/findings.test.js +79 -0
- package/dist/quality/findings.test.js.map +1 -0
- package/dist/quality/index.d.ts +20 -0
- package/dist/quality/index.d.ts.map +1 -0
- package/dist/quality/index.js +20 -0
- package/dist/quality/index.js.map +1 -0
- package/dist/quality/rule.d.ts +43 -0
- package/dist/quality/rule.d.ts.map +1 -0
- package/dist/quality/rule.js +162 -0
- package/dist/quality/rule.js.map +1 -0
- package/dist/quality/rule.test.d.ts +2 -0
- package/dist/quality/rule.test.d.ts.map +1 -0
- package/dist/quality/rule.test.js +187 -0
- package/dist/quality/rule.test.js.map +1 -0
- package/dist/quality/tools.d.ts +30 -0
- package/dist/quality/tools.d.ts.map +1 -0
- package/dist/quality/tools.js +33 -0
- package/dist/quality/tools.js.map +1 -0
- package/dist/quality/tools.test.d.ts +2 -0
- package/dist/quality/tools.test.d.ts.map +1 -0
- package/dist/quality/tools.test.js +41 -0
- package/dist/quality/tools.test.js.map +1 -0
- package/dist/quality/waive.d.ts +37 -0
- package/dist/quality/waive.d.ts.map +1 -0
- package/dist/quality/waive.js +39 -0
- package/dist/quality/waive.js.map +1 -0
- package/dist/quality/waivers.d.ts +63 -0
- package/dist/quality/waivers.d.ts.map +1 -0
- package/dist/quality/waivers.js +132 -0
- package/dist/quality/waivers.js.map +1 -0
- package/dist/quality/waivers.test.d.ts +2 -0
- package/dist/quality/waivers.test.d.ts.map +1 -0
- package/dist/quality/waivers.test.js +138 -0
- package/dist/quality/waivers.test.js.map +1 -0
- package/dist/registry.d.ts +86 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +92 -0
- package/dist/registry.js.map +1 -0
- package/dist/registry.test.d.ts +2 -0
- package/dist/registry.test.d.ts.map +1 -0
- package/dist/registry.test.js +117 -0
- package/dist/registry.test.js.map +1 -0
- package/dist/rules.d.ts +107 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +632 -0
- package/dist/rules.js.map +1 -0
- package/dist/rules.test.d.ts +2 -0
- package/dist/rules.test.d.ts.map +1 -0
- package/dist/rules.test.js +488 -0
- package/dist/rules.test.js.map +1 -0
- package/dist/secrets.d.ts +17 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +17 -0
- package/dist/secrets.js.map +1 -0
- package/dist/secrets.test.d.ts +2 -0
- package/dist/secrets.test.d.ts.map +1 -0
- package/dist/secrets.test.js +20 -0
- package/dist/secrets.test.js.map +1 -0
- package/dist/shell-env.d.ts +23 -0
- package/dist/shell-env.d.ts.map +1 -0
- package/dist/shell-env.js +34 -0
- package/dist/shell-env.js.map +1 -0
- package/dist/shell-env.test.d.ts +2 -0
- package/dist/shell-env.test.d.ts.map +1 -0
- package/dist/shell-env.test.js +45 -0
- package/dist/shell-env.test.js.map +1 -0
- package/package.json +49 -4
package/dist/rules.js
ADDED
|
@@ -0,0 +1,632 @@
|
|
|
1
|
+
import { isAbsolute, resolve } from 'node:path';
|
|
2
|
+
import { findSecrets } from '@openagentsy/core';
|
|
3
|
+
import { approvalGate, createApprovalStore } from './approvals.js';
|
|
4
|
+
import { isReaderTool, isWritingTool, readPreToolCall } from './event.js';
|
|
5
|
+
import { isInside, pathSegments, projectName, worktreeRoot } from './paths.js';
|
|
6
|
+
import { qualityAfterWrite } from './quality/rule.js';
|
|
7
|
+
/**
|
|
8
|
+
* The default rules.
|
|
9
|
+
*
|
|
10
|
+
* Seven rules, all of them checked before a tool call, and all of them
|
|
11
|
+
* blocking: a call that trips one of them does not happen. The output
|
|
12
|
+
* checks are the other half of the package, and they flag instead.
|
|
13
|
+
*/
|
|
14
|
+
/** The answer of a rule that lets the call through. */
|
|
15
|
+
const CONTINUE = { continue: true };
|
|
16
|
+
/**
|
|
17
|
+
* The command, read in pieces.
|
|
18
|
+
*
|
|
19
|
+
* A quoted span is one piece, so a command that is passed as a quoted
|
|
20
|
+
* argument stays one thing. The pieces are cut at the given characters,
|
|
21
|
+
* and the quotes are kept, so the caller can tell a value from an
|
|
22
|
+
* argument.
|
|
23
|
+
*/
|
|
24
|
+
function scanCommand(command, cuts) {
|
|
25
|
+
const pieces = [];
|
|
26
|
+
let current = '';
|
|
27
|
+
let quote;
|
|
28
|
+
for (const char of command) {
|
|
29
|
+
if (quote !== undefined) {
|
|
30
|
+
current += char;
|
|
31
|
+
if (char === quote)
|
|
32
|
+
quote = undefined;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (char === '"' || char === "'") {
|
|
36
|
+
quote = char;
|
|
37
|
+
current += char;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (cuts(char)) {
|
|
41
|
+
if (current !== '')
|
|
42
|
+
pieces.push(current);
|
|
43
|
+
current = '';
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
current += char;
|
|
47
|
+
}
|
|
48
|
+
if (current !== '')
|
|
49
|
+
pieces.push(current);
|
|
50
|
+
return pieces;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The command, split into tokens.
|
|
54
|
+
*
|
|
55
|
+
* A quoted span is one token, so a command that is passed as a quoted
|
|
56
|
+
* argument stays one thing: `bash -c "git commit -n"` is three tokens and
|
|
57
|
+
* the third one holds the command. The quotes are kept, so the caller can
|
|
58
|
+
* tell a value from an argument.
|
|
59
|
+
*/
|
|
60
|
+
export function tokenise(command) {
|
|
61
|
+
return scanCommand(command, (char) => /\s/.test(char));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A token without its quotes.
|
|
65
|
+
*/
|
|
66
|
+
function unquote(token) {
|
|
67
|
+
if (token.length < 2)
|
|
68
|
+
return token;
|
|
69
|
+
const first = token[0];
|
|
70
|
+
const last = token[token.length - 1];
|
|
71
|
+
if ((first === '"' || first === "'") && first === last)
|
|
72
|
+
return token.slice(1, -1);
|
|
73
|
+
return token;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The flags whose value is a message and not an argument.
|
|
77
|
+
*/
|
|
78
|
+
const MESSAGE_FLAGS = new Set(['-m', '--message', '-F', '--file']);
|
|
79
|
+
/** The message flags that carry their value with an equals sign. */
|
|
80
|
+
const MESSAGE_FLAG_PREFIXES = ['-m=', '--message=', '-F=', '--file='];
|
|
81
|
+
/** The git subcommands whose arguments the hook rule reads. */
|
|
82
|
+
const GIT_SUBCOMMANDS = new Set(['commit', 'merge', 'rebase']);
|
|
83
|
+
/** The characters that end a command. */
|
|
84
|
+
const SEPARATOR_CHARS = new Set([';', '&', '|', '(', ')', '\n']);
|
|
85
|
+
/**
|
|
86
|
+
* Whether a token is a quoted span.
|
|
87
|
+
*/
|
|
88
|
+
function isQuoted(token) {
|
|
89
|
+
if (token.length < 2)
|
|
90
|
+
return false;
|
|
91
|
+
const first = token[0];
|
|
92
|
+
const last = token[token.length - 1];
|
|
93
|
+
return (first === '"' || first === "'") && first === last;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The command, split into the segments a separator ends.
|
|
97
|
+
*
|
|
98
|
+
* A separator inside a quoted span does not end a segment: the span is one
|
|
99
|
+
* argument, and a command in it belongs to the command that holds the
|
|
100
|
+
* argument.
|
|
101
|
+
*/
|
|
102
|
+
export function commandSegments(command) {
|
|
103
|
+
return scanCommand(command, (char) => SEPARATOR_CHARS.has(char)).filter((piece) => piece.trim() !== '');
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Whether the tokens are a git command the hook rule reads.
|
|
107
|
+
*/
|
|
108
|
+
function isGitParse(tokens) {
|
|
109
|
+
const gitIndex = tokens.indexOf('git');
|
|
110
|
+
if (gitIndex === -1)
|
|
111
|
+
return false;
|
|
112
|
+
const next = tokens[gitIndex + 1];
|
|
113
|
+
return next !== undefined && GIT_SUBCOMMANDS.has(next);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The tokens of a segment, without the values of the message flags.
|
|
117
|
+
*
|
|
118
|
+
* The value of a message flag is a message and not an argument, and it is
|
|
119
|
+
* dropped only inside a git command: `git commit -m "docs: explain rm
|
|
120
|
+
* -rf /"` is a commit whose message talks about a removal, while the `-m`
|
|
121
|
+
* of another command is that command's own flag.
|
|
122
|
+
*/
|
|
123
|
+
function segmentTokens(segment) {
|
|
124
|
+
const tokens = tokenise(segment);
|
|
125
|
+
if (!isGitParse(tokens))
|
|
126
|
+
return tokens;
|
|
127
|
+
const kept = [];
|
|
128
|
+
for (let index = 0; index < tokens.length; index += 1) {
|
|
129
|
+
const token = tokens[index] ?? '';
|
|
130
|
+
if (MESSAGE_FLAGS.has(token)) {
|
|
131
|
+
index += 1;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (MESSAGE_FLAG_PREFIXES.some((flag) => token.startsWith(flag)))
|
|
135
|
+
continue;
|
|
136
|
+
kept.push(token);
|
|
137
|
+
}
|
|
138
|
+
return kept;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The payload of every substitution in a command.
|
|
142
|
+
*
|
|
143
|
+
* The shell runs a substitution before the command that holds it, so the
|
|
144
|
+
* payload is a command of its own: `git commit -m "$(rm -rf /)"` removes
|
|
145
|
+
* the directory even though the message is only text.
|
|
146
|
+
*/
|
|
147
|
+
export function substitutionPayloads(command) {
|
|
148
|
+
const payloads = [];
|
|
149
|
+
const patterns = [/\$\(([^()]*)\)/g, /<\(([^()]*)\)/g, /`([^`]*)`/g];
|
|
150
|
+
for (const pattern of patterns) {
|
|
151
|
+
for (const match of command.matchAll(pattern)) {
|
|
152
|
+
const payload = match[1];
|
|
153
|
+
if (payload !== undefined && payload.trim() !== '')
|
|
154
|
+
payloads.push(payload);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return payloads;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The scope of the shell matcher.
|
|
161
|
+
*
|
|
162
|
+
* It covers: the flags of a removal in any order and either spelling, the
|
|
163
|
+
* git commands that skip the hooks, the other package managers, and the
|
|
164
|
+
* payload of every quoted span and every substitution, which is scanned as
|
|
165
|
+
* a command of its own.
|
|
166
|
+
*
|
|
167
|
+
* It does not cover: the shell. A payload behind a construct this matcher
|
|
168
|
+
* does not read - an alias, a function, a here-document, a variable - is
|
|
169
|
+
* not seen. A name the matcher does not know is treated as a writer, not
|
|
170
|
+
* as a reader.
|
|
171
|
+
*/
|
|
172
|
+
export function scannedParts(command) {
|
|
173
|
+
const parts = [];
|
|
174
|
+
for (const segment of commandSegments(command)) {
|
|
175
|
+
parts.push(...segmentParts(segment));
|
|
176
|
+
}
|
|
177
|
+
for (const payload of substitutionPayloads(command)) {
|
|
178
|
+
parts.push(...scannedParts(payload));
|
|
179
|
+
}
|
|
180
|
+
return parts;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* The parts of one segment.
|
|
184
|
+
*
|
|
185
|
+
* The quotes are flattened, so a command in a quoted span is read, and the
|
|
186
|
+
* separators the span held are separators again.
|
|
187
|
+
*/
|
|
188
|
+
function segmentParts(segment) {
|
|
189
|
+
const tokens = segmentTokens(segment);
|
|
190
|
+
const parts = commandSegments(tokens.map((token) => unquote(token)).join(' '));
|
|
191
|
+
for (const token of tokens) {
|
|
192
|
+
if (!isQuoted(token))
|
|
193
|
+
continue;
|
|
194
|
+
parts.push(...scannedParts(unquote(token)));
|
|
195
|
+
}
|
|
196
|
+
return parts;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Whether a command skips the git hooks.
|
|
200
|
+
*
|
|
201
|
+
* The `-n` of `git commit` is the short form of `--no-verify`, and it is
|
|
202
|
+
* caught in any position of the commit's own arguments:
|
|
203
|
+
* `git commit -n`, `git commit -m "wip" -n`, `git commit -a -n` and
|
|
204
|
+
* `git commit -nm "wip"` all skip the hooks. A command that is passed as a
|
|
205
|
+
* quoted argument is read too, so `bash -c "git commit -n"` is caught.
|
|
206
|
+
*/
|
|
207
|
+
export function skipsGitHooks(command) {
|
|
208
|
+
return scannedParts(command).some((part) => partSkipsHooks(part));
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Whether a part of a command skips the git hooks.
|
|
212
|
+
*
|
|
213
|
+
* The flags are read from the arguments of the git subcommand alone: the
|
|
214
|
+
* `-n` of `git merge` is `--no-stat`, the `-n` of `sudo` belongs to sudo,
|
|
215
|
+
* and after `--` a git command takes pathspecs. The long flag is matched
|
|
216
|
+
* by the prefixes git accepts, so `--no-verbose` is not a skip.
|
|
217
|
+
*/
|
|
218
|
+
function partSkipsHooks(part) {
|
|
219
|
+
if (/\bHUSKY=0\b/.test(part))
|
|
220
|
+
return true;
|
|
221
|
+
if (/\bcore\.hooksPath\b/.test(part))
|
|
222
|
+
return true;
|
|
223
|
+
const tokens = part.split(/\s+/).filter((token) => token.length > 0);
|
|
224
|
+
const gitIndex = tokens.indexOf('git');
|
|
225
|
+
if (gitIndex === -1)
|
|
226
|
+
return false;
|
|
227
|
+
const subIndex = tokens.findIndex((token, index) => index > gitIndex && GIT_SUBCOMMANDS.has(token));
|
|
228
|
+
if (subIndex === -1)
|
|
229
|
+
return false;
|
|
230
|
+
const args = [];
|
|
231
|
+
for (const token of tokens.slice(subIndex + 1)) {
|
|
232
|
+
if (token === '--')
|
|
233
|
+
break;
|
|
234
|
+
args.push(token);
|
|
235
|
+
}
|
|
236
|
+
if (args.some((token) => /^--no-(veri|verif|verify)$/.test(token)))
|
|
237
|
+
return true;
|
|
238
|
+
// The -n is the short form of --no-verify for commit alone.
|
|
239
|
+
if (tokens[subIndex] !== 'commit')
|
|
240
|
+
return false;
|
|
241
|
+
return args.some((token) => /^-([A-Za-z]+)$/.exec(token)?.[1]?.includes('n') === true);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* The package manager is Bun.
|
|
245
|
+
*
|
|
246
|
+
* A second package manager writes a second lockfile, and the two
|
|
247
|
+
* lockfiles disagree about what the project depends on. The name is
|
|
248
|
+
* caught wherever it is written, so a path to another package manager is
|
|
249
|
+
* caught too.
|
|
250
|
+
*/
|
|
251
|
+
const OTHER_PM = /(^|[\s;&|(/\\])(pnpm|yarn|npx|npm\s+(i|install|ci|add|exec))\b/i;
|
|
252
|
+
/**
|
|
253
|
+
* The files a person changes.
|
|
254
|
+
*
|
|
255
|
+
* The trust boundary is wider than the roles file: the model lock and the
|
|
256
|
+
* agent files are generated, the workflows run CI, the templates
|
|
257
|
+
* regenerate the agents, and the lessons, the waivers and the approvals
|
|
258
|
+
* are decisions.
|
|
259
|
+
*/
|
|
260
|
+
const PROTECTED_FILES = new Set([
|
|
261
|
+
'roles.yaml',
|
|
262
|
+
'openagentsy.models.lock.json',
|
|
263
|
+
'openagentsy.jsonc',
|
|
264
|
+
'biome.jsonc',
|
|
265
|
+
'turbo.json',
|
|
266
|
+
'bunfig.toml',
|
|
267
|
+
'bun.lock',
|
|
268
|
+
'opencode.json',
|
|
269
|
+
'opencode.jsonc',
|
|
270
|
+
]);
|
|
271
|
+
/** The directories a person changes. */
|
|
272
|
+
const PROTECTED_DIRS = ['.opencode', '.husky', '.github/workflows', 'templates'];
|
|
273
|
+
/**
|
|
274
|
+
* The state a person changes, under the state root.
|
|
275
|
+
*/
|
|
276
|
+
const PROTECTED_STATE = [
|
|
277
|
+
'.openagentsy/lessons',
|
|
278
|
+
'.openagentsy/quality/waivers.json',
|
|
279
|
+
'.openagentsy/conformance.json',
|
|
280
|
+
'.openagentsy/memory.jsonl',
|
|
281
|
+
'.openagentsy/approvals.json',
|
|
282
|
+
];
|
|
283
|
+
/**
|
|
284
|
+
* The lock family of the approval store.
|
|
285
|
+
*
|
|
286
|
+
* Every name in it is protected: the lock, the reclaim file, the stale
|
|
287
|
+
* file and the private copy a release makes. They are the store's, and an
|
|
288
|
+
* agent that removes one of them breaks the serialisation.
|
|
289
|
+
*/
|
|
290
|
+
function isApprovalLock(segments) {
|
|
291
|
+
if (!segments.includes('.openagentsy'))
|
|
292
|
+
return false;
|
|
293
|
+
const last = segments[segments.length - 1] ?? '';
|
|
294
|
+
return last.startsWith('approvals.json.lock');
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Whether the segments of a path hold a run of segments.
|
|
298
|
+
*/
|
|
299
|
+
function holdsSegments(segments, wanted) {
|
|
300
|
+
if (wanted.length === 0 || wanted.length > segments.length)
|
|
301
|
+
return false;
|
|
302
|
+
for (let start = 0; start + wanted.length <= segments.length; start += 1) {
|
|
303
|
+
if (wanted.every((segment, index) => segments[start + index] === segment))
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Whether a path is one a person changes.
|
|
310
|
+
*
|
|
311
|
+
* The path is compared on its segments, so a directory is a directory
|
|
312
|
+
* whether or not the path names it with a trailing slash, and a file is a
|
|
313
|
+
* file wherever it sits. A delete or a move that names the directory
|
|
314
|
+
* itself is caught as well.
|
|
315
|
+
*/
|
|
316
|
+
export function isProtected(path) {
|
|
317
|
+
const segments = pathSegments(path);
|
|
318
|
+
if (segments.length === 0)
|
|
319
|
+
return false;
|
|
320
|
+
const last = segments[segments.length - 1] ?? '';
|
|
321
|
+
if (PROTECTED_FILES.has(last))
|
|
322
|
+
return true;
|
|
323
|
+
for (const dir of PROTECTED_DIRS) {
|
|
324
|
+
if (holdsSegments(segments, dir.split('/')))
|
|
325
|
+
return true;
|
|
326
|
+
}
|
|
327
|
+
for (const entry of PROTECTED_STATE) {
|
|
328
|
+
if (holdsSegments(segments, entry.split('/')))
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
return isApprovalLock(segments);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* The tools a person decides with.
|
|
335
|
+
*
|
|
336
|
+
* The permission map denies these to every agent role, and that map is the
|
|
337
|
+
* primary enforcement: the rule is the second layer, for the built-in
|
|
338
|
+
* tools and for any host where the map is not the whole answer.
|
|
339
|
+
*/
|
|
340
|
+
const HUMAN_ONLY_TOOLS = ['oa_lesson_decide', 'oa_quality_waive', 'oa_memory_decide'];
|
|
341
|
+
/**
|
|
342
|
+
* Whether a flag makes a removal recursive.
|
|
343
|
+
*/
|
|
344
|
+
function isRecursiveFlag(flag) {
|
|
345
|
+
if (flag.startsWith('--'))
|
|
346
|
+
return flag === '--recursive';
|
|
347
|
+
const letters = flag.slice(1);
|
|
348
|
+
return letters.includes('r') || letters.includes('R');
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Whether a flag makes a removal forced.
|
|
352
|
+
*/
|
|
353
|
+
function isForceFlag(flag) {
|
|
354
|
+
if (flag.startsWith('--'))
|
|
355
|
+
return flag === '--force';
|
|
356
|
+
return flag.slice(1).includes('f');
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Whether a token names the removal.
|
|
360
|
+
*
|
|
361
|
+
* The name may follow the punctuation of the shell: `(rm`, `\rm` and
|
|
362
|
+
* `;rm` are the removal, and a subshell runs it.
|
|
363
|
+
*/
|
|
364
|
+
function isRmToken(token) {
|
|
365
|
+
return /(^|[/\\();|&])rm$/.test(token);
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* The flags of a removal.
|
|
369
|
+
*
|
|
370
|
+
* The flags are read to the end of the segment, because GNU `rm` permutes
|
|
371
|
+
* them: `rm build -rf` is `rm -rf build`. An operand is not a flag and
|
|
372
|
+
* does not end the scan, and `--` ends it.
|
|
373
|
+
*/
|
|
374
|
+
function rmFlags(tokens, from) {
|
|
375
|
+
const flags = [];
|
|
376
|
+
for (let index = from; index < tokens.length; index += 1) {
|
|
377
|
+
const token = tokens[index];
|
|
378
|
+
if (token === undefined || token === '--')
|
|
379
|
+
break;
|
|
380
|
+
if (!token.startsWith('-'))
|
|
381
|
+
continue;
|
|
382
|
+
flags.push(token);
|
|
383
|
+
}
|
|
384
|
+
return flags;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Whether the flags are a recursive and a forced removal.
|
|
388
|
+
*/
|
|
389
|
+
function isDangerousFlags(flags) {
|
|
390
|
+
return flags.some(isRecursiveFlag) && flags.some(isForceFlag);
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Whether the text holds a destructive `rm`.
|
|
394
|
+
*
|
|
395
|
+
* The flags of the removal are read in any order and in either spelling,
|
|
396
|
+
* and the dangerous pair is a recursive removal and a force: `rm -rf`,
|
|
397
|
+
* `rm -fr`, `rm -r -f` and `rm --recursive --force` are the same command.
|
|
398
|
+
* A removal that is not both is not the dangerous one.
|
|
399
|
+
*/
|
|
400
|
+
function hasDestructiveRm(command) {
|
|
401
|
+
const tokens = command.split(/\s+/).filter((token) => token.length > 0);
|
|
402
|
+
return tokens.some((token, index) => isRmToken(token) && isDangerousFlags(rmFlags(tokens, index + 1)));
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Whether a command destroys something.
|
|
406
|
+
*
|
|
407
|
+
* The command is read in parts, so a destructive command inside a
|
|
408
|
+
* substitution or inside a quoted argument is still one: `echo $(rm -rf
|
|
409
|
+
* /)` and `bash -c "rm -rf /"` are both caught. The flags of a removal
|
|
410
|
+
* are read per part, so `rm -r build; rm -f /tmp/x` is two removals and
|
|
411
|
+
* neither is the dangerous one.
|
|
412
|
+
*/
|
|
413
|
+
export function isDestructiveCommand(command) {
|
|
414
|
+
return scannedParts(command).some((part) => partIsDestructive(part));
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Whether a part of a command destroys something.
|
|
418
|
+
*/
|
|
419
|
+
function partIsDestructive(part) {
|
|
420
|
+
if (/\bgit\s+push\s+--force\b/i.test(part))
|
|
421
|
+
return true;
|
|
422
|
+
if (/\bgit\s+reset\s+--hard\b/i.test(part))
|
|
423
|
+
return true;
|
|
424
|
+
if (/\bdrop\s+table\b/i.test(part))
|
|
425
|
+
return true;
|
|
426
|
+
return hasDestructiveRm(part);
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Whether a command uses another package manager.
|
|
430
|
+
*/
|
|
431
|
+
export function usesOtherPackageManager(command) {
|
|
432
|
+
return scannedParts(command).some((part) => OTHER_PM.test(part));
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* The text a call would write.
|
|
436
|
+
*
|
|
437
|
+
* The host puts the content in the arguments: a write carries `content`,
|
|
438
|
+
* an edit carries `newString`, and a patch carries the whole patch. A
|
|
439
|
+
* patch is read for the lines it adds, so a secret in the text that is
|
|
440
|
+
* being added is found.
|
|
441
|
+
*/
|
|
442
|
+
export function contentOf(event) {
|
|
443
|
+
const parts = [];
|
|
444
|
+
for (const key of ['content', 'newString', 'text']) {
|
|
445
|
+
const value = event.args[key];
|
|
446
|
+
if (typeof value === 'string')
|
|
447
|
+
parts.push(value);
|
|
448
|
+
}
|
|
449
|
+
for (const key of ['patchText', 'patch']) {
|
|
450
|
+
const value = event.args[key];
|
|
451
|
+
if (typeof value === 'string')
|
|
452
|
+
parts.push(addedLines(value));
|
|
453
|
+
}
|
|
454
|
+
return parts.join('\n');
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* The lines a patch adds.
|
|
458
|
+
*/
|
|
459
|
+
function addedLines(patch) {
|
|
460
|
+
return patch
|
|
461
|
+
.split('\n')
|
|
462
|
+
.filter((line) => line.startsWith('+') && !line.startsWith('+++'))
|
|
463
|
+
.map((line) => line.slice(1))
|
|
464
|
+
.join('\n');
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* A path, made absolute against the workspace.
|
|
468
|
+
*
|
|
469
|
+
* A host names a file either way, and a relative path is relative to the
|
|
470
|
+
* project the agent works in.
|
|
471
|
+
*/
|
|
472
|
+
function absolutePath(root, path) {
|
|
473
|
+
return isAbsolute(path) ? path : resolve(root, path);
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Whether a call writes a file.
|
|
477
|
+
*
|
|
478
|
+
* A known writing tool writes. A known reader does not, even when the
|
|
479
|
+
* host says which file it read, so the exclusion cannot come back through
|
|
480
|
+
* the bridge. A name that is neither is treated as a writer when the
|
|
481
|
+
* call carries a file: a rule that let an unknown name through would let
|
|
482
|
+
* every write the host names in an unfamiliar way through.
|
|
483
|
+
*/
|
|
484
|
+
function writesFiles(call) {
|
|
485
|
+
if (isReaderTool(call.toolName))
|
|
486
|
+
return false;
|
|
487
|
+
if (isWritingTool(call.toolName))
|
|
488
|
+
return true;
|
|
489
|
+
return call.files.length > 0;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Whether a call writes content.
|
|
493
|
+
*/
|
|
494
|
+
function writesContent(call) {
|
|
495
|
+
if (isReaderTool(call.toolName))
|
|
496
|
+
return false;
|
|
497
|
+
if (isWritingTool(call.toolName))
|
|
498
|
+
return true;
|
|
499
|
+
return contentOf(call) !== '';
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* The seven default rules.
|
|
503
|
+
*
|
|
504
|
+
* They run in the order they are written, and every one of them blocks.
|
|
505
|
+
*/
|
|
506
|
+
export const defaultRules = ({ workspace, stateRoot, home, quality, }) => {
|
|
507
|
+
const root = resolve(workspace);
|
|
508
|
+
const roots = [root, worktreeRoot(projectName(root), home)];
|
|
509
|
+
const approvals = createApprovalStore(stateRoot);
|
|
510
|
+
return [
|
|
511
|
+
...(quality === undefined ? [] : [qualityAfterWrite({ workspace, stateRoot, ...quality })]),
|
|
512
|
+
{
|
|
513
|
+
id: 'no-skip-git-hooks',
|
|
514
|
+
event: 'PreToolCall',
|
|
515
|
+
block: true,
|
|
516
|
+
handler: (event) => {
|
|
517
|
+
const call = readPreToolCall(event);
|
|
518
|
+
if (call === undefined || call.command === undefined)
|
|
519
|
+
return CONTINUE;
|
|
520
|
+
if (!skipsGitHooks(call.command))
|
|
521
|
+
return CONTINUE;
|
|
522
|
+
return {
|
|
523
|
+
continue: false,
|
|
524
|
+
reason: 'Git hooks (lint, typecheck) cannot be skipped. Fix the reported errors instead.',
|
|
525
|
+
};
|
|
526
|
+
},
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
id: 'package-manager',
|
|
530
|
+
event: 'PreToolCall',
|
|
531
|
+
block: true,
|
|
532
|
+
handler: (event) => {
|
|
533
|
+
const call = readPreToolCall(event);
|
|
534
|
+
if (call === undefined || call.command === undefined)
|
|
535
|
+
return CONTINUE;
|
|
536
|
+
if (!usesOtherPackageManager(call.command))
|
|
537
|
+
return CONTINUE;
|
|
538
|
+
return {
|
|
539
|
+
continue: false,
|
|
540
|
+
reason: 'This repo uses Bun. Use `bun add` / `bun remove` / `bunx`, or `turbo run <task>`.',
|
|
541
|
+
};
|
|
542
|
+
},
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
id: 'workspace-writes-only',
|
|
546
|
+
event: 'PreToolCall',
|
|
547
|
+
block: true,
|
|
548
|
+
handler: (event) => {
|
|
549
|
+
const call = readPreToolCall(event);
|
|
550
|
+
if (call === undefined)
|
|
551
|
+
return CONTINUE;
|
|
552
|
+
if (!writesFiles(call))
|
|
553
|
+
return CONTINUE;
|
|
554
|
+
const outside = call.files.some((file) => [file.path, file.fromPath]
|
|
555
|
+
.filter((path) => path !== undefined)
|
|
556
|
+
.some((path) => !isInside(absolutePath(root, path), roots)));
|
|
557
|
+
if (!outside)
|
|
558
|
+
return CONTINUE;
|
|
559
|
+
return {
|
|
560
|
+
continue: false,
|
|
561
|
+
reason: 'Writes are limited to the workspace and OpenAgentsy worktrees.',
|
|
562
|
+
};
|
|
563
|
+
},
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
id: 'protect-policy',
|
|
567
|
+
event: 'PreToolCall',
|
|
568
|
+
block: true,
|
|
569
|
+
handler: (event) => {
|
|
570
|
+
const call = readPreToolCall(event);
|
|
571
|
+
if (call === undefined)
|
|
572
|
+
return CONTINUE;
|
|
573
|
+
if (!writesFiles(call))
|
|
574
|
+
return CONTINUE;
|
|
575
|
+
const touched = call.files.some((file) => (file.path !== undefined && isProtected(file.path)) ||
|
|
576
|
+
(file.fromPath !== undefined && isProtected(file.fromPath)));
|
|
577
|
+
if (!touched)
|
|
578
|
+
return CONTINUE;
|
|
579
|
+
return {
|
|
580
|
+
continue: false,
|
|
581
|
+
reason: 'Policy, role, permission, build-config, lockfile, hook, workflow, lesson and waiver files are changed by a person (or, for bun.lock, by `bun add`; for roles.yaml and templates, by running the generator). Propose the change in chat.',
|
|
582
|
+
};
|
|
583
|
+
},
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
id: 'human-only-decisions',
|
|
587
|
+
event: 'PreToolCall',
|
|
588
|
+
block: true,
|
|
589
|
+
handler: (event) => {
|
|
590
|
+
const call = readPreToolCall(event);
|
|
591
|
+
if (call === undefined)
|
|
592
|
+
return CONTINUE;
|
|
593
|
+
const tool = call.toolName;
|
|
594
|
+
const humanOnly = HUMAN_ONLY_TOOLS.some((name) => tool === name || tool.endsWith(`_${name}`));
|
|
595
|
+
if (!humanOnly)
|
|
596
|
+
return CONTINUE;
|
|
597
|
+
return {
|
|
598
|
+
continue: false,
|
|
599
|
+
reason: 'Lesson decisions, quality waivers and memory promotions are recorded by a person (/oa lesson, /oa waive, /oa memory). Propose it in chat with your evidence.',
|
|
600
|
+
};
|
|
601
|
+
},
|
|
602
|
+
},
|
|
603
|
+
{
|
|
604
|
+
id: 'secret-scan-writes',
|
|
605
|
+
event: 'PreToolCall',
|
|
606
|
+
block: true,
|
|
607
|
+
handler: (event) => {
|
|
608
|
+
const call = readPreToolCall(event);
|
|
609
|
+
if (call === undefined)
|
|
610
|
+
return CONTINUE;
|
|
611
|
+
if (!writesContent(call))
|
|
612
|
+
return CONTINUE;
|
|
613
|
+
const content = contentOf(call);
|
|
614
|
+
if (content === '')
|
|
615
|
+
return CONTINUE;
|
|
616
|
+
if (findSecrets(content).length === 0)
|
|
617
|
+
return CONTINUE;
|
|
618
|
+
return {
|
|
619
|
+
continue: false,
|
|
620
|
+
reason: 'The content contains what looks like a credential. Use an env var or secret reference.',
|
|
621
|
+
};
|
|
622
|
+
},
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
id: 'destructive-needs-approval',
|
|
626
|
+
event: 'PreToolCall',
|
|
627
|
+
block: true,
|
|
628
|
+
handler: approvalGate(isDestructiveCommand, approvals),
|
|
629
|
+
},
|
|
630
|
+
];
|
|
631
|
+
};
|
|
632
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.test.d.ts","sourceRoot":"","sources":["../src/rules.test.ts"],"names":[],"mappings":""}
|