@pretorian-worx/runclaudia-cli 0.12.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/README.md +49 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -0
- package/dist/format.d.ts +1 -0
- package/dist/format.js +5 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +272 -0
- package/dist/index.js.map +1 -0
- package/dist/ratings.d.ts +29 -0
- package/dist/ratings.js +91 -0
- package/dist/ratings.js.map +1 -0
- package/dist/reporters.d.ts +16 -0
- package/dist/reporters.js +127 -0
- package/dist/reporters.js.map +1 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Paul Schneider
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# @pretorian-worx/runclaudia-cli
|
|
2
|
+
|
|
3
|
+
The CLI for [claudia](https://github.com/pretorian-worx/runclaudia) — a diff-aware post-deploy test agent. Picks the relevant subset of your Playwright suite for a given diff, runs it against the deployed production URL, and reports the result to GitHub Actions, the merged PR, and Slack.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx -y @pretorian-worx/runclaudia-cli <subcommand> [args]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or globally:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm i -g @pretorian-worx/runclaudia-cli
|
|
15
|
+
claudia <subcommand> [args]
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Subcommands
|
|
19
|
+
|
|
20
|
+
- `claudia plan` — diff-aware test plan generation (uses Anthropic)
|
|
21
|
+
- `claudia map` — build/inspect the route + endpoint + infra + DB + spec map
|
|
22
|
+
- `claudia select` — pick a diff-relevant subset of Playwright/Cypress specs
|
|
23
|
+
- `claudia run` — `select` + execute the subset against a deployed URL
|
|
24
|
+
- `claudia ratings` — aggregate 👍/👎 reactions across PR plan comments
|
|
25
|
+
|
|
26
|
+
`claudia plan` requires `ANTHROPIC_API_KEY` in the environment. All other subcommands are deterministic local code (zero API calls).
|
|
27
|
+
|
|
28
|
+
## Post-deploy verification
|
|
29
|
+
|
|
30
|
+
This is the canonical use:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx -y @pretorian-worx/runclaudia-cli run \
|
|
34
|
+
--base $LAST_DEPLOY_SHA \
|
|
35
|
+
--head $JUST_DEPLOYED_SHA \
|
|
36
|
+
--target https://app.example.com \
|
|
37
|
+
--slack-webhook $SLACK_WEBHOOK_URL
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Result is auto-reported to:
|
|
41
|
+
- `$GITHUB_STEP_SUMMARY` when running in GitHub Actions
|
|
42
|
+
- A sticky comment on the merged PR that introduced the deployed commit
|
|
43
|
+
- Slack (if `--slack-webhook` or `CLAUDIA_SLACK_WEBHOOK` is set)
|
|
44
|
+
|
|
45
|
+
See the [main repo README](https://github.com/pretorian-worx/runclaudia#readme) for the full workflow example and the larger product context.
|
|
46
|
+
|
|
47
|
+
## License
|
|
48
|
+
|
|
49
|
+
MIT
|
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
const CANDIDATES = ["claudia.config.ts", "claudia.config.js", "claudia.config.mjs"];
|
|
5
|
+
export async function loadConfig(cwd) {
|
|
6
|
+
for (const name of CANDIDATES) {
|
|
7
|
+
const abs = resolve(cwd, name);
|
|
8
|
+
if (!existsSync(abs))
|
|
9
|
+
continue;
|
|
10
|
+
try {
|
|
11
|
+
const mod = await import(pathToFileURL(abs).href);
|
|
12
|
+
const cfg = (mod.default ?? mod);
|
|
13
|
+
return cfg ?? {};
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
void join;
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAS1C,MAAM,UAAU,GAAG,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,oBAAoB,CAAC,CAAC;AAEpF,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAC/B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;YAClD,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAkB,CAAC;YAClD,OAAO,GAAG,IAAI,EAAE,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,KAAK,IAAI,CAAC;IACV,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { formatPlanMarkdown as formatMarkdown, formatPlanJson as formatJson } from "@pretorian-worx/runclaudia-core";
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Compatibility re-export. The real renderers moved to @pretorian-worx/runclaudia-core in v0.11
|
|
2
|
+
// so the GitHub Action can import them without reaching into the CLI's dist/.
|
|
3
|
+
// New code should import directly from "@pretorian-worx/runclaudia-core".
|
|
4
|
+
export { formatPlanMarkdown as formatMarkdown, formatPlanJson as formatJson } from "@pretorian-worx/runclaudia-core";
|
|
5
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,8EAA8E;AAC9E,0EAA0E;AAC1E,OAAO,EAAE,kBAAkB,IAAI,cAAc,EAAE,cAAc,IAAI,UAAU,EAAE,MAAM,iCAAiC,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { defineCommand, runMain } from "citty";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { writeFileSync } from "node:fs";
|
|
5
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
6
|
+
import { mkdtempSync, readFileSync, existsSync } from "node:fs";
|
|
7
|
+
import { tmpdir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { buildPlaywrightCommand, formatRunMarkdown, formatSelectionMarkdown, loadOrBuildMap, parsePlaywrightReport, PlannerError, runPlan, runSelect, } from "@pretorian-worx/runclaudia-core";
|
|
10
|
+
import { formatJson, formatMarkdown } from "./format.js";
|
|
11
|
+
import { loadConfig } from "./config.js";
|
|
12
|
+
import { aggregateRatings, formatRatings } from "./ratings.js";
|
|
13
|
+
import { dispatchReporters } from "./reporters.js";
|
|
14
|
+
const planCmd = defineCommand({
|
|
15
|
+
meta: { name: "plan", description: "Produce a diff-aware test plan" },
|
|
16
|
+
args: {
|
|
17
|
+
base: { type: "string", required: true, description: "Base ref (e.g. main or a SHA)" },
|
|
18
|
+
head: { type: "string", default: "HEAD", description: "Head ref" },
|
|
19
|
+
cwd: { type: "string", description: "Project root directory" },
|
|
20
|
+
target: { type: "string", description: "Deployed URL the plan will reference" },
|
|
21
|
+
json: { type: "boolean", description: "Emit JSON instead of markdown" },
|
|
22
|
+
model: { type: "string", description: "Override the planner model" },
|
|
23
|
+
output: { type: "string", description: "Write output to a file as well as stdout" },
|
|
24
|
+
"refresh-map": { type: "boolean", description: "Force a fresh route-map build" },
|
|
25
|
+
},
|
|
26
|
+
async run({ args }) {
|
|
27
|
+
const rootDir = resolve(args.cwd ?? process.cwd());
|
|
28
|
+
const cfg = await loadConfig(rootDir);
|
|
29
|
+
let result;
|
|
30
|
+
try {
|
|
31
|
+
result = await runPlan({
|
|
32
|
+
rootDir: cfg.rootDir ? resolve(rootDir, cfg.rootDir) : rootDir,
|
|
33
|
+
base: args.base,
|
|
34
|
+
head: args.head,
|
|
35
|
+
targetUrl: args.target,
|
|
36
|
+
refreshMap: Boolean(args["refresh-map"]),
|
|
37
|
+
model: args.model ?? cfg.model,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
if (err instanceof PlannerError) {
|
|
42
|
+
process.stderr.write(`claudia: ${err.message}\n`);
|
|
43
|
+
process.stderr.write(JSON.stringify(err.details, null, 2) + "\n");
|
|
44
|
+
process.exit(2);
|
|
45
|
+
}
|
|
46
|
+
throw err;
|
|
47
|
+
}
|
|
48
|
+
const text = args.json ? formatJson(result) : formatMarkdown(result);
|
|
49
|
+
process.stdout.write(text + "\n");
|
|
50
|
+
if (args.output)
|
|
51
|
+
writeFileSync(resolve(args.output), text + "\n", "utf8");
|
|
52
|
+
if (result.plan.verdict === "skip")
|
|
53
|
+
process.exit(0);
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
const mapCmd = defineCommand({
|
|
57
|
+
meta: { name: "map", description: "Build or inspect the route map" },
|
|
58
|
+
args: {
|
|
59
|
+
cwd: { type: "string", description: "Project root directory" },
|
|
60
|
+
refresh: { type: "boolean", description: "Rebuild even if cache is fresh" },
|
|
61
|
+
json: { type: "boolean", description: "Print full map as JSON" },
|
|
62
|
+
},
|
|
63
|
+
async run({ args }) {
|
|
64
|
+
const rootDir = resolve(args.cwd ?? process.cwd());
|
|
65
|
+
const map = loadOrBuildMap({ rootDir, refresh: Boolean(args.refresh) });
|
|
66
|
+
if (args.json) {
|
|
67
|
+
process.stdout.write(JSON.stringify(map, null, 2) + "\n");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
process.stdout.write(`framework: ${map.framework}\nroutes: ${map.routes.length}\n`);
|
|
71
|
+
for (const r of map.routes)
|
|
72
|
+
process.stdout.write(` ${r.route} (${r.files.length} files)\n`);
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
const selectCmd = defineCommand({
|
|
76
|
+
meta: {
|
|
77
|
+
name: "select",
|
|
78
|
+
description: "Pick the subset of the user's existing Playwright/Cypress specs that cover the routes/endpoints implicated by a diff. Intended for post-deploy verification workflows.",
|
|
79
|
+
},
|
|
80
|
+
args: {
|
|
81
|
+
base: { type: "string", required: true, description: "Base ref (the last-deployed SHA)" },
|
|
82
|
+
head: { type: "string", default: "HEAD", description: "Head ref (the just-deployed SHA)" },
|
|
83
|
+
cwd: { type: "string", description: "Project root directory" },
|
|
84
|
+
json: { type: "boolean", description: "Emit JSON instead of markdown" },
|
|
85
|
+
"refresh-map": { type: "boolean", description: "Force a fresh map build" },
|
|
86
|
+
"grep-only": {
|
|
87
|
+
type: "boolean",
|
|
88
|
+
description: "Print just the Playwright --grep pattern (empty if no eligible specs)",
|
|
89
|
+
},
|
|
90
|
+
"files-only": {
|
|
91
|
+
type: "boolean",
|
|
92
|
+
description: "Print just the selected spec file paths, one per line",
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
run({ args }) {
|
|
96
|
+
const rootDir = resolve(args.cwd ?? process.cwd());
|
|
97
|
+
const result = runSelect({
|
|
98
|
+
rootDir,
|
|
99
|
+
base: args.base,
|
|
100
|
+
head: args.head,
|
|
101
|
+
refreshMap: Boolean(args["refresh-map"]),
|
|
102
|
+
});
|
|
103
|
+
if (args["grep-only"]) {
|
|
104
|
+
process.stdout.write((result.playwrightGrep ?? "") + "\n");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (args["files-only"]) {
|
|
108
|
+
for (const s of result.selected)
|
|
109
|
+
process.stdout.write(s.file + "\n");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (args.json) {
|
|
113
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
process.stdout.write(formatSelectionMarkdown(result, { base: args.base, head: args.head }) + "\n");
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
const runCmd = defineCommand({
|
|
120
|
+
meta: {
|
|
121
|
+
name: "run",
|
|
122
|
+
description: "Select + execute Playwright specs covering the diff against a deployed target URL. Intended for post-deploy verification workflows.",
|
|
123
|
+
},
|
|
124
|
+
args: {
|
|
125
|
+
base: { type: "string", required: true, description: "Base ref (the last-deployed SHA)" },
|
|
126
|
+
head: { type: "string", default: "HEAD", description: "Head ref (the just-deployed SHA)" },
|
|
127
|
+
target: { type: "string", required: true, description: "Deployed URL to run specs against (PLAYWRIGHT_BASE_URL)" },
|
|
128
|
+
cwd: { type: "string", description: "Project root directory" },
|
|
129
|
+
"playwright-config": { type: "string", description: "Path to Playwright config file" },
|
|
130
|
+
"refresh-map": { type: "boolean", description: "Force a fresh map build" },
|
|
131
|
+
json: { type: "boolean", description: "Emit JSON summary instead of markdown" },
|
|
132
|
+
"dry-run": { type: "boolean", description: "Print the command that would run; don't spawn it" },
|
|
133
|
+
"slack-webhook": {
|
|
134
|
+
type: "string",
|
|
135
|
+
description: "Slack incoming-webhook URL to POST the result to (or set CLAUDIA_SLACK_WEBHOOK)",
|
|
136
|
+
},
|
|
137
|
+
"no-step-summary": {
|
|
138
|
+
type: "boolean",
|
|
139
|
+
description: "Disable auto-writing to $GITHUB_STEP_SUMMARY when running in GitHub Actions",
|
|
140
|
+
},
|
|
141
|
+
"no-pr-comment": {
|
|
142
|
+
type: "boolean",
|
|
143
|
+
description: "Disable posting a sticky comment back to the merged PR for this SHA",
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
async run({ args }) {
|
|
147
|
+
const rootDir = resolve(args.cwd ?? process.cwd());
|
|
148
|
+
const selection = runSelect({
|
|
149
|
+
rootDir,
|
|
150
|
+
base: args.base,
|
|
151
|
+
head: args.head,
|
|
152
|
+
refreshMap: Boolean(args["refresh-map"]),
|
|
153
|
+
});
|
|
154
|
+
const tmpDir = mkdtempSync(join(tmpdir(), "claudia-run-"));
|
|
155
|
+
const jsonReportPath = join(tmpDir, "report.json");
|
|
156
|
+
const cmd = buildPlaywrightCommand({
|
|
157
|
+
selection,
|
|
158
|
+
target: args.target,
|
|
159
|
+
playwrightConfig: args["playwright-config"],
|
|
160
|
+
jsonReportPath,
|
|
161
|
+
});
|
|
162
|
+
if (!cmd) {
|
|
163
|
+
const md = formatRunMarkdown({
|
|
164
|
+
selection,
|
|
165
|
+
report: null,
|
|
166
|
+
target: args.target,
|
|
167
|
+
nothingToRun: true,
|
|
168
|
+
});
|
|
169
|
+
if (args.json) {
|
|
170
|
+
process.stdout.write(JSON.stringify({ status: "nothing-to-run", selection }, null, 2) + "\n");
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
process.stdout.write(md + "\n");
|
|
174
|
+
}
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (args["dry-run"]) {
|
|
178
|
+
process.stdout.write(`${cmd.command} ${cmd.args.join(" ")}\n`);
|
|
179
|
+
for (const [k, v] of Object.entries(cmd.env))
|
|
180
|
+
process.stdout.write(` ${k}=${v}\n`);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
process.stderr.write(`claudia: running ${cmd.command} ${cmd.args.join(" ")}\n`);
|
|
184
|
+
const child = spawn(cmd.command, cmd.args, {
|
|
185
|
+
cwd: rootDir,
|
|
186
|
+
env: { ...process.env, ...cmd.env },
|
|
187
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
188
|
+
});
|
|
189
|
+
const exitCode = await new Promise((resolveCode) => {
|
|
190
|
+
child.on("close", (code) => resolveCode(code ?? 1));
|
|
191
|
+
child.on("error", (err) => {
|
|
192
|
+
process.stderr.write(`claudia: failed to spawn Playwright: ${err.message}\n`);
|
|
193
|
+
resolveCode(127);
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
let report = null;
|
|
197
|
+
if (existsSync(jsonReportPath)) {
|
|
198
|
+
try {
|
|
199
|
+
const raw = JSON.parse(readFileSync(jsonReportPath, "utf8"));
|
|
200
|
+
report = parsePlaywrightReport(raw);
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
process.stderr.write(`claudia: could not parse Playwright JSON report (${err instanceof Error ? err.message : String(err)})\n`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const markdown = formatRunMarkdown({
|
|
207
|
+
selection,
|
|
208
|
+
report,
|
|
209
|
+
target: args.target,
|
|
210
|
+
nothingToRun: false,
|
|
211
|
+
});
|
|
212
|
+
if (args.json) {
|
|
213
|
+
process.stdout.write(JSON.stringify({ status: report ? "completed" : "no-report", exitCode, report }, null, 2) + "\n");
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
process.stdout.write(markdown + "\n");
|
|
217
|
+
}
|
|
218
|
+
// Resolve the SHA we just verified so reporters can find the originating PR.
|
|
219
|
+
const headSha = resolveSha(rootDir, args.head);
|
|
220
|
+
await dispatchReporters({
|
|
221
|
+
markdown,
|
|
222
|
+
headSha,
|
|
223
|
+
passed: report ? report.failed === 0 : exitCode === 0,
|
|
224
|
+
}, {
|
|
225
|
+
slackWebhook: args["slack-webhook"],
|
|
226
|
+
disableStepSummary: Boolean(args["no-step-summary"]),
|
|
227
|
+
disablePrComment: Boolean(args["no-pr-comment"]),
|
|
228
|
+
});
|
|
229
|
+
process.exit(exitCode);
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
function resolveSha(cwd, ref) {
|
|
233
|
+
try {
|
|
234
|
+
return execFileSync("git", ["rev-parse", ref], { cwd, encoding: "utf8" }).trim();
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
return ref;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const ratingsCmd = defineCommand({
|
|
241
|
+
meta: { name: "ratings", description: "Aggregate 👍/👎 reactions on claudia comments across a repo's PRs" },
|
|
242
|
+
args: {
|
|
243
|
+
repo: { type: "string", required: true, description: "owner/name (e.g. pretorian-worx/runclaudia)" },
|
|
244
|
+
limit: { type: "string", description: "Max PRs to scan (default 100)" },
|
|
245
|
+
state: { type: "string", description: "open | closed | all (default all)" },
|
|
246
|
+
json: { type: "boolean", description: "Emit JSON instead of markdown" },
|
|
247
|
+
},
|
|
248
|
+
run({ args }) {
|
|
249
|
+
const state = args.state;
|
|
250
|
+
if (state && !["open", "closed", "all"].includes(state)) {
|
|
251
|
+
process.stderr.write(`Invalid --state: ${state}\n`);
|
|
252
|
+
process.exit(2);
|
|
253
|
+
}
|
|
254
|
+
const summary = aggregateRatings({
|
|
255
|
+
repo: args.repo,
|
|
256
|
+
limit: args.limit ? parseInt(args.limit, 10) : undefined,
|
|
257
|
+
state,
|
|
258
|
+
});
|
|
259
|
+
if (args.json) {
|
|
260
|
+
process.stdout.write(JSON.stringify(summary, null, 2) + "\n");
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
process.stdout.write(formatRatings(summary) + "\n");
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
const main = defineCommand({
|
|
268
|
+
meta: { name: "claudia", description: "Diff-aware post-deploy test agent" },
|
|
269
|
+
subCommands: { plan: planCmd, map: mapCmd, select: selectCmd, run: runCmd, ratings: ratingsCmd },
|
|
270
|
+
});
|
|
271
|
+
runMain(main);
|
|
272
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface PRRating {
|
|
2
|
+
prNumber: number;
|
|
3
|
+
url: string;
|
|
4
|
+
thumbsUp: number;
|
|
5
|
+
thumbsDown: number;
|
|
6
|
+
verdict: "useful" | "not_useful" | "no_signal";
|
|
7
|
+
}
|
|
8
|
+
export interface RatingsSummary {
|
|
9
|
+
repo: string;
|
|
10
|
+
total: number;
|
|
11
|
+
useful: number;
|
|
12
|
+
notUseful: number;
|
|
13
|
+
noSignal: number;
|
|
14
|
+
usefulPercent: number | null;
|
|
15
|
+
perPR: PRRating[];
|
|
16
|
+
}
|
|
17
|
+
export interface RatingsOptions {
|
|
18
|
+
repo: string;
|
|
19
|
+
limit?: number;
|
|
20
|
+
state?: "open" | "closed" | "all";
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Aggregates 👍 / 👎 reactions on claudia's sticky comments across a repo's
|
|
24
|
+
* pull requests. Only +1 and -1 from non-bot users count; everything else
|
|
25
|
+
* (laugh, hooray, confused, heart, rocket, eyes, or reactions from the
|
|
26
|
+
* github-actions bot itself) is ignored.
|
|
27
|
+
*/
|
|
28
|
+
export declare function aggregateRatings(opts: RatingsOptions): RatingsSummary;
|
|
29
|
+
export declare function formatRatings(s: RatingsSummary): string;
|
package/dist/ratings.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
const MARKER = "<!-- claudia:plan -->";
|
|
3
|
+
/**
|
|
4
|
+
* Aggregates 👍 / 👎 reactions on claudia's sticky comments across a repo's
|
|
5
|
+
* pull requests. Only +1 and -1 from non-bot users count; everything else
|
|
6
|
+
* (laugh, hooray, confused, heart, rocket, eyes, or reactions from the
|
|
7
|
+
* github-actions bot itself) is ignored.
|
|
8
|
+
*/
|
|
9
|
+
export function aggregateRatings(opts) {
|
|
10
|
+
const limit = opts.limit ?? 100;
|
|
11
|
+
const state = opts.state ?? "all";
|
|
12
|
+
const prs = ghJson(["pr", "list", "-R", opts.repo, "--state", state, "--limit", String(limit), "--json", "number,url"]);
|
|
13
|
+
const perPR = [];
|
|
14
|
+
for (const pr of prs) {
|
|
15
|
+
const comments = ghJson([
|
|
16
|
+
"api",
|
|
17
|
+
`repos/${opts.repo}/issues/${pr.number}/comments`,
|
|
18
|
+
"--paginate",
|
|
19
|
+
"--jq",
|
|
20
|
+
"[.[] | {id, body}]",
|
|
21
|
+
]);
|
|
22
|
+
const claudiaComment = comments.find((c) => c.body?.includes(MARKER));
|
|
23
|
+
if (!claudiaComment)
|
|
24
|
+
continue;
|
|
25
|
+
const reactions = ghJson([
|
|
26
|
+
"api",
|
|
27
|
+
`repos/${opts.repo}/issues/comments/${claudiaComment.id}/reactions`,
|
|
28
|
+
"--paginate",
|
|
29
|
+
"--jq",
|
|
30
|
+
"[.[] | {content, user: {login: .user.login}}]",
|
|
31
|
+
]);
|
|
32
|
+
const thumbsUp = countReactions(reactions, "+1");
|
|
33
|
+
const thumbsDown = countReactions(reactions, "-1");
|
|
34
|
+
const verdict = thumbsUp + thumbsDown === 0
|
|
35
|
+
? "no_signal"
|
|
36
|
+
: thumbsUp > thumbsDown
|
|
37
|
+
? "useful"
|
|
38
|
+
: "not_useful";
|
|
39
|
+
perPR.push({ prNumber: pr.number, url: pr.url, thumbsUp, thumbsDown, verdict });
|
|
40
|
+
}
|
|
41
|
+
const useful = perPR.filter((p) => p.verdict === "useful").length;
|
|
42
|
+
const notUseful = perPR.filter((p) => p.verdict === "not_useful").length;
|
|
43
|
+
const noSignal = perPR.filter((p) => p.verdict === "no_signal").length;
|
|
44
|
+
const ratedTotal = useful + notUseful;
|
|
45
|
+
return {
|
|
46
|
+
repo: opts.repo,
|
|
47
|
+
total: perPR.length,
|
|
48
|
+
useful,
|
|
49
|
+
notUseful,
|
|
50
|
+
noSignal,
|
|
51
|
+
usefulPercent: ratedTotal === 0 ? null : (useful / ratedTotal) * 100,
|
|
52
|
+
perPR,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function countReactions(reactions, wanted) {
|
|
56
|
+
// Ignore the github-actions bot's own seeded reactions; we want real user signal.
|
|
57
|
+
return reactions.filter((r) => r.content === wanted && r.user?.login && r.user.login !== "github-actions[bot]").length;
|
|
58
|
+
}
|
|
59
|
+
function ghJson(args) {
|
|
60
|
+
try {
|
|
61
|
+
const raw = execFileSync("gh", args, { encoding: "utf8", maxBuffer: 16 * 1024 * 1024 });
|
|
62
|
+
return JSON.parse(raw);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
66
|
+
throw new Error(`gh ${args.join(" ")}: ${msg}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function formatRatings(s) {
|
|
70
|
+
const lines = [];
|
|
71
|
+
lines.push(`# claudia ratings — ${s.repo}`);
|
|
72
|
+
lines.push("");
|
|
73
|
+
if (s.total === 0) {
|
|
74
|
+
lines.push("No claudia comments found in this repo.");
|
|
75
|
+
return lines.join("\n");
|
|
76
|
+
}
|
|
77
|
+
lines.push(`PRs with a claudia comment: **${s.total}**`);
|
|
78
|
+
lines.push(`- 👍 useful: ${s.useful}`);
|
|
79
|
+
lines.push(`- 👎 not useful: ${s.notUseful}`);
|
|
80
|
+
lines.push(`- ⚪ no signal: ${s.noSignal}`);
|
|
81
|
+
if (s.usefulPercent !== null) {
|
|
82
|
+
lines.push("");
|
|
83
|
+
lines.push(`**Useful%: ${s.usefulPercent.toFixed(1)}%** (of ${s.useful + s.notUseful} rated PRs)`);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
lines.push("");
|
|
87
|
+
lines.push("No 👍/👎 reactions yet — no useful% to report.");
|
|
88
|
+
}
|
|
89
|
+
return lines.join("\n");
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=ratings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ratings.js","sourceRoot":"","sources":["../src/ratings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,MAAM,GAAG,uBAAuB,CAAC;AAyCvC;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAoB;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC;IAElC,MAAM,GAAG,GAAG,MAAM,CAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;IAE9I,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,MAAM,CAAmB;YACxC,KAAK;YACL,SAAS,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,WAAW;YACjD,YAAY;YACZ,MAAM;YACN,oBAAoB;SACrB,CAAC,CAAC;QACH,MAAM,cAAc,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACtE,IAAI,CAAC,cAAc;YAAE,SAAS;QAE9B,MAAM,SAAS,GAAG,MAAM,CAAa;YACnC,KAAK;YACL,SAAS,IAAI,CAAC,IAAI,oBAAoB,cAAc,CAAC,EAAE,YAAY;YACnE,YAAY;YACZ,MAAM;YACN,+CAA+C;SAChD,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,OAAO,GACX,QAAQ,GAAG,UAAU,KAAK,CAAC;YACzB,CAAC,CAAC,WAAW;YACb,CAAC,CAAC,QAAQ,GAAG,UAAU;gBACrB,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,YAAY,CAAC;QAErB,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;IAClE,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,MAAM,CAAC;IACzE,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;IAEtC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,MAAM;QACN,SAAS;QACT,QAAQ;QACR,aAAa,EAAE,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC,GAAG,GAAG;QACpE,KAAK;KACN,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,SAAqB,EAAE,MAAc;IAC3D,kFAAkF;IAClF,OAAO,SAAS,CAAC,MAAM,CACrB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,qBAAqB,CACvF,CAAC,MAAM,CAAC;AACX,CAAC;AAED,SAAS,MAAM,CAAI,IAAc;IAC/B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;QACxF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,CAAiB;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QACtD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9C,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC3C,IAAI,CAAC,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,SAAS,aAAa,CAAC,CAAC;IACrG,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface ReportContext {
|
|
2
|
+
/** Pre-rendered markdown summary of the verification run. */
|
|
3
|
+
markdown: string;
|
|
4
|
+
/** SHA whose deployment was verified. Used to look up the originating PR. */
|
|
5
|
+
headSha: string;
|
|
6
|
+
/** Whether the verification passed overall. */
|
|
7
|
+
passed: boolean;
|
|
8
|
+
/** Repo identifier "owner/name". Auto-detected from GITHUB_REPOSITORY when not set. */
|
|
9
|
+
repo?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ReporterOptions {
|
|
12
|
+
slackWebhook?: string;
|
|
13
|
+
disableStepSummary?: boolean;
|
|
14
|
+
disablePrComment?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function dispatchReporters(ctx: ReportContext, opts?: ReporterOptions): Promise<void>;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { appendFileSync } from "node:fs";
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
3
|
+
const STICKY_MARKER = "<!-- claudia:verify -->";
|
|
4
|
+
export async function dispatchReporters(ctx, opts = {}) {
|
|
5
|
+
await Promise.allSettled([
|
|
6
|
+
writeStepSummary(ctx, opts),
|
|
7
|
+
backCommentOnMergedPr(ctx, opts),
|
|
8
|
+
postToSlack(ctx, opts),
|
|
9
|
+
]);
|
|
10
|
+
}
|
|
11
|
+
// ---------- 1. $GITHUB_STEP_SUMMARY ----------
|
|
12
|
+
async function writeStepSummary(ctx, opts) {
|
|
13
|
+
if (opts.disableStepSummary)
|
|
14
|
+
return;
|
|
15
|
+
const file = process.env.GITHUB_STEP_SUMMARY;
|
|
16
|
+
if (!file)
|
|
17
|
+
return;
|
|
18
|
+
try {
|
|
19
|
+
appendFileSync(file, ctx.markdown + "\n", "utf8");
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
warn("step-summary", err);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// ---------- 2. PR back-comment ----------
|
|
26
|
+
async function backCommentOnMergedPr(ctx, opts) {
|
|
27
|
+
if (opts.disablePrComment)
|
|
28
|
+
return;
|
|
29
|
+
const repo = ctx.repo ?? process.env.GITHUB_REPOSITORY;
|
|
30
|
+
if (!repo)
|
|
31
|
+
return;
|
|
32
|
+
if (!ctx.headSha)
|
|
33
|
+
return;
|
|
34
|
+
let prNumber;
|
|
35
|
+
try {
|
|
36
|
+
prNumber = findPullRequestForSha(repo, ctx.headSha);
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
warn("pr-lookup", err);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (!prNumber)
|
|
43
|
+
return;
|
|
44
|
+
const body = `${STICKY_MARKER}\n${ctx.markdown}`;
|
|
45
|
+
try {
|
|
46
|
+
upsertStickyComment(repo, prNumber, body);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
warn("pr-comment", err);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function findPullRequestForSha(repo, sha) {
|
|
53
|
+
try {
|
|
54
|
+
const out = execFileSync("gh", [
|
|
55
|
+
"api",
|
|
56
|
+
`/repos/${repo}/commits/${sha}/pulls`,
|
|
57
|
+
"-H",
|
|
58
|
+
"Accept: application/vnd.github+json",
|
|
59
|
+
"--jq",
|
|
60
|
+
"[.[] | .number] | first",
|
|
61
|
+
], { encoding: "utf8", maxBuffer: 1024 * 1024, stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
62
|
+
if (!out || out === "null")
|
|
63
|
+
return null;
|
|
64
|
+
const n = parseInt(out, 10);
|
|
65
|
+
return Number.isNaN(n) ? null : n;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function upsertStickyComment(repo, prNumber, body) {
|
|
72
|
+
const comments = JSON.parse(execFileSync("gh", [
|
|
73
|
+
"api",
|
|
74
|
+
"--paginate",
|
|
75
|
+
`/repos/${repo}/issues/${prNumber}/comments`,
|
|
76
|
+
"--jq",
|
|
77
|
+
"[.[] | {id, body}]",
|
|
78
|
+
], { encoding: "utf8", maxBuffer: 16 * 1024 * 1024, stdio: ["ignore", "pipe", "pipe"] }));
|
|
79
|
+
const prior = comments.find((c) => c.body?.includes(STICKY_MARKER));
|
|
80
|
+
if (prior) {
|
|
81
|
+
execFileSync("gh", [
|
|
82
|
+
"api",
|
|
83
|
+
"-X",
|
|
84
|
+
"PATCH",
|
|
85
|
+
`/repos/${repo}/issues/comments/${prior.id}`,
|
|
86
|
+
"-f",
|
|
87
|
+
`body=${body}`,
|
|
88
|
+
], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
execFileSync("gh", [
|
|
92
|
+
"api",
|
|
93
|
+
"-X",
|
|
94
|
+
"POST",
|
|
95
|
+
`/repos/${repo}/issues/${prNumber}/comments`,
|
|
96
|
+
"-f",
|
|
97
|
+
`body=${body}`,
|
|
98
|
+
], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// ---------- 3. Slack ----------
|
|
102
|
+
async function postToSlack(ctx, opts) {
|
|
103
|
+
const url = opts.slackWebhook ?? process.env.CLAUDIA_SLACK_WEBHOOK;
|
|
104
|
+
if (!url)
|
|
105
|
+
return;
|
|
106
|
+
try {
|
|
107
|
+
const payload = {
|
|
108
|
+
text: ctx.markdown,
|
|
109
|
+
};
|
|
110
|
+
const res = await fetch(url, {
|
|
111
|
+
method: "POST",
|
|
112
|
+
headers: { "Content-Type": "application/json" },
|
|
113
|
+
body: JSON.stringify(payload),
|
|
114
|
+
});
|
|
115
|
+
if (!res.ok) {
|
|
116
|
+
warn("slack", new Error(`HTTP ${res.status}: ${await res.text().catch(() => "")}`));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
warn("slack", err);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function warn(label, err) {
|
|
124
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
125
|
+
process.stderr.write(`claudia: reporter[${label}] failed: ${msg}\n`);
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=reporters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporters.js","sourceRoot":"","sources":["../src/reporters.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pretorian-worx/runclaudia-cli",
|
|
3
|
+
"version": "0.12.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Diff-aware post-deploy test agent CLI — picks a relevant Playwright subset for a diff and runs it against the deployed prod artifact, with reporting to GitHub Actions, the merged PR, and Slack.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"ci",
|
|
8
|
+
"testing",
|
|
9
|
+
"playwright",
|
|
10
|
+
"post-deploy",
|
|
11
|
+
"diff",
|
|
12
|
+
"qa",
|
|
13
|
+
"claude",
|
|
14
|
+
"anthropic"
|
|
15
|
+
],
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"author": "Paul Schneider",
|
|
18
|
+
"homepage": "https://github.com/pretorian-worx/runclaudia#readme",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/pretorian-worx/runclaudia/issues"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/pretorian-worx/runclaudia.git",
|
|
25
|
+
"directory": "packages/cli"
|
|
26
|
+
},
|
|
27
|
+
"bin": {
|
|
28
|
+
"claudia": "./dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"main": "./dist/index.js",
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE"
|
|
35
|
+
],
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"citty": "^0.1.6",
|
|
41
|
+
"@pretorian-worx/runclaudia-core": "^0.12.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^22.0.0",
|
|
45
|
+
"typescript": "^5.6.0",
|
|
46
|
+
"vitest": "^2.1.0"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc -p tsconfig.json && chmod +x dist/index.js",
|
|
50
|
+
"start": "node ./dist/index.js",
|
|
51
|
+
"test": "vitest run",
|
|
52
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
53
|
+
}
|
|
54
|
+
}
|