@glossic/core 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.
package/dist/index.d.ts CHANGED
@@ -160,16 +160,44 @@ declare const backoffDelay: (attempt: number, baseDelayMs: number) => number;
160
160
  /** Runs a task again while it fails with a retryable provider error. */
161
161
  declare const withRetry: <T>(task: () => Promise<T>, options?: RetryOptions) => Promise<T>;
162
162
 
163
+ /**
164
+ * `projects` narrows a run to the units of those projects, and `reviewPlan`
165
+ * lets a caller narrow it after seeing what the plan costs -- both exist so a
166
+ * workspace too big for one run can be done a project at a time.
167
+ */
163
168
  interface GenerateContext extends PipelineContext {
164
169
  outDir: string;
165
170
  provider?: Provider;
166
171
  dryRun?: boolean;
167
172
  force?: boolean;
168
173
  only?: string;
174
+ projects?: readonly string[];
169
175
  cachePath?: string;
170
176
  retry?: RetryOptions;
171
177
  onEvent?: (event: GenerateEvent) => void;
178
+ reviewPlan?: PlanReviewer;
179
+ }
180
+ /** What one project would cost this run, for a caller deciding what to send. */
181
+ interface PlanProject {
182
+ id: string;
183
+ name: string;
184
+ pending: number;
185
+ cached: number;
186
+ estimatedTokens: number;
172
187
  }
188
+ /** The whole plan, in the shape a caller needs to warn about it or split it. */
189
+ interface PlanReview {
190
+ pending: number;
191
+ cached: number;
192
+ estimatedTokens: number;
193
+ projects: PlanProject[];
194
+ }
195
+ /**
196
+ * Called once with the plan and before any completion is sent, and answers
197
+ * with the projects to generate: undefined for all of them, an empty list for
198
+ * none. It is never called for a dry run, which sends nothing anyway.
199
+ */
200
+ type PlanReviewer = (review: PlanReview) => Promise<readonly string[] | undefined>;
173
201
  type UnitOutcome = "generated" | "cached" | "failed";
