@archpilotlabs/archpilot 0.0.14 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/archpilot-cli.js +131 -19
  2. package/package.json +1 -1
@@ -211102,10 +211102,13 @@ var commonIgnoreDirectories = [
211102
211102
  "node_modules",
211103
211103
  ".git",
211104
211104
  ".archpilot",
211105
+ ".next",
211105
211106
  "dist",
211106
211107
  "build",
211107
211108
  "out",
211108
- "coverage"
211109
+ "coverage",
211110
+ "fixtures",
211111
+ "__fixtures__"
211109
211112
  ];
211110
211113
  var commonApiRoots = ["src/api", "api", "app/api"];
211111
211114
  var commonDatabaseRoots = ["db", "database", "prisma", "migrations"];
@@ -214843,9 +214846,13 @@ function hasDeclaredComponents(components) {
214843
214846
  }
214844
214847
  function getDeclaredComponentEntries(components) {
214845
214848
  const entries = Array.isArray(components) ? components.map((component, index) => [
214846
- component.id ?? `component-${index + 1}`,
214849
+ component?.id ?? `component-${index + 1}`,
214847
214850
  component
214848
- ]) : Object.entries(components).sort(([left], [right]) => left.localeCompare(right));
214851
+ ]).filter(
214852
+ (entry) => Boolean(entry[1])
214853
+ ) : Object.entries(components).filter(
214854
+ (entry) => Boolean(entry[1])
214855
+ ).sort(([left], [right]) => left.localeCompare(right));
214849
214856
  const seenPaths = /* @__PURE__ */ new Set();
214850
214857
  return entries.filter(([, component]) => {
214851
214858
  const normalizedPath = normalizeArchitectureWorkspacePath(component.path);
@@ -214882,9 +214889,13 @@ function normalizeResources(resources) {
214882
214889
  return void 0;
214883
214890
  }
214884
214891
  const entries = Array.isArray(resources) ? resources.map((resource, index) => [
214885
- resource.id ?? `resource-${index + 1}`,
214892
+ resource?.id ?? `resource-${index + 1}`,
214886
214893
  resource
214887
- ]) : Object.entries(resources).sort(([left], [right]) => left.localeCompare(right));
214894
+ ]).filter(
214895
+ (entry) => Boolean(entry[1])
214896
+ ) : Object.entries(resources).filter(
214897
+ (entry) => Boolean(entry[1])
214898
+ ).sort(([left], [right]) => left.localeCompare(right));
214888
214899
  return entries.map(([resourceId, resource]) => normalizeResource(resourceId, resource));
214889
214900
  }
214890
214901
  function normalizeArchitectureWorkspaceModel(contract) {
@@ -215256,6 +215267,31 @@ async function readPackageName(packageJsonPath) {
215256
215267
  return void 0;
215257
215268
  }
215258
215269
  }
