@agents-inc/cli 0.48.0 → 0.60.1
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/CHANGELOG.md +181 -5
- package/README.md +1 -2
- package/dist/{chunk-2DNDAXF6.js → chunk-52M2XF3W.js} +57 -27
- package/dist/chunk-52M2XF3W.js.map +1 -0
- package/dist/{chunk-WSGKCBY5.js → chunk-52XO4ULK.js} +6 -9
- package/dist/chunk-52XO4ULK.js.map +1 -0
- package/dist/{chunk-AMNCCZSG.js → chunk-6G3KZSO4.js} +82 -63
- package/dist/chunk-6G3KZSO4.js.map +1 -0
- package/dist/{chunk-LESHL6SM.js → chunk-6OWHQ7HM.js} +21 -13
- package/dist/chunk-6OWHQ7HM.js.map +1 -0
- package/dist/{chunk-X3SZIBVW.js → chunk-7FMEMXJ4.js} +71 -71
- package/dist/chunk-7FMEMXJ4.js.map +1 -0
- package/dist/{chunk-I52THVF6.js → chunk-AJJJE7F7.js} +2 -2
- package/dist/{chunk-ZML3OCYA.js → chunk-AX3SZZWA.js} +2 -2
- package/dist/{chunk-NJVJ7VO5.js → chunk-BFD5NZQ4.js} +5 -4
- package/dist/chunk-BFD5NZQ4.js.map +1 -0
- package/dist/{chunk-GSPPOXMG.js → chunk-BKJHAJQW.js} +2 -2
- package/dist/{chunk-GSPPOXMG.js.map → chunk-BKJHAJQW.js.map} +1 -1
- package/dist/{chunk-FPTUCWBY.js → chunk-BMJZBLP7.js} +46 -30
- package/dist/chunk-BMJZBLP7.js.map +1 -0
- package/dist/chunk-BNQ5O6LE.js +74 -0
- package/dist/chunk-BNQ5O6LE.js.map +1 -0
- package/dist/{chunk-W62XVWXB.js → chunk-C577AJE7.js} +3 -3
- package/dist/chunk-CIG7IKX3.js +118 -0
- package/dist/chunk-CIG7IKX3.js.map +1 -0
- package/dist/chunk-EC3UJRKZ.js +1534 -0
- package/dist/chunk-EC3UJRKZ.js.map +1 -0
- package/dist/{chunk-IS7GP6XC.js → chunk-EMIUPGPL.js} +57 -52
- package/dist/chunk-EMIUPGPL.js.map +1 -0
- package/dist/chunk-G6WHCALR.js +593 -0
- package/dist/chunk-G6WHCALR.js.map +1 -0
- package/dist/{chunk-OTTITQ7C.js → chunk-H7WJK7NJ.js} +48 -95
- package/dist/chunk-H7WJK7NJ.js.map +1 -0
- package/dist/chunk-HGTC76BX.js +16 -0
- package/dist/chunk-HGTC76BX.js.map +1 -0
- package/dist/{chunk-G5OZQ376.js → chunk-K6OLORQL.js} +6 -6
- package/dist/{chunk-OHDEJEYB.js → chunk-KIWFEBKH.js} +41 -11
- package/dist/chunk-KIWFEBKH.js.map +1 -0
- package/dist/{chunk-YMUWTPOM.js → chunk-LWXRUR6B.js} +92 -100
- package/dist/chunk-LWXRUR6B.js.map +1 -0
- package/dist/{chunk-U2AEK4ZL.js → chunk-MGNYPVOJ.js} +2 -2
- package/dist/chunk-MKCHLXMY.js +40 -0
- package/dist/chunk-MKCHLXMY.js.map +1 -0
- package/dist/{chunk-37QYD33C.js → chunk-MMFQNJPE.js} +2 -2
- package/dist/{chunk-DG2U2WY3.js → chunk-MR6OBL3B.js} +3 -11
- package/dist/{chunk-DG2U2WY3.js.map → chunk-MR6OBL3B.js.map} +1 -1
- package/dist/{chunk-7IAKVZL5.js → chunk-O6BA7Q2B.js} +28 -59
- package/dist/chunk-O6BA7Q2B.js.map +1 -0
- package/dist/chunk-OCEFD7V6.js +201 -0
- package/dist/chunk-OCEFD7V6.js.map +1 -0
- package/dist/{chunk-YZTWZVGX.js → chunk-PUT7X3GA.js} +1 -1
- package/dist/chunk-PUT7X3GA.js.map +1 -0
- package/dist/chunk-RO6LX3UV.js +342 -0
- package/dist/chunk-RO6LX3UV.js.map +1 -0
- package/dist/{chunk-34BP5BC4.js → chunk-SDKCQXWE.js} +2 -2
- package/dist/{chunk-VBAAATPU.js → chunk-SEJF7CGJ.js} +41 -28
- package/dist/chunk-SEJF7CGJ.js.map +1 -0
- package/dist/{chunk-5O6GKXAN.js → chunk-SZRK3VOR.js} +24 -14
- package/dist/chunk-SZRK3VOR.js.map +1 -0
- package/dist/{chunk-5MN5S3DV.js → chunk-TC3NHO34.js} +22 -17
- package/dist/chunk-TC3NHO34.js.map +1 -0
- package/dist/{chunk-SPVSWDFM.js → chunk-TGLRDEEL.js} +8 -14
- package/dist/chunk-TGLRDEEL.js.map +1 -0
- package/dist/{chunk-P2SFRDWI.js → chunk-TZXYBG3R.js} +3634 -2875
- package/dist/chunk-TZXYBG3R.js.map +1 -0
- package/dist/{chunk-2BVZOYJP.js → chunk-VR3CDXDT.js} +2 -6
- package/dist/chunk-VR3CDXDT.js.map +1 -0
- package/dist/{chunk-KPJJOLAQ.js → chunk-WF6RM73R.js} +272 -40
- package/dist/chunk-WF6RM73R.js.map +1 -0
- package/dist/chunk-WYVDNGJB.js +31 -0
- package/dist/chunk-WYVDNGJB.js.map +1 -0
- package/dist/{chunk-F7KTUFGU.js → chunk-X5EG4EFP.js} +3 -2
- package/dist/chunk-X5EG4EFP.js.map +1 -0
- package/dist/{chunk-FHKNG3UA.js → chunk-XUDTFI4M.js} +2 -2
- package/dist/{chunk-AXV7NFFJ.js → chunk-YHCYKUA3.js} +14 -10
- package/dist/chunk-YHCYKUA3.js.map +1 -0
- package/dist/commands/build/marketplace.js +4 -4
- package/dist/commands/build/plugins.js +9 -7
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/build/stack.js +13 -10
- package/dist/commands/build/stack.js.map +1 -1
- package/dist/commands/compile.js +45 -72
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/config/index.js +7 -5
- package/dist/commands/config/index.js.map +1 -1
- package/dist/commands/config/path.js +8 -6
- package/dist/commands/config/path.js.map +1 -1
- package/dist/commands/config/show.js +7 -5
- package/dist/commands/diff.js +9 -7
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.js +20 -16
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +196 -94
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +20 -41
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/import/skill.js +10 -18
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/info.js +21 -20
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.js +41 -435
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.js +8 -6
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/agent.js +28 -15
- package/dist/commands/new/agent.js.map +1 -1
- package/dist/commands/new/marketplace.js +67 -31
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/new/skill.js +17 -208
- package/dist/commands/new/skill.js.map +1 -1
- package/dist/commands/outdated.js +16 -10
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/search.js +45 -35
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +93 -123
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +11 -9
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.js +42 -267
- package/dist/commands/validate.js.map +1 -1
- package/dist/components/common/confirm.test.js +4 -4
- package/dist/components/skill-search/skill-search.js +3 -3
- package/dist/components/wizard/category-grid.js +3 -2
- package/dist/components/wizard/category-grid.test.js +113 -59
- package/dist/components/wizard/category-grid.test.js.map +1 -1
- package/dist/components/wizard/checkbox-grid.js +5 -3
- package/dist/components/wizard/checkbox-grid.test.js +6 -5
- package/dist/components/wizard/checkbox-grid.test.js.map +1 -1
- package/dist/components/wizard/domain-selection.js +12 -9
- package/dist/components/wizard/help-modal.js +2 -2
- package/dist/components/wizard/menu-item.js +1 -1
- package/dist/components/wizard/search-modal.js +2 -2
- package/dist/components/wizard/search-modal.test.js +3 -3
- package/dist/components/wizard/search-modal.test.js.map +1 -1
- package/dist/components/wizard/section-progress.js +2 -2
- package/dist/components/wizard/section-progress.test.js +4 -4
- package/dist/components/wizard/section-progress.test.js.map +1 -1
- package/dist/components/wizard/selection-card.js +2 -2
- package/dist/components/wizard/source-grid.js +4 -3
- package/dist/components/wizard/source-grid.test.js +5 -4
- package/dist/components/wizard/source-grid.test.js.map +1 -1
- package/dist/components/wizard/stack-selection.js +9 -8
- package/dist/components/wizard/step-agents.js +11 -8
- package/dist/components/wizard/step-agents.test.js +20 -18
- package/dist/components/wizard/step-agents.test.js.map +1 -1
- package/dist/components/wizard/step-build.js +11 -8
- package/dist/components/wizard/step-build.test.js +18 -36
- package/dist/components/wizard/step-build.test.js.map +1 -1
- package/dist/components/wizard/step-confirm.js +4 -4
- package/dist/components/wizard/step-confirm.test.js +83 -23
- package/dist/components/wizard/step-confirm.test.js.map +1 -1
- package/dist/components/wizard/step-refine.js +2 -2
- package/dist/components/wizard/step-refine.test.js +3 -3
- package/dist/components/wizard/step-settings.js +9 -5
- package/dist/components/wizard/step-settings.test.js +13 -9
- package/dist/components/wizard/step-settings.test.js.map +1 -1
- package/dist/components/wizard/step-sources.js +13 -10
- package/dist/components/wizard/step-sources.test.js +19 -16
- package/dist/components/wizard/step-sources.test.js.map +1 -1
- package/dist/components/wizard/step-stack.js +16 -12
- package/dist/components/wizard/step-stack.test.js +18 -14
- package/dist/components/wizard/step-stack.test.js.map +1 -1
- package/dist/components/wizard/view-title.js +2 -2
- package/dist/components/wizard/wizard-layout.js +10 -8
- package/dist/components/wizard/wizard-tabs.js +2 -2
- package/dist/components/wizard/wizard-tabs.test.js +2 -2
- package/dist/components/wizard/wizard.js +29 -25
- package/dist/config-exports.js +20 -0
- package/dist/config-exports.js.map +1 -0
- package/dist/hooks/init.js +56 -3
- package/dist/hooks/init.js.map +1 -1
- package/dist/loader-2O32KKAQ.js +19 -0
- package/dist/source-loader-A6B3NDI4.js +16 -0
- package/dist/source-loader-A6B3NDI4.js.map +1 -0
- package/dist/source-manager-Q7IQSGIX.js +18 -0
- package/dist/source-manager-Q7IQSGIX.js.map +1 -0
- package/dist/src/agents/meta/agent-summoner/critical-reminders.md +1 -1
- package/dist/src/agents/meta/agent-summoner/critical-requirements.md +1 -1
- package/dist/src/agents/meta/agent-summoner/examples.md +2 -2
- package/dist/src/agents/meta/agent-summoner/output-format.md +1 -1
- package/dist/src/agents/meta/agent-summoner/workflow.md +8 -10
- package/{src/agents/meta/documentor/agent.yaml → dist/src/agents/meta/documentor/metadata.yaml} +1 -0
- package/dist/src/agents/meta/skill-summoner/critical-reminders.md +2 -2
- package/dist/src/agents/meta/skill-summoner/critical-requirements.md +1 -1
- package/dist/src/agents/meta/skill-summoner/intro.md +1 -1
- package/dist/src/agents/meta/skill-summoner/output-format.md +3 -3
- package/dist/src/agents/meta/skill-summoner/workflow.md +8 -8
- package/dist/stores/wizard-store.js +6 -5
- package/dist/stores/wizard-store.test.js +367 -75
- package/dist/stores/wizard-store.test.js.map +1 -1
- package/package.json +5 -1
- package/src/agents/meta/agent-summoner/critical-reminders.md +1 -1
- package/src/agents/meta/agent-summoner/critical-requirements.md +1 -1
- package/src/agents/meta/agent-summoner/examples.md +2 -2
- package/src/agents/meta/agent-summoner/output-format.md +1 -1
- package/src/agents/meta/agent-summoner/workflow.md +8 -10
- package/{dist/src/agents/meta/documentor/agent.yaml → src/agents/meta/documentor/metadata.yaml} +1 -0
- package/src/agents/meta/skill-summoner/critical-reminders.md +2 -2
- package/src/agents/meta/skill-summoner/critical-requirements.md +1 -1
- package/src/agents/meta/skill-summoner/intro.md +1 -1
- package/src/agents/meta/skill-summoner/output-format.md +3 -3
- package/src/agents/meta/skill-summoner/workflow.md +8 -8
- package/src/schemas/agent.schema.json +1 -1
- package/src/schemas/metadata.schema.json +6 -0
- package/src/schemas/project-config.schema.json +0 -3
- package/src/schemas/stacks.schema.json +1 -1
- package/config/skill-categories.yaml +0 -344
- package/config/skill-rules.yaml +0 -740
- package/config/stacks.yaml +0 -1865
- package/dist/chunk-2BVZOYJP.js.map +0 -1
- package/dist/chunk-2DNDAXF6.js.map +0 -1
- package/dist/chunk-5MN5S3DV.js.map +0 -1
- package/dist/chunk-5O6GKXAN.js.map +0 -1
- package/dist/chunk-7IAKVZL5.js.map +0 -1
- package/dist/chunk-AMNCCZSG.js.map +0 -1
- package/dist/chunk-AXV7NFFJ.js.map +0 -1
- package/dist/chunk-AXZNJ5PN.js +0 -99
- package/dist/chunk-AXZNJ5PN.js.map +0 -1
- package/dist/chunk-C7DLY64D.js +0 -115
- package/dist/chunk-C7DLY64D.js.map +0 -1
- package/dist/chunk-F7KTUFGU.js.map +0 -1
- package/dist/chunk-FPTUCWBY.js.map +0 -1
- package/dist/chunk-IS7GP6XC.js.map +0 -1
- package/dist/chunk-KPJJOLAQ.js.map +0 -1
- package/dist/chunk-LESHL6SM.js.map +0 -1
- package/dist/chunk-NJVJ7VO5.js.map +0 -1
- package/dist/chunk-OHDEJEYB.js.map +0 -1
- package/dist/chunk-OTTITQ7C.js.map +0 -1
- package/dist/chunk-P2SFRDWI.js.map +0 -1
- package/dist/chunk-PY2XZUBF.js +0 -29
- package/dist/chunk-PY2XZUBF.js.map +0 -1
- package/dist/chunk-SPVSWDFM.js.map +0 -1
- package/dist/chunk-VBAAATPU.js.map +0 -1
- package/dist/chunk-WSGKCBY5.js.map +0 -1
- package/dist/chunk-X3SZIBVW.js.map +0 -1
- package/dist/chunk-YDASDMTH.js +0 -183
- package/dist/chunk-YDASDMTH.js.map +0 -1
- package/dist/chunk-YMUWTPOM.js.map +0 -1
- package/dist/chunk-YZTWZVGX.js.map +0 -1
- package/dist/commands/config/get.js +0 -61
- package/dist/commands/config/get.js.map +0 -1
- package/dist/commands/config/set-project.js +0 -61
- package/dist/commands/config/set-project.js.map +0 -1
- package/dist/commands/config/unset-project.js +0 -57
- package/dist/commands/config/unset-project.js.map +0 -1
- package/dist/config/skill-categories.yaml +0 -344
- package/dist/config/skill-rules.yaml +0 -740
- package/dist/config/stacks.yaml +0 -1865
- package/dist/source-manager-Y7R6WPOW.js +0 -16
- package/dist/src/agents/migration/cli-migrator/agent.yaml +0 -12
- package/dist/src/agents/migration/cli-migrator/anti-patterns.md +0 -158
- package/dist/src/agents/migration/cli-migrator/conversion-mappings.md +0 -63
- package/dist/src/agents/migration/cli-migrator/critical-reminders.md +0 -17
- package/dist/src/agents/migration/cli-migrator/critical-requirements.md +0 -13
- package/dist/src/agents/migration/cli-migrator/intro.md +0 -15
- package/dist/src/agents/migration/cli-migrator/output-format.md +0 -164
- package/dist/src/agents/migration/cli-migrator/workflow.md +0 -230
- package/src/agents/migration/cli-migrator/agent.yaml +0 -12
- package/src/agents/migration/cli-migrator/anti-patterns.md +0 -158
- package/src/agents/migration/cli-migrator/conversion-mappings.md +0 -63
- package/src/agents/migration/cli-migrator/critical-reminders.md +0 -17
- package/src/agents/migration/cli-migrator/critical-requirements.md +0 -13
- package/src/agents/migration/cli-migrator/intro.md +0 -15
- package/src/agents/migration/cli-migrator/output-format.md +0 -164
- package/src/agents/migration/cli-migrator/workflow.md +0 -230
- /package/dist/{chunk-I52THVF6.js.map → chunk-AJJJE7F7.js.map} +0 -0
- /package/dist/{chunk-ZML3OCYA.js.map → chunk-AX3SZZWA.js.map} +0 -0
- /package/dist/{chunk-W62XVWXB.js.map → chunk-C577AJE7.js.map} +0 -0
- /package/dist/{chunk-G5OZQ376.js.map → chunk-K6OLORQL.js.map} +0 -0
- /package/dist/{chunk-U2AEK4ZL.js.map → chunk-MGNYPVOJ.js.map} +0 -0
- /package/dist/{chunk-37QYD33C.js.map → chunk-MMFQNJPE.js.map} +0 -0
- /package/dist/{chunk-34BP5BC4.js.map → chunk-SDKCQXWE.js.map} +0 -0
- /package/dist/{chunk-FHKNG3UA.js.map → chunk-XUDTFI4M.js.map} +0 -0
- /package/dist/{source-manager-Y7R6WPOW.js.map → loader-2O32KKAQ.js.map} +0 -0
- /package/dist/src/agents/developer/api-developer/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/developer/cli-developer/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/developer/web-architecture/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/developer/web-developer/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/meta/agent-summoner/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/meta/skill-summoner/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/pattern/pattern-scout/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/pattern/web-pattern-critique/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/planning/web-pm/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/researcher/api-researcher/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/researcher/web-researcher/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/reviewer/api-reviewer/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/reviewer/cli-reviewer/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/reviewer/web-reviewer/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/tester/cli-tester/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/tester/web-tester/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/developer/api-developer/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/developer/cli-developer/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/developer/web-architecture/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/developer/web-developer/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/meta/agent-summoner/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/meta/skill-summoner/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/pattern/pattern-scout/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/pattern/web-pattern-critique/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/planning/web-pm/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/researcher/api-researcher/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/researcher/web-researcher/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/reviewer/api-reviewer/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/reviewer/cli-reviewer/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/reviewer/web-reviewer/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/tester/cli-tester/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/tester/web-tester/{agent.yaml → metadata.yaml} +0 -0
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
BaseCommand,
|
|
4
|
-
EXIT_CODES
|
|
5
|
-
} from "../chunk-2BVZOYJP.js";
|
|
6
2
|
import {
|
|
7
3
|
compareLocalSkillsWithSource,
|
|
4
|
+
detectInstallation,
|
|
8
5
|
loadSkillsMatrixFromSource
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-TZXYBG3R.js";
|
|
7
|
+
import "../chunk-OCEFD7V6.js";
|
|
8
|
+
import {
|
|
9
|
+
typedEntries
|
|
10
|
+
} from "../chunk-T4EXUIBY.js";
|
|
11
|
+
import {
|
|
12
|
+
BaseCommand,
|
|
13
|
+
EXIT_CODES
|
|
14
|
+
} from "../chunk-VR3CDXDT.js";
|
|
11
15
|
import {
|
|
12
16
|
fileExists,
|
|
13
17
|
getErrorMessage
|
|
14
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-LWXRUR6B.js";
|
|
15
19
|
import {
|
|
16
20
|
CLI_BIN_NAME,
|
|
17
21
|
LOCAL_SKILLS_PATH
|
|
18
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-6OWHQ7HM.js";
|
|
23
|
+
import "../chunk-EC3UJRKZ.js";
|
|
19
24
|
import {
|
|
20
25
|
init_esm_shims
|
|
21
26
|
} from "../chunk-DHET7RCE.js";
|
|
@@ -66,7 +71,8 @@ var Outdated = class _Outdated extends BaseCommand {
|
|
|
66
71
|
};
|
|
67
72
|
async run() {
|
|
68
73
|
const { flags } = await this.parse(_Outdated);
|
|
69
|
-
const
|
|
74
|
+
const installation = await detectInstallation();
|
|
75
|
+
const projectDir = installation?.projectDir ?? process.cwd();
|
|
70
76
|
try {
|
|
71
77
|
const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);
|
|
72
78
|
if (!await fileExists(localSkillsPath)) {
|
|
@@ -95,7 +101,7 @@ var Outdated = class _Outdated extends BaseCommand {
|
|
|
95
101
|
this.log(`Loaded from ${isLocal ? "local" : "remote"}: ${sourcePath}`);
|
|
96
102
|
}
|
|
97
103
|
const sourceSkills = {};
|
|
98
|
-
for (const [skillId, skill] of
|
|
104
|
+
for (const [skillId, skill] of typedEntries(matrix.skills)) {
|
|
99
105
|
if (!skill) continue;
|
|
100
106
|
if (!skill.local) {
|
|
101
107
|
sourceSkills[skillId] = { path: skill.path };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/outdated.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport path from \"path\";\nimport { countBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { loadSkillsMatrixFromSource } from \"../lib/loading/index.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { compareLocalSkillsWithSource, type SkillComparisonResult } from \"../lib/skills/index.js\";\nimport { fileExists } from \"../utils/fs.js\";\nimport { CLI_BIN_NAME, LOCAL_SKILLS_PATH } from \"../consts.js\";\n\ntype ComparisonSummary = {\n outdated: number;\n current: number;\n localOnly: number;\n};\n\nfunction calculateSummary(results: SkillComparisonResult[]): ComparisonSummary {\n const counts = countBy(results, (r) => r.status);\n return {\n outdated: counts[\"outdated\"] ?? 0,\n current: counts[\"current\"] ?? 0,\n localOnly: counts[\"local-only\"] ?? 0,\n };\n}\n\nfunction formatHash(hash: string | null, isLocal: boolean): string {\n if (hash === null) {\n return isLocal ? \"(local)\" : \"-\";\n }\n return hash;\n}\n\nexport default class Outdated extends BaseCommand {\n static summary = \"Check which local skills are out of date compared to source\";\n static description =\n \"Compare local skills against their source repository to identify outdated skills that need updating\";\n\n static examples = [\n {\n description: \"Check for outdated skills\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Output results as JSON\",\n command: \"<%= config.bin %> <%= command.id %> --json\",\n },\n {\n description: \"Check against a custom source\",\n command: \"<%= config.bin %> <%= command.id %> --source github:org/marketplace\",\n },\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n json: Flags.boolean({\n description: \"Output results as JSON\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Outdated);\n const projectDir = process.cwd();\n\n try {\n const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);\n if (!(await fileExists(localSkillsPath))) {\n if (flags.json) {\n this.log(\n JSON.stringify({\n skills: [],\n summary: { outdated: 0, current: 0, localOnly: 0 },\n }),\n );\n } else {\n this.warn(\n `No local skills found. Run \\`${CLI_BIN_NAME} init\\` or \\`${CLI_BIN_NAME} edit\\` first.`,\n );\n }\n return;\n }\n\n if (!flags.json) {\n this.log(\"Loading skills...\");\n }\n\n const { matrix, sourcePath, isLocal } = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n projectDir,\n });\n\n if (!flags.json) {\n this.log(`Loaded from ${isLocal ? \"local\" : \"remote\"}: ${sourcePath}`);\n }\n\n const sourceSkills: Record<string, { path: string }> = {};\n for (const [skillId, skill] of
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/outdated.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport path from \"path\";\nimport { countBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { loadSkillsMatrixFromSource } from \"../lib/loading/index.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { detectInstallation } from \"../lib/installation/index.js\";\nimport { compareLocalSkillsWithSource, type SkillComparisonResult } from \"../lib/skills/index.js\";\nimport { fileExists } from \"../utils/fs.js\";\nimport { CLI_BIN_NAME, LOCAL_SKILLS_PATH } from \"../consts.js\";\nimport { typedEntries } from \"../utils/typed-object.js\";\n\ntype ComparisonSummary = {\n outdated: number;\n current: number;\n localOnly: number;\n};\n\nfunction calculateSummary(results: SkillComparisonResult[]): ComparisonSummary {\n const counts = countBy(results, (r) => r.status);\n return {\n outdated: counts[\"outdated\"] ?? 0,\n current: counts[\"current\"] ?? 0,\n localOnly: counts[\"local-only\"] ?? 0,\n };\n}\n\nfunction formatHash(hash: string | null, isLocal: boolean): string {\n if (hash === null) {\n return isLocal ? \"(local)\" : \"-\";\n }\n return hash;\n}\n\nexport default class Outdated extends BaseCommand {\n static summary = \"Check which local skills are out of date compared to source\";\n static description =\n \"Compare local skills against their source repository to identify outdated skills that need updating\";\n\n static examples = [\n {\n description: \"Check for outdated skills\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Output results as JSON\",\n command: \"<%= config.bin %> <%= command.id %> --json\",\n },\n {\n description: \"Check against a custom source\",\n command: \"<%= config.bin %> <%= command.id %> --source github:org/marketplace\",\n },\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n json: Flags.boolean({\n description: \"Output results as JSON\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Outdated);\n const installation = await detectInstallation();\n const projectDir = installation?.projectDir ?? process.cwd();\n\n try {\n const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);\n if (!(await fileExists(localSkillsPath))) {\n if (flags.json) {\n this.log(\n JSON.stringify({\n skills: [],\n summary: { outdated: 0, current: 0, localOnly: 0 },\n }),\n );\n } else {\n this.warn(\n `No local skills found. Run \\`${CLI_BIN_NAME} init\\` or \\`${CLI_BIN_NAME} edit\\` first.`,\n );\n }\n return;\n }\n\n if (!flags.json) {\n this.log(\"Loading skills...\");\n }\n\n const { matrix, sourcePath, isLocal } = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n projectDir,\n });\n\n if (!flags.json) {\n this.log(`Loaded from ${isLocal ? \"local\" : \"remote\"}: ${sourcePath}`);\n }\n\n const sourceSkills: Record<string, { path: string }> = {};\n for (const [skillId, skill] of typedEntries(matrix.skills)) {\n if (!skill) continue;\n if (!skill.local) {\n sourceSkills[skillId] = { path: skill.path };\n }\n }\n\n const results = await compareLocalSkillsWithSource(projectDir, sourcePath, sourceSkills);\n const summary = calculateSummary(results);\n\n if (flags.json) {\n this.log(\n JSON.stringify(\n {\n skills: results.map((r) => ({\n id: r.id,\n localHash: r.localHash,\n sourceHash: r.sourceHash,\n status: r.status,\n })),\n summary: {\n outdated: summary.outdated,\n current: summary.current,\n localOnly: summary.localOnly,\n },\n },\n null,\n 2,\n ),\n );\n } else {\n this.log(\"\");\n if (results.length === 0) {\n this.logInfo(\"No local skills found to compare.\");\n } else {\n printTable({\n data: results.map((result) => ({\n skill: result.id,\n localHash: formatHash(result.localHash, true),\n sourceHash: formatHash(result.sourceHash, false),\n status: result.status,\n })),\n columns: [\n { key: \"skill\", name: \"Skill\" },\n { key: \"localHash\", name: \"Local Hash\" },\n { key: \"sourceHash\", name: \"Source Hash\" },\n { key: \"status\", name: \"Status\" },\n ],\n headerOptions: { bold: true },\n });\n\n this.log(\"\");\n\n const parts: string[] = [];\n if (summary.outdated > 0) {\n parts.push(`${summary.outdated} outdated`);\n }\n if (summary.current > 0) {\n parts.push(`${summary.current} current`);\n }\n if (summary.localOnly > 0) {\n parts.push(`${summary.localOnly} local-only`);\n }\n this.log(`Summary: ${parts.join(\", \")}`);\n }\n this.log(\"\");\n }\n\n if (summary.outdated > 0) {\n this.error(\"Some skills are outdated\", { exit: EXIT_CODES.ERROR });\n }\n } catch (error) {\n const message = getErrorMessage(error);\n\n if (flags.json) {\n this.error(JSON.stringify({ error: message }), {\n exit: EXIT_CODES.ERROR,\n });\n } else {\n this.error(`Error: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/commands/search.js
CHANGED
|
@@ -1,35 +1,40 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SkillSearch
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-BFD5NZQ4.js";
|
|
5
|
+
import "../chunk-XUDTFI4M.js";
|
|
6
6
|
import "../chunk-U3IGFMCY.js";
|
|
7
7
|
import {
|
|
8
8
|
INFO_MESSAGES,
|
|
9
9
|
STATUS_MESSAGES,
|
|
10
10
|
SUCCESS_MESSAGES
|
|
11
|
-
} from "../chunk-
|
|
12
|
-
import {
|
|
13
|
-
BaseCommand,
|
|
14
|
-
EXIT_CODES
|
|
15
|
-
} from "../chunk-2BVZOYJP.js";
|
|
11
|
+
} from "../chunk-MR6OBL3B.js";
|
|
16
12
|
import {
|
|
17
13
|
fetchFromSource,
|
|
18
14
|
loadSkillsMatrixFromSource,
|
|
19
15
|
resolveAllSources
|
|
20
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-TZXYBG3R.js";
|
|
17
|
+
import {
|
|
18
|
+
parseFrontmatter
|
|
19
|
+
} from "../chunk-OCEFD7V6.js";
|
|
21
20
|
import "../chunk-T4EXUIBY.js";
|
|
21
|
+
import {
|
|
22
|
+
BaseCommand,
|
|
23
|
+
EXIT_CODES
|
|
24
|
+
} from "../chunk-VR3CDXDT.js";
|
|
22
25
|
import {
|
|
23
26
|
copy,
|
|
24
27
|
ensureDir,
|
|
25
28
|
fileExists,
|
|
26
|
-
listDirectories
|
|
27
|
-
|
|
29
|
+
listDirectories,
|
|
30
|
+
readFile
|
|
31
|
+
} from "../chunk-LWXRUR6B.js";
|
|
28
32
|
import {
|
|
29
33
|
DEFAULT_SKILLS_SUBDIR,
|
|
30
34
|
LOCAL_SKILLS_PATH,
|
|
31
35
|
STANDARD_FILES
|
|
32
|
-
} from "../chunk-
|
|
36
|
+
} from "../chunk-6OWHQ7HM.js";
|
|
37
|
+
import "../chunk-EC3UJRKZ.js";
|
|
33
38
|
import {
|
|
34
39
|
init_esm_shims
|
|
35
40
|
} from "../chunk-DHET7RCE.js";
|
|
@@ -55,7 +60,8 @@ function truncate(str, maxLength) {
|
|
|
55
60
|
function matchesQuery(skill, query) {
|
|
56
61
|
const lowerQuery = query.toLowerCase();
|
|
57
62
|
if (skill.id.toLowerCase().includes(lowerQuery)) return true;
|
|
58
|
-
if (skill.displayName
|
|
63
|
+
if (skill.displayName.toLowerCase().includes(lowerQuery)) return true;
|
|
64
|
+
if (skill.slug?.toLowerCase().includes(lowerQuery)) return true;
|
|
59
65
|
if (skill.description.toLowerCase().includes(lowerQuery)) return true;
|
|
60
66
|
if (skill.category.toLowerCase().includes(lowerQuery)) return true;
|
|
61
67
|
return skill.tags.some((tag) => tag.toLowerCase().includes(lowerQuery));
|
|
@@ -82,28 +88,32 @@ async function fetchSkillsFromSource(source, forceRefresh) {
|
|
|
82
88
|
const skills = [];
|
|
83
89
|
for (const skillDir of skillDirs) {
|
|
84
90
|
const skillMdPath = path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);
|
|
85
|
-
if (await fileExists(skillMdPath))
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
91
|
+
if (!await fileExists(skillMdPath)) continue;
|
|
92
|
+
const content = await readFile(skillMdPath);
|
|
93
|
+
const frontmatter = parseFrontmatter(content, skillMdPath);
|
|
94
|
+
if (!frontmatter) continue;
|
|
95
|
+
skills.push({
|
|
96
|
+
id: frontmatter.name,
|
|
97
|
+
description: frontmatter.description,
|
|
98
|
+
// Boundary cast: directory name used as slug for third-party source skill
|
|
99
|
+
slug: skillDir,
|
|
100
|
+
displayName: skillDir,
|
|
101
|
+
// Boundary cast: external source skills have no category metadata
|
|
102
|
+
category: "imported",
|
|
103
|
+
tags: [],
|
|
104
|
+
author: `@${source.name}`,
|
|
105
|
+
conflictsWith: [],
|
|
106
|
+
isRecommended: false,
|
|
107
|
+
requires: [],
|
|
108
|
+
alternatives: [],
|
|
109
|
+
discourages: [],
|
|
110
|
+
compatibleWith: [],
|
|
111
|
+
requiresSetup: [],
|
|
112
|
+
providesSetupFor: [],
|
|
113
|
+
sourceName: source.name,
|
|
114
|
+
sourceUrl: source.url,
|
|
115
|
+
path: path.join(skillsDir, skillDir)
|
|
116
|
+
});
|
|
107
117
|
}
|
|
108
118
|
return skills;
|
|
109
119
|
} catch {
|
|
@@ -246,7 +256,7 @@ var Search = class _Search extends BaseCommand {
|
|
|
246
256
|
if (flags.category) {
|
|
247
257
|
results = results.filter((skill) => matchesCategory(skill, flags.category));
|
|
248
258
|
}
|
|
249
|
-
results = sortBy(results, (r) => r.displayName || r.id);
|
|
259
|
+
results = sortBy(results, (r) => (r.displayName || r.id).toLowerCase());
|
|
250
260
|
this.log("");
|
|
251
261
|
if (results.length === 0) {
|
|
252
262
|
this.warn(`No skills found matching "${query}"`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/search.tsx","../../src/cli/components/skill-search/index.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport { render } from \"ink\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { SkillSearch, type SkillSearchResult } from \"../components/skill-search/index.js\";\nimport type { SourcedSkill } from \"../components/skill-search/skill-search.js\";\nimport { DEFAULT_SKILLS_SUBDIR, LOCAL_SKILLS_PATH, STANDARD_FILES } from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { resolveAllSources, type SourceEntry } from \"../lib/configuration/index.js\";\nimport { loadSkillsMatrixFromSource, fetchFromSource } from \"../lib/loading/index.js\";\nimport type { CategoryPath, ResolvedSkill, SkillId } from \"../types/index.js\";\nimport { listDirectories, fileExists, copy, ensureDir } from \"../utils/fs.js\";\nimport { SUCCESS_MESSAGES, STATUS_MESSAGES, INFO_MESSAGES } from \"../utils/messages.js\";\n\nconst MAX_DESCRIPTION_WIDTH = 50;\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return `${str.slice(0, maxLength - 3)}...`;\n}\n\nfunction matchesQuery(skill: ResolvedSkill, query: string): boolean {\n const lowerQuery = query.toLowerCase();\n\n if (skill.id.toLowerCase().includes(lowerQuery)) return true;\n if (skill.displayName?.toLowerCase().includes(lowerQuery)) return true;\n if (skill.description.toLowerCase().includes(lowerQuery)) return true;\n if (skill.category.toLowerCase().includes(lowerQuery)) return true;\n\n return skill.tags.some((tag) => tag.toLowerCase().includes(lowerQuery));\n}\n\nfunction matchesCategory(skill: ResolvedSkill, category: CategoryPath): boolean {\n const lowerCategory = category.toLowerCase();\n return skill.category.toLowerCase().includes(lowerCategory);\n}\n\nfunction toSourcedSkill(\n skill: ResolvedSkill,\n sourceName: string,\n sourceUrl?: string,\n): SourcedSkill {\n return {\n ...skill,\n sourceName,\n sourceUrl,\n };\n}\n\nasync function fetchSkillsFromSource(\n source: SourceEntry,\n forceRefresh: boolean,\n): Promise<SourcedSkill[]> {\n try {\n const result = await fetchFromSource(source.url, { forceRefresh });\n const skillsDir = path.join(result.path, DEFAULT_SKILLS_SUBDIR);\n\n if (!(await fileExists(skillsDir))) {\n return [];\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const skills: SourcedSkill[] = [];\n\n for (const skillDir of skillDirs) {\n const skillMdPath = path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);\n if (await fileExists(skillMdPath)) {\n skills.push({\n // Directory name is an untyped string — cast at data boundary\n id: skillDir as SkillId,\n description: `Skill from ${source.name}`,\n // Synthetic category for third-party sources — not in CategoryPath union\n category: \"imported\" as CategoryPath,\n tags: [],\n author: `@${source.name}`,\n conflictsWith: [],\n recommends: [],\n requires: [],\n alternatives: [],\n discourages: [],\n compatibleWith: [],\n requiresSetup: [],\n providesSetupFor: [],\n sourceName: source.name,\n sourceUrl: source.url,\n path: path.join(skillsDir, skillDir),\n });\n }\n }\n\n return skills;\n } catch {\n // Source unavailable, return empty\n return [];\n }\n}\n\nexport default class Search extends BaseCommand {\n static summary = \"Search available skills\";\n static description =\n \"Search skills by ID, alias, description, category, or tags. \" +\n \"Run without arguments or with -i for interactive mode with multi-select.\";\n\n static examples = [\n {\n description: \"Search for React skills\",\n command: \"<%= config.bin %> search react\",\n },\n {\n description: \"Interactive search mode\",\n command: \"<%= config.bin %> search\",\n },\n {\n description: \"Interactive with pre-filled query\",\n command: \"<%= config.bin %> search -i react\",\n },\n {\n description: \"Search with category filter\",\n command: \"<%= config.bin %> search state -c frontend\",\n },\n ];\n\n static args = {\n query: Args.string({\n description: \"Search query (matches name, description, category, tags)\",\n required: false,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n interactive: Flags.boolean({\n char: \"i\",\n description: \"Launch interactive search with multi-select\",\n default: false,\n }),\n category: Flags.string({\n char: \"c\",\n description: \"Filter by category\",\n required: false,\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote sources\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Search);\n const projectDir = process.cwd();\n\n const isInteractive = flags.interactive || !args.query;\n\n if (isInteractive) {\n await this.runInteractive(args.query, flags.refresh, projectDir);\n } else {\n await this.runStatic(args.query!, flags);\n }\n }\n\n private async runInteractive(\n initialQuery: string | undefined,\n forceRefresh: boolean,\n projectDir: string,\n ): Promise<void> {\n this.log(\"Loading skills from all sources...\");\n\n try {\n const { matrix, sourcePath } = await loadSkillsMatrixFromSource({\n sourceFlag: undefined,\n projectDir,\n forceRefresh,\n });\n\n const primarySkills = Object.values(matrix.skills)\n .filter((skill): skill is ResolvedSkill => skill !== undefined)\n .map((skill) => toSourcedSkill(skill, \"marketplace\", sourcePath));\n\n const { extras } = await resolveAllSources(projectDir);\n\n const extraSkillArrays = await Promise.all(\n extras.map((source) => fetchSkillsFromSource(source, forceRefresh)),\n );\n\n const allSkills: SourcedSkill[] = [...primarySkills, ...extraSkillArrays.flat()];\n const sourceCount = 1 + extras.length;\n\n this.log(`Loaded ${allSkills.length} skills from ${sourceCount} source(s)`);\n this.log(\"\");\n\n const searchResultPromise = new Promise<SkillSearchResult>((resolve) => {\n const { waitUntilExit } = render(\n <SkillSearch\n skills={allSkills}\n sourceCount={sourceCount}\n initialQuery={initialQuery}\n onComplete={(result) => {\n resolve(result);\n }}\n onCancel={() => {\n resolve({ selectedSkills: [], cancelled: true });\n }}\n />,\n );\n\n waitUntilExit().then(() => {\n resolve({ selectedSkills: [], cancelled: true });\n });\n });\n\n const searchResult = await searchResultPromise;\n\n if (searchResult.cancelled) {\n this.log(\"Search cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n if (searchResult.selectedSkills.length === 0) {\n this.log(\"No skills selected\");\n return;\n }\n\n this.log(\"\");\n this.log(`Importing ${searchResult.selectedSkills.length} skill(s)...`);\n\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n\n for (const skill of searchResult.selectedSkills) {\n if (skill.path) {\n const destPath = path.join(destDir, skill.id);\n await ensureDir(path.dirname(destPath));\n await copy(skill.path, destPath);\n this.logSuccess(`Imported: ${skill.id}`);\n } else {\n this.warn(`Skipping ${skill.id}: No source path available`);\n }\n }\n\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.IMPORT_COMPLETE);\n this.log(`Skills location: ${destDir}`);\n this.log(INFO_MESSAGES.RUN_COMPILE);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async runStatic(\n query: string,\n flags: { source?: string; category?: string },\n ): Promise<void> {\n try {\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const { matrix, sourcePath, isLocal } = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n });\n\n this.log(`Loaded from ${isLocal ? \"local\" : \"remote\"}: ${sourcePath}`);\n\n const allSkills = Object.values(matrix.skills).filter(\n (skill): skill is ResolvedSkill => skill !== undefined,\n );\n\n let results = allSkills.filter((skill) => matchesQuery(skill, query));\n\n if (flags.category) {\n // CLI flag is an untyped string — cast at data boundary\n results = results.filter((skill) => matchesCategory(skill, flags.category as CategoryPath));\n }\n\n results = sortBy(results, (r) => r.displayName || r.id);\n\n this.log(\"\");\n if (results.length === 0) {\n this.warn(`No skills found matching \"${query}\"`);\n if (flags.category) {\n this.logInfo(`Category filter: ${flags.category}`);\n }\n } else {\n this.logInfo(\n `Found ${results.length} skill${results.length === 1 ? \"\" : \"s\"} matching \"${query}\"`,\n );\n if (flags.category) {\n this.logInfo(`Category filter: ${flags.category}`);\n }\n this.log(\"\");\n\n printTable({\n data: results.map((skill) => ({\n id: skill.displayName || skill.id,\n category: skill.category,\n description: truncate(skill.description, MAX_DESCRIPTION_WIDTH),\n })),\n columns: [\n { key: \"id\", name: \"ID\" },\n { key: \"category\", name: \"Category\" },\n { key: \"description\", name: \"Description\" },\n ],\n headerOptions: { bold: true },\n });\n }\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n","export { SkillSearch, type SkillSearchResult } from \"./skill-search.js\";\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/search.tsx","../../src/cli/components/skill-search/index.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport { render } from \"ink\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { SkillSearch, type SkillSearchResult } from \"../components/skill-search/index.js\";\nimport type { SourcedSkill } from \"../components/skill-search/skill-search.js\";\nimport { DEFAULT_SKILLS_SUBDIR, LOCAL_SKILLS_PATH, STANDARD_FILES } from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { resolveAllSources, type SourceEntry } from \"../lib/configuration/index.js\";\nimport {\n loadSkillsMatrixFromSource,\n fetchFromSource,\n parseFrontmatter,\n} from \"../lib/loading/index.js\";\nimport type { CategoryPath, ResolvedSkill, SkillSlug } from \"../types/index.js\";\nimport { listDirectories, fileExists, readFile, copy, ensureDir } from \"../utils/fs.js\";\nimport { SUCCESS_MESSAGES, STATUS_MESSAGES, INFO_MESSAGES } from \"../utils/messages.js\";\n\nconst MAX_DESCRIPTION_WIDTH = 50;\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return `${str.slice(0, maxLength - 3)}...`;\n}\n\nfunction matchesQuery(skill: ResolvedSkill, query: string): boolean {\n const lowerQuery = query.toLowerCase();\n\n if (skill.id.toLowerCase().includes(lowerQuery)) return true;\n if (skill.displayName.toLowerCase().includes(lowerQuery)) return true;\n if (skill.slug?.toLowerCase().includes(lowerQuery)) return true;\n if (skill.description.toLowerCase().includes(lowerQuery)) return true;\n if (skill.category.toLowerCase().includes(lowerQuery)) return true;\n\n return skill.tags.some((tag) => tag.toLowerCase().includes(lowerQuery));\n}\n\nfunction matchesCategory(skill: ResolvedSkill, category: CategoryPath): boolean {\n const lowerCategory = category.toLowerCase();\n return skill.category.toLowerCase().includes(lowerCategory);\n}\n\nfunction toSourcedSkill(\n skill: ResolvedSkill,\n sourceName: string,\n sourceUrl?: string,\n): SourcedSkill {\n return {\n ...skill,\n sourceName,\n sourceUrl,\n };\n}\n\nasync function fetchSkillsFromSource(\n source: SourceEntry,\n forceRefresh: boolean,\n): Promise<SourcedSkill[]> {\n try {\n const result = await fetchFromSource(source.url, { forceRefresh });\n const skillsDir = path.join(result.path, DEFAULT_SKILLS_SUBDIR);\n\n if (!(await fileExists(skillsDir))) {\n return [];\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const skills: SourcedSkill[] = [];\n\n for (const skillDir of skillDirs) {\n const skillMdPath = path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);\n if (!(await fileExists(skillMdPath))) continue;\n\n const content = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(content, skillMdPath);\n if (!frontmatter) continue;\n\n skills.push({\n id: frontmatter.name,\n description: frontmatter.description,\n // Boundary cast: directory name used as slug for third-party source skill\n slug: skillDir as SkillSlug,\n displayName: skillDir,\n // Boundary cast: external source skills have no category metadata\n category: \"imported\" as CategoryPath,\n tags: [],\n author: `@${source.name}`,\n conflictsWith: [],\n isRecommended: false,\n requires: [],\n alternatives: [],\n discourages: [],\n compatibleWith: [],\n requiresSetup: [],\n providesSetupFor: [],\n sourceName: source.name,\n sourceUrl: source.url,\n path: path.join(skillsDir, skillDir),\n });\n }\n\n return skills;\n } catch {\n // Source unavailable, return empty\n return [];\n }\n}\n\nexport default class Search extends BaseCommand {\n static summary = \"Search available skills\";\n static description =\n \"Search skills by ID, alias, description, category, or tags. \" +\n \"Run without arguments or with -i for interactive mode with multi-select.\";\n\n static examples = [\n {\n description: \"Search for React skills\",\n command: \"<%= config.bin %> search react\",\n },\n {\n description: \"Interactive search mode\",\n command: \"<%= config.bin %> search\",\n },\n {\n description: \"Interactive with pre-filled query\",\n command: \"<%= config.bin %> search -i react\",\n },\n {\n description: \"Search with category filter\",\n command: \"<%= config.bin %> search state -c frontend\",\n },\n ];\n\n static args = {\n query: Args.string({\n description: \"Search query (matches name, description, category, tags)\",\n required: false,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n interactive: Flags.boolean({\n char: \"i\",\n description: \"Launch interactive search with multi-select\",\n default: false,\n }),\n category: Flags.string({\n char: \"c\",\n description: \"Filter by category\",\n required: false,\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote sources\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Search);\n const projectDir = process.cwd();\n\n const isInteractive = flags.interactive || !args.query;\n\n if (isInteractive) {\n await this.runInteractive(args.query, flags.refresh, projectDir);\n } else {\n await this.runStatic(args.query!, flags);\n }\n }\n\n private async runInteractive(\n initialQuery: string | undefined,\n forceRefresh: boolean,\n projectDir: string,\n ): Promise<void> {\n this.log(\"Loading skills from all sources...\");\n\n try {\n const { matrix, sourcePath } = await loadSkillsMatrixFromSource({\n sourceFlag: undefined,\n projectDir,\n forceRefresh,\n });\n\n const primarySkills = Object.values(matrix.skills)\n .filter((skill): skill is ResolvedSkill => skill !== undefined)\n .map((skill) => toSourcedSkill(skill, \"marketplace\", sourcePath));\n\n const { extras } = await resolveAllSources(projectDir);\n\n const extraSkillArrays = await Promise.all(\n extras.map((source) => fetchSkillsFromSource(source, forceRefresh)),\n );\n\n const allSkills: SourcedSkill[] = [...primarySkills, ...extraSkillArrays.flat()];\n const sourceCount = 1 + extras.length;\n\n this.log(`Loaded ${allSkills.length} skills from ${sourceCount} source(s)`);\n this.log(\"\");\n\n const searchResultPromise = new Promise<SkillSearchResult>((resolve) => {\n const { waitUntilExit } = render(\n <SkillSearch\n skills={allSkills}\n sourceCount={sourceCount}\n initialQuery={initialQuery}\n onComplete={(result) => {\n resolve(result);\n }}\n onCancel={() => {\n resolve({ selectedSkills: [], cancelled: true });\n }}\n />,\n );\n\n waitUntilExit().then(() => {\n resolve({ selectedSkills: [], cancelled: true });\n });\n });\n\n const searchResult = await searchResultPromise;\n\n if (searchResult.cancelled) {\n this.log(\"Search cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n if (searchResult.selectedSkills.length === 0) {\n this.log(\"No skills selected\");\n return;\n }\n\n this.log(\"\");\n this.log(`Importing ${searchResult.selectedSkills.length} skill(s)...`);\n\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n\n for (const skill of searchResult.selectedSkills) {\n if (skill.path) {\n const destPath = path.join(destDir, skill.id);\n await ensureDir(path.dirname(destPath));\n await copy(skill.path, destPath);\n this.logSuccess(`Imported: ${skill.id}`);\n } else {\n this.warn(`Skipping ${skill.id}: No source path available`);\n }\n }\n\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.IMPORT_COMPLETE);\n this.log(`Skills location: ${destDir}`);\n this.log(INFO_MESSAGES.RUN_COMPILE);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async runStatic(\n query: string,\n flags: { source?: string; category?: string },\n ): Promise<void> {\n try {\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const { matrix, sourcePath, isLocal } = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n });\n\n this.log(`Loaded from ${isLocal ? \"local\" : \"remote\"}: ${sourcePath}`);\n\n const allSkills = Object.values(matrix.skills).filter(\n (skill): skill is ResolvedSkill => skill !== undefined,\n );\n\n let results = allSkills.filter((skill) => matchesQuery(skill, query));\n\n if (flags.category) {\n // CLI flag is an untyped string — cast at data boundary\n results = results.filter((skill) => matchesCategory(skill, flags.category as CategoryPath));\n }\n\n results = sortBy(results, (r) => (r.displayName || r.id).toLowerCase());\n\n this.log(\"\");\n if (results.length === 0) {\n this.warn(`No skills found matching \"${query}\"`);\n if (flags.category) {\n this.logInfo(`Category filter: ${flags.category}`);\n }\n } else {\n this.logInfo(\n `Found ${results.length} skill${results.length === 1 ? \"\" : \"s\"} matching \"${query}\"`,\n );\n if (flags.category) {\n this.logInfo(`Category filter: ${flags.category}`);\n }\n this.log(\"\");\n\n printTable({\n data: results.map((skill) => ({\n id: skill.displayName || skill.id,\n category: skill.category,\n description: truncate(skill.description, MAX_DESCRIPTION_WIDTH),\n })),\n columns: [\n { key: \"id\", name: \"ID\" },\n { key: \"category\", name: \"Category\" },\n { key: \"description\", name: \"Description\" },\n ],\n headerOptions: { bold: true },\n });\n }\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n","export { SkillSearch, type SkillSearchResult } from \"./skill-search.js\";\n"],"mappings":"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","names":[]}
|
|
@@ -3,37 +3,36 @@ import {
|
|
|
3
3
|
Confirm
|
|
4
4
|
} from "../chunk-N6S7ZRIL.js";
|
|
5
5
|
import {
|
|
6
|
-
claudePluginUninstall,
|
|
7
|
-
isClaudeCLIAvailable
|
|
8
|
-
} from "../chunk-YDASDMTH.js";
|
|
9
|
-
import {
|
|
10
|
-
DRY_RUN_MESSAGES,
|
|
11
6
|
INFO_MESSAGES,
|
|
12
7
|
SUCCESS_MESSAGES
|
|
13
|
-
} from "../chunk-
|
|
14
|
-
import {
|
|
15
|
-
BaseCommand,
|
|
16
|
-
EXIT_CODES
|
|
17
|
-
} from "../chunk-2BVZOYJP.js";
|
|
8
|
+
} from "../chunk-MR6OBL3B.js";
|
|
18
9
|
import {
|
|
10
|
+
claudePluginUninstall,
|
|
19
11
|
getProjectPluginsDir,
|
|
12
|
+
isClaudeCLIAvailable,
|
|
20
13
|
listPluginNames,
|
|
21
14
|
loadProjectSourceConfig,
|
|
22
15
|
readForkedFromMetadata
|
|
23
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-TZXYBG3R.js";
|
|
17
|
+
import "../chunk-OCEFD7V6.js";
|
|
24
18
|
import "../chunk-T4EXUIBY.js";
|
|
19
|
+
import {
|
|
20
|
+
BaseCommand,
|
|
21
|
+
EXIT_CODES
|
|
22
|
+
} from "../chunk-VR3CDXDT.js";
|
|
25
23
|
import {
|
|
26
24
|
directoryExists,
|
|
27
25
|
getErrorMessage,
|
|
28
26
|
listDirectories,
|
|
29
27
|
remove
|
|
30
|
-
} from "../chunk-
|
|
28
|
+
} from "../chunk-LWXRUR6B.js";
|
|
31
29
|
import {
|
|
32
30
|
CLAUDE_DIR,
|
|
33
31
|
CLAUDE_SRC_DIR,
|
|
34
32
|
CLI_COLORS,
|
|
35
33
|
DEFAULT_BRANDING
|
|
36
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-6OWHQ7HM.js";
|
|
35
|
+
import "../chunk-EC3UJRKZ.js";
|
|
37
36
|
import {
|
|
38
37
|
init_esm_shims
|
|
39
38
|
} from "../chunk-DHET7RCE.js";
|
|
@@ -46,16 +45,16 @@ import path from "path";
|
|
|
46
45
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
47
46
|
function collectConfiguredSources(config) {
|
|
48
47
|
if (!config) return [];
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
sources
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return
|
|
48
|
+
return [
|
|
49
|
+
...config.source ? [config.source] : [],
|
|
50
|
+
...config.sources?.map((entry) => entry.url) ?? []
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
function collectConfiguredAgents(config) {
|
|
54
|
+
if (!config) return [];
|
|
55
|
+
const agents = config.agents;
|
|
56
|
+
if (!Array.isArray(agents)) return [];
|
|
57
|
+
return agents.map((a) => a.name);
|
|
59
58
|
}
|
|
60
59
|
async function detectUninstallTarget(projectDir) {
|
|
61
60
|
const pluginsDir = getProjectPluginsDir(projectDir);
|
|
@@ -78,6 +77,7 @@ async function detectUninstallTarget(projectDir) {
|
|
|
78
77
|
} catch {
|
|
79
78
|
}
|
|
80
79
|
const configuredSources = collectConfiguredSources(config);
|
|
80
|
+
const configuredAgents = collectConfiguredAgents(config);
|
|
81
81
|
return {
|
|
82
82
|
hasPlugins: pluginNames.length > 0,
|
|
83
83
|
pluginNames,
|
|
@@ -91,7 +91,8 @@ async function detectUninstallTarget(projectDir) {
|
|
|
91
91
|
claudeDir,
|
|
92
92
|
claudeSrcDir,
|
|
93
93
|
config,
|
|
94
|
-
configuredSources
|
|
94
|
+
configuredSources,
|
|
95
|
+
configuredAgents
|
|
95
96
|
};
|
|
96
97
|
}
|
|
97
98
|
var UninstallConfirm = ({
|
|
@@ -163,14 +164,16 @@ function skillMatchesConfiguredSource(forkedFromSource, configuredSources) {
|
|
|
163
164
|
if (!forkedFromSource || configuredSources.length === 0) return false;
|
|
164
165
|
return configuredSources.includes(forkedFromSource);
|
|
165
166
|
}
|
|
167
|
+
function shouldRemoveSkill(forkedFrom, configuredSources, hasConfig) {
|
|
168
|
+
return forkedFrom !== null && (skillMatchesConfiguredSource(forkedFrom.source, configuredSources) || !forkedFrom.source && hasConfig);
|
|
169
|
+
}
|
|
166
170
|
var Uninstall = class _Uninstall extends BaseCommand {
|
|
167
171
|
static summary = `Remove ${DEFAULT_BRANDING.NAME} from this project`;
|
|
168
172
|
static description = `Uninstall ${DEFAULT_BRANDING.NAME} from this project. Removes CLI-managed skills (matched by source), compiled agents, and plugins. User-created content is preserved.`;
|
|
169
173
|
static examples = [
|
|
170
174
|
"<%= config.bin %> <%= command.id %>",
|
|
171
175
|
"<%= config.bin %> <%= command.id %> --yes",
|
|
172
|
-
"<%= config.bin %> <%= command.id %> --all"
|
|
173
|
-
"<%= config.bin %> <%= command.id %> --dry-run"
|
|
176
|
+
"<%= config.bin %> <%= command.id %> --all"
|
|
174
177
|
];
|
|
175
178
|
static flags = {
|
|
176
179
|
...BaseCommand.baseFlags,
|
|
@@ -190,10 +193,6 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
190
193
|
this.log("");
|
|
191
194
|
this.log(`${DEFAULT_BRANDING.NAME} Uninstall`);
|
|
192
195
|
this.log("");
|
|
193
|
-
if (flags["dry-run"]) {
|
|
194
|
-
this.log(DRY_RUN_MESSAGES.PREVIEW_NO_FILES_REMOVED);
|
|
195
|
-
this.log("");
|
|
196
|
-
}
|
|
197
196
|
const target = await detectUninstallTarget(projectDir);
|
|
198
197
|
const hasAnythingToRemove = target.hasPlugins || target.hasLocalSkills || target.hasLocalAgents || flags.all && target.hasClaudeSrcDir;
|
|
199
198
|
if (!hasAnythingToRemove) {
|
|
@@ -204,7 +203,7 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
204
203
|
this.log(INFO_MESSAGES.NO_CHANGES_MADE);
|
|
205
204
|
return;
|
|
206
205
|
}
|
|
207
|
-
if (!flags.yes
|
|
206
|
+
if (!flags.yes) {
|
|
208
207
|
const confirmed = await new Promise((resolve) => {
|
|
209
208
|
const { waitUntilExit } = render(
|
|
210
209
|
/* @__PURE__ */ jsx(
|
|
@@ -246,19 +245,6 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
246
245
|
}
|
|
247
246
|
this.log("");
|
|
248
247
|
}
|
|
249
|
-
if (flags["dry-run"]) {
|
|
250
|
-
if (target.hasPlugins) {
|
|
251
|
-
this.log(`[dry-run] Would uninstall ${target.pluginNames.length} plugins:`);
|
|
252
|
-
for (const pluginName of target.pluginNames) {
|
|
253
|
-
this.log(`[dry-run] ${pluginName}`);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
await this.dryRunLocalRemoval(target, flags.all);
|
|
257
|
-
this.log("");
|
|
258
|
-
this.log(DRY_RUN_MESSAGES.COMPLETE_NO_FILES_REMOVED);
|
|
259
|
-
this.log("");
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
248
|
if (target.hasPlugins) {
|
|
263
249
|
this.log("Uninstalling plugins...");
|
|
264
250
|
try {
|
|
@@ -298,97 +284,81 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
298
284
|
this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);
|
|
299
285
|
this.log("");
|
|
300
286
|
}
|
|
301
|
-
/**
|
|
302
|
-
* Selectively removes local files installed by the CLI using config-based matching.
|
|
303
|
-
*
|
|
304
|
-
* - Skills: removes skill dirs whose forked_from.source matches a configured source
|
|
305
|
-
* - Agents: removes agents whose frontmatter name matches a configured agent, or
|
|
306
|
-
* all agents if config.yaml exists (CLI was used to compile them)
|
|
307
|
-
* - Plugins: removed separately (always)
|
|
308
|
-
* - .claude-src/: only removed with --all flag
|
|
309
|
-
* - .claude/: only removed if empty after selective cleanup
|
|
310
|
-
*/
|
|
311
287
|
async removeLocalFiles(target, removeAll) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if (target.hasLocalSkills) {
|
|
315
|
-
const skillDirNames = await listDirectories(target.skillsDir);
|
|
316
|
-
for (const skillDirName of skillDirNames) {
|
|
317
|
-
const skillDir = path.join(target.skillsDir, skillDirName);
|
|
318
|
-
const forkedFrom = await readForkedFromMetadata(skillDir);
|
|
319
|
-
const shouldRemove = forkedFrom !== null && (skillMatchesConfiguredSource(forkedFrom.source, target.configuredSources) || // Legacy skills without source field are treated as CLI-managed when config exists
|
|
320
|
-
!forkedFrom.source && target.config !== null);
|
|
321
|
-
if (shouldRemove) {
|
|
322
|
-
await remove(skillDir);
|
|
323
|
-
removedSkillCount++;
|
|
324
|
-
this.log(` Uninstalled skill '${skillDirName}'`);
|
|
325
|
-
} else {
|
|
326
|
-
this.warn(`Skipping '${skillDirName}': not created by ${DEFAULT_BRANDING.NAME} CLI`);
|
|
327
|
-
skippedSkillCount++;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
if (removedSkillCount > 0) {
|
|
331
|
-
this.logSuccess(
|
|
332
|
-
`Removed ${removedSkillCount} CLI-installed ${removedSkillCount === 1 ? "skill" : "skills"}`
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
if (skippedSkillCount === 0 && await directoryExists(target.skillsDir)) {
|
|
336
|
-
if (await isDirectoryEmpty(target.skillsDir)) {
|
|
337
|
-
await remove(target.skillsDir);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
if (target.hasLocalAgents) {
|
|
342
|
-
if (target.config !== null) {
|
|
343
|
-
const { readdir } = await import("fs/promises");
|
|
344
|
-
try {
|
|
345
|
-
const agentFiles = (await readdir(target.agentsDir)).filter((f) => f.endsWith(".md"));
|
|
346
|
-
for (const agentFile of agentFiles) {
|
|
347
|
-
this.log(` Uninstalled agent '${agentFile.replace(/\.md$/, "")}'`);
|
|
348
|
-
}
|
|
349
|
-
} catch {
|
|
350
|
-
}
|
|
351
|
-
await remove(target.agentsDir);
|
|
352
|
-
this.logSuccess("Removed compiled agents");
|
|
353
|
-
}
|
|
354
|
-
}
|
|
288
|
+
await this.removeMatchingSkills(target);
|
|
289
|
+
await this.removeMatchingAgents(target);
|
|
355
290
|
if (removeAll && target.hasClaudeSrcDir) {
|
|
356
291
|
await remove(target.claudeSrcDir);
|
|
357
292
|
this.logSuccess(`Removed ${CLAUDE_SRC_DIR}/`);
|
|
358
293
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
294
|
+
await this.removeEmptyClaudeDir(target);
|
|
295
|
+
}
|
|
296
|
+
async removeMatchingSkills(target) {
|
|
297
|
+
if (!target.hasLocalSkills) return;
|
|
298
|
+
const skillDirNames = await listDirectories(target.skillsDir);
|
|
299
|
+
let removedCount = 0;
|
|
300
|
+
let skippedCount = 0;
|
|
301
|
+
for (const skillDirName of skillDirNames) {
|
|
302
|
+
const skillDir = path.join(target.skillsDir, skillDirName);
|
|
303
|
+
const forkedFrom = await readForkedFromMetadata(skillDir);
|
|
304
|
+
if (shouldRemoveSkill(forkedFrom, target.configuredSources, target.config !== null)) {
|
|
305
|
+
await remove(skillDir);
|
|
306
|
+
removedCount++;
|
|
307
|
+
this.log(` Uninstalled skill '${skillDirName}'`);
|
|
363
308
|
} else {
|
|
364
|
-
this.
|
|
309
|
+
this.warn(`Skipping '${skillDirName}': not created by ${DEFAULT_BRANDING.NAME} CLI`);
|
|
310
|
+
skippedCount++;
|
|
365
311
|
}
|
|
366
312
|
}
|
|
313
|
+
if (removedCount > 0) {
|
|
314
|
+
this.logSuccess(
|
|
315
|
+
`Removed ${removedCount} CLI-installed ${removedCount === 1 ? "skill" : "skills"}`
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
if (skippedCount > 0) return;
|
|
319
|
+
if (!await directoryExists(target.skillsDir)) return;
|
|
320
|
+
if (await isDirectoryEmpty(target.skillsDir)) {
|
|
321
|
+
await remove(target.skillsDir);
|
|
322
|
+
}
|
|
367
323
|
}
|
|
368
|
-
async
|
|
369
|
-
if (target.
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
`[dry-run] Would skip '${skillDirName}': not created by ${DEFAULT_BRANDING.NAME} CLI`
|
|
380
|
-
);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
324
|
+
async removeMatchingAgents(target) {
|
|
325
|
+
if (!target.hasLocalAgents) return;
|
|
326
|
+
if (target.configuredAgents.length === 0) return;
|
|
327
|
+
const agentFiles = await this.listAgentFiles(target.agentsDir);
|
|
328
|
+
let removedCount = 0;
|
|
329
|
+
for (const agentFile of agentFiles) {
|
|
330
|
+
const agentName = agentFile.replace(/\.md$/, "");
|
|
331
|
+
if (!target.configuredAgents.includes(agentName)) continue;
|
|
332
|
+
await remove(path.join(target.agentsDir, agentFile));
|
|
333
|
+
this.log(` Uninstalled agent '${agentName}'`);
|
|
334
|
+
removedCount++;
|
|
383
335
|
}
|
|
384
|
-
if (
|
|
385
|
-
this.
|
|
336
|
+
if (removedCount > 0) {
|
|
337
|
+
this.logSuccess(
|
|
338
|
+
`Removed ${removedCount} compiled ${removedCount === 1 ? "agent" : "agents"}`
|
|
339
|
+
);
|
|
386
340
|
}
|
|
387
|
-
if (
|
|
388
|
-
|
|
341
|
+
if (!await directoryExists(target.agentsDir)) return;
|
|
342
|
+
if (await isDirectoryEmpty(target.agentsDir)) {
|
|
343
|
+
await remove(target.agentsDir);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
async listAgentFiles(agentsDir) {
|
|
347
|
+
try {
|
|
348
|
+
const { readdir } = await import("fs/promises");
|
|
349
|
+
return (await readdir(agentsDir)).filter((f) => f.endsWith(".md"));
|
|
350
|
+
} catch {
|
|
351
|
+
return [];
|
|
389
352
|
}
|
|
390
|
-
|
|
391
|
-
|
|
353
|
+
}
|
|
354
|
+
async removeEmptyClaudeDir(target) {
|
|
355
|
+
if (!target.hasClaudeDir) return;
|
|
356
|
+
if (!await directoryExists(target.claudeDir)) return;
|
|
357
|
+
if (await isDirectoryEmpty(target.claudeDir)) {
|
|
358
|
+
await remove(target.claudeDir);
|
|
359
|
+
this.logSuccess(`Removed ${CLAUDE_DIR}/`);
|
|
360
|
+
} else {
|
|
361
|
+
this.log(`Kept ${CLAUDE_DIR}/ (contains user content)`);
|
|
392
362
|
}
|
|
393
363
|
}
|
|
394
364
|
};
|