@vibe-agent-toolkit/cli 0.1.41-rc.6 → 0.1.41-rc.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/bin/vat +25 -2
- package/dist/bin/vat.js +25 -2
- package/dist/bin/vat.js.map +1 -1
- package/dist/bin.js +12 -1
- package/dist/bin.js.map +1 -1
- package/dist/commands/agent/list.d.ts +11 -0
- package/dist/commands/agent/list.d.ts.map +1 -1
- package/dist/commands/agent/list.js +30 -11
- package/dist/commands/agent/list.js.map +1 -1
- package/dist/commands/audit/hierarchical-output.d.ts +6 -2
- package/dist/commands/audit/hierarchical-output.d.ts.map +1 -1
- package/dist/commands/audit/hierarchical-output.js +93 -50
- package/dist/commands/audit/hierarchical-output.js.map +1 -1
- package/dist/commands/audit-settings.d.ts +35 -0
- package/dist/commands/audit-settings.d.ts.map +1 -1
- package/dist/commands/audit-settings.js +121 -51
- package/dist/commands/audit-settings.js.map +1 -1
- package/dist/commands/audit.d.ts +97 -2
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +505 -231
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/build.d.ts +14 -0
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +126 -32
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/claude/marketplace/license-utils.d.ts +39 -2
- package/dist/commands/claude/marketplace/license-utils.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/license-utils.js +114 -68
- package/dist/commands/claude/marketplace/license-utils.js.map +1 -1
- package/dist/commands/claude/marketplace/publish.js +5 -4
- package/dist/commands/claude/marketplace/publish.js.map +1 -1
- package/dist/commands/claude/marketplace/validate.d.ts +97 -0
- package/dist/commands/claude/marketplace/validate.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/validate.js +157 -49
- package/dist/commands/claude/marketplace/validate.js.map +1 -1
- package/dist/commands/claude/org/skills.d.ts +11 -3
- package/dist/commands/claude/org/skills.d.ts.map +1 -1
- package/dist/commands/claude/org/skills.js +70 -20
- package/dist/commands/claude/org/skills.js.map +1 -1
- package/dist/commands/claude/org/stubs.d.ts +9 -1
- package/dist/commands/claude/org/stubs.d.ts.map +1 -1
- package/dist/commands/claude/org/stubs.js +11 -3
- package/dist/commands/claude/org/stubs.js.map +1 -1
- package/dist/commands/claude/plugin/build.d.ts +116 -0
- package/dist/commands/claude/plugin/build.d.ts.map +1 -1
- package/dist/commands/claude/plugin/build.js +173 -40
- package/dist/commands/claude/plugin/build.js.map +1 -1
- package/dist/commands/claude/plugin/marketplace-json.d.ts +36 -0
- package/dist/commands/claude/plugin/marketplace-json.d.ts.map +1 -0
- package/dist/commands/claude/plugin/marketplace-json.js +34 -0
- package/dist/commands/claude/plugin/marketplace-json.js.map +1 -0
- package/dist/commands/claude/plugin/plugin-json-merge.d.ts +30 -1
- package/dist/commands/claude/plugin/plugin-json-merge.d.ts.map +1 -1
- package/dist/commands/claude/plugin/plugin-json-merge.js +107 -14
- package/dist/commands/claude/plugin/plugin-json-merge.js.map +1 -1
- package/dist/commands/claude/plugin/tree-copy.d.ts.map +1 -1
- package/dist/commands/claude/plugin/tree-copy.js +0 -1
- package/dist/commands/claude/plugin/tree-copy.js.map +1 -1
- package/dist/commands/corpus/report.d.ts +22 -4
- package/dist/commands/corpus/report.d.ts.map +1 -1
- package/dist/commands/corpus/report.js +1 -0
- package/dist/commands/corpus/report.js.map +1 -1
- package/dist/commands/corpus/runner.d.ts +16 -1
- package/dist/commands/corpus/runner.d.ts.map +1 -1
- package/dist/commands/corpus/runner.js +55 -48
- package/dist/commands/corpus/runner.js.map +1 -1
- package/dist/commands/doctor.d.ts +57 -8
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +142 -67
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/inventory.d.ts +2 -0
- package/dist/commands/inventory.d.ts.map +1 -1
- package/dist/commands/inventory.js +45 -4
- package/dist/commands/inventory.js.map +1 -1
- package/dist/commands/phase-utils.d.ts +240 -11
- package/dist/commands/phase-utils.d.ts.map +1 -1
- package/dist/commands/phase-utils.js +352 -15
- package/dist/commands/phase-utils.js.map +1 -1
- package/dist/commands/rag/query-command.d.ts +40 -0
- package/dist/commands/rag/query-command.d.ts.map +1 -1
- package/dist/commands/rag/query-command.js +47 -20
- package/dist/commands/rag/query-command.js.map +1 -1
- package/dist/commands/resources/index.d.ts.map +1 -1
- package/dist/commands/resources/index.js +38 -13
- package/dist/commands/resources/index.js.map +1 -1
- package/dist/commands/resources/scan.d.ts +37 -0
- package/dist/commands/resources/scan.d.ts.map +1 -1
- package/dist/commands/resources/scan.js +47 -32
- package/dist/commands/resources/scan.js.map +1 -1
- package/dist/commands/resources/validate.d.ts +136 -1
- package/dist/commands/resources/validate.d.ts.map +1 -1
- package/dist/commands/resources/validate.js +121 -68
- package/dist/commands/resources/validate.js.map +1 -1
- package/dist/commands/skill/review.d.ts.map +1 -1
- package/dist/commands/skill/review.js +40 -23
- package/dist/commands/skill/review.js.map +1 -1
- package/dist/commands/skill/test/run.d.ts +1 -1
- package/dist/commands/skill/test/run.d.ts.map +1 -1
- package/dist/commands/skill/test/run.js +8 -6
- package/dist/commands/skill/test/run.js.map +1 -1
- package/dist/commands/skills/build.d.ts +140 -0
- package/dist/commands/skills/build.d.ts.map +1 -1
- package/dist/commands/skills/build.js +348 -94
- package/dist/commands/skills/build.js.map +1 -1
- package/dist/commands/skills/command-helpers.d.ts +6 -10
- package/dist/commands/skills/command-helpers.d.ts.map +1 -1
- package/dist/commands/skills/command-helpers.js +6 -22
- package/dist/commands/skills/command-helpers.js.map +1 -1
- package/dist/commands/skills/list.d.ts +18 -0
- package/dist/commands/skills/list.d.ts.map +1 -1
- package/dist/commands/skills/list.js +41 -15
- package/dist/commands/skills/list.js.map +1 -1
- package/dist/commands/skills/package.d.ts +17 -0
- package/dist/commands/skills/package.d.ts.map +1 -1
- package/dist/commands/skills/package.js +72 -43
- package/dist/commands/skills/package.js.map +1 -1
- package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
- package/dist/commands/skills/skill-discovery.js +9 -1
- package/dist/commands/skills/skill-discovery.js.map +1 -1
- package/dist/commands/skills/validate-command.d.ts.map +1 -1
- package/dist/commands/skills/validate-command.js +22 -6
- package/dist/commands/skills/validate-command.js.map +1 -1
- package/dist/commands/skills/validate.d.ts +79 -0
- package/dist/commands/skills/validate.d.ts.map +1 -1
- package/dist/commands/skills/validate.js +268 -79
- package/dist/commands/skills/validate.js.map +1 -1
- package/dist/commands/validate.d.ts +18 -0
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +79 -66
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/verify.d.ts +38 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +247 -84
- package/dist/commands/verify.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/skill-resolution/index.d.ts +1 -1
- package/dist/skill-resolution/index.d.ts.map +1 -1
- package/dist/skill-resolution/index.js +1 -1
- package/dist/skill-resolution/index.js.map +1 -1
- package/dist/skill-resolution/packaging-config.d.ts +15 -2
- package/dist/skill-resolution/packaging-config.d.ts.map +1 -1
- package/dist/skill-resolution/packaging-config.js +39 -2
- package/dist/skill-resolution/packaging-config.js.map +1 -1
- package/dist/utils/command-error.d.ts +34 -1
- package/dist/utils/command-error.d.ts.map +1 -1
- package/dist/utils/command-error.js +32 -1
- package/dist/utils/command-error.js.map +1 -1
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js +0 -2
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/help-loader.d.ts +6 -2
- package/dist/utils/help-loader.d.ts.map +1 -1
- package/dist/utils/help-loader.js +9 -16
- package/dist/utils/help-loader.js.map +1 -1
- package/dist/utils/issue-anchor.d.ts +26 -0
- package/dist/utils/issue-anchor.d.ts.map +1 -0
- package/dist/utils/issue-anchor.js +39 -0
- package/dist/utils/issue-anchor.js.map +1 -0
- package/dist/utils/issue-rendering.d.ts +149 -0
- package/dist/utils/issue-rendering.d.ts.map +1 -0
- package/dist/utils/issue-rendering.js +229 -0
- package/dist/utils/issue-rendering.js.map +1 -0
- package/dist/utils/output.d.ts +80 -9
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +138 -23
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/project-root-policy.d.ts +2 -2
- package/dist/utils/project-root-policy.js +2 -2
- package/dist/utils/relativize-paths.d.ts +45 -0
- package/dist/utils/relativize-paths.d.ts.map +1 -0
- package/dist/utils/relativize-paths.js +67 -0
- package/dist/utils/relativize-paths.js.map +1 -0
- package/dist/utils/resource-loader.d.ts +21 -2
- package/dist/utils/resource-loader.d.ts.map +1 -1
- package/dist/utils/resource-loader.js +85 -11
- package/dist/utils/resource-loader.js.map +1 -1
- package/dist/utils/skill-packaging-config.d.ts +22 -1
- package/dist/utils/skill-packaging-config.d.ts.map +1 -1
- package/dist/utils/skill-packaging-config.js +26 -0
- package/dist/utils/skill-packaging-config.js.map +1 -1
- package/dist/utils/validate-help-files.d.ts +3 -2
- package/dist/utils/validate-help-files.d.ts.map +1 -1
- package/dist/utils/validate-help-files.js +48 -5
- package/dist/utils/validate-help-files.js.map +1 -1
- package/dist/utils/verdict-helpers.d.ts +14 -5
- package/dist/utils/verdict-helpers.d.ts.map +1 -1
- package/dist/utils/verdict-helpers.js +19 -16
- package/dist/utils/verdict-helpers.js.map +1 -1
- package/docs/audit.md +40 -14
- package/docs/doctor.md +46 -10
- package/docs/index.md +1 -1
- package/docs/rag.md +9 -4
- package/docs/resources.md +54 -22
- package/docs/skills.md +11 -7
- package/package.json +12 -12
|
@@ -6,16 +6,27 @@
|
|
|
6
6
|
* (commands, hooks, agents, .mcp.json, skills/, .claude-plugin/plugin.json) and
|
|
7
7
|
* imports pool skills (from dist/skills/) via the `skills:` selector.
|
|
8
8
|
*/
|
|
9
|
+
import { type SeverityCounts } from '@vibe-agent-toolkit/agent-schema';
|
|
10
|
+
import { type DeclaredEvalSuite, type PackageSkillResult } from '@vibe-agent-toolkit/agent-skills';
|
|
11
|
+
import type { ResourceRegistry, SkillsConfig } from '@vibe-agent-toolkit/resources';
|
|
9
12
|
import { Command } from 'commander';
|
|
10
13
|
import { createLogger } from '../../../utils/logger.js';
|
|
11
14
|
export interface PluginBuildCommandOptions {
|
|
12
15
|
marketplace?: string;
|
|
13
16
|
debug?: boolean;
|
|
17
|
+
verbose?: boolean;
|
|
14
18
|
}
|
|
15
19
|
interface PluginBuildResult {
|
|
16
20
|
pluginName: string;
|
|
17
21
|
pluginDir: string;
|
|
18
22
|
pluginVersion: string | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* The plugin's merged `author` (config-owned name/email plus the subfields
|
|
25
|
+
* config cannot express, passed through from the author's plugin.json). Carried
|
|
26
|
+
* up so marketplace.json republishes THIS object rather than rebuilding one
|
|
27
|
+
* from the config `owner` and silently dropping the passthrough subfields.
|
|
28
|
+
*/
|
|
29
|
+
pluginAuthor: Record<string, unknown>;
|
|
19
30
|
skillsCopied: string[];
|
|
20
31
|
commandsCopied: number;
|
|
21
32
|
hooksCopied: number;
|
|
@@ -24,6 +35,15 @@ interface PluginBuildResult {
|
|
|
24
35
|
treeFilesCopied: number;
|
|
25
36
|
explicitFilesCopied: number;
|
|
26
37
|
localSkillsPackaged: number;
|
|
38
|
+
/**
|
|
39
|
+
* Per-severity post-build findings across this plugin's plugin-local skills.
|
|
40
|
+
*
|
|
41
|
+
* Published rather than folded into the plugin's success/failure: the build
|
|
42
|
+
* gate is two-valued (a warning does not fail it), so a bare `status` cannot
|
|
43
|
+
* say whether a "built" plugin shipped warnings or info findings — and the
|
|
44
|
+
* reading a consumer takes from silence is the reassuring one.
|
|
45
|
+
*/
|
|
46
|
+
localSkillIssueCounts: SeverityCounts;
|
|
27
47
|
}
|
|
28
48
|
export interface MarketplaceBuildResult {
|
|
29
49
|
name: string;
|
|
@@ -45,10 +65,106 @@ export declare function createPluginBuildCommand(): Command;
|
|
|
45
65
|
* vibe-agent-toolkit.config.yaml), so callers that already know the root build
|
|
46
66
|
* against it rather than re-discovering from cwd. `options.marketplace` restricts
|
|
47
67
|
* the build to a single marketplace by name.
|
|
68
|
+
*
|
|
69
|
+
* `options.verbose` affects the stderr findings report ONLY (see
|
|
70
|
+
* `summarizePackagedSkillIssues`); it changes nothing this function returns, so a
|
|
71
|
+
* programmatic caller — `vat skill test`, which builds a marketplace purely to
|
|
72
|
+
* stage a skill — can leave it off and still get the same result objects.
|
|
48
73
|
*/
|
|
49
74
|
export declare function runClaudePluginBuild(configDir: string, options?: {
|
|
50
75
|
marketplace?: string;
|
|
51
76
|
logger?: ReturnType<typeof createLogger>;
|
|
77
|
+
verbose?: boolean;
|
|
52
78
|
}): Promise<MarketplaceBuildResult[]>;
|
|
79
|
+
/** One plugin-local skill, discovered once and carried through every later phase. */
|
|
80
|
+
interface PluginLocalSkill {
|
|
81
|
+
/** Forward-slash dir path relative to the plugin's `skills/` dir (`a`, `group/b`). */
|
|
82
|
+
skillDirPath: string;
|
|
83
|
+
/** Absolute path to its `SKILL.md`. */
|
|
84
|
+
skillPath: string;
|
|
85
|
+
/** Its DECLARED name (frontmatter → H1 → filename), the key per-skill config uses. */
|
|
86
|
+
skillName: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* PACKAGE each plugin-local skill (a skill living in the plugin's own `skills/`
|
|
90
|
+
* source tree) with the SAME packager that produces pool skills.
|
|
91
|
+
*
|
|
92
|
+
* This is the "one production path" rule. A plugin-local skill used to be
|
|
93
|
+
* tree-copied VERBATIM — every byte in its source directory shipped, links were
|
|
94
|
+
* never rewritten, and `files:` had to be re-applied separately because the
|
|
95
|
+
* packager never ran. That produced a materially different artifact from the
|
|
96
|
+
* pool path for the same kind of thing, and the difference was invisible: it
|
|
97
|
+
* shipped eval suites (answer keys included), scratch files, and un-rewritten
|
|
98
|
+
* links. The collision referee already conceded the point by preferring the
|
|
99
|
+
* pool copy whenever both existed.
|
|
100
|
+
*
|
|
101
|
+
* Now both paths run `packageSkill`, so "what ships in a skill" has exactly one
|
|
102
|
+
* answer: link-reachable resources plus declared `files:`, links rewritten,
|
|
103
|
+
* declared test input excluded, post-build checks applied.
|
|
104
|
+
*
|
|
105
|
+
* `input.skills` is the already-refereed set: pool-sourced collisions have been
|
|
106
|
+
* filtered out by {@link resolveCollidingSkills} and are copied in by Phase 3
|
|
107
|
+
* instead. Returns each packaged skill's result for error reporting.
|
|
108
|
+
*
|
|
109
|
+
* The returned list is also the ONLY definition of "which dirs under `skills/` did
|
|
110
|
+
* the packager produce": the tree-copy exclusion list is derived from it (see
|
|
111
|
+
* Phase 2b in {@link buildPlugin}), so a directory absent from it is a directory
|
|
112
|
+
* the tree-copy still ships.
|
|
113
|
+
*/
|
|
114
|
+
export declare function packagePluginLocalSkills(input: {
|
|
115
|
+
skills: readonly PluginLocalSkill[];
|
|
116
|
+
pluginDir: string;
|
|
117
|
+
skillsConfig: SkillsConfig | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* THE project registry for this build, built once by {@link runClaudePluginBuild}.
|
|
120
|
+
*
|
|
121
|
+
* Not optional, and not defaulted: `packageSkill` silently falls back to
|
|
122
|
+
* crawling and parsing every markdown file in the project when it gets no
|
|
123
|
+
* registry, so an omission here costs one whole-project scan PER SKILL rather
|
|
124
|
+
* than failing. That is exactly what this lane used to do.
|
|
125
|
+
*/
|
|
126
|
+
registry: ResourceRegistry;
|
|
127
|
+
/**
|
|
128
|
+
* THE project's declared eval suites, assembled once by {@link runClaudePluginBuild}.
|
|
129
|
+
*
|
|
130
|
+
* Not optional, and not defaulted, for the same reason as `registry` above: an
|
|
131
|
+
* omission would not fail, it would silently package one skill's bundle carrying
|
|
132
|
+
* ANOTHER skill's eval answer key — the failure mode a default value hid the first
|
|
133
|
+
* time this rule shipped.
|
|
134
|
+
*/
|
|
135
|
+
projectSkills: readonly DeclaredEvalSuite[];
|
|
136
|
+
logger: ReturnType<typeof createLogger>;
|
|
137
|
+
}): Promise<Array<{
|
|
138
|
+
skillDirPath: string;
|
|
139
|
+
result: PackageSkillResult;
|
|
140
|
+
}>>;
|
|
141
|
+
/**
|
|
142
|
+
* Summarize post-build issues for the plugin-local skills: the lines to print,
|
|
143
|
+
* the dirs that emitted errors, and the per-severity distribution.
|
|
144
|
+
*
|
|
145
|
+
* Mirrors `vat skills build`: a skill whose packaged output fails validation
|
|
146
|
+
* fails the build, so the two lanes hold the same bar, and they now render
|
|
147
|
+
* findings through the same helper — this lane used to label every non-error
|
|
148
|
+
* severity `[WARNING]`, so `info` findings were reported as warnings, and it
|
|
149
|
+
* read only `postBuildIssues`, so a skill failing purely on the built-output
|
|
150
|
+
* validation aborted the plugin build with no issue text at all.
|
|
151
|
+
*
|
|
152
|
+
* `verbose` governs the RENDERED lines and nothing else: `withErrors` (what the
|
|
153
|
+
* caller fails the plugin on) and `issueCounts` (what stdout publishes) are
|
|
154
|
+
* computed from the whole set at every verbosity, so quieting the report cannot
|
|
155
|
+
* quiet the gate. Per the shared policy in `issuesToRenderAtVerbosity`, errors
|
|
156
|
+
* always get a full block; warnings and info collapse into the per-skill heading
|
|
157
|
+
* above them, which still names the complete severity breakdown.
|
|
158
|
+
*
|
|
159
|
+
* Pure so the whole rendered set is assertable.
|
|
160
|
+
*/
|
|
161
|
+
export declare function summarizePackagedSkillIssues(packaged: Array<{
|
|
162
|
+
skillDirPath: string;
|
|
163
|
+
result: PackageSkillResult;
|
|
164
|
+
}>, verbose: boolean): {
|
|
165
|
+
lines: string[];
|
|
166
|
+
withErrors: string[];
|
|
167
|
+
issueCounts: SeverityCounts;
|
|
168
|
+
};
|
|
53
169
|
export {};
|
|
54
170
|
//# sourceMappingURL=build.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/plugin/build.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/plugin/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,16 +9,20 @@
|
|
|
9
9
|
import { cpSync, existsSync, readFileSync } from 'node:fs';
|
|
10
10
|
import { mkdir, readdir, rm, writeFile } from 'node:fs/promises';
|
|
11
11
|
import { basename } from 'node:path';
|
|
12
|
-
import {
|
|
12
|
+
import { countBySeverity } from '@vibe-agent-toolkit/agent-schema';
|
|
13
|
+
import { createProjectRegistry, getPluginOutputDir, getPluginSourceDir, listPluginSourceSkillDirs, listUntrackedPluginSkillDirs, packageSkill, packagingConfigToPackageOptions, skillNameToFsPath } from '@vibe-agent-toolkit/agent-skills';
|
|
13
14
|
import { safePath, toForwardSlash } from '@vibe-agent-toolkit/utils';
|
|
14
15
|
import { Command } from 'commander';
|
|
15
16
|
import { readSkillName } from '../../../commands/skills/skill-discovery.js';
|
|
16
17
|
import { handleCommandError } from '../../../utils/command-error.js';
|
|
17
18
|
import { loadConfig } from '../../../utils/config-loader.js';
|
|
19
|
+
import { collectPostBuildIssues, formatIssueLines, formatIssueSetHeading, issuesToRenderAtVerbosity, sumSeverityCounts, } from '../../../utils/issue-rendering.js';
|
|
18
20
|
import { createLogger } from '../../../utils/logger.js';
|
|
19
21
|
import { writeYamlOutput } from '../../../utils/output.js';
|
|
20
|
-
import { mergeSkillPackagingConfig } from '../../../utils/skill-packaging-config.js';
|
|
22
|
+
import { collectDeclaredEvalSuites, mergeSkillPackagingConfig } from '../../../utils/skill-packaging-config.js';
|
|
23
|
+
import { discoverSkillsFromConfig } from '../../skills/skill-discovery.js';
|
|
21
24
|
import { loadClaudeProjectConfig } from '../claude-config.js';
|
|
25
|
+
import { buildMarketplaceJson } from './marketplace-json.js';
|
|
22
26
|
import { resolvePluginChangelogPath } from './plugin-changelog.js';
|
|
23
27
|
import { applyPluginFiles } from './plugin-files.js';
|
|
24
28
|
import { mergePluginJson, resolveVersion } from './plugin-json-merge.js';
|
|
@@ -30,6 +34,7 @@ export function createPluginBuildCommand() {
|
|
|
30
34
|
command
|
|
31
35
|
.description('Generate Claude plugin artifacts from plugin directories and pre-built skills')
|
|
32
36
|
.option('--marketplace <name>', 'Build specific marketplace only')
|
|
37
|
+
.option('-v, --verbose', 'Show every individual finding, not just the errors')
|
|
33
38
|
.option('--debug', 'Enable debug logging')
|
|
34
39
|
.action(pluginBuildCommand)
|
|
35
40
|
.addHelpText('after', `
|
|
@@ -59,6 +64,12 @@ Output:
|
|
|
59
64
|
YAML summary -> stdout
|
|
60
65
|
Build progress -> stderr
|
|
61
66
|
|
|
67
|
+
On stderr, each packaged skill's findings heading names the whole set and
|
|
68
|
+
its severity breakdown, and errors are always printed in full beneath it.
|
|
69
|
+
Warnings and info findings stay collapsed into that heading unless
|
|
70
|
+
--verbose. The stdout YAML is NOT affected by --verbose: its issueCounts
|
|
71
|
+
cover every finding at every verbosity.
|
|
72
|
+
|
|
62
73
|
Exit Codes:
|
|
63
74
|
0 - Build successful
|
|
64
75
|
1 - Build error (empty plugin, invalid config)
|
|
@@ -95,9 +106,15 @@ async function discoverBuiltSkills(configDir) {
|
|
|
95
106
|
* vibe-agent-toolkit.config.yaml), so callers that already know the root build
|
|
96
107
|
* against it rather than re-discovering from cwd. `options.marketplace` restricts
|
|
97
108
|
* the build to a single marketplace by name.
|
|
109
|
+
*
|
|
110
|
+
* `options.verbose` affects the stderr findings report ONLY (see
|
|
111
|
+
* `summarizePackagedSkillIssues`); it changes nothing this function returns, so a
|
|
112
|
+
* programmatic caller — `vat skill test`, which builds a marketplace purely to
|
|
113
|
+
* stage a skill — can leave it off and still get the same result objects.
|
|
98
114
|
*/
|
|
99
115
|
export async function runClaudePluginBuild(configDir, options = {}) {
|
|
100
116
|
const logger = options.logger ?? createLogger({});
|
|
117
|
+
const verbose = options.verbose === true;
|
|
101
118
|
const projectConfig = loadConfig(configDir);
|
|
102
119
|
const marketplaces = projectConfig?.claude?.marketplaces;
|
|
103
120
|
if (!marketplaces || Object.keys(marketplaces).length === 0) {
|
|
@@ -128,6 +145,22 @@ export async function runClaudePluginBuild(configDir, options = {}) {
|
|
|
128
145
|
logger.info(`Building Claude plugin artifacts`);
|
|
129
146
|
logger.info(` Config: ${safePath.join(configDir, 'vibe-agent-toolkit.config.yaml')}`);
|
|
130
147
|
logger.info(` Skills available: ${availableSkills.length}`);
|
|
148
|
+
// THE registry for this build: one crawl+parse of the project's markdown,
|
|
149
|
+
// shared by every plugin-local skill in every marketplace. `packageSkill`
|
|
150
|
+
// builds this itself when it is not given one, so omitting it does not fail —
|
|
151
|
+
// it just re-reads the whole project once per skill, which is how a 46-skill
|
|
152
|
+
// build came to take longer than a 30-minute CI budget.
|
|
153
|
+
const sharedRegistry = await createProjectRegistry(configDir);
|
|
154
|
+
logger.debug(`Project registry: ${sharedRegistry.getAllResources().length} markdown resources (built once)`);
|
|
155
|
+
// THE project's declared eval suites for this build, assembled ONCE and threaded
|
|
156
|
+
// to every plugin-local skill. Test input never ships, and the rule is
|
|
157
|
+
// project-wide: a file ANY skill declares as its eval suite is an answer key, so
|
|
158
|
+
// a plugin-local skill's bundle must exclude the OTHER skills' suites too — not
|
|
159
|
+
// just its own. Discovery is not free, hence once per run rather than per skill.
|
|
160
|
+
const projectSkills = skillsConfig === undefined
|
|
161
|
+
? []
|
|
162
|
+
: collectDeclaredEvalSuites(skillsConfig, await discoverSkillsFromConfig(skillsConfig, configDir));
|
|
163
|
+
logger.debug(`Project declared eval suites: ${projectSkills.length}`);
|
|
131
164
|
const results = [];
|
|
132
165
|
const allPluginNames = [];
|
|
133
166
|
for (const mp of Object.values(marketplaces)) {
|
|
@@ -142,7 +175,18 @@ export async function runClaudePluginBuild(configDir, options = {}) {
|
|
|
142
175
|
}
|
|
143
176
|
const mpConfig = marketplaces[name];
|
|
144
177
|
logger.info(`\n Building marketplace: ${name}`);
|
|
145
|
-
const result = await buildMarketplace(
|
|
178
|
+
const result = await buildMarketplace({
|
|
179
|
+
name,
|
|
180
|
+
config: mpConfig,
|
|
181
|
+
availableSkills,
|
|
182
|
+
configDir,
|
|
183
|
+
skillsConfig,
|
|
184
|
+
rootVersion,
|
|
185
|
+
registry: sharedRegistry,
|
|
186
|
+
projectSkills,
|
|
187
|
+
logger,
|
|
188
|
+
verbose,
|
|
189
|
+
});
|
|
146
190
|
results.push(result);
|
|
147
191
|
if (result.status === 'error') {
|
|
148
192
|
throw new Error(`Claude plugin build failed for marketplace '${name}': ${result.reason ?? 'unknown error'}`);
|
|
@@ -166,12 +210,17 @@ async function pluginBuildCommand(options) {
|
|
|
166
210
|
const results = await runClaudePluginBuild(configDir, {
|
|
167
211
|
...(options.marketplace ? { marketplace: options.marketplace } : {}),
|
|
168
212
|
logger,
|
|
213
|
+
verbose: options.verbose === true,
|
|
169
214
|
});
|
|
170
215
|
const duration = Date.now() - startTime;
|
|
171
216
|
const totalPlugins = results.flatMap((r) => r.plugins).length;
|
|
172
217
|
const totalSkills = results.flatMap((r) => r.plugins).flatMap((p) => p.skillsCopied).length;
|
|
218
|
+
const allPlugins = results.flatMap((r) => r.plugins);
|
|
173
219
|
writeYamlOutput({
|
|
174
220
|
status: 'success',
|
|
221
|
+
// The build gate is two-valued and a warning does not fail it, so the
|
|
222
|
+
// distribution has to travel next to the status rather than inside it.
|
|
223
|
+
issueCounts: sumSeverityCounts(allPlugins.map((p) => p.localSkillIssueCounts)),
|
|
175
224
|
marketplacesBuilt: results.filter((r) => r.status === 'built').length,
|
|
176
225
|
pluginsBuilt: totalPlugins,
|
|
177
226
|
skillsPackaged: totalSkills,
|
|
@@ -190,6 +239,7 @@ async function pluginBuildCommand(options) {
|
|
|
190
239
|
treeFilesCopied: p.treeFilesCopied,
|
|
191
240
|
explicitFilesCopied: p.explicitFilesCopied,
|
|
192
241
|
localSkillsPackaged: p.localSkillsPackaged,
|
|
242
|
+
issueCounts: p.localSkillIssueCounts,
|
|
193
243
|
})),
|
|
194
244
|
})),
|
|
195
245
|
duration: `${duration}ms`,
|
|
@@ -224,7 +274,8 @@ async function copyDistributionFiles(marketplaceDir, configDir, config, logger)
|
|
|
224
274
|
}
|
|
225
275
|
}
|
|
226
276
|
}
|
|
227
|
-
async function buildMarketplace(
|
|
277
|
+
async function buildMarketplace(input) {
|
|
278
|
+
const { name, config, availableSkills, configDir, skillsConfig, rootVersion, registry, projectSkills, logger, verbose } = input;
|
|
228
279
|
const plugins = [];
|
|
229
280
|
// Clean stale marketplace directory before rebuilding — removes orphaned plugins
|
|
230
281
|
const marketplaceBaseDir = safePath.join(configDir, 'dist', '.claude', 'plugins', 'marketplaces', name);
|
|
@@ -243,7 +294,10 @@ async function buildMarketplace(name, config, availableSkills, configDir, skills
|
|
|
243
294
|
skillsConfig,
|
|
244
295
|
owner: config.owner,
|
|
245
296
|
rootVersion,
|
|
297
|
+
registry,
|
|
298
|
+
projectSkills,
|
|
246
299
|
logger,
|
|
300
|
+
verbose,
|
|
247
301
|
});
|
|
248
302
|
plugins.push(pluginResult);
|
|
249
303
|
}
|
|
@@ -252,27 +306,18 @@ async function buildMarketplace(name, config, availableSkills, configDir, skills
|
|
|
252
306
|
const claudePluginDir = safePath.join(marketplaceDir, CLAUDE_PLUGIN_DIRNAME);
|
|
253
307
|
// eslint-disable-next-line security/detect-non-literal-fs-filename -- resolved paths
|
|
254
308
|
await mkdir(claudePluginDir, { recursive: true });
|
|
255
|
-
|
|
256
|
-
|
|
309
|
+
// Each entry's author is the plugin's own MERGED author (see marketplace-json.ts),
|
|
310
|
+
// so marketplace.json and that plugin's plugin.json cannot disagree.
|
|
311
|
+
const marketplaceJson = buildMarketplaceJson({
|
|
257
312
|
name,
|
|
258
|
-
owner:
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
...(pluginDesc ? { description: pluginDesc } : {}),
|
|
267
|
-
source: `./plugins/${p.pluginName}`,
|
|
268
|
-
...(p.pluginVersion ? { version: p.pluginVersion } : {}),
|
|
269
|
-
author: {
|
|
270
|
-
name: config.owner.name,
|
|
271
|
-
...(config.owner.email ? { email: config.owner.email } : {}),
|
|
272
|
-
},
|
|
273
|
-
};
|
|
274
|
-
}),
|
|
275
|
-
};
|
|
313
|
+
owner: config.owner,
|
|
314
|
+
plugins: plugins.map((p) => ({
|
|
315
|
+
name: p.pluginName,
|
|
316
|
+
description: config.plugins.find((pd) => pd.name === p.pluginName)?.description,
|
|
317
|
+
version: p.pluginVersion,
|
|
318
|
+
author: p.pluginAuthor,
|
|
319
|
+
})),
|
|
320
|
+
});
|
|
276
321
|
// eslint-disable-next-line security/detect-non-literal-fs-filename -- resolved paths
|
|
277
322
|
await writeFile(safePath.join(claudePluginDir, 'marketplace.json'), JSON.stringify(marketplaceJson, null, 2));
|
|
278
323
|
logger.info(` .claude-plugin/marketplace.json`);
|
|
@@ -355,7 +400,7 @@ async function writeMergedPluginJson(pluginDef, authorJson, pluginVersion, plugi
|
|
|
355
400
|
const pluginJsonDir = safePath.join(pluginDir, CLAUDE_PLUGIN_DIRNAME);
|
|
356
401
|
// eslint-disable-next-line security/detect-non-literal-fs-filename -- resolved paths
|
|
357
402
|
await mkdir(pluginJsonDir, { recursive: true });
|
|
358
|
-
const { merged, warnings } = mergePluginJson({
|
|
403
|
+
const { merged, author, warnings } = mergePluginJson({
|
|
359
404
|
vat: {
|
|
360
405
|
name: pluginDef.name,
|
|
361
406
|
version: pluginVersion,
|
|
@@ -369,6 +414,7 @@ async function writeMergedPluginJson(pluginDef, authorJson, pluginVersion, plugi
|
|
|
369
414
|
// eslint-disable-next-line security/detect-non-literal-fs-filename -- resolved paths
|
|
370
415
|
await writeFile(safePath.join(pluginJsonDir, 'plugin.json'), JSON.stringify(merged, null, 2));
|
|
371
416
|
logger.info(` .claude-plugin/plugin.json`);
|
|
417
|
+
return author;
|
|
372
418
|
}
|
|
373
419
|
/**
|
|
374
420
|
* Copy pool skills (from dist/skills/) selected by the plugin's skills: selector
|
|
@@ -470,8 +516,31 @@ function lastPathSegment(dirPath) {
|
|
|
470
516
|
* Phase 2b in {@link buildPlugin}), so a directory absent from it is a directory
|
|
471
517
|
* the tree-copy still ships.
|
|
472
518
|
*/
|
|
473
|
-
async function packagePluginLocalSkills(input) {
|
|
519
|
+
export async function packagePluginLocalSkills(input) {
|
|
474
520
|
const packaged = [];
|
|
521
|
+
// KNOWN GAP — NO PER-SKILL CONTAINMENT. `packageSkill` reports most problems by
|
|
522
|
+
// RETURNING a result whose `hasErrors` is set, but it THROWS on structural packaging
|
|
523
|
+
// failures (filename collisions, unreadable sources). This loop awaits it bare, so one
|
|
524
|
+
// throw escapes the whole plugin build and discards every skill packaged before it —
|
|
525
|
+
// while the partial `skills/<dir>/` trees already written stay on disk, described by
|
|
526
|
+
// nothing.
|
|
527
|
+
//
|
|
528
|
+
// This is the SAME defect, in the same shape, that `packageSkills` had until commit
|
|
529
|
+
// ba140fae ("fix(skills): one unbuildable skill no longer discards the whole build").
|
|
530
|
+
// Copy that fix: it wraps each iteration in try/catch and returns a
|
|
531
|
+
// `SkillPackageOutcome` discriminated union (`built` | `failed`) carrying the error,
|
|
532
|
+
// deliberately NOT a synthetic `PackageSkillResult` (which would have to invent
|
|
533
|
+
// `outputPath`/`skill`/`files`, so consumers would report a file count for a bundle
|
|
534
|
+
// that is not on disk).
|
|
535
|
+
//
|
|
536
|
+
// Why it matters concretely: a `vat build` on a 90-skill adopter (2026-07-30) hit 3
|
|
537
|
+
// filename collisions across three separate skills and, thanks to `packageSkills`'
|
|
538
|
+
// containment, still built the other 87. This lane would have thrown all 90 away.
|
|
539
|
+
//
|
|
540
|
+
// Note the containment this lane lacks is for a skill that THROWS, and a filename
|
|
541
|
+
// collision no longer throws — it is a returned finding. The remaining throw paths
|
|
542
|
+
// are an absent or unreadable `files:` source; do not use a collision as the fixture
|
|
543
|
+
// when adding that guard, or the test will pass without the guard existing.
|
|
475
544
|
for (const { skillDirPath, skillPath, skillName } of input.skills) {
|
|
476
545
|
// Per-skill config is keyed by the skill's declared NAME; the directory path and
|
|
477
546
|
// its trailing segment are fallbacks for the common cases where they coincide.
|
|
@@ -483,30 +552,90 @@ async function packagePluginLocalSkills(input) {
|
|
|
483
552
|
input.skillsConfig?.config?.[skillDirPath] ??
|
|
484
553
|
input.skillsConfig?.config?.[lastPathSegment(skillDirPath)]);
|
|
485
554
|
const skillOutputDir = safePath.join(input.pluginDir, 'skills', skillDirPath);
|
|
486
|
-
|
|
555
|
+
// KNOWN GAP — false ALLOW_UNUSED for plugin-local skills. If you are here, please
|
|
556
|
+
// consider fixing it while the hood is open.
|
|
557
|
+
//
|
|
558
|
+
// This loop omits `allowLedger`, and omitting it is a positive claim that THIS
|
|
559
|
+
// call is the whole run (see PackageSkillOptions.allowLedger). That claim is FALSE
|
|
560
|
+
// here: we are looping. `validation.allow` is declared once per package but matched
|
|
561
|
+
// once per skill, so an entry matched while packaging skill A is reported unused
|
|
562
|
+
// while packaging skill B. `vat skills build` had exactly this bug and fixed it by
|
|
563
|
+
// creating one ledger for the invocation, threading it through, and draining it
|
|
564
|
+
// once after the last skill — see `runSkillBuild` in ../../skills/build.ts, which
|
|
565
|
+
// is the model to copy.
|
|
566
|
+
//
|
|
567
|
+
// Why it is not fixed here: this lane has no channel for RUN-level issues in its
|
|
568
|
+
// YAML output (every issue it reports is attributed to a skill dir), and inventing
|
|
569
|
+
// a second reporting shape was worse than leaving one honest comment. Fixing this
|
|
570
|
+
// properly means adding that channel first.
|
|
571
|
+
//
|
|
572
|
+
// Why it measures zero today: VAT's own plugins are assembled from the shared skill
|
|
573
|
+
// pool by copy-in, so this loop packages nothing. A project with plugin-local
|
|
574
|
+
// `skills/` directories AND package-scoped `validation.allow` entries still sees the
|
|
575
|
+
// false warnings. This is also the last thing blocking a promotion of ALLOW_UNUSED
|
|
576
|
+
// from `warning` to `error`, which would turn those false positives into hard build
|
|
577
|
+
// failures.
|
|
578
|
+
//
|
|
579
|
+
// That promotion is now MEASURABLE rather than open-ended. On the 90-skill adopter
|
|
580
|
+
// (2026-07-30) this lane's ledger drains to 17 unused allow entries, against 14 in
|
|
581
|
+
// the `vat skills build` (`skills`) lane — so the work this comment gates is a
|
|
582
|
+
// bounded 17-entry reconciliation, not an unbounded one. UNVERIFIED how much of the
|
|
583
|
+
// 17 - 14 delta is the false-positive class described above versus genuinely dead
|
|
584
|
+
// entries; nobody has classified them entry by entry.
|
|
585
|
+
const result = await packageSkill(skillPath, {
|
|
586
|
+
...packagingConfigToPackageOptions(packagingConfig, { skillPath, outputPath: skillOutputDir }, input.projectSkills),
|
|
587
|
+
registry: input.registry,
|
|
588
|
+
});
|
|
487
589
|
input.logger.info(` ${skillName} -> skills/${skillDirPath} (${result.files.dependencies.length + 1} files)`);
|
|
488
590
|
packaged.push({ skillDirPath, result });
|
|
489
591
|
}
|
|
490
592
|
return packaged;
|
|
491
593
|
}
|
|
492
594
|
/**
|
|
493
|
-
*
|
|
494
|
-
*
|
|
495
|
-
*
|
|
496
|
-
*
|
|
497
|
-
*
|
|
595
|
+
* Summarize post-build issues for the plugin-local skills: the lines to print,
|
|
596
|
+
* the dirs that emitted errors, and the per-severity distribution.
|
|
597
|
+
*
|
|
598
|
+
* Mirrors `vat skills build`: a skill whose packaged output fails validation
|
|
599
|
+
* fails the build, so the two lanes hold the same bar, and they now render
|
|
600
|
+
* findings through the same helper — this lane used to label every non-error
|
|
601
|
+
* severity `[WARNING]`, so `info` findings were reported as warnings, and it
|
|
602
|
+
* read only `postBuildIssues`, so a skill failing purely on the built-output
|
|
603
|
+
* validation aborted the plugin build with no issue text at all.
|
|
604
|
+
*
|
|
605
|
+
* `verbose` governs the RENDERED lines and nothing else: `withErrors` (what the
|
|
606
|
+
* caller fails the plugin on) and `issueCounts` (what stdout publishes) are
|
|
607
|
+
* computed from the whole set at every verbosity, so quieting the report cannot
|
|
608
|
+
* quiet the gate. Per the shared policy in `issuesToRenderAtVerbosity`, errors
|
|
609
|
+
* always get a full block; warnings and info collapse into the per-skill heading
|
|
610
|
+
* above them, which still names the complete severity breakdown.
|
|
611
|
+
*
|
|
612
|
+
* Pure so the whole rendered set is assertable.
|
|
498
613
|
*/
|
|
499
|
-
function
|
|
614
|
+
export function summarizePackagedSkillIssues(packaged, verbose) {
|
|
615
|
+
const lines = [];
|
|
500
616
|
const withErrors = [];
|
|
617
|
+
const perSkillCounts = [];
|
|
501
618
|
for (const { skillDirPath, result } of packaged) {
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
619
|
+
const issues = collectPostBuildIssues(result);
|
|
620
|
+
perSkillCounts.push(countBySeverity(issues));
|
|
621
|
+
if (issues.length > 0) {
|
|
622
|
+
lines.push(` ${skillDirPath}: ${formatIssueSetHeading(issues, 'post-build')}`);
|
|
623
|
+
for (const issue of issuesToRenderAtVerbosity(issues, verbose)) {
|
|
624
|
+
lines.push(...formatIssueLines(issue, ' '));
|
|
625
|
+
}
|
|
505
626
|
}
|
|
506
627
|
if (result.hasErrors)
|
|
507
628
|
withErrors.push(skillDirPath);
|
|
508
629
|
}
|
|
509
|
-
return withErrors;
|
|
630
|
+
return { lines, withErrors, issueCounts: sumSeverityCounts(perSkillCounts) };
|
|
631
|
+
}
|
|
632
|
+
/** Print the summary to stderr and return what the caller gates on. */
|
|
633
|
+
function reportPackagedSkillIssues(packaged, logger, verbose) {
|
|
634
|
+
const { lines, withErrors, issueCounts } = summarizePackagedSkillIssues(packaged, verbose);
|
|
635
|
+
for (const line of lines) {
|
|
636
|
+
logger.info(line);
|
|
637
|
+
}
|
|
638
|
+
return { withErrors, issueCounts };
|
|
510
639
|
}
|
|
511
640
|
/**
|
|
512
641
|
* Split the plugin's own skills into those that COLLIDE with its resolved pool
|
|
@@ -554,7 +683,7 @@ function resolveCollidingSkills(skills, selectedSkillNames) {
|
|
|
554
683
|
return { colliding, packageable, conflicts };
|
|
555
684
|
}
|
|
556
685
|
async function buildPlugin(input) {
|
|
557
|
-
const { marketplaceName, pluginDef, marketplaceAvailable, configDir, skillsConfig, owner, rootVersion, logger } = input;
|
|
686
|
+
const { marketplaceName, pluginDef, marketplaceAvailable, configDir, skillsConfig, owner, rootVersion, registry, projectSkills, logger, verbose } = input;
|
|
558
687
|
const pluginDir = getPluginOutputDir(configDir, marketplaceName, pluginDef.name);
|
|
559
688
|
const pluginSourceDir = getPluginSourceDir(configDir, pluginDef);
|
|
560
689
|
logger.info(` Building plugin: ${pluginDef.name}`);
|
|
@@ -621,9 +750,11 @@ async function buildPlugin(input) {
|
|
|
621
750
|
skills: packageable,
|
|
622
751
|
pluginDir,
|
|
623
752
|
skillsConfig,
|
|
753
|
+
registry,
|
|
754
|
+
projectSkills,
|
|
624
755
|
logger,
|
|
625
756
|
});
|
|
626
|
-
const skillsWithErrors = reportPackagedSkillIssues(packagedLocalSkills, logger);
|
|
757
|
+
const { withErrors: skillsWithErrors, issueCounts: localSkillIssueCounts } = reportPackagedSkillIssues(packagedLocalSkills, logger, verbose);
|
|
627
758
|
if (skillsWithErrors.length > 0) {
|
|
628
759
|
throw new Error(`Plugin '${pluginDef.name}': ${skillsWithErrors.length} plugin-local skill(s) emitted ` +
|
|
629
760
|
`post-build validation errors: ${skillsWithErrors.join(', ')}`);
|
|
@@ -677,7 +808,7 @@ async function buildPlugin(input) {
|
|
|
677
808
|
// truth that flows into both the merged plugin.json and marketplace.json.
|
|
678
809
|
const authorJson = readAuthorPluginJson(pluginSourceDir);
|
|
679
810
|
const pluginVersion = resolveVersion(pluginDef, authorJson, rootVersion, { warn: (message) => logger.info(`warning: ${message}`) });
|
|
680
|
-
await writeMergedPluginJson(pluginDef, authorJson, pluginVersion, pluginDir, owner, logger);
|
|
811
|
+
const pluginAuthor = await writeMergedPluginJson(pluginDef, authorJson, pluginVersion, pluginDir, owner, logger);
|
|
681
812
|
// Phase 6: per-plugin CHANGELOG copy. Resolves to <pluginSourceDir>/CHANGELOG.md
|
|
682
813
|
// by default, or `entry.changelog` (relative to plugin source) when configured.
|
|
683
814
|
// No-op when neither resolves — marketplace-level CHANGELOG (handled in
|
|
@@ -691,6 +822,7 @@ async function buildPlugin(input) {
|
|
|
691
822
|
pluginName: pluginDef.name,
|
|
692
823
|
pluginDir,
|
|
693
824
|
pluginVersion,
|
|
825
|
+
pluginAuthor,
|
|
694
826
|
skillsCopied,
|
|
695
827
|
commandsCopied: treeResult.commandsCopied,
|
|
696
828
|
hooksCopied: treeResult.hooksCopied,
|
|
@@ -699,6 +831,7 @@ async function buildPlugin(input) {
|
|
|
699
831
|
treeFilesCopied: treeResult.filesCopied,
|
|
700
832
|
explicitFilesCopied,
|
|
701
833
|
localSkillsPackaged,
|
|
834
|
+
localSkillIssueCounts,
|
|
702
835
|
};
|
|
703
836
|
}
|
|
704
837
|
//# sourceMappingURL=build.js.map
|