@simplysm/sd-claude 13.0.71 → 13.0.74

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.
Files changed (40) hide show
  1. package/README.md +286 -13
  2. package/claude/refs/sd-code-conventions.md +11 -0
  3. package/claude/refs/sd-library-issue.md +7 -0
  4. package/claude/rules/sd-claude-rules.md +15 -4
  5. package/claude/rules/sd-refs-linker.md +1 -0
  6. package/claude/sd-statusline.js +1 -1
  7. package/claude/skills/sd-brainstorm/SKILL.md +1 -1
  8. package/claude/skills/sd-check/SKILL.md +15 -6
  9. package/claude/skills/sd-commit/SKILL.md +2 -0
  10. package/claude/skills/sd-debug/find-polluter.sh +8 -2
  11. package/claude/skills/sd-debug/root-cause-tracing.md +2 -2
  12. package/claude/skills/sd-document/extract_docx.py +5 -5
  13. package/claude/skills/sd-document/extract_pdf.py +11 -11
  14. package/claude/skills/sd-document/extract_pptx.py +5 -5
  15. package/claude/skills/sd-document/extract_xlsx.py +7 -7
  16. package/claude/skills/sd-email-analyze/email-analyzer.py +28 -28
  17. package/claude/skills/sd-plan/SKILL.md +11 -2
  18. package/claude/skills/sd-plan-dev/SKILL.md +5 -3
  19. package/claude/skills/sd-plan-dev/final-review-prompt.md +3 -3
  20. package/claude/skills/sd-readme/SKILL.md +86 -106
  21. package/claude/skills/sd-review/SKILL.md +58 -62
  22. package/claude/skills/sd-review/api-reviewer-prompt.md +90 -0
  23. package/claude/skills/sd-review/code-reviewer-prompt.md +85 -0
  24. package/claude/skills/sd-review/code-simplifier-prompt.md +88 -0
  25. package/claude/skills/sd-worktree/SKILL.md +10 -8
  26. package/claude/skills/sd-worktree/sd-worktree.mjs +5 -5
  27. package/dist/commands/auth-list.d.ts +1 -1
  28. package/dist/commands/auth-list.d.ts.map +1 -1
  29. package/dist/commands/auth-list.js +79 -21
  30. package/dist/commands/auth-list.js.map +1 -1
  31. package/dist/sd-claude.js +2 -2
  32. package/dist/sd-claude.js.map +1 -1
  33. package/package.json +1 -1
  34. package/src/commands/auth-list.ts +110 -24
  35. package/src/sd-claude.ts +2 -2
  36. package/tests/auth-list.spec.ts +42 -19
  37. package/claude/agents/sd-api-reviewer.md +0 -81
  38. package/claude/agents/sd-code-reviewer.md +0 -48
  39. package/claude/agents/sd-code-simplifier.md +0 -47
  40. package/claude/agents/sd-security-reviewer.md +0 -92
@@ -9,104 +9,100 @@ description: "Comprehensive multi-perspective code review (explicit invocation o
9
9
 
10
10
  Perform a multi-perspective code review of a package or specified path, producing a comprehensive report. **Analysis only — no code modifications.**
11
11
 
12
- Analyzes code via the built-in Explore agent, then runs up to 4 subagents in parallel for specialized review. Collects subagent results, verifies each finding against actual code, and writes the final report.
12
+ Dispatches up to 3 reviewer agents in parallel using prompt templates. Each agent independently explores the codebase from its own perspective. Collects results, verifies findings against actual code, and compiles the final report.
13
13
 
14
14
  ## Usage
15
15
 
16
- - `/sd-review packages/solid` — review source code at the given path
16
+ - `/sd-review packages/solid` — full review (all 3 perspectives)
17
+ - `/sd-review packages/solid focus on bugs` — selective review based on request
17
18
  - `/sd-review` — if no argument, ask the user for the target path
18
19
 
19
- ## When to Use
20
-
21
- - Before merging major features or after significant refactoring
22
- - When assessing overall code quality of a package
23
- - When onboarding to unfamiliar code and want a quality overview
24
-
25
- **When NOT to use:**
26
-
27
- - Single-file or trivial changes (typo, config tweak)
28
- - When you need code modifications (sd-review is analysis-only)
29
-
30
20
  ## Target Selection
31
21
 
32
- - With argument: `/sd-review packages/solid` — review source code at the given path
22
+ - With argument: review source code at the given path
33
23
  - Without argument: ask the user for the target path