215270
+ function collectPackageExportSubpaths(exportsValue) {
215271
+ if (typeof exportsValue === "string") {
215272
+ return ["."];
215273
+ }
215274
+ if (!exportsValue || typeof exportsValue !== "object" || Array.isArray(exportsValue)) {
215275
+ return [];
215276
+ }
215277
+ return Object.keys(exportsValue).filter((key) => key === "." || key.startsWith("./")).sort((left, right) => left.localeCompare(right));
215278
+ }
215279
+ async function readPackagePublicExportSubpaths(moduleRoot) {
215280
+ const contents = await readTextFileIfExists2(path7.join(moduleRoot, "package.json"));
215281
+ if (!contents) {
215282
+ return [];
215283
+ }
215284
+ try {
215285
+ const parsed = JSON.parse(contents);
215286
+ const exportSubpaths = collectPackageExportSubpaths(parsed.exports);
215287
+ if (exportSubpaths.length > 0) {
215288
+ return exportSubpaths;
215289
+ }
215290
+ return typeof parsed.main === "string" && parsed.main.trim().length > 0 ? ["."] : [];
215291
+ } catch {
215292
+ return [];
215293
+ }
215294
+ }
215259
215295
  async function buildWorkspacePackageAliasMap(workspaceRoot, moduleRoots) {
215260
215296
  const aliases = [];
215261
215297
  for (const [moduleId, moduleRoot] of [...moduleRoots.entries()].sort(
@@ -215269,7 +215305,8 @@ async function buildWorkspacePackageAliasMap(workspaceRoot, moduleRoots) {
215269
215305
  packageName,
215270
215306
  moduleId,
215271
215307
  moduleRoot,
215272
- targetRoot: await resolvePackageAliasSourceRoot(moduleRoot)
215308
+ targetRoot: await resolvePackageAliasSourceRoot(moduleRoot),
215309
+ publicExportSubpaths: await readPackagePublicExportSubpaths(moduleRoot)
215273
215310
  });
215274
215311
  }
215275
215312
  aliases.push(...await buildTsConfigPathAliasMap(workspaceRoot, moduleRoots));
@@ -215335,7 +215372,8 @@ async function buildTsConfigPathAliasMap(workspaceRoot, moduleRoots) {
215335
215372
  packageName: aliasPrefix,
215336
215373
  moduleId,
215337
215374
  moduleRoot,
215338
- targetRoot: absoluteTarget
215375
+ targetRoot: absoluteTarget,
215376
+ publicExportSubpaths: await readPackagePublicExportSubpaths(moduleRoot)
215339
215377
  });
215340
215378
  continue;
215341
215379
  }
@@ -215343,7 +215381,8 @@ async function buildTsConfigPathAliasMap(workspaceRoot, moduleRoots) {
215343
215381
  packageName: aliasPrefix,
215344
215382
  moduleId,
215345
215383
  moduleRoot,
215346
- targetFile: absoluteTarget
215384
+ targetFile: absoluteTarget,
215385
+ publicExportSubpaths: await readPackagePublicExportSubpaths(moduleRoot)
215347
215386
  });
215348
215387
  }
215349
215388
  }
@@ -215867,7 +215906,28 @@ function resolvePackageAliasRemainder(packageName, importSpecifier) {
215867
215906
  }
215868
215907
  return void 0;
215869
215908
  }
