feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496) - #516

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset
Jul 20, 2026
Merged

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496)#516
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 20, 2026

Copy link
Copy Markdown
Owner

概要

スキル表示名の human-in-the-loop 確定(ADR-0016 D11 / #476)で、一度確定した表示名・畳み込みグループを「解除(バラす)」する導線が無い問題(#496)を解消する。upsert(削除しない)設計で確定行が残り続け、機械デフォルトへ完全リセットできなかったギャップを埋める。

Closes#496

設計方針

「解除」= 対象 identity の Layer 3 確定行を DELETE して機械デフォルトへ戻す単一アクション。グループの全メンバー identity をまとめて送ることで「グループ解除(バラす)」と「確定リセット(表示名を戻す)」を同時に満たす。issue の案1(DELETE エンドポイント)を主軸に採用し、案3のメンバー個別分割 UI は作らない(ADR に残課題として明記)。

変更点

Backend

  • DELETE /skills/display-decisions を新設(identity 群指定で確定行を削除)。authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない確定行は冪等に無視)。リセット後の最新一覧を返す
  • repositories/skill.pydelete_by_identities(user_id 固定・ORM 削除)
  • schemasSkillDisplayResetRequest 追加 → make codegen-typesgenerated.ts 再生成

Web

  • utils/skillDisplay: isResettableGroup / buildResetIdentities(TDD)
  • hooks/useGitHubSkills: reset / resetting(TDD)
  • スキル一覧の確定済みチップに「解除」ボタン追加

Docs

  • ADR-0016 D11 に項 (g)(解除)と変更履歴を追記

テスト

  • backend: 5 ケース(401 / 422 / リセット反映 / グループ全バラし / 冪等)
  • web: util 5・hook 2 ケース(red→green で TDD)
  • E2E: 解除フロー 1 本

ローカル make ci green(backend 729 / web 389 / build OK)、E2E(github-link)8 passed。

レビュー観点

  • API 契約追加: body 付き DELETE の新設(generated.ts は同 PR に再生成済み)
  • 設計分岐: 削除ベースの全リセットを採用、メンバー個別分割 UI は未実装(残課題)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a reset option for confirmed GitHub skill display names.
    • Resetting restores machine-generated names and can ungroup related skills.
    • Reset buttons show progress states and are unavailable during other updates.
  • Bug Fixes

    • Reset operations are validated, idempotent, and preserve existing data when they fail.
  • Documentation

    • Documented the reset behavior, authorization, and fallback display rules.
  • Tests

    • Added coverage for authentication, validation, grouped skills, failures, and end-to-end reset behavior.

一度確定した表示名・畳み込みグループを機械デフォルトへ戻す導線が無く、
upsert(削除しない)設計で確定行が残り続け完全リセットできなかったギャップを埋める。
Backend:
- DELETE /skills/display-decisions を新設(identity 群指定で Layer 3 確定行を削除)。
authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない
確定行は冪等に無視)。リセット後の最新スキル一覧を返す
- repositories/skill.py に delete_by_identities を追加(user_id 固定・ORM 削除)
- schemas に SkillDisplayResetRequest を追加、make codegen-types で generated.ts 再生成
Web:
- utils/skillDisplay に isResettableGroup / buildResetIdentities を追加(TDD)
- useGitHubSkills に reset / resetting を追加(TDD)
- スキル一覧の確定済みチップに「解除」ボタンを追加。グループ全メンバーを
まとめて解除するため畳み込みも解ける
Docs:
- ADR-0016 D11 に項 (g)(解除)と変更履歴を追記
テスト: backend 5 ケース / web util 5・hook 2 ケース / E2E 解除フロー 1 本を追加
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 labels Jul 20, 2026
@coderabbitai

coderabbitaiBot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd3e8a7b-a58b-4e27-955e-c4e0ace210f1

📥 Commits

Reviewing files that changed from the base of the PR and between 5c9251a and 97b01f7.

📒 Files selected for processing (1)
  • web/src/components/github-link/SkillDisplaySection.tsx
📝 Walkthrough

Walkthrough

Adds an authenticated DELETE flow for resetting confirmed GitHub skill display decisions. The backend removes matching records and returns refreshed skills, while the generated client, hook, grouped UI controls, tests, and ADR support the reset behavior.

Changes

Skill display reset

