@reneturcios/greenlight 0.4.0 → 0.5.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/README.md +25 -1
- package/dist/cli.js +119 -2
- package/dist/cli.js.map +1 -1
- package/dist/digest.d.ts +1 -1
- package/dist/digest.js +1 -1
- package/dist/doctor.d.ts +34 -0
- package/dist/doctor.js +158 -0
- package/dist/doctor.js.map +1 -0
- package/dist/github.js +2 -2
- package/dist/github.js.map +1 -1
- package/dist/guard.d.ts +1 -1
- package/dist/guard.js +1 -1
- package/dist/help.d.ts +25 -0
- package/dist/help.js +234 -0
- package/dist/help.js.map +1 -0
- package/dist/index.js +47 -2
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +61 -0
- package/dist/init.js +298 -0
- package/dist/init.js.map +1 -0
- package/dist/verify-comment.d.ts +75 -0
- package/dist/verify-comment.js +149 -0
- package/dist/verify-comment.js.map +1 -0
- package/dist/verify-parsers.d.ts +25 -0
- package/dist/verify-parsers.js +56 -0
- package/dist/verify-parsers.js.map +1 -0
- package/dist/verify.d.ts +52 -0
- package/dist/verify.js +276 -0
- package/dist/verify.js.map +1 -0
- package/integrations/README.md +2 -1
- package/integrations/claude-code/CLAUDE.snippet.md +6 -5
- package/integrations/cline/README.md +1 -1
- package/integrations/copilot/copilot-instructions.snippet.md +6 -3
- package/integrations/cursor/greenlight.mdc +2 -1
- package/integrations/windsurf/README.md +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/verify.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface VerifyOptions {
|
|
2
|
+
/** Base ref for the comparison (default: merge-base with upstream, or origin/main). */
|
|
3
|
+
base?: string;
|
|
4
|
+
/** Override the detected test command. */
|
|
5
|
+
cmd?: string;
|
|
6
|
+
/** Override the parser choice (parser name, e.g. "node:test", "pytest"). */
|
|
7
|
+
parser?: string;
|
|
8
|
+
/** Per-run timeout in seconds. */
|
|
9
|
+
timeoutSecs?: number;
|
|
10
|
+
/** Run even when the working tree has uncommitted changes. */
|
|
11
|
+
allowDirty?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface VerifyDelta {
|
|
14
|
+
newlyFailing: string[];
|
|
15
|
+
newlyPassing: string[];
|
|
16
|
+
stillFailing: string[];
|
|
17
|
+
baseTotal: {
|
|
18
|
+
passed: number;
|
|
19
|
+
failed: number;
|
|
20
|
+
};
|
|
21
|
+
headTotal: {
|
|
22
|
+
passed: number;
|
|
23
|
+
failed: number;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface VerifyResult {
|
|
27
|
+
ok: boolean;
|
|
28
|
+
/** Machine form of the outcome. */
|
|
29
|
+
outcome: "fixed" | "broke" | "clean" | "no-change" | "unverifiable";
|
|
30
|
+
/** "unverifiable" only: why the comparison could not be made. */
|
|
31
|
+
reason?: string;
|
|
32
|
+
command?: string;
|
|
33
|
+
parser?: string;
|
|
34
|
+
base?: string;
|
|
35
|
+
delta?: VerifyDelta;
|
|
36
|
+
markdown: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Detect the repo's test command from its manifest files. Returns null
|
|
40
|
+
* when nothing is detectable; the caller must then report unverifiable
|
|
41
|
+
* rather than guess a command.
|
|
42
|
+
*/
|
|
43
|
+
export declare function detectTestCommand(dir: string): string | null;
|
|
44
|
+
/** Resolve the default base ref: upstream merge-base, else local origin/main. */
|
|
45
|
+
export declare function defaultBase(dir: string): string | null;
|
|
46
|
+
export declare function renderVerifyMarkdown(r: VerifyResult): string;
|
|
47
|
+
/**
|
|
48
|
+
* Run the red-green comparison. All failure paths are explicit: this
|
|
49
|
+
* function would rather say "unverifiable" with a reason than report a
|
|
50
|
+
* delta it cannot defend.
|
|
51
|
+
*/
|
|
52
|
+
export declare function verifyRepo(dir: string, opts?: VerifyOptions): VerifyResult;
|
package/dist/verify.js
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Honest verify: the red-green runner.
|
|
3
|
+
*
|
|
4
|
+
* `greenlight verify` answers one question with evidence: did my change
|
|
5
|
+
* fix the failing test, break something new, or neither? It runs the
|
|
6
|
+
* repo's test command on a base worktree and on the current tree, parses
|
|
7
|
+
* both runs into test identities with verify-parsers, and reports the
|
|
8
|
+
* DELTA: newly failing (yours), newly passing (fixed), still failing
|
|
9
|
+
* (pre-existing, not yours). Counts come from parsed output, never raw
|
|
10
|
+
* log lines.
|
|
11
|
+
*
|
|
12
|
+
* CLI only, on purpose: this runs test suites on the machine where the
|
|
13
|
+
* code lives, and suites can take minutes. The MCP server is for agents
|
|
14
|
+
* on other machines; the thing that runs your tests belongs in the CLI.
|
|
15
|
+
*/
|
|
16
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
17
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
18
|
+
import { tmpdir } from "node:os";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
import { parserForCommand, RUNNER_PARSERS } from "./verify-parsers.js";
|
|
21
|
+
function sh(dir, args) {
|
|
22
|
+
return execFileSync("git", args, { cwd: dir, encoding: "utf8" }).trim();
|
|
23
|
+
}
|
|
24
|
+
function isGitRepo(dir) {
|
|
25
|
+
try {
|
|
26
|
+
sh(dir, ["rev-parse", "--git-dir"]);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function isTreeClean(dir) {
|
|
34
|
+
try {
|
|
35
|
+
return sh(dir, ["status", "--porcelain"]).length === 0;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Detect the repo's test command from its manifest files. Returns null
|
|
43
|
+
* when nothing is detectable; the caller must then report unverifiable
|
|
44
|
+
* rather than guess a command.
|
|
45
|
+
*/
|
|
46
|
+
export function detectTestCommand(dir) {
|
|
47
|
+
const pkg = join(dir, "package.json");
|
|
48
|
+
if (existsSync(pkg)) {
|
|
49
|
+
try {
|
|
50
|
+
const doc = JSON.parse(readFileSync(pkg, "utf8"));
|
|
51
|
+
// Return the script itself, not "npm test": the parser needs to see
|
|
52
|
+
// the real runner (node --test, vitest, pytest) to claim the output.
|
|
53
|
+
if (doc.scripts?.test)
|
|
54
|
+
return doc.scripts.test;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// fall through
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (existsSync(join(dir, "pyproject.toml")) || existsSync(join(dir, "pytest.ini")) || existsSync(join(dir, "setup.cfg"))) {
|
|
61
|
+
return "pytest -q";
|
|
62
|
+
}
|
|
63
|
+
if (existsSync(join(dir, "go.mod")))
|
|
64
|
+
return "go test ./...";
|
|
65
|
+
if (existsSync(join(dir, "Cargo.toml")))
|
|
66
|
+
return "cargo test";
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
/** Resolve the default base ref: upstream merge-base, else local origin/main. */
|
|
70
|
+
export function defaultBase(dir) {
|
|
71
|
+
try {
|
|
72
|
+
const upstream = sh(dir, ["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"]);
|
|
73
|
+
return sh(dir, ["merge-base", "HEAD", upstream]);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// no upstream tracking
|
|
77
|
+
}
|
|
78
|
+
for (const cand of ["origin/main", "origin/master"]) {
|
|
79
|
+
try {
|
|
80
|
+
sh(dir, ["rev-parse", "--verify", cand]);
|
|
81
|
+
return sh(dir, ["merge-base", "HEAD", cand]);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// try next
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
/** Run a shell command in dir with a timeout, capturing merged output. */
|
|
90
|
+
function runCommand(dir, command, timeoutMs) {
|
|
91
|
+
try {
|
|
92
|
+
const r = spawnSync("sh", ["-c", command], {
|
|
93
|
+
cwd: dir,
|
|
94
|
+
encoding: "utf8",
|
|
95
|
+
timeout: timeoutMs,
|
|
96
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
97
|
+
});
|
|
98
|
+
if (r.error) {
|
|
99
|
+
const err = r.error;
|
|
100
|
+
if (err.code === "ENOENT")
|
|
101
|
+
return { output: "", exitCode: -1, timedOut: false, spawnFailed: true };
|
|
102
|
+
if (err.killed)
|
|
103
|
+
return { output: r.stdout + r.stderr, exitCode: -1, timedOut: true, spawnFailed: false };
|
|
104
|
+
return { output: String(err.message), exitCode: -1, timedOut: false, spawnFailed: true };
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
output: (r.stdout ?? "") + (r.stderr ?? ""),
|
|
108
|
+
exitCode: r.status ?? -1,
|
|
109
|
+
timedOut: false,
|
|
110
|
+
spawnFailed: false,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
return { output: String(err), exitCode: -1, timedOut: false, spawnFailed: true };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function deltaOf(baseFailed, headFailed) {
|
|
118
|
+
const b = new Set(baseFailed);
|
|
119
|
+
const h = new Set(headFailed);
|
|
120
|
+
return {
|
|
121
|
+
newlyFailing: [...h].filter((t) => !b.has(t)),
|
|
122
|
+
newlyPassing: [...b].filter((t) => !h.has(t)),
|
|
123
|
+
stillFailing: [...h].filter((t) => b.has(t)),
|
|
124
|
+
baseTotal: { passed: 0, failed: baseFailed.length },
|
|
125
|
+
headTotal: { passed: 0, failed: headFailed.length },
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export function renderVerifyMarkdown(r) {
|
|
129
|
+
if (r.outcome === "unverifiable") {
|
|
130
|
+
return `## Verify: unverifiable\n\n${r.reason ?? "no reason given"}\n`;
|
|
131
|
+
}
|
|
132
|
+
const d = r.delta;
|
|
133
|
+
const lines = [
|
|
134
|
+
`## Verify: base \`${r.base}\` vs working tree`,
|
|
135
|
+
``,
|
|
136
|
+
`Test command: \`${r.command}\` (parsed with ${r.parser})`,
|
|
137
|
+
`Base: ${d.baseTotal.failed} failing | Head: ${d.headTotal.failed} failing`,
|
|
138
|
+
``,
|
|
139
|
+
];
|
|
140
|
+
if (d.newlyPassing.length > 0) {
|
|
141
|
+
lines.push(`### Fixed by your change (${d.newlyPassing.length})`);
|
|
142
|
+
for (const t of d.newlyPassing)
|
|
143
|
+
lines.push(`- ${t}`);
|
|
144
|
+
lines.push(``);
|
|
145
|
+
}
|
|
146
|
+
if (d.newlyFailing.length > 0) {
|
|
147
|
+
lines.push(`### Newly failing: these are yours (${d.newlyFailing.length})`);
|
|
148
|
+
for (const t of d.newlyFailing)
|
|
149
|
+
lines.push(`- ${t}`);
|
|
150
|
+
lines.push(``);
|
|
151
|
+
}
|
|
152
|
+
if (d.stillFailing.length > 0) {
|
|
153
|
+
lines.push(`### Still failing: pre-existing, not yours (${d.stillFailing.length})`);
|
|
154
|
+
for (const t of d.stillFailing)
|
|
155
|
+
lines.push(`- ${t}`);
|
|
156
|
+
lines.push(``);
|
|
157
|
+
}
|
|
158
|
+
if (d.newlyPassing.length === 0 && d.newlyFailing.length === 0 && d.stillFailing.length === 0) {
|
|
159
|
+
lines.push(`No failing tests on either side; nothing to report.`);
|
|
160
|
+
}
|
|
161
|
+
return lines.join("\n");
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Run the red-green comparison. All failure paths are explicit: this
|
|
165
|
+
* function would rather say "unverifiable" with a reason than report a
|
|
166
|
+
* delta it cannot defend.
|
|
167
|
+
*/
|
|
168
|
+
export function verifyRepo(dir, opts = {}) {
|
|
169
|
+
const timeoutMs = (opts.timeoutSecs ?? 600) * 1000;
|
|
170
|
+
if (!isGitRepo(dir)) {
|
|
171
|
+
return { ok: false, outcome: "unverifiable", reason: `${dir} is not a git repository`, markdown: "" };
|
|
172
|
+
}
|
|
173
|
+
if (!opts.allowDirty && !isTreeClean(dir)) {
|
|
174
|
+
return {
|
|
175
|
+
ok: false,
|
|
176
|
+
outcome: "unverifiable",
|
|
177
|
+
reason: "working tree has uncommitted changes; commit or stash first, or re-run with --allow-dirty (the head run will then include your uncommitted changes)",
|
|
178
|
+
markdown: "",
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
const base = opts.base ?? defaultBase(dir);
|
|
182
|
+
if (!base) {
|
|
183
|
+
return {
|
|
184
|
+
ok: false,
|
|
185
|
+
outcome: "unverifiable",
|
|
186
|
+
reason: "could not determine a base ref (no upstream tracking branch, no local origin/main); pass --base <ref>",
|
|
187
|
+
markdown: "",
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
const command = opts.cmd ?? detectTestCommand(dir);
|
|
191
|
+
if (!command) {
|
|
192
|
+
return {
|
|
193
|
+
ok: false,
|
|
194
|
+
outcome: "unverifiable",
|
|
195
|
+
reason: "no test command detected (checked package.json scripts.test, pytest, go, cargo); pass --cmd \"<test command>\"",
|
|
196
|
+
markdown: "",
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const parser = opts.parser
|
|
200
|
+
? (RUNNER_PARSERS.find((p) => p.name === opts.parser) ?? null)
|
|
201
|
+
: parserForCommand(command);
|
|
202
|
+
if (!parser) {
|
|
203
|
+
return {
|
|
204
|
+
ok: false,
|
|
205
|
+
outcome: "unverifiable",
|
|
206
|
+
reason: `no output parser claims "${command}" (parsers: ${["node:test", "pytest"].join(", ")}); pass --cmd with a supported runner`,
|
|
207
|
+
markdown: "",
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
// Base runs in a detached temp worktree so the working tree is never
|
|
211
|
+
// touched. Removed afterwards even on failure.
|
|
212
|
+
const baseDir = mkdtempSync(join(tmpdir(), "greenlight-verify-base-"));
|
|
213
|
+
try {
|
|
214
|
+
try {
|
|
215
|
+
sh(dir, ["worktree", "add", "--detach", baseDir, base]);
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
return { ok: false, outcome: "unverifiable", reason: `could not create base worktree: ${err instanceof Error ? err.message : String(err)}`, markdown: "" };
|
|
219
|
+
}
|
|
220
|
+
const baseRun = runCommand(baseDir, command, timeoutMs);
|
|
221
|
+
const headRun = runCommand(dir, command, timeoutMs);
|
|
222
|
+
for (const [name, run] of [["base", baseRun], ["head", headRun]]) {
|
|
223
|
+
if (run.spawnFailed) {
|
|
224
|
+
return { ok: false, outcome: "unverifiable", reason: `could not run the test command on ${name}: ${run.output || "spawn failed"}`, markdown: "" };
|
|
225
|
+
}
|
|
226
|
+
if (run.timedOut) {
|
|
227
|
+
return { ok: false, outcome: "unverifiable", reason: `test command timed out on ${name} after ${opts.timeoutSecs ?? 600}s`, markdown: "" };
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const baseParsed = parser.parse(baseRun.output);
|
|
231
|
+
const headParsed = parser.parse(headRun.output);
|
|
232
|
+
if (baseParsed.passed.length + baseParsed.failed.length === 0 || headParsed.passed.length + headParsed.failed.length === 0) {
|
|
233
|
+
return {
|
|
234
|
+
ok: false,
|
|
235
|
+
outcome: "unverifiable",
|
|
236
|
+
reason: `parsed zero tests from the ${parser.name} output (base: ${baseParsed.passed.length + baseParsed.failed.length}, head: ${headParsed.passed.length + headParsed.failed.length}); the parser may not understand this runner's output format`,
|
|
237
|
+
markdown: "",
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
const delta = deltaOf(baseParsed.failed, headParsed.failed);
|
|
241
|
+
delta.baseTotal = { passed: baseParsed.passed.length, failed: baseParsed.failed.length };
|
|
242
|
+
delta.headTotal = { passed: headParsed.passed.length, failed: headParsed.failed.length };
|
|
243
|
+
const outcome = delta.newlyFailing.length > 0
|
|
244
|
+
? "broke"
|
|
245
|
+
: delta.newlyPassing.length > 0
|
|
246
|
+
? "fixed"
|
|
247
|
+
: delta.stillFailing.length > 0
|
|
248
|
+
? "no-change"
|
|
249
|
+
: "clean";
|
|
250
|
+
const result = {
|
|
251
|
+
ok: true,
|
|
252
|
+
outcome,
|
|
253
|
+
command,
|
|
254
|
+
parser: parser.name,
|
|
255
|
+
base,
|
|
256
|
+
delta,
|
|
257
|
+
markdown: "",
|
|
258
|
+
};
|
|
259
|
+
result.markdown = renderVerifyMarkdown(result);
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
try {
|
|
264
|
+
sh(dir, ["worktree", "remove", "--force", baseDir]);
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
try {
|
|
268
|
+
rmSync(baseDir, { recursive: true, force: true });
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
// best effort; a stale worktree dir is cleaned by git gc
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
|
package/integrations/README.md
CHANGED
|
@@ -29,7 +29,7 @@ without it the tools still work but share the small anonymous budget.
|
|
|
29
29
|
## Verify it worked
|
|
30
30
|
|
|
31
31
|
Ask the agent: "list your MCP tools." You should see the `greenlight`
|
|
32
|
-
server with all
|
|
32
|
+
server with all 13 tools:
|
|
33
33
|
|
|
34
34
|
- `check_issue` — verdict on whether an issue is landable (GO / RISKY / TAKEN / GATED / STALE)
|
|
35
35
|
- `scan_repo` — find starter issues worth working in a repo
|
|
@@ -43,6 +43,7 @@ server with all 12 tools:
|
|
|
43
43
|
- `repo_digest` — repo-level maintainer report: PR races with first-claim arbitration, claimed-by-other conflicts, stale claims, assignment-gate conflicts (never posts)
|
|
44
44
|
- `claim_status` — Claim Protocol pre-flight for one issue: who holds it, until when, who is queued, competing PRs, gates, whether the repo honors the protocol
|
|
45
45
|
- `preflight` — the one-call answer: claim_status plus the repo friction summary
|
|
46
|
+
- `verify_comment` — draft the verified-finding comment for maintainer-only repos (draft only, never posts)
|
|
46
47
|
|
|
47
48
|
## Format notes
|
|
48
49
|
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# Greenlight rules for Claude Code
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Drop-in rules for the Greenlight workflow through the greenlight MCP tools.
|
|
4
|
+
Installed by `greenlight init --agent claude-code`, or paste manually into
|
|
5
|
+
your project's CLAUDE.md (or keep the file and reference it from CLAUDE.md).
|
|
6
6
|
|
|
7
7
|
## Greenlight: check before you open a PR
|
|
8
8
|
|
|
9
9
|
You have the Greenlight MCP server connected (server name: greenlight,
|
|
10
|
-
|
|
11
|
-
open_pr, ci_triage, review_triage
|
|
10
|
+
12 tools: check_issue, scan_repo, repo_friction, claim_issue, prep_issue,
|
|
11
|
+
open_pr, ci_triage, review_triage, guard_pr, repo_digest, claim_status,
|
|
12
|
+
preflight). It answers one question at every step:
|
|
12
13
|
is this contribution worth doing, and is the problem mine?
|
|
13
14
|
|
|
14
15
|
Rules:
|
|
@@ -7,7 +7,7 @@ file form is:
|
|
|
7
7
|
|
|
8
8
|
Copy the `cline_mcp_settings.json` file in this folder there (merging with
|
|
9
9
|
any servers you already have), then check the Cline "MCP Servers" panel:
|
|
10
|
-
the `greenlight` server should list
|
|
10
|
+
the `greenlight` server should list 12 tools. The `disabled: false` field is
|
|
11
11
|
Cline's way of keeping the server enabled without deleting it.
|
|
12
12
|
|
|
13
13
|
Workflow: see the integrations README — your agent checks Greenlight
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
# Greenlight instructions for GitHub Copilot / VS Code
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Drop-in instructions for the Greenlight workflow through the greenlight MCP
|
|
4
|
+
tools. Installed by `greenlight init --agent copilot`, or paste manually
|
|
5
|
+
into your project's `.github/copilot-instructions.md` (create the folder if
|
|
6
|
+
it does not exist).
|
|
5
7
|
|
|
6
8
|
## Greenlight: check before you open a PR
|
|
7
9
|
|
|
8
10
|
You have the Greenlight MCP server connected (server `greenlight`, tools:
|
|
9
11
|
check_issue, scan_repo, repo_friction, claim_issue, prep_issue, open_pr,
|
|
10
|
-
ci_triage, review_triage
|
|
12
|
+
ci_triage, review_triage, guard_pr, repo_digest, claim_status, preflight).
|
|
13
|
+
Apply these instructions whenever working on a
|
|
11
14
|
pull request to an open source project:
|
|
12
15
|
|
|
13
16
|
1. Before writing any code for a GitHub issue, call `check_issue` with the
|
|
@@ -7,7 +7,8 @@ alwaysApply: false
|
|
|
7
7
|
|
|
8
8
|
You have the Greenlight MCP server connected (server `greenlight`, tools:
|
|
9
9
|
check_issue, scan_repo, repo_friction, claim_issue, prep_issue, open_pr,
|
|
10
|
-
ci_triage, review_triage
|
|
10
|
+
ci_triage, review_triage, guard_pr, repo_digest, claim_status, preflight).
|
|
11
|
+
Apply these rules whenever the user is working on
|
|
11
12
|
a pull request to an open source project:
|
|
12
13
|
|
|
13
14
|
1. Before writing any code for a GitHub issue, call `check_issue` with the
|
|
@@ -6,7 +6,7 @@ Windsurf's global MCP config lives at:
|
|
|
6
6
|
|
|
7
7
|
Copy the `mcp_config.json` file in this folder there (merging with any
|
|
8
8
|
servers you already have), then restart Windsurf and check its MCP panel:
|
|
9
|
-
the `greenlight` server should list
|
|
9
|
+
the `greenlight` server should list 12 tools. Newer Windsurf versions also
|
|
10
10
|
accept a project-level `.windsurf/mcp.json` file using the same
|
|
11
11
|
`mcpServers` format.
|
|
12
12
|
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
"url": "https://github.com/CloudCorpRecords/greenlight",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.5.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
14
14
|
"identifier": "@reneturcios/greenlight",
|
|
15
|
-
"version": "0.
|
|
15
|
+
"version": "0.5.0",
|
|
16
16
|
"runtimeHint": "npx",
|
|
17
17
|
"packageArguments": [
|
|
18
18
|
{
|