34
24
 
35
25
  **Important:** Review ALL source files under the target path. Do not use git status or git diff to limit scope.
36
26
 
37
- ## Reviewer Agents
27
+ ## Reviewer Perspectives
38
28
 
39
- Run subagents in parallel via the Task tool:
29
+ | Reviewer | Prompt Template | Perspective |
30
+ |----------|----------------|-------------|
31
+ | **Code Reviewer** | `code-reviewer-prompt.md` | Correctness & Safety — bugs, security, logic errors |
32
+ | **API Reviewer** | `api-reviewer-prompt.md` | Usability & DX — naming, types, consistency |
33
+ | **Code Simplifier** | `code-simplifier-prompt.md` | Maintainability — complexity, duplication, structure |
40
34
 
41
- | Agent Type | Role | Condition |
42
- | ---------------------- | --------------------------------------------------- | ---------------------------------------------------------- |
43
- | `sd-code-reviewer` | Bugs, security, logic errors, convention issues | Always |
44
- | `sd-code-simplifier` | Complexity, duplication, readability issues | Always |
45
- | `sd-api-reviewer` | DX/usability, naming, type hints | Always |
46
- | `sd-security-reviewer` | ORM SQL injection, input validation vulnerabilities | When target path contains ORM queries or service endpoints |
35
+ ## Reviewer Selection
47
36
 
48
- ## Workflow
37
+ By default, run **all 3 reviewers**. If the user specifies a focus in natural language, select only the relevant reviewer(s):
49
38
 
50
- ### Step 1: Code Analysis via Explore Agent
39
+ | User says | Run |
40
+ |-----------|-----|
41
+ | "bugs", "security", "safety" | Code Reviewer only |
42
+ | "API", "naming", "types", "DX" | API Reviewer only |
43
+ | "complexity", "duplication", "structure", "maintainability" | Code Simplifier only |
44
+ | "bugs and API" | Code Reviewer + API Reviewer |
45
+ | (no specific focus) | All 3 |
51
46
 
52
- Invoke the built-in Explore agent via the Task tool to analyze the target path:
47
+ Use judgment for ambiguous requests. When in doubt, run all 3.
53
48
 
54
- ```
55
- Task(subagent_type=Explore)
56
- Prompt: "very thorough" analysis of <target-path>:
57
- - Entry points, core files, module boundaries
58
- - Call chains, data transformations, state changes
59
- - Abstraction layers, design patterns, dependency graph
60
- - Error handling, public API surface
61
- ```
49
+ ## Workflow
62
50
 
63
- This runs in a **separate context**, so it does not consume the main context window.
51
+ ### Step 1: Dispatch Reviewers
64
52
 
65
- ### Step 2: Dispatch Analysis to Reviewers
53
+ Read the prompt template files from this skill's directory. Replace `[TARGET_PATH]` with the actual target path. Then dispatch using `Agent(general-purpose)`:
66
54
 
67
- Run subagents **in parallel** via the Task tool. Include the Explore analysis results in each subagent's prompt:
55
+ ```
56
+ Agent(subagent_type=general-purpose, prompt=<filled template>)
57
+ ```
68
58
 
69
- - **sd-code-reviewer**: Based on the analysis, find bugs, security vulnerabilities, logic errors, and convention issues. Each finding must include **file:line** and **evidence**.
70
- - **sd-code-simplifier**: Based on the analysis, find unnecessary complexity, code duplication, and readability issues. Each finding must include **file:line** and **evidence**. **No code modifications.**
71
- - **sd-api-reviewer**: Based on the analysis, review API intuitiveness, naming consistency, type hints, error messages, and configuration complexity. Each finding must include **file:line** and **evidence**.
72
- - **sd-security-reviewer** _(conditional)_: If the Explore analysis reveals ORM queries (`orm-common`, `orm-node`, query builders, `expr.eq`, `.where()`, `.result()`) or service endpoints (`ServiceServer`, RPC handlers), also dispatch this agent. Based on the analysis, find SQL injection risks, missing input validation, and unvalidated user input reaching ORM queries. Each finding must include **file:line** and **evidence**.
59
+ Run selected reviewers **in parallel** (multiple Agent calls in a single message).
73
60
 
74
- ### Step 3: Verify Issues
61
+ ### Step 2: Verify Findings
75
62
 
76
- After collecting results from all 3 subagents, verify each issue against the actual code:
63
+ After collecting results from all reviewers, **Read the actual code** for each finding and verify:
77
64
 