Layer / File(s)Summary
Backend reset contract and deletion flow
backend/app/schemas/github_skill.py, backend/app/repositories/skill.py, backend/app/routers/github_link/endpoints.py, backend/tests/test_skill_display_api.py, docs/adr/0016-github-skill-inference.md
Adds the reset request schema, identity-based deletion, endpoint validation, refreshed skill responses, authorization/idempotency tests, and ADR documentation.
Generated client and hook integration
web/src/api/generated.ts, web/src/api/types.ts, web/src/api/githubLink.ts, web/src/hooks/useGitHubSkills.ts, web/src/hooks/useGitHubSkills.test.ts
Adds the DELETE API contract and wrapper, then exposes reset state and error-preserving reset behavior through useGitHubSkills.
Grouped reset controls and user-facing validation
web/src/utils/skillDisplay.ts, web/src/components/github-link/SkillDisplaySection.tsx, web/src/components/github-link/*.css, web/src/constants/messages.ts, web/src/utils/skillDisplay.test.ts, web/e2e/github-link.spec.ts
Determines resettable groups, builds member identities, renders disabled/in-progress reset controls, adds messages and styling, and verifies fallback display behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant Backend
User->>SkillDisplaySection: Click reset
SkillDisplaySection->>useGitHubSkills: Reset group identities
useGitHubSkills->>GitHubLinkAPI: Send DELETE request
GitHubLinkAPI->>Backend: Delete display decisions
Backend-->>GitHubLinkAPI: Return refreshed skills
GitHubLinkAPI-->>useGitHubSkills: Updated skill list
useGitHubSkills-->>SkillDisplaySection: Render machine defaults
Loading

Possibly related PRs

  • yusuke0610/devforge#495: Introduced the display-decision model and confirmation workflow extended by this reset flow.

Suggested labels:agent

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ Passed主要変更であるスキル表示名の確定解除機能を具体的に示しており、PR内容と一致しています。
Linked Issues check✅ PassedDELETE API、repo削除、UIの解除導線、生成型更新、テスト追加が #496 の要件を満たしています。
Out of Scope Changes check✅ Passedテスト、ADR、生成型、UI補助ユーティリティはいずれも解除機能に直接関連しており、明らかな逸脱はありません。
Docstring Coverage✅ PassedDocstring coverage is 94.74% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/skill-display-decision-reset

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.

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (1)
web/src/components/github-link/SkillDisplaySection.tsx (1)

60-73: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Polish reset button text state.

Because resetting is a single global boolean coming from the hook, clicking "解除" on one group will simultaneously change the text of all visible reset buttons to "解除中...". You can track the clicked group locally to only change the text of the button that was actually clicked, while still keeping all buttons disabled during the request.

✨ Proposed optional polish

Add a local state at the top of the component (e.g., around line 37):

const[resettingKey,setResettingKey]=useState<string|null>(null);

Then update the button rendering to use the local state for its text:

- {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}- {isResettableGroup(group) && (- <button- type="button"- className={styles.resetButton}- onClick={() => void reset(buildResetIdentities(group))}- disabled={resetting || confirming || proposing}- aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}- >- {resetting- ? SKILL_DISPLAY_MESSAGES.RESETTING- : SKILL_DISPLAY_MESSAGES.RESET}- </button>- )}+ {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}+ {isResettableGroup(group) && (+ <button+ type="button"+ className={styles.resetButton}+ onClick={async () => {+ setResettingKey(group.key);+ await reset(buildResetIdentities(group));+ setResettingKey(null);+ }}+ disabled={resetting || confirming || proposing}+ aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}+ >+ {resettingKey === group.key+ ? SKILL_DISPLAY_MESSAGES.RESETTING+ : SKILL_DISPLAY_MESSAGES.RESET}+ </button>+ )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@web/src/components/github-link/SkillDisplaySection.tsx` around lines 60 - 73,
Update SkillDisplaySection’s reset-button state using a local resettingKey state
tied to the clicked group, and use it to show RESETTING only for that group’s
button. Keep the existing global resetting value for disabling all reset buttons
during the request, and clear the local key when the reset operation completes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 60-73: Update SkillDisplaySection’s reset-button state using a
local resettingKey state tied to the clicked group, and use it to show RESETTING
only for that group’s button. Keep the existing global resetting value for
disabling all reset buttons during the request, and clear the local key when the
reset operation completes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d4c189f7-4199-4f82-84e4-44800f6f5404

📥 Commits

Reviewing files that changed from the base of the PR and between 6955c4c and 5c9251a.

📒 Files selected for processing (16)
  • backend/app/repositories/skill.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/tests/test_skill_display_api.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/types.ts
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

global resetting は全解除ボタンの無効化に使い、押されたグループの区別は
ローカルの resettingKey で行う。確定済みグループが複数ある場合に全ボタンへ
「解除中...」が出ていたのを、対象グループのボタンだけに出るよう修正。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit aa78d18 into mainJul 20, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-decision-reset branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

スキル表示名の畳み込みグループを解除(バラす)できる導線がない(ADR-0016 D11 残課題)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496) - #516

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset
Jul 20, 2026
Merged

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496)#516
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 20, 2026

Copy link
Copy Markdown
Owner

概要

スキル表示名の human-in-the-loop 確定(ADR-0016 D11 / #476)で、一度確定した表示名・畳み込みグループを「解除(バラす)」する導線が無い問題(#496)を解消する。upsert(削除しない)設計で確定行が残り続け、機械デフォルトへ完全リセットできなかったギャップを埋める。

Closes#496

設計方針

「解除」= 対象 identity の Layer 3 確定行を DELETE して機械デフォルトへ戻す単一アクション。グループの全メンバー identity をまとめて送ることで「グループ解除(バラす)」と「確定リセット(表示名を戻す)」を同時に満たす。issue の案1(DELETE エンドポイント)を主軸に採用し、案3のメンバー個別分割 UI は作らない(ADR に残課題として明記)。

変更点

Backend

  • DELETE /skills/display-decisions を新設(identity 群指定で確定行を削除)。authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない確定行は冪等に無視)。リセット後の最新一覧を返す
  • repositories/skill.pydelete_by_identities(user_id 固定・ORM 削除)
  • schemasSkillDisplayResetRequest 追加 → make codegen-typesgenerated.ts 再生成

Web

  • utils/skillDisplay: isResettableGroup / buildResetIdentities(TDD)
  • hooks/useGitHubSkills: reset / resetting(TDD)
  • スキル一覧の確定済みチップに「解除」ボタン追加

Docs

  • ADR-0016 D11 に項 (g)(解除)と変更履歴を追記

テスト

  • backend: 5 ケース(401 / 422 / リセット反映 / グループ全バラし / 冪等)
  • web: util 5・hook 2 ケース(red→green で TDD)
  • E2E: 解除フロー 1 本

ローカル make ci green(backend 729 / web 389 / build OK)、E2E(github-link)8 passed。

レビュー観点

  • API 契約追加: body 付き DELETE の新設(generated.ts は同 PR に再生成済み)
  • 設計分岐: 削除ベースの全リセットを採用、メンバー個別分割 UI は未実装(残課題)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a reset option for confirmed GitHub skill display names.
    • Resetting restores machine-generated names and can ungroup related skills.
    • Reset buttons show progress states and are unavailable during other updates.
  • Bug Fixes

    • Reset operations are validated, idempotent, and preserve existing data when they fail.
  • Documentation

    • Documented the reset behavior, authorization, and fallback display rules.
  • Tests

    • Added coverage for authentication, validation, grouped skills, failures, and end-to-end reset behavior.

一度確定した表示名・畳み込みグループを機械デフォルトへ戻す導線が無く、
upsert(削除しない)設計で確定行が残り続け完全リセットできなかったギャップを埋める。
Backend:
- DELETE /skills/display-decisions を新設(identity 群指定で Layer 3 確定行を削除)。
authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない
確定行は冪等に無視)。リセット後の最新スキル一覧を返す
- repositories/skill.py に delete_by_identities を追加(user_id 固定・ORM 削除)
- schemas に SkillDisplayResetRequest を追加、make codegen-types で generated.ts 再生成
Web:
- utils/skillDisplay に isResettableGroup / buildResetIdentities を追加(TDD)
- useGitHubSkills に reset / resetting を追加(TDD)
- スキル一覧の確定済みチップに「解除」ボタンを追加。グループ全メンバーを
まとめて解除するため畳み込みも解ける
Docs:
- ADR-0016 D11 に項 (g)(解除)と変更履歴を追記
テスト: backend 5 ケース / web util 5・hook 2 ケース / E2E 解除フロー 1 本を追加
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 labels Jul 20, 2026
@coderabbitai

coderabbitaiBot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd3e8a7b-a58b-4e27-955e-c4e0ace210f1

📥 Commits

Reviewing files that changed from the base of the PR and between 5c9251a and 97b01f7.

📒 Files selected for processing (1)
  • web/src/components/github-link/SkillDisplaySection.tsx
📝 Walkthrough

Walkthrough

Adds an authenticated DELETE flow for resetting confirmed GitHub skill display decisions. The backend removes matching records and returns refreshed skills, while the generated client, hook, grouped UI controls, tests, and ADR support the reset behavior.

Changes

Skill display reset

Layer / File(s)Summary
Backend reset contract and deletion flow
backend/app/schemas/github_skill.py, backend/app/repositories/skill.py, backend/app/routers/github_link/endpoints.py, backend/tests/test_skill_display_api.py, docs/adr/0016-github-skill-inference.md
Adds the reset request schema, identity-based deletion, endpoint validation, refreshed skill responses, authorization/idempotency tests, and ADR documentation.
Generated client and hook integration
web/src/api/generated.ts, web/src/api/types.ts, web/src/api/githubLink.ts, web/src/hooks/useGitHubSkills.ts, web/src/hooks/useGitHubSkills.test.ts
Adds the DELETE API contract and wrapper, then exposes reset state and error-preserving reset behavior through useGitHubSkills.
Grouped reset controls and user-facing validation
web/src/utils/skillDisplay.ts, web/src/components/github-link/SkillDisplaySection.tsx, web/src/components/github-link/*.css, web/src/constants/messages.ts, web/src/utils/skillDisplay.test.ts, web/e2e/github-link.spec.ts
Determines resettable groups, builds member identities, renders disabled/in-progress reset controls, adds messages and styling, and verifies fallback display behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant Backend
User->>SkillDisplaySection: Click reset
SkillDisplaySection->>useGitHubSkills: Reset group identities
useGitHubSkills->>GitHubLinkAPI: Send DELETE request
GitHubLinkAPI->>Backend: Delete display decisions
Backend-->>GitHubLinkAPI: Return refreshed skills
GitHubLinkAPI-->>useGitHubSkills: Updated skill list
useGitHubSkills-->>SkillDisplaySection: Render machine defaults
Loading

Possibly related PRs

  • yusuke0610/devforge#495: Introduced the display-decision model and confirmation workflow extended by this reset flow.

Suggested labels:agent

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ Passed主要変更であるスキル表示名の確定解除機能を具体的に示しており、PR内容と一致しています。
Linked Issues check✅ PassedDELETE API、repo削除、UIの解除導線、生成型更新、テスト追加が #496 の要件を満たしています。
Out of Scope Changes check✅ Passedテスト、ADR、生成型、UI補助ユーティリティはいずれも解除機能に直接関連しており、明らかな逸脱はありません。
Docstring Coverage✅ PassedDocstring coverage is 94.74% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/skill-display-decision-reset

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.

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (1)
web/src/components/github-link/SkillDisplaySection.tsx (1)

60-73: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Polish reset button text state.

Because resetting is a single global boolean coming from the hook, clicking "解除" on one group will simultaneously change the text of all visible reset buttons to "解除中...". You can track the clicked group locally to only change the text of the button that was actually clicked, while still keeping all buttons disabled during the request.

✨ Proposed optional polish

Add a local state at the top of the component (e.g., around line 37):

const[resettingKey,setResettingKey]=useState<string|null>(null);

Then update the button rendering to use the local state for its text:

- {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}- {isResettableGroup(group) && (- <button- type="button"- className={styles.resetButton}- onClick={() => void reset(buildResetIdentities(group))}- disabled={resetting || confirming || proposing}- aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}- >- {resetting- ? SKILL_DISPLAY_MESSAGES.RESETTING- : SKILL_DISPLAY_MESSAGES.RESET}- </button>- )}+ {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}+ {isResettableGroup(group) && (+ <button+ type="button"+ className={styles.resetButton}+ onClick={async () => {+ setResettingKey(group.key);+ await reset(buildResetIdentities(group));+ setResettingKey(null);+ }}+ disabled={resetting || confirming || proposing}+ aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}+ >+ {resettingKey === group.key+ ? SKILL_DISPLAY_MESSAGES.RESETTING+ : SKILL_DISPLAY_MESSAGES.RESET}+ </button>+ )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@web/src/components/github-link/SkillDisplaySection.tsx` around lines 60 - 73,
Update SkillDisplaySection’s reset-button state using a local resettingKey state
tied to the clicked group, and use it to show RESETTING only for that group’s
button. Keep the existing global resetting value for disabling all reset buttons
during the request, and clear the local key when the reset operation completes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 60-73: Update SkillDisplaySection’s reset-button state using a
local resettingKey state tied to the clicked group, and use it to show RESETTING
only for that group’s button. Keep the existing global resetting value for
disabling all reset buttons during the request, and clear the local key when the
reset operation completes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d4c189f7-4199-4f82-84e4-44800f6f5404

📥 Commits

Reviewing files that changed from the base of the PR and between 6955c4c and 5c9251a.

📒 Files selected for processing (16)
  • backend/app/repositories/skill.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/tests/test_skill_display_api.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/types.ts
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

global resetting は全解除ボタンの無効化に使い、押されたグループの区別は
ローカルの resettingKey で行う。確定済みグループが複数ある場合に全ボタンへ
「解除中...」が出ていたのを、対象グループのボタンだけに出るよう修正。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit aa78d18 into mainJul 20, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-decision-reset branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

スキル表示名の畳み込みグループを解除(バラす)できる導線がない(ADR-0016 D11 残課題)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496) - #516

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset
Jul 20, 2026
Merged

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496)#516
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 20, 2026

Copy link
Copy Markdown
Owner

概要

スキル表示名の human-in-the-loop 確定(ADR-0016 D11 / #476)で、一度確定した表示名・畳み込みグループを「解除(バラす)」する導線が無い問題(#496)を解消する。upsert(削除しない)設計で確定行が残り続け、機械デフォルトへ完全リセットできなかったギャップを埋める。

Closes#496

設計方針

「解除」= 対象 identity の Layer 3 確定行を DELETE して機械デフォルトへ戻す単一アクション。グループの全メンバー identity をまとめて送ることで「グループ解除(バラす)」と「確定リセット(表示名を戻す)」を同時に満たす。issue の案1(DELETE エンドポイント)を主軸に採用し、案3のメンバー個別分割 UI は作らない(ADR に残課題として明記)。

変更点

Backend

  • DELETE /skills/display-decisions を新設(identity 群指定で確定行を削除)。authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない確定行は冪等に無視)。リセット後の最新一覧を返す
  • repositories/skill.pydelete_by_identities(user_id 固定・ORM 削除)
  • schemasSkillDisplayResetRequest 追加 → make codegen-typesgenerated.ts 再生成

Web

  • utils/skillDisplay: isResettableGroup / buildResetIdentities(TDD)
  • hooks/useGitHubSkills: reset / resetting(TDD)
  • スキル一覧の確定済みチップに「解除」ボタン追加

Docs

  • ADR-0016 D11 に項 (g)(解除)と変更履歴を追記

テスト

  • backend: 5 ケース(401 / 422 / リセット反映 / グループ全バラし / 冪等)
  • web: util 5・hook 2 ケース(red→green で TDD)
  • E2E: 解除フロー 1 本

ローカル make ci green(backend 729 / web 389 / build OK)、E2E(github-link)8 passed。

レビュー観点

  • API 契約追加: body 付き DELETE の新設(generated.ts は同 PR に再生成済み)
  • 設計分岐: 削除ベースの全リセットを採用、メンバー個別分割 UI は未実装(残課題)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a reset option for confirmed GitHub skill display names.
    • Resetting restores machine-generated names and can ungroup related skills.
    • Reset buttons show progress states and are unavailable during other updates.
  • Bug Fixes

    • Reset operations are validated, idempotent, and preserve existing data when they fail.
  • Documentation

    • Documented the reset behavior, authorization, and fallback display rules.
  • Tests

    • Added coverage for authentication, validation, grouped skills, failures, and end-to-end reset behavior.

一度確定した表示名・畳み込みグループを機械デフォルトへ戻す導線が無く、
upsert(削除しない)設計で確定行が残り続け完全リセットできなかったギャップを埋める。
Backend:
- DELETE /skills/display-decisions を新設(identity 群指定で Layer 3 確定行を削除)。
authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない
確定行は冪等に無視)。リセット後の最新スキル一覧を返す
- repositories/skill.py に delete_by_identities を追加(user_id 固定・ORM 削除)
- schemas に SkillDisplayResetRequest を追加、make codegen-types で generated.ts 再生成
Web:
- utils/skillDisplay に isResettableGroup / buildResetIdentities を追加(TDD)
- useGitHubSkills に reset / resetting を追加(TDD)
- スキル一覧の確定済みチップに「解除」ボタンを追加。グループ全メンバーを
まとめて解除するため畳み込みも解ける
Docs:
- ADR-0016 D11 に項 (g)(解除)と変更履歴を追記
テスト: backend 5 ケース / web util 5・hook 2 ケース / E2E 解除フロー 1 本を追加
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 labels Jul 20, 2026
@coderabbitai

coderabbitaiBot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd3e8a7b-a58b-4e27-955e-c4e0ace210f1

📥 Commits

Reviewing files that changed from the base of the PR and between 5c9251a and 97b01f7.

📒 Files selected for processing (1)
  • web/src/components/github-link/SkillDisplaySection.tsx
📝 Walkthrough

Walkthrough

Adds an authenticated DELETE flow for resetting confirmed GitHub skill display decisions. The backend removes matching records and returns refreshed skills, while the generated client, hook, grouped UI controls, tests, and ADR support the reset behavior.

Changes

Skill display reset

Layer / File(s)Summary
Backend reset contract and deletion flow
backend/app/schemas/github_skill.py, backend/app/repositories/skill.py, backend/app/routers/github_link/endpoints.py, backend/tests/test_skill_display_api.py, docs/adr/0016-github-skill-inference.md
Adds the reset request schema, identity-based deletion, endpoint validation, refreshed skill responses, authorization/idempotency tests, and ADR documentation.
Generated client and hook integration
web/src/api/generated.ts, web/src/api/types.ts, web/src/api/githubLink.ts, web/src/hooks/useGitHubSkills.ts, web/src/hooks/useGitHubSkills.test.ts
Adds the DELETE API contract and wrapper, then exposes reset state and error-preserving reset behavior through useGitHubSkills.
Grouped reset controls and user-facing validation
web/src/utils/skillDisplay.ts, web/src/components/github-link/SkillDisplaySection.tsx, web/src/components/github-link/*.css, web/src/constants/messages.ts, web/src/utils/skillDisplay.test.ts, web/e2e/github-link.spec.ts
Determines resettable groups, builds member identities, renders disabled/in-progress reset controls, adds messages and styling, and verifies fallback display behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant Backend
User->>SkillDisplaySection: Click reset
SkillDisplaySection->>useGitHubSkills: Reset group identities
useGitHubSkills->>GitHubLinkAPI: Send DELETE request
GitHubLinkAPI->>Backend: Delete display decisions
Backend-->>GitHubLinkAPI: Return refreshed skills
GitHubLinkAPI-->>useGitHubSkills: Updated skill list
useGitHubSkills-->>SkillDisplaySection: Render machine defaults
Loading

Possibly related PRs

  • yusuke0610/devforge#495: Introduced the display-decision model and confirmation workflow extended by this reset flow.

Suggested labels:agent

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ Passed主要変更であるスキル表示名の確定解除機能を具体的に示しており、PR内容と一致しています。
Linked Issues check✅ PassedDELETE API、repo削除、UIの解除導線、生成型更新、テスト追加が #496 の要件を満たしています。
Out of Scope Changes check✅ Passedテスト、ADR、生成型、UI補助ユーティリティはいずれも解除機能に直接関連しており、明らかな逸脱はありません。
Docstring Coverage✅ PassedDocstring coverage is 94.74% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/skill-display-decision-reset

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.

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (1)
web/src/components/github-link/SkillDisplaySection.tsx (1)

60-73: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Polish reset button text state.

Because resetting is a single global boolean coming from the hook, clicking "解除" on one group will simultaneously change the text of all visible reset buttons to "解除中...". You can track the clicked group locally to only change the text of the button that was actually clicked, while still keeping all buttons disabled during the request.

✨ Proposed optional polish

Add a local state at the top of the component (e.g., around line 37):

const[resettingKey,setResettingKey]=useState<string|null>(null);

Then update the button rendering to use the local state for its text:

- {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}- {isResettableGroup(group) && (- <button- type="button"- className={styles.resetButton}- onClick={() => void reset(buildResetIdentities(group))}- disabled={resetting || confirming || proposing}- aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}- >- {resetting- ? SKILL_DISPLAY_MESSAGES.RESETTING- : SKILL_DISPLAY_MESSAGES.RESET}- </button>- )}+ {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}+ {isResettableGroup(group) && (+ <button+ type="button"+ className={styles.resetButton}+ onClick={async () => {+ setResettingKey(group.key);+ await reset(buildResetIdentities(group));+ setResettingKey(null);+ }}+ disabled={resetting || confirming || proposing}+ aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}+ >+ {resettingKey === group.key+ ? SKILL_DISPLAY_MESSAGES.RESETTING+ : SKILL_DISPLAY_MESSAGES.RESET}+ </button>+ )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@web/src/components/github-link/SkillDisplaySection.tsx` around lines 60 - 73,
Update SkillDisplaySection’s reset-button state using a local resettingKey state
tied to the clicked group, and use it to show RESETTING only for that group’s
button. Keep the existing global resetting value for disabling all reset buttons
during the request, and clear the local key when the reset operation completes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 60-73: Update SkillDisplaySection’s reset-button state using a
local resettingKey state tied to the clicked group, and use it to show RESETTING
only for that group’s button. Keep the existing global resetting value for
disabling all reset buttons during the request, and clear the local key when the
reset operation completes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d4c189f7-4199-4f82-84e4-44800f6f5404

📥 Commits

Reviewing files that changed from the base of the PR and between 6955c4c and 5c9251a.

📒 Files selected for processing (16)
  • backend/app/repositories/skill.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/tests/test_skill_display_api.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/types.ts
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

global resetting は全解除ボタンの無効化に使い、押されたグループの区別は
ローカルの resettingKey で行う。確定済みグループが複数ある場合に全ボタンへ
「解除中...」が出ていたのを、対象グループのボタンだけに出るよう修正。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit aa78d18 into mainJul 20, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-decision-reset branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

スキル表示名の畳み込みグループを解除(バラす)できる導線がない(ADR-0016 D11 残課題)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496) - #516

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset
Jul 20, 2026
Merged

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496)#516
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 20, 2026

Copy link
Copy Markdown
Owner

概要

スキル表示名の human-in-the-loop 確定(ADR-0016 D11 / #476)で、一度確定した表示名・畳み込みグループを「解除(バラす)」する導線が無い問題(#496)を解消する。upsert(削除しない)設計で確定行が残り続け、機械デフォルトへ完全リセットできなかったギャップを埋める。

Closes#496

設計方針

「解除」= 対象 identity の Layer 3 確定行を DELETE して機械デフォルトへ戻す単一アクション。グループの全メンバー identity をまとめて送ることで「グループ解除(バラす)」と「確定リセット(表示名を戻す)」を同時に満たす。issue の案1(DELETE エンドポイント)を主軸に採用し、案3のメンバー個別分割 UI は作らない(ADR に残課題として明記)。

変更点

Backend

  • DELETE /skills/display-decisions を新設(identity 群指定で確定行を削除)。authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない確定行は冪等に無視)。リセット後の最新一覧を返す
  • repositories/skill.pydelete_by_identities(user_id 固定・ORM 削除)
  • schemasSkillDisplayResetRequest 追加 → make codegen-typesgenerated.ts 再生成

Web

  • utils/skillDisplay: isResettableGroup / buildResetIdentities(TDD)
  • hooks/useGitHubSkills: reset / resetting(TDD)
  • スキル一覧の確定済みチップに「解除」ボタン追加

Docs

  • ADR-0016 D11 に項 (g)(解除)と変更履歴を追記

テスト

  • backend: 5 ケース(401 / 422 / リセット反映 / グループ全バラし / 冪等)
  • web: util 5・hook 2 ケース(red→green で TDD)
  • E2E: 解除フロー 1 本

ローカル make ci green(backend 729 / web 389 / build OK)、E2E(github-link)8 passed。

レビュー観点

  • API 契約追加: body 付き DELETE の新設(generated.ts は同 PR に再生成済み)
  • 設計分岐: 削除ベースの全リセットを採用、メンバー個別分割 UI は未実装(残課題)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a reset option for confirmed GitHub skill display names.
    • Resetting restores machine-generated names and can ungroup related skills.
    • Reset buttons show progress states and are unavailable during other updates.
  • Bug Fixes

    • Reset operations are validated, idempotent, and preserve existing data when they fail.
  • Documentation

    • Documented the reset behavior, authorization, and fallback display rules.
  • Tests

    • Added coverage for authentication, validation, grouped skills, failures, and end-to-end reset behavior.

一度確定した表示名・畳み込みグループを機械デフォルトへ戻す導線が無く、
upsert(削除しない)設計で確定行が残り続け完全リセットできなかったギャップを埋める。
Backend:
- DELETE /skills/display-decisions を新設(identity 群指定で Layer 3 確定行を削除)。
authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない
確定行は冪等に無視)。リセット後の最新スキル一覧を返す
- repositories/skill.py に delete_by_identities を追加(user_id 固定・ORM 削除)
- schemas に SkillDisplayResetRequest を追加、make codegen-types で generated.ts 再生成
Web:
- utils/skillDisplay に isResettableGroup / buildResetIdentities を追加(TDD)
- useGitHubSkills に reset / resetting を追加(TDD)
- スキル一覧の確定済みチップに「解除」ボタンを追加。グループ全メンバーを
まとめて解除するため畳み込みも解ける
Docs:
- ADR-0016 D11 に項 (g)(解除)と変更履歴を追記
テスト: backend 5 ケース / web util 5・hook 2 ケース / E2E 解除フロー 1 本を追加
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 labels Jul 20, 2026
@coderabbitai

coderabbitaiBot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd3e8a7b-a58b-4e27-955e-c4e0ace210f1

📥 Commits

Reviewing files that changed from the base of the PR and between 5c9251a and 97b01f7.

📒 Files selected for processing (1)
  • web/src/components/github-link/SkillDisplaySection.tsx
📝 Walkthrough

Walkthrough

Adds an authenticated DELETE flow for resetting confirmed GitHub skill display decisions. The backend removes matching records and returns refreshed skills, while the generated client, hook, grouped UI controls, tests, and ADR support the reset behavior.

Changes

Skill display reset

Layer / File(s)Summary
Backend reset contract and deletion flow
backend/app/schemas/github_skill.py, backend/app/repositories/skill.py, backend/app/routers/github_link/endpoints.py, backend/tests/test_skill_display_api.py, docs/adr/0016-github-skill-inference.md
Adds the reset request schema, identity-based deletion, endpoint validation, refreshed skill responses, authorization/idempotency tests, and ADR documentation.
Generated client and hook integration
web/src/api/generated.ts, web/src/api/types.ts, web/src/api/githubLink.ts, web/src/hooks/useGitHubSkills.ts, web/src/hooks/useGitHubSkills.test.ts
Adds the DELETE API contract and wrapper, then exposes reset state and error-preserving reset behavior through useGitHubSkills.
Grouped reset controls and user-facing validation
web/src/utils/skillDisplay.ts, web/src/components/github-link/SkillDisplaySection.tsx, web/src/components/github-link/*.css, web/src/constants/messages.ts, web/src/utils/skillDisplay.test.ts, web/e2e/github-link.spec.ts
Determines resettable groups, builds member identities, renders disabled/in-progress reset controls, adds messages and styling, and verifies fallback display behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant Backend
User->>SkillDisplaySection: Click reset
SkillDisplaySection->>useGitHubSkills: Reset group identities
useGitHubSkills->>GitHubLinkAPI: Send DELETE request
GitHubLinkAPI->>Backend: Delete display decisions
Backend-->>GitHubLinkAPI: Return refreshed skills
GitHubLinkAPI-->>useGitHubSkills: Updated skill list
useGitHubSkills-->>SkillDisplaySection: Render machine defaults
Loading

Possibly related PRs

  • yusuke0610/devforge#495: Introduced the display-decision model and confirmation workflow extended by this reset flow.

Suggested labels:agent

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ Passed主要変更であるスキル表示名の確定解除機能を具体的に示しており、PR内容と一致しています。
Linked Issues check✅ PassedDELETE API、repo削除、UIの解除導線、生成型更新、テスト追加が #496 の要件を満たしています。
Out of Scope Changes check✅ Passedテスト、ADR、生成型、UI補助ユーティリティはいずれも解除機能に直接関連しており、明らかな逸脱はありません。
Docstring Coverage✅ PassedDocstring coverage is 94.74% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/skill-display-decision-reset

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.

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (1)
web/src/components/github-link/SkillDisplaySection.tsx (1)

60-73: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Polish reset button text state.

Because resetting is a single global boolean coming from the hook, clicking "解除" on one group will simultaneously change the text of all visible reset buttons to "解除中...". You can track the clicked group locally to only change the text of the button that was actually clicked, while still keeping all buttons disabled during the request.

✨ Proposed optional polish

Add a local state at the top of the component (e.g., around line 37):

const[resettingKey,setResettingKey]=useState<string|null>(null);

Then update the button rendering to use the local state for its text:

- {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}- {isResettableGroup(group) && (- <button- type="button"- className={styles.resetButton}- onClick={() => void reset(buildResetIdentities(group))}- disabled={resetting || confirming || proposing}- aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}- >- {resetting- ? SKILL_DISPLAY_MESSAGES.RESETTING- : SKILL_DISPLAY_MESSAGES.RESET}- </button>- )}+ {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}+ {isResettableGroup(group) && (+ <button+ type="button"+ className={styles.resetButton}+ onClick={async () => {+ setResettingKey(group.key);+ await reset(buildResetIdentities(group));+ setResettingKey(null);+ }}+ disabled={resetting || confirming || proposing}+ aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}+ >+ {resettingKey === group.key+ ? SKILL_DISPLAY_MESSAGES.RESETTING+ : SKILL_DISPLAY_MESSAGES.RESET}+ </button>+ )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@web/src/components/github-link/SkillDisplaySection.tsx` around lines 60 - 73,
Update SkillDisplaySection’s reset-button state using a local resettingKey state
tied to the clicked group, and use it to show RESETTING only for that group’s
button. Keep the existing global resetting value for disabling all reset buttons
during the request, and clear the local key when the reset operation completes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 60-73: Update SkillDisplaySection’s reset-button state using a
local resettingKey state tied to the clicked group, and use it to show RESETTING
only for that group’s button. Keep the existing global resetting value for
disabling all reset buttons during the request, and clear the local key when the
reset operation completes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d4c189f7-4199-4f82-84e4-44800f6f5404

📥 Commits

Reviewing files that changed from the base of the PR and between 6955c4c and 5c9251a.

📒 Files selected for processing (16)
  • backend/app/repositories/skill.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/tests/test_skill_display_api.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/types.ts
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

global resetting は全解除ボタンの無効化に使い、押されたグループの区別は
ローカルの resettingKey で行う。確定済みグループが複数ある場合に全ボタンへ
「解除中...」が出ていたのを、対象グループのボタンだけに出るよう修正。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit aa78d18 into mainJul 20, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-decision-reset branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

スキル表示名の畳み込みグループを解除(バラす)できる導線がない(ADR-0016 D11 残課題)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496) - #516

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset
Jul 20, 2026
Merged

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496)#516
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 20, 2026

Copy link
Copy Markdown
Owner

概要

スキル表示名の human-in-the-loop 確定(ADR-0016 D11 / #476)で、一度確定した表示名・畳み込みグループを「解除(バラす)」する導線が無い問題(#496)を解消する。upsert(削除しない)設計で確定行が残り続け、機械デフォルトへ完全リセットできなかったギャップを埋める。

Closes#496

設計方針

「解除」= 対象 identity の Layer 3 確定行を DELETE して機械デフォルトへ戻す単一アクション。グループの全メンバー identity をまとめて送ることで「グループ解除(バラす)」と「確定リセット(表示名を戻す)」を同時に満たす。issue の案1(DELETE エンドポイント)を主軸に採用し、案3のメンバー個別分割 UI は作らない(ADR に残課題として明記)。

変更点

Backend

  • DELETE /skills/display-decisions を新設(identity 群指定で確定行を削除)。authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない確定行は冪等に無視)。リセット後の最新一覧を返す
  • repositories/skill.pydelete_by_identities(user_id 固定・ORM 削除)
  • schemasSkillDisplayResetRequest 追加 → make codegen-typesgenerated.ts 再生成

Web

  • utils/skillDisplay: isResettableGroup / buildResetIdentities(TDD)
  • hooks/useGitHubSkills: reset / resetting(TDD)
  • スキル一覧の確定済みチップに「解除」ボタン追加

Docs

  • ADR-0016 D11 に項 (g)(解除)と変更履歴を追記

テスト

  • backend: 5 ケース(401 / 422 / リセット反映 / グループ全バラし / 冪等)
  • web: util 5・hook 2 ケース(red→green で TDD)
  • E2E: 解除フロー 1 本

ローカル make ci green(backend 729 / web 389 / build OK)、E2E(github-link)8 passed。

レビュー観点

  • API 契約追加: body 付き DELETE の新設(generated.ts は同 PR に再生成済み)
  • 設計分岐: 削除ベースの全リセットを採用、メンバー個別分割 UI は未実装(残課題)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a reset option for confirmed GitHub skill display names.
    • Resetting restores machine-generated names and can ungroup related skills.
    • Reset buttons show progress states and are unavailable during other updates.
  • Bug Fixes

    • Reset operations are validated, idempotent, and preserve existing data when they fail.
  • Documentation

    • Documented the reset behavior, authorization, and fallback display rules.
  • Tests

    • Added coverage for authentication, validation, grouped skills, failures, and end-to-end reset behavior.

一度確定した表示名・畳み込みグループを機械デフォルトへ戻す導線が無く、
upsert(削除しない)設計で確定行が残り続け完全リセットできなかったギャップを埋める。
Backend:
- DELETE /skills/display-decisions を新設(identity 群指定で Layer 3 確定行を削除)。
authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない
確定行は冪等に無視)。リセット後の最新スキル一覧を返す
- repositories/skill.py に delete_by_identities を追加(user_id 固定・ORM 削除)
- schemas に SkillDisplayResetRequest を追加、make codegen-types で generated.ts 再生成
Web:
- utils/skillDisplay に isResettableGroup / buildResetIdentities を追加(TDD)
- useGitHubSkills に reset / resetting を追加(TDD)
- スキル一覧の確定済みチップに「解除」ボタンを追加。グループ全メンバーを
まとめて解除するため畳み込みも解ける
Docs:
- ADR-0016 D11 に項 (g)(解除)と変更履歴を追記
テスト: backend 5 ケース / web util 5・hook 2 ケース / E2E 解除フロー 1 本を追加
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 labels Jul 20, 2026
@coderabbitai

coderabbitaiBot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd3e8a7b-a58b-4e27-955e-c4e0ace210f1

📥 Commits

Reviewing files that changed from the base of the PR and between 5c9251a and 97b01f7.

📒 Files selected for processing (1)
  • web/src/components/github-link/SkillDisplaySection.tsx
📝 Walkthrough

Walkthrough

Adds an authenticated DELETE flow for resetting confirmed GitHub skill display decisions. The backend removes matching records and returns refreshed skills, while the generated client, hook, grouped UI controls, tests, and ADR support the reset behavior.

Changes

Skill display reset

Layer / File(s)Summary
Backend reset contract and deletion flow
backend/app/schemas/github_skill.py, backend/app/repositories/skill.py, backend/app/routers/github_link/endpoints.py, backend/tests/test_skill_display_api.py, docs/adr/0016-github-skill-inference.md
Adds the reset request schema, identity-based deletion, endpoint validation, refreshed skill responses, authorization/idempotency tests, and ADR documentation.
Generated client and hook integration
web/src/api/generated.ts, web/src/api/types.ts, web/src/api/githubLink.ts, web/src/hooks/useGitHubSkills.ts, web/src/hooks/useGitHubSkills.test.ts
Adds the DELETE API contract and wrapper, then exposes reset state and error-preserving reset behavior through useGitHubSkills.
Grouped reset controls and user-facing validation
web/src/utils/skillDisplay.ts, web/src/components/github-link/SkillDisplaySection.tsx, web/src/components/github-link/*.css, web/src/constants/messages.ts, web/src/utils/skillDisplay.test.ts, web/e2e/github-link.spec.ts
Determines resettable groups, builds member identities, renders disabled/in-progress reset controls, adds messages and styling, and verifies fallback display behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant Backend
User->>SkillDisplaySection: Click reset
SkillDisplaySection->>useGitHubSkills: Reset group identities
useGitHubSkills->>GitHubLinkAPI: Send DELETE request
GitHubLinkAPI->>Backend: Delete display decisions
Backend-->>GitHubLinkAPI: Return refreshed skills
GitHubLinkAPI-->>useGitHubSkills: Updated skill list
useGitHubSkills-->>SkillDisplaySection: Render machine defaults
Loading

Possibly related PRs

  • yusuke0610/devforge#495: Introduced the display-decision model and confirmation workflow extended by this reset flow.

Suggested labels:agent

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ Passed主要変更であるスキル表示名の確定解除機能を具体的に示しており、PR内容と一致しています。
Linked Issues check✅ PassedDELETE API、repo削除、UIの解除導線、生成型更新、テスト追加が #496 の要件を満たしています。
Out of Scope Changes check✅ Passedテスト、ADR、生成型、UI補助ユーティリティはいずれも解除機能に直接関連しており、明らかな逸脱はありません。
Docstring Coverage✅ PassedDocstring coverage is 94.74% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/skill-display-decision-reset

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.

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (1)
web/src/components/github-link/SkillDisplaySection.tsx (1)

60-73: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Polish reset button text state.

Because resetting is a single global boolean coming from the hook, clicking "解除" on one group will simultaneously change the text of all visible reset buttons to "解除中...". You can track the clicked group locally to only change the text of the button that was actually clicked, while still keeping all buttons disabled during the request.

✨ Proposed optional polish

Add a local state at the top of the component (e.g., around line 37):

const[resettingKey,setResettingKey]=useState<string|null>(null);

Then update the button rendering to use the local state for its text:

- {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}- {isResettableGroup(group) && (- <button- type="button"- className={styles.resetButton}- onClick={() => void reset(buildResetIdentities(group))}- disabled={resetting || confirming || proposing}- aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}- >- {resetting- ? SKILL_DISPLAY_MESSAGES.RESETTING- : SKILL_DISPLAY_MESSAGES.RESET}- </button>- )}+ {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}+ {isResettableGroup(group) && (+ <button+ type="button"+ className={styles.resetButton}+ onClick={async () => {+ setResettingKey(group.key);+ await reset(buildResetIdentities(group));+ setResettingKey(null);+ }}+ disabled={resetting || confirming || proposing}+ aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}+ >+ {resettingKey === group.key+ ? SKILL_DISPLAY_MESSAGES.RESETTING+ : SKILL_DISPLAY_MESSAGES.RESET}+ </button>+ )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@web/src/components/github-link/SkillDisplaySection.tsx` around lines 60 - 73,
Update SkillDisplaySection’s reset-button state using a local resettingKey state
tied to the clicked group, and use it to show RESETTING only for that group’s
button. Keep the existing global resetting value for disabling all reset buttons
during the request, and clear the local key when the reset operation completes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 60-73: Update SkillDisplaySection’s reset-button state using a
local resettingKey state tied to the clicked group, and use it to show RESETTING
only for that group’s button. Keep the existing global resetting value for
disabling all reset buttons during the request, and clear the local key when the
reset operation completes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d4c189f7-4199-4f82-84e4-44800f6f5404

📥 Commits

Reviewing files that changed from the base of the PR and between 6955c4c and 5c9251a.

📒 Files selected for processing (16)
  • backend/app/repositories/skill.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/tests/test_skill_display_api.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/types.ts
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

global resetting は全解除ボタンの無効化に使い、押されたグループの区別は
ローカルの resettingKey で行う。確定済みグループが複数ある場合に全ボタンへ
「解除中...」が出ていたのを、対象グループのボタンだけに出るよう修正。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit aa78d18 into mainJul 20, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-decision-reset branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

スキル表示名の畳み込みグループを解除(バラす)できる導線がない(ADR-0016 D11 残課題)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496) - #516

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset
Jul 20, 2026
Merged

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496)#516
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 20, 2026

Copy link
Copy Markdown
Owner

概要

スキル表示名の human-in-the-loop 確定(ADR-0016 D11 / #476)で、一度確定した表示名・畳み込みグループを「解除(バラす)」する導線が無い問題(#496)を解消する。upsert(削除しない)設計で確定行が残り続け、機械デフォルトへ完全リセットできなかったギャップを埋める。

Closes#496

設計方針

「解除」= 対象 identity の Layer 3 確定行を DELETE して機械デフォルトへ戻す単一アクション。グループの全メンバー identity をまとめて送ることで「グループ解除(バラす)」と「確定リセット(表示名を戻す)」を同時に満たす。issue の案1(DELETE エンドポイント)を主軸に採用し、案3のメンバー個別分割 UI は作らない(ADR に残課題として明記)。

変更点

Backend

  • DELETE /skills/display-decisions を新設(identity 群指定で確定行を削除)。authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない確定行は冪等に無視)。リセット後の最新一覧を返す
  • repositories/skill.pydelete_by_identities(user_id 固定・ORM 削除)
  • schemasSkillDisplayResetRequest 追加 → make codegen-typesgenerated.ts 再生成

Web

  • utils/skillDisplay: isResettableGroup / buildResetIdentities(TDD)
  • hooks/useGitHubSkills: reset / resetting(TDD)
  • スキル一覧の確定済みチップに「解除」ボタン追加

Docs

  • ADR-0016 D11 に項 (g)(解除)と変更履歴を追記

テスト

  • backend: 5 ケース(401 / 422 / リセット反映 / グループ全バラし / 冪等)
  • web: util 5・hook 2 ケース(red→green で TDD)
  • E2E: 解除フロー 1 本

ローカル make ci green(backend 729 / web 389 / build OK)、E2E(github-link)8 passed。

レビュー観点

  • API 契約追加: body 付き DELETE の新設(generated.ts は同 PR に再生成済み)
  • 設計分岐: 削除ベースの全リセットを採用、メンバー個別分割 UI は未実装(残課題)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a reset option for confirmed GitHub skill display names.
    • Resetting restores machine-generated names and can ungroup related skills.
    • Reset buttons show progress states and are unavailable during other updates.
  • Bug Fixes

    • Reset operations are validated, idempotent, and preserve existing data when they fail.
  • Documentation

    • Documented the reset behavior, authorization, and fallback display rules.
  • Tests

    • Added coverage for authentication, validation, grouped skills, failures, and end-to-end reset behavior.

一度確定した表示名・畳み込みグループを機械デフォルトへ戻す導線が無く、
upsert(削除しない)設計で確定行が残り続け完全リセットできなかったギャップを埋める。
Backend:
- DELETE /skills/display-decisions を新設(identity 群指定で Layer 3 確定行を削除)。
authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない
確定行は冪等に無視)。リセット後の最新スキル一覧を返す
- repositories/skill.py に delete_by_identities を追加(user_id 固定・ORM 削除)
- schemas に SkillDisplayResetRequest を追加、make codegen-types で generated.ts 再生成
Web:
- utils/skillDisplay に isResettableGroup / buildResetIdentities を追加(TDD)
- useGitHubSkills に reset / resetting を追加(TDD)
- スキル一覧の確定済みチップに「解除」ボタンを追加。グループ全メンバーを
まとめて解除するため畳み込みも解ける
Docs:
- ADR-0016 D11 に項 (g)(解除)と変更履歴を追記
テスト: backend 5 ケース / web util 5・hook 2 ケース / E2E 解除フロー 1 本を追加
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 labels Jul 20, 2026
@coderabbitai

coderabbitaiBot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd3e8a7b-a58b-4e27-955e-c4e0ace210f1

📥 Commits

Reviewing files that changed from the base of the PR and between 5c9251a and 97b01f7.

📒 Files selected for processing (1)
  • web/src/components/github-link/SkillDisplaySection.tsx
📝 Walkthrough

Walkthrough

Adds an authenticated DELETE flow for resetting confirmed GitHub skill display decisions. The backend removes matching records and returns refreshed skills, while the generated client, hook, grouped UI controls, tests, and ADR support the reset behavior.

Changes

Skill display reset

Layer / File(s)Summary
Backend reset contract and deletion flow
backend/app/schemas/github_skill.py, backend/app/repositories/skill.py, backend/app/routers/github_link/endpoints.py, backend/tests/test_skill_display_api.py, docs/adr/0016-github-skill-inference.md
Adds the reset request schema, identity-based deletion, endpoint validation, refreshed skill responses, authorization/idempotency tests, and ADR documentation.
Generated client and hook integration
web/src/api/generated.ts, web/src/api/types.ts, web/src/api/githubLink.ts, web/src/hooks/useGitHubSkills.ts, web/src/hooks/useGitHubSkills.test.ts
Adds the DELETE API contract and wrapper, then exposes reset state and error-preserving reset behavior through useGitHubSkills.
Grouped reset controls and user-facing validation
web/src/utils/skillDisplay.ts, web/src/components/github-link/SkillDisplaySection.tsx, web/src/components/github-link/*.css, web/src/constants/messages.ts, web/src/utils/skillDisplay.test.ts, web/e2e/github-link.spec.ts
Determines resettable groups, builds member identities, renders disabled/in-progress reset controls, adds messages and styling, and verifies fallback display behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant Backend
User->>SkillDisplaySection: Click reset
SkillDisplaySection->>useGitHubSkills: Reset group identities
useGitHubSkills->>GitHubLinkAPI: Send DELETE request
GitHubLinkAPI->>Backend: Delete display decisions
Backend-->>GitHubLinkAPI: Return refreshed skills
GitHubLinkAPI-->>useGitHubSkills: Updated skill list
useGitHubSkills-->>SkillDisplaySection: Render machine defaults
Loading

Possibly related PRs

  • yusuke0610/devforge#495: Introduced the display-decision model and confirmation workflow extended by this reset flow.

Suggested labels:agent

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ Passed主要変更であるスキル表示名の確定解除機能を具体的に示しており、PR内容と一致しています。
Linked Issues check✅ PassedDELETE API、repo削除、UIの解除導線、生成型更新、テスト追加が #496 の要件を満たしています。
Out of Scope Changes check✅ Passedテスト、ADR、生成型、UI補助ユーティリティはいずれも解除機能に直接関連しており、明らかな逸脱はありません。
Docstring Coverage✅ PassedDocstring coverage is 94.74% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/skill-display-decision-reset

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.

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (1)
web/src/components/github-link/SkillDisplaySection.tsx (1)

60-73: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Polish reset button text state.

Because resetting is a single global boolean coming from the hook, clicking "解除" on one group will simultaneously change the text of all visible reset buttons to "解除中...". You can track the clicked group locally to only change the text of the button that was actually clicked, while still keeping all buttons disabled during the request.

✨ Proposed optional polish

Add a local state at the top of the component (e.g., around line 37):

const[resettingKey,setResettingKey]=useState<string|null>(null);

Then update the button rendering to use the local state for its text:

- {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}- {isResettableGroup(group) && (- <button- type="button"- className={styles.resetButton}- onClick={() => void reset(buildResetIdentities(group))}- disabled={resetting || confirming || proposing}- aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}- >- {resetting- ? SKILL_DISPLAY_MESSAGES.RESETTING- : SKILL_DISPLAY_MESSAGES.RESET}- </button>- )}+ {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}+ {isResettableGroup(group) && (+ <button+ type="button"+ className={styles.resetButton}+ onClick={async () => {+ setResettingKey(group.key);+ await reset(buildResetIdentities(group));+ setResettingKey(null);+ }}+ disabled={resetting || confirming || proposing}+ aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}+ >+ {resettingKey === group.key+ ? SKILL_DISPLAY_MESSAGES.RESETTING+ : SKILL_DISPLAY_MESSAGES.RESET}+ </button>+ )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@web/src/components/github-link/SkillDisplaySection.tsx` around lines 60 - 73,
Update SkillDisplaySection’s reset-button state using a local resettingKey state
tied to the clicked group, and use it to show RESETTING only for that group’s
button. Keep the existing global resetting value for disabling all reset buttons
during the request, and clear the local key when the reset operation completes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 60-73: Update SkillDisplaySection’s reset-button state using a
local resettingKey state tied to the clicked group, and use it to show RESETTING
only for that group’s button. Keep the existing global resetting value for
disabling all reset buttons during the request, and clear the local key when the
reset operation completes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d4c189f7-4199-4f82-84e4-44800f6f5404

📥 Commits

Reviewing files that changed from the base of the PR and between 6955c4c and 5c9251a.

📒 Files selected for processing (16)
  • backend/app/repositories/skill.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/tests/test_skill_display_api.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/types.ts
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

global resetting は全解除ボタンの無効化に使い、押されたグループの区別は
ローカルの resettingKey で行う。確定済みグループが複数ある場合に全ボタンへ
「解除中...」が出ていたのを、対象グループのボタンだけに出るよう修正。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit aa78d18 into mainJul 20, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-decision-reset branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

スキル表示名の畳み込みグループを解除(バラす)できる導線がない(ADR-0016 D11 残課題)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496) - #516

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset
Jul 20, 2026
Merged

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496)#516
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 20, 2026

Copy link
Copy Markdown
Owner

概要

スキル表示名の human-in-the-loop 確定(ADR-0016 D11 / #476)で、一度確定した表示名・畳み込みグループを「解除(バラす)」する導線が無い問題(#496)を解消する。upsert(削除しない)設計で確定行が残り続け、機械デフォルトへ完全リセットできなかったギャップを埋める。

Closes#496

設計方針

「解除」= 対象 identity の Layer 3 確定行を DELETE して機械デフォルトへ戻す単一アクション。グループの全メンバー identity をまとめて送ることで「グループ解除(バラす)」と「確定リセット(表示名を戻す)」を同時に満たす。issue の案1(DELETE エンドポイント)を主軸に採用し、案3のメンバー個別分割 UI は作らない(ADR に残課題として明記)。

変更点

Backend

  • DELETE /skills/display-decisions を新設(identity 群指定で確定行を削除)。authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない確定行は冪等に無視)。リセット後の最新一覧を返す
  • repositories/skill.pydelete_by_identities(user_id 固定・ORM 削除)
  • schemasSkillDisplayResetRequest 追加 → make codegen-typesgenerated.ts 再生成

Web

  • utils/skillDisplay: isResettableGroup / buildResetIdentities(TDD)
  • hooks/useGitHubSkills: reset / resetting(TDD)
  • スキル一覧の確定済みチップに「解除」ボタン追加

Docs

  • ADR-0016 D11 に項 (g)(解除)と変更履歴を追記

テスト

  • backend: 5 ケース(401 / 422 / リセット反映 / グループ全バラし / 冪等)
  • web: util 5・hook 2 ケース(red→green で TDD)
  • E2E: 解除フロー 1 本

ローカル make ci green(backend 729 / web 389 / build OK)、E2E(github-link)8 passed。

レビュー観点

  • API 契約追加: body 付き DELETE の新設(generated.ts は同 PR に再生成済み)
  • 設計分岐: 削除ベースの全リセットを採用、メンバー個別分割 UI は未実装(残課題)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a reset option for confirmed GitHub skill display names.
    • Resetting restores machine-generated names and can ungroup related skills.
    • Reset buttons show progress states and are unavailable during other updates.
  • Bug Fixes

    • Reset operations are validated, idempotent, and preserve existing data when they fail.
  • Documentation

    • Documented the reset behavior, authorization, and fallback display rules.
  • Tests

    • Added coverage for authentication, validation, grouped skills, failures, and end-to-end reset behavior.

一度確定した表示名・畳み込みグループを機械デフォルトへ戻す導線が無く、
upsert(削除しない)設計で確定行が残り続け完全リセットできなかったギャップを埋める。
Backend:
- DELETE /skills/display-decisions を新設(identity 群指定で Layer 3 確定行を削除)。
authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない
確定行は冪等に無視)。リセット後の最新スキル一覧を返す
- repositories/skill.py に delete_by_identities を追加(user_id 固定・ORM 削除)
- schemas に SkillDisplayResetRequest を追加、make codegen-types で generated.ts 再生成
Web:
- utils/skillDisplay に isResettableGroup / buildResetIdentities を追加(TDD)
- useGitHubSkills に reset / resetting を追加(TDD)
- スキル一覧の確定済みチップに「解除」ボタンを追加。グループ全メンバーを
まとめて解除するため畳み込みも解ける
Docs:
- ADR-0016 D11 に項 (g)(解除)と変更履歴を追記
テスト: backend 5 ケース / web util 5・hook 2 ケース / E2E 解除フロー 1 本を追加
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 labels Jul 20, 2026
@coderabbitai

coderabbitaiBot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd3e8a7b-a58b-4e27-955e-c4e0ace210f1

📥 Commits

Reviewing files that changed from the base of the PR and between 5c9251a and 97b01f7.

📒 Files selected for processing (1)
  • web/src/components/github-link/SkillDisplaySection.tsx
📝 Walkthrough

Walkthrough

Adds an authenticated DELETE flow for resetting confirmed GitHub skill display decisions. The backend removes matching records and returns refreshed skills, while the generated client, hook, grouped UI controls, tests, and ADR support the reset behavior.

Changes

Skill display reset

Layer / File(s)Summary
Backend reset contract and deletion flow
backend/app/schemas/github_skill.py, backend/app/repositories/skill.py, backend/app/routers/github_link/endpoints.py, backend/tests/test_skill_display_api.py, docs/adr/0016-github-skill-inference.md
Adds the reset request schema, identity-based deletion, endpoint validation, refreshed skill responses, authorization/idempotency tests, and ADR documentation.
Generated client and hook integration
web/src/api/generated.ts, web/src/api/types.ts, web/src/api/githubLink.ts, web/src/hooks/useGitHubSkills.ts, web/src/hooks/useGitHubSkills.test.ts
Adds the DELETE API contract and wrapper, then exposes reset state and error-preserving reset behavior through useGitHubSkills.
Grouped reset controls and user-facing validation
web/src/utils/skillDisplay.ts, web/src/components/github-link/SkillDisplaySection.tsx, web/src/components/github-link/*.css, web/src/constants/messages.ts, web/src/utils/skillDisplay.test.ts, web/e2e/github-link.spec.ts
Determines resettable groups, builds member identities, renders disabled/in-progress reset controls, adds messages and styling, and verifies fallback display behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant Backend
User->>SkillDisplaySection: Click reset
SkillDisplaySection->>useGitHubSkills: Reset group identities
useGitHubSkills->>GitHubLinkAPI: Send DELETE request
GitHubLinkAPI->>Backend: Delete display decisions
Backend-->>GitHubLinkAPI: Return refreshed skills
GitHubLinkAPI-->>useGitHubSkills: Updated skill list
useGitHubSkills-->>SkillDisplaySection: Render machine defaults
Loading

Possibly related PRs

  • yusuke0610/devforge#495: Introduced the display-decision model and confirmation workflow extended by this reset flow.

Suggested labels:agent

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ Passed主要変更であるスキル表示名の確定解除機能を具体的に示しており、PR内容と一致しています。
Linked Issues check✅ PassedDELETE API、repo削除、UIの解除導線、生成型更新、テスト追加が #496 の要件を満たしています。
Out of Scope Changes check✅ Passedテスト、ADR、生成型、UI補助ユーティリティはいずれも解除機能に直接関連しており、明らかな逸脱はありません。
Docstring Coverage✅ PassedDocstring coverage is 94.74% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/skill-display-decision-reset

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.

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (1)
web/src/components/github-link/SkillDisplaySection.tsx (1)

60-73: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Polish reset button text state.

Because resetting is a single global boolean coming from the hook, clicking "解除" on one group will simultaneously change the text of all visible reset buttons to "解除中...". You can track the clicked group locally to only change the text of the button that was actually clicked, while still keeping all buttons disabled during the request.

✨ Proposed optional polish

Add a local state at the top of the component (e.g., around line 37):

const[resettingKey,setResettingKey]=useState<string|null>(null);

Then update the button rendering to use the local state for its text:

- {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}- {isResettableGroup(group) && (- <button- type="button"- className={styles.resetButton}- onClick={() => void reset(buildResetIdentities(group))}- disabled={resetting || confirming || proposing}- aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}- >- {resetting- ? SKILL_DISPLAY_MESSAGES.RESETTING- : SKILL_DISPLAY_MESSAGES.RESET}- </button>- )}+ {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}+ {isResettableGroup(group) && (+ <button+ type="button"+ className={styles.resetButton}+ onClick={async () => {+ setResettingKey(group.key);+ await reset(buildResetIdentities(group));+ setResettingKey(null);+ }}+ disabled={resetting || confirming || proposing}+ aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}+ >+ {resettingKey === group.key+ ? SKILL_DISPLAY_MESSAGES.RESETTING+ : SKILL_DISPLAY_MESSAGES.RESET}+ </button>+ )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@web/src/components/github-link/SkillDisplaySection.tsx` around lines 60 - 73,
Update SkillDisplaySection’s reset-button state using a local resettingKey state
tied to the clicked group, and use it to show RESETTING only for that group’s
button. Keep the existing global resetting value for disabling all reset buttons
during the request, and clear the local key when the reset operation completes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 60-73: Update SkillDisplaySection’s reset-button state using a
local resettingKey state tied to the clicked group, and use it to show RESETTING
only for that group’s button. Keep the existing global resetting value for
disabling all reset buttons during the request, and clear the local key when the
reset operation completes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d4c189f7-4199-4f82-84e4-44800f6f5404

📥 Commits

Reviewing files that changed from the base of the PR and between 6955c4c and 5c9251a.

📒 Files selected for processing (16)
  • backend/app/repositories/skill.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/tests/test_skill_display_api.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/types.ts
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

global resetting は全解除ボタンの無効化に使い、押されたグループの区別は
ローカルの resettingKey で行う。確定済みグループが複数ある場合に全ボタンへ
「解除中...」が出ていたのを、対象グループのボタンだけに出るよう修正。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit aa78d18 into mainJul 20, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-decision-reset branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

スキル表示名の畳み込みグループを解除(バラす)できる導線がない(ADR-0016 D11 残課題)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496) - #516

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset
Jul 20, 2026
Merged

feat: スキル表示名の畳み込み確定を解除(バラす)できるようにする(ADR-0016 D11 / #496)#516
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-decision-reset

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 20, 2026

Copy link
Copy Markdown
Owner

概要

スキル表示名の human-in-the-loop 確定(ADR-0016 D11 / #476)で、一度確定した表示名・畳み込みグループを「解除(バラす)」する導線が無い問題(#496)を解消する。upsert(削除しない)設計で確定行が残り続け、機械デフォルトへ完全リセットできなかったギャップを埋める。

Closes#496

設計方針

「解除」= 対象 identity の Layer 3 確定行を DELETE して機械デフォルトへ戻す単一アクション。グループの全メンバー identity をまとめて送ることで「グループ解除(バラす)」と「確定リセット(表示名を戻す)」を同時に満たす。issue の案1(DELETE エンドポイント)を主軸に採用し、案3のメンバー個別分割 UI は作らない(ADR に残課題として明記)。

変更点

Backend

  • DELETE /skills/display-decisions を新設(identity 群指定で確定行を削除)。authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない確定行は冪等に無視)。リセット後の最新一覧を返す
  • repositories/skill.pydelete_by_identities(user_id 固定・ORM 削除)
  • schemasSkillDisplayResetRequest 追加 → make codegen-typesgenerated.ts 再生成

Web

  • utils/skillDisplay: isResettableGroup / buildResetIdentities(TDD)
  • hooks/useGitHubSkills: reset / resetting(TDD)
  • スキル一覧の確定済みチップに「解除」ボタン追加

Docs

  • ADR-0016 D11 に項 (g)(解除)と変更履歴を追記

テスト

  • backend: 5 ケース(401 / 422 / リセット反映 / グループ全バラし / 冪等)
  • web: util 5・hook 2 ケース(red→green で TDD)
  • E2E: 解除フロー 1 本

ローカル make ci green(backend 729 / web 389 / build OK)、E2E(github-link)8 passed。

レビュー観点

  • API 契約追加: body 付き DELETE の新設(generated.ts は同 PR に再生成済み)
  • 設計分岐: 削除ベースの全リセットを採用、メンバー個別分割 UI は未実装(残課題)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a reset option for confirmed GitHub skill display names.
    • Resetting restores machine-generated names and can ungroup related skills.
    • Reset buttons show progress states and are unavailable during other updates.
  • Bug Fixes

    • Reset operations are validated, idempotent, and preserve existing data when they fail.
  • Documentation

    • Documented the reset behavior, authorization, and fallback display rules.
  • Tests

    • Added coverage for authentication, validation, grouped skills, failures, and end-to-end reset behavior.

一度確定した表示名・畳み込みグループを機械デフォルトへ戻す導線が無く、
upsert(削除しない)設計で確定行が残り続け完全リセットできなかったギャップを埋める。
Backend:
- DELETE /skills/display-decisions を新設(identity 群指定で Layer 3 確定行を削除)。
authz は confirm と同一(当該ユーザーの検出済みスキルに属すること/存在しない
確定行は冪等に無視)。リセット後の最新スキル一覧を返す
- repositories/skill.py に delete_by_identities を追加(user_id 固定・ORM 削除)
- schemas に SkillDisplayResetRequest を追加、make codegen-types で generated.ts 再生成
Web:
- utils/skillDisplay に isResettableGroup / buildResetIdentities を追加(TDD)
- useGitHubSkills に reset / resetting を追加(TDD)
- スキル一覧の確定済みチップに「解除」ボタンを追加。グループ全メンバーを
まとめて解除するため畳み込みも解ける
Docs:
- ADR-0016 D11 に項 (g)(解除)と変更履歴を追記
テスト: backend 5 ケース / web util 5・hook 2 ケース / E2E 解除フロー 1 本を追加
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 labels Jul 20, 2026
@coderabbitai

coderabbitaiBot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd3e8a7b-a58b-4e27-955e-c4e0ace210f1

📥 Commits

Reviewing files that changed from the base of the PR and between 5c9251a and 97b01f7.

📒 Files selected for processing (1)
  • web/src/components/github-link/SkillDisplaySection.tsx
📝 Walkthrough

Walkthrough

Adds an authenticated DELETE flow for resetting confirmed GitHub skill display decisions. The backend removes matching records and returns refreshed skills, while the generated client, hook, grouped UI controls, tests, and ADR support the reset behavior.

Changes

Skill display reset

Layer / File(s)Summary
Backend reset contract and deletion flow
backend/app/schemas/github_skill.py, backend/app/repositories/skill.py, backend/app/routers/github_link/endpoints.py, backend/tests/test_skill_display_api.py, docs/adr/0016-github-skill-inference.md
Adds the reset request schema, identity-based deletion, endpoint validation, refreshed skill responses, authorization/idempotency tests, and ADR documentation.
Generated client and hook integration
web/src/api/generated.ts, web/src/api/types.ts, web/src/api/githubLink.ts, web/src/hooks/useGitHubSkills.ts, web/src/hooks/useGitHubSkills.test.ts
Adds the DELETE API contract and wrapper, then exposes reset state and error-preserving reset behavior through useGitHubSkills.
Grouped reset controls and user-facing validation
web/src/utils/skillDisplay.ts, web/src/components/github-link/SkillDisplaySection.tsx, web/src/components/github-link/*.css, web/src/constants/messages.ts, web/src/utils/skillDisplay.test.ts, web/e2e/github-link.spec.ts
Determines resettable groups, builds member identities, renders disabled/in-progress reset controls, adds messages and styling, and verifies fallback display behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant Backend
User->>SkillDisplaySection: Click reset
SkillDisplaySection->>useGitHubSkills: Reset group identities
useGitHubSkills->>GitHubLinkAPI: Send DELETE request
GitHubLinkAPI->>Backend: Delete display decisions
Backend-->>GitHubLinkAPI: Return refreshed skills
GitHubLinkAPI-->>useGitHubSkills: Updated skill list
useGitHubSkills-->>SkillDisplaySection: Render machine defaults
Loading

Possibly related PRs

  • yusuke0610/devforge#495: Introduced the display-decision model and confirmation workflow extended by this reset flow.

Suggested labels:agent

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ Passed主要変更であるスキル表示名の確定解除機能を具体的に示しており、PR内容と一致しています。
Linked Issues check✅ PassedDELETE API、repo削除、UIの解除導線、生成型更新、テスト追加が #496 の要件を満たしています。
Out of Scope Changes check✅ Passedテスト、ADR、生成型、UI補助ユーティリティはいずれも解除機能に直接関連しており、明らかな逸脱はありません。
Docstring Coverage✅ PassedDocstring coverage is 94.74% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/skill-display-decision-reset

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.

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (1)
web/src/components/github-link/SkillDisplaySection.tsx (1)

60-73: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Polish reset button text state.

Because resetting is a single global boolean coming from the hook, clicking "解除" on one group will simultaneously change the text of all visible reset buttons to "解除中...". You can track the clicked group locally to only change the text of the button that was actually clicked, while still keeping all buttons disabled during the request.

✨ Proposed optional polish

Add a local state at the top of the component (e.g., around line 37):

const[resettingKey,setResettingKey]=useState<string|null>(null);

Then update the button rendering to use the local state for its text:

- {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}- {isResettableGroup(group) && (- <button- type="button"- className={styles.resetButton}- onClick={() => void reset(buildResetIdentities(group))}- disabled={resetting || confirming || proposing}- aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}- >- {resetting- ? SKILL_DISPLAY_MESSAGES.RESETTING- : SKILL_DISPLAY_MESSAGES.RESET}- </button>- )}+ {/* 確定済みグループのみ、機械デフォルトへ戻す「解除」を出す(#496) */}+ {isResettableGroup(group) && (+ <button+ type="button"+ className={styles.resetButton}+ onClick={async () => {+ setResettingKey(group.key);+ await reset(buildResetIdentities(group));+ setResettingKey(null);+ }}+ disabled={resetting || confirming || proposing}+ aria-label={SKILL_DISPLAY_MESSAGES.resetAriaLabel(group.label)}+ >+ {resettingKey === group.key+ ? SKILL_DISPLAY_MESSAGES.RESETTING+ : SKILL_DISPLAY_MESSAGES.RESET}+ </button>+ )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@web/src/components/github-link/SkillDisplaySection.tsx` around lines 60 - 73,
Update SkillDisplaySection’s reset-button state using a local resettingKey state
tied to the clicked group, and use it to show RESETTING only for that group’s
button. Keep the existing global resetting value for disabling all reset buttons
during the request, and clear the local key when the reset operation completes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 60-73: Update SkillDisplaySection’s reset-button state using a
local resettingKey state tied to the clicked group, and use it to show RESETTING
only for that group’s button. Keep the existing global resetting value for
disabling all reset buttons during the request, and clear the local key when the
reset operation completes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d4c189f7-4199-4f82-84e4-44800f6f5404

📥 Commits

Reviewing files that changed from the base of the PR and between 6955c4c and 5c9251a.

📒 Files selected for processing (16)
  • backend/app/repositories/skill.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/tests/test_skill_display_api.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/types.ts
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

global resetting は全解除ボタンの無効化に使い、押されたグループの区別は
ローカルの resettingKey で行う。確定済みグループが複数ある場合に全ボタンへ
「解除中...」が出ていたのを、対象グループのボタンだけに出るよう修正。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit aa78d18 into mainJul 20, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-decision-reset branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

スキル表示名の畳み込みグループを解除(バラす)できる導線がない(ADR-0016 D11 残課題)

1 participant

@yusuke0610