@codedrifters/configulator 0.0.276 → 0.0.277

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.mjs CHANGED
@@ -26554,8 +26554,8 @@ var FALLBACKS = {
26554
26554
  monorepoLayoutSeedBlock: ""
26555
26555
  };
26556
26556
  var TEMPLATE_RE = /\{\{(\w+(?:\.\w+)*)\}\}/g;
26557
- function getNestedValue(obj, path7) {
26558
- const parts = path7.split(".");
26557
+ function getNestedValue(obj, path8) {
26558
+ const parts = path8.split(".");
26559
26559
  let current = obj;
26560
26560
  for (const part of parts) {
26561
26561
  if (current == null || typeof current !== "object") {
@@ -29164,9 +29164,388 @@ function auditReportJsonSchema() {
29164
29164
  };
29165
29165
  }
29166
29166
 
29167
+ // src/docs-sync/scan/checks/api-diff-check.ts
29168
+ function parseApiRollup(rollup) {
29169
+ const fenceContents = extractFirstTsFence(rollup);
29170
+ if (fenceContents === void 0) {
29171
+ return [];
29172
+ }
29173
+ const lines = fenceContents.split("\n");
29174
+ const entries = [];
29175
+ let i = 0;
29176
+ while (i < lines.length) {
29177
+ const line = lines[i];
29178
+ const trimmed = line.trim();
29179
+ if (!trimmed.startsWith("export ")) {
29180
+ i += 1;
29181
+ continue;
29182
+ }
29183
+ const startIndex = i;
29184
+ let buffer = trimmed;
29185
+ let braceDepth = countBraceDelta(trimmed);
29186
+ let endsWithSemicolon = trimmed.endsWith(";");
29187
+ i += 1;
29188
+ while (i < lines.length && !isComplete(buffer, braceDepth, endsWithSemicolon)) {
29189
+ const next = lines[i];
29190
+ const nextTrimmed = next.trim();
29191
+ if (nextTrimmed.length === 0 || nextTrimmed.startsWith("//")) {
29192
+ i += 1;
29193
+ continue;
29194
+ }
29195
+ buffer = `${buffer} ${nextTrimmed}`;
29196
+ braceDepth += countBraceDelta(nextTrimmed);
29197
+ endsWithSemicolon = nextTrimmed.endsWith(";");
29198
+ i += 1;
29199
+ }
29200
+ const normalized = normalizeWhitespace(buffer);
29201
+ const name = extractDeclarationName(normalized);
29202
+ if (name) {
29203
+ entries.push({ name, signature: normalized });
29204
+ }
29205
+ if (name && normalized.startsWith("export {")) {
29206
+ const names = extractExportListNames(normalized);
29207
+ if (names.length > 1) {
29208
+ entries.pop();
29209
+ for (const exportName of names) {
29210
+ entries.push({ name: exportName, signature: normalized });
29211
+ }
29212
+ }
29213
+ }
29214
+ if (i === startIndex) {
29215
+ i += 1;
29216
+ }
29217
+ }
29218
+ const dedup = /* @__PURE__ */ new Map();
29219
+ for (const entry of entries) {
29220
+ if (!dedup.has(entry.name)) {
29221
+ dedup.set(entry.name, entry);
29222
+ }
29223
+ }
29224
+ return Array.from(dedup.values()).sort(
29225
+ (a, b) => a.name.localeCompare(b.name)
29226
+ );
29227
+ }
29228
+ function diffApiRollups(baselineRollup, currentRollup) {
29229
+ const baseline = /* @__PURE__ */ new Map();
29230
+ for (const entry of parseApiRollup(baselineRollup)) {
29231
+ baseline.set(entry.name, entry);
29232
+ }
29233
+ const current = /* @__PURE__ */ new Map();
29234
+ for (const entry of parseApiRollup(currentRollup)) {
29235
+ current.set(entry.name, entry);
29236
+ }
29237
+ const added = [];
29238
+ const removed = [];
29239
+ const changed = [];
29240
+ for (const [name, entry] of current.entries()) {
29241
+ const before = baseline.get(name);
29242
+ if (!before) {
29243
+ added.push(entry);
29244
+ continue;
29245
+ }
29246
+ if (before.signature !== entry.signature) {
29247
+ changed.push(entry);
29248
+ }
29249
+ }
29250
+ for (const [name, entry] of baseline.entries()) {
29251
+ if (!current.has(name)) {
29252
+ removed.push(entry);
29253
+ }
29254
+ }
29255
+ added.sort((a, b) => a.name.localeCompare(b.name));
29256
+ removed.sort((a, b) => a.name.localeCompare(b.name));
29257
+ changed.sort((a, b) => a.name.localeCompare(b.name));
29258
+ return { added, removed, changed };
29259
+ }
29260
+ function createApiDiffCheck(options) {
29261
+ const baseline = options.baselineRollup;
29262
+ const current = options.currentRollup;
29263
+ const rollupPath = options.rollupPath ?? "";
29264
+ return {
29265
+ name: options.name ?? "apiDiff",
29266
+ run(_context) {
29267
+ const diff = diffApiRollups(baseline, current);
29268
+ const findings = [];
29269
+ for (const entry of diff.added) {
29270
+ findings.push({
29271
+ category: AuditCategory.ApiDiff,
29272
+ severity: AuditSeverity.Mechanical,
29273
+ location: { file: rollupPath, line: 0 },
29274
+ subject: entry.name,
29275
+ details: `New public export \`${entry.name}\` not present in baseline rollup.`,
29276
+ change: "added",
29277
+ symbol: entry.name,
29278
+ fixHint: "stub-tsdoc"
29279
+ });
29280
+ }
29281
+ for (const entry of diff.removed) {
29282
+ findings.push({
29283
+ category: AuditCategory.ApiDiff,
29284
+ severity: AuditSeverity.Advisory,
29285
+ location: { file: rollupPath, line: 0 },
29286
+ subject: entry.name,
29287
+ details: `Public export \`${entry.name}\` was present in baseline rollup but is gone in the current rollup.`,
29288
+ change: "removed",
29289
+ symbol: entry.name
29290
+ });
29291
+ }
29292
+ for (const entry of diff.changed) {
29293
+ findings.push({
29294
+ category: AuditCategory.ApiDiff,
29295
+ severity: AuditSeverity.Advisory,
29296
+ location: { file: rollupPath, line: 0 },
29297
+ subject: entry.name,
29298
+ details: `Public export \`${entry.name}\` signature changed since baseline rollup.`,
29299
+ change: "changed",
29300
+ symbol: entry.name
29301
+ });
29302
+ }
29303
+ return findings;
29304
+ }
29305
+ };
29306
+ }
29307
+ function extractFirstTsFence(rollup) {
29308
+ const lines = rollup.split("\n");
29309
+ let start = -1;
29310
+ for (let i = 0; i < lines.length; i++) {
29311
+ const line = lines[i].trim();
29312
+ if (line === "```ts" || line === "```typescript") {
29313
+ start = i + 1;
29314
+ break;
29315
+ }
29316
+ }
29317
+ if (start < 0) {
29318
+ return void 0;
29319
+ }
29320
+ for (let j = start; j < lines.length; j++) {
29321
+ if (lines[j].trim() === "```") {
29322
+ return lines.slice(start, j).join("\n");
29323
+ }
29324
+ }
29325
+ return lines.slice(start).join("\n");
29326
+ }
29327
+ function countBraceDelta(line) {
29328
+ let delta = 0;
29329
+ for (const ch of line) {
29330
+ if (ch === "{") {
29331
+ delta += 1;
29332
+ } else if (ch === "}") {
29333
+ delta -= 1;
29334
+ }
29335
+ }
29336
+ return delta;
29337
+ }
29338
+ function isComplete(buffer, braceDepth, endsWithSemicolon) {
29339
+ if (braceDepth > 0) {
29340
+ return false;
29341
+ }
29342
+ if (endsWithSemicolon) {
29343
+ return true;
29344
+ }
29345
+ return buffer.trimEnd().endsWith("}");
29346
+ }
29347
+ function normalizeWhitespace(s) {
29348
+ return s.replace(/\s+/g, " ").replace(/\(\s+/g, "(").replace(/\s+\)/g, ")").replace(/\[\s+/g, "[").replace(/\s+\]/g, "]").replace(/\{\s+/g, "{").replace(/\s+\}/g, "}").replace(/\s+,/g, ",").replace(/\s+;/g, ";").replace(/\s+:/g, ":").trim();
29349
+ }
29350
+ var DECLARATION_KEYWORDS = [
29351
+ "function",
29352
+ "class",
29353
+ "interface",
29354
+ "type",
29355
+ "enum",
29356
+ "const",
29357
+ "let",
29358
+ "var",
29359
+ "namespace",
29360
+ "abstract",
29361
+ "default",
29362
+ "async"
29363
+ ];
29364
+ function extractDeclarationName(declaration) {
29365
+ const tokens = declaration.split(/\s+/);
29366
+ if (tokens.length === 0 || tokens[0] !== "export") {
29367
+ return void 0;
29368
+ }
29369
+ let cursor = 1;
29370
+ while (cursor < tokens.length && DECLARATION_KEYWORDS.includes(tokens[cursor])) {
29371
+ cursor += 1;
29372
+ }
29373
+ if (cursor >= tokens.length) {
29374
+ return void 0;
29375
+ }
29376
+ const candidate = tokens[cursor];
29377
+ if (candidate.startsWith("{")) {
29378
+ const stripped = candidate.replace(/^\{/, "").replace(/[},].*$/, "");
29379
+ return stripped || void 0;
29380
+ }
29381
+ const cleaned = candidate.replace(/[<(:;].*$/, "");
29382
+ return cleaned || void 0;
29383
+ }
29384
+ function extractExportListNames(declaration) {
29385
+ const open = declaration.indexOf("{");
29386
+ const close = declaration.indexOf("}", open);
29387
+ if (open < 0 || close < 0) {
29388
+ return [];
29389
+ }
29390
+ const inside = declaration.slice(open + 1, close);
29391
+ const names = [];
29392
+ for (const part of inside.split(",")) {
29393
+ const token = part.trim();
29394
+ if (!token) {
29395
+ continue;
29396
+ }
29397
+ const asMatch = token.match(/\sas\s+(\S+)$/);
29398
+ if (asMatch) {
29399
+ names.push(asMatch[1]);
29400
+ } else {
29401
+ names.push(token);
29402
+ }
29403
+ }
29404
+ return names;
29405
+ }
29406
+
29407
+ // src/docs-sync/scan/checks/reference-mismatch-check.ts
29408
+ function referenceRecordToFinding(record, signatureChangedSymbols) {
29409
+ if (signatureChangedSymbols.has(record.symbol)) {
29410
+ return {
29411
+ category: AuditCategory.ReferenceMismatches,
29412
+ severity: AuditSeverity.Advisory,
29413
+ location: { file: record.docPath, line: record.line },
29414
+ subject: record.symbol,
29415
+ details: `Inline reference \`${record.symbol}\` resolves to a symbol whose signature has changed; review the surrounding prose.`,
29416
+ mismatch: "signature-changed",
29417
+ symbol: record.symbol
29418
+ };
29419
+ }
29420
+ if (!record.isKnown) {
29421
+ return {
29422
+ category: AuditCategory.ReferenceMismatches,
29423
+ severity: AuditSeverity.Advisory,
29424
+ location: { file: record.docPath, line: record.line },
29425
+ subject: record.symbol,
29426
+ details: `Inline reference \`${record.symbol}\` does not match any known public export.`,
29427
+ mismatch: "unknown-symbol",
29428
+ symbol: record.symbol
29429
+ };
29430
+ }
29431
+ return void 0;
29432
+ }
29433
+ function createReferenceMismatchCheck(options) {
29434
+ const records = options.records;
29435
+ const signatureChangedSymbols = new Set(
29436
+ options.signatureChangedSymbols ?? []
29437
+ );
29438
+ return {
29439
+ name: options.name ?? "referenceMismatches",
29440
+ run(_context) {
29441
+ const findings = [];
29442
+ for (const record of records) {
29443
+ const finding = referenceRecordToFinding(
29444
+ record,
29445
+ signatureChangedSymbols
29446
+ );
29447
+ if (finding !== void 0) {
29448
+ findings.push(finding);
29449
+ }
29450
+ }
29451
+ return findings;
29452
+ }
29453
+ };
29454
+ }
29455
+
29456
+ // src/docs-sync/scan/checks/tsdoc-coverage-check.ts
29457
+ import * as path5 from "path";
29458
+ function tsdocRecordToFindings(record, context) {
29459
+ const findings = [];
29460
+ const file = relativizeFile(record.location.file, context.repoRoot);
29461
+ const line = record.location.line;
29462
+ const symbol = record.symbol;
29463
+ if (!record.hasSummary) {
29464
+ findings.push({
29465
+ category: AuditCategory.TsdocCoverage,
29466
+ severity: AuditSeverity.Mechanical,
29467
+ location: { file, line },
29468
+ subject: symbol,
29469
+ details: `Public export \`${symbol}\` is missing a TSDoc summary.`,
29470
+ shortfall: "missing-summary",
29471
+ symbol,
29472
+ fixHint: "stub-tsdoc"
29473
+ });
29474
+ return findings;
29475
+ }
29476
+ if (record.hasThinSummary) {
29477
+ findings.push({
29478
+ category: AuditCategory.TsdocCoverage,
29479
+ severity: AuditSeverity.Advisory,
29480
+ location: { file, line },
29481
+ subject: symbol,
29482
+ details: `Public export \`${symbol}\` carries a thin TSDoc summary; consider expanding it.`,
29483
+ shortfall: "thin-summary",
29484
+ symbol
29485
+ });
29486
+ }
29487
+ if (!record.hasParams && isParamCarryingKind(record)) {
29488
+ findings.push({
29489
+ category: AuditCategory.TsdocCoverage,
29490
+ severity: AuditSeverity.Advisory,
29491
+ location: { file, line },
29492
+ subject: symbol,
29493
+ details: `Public export \`${symbol}\` has parameters with no \`@param\` block tag.`,
29494
+ shortfall: "missing-params",
29495
+ symbol
29496
+ });
29497
+ }
29498
+ if (!record.hasReturns && isReturnCarryingKind(record)) {
29499
+ findings.push({
29500
+ category: AuditCategory.TsdocCoverage,
29501
+ severity: AuditSeverity.Advisory,
29502
+ location: { file, line },
29503
+ subject: symbol,
29504
+ details: `Public export \`${symbol}\` has a return value with no \`@returns\` block tag.`,
29505
+ shortfall: "missing-returns",
29506
+ symbol
29507
+ });
29508
+ }
29509
+ return findings;
29510
+ }
29511
+ function createTsdocCoverageCheck(options) {
29512
+ const records = options.records;
29513
+ return {
29514
+ name: options.name ?? "tsdocCoverage",
29515
+ run(context) {
29516
+ const findings = [];
29517
+ for (const record of records) {
29518
+ for (const finding of tsdocRecordToFindings(record, context)) {
29519
+ findings.push(finding);
29520
+ }
29521
+ }
29522
+ return findings;
29523
+ }
29524
+ };
29525
+ }
29526
+ function isParamCarryingKind(record) {
29527
+ return record.kind === "Function";
29528
+ }
29529
+ function isReturnCarryingKind(record) {
29530
+ return record.kind === "Function";
29531
+ }
29532
+ function relativizeFile(file, repoRoot) {
29533
+ if (!file) {
29534
+ return "";
29535
+ }
29536
+ if (!path5.isAbsolute(file)) {
29537
+ return toPosix3(file);
29538
+ }
29539
+ const rel = path5.relative(repoRoot, file);
29540
+ return toPosix3(rel);
29541
+ }
29542
+ function toPosix3(p) {
29543
+ return p.split(path5.sep).join("/");
29544
+ }
29545
+
29167
29546
  // src/docs-sync/scan/run-scan.ts
29168
29547
  import * as fs3 from "fs";
29169
- import * as path5 from "path";
29548
+ import * as path6 from "path";
29170
29549
  var DEFAULT_AUDIT_REPORT_DIR = ".claude/state/docs-sync";
29171
29550
  var SEVERITY_RANK = {
29172
29551
  blocking: 0,
@@ -29181,7 +29560,7 @@ var AUDIT_CATEGORY_ORDER = [
29181
29560
  AuditCategory.SampleFailures
29182
29561
  ];
29183
29562
  function runScan(options) {
29184
- const repoRoot = path5.resolve(options.repoRoot);
29563
+ const repoRoot = path6.resolve(options.repoRoot);
29185
29564
  const mode = options.mode;
29186
29565
  const scope = options.scope ?? "";
29187
29566
  const issueNumber = options.issueNumber;
@@ -29256,11 +29635,11 @@ function buildReport(args) {
29256
29635
  };
29257
29636
  }
29258
29637
  function persistAuditReport(args) {
29259
- const repoRoot = path5.resolve(args.repoRoot);
29638
+ const repoRoot = path6.resolve(args.repoRoot);
29260
29639
  const reportDir = args.reportDir ?? DEFAULT_AUDIT_REPORT_DIR;
29261
- const targetDir = path5.resolve(repoRoot, reportDir);
29640
+ const targetDir = path6.resolve(repoRoot, reportDir);
29262
29641
  fs3.mkdirSync(targetDir, { recursive: true });
29263
- const targetFile = path5.join(
29642
+ const targetFile = path6.join(
29264
29643
  targetDir,
29265
29644
  `${args.report.issueNumber}-audit.json`
29266
29645
  );
@@ -29323,7 +29702,7 @@ function compareFindings(a, b) {
29323
29702
  }
29324
29703
 
29325
29704
  // src/docs-sync/tsdoc-coverage/coverage.ts
29326
- import * as path6 from "path";
29705
+ import * as path7 from "path";
29327
29706
  import { TSDocParser } from "@microsoft/tsdoc";
29328
29707
  import * as ts2 from "typescript";
29329
29708
  var TsDocCoverageKind = {
@@ -29341,8 +29720,8 @@ var DEFAULT_THIN_SUMMARY_WORD_THRESHOLD = 4;
29341
29720
  var DEFAULT_ENTRY_POINT = "src/index.ts";
29342
29721
  function analyzeTsDocCoverage(options) {
29343
29722
  const resolvedOptions = typeof options === "string" ? { packageRoot: options } : options;
29344
- const packageRoot = path6.resolve(resolvedOptions.packageRoot);
29345
- const entryPoint = path6.resolve(
29723
+ const packageRoot = path7.resolve(resolvedOptions.packageRoot);
29724
+ const entryPoint = path7.resolve(
29346
29725
  packageRoot,
29347
29726
  resolvedOptions.entryPoint ?? DEFAULT_ENTRY_POINT
29348
29727
  );
@@ -29405,7 +29784,7 @@ function analyzeTsDocCoverage(options) {
29405
29784
  }
29406
29785
  function resolveCompilerOptions(packageRoot, tsconfigPath) {
29407
29786
  if (tsconfigPath) {
29408
- const absoluteTsconfig = path6.resolve(packageRoot, tsconfigPath);
29787
+ const absoluteTsconfig = path7.resolve(packageRoot, tsconfigPath);
29409
29788
  const configFile = ts2.readConfigFile(absoluteTsconfig, ts2.sys.readFile);
29410
29789
  if (configFile.error) {
29411
29790
  throw new Error(
@@ -29415,7 +29794,7 @@ function resolveCompilerOptions(packageRoot, tsconfigPath) {
29415
29794
  const parsed = ts2.parseJsonConfigFileContent(
29416
29795
  configFile.config,
29417
29796
  ts2.sys,
29418
- path6.dirname(absoluteTsconfig)
29797
+ path7.dirname(absoluteTsconfig)
29419
29798
  );
29420
29799
  return { ...parsed.options, noEmit: true };
29421
29800
  }
@@ -29724,14 +30103,14 @@ var LAYOUT_ROOT_BY_PROJECT_TYPE = {
29724
30103
  };
29725
30104
  function validateMonorepoLayout(root) {
29726
30105
  const violations = [];
29727
- const rootOutdir = toPosix3(root.outdir);
30106
+ const rootOutdir = toPosix4(root.outdir);
29728
30107
  for (const sub of root.subprojects) {
29729
30108
  const className = sub.constructor.name;
29730
30109
  const expectedRoot = expectedRootFor(sub, className);
29731
30110
  if (expectedRoot === void 0) {
29732
30111
  continue;
29733
30112
  }
29734
- const relOutdir = relativeOutdir(rootOutdir, toPosix3(sub.outdir));
30113
+ const relOutdir = relativeOutdir(rootOutdir, toPosix4(sub.outdir));
29735
30114
  if (!outdirMatchesRoot(relOutdir, expectedRoot)) {
29736
30115
  violations.push({
29737
30116
  projectName: sub.name,
@@ -29790,7 +30169,7 @@ function outdirMatchesRoot(relOutdir, expectedRoot) {
29790
30169
  }
29791
30170
  return segments.length >= 2;
29792
30171
  }
29793
- function toPosix3(p) {
30172
+ function toPosix4(p) {
29794
30173
  return p.replace(/\\/g, "/");
29795
30174
  }
29796
30175
  function relativeOutdir(rootOutdir, subOutdir) {
@@ -29879,8 +30258,8 @@ var ResetTask = class _ResetTask extends Component14 {
29879
30258
  const resetTask = this.project.tasks.addTask(this.taskName, {
29880
30259
  description: "Delete build artifacts specified by pathsToRemove option, or artifactsDirectory if pathsToRemove is empty"
29881
30260
  });
29882
- this.pathsToRemove.forEach((path7) => {
29883
- resetTask.exec(`[ -e "${path7}" ] && rm -rf ${path7} || true`);
30261
+ this.pathsToRemove.forEach((path8) => {
30262
+ resetTask.exec(`[ -e "${path8}" ] && rm -rf ${path8} || true`);
29884
30263
  });
29885
30264
  const rootHasTurbo = TurboRepo.of(this.project.root) !== void 0;
29886
30265
  const isSubproject = this.project !== this.project.root;
@@ -31801,7 +32180,7 @@ export const collections = {
31801
32180
  `;
31802
32181
 
31803
32182
  // src/typescript/typescript-config.ts
31804
- import { relative as relative6 } from "path";
32183
+ import { relative as relative7 } from "path";
31805
32184
  import { Component as Component19 } from "projen";
31806
32185
  import { ensureRelativePathStartsWithDot } from "projen/lib/util/path";
31807
32186
  var TypeScriptConfig = class extends Component19 {
@@ -31820,7 +32199,7 @@ var TypeScriptConfig = class extends Component19 {
31820
32199
  ...tsPaths,
31821
32200
  [dep.name]: [
31822
32201
  ensureRelativePathStartsWithDot(
31823
- relative6(project.outdir, subproject.outdir)
32202
+ relative7(project.outdir, subproject.outdir)
31824
32203
  )
31825
32204
  ]
31826
32205
  };
@@ -31976,7 +32355,11 @@ export {
31976
32355
  classifyRun,
31977
32356
  companyProfileBundle,
31978
32357
  compileFencedSamples,
32358
+ createApiDiffCheck,
32359
+ createReferenceMismatchCheck,
32360
+ createTsdocCoverageCheck,
31979
32361
  customerProfileBundle,
32362
+ diffApiRollups,
31980
32363
  docsSyncBundle,
31981
32364
  emptyCategoryBuckets,
31982
32365
  extractApiProcedure,
@@ -31991,11 +32374,13 @@ export {
31991
32374
  maintenanceAuditBundle,
31992
32375
  meetingAnalysisBundle,
31993
32376
  orchestratorBundle,
32377
+ parseApiRollup,
31994
32378
  peopleProfileBundle,
31995
32379
  persistAuditReport,
31996
32380
  pnpmBundle,
31997
32381
  prReviewBundle,
31998
32382
  projenBundle,
32383
+ referenceRecordToFinding,
31999
32384
  regulatoryResearchBundle,
32000
32385
  renderAgentTierCaseStatement,
32001
32386
  renderAgentTierSection,
@@ -32058,6 +32443,7 @@ export {
32058
32443
  slackBundle,
32059
32444
  softwareProfileBundle,
32060
32445
  standardsResearchBundle,
32446
+ tsdocRecordToFindings,
32061
32447
  turborepoBundle,
32062
32448
  typescriptBundle,
32063
32449
  validateAgentTierConfig,