greenrun-cli 0.1.3 → 0.1.5

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/dist/cli.js CHANGED
@@ -15,6 +15,7 @@ function printHelp() {
15
15
 
16
16
  Usage:
17
17
  greenrun init Interactive setup wizard
18
+ greenrun update Update command templates to latest version
18
19
  greenrun serve Start MCP server
19
20
  greenrun --version, -v Print version
20
21
  greenrun --help, -h Print this help
@@ -42,6 +43,11 @@ async function main() {
42
43
  await runInit(args.slice(1));
43
44
  return;
44
45
  }
46
+ if (command === 'update') {
47
+ const { runUpdate } = await import('./commands/init.js');
48
+ runUpdate();
49
+ return;
50
+ }
45
51
  if (command === 'serve') {
46
52
  const { startServer } = await import('./server.js');
47
53
  await startServer();
@@ -1 +1,2 @@
1
+ export declare function runUpdate(): void;
1
2
  export declare function runInit(args: string[]): Promise<void>;
@@ -138,6 +138,56 @@ function installClaudeMd() {
138
138
  console.log(' Created CLAUDE.md with Greenrun instructions');
139
139
  }
140
140
  }
141
+ function installSettings() {
142
+ const settingsDir = join(process.cwd(), '.claude');
143
+ mkdirSync(settingsDir, { recursive: true });
144
+ const settingsPath = join(settingsDir, 'settings.local.json');
145
+ let existing = {};
146
+ if (existsSync(settingsPath)) {
147
+ try {
148
+ existing = JSON.parse(readFileSync(settingsPath, 'utf-8'));
149
+ }
150
+ catch {
151
+ // overwrite invalid JSON
152
+ }
153
+ }
154
+ const greenrunTools = [
155
+ 'mcp__greenrun__list_projects',
156
+ 'mcp__greenrun__get_project',
157
+ 'mcp__greenrun__create_project',
158
+ 'mcp__greenrun__list_pages',
159
+ 'mcp__greenrun__create_page',
160
+ 'mcp__greenrun__list_tests',
161
+ 'mcp__greenrun__get_test',
162
+ 'mcp__greenrun__create_test',
163
+ 'mcp__greenrun__update_test',
164
+ 'mcp__greenrun__start_run',
165
+ 'mcp__greenrun__complete_run',
166
+ 'mcp__greenrun__get_run',
167
+ 'mcp__greenrun__list_runs',
168
+ 'mcp__greenrun__sweep',
169
+ ];
170
+ const browserTools = [
171
+ 'mcp__claude-in-chrome__tabs_context_mcp',
172
+ 'mcp__claude-in-chrome__tabs_create_mcp',
173
+ 'mcp__claude-in-chrome__navigate',
174
+ 'mcp__claude-in-chrome__computer',
175
+ 'mcp__claude-in-chrome__read_page',
176
+ 'mcp__claude-in-chrome__find',
177
+ 'mcp__claude-in-chrome__form_input',
178
+ 'mcp__claude-in-chrome__javascript_tool',
179
+ 'mcp__claude-in-chrome__get_page_text',
180
+ 'mcp__claude-in-chrome__read_console_messages',
181
+ 'mcp__claude-in-chrome__read_network_requests',
182
+ ];
183
+ const requiredTools = [...greenrunTools, ...browserTools];
184
+ existing.permissions = existing.permissions || {};
185
+ const currentAllow = existing.permissions.allow || [];
186
+ const merged = [...new Set([...currentAllow, ...requiredTools])];
187
+ existing.permissions.allow = merged;
188
+ writeFileSync(settingsPath, JSON.stringify(existing, null, 2) + '\n');
189
+ console.log(' Updated .claude/settings.local.json with tool permissions');
190
+ }
141
191
  function installCommands() {
142
192
  const commandsDir = join(process.cwd(), '.claude', 'commands');
143
193
  mkdirSync(commandsDir, { recursive: true });
@@ -153,6 +203,13 @@ function installCommands() {
153
203
  console.log(` Installed /${cmd.replace('.md', '')}`);
154
204
  }
155
205
  }
206
+ export function runUpdate() {
207
+ console.log('\nGreenrun - Updating templates\n');
208
+ installCommands();
209
+ installSettings();
210
+ installClaudeMd();
211
+ console.log('\nDone! Templates updated to latest version.\n');
212
+ }
156
213
  export async function runInit(args) {
157
214
  const opts = parseFlags(args);
158
215
  const interactive = !opts.token;
@@ -241,6 +298,7 @@ export async function runInit(args) {
241
298
  if (opts.commands) {
242
299
  installCommands();
243
300
  }
301
+ installSettings();
244
302
  console.log(`
245
303
  Done! Restart Claude Code to connect.
246
304
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "greenrun-cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "CLI and MCP server for Greenrun - browser test management for Claude Code",
5
5
  "type": "module",
6
6
  "main": "dist/server.js",
@@ -23,17 +23,25 @@ If no argument is given, run all active tests.
23
23
 
24
24
  If there are no matching active tests, tell the user and stop.
25
25
 
26
- ### 3. Execute tests in parallel
26
+ ### 3. Pre-fetch test details
27
+
28
+ Call `get_test` for ALL matching tests **in parallel** (multiple tool calls in one message). This retrieves the full instructions for each test.
29
+
30
+ Then call `start_run` for ALL tests **in parallel** to get run IDs.
31
+
32
+ You now have everything needed to launch agents: test name, full instructions, and run_id for each test.
33
+
34
+ ### 4. Execute tests in parallel
27
35
 
28
36
  Split the test list into batches of size `concurrency` (from the project settings).
29
37
 
30
- For each batch, launch all tests simultaneously using the **Task tool** with `run_in_background: true`. Each background agent receives a prompt containing everything it needs to execute one test independently:
38
+ For each batch, launch all tests simultaneously using the **Task tool** with `run_in_background: true`. Each background agent receives a prompt with the full instructions and run_id embedded — agents do NOT need to call `get_test` or `start_run`.
31
39
 
32
40
  ```
33
41
  For each test in the current batch, call the Task tool with:
34
42
  - subagent_type: "general-purpose"
35
43
  - run_in_background: true
36
- - max_turns: 30
44
+ - max_turns: 50
37
45
  - model: "sonnet"
38
46
  - prompt: (see below)
39
47
  ```
@@ -41,33 +49,46 @@ For each test in the current batch, call the Task tool with:
41
49
  The prompt for each background agent should be:
42
50
 
43
51
  ```
44
- You are executing a single Greenrun browser test. You have access to browser automation tools and Greenrun MCP tools.
45
-
46
- **Test: {test_name}** (ID: {test_id})
47
-
48
- Step 1: Call `get_test` with test_id "{test_id}" to get full instructions.
49
- Step 2: Call `start_run` with test_id "{test_id}" to begin - save the returned `run_id`.
50
- Step 3: Execute the test instructions using browser automation:
51
- - Call `tabs_context_mcp` then create a new browser tab for this test
52
- - Follow each instruction step exactly as written
53
- - The instructions will tell you where to navigate and what to do
54
- - Only take a screenshot when you need to verify a visual assertion — not for every navigation or click
55
- - When reading page content, prefer `find` or `read_page` with `filter: "interactive"` over full DOM reads
52
+ You are executing a single Greenrun browser test using browser automation tools. Be efficient minimize tool calls to complete the test as fast as possible.
53
+
54
+ **Test: {test_name}**
55
+ **Run ID: {run_id}**
56
+
57
+ ## Test Instructions
58
+
59
+ {paste the full test instructions from get_test here}
60
+
61
+ ## Execution Steps
62
+
63
+ 1. Call `tabs_context_mcp` then create a new browser tab with `tabs_create_mcp`
64
+ 2. Follow each test instruction step exactly as written, using these rules to minimize tool calls:
65
+
66
+ **Speed rules (critical):**
67
+ - NEVER take screenshots. Use `read_page` or `find` for all assertions and to locate elements.
68
+ - Navigate directly to URLs (e.g. `navigate` to `/tokens`) instead of clicking through nav links
69
+ - Use `javascript_tool` for quick assertions: `document.querySelector('h1')?.textContent` is faster than `read_page` for checking a heading
70
+ - Use `read_page` with `filter: "interactive"` to verify multiple things in one call rather than separate `find` calls
71
+ - Use `form_input` with element refs for filling forms — avoid click-then-type sequences
72
+ - When clicking elements, use `ref` parameter instead of coordinates to avoid needing screenshots
73
+ - Combine verification: after a page loads, do ONE `read_page` call and check all assertions from that result
74
+
75
+ **Reliability rules:**
56
76
  - NEVER trigger JavaScript alerts, confirms, or prompts — they block the browser extension entirely. Before clicking delete buttons or other destructive actions, use `javascript_tool` to override: `window.alert = () => {}; window.confirm = () => true; window.prompt = () => null;`
57
77
  - If browser tools stop responding (no result or timeout), assume a dialog is blocking — report the error and stop. Do not keep retrying.
58
78
  - If you get stuck or a step fails, record the failure and move on — do not retry more than once
59
- Step 4: Call `complete_run` with:
60
- - run_id: the run ID from step 2
79
+ - If you are redirected to a login page, try using an existing logged-in tab from `tabs_context_mcp` instead of creating a new one
80
+
81
+ 3. Call `complete_run` with:
82
+ - run_id: "{run_id}"
61
83
  - status: "passed" if all checks succeeded, "failed" if any check failed, "error" if execution was blocked
62
84
  - result: a brief summary of what happened (include the failure reason if failed/error)
63
- Step 5: Close the browser tab you created to clean up.
64
85
 
65
86
  Return a single line summary: {test_name} | {status} | {result_summary}
66
87
  ```
67
88
 
68
89
  After launching all agents in a batch, wait for them all to complete (use `TaskOutput` to collect results) before launching the next batch.
69
90
 
70
- ### 4. Summarize results
91
+ ### 5. Summarize results
71
92
 
72
93
  After all batches complete, collect results from all background agents and present a summary table:
73
94