78
- - **Valid**: the issue is real → include in the report
65
+ - **Valid**: the issue is real AND within scope → include in the report
66
+ - **Invalid — self-contradicted**: the reviewer's own analysis shows the issue is mitigated (e.g., "exploitability is limited because..."). Drop it.
67
+ - **Invalid — type-only**: reports a type definition as a runtime issue without showing actual runtime code that triggers it. Drop it.
68
+ - **Invalid — out of scope**: the issue is about code outside the target path (e.g., how other packages use this code). Drop it.
69
+ - **Invalid — duplicate**: another reviewer already reported the same issue. Keep only the one from the correct domain (bugs→Code, API→API, structure→Simplifier).
70
+ - **Invalid — bikeshedding**: minor style preference on stable, well-commented code (magic numbers with clear comments, small interface field duplication, naming when used consistently). Drop it.
71
+ - **Invalid — severity inflated**: downgrade or drop findings where the stated severity doesn't match the actual impact.
79
72
  - **Invalid — already handled**: handled elsewhere in the codebase (provide evidence)
80
73
  - **Invalid — intentional pattern**: by-design architectural decision
81
74
  - **Invalid — misread**: the reviewer misinterpreted the code
82
75
 
83
- ### Step 4: Final Report
76
+ ### Step 3: Final Report
84
77
 
85
- Compile only **verified findings** into a comprehensive report.
78
+ Compile only **verified findings** grouped by severity (not by reviewer):
86
79
 
87
- ### Report Structure
80
+ ```
81
+ ## Review Report: <target-path>
88
82
 
89
- | Section | Priority | Source |
90
- | -------------------------------- | -------- | --------------------------------------------------------------- |
91
- | **Architecture Summary** | — | Explore analysis |
92
- | **Critical Issues** | P0 | Bugs, security vulnerabilities |
93
- | **Security Issues** | P0 | SQL injection, input validation (when sd-security-reviewer ran) |
94
- | **Quality Issues** | P1 | Logic errors, missing error handling, performance |
95
- | **DX/Usability Issues** | P2 | API intuitiveness, naming, type hints |
96
- | **Simplification Opportunities** | P3 | Complexity removal, duplicate code, abstractions |
97
- | **Convention Issues** | P4 | Project convention mismatches |
83
+ ### CRITICAL
84
+ [verified critical findings from all reviewers]
98
85
 
99
- Each issue includes **file:line**, **description**, and **suggestion**.
86
+ ### WARNING
87
+ [verified warning findings from all reviewers]
88
+
89
+ ### INFO
90
+ [verified info findings from all reviewers]
91
+
92
+ ### Invalid Findings Summary (optional)
93
+ [findings filtered out and why]
94
+ ```
100
95
 
101
- Optionally include an **Invalid Findings Summary** appendix showing which findings were filtered out and why.
96
+ Each finding includes: **source reviewer**, **file:line**, **evidence**, **issue**, and **suggestion**.
102
97
 
103
98
  ## Common Mistakes
104
99
 
105
- | Mistake | Fix |
106
- | ------------------------------------ | --------------------------------------------------- |
107
- | Using git diff to limit review scope | Review ALL source files under target path |
108
- | Skipping verification step | Always verify subagent findings against actual code |
109
- | Reporting unverified issues | Only include verified findings in final report |
100
+ | Mistake | Fix |
101
+ |---------|-----|
102
+ | Using git diff to limit review scope | Review ALL source files under target path |
103
+ | Skipping verification step | Always verify reviewer findings against actual code |
104
+ | Reporting unverified issues | Only include verified findings in final report |
105
+ | Running all reviewers for focused requests | Match reviewer selection to user's request |
110
106
 
111
107
  ## Completion Criteria
112
108
 
