@invariant-ui/cli 0.0.0-stage → 0.2.0

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 (190) hide show
  1. package/LICENSE +105 -0
  2. package/README.md +250 -2
  3. package/dist/agent-kit/apply.js +232 -0
  4. package/dist/agent-kit/guidance.js +236 -0
  5. package/dist/agent-kit/index.js +5 -0
  6. package/dist/agent-kit/integrations.js +121 -0
  7. package/dist/agent-kit/plugin.js +115 -0
  8. package/dist/artifact-generator/index.js +75 -0
  9. package/dist/browser-verify/driver.js +2 -0
  10. package/dist/browser-verify/index.js +4 -0
  11. package/dist/browser-verify/playwright.js +82 -0
  12. package/dist/browser-verify/runner.js +175 -0
  13. package/dist/browser-verify/spec.js +103 -0
  14. package/dist/cli/args.js +77 -0
  15. package/dist/cli/baseline.js +64 -0
  16. package/dist/cli/cli.js +121 -0
  17. package/dist/cli/commands-browser.js +104 -0
  18. package/dist/cli/commands-discover.js +312 -0
  19. package/dist/cli/commands-enforcement.js +35 -0
  20. package/dist/cli/commands-governance.js +179 -0
  21. package/dist/cli/commands-hook.js +269 -0
  22. package/dist/cli/commands-patterns.js +324 -0
  23. package/dist/cli/commands-setup.js +485 -0
  24. package/dist/cli/commands-validate.js +157 -0
  25. package/dist/cli/commands.js +517 -0
  26. package/dist/cli/config.js +197 -0
  27. package/dist/cli/diff.js +66 -0
  28. package/dist/cli/enforcement-log.js +83 -0
  29. package/dist/cli/enforcement-report.js +96 -0
  30. package/dist/cli/errors.js +10 -0
  31. package/dist/cli/format.js +22 -0
  32. package/dist/cli/index.js +5 -0
  33. package/dist/cli/io.js +2 -0
  34. package/dist/cli/main.js +31 -0
  35. package/dist/cli/pipeline.js +262 -0
  36. package/dist/cli/publish.js +77 -0
  37. package/dist/cli/report.js +127 -0
  38. package/dist/cli/starter-rules.js +57 -0
  39. package/dist/cli/store.js +60 -0
  40. package/dist/cli/version.js +5 -0
  41. package/dist/cli/watch.js +68 -0
  42. package/dist/cli/workflow.js +52 -0
  43. package/dist/compiler-angular/adapter.js +115 -0
  44. package/dist/compiler-angular/analyze.js +222 -0
  45. package/dist/compiler-angular/classes.js +446 -0
  46. package/dist/compiler-angular/declared.js +285 -0
  47. package/dist/compiler-angular/emit.js +183 -0
  48. package/dist/compiler-angular/index.js +4 -0
  49. package/dist/compiler-angular/template.js +142 -0
  50. package/dist/compiler-core/adapter.js +2 -0
  51. package/dist/compiler-core/adapters/inventory.js +312 -0
  52. package/dist/compiler-core/compile.js +148 -0
  53. package/dist/compiler-core/component-facts.js +123 -0
  54. package/dist/compiler-core/discovery/docs.js +66 -0
  55. package/dist/compiler-core/discovery/entries.js +270 -0
  56. package/dist/compiler-core/discovery/exports.js +207 -0
  57. package/dist/compiler-core/discovery/graph.js +59 -0
  58. package/dist/compiler-core/discovery/index.js +103 -0
  59. package/dist/compiler-core/discovery/packages.js +148 -0
  60. package/dist/compiler-core/discovery/schema.js +144 -0
  61. package/dist/compiler-core/discovery/storybook.js +232 -0
  62. package/dist/compiler-core/discovery/support.js +82 -0
  63. package/dist/compiler-core/discovery/tokens.js +186 -0
  64. package/dist/compiler-core/discovery/tooling.js +146 -0
  65. package/dist/compiler-core/fs.js +89 -0
  66. package/dist/compiler-core/glob.js +3 -0
  67. package/dist/compiler-core/index.js +16 -0
  68. package/dist/compiler-core/ir-builder.js +68 -0
  69. package/dist/compiler-core/json-schema.js +11 -0
  70. package/dist/compiler-core/testing/index.js +81 -0
  71. package/dist/compiler-core/ts/ast.js +166 -0
  72. package/dist/compiler-core/ts/members.js +163 -0
  73. package/dist/compiler-core/ts/program.js +81 -0
  74. package/dist/compiler-core/ts/static-eval.js +145 -0
  75. package/dist/compiler-core/ts/tsconfig-paths.js +60 -0
  76. package/dist/compiler-core/walk.js +46 -0
  77. package/dist/compiler-ir/index.js +4 -0
  78. package/dist/compiler-ir/ir.js +67 -0
  79. package/dist/compiler-ir/json-schema.js +6 -0
  80. package/dist/compiler-ir/validate.js +116 -0
  81. package/dist/compiler-react/adapter.js +147 -0
  82. package/dist/compiler-react/analyze.js +199 -0
  83. package/dist/compiler-react/behavior.js +75 -0
  84. package/dist/compiler-react/detect.js +558 -0
  85. package/dist/compiler-react/emit.js +188 -0
  86. package/dist/compiler-react/index.js +2 -0
  87. package/dist/compiler-react/props.js +157 -0
  88. package/dist/compiler-react/styling.js +138 -0
  89. package/dist/compiler-react/usage.js +116 -0
  90. package/dist/compiler-react/variants.js +111 -0
  91. package/dist/compiler-storybook/adapter.js +253 -0
  92. package/dist/compiler-storybook/csf.js +521 -0
  93. package/dist/compiler-storybook/emit.js +202 -0
  94. package/dist/compiler-storybook/index-json.js +41 -0
  95. package/dist/compiler-storybook/index.js +5 -0
  96. package/dist/compiler-storybook/mdx.js +120 -0
  97. package/dist/compiler-tokens/adapter.js +158 -0
  98. package/dist/compiler-tokens/css.js +59 -0
  99. package/dist/compiler-tokens/index.js +5 -0
  100. package/dist/compiler-tokens/json-lines.js +106 -0
  101. package/dist/compiler-tokens/json-tokens.js +52 -0
  102. package/dist/compiler-vue/adapter.js +107 -0
  103. package/dist/compiler-vue/analyze.js +344 -0
  104. package/dist/compiler-vue/declared.js +343 -0
  105. package/dist/compiler-vue/emit.js +129 -0
  106. package/dist/compiler-vue/index.js +5 -0
  107. package/dist/compiler-vue/script.js +472 -0
  108. package/dist/compiler-vue/sfc.js +44 -0
  109. package/dist/compiler-vue/template.js +73 -0
  110. package/dist/contract/archetype-checks.js +153 -0
  111. package/dist/contract/components.js +102 -0
  112. package/dist/contract/conflicts.js +39 -0
  113. package/dist/contract/contract.js +46 -0
  114. package/dist/contract/evidence.js +84 -0
  115. package/dist/contract/fact-path.js +39 -0
  116. package/dist/contract/facts.js +62 -0
  117. package/dist/contract/index.js +16 -0
  118. package/dist/contract/integrity.js +21 -0
  119. package/dist/contract/json-schema.js +11 -0
  120. package/dist/contract/knowledge.js +95 -0
  121. package/dist/contract/pattern-checks.js +254 -0
  122. package/dist/contract/patterns.js +225 -0
  123. package/dist/contract/primitives.js +81 -0
  124. package/dist/contract/sources.js +30 -0
  125. package/dist/contract/tokens.js +41 -0
  126. package/dist/contract/validate.js +253 -0
  127. package/dist/contract-query/archetype.js +188 -0
  128. package/dist/contract-query/index.js +6 -0
  129. package/dist/contract-query/patterns.js +298 -0
  130. package/dist/contract-query/search.js +132 -0
  131. package/dist/contract-query/system.js +148 -0
  132. package/dist/contract-query/views.js +288 -0
  133. package/dist/governance/decisions.js +229 -0
  134. package/dist/governance/index.js +5 -0
  135. package/dist/governance/patterns-file.js +156 -0
  136. package/dist/governance/patterns.js +510 -0
  137. package/dist/governance/policies.js +148 -0
  138. package/dist/mcp/index.js +7 -0
  139. package/dist/mcp/loader.js +70 -0
  140. package/dist/mcp/protocol.js +27 -0
  141. package/dist/mcp/resources.js +138 -0
  142. package/dist/mcp/server.js +177 -0
  143. package/dist/mcp/stdio.js +28 -0
  144. package/dist/mcp/tools.js +267 -0
  145. package/dist/reconciliation/code.js +62 -0
  146. package/dist/reconciliation/components.js +401 -0
  147. package/dist/reconciliation/conflicts.js +126 -0
  148. package/dist/reconciliation/facts.js +41 -0
  149. package/dist/reconciliation/index.js +7 -0
  150. package/dist/reconciliation/reconcile.js +134 -0
  151. package/dist/reconciliation/resolve.js +158 -0
  152. package/dist/reconciliation/review.js +81 -0
  153. package/dist/reconciliation/storybook.js +370 -0
  154. package/dist/reconciliation/tokens.js +179 -0
  155. package/dist/reconciliation/util.js +55 -0
  156. package/dist/semantic-engine/additive.js +51 -0
  157. package/dist/semantic-engine/compounds.js +91 -0
  158. package/dist/semantic-engine/documents.js +157 -0
  159. package/dist/semantic-engine/enrich.js +42 -0
  160. package/dist/semantic-engine/index.js +7 -0
  161. package/dist/semantic-engine/infer.js +38 -0
  162. package/dist/semantic-engine/tokens.js +120 -0
  163. package/dist/shared/canonical.js +65 -0
  164. package/dist/shared/diagnostic.js +78 -0
  165. package/dist/shared/glob.js +98 -0
  166. package/dist/shared/index.js +4 -0
  167. package/dist/shared/json.js +2 -0
  168. package/dist/validation/card.js +50 -0
  169. package/dist/validation/discovery/arrangements.js +162 -0
  170. package/dist/validation/discovery/discover.js +70 -0
  171. package/dist/validation/discovery/index.js +8 -0
  172. package/dist/validation/discovery/model.js +127 -0
  173. package/dist/validation/discovery/promote.js +24 -0
  174. package/dist/validation/discovery/reviews.js +63 -0
  175. package/dist/validation/discovery/shapes.js +47 -0
  176. package/dist/validation/discovery/similar-files.js +146 -0
  177. package/dist/validation/discovery/util.js +47 -0
  178. package/dist/validation/index.js +11 -0
  179. package/dist/validation/interaction-facts.js +341 -0
  180. package/dist/validation/interaction-workflows.js +633 -0
  181. package/dist/validation/literals.js +251 -0
  182. package/dist/validation/pattern-rules.js +608 -0
  183. package/dist/validation/policy.js +241 -0
  184. package/dist/validation/report.js +163 -0
  185. package/dist/validation/rules.js +269 -0
  186. package/dist/validation/scan.js +295 -0
  187. package/dist/validation/text.js +34 -0
  188. package/dist/validation/validate-code.js +513 -0
  189. package/dist/validation/validate-usage.js +196 -0
  190. package/package.json +38 -4
