@hasna/skills 0.0.2 ā 0.0.3
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/bin/index.js +253 -715
- package/bin/mcp.js +221 -683
- package/package.json +1 -1
- package/src/cli/cli.test.ts +14 -14
- package/src/cli/index.tsx +1 -1
- package/src/lib/installer.test.ts +41 -41
- package/src/lib/registry.test.ts +10 -10
- package/src/lib/registry.ts +10 -472
- package/src/lib/skillinfo.test.ts +12 -12
- package/src/mcp/index.ts +1 -1
- package/skills/skill-architecture-docs/CLAUDE.md +0 -19
- package/skills/skill-architecture-docs/package.json +0 -32
- package/skills/skill-architecture-docs/src/index.ts +0 -543
- package/skills/skill-auto-format/CLAUDE.md +0 -19
- package/skills/skill-auto-format/package.json +0 -32
- package/skills/skill-auto-format/src/index.ts +0 -103
- package/skills/skill-auto-format/tsconfig.json +0 -14
- package/skills/skill-brainstorm/README.md +0 -17
- package/skills/skill-brainstorm/install.sh +0 -112
- package/skills/skill-brainstorm/src/auth.ts +0 -49
- package/skills/skill-brainstorm/src/installer.ts +0 -324
- package/skills/skill-brainstorm/src/skill-install.ts +0 -205
- package/skills/skill-browser-agent/CLAUDE.md +0 -19
- package/skills/skill-browser-agent/package.json +0 -32
- package/skills/skill-browser-agent/src/index.ts +0 -626
- package/skills/skill-browser-agent/tsconfig.json +0 -14
- package/skills/skill-browseruse/LICENSE +0 -21
- package/skills/skill-browseruse/README.md +0 -27
- package/skills/skill-browseruse/SKILL.md +0 -113
- package/skills/skill-browseruse/install.sh +0 -112
- package/skills/skill-browseruse/package.json +0 -31
- package/skills/skill-browseruse/src/auth.ts +0 -49
- package/skills/skill-browseruse/src/installer.ts +0 -324
- package/skills/skill-browseruse/src/skill-install.ts +0 -174
- package/skills/skill-calculate/LICENSE +0 -21
- package/skills/skill-calculate/README.md +0 -17
- package/skills/skill-calculate/install.sh +0 -112
- package/skills/skill-calculate/package.json +0 -31
- package/skills/skill-calculate/src/auth.ts +0 -49
- package/skills/skill-calculate/src/installer.ts +0 -324
- package/skills/skill-calculate/src/skill-install.ts +0 -205
- package/skills/skill-chromedevtools/LICENSE +0 -21
- package/skills/skill-chromedevtools/README.md +0 -27
- package/skills/skill-chromedevtools/SKILL.md +0 -110
- package/skills/skill-chromedevtools/install.sh +0 -112
- package/skills/skill-chromedevtools/package.json +0 -31
- package/skills/skill-chromedevtools/src/auth.ts +0 -49
- package/skills/skill-chromedevtools/src/installer.ts +0 -324
- package/skills/skill-chromedevtools/src/skill-install.ts +0 -174
- package/skills/skill-companyguide/LICENSE +0 -21
- package/skills/skill-companyguide/README.md +0 -17
- package/skills/skill-companyguide/install.sh +0 -112
- package/skills/skill-companyguide/package.json +0 -31
- package/skills/skill-companyguide/src/auth.ts +0 -49
- package/skills/skill-companyguide/src/installer.ts +0 -324
- package/skills/skill-companyguide/src/skill-install.ts +0 -205
- package/skills/skill-compose-gmail/tsconfig.json +0 -14
- package/skills/skill-context7/LICENSE +0 -21
- package/skills/skill-context7/README.md +0 -27
- package/skills/skill-context7/SKILL.md +0 -103
- package/skills/skill-context7/install.sh +0 -112
- package/skills/skill-context7/package.json +0 -31
- package/skills/skill-context7/src/auth.ts +0 -49
- package/skills/skill-context7/src/installer.ts +0 -324
- package/skills/skill-context7/src/skill-install.ts +0 -174
- package/skills/skill-crawl/LICENSE +0 -21
- package/skills/skill-crawl/README.md +0 -17
- package/skills/skill-crawl/install.sh +0 -112
- package/skills/skill-crawl/package.json +0 -31
- package/skills/skill-crawl/src/auth.ts +0 -49
- package/skills/skill-crawl/src/installer.ts +0 -324
- package/skills/skill-crawl/src/skill-install.ts +0 -205
- package/skills/skill-csv-transformer/CLAUDE.md +0 -19
- package/skills/skill-csv-transformer/package.json +0 -32
- package/skills/skill-csv-transformer/src/index.ts +0 -81
- package/skills/skill-csv-transformer/tsconfig.json +0 -14
- package/skills/skill-debug/LICENSE +0 -21
- package/skills/skill-debug/README.md +0 -17
- package/skills/skill-debug/install.sh +0 -112
- package/skills/skill-debug/package.json +0 -31
- package/skills/skill-debug/src/auth.ts +0 -49
- package/skills/skill-debug/src/installer.ts +0 -324
- package/skills/skill-debug/src/skill-install.ts +0 -205
- package/skills/skill-deep-research/CLAUDE.md +0 -19
- package/skills/skill-deep-research/package.json +0 -32
- package/skills/skill-deep-research/src/index.ts +0 -1149
- package/skills/skill-deep-research/tsconfig.json +0 -14
- package/skills/skill-dns-manager/CLAUDE.md +0 -19
- package/skills/skill-dns-manager/package.json +0 -32
- package/skills/skill-dns-manager/src/index.ts +0 -92
- package/skills/skill-dns-manager/tsconfig.json +0 -14
- package/skills/skill-download/LICENSE +0 -21
- package/skills/skill-download/README.md +0 -17
- package/skills/skill-download/install.sh +0 -112
- package/skills/skill-download/package.json +0 -31
- package/skills/skill-download/src/auth.ts +0 -49
- package/skills/skill-download/src/installer.ts +0 -324
- package/skills/skill-download/src/skill-install.ts +0 -205
- package/skills/skill-exa/LICENSE +0 -21
- package/skills/skill-exa/README.md +0 -26
- package/skills/skill-exa/SKILL.md +0 -92
- package/skills/skill-exa/install.sh +0 -112
- package/skills/skill-exa/package.json +0 -31
- package/skills/skill-exa/src/auth.ts +0 -49
- package/skills/skill-exa/src/installer.ts +0 -324
- package/skills/skill-exa/src/skill-install.ts +0 -174
- package/skills/skill-filesearch/LICENSE +0 -21
- package/skills/skill-filesearch/README.md +0 -17
- package/skills/skill-filesearch/install.sh +0 -112
- package/skills/skill-filesearch/package.json +0 -31
- package/skills/skill-filesearch/src/auth.ts +0 -49
- package/skills/skill-filesearch/src/installer.ts +0 -324
- package/skills/skill-filesearch/src/skill-install.ts +0 -205
- package/skills/skill-fill/LICENSE +0 -21
- package/skills/skill-fill/README.md +0 -17
- package/skills/skill-fill/install.sh +0 -112
- package/skills/skill-fill/package.json +0 -31
- package/skills/skill-fill/src/auth.ts +0 -49
- package/skills/skill-fill/src/installer.ts +0 -324
- package/skills/skill-fill/src/skill-install.ts +0 -205
- package/skills/skill-generate-audio/CLAUDE.md +0 -3
- package/skills/skill-generate-audio/SKILL.md +0 -53
- package/skills/skill-generate-audio/package.json +0 -30
- package/skills/skill-generate-audio/src/index.ts +0 -656
- package/skills/skill-generate-audio/tsconfig.json +0 -18
- package/skills/skill-generate-readme/CLAUDE.md +0 -19
- package/skills/skill-generate-readme/package.json +0 -32
- package/skills/skill-generate-readme/src/index.ts +0 -867
- package/skills/skill-generate-readme/tsconfig.json +0 -14
- package/skills/skill-generate-slides/CLAUDE.md +0 -19
- package/skills/skill-generate-slides/package.json +0 -32
- package/skills/skill-generate-slides/src/ai.ts +0 -140
- package/skills/skill-generate-slides/src/cli.ts +0 -161
- package/skills/skill-generate-slides/src/export.ts +0 -65
- package/skills/skill-generate-slides/src/index.ts +0 -1417
- package/skills/skill-generate-slides/src/layout.ts +0 -31
- package/skills/skill-generate-slides/src/parse.ts +0 -282
- package/skills/skill-generate-slides/src/render.ts +0 -711
- package/skills/skill-generate-slides/tsconfig.json +0 -14
- package/skills/skill-get-api-docs/CLAUDE.md +0 -19
- package/skills/skill-get-api-docs/package.json +0 -32
- package/skills/skill-get-api-docs/src/index.ts +0 -1176
- package/skills/skill-get-api-docs/tsconfig.json +0 -14
- package/skills/skill-googledrive/LICENSE +0 -21
- package/skills/skill-googledrive/README.md +0 -27
- package/skills/skill-googledrive/SKILL.md +0 -140
- package/skills/skill-googledrive/install.sh +0 -112
- package/skills/skill-googledrive/package.json +0 -31
- package/skills/skill-googledrive/src/auth.ts +0 -49
- package/skills/skill-googledrive/src/installer.ts +0 -324
- package/skills/skill-googledrive/src/skill-install.ts +0 -174
- package/skills/skill-grant-compliance-scanner/CLAUDE.md +0 -19
- package/skills/skill-grant-compliance-scanner/package.json +0 -32
- package/skills/skill-grant-compliance-scanner/src/index.ts +0 -94
- package/skills/skill-grant-compliance-scanner/tsconfig.json +0 -14
- package/skills/skill-hubsearch/LICENSE +0 -21
- package/skills/skill-hubsearch/README.md +0 -17
- package/skills/skill-hubsearch/install.sh +0 -112
- package/skills/skill-hubsearch/package.json +0 -31
- package/skills/skill-hubsearch/src/auth.ts +0 -49
- package/skills/skill-hubsearch/src/installer.ts +0 -324
- package/skills/skill-hubsearch/src/skill-install.ts +0 -205
- package/skills/skill-implementation-architecture/CLAUDE.md +0 -19
- package/skills/skill-implementation-architecture/package.json +0 -32
- package/skills/skill-implementation-architecture/src/index.ts +0 -460
- package/skills/skill-implementation-architecture/tsconfig.json +0 -14
- package/skills/skill-implementation-audit/CLAUDE.md +0 -19
- package/skills/skill-implementation-audit/package.json +0 -32
- package/skills/skill-implementation-audit/src/index.ts +0 -502
- package/skills/skill-implementation-audit/tsconfig.json +0 -14
- package/skills/skill-implementation-cost/CLAUDE.md +0 -19
- package/skills/skill-implementation-cost/package.json +0 -32
- package/skills/skill-implementation-cost/src/index.ts +0 -873
- package/skills/skill-implementation-cost/tsconfig.json +0 -14
- package/skills/skill-implementation-dispatch/CLAUDE.md +0 -19
- package/skills/skill-implementation-dispatch/package.json +0 -32
- package/skills/skill-implementation-dispatch/src/index.ts +0 -390
- package/skills/skill-implementation-dispatch/tsconfig.json +0 -14
- package/skills/skill-implementation-hook/CLAUDE.md +0 -19
- package/skills/skill-implementation-hook/package.json +0 -32
- package/skills/skill-implementation-hook/src/index.ts +0 -787
- package/skills/skill-implementation-hook/tsconfig.json +0 -14
- package/skills/skill-implementation-index/CLAUDE.md +0 -19
- package/skills/skill-implementation-index/package.json +0 -32
- package/skills/skill-implementation-index/src/index.ts +0 -767
- package/skills/skill-implementation-index/tsconfig.json +0 -14
- package/skills/skill-implementation-init/CLAUDE.md +0 -19
- package/skills/skill-implementation-init/package.json +0 -32
- package/skills/skill-implementation-init/src/index.ts +0 -378
- package/skills/skill-implementation-init/tsconfig.json +0 -14
- package/skills/skill-implementation-memento/CLAUDE.md +0 -19
- package/skills/skill-implementation-memento/package.json +0 -32
- package/skills/skill-implementation-memento/src/index.ts +0 -442
- package/skills/skill-implementation-memento/tsconfig.json +0 -14
- package/skills/skill-linear/LICENSE +0 -21
- package/skills/skill-linear/README.md +0 -28
- package/skills/skill-linear/SKILL.md +0 -94
- package/skills/skill-linear/install.sh +0 -112
- package/skills/skill-linear/package.json +0 -31
- package/skills/skill-linear/src/auth.ts +0 -49
- package/skills/skill-linear/src/installer.ts +0 -324
- package/skills/skill-linear/src/skill-install.ts +0 -174
- package/skills/skill-mail/LICENSE +0 -21
- package/skills/skill-mail/README.md +0 -17
- package/skills/skill-mail/install.sh +0 -112
- package/skills/skill-mail/package.json +0 -31
- package/skills/skill-mail/src/auth.ts +0 -49
- package/skills/skill-mail/src/installer.ts +0 -324
- package/skills/skill-mail/src/skill-install.ts +0 -205
- package/skills/skill-manage-gmail/CLAUDE.md +0 -19
- package/skills/skill-manage-gmail/package.json +0 -32
- package/skills/skill-manage-gmail/src/index.ts +0 -504
- package/skills/skill-manage-gmail/tsconfig.json +0 -14
- package/skills/skill-merch-mockup-factory/CLAUDE.md +0 -19
- package/skills/skill-merch-mockup-factory/package.json +0 -32
- package/skills/skill-merch-mockup-factory/src/index.ts +0 -296
- package/skills/skill-merch-mockup-factory/tsconfig.json +0 -14
- package/skills/skill-message/LICENSE +0 -21
- package/skills/skill-message/README.md +0 -17
- package/skills/skill-message/install.sh +0 -112
- package/skills/skill-message/package.json +0 -31
- package/skills/skill-message/src/auth.ts +0 -49
- package/skills/skill-message/src/installer.ts +0 -324
- package/skills/skill-message/src/skill-install.ts +0 -205
- package/skills/skill-newsletter-campaign-planner/CLAUDE.md +0 -19
- package/skills/skill-newsletter-campaign-planner/package.json +0 -32
- package/skills/skill-newsletter-campaign-planner/src/index.ts +0 -252
- package/skills/skill-newsletter-campaign-planner/tsconfig.json +0 -14
- package/skills/skill-notify/LICENSE +0 -21
- package/skills/skill-notify/README.md +0 -17
- package/skills/skill-notify/install.sh +0 -112
- package/skills/skill-notify/package.json +0 -31
- package/skills/skill-notify/src/auth.ts +0 -49
- package/skills/skill-notify/src/installer.ts +0 -324
- package/skills/skill-notify/src/skill-install.ts +0 -205
- package/skills/skill-notion/LICENSE +0 -21
- package/skills/skill-notion/README.md +0 -27
- package/skills/skill-notion/SKILL.md +0 -115
- package/skills/skill-notion/install.sh +0 -112
- package/skills/skill-notion/package.json +0 -31
- package/skills/skill-notion/src/auth.ts +0 -49
- package/skills/skill-notion/src/installer.ts +0 -324
- package/skills/skill-notion/src/skill-install.ts +0 -174
- package/skills/skill-parse-pdf/CLAUDE.md +0 -19
- package/skills/skill-parse-pdf/package.json +0 -32
- package/skills/skill-parse-pdf/src/index.ts +0 -581
- package/skills/skill-parse-pdf/tsconfig.json +0 -14
- package/skills/skill-playwright/LICENSE +0 -21
- package/skills/skill-playwright/README.md +0 -27
- package/skills/skill-playwright/SKILL.md +0 -116
- package/skills/skill-playwright/install.sh +0 -112
- package/skills/skill-playwright/package.json +0 -31
- package/skills/skill-playwright/src/auth.ts +0 -49
- package/skills/skill-playwright/src/installer.ts +0 -324
- package/skills/skill-playwright/src/skill-install.ts +0 -174
- package/skills/skill-projectbuild/LICENSE +0 -21
- package/skills/skill-projectbuild/README.md +0 -17
- package/skills/skill-projectbuild/install.sh +0 -112
- package/skills/skill-projectbuild/package.json +0 -31
- package/skills/skill-projectbuild/src/auth.ts +0 -49
- package/skills/skill-projectbuild/src/installer.ts +0 -324
- package/skills/skill-projectbuild/src/skill-install.ts +0 -205
- package/skills/skill-read-gmail/CLAUDE.md +0 -19
- package/skills/skill-read-gmail/package.json +0 -32
- package/skills/skill-read-gmail/src/index.ts +0 -343
- package/skills/skill-read-gmail/tsconfig.json +0 -14
- package/skills/skill-remember/LICENSE +0 -21
- package/skills/skill-remember/README.md +0 -17
- package/skills/skill-remember/install.sh +0 -112
- package/skills/skill-remember/package.json +0 -31
- package/skills/skill-remember/src/auth.ts +0 -49
- package/skills/skill-remember/src/installer.ts +0 -324
- package/skills/skill-remember/src/skill-install.ts +0 -205
- package/skills/skill-schedule/README.md +0 -17
- package/skills/skill-schedule/install.sh +0 -112
- package/skills/skill-schedule/src/auth.ts +0 -49
- package/skills/skill-schedule/src/installer.ts +0 -324
- package/skills/skill-schedule/src/skill-install.ts +0 -205
- package/skills/skill-search/LICENSE +0 -21
- package/skills/skill-search/README.md +0 -17
- package/skills/skill-search/install.sh +0 -112
- package/skills/skill-search/package.json +0 -31
- package/skills/skill-search/src/auth.ts +0 -49
- package/skills/skill-search/src/installer.ts +0 -324
- package/skills/skill-search/src/skill-install.ts +0 -205
- package/skills/skill-shadcn/LICENSE +0 -21
- package/skills/skill-shadcn/README.md +0 -27
- package/skills/skill-shadcn/SKILL.md +0 -113
- package/skills/skill-shadcn/install.sh +0 -112
- package/skills/skill-shadcn/package.json +0 -31
- package/skills/skill-shadcn/src/auth.ts +0 -49
- package/skills/skill-shadcn/src/installer.ts +0 -324
- package/skills/skill-shadcn/src/skill-install.ts +0 -174
- package/skills/skill-shadcn-theme/CLAUDE.md +0 -19
- package/skills/skill-shadcn-theme/package.json +0 -32
- package/skills/skill-shadcn-theme/src/index.ts +0 -16
- package/skills/skill-shadcn-theme/tsconfig.json +0 -14
- package/skills/skill-social-template-kit/CLAUDE.md +0 -19
- package/skills/skill-social-template-kit/package.json +0 -32
- package/skills/skill-social-template-kit/src/index.ts +0 -303
- package/skills/skill-social-template-kit/tsconfig.json +0 -14
- package/skills/skill-summarize/LICENSE +0 -21
- package/skills/skill-summarize/README.md +0 -17
- package/skills/skill-summarize/install.sh +0 -112
- package/skills/skill-summarize/package.json +0 -31
- package/skills/skill-summarize/src/auth.ts +0 -49
- package/skills/skill-summarize/src/installer.ts +0 -324
- package/skills/skill-summarize/src/skill-install.ts +0 -205
- package/skills/skill-sync/LICENSE +0 -21
- package/skills/skill-sync/README.md +0 -17
- package/skills/skill-sync/install.sh +0 -112
- package/skills/skill-sync/package.json +0 -31
- package/skills/skill-sync/src/auth.ts +0 -49
- package/skills/skill-sync/src/installer.ts +0 -324
- package/skills/skill-sync/src/skill-install.ts +0 -205
- package/skills/skill-time-blocking-orchestrator/CLAUDE.md +0 -19
- package/skills/skill-time-blocking-orchestrator/package.json +0 -32
- package/skills/skill-time-blocking-orchestrator/src/index.ts +0 -328
- package/skills/skill-time-blocking-orchestrator/tsconfig.json +0 -14
- package/skills/skill-transform/.env.example +0 -2
- package/skills/skill-transform/LICENSE +0 -21
- package/skills/skill-transform/README.md +0 -17
- package/skills/skill-transform/SKILL.md +0 -127
- package/skills/skill-transform/install.sh +0 -112
- package/skills/skill-transform/package.json +0 -37
- package/skills/skill-transform/src/auth.ts +0 -49
- package/skills/skill-transform/src/http-client.ts +0 -128
- package/skills/skill-transform/src/index-http.ts +0 -111
- package/skills/skill-transform/src/index-local.ts +0 -368
- package/skills/skill-transform/src/index.ts +0 -111
- package/skills/skill-transform/src/installer.ts +0 -324
- package/skills/skill-transform/src/skill-install.ts +0 -205
- package/skills/skill-transform/src/transformers/ai-transformer.ts +0 -202
- package/skills/skill-transform/src/transformers/format-detector.ts +0 -147
- package/skills/skill-transform/src/types.ts +0 -95
- package/skills/skill-transform/tsconfig.json +0 -18
- package/skills/skill-translate/LICENSE +0 -21
- package/skills/skill-translate/README.md +0 -17
- package/skills/skill-translate/install.sh +0 -112
- package/skills/skill-translate/package.json +0 -31
- package/skills/skill-translate/src/auth.ts +0 -49
- package/skills/skill-translate/src/installer.ts +0 -324
- package/skills/skill-translate/src/skill-install.ts +0 -205
- package/skills/skill-vendor-comparison-coach/CLAUDE.md +0 -19
- package/skills/skill-vendor-comparison-coach/package.json +0 -32
- package/skills/skill-vendor-comparison-coach/src/index.ts +0 -337
- package/skills/skill-vendor-comparison-coach/tsconfig.json +0 -14
- package/skills/skill-videodownload/.env.example +0 -5
- package/skills/skill-videodownload/CLAUDE.md +0 -64
- package/skills/skill-videodownload/LICENSE +0 -21
- package/skills/skill-videodownload/README.md +0 -166
- package/skills/skill-videodownload/package.json +0 -49
- package/skills/skill-videodownload/src/commands/config.ts +0 -89
- package/skills/skill-videodownload/src/commands/download.ts +0 -61
- package/skills/skill-videodownload/src/commands/info.ts +0 -83
- package/skills/skill-videodownload/src/commands/list.ts +0 -84
- package/skills/skill-videodownload/src/lib/downloader.ts +0 -270
- package/skills/skill-videodownload/src/lib/storage.ts +0 -167
- package/skills/skill-videodownload/src/types/index.ts +0 -64
- package/skills/skill-videodownload/src/utils/logger.ts +0 -49
- package/skills/skill-videodownload/src/utils/paths.ts +0 -94
- package/skills/skill-videodownload/tsconfig.json +0 -17
- package/skills/skill-voiceover/.env.example +0 -5
- package/skills/skill-voiceover/CLAUDE.md +0 -40
- package/skills/skill-voiceover/LICENSE +0 -21
- package/skills/skill-voiceover/README.md +0 -64
- package/skills/skill-voiceover/package.json +0 -43
- package/skills/skill-voiceover/src/commands/config.ts +0 -38
- package/skills/skill-voiceover/src/commands/generate.ts +0 -37
- package/skills/skill-voiceover/src/commands/voices.ts +0 -33
- package/skills/skill-voiceover/src/lib/generator.ts +0 -159
- package/skills/skill-voiceover/src/lib/storage.ts +0 -55
- package/skills/skill-voiceover/src/types/index.ts +0 -55
- package/skills/skill-voiceover/src/utils/logger.ts +0 -30
- package/skills/skill-voiceover/src/utils/paths.ts +0 -22
- package/skills/skill-voiceover/tsconfig.json +0 -17
- package/skills/skill-websearch/LICENSE +0 -21
- package/skills/skill-websearch/README.md +0 -17
- package/skills/skill-websearch/install.sh +0 -112
- package/skills/skill-websearch/package.json +0 -31
- package/skills/skill-websearch/src/auth.ts +0 -49
- package/skills/skill-websearch/src/installer.ts +0 -324
- package/skills/skill-websearch/src/skill-install.ts +0 -205
- /package/skills/{skill-compose-gmail ā skill-gmail}/CLAUDE.md +0 -0
- /package/skills/{skill-compose-gmail ā skill-gmail}/package.json +0 -0
- /package/skills/{skill-compose-gmail ā skill-gmail}/src/index.ts +0 -0
- /package/skills/{skill-architecture-docs ā skill-gmail}/tsconfig.json +0 -0
|
@@ -1,867 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generate README - Auto-generate comprehensive README.md files from codebase analysis
|
|
5
|
-
*
|
|
6
|
-
* This skill analyzes a codebase and generates a professional README.md with:
|
|
7
|
-
* - Project detection (type, frameworks, dependencies)
|
|
8
|
-
* - Badge generation
|
|
9
|
-
* - Code examples
|
|
10
|
-
* - Multiple templates
|
|
11
|
-
* - Custom sections
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { readFile, writeFile, readdir, stat, exists } from "fs/promises";
|
|
15
|
-
import { resolve, join, dirname, basename } from "path";
|
|
16
|
-
import { parseArgs } from "util";
|
|
17
|
-
|
|
18
|
-
// Types
|
|
19
|
-
interface PackageJson {
|
|
20
|
-
name?: string;
|
|
21
|
-
version?: string;
|
|
22
|
-
description?: string;
|
|
23
|
-
author?: string | { name: string; email?: string };
|
|
24
|
-
license?: string;
|
|
25
|
-
repository?: string | { type: string; url: string };
|
|
26
|
-
homepage?: string;
|
|
27
|
-
main?: string;
|
|
28
|
-
scripts?: Record<string, string>;
|
|
29
|
-
dependencies?: Record<string, string>;
|
|
30
|
-
devDependencies?: Record<string, string>;
|
|
31
|
-
keywords?: string[];
|
|
32
|
-
engines?: Record<string, string>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
interface PyProjectToml {
|
|
36
|
-
tool?: {
|
|
37
|
-
poetry?: {
|
|
38
|
-
name?: string;
|
|
39
|
-
version?: string;
|
|
40
|
-
description?: string;
|
|
41
|
-
authors?: string[];
|
|
42
|
-
license?: string;
|
|
43
|
-
homepage?: string;
|
|
44
|
-
repository?: string;
|
|
45
|
-
dependencies?: Record<string, string>;
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
project?: {
|
|
49
|
-
name?: string;
|
|
50
|
-
version?: string;
|
|
51
|
-
description?: string;
|
|
52
|
-
authors?: Array<{ name: string; email?: string }>;
|
|
53
|
-
license?: string;
|
|
54
|
-
dependencies?: string[];
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
interface CargoToml {
|
|
59
|
-
package?: {
|
|
60
|
-
name?: string;
|
|
61
|
-
version?: string;
|
|
62
|
-
description?: string;
|
|
63
|
-
authors?: string[];
|
|
64
|
-
license?: string;
|
|
65
|
-
repository?: string;
|
|
66
|
-
homepage?: string;
|
|
67
|
-
};
|
|
68
|
-
dependencies?: Record<string, any>;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
interface ProjectInfo {
|
|
72
|
-
name: string;
|
|
73
|
-
version: string;
|
|
74
|
-
description: string;
|
|
75
|
-
author: string;
|
|
76
|
-
license: string;
|
|
77
|
-
repository: string;
|
|
78
|
-
homepage: string;
|
|
79
|
-
type: "nodejs" | "python" | "rust" | "go" | "ruby" | "php" | "java" | "unknown";
|
|
80
|
-
frameworks: string[];
|
|
81
|
-
dependencies: Record<string, string>;
|
|
82
|
-
devDependencies: Record<string, string>;
|
|
83
|
-
packageManager: "npm" | "yarn" | "pnpm" | "bun" | "pip" | "poetry" | "cargo" | "go" | "unknown";
|
|
84
|
-
hasTests: boolean;
|
|
85
|
-
hasCI: boolean;
|
|
86
|
-
mainFile?: string;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
interface Config {
|
|
90
|
-
template: "minimal" | "standard" | "comprehensive";
|
|
91
|
-
output: string;
|
|
92
|
-
sections: {
|
|
93
|
-
features: boolean;
|
|
94
|
-
installation: boolean;
|
|
95
|
-
usage: boolean;
|
|
96
|
-
api: boolean;
|
|
97
|
-
contributing: boolean;
|
|
98
|
-
license: boolean;
|
|
99
|
-
changelog: boolean;
|
|
100
|
-
roadmap: boolean;
|
|
101
|
-
};
|
|
102
|
-
customSections: Array<{ title: string; content: string }>;
|
|
103
|
-
badges: string[];
|
|
104
|
-
noBadges: boolean;
|
|
105
|
-
noToc: boolean;
|
|
106
|
-
noExamples: boolean;
|
|
107
|
-
license?: string;
|
|
108
|
-
author?: string;
|
|
109
|
-
repository?: string;
|
|
110
|
-
homepage?: string;
|
|
111
|
-
title?: string;
|
|
112
|
-
description?: string;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
interface Arguments {
|
|
116
|
-
template: "minimal" | "standard" | "comprehensive";
|
|
117
|
-
output: string;
|
|
118
|
-
config?: string;
|
|
119
|
-
sections?: string;
|
|
120
|
-
exclude?: string;
|
|
121
|
-
dryRun: boolean;
|
|
122
|
-
force: boolean;
|
|
123
|
-
noBadges: boolean;
|
|
124
|
-
noToc: boolean;
|
|
125
|
-
noExamples: boolean;
|
|
126
|
-
includeChangelog: boolean;
|
|
127
|
-
license?: string;
|
|
128
|
-
badges?: string;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Constants
|
|
132
|
-
const SKILL_NAME = "generate-readme";
|
|
133
|
-
const OUTPUT_DIR = process.env.SKILLS_OUTPUT_DIR || ".skills";
|
|
134
|
-
const PROJECT_ROOT = process.env.SKILLS_PROJECT_ROOT || process.cwd();
|
|
135
|
-
const CWD = process.env.SKILLS_CWD || process.cwd();
|
|
136
|
-
|
|
137
|
-
// Utility functions
|
|
138
|
-
function log(message: string, level: "info" | "error" | "success" = "info") {
|
|
139
|
-
const prefix = {
|
|
140
|
-
info: "ā¹",
|
|
141
|
-
error: "ā",
|
|
142
|
-
success: "ā",
|
|
143
|
-
}[level];
|
|
144
|
-
console.log(`${prefix} ${message}`);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
async function fileExists(path: string): Promise<boolean> {
|
|
148
|
-
try {
|
|
149
|
-
await stat(path);
|
|
150
|
-
return true;
|
|
151
|
-
} catch {
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
async function findPackageFile(): Promise<string | null> {
|
|
157
|
-
const packageFiles = [
|
|
158
|
-
"package.json",
|
|
159
|
-
"pyproject.toml",
|
|
160
|
-
"Cargo.toml",
|
|
161
|
-
"go.mod",
|
|
162
|
-
"Gemfile",
|
|
163
|
-
"composer.json",
|
|
164
|
-
"pom.xml",
|
|
165
|
-
"build.gradle",
|
|
166
|
-
];
|
|
167
|
-
|
|
168
|
-
for (const file of packageFiles) {
|
|
169
|
-
const path = join(CWD, file);
|
|
170
|
-
if (await fileExists(path)) {
|
|
171
|
-
return path;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
async function parsePackageJson(path: string): Promise<Partial<ProjectInfo>> {
|
|
179
|
-
const content = await readFile(path, "utf-8");
|
|
180
|
-
const pkg: PackageJson = JSON.parse(content);
|
|
181
|
-
|
|
182
|
-
// Detect frameworks
|
|
183
|
-
const frameworks: string[] = [];
|
|
184
|
-
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
185
|
-
|
|
186
|
-
const frameworkMap: Record<string, string> = {
|
|
187
|
-
next: "Next.js",
|
|
188
|
-
react: "React",
|
|
189
|
-
vue: "Vue.js",
|
|
190
|
-
"@angular/core": "Angular",
|
|
191
|
-
express: "Express",
|
|
192
|
-
"@nestjs/core": "NestJS",
|
|
193
|
-
fastify: "Fastify",
|
|
194
|
-
koa: "Koa",
|
|
195
|
-
svelte: "Svelte",
|
|
196
|
-
"@remix-run/react": "Remix",
|
|
197
|
-
astro: "Astro",
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
for (const [dep, framework] of Object.entries(frameworkMap)) {
|
|
201
|
-
if (allDeps[dep]) {
|
|
202
|
-
frameworks.push(framework);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Determine package manager
|
|
207
|
-
let packageManager: ProjectInfo["packageManager"] = "npm";
|
|
208
|
-
if (await fileExists(join(CWD, "bun.lockb"))) packageManager = "bun";
|
|
209
|
-
else if (await fileExists(join(CWD, "pnpm-lock.yaml"))) packageManager = "pnpm";
|
|
210
|
-
else if (await fileExists(join(CWD, "yarn.lock"))) packageManager = "yarn";
|
|
211
|
-
|
|
212
|
-
const repoUrl =
|
|
213
|
-
typeof pkg.repository === "string" ? pkg.repository : pkg.repository?.url || "";
|
|
214
|
-
|
|
215
|
-
return {
|
|
216
|
-
name: pkg.name || basename(CWD),
|
|
217
|
-
version: pkg.version || "1.0.0",
|
|
218
|
-
description: pkg.description || "",
|
|
219
|
-
author: typeof pkg.author === "string" ? pkg.author : pkg.author?.name || "",
|
|
220
|
-
license: pkg.license || "MIT",
|
|
221
|
-
repository: repoUrl.replace(/^git\+/, "").replace(/\.git$/, ""),
|
|
222
|
-
homepage: pkg.homepage || "",
|
|
223
|
-
type: "nodejs",
|
|
224
|
-
frameworks,
|
|
225
|
-
dependencies: pkg.dependencies || {},
|
|
226
|
-
devDependencies: pkg.devDependencies || {},
|
|
227
|
-
packageManager,
|
|
228
|
-
mainFile: pkg.main,
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
async function parsePyProjectToml(path: string): Promise<Partial<ProjectInfo>> {
|
|
233
|
-
const content = await readFile(path, "utf-8");
|
|
234
|
-
|
|
235
|
-
// Simple TOML parser for pyproject.toml
|
|
236
|
-
const lines = content.split("\n");
|
|
237
|
-
const info: Partial<ProjectInfo> = {
|
|
238
|
-
type: "python",
|
|
239
|
-
frameworks: [],
|
|
240
|
-
dependencies: {},
|
|
241
|
-
devDependencies: {},
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
let section = "";
|
|
245
|
-
for (const line of lines) {
|
|
246
|
-
const trimmed = line.trim();
|
|
247
|
-
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
248
|
-
section = trimmed.slice(1, -1);
|
|
249
|
-
} else if (trimmed.includes("=")) {
|
|
250
|
-
const [key, ...valueParts] = trimmed.split("=");
|
|
251
|
-
const value = valueParts.join("=").trim().replace(/^["']|["']$/g, "");
|
|
252
|
-
|
|
253
|
-
if (section === "tool.poetry" || section === "project") {
|
|
254
|
-
if (key.trim() === "name") info.name = value;
|
|
255
|
-
if (key.trim() === "version") info.version = value;
|
|
256
|
-
if (key.trim() === "description") info.description = value;
|
|
257
|
-
if (key.trim() === "license") info.license = value;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Detect Python frameworks
|
|
263
|
-
const frameworks: string[] = [];
|
|
264
|
-
if (content.includes("django")) frameworks.push("Django");
|
|
265
|
-
if (content.includes("fastapi")) frameworks.push("FastAPI");
|
|
266
|
-
if (content.includes("flask")) frameworks.push("Flask");
|
|
267
|
-
if (content.includes("tornado")) frameworks.push("Tornado");
|
|
268
|
-
|
|
269
|
-
info.frameworks = frameworks;
|
|
270
|
-
info.packageManager = content.includes("[tool.poetry]") ? "poetry" : "pip";
|
|
271
|
-
|
|
272
|
-
return info;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
async function parseCargoToml(path: string): Promise<Partial<ProjectInfo>> {
|
|
276
|
-
const content = await readFile(path, "utf-8");
|
|
277
|
-
|
|
278
|
-
// Simple TOML parser for Cargo.toml
|
|
279
|
-
const lines = content.split("\n");
|
|
280
|
-
const info: Partial<ProjectInfo> = {
|
|
281
|
-
type: "rust",
|
|
282
|
-
frameworks: [],
|
|
283
|
-
dependencies: {},
|
|
284
|
-
devDependencies: {},
|
|
285
|
-
packageManager: "cargo",
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
let section = "";
|
|
289
|
-
for (const line of lines) {
|
|
290
|
-
const trimmed = line.trim();
|
|
291
|
-
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
292
|
-
section = trimmed.slice(1, -1);
|
|
293
|
-
} else if (trimmed.includes("=") && section === "package") {
|
|
294
|
-
const [key, ...valueParts] = trimmed.split("=");
|
|
295
|
-
const value = valueParts.join("=").trim().replace(/^["']|["']$/g, "");
|
|
296
|
-
|
|
297
|
-
if (key.trim() === "name") info.name = value;
|
|
298
|
-
if (key.trim() === "version") info.version = value;
|
|
299
|
-
if (key.trim() === "description") info.description = value;
|
|
300
|
-
if (key.trim() === "license") info.license = value;
|
|
301
|
-
if (key.trim() === "repository") info.repository = value;
|
|
302
|
-
if (key.trim() === "homepage") info.homepage = value;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// Detect Rust frameworks
|
|
307
|
-
const frameworks: string[] = [];
|
|
308
|
-
if (content.includes("actix-web")) frameworks.push("Actix Web");
|
|
309
|
-
if (content.includes("rocket")) frameworks.push("Rocket");
|
|
310
|
-
if (content.includes("tokio")) frameworks.push("Tokio");
|
|
311
|
-
if (content.includes("axum")) frameworks.push("Axum");
|
|
312
|
-
|
|
313
|
-
info.frameworks = frameworks;
|
|
314
|
-
|
|
315
|
-
return info;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
async function detectProjectInfo(): Promise<ProjectInfo> {
|
|
319
|
-
const packageFile = await findPackageFile();
|
|
320
|
-
|
|
321
|
-
if (!packageFile) {
|
|
322
|
-
log("No package file found, using defaults", "info");
|
|
323
|
-
return {
|
|
324
|
-
name: basename(CWD),
|
|
325
|
-
version: "1.0.0",
|
|
326
|
-
description: "",
|
|
327
|
-
author: "",
|
|
328
|
-
license: "MIT",
|
|
329
|
-
repository: "",
|
|
330
|
-
homepage: "",
|
|
331
|
-
type: "unknown",
|
|
332
|
-
frameworks: [],
|
|
333
|
-
dependencies: {},
|
|
334
|
-
devDependencies: {},
|
|
335
|
-
packageManager: "unknown",
|
|
336
|
-
hasTests: false,
|
|
337
|
-
hasCI: false,
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
log(`Found package file: ${basename(packageFile)}`, "info");
|
|
342
|
-
|
|
343
|
-
let info: Partial<ProjectInfo> = {};
|
|
344
|
-
|
|
345
|
-
if (packageFile.endsWith("package.json")) {
|
|
346
|
-
info = await parsePackageJson(packageFile);
|
|
347
|
-
} else if (packageFile.endsWith("pyproject.toml")) {
|
|
348
|
-
info = await parsePyProjectToml(packageFile);
|
|
349
|
-
} else if (packageFile.endsWith("Cargo.toml")) {
|
|
350
|
-
info = await parseCargoToml(packageFile);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// Check for tests
|
|
354
|
-
const testDirs = ["test", "tests", "__tests__", "spec"];
|
|
355
|
-
let hasTests = false;
|
|
356
|
-
for (const dir of testDirs) {
|
|
357
|
-
if (await fileExists(join(CWD, dir))) {
|
|
358
|
-
hasTests = true;
|
|
359
|
-
break;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// Check for CI
|
|
364
|
-
const ciFiles = [".github/workflows", ".gitlab-ci.yml", ".travis.yml", "circle.yml"];
|
|
365
|
-
let hasCI = false;
|
|
366
|
-
for (const file of ciFiles) {
|
|
367
|
-
if (await fileExists(join(CWD, file))) {
|
|
368
|
-
hasCI = true;
|
|
369
|
-
break;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
return {
|
|
374
|
-
name: info.name || basename(CWD),
|
|
375
|
-
version: info.version || "1.0.0",
|
|
376
|
-
description: info.description || "",
|
|
377
|
-
author: info.author || "",
|
|
378
|
-
license: info.license || "MIT",
|
|
379
|
-
repository: info.repository || "",
|
|
380
|
-
homepage: info.homepage || "",
|
|
381
|
-
type: info.type || "unknown",
|
|
382
|
-
frameworks: info.frameworks || [],
|
|
383
|
-
dependencies: info.dependencies || {},
|
|
384
|
-
devDependencies: info.devDependencies || {},
|
|
385
|
-
packageManager: info.packageManager || "unknown",
|
|
386
|
-
hasTests,
|
|
387
|
-
hasCI,
|
|
388
|
-
mainFile: info.mainFile,
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
function generateBadges(project: ProjectInfo, config: Config): string[] {
|
|
393
|
-
if (config.noBadges) return [];
|
|
394
|
-
|
|
395
|
-
const badges: string[] = [];
|
|
396
|
-
const badgeTypes = config.badges.length > 0 ? config.badges : ["npm", "license", "build"];
|
|
397
|
-
|
|
398
|
-
for (const type of badgeTypes) {
|
|
399
|
-
switch (type) {
|
|
400
|
-
case "npm":
|
|
401
|
-
if (project.type === "nodejs" && project.name) {
|
|
402
|
-
badges.push(
|
|
403
|
-
`[](https://www.npmjs.com/package/${project.name})`
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
break;
|
|
407
|
-
case "license":
|
|
408
|
-
if (project.license) {
|
|
409
|
-
badges.push(
|
|
410
|
-
`[](https://opensource.org/licenses/${project.license})`
|
|
411
|
-
);
|
|
412
|
-
}
|
|
413
|
-
break;
|
|
414
|
-
case "build":
|
|
415
|
-
if (project.hasCI && project.repository) {
|
|
416
|
-
const repo = project.repository.replace("https://github.com/", "");
|
|
417
|
-
badges.push(
|
|
418
|
-
`[](https://github.com/${repo}/actions)`
|
|
419
|
-
);
|
|
420
|
-
}
|
|
421
|
-
break;
|
|
422
|
-
case "coverage":
|
|
423
|
-
badges.push(
|
|
424
|
-
`[](https://coveralls.io/github/USER/REPO?branch=main)`
|
|
425
|
-
);
|
|
426
|
-
break;
|
|
427
|
-
case "downloads":
|
|
428
|
-
if (project.type === "nodejs" && project.name) {
|
|
429
|
-
badges.push(
|
|
430
|
-
`[](https://www.npmjs.com/package/${project.name})`
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
break;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
return badges;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
function generateInstallSection(project: ProjectInfo): string {
|
|
441
|
-
const sections: string[] = ["## Installation"];
|
|
442
|
-
|
|
443
|
-
switch (project.packageManager) {
|
|
444
|
-
case "npm":
|
|
445
|
-
sections.push("```bash\nnpm install " + project.name + "\n```");
|
|
446
|
-
break;
|
|
447
|
-
case "yarn":
|
|
448
|
-
sections.push("```bash\nyarn add " + project.name + "\n```");
|
|
449
|
-
break;
|
|
450
|
-
case "pnpm":
|
|
451
|
-
sections.push("```bash\npnpm add " + project.name + "\n```");
|
|
452
|
-
break;
|
|
453
|
-
case "bun":
|
|
454
|
-
sections.push("```bash\nbun add " + project.name + "\n```");
|
|
455
|
-
break;
|
|
456
|
-
case "pip":
|
|
457
|
-
sections.push("```bash\npip install " + project.name + "\n```");
|
|
458
|
-
break;
|
|
459
|
-
case "poetry":
|
|
460
|
-
sections.push("```bash\npoetry add " + project.name + "\n```");
|
|
461
|
-
break;
|
|
462
|
-
case "cargo":
|
|
463
|
-
sections.push("```toml\n[dependencies]\n" + project.name + ' = "' + project.version + '"\n```');
|
|
464
|
-
break;
|
|
465
|
-
default:
|
|
466
|
-
sections.push("Installation instructions coming soon.");
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
return sections.join("\n\n");
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
function generateUsageSection(project: ProjectInfo, config: Config): string {
|
|
473
|
-
const sections: string[] = ["## Usage"];
|
|
474
|
-
|
|
475
|
-
if (config.noExamples) {
|
|
476
|
-
sections.push("Usage examples coming soon.");
|
|
477
|
-
return sections.join("\n\n");
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
// Generate basic usage example based on project type
|
|
481
|
-
if (project.type === "nodejs") {
|
|
482
|
-
sections.push("```javascript\nconst " + project.name.replace(/[^a-zA-Z0-9]/g, "") +
|
|
483
|
-
" = require('" + project.name + "');\n\n// Your code here\n```");
|
|
484
|
-
} else if (project.type === "python") {
|
|
485
|
-
sections.push("```python\nimport " + project.name.replace(/[^a-zA-Z0-9]/g, "_") +
|
|
486
|
-
"\n\n# Your code here\n```");
|
|
487
|
-
} else if (project.type === "rust") {
|
|
488
|
-
sections.push("```rust\nuse " + project.name.replace(/-/g, "_") +
|
|
489
|
-
";\n\nfn main() {\n // Your code here\n}\n```");
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
return sections.join("\n\n");
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
function generateFeaturesSection(project: ProjectInfo): string {
|
|
496
|
-
const sections: string[] = ["## Features"];
|
|
497
|
-
|
|
498
|
-
const features: string[] = [];
|
|
499
|
-
|
|
500
|
-
if (project.frameworks.length > 0) {
|
|
501
|
-
features.push(`Built with ${project.frameworks.join(", ")}`);
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
if (project.hasTests) {
|
|
505
|
-
features.push("Comprehensive test suite");
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
if (project.hasCI) {
|
|
509
|
-
features.push("Continuous integration");
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
features.push("Easy to use API");
|
|
513
|
-
features.push("Well documented");
|
|
514
|
-
features.push("TypeScript support" + (project.type === "nodejs" ? "" : " (coming soon)"));
|
|
515
|
-
|
|
516
|
-
sections.push(features.map(f => `- ${f}`).join("\n"));
|
|
517
|
-
|
|
518
|
-
return sections.join("\n\n");
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
function generateTableOfContents(sections: string[]): string {
|
|
522
|
-
const toc: string[] = ["## Table of Contents"];
|
|
523
|
-
|
|
524
|
-
for (const section of sections) {
|
|
525
|
-
const match = section.match(/^## (.+)$/m);
|
|
526
|
-
if (match) {
|
|
527
|
-
const title = match[1];
|
|
528
|
-
const anchor = title.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
529
|
-
toc.push(`- [${title}](#${anchor})`);
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
return toc.join("\n");
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
function generateContributingSection(): string {
|
|
537
|
-
return `## Contributing
|
|
538
|
-
|
|
539
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
540
|
-
|
|
541
|
-
1. Fork the repository
|
|
542
|
-
2. Create your feature branch (\`git checkout -b feature/AmazingFeature\`)
|
|
543
|
-
3. Commit your changes (\`git commit -m 'Add some AmazingFeature'\`)
|
|
544
|
-
4. Push to the branch (\`git push origin feature/AmazingFeature\`)
|
|
545
|
-
5. Open a Pull Request`;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
function generateLicenseSection(project: ProjectInfo): string {
|
|
549
|
-
return `## License
|
|
550
|
-
|
|
551
|
-
This project is licensed under the ${project.license} License - see the LICENSE file for details.`;
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
function generateChangelogSection(): string {
|
|
555
|
-
return `## Changelog
|
|
556
|
-
|
|
557
|
-
### [1.0.0] - ${new Date().toISOString().split("T")[0]}
|
|
558
|
-
|
|
559
|
-
#### Added
|
|
560
|
-
- Initial release`;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
function generateAPISection(project: ProjectInfo): string {
|
|
564
|
-
return `## API Reference
|
|
565
|
-
|
|
566
|
-
### Methods
|
|
567
|
-
|
|
568
|
-
#### \`example()\`
|
|
569
|
-
|
|
570
|
-
Description of example method.
|
|
571
|
-
|
|
572
|
-
**Parameters:**
|
|
573
|
-
- \`param1\` (string): Description of param1
|
|
574
|
-
- \`param2\` (number): Description of param2
|
|
575
|
-
|
|
576
|
-
**Returns:**
|
|
577
|
-
- Returns description
|
|
578
|
-
|
|
579
|
-
**Example:**
|
|
580
|
-
\`\`\`javascript
|
|
581
|
-
const result = example('value', 42);
|
|
582
|
-
\`\`\``;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
async function generateReadme(project: ProjectInfo, config: Config): Promise<string> {
|
|
586
|
-
const sections: string[] = [];
|
|
587
|
-
|
|
588
|
-
// Title
|
|
589
|
-
const title = config.title || project.name;
|
|
590
|
-
sections.push(`# ${title}`);
|
|
591
|
-
|
|
592
|
-
// Badges
|
|
593
|
-
const badges = generateBadges(project, config);
|
|
594
|
-
if (badges.length > 0) {
|
|
595
|
-
sections.push(badges.join("\n"));
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
// Description
|
|
599
|
-
const description = config.description || project.description || "A great project";
|
|
600
|
-
sections.push(description);
|
|
601
|
-
|
|
602
|
-
// Features
|
|
603
|
-
if (config.sections.features && config.template !== "minimal") {
|
|
604
|
-
sections.push(generateFeaturesSection(project));
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
// Table of Contents
|
|
608
|
-
if (!config.noToc && config.template !== "minimal") {
|
|
609
|
-
// We'll add this after we know all sections
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
// Installation
|
|
613
|
-
if (config.sections.installation) {
|
|
614
|
-
sections.push(generateInstallSection(project));
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// Usage
|
|
618
|
-
if (config.sections.usage) {
|
|
619
|
-
sections.push(generateUsageSection(project, config));
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
// API Reference
|
|
623
|
-
if (config.sections.api && config.template === "comprehensive") {
|
|
624
|
-
sections.push(generateAPISection(project));
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
// Custom sections
|
|
628
|
-
for (const customSection of config.customSections) {
|
|
629
|
-
sections.push(`## ${customSection.title}\n\n${customSection.content}`);
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
// Contributing
|
|
633
|
-
if (config.sections.contributing && config.template !== "minimal") {
|
|
634
|
-
sections.push(generateContributingSection());
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
// Changelog
|
|
638
|
-
if (config.sections.changelog && config.template === "comprehensive") {
|
|
639
|
-
sections.push(generateChangelogSection());
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
// License
|
|
643
|
-
if (config.sections.license) {
|
|
644
|
-
sections.push(generateLicenseSection(project));
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
// Insert TOC after description if needed
|
|
648
|
-
if (!config.noToc && config.template !== "minimal") {
|
|
649
|
-
const toc = generateTableOfContents(sections.slice(2)); // Skip title and badges
|
|
650
|
-
sections.splice(3, 0, toc); // Insert after description
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
return sections.join("\n\n") + "\n";
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
async function loadConfig(configPath?: string): Promise<Partial<Config>> {
|
|
657
|
-
if (!configPath) {
|
|
658
|
-
const defaultPath = join(CWD, ".readme-config.json");
|
|
659
|
-
if (await fileExists(defaultPath)) {
|
|
660
|
-
configPath = defaultPath;
|
|
661
|
-
} else {
|
|
662
|
-
return {};
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
try {
|
|
667
|
-
const content = await readFile(configPath, "utf-8");
|
|
668
|
-
return JSON.parse(content);
|
|
669
|
-
} catch (error) {
|
|
670
|
-
log(`Failed to load config from ${configPath}`, "error");
|
|
671
|
-
return {};
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
function showHelp(): void {
|
|
676
|
-
console.log(`
|
|
677
|
-
skill-generate-readme - Auto-generate comprehensive README.md files from codebase analysis
|
|
678
|
-
|
|
679
|
-
Usage:
|
|
680
|
-
skills run generate-readme -- [options]
|
|
681
|
-
|
|
682
|
-
Options:
|
|
683
|
-
-h, --help Show this help message
|
|
684
|
-
--template <type> Template: minimal | standard | comprehensive (default: standard)
|
|
685
|
-
--output <path> Output file path (default: README.md)
|
|
686
|
-
--config <path> Custom config file path
|
|
687
|
-
--sections <list> Comma-separated sections to include
|
|
688
|
-
--exclude <list> Comma-separated sections to exclude
|
|
689
|
-
--dry-run Preview without writing file
|
|
690
|
-
--force Overwrite existing README
|
|
691
|
-
--no-badges Disable badge generation
|
|
692
|
-
--no-toc Disable table of contents
|
|
693
|
-
--no-examples Disable code examples
|
|
694
|
-
--include-changelog Include changelog section
|
|
695
|
-
--license <type> License type
|
|
696
|
-
--badges <list> Comma-separated badge types (npm,license,build,coverage,downloads)
|
|
697
|
-
|
|
698
|
-
Output includes:
|
|
699
|
-
- Project detection (type, frameworks, dependencies)
|
|
700
|
-
- Badge generation
|
|
701
|
-
- Code examples
|
|
702
|
-
- Installation instructions
|
|
703
|
-
- API reference (comprehensive template)
|
|
704
|
-
- Contributing guidelines
|
|
705
|
-
- License section
|
|
706
|
-
|
|
707
|
-
Examples:
|
|
708
|
-
skills run generate-readme -- --template comprehensive --force
|
|
709
|
-
skills run generate-readme -- --sections "installation,usage" --no-badges
|
|
710
|
-
|
|
711
|
-
Note:
|
|
712
|
-
Detects project type from package.json, pyproject.toml, Cargo.toml, etc.
|
|
713
|
-
`);
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
function parseArguments(): Arguments {
|
|
717
|
-
const { values } = parseArgs({
|
|
718
|
-
args: process.argv.slice(2),
|
|
719
|
-
options: {
|
|
720
|
-
help: { type: "boolean", short: "h" },
|
|
721
|
-
template: { type: "string", default: "standard" },
|
|
722
|
-
output: { type: "string", default: "README.md" },
|
|
723
|
-
config: { type: "string" },
|
|
724
|
-
sections: { type: "string" },
|
|
725
|
-
exclude: { type: "string" },
|
|
726
|
-
"dry-run": { type: "boolean", default: false },
|
|
727
|
-
force: { type: "boolean", default: false },
|
|
728
|
-
"no-badges": { type: "boolean", default: false },
|
|
729
|
-
"no-toc": { type: "boolean", default: false },
|
|
730
|
-
"no-examples": { type: "boolean", default: false },
|
|
731
|
-
"include-changelog": { type: "boolean", default: false },
|
|
732
|
-
license: { type: "string" },
|
|
733
|
-
badges: { type: "string" },
|
|
734
|
-
},
|
|
735
|
-
strict: false,
|
|
736
|
-
});
|
|
737
|
-
|
|
738
|
-
if (values.help) {
|
|
739
|
-
showHelp();
|
|
740
|
-
process.exit(0);
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
return {
|
|
744
|
-
template: (values.template as any) || "standard",
|
|
745
|
-
output: values.output || "README.md",
|
|
746
|
-
config: values.config,
|
|
747
|
-
sections: values.sections,
|
|
748
|
-
exclude: values.exclude,
|
|
749
|
-
dryRun: values["dry-run"] || false,
|
|
750
|
-
force: values.force || false,
|
|
751
|
-
noBadges: values["no-badges"] || false,
|
|
752
|
-
noToc: values["no-toc"] || false,
|
|
753
|
-
noExamples: values["no-examples"] || false,
|
|
754
|
-
includeChangelog: values["include-changelog"] || false,
|
|
755
|
-
license: values.license,
|
|
756
|
-
badges: values.badges,
|
|
757
|
-
};
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
async function main() {
|
|
761
|
-
try {
|
|
762
|
-
log(`Starting ${SKILL_NAME}...`, "info");
|
|
763
|
-
|
|
764
|
-
// Parse arguments
|
|
765
|
-
const args = parseArguments();
|
|
766
|
-
|
|
767
|
-
// Load config
|
|
768
|
-
const fileConfig = await loadConfig(args.config);
|
|
769
|
-
|
|
770
|
-
// Merge config
|
|
771
|
-
const config: Config = {
|
|
772
|
-
template: args.template,
|
|
773
|
-
output: join(CWD, args.output),
|
|
774
|
-
sections: {
|
|
775
|
-
features: true,
|
|
776
|
-
installation: true,
|
|
777
|
-
usage: true,
|
|
778
|
-
api: args.template === "comprehensive",
|
|
779
|
-
contributing: args.template !== "minimal",
|
|
780
|
-
license: true,
|
|
781
|
-
changelog: args.includeChangelog || args.template === "comprehensive",
|
|
782
|
-
roadmap: args.template === "comprehensive",
|
|
783
|
-
...fileConfig.sections,
|
|
784
|
-
},
|
|
785
|
-
customSections: fileConfig.customSections || [],
|
|
786
|
-
badges: args.badges ? args.badges.split(",") : fileConfig.badges || [],
|
|
787
|
-
noBadges: args.noBadges,
|
|
788
|
-
noToc: args.noToc,
|
|
789
|
-
noExamples: args.noExamples,
|
|
790
|
-
...fileConfig,
|
|
791
|
-
};
|
|
792
|
-
|
|
793
|
-
// Apply sections filter
|
|
794
|
-
if (args.sections) {
|
|
795
|
-
const included = args.sections.split(",");
|
|
796
|
-
for (const key of Object.keys(config.sections)) {
|
|
797
|
-
config.sections[key as keyof typeof config.sections] = included.includes(key);
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
// Apply exclude filter
|
|
802
|
-
if (args.exclude) {
|
|
803
|
-
const excluded = args.exclude.split(",");
|
|
804
|
-
for (const key of excluded) {
|
|
805
|
-
if (key in config.sections) {
|
|
806
|
-
config.sections[key as keyof typeof config.sections] = false;
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
// Detect project info
|
|
812
|
-
log("Analyzing project...", "info");
|
|
813
|
-
const project = await detectProjectInfo();
|
|
814
|
-
|
|
815
|
-
log(`Detected: ${project.type} project`, "info");
|
|
816
|
-
if (project.frameworks.length > 0) {
|
|
817
|
-
log(`Frameworks: ${project.frameworks.join(", ")}`, "info");
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
// Check if output file exists
|
|
821
|
-
if (!args.force && await fileExists(config.output)) {
|
|
822
|
-
log(`File ${config.output} already exists. Use --force to overwrite.`, "error");
|
|
823
|
-
process.exit(1);
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
// Generate README
|
|
827
|
-
log(`Generating README with ${config.template} template...`, "info");
|
|
828
|
-
const readme = await generateReadme(project, config);
|
|
829
|
-
|
|
830
|
-
// Generate badges for summary
|
|
831
|
-
const badges = generateBadges(project, config);
|
|
832
|
-
|
|
833
|
-
// Dry run
|
|
834
|
-
if (args.dryRun) {
|
|
835
|
-
log("Dry run - preview:", "info");
|
|
836
|
-
console.log("\n" + "=".repeat(80));
|
|
837
|
-
console.log(readme);
|
|
838
|
-
console.log("=".repeat(80) + "\n");
|
|
839
|
-
log("Dry run complete. Use without --dry-run to write file.", "success");
|
|
840
|
-
return;
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
// Write README
|
|
844
|
-
await writeFile(config.output, readme, "utf-8");
|
|
845
|
-
log(`README generated: ${config.output}`, "success");
|
|
846
|
-
|
|
847
|
-
// Export to skills output directory
|
|
848
|
-
const exportDir = join(OUTPUT_DIR, "exports", SKILL_NAME);
|
|
849
|
-
await Bun.write(join(exportDir, basename(config.output)), readme);
|
|
850
|
-
log(`Exported to: ${exportDir}/${basename(config.output)}`, "success");
|
|
851
|
-
|
|
852
|
-
// Summary
|
|
853
|
-
console.log("\nš Summary:");
|
|
854
|
-
console.log(` Template: ${config.template}`);
|
|
855
|
-
console.log(` Output: ${config.output}`);
|
|
856
|
-
console.log(` Sections: ${Object.entries(config.sections).filter(([_, v]) => v).map(([k]) => k).join(", ")}`);
|
|
857
|
-
console.log(` Badges: ${config.noBadges ? "disabled" : badges.length || "auto"}`);
|
|
858
|
-
console.log(` Lines: ${readme.split("\n").length}`);
|
|
859
|
-
|
|
860
|
-
} catch (error) {
|
|
861
|
-
log(`Error: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
862
|
-
console.error(error);
|
|
863
|
-
process.exit(1);
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
main();
|