@@ -0,0 +1,90 @@
1
+ # API Reviewer Prompt
2
+
3
+ Template for `Agent(general-purpose)`. Fill in `[TARGET_PATH]`.
4
+
5
+ ```
6
+ You are reviewing a library's public API for developer experience (DX).
7
+ Your question: "Would a first-time developer be confused or make mistakes using this API?"
8
+
9
+ ## Target
10
+
11
+ Review ALL source files at [TARGET_PATH].
12
+
13
+ ## Step 1: List all source files
14
+
15
+ Use Glob to list all .ts files under the target path (exclude node_modules, dist).
16
+
17
+ ## Step 2: Map the public API surface
18
+
19
+ - Read index.ts to list all exports (types, functions, constants)
20
+ - Read each exported type/interface/function definition
21
+ - Read test files and consumer code to see actual usage patterns
22
+
23
+ ## Step 3: Find issues
24
+
25
+ Look for:
26
+ - Naming consistency: same concept with different names, inconsistent prefix/suffix
27
+ - Intuitiveness: behavior can't be predicted from the name alone
28
+ - Type design: insufficient types for autocompletion, `any` in public interfaces, generic inference failures
29
+ - Defaults: basic use cases requiring excessive configuration
30
+ - Pattern consistency: similar tasks requiring different patterns
31
+
32
+ Important: Internal consistency takes priority over external standards.
33
+ Before suggesting a naming change, verify the existing pattern across ALL similar
34
+ components in the library. Do NOT suggest external conventions that break internal consistency.
35
+
36
+ Do NOT report:
37
+ - Bugs, security, logic errors, race conditions
38
+ - Code complexity, duplication, readability
39
+ - Do NOT use WebSearch to compare with external libraries
40
+ - TypeScript type system limitations that require workarounds (e.g., discriminated unions not narrowing due to template literals) — these are language constraints, not API design flaws
41
+ - Naming preferences where the current name is used consistently across the codebase — consistency > personal preference
42
+ - Minor field duplication in small interfaces (< 10 fields) where extraction adds indirection without real benefit
43
+
44
+ ## Step 4: Self-verify before reporting
45
+
46
+ Before including ANY finding, verify:
47
+
48
+ 1. **Severity check**: CRITICAL = developers WILL write wrong code because of this API. Not "could theoretically be confusing."
49
+ 2. **Consistency check**: Before suggesting a rename, search ALL usages. If the name is used consistently everywhere, it's NOT a finding.
50
+ 3. **Scope check**: Only report on the PUBLIC API of the target package. Do not report on how consumers should use it differently.
51
+
52
+ **Quality over quantity: 3 verified findings > 10 maybe-findings.**
53
+
54
+ ## Constraints
55
+
56
+ - Analysis only. Do NOT modify any files.
57
+ - Only report issues with real evidence from the code.
58
+ - CRITICAL severity requires proof that the current API actively misleads — not just "could be better."
59
+
60
+ ## Output Format
61
+
62
+ Use this exact format for every finding:
63
+
64
+ ### [CRITICAL|WARNING|INFO] title
65
+
66
+ - **File**: path/to/file.ts:42
67
+ - **Evidence**: what you observed (include code snippet)
68
+ - **Issue**: what the problem is
69
+ - **Suggestion**: how to improve it
70
+
71
+ Severity:
72
+ - CRITICAL: API misleads developers or types are insufficient for correct usage
73
+ - WARNING: Significant DX friction — unnecessary complexity or inconsistency
74
+ - INFO: Minor improvement — better naming or defaults exist
75
+
76
+ Start your report with:
77
+
78
+ ## API Review Results
79
+
80
+ ### Summary
81
+ - Files reviewed: N
82
+ - Public API surface: brief description
83
+ - Findings: X CRITICAL, Y WARNING, Z INFO
84
+
85
+ ### Findings
86
+ [findings here]
87
+
88
+ ### Positive Observations
89
+ [what's already well-designed — keep these]
90
+ ```
@@ -0,0 +1,85 @@
1
+ # Code Reviewer Prompt
2
+
3
+ Template for `Agent(general-purpose)`. Fill in `[TARGET_PATH]`.
4
+
5
+ ```
6
+ You are reviewing code for correctness and safety.
7
+ Your question: "Does this code produce wrong results or pose risks?"
8
+
9
+ ## Target
10
+
11
+ Review ALL source files at [TARGET_PATH].
12
+
13
+ ## Step 1: List all source files
14
+
15
+ Use Glob to list all .ts files under the target path (exclude node_modules, dist).
16
+ This is your review scope — every file in this list must be examined.
17
+
18
+ ## Step 2: Understand the codebase
19
+
20
+ Read the project's CLAUDE.md for conventions. Then:
21
+ - Read index.ts to map the module structure
22
+ - Read each source file to understand logic flows, data transformations, error paths
23
+
24
+ ## Step 3: Find issues
25
+
26
+ Look for:
27
+ - Bugs: null/undefined risks, off-by-one, wrong conditions, missing return values
28
+ - Security: injection, XSS, auth/authz gaps, sensitive data exposure, input validation
29
+ - Race conditions: async ordering, shared state without synchronization
30
+ - Resource leaks: uncleared subscriptions/listeners, unclosed handles
31
+ - Error handling: swallowed exceptions, wrong fallbacks, missing propagation
32
+
33
+ Do NOT report:
34
+ - Naming consistency, API design, type quality (including `any` types)
35
+ - Code complexity, duplication, readability improvements
36
+ - Style preferences unless they cause actual bugs
37
+ - Type definitions alone — a type allowing `stack?: string` is NOT a security issue unless the runtime code actually sends it unsanitized
38
+ - Speculative future risks — "if config were changed to X, this would break" is not a finding
39
+ - Issues in code OUTSIDE the target path (e.g., how other packages consume these types)
40
+
41
+ ## Step 4: Self-verify before reporting
42
+
43
+ Before including ANY finding, ask yourself:
44
+
45
+ 1. **Is there runtime code here that actually triggers this?** (Not just a type definition)
46
+ 2. **Does the evidence contradict my conclusion?** (If you find a bound/limit that prevents the issue, drop it)
47
+ 3. **Is this within the target scope?** (Not about how other packages use this code)
48
+
49
+ If you write "in practice this is unlikely because..." or "exploitability is limited because..." — that means it's NOT a real finding. Drop it.
50
+
51
+ **Quality over quantity: 3 verified findings > 10 maybe-findings.**
52
+
53
+ ## Constraints
54
+
55
+ - Analysis only. Do NOT modify any files.
56
+ - Only report issues where the runtime behavior is demonstrably wrong or risky.
57
+ - If your own analysis shows the issue is mitigated, do NOT report it.
58
+
59
+ ## Output Format
60
+
61
+ Use this exact format for every finding:
62
+
63
+ ### [CRITICAL|WARNING|INFO] title
64
+
65
+ - **File**: path/to/file.ts:42
66
+ - **Evidence**: what you observed (include code snippet)
67
+ - **Issue**: what the problem is
68
+ - **Suggestion**: how to fix it
69
+
70
+ Severity:
71
+ - CRITICAL: Will cause bugs, outages, or security breaches
72
+ - WARNING: Real problem that can occur in practice
73
+ - INFO: Defensive improvement, low risk
74
+
75
+ Start your report with:
76
+
77
+ ## Code Review Results
78
+
79
+ ### Summary
80
+ - Files reviewed: N
81
+ - Findings: X CRITICAL, Y WARNING, Z INFO
82
+
83
+ ### Findings
84
+ [findings here]
85
+ ```
@@ -0,0 +1,88 @@
1
+ # Code Simplifier Prompt
2
+
3
+ Template for `Agent(general-purpose)`. Fill in `[TARGET_PATH]`.
4
+
5
+ ```
6
+ You are a maintainability analyst reviewing code structure.
7
+ Your question: "Would a developer struggle to understand or modify this code?"
8
+
9
+ ## Target
10
+
11
+ Review ALL source files at [TARGET_PATH].
12
+
13
+ ## Step 1: List all source files
14
+
15
+ Use Glob to list all .ts files under the target path (exclude node_modules, dist).
16
+
17
+ ## Step 2: Understand the structure
18
+
19
+ - Map module dependencies and abstraction layers
20
+ - Compare whether similar-role files use consistent patterns
21
+ - Identify complexity hotspots: deep nesting, long functions, complex conditionals
22
+
23
+ ## Step 3: Find issues
24
+
25
+ Look for:
26
+ - Unnecessary complexity: over-abstraction, needless indirection, complex generics
27
+ - Duplication: same logic repeated, similar functions that could be unified
28
+ - Readability: hard-to-follow control flow, unclear variable names, implicit behavior
29
+ - Structure: too many files for simple concepts, or too many responsibilities in one file
30
+ - Maintainability risk: changes that cascade widely, tightly coupled modules
31
+
32
+ Do NOT report:
33
+ - Bugs, security, logic errors → that's the code reviewer's job
34
+ - Naming consistency, API design, type quality (including `any` types) → that's the API reviewer's job
35
+ - Property shorthand (`uuid: uuid` vs `uuid`)
36
+ - `else` after `return`
37
+ - Comment style or JSDoc presence/absence
38
+ - Import ordering or formatting preferences
39
+ - Magic numbers that are well-explained by adjacent comments
40
+ - Small interface duplication (< 10 fields) where extracting a base adds indirection without real benefit
41
+ - Type placement across packages unless it causes concrete import/dependency issues
42
+ - Issues in code OUTSIDE the target path (e.g., how other packages implement or consume these types)
43
+
44
+ ## Step 4: Self-verify before reporting
45
+
46
+ Before including ANY finding:
47
+
48
+ 1. **Impact test**: Would a developer actually struggle with this? Or is it just "could be slightly cleaner"?
49
+ 2. **Scope check**: Is the issue IN the target code, or in how other code uses it?
50
+ 3. **Overlap check**: Is this already in the code reviewer's or API reviewer's domain? If yes, skip it.
51
+
52
+ **Quality over quantity: 3 verified findings > 10 maybe-findings.**
53
+
54
+ ## Constraints
55
+
56
+ - Analysis only. Do NOT modify any files.
57
+ - Do NOT provide corrected code blocks. Describe issues and suggestions in words only.
58
+ - Only report issues with real evidence from the code.
59
+ - Focus on substance: structural issues that genuinely make the code hard to understand or modify.
60
+ - Do NOT report findings that belong to other reviewers' scope.
61
+
62
+ ## Output Format
63
+
64
+ Use this exact format for every finding:
65
+
66
+ ### [CRITICAL|WARNING|INFO] title
67
+
68
+ - **File**: path/to/file.ts:42
69
+ - **Evidence**: what you observed (include code snippet)
70
+ - **Issue**: what the problem is
71
+ - **Suggestion**: how to improve it (in words, not code)
72
+
73
+ Severity:
74
+ - CRITICAL: Major structural problem. Very hard to understand or modify safely.
75
+ - WARNING: Significant maintainability concern. Unnecessary complexity or duplication.
76
+ - INFO: Improvement opportunity. Cleaner approach exists but current code is workable.
77
+
78
+ Start your report with:
79
+
80
+ ## Maintainability Review Results
81
+
82
+ ### Summary
83
+ - Files reviewed: N
84
+ - Findings: X CRITICAL, Y WARNING, Z INFO
85
+
86
+ ### Findings
87
+ [findings here]
88
+ ```
@@ -16,10 +16,11 @@ model: haiku
16
16
 
