agents-inc 0.171.0 → 0.173.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 +31 -0
- package/dist/{chunk-W4KAY26P.js → chunk-2RTBSLSR.js} +12 -3
- package/dist/{chunk-W4KAY26P.js.map → chunk-2RTBSLSR.js.map} +1 -1
- package/dist/{chunk-WM2N2D6Q.js → chunk-3N4FSTVX.js} +12 -6
- package/dist/{chunk-WM2N2D6Q.js.map → chunk-3N4FSTVX.js.map} +1 -1
- package/dist/{chunk-ZC6GC66J.js → chunk-3R3LHA4Q.js} +2 -2
- package/dist/{chunk-24OD7IP4.js → chunk-7OG635DK.js} +26 -4
- package/dist/chunk-7OG635DK.js.map +1 -0
- package/dist/{chunk-WDH6HHA3.js → chunk-A3ZAXL5T.js} +4 -5
- package/dist/{chunk-WDH6HHA3.js.map → chunk-A3ZAXL5T.js.map} +1 -1
- package/dist/{chunk-KMOCMVK5.js → chunk-AARQBW5L.js} +106 -60
- package/dist/chunk-AARQBW5L.js.map +1 -0
- package/dist/{chunk-WII6GOPM.js → chunk-BRZA7ZCX.js} +52 -31
- package/dist/chunk-BRZA7ZCX.js.map +1 -0
- package/dist/{chunk-AWWCRL5A.js → chunk-EHJIQDXR.js} +8 -6
- package/dist/{chunk-AWWCRL5A.js.map → chunk-EHJIQDXR.js.map} +1 -1
- package/dist/{chunk-RDXY4GRO.js → chunk-F437ICEG.js} +2 -2
- package/dist/chunk-G7NUK3BF.js +253 -0
- package/dist/chunk-G7NUK3BF.js.map +1 -0
- package/dist/{chunk-7IVLVEHX.js → chunk-ITQF35UQ.js} +3 -3
- package/dist/{chunk-QIR56IDM.js → chunk-LJQXQTFC.js} +29 -102
- package/dist/chunk-LJQXQTFC.js.map +1 -0
- package/dist/{chunk-A6OWEJGC.js → chunk-MHAQWMNJ.js} +35 -5
- package/dist/{chunk-A6OWEJGC.js.map → chunk-MHAQWMNJ.js.map} +1 -1
- package/dist/{chunk-YLUOGAW7.js → chunk-N33AKFLR.js} +2 -2
- package/dist/{chunk-TNFYBKVD.js → chunk-Q4UNHVPX.js} +25 -14
- package/dist/chunk-Q4UNHVPX.js.map +1 -0
- package/dist/chunk-Q6WRR4BN.js +195 -0
- package/dist/chunk-Q6WRR4BN.js.map +1 -0
- package/dist/{chunk-JGPE4RRE.js → chunk-SPQSNZMM.js} +2 -2
- package/dist/{chunk-EOKNEGRD.js → chunk-VR6QTK5Z.js} +8 -8
- package/dist/{chunk-S2SKVJT2.js → chunk-VSPC74SS.js} +48 -26
- package/dist/chunk-VSPC74SS.js.map +1 -0
- package/dist/{chunk-3YYHL76L.js → chunk-WVFBBZEP.js} +648 -394
- package/dist/chunk-WVFBBZEP.js.map +1 -0
- package/dist/commands/build/marketplace.js +16 -14
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +6 -6
- package/dist/commands/compile.js +12 -12
- package/dist/commands/doctor.js +87 -86
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +150 -152
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +25 -30
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +19 -16
- package/dist/commands/list.js +14 -17
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +4 -4
- package/dist/commands/search.js +15 -13
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +11 -11
- package/dist/commands/uninstall.js +145 -130
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +6 -6
- 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 +3 -4
- package/dist/components/common/summary-panel.js +11 -146
- package/dist/components/common/summary-panel.js.map +1 -1
- package/dist/hooks/init.js +39 -27
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-E67DSYTN.js +14 -0
- package/dist/{recompile-project-agents-IQANWGOP.js → recompile-project-agents-6G6M2RS6.js} +8 -8
- package/dist/{source-loader-YGG7DY2W.js → source-loader-W7XCNKNA.js} +4 -4
- package/dist/src/agents/tester/web-tester/playbook.md +1 -1
- package/package.json +1 -1
- package/src/agents/tester/web-tester/playbook.md +1 -1
- package/dist/chunk-24OD7IP4.js.map +0 -1
- package/dist/chunk-3YYHL76L.js.map +0 -1
- package/dist/chunk-4RQKCV6I.js +0 -103
- package/dist/chunk-4RQKCV6I.js.map +0 -1
- package/dist/chunk-5FM77WKW.js +0 -69
- package/dist/chunk-5FM77WKW.js.map +0 -1
- package/dist/chunk-KMOCMVK5.js.map +0 -1
- package/dist/chunk-QIR56IDM.js.map +0 -1
- package/dist/chunk-R572RLTI.js +0 -108
- package/dist/chunk-R572RLTI.js.map +0 -1
- package/dist/chunk-S2SKVJT2.js.map +0 -1
- package/dist/chunk-TNFYBKVD.js.map +0 -1
- package/dist/chunk-WII6GOPM.js.map +0 -1
- package/dist/components/common/removal-plan-confirm.js +0 -10
- package/dist/load-agent-defs-UBWITIEI.js +0 -14
- package/dist/source-loader-YGG7DY2W.js.map +0 -1
- /package/dist/{chunk-ZC6GC66J.js.map → chunk-3R3LHA4Q.js.map} +0 -0
- /package/dist/{chunk-RDXY4GRO.js.map → chunk-F437ICEG.js.map} +0 -0
- /package/dist/{chunk-7IVLVEHX.js.map → chunk-ITQF35UQ.js.map} +0 -0
- /package/dist/{chunk-YLUOGAW7.js.map → chunk-N33AKFLR.js.map} +0 -0
- /package/dist/{chunk-JGPE4RRE.js.map → chunk-SPQSNZMM.js.map} +0 -0
- /package/dist/{chunk-EOKNEGRD.js.map → chunk-VR6QTK5Z.js.map} +0 -0
- /package/dist/{components/common/removal-plan-confirm.js.map → load-agent-defs-E67DSYTN.js.map} +0 -0
- /package/dist/{recompile-project-agents-IQANWGOP.js.map → recompile-project-agents-6G6M2RS6.js.map} +0 -0
- /package/dist/{load-agent-defs-UBWITIEI.js.map → source-loader-W7XCNKNA.js.map} +0 -0
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BaseCommand,
|
|
4
4
|
EXIT_CODES
|
|
5
|
-
} from "../../chunk-
|
|
5
|
+
} from "../../chunk-LJQXQTFC.js";
|
|
6
6
|
import {
|
|
7
|
+
NO_VALID_DEFAULT_EXPORT,
|
|
8
|
+
configLoadFailure,
|
|
9
|
+
configUnreadableError,
|
|
7
10
|
generateMarketplace,
|
|
8
11
|
getErrorMessage,
|
|
9
12
|
getMarketplaceStats,
|
|
@@ -20,10 +23,10 @@ import {
|
|
|
20
23
|
warn,
|
|
21
24
|
writeFile,
|
|
22
25
|
writeMarketplace
|
|
23
|
-
} from "../../chunk-
|
|
26
|
+
} from "../../chunk-WVFBBZEP.js";
|
|
24
27
|
import {
|
|
25
28
|
plural
|
|
26
|
-
} from "../../chunk-
|
|
29
|
+
} from "../../chunk-7OG635DK.js";
|
|
27
30
|
import {
|
|
28
31
|
CATALOG_JSON,
|
|
29
32
|
CLI_INVOKE_COMMAND,
|
|
@@ -32,7 +35,7 @@ import {
|
|
|
32
35
|
PLUGINS_DIST_PATH,
|
|
33
36
|
PLUGIN_MANIFEST_DIR,
|
|
34
37
|
STANDARD_FILES
|
|
35
|
-
} from "../../chunk-
|
|
38
|
+
} from "../../chunk-MHAQWMNJ.js";
|
|
36
39
|
import "../../chunk-GHHJYNAN.js";
|
|
37
40
|
|
|
38
41
|
// src/cli/commands/build/marketplace.ts
|
|
@@ -224,10 +227,18 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
|
224
227
|
/** Unconditional: consumers must be able to read an absent catalogue as a broken marketplace. */
|
|
225
228
|
async readCatalog(projectRoot) {
|
|
226
229
|
this.log(`Reading the skills for ${CATALOG_JSON}...`);
|
|
227
|
-
await
|
|
230
|
+
await this.refuseAConfigDeclaringNothing(projectRoot);
|
|
228
231
|
const matrix = await loadMarketplaceMatrix(projectRoot);
|
|
229
232
|
return { ...matrix, generatedAt: GENERATED_AT_BUILD };
|
|
230
233
|
}
|
|
234
|
+
/** Every other reader takes such a file as absent; the build is where its author can fix it. */
|
|
235
|
+
async refuseAConfigDeclaringNothing(projectRoot) {
|
|
236
|
+
const read = await readSourceRepoConfig(projectRoot);
|
|
237
|
+
if (read.kind !== "declares-nothing") return;
|
|
238
|
+
this.error(configUnreadableError(configLoadFailure(read.configPath, NO_VALID_DEFAULT_EXPORT)), {
|
|
239
|
+
exit: EXIT_CODES.ERROR
|
|
240
|
+
});
|
|
241
|
+
}
|
|
231
242
|
async writeManifest(outputPath, marketplace) {
|
|
232
243
|
this.log(`Writing ${MARKETPLACE_JSON}...`);
|
|
233
244
|
await writeMarketplace(outputPath, marketplace);
|
|
@@ -268,15 +279,6 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
|
268
279
|
}
|
|
269
280
|
}
|
|
270
281
|
};
|
|
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
282
|
function noPluginsToPublish(pluginsDir, pluginsDirFlag) {
|
|
281
283
|
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
284
|
}
|
|
@@ -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 { 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":[]}
|
|
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 configUnreadableError,\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 { configLoadFailure, NO_VALID_DEFAULT_EXPORT } from \"../../lib/configuration/config-loader\";\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 this.refuseAConfigDeclaringNothing(projectRoot);\n const matrix = await loadMarketplaceMatrix(projectRoot);\n return { ...matrix, generatedAt: GENERATED_AT_BUILD };\n }\n\n /** Every other reader takes such a file as absent; the build is where its author can fix it. */\n private async refuseAConfigDeclaringNothing(projectRoot: string): Promise<void> {\n const read = await readSourceRepoConfig(projectRoot);\n if (read.kind !== \"declares-nothing\") return;\n\n this.error(configUnreadableError(configLoadFailure(read.configPath, NO_VALID_DEFAULT_EXPORT)), {\n exit: EXIT_CODES.ERROR,\n });\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 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,11 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
compileAllAgentPlugins,
|
|
4
4
|
printAgentCompilationSummary
|
|
5
|
-
} from "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
5
|
+
} from "../../chunk-BRZA7ZCX.js";
|
|
6
|
+
import "../../chunk-EHJIQDXR.js";
|
|
7
7
|
import {
|
|
8
8
|
BaseCommand
|
|
9
|
-
} from "../../chunk-
|
|
9
|
+
} from "../../chunk-LJQXQTFC.js";
|
|
10
10
|
import {
|
|
11
11
|
compileAllSkillPlugins,
|
|
12
12
|
compileSkillPlugin,
|
|
@@ -15,14 +15,14 @@ import {
|
|
|
15
15
|
readPluginManifest,
|
|
16
16
|
remove,
|
|
17
17
|
setVerbose
|
|
18
|
-
} from "../../chunk-
|
|
18
|
+
} from "../../chunk-WVFBBZEP.js";
|
|
19
19
|
import {
|
|
20
20
|
plural
|
|
21
|
-
} from "../../chunk-
|
|
21
|
+
} from "../../chunk-7OG635DK.js";
|
|
22
22
|
import {
|
|
23
23
|
DIRS,
|
|
24
24
|
PLUGINS_DIST_PATH
|
|
25
|
-
} from "../../chunk-
|
|
25
|
+
} from "../../chunk-MHAQWMNJ.js";
|
|
26
26
|
import "../../chunk-GHHJYNAN.js";
|
|
27
27
|
|
|
28
28
|
// src/cli/commands/build/plugins.ts
|
package/dist/commands/compile.js
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
unofferablePlacementsFound
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-F437ICEG.js";
|
|
5
5
|
import {
|
|
6
6
|
hostCompileNotices
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-3N4FSTVX.js";
|
|
8
8
|
import {
|
|
9
9
|
detectBothInstallations,
|
|
10
10
|
reconcileTypesFromDisk
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-VSPC74SS.js";
|
|
12
12
|
import {
|
|
13
13
|
compileAgents,
|
|
14
14
|
discoverInstalledSkills
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-VR6QTK5Z.js";
|
|
16
16
|
import {
|
|
17
17
|
loadAgentDefs
|
|
18
|
-
} from "../chunk-
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-
|
|
18
|
+
} from "../chunk-ITQF35UQ.js";
|
|
19
|
+
import "../chunk-BRZA7ZCX.js";
|
|
20
|
+
import "../chunk-EHJIQDXR.js";
|
|
21
21
|
import {
|
|
22
22
|
providerFlag,
|
|
23
23
|
providerNamedBy,
|
|
24
24
|
refuseAnAmbiguousInstallation
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-2RTBSLSR.js";
|
|
26
26
|
import {
|
|
27
27
|
BaseCommand,
|
|
28
28
|
EXIT_CODES
|
|
29
|
-
} from "../chunk-
|
|
29
|
+
} from "../chunk-LJQXQTFC.js";
|
|
30
30
|
import {
|
|
31
31
|
ConfigLoadError,
|
|
32
32
|
ERROR_MESSAGES,
|
|
@@ -49,15 +49,15 @@ import {
|
|
|
49
49
|
skillMetadataUnusableDetail,
|
|
50
50
|
skillMetadataUnusableError,
|
|
51
51
|
verbose
|
|
52
|
-
} from "../chunk-
|
|
52
|
+
} from "../chunk-WVFBBZEP.js";
|
|
53
53
|
import {
|
|
54
54
|
plural
|
|
55
|
-
} from "../chunk-
|
|
55
|
+
} from "../chunk-7OG635DK.js";
|
|
56
56
|
import {
|
|
57
57
|
STANDARD_FILES,
|
|
58
58
|
effectivelyExcludedSkillIds,
|
|
59
59
|
isActiveAt
|
|
60
|
-
} from "../chunk-
|
|
60
|
+
} from "../chunk-MHAQWMNJ.js";
|
|
61
61
|
import "../chunk-GHHJYNAN.js";
|
|
62
62
|
|
|
63
63
|
// src/cli/commands/compile.ts
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,28 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "../chunk-
|
|
2
|
+
import "../chunk-BRZA7ZCX.js";
|
|
3
3
|
import {
|
|
4
4
|
filterExcludedEntries,
|
|
5
5
|
listAgentFilesOf,
|
|
6
6
|
listAgentMdFiles,
|
|
7
7
|
splitAgentsByProvenance
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-EHJIQDXR.js";
|
|
9
9
|
import {
|
|
10
10
|
ambiguityFinding
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-2RTBSLSR.js";
|
|
12
12
|
import {
|
|
13
13
|
BaseCommand,
|
|
14
14
|
EXIT_CODES
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-LJQXQTFC.js";
|
|
16
16
|
import {
|
|
17
17
|
ConfigDefaultExportError,
|
|
18
18
|
ConfigLoadError,
|
|
19
|
+
INFO_MESSAGES,
|
|
19
20
|
MarketplaceManifestRequiredError,
|
|
20
21
|
MarketplaceNameRefusedError,
|
|
21
22
|
MarketplaceRefusedError,
|
|
23
|
+
MarketplaceUnreachableError,
|
|
22
24
|
SOURCE_ENV_VAR,
|
|
23
25
|
agentCodec,
|
|
24
26
|
agentYamlGenerationSchema,
|
|
25
27
|
agentsDir,
|
|
28
|
+
askingEachMarketplaceItself,
|
|
26
29
|
configDirsInPlay,
|
|
27
30
|
declaresNoContent,
|
|
28
31
|
detectInstallations,
|
|
@@ -80,7 +83,6 @@ import {
|
|
|
80
83
|
splitMetadataValidationIssues,
|
|
81
84
|
stackConfigValidationSchema,
|
|
82
85
|
stacksConfigSchema,
|
|
83
|
-
typedValues,
|
|
84
86
|
validResult,
|
|
85
87
|
validateAgentFrontmatter,
|
|
86
88
|
validateAllPlugins,
|
|
@@ -89,11 +91,12 @@ import {
|
|
|
89
91
|
validateSkillFrontmatter,
|
|
90
92
|
validateSkillMetadata,
|
|
91
93
|
verbose
|
|
92
|
-
} from "../chunk-
|
|
94
|
+
} from "../chunk-WVFBBZEP.js";
|
|
93
95
|
import {
|
|
94
96
|
matrix,
|
|
95
|
-
plural
|
|
96
|
-
|
|
97
|
+
plural,
|
|
98
|
+
typedValues
|
|
99
|
+
} from "../chunk-7OG635DK.js";
|
|
97
100
|
import {
|
|
98
101
|
CLI_INVOKE_COMMAND,
|
|
99
102
|
DEFAULT_BRANDING,
|
|
@@ -108,7 +111,7 @@ import {
|
|
|
108
111
|
STANDARD_FILES,
|
|
109
112
|
UI_SYMBOLS,
|
|
110
113
|
effectivelyExcludedSkillIds
|
|
111
|
-
} from "../chunk-
|
|
114
|
+
} from "../chunk-MHAQWMNJ.js";
|
|
112
115
|
import "../chunk-GHHJYNAN.js";
|
|
113
116
|
|
|
114
117
|
// src/cli/commands/doctor.ts
|
|
@@ -117,8 +120,20 @@ import path4 from "path";
|
|
|
117
120
|
|
|
118
121
|
// src/cli/lib/doctor/installation-reads.ts
|
|
119
122
|
import os from "os";
|
|
120
|
-
function hostsOnDisk(projectDir) {
|
|
121
|
-
|
|
123
|
+
async function hostsOnDisk(projectDir) {
|
|
124
|
+
const found = await detectInstallations(projectDir);
|
|
125
|
+
if (inheritsTheGlobalInstallation(found)) return hostsOf(providerInUse(os.homedir()));
|
|
126
|
+
const project = providerInUse(projectDir);
|
|
127
|
+
return { project, global: globalBeside(project, found) };
|
|
128
|
+
}
|
|
129
|
+
function inheritsTheGlobalInstallation(found) {
|
|
130
|
+
return found.length > 0 && found.every((installation) => installation.scope === "global");
|
|
131
|
+
}
|
|
132
|
+
function globalBeside(project, found) {
|
|
133
|
+
const inherited = found.some(
|
|
134
|
+
(installation) => installation.scope === "global" && installation.provider === project
|
|
135
|
+
);
|
|
136
|
+
return inherited ? project : providerInUse(os.homedir());
|
|
122
137
|
}
|
|
123
138
|
function hostsOf(provider) {
|
|
124
139
|
return { project: provider, global: provider };
|
|
@@ -202,7 +217,7 @@ async function configuredSkillsAt(root, provider) {
|
|
|
202
217
|
|
|
203
218
|
// src/cli/lib/doctor/ownership.ts
|
|
204
219
|
import path3 from "path";
|
|
205
|
-
import { groupBy } from "remeda";
|
|
220
|
+
import { groupBy, unique } from "remeda";
|
|
206
221
|
|
|
207
222
|
// src/cli/lib/content-validator.ts
|
|
208
223
|
import os2 from "os";
|
|
@@ -780,12 +795,12 @@ async function validateInstalledSkillMetadata(metadataPath) {
|
|
|
780
795
|
// src/cli/lib/doctor/ownership.ts
|
|
781
796
|
async function judgeOwnership(state, config, installation) {
|
|
782
797
|
const agentFolders = agentFoldersToJudge(state, config, installation);
|
|
783
|
-
const
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
798
|
+
const [skills, agents, orphanedAgentFiles] = await Promise.all([
|
|
799
|
+
unownedSkillDirs(state, installation),
|
|
800
|
+
unownedAgentFiles(agentFolders),
|
|
801
|
+
Promise.all(agentFolders.map(unclaimedAgentFiles))
|
|
787
802
|
]);
|
|
788
|
-
return { unowned,
|
|
803
|
+
return { unowned: { skills, agents }, orphanedAgentFiles: orphanedAgentFiles.flat() };
|
|
789
804
|
}
|
|
790
805
|
function agentFoldersToJudge(state, config, { projectDir, hosts }) {
|
|
791
806
|
return oncePerFolder(
|
|
@@ -796,13 +811,13 @@ function agentFoldersToJudge(state, config, { projectDir, hosts }) {
|
|
|
796
811
|
}))
|
|
797
812
|
);
|
|
798
813
|
}
|
|
799
|
-
function
|
|
800
|
-
return
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
claimed: claimed(state, scope, config && skillIdsClaimedIn(config, scope))
|
|
804
|
-
}))
|
|
814
|
+
async function unownedSkillDirs(state, { projectDir, hosts }) {
|
|
815
|
+
if (state.kind !== "absent") return [];
|
|
816
|
+
const dirs = unique(
|
|
817
|
+
scopesToJudge(state, hosts).map((scope) => skillsDir(hosts[scope], scope, projectDir))
|
|
805
818
|
);
|
|
819
|
+
const listed = await Promise.all(dirs.map(skillDirsWithOurProvenanceIn));
|
|
820
|
+
return listed.flat();
|
|
806
821
|
}
|
|
807
822
|
function scopesToJudge(state, hosts) {
|
|
808
823
|
const ownConfig = state.kind !== "absent" && !inherits(state);
|
|
@@ -819,9 +834,6 @@ function claimed(state, scope, names) {
|
|
|
819
834
|
function agentNamesClaimedIn(config, scope) {
|
|
820
835
|
return config.agents.filter((agent) => claimsAt(agent, scope)).map((agent) => agent.name);
|
|
821
836
|
}
|
|
822
|
-
function skillIdsClaimedIn(config, scope) {
|
|
823
|
-
return config.skills.filter((skill) => claimsAt(skill, scope)).map((skill) => skill.id);
|
|
824
|
-
}
|
|
825
837
|
function claimsAt(entry, scope) {
|
|
826
838
|
return entry.scope === scope && (scope === "global" || !entry.excluded);
|
|
827
839
|
}
|
|
@@ -835,31 +847,11 @@ function joinClaims(into, from) {
|
|
|
835
847
|
if (from.claimed === null) return into;
|
|
836
848
|
return { ...into, claimed: /* @__PURE__ */ new Set([...into.claimed, ...from.claimed]) };
|
|
837
849
|
}
|
|
838
|
-
async function
|
|
839
|
-
const
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
Promise.all(
|
|
844
|
-
agentFolders.filter(isUnclaimed).map(({ dir, codec }) => agentFilesWithOurProvenanceIn(dir, codec))
|
|
845
|
-
)
|
|
846
|
-
]);
|
|
847
|
-
return { skills: skills.flat(), agents: agents.flat() };
|
|
848
|
-
}
|
|
849
|
-
async function orphansIn(agentFolders, skillFolders) {
|
|
850
|
-
const [skills, agents] = await Promise.all([
|
|
851
|
-
Promise.all(skillFolders.map(unclaimedSkillDirs)),
|
|
852
|
-
Promise.all(agentFolders.map(unclaimedAgentFiles))
|
|
853
|
-
]);
|
|
854
|
-
return { skills: skills.flat(), agents: agents.flat() };
|
|
855
|
-
}
|
|
856
|
-
function isUnclaimed(folder) {
|
|
857
|
-
return folder.claimed === null;
|
|
858
|
-
}
|
|
859
|
-
async function unclaimedSkillDirs({ dir, claimed: claimed2 }) {
|
|
860
|
-
if (claimed2 === null) return [];
|
|
861
|
-
const ours = await listSkillDirsWithOurProvenance(dir);
|
|
862
|
-
return ours.filter((name) => !claimed2.has(name));
|
|
850
|
+
async function unownedAgentFiles(agentFolders) {
|
|
851
|
+
const listed = await Promise.all(
|
|
852
|
+
agentFolders.filter((folder) => folder.claimed === null).map(({ dir, codec }) => agentFilesWithOurProvenanceIn(dir, codec))
|
|
853
|
+
);
|
|
854
|
+
return listed.flat();
|
|
863
855
|
}
|
|
864
856
|
async function unclaimedAgentFiles({ dir, codec, claimed: claimed2 }) {
|
|
865
857
|
if (claimed2 === null || !await directoryExists(dir)) return [];
|
|
@@ -868,7 +860,7 @@ async function unclaimedAgentFiles({ dir, codec, claimed: claimed2 }) {
|
|
|
868
860
|
}
|
|
869
861
|
|
|
870
862
|
// src/cli/commands/doctor.ts
|
|
871
|
-
import { countBy, unique } from "remeda";
|
|
863
|
+
import { countBy, unique as unique2 } from "remeda";
|
|
872
864
|
function checkConfigValid(state, installation) {
|
|
873
865
|
const theConfig = (verdict) => configRowMessage(state, installation, verdict);
|
|
874
866
|
if (state.kind === "absent") {
|
|
@@ -985,7 +977,7 @@ function checkSkillsResolved(config, matrix2) {
|
|
|
985
977
|
function skillIdsToResolve(config) {
|
|
986
978
|
const excludedIds = effectivelyExcludedSkillIds(config.skills);
|
|
987
979
|
const stackIds = config.stack ? getStackSkillIds(config.stack) : [];
|
|
988
|
-
return
|
|
980
|
+
return unique2([...stackIds, ...config.skills.map((s) => s.id)]).filter(
|
|
989
981
|
(id) => !excludedIds.has(id)
|
|
990
982
|
);
|
|
991
983
|
}
|
|
@@ -1003,7 +995,7 @@ async function checkAgentsCompiled(config, installation) {
|
|
|
1003
995
|
const unrenderable = agentChecks.filter((c) => c.state === "unrenderable");
|
|
1004
996
|
const missingAgents = agentChecks.filter((c) => c.state === "missing").map((c) => c.name);
|
|
1005
997
|
if (unrenderable.length === config.agents.length) {
|
|
1006
|
-
const hostsLeavingThemOut =
|
|
998
|
+
const hostsLeavingThemOut = unique2(unrenderable.map((a) => a.provider)).join(" or ");
|
|
1007
999
|
return {
|
|
1008
1000
|
kind: "agents",
|
|
1009
1001
|
status: "pass",
|
|
@@ -1041,33 +1033,30 @@ async function agentCompileCheck(agent, { projectDir, hosts }) {
|
|
|
1041
1033
|
async function checkNoOrphans(state, config, installation) {
|
|
1042
1034
|
return ownershipResult(state, await judgeOwnership(state, config, installation));
|
|
1043
1035
|
}
|
|
1044
|
-
function ownershipResult(state, { unowned,
|
|
1036
|
+
function ownershipResult(state, { unowned, orphanedAgentFiles }) {
|
|
1045
1037
|
if (unowned.skills.length > 0 || unowned.agents.length > 0) {
|
|
1046
1038
|
return {
|
|
1047
1039
|
kind: "orphans-unowned",
|
|
1048
1040
|
status: "fail",
|
|
1049
1041
|
message: `${countedArtifacts(unowned.skills, unowned.agents)} installed here, and no configuration declares them`,
|
|
1050
|
-
details: [...unowned.skills, ...unowned.agents, ...orphanLines(
|
|
1042
|
+
details: [...unowned.skills, ...unowned.agents, ...orphanLines(orphanedAgentFiles)].map(
|
|
1051
1043
|
(line) => `- ${line}`
|
|
1052
1044
|
)
|
|
1053
1045
|
};
|
|
1054
1046
|
}
|
|
1055
|
-
if (
|
|
1047
|
+
if (orphanedAgentFiles.length > 0) {
|
|
1056
1048
|
return {
|
|
1057
1049
|
kind: "orphans",
|
|
1058
1050
|
status: "warn",
|
|
1059
|
-
message:
|
|
1060
|
-
details: orphanLines(
|
|
1051
|
+
message: plural(orphanedAgentFiles.length, "orphaned agent file"),
|
|
1052
|
+
details: orphanLines(orphanedAgentFiles).map((line) => `- ${line}`)
|
|
1061
1053
|
};
|
|
1062
1054
|
}
|
|
1063
1055
|
if (state.kind === "absent") return skippedResult("orphans");
|
|
1064
|
-
return { kind: "orphans", status: "pass", message: "No orphaned
|
|
1065
|
-
}
|
|
1066
|
-
function orphanLines({ skills, agents }) {
|
|
1067
|
-
return [...skills, ...agents].map((name) => `${name} (not in config)`);
|
|
1056
|
+
return { kind: "orphans", status: "pass", message: "No orphaned agent files" };
|
|
1068
1057
|
}
|
|
1069
|
-
function
|
|
1070
|
-
return
|
|
1058
|
+
function orphanLines(fileNames) {
|
|
1059
|
+
return fileNames.map((name) => `${name} (not in config)`);
|
|
1071
1060
|
}
|
|
1072
1061
|
function ratio(found, total, noun) {
|
|
1073
1062
|
return `${found}/${plural(total, noun)}`;
|
|
@@ -1124,7 +1113,7 @@ async function checkPluginSkillsInstalled(config, installation) {
|
|
|
1124
1113
|
message: "No plugin-mode skills configured"
|
|
1125
1114
|
};
|
|
1126
1115
|
}
|
|
1127
|
-
const scopes =
|
|
1116
|
+
const scopes = unique2(pluginSkills.map((s) => s.scope));
|
|
1128
1117
|
const missingPerScope = await Promise.all(
|
|
1129
1118
|
scopes.map((scope) => pluginSkillsMissingAt(scope, pluginSkills, installation))
|
|
1130
1119
|
);
|
|
@@ -1158,43 +1147,55 @@ var MARKETPLACE_CHOSEN_BY = {
|
|
|
1158
1147
|
default: "nothing here names one, so this is the default"
|
|
1159
1148
|
};
|
|
1160
1149
|
function howItWasReached(source, isLocal) {
|
|
1161
|
-
return isLocal ? `Read ${source} from disk` : `
|
|
1150
|
+
return isLocal ? `Read ${source} from disk` : `Reached ${source} over the network`;
|
|
1162
1151
|
}
|
|
1163
|
-
function reachedMarketplace(result) {
|
|
1152
|
+
function reachedMarketplace(result, differingCopiesReplaced) {
|
|
1164
1153
|
const { source, sourceOrigin } = result.sourceConfig;
|
|
1165
|
-
const available = `${plural(result.marketplaceSkillIds.size, "skill")} available`;
|
|
1166
|
-
const chosenBy = MARKETPLACE_CHOSEN_BY[sourceOrigin];
|
|
1167
|
-
if (result.unreachable) {
|
|
1168
|
-
return {
|
|
1169
|
-
kind: "source",
|
|
1170
|
-
status: "warn",
|
|
1171
|
-
message: `Could not reach ${source} \u2014 read its cached copy instead`,
|
|
1172
|
-
details: [available, `The copy at ${result.sourcePath} may be out of date \u2014 ${chosenBy}`]
|
|
1173
|
-
};
|
|
1174
|
-
}
|
|
1175
1154
|
return {
|
|
1176
1155
|
kind: "source",
|
|
1177
1156
|
status: "pass",
|
|
1178
1157
|
message: `Connected to ${result.isLocal ? "local" : "remote"}: ${result.sourcePath}`,
|
|
1179
|
-
details: [
|
|
1158
|
+
details: [
|
|
1159
|
+
`${plural(result.marketplaceSkillIds.size, "skill")} available`,
|
|
1160
|
+
`${howItWasReached(source, result.isLocal)} \u2014 ${MARKETPLACE_CHOSEN_BY[sourceOrigin]}`,
|
|
1161
|
+
...savedCopyLines(source, differingCopiesReplaced)
|
|
1162
|
+
]
|
|
1180
1163
|
};
|
|
1181
1164
|
}
|
|
1165
|
+
function savedCopyLines(source, differingCopiesReplaced) {
|
|
1166
|
+
return differingCopiesReplaced.has(source) ? [INFO_MESSAGES.SAVED_COPY_REPLACED] : [];
|
|
1167
|
+
}
|
|
1182
1168
|
async function checkSourceReachable({
|
|
1183
1169
|
projectDir,
|
|
1184
1170
|
hosts
|
|
1185
1171
|
}) {
|
|
1186
1172
|
try {
|
|
1187
|
-
return
|
|
1188
|
-
|
|
1173
|
+
return await askingEachMarketplaceItself(
|
|
1174
|
+
async (differingCopiesReplaced) => reachedMarketplace(
|
|
1175
|
+
await loadSkillsMatrixFromSource({ projectDir, provider: hosts.project }),
|
|
1176
|
+
differingCopiesReplaced
|
|
1177
|
+
)
|
|
1189
1178
|
);
|
|
1190
1179
|
} catch (error) {
|
|
1180
|
+
return marketplaceNotLoaded(error);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
var NO_SAVED_COPY_READ = "Doctor asks the marketplace itself, not the saved copy, which other commands still read offline";
|
|
1184
|
+
function marketplaceNotLoaded(error) {
|
|
1185
|
+
if (error instanceof MarketplaceUnreachableError) {
|
|
1191
1186
|
return {
|
|
1192
1187
|
kind: "source",
|
|
1193
1188
|
status: "fail",
|
|
1194
|
-
message:
|
|
1195
|
-
details: [
|
|
1189
|
+
message: `Could not reach ${error.source}`,
|
|
1190
|
+
details: [error.reason, NO_SAVED_COPY_READ]
|
|
1196
1191
|
};
|
|
1197
1192
|
}
|
|
1193
|
+
return {
|
|
1194
|
+
kind: "source",
|
|
1195
|
+
status: "fail",
|
|
1196
|
+
message: refusedOr(error, "Failed to load marketplace"),
|
|
1197
|
+
details: [getErrorMessage(error)]
|
|
1198
|
+
};
|
|
1198
1199
|
}
|
|
1199
1200
|
var CONFIG_CHECK = {
|
|
1200
1201
|
kind: "content-config",
|
|
@@ -1354,7 +1355,7 @@ function commandActingOn(provider, command) {
|
|
|
1354
1355
|
return `${CLI_INVOKE_COMMAND} ${command}${providerArgument(provider)}`;
|
|
1355
1356
|
}
|
|
1356
1357
|
function formatTips(results) {
|
|
1357
|
-
return
|
|
1358
|
+
return unique2(TIPS.flatMap((tip) => linesOf(tip, results)));
|
|
1358
1359
|
}
|
|
1359
1360
|
function linesOf(tip, results) {
|
|
1360
1361
|
return results.filter((result) => answers(tip, result)).map((result) => tip.line(result.provider));
|
|
@@ -1374,7 +1375,7 @@ async function checkInstallationsInPlay(projectDir, providers) {
|
|
|
1374
1375
|
const finding = await ambiguityFinding(projectDir);
|
|
1375
1376
|
return {
|
|
1376
1377
|
kind: "installations",
|
|
1377
|
-
status: "
|
|
1378
|
+
status: "pass",
|
|
1378
1379
|
message: `${providers.length} installations here, each checked below`,
|
|
1379
1380
|
details: finding === null ? [] : [`- ${finding}`]
|
|
1380
1381
|
};
|
|
@@ -1512,7 +1513,7 @@ var Doctor = class _Doctor extends BaseCommand {
|
|
|
1512
1513
|
return this.checkTheInstallation(projectDir, failedContent);
|
|
1513
1514
|
}
|
|
1514
1515
|
async checkTheInstallation(projectDir, failedContent) {
|
|
1515
|
-
const installation = { projectDir, hosts: hostsOnDisk(projectDir) };
|
|
1516
|
+
const installation = { projectDir, hosts: await hostsOnDisk(projectDir) };
|
|
1516
1517
|
const configState = await resolveConfigState(installation);
|
|
1517
1518
|
if (configState.kind === "absent") {
|
|
1518
1519
|
const sourceRepo = await safeCheck("source-repo", () => uninstalledSourceRepo(projectDir));
|