@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
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Finding } from '@openagentsy/quality/rule';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* The waivers.
|
|
5
|
+
*
|
|
6
|
+
* A waiver is a decision a person makes: this rule is not a problem in this
|
|
7
|
+
* file, and here is why. An agent may propose one in chat; only a person
|
|
8
|
+
* records one, with the command. So the file holds the decisions of people,
|
|
9
|
+
* and the rule asks the store whether a finding is covered before it calls
|
|
10
|
+
* that finding open.
|
|
11
|
+
*
|
|
12
|
+
* The file lives under the state root, beside the findings, and it is the
|
|
13
|
+
* only truth: the rule reads it after a write, and the write of a waiver is
|
|
14
|
+
* the write of a person and not of a session.
|
|
15
|
+
*/
|
|
16
|
+
/** A waiver, as the file holds it. */
|
|
17
|
+
export declare const WaiverSchema: z.ZodObject<{
|
|
18
|
+
ruleId: z.ZodString;
|
|
19
|
+
path: z.ZodString;
|
|
20
|
+
reason: z.ZodString;
|
|
21
|
+
decidedBy: z.ZodString;
|
|
22
|
+
ts: z.ZodString;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
/** A waiver. */
|
|
25
|
+
export type Waiver = z.infer<typeof WaiverSchema>;
|
|
26
|
+
/** The file the waivers live in. */
|
|
27
|
+
export declare function waiversPath(stateRoot: string): string;
|
|
28
|
+
/** What the store can do. */
|
|
29
|
+
export interface WaiverStore {
|
|
30
|
+
/** Every waiver. */
|
|
31
|
+
all(): Promise<Waiver[]>;
|
|
32
|
+
/** Record a waiver. */
|
|
33
|
+
add(waiver: Waiver): Promise<void>;
|
|
34
|
+
/** How many waivers there are. */
|
|
35
|
+
count(): Promise<number>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The store of a project.
|
|
39
|
+
*
|
|
40
|
+
* The state root is the root of the project, so two projects never read
|
|
41
|
+
* each other's waivers.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createWaiverStore(stateRoot: string): WaiverStore;
|
|
44
|
+
/**
|
|
45
|
+
* The lookup the rule asks.
|
|
46
|
+
*
|
|
47
|
+
* The rule holds the seam, and this is what fills it: a finding that a
|
|
48
|
+
* waiver covers is not open.
|
|
49
|
+
*/
|
|
50
|
+
export interface WaiverLookup {
|
|
51
|
+
/** Whether a waiver covers a finding. */
|
|
52
|
+
covers(finding: Finding): boolean;
|
|
53
|
+
}
|
|
54
|
+
/** The lookup that covers nothing. */
|
|
55
|
+
export declare const noWaivers: WaiverLookup;
|
|
56
|
+
/**
|
|
57
|
+
* The lookup of the waivers on disk.
|
|
58
|
+
*
|
|
59
|
+
* The waivers are read once, and the lookup answers from what it read: the
|
|
60
|
+
* rule asks on every write, and a write may not wait for a file.
|
|
61
|
+
*/
|
|
62
|
+
export declare function loadWaiverLookup(stateRoot: string): Promise<WaiverLookup>;
|
|
63
|
+
//# sourceMappingURL=waivers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waivers.d.ts","sourceRoot":"","sources":["../../src/quality/waivers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;GAYG;AAEH,sCAAsC;AACtC,eAAO,MAAM,YAAY;;;;;;iBAMvB,CAAC;AAEH,gBAAgB;AAChB,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,oCAAoC;AACpC,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAErD;AAWD,6BAA6B;AAC7B,MAAM,WAAW,WAAW;IAC1B,oBAAoB;IACpB,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzB,uBAAuB;IACvB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,kCAAkC;IAClC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAUhE;AA8CD;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;CACnC;AAED,sCAAsC;AACtC,eAAO,MAAM,SAAS,EAAE,YAAsC,CAAC;AAE/D;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAG/E"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { normalizePath } from '@openagentsy/core';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
/**
|
|
6
|
+
* The waivers.
|
|
7
|
+
*
|
|
8
|
+
* A waiver is a decision a person makes: this rule is not a problem in this
|
|
9
|
+
* file, and here is why. An agent may propose one in chat; only a person
|
|
10
|
+
* records one, with the command. So the file holds the decisions of people,
|
|
11
|
+
* and the rule asks the store whether a finding is covered before it calls
|
|
12
|
+
* that finding open.
|
|
13
|
+
*
|
|
14
|
+
* The file lives under the state root, beside the findings, and it is the
|
|
15
|
+
* only truth: the rule reads it after a write, and the write of a waiver is
|
|
16
|
+
* the write of a person and not of a session.
|
|
17
|
+
*/
|
|
18
|
+
/** A waiver, as the file holds it. */
|
|
19
|
+
export const WaiverSchema = z.object({
|
|
20
|
+
ruleId: z.string(),
|
|
21
|
+
path: z.string(),
|
|
22
|
+
reason: z.string().min(10),
|
|
23
|
+
decidedBy: z.string(),
|
|
24
|
+
ts: z.string(),
|
|
25
|
+
});
|
|
26
|
+
/** The file the waivers live in. */
|
|
27
|
+
export function waiversPath(stateRoot) {
|
|
28
|
+
return join(stateRoot, '.openagentsy', 'quality', 'waivers.json');
|
|
29
|
+
}
|
|
30
|
+
/** The file, as it holds the waivers. */
|
|
31
|
+
const WaiversFileSchema = z.object({
|
|
32
|
+
version: z.number(),
|
|
33
|
+
waivers: z.array(WaiverSchema),
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* The store of a project.
|
|
37
|
+
*
|
|
38
|
+
* The state root is the root of the project, so two projects never read
|
|
39
|
+
* each other's waivers.
|
|
40
|
+
*/
|
|
41
|
+
export function createWaiverStore(stateRoot) {
|
|
42
|
+
const path = waiversPath(stateRoot);
|
|
43
|
+
return {
|
|
44
|
+
all: async () => (await readState(path)).waivers,
|
|
45
|
+
add: async (waiver) => {
|
|
46
|
+
const state = await readState(path);
|
|
47
|
+
await writeState(path, { version: state.version, waivers: [...state.waivers, waiver] });
|
|
48
|
+
},
|
|
49
|
+
count: async () => (await readState(path)).waivers.length,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** The state of a project that has no waivers yet. */
|
|
53
|
+
function emptyState() {
|
|
54
|
+
return { version: 1, waivers: [] };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* What the file holds, when it holds something a store can read.
|
|
58
|
+
*
|
|
59
|
+
* A file that cannot be read, or that does not fit the schema, holds
|
|
60
|
+
* nothing: a broken file of decisions must not fail the write that asked
|
|
61
|
+
* about them.
|
|
62
|
+
*/
|
|
63
|
+
async function readState(path) {
|
|
64
|
+
let text;
|
|
65
|
+
try {
|
|
66
|
+
text = await readFile(path, 'utf8');
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return emptyState();
|
|
70
|
+
}
|
|
71
|
+
let parsed;
|
|
72
|
+
try {
|
|
73
|
+
parsed = JSON.parse(text);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return emptyState();
|
|
77
|
+
}
|
|
78
|
+
const result = WaiversFileSchema.safeParse(parsed);
|
|
79
|
+
if (!result.success)
|
|
80
|
+
return emptyState();
|
|
81
|
+
return result.data;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Write the state.
|
|
85
|
+
*
|
|
86
|
+
* The write goes to a temporary file that is renamed over the old one, so a
|
|
87
|
+
* reader never sees half a file: the rule reads this file while the person
|
|
88
|
+
* writes it.
|
|
89
|
+
*/
|
|
90
|
+
async function writeState(path, state) {
|
|
91
|
+
await mkdir(dirname(path), { recursive: true });
|
|
92
|
+
const temporary = `${path}.tmp`;
|
|
93
|
+
await writeFile(temporary, `${JSON.stringify(state, null, 2)}\n`, 'utf8');
|
|
94
|
+
await rename(temporary, path);
|
|
95
|
+
}
|
|
96
|
+
/** The lookup that covers nothing. */
|
|
97
|
+
export const noWaivers = { covers: () => false };
|
|
98
|
+
/**
|
|
99
|
+
* The lookup of the waivers on disk.
|
|
100
|
+
*
|
|
101
|
+
* The waivers are read once, and the lookup answers from what it read: the
|
|
102
|
+
* rule asks on every write, and a write may not wait for a file.
|
|
103
|
+
*/
|
|
104
|
+
export async function loadWaiverLookup(stateRoot) {
|
|
105
|
+
const waivers = await createWaiverStore(stateRoot).all();
|
|
106
|
+
return { covers: (finding) => coversFinding(stateRoot, waivers, finding) };
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Whether one of the waivers covers a finding.
|
|
110
|
+
*
|
|
111
|
+
* A waiver names a rule and a path, and it covers the findings of that rule
|
|
112
|
+
* in that file and in no other.
|
|
113
|
+
*/
|
|
114
|
+
function coversFinding(root, waivers, finding) {
|
|
115
|
+
const file = relativeTo(root, finding.file);
|
|
116
|
+
return waivers.some((waiver) => waiver.ruleId === finding.ruleId && relativeTo(root, waiver.path) === file);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* A path relative to the root, when the path is inside it.
|
|
120
|
+
*
|
|
121
|
+
* A finding carries the path the agent knows, and that path is sometimes
|
|
122
|
+
* absolute and sometimes relative. A waiver carries the path a person
|
|
123
|
+
* typed. Both are brought to the same form before they are compared.
|
|
124
|
+
*/
|
|
125
|
+
function relativeTo(root, path) {
|
|
126
|
+
const normalized = normalizePath(path);
|
|
127
|
+
const base = normalizePath(root);
|
|
128
|
+
if (!normalized.startsWith(`${base}/`))
|
|
129
|
+
return normalized;
|
|
130
|
+
return normalized.slice(base.length + 1);
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=waivers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waivers.js","sourceRoot":"","sources":["../../src/quality/waivers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waivers.test.d.ts","sourceRoot":"","sources":["../../src/quality/waivers.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { mkdtemp, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { waive } from './waive.js';
|
|
6
|
+
import { createWaiverStore, loadWaiverLookup, noWaivers, waiversPath, } from './waivers.js';
|
|
7
|
+
/** A state root the test writes into. */
|
|
8
|
+
async function scratch() {
|
|
9
|
+
return await mkdtemp(join(tmpdir(), 'openagentsy-waivers-'));
|
|
10
|
+
}
|
|
11
|
+
/** A finding, for a waiver to cover. */
|
|
12
|
+
function finding(over = {}) {
|
|
13
|
+
return {
|
|
14
|
+
ruleId: 'css/no-transition-all',
|
|
15
|
+
source: 'hallmark:floor-2',
|
|
16
|
+
tier: 'reflex',
|
|
17
|
+
file: 'src/app.css',
|
|
18
|
+
line: 12,
|
|
19
|
+
message: 'A transition of all moves every property.',
|
|
20
|
+
fix: 'Name the properties to transition instead of all',
|
|
21
|
+
...over,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** A waiver, as a person recorded it. */
|
|
25
|
+
function waiver(over = {}) {
|
|
26
|
+
return {
|
|
27
|
+
ruleId: 'css/no-transition-all',
|
|
28
|
+
path: 'src/app.css',
|
|
29
|
+
reason: 'The file is a fixture, not a page.',
|
|
30
|
+
decidedBy: 'human',
|
|
31
|
+
ts: '2026-10-27T10:00:00.000Z',
|
|
32
|
+
...over,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
describe('the waiver store', () => {
|
|
36
|
+
it('holds no waiver when the project has none', async () => {
|
|
37
|
+
const root = await scratch();
|
|
38
|
+
const store = createWaiverStore(root);
|
|
39
|
+
expect(await store.all()).toEqual([]);
|
|
40
|
+
expect(await store.count()).toBe(0);
|
|
41
|
+
});
|
|
42
|
+
it('keeps the waivers in the state root', async () => {
|
|
43
|
+
const root = await scratch();
|
|
44
|
+
await createWaiverStore(root).add(waiver());
|
|
45
|
+
expect(waiversPath(root)).toBe(join(root, '.openagentsy', 'quality', 'waivers.json'));
|
|
46
|
+
const text = await readFile(waiversPath(root), 'utf8');
|
|
47
|
+
expect(text).toContain('css/no-transition-all');
|
|
48
|
+
});
|
|
49
|
+
it('reads a file that is not there as no waiver', async () => {
|
|
50
|
+
const root = await scratch();
|
|
51
|
+
expect(await createWaiverStore(root).all()).toEqual([]);
|
|
52
|
+
});
|
|
53
|
+
it('reads a file that is broken as no waiver', async () => {
|
|
54
|
+
const root = await scratch();
|
|
55
|
+
const store = createWaiverStore(root);
|
|
56
|
+
await store.add(waiver());
|
|
57
|
+
await writeFile(waiversPath(root), 'not json', 'utf8');
|
|
58
|
+
expect(await store.all()).toEqual([]);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('the waiver lookup', () => {
|
|
62
|
+
it('covers the finding the waiver names', async () => {
|
|
63
|
+
const root = await scratch();
|
|
64
|
+
await createWaiverStore(root).add(waiver());
|
|
65
|
+
const lookup = await loadWaiverLookup(root);
|
|
66
|
+
expect(lookup.covers(finding())).toBe(true);
|
|
67
|
+
});
|
|
68
|
+
it('covers no other rule and no other file', async () => {
|
|
69
|
+
const root = await scratch();
|
|
70
|
+
await createWaiverStore(root).add(waiver());
|
|
71
|
+
const lookup = await loadWaiverLookup(root);
|
|
72
|
+
expect(lookup.covers(finding({ ruleId: 'css/contrast' }))).toBe(false);
|
|
73
|
+
expect(lookup.covers(finding({ file: 'src/other.css' }))).toBe(false);
|
|
74
|
+
});
|
|
75
|
+
it('covers nothing when the project has no waiver', async () => {
|
|
76
|
+
const root = await scratch();
|
|
77
|
+
const lookup = await loadWaiverLookup(root);
|
|
78
|
+
expect(lookup.covers(finding())).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
it('covers nothing with the empty lookup', () => {
|
|
81
|
+
expect(noWaivers.covers(finding())).toBe(false);
|
|
82
|
+
});
|
|
83
|
+
it('compares an absolute path with a relative one', async () => {
|
|
84
|
+
const root = await scratch();
|
|
85
|
+
await createWaiverStore(root).add(waiver({ path: join(root, 'src/app.css') }));
|
|
86
|
+
const lookup = await loadWaiverLookup(root);
|
|
87
|
+
expect(lookup.covers(finding({ file: join(root, 'src/app.css') }))).toBe(true);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
describe('the recording of a waiver', () => {
|
|
91
|
+
it('records a waiver for a rule that may be waived', async () => {
|
|
92
|
+
const root = await scratch();
|
|
93
|
+
const recorded = await waive({
|
|
94
|
+
stateRoot: root,
|
|
95
|
+
ruleId: 'css/no-transition-all',
|
|
96
|
+
path: 'src/app.css',
|
|
97
|
+
reason: 'The file is a fixture, not a page.',
|
|
98
|
+
decidedBy: 'human',
|
|
99
|
+
});
|
|
100
|
+
expect(recorded.ruleId).toBe('css/no-transition-all');
|
|
101
|
+
expect(recorded.decidedBy).toBe('human');
|
|
102
|
+
expect(await createWaiverStore(root).count()).toBe(1);
|
|
103
|
+
});
|
|
104
|
+
it('refuses a floor rule', async () => {
|
|
105
|
+
const root = await scratch();
|
|
106
|
+
await expect(waive({
|
|
107
|
+
stateRoot: root,
|
|
108
|
+
ruleId: 'css/contrast',
|
|
109
|
+
path: 'src/app.css',
|
|
110
|
+
reason: 'The contrast is fine, I have looked at it.',
|
|
111
|
+
decidedBy: 'human',
|
|
112
|
+
})).rejects.toThrow('cannot be waived');
|
|
113
|
+
expect(await createWaiverStore(root).count()).toBe(0);
|
|
114
|
+
});
|
|
115
|
+
it('refuses a reason that is too short', async () => {
|
|
116
|
+
const root = await scratch();
|
|
117
|
+
await expect(waive({
|
|
118
|
+
stateRoot: root,
|
|
119
|
+
ruleId: 'css/no-transition-all',
|
|
120
|
+
path: 'src/app.css',
|
|
121
|
+
reason: 'because',
|
|
122
|
+
decidedBy: 'human',
|
|
123
|
+
})).rejects.toThrow('ten characters');
|
|
124
|
+
expect(await createWaiverStore(root).count()).toBe(0);
|
|
125
|
+
});
|
|
126
|
+
it('refuses a rule that does not exist', async () => {
|
|
127
|
+
const root = await scratch();
|
|
128
|
+
await expect(waive({
|
|
129
|
+
stateRoot: root,
|
|
130
|
+
ruleId: 'css/no-such-rule',
|
|
131
|
+
path: 'src/app.css',
|
|
132
|
+
reason: 'The file is a fixture, not a page.',
|
|
133
|
+
decidedBy: 'human',
|
|
134
|
+
})).rejects.toThrow('no rule is named');
|
|
135
|
+
expect(await createWaiverStore(root).count()).toBe(0);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=waivers.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waivers.test.js","sourceRoot":"","sources":["../../src/quality/waivers.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,EAET,WAAW,GACZ,MAAM,cAAc,CAAC;AAEtB,yCAAyC;AACzC,KAAK,UAAU,OAAO;IACpB,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,wCAAwC;AACxC,SAAS,OAAO,CAAC,OAAyB,EAAE;IAC1C,OAAO;QACL,MAAM,EAAE,uBAAuB;QAC/B,MAAM,EAAE,kBAAkB;QAC1B,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,EAAE;QACR,OAAO,EAAE,2CAA2C;QACpD,GAAG,EAAE,kDAAkD;QACvD,GAAG,IAAI;KACR,CAAC;AACJ,CAAC;AAED,yCAAyC;AACzC,SAAS,MAAM,CAAC,OAAwB,EAAE;IACxC,OAAO;QACL,MAAM,EAAE,uBAAuB;QAC/B,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE,oCAAoC;QAC5C,SAAS,EAAE,OAAO;QAClB,EAAE,EAAE,0BAA0B;QAC9B,GAAG,IAAI;KACR,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5C,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;QACtF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1B,MAAM,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;QACvD,MAAM,CAAC,MAAM,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC;YAC3B,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,uBAAuB;YAC/B,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,oCAAoC;YAC5C,SAAS,EAAE,OAAO;SACnB,CAAC,CAAC;QACH,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACtD,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,MAAM,MAAM,CACV,KAAK,CAAC;YACJ,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,cAAc;YACtB,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,4CAA4C;YACpD,SAAS,EAAE,OAAO;SACnB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,MAAM,MAAM,CACV,KAAK,CAAC;YACJ,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,uBAAuB;YAC/B,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,OAAO;SACnB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,MAAM,MAAM,CACV,KAAK,CAAC;YACJ,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,kBAAkB;YAC1B,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,oCAAoC;YAC5C,SAAS,EAAE,OAAO;SACnB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hook registry.
|
|
3
|
+
*
|
|
4
|
+
* A rule says what must hold; a moment says when it is checked. The
|
|
5
|
+
* registry holds the rules, puts them in the order they run, and runs the
|
|
6
|
+
* rules of one moment.
|
|
7
|
+
*
|
|
8
|
+
* `@agentsy/runtime` would provide this, but it is not on npm (verified
|
|
9
|
+
* 2026-10-27), so the registry lives here. It is small on purpose: an
|
|
10
|
+
* ordered list, a chain that stops, and the reasons it stopped.
|
|
11
|
+
*/
|
|
12
|
+
/** The moments a rule is checked at. */
|
|
13
|
+
export type HookEvent = 'UserPromptSubmit' | 'PreToolCall' | 'PostToolCall' | 'PreCompact' | 'SubagentStop' | 'PreResponse' | 'PostResponse' | 'ModelCall';
|
|
14
|
+
/**
|
|
15
|
+
* What a handler answers.
|
|
16
|
+
*
|
|
17
|
+
* `{ continue: true }` says the call may go on, `{ continue: false, reason }`
|
|
18
|
+
* stops it and says why, and `{ transform }` hands the caller something to
|
|
19
|
+
* apply to the call.
|
|
20
|
+
*/
|
|
21
|
+
export type HandlerResult = {
|
|
22
|
+
continue: true;
|
|
23
|
+
} | {
|
|
24
|
+
continue: false;
|
|
25
|
+
reason: string;
|
|
26
|
+
} | {
|
|
27
|
+
transform: unknown;
|
|
28
|
+
};
|
|
29
|
+
/** A rule: an id, the moment it is checked at, and the handler. */
|
|
30
|
+
export interface Rule {
|
|
31
|
+
/** The name the rule is known by. */
|
|
32
|
+
id: string;
|
|
33
|
+
/** The moment the rule is checked at. */
|
|
34
|
+
event: HookEvent;
|
|
35
|
+
/** A blocking rule runs before every other rule. */
|
|
36
|
+
block?: boolean;
|
|
37
|
+
/** The order among the rules of one kind; the higher number runs first. */
|
|
38
|
+
priority?: number;
|
|
39
|
+
/** The roles the rule applies to; a rule without roles applies to all. */
|
|
40
|
+
roles?: string[];
|
|
41
|
+
/** The check itself. */
|
|
42
|
+
handler: (event: unknown) => Promise<HandlerResult> | HandlerResult;
|
|
43
|
+
}
|
|
44
|
+
/** The priority a blocking rule runs at, so that it runs first. */
|
|
45
|
+
export declare const BLOCK_PRIORITY = 1000;
|
|
46
|
+
/** What one run of a moment's rules produced. */
|
|
47
|
+
export interface RunResult {
|
|
48
|
+
/** Whether the call may go on. */
|
|
49
|
+
continue: boolean;
|
|
50
|
+
/** Why the chain stopped, in the order the rules stopped it. */
|
|
51
|
+
reasons: string[];
|
|
52
|
+
/** What the handlers asked to change, in the order they asked. */
|
|
53
|
+
transformed: unknown[];
|
|
54
|
+
}
|
|
55
|
+
/** The registry: the rules, in the order they run. */
|
|
56
|
+
export interface HookRegistry {
|
|
57
|
+
/** Run the rules of one moment. */
|
|
58
|
+
run(event: HookEvent, input: unknown): Promise<RunResult>;
|
|
59
|
+
/** The rules in the order they run; one moment's rules when a moment is named. */
|
|
60
|
+
rules(event?: HookEvent): Rule[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The rules in the order they run.
|
|
64
|
+
*
|
|
65
|
+
* A blocking rule runs first, because a rule that stops a call is worth
|
|
66
|
+
* more than a rule that only notes something. Then the priority, highest
|
|
67
|
+
* first, and then the order the rules were written in, so two rules of the
|
|
68
|
+
* same priority keep the order a person gave them.
|
|
69
|
+
*/
|
|
70
|
+
export declare function orderRules(rules: readonly Rule[]): Rule[];
|
|
71
|
+
/**
|
|
72
|
+
* Run the rules of one moment.
|
|
73
|
+
*
|
|
74
|
+
* The chain stops at the first rule that stops it, and the reason is kept.
|
|
75
|
+
* The transforms are all returned, in order, because a transform is a
|
|
76
|
+
* change and a change is not a stop.
|
|
77
|
+
*/
|
|
78
|
+
export declare function run(event: HookEvent, rules: readonly Rule[], input: unknown): Promise<RunResult>;
|
|
79
|
+
/**
|
|
80
|
+
* The registry for a set of rules.
|
|
81
|
+
*
|
|
82
|
+
* The rules are ordered once, so a caller can read them in the order they
|
|
83
|
+
* run and a run does not reorder them again.
|
|
84
|
+
*/
|
|
85
|
+
export declare function createOaRegistry(rules: readonly Rule[]): HookRegistry;
|
|
86
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,wCAAwC;AACxC,MAAM,MAAM,SAAS,GACjB,kBAAkB,GAClB,aAAa,GACb,cAAc,GACd,YAAY,GACZ,cAAc,GACd,aAAa,GACb,cAAc,GACd,WAAW,CAAC;AAEhB;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GAClB;IAAE,QAAQ,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAE3B,mEAAmE;AACnE,MAAM,WAAW,IAAI;IACnB,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,yCAAyC;IACzC,KAAK,EAAE,SAAS,CAAC;IACjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,wBAAwB;IACxB,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC;CACrE;AAED,mEAAmE;AACnE,eAAO,MAAM,cAAc,OAAO,CAAC;AAEnC,iDAAiD;AACjD,MAAM,WAAW,SAAS;IACxB,kCAAkC;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,gEAAgE;IAChE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,kEAAkE;IAClE,WAAW,EAAE,OAAO,EAAE,CAAC;CACxB;AAED,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1D,kFAAkF;IAClF,KAAK,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,EAAE,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,IAAI,EAAE,CAYzD;AAeD;;;;;;GAMG;AACH,wBAAsB,GAAG,CACvB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,SAAS,CAAC,CAoBpB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,YAAY,CAOrE"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hook registry.
|
|
3
|
+
*
|
|
4
|
+
* A rule says what must hold; a moment says when it is checked. The
|
|
5
|
+
* registry holds the rules, puts them in the order they run, and runs the
|
|
6
|
+
* rules of one moment.
|
|
7
|
+
*
|
|
8
|
+
* `@agentsy/runtime` would provide this, but it is not on npm (verified
|
|
9
|
+
* 2026-10-27), so the registry lives here. It is small on purpose: an
|
|
10
|
+
* ordered list, a chain that stops, and the reasons it stopped.
|
|
11
|
+
*/
|
|
12
|
+
/** The priority a blocking rule runs at, so that it runs first. */
|
|
13
|
+
export const BLOCK_PRIORITY = 1000;
|
|
14
|
+
/**
|
|
15
|
+
* The rules in the order they run.
|
|
16
|
+
*
|
|
17
|
+
* A blocking rule runs first, because a rule that stops a call is worth
|
|
18
|
+
* more than a rule that only notes something. Then the priority, highest
|
|
19
|
+
* first, and then the order the rules were written in, so two rules of the
|
|
20
|
+
* same priority keep the order a person gave them.
|
|
21
|
+
*/
|
|
22
|
+
export function orderRules(rules) {
|
|
23
|
+
return rules
|
|
24
|
+
.map((rule, index) => ({ rule, index }))
|
|
25
|
+
.sort((a, b) => {
|
|
26
|
+
const aBlock = a.rule.block === true;
|
|
27
|
+
const bBlock = b.rule.block === true;
|
|
28
|
+
if (aBlock !== bBlock)
|
|
29
|
+
return aBlock ? -1 : 1;
|
|
30
|
+
const priority = (b.rule.priority ?? 0) - (a.rule.priority ?? 0);
|
|
31
|
+
if (priority !== 0)
|
|
32
|
+
return priority;
|
|
33
|
+
return a.index - b.index;
|
|
34
|
+
})
|
|
35
|
+
.map((entry) => entry.rule);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The role a call is made for.
|
|
39
|
+
*
|
|
40
|
+
* A rule can be scoped to a role, and the event carries the role. An event
|
|
41
|
+
* with no role runs no scoped rule: a rule that applies to one role cannot
|
|
42
|
+
* apply to an unknown one.
|
|
43
|
+
*/
|
|
44
|
+
function roleOf(input) {
|
|
45
|
+
if (typeof input !== 'object' || input === null)
|
|
46
|
+
return undefined;
|
|
47
|
+
const role = input.role;
|
|
48
|
+
return typeof role === 'string' ? role : undefined;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Run the rules of one moment.
|
|
52
|
+
*
|
|
53
|
+
* The chain stops at the first rule that stops it, and the reason is kept.
|
|
54
|
+
* The transforms are all returned, in order, because a transform is a
|
|
55
|
+
* change and a change is not a stop.
|
|
56
|
+
*/
|
|
57
|
+
export async function run(event, rules, input) {
|
|
58
|
+
const reasons = [];
|
|
59
|
+
const transformed = [];
|
|
60
|
+
const role = roleOf(input);
|
|
61
|
+
for (const rule of orderRules(rules)) {
|
|
62
|
+
if (rule.event !== event)
|
|
63
|
+
continue;
|
|
64
|
+
if (rule.roles !== undefined && (role === undefined || !rule.roles.includes(role))) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const result = await rule.handler(input);
|
|
68
|
+
if ('transform' in result) {
|
|
69
|
+
transformed.push(result.transform);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (result.continue === false) {
|
|
73
|
+
reasons.push(result.reason);
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return { continue: reasons.length === 0, reasons, transformed };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The registry for a set of rules.
|
|
81
|
+
*
|
|
82
|
+
* The rules are ordered once, so a caller can read them in the order they
|
|
83
|
+
* run and a run does not reorder them again.
|
|
84
|
+
*/
|
|
85
|
+
export function createOaRegistry(rules) {
|
|
86
|
+
const ordered = orderRules(rules);
|
|
87
|
+
return {
|
|
88
|
+
run: (event, input) => run(event, ordered, input),
|
|
89
|
+
rules: (event) => event === undefined ? ordered : ordered.filter((rule) => rule.event === event),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.test.d.ts","sourceRoot":"","sources":["../src/registry.test.ts"],"names":[],"mappings":""}
|