docspack 0.2.0 → 0.3.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 (65) hide show
  1. package/README.md +9 -3
  2. package/dist/build.d.ts +21 -0
  3. package/dist/build.d.ts.map +1 -1
  4. package/dist/build.js +138 -24
  5. package/dist/build.js.map +1 -1
  6. package/dist/cli.js +74 -131
  7. package/dist/cli.js.map +1 -1
  8. package/dist/config.d.ts +7 -2
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/config.js +20 -1
  11. package/dist/config.js.map +1 -1
  12. package/dist/db.d.ts +8 -4
  13. package/dist/db.d.ts.map +1 -1
  14. package/dist/db.js +13 -7
  15. package/dist/db.js.map +1 -1
  16. package/dist/doctor.js +1 -1
  17. package/dist/doctor.js.map +1 -1
  18. package/dist/eval.d.ts +52 -0
  19. package/dist/eval.d.ts.map +1 -0
  20. package/dist/eval.js +101 -0
  21. package/dist/eval.js.map +1 -0
  22. package/dist/help.d.ts +31 -0
  23. package/dist/help.d.ts.map +1 -0
  24. package/dist/help.js +342 -0
  25. package/dist/help.js.map +1 -0
  26. package/dist/index.d.ts +4 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +4 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/preview.d.ts.map +1 -1
  31. package/dist/preview.js +4 -2
  32. package/dist/preview.js.map +1 -1
  33. package/dist/search.d.ts +6 -0
  34. package/dist/search.d.ts.map +1 -1
  35. package/dist/search.js +25 -3
  36. package/dist/search.js.map +1 -1
  37. package/dist/spec.d.ts +21 -1
  38. package/dist/spec.d.ts.map +1 -1
  39. package/dist/spec.js +44 -5
  40. package/dist/spec.js.map +1 -1
  41. package/dist/stopwords.d.ts +14 -0
  42. package/dist/stopwords.d.ts.map +1 -0
  43. package/dist/stopwords.js +121 -0
  44. package/dist/stopwords.js.map +1 -0
  45. package/dist/sync.js +1 -1
  46. package/dist/sync.js.map +1 -1
  47. package/dist/verify.d.ts +8 -2
  48. package/dist/verify.d.ts.map +1 -1
  49. package/dist/verify.js +48 -15
  50. package/dist/verify.js.map +1 -1
  51. package/package.json +1 -1
  52. package/src/build.ts +178 -24
  53. package/src/cli.ts +91 -138
  54. package/src/config.ts +35 -5
  55. package/src/db.ts +13 -7
  56. package/src/doctor.ts +1 -1
  57. package/src/eval.ts +149 -0
  58. package/src/help.ts +382 -0
  59. package/src/index.ts +20 -0
  60. package/src/preview.ts +4 -1
  61. package/src/search.ts +33 -3
  62. package/src/spec.ts +66 -6
  63. package/src/stopwords.ts +120 -0
  64. package/src/sync.ts +1 -1
  65. package/src/verify.ts +69 -19
package/dist/verify.js CHANGED
@@ -4,7 +4,7 @@ import { readBuildConfig } from "./config.js";
4
4
  import { discoverPackages, resolvePackageDir } from "./discovery.js";
5
5
  import { DocspackError } from "./errors.js";
6
6
  import { readExportSurface } from "./exports.js";
7
- import { chunkId, LLMS_DIR, MANIFEST_FILE, parseManifest } from "./spec.js";
7
+ import { chunkId, formatDocumentedLibrary, LLMS_DIR, MANIFEST_FILE, parseDocumentedLibrary, parseManifest, } from "./spec.js";
8
8
  /** Below this length a name is too generic to reason about. */
9
9
  const MIN_SYMBOL = 4;
