Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
cache: true
- name: Run tests
run: go test ./... -race -coverprofile=coverage.out
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage
path: coverage.out
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:

- name: Mint Homebrew tap token
id: tap-token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
app-id: ${{ secrets.GHA_APP_CLIENT_ID }}
private-key: ${{ secrets.GHA_APP_PRIVATE_KEY }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ When ccw creates a new worktree, the worktree directory and the Claude Code sess
- Branch: `worktree-<name>`
- Session name: `<name>` (set via `claude -n <name>`)

`<name>` is generated like `quick-falcon-7bd2`. Renaming the session manually with `/rename` is fine — ccw does not track it, and `--continue` keys off the working directory so conversation restore is unaffected.
`<name>` is generated as `ccw-<owner>-<repo>-<shorthash6>` (e.g. `ccw-tqer39-ccw-cli-a3f2b1`). `<owner>` / `<repo>` come from the `origin` remote URL; `<shorthash6>` is the 6-char short SHA of the local default branch tip at creation time. When `origin` is unset, `<owner>` becomes `local` and `<repo>` is the directory basename. Duplicate names are disambiguated with `-2`, `-3`, … Renaming the session manually with `/rename` is fine — ccw does not track it, and `--continue` keys off the working directory so conversation restore is unaffected.

## 📦 Installation

Expand Down
12 changes: 10 additions & 2 deletions cmd/ccw/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,11 @@ func run(flags cli.Flags) int {
}

if flags.NewWorktree {
name := namegen.Generate()
name, err := namegen.Generate(mainRepo)
if err != nil {
ui.Error("generate worktree name: %v\nhint: ensure a 'main' or 'master' branch with at least one commit, or run `git remote set-head origin -a`", err)
return 1
}
Comment on lines 74 to +79

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Hint is too narrow for the error space, and duplicated at the picker call site.

namegen.Generate can fail for several distinct reasons (origin URL parse, default branch resolution, short hash, worktree enumeration, collision cap of 99, normalization). The current hint only addresses the default-branch case and may mislead users when the failure is e.g. a malformed origin URL, a missing tip commit, or a saturated collision suffix space. The same exact message is also duplicated at lines 102–106 in runPicker — worth extracting a helper and/or tailoring the hint to the underlying error category.

♻️ Suggested refactor — extract helper, log raw error
+func reportNameGenError(err error) {
+	ui.Error("generate worktree name: %v", err)
+	ui.Info("hint: verify `origin` URL (or unset it for local), that the default branch (origin/HEAD, main, or master) has at least one commit, and that .claude/worktrees does not already contain ccw-<owner>-<repo>-<hash>-{2..99}.")
+}
+
 func run(flags cli.Flags) int {
@@
 	if flags.NewWorktree {
-		name, err := namegen.Generate(mainRepo)
-		if err != nil {
-			ui.Error("generate worktree name: %v\nhint: ensure a 'main' or 'master' branch with at least one commit, or run `git remote set-head origin -a`", err)
-			return 1
-		}
+		name, err := namegen.Generate(mainRepo)
+		if err != nil {
+			reportNameGenError(err)
+			return 1
+		}
@@
 		case picker.ActionNew:
-			name, err := namegen.Generate(mainRepo)
-			if err != nil {
-				ui.Error("generate worktree name: %v\nhint: ensure a 'main' or 'master' branch with at least one commit, or run `git remote set-head origin -a`", err)
-				return 1
-			}
+			name, err := namegen.Generate(mainRepo)
+			if err != nil {
+				reportNameGenError(err)
+				return 1
+			}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if flags.NewWorktree {
name := namegen.Generate()
name, err := namegen.Generate(mainRepo)
if err != nil {
ui.Error("generate worktree name: %v\nhint: ensure a 'main' or 'master' branch with at least one commit, or run `git remote set-head origin -a`", err)
return 1
}
func reportNameGenError(err error) {
ui.Error("generate worktree name: %v", err)
ui.Info("hint: verify `origin` URL (or unset it for local), that the default branch (origin/HEAD, main, or master) has at least one commit, and that .claude/worktrees does not already contain ccw-<owner>-<repo>-<hash>-{2..99}.")
}
func run(flags cli.Flags) int {
if flags.NewWorktree {
name, err := namegen.Generate(mainRepo)
if err != nil {
reportNameGenError(err)
return 1
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/ccw/main.go` around lines 74 - 79, The current error handling around
namegen.Generate in the NewWorktree path logs a narrow, duplicated hint that can
mislead users; extract a small helper (e.g., reportNamegenError) used by the
NewWorktree branch and runPicker to format errors from namegen.Generate, surface
the raw error in the ui.Error message, and tailor the user hint based on error
categories (origin URL/parse, missing tip/default branch, collision cap,
worktree enumeration, normalization) rather than always suggesting the
default-branch fix; update calls to namegen.Generate to call the helper so both
sites share the same logic and include the raw error details for debugging while
giving a concise, category-specific hint.

code, err := claude.LaunchNew(mainRepo, name, preamble, flags.Passthrough)
if err != nil {
ui.Error("%v", err)
Expand All @@ -95,7 +99,11 @@ func runPicker(mainRepo string, passthrough []string, interactive bool) int {
case picker.ActionCancel:
return 0
case picker.ActionNew:
name := namegen.Generate()
name, err := namegen.Generate(mainRepo)
if err != nil {
ui.Error("generate worktree name: %v\nhint: ensure a 'main' or 'master' branch with at least one commit, or run `git remote set-head origin -a`", err)
return 1
}
code, err := claude.LaunchNew(mainRepo, name, "", passthrough)
if err != nil {
ui.Error("%v", err)
Expand Down
2 changes: 1 addition & 1 deletion docs/README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ ccw は新規 worktree を作るとき、worktree 名と Claude Code のセッ
- ブランチ: `worktree-<name>`
- セッション名: `<name>`(`claude -n <name>` で設定)

`<name>` は `quick-falcon-7bd2` のようにジェネレータが生成します。手動で `/rename` した場合も ccw は追跡しません。`--continue` は cwd 基準で動くので会話復元には影響しません
`<name>` は `ccw-<owner>-<repo>-<shorthash6>`(例: `ccw-tqer39-ccw-cli-a3f2b1`)形式で生成されます。`<owner>` / `<repo>` は `origin` remote の URL から抽出、`<shorthash6>` は作成時点のローカル default branch tip の short SHA です。`origin` が未設定の場合は `<owner>` が `local`、`<repo>` がディレクトリ basename になります。同名衝突は `-2`, `-3`, … で回避します。`/rename` で手動改名しても ccw 側は追跡しないため問題ありません(`--continue` は作業ディレクトリ基準で会話を復元します)

## 📦 インストール

Expand Down
Loading