claude-issue-solver 1.9.0 โ†’ 1.10.1

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 CHANGED
@@ -26,6 +26,7 @@ This CLI tool fetches an issue from your repo, creates a worktree, opens Claude
26
26
  $ claude-issue
27
27
 
28
28
  Open issues for my-project:
29
+ (2 issues with open PRs hidden)
29
30
 
30
31
  ? Select an issue to solve:
31
32
  โฏ #42 Add dark mode support
@@ -45,11 +46,13 @@ Open issues for my-project:
45
46
 
46
47
  ## Features
47
48
 
48
- - ๐ŸŽฏ **Interactive issue selection** - Lists open issues with arrow-key navigation
49
+ - ๐ŸŽฏ **Interactive issue selection** - Lists open issues with arrow-key navigation (hides issues with open PRs)
50
+ - โœจ **Create and solve** - Create new issues and start solving them immediately
49
51
  - ๐ŸŒฟ **Worktree isolation** - Each issue gets its own worktree, work on multiple issues in parallel
50
- - ๐Ÿค– **Automatic PR creation** - Creates a PR that closes the issue when merged
51
- - ๐Ÿ“ **Works with any repo** - Auto-detects project name from git remote
52
- - ๐Ÿ’ป **Opens in new terminal** - Keeps your current terminal free (supports iTerm2 and Terminal.app on macOS)
52
+ - ๐Ÿค– **Real-time PR creation** - Automatically creates/updates PR as Claude commits changes
53
+ - ๐Ÿงน **Smart cleanup** - Auto-clean merged PRs, close VS Code/terminal windows on macOS
54
+ - ๐Ÿ“ **Monorepo support** - Recursively copies all `.env*` files, symlinks `node_modules`
55
+ - ๐Ÿ’ป **Cross-platform terminals** - iTerm2, Terminal.app (macOS), gnome-terminal, xterm, konsole (Linux)
53
56
 
54
57
  ## Requirements
55
58
 
@@ -87,31 +90,60 @@ claude-issue 42
87
90
 
88
91
  # List open issues
89
92
  claude-issue list
93
+ claude-issue ls
94
+
95
+ # Create a new issue and solve it immediately
96
+ claude-issue new "Add dark mode support"
97
+ claude-issue new "Fix login bug" -b "Users can't login on mobile"
98
+ claude-issue new "Fix crash" -l bug -l priority
90
99
 
91
100
  # Create PR for a solved issue (if you skipped it earlier)
92
101
  claude-issue pr 42
93
102
 
94
- # Clean up worktree and branch after PR is merged
95
- claude-issue clean 42
96
-
97
- # Clean all worktrees (shows PR/issue status)
98
- claude-issue clean
103
+ # Clean up worktree and branch
104
+ claude-issue clean 42 # Clean specific issue
105
+ claude-issue clean # Interactive selection
106
+ claude-issue clean --all # Clean all worktrees (with confirmation)
107
+ claude-issue clean --merged # Auto-clean only merged PRs (no confirmation)
99
108
 
100
109
  # Navigate to a worktree or open its PR
101
- claude-issue go
110
+ claude-issue go # Interactive selection
111
+ claude-issue go 42 # Go to specific issue
102
112
 
103
113
  # Show help
104
114
  claude-issue --help
