@component-compass/cli 0.0.3 → 0.0.5

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 (101) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/commands/init.js +1 -3
  3. package/dist/commands/init.js.map +1 -1
  4. package/dist/commands/scan.d.ts +12 -1
  5. package/dist/commands/scan.js +158 -55
  6. package/dist/commands/scan.js.map +1 -1
  7. package/dist/config/loader.js +5 -9
  8. package/dist/config/loader.js.map +1 -1
  9. package/dist/config/schema.d.ts +2 -15
  10. package/dist/config/schema.js.map +1 -1
  11. package/dist/envelope/index.d.ts +0 -9
  12. package/dist/envelope/index.js +1 -46
  13. package/dist/envelope/index.js.map +1 -1
  14. package/dist/identity.d.ts +11 -15
  15. package/dist/identity.js +29 -20
  16. package/dist/identity.js.map +1 -1
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.js +1 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/local-index/detect-react.d.ts +2 -1
  21. package/dist/local-index/detect-react.js +135 -115
  22. package/dist/local-index/detect-react.js.map +1 -1
  23. package/dist/local-index/detect-vue.d.ts +15 -1
  24. package/dist/local-index/detect-vue.js +130 -107
  25. package/dist/local-index/detect-vue.js.map +1 -1
  26. package/dist/local-index/detect-wc.d.ts +7 -1
  27. package/dist/local-index/detect-wc.js +56 -60
  28. package/dist/local-index/detect-wc.js.map +1 -1
  29. package/dist/local-index/index.d.ts +11 -6
  30. package/dist/local-index/index.js +25 -27
  31. package/dist/local-index/index.js.map +1 -1
  32. package/dist/manifest/barrel-parser.d.ts +10 -0
  33. package/dist/manifest/barrel-parser.js +11 -0
  34. package/dist/manifest/barrel-parser.js.map +1 -1
  35. package/dist/manifest/derived-manifest-stub.d.ts +15 -6
  36. package/dist/manifest/derived-manifest-stub.js +43 -7
  37. package/dist/manifest/derived-manifest-stub.js.map +1 -1
  38. package/dist/manifest/lazy-resolver.d.ts +42 -16
  39. package/dist/manifest/lazy-resolver.js +122 -49
  40. package/dist/manifest/lazy-resolver.js.map +1 -1
  41. package/dist/occurrences.js +20 -4
  42. package/dist/occurrences.js.map +1 -1
  43. package/dist/parse-by-ext.d.ts +21 -0
  44. package/dist/parse-by-ext.js +53 -0
  45. package/dist/parse-by-ext.js.map +1 -0
  46. package/dist/reporter/index.d.ts +5 -21
  47. package/dist/reporter/index.js +6 -52
  48. package/dist/reporter/index.js.map +1 -1
  49. package/dist/reporter/stdout.js +4 -4
  50. package/dist/reporter/stdout.js.map +1 -1
  51. package/dist/rollup.d.ts +5 -4
  52. package/dist/rollup.js +7 -4
  53. package/dist/rollup.js.map +1 -1
  54. package/dist/scan/cem-index.d.ts +38 -0
  55. package/dist/scan/cem-index.js +139 -0
  56. package/dist/scan/cem-index.js.map +1 -0
  57. package/dist/scan/git-mtime.d.ts +2 -0
  58. package/dist/scan/git-mtime.js +22 -0
  59. package/dist/scan/git-mtime.js.map +1 -0
  60. package/dist/scan/meta.d.ts +5 -0
  61. package/dist/scan/meta.js +58 -0
  62. package/dist/scan/meta.js.map +1 -0
  63. package/dist/scan/stamp-deprecated.d.ts +16 -0
  64. package/dist/scan/stamp-deprecated.js +33 -0
  65. package/dist/scan/stamp-deprecated.js.map +1 -0
  66. package/dist/scan/stamp-version.d.ts +18 -0
  67. package/dist/scan/stamp-version.js +94 -0
  68. package/dist/scan/stamp-version.js.map +1 -0
  69. package/dist/seeds.d.ts +18 -18
  70. package/dist/seeds.js +82 -45
  71. package/dist/seeds.js.map +1 -1
  72. package/dist/types.d.ts +2 -5
  73. package/dist/util/git.d.ts +8 -0
  74. package/dist/util/git.js +73 -0
  75. package/dist/util/git.js.map +1 -1
  76. package/dist/util/progress.d.ts +21 -0
  77. package/dist/util/progress.js +54 -0
  78. package/dist/util/progress.js.map +1 -0
  79. package/dist/walker/files.d.ts +1 -0
  80. package/dist/walker/files.js +11 -5
  81. package/dist/walker/files.js.map +1 -1
  82. package/dist/workspace/find-owning-package.d.ts +6 -0
  83. package/dist/workspace/find-owning-package.js +22 -2
  84. package/dist/workspace/find-owning-package.js.map +1 -1
  85. package/dist/workspace/index.d.ts +1 -1
  86. package/dist/workspace/index.js +1 -1
  87. package/dist/workspace/index.js.map +1 -1
  88. package/package.json +13 -7
  89. package/schema/config.schema.json +2 -24
  90. package/dist/commands/no-deps-diagnostic.d.ts +0 -15
  91. package/dist/commands/no-deps-diagnostic.js +0 -23
  92. package/dist/commands/no-deps-diagnostic.js.map +0 -1
  93. package/dist/config/tag-rules.d.ts +0 -2
  94. package/dist/config/tag-rules.js +0 -34
  95. package/dist/config/tag-rules.js.map +0 -1
  96. package/dist/local-index/walker.d.ts +0 -11
  97. package/dist/local-index/walker.js +0 -47
  98. package/dist/local-index/walker.js.map +0 -1
  99. package/dist/manifest/diagnostic-filter.d.ts +0 -13
  100. package/dist/manifest/diagnostic-filter.js +0 -36
  101. package/dist/manifest/diagnostic-filter.js.map +0 -1
