@falkenslab/agent-kit 0.23.0 → 0.24.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/dist/chat/extensions.js +1 -1
- package/dist/core/extensionCatalog.d.ts +2 -0
- package/dist/core/extensionCatalog.js +6 -4
- package/dist/core/extensions.d.ts +7 -0
- package/dist/core/extensions.js +13 -0
- package/dist/core/externalExtensions.d.ts +3 -0
- package/dist/core/externalExtensions.js +2 -1
- package/dist/tui/extensionCommand.js +6 -3
- package/package.json +1 -1
- package/schemas/agent-kit-metadata.schema.json +6 -0
- package/schemas/marketplace-catalog.schema.json +15 -1
package/dist/chat/extensions.js
CHANGED
|
@@ -38,7 +38,7 @@ export function describeCapabilities(status) {
|
|
|
38
38
|
/** One line for a catalog entry: what installs it, its version, whether it's installed or has an update, what it is. */
|
|
39
39
|
export function describeEntry(entry) {
|
|
40
40
|
const state = entry.installed ? (entry.update ? ` ${t().extensionUpdateAvailable(entry.installed.manifest?.version ?? "?")}` : ` ${t().extensionIsInstalled}`) : "";
|
|
41
|
-
return `${entry.spec}${entry.version ? ` ${entry.version}` : ""}${state}${entry.
|
|
41
|
+
return `${entry.spec}${entry.version ? ` ${entry.version}` : ""}${state}${entry.description ? ` ${entry.description}` : ""}`;
|
|
42
42
|
}
|
|
43
43
|
/** An installed extension's options, one line each: its value, its default, or whether a sensitive one is set (never its value). */
|
|
44
44
|
export async function describeOptions(extension) {
|
|
@@ -22,6 +22,8 @@ export interface CatalogEntry {
|
|
|
22
22
|
/** From the agent's own marketplace: installed without a confirmation. */
|
|
23
23
|
official: boolean;
|
|
24
24
|
plugin: MarketplacePlugin;
|
|
25
|
+
/** What it is, in the kit's language (#67): its own there, else the marketplace entry's, else its `plugin.json`'s, in English. */
|
|
26
|
+
description: string;
|
|
25
27
|
/** The version it offers: its `plugin.json`'s when the marketplace has its folder, else the marketplace's entry's. */
|
|
26
28
|
version?: string;
|
|
27
29
|
/** Installed (and used: not shadowed), from wherever it came. */
|
|
@@ -4,7 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { addExtension, codeStoreDir, hashExtension, inKitRange, installTarget, isGitSource, listInstalled, readExternalManifest, readLock, storedCodeDir } from "./externalExtensions.js";
|
|
5
5
|
import { cachePackage, cachedPackageDir } from "./npxPackages.js";
|
|
6
6
|
import { trustWorkspace } from "./workspaceTrust.js";
|
|
7
|
-
import { describeCapability } from "./extensions.js";
|
|
7
|
+
import { describeCapability, describeInLanguage } from "./extensions.js";
|
|
8
8
|
import { getLanguage } from "./messages/index.js";
|
|
9
9
|
import { addMarketplace, findPlugin, installFromMarketplace, listMarketplaces, resolvePluginSource, updateMarketplace } from "./marketplaces.js";
|
|
10
10
|
/**
|
|
@@ -68,13 +68,14 @@ async function offered(marketplace, plugin) {
|
|
|
68
68
|
const version = manifest?.version ?? plugin.version;
|
|
69
69
|
const capabilities = (manifest?.capabilities ?? []).map((capability) => describeCapability(capability, getLanguage()));
|
|
70
70
|
const requirements = (manifest?.requirements ?? []).map((requirement) => ({ name: requirement.name, for: requirement.for }));
|
|
71
|
-
|
|
71
|
+
const description = describeInLanguage(plugin.description ?? manifest?.description ?? "", manifest?.descriptions, getLanguage());
|
|
72
|
+
return { ...(version ? { version } : {}), keywords: manifest?.keywords ?? [], ...(logo ? { logo } : {}), ...(banner ? { banner } : {}), capabilities, requirements, description };
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
catch {
|
|
75
76
|
// A source the kit doesn't install: the entry's own fields.
|
|
76
77
|
}
|
|
77
|
-
return { ...(plugin.version ? { version: plugin.version } : {}), keywords: [], capabilities: [], requirements: [] };
|
|
78
|
+
return { ...(plugin.version ? { version: plugin.version } : {}), keywords: [], capabilities: [], requirements: [], description: plugin.description ?? "" };
|
|
78
79
|
}
|
|
79
80
|
/** Whether `offered` is newer than `installed` (x.y.z); a version that can't be compared isn't. */
|
|
80
81
|
export function isNewer(offered, installed) {
|
|
@@ -96,7 +97,7 @@ export async function extensionCatalog(dirs, options = {}) {
|
|
|
96
97
|
if (wanted && !topics.some((topic) => wanted.has(topic)))
|
|
97
98
|
continue;
|
|
98
99
|
// Its capabilities count too: a search for "grading" finds what grades.
|
|
99
|
-
const text = [plugin.name, plugin.description, ...topics, ...look.capabilities.flatMap(({ id, label, description }) => [id, label, description])].join(" ").toLowerCase();
|
|
100
|
+
const text = [plugin.name, plugin.description, look.description, ...topics, ...look.capabilities.flatMap(({ id, label, description }) => [id, label, description])].join(" ").toLowerCase();
|
|
100
101
|
if (!words.every((word) => text.includes(word)))
|
|
101
102
|
continue;
|
|
102
103
|
const version = look.version;
|
|
@@ -104,6 +105,7 @@ export async function extensionCatalog(dirs, options = {}) {
|
|
|
104
105
|
const fromHere = mine?.lock.marketplace === `${plugin.name}@${marketplace.name}`;
|
|
105
106
|
entries.push({
|
|
106
107
|
spec: `${plugin.name}@${marketplace.name}`,
|
|
108
|
+
description: look.description,
|
|
107
109
|
marketplace: marketplace.name,
|
|
108
110
|
official: marketplace.official,
|
|
109
111
|
plugin,
|
|
@@ -135,6 +135,13 @@ export declare function describeCapability(capability: ExtensionCapability, lang
|
|
|
135
135
|
* one is missing.
|
|
136
136
|
*/
|
|
137
137
|
export declare function capabilitiesProblem(pluginRoot: string, capabilities: readonly ExtensionCapability[]): Promise<string | undefined>;
|
|
138
|
+
/**
|
|
139
|
+
* A manifest's `metadata["agent-kit"].description` (#67): its description in other languages than
|
|
140
|
+
* English, which stays the top-level `description` Claude Code reads. Only languages the kit speaks.
|
|
141
|
+
*/
|
|
142
|
+
export declare function parseDescriptions(raw: unknown): Partial<Record<Language, string>>;
|
|
143
|
+
/** An extension's description in `language`: its own there, else the English one. */
|
|
144
|
+
export declare function describeInLanguage(english: string, descriptions: Partial<Record<Language, string>> | undefined, language: Language): string;
|
|
138
145
|
/** An extension's manifest, as the kit reads it. */
|
|
139
146
|
export interface ExtensionManifest {
|
|
140
147
|
name: string;
|
package/dist/core/extensions.js
CHANGED
|
@@ -49,6 +49,19 @@ export async function capabilitiesProblem(pluginRoot, capabilities) {
|
|
|
49
49
|
}
|
|
50
50
|
return undefined;
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* A manifest's `metadata["agent-kit"].description` (#67): its description in other languages than
|
|
54
|
+
* English, which stays the top-level `description` Claude Code reads. Only languages the kit speaks.
|
|
55
|
+
*/
|
|
56
|
+
export function parseDescriptions(raw) {
|
|
57
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
58
|
+
return {};
|
|
59
|
+
return Object.fromEntries(Object.entries(raw).filter(([language, text]) => SUPPORTED_LANGUAGES.includes(language) && typeof text === "string" && text.length > 0));
|
|
60
|
+
}
|
|
61
|
+
/** An extension's description in `language`: its own there, else the English one. */
|
|
62
|
+
export function describeInLanguage(english, descriptions, language) {
|
|
63
|
+
return descriptions?.[language] ?? english;
|
|
64
|
+
}
|
|
52
65
|
/** Reads an extension's manifest from its plugin. */
|
|
53
66
|
export function readExtensionManifest(pluginRoot) {
|
|
54
67
|
const file = path.join(pluginRoot, ".claude-plugin", "plugin.json");
|
|
@@ -49,7 +49,10 @@ export interface ExtensionAuthor {
|
|
|
49
49
|
*/
|
|
50
50
|
export interface ExternalManifest {
|
|
51
51
|
name: string;
|
|
52
|
+
/** Its description in English: `plugin.json`'s, which Claude Code reads. */
|
|
52
53
|
description: string;
|
|
54
|
+
/** Its description in other languages (#67), from `metadata["agent-kit"].description`. */
|
|
55
|
+
descriptions: Partial<Record<Language, string>>;
|
|
53
56
|
version?: string;
|
|
54
57
|
author?: ExtensionAuthor;
|
|
55
58
|
homepage?: string;
|
|
@@ -5,7 +5,7 @@ import os from "node:os";
|
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { promisify } from "node:util";
|
|
8
|
-
import { capabilitiesProblem, parseCapabilities, providedBy } from "./extensions.js";
|
|
8
|
+
import { capabilitiesProblem, parseCapabilities, parseDescriptions, providedBy } from "./extensions.js";
|
|
9
9
|
import { getLanguage } from "./messages/index.js";
|
|
10
10
|
import { truncate } from "./toolLabels.js";
|
|
11
11
|
import { agentKitVersion } from "./version.js";
|
|
@@ -97,6 +97,7 @@ export async function readExternalManifest(dir) {
|
|
|
97
97
|
return {
|
|
98
98
|
name,
|
|
99
99
|
description: typeof raw.description === "string" ? raw.description : "",
|
|
100
|
+
descriptions: parseDescriptions(kit.description),
|
|
100
101
|
...text("version"),
|
|
101
102
|
...(author && typeof author === "object" && typeof author.name === "string"
|
|
102
103
|
? { author: { name: author.name, ...(author.email ? { email: author.email } : {}), ...(author.url ? { url: author.url } : {}) } }
|
|
@@ -6,7 +6,7 @@ import { addExtension, extensionOptionStates, installTarget, folderSize, isGitSo
|
|
|
6
6
|
import { describe, describeOptions } from "../chat/extensions.js";
|
|
7
7
|
import { extensionCatalog, knownMarketplaces as catalogMarketplaces, restoreExtensions, updateExtension } from "../core/extensionCatalog.js";
|
|
8
8
|
import { trustWorkspace } from "../core/workspaceTrust.js";
|
|
9
|
-
import { describeCapability } from "../core/extensions.js";
|
|
9
|
+
import { describeCapability, describeInLanguage } from "../core/extensions.js";
|
|
10
10
|
import { getLanguage } from "../core/messages/index.js";
|
|
11
11
|
export { chatExtensionsCommand, describe } from "../chat/extensions.js";
|
|
12
12
|
/**
|
|
@@ -402,10 +402,13 @@ async function info(extension) {
|
|
|
402
402
|
if (!manifest)
|
|
403
403
|
return [describe(extension), "Its manifest can't be read."];
|
|
404
404
|
const author = manifest.author ? [manifest.author.name, manifest.author.email && `<${manifest.author.email}>`, manifest.author.url && `(${manifest.author.url})`].filter(Boolean).join(" ") : undefined;
|
|
405
|
-
|
|
405
|
+
// Its README in the kit's language when it has one (README.es.md), else the English (#67).
|
|
406
|
+
const language = getLanguage();
|
|
407
|
+
const translated = path.join(extension.dir, `README.${language}.md`);
|
|
408
|
+
const readme = language !== "en" && (await stat(translated).catch(() => null))?.isFile() ? translated : path.join(extension.dir, "README.md");
|
|
406
409
|
const field = (label, value) => (value ? [`${label.padEnd(13)}${value}`] : []);
|
|
407
410
|
return [
|
|
408
|
-
`${manifest.name}${manifest.version ? ` ${manifest.version}` : ""}: ${manifest.description}`,
|
|
411
|
+
`${manifest.name}${manifest.version ? ` ${manifest.version}` : ""}: ${describeInLanguage(manifest.description, manifest.descriptions, language)}`,
|
|
409
412
|
...field("Author", author),
|
|
410
413
|
...field("License", manifest.license),
|
|
411
414
|
...field("Homepage", manifest.homepage),
|
package/package.json
CHANGED
|
@@ -11,6 +11,12 @@
|
|
|
11
11
|
"type": "string",
|
|
12
12
|
"pattern": "^\\s*(?:(?:>=|<=|>|<|=)?\\s*v?\\d+(?:\\.\\d+){0,2})(?:\\s+(?:>=|<=|>|<|=)?\\s*v?\\d+(?:\\.\\d+){0,2})*\\s*$"
|
|
13
13
|
},
|
|
14
|
+
"description": {
|
|
15
|
+
"description": "Its description in other languages than English, which stays plugin.json's own description (Claude Code reads that one).",
|
|
16
|
+
"type": "object",
|
|
17
|
+
"propertyNames": { "enum": ["es", "fr", "de"] },
|
|
18
|
+
"additionalProperties": { "type": "string", "minLength": 1 }
|
|
19
|
+
},
|
|
14
20
|
"provides": { "description": "Capabilities it lets the agent use, by name only. Its capabilities' ids count as provided too.", "type": "array", "items": { "type": "string", "minLength": 1 } },
|
|
15
21
|
"capabilities": {
|
|
16
22
|
"description": "What it lets the agent do, for the person: each one's skills and tools together, described per language. Its id is what requires names; neutral ids (lms-grading) let skills depend on what can be done, not on which extension does it.",
|
|
@@ -35,7 +35,14 @@
|
|
|
35
35
|
"properties": {
|
|
36
36
|
"name": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" },
|
|
37
37
|
"version": { "description": "Its plugin.json's, the same as its marketplace entry's.", "type": "string", "minLength": 1 },
|
|
38
|
-
"description": { "type": "string" },
|
|
38
|
+
"description": { "description": "In English: its marketplace entry's, else its plugin.json's.", "type": "string" },
|
|
39
|
+
"descriptions": {
|
|
40
|
+
"description": "Its description per language, English among them; only when it has one in another language.",
|
|
41
|
+
"type": "object",
|
|
42
|
+
"propertyNames": { "enum": ["en", "es", "fr", "de"] },
|
|
43
|
+
"required": ["en"],
|
|
44
|
+
"additionalProperties": { "type": "string" }
|
|
45
|
+
},
|
|
39
46
|
"category": { "type": ["string", "null"] },
|
|
40
47
|
"topics": {
|
|
41
48
|
"description": "Its plugin.json's keywords and its entry's tags, keywords and category, lowercased, without repeats.",
|
|
@@ -47,6 +54,13 @@
|
|
|
47
54
|
"license": { "type": ["string", "null"] },
|
|
48
55
|
"homepage": { "$ref": "#/$defs/url" },
|
|
49
56
|
"readme": { "$ref": "#/$defs/url" },
|
|
57
|
+
"readmes": {
|
|
58
|
+
"description": "Its README per language (README.md, README.es.md…), as URLs; only when it has one in another language.",
|
|
59
|
+
"type": "object",
|
|
60
|
+
"propertyNames": { "enum": ["en", "es", "fr", "de"] },
|
|
61
|
+
"required": ["en"],
|
|
62
|
+
"additionalProperties": { "$ref": "#/$defs/url" }
|
|
63
|
+
},
|
|
50
64
|
"install": {
|
|
51
65
|
"type": "object",
|
|
52
66
|
"additionalProperties": false,
|