215870
- async function resolveWorkspacePackageImportPath(importSpecifier, workspacePackageAliases, adapter) {
215909
+ function packageExportPatternMatches(pattern, subpath) {
215910
+ if (!pattern.includes("*")) {
215911
+ return pattern === subpath;
215912
+ }
215913
+ const [prefix, suffix = ""] = pattern.split("*", 2);
215914
+ return subpath.startsWith(prefix) && subpath.endsWith(suffix);
215915
+ }
215916
+ function isImportSpecifierPackageExport(alias, importSpecifier) {
215917
+ const remainder = resolvePackageAliasRemainder(alias.packageName, importSpecifier);
215918
+ if (remainder === void 0) {
215919
+ return false;
215920
+ }
215921
+ const exportSubpaths = alias.publicExportSubpaths ?? [];
215922
+ if (exportSubpaths.length === 0) {
215923
+ return false;
215924
+ }
215925
+ const importSubpath = remainder.length === 0 ? "." : `./${remainder}`;
215926
+ return exportSubpaths.some(
215927
+ (exportSubpath) => packageExportPatternMatches(exportSubpath, importSubpath)
215928
+ );
215929
+ }
215930
+ async function resolveWorkspacePackageImportTarget(importSpecifier, workspacePackageAliases, adapter) {
215871
215931
  const packageAlias = workspacePackageAliases.map((alias2) => ({
215872
215932
  alias: alias2,
215873
215933
  remainder: resolvePackageAliasRemainder(alias2.packageName, importSpecifier)
@@ -215886,18 +215946,31 @@ async function resolveWorkspacePackageImportPath(importSpecifier, workspacePacka
215886
215946
  }
215887
215947
  const { alias, remainder } = packageAlias;
215888
215948
  if (remainder.length === 0) {
215889
- return resolveImportPath(alias.targetFile ?? alias.targetRoot ?? alias.moduleRoot, adapter);
215949
+ const resolvedPath = await resolveImportPath(alias.targetFile ?? alias.moduleRoot, adapter) ?? (alias.targetRoot && alias.targetRoot !== alias.moduleRoot ? await resolveImportPath(alias.targetRoot, adapter) : void 0);
215950
+ return resolvedPath ? {
215951
+ alias,
215952
+ resolvedPath,
215953
+ isPublicPackageImport: isImportSpecifierPackageExport(alias, importSpecifier)
215954
+ } : void 0;
215890
215955
  }
215891
215956
  if (alias.targetRoot) {
215892
- return resolveImportPath(
215957
+ const resolvedPath = await resolveImportPath(
215893
215958
  path7.join(alias.targetRoot, ...remainder.split("/").filter((segment) => segment.length > 0)),
215894
215959
  adapter
215895
215960
  );
215961
+ return resolvedPath ? {
215962
+ alias,
215963
+ resolvedPath,
215964
+ isPublicPackageImport: isImportSpecifierPackageExport(alias, importSpecifier)
215965
+ } : void 0;
215896
215966
  }
215897
215967
  return void 0;
215898
215968
  }
215899
215969
  async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath, moduleRoots, explicitStandaloneModuleByPath, workspacePackageAliases, sourceFilePath, importSpecifier, adapter) {
215900
215970
  let basePath;
215971
+ let packageAliasTargetModule;
215972
+ let packageAliasTargetModuleRoot;
215973
+ let isPublicPackageAliasImport = false;
215901
215974
  const normalizedModulesRoot = normalizePath3(modulesRootRelativePath).replace(/^\/+/, "");
215902
215975
  if (usesJavaImportParser(adapter) && !importSpecifier.startsWith(".")) {
215903
215976
  const resolvedJava = resolveJavaModuleImport(
@@ -215952,13 +216025,16 @@ async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath,
215952
216025
  } else if (normalizedModulesRoot.startsWith("src/") && importSpecifier.startsWith(`${normalizedModulesRoot.slice("src/".length)}/`)) {
215953
216026
  basePath = path7.join(workspaceRoot, "src", importSpecifier);
215954
216027
  } else {
215955
- const workspacePackageImportPath = await resolveWorkspacePackageImportPath(
216028
+ const workspacePackageImportTarget = await resolveWorkspacePackageImportTarget(
215956
216029
  importSpecifier,
215957
216030
  workspacePackageAliases,
215958
216031
  adapter
215959
216032
  );
215960
- if (workspacePackageImportPath) {
215961
- basePath = workspacePackageImportPath;
216033
+ if (workspacePackageImportTarget) {
216034
+ basePath = workspacePackageImportTarget.resolvedPath;
216035
+ packageAliasTargetModule = workspacePackageImportTarget.alias.moduleId;
216036
+ packageAliasTargetModuleRoot = workspacePackageImportTarget.alias.moduleRoot;
216037
+ isPublicPackageAliasImport = workspacePackageImportTarget.isPublicPackageImport;
215962
216038
  } else {
215963
216039
  const moduleImportTarget = [...moduleRoots.entries()].filter(([moduleId]) => importSpecifier === moduleId || importSpecifier.startsWith(`${moduleId}/`)).sort((left, right) => right[0].length - left[0].length || left[0].localeCompare(right[0]))[0];
215964
216040
  if (moduleImportTarget) {
@@ -215975,7 +216051,7 @@ async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath,
215975
216051
  if (!resolvedPath) {
215976
216052
  return void 0;
215977
216053
  }
215978
- const targetModuleEntry = [...moduleRoots.entries()].filter(([, moduleRoot]) => isPathInsideOrEqual2(resolvedPath, moduleRoot)).sort((left, right) => right[1].length - left[1].length || left[0].localeCompare(right[0]))[0];
216054
+ const targetModuleEntry = packageAliasTargetModule && packageAliasTargetModuleRoot ? [packageAliasTargetModule, packageAliasTargetModuleRoot] : [...moduleRoots.entries()].filter(([, moduleRoot]) => isPathInsideOrEqual2(resolvedPath, moduleRoot)).sort((left, right) => right[1].length - left[1].length || left[0].localeCompare(right[0]))[0];
215979
216055
  if (!targetModuleEntry) {
215980
216056
  const standaloneTargetModule = explicitStandaloneModuleByPath.get(
215981
216057
  normalizePath3(path7.relative(workspaceRoot, resolvedPath))
@@ -216000,13 +216076,14 @@ async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath,
216000
216076
  const nestedIndexEntrypointCandidates = adapter.dependencyParsingFileExtensions.flatMap(
216001
216077
  (extension) => [`src/index${extension}`, `public/index${extension}`]
216002
216078
  );
216003
- const isPublicImport = indexEntrypointCandidates.includes(targetSubPath) || nestedIndexEntrypointCandidates.includes(targetSubPath) || adapter.publicEntrypointDirectoryNames.some(
216079
+ const isPublicImport = isPublicPackageAliasImport || indexEntrypointCandidates.includes(targetSubPath) || nestedIndexEntrypointCandidates.includes(targetSubPath) || adapter.publicEntrypointDirectoryNames.some(
216004
216080
  (dirName) => targetSubPath.startsWith(`${dirName}/`)
216005
216081
  );
216006
216082
  return {
216007
216083
  targetModule,
216008
216084
  resolvedRelativePath: normalizePath3(path7.relative(workspaceRoot, resolvedPath)),
216009
- isPublicImport
216085
+ isPublicImport,
216086
+ ...isPublicPackageAliasImport ? { isPackagePublicImport: true } : {}
216010
216087
  };
216011
216088
  }
216012
216089
  async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath, moduleRoots, explicitStandaloneModuleByPath, workspacePackageAliases, adapter, options) {
@@ -216059,6 +216136,7 @@ async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath,
216059
216136
  line: importReference.line,
216060
216137
  targetModule: resolved.targetModule,
216061
216138
  isPublicImport: resolved.isPublicImport,
216139
+ ...resolved.isPackagePublicImport ? { isPackagePublicImport: true } : {},
216062
216140
  resolvedTargetRelativePath: resolved.resolvedRelativePath
216063
216141
  });
216064
216142
  }
@@ -216814,6 +216892,9 @@ async function validateDependencyContractBoundaries(workspaceRoot, architectureC
216814
216892
  if (options.suppressPublicSurfaceFailuresForNonPublicImports === true && !dependencyImport.isPublicImport) {
216815
216893
  continue;
216816
216894
  }
216895
+ if (dependencyImport.isPackagePublicImport === true) {
216896
+ continue;
216897
+ }
216817
216898
  if (!isImportWithinPublicEntrypoints(
216818
216899
  dependencyImport.resolvedTargetRelativePath,
216819
216900
  publicEntrypoints
@@ -218687,6 +218768,9 @@ var archpilotIgnoreFileName = ".archpilotignore";
218687
218768
  var defaultArchpilotIgnoreContent = [
218688
218769
  "node_modules/",
218689
218770
  ".git/",
218771
+ ".archpilot/reports/",
218772
+ ".archpilot/history/",
218773
+ ".archpilot/badges/",
218690
218774
  ".next/",
218691
218775
  "dist/",
218692
218776
  "build/",
@@ -218751,7 +218835,9 @@ function loadArchpilotIgnoreMatcher(workspaceRoot) {
218751
218835
  } catch {
218752
218836
  contents = void 0;
218753
218837
  }
218754
- return createArchpilotIgnoreMatcher(contents ? parseArchpilotIgnore(contents) : []);
218838
+ const defaultPatterns = parseArchpilotIgnore(defaultArchpilotIgnoreContent);
218839
+ const customPatterns = contents ? parseArchpilotIgnore(contents) : [];
218840
+ return createArchpilotIgnoreMatcher([...defaultPatterns, ...customPatterns]);
218755
218841
  }
218756
218842
  function ensureArchpilotIgnoreFileSync(workspaceRoot) {
218757
218843
  const ignorePath = path13.join(workspaceRoot, archpilotIgnoreFileName);
@@ -224434,7 +224520,18 @@ async function validateDependencyGraphIsolation(workspaceRoot, contract, depende
224434
224520
  for (const entry of entries) {
224435
224521
  const fullPath = path27.join(directoryPath, entry.name);
224436
224522
  if (entry.isDirectory()) {
224437
- if (["node_modules", "dist", "out", "build", "coverage", ".git"].includes(entry.name)) {
224523
+ if ([
224524
+ "node_modules",
224525
+ ".git",
224526
+ ".archpilot",
224527
+ ".next",
224528
+ "dist",
224529
+ "out",
224530
+ "build",
224531
+ "coverage",
224532
+ "fixtures",
224533
+ "__fixtures__"
224534
+ ].includes(entry.name)) {
224438
224535
  continue;
224439
224536
  }
224440
224537
  const nested = await collectModuleSourceEvidence2(fullPath);
@@ -225148,6 +225245,7 @@ async function writeValidationReport(workspaceRoot, config, results, validationC
225148
225245
  policyStatus,
225149
225246
  adrSummary
225150
225247
  );
225248
+ statusExport.xArchPilot = await buildManagedMetadata("validation-status", timestampIso);
225151
225249
  let healthTrend = {
225152
225250
  currentScore: statusExport.summary.healthScore,
225153
225251
  trendDirection: "no-history"
@@ -225463,6 +225561,14 @@ async function runArchitectureValidationForWorkspace(workspaceRoot, options) {
225463
225561
  modulesRootRelativePath: configuredModulesRoot
225464
225562
  })
225465
225563
  );
225564
+ emitOperationalMessage(
225565
+ options?.onOperationalMessage,
225566
+ "info",
225567
+ `Dependency scan summary: modules=${dependencyGraphSummary.modules.length}, importEdges=${dependencyGraphSummary.modules.reduce(
225568
+ (total, moduleEntry) => total + moduleEntry.actualDependencies.length,
225569
+ 0
225570
+ )}, ignoredDefaults=node_modules,.git,.archpilot,dist,build,out,coverage,fixtures.`
225571
+ );
225466
225572
  results.push(
225467
225573
  ...await phase(
225468
225574
  "Analyzing dependency graph rules",
@@ -226813,6 +226919,7 @@ function renderArchitectureReviewJson(summary, options) {
226813
226919
  );
226814
226920
  return `${JSON.stringify(
226815
226921
  {
226922
+ ...options?.metadata ? { xArchPilot: options.metadata } : {},
226816
226923
  reportVersion: summary.reportVersion,
226817
226924
  projectName: summary.projectName,
226818
226925
  generatedAtUtc: summary.generatedAtUtc,
@@ -231674,6 +231781,10 @@ async function writeArchitectureReportArtifacts(input2) {
231674
231781
  let reportWriteError;
231675
231782
  try {
231676
231783
  const modulePaths = await readModulePaths(input2.workspaceRoot);
231784
+ const summaryMetadata = await buildManagedMetadata(
231785
+ "validation-summary",
231786
+ input2.reviewSummary.generatedAtUtc
231787
+ );
231677
231788
  await import_node_fs34.promises.mkdir(reportsDir, { recursive: true });
231678
231789
  await Promise.all([
231679
231790
  import_node_fs34.promises.writeFile(
@@ -231695,6 +231806,7 @@ async function writeArchitectureReportArtifacts(input2) {
231695
231806
  import_node_fs34.promises.writeFile(
231696
231807
  reviewJsonPath,
231697
231808
  renderArchitectureReviewJson(input2.reviewSummary, {
231809
+ metadata: summaryMetadata,
231698
231810
  remediation: input2.remediation,
231699
231811
  suppressionSummary: input2.suppressionSummary,
231700
231812
  dependencyGraphSummary: input2.dependencyGraphSummary,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archpilotlabs/archpilot",
3
- "version": "0.0.14",
3
+ "version": "0.0.15",
4
4
  "description": "Executable architecture governance CLI",
5
5
  "homepage": "https://archpilot.org",
6
6
  "bugs": {