@component-compass/plugin-core 0.1.11 → 0.1.17

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.
@@ -34,6 +34,24 @@ export type Diagnostic = {
34
34
  line: number;
35
35
  column: number;
36
36
  specifier: string;
37
+ } | {
38
+ code: "unresolved-component-tag";
39
+ severity: "warning";
40
+ filePath: string;
41
+ line?: number;
42
+ column?: number;
43
+ tagName: string;
44
+ } | {
45
+ code: "auto-import-stale-entry";
46
+ severity: "warning";
47
+ filePath: string;
48
+ componentName: string;
49
+ target: string;
50
+ } | {
51
+ code: "auto-import-manifest-missing";
52
+ severity: "warning";
53
+ filePath: string;
54
+ detail: string;
37
55
  } | {
38
56
  code: "unresolved-reference";
39
57
  severity: "info";
@@ -33,6 +33,12 @@ function dedupKey(d) {
33
33
  return `${d.code}::${d.filePath}::${d.tagName}`;
34
34
  case "unresolved-import":
35
35
  return `${d.code}::${d.filePath}::${d.line}::${d.column}::${d.specifier}`;
36
+ case "unresolved-component-tag":
37
+ return `${d.code}::${d.filePath}::${d.line ?? ""}::${d.column ?? ""}::${d.tagName}`;
38
+ case "auto-import-stale-entry":
39
+ return `${d.code}::${d.componentName}::${d.target}`;
40
+ case "auto-import-manifest-missing":
41
+ return `${d.code}::${d.filePath}`;
36
42
  case "unresolved-reference":
37
43
  return `${d.code}::${d.filePath}::${d.line}::${d.column}::${d.symbol}::${d.memberChain.join(".")}`;
38
44
  case "cycle-in-resolution":
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostic.js","sourceRoot":"","sources":["../src/diagnostic.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+EH,SAAS,iBAAiB,CAAC,CAAQ;IACjC,MAAM,IAAI,KAAK,CAAC,8BAA+B,CAAsB,CAAC,IAAI,EAAE,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,QAAQ,CAAC,CAAa;IAC7B,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,uBAAuB;YAC1B,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,IAAI,IAAI,EAAE,KAAK,CAAC,CAAC,MAAM,IAAI,EAAE,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QACvF,KAAK,oBAAoB;YACvB,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,IAAI,IAAI,EAAE,KAAK,CAAC,CAAC,MAAM,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;QACtF,KAAK,2BAA2B;YAC9B,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;QAClD,KAAK,mBAAmB;YACtB,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;QAC5E,KAAK,sBAAsB;YACzB,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACrG,KAAK,qBAAqB;YACxB,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QACjD,KAAK,gBAAgB;YACnB,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;QACrD,KAAK,gBAAgB;YACnB,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;QACrD;YACE,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;AACH,CAAC;AAID,MAAM,UAAU,yBAAyB;IACvC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,OAAO;QACL,IAAI,CAAC,CAAC;YACJ,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,OAAO;YAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,KAAK;YACH,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;YAC5B,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACnB,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"diagnostic.js","sourceRoot":"","sources":["../src/diagnostic.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ export type { TagName, WrapperId, IndexedComponent, Loc, WarningCode, Warning, S
8
8
  export { asTagName, asWrapperId, emptyLocalIndex } from "./scan-types.js";
9
9
  export type { Enrichment, AuthoredLeafPayload } from "./enrichment.js";
10
10
  export { normalizeOwnerPath } from "./owner-utils.js";
11
+ export { logicalKeyFor, hashLogicalKey, computeLogicalId } from "./logical-id.js";
11
12
  export { computeOccurrenceId } from "./occurrence-id.js";
12
13
  export { projectPropUsages, classifyExprText } from "./project-props.js";
13
14
  export type { CompositionRollup, DeclaredProp, DeclaredPropApi } from "./output-types.js";
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ export { manifestJsonSchema } from "./schema.js";
4
4
  export { ManifestBuilder } from "./builder.js";
5
5
  export { asTagName, asWrapperId, emptyLocalIndex } from "./scan-types.js";
6
6
  export { normalizeOwnerPath } from "./owner-utils.js";
7
+ export { logicalKeyFor, hashLogicalKey, computeLogicalId } from "./logical-id.js";
7
8
  export { computeOccurrenceId } from "./occurrence-id.js";
8
9
  export { projectPropUsages, classifyExprText } from "./project-props.js";
9
10
  export * from "./output-types.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC3G,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAe/C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAI1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGzE,cAAc,mBAAmB,CAAC;AAGlC,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC3G,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAe/C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAI1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGzE,cAAc,mBAAmB,CAAC;AAGlC,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { OutputIdentity } from "./output-types.js";
2
+ export declare function logicalKeyFor(identity: OutputIdentity): string | null;
3
+ export declare function hashLogicalKey(key: string): string;
4
+ export declare function computeLogicalId(identity: OutputIdentity, physicalId: string): string;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * THE logical-id seam (COM-388). A logical component groups the physical
3
+ * identities that realize it; the key is a pure function of one identity:
4
+ * - external custom-element -> logical::<tagName>
5
+ * - external react/vue with `wraps` -> its TARGET's tag key (same as above)
6
+ * - everything else -> null (singleton: logicalId = physical id)
7
+ * Tag keys are deliberately modulePath-free (COM-341/COM-338) and derivable
8
+ * from the identity alone so every repo lands on the same id (COM-252).
9
+ * Keyed on tag name alone, not package+tag (spec D7, 2026-07-25): tag names
10
+ * are the platform's global-uniqueness contract, and package-keying split a
11
+ * resolved custom element from its package-unresolved twin onto two logical
12
+ * ids for the same element.
13
+ * Do not re-derive these keys anywhere else — import from here (CLI stamps
14
+ * at scan time; web-shared derives only for legacy stored artifacts).
15
+ *
16
+ * This module is ISOMORPHIC on purpose. `deriveLogicalId` (web-shared) is
17
+ * reachable from `"use client"` components, so the seam gets bundled for the
18
+ * browser as well as run in Node. Hashing therefore goes through
19
+ * `@noble/hashes` (zero-dependency, no `node:crypto`); `hashLogicalKey` stays
20
+ * byte-identical to the `createHash("sha1")` form it replaced — see the
21
+ * byte-identity suite in tests/logical-id.test.ts. Keep this file free of
22
+ * *unconditional* Node builtins: anything added here ships to the client.
23
+ * (`@noble/hashes/utils` resolves `node:crypto` only under the `node` export
24
+ * condition, via `@noble/hashes/crypto` -> `cryptoNode.js`; isomorphism rests
25
+ * on bundlers picking the browser condition, not on the module graph being
26
+ * literally builtin-free.)
27
+ */
28
+ import { sha1 } from "@noble/hashes/legacy";
29
+ import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils";
30
+ export function logicalKeyFor(identity) {
31
+ if (identity.scope !== "external")
32
+ return null;
33
+ if (identity.kind === "custom-element" && identity.tagName !== undefined) {
34
+ return `logical::${identity.tagName}`;
35
+ }
36
+ if (identity.wraps !== undefined) {
37
+ return `logical::${identity.wraps.tagName}`;
38
+ }
39
+ return null;
40
+ }
41
+ export function hashLogicalKey(key) {
42
+ return bytesToHex(sha1(utf8ToBytes(key))).slice(0, 16);
43
+ }
44
+ export function computeLogicalId(identity, physicalId) {
45
+ const key = logicalKeyFor(identity);
46
+ return key === null ? physicalId : hashLogicalKey(key);
47
+ }
48
+ //# sourceMappingURL=logical-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logical-id.js","sourceRoot":"","sources":["../src/logical-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAG9D,MAAM,UAAU,aAAa,CAAC,QAAwB;IACpD,IAAI,QAAQ,CAAC,KAAK,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,QAAQ,CAAC,IAAI,KAAK,gBAAgB,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACzE,OAAO,YAAY,QAAQ,CAAC,OAAO,EAAE,CAAC;IACxC,CAAC;IACD,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,YAAY,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAwB,EAAE,UAAkB;IAC3E,MAAM,GAAG,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACpC,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;AACzD,CAAC"}
@@ -3,6 +3,7 @@
3
3
  * occurrences). Lives in plugin-core so consumers (cli, future analytics,
4
4
  * agents) share one source of truth without depending on cli internals.
5
5
  */
6
+ import type { Diagnostic } from "./diagnostic.js";
6
7
  import type { OccurrenceVia } from "./via-types.js";
7
8
  import type { Lifecycle } from "./types.js";
8
9
  export type ComponentScope = "external" | "local";
@@ -46,9 +47,9 @@ export type OutputIdentity = {
46
47
  column: number;
47
48
  };
48
49
  /**
49
- * Cross-link from a React wrapper to the underlying custom element it wraps.
50
- * Set on react-component identities whose package's CEM declares a
51
- * custom-element with `className === this.exportName`.
50
+ * Cross-link from a framework wrapper to the underlying custom element it wraps.
51
+ * Set on react-component and vue-component identities whose package's CEM
52
+ * declares a custom-element with `className === this.exportName`.
52
53
  * Absent when no CEM match or for non-wrapper imports.
53
54
  * Does NOT participate in componentId hashing.
54
55
  */
@@ -57,13 +58,6 @@ export type OutputIdentity = {
57
58
  tagName: string;
58
59
  packageName: string;
59
60
  };
60
- /**
61
- * Cross-link from a custom element to all React wrappers pointing at it.
62
- * Sorted array of componentIds (deterministic order). Populated in the
63
- * post-resolve aggregation phase of scan.ts.
64
- * Does NOT participate in componentId hashing.
65
- */
66
- wrappedBy?: string[];
67
61
  };
68
62
  export type PropDecl = {
69
63
  type?: string;
@@ -193,17 +187,22 @@ export type EntryPackageRef = {
193
187
  };
194
188
  /**
195
189
  * Why this component is in the inventory (#340 spec, 2026-07-16).
196
- * Total classification; precedence: direct > via-wrapper > root > none.
190
+ * Total classification; precedence: direct > root > none.
197
191
  * - direct: ≥1 parsed occurrence (JSX / template / HTML tag).
198
- * - via-wrapper: zero occurrences; wrap-aggregation join anchor of a used wrapper.
199
192
  * - root: local, zero occurrences, framework entry-point file's default export.
200
193
  * - none: anything else, including external zero-occurrence rows. Catch-all.
201
194
  * Manifest-derived components are never emitted, so no catalogue value exists.
202
195
  */
203
- export type UsageKind = "direct" | "via-wrapper" | "root" | "none";
196
+ export type UsageKind = "direct" | "root" | "none";
204
197
  export type OutputComponent = {
205
198
  id: string;
206
199
  identity: OutputIdentity;
200
+ /**
201
+ * Logical-component id this physical identity realizes (COM-388).
202
+ * Singletons carry their own `id`; wrap chains share the tag-keyed hash.
203
+ * See plugin-core/src/logical-id.ts — the ONE derivation seam.
204
+ */
205
+ logicalId: string;
207
206
  manifest: {
208
207
  source: "authored";
209
208
  data: AuthoredManifestData;
@@ -285,6 +284,21 @@ export type ScanMeta = {
285
284
  branch: string | null;
286
285
  };
287
286
  };
287
+ /**
288
+ * First-class realization edge (COM-388). Replaces the deleted synthetic
289
+ * zero-occurrence node: the edge target is a logical key, bound to a physical
290
+ * componentId only when that target was observed in this repo's scan.
291
+ * Only "wraps" is emitted today; the union stays open for future sources
292
+ * ("re-exports" provenance is already carried by #242 folding + entryPackages).
293
+ */
294
+ export type RelationshipEdge = {
295
+ sourceId: string;
296
+ type: "wraps";
297
+ target: {
298
+ logicalKey: string;
299
+ componentId?: string;
300
+ };
301
+ };
288
302
  /**
289
303
  * The complete scan artifact shape produced by the CLI.
290
304
  * Two-grain structure: components (rolled-up identity + manifest + composition) +
@@ -294,4 +308,12 @@ export type ScanArtifact = {
294
308
  meta: ScanMeta;
295
309
  components: OutputComponent[];
296
310
  occurrences: OutputOccurrence[];
311
+ relationships: RelationshipEdge[];
312
+ /**
313
+ * Observations the scan could not turn into a component — unresolved tags,
314
+ * unresolved imports, bailed-out re-export chains. Reader surfaces project
315
+ * from these to tell a consumer what the scan could NOT see, which no
316
+ * component row can express.
317
+ */
318
+ diagnostics: Diagnostic[];
297
319
  };
@@ -5,7 +5,7 @@
5
5
  * depend on the CLI package (circular), so every type that crosses the
6
6
  * parser ↔ CLI boundary lives here in `plugin-core`.
7
7
  */
8
- import type { DeclaredPropApi, OutputComponent, OutputOccurrence, ScanMeta } from "./output-types.js";
8
+ import type { DeclaredPropApi, OutputComponent, OutputOccurrence, RelationshipEdge, ScanMeta } from "./output-types.js";
9
9
  import type { Diagnostic, DiagnosticCollector } from "./diagnostic.js";
10
10
  import type { ComponentId, ManifestComponent, ManifestSource } from "./types.js";
11
11
  import type { OccurrenceVia } from "./via-types.js";
@@ -280,4 +280,6 @@ export type ScanOutput = {
280
280
  components: OutputComponent[];
281
281
  occurrences: OutputOccurrence[];
282
282
  diagnostics: Diagnostic[];
283
+ /** Realization edges (COM-388). Populated post-resolve by applyWrapRelationships (scan.ts). */
284
+ relationships: RelationshipEdge[];
283
285
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@component-compass/plugin-core",
3
- "version": "0.1.11",
3
+ "version": "0.1.17",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -8,6 +8,10 @@
8
8
  ".": {
9
9
  "types": "./dist/index.d.ts",
10
10
  "import": "./dist/index.js"
11
+ },
12
+ "./logical-id": {
13
+ "types": "./dist/logical-id.d.ts",
14
+ "import": "./dist/logical-id.js"
11
15
  }
12
16
  },
13
17
  "files": [
@@ -21,6 +25,7 @@
21
25
  "clean": "rm -rf dist .turbo"
22
26
  },
23
27
  "dependencies": {
28
+ "@noble/hashes": "1.8.0",
24
29
  "ajv": "8.20.0"
25
30
  },
26
31
  "devDependencies": {