17
17
  2. **If `merge` fails or produces conflicts → STOP IMMEDIATELY and show this message:**
18
18
  ```
19
- ⚠️ merge 문제가 발생했습니다.
20
- 직접 수동으로 merge 진행해 주세요.
21
- (에러 내용: <에러/충돌 정보 그대로 출력>)
19
+ ⚠️ A problem occurred during merge.
20
+ Please proceed with the merge manually.
21
+ (Error details: <print error/conflict info as-is>)
22
22
  ```
23
+ - Show this message in the system's configured language.
23
24
  - Do NOT attempt to resolve conflicts yourself.
24
25
  - Do NOT run `git merge --abort` without asking.
25
26
  - Do NOT proceed to `clean` after a failed merge.
@@ -28,10 +29,11 @@ model: haiku
28
29
 
29
30
  3. **If `rebase` fails or produces conflicts → STOP IMMEDIATELY and show this message:**
30
31
  ```
31
- ⚠️ rebase 문제가 발생했습니다.
32
- 직접 수동으로 rebase 진행해 주세요.
33
- (에러 내용: <에러/충돌 정보 그대로 출력>)
32
+ ⚠️ A problem occurred during rebase.
33
+ Please proceed with the rebase manually.
34
+ (Error details: <print error/conflict info as-is>)
34
35
  ```
