@vibe-agent-toolkit/cli 0.1.22-rc.3 → 0.1.23-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/commands/claude/index.d.ts.map +1 -1
  2. package/dist/commands/claude/index.js +5 -2
  3. package/dist/commands/claude/index.js.map +1 -1
  4. package/dist/commands/claude/marketplace/changelog-utils.d.ts +22 -0
  5. package/dist/commands/claude/marketplace/changelog-utils.d.ts.map +1 -0
  6. package/dist/commands/claude/marketplace/changelog-utils.js +47 -0
  7. package/dist/commands/claude/marketplace/changelog-utils.js.map +1 -0
  8. package/dist/commands/claude/marketplace/git-publish.d.ts +37 -0
  9. package/dist/commands/claude/marketplace/git-publish.d.ts.map +1 -0
  10. package/dist/commands/claude/marketplace/git-publish.js +143 -0
  11. package/dist/commands/claude/marketplace/git-publish.js.map +1 -0
  12. package/dist/commands/claude/marketplace/index.d.ts +3 -0
  13. package/dist/commands/claude/marketplace/index.d.ts.map +1 -0
  14. package/dist/commands/claude/marketplace/index.js +25 -0
  15. package/dist/commands/claude/marketplace/index.js.map +1 -0
  16. package/dist/commands/claude/marketplace/license-utils.d.ts +37 -0
  17. package/dist/commands/claude/marketplace/license-utils.d.ts.map +1 -0
  18. package/dist/commands/claude/marketplace/license-utils.js +123 -0
  19. package/dist/commands/claude/marketplace/license-utils.js.map +1 -0
  20. package/dist/commands/claude/marketplace/publish-tree.d.ts +38 -0
  21. package/dist/commands/claude/marketplace/publish-tree.d.ts.map +1 -0
  22. package/dist/commands/claude/marketplace/publish-tree.js +64 -0
  23. package/dist/commands/claude/marketplace/publish-tree.js.map +1 -0
  24. package/dist/commands/claude/marketplace/publish.d.ts +18 -0
  25. package/dist/commands/claude/marketplace/publish.d.ts.map +1 -0
  26. package/dist/commands/claude/marketplace/publish.js +196 -0
  27. package/dist/commands/claude/marketplace/publish.js.map +1 -0
  28. package/dist/commands/claude/marketplace/validate.d.ts +13 -0
  29. package/dist/commands/claude/marketplace/validate.d.ts.map +1 -0
  30. package/dist/commands/claude/marketplace/validate.js +169 -0
  31. package/dist/commands/claude/marketplace/validate.js.map +1 -0
  32. package/dist/commands/claude/org/skills.d.ts +0 -3
  33. package/dist/commands/claude/org/skills.d.ts.map +1 -1
  34. package/dist/commands/claude/org/skills.js +313 -25
  35. package/dist/commands/claude/org/skills.js.map +1 -1
  36. package/dist/commands/claude/plugin/build.js +30 -5
  37. package/dist/commands/claude/plugin/build.js.map +1 -1
  38. package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
  39. package/dist/commands/skills/skill-discovery.js +1 -0
  40. package/dist/commands/skills/skill-discovery.js.map +1 -1
  41. package/dist/commands/verify.d.ts +1 -0
  42. package/dist/commands/verify.d.ts.map +1 -1
  43. package/dist/commands/verify.js +36 -5
  44. package/dist/commands/verify.js.map +1 -1
  45. package/dist/utils/skill-discovery.d.ts.map +1 -1
  46. package/dist/utils/skill-discovery.js +1 -0
  47. package/dist/utils/skill-discovery.js.map +1 -1
  48. package/package.json +11 -11
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/claude/index.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,mBAAmB,IAAI,OAAO,CAyB7C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/claude/index.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,mBAAmB,IAAI,OAAO,CA2B7C"}
@@ -6,18 +6,20 @@
6
6
  * Org administration: vat claude org ... (coming in this release)
7
7
  */
8
8
  import { Command } from 'commander';
9
+ import { createMarketplaceCommand } from './marketplace/index.js';
9
10
  import { createOrgCommand } from './org/index.js';
10
11
  import { createPluginCommand } from './plugin/index.js';
