@rfxlamia/skillkit 1.0.0

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 (225) hide show
  1. package/README.md +16 -0
  2. package/agents/creative-copywriter.md +212 -0
  3. package/agents/dario-amodei.md +135 -0
  4. package/agents/doc-simplifier.md +63 -0
  5. package/agents/kotlin-pro.md +433 -0
  6. package/agents/red-team.md +136 -0
  7. package/agents/sam-altman.md +121 -0
  8. package/agents/seo-manager.md +184 -0
  9. package/bin/skillkit.js +3 -0
  10. package/package.json +35 -0
  11. package/skills/adversarial-review/SKILL.md +219 -0
  12. package/skills/baby-education/SKILL.md +260 -0
  13. package/skills/baby-education/references/advanced-techniques.md +323 -0
  14. package/skills/baby-education/references/transformations.md +345 -0
  15. package/skills/been-there-done-that/SKILL.md +455 -0
  16. package/skills/been-there-done-that/references/analysis-patterns.md +162 -0
  17. package/skills/been-there-done-that/references/git-commands.md +132 -0
  18. package/skills/been-there-done-that/references/tree-insertion-logic.md +145 -0
  19. package/skills/coolhunter/SKILL.md +270 -0
  20. package/skills/coolhunter/assets/elicitation-methods.csv +51 -0
  21. package/skills/coolhunter/knowledge/elicitation-methods.md +312 -0
  22. package/skills/coolhunter/references/workflow-execution.md +238 -0
  23. package/skills/coolhunter/workflow-plan-coolhunter.md +232 -0
  24. package/skills/creative-copywriting/SKILL.md +324 -0
  25. package/skills/creative-copywriting/databases/README.md +60 -0
  26. package/skills/creative-copywriting/databases/carousel-structures.csv +16 -0
  27. package/skills/creative-copywriting/databases/emotional-arcs.csv +11 -0
  28. package/skills/creative-copywriting/databases/hook-formulas.csv +51 -0
  29. package/skills/creative-copywriting/databases/power-words.csv +201 -0
  30. package/skills/creative-copywriting/databases/psychological-triggers.csv +21 -0
  31. package/skills/creative-copywriting/databases/read-more-patterns.csv +26 -0
  32. package/skills/creative-copywriting/databases/swipe-triggers.csv +31 -0
  33. package/skills/creative-copywriting/references/carousel-psychology.md +223 -0
  34. package/skills/creative-copywriting/references/hook-anatomy.md +169 -0
  35. package/skills/creative-copywriting/references/power-word-science.md +134 -0
  36. package/skills/creative-copywriting/references/storytelling-frameworks.md +157 -0
  37. package/skills/diverse-content-gen/SKILL.md +201 -0
  38. package/skills/diverse-content-gen/references/advanced-techniques.md +320 -0
  39. package/skills/diverse-content-gen/references/research-findings.md +379 -0
  40. package/skills/diverse-content-gen/references/task-workflows.md +241 -0
  41. package/skills/diverse-content-gen/references/tool-integration.md +419 -0
  42. package/skills/diverse-content-gen/references/troubleshooting.md +426 -0
  43. package/skills/diverse-content-gen/references/vs-core-technique.md +240 -0
  44. package/skills/framework-critical-thinking/SKILL.md +220 -0
  45. package/skills/framework-critical-thinking/references/bias_detector.md +375 -0
  46. package/skills/framework-critical-thinking/references/fallback_handler.md +239 -0
  47. package/skills/framework-critical-thinking/references/memory_curator.md +161 -0
  48. package/skills/framework-critical-thinking/references/metacognitive_monitor.md +297 -0
  49. package/skills/framework-critical-thinking/references/producer_critic_orchestrator.md +333 -0
  50. package/skills/framework-critical-thinking/references/reasoning_router.md +235 -0
  51. package/skills/framework-critical-thinking/references/reasoning_validator.md +97 -0
  52. package/skills/framework-critical-thinking/references/reflection_trigger.md +78 -0
  53. package/skills/framework-critical-thinking/references/self_verification.md +388 -0
  54. package/skills/framework-critical-thinking/references/uncertainty_quantifier.md +207 -0
  55. package/skills/framework-initiative/SKILL.md +231 -0
  56. package/skills/framework-initiative/references/examples.md +150 -0
  57. package/skills/framework-initiative/references/impact-analysis.md +157 -0
  58. package/skills/framework-initiative/references/intent-patterns.md +145 -0
  59. package/skills/framework-initiative/references/star-framework.md +165 -0
  60. package/skills/humanize-docs/SKILL.md +203 -0
  61. package/skills/humanize-docs/references/advanced-techniques.md +13 -0
  62. package/skills/humanize-docs/references/core-transformations.md +368 -0
  63. package/skills/humanize-docs/references/detection-patterns.md +400 -0
  64. package/skills/humanize-docs/references/examples-gallery.md +374 -0
  65. package/skills/imagine/SKILL.md +190 -0
  66. package/skills/imagine/references/artstyle-corporate-memphis.md +625 -0
  67. package/skills/imagine/references/artstyle-crewdson-hyperrealism.md +295 -0
  68. package/skills/imagine/references/artstyle-iphone-social-media.md +426 -0
  69. package/skills/imagine/references/artstyle-sciencesaru.md +276 -0
  70. package/skills/pre-deploy-checklist/README.md +26 -0
  71. package/skills/pre-deploy-checklist/SKILL.md +153 -0
  72. package/skills/pre-deploy-checklist/references/checklist-categories.md +174 -0
  73. package/skills/pre-deploy-checklist/references/domain-prompts.md +216 -0
  74. package/skills/prompt-engineering/SKILL.md +209 -0
  75. package/skills/prompt-engineering/references/advanced-combinations.md +444 -0
  76. package/skills/prompt-engineering/references/chain-of-thought.md +140 -0
  77. package/skills/prompt-engineering/references/decision_matrix.md +220 -0
  78. package/skills/prompt-engineering/references/few-shot.md +346 -0
  79. package/skills/prompt-engineering/references/json-format.md +270 -0
  80. package/skills/prompt-engineering/references/natural-language.md +420 -0
  81. package/skills/prompt-engineering/references/pitfalls.md +365 -0
  82. package/skills/prompt-engineering/references/prompt-chaining.md +498 -0
  83. package/skills/prompt-engineering/references/react.md +108 -0
  84. package/skills/prompt-engineering/references/self-consistency.md +322 -0
  85. package/skills/prompt-engineering/references/tree-of-thoughts.md +386 -0
  86. package/skills/prompt-engineering/references/xml-format.md +220 -0
  87. package/skills/prompt-engineering/references/yaml-format.md +488 -0
  88. package/skills/prompt-engineering/references/zero-shot.md +74 -0
  89. package/skills/quick-spec/SKILL.md +280 -0
  90. package/skills/quick-spec/assets/tech-spec-template.md +74 -0
  91. package/skills/quick-spec/references/step-01-understand.md +189 -0
  92. package/skills/quick-spec/references/step-02-investigate.md +144 -0
  93. package/skills/quick-spec/references/step-03-generate.md +128 -0
  94. package/skills/quick-spec/references/step-04-review.md +173 -0
  95. package/skills/quick-spec/tests/test_scenarios.md +83 -0
  96. package/skills/quick-spec/tests/test_skill.py +136 -0
  97. package/skills/readme-expert/SKILL.md +538 -0
  98. package/skills/readme-expert/knowledge/INDEX.md +192 -0
  99. package/skills/readme-expert/knowledge/application/quality-standards.md +470 -0
  100. package/skills/readme-expert/knowledge/application/script-executor.md +604 -0
  101. package/skills/readme-expert/knowledge/application/template-library.md +822 -0
  102. package/skills/readme-expert/knowledge/foundation/codebase-scanner.md +361 -0
  103. package/skills/readme-expert/knowledge/foundation/validation-checklist.md +481 -0
  104. package/skills/red-teaming/SKILL.md +321 -0
  105. package/skills/red-teaming/references/ai-llm-redteam.md +517 -0
  106. package/skills/red-teaming/references/attack-techniques.md +410 -0
  107. package/skills/red-teaming/references/cybersecurity-redteam.md +383 -0
  108. package/skills/red-teaming/references/tools-frameworks.md +446 -0
  109. package/skills/releasing/.skillkit-mode +1 -0
  110. package/skills/releasing/SKILL.md +225 -0
  111. package/skills/releasing/references/version-detection.md +108 -0
  112. package/skills/screenwriter/SKILL.md +273 -0
  113. package/skills/screenwriter/references/advanced-techniques.md +216 -0
  114. package/skills/screenwriter/references/pipeline-integration.md +266 -0
  115. package/skills/skillkit/.claude-plugin/plugin.json +27 -0
  116. package/skills/skillkit/CHANGELOG.md +484 -0
  117. package/skills/skillkit/SKILL.md +511 -0
  118. package/skills/skillkit/commands/skillkit.md +6 -0
  119. package/skills/skillkit/commands/validate-plan.md +6 -0
  120. package/skills/skillkit/commands/verify.md +6 -0
  121. package/skills/skillkit/knowledge/INDEX.md +352 -0
  122. package/skills/skillkit/knowledge/application/09-case-studies.md +257 -0
  123. package/skills/skillkit/knowledge/application/10-technical-architecture.md +324 -0
  124. package/skills/skillkit/knowledge/application/11-adoption-strategy.md +267 -0
  125. package/skills/skillkit/knowledge/application/12-testing-and-validation.md +276 -0
  126. package/skills/skillkit/knowledge/application/13-competitive-landscape.md +198 -0
  127. package/skills/skillkit/knowledge/foundation/01-why-skills-exist.md +246 -0
  128. package/skills/skillkit/knowledge/foundation/02-skills-vs-subagents-comparison.md +312 -0
  129. package/skills/skillkit/knowledge/foundation/03-skills-vs-subagents-decision-tree.md +346 -0
  130. package/skills/skillkit/knowledge/foundation/04-hybrid-patterns.md +308 -0
  131. package/skills/skillkit/knowledge/foundation/05-token-economics.md +275 -0
  132. package/skills/skillkit/knowledge/foundation/06-platform-constraints.md +237 -0
  133. package/skills/skillkit/knowledge/foundation/07-security-concerns.md +322 -0
  134. package/skills/skillkit/knowledge/foundation/08-when-not-to-use-skills.md +270 -0
  135. package/skills/skillkit/knowledge/plugin-guide.md +614 -0
  136. package/skills/skillkit/knowledge/tools/14-validation-tools-guide.md +150 -0
  137. package/skills/skillkit/knowledge/tools/15-cost-tools-guide.md +157 -0
  138. package/skills/skillkit/knowledge/tools/16-security-tools-guide.md +122 -0
  139. package/skills/skillkit/knowledge/tools/17-pattern-tools-guide.md +161 -0
  140. package/skills/skillkit/knowledge/tools/18-decision-helper-guide.md +243 -0
  141. package/skills/skillkit/knowledge/tools/19-test-generator-guide.md +275 -0
  142. package/skills/skillkit/knowledge/tools/20-split-skill-guide.md +149 -0
  143. package/skills/skillkit/knowledge/tools/21-quality-scorer-guide.md +226 -0
  144. package/skills/skillkit/knowledge/tools/22-migration-helper-guide.md +356 -0
  145. package/skills/skillkit/knowledge/tools/23-subagent-creation-guide.md +448 -0
  146. package/skills/skillkit/knowledge/tools/24-behavioral-testing-guide.md +122 -0
  147. package/skills/skillkit/references/proposal-generation.md +982 -0
  148. package/skills/skillkit/references/rationalization-catalog.md +75 -0
  149. package/skills/skillkit/references/research-methodology.md +661 -0
  150. package/skills/skillkit/references/section-2-full-creation-workflow.md +452 -0
  151. package/skills/skillkit/references/section-3-validation-workflow-existing-skill.md +63 -0
  152. package/skills/skillkit/references/section-4-decision-workflow-skills-vs-subagents.md +64 -0
  153. package/skills/skillkit/references/section-5-migration-workflow-doc-to-skill.md +58 -0
  154. package/skills/skillkit/references/section-6-subagent-creation-workflow.md +499 -0
  155. package/skills/skillkit/references/section-7-knowledge-reference-map.md +72 -0
  156. package/skills/skillkit/scripts/decision_helper.py +799 -0
  157. package/skills/skillkit/scripts/init_skill.py +400 -0
  158. package/skills/skillkit/scripts/init_subagent.py +231 -0
  159. package/skills/skillkit/scripts/migration_helper.py +669 -0
  160. package/skills/skillkit/scripts/package_skill.py +211 -0
  161. package/skills/skillkit/scripts/pattern_detector.py +381 -0
  162. package/skills/skillkit/scripts/pattern_detector_new.py +382 -0
  163. package/skills/skillkit/scripts/pressure_tester.py +157 -0
  164. package/skills/skillkit/scripts/quality_scorer.py +999 -0
  165. package/skills/skillkit/scripts/quick_validate.py +100 -0
  166. package/skills/skillkit/scripts/security_scanner.py +474 -0
  167. package/skills/skillkit/scripts/split_skill.py +540 -0
  168. package/skills/skillkit/scripts/test_generator.py +695 -0
  169. package/skills/skillkit/scripts/token_estimator.py +493 -0
  170. package/skills/skillkit/scripts/utils/__init__.py +49 -0
  171. package/skills/skillkit/scripts/utils/budget_tracker.py +388 -0
  172. package/skills/skillkit/scripts/utils/output_formatter.py +263 -0
  173. package/skills/skillkit/scripts/utils/reference_validator.py +401 -0
  174. package/skills/skillkit/scripts/validate_skill.py +594 -0
  175. package/skills/skillkit/tests/test_behavioral.py +39 -0
  176. package/skills/skillkit/tests/test_scenarios.md +83 -0
  177. package/skills/skillkit/tests/test_skill.py +136 -0
  178. package/skills/social-media-seo/SKILL.md +278 -0
  179. package/skills/social-media-seo/databases/caption-styles.csv +31 -0
  180. package/skills/social-media-seo/databases/engagement-tactics.csv +16 -0
  181. package/skills/social-media-seo/databases/hashtag-strategies.csv +21 -0
  182. package/skills/social-media-seo/databases/hook-formulas.csv +26 -0
  183. package/skills/social-media-seo/databases/keyword-clusters.csv +11 -0
  184. package/skills/social-media-seo/databases/thread-structures.csv +26 -0
  185. package/skills/social-media-seo/databases/viral-patterns.csv +21 -0
  186. package/skills/social-media-seo/references/analytics-guide.md +321 -0
  187. package/skills/social-media-seo/references/instagram-seo.md +235 -0
  188. package/skills/social-media-seo/references/threads-seo.md +305 -0
  189. package/skills/social-media-seo/references/x-twitter-seo.md +337 -0
  190. package/skills/social-media-seo/scripts/query_database.py +191 -0
  191. package/skills/storyteller/SKILL.md +241 -0
  192. package/skills/storyteller/references/transformation-methodology.md +293 -0
  193. package/skills/storyteller/references/visual-vocabulary.md +177 -0
  194. package/skills/thread-pro/SKILL.md +162 -0
  195. package/skills/thread-pro/anti-ai-patterns.md +120 -0
  196. package/skills/thread-pro/hook-formulas.md +138 -0
  197. package/skills/thread-pro/references/anti-ai-patterns.md +120 -0
  198. package/skills/thread-pro/references/hook-formulas.md +138 -0
  199. package/skills/thread-pro/references/thread-structures.md +240 -0
  200. package/skills/thread-pro/references/voice-injection.md +130 -0
  201. package/skills/thread-pro/thread-structures.md +240 -0
  202. package/skills/thread-pro/voice-injection.md +130 -0
  203. package/skills/tinkering/SKILL.md +251 -0
  204. package/skills/tinkering/references/graduation-checklist.md +100 -0
  205. package/skills/validate-plan/.skillkit-mode +1 -0
  206. package/skills/validate-plan/SKILL.md +406 -0
  207. package/skills/validate-plan/references/dry-principles.md +251 -0
  208. package/skills/validate-plan/references/gap-analysis-guide.md +320 -0
  209. package/skills/validate-plan/references/tdd-patterns.md +413 -0
  210. package/skills/validate-plan/references/yagni-checklist.md +330 -0
  211. package/skills/verify-before-ship/.skillkit-mode +1 -0
  212. package/skills/verify-before-ship/SKILL.md +116 -0
  213. package/skills/verify-before-ship/references/anti-rationalization.md +212 -0
  214. package/skills/verify-before-ship/references/verification-gates.md +305 -0
  215. package/skills-manifest.json +217 -0
  216. package/src/banner.js +10 -0
  217. package/src/cli.js +30 -0
  218. package/src/install.js +53 -0
  219. package/src/install.test.js +40 -0
  220. package/src/picker.js +74 -0
  221. package/src/picker.test.js +21 -0
  222. package/src/scope.js +57 -0
  223. package/src/scope.test.js +19 -0
  224. package/src/update.js +34 -0
  225. package/src/update.test.js +24 -0
