@intentius/chant 0.124.21 → 0.124.23

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 (95) hide show
  1. package/dist/audit/rules-doc.js +1 -1
  2. package/dist/cli/handlers/graph.js +24 -1
  3. package/dist/codegen/docs-pages.d.ts +1 -0
  4. package/dist/codegen/docs-pages.d.ts.map +1 -1
  5. package/dist/codegen/docs-pages.js +1 -0
  6. package/dist/codegen/docs-sections.d.ts +2 -0
  7. package/dist/codegen/docs-sections.d.ts.map +1 -1
  8. package/dist/codegen/docs-sections.js +8 -0
  9. package/dist/codegen/docs-types.d.ts +7 -0
  10. package/dist/codegen/docs-types.d.ts.map +1 -1
  11. package/dist/codegen/docs.d.ts.map +1 -1
  12. package/dist/codegen/docs.js +20 -0
  13. package/dist/fold/subset.d.ts +3 -1
  14. package/dist/fold/subset.d.ts.map +1 -1
  15. package/dist/fold/subset.js +3 -1
  16. package/dist/graph-ir.d.ts +43 -0
  17. package/dist/graph-ir.d.ts.map +1 -1
  18. package/dist/graph-ir.js +27 -0
  19. package/dist/lexicon.d.ts +25 -1
  20. package/dist/lexicon.d.ts.map +1 -1
  21. package/dist/lint/rules/evl004-spread-non-const.d.ts.map +1 -1
  22. package/dist/lint/rules/evl004-spread-non-const.js +19 -1
  23. package/dist/wave-runtime.mjs +222 -206
  24. package/dist/workspace/checks/links.d.ts +5 -0
  25. package/dist/workspace/checks/links.d.ts.map +1 -1
  26. package/dist/workspace/checks/links.js +54 -8
  27. package/dist/workspace/checks.d.ts +4 -1
  28. package/dist/workspace/checks.d.ts.map +1 -1
  29. package/dist/workspace/checks.js +6 -2
  30. package/dist/workspace/compose-graph.d.ts +4 -1
  31. package/dist/workspace/compose-graph.d.ts.map +1 -1
  32. package/dist/workspace/compose-graph.js +3 -2
  33. package/dist/workspace/dbt-project-reader.d.ts +36 -0
  34. package/dist/workspace/dbt-project-reader.d.ts.map +1 -0
  35. package/dist/workspace/dbt-project-reader.js +290 -0
  36. package/dist/workspace/graph-cli.d.ts.map +1 -1
  37. package/dist/workspace/graph-cli.js +3 -1
  38. package/dist/workspace/graph.schema.json +41 -3
  39. package/dist/workspace/intent.js +7 -2
  40. package/dist/workspace/kind-link-readers.d.ts +84 -0
  41. package/dist/workspace/kind-link-readers.d.ts.map +1 -0
  42. package/dist/workspace/kind-link-readers.js +53 -0
  43. package/dist/workspace/kinds.d.ts +15 -0
  44. package/dist/workspace/kinds.d.ts.map +1 -1
  45. package/dist/workspace/kinds.js +11 -0
  46. package/dist/workspace/lexicon-outputs.d.ts +63 -0
  47. package/dist/workspace/lexicon-outputs.d.ts.map +1 -0
  48. package/dist/workspace/lexicon-outputs.js +241 -0
  49. package/dist/workspace/links.d.ts +29 -7
  50. package/dist/workspace/links.d.ts.map +1 -1
  51. package/dist/workspace/links.js +109 -34
  52. package/dist/workspace/member-handles.d.ts +18 -1
  53. package/dist/workspace/member-handles.d.ts.map +1 -1
  54. package/dist/workspace/member-handles.js +31 -14
  55. package/dist/workspace/records-checkout.d.ts +11 -1
  56. package/dist/workspace/records-checkout.d.ts.map +1 -1
  57. package/dist/workspace/records-checkout.js +38 -2
  58. package/dist/workspace/status.d.ts.map +1 -1
  59. package/dist/workspace/status.js +3 -2
  60. package/dist/workspace/workspace-kinds.schema.json +5 -0
  61. package/package.json +1 -1
  62. package/src/audit/rules-doc.ts +1 -1
  63. package/src/cli/handlers/graph.ts +22 -1
  64. package/src/codegen/docs-pages.ts +1 -0
  65. package/src/codegen/docs-sections.ts +8 -0
  66. package/src/codegen/docs-site/AgentPrompt.astro +153 -0
  67. package/src/codegen/docs-types.ts +7 -0
  68. package/src/codegen/docs.ts +27 -0
  69. package/src/fold/subset.ts +3 -1
  70. package/src/graph-ir.test.ts +23 -1
  71. package/src/graph-ir.ts +65 -0
  72. package/src/lexicon.ts +26 -1
  73. package/src/lint/rules/evl004-spread-non-const.test.ts +18 -0
  74. package/src/lint/rules/evl004-spread-non-const.ts +16 -1
  75. package/src/wave-loop-golden.test.ts +3 -0
  76. package/src/workspace/checks/links.ts +57 -8
  77. package/src/workspace/checks.e2e.test.ts +1 -1
  78. package/src/workspace/checks.ts +9 -2
  79. package/src/workspace/compose-graph.ts +5 -3
  80. package/src/workspace/dbt-kind.e2e.test.ts +95 -0
  81. package/src/workspace/dbt-kind.test.ts +283 -0
  82. package/src/workspace/dbt-project-reader.ts +291 -0
  83. package/src/workspace/graph-cli.ts +3 -1
  84. package/src/workspace/graph.schema.json +41 -3
  85. package/src/workspace/intent.ts +7 -2
  86. package/src/workspace/kind-link-readers.ts +109 -0
  87. package/src/workspace/kinds.ts +21 -1
  88. package/src/workspace/lexicon-outputs.ts +272 -0
  89. package/src/workspace/links.test.ts +22 -0
  90. package/src/workspace/links.ts +129 -34
  91. package/src/workspace/member-handles.ts +28 -8
  92. package/src/workspace/records-checkout.ts +36 -2
  93. package/src/workspace/records-uncommitted.test.ts +5 -1
  94. package/src/workspace/status.ts +3 -2
  95. package/src/workspace/workspace-kinds.schema.json +5 -0
