@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.
- package/README.md +16 -0
- package/agents/creative-copywriter.md +212 -0
- package/agents/dario-amodei.md +135 -0
- package/agents/doc-simplifier.md +63 -0
- package/agents/kotlin-pro.md +433 -0
- package/agents/red-team.md +136 -0
- package/agents/sam-altman.md +121 -0
- package/agents/seo-manager.md +184 -0
- package/bin/skillkit.js +3 -0
- package/package.json +35 -0
- package/skills/adversarial-review/SKILL.md +219 -0
- package/skills/baby-education/SKILL.md +260 -0
- package/skills/baby-education/references/advanced-techniques.md +323 -0
- package/skills/baby-education/references/transformations.md +345 -0
- package/skills/been-there-done-that/SKILL.md +455 -0
- package/skills/been-there-done-that/references/analysis-patterns.md +162 -0
- package/skills/been-there-done-that/references/git-commands.md +132 -0
- package/skills/been-there-done-that/references/tree-insertion-logic.md +145 -0
- package/skills/coolhunter/SKILL.md +270 -0
- package/skills/coolhunter/assets/elicitation-methods.csv +51 -0
- package/skills/coolhunter/knowledge/elicitation-methods.md +312 -0
- package/skills/coolhunter/references/workflow-execution.md +238 -0
- package/skills/coolhunter/workflow-plan-coolhunter.md +232 -0
- package/skills/creative-copywriting/SKILL.md +324 -0
- package/skills/creative-copywriting/databases/README.md +60 -0
- package/skills/creative-copywriting/databases/carousel-structures.csv +16 -0
- package/skills/creative-copywriting/databases/emotional-arcs.csv +11 -0
- package/skills/creative-copywriting/databases/hook-formulas.csv +51 -0
- package/skills/creative-copywriting/databases/power-words.csv +201 -0
- package/skills/creative-copywriting/databases/psychological-triggers.csv +21 -0
- package/skills/creative-copywriting/databases/read-more-patterns.csv +26 -0
- package/skills/creative-copywriting/databases/swipe-triggers.csv +31 -0
- package/skills/creative-copywriting/references/carousel-psychology.md +223 -0
- package/skills/creative-copywriting/references/hook-anatomy.md +169 -0
- package/skills/creative-copywriting/references/power-word-science.md +134 -0
- package/skills/creative-copywriting/references/storytelling-frameworks.md +157 -0
- package/skills/diverse-content-gen/SKILL.md +201 -0
- package/skills/diverse-content-gen/references/advanced-techniques.md +320 -0
- package/skills/diverse-content-gen/references/research-findings.md +379 -0
- package/skills/diverse-content-gen/references/task-workflows.md +241 -0
- package/skills/diverse-content-gen/references/tool-integration.md +419 -0
- package/skills/diverse-content-gen/references/troubleshooting.md +426 -0
- package/skills/diverse-content-gen/references/vs-core-technique.md +240 -0
- package/skills/framework-critical-thinking/SKILL.md +220 -0
- package/skills/framework-critical-thinking/references/bias_detector.md +375 -0
- package/skills/framework-critical-thinking/references/fallback_handler.md +239 -0
- package/skills/framework-critical-thinking/references/memory_curator.md +161 -0
- package/skills/framework-critical-thinking/references/metacognitive_monitor.md +297 -0
- package/skills/framework-critical-thinking/references/producer_critic_orchestrator.md +333 -0
- package/skills/framework-critical-thinking/references/reasoning_router.md +235 -0
- package/skills/framework-critical-thinking/references/reasoning_validator.md +97 -0
- package/skills/framework-critical-thinking/references/reflection_trigger.md +78 -0
- package/skills/framework-critical-thinking/references/self_verification.md +388 -0
- package/skills/framework-critical-thinking/references/uncertainty_quantifier.md +207 -0
- package/skills/framework-initiative/SKILL.md +231 -0
- package/skills/framework-initiative/references/examples.md +150 -0
- package/skills/framework-initiative/references/impact-analysis.md +157 -0
- package/skills/framework-initiative/references/intent-patterns.md +145 -0
- package/skills/framework-initiative/references/star-framework.md +165 -0
- package/skills/humanize-docs/SKILL.md +203 -0
- package/skills/humanize-docs/references/advanced-techniques.md +13 -0
- package/skills/humanize-docs/references/core-transformations.md +368 -0
- package/skills/humanize-docs/references/detection-patterns.md +400 -0
- package/skills/humanize-docs/references/examples-gallery.md +374 -0
- package/skills/imagine/SKILL.md +190 -0
- package/skills/imagine/references/artstyle-corporate-memphis.md +625 -0
- package/skills/imagine/references/artstyle-crewdson-hyperrealism.md +295 -0
- package/skills/imagine/references/artstyle-iphone-social-media.md +426 -0
- package/skills/imagine/references/artstyle-sciencesaru.md +276 -0
- package/skills/pre-deploy-checklist/README.md +26 -0
- package/skills/pre-deploy-checklist/SKILL.md +153 -0
- package/skills/pre-deploy-checklist/references/checklist-categories.md +174 -0
- package/skills/pre-deploy-checklist/references/domain-prompts.md +216 -0
- package/skills/prompt-engineering/SKILL.md +209 -0
- package/skills/prompt-engineering/references/advanced-combinations.md +444 -0
- package/skills/prompt-engineering/references/chain-of-thought.md +140 -0
- package/skills/prompt-engineering/references/decision_matrix.md +220 -0
- package/skills/prompt-engineering/references/few-shot.md +346 -0
- package/skills/prompt-engineering/references/json-format.md +270 -0
- package/skills/prompt-engineering/references/natural-language.md +420 -0
- package/skills/prompt-engineering/references/pitfalls.md +365 -0
- package/skills/prompt-engineering/references/prompt-chaining.md +498 -0
- package/skills/prompt-engineering/references/react.md +108 -0
- package/skills/prompt-engineering/references/self-consistency.md +322 -0
- package/skills/prompt-engineering/references/tree-of-thoughts.md +386 -0
- package/skills/prompt-engineering/references/xml-format.md +220 -0
- package/skills/prompt-engineering/references/yaml-format.md +488 -0
- package/skills/prompt-engineering/references/zero-shot.md +74 -0
- package/skills/quick-spec/SKILL.md +280 -0
- package/skills/quick-spec/assets/tech-spec-template.md +74 -0
- package/skills/quick-spec/references/step-01-understand.md +189 -0
- package/skills/quick-spec/references/step-02-investigate.md +144 -0
- package/skills/quick-spec/references/step-03-generate.md +128 -0
- package/skills/quick-spec/references/step-04-review.md +173 -0
- package/skills/quick-spec/tests/test_scenarios.md +83 -0
- package/skills/quick-spec/tests/test_skill.py +136 -0
- package/skills/readme-expert/SKILL.md +538 -0
- package/skills/readme-expert/knowledge/INDEX.md +192 -0
- package/skills/readme-expert/knowledge/application/quality-standards.md +470 -0
- package/skills/readme-expert/knowledge/application/script-executor.md +604 -0
- package/skills/readme-expert/knowledge/application/template-library.md +822 -0
- package/skills/readme-expert/knowledge/foundation/codebase-scanner.md +361 -0
- package/skills/readme-expert/knowledge/foundation/validation-checklist.md +481 -0
- package/skills/red-teaming/SKILL.md +321 -0
- package/skills/red-teaming/references/ai-llm-redteam.md +517 -0
- package/skills/red-teaming/references/attack-techniques.md +410 -0
- package/skills/red-teaming/references/cybersecurity-redteam.md +383 -0
- package/skills/red-teaming/references/tools-frameworks.md +446 -0
- package/skills/releasing/.skillkit-mode +1 -0
- package/skills/releasing/SKILL.md +225 -0
- package/skills/releasing/references/version-detection.md +108 -0
- package/skills/screenwriter/SKILL.md +273 -0
- package/skills/screenwriter/references/advanced-techniques.md +216 -0
- package/skills/screenwriter/references/pipeline-integration.md +266 -0
- package/skills/skillkit/.claude-plugin/plugin.json +27 -0
- package/skills/skillkit/CHANGELOG.md +484 -0
- package/skills/skillkit/SKILL.md +511 -0
- package/skills/skillkit/commands/skillkit.md +6 -0
- package/skills/skillkit/commands/validate-plan.md +6 -0
- package/skills/skillkit/commands/verify.md +6 -0
- package/skills/skillkit/knowledge/INDEX.md +352 -0
- package/skills/skillkit/knowledge/application/09-case-studies.md +257 -0
- package/skills/skillkit/knowledge/application/10-technical-architecture.md +324 -0
- package/skills/skillkit/knowledge/application/11-adoption-strategy.md +267 -0
- package/skills/skillkit/knowledge/application/12-testing-and-validation.md +276 -0
- package/skills/skillkit/knowledge/application/13-competitive-landscape.md +198 -0
- package/skills/skillkit/knowledge/foundation/01-why-skills-exist.md +246 -0
- package/skills/skillkit/knowledge/foundation/02-skills-vs-subagents-comparison.md +312 -0
- package/skills/skillkit/knowledge/foundation/03-skills-vs-subagents-decision-tree.md +346 -0
- package/skills/skillkit/knowledge/foundation/04-hybrid-patterns.md +308 -0
- package/skills/skillkit/knowledge/foundation/05-token-economics.md +275 -0
- package/skills/skillkit/knowledge/foundation/06-platform-constraints.md +237 -0
- package/skills/skillkit/knowledge/foundation/07-security-concerns.md +322 -0
- package/skills/skillkit/knowledge/foundation/08-when-not-to-use-skills.md +270 -0
- package/skills/skillkit/knowledge/plugin-guide.md +614 -0
- package/skills/skillkit/knowledge/tools/14-validation-tools-guide.md +150 -0
- package/skills/skillkit/knowledge/tools/15-cost-tools-guide.md +157 -0
- package/skills/skillkit/knowledge/tools/16-security-tools-guide.md +122 -0
- package/skills/skillkit/knowledge/tools/17-pattern-tools-guide.md +161 -0
- package/skills/skillkit/knowledge/tools/18-decision-helper-guide.md +243 -0
- package/skills/skillkit/knowledge/tools/19-test-generator-guide.md +275 -0
- package/skills/skillkit/knowledge/tools/20-split-skill-guide.md +149 -0
- package/skills/skillkit/knowledge/tools/21-quality-scorer-guide.md +226 -0
- package/skills/skillkit/knowledge/tools/22-migration-helper-guide.md +356 -0
- package/skills/skillkit/knowledge/tools/23-subagent-creation-guide.md +448 -0
- package/skills/skillkit/knowledge/tools/24-behavioral-testing-guide.md +122 -0
- package/skills/skillkit/references/proposal-generation.md +982 -0
- package/skills/skillkit/references/rationalization-catalog.md +75 -0
- package/skills/skillkit/references/research-methodology.md +661 -0
- package/skills/skillkit/references/section-2-full-creation-workflow.md +452 -0
- package/skills/skillkit/references/section-3-validation-workflow-existing-skill.md +63 -0
- package/skills/skillkit/references/section-4-decision-workflow-skills-vs-subagents.md +64 -0
- package/skills/skillkit/references/section-5-migration-workflow-doc-to-skill.md +58 -0
- package/skills/skillkit/references/section-6-subagent-creation-workflow.md +499 -0
- package/skills/skillkit/references/section-7-knowledge-reference-map.md +72 -0
- package/skills/skillkit/scripts/decision_helper.py +799 -0
- package/skills/skillkit/scripts/init_skill.py +400 -0
- package/skills/skillkit/scripts/init_subagent.py +231 -0
- package/skills/skillkit/scripts/migration_helper.py +669 -0
- package/skills/skillkit/scripts/package_skill.py +211 -0
- package/skills/skillkit/scripts/pattern_detector.py +381 -0
- package/skills/skillkit/scripts/pattern_detector_new.py +382 -0
- package/skills/skillkit/scripts/pressure_tester.py +157 -0
- package/skills/skillkit/scripts/quality_scorer.py +999 -0
- package/skills/skillkit/scripts/quick_validate.py +100 -0
- package/skills/skillkit/scripts/security_scanner.py +474 -0
- package/skills/skillkit/scripts/split_skill.py +540 -0
- package/skills/skillkit/scripts/test_generator.py +695 -0
- package/skills/skillkit/scripts/token_estimator.py +493 -0
- package/skills/skillkit/scripts/utils/__init__.py +49 -0
- package/skills/skillkit/scripts/utils/budget_tracker.py +388 -0
- package/skills/skillkit/scripts/utils/output_formatter.py +263 -0
- package/skills/skillkit/scripts/utils/reference_validator.py +401 -0
- package/skills/skillkit/scripts/validate_skill.py +594 -0
- package/skills/skillkit/tests/test_behavioral.py +39 -0
- package/skills/skillkit/tests/test_scenarios.md +83 -0
- package/skills/skillkit/tests/test_skill.py +136 -0
- package/skills/social-media-seo/SKILL.md +278 -0
- package/skills/social-media-seo/databases/caption-styles.csv +31 -0
- package/skills/social-media-seo/databases/engagement-tactics.csv +16 -0
- package/skills/social-media-seo/databases/hashtag-strategies.csv +21 -0
- package/skills/social-media-seo/databases/hook-formulas.csv +26 -0
- package/skills/social-media-seo/databases/keyword-clusters.csv +11 -0
- package/skills/social-media-seo/databases/thread-structures.csv +26 -0
- package/skills/social-media-seo/databases/viral-patterns.csv +21 -0
- package/skills/social-media-seo/references/analytics-guide.md +321 -0
- package/skills/social-media-seo/references/instagram-seo.md +235 -0
- package/skills/social-media-seo/references/threads-seo.md +305 -0
- package/skills/social-media-seo/references/x-twitter-seo.md +337 -0
- package/skills/social-media-seo/scripts/query_database.py +191 -0
- package/skills/storyteller/SKILL.md +241 -0
- package/skills/storyteller/references/transformation-methodology.md +293 -0
- package/skills/storyteller/references/visual-vocabulary.md +177 -0
- package/skills/thread-pro/SKILL.md +162 -0
- package/skills/thread-pro/anti-ai-patterns.md +120 -0
- package/skills/thread-pro/hook-formulas.md +138 -0
- package/skills/thread-pro/references/anti-ai-patterns.md +120 -0
- package/skills/thread-pro/references/hook-formulas.md +138 -0
- package/skills/thread-pro/references/thread-structures.md +240 -0
- package/skills/thread-pro/references/voice-injection.md +130 -0
- package/skills/thread-pro/thread-structures.md +240 -0
- package/skills/thread-pro/voice-injection.md +130 -0
- package/skills/tinkering/SKILL.md +251 -0
- package/skills/tinkering/references/graduation-checklist.md +100 -0
- package/skills/validate-plan/.skillkit-mode +1 -0
- package/skills/validate-plan/SKILL.md +406 -0
- package/skills/validate-plan/references/dry-principles.md +251 -0
- package/skills/validate-plan/references/gap-analysis-guide.md +320 -0
- package/skills/validate-plan/references/tdd-patterns.md +413 -0
- package/skills/validate-plan/references/yagni-checklist.md +330 -0
- package/skills/verify-before-ship/.skillkit-mode +1 -0
- package/skills/verify-before-ship/SKILL.md +116 -0
- package/skills/verify-before-ship/references/anti-rationalization.md +212 -0
- package/skills/verify-before-ship/references/verification-gates.md +305 -0
- package/skills-manifest.json +217 -0
- package/src/banner.js +10 -0
- package/src/cli.js +30 -0
- package/src/install.js +53 -0
- package/src/install.test.js +40 -0
- package/src/picker.js +74 -0
- package/src/picker.test.js +21 -0
- package/src/scope.js +57 -0
- package/src/scope.test.js +19 -0
- package/src/update.js +34 -0
- 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
|
+
})
|