package/src/picker.js ADDED
@@ -0,0 +1,74 @@
1
+ import { multiselect, select, log } from '@clack/prompts'
2
+ import { readFileSync } from 'fs'
3
+ import { join, dirname } from 'path'
4
+ import { fileURLToPath } from 'url'
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url))
7
+ const manifest = JSON.parse(readFileSync(join(__dirname, '..', 'skills-manifest.json'), 'utf8'))
8
+
9
+ const CATEGORY_ICONS = {
10
+ core: '⚙️',
11
+ engineering: '🧠',
12
+ documentation: '📖',
13
+ planning: '📐',
14
+ deployment: '🚀',
15
+ productivity: '📊',
16
+ quality: '🛡️',
17
+ security: '🔒',
18
+ experimentation: '🧪',
19
+ 'agent-frameworks': '🤖',
20
+ creative: '✍️',
21
+ uncategorized: ' '
22
+ }
23
+
24
+ export function getCategoryDisplay(skill) {
25
+ const icon = CATEGORY_ICONS[skill.category] || CATEGORY_ICONS.uncategorized
26
+ const label = skill.category ? skill.category.replace(/-/g, ' ') : ''
27
+ return `${icon} ${label}`
28
+ }
29
+
30
+ export async function pickInstallables() {
31
+ const mode = await select({
32
+ message: 'What to install?',
33
+ options: [
34
+ { value: 'all', label: 'Everything (24 skills + 7 agents)' },
35
+ { value: 'skills-only', label: 'All skills only' },
36
+ { value: 'agents-only', label: 'All agents only' },
37
+ { value: 'pick', label: 'Let me choose...' }
38
+ ]
39
+ })
40
+
41
+ if (mode === 'all') return { skills: manifest.skills, agents: manifest.agents }
42
+ if (mode === 'skills-only') return { skills: manifest.skills, agents: [] }
43
+ if (mode === 'agents-only') return { skills: [], agents: manifest.agents }
44
+
45
+ // Manual pick
46
+ const skillChoices = manifest.skills.map(s => ({
47
+ value: s.name,
48
+ label: `${getCategoryDisplay(s)} ${s.name}`,
49
+ hint: s.description.slice(0, 60) + (s.description.length > 60 ? '…' : '')
50
+ }))
51
+
52
+ const agentChoices = manifest.agents.map(a => ({
53
+ value: a.name,
54
+ label: `🤝 ${a.name}`,
55
+ hint: a.description.slice(0, 60) + (a.description.length > 60 ? '…' : '')
56
+ }))
57
+
58
+ const selectedSkills = await multiselect({
59
+ message: 'Select skills to install: (space to toggle, a to select all)',
60
+ options: skillChoices,
61
+ required: false
62
+ })
63
+
64
+ const selectedAgents = await multiselect({
65
+ message: 'Select agents to install:',
66
+ options: agentChoices,
67
+ required: false
68
+ })
69
+
70
+ return {
71
+ skills: manifest.skills.filter(s => selectedSkills.includes(s.name)),
72
+ agents: manifest.agents.filter(a => selectedAgents.includes(a.name))
73
+ }
74
+ }
@@ -0,0 +1,21 @@
1
+ import { test } from 'node:test'
2
+ import assert from 'node:assert'
3
+ import { getCategoryDisplay } from './picker.js'
4
+
5
+ test('getCategoryDisplay returns icon and category label', () => {
6
+ const skill = { name: 'test-skill', category: 'creative' }
7
+ const result = getCategoryDisplay(skill)
8
+ assert.strictEqual(result, '✍️ creative')
9
+ })
10
+
11
+ test('getCategoryDisplay handles uncategorized skills', () => {
12
+ const skill = { name: 'test-skill', category: 'unknown-category' }
13
+ const result = getCategoryDisplay(skill)
14
+ assert.strictEqual(result, ' unknown category')
15
+ })
16
+
17
+ test('getCategoryDisplay handles missing category', () => {
18
+ const skill = { name: 'test-skill' }
19
+ const result = getCategoryDisplay(skill)
20
+ assert.strictEqual(result, ' ')
21
+ })
package/src/scope.js ADDED
@@ -0,0 +1,57 @@
1
+ import { select, log } from '@clack/prompts'
2
+ import { homedir } from 'os'
3
+ import { join } from 'path'
4
+ import { existsSync } from 'fs'
5
+
6
+ export async function selectScope() {
7
+ const userSkillsPath = join(homedir(), '.claude', 'skills')
8
+ const projectSkillsPath = join(process.cwd(), '.claude', 'skills')
9
+ const projectExists = existsSync(join(process.cwd(), '.claude', 'skills'))
10
+
11
+ const scope = await select({
12
+ message: 'Install to:',
13
+ options: [
14
+ {
15
+ value: 'user',
16
+ label: `User scope ~/.claude/skills/`,
17
+ hint: 'available in all projects'
18
+ },
19
+ {
20
+ value: 'project',
21
+ label: `Project scope ./.claude/skills/`,
22
+ hint: projectExists ? 'detected .claude/skills/ here' : `will create ${projectSkillsPath}`
23
+ }
24
+ ]
25
+ })
26
+
27
+ if (scope === 'user') {
28
+ return {
29
+ scope: 'user',
30
+ skillsDir: userSkillsPath,
31
+ agentsDir: join(homedir(), '.claude', 'agents')
32
+ }
33
+ }
34
+
35
+ return {
36
+ scope: 'project',
37
+ skillsDir: projectSkillsPath,
38
+ agentsDir: join(process.cwd(), '.claude', 'agents')
39
+ }
40
+ }
41
+
42
+ // Export for testing
43
+ export function getUserScope() {
44
+ return {
45
+ scope: 'user',
46
+ skillsDir: join(homedir(), '.claude', 'skills'),
47
+ agentsDir: join(homedir(), '.claude', 'agents')
48
+ }
49
+ }
50
+
51
+ export function getProjectScope() {
52
+ return {
53
+ scope: 'project',
54
+ skillsDir: join(process.cwd(), '.claude', 'skills'),
55
+ agentsDir: join(process.cwd(), '.claude', 'agents')
56
+ }
57
+ }
@@ -0,0 +1,19 @@
1
+ import { test } from 'node:test'
2
+ import assert from 'node:assert'
3
+ import { homedir } from 'os'
4
+ import { join } from 'path'
5
+ import { getUserScope, getProjectScope } from './scope.js'
6
+
7
+ test('getUserScope returns correct paths', () => {
8
+ const scope = getUserScope()
9
+ assert.strictEqual(scope.scope, 'user')
10
+ assert.strictEqual(scope.skillsDir, join(homedir(), '.claude', 'skills'))
11
+ assert.strictEqual(scope.agentsDir, join(homedir(), '.claude', 'agents'))
12
+ })
13
+
14
+ test('getProjectScope returns correct paths', () => {
15
+ const scope = getProjectScope()
16
+ assert.strictEqual(scope.scope, 'project')
17
+ assert.strictEqual(scope.skillsDir, join(process.cwd(), '.claude', 'skills'))
18
+ assert.strictEqual(scope.agentsDir, join(process.cwd(), '.claude', 'agents'))
19
+ })
package/src/update.js ADDED
@@ -0,0 +1,34 @@
1
+ import { readFileSync } from 'fs'
2
+ import { join, dirname } from 'path'
3
+ import { fileURLToPath } from 'url'
4
+ import { log, select } from '@clack/prompts'
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url))
7
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'))
8
+
9
+ export async function checkForUpdates() {
10
+ // npx always runs latest — no need to check
11
+ if (process.env.npm_execpath?.includes('npx')) return
12
+
13
+ try {
14
+ const res = await fetch(`https://registry.npmjs.org/@rfxlamia/skillkit/latest`)
15
+ if (!res.ok) {
16
+ if (process.env.DEBUG) log.warn(`Update check failed: HTTP ${res.status}`)
17
+ return
18
+ }
19
+ const { version: latest } = await res.json()
20
+
21
+ if (latest !== pkg.version) {
22
+ log.warn(`Update available: ${pkg.version} → ${latest}`)
23
+ log.info(`Run: npx @rfxlamia/skillkit@latest install`)
24
+ }
25
+ } catch (err) {
26
+ // Network unavailable or other errors — log in debug mode
27
+ if (process.env.DEBUG) log.warn(`Update check failed: ${err.message}`)
28
+ }
29
+ }
30
+
31
+ // Export for testing
32
+ export function isNpxExecution() {
33
+ return process.env.npm_execpath?.includes('npx') ?? false
34
+ }
@@ -0,0 +1,24 @@
1
+ import { test } from 'node:test'
2
+ import assert from 'node:assert'
3
+ import { isNpxExecution } from './update.js'
4
+
5
+ test('isNpxExecution returns true when npm_execpath includes npx', () => {
6
+ const original = process.env.npm_execpath
7
+ process.env.npm_execpath = '/usr/local/lib/node_modules/npm/bin/npx-cli.js'
8
+ assert.strictEqual(isNpxExecution(), true)
9
+ process.env.npm_execpath = original
10
+ })
11
+
12
+ test('isNpxExecution returns false when npm_execpath does not include npx', () => {
13
+ const original = process.env.npm_execpath
14
+ process.env.npm_execpath = '/usr/local/lib/node_modules/npm/bin/npm-cli.js'
15
+ assert.strictEqual(isNpxExecution(), false)
16
+ process.env.npm_execpath = original
17
+ })
18
+
19
+ test('isNpxExecution returns false when npm_execpath is undefined', () => {
20
+ const original = process.env.npm_execpath
21
+ delete process.env.npm_execpath
22
+ assert.strictEqual(isNpxExecution(), false)
23
+ process.env.npm_execpath = original
24
+ })