@link-assistant/hive-mind 0.51.20 ā 0.52.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/CHANGELOG.md +46 -0
- package/README.md +57 -89
- package/package.json +1 -1
- package/src/claude.command-builder.lib.mjs +89 -0
- package/src/claude.lib.mjs +13 -0
- package/src/hive.config.lib.mjs +5 -0
- package/src/hive.mjs +3 -2
- package/src/solve.config.lib.mjs +5 -0
- package/src/solve.mjs +64 -16
- package/src/solve.results.lib.mjs +33 -20
- package/src/solve.watch.lib.mjs +12 -8
- package/CLAUDE.md +0 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# @link-assistant/hive-mind
|
|
2
2
|
|
|
3
|
+
## 0.52.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- b280bcc: Add `--prompt-playwright-mcp` flag to control Playwright MCP hints in system prompt
|
|
8
|
+
|
|
9
|
+
Users can now explicitly control whether Playwright MCP browser automation hints appear in the AI's system prompt:
|
|
10
|
+
- Use `--no-prompt-playwright-mcp` to disable hints even when Playwright MCP is installed
|
|
11
|
+
- Use `--prompt-playwright-mcp` to explicitly enable hints
|
|
12
|
+
- Omit the flag to keep the default auto-detection behavior
|
|
13
|
+
|
|
14
|
+
## 0.51.21
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Increase swap space from 2GB to 4GB in installation script for improved stability
|
|
19
|
+
|
|
20
|
+
Fix: Show Claude CLI resume command using `(cd ... && claude --resume ...)` pattern
|
|
21
|
+
|
|
22
|
+
When using `--tool claude` (or the default tool), the console now displays a copyable Claude CLI resume command at the end of every session (success, failure, or usage limit reached):
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
š” To continue this session in Claude Code interactive mode:
|
|
26
|
+
|
|
27
|
+
(cd "/tmp/gh-issue-solver-..." && claude --resume <session-id>)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Changes in this PR:
|
|
31
|
+
- Refactored `claude.command-builder.lib.mjs` to build Claude CLI commands instead of solve.mjs commands
|
|
32
|
+
- Added `buildClaudeResumeCommand()` for generating `(cd ... && claude --resume ...)` pattern
|
|
33
|
+
- Added `buildClaudeInitialCommand()` for generating `(cd ... && claude ...)` pattern
|
|
34
|
+
- Removed solve.mjs resume command display from console output
|
|
35
|
+
- Updated PR comments to use Claude CLI resume command pattern
|
|
36
|
+
|
|
37
|
+
This allows users to:
|
|
38
|
+
- Investigate sessions interactively in Claude Code
|
|
39
|
+
- Resume from where they left off after usage limits reset
|
|
40
|
+
- See full context and history
|
|
41
|
+
- Debug issues
|
|
42
|
+
|
|
43
|
+
The command uses the `(cd ... && claude --resume ...)` pattern for a fully copyable, executable command that works regardless of the current directory.
|
|
44
|
+
|
|
45
|
+
Note: The resume command is only shown for `--tool claude` since other tools (codex, opencode, agent) have different resume mechanisms.
|
|
46
|
+
|
|
47
|
+
Fixes #942
|
|
48
|
+
|
|
3
49
|
## 0.51.20
|
|
4
50
|
|
|
5
51
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -59,7 +59,7 @@ Minimum system requirements to run `hive.mjs`:
|
|
|
59
59
|
```
|
|
60
60
|
1 CPU Core
|
|
61
61
|
1 GB RAM
|
|
62
|
-
>
|
|
62
|
+
> 4 GB SWAP
|
|
63
63
|
50 GB disk space
|
|
64
64
|
```
|
|
65
65
|
|
|
@@ -301,100 +301,54 @@ review --repo owner/repo --pr 456
|
|
|
301
301
|
|
|
302
302
|
```bash
|
|
303
303
|
solve <issue-url> [options]
|
|
304
|
-
|
|
305
|
-
--model, -m Model (sonnet, opus for claude; grok-code-fast-1, gpt4o for opencode; gpt5, gpt5-codex, o3 for codex; grok, sonnet, haiku for agent)
|
|
306
|
-
[default: sonnet for claude, grok-code-fast-1 for opencode, gpt-5 for codex, grok-code-fast-1 for agent]
|
|
307
|
-
--tool AI tool (claude, opencode, codex, agent) [default: claude]
|
|
308
|
-
--fork, -f Fork repo if no write access [default: false]
|
|
309
|
-
--auto-fork Automatically fork public repos without write access (fails for private)
|
|
310
|
-
[default: true]
|
|
311
|
-
--base-branch, -b Target branch for PR [default: repo default]
|
|
312
|
-
--resume, -r Resume from session ID
|
|
313
|
-
--verbose, -v Enable verbose logging [default: false]
|
|
314
|
-
--dry-run, -n Prepare only, don't execute [default: false]
|
|
315
|
-
--only-prepare-command Only prepare and print the command [default: false]
|
|
316
|
-
--skip-tool-check Skip tool connection check (use --no-tool-check to disable)
|
|
317
|
-
[default: false]
|
|
318
|
-
--auto-pull-request-creation Create draft PR before execution [default: true]
|
|
319
|
-
--attach-logs Attach logs to PR (ā ļø sensitive) [default: false]
|
|
320
|
-
--auto-close-pull-request-on-fail Close PR on fail [default: false]
|
|
321
|
-
--auto-continue Continue with existing PR when issue URL is provided
|
|
322
|
-
[default: true]
|
|
323
|
-
--auto-continue-limit, -c Auto-continue when limit resets [default: false]
|
|
324
|
-
--auto-resume-on-errors Auto-resume on network errors (503, etc.)
|
|
325
|
-
[default: false]
|
|
326
|
-
--auto-continue-only-on-new-comments Fail if no new comments
|
|
327
|
-
[default: false]
|
|
328
|
-
--auto-commit-uncommitted-changes Auto-commit changes [default: false]
|
|
329
|
-
--auto-merge-default-branch-to-pull-request-branch Merge default branch to PR branch
|
|
330
|
-
(only in continue mode) [default: false]
|
|
331
|
-
--allow-fork-divergence-resolution-using-force-push-with-lease
|
|
332
|
-
Allow force-push with --force-with-lease when fork diverges
|
|
333
|
-
(DANGEROUS: can overwrite fork history) [default: false]
|
|
334
|
-
--prefix-fork-name-with-owner-name Prefix fork name with owner (owner-repo)
|
|
335
|
-
Useful for forking repos with same name from different owners
|
|
336
|
-
[default: true]
|
|
337
|
-
--continue-only-on-feedback Only continue if feedback detected
|
|
338
|
-
[default: false]
|
|
339
|
-
--watch, -w Monitor for feedback and auto-restart [default: false]
|
|
340
|
-
--watch-interval Feedback check interval (seconds) [default: 60]
|
|
341
|
-
--min-disk-space Minimum disk space in MB [default: 500]
|
|
342
|
-
--log-dir, -l Directory for log files [default: cwd]
|
|
343
|
-
--think Thinking level (low, medium, high, max) [optional]
|
|
344
|
-
--sentry Enable Sentry error tracking (use --no-sentry to disable)
|
|
345
|
-
[default: true]
|
|
346
|
-
--auto-cleanup Delete temp directory on completion
|
|
347
|
-
[default: true for private repos, false for public repos]
|
|
348
|
-
--version Show version number
|
|
349
|
-
--help, -h Show help
|
|
350
304
|
```
|
|
351
305
|
|
|
306
|
+
**Most frequently used options:**
|
|
307
|
+
|
|
308
|
+
| Option | Alias | Description | Default |
|
|
309
|
+
| --------- | ----- | --------------------------------------- | ------- |
|
|
310
|
+
| `--model` | `-m` | AI model to use (sonnet, opus, haiku) | sonnet |
|
|
311
|
+
| `--think` | | Thinking level (low, medium, high, max) | - |
|
|
312
|
+
|
|
313
|
+
**Other useful options:**
|
|
314
|
+
|
|
315
|
+
| Option | Alias | Description | Default |
|
|
316
|
+
| --------------- | ----- | ------------------------------------------------ | ------- |
|
|
317
|
+
| `--tool` | | AI tool (claude, opencode, codex, agent) | claude |
|
|
318
|
+
| `--verbose` | `-v` | Enable verbose logging | false |
|
|
319
|
+
| `--attach-logs` | | Attach logs to PR (ā ļø may expose sensitive data) | false |
|
|
320
|
+
| `--help` | `-h` | Show all available options | - |
|
|
321
|
+
|
|
322
|
+
> **š Full options list**: See [docs/CONFIGURATION.md](./docs/CONFIGURATION.md#solve-options) for all available options including forking, auto-continue, watch mode, and experimental features.
|
|
323
|
+
|
|
352
324
|
## š§ hive Options
|
|
353
325
|
|
|
354
326
|
```bash
|
|
355
327
|
hive <github-url> [options]
|
|
356
|
-
|
|
357
|
-
--monitor-tag, -t Label to monitor [default: "help wanted"]
|
|
358
|
-
--all-issues, -a Monitor all issues (ignore labels) [default: false]
|
|
359
|
-
--skip-issues-with-prs, -s Skip issues with existing PRs [default: false]
|
|
360
|
-
--concurrency, -c Parallel workers [default: 2]
|
|
361
|
-
--pull-requests-per-issue, -p Number of PRs per issue [default: 1]
|
|
362
|
-
--model, -m Model (opus, sonnet for claude; grok-code-fast-1, gpt4o for opencode; gpt5, gpt5-codex, o3 for codex; grok, sonnet, haiku for agent)
|
|
363
|
-
[default: sonnet for claude, grok-code-fast-1 for opencode, gpt-5 for codex, grok-code-fast-1 for agent]
|
|
364
|
-
--tool AI tool (claude, opencode, codex, agent) [default: claude]
|
|
365
|
-
--interval, -i Poll interval (seconds) [default: 300]
|
|
366
|
-
--max-issues Limit processed issues [default: 0 (unlimited)]
|
|
367
|
-
--once Single run (don't monitor) [default: false]
|
|
368
|
-
--dry-run List issues without processing [default: false]
|
|
369
|
-
--skip-tool-check Skip tool connection check (use --no-tool-check to disable)
|
|
370
|
-
[default: false]
|
|
371
|
-
--verbose, -v Enable verbose logging [default: false]
|
|
372
|
-
--min-disk-space Minimum disk space in MB [default: 500]
|
|
373
|
-
--auto-cleanup Clean /tmp/* /var/tmp/* on success [default: false]
|
|
374
|
-
--fork, -f Fork repos if no write access [default: false]
|
|
375
|
-
--auto-fork Automatically fork public repos without write access
|
|
376
|
-
[default: true]
|
|
377
|
-
--attach-logs Attach logs to PRs (ā ļø sensitive) [default: false]
|
|
378
|
-
--project-number, -pn GitHub Project number to monitor
|
|
379
|
-
--project-owner, -po GitHub Project owner (org or user)
|
|
380
|
-
--project-status, -ps Project status column to monitor [default: "Ready"]
|
|
381
|
-
--project-mode, -pm Enable project-based monitoring [default: false]
|
|
382
|
-
--youtrack-mode Enable YouTrack mode instead of GitHub [default: false]
|
|
383
|
-
--youtrack-stage Override YouTrack stage to monitor
|
|
384
|
-
--youtrack-project Override YouTrack project code
|
|
385
|
-
--target-branch, -tb Target branch for pull requests [default: repo default]
|
|
386
|
-
--log-dir, -l Directory for log files [default: cwd]
|
|
387
|
-
--auto-continue Pass --auto-continue to solve for each issue
|
|
388
|
-
[default: true]
|
|
389
|
-
--think Thinking level (low, medium, high, max) [optional]
|
|
390
|
-
--sentry Enable Sentry error tracking (use --no-sentry to disable)
|
|
391
|
-
[default: true]
|
|
392
|
-
--watch, -w Monitor for feedback and auto-restart [default: false]
|
|
393
|
-
--issue-order, -o Order issues by date (asc, desc) [default: asc]
|
|
394
|
-
--version Show version number
|
|
395
|
-
--help, -h Show help
|
|
396
328
|
```
|
|
397
329
|
|
|
330
|
+
**Most frequently used options:**
|
|
331
|
+
|
|
332
|
+
| Option | Alias | Description | Default |
|
|
333
|
+
| -------------- | ----- | --------------------------------------- | ------- |
|
|
334
|
+
| `--model` | `-m` | AI model to use (sonnet, opus, haiku) | sonnet |
|
|
335
|
+
| `--think` | | Thinking level (low, medium, high, max) | - |
|
|
336
|
+
| `--all-issues` | `-a` | Monitor all issues (ignore labels) | false |
|
|
337
|
+
| `--once` | | Single run (don't monitor continuously) | false |
|
|
338
|
+
|
|
339
|
+
**Other useful options:**
|
|
340
|
+
|
|
341
|
+
| Option | Alias | Description | Default |
|
|
342
|
+
| ------------------------ | ----- | ------------------------------------------------- | ------- |
|
|
343
|
+
| `--tool` | | AI tool (claude, opencode, agent) | claude |
|
|
344
|
+
| `--concurrency` | `-c` | Number of parallel workers | 2 |
|
|
345
|
+
| `--skip-issues-with-prs` | `-s` | Skip issues with existing PRs | false |
|
|
346
|
+
| `--verbose` | `-v` | Enable verbose logging | false |
|
|
347
|
+
| `--attach-logs` | | Attach logs to PRs (ā ļø may expose sensitive data) | false |
|
|
348
|
+
| `--help` | `-h` | Show all available options | - |
|
|
349
|
+
|
|
350
|
+
> **š Full options list**: See [docs/CONFIGURATION.md](./docs/CONFIGURATION.md#hive-options) for all available options including project monitoring, YouTrack integration, and experimental features.
|
|
351
|
+
|
|
398
352
|
## š¤ Telegram Bot
|
|
399
353
|
|
|
400
354
|
The Hive Mind includes a Telegram bot interface (SwarmMindBot) for remote command execution.
|
|
@@ -641,12 +595,14 @@ grep -E '\(cd /tmp/gh-issue-solver-[0-9]+ && claude --resume [0-9a-f-]{36}\)' hi
|
|
|
641
595
|
|
|
642
596
|
## š§ Configuration
|
|
643
597
|
|
|
644
|
-
Authentication
|
|
598
|
+
**Authentication:**
|
|
645
599
|
|
|
646
600
|
- `gh auth login` - GitHub CLI authentication
|
|
647
601
|
- `claude-profiles` - Claude authentication profile migration to server
|
|
648
602
|
|
|
649
|
-
|
|
603
|
+
**Environment Variables & Advanced Options:**
|
|
604
|
+
|
|
605
|
+
For comprehensive configuration including environment variables, timeouts, retry limits, Telegram bot settings, YouTrack integration, and all CLI options, see [docs/CONFIGURATION.md](./docs/CONFIGURATION.md).
|
|
650
606
|
|
|
651
607
|
## š Reporting Issues
|
|
652
608
|
|
|
@@ -795,6 +751,18 @@ That can be done, but not recommended as reboot have better effect.
|
|
|
795
751
|
|
|
796
752
|
Unlicense License - see [LICENSE](./LICENSE)
|
|
797
753
|
|
|
754
|
+
## š Best Practices
|
|
755
|
+
|
|
756
|
+
Hive Mind works even better when repositories have strong CI/CD pipelines. See [BEST-PRACTICES.md](./docs/BEST-PRACTICES.md) for recommended configurations that maximize AI solver quality.
|
|
757
|
+
|
|
758
|
+
Key benefits of proper CI/CD:
|
|
759
|
+
|
|
760
|
+
- AI solvers iterate until all checks pass
|
|
761
|
+
- Consistent quality regardless of human/AI team composition
|
|
762
|
+
- File size limits ensure code is readable by both AI and humans
|
|
763
|
+
|
|
764
|
+
Ready-to-use templates are available for JavaScript, Rust, Python, Go, C#, and Java.
|
|
765
|
+
|
|
798
766
|
## š¤ Contributing
|
|
799
767
|
|
|
800
768
|
This project uses AI-driven development. See [CONTRIBUTING.md](./docs/CONTRIBUTING.md) for human-AI collaboration guidelines.
|
package/package.json
CHANGED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Claude CLI Command Builder Library
|
|
5
|
+
*
|
|
6
|
+
* This module provides utilities for building Claude-specific CLI commands.
|
|
7
|
+
* These builders are specifically designed for the Claude Code CLI tool (--tool claude)
|
|
8
|
+
* and help generate consistent, copy-pasteable commands using the pattern:
|
|
9
|
+
*
|
|
10
|
+
* (cd "/path/to/workdir" && claude --resume <session-id>)
|
|
11
|
+
*
|
|
12
|
+
* This is the same pattern used by --auto-continue-on-limit-reset and allows users to:
|
|
13
|
+
* 1. Resume sessions directly using Claude CLI (not through solve.mjs)
|
|
14
|
+
* 2. Investigate issues interactively in the working directory
|
|
15
|
+
* 3. Continue work after usage limits reset
|
|
16
|
+
*
|
|
17
|
+
* Functions:
|
|
18
|
+
* - buildClaudeResumeCommand: Generate `(cd ... && claude --resume ...)` command
|
|
19
|
+
* - buildClaudeInitialCommand: Generate `(cd ... && claude ...)` command for new sessions
|
|
20
|
+
*
|
|
21
|
+
* Related issue: https://github.com/link-assistant/hive-mind/issues/942
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Build the Claude CLI resume command with the (cd ... && claude --resume ...) pattern
|
|
26
|
+
*
|
|
27
|
+
* This generates a copy-pasteable command that users can execute directly
|
|
28
|
+
* to resume a Claude session in interactive mode. This is the same pattern
|
|
29
|
+
* used by --auto-continue-on-limit-reset.
|
|
30
|
+
*
|
|
31
|
+
* The command includes all necessary flags to match how the original session was run:
|
|
32
|
+
* - --resume <sessionId>: Resume from the specified session
|
|
33
|
+
* - --model <model>: Use the same model as the original session (optional)
|
|
34
|
+
*
|
|
35
|
+
* Note: This function is specifically designed for Claude CLI (--tool claude)
|
|
36
|
+
* and should only be used when the tool is 'claude' or undefined (defaults to claude).
|
|
37
|
+
*
|
|
38
|
+
* @param {Object} options - Options for building the command
|
|
39
|
+
* @param {string} options.tempDir - The working directory (e.g., /tmp/gh-issue-solver-...)
|
|
40
|
+
* @param {string} options.sessionId - The session ID to resume
|
|
41
|
+
* @param {string} options.claudePath - Path to the claude CLI binary (defaults to 'claude')
|
|
42
|
+
* @param {string} [options.model] - The model to use (e.g., 'sonnet', 'opus', 'claude-sonnet-4-20250514')
|
|
43
|
+
* @returns {string} - The full resume command with (cd ... && claude --resume ...) pattern
|
|
44
|
+
*/
|
|
45
|
+
export const buildClaudeResumeCommand = ({ tempDir, sessionId, claudePath = 'claude', model }) => {
|
|
46
|
+
let args = `--resume ${sessionId}`;
|
|
47
|
+
|
|
48
|
+
if (model) {
|
|
49
|
+
args += ` --model ${model}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return `(cd "${tempDir}" && ${claudePath} ${args})`;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Build the Claude CLI initial command with the (cd ... && claude ...) pattern
|
|
57
|
+
*
|
|
58
|
+
* This generates the command pattern used when starting a new Claude session.
|
|
59
|
+
* Useful for documentation and debugging purposes.
|
|
60
|
+
*
|
|
61
|
+
* Note: This function is specifically designed for Claude CLI (--tool claude)
|
|
62
|
+
* and should only be used when the tool is 'claude' or undefined (defaults to claude).
|
|
63
|
+
*
|
|
64
|
+
* @param {Object} options - Options for building the command
|
|
65
|
+
* @param {string} options.tempDir - The working directory (e.g., /tmp/gh-issue-solver-...)
|
|
66
|
+
* @param {string} options.claudePath - Path to the claude CLI binary (defaults to 'claude')
|
|
67
|
+
* @param {string} [options.model] - The model to use
|
|
68
|
+
* @param {boolean} [options.verbose] - Whether to include --verbose flag
|
|
69
|
+
* @returns {string} - The command pattern (cd ... && claude ...)
|
|
70
|
+
*/
|
|
71
|
+
export const buildClaudeInitialCommand = ({ tempDir, claudePath = 'claude', model, verbose = false }) => {
|
|
72
|
+
let args = '--output-format stream-json --dangerously-skip-permissions';
|
|
73
|
+
|
|
74
|
+
if (verbose) {
|
|
75
|
+
args += ' --verbose';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (model) {
|
|
79
|
+
args += ` --model ${model}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return `(cd "${tempDir}" && ${claudePath} ${args})`;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Export default object for compatibility
|
|
86
|
+
export default {
|
|
87
|
+
buildClaudeResumeCommand,
|
|
88
|
+
buildClaudeInitialCommand,
|
|
89
|
+
};
|
package/src/claude.lib.mjs
CHANGED
|
@@ -14,6 +14,17 @@ import { timeouts, retryLimits } from './config.lib.mjs';
|
|
|
14
14
|
import { detectUsageLimit, formatUsageLimitMessage } from './usage-limit.lib.mjs';
|
|
15
15
|
import { createInteractiveHandler } from './interactive-mode.lib.mjs';
|
|
16
16
|
import { displayBudgetStats } from './claude.budget-stats.lib.mjs';
|
|
17
|
+
// Import Claude command builder for generating resume commands
|
|
18
|
+
import { buildClaudeResumeCommand } from './claude.command-builder.lib.mjs';
|
|
19
|
+
|
|
20
|
+
// Helper to display resume command at end of session
|
|
21
|
+
const showResumeCommand = async (sessionId, tempDir, claudePath, model, log) => {
|
|
22
|
+
if (!sessionId || !tempDir) return;
|
|
23
|
+
const cmd = buildClaudeResumeCommand({ tempDir, sessionId, claudePath, model });
|
|
24
|
+
await log('\nš” To continue this session in Claude Code interactive mode:\n');
|
|
25
|
+
await log(` ${cmd}\n`);
|
|
26
|
+
};
|
|
27
|
+
|
|
17
28
|
/**
|
|
18
29
|
* Format numbers with spaces as thousands separator (no commas)
|
|
19
30
|
* Per issue #667: Use spaces for thousands, . for decimals
|
|
@@ -1250,6 +1261,7 @@ export const executeClaudeCommand = async params => {
|
|
|
1250
1261
|
await log(` Load: ${resourcesAfter.load}`, { verbose: true });
|
|
1251
1262
|
// Log attachment will be handled by solve.mjs when it receives success=false
|
|
1252
1263
|
await log('', { verbose: true });
|
|
1264
|
+
await showResumeCommand(sessionId, tempDir, claudePath, argv.model, log);
|
|
1253
1265
|
return {
|
|
1254
1266
|
success: false,
|
|
1255
1267
|
sessionId,
|
|
@@ -1349,6 +1361,7 @@ export const executeClaudeCommand = async params => {
|
|
|
1349
1361
|
await log(` ā ļø Could not calculate token usage: ${tokenError.message}`, { verbose: true });
|
|
1350
1362
|
}
|
|
1351
1363
|
}
|
|
1364
|
+
await showResumeCommand(sessionId, tempDir, claudePath, argv.model, log);
|
|
1352
1365
|
return {
|
|
1353
1366
|
success: true,
|
|
1354
1367
|
sessionId,
|
package/src/hive.config.lib.mjs
CHANGED
|
@@ -266,6 +266,11 @@ export const createYargsConfig = yargsInstance => {
|
|
|
266
266
|
description: 'Create comprehensive case study documentation for the issue including logs, analysis, timeline, root cause investigation, and proposed solutions. Organizes findings into ./docs/case-studies/issue-{id}/ directory. Only supported for --tool claude.',
|
|
267
267
|
default: false,
|
|
268
268
|
})
|
|
269
|
+
.option('prompt-playwright-mcp', {
|
|
270
|
+
type: 'boolean',
|
|
271
|
+
description: 'Enable Playwright MCP browser automation hints in system prompt (enabled by default, only takes effect if Playwright MCP is installed). Use --no-prompt-playwright-mcp to disable. Only supported for --tool claude.',
|
|
272
|
+
default: true,
|
|
273
|
+
})
|
|
269
274
|
.parserConfiguration({
|
|
270
275
|
'boolean-negation': true,
|
|
271
276
|
'strip-dashed': false,
|
package/src/hive.mjs
CHANGED
|
@@ -750,6 +750,7 @@ if (isDirectExecution) {
|
|
|
750
750
|
const promptExploreSubAgentFlag = argv.promptExploreSubAgent ? ' --prompt-explore-sub-agent' : '';
|
|
751
751
|
const promptIssueReportingFlag = argv.promptIssueReporting ? ' --prompt-issue-reporting' : '';
|
|
752
752
|
const promptCaseStudiesFlag = argv.promptCaseStudies ? ' --prompt-case-studies' : '';
|
|
753
|
+
const promptPlaywrightMcpFlag = argv.promptPlaywrightMcp === true ? ' --prompt-playwright-mcp' : argv.promptPlaywrightMcp === false ? ' --no-prompt-playwright-mcp' : '';
|
|
753
754
|
// Use spawn to get real-time streaming output while avoiding command-stream's automatic quote addition
|
|
754
755
|
const { spawn } = await import('child_process');
|
|
755
756
|
|
|
@@ -800,9 +801,9 @@ if (isDirectExecution) {
|
|
|
800
801
|
if (argv.promptExploreSubAgent) args.push('--prompt-explore-sub-agent');
|
|
801
802
|
if (argv.promptIssueReporting) args.push('--prompt-issue-reporting');
|
|
802
803
|
if (argv.promptCaseStudies) args.push('--prompt-case-studies');
|
|
803
|
-
|
|
804
|
+
if (argv.promptPlaywrightMcp !== undefined) args.push(argv.promptPlaywrightMcp ? '--prompt-playwright-mcp' : '--no-prompt-playwright-mcp');
|
|
804
805
|
// Log the actual command being executed so users can investigate/reproduce
|
|
805
|
-
const command = `${solveCommand} "${issueUrl}" --model ${argv.model}${toolFlag}${forkFlag}${autoForkFlag}${verboseFlag}${attachLogsFlag}${targetBranchFlag}${logDirFlag}${dryRunFlag}${skipToolConnectionCheckFlag}${autoContinueFlag}${thinkFlag}${promptPlanSubAgentFlag}${noSentryFlag}${watchFlag}${prefixForkNameWithOwnerNameFlag}${interactiveModeFlag}${promptExploreSubAgentFlag}${promptIssueReportingFlag}${promptCaseStudiesFlag}`;
|
|
806
|
+
const command = `${solveCommand} "${issueUrl}" --model ${argv.model}${toolFlag}${forkFlag}${autoForkFlag}${verboseFlag}${attachLogsFlag}${targetBranchFlag}${logDirFlag}${dryRunFlag}${skipToolConnectionCheckFlag}${autoContinueFlag}${thinkFlag}${promptPlanSubAgentFlag}${noSentryFlag}${watchFlag}${prefixForkNameWithOwnerNameFlag}${interactiveModeFlag}${promptExploreSubAgentFlag}${promptIssueReportingFlag}${promptCaseStudiesFlag}${promptPlaywrightMcpFlag}`;
|
|
806
807
|
await log(` š Command: ${command}`);
|
|
807
808
|
|
|
808
809
|
let exitCode = 0;
|
package/src/solve.config.lib.mjs
CHANGED
|
@@ -281,6 +281,11 @@ export const createYargsConfig = yargsInstance => {
|
|
|
281
281
|
description: 'Create comprehensive case study documentation for the issue including logs, analysis, timeline, root cause investigation, and proposed solutions. Organizes findings into ./docs/case-studies/issue-{id}/ directory. Only supported for --tool claude.',
|
|
282
282
|
default: false,
|
|
283
283
|
})
|
|
284
|
+
.option('prompt-playwright-mcp', {
|
|
285
|
+
type: 'boolean',
|
|
286
|
+
description: 'Enable Playwright MCP browser automation hints in system prompt (enabled by default, only takes effect if Playwright MCP is installed). Use --no-prompt-playwright-mcp to disable. Only supported for --tool claude.',
|
|
287
|
+
default: true,
|
|
288
|
+
})
|
|
284
289
|
.parserConfiguration({
|
|
285
290
|
'boolean-negation': true,
|
|
286
291
|
})
|
package/src/solve.mjs
CHANGED
|
@@ -58,7 +58,7 @@ const { processAutoContinueForIssue } = autoContinue;
|
|
|
58
58
|
const repository = await import('./solve.repository.lib.mjs');
|
|
59
59
|
const { setupTempDirectory, cleanupTempDirectory } = repository;
|
|
60
60
|
const results = await import('./solve.results.lib.mjs');
|
|
61
|
-
const { cleanupClaudeFile, showSessionSummary, verifyResults } = results;
|
|
61
|
+
const { cleanupClaudeFile, showSessionSummary, verifyResults, buildClaudeResumeCommand } = results;
|
|
62
62
|
const claudeLib = await import('./claude.lib.mjs');
|
|
63
63
|
const { executeClaude } = claudeLib;
|
|
64
64
|
|
|
@@ -828,14 +828,18 @@ try {
|
|
|
828
828
|
// Default to Claude
|
|
829
829
|
// Check for Playwright MCP availability if using Claude tool
|
|
830
830
|
if (argv.tool === 'claude' || !argv.tool) {
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
831
|
+
// If flag is true (default), check if Playwright MCP is actually available
|
|
832
|
+
if (argv.promptPlaywrightMcp) {
|
|
833
|
+
const { checkPlaywrightMcpAvailability } = claudeLib;
|
|
834
|
+
const playwrightMcpAvailable = await checkPlaywrightMcpAvailability();
|
|
835
|
+
if (playwrightMcpAvailable) {
|
|
836
|
+
await log('š Playwright MCP detected - enabling browser automation hints', { verbose: true });
|
|
837
|
+
} else {
|
|
838
|
+
await log('ā¹ļø Playwright MCP not detected - browser automation hints will be disabled', { verbose: true });
|
|
839
|
+
argv.promptPlaywrightMcp = false;
|
|
840
|
+
}
|
|
836
841
|
} else {
|
|
837
|
-
await log('ā¹ļø Playwright MCP
|
|
838
|
-
argv.promptPlaywrightMcp = false;
|
|
842
|
+
await log('ā¹ļø Playwright MCP explicitly disabled via --no-prompt-playwright-mcp', { verbose: true });
|
|
839
843
|
}
|
|
840
844
|
}
|
|
841
845
|
const claudeResult = await executeClaude({
|
|
@@ -886,12 +890,35 @@ try {
|
|
|
886
890
|
await log('\nā USAGE LIMIT REACHED!');
|
|
887
891
|
await log(' The AI tool has reached its usage limit.');
|
|
888
892
|
|
|
893
|
+
// Always show manual resume command in console so users can resume after limit resets
|
|
894
|
+
if (sessionId) {
|
|
895
|
+
const resetTime = global.limitResetTime;
|
|
896
|
+
await log('');
|
|
897
|
+
await log(`š Working directory: ${tempDir}`);
|
|
898
|
+
await log(`š Session ID: ${sessionId}`);
|
|
899
|
+
if (resetTime) {
|
|
900
|
+
await log(`ā° Limit resets at: ${resetTime}`);
|
|
901
|
+
}
|
|
902
|
+
await log('');
|
|
903
|
+
// Show claude resume command only for --tool claude (or default)
|
|
904
|
+
// Uses the (cd ... && claude --resume ...) pattern for a fully copyable, executable command
|
|
905
|
+
const toolForResume = argv.tool || 'claude';
|
|
906
|
+
if (toolForResume === 'claude') {
|
|
907
|
+
const claudeResumeCmd = buildClaudeResumeCommand({ tempDir, sessionId, model: argv.model });
|
|
908
|
+
await log('š” To continue this session in Claude Code interactive mode:');
|
|
909
|
+
await log('');
|
|
910
|
+
await log(` ${claudeResumeCmd}`);
|
|
911
|
+
await log('');
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
|
|
889
915
|
// If --attach-logs is enabled and we have a PR, attach logs with usage limit details
|
|
890
916
|
if (shouldAttachLogs && sessionId && prNumber) {
|
|
891
917
|
await log('\nš Attaching logs to Pull Request...');
|
|
892
918
|
try {
|
|
893
|
-
// Build resume command
|
|
894
|
-
const
|
|
919
|
+
// Build Claude CLI resume command
|
|
920
|
+
const tool = argv.tool || 'claude';
|
|
921
|
+
const resumeCommand = tool === 'claude' ? buildClaudeResumeCommand({ tempDir, sessionId, model: argv.model }) : null;
|
|
895
922
|
const logUploadSuccess = await attachLogToGitHub({
|
|
896
923
|
logFile: getLogFile(),
|
|
897
924
|
targetType: 'pr',
|
|
@@ -921,7 +948,11 @@ try {
|
|
|
921
948
|
// Fallback: Post simple failure comment if logs are not attached
|
|
922
949
|
try {
|
|
923
950
|
const resetTime = global.limitResetTime;
|
|
924
|
-
|
|
951
|
+
// Build Claude CLI resume command
|
|
952
|
+
const tool = argv.tool || 'claude';
|
|
953
|
+
const resumeCmd = tool === 'claude' ? buildClaudeResumeCommand({ tempDir, sessionId, model: argv.model }) : null;
|
|
954
|
+
const resumeSection = resumeCmd ? `To resume after the limit resets, use:\n\`\`\`bash\n${resumeCmd}\n\`\`\`` : `Session ID: \`${sessionId}\``;
|
|
955
|
+
const failureComment = resetTime ? `ā **Usage Limit Reached**\n\nThe AI tool has reached its usage limit. The limit will reset at: **${resetTime}**\n\n${resumeSection}` : `ā **Usage Limit Reached**\n\nThe AI tool has reached its usage limit. Please wait for the limit to reset.\n\n${resumeSection}`;
|
|
925
956
|
|
|
926
957
|
const commentResult = await $`gh pr comment ${prNumber} --repo ${owner}/${repo} --body ${failureComment}`;
|
|
927
958
|
if (commentResult.code === 0) {
|
|
@@ -940,8 +971,9 @@ try {
|
|
|
940
971
|
if (shouldAttachLogs && sessionId) {
|
|
941
972
|
await log('\nš Attaching logs to Pull Request (auto-continue mode)...');
|
|
942
973
|
try {
|
|
943
|
-
// Build resume command
|
|
944
|
-
const
|
|
974
|
+
// Build Claude CLI resume command
|
|
975
|
+
const tool = argv.tool || 'claude';
|
|
976
|
+
const resumeCommand = tool === 'claude' ? buildClaudeResumeCommand({ tempDir, sessionId, model: argv.model }) : null;
|
|
945
977
|
const logUploadSuccess = await attachLogToGitHub({
|
|
946
978
|
logFile: getLogFile(),
|
|
947
979
|
targetType: 'pr',
|
|
@@ -986,7 +1018,10 @@ try {
|
|
|
986
1018
|
return `${days}:${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`;
|
|
987
1019
|
};
|
|
988
1020
|
|
|
989
|
-
|
|
1021
|
+
// Build Claude CLI resume command
|
|
1022
|
+
const tool = argv.tool || 'claude';
|
|
1023
|
+
const resumeCmd = tool === 'claude' ? buildClaudeResumeCommand({ tempDir, sessionId, model: argv.model }) : null;
|
|
1024
|
+
const waitingComment = `ā³ **Usage Limit Reached - Waiting to Continue**\n\nThe AI tool has reached its usage limit. Auto-continue is enabled with \`--auto-continue-on-limit-reset\`.\n\n**Reset time:** ${global.limitResetTime}\n**Wait time:** ${formatWaitTime(waitMs)} (days:hours:minutes:seconds)\n\nThe session will automatically resume when the limit resets.\n\nSession ID: \`${sessionId}\`${resumeCmd ? `\n\nTo resume manually:\n\`\`\`bash\n${resumeCmd}\n\`\`\`` : ''}`;
|
|
990
1025
|
|
|
991
1026
|
const commentResult = await $`gh pr comment ${prNumber} --repo ${owner}/${repo} --body ${waitingComment}`;
|
|
992
1027
|
if (commentResult.code === 0) {
|
|
@@ -1001,12 +1036,25 @@ try {
|
|
|
1001
1036
|
}
|
|
1002
1037
|
|
|
1003
1038
|
if (!success) {
|
|
1039
|
+
// Show claude resume command only for --tool claude (or default) on failure
|
|
1040
|
+
// Uses the (cd ... && claude --resume ...) pattern for a fully copyable, executable command
|
|
1041
|
+
const toolForFailure = argv.tool || 'claude';
|
|
1042
|
+
if (sessionId && toolForFailure === 'claude') {
|
|
1043
|
+
const claudeResumeCmd = buildClaudeResumeCommand({ tempDir, sessionId, model: argv.model });
|
|
1044
|
+
await log('');
|
|
1045
|
+
await log('š” To continue this session in Claude Code interactive mode:');
|
|
1046
|
+
await log('');
|
|
1047
|
+
await log(` ${claudeResumeCmd}`);
|
|
1048
|
+
await log('');
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1004
1051
|
// If --attach-logs is enabled and we have a PR, attach failure logs before exiting
|
|
1005
1052
|
if (shouldAttachLogs && sessionId && global.createdPR && global.createdPR.number) {
|
|
1006
1053
|
await log('\nš Attaching failure logs to Pull Request...');
|
|
1007
1054
|
try {
|
|
1008
|
-
// Build resume command
|
|
1009
|
-
const
|
|
1055
|
+
// Build Claude CLI resume command
|
|
1056
|
+
const tool = argv.tool || 'claude';
|
|
1057
|
+
const resumeCommand = sessionId && tool === 'claude' ? buildClaudeResumeCommand({ tempDir, sessionId, model: argv.model }) : null;
|
|
1010
1058
|
const logUploadSuccess = await attachLogToGitHub({
|
|
1011
1059
|
logFile: getLogFile(),
|
|
1012
1060
|
targetType: 'pr',
|
|
@@ -31,6 +31,12 @@ const { sanitizeLogContent, attachLogToGitHub } = githubLib;
|
|
|
31
31
|
const autoContinue = await import('./solve.auto-continue.lib.mjs');
|
|
32
32
|
const { autoContinueWhenLimitResets } = autoContinue;
|
|
33
33
|
|
|
34
|
+
// Import Claude-specific command builders
|
|
35
|
+
// These are used to generate copy-pasteable Claude CLI resume commands for users
|
|
36
|
+
// Pattern: (cd "/tmp/gh-issue-solver-..." && claude --resume <session-id>)
|
|
37
|
+
const claudeCommandBuilder = await import('./claude.command-builder.lib.mjs');
|
|
38
|
+
export const { buildClaudeResumeCommand, buildClaudeInitialCommand } = claudeCommandBuilder;
|
|
39
|
+
|
|
34
40
|
// Import error handling functions
|
|
35
41
|
// const errorHandlers = await import('./solve.error-handlers.lib.mjs'); // Not currently used
|
|
36
42
|
// Import Sentry integration
|
|
@@ -352,37 +358,44 @@ export const showSessionSummary = async (sessionId, limitReached, argv, issueUrl
|
|
|
352
358
|
const absoluteLogPath = path.resolve(getLogFile());
|
|
353
359
|
await log(`ā
Complete log file: ${absoluteLogPath}`);
|
|
354
360
|
|
|
361
|
+
// Show claude resume command only for --tool claude (or default)
|
|
362
|
+
// This allows users to investigate, resume, see context, and more
|
|
363
|
+
// Uses the (cd ... && claude --resume ...) pattern for a fully copyable, executable command
|
|
364
|
+
const tool = argv.tool || 'claude';
|
|
365
|
+
if (tool === 'claude') {
|
|
366
|
+
// Build the Claude CLI resume command using the command builder
|
|
367
|
+
const claudeResumeCmd = buildClaudeResumeCommand({ tempDir, sessionId, model: argv.model });
|
|
368
|
+
|
|
369
|
+
await log('');
|
|
370
|
+
await log('š” To continue this session in Claude Code interactive mode:');
|
|
371
|
+
await log('');
|
|
372
|
+
await log(` ${claudeResumeCmd}`);
|
|
373
|
+
await log('');
|
|
374
|
+
}
|
|
375
|
+
|
|
355
376
|
if (limitReached) {
|
|
356
|
-
await log('
|
|
377
|
+
await log('ā° LIMIT REACHED DETECTED!');
|
|
357
378
|
|
|
358
379
|
if (argv.autoContinueOnLimitReset && global.limitResetTime) {
|
|
359
380
|
await log(`\nš AUTO-CONTINUE ON LIMIT RESET ENABLED - Will resume at ${global.limitResetTime}`);
|
|
360
381
|
await autoContinueWhenLimitResets(issueUrl, sessionId, argv, shouldAttachLogs);
|
|
361
382
|
} else {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
await log(`./solve.mjs "${issueUrl}" --resume ${sessionId}`);
|
|
366
|
-
|
|
367
|
-
if (global.limitResetTime) {
|
|
368
|
-
await log(`\nš” Or enable auto-continue-on-limit-reset to wait until ${global.limitResetTime}:\n`);
|
|
369
|
-
await log(`./solve.mjs "${issueUrl}" --resume ${sessionId} --auto-continue-on-limit-reset`);
|
|
370
|
-
}
|
|
383
|
+
if (global.limitResetTime) {
|
|
384
|
+
await log(`\nā° Limit resets at: ${global.limitResetTime}`);
|
|
385
|
+
}
|
|
371
386
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
387
|
+
await log('\nš” After the limit resets, resume using the Claude command above.');
|
|
388
|
+
|
|
389
|
+
if (argv.autoCleanup !== false) {
|
|
390
|
+
await log('');
|
|
391
|
+
await log('ā ļø Note: Temporary directory will be automatically cleaned up.');
|
|
375
392
|
await log(' To keep the directory for debugging or resuming, use --no-auto-cleanup');
|
|
376
393
|
}
|
|
377
394
|
}
|
|
378
395
|
} else {
|
|
379
|
-
// Show
|
|
380
|
-
if (argv.autoCleanup
|
|
381
|
-
await log('
|
|
382
|
-
await log(` (cd ${tempDir} && claude --resume ${sessionId})`);
|
|
383
|
-
await log('');
|
|
384
|
-
} else {
|
|
385
|
-
await log('\nā ļø Note: Temporary directory will be automatically cleaned up.');
|
|
396
|
+
// Show note about auto-cleanup only when enabled
|
|
397
|
+
if (argv.autoCleanup !== false) {
|
|
398
|
+
await log('ā¹ļø Note: Temporary directory will be automatically cleaned up.');
|
|
386
399
|
await log(' To keep the directory for debugging or resuming, use --no-auto-cleanup');
|
|
387
400
|
}
|
|
388
401
|
}
|
package/src/solve.watch.lib.mjs
CHANGED
|
@@ -400,15 +400,19 @@ export const watchForFeedback = async params => {
|
|
|
400
400
|
|
|
401
401
|
// Check for Playwright MCP availability if using Claude tool
|
|
402
402
|
if (argv.tool === 'claude' || !argv.tool) {
|
|
403
|
-
|
|
404
|
-
if (
|
|
405
|
-
|
|
406
|
-
|
|
403
|
+
// If flag is true (default), check if Playwright MCP is actually available
|
|
404
|
+
if (argv.promptPlaywrightMcp) {
|
|
405
|
+
const playwrightMcpAvailable = await checkPlaywrightMcpAvailability();
|
|
406
|
+
if (playwrightMcpAvailable) {
|
|
407
|
+
await log('š Playwright MCP detected - enabling browser automation hints', { verbose: true });
|
|
408
|
+
} else {
|
|
409
|
+
await log('ā¹ļø Playwright MCP not detected - browser automation hints will be disabled', {
|
|
410
|
+
verbose: true,
|
|
411
|
+
});
|
|
412
|
+
argv.promptPlaywrightMcp = false;
|
|
413
|
+
}
|
|
407
414
|
} else {
|
|
408
|
-
await log('ā¹ļø Playwright MCP
|
|
409
|
-
verbose: true,
|
|
410
|
-
});
|
|
411
|
-
argv.promptPlaywrightMcp = false;
|
|
415
|
+
await log('ā¹ļø Playwright MCP explicitly disabled via --no-prompt-playwright-mcp', { verbose: true });
|
|
412
416
|
}
|
|
413
417
|
}
|
|
414
418
|
|