vskill 0.4.11 → 0.4.13

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.
@@ -0,0 +1,6 @@
1
+ interface MarketplaceSyncOpts {
2
+ dryRun?: boolean;
3
+ cwd?: string;
4
+ }
5
+ export declare function marketplaceCommand(subcommand: string, opts: MarketplaceSyncOpts): Promise<void>;
6
+ export {};
@@ -0,0 +1,88 @@
1
+ // ---------------------------------------------------------------------------
2
+ // vskill marketplace sync — sync .claude-plugin/marketplace.json from plugins/
3
+ // ---------------------------------------------------------------------------
4
+ import { readFileSync, writeFileSync, readdirSync, existsSync } from "node:fs";
5
+ import { join, resolve } from "node:path";
6
+ import { findProjectRoot } from "../utils/project-root.js";
7
+ import { syncMarketplace } from "../marketplace/index.js";
8
+ import { bold, green, yellow, dim, spinner, table } from "../utils/output.js";
9
+ export async function marketplaceCommand(subcommand, opts) {
10
+ if (subcommand !== "sync") {
11
+ console.error(`Unknown marketplace subcommand: ${subcommand}. Available: sync`);
12
+ process.exit(1);
13
+ return;
14
+ }
15
+ await syncCommand(opts);
16
+ }
17
+ async function syncCommand(opts) {
18
+ const root = opts.cwd
19
+ ? resolve(opts.cwd)
20
+ : (findProjectRoot(process.cwd()) ?? process.cwd());
21
+ const marketplacePath = join(root, ".claude-plugin", "marketplace.json");
22
+ if (!existsSync(marketplacePath)) {
23
+ console.error(`marketplace.json not found at ${marketplacePath}`);
24
+ process.exit(1);
25
+ return;
26
+ }
27
+ const spin = spinner("Scanning plugins...");
28
+ const pluginsDir = join(root, "plugins");
29
+ const localPlugins = [];
30
+ const skipped = [];
31
+ if (existsSync(pluginsDir)) {
32
+ for (const entry of readdirSync(pluginsDir, { withFileTypes: true })) {
33
+ if (!entry.isDirectory())
34
+ continue;
35
+ const pluginJsonPath = join(pluginsDir, entry.name, ".claude-plugin", "plugin.json");
36
+ if (!existsSync(pluginJsonPath)) {
37
+ skipped.push(entry.name);
38
+ continue;
39
+ }
40
+ try {
41
+ const meta = JSON.parse(readFileSync(pluginJsonPath, "utf-8"));
42
+ localPlugins.push({
43
+ name: entry.name,
44
+ description: meta.description,
45
+ version: meta.version,
46
+ category: meta.category,
47
+ });
48
+ }
49
+ catch {
50
+ skipped.push(entry.name);
51
+ }
52
+ }
53
+ }
54
+ spin.stop();
55
+ const manifestContent = readFileSync(marketplacePath, "utf-8");
56
+ let result;
57
+ try {
58
+ result = syncMarketplace(manifestContent, localPlugins);
59
+ }
60
+ catch {
61
+ console.error(`marketplace.json is malformed JSON at ${marketplacePath}`);
62
+ process.exit(1);
63
+ return;
64
+ }
65
+ const rows = [
66
+ ...result.added.map((n) => [green("+ added"), n]),
67
+ ...result.updated.map((n) => [yellow("~ updated"), n]),
68
+ ...result.unchanged.map((n) => [dim(" unchanged"), n]),
69
+ ];
70
+ if (rows.length > 0) {
71
+ console.log("\n" + table(["Status", "Plugin"], rows));
72
+ }
73
+ if (skipped.length > 0) {
74
+ console.log(yellow(`\nSkipped (no plugin.json): ${skipped.join(", ")}`));
75
+ }
76
+ if (opts.dryRun) {
77
+ console.log(dim("\n--dry-run: no changes written"));
78
+ return;
79
+ }
80
+ if (result.added.length > 0 || result.updated.length > 0) {
81
+ writeFileSync(marketplacePath, JSON.stringify(result.updatedManifest, null, 2) + "\n");
82
+ console.log(bold(`\n✓ marketplace.json updated (${result.added.length} added, ${result.updated.length} updated)`));
83
+ }
84
+ else {
85
+ console.log(dim("\n✓ marketplace.json already up to date"));
86
+ }
87
+ }
88
+ //# sourceMappingURL=marketplace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketplace.js","sourceRoot":"","sources":["../../src/commands/marketplace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,129 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ // ---------------------------------------------------------------------------
3
+ // Mocks — vi.hoisted for ESM compatibility
4
+ // ---------------------------------------------------------------------------
5
+ const mocks = vi.hoisted(() => ({
6
+ existsSync: vi.fn(),
7
+ readFileSync: vi.fn(),
8
+ writeFileSync: vi.fn(),
9
+ readdirSync: vi.fn(),
10
+ findProjectRoot: vi.fn(),
11
+ processExit: vi.fn(),
12
+ }));
13
+ vi.mock("node:fs", () => ({
14
+ existsSync: (...args) => mocks.existsSync(...args),
15
+ readFileSync: (...args) => mocks.readFileSync(...args),
16
+ writeFileSync: (...args) => mocks.writeFileSync(...args),
17
+ readdirSync: (...args) => mocks.readdirSync(...args),
18
+ }));
19
+ vi.mock("../utils/project-root.js", () => ({
20
+ findProjectRoot: (...args) => mocks.findProjectRoot(...args),
21
+ }));
22
+ vi.mock("../utils/output.js", () => ({
23
+ bold: (s) => s,
24
+ green: (s) => s,
25
+ red: (s) => s,
26
+ yellow: (s) => s,
27
+ dim: (s) => s,
28
+ cyan: (s) => s,
29
+ spinner: (_msg) => ({ stop: (_final) => { } }),
30
+ table: (headers, rows) => {
31
+ return [headers.join(" "), ...rows.map((r) => r.join(" "))].join("\n");
32
+ },
33
+ }));
34
+ // Capture process.exit calls without terminating the test runner
35
+ const originalExit = process.exit;
36
+ beforeEach(() => {
37
+ process.exit = mocks.processExit;
38
+ });
39
+ // ---------------------------------------------------------------------------
40
+ // Import module under test AFTER mocks
41
+ // ---------------------------------------------------------------------------
42
+ const { marketplaceCommand } = await import("./marketplace.js");
43
+ // ---------------------------------------------------------------------------
44
+ // Helpers
45
+ // ---------------------------------------------------------------------------
46
+ function makeMarketplaceJson(plugins = []) {
47
+ return JSON.stringify({
48
+ name: "vskill",
49
+ owner: { name: "Test Author" },
50
+ plugins: [
51
+ { name: "mobile", source: "./plugins/mobile", version: "2.3.0" },
52
+ ...plugins,
53
+ ],
54
+ });
55
+ }
56
+ function makeDirEntry(name, isDir = true) {
57
+ return { name, isDirectory: () => isDir };
58
+ }
59
+ // ---------------------------------------------------------------------------
60
+ // Tests
61
+ // ---------------------------------------------------------------------------
62
+ describe("marketplaceCommand", () => {
63
+ beforeEach(() => {
64
+ vi.clearAllMocks();
65
+ mocks.findProjectRoot.mockReturnValue("/fake/root");
66
+ process.exit = mocks.processExit;
67
+ });
68
+ it("writes updated marketplace.json when a new plugin is found", async () => {
69
+ mocks.existsSync.mockImplementation((p) => {
70
+ if (p.endsWith("marketplace.json"))
71
+ return true;
72
+ if (p.endsWith("plugins"))
73
+ return true;
74
+ if (p.endsWith("plugin.json"))
75
+ return true;
76
+ return false;
77
+ });
78
+ mocks.readdirSync.mockReturnValue([makeDirEntry("newplugin")]);
79
+ mocks.readFileSync.mockImplementation((p) => {
80
+ if (String(p).endsWith("marketplace.json"))
81
+ return makeMarketplaceJson();
82
+ // plugin.json for newplugin
83
+ return JSON.stringify({ name: "newplugin", description: "New one", version: "1.0.0" });
84
+ });
85
+ await marketplaceCommand("sync", {});
86
+ expect(mocks.writeFileSync).toHaveBeenCalledOnce();
87
+ const written = JSON.parse(mocks.writeFileSync.mock.calls[0][1]);
88
+ expect(written.plugins.map((p) => p.name)).toContain("newplugin");
89
+ });
90
+ it("does NOT write marketplace.json in --dry-run mode", async () => {
91
+ mocks.existsSync.mockReturnValue(true);
92
+ mocks.readdirSync.mockReturnValue([makeDirEntry("newplugin")]);
93
+ mocks.readFileSync.mockImplementation((p) => {
94
+ if (String(p).endsWith("marketplace.json"))
95
+ return makeMarketplaceJson();
96
+ return JSON.stringify({ name: "newplugin", version: "1.0.0" });
97
+ });
98
+ await marketplaceCommand("sync", { dryRun: true });
99
+ expect(mocks.writeFileSync).not.toHaveBeenCalled();
100
+ });
101
+ it("skips a plugin dir that has no plugin.json and continues", async () => {
102
+ mocks.existsSync.mockImplementation((p) => {
103
+ if (p.endsWith("marketplace.json"))
104
+ return true;
105
+ if (p.endsWith("plugins"))
106
+ return true;
107
+ // plugin.json does not exist
108
+ if (p.endsWith("plugin.json"))
109
+ return false;
110
+ return false;
111
+ });
112
+ mocks.readdirSync.mockReturnValue([makeDirEntry("orphan")]);
113
+ mocks.readFileSync.mockReturnValue(makeMarketplaceJson());
114
+ // Should not throw
115
+ await marketplaceCommand("sync", {});
116
+ // writeFileSync should NOT be called since nothing changed
117
+ expect(mocks.writeFileSync).not.toHaveBeenCalled();
118
+ });
119
+ it("exits 1 when marketplace.json is not found", async () => {
120
+ mocks.existsSync.mockReturnValue(false);
121
+ await marketplaceCommand("sync", {});
122
+ expect(mocks.processExit).toHaveBeenCalledWith(1);
123
+ });
124
+ it("exits 1 for unknown subcommand", async () => {
125
+ await marketplaceCommand("unknown-cmd", {});
126
+ expect(mocks.processExit).toHaveBeenCalledWith(1);
127
+ });
128
+ });
129
+ //# sourceMappingURL=marketplace.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketplace.test.js","sourceRoot":"","sources":["../../src/commands/marketplace.test.ts"],"names":[],"mappings":"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"}