11
12
  export function createClaudeCommand() {
12
13
  const command = new Command('claude');
13
14
  command
14
- .description('Manage Claude Code plugins and org administration')
15
+ .description('Manage Claude Code plugins, marketplaces, and org administration')
15
16
  .helpCommand(false)
16
17
  .addHelpText('after', `
17
18
  Description:
18
- Gateway to the Claude ecosystem — local plugin management and org administration.
19
+ Gateway to the Claude ecosystem — plugin management, marketplaces, and org administration.
19
20
 
20
21
  Plugin management: install, list, and uninstall skill packages in ~/.claude/
22
+ Marketplace: validate and publish marketplace directories
21
23
  Org administration: manage users, workspaces, API keys, and usage via Admin API
22
24
 
23
25
  Examples:
@@ -28,6 +30,7 @@ Examples:
28
30
  $ vat claude org usage --from 2025-01-01T00:00:00Z # Token usage report
29
31
  `);
30
32
  command.addCommand(createPluginCommand());
33
+ command.addCommand(createMarketplaceCommand());
31
34
  command.addCommand(createOrgCommand());
32
35
  return command;
33
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/claude/index.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,UAAU,mBAAmB;IACjC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEtC,OAAO;SACJ,WAAW,CAAC,mDAAmD,CAAC;SAChE,WAAW,CAAC,KAAK,CAAC;SAClB,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;CAazB,CAAC,CAAC;IAED,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAEvC,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/claude/index.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,UAAU,mBAAmB;IACjC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEtC,OAAO;SACJ,WAAW,CAAC,kEAAkE,CAAC;SAC/E,WAAW,CAAC,KAAK,CAAC;SAClB,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;CAczB,CAAC,CAAC;IAED,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,UAAU,CAAC,wBAAwB,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAEvC,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Changelog parsing and stamping utilities for marketplace publish.
3
+ *
4
+ * Follows Keep a Changelog format: https://keepachangelog.com/
5
+ * Parses [Unreleased] section and stamps it with version + date on publish.
6
+ */
7
+ /**
8
+ * Extract the content of the [Unreleased] section from a changelog string.
9
+ * Returns the content between [Unreleased] heading and the next version heading (or EOF).
10
+ * Returns empty string if no [Unreleased] section or it has no content.
11
+ */
12
+ export declare function parseUnreleasedSection(changelog: string): string;
13
+ /**
14
+ * Replace `## [Unreleased]` with `## [version] - date` in changelog text.
15
+ * Returns the full modified changelog string.
16
+ */
17
+ export declare function stampChangelog(changelog: string, version: string, date: string): string;
18
+ /**
19
+ * Read a changelog file from disk.
20
+ */
21
+ export declare function readChangelog(filePath: string, baseDir: string): string;
22
+ //# sourceMappingURL=changelog-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changelog-utils.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/changelog-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAehE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAIvE"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Changelog parsing and stamping utilities for marketplace publish.
3
+ *
4
+ * Follows Keep a Changelog format: https://keepachangelog.com/
5
+ * Parses [Unreleased] section and stamps it with version + date on publish.
6
+ */
7
+ import { readFileSync } from 'node:fs';
8
+ import { resolve } from 'node:path';
9
+ /**
10
+ * Regex to match the [Unreleased] heading (case-insensitive).
11
+ */
12
+ const UNRELEASED_HEADING_RE = /^## \[unreleased\]\s*$/im;
13
+ const VERSION_HEADING_RE = /^## \[\d+\.\d+/m;
14
+ /**
15
+ * Extract the content of the [Unreleased] section from a changelog string.
16
+ * Returns the content between [Unreleased] heading and the next version heading (or EOF).
17
+ * Returns empty string if no [Unreleased] section or it has no content.
18
+ */
19
+ export function parseUnreleasedSection(changelog) {
20
+ const unreleasedMatch = UNRELEASED_HEADING_RE.exec(changelog);
21
+ if (!unreleasedMatch) {
22
+ return '';
23
+ }
24
+ const startIndex = unreleasedMatch.index + unreleasedMatch[0].length;
25
+ const rest = changelog.slice(startIndex);
26
+ const nextVersionMatch = VERSION_HEADING_RE.exec(rest);
27
+ const content = nextVersionMatch
28
+ ? rest.slice(0, nextVersionMatch.index)
29
+ : rest;
30
+ return content.trimEnd();
31
+ }
32
+ /**
33
+ * Replace `## [Unreleased]` with `## [version] - date` in changelog text.
34
+ * Returns the full modified changelog string.
35
+ */
36
+ export function stampChangelog(changelog, version, date) {
37
+ return changelog.replace(UNRELEASED_HEADING_RE, `## [${version}] - ${date}`);
38
+ }
39
+ /**
40
+ * Read a changelog file from disk.
41
+ */
42
+ export function readChangelog(filePath, baseDir) {
43
+ const resolved = resolve(baseDir, filePath);
44
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- path from validated config
45
+ return readFileSync(resolved, 'utf-8');
46
+ }
47
+ //# sourceMappingURL=changelog-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changelog-utils.js","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/changelog-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;GAEG;AACH,MAAM,qBAAqB,GAAG,0BAA0B,CAAC;AACzD,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AAE7C;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAiB;IACtD,MAAM,eAAe,GAAG,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9D,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAAC,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACrE,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAEzC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,gBAAgB;QAC9B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,KAAK,CAAC;QACvC,CAAC,CAAC,IAAI,CAAC;IAET,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,OAAe,EAAE,IAAY;IAC7E,OAAO,SAAS,CAAC,OAAO,CAAC,qBAAqB,EAAE,OAAO,OAAO,OAAO,IAAI,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,OAAe;IAC7D,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC5C,iGAAiG;IACjG,OAAO,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Git operations for marketplace publish.
3
+ *
4
+ * Handles: fetch/create orphan branch, stage tree, squash commit, push.
5
+ * Uses child_process.spawnSync for git commands (no external dependencies).
6
+ */
7
+ import type { Logger } from '../../../utils/logger.js';
8
+ export interface CommitMetadata {
9
+ sourceRepo?: string;
10
+ commitRange?: string;
11
+ }
12
+ export interface PublishGitOptions {
13
+ publishDir: string;
14
+ branch: string;
15
+ remote: string;
16
+ commitMessage: string;
17
+ force: boolean;
18
+ dryRun: boolean;
19
+ noPush: boolean;
20
+ logger: Logger;
21
+ }
22
+ /**
23
+ * Format a commit message for marketplace publish.
24
+ */
25
+ export declare function createCommitMessage(version: string, changelogDelta: string, metadata?: CommitMetadata): string;
26
+ /**
27
+ * Publish the composed tree to a git branch.
28
+ *
29
+ * Strategy:
30
+ * 1. Create a temp repo
31
+ * 2. Init it and add the publish tree content
32
+ * 3. Fetch the existing branch (if any) from the remote
33
+ * 4. Create a new commit on top of the branch history
34
+ * 5. Deliver: dry-run (preview), no-push (local branch), or push to remote
35
+ */
36
+ export declare function publishToGitBranch(options: PublishGitOptions): Promise<void>;
37
+ //# sourceMappingURL=git-publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-publish.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/git-publish.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,cAAc,GACxB,MAAM,CAeR;AAsFD;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDlF"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Git operations for marketplace publish.
3
+ *
4
+ * Handles: fetch/create orphan branch, stage tree, squash commit, push.
5
+ * Uses child_process.spawnSync for git commands (no external dependencies).
6
+ */
7
+ import { spawnSync } from 'node:child_process';
8
+ import { cpSync, mkdtempSync, rmSync } from 'node:fs';
9
+ import { join } from 'node:path';
10
+ import { normalizedTmpdir } from '@vibe-agent-toolkit/utils';
11
+ /**
12
+ * Format a commit message for marketplace publish.
13
+ */
14
+ export function createCommitMessage(version, changelogDelta, metadata) {
15
+ const lines = [`publish v${version}`];
16
+ if (changelogDelta) {
17
+ lines.push('', changelogDelta);
18
+ }
19
+ if (metadata?.sourceRepo) {
20
+ lines.push('', `Source: ${metadata.sourceRepo}`);
21
+ if (metadata.commitRange) {
22
+ lines.push(`Commits: ${metadata.commitRange}`);
23
+ }
24
+ }
25
+ return lines.join('\n');
26
+ }
27
+ /**
28
+ * Execute a git command and return the result.
29
+ * Throws on non-zero exit code unless allowFailure is true.
30
+ */
31
+ function git(args, options) {
32
+ // eslint-disable-next-line sonarjs/no-os-command-from-path -- git is a standard system command
33
+ const result = spawnSync('git', args, {
34
+ cwd: options.cwd,
35
+ encoding: 'utf-8',
36
+ stdio: ['pipe', 'pipe', 'pipe'],
37
+ timeout: options.timeout,
38
+ });
39
+ const status = result.status ?? 1;
40
+ if (status !== 0 && !options.allowFailure) {
41
+ throw new Error(`git ${args.join(' ')} failed (exit ${status}):\n${result.stderr ?? ''}`);
42
+ }
43
+ return {
44
+ stdout: (result.stdout ?? '').trim(),
45
+ stderr: (result.stderr ?? '').trim(),
46
+ status,
47
+ };
48
+ }
49
+ /**
50
+ * Resolve a remote name (e.g., "origin") to a URL.
51
+ * If the value already looks like a URL, returns it as-is.
52
+ */
53
+ function resolveRemoteUrl(remote, cwd) {
54
+ if (remote.includes('/') || remote.includes(':')) {
55
+ return remote;
56
+ }
57
+ const urlResult = git(['remote', 'get-url', remote], { cwd, allowFailure: true });
58
+ if (urlResult.status === 0) {
59
+ return urlResult.stdout;
60
+ }
61
+ throw new Error(`Git remote "${remote}" not found. Configure it or use a full URL.`);
62
+ }
63
+ /**
64
+ * Deliver the commit: dry-run (show info), no-push (local branch), or push to remote.
65
+ */
66
+ function deliverCommit(tmpRepo, cwd, options, remoteUrl) {
67
+ const { branch, remote, force, dryRun, noPush, logger } = options;
68
+ if (dryRun) {
69
+ logger.info(' [dry-run] Would push to remote. Commit staged at:');
70
+ logger.info(` ${tmpRepo}`);
71
+ const diffStat = git(['diff', '--stat', 'HEAD~1..HEAD'], { cwd: tmpRepo, allowFailure: true });
72
+ if (diffStat.status === 0) {
73
+ logger.info(` Changes:\n${diffStat.stdout}`);
74
+ }
75
+ return;
76
+ }
77
+ if (noPush) {
78
+ const fetchSpec = force
79
+ ? `+refs/heads/${branch}:refs/heads/${branch}`
80
+ : `refs/heads/${branch}:refs/heads/${branch}`;
81
+ git(['fetch', tmpRepo, fetchSpec], { cwd });
82
+ logger.info(` Created local branch "${branch}" (not pushed)`);
83
+ logger.info(` To push later: git push ${remote} ${branch}`);
84
+ return;
85
+ }
86
+ const pushArgs = ['push', remoteUrl, `${branch}:${branch}`];
87
+ if (force) {
88
+ pushArgs.splice(1, 0, '--force');
89
+ }
90
+ git(pushArgs, { cwd: tmpRepo });
91
+ logger.info(` Pushed to ${remoteUrl} branch ${branch}`);
92
+ }
93
+ /**
94
+ * Publish the composed tree to a git branch.
95
+ *
96
+ * Strategy:
97
+ * 1. Create a temp repo
98
+ * 2. Init it and add the publish tree content
99
+ * 3. Fetch the existing branch (if any) from the remote
100
+ * 4. Create a new commit on top of the branch history
101
+ * 5. Deliver: dry-run (preview), no-push (local branch), or push to remote
102
+ */
103
+ export async function publishToGitBranch(options) {
104
+ const { publishDir, branch, commitMessage, force, dryRun, logger } = options;
105
+ const cwd = process.cwd();
106
+ const remoteUrl = resolveRemoteUrl(options.remote, cwd);
107
+ logger.info(` Remote: ${remoteUrl}`);
108
+ logger.info(` Branch: ${branch}`);
109
+ const tmpRepo = mkdtempSync(join(normalizedTmpdir(), 'vat-marketplace-publish-'));
110
+ logger.debug(` Staging repo: ${tmpRepo}`);
111
+ try {
112
+ git(['init', '-b', branch], { cwd: tmpRepo });
113
+ git(['config', 'user.email', 'vat-publish@localhost'], { cwd: tmpRepo });
114
+ git(['config', 'user.name', 'vat marketplace publish'], { cwd: tmpRepo });
115
+ // Try to fetch existing branch history (skip for dry-run — commit parent doesn't matter)
116
+ if (!dryRun) {
117
+ const fetchResult = git(['fetch', remoteUrl, `${branch}:${branch}`], { cwd: tmpRepo, allowFailure: true, timeout: 30_000 });
118
+ if (fetchResult.status === 0 && !force) {
119
+ git(['reset', '--soft', branch], { cwd: tmpRepo });
120
+ }
121
+ }
122
+ // Copy publish tree content into temp repo
123
+ cpSync(publishDir, tmpRepo, { recursive: true });
124
+ git(['add', '-A'], { cwd: tmpRepo });
125
+ // Check if there are changes to commit
126
+ const diffResult = git(['diff', '--cached', '--quiet'], { cwd: tmpRepo, allowFailure: true });
127
+ if (diffResult.status === 0) {
128
+ logger.info(' No changes to publish (tree is identical to current branch)');
129
+ return;
130
+ }
131
+ git(['commit', '-m', commitMessage], { cwd: tmpRepo });
132
+ const log = git(['log', '--oneline', '-1'], { cwd: tmpRepo });
133
+ logger.info(` Commit: ${log.stdout}`);
134
+ deliverCommit(tmpRepo, cwd, options, remoteUrl);
135
+ }
136
+ finally {
137
+ // Keep temp repo for dry-run so user can inspect
138
+ if (!dryRun) {
139
+ rmSync(tmpRepo, { recursive: true, force: true });
140
+ }
141
+ }
142
+ }
143
+ //# sourceMappingURL=git-publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-publish.js","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/git-publish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createMarketplaceCommand(): Command;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,wBAAwB,IAAI,OAAO,CAuBlD"}
@@ -0,0 +1,25 @@
1
+ import { Command } from 'commander';
2
+ import { createMarketplacePublishCommand } from './publish.js';
3
+ import { createMarketplaceValidateCommand } from './validate.js';
4
+ export function createMarketplaceCommand() {
5
+ const command = new Command('marketplace');
6
+ command
7
+ .description('Validate and publish Claude plugin marketplaces')
8
+ .helpCommand(false)
9
+ .addHelpText('after', `
10
+ Description:
11
+ Standalone marketplace validation and publishing.
12
+
13
+ validate: Strict validation of a marketplace directory (works without config)
14
+ publish: Push built marketplace to a Git branch for distribution
15
+
16
+ Example:
17
+ $ vat claude marketplace validate . # Validate current directory
18
+ $ vat claude marketplace publish # Publish to claude-marketplace branch
19
+ $ vat claude marketplace publish --dry-run # Preview publish without pushing
20
+ `);
21
+ command.addCommand(createMarketplaceValidateCommand());
22
+ command.addCommand(createMarketplacePublishCommand());
23
+ return command;
24
+ }
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,gCAAgC,EAAE,MAAM,eAAe,CAAC;AAEjE,MAAM,UAAU,wBAAwB;IACtC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAE3C,OAAO;SACJ,WAAW,CAAC,iDAAiD,CAAC;SAC9D,WAAW,CAAC,KAAK,CAAC;SAClB,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;CAWzB,CAAC,CAAC;IAED,OAAO,CAAC,UAAU,CAAC,gCAAgC,EAAE,CAAC,CAAC;IACvD,OAAO,CAAC,UAAU,CAAC,+BAA+B,EAAE,CAAC,CAAC;IAEtD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * License resolution utilities for marketplace publish.
3
+ *
4
+ * Handles SPDX shortcut identifiers (e.g., "mit" → full MIT license text)
5
+ * and file path references (e.g., "./LICENSE" → copy as-is).
6
+ */
7
+ /**
8
+ * Check if a license value looks like a file path.
9
+ *
10
+ * A value is treated as a file path if it contains a `/` or has a dot that
11
+ * looks like a file extension (dot followed by a non-digit, e.g. `.txt`, `.md`).
12
+ * Version-style dots in SPDX identifiers (e.g. `apache-2.0`, `gpl-3.0`) are
13
+ * NOT treated as file-path indicators.
14
+ */
15
+ export declare function isFilePath(value: string): boolean;
16
+ /**
17
+ * Check if a value is a known SPDX license identifier (case-insensitive).
18
+ */
19
+ export declare function isSpdxIdentifier(value: string): boolean;
20
+ /**
21
+ * Read a license file from disk.
22
+ */
23
+ export declare function readLicenseFile(filePath: string, baseDir: string): string;
24
+ /**
25
+ * Generate standard license text for a known SPDX identifier.
26
+ */
27
+ export declare function generateLicenseText(spdxId: string, ownerName: string, year: number): string;
28
+ /**
29
+ * Resolve a license config value to LICENSE file content.
30
+ *
31
+ * @param licenseValue - SPDX identifier or file path from config
32
+ * @param ownerName - Owner name for generated license text
33
+ * @param baseDir - Base directory for resolving file paths
34
+ * @returns License text content
35
+ */
36
+ export declare function resolveLicense(licenseValue: string, ownerName: string, baseDir: string): string;
37
+ //# sourceMappingURL=license-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license-utils.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/license-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIjD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAIzE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAqD3F;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAa/F"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * License resolution utilities for marketplace publish.
3
+ *
4
+ * Handles SPDX shortcut identifiers (e.g., "mit" → full MIT license text)
5
+ * and file path references (e.g., "./LICENSE" → copy as-is).
6
+ */
7
+ import { readFileSync } from 'node:fs';
8
+ import { resolve } from 'node:path';
9
+ /** Known SPDX identifiers (lowercase). Extend as needed. */
10
+ const KNOWN_SPDX_IDS = new Set([
11
+ 'mit',
12
+ 'apache-2.0',
13
+ 'gpl-2.0',
14
+ 'gpl-3.0',
15
+ 'lgpl-2.1',
16
+ 'lgpl-3.0',
17
+ 'bsd-2-clause',
18
+ 'bsd-3-clause',
19
+ 'isc',
20
+ 'mpl-2.0',
21
+ 'unlicense',
22
+ ]);
23
+ /**
24
+ * Check if a license value looks like a file path.
25
+ *
26
+ * A value is treated as a file path if it contains a `/` or has a dot that
27
+ * looks like a file extension (dot followed by a non-digit, e.g. `.txt`, `.md`).
28
+ * Version-style dots in SPDX identifiers (e.g. `apache-2.0`, `gpl-3.0`) are
29
+ * NOT treated as file-path indicators.
30
+ */
31
+ export function isFilePath(value) {
32
+ if (value.includes('/'))
33
+ return true;
34
+ // Match a dot followed by a non-digit character — file extension pattern
35
+ return /\.[^\d]/.test(value);
36
+ }
37
+ /**
38
+ * Check if a value is a known SPDX license identifier (case-insensitive).
39
+ */
40
+ export function isSpdxIdentifier(value) {
41
+ return KNOWN_SPDX_IDS.has(value.toLowerCase());
42
+ }
43
+ /**
44
+ * Read a license file from disk.
45
+ */
46
+ export function readLicenseFile(filePath, baseDir) {
47
+ const resolved = resolve(baseDir, filePath);
48
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- path from validated config
49
+ return readFileSync(resolved, 'utf-8');
50
+ }
51
+ /**
52
+ * Generate standard license text for a known SPDX identifier.
53
+ */
54
+ export function generateLicenseText(spdxId, ownerName, year) {
55
+ const id = spdxId.toLowerCase();
56
+ switch (id) {
57
+ case 'mit':
58
+ return `MIT License
59
+
60
+ Copyright (c) ${year} ${ownerName}
61
+
62
+ Permission is hereby granted, free of charge, to any person obtaining a copy
63
+ of this software and associated documentation files (the "Software"), to deal
64
+ in the Software without restriction, including without limitation the rights
65
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
66
+ copies of the Software, and to permit persons to whom the Software is
67
+ furnished to do so, subject to the following conditions:
68
+
69
+ The above copyright notice and this permission notice shall be included in all
70
+ copies or substantial portions of the Software.
71
+
72
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
73
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
74
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
75
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
76
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
77
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
78
+ SOFTWARE.
79
+ `;
80
+ case 'apache-2.0':
81
+ return `Copyright ${year} ${ownerName}
82
+
83
+ Licensed under the Apache License, Version 2.0 (the "License");
84
+ you may not use this file except in compliance with the License.
85
+ You may obtain a copy of the License at
86
+
87
+ http://www.apache.org/licenses/LICENSE-2.0
88
+
89
+ Unless required by applicable law or agreed to in writing, software
90
+ distributed under the License is distributed on an "AS IS" BASIS,
91
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
92
+ See the License for the specific language governing permissions and
93
+ limitations under the License.
94
+ `;
95
+ default:
96
+ if (!KNOWN_SPDX_IDS.has(id)) {
97
+ throw new Error(`Unknown SPDX license identifier: "${spdxId}". Use a file path instead.`);
98
+ }
99
+ return `This software is licensed under the ${spdxId} license.
100
+
101
+ Copyright (c) ${year} ${ownerName}
102
+ `;
103
+ }
104
+ }
105
+ /**
106
+ * Resolve a license config value to LICENSE file content.
107
+ *
108
+ * @param licenseValue - SPDX identifier or file path from config
109
+ * @param ownerName - Owner name for generated license text
110
+ * @param baseDir - Base directory for resolving file paths
111
+ * @returns License text content
112
+ */
113
+ export function resolveLicense(licenseValue, ownerName, baseDir) {
114
+ if (isFilePath(licenseValue)) {
115
+ return readLicenseFile(licenseValue, baseDir);
116
+ }
117
+ if (!isSpdxIdentifier(licenseValue)) {
118
+ throw new Error(`"${licenseValue}" is neither a known SPDX identifier nor a file path. ` +
119
+ `Use a known identifier (mit, apache-2.0, etc.) or a file path (./LICENSE).`);
120
+ }
121
+ return generateLicenseText(licenseValue, ownerName, new Date().getFullYear());
122
+ }
123
+ //# sourceMappingURL=license-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license-utils.js","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/license-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,4DAA4D;AAC5D,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC7B,KAAK;IACL,YAAY;IACZ,SAAS;IACT,SAAS;IACT,UAAU;IACV,UAAU;IACV,cAAc;IACd,cAAc;IACd,KAAK;IACL,SAAS;IACT,WAAW;CACZ,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,yEAAyE;IACzE,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,OAAe;IAC/D,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC5C,iGAAiG;IACjG,OAAO,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,SAAiB,EAAE,IAAY;IACjF,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAEhC,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,KAAK;YACR,OAAO;;gBAEG,IAAI,IAAI,SAAS;;;;;;;;;;;;;;;;;;;CAmBhC,CAAC;QAEE,KAAK,YAAY;YACf,OAAO,aAAa,IAAI,IAAI,SAAS;;;;;;;;;;;;;CAa1C,CAAC;QAEE;YACE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,qCAAqC,MAAM,6BAA6B,CAAC,CAAC;YAC5F,CAAC;YACD,OAAO,uCAAuC,MAAM;;gBAE1C,IAAI,IAAI,SAAS;CAChC,CAAC;IACA,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,YAAoB,EAAE,SAAiB,EAAE,OAAe;IACrF,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,OAAO,eAAe,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACb,IAAI,YAAY,wDAAwD;YACtE,4EAA4E,CAC/E,CAAC;IACJ,CAAC;IAED,OAAO,mBAAmB,CAAC,YAAY,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AAChF,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Compose a publish tree from build output + metadata files.
3
+ *
4
+ * Takes the marketplace artifacts from dist/.claude/plugins/marketplaces/<name>/
5
+ * and combines them with CHANGELOG.md, README.md, and LICENSE into a clean
6
+ * directory ready to be committed to the publish branch.
7
+ */
8
+ export interface ChangelogOptions {
9
+ sourcePath: string;
10
+ }
11
+ export interface ReadmeOptions {
12
+ sourcePath: string;
13
+ }
14
+ export type LicenseOptions = {
15
+ type: 'spdx';
16
+ value: string;
17
+ ownerName: string;
18
+ } | {
19
+ type: 'file';
20
+ filePath: string;
21
+ };
22
+ export interface ComposeOptions {
23
+ marketplaceName: string;
24
+ configDir: string;
25
+ outputDir: string;
26
+ version: string;
27
+ date: string;
28
+ changelog?: ChangelogOptions;
29
+ readme?: ReadmeOptions;
30
+ license?: LicenseOptions;
31
+ }
32
+ export interface ComposeResult {
33
+ version: string;
34
+ changelogDelta: string;
35
+ files: string[];
36
+ }
37
+ export declare function composePublishTree(options: ComposeOptions): Promise<ComposeResult>;
38
+ //# sourceMappingURL=publish-tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-tree.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/publish-tree.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,MAAM,WAAW,cAAc;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAiExF"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Compose a publish tree from build output + metadata files.
3
+ *
4
+ * Takes the marketplace artifacts from dist/.claude/plugins/marketplaces/<name>/
5
+ * and combines them with CHANGELOG.md, README.md, and LICENSE into a clean
6
+ * directory ready to be committed to the publish branch.
7
+ */
8
+ import { existsSync, readFileSync } from 'node:fs';
9
+ import { cp, writeFile } from 'node:fs/promises';
10
+ import { join, resolve } from 'node:path';
11
+ import { parseUnreleasedSection, readChangelog, stampChangelog } from './changelog-utils.js';
12
+ import { generateLicenseText, readLicenseFile } from './license-utils.js';
13
+ export async function composePublishTree(options) {
14
+ const { marketplaceName, configDir, outputDir, version, date } = options;
15
+ const files = [];
16
+ let changelogDelta = '';
17
+ // 1. Verify build output exists
18
+ const buildDir = join(configDir, 'dist', '.claude', 'plugins', 'marketplaces', marketplaceName);
19
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated config
20
+ if (!existsSync(buildDir)) {
21
+ throw new Error(`Marketplace build output not found at ${buildDir}. Run "vat build" first.`);
22
+ }
23
+ // 2. Copy marketplace artifacts to output
24
+ await cp(buildDir, outputDir, { recursive: true });
25
+ files.push('.claude-plugin/marketplace.json', 'plugins/');
26
+ // 3. Process changelog
27
+ if (options.changelog) {
28
+ const rawChangelog = readChangelog(options.changelog.sourcePath, configDir);
29
+ const unreleased = parseUnreleasedSection(rawChangelog);
30
+ if (unreleased.trim() === '') {
31
+ throw new Error(`Changelog "${options.changelog.sourcePath}" has an empty [Unreleased] section. ` +
32
+ `Add release notes before publishing.`);
33
+ }
34
+ changelogDelta = unreleased.trim();
35
+ const stamped = stampChangelog(rawChangelog, version, date);
36
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated config
37
+ await writeFile(join(outputDir, 'CHANGELOG.md'), stamped);
38
+ files.push('CHANGELOG.md');
39
+ }
40
+ // 4. Process readme
41
+ if (options.readme) {
42
+ const readmePath = resolve(configDir, options.readme.sourcePath);
43
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- path from validated config
44
+ const readmeContent = readFileSync(readmePath, 'utf-8');
45
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated config
46
+ await writeFile(join(outputDir, 'README.md'), readmeContent);
47
+ files.push('README.md');
48
+ }
49
+ // 5. Process license
50
+ if (options.license) {
51
+ let licenseContent;
52
+ if (options.license.type === 'spdx') {
53
+ licenseContent = generateLicenseText(options.license.value, options.license.ownerName, new Date().getFullYear());
54
+ }
55
+ else {
56
+ licenseContent = readLicenseFile(options.license.filePath, configDir);
57
+ }
58
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated config
59
+ await writeFile(join(outputDir, 'LICENSE'), licenseContent);
60
+ files.push('LICENSE');
61
+ }
62
+ return { version, changelogDelta, files };
63
+ }
64
+ //# sourceMappingURL=publish-tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-tree.js","sourceRoot":"","sources":["../../../../src/commands/claude/marketplace/publish-tree.ts"],"names":[],"mappings":"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"}