@simplysm/sd-claude 13.0.75 → 13.0.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claude/refs/sd-code-conventions.md +102 -4
- package/claude/refs/sd-solid.md +13 -2
- package/claude/refs/sd-workflow.md +2 -1
- package/claude/rules/sd-claude-rules.md +18 -1
- package/claude/rules/sd-refs-linker.md +1 -1
- package/claude/sd-statusline.js +51 -9
- package/claude/skills/sd-api-name-review/SKILL.md +118 -13
- package/claude/skills/sd-brainstorm/SKILL.md +82 -8
- package/claude/skills/sd-check/SKILL.md +28 -14
- package/claude/skills/sd-commit/SKILL.md +1 -4
- package/claude/skills/sd-debug/SKILL.md +8 -13
- package/claude/skills/sd-debug/condition-based-waiting.md +5 -11
- package/claude/skills/sd-debug/root-cause-tracing.md +18 -33
- package/claude/skills/sd-explore/SKILL.md +118 -0
- package/claude/skills/sd-plan/SKILL.md +31 -0
- package/claude/skills/sd-plan-dev/SKILL.md +92 -75
- package/claude/skills/sd-plan-dev/code-quality-reviewer-prompt.md +1 -3
- package/claude/skills/sd-plan-dev/implementer-prompt.md +10 -1
- package/claude/skills/sd-readme/SKILL.md +1 -1
- package/claude/skills/sd-review/SKILL.md +128 -55
- package/claude/skills/sd-review/api-reviewer-prompt.md +23 -38
- package/claude/skills/sd-review/code-reviewer-prompt.md +26 -29
- package/claude/skills/sd-review/convention-checker-prompt.md +61 -0
- package/claude/skills/sd-review/refactoring-analyzer-prompt.md +92 -0
- package/claude/skills/sd-skill/SKILL.md +20 -3
- package/claude/skills/sd-skill/anthropic-best-practices.md +71 -1091
- package/claude/skills/sd-skill/testing-skills-with-subagents.md +9 -5
- package/claude/skills/sd-skill/writing-guide.md +7 -11
- package/claude/skills/sd-tdd/SKILL.md +15 -20
- package/claude/skills/sd-use/SKILL.md +18 -27
- package/claude/skills/sd-worktree/SKILL.md +58 -113
- package/package.json +1 -1
- package/claude/skills/sd-check/baseline-analysis.md +0 -150
- package/claude/skills/sd-check/test-scenarios.md +0 -205
- package/claude/skills/sd-debug/test-baseline-pressure.md +0 -61
- package/claude/skills/sd-review/code-simplifier-prompt.md +0 -88
- package/claude/skills/sd-worktree/sd-worktree.mjs +0 -152
|
@@ -19,6 +19,7 @@ Before using extension methods: Verify actual existence in `@simplysm/core-commo
|
|
|
19
19
|
|
|
20
20
|
- Do not use `Async` suffix on function names — Async is the default
|
|
21
21
|
- When both sync and async versions exist, use `Sync` suffix on the sync function
|
|
22
|
+
- **Exception — extensions**: When adding an async version to an existing prototype (e.g., `Array`), follow the original naming convention. If the sync method already exists without a `Sync` suffix, use `Async` suffix for the async version.
|
|
22
23
|
|
|
23
24
|
```typescript
|
|
24
25
|
// Good
|
|
@@ -27,8 +28,12 @@ function readFileSync() { ... } // Sync version
|
|
|
27
28
|
|
|
28
29
|
// Bad
|
|
29
30
|
async function readFileAsync() { ... } // Async suffix prohibited
|
|
31
|
+
|
|
32
|
+
// Exception — Array extension already has mapMany()
|
|
33
|
+
Array.prototype.mapManyAsync = async function () { ... } // OK
|
|
30
34
|
```
|
|
31
35
|
|
|
36
|
+
|
|
32
37
|
## File Naming
|
|
33
38
|
|
|
34
39
|
- Auxiliary files (`types.ts`, `utils.ts`, etc.) must be prefixed with the main file name (e.g., `CrudSheet.types.ts`)
|
|
@@ -37,7 +42,7 @@ async function readFileAsync() { ... } // Async suffix prohibited
|
|
|
37
42
|
## JSDoc Convention
|
|
38
43
|
|
|
39
44
|
- Not enforced — omit when code is self-explanatory
|
|
40
|
-
- When written, use
|
|
45
|
+
- When written, use English
|
|
41
46
|
|
|
42
47
|
## Re-export Restriction
|
|
43
48
|
|
|
@@ -46,12 +51,105 @@ async function readFileAsync() { ... } // Async suffix prohibited
|
|
|
46
51
|
|
|
47
52
|
## index.ts Export Pattern
|
|
48
53
|
|
|
49
|
-
-
|
|
50
|
-
- Small packages (≤10 exports): `//` comments only
|
|
54
|
+
- Use `//` comments to group exports
|
|
51
55
|
- Always `export *` (wildcard), never explicit `export type { ... } from "..."`
|
|
52
56
|
|
|
57
|
+
## `#region` / `#endregion`
|
|
58
|
+
|
|
59
|
+
- When splitting a large ts/tsx file has a bigger tradeoff than keeping it as-is, use `#region`/`#endregion` to organize sections within the file
|
|
60
|
+
- Do not use in simple export files like index.ts
|
|
61
|
+
|
|
62
|
+
## `any` vs `unknown` vs Generics
|
|
63
|
+
|
|
64
|
+
Choose based on **what you do with the value**:
|
|
65
|
+
|
|
66
|
+
| Type | When | Key rule |
|
|
67
|
+
|------|------|----------|
|
|
68
|
+
| `any` | Value is **passed through** without property access | No `.prop`, no method calls, no narrowing |
|
|
69
|
+
| `unknown` | Value's properties **will be accessed** but type is unknown | Must narrow with type guard before any access |
|
|
70
|
+
| Generic `<T>` | **Input/output type relationship** must be preserved | Caller's type flows through to return type |
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
// any — pure pass-through, no property access
|
|
74
|
+
function logAndStore(value: any): void {
|
|
75
|
+
console.log(value); // OK: no property access
|
|
76
|
+
storage.push(value); // OK: just forwarding
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// unknown — will access properties, must narrow first
|
|
80
|
+
function getName(data: unknown): string {
|
|
81
|
+
if (typeof data === "object" && data !== null && "name" in data) {
|
|
82
|
+
return String((data as { name: unknown }).name);
|
|
83
|
+
}
|
|
84
|
+
throw new Error("No name property");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Generic — input type preserved in output
|
|
88
|
+
function wrapValue<T>(value: T): { value: T } {
|
|
89
|
+
return { value };
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**any vs Generic for pass-through:** If the function only forwards a value without accessing it AND the caller does not need type preservation in the return, use `any`. If the caller needs the same type back (input→output relationship), use a generic.
|
|
94
|
+
|
|
53
95
|
## Type Safety for Public APIs
|
|
54
96
|
|
|
55
97
|
- API changes must be detectable via **typecheck alone** — all affected usage sites must show compile errors
|
|
56
98
|
- Public component props must support **IDE intellisense** (autocomplete, type hints)
|
|
57
|
-
-
|
|
99
|
+
- **No `Record<string, any>` for structured props** — define explicit interfaces so consumers get autocomplete
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
// Bad — consumers get no autocomplete, changes are invisible
|
|
103
|
+
interface TableProps {
|
|
104
|
+
columns: Record<string, any>;
|
|
105
|
+
onRowClick: Function;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Good — changes to ColumnDef break consumers at compile time
|
|
109
|
+
interface TableProps<TRow> {
|
|
110
|
+
columns: ColumnDef<TRow>[];
|
|
111
|
+
onRowClick?: (row: TRow) => void;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Forced Type Casting Prohibition
|
|
116
|
+
|
|
117
|
+
- **`as unknown as X` is prohibited** — dangerous escape hatch that silences real type errors
|
|
118
|
+
- **`as X` must be avoided** unless there is no alternative — when tempted, try these fixes first:
|
|
119
|
+
|
|
120
|
+
| Type error situation | Fix (instead of `as`) |
|
|
121
|
+
|---------------------|-----------------------|
|
|
122
|
+
| Missing properties | Add them to the interface |
|
|
123
|
+
| Type too wide | Use generics to propagate correctly |
|
|
124
|
+
| Unknown shape | Type guard: `if ("prop" in obj)`, `instanceof` |
|
|
125
|
+
| Multiple shapes | Discriminated union or overload |
|
|
126
|
+
| Wrong at source | Fix the root cause, not the usage site |
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// Bad — casting hides the real problem
|
|
130
|
+
const admin = user as unknown as AdminUser;
|
|
131
|
+
|
|
132
|
+
// Bad — lazy cast instead of proper narrowing
|
|
133
|
+
const name = (event as any).target.name;
|
|
134
|
+
|
|
135
|
+
// Good — fix parameter type at the source
|
|
136
|
+
function getAdminDashboard(admin: AdminUser): string { ... }
|
|
137
|
+
|
|
138
|
+
// Good — narrow unknown with type guard
|
|
139
|
+
function getNameFromEvent(event: unknown): string {
|
|
140
|
+
if (typeof event === "object" && event !== null && "target" in event) {
|
|
141
|
+
const target = event.target;
|
|
142
|
+
if (typeof target === "object" && target !== null && "name" in target) {
|
|
143
|
+
return String(target.name);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
throw new Error("Invalid event structure");
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Boolean Prop Defaults
|
|
151
|
+
|
|
152
|
+
- Name boolean props so their default value is `false`
|
|
153
|
+
- Prefer `hide*`, `disable*` patterns where the feature is ON by default
|
|
154
|
+
- This avoids double-negation in JSX: `hideX={false}` is clearer than `showX={true}` when both mean "show X"
|
|
155
|
+
- Exception: inherent HTML attributes like `draggable` may default to `true`
|
package/claude/refs/sd-solid.md
CHANGED
|
@@ -34,8 +34,17 @@
|
|
|
34
34
|
|
|
35
35
|
All sub-components via dot notation only (`Parent.Child`).
|
|
36
36
|
|
|
37
|
-
-
|
|
38
|
-
|
|
37
|
+
- Export using `Object.assign` pattern:
|
|
38
|
+
```ts
|
|
39
|
+
export const Select = Object.assign(SelectInnerComponent, {
|
|
40
|
+
Item: SelectItem,
|
|
41
|
+
Header: SelectHeader,
|
|
42
|
+
Action: SelectAction,
|
|
43
|
+
ItemTemplate: SelectItemTemplate,
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
- Do NOT declare a separate type or interface for the compound component (e.g., `SelectComponent`, `TabsComponent`)
|
|
47
|
+
- Do NOT use type assertions on the export (e.g., `as SelectComponent`)
|
|
39
48
|
- Don't export sub-components separately (export parent only)
|
|
40
49
|
- UI elements → compound sub-components, non-rendering config (state, behavior, callbacks) → props
|
|
41
50
|
|
|
@@ -48,6 +57,8 @@ All sub-components via dot notation only (`Parent.Child`).
|
|
|
48
57
|
- Default `rem`, use `em` for text-relative sizing (e.g., Icon)
|
|
49
58
|
- Use `clsx()` with semantic grouping + `twMerge()` for conflict resolution
|
|
50
59
|
- Before modifying styles: Read existing class patterns of the same component
|
|
60
|
+
- **Class strings inline**: Do not extract class strings into separate variables — write them directly in the JSX return
|
|
61
|
+
- **`*.styles.ts` files**: Tailwind class strings must be wrapped with `clsx()` for IntelliSense support
|
|
51
62
|
|
|
52
63
|
## Application View Naming (`client-*`)
|
|
53
64
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
## Problem-Solving Principles
|
|
7
7
|
|
|
8
8
|
- **Root cause first**: When encountering errors or unexpected behavior, always investigate the root cause before attempting a fix. Do not apply workarounds, hacks, or surface-level patches.
|
|
9
|
-
- **No band-aid fixes**: Avoid techniques like suppressing errors, adding defensive checks to hide symptoms, or
|
|
9
|
+
- **No band-aid fixes**: Avoid techniques like suppressing errors, adding defensive checks to hide symptoms, bypassing validation, or inflating timeout values. These mask the real problem and create technical debt.
|
|
10
10
|
- **Consider refactoring**: If the root cause reveals a design flaw or structural issue, propose a refactoring approach rather than working around it. A proper fix — even if larger in scope — is better than a fragile workaround.
|
|
11
11
|
- **Trace the full chain**: Follow the error or issue through the entire call chain (caller -> callee -> dependencies) to understand why it happens, not just where it happens.
|
|
12
12
|
- **When uncertain, ask**: If the root cause is unclear or the fix requires significant changes, discuss with the user before proceeding. Present findings and options rather than silently applying a quick fix.
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
- Before creating new files: Glob/Read similar existing files to check structure and patterns
|
|
17
17
|
- Before modifying functions/classes: Read the file to understand existing code style
|
|
18
18
|
- When unsure about API/method usage: Check signatures in source code
|
|
19
|
+
- **Always search the local codebase first.** Do not search the web or external docs until you have confirmed the answer is not in local code.
|
|
19
20
|
- **If confidence is low, ask the user instead of writing code**
|
|
20
21
|
|
|
21
22
|
## Memory Policy
|
|
@@ -35,10 +35,27 @@ If a referenced file or document cannot be found, **stop immediately and ask the
|
|
|
35
35
|
- **Do NOT comment on code outside the requested change.** This includes:
|
|
36
36
|
- Listing issues you noticed but did not fix
|
|
37
37
|
- Describing what you "left alone" or "did not change"
|
|
38
|
-
- "
|
|
38
|
+
- "reference", "suggestions", "by the way", "note", "what I left alone"
|
|
39
39
|
- Any unsolicited observations about surrounding code quality
|
|
40
40
|
- Only describe **what you changed** — nothing else
|
|
41
41
|
|
|
42
|
+
### Analysis & Comparison
|
|
43
|
+
|
|
44
|
+
- When analyzing, comparing, diffing, or auditing: **enumerate all items exhaustively**. Never provide a shallow summary — list every difference, even minor ones.
|
|
45
|
+
- Example: v12 vs v13 migration gap → list ALL API, type, pattern differences item by item
|
|
46
|
+
|
|
47
|
+
### Direct Action Requests
|
|
48
|
+
|
|
49
|
+
- When the user provides a specific action (e.g., "rename X to Y", "delete this file"), **execute it directly**. Do not route through skill agents or sub-agent workflows for trivial operations.
|
|
50
|
+
|
|
51
|
+
## Worktree Rules
|
|
52
|
+
|
|
53
|
+
All git worktrees MUST be created under the **`.worktrees/`** directory (project root). Never use `.claude/worktrees/` or any other location.
|
|
54
|
+
|
|
55
|
+
- When using `isolation: "worktree"` on Agent tool calls, the worktree is created in `.worktrees/`.
|
|
56
|
+
- **After work is complete, you MUST delete the worktree and its branch** before finishing. No worktree may be left behind.
|
|
57
|
+
- Prefer using the **`/sd-worktree`** skill for worktree creation/deletion. It includes fixes for Claude Code's built-in worktree bugs.
|
|
58
|
+
|
|
42
59
|
## Asking Clarifying Questions
|
|
43
60
|
|
|
44
61
|
When you need to ask the user a question, you MUST use the `AskUserQuestion` tool. Do NOT ask questions in plain text.
|
|
@@ -13,7 +13,7 @@ Determine the major version by the `version` field in `package.json`.
|
|
|
13
13
|
|
|
14
14
|
| When | Read this file |
|
|
15
15
|
| ------------------------------------------------ | ------------------------------------- |
|
|
16
|
-
| Writing or
|
|
16
|
+
| Writing, modifying, or reviewing code | `.claude/refs/sd-code-conventions.md` |
|
|
17
17
|
| Working with `.cache/` or Playwright screenshots | `.claude/refs/sd-directories.md` |
|
|
18
18
|
| Using `@simplysm/*` package APIs | `.claude/refs/sd-simplysm-docs.md` |
|
|
19
19
|
| Debugging, problem-solving, or planning approach | `.claude/refs/sd-workflow.md` |
|
package/claude/sd-statusline.js
CHANGED
|
@@ -8,6 +8,8 @@ import { stdin } from "process";
|
|
|
8
8
|
|
|
9
9
|
const STDIN_TIMEOUT_MS = 5000;
|
|
10
10
|
const FETCH_TIMEOUT_MS = 3000;
|
|
11
|
+
const CACHE_TTL_MS = 120_000; // 2 minutes
|
|
12
|
+
const CACHE_PATH = path.join(os.homedir(), ".claude", "usage-api-cache.json");
|
|
11
13
|
|
|
12
14
|
//#endregion
|
|
13
15
|
|
|
@@ -75,16 +77,49 @@ function getOAuthToken() {
|
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
/**
|
|
78
|
-
*
|
|
80
|
+
* Read cached usage data from local file.
|
|
81
|
+
* @returns {{ data: object, timestamp: number } | undefined}
|
|
82
|
+
*/
|
|
83
|
+
function readCache() {
|
|
84
|
+
try {
|
|
85
|
+
if (!fs.existsSync(CACHE_PATH)) return undefined;
|
|
86
|
+
const content = fs.readFileSync(CACHE_PATH, "utf-8");
|
|
87
|
+
return JSON.parse(content);
|
|
88
|
+
} catch {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Write usage data to local cache file.
|
|
95
|
+
* @param {object} data
|
|
96
|
+
*/
|
|
97
|
+
function writeCache(data) {
|
|
98
|
+
try {
|
|
99
|
+
fs.writeFileSync(CACHE_PATH, JSON.stringify({ data, timestamp: Date.now() }), "utf-8");
|
|
100
|
+
} catch {
|
|
101
|
+
// ignore write errors
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Fetch Anthropic API usage information using OAuth token, with 1-minute cache.
|
|
79
107
|
* @param {string} token - OAuth access token
|
|
108
|
+
* @param {string} version - Claude Code version
|
|
80
109
|
* @returns {Promise<{
|
|
81
|
-
* seven_day?: {utilization?: number, resets_at?: string},
|
|
82
|
-
* daily?: {utilization?: number, resets_at?: string},
|
|
83
|
-
* five_hour?: {utilization?: number, resets_at?: string},
|
|
84
|
-
* extra_usage?: {is_enabled?: boolean, monthly_limit?: number | null, used_credits?: number}
|
|
110
|
+
* seven_day?: {utilization?: number, resets_at?: string},
|
|
111
|
+
* daily?: {utilization?: number, resets_at?: string},
|
|
112
|
+
* five_hour?: {utilization?: number, resets_at?: string},
|
|
113
|
+
* extra_usage?: {is_enabled?: boolean, monthly_limit?: number | null, used_credits?: number}
|
|
85
114
|
* } | undefined>}
|
|
86
115
|
*/
|
|
87
|
-
async function fetchUsage(token) {
|
|
116
|
+
async function fetchUsage(token, version) {
|
|
117
|
+
// Return cached data if still valid
|
|
118
|
+
const cache = readCache();
|
|
119
|
+
if (cache != null && Date.now() - cache.timestamp < CACHE_TTL_MS) {
|
|
120
|
+
return cache.data;
|
|
121
|
+
}
|
|
122
|
+
|
|
88
123
|
try {
|
|
89
124
|
const controller = new AbortController();
|
|
90
125
|
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
@@ -92,7 +127,8 @@ async function fetchUsage(token) {
|
|
|
92
127
|
const response = await fetch("https://api.anthropic.com/api/oauth/usage", {
|
|
93
128
|
headers: {
|
|
94
129
|
"Authorization": `Bearer ${token}`,
|
|
95
|
-
"
|
|
130
|
+
"Accept": "application/json",
|
|
131
|
+
'anthropic-beta': 'oauth-2025-04-20'
|
|
96
132
|
},
|
|
97
133
|
signal: controller.signal,
|
|
98
134
|
});
|
|
@@ -100,18 +136,23 @@ async function fetchUsage(token) {
|
|
|
100
136
|
clearTimeout(timeout);
|
|
101
137
|
|
|
102
138
|
if (!response.ok) {
|
|
139
|
+
// API failed — update timestamp to prevent retry for TTL duration
|
|
140
|
+
writeCache(cache?.data ?? {});
|
|
103
141
|
return undefined;
|
|
104
142
|
}
|
|
105
143
|
|
|
106
144
|
const data = await response.json();
|
|
107
145
|
|
|
108
|
-
// Validate response structure
|
|
109
146
|
if (data == null || typeof data !== "object") {
|
|
147
|
+
writeCache(cache?.data ?? {});
|
|
110
148
|
return undefined;
|
|
111
149
|
}
|
|
112
150
|
|
|
151
|
+
writeCache(data);
|
|
113
152
|
return data;
|
|
114
153
|
} catch {
|
|
154
|
+
// Network error — update timestamp to prevent retry for TTL duration
|
|
155
|
+
writeCache(cache?.data ?? {});
|
|
115
156
|
return undefined;
|
|
116
157
|
}
|
|
117
158
|
}
|
|
@@ -172,6 +213,7 @@ function formatTimeRemaining(isoDate) {
|
|
|
172
213
|
* @property {{display_name?: string}} [model] - Model information
|
|
173
214
|
* @property {{context_window_size?: number, remaining_context_tokens?: number, current_usage?: {input_tokens?: number, output_tokens?: number, cache_creation_input_tokens?: number, cache_read_input_tokens?: number}}} [context_window] - Context window information
|
|
174
215
|
* @property {{tokens_used?: number, tokens_limit?: number}} [weekly_token_usage] - Weekly token usage (fallback)
|
|
216
|
+
* @property {string} [version] - Claude Code version
|
|
175
217
|
*/
|
|
176
218
|
|
|
177
219
|
/**
|
|
@@ -212,7 +254,7 @@ async function main() {
|
|
|
212
254
|
let extraUsage = "";
|
|
213
255
|
|
|
214
256
|
if (token != null) {
|
|
215
|
-
const usageResponse = await fetchUsage(token);
|
|
257
|
+
const usageResponse = await fetchUsage(token, input.version ?? "unknown");
|
|
216
258
|
if (usageResponse != null) {
|
|
217
259
|
// Use daily or five_hour
|
|
218
260
|
const dailyData = usageResponse.daily ?? usageResponse.five_hour;
|
|
@@ -8,32 +8,97 @@ model: sonnet
|
|
|
8
8
|
|
|
9
9
|
## Overview
|
|
10
10
|
|
|
11
|
-
Compare a library/module's public API names against industry standards and review internal consistency, producing a standardization report. **
|
|
11
|
+
Compare a library/module's public API names against industry standards and review internal consistency, producing a standardization report. Uses **sd-explore** to extract the API surface, then dispatches research agents for industry comparison.
|
|
12
|
+
|
|
13
|
+
**Analysis only — no code modifications.**
|
|
14
|
+
|
|
15
|
+
## Principles
|
|
16
|
+
|
|
17
|
+
- **Breaking changes are irrelevant**: Do NOT dismiss findings because renaming would cause a breaking change.
|
|
18
|
+
- **Internal consistency first**: Internal naming consistency takes priority over external standards.
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
- `/sd-api-name-review packages/solid` — full naming review
|
|
23
|
+
- `/sd-api-name-review packages/orm-common` — review specific package
|
|
24
|
+
- `/sd-api-name-review` — if no argument, ask the user for the target path
|
|
12
25
|
|
|
13
26
|
## Target Selection
|
|
14
27
|
|
|
15
|
-
|
|
16
|
-
|
|
28
|
+
- With argument: review source code at the given path
|
|
29
|
+
- Without argument: ask the user for the target path
|
|
30
|
+
|
|
31
|
+
**Important:** Review ALL source files under the target path. Do not use git status or git diff to limit scope.
|
|
32
|
+
|
|
33
|
+
## Workflow
|
|
34
|
+
|
|
35
|
+
### Step 1: Prepare Context
|
|
36
|
+
|
|
37
|
+
Read these files:
|
|
38
|
+
- `CLAUDE.md` — project overview
|
|
39
|
+
- `.claude/rules/sd-refs-linker.md` — reference guide
|
|
40
|
+
- Target's `package.json` — version (v12/v13)
|
|
17
41
|
|
|
18
|
-
|
|
42
|
+
Based on version and target, read all applicable reference files (e.g., `sd-code-conventions.md`, `sd-solid.md`).
|
|
19
43
|
|
|
20
|
-
|
|
44
|
+
Keep the collected conventions in memory — they will inform the analysis in later steps.
|
|
21
45
|
|
|
46
|
+
### Step 2: API Extraction (via sd-explore)
|
|
47
|
+
|
|
48
|
+
Follow the **sd-explore** workflow to extract the target's public API surface.
|
|
49
|
+
|
|
50
|
+
**sd-explore input:**
|
|
51
|
+
|
|
52
|
+
- **Target path**: the review target directory
|
|
53
|
+
- **Name**: `api-name-review`
|
|
54
|
+
- **File patterns**: `**/*.ts`, `**/*.tsx` (exclude `node_modules`, `dist`)
|
|
55
|
+
- **Analysis instructions**:
|
|
56
|
+
|
|
57
|
+
"For each file, extract its public API surface:
|
|
22
58
|
- All exported identifiers (functions, classes, types, constants, etc.)
|
|
23
59
|
- Names and types of user-facing parameters/options/config
|
|
24
60
|
- Naming pattern classification (prefixes, suffixes, verb/adjective/noun usage, abbreviations, etc.)
|
|
25
61
|
|
|
26
|
-
|
|
62
|
+
Output format:
|
|
63
|
+
```
|
|
64
|
+
# API Surface: [directory names]
|
|
27
65
|
|
|
28
|
-
|
|
66
|
+
## Exports
|
|
67
|
+
- `path/to/file.ts` — `exportName`: type (function/class/type/const), signature summary
|
|
68
|
+
|
|
69
|
+
## Naming Patterns
|
|
70
|
+
- Pattern: description (e.g., 'create-' prefix for factory functions)
|
|
71
|
+
- Examples: list of identifiers using this pattern
|
|
72
|
+
```
|
|
73
|
+
"
|
|
74
|
+
|
|
75
|
+
### Step 3: Industry Standard Research
|
|
76
|
+
|
|
77
|
+
Based on Step 2 results:
|
|
29
78
|
|
|
30
79
|
1. Identify **recurring naming patterns** from the extracted API
|
|
31
80
|
2. Determine the target's domain and tech stack to **select comparable libraries**
|
|
32
|
-
3.
|
|
81
|
+
3. Dispatch **parallel agents** to web-search/fetch official docs for each comparable library, investigating naming conventions for the same pattern categories
|
|
82
|
+
|
|
83
|
+
Each research agent receives:
|
|
33
84
|
|
|
34
|
-
|
|
85
|
+
```
|
|
86
|
+
Research naming conventions in [library name] for these pattern categories:
|
|
87
|
+
[list of patterns from Step 2]
|
|
35
88
|
|
|
36
|
-
|
|
89
|
+
For each pattern, document:
|
|
90
|
+
- What naming convention the library uses
|
|
91
|
+
- Specific examples from the API
|
|
92
|
+
- Any documented rationale for the convention
|
|
93
|
+
|
|
94
|
+
Write results to: .tmp/api-name-review/research-{library_name}.md
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Step 4: Comparative Analysis & Verification
|
|
98
|
+
|
|
99
|
+
Cross-compare Step 2 (API surface) and Step 3 (industry research) results.
|
|
100
|
+
|
|
101
|
+
Classify each naming pattern:
|
|
37
102
|
|
|
38
103
|
| Priority | Criteria |
|
|
39
104
|
| -------- | ------------------------------------------------------ |
|
|
@@ -42,8 +107,48 @@ Cross-compare Phase 1 and Phase 2 results to produce the report.
|
|
|
42
107
|
| **P2** | Better industry term exists (optional) |
|
|
43
108
|
| **Keep** | Already aligned with standards |
|
|
44
109
|
|
|
45
|
-
|
|
110
|
+
**MANDATORY: Read actual code for EVERY finding.** For each finding, `Read` the file at the referenced location before finalizing. Do NOT rely on explore descriptions alone — verify against the actual code.
|
|
111
|
+
|
|
112
|
+
Each finding includes: current name, recommended change, rationale (usage patterns per library).
|
|
113
|
+
|
|
114
|
+
### Step 5: Report & User Confirmation
|
|
115
|
+
|
|
116
|
+
Present **Keep** items to the user as a summary.
|
|
117
|
+
|
|
118
|
+
Then present each **P0/P1/P2** finding to the user **one at a time**, ordered by priority (P0 → P1 → P2).
|
|
119
|
+
|
|
120
|
+
For each finding, explain:
|
|
121
|
+
1. **What the problem is** — the current name and why it's misaligned or inconsistent
|
|
122
|
+
2. **How it could be fixed** — recommended name(s) with rationale from surveyed libraries
|
|
123
|
+
3. **Ask**: address this or skip?
|
|
124
|
+
|
|
125
|
+
Collect only findings the user confirms. If the user skips all findings, report that and end.
|
|
126
|
+
|
|
127
|
+
### Step 6: Brainstorm Handoff
|
|
128
|
+
|
|
129
|
+
Invoke **sd-brainstorm** with all user-confirmed findings as context:
|
|
130
|
+
|
|
131
|
+
_
|
|
132
|
+
"Design naming changes for the following review findings.
|
|
133
|
+
|
|
134
|
+
**For each finding, you MUST:**
|
|
135
|
+
1. Review it thoroughly — examine the code, understand the context, assess the real impact
|
|
136
|
+
2. If any aspect is unclear or ambiguous, ask the user (one question at a time, per brainstorm rules)
|
|
137
|
+
3. If a finding has low cost-benefit (adds complexity for marginal gain, pure style preference, scope too small), drop it. After triage, briefly list all dropped findings with one-line reasons (no user confirmation needed).
|
|
138
|
+
4. For findings worth fixing, explore approaches and design solutions
|
|
139
|
+
|
|
140
|
+
Findings that survive your triage become the design scope. Apply your normal brainstorm process (gap review → approaches → design presentation) to the surviving findings as a group.
|
|
141
|
+
|
|
142
|
+
<include all confirmed findings with their priority, file:line, current name, recommended name, and rationale>"
|
|
143
|
+
|
|
144
|
+
sd-brainstorm then owns the full cycle: triage (with user input as needed) → design.
|
|
46
145
|
|
|
47
|
-
##
|
|
146
|
+
## Common Mistakes
|
|
48
147
|
|
|
49
|
-
|
|
148
|
+
| Mistake | Fix |
|
|
149
|
+
|---------|-----|
|
|
150
|
+
| Using git diff to limit scope | Review ALL source files under target |
|
|
151
|
+
| Skipping context preparation | Always read conventions and refs before analysis |
|
|
152
|
+
| Skipping verification | Always verify findings against actual code |
|
|
153
|
+
| Dismissing findings due to breaking changes | Breaking changes are irrelevant — report the naming issue |
|
|
154
|
+
| Not writing research results to files | Research agents MUST write to disk — prevents context bloat |
|
|
@@ -14,12 +14,36 @@ Start by understanding the current project context, then ask questions one at a
|
|
|
14
14
|
## The Process
|
|
15
15
|
|
|
16
16
|
**Understanding the idea:**
|
|
17
|
-
- Check out the current project state first (files, docs, recent commits)
|
|
17
|
+
- Check out the current project state first (files, docs, recent commits).
|
|
18
18
|
- Ask questions one at a time to refine the idea
|
|
19
19
|
- Prefer multiple choice questions when possible, but open-ended is fine too
|
|
20
20
|
- Only one question per message - if a topic needs more exploration, break it into multiple questions
|
|
21
21
|
- Focus on understanding: purpose, constraints, success criteria
|
|
22
22
|
|
|
23
|
+
**When a main design document is provided as context:**
|
|
24
|
+
|
|
25
|
+
```mermaid
|
|
26
|
+
flowchart TD
|
|
27
|
+
A{"Main design with<br>section plan in context?"}
|
|
28
|
+
A -->|no| B[Normal brainstorm]
|
|
29
|
+
A -->|yes| C{Section specified?}
|
|
30
|
+
C -->|no| D["Show section progress<br>Ask which section<br>(suggest next incomplete)"]
|
|
31
|
+
C -->|yes| E{"Prerequisites<br>complete?"}
|
|
32
|
+
E -->|yes| F[Proceed with section]
|
|
33
|
+
E -->|no| G["Warn prerequisites incomplete<br>Ask: proceed anyway<br>or complete first?"]
|
|
34
|
+
G -->|"user: proceed"| F
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
When proceeding with a section:
|
|
38
|
+
|
|
39
|
+
1. **Read the main design** — understand goals, overall structure, and the target section's scope
|
|
40
|
+
2. **Read actual code** — check the current codebase state for what previous sections have built. Reference the **actual code**, NOT previous section design documents. Code may have diverged from earlier designs during implementation.
|
|
41
|
+
3. **Scope the brainstorm** — limit questions, gap review, approaches, and design presentation to the target section only. Do not re-question decisions already established in the main design.
|
|
42
|
+
4. **Conflict detection** — if the main design's direction conflicts with the actual code state, alert the user and ask for direction before proceeding.
|
|
43
|
+
5. After the design is complete, save as `docs/plans/YYYY-MM-DD-<topic>-section-N-design.md`
|
|
44
|
+
6. Update the main design document: mark the section `[ ]` → `[x]` in the section plan
|
|
45
|
+
7. Commit both files, then proceed to the normal **Next Steps Guide** (Path A/B)
|
|
46
|
+
|
|
23
47
|
**Gap review loop:**
|
|
24
48
|
|
|
25
49
|
When you think you've asked enough, **STOP and run a gap review before moving on.**
|
|
@@ -69,12 +93,63 @@ If your first gap review shows all ✅:
|
|
|
69
93
|
- Present options conversationally with your recommendation and reasoning
|
|
70
94
|
- Lead with your recommended option and explain why
|
|
71
95
|
|
|
72
|
-
**
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
96
|
+
**Scale assessment:**
|
|
97
|
+
|
|
98
|
+
After the approach is selected, assess scale (file count, logic complexity, number of distinct subsystems, scope of impact):
|
|
99
|
+
|
|
100
|
+
```mermaid
|
|
101
|
+
flowchart TD
|
|
102
|
+
A{"Assess design scale"}
|
|
103
|
+
A -->|manageable| B["Proceed to<br>After the Design<br>(Path A/B)"]
|
|
104
|
+
A -->|large| C["Propose to user:<br>proceed as-is OR<br>split into sections"]
|
|
105
|
+
C --> D{"User choice?"}
|
|
106
|
+
D -->|"proceed as-is"| B
|
|
107
|
+
D -->|split| E["Propose 2-3 section<br>division approaches<br>(by feature/layer/dependency)"]
|
|
108
|
+
E -->|"user selects"| F["Append section plan<br>to design doc<br>Save + commit"]
|
|
109
|
+
F --> G["Show section guide<br>Brainstorm ENDS"]
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**How to present the split proposal:**
|
|
113
|
+
|
|
114
|
+
When proposing the split to the user, you MUST clearly explain what "section split" means:
|
|
115
|
+
|
|
116
|
+
- **Section split** = the design document is divided into sections, and each section goes through its own **separate brainstorm → plan → plan-dev → check → commit cycle**.
|
|
117
|
+
- This is NOT about implementation phasing (doing some changes before others). It's about breaking the design work itself into independently deliverable chunks.
|
|
118
|
+
- Explain: "Splitting into sections means each section goes through its own brainstorm → plan → plan-dev cycle. Complete and commit one section before moving to the next."
|
|
119
|
+
- Contrast with: "Proceeding as-is means this single design document goes straight to plan → plan-dev."
|
|
120
|
+
|
|
121
|
+
**Section plan format** (append to existing design content as-is):
|
|
122
|
+
|
|
123
|
+
```markdown
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Section Plan
|
|
127
|
+
|
|
128
|
+
- [ ] Section 1: <name> — <scope summary>
|
|
129
|
+
- [ ] Section 2: <name> — <scope summary> (after section 1)
|
|
130
|
+
- [ ] Section 3: <name> — <scope summary> (after section 1, 2)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Section guide** (shown instead of Path A/B, in user's configured language):
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
Design has been split into sections.
|
|
137
|
+
|
|
138
|
+
Main design: docs/plans/YYYY-MM-DD-<topic>-design.md
|
|
139
|
+
|
|
140
|
+
Section progress:
|
|
141
|
+
- [ ] Section 1: <name>
|
|
142
|
+
- [ ] Section 2: <name> (after section 1)
|
|
143
|
+
- [ ] Section 3: <name> (after section 1, 2)
|
|
144
|
+
|
|
145
|
+
Run each section in order:
|
|
146
|
+
sd-brainstorm docs/plans/YYYY-MM-DD-<topic>-design.md section 1
|
|
147
|
+
|
|
148
|
+
After each section's brainstorm completes, you can choose Path A/B
|
|
149
|
+
to run plan → plan-dev → check → commit.
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Do NOT auto-proceed to any section.
|
|
78
153
|
|
|
79
154
|
## After the Design
|
|
80
155
|
|
|
@@ -137,5 +212,4 @@ You can start from any step or skip steps as needed.
|
|
|
137
212
|
- **Multiple choice preferred** - Easier to answer than open-ended when possible
|
|
138
213
|
- **YAGNI ruthlessly** - Remove unnecessary features from all designs
|
|
139
214
|
- **Explore alternatives** - Always propose 2-3 approaches before settling
|
|
140
|
-
- **Incremental validation** - Present design in sections, validate each
|
|
141
215
|
- **Be flexible** - Go back and clarify when something doesn't make sense
|