@codemcp/ade 0.7.0 → 0.8.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.
Files changed (38) hide show
  1. package/.beads/issues.jsonl +26 -0
  2. package/.beads/last-touched +1 -1
  3. package/.vibe/beads-state-ade-fix-docset-writing-37fuoj.json +29 -0
  4. package/.vibe/development-plan-fix-docset-writing.md +77 -0
  5. package/.vibe/docs/architecture.md +201 -0
  6. package/.vibe/docs/design.md +179 -0
  7. package/.vibe/docs/requirements.md +17 -0
  8. package/ade.extensions.mjs +13 -15
  9. package/docs/CLI-PRD.md +38 -40
  10. package/docs/CLI-design.md +47 -57
  11. package/docs/guide/extensions.md +6 -14
  12. package/package.json +1 -1
  13. package/packages/cli/dist/index.js +15202 -5579
  14. package/packages/cli/package.json +1 -1
  15. package/packages/cli/src/commands/conventions.integration.spec.ts +29 -4
  16. package/packages/cli/src/commands/extensions.integration.spec.ts +26 -4
  17. package/packages/cli/src/commands/install.ts +2 -0
  18. package/packages/cli/src/commands/knowledge-docset.integration.spec.ts +179 -0
  19. package/packages/cli/src/commands/knowledge.integration.spec.ts +24 -36
  20. package/packages/cli/src/commands/setup.spec.ts +1 -101
  21. package/packages/cli/src/commands/setup.ts +23 -36
  22. package/packages/cli/src/knowledge-installer.spec.ts +43 -3
  23. package/packages/cli/src/knowledge-installer.ts +12 -9
  24. package/packages/core/package.json +1 -1
  25. package/packages/core/src/catalog/catalog.spec.ts +75 -43
  26. package/packages/core/src/catalog/facets/architecture.ts +89 -58
  27. package/packages/core/src/catalog/facets/practices.ts +9 -8
  28. package/packages/core/src/index.ts +4 -4
  29. package/packages/core/src/registry.spec.ts +1 -1
  30. package/packages/core/src/registry.ts +2 -2
  31. package/packages/core/src/resolver.spec.ts +61 -154
  32. package/packages/core/src/resolver.ts +0 -54
  33. package/packages/core/src/types.ts +5 -10
  34. package/packages/core/src/writers/docset.spec.ts +40 -0
  35. package/packages/core/src/writers/docset.ts +24 -0
  36. package/packages/harnesses/package.json +1 -1
  37. package/packages/core/src/writers/knowledge.spec.ts +0 -26
  38. package/packages/core/src/writers/knowledge.ts +0 -15
@@ -56,6 +56,24 @@ describe("installKnowledge", () => {
56
56
  );
57
57
  });
58
58
 
59
+ it("uses source.preset when provided instead of defaulting to git-repo", async () => {
60
+ const sources: KnowledgeSource[] = [
61
+ {
62
+ name: "my-archive",
63
+ origin: "https://example.com/docs.tar.gz",
64
+ description: "Archive docs",
65
+ preset: "archive"
66
+ }
67
+ ];
68
+
69
+ await installKnowledge(sources, "/tmp/project");
70
+
71
+ expect(createDocset).toHaveBeenCalledWith(
72
+ expect.objectContaining({ preset: "archive" }),
73
+ expect.anything()
74
+ );
75
+ });
76
+
59
77
  it("calls initDocset for each knowledge source after creation", async () => {
60
78
  const sources: KnowledgeSource[] = [
61
79
  {
@@ -76,9 +94,9 @@ describe("installKnowledge", () => {
76
94
  );
77
95
  });
78
96
 
79
- it("continues with remaining sources when one fails", async () => {
97
+ it("continues with remaining sources when createDocset fails with a real error", async () => {
80
98
  vi.mocked(createDocset)
81
- .mockRejectedValueOnce(new Error("already exists"))
99
+ .mockRejectedValueOnce(new Error("network error"))
82
100
  .mockResolvedValueOnce({
83
101
  docset: {},
84
102
  configPath: ".knowledge/config.yaml",
@@ -102,10 +120,32 @@ describe("installKnowledge", () => {
102
120
 
103
121
  // Should have attempted both
104
122
  expect(createDocset).toHaveBeenCalledTimes(2);
105
- // initDocset only called for the successful one
123
+ // initDocset only called for the successful one (real error skips it)
106
124
  expect(initDocset).toHaveBeenCalledTimes(1);
107
125
  expect(initDocset).toHaveBeenCalledWith(
108
126
  expect.objectContaining({ docsetId: "succeeding" })
109
127
  );
110
128
  });
129
+
130
+ it("proceeds to initDocset when createDocset reports docset already exists", async () => {
131
+ vi.mocked(createDocset).mockRejectedValueOnce(
132
+ new Error("Docset with ID 'react-docs' already exists")
133
+ );
134
+
135
+ const sources: KnowledgeSource[] = [
136
+ {
137
+ name: "react-docs",
138
+ origin: "https://github.com/facebook/react.git",
139
+ description: "React documentation"
140
+ }
141
+ ];
142
+
143
+ await installKnowledge(sources, "/tmp/project");
144
+
145
+ // createDocset failed with "already exists" — initDocset must still be called
146
+ expect(initDocset).toHaveBeenCalledTimes(1);
147
+ expect(initDocset).toHaveBeenCalledWith(
148
+ expect.objectContaining({ docsetId: "react-docs" })
149
+ );
150
+ });
111
151
  });
@@ -8,7 +8,7 @@ import {
8
8
  * Install knowledge sources using the @codemcp/knowledge programmatic API.
9
9
  *
10
10
  * For each knowledge source:
11
- * 1. Creates a docset config entry via `createDocset`
11
+ * 1. Creates a docset config entry via `createDocset` (skips if already exists)
12
12
  * 2. Initializes (downloads) the docset via `initDocset`
13
13
  *
14
14
  * Errors on individual sources are logged and skipped so that one failure
@@ -16,7 +16,8 @@ import {
16
16
  */
17
17
  export async function installKnowledge(
18
18
  sources: KnowledgeSource[],
19
- projectRoot: string
19
+ projectRoot: string,
20
+ options: { force?: boolean } = {}
20
21
  ): Promise<void> {
21
22
  if (sources.length === 0) return;
22
23
 
@@ -26,23 +27,25 @@ export async function installKnowledge(
26
27
  {
27
28
  id: source.name,
28
29
  name: source.description,
29
- preset: "git-repo" as const,
30
+ preset: source.preset ?? "git-repo",
30
31
  url: source.origin
31
32
  },
32
33
  { cwd: projectRoot }
33
34
  );
34
35
  } catch (err) {
35
- console.warn(
36
- `Warning: failed to create docset "${source.name}":`,
37
- err instanceof Error ? err.message : err
38
- );
39
- continue;
36
+ const msg = err instanceof Error ? err.message : String(err);
37
+ if (!msg.includes("already exists")) {
38
+ console.warn(`Warning: failed to create docset "${source.name}":`, msg);
39
+ continue;
40
+ }
41
+ // Docset already registered in config — proceed to (re-)initialize it
40
42
  }
41
43
 
42
44
  try {
43
45
  await initDocset({
44
46
  docsetId: source.name,
45
- cwd: projectRoot
47
+ cwd: projectRoot,
48
+ ...(options.force && { force: true })
46
49
  });
47
50
  } catch (err) {
48
51
  console.warn(
@@ -39,5 +39,5 @@
39
39
  "typescript": "catalog:",
40
40
  "vitest": "catalog:"
41
41
  },
42
- "version": "0.7.0"
42
+ "version": "0.8.0"
43
43
  }
@@ -118,29 +118,39 @@ describe("catalog", () => {
118
118
  expect(names).toContain("nodejs-backend-testing");
119
119
  });
120
120
 
121
- it("nodejs-backend option declares docsets for tRPC, Drizzle, Express, and Zod", () => {
121
+ it("nodejs-backend option declares docset recipe entries for tRPC, Drizzle, Express, and Zod", () => {
122
122
  const catalog = getDefaultCatalog();
123
123
  const architecture = getFacet(catalog, "architecture")!;
124
124
  const nodejsBackend = getOption(architecture, "nodejs-backend")!;
125
125
 
126
- expect(nodejsBackend.docsets).toBeDefined();
127
- const ids = nodejsBackend.docsets!.map((d) => d.id);
128
- expect(ids).toContain("trpc-docs");
129
- expect(ids).toContain("drizzle-orm-docs");
130
- expect(ids).toContain("express-docs");
131
- expect(ids).toContain("zod-docs");
126
+ const docsetIds = nodejsBackend.recipe
127
+ .filter((p) => p.writer === "docset")
128
+ .map((p) => (p.config as { id: string }).id);
129
+ expect(docsetIds).toContain("trpc-docs");
130
+ expect(docsetIds).toContain("drizzle-orm-docs");
131
+ expect(docsetIds).toContain("express-docs");
132
+ expect(docsetIds).toContain("zod-docs");
132
133
  });
133
134
 
134
- it("each nodejs-backend docset has required fields", () => {
135
+ it("each nodejs-backend docset recipe entry has required fields", () => {
135
136
  const catalog = getDefaultCatalog();
136
137
  const architecture = getFacet(catalog, "architecture")!;
137
138
  const nodejsBackend = getOption(architecture, "nodejs-backend")!;
138
139
 
139
- for (const docset of nodejsBackend.docsets!) {
140
- expect(docset.id).toBeTruthy();
141
- expect(docset.label).toBeTruthy();
142
- expect(docset.origin).toMatch(/^https:\/\//);
143
- expect(docset.description).toBeTruthy();
140
+ const docsetProvisions = nodejsBackend.recipe.filter(
141
+ (p) => p.writer === "docset"
142
+ );
143
+ for (const provision of docsetProvisions) {
144
+ const config = provision.config as {
145
+ id: string;
146
+ label: string;
147
+ origin: string;
148
+ description: string;
149
+ };
150
+ expect(config.id).toBeTruthy();
151
+ expect(config.label).toBeTruthy();
152
+ expect(config.origin).toMatch(/^https:\/\//);
153
+ expect(config.description).toBeTruthy();
144
154
  }
145
155
  });
146
156
  });
@@ -167,57 +177,77 @@ describe("catalog", () => {
167
177
  expect(names).toContain("java-backend-testing");
168
178
  });
169
179
 
170
- it("java-backend option declares docsets for Spring Boot, Spring Data JPA, Spring Security, and Lombok", () => {
180
+ it("java-backend option declares docset recipe entries for Spring Boot, Spring Data JPA, Spring Security, and Lombok", () => {
171
181
  const catalog = getDefaultCatalog();
172
182
  const architecture = getFacet(catalog, "architecture")!;
173
183
  const javaBackend = getOption(architecture, "java-backend")!;
174
184
 
175
- expect(javaBackend.docsets).toBeDefined();
176
- const ids = javaBackend.docsets!.map((d) => d.id);
177
- expect(ids).toContain("spring-boot-docs");
178
- expect(ids).toContain("spring-data-jpa-docs");
179
- expect(ids).toContain("spring-security-docs");
180
- expect(ids).toContain("lombok-docs");
185
+ const docsetIds = javaBackend.recipe
186
+ .filter((p) => p.writer === "docset")
187
+ .map((p) => (p.config as { id: string }).id);
188
+ expect(docsetIds).toContain("spring-boot-docs");
189
+ expect(docsetIds).toContain("spring-data-jpa-docs");
190
+ expect(docsetIds).toContain("spring-security-docs");
191
+ expect(docsetIds).toContain("lombok-docs");
181
192
  });
182
193
 
183
- it("each java-backend docset has required fields", () => {
194
+ it("each java-backend docset recipe entry has required fields", () => {
184
195
  const catalog = getDefaultCatalog();
185
196
  const architecture = getFacet(catalog, "architecture")!;
186
197
  const javaBackend = getOption(architecture, "java-backend")!;
187
198
 
188
- for (const docset of javaBackend.docsets!) {
189
- expect(docset.id).toBeTruthy();
190
- expect(docset.label).toBeTruthy();
191
- expect(docset.origin).toMatch(/^https:\/\//);
192
- expect(docset.description).toBeTruthy();
199
+ const docsetProvisions = javaBackend.recipe.filter(
200
+ (p) => p.writer === "docset"
201
+ );
202
+ for (const provision of docsetProvisions) {
203
+ const config = provision.config as {
204
+ id: string;
205
+ label: string;
206
+ origin: string;
207
+ description: string;
208
+ };
209
+ expect(config.id).toBeTruthy();
210
+ expect(config.label).toBeTruthy();
211
+ expect(config.origin).toMatch(/^https:\/\//);
212
+ expect(config.description).toBeTruthy();
193
213
  }
194
214
  });
195
215
  });
196
216
 
197
217
  describe("architecture facet docsets", () => {
198
- it("tanstack option declares docsets for Router, Query, Form, and Table", () => {
218
+ it("tanstack option declares docset recipe entries for Router, Query, Form, and Table", () => {
199
219
  const catalog = getDefaultCatalog();
200
220
  const architecture = getFacet(catalog, "architecture")!;
201
221
  const tanstack = getOption(architecture, "tanstack")!;
202
222
 
203
- expect(tanstack.docsets).toBeDefined();
204
- const ids = tanstack.docsets!.map((d) => d.id);
205
- expect(ids).toContain("tanstack-router-docs");
206
- expect(ids).toContain("tanstack-query-docs");
207
- expect(ids).toContain("tanstack-form-docs");
208
- expect(ids).toContain("tanstack-table-docs");
223
+ const docsetIds = tanstack.recipe
224
+ .filter((p) => p.writer === "docset")
225
+ .map((p) => (p.config as { id: string }).id);
226
+ expect(docsetIds).toContain("tanstack-router-docs");
227
+ expect(docsetIds).toContain("tanstack-query-docs");
228
+ expect(docsetIds).toContain("tanstack-form-docs");
229
+ expect(docsetIds).toContain("tanstack-table-docs");
209
230
  });
210
231
 
211
- it("each docset has required fields", () => {
232
+ it("each tanstack docset recipe entry has required fields", () => {
212
233
  const catalog = getDefaultCatalog();
213
234
  const architecture = getFacet(catalog, "architecture")!;
214
235
  const tanstack = getOption(architecture, "tanstack")!;
215
236
 
216
- for (const docset of tanstack.docsets!) {
217
- expect(docset.id).toBeTruthy();
218
- expect(docset.label).toBeTruthy();
219
- expect(docset.origin).toMatch(/^https:\/\//);
220
- expect(docset.description).toBeTruthy();
237
+ const docsetProvisions = tanstack.recipe.filter(
238
+ (p) => p.writer === "docset"
239
+ );
240
+ for (const provision of docsetProvisions) {
241
+ const config = provision.config as {
242
+ id: string;
243
+ label: string;
244
+ origin: string;
245
+ description: string;
246
+ };
247
+ expect(config.id).toBeTruthy();
248
+ expect(config.label).toBeTruthy();
249
+ expect(config.origin).toMatch(/^https:\/\//);
250
+ expect(config.description).toBeTruthy();
221
251
  }
222
252
  });
223
253
  });
@@ -251,14 +281,16 @@ describe("catalog", () => {
251
281
  expect(skills[0].name).toBe("conventional-commits");
252
282
  });
253
283
 
254
- it("conventional-commits option declares the spec docset", () => {
284
+ it("conventional-commits option declares the spec docset via a recipe entry", () => {
255
285
  const catalog = getDefaultCatalog();
256
286
  const practices = getFacet(catalog, "practices")!;
257
287
  const option = getOption(practices, "conventional-commits")!;
258
288
 
259
- expect(option.docsets).toBeDefined();
260
- expect(option.docsets).toHaveLength(1);
261
- expect(option.docsets![0].id).toBe("conventional-commits-spec");
289
+ const docsetIds = option.recipe
290
+ .filter((p) => p.writer === "docset")
291
+ .map((p) => (p.config as { id: string }).id);
292
+ expect(docsetIds).toHaveLength(1);
293
+ expect(docsetIds[0]).toBe("conventional-commits-spec");
262
294
  });
263
295
 
264
296
  it("has tdd-london option with a single skill", () => {
@@ -115,32 +115,42 @@ export const architectureFacet: Facet = {
115
115
  }
116
116
  ]
117
117
  }
118
- }
119
- ],
120
- docsets: [
118
+ },
121
119
  {
122
- id: "tanstack-router-docs",
123
- label: "TanStack Router",
124
- origin: "https://github.com/TanStack/router.git",
125
- description: "File-based routing, loaders, and search params"
120
+ writer: "docset",
121
+ config: {
122
+ id: "tanstack-router-docs",
123
+ label: "TanStack Router",
124
+ origin: "https://github.com/TanStack/router.git",
125
+ description: "File-based routing, loaders, and search params"
126
+ }
126
127
  },
127
128
  {
128
- id: "tanstack-query-docs",
129
- label: "TanStack Query",
130
- origin: "https://github.com/TanStack/query.git",
131
- description: "Server state management, caching, and mutations"
129
+ writer: "docset",
130
+ config: {
131
+ id: "tanstack-query-docs",
132
+ label: "TanStack Query",
133
+ origin: "https://github.com/TanStack/query.git",
134
+ description: "Server state management, caching, and mutations"
135
+ }
132
136
  },
133
137
  {
134
- id: "tanstack-form-docs",
135
- label: "TanStack Form",
136
- origin: "https://github.com/TanStack/form.git",
137
- description: "Type-safe form state and validation"
138
+ writer: "docset",
139
+ config: {
140
+ id: "tanstack-form-docs",
141
+ label: "TanStack Form",
142
+ origin: "https://github.com/TanStack/form.git",
143
+ description: "Type-safe form state and validation"
144
+ }
138
145
  },
139
146
  {
140
- id: "tanstack-table-docs",
141
- label: "TanStack Table",
142
- origin: "https://github.com/TanStack/table.git",
143
- description: "Headless table and datagrid utilities"
147
+ writer: "docset",
148
+ config: {
149
+ id: "tanstack-table-docs",
150
+ label: "TanStack Table",
151
+ origin: "https://github.com/TanStack/table.git",
152
+ description: "Headless table and datagrid utilities"
153
+ }
144
154
  }
145
155
  ]
146
156
  },
@@ -256,32 +266,42 @@ export const architectureFacet: Facet = {
256
266
  }
257
267
  ]
258
268
  }
259
- }
260
- ],
261
- docsets: [
269
+ },
262
270
  {
263
- id: "trpc-docs",
264
- label: "tRPC",
265
- origin: "https://github.com/trpc/trpc.git",
266
- description: "End-to-end type-safe APIs, routers, and procedures"
271
+ writer: "docset",
272
+ config: {
273
+ id: "trpc-docs",
274
+ label: "tRPC",
275
+ origin: "https://github.com/trpc/trpc.git",
276
+ description: "End-to-end type-safe APIs, routers, and procedures"
277
+ }
267
278
  },
268
279
  {
269
- id: "drizzle-orm-docs",
270
- label: "Drizzle ORM",
271
- origin: "https://github.com/drizzle-team/drizzle-orm.git",
272
- description: "Type-safe SQL schema, queries, and migrations"
280
+ writer: "docset",
281
+ config: {
282
+ id: "drizzle-orm-docs",
283
+ label: "Drizzle ORM",
284
+ origin: "https://github.com/drizzle-team/drizzle-orm.git",
285
+ description: "Type-safe SQL schema, queries, and migrations"
286
+ }
273
287
  },
274
288
  {
275
- id: "express-docs",
276
- label: "Express",
277
- origin: "https://github.com/expressjs/express.git",
278
- description: "HTTP server, routing, and middleware"
289
+ writer: "docset",
290
+ config: {
291
+ id: "express-docs",
292
+ label: "Express",
293
+ origin: "https://github.com/expressjs/express.git",
294
+ description: "HTTP server, routing, and middleware"
295
+ }
279
296
  },
280
297
  {
281
- id: "zod-docs",
282
- label: "Zod",
283
- origin: "https://github.com/colinhacks/zod.git",
284
- description: "TypeScript-first schema validation"
298
+ writer: "docset",
299
+ config: {
300
+ id: "zod-docs",
301
+ label: "Zod",
302
+ origin: "https://github.com/colinhacks/zod.git",
303
+ description: "TypeScript-first schema validation"
304
+ }
285
305
  }
286
306
  ]
287
307
  },
@@ -404,33 +424,44 @@ export const architectureFacet: Facet = {
404
424
  }
405
425
  ]
406
426
  }
407
- }
408
- ],
409
- docsets: [
427
+ },
410
428
  {
411
- id: "spring-boot-docs",
412
- label: "Spring Boot",
413
- origin: "https://github.com/spring-projects/spring-boot.git",
414
- description: "Spring Boot framework, auto-configuration, and actuator"
429
+ writer: "docset",
430
+ config: {
431
+ id: "spring-boot-docs",
432
+ label: "Spring Boot",
433
+ origin: "https://github.com/spring-projects/spring-boot.git",
434
+ description:
435
+ "Spring Boot framework, auto-configuration, and actuator"
436
+ }
415
437
  },
416
438
  {
417
- id: "spring-data-jpa-docs",
418
- label: "Spring Data JPA",
419
- origin: "https://github.com/spring-projects/spring-data-jpa.git",
420
- description: "JPA repositories, derived queries, and specifications"
439
+ writer: "docset",
440
+ config: {
441
+ id: "spring-data-jpa-docs",
442
+ label: "Spring Data JPA",
443
+ origin: "https://github.com/spring-projects/spring-data-jpa.git",
444
+ description: "JPA repositories, derived queries, and specifications"
445
+ }
421
446
  },
422
447
  {
423
- id: "spring-security-docs",
424
- label: "Spring Security",
425
- origin: "https://github.com/spring-projects/spring-security.git",
426
- description: "Authentication, authorization, and security filters"
448
+ writer: "docset",
449
+ config: {
450
+ id: "spring-security-docs",
451
+ label: "Spring Security",
452
+ origin: "https://github.com/spring-projects/spring-security.git",
453
+ description: "Authentication, authorization, and security filters"
454
+ }
427
455
  },
428
456
  {
429
- id: "lombok-docs",
430
- label: "Lombok",
431
- origin: "https://github.com/projectlombok/lombok.git",
432
- description:
433
- "Boilerplate reduction with annotations for getters, builders, and constructors"
457
+ writer: "docset",
458
+ config: {
459
+ id: "lombok-docs",
460
+ label: "Lombok",
461
+ origin: "https://github.com/projectlombok/lombok.git",
462
+ description:
463
+ "Boilerplate reduction with annotations for getters, builders, and constructors"
464
+ }
434
465
  }
435
466
  ]
436
467
  }
@@ -54,15 +54,16 @@ export const practicesFacet: Facet = {
54
54
  }
55
55
  ]
56
56
  }
57
- }
58
- ],
59
- docsets: [
57
+ },
60
58
  {
61
- id: "conventional-commits-spec",
62
- label: "Conventional Commits Spec",
63
- origin:
64
- "https://github.com/conventional-commits/conventionalcommits.org.git",
65
- description: "The Conventional Commits specification"
59
+ writer: "docset",
60
+ config: {
61
+ id: "conventional-commits-spec",
62
+ label: "Conventional Commits Spec",
63
+ origin:
64
+ "https://github.com/conventional-commits/conventionalcommits.org.git",
65
+ description: "The Conventional Commits specification"
66
+ }
66
67
  }
67
68
  ]
68
69
  },
@@ -2,14 +2,14 @@ export {
2
2
  type Catalog,
3
3
  type Facet,
4
4
  type Option,
5
- type Provision,
6
- type DocsetDef
5
+ type Provision
7
6
  } from "./types.js";
8
7
  export {
9
8
  type LogicalConfig,
10
9
  type McpServerEntry,
11
10
  type CliAction,
12
11
  type KnowledgeSource,
12
+ type DocsetPreset,
13
13
  type SkillDefinition,
14
14
  type InlineSkill,
15
15
  type ExternalSkill,
@@ -39,7 +39,7 @@ export {
39
39
  getAgentWriter,
40
40
  createDefaultRegistry
41
41
  } from "./registry.js";
42
- export { resolve, collectDocsets } from "./resolver.js";
42
+ export { resolve } from "./resolver.js";
43
43
  export {
44
44
  getDefaultCatalog,
45
45
  getFacet,
@@ -50,5 +50,5 @@ export {
50
50
  } from "./catalog/index.js";
51
51
  export { type AdeExtensions, AdeExtensionsSchema } from "./types.js";
52
52
  export { skillsWriter } from "./writers/skills.js";
53
- export { knowledgeWriter } from "./writers/knowledge.js";
53
+ export { docsetWriter } from "./writers/docset.js";
54
54
  export { permissionPolicyWriter } from "./writers/permission-policy.js";
@@ -120,7 +120,7 @@ describe("registry", () => {
120
120
  const expectedIds = [
121
121
  "workflows",
122
122
  "skills",
123
- "knowledge",
123
+ "docset",
124
124
  "mcp-server",
125
125
  "instruction",
126
126
  "installable",
@@ -7,7 +7,7 @@ import { instructionWriter } from "./writers/instruction.js";
7
7
  import { workflowsWriter } from "./writers/workflows.js";
8
8
  import { mcpServerWriter } from "./writers/mcp-server.js";
9
9
  import { skillsWriter } from "./writers/skills.js";
10
- import { knowledgeWriter } from "./writers/knowledge.js";
10
+ import { docsetWriter } from "./writers/docset.js";
11
11
  import { gitHooksWriter } from "./writers/git-hooks.js";
12
12
  import { setupNoteWriter } from "./writers/setup-note.js";
13
13
  import { permissionPolicyWriter } from "./writers/permission-policy.js";
@@ -54,7 +54,7 @@ export function createDefaultRegistry(): WriterRegistry {
54
54
  registerProvisionWriter(registry, workflowsWriter);
55
55
  registerProvisionWriter(registry, mcpServerWriter);
56
56
  registerProvisionWriter(registry, skillsWriter);
57
- registerProvisionWriter(registry, knowledgeWriter);
57
+ registerProvisionWriter(registry, docsetWriter);
58
58
  registerProvisionWriter(registry, gitHooksWriter);
59
59
  registerProvisionWriter(registry, setupNoteWriter);
60
60
  registerProvisionWriter(registry, permissionPolicyWriter);