36
+ - Show this message in the system's configured language.
35
37
  - Same rules as merge. Do NOT auto-resolve. Just show the message and STOP.
36
38
 
37
39
  4. **NEVER run destructive git commands during worktree workflows:**
@@ -102,9 +104,9 @@ node .claude/skills/sd-worktree/sd-worktree.mjs merge [name]
102
104
 
103
105
  **MERGE SAFETY PROTOCOL:**
104
106
  1. Before merge: check BOTH main and worktree for uncommitted changes
105
- 2. If the script exits with non-zero → show "직접 수동으로 merge 주세요" message and STOP.
107
+ 2. If the script exits with non-zero → show "Please proceed with the merge manually." message (in system language) and STOP.
106
108
  3. After merge: run `git status` in main to confirm no conflicts
107
- 4. If conflicts or errors → show "직접 수동으로 merge 주세요" message and STOP.
109
+ 4. If conflicts or errors → show "Please proceed with the merge manually." message (in system language) and STOP.
108
110
  5. Only proceed to `clean` after confirming merge was fully successful
109
111
 
110
112
  ### clean — Remove worktree and delete branch
@@ -13,7 +13,7 @@ function getOutput(command) {
13
13
  return execSync(command, { encoding: "utf-8" }).trim();
14
14
  }
