@codedrifters/configulator 0.0.273 → 0.0.274

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/lib/index.js CHANGED
@@ -223,6 +223,7 @@ __export(index_exports, {
223
223
  DEFAULT_PROGRESS_FILES_STATE_DIR: () => DEFAULT_PROGRESS_FILES_STATE_DIR,
224
224
  DEFAULT_REQUIRE_LINKED_ISSUE: () => DEFAULT_REQUIRE_LINKED_ISSUE,
225
225
  DEFAULT_REQUIRE_PRODUCT_CONTEXT: () => DEFAULT_REQUIRE_PRODUCT_CONTEXT,
226
+ DEFAULT_SAMPLE_COMPILER_OPTIONS: () => DEFAULT_SAMPLE_COMPILER_OPTIONS,
226
227
  DEFAULT_SCHEDULED_TASKS_ROOT: () => DEFAULT_SCHEDULED_TASKS_ROOT,
227
228
  DEFAULT_SCHEDULED_TASK_ENTRIES: () => DEFAULT_SCHEDULED_TASK_ENTRIES,
228
229
  DEFAULT_SHARED_EDITING_CONFLICT_STRATEGY: () => DEFAULT_SHARED_EDITING_CONFLICT_STRATEGY,
@@ -268,6 +269,7 @@ __export(index_exports, {
268
269
  SCOPE_CLASS_VALUES: () => SCOPE_CLASS_VALUES,
269
270
  SHARED_EDITING_CONFLICT_STRATEGY_VALUES: () => SHARED_EDITING_CONFLICT_STRATEGY_VALUES,
270
271
  STARLIGHT_ROLE: () => STARLIGHT_ROLE,
272
+ SampleLang: () => SampleLang,
271
273
  StarlightProject: () => StarlightProject,
272
274
  TestRunner: () => TestRunner,
273
275
  TsDocCoverageKind: () => TsDocCoverageKind,
@@ -310,14 +312,17 @@ __export(index_exports, {
310
312
  buildStandardsResearchBundle: () => buildStandardsResearchBundle,
311
313
  buildUnblockDependentsProcedure: () => buildUnblockDependentsProcedure,
312
314
  businessModelsBundle: () => businessModelsBundle,
315
+ checkDocSamplesProcedure: () => checkDocSamplesProcedure,
313
316
  checkLinksProcedure: () => checkLinksProcedure,
314
317
  classifyIssueScope: () => classifyIssueScope,
315
318
  classifyRun: () => classifyRun,
316
319
  companyProfileBundle: () => companyProfileBundle,
320
+ compileFencedSamples: () => compileFencedSamples,
317
321
  customerProfileBundle: () => customerProfileBundle,
318
322
  docsSyncBundle: () => docsSyncBundle,
319
323
  extractApiProcedure: () => extractApiProcedure,
320
324
  extractDocReferences: () => extractDocReferences,
325
+ extractFencedSamples: () => extractFencedSamples,
321
326
  formatLayoutViolation: () => formatLayoutViolation,
322
327
  formatStarlightSingletonViolation: () => formatStarlightSingletonViolation,
323
328
  getLatestEligibleVersion: () => getLatestEligibleVersion,
@@ -334,6 +339,7 @@ __export(index_exports, {
334
339
  regulatoryResearchBundle: () => regulatoryResearchBundle,
335
340
  renderAgentTierCaseStatement: () => renderAgentTierCaseStatement,
336
341
  renderAgentTierSection: () => renderAgentTierSection,
342
+ renderCheckDocSamplesProcedure: () => renderCheckDocSamplesProcedure,
337
343
  renderCheckLinksProcedure: () => renderCheckLinksProcedure,
338
344
  renderCustomDocSectionBlock: () => renderCustomDocSectionBlock,
339
345
  renderCustomDocSections: () => renderCustomDocSections,
@@ -9269,6 +9275,126 @@ var checkLinksProcedure = {
9269
9275
  description: "Link integrity checker that wraps `astro check` (internal links) and `lychee` (external URLs) and normalizes their output into a single JSON-array stream of { url, docPath, line, kind, reason } records. Detection is data: the helper exits 0 when a tool ran successfully regardless of how many broken links it reported. Non-zero exits are reserved for tool-level failures.",
9270
9276
  content: renderCheckLinksProcedure()
9271
9277
  };
9278
+ function renderCheckDocSamplesProcedure() {
9279
+ const nodeScript = [
9280
+ "(async () => {",
9281
+ " const { compileFencedSamples } = await import('@codedrifters/configulator');",
9282
+ " const docsRoot = process.argv[1];",
9283
+ " const failures = compileFencedSamples({ docsRoot });",
9284
+ " process.stdout.write(JSON.stringify(failures));",
9285
+ "})().catch((err) => {",
9286
+ " console.error('check-doc-samples.sh: ' + (err && err.stack ? err.stack : err));",
9287
+ " process.exit(3);",
9288
+ "});"
9289
+ ].join("\n");
9290
+ return [
9291
+ "#!/usr/bin/env bash",
9292
+ "# check-doc-samples.sh \u2014 Compile fenced TS/TSX samples in the Starlight docs.",
9293
+ "#",
9294
+ "# Usage:",
9295
+ "# .claude/procedures/check-doc-samples.sh <docs-root>",
9296
+ "#",
9297
+ "# Where:",
9298
+ "# <docs-root> \u2014 path to the markdown content tree",
9299
+ "# (e.g. `docs/src/content/docs`). Walked recursively",
9300
+ "# for `*.md` files.",
9301
+ "#",
9302
+ "# Wraps the `compileFencedSamples` API exported from",
9303
+ "# `@codedrifters/configulator`. For every fenced ` ```ts `,",
9304
+ "# ` ```typescript `, ` ```tsx `, or ` ```typescriptreact ` block in",
9305
+ "# the docs, the helper writes the sample to an in-memory file,",
9306
+ "# runs the TypeScript compiler against it (in-process, via the TS",
9307
+ "# compiler API), and reports any compilation diagnostics.",
9308
+ "#",
9309
+ "# Skipped samples (fence meta `skip` / `no-check`, or first line",
9310
+ "# `// @no-check`) are passed through unchecked.",
9311
+ "#",
9312
+ "# Output (stdout, single JSON array):",
9313
+ "#",
9314
+ "# [",
9315
+ "# {",
9316
+ '# "docPath": "<path relative to <docs-root>>",',
9317
+ '# "line": <1-indexed line number of the opening fence>,',
9318
+ '# "fenceIndex": <0-indexed fenced-block position within the doc>,',
9319
+ '# "lang": "ts" | "typescript" | "tsx" | "typescriptreact",',
9320
+ '# "diagnostics": [ "<TS<code>: <message>>", ... ]',
9321
+ "# },",
9322
+ "# ...",
9323
+ "# ]",
9324
+ "#",
9325
+ "# An empty array (`[]`) is emitted when every sample compiled.",
9326
+ "# Detection is **data**, not failure: this helper exits 0 when the",
9327
+ "# compilation phase ran successfully, regardless of how many",
9328
+ "# samples failed to compile. The downstream docs-sync scan phase",
9329
+ "# (#520) is responsible for treating failures as one of the two",
9330
+ "# hard-block cases per the parent epic.",
9331
+ "#",
9332
+ "# Exit codes:",
9333
+ "# 0 \u2014 compilation phase ran; failures (zero or more) are on",
9334
+ "# stdout as a JSON array.",
9335
+ "# 1 \u2014 usage error (missing args, unreadable docs root).",
9336
+ "# 2 \u2014 a required binary is not on PATH (`node` / `pnpm`).",
9337
+ "# 3 \u2014 the compilation phase threw an unhandled exception.",
9338
+ "# Stderr carries the diagnostic.",
9339
+ "#",
9340
+ "# Dependencies: expects `node` and `pnpm` on PATH and the workspace",
9341
+ "# `@codedrifters/configulator` package to be installed (the helper",
9342
+ "# resolves the API through `pnpm exec node` from the repo root).",
9343
+ "",
9344
+ "set -uo pipefail",
9345
+ "",
9346
+ "err() {",
9347
+ ' printf "check-doc-samples.sh: %s\\n" "$*" >&2',
9348
+ "}",
9349
+ "",
9350
+ 'if [ "$#" -lt 1 ]; then',
9351
+ ' err "usage: check-doc-samples.sh <docs-root>"',
9352
+ " exit 1",
9353
+ "fi",
9354
+ "",
9355
+ 'docs_root="$1"',
9356
+ "",
9357
+ 'if [ ! -d "$docs_root" ]; then',
9358
+ ' err "docs root not found: $docs_root"',
9359
+ " exit 1",
9360
+ "fi",
9361
+ "",
9362
+ "if ! command -v node >/dev/null 2>&1; then",
9363
+ ' err "node is required but not on PATH"',
9364
+ " exit 2",
9365
+ "fi",
9366
+ "",
9367
+ "if ! command -v pnpm >/dev/null 2>&1; then",
9368
+ ' err "pnpm is required but not on PATH"',
9369
+ " exit 2",
9370
+ "fi",
9371
+ "",
9372
+ "# Resolve docs_root to an absolute path so the inline node script",
9373
+ "# is independent of the cwd `pnpm exec` chooses.",
9374
+ 'docs_root_abs="$(cd "$docs_root" && pwd)"',
9375
+ "",
9376
+ "# Run the inline node script through `pnpm exec` so module",
9377
+ "# resolution finds `@codedrifters/configulator` via the workspace",
9378
+ "# even when the helper is invoked from a sub-package directory.",
9379
+ "# The `--input-type=module` flag lets us use top-level `await` and",
9380
+ "# `import()` cleanly. Diagnostics from the script flow to stderr;",
9381
+ "# stdout carries only the JSON array.",
9382
+ 'pnpm exec node --input-type=module -e "' + nodeScript.replace(/"/g, '\\"') + '" "$docs_root_abs"',
9383
+ "status=$?",
9384
+ "",
9385
+ 'if [ "$status" -ne 0 ]; then',
9386
+ ' err "compileFencedSamples exited with status $status"',
9387
+ " exit 3",
9388
+ "fi",
9389
+ "",
9390
+ "exit 0"
9391
+ ].join("\n");
9392
+ }
9393
+ var checkDocSamplesProcedure = {
9394
+ name: "check-doc-samples.sh",
9395
+ description: "Fenced-sample compilation checker that wraps the `compileFencedSamples` API and emits a JSON-array stream of { docPath, line, fenceIndex, lang, diagnostics } failure records. Skipped samples (meta `skip`/`no-check`, or first-line `// @no-check`) are passed through unchecked. Detection is data: the helper exits 0 whenever compilation ran successfully regardless of failure count.",
9396
+ content: renderCheckDocSamplesProcedure()
9397
+ };
9272
9398
  function buildDocsSyncBundle(paths = DEFAULT_AGENT_PATHS) {
9273
9399
  return {
9274
9400
  name: "docs-sync",
@@ -9318,7 +9444,11 @@ function buildDocsSyncBundle(paths = DEFAULT_AGENT_PATHS) {
9318
9444
  ],
9319
9445
  skills: [buildDocsSyncPrSkill(), buildDocsSyncAuditSkill()],
9320
9446
  subAgents: [buildDocsSyncSubAgent(paths)],
9321
- procedures: [extractApiProcedure, checkLinksProcedure],
9447
+ procedures: [
9448
+ extractApiProcedure,
9449
+ checkLinksProcedure,
9450
+ checkDocSamplesProcedure
9451
+ ],
9322
9452
  labels: [
9323
9453
  {
9324
9454
  name: "type:docs-sync",
@@ -27062,8 +27192,8 @@ var FALLBACKS = {
27062
27192
  monorepoLayoutSeedBlock: ""
27063
27193
  };
27064
27194
  var TEMPLATE_RE = /\{\{(\w+(?:\.\w+)*)\}\}/g;
27065
- function getNestedValue(obj, path4) {
27066
- const parts = path4.split(".");
27195
+ function getNestedValue(obj, path6) {
27196
+ const parts = path6.split(".");
27067
27197
  let current = obj;
27068
27198
  for (const part of parts) {
27069
27199
  if (current == null || typeof current !== "object") {
@@ -27289,20 +27419,20 @@ var ClaudeRenderer = class _ClaudeRenderer {
27289
27419
  obj.excludedCommands = [...sandbox.excludedCommands];
27290
27420
  }
27291
27421
  if (sandbox.filesystem) {
27292
- const fs2 = {};
27422
+ const fs3 = {};
27293
27423
  if (sandbox.filesystem.allowRead?.length) {
27294
- fs2.allowRead = [...sandbox.filesystem.allowRead];
27424
+ fs3.allowRead = [...sandbox.filesystem.allowRead];
27295
27425
  }
27296
27426
  if (sandbox.filesystem.denyRead?.length) {
27297
- fs2.denyRead = [...sandbox.filesystem.denyRead];
27427
+ fs3.denyRead = [...sandbox.filesystem.denyRead];
27298
27428
  }
27299
27429
  if (sandbox.filesystem.allowWrite?.length) {
27300
- fs2.allowWrite = [...sandbox.filesystem.allowWrite];
27430
+ fs3.allowWrite = [...sandbox.filesystem.allowWrite];
27301
27431
  }
27302
27432
  if (sandbox.filesystem.denyWrite?.length) {
27303
- fs2.denyWrite = [...sandbox.filesystem.denyWrite];
27433
+ fs3.denyWrite = [...sandbox.filesystem.denyWrite];
27304
27434
  }
27305
- if (Object.keys(fs2).length > 0) obj.filesystem = fs2;
27435
+ if (Object.keys(fs3).length > 0) obj.filesystem = fs3;
27306
27436
  }
27307
27437
  if (sandbox.network) {
27308
27438
  const net = {};
@@ -29164,10 +29294,357 @@ function stripYamlFrontmatter(source) {
29164
29294
  return lines.join("\n");
29165
29295
  }
29166
29296
 
29167
- // src/docs-sync/tsdoc-coverage/coverage.ts
29297
+ // src/docs-sync/sample-compilation/compilation.ts
29298
+ var path4 = __toESM(require("path"));
29299
+ var ts = __toESM(require("typescript"));
29300
+
29301
+ // src/docs-sync/sample-compilation/extraction.ts
29302
+ var fs2 = __toESM(require("fs"));
29168
29303
  var path3 = __toESM(require("path"));
29304
+ var import_mdast_util_from_markdown2 = require("mdast-util-from-markdown");
29305
+ var SampleLang = {
29306
+ Ts: "ts",
29307
+ Typescript: "typescript",
29308
+ Tsx: "tsx",
29309
+ Typescriptreact: "typescriptreact"
29310
+ };
29311
+ var DEFAULT_DOCS_ROOT2 = "docs/src/content/docs";
29312
+ var PLAIN_LANGS = /* @__PURE__ */ new Set([SampleLang.Ts, SampleLang.Typescript]);
29313
+ var JSX_LANGS = /* @__PURE__ */ new Set([
29314
+ SampleLang.Tsx,
29315
+ SampleLang.Typescriptreact
29316
+ ]);
29317
+ function extractFencedSamples(options = {}) {
29318
+ const docsRoot = path3.resolve(options.docsRoot ?? DEFAULT_DOCS_ROOT2);
29319
+ const includeTsx = options.includeTsx ?? true;
29320
+ if (!fs2.existsSync(docsRoot)) {
29321
+ return [];
29322
+ }
29323
+ const records = [];
29324
+ for (const absolutePath of walkMarkdownFiles2(docsRoot)) {
29325
+ const docPath = toPosix2(path3.relative(docsRoot, absolutePath));
29326
+ const source = fs2.readFileSync(absolutePath, "utf-8");
29327
+ const tree = (0, import_mdast_util_from_markdown2.fromMarkdown)(stripYamlFrontmatter2(source));
29328
+ let fenceIndex = 0;
29329
+ collectFencedCode(tree, (node) => {
29330
+ const lang = normalizeLang(node.lang);
29331
+ if (lang === void 0) {
29332
+ return;
29333
+ }
29334
+ if (!includeTsx && JSX_LANGS.has(lang)) {
29335
+ return;
29336
+ }
29337
+ if (!PLAIN_LANGS.has(lang) && !JSX_LANGS.has(lang)) {
29338
+ return;
29339
+ }
29340
+ const start = node.position?.start;
29341
+ if (!start) {
29342
+ return;
29343
+ }
29344
+ const skip = detectSkip(node);
29345
+ records.push({
29346
+ docPath,
29347
+ line: start.line,
29348
+ fenceIndex,
29349
+ lang,
29350
+ code: node.value ?? "",
29351
+ skipped: skip.skipped,
29352
+ skipReason: skip.reason
29353
+ });
29354
+ fenceIndex += 1;
29355
+ });
29356
+ }
29357
+ records.sort((a, b) => {
29358
+ if (a.docPath !== b.docPath) {
29359
+ return a.docPath.localeCompare(b.docPath);
29360
+ }
29361
+ if (a.line !== b.line) {
29362
+ return a.line - b.line;
29363
+ }
29364
+ return a.fenceIndex - b.fenceIndex;
29365
+ });
29366
+ return records;
29367
+ }
29368
+ function walkMarkdownFiles2(root) {
29369
+ const out = [];
29370
+ const stack = [root];
29371
+ while (stack.length > 0) {
29372
+ const dir = stack.pop();
29373
+ let entries;
29374
+ try {
29375
+ entries = fs2.readdirSync(dir, { withFileTypes: true });
29376
+ } catch {
29377
+ continue;
29378
+ }
29379
+ for (const entry of entries) {
29380
+ const full = path3.join(dir, entry.name);
29381
+ if (entry.isDirectory()) {
29382
+ stack.push(full);
29383
+ } else if (entry.isFile() && full.toLowerCase().endsWith(".md")) {
29384
+ out.push(full);
29385
+ }
29386
+ }
29387
+ }
29388
+ out.sort();
29389
+ return out;
29390
+ }
29391
+ function collectFencedCode(tree, visit) {
29392
+ walk(tree);
29393
+ function walk(node) {
29394
+ if (node.type === "code") {
29395
+ visit(node);
29396
+ return;
29397
+ }
29398
+ if (node.type === "html") {
29399
+ return;
29400
+ }
29401
+ const parent = node;
29402
+ if (Array.isArray(parent.children)) {
29403
+ for (const child of parent.children) {
29404
+ walk(child);
29405
+ }
29406
+ }
29407
+ }
29408
+ }
29409
+ function normalizeLang(raw) {
29410
+ if (!raw) {
29411
+ return void 0;
29412
+ }
29413
+ const lower = raw.toLowerCase();
29414
+ switch (lower) {
29415
+ case "ts":
29416
+ return SampleLang.Ts;
29417
+ case "typescript":
29418
+ return SampleLang.Typescript;
29419
+ case "tsx":
29420
+ return SampleLang.Tsx;
29421
+ case "typescriptreact":
29422
+ return SampleLang.Typescriptreact;
29423
+ default:
29424
+ return void 0;
29425
+ }
29426
+ }
29427
+ var META_SKIP_PATTERN = /\b(skip|no-check)\b/i;
29428
+ var PRAGMA_NO_CHECK_PATTERN = /^\s*\/\/\s*@no-check\b/i;
29429
+ function detectSkip(node) {
29430
+ const meta = node.meta ?? "";
29431
+ const metaMatch = META_SKIP_PATTERN.exec(meta);
29432
+ if (metaMatch) {
29433
+ return { skipped: true, reason: `meta:${metaMatch[1].toLowerCase()}` };
29434
+ }
29435
+ const code = node.value ?? "";
29436
+ const firstLine = firstNonBlankLine(code);
29437
+ if (firstLine !== void 0 && PRAGMA_NO_CHECK_PATTERN.test(firstLine)) {
29438
+ return { skipped: true, reason: "pragma:@no-check" };
29439
+ }
29440
+ return { skipped: false, reason: "" };
29441
+ }
29442
+ function firstNonBlankLine(source) {
29443
+ for (const line of source.split("\n")) {
29444
+ if (line.trim().length > 0) {
29445
+ return line;
29446
+ }
29447
+ }
29448
+ return void 0;
29449
+ }
29450
+ function toPosix2(p) {
29451
+ return p.split(path3.sep).join("/");
29452
+ }
29453
+ function stripYamlFrontmatter2(source) {
29454
+ if (!source.startsWith("---")) {
29455
+ return source;
29456
+ }
29457
+ const lines = source.split("\n");
29458
+ if (lines[0] !== "---") {
29459
+ return source;
29460
+ }
29461
+ let endIndex = -1;
29462
+ for (let i = 1; i < lines.length; i++) {
29463
+ if (lines[i] === "---") {
29464
+ endIndex = i;
29465
+ break;
29466
+ }
29467
+ }
29468
+ if (endIndex < 0) {
29469
+ return source;
29470
+ }
29471
+ for (let i = 0; i <= endIndex; i++) {
29472
+ lines[i] = "";
29473
+ }
29474
+ return lines.join("\n");
29475
+ }
29476
+
29477
+ // src/docs-sync/sample-compilation/compilation.ts
29478
+ var DEFAULT_SAMPLE_COMPILER_OPTIONS = {
29479
+ target: ts.ScriptTarget.ES2022,
29480
+ module: ts.ModuleKind.ESNext,
29481
+ moduleResolution: ts.ModuleResolutionKind.Bundler,
29482
+ lib: ["lib.es2022.d.ts", "lib.dom.d.ts"],
29483
+ strict: true,
29484
+ noUnusedLocals: false,
29485
+ noUnusedParameters: false,
29486
+ skipLibCheck: true,
29487
+ esModuleInterop: true,
29488
+ resolveJsonModule: true,
29489
+ isolatedModules: true,
29490
+ jsx: ts.JsxEmit.Preserve,
29491
+ noEmit: true,
29492
+ allowSyntheticDefaultImports: true
29493
+ };
29494
+ var REPO_RELATIVE_MODULE_PATTERN = /^['"](?:\.\.?\/|\/)/;
29495
+ function compileFencedSamples(options = {}) {
29496
+ const samples = extractFencedSamples(options);
29497
+ const tolerateRepoRelative = options.tolerateRepoRelativeMissingModule ?? true;
29498
+ const failures = [];
29499
+ for (const sample of samples) {
29500
+ if (sample.skipped) {
29501
+ continue;
29502
+ }
29503
+ const diagnostics = compileSingleSample(
29504
+ sample,
29505
+ options.compilerOptions,
29506
+ tolerateRepoRelative
29507
+ );
29508
+ if (diagnostics.length > 0) {
29509
+ failures.push({
29510
+ docPath: sample.docPath,
29511
+ line: sample.line,
29512
+ fenceIndex: sample.fenceIndex,
29513
+ lang: sample.lang,
29514
+ diagnostics
29515
+ });
29516
+ }
29517
+ }
29518
+ return failures;
29519
+ }
29520
+ function compileSingleSample(sample, overrides, tolerateRepoRelative) {
29521
+ const filename = sampleFilename(sample);
29522
+ const compilerOptions = mergeCompilerOptions(overrides);
29523
+ const host = createSingleFileHost(filename, sample.code, compilerOptions);
29524
+ const program = ts.createProgram({
29525
+ rootNames: [filename],
29526
+ options: compilerOptions,
29527
+ host
29528
+ });
29529
+ const sourceFile = program.getSourceFile(filename);
29530
+ const collected = [];
29531
+ if (sourceFile) {
29532
+ collected.push(...program.getSyntacticDiagnostics(sourceFile));
29533
+ collected.push(...program.getSemanticDiagnostics(sourceFile));
29534
+ } else {
29535
+ collected.push(...program.getSyntacticDiagnostics());
29536
+ collected.push(...program.getSemanticDiagnostics());
29537
+ }
29538
+ const diagnostics = [];
29539
+ for (const d of collected) {
29540
+ if (tolerateRepoRelative && isRepoRelativeMissingModule(d, sample.code)) {
29541
+ continue;
29542
+ }
29543
+ diagnostics.push(formatDiagnostic(d));
29544
+ }
29545
+ return diagnostics;
29546
+ }
29547
+ function sampleFilename(sample) {
29548
+ const safeDoc = sample.docPath.replace(/[^a-zA-Z0-9]+/g, "_");
29549
+ const ext = sample.lang === SampleLang.Tsx || sample.lang === SampleLang.Typescriptreact ? "tsx" : "ts";
29550
+ return path4.posix.join("/", `${safeDoc}__${sample.fenceIndex}.${ext}`);
29551
+ }
29552
+ function mergeCompilerOptions(overrides) {
29553
+ if (!overrides) {
29554
+ return { ...DEFAULT_SAMPLE_COMPILER_OPTIONS };
29555
+ }
29556
+ const merged = { ...DEFAULT_SAMPLE_COMPILER_OPTIONS };
29557
+ for (const key of Object.keys(overrides)) {
29558
+ const value = overrides[key];
29559
+ if (value === void 0) {
29560
+ delete merged[key];
29561
+ } else {
29562
+ merged[key] = value;
29563
+ }
29564
+ }
29565
+ return merged;
29566
+ }
29567
+ function createSingleFileHost(filename, source, compilerOptions) {
29568
+ const baseHost = ts.createCompilerHost(compilerOptions, true);
29569
+ return {
29570
+ ...baseHost,
29571
+ getSourceFile(name, languageVersionOrOptions, onError, shouldCreate) {
29572
+ if (name === filename) {
29573
+ return ts.createSourceFile(
29574
+ name,
29575
+ source,
29576
+ languageVersionOrOptions,
29577
+ true
29578
+ );
29579
+ }
29580
+ return baseHost.getSourceFile(
29581
+ name,
29582
+ languageVersionOrOptions,
29583
+ onError,
29584
+ shouldCreate
29585
+ );
29586
+ },
29587
+ fileExists(name) {
29588
+ if (name === filename) {
29589
+ return true;
29590
+ }
29591
+ return baseHost.fileExists(name);
29592
+ },
29593
+ readFile(name) {
29594
+ if (name === filename) {
29595
+ return source;
29596
+ }
29597
+ return baseHost.readFile(name);
29598
+ },
29599
+ writeFile() {
29600
+ },
29601
+ getCanonicalFileName(name) {
29602
+ return baseHost.getCanonicalFileName(name);
29603
+ },
29604
+ useCaseSensitiveFileNames() {
29605
+ return baseHost.useCaseSensitiveFileNames();
29606
+ },
29607
+ getNewLine() {
29608
+ return baseHost.getNewLine();
29609
+ },
29610
+ getDefaultLibFileName(o) {
29611
+ return baseHost.getDefaultLibFileName(o);
29612
+ },
29613
+ getCurrentDirectory() {
29614
+ return baseHost.getCurrentDirectory();
29615
+ }
29616
+ };
29617
+ }
29618
+ function isRepoRelativeMissingModule(d, code) {
29619
+ if (d.code !== 2307) {
29620
+ return false;
29621
+ }
29622
+ const text = ts.flattenDiagnosticMessageText(d.messageText, "\n");
29623
+ const match = /'([^']+)'/.exec(text);
29624
+ if (!match) {
29625
+ return false;
29626
+ }
29627
+ const specifier = match[1];
29628
+ if (!specifier) {
29629
+ return false;
29630
+ }
29631
+ const inSourceSingle = `'${specifier}'`;
29632
+ const inSourceDouble = `"${specifier}"`;
29633
+ if (!code.includes(inSourceSingle) && !code.includes(inSourceDouble)) {
29634
+ return false;
29635
+ }
29636
+ return REPO_RELATIVE_MODULE_PATTERN.test(`'${specifier}'`);
29637
+ }
29638
+ function formatDiagnostic(d) {
29639
+ const text = ts.flattenDiagnosticMessageText(d.messageText, " ");
29640
+ const code = d.code === void 0 ? "" : `TS${d.code}: `;
29641
+ return `${code}${text}`.trim();
29642
+ }
29643
+
29644
+ // src/docs-sync/tsdoc-coverage/coverage.ts
29645
+ var path5 = __toESM(require("path"));
29169
29646
  var import_tsdoc = require("@microsoft/tsdoc");
29170
- var ts = __toESM(require("typescript"));
29647
+ var ts2 = __toESM(require("typescript"));
29171
29648
  var TsDocCoverageKind = {
29172
29649
  Class: "Class",
29173
29650
  Interface: "Interface",
@@ -29183,8 +29660,8 @@ var DEFAULT_THIN_SUMMARY_WORD_THRESHOLD = 4;
29183
29660
  var DEFAULT_ENTRY_POINT = "src/index.ts";
29184
29661
  function analyzeTsDocCoverage(options) {
29185
29662
  const resolvedOptions = typeof options === "string" ? { packageRoot: options } : options;
29186
- const packageRoot = path3.resolve(resolvedOptions.packageRoot);
29187
- const entryPoint = path3.resolve(
29663
+ const packageRoot = path5.resolve(resolvedOptions.packageRoot);
29664
+ const entryPoint = path5.resolve(
29188
29665
  packageRoot,
29189
29666
  resolvedOptions.entryPoint ?? DEFAULT_ENTRY_POINT
29190
29667
  );
@@ -29193,7 +29670,7 @@ function analyzeTsDocCoverage(options) {
29193
29670
  packageRoot,
29194
29671
  resolvedOptions.tsconfigPath
29195
29672
  );
29196
- const program = ts.createProgram({
29673
+ const program = ts2.createProgram({
29197
29674
  rootNames: [entryPoint],
29198
29675
  options: compilerOptions
29199
29676
  });
@@ -29247,24 +29724,24 @@ function analyzeTsDocCoverage(options) {
29247
29724
  }
29248
29725
  function resolveCompilerOptions(packageRoot, tsconfigPath) {
29249
29726
  if (tsconfigPath) {
29250
- const absoluteTsconfig = path3.resolve(packageRoot, tsconfigPath);
29251
- const configFile = ts.readConfigFile(absoluteTsconfig, ts.sys.readFile);
29727
+ const absoluteTsconfig = path5.resolve(packageRoot, tsconfigPath);
29728
+ const configFile = ts2.readConfigFile(absoluteTsconfig, ts2.sys.readFile);
29252
29729
  if (configFile.error) {
29253
29730
  throw new Error(
29254
- `analyzeTsDocCoverage: failed to read tsconfig at ${absoluteTsconfig}: ${ts.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`
29731
+ `analyzeTsDocCoverage: failed to read tsconfig at ${absoluteTsconfig}: ${ts2.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`
29255
29732
  );
29256
29733
  }
29257
- const parsed = ts.parseJsonConfigFileContent(
29734
+ const parsed = ts2.parseJsonConfigFileContent(
29258
29735
  configFile.config,
29259
- ts.sys,
29260
- path3.dirname(absoluteTsconfig)
29736
+ ts2.sys,
29737
+ path5.dirname(absoluteTsconfig)
29261
29738
  );
29262
29739
  return { ...parsed.options, noEmit: true };
29263
29740
  }
29264
29741
  return {
29265
- target: ts.ScriptTarget.ESNext,
29266
- module: ts.ModuleKind.NodeNext,
29267
- moduleResolution: ts.ModuleResolutionKind.NodeNext,
29742
+ target: ts2.ScriptTarget.ESNext,
29743
+ module: ts2.ModuleKind.NodeNext,
29744
+ moduleResolution: ts2.ModuleResolutionKind.NodeNext,
29268
29745
  allowJs: false,
29269
29746
  declaration: false,
29270
29747
  noEmit: true,
@@ -29289,7 +29766,7 @@ function resolveAlias(symbol, checker) {
29289
29766
  return current;
29290
29767
  }
29291
29768
  function isAlias(symbol) {
29292
- return (symbol.flags & ts.SymbolFlags.Alias) !== 0;
29769
+ return (symbol.flags & ts2.SymbolFlags.Alias) !== 0;
29293
29770
  }
29294
29771
  function pickPrimaryDeclaration(symbol) {
29295
29772
  const declarations = symbol.getDeclarations();
@@ -29297,53 +29774,53 @@ function pickPrimaryDeclaration(symbol) {
29297
29774
  return void 0;
29298
29775
  }
29299
29776
  const concrete = declarations.find(
29300
- (d) => !ts.isExportSpecifier(d) && !ts.isExportAssignment(d) && !ts.isExportDeclaration(d)
29777
+ (d) => !ts2.isExportSpecifier(d) && !ts2.isExportAssignment(d) && !ts2.isExportDeclaration(d)
29301
29778
  );
29302
29779
  return concrete ?? declarations[0];
29303
29780
  }
29304
29781
  function classifyDeclaration(declaration) {
29305
- if (ts.isClassDeclaration(declaration)) {
29782
+ if (ts2.isClassDeclaration(declaration)) {
29306
29783
  return TsDocCoverageKind.Class;
29307
29784
  }
29308
- if (ts.isInterfaceDeclaration(declaration)) {
29785
+ if (ts2.isInterfaceDeclaration(declaration)) {
29309
29786
  return TsDocCoverageKind.Interface;
29310
29787
  }
29311
- if (ts.isTypeAliasDeclaration(declaration)) {
29788
+ if (ts2.isTypeAliasDeclaration(declaration)) {
29312
29789
  return TsDocCoverageKind.TypeAlias;
29313
29790
  }
29314
- if (ts.isEnumDeclaration(declaration)) {
29791
+ if (ts2.isEnumDeclaration(declaration)) {
29315
29792
  return TsDocCoverageKind.Enum;
29316
29793
  }
29317
- if (ts.isFunctionDeclaration(declaration) || ts.isMethodDeclaration(declaration)) {
29794
+ if (ts2.isFunctionDeclaration(declaration) || ts2.isMethodDeclaration(declaration)) {
29318
29795
  return TsDocCoverageKind.Function;
29319
29796
  }
29320
- if (ts.isVariableDeclaration(declaration) || ts.isVariableStatement(declaration)) {
29797
+ if (ts2.isVariableDeclaration(declaration) || ts2.isVariableStatement(declaration)) {
29321
29798
  return TsDocCoverageKind.Variable;
29322
29799
  }
29323
- if (ts.isModuleDeclaration(declaration)) {
29800
+ if (ts2.isModuleDeclaration(declaration)) {
29324
29801
  return TsDocCoverageKind.Module;
29325
29802
  }
29326
- if (ts.isExportAssignment(declaration)) {
29803
+ if (ts2.isExportAssignment(declaration)) {
29327
29804
  return TsDocCoverageKind.Default;
29328
29805
  }
29329
29806
  return TsDocCoverageKind.Other;
29330
29807
  }
29331
29808
  function resolveLocation(declaration) {
29332
- const target = ts.isVariableDeclaration(declaration) ? declaration.parent.parent ?? declaration : declaration;
29809
+ const target = ts2.isVariableDeclaration(declaration) ? declaration.parent.parent ?? declaration : declaration;
29333
29810
  const source = target.getSourceFile();
29334
29811
  const { line } = source.getLineAndCharacterOfPosition(target.getStart());
29335
29812
  return { file: source.fileName, line: line + 1 };
29336
29813
  }
29337
29814
  function parseTsDocFor(declaration, parser) {
29338
- const target = ts.isVariableDeclaration(declaration) ? declaration.parent.parent ?? declaration : declaration;
29815
+ const target = ts2.isVariableDeclaration(declaration) ? declaration.parent.parent ?? declaration : declaration;
29339
29816
  const sourceText = target.getSourceFile().getFullText();
29340
- const ranges = ts.getLeadingCommentRanges(sourceText, target.getFullStart());
29817
+ const ranges = ts2.getLeadingCommentRanges(sourceText, target.getFullStart());
29341
29818
  if (!ranges || ranges.length === 0) {
29342
29819
  return void 0;
29343
29820
  }
29344
29821
  for (let i = ranges.length - 1; i >= 0; i--) {
29345
29822
  const range = ranges[i];
29346
- if (range.kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
29823
+ if (range.kind !== ts2.SyntaxKind.MultiLineCommentTrivia) {
29347
29824
  continue;
29348
29825
  }
29349
29826
  const text = sourceText.slice(range.pos, range.end);
@@ -29566,14 +30043,14 @@ var LAYOUT_ROOT_BY_PROJECT_TYPE = {
29566
30043
  };
29567
30044
  function validateMonorepoLayout(root) {
29568
30045
  const violations = [];
29569
- const rootOutdir = toPosix2(root.outdir);
30046
+ const rootOutdir = toPosix3(root.outdir);
29570
30047
  for (const sub of root.subprojects) {
29571
30048
  const className = sub.constructor.name;
29572
30049
  const expectedRoot = expectedRootFor(sub, className);
29573
30050
  if (expectedRoot === void 0) {
29574
30051
  continue;
29575
30052
  }
29576
- const relOutdir = relativeOutdir(rootOutdir, toPosix2(sub.outdir));
30053
+ const relOutdir = relativeOutdir(rootOutdir, toPosix3(sub.outdir));
29577
30054
  if (!outdirMatchesRoot(relOutdir, expectedRoot)) {
29578
30055
  violations.push({
29579
30056
  projectName: sub.name,
@@ -29632,7 +30109,7 @@ function outdirMatchesRoot(relOutdir, expectedRoot) {
29632
30109
  }
29633
30110
  return segments.length >= 2;
29634
30111
  }
29635
- function toPosix2(p) {
30112
+ function toPosix3(p) {
29636
30113
  return p.replace(/\\/g, "/");
29637
30114
  }
29638
30115
  function relativeOutdir(rootOutdir, subOutdir) {
@@ -29712,8 +30189,8 @@ var ResetTask = class _ResetTask extends import_projen14.Component {
29712
30189
  const resetTask = this.project.tasks.addTask(this.taskName, {
29713
30190
  description: "Delete build artifacts specified by pathsToRemove option, or artifactsDirectory if pathsToRemove is empty"
29714
30191
  });
29715
- this.pathsToRemove.forEach((path4) => {
29716
- resetTask.exec(`[ -e "${path4}" ] && rm -rf ${path4} || true`);
30192
+ this.pathsToRemove.forEach((path6) => {
30193
+ resetTask.exec(`[ -e "${path6}" ] && rm -rf ${path6} || true`);
29717
30194
  });
29718
30195
  const rootHasTurbo = TurboRepo.of(this.project.root) !== void 0;
29719
30196
  const isSubproject = this.project !== this.project.root;
@@ -31695,6 +32172,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
31695
32172
  DEFAULT_PROGRESS_FILES_STATE_DIR,
31696
32173
  DEFAULT_REQUIRE_LINKED_ISSUE,
31697
32174
  DEFAULT_REQUIRE_PRODUCT_CONTEXT,
32175
+ DEFAULT_SAMPLE_COMPILER_OPTIONS,
31698
32176
  DEFAULT_SCHEDULED_TASKS_ROOT,
31699
32177
  DEFAULT_SCHEDULED_TASK_ENTRIES,
31700
32178
  DEFAULT_SHARED_EDITING_CONFLICT_STRATEGY,
@@ -31740,6 +32218,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
31740
32218
  SCOPE_CLASS_VALUES,
31741
32219
  SHARED_EDITING_CONFLICT_STRATEGY_VALUES,
31742
32220
  STARLIGHT_ROLE,
32221
+ SampleLang,
31743
32222
  StarlightProject,
31744
32223
  TestRunner,
31745
32224
  TsDocCoverageKind,
@@ -31782,14 +32261,17 @@ var TypeScriptConfig = class extends import_projen23.Component {
31782
32261
  buildStandardsResearchBundle,
31783
32262
  buildUnblockDependentsProcedure,
31784
32263
  businessModelsBundle,
32264
+ checkDocSamplesProcedure,
31785
32265
  checkLinksProcedure,
31786
32266
  classifyIssueScope,
31787
32267
  classifyRun,
31788
32268
  companyProfileBundle,
32269
+ compileFencedSamples,
31789
32270
  customerProfileBundle,
31790
32271
  docsSyncBundle,
31791
32272
  extractApiProcedure,
31792
32273
  extractDocReferences,
32274
+ extractFencedSamples,
31793
32275
  formatLayoutViolation,
31794
32276
  formatStarlightSingletonViolation,
31795
32277
  getLatestEligibleVersion,
@@ -31806,6 +32288,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
31806
32288
  regulatoryResearchBundle,
31807
32289
  renderAgentTierCaseStatement,
31808
32290
  renderAgentTierSection,
32291
+ renderCheckDocSamplesProcedure,
31809
32292
  renderCheckLinksProcedure,
31810
32293
  renderCustomDocSectionBlock,
31811
32294
  renderCustomDocSections,