agents-inc 0.170.1 → 0.171.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/dist/{chunk-52HDHJ7I.js → chunk-24OD7IP4.js} +32 -21
- package/dist/chunk-24OD7IP4.js.map +1 -0
- package/dist/{chunk-MQ6CGZNJ.js → chunk-3YYHL76L.js} +1879 -2019
- package/dist/chunk-3YYHL76L.js.map +1 -0
- package/dist/chunk-4RQKCV6I.js +103 -0
- package/dist/chunk-4RQKCV6I.js.map +1 -0
- package/dist/{chunk-USVBYQSQ.js → chunk-5FM77WKW.js} +16 -6
- package/dist/chunk-5FM77WKW.js.map +1 -0
- package/dist/{chunk-HED2DAXZ.js → chunk-7IVLVEHX.js} +5 -5
- package/dist/chunk-7IVLVEHX.js.map +1 -0
- package/dist/{chunk-PJWGTNOX.js → chunk-A6OWEJGC.js} +144 -186
- package/dist/chunk-A6OWEJGC.js.map +1 -0
- package/dist/{chunk-BMRUNMPV.js → chunk-AWWCRL5A.js} +35 -35
- package/dist/chunk-AWWCRL5A.js.map +1 -0
- package/dist/{chunk-F2BHT5C4.js → chunk-EOKNEGRD.js} +129 -151
- package/dist/chunk-EOKNEGRD.js.map +1 -0
- package/dist/{chunk-NQW25DCF.js → chunk-GHHJYNAN.js} +1 -7
- package/dist/chunk-GHHJYNAN.js.map +1 -0
- package/dist/chunk-JGPE4RRE.js +35 -0
- package/dist/chunk-JGPE4RRE.js.map +1 -0
- package/dist/{chunk-JFLVEFFP.js → chunk-KIK5EZYD.js} +1 -1
- package/dist/chunk-KIK5EZYD.js.map +1 -0
- package/dist/{chunk-NCWDK6L7.js → chunk-KMOCMVK5.js} +254 -379
- package/dist/chunk-KMOCMVK5.js.map +1 -0
- package/dist/{chunk-4AAOOAIN.js → chunk-P6CYS4JK.js} +2 -2
- package/dist/chunk-P6CYS4JK.js.map +1 -0
- package/dist/chunk-QIR56IDM.js +1169 -0
- package/dist/chunk-QIR56IDM.js.map +1 -0
- package/dist/{chunk-6ZRH5RHC.js → chunk-R572RLTI.js} +4 -4
- package/dist/chunk-R572RLTI.js.map +1 -0
- package/dist/{chunk-WTWMGH2C.js → chunk-RDXY4GRO.js} +2 -2
- package/dist/chunk-RDXY4GRO.js.map +1 -0
- package/dist/{chunk-7RDMTR64.js → chunk-S2SKVJT2.js} +785 -256
- package/dist/chunk-S2SKVJT2.js.map +1 -0
- package/dist/{chunk-SZYQISA2.js → chunk-TNFYBKVD.js} +43 -29
- package/dist/chunk-TNFYBKVD.js.map +1 -0
- package/dist/{chunk-RIPSGNLU.js → chunk-W4KAY26P.js} +3 -3
- package/dist/chunk-W4KAY26P.js.map +1 -0
- package/dist/{chunk-OYJQUA3D.js → chunk-WDH6HHA3.js} +31 -13
- package/dist/chunk-WDH6HHA3.js.map +1 -0
- package/dist/{chunk-3G7X2WKI.js → chunk-WII6GOPM.js} +18 -38
- package/dist/chunk-WII6GOPM.js.map +1 -0
- package/dist/{chunk-F5EBEATU.js → chunk-WM2N2D6Q.js} +34 -46
- package/dist/chunk-WM2N2D6Q.js.map +1 -0
- package/dist/{chunk-KOLDW6SF.js → chunk-YLUOGAW7.js} +2 -2
- package/dist/chunk-YLUOGAW7.js.map +1 -0
- package/dist/{chunk-44TE3RKH.js → chunk-ZC6GC66J.js} +5 -4
- package/dist/chunk-ZC6GC66J.js.map +1 -0
- package/dist/{chunk-NEZ4OAOL.js → chunk-ZEGM3MVR.js} +3 -5
- package/dist/chunk-ZEGM3MVR.js.map +1 -0
- package/dist/commands/build/marketplace.js +46 -46
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +25 -28
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/compile.js +87 -178
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +510 -360
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +451 -357
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +144 -125
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +20 -27
- package/dist/commands/list.js +39 -55
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +6 -11
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/search.js +35 -32
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +17 -77
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/uninstall.js +159 -222
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +9 -32
- package/dist/commands/update.js.map +1 -1
- package/dist/components/common/prompt-confirm.js +2 -2
- package/dist/components/common/removal-plan-confirm.js +2 -2
- package/dist/components/common/scroll-affordance.js +2 -2
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/common/skill-agent-summary.js +4 -4
- package/dist/components/common/spinner.js +2 -4
- package/dist/components/common/summary-panel.js +5 -5
- package/dist/components/common/summary-panel.js.map +1 -1
- package/dist/config-exports.js +7 -3
- package/dist/config-exports.js.map +1 -1
- package/dist/hooks/init.js +18 -19
- package/dist/hooks/init.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/load-agent-defs-UBWITIEI.js +14 -0
- package/dist/recompile-project-agents-IQANWGOP.js +65 -0
- package/dist/recompile-project-agents-IQANWGOP.js.map +1 -0
- package/dist/{source-loader-C5SQXZXI.js → source-loader-YGG7DY2W.js} +5 -5
- package/dist/src/agents/developer/ai-developer/playbook.md +2 -5
- package/dist/src/agents/developer/api-developer/playbook.md +2 -5
- package/dist/src/agents/developer/cli-developer/playbook.md +2 -5
- package/dist/src/agents/developer/web-developer/playbook.md +2 -5
- package/dist/src/agents/meta/agent-summoner/output.md +2 -2
- package/dist/src/agents/meta/agent-summoner/playbook.md +1 -13
- package/dist/src/agents/meta/codex-keeper/critical-requirements.md +2 -5
- package/dist/src/agents/meta/convention-keeper/critical-requirements.md +2 -4
- package/dist/src/agents/tester/ai-tester/critical-requirements.md +1 -2
- package/dist/src/agents/tester/ai-tester/playbook.md +2 -0
- package/dist/src/agents/tester/api-tester/critical-requirements.md +1 -2
- package/dist/src/agents/tester/api-tester/playbook.md +2 -0
- package/dist/src/agents/tester/cli-tester/critical-requirements.md +1 -2
- package/dist/src/agents/tester/cli-tester/playbook.md +2 -0
- package/dist/src/agents/tester/web-tester/critical-requirements.md +1 -2
- package/dist/src/agents/tester/web-tester/playbook.md +2 -0
- package/package.json +9 -8
- package/src/agents/developer/ai-developer/playbook.md +2 -5
- package/src/agents/developer/api-developer/playbook.md +2 -5
- package/src/agents/developer/cli-developer/playbook.md +2 -5
- package/src/agents/developer/web-developer/playbook.md +2 -5
- package/src/agents/meta/agent-summoner/output.md +2 -2
- package/src/agents/meta/agent-summoner/playbook.md +1 -13
- package/src/agents/meta/codex-keeper/critical-requirements.md +2 -5
- package/src/agents/meta/convention-keeper/critical-requirements.md +2 -4
- package/src/agents/tester/ai-tester/critical-requirements.md +1 -2
- package/src/agents/tester/ai-tester/playbook.md +2 -0
- package/src/agents/tester/api-tester/critical-requirements.md +1 -2
- package/src/agents/tester/api-tester/playbook.md +2 -0
- package/src/agents/tester/cli-tester/critical-requirements.md +1 -2
- package/src/agents/tester/cli-tester/playbook.md +2 -0
- package/src/agents/tester/web-tester/critical-requirements.md +1 -2
- package/src/agents/tester/web-tester/playbook.md +2 -0
- package/src/schemas/project-config.schema.json +0 -3
- package/src/schemas/project-source-config.schema.json +0 -6
- package/dist/chunk-3G7X2WKI.js.map +0 -1
- package/dist/chunk-44TE3RKH.js.map +0 -1
- package/dist/chunk-4AAOOAIN.js.map +0 -1
- package/dist/chunk-52HDHJ7I.js.map +0 -1
- package/dist/chunk-6HNXYYVF.js +0 -373
- package/dist/chunk-6HNXYYVF.js.map +0 -1
- package/dist/chunk-6ZRH5RHC.js.map +0 -1
- package/dist/chunk-7RDMTR64.js.map +0 -1
- package/dist/chunk-BMRUNMPV.js.map +0 -1
- package/dist/chunk-CLPUWOSA.js +0 -46
- package/dist/chunk-CLPUWOSA.js.map +0 -1
- package/dist/chunk-F2BHT5C4.js.map +0 -1
- package/dist/chunk-F5EBEATU.js.map +0 -1
- package/dist/chunk-HED2DAXZ.js.map +0 -1
- package/dist/chunk-JFLVEFFP.js.map +0 -1
- package/dist/chunk-KOLDW6SF.js.map +0 -1
- package/dist/chunk-MQ6CGZNJ.js.map +0 -1
- package/dist/chunk-NCWDK6L7.js.map +0 -1
- package/dist/chunk-NEZ4OAOL.js.map +0 -1
- package/dist/chunk-NIHUOWE4.js +0 -106
- package/dist/chunk-NIHUOWE4.js.map +0 -1
- package/dist/chunk-NQW25DCF.js.map +0 -1
- package/dist/chunk-OYJQUA3D.js.map +0 -1
- package/dist/chunk-PJWGTNOX.js.map +0 -1
- package/dist/chunk-RIPSGNLU.js.map +0 -1
- package/dist/chunk-SZYQISA2.js.map +0 -1
- package/dist/chunk-USVBYQSQ.js.map +0 -1
- package/dist/chunk-V3KTSP3Q.js +0 -940
- package/dist/chunk-V3KTSP3Q.js.map +0 -1
- package/dist/chunk-WTWMGH2C.js.map +0 -1
- package/dist/load-agent-defs-YMDWBFDP.js +0 -14
- package/dist/recompile-project-agents-SZ76WNTW.js +0 -18
- package/dist/source-loader-C5SQXZXI.js.map +0 -1
- /package/dist/{load-agent-defs-YMDWBFDP.js.map → load-agent-defs-UBWITIEI.js.map} +0 -0
- /package/dist/{recompile-project-agents-SZ76WNTW.js.map → source-loader-YGG7DY2W.js.map} +0 -0
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BaseCommand,
|
|
4
4
|
EXIT_CODES
|
|
5
|
-
} from "../../chunk-
|
|
6
|
-
import "../../chunk-CLPUWOSA.js";
|
|
5
|
+
} from "../../chunk-QIR56IDM.js";
|
|
7
6
|
import {
|
|
8
7
|
generateMarketplace,
|
|
9
8
|
getErrorMessage,
|
|
@@ -12,8 +11,8 @@ import {
|
|
|
12
11
|
marketplaceHasNoVersion,
|
|
13
12
|
marketplaceNameNotPublishable,
|
|
14
13
|
marketplaceOwnerHasNoName,
|
|
15
|
-
plural,
|
|
16
14
|
readFile,
|
|
15
|
+
readSourceRepoConfig,
|
|
17
16
|
setVerbose,
|
|
18
17
|
validateKebabCaseName,
|
|
19
18
|
validateMarketplaceName,
|
|
@@ -21,8 +20,10 @@ import {
|
|
|
21
20
|
warn,
|
|
22
21
|
writeFile,
|
|
23
22
|
writeMarketplace
|
|
24
|
-
} from "../../chunk-
|
|
25
|
-
import
|
|
23
|
+
} from "../../chunk-3YYHL76L.js";
|
|
24
|
+
import {
|
|
25
|
+
plural
|
|
26
|
+
} from "../../chunk-24OD7IP4.js";
|
|
26
27
|
import {
|
|
27
28
|
CATALOG_JSON,
|
|
28
29
|
CLI_INVOKE_COMMAND,
|
|
@@ -31,8 +32,8 @@ import {
|
|
|
31
32
|
PLUGINS_DIST_PATH,
|
|
32
33
|
PLUGIN_MANIFEST_DIR,
|
|
33
34
|
STANDARD_FILES
|
|
34
|
-
} from "../../chunk-
|
|
35
|
-
import "../../chunk-
|
|
35
|
+
} from "../../chunk-A6OWEJGC.js";
|
|
36
|
+
import "../../chunk-GHHJYNAN.js";
|
|
36
37
|
|
|
37
38
|
// src/cli/commands/build/marketplace.ts
|
|
38
39
|
import { Flags } from "@oclif/core";
|
|
@@ -122,6 +123,31 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
|
122
123
|
}
|
|
123
124
|
async loadMarketplaceIdentity(projectRoot, nameOverride) {
|
|
124
125
|
const packageJsonPath = path.join(projectRoot, STANDARD_FILES.PACKAGE_JSON);
|
|
126
|
+
const { name, version, description, author } = await this.readPackageJson(
|
|
127
|
+
projectRoot,
|
|
128
|
+
packageJsonPath
|
|
129
|
+
);
|
|
130
|
+
if (version.trim() === "") {
|
|
131
|
+
this.error(marketplaceHasNoVersion(packageJsonPath), { exit: EXIT_CODES.ERROR });
|
|
132
|
+
}
|
|
133
|
+
const owner = parseAuthor(author);
|
|
134
|
+
if (owner.name.trim() === "") {
|
|
135
|
+
this.error(marketplaceOwnerHasNoName(packageJsonPath), { exit: EXIT_CODES.ERROR });
|
|
136
|
+
}
|
|
137
|
+
const resolvedName = this.resolvePublishableName(name, nameOverride, packageJsonPath);
|
|
138
|
+
const reservedError = validateMarketplaceName(resolvedName, name, RESERVED_NAME_WAY_OUT);
|
|
139
|
+
if (reservedError) {
|
|
140
|
+
this.error(reservedError, { exit: EXIT_CODES.ERROR });
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
name: resolvedName,
|
|
144
|
+
version,
|
|
145
|
+
description,
|
|
146
|
+
ownerName: owner.name,
|
|
147
|
+
...owner.email !== void 0 && { ownerEmail: owner.email }
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
async readPackageJson(projectRoot, packageJsonPath) {
|
|
125
151
|
let rawContent;
|
|
126
152
|
try {
|
|
127
153
|
rawContent = await readFile(packageJsonPath);
|
|
@@ -147,36 +173,9 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
|
147
173
|
{ exit: EXIT_CODES.ERROR }
|
|
148
174
|
);
|
|
149
175
|
}
|
|
150
|
-
|
|
151
|
-
if (version.trim() === "") {
|
|
152
|
-
this.error(marketplaceHasNoVersion(packageJsonPath), { exit: EXIT_CODES.ERROR });
|
|
153
|
-
}
|
|
154
|
-
const owner = parseAuthor(author);
|
|
155
|
-
if (owner.name.trim() === "") {
|
|
156
|
-
this.error(marketplaceOwnerHasNoName(packageJsonPath), { exit: EXIT_CODES.ERROR });
|
|
157
|
-
}
|
|
158
|
-
const resolvedName = this.resolvePublishableName(name, nameOverride, packageJsonPath);
|
|
159
|
-
const reservedError = validateMarketplaceName(resolvedName, name, RESERVED_NAME_WAY_OUT);
|
|
160
|
-
if (reservedError) {
|
|
161
|
-
this.error(reservedError, { exit: EXIT_CODES.ERROR });
|
|
162
|
-
}
|
|
163
|
-
return {
|
|
164
|
-
name: resolvedName,
|
|
165
|
-
version,
|
|
166
|
-
description,
|
|
167
|
-
ownerName: owner.name,
|
|
168
|
-
...owner.email !== void 0 && { ownerEmail: owner.email }
|
|
169
|
-
};
|
|
176
|
+
return parseResult.data;
|
|
170
177
|
}
|
|
171
|
-
/**
|
|
172
|
-
* The name this marketplace publishes under, refused before anything is written when
|
|
173
|
-
* it is not one `claude plugin marketplace add` will accept.
|
|
174
|
-
*
|
|
175
|
-
* Both halves are judged by the same rule and refused with different sentences: a
|
|
176
|
-
* `--name` the author typed is an argument they can retype, while a name derived from
|
|
177
|
-
* package.json is a fact about their package — an npm scoped name is legitimate there
|
|
178
|
-
* and illegitimate here — so its way out is the flag rather than a package rename.
|
|
179
|
-
*/
|
|
178
|
+
/** A package.json name that fails gets a different refusal: its way out is `--name`. */
|
|
180
179
|
resolvePublishableName(packageName, nameOverride, packageJsonPath) {
|
|
181
180
|
if (nameOverride !== void 0) {
|
|
182
181
|
const invalidOverride = validateKebabCaseName(nameOverride, MARKETPLACE_NOUN);
|
|
@@ -222,18 +221,10 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
|
222
221
|
}
|
|
223
222
|
return marketplace;
|
|
224
223
|
}
|
|
225
|
-
/**
|
|
226
|
-
* The catalogue published beside the manifest.
|
|
227
|
-
*
|
|
228
|
-
* Unconditional, and there is no flag to make it otherwise: a consumer
|
|
229
|
-
* fetching a marketplace cannot tell an author who omitted a flag from a
|
|
230
|
-
* marketplace that is broken, so an absent catalogue has to mean the second.
|
|
231
|
-
*
|
|
232
|
-
* `generatedAt` is stamped rather than carried: see {@link GENERATED_AT_BUILD}
|
|
233
|
-
* for why a published artefact records a build and not a moment.
|
|
234
|
-
*/
|
|
224
|
+
/** Unconditional: consumers must be able to read an absent catalogue as a broken marketplace. */
|
|
235
225
|
async readCatalog(projectRoot) {
|
|
236
226
|
this.log(`Reading the skills for ${CATALOG_JSON}...`);
|
|
227
|
+
await warnOfAConfigDeclaringNothing(projectRoot);
|
|
237
228
|
const matrix = await loadMarketplaceMatrix(projectRoot);
|
|
238
229
|
return { ...matrix, generatedAt: GENERATED_AT_BUILD };
|
|
239
230
|
}
|
|
@@ -277,6 +268,15 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
|
277
268
|
}
|
|
278
269
|
}
|
|
279
270
|
};
|
|
271
|
+
async function warnOfAConfigDeclaringNothing(projectRoot) {
|
|
272
|
+
const read = await readSourceRepoConfig(projectRoot);
|
|
273
|
+
if (read.kind === "declares-nothing") {
|
|
274
|
+
warn(configDeclaresNothing(path.relative(projectRoot, read.configPath)));
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function configDeclaresNothing(configPath) {
|
|
278
|
+
return `${configPath} is empty or exports nothing, so this build reads the marketplace with the default layout. Give it a default export, or delete it.`;
|
|
279
|
+
}
|
|
280
280
|
function noPluginsToPublish(pluginsDir, pluginsDirFlag) {
|
|
281
281
|
return `No plugins found in ${pluginsDir}. A marketplace with no plugins is refused when it is read back, so none was written. Run '${CLI_INVOKE_COMMAND} build plugins' first, or point --plugins-dir at the directory holding them (it is '${pluginsDirFlag}' for this run).`;
|
|
282
282
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/build/marketplace.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\nimport { z } from \"zod\";\n\nimport { BaseCommand } from \"../../base-command\";\nimport { setVerbose, warn } from \"../../utils/logger\";\nimport {\n marketplaceHasNoVersion,\n marketplaceNameNotPublishable,\n marketplaceOwnerHasNoName,\n} from \"../../utils/messages\";\nimport { readFile, writeFile } from \"../../utils/fs\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { EXIT_CODES } from \"../../lib/exit-codes\";\nimport { loadMarketplaceMatrix } from \"../../lib/loading\";\nimport {\n generateMarketplace,\n writeMarketplace,\n getMarketplaceStats,\n validateMarketplaceName,\n validateSkillIdNamespace,\n} from \"../../lib/marketplace-generator\";\nimport {\n CATALOG_JSON,\n CLI_INVOKE_COMMAND,\n GENERATED_AT_BUILD,\n MARKETPLACE_JSON,\n PLUGIN_MANIFEST_DIR,\n PLUGINS_DIST_PATH,\n STANDARD_FILES,\n} from \"../../consts\";\nimport type { Marketplace, MergedSkillsMatrix } from \"../../types\";\nimport { validateKebabCaseName } from \"../../lib/validate-kebab-name.js\";\nimport { plural } from \"../../utils/string.js\";\n\nconst DEFAULT_OUTPUT_FILE = `${PLUGIN_MANIFEST_DIR}/${MARKETPLACE_JSON}`;\n\nconst AUTHOR_STRING_PATTERN = /^(.*?)\\s*<([^>]+)>\\s*(?:\\(([^)]+)\\))?\\s*$/;\n\n/** The entity {@link validateKebabCaseName} names in this command's refusals. */\nconst MARKETPLACE_NOUN = \"Marketplace\";\n\n/** How a reserved name is replaced here: it is read off package.json, and `--name` overrides it. */\nconst RESERVED_NAME_WAY_OUT = \"set package.json 'name', or pass --name\";\n\nconst packageAuthorObjectSchema = z.object({\n name: z.string(),\n email: z.string().exactOptional(),\n url: z.string().exactOptional(),\n});\n\nconst packageJsonSchema = z\n .object({\n name: z.string(),\n version: z.string(),\n description: z.string(),\n author: z.union([z.string(), packageAuthorObjectSchema]).exactOptional(),\n })\n .passthrough();\n\ntype PackageJson = z.infer<typeof packageJsonSchema>;\ntype MarketplaceIdentity = Pick<PackageJson, \"name\" | \"version\" | \"description\"> & {\n ownerName: string;\n ownerEmail?: string;\n};\n\nexport default class BuildMarketplace extends BaseCommand {\n static summary = \"Generate marketplace.json from built plugins (requires skills repo)\";\n\n static description =\n \"Generate marketplace.json from built plugins. This command scans the plugins directory and generates a marketplace manifest file. Reads marketplace identity (name, version, description, author) from package.json in the current working directory. Use --name to override the marketplace name when package.json uses an npm scoped name (e.g. @scope/pkg), which is not a valid marketplace name.\";\n\n static examples = [\n {\n description: \"Generate marketplace.json from the default plugins directory\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Generate marketplace.json from a custom plugins directory\",\n command: \"<%= config.bin %> <%= command.id %> --plugins-dir dist/stacks\",\n },\n {\n description: \"Write marketplace.json to a custom output path\",\n command: \"<%= config.bin %> <%= command.id %> --output .claude-plugin/market.json\",\n },\n {\n description:\n \"Override the marketplace name (use when package.json has an npm scoped name like @scope/pkg)\",\n command: \"<%= config.bin %> <%= command.id %> --name my-marketplace\",\n },\n ];\n\n static flags = {\n name: Flags.string({\n description:\n \"Override the marketplace name (defaults to package.json 'name'). Must be kebab-case.\",\n }),\n \"plugins-dir\": Flags.string({\n char: \"p\",\n description: \"Plugins directory\",\n default: PLUGINS_DIST_PATH,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output file\",\n default: DEFAULT_OUTPUT_FILE,\n }),\n verbose: Flags.boolean({\n char: \"v\",\n description: \"Enable verbose logging\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(BuildMarketplace);\n setVerbose(flags.verbose);\n\n const projectRoot = process.cwd();\n const pluginsDir = path.resolve(projectRoot, flags[\"plugins-dir\"]);\n const outputPath = path.resolve(projectRoot, flags.output);\n const identity = await this.loadMarketplaceIdentity(projectRoot, flags.name);\n\n this.printHeader(pluginsDir, outputPath);\n\n try {\n // Everything is read and refused before the first write: a build that fails writes nothing,\n // so the manifest and the catalogue on disk always describe the same build.\n const marketplace = await this.scanPlugins(pluginsDir, flags[\"plugins-dir\"], identity);\n const catalog = await this.readCatalog(projectRoot);\n\n await this.writeManifest(outputPath, marketplace);\n await this.writeCatalog(outputPath, catalog);\n this.printStats(marketplace);\n this.printSample(marketplace);\n\n this.log(\"\");\n this.logSuccess(\n `Marketplace generated with ${plural(getMarketplaceStats(marketplace).total, \"plugin\")}!`,\n );\n this.log(\"\");\n } catch (error) {\n this.log(\"Generation failed\");\n this.handleError(error);\n }\n }\n\n private async loadMarketplaceIdentity(\n projectRoot: string,\n nameOverride?: string,\n ): Promise<MarketplaceIdentity> {\n const packageJsonPath = path.join(projectRoot, STANDARD_FILES.PACKAGE_JSON);\n\n let rawContent: string;\n try {\n rawContent = await readFile(packageJsonPath);\n } catch {\n this.error(\n `Missing package.json at ${projectRoot}. build marketplace reads marketplace identity from package.json.`,\n { exit: EXIT_CODES.ERROR },\n );\n }\n\n let parsedJson: unknown;\n try {\n parsedJson = JSON.parse(rawContent);\n } catch (error) {\n this.error(`Failed to parse package.json at ${packageJsonPath}: ${getErrorMessage(error)}`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n const parseResult = packageJsonSchema.safeParse(parsedJson);\n if (!parseResult.success) {\n const missingFields = parseResult.error.issues.map((i) => i.path.join(\".\")).join(\", \");\n this.error(\n `package.json at ${packageJsonPath} is missing required fields: ${missingFields}. build marketplace reads marketplace identity from package.json.`,\n { exit: EXIT_CODES.ERROR },\n );\n }\n\n const { name, version, description, author } = parseResult.data;\n\n if (version.trim() === \"\") {\n this.error(marketplaceHasNoVersion(packageJsonPath), { exit: EXIT_CODES.ERROR });\n }\n\n const owner = parseAuthor(author);\n if (owner.name.trim() === \"\") {\n this.error(marketplaceOwnerHasNoName(packageJsonPath), { exit: EXIT_CODES.ERROR });\n }\n\n const resolvedName = this.resolvePublishableName(name, nameOverride, packageJsonPath);\n\n const reservedError = validateMarketplaceName(resolvedName, name, RESERVED_NAME_WAY_OUT);\n if (reservedError) {\n this.error(reservedError, { exit: EXIT_CODES.ERROR });\n }\n\n return {\n name: resolvedName,\n version,\n description,\n ownerName: owner.name,\n ...(owner.email !== undefined && { ownerEmail: owner.email }),\n };\n }\n\n /**\n * The name this marketplace publishes under, refused before anything is written when\n * it is not one `claude plugin marketplace add` will accept.\n *\n * Both halves are judged by the same rule and refused with different sentences: a\n * `--name` the author typed is an argument they can retype, while a name derived from\n * package.json is a fact about their package — an npm scoped name is legitimate there\n * and illegitimate here — so its way out is the flag rather than a package rename.\n */\n private resolvePublishableName(\n packageName: string,\n nameOverride: string | undefined,\n packageJsonPath: string,\n ): string {\n if (nameOverride !== undefined) {\n const invalidOverride = validateKebabCaseName(nameOverride, MARKETPLACE_NOUN);\n if (invalidOverride) {\n this.error(`Invalid --name '${nameOverride}': ${invalidOverride}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n return nameOverride;\n }\n\n if (validateKebabCaseName(packageName, MARKETPLACE_NOUN)) {\n this.error(marketplaceNameNotPublishable(packageName, packageJsonPath), {\n exit: EXIT_CODES.ERROR,\n });\n }\n return packageName;\n }\n\n private printHeader(pluginsDir: string, outputPath: string): void {\n this.log(\"\");\n this.log(\"Generating marketplace.json\");\n this.log(` Plugins directory: ${pluginsDir}`);\n this.log(` Output file: ${outputPath}`);\n this.log(\"\");\n }\n\n private async scanPlugins(\n pluginsDir: string,\n pluginsDirFlag: string,\n identity: MarketplaceIdentity,\n ): Promise<Marketplace> {\n this.log(\"Scanning plugins...\");\n\n const marketplace = await generateMarketplace(pluginsDir, {\n name: identity.name,\n version: identity.version,\n description: identity.description,\n ownerName: identity.ownerName,\n ...(identity.ownerEmail !== undefined && { ownerEmail: identity.ownerEmail }),\n pluginRoot: `./${pluginsDirFlag}`,\n });\n\n const stats = getMarketplaceStats(marketplace);\n this.log(`Found ${plural(stats.total, \"plugin\")}`);\n\n if (marketplace.plugins.length === 0) {\n this.error(noPluginsToPublish(pluginsDir, pluginsDirFlag), { exit: EXIT_CODES.ERROR });\n }\n\n const namespaceError = validateSkillIdNamespace(marketplace);\n if (namespaceError) {\n this.error(namespaceError, { exit: EXIT_CODES.ERROR });\n }\n\n return marketplace;\n }\n\n /**\n * The catalogue published beside the manifest.\n *\n * Unconditional, and there is no flag to make it otherwise: a consumer\n * fetching a marketplace cannot tell an author who omitted a flag from a\n * marketplace that is broken, so an absent catalogue has to mean the second.\n *\n * `generatedAt` is stamped rather than carried: see {@link GENERATED_AT_BUILD}\n * for why a published artefact records a build and not a moment.\n */\n private async readCatalog(projectRoot: string): Promise<MergedSkillsMatrix> {\n this.log(`Reading the skills for ${CATALOG_JSON}...`);\n const matrix = await loadMarketplaceMatrix(projectRoot);\n return { ...matrix, generatedAt: GENERATED_AT_BUILD };\n }\n\n private async writeManifest(outputPath: string, marketplace: Marketplace): Promise<void> {\n this.log(`Writing ${MARKETPLACE_JSON}...`);\n await writeMarketplace(outputPath, marketplace);\n this.log(`Wrote ${outputPath}`);\n }\n\n private async writeCatalog(outputPath: string, catalog: MergedSkillsMatrix): Promise<void> {\n const catalogPath = path.join(path.dirname(outputPath), CATALOG_JSON);\n\n this.log(`Writing ${CATALOG_JSON}...`);\n await writeFile(catalogPath, `${JSON.stringify(catalog, null, 2)}\\n`);\n this.log(`Wrote ${catalogPath}`);\n }\n\n private printStats(marketplace: Marketplace): void {\n this.log(\"\");\n this.log(\"Category breakdown:\");\n const sortedCategories = sortBy(\n Object.entries(getMarketplaceStats(marketplace).byCategory),\n ([, count]) => -count,\n );\n for (const [category, count] of sortedCategories) {\n this.log(` ${category}: ${count}`);\n }\n }\n\n private printSample(marketplace: Marketplace): void {\n this.log(\"\");\n this.log(\"Sample plugins:\");\n const sampleSize = 5;\n for (const plugin of marketplace.plugins.slice(0, sampleSize)) {\n const version = plugin.version ? `v${plugin.version}` : \"\";\n const category = plugin.category ? `[${plugin.category}]` : \"\";\n this.log(` ${plugin.name} ${version} ${category}`);\n if (plugin.description) {\n this.log(` ${plugin.description}`);\n }\n }\n if (marketplace.plugins.length > sampleSize) {\n this.log(` ... and ${marketplace.plugins.length - sampleSize} more`);\n }\n }\n}\n\ntype ParsedAuthor = {\n name: string;\n email?: string;\n};\n\n/**\n * Refuses a manifest with no plugins in it, which the reader in this same package will not accept:\n * `marketplaceSchema.plugins` is `z.array(...).min(1)`, so `fetchMarketplace` throws\n * `plugins: Too small` on a file this command wrote and called a success. Every field that schema\n * constrains is a condition this command refuses before writing — `name`, `version` and\n * `owner.name` are the other three, all guarded off package.json. `version` was the one this\n * sentence claimed and did not have: `packageJsonSchema` types it as a bare string and the\n * generator defaults it with `??`, so `\"\"` reached the manifest untouched. This one is only\n * knowable after the scan, which is why it sits here rather than beside them.\n *\n * The two ways in are running before `build plugins` and pointing `--plugins-dir` somewhere else, so\n * the sentence names the directory it scanned and both ways out. Written here rather than in\n * `utils/messages.ts` for the reason the `Missing package.json` refusal above it is: it has one\n * caller and composes nothing another surface has to agree with.\n */\nfunction noPluginsToPublish(pluginsDir: string, pluginsDirFlag: string): string {\n return (\n `No plugins found in ${pluginsDir}. A marketplace with no plugins is refused when it is read ` +\n `back, so none was written. Run '${CLI_INVOKE_COMMAND} build plugins' first, or point ` +\n `--plugins-dir at the directory holding them (it is '${pluginsDirFlag}' for this run).`\n );\n}\n\n/**\n * Parses a package.json `author` field into name + optional email.\n *\n * npm supports both shorthand strings `\"Name <email> (url)\"` and object form\n * `{ name, email, url }`. An absent author and one that yields no name both come back\n * with an empty `name`, and the caller refuses on that — one condition, one sentence,\n * written where the refusal is. A missing EMAIL is warned about and carried on from,\n * because `owner.email` is the half the manifest schema leaves optional.\n */\nfunction parseAuthor(author: string | { name: string; email?: string } | undefined): ParsedAuthor {\n if (!author) return { name: \"\" };\n\n if (typeof author === \"object\") {\n return { name: author.name, ...(author.email !== undefined && { email: author.email }) };\n }\n\n const [, matchedName, matchedEmail] = author.match(AUTHOR_STRING_PATTERN) ?? [];\n if (matchedName !== undefined && matchedEmail !== undefined) {\n return { name: matchedName.trim(), email: matchedEmail.trim() };\n }\n\n warn(\n `package.json 'author' field \"${author}\" has no parseable email — marketplace owner.email will be empty`,\n );\n return { name: author.trim() };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/build/marketplace.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\nimport { z } from \"zod\";\n\nimport { BaseCommand } from \"../../base-command\";\nimport { setVerbose, warn } from \"../../utils/logger\";\nimport {\n marketplaceHasNoVersion,\n marketplaceNameNotPublishable,\n marketplaceOwnerHasNoName,\n} from \"../../utils/messages\";\nimport { readFile, writeFile } from \"../../utils/fs\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { EXIT_CODES } from \"../../lib/exit-codes\";\nimport { readSourceRepoConfig } from \"../../lib/configuration/config\";\nimport { loadMarketplaceMatrix } from \"../../lib/loading\";\nimport {\n generateMarketplace,\n writeMarketplace,\n getMarketplaceStats,\n validateMarketplaceName,\n validateSkillIdNamespace,\n} from \"../../lib/marketplace-generator\";\nimport {\n CATALOG_JSON,\n CLI_INVOKE_COMMAND,\n GENERATED_AT_BUILD,\n MARKETPLACE_JSON,\n PLUGIN_MANIFEST_DIR,\n PLUGINS_DIST_PATH,\n STANDARD_FILES,\n} from \"../../consts\";\nimport type { Marketplace, MergedSkillsMatrix } from \"../../types\";\nimport { validateKebabCaseName } from \"../../lib/validate-kebab-name.js\";\nimport { plural } from \"../../utils/string.js\";\n\nconst DEFAULT_OUTPUT_FILE = `${PLUGIN_MANIFEST_DIR}/${MARKETPLACE_JSON}`;\n\nconst AUTHOR_STRING_PATTERN = /^(.*?)\\s*<([^>]+)>\\s*(?:\\(([^)]+)\\))?\\s*$/;\n\nconst MARKETPLACE_NOUN = \"Marketplace\";\n\nconst RESERVED_NAME_WAY_OUT = \"set package.json 'name', or pass --name\";\n\nconst packageAuthorObjectSchema = z.object({\n name: z.string(),\n email: z.string().exactOptional(),\n url: z.string().exactOptional(),\n});\n\nconst packageJsonSchema = z\n .object({\n name: z.string(),\n version: z.string(),\n description: z.string(),\n author: z.union([z.string(), packageAuthorObjectSchema]).exactOptional(),\n })\n .passthrough();\n\ntype PackageJson = z.infer<typeof packageJsonSchema>;\ntype MarketplaceIdentity = Pick<PackageJson, \"name\" | \"version\" | \"description\"> & {\n ownerName: string;\n ownerEmail?: string;\n};\n\nexport default class BuildMarketplace extends BaseCommand {\n static summary = \"Generate marketplace.json from built plugins (requires skills repo)\";\n\n static description =\n \"Generate marketplace.json from built plugins. This command scans the plugins directory and generates a marketplace manifest file. Reads marketplace identity (name, version, description, author) from package.json in the current working directory. Use --name to override the marketplace name when package.json uses an npm scoped name (e.g. @scope/pkg), which is not a valid marketplace name.\";\n\n static examples = [\n {\n description: \"Generate marketplace.json from the default plugins directory\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Generate marketplace.json from a custom plugins directory\",\n command: \"<%= config.bin %> <%= command.id %> --plugins-dir dist/stacks\",\n },\n {\n description: \"Write marketplace.json to a custom output path\",\n command: \"<%= config.bin %> <%= command.id %> --output .claude-plugin/market.json\",\n },\n {\n description:\n \"Override the marketplace name (use when package.json has an npm scoped name like @scope/pkg)\",\n command: \"<%= config.bin %> <%= command.id %> --name my-marketplace\",\n },\n ];\n\n static flags = {\n name: Flags.string({\n description:\n \"Override the marketplace name (defaults to package.json 'name'). Must be kebab-case.\",\n }),\n \"plugins-dir\": Flags.string({\n char: \"p\",\n description: \"Plugins directory\",\n default: PLUGINS_DIST_PATH,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output file\",\n default: DEFAULT_OUTPUT_FILE,\n }),\n verbose: Flags.boolean({\n char: \"v\",\n description: \"Enable verbose logging\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(BuildMarketplace);\n setVerbose(flags.verbose);\n\n const projectRoot = process.cwd();\n const pluginsDir = path.resolve(projectRoot, flags[\"plugins-dir\"]);\n const outputPath = path.resolve(projectRoot, flags.output);\n const identity = await this.loadMarketplaceIdentity(projectRoot, flags.name);\n\n this.printHeader(pluginsDir, outputPath);\n\n try {\n // Read and refuse everything before the first write, so manifest and catalogue always agree.\n const marketplace = await this.scanPlugins(pluginsDir, flags[\"plugins-dir\"], identity);\n const catalog = await this.readCatalog(projectRoot);\n\n await this.writeManifest(outputPath, marketplace);\n await this.writeCatalog(outputPath, catalog);\n this.printStats(marketplace);\n this.printSample(marketplace);\n\n this.log(\"\");\n this.logSuccess(\n `Marketplace generated with ${plural(getMarketplaceStats(marketplace).total, \"plugin\")}!`,\n );\n this.log(\"\");\n } catch (error) {\n this.log(\"Generation failed\");\n this.handleError(error);\n }\n }\n\n private async loadMarketplaceIdentity(\n projectRoot: string,\n nameOverride?: string,\n ): Promise<MarketplaceIdentity> {\n const packageJsonPath = path.join(projectRoot, STANDARD_FILES.PACKAGE_JSON);\n const { name, version, description, author } = await this.readPackageJson(\n projectRoot,\n packageJsonPath,\n );\n\n if (version.trim() === \"\") {\n this.error(marketplaceHasNoVersion(packageJsonPath), { exit: EXIT_CODES.ERROR });\n }\n\n const owner = parseAuthor(author);\n if (owner.name.trim() === \"\") {\n this.error(marketplaceOwnerHasNoName(packageJsonPath), { exit: EXIT_CODES.ERROR });\n }\n\n const resolvedName = this.resolvePublishableName(name, nameOverride, packageJsonPath);\n\n const reservedError = validateMarketplaceName(resolvedName, name, RESERVED_NAME_WAY_OUT);\n if (reservedError) {\n this.error(reservedError, { exit: EXIT_CODES.ERROR });\n }\n\n return {\n name: resolvedName,\n version,\n description,\n ownerName: owner.name,\n ...(owner.email !== undefined && { ownerEmail: owner.email }),\n };\n }\n\n private async readPackageJson(\n projectRoot: string,\n packageJsonPath: string,\n ): Promise<PackageJson> {\n let rawContent: string;\n try {\n rawContent = await readFile(packageJsonPath);\n } catch {\n this.error(\n `Missing package.json at ${projectRoot}. build marketplace reads marketplace identity from package.json.`,\n { exit: EXIT_CODES.ERROR },\n );\n }\n\n let parsedJson: unknown;\n try {\n parsedJson = JSON.parse(rawContent);\n } catch (error) {\n this.error(`Failed to parse package.json at ${packageJsonPath}: ${getErrorMessage(error)}`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n const parseResult = packageJsonSchema.safeParse(parsedJson);\n if (!parseResult.success) {\n const missingFields = parseResult.error.issues.map((i) => i.path.join(\".\")).join(\", \");\n this.error(\n `package.json at ${packageJsonPath} is missing required fields: ${missingFields}. build marketplace reads marketplace identity from package.json.`,\n { exit: EXIT_CODES.ERROR },\n );\n }\n\n return parseResult.data;\n }\n\n /** A package.json name that fails gets a different refusal: its way out is `--name`. */\n private resolvePublishableName(\n packageName: string,\n nameOverride: string | undefined,\n packageJsonPath: string,\n ): string {\n if (nameOverride !== undefined) {\n const invalidOverride = validateKebabCaseName(nameOverride, MARKETPLACE_NOUN);\n if (invalidOverride) {\n this.error(`Invalid --name '${nameOverride}': ${invalidOverride}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n return nameOverride;\n }\n\n if (validateKebabCaseName(packageName, MARKETPLACE_NOUN)) {\n this.error(marketplaceNameNotPublishable(packageName, packageJsonPath), {\n exit: EXIT_CODES.ERROR,\n });\n }\n return packageName;\n }\n\n private printHeader(pluginsDir: string, outputPath: string): void {\n this.log(\"\");\n this.log(\"Generating marketplace.json\");\n this.log(` Plugins directory: ${pluginsDir}`);\n this.log(` Output file: ${outputPath}`);\n this.log(\"\");\n }\n\n private async scanPlugins(\n pluginsDir: string,\n pluginsDirFlag: string,\n identity: MarketplaceIdentity,\n ): Promise<Marketplace> {\n this.log(\"Scanning plugins...\");\n\n const marketplace = await generateMarketplace(pluginsDir, {\n name: identity.name,\n version: identity.version,\n description: identity.description,\n ownerName: identity.ownerName,\n ...(identity.ownerEmail !== undefined && { ownerEmail: identity.ownerEmail }),\n pluginRoot: `./${pluginsDirFlag}`,\n });\n\n const stats = getMarketplaceStats(marketplace);\n this.log(`Found ${plural(stats.total, \"plugin\")}`);\n\n if (marketplace.plugins.length === 0) {\n this.error(noPluginsToPublish(pluginsDir, pluginsDirFlag), { exit: EXIT_CODES.ERROR });\n }\n\n const namespaceError = validateSkillIdNamespace(marketplace);\n if (namespaceError) {\n this.error(namespaceError, { exit: EXIT_CODES.ERROR });\n }\n\n return marketplace;\n }\n\n /** Unconditional: consumers must be able to read an absent catalogue as a broken marketplace. */\n private async readCatalog(projectRoot: string): Promise<MergedSkillsMatrix> {\n this.log(`Reading the skills for ${CATALOG_JSON}...`);\n await warnOfAConfigDeclaringNothing(projectRoot);\n const matrix = await loadMarketplaceMatrix(projectRoot);\n return { ...matrix, generatedAt: GENERATED_AT_BUILD };\n }\n\n private async writeManifest(outputPath: string, marketplace: Marketplace): Promise<void> {\n this.log(`Writing ${MARKETPLACE_JSON}...`);\n await writeMarketplace(outputPath, marketplace);\n this.log(`Wrote ${outputPath}`);\n }\n\n private async writeCatalog(outputPath: string, catalog: MergedSkillsMatrix): Promise<void> {\n const catalogPath = path.join(path.dirname(outputPath), CATALOG_JSON);\n\n this.log(`Writing ${CATALOG_JSON}...`);\n await writeFile(catalogPath, `${JSON.stringify(catalog, null, 2)}\\n`);\n this.log(`Wrote ${catalogPath}`);\n }\n\n private printStats(marketplace: Marketplace): void {\n this.log(\"\");\n this.log(\"Category breakdown:\");\n const sortedCategories = sortBy(\n Object.entries(getMarketplaceStats(marketplace).byCategory),\n ([, count]) => -count,\n );\n for (const [category, count] of sortedCategories) {\n this.log(` ${category}: ${count}`);\n }\n }\n\n private printSample(marketplace: Marketplace): void {\n this.log(\"\");\n this.log(\"Sample plugins:\");\n const sampleSize = 5;\n for (const plugin of marketplace.plugins.slice(0, sampleSize)) {\n const version = plugin.version ? `v${plugin.version}` : \"\";\n const category = plugin.category ? `[${plugin.category}]` : \"\";\n this.log(` ${plugin.name} ${version} ${category}`);\n if (plugin.description) {\n this.log(` ${plugin.description}`);\n }\n }\n if (marketplace.plugins.length > sampleSize) {\n this.log(` ... and ${marketplace.plugins.length - sampleSize} more`);\n }\n }\n}\n\ntype ParsedAuthor = {\n name: string;\n email?: string;\n};\n\n/** The loader reads such a file as absent, so without this the build would say nothing of it. */\nasync function warnOfAConfigDeclaringNothing(projectRoot: string): Promise<void> {\n const read = await readSourceRepoConfig(projectRoot);\n if (read.kind === \"declares-nothing\") {\n warn(configDeclaresNothing(path.relative(projectRoot, read.configPath)));\n }\n}\n\nfunction configDeclaresNothing(configPath: string): string {\n return (\n `${configPath} is empty or exports nothing, so this build reads the marketplace with the ` +\n `default layout. Give it a default export, or delete it.`\n );\n}\n\n/** The marketplace schema requires at least one plugin, so an empty manifest is never written. */\nfunction noPluginsToPublish(pluginsDir: string, pluginsDirFlag: string): string {\n return (\n `No plugins found in ${pluginsDir}. A marketplace with no plugins is refused when it is read ` +\n `back, so none was written. Run '${CLI_INVOKE_COMMAND} build plugins' first, or point ` +\n `--plugins-dir at the directory holding them (it is '${pluginsDirFlag}' for this run).`\n );\n}\n\n/** Accepts `\"Name <email> (url)\"` or `{ name, email, url }`; the caller refuses an empty name. */\nfunction parseAuthor(author: string | { name: string; email?: string } | undefined): ParsedAuthor {\n if (!author) return { name: \"\" };\n\n if (typeof author === \"object\") {\n return { name: author.name, ...(author.email !== undefined && { email: author.email }) };\n }\n\n const [, matchedName, matchedEmail] = author.match(AUTHOR_STRING_PATTERN) ?? [];\n if (matchedName !== undefined && matchedEmail !== undefined) {\n return { name: matchedName.trim(), email: matchedEmail.trim() };\n }\n\n warn(\n `package.json 'author' field \"${author}\" has no parseable email — marketplace owner.email will be empty`,\n );\n return { name: author.trim() };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,28 +2,28 @@
|
|
|
2
2
|
import {
|
|
3
3
|
compileAllAgentPlugins,
|
|
4
4
|
printAgentCompilationSummary
|
|
5
|
-
} from "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
5
|
+
} from "../../chunk-WII6GOPM.js";
|
|
6
|
+
import "../../chunk-AWWCRL5A.js";
|
|
7
7
|
import {
|
|
8
8
|
BaseCommand
|
|
9
|
-
} from "../../chunk-
|
|
10
|
-
import "../../chunk-CLPUWOSA.js";
|
|
9
|
+
} from "../../chunk-QIR56IDM.js";
|
|
11
10
|
import {
|
|
12
11
|
compileAllSkillPlugins,
|
|
13
12
|
compileSkillPlugin,
|
|
14
13
|
listDirectories,
|
|
15
|
-
plural,
|
|
16
14
|
printCompilationSummary,
|
|
17
15
|
readPluginManifest,
|
|
18
16
|
remove,
|
|
19
17
|
setVerbose
|
|
20
|
-
} from "../../chunk-
|
|
21
|
-
import
|
|
18
|
+
} from "../../chunk-3YYHL76L.js";
|
|
19
|
+
import {
|
|
20
|
+
plural
|
|
21
|
+
} from "../../chunk-24OD7IP4.js";
|
|
22
22
|
import {
|
|
23
23
|
DIRS,
|
|
24
24
|
PLUGINS_DIST_PATH
|
|
25
|
-
} from "../../chunk-
|
|
26
|
-
import "../../chunk-
|
|
25
|
+
} from "../../chunk-A6OWEJGC.js";
|
|
26
|
+
import "../../chunk-GHHJYNAN.js";
|
|
27
27
|
|
|
28
28
|
// src/cli/commands/build/plugins.ts
|
|
29
29
|
import { Flags } from "@oclif/core";
|
|
@@ -102,24 +102,26 @@ var BuildPlugins = class _BuildPlugins extends BaseCommand {
|
|
|
102
102
|
this.log("");
|
|
103
103
|
}
|
|
104
104
|
/**
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* must be skipped: single-skill mode (would wipe every other plugin) or a
|
|
108
|
-
* partial compile failure (a failed skill is indistinguishable from a removed
|
|
109
|
-
* one, so deleting it would be a worse bug than the stale entry).
|
|
105
|
+
* Returns the plugin names that should remain, or `null` to skip pruning: in single-skill mode,
|
|
106
|
+
* or after a failure, since a failed skill is indistinguishable from a removed one.
|
|
110
107
|
*/
|
|
111
108
|
async compileSkills(skillFlag, skillsDir, outputDir) {
|
|
112
109
|
if (skillFlag) {
|
|
113
|
-
|
|
114
|
-
this.log(`Compiling skill at ${skillPath}...`);
|
|
115
|
-
const result = await compileSkillPlugin({
|
|
116
|
-
skillPath,
|
|
117
|
-
outputDir
|
|
118
|
-
});
|
|
119
|
-
this.log(`Compiled ${result.skillName}`);
|
|
120
|
-
this.log(` Plugin path: ${result.pluginPath}`);
|
|
110
|
+
await this.compileOneSkill(path.resolve(skillsDir, skillFlag), outputDir);
|
|
121
111
|
return null;
|
|
122
112
|
}
|
|
113
|
+
return this.compileEverySkill(skillsDir, outputDir);
|
|
114
|
+
}
|
|
115
|
+
async compileOneSkill(skillPath, outputDir) {
|
|
116
|
+
this.log(`Compiling skill at ${skillPath}...`);
|
|
117
|
+
const result = await compileSkillPlugin({
|
|
118
|
+
skillPath,
|
|
119
|
+
outputDir
|
|
120
|
+
});
|
|
121
|
+
this.log(`Compiled ${result.skillName}`);
|
|
122
|
+
this.log(` Plugin path: ${result.pluginPath}`);
|
|
123
|
+
}
|
|
124
|
+
async compileEverySkill(skillsDir, outputDir) {
|
|
123
125
|
this.log("Finding and compiling all skills...");
|
|
124
126
|
const { compiled, failed } = await compileAllSkillPlugins(skillsDir, outputDir);
|
|
125
127
|
this.log(`Compiled ${plural(compiled.length, "skill plugin")}`);
|
|
@@ -143,12 +145,7 @@ var BuildPlugins = class _BuildPlugins extends BaseCommand {
|
|
|
143
145
|
this.log(`Compiled ${plural(agentResults.length, "agent plugin")}`);
|
|
144
146
|
printAgentCompilationSummary(agentResults);
|
|
145
147
|
}
|
|
146
|
-
/**
|
|
147
|
-
* Removes skill-plugin directories in `outputDir` that no longer correspond to
|
|
148
|
-
* a compiled skill. Only skill plugins are pruned: agent plugins are preserved
|
|
149
|
-
* (this run has no authority over them) and non-plugin directories are left
|
|
150
|
-
* untouched. Callers must only invoke this after a clean full-scan compile.
|
|
151
|
-
*/
|
|
148
|
+
/** Prunes skill plugins only; agent plugins and non-plugin directories are left alone. */
|
|
152
149
|
async pruneStaleSkillPlugins(outputDir, expectedSkillPlugins) {
|
|
153
150
|
const dirNames = await listDirectories(outputDir);
|
|
154
151
|
for (const dirName of dirNames) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/build/plugins.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport path from \"path\";\n\nimport { BaseCommand } from \"../../base-command\";\nimport { setVerbose } from \"../../utils/logger\";\nimport { listDirectories, remove } from \"../../utils/fs\";\nimport { DIRS, PLUGINS_DIST_PATH } from \"../../consts\";\nimport {\n compileAllSkillPlugins,\n compileSkillPlugin,\n printCompilationSummary,\n} from \"../../lib/skills\";\nimport { compileAllAgentPlugins, printAgentCompilationSummary } from \"../../lib/agents\";\nimport { readPluginManifest } from \"../../lib/plugins\";\nimport { plural } from \"../../utils/string\";\n\nexport default class BuildPlugins extends BaseCommand {\n static summary = \"Build skills and agents into standalone plugins\";\n\n static description =\n \"Build skills and agents into standalone plugins. By default, compiles all skills. Use --skill to compile a specific skill only. Use --agents-dir to also compile agents.\";\n\n static examples = [\n {\n description: \"Compile every skill into plugins\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Compile a single skill by name\",\n command: \"<%= config.bin %> <%= command.id %> --skill cli-commander\",\n },\n {\n description: \"Write plugins to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> --output-dir ./plugins\",\n },\n {\n description: \"Also compile agents from a directory\",\n command: \"<%= config.bin %> <%= command.id %> --agents-dir ./agents\",\n },\n {\n description: \"Compile with verbose logging\",\n command: \"<%= config.bin %> <%= command.id %> --verbose\",\n },\n ];\n\n static flags = {\n \"agents-dir\": Flags.string({\n char: \"a\",\n description: \"Agents source directory (builds one plugin per agent)\",\n }),\n \"output-dir\": Flags.string({\n char: \"o\",\n description: \"Output directory\",\n default: PLUGINS_DIST_PATH,\n }),\n skill: Flags.string({\n description: \"Compile only a specific skill (path to skill directory)\",\n }),\n verbose: Flags.boolean({\n char: \"v\",\n description: \"Enable verbose logging\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(BuildPlugins);\n setVerbose(flags.verbose);\n\n const projectRoot = process.cwd();\n const skillsDir = path.resolve(projectRoot, DIRS.skills);\n const outputDir = path.resolve(projectRoot, flags[\"output-dir\"]);\n\n this.printHeader(skillsDir, outputDir);\n\n try {\n const expectedSkillPlugins = await this.compileSkills(flags.skill, skillsDir, outputDir);\n\n if (flags[\"agents-dir\"]) {\n await this.compileAgents(projectRoot, flags[\"agents-dir\"], outputDir);\n }\n\n if (expectedSkillPlugins) {\n await this.pruneStaleSkillPlugins(outputDir, expectedSkillPlugins);\n }\n\n this.log(\"\");\n this.logSuccess(\"Plugin compilation complete!\");\n } catch (error) {\n this.log(\"Compilation failed\");\n this.handleError(error);\n }\n }\n\n private printHeader(skillsDir: string, outputDir: string): void {\n this.log(\"\");\n this.log(\"Compiling skill plugins\");\n this.log(` Skills directory: ${skillsDir}`);\n this.log(` Output directory: ${outputDir}`);\n this.log(\"\");\n }\n\n /**\n *
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/build/plugins.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport path from \"path\";\n\nimport { BaseCommand } from \"../../base-command\";\nimport { setVerbose } from \"../../utils/logger\";\nimport { listDirectories, remove } from \"../../utils/fs\";\nimport { DIRS, PLUGINS_DIST_PATH } from \"../../consts\";\nimport {\n compileAllSkillPlugins,\n compileSkillPlugin,\n printCompilationSummary,\n} from \"../../lib/skills\";\nimport { compileAllAgentPlugins, printAgentCompilationSummary } from \"../../lib/agents\";\nimport { readPluginManifest } from \"../../lib/plugins\";\nimport { plural } from \"../../utils/string\";\n\nexport default class BuildPlugins extends BaseCommand {\n static summary = \"Build skills and agents into standalone plugins\";\n\n static description =\n \"Build skills and agents into standalone plugins. By default, compiles all skills. Use --skill to compile a specific skill only. Use --agents-dir to also compile agents.\";\n\n static examples = [\n {\n description: \"Compile every skill into plugins\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Compile a single skill by name\",\n command: \"<%= config.bin %> <%= command.id %> --skill cli-commander\",\n },\n {\n description: \"Write plugins to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> --output-dir ./plugins\",\n },\n {\n description: \"Also compile agents from a directory\",\n command: \"<%= config.bin %> <%= command.id %> --agents-dir ./agents\",\n },\n {\n description: \"Compile with verbose logging\",\n command: \"<%= config.bin %> <%= command.id %> --verbose\",\n },\n ];\n\n static flags = {\n \"agents-dir\": Flags.string({\n char: \"a\",\n description: \"Agents source directory (builds one plugin per agent)\",\n }),\n \"output-dir\": Flags.string({\n char: \"o\",\n description: \"Output directory\",\n default: PLUGINS_DIST_PATH,\n }),\n skill: Flags.string({\n description: \"Compile only a specific skill (path to skill directory)\",\n }),\n verbose: Flags.boolean({\n char: \"v\",\n description: \"Enable verbose logging\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(BuildPlugins);\n setVerbose(flags.verbose);\n\n const projectRoot = process.cwd();\n const skillsDir = path.resolve(projectRoot, DIRS.skills);\n const outputDir = path.resolve(projectRoot, flags[\"output-dir\"]);\n\n this.printHeader(skillsDir, outputDir);\n\n try {\n const expectedSkillPlugins = await this.compileSkills(flags.skill, skillsDir, outputDir);\n\n if (flags[\"agents-dir\"]) {\n await this.compileAgents(projectRoot, flags[\"agents-dir\"], outputDir);\n }\n\n if (expectedSkillPlugins) {\n await this.pruneStaleSkillPlugins(outputDir, expectedSkillPlugins);\n }\n\n this.log(\"\");\n this.logSuccess(\"Plugin compilation complete!\");\n } catch (error) {\n this.log(\"Compilation failed\");\n this.handleError(error);\n }\n }\n\n private printHeader(skillsDir: string, outputDir: string): void {\n this.log(\"\");\n this.log(\"Compiling skill plugins\");\n this.log(` Skills directory: ${skillsDir}`);\n this.log(` Output directory: ${outputDir}`);\n this.log(\"\");\n }\n\n /**\n * Returns the plugin names that should remain, or `null` to skip pruning: in single-skill mode,\n * or after a failure, since a failed skill is indistinguishable from a removed one.\n */\n private async compileSkills(\n skillFlag: string | undefined,\n skillsDir: string,\n outputDir: string,\n ): Promise<Set<string> | null> {\n if (skillFlag) {\n await this.compileOneSkill(path.resolve(skillsDir, skillFlag), outputDir);\n return null;\n }\n\n return this.compileEverySkill(skillsDir, outputDir);\n }\n\n private async compileOneSkill(skillPath: string, outputDir: string): Promise<void> {\n this.log(`Compiling skill at ${skillPath}...`);\n\n const result = await compileSkillPlugin({\n skillPath,\n outputDir,\n });\n\n this.log(`Compiled ${result.skillName}`);\n this.log(` Plugin path: ${result.pluginPath}`);\n }\n\n private async compileEverySkill(\n skillsDir: string,\n outputDir: string,\n ): Promise<Set<string> | null> {\n this.log(\"Finding and compiling all skills...\");\n\n const { compiled, failed } = await compileAllSkillPlugins(skillsDir, outputDir);\n\n this.log(`Compiled ${plural(compiled.length, \"skill plugin\")}`);\n printCompilationSummary(compiled);\n\n if (failed.length > 0) {\n this.warn(\n `Skipping stale-plugin pruning: ${failed.length} skill(s) failed to compile ` +\n `(${failed.join(\", \")}). A failed skill is indistinguishable from a removed one.`,\n );\n return null;\n }\n\n return new Set(compiled.map((result) => result.skillName));\n }\n\n private async compileAgents(\n projectRoot: string,\n agentsDir: string,\n outputDir: string,\n ): Promise<void> {\n const resolvedAgentsDir = path.resolve(projectRoot, agentsDir);\n\n this.log(\"\");\n this.log(\"Compiling agent plugins\");\n this.log(` Agents directory: ${resolvedAgentsDir}`);\n this.log(\"\");\n\n this.log(\"Finding and compiling all agents...\");\n\n const agentResults = await compileAllAgentPlugins(resolvedAgentsDir, outputDir);\n\n this.log(`Compiled ${plural(agentResults.length, \"agent plugin\")}`);\n printAgentCompilationSummary(agentResults);\n }\n\n /** Prunes skill plugins only; agent plugins and non-plugin directories are left alone. */\n private async pruneStaleSkillPlugins(\n outputDir: string,\n expectedSkillPlugins: ReadonlySet<string>,\n ): Promise<void> {\n const dirNames = await listDirectories(outputDir);\n\n for (const dirName of dirNames) {\n if (expectedSkillPlugins.has(dirName)) continue;\n\n const pluginDir = path.join(outputDir, dirName);\n const manifest = await readPluginManifest(pluginDir);\n if (!manifest) continue;\n if (manifest.agents !== undefined) continue;\n\n await remove(pluginDir);\n this.log(` Pruned stale plugin: ${dirName}`);\n }\n }\n}\n"],"mappings":"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","names":[]}
|