@@ -0,0 +1,58 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { basename, dirname, join, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { ulid } from "ulid";
5
+ import { readGitCommit, readGitRemote, readGitBranch, readInitialCommit } from "../util/git.js";
6
+ import { readToolVersion } from "../envelope/index.js";
7
+ export async function stampMeta(opts) {
8
+ const commit = await readGitCommit(opts.cwd);
9
+ if (!commit)
10
+ throw new Error(`not a git repository: ${opts.cwd}`);
11
+ const rawInitialCommit = await readInitialCommit(opts.cwd);
12
+ const initialCommit = rawInitialCommit ?? null;
13
+ if (!initialCommit) {
14
+ process.stderr.write("warn: initial commit unavailable (shallow clone?) — set fetch-depth: 0 in CI for stable repo identity\n");
15
+ }
16
+ const gitRemote = await readGitRemote(opts.cwd);
17
+ const branch = await readGitBranch(opts.cwd);
18
+ const id = opts.repoIdOverride ?? deriveId(gitRemote, opts.cwd);
19
+ return {
20
+ ccVersion: readToolVersion(findCliPackageRoot()),
21
+ scanId: ulid(),
22
+ scannedAt: new Date().toISOString(),
23
+ repo: { id, gitRemote, commit, initialCommit, branch },
24
+ };
25
+ }
26
+ function deriveId(remote, cwd) {
27
+ if (remote) {
28
+ const match = remote.match(/[/:]([^/]+?)(\.git)?$/);
29
+ if (match?.[1])
30
+ return match[1];
31
+ }
32
+ return basename(cwd);
33
+ }
34
+ /**
35
+ * Walk up from this module's directory until we find the @component-compass/cli
36
+ * package.json. Robust to running from dist/ or src/ (vitest) without
37
+ * hardcoding a relative depth. Mirrors the pattern in envelope/index.ts.
38
+ */
39
+ function findCliPackageRoot() {
40
+ let dir = dirname(fileURLToPath(import.meta.url));
41
+ for (let i = 0; i < 6; i++) {
42
+ const candidate = join(dir, "package.json");
43
+ try {
44
+ const parsed = JSON.parse(readFileSync(candidate, "utf8"));
45
+ if (parsed.name === "@component-compass/cli")
46
+ return dir;
47
+ }
48
+ catch {
49
+ // continue walking
50
+ }
51
+ const parent = resolve(dir, "..");
52
+ if (parent === dir)
53
+ break;
54
+ dir = parent;
55
+ }
56
+ return dirname(fileURLToPath(import.meta.url));
57
+ }
58
+ //# sourceMappingURL=meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/scan/meta.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { OutputComponent } from "@component-compass/plugin-core";
2
+ import type { CemIndex } from "./cem-index.js";
3
+ /**
4
+ * Stamp `deprecated: true` onto each custom-element component whose CEM
5
+ * declaration carries `deprecated: true` (or a reason string). All other
6
+ * components keep the default `deprecated: false` set during rollup.
7
+ *
8
+ * Sources checked, in priority order:
9
+ * 1. Global CEM index (built from node_modules at scan startup) — covers
10
+ * custom-elements resolved via the HTML/Lit/Vue tag-name path.
11
+ * 2. component.manifest?.data?.lifecycle?.status — covers components whose
12
+ * manifest was loaded via the lazy-resolver path.
13
+ *
14
+ * A component is deprecated when EITHER source says so.
15
+ */
16
+ export declare function stampDeprecated(components: OutputComponent[], cemIndex: CemIndex): void;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Stamp `deprecated: true` onto each custom-element component whose CEM
3
+ * declaration carries `deprecated: true` (or a reason string). All other
4
+ * components keep the default `deprecated: false` set during rollup.
5
+ *
6
+ * Sources checked, in priority order:
7
+ * 1. Global CEM index (built from node_modules at scan startup) — covers
8
+ * custom-elements resolved via the HTML/Lit/Vue tag-name path.
9
+ * 2. component.manifest?.data?.lifecycle?.status — covers components whose
10
+ * manifest was loaded via the lazy-resolver path.
11
+ *
12
+ * A component is deprecated when EITHER source says so.
13
+ */
14
+ export function stampDeprecated(components, cemIndex) {
15
+ for (const c of components) {
16
+ // Manifest-lifecycle path: already captured via lazy-resolver enrichment.
17
+ if (c.manifest?.data?.lifecycle?.status === "deprecated") {
18
+ c.deprecated = true;
19
+ continue;
20
+ }
21
+ // CEM-index path: look up the tag name in the global CEM index.
22
+ if (c.identity.kind === "custom-element" && c.identity.tagName) {
23
+ const entry = cemIndex.byTag.get(c.identity.tagName);
24
+ if (entry) {
25
+ const rawDecl = entry.manifest;
26
+ if (rawDecl && rawDecl.deprecated !== undefined && rawDecl.deprecated !== false) {
27
+ c.deprecated = true;
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
33
+ //# sourceMappingURL=stamp-deprecated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stamp-deprecated.js","sourceRoot":"","sources":["../../src/scan/stamp-deprecated.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAC7B,UAA6B,EAC7B,QAAkB;IAElB,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,0EAA0E;QAC1E,IAAI,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,KAAK,YAAY,EAAE,CAAC;YACzD,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC;YACpB,SAAS;QACX,CAAC;QAED,gEAAgE;QAChE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC/D,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACrD,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,OAAO,GAAG,KAAK,CAAC,QAAoD,CAAC;gBAC3E,IAAI,OAAO,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC;oBAChF,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { OutputComponent, OutputOccurrence } from "@component-compass/plugin-core";
2
+ /**
3
+ * Reads each external/workspace package's `version` from its installed
4
+ * `package.json` and stamps it onto every component from that package.
5
+ * Local components keep `version: null`.
6
+ *
7
+ * Uses Node-style module resolution: walks upward from a representative
8
+ * occurrence's file directory through ancestor `node_modules` directories
9
+ * until the package is found. Starting from inside the sub-app that uses
10
+ * the package handles multi-app monorepos where deps are installed per-app
11
+ * (e.g. `pie-aperture/nextjs-app-v14/node_modules/`) rather than hoisted
12
+ * to the workspace root. Falls back to `startDir` for packages with no
13
+ * occurrences.
14
+ *
15
+ * Batches IO: one package.json read per unique external package name, not
16
+ * per component.
17
+ */
18
+ export declare function stampVersion(startDir: string, components: OutputComponent[], occurrences?: OutputOccurrence[]): Promise<void>;
@@ -0,0 +1,94 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join, dirname, resolve } from "node:path";
3
+ /**
4
+ * Reads each external/workspace package's `version` from its installed
5
+ * `package.json` and stamps it onto every component from that package.
6
+ * Local components keep `version: null`.
7
+ *
8
+ * Uses Node-style module resolution: walks upward from a representative
9
+ * occurrence's file directory through ancestor `node_modules` directories
10
+ * until the package is found. Starting from inside the sub-app that uses
11
+ * the package handles multi-app monorepos where deps are installed per-app
12
+ * (e.g. `pie-aperture/nextjs-app-v14/node_modules/`) rather than hoisted
13
+ * to the workspace root. Falls back to `startDir` for packages with no
14
+ * occurrences.
15
+ *
16
+ * Batches IO: one package.json read per unique external package name, not
17
+ * per component.
18
+ */
19
+ export async function stampVersion(startDir, components, occurrences = []) {
20
+ // Collect unique external package names.
21
+ const packageNames = new Set();
22
+ for (const c of components) {
23
+ if (c.identity.scope !== "local" && c.identity.packageName) {
24
+ packageNames.add(c.identity.packageName);
25
+ }
26
+ }
27
+ // componentId → packageName for fast occurrence → package lookup.
28
+ const pkgByComponentId = new Map();
29
+ for (const c of components) {
30
+ if (c.identity.scope !== "local" && c.identity.packageName) {
31
+ pkgByComponentId.set(c.id, c.identity.packageName);
32
+ }
33
+ }
34
+ // packageName → directory to start the walk-up from. Use the parent dir of
35
+ // any occurrence's file path (resolved relative to startDir). Multi-app
36
+ // monorepos install deps per-app, so walking up from inside the sub-app
37
+ // hits the per-app node_modules. Falls back to startDir for packages with
38
+ // no occurrences.
39
+ const starterDirByPackage = new Map();
40
+ for (const o of occurrences) {
41
+ const pkg = pkgByComponentId.get(o.componentId);
42
+ if (pkg && !starterDirByPackage.has(pkg)) {
43
+ starterDirByPackage.set(pkg, dirname(resolve(startDir, o.filePath)));
44
+ }
45
+ }
46
+ // Read each package.json once. Store null when not found / no version field.
47
+ const versionByPackage = new Map();
48
+ await Promise.all([...packageNames].map(async (name) => {
49
+ const searchFrom = starterDirByPackage.get(name) ?? startDir;
50
+ const version = await resolvePackageVersion(searchFrom, name);
51
+ versionByPackage.set(name, version);
52
+ }));
53
+ // Stamp each component.
54
+ for (const c of components) {
55
+ if (c.identity.scope !== "local" && c.identity.packageName) {
56
+ c.version = versionByPackage.get(c.identity.packageName) ?? null;
57
+ }
58
+ else {
59
+ c.version = null;
60
+ }
61
+ }
62
+ }
63
+ /**
64
+ * Walk up the directory tree from `startDir`, trying
65
+ * `<dir>/node_modules/<packageName>/package.json` at each level.
66
+ * Returns the `version` string, or null when not found anywhere.
67
+ */
68
+ async function resolvePackageVersion(startDir, packageName) {
69
+ let dir = startDir;
70
+ while (true) {
71
+ const pkgPath = join(dir, "node_modules", packageName, "package.json");
72
+ try {
73
+ const raw = await readFile(pkgPath, "utf8");
74
+ try {
75
+ const pkg = JSON.parse(raw);
76
+ return pkg.version ?? null;
77
+ }
78
+ catch {
79
+ // Malformed JSON — file exists, version unreadable.
80
+ return null;
81
+ }
82
+ }
83
+ catch {
84
+ // File not found or unreadable — try parent.
85
+ }
86
+ const parent = dirname(dir);
87
+ if (parent === dir) {
88
+ // Reached filesystem root.
89
+ return null;
90
+ }
91
+ dir = parent;
92
+ }
93
+ }
94
+ //# sourceMappingURL=stamp-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stamp-version.js","sourceRoot":"","sources":["../../src/scan/stamp-version.ts"],"names":[],"mappings":"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"}
package/dist/seeds.d.ts CHANGED
@@ -1,14 +1,12 @@
1
1
  /**
2
- * Builds per-component seeds from a resolver-emitted snapshot,
3
- * parser-emitted occurrences, and the workspace tag rules. Seeds are the
4
- * per-component input to `rollupOccurrencesToComponents`: they carry
5
- * identity, derivedTags, and manifest enrichment but no occurrence data
6
- * (that is merged separately during rollup).
2
+ * Builds per-component seeds from a resolver-emitted snapshot and
3
+ * parser-emitted occurrences. Seeds are the per-component input to
4
+ * `rollupOccurrencesToComponents`: they carry identity and manifest enrichment
5
+ * but no occurrence data (that is merged separately during rollup).
7
6
  *
8
7
  * Pure function; no I/O.
9
8
  */
10
9
  import type { IndexedComponent, LocalDefinitionIndex, ParseResult } from "@component-compass/plugin-core";
11
- import type { TagRule } from "./config/schema.js";
12
10
  import type { ComponentSeed } from "./rollup.js";
13
11
  import type { WorkspaceGraph } from "./workspace/types.js";
14
12
  /**
@@ -25,17 +23,19 @@ export type SnapshotEntry = {
25
23
  * ComponentSeeds.
26
24
  *
27
25
  * Two sources contribute:
28
- * 1. Snapshotted componentsfull enrichment via `manifestComponentToOutput`,
29
- * labelled with the snapshot entry's `enrichmentSource`.
30
- * 2. Components observed in parser walks but absent from the snapshot —
31
- * emitted with `manifest: null` so they surface in `components[]` per
32
- * the realignment principle ("manifest is enrichment, not gate").
26
+ * 1. Components observed in parser walks carry `modulePath` from the
27
+ * resolver and surface with `manifest: null` initially.
28
+ * 2. Snapshotted components full enrichment via `manifestComponentToOutput`,
29
+ * labelled with the snapshot entry's `enrichmentSource`. Snapshot entries
30
+ * have NO `modulePath` (manifests don't carry that info), so their stable
31
+ * id differs from the parser-emitted seed for the same logical component.
32
+ * To avoid emitting a ghost component, we attach the snapshot's manifest
33
+ * enrichment to a matching parser-emitted seed when the match is
34
+ * unambiguous (exactly one parser seed with `{kind, packageName,
35
+ * exportName-or-tagName}`). Ambiguous matches fall through to a
36
+ * snapshot-only seed.
33
37
  *
34
- * Dedupe by stable id; snapshotted seeds win.
35
- *
36
- * Scope derivation follows the three-lane model in identity.ts:
37
- * - local → source.type === "local"
38
- * - ds → external + derivedTags.length > 0
39
- * - external → external + no matching tag rules
38
+ * Scope derivation: "local" for source.type === "local"; "external" otherwise.
39
+ * DS-grouping is the web app's responsibility — CC emits two scopes only.
40
40
  */
41
- export declare function buildComponentSeeds(snapshot: SnapshotEntry[], parseResults: ParseResult[], tagRules: TagRule[] | undefined, localIndex?: LocalDefinitionIndex, repoRoot?: string, workspaceGraph?: WorkspaceGraph): ComponentSeed[];
41
+ export declare function buildComponentSeeds(snapshot: SnapshotEntry[], parseResults: ParseResult[], localIndex?: LocalDefinitionIndex, repoRoot?: string, workspaceGraph?: WorkspaceGraph): ComponentSeed[];
package/dist/seeds.js CHANGED
@@ -1,14 +1,12 @@
1
1
  /**
2
- * Builds per-component seeds from a resolver-emitted snapshot,
3
- * parser-emitted occurrences, and the workspace tag rules. Seeds are the
4
- * per-component input to `rollupOccurrencesToComponents`: they carry
5
- * identity, derivedTags, and manifest enrichment but no occurrence data
6
- * (that is merged separately during rollup).
2
+ * Builds per-component seeds from a resolver-emitted snapshot and
3
+ * parser-emitted occurrences. Seeds are the per-component input to
4
+ * `rollupOccurrencesToComponents`: they carry identity and manifest enrichment
5
+ * but no occurrence data (that is merged separately during rollup).
7
6
  *
8
7
  * Pure function; no I/O.
9
8
  */
10
9
  import { relative, isAbsolute } from "node:path";
11
- import { evaluateTagRules } from "./config/tag-rules.js";
12
10
  import { manifestComponentToOutput } from "./reporter/index.js";
13
11
  import { computeOutputIdentity, computeStableId, computeStableIdFromComponentId, } from "./identity.js";
14
12
  /**
@@ -16,40 +14,25 @@ import { computeOutputIdentity, computeStableId, computeStableIdFromComponentId,
16
14
  * ComponentSeeds.
17
15
  *
18
16
  * Two sources contribute:
19
- * 1. Snapshotted componentsfull enrichment via `manifestComponentToOutput`,
20
- * labelled with the snapshot entry's `enrichmentSource`.
21
- * 2. Components observed in parser walks but absent from the snapshot —
22
- * emitted with `manifest: null` so they surface in `components[]` per
23
- * the realignment principle ("manifest is enrichment, not gate").
17
+ * 1. Components observed in parser walks carry `modulePath` from the
18
+ * resolver and surface with `manifest: null` initially.
19
+ * 2. Snapshotted components full enrichment via `manifestComponentToOutput`,
20
+ * labelled with the snapshot entry's `enrichmentSource`. Snapshot entries
21
+ * have NO `modulePath` (manifests don't carry that info), so their stable
22
+ * id differs from the parser-emitted seed for the same logical component.
23
+ * To avoid emitting a ghost component, we attach the snapshot's manifest
24
+ * enrichment to a matching parser-emitted seed when the match is
25
+ * unambiguous (exactly one parser seed with `{kind, packageName,
26
+ * exportName-or-tagName}`). Ambiguous matches fall through to a
27
+ * snapshot-only seed.
24
28
  *
25
- * Dedupe by stable id; snapshotted seeds win.
26
- *
27
- * Scope derivation follows the three-lane model in identity.ts:
28
- * - local → source.type === "local"
29
- * - ds → external + derivedTags.length > 0
30
- * - external → external + no matching tag rules
29
+ * Scope derivation: "local" for source.type === "local"; "external" otherwise.
30
+ * DS-grouping is the web app's responsibility — CC emits two scopes only.
31
31
  */
32
- export function buildComponentSeeds(snapshot, parseResults, tagRules, localIndex, repoRoot, workspaceGraph) {
32
+ export function buildComponentSeeds(snapshot, parseResults, localIndex, repoRoot, workspaceGraph) {
33
33
  const seedsById = new Map();
34
- // 1. Resolver-snapshotted components first (so they win on dedupe).
35
- for (const entry of snapshot) {
36
- const componentId = indexedToComponentId(entry.component);
37
- const packageName = entry.component.source.type === "external"
38
- ? entry.component.source.package
39
- : null;
40
- const derivedTags = evaluateTagRules(packageName, tagRules);
41
- const identity = computeOutputIdentity({
42
- componentId,
43
- derivedTags,
44
- repoId: "",
45
- ...(workspaceGraph !== undefined ? { workspaceGraph } : {}),
46
- });
47
- const id = computeStableId(identity);
48
- const manifest = manifestComponentToOutput(entry.component, entry.enrichmentSource);
49
- seedsById.set(id, { id, identity, derivedTags, manifest });
50
- }
51
- // 2. Components observed in parser walks but not yet seeded.
52
- // Emitted with manifest: null per the realignment principle.
34
+ // 1. Parser-emitted components first. These carry `modulePath` for
35
+ // resolver-driven externals and are the ones occurrences hash against.
53
36
  for (const result of parseResults) {
54
37
  for (const occ of result.occurrences) {
55
38
  // Normalise local filePaths: parsers emit absolute paths; the local index
@@ -67,10 +50,6 @@ export function buildComponentSeeds(snapshot, parseResults, tagRules, localIndex
67
50
  const id = computeStableIdFromComponentId(componentId);
68
51
  if (seedsById.has(id))
69
52
  continue;
70
- const packageName = componentId.source.type === "external"
71
- ? componentId.source.package
72
- : null;
73
- const derivedTags = evaluateTagRules(packageName, tagRules);
74
53
  const isLocal = componentId.source.type === "local";
75
54
  let definitionLoc;
76
55
  if (isLocal && localIndex) {
@@ -90,14 +69,39 @@ export function buildComponentSeeds(snapshot, parseResults, tagRules, localIndex
90
69
  }
91
70
  const identity = computeOutputIdentity({
92
71
  componentId,
93
- derivedTags,
94
72
  repoId: "",
95
73
  ...(workspaceGraph !== undefined ? { workspaceGraph } : {}),
96
74
  ...(definitionLoc !== undefined ? { definitionLoc } : {}),
97
75
  });
98
- seedsById.set(id, { id, identity, derivedTags, manifest: null });
76
+ seedsById.set(id, { id, identity, manifest: null, deprecated: false });
99
77
  }
100
78
  }
79
+ // 2. Snapshotted components. Snapshot entries lack `modulePath`, so their
80
+ // stable id won't collide with the parser-emitted seed even when they
81
+ // describe the same logical component. Instead of hashing, look up by
82
+ // `{kind, packageName, exportName-or-tagName}` and attach the manifest
83
+ // enrichment to that parser seed. Only merge when exactly one parser
84
+ // seed matches — multiple matches (e.g. two subpaths both exporting
85
+ // `default`) are ambiguous, so fall through to a snapshot-only seed.
86
+ for (const entry of snapshot) {
87
+ const componentId = indexedToComponentId(entry.component);
88
+ const manifest = manifestComponentToOutput(entry.component, entry.enrichmentSource);
89
+ const mergeTarget = findUnambiguousMergeTarget(seedsById, componentId);
90
+ if (mergeTarget !== null) {
91
+ mergeTarget.manifest = manifest;
92
+ mergeTarget.deprecated = false;
93
+ continue;
94
+ }
95
+ const identity = computeOutputIdentity({
96
+ componentId,
97
+ repoId: "",
98
+ ...(workspaceGraph !== undefined ? { workspaceGraph } : {}),
99
+ });
100
+ const id = computeStableId(identity);
101
+ if (seedsById.has(id))
102
+ continue;
103
+ seedsById.set(id, { id, identity, manifest, deprecated: false });
104
+ }
101
105
  // 3. Local definitions that were never referenced in any occurrence.
102
106
  // These must still appear in components[] so they can serve as
103
107
  // owner-edge targets in the composition graph.
@@ -112,17 +116,50 @@ export function buildComponentSeeds(snapshot, parseResults, tagRules, localIndex
112
116
  : undefined;
113
117
  const identity = computeOutputIdentity({
114
118
  componentId: def.componentId,
115
- derivedTags: [],
116
119
  repoId: "",
117
120
  ...(workspaceGraph !== undefined ? { workspaceGraph } : {}),
118
121
  ...(definitionLoc !== undefined ? { definitionLoc } : {}),
119
122
  });
120
- seedsById.set(id, { id, identity, derivedTags: [], manifest: null });
123
+ seedsById.set(id, { id, identity, manifest: null, deprecated: false });
121
124
  }
122
125
  }
123
126
  }
124
127
  return [...seedsById.values()];
125
128
  }
129
+ /**
130
+ * Find a parser-emitted seed whose logical identity matches the snapshot's
131
+ * `ComponentId`, ignoring `modulePath` (snapshot entries don't carry it).
132
+ *
133
+ * The match is intentionally narrowed to **unambiguous** cases: if two or more
134
+ * parser seeds share the same `{kind, packageName, exportName/tagName}` (e.g.
135
+ * two subpaths of one package both exporting `default`), we cannot safely pick
136
+ * one to enrich, so we return null and let the caller fall through to a
137
+ * snapshot-only seed.
138
+ */
139
+ function findUnambiguousMergeTarget(seeds, candidate) {
140
+ if (candidate.source.type !== "external")
141
+ return null;
142
+ const candidatePackage = candidate.source.package;
143
+ let match = null;
144
+ for (const seed of seeds.values()) {
145
+ if (seed.identity.kind !== candidate.kind)
146
+ continue;
147
+ if (seed.identity.packageName !== candidatePackage)
148
+ continue;
149
+ if (candidate.kind === "custom-element") {
150
+ if (seed.identity.tagName !== candidate.tagName)
151
+ continue;
152
+ }
153
+ else {
154
+ if (seed.identity.exportName !== candidate.export)
155
+ continue;
156
+ }
157
+ if (match !== null)
158
+ return null; // ambiguous — bail out
159
+ match = seed;
160
+ }
161
+ return match;
162
+ }
126
163
  /**
127
164
  * Convert an `IndexedComponent` to a `ComponentId` for use with
128
165
  * `computeOutputIdentity`. `IndexedComponent` extends `ManifestComponent`
package/dist/seeds.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"seeds.js","sourceRoot":"","sources":["../src/seeds.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"seeds.js","sourceRoot":"","sources":["../src/seeds.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,16 +1,13 @@
1
1
  export type { Loc, WarningCode, Warning } from "@component-compass/plugin-core";
2
- export type { TagRule } from "./config/schema.js";
3
- import type { TagRule } from "./config/schema.js";
4
2
  export type ResolvedConfig = {
5
3
  configPath: string;
6
4
  configDir: string;
7
- repoId: string;
8
- packageScopes: string[];
5
+ repoId?: string;
9
6
  include: string[];
10
7
  exclude: string[];
11
8
  captureValues: boolean;
12
9
  output: string;
10
+ gitignore: boolean;
13
11
  tsconfigPath?: string;
14
12
  aliases?: Record<string, string[]>;
15
- tagRules?: TagRule[];
16
13
  };
@@ -1 +1,9 @@
1
+ export type MTimeRange = {
2
+ firstCommitAt: string;
3
+ lastCommitAt: string;
4
+ };
5
+ export declare function readFileMTimes(root: string, paths: string[]): Promise<Map<string, MTimeRange>>;
1
6
  export declare function readGitCommit(root: string): Promise<string | undefined>;
7
+ export declare function readInitialCommit(root: string): Promise<string | undefined>;
8
+ export declare function readGitRemote(root: string): Promise<string | null>;
9
+ export declare function readGitBranch(root: string): Promise<string | null>;
package/dist/util/git.js CHANGED
@@ -1,6 +1,50 @@
1
1
  import { execFile } from "node:child_process";
2
2
  import { promisify } from "node:util";
3
3
  const exec = promisify(execFile);
4
+ export async function readFileMTimes(root, paths) {
5
+ if (paths.length === 0)
6
+ return new Map();
7
+ const out = new Map();
8
+ // git log --reverse interleaves commits oldest-first. Marker line precedes
9
+ // each commit's file list. Walk linearly: track currentDate, then bucket
10
+ // each named path into first (set once) / last (overwrite each commit).
11
+ // Known fidelity gaps: shallow clones cap firstCommitAt at the depth boundary;
12
+ // renames without --follow stop at the rename. Both documented in the spec.
13
+ try {
14
+ const args = [
15
+ "-c",
16
+ "core.quotePath=false",
17
+ "log",
18
+ "--reverse",
19
+ "--name-only",
20
+ "--format=__CC_COMMIT__ %aI",
21
+ "--",
22
+ ...paths,
23
+ ];
24
+ const { stdout } = await exec("git", args, {
25
+ cwd: root,
26
+ maxBuffer: 64 * 1024 * 1024,
27
+ });
28
+ let currentDate = null;
29
+ for (const line of stdout.split("\n")) {
30
+ if (line.startsWith("__CC_COMMIT__ ")) {
31
+ currentDate = line.slice("__CC_COMMIT__ ".length).trim();
32
+ }
33
+ else if (line.trim() && currentDate) {
34
+ const p = line.trim();
35
+ const existing = out.get(p);
36
+ if (existing)
37
+ existing.lastCommitAt = currentDate;
38
+ else
39
+ out.set(p, { firstCommitAt: currentDate, lastCommitAt: currentDate });
40
+ }
41
+ }
42
+ }
43
+ catch {
44
+ // git failure or buffer overflow — return whatever's accumulated (or empty).
45
+ }
46
+ return out;
47
+ }
4
48
  export async function readGitCommit(root) {
5
49
  try {
6
50
  const { stdout } = await exec("git", ["rev-parse", "HEAD"], { cwd: root });
@@ -10,4 +54,33 @@ export async function readGitCommit(root) {
10
54
  return undefined;
11
55
  }
12
56
  }
57
+ export async function readInitialCommit(root) {
58
+ try {
59
+ const { stdout } = await exec("git", ["rev-list", "--max-parents=0", "HEAD"], { cwd: root });
60
+ return stdout.trim().split("\n")[0];
61
+ }
62
+ catch {
63
+ return undefined;
64
+ }
65
+ }
66
+ export async function readGitRemote(root) {
67
+ try {
68
+ const { stdout } = await exec("git", ["config", "--get", "remote.origin.url"], { cwd: root });
69
+ return stdout.trim() || null;
70
+ }
71
+ catch {
72
+ return null;
73
+ }
74
+ }
75
+ export async function readGitBranch(root) {
76
+ try {
77
+ const { stdout } = await exec("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd: root });
78
+ const branch = stdout.trim();
79
+ // "HEAD" means detached HEAD state — not a named branch.
80
+ return branch === "HEAD" ? null : branch || null;
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ }
13
86
  //# sourceMappingURL=git.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/util/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAEjC,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/util/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Rate-limited progress reporter for the scan loop. Emits a single line on
3
+ * stderr — rewriting in place when stderr is a TTY, appending one line per
4
+ * tick otherwise (CI logs).
5
+ *
6
+ * Rate limit: emit when either ≥50 ticks have happened since the last emit
7
+ * OR ≥250ms have elapsed. Tuned so the line moves smoothly on TTYs without
8
+ * spamming non-TTY logs.
9
+ */
10
+ export type ProgressOptions = {
11
+ total: number;
12
+ writer: (s: string) => void;
13
+ isTTY: boolean;
14
+ /** Verb prefix in the rendered line (default: "Scanned"). */
15
+ label?: string;
16
+ };
17
+ export type Progress = {
18
+ tick(): void;
19
+ done(): void;
20
+ };
21
+ export declare function createProgress(opts: ProgressOptions): Progress;