10
10
  /**
@@ -125,28 +125,39 @@ async function verifyOne(cwd, packageDir) {
125
125
  }
126
126
  async function verifyPackage(cwd, id, packageDir, manifest) {
127
127
  const empty = { id, checked: 0, matched: 0, unrecognised: 0, findings: [] };
128
- const { documents } = await readBuildConfig(packageDir);
129
- if (documents === undefined) {
128
+ const declaredLibraries = await documentedLibraries(packageDir, manifest);
129
+ if (declaredLibraries.length === 0) {
130
130
  return {
131
131
  ...empty,
132
132
  status: "skipped",
133
- reason: `declares no "docspack.documents", so there is nothing to check against`,
133
+ reason: `declares no "documents", so there is nothing to check against`,
134
134
  };
135
135
  }
136
- const libraryDir = (await resolvePackageDir(documents, packageDir)) ?? (await resolvePackageDir(documents, cwd));
137
- if (libraryDir === undefined) {
138
- return { ...empty, status: "skipped", documents, reason: `${documents} is not installed` };
136
+ const documents = declaredLibraries.map(formatDocumentedLibrary);
137
+ // An entity is fine if any documented library declares it: a monorepo documents eighteen
138
+ // packages from one surface, and a name belongs to whichever of them exports it.
139
+ const names = new Set();
140
+ const missing = [];
141
+ for (const library of declaredLibraries) {
142
+ const libraryDir = (await resolvePackageDir(library.name, packageDir)) ??
143
+ (await resolvePackageDir(library.name, cwd));
144
+ const surface = libraryDir === undefined ? undefined : await readExportSurface(libraryDir);
145
+ if (surface === undefined || surface.names.size === 0) {
146
+ missing.push(library.name);
147
+ continue;
148
+ }
149
+ for (const name of surface.names)
150
+ names.add(name);
139
151
  }
140
- const surface = await readExportSurface(libraryDir);
141
- if (surface === undefined || surface.names.size === 0) {
152
+ if (names.size === 0) {
142
153
  return {
143
154
  ...empty,
144
155
  status: "skipped",
145
156
  documents,
146
- reason: `${documents} ships no type declarations to check against`,
157
+ reason: `${missing.join(", ")} ${missing.length === 1 ? "is" : "are"} not installed, or ship no type declarations`,
147
158
  };
148
159
  }
149
- const declared = new Set([...surface.names].map(normalize));
160
+ const declared = new Set([...names].map(normalize));
150
161
  const findings = [];
151
162
  let checked = 0;
152
163
  let matched = 0;
@@ -163,7 +174,7 @@ async function verifyPackage(cwd, id, packageDir, manifest) {
163
174
  matched += 1;
164
175
  continue;
165
176
  }
166
- const suggestion = nearestName(symbol, surface);
177
+ const suggestion = nearestName(symbol, names);
167
178
  if (suggestion === undefined) {
168
179
  unrecognised += 1;
169
180
  continue;
@@ -177,7 +188,29 @@ async function verifyPackage(cwd, id, packageDir, manifest) {
177
188
  });
178
189
  }
179
190
  }
180
- return { id, status: "verified", documents, checked, matched, unrecognised, findings };
191
+ return {
192
+ id,
193
+ status: "verified",
194
+ documents,
195
+ ...(missing.length === 0 ? {} : { unchecked: missing }),
196
+ checked,
197
+ matched,
198
+ unrecognised,
199
+ findings,
200
+ };
201
+ }
202
+ /**
203
+ * What a package says it documents.
204
+ *
205
+ * The manifest is the answer when it carries one, because that is the only copy a consumer of an
206
+ * installed package can see. The `docspack` key is read as a fallback: it is build configuration
207
+ * rather than payload, and a package built before `documents` reached the manifest has only that.
208
+ */
209
+ async function documentedLibraries(packageDir, manifest) {
210
+ if (manifest.documents !== undefined && manifest.documents.length > 0)
211
+ return manifest.documents;
212
+ const { documents } = await readBuildConfig(packageDir);
213
+ return (documents ?? []).map(parseDocumentedLibrary);
181
214
  }
