Skip to content

feat(namegen): deterministic worktree names (ccw-<owner>-<repo>-<shorthash6>)#48

Merged
tqer39 merged 13 commits into
mainfrom
worktree-jolly-lion-bf9c
Apr 25, 2026
Merged

feat(namegen): deterministic worktree names (ccw-<owner>-<repo>-<shorthash6>)#48
tqer39 merged 13 commits into
mainfrom
worktree-jolly-lion-bf9c

Conversation

@tqer39

@tqer39 tqer39 commented Apr 25, 2026

Copy link
Copy Markdown
Owner

Summary

  • ランダムスラグ (quick-falcon-7bd2) を、リポジトリが一目で分かる決定論的形式 ccw-<owner>-<repo>-<shorthash6> (例: ccw-tqer39-ccw-cli-a3f2b1) に置換しました。Claude Code のセッション名がディレクトリと 1:1 で揃うため、複数 worktree 並走時の取り違いが解消されます。
  • internal/gitx/ParseOriginURL (SSH/HTTPS/ssh:///git://.git 除去、GitLab nested は末尾 2 segment)、OriginURLDefaultBranch (origin/HEADmainmaster フォールバック)、ShortHash を追加。internal/namegen/Generate(mainRepo) を中心に再構成し、衝突は -2,-3,… で回避 (cap 99)、origin 未設定時は local/basename にフォールバックします。
  • 設計書 docs/superpowers/specs/2026-04-25-deterministic-worktree-name-design.md と実装計画 docs/superpowers/plans/2026-04-25-deterministic-worktree-name.md を同梱。README EN/JA の Naming convention セクションも刷新しました。
  • 派生作業として internal/picker/*_test.go の bubbletea v2 / lipgloss v2 互換性破損を別コミットで修復。pinact が自動正規化した workflow の version コメントも独立 chore コミットに分離しています。

Test Plan

  • go test ./... (209 pass / 14 packages)
  • go vet ./... clean
  • go build ./cmd/ccw succeeds; ccw -h / -v 表示確認
  • lefthook run pre-commit --all-files 全 11 hook green
  • CI (GitHub Actions) で同等 lint / test が通ることを確認
  • 実環境で ccw -n を実行し .claude/worktrees/ccw-tqer39-ccw-cli-<sha>/ が生成されること、Claude Code セッション名が一致することを目視確認

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Updated naming convention documentation describing the new deterministic session naming format and collision handling.
  • New Features

    • Worktree sessions now generate deterministic names formatted as ccw-<owner>-<repo>-<shorthash6>, derived from git repository information and the default branch's short commit hash, replacing random slug generation.
  • Chores

    • Enhanced error reporting for session creation failures.

tqer39 and others added 11 commits April 25, 2026 19:13
セッション名から「どの repo の、どの base commit から切ったか」が
判別できるよう、ランダム slug を origin owner/repo + default branch の
short SHA に置き換える設計。
10 タスク構成 (TDD): gitx 拡張 (Origin/Branch/ShortHash/ParseOriginURL) →
namegen 全置換 (normalize/buildName/Generate) → cmd/ccw 連携 → README 更新。
f783ee1 (bubbletea v2 へのアップグレード) で picker テストが下記により
ビルド失敗していた:

- view_test.go: m.View() の戻り値が tea.View 構造体に変更
  → m.View().Content (string) を参照
- style_test.go: lipgloss v2 で ColorProfile()/SetColorProfile() および
  termenv 直接参照が削除
  → プロファイル強制を削除(lipgloss v2 は Render 段階で常に ANSI を返す)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…po>-<shorthash6>

ランダム slug Generate() を Generate(mainRepo) に置換。
- normalize: lowercase + [a-z0-9-] + dash 圧縮 + trim
- buildName: ccw-<owner>-<repo>-<shorthash> の合成、衝突時 -N 付与(cap 99)
- Generate: gitx (OriginURL / DefaultBranch / ShortHash) + filesystem ベースの
  衝突検出。フェイク差し替え可能(テスト用)
- origin 未設定時は owner=local、repo=basename にフォールバック
- cmd/ccw/main.go の 2 箇所をエラー対応に更新
…ash6>

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Addresses the final code review of the deterministic-worktree-name branch:

- takenNames now unions .claude/worktrees entries with `git worktree list`
  basenames (spec required both; previously only the directory was checked).
- Adds worktreeListFn hook so namegen tests stay hermetic.
- Adds TestGenerate_CollisionWithGitWorktree and TestGenerate_ShortHashError
  to cover paths the previous suite never exercised.
- Adds ssh:// and git:// cases to TestParseOriginURL.
- main.go now appends a hint to the Generate failure message pointing at the
  branch / origin/HEAD remediation called out in the spec.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 25, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@tqer39 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 57 minutes and 30 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 57 minutes and 30 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5c016d23-df18-4287-99e2-96555f90d3ac

📥 Commits

Reviewing files that changed from the base of the PR and between 61f8c16 and b07e63e.

📒 Files selected for processing (2)
  • internal/gitx/branch_test.go
  • internal/picker/style_test.go
📝 Walkthrough

Walkthrough

This PR implements deterministic worktree naming by replacing random slug generation with a systematic format ccw-<owner>-<repo>-<shorthash6>. It adds git helper functions to extract owner/repo from origin URLs, resolve default branches, and compute short hashes, refactors the name generator to accept repository context with error handling, detects naming collisions with numeric suffixes, updates CLI call sites, and synchronizes documentation across English and Japanese READMEs and design specs.

Changes

Cohort / File(s) Summary
Workflow version pinning
.github/workflows/ci.yml, .github/workflows/release.yml
Minor version comment updates for GitHub Actions (v7v7.0.1, v3v3.1.1); no functional workflow changes.
Documentation updates
README.md, docs/README.ja.md
Updates worktree naming convention examples from unspecified format to explicit ccw-<owner>-<repo>-<shorthash6> derived from git origin and branch tip; documents collision handling via numeric suffixes.
Design and implementation plan
docs/superpowers/plans/2026-04-25-deterministic-worktree-name.md, docs/superpowers/specs/2026-04-25-deterministic-worktree-name-design.md
Adds comprehensive documentation specs and implementation plan detailing origin URL parsing, default branch resolution, short hash computation, collision detection algorithm, API shape changes, and test coverage requirements.
Git helper utilities
internal/gitx/branch.go, internal/gitx/branch_test.go, internal/gitx/origin.go, internal/gitx/origin_test.go
Introduces new exported functions: DefaultBranch (resolves via origin/HEAD, falls back to main/master), ShortHash (computes abbreviated commit hash), ParseOriginURL (extracts owner/repo from SSH/HTTPS URLs), and OriginURL (retrieves configured origin); comprehensive table-driven tests for URL variants and error cases.
Name generation refactor
internal/namegen/namegen.go, internal/namegen/namegen_test.go
Shifts from random adjective/noun generation to deterministic ccw-<owner>-<repo>-<shorthash6> format; Generate() signature changes to Generate(mainRepo string) (string, error); adds collision detection using worktree directories and git worktree list, numeric suffix appending (-2 through -99), normalization of owner/repo/hash to slug-safe tokens, and local fallback when origin is unset; test suite rewritten with table-driven helpers and faked git functions.
CLI integration
cmd/ccw/main.go
Updates two call sites (run and runPicker) to pass mainRepo to namegen.Generate(); adds error handling with user-friendly diagnostic message suggesting git remote set-head origin -a or ensuring main/master exists; exits with code 1 on name generation failure.

Sequence Diagram

sequenceDiagram
    participant CLI as CLI (main.go)
    participant NameGen as Namegen
    participant GitX as GitX Helpers
    participant Repo as Repository
    participant FS as Filesystem

    CLI->>NameGen: Generate(mainRepo)
    activate NameGen
    
    NameGen->>GitX: OriginURL(mainRepo)
    GitX->>Repo: git config --get remote.origin.url
    Repo-->>GitX: origin URL / empty
    GitX-->>NameGen: URL or empty string
    
    alt Origin exists
        NameGen->>GitX: ParseOriginURL(url)
        GitX-->>NameGen: owner, repo, error?
    else Origin missing
        NameGen-->>NameGen: Use "local" as owner
    end
    
    NameGen->>GitX: DefaultBranch(mainRepo)
    GitX->>Repo: git symbolic-ref refs/remotes/origin/HEAD
    alt origin/HEAD set
        Repo-->>GitX: default branch
    else Try fallbacks
        GitX->>Repo: git rev-parse --verify main/master
        Repo-->>GitX: ref exists
    end
    GitX-->>NameGen: branch name or error
    
    NameGen->>GitX: ShortHash(mainRepo, branch, 6)
    GitX->>Repo: git rev-parse --short=6 branch
    Repo-->>GitX: short hash
    GitX-->>NameGen: hash
    
    NameGen->>NameGen: normalize(owner, repo, hash)<br/>→ slug-safe tokens
    NameGen->>NameGen: baseVersion = ccw-{owner}-{repo}-{hash}
    
    NameGen->>FS: ls .claude/worktrees/
    FS-->>NameGen: existing names
    
    NameGen->>Repo: git worktree list --porcelain
    Repo-->>NameGen: worktree basenames
    
    NameGen->>NameGen: buildName(baseVersion)<br/>check collisions,<br/>append -2, -3, etc.
    
    NameGen-->>CLI: final name or error
    deactivate NameGen
    
    alt Success
        CLI->>Repo: git worktree add ...
    else Error
        CLI-->>CLI: Print error hint
        CLI-->>CLI: Exit 1
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • PR #4: Updates cmd/ccw/main.go skeleton with the new namegen.Generate(mainRepo) call sites and error handling introduced in this PR.
  • PR #5: Extends internal/gitx utilities that form the foundation for the origin/branch/hash helpers added here.
  • PR #43: Prior changes to name generation and call sites that are refactored and superseded by this deterministic naming implementation.

Poem

🐰 A hop through hashes, owner and repo,
No more random slugs in the naming flow!
Deterministic paths from git's remote head,
Collisions resolved with numbers instead.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: replacing random worktree names with deterministic ones in the format ccw---.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch worktree-jolly-lion-bf9c

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmd/ccw/main.go`:
- Around line 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.

In `@docs/superpowers/plans/2026-04-25-deterministic-worktree-name.md`:
- Around line 437-457: The test case list contains a stale expectation for
normalize: the entry {"repo.git", "repo"} is incorrect because
normalize("repo.git") yields "repo-git"; update the test cases in the cases
slice (used by the t.Run loop) by either removing the {"repo.git", "repo"} line
or changing its expected value to {"repo.git", "repo-git"} so it matches the
implemented normalize function.

In `@docs/superpowers/specs/2026-04-25-deterministic-worktree-name-design.md`:
- Around line 188-200: The parenthetical claiming "normalize 単独でも `.` は `-` 置換 →
連続圧縮 → trim で消える" is incorrect: normalize("repo.git") => "repo-git" and the
interior dash is not removed by Trim; update the text to either remove that
parenthetical or replace it with a short clarification that ParseOriginURL must
strip a trailing `.git` before calling normalize, referencing the normalize
function and ParseOriginURL so readers know the implementation relies on
ParseOriginURL to remove `.git`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 119acbb3-afb8-4e03-b052-164eeae25873

📥 Commits

Reviewing files that changed from the base of the PR and between d10a8ee and d02452c.

📒 Files selected for processing (15)
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • README.md
  • cmd/ccw/main.go
  • docs/README.ja.md
  • docs/superpowers/plans/2026-04-25-deterministic-worktree-name.md
  • docs/superpowers/specs/2026-04-25-deterministic-worktree-name-design.md
  • internal/gitx/branch.go
  • internal/gitx/branch_test.go
  • internal/gitx/origin.go
  • internal/gitx/origin_test.go
  • internal/namegen/namegen.go
  • internal/namegen/namegen_test.go
  • internal/picker/style_test.go
  • internal/picker/view_test.go
💤 Files with no reviewable changes (1)
  • internal/picker/style_test.go

Comment thread cmd/ccw/main.go
Comment on lines 74 to +79
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
}

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.

Comment on lines +437 to +457
{"Anthropic", "anthropic"},
{"My Org", "my-org"},
{"_underscore_", "underscore"},
{"--double--dash--", "double-dash"},
{"repo.git", "repo"},
{"a..b..c", "a-b-c"},
{"", ""},
{"a", "a"},
{"123", "123"},
{"日本語repo", "repo"},
}
for _, tc := range cases {
t.Run(tc.in, func(t *testing.T) {
got := normalize(tc.in)
if got != tc.want {
t.Errorf("normalize(%q) = %q, want %q", tc.in, got, tc.want)
}
})
}
}
```

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

Stale test expectation: {"repo.git", "repo"} would fail the implemented normalize.

normalize("repo.git") produces repo-git, not repo — the . is replaced by -, and trim only removes leading/trailing dashes, not the interior one. The actual test in internal/namegen/namegen_test.go correctly omits this case (replaced by {"a..b..c", "a-b-c"}). Since this plan was already executed, this is just a stale aside that future readers might use as a reference; consider deleting the line or aligning it with the implemented test set.

📝 Proposed fix
-  {"repo.git", "repo"},
   {"a..b..c", "a-b-c"},
📝 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
{"Anthropic", "anthropic"},
{"My Org", "my-org"},
{"_underscore_", "underscore"},
{"--double--dash--", "double-dash"},
{"repo.git", "repo"},
{"a..b..c", "a-b-c"},
{"", ""},
{"a", "a"},
{"123", "123"},
{"日本語repo", "repo"},
}
for _, tc := range cases {
t.Run(tc.in, func(t *testing.T) {
got := normalize(tc.in)
if got != tc.want {
t.Errorf("normalize(%q) = %q, want %q", tc.in, got, tc.want)
}
})
}
}
```
{"Anthropic", "anthropic"},
{"My Org", "my-org"},
{"_underscore_", "underscore"},
{"--double--dash--", "double-dash"},
{"a..b..c", "a-b-c"},
{"", ""},
{"a", "a"},
{"123", "123"},
{"日本語repo", "repo"},
}
for _, tc := range cases {
t.Run(tc.in, func(t *testing.T) {
got := normalize(tc.in)
if got != tc.want {
t.Errorf("normalize(%q) = %q, want %q", tc.in, got, tc.want)
}
})
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/superpowers/plans/2026-04-25-deterministic-worktree-name.md` around
lines 437 - 457, The test case list contains a stale expectation for normalize:
the entry {"repo.git", "repo"} is incorrect because normalize("repo.git") yields
"repo-git"; update the test cases in the cases slice (used by the t.Run loop) by
either removing the {"repo.git", "repo"} line or changing its expected value to
{"repo.git", "repo-git"} so it matches the implemented normalize function.

Comment on lines +188 to +200
- `normalize` (segment 単位、slash を含まない入力前提):
- `Anthropic` → `anthropic`
- `My Org` → `my-org`
- `_underscore_` → `underscore`
- `--double--dash--` → `double-dash`
- `repo.git` → `repo`(`.git` は `ParseOriginURL` で除去済み前提だが、normalize 単独でも `.` は `-` 置換 → 連続圧縮 → trim で消える)
- 空文字 → 空文字
- `buildName`:
- `("tqer39", "ccw-cli", "a3f2b1", {})` → `"ccw-tqer39-ccw-cli-a3f2b1"`
- 衝突 1 個 → `-2` 付与
- 衝突 2 個 → `-3` 付与
- 衝突 99 個まで → `-99` 付与、100 でエラー
- `Generate` (integration): `gitx` 関数を関数値で差し替え可能にして hermetic に

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

Minor: incorrect claim about normalize alone handling repo.git.

The parenthetical on line 193 — "normalize 単独でも .- 置換 → 連続圧縮 → trim で消える" — is not accurate. normalize("repo.git") yields repo-git: the . is replaced by -, but the resulting interior dash isn't removed by strings.Trim (which only strips leading/trailing dashes). The implementation correctly relies on ParseOriginURL stripping .git before normalize is called (matching the comment in internal/namegen/namegen.go line 23), so the design is sound — just this aside is misleading. Consider rewording or deleting the parenthetical to avoid future confusion.

📝 Proposed wording
-  - `repo.git` → `repo`(`.git` は `ParseOriginURL` で除去済み前提だが、normalize 単独でも `.` は `-` 置換 → 連続圧縮 → trim で消える)
+  - `repo.git` → `repo`(`.git` は `ParseOriginURL` で事前に除去される。normalize 単独で渡された場合は `repo-git` になる)
📝 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
- `normalize` (segment 単位、slash を含まない入力前提):
- `Anthropic``anthropic`
- `My Org``my-org`
- `_underscore_``underscore`
- `--double--dash--``double-dash`
- `repo.git``repo``.git``ParseOriginURL` で除去済み前提だが、normalize 単独でも `.``-` 置換 → 連続圧縮 → trim で消える
- 空文字 → 空文字
- `buildName`:
- `("tqer39", "ccw-cli", "a3f2b1", {})``"ccw-tqer39-ccw-cli-a3f2b1"`
- 衝突 1 個 → `-2` 付与
- 衝突 2 個 → `-3` 付与
- 衝突 99 個まで → `-99` 付与、100 でエラー
- `Generate` (integration): `gitx` 関数を関数値で差し替え可能にして hermetic に
- `normalize` (segment 単位、slash を含まない入力前提):
- `Anthropic``anthropic`
- `My Org``my-org`
- `_underscore_``underscore`
- `--double--dash--``double-dash`
- `repo.git``repo``.git``ParseOriginURL` で事前に除去される。normalize 単独で渡された場合は `repo-git` になる
- 空文字 → 空文字
- `buildName`:
- `("tqer39", "ccw-cli", "a3f2b1", {})``"ccw-tqer39-ccw-cli-a3f2b1"`
- 衝突 1 個 → `-2` 付与
- 衝突 2 個 → `-3` 付与
- 衝突 99 個まで → `-99` 付与、100 でエラー
- `Generate` (integration): `gitx` 関数を関数値で差し替え可能にして hermetic に
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/superpowers/specs/2026-04-25-deterministic-worktree-name-design.md`
around lines 188 - 200, The parenthetical claiming "normalize 単独でも `.` は `-` 置換
→ 連続圧縮 → trim で消える" is incorrect: normalize("repo.git") => "repo-git" and the
interior dash is not removed by Trim; update the text to either remove that
parenthetical or replace it with a short clarification that ParseOriginURL must
strip a trailing `.git` before calling normalize, referencing the normalize
function and ParseOriginURL so readers know the implementation relies on
ParseOriginURL to remove `.git`.

tqer39 and others added 2 commits April 26, 2026 03:48
Per project convention to keep code comments in English while user-facing
text and design docs stay in Japanese.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@tqer39 tqer39 merged commit 9d3dc6e into main Apr 25, 2026
8 checks passed
@tqer39 tqer39 deleted the worktree-jolly-lion-bf9c branch April 25, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant