@intentius/chant 0.49.0 → 0.50.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.
- package/dist/audit/catalog.d.ts +13 -3
- package/dist/audit/catalog.d.ts.map +1 -1
- package/dist/audit/core.d.ts +9 -0
- package/dist/audit/core.d.ts.map +1 -1
- package/dist/audit/discover.d.ts +6 -0
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/fetch.d.ts.map +1 -1
- package/dist/audit/report-html.d.ts.map +1 -1
- package/dist/audit/report-model.d.ts +6 -0
- package/dist/audit/report-model.d.ts.map +1 -1
- package/dist/audit/report.d.ts.map +1 -1
- package/dist/audit/rules-doc.d.ts.map +1 -1
- package/dist/audit/secrets.d.ts +95 -0
- package/dist/audit/secrets.d.ts.map +1 -0
- package/dist/audit/wrangler.d.ts +33 -0
- package/dist/audit/wrangler.d.ts.map +1 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/cli/commands/audit.d.ts +7 -0
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/build.d.ts +23 -0
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/components.d.ts +31 -0
- package/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.d.ts +11 -0
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +32 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -0
- package/dist/cli/handlers/scenario.d.ts +39 -0
- package/dist/cli/handlers/scenario.d.ts.map +1 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/server.d.ts +35 -2
- package/dist/cli/mcp/server.d.ts.map +1 -1
- package/dist/cli/mcp/types.d.ts +29 -1
- package/dist/cli/mcp/types.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +14 -2
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/docs-rule-scanning.d.ts.map +1 -1
- package/dist/components/capability.d.ts +17 -2
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +7 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/component.d.ts +15 -0
- package/dist/components/component.d.ts.map +1 -1
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/verbs/index.d.ts +6 -1
- package/dist/components/verbs/index.d.ts.map +1 -1
- package/dist/components/verbs/run-agent.d.ts +499 -0
- package/dist/components/verbs/run-agent.d.ts.map +1 -0
- package/dist/components/verbs/sign.d.ts +30 -0
- package/dist/components/verbs/sign.d.ts.map +1 -1
- package/dist/composite.d.ts +6 -1
- package/dist/composite.d.ts.map +1 -1
- package/dist/discovery/collect.d.ts.map +1 -1
- package/dist/discovery/fold-import.d.ts +15 -1
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/fold-rank.d.ts +66 -0
- package/dist/discovery/fold-rank.d.ts.map +1 -0
- package/dist/discovery/index.d.ts +15 -0
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/param-deps.d.ts +17 -0
- package/dist/discovery/param-deps.d.ts.map +1 -0
- package/dist/fold/fold.d.ts +55 -2
- package/dist/fold/fold.d.ts.map +1 -1
- package/dist/fold/subset.d.ts +21 -14
- package/dist/fold/subset.d.ts.map +1 -1
- package/dist/lexicon-schema.d.ts +2 -0
- package/dist/lexicon-schema.d.ts.map +1 -1
- package/dist/lexicon.d.ts +93 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/converge-ledger.d.ts +90 -0
- package/dist/lifecycle/converge-ledger.d.ts.map +1 -0
- package/dist/lifecycle/deep-diff.d.ts +18 -0
- package/dist/lifecycle/deep-diff.d.ts.map +1 -1
- package/dist/lifecycle/deep-observe.d.ts +9 -1
- package/dist/lifecycle/deep-observe.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +33 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -0
- package/dist/lifecycle/git.d.ts +145 -21
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/index.d.ts +4 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/lease.d.ts +113 -0
- package/dist/lifecycle/lease.d.ts.map +1 -0
- package/dist/lifecycle/scenario-eval.d.ts +42 -0
- package/dist/lifecycle/scenario-eval.d.ts.map +1 -0
- package/dist/lifecycle/scenario.d.ts +163 -0
- package/dist/lifecycle/scenario.d.ts.map +1 -0
- package/dist/lifecycle/symptoms.d.ts +63 -0
- package/dist/lifecycle/symptoms.d.ts.map +1 -0
- package/dist/lint/output-docs.d.ts +94 -0
- package/dist/lint/output-docs.d.ts.map +1 -0
- package/dist/lint/post-synth.d.ts +29 -0
- package/dist/lint/post-synth.d.ts.map +1 -1
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.d.ts +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.d.ts.map +1 -0
- package/dist/lsp/lexicon-providers.d.ts +7 -0
- package/dist/lsp/lexicon-providers.d.ts.map +1 -1
- package/dist/op/activity-contract.d.ts +139 -0
- package/dist/op/activity-contract.d.ts.map +1 -0
- package/dist/op/builders.d.ts +42 -2
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/converge-rule.d.ts +161 -0
- package/dist/op/converge-rule.d.ts.map +1 -0
- package/dist/op/generate-pipeline.d.ts +39 -0
- package/dist/op/generate-pipeline.d.ts.map +1 -0
- package/dist/op/index.d.ts +14 -0
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/op-verb-class.d.ts +42 -0
- package/dist/op/op-verb-class.d.ts.map +1 -0
- package/dist/op/operator.d.ts +128 -0
- package/dist/op/operator.d.ts.map +1 -0
- package/dist/op/step-output-ref.d.ts +187 -0
- package/dist/op/step-output-ref.d.ts.map +1 -0
- package/dist/op/types.d.ts +18 -1
- package/dist/op/types.d.ts.map +1 -1
- package/dist/provenance.d.ts +73 -3
- package/dist/provenance.d.ts.map +1 -1
- package/dist/runtime-adapter.d.ts +7 -1
- package/dist/runtime-adapter.d.ts.map +1 -1
- package/dist/serializer.d.ts +18 -0
- package/dist/serializer.d.ts.map +1 -1
- package/dist/toml.d.ts +40 -5
- package/dist/toml.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/audit/catalog.test.ts +1 -1
- package/src/audit/catalog.ts +75 -3
- package/src/audit/core.ts +9 -0
- package/src/audit/discover.ts +29 -2
- package/src/audit/fetch.test.ts +216 -3
- package/src/audit/fetch.ts +270 -59
- package/src/audit/report-html.ts +5 -2
- package/src/audit/report-model.ts +9 -0
- package/src/audit/report.test.ts +22 -0
- package/src/audit/report.ts +3 -2
- package/src/audit/rules-doc.ts +2 -0
- package/src/audit/secrets.test.ts +303 -0
- package/src/audit/secrets.ts +406 -0
- package/src/audit/wrangler.test.ts +230 -0
- package/src/audit/wrangler.ts +290 -0
- package/src/build.ts +8 -3
- package/src/cli/command-group.ts +1 -1
- package/src/cli/commands/__fixtures__/schemas/sarif-2.1.0.schema.json +2882 -0
- package/src/cli/commands/audit.test.ts +215 -1
- package/src/cli/commands/audit.ts +86 -17
- package/src/cli/commands/build.test.ts +167 -2
- package/src/cli/commands/build.ts +114 -23
- package/src/cli/handlers/build.ts +2 -0
- package/src/cli/handlers/components.test.ts +199 -1
- package/src/cli/handlers/components.ts +160 -3
- package/src/cli/handlers/graph.test.ts +20 -0
- package/src/cli/handlers/graph.ts +10 -1
- package/src/cli/handlers/lifecycle.ts +12 -4
- package/src/cli/handlers/operator.test.ts +255 -0
- package/src/cli/handlers/operator.ts +240 -0
- package/src/cli/handlers/scenario.test.ts +456 -0
- package/src/cli/handlers/scenario.ts +330 -0
- package/src/cli/main.test.ts +23 -0
- package/src/cli/main.ts +72 -1
- package/src/cli/mcp/server.test.ts +265 -2
- package/src/cli/mcp/server.ts +84 -7
- package/src/cli/mcp/types.ts +27 -1
- package/src/cli/registry.ts +14 -2
- package/src/codegen/docs-rule-scanning.test.ts +42 -0
- package/src/codegen/docs-rule-scanning.ts +25 -2
- package/src/components/README.md +7 -0
- package/src/components/capability.ts +17 -2
- package/src/components/cli-support.test.ts +17 -0
- package/src/components/cli-support.ts +13 -1
- package/src/components/component-schema.test.ts +32 -0
- package/src/components/component.schema.json +6 -0
- package/src/components/component.test.ts +21 -0
- package/src/components/component.ts +15 -0
- package/src/components/driver.ts +12 -4
- package/src/components/verbs/index.ts +6 -1
- package/src/components/verbs/run-agent.test.ts +683 -0
- package/src/components/verbs/run-agent.ts +786 -0
- package/src/components/verbs/sign.test.ts +19 -0
- package/src/components/verbs/sign.ts +34 -2
- package/src/composite.ts +31 -2
- package/src/discovery/collect.ts +11 -2
- package/src/discovery/fold-import.test.ts +54 -0
- package/src/discovery/fold-import.ts +178 -38
- package/src/discovery/fold-rank.test.ts +197 -0
- package/src/discovery/fold-rank.ts +346 -0
- package/src/discovery/index.ts +16 -1
- package/src/discovery/param-deps.test.ts +118 -0
- package/src/discovery/param-deps.ts +170 -0
- package/src/fold/fold.test.ts +6 -2
- package/src/fold/fold.ts +184 -3
- package/src/fold/subset.test.ts +82 -19
- package/src/fold/subset.ts +79 -41
- package/src/lexicon-schema.ts +3 -0
- package/src/lexicon.ts +103 -2
- package/src/lifecycle/converge-ledger.test.ts +199 -0
- package/src/lifecycle/converge-ledger.ts +179 -0
- package/src/lifecycle/deep-diff.test.ts +79 -1
- package/src/lifecycle/deep-diff.ts +23 -0
- package/src/lifecycle/deep-observe.ts +13 -2
- package/src/lifecycle/gate-ledger.test.ts +103 -0
- package/src/lifecycle/gate-ledger.ts +140 -0
- package/src/lifecycle/git.test.ts +430 -0
- package/src/lifecycle/git.ts +446 -84
- package/src/lifecycle/index.ts +4 -0
- package/src/lifecycle/lease.test.ts +343 -0
- package/src/lifecycle/lease.ts +270 -0
- package/src/lifecycle/scenario-eval.test.ts +199 -0
- package/src/lifecycle/scenario-eval.ts +158 -0
- package/src/lifecycle/scenario.test.ts +195 -0
- package/src/lifecycle/scenario.ts +321 -0
- package/src/lifecycle/symptoms.test.ts +116 -0
- package/src/lifecycle/symptoms.ts +126 -0
- package/src/lint/output-docs.test.ts +220 -0
- package/src/lint/output-docs.ts +204 -0
- package/src/lint/post-synth.test.ts +97 -0
- package/src/lint/post-synth.ts +45 -0
- package/src/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.ts +26 -0
- package/src/lint/rules/comp/comp.test.ts +49 -1
- package/src/lint/rules/evl001-non-literal-expression.test.ts +8 -3
- package/src/lint/rules/evl001-non-literal-expression.ts +6 -6
- package/src/lsp/lexicon-providers.test.ts +44 -0
- package/src/lsp/lexicon-providers.ts +11 -1
- package/src/op/activity-contract.test.ts +180 -0
- package/src/op/activity-contract.ts +278 -0
- package/src/op/builders-exports.test.ts +17 -1
- package/src/op/builders.ts +59 -5
- package/src/op/converge-rule.test.ts +179 -0
- package/src/op/converge-rule.ts +311 -0
- package/src/op/generate-pipeline.test.ts +53 -0
- package/src/op/generate-pipeline.ts +99 -0
- package/src/op/index.ts +30 -0
- package/src/op/local-executor.test.ts +92 -0
- package/src/op/local-executor.ts +45 -9
- package/src/op/op-verb-class.test.ts +126 -0
- package/src/op/op-verb-class.ts +115 -0
- package/src/op/operator.test.ts +346 -0
- package/src/op/operator.ts +213 -0
- package/src/op/step-output-ref.test.ts +334 -0
- package/src/op/step-output-ref.ts +453 -0
- package/src/op/types.ts +18 -1
- package/src/provenance.test.ts +151 -4
- package/src/provenance.ts +118 -4
- package/src/runtime-adapter.ts +31 -10
- package/src/serializer.ts +18 -0
- package/src/toml.test.ts +157 -384
- package/src/toml.ts +371 -5
package/src/fold/subset.test.ts
CHANGED
|
@@ -74,10 +74,12 @@ const SUPPORTED_CASES: SubsetCase[] = [
|
|
|
74
74
|
|
|
75
75
|
const UNSUPPORTED_CASES: SubsetCase[] = [
|
|
76
76
|
{ name: "function call as a value", expr: `getName()` },
|
|
77
|
-
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
|
|
77
|
+
// chant #1966 moved "method call as a value" and "registered helper name
|
|
78
|
+
// reached as a method" out of this strict-parity list and into "documented
|
|
79
|
+
// divergences" below — a method call now folds when its receiver resolves,
|
|
80
|
+
// which is exactly the identifier-resolution asymmetry every other
|
|
81
|
+
// divergence there already documents.
|
|
82
|
+
//
|
|
81
83
|
// ...and a registered helper with an unfoldable argument is rejected on the
|
|
82
84
|
// argument, by both sides, at the argument's own position.
|
|
83
85
|
{ name: "registered helper with an unfoldable argument", expr: `phase("Apply", [getName()])` },
|
|
@@ -258,28 +260,85 @@ describe("documented divergences — NOT unified by design (see subset.ts module
|
|
|
258
260
|
expect(evl001NonLiteralExpressionRule.check(context)).toHaveLength(0);
|
|
259
261
|
});
|
|
260
262
|
|
|
261
|
-
test("
|
|
263
|
+
test("method call on an unresolved receiver: fold rejects; EVL001 accepts the shape (chant #1966, resolution-dependent)", () => {
|
|
264
|
+
// `config.getName()` — chant #1966 widened `findSubsetViolation` to
|
|
265
|
+
// accept a method call unconditionally (mirroring `.step` and a nested
|
|
266
|
+
// `new` before it), because whether the receiver resolves to a value
|
|
267
|
+
// with that method is resolution-dependent (module doc, point 1) and out
|
|
268
|
+
// of reach for a syntax-only classifier. fold() still rejects it here on
|
|
269
|
+
// the receiver: `config` isn't a `const` this file has.
|
|
270
|
+
const source = `const bad = new Thing({ x: config.getName() });`;
|
|
271
|
+
const sourceFile = ts.createSourceFile("t.ts", source, ts.ScriptTarget.Latest, true);
|
|
272
|
+
const consts = collectConsts(sourceFile);
|
|
273
|
+
const badInit = consts.get("bad") as ts.NewExpression;
|
|
274
|
+
|
|
275
|
+
expect(() => foldResource(badInit, consts, [])).toThrow(FoldError);
|
|
276
|
+
|
|
277
|
+
const context: LintContext = { sourceFile, entities: [], filePath: "t.ts", lexicon: undefined };
|
|
278
|
+
expect(evl001NonLiteralExpressionRule.check(context)).toHaveLength(0);
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
test("registered helper name reached as a method: not the registered call, on either side — rejected for a different reason since #1966", () => {
|
|
282
|
+
// chant #1082 — a registered helper NAME reached through a namespace is
|
|
283
|
+
// still a method call, never the bare registered call: `fold()`'s
|
|
284
|
+
// `{__helper}` shape only ever matches a BARE identifier callee, so
|
|
285
|
+
// `helpers.phase(...)` never gets that treatment, before or after #1966.
|
|
286
|
+
// What changed is WHY it's rejected — `helpers` is an unresolved
|
|
287
|
+
// identifier now reached through the general method-call case, not "no
|
|
288
|
+
// case for a property-access callee" — same divergence direction as the
|
|
289
|
+
// test above.
|
|
290
|
+
const source = `const bad = new Thing({ x: helpers.phase("Apply", []) });`;
|
|
291
|
+
const sourceFile = ts.createSourceFile("t.ts", source, ts.ScriptTarget.Latest, true);
|
|
292
|
+
const consts = collectConsts(sourceFile);
|
|
293
|
+
const badInit = consts.get("bad") as ts.NewExpression;
|
|
294
|
+
|
|
295
|
+
let error: unknown;
|
|
296
|
+
try {
|
|
297
|
+
foldResource(badInit, consts, []);
|
|
298
|
+
} catch (e) {
|
|
299
|
+
error = e;
|
|
300
|
+
}
|
|
301
|
+
expect(error).toBeInstanceOf(FoldError);
|
|
302
|
+
expect((error as FoldError).message).toContain("unresolved identifier: helpers");
|
|
303
|
+
|
|
304
|
+
const context: LintContext = { sourceFile, entities: [], filePath: "t.ts", lexicon: undefined };
|
|
305
|
+
expect(evl001NonLiteralExpressionRule.check(context)).toHaveLength(0);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
test("composite step access: NO LONGER a divergence (chant #1174) — both fold and EVL001 accept it", () => {
|
|
262
309
|
// `Checkout({...}).step` — the single-action Composite() wrapper idiom
|
|
263
310
|
// every lexicon's own docs/examples embed inline inside a Job's
|
|
264
|
-
// `steps:` array.
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
//
|
|
268
|
-
//
|
|
269
|
-
//
|
|
311
|
+
// `steps:` array. This was a documented, EVL-only-permissive divergence
|
|
312
|
+
// from chant #1544 until #1174: `fold()` had no way to invoke an
|
|
313
|
+
// arbitrary composite factory, so it fell the file back to run
|
|
314
|
+
// (correct, not an error) while EVL001 already opted into treating the
|
|
315
|
+
// shape as valid via a since-removed `allowCompositeStepAccess` flag.
|
|
316
|
+
//
|
|
317
|
+
// fold() now folds this to a `{__compositeStep, args}` envelope
|
|
318
|
+
// (../fold/fold.ts) that ../discovery/fold-import.ts's bridge resolves
|
|
319
|
+
// through the folding file's own imports — interpreted when the callee
|
|
320
|
+
// is a project-file registered Composite (chant #1023), invoked for
|
|
321
|
+
// real otherwise (every lexicon-package composite, which is what
|
|
322
|
+
// `Checkout` is) — and reads `.step` off the REAL result. Kept as a
|
|
323
|
+
// test rather than deleted: the assertion that the divergence stays
|
|
324
|
+
// closed.
|
|
270
325
|
const source = `const bad = new Thing({ x: Checkout({}).step });`;
|
|
271
326
|
const sourceFile = ts.createSourceFile("t.ts", source, ts.ScriptTarget.Latest, true);
|
|
272
327
|
const consts = collectConsts(sourceFile);
|
|
273
328
|
const badInit = consts.get("bad") as ts.NewExpression;
|
|
274
329
|
|
|
275
|
-
expect(
|
|
330
|
+
expect(foldResource(badInit, consts, [])).toEqual({
|
|
331
|
+
__resource: "Thing",
|
|
332
|
+
props: { x: { __compositeStep: "Checkout", args: [{}] } },
|
|
333
|
+
});
|
|
276
334
|
|
|
277
|
-
// findSubsetViolation
|
|
278
|
-
//
|
|
279
|
-
const
|
|
280
|
-
|
|
335
|
+
// findSubsetViolation (fold()'s own shared predicate, no opt-in needed
|
|
336
|
+
// anymore) agrees the shape is admissible.
|
|
337
|
+
const stepAccessExpr = (
|
|
338
|
+
(badInit.arguments![0] as ts.ObjectLiteralExpression).properties[0] as ts.PropertyAssignment
|
|
339
|
+
).initializer;
|
|
340
|
+
expect(findSubsetViolation(stepAccessExpr)).toBeUndefined();
|
|
281
341
|
|
|
282
|
-
// EVL001 itself opts in and stops flagging it.
|
|
283
342
|
const context: LintContext = { sourceFile, entities: [], filePath: "t.ts", lexicon: undefined };
|
|
284
343
|
expect(evl001NonLiteralExpressionRule.check(context)).toHaveLength(0);
|
|
285
344
|
});
|
|
@@ -378,10 +437,14 @@ describe("findSubsetViolation — optional intrinsic registry (#1044)", () => {
|
|
|
378
437
|
expect(v?.message).toContain("function call as a value is not foldable: Ref(...)");
|
|
379
438
|
});
|
|
380
439
|
|
|
381
|
-
test("the registry doesn't widen anything else: a name in it without the opt-in, a method
|
|
440
|
+
test("the registry doesn't widen anything else: a name in it without the opt-in, a closure-taking method, and a plain call stay violations", () => {
|
|
382
441
|
const notOptedIn: IntrinsicDef[] = [{ name: "Reference", isTag: false }];
|
|
383
442
|
expect(findSubsetViolation(propValue(`Reference("db")`), notOptedIn)).toBeDefined();
|
|
384
|
-
|
|
443
|
+
// chant #1966 — `aws.Ref("db")` is a method call (`Ref` reached through a
|
|
444
|
+
// namespace, not a bare identifier), so it's no longer here: shape-wise
|
|
445
|
+
// it's now the same resolution-dependent divergence
|
|
446
|
+
// "method call on an unresolved receiver" documents above, unrelated to
|
|
447
|
+
// whether `Ref` itself is opted into `foldsAsCall`.
|
|
385
448
|
expect(findSubsetViolation(propValue(`cidrs.map((c) => c)`, `const cidrs = [];`), REF)).toBeDefined();
|
|
386
449
|
expect(findSubsetViolation(propValue(`makeName("a")`), REF)).toBeDefined();
|
|
387
450
|
});
|
package/src/fold/subset.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as ts from "typescript";
|
|
2
2
|
import { isFoldableHelperName } from "./foldable-helpers";
|
|
3
|
-
import { intrinsicCallFolds, type IntrinsicDef } from "../lexicon";
|
|
3
|
+
import { intrinsicCallFolds, intrinsicCallFoldsEagerly, type IntrinsicDef } from "../lexicon";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* subset — the single canonical definition of chant's statically-foldable
|
|
@@ -231,19 +231,18 @@ export function unsupportedExpressionMessage(node: ts.Node): string {
|
|
|
231
231
|
export function checkObjectMember(
|
|
232
232
|
prop: ts.ObjectLiteralElementLike,
|
|
233
233
|
intrinsics?: readonly IntrinsicDef[],
|
|
234
|
-
allowCompositeStepAccess?: boolean,
|
|
235
234
|
): SubsetViolation | undefined {
|
|
236
235
|
if (ts.isPropertyAssignment(prop)) {
|
|
237
236
|
if (!isLiteralPropertyName(prop.name)) {
|
|
238
237
|
return violation(prop.name, computedPropertyNameMessage(prop.name));
|
|
239
238
|
}
|
|
240
|
-
return findSubsetViolation(prop.initializer, intrinsics
|
|
239
|
+
return findSubsetViolation(prop.initializer, intrinsics);
|
|
241
240
|
}
|
|
242
241
|
if (ts.isShorthandPropertyAssignment(prop)) {
|
|
243
242
|
return undefined;
|
|
244
243
|
}
|
|
245
244
|
if (ts.isSpreadAssignment(prop)) {
|
|
246
|
-
return findSubsetViolation(prop.expression, intrinsics
|
|
245
|
+
return findSubsetViolation(prop.expression, intrinsics);
|
|
247
246
|
}
|
|
248
247
|
return violation(prop, UNSUPPORTED_OBJECT_MEMBER_MESSAGE);
|
|
249
248
|
}
|
|
@@ -252,10 +251,9 @@ export function checkObjectMember(
|
|
|
252
251
|
function checkArrayElement(
|
|
253
252
|
el: ts.Expression,
|
|
254
253
|
intrinsics?: readonly IntrinsicDef[],
|
|
255
|
-
allowCompositeStepAccess?: boolean,
|
|
256
254
|
): SubsetViolation | undefined {
|
|
257
|
-
if (ts.isSpreadElement(el)) return findSubsetViolation(el.expression, intrinsics
|
|
258
|
-
return findSubsetViolation(el, intrinsics
|
|
255
|
+
if (ts.isSpreadElement(el)) return findSubsetViolation(el.expression, intrinsics);
|
|
256
|
+
return findSubsetViolation(el, intrinsics);
|
|
259
257
|
}
|
|
260
258
|
|
|
261
259
|
/**
|
|
@@ -268,23 +266,29 @@ function checkArrayElement(
|
|
|
268
266
|
* `fold()`-evaluation-order) unsupported node, or `undefined` when `node`'s
|
|
269
267
|
* whole shape is foldable.
|
|
270
268
|
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
269
|
+
* The `<call>(...).step` composite-consumer idiom (`Checkout({...}).step`,
|
|
270
|
+
* every lexicon's single-action `Composite()` wrapper embedded inline in a
|
|
271
|
+
* `Job`'s `steps` array — see composites.mdx) used to be an EVL-only,
|
|
272
|
+
* MORE-permissive divergence here (chant #1544's `allowCompositeStepAccess`
|
|
273
|
+
* opt-in parameter, since removed): `fold()` had no way to invoke an
|
|
274
|
+
* arbitrary composite factory, so it fell the file back to run for this
|
|
275
|
+
* shape (documented, correct behavior, never an error) while this shared
|
|
276
|
+
* predicate had to be told to stop treating that fallback as a lint error.
|
|
277
|
+
* chant #1174 closed the divergence — `fold()` now folds exactly this shape
|
|
278
|
+
* (narrowed to the literal member name `"step"`, the one idiom actually in
|
|
279
|
+
* use) — so this classifier accepts it unconditionally, the same way it
|
|
280
|
+
* already accepts a nested `new Type(...)` unconditionally since #1169.
|
|
281
|
+
*
|
|
282
|
+
* chant #1966 adds a CallExpression whose callee is a property access —
|
|
283
|
+
* `github.actor.toString()`, `matrix("os").toString()`, `[...].join(",")` —
|
|
284
|
+
* to the same unconditional-acceptance set: whether the receiver actually
|
|
285
|
+
* folds to a value with a callable method of that name is resolution-
|
|
286
|
+
* dependent (module doc, point 1), so this classifier stays permissive and
|
|
287
|
+
* only recurses into shape.
|
|
283
288
|
*/
|
|
284
289
|
export function findSubsetViolation(
|
|
285
290
|
node: ts.Node,
|
|
286
291
|
intrinsics?: readonly IntrinsicDef[],
|
|
287
|
-
allowCompositeStepAccess?: boolean,
|
|
288
292
|
): SubsetViolation | undefined {
|
|
289
293
|
if (
|
|
290
294
|
ts.isParenthesizedExpression(node) ||
|
|
@@ -292,7 +296,7 @@ export function findSubsetViolation(
|
|
|
292
296
|
ts.isSatisfiesExpression(node) ||
|
|
293
297
|
ts.isNonNullExpression(node)
|
|
294
298
|
) {
|
|
295
|
-
return findSubsetViolation(node.expression, intrinsics
|
|
299
|
+
return findSubsetViolation(node.expression, intrinsics);
|
|
296
300
|
}
|
|
297
301
|
|
|
298
302
|
if (
|
|
@@ -327,7 +331,7 @@ export function findSubsetViolation(
|
|
|
327
331
|
|
|
328
332
|
if (ts.isTemplateExpression(node)) {
|
|
329
333
|
for (const span of node.templateSpans) {
|
|
330
|
-
const v = findSubsetViolation(span.expression, intrinsics
|
|
334
|
+
const v = findSubsetViolation(span.expression, intrinsics);
|
|
331
335
|
if (v) return v;
|
|
332
336
|
}
|
|
333
337
|
return undefined;
|
|
@@ -335,7 +339,7 @@ export function findSubsetViolation(
|
|
|
335
339
|
|
|
336
340
|
if (ts.isObjectLiteralExpression(node)) {
|
|
337
341
|
for (const prop of node.properties) {
|
|
338
|
-
const v = checkObjectMember(prop, intrinsics
|
|
342
|
+
const v = checkObjectMember(prop, intrinsics);
|
|
339
343
|
if (v) return v;
|
|
340
344
|
}
|
|
341
345
|
return undefined;
|
|
@@ -343,35 +347,35 @@ export function findSubsetViolation(
|
|
|
343
347
|
|
|
344
348
|
if (ts.isArrayLiteralExpression(node)) {
|
|
345
349
|
for (const el of node.elements) {
|
|
346
|
-
const v = checkArrayElement(el, intrinsics
|
|
350
|
+
const v = checkArrayElement(el, intrinsics);
|
|
347
351
|
if (v) return v;
|
|
348
352
|
}
|
|
349
353
|
return undefined;
|
|
350
354
|
}
|
|
351
355
|
|
|
352
356
|
if (ts.isPropertyAccessExpression(node)) {
|
|
353
|
-
// chant #
|
|
354
|
-
// (any callee, any argument shape) is the composite-consumer idiom,
|
|
355
|
-
//
|
|
356
|
-
//
|
|
357
|
-
if (
|
|
357
|
+
// chant #1174 — see this function's doc comment. `<call>(...).step`
|
|
358
|
+
// (any callee, any argument shape) is the composite-consumer idiom, and
|
|
359
|
+
// `fold()` now folds it too (narrowed to the literal member `"step"` —
|
|
360
|
+
// see fold.ts's PropertyAccessExpression branch).
|
|
361
|
+
if (node.name.text === "step" && ts.isCallExpression(node.expression)) {
|
|
358
362
|
return undefined;
|
|
359
363
|
}
|
|
360
|
-
return findSubsetViolation(node.expression, intrinsics
|
|
364
|
+
return findSubsetViolation(node.expression, intrinsics);
|
|
361
365
|
}
|
|
362
366
|
|
|
363
367
|
if (ts.isElementAccessExpression(node)) {
|
|
364
368
|
if (!isLiteralElementKey(node.argumentExpression)) {
|
|
365
369
|
return violation(node.argumentExpression, dynamicElementAccessMessage(node.argumentExpression), "EVL003");
|
|
366
370
|
}
|
|
367
|
-
return findSubsetViolation(node.expression, intrinsics
|
|
371
|
+
return findSubsetViolation(node.expression, intrinsics);
|
|
368
372
|
}
|
|
369
373
|
|
|
370
374
|
if (ts.isPrefixUnaryExpression(node)) {
|
|
371
375
|
if (!SUPPORTED_UNARY_OPERATORS.has(node.operator)) {
|
|
372
376
|
return violation(node, UNSUPPORTED_UNARY_MESSAGE);
|
|
373
377
|
}
|
|
374
|
-
return findSubsetViolation(node.operand, intrinsics
|
|
378
|
+
return findSubsetViolation(node.operand, intrinsics);
|
|
375
379
|
}
|
|
376
380
|
|
|
377
381
|
if (ts.isBinaryExpression(node)) {
|
|
@@ -382,17 +386,17 @@ export function findSubsetViolation(
|
|
|
382
386
|
// Flow-insensitive — see module doc: fold() short-circuits &&/||/?? and
|
|
383
387
|
// only evaluates the taken side; EVL requires both sides shape-valid.
|
|
384
388
|
return (
|
|
385
|
-
findSubsetViolation(node.left, intrinsics
|
|
386
|
-
findSubsetViolation(node.right, intrinsics
|
|
389
|
+
findSubsetViolation(node.left, intrinsics) ??
|
|
390
|
+
findSubsetViolation(node.right, intrinsics)
|
|
387
391
|
);
|
|
388
392
|
}
|
|
389
393
|
|
|
390
394
|
if (ts.isConditionalExpression(node)) {
|
|
391
395
|
// Flow-insensitive — see module doc: fold() only folds the taken branch.
|
|
392
396
|
return (
|
|
393
|
-
findSubsetViolation(node.condition, intrinsics
|
|
394
|
-
findSubsetViolation(node.whenTrue, intrinsics
|
|
395
|
-
findSubsetViolation(node.whenFalse, intrinsics
|
|
397
|
+
findSubsetViolation(node.condition, intrinsics) ??
|
|
398
|
+
findSubsetViolation(node.whenTrue, intrinsics) ??
|
|
399
|
+
findSubsetViolation(node.whenFalse, intrinsics)
|
|
396
400
|
);
|
|
397
401
|
}
|
|
398
402
|
|
|
@@ -403,14 +407,14 @@ export function findSubsetViolation(
|
|
|
403
407
|
// argument is classified on its own terms and nothing is rejected merely
|
|
404
408
|
// for being in the "wrong" position.
|
|
405
409
|
for (const arg of node.arguments ?? []) {
|
|
406
|
-
const v = findSubsetViolation(arg, intrinsics
|
|
410
|
+
const v = findSubsetViolation(arg, intrinsics);
|
|
407
411
|
if (v) return v;
|
|
408
412
|
}
|
|
409
413
|
return undefined;
|
|
410
414
|
}
|
|
411
415
|
|
|
412
416
|
if (ts.isSpreadElement(node)) {
|
|
413
|
-
return findSubsetViolation(node.expression, intrinsics
|
|
417
|
+
return findSubsetViolation(node.expression, intrinsics);
|
|
414
418
|
}
|
|
415
419
|
|
|
416
420
|
if (ts.isCallExpression(node)) {
|
|
@@ -426,7 +430,7 @@ export function findSubsetViolation(
|
|
|
426
430
|
// ever be MORE permissive than `fold()`, never stricter.
|
|
427
431
|
if (ts.isIdentifier(node.expression) && isFoldableHelperName(node.expression.text)) {
|
|
428
432
|
for (const arg of node.arguments) {
|
|
429
|
-
const v = findSubsetViolation(arg, intrinsics
|
|
433
|
+
const v = findSubsetViolation(arg, intrinsics);
|
|
430
434
|
if (v) return v;
|
|
431
435
|
}
|
|
432
436
|
return undefined;
|
|
@@ -446,12 +450,46 @@ export function findSubsetViolation(
|
|
|
446
450
|
intrinsics.some((i) => i.name === (node.expression as ts.Identifier).text && intrinsicCallFolds(i))
|
|
447
451
|
) {
|
|
448
452
|
for (const arg of node.arguments) {
|
|
449
|
-
const v = findSubsetViolation(arg, intrinsics
|
|
453
|
+
const v = findSubsetViolation(arg, intrinsics);
|
|
450
454
|
if (v) return v;
|
|
451
455
|
}
|
|
452
456
|
return undefined;
|
|
453
457
|
}
|
|
454
458
|
|
|
459
|
+
// chant #1966 — the eager counterpart of the #1044 case above: a lexicon
|
|
460
|
+
// intrinsic registered with `foldsEagerly` instead of `foldsAsCall`
|
|
461
|
+
// ({@link intrinsicCallFoldsEagerly}, ../lexicon.ts). Same registry-gated
|
|
462
|
+
// shape, same reasoning.
|
|
463
|
+
if (
|
|
464
|
+
intrinsics &&
|
|
465
|
+
ts.isIdentifier(node.expression) &&
|
|
466
|
+
intrinsics.some((i) => i.name === (node.expression as ts.Identifier).text && intrinsicCallFoldsEagerly(i))
|
|
467
|
+
) {
|
|
468
|
+
for (const arg of node.arguments) {
|
|
469
|
+
const v = findSubsetViolation(arg, intrinsics);
|
|
470
|
+
if (v) return v;
|
|
471
|
+
}
|
|
472
|
+
return undefined;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// chant #1966 — a method call (`github.actor.toString()`, `[...].join(",")`,
|
|
476
|
+
// `matrix("os").toString()`): `fold()` now folds this shape unconditionally
|
|
477
|
+
// — the receiver must fold to a real value with the named method, which is
|
|
478
|
+
// resolution-dependent (module doc, point 1) and so out of reach for a
|
|
479
|
+
// syntax-only classifier, exactly the same asymmetry as `.step` above and
|
|
480
|
+
// a same-file `new` used as a value (#1169). Accepted here regardless of
|
|
481
|
+
// the intrinsics registry, unlike the two cases just above: nothing about
|
|
482
|
+
// whether a method call folds depends on a lexicon's registration.
|
|
483
|
+
if (ts.isPropertyAccessExpression(node.expression)) {
|
|
484
|
+
const v = findSubsetViolation(node.expression.expression, intrinsics);
|
|
485
|
+
if (v) return v;
|
|
486
|
+
for (const arg of node.arguments) {
|
|
487
|
+
const argViolation = findSubsetViolation(arg, intrinsics);
|
|
488
|
+
if (argViolation) return argViolation;
|
|
489
|
+
}
|
|
490
|
+
return undefined;
|
|
491
|
+
}
|
|
492
|
+
|
|
455
493
|
return violation(node, callExpressionMessage(node));
|
|
456
494
|
}
|
|
457
495
|
|
package/src/lexicon-schema.ts
CHANGED
|
@@ -21,6 +21,9 @@ export const IntrinsicDefSchema = z.object({
|
|
|
21
21
|
// registration written before #1044 means. Only an explicit `true` opts a
|
|
22
22
|
// call into folding. See IntrinsicDef.foldsAsCall in ../lexicon.ts.
|
|
23
23
|
foldsAsCall: z.boolean().optional(),
|
|
24
|
+
// chant #1966 — same default-off shape as foldsAsCall, for the EAGER
|
|
25
|
+
// call-form opt-in. See IntrinsicDef.foldsEagerly in ../lexicon.ts.
|
|
26
|
+
foldsEagerly: z.boolean().optional(),
|
|
24
27
|
});
|
|
25
28
|
|
|
26
29
|
// ---------------------------------------------------------------------------
|
package/src/lexicon.ts
CHANGED
|
@@ -226,6 +226,29 @@ export interface IntrinsicDef {
|
|
|
226
226
|
* run path would have called, from the module the source itself named.
|
|
227
227
|
*/
|
|
228
228
|
readonly foldsAsCall?: boolean;
|
|
229
|
+
/**
|
|
230
|
+
* chant #1966 — opt this intrinsic's PLAIN-CALL form into EAGER folding:
|
|
231
|
+
* unlike {@link foldsAsCall}, which defers to a `{__intrinsic}` envelope
|
|
232
|
+
* revived later, `fold()` (../fold/fold.ts) calls the real function
|
|
233
|
+
* immediately, with the folded arguments, and its real return value IS the
|
|
234
|
+
* folded value.
|
|
235
|
+
*
|
|
236
|
+
* Exists for a lexicon helper whose result is commonly embedded directly in
|
|
237
|
+
* a template literal (`` `${matrix("os")}` ``, github's
|
|
238
|
+
* `matrix`/`inputs`/…) — an envelope is still a plain `{__intrinsic, args}`
|
|
239
|
+
* object when the enclosing template folds, so `String()` coercion at fold
|
|
240
|
+
* time would stringify it as `"[object Object]"` instead of the real value.
|
|
241
|
+
* Eager evaluation produces the real, already-live result instead.
|
|
242
|
+
*
|
|
243
|
+
* Same admission bar as {@link foldsAsCall} (a pure function of its
|
|
244
|
+
* arguments — no I/O, no mutable state, no dependency on anything but its
|
|
245
|
+
* arguments) and mutually exclusive with both {@link isTag} and
|
|
246
|
+
* `foldsAsCall`: a plain call folds exactly one way.
|
|
247
|
+
* `../discovery/fold-import.ts`'s `resolveActiveLexiconExport` checks this
|
|
248
|
+
* to admit the function export into `externals` at all — a lexicon
|
|
249
|
+
* package's function export is excluded there otherwise.
|
|
250
|
+
*/
|
|
251
|
+
readonly foldsEagerly?: boolean;
|
|
229
252
|
}
|
|
230
253
|
|
|
231
254
|
/**
|
|
@@ -257,8 +280,8 @@ export interface IntrinsicDef {
|
|
|
257
280
|
* `dist/manifest.json`) that may predate either field. `undefined` there
|
|
258
281
|
* means what it always did — not a tag, not opted in.
|
|
259
282
|
*/
|
|
260
|
-
export function intrinsicFolds(def: { isTag?: boolean; foldsAsCall?: boolean }): boolean {
|
|
261
|
-
return intrinsicTagFolds(def) || intrinsicCallFolds(def);
|
|
283
|
+
export function intrinsicFolds(def: { isTag?: boolean; foldsAsCall?: boolean; foldsEagerly?: boolean }): boolean {
|
|
284
|
+
return intrinsicTagFolds(def) || intrinsicCallFolds(def) || intrinsicCallFoldsEagerly(def);
|
|
262
285
|
}
|
|
263
286
|
|
|
264
287
|
/** True when this intrinsic's TAGGED-TEMPLATE form folds (`Sub\`...\``) — see {@link intrinsicFolds}. */
|
|
@@ -280,6 +303,15 @@ export function intrinsicCallFolds(def: { isTag?: boolean; foldsAsCall?: boolean
|
|
|
280
303
|
return def.isTag !== true && def.foldsAsCall === true;
|
|
281
304
|
}
|
|
282
305
|
|
|
306
|
+
/**
|
|
307
|
+
* True when this intrinsic's PLAIN-CALL form folds EAGERLY (chant #1966) —
|
|
308
|
+
* i.e. the lexicon opted it in via {@link IntrinsicDef.foldsEagerly}.
|
|
309
|
+
* `isTag: true` disqualifies, same as {@link intrinsicCallFolds}.
|
|
310
|
+
*/
|
|
311
|
+
export function intrinsicCallFoldsEagerly(def: { isTag?: boolean; foldsEagerly?: boolean }): boolean {
|
|
312
|
+
return def.isTag !== true && def.foldsEagerly === true;
|
|
313
|
+
}
|
|
314
|
+
|
|
283
315
|
/**
|
|
284
316
|
* Options passed to a MigrationSource by `chant migrate`.
|
|
285
317
|
*/
|
|
@@ -406,6 +438,61 @@ export interface ComponentPipelineResult {
|
|
|
406
438
|
jobs: ComponentPipelineJob[];
|
|
407
439
|
}
|
|
408
440
|
|
|
441
|
+
/**
|
|
442
|
+
* Finding-mode a scheduled Op surfaces on drift — the vocabulary the
|
|
443
|
+
* temporal-lexicon composites (`WorkflowAuditOp`/`PipelineAuditOp`/
|
|
444
|
+
* `ReconcileOp`) already declare on the Op itself (#927). The mode is baked
|
|
445
|
+
* into the Op's own activity args at build time and is never re-passed on the
|
|
446
|
+
* generated CI invocation; here it decides only what token/permission wiring
|
|
447
|
+
* the generated job needs to act on a finding — elevated write access for
|
|
448
|
+
* `issue`/`pull-request`/`merge-request`, none for `report`.
|
|
449
|
+
*/
|
|
450
|
+
export type OpFindingMode = "report" | "issue" | "pull-request" | "merge-request";
|
|
451
|
+
|
|
452
|
+
/** One scheduled Op to generate CI for — the cron-triggered counterpart to a component (generate mode). */
|
|
453
|
+
export interface ScheduledOpSpec {
|
|
454
|
+
/** Op name (`*.op.ts`'s `Op({ name })`) — what `chant run <name>` targets. */
|
|
455
|
+
name: string;
|
|
456
|
+
/** Cron expression driving the CI-native trigger — the CI-only alternative to a Temporal `TemporalSchedule`. */
|
|
457
|
+
schedule: string;
|
|
458
|
+
/** This Op's finding-mode, for permission/token wiring only (see {@link OpFindingMode}). Default: "report" — no elevated permissions. */
|
|
459
|
+
findingMode?: OpFindingMode;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/** One CI job generated for a scheduled Op. */
|
|
463
|
+
export interface OpPipelineJob {
|
|
464
|
+
/** CI job name (safe as a YAML key). */
|
|
465
|
+
jobName: string;
|
|
466
|
+
/** The Op this job runs. */
|
|
467
|
+
op: string;
|
|
468
|
+
/** Cron expression this job's workflow is scheduled on. */
|
|
469
|
+
schedule: string;
|
|
470
|
+
/** The finding-mode wired for this job. */
|
|
471
|
+
findingMode: OpFindingMode;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* One generated CI file for a scheduled Op. Unlike a component pipeline —
|
|
476
|
+
* one combined document for the whole graph — a cron trigger is
|
|
477
|
+
* workflow-scoped in every CI provider chant targets (GitHub Actions'
|
|
478
|
+
* `on.schedule`, a GitLab pipeline schedule bound to one `.gitlab-ci.yml`), so
|
|
479
|
+
* each scheduled Op gets its own file.
|
|
480
|
+
*/
|
|
481
|
+
export interface OpPipelineFile {
|
|
482
|
+
/** Suggested file name (e.g. `<op-name>.yml`), relative to the provider's workflow directory. */
|
|
483
|
+
name: string;
|
|
484
|
+
/** The synthesized CI YAML for this Op. */
|
|
485
|
+
yaml: string;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/** The synthesized CI pipeline for a set of scheduled Ops (generate mode's Op counterpart, #927). */
|
|
489
|
+
export interface OpPipelineResult {
|
|
490
|
+
/** One file per scheduled Op. */
|
|
491
|
+
files: OpPipelineFile[];
|
|
492
|
+
/** Every generated job, in emit order — one per Op. */
|
|
493
|
+
jobs: OpPipelineJob[];
|
|
494
|
+
}
|
|
495
|
+
|
|
409
496
|
/**
|
|
410
497
|
* Live status of a single deploy unit (a CloudFormation stack, a K8s release, …)
|
|
411
498
|
* addressed by its deployed name — the per-component presence signal
|
|
@@ -640,6 +727,20 @@ export interface LexiconPlugin {
|
|
|
640
727
|
options?: ComponentPipelineOptions,
|
|
641
728
|
): ComponentPipelineResult;
|
|
642
729
|
|
|
730
|
+
/**
|
|
731
|
+
* Generate CI for a set of scheduled, stateless Ops — the cron-triggered
|
|
732
|
+
* sibling of {@link generateComponentPipeline} (#927). Each
|
|
733
|
+
* `ScheduledOpSpec` becomes its own CI file (cron triggers are
|
|
734
|
+
* workflow-scoped in every CI provider chant targets), invoking `chant run
|
|
735
|
+
* <name>` on the local executor — the same one-shot invocation `chant run
|
|
736
|
+
* <op>` runs by hand. Only CI-provider lexicons (gitlab, github, forgejo)
|
|
737
|
+
* implement this; omit for lexicons that are not CI providers.
|
|
738
|
+
*/
|
|
739
|
+
generateOpPipeline?(
|
|
740
|
+
ops: ScheduledOpSpec[],
|
|
741
|
+
options?: ComponentPipelineOptions,
|
|
742
|
+
): OpPipelineResult;
|
|
743
|
+
|
|
643
744
|
/**
|
|
644
745
|
* Render this lexicon's config-declared build roots into entities (#1548
|
|
645
746
|
* piece 3) — the seam for a build root that is NOT typed chant source. The
|