182
215
  /**
183
216
  * The name worth checking in an entity like `client.setKey()`, or nothing when the entity is
@@ -211,12 +244,12 @@ function normalize(name) {
211
244
  * is left alone. In particular a differing first word is never a match: `includeLanguages` and
212
245
  * `excludeLanguages` are two edits apart and mean opposite things.
213
246
  */
214
- function nearestName(symbol, surface) {
247
+ function nearestName(symbol, names) {
215
248
  const lower = normalize(symbol);
216
249
  const words = camelWords(symbol);
217
250
  let best;
218
251
  let bestDistance = Number.POSITIVE_INFINITY;
219
- for (const candidate of surface.names) {
252
+ for (const candidate of names) {
220
253
  if (candidate.length < MIN_SYMBOL)
221
254
  continue;
222
255
  const candidateWords = camelWords(candidate);
@@ -1 +1 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EACL,OAAO,EAEP,uBAAuB,EACvB,QAAQ,EACR,aAAa,EAEb,sBAAsB,EACtB,aAAa,GACd,MAAM,WAAW,CAAC;AA+CnB,+DAA+D;AAC/D,MAAM,UAAU,GAAG,CAAC,CAAC;AAErB;;;GAGG;AACH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;IACxB,SAAS;IACT,KAAK;IACL,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,SAAS;IACT,OAAO;IACP,OAAO;IACP,MAAM;IACN,WAAW;IACX,OAAO;IACP,QAAQ;IACR,SAAS;IACT,KAAK;IACL,QAAQ;IACR,SAAS;IACT,SAAS;IACT,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,UAAU;IACV,OAAO;IACP,UAAU;IACV,SAAS;CACV,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC;IACvB,OAAO;IACP,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,UAAU;IACV,IAAI;IACJ,QAAQ;IACR,YAAY;IACZ,MAAM;IACN,MAAM;IACN,MAAM;IACN,WAAW;IACX,QAAQ;IACR,QAAQ;IACR,IAAI;IACJ,MAAM;IACN,SAAS;IACT,SAAS;IACT,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,KAAK;IACL,QAAQ;CACT,CAAC,CAAC;AAEH,0FAA0F;AAC1F,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,KAAK;IACL,KAAK;IACL,MAAM;IACN,IAAI;IACJ,MAAM;IACN,OAAO;IACP,MAAM;IACN,IAAI;IACJ,KAAK;IACL,KAAK;IACL,MAAM;IACN,IAAI;IACJ,KAAK;IACL,KAAK;IACL,MAAM;IACN,KAAK;CACN,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAsB;IACxD,MAAM,QAAQ,GACZ,OAAO,CAAC,UAAU,KAAK,SAAS;QAC9B,CAAC,CAAC,MAAM,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC;QACpC,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAEzD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;AAC9E,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAW;IACxC,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,OAAO,GAAsB,EAAE,CAAC;IAEtC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,UAAkB;IACtD,IAAI,QAAyB,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9E,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,QAAQ,IAAI,aAAa,EAAE,CAAC,CAAC;IAC5E,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,aAAa,CAAC,MAAM,QAAQ,IAAI,aAAa,OAAO,UAAU,EAAE,EAAE;YAC1E,IAAI,EAAE,6BAA6B;SACpC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,aAAa,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AAC1F,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,GAAW,EACX,EAAU,EACV,UAAkB,EAClB,QAAyB;IAEzB,MAAM,KAAK,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAE5E,MAAM,iBAAiB,GAAG,MAAM,mBAAmB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC1E,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO;YACL,GAAG,KAAK;YACR,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,+DAA+D;SACxE,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACjE,yFAAyF;IACzF,iFAAiF;IACjF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;QACxC,MAAM,UAAU,GACd,CAAC,MAAM,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YACnD,CAAC,MAAM,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC3F,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO;YACL,GAAG,KAAK;YACR,MAAM,EAAE,SAAS;YACjB,SAAS;YACT,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,8CAA8C;SACnH,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpC,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;YACvC,IAAI,MAAM,KAAK,SAAS;gBAAE,SAAS;YAEnC,OAAO,IAAI,CAAC,CAAC;YACb,mFAAmF;YACnF,+CAA+C;YAC/C,IAAI,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAC,CAAC;gBACb,SAAS;YACX,CAAC;YAED,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC9C,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,YAAY,IAAI,CAAC,CAAC;gBAClB,SAAS;YACX,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC;gBACZ,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC;gBAC9B,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,MAAM;gBACN,MAAM;gBACN,UAAU;aACX,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO;QACL,EAAE;QACF,MAAM,EAAE,UAAU;QAClB,SAAS;QACT,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;QACvD,OAAO;QACP,OAAO;QACP,YAAY;QACZ,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,mBAAmB,CAChC,UAAkB,EAClB,QAAyB;IAEzB,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS,IAAI,QAAQ,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC,SAAS,CAAC;IACjG,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,eAAe,CAAC,UAAU,CAAC,CAAC;IACxD,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,MAAc;IACrC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC;IACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEzE,IAAI,MAAM,CAAC,MAAM,GAAG,UAAU;QAAE,OAAO,SAAS,CAAC;IACjD,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3D,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1D,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,wFAAwF;AACxF,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AAC/C,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,WAAW,CAAC,MAAc,EAAE,KAA0B;IAC7D,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,IAAwB,CAAC;IAC7B,IAAI,YAAY,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAE5C,KAAK,MAAM,SAAS,IAAI,KAAK,EAAE,CAAC;QAC9B,IAAI,SAAS,CAAC,MAAM,GAAG,UAAU;YAAE,SAAS;QAC5C,MAAM,cAAc,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC;YAAE,OAAO,SAAS,CAAC;QAE3D,IAAI,cAAc,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;YAAE,SAAS;QAC7C,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;QACnC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;YAAE,SAAS;QAExD,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAC/C,IAAI,QAAQ,GAAG,YAAY,EAAE,CAAC;YAC5B,YAAY,GAAG,QAAQ,CAAC;YACxB,IAAI,GAAG,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,IAAI,IAAI,KAAK,SAAS,IAAI,YAAY,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7D,8FAA8F;IAC9F,IAAI,YAAY,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,mDAAmD;AACnD,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI;SACR,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,KAAK,CAAC,UAAU,CAAC;SACjB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACjC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,CAAoB,EAAE,CAAoB;IAC/D,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxE,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5E,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,IAAI,KAAK,OAAO,CAAC,KAAK,CAAC;YAAE,KAAK,IAAI,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,KAAK,KAAK,OAAO,CAAC,MAAM,CAAC;AAClC,CAAC;AAED,8DAA8D;AAC9D,SAAS,YAAY,CAAC,CAAS,EAAE,CAAS,EAAE,KAAa;IACvD,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,KAAK;QAAE,OAAO,KAAK,GAAG,CAAC,CAAC;IAE5D,IAAI,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IACzE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EACzB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EACtB,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAC9B,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,OAAO,GAAG,KAAK;YAAE,OAAO,KAAK,GAAG,CAAC,CAAC;QACtC,QAAQ,GAAG,OAAO,CAAC;IACrB,CAAC;IACD,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;AACzC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docspack",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Local, version-locked documentation packages for AI agents, indexed in SQLite and served over MCP.",
5
5
  "keywords": [
6
6
  "ai",
package/src/build.ts CHANGED
@@ -11,11 +11,14 @@ import { fetchableLinks, parseLlmsTxt } from "./llms-txt.js";
11
11
  import {
12
12
  CHUNKS_DIR,
13
13
  type ChunkSpec,
14
+ type DocumentedLibrary,
14
15
  estimateTokens,
15
16
  LLMS_DIR,
16
17
  MANIFEST_FILE,
18
+ parseDocumentedLibrary,
17
19
  serializeManifest,
18
20
  } from "./spec.js";
21
+ import { STOPWORDS } from "./stopwords.js";
19
22
 
20
23
  export interface BuildOptions {
21
24
  /** Directory the docs package is written to. */
@@ -30,6 +33,14 @@ export interface BuildOptions {
30
33
  readonly source?: string;
31
34
  readonly pages?: number;
32
35
  readonly maxChunkTokens?: number;
36
+ /**
37
+ * Merge adjacent sections until a chunk reaches this size, never crossing `maxChunkTokens`.
38
+ * Off unless set: splitting at every heading is right for prose, and wrong only for generated
39
+ * reference, where a heading is a field name.
40
+ */
41
+ readonly minChunkTokens?: number;
42
+ /** Libraries this package documents, each `name` or `name@version`. Recorded in the manifest. */
43
+ readonly documents?: readonly string[];
33
44
  readonly http?: HttpClient;
34
45
  readonly onProgress?: (message: string) => void;
35
46
  }
@@ -76,7 +87,14 @@ export async function buildPackage(input: BuildOptions): Promise<BuildResult> {
76
87
  }
77
88
 
78
89
  const maxTokens = options.maxChunkTokens ?? DEFAULT_MAX_CHUNK_TOKENS;
79
- const { chunks, files } = chunkDocuments(documents, maxTokens);
90
+ const minTokens = options.minChunkTokens;
91
+ if (minTokens !== undefined && minTokens > maxTokens) {
92
+ throw new DocspackError(
93
+ `minChunkTokens (${minTokens}) is larger than maxChunkTokens (${maxTokens})`,
94
+ { hint: "A chunk cannot be required to be bigger than it is allowed to be." },
95
+ );
96
+ }
97
+ const { chunks, files } = chunkDocuments(documents, maxTokens, minTokens);
80
98
 
81
99
  const llmsDir = join(options.out, LLMS_DIR);
82
100
  await rm(llmsDir, { recursive: true, force: true });
@@ -85,9 +103,15 @@ export async function buildPackage(input: BuildOptions): Promise<BuildResult> {
85
103
  for (const file of files) {
86
104
  await writeFile(join(llmsDir, file.path), file.contents, "utf8");
87
105
  }
106
+ const libraries: DocumentedLibrary[] = (options.documents ?? []).map(parseDocumentedLibrary);
88
107
  await writeFile(
89
108
  join(llmsDir, MANIFEST_FILE),
90
- serializeManifest({ name: identity.name, version: identity.version, chunks }),
109
+ serializeManifest({
110
+ name: identity.name,
111
+ version: identity.version,
112
+ ...(libraries.length === 0 ? {} : { documents: libraries }),
113
+ chunks,
114
+ }),
91
115
  "utf8",
92
116
  );
93
117
  await writeFile(join(options.out, "llms.txt"), renderLlmsTxt(identity.name, chunks), "utf8");
@@ -114,7 +138,7 @@ export async function buildPackage(input: BuildOptions): Promise<BuildResult> {
114
138
  version: identity.version,
115
139
  dir: options.out,
116
140
  chunks: chunks.length,
117
- tokens: chunks.reduce((total, chunk) => total + chunk.tokens, 0),
141
+ tokens: chunks.reduce((total, chunk) => total + (chunk.tokens ?? 0), 0),
118
142
  warnings,
119
143
  };
120
144
  }
@@ -142,6 +166,12 @@ async function withConfig(options: BuildOptions): Promise<BuildOptions> {
142
166
  ...(options.maxChunkTokens === undefined && config.maxChunkTokens !== undefined
143
167
  ? { maxChunkTokens: config.maxChunkTokens }
144
168
  : {}),
169
+ ...(options.minChunkTokens === undefined && config.minChunkTokens !== undefined
170
+ ? { minChunkTokens: config.minChunkTokens }
171
+ : {}),
172
+ ...(options.documents === undefined && config.documents !== undefined
173
+ ? { documents: config.documents }
174
+ : {}),
145
175
  ...(options.pages === undefined && config.pages !== undefined ? { pages: config.pages } : {}),
146
176
  };
147
177
  }
@@ -396,16 +426,18 @@ function renderOperation(
396
426
  function chunkDocuments(
397
427
  documents: readonly SourceDocument[],
398
428
  maxTokens: number,
429
+ minTokens: number | undefined,
399
430
  ): { chunks: ChunkSpec[]; files: { path: string; contents: string }[] } {
400
431
  const chunks: ChunkSpec[] = [];
401
432
  const files: { path: string; contents: string }[] = [];
402
433
  const taken = new Set<string>();
403
434
 
404
435
  for (const document of documents) {
436
+ const text = collapseTablePadding(document.text);
405
437
  const sections =
406
438
  document.atomic === true
407
- ? [{ heading: document.title, body: document.text }]
408
- : splitMarkdown(document.text, document.title, maxTokens);
439
+ ? [{ heading: document.title, body: text, level: 0 }]
440
+ : splitMarkdown(text, document.title, maxTokens, minTokens);
409
441
 
410
442
  for (const section of sections) {
411
443
  const directives = readDirectives(section.body);
@@ -419,11 +451,9 @@ function chunkDocuments(
419
451
  id,
420
452
  file,
421
453
  tokens: estimateTokens(contents),
422
- // Directive tags first: they are the author aiming one chunk, and `uniqueWords` caps.
423
- tags: uniqueWords([
424
- ...directives.tags,
454
+ tags: chunkTags(directives.tags, [
425
455
  document.title,
426
- section.heading,
456
+ ...(section.headings ?? [section.heading]),
427
457
  ...(document.tags ?? []),
428
458
  ]),
429
459
  entities: [
@@ -440,17 +470,35 @@ function chunkDocuments(
440
470
  return { chunks, files };
441
471
  }
442
472
 
473
+ /** One piece of a document, before it becomes a chunk. */
474
+ interface Section {
475
+ readonly heading: string;
476
+ readonly body: string;
477
+ /** Depth of the heading in the source, or 0 when it was inherited rather than written. */
478
+ readonly level: number;
479
+ /**
480
+ * Headings to index as tags, when they are not just `heading`. A packed chunk answers for every
481
+ * section in it, so all of their headings are search terms for it.
482
+ */
483
+ readonly headings?: readonly string[];
484
+ }
485
+
443
486
  /**
444
487
  * Splits Markdown at `##` headings, then `###`, then paragraphs, until every piece fits the token
445
488
  * budget. Retrieval works best when a chunk answers one question.
489
+ *
490
+ * With `minTokens` set, adjacent pieces are then packed back together up to the budget. Every
491
+ * API generator emits pages whose headings are field names — `Category` is one line, `Sizes` is
492
+ * three — and one chunk per heading there is hundreds of chunks too small to answer anything.
446
493
  */
447
494
  function splitMarkdown(
448
495
  text: string,
449
496
  title: string,
450
497
  maxTokens: number,
451
- ): { heading: string; body: string }[] {
452
- const sections = splitAtLevel(text, 2, title);
453
- const result: { heading: string; body: string }[] = [];
498
+ minTokens: number | undefined,
499
+ ): Section[] {
500
+ const sections = splitAtLevel(text, 2, title, 0);
501
+ const result: Section[] = [];
454
502
 
455
503
  for (const section of sections) {
456
504
  if (estimateTokens(section.body) <= maxTokens) {
@@ -458,7 +506,7 @@ function splitMarkdown(
458
506
  continue;
459
507
  }
460
508
 
461
- const deeper = splitAtLevel(section.body, 3, section.heading);
509
+ const deeper = splitAtLevel(section.body, 3, section.heading, section.level);
462
510
  for (const part of deeper) {
463
511
  if (estimateTokens(part.body) <= maxTokens) {
464
512
  if (part.body.trim().length > 0) result.push(part);
@@ -468,22 +516,26 @@ function splitMarkdown(
468
516
  ...splitParagraphs(part.body, maxTokens).map((body, index) => ({
469
517
  heading: index === 0 ? part.heading : `${part.heading} (${index + 1})`,
470
518
  body,
519
+ // A continuation carries no heading of its own, so packing must not re-emit one.
520
+ level: index === 0 ? part.level : 0,
471
521
  })),
472
522
  );
473
523
  }
474
524
  }
475
525
 
476
- return result.length > 0 ? result : [{ heading: title, body: text }];
526
+ const pieces = result.length > 0 ? result : [{ heading: title, body: text, level: 0 }];
527
+ return minTokens === undefined ? pieces : packSections(pieces, title, minTokens, maxTokens);
477
528
  }
478
529
 
479
530
  function splitAtLevel(
480
531
  text: string,
481
532
  level: number,
482
533
  fallbackHeading: string,
483
- ): { heading: string; body: string }[] {
534
+ fallbackLevel: number,
535
+ ): Section[] {
484
536
  const marker = new RegExp(`^#{${level}}\\s+(.+?)\\s*$`);
485
- const sections: { heading: string; body: string[] }[] = [];
486
- let current = { heading: fallbackHeading, body: [] as string[] };
537
+ const sections: { heading: string; body: string[]; level: number }[] = [];
538
+ let current = { heading: fallbackHeading, body: [] as string[], level: fallbackLevel };
487
539
  let inFence = false;
488
540
 
489
541
  for (const line of text.split("\n")) {
@@ -492,7 +544,7 @@ function splitAtLevel(
492
544
  const match = inFence ? null : marker.exec(line);
493
545
  if (match?.[1] !== undefined) {
494
546
  if (current.body.join("\n").trim().length > 0) sections.push(current);
495
- current = { heading: match[1], body: [] };
547
+ current = { heading: match[1], body: [], level };
496
548
  continue;
497
549
  }
498
550
  current.body.push(line);
@@ -501,10 +553,57 @@ function splitAtLevel(
501
553
 
502
554
  return sections.map((section) => ({
503
555
  heading: section.heading,
556
+ level: section.level,
504
557
  body: section.body.join("\n").trim(),
505
558
  }));
506
559
  }
507
560
 
561
+ /**
562
+ * Merges adjacent sections until a group reaches `minTokens`, never crossing `maxTokens`. A
563
+ * merged group is headed by the document title and keeps each section's own heading inside it,
564
+ * so a whole component lands in one chunk without losing the structure a reader needs.
565
+ */
566
+ function packSections(
567
+ sections: readonly Section[],
568
+ title: string,
569
+ minTokens: number,
570
+ maxTokens: number,
571
+ ): Section[] {
572
+ const packed: Section[] = [];
573
+ let group: Section[] = [];
574
+ let tokens = 0;
575
+
576
+ const flush = (): void => {
577
+ if (group.length === 1 && group[0] !== undefined) packed.push(group[0]);
578
+ else if (group.length > 1) {
579
+ packed.push({
580
+ heading: title,
581
+ level: 0,
582
+ body: group.map(withHeading).join("\n\n"),
583
+ headings: group.map((section) => section.heading),
584
+ });
585
+ }
586
+ group = [];
587
+ tokens = 0;
588
+ };
589
+
590
+ for (const section of sections) {
591
+ const size = estimateTokens(withHeading(section));
592
+ if (group.length > 0 && (tokens >= minTokens || tokens + size > maxTokens)) flush();
593
+ group.push(section);
594
+ tokens += size;
595
+ }
596
+ flush();
597
+
598
+ return packed;
599
+ }
600
+
601
+ /** A section as it appeared in the source, heading included when it had one. */
602
+ function withHeading(section: Section): string {
603
+ if (section.level === 0) return section.body;
604
+ return `${"#".repeat(section.level)} ${section.heading}\n\n${section.body}`;
605
+ }
606
+
508
607
  function splitParagraphs(text: string, maxTokens: number): string[] {
509
608
  const parts: string[] = [];
510
609
  let buffer: string[] = [];
@@ -620,14 +719,69 @@ function slugify(input: string, fallback: string): string {
620
719
  return slug.length > 0 ? slug : fallback;
621
720
  }
622
721
 
623
- function uniqueWords(inputs: readonly string[]): string[] {
624
- const words = new Set<string>();
722
+ const MAX_TAGS = 24;
723
+
724
+ /**
725
+ * The words indexed alongside a chunk.
726
+ *
727
+ * Directive tags are taken as the author wrote them — those are deliberate, and one of them
728
+ * being a function word is the author's decision. Words lifted out of a title or a heading are
729
+ * filtered: nobody chose them as search terms, and the tag field is weighted 3× in the ranking,
730
+ * which is what made "How to use it" the answer to every question beginning "how do I".
731
+ */
732
+ function chunkTags(authored: readonly string[], derived: readonly string[]): string[] {
733
+ const tags = new Set(words(authored));
734
+ for (const word of words(derived)) {
735
+ if (!STOPWORDS.has(word)) tags.add(word);
736
+ }
737
+ return [...tags].slice(0, MAX_TAGS);
738
+ }
739
+
740
+ function words(inputs: readonly string[]): string[] {
741
+ const found: string[] = [];
625
742
  for (const input of inputs) {
626
- for (const word of input.toLowerCase().match(/[\p{L}\p{N}]{2,}/gu) ?? []) {
627
- words.add(word);
628
- }
743
+ found.push(...(input.toLowerCase().match(/[\p{L}\p{N}]{2,}/gu) ?? []));
629
744
  }
630
- return [...words].slice(0, 24);
745
+ return found;
746
+ }
747
+
748
+ /** A row of a Markdown table: `| Name | Type |`, and the `|---|---:|` rule under it. */
749
+ const TABLE_ROW = /^\|.*\|/;
750
+ const TABLE_RULE = /^[|\-: \t]+$/;
751
+
752
+ /**
753
+ * Collapses the alignment padding out of Markdown tables.
754
+ *
755
+ * Every API generator pads table cells into columns. That padding is whitespace to a reader and
756
+ * to a renderer, but tokens are estimated from characters, so a generated props table is
757
+ * measured at several times its real weight — which spends the response budget, trips
758
+ * `chunk-too-large`, and forces splits that leave fragments competing for the same query. One
759
+ * chart's props table measured 4,094 tokens padded and 1,245 collapsed.
760
+ *
761
+ * Runs inside a code fence are left alone; a fenced table is example text, and its alignment is
762
+ * the thing being shown.
763
+ */
764
+ export function collapseTablePadding(text: string): string {
765
+ let inFence = false;
766
+
767
+ return text
768
+ .split("\n")
769
+ .map((line) => {
770
+ if (/^\s*(?:```|~~~)/.test(line)) {
771
+ inFence = !inFence;
772
+ return line;
773
+ }
774
+ if (inFence) return line;
775
+
776
+ const indent = /^[ \t]*/.exec(line)?.[0] ?? "";
777
+ const rest = line.slice(indent.length);
778
+ // Four spaces or more is an indented code block, whatever the line looks like.
779
+ if (indent.length >= 4 || !TABLE_ROW.test(rest)) return line;
780
+
781
+ const collapsed = rest.replace(/[ \t]{2,}/g, " ");
782
+ return indent + (TABLE_RULE.test(rest) ? collapsed.replace(/-{4,}/g, "---") : collapsed);
783
+ })
784
+ .join("\n");
631
785
  }
632
786
 
633
787
  function uniqueId(base: string, taken: Set<string>): string {