superacli 1.1.0 → 1.1.2
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/.beads/.br_history/issues.20260308_235202_180577215.jsonl +57 -0
- package/.beads/.br_history/issues.20260308_235202_387414163.jsonl +57 -0
- package/.beads/.br_history/issues.20260308_235202_564422794.jsonl +57 -0
- package/.beads/.br_history/issues.20260308_235202_742600597.jsonl +57 -0
- package/.beads/.br_history/issues.20260308_235208_133360069.jsonl +57 -0
- package/.beads/.br_history/issues.20260308_235505_473406307.jsonl +57 -0
- package/.beads/.br_history/issues.20260308_235505_662360489.jsonl +57 -0
- package/.beads/.br_history/issues.20260308_235505_843935624.jsonl +57 -0
- package/.beads/.br_history/issues.20260308_235506_044530221.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_002618_115728731.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_003748_878174586.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_004057_868755623.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_004058_512842163.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_004058_994445226.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_004059_475988596.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_161902_566857851.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_170512_277017739.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_170512_477876921.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_170512_664382701.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_170512_859400333.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_212326_082771164.jsonl +57 -0
- package/.beads/.br_history/issues.20260309_212326_245619716.jsonl +58 -0
- package/.beads/.br_history/issues.20260309_212326_403198317.jsonl +59 -0
- package/.beads/.br_history/issues.20260309_212332_539197678.jsonl +60 -0
- package/.beads/.br_history/issues.20260309_212332_731373599.jsonl +60 -0
- package/.beads/.br_history/issues.20260309_212332_928710953.jsonl +60 -0
- package/.beads/.br_history/issues.20260309_213021_341505240.jsonl +60 -0
- package/.beads/.br_history/issues.20260309_213022_023136934.jsonl +60 -0
- package/.beads/.br_history/issues.20260309_213022_400050719.jsonl +60 -0
- package/.beads/issues.jsonl +20 -17
- package/README.md +1 -1
- package/__tests__/adapter-schema.test.js +3 -0
- package/__tests__/aws-plugin.test.js +84 -0
- package/__tests__/az-plugin.test.js +84 -0
- package/__tests__/builtin-adapter.test.js +29 -0
- package/__tests__/cline-plugin.test.js +109 -0
- package/__tests__/cline-skill.test.js +49 -0
- package/__tests__/docker-plugin.test.js +3 -1
- package/__tests__/eza-plugin.test.js +81 -0
- package/__tests__/gcloud-plugin.test.js +86 -0
- package/__tests__/gh-plugin.test.js +86 -0
- package/__tests__/helm-plugin.test.js +81 -0
- package/__tests__/http-adapter.test.js +118 -0
- package/__tests__/just-plugin.test.js +82 -0
- package/__tests__/kubectl-plugin.test.js +83 -0
- package/__tests__/linear-plugin.test.js +81 -0
- package/__tests__/mcp-adapter.test.js +187 -0
- package/__tests__/nextest-plugin.test.js +82 -0
- package/__tests__/npm-plugin.test.js +81 -0
- package/__tests__/nullclaw-plugin.test.js +157 -0
- package/__tests__/openapi-adapter.test.js +199 -0
- package/__tests__/plugin-agency-agents.test.js +6 -6
- package/__tests__/plugin-nullclaw.test.js +78 -0
- package/__tests__/plugin-visual-explainer.test.js +62 -0
- package/__tests__/plugins-manager.test.js +59 -10
- package/__tests__/pnpm-plugin.test.js +81 -0
- package/__tests__/poetry-plugin.test.js +83 -0
- package/__tests__/process-adapter.test.js +124 -90
- package/__tests__/pulumi-plugin.test.js +81 -0
- package/__tests__/railway-plugin.test.js +84 -0
- package/__tests__/server-app.test.js +67 -0
- package/__tests__/server-config-service.test.js +79 -0
- package/__tests__/server-routes-ask.test.js +89 -0
- package/__tests__/server-routes-commands.test.js +55 -0
- package/__tests__/server-routes-config.test.js +87 -0
- package/__tests__/server-routes-jobs.test.js +53 -0
- package/__tests__/server-routes-misc.test.js +112 -0
- package/__tests__/server-storage-adapter.test.js +40 -0
- package/__tests__/server-storage-file.test.js +73 -0
- package/__tests__/server-storage-mongo.test.js +74 -0
- package/__tests__/shell-adapter.test.js +81 -22
- package/__tests__/stripe-plugin.test.js +3 -1
- package/__tests__/supabase-plugin.test.js +86 -0
- package/__tests__/terraform-plugin.test.js +83 -0
- package/__tests__/uv-plugin.test.js +81 -0
- package/__tests__/vercel-plugin.test.js +81 -0
- package/__tests__/watchexec-plugin.test.js +80 -0
- package/cli/adapter-schema.js +5 -0
- package/cli/adapters/process.js +53 -2
- package/cli/plugin-install-guidance.js +320 -0
- package/cli/plugins-manager.js +272 -212
- package/cli/skills.js +16 -5
- package/cli/supercli.js +26 -2
- package/docs/plugins.md +2 -0
- package/docs/skills/cline-non-interactive/SKILL.md +59 -0
- package/docs/skills-catalog.md +35 -0
- package/docs/visual-overview.md +21 -0
- package/jest.config.js +4 -1
- package/package.json +4 -3
- package/plugins/agency-agents/plugin.json +5 -0
- package/{cli/plugin-agency-agents.js → plugins/agency-agents/scripts/post-install.js} +13 -3
- package/plugins/aws/README.md +46 -0
- package/plugins/aws/plugin.json +42 -0
- package/plugins/az/README.md +46 -0
- package/plugins/az/plugin.json +42 -0
- package/plugins/clickup/plugin.json +38 -0
- package/plugins/clickup/scripts/post-install.js +107 -0
- package/plugins/clickup/scripts/post-uninstall.js +30 -0
- package/plugins/cline/README.md +48 -0
- package/plugins/cline/plugin.json +92 -0
- package/plugins/eza/README.md +40 -0
- package/plugins/eza/plugin.json +42 -0
- package/plugins/gcloud/README.md +46 -0
- package/plugins/gcloud/plugin.json +42 -0
- package/plugins/gh/README.md +46 -0
- package/plugins/gh/plugin.json +43 -0
- package/plugins/helm/README.md +42 -0
- package/plugins/helm/plugin.json +42 -0
- package/plugins/just/README.md +42 -0
- package/plugins/just/plugin.json +42 -0
- package/plugins/kubectl/README.md +46 -0
- package/plugins/kubectl/plugin.json +42 -0
- package/plugins/linear/README.md +60 -0
- package/plugins/linear/plugin.json +42 -0
- package/plugins/nextest/README.md +42 -0
- package/plugins/nextest/plugin.json +42 -0
- package/plugins/npm/README.md +46 -0
- package/plugins/npm/plugin.json +42 -0
- package/plugins/nullclaw/README.md +45 -0
- package/plugins/nullclaw/plugin.json +64 -0
- package/plugins/nullclaw/scripts/post-install.js +189 -0
- package/plugins/nullclaw/scripts/post-uninstall.js +25 -0
- package/plugins/openfang/plugin.json +37 -0
- package/plugins/openfang/scripts/post-install.js +163 -0
- package/plugins/openfang/scripts/post-uninstall.js +30 -0
- package/plugins/plugins.json +234 -0
- package/plugins/pnpm/README.md +46 -0
- package/plugins/pnpm/plugin.json +42 -0
- package/plugins/poetry/README.md +46 -0
- package/plugins/poetry/plugin.json +42 -0
- package/plugins/pulumi/README.md +46 -0
- package/plugins/pulumi/plugin.json +42 -0
- package/plugins/railway/README.md +58 -0
- package/plugins/railway/plugin.json +43 -0
- package/plugins/supabase/README.md +55 -0
- package/plugins/supabase/plugin.json +42 -0
- package/plugins/superpowers/plugin.json +22 -0
- package/plugins/superpowers/scripts/post-install.js +124 -0
- package/plugins/superpowers/scripts/post-uninstall.js +30 -0
- package/plugins/terraform/README.md +46 -0
- package/plugins/terraform/plugin.json +42 -0
- package/plugins/uv/README.md +46 -0
- package/plugins/uv/plugin.json +42 -0
- package/plugins/vercel/README.md +47 -0
- package/plugins/vercel/plugin.json +42 -0
- package/plugins/visual-explainer/plugin.json +15 -0
- package/plugins/visual-explainer/scripts/post-install.js +111 -0
- package/plugins/watchexec/README.md +40 -0
- package/plugins/watchexec/plugin.json +42 -0
- package/tests/test-aws-smoke.sh +56 -0
- package/tests/test-az-smoke.sh +56 -0
- package/tests/test-cline-smoke.sh +37 -0
- package/tests/test-eza-smoke.sh +33 -0
- package/tests/test-gcloud-smoke.sh +56 -0
- package/tests/test-gh-smoke.sh +56 -0
- package/tests/test-helm-smoke.sh +33 -0
- package/tests/test-just-smoke.sh +40 -0
- package/tests/test-kubectl-smoke.sh +37 -0
- package/tests/test-linear-smoke.sh +97 -0
- package/tests/test-nextest-smoke.sh +33 -0
- package/tests/test-npm-smoke.sh +32 -0
- package/tests/test-nullclaw-smoke.sh +51 -0
- package/tests/test-plugins-registry.js +110 -0
- package/tests/test-pnpm-smoke.sh +33 -0
- package/tests/test-poetry-smoke.sh +33 -0
- package/tests/test-pulumi-smoke.sh +33 -0
- package/tests/test-railway-smoke.sh +95 -0
- package/tests/test-supabase-smoke.sh +95 -0
- package/tests/test-terraform-smoke.sh +33 -0
- package/tests/test-uv-smoke.sh +33 -0
- package/tests/test-vercel-smoke.sh +55 -0
- package/tests/test-watchexec-smoke.sh +33 -0
- package/.beads/.br_history/issues.20260308_180927_477542428.jsonl +0 -12
- package/.beads/.br_history/issues.20260308_181032_020230108.jsonl +0 -12
- package/.beads/.br_history/issues.20260308_181032_180539413.jsonl +0 -12
- package/.beads/.br_history/issues.20260308_181032_372621506.jsonl +0 -12
- package/.beads/.br_history/issues.20260308_181032_565142225.jsonl +0 -12
- package/.beads/.br_history/issues.20260308_181311_336346464.jsonl +0 -12
- package/.beads/.br_history/issues.20260308_181444_039234498.jsonl +0 -13
- package/.beads/.br_history/issues.20260308_181503_794764403.jsonl +0 -13
- package/.beads/.br_history/issues.20260308_181503_950163105.jsonl +0 -13
- package/.beads/.br_history/issues.20260308_192031_852553505.jsonl +0 -13
- package/.beads/.br_history/issues.20260308_193552_846920518.jsonl +0 -14
- package/.beads/.br_history/issues.20260308_194054_394884833.jsonl +0 -14
- package/.beads/.br_history/issues.20260308_194209_440472460.jsonl +0 -15
- package/.beads/.br_history/issues.20260308_195319_099391899.jsonl +0 -15
- package/.beads/.br_history/issues.20260308_195324_176987204.jsonl +0 -16
- package/.beads/.br_history/issues.20260308_195436_929114019.jsonl +0 -16
- package/.beads/.br_history/issues.20260308_195437_055808298.jsonl +0 -17
- package/.beads/.br_history/issues.20260308_195437_304297399.jsonl +0 -18
- package/.beads/.br_history/issues.20260308_195437_556007332.jsonl +0 -19
- package/.beads/.br_history/issues.20260308_195444_987209695.jsonl +0 -20
- package/.beads/.br_history/issues.20260308_195445_133350193.jsonl +0 -20
- package/.beads/.br_history/issues.20260308_195445_400185615.jsonl +0 -20
- package/.beads/.br_history/issues.20260308_195445_689886334.jsonl +0 -20
- package/.beads/.br_history/issues.20260308_195445_949947727.jsonl +0 -20
- package/.beads/.br_history/issues.20260308_195745_580473297.jsonl +0 -20
- package/.beads/.br_history/issues.20260308_195745_725920532.jsonl +0 -20
- package/.beads/.br_history/issues.20260308_195745_968227911.jsonl +0 -20
- package/.beads/.br_history/issues.20260308_195746_224276322.jsonl +0 -20
- package/.beads/.br_history/issues.20260308_200018_386890807.jsonl +0 -20
- package/ref-btcbot/.env.example +0 -19
- package/ref-btcbot/README.md +0 -3
- package/ref-btcbot/docs/bot.md +0 -72
- package/ref-btcbot/docs/skills/btcbot.backtest/SKILL.md +0 -70
- package/ref-btcbot/docs/skills/btcbot.config/SKILL.md +0 -79
- package/ref-btcbot/docs/skills/btcbot.orders/SKILL.md +0 -60
- package/ref-btcbot/docs/skills/btcbot.positions/SKILL.md +0 -54
- package/ref-btcbot/docs/skills/btcbot.risk/SKILL.md +0 -69
- package/ref-btcbot/docs/skills/btcbot.run-loop/SKILL.md +0 -63
- package/ref-btcbot/docs/skills/btcbot.run-once/SKILL.md +0 -63
- package/ref-btcbot/docs/skills/btcbot.status/SKILL.md +0 -59
- package/ref-btcbot/examples/sample-candles.json +0 -52
- package/ref-btcbot/package.json +0 -18
- package/ref-btcbot/plugin/plugin.json +0 -146
- package/ref-btcbot/src/cli.js +0 -104
- package/ref-btcbot/src/config.js +0 -80
- package/ref-btcbot/src/core/bot-runner.js +0 -78
- package/ref-btcbot/src/core/exchange-factory.js +0 -19
- package/ref-btcbot/src/core/live-exchange.js +0 -12
- package/ref-btcbot/src/core/paper-exchange.js +0 -82
- package/ref-btcbot/src/core/risk-engine.js +0 -42
- package/ref-btcbot/src/core/state-repository.js +0 -47
- package/ref-btcbot/src/services/backtest-service.js +0 -44
- package/ref-btcbot/src/services/market-data.js +0 -32
- package/ref-btcbot/src/storage/json-store.js +0 -45
- package/ref-btcbot/src/strategy/hedge-strategy.js +0 -65
- package/ref-btcbot/src/strategy/indicators.js +0 -56
- package/ref-btcbot/src/web/api.js +0 -50
- package/ref-btcbot/src/web/app.js +0 -51
- package/ref-btcbot/src/web/index.html +0 -70
- package/ref-btcbot/src/web/server.js +0 -33
- /package/.beads/.br_history/{issues.20260308_180927_477542428.jsonl.meta.json → issues.20260308_235202_180577215.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_181032_020230108.jsonl.meta.json → issues.20260308_235202_387414163.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_181032_180539413.jsonl.meta.json → issues.20260308_235202_564422794.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_181032_372621506.jsonl.meta.json → issues.20260308_235202_742600597.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_181032_565142225.jsonl.meta.json → issues.20260308_235208_133360069.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_181311_336346464.jsonl.meta.json → issues.20260308_235505_473406307.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_181444_039234498.jsonl.meta.json → issues.20260308_235505_662360489.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_181503_794764403.jsonl.meta.json → issues.20260308_235505_843935624.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_181503_950163105.jsonl.meta.json → issues.20260308_235506_044530221.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_192031_852553505.jsonl.meta.json → issues.20260309_002618_115728731.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_193552_846920518.jsonl.meta.json → issues.20260309_003748_878174586.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_194054_394884833.jsonl.meta.json → issues.20260309_004057_868755623.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_194209_440472460.jsonl.meta.json → issues.20260309_004058_512842163.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195319_099391899.jsonl.meta.json → issues.20260309_004058_994445226.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195324_176987204.jsonl.meta.json → issues.20260309_004059_475988596.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195436_929114019.jsonl.meta.json → issues.20260309_161902_566857851.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195437_055808298.jsonl.meta.json → issues.20260309_170512_277017739.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195437_304297399.jsonl.meta.json → issues.20260309_170512_477876921.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195437_556007332.jsonl.meta.json → issues.20260309_170512_664382701.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195444_987209695.jsonl.meta.json → issues.20260309_170512_859400333.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195445_133350193.jsonl.meta.json → issues.20260309_212326_082771164.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195445_400185615.jsonl.meta.json → issues.20260309_212326_245619716.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195445_689886334.jsonl.meta.json → issues.20260309_212326_403198317.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195445_949947727.jsonl.meta.json → issues.20260309_212332_539197678.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195745_580473297.jsonl.meta.json → issues.20260309_212332_731373599.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195745_725920532.jsonl.meta.json → issues.20260309_212332_928710953.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195745_968227911.jsonl.meta.json → issues.20260309_213021_341505240.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_195746_224276322.jsonl.meta.json → issues.20260309_213022_023136934.jsonl.meta.json} +0 -0
- /package/.beads/.br_history/{issues.20260308_200018_386890807.jsonl.meta.json → issues.20260309_213022_400050719.jsonl.meta.json} +0 -0
package/cli/plugins-manager.js
CHANGED
|
@@ -2,9 +2,9 @@ const fs = require("fs")
|
|
|
2
2
|
const path = require("path")
|
|
3
3
|
const os = require("os")
|
|
4
4
|
const { spawnSync } = require("child_process")
|
|
5
|
-
const { installAgencyAgentsSkillProvider } = require("./plugin-agency-agents")
|
|
6
5
|
const { SUPPORTED_ADAPTERS } = require("./adapter-schema")
|
|
7
6
|
const { getRegistryPlugin } = require("./plugins-registry")
|
|
7
|
+
const { getPluginInstallGuidance } = require("./plugin-install-guidance")
|
|
8
8
|
const {
|
|
9
9
|
readPluginsLock,
|
|
10
10
|
writePluginsLock,
|
|
@@ -15,70 +15,42 @@ const BUNDLED_PLUGINS = {
|
|
|
15
15
|
beads: path.resolve(__dirname, "..", "plugins", "beads", "plugin.json"),
|
|
16
16
|
gwc: path.resolve(__dirname, "..", "plugins", "gwc", "plugin.json"),
|
|
17
17
|
docker: path.resolve(__dirname, "..", "plugins", "docker", "plugin.json"),
|
|
18
|
-
"agency-agents": path.resolve(__dirname, "..", "plugins", "agency-agents", "plugin.json")
|
|
18
|
+
"agency-agents": path.resolve(__dirname, "..", "plugins", "agency-agents", "plugin.json"),
|
|
19
|
+
"visual-explainer": path.resolve(__dirname, "..", "plugins", "visual-explainer", "plugin.json")
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
plugin:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
plugin: "docker",
|
|
54
|
-
binary: "docker",
|
|
55
|
-
check: "docker --version",
|
|
56
|
-
install_steps: [
|
|
57
|
-
"docker --version"
|
|
58
|
-
],
|
|
59
|
-
note: "Install Docker Engine/Desktop using your OS package manager, then verify with docker --version."
|
|
60
|
-
},
|
|
61
|
-
stripe: {
|
|
62
|
-
plugin: "stripe",
|
|
63
|
-
binary: "stripe",
|
|
64
|
-
check: "stripe --version",
|
|
65
|
-
install_steps: [
|
|
66
|
-
"brew install stripe/stripe-cli/stripe",
|
|
67
|
-
"stripe --version",
|
|
68
|
-
"stripe login"
|
|
69
|
-
],
|
|
70
|
-
note: "Install Stripe CLI and authenticate with stripe login before running API commands."
|
|
71
|
-
},
|
|
72
|
-
"agency-agents": {
|
|
73
|
-
plugin: "agency-agents",
|
|
74
|
-
binary: "curl",
|
|
75
|
-
check: "curl --version",
|
|
76
|
-
install_steps: [
|
|
77
|
-
"supercli plugins install agency-agents",
|
|
78
|
-
"supercli skills list --catalog --provider agency-agents --json",
|
|
79
|
-
"supercli skills get agency-agents:engineering.engineering-frontend-developer"
|
|
80
|
-
],
|
|
81
|
-
note: "Install indexes remote markdown skills from https://github.com/msitarzewski/agency-agents (best effort, upstream paths may change)."
|
|
22
|
+
function validateNodeHook(hook, kind) {
|
|
23
|
+
if (!hook) return null
|
|
24
|
+
if (!hook.script || typeof hook.script !== "string") {
|
|
25
|
+
throw Object.assign(new Error(`Invalid plugin manifest: ${kind}.script must be a string`), {
|
|
26
|
+
code: 85,
|
|
27
|
+
type: "invalid_argument",
|
|
28
|
+
recoverable: false
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const runtime = hook.runtime || "node"
|
|
33
|
+
if (runtime !== "node") {
|
|
34
|
+
throw Object.assign(new Error(`Invalid plugin manifest: ${kind}.runtime must be 'node'`), {
|
|
35
|
+
code: 85,
|
|
36
|
+
type: "invalid_argument",
|
|
37
|
+
recoverable: false
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const timeoutMs = hook.timeout_ms === undefined ? 15000 : Number(hook.timeout_ms)
|
|
42
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > 15000) {
|
|
43
|
+
throw Object.assign(new Error(`Invalid plugin manifest: ${kind}.timeout_ms must be a positive number <= 15000`), {
|
|
44
|
+
code: 85,
|
|
45
|
+
type: "invalid_argument",
|
|
46
|
+
recoverable: false
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
script: hook.script,
|
|
52
|
+
runtime,
|
|
53
|
+
timeout_ms: timeoutMs
|
|
82
54
|
}
|
|
83
55
|
}
|
|
84
56
|
|
|
@@ -129,6 +101,10 @@ function resolveRepoManifestPath(baseDir, manifestPath) {
|
|
|
129
101
|
return candidate
|
|
130
102
|
}
|
|
131
103
|
|
|
104
|
+
function noCleanup() {
|
|
105
|
+
return undefined
|
|
106
|
+
}
|
|
107
|
+
|
|
132
108
|
function loadManifestFromGit(repo, options = {}) {
|
|
133
109
|
if (!repo || typeof repo !== "string") {
|
|
134
110
|
throw Object.assign(new Error("Missing git repo URL/path for plugin install"), {
|
|
@@ -139,53 +115,50 @@ function loadManifestFromGit(repo, options = {}) {
|
|
|
139
115
|
}
|
|
140
116
|
|
|
141
117
|
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "dcli-plugin-"))
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
args.push(repo, tmpDir)
|
|
148
|
-
const clone = spawnSync("git", args, { encoding: "utf-8", timeout: 15000 })
|
|
149
|
-
|
|
150
|
-
if (clone.error) {
|
|
151
|
-
const suggestion = clone.error.code === "ENOENT"
|
|
152
|
-
? ["Install git and retry"]
|
|
153
|
-
: []
|
|
154
|
-
throw Object.assign(new Error(`Failed to clone plugin repo '${repo}': ${clone.error.message}`), {
|
|
155
|
-
code: 105,
|
|
156
|
-
type: "integration_error",
|
|
157
|
-
recoverable: true,
|
|
158
|
-
suggestions: suggestion
|
|
159
|
-
})
|
|
160
|
-
}
|
|
161
|
-
if (clone.status !== 0) {
|
|
162
|
-
throw Object.assign(new Error(`Failed to clone plugin repo '${repo}': ${(clone.stderr || "").trim() || `exit ${clone.status}`}`), {
|
|
163
|
-
code: 105,
|
|
164
|
-
type: "integration_error",
|
|
165
|
-
recoverable: true
|
|
166
|
-
})
|
|
167
|
-
}
|
|
118
|
+
const args = ["clone", "--depth", "1"]
|
|
119
|
+
if (options.ref) args.push("--branch", String(options.ref), "--single-branch")
|
|
120
|
+
args.push(repo, tmpDir)
|
|
121
|
+
const clone = spawnSync("git", args, { encoding: "utf-8", timeout: 15000 })
|
|
168
122
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
123
|
+
if (clone.error) {
|
|
124
|
+
fs.rmSync(tmpDir, { recursive: true, force: true })
|
|
125
|
+
const suggestion = clone.error.code === "ENOENT" ? ["Install git and retry"] : []
|
|
126
|
+
throw Object.assign(new Error(`Failed to clone plugin repo '${repo}': ${clone.error.message}`), {
|
|
127
|
+
code: 105,
|
|
128
|
+
type: "integration_error",
|
|
129
|
+
recoverable: true,
|
|
130
|
+
suggestions: suggestion
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
if (clone.status !== 0) {
|
|
134
|
+
fs.rmSync(tmpDir, { recursive: true, force: true })
|
|
135
|
+
throw Object.assign(new Error(`Failed to clone plugin repo '${repo}': ${(clone.stderr || "").trim() || `exit ${clone.status}`}`), {
|
|
136
|
+
code: 105,
|
|
137
|
+
type: "integration_error",
|
|
138
|
+
recoverable: true
|
|
139
|
+
})
|
|
140
|
+
}
|
|
177
141
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
resolvedFrom: {
|
|
181
|
-
type: "git",
|
|
182
|
-
repo,
|
|
183
|
-
ref: options.ref || null,
|
|
184
|
-
manifest_path: options.manifestPath || "plugin.json"
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
} finally {
|
|
142
|
+
const manifestPath = resolveRepoManifestPath(tmpDir, options.manifestPath)
|
|
143
|
+
if (!fs.existsSync(manifestPath)) {
|
|
188
144
|
fs.rmSync(tmpDir, { recursive: true, force: true })
|
|
145
|
+
throw Object.assign(new Error(`Plugin manifest not found in repo: ${options.manifestPath || "plugin.json"}`), {
|
|
146
|
+
code: 92,
|
|
147
|
+
type: "resource_not_found",
|
|
148
|
+
recoverable: false
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
manifest: parseManifestFile(manifestPath),
|
|
154
|
+
manifestPath,
|
|
155
|
+
resolvedFrom: {
|
|
156
|
+
type: "git",
|
|
157
|
+
repo,
|
|
158
|
+
ref: options.ref || null,
|
|
159
|
+
manifest_path: options.manifestPath || "plugin.json"
|
|
160
|
+
},
|
|
161
|
+
cleanup: () => fs.rmSync(tmpDir, { recursive: true, force: true })
|
|
189
162
|
}
|
|
190
163
|
}
|
|
191
164
|
|
|
@@ -195,11 +168,9 @@ function resolveRegistrySource(name) {
|
|
|
195
168
|
|
|
196
169
|
const source = entry.source || {}
|
|
197
170
|
const sourceType = source.type || "bundled"
|
|
198
|
-
|
|
199
171
|
if (sourceType === "git") {
|
|
200
172
|
return {
|
|
201
173
|
type: "git",
|
|
202
|
-
entry,
|
|
203
174
|
repo: source.repo,
|
|
204
175
|
ref: source.ref,
|
|
205
176
|
manifestPath: source.manifest_path
|
|
@@ -207,11 +178,9 @@ function resolveRegistrySource(name) {
|
|
|
207
178
|
}
|
|
208
179
|
|
|
209
180
|
const manifestPath = source.manifest_path || `plugins/${entry.name}/plugin.json`
|
|
210
|
-
const absolute = path.resolve(__dirname, "..", manifestPath)
|
|
211
181
|
return {
|
|
212
182
|
type: "path",
|
|
213
|
-
|
|
214
|
-
manifestPath: absolute
|
|
183
|
+
manifestPath: path.resolve(__dirname, "..", manifestPath)
|
|
215
184
|
}
|
|
216
185
|
}
|
|
217
186
|
|
|
@@ -227,10 +196,12 @@ function loadPluginManifest(ref, options = {}) {
|
|
|
227
196
|
if (directManifestPath && fs.existsSync(directManifestPath)) {
|
|
228
197
|
return {
|
|
229
198
|
manifest: parseManifestFile(directManifestPath),
|
|
199
|
+
manifestPath: directManifestPath,
|
|
230
200
|
resolvedFrom: {
|
|
231
201
|
type: "path",
|
|
232
202
|
manifest_path: directManifestPath
|
|
233
|
-
}
|
|
203
|
+
},
|
|
204
|
+
cleanup: noCleanup
|
|
234
205
|
}
|
|
235
206
|
}
|
|
236
207
|
|
|
@@ -261,11 +232,127 @@ function loadPluginManifest(ref, options = {}) {
|
|
|
261
232
|
|
|
262
233
|
return {
|
|
263
234
|
manifest: parseManifestFile(registrySource.manifestPath),
|
|
235
|
+
manifestPath: registrySource.manifestPath,
|
|
264
236
|
resolvedFrom: {
|
|
265
237
|
type: "registry",
|
|
266
238
|
name: ref,
|
|
267
239
|
manifest_path: registrySource.manifestPath
|
|
240
|
+
},
|
|
241
|
+
cleanup: noCleanup
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function parsePostInstallResult(stdout) {
|
|
246
|
+
const text = (stdout || "").trim()
|
|
247
|
+
if (!text) return null
|
|
248
|
+
try {
|
|
249
|
+
return JSON.parse(text)
|
|
250
|
+
} catch {
|
|
251
|
+
return { raw: text }
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function resolveHookScriptPath(manifestDir, script, kind) {
|
|
256
|
+
const scriptPath = path.resolve(manifestDir, script)
|
|
257
|
+
const normalizedBase = path.resolve(manifestDir) + path.sep
|
|
258
|
+
if (!scriptPath.startsWith(normalizedBase)) {
|
|
259
|
+
throw Object.assign(new Error(`Invalid ${kind} script path '${script}'`), {
|
|
260
|
+
code: 85,
|
|
261
|
+
type: "invalid_argument",
|
|
262
|
+
recoverable: false
|
|
263
|
+
})
|
|
264
|
+
}
|
|
265
|
+
if (!fs.existsSync(scriptPath)) {
|
|
266
|
+
throw Object.assign(new Error(`${kind} script not found: ${script}`), {
|
|
267
|
+
code: 92,
|
|
268
|
+
type: "resource_not_found",
|
|
269
|
+
recoverable: false
|
|
270
|
+
})
|
|
271
|
+
}
|
|
272
|
+
return scriptPath
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function runNodeHook(pluginName, kind, hook, scriptPath, env = {}) {
|
|
276
|
+
const result = spawnSync("node", [scriptPath], {
|
|
277
|
+
encoding: "utf-8",
|
|
278
|
+
timeout: hook.timeout_ms,
|
|
279
|
+
env: {
|
|
280
|
+
...process.env,
|
|
281
|
+
...env,
|
|
282
|
+
SUPERCLI_PLUGIN_NAME: pluginName,
|
|
283
|
+
SUPERCLI_PLUGIN_DIR: path.dirname(scriptPath)
|
|
268
284
|
}
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
if (result.error) {
|
|
288
|
+
throw Object.assign(new Error(`${kind} hook failed for '${pluginName}': ${result.error.message}`), {
|
|
289
|
+
code: 105,
|
|
290
|
+
type: "integration_error",
|
|
291
|
+
recoverable: true
|
|
292
|
+
})
|
|
293
|
+
}
|
|
294
|
+
if (result.status !== 0) {
|
|
295
|
+
throw Object.assign(new Error(`${kind} hook failed for '${pluginName}': ${(result.stderr || "").trim() || `exit ${result.status}`}`), {
|
|
296
|
+
code: 105,
|
|
297
|
+
type: "integration_error",
|
|
298
|
+
recoverable: true
|
|
299
|
+
})
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return parsePostInstallResult(result.stdout)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function runPostInstall(manifest, manifestPath) {
|
|
306
|
+
const hook = validateNodeHook(manifest.post_install, "post_install")
|
|
307
|
+
if (!hook) return null
|
|
308
|
+
const manifestDir = path.dirname(manifestPath)
|
|
309
|
+
const scriptPath = resolveHookScriptPath(manifestDir, hook.script, "post-install")
|
|
310
|
+
return runNodeHook(manifest.name, "Post-install", hook, scriptPath)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function serializeHook(manifestPath, hook, kind) {
|
|
314
|
+
const validHook = validateNodeHook(hook, kind)
|
|
315
|
+
if (!validHook) return null
|
|
316
|
+
const manifestDir = path.dirname(manifestPath)
|
|
317
|
+
const scriptPath = resolveHookScriptPath(manifestDir, validHook.script, kind.replace(/_/g, "-"))
|
|
318
|
+
return {
|
|
319
|
+
runtime: validHook.runtime,
|
|
320
|
+
timeout_ms: validHook.timeout_ms,
|
|
321
|
+
script_path: scriptPath,
|
|
322
|
+
script_name: path.basename(scriptPath),
|
|
323
|
+
script_source: fs.readFileSync(scriptPath, "utf-8")
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function runStoredHook(pluginName, kind, storedHook) {
|
|
328
|
+
if (!storedHook) return null
|
|
329
|
+
const runtime = storedHook.runtime || "node"
|
|
330
|
+
if (runtime !== "node") {
|
|
331
|
+
throw Object.assign(new Error(`Unsupported stored ${kind} runtime '${runtime}' for '${pluginName}'`), {
|
|
332
|
+
code: 85,
|
|
333
|
+
type: "invalid_argument",
|
|
334
|
+
recoverable: false
|
|
335
|
+
})
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (storedHook.script_path && fs.existsSync(storedHook.script_path)) {
|
|
339
|
+
return runNodeHook(pluginName, `Post-${kind}`, {
|
|
340
|
+
runtime,
|
|
341
|
+
timeout_ms: Number(storedHook.timeout_ms) || 15000
|
|
342
|
+
}, storedHook.script_path)
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "dcli-plugin-hook-"))
|
|
346
|
+
try {
|
|
347
|
+
const scriptName = storedHook.script_name || `${kind}.js`
|
|
348
|
+
const scriptPath = path.join(tmpDir, scriptName)
|
|
349
|
+
fs.writeFileSync(scriptPath, storedHook.script_source || "")
|
|
350
|
+
return runNodeHook(pluginName, `Post-${kind}`, {
|
|
351
|
+
runtime,
|
|
352
|
+
timeout_ms: Number(storedHook.timeout_ms) || 15000
|
|
353
|
+
}, scriptPath)
|
|
354
|
+
} finally {
|
|
355
|
+
fs.rmSync(tmpDir, { recursive: true, force: true })
|
|
269
356
|
}
|
|
270
357
|
}
|
|
271
358
|
|
|
@@ -306,8 +393,7 @@ function doctorPlugin(name) {
|
|
|
306
393
|
const checks = []
|
|
307
394
|
for (const check of (plugin.checks || [])) {
|
|
308
395
|
if (check && check.type === "binary" && check.name) {
|
|
309
|
-
|
|
310
|
-
checks.push({ type: "binary", ...result })
|
|
396
|
+
checks.push({ type: "binary", ...checkBinary(check.name) })
|
|
311
397
|
}
|
|
312
398
|
}
|
|
313
399
|
|
|
@@ -316,32 +402,15 @@ function doctorPlugin(name) {
|
|
|
316
402
|
for (const cmd of (plugin.commands || [])) {
|
|
317
403
|
const adapter = cmd.adapter || "(missing)"
|
|
318
404
|
adapterCounts[adapter] = (adapterCounts[adapter] || 0) + 1
|
|
319
|
-
|
|
320
405
|
if (!SUPPORTED_ADAPTERS.includes(adapter)) {
|
|
321
|
-
checks.push({
|
|
322
|
-
type: "policy",
|
|
323
|
-
ok: false,
|
|
324
|
-
message: `Command '${commandKey(cmd)}' uses unknown adapter '${adapter}'`
|
|
325
|
-
})
|
|
406
|
+
checks.push({ type: "policy", ok: false, message: `Command '${commandKey(cmd)}' uses unknown adapter '${adapter}'` })
|
|
326
407
|
}
|
|
327
|
-
|
|
328
408
|
const cfg = cmd.adapterConfig || {}
|
|
329
409
|
if (adapter === "shell") {
|
|
330
|
-
if (cfg.unsafe !== true) {
|
|
331
|
-
|
|
332
|
-
type: "policy",
|
|
333
|
-
ok: false,
|
|
334
|
-
message: `Shell command '${commandKey(cmd)}' must set adapterConfig.unsafe=true`
|
|
335
|
-
})
|
|
336
|
-
} else {
|
|
337
|
-
unsafeCommands += 1
|
|
338
|
-
}
|
|
410
|
+
if (cfg.unsafe !== true) checks.push({ type: "policy", ok: false, message: `Shell command '${commandKey(cmd)}' must set adapterConfig.unsafe=true` })
|
|
411
|
+
else unsafeCommands += 1
|
|
339
412
|
if (cfg.non_interactive === false) {
|
|
340
|
-
checks.push({
|
|
341
|
-
type: "policy",
|
|
342
|
-
ok: false,
|
|
343
|
-
message: `Shell command '${commandKey(cmd)}' cannot disable non_interactive`
|
|
344
|
-
})
|
|
413
|
+
checks.push({ type: "policy", ok: false, message: `Shell command '${commandKey(cmd)}' cannot disable non_interactive` })
|
|
345
414
|
}
|
|
346
415
|
}
|
|
347
416
|
}
|
|
@@ -378,95 +447,90 @@ function installPlugin(ref, options = {}) {
|
|
|
378
447
|
}
|
|
379
448
|
|
|
380
449
|
const loaded = loadPluginManifest(ref, options)
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
const existingByKey = {}
|
|
387
|
-
for (const cmd of currentCommands) {
|
|
388
|
-
existingByKey[commandKey(cmd)] = true
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
const ownerByKey = {}
|
|
392
|
-
for (const [pluginName, plugin] of Object.entries(lock.installed)) {
|
|
393
|
-
for (const cmd of (plugin.commands || [])) {
|
|
394
|
-
ownerByKey[commandKey(cmd)] = pluginName
|
|
395
|
-
}
|
|
396
|
-
}
|
|
450
|
+
try {
|
|
451
|
+
const manifest = loaded.manifest
|
|
452
|
+
const lock = readPluginsLock()
|
|
453
|
+
const existing = lock.installed[manifest.name]
|
|
454
|
+
const currentCommands = Array.isArray(options.currentCommands) ? options.currentCommands : []
|
|
397
455
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
const installedCommands = []
|
|
456
|
+
const existingByKey = {}
|
|
457
|
+
for (const cmd of currentCommands) existingByKey[commandKey(cmd)] = true
|
|
401
458
|
|
|
402
|
-
|
|
403
|
-
const
|
|
404
|
-
|
|
405
|
-
if ((!existingByKey[key] && !owner) || existingKeysForSamePlugin.has(key)) {
|
|
406
|
-
installedCommands.push(cmd)
|
|
407
|
-
continue
|
|
459
|
+
const ownerByKey = {}
|
|
460
|
+
for (const [pluginName, plugin] of Object.entries(lock.installed)) {
|
|
461
|
+
for (const cmd of (plugin.commands || [])) ownerByKey[commandKey(cmd)] = pluginName
|
|
408
462
|
}
|
|
409
463
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
464
|
+
const existingKeysForSamePlugin = new Set((existing && existing.commands ? existing.commands : []).map(commandKey))
|
|
465
|
+
const conflicts = []
|
|
466
|
+
const installedCommands = []
|
|
414
467
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
468
|
+
for (const cmd of manifest.commands) {
|
|
469
|
+
const key = commandKey(cmd)
|
|
470
|
+
const owner = ownerByKey[key]
|
|
471
|
+
if ((!existingByKey[key] && !owner) || existingKeysForSamePlugin.has(key)) {
|
|
419
472
|
installedCommands.push(cmd)
|
|
420
473
|
continue
|
|
421
474
|
}
|
|
422
|
-
|
|
423
|
-
|
|
475
|
+
if (onConflict === "skip") {
|
|
476
|
+
conflicts.push({ key, owner, action: "skipped" })
|
|
477
|
+
continue
|
|
478
|
+
}
|
|
479
|
+
if (onConflict === "replace") {
|
|
480
|
+
if (owner) {
|
|
481
|
+
lock.installed[owner].commands = (lock.installed[owner].commands || []).filter(c => commandKey(c) !== key)
|
|
482
|
+
conflicts.push({ key, owner, action: "replaced" })
|
|
483
|
+
installedCommands.push(cmd)
|
|
484
|
+
continue
|
|
485
|
+
}
|
|
486
|
+
conflicts.push({ key, owner: "base", action: "blocked" })
|
|
487
|
+
continue
|
|
488
|
+
}
|
|
489
|
+
conflicts.push({ key, owner, action: "blocked" })
|
|
424
490
|
}
|
|
425
491
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
suggestions: [
|
|
435
|
-
"Retry with --on-conflict skip",
|
|
436
|
-
"Retry with --on-conflict replace"
|
|
437
|
-
]
|
|
438
|
-
})
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
lock.installed[manifest.name] = {
|
|
442
|
-
name: manifest.name,
|
|
443
|
-
version: manifest.version || "0.0.0",
|
|
444
|
-
description: manifest.description || "",
|
|
445
|
-
source: manifest.source || ref,
|
|
446
|
-
resolved_from: loaded.resolvedFrom,
|
|
447
|
-
installed_at: new Date().toISOString(),
|
|
448
|
-
commands: installedCommands,
|
|
449
|
-
checks: manifest.checks || []
|
|
450
|
-
}
|
|
492
|
+
if (onConflict === "fail" && conflicts.length > 0) {
|
|
493
|
+
throw Object.assign(new Error(`Plugin install conflict for: ${conflicts.map(c => c.key).join(", ")}`), {
|
|
494
|
+
code: 85,
|
|
495
|
+
type: "invalid_argument",
|
|
496
|
+
recoverable: false,
|
|
497
|
+
suggestions: ["Retry with --on-conflict skip", "Retry with --on-conflict replace"]
|
|
498
|
+
})
|
|
499
|
+
}
|
|
451
500
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
501
|
+
lock.installed[manifest.name] = {
|
|
502
|
+
name: manifest.name,
|
|
503
|
+
version: manifest.version || "0.0.0",
|
|
504
|
+
description: manifest.description || "",
|
|
505
|
+
source: manifest.source || ref,
|
|
506
|
+
resolved_from: loaded.resolvedFrom,
|
|
507
|
+
installed_at: new Date().toISOString(),
|
|
508
|
+
commands: installedCommands,
|
|
509
|
+
checks: manifest.checks || [],
|
|
510
|
+
lifecycle_hooks: {
|
|
511
|
+
post_uninstall: serializeHook(loaded.manifestPath, manifest.post_uninstall, "post_uninstall")
|
|
512
|
+
}
|
|
513
|
+
}
|
|
456
514
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
515
|
+
const postInstall = runPostInstall(manifest, loaded.manifestPath)
|
|
516
|
+
writePluginsLock(lock)
|
|
517
|
+
return {
|
|
518
|
+
plugin: manifest.name,
|
|
519
|
+
version: manifest.version || "0.0.0",
|
|
520
|
+
installed_commands: installedCommands.length,
|
|
521
|
+
conflicts,
|
|
522
|
+
post_install: postInstall
|
|
523
|
+
}
|
|
524
|
+
} finally {
|
|
525
|
+
if (typeof loaded.cleanup === "function") loaded.cleanup()
|
|
464
526
|
}
|
|
465
527
|
}
|
|
466
528
|
|
|
467
529
|
function removePlugin(name) {
|
|
468
530
|
const lock = readPluginsLock()
|
|
469
|
-
|
|
531
|
+
const plugin = lock.installed[name]
|
|
532
|
+
if (!plugin) return false
|
|
533
|
+
runStoredHook(name, "uninstall", plugin.lifecycle_hooks && plugin.lifecycle_hooks.post_uninstall)
|
|
470
534
|
delete lock.installed[name]
|
|
471
535
|
writePluginsLock(lock)
|
|
472
536
|
return true
|
|
@@ -477,10 +541,6 @@ function getPlugin(name) {
|
|
|
477
541
|
return lock.installed[name] || null
|
|
478
542
|
}
|
|
479
543
|
|
|
480
|
-
function getPluginInstallGuidance(name) {
|
|
481
|
-
return PLUGIN_INSTALL_GUIDANCE[name] || null
|
|
482
|
-
}
|
|
483
|
-
|
|
484
544
|
module.exports = {
|
|
485
545
|
installPlugin,
|
|
486
546
|
removePlugin,
|
package/cli/skills.js
CHANGED
|
@@ -317,13 +317,23 @@ function handleSkillsCommand(options) {
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
if (subcommand === "list") {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
320
|
+
const useCatalog = flags.catalog === true || flags.catalog === "true" || !!flags.provider
|
|
321
|
+
if (flags["no-catalog"] || flags.catalog === false || flags.catalog === "false" || !useCatalog) {
|
|
322
|
+
const skills = listSkillsMetadata(config)
|
|
323
|
+
if (humanMode && !flags.json) {
|
|
324
|
+
console.log("\n ⚡ Skills (command-level only)\n")
|
|
325
|
+
outputHumanTable(skills, [
|
|
326
|
+
{ key: "name", label: "Name" },
|
|
327
|
+
{ key: "description", label: "Description" }
|
|
328
|
+
])
|
|
329
|
+
console.log("")
|
|
330
|
+
} else {
|
|
331
|
+
output({ skills })
|
|
332
|
+
}
|
|
323
333
|
return true
|
|
324
334
|
}
|
|
325
335
|
|
|
326
|
-
const skills =
|
|
336
|
+
const skills = listCatalogSkills({ provider: flags.provider })
|
|
327
337
|
if (humanMode && !flags.json) {
|
|
328
338
|
console.log("\n ⚡ Skills\n")
|
|
329
339
|
outputHumanTable(skills, [
|
|
@@ -332,7 +342,8 @@ function handleSkillsCommand(options) {
|
|
|
332
342
|
])
|
|
333
343
|
console.log("")
|
|
334
344
|
} else {
|
|
335
|
-
|
|
345
|
+
const index = readIndex() || {}
|
|
346
|
+
output({ skills, index: { updated_at: index.updated_at || null } })
|
|
336
347
|
}
|
|
337
348
|
return true
|
|
338
349
|
}
|