updated 1mo ago
/func-understand 㯠TypeScript/JavaScript ãããžã§ã¯ãå ã® 1 颿°ãèµ·ç¹ã«ãåŒã³åºãå (upstream)ãšåŒã³åºãå (downstream)ã®éçåŒã³åºãã°ã©ããè§£æããAI ã«ããæ¥æ¬èªèŠçŽä»ãã®èªå·±å®çµã€ã³ã¿ã©ã¯ãã£ã HTML ãšããŠå¯èŠåããã
What can you do with Func Understand?
name: func-understand description: Use when the user invokes /func-understand or asks to visualize a function's call graph, callers/callees, upstream routing path, or dependency chain as an interactive HTML view for a TS/JS codebase.
Function Call Graph Understanding
Purpose
/func-understand 㯠TypeScript/JavaScript ãããžã§ã¯ãå
ã® 1 颿°ãèµ·ç¹ã«ãåŒã³åºãå
(upstream)ãšåŒã³åºãå
(downstream)ã®éçåŒã³åºãã°ã©ããè§£æããAI ã«ããæ¥æ¬èªèŠçŽä»ãã®èªå·±å®çµã€ã³ã¿ã©ã¯ãã£ã HTML ãšããŠå¯èŠåããã
ãã€ãã©ã€ã³ã¯ 5 段é:
- åæç¢ºèª
- ãã¹ãé€å€å®çŸ©ã®ç¢ºèªã»çæ
- è§£æå®è¡(
analyze-callgraph.mjs) - AI èŠçŽ(ã°ã©ã JSON ã« summary ãåãã)
- HTML çæ(
generate-html.mjs)
以äžã<skill> ã¯ãã® SKILL.md ã眮ãããŠãããã£ã¬ã¯ããªã®çµ¶å¯Ÿãã¹ãæã(ã¹ãã«èµ·åæã«æç€ºããã "Base directory for this skill" ã®ãã¹ããããåç
§ãã)ã
1. åæç¢ºèª
- 察象㯠TS/JS ãããžã§ã¯ãã®ã¿ã察象ãã£ã¬ã¯ããªã TS/JS ãããžã§ã¯ãã§ãªãå Žåã¯ãã®æšãäŒããŠäžæããã
<skill>/scripts/node_modulesãååšããªããã°ãååã®ã¿cd <skill>/scripts && npm install --omit=devãå®è¡ãã(ãšã³ããŠãŒã¶ãŒã®ç°å¢ã«@playwright/testãªã©ã® devDependencies ãå ¥ããªã)ãæ¢ã«ååšããå Žåã¯åå®è¡ããªãã- å¯Ÿè±¡é¢æ°åããŠãŒã¶ãŒå ¥åããæç¢ºã§ãªãå Žå(ã³ãã³ãåŒæ°ç¡ãã§èµ·åãããå Žåãªã©)㯠AskUserQuestion ã§å¯Ÿè±¡é¢æ°åã確èªããã
2. ãã¹ãé€å€å®çŸ©ã®ç¢ºèªã»çæ
ãã¹ãé¢é£ãã¡ã€ã«(*.test.ts / __tests__/ ãªã©)ã¯ããã©ã«ãã§ã°ã©ãããé€å€ããããé€å€ãã¿ãŒã³ã¯è§£æå¯Ÿè±¡ãªãããšã®å®çŸ©ãã¡ã€ã« <project-root>/.func-understand.json ãæã€ã
- ãŠãŒã¶ãŒãããã¹ã蟌ã¿ã§ãçãšæç€ºããå Žå: ãã®ã»ã¯ã·ã§ã³ãã¹ãããããè§£æå®è¡æã«
--include-testsãä»äžããã <project-root>/.func-understand.jsonãæ¢ã«ååšããå Žå: ãã®ãŸãŸäœ¿ã(å 容ã®ç¢ºèªã»åçæã¯ããªã)ã- ååšããªãå Žå(ååã®ã¿)ã以äžã®æé ã§çæãã:
-
ãªãã®ãã¹ãèšå®ã調æ»ãã:
jest.config.*/vitest.config.*/playwright.config.*/cypress.config.*/package.json(testã¹ã¯ãªããã»jestãã£ãŒã«ã)/ tsconfig ã®excludeãªã©ã -
èŠã€ãã£ã testMatch / include / specPattern ããµããŒãæ§æã® glob ã«è»¢èšããŠ
testExcludeé åãäœãããµããŒãæ§æã¯**/*/?/{a,b}ã®ã¿ã§ããã¿ãŒã³ã¯ projectRoot ããã®çžå¯Ÿãã¹(posix åºåã)å šäœã«ããããããextglob(?(*.)/@(spec|test)ç)ã¯ãµããŒãæ§æã®çµã¿åããã«å±éãã(äŸ: jest ããã©ã«ãã®**/?(*.)+(spec|test).[jt]s?(x)â["**/*.test.*", "**/*.spec.*", "**/test.*", "**/spec.*"])ã -
ãã¹ãèšå®ãèŠã€ãããªããã°ã次ã®ãã©ãŒã«ããã¯æ¢å®ã»ããããã®ãŸãŸæžã蟌ã:
{ "testExclude": [ "**/*.test.*", "**/*.spec.*", "**/*_test.*", "**/*-test.*", "**/*.cy.*", "**/*.e2e-spec.*", "**/__tests__/**", "**/__mocks__/**", "**/__snapshots__/**", "**/__fixtures__/**", "**/__helpers__/**", "**/test/**", "**/tests/**", "**/spec/**", "**/e2e/**", "**/cypress/**" ] } -
察象ã git ãªããªã
.git/info/excludeã®æ«å°Ÿã«.func-understand.jsonã®è¡ã远èšãã(æ¢ã«èšèŒãããã°äœãããªã)ããã®å®çŸ©ãã¡ã€ã«ã¯ããŒã«ã«çæç©ã§ããã³ãããããªãåæ(å ±æããããŠãŒã¶ãŒã¯åèª exclude ããå€ãã°ãã)ã
-
- 察象ãªããžã®æžã蟌ã¿ãäžé©åãªå Žå(èªã¿åãå°çšã»ç¬¬äžè
ãªãç)ã¯ãscratchpad ã«å®çŸ©ãã¡ã€ã«ãçæããè§£æå®è¡æã«
--test-exclude <ãã®ãã¹>ãä»äžããã - äœãçŽãããå Žå(ãã¹ãèšå®ãå€ãã£ãç)ã¯ãå®çŸ©ãã¡ã€ã«ãåé€ããŠåå®è¡ãããããŠãŒã¶ãŒã®æç€ºã«åŸã£ãŠåçæããã
- èµ·ç¹é¢æ°ããã¹ããã¡ã€ã«å ã«ããå Žåã¯ã¹ã¯ãªãããèªåã§é€å€ãç¡å¹åãã(stderr ã«ãã®æšãåºã)ããã®å Žåã¯æçµå ±åã§ãèµ·ç¹ããã¹ããã¡ã€ã«ã®ããé€å€ã¯é©çšãããŠããªããããšã«è§Šããã
3. è§£æå®è¡
node <skill>/scripts/analyze-callgraph.mjs \
--project <ãããžã§ã¯ãã«ãŒã> \
--function <颿°å> \
--out <scratchpad>/graph.json
å¿
èŠã«å¿ã㊠--file <relFile> --line <n> --tsconfig <path> --upstream-depth <n> --downstream-depth <n> --max-nodes <n> --include-tests --test-exclude <path> ãä»äžããã--include-tests ãš --test-exclude ãäž¡æ¹æå®ããå Žå㯠--include-tests ãåªå
ãããå®çŸ©ãã¡ã€ã«ã¯èªã¿èŸŒãŸããªãã
stdout ã® JSON ãš exit code ã§åå²ãã:
- exit 2,
status: "ambiguous":candidatesã®åèŠçŽ ãã©ãã«relFile:startLine (containerName)ãšã㊠AskUserQuestion ã§æç€ºãããŠãŒã¶ãŒã«éžã°ãããcontainerNameã null/æªèšå®ã®åè£ã¯æ¬åŒ§éšåãçç¥ãrelFile:startLineãšãããAskUserQuestion ã®labelã¯ãã®çãã©ãã«ã®ã¿ã«ãšã©ããsignatureãªã©è©³çްæ å ±ã¯descriptionåŽã«å ¥ãããéžæãããåè£ã®relFileãšstartLineã--file--lineãšããŠä»äžããåãã³ãã³ããåå®è¡ãããcandidatesã«ã¯é¢æ°ã ãã§ãªã kindvariable/enumã®åè£ãæ··ããããšããã(ååã®ã¢ãžã¥ãŒã«ã¬ãã«å€æ°ã»enum ãè€æ°ååšããå Žå)ããåå®è¡ã®æé ã¯åãã - exit 2,
status: "not-a-function": æå®åã¯å®åšããã颿°ã§ã¯ãªããmatchesã®åèŠçŽ ã䜿ããNAME㯠kind(class/interface/type/enum)ãšããŠrelFile:startLineã«å®åšããŸããã颿°ã§ã¯ãªãããåŒã³åºãã°ã©ãã®èµ·ç¹ã«ã§ããŸããããšãŠãŒã¶ãŒã«èª¬æãã(è€æ°äžèŽæã¯ãã¹ãŠåæ)ãã¢ãžã¥ãŒã«ã¬ãã«ã®å€æ°ã»enum ãæå®ããå Žåã¯åç §ã°ã©ãã¢ãŒããšããŠèªåè§£æããããããã®ã¹ããŒã¿ã¹ã«ã¯ãªããªããã**ã¢ãžã¥ãŒã«ã¹ã³ãŒãã§ãªã enum(颿°å ã»namespace å ãªã©)**ã¯åŒãç¶ãnot-a-function(kind:enum)ã«ãªããsuggestionsã空ã§ãªããã°åè£ãšããŠæç€ºãã颿°åã®åå ¥åãä¿ã(AskUserQuestion ãŸãã¯èªç±å ¥åã§ã®ç¢ºèª)ã - exit 2,
status: "not-found":suggestionsã空ã®å Žåã解決ããã tsconfig ã solution-style(files: []+referencesã®ã¿ â Vite ã® TS scaffold æšæº)ã§ããå¯èœæ§ã確èªãã--tsconfig tsconfig.app.json(ãŸãã¯referencesãæãèšå®)ãä»ããŠåå®è¡ãããããã§ã解決ããªãå Žåã«ãsuggestionsãæç€ºããŠé¢æ°åã®åå ¥åãä¿ã(AskUserQuestion ãŸãã¯èªç±å ¥åã§ã®ç¢ºèª)ã颿°å ããŒã«ã«å€æ°(catch ç¯ã»for-of/for-in ã®ã«ãŒã倿°ãå«ã)ãæå®ããå Žåããã®ã¹ããŒã¿ã¹ã«ãªã(åç §ã°ã©ãã®èµ·ç¹ã«ã§ããã®ã¯ã¢ãžã¥ãŒã«ã¬ãã«ã®å€æ°ã»enum ã®ã¿)ã - exit 0,
status: "ok":truncated: trueã®å Žåãçæèªäœã¯ç¶è¡ããŠããããæçµå ±åæã«ãã°ã©ãã--max-nodesçã®äžéã§æã¡åãããããã--upstream-depth/--downstream-depthãæå®ããŠåå®è¡ãããšå šäœåã確èªã§ãããæšãææ¡ããã- ã¢ãã¬ãæ§æãªã©ã§æåŸ
ãããåŒã³åºãå
(upstream)ããããžã§ã¯ãå¢çããŒãã§éåããŠãããšæãããå Žåãã«ãŒã/åç
§å
ã®
tsconfig.jsonã--tsconfigã«æå®ããŠåå®è¡ããããæ¡å ããã - stdout ã®ãããã¬ãã«(
statusã®é£)ãããã³ graph.json ã®metaã«mode: "reference"ãä»ããŠããå Žåã¯åç §ã°ã©ãã¢ãŒã(æå®åãã¢ãžã¥ãŒã«ã¬ãã«ã®å€æ°ã»enum ãšããŠè§£æ±ºãããå Žåã®èªåãã©ãŒã«ããã¯)ãã°ã©ãã¯ãæå®ãã倿°ã»enum ãèªã颿°(readsãšããž)ãšãã®äžæµã®åŒã³åºãå ãã§ãããäžæµæ¹åã®ããŒãã¯ååšããªãã--downstream-depthãä»ããŠããšã©ãŒã«ã¯ãªããåã«ç¡èŠããããåäœçœ®ã§ã®åç §(function f(m: Mode)ã®å泚éãtypeof SETTINGSãªã©)ã reads ãšããŠèšäžããããããenum ãèµ·ç¹ã«ããå Žåã¯å泚éã§ã®åç §ã倿°ãå ããããšãããã
- exit 1: stderr ã®ãšã©ãŒã¡ãã»ãŒãž(äžæ£ãªæ°å€ãã©ã°ãªã©ãå«ã)ããã®ãŸãŸãŠãŒã¶ãŒã«äŒããåå ãä¿®æ£ããŠåå®è¡ããããã ã solution-style tsconfig(
files: []+referencesã®ã¿)ã瀺ãã¡ãã»ãŒãžã®å Žåã¯ããŠãŒã¶ãŒã«å·®ãæ»ãã--tsconfig tsconfig.app.json(ãŸãã¯referencesãæãèšå®)ãä»ããŠãã®å Žã§èªåçã«åå®è¡ããã
4. AI èŠçŽ
--out ã«æžãåºããã graph.json ãèªã¿èŸŒã¿ã以äžã®æ¡ä»¶ãæºããããŒãã®ã¿ã«èŠçŽãæžã:
min(upstreamDistance ?? Infinity, downstreamDistance ?? Infinity) <= 2 ã〠internal === true
- å察象ããŒãã«ããã®ã³ãŒããèªãã§ 1ã3 è¡ã®æ¥æ¬èªèŠçŽãäœæããããŒãã®
summaryãã£ãŒã«ãã«åãããããŒãã®codeã¯å®£èšã®å šæãå ¥ã£ãŠãã(åãè©°ããªã)ãããèŠçŽã¯codeã ãã§å®çµããŠããã - 察象ããŒãã 30 ãè¶
ããå Žåã¯ãTask tool ã®ãµããšãŒãžã§ã³ãã«åå²ããŠèŠçŽããã(1 ãšãŒãžã§ã³ããããæå€§ 30 ããŒã)ãåãµããšãŒãžã§ã³ãã«ã¯å¯Ÿè±¡ããŒãã®
id/name/codeã®ã¿ãæž¡ãã{ "id": "summary text", ... }圢åŒã® JSON ãè¿ããããè¿ã£ãŠããèŠçŽãããŒãã«ããŒãžããã - 察象ç¯å²å€ã®ããŒãã«ã¯äžåè§Šããªã: è·é¢ 2 è¶
ã®å
éšããŒãã¯
summaryãnullã®ãŸãŸå€æŽããªããexternal/boundary ããŒã(internal: false)ã«ã¯ããããsummaryããŒèªäœãååšããªã(graph-builder ãä»äžããªã)ããã远å ããŠã¯ãªããªãã - èŠçŽãåãçµããã graph.json ãåããã¹ã«äžæžãä¿åããã
5. HTML çæ
node <skill>/scripts/generate-html.mjs \
--graph <scratchpad>/graph.json \
--out <project-root>/docs/func-understand/YYYY-MM-DD-HHMM-<颿°å>.html \
--title "<颿°å> ã®åŒã³åºãã°ã©ã"
- åºåãã£ã¬ã¯ããª
docs/func-understand/ãç¡ããã°äœæããã - 察象ãããžã§ã¯ããèªã¿åãå°çšã»ç¬¬äžè
ãªããžããªã»ãã®ä»æžã蟌ã¿ãäžé©åãªå Žåã¯ã
<project-root>/docs/func-understand/ã«ã¯æžã蟌ãŸããã¹ã¯ã©ãããããçã®äœæ¥çšãã£ã¬ã¯ããª(ç¡ããã°äžæãã£ã¬ã¯ããª)ã«åºåãããã®çµ¶å¯Ÿãã¹ãå ±åããã - ãã¡ã€ã«åã®æ¥æã¯ã³ãã³ãå®è¡æå»(ããŒã«ã«æå»ã
YYYY-MM-DD-HHMM圢åŒ)ã䜿ãã - çæåŸã
open <åºåãã¹>ãªã©ã§ãã©ãŠã¶è¡šç€ºããã - æçµå¿çã§ã¯çæãã HTML ã®çµ¶å¯Ÿãã¹ããŠãŒã¶ãŒã«å ±åããã
6. 泚æ
- çæãã HTML ã®äžèº«ã chat ã«è²Œãä»ããªããåžžã«ãã¡ã€ã«ãã¹ã§æ¡å ããã
- ã°ã©ãæ§é (ããŒã/ãšããž/è·é¢)ã®æ£ç¢ºæ§ã¯ã¹ã¯ãªãã(
analyze-callgraph.mjs)ã®åºåããã®ãŸãŸæ£ã§ããããšãŒãžã§ã³ããæã§ä¿®æ£ã»è¿œå ããŠã¯ãªããªãããšãŒãžã§ã³ããè¡ãã®ã¯summaryãã£ãŒã«ãã®è¿œèšã®ã¿ã - æ¢ç¥ã®å¶çŽ(ãŠãŒã¶ãŒãžã®èª¬æã truncated/å¢çããŒãæã®æ¡å
ã«å©çšãã):
- ã€ãã³ãçµç±ã»DIçµç±ãªã©ã®åçãªåŒã³åºãã¯æ€åºã§ããªãã颿°åã®ååæž¡ã(
items.map(helper)çãåŒã³åºãã®åŒæ°äœçœ®)ã¯äžäžæµãšãcallback-passedãšããžãšããŠæ€åºãããããªããžã§ã¯ããªãã©ã«ã倿°ä»£å ¥ãçµç±ãã鿥çãªåãæž¡ãã¯ãæž¡ããã颿°ãæ¢ã«ã°ã©ãã«èŒã£ãŠããå Žåã®ã¿æ€åºããããã¯ã©ã¹ã³ã³ã¹ãã©ã¯ã¿æ¬äœå ã®ååæž¡ãã¯æ€åºå¯Ÿè±¡å€ã - TS æšæºã©ã€ãã©ãª(
push/mapç)ãš Node çµã¿èŸŒã¿(@types/nodeã«è§£æ±ºããããã®)ãžã®åŒã³åºãã¯ããŒãåãããªããnpm ããã±ãŒãžãžã®åŒã³åºãã¯å¢çããŒããšããŠè¡šç€ºããããã°ã©ããèµ·ç¹ããŒã1åã ãã«ãªã£ãå Žåã¯ãè§£æå€±æãã§ã¯ãªãããã®é¢æ°ãæšæºã©ã€ãã©ãªããåŒãã§ããªããããšãæå³ããã - project references ã䜿ãã¢ãã¬ããããã«ãææç©ããŸããåŒã³åºãã¯å¢çããŒããšããŠè¡šçŸãããããã§çµè·¯ãéåãã(
--tsconfigã®æå®ã§æ¹åããå Žåããã)ã - ç¡å颿°(å¿å颿°åŒ)ã¯è§£æå¯Ÿè±¡ãšããŠæå®ã§ããªãã
- TypeScript 7 ç³»ã®ãããžã§ã¯ãã§ã¯ã忢±ãããŠãã TypeScript 5 ç³»ã«ãã©ãŒã«ããã¯ããŠè§£æããã
- ãã¹ãé¢é£ãã¡ã€ã«(
.func-understand.jsonã®testExcludeã«ããããããã¡ã€ã«)ã¯ããã©ã«ãã§ããŒãåãããªãããã¹ã蟌ã¿ã§èŠããå Žåã¯--include-testsãä»ãããèµ·ç¹ããã¹ããã¡ã€ã«å ã®å Žåã¯èªåã§é€å€ãç¡å¹åãããã - ããŒãã®
codeã¯å šæãä¿æããããã1000 è¡çŽã®é¢æ°ãå«ãã°ã©ãã§ã¯ HTML ãæ°çŸ KBãæ° MB 倧ãããªããHTML ã®è©³çްããã«ã¯ 200 è¡ãè¶ ããããŒããæ¢å®ã§å é 200 è¡ã®ã¿è¡šç€ºãããå šæã衚瀺ããã¿ã³ã§æ®ããå±éãã(æ®ãè¡æ°ã¯ãã¿ã³ã«è¡šç€ºããã)ã
- ã€ãã³ãçµç±ã»DIçµç±ãªã©ã®åçãªåŒã³åºãã¯æ€åºã§ããªãã颿°åã®ååæž¡ã(
Install
Add Func Understand to your client. Pick the one you use.
npx skills add RyutoHaraguchi/cc-pluginsInstalls every skill in the repository, then prompts for which to keep.
/plugin marketplace add RyutoHaraguchi/cc-pluginsAdds the repository as a plugin marketplace; install individual plugins with `/plugin install`.
git clone https://github.com/RyutoHaraguchi/cc-plugins
cp -r plugins/cc-func-understand/skills/func-understand ~/.claude/skills/A skill is a plain directory. Copy it into `.claude/skills/` in a project or in your home directory.
Score
71 / 100
Good