@@ -15,7 +15,11 @@
15
15
  * that parameter give way to the declared one, which is how an inferred edge
16
16
  * is promoted.
17
17
  *
18
- * Every row says how it was found (`declared` or `inferred:joinKey`), where it
18
+ * A member whose kind has a link reader (#3932, `./kind-link-readers.ts`) also
19
+ * states links in its own files, such as a dbt project's sources. Those rows
20
+ * have origin `kind-reader` and carry the file and line that state them.
21
+ *
22
+ * Every row says how it was found (`declared`, `kind-reader` or `inferred:joinKey`), where it
19
23
  * resolved (`source`, or `live` for the rows of `check --live`, #2549) and its status. A link that
20
24
  * can't be resolved is kept, with the reason.
21
25
  *
@@ -29,6 +33,7 @@ import { type JoinLabel } from "../join-key.js";
29
33
  import type { Declaration, LinkDeclaration, Member } from "./declaration.js";
30
34
  import type { KindRegistry, MemberKind } from "./kinds.js";
31
35
  import type { MemberCollector } from "./compose-graph.js";
36
+ import type { KindLinkRead } from "./kind-link-readers.js";
32
37
  /**
33
38
  * The link kinds chant knows. Closed: a link of any other kind fails closed.
34
39
  * `output` reads a named output of the producer. `telemetry` (#2558, D22)
@@ -41,13 +46,19 @@ export declare const DEFAULT_LINK_KIND = "output";
41
46
  export declare const TELEMETRY_LINK_KIND = "telemetry";
42
47
  /** The OTLP protocols a telemetry link may state, as `OTEL_EXPORTER_OTLP_PROTOCOL` names them. */
43
48
  export declare const TELEMETRY_PROTOCOLS: readonly ["grpc", "http/protobuf", "http/json"];
44
- /** How a row was found: written down, or inferred by the named rule. */
45
- export type LinkOrigin = "declared" | "inferred:joinKey";
49
+ /**
50
+ * How a row was found: written down in the declaration, read from the
51
+ * member's own files by its kind's link reader (#3932), or inferred by the
52
+ * named rule.
53
+ */
54
+ export type LinkOrigin = "declared" | "kind-reader" | "inferred:joinKey";
46
55
  /** One output or parameter of a member, as a join sees it. */
47
56
  export interface JoinHandle {
48
57
  name: string;
49
58
  /** The node that holds it, when the reader knows one (a graph IR id). */
50
59
  node?: string;
60
+ /** Names it had before, from a rename hint in the producer's source (#3931). */
61
+ previously?: readonly string[];
51
62
  }
52
63
  /** What a member offers links, and what it reads. */
53
64
  export interface MemberHandles {
@@ -72,6 +83,10 @@ interface RowBase {
72
83
  resolves: "source" | "live";
73
84
  /** Why the row is not `resolved`, or null. */
74
85
  reason: string | null;
86
+ /** A `kind-reader` row (#3932): the reader, and the file (from the workspace root) and line that state the link. */
87
+ reader?: string;
88
+ file?: string;
89
+ line?: number;
75
90
  }
76
91
  /** A declared link, or an inferred join with one producer. */
77
92
  export interface LinkRow extends RowBase {
@@ -102,7 +117,11 @@ export interface TelemetryTargets {
102
117
  collectors: ReadonlyMap<string, MemberCollector>;
103
118
  composed: ReadonlySet<string>;
104
119
  }
105
- /** A parameter that joins outputs of two or more producers (or two outputs of one). */
120
+ /**
121
+ * A parameter that joins outputs of two or more producers (or two outputs of
122
+ * one). For a `kind-reader` row whose file names no producer, `input` is the
123
+ * output it reads, and the candidates are the members that could produce it.
124
+ */
106
125
  export interface AmbiguousRow extends RowBase {
107
126
  status: "ambiguous";
108
127
  input: string;
@@ -132,9 +151,11 @@ export declare function linkTargetProblem(declaration: Declaration, consumer: Me
132
151
  * Resolve every declared link and infer the joins nobody wrote down.
133
152
  * `handles` holds one entry per member whose handles were read; a member
134
153
  * missing from it is unresolved. Declared rows come first, in declaration
135
- * order; inferred and ambiguous rows follow, sorted by consumer and parameter.
154
+ * order; then the rows each member's kind reader found (`readLinks`, #3932),
155
+ * in member and file order; inferred and ambiguous rows follow, sorted by
156
+ * consumer and parameter.
136
157
  */
137
- export declare function resolveLinks(declaration: Declaration, handles: ReadonlyMap<string, MemberHandles>, telemetry?: TelemetryTargets): LinkTableRow[];
158
+ export declare function resolveLinks(declaration: Declaration, handles: ReadonlyMap<string, MemberHandles>, telemetry?: TelemetryTargets, readLinks?: ReadonlyMap<string, KindLinkRead>): LinkTableRow[];
138
159
  /**
139
160
  * The handles of a member whose kind lists its outputs, or exposes none.
140
161
  * Undefined for a kind whose outputs are read from the member (`chant`).
@@ -150,6 +171,7 @@ export interface ComposedHandles {
150
171
  member: string;
151
172
  name: string;
152
173
  node?: string;
174
+ previously?: readonly string[];
153
175
  }[];
154
176
  imports: readonly {
155
177
  member: string;
@@ -171,6 +193,6 @@ export declare function irMemberHandles(graph: ComposedHandles): Map<string, Mem
171
193
  * With `kinds`, a member that isn't composed but whose kind lists its outputs
172
194
  * (`other`, kinds from a package) is a link target too.
173
195
  */
174
- export declare function graphLinks(declaration: Declaration, graph: ComposedHandles, kinds?: KindRegistry): LinkTableRow[];
196
+ export declare function graphLinks(declaration: Declaration, graph: ComposedHandles, kinds?: KindRegistry, readLinks?: ReadonlyMap<string, KindLinkRead>): LinkTableRow[];
175
197
  export {};
176
198
  //# sourceMappingURL=links.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../src/workspace/links.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../src/workspace/links.ts"],"names":[],"mappings":"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"}
@@ -15,7 +15,11 @@
15
15
  * that parameter give way to the declared one, which is how an inferred edge
16
16
  * is promoted.
17
17
  *
18
- * Every row says how it was found (`declared` or `inferred:joinKey`), where it
18
+ * A member whose kind has a link reader (#3932, `./kind-link-readers.ts`) also
19
+ * states links in its own files, such as a dbt project's sources. Those rows
20
+ * have origin `kind-reader` and carry the file and line that state them.
21
+ *
22
+ * Every row says how it was found (`declared`, `kind-reader` or `inferred:joinKey`), where it
19
23
  * resolved (`source`, or `live` for the rows of `check --live`, #2549) and its status. A link that
20
24
  * can't be resolved is kept, with the reason.
21
25
  *
@@ -79,9 +83,11 @@ function nearNames(name, outputs) {
79
83
  * Resolve every declared link and infer the joins nobody wrote down.
80
84
  * `handles` holds one entry per member whose handles were read; a member
81
85
  * missing from it is unresolved. Declared rows come first, in declaration
82
- * order; inferred and ambiguous rows follow, sorted by consumer and parameter.
86
+ * order; then the rows each member's kind reader found (`readLinks`, #3932),
87
+ * in member and file order; inferred and ambiguous rows follow, sorted by
88
+ * consumer and parameter.
83
89
  */
84
- export function resolveLinks(declaration, handles, telemetry) {
90
+ export function resolveLinks(declaration, handles, telemetry, readLinks) {
85
91
  const rows = [];
86
92
  const declaredTargets = new Map();
87
93
  for (const consumer of declaration.members) {
@@ -123,34 +129,19 @@ export function resolveLinks(declaration, handles, telemetry) {
123
129
  row.reason = `protocol applies to telemetry links; this link has kind ${kind}`;
124
130
  continue;
125
131
  }
126
- const producer = handles.get(link.member);
127
- const found = producer?.outputs.find((o) => o.name === link.output);
128
- if (found) {
129
- if (found.node)
130
- row.to = found.node;
131
- continue;
132
- }
133
- if (!producer) {
134
- row.status = "unresolved";
135
- row.reason = `the outputs of ${link.member} were not read`;
136
- }
137
- else if (producer.exposesNone) {
138
- row.status = "missing";
139
- row.reason = producer.why ?? `${link.member} exposes no outputs`;
140
- }
141
- else if (!producer.complete) {
142
- row.status = "unresolved";
143
- row.reason = `${link.output} was not found in ${link.member}, whose outputs could not all be read in source${producer.why ? ` (${producer.why})` : ""}`;
144
- }
145
- else {
146
- const near = nearNames(link.output, producer.outputs);
147
- const known = producer.outputs.map((o) => o.name);
148
- row.status = "missing";
149
- row.reason =
150
- `${link.member} has no output ${link.output}` +
151
- (near.length ? `; did you mean ${near.join(" or ")}? Links match exactly` : "") +
152
- (known.length ? `; its outputs: ${[...new Set(known)].sort(cmp).join(", ")}` : "; it exposes no outputs");
153
- }
132
+ resolveOutput(row, handles);
133
+ }
134
+ }
135
+ // Links a kind's reader found in the member's own files (#3932).
136
+ for (const consumer of declaration.members) {
137
+ const read = readLinks?.get(consumer.name);
138
+ if (!read)
139
+ continue;
140
+ for (const link of read.links) {
141
+ const row = readerRow(declaration, consumer, read, link, handles);
142
+ rows.push(row);
143
+ if (row.status !== "ambiguous")
144
+ (declaredTargets.get(consumer.name) ?? declaredTargets.set(consumer.name, new Set()).get(consumer.name)).add(`${row.producer}\0${row.output}`);
154
145
  }
155
146
  }
156
147
  // Inferred joins: a consumer's parameter against every other member's outputs.
@@ -213,6 +204,88 @@ export function resolveLinks(declaration, handles, telemetry) {
213
204
  inferred.sort((a, b) => cmp(a.consumer, b.consumer) || cmp(a.input ?? "", b.input ?? ""));
214
205
  return [...rows, ...inferred];
215
206
  }
207
+ /** Match a declared or reader's output row against its producer's handles, setting its status and reason. */
208
+ function resolveOutput(row, handles) {
209
+ const producer = handles.get(row.producer);
210
+ const found = producer?.outputs.find((o) => o.name === row.output);
211
+ if (found) {
212
+ if (found.node)
213
+ row.to = found.node;
214
+ return;
215
+ }
216
+ if (!producer) {
217
+ row.status = "unresolved";
218
+ row.reason = `the outputs of ${row.producer} were not read`;
219
+ }
220
+ else if (producer.exposesNone) {
221
+ row.status = "missing";
222
+ row.reason = producer.why ?? `${row.producer} exposes no outputs`;
223
+ }
224
+ else if (!producer.complete) {
225
+ row.status = "unresolved";
226
+ row.reason = `${row.output} was not found in ${row.producer}, whose outputs could not all be read in source${producer.why ? ` (${producer.why})` : ""}`;
227
+ }
228
+ else {
229
+ const renamed = [...new Set(producer.outputs.filter((o) => o.previously?.includes(row.output)).map((o) => o.name))].sort(cmp);
230
+ const near = renamed.length ? [] : nearNames(row.output, producer.outputs);
231
+ const known = producer.outputs.map((o) => o.name);
232
+ row.status = "missing";
233
+ row.reason =
234
+ `${row.producer} has no output ${row.output}` +
235
+ (renamed.length ? `; it was renamed to ${renamed.join(" or ")}, so link to that instead` : "") +
236
+ (near.length ? `; did you mean ${near.join(" or ")}? Links match exactly` : "") +
237
+ (known.length ? `; its outputs: ${[...new Set(known)].sort(cmp).join(", ")}` : "; it exposes no outputs");
238
+ }
239
+ }
240
+ /**
241
+ * The row for one link a kind's reader found (#3932). A link whose file names
242
+ * its producer resolves like a declared one. One that doesn't is given the
243
+ * producer that exposes its anchor (a dbt column's table); when none does,
244
+ * and exactly one other member exposes outputs at all, that member, so a
245
+ * dropped table is missing from the only place it could be. Otherwise the
246
+ * row is ambiguous, and the message names the field that settles it.
247
+ */
248
+ function readerRow(declaration, consumer, read, link, handles) {
249
+ const base = { consumer: consumer.name, kind: DEFAULT_LINK_KIND, origin: "kind-reader", resolves: "source", reader: read.reader, file: link.file, line: link.line };
250
+ let producer = link.member;
251
+ if (producer === null) {
252
+ const anchor = link.anchor ?? link.output;
253
+ const others = declaration.members.filter((m) => m.name !== consumer.name);
254
+ const exposing = others.filter((m) => handles.get(m.name)?.outputs.some((o) => o.name === anchor));
255
+ const possible = others.filter((m) => {
256
+ const h = handles.get(m.name);
257
+ return h !== undefined && !h.exposesNone;
258
+ });
259
+ if (exposing.length === 1)
260
+ producer = exposing[0].name;
261
+ else if (exposing.length === 0 && possible.length === 1)
262
+ producer = possible[0].name;
263
+ else {
264
+ const candidates = (exposing.length > 0 ? exposing : possible).map((m) => ({ producer: m.name, output: link.output, label: "exact" }));
265
+ const field = read.producerField ? `; set fields.${read.producerField} on ${consumer.name} to name it` : "";
266
+ return {
267
+ ...base,
268
+ status: "ambiguous",
269
+ input: link.output,
270
+ candidates,
271
+ reason: exposing.length > 1
272
+ ? `${link.file}:${link.line} reads ${anchor}, which ${exposing.map((m) => m.name).join(" and ")} all expose${field}`
273
+ : candidates.length > 0
274
+ ? `${link.file}:${link.line} reads ${anchor}, which no member exposes, and ${consumer.name} does not say which of ${candidates.map((c) => c.producer).join(", ")} produces it${field}`
275
+ : `${link.file}:${link.line} reads ${anchor}, and no other member exposes outputs`,
276
+ };
277
+ }
278
+ }
279
+ const row = { ...base, producer, output: link.output, label: "exact", input: null, status: "resolved", reason: null };
280
+ const problem = linkTargetProblem(declaration, consumer, { member: producer });
281
+ if (problem) {
282
+ row.status = "invalid";
283
+ row.reason = read.producerField ? `fields.${read.producerField}: ${problem}` : problem;
284
+ return row;
285
+ }
286
+ resolveOutput(row, handles);
287
+ return row;
288
+ }
216
289
  /**
217
290
  * Resolve a telemetry link against the producer's collector (#2558): the
218
291
  * target exists (presence), and when the link states a protocol, the target
@@ -290,7 +363,9 @@ export function irMemberHandles(graph) {
290
363
  for (const member of graph.composed) {
291
364
  out.set(member, {
292
365
  member,
293
- outputs: graph.exports.filter((e) => e.member === member).map((e) => ({ name: e.name, ...(e.node ? { node: e.node } : {}) })),
366
+ outputs: graph.exports
367
+ .filter((e) => e.member === member)
368
+ .map((e) => ({ name: e.name, ...(e.node ? { node: e.node } : {}), ...(e.previously?.length ? { previously: e.previously } : {}) })),
294
369
  inputs: graph.imports.filter((i) => i.member === member).map((i) => ({ name: i.name, node: i.node })),
295
370
  complete: true,
296
371
  why: null,
@@ -306,7 +381,7 @@ export function irMemberHandles(graph) {
306
381
  * With `kinds`, a member that isn't composed but whose kind lists its outputs
307
382
  * (`other`, kinds from a package) is a link target too.
308
383
  */
309
- export function graphLinks(declaration, graph, kinds) {
384
+ export function graphLinks(declaration, graph, kinds, readLinks) {
310
385
  const handles = irMemberHandles(graph);
311
386
  for (const m of declaration.members) {
312
387
  const kind = kinds?.get(m.kind);
@@ -320,7 +395,7 @@ export function graphLinks(declaration, graph, kinds) {
320
395
  collectors: new Map((graph.collectors ?? []).map((c) => [c.member, c])),
321
396
  composed: new Set(graph.composed),
322
397
  };
323
- return resolveLinks(declaration, handles, telemetry).map((row) => {
398
+ return resolveLinks(declaration, handles, telemetry, readLinks).map((row) => {
324
399
  if (row.status === "ambiguous" || row.origin !== "declared")
325
400
  return row;
326
401
  // The declaration's pointer means nothing to a graph reader.
@@ -23,6 +23,7 @@ import { type Declaration, type ResolvedGroup } from "./declaration.js";
23
23
  import type { KindRegistry } from "./kinds.js";
24
24
  import { type MemberHandles } from "./links.js";
25
25
  import { type WorkspaceTree } from "./tree.js";
26
+ import type { MemberLexiconOutputs } from "./lexicon-outputs.js";
26
27
  /** One output or parameter found in source. */
27
28
  export interface SourceHandle {
28
29
  name: string;
@@ -37,18 +38,34 @@ export interface SourceHandles {
37
38
  /** Why the list of outputs may be incomplete, one line each. Empty when it is complete. */
38
39
  gaps: string[];
39
40
  }
41
+ /**
42
+ * Every source file under `dir` (tree-relative), leaving out `exclude`d
43
+ * directories (other members, group matches), `node_modules`, dot
44
+ * directories and build output.
45
+ */
46
+ export declare function sourceFiles(tree: WorkspaceTree, dir: string, exclude: ReadonlySet<string>): string[];
40
47
  /**
41
48
  * Read a chant member's outputs and parameters from the source under `dir`
42
49
  * (tree-relative, `""` for the root), leaving out the `exclude`d directories.
43
50
  * Runs no member code.
44
51
  */
45
52
  export declare function readSourceHandles(tree: WorkspaceTree, dir: string, exclude?: ReadonlySet<string>): SourceHandles;
53
+ /**
54
+ * The directories inside member `m` that are not its source: other members'
55
+ * directories and example-group matches nested in it.
56
+ */
57
+ export declare function memberExcludes(declaration: Declaration, groups: readonly ResolvedGroup[], m: Declaration["members"][number]): Set<string>;
46
58
  /**
47
59
  * Every member's handles, read in source for `chant workspace check`. A
48
60
  * `chant` member's outputs and parameters are parsed from its TypeScript
49
61
  * without running it; other kinds expose what the kind and the entry list.
50
62
  * A member whose directory is missing or whose kind is unknown is left out,
51
63
  * so links to it are unresolved.
64
+ *
65
+ * `lexiconOutputs` adds what the member's lexicons report about their own
66
+ * declarations (#3931, `./lexicon-outputs.ts`), gathered beforehand because
67
+ * reading them folds the member's files, which is asynchronous. Its gaps
68
+ * count as the member's.
52
69
  */
53
- export declare function sourceMemberHandles(declaration: Declaration, tree: WorkspaceTree, groups: readonly ResolvedGroup[], kinds: KindRegistry): Map<string, MemberHandles>;
70
+ export declare function sourceMemberHandles(declaration: Declaration, tree: WorkspaceTree, groups: readonly ResolvedGroup[], kinds: KindRegistry, lexiconOutputs?: ReadonlyMap<string, MemberLexiconOutputs>): Map<string, MemberHandles>;
54
71
  //# sourceMappingURL=member-handles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"member-handles.d.ts","sourceRoot":"","sources":["../../src/workspace/member-handles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAY,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AAIlE,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,2DAA2D;IAC3D,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,2FAA2F;IAC3F,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AA8HD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAAW,CAAC,MAAM,CAAa,GAAG,aAAa,CAa3H;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,KAAK,EAAE,YAAY,GAClB,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAyB5B"}
1
+ {"version":3,"file":"member-handles.d.ts","sourceRoot":"","sources":["../../src/workspace/member-handles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAY,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAI9D,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,2DAA2D;IAC3D,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,2FAA2F;IAC3F,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAaD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAepG;AA6FD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAAW,CAAC,MAAM,CAAa,GAAG,aAAa,CAa3H;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,aAAa,EAAE,EAAE,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAKzI;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,KAAK,EAAE,YAAY,EACnB,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,GACzD,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CA2B5B"}
@@ -39,7 +39,7 @@ function isSourceFile(name) {
39
39
  * directories (other members, group matches), `node_modules`, dot
40
40
  * directories and build output.
41
41
  */
42
- function sourceFiles(tree, dir, exclude) {
42
+ export function sourceFiles(tree, dir, exclude) {
43
43
  const out = [];
44
44
  const walk = (at) => {
45
45
  for (const e of tree.list(at) ?? []) {
@@ -174,14 +174,34 @@ export function readSourceHandles(tree, dir, exclude = new Set()) {
174
174
  }
175
175
  return out;
176
176
  }
177
+ /**
178
+ * The directories inside member `m` that are not its source: other members'
179
+ * directories and example-group matches nested in it.
180
+ */
181
+ export function memberExcludes(declaration, groups, m) {
182
+ const exclude = new Set();
183
+ for (const o of declaration.members)
184
+ if (o !== m && o.dir !== "." && isInside(o.dir, m.dir))
185
+ exclude.add(o.dir);
186
+ for (const g of groups)
187
+ for (const dir of g.matches)
188
+ if (isInside(dir, m.dir))
189
+ exclude.add(dir);
190
+ return exclude;
191
+ }
177
192
  /**
178
193
  * Every member's handles, read in source for `chant workspace check`. A
179
194
  * `chant` member's outputs and parameters are parsed from its TypeScript
180
195
  * without running it; other kinds expose what the kind and the entry list.
181
196
  * A member whose directory is missing or whose kind is unknown is left out,
182
197
  * so links to it are unresolved.
198
+ *
199
+ * `lexiconOutputs` adds what the member's lexicons report about their own
200
+ * declarations (#3931, `./lexicon-outputs.ts`), gathered beforehand because
201
+ * reading them folds the member's files, which is asynchronous. Its gaps
202
+ * count as the member's.
183
203
  */
184
- export function sourceMemberHandles(declaration, tree, groups, kinds) {
204
+ export function sourceMemberHandles(declaration, tree, groups, kinds, lexiconOutputs) {
185
205
  const out = new Map();
186
206
  for (const m of declaration.members) {
187
207
  const kind = kinds.get(m.kind);
@@ -193,21 +213,18 @@ export function sourceMemberHandles(declaration, tree, groups, kinds) {
193
213
  }
194
214
  else {
195
215
  // Other members' directories and group matches inside this one are not its source.
196
- const exclude = new Set();
197
- for (const o of declaration.members)
198
- if (o !== m && o.dir !== "." && isInside(o.dir, m.dir))
199
- exclude.add(o.dir);
200
- for (const g of groups)
201
- for (const dir of g.matches)
202
- if (isInside(dir, m.dir))
203
- exclude.add(dir);
204
- const read = readSourceHandles(tree, memberDir(m.dir), exclude);
216
+ const read = readSourceHandles(tree, memberDir(m.dir), memberExcludes(declaration, groups, m));
217
+ const lexicon = lexiconOutputs?.get(m.name);
218
+ const gaps = [...read.gaps, ...(lexicon?.gaps ?? [])];
205
219
  out.set(m.name, {
206
220
  member: m.name,
207
- outputs: read.outputs.map((o) => ({ name: o.name })),
221
+ outputs: [
222
+ ...read.outputs.map((o) => ({ name: o.name })),
223
+ ...(lexicon?.outputs ?? []).map((o) => ({ name: o.name, ...(o.previously?.length ? { previously: o.previously } : {}) })),
224
+ ],
208
225
  inputs: read.inputs.map((i) => ({ name: i.name })),
209
- complete: read.gaps.length === 0,
210
- why: read.gaps.length === 0 ? null : read.gaps.length === 1 ? read.gaps[0] : `${read.gaps[0]}, and ${read.gaps.length - 1} more`,
226
+ complete: gaps.length === 0,
227
+ why: gaps.length === 0 ? null : gaps.length === 1 ? gaps[0] : `${gaps[0]}, and ${gaps.length - 1} more`,
211
228
  exposesNone: false,
212
229
  });
213
230
  }
@@ -11,7 +11,9 @@
11
11
  *
12
12
  * Every git call here reads. None takes the index lock or refreshes the
13
13
  * index (`--no-optional-locks`), so a read leaves the checkout as it was,
14
- * `.git` included, which the reader conformance suite checks.
14
+ * `.git` included, which the reader conformance suite checks. A diff against
15
+ * the working tree is the exception git makes: it refreshes the index even
16
+ * then, so {@link worktreeChanges} runs it on a private copy.
15
17
  */
16
18
  import { type BaseSource } from "./trust/provenance.js";
17
19
  /** Where a record's file stands against `HEAD`. */
@@ -32,6 +34,14 @@ export interface CheckoutView extends CheckoutHead {
32
34
  /** Record files of the kind at `head` that the working tree no longer has, from the repository root, sorted. */
33
35
  deleted: string[];
34
36
  }
37
+ /**
38
+ * The paths under `spec` whose working-tree content differs from `rev`, or
39
+ * undefined when git can't say. `git diff <rev>` refreshes the index's stat
40
+ * data for a file touched without a change, and writes the index even under
41
+ * `--no-optional-locks` (git 2.54), so it runs against a copy of the index
42
+ * (`GIT_INDEX_FILE`) and the checkout's own index is never written.
43
+ */
44
+ export declare function worktreeChanges(top: string, rev: string, spec: string): string[] | undefined;
35
45
  /**
36
46
  * The branch, head and base of the checkout at `top`. `explicitBase` is
37
47
  * `--base`, as the trust policy takes it; otherwise the target branch is the
@@ -1 +1 @@
1
- {"version":3,"file":"records-checkout.d.ts","sourceRoot":"","sources":["../../src/workspace/records-checkout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAElE,mDAAmD;AACnD,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,KAAK,CAAC;AAE7D,6FAA6F;AAC7F,MAAM,WAAW,YAAY;IAC3B,uGAAuG;IACvG,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,+GAA+G;IAC/G,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,+IAA+I;IAC/I,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,+HAA+H;IAC/H,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;CAC7B;AAED,gHAAgH;AAChH,MAAM,WAAW,YAAa,SAAQ,YAAY;IAChD,gHAAgH;IAChH,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAmBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,CAMjF;AAOD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,KAAK,EAAE,MAAM,GACZ;IAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAe3D"}
1
+ {"version":3,"file":"records-checkout.d.ts","sourceRoot":"","sources":["../../src/workspace/records-checkout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAElE,mDAAmD;AACnD,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,KAAK,CAAC;AAE7D,6FAA6F;AAC7F,MAAM,WAAW,YAAY;IAC3B,uGAAuG;IACvG,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,+GAA+G;IAC/G,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,+IAA+I;IAC/I,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,+HAA+H;IAC/H,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;CAC7B;AAED,gHAAgH;AAChH,MAAM,WAAW,YAAa,SAAQ,YAAY;IAChD,gHAAgH;IAChH,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAmBD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAoB5F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,CAMjF;AAOD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,KAAK,EAAE,MAAM,GACZ;IAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAe3D"}
@@ -11,9 +11,14 @@
11
11
  *
12
12
  * Every git call here reads. None takes the index lock or refreshes the
13
13
  * index (`--no-optional-locks`), so a read leaves the checkout as it was,
14
- * `.git` included, which the reader conformance suite checks.
14
+ * `.git` included, which the reader conformance suite checks. A diff against
15
+ * the working tree is the exception git makes: it refreshes the index even
16
+ * then, so {@link worktreeChanges} runs it on a private copy.
15
17
  */
16
18
  import { execFileSync } from "node:child_process";
19
+ import { copyFileSync, existsSync, mkdtempSync, rmSync } from "node:fs";
20
+ import { tmpdir } from "node:os";
21
+ import { isAbsolute, join } from "node:path";
17
22
  import { resolveBase } from "./trust/provenance.js";
18
23
  function git(top, args) {
19
24
  return execFileSync("git", ["--no-optional-locks", "--literal-pathspecs", ...args], {
@@ -31,6 +36,37 @@ function tryGit(top, args) {
31
36
  return undefined;
32
37
  }
33
38
  }
39
+ /**
40
+ * The paths under `spec` whose working-tree content differs from `rev`, or
41
+ * undefined when git can't say. `git diff <rev>` refreshes the index's stat
42
+ * data for a file touched without a change, and writes the index even under
43
+ * `--no-optional-locks` (git 2.54), so it runs against a copy of the index
44
+ * (`GIT_INDEX_FILE`) and the checkout's own index is never written.
45
+ */
46
+ export function worktreeChanges(top, rev, spec) {
47
+ const scratch = mkdtempSync(join(tmpdir(), "chant-index-"));
48
+ try {
49
+ const at = tryGit(top, ["rev-parse", "--git-path", "index"])?.trim();
50
+ const index = at ? (isAbsolute(at) ? at : join(top, at)) : undefined;
51
+ const copy = join(scratch, "index");
52
+ if (index && existsSync(index))
53
+ copyFileSync(index, copy);
54
+ const out = execFileSync("git", ["--no-optional-locks", "--literal-pathspecs", "diff", "--name-only", "-z", "--no-renames", rev, "--", spec], {
55
+ cwd: top,
56
+ encoding: "utf-8",
57
+ stdio: ["ignore", "pipe", "pipe"],
58
+ maxBuffer: 256 * 1024 * 1024,
59
+ env: { ...process.env, GIT_INDEX_FILE: copy },
60
+ });
61
+ return out.split("\0").filter(Boolean);
62
+ }
63
+ catch {
64
+ return undefined;
65
+ }
66
+ finally {
67
+ rmSync(scratch, { recursive: true, force: true });
68
+ }
69
+ }
34
70
  /**
35
71
  * The branch, head and base of the checkout at `top`. `explicitBase` is
36
72
  * `--base`, as the trust policy takes it; otherwise the target branch is the
@@ -67,7 +103,7 @@ export function worktreeStates(top, head, dir, paths, match) {
67
103
  const direct = (p) => p.startsWith(prefix) && !p.slice(prefix.length).includes("/");
68
104
  const spec = dir === "." ? "." : dir;
69
105
  const atHead = new Set(zList(tryGit(top, ["ls-tree", "-r", "-z", "--name-only", head, "--", spec])).filter(direct));
70
- const changed = new Set(zList(tryGit(top, ["diff", "--name-only", "-z", "--no-renames", head, "--", spec])));
106
+ const changed = new Set(worktreeChanges(top, head, spec) ?? []);
71
107
  for (const p of paths)
72
108
  states.set(p, !atHead.has(p) ? "new" : changed.has(p) ? "modified" : "committed");
73
109
  const present = new Set(paths);
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/workspace/status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/workspace/status.ts"],"names":[],"mappings":"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"}
@@ -39,7 +39,7 @@ import { readPathSha } from "../lifecycle/git.js";
39
39
  import { latestPerComponent, readReleaseLedger } from "../lifecycle/release-ledger.js";
40
40
  import { readReleasePlan } from "../lifecycle/plan-ledger.js";
41
41
  import { listWorkLeases } from "../lifecycle/work-lease.js";
42
- import { readCheckoutHead } from "./records-checkout.js";
42
+ import { readCheckoutHead, worktreeChanges } from "./records-checkout.js";
43
43
  import { policyView, replicationState } from "./wip.js";
44
44
  import { findWorkspaceRoot } from "../project-root.js";
45
45
  import { resolveBoxes } from "./box-isolation.js";
@@ -174,7 +174,8 @@ async function shipView(member, cwd, read) {
174
174
  // The commit must be here: a release from a commit this checkout never had says nothing about it.
175
175
  if (lines(["cat-file", "-e", `${last.gitSha}^{commit}`]) === null)
176
176
  return view;
177
- const changed = lines(["diff", "--name-only", "-z", "--no-renames", last.gitSha, "--"]);
177
+ // A diff against the working tree writes the index; run it on a copy.
178
+ const changed = worktreeChanges(top, last.gitSha, ".") ?? null;
178
179
  const untracked = lines(["ls-files", "--others", "--exclude-standard", "-z"]);
179
180
  if (changed === null || untracked === null)
180
181
  return view;
@@ -78,6 +78,11 @@
78
78
  },
79
79
  "fields": {
80
80
  "$ref": "#/$defs/fields"
81
+ },
82
+ "reader": {
83
+ "type": "string",
84
+ "pattern": "^[a-z][a-z0-9-]{0,39}$",
85
+ "description": "A link reader chant ships, by name, that derives a member's links from the member's own files (#3932): dbt-project reads a dbt project's sources. The reader is chant's code and runs offline, parsing files as data; the package supplies only the name. A name this chant doesn't have keeps the kind without a reader, and the load reports it. A chant older than this field fails a kinds file that uses it."
81
86
  }
82
87
  },
83
88
  "patternProperties": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant",
3
- "version": "0.124.21",
3
+ "version": "0.124.23",
4
4
  "description": "Declarative infrastructure-as-code toolkit — TypeScript on Node.js",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -84,7 +84,7 @@ export function ruleBlock(m: RuleMeta): string {
84
84
  // heading instead, so an old link/alias reference still lands on the id.
85
85
  const tags = m.deprecated ? `${m.tier} · ${m.fixKind} · ~~deprecated~~` : `${m.tier} · ${m.fixKind}`;
86
86
  return (
87
- `### ${m.id}\n\n**${mdxEscape(m.title)}** — ${tags}\n\n${mdxEscape(m.remediation)}` +
87
+ `### ${m.id}\n\n**${mdxEscape(m.title)}** (${tags})\n\n${mdxEscape(m.remediation)}` +
88
88
  `${backingTable(m)}` +
89
89
  `${m.aliases?.length ? aliasesLine(m.aliases) : ""}` +
90
90
  `${m.deprecated ? deprecatedNote(m.deprecated) : ""}`