174
202
  type GenerateEvent = {
175
203
  type: "unit-start";
@@ -193,9 +221,15 @@ interface GeneratePlanEntry {
193
221
  reason: GenerateReason;
194
222
  regenerate: boolean;
195
223
  }
224
+ /**
225
+ * A page that was written, but not exactly as the provider wrote it. It carries
226
+ * the numbers rather than a sentence, because the sentence has to be spelled
227
+ * and pluralised in whatever language the CLI is speaking.
228
+ */
196
229
  interface GenerateWarning {
197
230
  unitId: string;
198
- message: string;
231
+ dropped: number;
232
+ excerpt: string;
199
233
  }
200
234
  interface GenerateFailure {
201
235
  unitId: string;
@@ -203,6 +237,16 @@ interface GenerateFailure {
203
237
  code: string | undefined;
204
238
  detail: string | undefined;
205
239
  }
240
+ /**
241
+ * Why a run gave up on the rest of its plan, and how many units it never
242
+ * reached. `unitId` is the one that hit the wall, and it is in `failures` too.
243
+ */
244
+ interface GenerateAbort {
245
+ unitId: string;
246
+ code: string;
247
+ reason: string;
248
+ remaining: number;
249
+ }
206
250
  interface GenerateResult {
207
251
  manifest: Manifest;
208
252
  written: string[];
@@ -210,6 +254,8 @@ interface GenerateResult {
210
254
  failures: GenerateFailure[];
211
255
  warnings: GenerateWarning[];
212
256
  filteredOut: string[];
257
+ skipped: string[];
258
+ aborted: GenerateAbort | undefined;
213
259
  estimatedTokens: number;
214
260
  savedTokens: number;
215
261
  generated: number;
@@ -367,4 +413,4 @@ declare const resolveWorkspace: (root: string) => Promise<Workspace>;
367
413
 
368
414
  declare const CORE_VERSION: string;
369
415
 
370
- export { type AdapterRegistry, type BuildManifestOptions, type BuildPromptInput, CACHE_VERSION, CONFIG_FILENAMES, CORE_VERSION, type CacheEntry, CacheEntrySchema, type CacheFile, CacheFileSchema, type CheckContext, type CheckEntry, type CheckResult, type ConfigOrigin, type ConfigOrigins, type ConfigSources, type ContentProblem, DEFAULT_CACHE_PATH, DEFAULT_MANIFEST_PATH, type FailedConfig, type FakeProvider, type FakeProviderOptions, GROUPING_KEYS, type GenerateContext, type GenerateEvent, type GenerateFailure, type GeneratePlanEntry, type GenerateReason, type GenerateResult, type GenerateWarning, INDEX_DOC_PATH, type LoadedConfig, MAX_FILE_BYTES, MAX_PREAMBLE_LENGTH, MIN_DOCUMENT_LENGTH, type MissingConfig, NoProviderAvailableError, type NormalizedDocument, NotImplementedError, PROMPT_VERSION, PROVIDER_PREFERENCE, type PipelineContext, type PreparedDocument, type ProjectConfig, type ProviderRegistry, type ProviderStatus, Registry, type RenderIndexDocInput, type RenderUnitDocInput, type ResolveProviderOptions, type ResolvedConfig, type RetryOptions, SYSTEM_PROMPT, type ScanResult, type UnitOutcome, type UnitSource, UnknownProviderError, assertDocumentContent, backoffDelay, buildManifest, buildUnitPrompt, check, createAdapterRegistry, createFakeProvider, createProviderRegistry, emptyCache, estimateTokens, excerpt, findConfigFile, findContentProblem, generate, indexCache, loadProjectConfig, modelCacheKey, normalizeDocument, orderAdapters, pathExists, prepareDocument, probeProviders, readCache, readDocFrontmatter, readJson, readManifest, readText, readUnitSources, renderIndexDoc, renderUnitDoc, resolveConfig, resolveProvider, resolveWorkspace, scan, serializeCache, serializeManifest, unitDocPath, withRetry, writeCache, writeManifest };
416
+ export { type AdapterRegistry, type BuildManifestOptions, type BuildPromptInput, CACHE_VERSION, CONFIG_FILENAMES, CORE_VERSION, type CacheEntry, CacheEntrySchema, type CacheFile, CacheFileSchema, type CheckContext, type CheckEntry, type CheckResult, type ConfigOrigin, type ConfigOrigins, type ConfigSources, type ContentProblem, DEFAULT_CACHE_PATH, DEFAULT_MANIFEST_PATH, type FailedConfig, type FakeProvider, type FakeProviderOptions, GROUPING_KEYS, type GenerateAbort, type GenerateContext, type GenerateEvent, type GenerateFailure, type GeneratePlanEntry, type GenerateReason, type GenerateResult, type GenerateWarning, INDEX_DOC_PATH, type LoadedConfig, MAX_FILE_BYTES, MAX_PREAMBLE_LENGTH, MIN_DOCUMENT_LENGTH, type MissingConfig, NoProviderAvailableError, type NormalizedDocument, NotImplementedError, PROMPT_VERSION, PROVIDER_PREFERENCE, type PipelineContext, type PlanProject, type PlanReview, type PlanReviewer, type PreparedDocument, type ProjectConfig, type ProviderRegistry, type ProviderStatus, Registry, type RenderIndexDocInput, type RenderUnitDocInput, type ResolveProviderOptions, type ResolvedConfig, type RetryOptions, SYSTEM_PROMPT, type ScanResult, type UnitOutcome, type UnitSource, UnknownProviderError, assertDocumentContent, backoffDelay, buildManifest, buildUnitPrompt, check, createAdapterRegistry, createFakeProvider, createProviderRegistry, emptyCache, estimateTokens, excerpt, findConfigFile, findContentProblem, generate, indexCache, loadProjectConfig, modelCacheKey, normalizeDocument, orderAdapters, pathExists, prepareDocument, probeProviders, readCache, readDocFrontmatter, readJson, readManifest, readText, readUnitSources, renderIndexDoc, renderUnitDoc, resolveConfig, resolveProvider, resolveWorkspace, scan, serializeCache, serializeManifest, unitDocPath, withRetry, writeCache, writeManifest };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import fs2 from 'fs/promises';
2
2
  import path3 from 'path';
3
3
  import { z } from 'zod';
4
- import { sortBy, ManifestSchema, MANIFEST_VERSION, toPosix, GlossicConfigSchema, compareStrings, isRetryableProviderError, ProviderError } from '@glossic/schema';
4
+ import { sortBy, ManifestSchema, MANIFEST_VERSION, toPosix, GlossicConfigSchema, compareStrings, isRetryableProviderError, ProviderError, isFatalProviderError } from '@glossic/schema';
5
5
  export { compareStrings, joinPosix, relativePosix, sortBy, toPosix } from '@glossic/schema';
6
6
  import { glob } from 'tinyglobby';
7
7
  import { parse } from 'yaml';
@@ -10,7 +10,7 @@ import picomatch from 'picomatch';
10
10
 
11
11
  // package.json
12
12
  var package_default = {
13
- version: "0.2.0"};
13
+ version: "0.3.0"};
14
14
  var pathExists = async (target) => {
15
15
  try {
16
16
  await fs2.access(target);
@@ -879,6 +879,24 @@ var docsDirOf = (root, outDir) => {
879
879
  const relative = toPosix(path3.relative(root, outDir));
880
880
  return relative === "" ? "." : relative;
881
881
  };
882
+ var reviewOf = (decisions, manifest) => {
883
+ const projects = manifest.workspace.projects.map((project) => {
884
+ const own = decisions.filter(({ job }) => job.unit.projectId === project.id);
885
+ return {
886
+ id: project.id,
887
+ name: project.name,
888
+ pending: own.filter(({ reason }) => reason !== "cached").length,
889
+ cached: own.filter(({ reason }) => reason === "cached").length,
890
+ estimatedTokens: own.filter(({ reason }) => reason !== "cached").reduce((sum, { job }) => sum + job.estimatedTokens, 0)
891
+ };
892
+ }).filter((project) => project.pending + project.cached > 0);
893
+ return {
894
+ pending: projects.reduce((sum, project) => sum + project.pending, 0),
895
+ cached: projects.reduce((sum, project) => sum + project.cached, 0),
896
+ estimatedTokens: projects.reduce((sum, project) => sum + project.estimatedTokens, 0),
897
+ projects
898
+ };
899
+ };
882
900
  var stringField = (cause, field) => {
883
901
  if (typeof cause !== "object" || cause === null || !(field in cause)) {
884
902
  return void 0;
@@ -913,50 +931,69 @@ var generate = async (ctx) => {
913
931
  reason: await decide(job, previousEntries.get(job.unit.id), decisionContext)
914
932
  }))
915
933
  );
916
- const plan = decisions.map(({ job, reason }) => ({
917
- unitId: job.unit.id,
918
- docPath: job.docPath,
919
- files: job.unit.facts.base.files.length,
920
- estimatedTokens: job.estimatedTokens,
921
- reason,
922
- regenerate: reason !== "cached"
923
- })).sort((a, b) => compareStrings(a.unitId, b.unitId));
924
- const sumTokens = (regenerate) => plan.filter((entry) => entry.regenerate === regenerate).reduce((sum, entry) => sum + entry.estimatedTokens, 0);
925
- const estimatedTokens = sumTokens(true);
926
- const savedTokens = sumTokens(false);
927
- const fromCache = plan.filter((entry) => !entry.regenerate).length;
934
+ const summarise = (entries) => {
935
+ const plan2 = entries.map(({ job, reason }) => ({
936
+ unitId: job.unit.id,
937
+ docPath: job.docPath,
938
+ files: job.unit.facts.base.files.length,
939
+ estimatedTokens: job.estimatedTokens,
940
+ reason,
941
+ regenerate: reason !== "cached"
942
+ })).sort((a, b) => compareStrings(a.unitId, b.unitId));
943
+ const sumTokens = (regenerate) => plan2.filter((entry) => entry.regenerate === regenerate).reduce((sum, entry) => sum + entry.estimatedTokens, 0);
944
+ return {
945
+ plan: plan2,
946
+ estimatedTokens: sumTokens(true),
947
+ savedTokens: sumTokens(false),
948
+ fromCache: plan2.filter((entry) => !entry.regenerate).length
949
+ };
950
+ };
928
951
  if (ctx.dryRun === true || ctx.provider === void 0) {
952
+ const whole = summarise(decisions);
929
953
  return {
930
954
  manifest,
931
955
  written: [],
932
- plan,
956
+ plan: whole.plan,
933
957
  failures: [],
934
958
  warnings: [],
935
959
  filteredOut,
936
- estimatedTokens,
937
- savedTokens,
960
+ skipped: [],
961
+ aborted: void 0,
962
+ estimatedTokens: whole.estimatedTokens,
963
+ savedTokens: whole.savedTokens,
938
964
  generated: 0,
939
- fromCache,
965
+ fromCache: whole.fromCache,
940
966
  dryRun: true
941
967
  };
942
968
  }
969
+ const requested = ctx.reviewPlan === void 0 ? ctx.projects : await ctx.reviewPlan(reviewOf(decisions, manifest)) ?? ctx.projects;
970
+ const inScope = requested === void 0 ? decisions : decisions.filter(({ job }) => requested.includes(job.unit.projectId));
971
+ const outOfScope = requested === void 0 ? [] : decisions.filter(({ job }) => !requested.includes(job.unit.projectId)).map(({ job }) => job.unit.id);
972
+ const { plan, estimatedTokens, savedTokens, fromCache } = summarise(inScope);
973
+ const scopedFilteredOut = [...filteredOut, ...outOfScope].sort(compareStrings);
943
974
  const provider = ctx.provider;
944
975
  const failures = [];
945
976
  const warnings = [];
946
977
  const summaries = /* @__PURE__ */ new Map();
947
- const pending = decisions.filter(({ reason }) => reason !== "cached");
948
- const total = decisions.length;
978
+ const pending = inScope.filter(({ reason }) => reason !== "cached");
979
+ const skipped = [];
980
+ let aborted;
981
+ const total = inScope.length;
949
982
  let completed = 0;
950
983
  const report = (event) => ctx.onEvent?.(event);
951
984
  const finished = (unitId, outcome, durationMs) => {
952
985
  completed += 1;
953
986
  report({ type: "unit-done", unitId, index: completed, total, outcome, durationMs });
954
987
  };
955
- for (const { job } of decisions.filter(({ reason }) => reason === "cached")) {
988
+ for (const { job } of inScope.filter(({ reason }) => reason === "cached")) {
956
989
  report({ type: "unit-start", unitId: job.unit.id, index: completed + 1, total });
957
990
  finished(job.unit.id, "cached", 0);
958
991
  }
959
992
  const outcomes = await mapWithConcurrency(pending, config.concurrency, async ({ job }) => {
993
+ if (aborted !== void 0) {
994
+ skipped.push(job.unit.id);
995
+ return void 0;
996
+ }
960
997
  const startedAt = Date.now();
961
998
  report({ type: "unit-start", unitId: job.unit.id, index: completed + 1, total });
962
999
  try {
@@ -965,22 +1002,35 @@ var generate = async (ctx) => {
965
1002
  if (prepared.droppedPreamble !== void 0) {
966
1003
  warnings.push({
967
1004
  unitId: job.unit.id,
968
- message: `dropped ${prepared.droppedPreamble.length} characters before the first heading: ${excerpt(prepared.droppedPreamble, 120)}`
1005
+ dropped: prepared.droppedPreamble.length,
1006
+ excerpt: excerpt(prepared.droppedPreamble, 120)
969
1007
  });
970
1008
  }
971
1009
  finished(job.unit.id, "generated", Date.now() - startedAt);
972
1010
  return { job, body: prepared.body };
973
1011
  } catch (cause) {
974
- failures.push({
1012
+ const failure = {
975
1013
  unitId: job.unit.id,
976
1014
  reason: cause instanceof Error ? cause.message : String(cause),
977
1015
  code: stringField(cause, "code"),
978
1016
  detail: stringField(cause, "detail")
979
- });
1017
+ };
1018
+ failures.push(failure);
1019
+ if (aborted === void 0 && isFatalProviderError(cause)) {
1020
+ aborted = {
1021
+ unitId: failure.unitId,
1022
+ code: failure.code ?? "unknown",
1023
+ reason: failure.reason,
1024
+ remaining: 0
1025
+ };
1026
+ }
980
1027
  finished(job.unit.id, "failed", Date.now() - startedAt);
981
1028
  return void 0;
982
1029
  }
983
1030
  });
1031
+ if (aborted !== void 0) {
1032
+ aborted = { ...aborted, remaining: skipped.length };
1033
+ }
984
1034
  const written = [];
985
1035
  const fresh = [];
986
1036
  for (const outcome of outcomes) {
@@ -1029,7 +1079,9 @@ var generate = async (ctx) => {
1029
1079
  plan,
1030
1080
  failures: failures.sort((a, b) => compareStrings(a.unitId, b.unitId)),
1031
1081
  warnings: warnings.sort((a, b) => compareStrings(a.unitId, b.unitId)),
1032
- filteredOut,
1082
+ filteredOut: scopedFilteredOut,
1083
+ skipped: skipped.sort(compareStrings),
1084
+ aborted,
1033
1085
  estimatedTokens,
1034
1086
  savedTokens,
1035
1087
  generated: fresh.length,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/utils/fs.ts","../src/cache.ts","../src/manifest.ts","../src/workspace.ts","../src/scan.ts","../src/markdown.ts","../src/check.ts","../src/config-file.ts","../src/config-resolve.ts","../src/errors.ts","../src/retry.ts","../src/prompt.ts","../src/utils/concurrency.ts","../src/generate/jobs.ts","../src/generate/decide.ts","../src/validate.ts","../src/generate/index.ts","../src/provider.ts","../src/registry.ts","../src/testing.ts","../src/index.ts"],"names":["fs","path","parseYaml","glob","GlossicConfigSchema","fence"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"name\": \"@glossic/core\",\n \"version\": \"0.2.0\",\n \"description\": \"Glossic orchestration core: registries, pipeline and manifest plumbing\",\n \"keywords\": [\n \"documentation\",\n \"docs\",\n \"docs-as-code\",\n \"glossic\",\n \"orchestration\",\n \"pipeline\",\n \"manifest\",\n \"incremental\",\n \"cache\"\n ],\n \"license\": \"MIT\",\n \"author\": \"Rody Huancas\",\n \"homepage\": \"https://github.com/rody-huancas/glossic#readme\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rody-huancas/glossic.git\",\n \"directory\": \"packages/core\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/rody-huancas/glossic/issues\"\n },\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=20\"\n },\n \"files\": [\n \"dist\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@glossic/schema\": \"workspace:*\",\n \"jiti\": \"^2.6.1\",\n \"picomatch\": \"^4.0.3\",\n \"tinyglobby\": \"^0.2.15\",\n \"yaml\": \"^2.8.1\",\n \"zod\": \"^4.1.5\"\n }\n}\n","import fs from \"node:fs/promises\";\n\n/** True when the path can be reached; never throws. */\nexport const pathExists = async (target: string): Promise<boolean> => {\n try {\n await fs.access(target);\n return true;\n } catch {\n return false;\n }\n};\n\n/** File contents, or undefined when it cannot be read. */\nexport const readText = async (target: string): Promise<string | undefined> => {\n try {\n return await fs.readFile(target, \"utf8\");\n } catch {\n return undefined;\n }\n};\n\n/** Parsed JSON, or undefined when the file is missing or malformed. */\nexport const readJson = async <T>(target: string): Promise<T | undefined> => {\n const raw = await readText(target);\n \n if (raw === undefined) {\n return undefined;\n }\n\n try {\n return JSON.parse(raw) as T;\n } catch {\n return undefined;\n }\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport { sortBy } from \"./utils/index.js\";\n\nexport const DEFAULT_CACHE_PATH = \".glossic/cache.json\";\n/** Bumped by hand when the entry shape changes; a mismatch discards the whole file. */\nexport const CACHE_VERSION = \"1\";\n\n/** What a unit was documented from, so the next run can tell whether anything moved. */\nexport const CacheEntrySchema = z.object({\n unitId : z.string().min(1),\n unitHash : z.string().min(1),\n promptVersion: z.string().min(1),\n model : z.string().min(1),\n lang : z.string().min(1),\n outputPath : z.string().min(1),\n generatedAt : z.string().min(1),\n});\nexport type CacheEntry = z.infer<typeof CacheEntrySchema>;\n\nexport const CacheFileSchema = z.object({\n version: z.string().min(1),\n entries: z.array(CacheEntrySchema),\n});\nexport type CacheFile = z.infer<typeof CacheFileSchema>;\n\nexport const emptyCache = (): CacheFile => ({ version: CACHE_VERSION, entries: [] });\n\n\n/** Reads the cache, returning an empty one for a missing, corrupt or outdated file. */\nexport const readCache = async (target: string): Promise<CacheFile> => {\n try {\n const raw = await fs.readFile(path.resolve(target), \"utf8\");\n const parsed = CacheFileSchema.parse(JSON.parse(raw));\n\n return parsed.version === CACHE_VERSION ? parsed : emptyCache();\n } catch {\n return emptyCache();\n }\n};\n\n/** JSON with the entries sorted by unit id, so the file does not churn between runs. */\nexport const serializeCache = (cache: CacheFile): string => {\n return `${JSON.stringify({ ...cache, entries: sortBy(cache.entries, (entry) => entry.unitId) }, null, 2)}\\n`;\n}\n\n/** Writes the cache, creating its directory. Returns the absolute path written. */\nexport const writeCache = async (cache: CacheFile, target: string): Promise<string> => {\n const absolute = path.resolve(target);\n\n await fs.mkdir(path.dirname(absolute), { recursive: true });\n await fs.writeFile(absolute, serializeCache(cache), \"utf8\");\n\n return absolute;\n};\n\n/** Entries keyed by unit id, for lookups while deciding what to regenerate. */\nexport const indexCache = (cache: CacheFile): Map<string, CacheEntry> => {\n return new Map(cache.entries.map((entry) => [entry.unitId, entry]));\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { ExtractResult, Manifest, Relation, Unit, Workspace } from \"@glossic/schema\";\nimport { MANIFEST_VERSION, ManifestSchema } from \"@glossic/schema\";\n\nimport { compareStrings, sortBy } from \"./utils/index.js\";\n\nexport const DEFAULT_MANIFEST_PATH = \".glossic/manifest.json\";\n\nexport interface BuildManifestOptions {\n generatedAt?: string;\n}\n\n/** Sorts everything inside one unit, so its hash does not depend on walk order. */\nconst sortUnit = (unit: Unit): Unit => ({\n ...unit,\n facts: {\n ...unit.facts,\n base: {\n ...unit.facts.base,\n files : sortBy(unit.facts.base.files, (file) => file.path),\n languages: [...unit.facts.base.languages].sort(\n (a, b) => b.count - a.count || compareStrings(a.language, b.language),\n ),\n },\n producedBy: [...unit.facts.producedBy].sort(compareStrings),\n },\n});\n\nconst compareRelations = (a: Relation, b: Relation): number => {\n return compareStrings(a.from, b.from) || compareStrings(a.to, b.to) || compareStrings(a.kind, b.kind);\n}\n\n\n/** Assembles the manifest, sorting every list so two runs over the same code match. */\nexport const buildManifest = (workspace: Workspace, results: readonly ExtractResult[], options: BuildManifestOptions = {}): Manifest => {\n const units = results.flatMap((result) => result.units).map(sortUnit);\n const relations = results.flatMap((result) => result.relations);\n\n return ManifestSchema.parse({\n version : MANIFEST_VERSION,\n generatedAt: options.generatedAt ?? new Date().toISOString(),\n workspace : {\n ...workspace,\n projects: sortBy(workspace.projects, (project) => project.id),\n },\n units : sortBy(units, (unit) => unit.id),\n relations: [...relations].sort(compareRelations),\n });\n};\n\n/** The manifest as it lands on disk: JSON, two-space indent, trailing newline. */\nexport const serializeManifest = (manifest: Manifest): string => {\n return `${JSON.stringify(manifest, null, 2)}\\n`;\n}\n\n\n/** Writes the manifest, creating its directory. Returns the absolute path written. */\nexport const writeManifest = async (manifest: Manifest, target: string): Promise<string> => {\n const absolute = path.resolve(target);\n\n await fs.mkdir(path.dirname(absolute), { recursive: true });\n await fs.writeFile(absolute, serializeManifest(manifest), \"utf8\");\n \n return absolute;\n};\n\n/** Reads and validates a manifest, or undefined when it is missing or invalid. */\nexport const readManifest = async (target: string): Promise<Manifest | undefined> => {\n try {\n const raw = await fs.readFile(path.resolve(target), \"utf8\");\n return ManifestSchema.parse(JSON.parse(raw));\n } catch {\n return undefined;\n }\n};\n","import path from \"node:path\";\nimport type { Project, Workspace, WorkspaceTool } from \"@glossic/schema\";\nimport { glob } from \"tinyglobby\";\nimport { parse as parseYaml } from \"yaml\";\n\nimport { pathExists, readJson, readText, sortBy, toPosix } from \"./utils/index.js\";\n\ninterface PackageJson {\n name ?: string;\n packageManager?: string;\n workspaces ?: string[] | { packages?: string[] };\n}\n\ninterface MonorepoMarker {\n tool : WorkspaceTool;\n globs: string[];\n}\n\nconst GLOB_IGNORES = [\"**/node_modules/**\", \"**/dist/**\", \"**/build/**\", \"**/.git/**\"];\n\nconst LOCKFILE_PACKAGE_MANAGERS: ReadonlyArray<readonly [string, string]> = [\n [\"pnpm-lock.yaml\", \"pnpm\"],\n [\"yarn.lock\", \"yarn\"],\n [\"package-lock.json\", \"npm\"],\n [\"bun.lock\", \"bun\"],\n [\"bun.lockb\", \"bun\"],\n [\"composer.lock\", \"composer\"],\n [\"composer.json\", \"composer\"],\n];\n\nconst asStringArray = (value: unknown): string[] =>\n Array.isArray(value) ? value.filter((item): item is string => typeof item === \"string\") : [];\n\n/** The package manager in use, from the packageManager field or from the lockfile. */\nconst detectPackageManager = async (dir: string, pkg: PackageJson | undefined): Promise<string | undefined> => {\n const declared = pkg?.packageManager;\n\n if (typeof declared === \"string\" && declared.length > 0) {\n const [name] = declared.split(\"@\");\n\n if (name !== undefined && name.length > 0) {\n return name;\n }\n }\n\n for (const [lockfile, manager] of LOCKFILE_PACKAGE_MANAGERS) {\n if (await pathExists(path.join(dir, lockfile))) {\n return manager;\n }\n }\n\n return undefined;\n};\n\n\n/** The monorepo tool and the globs defining its projects, when this repo is one. */\nconst detectMonorepo = async (root: string, pkg: PackageJson | undefined): Promise<MonorepoMarker | undefined> => {\n const pnpmWorkspace = await readText(path.join(root, \"pnpm-workspace.yaml\"));\n\n if (pnpmWorkspace !== undefined) {\n const parsed: unknown = parseYaml(pnpmWorkspace);\n const globs = asStringArray((parsed as { packages?: unknown } | null)?.packages);\n\n if (globs.length > 0) {\n return { tool: \"pnpm\", globs };\n }\n }\n\n const workspaces = Array.isArray(pkg?.workspaces) ? pkg.workspaces : asStringArray(pkg?.workspaces?.packages);\n\n if (workspaces.length > 0) {\n return { tool: \"npm-workspaces\", globs: workspaces };\n }\n\n if (await pathExists(path.join(root, \"turbo.json\"))) {\n return { tool: \"turbo\", globs: [\"apps/*\", \"packages/*\"] };\n }\n\n if (await pathExists(path.join(root, \"nx.json\"))) {\n return { tool: \"nx\", globs: [\"apps/*\", \"libs/*\", \"packages/*\"] };\n }\n\n const lerna = await readJson<{ packages?: unknown }>(path.join(root, \"lerna.json\"));\n\n if (lerna !== undefined) {\n const globs = asStringArray(lerna.packages);\n return { tool: \"lerna\", globs: globs.length > 0 ? globs : [\"packages/*\"] };\n }\n\n return undefined;\n};\n\nconst expandProjectDirs = async (root: string, globs: string[]): Promise<string[]> => {\n const patterns: string[] = [];\n const ignore = [...GLOB_IGNORES];\n\n for (const entry of globs) {\n if (entry.startsWith(\"!\")) {\n ignore.push(`${entry.slice(1)}/**`);\n continue;\n }\n \n patterns.push(`${entry}/package.json`);\n }\n\n if (patterns.length === 0) return [];\n\n const manifests = await glob({\n patterns,\n cwd: root,\n ignore,\n onlyFiles : true,\n followSymbolicLinks: false,\n dot : false,\n });\n\n const dirs = manifests.map((manifest) => toPosix(path.posix.dirname(toPosix(manifest))));\n\n return [...new Set(dirs)].sort();\n};\n\nconst buildProject = async (root: string, rootDir: string, fallbackManager: string | undefined): Promise<Project> => {\n const dir = path.resolve(root, rootDir);\n const pkg = await readJson<PackageJson>(path.join(dir, \"package.json\"));\n const packageManager = (await detectPackageManager(dir, pkg)) ?? fallbackManager;\n const name = pkg?.name ?? path.basename(dir);\n\n const project: Project = {\n id: rootDir === \".\" ? \"root\" : rootDir,\n name,\n rootDir,\n };\n\n return packageManager === undefined ? project : { ...project, packageManager };\n};\n\n\n/** Identifies the repository and lists its projects, monorepo or not. */\nexport const resolveWorkspace = async (root: string): Promise<Workspace> => {\n const absoluteRoot = path.resolve(root);\n const pkg = await readJson<PackageJson>(path.join(absoluteRoot, \"package.json\"));\n const packageManager = await detectPackageManager(absoluteRoot, pkg);\n const name = pkg?.name ?? path.basename(absoluteRoot);\n\n const marker = await detectMonorepo(absoluteRoot, pkg);\n const projectDirs = marker === undefined ? [] : await expandProjectDirs(absoluteRoot, marker.globs);\n\n const isMonorepo = projectDirs.length > 0;\n const rootDirs = isMonorepo ? projectDirs : [\".\"];\n const projects = await Promise.all(\n rootDirs.map((rootDir) => buildProject(absoluteRoot, rootDir, packageManager)),\n );\n\n const workspace: Workspace = {\n name,\n root: toPosix(absoluteRoot),\n isMonorepo,\n tool : isMonorepo && marker !== undefined ? marker.tool: \"none\",\n projects: sortBy(projects, (project) => project.id),\n };\n\n return packageManager === undefined ? workspace : { ...workspace, packageManager };\n};\n","import path from \"node:path\";\n\nimport { GlossicConfigSchema } from \"@glossic/schema\";\nimport type { Adapter, AdapterContext, DiscoverContext, ExtractResult, GlossicConfig, Manifest, Workspace } from \"@glossic/schema\";\n\nimport { buildManifest } from \"./manifest.js\";\nimport { resolveWorkspace } from \"./workspace.js\";\n\n/** What every pipeline stage needs: where to scan, with which adapters and config. */\nexport interface PipelineContext {\n root : string;\n adapters : readonly Adapter[];\n config ?: GlossicConfig;\n generatedAt?: string;\n}\n\nexport interface ScanResult {\n manifest : Manifest;\n workspace : Workspace;\n adapterByProject: Record<string, string>;\n}\n\n\n/** Puts the adapters in the order the config asks for, dropping the ones it omits. */\nexport const orderAdapters = (adapters: readonly Adapter[], wanted: readonly string[]): Adapter[] => {\n const byName = new Map(adapters.map((adapter) => [adapter.name, adapter]));\n\n return wanted\n .map((name) => byName.get(name))\n .filter((adapter): adapter is Adapter => adapter !== undefined);\n};\n\n/** The first adapter that claims the project. */\nconst selectAdapter = async (adapters: readonly Adapter[], ctx: DiscoverContext): Promise<Adapter | undefined> => {\n for (const adapter of adapters) {\n if (await adapter.detect(ctx)) {\n return adapter;\n }\n }\n\n return undefined;\n};\n\n\n/** Walks the workspace and turns it into a manifest, calling no provider. */\nexport const scan = async (ctx: PipelineContext): Promise<ScanResult> => {\n const config = ctx.config ?? GlossicConfigSchema.parse({});\n const workspace = await resolveWorkspace(path.resolve(ctx.root));\n const adapters = orderAdapters(ctx.adapters, config.adapters);\n const adapterContext: AdapterContext = { root: workspace.root, workspace, config };\n\n const results: ExtractResult[] = [];\n const adapterByProject: Record<string, string> = {};\n\n for (const project of workspace.projects) {\n const discoverContext: DiscoverContext = { ...adapterContext, project };\n const adapter = await selectAdapter(adapters, discoverContext);\n\n if (adapter === undefined) continue;\n\n adapterByProject[project.id] = adapter.name;\n\n const units = await adapter.discover(discoverContext);\n \n results.push(await adapter.extract({ ...discoverContext, units }));\n }\n\n const manifest = buildManifest(\n workspace,\n results,\n ctx.generatedAt === undefined ? {} : { generatedAt: ctx.generatedAt },\n );\n\n return { manifest, workspace, adapterByProject };\n};\n","import type { Manifest, Project, Unit } from \"@glossic/schema\";\n\nimport { compareStrings } from \"./utils/index.js\";\n\n/** Where a unit's page goes, relative to the output directory. */\nexport const unitDocPath = (unit: Unit): string => {\n return unit.path === \".\" ? \"root.md\" : `${unit.path}.md`;\n}\n\nexport const INDEX_DOC_PATH = \"index.md\";\n\nconst frontmatter = (entries: ReadonlyArray<readonly [string, string | number]>): string =>\n [\n \"---\",\n ...entries.map(([key, value]) =>\n typeof value === \"number\" ? `${key}: ${value}` : `${key}: ${JSON.stringify(value)}`,\n ),\n \"---\",\n ].join(\"\\n\");\n\nexport interface RenderUnitDocInput {\n unit : Unit;\n project : Project;\n body : string;\n generatedAt: string;\n}\n\n\n/** One unit's page: frontmatter carrying the hash, then the prose the provider wrote. */\nexport const renderUnitDoc = (input: RenderUnitDocInput): string => {\n const { unit } = input;\n const title = unit.name === \"root\" ? input.project.name : unit.name;\n\n const entries: Array<readonly [string, string | number]> = [\n [\"title\", title],\n [\"unit\", unit.id],\n [\"project\", unit.projectId],\n [\"path\", unit.path],\n [\"hash\", unit.hash],\n [\"files\", unit.facts.base.files.length],\n [\"generatedAt\", input.generatedAt],\n ];\n\n if (unit.facts.base.roleHint !== null) {\n entries.splice(4, 0, [\"role\", unit.facts.base.roleHint]);\n }\n\n return [frontmatter(entries), \"\", input.body.trim(), \"\"].join(\"\\n\");\n};\n\nexport interface RenderIndexDocInput {\n manifest : Manifest;\n generatedAt: string;\n}\n\nconst languageSummary = (units: readonly Unit[]): string => {\n const totals = new Map<string, number>();\n\n for (const unit of units) {\n for (const entry of unit.facts.base.languages) {\n totals.set(entry.language, (totals.get(entry.language) ?? 0) + entry.count);\n }\n }\n\n return [...totals.entries()]\n .sort(([aLang, aCount], [bLang, bCount]) => bCount - aCount || compareStrings(aLang, bLang))\n .map(([language, count]) => `${language} (${count})`)\n .join(\", \");\n};\n\n\n/** The index page listing every unit in the workspace. */\nexport const renderIndexDoc = (input: RenderIndexDocInput): string => {\n const { manifest } = input;\n const { workspace, units } = manifest;\n\n const lines: string[] = [\n frontmatter([\n [\"title\", workspace.name],\n [\"generatedAt\", input.generatedAt],\n [\"units\", units.length],\n ]),\n \"\",\n `# ${workspace.name}`,\n \"\",\n workspace.isMonorepo\n ? `${workspace.tool} monorepo with ${workspace.projects.length} projects.`\n : \"Single-project workspace.\",\n \"\",\n ];\n\n for (const project of workspace.projects) {\n const projectUnits = units.filter((unit) => unit.projectId === project.id);\n\n lines.push(`## ${project.name}`, \"\");\n\n if (projectUnits.length === 0) {\n lines.push(\"No documented units.\", \"\");\n continue;\n }\n\n for (const unit of projectUnits) {\n const role = unit.facts.base.roleHint;\n const suffix = role === null ? \"\" : ` — ${role}`;\n\n lines.push(\n `- [${unit.name}](./${unitDocPath(unit)}) — ${unit.facts.base.files.length} files${suffix}`,\n );\n }\n lines.push(\"\");\n }\n\n const languages = languageSummary(units);\n\n if (languages !== \"\") {\n lines.push(`Languages: ${languages}`, \"\");\n }\n\n return lines.join(\"\\n\");\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { Manifest } from \"@glossic/schema\";\nimport { glob } from \"tinyglobby\";\nimport { parse as parseYaml } from \"yaml\";\n\nimport { scan } from \"./scan.js\";\nimport { INDEX_DOC_PATH, unitDocPath } from \"./markdown.js\";\nimport { compareStrings, sortBy, toPosix } from \"./utils/index.js\";\nimport type { PipelineContext } from \"./scan.js\";\n\nexport interface CheckContext extends PipelineContext {\n outDir: string;\n}\n\n/** One unit weighed against its page: the hash expected against the one on disk. */\nexport interface CheckEntry {\n unitId : string;\n docPath : string;\n expectedHash : string;\n documentedHash: string | undefined;\n}\n\nexport interface CheckResult {\n outDir : string;\n upToDate: CheckEntry[];\n missing : CheckEntry[];\n stale : CheckEntry[];\n orphaned: string[];\n ok : boolean;\n}\n\ninterface DocumentFrontmatter {\n unit: string | undefined;\n hash: string | undefined;\n}\n\nconst FRONTMATTER = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n/;\n\n/** The frontmatter of a generated page, empty when the file carries none. */\nexport const readDocFrontmatter = async (file: string): Promise<DocumentFrontmatter> => {\n try {\n const raw = await fs.readFile(file, \"utf8\");\n const match = FRONTMATTER.exec(raw);\n\n if (match === null) {\n return { unit: undefined, hash: undefined };\n }\n\n const parsed: unknown = parseYaml(match[1] ?? \"\");\n \n if (typeof parsed !== \"object\" || parsed === null) {\n return { unit: undefined, hash: undefined };\n }\n\n const record = parsed as Record<string, unknown>;\n\n return {\n unit: typeof record.unit === \"string\" ? record.unit : undefined,\n hash: typeof record.hash === \"string\" ? record.hash : undefined,\n };\n } catch {\n return { unit: undefined, hash: undefined };\n }\n};\n\n/** Every markdown page under the output directory, as posix paths. */\nconst listDocs = async (outDir: string): Promise<string[]> => {\n try {\n const entries = await glob({\n patterns : [\"**/*.md\"],\n cwd : outDir,\n onlyFiles : true,\n followSymbolicLinks: false,\n });\n\n return entries.map(toPosix).sort(compareStrings);\n } catch {\n return [];\n }\n};\n\n\n/**\n * Compares the pages on disk against a fresh scan, calling no provider. This\n * is what a CI job runs to fail on documentation nobody regenerated.\n */\nexport const check = async (ctx: CheckContext): Promise<CheckResult> => {\n const { manifest }: { manifest: Manifest } = await scan(ctx);\n\n const docs = await listDocs(ctx.outDir);\n const expected = new Map(manifest.units.map((unit) => [unitDocPath(unit), unit]));\n\n const upToDate: CheckEntry[] = [];\n const missing : CheckEntry[] = [];\n const stale : CheckEntry[] = [];\n\n for (const unit of manifest.units) {\n const docPath = unitDocPath(unit);\n const entryBase = { unitId: unit.id, docPath, expectedHash: unit.hash };\n\n if (!docs.includes(docPath)) {\n missing.push({ ...entryBase, documentedHash: undefined });\n continue;\n }\n\n const { hash } = await readDocFrontmatter(path.resolve(ctx.outDir, docPath));\n\n if (hash === unit.hash) {\n upToDate.push({ ...entryBase, documentedHash: hash });\n } else {\n stale.push({ ...entryBase, documentedHash: hash });\n }\n }\n\n const orphaned = docs\n .filter((doc) => doc !== INDEX_DOC_PATH && !expected.has(doc))\n .sort(compareStrings);\n\n const byUnitId = (entries: CheckEntry[]): CheckEntry[] => {\n return sortBy(entries, (entry) => entry.unitId);\n }\n\n return {\n outDir : toPosix(ctx.outDir),\n upToDate: byUnitId(upToDate),\n missing : byUnitId(missing),\n stale : byUnitId(stale),\n orphaned,\n ok: missing.length === 0 && stale.length === 0 && orphaned.length === 0,\n };\n};\n","import path from \"node:path\";\n\nimport { createJiti } from \"jiti\";\nimport { GlossicConfigSchema } from \"@glossic/schema\";\nimport type { GlossicUserConfig } from \"@glossic/schema\";\n\nimport { pathExists, toPosix } from \"./utils/index.js\";\n\n/** Config filenames, in the order they are looked for. */\nexport const CONFIG_FILENAMES = [\n \"glossic.config.ts\",\n \"glossic.config.mts\",\n \"glossic.config.js\",\n \"glossic.config.mjs\",\n];\n\n\n/** Posix path of the project's config file, when it has one. */\nexport const findConfigFile = async (root: string): Promise<string | undefined> => {\n for (const filename of CONFIG_FILENAMES) {\n const candidate = path.resolve(root, filename);\n if (await pathExists(candidate)) {\n return toPosix(candidate);\n }\n }\n\n return undefined;\n};\n\n/** The project has no config file at all. */\nexport interface MissingConfig {\n status: \"missing\";\n}\n\n/** The file is there but unusable, and `error` is the reason to put in front of the user. */\nexport interface FailedConfig {\n status: \"failed\";\n file : string;\n error : string;\n}\n\n/** `values` carries only the keys the file actually set, so a no-op config leaves it empty. */\nexport interface LoadedConfig {\n status: \"loaded\";\n file : string;\n values: GlossicUserConfig;\n}\n\n/** The three things a config file can be, so a missing file never reads as a broken one. */\nexport type ProjectConfig = MissingConfig | FailedConfig | LoadedConfig;\n\n/** The reason ends up on one terminal line, so the stack and the rest of the message go. */\nconst describeError = (cause: unknown): string => {\n const message = cause instanceof Error ? cause.message : String(cause);\n\n return message.split(\"\\n\")[0]?.trim() || \"unknown error\";\n};\n\n/** The module's default export as a config, or why it is not one. */\nconst readDefaultExport = (file: string, value: unknown): FailedConfig | LoadedConfig => {\n const parsed = GlossicConfigSchema.partial().safeParse(value);\n\n if (!parsed.success) {\n const error = parsed.error.issues\n .map((issue) =>\n issue.path.length === 0 ? issue.message : `${issue.path.join(\".\")}: ${issue.message}`,\n )\n .join(\"; \");\n\n return { status: \"failed\", file, error };\n }\n\n const declared = Object.keys(value as Record<string, unknown>);\n\n const values = Object.fromEntries(\n Object.entries(parsed.data).filter(([key]) => declared.includes(key)),\n ) as GlossicUserConfig;\n\n return { status: \"loaded\", file, values };\n};\n\n\n/** Never throws: a config that cannot be loaded is reported as such, not hidden. */\nexport const loadProjectConfig = async (root: string): Promise<ProjectConfig> => {\n const file = await findConfigFile(root);\n\n if (file === undefined) {\n return { status: \"missing\" };\n }\n\n try {\n const jiti = createJiti(import.meta.url, { moduleCache: false });\n const loaded = await jiti.import(file, { default: true });\n\n return readDefaultExport(file, loaded);\n } catch (cause) {\n return { status: \"failed\", file, error: describeError(cause) };\n }\n};\n","import type { GlossicConfig, GlossicUserConfig } from \"@glossic/schema\";\nimport { GlossicConfigSchema } from \"@glossic/schema\";\n\n/** Which source decided one option's value; `glossic doctor` prints it. */\nexport type ConfigOrigin = \"flag\" | \"project\" | \"preference\" | \"default\";\n\nexport type ConfigOrigins = Record<string, ConfigOrigin>;\n\nexport interface ConfigSources {\n flags ?: GlossicUserConfig | undefined;\n project ?: GlossicUserConfig | undefined;\n preference?: GlossicUserConfig | undefined;\n}\n\nexport interface ResolvedConfig {\n config : GlossicConfig;\n origins: ConfigOrigins;\n}\n\nconst ORDER: ReadonlyArray<[\"flag\" | \"project\" | \"preference\", keyof ConfigSources]> = [\n [\"flag\", \"flags\"],\n [\"project\", \"project\"],\n [\"preference\", \"preference\"],\n];\n\nconst isSet = (value: unknown): boolean => {\n return value !== undefined && !(typeof value === \"string\" && value.trim() === \"\");\n}\n\n\n/**\n * Merges the sources under one precedence chain (flags, project config, saved\n * preference, schema defaults) and records which one won each key.\n */\nexport const resolveConfig = (sources: ConfigSources = {}): ResolvedConfig => {\n const merged : Record<string, unknown> = {};\n const origins: ConfigOrigins = {};\n\n for (const [origin, key] of [...ORDER].reverse()) {\n const source = sources[key];\n\n if (source === undefined) continue;\n\n for (const [name, value] of Object.entries(source)) {\n if (!isSet(value)) continue;\n\n merged[name] = value;\n origins[name] = origin;\n }\n }\n\n const config = GlossicConfigSchema.parse(merged);\n\n for (const name of Object.keys(config)) {\n origins[name] ??= \"default\";\n }\n\n return { config, origins };\n};\n\n\n/** The options that change how files become units, and so invalidate a scan. */\nexport const GROUPING_KEYS = [\n \"include\",\n \"exclude\",\n \"ignoreUnits\",\n \"excludeFromContent\",\n \"mergeChildrenInto\",\n \"minUnitFiles\",\n \"maxUnitFiles\",\n] as const;\n","/** Placeholder for a code path that is scaffolded but not written yet. */\nexport class NotImplementedError extends Error {\n constructor(what: string) {\n super(`${what} is not implemented`);\n this.name = \"NotImplementedError\";\n }\n}\n\n\n/**\n * Nothing on this machine can write prose. The message is the install\n * instructions, because this is the first wall a new user hits.\n */\nexport class NoProviderAvailableError extends Error {\n readonly tried: string[];\n\n constructor(tried: readonly string[]) {\n super(\n [\n \"No LLM provider is available.\",\n \"\",\n \"glossic needs one of these two:\",\n \"\",\n \" 1. Claude Code — install the CLI and sign in:\",\n \" https://claude.com/claude-code\",\n \" glossic picks it up as soon as `claude --version` works.\",\n \"\",\n \" 2. Anthropic API — export an API key:\",\n \" export ANTHROPIC_API_KEY=sk-ant-...\",\n \" https://console.anthropic.com/settings/keys\",\n \"\",\n \"Run `glossic doctor` to see what glossic can find on this machine.\",\n ].join(\"\\n\"),\n );\n this.name = \"NoProviderAvailableError\";\n this.tried = [...tried];\n }\n}\n\n/** The provider named by a flag or by the config does not exist. */\nexport class UnknownProviderError extends Error {\n constructor(requested: string, known: readonly string[]) {\n super(`unknown provider \"${requested}\". Available: ${[...known].sort().join(\", \")}`);\n this.name = \"UnknownProviderError\";\n }\n}\n","import { isRetryableProviderError } from \"@glossic/schema\";\n\n/** `sleep` and `onRetry` exist so a test can drive the loop without waiting. */\nexport interface RetryOptions {\n attempts ?: number;\n baseDelayMs?: number;\n sleep ?: (ms: number) => Promise<void>;\n onRetry ?: (attempt: number, error: unknown) => void;\n}\n\nconst DEFAULT_ATTEMPTS = 3;\nconst DEFAULT_BASE_DELAY_MS = 500;\n\nconst defaultSleep = (ms: number): Promise<void> => {\n return new Promise((resolve) => {\n setTimeout(resolve, ms).unref?.();\n });\n}\n\n\n/** Exponential backoff: the delay doubles with every attempt. */\nexport const backoffDelay = (attempt: number, baseDelayMs: number): number => {\n return baseDelayMs * 2 ** (attempt - 1);\n}\n\n\n/** Runs a task again while it fails with a retryable provider error. */\nexport const withRetry = async <T>(task: () => Promise<T>, options: RetryOptions = {}): Promise<T> => {\n const attempts = options.attempts ?? DEFAULT_ATTEMPTS;\n const baseDelayMs = options.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;\n const sleep = options.sleep ?? defaultSleep;\n\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= attempts; attempt += 1) {\n try {\n return await task();\n } catch (error) {\n lastError = error;\n\n if (attempt === attempts || !isRetryableProviderError(error)) {\n throw error;\n }\n\n options.onRetry?.(attempt, error);\n\n await sleep(backoffDelay(attempt, baseDelayMs));\n }\n }\n\n throw lastError;\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { CompletionRequest, Project, Unit } from \"@glossic/schema\";\nimport { compareStrings } from \"./utils/index.js\";\n\n/** A file longer than this is truncated before it goes into a prompt. */\nexport const MAX_FILE_BYTES = 24_000;\n\nconst CHARS_PER_TOKEN = 4;\n\nexport interface UnitSource {\n path : string;\n language : string;\n content : string;\n truncated: boolean;\n}\n\nexport interface BuildPromptInput {\n unit : Unit;\n project : Project;\n workspaceName : string;\n sources : readonly UnitSource[];\n lang : string;\n model ?: string | undefined;\n temperature ?: number | undefined;\n}\n\n\n/** Bumped by hand when the prompt changes, which invalidates every cached unit. */\nexport const PROMPT_VERSION = \"4\";\n\n/** The rules the model is held to; assertDocumentContent checks the answer against them. */\nexport const SYSTEM_PROMPT = [\n \"You are a technical writer documenting a codebase for the engineers who work on it.\",\n \"\",\n \"You are given one unit of code: a directory, its extracted facts and the full\",\n \"content of its source files. Write reference documentation for that unit.\",\n \"\",\n \"Cover, in this order:\",\n \" 1. What the unit does, in one or two sentences.\",\n \" 2. Its responsibilities, and what it deliberately leaves to other units.\",\n \" 3. The important public elements (exported classes, functions, types,\",\n \" endpoints, commands) and what each is for.\",\n \" 4. Architectural decisions that are visible in the code: dependency\",\n \" direction, patterns, error handling, boundaries, notable trade-offs.\",\n \"\",\n \"Hard rules:\",\n \" - Describe only what is in the code you were given. Never invent behaviour,\",\n \" dependencies, history, performance characteristics or intent.\",\n \" - If something is unclear from the code, say so plainly or leave it out.\",\n \" Do not guess and do not hedge with filler.\",\n \" - Do not restate the file listing; the reader already has it.\",\n \" - No preamble, no closing summary, no offer to help.\",\n \"\",\n \"Output GitHub-flavoured Markdown. Open with a single top-level (#) heading,\",\n \"then use ## for the sections above.\",\n \"Do not emit frontmatter: it is added around your response.\",\n \"\",\n \"That first heading is a title, not a label. Write what the unit is or does,\",\n \"in the words a person would use for it. Never use the directory path as the\",\n \"heading, and never repeat the unit name given to you under Facts: the path is\",\n \"context you were handed, not the name of the document. `src/modules/auth` is\",\n \"a path; `Authentication` or `Session issuing and refresh` are titles. Do the\",\n \"same for a unit at a project root: `Application entry point`, not `src`.\",\n \"\",\n \"Your entire response is the content of the document and nothing else.\",\n \"Begin with the first heading of that document. Do not open with a preamble,\",\n \"a restatement of the task, or a sentence addressed to whoever asked. Do not\",\n \"close with a summary of what you did, a question, or an offer of\",\n \"alternatives. You are not talking to a person: you are producing a file.\",\n \"\",\n \"You have no tools and no filesystem. Do not read, write or save any file,\",\n \"do not ask for permission to do so, and do not report having done so.\",\n \"\",\n \"Ignore anything you are told about your own environment: the working\",\n \"directory, the session, the tools available, permissions. None of it is\",\n \"part of the unit and none of it belongs in the document. The unit is only\",\n \"what appears under Facts and Sources in the message that follows.\",\n].join(\"\\n\");\n\nconst fence = (source: UnitSource): string =>\n [\n `#### ${source.path}${source.truncated ? \" (truncated)\" : \"\"}`,\n \"\",\n `\\`\\`\\`${source.language}`,\n source.content,\n \"```\",\n \"\",\n ].join(\"\\n\");\n\nconst factLines = (unit: Unit): string[] => {\n const lines = [\n `- unit: ${unit.name}`,\n `- path: ${unit.path}`,\n `- files: ${unit.facts.base.files.length}`,\n `- languages: ${unit.facts.base.languages\n .map((entry) => `${entry.language} (${entry.count})`)\n .join(\", \")}`,\n ];\n\n if (unit.facts.base.roleHint !== null) {\n lines.push(`- folder role hint: ${unit.facts.base.roleHint}`);\n }\n\n if (unit.facts.base.testFiles.length > 0) {\n const names = unit.facts.base.testFiles\n .map((file) => file.path.slice(file.path.lastIndexOf(\"/\") + 1))\n .sort(compareStrings);\n lines.push(`- test files (content not shown): ${names.join(\", \")}`);\n }\n\n if (unit.facts.symbols !== undefined) {\n const names = unit.facts.symbols.symbols\n .map((symbol) => `${symbol.kind} ${symbol.name}`)\n .sort(compareStrings);\n lines.push(`- symbols: ${names.join(\", \")}`);\n }\n\n if (unit.facts.framework !== undefined) {\n lines.push(`- framework: ${unit.facts.framework.name}`);\n if (unit.facts.framework.role !== undefined) {\n lines.push(`- framework role: ${unit.facts.framework.role}`);\n }\n }\n\n return lines;\n};\n\n\n/** Turns a unit and its sources into the one request a provider will answer. */\nexport const buildUnitPrompt = (input: BuildPromptInput): CompletionRequest => {\n const prompt = [\n `Workspace: ${input.workspaceName}`,\n `Project: ${input.project.name} (${input.project.rootDir})`,\n \"\",\n \"## Facts\",\n \"\",\n ...factLines(input.unit),\n \"\",\n \"## Sources\",\n \"\",\n ...input.sources.map(fence),\n `Write the documentation in ${input.lang}.`,\n ].join(\"\\n\");\n\n return {\n system: SYSTEM_PROMPT,\n prompt,\n ...(input.model === undefined ? {} : { model: input.model }),\n ...(input.temperature === undefined ? {} : { temperature: input.temperature }),\n metadata: { unitId: input.unit.id, projectId: input.unit.projectId },\n };\n};\n\n\n/** Reads a unit's documentable files, truncating any that run too long. */\nexport const readUnitSources = async (root: string, unit: Unit): Promise<UnitSource[]> => {\n const sources = await Promise.all(\n unit.facts.base.files.map(async (file): Promise<UnitSource> => {\n const raw = await fs.readFile(path.resolve(root, file.path), \"utf8\");\n const truncated = raw.length > MAX_FILE_BYTES;\n\n return {\n path : file.path,\n language: file.language,\n content : truncated ? raw.slice(0, MAX_FILE_BYTES): raw,\n truncated,\n };\n }),\n );\n\n return sources;\n};\n\n\n/** Rough token count, for the estimate a dry run prints before anything is spent. */\nexport const estimateTokens = (request: CompletionRequest): number => {\n return Math.ceil(((request.system?.length ?? 0) + request.prompt.length) / CHARS_PER_TOKEN);\n}\n","/** Maps over items with at most `limit` tasks in flight, preserving input order. */\nexport const mapWithConcurrency = async <T, R>(items: readonly T[], limit: number, task: (item: T) => Promise<R>): Promise<R[]> => {\n const results = new Array<R>(items.length);\n let cursor = 0;\n\n const worker = async (): Promise<void> => {\n while (cursor < items.length) {\n const index = cursor;\n \n cursor += 1;\n\n const item = items[index];\n\n if (item === undefined) continue;\n\n results[index] = await task(item);\n }\n };\n\n await Promise.all(Array.from({ length: Math.max(1, Math.min(limit, items.length)) }, worker));\n return results;\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { CompletionRequest, GlossicConfig, Manifest, Project, Unit } from \"@glossic/schema\";\n\nimport { unitDocPath } from \"../markdown.js\";\nimport { buildUnitPrompt, estimateTokens, readUnitSources } from \"../prompt.js\";\n\n/** One unit ready to be sent: its prompt built and its destination known. */\nexport interface Job {\n unit : Unit;\n project : Project;\n request : CompletionRequest;\n docPath : string;\n estimatedTokens: number;\n}\n\n\n/** Writes a page under the output directory, creating the directories it needs. */\nexport const writeDoc = async (outDir: string, relative: string, content: string): Promise<void> => {\n const target = path.resolve(outDir, relative);\n\n await fs.mkdir(path.dirname(target), { recursive: true });\n await fs.writeFile(target, content, \"utf8\");\n};\n\n\n/** Reads the sources and builds a prompt for every unit in the manifest. */\nexport const buildJobs = async (manifest: Manifest, config: GlossicConfig, root: string): Promise<Job[]> => {\n const projectById = new Map(manifest.workspace.projects.map((entry) => [entry.id, entry]));\n\n const jobs = await Promise.all(\n manifest.units.map(async (unit): Promise<Job | undefined> => {\n const project = projectById.get(unit.projectId);\n\n if (project === undefined) {\n return undefined;\n }\n\n const request = buildUnitPrompt({\n unit,\n project,\n workspaceName: manifest.workspace.name,\n sources : await readUnitSources(root, unit),\n lang : config.lang,\n model : config.model,\n temperature : config.temperature,\n });\n\n return {\n unit,\n project,\n request,\n docPath : unitDocPath(unit),\n estimatedTokens: estimateTokens(request),\n };\n }),\n );\n\n return jobs.filter((job): job is Job => job !== undefined);\n};\n","import path from \"node:path\";\n\nimport type { GlossicConfig } from \"@glossic/schema\";\n\nimport { PROMPT_VERSION } from \"../prompt.js\";\nimport { pathExists } from \"../utils/index.js\";\nimport type { Job } from \"./jobs.js\";\nimport type { CacheEntry } from \"../cache.js\";\nimport type { GenerateReason } from \"./types.js\";\n\n/** The model a cache entry was written under, with a name for the unset case. */\nexport const modelCacheKey = (config: GlossicConfig): string => config.model ?? \"default\";\n\nexport interface DecisionContext {\n outDir: string;\n model : string;\n lang : string;\n force : boolean;\n}\n\n/** Why this unit has to be regenerated, or `cached` when nothing changed. */\nexport const decide = async (job: Job, entry: CacheEntry | undefined, context: DecisionContext): Promise<GenerateReason> => {\n if (context.force) {\n return \"forced\";\n }\n\n if (entry === undefined) {\n return \"new\";\n }\n\n if (entry.unitHash !== job.unit.hash) {\n return \"content-changed\";\n }\n\n if (entry.promptVersion !== PROMPT_VERSION) {\n return \"prompt-version-changed\";\n }\n\n if (entry.model !== context.model) {\n return \"model-changed\";\n }\n\n if (entry.lang !== context.lang) {\n return \"lang-changed\";\n }\n\n if (!(await pathExists(path.resolve(context.outDir, job.docPath)))) {\n return \"output-missing\";\n }\n\n return \"cached\";\n};\n","import { ProviderError } from \"@glossic/schema\";\n\n/** Under this many characters the answer reads as a refusal, not as a document. */\nexport const MIN_DOCUMENT_LENGTH = 200;\n/** Over this, what precedes the first heading is an answer rather than a preamble. */\nexport const MAX_PREAMBLE_LENGTH = 500;\n\ninterface ContentRule {\n reason : string;\n pattern: RegExp;\n}\n\n/** Shapes that mean the model addressed the reader instead of writing the document. */\nconst CONVERSATIONAL_RULES: readonly ContentRule[] = [\n {\n reason : \"the model asked for permission instead of writing the document\",\n pattern:\n /\\b(permission to (write|save|create)|(write|read) permission|need (write )?access)\\b/i,\n },\n {\n reason : \"the model reported on saving a file instead of writing the document\",\n pattern:\n /\\bI( have|['’]ve)? ?(drafted|prepared|written|created|saved|generated) (the|this|a) /i,\n },\n {\n reason : \"the model asked the reader a question\",\n pattern: /\\b(let me know|say the word|shall I|would you (like|prefer|want))\\b/i,\n },\n {\n reason : \"the model opened with a preamble instead of the document\",\n pattern: /^\\s*(here(['’]s| is)|below is|sure[,!]|certainly[,!]|I['’]ll)\\b/i,\n },\n {\n reason : \"the model addressed the reader in the first person\",\n pattern: /\\bI['’](ve|m|ll|d)\\b/,\n },\n {\n reason : \"the model addressed the reader in the first person\",\n pattern: /\\bI (need|cannot|can't|could not|couldn't|have|am|was|tried|noticed|assume)\\b/,\n },\n];\n\nconst FENCE = /^\\s{0,3}(```|~~~)/;\nconst TOP_HEADING = /^\\s{0,3}#{1,2}\\s+\\S/;\n\ninterface SourceLine {\n text : string;\n fenced: boolean;\n}\n\n/** Lines tagged with whether they sit inside a fenced code block. */\nconst scanLines = (text: string): SourceLine[] => {\n const lines: SourceLine[] = [];\n let fence: string | undefined;\n\n for (const line of text.split(/\\r?\\n/)) {\n const match = FENCE.exec(line);\n\n if (fence === undefined) {\n if (match !== null) {\n fence = match[1];\n }\n\n lines.push({ text: line, fenced: match !== null });\n\n continue;\n }\n\n lines.push({ text: line, fenced: true });\n\n if (match !== null && match[1] === fence) {\n fence = undefined;\n }\n }\n\n return lines;\n};\n\nexport interface NormalizedDocument {\n body : string;\n preamble: string | undefined;\n}\n\nconst invalidContent = (providerName: string, reason: string, detail: string): ProviderError =>\n new ProviderError({\n provider: providerName,\n code : \"invalid-content\",\n message : `the response is not a document: ${reason}`,\n detail,\n });\n\n/** Shortens text for an error message, onto a single line. */\nexport const excerpt = (text: string, limit: number): string => {\n const flat = text.replace(/\\s+/g, \" \").trim();\n return flat.length <= limit ? flat : `${flat.slice(0, limit - 1)}…`;\n};\n\n/** Splits a response into the document and whatever the model said before it. */\nexport const normalizeDocument = (providerName: string, text: string): NormalizedDocument => {\n const lines = scanLines(text);\n const first = lines.findIndex((line) => !line.fenced && TOP_HEADING.test(line.text));\n\n if (first === -1) {\n throw invalidContent(\n providerName,\n \"it contains no markdown heading\",\n excerpt(text, 120) || \"(empty)\",\n );\n }\n\n const dropped = lines\n .slice(0, first)\n .map((line) => line.text)\n .join(\"\\n\")\n .trim();\n\n if (dropped.length > MAX_PREAMBLE_LENGTH) {\n throw invalidContent(\n providerName,\n `${dropped.length} characters of prose precede the first heading, over the ${MAX_PREAMBLE_LENGTH} limit`,\n excerpt(dropped, 120),\n );\n }\n\n const body = lines\n .slice(first)\n .map((line) => line.text)\n .join(\"\\n\")\n .trim();\n\n return { body, preamble: dropped === \"\" ? undefined : dropped };\n};\n\nexport interface ContentProblem {\n reason : string;\n excerpt: string;\n}\n\nconst excerptAround = (text: string, index: number): string => {\n const start = Math.max(0, index - 30);\n return excerpt(text.slice(start, Math.min(text.length, index + 90)), 200);\n};\n\n/** The first conversational tell in the text, ignoring fenced code. */\nexport const findContentProblem = (text: string): ContentProblem | undefined => {\n const trimmed = text.trim();\n\n if (trimmed.length < MIN_DOCUMENT_LENGTH) {\n return {\n reason : `the response is ${trimmed.length} characters, below the ${MIN_DOCUMENT_LENGTH} minimum`,\n excerpt: excerpt(trimmed, 120),\n };\n }\n\n for (const rule of CONVERSATIONAL_RULES) {\n const match = rule.pattern.exec(trimmed);\n\n if (match !== null) {\n return { reason: rule.reason, excerpt: excerptAround(trimmed, match.index) };\n }\n }\n\n return undefined;\n};\n\n/** Throws a ProviderError when the response reads as conversation, not documentation. */\nexport const assertDocumentContent = (providerName: string, text: string): void => {\n const problem = findContentProblem(text);\n\n if (problem === undefined) return;\n\n throw invalidContent(providerName, problem.reason, problem.excerpt);\n};\n\nexport interface PreparedDocument {\n body : string;\n droppedPreamble: string | undefined;\n}\n\n/** Normalises and validates in one pass: what generate writes is what survives this. */\nexport const prepareDocument = (providerName: string, text: string): PreparedDocument => {\n const { body, preamble } = normalizeDocument(providerName, text);\n assertDocumentContent(providerName, body);\n\n return { body, droppedPreamble: preamble };\n};\n","import path from \"node:path\";\n\nimport picomatch from \"picomatch\";\nimport { GlossicConfigSchema } from \"@glossic/schema\";\nimport type { Unit } from \"@glossic/schema\";\n\nimport { scan } from \"../scan.js\";\nimport { withRetry } from \"../retry.js\";\nimport { PROMPT_VERSION } from \"../prompt.js\";\nimport { mapWithConcurrency } from \"../utils/concurrency.js\";\nimport { buildJobs, writeDoc } from \"./jobs.js\";\nimport { decide, modelCacheKey } from \"./decide.js\";\nimport { compareStrings, toPosix } from \"../utils/index.js\";\nimport { excerpt, prepareDocument } from \"../validate.js\";\nimport { INDEX_DOC_PATH, renderIndexDoc, renderUnitDoc } from \"../markdown.js\";\nimport { type CacheEntry, type CacheFile, DEFAULT_CACHE_PATH, emptyCache, indexCache, readCache, writeCache } from \"../cache.js\";\nimport type { Job } from \"./jobs.js\";\nimport type { DecisionContext } from \"./decide.js\";\nimport type { GenerateContext, GenerateEvent, GenerateFailure, GeneratePlanEntry, GenerateResult, GenerateWarning, UnitOutcome } from \"./types.js\";\n\nexport * from \"./types.js\";\nexport { modelCacheKey } from \"./decide.js\";\n\n\n/** Relative to the root and posix, because the manifest travels between machines. */\nconst docsDirOf = (root: string, outDir: string): string => {\n const relative = toPosix(path.relative(root, outDir));\n\n return relative === \"\" ? \".\" : relative;\n};\n\n\n/** One string field off an unknown error cause, for the failure report. */\nconst stringField = (cause: unknown, field: string): string | undefined => {\n if (typeof cause !== \"object\" || cause === null || !(field in cause)) {\n return undefined;\n }\n\n const value = (cause as Record<string, unknown>)[field];\n\n return typeof value === \"string\" ? value : undefined;\n};\n\n\nexport const generate = async (ctx: GenerateContext): Promise<GenerateResult> => {\n const config = ctx.config ?? GlossicConfigSchema.parse({});\n const scanned = await scan(ctx);\n const generatedAt = scanned.manifest.generatedAt;\n const root = scanned.manifest.workspace.root;\n const manifest = { ...scanned.manifest, docsDir: docsDirOf(root, ctx.outDir) };\n\n const cachePath = ctx.cachePath ?? path.resolve(root, DEFAULT_CACHE_PATH);\n const model = modelCacheKey(config);\n const previous = await readCache(cachePath);\n const previousEntries = indexCache(previous);\n\n const allJobs = await buildJobs(manifest, config, root);\n\n const matches = ctx.only === undefined ? undefined : picomatch(ctx.only);\n\n const isSelected = (job: Job): boolean =>\n matches === undefined ||\n matches(job.unit.id) ||\n matches(job.unit.name) ||\n matches(job.unit.path);\n\n const selected = allJobs.filter(isSelected);\n const filteredOut = allJobs\n .filter((job) => !isSelected(job))\n .map((job) => job.unit.id)\n .sort(compareStrings);\n\n const decisionContext: DecisionContext = {\n outDir: ctx.outDir,\n model,\n lang : config.lang,\n force: ctx.force === true,\n };\n\n const decisions = await Promise.all(\n selected.map(async (job) => ({\n job,\n reason: await decide(job, previousEntries.get(job.unit.id), decisionContext),\n })),\n );\n\n const plan: GeneratePlanEntry[] = decisions\n .map(({ job, reason }) => ({\n unitId : job.unit.id,\n docPath : job.docPath,\n files : job.unit.facts.base.files.length,\n estimatedTokens: job.estimatedTokens,\n reason,\n regenerate: reason !== \"cached\",\n }))\n .sort((a, b) => compareStrings(a.unitId, b.unitId));\n\n const sumTokens = (regenerate: boolean): number => plan\n .filter((entry) => entry.regenerate === regenerate)\n .reduce((sum, entry) => sum + entry.estimatedTokens, 0);\n\n const estimatedTokens = sumTokens(true);\n const savedTokens = sumTokens(false);\n const fromCache = plan.filter((entry) => !entry.regenerate).length;\n\n if (ctx.dryRun === true || ctx.provider === undefined) {\n return {\n manifest,\n written: [],\n plan,\n failures: [],\n warnings: [],\n filteredOut,\n estimatedTokens,\n savedTokens,\n generated: 0,\n fromCache,\n dryRun: true,\n };\n }\n\n const provider = ctx.provider;\n const failures: GenerateFailure[] = [];\n const warnings: GenerateWarning[] = [];\n const summaries = new Map<string, string>();\n const pending = decisions.filter(({ reason }) => reason !== \"cached\");\n\n const total = decisions.length;\n let completed = 0;\n\n const report = (event: GenerateEvent): void => ctx.onEvent?.(event);\n\n const finished = (unitId: string, outcome: UnitOutcome, durationMs: number): void => {\n completed += 1;\n report({ type: \"unit-done\", unitId, index: completed, total, outcome, durationMs });\n };\n\n for (const { job } of decisions.filter(({ reason }) => reason === \"cached\")) {\n report({ type: \"unit-start\", unitId: job.unit.id, index: completed + 1, total });\n finished(job.unit.id, \"cached\", 0);\n }\n\n const outcomes = await mapWithConcurrency(pending, config.concurrency, async ({ job }) => {\n const startedAt = Date.now();\n report({ type: \"unit-start\", unitId: job.unit.id, index: completed + 1, total });\n\n try {\n const completion = await withRetry(() => provider.complete(job.request), ctx.retry);\n\n const prepared = prepareDocument(provider.name, completion.text);\n\n if (prepared.droppedPreamble !== undefined) {\n warnings.push({\n unitId : job.unit.id,\n message: `dropped ${prepared.droppedPreamble.length} characters before the first heading: ${excerpt(prepared.droppedPreamble, 120)}`,\n });\n }\n\n finished(job.unit.id, \"generated\", Date.now() - startedAt);\n return { job, body: prepared.body };\n } catch (cause) {\n failures.push({\n unitId: job.unit.id,\n reason: cause instanceof Error ? cause.message: String(cause),\n code : stringField(cause, \"code\"),\n detail: stringField(cause, \"detail\"),\n });\n\n finished(job.unit.id, \"failed\", Date.now() - startedAt);\n return undefined;\n }\n });\n\n const written: string[] = [];\n const fresh: CacheEntry[] = [];\n\n for (const outcome of outcomes) {\n if (outcome === undefined) continue;\n\n await writeDoc(\n ctx.outDir,\n outcome.job.docPath,\n renderUnitDoc({\n unit : outcome.job.unit,\n project: outcome.job.project,\n body : outcome.body,\n generatedAt,\n }),\n );\n\n written.push(toPosix(outcome.job.docPath));\n summaries.set(outcome.job.unit.id, outcome.body);\n fresh.push({\n unitId : outcome.job.unit.id,\n unitHash : outcome.job.unit.hash,\n promptVersion: PROMPT_VERSION,\n model,\n lang : config.lang,\n outputPath: outcome.job.docPath,\n generatedAt,\n });\n }\n\n const merged = new Map(previousEntries);\n\n for (const entry of fresh) {\n merged.set(entry.unitId, entry);\n }\n\n const liveUnitIds = new Set(manifest.units.map((unit) => unit.id));\n\n const nextCache: CacheFile = {\n version: emptyCache().version,\n entries: [...merged.values()].filter((entry) => liveUnitIds.has(entry.unitId)),\n };\n\n await writeCache(nextCache, cachePath);\n await writeDoc(ctx.outDir, INDEX_DOC_PATH, renderIndexDoc({ manifest, generatedAt }));\n\n written.push(INDEX_DOC_PATH);\n\n const documentedUnits: Unit[] = manifest.units.map((unit) => {\n const summary = summaries.get(unit.id);\n return summary === undefined ? unit : { ...unit, summary };\n });\n\n return {\n manifest: { ...manifest, units: documentedUnits },\n written : written.sort(compareStrings),\n plan,\n failures: failures.sort((a, b) => compareStrings(a.unitId, b.unitId)),\n warnings: warnings.sort((a, b) => compareStrings(a.unitId, b.unitId)),\n filteredOut,\n estimatedTokens,\n savedTokens,\n generated: fresh.length,\n fromCache,\n dryRun: false,\n };\n};\n","import type { GlossicConfig, Provider } from \"@glossic/schema\";\n\nimport { NoProviderAvailableError, UnknownProviderError } from \"./errors.js\";\nimport { compareStrings } from \"./utils/index.js\";\n\n\n/** Auto-detection order: the local CLI first, the paid API second. */\nexport const PROVIDER_PREFERENCE = [\"claude-code\", \"anthropic\"];\n\nexport interface ResolveProviderOptions {\n providers : readonly Provider[];\n config ?: Pick<GlossicConfig, \"provider\"> | undefined;\n requested?: string | undefined;\n}\n\nexport interface ProviderStatus {\n name : string;\n available: boolean;\n}\n\n/** Providers in auto-detection order, with unknown names last and sorted. */\nconst byPreference = (providers: readonly Provider[]): Provider[] =>\n [...providers].sort((a, b) => {\n const rankA = PROVIDER_PREFERENCE.indexOf(a.name);\n const rankB = PROVIDER_PREFERENCE.indexOf(b.name);\n\n if (rankA !== rankB) {\n if (rankA === -1) return 1;\n if (rankB === -1) return -1;\n\n return rankA - rankB;\n }\n\n return compareStrings(a.name, b.name);\n });\n\n/** Asks every provider whether it can run, in preference order. Never throws. */\nexport const probeProviders = async (providers: readonly Provider[]): Promise<ProviderStatus[]> =>\n Promise.all(\n byPreference(providers).map(async (provider) => ({\n name : provider.name,\n available: await provider.available().catch(() => false),\n })),\n );\n\n\n/**\n * The provider to use: the one named by a flag or the config, otherwise the\n * first one available in preference order.\n */\nexport const resolveProvider = async (options: ResolveProviderOptions): Promise<Provider> => {\n const known = options.providers.map((provider) => provider.name);\n const explicit = options.requested ?? options.config?.provider;\n\n if (explicit !== undefined && explicit !== \"\") {\n const match = options.providers.find((provider) => provider.name === explicit);\n\n if (match === undefined) {\n throw new UnknownProviderError(explicit, known);\n }\n\n return match;\n }\n\n for (const provider of byPreference(options.providers)) {\n if (await provider.available().catch(() => false)) {\n return provider;\n }\n }\n\n throw new NoProviderAvailableError(known);\n};\n","import type { Adapter, Provider } from \"@glossic/schema\";\n\n/** A name-keyed collection of adapters or providers, kept in insertion order. */\nexport class Registry<T extends { name: string }> {\n readonly #items = new Map<string, T>();\n\n register(item: T): this {\n this.#items.set(item.name, item);\n return this;\n }\n\n get(name: string): T | undefined {\n return this.#items.get(name);\n }\n\n has(name: string): boolean {\n return this.#items.has(name);\n }\n\n list(): T[] {\n return [...this.#items.values()];\n }\n\n get size(): number {\n return this.#items.size;\n }\n}\n\nexport type AdapterRegistry = Registry<Adapter>;\nexport type ProviderRegistry = Registry<Provider>;\n\nexport const createAdapterRegistry = (adapters: Adapter[] = []): AdapterRegistry => {\n const registry = new Registry<Adapter>();\n\n for (const adapter of adapters) {\n registry.register(adapter);\n }\n\n return registry;\n};\n\nexport const createProviderRegistry = (providers: Provider[] = []): ProviderRegistry => {\n const registry = new Registry<Provider>();\n\n for (const provider of providers) {\n registry.register(provider);\n }\n\n return registry;\n};\n","import type { CompletionRequest, CompletionResult, Provider } from \"@glossic/schema\";\n\n/** A provider that records what it was asked, for assertions. */\nexport interface FakeProvider extends Provider {\n readonly calls: CompletionRequest[];\n}\n\nexport interface FakeProviderOptions {\n name ?: string;\n available?: boolean;\n respond ?: (request: CompletionRequest, index: number) => string;\n}\n\n\nconst defaultDocument = (request: CompletionRequest, index: number): string =>\n [\n \"## What it does\",\n \"\",\n `Fake documentation number ${index} for ${String(request.metadata.unitId ?? \"a unit\")}.`,\n \"\",\n \"## Responsibilities\",\n \"\",\n \"The unit owns its own behaviour and delegates everything else to its\",\n \"neighbours. Nothing here reaches outside the boundary it declares.\",\n \"\",\n \"## Public elements\",\n \"\",\n \"- Everything the unit exports, described in one line each.\",\n \"\",\n \"## Architectural decisions\",\n \"\",\n \"Dependencies point one way, errors are typed, and the ordering is total.\",\n ].join(\"\\n\");\n\n\n/** A provider that answers from memory, so a test can drive the pipeline end to end. */\nexport const createFakeProvider = (options: FakeProviderOptions = {}): FakeProvider => {\n const calls: CompletionRequest[] = [];\n\n return {\n name: options.name ?? \"fake\",\n calls,\n available: async () : Promise<boolean> => options.available ?? true,\n complete : async (request: CompletionRequest): Promise<CompletionResult> => {\n const index = calls.length;\n calls.push(request);\n\n const text = options.respond?.(request, index) ?? defaultDocument(request, index);\n return { text, model: \"fake-model\", usage: { inputTokens: 10, outputTokens: 5 } };\n },\n };\n};\n","import manifest from \"../package.json\" with { type: \"json\" };\n\nexport const CORE_VERSION: string = manifest.version;\n\nexport * from \"./cache.js\";\nexport * from \"./check.js\";\nexport * from \"./config-file.js\";\nexport * from \"./config-resolve.js\";\nexport * from \"./errors.js\";\nexport * from \"./generate/index.js\";\nexport * from \"./manifest.js\";\nexport * from \"./markdown.js\";\nexport * from \"./prompt.js\";\nexport * from \"./provider.js\";\nexport * from \"./registry.js\";\nexport * from \"./retry.js\";\nexport * from \"./scan.js\";\nexport * from \"./testing.js\";\nexport * from \"./utils/index.js\";\nexport * from \"./validate.js\";\nexport * from \"./workspace.js\";\n"]}
1
+ {"version":3,"sources":["../package.json","../src/utils/fs.ts","../src/cache.ts","../src/manifest.ts","../src/workspace.ts","../src/scan.ts","../src/markdown.ts","../src/check.ts","../src/config-file.ts","../src/config-resolve.ts","../src/errors.ts","../src/retry.ts","../src/prompt.ts","../src/utils/concurrency.ts","../src/generate/jobs.ts","../src/generate/decide.ts","../src/validate.ts","../src/generate/index.ts","../src/provider.ts","../src/registry.ts","../src/testing.ts","../src/index.ts"],"names":["fs","path","parseYaml","glob","GlossicConfigSchema","fence","plan"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"name\": \"@glossic/core\",\n \"version\": \"0.3.0\",\n \"description\": \"Glossic orchestration core: registries, pipeline and manifest plumbing\",\n \"keywords\": [\n \"documentation\",\n \"docs\",\n \"docs-as-code\",\n \"glossic\",\n \"orchestration\",\n \"pipeline\",\n \"manifest\",\n \"incremental\",\n \"cache\"\n ],\n \"license\": \"MIT\",\n \"author\": \"Rody Huancas\",\n \"homepage\": \"https://github.com/rody-huancas/glossic#readme\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rody-huancas/glossic.git\",\n \"directory\": \"packages/core\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/rody-huancas/glossic/issues\"\n },\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=20\"\n },\n \"files\": [\n \"dist\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@glossic/schema\": \"workspace:*\",\n \"jiti\": \"^2.6.1\",\n \"picomatch\": \"^4.0.3\",\n \"tinyglobby\": \"^0.2.15\",\n \"yaml\": \"^2.8.1\",\n \"zod\": \"^4.1.5\"\n }\n}\n","import fs from \"node:fs/promises\";\n\n/** True when the path can be reached; never throws. */\nexport const pathExists = async (target: string): Promise<boolean> => {\n try {\n await fs.access(target);\n return true;\n } catch {\n return false;\n }\n};\n\n/** File contents, or undefined when it cannot be read. */\nexport const readText = async (target: string): Promise<string | undefined> => {\n try {\n return await fs.readFile(target, \"utf8\");\n } catch {\n return undefined;\n }\n};\n\n/** Parsed JSON, or undefined when the file is missing or malformed. */\nexport const readJson = async <T>(target: string): Promise<T | undefined> => {\n const raw = await readText(target);\n \n if (raw === undefined) {\n return undefined;\n }\n\n try {\n return JSON.parse(raw) as T;\n } catch {\n return undefined;\n }\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport { sortBy } from \"./utils/index.js\";\n\nexport const DEFAULT_CACHE_PATH = \".glossic/cache.json\";\n/** Bumped by hand when the entry shape changes; a mismatch discards the whole file. */\nexport const CACHE_VERSION = \"1\";\n\n/** What a unit was documented from, so the next run can tell whether anything moved. */\nexport const CacheEntrySchema = z.object({\n unitId : z.string().min(1),\n unitHash : z.string().min(1),\n promptVersion: z.string().min(1),\n model : z.string().min(1),\n lang : z.string().min(1),\n outputPath : z.string().min(1),\n generatedAt : z.string().min(1),\n});\nexport type CacheEntry = z.infer<typeof CacheEntrySchema>;\n\nexport const CacheFileSchema = z.object({\n version: z.string().min(1),\n entries: z.array(CacheEntrySchema),\n});\nexport type CacheFile = z.infer<typeof CacheFileSchema>;\n\nexport const emptyCache = (): CacheFile => ({ version: CACHE_VERSION, entries: [] });\n\n\n/** Reads the cache, returning an empty one for a missing, corrupt or outdated file. */\nexport const readCache = async (target: string): Promise<CacheFile> => {\n try {\n const raw = await fs.readFile(path.resolve(target), \"utf8\");\n const parsed = CacheFileSchema.parse(JSON.parse(raw));\n\n return parsed.version === CACHE_VERSION ? parsed : emptyCache();\n } catch {\n return emptyCache();\n }\n};\n\n/** JSON with the entries sorted by unit id, so the file does not churn between runs. */\nexport const serializeCache = (cache: CacheFile): string => {\n return `${JSON.stringify({ ...cache, entries: sortBy(cache.entries, (entry) => entry.unitId) }, null, 2)}\\n`;\n}\n\n/** Writes the cache, creating its directory. Returns the absolute path written. */\nexport const writeCache = async (cache: CacheFile, target: string): Promise<string> => {\n const absolute = path.resolve(target);\n\n await fs.mkdir(path.dirname(absolute), { recursive: true });\n await fs.writeFile(absolute, serializeCache(cache), \"utf8\");\n\n return absolute;\n};\n\n/** Entries keyed by unit id, for lookups while deciding what to regenerate. */\nexport const indexCache = (cache: CacheFile): Map<string, CacheEntry> => {\n return new Map(cache.entries.map((entry) => [entry.unitId, entry]));\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { ExtractResult, Manifest, Relation, Unit, Workspace } from \"@glossic/schema\";\nimport { MANIFEST_VERSION, ManifestSchema } from \"@glossic/schema\";\n\nimport { compareStrings, sortBy } from \"./utils/index.js\";\n\nexport const DEFAULT_MANIFEST_PATH = \".glossic/manifest.json\";\n\nexport interface BuildManifestOptions {\n generatedAt?: string;\n}\n\n/** Sorts everything inside one unit, so its hash does not depend on walk order. */\nconst sortUnit = (unit: Unit): Unit => ({\n ...unit,\n facts: {\n ...unit.facts,\n base: {\n ...unit.facts.base,\n files : sortBy(unit.facts.base.files, (file) => file.path),\n languages: [...unit.facts.base.languages].sort(\n (a, b) => b.count - a.count || compareStrings(a.language, b.language),\n ),\n },\n producedBy: [...unit.facts.producedBy].sort(compareStrings),\n },\n});\n\nconst compareRelations = (a: Relation, b: Relation): number => {\n return compareStrings(a.from, b.from) || compareStrings(a.to, b.to) || compareStrings(a.kind, b.kind);\n}\n\n\n/** Assembles the manifest, sorting every list so two runs over the same code match. */\nexport const buildManifest = (workspace: Workspace, results: readonly ExtractResult[], options: BuildManifestOptions = {}): Manifest => {\n const units = results.flatMap((result) => result.units).map(sortUnit);\n const relations = results.flatMap((result) => result.relations);\n\n return ManifestSchema.parse({\n version : MANIFEST_VERSION,\n generatedAt: options.generatedAt ?? new Date().toISOString(),\n workspace : {\n ...workspace,\n projects: sortBy(workspace.projects, (project) => project.id),\n },\n units : sortBy(units, (unit) => unit.id),\n relations: [...relations].sort(compareRelations),\n });\n};\n\n/** The manifest as it lands on disk: JSON, two-space indent, trailing newline. */\nexport const serializeManifest = (manifest: Manifest): string => {\n return `${JSON.stringify(manifest, null, 2)}\\n`;\n}\n\n\n/** Writes the manifest, creating its directory. Returns the absolute path written. */\nexport const writeManifest = async (manifest: Manifest, target: string): Promise<string> => {\n const absolute = path.resolve(target);\n\n await fs.mkdir(path.dirname(absolute), { recursive: true });\n await fs.writeFile(absolute, serializeManifest(manifest), \"utf8\");\n \n return absolute;\n};\n\n/** Reads and validates a manifest, or undefined when it is missing or invalid. */\nexport const readManifest = async (target: string): Promise<Manifest | undefined> => {\n try {\n const raw = await fs.readFile(path.resolve(target), \"utf8\");\n return ManifestSchema.parse(JSON.parse(raw));\n } catch {\n return undefined;\n }\n};\n","import path from \"node:path\";\nimport type { Project, Workspace, WorkspaceTool } from \"@glossic/schema\";\nimport { glob } from \"tinyglobby\";\nimport { parse as parseYaml } from \"yaml\";\n\nimport { pathExists, readJson, readText, sortBy, toPosix } from \"./utils/index.js\";\n\ninterface PackageJson {\n name ?: string;\n packageManager?: string;\n workspaces ?: string[] | { packages?: string[] };\n}\n\ninterface MonorepoMarker {\n tool : WorkspaceTool;\n globs: string[];\n}\n\nconst GLOB_IGNORES = [\"**/node_modules/**\", \"**/dist/**\", \"**/build/**\", \"**/.git/**\"];\n\nconst LOCKFILE_PACKAGE_MANAGERS: ReadonlyArray<readonly [string, string]> = [\n [\"pnpm-lock.yaml\", \"pnpm\"],\n [\"yarn.lock\", \"yarn\"],\n [\"package-lock.json\", \"npm\"],\n [\"bun.lock\", \"bun\"],\n [\"bun.lockb\", \"bun\"],\n [\"composer.lock\", \"composer\"],\n [\"composer.json\", \"composer\"],\n];\n\nconst asStringArray = (value: unknown): string[] =>\n Array.isArray(value) ? value.filter((item): item is string => typeof item === \"string\") : [];\n\n/** The package manager in use, from the packageManager field or from the lockfile. */\nconst detectPackageManager = async (dir: string, pkg: PackageJson | undefined): Promise<string | undefined> => {\n const declared = pkg?.packageManager;\n\n if (typeof declared === \"string\" && declared.length > 0) {\n const [name] = declared.split(\"@\");\n\n if (name !== undefined && name.length > 0) {\n return name;\n }\n }\n\n for (const [lockfile, manager] of LOCKFILE_PACKAGE_MANAGERS) {\n if (await pathExists(path.join(dir, lockfile))) {\n return manager;\n }\n }\n\n return undefined;\n};\n\n\n/** The monorepo tool and the globs defining its projects, when this repo is one. */\nconst detectMonorepo = async (root: string, pkg: PackageJson | undefined): Promise<MonorepoMarker | undefined> => {\n const pnpmWorkspace = await readText(path.join(root, \"pnpm-workspace.yaml\"));\n\n if (pnpmWorkspace !== undefined) {\n const parsed: unknown = parseYaml(pnpmWorkspace);\n const globs = asStringArray((parsed as { packages?: unknown } | null)?.packages);\n\n if (globs.length > 0) {\n return { tool: \"pnpm\", globs };\n }\n }\n\n const workspaces = Array.isArray(pkg?.workspaces) ? pkg.workspaces : asStringArray(pkg?.workspaces?.packages);\n\n if (workspaces.length > 0) {\n return { tool: \"npm-workspaces\", globs: workspaces };\n }\n\n if (await pathExists(path.join(root, \"turbo.json\"))) {\n return { tool: \"turbo\", globs: [\"apps/*\", \"packages/*\"] };\n }\n\n if (await pathExists(path.join(root, \"nx.json\"))) {\n return { tool: \"nx\", globs: [\"apps/*\", \"libs/*\", \"packages/*\"] };\n }\n\n const lerna = await readJson<{ packages?: unknown }>(path.join(root, \"lerna.json\"));\n\n if (lerna !== undefined) {\n const globs = asStringArray(lerna.packages);\n return { tool: \"lerna\", globs: globs.length > 0 ? globs : [\"packages/*\"] };\n }\n\n return undefined;\n};\n\nconst expandProjectDirs = async (root: string, globs: string[]): Promise<string[]> => {\n const patterns: string[] = [];\n const ignore = [...GLOB_IGNORES];\n\n for (const entry of globs) {\n if (entry.startsWith(\"!\")) {\n ignore.push(`${entry.slice(1)}/**`);\n continue;\n }\n \n patterns.push(`${entry}/package.json`);\n }\n\n if (patterns.length === 0) return [];\n\n const manifests = await glob({\n patterns,\n cwd: root,\n ignore,\n onlyFiles : true,\n followSymbolicLinks: false,\n dot : false,\n });\n\n const dirs = manifests.map((manifest) => toPosix(path.posix.dirname(toPosix(manifest))));\n\n return [...new Set(dirs)].sort();\n};\n\nconst buildProject = async (root: string, rootDir: string, fallbackManager: string | undefined): Promise<Project> => {\n const dir = path.resolve(root, rootDir);\n const pkg = await readJson<PackageJson>(path.join(dir, \"package.json\"));\n const packageManager = (await detectPackageManager(dir, pkg)) ?? fallbackManager;\n const name = pkg?.name ?? path.basename(dir);\n\n const project: Project = {\n id: rootDir === \".\" ? \"root\" : rootDir,\n name,\n rootDir,\n };\n\n return packageManager === undefined ? project : { ...project, packageManager };\n};\n\n\n/** Identifies the repository and lists its projects, monorepo or not. */\nexport const resolveWorkspace = async (root: string): Promise<Workspace> => {\n const absoluteRoot = path.resolve(root);\n const pkg = await readJson<PackageJson>(path.join(absoluteRoot, \"package.json\"));\n const packageManager = await detectPackageManager(absoluteRoot, pkg);\n const name = pkg?.name ?? path.basename(absoluteRoot);\n\n const marker = await detectMonorepo(absoluteRoot, pkg);\n const projectDirs = marker === undefined ? [] : await expandProjectDirs(absoluteRoot, marker.globs);\n\n const isMonorepo = projectDirs.length > 0;\n const rootDirs = isMonorepo ? projectDirs : [\".\"];\n const projects = await Promise.all(\n rootDirs.map((rootDir) => buildProject(absoluteRoot, rootDir, packageManager)),\n );\n\n const workspace: Workspace = {\n name,\n root: toPosix(absoluteRoot),\n isMonorepo,\n tool : isMonorepo && marker !== undefined ? marker.tool: \"none\",\n projects: sortBy(projects, (project) => project.id),\n };\n\n return packageManager === undefined ? workspace : { ...workspace, packageManager };\n};\n","import path from \"node:path\";\n\nimport { GlossicConfigSchema } from \"@glossic/schema\";\nimport type { Adapter, AdapterContext, DiscoverContext, ExtractResult, GlossicConfig, Manifest, Workspace } from \"@glossic/schema\";\n\nimport { buildManifest } from \"./manifest.js\";\nimport { resolveWorkspace } from \"./workspace.js\";\n\n/** What every pipeline stage needs: where to scan, with which adapters and config. */\nexport interface PipelineContext {\n root : string;\n adapters : readonly Adapter[];\n config ?: GlossicConfig;\n generatedAt?: string;\n}\n\nexport interface ScanResult {\n manifest : Manifest;\n workspace : Workspace;\n adapterByProject: Record<string, string>;\n}\n\n\n/** Puts the adapters in the order the config asks for, dropping the ones it omits. */\nexport const orderAdapters = (adapters: readonly Adapter[], wanted: readonly string[]): Adapter[] => {\n const byName = new Map(adapters.map((adapter) => [adapter.name, adapter]));\n\n return wanted\n .map((name) => byName.get(name))\n .filter((adapter): adapter is Adapter => adapter !== undefined);\n};\n\n/** The first adapter that claims the project. */\nconst selectAdapter = async (adapters: readonly Adapter[], ctx: DiscoverContext): Promise<Adapter | undefined> => {\n for (const adapter of adapters) {\n if (await adapter.detect(ctx)) {\n return adapter;\n }\n }\n\n return undefined;\n};\n\n\n/** Walks the workspace and turns it into a manifest, calling no provider. */\nexport const scan = async (ctx: PipelineContext): Promise<ScanResult> => {\n const config = ctx.config ?? GlossicConfigSchema.parse({});\n const workspace = await resolveWorkspace(path.resolve(ctx.root));\n const adapters = orderAdapters(ctx.adapters, config.adapters);\n const adapterContext: AdapterContext = { root: workspace.root, workspace, config };\n\n const results: ExtractResult[] = [];\n const adapterByProject: Record<string, string> = {};\n\n for (const project of workspace.projects) {\n const discoverContext: DiscoverContext = { ...adapterContext, project };\n const adapter = await selectAdapter(adapters, discoverContext);\n\n if (adapter === undefined) continue;\n\n adapterByProject[project.id] = adapter.name;\n\n const units = await adapter.discover(discoverContext);\n \n results.push(await adapter.extract({ ...discoverContext, units }));\n }\n\n const manifest = buildManifest(\n workspace,\n results,\n ctx.generatedAt === undefined ? {} : { generatedAt: ctx.generatedAt },\n );\n\n return { manifest, workspace, adapterByProject };\n};\n","import type { Manifest, Project, Unit } from \"@glossic/schema\";\n\nimport { compareStrings } from \"./utils/index.js\";\n\n/** Where a unit's page goes, relative to the output directory. */\nexport const unitDocPath = (unit: Unit): string => {\n return unit.path === \".\" ? \"root.md\" : `${unit.path}.md`;\n}\n\nexport const INDEX_DOC_PATH = \"index.md\";\n\nconst frontmatter = (entries: ReadonlyArray<readonly [string, string | number]>): string =>\n [\n \"---\",\n ...entries.map(([key, value]) =>\n typeof value === \"number\" ? `${key}: ${value}` : `${key}: ${JSON.stringify(value)}`,\n ),\n \"---\",\n ].join(\"\\n\");\n\nexport interface RenderUnitDocInput {\n unit : Unit;\n project : Project;\n body : string;\n generatedAt: string;\n}\n\n\n/** One unit's page: frontmatter carrying the hash, then the prose the provider wrote. */\nexport const renderUnitDoc = (input: RenderUnitDocInput): string => {\n const { unit } = input;\n const title = unit.name === \"root\" ? input.project.name : unit.name;\n\n const entries: Array<readonly [string, string | number]> = [\n [\"title\", title],\n [\"unit\", unit.id],\n [\"project\", unit.projectId],\n [\"path\", unit.path],\n [\"hash\", unit.hash],\n [\"files\", unit.facts.base.files.length],\n [\"generatedAt\", input.generatedAt],\n ];\n\n if (unit.facts.base.roleHint !== null) {\n entries.splice(4, 0, [\"role\", unit.facts.base.roleHint]);\n }\n\n return [frontmatter(entries), \"\", input.body.trim(), \"\"].join(\"\\n\");\n};\n\nexport interface RenderIndexDocInput {\n manifest : Manifest;\n generatedAt: string;\n}\n\nconst languageSummary = (units: readonly Unit[]): string => {\n const totals = new Map<string, number>();\n\n for (const unit of units) {\n for (const entry of unit.facts.base.languages) {\n totals.set(entry.language, (totals.get(entry.language) ?? 0) + entry.count);\n }\n }\n\n return [...totals.entries()]\n .sort(([aLang, aCount], [bLang, bCount]) => bCount - aCount || compareStrings(aLang, bLang))\n .map(([language, count]) => `${language} (${count})`)\n .join(\", \");\n};\n\n\n/** The index page listing every unit in the workspace. */\nexport const renderIndexDoc = (input: RenderIndexDocInput): string => {\n const { manifest } = input;\n const { workspace, units } = manifest;\n\n const lines: string[] = [\n frontmatter([\n [\"title\", workspace.name],\n [\"generatedAt\", input.generatedAt],\n [\"units\", units.length],\n ]),\n \"\",\n `# ${workspace.name}`,\n \"\",\n workspace.isMonorepo\n ? `${workspace.tool} monorepo with ${workspace.projects.length} projects.`\n : \"Single-project workspace.\",\n \"\",\n ];\n\n for (const project of workspace.projects) {\n const projectUnits = units.filter((unit) => unit.projectId === project.id);\n\n lines.push(`## ${project.name}`, \"\");\n\n if (projectUnits.length === 0) {\n lines.push(\"No documented units.\", \"\");\n continue;\n }\n\n for (const unit of projectUnits) {\n const role = unit.facts.base.roleHint;\n const suffix = role === null ? \"\" : ` — ${role}`;\n\n lines.push(\n `- [${unit.name}](./${unitDocPath(unit)}) — ${unit.facts.base.files.length} files${suffix}`,\n );\n }\n lines.push(\"\");\n }\n\n const languages = languageSummary(units);\n\n if (languages !== \"\") {\n lines.push(`Languages: ${languages}`, \"\");\n }\n\n return lines.join(\"\\n\");\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { Manifest } from \"@glossic/schema\";\nimport { glob } from \"tinyglobby\";\nimport { parse as parseYaml } from \"yaml\";\n\nimport { scan } from \"./scan.js\";\nimport { INDEX_DOC_PATH, unitDocPath } from \"./markdown.js\";\nimport { compareStrings, sortBy, toPosix } from \"./utils/index.js\";\nimport type { PipelineContext } from \"./scan.js\";\n\nexport interface CheckContext extends PipelineContext {\n outDir: string;\n}\n\n/** One unit weighed against its page: the hash expected against the one on disk. */\nexport interface CheckEntry {\n unitId : string;\n docPath : string;\n expectedHash : string;\n documentedHash: string | undefined;\n}\n\nexport interface CheckResult {\n outDir : string;\n upToDate: CheckEntry[];\n missing : CheckEntry[];\n stale : CheckEntry[];\n orphaned: string[];\n ok : boolean;\n}\n\ninterface DocumentFrontmatter {\n unit: string | undefined;\n hash: string | undefined;\n}\n\nconst FRONTMATTER = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n/;\n\n/** The frontmatter of a generated page, empty when the file carries none. */\nexport const readDocFrontmatter = async (file: string): Promise<DocumentFrontmatter> => {\n try {\n const raw = await fs.readFile(file, \"utf8\");\n const match = FRONTMATTER.exec(raw);\n\n if (match === null) {\n return { unit: undefined, hash: undefined };\n }\n\n const parsed: unknown = parseYaml(match[1] ?? \"\");\n \n if (typeof parsed !== \"object\" || parsed === null) {\n return { unit: undefined, hash: undefined };\n }\n\n const record = parsed as Record<string, unknown>;\n\n return {\n unit: typeof record.unit === \"string\" ? record.unit : undefined,\n hash: typeof record.hash === \"string\" ? record.hash : undefined,\n };\n } catch {\n return { unit: undefined, hash: undefined };\n }\n};\n\n/** Every markdown page under the output directory, as posix paths. */\nconst listDocs = async (outDir: string): Promise<string[]> => {\n try {\n const entries = await glob({\n patterns : [\"**/*.md\"],\n cwd : outDir,\n onlyFiles : true,\n followSymbolicLinks: false,\n });\n\n return entries.map(toPosix).sort(compareStrings);\n } catch {\n return [];\n }\n};\n\n\n/**\n * Compares the pages on disk against a fresh scan, calling no provider. This\n * is what a CI job runs to fail on documentation nobody regenerated.\n */\nexport const check = async (ctx: CheckContext): Promise<CheckResult> => {\n const { manifest }: { manifest: Manifest } = await scan(ctx);\n\n const docs = await listDocs(ctx.outDir);\n const expected = new Map(manifest.units.map((unit) => [unitDocPath(unit), unit]));\n\n const upToDate: CheckEntry[] = [];\n const missing : CheckEntry[] = [];\n const stale : CheckEntry[] = [];\n\n for (const unit of manifest.units) {\n const docPath = unitDocPath(unit);\n const entryBase = { unitId: unit.id, docPath, expectedHash: unit.hash };\n\n if (!docs.includes(docPath)) {\n missing.push({ ...entryBase, documentedHash: undefined });\n continue;\n }\n\n const { hash } = await readDocFrontmatter(path.resolve(ctx.outDir, docPath));\n\n if (hash === unit.hash) {\n upToDate.push({ ...entryBase, documentedHash: hash });\n } else {\n stale.push({ ...entryBase, documentedHash: hash });\n }\n }\n\n const orphaned = docs\n .filter((doc) => doc !== INDEX_DOC_PATH && !expected.has(doc))\n .sort(compareStrings);\n\n const byUnitId = (entries: CheckEntry[]): CheckEntry[] => {\n return sortBy(entries, (entry) => entry.unitId);\n }\n\n return {\n outDir : toPosix(ctx.outDir),\n upToDate: byUnitId(upToDate),\n missing : byUnitId(missing),\n stale : byUnitId(stale),\n orphaned,\n ok: missing.length === 0 && stale.length === 0 && orphaned.length === 0,\n };\n};\n","import path from \"node:path\";\n\nimport { createJiti } from \"jiti\";\nimport { GlossicConfigSchema } from \"@glossic/schema\";\nimport type { GlossicUserConfig } from \"@glossic/schema\";\n\nimport { pathExists, toPosix } from \"./utils/index.js\";\n\n/** Config filenames, in the order they are looked for. */\nexport const CONFIG_FILENAMES = [\n \"glossic.config.ts\",\n \"glossic.config.mts\",\n \"glossic.config.js\",\n \"glossic.config.mjs\",\n];\n\n\n/** Posix path of the project's config file, when it has one. */\nexport const findConfigFile = async (root: string): Promise<string | undefined> => {\n for (const filename of CONFIG_FILENAMES) {\n const candidate = path.resolve(root, filename);\n if (await pathExists(candidate)) {\n return toPosix(candidate);\n }\n }\n\n return undefined;\n};\n\n/** The project has no config file at all. */\nexport interface MissingConfig {\n status: \"missing\";\n}\n\n/** The file is there but unusable, and `error` is the reason to put in front of the user. */\nexport interface FailedConfig {\n status: \"failed\";\n file : string;\n error : string;\n}\n\n/** `values` carries only the keys the file actually set, so a no-op config leaves it empty. */\nexport interface LoadedConfig {\n status: \"loaded\";\n file : string;\n values: GlossicUserConfig;\n}\n\n/** The three things a config file can be, so a missing file never reads as a broken one. */\nexport type ProjectConfig = MissingConfig | FailedConfig | LoadedConfig;\n\n/** The reason ends up on one terminal line, so the stack and the rest of the message go. */\nconst describeError = (cause: unknown): string => {\n const message = cause instanceof Error ? cause.message : String(cause);\n\n return message.split(\"\\n\")[0]?.trim() || \"unknown error\";\n};\n\n/** The module's default export as a config, or why it is not one. */\nconst readDefaultExport = (file: string, value: unknown): FailedConfig | LoadedConfig => {\n const parsed = GlossicConfigSchema.partial().safeParse(value);\n\n if (!parsed.success) {\n const error = parsed.error.issues\n .map((issue) =>\n issue.path.length === 0 ? issue.message : `${issue.path.join(\".\")}: ${issue.message}`,\n )\n .join(\"; \");\n\n return { status: \"failed\", file, error };\n }\n\n const declared = Object.keys(value as Record<string, unknown>);\n\n const values = Object.fromEntries(\n Object.entries(parsed.data).filter(([key]) => declared.includes(key)),\n ) as GlossicUserConfig;\n\n return { status: \"loaded\", file, values };\n};\n\n\n/** Never throws: a config that cannot be loaded is reported as such, not hidden. */\nexport const loadProjectConfig = async (root: string): Promise<ProjectConfig> => {\n const file = await findConfigFile(root);\n\n if (file === undefined) {\n return { status: \"missing\" };\n }\n\n try {\n const jiti = createJiti(import.meta.url, { moduleCache: false });\n const loaded = await jiti.import(file, { default: true });\n\n return readDefaultExport(file, loaded);\n } catch (cause) {\n return { status: \"failed\", file, error: describeError(cause) };\n }\n};\n","import type { GlossicConfig, GlossicUserConfig } from \"@glossic/schema\";\nimport { GlossicConfigSchema } from \"@glossic/schema\";\n\n/** Which source decided one option's value; `glossic doctor` prints it. */\nexport type ConfigOrigin = \"flag\" | \"project\" | \"preference\" | \"default\";\n\nexport type ConfigOrigins = Record<string, ConfigOrigin>;\n\nexport interface ConfigSources {\n flags ?: GlossicUserConfig | undefined;\n project ?: GlossicUserConfig | undefined;\n preference?: GlossicUserConfig | undefined;\n}\n\nexport interface ResolvedConfig {\n config : GlossicConfig;\n origins: ConfigOrigins;\n}\n\nconst ORDER: ReadonlyArray<[\"flag\" | \"project\" | \"preference\", keyof ConfigSources]> = [\n [\"flag\", \"flags\"],\n [\"project\", \"project\"],\n [\"preference\", \"preference\"],\n];\n\nconst isSet = (value: unknown): boolean => {\n return value !== undefined && !(typeof value === \"string\" && value.trim() === \"\");\n}\n\n\n/**\n * Merges the sources under one precedence chain (flags, project config, saved\n * preference, schema defaults) and records which one won each key.\n */\nexport const resolveConfig = (sources: ConfigSources = {}): ResolvedConfig => {\n const merged : Record<string, unknown> = {};\n const origins: ConfigOrigins = {};\n\n for (const [origin, key] of [...ORDER].reverse()) {\n const source = sources[key];\n\n if (source === undefined) continue;\n\n for (const [name, value] of Object.entries(source)) {\n if (!isSet(value)) continue;\n\n merged[name] = value;\n origins[name] = origin;\n }\n }\n\n const config = GlossicConfigSchema.parse(merged);\n\n for (const name of Object.keys(config)) {\n origins[name] ??= \"default\";\n }\n\n return { config, origins };\n};\n\n\n/** The options that change how files become units, and so invalidate a scan. */\nexport const GROUPING_KEYS = [\n \"include\",\n \"exclude\",\n \"ignoreUnits\",\n \"excludeFromContent\",\n \"mergeChildrenInto\",\n \"minUnitFiles\",\n \"maxUnitFiles\",\n] as const;\n","/** Placeholder for a code path that is scaffolded but not written yet. */\nexport class NotImplementedError extends Error {\n constructor(what: string) {\n super(`${what} is not implemented`);\n this.name = \"NotImplementedError\";\n }\n}\n\n\n/**\n * Nothing on this machine can write prose. The message is the install\n * instructions, because this is the first wall a new user hits.\n */\nexport class NoProviderAvailableError extends Error {\n readonly tried: string[];\n\n constructor(tried: readonly string[]) {\n super(\n [\n \"No LLM provider is available.\",\n \"\",\n \"glossic needs one of these two:\",\n \"\",\n \" 1. Claude Code — install the CLI and sign in:\",\n \" https://claude.com/claude-code\",\n \" glossic picks it up as soon as `claude --version` works.\",\n \"\",\n \" 2. Anthropic API — export an API key:\",\n \" export ANTHROPIC_API_KEY=sk-ant-...\",\n \" https://console.anthropic.com/settings/keys\",\n \"\",\n \"Run `glossic doctor` to see what glossic can find on this machine.\",\n ].join(\"\\n\"),\n );\n this.name = \"NoProviderAvailableError\";\n this.tried = [...tried];\n }\n}\n\n/** The provider named by a flag or by the config does not exist. */\nexport class UnknownProviderError extends Error {\n constructor(requested: string, known: readonly string[]) {\n super(`unknown provider \"${requested}\". Available: ${[...known].sort().join(\", \")}`);\n this.name = \"UnknownProviderError\";\n }\n}\n","import { isRetryableProviderError } from \"@glossic/schema\";\n\n/** `sleep` and `onRetry` exist so a test can drive the loop without waiting. */\nexport interface RetryOptions {\n attempts ?: number;\n baseDelayMs?: number;\n sleep ?: (ms: number) => Promise<void>;\n onRetry ?: (attempt: number, error: unknown) => void;\n}\n\nconst DEFAULT_ATTEMPTS = 3;\nconst DEFAULT_BASE_DELAY_MS = 500;\n\nconst defaultSleep = (ms: number): Promise<void> => {\n return new Promise((resolve) => {\n setTimeout(resolve, ms).unref?.();\n });\n}\n\n\n/** Exponential backoff: the delay doubles with every attempt. */\nexport const backoffDelay = (attempt: number, baseDelayMs: number): number => {\n return baseDelayMs * 2 ** (attempt - 1);\n}\n\n\n/** Runs a task again while it fails with a retryable provider error. */\nexport const withRetry = async <T>(task: () => Promise<T>, options: RetryOptions = {}): Promise<T> => {\n const attempts = options.attempts ?? DEFAULT_ATTEMPTS;\n const baseDelayMs = options.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;\n const sleep = options.sleep ?? defaultSleep;\n\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= attempts; attempt += 1) {\n try {\n return await task();\n } catch (error) {\n lastError = error;\n\n if (attempt === attempts || !isRetryableProviderError(error)) {\n throw error;\n }\n\n options.onRetry?.(attempt, error);\n\n await sleep(backoffDelay(attempt, baseDelayMs));\n }\n }\n\n throw lastError;\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { CompletionRequest, Project, Unit } from \"@glossic/schema\";\nimport { compareStrings } from \"./utils/index.js\";\n\n/** A file longer than this is truncated before it goes into a prompt. */\nexport const MAX_FILE_BYTES = 24_000;\n\nconst CHARS_PER_TOKEN = 4;\n\nexport interface UnitSource {\n path : string;\n language : string;\n content : string;\n truncated: boolean;\n}\n\nexport interface BuildPromptInput {\n unit : Unit;\n project : Project;\n workspaceName : string;\n sources : readonly UnitSource[];\n lang : string;\n model ?: string | undefined;\n temperature ?: number | undefined;\n}\n\n\n/** Bumped by hand when the prompt changes, which invalidates every cached unit. */\nexport const PROMPT_VERSION = \"4\";\n\n/** The rules the model is held to; assertDocumentContent checks the answer against them. */\nexport const SYSTEM_PROMPT = [\n \"You are a technical writer documenting a codebase for the engineers who work on it.\",\n \"\",\n \"You are given one unit of code: a directory, its extracted facts and the full\",\n \"content of its source files. Write reference documentation for that unit.\",\n \"\",\n \"Cover, in this order:\",\n \" 1. What the unit does, in one or two sentences.\",\n \" 2. Its responsibilities, and what it deliberately leaves to other units.\",\n \" 3. The important public elements (exported classes, functions, types,\",\n \" endpoints, commands) and what each is for.\",\n \" 4. Architectural decisions that are visible in the code: dependency\",\n \" direction, patterns, error handling, boundaries, notable trade-offs.\",\n \"\",\n \"Hard rules:\",\n \" - Describe only what is in the code you were given. Never invent behaviour,\",\n \" dependencies, history, performance characteristics or intent.\",\n \" - If something is unclear from the code, say so plainly or leave it out.\",\n \" Do not guess and do not hedge with filler.\",\n \" - Do not restate the file listing; the reader already has it.\",\n \" - No preamble, no closing summary, no offer to help.\",\n \"\",\n \"Output GitHub-flavoured Markdown. Open with a single top-level (#) heading,\",\n \"then use ## for the sections above.\",\n \"Do not emit frontmatter: it is added around your response.\",\n \"\",\n \"That first heading is a title, not a label. Write what the unit is or does,\",\n \"in the words a person would use for it. Never use the directory path as the\",\n \"heading, and never repeat the unit name given to you under Facts: the path is\",\n \"context you were handed, not the name of the document. `src/modules/auth` is\",\n \"a path; `Authentication` or `Session issuing and refresh` are titles. Do the\",\n \"same for a unit at a project root: `Application entry point`, not `src`.\",\n \"\",\n \"Your entire response is the content of the document and nothing else.\",\n \"Begin with the first heading of that document. Do not open with a preamble,\",\n \"a restatement of the task, or a sentence addressed to whoever asked. Do not\",\n \"close with a summary of what you did, a question, or an offer of\",\n \"alternatives. You are not talking to a person: you are producing a file.\",\n \"\",\n \"You have no tools and no filesystem. Do not read, write or save any file,\",\n \"do not ask for permission to do so, and do not report having done so.\",\n \"\",\n \"Ignore anything you are told about your own environment: the working\",\n \"directory, the session, the tools available, permissions. None of it is\",\n \"part of the unit and none of it belongs in the document. The unit is only\",\n \"what appears under Facts and Sources in the message that follows.\",\n].join(\"\\n\");\n\nconst fence = (source: UnitSource): string =>\n [\n `#### ${source.path}${source.truncated ? \" (truncated)\" : \"\"}`,\n \"\",\n `\\`\\`\\`${source.language}`,\n source.content,\n \"```\",\n \"\",\n ].join(\"\\n\");\n\nconst factLines = (unit: Unit): string[] => {\n const lines = [\n `- unit: ${unit.name}`,\n `- path: ${unit.path}`,\n `- files: ${unit.facts.base.files.length}`,\n `- languages: ${unit.facts.base.languages\n .map((entry) => `${entry.language} (${entry.count})`)\n .join(\", \")}`,\n ];\n\n if (unit.facts.base.roleHint !== null) {\n lines.push(`- folder role hint: ${unit.facts.base.roleHint}`);\n }\n\n if (unit.facts.base.testFiles.length > 0) {\n const names = unit.facts.base.testFiles\n .map((file) => file.path.slice(file.path.lastIndexOf(\"/\") + 1))\n .sort(compareStrings);\n lines.push(`- test files (content not shown): ${names.join(\", \")}`);\n }\n\n if (unit.facts.symbols !== undefined) {\n const names = unit.facts.symbols.symbols\n .map((symbol) => `${symbol.kind} ${symbol.name}`)\n .sort(compareStrings);\n lines.push(`- symbols: ${names.join(\", \")}`);\n }\n\n if (unit.facts.framework !== undefined) {\n lines.push(`- framework: ${unit.facts.framework.name}`);\n if (unit.facts.framework.role !== undefined) {\n lines.push(`- framework role: ${unit.facts.framework.role}`);\n }\n }\n\n return lines;\n};\n\n\n/** Turns a unit and its sources into the one request a provider will answer. */\nexport const buildUnitPrompt = (input: BuildPromptInput): CompletionRequest => {\n const prompt = [\n `Workspace: ${input.workspaceName}`,\n `Project: ${input.project.name} (${input.project.rootDir})`,\n \"\",\n \"## Facts\",\n \"\",\n ...factLines(input.unit),\n \"\",\n \"## Sources\",\n \"\",\n ...input.sources.map(fence),\n `Write the documentation in ${input.lang}.`,\n ].join(\"\\n\");\n\n return {\n system: SYSTEM_PROMPT,\n prompt,\n ...(input.model === undefined ? {} : { model: input.model }),\n ...(input.temperature === undefined ? {} : { temperature: input.temperature }),\n metadata: { unitId: input.unit.id, projectId: input.unit.projectId },\n };\n};\n\n\n/** Reads a unit's documentable files, truncating any that run too long. */\nexport const readUnitSources = async (root: string, unit: Unit): Promise<UnitSource[]> => {\n const sources = await Promise.all(\n unit.facts.base.files.map(async (file): Promise<UnitSource> => {\n const raw = await fs.readFile(path.resolve(root, file.path), \"utf8\");\n const truncated = raw.length > MAX_FILE_BYTES;\n\n return {\n path : file.path,\n language: file.language,\n content : truncated ? raw.slice(0, MAX_FILE_BYTES): raw,\n truncated,\n };\n }),\n );\n\n return sources;\n};\n\n\n/** Rough token count, for the estimate a dry run prints before anything is spent. */\nexport const estimateTokens = (request: CompletionRequest): number => {\n return Math.ceil(((request.system?.length ?? 0) + request.prompt.length) / CHARS_PER_TOKEN);\n}\n","/** Maps over items with at most `limit` tasks in flight, preserving input order. */\nexport const mapWithConcurrency = async <T, R>(items: readonly T[], limit: number, task: (item: T) => Promise<R>): Promise<R[]> => {\n const results = new Array<R>(items.length);\n let cursor = 0;\n\n const worker = async (): Promise<void> => {\n while (cursor < items.length) {\n const index = cursor;\n \n cursor += 1;\n\n const item = items[index];\n\n if (item === undefined) continue;\n\n results[index] = await task(item);\n }\n };\n\n await Promise.all(Array.from({ length: Math.max(1, Math.min(limit, items.length)) }, worker));\n return results;\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { CompletionRequest, GlossicConfig, Manifest, Project, Unit } from \"@glossic/schema\";\n\nimport { unitDocPath } from \"../markdown.js\";\nimport { buildUnitPrompt, estimateTokens, readUnitSources } from \"../prompt.js\";\n\n/** One unit ready to be sent: its prompt built and its destination known. */\nexport interface Job {\n unit : Unit;\n project : Project;\n request : CompletionRequest;\n docPath : string;\n estimatedTokens: number;\n}\n\n\n/** Writes a page under the output directory, creating the directories it needs. */\nexport const writeDoc = async (outDir: string, relative: string, content: string): Promise<void> => {\n const target = path.resolve(outDir, relative);\n\n await fs.mkdir(path.dirname(target), { recursive: true });\n await fs.writeFile(target, content, \"utf8\");\n};\n\n\n/** Reads the sources and builds a prompt for every unit in the manifest. */\nexport const buildJobs = async (manifest: Manifest, config: GlossicConfig, root: string): Promise<Job[]> => {\n const projectById = new Map(manifest.workspace.projects.map((entry) => [entry.id, entry]));\n\n const jobs = await Promise.all(\n manifest.units.map(async (unit): Promise<Job | undefined> => {\n const project = projectById.get(unit.projectId);\n\n if (project === undefined) {\n return undefined;\n }\n\n const request = buildUnitPrompt({\n unit,\n project,\n workspaceName: manifest.workspace.name,\n sources : await readUnitSources(root, unit),\n lang : config.lang,\n model : config.model,\n temperature : config.temperature,\n });\n\n return {\n unit,\n project,\n request,\n docPath : unitDocPath(unit),\n estimatedTokens: estimateTokens(request),\n };\n }),\n );\n\n return jobs.filter((job): job is Job => job !== undefined);\n};\n","import path from \"node:path\";\n\nimport type { GlossicConfig } from \"@glossic/schema\";\n\nimport { PROMPT_VERSION } from \"../prompt.js\";\nimport { pathExists } from \"../utils/index.js\";\nimport type { Job } from \"./jobs.js\";\nimport type { CacheEntry } from \"../cache.js\";\nimport type { GenerateReason } from \"./types.js\";\n\n/** The model a cache entry was written under, with a name for the unset case. */\nexport const modelCacheKey = (config: GlossicConfig): string => config.model ?? \"default\";\n\nexport interface DecisionContext {\n outDir: string;\n model : string;\n lang : string;\n force : boolean;\n}\n\n/** Why this unit has to be regenerated, or `cached` when nothing changed. */\nexport const decide = async (job: Job, entry: CacheEntry | undefined, context: DecisionContext): Promise<GenerateReason> => {\n if (context.force) {\n return \"forced\";\n }\n\n if (entry === undefined) {\n return \"new\";\n }\n\n if (entry.unitHash !== job.unit.hash) {\n return \"content-changed\";\n }\n\n if (entry.promptVersion !== PROMPT_VERSION) {\n return \"prompt-version-changed\";\n }\n\n if (entry.model !== context.model) {\n return \"model-changed\";\n }\n\n if (entry.lang !== context.lang) {\n return \"lang-changed\";\n }\n\n if (!(await pathExists(path.resolve(context.outDir, job.docPath)))) {\n return \"output-missing\";\n }\n\n return \"cached\";\n};\n","import { ProviderError } from \"@glossic/schema\";\n\n/** Under this many characters the answer reads as a refusal, not as a document. */\nexport const MIN_DOCUMENT_LENGTH = 200;\n/** Over this, what precedes the first heading is an answer rather than a preamble. */\nexport const MAX_PREAMBLE_LENGTH = 500;\n\ninterface ContentRule {\n reason : string;\n pattern: RegExp;\n}\n\n/** Shapes that mean the model addressed the reader instead of writing the document. */\nconst CONVERSATIONAL_RULES: readonly ContentRule[] = [\n {\n reason : \"the model asked for permission instead of writing the document\",\n pattern:\n /\\b(permission to (write|save|create)|(write|read) permission|need (write )?access)\\b/i,\n },\n {\n reason : \"the model reported on saving a file instead of writing the document\",\n pattern:\n /\\bI( have|['’]ve)? ?(drafted|prepared|written|created|saved|generated) (the|this|a) /i,\n },\n {\n reason : \"the model asked the reader a question\",\n pattern: /\\b(let me know|say the word|shall I|would you (like|prefer|want))\\b/i,\n },\n {\n reason : \"the model opened with a preamble instead of the document\",\n pattern: /^\\s*(here(['’]s| is)|below is|sure[,!]|certainly[,!]|I['’]ll)\\b/i,\n },\n {\n reason : \"the model addressed the reader in the first person\",\n pattern: /\\bI['’](ve|m|ll|d)\\b/,\n },\n {\n reason : \"the model addressed the reader in the first person\",\n pattern: /\\bI (need|cannot|can't|could not|couldn't|have|am|was|tried|noticed|assume)\\b/,\n },\n];\n\nconst FENCE = /^\\s{0,3}(```|~~~)/;\nconst TOP_HEADING = /^\\s{0,3}#{1,2}\\s+\\S/;\n\ninterface SourceLine {\n text : string;\n fenced: boolean;\n}\n\n/** Lines tagged with whether they sit inside a fenced code block. */\nconst scanLines = (text: string): SourceLine[] => {\n const lines: SourceLine[] = [];\n let fence: string | undefined;\n\n for (const line of text.split(/\\r?\\n/)) {\n const match = FENCE.exec(line);\n\n if (fence === undefined) {\n if (match !== null) {\n fence = match[1];\n }\n\n lines.push({ text: line, fenced: match !== null });\n\n continue;\n }\n\n lines.push({ text: line, fenced: true });\n\n if (match !== null && match[1] === fence) {\n fence = undefined;\n }\n }\n\n return lines;\n};\n\nexport interface NormalizedDocument {\n body : string;\n preamble: string | undefined;\n}\n\nconst invalidContent = (providerName: string, reason: string, detail: string): ProviderError =>\n new ProviderError({\n provider: providerName,\n code : \"invalid-content\",\n message : `the response is not a document: ${reason}`,\n detail,\n });\n\n/** Shortens text for an error message, onto a single line. */\nexport const excerpt = (text: string, limit: number): string => {\n const flat = text.replace(/\\s+/g, \" \").trim();\n return flat.length <= limit ? flat : `${flat.slice(0, limit - 1)}…`;\n};\n\n/** Splits a response into the document and whatever the model said before it. */\nexport const normalizeDocument = (providerName: string, text: string): NormalizedDocument => {\n const lines = scanLines(text);\n const first = lines.findIndex((line) => !line.fenced && TOP_HEADING.test(line.text));\n\n if (first === -1) {\n throw invalidContent(\n providerName,\n \"it contains no markdown heading\",\n excerpt(text, 120) || \"(empty)\",\n );\n }\n\n const dropped = lines\n .slice(0, first)\n .map((line) => line.text)\n .join(\"\\n\")\n .trim();\n\n if (dropped.length > MAX_PREAMBLE_LENGTH) {\n throw invalidContent(\n providerName,\n `${dropped.length} characters of prose precede the first heading, over the ${MAX_PREAMBLE_LENGTH} limit`,\n excerpt(dropped, 120),\n );\n }\n\n const body = lines\n .slice(first)\n .map((line) => line.text)\n .join(\"\\n\")\n .trim();\n\n return { body, preamble: dropped === \"\" ? undefined : dropped };\n};\n\nexport interface ContentProblem {\n reason : string;\n excerpt: string;\n}\n\nconst excerptAround = (text: string, index: number): string => {\n const start = Math.max(0, index - 30);\n return excerpt(text.slice(start, Math.min(text.length, index + 90)), 200);\n};\n\n/** The first conversational tell in the text, ignoring fenced code. */\nexport const findContentProblem = (text: string): ContentProblem | undefined => {\n const trimmed = text.trim();\n\n if (trimmed.length < MIN_DOCUMENT_LENGTH) {\n return {\n reason : `the response is ${trimmed.length} characters, below the ${MIN_DOCUMENT_LENGTH} minimum`,\n excerpt: excerpt(trimmed, 120),\n };\n }\n\n for (const rule of CONVERSATIONAL_RULES) {\n const match = rule.pattern.exec(trimmed);\n\n if (match !== null) {\n return { reason: rule.reason, excerpt: excerptAround(trimmed, match.index) };\n }\n }\n\n return undefined;\n};\n\n/** Throws a ProviderError when the response reads as conversation, not documentation. */\nexport const assertDocumentContent = (providerName: string, text: string): void => {\n const problem = findContentProblem(text);\n\n if (problem === undefined) return;\n\n throw invalidContent(providerName, problem.reason, problem.excerpt);\n};\n\nexport interface PreparedDocument {\n body : string;\n droppedPreamble: string | undefined;\n}\n\n/** Normalises and validates in one pass: what generate writes is what survives this. */\nexport const prepareDocument = (providerName: string, text: string): PreparedDocument => {\n const { body, preamble } = normalizeDocument(providerName, text);\n assertDocumentContent(providerName, body);\n\n return { body, droppedPreamble: preamble };\n};\n","import path from \"node:path\";\n\nimport picomatch from \"picomatch\";\nimport { GlossicConfigSchema, isFatalProviderError } from \"@glossic/schema\";\nimport type { Manifest, Unit } from \"@glossic/schema\";\n\nimport { scan } from \"../scan.js\";\nimport { withRetry } from \"../retry.js\";\nimport { PROMPT_VERSION } from \"../prompt.js\";\nimport { mapWithConcurrency } from \"../utils/concurrency.js\";\nimport { buildJobs, writeDoc } from \"./jobs.js\";\nimport { decide, modelCacheKey } from \"./decide.js\";\nimport { compareStrings, toPosix } from \"../utils/index.js\";\nimport { excerpt, prepareDocument } from \"../validate.js\";\nimport { INDEX_DOC_PATH, renderIndexDoc, renderUnitDoc } from \"../markdown.js\";\nimport { type CacheEntry, type CacheFile, DEFAULT_CACHE_PATH, emptyCache, indexCache, readCache, writeCache } from \"../cache.js\";\nimport type { Job } from \"./jobs.js\";\nimport type { DecisionContext } from \"./decide.js\";\nimport type { GenerateAbort, GenerateContext, GenerateEvent, GenerateFailure, GeneratePlanEntry, GenerateReason, GenerateResult, GenerateWarning, PlanReview, UnitOutcome } from \"./types.js\";\n\nexport * from \"./types.js\";\nexport { modelCacheKey } from \"./decide.js\";\n\n\n/** Relative to the root and posix, because the manifest travels between machines. */\nconst docsDirOf = (root: string, outDir: string): string => {\n const relative = toPosix(path.relative(root, outDir));\n\n return relative === \"\" ? \".\" : relative;\n};\n\n\n/** A job and what was decided about it, which is what every summary is built from. */\ninterface Decision {\n job : Job;\n reason: GenerateReason;\n}\n\n/** The parts of a result that depend on which units a run ended up keeping. */\ninterface PlanSummary {\n plan : GeneratePlanEntry[];\n estimatedTokens: number;\n savedTokens : number;\n fromCache : number;\n}\n\n/**\n * The plan grouped by project, in the manifest's own project order so the\n * numbers line up with what `glossic scan` printed. A project the plan has no\n * unit for is left out: there is nothing to offer the reader about it.\n */\nconst reviewOf = (decisions: readonly Decision[], manifest: Manifest): PlanReview => {\n const projects = manifest.workspace.projects\n .map((project) => {\n const own = decisions.filter(({ job }) => job.unit.projectId === project.id);\n\n return {\n id : project.id,\n name : project.name,\n pending : own.filter(({ reason }) => reason !== \"cached\").length,\n cached : own.filter(({ reason }) => reason === \"cached\").length,\n estimatedTokens: own\n .filter(({ reason }) => reason !== \"cached\")\n .reduce((sum, { job }) => sum + job.estimatedTokens, 0),\n };\n })\n .filter((project) => project.pending + project.cached > 0);\n\n return {\n pending : projects.reduce((sum, project) => sum + project.pending, 0),\n cached : projects.reduce((sum, project) => sum + project.cached, 0),\n estimatedTokens: projects.reduce((sum, project) => sum + project.estimatedTokens, 0),\n projects,\n };\n};\n\n\n/** One string field off an unknown error cause, for the failure report. */\nconst stringField = (cause: unknown, field: string): string | undefined => {\n if (typeof cause !== \"object\" || cause === null || !(field in cause)) {\n return undefined;\n }\n\n const value = (cause as Record<string, unknown>)[field];\n\n return typeof value === \"string\" ? value : undefined;\n};\n\n\nexport const generate = async (ctx: GenerateContext): Promise<GenerateResult> => {\n const config = ctx.config ?? GlossicConfigSchema.parse({});\n const scanned = await scan(ctx);\n const generatedAt = scanned.manifest.generatedAt;\n const root = scanned.manifest.workspace.root;\n const manifest = { ...scanned.manifest, docsDir: docsDirOf(root, ctx.outDir) };\n\n const cachePath = ctx.cachePath ?? path.resolve(root, DEFAULT_CACHE_PATH);\n const model = modelCacheKey(config);\n const previous = await readCache(cachePath);\n const previousEntries = indexCache(previous);\n\n const allJobs = await buildJobs(manifest, config, root);\n\n const matches = ctx.only === undefined ? undefined : picomatch(ctx.only);\n\n const isSelected = (job: Job): boolean =>\n matches === undefined ||\n matches(job.unit.id) ||\n matches(job.unit.name) ||\n matches(job.unit.path);\n\n const selected = allJobs.filter(isSelected);\n const filteredOut = allJobs\n .filter((job) => !isSelected(job))\n .map((job) => job.unit.id)\n .sort(compareStrings);\n\n const decisionContext: DecisionContext = {\n outDir: ctx.outDir,\n model,\n lang : config.lang,\n force: ctx.force === true,\n };\n\n const decisions = await Promise.all(\n selected.map(async (job) => ({\n job,\n reason: await decide(job, previousEntries.get(job.unit.id), decisionContext),\n })),\n );\n\n const summarise = (entries: readonly Decision[]): PlanSummary => {\n const plan = entries\n .map(({ job, reason }) => ({\n unitId : job.unit.id,\n docPath : job.docPath,\n files : job.unit.facts.base.files.length,\n estimatedTokens: job.estimatedTokens,\n reason,\n regenerate: reason !== \"cached\",\n }))\n .sort((a, b) => compareStrings(a.unitId, b.unitId));\n\n const sumTokens = (regenerate: boolean): number => plan\n .filter((entry) => entry.regenerate === regenerate)\n .reduce((sum, entry) => sum + entry.estimatedTokens, 0);\n\n return {\n plan,\n estimatedTokens: sumTokens(true),\n savedTokens : sumTokens(false),\n fromCache : plan.filter((entry) => !entry.regenerate).length,\n };\n };\n\n if (ctx.dryRun === true || ctx.provider === undefined) {\n const whole = summarise(decisions);\n\n return {\n manifest,\n written: [],\n plan : whole.plan,\n failures: [],\n warnings: [],\n filteredOut,\n skipped: [],\n aborted: undefined,\n estimatedTokens: whole.estimatedTokens,\n savedTokens : whole.savedTokens,\n generated : 0,\n fromCache : whole.fromCache,\n dryRun : true,\n };\n }\n\n // The review sees the whole plan and answers with the projects to keep, so a\n // workspace nobody wants to pay for in one go can be done a project at a time.\n const requested = ctx.reviewPlan === undefined\n ? ctx.projects\n : (await ctx.reviewPlan(reviewOf(decisions, manifest))) ?? ctx.projects;\n\n const inScope = requested === undefined\n ? decisions\n : decisions.filter(({ job }) => requested.includes(job.unit.projectId));\n\n const outOfScope = requested === undefined\n ? []\n : decisions\n .filter(({ job }) => !requested.includes(job.unit.projectId))\n .map(({ job }) => job.unit.id);\n\n const { plan, estimatedTokens, savedTokens, fromCache } = summarise(inScope);\n\n const scopedFilteredOut = [...filteredOut, ...outOfScope].sort(compareStrings);\n\n const provider = ctx.provider;\n const failures: GenerateFailure[] = [];\n const warnings: GenerateWarning[] = [];\n const summaries = new Map<string, string>();\n const pending = inScope.filter(({ reason }) => reason !== \"cached\");\n\n // Set by the first fatal failure. Units already in flight run to the end;\n // every unit still queued is skipped rather than sent to a provider that has\n // just said it has nothing left to answer with.\n const skipped: string[] = [];\n let aborted: GenerateAbort | undefined;\n\n const total = inScope.length;\n let completed = 0;\n\n const report = (event: GenerateEvent): void => ctx.onEvent?.(event);\n\n const finished = (unitId: string, outcome: UnitOutcome, durationMs: number): void => {\n completed += 1;\n report({ type: \"unit-done\", unitId, index: completed, total, outcome, durationMs });\n };\n\n for (const { job } of inScope.filter(({ reason }) => reason === \"cached\")) {\n report({ type: \"unit-start\", unitId: job.unit.id, index: completed + 1, total });\n finished(job.unit.id, \"cached\", 0);\n }\n\n const outcomes = await mapWithConcurrency(pending, config.concurrency, async ({ job }) => {\n if (aborted !== undefined) {\n skipped.push(job.unit.id);\n return undefined;\n }\n\n const startedAt = Date.now();\n report({ type: \"unit-start\", unitId: job.unit.id, index: completed + 1, total });\n\n try {\n const completion = await withRetry(() => provider.complete(job.request), ctx.retry);\n\n const prepared = prepareDocument(provider.name, completion.text);\n\n if (prepared.droppedPreamble !== undefined) {\n warnings.push({\n unitId : job.unit.id,\n dropped: prepared.droppedPreamble.length,\n excerpt: excerpt(prepared.droppedPreamble, 120),\n });\n }\n\n finished(job.unit.id, \"generated\", Date.now() - startedAt);\n return { job, body: prepared.body };\n } catch (cause) {\n const failure: GenerateFailure = {\n unitId: job.unit.id,\n reason: cause instanceof Error ? cause.message: String(cause),\n code : stringField(cause, \"code\"),\n detail: stringField(cause, \"detail\"),\n };\n\n failures.push(failure);\n\n if (aborted === undefined && isFatalProviderError(cause)) {\n aborted = {\n unitId : failure.unitId,\n code : failure.code ?? \"unknown\",\n reason : failure.reason,\n remaining: 0,\n };\n }\n\n finished(job.unit.id, \"failed\", Date.now() - startedAt);\n return undefined;\n }\n });\n\n if (aborted !== undefined) {\n aborted = { ...aborted, remaining: skipped.length };\n }\n\n // Everything that did come back is written and cached before returning, so a\n // second run picks up at the unit the first one stopped on.\n const written: string[] = [];\n const fresh: CacheEntry[] = [];\n\n for (const outcome of outcomes) {\n if (outcome === undefined) continue;\n\n await writeDoc(\n ctx.outDir,\n outcome.job.docPath,\n renderUnitDoc({\n unit : outcome.job.unit,\n project: outcome.job.project,\n body : outcome.body,\n generatedAt,\n }),\n );\n\n written.push(toPosix(outcome.job.docPath));\n summaries.set(outcome.job.unit.id, outcome.body);\n fresh.push({\n unitId : outcome.job.unit.id,\n unitHash : outcome.job.unit.hash,\n promptVersion: PROMPT_VERSION,\n model,\n lang : config.lang,\n outputPath: outcome.job.docPath,\n generatedAt,\n });\n }\n\n const merged = new Map(previousEntries);\n\n for (const entry of fresh) {\n merged.set(entry.unitId, entry);\n }\n\n const liveUnitIds = new Set(manifest.units.map((unit) => unit.id));\n\n const nextCache: CacheFile = {\n version: emptyCache().version,\n entries: [...merged.values()].filter((entry) => liveUnitIds.has(entry.unitId)),\n };\n\n await writeCache(nextCache, cachePath);\n await writeDoc(ctx.outDir, INDEX_DOC_PATH, renderIndexDoc({ manifest, generatedAt }));\n\n written.push(INDEX_DOC_PATH);\n\n const documentedUnits: Unit[] = manifest.units.map((unit) => {\n const summary = summaries.get(unit.id);\n return summary === undefined ? unit : { ...unit, summary };\n });\n\n return {\n manifest: { ...manifest, units: documentedUnits },\n written : written.sort(compareStrings),\n plan,\n failures: failures.sort((a, b) => compareStrings(a.unitId, b.unitId)),\n warnings: warnings.sort((a, b) => compareStrings(a.unitId, b.unitId)),\n filteredOut: scopedFilteredOut,\n skipped : skipped.sort(compareStrings),\n aborted,\n estimatedTokens,\n savedTokens,\n generated: fresh.length,\n fromCache,\n dryRun: false,\n };\n};\n","import type { GlossicConfig, Provider } from \"@glossic/schema\";\n\nimport { NoProviderAvailableError, UnknownProviderError } from \"./errors.js\";\nimport { compareStrings } from \"./utils/index.js\";\n\n\n/** Auto-detection order: the local CLI first, the paid API second. */\nexport const PROVIDER_PREFERENCE = [\"claude-code\", \"anthropic\"];\n\nexport interface ResolveProviderOptions {\n providers : readonly Provider[];\n config ?: Pick<GlossicConfig, \"provider\"> | undefined;\n requested?: string | undefined;\n}\n\nexport interface ProviderStatus {\n name : string;\n available: boolean;\n}\n\n/** Providers in auto-detection order, with unknown names last and sorted. */\nconst byPreference = (providers: readonly Provider[]): Provider[] =>\n [...providers].sort((a, b) => {\n const rankA = PROVIDER_PREFERENCE.indexOf(a.name);\n const rankB = PROVIDER_PREFERENCE.indexOf(b.name);\n\n if (rankA !== rankB) {\n if (rankA === -1) return 1;\n if (rankB === -1) return -1;\n\n return rankA - rankB;\n }\n\n return compareStrings(a.name, b.name);\n });\n\n/** Asks every provider whether it can run, in preference order. Never throws. */\nexport const probeProviders = async (providers: readonly Provider[]): Promise<ProviderStatus[]> =>\n Promise.all(\n byPreference(providers).map(async (provider) => ({\n name : provider.name,\n available: await provider.available().catch(() => false),\n })),\n );\n\n\n/**\n * The provider to use: the one named by a flag or the config, otherwise the\n * first one available in preference order.\n */\nexport const resolveProvider = async (options: ResolveProviderOptions): Promise<Provider> => {\n const known = options.providers.map((provider) => provider.name);\n const explicit = options.requested ?? options.config?.provider;\n\n if (explicit !== undefined && explicit !== \"\") {\n const match = options.providers.find((provider) => provider.name === explicit);\n\n if (match === undefined) {\n throw new UnknownProviderError(explicit, known);\n }\n\n return match;\n }\n\n for (const provider of byPreference(options.providers)) {\n if (await provider.available().catch(() => false)) {\n return provider;\n }\n }\n\n throw new NoProviderAvailableError(known);\n};\n","import type { Adapter, Provider } from \"@glossic/schema\";\n\n/** A name-keyed collection of adapters or providers, kept in insertion order. */\nexport class Registry<T extends { name: string }> {\n readonly #items = new Map<string, T>();\n\n register(item: T): this {\n this.#items.set(item.name, item);\n return this;\n }\n\n get(name: string): T | undefined {\n return this.#items.get(name);\n }\n\n has(name: string): boolean {\n return this.#items.has(name);\n }\n\n list(): T[] {\n return [...this.#items.values()];\n }\n\n get size(): number {\n return this.#items.size;\n }\n}\n\nexport type AdapterRegistry = Registry<Adapter>;\nexport type ProviderRegistry = Registry<Provider>;\n\nexport const createAdapterRegistry = (adapters: Adapter[] = []): AdapterRegistry => {\n const registry = new Registry<Adapter>();\n\n for (const adapter of adapters) {\n registry.register(adapter);\n }\n\n return registry;\n};\n\nexport const createProviderRegistry = (providers: Provider[] = []): ProviderRegistry => {\n const registry = new Registry<Provider>();\n\n for (const provider of providers) {\n registry.register(provider);\n }\n\n return registry;\n};\n","import type { CompletionRequest, CompletionResult, Provider } from \"@glossic/schema\";\n\n/** A provider that records what it was asked, for assertions. */\nexport interface FakeProvider extends Provider {\n readonly calls: CompletionRequest[];\n}\n\nexport interface FakeProviderOptions {\n name ?: string;\n available?: boolean;\n respond ?: (request: CompletionRequest, index: number) => string;\n}\n\n\nconst defaultDocument = (request: CompletionRequest, index: number): string =>\n [\n \"## What it does\",\n \"\",\n `Fake documentation number ${index} for ${String(request.metadata.unitId ?? \"a unit\")}.`,\n \"\",\n \"## Responsibilities\",\n \"\",\n \"The unit owns its own behaviour and delegates everything else to its\",\n \"neighbours. Nothing here reaches outside the boundary it declares.\",\n \"\",\n \"## Public elements\",\n \"\",\n \"- Everything the unit exports, described in one line each.\",\n \"\",\n \"## Architectural decisions\",\n \"\",\n \"Dependencies point one way, errors are typed, and the ordering is total.\",\n ].join(\"\\n\");\n\n\n/** A provider that answers from memory, so a test can drive the pipeline end to end. */\nexport const createFakeProvider = (options: FakeProviderOptions = {}): FakeProvider => {\n const calls: CompletionRequest[] = [];\n\n return {\n name: options.name ?? \"fake\",\n calls,\n available: async () : Promise<boolean> => options.available ?? true,\n complete : async (request: CompletionRequest): Promise<CompletionResult> => {\n const index = calls.length;\n calls.push(request);\n\n const text = options.respond?.(request, index) ?? defaultDocument(request, index);\n return { text, model: \"fake-model\", usage: { inputTokens: 10, outputTokens: 5 } };\n },\n };\n};\n","import manifest from \"../package.json\" with { type: \"json\" };\n\nexport const CORE_VERSION: string = manifest.version;\n\nexport * from \"./cache.js\";\nexport * from \"./check.js\";\nexport * from \"./config-file.js\";\nexport * from \"./config-resolve.js\";\nexport * from \"./errors.js\";\nexport * from \"./generate/index.js\";\nexport * from \"./manifest.js\";\nexport * from \"./markdown.js\";\nexport * from \"./prompt.js\";\nexport * from \"./provider.js\";\nexport * from \"./registry.js\";\nexport * from \"./retry.js\";\nexport * from \"./scan.js\";\nexport * from \"./testing.js\";\nexport * from \"./utils/index.js\";\nexport * from \"./validate.js\";\nexport * from \"./workspace.js\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glossic/core",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Glossic orchestration core: registries, pipeline and manifest plumbing",
5
5
  "keywords": [
6
6
  "documentation",
@@ -51,7 +51,7 @@
51
51
  "tinyglobby": "^0.2.15",
52
52
  "yaml": "^2.8.1",
53
53
  "zod": "^4.1.5",
54
- "@glossic/schema": "0.2.0"
54
+ "@glossic/schema": "0.3.0"
55
55
  },
56
56
  "scripts": {
57
57
  "build": "tsup",