@dougharness/codex 1.0.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 +21 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +44 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +20 -0
- package/dist/cli.js +108 -0
- package/dist/cli.js.map +1 -0
- package/dist/contract.d.ts +54 -0
- package/dist/contract.js +305 -0
- package/dist/contract.js.map +1 -0
- package/dist/git.d.ts +14 -0
- package/dist/git.js +36 -0
- package/dist/git.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/parse.d.ts +21 -0
- package/dist/parse.js +115 -0
- package/dist/parse.js.map +1 -0
- package/dist/prompt.d.ts +14 -0
- package/dist/prompt.js +62 -0
- package/dist/prompt.js.map +1 -0
- package/dist/run.d.ts +65 -0
- package/dist/run.js +195 -0
- package/dist/run.js.map +1 -0
- package/dist/schema.d.ts +174 -0
- package/dist/schema.js +84 -0
- package/dist/schema.js.map +1 -0
- package/package.json +24 -0
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
export declare const SEVERITIES: readonly ["blocker", "major", "minor"];
|
|
2
|
+
export type Severity = (typeof SEVERITIES)[number];
|
|
3
|
+
export declare const VERDICTS: readonly ["pass", "fail", "inconclusive"];
|
|
4
|
+
export type Verdict = (typeof VERDICTS)[number];
|
|
5
|
+
export interface ReviewIssue {
|
|
6
|
+
severity: Severity;
|
|
7
|
+
file: string;
|
|
8
|
+
line?: number;
|
|
9
|
+
description: string;
|
|
10
|
+
/** What the reviewer ran or read that shows the problem. */
|
|
11
|
+
evidence?: string;
|
|
12
|
+
}
|
|
13
|
+
/** What the model is asked to return. Everything else in ReviewResult is measured by the adapter. */
|
|
14
|
+
export interface ModelReview {
|
|
15
|
+
verdict: Verdict;
|
|
16
|
+
summary: string;
|
|
17
|
+
issues: ReviewIssue[];
|
|
18
|
+
}
|
|
19
|
+
/** What a worker (or reviewer) hands back when it stops partway through, at the harness's direction. */
|
|
20
|
+
export interface Handoff {
|
|
21
|
+
completed: string[];
|
|
22
|
+
remaining: string[];
|
|
23
|
+
next: string;
|
|
24
|
+
verify: string;
|
|
25
|
+
}
|
|
26
|
+
export interface CommandRun {
|
|
27
|
+
command: string;
|
|
28
|
+
/** Exit status as reported by the Codex event stream. null if it never completed. */
|
|
29
|
+
exitCode: number | null;
|
|
30
|
+
ok: boolean;
|
|
31
|
+
outputTail?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ReviewResult {
|
|
34
|
+
/**
|
|
35
|
+
* Same as the model's verdict when the review ran; "inconclusive" for every failure mode. The adapter
|
|
36
|
+
* turns a `fail` into `pass` when every blocker was downgraded under R12 (see `downgraded`); a `fail`
|
|
37
|
+
* with nothing downgraded is left alone.
|
|
38
|
+
*/
|
|
39
|
+
verdict: Verdict;
|
|
40
|
+
summary: string;
|
|
41
|
+
issues: ReviewIssue[];
|
|
42
|
+
/** Commands Codex actually executed, with the exit codes it observed. Never from the model's prose. */
|
|
43
|
+
commandsRun: CommandRun[];
|
|
44
|
+
/** Files in base...head as computed by git, so the reviewer's scope claims can be checked. */
|
|
45
|
+
changedFiles: string[];
|
|
46
|
+
base: string;
|
|
47
|
+
head: string;
|
|
48
|
+
dir: string;
|
|
49
|
+
reviewer: "codex";
|
|
50
|
+
model: string | null;
|
|
51
|
+
sandbox: Sandbox;
|
|
52
|
+
/** null when the review completed; otherwise why it did not. */
|
|
53
|
+
error: ReviewError | null;
|
|
54
|
+
codexExitCode: number | null;
|
|
55
|
+
durationMs: number;
|
|
56
|
+
usage: {
|
|
57
|
+
inputTokens: number;
|
|
58
|
+
outputTokens: number;
|
|
59
|
+
} | null;
|
|
60
|
+
/**
|
|
61
|
+
* The nesting guard: `name` is the environment variable the adapter sets on the worker it spawns
|
|
62
|
+
* (`DOUG_CODEX_REVIEW`); `passed` is true once the adapter attempted to spawn codex with the marker
|
|
63
|
+
* in its environment; `inherited` is true when the adapter's own process environment already had
|
|
64
|
+
* the variable set to a non-empty value (this review is running inside another codex-review).
|
|
65
|
+
*/
|
|
66
|
+
marker: {
|
|
67
|
+
name: string;
|
|
68
|
+
passed: boolean;
|
|
69
|
+
inherited: boolean;
|
|
70
|
+
};
|
|
71
|
+
/** True when the worker stopped at a boundary rather than finishing (R13); absent or false otherwise. */
|
|
72
|
+
partial?: boolean;
|
|
73
|
+
/** Present when partial is true: what a fresh worker needs to pick the remaining work up (R13). */
|
|
74
|
+
handoff?: Handoff;
|
|
75
|
+
/**
|
|
76
|
+
* Present only when `enforceBlockerEvidence` (contract.ts) downgraded at least one blocker for lacking
|
|
77
|
+
* R12 evidence: `index` into `issues` (now `major`) and the reason it was downgraded.
|
|
78
|
+
*/
|
|
79
|
+
downgraded?: {
|
|
80
|
+
index: number;
|
|
81
|
+
reason: string;
|
|
82
|
+
}[];
|
|
83
|
+
}
|
|
84
|
+
export type ReviewError = {
|
|
85
|
+
kind: "codex-not-found";
|
|
86
|
+
message: string;
|
|
87
|
+
} | {
|
|
88
|
+
kind: "codex-failed";
|
|
89
|
+
message: string;
|
|
90
|
+
stderrTail: string;
|
|
91
|
+
} | {
|
|
92
|
+
kind: "timeout";
|
|
93
|
+
message: string;
|
|
94
|
+
} | {
|
|
95
|
+
kind: "no-final-message";
|
|
96
|
+
message: string;
|
|
97
|
+
} | {
|
|
98
|
+
kind: "unparseable";
|
|
99
|
+
message: string;
|
|
100
|
+
raw: string;
|
|
101
|
+
} | {
|
|
102
|
+
kind: "git";
|
|
103
|
+
message: string;
|
|
104
|
+
}
|
|
105
|
+
/** The reviewer changed the working tree it was reviewing; its verdict cannot be trusted. */
|
|
106
|
+
| {
|
|
107
|
+
kind: "worktree-modified";
|
|
108
|
+
message: string;
|
|
109
|
+
changes: string[];
|
|
110
|
+
};
|
|
111
|
+
export declare const SANDBOXES: readonly ["read-only", "workspace-write"];
|
|
112
|
+
export type Sandbox = (typeof SANDBOXES)[number];
|
|
113
|
+
/**
|
|
114
|
+
* Codex 0.155.1 accepts `-c model_reasoning_effort=<level>` on `codex exec` at argv-parse time but does not
|
|
115
|
+
* validate the value itself (an unknown level loads fine), so codex-review rejects one that is not one of
|
|
116
|
+
* these five documented levels. The binary's own model catalog lists no `minimal` and adds `max`/`ultra` for
|
|
117
|
+
* some models; neither is verified for use here, so this stays the documented set.
|
|
118
|
+
*/
|
|
119
|
+
export declare const REASONING_EFFORTS: readonly ["minimal", "low", "medium", "high", "xhigh"];
|
|
120
|
+
export type ReasoningEffort = (typeof REASONING_EFFORTS)[number];
|
|
121
|
+
/**
|
|
122
|
+
* JSON Schema for the model's final message. Codex passes it to the API in strict mode, which requires
|
|
123
|
+
* every property to be listed in `required`; optional fields are therefore nullable rather than absent.
|
|
124
|
+
*/
|
|
125
|
+
export declare const MODEL_REVIEW_SCHEMA: {
|
|
126
|
+
readonly type: "object";
|
|
127
|
+
readonly additionalProperties: false;
|
|
128
|
+
readonly required: readonly ["verdict", "summary", "issues"];
|
|
129
|
+
readonly properties: {
|
|
130
|
+
readonly verdict: {
|
|
131
|
+
readonly type: "string";
|
|
132
|
+
readonly enum: readonly ["pass", "fail", "inconclusive"];
|
|
133
|
+
};
|
|
134
|
+
readonly summary: {
|
|
135
|
+
readonly type: "string";
|
|
136
|
+
};
|
|
137
|
+
readonly issues: {
|
|
138
|
+
readonly type: "array";
|
|
139
|
+
readonly items: {
|
|
140
|
+
readonly type: "object";
|
|
141
|
+
readonly additionalProperties: false;
|
|
142
|
+
readonly required: readonly ["severity", "file", "line", "description", "evidence"];
|
|
143
|
+
readonly properties: {
|
|
144
|
+
readonly severity: {
|
|
145
|
+
readonly type: "string";
|
|
146
|
+
readonly enum: readonly ["blocker", "major", "minor"];
|
|
147
|
+
};
|
|
148
|
+
readonly file: {
|
|
149
|
+
readonly type: "string";
|
|
150
|
+
};
|
|
151
|
+
readonly line: {
|
|
152
|
+
readonly type: readonly ["integer", "null"];
|
|
153
|
+
readonly description: "1-based line in file, or null";
|
|
154
|
+
};
|
|
155
|
+
readonly description: {
|
|
156
|
+
readonly type: "string";
|
|
157
|
+
};
|
|
158
|
+
readonly evidence: {
|
|
159
|
+
readonly type: readonly ["string", "null"];
|
|
160
|
+
readonly description: "the command or observation that demonstrates the issue, or null";
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
/** Validates a parsed final message. Returns the normalized review or an error string. */
|
|
168
|
+
export declare function validateModelReview(value: unknown): {
|
|
169
|
+
review: ModelReview;
|
|
170
|
+
} | {
|
|
171
|
+
error: string;
|
|
172
|
+
};
|
|
173
|
+
/** Exit code for the CLI: 0 no blockers, 1 blockers or a fail verdict, 2 could not review. */
|
|
174
|
+
export declare function exitCodeFor(result: ReviewResult): number;
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// The contract between Doug and any worker: spec in, diff plus evidence out.
|
|
2
|
+
// This file defines the "out" side for the review role. The JSON Schema is handed to
|
|
3
|
+
// `codex exec --output-schema` so the model's final message is constrained to it, and the
|
|
4
|
+
// parser validates it again because a schema on the way out is not a guarantee on the way in.
|
|
5
|
+
export const SEVERITIES = ["blocker", "major", "minor"];
|
|
6
|
+
export const VERDICTS = ["pass", "fail", "inconclusive"];
|
|
7
|
+
export const SANDBOXES = ["read-only", "workspace-write"];
|
|
8
|
+
/**
|
|
9
|
+
* Codex 0.155.1 accepts `-c model_reasoning_effort=<level>` on `codex exec` at argv-parse time but does not
|
|
10
|
+
* validate the value itself (an unknown level loads fine), so codex-review rejects one that is not one of
|
|
11
|
+
* these five documented levels. The binary's own model catalog lists no `minimal` and adds `max`/`ultra` for
|
|
12
|
+
* some models; neither is verified for use here, so this stays the documented set.
|
|
13
|
+
*/
|
|
14
|
+
export const REASONING_EFFORTS = ["minimal", "low", "medium", "high", "xhigh"];
|
|
15
|
+
/**
|
|
16
|
+
* JSON Schema for the model's final message. Codex passes it to the API in strict mode, which requires
|
|
17
|
+
* every property to be listed in `required`; optional fields are therefore nullable rather than absent.
|
|
18
|
+
*/
|
|
19
|
+
export const MODEL_REVIEW_SCHEMA = {
|
|
20
|
+
type: "object",
|
|
21
|
+
additionalProperties: false,
|
|
22
|
+
required: ["verdict", "summary", "issues"],
|
|
23
|
+
properties: {
|
|
24
|
+
verdict: { type: "string", enum: [...VERDICTS] },
|
|
25
|
+
summary: { type: "string" },
|
|
26
|
+
issues: {
|
|
27
|
+
type: "array",
|
|
28
|
+
items: {
|
|
29
|
+
type: "object",
|
|
30
|
+
additionalProperties: false,
|
|
31
|
+
required: ["severity", "file", "line", "description", "evidence"],
|
|
32
|
+
properties: {
|
|
33
|
+
severity: { type: "string", enum: [...SEVERITIES] },
|
|
34
|
+
file: { type: "string" },
|
|
35
|
+
line: { type: ["integer", "null"], description: "1-based line in file, or null" },
|
|
36
|
+
description: { type: "string" },
|
|
37
|
+
evidence: { type: ["string", "null"], description: "the command or observation that demonstrates the issue, or null" },
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
/** Validates a parsed final message. Returns the normalized review or an error string. */
|
|
44
|
+
export function validateModelReview(value) {
|
|
45
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
46
|
+
return { error: "final message is not a JSON object" };
|
|
47
|
+
const v = value;
|
|
48
|
+
if (!VERDICTS.includes(v.verdict))
|
|
49
|
+
return { error: `verdict must be one of ${VERDICTS.join(", ")}` };
|
|
50
|
+
if (typeof v.summary !== "string")
|
|
51
|
+
return { error: "summary must be a string" };
|
|
52
|
+
if (!Array.isArray(v.issues))
|
|
53
|
+
return { error: "issues must be an array" };
|
|
54
|
+
const issues = [];
|
|
55
|
+
for (const [i, raw] of v.issues.entries()) {
|
|
56
|
+
if (!raw || typeof raw !== "object")
|
|
57
|
+
return { error: `issues[${i}] must be an object` };
|
|
58
|
+
const it = raw;
|
|
59
|
+
if (!SEVERITIES.includes(it.severity))
|
|
60
|
+
return { error: `issues[${i}].severity must be one of ${SEVERITIES.join(", ")}` };
|
|
61
|
+
if (typeof it.file !== "string")
|
|
62
|
+
return { error: `issues[${i}].file must be a string` };
|
|
63
|
+
if (typeof it.description !== "string" || !it.description.trim())
|
|
64
|
+
return { error: `issues[${i}].description must be a non-empty string` };
|
|
65
|
+
const issue = { severity: it.severity, file: it.file, description: it.description };
|
|
66
|
+
if (typeof it.line === "number" && Number.isInteger(it.line))
|
|
67
|
+
issue.line = it.line;
|
|
68
|
+
if (typeof it.evidence === "string" && it.evidence)
|
|
69
|
+
issue.evidence = it.evidence;
|
|
70
|
+
issues.push(issue);
|
|
71
|
+
}
|
|
72
|
+
return { review: { verdict: v.verdict, summary: v.summary, issues } };
|
|
73
|
+
}
|
|
74
|
+
/** Exit code for the CLI: 0 no blockers, 1 blockers or a fail verdict, 2 could not review. */
|
|
75
|
+
export function exitCodeFor(result) {
|
|
76
|
+
if (result.error)
|
|
77
|
+
return 2;
|
|
78
|
+
if (result.verdict === "inconclusive")
|
|
79
|
+
return 2;
|
|
80
|
+
if (result.verdict === "fail" || result.issues.some((i) => i.severity === "blocker"))
|
|
81
|
+
return 1;
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dougharness/codex",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "codex-review: Codex CLI as an adversarial reviewer. Spec in, diff plus evidence out, structured JSON with real exit statuses.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/eschwa3/dougharness.git",
|
|
10
|
+
"directory": "packages/doug-codex"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"codex-review": "./dist/bin.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=22.16"
|
|
23
|
+
}
|
|
24
|
+
}
|