@@ -0,0 +1,111 @@
1
+ import { declarationOf, literalValue, resolveSymbol, unwrap, walkSameFunction } from "../compiler-core/index.js";
2
+ import ts from "typescript";
3
+ /**
4
+ * Variants come from two deterministic sources: props typed as a union of two or more string
5
+ * literals, and `cva(...)` configs (`variants` + `defaultVariants`) whose function the component calls.
6
+ */
7
+ export function variantsOf(analysis, candidate, props) {
8
+ const out = new Map();
9
+ for (const p of props) {
10
+ const values = p.allowedValues;
11
+ if (p.kind !== "enum" || !values || values.length < 2 || !values.every((v) => typeof v === "string"))
12
+ continue;
13
+ const fallback = typeof p.default === "string" && values.includes(p.default) ? p.default : undefined;
14
+ out.set(p.name, {
15
+ name: p.name,
16
+ values: values,
17
+ ...(fallback ? { default: fallback } : {}),
18
+ source: "prop-union",
19
+ node: p.declaration.node
20
+ });
21
+ }
22
+ for (const cva of cvaCallsUsedBy(analysis, candidate)) {
23
+ for (const [name, info] of cva.variants) {
24
+ const existing = out.get(name);
25
+ if (existing?.source !== "cva")
26
+ out.set(name, { ...info, via: cva.via, node: cva.node });
27
+ }
28
+ }
29
+ return [...out.values()].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
30
+ }
31
+ function cvaCallsUsedBy(analysis, candidate) {
32
+ const impl = candidate.impl;
33
+ if (!impl)
34
+ return [];
35
+ const { checker } = analysis;
36
+ const found = new Map();
37
+ const consider = (identifier) => {
38
+ const decl = declarationOf(resolveSymbol(checker, checker.getSymbolAtLocation(identifier)));
39
+ if (decl && ts.isVariableDeclaration(decl) && decl.initializer && isCva(decl.initializer))
40
+ found.set(decl, identifier.text);
41
+ };
42
+ if (ts.isFunctionLike(impl)) {
43
+ walkSameFunction(impl, (n) => {
44
+ if (ts.isCallExpression(n) && ts.isIdentifier(n.expression))
45
+ consider(n.expression);
46
+ });
47
+ }
48
+ else {
49
+ const walk = (n) => {
50
+ if (ts.isCallExpression(n) && ts.isIdentifier(n.expression))
51
+ consider(n.expression);
52
+ ts.forEachChild(n, walk);
53
+ };
54
+ walk(impl);
55
+ }
56
+ return [...found].map(([decl, via]) => {
57
+ const init = unwrap(decl.initializer);
58
+ return { via, node: decl, variants: parseCva(init, via) };
59
+ });
60
+ }
61
+ function isCva(expression) {
62
+ const node = unwrap(expression);
63
+ return ts.isCallExpression(node) && node.expression.getText() === "cva";
64
+ }
65
+ function parseCva(call, via) {
66
+ const result = new Map();
67
+ const config = call.arguments[1] ? unwrap(call.arguments[1]) : undefined;
68
+ if (!config || !ts.isObjectLiteralExpression(config))
69
+ return result;
70
+ const member = (name) => {
71
+ const p = config.properties.find((x) => ts.isPropertyAssignment(x) && x.name.getText() === name);
72
+ return p && ts.isPropertyAssignment(p) ? unwrap(p.initializer) : undefined;
73
+ };
74
+ const variants = member("variants");
75
+ const defaults = member("defaultVariants");
76
+ const defaultMap = new Map();
77
+ if (defaults && ts.isObjectLiteralExpression(defaults)) {
78
+ for (const p of defaults.properties) {
79
+ if (ts.isPropertyAssignment(p)) {
80
+ const v = literalValue(p.initializer);
81
+ if (v !== undefined)
82
+ defaultMap.set(p.name.getText().replace(/^["']|["']$/g, ""), v);
83
+ }
84
+ }
85
+ }
86
+ if (variants && ts.isObjectLiteralExpression(variants)) {
87
+ for (const p of variants.properties) {
88
+ if (!ts.isPropertyAssignment(p))
89
+ continue;
90
+ const inner = unwrap(p.initializer);
91
+ if (!ts.isObjectLiteralExpression(inner))
92
+ continue;
93
+ const name = p.name.getText().replace(/^["']|["']$/g, "");
94
+ const values = inner.properties.flatMap((v) => ts.isPropertyAssignment(v) || ts.isShorthandPropertyAssignment(v)
95
+ ? [v.name.getText().replace(/^["']|["']$/g, "")]
96
+ : []);
97
+ const fallback = defaultMap.get(name);
98
+ result.set(name, {
99
+ name,
100
+ values,
101
+ ...(typeof fallback === "string" || typeof fallback === "boolean" || typeof fallback === "number"
102
+ ? { default: String(fallback) }
103
+ : {}),
104
+ source: "cva",
105
+ via
106
+ });
107
+ }
108
+ }
109
+ return result;
110
+ }
111
+ //# sourceMappingURL=variants.js.map
@@ -0,0 +1,253 @@
1
+ import { createAnalysis, DEFAULT_IGNORED_DIRS, hashText, IrBuilder, posix, tsconfigPaths, walk } from "../compiler-core/index.js";
2
+ import { hashJson } from "../shared/index.js";
3
+ import { extractCsf } from "./csf.js";
4
+ import { CAPABILITIES, emitCsf, emitMdx } from "./emit.js";
5
+ import { parseBuiltIndex } from "./index-json.js";
6
+ import { parseMdx } from "./mdx.js";
7
+ export const ADAPTER_ID = "storybook";
8
+ export const ADAPTER_VERSION = "0.1.0";
9
+ const CODE_FILE = /\.(?:[cm]?[jt]sx?)$/;
10
+ // `.vue` files are loaded as well, so stories that import single-file components can be linked to them.
11
+ const PROGRAM_FILE = /\.(?:[cm]?[jt]sx?|vue)$|(?:^|\/)tsconfig[^/]*\.json$/;
12
+ const MAX_FILE_BYTES = 1_000_000;
13
+ /**
14
+ * Storybook adapter. Reads story files (CSF 2 and 3) and MDX pages statically: titles, the component each
15
+ * meta points at (resolved through the type checker to a file and declaration), args, argTypes and
16
+ * controls, parameters, tags, play-function structure, and components composed in story renders. A built
17
+ * `storybook-static/index.json`, when present, is recorded as optional evidence. Nothing is executed and
18
+ * no story identity is synthesized: a story is identified by its export.
19
+ */
20
+ export const storybookAdapter = {
21
+ id: ADAPTER_ID,
22
+ version: ADAPTER_VERSION,
23
+ type: "storybook",
24
+ async discover({ fs, project }) {
25
+ const sources = [];
26
+ const used = new Set();
27
+ for (const sb of project.storybooks) {
28
+ if (sb.storyFiles.length === 0)
29
+ continue;
30
+ const { files, hashes, paths } = await loadProgramFiles(fs, project, sb);
31
+ const slug = (sb.directory === "." ? "root" : sb.directory)
32
+ .toLowerCase()
33
+ .replace(/[^a-z0-9._-]+/g, "-")
34
+ .replace(/^[^a-z0-9]+|[-.]+$/g, "") || "root";
35
+ let id = `stories-${slug}`;
36
+ for (let n = 2; used.has(id); n++)
37
+ id = `stories-${slug}-${n}`;
38
+ used.add(id);
39
+ const index = sb.builtOutput?.hasIndexJson
40
+ ? await readText(fs, posix.join(sb.builtOutput.path, "index.json"))
41
+ : undefined;
42
+ sources.push({
43
+ id,
44
+ type: "storybook",
45
+ location: sb.directory,
46
+ config: { storybookId: sb.id, files: [...files.keys()], paths },
47
+ ...(sb.version?.installedVersion
48
+ ? { version: { kind: "tool-version", value: sb.version.installedVersion } }
49
+ : {}),
50
+ inputHash: hashJson({
51
+ files: hashes,
52
+ index: index === undefined ? null : hashText(index),
53
+ config: sb.configHash
54
+ })
55
+ });
56
+ }
57
+ return { sources, diagnostics: [] };
58
+ },
59
+ async extract({ fs, project, source, clock }, config) {
60
+ const sb = project.storybooks.find((s) => s.id === config.storybookId);
61
+ if (!sb)
62
+ throw new Error(`Storybook ${config.storybookId} is not in the project discovery`);
63
+ const files = new Map();
64
+ for (const path of config.files)
65
+ files.set(path, await fs.readFile(path));
66
+ const analysis = createAnalysis(files, { paths: config.paths });
67
+ const builder = new IrBuilder({
68
+ source: {
69
+ id: source.id,
70
+ type: source.type,
71
+ location: source.location,
72
+ ...(source.version ? { version: source.version } : {}),
73
+ inputHash: source.inputHash,
74
+ adapter: { name: ADAPTER_ID, version: ADAPTER_VERSION }
75
+ },
76
+ extractor: { name: "storybook-csf", version: ADAPTER_VERSION },
77
+ capabilities: CAPABILITIES,
78
+ clock
79
+ });
80
+ let index;
81
+ if (sb.builtOutput?.hasIndexJson) {
82
+ const text = await readText(fs, posix.join(sb.builtOutput.path, "index.json"));
83
+ index = text === undefined ? undefined : parseBuiltIndex(text);
84
+ if (!index)
85
+ builder.diagnostic({
86
+ code: "storybook.index-unreadable",
87
+ severity: "info",
88
+ message: `${sb.builtOutput.path}/index.json could not be read as a story index and was ignored`
89
+ });
90
+ }
91
+ const storyFiles = sb.storyFiles.filter((f) => CODE_FILE.test(f));
92
+ const mdxFiles = sb.storyFiles.filter((f) => f.endsWith(".mdx"));
93
+ const projectFiles = new Set(files.keys());
94
+ let partial = sb.dynamicProperties.length > 0 || sb.storyFilesTruncated;
95
+ const note = (code, severity, message, location) => {
96
+ builder.diagnostic({ code, severity, message, location });
97
+ };
98
+ // One unusual story file must not fail the whole source: isolate it, report it, and mark the result partial.
99
+ const readStoryFile = (file) => {
100
+ const sf = analysis.sourceFile(file);
101
+ const csf = sf ? extractCsf(analysis, sf) : undefined;
102
+ if (!csf || (!csf.group && csf.stories.length === 0)) {
103
+ note("storybook.no-meta", "warning", `${file} matches the story globs but has no default-exported meta and no stories`, { path: file });
104
+ return;
105
+ }
106
+ emitCsf(builder, csf, index?.entries, index ? posix.relative(sb.directory, file) : undefined);
107
+ const group = csf.group;
108
+ if (!group) {
109
+ note("storybook.no-meta", "warning", `${file} exports stories but no default-exported meta`, {
110
+ path: file
111
+ });
112
+ }
113
+ else {
114
+ if (!group.title)
115
+ note("storybook.title-auto", "info", `${file} has no explicit title; Storybook infers it from the path, which is not reproduced here`, { path: file, line: group.line });
116
+ if (!group.component)
117
+ note("storybook.component-missing", "info", `${file} meta has no resolvable component`, {
118
+ path: file,
119
+ line: group.line
120
+ });
121
+ else if (!group.component.file) {
122
+ const origin = group.component.external
123
+ ? ` (from package ${group.component.external})`
124
+ : group.component.unresolvedModule
125
+ ? ` (module ${group.component.unresolvedModule} not found)`
126
+ : "";
127
+ note("storybook.component-unresolved", "info", `${file} meta component ${group.component.text} could not be resolved to a project file${origin}`, { path: file, line: group.line });
128
+ }
129
+ }
130
+ if (csf.selectionUncertain)
131
+ partial = true;
132
+ if ([csf.group, ...csf.stories].some((x) => x && x.args.unresolved.length > 0)) {
133
+ note("storybook.dynamic-args", "info", `${file} has args that are not statically resolvable; they are listed as unresolved, not guessed`, { path: file });
134
+ }
135
+ };
136
+ for (const file of storyFiles) {
137
+ try {
138
+ readStoryFile(file);
139
+ }
140
+ catch (error) {
141
+ partial = true;
142
+ note("storybook.file-failed", "warning", `${file} could not be analyzed: ${error.message}`, { path: file });
143
+ }
144
+ }
145
+ for (const file of mdxFiles) {
146
+ const text = files.has(file) ? files.get(file) : await fs.readFile(file);
147
+ emitMdx(builder, parseMdx(file, text, projectFiles));
148
+ }
149
+ if (index) {
150
+ const known = new Set(sb.storyFiles.map((f) => posix.relative(sb.directory, f)));
151
+ for (const entry of index.entries) {
152
+ const path = entry.importPath.replace(/^\.\//, "");
153
+ if (!known.has(path))
154
+ note("storybook.index-stale", "warning", `The built index lists ${entry.importPath}, which no longer matches the story globs`, { path: posix.join(sb.directory, path) });
155
+ }
156
+ const indexed = new Set(index.entries.map((e) => e.importPath.replace(/^\.\//, "")));
157
+ for (const file of sb.storyFiles) {
158
+ if (!indexed.has(posix.relative(sb.directory, file)))
159
+ note("storybook.not-in-built-index", "info", `${file} is not in the built index (the build may predate it)`, { path: file });
160
+ }
161
+ }
162
+ return { ir: builder.build(partial ? "partial" : "complete") };
163
+ },
164
+ async validate({ ir }) {
165
+ return ir.entities.length === 0
166
+ ? [
167
+ {
168
+ code: "storybook.no-stories",
169
+ severity: "warning",
170
+ message: `No stories were extracted for ${ir.source.id}`,
171
+ sourceId: ir.source.id
172
+ }
173
+ ]
174
+ : [];
175
+ }
176
+ };
177
+ /**
178
+ * Files for the type-checking program: every package that owns a story file, plus the workspace packages
179
+ * those packages depend on (so `import { X } from "@scope/ui"` resolves to the real declaration).
180
+ */
181
+ async function loadProgramFiles(fs, project, sb) {
182
+ const owners = new Map();
183
+ const owner = (file) => project.packages
184
+ .filter((p) => p.dir === "." || file === p.dir || file.startsWith(`${p.dir}/`))
185
+ .sort((a, b) => b.dir.length - a.dir.length)[0];
186
+ for (const file of sb.storyFiles) {
187
+ const pkg = owner(file);
188
+ if (pkg)
189
+ owners.set(pkg.id, pkg);
190
+ }
191
+ const byName = new Map(project.packages.flatMap((p) => (p.name ? [[p.name, p]] : [])));
192
+ const included = new Map(owners);
193
+ for (const pkg of owners.values()) {
194
+ for (const dep of pkg.dependencies) {
195
+ const target = byName.get(dep.name);
196
+ if (target)
197
+ included.set(target.id, target);
198
+ }
199
+ }
200
+ const paths = {};
201
+ const named = {};
202
+ for (const pkg of included.values()) {
203
+ if (!pkg.name)
204
+ continue;
205
+ for (const entry of pkg.entryPoints) {
206
+ if (!entry.file)
207
+ continue;
208
+ const specifier = entry.subpath === "." ? pkg.name : `${pkg.name}/${entry.subpath.replace(/^\.\//, "")}`;
209
+ named[specifier] = [entry.file];
210
+ }
211
+ }
212
+ const files = new Map();
213
+ const hashes = [];
214
+ for (const pkg of [...included.values()].sort((a, b) => (a.dir < b.dir ? -1 : 1))) {
215
+ const nested = project.packages.filter((p) => p.id !== pkg.id && p.dir !== "." && (pkg.dir === "." || p.dir.startsWith(`${pkg.dir}/`)));
216
+ const walked = await walk(fs, {
217
+ ignoreDirs: new Set(DEFAULT_IGNORED_DIRS),
218
+ maxFiles: 20_000,
219
+ start: pkg.dir
220
+ });
221
+ for (const path of walked.files) {
222
+ if (!PROGRAM_FILE.test(path) ||
223
+ files.has(path) ||
224
+ nested.some((n) => path === n.dir || path.startsWith(`${n.dir}/`)))
225
+ continue;
226
+ const text = await fs.readFile(path);
227
+ if (text.length > MAX_FILE_BYTES)
228
+ continue;
229
+ files.set(path, text);
230
+ hashes.push([path, hashText(text)]);
231
+ }
232
+ }
233
+ // MDX files are read as documents, so their content also determines the input hash.
234
+ for (const file of sb.storyFiles.filter((f) => f.endsWith(".mdx"))) {
235
+ const text = await fs.readFile(file);
236
+ hashes.push([file, hashText(text)]);
237
+ }
238
+ // Each package's own tsconfig `paths` apply first; workspace package names then take precedence.
239
+ for (const pkg of [...included.values()].sort((a, b) => (a.dir < b.dir ? -1 : 1)))
240
+ Object.assign(paths, tsconfigPaths(files, pkg.dir));
241
+ Object.assign(paths, named);
242
+ return { files, hashes, paths };
243
+ }
244
+ async function readText(fs, path) {
245
+ try {
246
+ const text = await fs.readFile(path);
247
+ return text.length > MAX_FILE_BYTES * 5 ? undefined : text;
248
+ }
249
+ catch {
250
+ return undefined;
251
+ }
252
+ }
253
+ //# sourceMappingURL=adapter.js.map