105
115
  ```
106
116
 
117
+ ## Commands Reference
118
+
119
+ | Command | Alias | Description |
120
+ |---------|-------|-------------|
121
+ | `claude-issue` | - | Interactive issue selection |
122
+ | `claude-issue <number>` | - | Solve specific issue |
123
+ | `claude-issue new <title>` | - | Create issue and solve it |
124
+ | `claude-issue list` | `ls` | List open issues |
125
+ | `claude-issue pr <number>` | - | Create PR for solved issue |
126
+ | `claude-issue clean [number]` | `rm` | Remove worktree and branch |
127
+ | `claude-issue go [number]` | - | Navigate to worktree |
128
+
129
+ ### Command Options
130
+
131
+ **`new` command:**
132
+ - `-b, --body <text>` - Issue description
133
+ - `-l, --label <name>` - Add label (can be used multiple times)
134
+
135
+ **`clean` command:**
136
+ - `-a, --all` - Clean all issue worktrees (with confirmation)
137
+ - `-m, --merged` - Clean only worktrees with merged PRs (no confirmation)
138
+
107
139
  ## How it works
108
140
 
109
141
  1. **Fetches issue** - Gets title and description from GitHub
110
142
  2. **Creates worktree** - Makes a new git worktree with branch `issue-{number}-{slug}`
111
- 3. **Sets up environment** - Copies `.env` files, symlinks `node_modules`
143
+ 3. **Sets up environment** - Recursively copies all `.env*` files, symlinks `node_modules`
112
144
  4. **Opens Claude** - Launches Claude Code in a new terminal with the issue as context
113
- 5. **Interactive session** - Claude stays open so you can ask for changes
114
- 6. **Creates PR** - When you exit, prompts to create a PR that closes the issue
145
+ 5. **Real-time PR creation** - Background watcher creates PR on first commit, pushes updates on subsequent commits
146
+ 6. **Interactive session** - Claude stays open so you can ask for changes
115
147
 
116
148
  ## Workflow
117
149
 
@@ -142,24 +174,65 @@ claude-issue --help
142
174
  โ”‚
143
175
  โ–ผ
144
176
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
145
- โ”‚ Create PR โ”‚
177
+ โ”‚ Auto-create PR โ”‚
146
178
  โ”‚ "Closes #42" โ”‚
147
179
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
148
180
  โ”‚
149
181
  โ–ผ
150
182
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
151
183
  โ”‚ claude-issue โ”‚
152
- โ”‚ clean 42 โ”‚
184
+ โ”‚ clean --merged โ”‚
153
185
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
154
186
  ```
155
187
 
188
+ ## Smart Features
189
+
190
+ ### Issue Filtering
191
+ When selecting issues, the tool automatically hides issues that already have open PRs from `issue-{number}-*` branches. A message shows how many were hidden.
192
+
193
+ ### PR Status Display
194
+ When cleaning, the tool shows the status of each worktree:
195
+ - `โœ“ PR merged` - Safe to clean
196
+ - `โ— PR open` - PR still under review
197
+ - `โœ— PR closed` - PR was closed without merging
198
+ - `โ— Issue closed` - Issue was closed
199
+ - `โ—‹ Issue open` - Issue still open
200
+
201
+ ### Orphaned Folder Cleanup
202
+ If a worktree folder exists but isn't registered in git (e.g., after a failed cleanup), the tool detects it and offers to remove it.
203
+
204
+ ### Auto-Close Windows (macOS)
205
+ When cleaning a worktree, the tool automatically closes related terminal windows (iTerm2/Terminal.app) and VS Code windows that have the worktree open.
206
+
207
+ ### Monorepo Support
208
+ The tool recursively finds and copies all `.env*` files from your project, preserving directory structure. This works great with turborepo and other monorepo setups where env files exist in subdirectories like `apps/myapp/.env.local`.
209
+
210
+ Skipped directories: `node_modules`, `.git`, `dist`, `build`, `.next`, `.turbo`
211
+
212
+ ### Branch Naming
213
+ Branches are named `issue-{number}-{slug}` where the slug is:
214
+ - Lowercase with hyphens
215
+ - Max 30 characters
216
+ - Bracket prefixes removed (e.g., `[Bug]` is stripped)
217
+ - Duplicate consecutive words removed (e.g., `fix-fix-bug` โ†’ `fix-bug`)
218
+
156
219
  ## Tips
157
220
 
158
- - Use `/exit` in Claude to end the session and trigger PR creation
159
- - Worktrees share the same `.git` so commits are visible in main repo
160
- - Run `claude-issue clean` after merging to clean up - it shows PR status (merged/open/closed)
161
- - You can work on multiple issues in parallel - each gets its own worktree
221
+ - PRs are created automatically when Claude makes commits - no need to wait until the end
222
+ - Use `claude-issue clean --merged` after merging PRs for quick cleanup
223
+ - Worktrees share the same `.git` so commits are visible in the main repo
224
+ - You can work on multiple issues in parallel - each gets its own worktree and terminal
162
225
  - Use `claude-issue go` to quickly navigate to worktrees or open PRs in browser
226
+ - The `go` command also offers options to open in Finder (macOS) or copy the cd command
227
+
228
+ ## Platform Support
229
+
230
+ | Feature | macOS | Linux |
231
+ |---------|-------|-------|
232
+ | New terminal window | iTerm2, Terminal.app | gnome-terminal, xterm, konsole |
233
+ | Auto-close terminals on clean | โœ“ | - |
234
+ | Auto-close VS Code on clean | โœ“ | - |
235
+ | Open in Finder | โœ“ | - |
163
236
 
