@oussamadouhou/agent-enforcement 0.1.2
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/.claude-plugin/plugin.json +5 -0
- package/README.md +67 -0
- package/dist/adapters/logger.d.ts +23 -0
- package/dist/adapters/logger.d.ts.map +1 -0
- package/dist/adapters/logger.js +58 -0
- package/dist/adapters/logger.js.map +1 -0
- package/dist/adapters/message-reader.d.ts +20 -0
- package/dist/adapters/message-reader.d.ts.map +1 -0
- package/dist/adapters/message-reader.js +123 -0
- package/dist/adapters/message-reader.js.map +1 -0
- package/dist/constants.d.ts +22 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +50 -0
- package/dist/constants.js.map +1 -0
- package/dist/detection/environment.d.ts +7 -0
- package/dist/detection/environment.d.ts.map +1 -0
- package/dist/detection/environment.js +30 -0
- package/dist/detection/environment.js.map +1 -0
- package/dist/hook.d.ts +35 -0
- package/dist/hook.d.ts.map +1 -0
- package/dist/hook.js +223 -0
- package/dist/hook.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +6 -0
- package/dist/plugin.js.map +1 -0
- package/dist/schema/verification-schema.d.ts +127 -0
- package/dist/schema/verification-schema.d.ts.map +1 -0
- package/dist/schema/verification-schema.js +132 -0
- package/dist/schema/verification-schema.js.map +1 -0
- package/docs/EVIDENCE_SYSTEM.md +214 -0
- package/fixtures/claude/project-abc/session-123.jsonl +2 -0
- package/fixtures/opencode/messages/session-123/msg_001.json +4 -0
- package/hooks/enforcement.py +255 -0
- package/hooks/hooks.json +15 -0
- package/package.json +70 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @oussamadouhou/agent-enforcement
|
|
2
|
+
|
|
3
|
+
Evidence enforcement hooks for OpenCode and Claude Code. This package blocks or warns when `todowrite` tasks are marked complete without the required evidence block, checklist, and trust markers.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @oussamadouhou/agent-enforcement
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## OpenCode usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import type { Plugin } from "@opencode-ai/plugin"
|
|
15
|
+
import { createEvidenceEnforcementHook } from "@oussamadouhou/agent-enforcement"
|
|
16
|
+
|
|
17
|
+
const AgentEnforcementPlugin: Plugin = async ctx => {
|
|
18
|
+
return createEvidenceEnforcementHook(ctx)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default AgentEnforcementPlugin
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Claude Code usage
|
|
25
|
+
|
|
26
|
+
Copy the plugin to your Claude Code plugins directory and enable `hooks/enforcement.py`:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cp -r . ~/.claude/plugins/agent-enforcement
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Then ensure `hooks/hooks.json` is configured in your Claude settings.
|
|
33
|
+
|
|
34
|
+
## Configuration
|
|
35
|
+
|
|
36
|
+
- `OPENCODE_ENFORCEMENT_LEVEL` or `ENFORCEMENT_LEVEL`: `0` (creative), `1` (standard), `2` (strict)
|
|
37
|
+
- `ENFORCEMENT_LOG_MODE`: `file` | `console` | `silent`
|
|
38
|
+
- `ENFORCEMENT_LOG_PATH`: file path for logs
|
|
39
|
+
- `ENFORCEMENT_LOG_LEVEL`: `debug` | `info` | `warn` | `error`
|
|
40
|
+
|
|
41
|
+
## Evidence format
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
**Evidence for task-1**:
|
|
45
|
+
|
|
46
|
+
**Execution**:
|
|
47
|
+
- Tool: read
|
|
48
|
+
|
|
49
|
+
**Verification**:
|
|
50
|
+
- Checked output
|
|
51
|
+
|
|
52
|
+
**Checklist**:
|
|
53
|
+
- [x] Tool executed successfully
|
|
54
|
+
- [x] Output captured
|
|
55
|
+
- [x] Result matches expected
|
|
56
|
+
- [x] No workarounds used
|
|
57
|
+
- [x] Independently verifiable
|
|
58
|
+
|
|
59
|
+
**Trust**: 🟢 HIGH | ✅ Ground Truth
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Development
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
bun test
|
|
66
|
+
bun run build
|
|
67
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface Logger {
|
|
2
|
+
info(msg: string): void;
|
|
3
|
+
warn(msg: string): void;
|
|
4
|
+
error(msg: string): void;
|
|
5
|
+
debug(msg: string): void;
|
|
6
|
+
}
|
|
7
|
+
export interface LogConfig {
|
|
8
|
+
mode: "file" | "console" | "silent";
|
|
9
|
+
path?: string;
|
|
10
|
+
level?: "debug" | "info" | "warn" | "error";
|
|
11
|
+
}
|
|
12
|
+
export declare function getLogConfig(): LogConfig;
|
|
13
|
+
export declare class DefaultLogger implements Logger {
|
|
14
|
+
private config;
|
|
15
|
+
constructor(config?: LogConfig);
|
|
16
|
+
private shouldLog;
|
|
17
|
+
private log;
|
|
18
|
+
info(msg: string): void;
|
|
19
|
+
warn(msg: string): void;
|
|
20
|
+
error(msg: string): void;
|
|
21
|
+
debug(msg: string): void;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/adapters/logger.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAA;IACnC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;CAC5C;AASD,wBAAgB,YAAY,IAAI,SAAS,CAMxC;AAED,qBAAa,aAAc,YAAW,MAAM;IAC1C,OAAO,CAAC,MAAM,CAAW;gBAEb,MAAM,CAAC,EAAE,SAAS;IAI9B,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,GAAG;IAiBX,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIvB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIvB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAGzB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { appendFileSync } from "node:fs";
|
|
2
|
+
const LOG_LEVELS = {
|
|
3
|
+
debug: 10,
|
|
4
|
+
info: 20,
|
|
5
|
+
warn: 30,
|
|
6
|
+
error: 40,
|
|
7
|
+
};
|
|
8
|
+
export function getLogConfig() {
|
|
9
|
+
return {
|
|
10
|
+
mode: process.env.ENFORCEMENT_LOG_MODE || "file",
|
|
11
|
+
path: process.env.ENFORCEMENT_LOG_PATH || "/tmp/agent-enforcement.log",
|
|
12
|
+
level: process.env.ENFORCEMENT_LOG_LEVEL || "info",
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export class DefaultLogger {
|
|
16
|
+
config;
|
|
17
|
+
constructor(config) {
|
|
18
|
+
this.config = config ?? getLogConfig();
|
|
19
|
+
}
|
|
20
|
+
shouldLog(level) {
|
|
21
|
+
if (this.config.mode === "silent") {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const minLevel = this.config.level ?? "info";
|
|
25
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[minLevel];
|
|
26
|
+
}
|
|
27
|
+
log(level, msg) {
|
|
28
|
+
if (!this.shouldLog(level)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const timestamp = new Date().toISOString();
|
|
32
|
+
const formatted = `[${timestamp}] [${level.toUpperCase()}] ${msg}`;
|
|
33
|
+
if (this.config.mode === "file") {
|
|
34
|
+
try {
|
|
35
|
+
appendFileSync(this.config.path ?? "/tmp/agent-enforcement.log", `${formatted}\n`);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else if (this.config.mode === "console") {
|
|
42
|
+
console.log(formatted);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
info(msg) {
|
|
46
|
+
this.log("info", msg);
|
|
47
|
+
}
|
|
48
|
+
warn(msg) {
|
|
49
|
+
this.log("warn", msg);
|
|
50
|
+
}
|
|
51
|
+
error(msg) {
|
|
52
|
+
this.log("error", msg);
|
|
53
|
+
}
|
|
54
|
+
debug(msg) {
|
|
55
|
+
this.log("debug", msg);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/adapters/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAexC,MAAM,UAAU,GAAoD;IAClE,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,EAAE;CACV,CAAA;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO;QACL,IAAI,EAAG,OAAO,CAAC,GAAG,CAAC,oBAA0C,IAAI,MAAM;QACvE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,4BAA4B;QACtE,KAAK,EAAG,OAAO,CAAC,GAAG,CAAC,qBAA4C,IAAI,MAAM;KAC3E,CAAA;AACH,CAAC;AAED,MAAM,OAAO,aAAa;IAChB,MAAM,CAAW;IAEzB,YAAY,MAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,YAAY,EAAE,CAAA;IACxC,CAAC;IAEO,SAAS,CAAC,KAAsC;QACtD,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,KAAK,CAAA;QACd,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAA;QAC5C,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAA;IAClD,CAAC;IAEO,GAAG,CAAC,KAAsC,EAAE,GAAW;QAC7D,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAM;QACR,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QAC1C,MAAM,SAAS,GAAG,IAAI,SAAS,MAAM,KAAK,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAA;QAClE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,4BAA4B,EAAE,GAAG,SAAS,IAAI,CAAC,CAAA;YACpF,CAAC;YAAC,MAAM,CAAC;gBACP,OAAM;YACR,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAW;QACd,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACvB,CAAC;IAED,IAAI,CAAC,GAAW;QACd,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,GAAW;QACf,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IACxB,CAAC;IAED,KAAK,CAAC,GAAW;QACf,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Logger } from "./logger";
|
|
2
|
+
export interface MessageReader {
|
|
3
|
+
getLastAssistantMessage(sessionID: string): string | null;
|
|
4
|
+
}
|
|
5
|
+
export declare class OpenCodeMessageReader implements MessageReader {
|
|
6
|
+
private storagePath;
|
|
7
|
+
private logger?;
|
|
8
|
+
constructor(storagePath?: string, logger?: Logger);
|
|
9
|
+
private getMessageDir;
|
|
10
|
+
getLastAssistantMessage(sessionID: string): string | null;
|
|
11
|
+
}
|
|
12
|
+
export declare class ClaudeCodeMessageReader implements MessageReader {
|
|
13
|
+
private projectPath;
|
|
14
|
+
private logger?;
|
|
15
|
+
constructor(projectPath?: string, logger?: Logger);
|
|
16
|
+
private detectProjectPath;
|
|
17
|
+
getLastAssistantMessage(sessionID: string): string | null;
|
|
18
|
+
private extractText;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=message-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-reader.d.ts","sourceRoot":"","sources":["../../src/adapters/message-reader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEtC,MAAM,WAAW,aAAa;IAC5B,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAC1D;AAED,qBAAa,qBAAsB,YAAW,aAAa;IACzD,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,MAAM,CAAC,CAAQ;gBAEX,WAAW,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAQjD,OAAO,CAAC,aAAa;IAoBrB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAwB1D;AAED,qBAAa,uBAAwB,YAAW,aAAa;IAC3D,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,MAAM,CAAC,CAAQ;gBAEX,WAAW,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAKjD,OAAO,CAAC,iBAAiB;IAuBzB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA2BzD,OAAO,CAAC,WAAW;CAsBpB"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
export class OpenCodeMessageReader {
|
|
5
|
+
storagePath;
|
|
6
|
+
logger;
|
|
7
|
+
constructor(storagePath, logger) {
|
|
8
|
+
this.storagePath =
|
|
9
|
+
storagePath ??
|
|
10
|
+
process.env.OPENCODE_MESSAGE_STORAGE ??
|
|
11
|
+
join(os.homedir(), ".local/share/opencode/storage/message");
|
|
12
|
+
this.logger = logger;
|
|
13
|
+
}
|
|
14
|
+
getMessageDir(sessionID) {
|
|
15
|
+
if (!existsSync(this.storagePath)) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const directPath = join(this.storagePath, sessionID);
|
|
19
|
+
if (existsSync(directPath)) {
|
|
20
|
+
return directPath;
|
|
21
|
+
}
|
|
22
|
+
for (const dir of readdirSync(this.storagePath)) {
|
|
23
|
+
const sessionPath = join(this.storagePath, dir, sessionID);
|
|
24
|
+
if (existsSync(sessionPath)) {
|
|
25
|
+
return sessionPath;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
getLastAssistantMessage(sessionID) {
|
|
31
|
+
const messageDir = this.getMessageDir(sessionID);
|
|
32
|
+
if (!messageDir) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const files = readdirSync(messageDir)
|
|
37
|
+
.filter(file => file.endsWith(".json"))
|
|
38
|
+
.sort()
|
|
39
|
+
.reverse();
|
|
40
|
+
for (const file of files) {
|
|
41
|
+
const content = JSON.parse(readFileSync(join(messageDir, file), "utf-8"));
|
|
42
|
+
if (content.role === "assistant" && typeof content.text === "string") {
|
|
43
|
+
return content.text;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
this.logger?.warn(`Failed to read message files for ${sessionID}: ${String(error)}`);
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export class ClaudeCodeMessageReader {
|
|
54
|
+
projectPath;
|
|
55
|
+
logger;
|
|
56
|
+
constructor(projectPath, logger) {
|
|
57
|
+
this.projectPath = projectPath ?? this.detectProjectPath();
|
|
58
|
+
this.logger = logger;
|
|
59
|
+
}
|
|
60
|
+
detectProjectPath() {
|
|
61
|
+
const projectsPath = join(os.homedir(), ".claude/projects");
|
|
62
|
+
if (!existsSync(projectsPath)) {
|
|
63
|
+
return process.cwd();
|
|
64
|
+
}
|
|
65
|
+
const projects = readdirSync(projectsPath).filter(project => existsSync(join(projectsPath, project, "settings.json")));
|
|
66
|
+
if (projects.length === 0) {
|
|
67
|
+
return process.cwd();
|
|
68
|
+
}
|
|
69
|
+
const sorted = projects.sort((a, b) => {
|
|
70
|
+
const statA = statSync(join(projectsPath, a)).mtimeMs;
|
|
71
|
+
const statB = statSync(join(projectsPath, b)).mtimeMs;
|
|
72
|
+
return statB - statA;
|
|
73
|
+
});
|
|
74
|
+
return join(projectsPath, sorted[0]);
|
|
75
|
+
}
|
|
76
|
+
getLastAssistantMessage(sessionID) {
|
|
77
|
+
const sessionFile = join(this.projectPath, `${sessionID}.jsonl`);
|
|
78
|
+
if (!existsSync(sessionFile)) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const content = readFileSync(sessionFile, "utf-8");
|
|
83
|
+
const lines = content.trim().split("\n");
|
|
84
|
+
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
85
|
+
try {
|
|
86
|
+
const message = JSON.parse(lines[i]);
|
|
87
|
+
if (message.role === "assistant") {
|
|
88
|
+
const text = this.extractText(message);
|
|
89
|
+
return text ?? lines[i];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
this.logger?.warn(`Failed to read Claude Code session ${sessionID}: ${String(error)}`);
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
extractText(message) {
|
|
103
|
+
const text = message.text;
|
|
104
|
+
if (typeof text === "string") {
|
|
105
|
+
return text;
|
|
106
|
+
}
|
|
107
|
+
const content = message.content;
|
|
108
|
+
if (Array.isArray(content)) {
|
|
109
|
+
for (const part of content) {
|
|
110
|
+
if (part &&
|
|
111
|
+
typeof part === "object" &&
|
|
112
|
+
part.type === "text") {
|
|
113
|
+
const textPart = part.text;
|
|
114
|
+
if (typeof textPart === "string") {
|
|
115
|
+
return textPart;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=message-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-reader.js","sourceRoot":"","sources":["../../src/adapters/message-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const HOOK_NAME = "evidence-enforcement";
|
|
2
|
+
export declare const ENFORCEMENT_LEVELS: {
|
|
3
|
+
readonly CREATIVE: 0;
|
|
4
|
+
readonly STANDARD: 1;
|
|
5
|
+
readonly STRICT: 2;
|
|
6
|
+
};
|
|
7
|
+
export type EnforcementLevel = typeof ENFORCEMENT_LEVELS[keyof typeof ENFORCEMENT_LEVELS];
|
|
8
|
+
export declare const EVIDENCE_PATTERNS: {
|
|
9
|
+
EVIDENCE_BLOCK: RegExp;
|
|
10
|
+
EXECUTION_SECTION: RegExp;
|
|
11
|
+
VERIFICATION_SECTION: RegExp;
|
|
12
|
+
CHECKLIST_SECTION: RegExp;
|
|
13
|
+
TRUST_MARKERS: RegExp;
|
|
14
|
+
CHECKLIST_ITEM: RegExp;
|
|
15
|
+
};
|
|
16
|
+
export declare const REQUIRED_CHECKLIST_ITEMS: string[];
|
|
17
|
+
export declare const ERROR_MESSAGES: {
|
|
18
|
+
NO_EVIDENCE_BLOCK: (level: EnforcementLevel) => string;
|
|
19
|
+
INCOMPLETE_CHECKLIST: (missingItems: string[], level: EnforcementLevel) => string;
|
|
20
|
+
NO_TRUST_MARKERS: (level: EnforcementLevel) => string;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,yBAAyB,CAAA;AAE/C,eAAO,MAAM,kBAAkB;;;;CAIrB,CAAA;AAEV,MAAM,MAAM,gBAAgB,GAAG,OAAO,kBAAkB,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAA;AAEzF,eAAO,MAAM,iBAAiB;;;;;;;CAO7B,CAAA;AAED,eAAO,MAAM,wBAAwB,UAMpC,CAAA;AAID,eAAO,MAAM,cAAc;+BACE,gBAAgB;yCAgBN,MAAM,EAAE,SAAS,gBAAgB;8BAO5C,gBAAgB;CAO3C,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export const HOOK_NAME = "evidence-enforcement";
|
|
2
|
+
export const ENFORCEMENT_LEVELS = {
|
|
3
|
+
CREATIVE: 0,
|
|
4
|
+
STANDARD: 1,
|
|
5
|
+
STRICT: 2,
|
|
6
|
+
};
|
|
7
|
+
export const EVIDENCE_PATTERNS = {
|
|
8
|
+
EVIDENCE_BLOCK: /\*\*Evidence(?:\s+for\s+[\w-]+)?\*\*:/i,
|
|
9
|
+
EXECUTION_SECTION: /\*\*Execution\*\*:/i,
|
|
10
|
+
VERIFICATION_SECTION: /\*\*Verification\*\*:/i,
|
|
11
|
+
CHECKLIST_SECTION: /\*\*Checklist\*\*:/i,
|
|
12
|
+
TRUST_MARKERS: /\*\*(?:Confidence|Trust)\*\*:/i,
|
|
13
|
+
CHECKLIST_ITEM: /\[\s*[xX]\s*\]/,
|
|
14
|
+
};
|
|
15
|
+
export const REQUIRED_CHECKLIST_ITEMS = [
|
|
16
|
+
"Tool executed",
|
|
17
|
+
"Output captured",
|
|
18
|
+
"Result matches",
|
|
19
|
+
"No workarounds",
|
|
20
|
+
"Independently verifiable",
|
|
21
|
+
];
|
|
22
|
+
const DOCS_PATH = "~/.config/opencode/plugins/agent-enforcement/docs/EVIDENCE_SYSTEM.md";
|
|
23
|
+
export const ERROR_MESSAGES = {
|
|
24
|
+
NO_EVIDENCE_BLOCK: (level) => `[${HOOK_NAME}] ${level === ENFORCEMENT_LEVELS.STRICT ? "BLOCKED" : "WARNING"}: ` +
|
|
25
|
+
"Cannot mark todo complete without evidence block.\n\n" +
|
|
26
|
+
"Required format:\n" +
|
|
27
|
+
"**Evidence for [todo-id]**:\n" +
|
|
28
|
+
"**Execution**: [command/tool used]\n" +
|
|
29
|
+
"**Verification**: [what was checked]\n" +
|
|
30
|
+
"**Checklist**:\n" +
|
|
31
|
+
"- [x] Tool executed successfully\n" +
|
|
32
|
+
"- [x] Output captured\n" +
|
|
33
|
+
"- [x] Result matches expected\n" +
|
|
34
|
+
"- [x] No workarounds used\n" +
|
|
35
|
+
"- [x] Independently verifiable\n" +
|
|
36
|
+
"**Trust**: 🟢 HIGH | ✅ Ground Truth\n\n" +
|
|
37
|
+
`See ${DOCS_PATH} for full documentation.`,
|
|
38
|
+
INCOMPLETE_CHECKLIST: (missingItems, level) => `[${HOOK_NAME}] ${level === ENFORCEMENT_LEVELS.STRICT ? "BLOCKED" : "WARNING"}: ` +
|
|
39
|
+
"Evidence checklist incomplete.\n\n" +
|
|
40
|
+
`Missing checklist items:\n${missingItems.map(item => `- [ ] ${item}`).join("\n")}\n\n` +
|
|
41
|
+
`All items must be checked [x] before marking todo complete.\n\n` +
|
|
42
|
+
`See ${DOCS_PATH} for checklist requirements.`,
|
|
43
|
+
NO_TRUST_MARKERS: (level) => `[${HOOK_NAME}] ${level === ENFORCEMENT_LEVELS.STRICT ? "BLOCKED" : "WARNING"}: ` +
|
|
44
|
+
"Trust markers missing.\n\n" +
|
|
45
|
+
"Required:\n" +
|
|
46
|
+
"**Confidence**: 🟢 HIGH | 🟡 MEDIUM | 🔴 LOW\n" +
|
|
47
|
+
"**Evidence**: ✅ Ground Truth | ⚠️ Simulation | ❌ Assumption\n\n" +
|
|
48
|
+
`See ${DOCS_PATH} for trust marker details.`,
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,sBAAsB,CAAA;AAE/C,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,QAAQ,EAAE,CAAC;IACX,QAAQ,EAAE,CAAC;IACX,MAAM,EAAE,CAAC;CACD,CAAA;AAIV,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,cAAc,EAAE,wCAAwC;IACxD,iBAAiB,EAAE,qBAAqB;IACxC,oBAAoB,EAAE,wBAAwB;IAC9C,iBAAiB,EAAE,qBAAqB;IACxC,aAAa,EAAE,gCAAgC;IAC/C,cAAc,EAAE,gBAAgB;CACjC,CAAA;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,eAAe;IACf,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB;IAChB,0BAA0B;CAC3B,CAAA;AAED,MAAM,SAAS,GAAG,sEAAsE,CAAA;AAExF,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,iBAAiB,EAAE,CAAC,KAAuB,EAAE,EAAE,CAC7C,IAAI,SAAS,KAAK,KAAK,KAAK,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,IAAI;QACjF,uDAAuD;QACvD,oBAAoB;QACpB,+BAA+B;QAC/B,sCAAsC;QACtC,wCAAwC;QACxC,kBAAkB;QAClB,oCAAoC;QACpC,yBAAyB;QACzB,iCAAiC;QACjC,6BAA6B;QAC7B,kCAAkC;QAClC,yCAAyC;QACzC,OAAO,SAAS,0BAA0B;IAE5C,oBAAoB,EAAE,CAAC,YAAsB,EAAE,KAAuB,EAAE,EAAE,CACxE,IAAI,SAAS,KAAK,KAAK,KAAK,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,IAAI;QACjF,oCAAoC;QACpC,6BAA6B,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;QACvF,iEAAiE;QACjE,OAAO,SAAS,8BAA8B;IAEhD,gBAAgB,EAAE,CAAC,KAAuB,EAAE,EAAE,CAC5C,IAAI,SAAS,KAAK,KAAK,KAAK,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,IAAI;QACjF,4BAA4B;QAC5B,aAAa;QACb,gDAAgD;QAChD,iEAAiE;QACjE,OAAO,SAAS,4BAA4B;CAC/C,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type EnvironmentType = "claude-code" | "opencode";
|
|
2
|
+
export interface EnvironmentDetection {
|
|
3
|
+
type: EnvironmentType;
|
|
4
|
+
hasOhMyOpenCode: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function detectEnvironment(directory?: string): EnvironmentDetection;
|
|
7
|
+
//# sourceMappingURL=environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/detection/environment.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,UAAU,CAAA;AAExD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,eAAe,CAAA;IACrB,eAAe,EAAE,OAAO,CAAA;CACzB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,MAAsB,GAAG,oBAAoB,CAOzF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
export function detectEnvironment(directory = process.cwd()) {
|
|
5
|
+
if (process.env.CLAUDE_PLUGIN_ROOT) {
|
|
6
|
+
return { type: "claude-code", hasOhMyOpenCode: false };
|
|
7
|
+
}
|
|
8
|
+
const hasOhMyOpenCode = checkForOhMyOpenCode(directory);
|
|
9
|
+
return { type: "opencode", hasOhMyOpenCode };
|
|
10
|
+
}
|
|
11
|
+
function checkForOhMyOpenCode(directory) {
|
|
12
|
+
const configPaths = [
|
|
13
|
+
join(directory, "opencode.json"),
|
|
14
|
+
join(directory, "opencode.jsonc"),
|
|
15
|
+
join(os.homedir(), ".config/opencode.json"),
|
|
16
|
+
];
|
|
17
|
+
return configPaths.some(configPath => {
|
|
18
|
+
if (!existsSync(configPath)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const content = readFileSync(configPath, "utf-8");
|
|
23
|
+
return content.includes("disabled_hooks") || content.includes("oh-my-opencode");
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=environment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/detection/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,MAAM,SAAS,CAAA;AASxB,MAAM,UAAU,iBAAiB,CAAC,YAAoB,OAAO,CAAC,GAAG,EAAE;IACjE,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;QACnC,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,eAAe,EAAE,KAAK,EAAE,CAAA;IACxD,CAAC;IAED,MAAM,eAAe,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAA;IACvD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,CAAA;AAC9C,CAAC;AAED,SAAS,oBAAoB,CAAC,SAAiB;IAC7C,MAAM,WAAW,GAAG;QAClB,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC;QAChC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC;QACjC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,uBAAuB,CAAC;KAC5C,CAAA;IAED,OAAO,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;QACnC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;YACjD,OAAO,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAA;QACjF,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
package/dist/hook.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { PluginInput } from "@opencode-ai/plugin";
|
|
2
|
+
import { type EnforcementLevel } from "./constants";
|
|
3
|
+
import { type Logger } from "./adapters/logger";
|
|
4
|
+
import { type MessageReader } from "./adapters/message-reader";
|
|
5
|
+
export interface EnforcementOptions {
|
|
6
|
+
level?: EnforcementLevel;
|
|
7
|
+
logger?: Logger;
|
|
8
|
+
messageReader?: MessageReader;
|
|
9
|
+
messageStoragePath?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function createEvidenceEnforcementHook(ctx: PluginInput, options?: EnforcementOptions): {
|
|
12
|
+
event: ({ event }: {
|
|
13
|
+
event: {
|
|
14
|
+
type: string;
|
|
15
|
+
properties?: any;
|
|
16
|
+
};
|
|
17
|
+
}) => Promise<void>;
|
|
18
|
+
"tool.execute.before": (input: {
|
|
19
|
+
tool: string;
|
|
20
|
+
sessionID: string;
|
|
21
|
+
callID: string;
|
|
22
|
+
}, output: {
|
|
23
|
+
args: Record<string, unknown>;
|
|
24
|
+
}) => Promise<void>;
|
|
25
|
+
"tool.execute.after": (input: {
|
|
26
|
+
tool: string;
|
|
27
|
+
sessionID: string;
|
|
28
|
+
callID: string;
|
|
29
|
+
}, output: {
|
|
30
|
+
title: string;
|
|
31
|
+
output: string;
|
|
32
|
+
metadata: unknown;
|
|
33
|
+
}) => Promise<void>;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAEL,KAAK,gBAAgB,EAKtB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,2BAA2B,CAAA;AAclC,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,gBAAgB,CAAA;IACxB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,WAAW,EAChB,OAAO,GAAE,kBAAuB;uBAcL;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,UAAU,CAAC,EAAE,GAAG,CAAA;SAAE,CAAA;KAAE,KAAG,OAAO,CAAC,IAAI,CAAC;mCA0B7E;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,UAClD;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,KACxC,OAAO,CAAC,IAAI,CAAC;kCAuFP;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,UAClD;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,KAC3D,OAAO,CAAC,IAAI,CAAC;EAmCnB"}
|