15
15
 
16
- // 메인 working tree 경로 (worktree 안에서 실행해도 정확)
16
+ // Main working tree path (accurate even when run inside a worktree)
17
17
  const mainWorktree = getOutput("git worktree list --porcelain")
18
18
  .split("\n")[0]
19
19
  .replace("worktree ", "");
@@ -71,7 +71,7 @@ switch (cmd) {
71
71
  console.error("Usage: sd-worktree.mjs merge [name] (or run inside .worktrees/<name>)");
72
72
  process.exit(1);
73
73
  }
74
- // uncommitted 변경 확인
74
+ // Check for uncommitted changes
75
75
  const worktreePath_m = resolve(mainWorktree, ".worktrees", name);
76
76
  if (existsSync(worktreePath_m)) {
77
77
  const status = getOutput(`git -C "${worktreePath_m}" status --porcelain`);
@@ -99,7 +99,7 @@ switch (cmd) {
99
99
  console.error(`Error: worktree '${name}' does not exist.`);
100
100
  process.exit(1);
101
101
  }
102
- // uncommitted 변경 확인
102
+ // Check for uncommitted changes
103
103
  const statusR = getOutput(`git -C "${worktreePath_r}" status --porcelain`);
104
104
  if (statusR) {
105
105
  console.error(`Error: worktree '${name}' has uncommitted changes:\n${statusR}`);
@@ -119,7 +119,7 @@ switch (cmd) {
119
119
  console.error("Usage: sd-worktree.mjs clean [name] (or run inside .worktrees/<name>)");
120
120
  process.exit(1);
121
121
  }
122
- // worktree 안에서 실행 차단
122
+ // Block execution from inside the worktree
123
123
  const worktreePath = resolve(mainWorktree, ".worktrees", name);
124
124
  const cwd = process.cwd();
125
125
  if (cwd === worktreePath || cwd.startsWith(worktreePath + "/")) {
@@ -134,7 +134,7 @@ switch (cmd) {
134
134
  try {
135
135
  run(`git worktree remove --force "${worktreePath}"`, { cwd: mainWorktree });
136
136
  } catch {
137
- // node_modules 등으로 git worktree remove 실패 수동 정리
137
+ // Manual cleanup when git worktree remove fails (e.g., due to node_modules)
138
138
  console.log("git worktree remove failed, cleaning up manually...");
139
139
  rmSync(worktreePath, { recursive: true, force: true });
140
140
  run("git worktree prune", { cwd: mainWorktree });
@@ -1,2 +1,2 @@
1
- export declare function runAuthList(homeDir?: string): void;
1
+ export declare function runAuthList(homeDir?: string): Promise<void>;
2
2
  //# sourceMappingURL=auth-list.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-list.d.ts","sourceRoot":"","sources":["../../src/commands/auth-list.ts"],"names":[],"mappings":"AAIA,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAuClD"}
1
+ {"version":3,"file":"auth-list.d.ts","sourceRoot":"","sources":["../../src/commands/auth-list.ts"],"names":[],"mappings":"AAwEA,wBAAsB,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyDjE"}
@@ -1,7 +1,53 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import { listProfiles, getCurrentUserID, getProfileDir } from "./auth-utils.js";
4
- function runAuthList(homeDir) {
4
+ const FETCH_TIMEOUT_MS = 5e3;
5
+ async function fetchUsage(accessToken) {
6
+ try {
7
+ const controller = new AbortController();
8
+ const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
9
+ const response = await fetch("https://api.anthropic.com/api/oauth/usage", {
10
+ headers: {
11
+ Authorization: `Bearer ${accessToken}`,
12
+ "anthropic-beta": "oauth-2025-04-20"
13
+ },
14
+ signal: controller.signal
15
+ });
16
+ clearTimeout(timeout);
17
+ if (!response.ok) {
18
+ return void 0;
19
+ }
20
+ return await response.json();
21
+ } catch {
22
+ return void 0;
23
+ }
24
+ }
25
+ function formatTimeRemaining(isoDate) {
26
+ if (isoDate == null) return "";
27
+ try {
28
+ const resetTime = new Date(isoDate).getTime();
29
+ if (Number.isNaN(resetTime)) return "";
30
+ const diffMs = resetTime - Date.now();
31
+ if (diffMs <= 0) return "";
32
+ const diffMinutes = Math.floor(diffMs / (1e3 * 60));
33
+ const diffHours = Math.floor(diffMinutes / 60);
34
+ const days = Math.floor(diffHours / 24);
35
+ const hours = diffHours % 24;
36
+ const minutes = diffMinutes % 60;
37
+ if (days > 0) return `${String(days)}d${String(hours)}h`;
38
+ if (hours > 0) return `${String(hours)}h${String(minutes)}m`;
39
+ return `${String(minutes)}m`;
40
+ } catch {
41
+ return "";
42
+ }
43
+ }
44
+ function formatUsage(label, data) {
45
+ if (data == null) return `${label}: ?`;
46
+ const pct = data.utilization != null ? `${String(Math.round(data.utilization))}%` : "?";
47
+ const remaining = formatTimeRemaining(data.resets_at);
48
+ return remaining ? `${label}: ${pct}(${remaining})` : `${label}: ${pct}`;
49
+ }
50
+ async function runAuthList(homeDir) {
5
51
  const profiles = listProfiles(homeDir);
6
52
  if (profiles.length === 0) {
7
53
  console.log("No saved profiles.");
@@ -9,26 +55,38 @@ function runAuthList(homeDir) {
9
55
  }
10
56
  const currentUserID = getCurrentUserID(homeDir);
11
57
  const sorted = [...profiles].sort((a, b) => a.localeCompare(b));
12
- for (const name of sorted) {
13
- const profileDir = getProfileDir(name, homeDir);
14
- const authData = JSON.parse(
15
- fs.readFileSync(path.join(profileDir, "auth.json"), "utf-8")
16
- );
17
- const credData = JSON.parse(
18
- fs.readFileSync(path.join(profileDir, "credentials.json"), "utf-8")
19
- );
20
- const oauthAccount = authData["oauthAccount"];
21
- const email = oauthAccount?.["emailAddress"] ?? "";
22
- const userID = authData["userID"];
23
- const oauth = credData["claudeAiOauth"];
24
- let expiresStr = "unknown";
25
- if (oauth != null && typeof oauth["expiresAt"] === "number") {
26
- const d = new Date(oauth["expiresAt"]);
27
- expiresStr = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
28
- }
29
- const isActive = currentUserID != null && userID === currentUserID;
30
- const prefix = isActive ? "*" : " ";
31
- console.log(`${prefix} ${name} (${email}) expires: ${expiresStr}`);
58
+ const results = await Promise.all(
59
+ sorted.map(async (name) => {
60
+ const profileDir = getProfileDir(name, homeDir);
61
+ const authData = JSON.parse(
62
+ fs.readFileSync(path.join(profileDir, "auth.json"), "utf-8")
63
+ );
64
+ const credData = JSON.parse(
65
+ fs.readFileSync(path.join(profileDir, "credentials.json"), "utf-8")
66
+ );
67
+ const oauthAccount = authData["oauthAccount"];
68
+ const email = oauthAccount?.["emailAddress"] ?? "";
69
+ const userID = authData["userID"];
70
+ const oauth = credData["claudeAiOauth"];
71
+ let expiresStr = "unknown";
72
+ if (oauth != null && typeof oauth["expiresAt"] === "number") {
73
+ const d = new Date(oauth["expiresAt"]);
74
+ expiresStr = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
75
+ }
76
+ const isActive = currentUserID != null && userID === currentUserID;
77
+ const prefix = isActive ? "*" : " ";
78
+ const accessToken = oauth?.["accessToken"];
79
+ const expiresAt = oauth?.["expiresAt"];
80
+ const tokenExpired = typeof expiresAt === "number" && Date.now() > expiresAt;
81
+ const usage = accessToken != null && !tokenExpired ? await fetchUsage(accessToken) : void 0;
82
+ const dailyData = usage?.daily ?? usage?.five_hour;
83
+ const fiveHourStr = formatUsage("5h", dailyData);
84
+ const weekStr = formatUsage("7d", usage?.seven_day);
85
+ return `${prefix} ${name} (${email}) expires: ${expiresStr} \u2502 ${fiveHourStr} \u2502 ${weekStr}`;
86
+ })
87
+ );
88
+ for (const line of results) {
89
+ console.log(line);
32
90
  }
33
91
  }
34
92
  export {