@bendyline/gezel-catalog 1.0.5 → 1.0.7
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/index.d.ts +71 -9
- package/dist/index.js +250 -14
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CatalogKind, CatalogItemSummary, CatalogItemDetail, CatalogItemVersionInfo, CraftbookTestSpec, ToolsetCategory, ToolsetManifest } from '@bendyline/gezel';
|
|
2
|
+
import { z } from 'zod';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* ─ CatalogSource ───────────────────────────────────────────────────
|
|
@@ -43,7 +44,7 @@ interface CatalogSource {
|
|
|
43
44
|
readItemFile(kind: CatalogKind, id: string, relPath: string, version?: string): Promise<Buffer | null>;
|
|
44
45
|
/**
|
|
45
46
|
* Optional: every file under an item's folder as item-relative paths. Only
|
|
46
|
-
* on-disk sources implement it (used by the `.
|
|
47
|
+
* on-disk sources implement it (used by the `.gezapp` exporter); synthetic
|
|
47
48
|
* sources (builtin toolsets) omit it.
|
|
48
49
|
*/
|
|
49
50
|
listItemFiles?(kind: CatalogKind, id: string): Promise<string[]>;
|
|
@@ -122,7 +123,7 @@ declare class BundledSource implements CatalogSource {
|
|
|
122
123
|
/**
|
|
123
124
|
* Every file under an item's folder, as item-relative paths (e.g.
|
|
124
125
|
* `manifest.json`, `versions/1.0.0/pages/gallery/index.html`), sorted. Used
|
|
125
|
-
* by the `.
|
|
126
|
+
* by the `.gezapp` exporter to pack an item verbatim — pages, seeds, and all
|
|
126
127
|
* assets, not just the ones the manifest names. Read each back with
|
|
127
128
|
* `readItemFile(kind, id, relPath)` (no version → item-relative). Empty when
|
|
128
129
|
* the item folder is missing.
|
|
@@ -172,9 +173,11 @@ declare class BundledSource implements CatalogSource {
|
|
|
172
173
|
*
|
|
173
174
|
* 1. BuiltinToolsetsSource — synthetic groups for our in-process MCP
|
|
174
175
|
* server. Tools we ship and own.
|
|
175
|
-
* 2.
|
|
176
|
+
* 2. InstalledAiAppsSource — active `.gezapp` packages mounted as units.
|
|
177
|
+
* 3. LocalCatalogSource — manually authored/imported user content.
|
|
178
|
+
* 4. BundledSource — pre-reviewed third-party catalog shipped with
|
|
176
179
|
* the app (`data/`). Hand-curated.
|
|
177
|
-
*
|
|
180
|
+
* 5. CommunitySource — auto-imported entries from the upstream MCP
|
|
178
181
|
* registry (`data/community/`). Permissively-licensed only;
|
|
179
182
|
* treated as a second tier that the UI can label distinctly.
|
|
180
183
|
*
|
|
@@ -185,9 +188,9 @@ declare class CatalogService {
|
|
|
185
188
|
private readonly contentRootProvider;
|
|
186
189
|
/**
|
|
187
190
|
* @param sources explicit source list (replaces the defaults entirely).
|
|
188
|
-
* @param opts.localRoot a GEZEL_HOME to read user-installed
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
+
* @param opts.localRoot a GEZEL_HOME to read user-installed catalog items and
|
|
192
|
+
* mounted `.gezapp` packages from. Both sit ahead of the bundled tier so a
|
|
193
|
+
* user's installed item shadows a same-id bundled one.
|
|
191
194
|
* @param opts.contentRoot dynamic gilde content root for the default
|
|
192
195
|
* bundled + community tiers, re-read on every disk access. The live
|
|
193
196
|
* gilde update mechanism flips it without reconstructing this service
|
|
@@ -217,7 +220,7 @@ declare class CatalogService {
|
|
|
217
220
|
label: string;
|
|
218
221
|
}>;
|
|
219
222
|
/**
|
|
220
|
-
* Merged listing across sources. Items from earlier sources
|
|
223
|
+
* Merged listing across sources. Items from earlier sources
|
|
221
224
|
* shadow later sources (remote) on id collision.
|
|
222
225
|
*/
|
|
223
226
|
list(kind: CatalogKind): Promise<CatalogItemSummary[]>;
|
|
@@ -288,6 +291,29 @@ declare class LocalCatalogSource extends BundledSource {
|
|
|
288
291
|
listItemFiles(kind: CatalogKind, id: string): Promise<string[]>;
|
|
289
292
|
}
|
|
290
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Dynamic catalog source over the active `.gezapp` registry. Package versions
|
|
296
|
+
* stay mounted as units under `~/.gezel/ai-apps/`; the importer never flattens
|
|
297
|
+
* their files into the generic local catalog, so provenance and uninstall
|
|
298
|
+
* remain tractable.
|
|
299
|
+
*/
|
|
300
|
+
declare class InstalledAiAppsSource implements CatalogSource {
|
|
301
|
+
private readonly home;
|
|
302
|
+
private readonly gezelVersion?;
|
|
303
|
+
readonly id = "installed-ai-apps";
|
|
304
|
+
readonly label = "AI Apps";
|
|
305
|
+
constructor(home: string, gezelVersion?: string | undefined);
|
|
306
|
+
listKinds(): Promise<CatalogKind[]>;
|
|
307
|
+
list(kind: CatalogKind): Promise<CatalogItemSummary[]>;
|
|
308
|
+
get(kind: CatalogKind, id: string, version?: string): Promise<CatalogItemDetail | null>;
|
|
309
|
+
listVersions(kind: CatalogKind, id: string): Promise<CatalogItemVersionInfo[]>;
|
|
310
|
+
readItemFile(kind: CatalogKind, id: string, relPath: string, version?: string): Promise<Buffer | null>;
|
|
311
|
+
listItemFiles(kind: CatalogKind, id: string): Promise<string[]>;
|
|
312
|
+
private registry;
|
|
313
|
+
private sources;
|
|
314
|
+
private rescope;
|
|
315
|
+
}
|
|
316
|
+
|
|
291
317
|
/**
|
|
292
318
|
* Categorize a toolset by its identity-manifest fields. The order of
|
|
293
319
|
* checks matches the priority order of `RULES` above.
|
|
@@ -304,6 +330,42 @@ declare function categorizeToolset(input: {
|
|
|
304
330
|
maintainerName?: string;
|
|
305
331
|
}): ToolsetCategory;
|
|
306
332
|
|
|
333
|
+
/**
|
|
334
|
+
* The gilde `schemas/` payload, defined once and consumed twice: the
|
|
335
|
+
* `export-gilde-schemas` script writes it into a gilde checkout, and
|
|
336
|
+
* `gilde-schema-freshness.test.ts` diffs it against the gilde this build
|
|
337
|
+
* actually resolves.
|
|
338
|
+
*
|
|
339
|
+
* The two consumers resolve gilde differently on purpose. The script
|
|
340
|
+
* writes to the sibling checkout (`GILDE_DIR`) because that is what you
|
|
341
|
+
* PR; the test reads the RESOLVED package (`gildePackageRoot()`) because
|
|
342
|
+
* that is what gezel ships against. With `pnpm link:gilde` they are the
|
|
343
|
+
* same tree; without it, the test is checking the pinned tarball.
|
|
344
|
+
*
|
|
345
|
+
* Why the test exists: gilde's `build-index` normalizes every manifest
|
|
346
|
+
* through these committed JSON Schemas, and a property the schema does
|
|
347
|
+
* not declare is dropped from the published `index.json` — which is the
|
|
348
|
+
* fast path `BundledSource` reads at runtime. So a core schema field
|
|
349
|
+
* added without re-exporting does not fail anywhere; it is silently
|
|
350
|
+
* erased from shipped content. Three craftbooks were shipping that way
|
|
351
|
+
* (`pull-request-review` lost `corpusCoverage.artifact`,
|
|
352
|
+
* `powerpoint-deck` lost `markdownHeadingsMatch.outlineArtifact`,
|
|
353
|
+
* `invoice-run` lost `spawn.overArtifact`) before anyone noticed.
|
|
354
|
+
*/
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* `unrepresentable` stays at its default ('throw') so a future transform
|
|
358
|
+
* in a published schema fails loudly here instead of silently weakening
|
|
359
|
+
* gilde validation.
|
|
360
|
+
*/
|
|
361
|
+
declare function renderSchema(filename: string, schema: z.ZodType): string;
|
|
362
|
+
/**
|
|
363
|
+
* Every file the gilde `schemas/` directory should contain, as exact
|
|
364
|
+
* file contents. Byte-for-byte what the exporter writes, so a test can
|
|
365
|
+
* compare against the committed copies without reimplementing anything.
|
|
366
|
+
*/
|
|
367
|
+
declare function renderGildeSchemaFiles(): Array<[filename: string, content: string]>;
|
|
368
|
+
|
|
307
369
|
/**
|
|
308
370
|
* ─ Built-in toolsets ────────────────────────────────────────────────
|
|
309
371
|
*
|
|
@@ -560,4 +622,4 @@ declare function totalSize(files: ReadonlyArray<HfFileEntry>): number;
|
|
|
560
622
|
*/
|
|
561
623
|
declare function selectMlxInstallFiles(files: ReadonlyArray<HfFileEntry>): HfFileEntry[];
|
|
562
624
|
|
|
563
|
-
export { BUILTIN_TOOLSETS, BUILTIN_TOOL_TO_GROUP, type BuiltinToolsetGroup, BuiltinToolsetsSource, BundledSource, type BundledSourceOptions, CatalogService, type CatalogSource, CommunitySource, type FetchTreeOptions, GILDE_PACKAGE_NAME, type GildeContentRegression, type GildeContentValidation, type GildeReleaseInfo, type HfFileEntry, LocalCatalogSource, builtinCatalogId, categorizeToolset, compareRelease, extractNpmPackageTarball, fetchGildeReleases, fetchHuggingfaceCommit, fetchHuggingfaceTree, getBuiltinToolset, gildeDataDir, gildePackageRoot, installNpmPackageToolset, isGildeReleaseVersion, pickGildePatchUpdate, publishStagedNpmInstall, recoverInterruptedNpmInstall, selectMlxInstallFiles, stageGildeVersion, totalSize, validateGildeContentUpgrade, validateNpmArchiveEntry, verifyTarballSha256 };
|
|
625
|
+
export { BUILTIN_TOOLSETS, BUILTIN_TOOL_TO_GROUP, type BuiltinToolsetGroup, BuiltinToolsetsSource, BundledSource, type BundledSourceOptions, CatalogService, type CatalogSource, CommunitySource, type FetchTreeOptions, GILDE_PACKAGE_NAME, type GildeContentRegression, type GildeContentValidation, type GildeReleaseInfo, type HfFileEntry, InstalledAiAppsSource, LocalCatalogSource, builtinCatalogId, categorizeToolset, compareRelease, extractNpmPackageTarball, fetchGildeReleases, fetchHuggingfaceCommit, fetchHuggingfaceTree, getBuiltinToolset, gildeDataDir, gildePackageRoot, installNpmPackageToolset, isGildeReleaseVersion, pickGildePatchUpdate, publishStagedNpmInstall, recoverInterruptedNpmInstall, renderGildeSchemaFiles, renderSchema, selectMlxInstallFiles, stageGildeVersion, totalSize, validateGildeContentUpgrade, validateNpmArchiveEntry, verifyTarballSha256 };
|
package/dist/index.js
CHANGED
|
@@ -33,6 +33,8 @@ var BUILTIN_TOOLSET_ICONS = {
|
|
|
33
33
|
tasks: `<svg ${SVG_ATTRS}><rect x="3" y="4" width="6" height="6" rx="1"/><path d="M4.5 7L6 8.5 8 5.5"/><rect x="3" y="14" width="6" height="6" rx="1"/><path d="M12 7h9M12 17h9"/></svg>`,
|
|
34
34
|
// Three connected nodes — a small team.
|
|
35
35
|
"team-management": `<svg ${SVG_ATTRS}><circle cx="12" cy="6" r="2.5"/><circle cx="6" cy="17" r="2.5"/><circle cx="18" cy="17" r="2.5"/><path d="M10.5 8L7.5 14.5M13.5 8l3 6.5M8.5 17h7"/></svg>`,
|
|
36
|
+
// A closed shipping box — a packaged app bundle.
|
|
37
|
+
"ai-apps": `<svg ${SVG_ATTRS}><path d="M21 8L12 3 3 8v8l9 5 9-5V8z"/><path d="M3 8l9 5 9-5"/><path d="M7.5 5.5l9 5"/></svg>`,
|
|
36
38
|
// Terminal-like frame with a prompt arrow.
|
|
37
39
|
"code-execution": `<svg ${SVG_ATTRS}><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M7 10l3 2-3 2M13 14h4"/></svg>`,
|
|
38
40
|
// Browser window + a tiny pointer.
|
|
@@ -61,8 +63,8 @@ var BUILTIN_TOOLSETS = [
|
|
|
61
63
|
{
|
|
62
64
|
id: "memory",
|
|
63
65
|
name: "Memory",
|
|
64
|
-
description: "
|
|
65
|
-
tools: ["search_memory", "save_memory", "list_memories"]
|
|
66
|
+
description: "Search indexed project knowledge through one unified surface, plus persistent notes a gezel can recall and write back. The generic search spans workspace content, artifacts, project/gezel memory, and shared documents.",
|
|
67
|
+
tools: ["search", "search_memory", "save_memory", "list_memories"]
|
|
66
68
|
},
|
|
67
69
|
{
|
|
68
70
|
id: "workspace-fs-read",
|
|
@@ -152,7 +154,7 @@ var BUILTIN_TOOLSETS = [
|
|
|
152
154
|
},
|
|
153
155
|
{
|
|
154
156
|
id: "documents",
|
|
155
|
-
name: "
|
|
157
|
+
name: "Shared document library",
|
|
156
158
|
description: "Cross-project shared library \u2014 mission docs, guidelines, and any markdown the user wants every gezel to be able to find.",
|
|
157
159
|
tools: [
|
|
158
160
|
"list_documents",
|
|
@@ -168,6 +170,12 @@ var BUILTIN_TOOLSETS = [
|
|
|
168
170
|
description: "Project-scoped read-write outputs (reports, scratch files, scripts a gezel produces, and large outputs auto-saved by tools that exceed the inline cap).",
|
|
169
171
|
tools: ["list_artifacts", "read_artifact", "write_artifact", "grep_artifact"]
|
|
170
172
|
},
|
|
173
|
+
{
|
|
174
|
+
id: "data-tables",
|
|
175
|
+
name: "Data Tables",
|
|
176
|
+
description: "Read a project's mirrored data tables with SQL. `list_tables` shows what is there, `describe_table` explains a table's columns and units, and `query_table` runs one read-only query and returns the answer \u2014 never the underlying rows, which is what lets a table be far larger than the context window.",
|
|
177
|
+
tools: ["list_tables", "describe_table", "query_table"]
|
|
178
|
+
},
|
|
171
179
|
{
|
|
172
180
|
id: "tasks",
|
|
173
181
|
name: "Task Management",
|
|
@@ -243,8 +251,6 @@ var BUILTIN_TOOLSETS = [
|
|
|
243
251
|
"list_project_types",
|
|
244
252
|
"apply_project_type",
|
|
245
253
|
"start_project_from_type",
|
|
246
|
-
"export_project_type",
|
|
247
|
-
"import_project_type",
|
|
248
254
|
"list_project_gezels",
|
|
249
255
|
"add_gezel_to_project",
|
|
250
256
|
"remove_gezel_from_project",
|
|
@@ -253,6 +259,12 @@ var BUILTIN_TOOLSETS = [
|
|
|
253
259
|
"disable_suggested_work"
|
|
254
260
|
]
|
|
255
261
|
},
|
|
262
|
+
{
|
|
263
|
+
id: "ai-apps",
|
|
264
|
+
name: "AI Apps",
|
|
265
|
+
description: "Package a configured project into a shareable .gezapp bundle and install one back. Deliberately in no role default: this is a distribution chore the user drives from Settings or the `gezel app` CLI, not something a gezel reaches for mid-conversation. Install it on a gezel whose actual job is publishing app bundles.",
|
|
266
|
+
tools: ["export_ai_app", "import_ai_app"]
|
|
267
|
+
},
|
|
256
268
|
{
|
|
257
269
|
id: "audio",
|
|
258
270
|
name: "Audio",
|
|
@@ -303,8 +315,14 @@ var BUILTIN_TOOLSETS = [
|
|
|
303
315
|
{
|
|
304
316
|
id: "web",
|
|
305
317
|
name: "Web Access",
|
|
306
|
-
description: "Search the web (when a keyed backend like Brave is configured) or Wikipedia, fetch URL contents, and find interactive elements on a browser-controlled page (after a Playwright navigate / click / type). `web_search` only registers when a real keyed backend is configured; `wikipedia_search` only
|
|
307
|
-
tools: [
|
|
318
|
+
description: "Search the web (when a keyed backend like Brave is configured) or Wikipedia, fetch URL contents, and find interactive elements on a browser-controlled page (after a Playwright navigate / click / type). `web_search` only registers when a real keyed backend is configured; `wikipedia_search` / `wikipedia_read` only register for non-cloud models (cloud models already have Wikipedia in training). Wikipedia search results arrive with article lead text already included, so reading a result does not need a follow-up fetch.",
|
|
319
|
+
tools: [
|
|
320
|
+
"web_search",
|
|
321
|
+
"wikipedia_search",
|
|
322
|
+
"wikipedia_read",
|
|
323
|
+
"fetch_url",
|
|
324
|
+
"browser_find_page_element"
|
|
325
|
+
]
|
|
308
326
|
},
|
|
309
327
|
{
|
|
310
328
|
id: "images",
|
|
@@ -718,7 +736,7 @@ var BundledSource = class {
|
|
|
718
736
|
/**
|
|
719
737
|
* Every file under an item's folder, as item-relative paths (e.g.
|
|
720
738
|
* `manifest.json`, `versions/1.0.0/pages/gallery/index.html`), sorted. Used
|
|
721
|
-
* by the `.
|
|
739
|
+
* by the `.gezapp` exporter to pack an item verbatim — pages, seeds, and all
|
|
722
740
|
* assets, not just the ones the manifest names. Read each back with
|
|
723
741
|
* `readItemFile(kind, id, relPath)` (no version → item-relative). Empty when
|
|
724
742
|
* the item folder is missing.
|
|
@@ -1005,6 +1023,7 @@ function craftbookManifestFromDoc(identity, doc, version, availableVersions) {
|
|
|
1005
1023
|
version,
|
|
1006
1024
|
releasedAt: doc.releasedAt,
|
|
1007
1025
|
role: identity.role,
|
|
1026
|
+
...identity.category ? { category: identity.category } : {},
|
|
1008
1027
|
...identity.workflow ? { workflow: identity.workflow } : {},
|
|
1009
1028
|
// The prose lives inline on the doc (`description`) — there is no
|
|
1010
1029
|
// separate about.md file to point at. `get()` surfaces it directly.
|
|
@@ -1020,11 +1039,15 @@ function craftbookManifestFromDoc(identity, doc, version, availableVersions) {
|
|
|
1020
1039
|
...doc.paramSchema ? { paramSchema: doc.paramSchema } : {},
|
|
1021
1040
|
...doc.command ? { command: doc.command } : {},
|
|
1022
1041
|
...doc.requirements ? { requirements: doc.requirements } : {},
|
|
1042
|
+
...doc.recommends ? { recommends: doc.recommends } : {},
|
|
1023
1043
|
...doc.runModes ? { runModes: doc.runModes } : {},
|
|
1024
1044
|
...doc.toolsets ? { toolsets: doc.toolsets } : {},
|
|
1045
|
+
...doc.commands ? { commands: doc.commands } : {},
|
|
1025
1046
|
...doc.connectors ? { connectors: doc.connectors } : {},
|
|
1026
1047
|
...doc.hooks ? { hooks: doc.hooks } : {},
|
|
1027
1048
|
...doc.spawn ? { spawn: doc.spawn } : {},
|
|
1049
|
+
...doc.diffpackCapable ? { diffpackCapable: true } : {},
|
|
1050
|
+
...doc.capabilityFloor ? { capabilityFloor: doc.capabilityFloor } : {},
|
|
1028
1051
|
availableVersions
|
|
1029
1052
|
};
|
|
1030
1053
|
}
|
|
@@ -1111,6 +1134,7 @@ function mergeIdentityAndVersion(kind, identity, version, availableVersions) {
|
|
|
1111
1134
|
version: version.version,
|
|
1112
1135
|
releasedAt: version.releasedAt,
|
|
1113
1136
|
role: identity.role,
|
|
1137
|
+
...identity.category ? { category: identity.category } : {},
|
|
1114
1138
|
...identity.workflow ? { workflow: identity.workflow } : {},
|
|
1115
1139
|
about: version.about,
|
|
1116
1140
|
steps: version.steps,
|
|
@@ -1125,6 +1149,7 @@ function mergeIdentityAndVersion(kind, identity, version, availableVersions) {
|
|
|
1125
1149
|
...version.paramSchema ? { paramSchema: version.paramSchema } : {},
|
|
1126
1150
|
...version.command ? { command: version.command } : {},
|
|
1127
1151
|
...version.requirements ? { requirements: version.requirements } : {},
|
|
1152
|
+
...version.recommends ? { recommends: version.recommends } : {},
|
|
1128
1153
|
...version.runModes ? { runModes: version.runModes } : {},
|
|
1129
1154
|
...version.toolsets ? { toolsets: version.toolsets } : {},
|
|
1130
1155
|
...version.connectors ? { connectors: version.connectors } : {},
|
|
@@ -1140,6 +1165,7 @@ function mergeIdentityAndVersion(kind, identity, version, availableVersions) {
|
|
|
1140
1165
|
description: identity.description,
|
|
1141
1166
|
tags: identity.tags,
|
|
1142
1167
|
...identity.category !== void 0 ? { category: identity.category } : {},
|
|
1168
|
+
...identity.icon !== void 0 ? { icon: identity.icon } : {},
|
|
1143
1169
|
maintainer: identity.maintainer,
|
|
1144
1170
|
...identity.logo !== void 0 ? { logo: identity.logo } : {},
|
|
1145
1171
|
...identity.license !== void 0 ? { license: identity.license } : {},
|
|
@@ -1363,6 +1389,108 @@ var CommunitySource = class extends BundledSource {
|
|
|
1363
1389
|
}
|
|
1364
1390
|
};
|
|
1365
1391
|
|
|
1392
|
+
// src/installed-ai-apps-source.ts
|
|
1393
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
1394
|
+
import { GezappRegistrySchema } from "@bendyline/gezel";
|
|
1395
|
+
import { aiAppItemsDir, aiAppsRegistryFile } from "@bendyline/gezel/paths";
|
|
1396
|
+
var AI_APP_KINDS = /* @__PURE__ */ new Set([
|
|
1397
|
+
"project-type",
|
|
1398
|
+
"gezel-template",
|
|
1399
|
+
"craftbook-template"
|
|
1400
|
+
]);
|
|
1401
|
+
var InstalledAiAppsSource = class {
|
|
1402
|
+
constructor(home, gezelVersion) {
|
|
1403
|
+
this.home = home;
|
|
1404
|
+
this.gezelVersion = gezelVersion;
|
|
1405
|
+
}
|
|
1406
|
+
home;
|
|
1407
|
+
gezelVersion;
|
|
1408
|
+
id = "installed-ai-apps";
|
|
1409
|
+
label = "AI Apps";
|
|
1410
|
+
async listKinds() {
|
|
1411
|
+
return [...AI_APP_KINDS];
|
|
1412
|
+
}
|
|
1413
|
+
async list(kind) {
|
|
1414
|
+
if (!AI_APP_KINDS.has(kind)) return [];
|
|
1415
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1416
|
+
const out = [];
|
|
1417
|
+
for (const source of await this.sources()) {
|
|
1418
|
+
for (const item of await source.list(kind)) {
|
|
1419
|
+
if (seen.has(item.manifest.id)) continue;
|
|
1420
|
+
seen.add(item.manifest.id);
|
|
1421
|
+
out.push(this.rescope(item));
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
out.sort((a, b) => a.manifest.name.localeCompare(b.manifest.name));
|
|
1425
|
+
return out;
|
|
1426
|
+
}
|
|
1427
|
+
async get(kind, id, version) {
|
|
1428
|
+
if (!AI_APP_KINDS.has(kind)) return null;
|
|
1429
|
+
for (const source of await this.sources()) {
|
|
1430
|
+
const item = await source.get(kind, id, version);
|
|
1431
|
+
if (item) return this.rescope(item);
|
|
1432
|
+
}
|
|
1433
|
+
return null;
|
|
1434
|
+
}
|
|
1435
|
+
async listVersions(kind, id) {
|
|
1436
|
+
if (!AI_APP_KINDS.has(kind)) return [];
|
|
1437
|
+
const byVersion = /* @__PURE__ */ new Map();
|
|
1438
|
+
for (const source of await this.sources()) {
|
|
1439
|
+
for (const version of await source.listVersions(kind, id)) {
|
|
1440
|
+
if (!byVersion.has(version.version)) byVersion.set(version.version, version);
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
return [...byVersion.values()];
|
|
1444
|
+
}
|
|
1445
|
+
async readItemFile(kind, id, relPath, version) {
|
|
1446
|
+
if (!AI_APP_KINDS.has(kind)) return null;
|
|
1447
|
+
for (const source of await this.sources()) {
|
|
1448
|
+
const content = await source.readItemFile(kind, id, relPath, version);
|
|
1449
|
+
if (content) return content;
|
|
1450
|
+
}
|
|
1451
|
+
return null;
|
|
1452
|
+
}
|
|
1453
|
+
async listItemFiles(kind, id) {
|
|
1454
|
+
if (!AI_APP_KINDS.has(kind)) return [];
|
|
1455
|
+
for (const source of await this.sources()) {
|
|
1456
|
+
const files = await source.listItemFiles(kind, id);
|
|
1457
|
+
if (files.length > 0) return files;
|
|
1458
|
+
}
|
|
1459
|
+
return [];
|
|
1460
|
+
}
|
|
1461
|
+
async registry() {
|
|
1462
|
+
try {
|
|
1463
|
+
return GezappRegistrySchema.parse(
|
|
1464
|
+
JSON.parse(await readFile2(aiAppsRegistryFile(this.home), "utf8"))
|
|
1465
|
+
);
|
|
1466
|
+
} catch {
|
|
1467
|
+
return { schemaVersion: 1, apps: [] };
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
async sources() {
|
|
1471
|
+
const registry = await this.registry();
|
|
1472
|
+
return registry.apps.filter((entry) => entry.enabled).map(
|
|
1473
|
+
(entry) => new BundledSource({
|
|
1474
|
+
dataDir: aiAppItemsDir(this.home, entry.appId, entry.version),
|
|
1475
|
+
id: `gezapp:${entry.appId}@${entry.version}`,
|
|
1476
|
+
label: this.label,
|
|
1477
|
+
noIndex: true,
|
|
1478
|
+
...this.gezelVersion !== void 0 ? { gezelVersion: this.gezelVersion } : {}
|
|
1479
|
+
})
|
|
1480
|
+
);
|
|
1481
|
+
}
|
|
1482
|
+
rescope(item) {
|
|
1483
|
+
const { logoUrl: _ignored, ...rest } = item;
|
|
1484
|
+
const logo = item.manifest.logo;
|
|
1485
|
+
const logoUrl = logo && /^https?:\/\//.test(logo) ? logo : logo ? `/api/catalog/${item.kind}/${encodeURIComponent(item.manifest.id)}/file/${encodeURIComponent(logo)}?source=${encodeURIComponent(this.id)}` : void 0;
|
|
1486
|
+
return {
|
|
1487
|
+
...rest,
|
|
1488
|
+
sourceId: this.id,
|
|
1489
|
+
...logoUrl ? { logoUrl } : {}
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1492
|
+
};
|
|
1493
|
+
|
|
1366
1494
|
// src/local-source.ts
|
|
1367
1495
|
var LOCAL_KINDS = /* @__PURE__ */ new Set([
|
|
1368
1496
|
"project-type",
|
|
@@ -1411,9 +1539,9 @@ var CatalogService = class {
|
|
|
1411
1539
|
contentRootProvider;
|
|
1412
1540
|
/**
|
|
1413
1541
|
* @param sources explicit source list (replaces the defaults entirely).
|
|
1414
|
-
* @param opts.localRoot a GEZEL_HOME to read user-installed
|
|
1415
|
-
*
|
|
1416
|
-
*
|
|
1542
|
+
* @param opts.localRoot a GEZEL_HOME to read user-installed catalog items and
|
|
1543
|
+
* mounted `.gezapp` packages from. Both sit ahead of the bundled tier so a
|
|
1544
|
+
* user's installed item shadows a same-id bundled one.
|
|
1417
1545
|
* @param opts.contentRoot dynamic gilde content root for the default
|
|
1418
1546
|
* bundled + community tiers, re-read on every disk access. The live
|
|
1419
1547
|
* gilde update mechanism flips it without reconstructing this service
|
|
@@ -1434,8 +1562,10 @@ var CatalogService = class {
|
|
|
1434
1562
|
const contentRoot = opts?.contentRoot;
|
|
1435
1563
|
const gezelVersion = opts?.gezelVersion;
|
|
1436
1564
|
const local = opts?.localRoot ? [new LocalCatalogSource(opts.localRoot, gezelVersion)] : [];
|
|
1565
|
+
const aiApps = opts?.localRoot ? [new InstalledAiAppsSource(opts.localRoot, gezelVersion)] : [];
|
|
1437
1566
|
this.sources = [
|
|
1438
1567
|
new BuiltinToolsetsSource(),
|
|
1568
|
+
...aiApps,
|
|
1439
1569
|
...local,
|
|
1440
1570
|
new BundledSource({
|
|
1441
1571
|
...contentRoot ? { dataDir: contentRoot } : {},
|
|
@@ -1461,7 +1591,7 @@ var CatalogService = class {
|
|
|
1461
1591
|
return this.sources.map((s) => ({ id: s.id, label: s.label }));
|
|
1462
1592
|
}
|
|
1463
1593
|
/**
|
|
1464
|
-
* Merged listing across sources. Items from earlier sources
|
|
1594
|
+
* Merged listing across sources. Items from earlier sources
|
|
1465
1595
|
* shadow later sources (remote) on id collision.
|
|
1466
1596
|
*/
|
|
1467
1597
|
async list(kind) {
|
|
@@ -1832,11 +1962,114 @@ function categorizeToolset(input) {
|
|
|
1832
1962
|
return "other";
|
|
1833
1963
|
}
|
|
1834
1964
|
|
|
1965
|
+
// src/gilde-schema-export.ts
|
|
1966
|
+
import {
|
|
1967
|
+
ChatModelIdentitySchema,
|
|
1968
|
+
ChatModelVersionManifestSchema as ChatModelVersionManifestSchema2,
|
|
1969
|
+
ConnectorTypeIdentitySchema,
|
|
1970
|
+
ConnectorTypeVersionManifestSchema as ConnectorTypeVersionManifestSchema2,
|
|
1971
|
+
CraftbookDocSchema,
|
|
1972
|
+
CraftbookTemplateIdentitySchema,
|
|
1973
|
+
CraftbookTemplateVersionManifestSchema as CraftbookTemplateVersionManifestSchema2,
|
|
1974
|
+
CraftbookTestSpecSchema,
|
|
1975
|
+
GezelTemplateIdentitySchema,
|
|
1976
|
+
GezelTemplateVersionManifestSchema as GezelTemplateVersionManifestSchema2,
|
|
1977
|
+
ImageModelIdentitySchema,
|
|
1978
|
+
ImageModelVersionManifestSchema as ImageModelVersionManifestSchema2,
|
|
1979
|
+
ProjectTypeIdentitySchema,
|
|
1980
|
+
ProjectTypeVersionManifestSchema as ProjectTypeVersionManifestSchema2,
|
|
1981
|
+
ToolsetIdentitySchema,
|
|
1982
|
+
ToolsetVersionManifestSchema as ToolsetVersionManifestSchema2,
|
|
1983
|
+
VideoModelIdentitySchema,
|
|
1984
|
+
VideoModelVersionManifestSchema as VideoModelVersionManifestSchema2
|
|
1985
|
+
} from "@bendyline/gezel";
|
|
1986
|
+
import { z } from "zod";
|
|
1987
|
+
var GILDE_SCHEMA_EXPORTS = [
|
|
1988
|
+
["toolset-identity.schema.json", ToolsetIdentitySchema],
|
|
1989
|
+
["toolset-version.schema.json", ToolsetVersionManifestSchema2],
|
|
1990
|
+
["gezel-template-identity.schema.json", GezelTemplateIdentitySchema],
|
|
1991
|
+
["gezel-template-version.schema.json", GezelTemplateVersionManifestSchema2],
|
|
1992
|
+
["craftbook-template-identity.schema.json", CraftbookTemplateIdentitySchema],
|
|
1993
|
+
["craftbook-template-version.schema.json", CraftbookTemplateVersionManifestSchema2],
|
|
1994
|
+
["project-type-identity.schema.json", ProjectTypeIdentitySchema],
|
|
1995
|
+
["project-type-version.schema.json", ProjectTypeVersionManifestSchema2],
|
|
1996
|
+
["connector-type-identity.schema.json", ConnectorTypeIdentitySchema],
|
|
1997
|
+
["connector-type-version.schema.json", ConnectorTypeVersionManifestSchema2],
|
|
1998
|
+
["chat-model-identity.schema.json", ChatModelIdentitySchema],
|
|
1999
|
+
["chat-model-version.schema.json", ChatModelVersionManifestSchema2],
|
|
2000
|
+
["image-model-identity.schema.json", ImageModelIdentitySchema],
|
|
2001
|
+
["image-model-version.schema.json", ImageModelVersionManifestSchema2],
|
|
2002
|
+
["video-model-identity.schema.json", VideoModelIdentitySchema],
|
|
2003
|
+
["video-model-version.schema.json", VideoModelVersionManifestSchema2],
|
|
2004
|
+
["craftbook-doc.schema.json", CraftbookDocSchema],
|
|
2005
|
+
["craftbook-test.schema.json", CraftbookTestSpecSchema]
|
|
2006
|
+
];
|
|
2007
|
+
var CATALOG_INDEX_SCHEMA = {
|
|
2008
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
2009
|
+
$id: "https://gezelgilde.com/schemas/catalog-index.schema.json",
|
|
2010
|
+
type: "object",
|
|
2011
|
+
properties: {
|
|
2012
|
+
schemaVersion: { type: "number", const: 1 },
|
|
2013
|
+
kind: { type: "string" },
|
|
2014
|
+
count: { type: "number", minimum: 0 },
|
|
2015
|
+
entries: {
|
|
2016
|
+
type: "array",
|
|
2017
|
+
items: {
|
|
2018
|
+
type: "object",
|
|
2019
|
+
properties: {
|
|
2020
|
+
manifest: { type: "object" },
|
|
2021
|
+
iconSvg: { type: "string" }
|
|
2022
|
+
},
|
|
2023
|
+
required: ["manifest"]
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
},
|
|
2027
|
+
required: ["schemaVersion", "kind", "count", "entries"]
|
|
2028
|
+
};
|
|
2029
|
+
var GILDE_SCHEMAS_README = `# schemas/
|
|
2030
|
+
|
|
2031
|
+
JSON Schemas for every content file in \`data/\`, consumed by
|
|
2032
|
+
\`tools/validate.mjs\`.
|
|
2033
|
+
|
|
2034
|
+
**Generated \u2014 do not edit.** These are exported from the Zod schemas in
|
|
2035
|
+
gezel core (\`packages/core/src/schemas/\`), which remain the source of
|
|
2036
|
+
truth. Regenerate from a gezel checkout with:
|
|
2037
|
+
|
|
2038
|
+
\`\`\`
|
|
2039
|
+
pnpm gilde:export-schemas
|
|
2040
|
+
\`\`\`
|
|
2041
|
+
|
|
2042
|
+
Note: Zod refinements do not survive the export, so validation here is
|
|
2043
|
+
slightly looser than gezel's runtime parse. Layout and cross-reference
|
|
2044
|
+
rules that matter are re-implemented in \`tools/validate.mjs\`.
|
|
2045
|
+
`;
|
|
2046
|
+
function renderSchema(filename, schema) {
|
|
2047
|
+
const json = z.toJSONSchema(schema, { target: "draft-2020-12", io: "input" });
|
|
2048
|
+
const withId = {
|
|
2049
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
2050
|
+
$id: `https://gezelgilde.com/schemas/${filename}`,
|
|
2051
|
+
...json
|
|
2052
|
+
};
|
|
2053
|
+
withId.$schema = "https://json-schema.org/draft/2020-12/schema";
|
|
2054
|
+
return `${JSON.stringify(withId, null, 2)}
|
|
2055
|
+
`;
|
|
2056
|
+
}
|
|
2057
|
+
function renderGildeSchemaFiles() {
|
|
2058
|
+
return [
|
|
2059
|
+
...GILDE_SCHEMA_EXPORTS.map(
|
|
2060
|
+
([filename, schema]) => [filename, renderSchema(filename, schema)]
|
|
2061
|
+
),
|
|
2062
|
+
["catalog-index.schema.json", `${JSON.stringify(CATALOG_INDEX_SCHEMA, null, 2)}
|
|
2063
|
+
`],
|
|
2064
|
+
["README.md", GILDE_SCHEMAS_README]
|
|
2065
|
+
];
|
|
2066
|
+
}
|
|
2067
|
+
|
|
1835
2068
|
// src/install/npm-package.ts
|
|
1836
2069
|
import { spawn } from "child_process";
|
|
1837
2070
|
import { createHash, randomUUID } from "crypto";
|
|
1838
2071
|
import { createReadStream } from "fs";
|
|
1839
|
-
import { mkdir, open, readFile as
|
|
2072
|
+
import { mkdir, open, readFile as readFile3, realpath, rename, rm, stat, writeFile } from "fs/promises";
|
|
1840
2073
|
import { dirname as dirname2, isAbsolute, join as join5, relative, resolve } from "path";
|
|
1841
2074
|
import {
|
|
1842
2075
|
HttpStatusError,
|
|
@@ -2045,7 +2278,7 @@ function validateNpmArchiveEntry(path, type) {
|
|
|
2045
2278
|
}
|
|
2046
2279
|
}
|
|
2047
2280
|
async function validateExtractedPackage(packageDir, expectedName, expectedVersion) {
|
|
2048
|
-
const raw = await
|
|
2281
|
+
const raw = await readFile3(join5(packageDir, "package.json"), "utf8");
|
|
2049
2282
|
const parsed = JSON.parse(raw);
|
|
2050
2283
|
if (parsed.name !== expectedName || parsed.version !== expectedVersion) {
|
|
2051
2284
|
throw new Error("[catalog] extracted package identity does not match the pinned manifest");
|
|
@@ -2489,6 +2722,7 @@ export {
|
|
|
2489
2722
|
CatalogService,
|
|
2490
2723
|
CommunitySource,
|
|
2491
2724
|
GILDE_PACKAGE_NAME,
|
|
2725
|
+
InstalledAiAppsSource,
|
|
2492
2726
|
LocalCatalogSource,
|
|
2493
2727
|
builtinCatalogId,
|
|
2494
2728
|
categorizeToolset,
|
|
@@ -2505,6 +2739,8 @@ export {
|
|
|
2505
2739
|
pickGildePatchUpdate,
|
|
2506
2740
|
publishStagedNpmInstall,
|
|
2507
2741
|
recoverInterruptedNpmInstall,
|
|
2742
|
+
renderGildeSchemaFiles,
|
|
2743
|
+
renderSchema,
|
|
2508
2744
|
selectMlxInstallFiles,
|
|
2509
2745
|
stageGildeVersion,
|
|
2510
2746
|
totalSize,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bendyline/gezel-catalog",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Gezel catalog loader: sources, install pipeline, and authoring scripts over the external @bendyline/gilde content package.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"!dist/**/*.map"
|
|
48
48
|
],
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@bendyline/gezel": "1.0.
|
|
51
|
-
"@bendyline/gilde": "0.1.
|
|
50
|
+
"@bendyline/gezel": "1.0.7",
|
|
51
|
+
"@bendyline/gilde": "0.1.51",
|
|
52
52
|
"tar": "7.5.21",
|
|
53
53
|
"zod": "^4.4.3"
|
|
54
54
|
},
|