164
237
  ## License
165
238
 
@@ -0,0 +1,4 @@
1
+ export declare function newCommand(title: string, options: {
2
+ body?: string;
3
+ label?: string[];
4
+ }): Promise<void>;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.newCommand = newCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const github_1 = require("../utils/github");
10
+ const solve_1 = require("./solve");
11
+ async function newCommand(title, options) {
12
+ const spinner = (0, ora_1.default)('Creating issue...').start();
13
+ const issueNumber = (0, github_1.createIssue)(title, options.body, options.label);
14
+ if (!issueNumber) {
15
+ spinner.fail('Failed to create issue');
16
+ console.log(chalk_1.default.dim('Make sure you have write access to this repository.'));
17
+ process.exit(1);
18
+ }
19
+ spinner.succeed(`Created issue #${issueNumber}`);
20
+ console.log(chalk_1.default.dim(`Title: ${title}\n`));
21
+ // Now solve it immediately
22
+ await (0, solve_1.solveCommand)(issueNumber);
23
+ }
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ const pr_1 = require("./commands/pr");
14
14
  const clean_1 = require("./commands/clean");
15
15
  const select_1 = require("./commands/select");
16
16
  const go_1 = require("./commands/go");
17
+ const new_1 = require("./commands/new");
17
18
  // eslint-disable-next-line @typescript-eslint/no-var-requires
18
19
  const packageJson = require('../package.json');
19
20
  const program = new commander_1.Command();
@@ -110,4 +111,13 @@ program
110
111
  }
111
112
  await (0, go_1.goCommand)(issueNumber);
112
113
  });
114
+ // New command - create issue and solve it
115
+ program
116
+ .command('new <title>')
117
+ .description('Create a new issue and immediately start solving it')
118
+ .option('-b, --body <body>', 'Issue description')
119
+ .option('-l, --label <label...>', 'Add labels to the issue')
120
+ .action(async (title, options) => {
121
+ await (0, new_1.newCommand)(title, options);
122
+ });
113
123
  program.parse();
@@ -8,6 +8,7 @@ export interface IssueListItem {
8
8
  number: number;
9
9
  title: string;
10
10
  }
11
+ export declare function createIssue(title: string, body?: string, labels?: string[]): number | null;
11
12
  export declare function getIssue(issueNumber: number): Issue | null;
12
13
  export declare function listIssues(limit?: number): IssueListItem[];
13
14
  export declare function createPullRequest(title: string, body: string, branch: string, base?: string): string;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createIssue = createIssue;
3
4
  exports.getIssue = getIssue;
4
5
  exports.listIssues = listIssues;
5
6
  exports.createPullRequest = createPullRequest;
@@ -7,6 +8,29 @@ exports.getIssueStatus = getIssueStatus;
7
8
  exports.getPRForBranch = getPRForBranch;
8
9
  exports.getIssuesWithOpenPRs = getIssuesWithOpenPRs;
9
10
  const child_process_1 = require("child_process");
11
+ function createIssue(title, body, labels) {
12
+ try {
13
+ let cmd = `gh issue create --title "${title.replace(/"/g, '\\"')}"`;
14
+ if (body) {
15
+ cmd += ` --body "${body.replace(/"/g, '\\"')}"`;
16
+ }
17
+ if (labels && labels.length > 0) {
18
+ for (const label of labels) {
19
+ cmd += ` --label "${label.replace(/"/g, '\\"')}"`;
20
+ }
21
+ }
22
+ const output = (0, child_process_1.execSync)(cmd, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
23
+ // Output is the issue URL, extract the number
24
+ const match = output.trim().match(/\/issues\/(\d+)$/);
25
+ if (match) {
26
+ return parseInt(match[1], 10);
27
+ }
28
+ return null;
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
10
34
  function getIssue(issueNumber) {
11
35
  try {
12
36
  const output = (0, child_process_1.execSync)(`gh issue view ${issueNumber} --json title,body,url`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-issue-solver",
3
- "version": "1.9.0",
3
+ "version": "1.10.1",
4
4
  "description": "Automatically solve GitHub issues using Claude Code",
5
5
  "main": "dist/index.js",
6
6
  "bin": {