本文へ移動
cccskills
無料GitHub で公開

feature

Use this whenever the user asks to "implement", "add", "build", "create", or "modify" a feature, page, view, component, or module in this Vue project. Three phases: Phase 0 scope analysis (flows + edge cases + UI needs + plan validation, STOP for user), Phase 1 implementation (layered UI → Store → API, Vue 3 Composition + Vuetify 4, /ui design rules), Phase 2 Definition-of-Done checklist + /verify + /pull-request. Auto-runs /create-module if the target module doesn't exist.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md12.8 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Feature Skill

Phase 0.0 — Issue Claim (if invoked with #N)

When this section runs: only if the invocation provides a GitHub issue number, e.g. /feature #1153. Skip entirely for /feature <freeform-spec> (no issue to claim — proceed directly to Phase 0).

1. Read the issue state

gh issue view <N> --json number,title,state,body,createdAt,assignees,comments

If the command fails (issue not found, network down, missing scope) → STOP and surface the error to the user before proceeding. Do not silently fall through to the claim step.

If state is closed → STOP, ask the user (working on a closed issue is almost always wrong).

2. Detect collision

Inspect assignees[] and the most recent comment whose body starts with WIP — (em dash U+2014, not a hyphen — only the canonical em-dash form is detected; hyphen variants WIP - are silently ignored):

SituationAction
assignees contains @me (current GitHub user)Continue silently — resuming own work
Most recent WIP — comment by @me (any age)Continue silently — resuming own work
assignees empty AND no WIP — comment from anyoneProceed to claim (step 3)
assignees contains user ≠ @meSTOP — surface "Issue #N already assigned to <user>. Take over? (y/N)". Wait for explicit user confirmation.
Most recent WIP — comment by user ≠ @me AND <24h oldSTOP — surface "Issue #N has fresh WIP from <user> (started <ts>). Collision likely. Continue anyway? (y/N)". Wait.
Most recent WIP — comment by user ≠ @me AND >24h oldStale claim — surface "Issue #N has stale WIP from <user> (started <ts>, >24h). Reclaim? (y/N)". Wait.

"Current GitHub user" = gh api user --jq .login. Run inline each time @me is compared (the call is fast and read-only).

3. Claim

If detection passed (or user confirmed override), run both commands:

gh issue edit <N> --add-assignee @me

gh issue comment <N> --body "WIP — session $(date -u +%Y%m%dT%H%M%SZ)-$(uuidgen | head -c 8), branch <branch-name>, started $(date -u +%Y-%m-%dT%H:%M:%SZ)"

Where <branch-name> is the branch this /feature invocation will use (planned name, even if not yet created). If the branch isn't decided yet, use branch TBD. Posting a follow-up comment with the real branch name after /pull-request creates it is best-effort manual — the linked PR superseding the WIP comment is what matters in practice.

4. Aged-scope gate (re-validate before implementing)

The issue body is the primary scope source — read it, not just the title (issues are often filed well ahead of execution, and the intended scope lives in the description). Before coding:

  • If the issue is old (createdAt older than ~7 days), or its body references files, symbols, or routes that no longer match the current codebase → re-validate the scope: check the referenced code, summarize the drift ("the issue says X, the code now does Y"), and present it to the user for confirmation before proceeding. A stale scope implemented as-written ships against a codebase that has moved.
  • Fresh issue with matching references → continue silently.
  • If the user aborts at this gate, roll back the FULL claim from step 3 — gh issue edit <N> --remove-assignee @me AND delete the WIP — comment just posted (gh api -X DELETE repos/<owner>/<repo>/issues/comments/<comment-id> — capture the id when posting, or take the last own WIP — comment). Leaving the comment behind would make step 2 treat the aborted claim as resumable on the next run.

4b. Non-interactive invocation (orchestrated runs)

When the invoker's brief declares a non-interactive run (an orchestrating agent executes the issue headlessly — no human present to answer), every STOP-and-ask in this skill becomes a structured final line instead of a question:

Interactive behaviorNon-interactive replacement
Collision prompt (any y/N row of the table above)Emit SKIP: collision — <detail> and stop
gh command failure (step 1) or state == closedEmit STOP: claim — <error> and stop
Aged-scope drift confirmation (step 4)Emit STOP: freshness — <drift summary> and stop
Phase 0 "Present plan & wait for validation"Satisfied by the issue body when the brief states the scope was validated upstream; insufficient scope → emit STOP: scope — <gap> and stop

Never wait on a prompt in a non-interactive run. If the stop happens after the claim (step 3) already landed, roll the claim back first (step 4's rollback: --remove-assignee + delete the WIP — comment) so the aborted attempt doesn't read as live work on the next run. Interactive sessions keep the exact behavior above.

5. Proceed to Phase 0

Continue to scope analysis below.


Phase 0 — Scope Analysis (interactive, before coding)

1. Identify target module

  • Read CLAUDE.md for project conventions and stack patterns.
  • Read ERRORS.md for known bugs and non-obvious pitfalls to avoid before coding.
  • Which module? Default to ONE unless justified.
  • If the module doesn't exist → run /create-module to scaffold it first, then continue.

2. Analyze flows & edge cases

For each user-facing flow this feature creates or modifies, identify:

  • Happy path — standard success scenario
  • Error path — what fails, what does the user see?
  • "Last one" edge — last owner, last org, last member
  • Retry edge — can the user retry after failure/rejection?
  • Multi-user impact — who else is affected?

3. Check completeness

  • Will every backend API endpoint have a corresponding UI?
  • Every UI action has visible feedback (success + error)
  • Feature works without mailer / without organizations enabled

3b. Minimal-code ladder (run before presenting)

Challenge every mechanism this change would introduce — a store field, a persisted flag, a composable, a wrapper component, a new field in the API contract. Stop at the first rung that holds:

  1. Does a product decision remove it? — accept the cost, accept the failure, do nothing, or surface it to the user. This rung holds only if the mechanism then disappears; if the product still needs it (a message still has to be rendered, a state still has to be held), keep going down the ladder.
  2. Already in this codebase? — reuse the composable, store or component.
  3. In the standard library? — use it.
  4. A native platform feature? (HTML input validation, CSS, a framework or design-system built-in) — use it.
  5. An already-installed dependency? — use it.
  6. One line, a constant, or config? — make it that.
  7. Only then: build it, minimal.

Persisted state is the expensive rung. State that outlives the session — a persisted store slice, a localStorage key, an API field the backend retains and replays back — encoding a policy (a preference, a cap, a memo of a past failure) is not a code choice: code is deleted, persisted state has to be migrated or read forever. A transient request or response field is not this; only state that is retained or restored counts. Rung 0 is mandatory for it, and it needs an explicit, blocking user confirmation in §4 before it is built — a yes on that specific state, never implied by the general plan validation.

Never traded away (lazy ≠ negligent): understanding the problem before picking a rung, validation at trust boundaries, error handling that prevents data loss, security, accessibility, and anything the user explicitly asked for.

4. Present plan & ask questions

STOP and present to the user:

  • Flows identified (happy + error + edge cases)
  • UI elements needed
  • Ladder outcome (§3b) — the selected rung first (<rung> — <what it resolves to>, e.g. 1 reuse — existing composable), then one line per rejected mechanism (<mechanism> — simpler option <X> rejected because <reason>). A change that adds a mechanism and rejects nothing means nobody looked.
  • Persisted state, if any — name it and wait for an explicit yes on it; a general "plan validated" does not cover it, and it is not built without that yes.
  • Open questions or scope decisions

Wait for user validation before coding. (Non-interactive runs: Phase 0.0 §4b — a validated issue body satisfies this step; never wait.)

Phase 1 — Implementation

5. Module structure

Follow layered approach: UI → Store → API. Each layer references only the one below.

  • Use Vue 3 Composition API + Vuetify 4
  • Follow /naming conventions
  • Follow existing module patterns
  • When an edge case or bug affects more than one call site, fix the root cause once in the shared function (store action, helper, service) — not a guard repeated at each caller.

Pass-through store actions: a store action that only forwards an API call (one request, no branching, no derived computation, and no state change after the await — a reset or assignment after the call needs its error-path test, since coverage stays 100% while the failure case goes untested) needs no dedicated test beyond being exercised once in the module's store test — skip the separate happy/error-path block for it. Keep the store's own test file; only the per-action boilerplate goes. This is reachable under this repo's per-file coverage thresholds (vitest.config.js) without lowering or excluding anything, because a zero-logic action has no branches to miss; the coverage report (/verify) is the check. If an action can't clear the thresholds from a single exercising call, give it its own test instead of skipping coverage.

6. UI rules

If the feature has visual components, apply /ui skill guidelines (design-system, components, patterns references).

Feedback:

  • No console.log(err) in catch blocks — the axios interceptor handles snackbar display
  • Use catch { /* interceptor handles */ } or re-throw

Destructive actions — confirmation proportional to impact:

  • Low impact (remove member): simple confirm dialog
  • High impact (delete org/account): type-to-confirm with entity name

Consistency (see /ui patterns):

  • Dialogs: max-width="440"
  • Destructive buttons: color="error" + variant="tonal" (inline) or variant="flat" (in dialog)
  • Primary buttons: color="primary" + variant="flat" + class="text-none text-body-medium"
  • All buttons: :class="config.vuetify.theme.rounded"
  • Role chips: roleColor() + variant="tonal" + size="small" + class="text-capitalize"

Responsive:

  • Side-by-side layouts: flex-column flex-sm-row
  • Data tables: hide non-essential columns on smAndDown
  • Form buttons: :block="$vuetify.display.xs" or flex-wrap

State & UX guards:

  • Forms with dirty flag → beforeRouteLeave guard
  • Dismissible banners → persist in sessionStorage, not component data
  • Active context → visually indicate (badge, border, chip)
  • Generated links/tokens → copy button with clipboard API
  • Dates: relative for recent ("2d ago"), absolute for historical ("DD/MM/YY")

Phase 2 — Definition of Done

7. Self-review checklist

Flow completeness:

  • Every API has a UI, every action shows feedback
  • Destructive actions have appropriate confirmation
  • Edge cases handled (last-one, retry, no mailer)

Consistency:

  • Dialog widths, button styles, chips follow rules above
  • Responsive layout verified at mobile breakpoint

State:

  • Unsaved changes guarded
  • Dismissible UI persisted correctly
  • Active context visually marked

Modularity:

  • Isolated in ONE module (or justified)
  • No cross-module Store imports except useAuthStore/useCoreStore
  • Tests added
  • Tests: unit tests (*.unit.tests.js) for all changes, except a pass-through store action (see Phase 1 §5) which only needs to be exercised once in the module's store test. E2E (*.e2e.tests.js) only if the change affects a critical user flow (auth, org onboarding, invite/join).

Error documentation:

  • If a non-obvious bug was fixed, document it in ERRORS.md (root of repo) with: symptom, root cause, fix

7b. Elegance check

For non-trivial changes: pause and ask yourself "is there a simpler or more elegant approach?" If the current implementation feels hacky, refactor before proceeding.

8. Run /verify

9. Run /pull-request

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Use this whenever the user asks to "create a module", "scaffold a feature", "add a Vue domain", "new module called X", or starts work on a brand-new vertical (views + components + store + router entry + tests). Duplicates the canonical `src/modules/tasks` template, applies kebab/Pascal/camel/ UPPER renames, and wires config-driven values. Module stays self-contained.

日本語の概要は準備中です。原文の説明を表示しています。

pierreb-devkit/Vue202026年10月9日 更新

naming

無料

Use this whenever a new file/folder is created or renamed in this Vue project, when reviewing a module for consistency, or when the right path for a file is unclear. Also triggers on "what should I name this?", "is this file named correctly?", "audit module naming". Enforces kebab-case folders, dot-prefixed `{module}.{name}.{type}.vue|js` files, multi-entity rules, singular vs plural for views, and the layered structure UI → Store → API.

日本語の概要は準備中です。原文の説明を表示しています。

pierreb-devkit/Vue202026年10月9日 更新

Use this whenever the user asks to "open a PR", "ship this", "create the pull request", "make a PR", or once a Vue feature/fix is verified and ready to push. Full lifecycle: branch → commit (commitizen) → issue → draft PR → CI → ready → autonomous monitor loop (fix comments, resolve threads, iterate until CI green + zero unresolved threads). `--perfect` adds a CodeRabbit convergence loop on top. Never works on `main`/`master`, never uses `--no-verify`.

日本語の概要は準備中です。原文の説明を表示しています。

pierreb-devkit/Vue202026年10月9日 更新

ui

無料

Design system reference for the Devkit Vue stack (Vuetify 4 + custom theme helpers). Use when asked about styling, theming, layout, design system, Vuetify components, visual verification, or UI patterns. Automatically consumed by /feature when the task has a visual component. Can also be invoked directly for design-only tasks (restyle, theme change, layout fix).

日本語の概要は準備中です。原文の説明を表示しています。

pierreb-devkit/Vue202026年10月9日 更新

Use this whenever a downstream Vue project needs to absorb upstream Devkit Vue changes — triggers on "update stack", "sync with devkit", "merge upstream", "pull stack updates", "resolve stack conflicts". Two-phase: ISO merge (stack modules stay byte-identical to upstream) then project alignment (apply MIGRATIONS.md, diff project modules vs `tasks` reference, /verify). Stack-code failures get an issue on `pierreb-devkit/Vue`.

日本語の概要は準備中です。原文の説明を表示しています。

pierreb-devkit/Vue202026年10月9日 更新

verify

無料

Run this after every code change in this Vue project, before committing, before opening a PR, or whenever the user says "verify", "check", "lint", "run tests", "build", "audit". Diff audit (router guards, store boundaries, UX, /ui consistency, error handling) → lint → tests + coverage gate → build. Coverage drops → add tests, never lower thresholds. Triggers on "is this ready to commit?", "any issues?", "tests passing?".

日本語の概要は準備中です。原文の説明を表示しています。

pierreb-devkit/Vue202026年10月9日 更新

pierreb-devkit のスキルをすべて見る

このスキルの問題を報告する