@elaraai/east-claude-plugin 0.0.0-stage → 1.0.89

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.
@@ -0,0 +1,3737 @@
1
+ // ../east-diagnostics/dist/src/east-type.js
2
+ function isEastExprType(type) {
3
+ const seen = /* @__PURE__ */ new Set();
4
+ const stack = [type];
5
+ while (stack.length > 0) {
6
+ const current = stack.pop();
7
+ if (current === void 0 || seen.has(current))
8
+ continue;
9
+ seen.add(current);
10
+ const name = current.aliasSymbol?.name ?? current.symbol?.name;
11
+ if (name !== void 0 && (name === "Expr" || name.endsWith("Expr")))
12
+ return true;
13
+ if (current.isUnionOrIntersection())
14
+ stack.push(...current.types);
15
+ const bases = current.getBaseTypes?.();
16
+ if (bases !== void 0)
17
+ stack.push(...bases);
18
+ }
19
+ return false;
20
+ }
21
+ function isBlockBuilderType(type) {
22
+ const name = type.aliasSymbol?.name ?? type.symbol?.name;
23
+ return name === "BlockBuilder";
24
+ }
25
+ function someTypeName(type, match) {
26
+ const seen = /* @__PURE__ */ new Set();
27
+ const stack = [type];
28
+ while (stack.length > 0) {
29
+ const current = stack.pop();
30
+ if (current === void 0 || seen.has(current))
31
+ continue;
32
+ seen.add(current);
33
+ const name = current.aliasSymbol?.name ?? current.symbol?.name;
34
+ if (name !== void 0 && match(name))
35
+ return true;
36
+ if (current.isUnionOrIntersection())
37
+ stack.push(...current.types);
38
+ }
39
+ return false;
40
+ }
41
+ function isEastPlatformDefinitionType(type) {
42
+ return someTypeName(type, (name) => name.endsWith("PlatformDefinition"));
43
+ }
44
+ var E3_DEFINITION_NAMES = /* @__PURE__ */ new Set([
45
+ "TaskDef",
46
+ "DatasetDef",
47
+ "DataTreeDef",
48
+ "FunctionDef",
49
+ "MutationDef",
50
+ "RecordDef",
51
+ "PackageDef"
52
+ ]);
53
+ function isEastDefinitionType(type) {
54
+ return someTypeName(type, (name) => E3_DEFINITION_NAMES.has(name) || name.endsWith("PlatformDefinition"));
55
+ }
56
+
57
+ // ../east-diagnostics/dist/src/block-builder.js
58
+ function matchBlockBuilderCall(node, ctx) {
59
+ const t = ctx.ts;
60
+ if (!t.isCallExpression(node))
61
+ return void 0;
62
+ const callee = node.expression;
63
+ if (!t.isPropertyAccessExpression(callee))
64
+ return void 0;
65
+ const method = callee.name.text;
66
+ if (method !== "let" && method !== "const")
67
+ return void 0;
68
+ if (!isBlockBuilderType(ctx.checker.getTypeAtLocation(callee.expression)))
69
+ return void 0;
70
+ return { call: node, method, args: node.arguments };
71
+ }
72
+
73
+ // ../east-diagnostics/dist/src/rules/no-redundant-east-cast.js
74
+ var NAME = "no-redundant-east-cast";
75
+ var CODE = 990001;
76
+ function isEastValueCall(expr, t) {
77
+ if (!t.isCallExpression(expr))
78
+ return false;
79
+ const callee = expr.expression;
80
+ return t.isPropertyAccessExpression(callee) && t.isIdentifier(callee.expression) && callee.expression.text === "East" && callee.name.text === "value";
81
+ }
82
+ function report(ctx, target, messageText, fixDescription, newText) {
83
+ const sf = ctx.sourceFile;
84
+ const start = target.getStart(sf);
85
+ const length = target.getEnd() - start;
86
+ ctx.report({
87
+ ruleName: NAME,
88
+ code: CODE,
89
+ start,
90
+ length,
91
+ messageText,
92
+ category: "warning",
93
+ fix: { description: fixDescription, changes: [{ start, length, newText }] }
94
+ });
95
+ }
96
+ var noRedundantEastCast = {
97
+ name: NAME,
98
+ code: CODE,
99
+ description: "Disallow TypeScript type info on the value of $.let/$.const that the East type argument already governs (a cast, `new Map<K,V>()` generics, or an `East.value(x,T)` wrapper).",
100
+ check(node, ctx) {
101
+ const match = matchBlockBuilderCall(node, ctx);
102
+ if (match === void 0)
103
+ return;
104
+ const t = ctx.ts;
105
+ const value = match.args[0];
106
+ if (value === void 0)
107
+ return;
108
+ const sf = ctx.sourceFile;
109
+ if (isEastValueCall(value, t)) {
110
+ const inner = value.arguments[0];
111
+ if (inner === void 0)
112
+ return;
113
+ const typeArg = match.args[1] ?? value.arguments[1];
114
+ const receiverText = match.call.expression.getText(sf);
115
+ const newText = `${receiverText}(${inner.getText(sf)}${typeArg !== void 0 ? `, ${typeArg.getText(sf)}` : ""})`;
116
+ report(ctx, match.call, `Redundant \`East.value(...)\` inside \`$.${match.method}\`: pass the value (and its East type) to \`$.${match.method}\` directly.`, "Lift the value and type out of East.value(...)", newText);
117
+ return;
118
+ }
119
+ if (match.args.length < 2)
120
+ return;
121
+ let cast;
122
+ if (t.isAsExpression(value))
123
+ cast = value.expression;
124
+ else if (t.isTypeAssertionExpression(value))
125
+ cast = value.expression;
126
+ if (cast !== void 0) {
127
+ report(ctx, value, `Redundant cast: \`$.${match.method}\` infers the value type from the East type argument; drop the \`as \u2026\` on the value.`, "Remove redundant cast", cast.getText(sf));
128
+ return;
129
+ }
130
+ if (t.isNewExpression(value) && value.typeArguments !== void 0 && value.typeArguments.length > 0) {
131
+ const ctorArgs = (value.arguments ?? []).map((a) => a.getText(sf)).join(", ");
132
+ report(ctx, value, `Redundant type arguments: \`$.${match.method}\` infers the value type from the East type argument; drop the \`<\u2026>\` on \`new ${value.expression.getText(sf)}\`.`, "Remove redundant constructor type arguments", `new ${value.expression.getText(sf)}(${ctorArgs})`);
133
+ }
134
+ }
135
+ };
136
+
137
+ // ../east-diagnostics/dist/src/rules/prefer-explicit-east-type.js
138
+ var NAME2 = "prefer-explicit-east-type";
139
+ var CODE2 = 990002;
140
+ function isEmptyNewMapOrSet(node, t) {
141
+ if (!t.isNewExpression(node) || !t.isIdentifier(node.expression))
142
+ return false;
143
+ const ctor = node.expression.text;
144
+ if (ctor !== "Map" && ctor !== "Set")
145
+ return false;
146
+ return node.arguments === void 0 || node.arguments.length === 0;
147
+ }
148
+ function isRawValueLiteral(node, t) {
149
+ return t.isNumericLiteral(node) || t.isBigIntLiteral(node) || t.isStringLiteralLike(node) || node.kind === t.SyntaxKind.TrueKeyword || node.kind === t.SyntaxKind.FalseKeyword || node.kind === t.SyntaxKind.NullKeyword || t.isArrayLiteralExpression(node) || t.isObjectLiteralExpression(node) || t.isNewExpression(node);
150
+ }
151
+ var preferExplicitEastType = {
152
+ name: NAME2,
153
+ code: CODE2,
154
+ description: "Encourage passing the East type as the second argument to $.let/$.const for raw JS values whose East type is under-determined.",
155
+ check(node, ctx) {
156
+ const match = matchBlockBuilderCall(node, ctx);
157
+ if (match === void 0 || match.args.length !== 1)
158
+ return;
159
+ const t = ctx.ts;
160
+ const value = match.args[0];
161
+ if (value === void 0)
162
+ return;
163
+ const underDetermined = t.isArrayLiteralExpression(value) && value.elements.length === 0 || t.isObjectLiteralExpression(value) && value.properties.length === 0 || isEmptyNewMapOrSet(value, t);
164
+ const mode = ctx.options.preferExplicitEastType?.mode ?? "under-determined";
165
+ const flag = underDetermined || mode === "all-raw-values" && isRawValueLiteral(value, t);
166
+ if (!flag)
167
+ return;
168
+ const sf = ctx.sourceFile;
169
+ const start = value.getStart(sf);
170
+ ctx.report({
171
+ ruleName: NAME2,
172
+ code: CODE2,
173
+ start,
174
+ length: value.getEnd() - start,
175
+ messageText: `Provide the East type as the second argument to \`$.${match.method}\` \u2014 e.g. \`$.${match.method}([], ArrayType(FloatType))\` \u2014 to pin the value type; it is under-determined from the value alone.`,
176
+ category: "suggestion"
177
+ });
178
+ }
179
+ };
180
+
181
+ // ../east-diagnostics/dist/src/east-source.js
182
+ import { existsSync } from "node:fs";
183
+ import { dirname, join, resolve } from "node:path";
184
+ function importDeclarationOf(sym, t) {
185
+ for (const d of sym?.declarations ?? []) {
186
+ let n = d;
187
+ if (t.isImportSpecifier(n))
188
+ n = n.parent.parent.parent;
189
+ else if (t.isNamespaceImport(n))
190
+ n = n.parent.parent;
191
+ else if (t.isImportClause(n))
192
+ n = n.parent;
193
+ else
194
+ continue;
195
+ if (t.isImportDeclaration(n))
196
+ return n;
197
+ }
198
+ return void 0;
199
+ }
200
+ function resolvesToEastImport(id, checker, t) {
201
+ const imp = importDeclarationOf(checker.getSymbolAtLocation(id), t);
202
+ return imp !== void 0 && t.isStringLiteral(imp.moduleSpecifier) && imp.moduleSpecifier.text.startsWith("@elaraai/");
203
+ }
204
+ function importedNameOf(id, checker, t) {
205
+ for (const d of checker.getSymbolAtLocation(id)?.declarations ?? []) {
206
+ if (t.isImportSpecifier(d))
207
+ return (d.propertyName ?? d.name).text;
208
+ }
209
+ return void 0;
210
+ }
211
+ var importsCache = /* @__PURE__ */ new WeakMap();
212
+ function importsEastPackage(sf, t) {
213
+ const cached = importsCache.get(sf);
214
+ if (cached !== void 0)
215
+ return cached;
216
+ let found = false;
217
+ for (const stmt of sf.statements) {
218
+ if (!t.isImportDeclaration(stmt) && !t.isExportDeclaration(stmt))
219
+ continue;
220
+ const spec = stmt.moduleSpecifier;
221
+ if (spec !== void 0 && t.isStringLiteral(spec) && spec.text.startsWith("@elaraai/")) {
222
+ found = true;
223
+ break;
224
+ }
225
+ }
226
+ importsCache.set(sf, found);
227
+ return found;
228
+ }
229
+ function unresolvedEastImport(sf, checker, t) {
230
+ for (const stmt of sf.statements) {
231
+ if (!t.isImportDeclaration(stmt) && !t.isExportDeclaration(stmt))
232
+ continue;
233
+ const spec = stmt.moduleSpecifier;
234
+ if (spec === void 0 || !t.isStringLiteral(spec) || spec.text !== "@elaraai/east")
235
+ continue;
236
+ if (checker.getSymbolAtLocation(spec) === void 0)
237
+ return true;
238
+ }
239
+ return false;
240
+ }
241
+ var declaresCache = /* @__PURE__ */ new WeakMap();
242
+ var E3_DECLARATION_MEMBERS = /* @__PURE__ */ new Set([
243
+ "input",
244
+ "task",
245
+ "customTask",
246
+ "function",
247
+ "record",
248
+ "mutation",
249
+ "package",
250
+ "export"
251
+ ]);
252
+ function declaresEastProgram(sf, checker, t) {
253
+ const cached = declaresCache.get(sf);
254
+ if (cached !== void 0)
255
+ return cached;
256
+ let found = false;
257
+ const visit = (n) => {
258
+ if (found)
259
+ return;
260
+ if (t.isCallExpression(n)) {
261
+ const callee = n.expression;
262
+ if (t.isPropertyAccessExpression(callee) && t.isIdentifier(callee.expression)) {
263
+ const root = callee.expression;
264
+ if (root.text === "East" && resolvesToEastImport(root, checker, t)) {
265
+ found = true;
266
+ return;
267
+ }
268
+ if (E3_DECLARATION_MEMBERS.has(callee.name.text)) {
269
+ const imp = importDeclarationOf(checker.getSymbolAtLocation(root), t);
270
+ if (imp !== void 0 && t.isStringLiteral(imp.moduleSpecifier) && imp.moduleSpecifier.text === "@elaraai/e3") {
271
+ found = true;
272
+ return;
273
+ }
274
+ }
275
+ } else if (t.isIdentifier(callee) && callee.text === "ui" && resolvesToEastImport(callee, checker, t)) {
276
+ found = true;
277
+ return;
278
+ }
279
+ }
280
+ t.forEachChild(n, visit);
281
+ };
282
+ visit(sf);
283
+ declaresCache.set(sf, found);
284
+ return found;
285
+ }
286
+ var pkgDirCache = /* @__PURE__ */ new Map();
287
+ function packageDirOf(p) {
288
+ const start = dirname(resolve(p));
289
+ if (pkgDirCache.has(start))
290
+ return pkgDirCache.get(start);
291
+ let dir = start;
292
+ let result;
293
+ for (; ; ) {
294
+ if (existsSync(join(dir, "package.json"))) {
295
+ result = dir;
296
+ break;
297
+ }
298
+ const parent = dirname(dir);
299
+ if (parent === dir)
300
+ break;
301
+ dir = parent;
302
+ }
303
+ pkgDirCache.set(start, result);
304
+ return result;
305
+ }
306
+ function resolvesWithinOwnPackage(sourceFileName, specifierText) {
307
+ try {
308
+ const own = packageDirOf(sourceFileName);
309
+ if (own === void 0)
310
+ return false;
311
+ const targetAbs = resolve(dirname(sourceFileName), specifierText);
312
+ return packageDirOf(targetAbs) === own;
313
+ } catch {
314
+ return true;
315
+ }
316
+ }
317
+
318
+ // ../east-diagnostics/dist/src/rules/prefer-some-none.js
319
+ var NAME3 = "prefer-some-none";
320
+ var CODE3 = 990003;
321
+ function membersOf(types) {
322
+ return types.flatMap((type) => type.isUnion() ? type.types : [type]);
323
+ }
324
+ function literalsOf(type) {
325
+ return membersOf([type]).flatMap((m) => m.isStringLiteral() ? [m.value] : []);
326
+ }
327
+ function variantMembers(expected, at, ctx) {
328
+ const out = [];
329
+ for (const member of membersOf(expected)) {
330
+ if (isEastExprType(member))
331
+ continue;
332
+ if (ctx.checker.getPropertyOfType(member, "value") === void 0)
333
+ continue;
334
+ const tag = ctx.checker.getPropertyOfType(member, "type");
335
+ if (tag === void 0)
336
+ continue;
337
+ out.push({ member, tags: literalsOf(ctx.checker.getTypeOfSymbolAtLocation(tag, at)) });
338
+ }
339
+ return out;
340
+ }
341
+ function propertyTypes(types, name, at, ctx) {
342
+ return membersOf(types).flatMap((m) => {
343
+ const prop = ctx.checker.getPropertyOfType(m, name);
344
+ return prop === void 0 ? [] : [ctx.checker.getTypeOfSymbolAtLocation(prop, at)];
345
+ });
346
+ }
347
+ function uninformative(type, ctx) {
348
+ const t = ctx.ts;
349
+ return (type.flags & (t.TypeFlags.Any | t.TypeFlags.Unknown | t.TypeFlags.TypeParameter)) !== 0;
350
+ }
351
+ function expectedTypes(e, ctx, depth = 0) {
352
+ const t = ctx.ts;
353
+ const parent = e.parent;
354
+ if (depth < 8 && t.isPropertyAssignment(parent) && parent.initializer === e && (t.isIdentifier(parent.name) || t.isStringLiteral(parent.name))) {
355
+ const literal = expectedTypes(parent.parent, ctx, depth + 1);
356
+ if (literal.length > 0)
357
+ return propertyTypes(literal, parent.name.text, e, ctx);
358
+ }
359
+ if (depth < 8 && t.isCallExpression(parent) && parent.arguments[1] === e && t.isIdentifier(parent.expression) && parent.expression.text === "variant" && resolvesToEastImport(parent.expression, ctx.checker, t)) {
360
+ const tag = parent.arguments[0];
361
+ if (tag === void 0 || !t.isStringLiteralLike(tag))
362
+ return [];
363
+ const matches = variantMembers(expectedTypes(parent, ctx, depth + 1), e, ctx).filter((m) => m.tags.includes(tag.text));
364
+ return propertyTypes(matches.map((m) => m.member), "value", e, ctx);
365
+ }
366
+ const direct = ctx.checker.getContextualType(e);
367
+ return direct !== void 0 && !uninformative(direct, ctx) ? [direct] : [];
368
+ }
369
+ var preferSomeNone = {
370
+ name: NAME3,
371
+ code: CODE3,
372
+ description: 'Prefer some()/none over variant("some", \u2026)/variant("none", null) for an Option.',
373
+ check(node, ctx) {
374
+ const t = ctx.ts;
375
+ if (!t.isCallExpression(node))
376
+ return;
377
+ const callee = node.expression;
378
+ if (!t.isIdentifier(callee) || callee.text !== "variant")
379
+ return;
380
+ if (!resolvesToEastImport(callee, ctx.checker, t))
381
+ return;
382
+ const first = node.arguments[0];
383
+ if (first === void 0 || !t.isStringLiteralLike(first))
384
+ return;
385
+ const tag = first.text;
386
+ if (tag !== "some" && tag !== "none")
387
+ return;
388
+ if (variantMembers(expectedTypes(node, ctx), node, ctx).some((m) => m.tags.some((other) => other !== "some" && other !== "none")))
389
+ return;
390
+ const sf = ctx.sourceFile;
391
+ const start = node.getStart(sf);
392
+ ctx.report({
393
+ ruleName: NAME3,
394
+ code: CODE3,
395
+ start,
396
+ length: node.getEnd() - start,
397
+ messageText: (tag === "some" ? 'Use `some(value)` instead of `variant("some", value)`.' : 'Use `none` instead of `variant("none", null)`.') + " If this is the case of a variant that is not an Option, type the value it builds (`ValueTypeOf<typeof T>`) so the case can be told apart.",
398
+ category: "warning"
399
+ });
400
+ }
401
+ };
402
+
403
+ // ../east-diagnostics/dist/src/rules/no-handrolled-variant.js
404
+ var NAME4 = "no-handrolled-variant";
405
+ var CODE4 = 990004;
406
+ var VARIANT_TYPE_NAMES = /* @__PURE__ */ new Set(["variant", "some", "none", "option", "VariantExpr"]);
407
+ function expectsVariant(type) {
408
+ const stack = [type];
409
+ while (stack.length > 0) {
410
+ const current = stack.pop();
411
+ if (current === void 0)
412
+ continue;
413
+ const name = current.aliasSymbol?.name ?? current.symbol?.name;
414
+ if (name !== void 0 && VARIANT_TYPE_NAMES.has(name))
415
+ return true;
416
+ if (current.isUnionOrIntersection())
417
+ stack.push(...current.types);
418
+ }
419
+ return false;
420
+ }
421
+ function propertyNamed(node, name, t) {
422
+ for (const p of node.properties) {
423
+ if ((t.isPropertyAssignment(p) || t.isShorthandPropertyAssignment(p)) && (t.isIdentifier(p.name) || t.isStringLiteral(p.name)) && p.name.text === name) {
424
+ return p;
425
+ }
426
+ }
427
+ return void 0;
428
+ }
429
+ function spelledAsVariant(node, ctx) {
430
+ const t = ctx.ts;
431
+ if (node.properties.length !== 2)
432
+ return false;
433
+ const tag = propertyNamed(node, "type", t);
434
+ if (tag === void 0 || propertyNamed(node, "value", t) === void 0)
435
+ return false;
436
+ const tagType = ctx.checker.getTypeAtLocation(t.isPropertyAssignment(tag) ? tag.initializer : tag.name);
437
+ const members = tagType.isUnion() ? tagType.types : [tagType];
438
+ return members.every((m) => (m.flags & t.TypeFlags.StringLike) !== 0);
439
+ }
440
+ function publishedShape(type, t) {
441
+ const members = (type.isUnion() ? type.types : [type]).filter((m) => (m.flags & (t.TypeFlags.Null | t.TypeFlags.Undefined)) === 0);
442
+ return members.length > 0 && members.every((m) => {
443
+ if ((m.flags & t.TypeFlags.Object) === 0)
444
+ return false;
445
+ const declarations = (m.aliasSymbol ?? m.symbol)?.declarations ?? [];
446
+ return declarations.length > 0 && declarations.every((d) => d.getSourceFile().isDeclarationFile);
447
+ });
448
+ }
449
+ var noHandrolledVariant = {
450
+ name: NAME4,
451
+ code: CODE4,
452
+ description: "Disallow a variant built as a plain `{ type, value }` object literal \u2014 where a variant is expected, or anywhere in East source; use variant()/some()/none.",
453
+ check(node, ctx) {
454
+ const t = ctx.ts;
455
+ if (!t.isObjectLiteralExpression(node))
456
+ return;
457
+ if (propertyNamed(node, "type", t) === void 0)
458
+ return;
459
+ const contextualType = ctx.checker.getContextualType(node);
460
+ const inVariantSlot = contextualType !== void 0 && expectsVariant(contextualType);
461
+ const byHand = !inVariantSlot && importsEastPackage(ctx.sourceFile, t) && spelledAsVariant(node, ctx) && (contextualType === void 0 || !publishedShape(contextualType, t));
462
+ if (!inVariantSlot && !byHand)
463
+ return;
464
+ const sf = ctx.sourceFile;
465
+ const start = node.getStart(sf);
466
+ ctx.report({
467
+ ruleName: NAME4,
468
+ code: CODE4,
469
+ start,
470
+ length: node.getEnd() - start,
471
+ messageText: 'Hand-rolled variant: build with `variant("Tag", value)`, `some(value)`, or `none` from @elaraai/east \u2014 never a plain `{ type, value }` object literal, which lacks the symbol East\'s variants carry.',
472
+ category: "warning"
473
+ });
474
+ }
475
+ };
476
+
477
+ // ../east-diagnostics/dist/src/rules/no-east-namespaced-type.js
478
+ var NAME5 = "no-east-namespaced-type";
479
+ var CODE5 = 990005;
480
+ var noEastNamespacedType = {
481
+ name: NAME5,
482
+ code: CODE5,
483
+ description: "Disallow East.<X>Type member access; import the type directly from @elaraai/east.",
484
+ check(node, ctx) {
485
+ const t = ctx.ts;
486
+ if (!t.isPropertyAccessExpression(node))
487
+ return;
488
+ if (!t.isIdentifier(node.expression) || node.expression.text !== "East")
489
+ return;
490
+ const name = node.name.text;
491
+ if (!name.endsWith("Type"))
492
+ return;
493
+ const sf = ctx.sourceFile;
494
+ const start = node.getStart(sf);
495
+ ctx.report({
496
+ ruleName: NAME5,
497
+ code: CODE5,
498
+ start,
499
+ length: node.getEnd() - start,
500
+ messageText: `\`East.${name}\` is not a member of the East namespace \u2014 import \`${name}\` directly from @elaraai/east.`,
501
+ category: "warning"
502
+ });
503
+ }
504
+ };
505
+
506
+ // ../east-diagnostics/dist/src/block-scope.js
507
+ function isEastFunctionCall(node, t) {
508
+ if (!t.isCallExpression(node))
509
+ return false;
510
+ const callee = node.expression;
511
+ return t.isPropertyAccessExpression(callee) && t.isIdentifier(callee.expression) && callee.expression.text === "East" && (callee.name.text === "function" || callee.name.text === "asyncFunction");
512
+ }
513
+ function isBlockBuilderCallback(node, ctx) {
514
+ const t = ctx.ts;
515
+ if (!t.isArrowFunction(node) && !t.isFunctionExpression(node))
516
+ return false;
517
+ const first = node.parameters[0];
518
+ if (first === void 0)
519
+ return false;
520
+ return isBlockBuilderType(ctx.checker.getTypeAtLocation(first.name));
521
+ }
522
+ function enclosingBlockScope(node, ctx) {
523
+ const t = ctx.ts;
524
+ let outermost;
525
+ let current = node.parent;
526
+ while (current !== void 0) {
527
+ if (isEastFunctionCall(current, t) || isBlockBuilderCallback(current, ctx)) {
528
+ outermost = current;
529
+ }
530
+ current = current.parent;
531
+ }
532
+ return outermost;
533
+ }
534
+ function insideBlockScope(node, ctx) {
535
+ return enclosingBlockScope(node, ctx) !== void 0;
536
+ }
537
+ function insideReactive(node, t) {
538
+ let cur = node.parent;
539
+ while (cur !== void 0) {
540
+ if (t.isJsxElement(cur) && cur.openingElement.tagName.getText().endsWith("Reactive"))
541
+ return true;
542
+ if (t.isJsxSelfClosingElement(cur) && cur.tagName.getText().endsWith("Reactive"))
543
+ return true;
544
+ if (t.isCallExpression(cur)) {
545
+ const callee = cur.expression;
546
+ if (t.isPropertyAccessExpression(callee) && t.isIdentifier(callee.expression) && callee.expression.text === "Reactive") {
547
+ return true;
548
+ }
549
+ }
550
+ cur = cur.parent;
551
+ }
552
+ return false;
553
+ }
554
+
555
+ // ../east-diagnostics/dist/src/rules/prefer-let-const-over-east-value.js
556
+ var NAME6 = "prefer-let-const-over-east-value";
557
+ var CODE6 = 990006;
558
+ function typeIsLoadBearing(value, t) {
559
+ let found = false;
560
+ const emptyArray = (n) => n !== void 0 && t.isArrayLiteralExpression(n) && n.elements.length === 0;
561
+ const visit = (n) => {
562
+ if (found)
563
+ return;
564
+ if (t.isIdentifier(n) && n.text === "none")
565
+ found = true;
566
+ else if (emptyArray(n))
567
+ found = true;
568
+ else if (t.isNewExpression(n) && t.isIdentifier(n.expression) && (n.expression.text === "Map" || n.expression.text === "Set") && (n.arguments === void 0 || n.arguments.length === 0 || emptyArray(n.arguments[0])))
569
+ found = true;
570
+ else if (t.isCallExpression(n) && t.isIdentifier(n.expression) && (n.expression.text === "variant" || n.expression.text === "some"))
571
+ found = true;
572
+ else
573
+ t.forEachChild(n, visit);
574
+ };
575
+ visit(value);
576
+ return found;
577
+ }
578
+ var preferLetConstOverEastValue = {
579
+ name: NAME6,
580
+ code: CODE6,
581
+ description: "Inside East.function blocks, bind with $.let/$.const (and return that) rather than East.value().",
582
+ check(node, ctx) {
583
+ const t = ctx.ts;
584
+ if (!t.isCallExpression(node))
585
+ return;
586
+ const callee = node.expression;
587
+ if (!t.isPropertyAccessExpression(callee))
588
+ return;
589
+ if (!t.isIdentifier(callee.expression) || callee.expression.text !== "East")
590
+ return;
591
+ if (callee.name.text !== "value")
592
+ return;
593
+ const parent = node.parent;
594
+ const asDeclaration = parent !== void 0 && t.isVariableDeclaration(parent) && parent.initializer === node;
595
+ const asReturn = parent !== void 0 && t.isReturnStatement(parent) && parent.expression === node;
596
+ const asCallbackBody = parent !== void 0 && t.isArrowFunction(parent) && parent.body === node && parent.parent !== void 0 && t.isCallExpression(parent.parent) && parent.parent.arguments.some((arg) => arg === parent);
597
+ if (!asDeclaration && !asReturn && !asCallbackBody)
598
+ return;
599
+ if (!insideBlockScope(node, ctx))
600
+ return;
601
+ const inner = node.arguments[0];
602
+ if ((asReturn || asCallbackBody) && node.arguments.length >= 2 && inner !== void 0 && typeIsLoadBearing(inner, t))
603
+ return;
604
+ const sf = ctx.sourceFile;
605
+ const start = node.getStart(sf);
606
+ ctx.report({
607
+ ruleName: NAME6,
608
+ code: CODE6,
609
+ start,
610
+ length: node.getEnd() - start,
611
+ messageText: asCallbackBody ? "Don't wrap a callback's return in `East.value(...)` \u2014 the callback's expected element type already supplies the East type. Return the plain value." : asReturn ? "Don't `return East.value(...)` \u2014 it erases the East type. Bind the value with `$.let`/`$.const` (passing the East type) and return that variable." : "Inside an East block, declare with `$.const(value, Type)` / `$.let(value, Type)` instead of `East.value(...)`, which erases the East type at the call site.",
612
+ category: "suggestion",
613
+ ...asCallbackBody && inner !== void 0 ? {
614
+ fix: {
615
+ description: "Return the plain value (drop the redundant East.value wrapper)",
616
+ changes: [
617
+ { start, length: node.getEnd() - start, newText: inner.getText(sf) }
618
+ ]
619
+ }
620
+ } : {}
621
+ });
622
+ }
623
+ };
624
+
625
+ // ../east-diagnostics/dist/src/rules/no-relative-src-import.js
626
+ var NAME7 = "no-relative-src-import";
627
+ var CODE7 = 990007;
628
+ var DEEP_PACKAGE_SRC = /^@elaraai\/[^/]+\/src(\/|$)/;
629
+ var RELATIVE_SRC = /\/src(\/|$)/;
630
+ var noRelativeSrcImport = {
631
+ name: NAME7,
632
+ code: CODE7,
633
+ description: "Import East packages by published name, not via ../src or a deep /src path.",
634
+ check(node, ctx) {
635
+ const t = ctx.ts;
636
+ let specifier;
637
+ if (t.isImportDeclaration(node))
638
+ specifier = node.moduleSpecifier;
639
+ else if (t.isExportDeclaration(node))
640
+ specifier = node.moduleSpecifier;
641
+ else
642
+ return;
643
+ if (specifier === void 0 || !t.isStringLiteral(specifier))
644
+ return;
645
+ const text = specifier.text;
646
+ const relativeIntoSrc = text.startsWith(".") && RELATIVE_SRC.test(text);
647
+ const deepPackageSrc = DEEP_PACKAGE_SRC.test(text);
648
+ if (!relativeIntoSrc && !deepPackageSrc)
649
+ return;
650
+ if (relativeIntoSrc && !deepPackageSrc && resolvesWithinOwnPackage(ctx.sourceFile.fileName, text))
651
+ return;
652
+ const sf = ctx.sourceFile;
653
+ const start = specifier.getStart(sf);
654
+ ctx.report({
655
+ ruleName: NAME7,
656
+ code: CODE7,
657
+ start,
658
+ length: specifier.getEnd() - start,
659
+ messageText: "Import East packages by their published name (e.g. `@elaraai/east`), not a relative `../src/...` path or a deep `/src` import.",
660
+ category: "warning"
661
+ });
662
+ }
663
+ };
664
+
665
+ // ../east-diagnostics/dist/src/rules/no-let-const-in-expression.js
666
+ var NAME8 = "no-let-const-in-expression";
667
+ var CODE8 = 990008;
668
+ var noLetConstInExpression = {
669
+ name: NAME8,
670
+ code: CODE8,
671
+ description: "Require $.let/$.const to be bound to a const; disallow using the result inline in an expression.",
672
+ check(node, ctx) {
673
+ const match = matchBlockBuilderCall(node, ctx);
674
+ if (match === void 0)
675
+ return;
676
+ const t = ctx.ts;
677
+ const call = match.call;
678
+ let current = call;
679
+ let parent = current.parent;
680
+ while (parent !== void 0 && t.isParenthesizedExpression(parent)) {
681
+ current = parent;
682
+ parent = parent.parent;
683
+ }
684
+ if (parent === void 0)
685
+ return;
686
+ const allowed = t.isVariableDeclaration(parent) && parent.initializer === current || t.isExpressionStatement(parent) && parent.expression === current || t.isReturnStatement(parent) && parent.expression === current || t.isArrowFunction(parent) && parent.body === current;
687
+ if (allowed)
688
+ return;
689
+ const sf = ctx.sourceFile;
690
+ const start = call.getStart(sf);
691
+ ctx.report({
692
+ ruleName: NAME8,
693
+ code: CODE8,
694
+ start,
695
+ length: call.getEnd() - start,
696
+ messageText: `\`$.${match.method}\` declares a variable \u2014 bind it to a \`const\` first (\`const x = $.${match.method}(value, Type)\`), don't use the result inline (e.g. \`$.if($.let(...))\` or \`$.let(...).add(...)\`).`,
697
+ category: "warning"
698
+ });
699
+ }
700
+ };
701
+
702
+ // ../east-diagnostics/dist/src/east-ir.js
703
+ function chainRootReceiver(node, ctx) {
704
+ const t = ctx.ts;
705
+ let root = node;
706
+ for (; ; ) {
707
+ if (t.isCallExpression(root))
708
+ root = root.expression;
709
+ else if (t.isPropertyAccessExpression(root) || t.isElementAccessExpression(root)) {
710
+ root = root.expression;
711
+ } else {
712
+ return root;
713
+ }
714
+ }
715
+ }
716
+ function bodyBuildsEastIr(body, ctx) {
717
+ const t = ctx.ts;
718
+ let found = false;
719
+ const visit = (n) => {
720
+ if (found)
721
+ return;
722
+ if (isBlockBuilderCallback(n, ctx))
723
+ return;
724
+ if (t.isCallExpression(n)) {
725
+ if (matchBlockBuilderCall(n, ctx) !== void 0 || isBlockBuilderType(ctx.checker.getTypeAtLocation(chainRootReceiver(n.expression, ctx)))) {
726
+ found = true;
727
+ return;
728
+ }
729
+ }
730
+ t.forEachChild(n, visit);
731
+ };
732
+ visit(body);
733
+ return found;
734
+ }
735
+
736
+ // ../east-diagnostics/dist/src/rules/no-unexecuted-east-expression.js
737
+ var NAME9 = "no-unexecuted-east-expression";
738
+ var CODE9 = 990009;
739
+ var noUnexecutedEastExpression = {
740
+ name: NAME9,
741
+ code: CODE9,
742
+ description: "Flag a bare East expression statement that is never executed with $() or bound \u2014 it has no effect.",
743
+ check(node, ctx) {
744
+ const t = ctx.ts;
745
+ if (!t.isExpressionStatement(node))
746
+ return;
747
+ const expr = node.expression;
748
+ const root = chainRootReceiver(expr, ctx);
749
+ if (isBlockBuilderType(ctx.checker.getTypeAtLocation(root)))
750
+ return;
751
+ if (!isEastExprType(ctx.checker.getTypeAtLocation(expr)))
752
+ return;
753
+ const sf = ctx.sourceFile;
754
+ const start = expr.getStart(sf);
755
+ ctx.report({
756
+ ruleName: NAME9,
757
+ code: CODE9,
758
+ start,
759
+ length: expr.getEnd() - start,
760
+ messageText: "This East expression is never executed or bound, so it has no effect. Wrap it in `$( \u2026 )` to run it for its effect, or bind it with `$.let` / `$.const`.",
761
+ category: "warning"
762
+ });
763
+ }
764
+ };
765
+
766
+ // ../east-diagnostics/dist/src/rules/no-reinlined-east-binding.js
767
+ var NAME10 = "no-reinlined-east-binding";
768
+ var CODE10 = 990010;
769
+ var noReinlinedEastBinding = {
770
+ name: NAME10,
771
+ code: CODE10,
772
+ description: "An East Expr bound to a JS const/let and reused inside an East block is re-inlined per use \u2014 bind it once with $.let/$.const.",
773
+ check(node, ctx) {
774
+ const t = ctx.ts;
775
+ if (!t.isVariableDeclaration(node))
776
+ return;
777
+ if (!t.isIdentifier(node.name))
778
+ return;
779
+ if (node.initializer === void 0)
780
+ return;
781
+ let init2 = node.initializer;
782
+ while (t.isParenthesizedExpression(init2))
783
+ init2 = init2.expression;
784
+ if (matchBlockBuilderCall(init2, ctx) !== void 0)
785
+ return;
786
+ if (t.isIdentifier(init2))
787
+ return;
788
+ if (!isEastExprType(ctx.checker.getTypeAtLocation(init2)))
789
+ return;
790
+ const declSymbol = ctx.checker.getSymbolAtLocation(node.name);
791
+ if (declSymbol === void 0)
792
+ return;
793
+ const name = node.name.text;
794
+ const perBody = /* @__PURE__ */ new Map();
795
+ const visit = (n) => {
796
+ if (t.isIdentifier(n) && n !== node.name && n.text === name) {
797
+ if (ctx.checker.getSymbolAtLocation(n) === declSymbol) {
798
+ const body = enclosingBlockScope(n, ctx);
799
+ if (body !== void 0)
800
+ perBody.set(body, (perBody.get(body) ?? 0) + 1);
801
+ }
802
+ }
803
+ t.forEachChild(n, visit);
804
+ };
805
+ visit(ctx.sourceFile);
806
+ let maxInBody = 0;
807
+ for (const count of perBody.values())
808
+ if (count > maxInBody)
809
+ maxInBody = count;
810
+ if (maxInBody < 2)
811
+ return;
812
+ const sf = ctx.sourceFile;
813
+ const start = node.getStart(sf);
814
+ ctx.report({
815
+ ruleName: NAME10,
816
+ code: CODE10,
817
+ start,
818
+ length: node.getEnd() - start,
819
+ messageText: "This East expression is bound to a JS `const`/`let` and used more than once inside an East block, so it is re-inlined \u2014 and re-evaluated, with a fresh identity for mutable values \u2014 at each use. Bind it once with `$.const`/`$.let`.",
820
+ category: "error"
821
+ });
822
+ }
823
+ };
824
+
825
+ // ../east-diagnostics/dist/src/rules/prefer-jsx-over-factory-call.js
826
+ var NAME11 = "prefer-jsx-over-factory-call";
827
+ var CODE11 = 990012;
828
+ var jsxElementCache = /* @__PURE__ */ new WeakMap();
829
+ function jsxElementType(ctx) {
830
+ const cached = jsxElementCache.get(ctx.sourceFile);
831
+ if (cached !== void 0)
832
+ return cached ?? void 0;
833
+ const computed = computeJsxElementType(ctx);
834
+ jsxElementCache.set(ctx.sourceFile, computed ?? null);
835
+ return computed;
836
+ }
837
+ function computeJsxElementType(ctx) {
838
+ const t = ctx.ts;
839
+ const elementOf = (ns) => {
840
+ const el = ctx.checker.getExportsOfModule(ns).find((s) => s.name === "Element");
841
+ return el ? ctx.checker.getDeclaredTypeOfSymbol(el) : void 0;
842
+ };
843
+ const resolveName = ctx.checker.resolveName;
844
+ const globalNs = resolveName?.("JSX", ctx.sourceFile, t.SymbolFlags.Namespace, false);
845
+ if (globalNs !== void 0) {
846
+ const fromGlobal = elementOf(globalNs);
847
+ if (fromGlobal !== void 0)
848
+ return fromGlobal;
849
+ }
850
+ const program = ctx.program;
851
+ if (program === void 0)
852
+ return void 0;
853
+ const options = program.getCompilerOptions();
854
+ const base = jsxImportSourceFor(options, ctx.sourceFile, t);
855
+ if (base === void 0)
856
+ return void 0;
857
+ const resolutionHost = {
858
+ fileExists: (f) => program.getSourceFile(f) !== void 0 || t.sys.fileExists(f),
859
+ readFile: (f) => program.getSourceFile(f)?.text ?? t.sys.readFile(f),
860
+ directoryExists: (d) => t.sys.directoryExists(d),
861
+ getCurrentDirectory: () => t.sys.getCurrentDirectory(),
862
+ getDirectories: (d) => t.sys.getDirectories(d)
863
+ };
864
+ if (t.sys.realpath !== void 0)
865
+ resolutionHost.realpath = (p) => t.sys.realpath(p);
866
+ const resolved = t.resolveModuleName(`${base}/jsx-runtime`, ctx.sourceFile.fileName, options, resolutionHost).resolvedModule?.resolvedFileName;
867
+ if (resolved === void 0)
868
+ return void 0;
869
+ const runtimeSf = program.getSourceFile(resolved);
870
+ const moduleSym = runtimeSf ? ctx.checker.getSymbolAtLocation(runtimeSf) : void 0;
871
+ if (moduleSym === void 0)
872
+ return void 0;
873
+ const jsxNs = ctx.checker.getExportsOfModule(moduleSym).find((s) => s.name === "JSX");
874
+ return jsxNs ? elementOf(jsxNs) : void 0;
875
+ }
876
+ function jsxImportSourceFor(options, sourceFile, t) {
877
+ const pragmas = sourceFile.pragmas;
878
+ const pragma = pragmas?.get("jsximportsource");
879
+ const fromPragma = Array.isArray(pragma) ? pragma[pragma.length - 1]?.arguments?.factory : pragma?.arguments?.factory;
880
+ if (fromPragma !== void 0)
881
+ return fromPragma;
882
+ if (options.jsx !== t.JsxEmit.ReactJSX && options.jsx !== t.JsxEmit.ReactJSXDev)
883
+ return void 0;
884
+ return options.jsxImportSource ?? "react";
885
+ }
886
+ function sameType(a, b, checker) {
887
+ const c = checker;
888
+ if (c.isTypeAssignableTo === void 0)
889
+ return a === b;
890
+ return c.isTypeAssignableTo(a, b) && c.isTypeAssignableTo(b, a);
891
+ }
892
+ var preferJsxOverFactoryCall = {
893
+ name: NAME11,
894
+ code: CODE11,
895
+ description: "In a .tsx file, prefer the <Foo> JSX tag over a factory's Foo.Root(...) when the call produces a JSX element.",
896
+ check(node, ctx) {
897
+ const t = ctx.ts;
898
+ if (ctx.sourceFile.languageVariant !== t.LanguageVariant.JSX)
899
+ return;
900
+ if (!t.isCallExpression(node))
901
+ return;
902
+ const callee = node.expression;
903
+ if (!t.isPropertyAccessExpression(callee))
904
+ return;
905
+ if (callee.name.text !== "Root")
906
+ return;
907
+ if (!t.isIdentifier(callee.expression))
908
+ return;
909
+ const factoryIdent = callee.expression;
910
+ const element = jsxElementType(ctx);
911
+ if (element === void 0)
912
+ return;
913
+ const result = ctx.checker.getTypeAtLocation(node);
914
+ if (!sameType(result, element, ctx.checker))
915
+ return;
916
+ let tagName = factoryIdent.text;
917
+ const sym = ctx.checker.getSymbolAtLocation(factoryIdent);
918
+ if (sym !== void 0 && (sym.flags & t.SymbolFlags.Alias) !== 0) {
919
+ const target = ctx.checker.getAliasedSymbol(sym);
920
+ if (target.name.length > 0)
921
+ tagName = target.name;
922
+ }
923
+ const sf = ctx.sourceFile;
924
+ const start = callee.getStart(sf);
925
+ ctx.report({
926
+ ruleName: NAME11,
927
+ code: CODE11,
928
+ start,
929
+ length: callee.getEnd() - start,
930
+ messageText: `Author this with the \`<${tagName}>\` JSX tag instead of \`${factoryIdent.text}.Root(...)\` \u2014 in a .tsx file the JSX tag is the authoring surface (the call already produces a JSX element).`,
931
+ category: "suggestion"
932
+ });
933
+ }
934
+ };
935
+
936
+ // ../east-diagnostics/dist/src/rules/no-untracked-east-data.js
937
+ var NAME12 = "no-untracked-east-data";
938
+ var CODE12 = 990013;
939
+ function plainLiteralInitializer(decl, t) {
940
+ const init2 = decl.initializer;
941
+ if (init2 === void 0)
942
+ return void 0;
943
+ const unwrapped = t.isAsExpression(init2) || t.isSatisfiesExpression(init2) ? init2.expression : init2;
944
+ if (t.isArrayLiteralExpression(unwrapped) || t.isObjectLiteralExpression(unwrapped)) {
945
+ return unwrapped;
946
+ }
947
+ return void 0;
948
+ }
949
+ var noUntrackedEastData = {
950
+ name: NAME12,
951
+ code: CODE12,
952
+ description: "Inside East blocks, bind data consumed in East-typed positions with $.const/$.let, not a bare JS const.",
953
+ check(node, ctx) {
954
+ const t = ctx.ts;
955
+ if (!t.isIdentifier(node))
956
+ return;
957
+ const parent = node.parent;
958
+ const isCallArg = parent !== void 0 && t.isCallExpression(parent) && parent.expression !== node && parent.arguments.some((arg) => arg === node);
959
+ const isJsxValue = parent !== void 0 && t.isJsxExpression(parent) && parent.expression === node;
960
+ if (!isCallArg && !isJsxValue)
961
+ return;
962
+ if (!insideBlockScope(node, ctx))
963
+ return;
964
+ const contextual = ctx.checker.getContextualType(node);
965
+ if (contextual === void 0 || !isEastExprType(contextual))
966
+ return;
967
+ const symbol = ctx.checker.getSymbolAtLocation(node);
968
+ const decl = symbol?.valueDeclaration;
969
+ if (decl === void 0 || !t.isVariableDeclaration(decl))
970
+ return;
971
+ if (plainLiteralInitializer(decl, t) === void 0)
972
+ return;
973
+ if (!insideBlockScope(decl, ctx))
974
+ return;
975
+ const sf = ctx.sourceFile;
976
+ const start = node.getStart(sf);
977
+ ctx.report({
978
+ ruleName: NAME12,
979
+ code: CODE12,
980
+ start,
981
+ length: node.getEnd() - start,
982
+ messageText: `Bare \`const ${node.text} = \u2026\` isn't tracked by the East block builder. Bind East data with \`$.const([...], Type)\` (or \`$.let\`) so the binding carries its East type and is evaluated once.`,
983
+ category: "suggestion"
984
+ });
985
+ }
986
+ };
987
+
988
+ // ../east-diagnostics/dist/src/rules/no-compile-time-data-injection.js
989
+ var NAME13 = "no-compile-time-data-injection";
990
+ var CODE13 = 990015;
991
+ var FS_MODULES = /* @__PURE__ */ new Set(["node:fs", "fs", "node:fs/promises", "fs/promises"]);
992
+ function fire(ctx, target, messageText) {
993
+ const sf = ctx.sourceFile;
994
+ const start = target.getStart(sf);
995
+ ctx.report({ ruleName: NAME13, code: CODE13, start, length: target.getEnd() - start, messageText, category: "warning" });
996
+ }
997
+ function importOfSymbol(sym, t) {
998
+ for (const d of sym?.declarations ?? []) {
999
+ let n = d;
1000
+ if (t.isImportSpecifier(n))
1001
+ n = n.parent.parent.parent;
1002
+ else if (t.isNamespaceImport(n))
1003
+ n = n.parent.parent;
1004
+ else if (t.isImportClause(n))
1005
+ n = n.parent;
1006
+ else
1007
+ continue;
1008
+ if (t.isImportDeclaration(n))
1009
+ return n;
1010
+ }
1011
+ return void 0;
1012
+ }
1013
+ function resolvesToFsImport(id, ctx) {
1014
+ const t = ctx.ts;
1015
+ const imp = importOfSymbol(ctx.checker.getSymbolAtLocation(id), t);
1016
+ return imp !== void 0 && t.isStringLiteral(imp.moduleSpecifier) && FS_MODULES.has(imp.moduleSpecifier.text);
1017
+ }
1018
+ function insidePlatformImplement(node, t) {
1019
+ let cur = node.parent;
1020
+ while (cur !== void 0) {
1021
+ if (t.isCallExpression(cur) && t.isPropertyAccessExpression(cur.expression) && cur.expression.name.text === "implement") {
1022
+ return true;
1023
+ }
1024
+ cur = cur.parent;
1025
+ }
1026
+ return false;
1027
+ }
1028
+ function isProcessEnv(node, t) {
1029
+ return t.isPropertyAccessExpression(node) && t.isIdentifier(node.expression) && node.expression.text === "process" && node.name.text === "env";
1030
+ }
1031
+ var noCompileTimeDataInjection = {
1032
+ name: NAME13,
1033
+ code: CODE13,
1034
+ description: "Flag build-time data ingestion (a node:fs import or call, JSON.parse, process.env) at module scope \u2014 load data at runtime via e3.input / datasets / platform tasks.",
1035
+ check(node, ctx) {
1036
+ const t = ctx.ts;
1037
+ if (!importsEastPackage(ctx.sourceFile, t))
1038
+ return;
1039
+ if (!declaresEastProgram(ctx.sourceFile, ctx.checker, t))
1040
+ return;
1041
+ if (t.isImportDeclaration(node)) {
1042
+ const spec = node.moduleSpecifier;
1043
+ if (t.isStringLiteral(spec) && FS_MODULES.has(spec.text)) {
1044
+ fire(ctx, node, `Importing \`${spec.text}\` into East/e3 source bakes build-time file I/O into the deployed program. Read data at runtime via \`e3.input\` / a dataset, or an \`east-node-io\` platform task.`);
1045
+ }
1046
+ return;
1047
+ }
1048
+ if (insideBlockScope(node, ctx))
1049
+ return;
1050
+ if (insidePlatformImplement(node, t))
1051
+ return;
1052
+ if (isProcessEnv(node, t)) {
1053
+ fire(ctx, node, "Reading `process.env` at module scope couples the deployed program to its build environment. Make it an `e3.input` / dataset parameter.");
1054
+ return;
1055
+ }
1056
+ if (!t.isCallExpression(node))
1057
+ return;
1058
+ const callee = node.expression;
1059
+ const base = t.isIdentifier(callee) ? callee : t.isPropertyAccessExpression(callee) && t.isIdentifier(callee.expression) ? callee.expression : void 0;
1060
+ if (base !== void 0 && resolvesToFsImport(base, ctx)) {
1061
+ fire(ctx, node, "This `node:fs` call reads/probes the filesystem at build/deploy time and bakes the result into the program. Ingest at runtime via `e3.input` / a dataset / an `east-node-io` task.");
1062
+ return;
1063
+ }
1064
+ if (t.isPropertyAccessExpression(callee) && t.isIdentifier(callee.expression) && callee.expression.text === "JSON" && callee.name.text === "parse") {
1065
+ fire(ctx, node, "`JSON.parse(...)` at module scope bakes parsed data into the program. Load it at runtime via `e3.input` / a dataset.");
1066
+ }
1067
+ }
1068
+ };
1069
+
1070
+ // ../east-diagnostics/dist/src/rules/no-compile-time-seed-data.js
1071
+ var NAME14 = "no-compile-time-seed-data";
1072
+ var CODE14 = 990021;
1073
+ function fire2(ctx, target, messageText) {
1074
+ const sf = ctx.sourceFile;
1075
+ const start = target.getStart(sf);
1076
+ ctx.report({ ruleName: NAME14, code: CODE14, start, length: target.getEnd() - start, messageText, category: "warning" });
1077
+ }
1078
+ function isE3InputCall(node, ctx) {
1079
+ const t = ctx.ts;
1080
+ const callee = node.expression;
1081
+ if (!t.isPropertyAccessExpression(callee) || callee.name.text !== "input")
1082
+ return false;
1083
+ if (!t.isIdentifier(callee.expression))
1084
+ return false;
1085
+ const imp = importDeclarationOf(ctx.checker.getSymbolAtLocation(callee.expression), t);
1086
+ return imp !== void 0 && t.isStringLiteral(imp.moduleSpecifier) && imp.moduleSpecifier.text === "@elaraai/e3";
1087
+ }
1088
+ function rootIdentifier(node, t) {
1089
+ let cur = node;
1090
+ for (; ; ) {
1091
+ if (t.isPropertyAccessExpression(cur) || t.isElementAccessExpression(cur))
1092
+ cur = cur.expression;
1093
+ else if (t.isCallExpression(cur))
1094
+ cur = cur.expression;
1095
+ else
1096
+ break;
1097
+ }
1098
+ return t.isIdentifier(cur) ? cur : void 0;
1099
+ }
1100
+ var VALUE_CTORS = /* @__PURE__ */ new Set([
1101
+ "Map",
1102
+ "Set",
1103
+ "Date",
1104
+ "ArrayBuffer",
1105
+ "Uint8Array",
1106
+ "Int8Array",
1107
+ "Uint8ClampedArray",
1108
+ "Int16Array",
1109
+ "Uint16Array",
1110
+ "Int32Array",
1111
+ "Uint32Array",
1112
+ "Float32Array",
1113
+ "Float64Array",
1114
+ "BigInt64Array",
1115
+ "BigUint64Array"
1116
+ ]);
1117
+ function embedsHostComputation(expr, ctx) {
1118
+ const t = ctx.ts;
1119
+ let bad = false;
1120
+ const visit = (n) => {
1121
+ if (bad)
1122
+ return;
1123
+ if (t.isCallExpression(n)) {
1124
+ const root = rootIdentifier(n.expression, t);
1125
+ if (root === void 0 || !resolvesToEastImport(root, ctx.checker, t)) {
1126
+ bad = true;
1127
+ return;
1128
+ }
1129
+ } else if (t.isNewExpression(n)) {
1130
+ const ctor = n.expression;
1131
+ const ok = t.isIdentifier(ctor) && (VALUE_CTORS.has(ctor.text) || resolvesToEastImport(ctor, ctx.checker, t));
1132
+ if (!ok) {
1133
+ bad = true;
1134
+ return;
1135
+ }
1136
+ }
1137
+ t.forEachChild(n, visit);
1138
+ };
1139
+ visit(expr);
1140
+ return bad;
1141
+ }
1142
+ var MUTATORS = /* @__PURE__ */ new Set(["set", "add", "push", "unshift", "splice", "delete", "clear", "fill", "sort", "copyWithin", "pop", "shift"]);
1143
+ function isAssignmentOp(kind, t) {
1144
+ const k = t.SyntaxKind;
1145
+ return kind === k.EqualsToken || kind === k.PlusEqualsToken || kind === k.MinusEqualsToken || kind === k.AsteriskEqualsToken || kind === k.SlashEqualsToken || kind === k.PercentEqualsToken || kind === k.AmpersandEqualsToken || kind === k.BarEqualsToken || kind === k.CaretEqualsToken || kind === k.LessThanLessThanEqualsToken || kind === k.GreaterThanGreaterThanEqualsToken || kind === k.GreaterThanGreaterThanGreaterThanEqualsToken || kind === k.AsteriskAsteriskEqualsToken || kind === k.QuestionQuestionEqualsToken || kind === k.BarBarEqualsToken || kind === k.AmpersandAmpersandEqualsToken;
1146
+ }
1147
+ function insideLoop(node, t) {
1148
+ let cur = node.parent;
1149
+ while (cur !== void 0) {
1150
+ if (t.isForStatement(cur) || t.isForOfStatement(cur) || t.isForInStatement(cur) || t.isWhileStatement(cur) || t.isDoStatement(cur)) {
1151
+ return true;
1152
+ }
1153
+ cur = cur.parent;
1154
+ }
1155
+ return false;
1156
+ }
1157
+ function isHostFilled(sym, ctx) {
1158
+ const t = ctx.ts;
1159
+ let filled = false;
1160
+ const isSym = (n) => t.isIdentifier(n) && ctx.checker.getSymbolAtLocation(n) === sym;
1161
+ const visit = (n) => {
1162
+ if (filled)
1163
+ return;
1164
+ if (t.isCallExpression(n) && t.isPropertyAccessExpression(n.expression) && MUTATORS.has(n.expression.name.text) && isSym(n.expression.expression)) {
1165
+ if (insideLoop(n, t) || n.arguments.some((a) => embedsHostComputation(a, ctx))) {
1166
+ filled = true;
1167
+ return;
1168
+ }
1169
+ }
1170
+ if (t.isBinaryExpression(n) && isAssignmentOp(n.operatorToken.kind, t)) {
1171
+ const root = rootIdentifier(n.left, t);
1172
+ if (root !== void 0 && isSym(root) && (insideLoop(n, t) || embedsHostComputation(n.right, ctx))) {
1173
+ filled = true;
1174
+ return;
1175
+ }
1176
+ }
1177
+ t.forEachChild(n, visit);
1178
+ };
1179
+ visit(ctx.sourceFile);
1180
+ return filled;
1181
+ }
1182
+ function inlineSeed(sourceArg, ctx) {
1183
+ const t = ctx.ts;
1184
+ if (!t.isCallExpression(sourceArg))
1185
+ return void 0;
1186
+ const callee = sourceArg.expression;
1187
+ if (!t.isIdentifier(callee) || importedNameOf(callee, ctx.checker, t) !== "variant" || !resolvesToEastImport(callee, ctx.checker, t))
1188
+ return void 0;
1189
+ const [tag, payload] = sourceArg.arguments;
1190
+ if (tag === void 0 || !t.isStringLiteralLike(tag) || tag.text !== "value")
1191
+ return void 0;
1192
+ return payload;
1193
+ }
1194
+ var noCompileTimeSeedData = {
1195
+ name: NAME14,
1196
+ code: CODE14,
1197
+ description: "Flag host-computed data passed as the inline seed (variant('value', \u2026)) of e3.input \u2014 it must be a small authored constant; load real data from a file source or at runtime.",
1198
+ check(node, ctx) {
1199
+ const t = ctx.ts;
1200
+ if (!t.isCallExpression(node) || !isE3InputCall(node, ctx))
1201
+ return;
1202
+ if (insideBlockScope(node, ctx))
1203
+ return;
1204
+ const sourceArg = node.arguments[2];
1205
+ if (sourceArg === void 0)
1206
+ return;
1207
+ const seedArg = inlineSeed(sourceArg, ctx);
1208
+ if (seedArg === void 0)
1209
+ return;
1210
+ let expr = seedArg;
1211
+ let sym;
1212
+ if (t.isIdentifier(seedArg)) {
1213
+ sym = ctx.checker.getSymbolAtLocation(seedArg);
1214
+ const decl = sym?.valueDeclaration;
1215
+ if (decl === void 0 || !t.isVariableDeclaration(decl) || decl.initializer === void 0)
1216
+ return;
1217
+ expr = decl.initializer;
1218
+ }
1219
+ while (t.isAsExpression(expr) || t.isSatisfiesExpression(expr) || t.isParenthesizedExpression(expr)) {
1220
+ expr = expr.expression;
1221
+ }
1222
+ const hostComputed = embedsHostComputation(expr, ctx);
1223
+ const hostFilled = sym !== void 0 && isHostFilled(sym, ctx);
1224
+ if (!hostComputed && !hostFilled)
1225
+ return;
1226
+ const nameArg = node.arguments[0];
1227
+ const name = nameArg !== void 0 && t.isStringLiteralLike(nameArg) ? nameArg.text : "\u2026";
1228
+ const reason = hostFilled ? "this seed is an authored-empty collection then filled in place by host code (a `for`-loop / `.set(...)`)" : "this seed is assembled by host calls (`num(...)`, `BigInt(...)`, parsed config) at module-evaluation time";
1229
+ fire2(ctx, seedArg, `Host-computed data passed as the \`e3.input("${name}", \u2026)\` seed bakes a build-time snapshot into the deployed program \u2014 ${reason}. An inline \`variant('value', \u2026)\` seed must be a small AUTHORED CONSTANT (a literal, an empty/literal Map/Set/array/struct, or an East value \`variant\`/\`some\`/\`none\`/\`East.value\`), or the source omitted. Keep real/bulk data out of the package: deliver it as a beast2 file and declare \`variant('file', path)\` (adopted by hash at deploy), put the bytes in a \`BlobType\` input and parse with \`blob.decodeCsv(...)\` inside an \`e3.task\`, read files in a task via a platform \`FileSystem.readFile\`, or use \`e3.record(...)\` + \`e3.mutation\` for set-once root state.`);
1230
+ }
1231
+ };
1232
+
1233
+ // ../east-diagnostics/dist/src/rules/no-host-in-east-block.js
1234
+ var NAME15 = "no-host-in-east-block";
1235
+ var CODE15 = 990020;
1236
+ function resolvesToInBlockEastBinding(id, ctx) {
1237
+ const t = ctx.ts;
1238
+ const sym = ctx.checker.getSymbolAtLocation(id);
1239
+ for (const d of sym?.declarations ?? []) {
1240
+ if (t.isFunctionDeclaration(d) && d.body !== void 0 && insideBlockScope(d, ctx))
1241
+ return true;
1242
+ if (t.isVariableDeclaration(d) && d.initializer !== void 0 && (t.isArrowFunction(d.initializer) || t.isFunctionExpression(d.initializer)) && insideBlockScope(d, ctx)) {
1243
+ return true;
1244
+ }
1245
+ if (t.isParameter(d)) {
1246
+ const fn = d.parent;
1247
+ if ((t.isArrowFunction(fn) || t.isFunctionExpression(fn) || t.isFunctionDeclaration(fn)) && insideBlockScope(fn, ctx)) {
1248
+ const first = fn.parameters[0];
1249
+ if (first === void 0 || !isBlockBuilderType(ctx.checker.getTypeAtLocation(first.name)))
1250
+ return true;
1251
+ }
1252
+ }
1253
+ }
1254
+ return false;
1255
+ }
1256
+ function isEastCall(call, ctx) {
1257
+ const t = ctx.ts;
1258
+ const f = call.expression;
1259
+ if (isEastExprType(ctx.checker.getTypeAtLocation(f)))
1260
+ return true;
1261
+ const root = chainRootReceiver(f, ctx);
1262
+ if (isBlockBuilderType(ctx.checker.getTypeAtLocation(root)))
1263
+ return true;
1264
+ if (t.isPropertyAccessExpression(f) && isEastExprType(ctx.checker.getTypeAtLocation(f.expression)))
1265
+ return true;
1266
+ if (t.isIdentifier(root) && resolvesToEastImport(root, ctx.checker, t))
1267
+ return true;
1268
+ if (t.isPropertyAccessExpression(f) && t.isIdentifier(root) && resolvesToInBlockEastBinding(root, ctx))
1269
+ return true;
1270
+ if (isEastPlatformDefinitionType(ctx.checker.getTypeAtLocation(f)))
1271
+ return true;
1272
+ if (isJsxCompositionCall(call, ctx))
1273
+ return true;
1274
+ if (t.isPropertyAccessExpression(f) && isLibDeclaredEastCall(call, f, ctx))
1275
+ return true;
1276
+ if (isConstantFoldCall(call, ctx))
1277
+ return true;
1278
+ return false;
1279
+ }
1280
+ function isConstantFoldCall(call, ctx) {
1281
+ const t = ctx.ts;
1282
+ if ((ctx.checker.getTypeAtLocation(call).flags & t.TypeFlags.StringLike) === 0)
1283
+ return false;
1284
+ let constant = true;
1285
+ const visit = (n) => {
1286
+ if (!constant)
1287
+ return;
1288
+ if (t.isIdentifier(n)) {
1289
+ const p = n.parent;
1290
+ if (p !== void 0 && t.isPropertyAccessExpression(p) && p.name === n)
1291
+ return;
1292
+ constant = false;
1293
+ return;
1294
+ }
1295
+ if (t.isTemplateExpression(n)) {
1296
+ constant = false;
1297
+ return;
1298
+ }
1299
+ t.forEachChild(n, visit);
1300
+ };
1301
+ visit(call);
1302
+ return constant;
1303
+ }
1304
+ function isLibDeclaredEastCall(call, f, ctx) {
1305
+ if (!isEastExprType(ctx.checker.getTypeAtLocation(call)))
1306
+ return false;
1307
+ const inPackageDts = (sym) => (sym?.declarations ?? []).some((d) => {
1308
+ const sf = d.getSourceFile();
1309
+ if (!sf.isDeclarationFile)
1310
+ return false;
1311
+ if (ctx.program !== void 0)
1312
+ return !ctx.program.isSourceFileDefaultLibrary(sf);
1313
+ return !/\/lib\.[^/]*\.d\.ts$/.test(sf.fileName);
1314
+ });
1315
+ if (inPackageDts(ctx.checker.getSymbolAtLocation(f)))
1316
+ return true;
1317
+ const receiverType = ctx.checker.getTypeAtLocation(f.expression);
1318
+ if (inPackageDts(receiverType.aliasSymbol ?? receiverType.symbol))
1319
+ return true;
1320
+ return rootBuiltByEastFactory(chainRootReceiver(f, ctx), ctx);
1321
+ }
1322
+ function rootBuiltByEastFactory(root, ctx) {
1323
+ const t = ctx.ts;
1324
+ if (!t.isIdentifier(root))
1325
+ return false;
1326
+ let sym = ctx.checker.getSymbolAtLocation(root);
1327
+ if (sym !== void 0 && (sym.flags & t.SymbolFlags.Alias) !== 0) {
1328
+ sym = ctx.checker.getAliasedSymbol(sym);
1329
+ }
1330
+ const decl = sym?.valueDeclaration;
1331
+ if (decl === void 0 || !t.isVariableDeclaration(decl) || decl.initializer === void 0)
1332
+ return false;
1333
+ let init2 = decl.initializer;
1334
+ while (t.isParenthesizedExpression(init2))
1335
+ init2 = init2.expression;
1336
+ if (!t.isCallExpression(init2))
1337
+ return false;
1338
+ const initRoot = chainRootReceiver(init2.expression, ctx);
1339
+ return t.isIdentifier(initRoot) && resolvesToEastImport(initRoot, ctx.checker, t);
1340
+ }
1341
+ function isJsxCompositionCall(call, ctx) {
1342
+ const t = ctx.ts;
1343
+ if (call.arguments.some((a) => isJsx(a, t) || (t.isArrowFunction(a) || t.isFunctionExpression(a)) && returnExpressions(a, t).some((r) => isJsx(r, t)))) {
1344
+ return true;
1345
+ }
1346
+ const f = call.expression;
1347
+ if (!t.isIdentifier(f))
1348
+ return false;
1349
+ const sym = ctx.checker.getSymbolAtLocation(f);
1350
+ for (const d of sym?.declarations ?? []) {
1351
+ let fn;
1352
+ if (t.isFunctionDeclaration(d) && d.body !== void 0)
1353
+ fn = d;
1354
+ else if (t.isVariableDeclaration(d) && d.initializer !== void 0 && (t.isArrowFunction(d.initializer) || t.isFunctionExpression(d.initializer))) {
1355
+ fn = d.initializer;
1356
+ }
1357
+ if (fn !== void 0 && returnExpressions(fn, t).some((r) => isJsx(r, t)))
1358
+ return true;
1359
+ }
1360
+ return false;
1361
+ }
1362
+ function isEast(expr, ctx) {
1363
+ return isEastExprType(ctx.checker.getTypeAtLocation(expr));
1364
+ }
1365
+ function insideJsx(node, ctx) {
1366
+ const t = ctx.ts;
1367
+ let cur = node.parent;
1368
+ while (cur !== void 0) {
1369
+ if (t.isJsxElement(cur) || t.isJsxSelfClosingElement(cur) || t.isJsxFragment(cur) || t.isJsxExpression(cur) || t.isJsxAttribute(cur)) {
1370
+ return true;
1371
+ }
1372
+ if (t.isArrowFunction(cur) || t.isFunctionExpression(cur) || t.isFunctionDeclaration(cur) || t.isMethodDeclaration(cur)) {
1373
+ return false;
1374
+ }
1375
+ cur = cur.parent;
1376
+ }
1377
+ return false;
1378
+ }
1379
+ function isJsx(node, t) {
1380
+ return t.isJsxElement(node) || t.isJsxFragment(node) || t.isJsxSelfClosingElement(node) || t.isParenthesizedExpression(node) && isJsx(node.expression, t);
1381
+ }
1382
+ function returnExpressions(fn, t) {
1383
+ if (fn.body === void 0)
1384
+ return [];
1385
+ if (!t.isBlock(fn.body))
1386
+ return [fn.body];
1387
+ const out = [];
1388
+ const visit = (n) => {
1389
+ if (t.isFunctionDeclaration(n) || t.isFunctionExpression(n) || t.isArrowFunction(n))
1390
+ return;
1391
+ if (t.isReturnStatement(n) && n.expression !== void 0)
1392
+ out.push(n.expression);
1393
+ t.forEachChild(n, visit);
1394
+ };
1395
+ t.forEachChild(fn.body, visit);
1396
+ return out;
1397
+ }
1398
+ var REPORT = (ctx, target, messageText, fix) => {
1399
+ const sf = ctx.sourceFile;
1400
+ const start = target.getStart(sf);
1401
+ const length = target.getEnd() - start;
1402
+ ctx.report({
1403
+ ruleName: NAME15,
1404
+ code: CODE15,
1405
+ start,
1406
+ length,
1407
+ messageText,
1408
+ category: "warning",
1409
+ ...fix !== void 0 ? { fix: { description: fix.description, changes: [{ start, length, newText: fix.newText }] } } : {}
1410
+ });
1411
+ };
1412
+ var noHostInEastBlock = {
1413
+ name: NAME15,
1414
+ code: CODE15,
1415
+ description: "Flag host-language constructs (host calls, operators on East operands, JS control-flow, host string interpolation) inside an East block \u2014 express them in East.",
1416
+ check(node, ctx) {
1417
+ const t = ctx.ts;
1418
+ if (!insideBlockScope(node, ctx))
1419
+ return;
1420
+ if (insideJsx(node, ctx))
1421
+ return;
1422
+ {
1423
+ let fn;
1424
+ let reportNode;
1425
+ if (t.isFunctionDeclaration(node) && node.body !== void 0) {
1426
+ fn = node;
1427
+ reportNode = node.name ?? node;
1428
+ } else if (t.isVariableDeclaration(node) && node.initializer !== void 0 && (t.isArrowFunction(node.initializer) || t.isFunctionExpression(node.initializer))) {
1429
+ fn = node.initializer;
1430
+ reportNode = node.name;
1431
+ }
1432
+ if (fn !== void 0 && reportNode !== void 0) {
1433
+ const first = fn.parameters[0];
1434
+ if (first !== void 0 && isBlockBuilderType(ctx.checker.getTypeAtLocation(first.name)))
1435
+ return;
1436
+ if (returnExpressions(fn, t).some((r) => isJsx(r, t)))
1437
+ return;
1438
+ REPORT(ctx, reportNode, "TS closure/function declared inside an East block \u2014 an authoring-time macro (it can't be serialized or recursed and expands inline at each call). Make it a real `East.function` (`$.const(East.function(...))`) or inline it.");
1439
+ return;
1440
+ }
1441
+ }
1442
+ if (t.isForStatement(node) || t.isWhileStatement(node) || t.isForOfStatement(node)) {
1443
+ if (t.isForOfStatement(node) && isEast(node.expression, ctx))
1444
+ return;
1445
+ if (!bodyBuildsEastIr(node.statement, ctx))
1446
+ return;
1447
+ REPORT(ctx, node.getChildAt(0, ctx.sourceFile), "Host loop building East IR \u2014 bind the data with `$.const([...], ArrayType(...))` and use an East collection op (`data.map(($, x) => \u2026)`) or `$.for(data, ($, x) => \u2026)`.");
1448
+ return;
1449
+ }
1450
+ if (t.isIfStatement(node)) {
1451
+ const emits = bodyBuildsEastIr(node.thenStatement, ctx) || node.elseStatement !== void 0 && bodyBuildsEastIr(node.elseStatement, ctx);
1452
+ if (!emits)
1453
+ return;
1454
+ REPORT(ctx, node.getChildAt(0, ctx.sourceFile), "Host `if` building East IR \u2014 use East's `$.if(cond, \u2026)` so the branch is chosen at East runtime.");
1455
+ return;
1456
+ }
1457
+ if (t.isConditionalExpression(node)) {
1458
+ if (isEast(node.condition, ctx) && isEast(node.whenTrue, ctx) && isEast(node.whenFalse, ctx)) {
1459
+ const sf = ctx.sourceFile;
1460
+ REPORT(ctx, node, "Host `?:` selecting between East values \u2014 use `cond.ifElse(() => a, () => b)`.", {
1461
+ description: "Rewrite as cond.ifElse(...)",
1462
+ newText: `(${node.condition.getText(sf)}).ifElse(() => ${node.whenTrue.getText(sf)}, () => ${node.whenFalse.getText(sf)})`
1463
+ });
1464
+ }
1465
+ return;
1466
+ }
1467
+ if (t.isBinaryExpression(node)) {
1468
+ const op = node.operatorToken.kind;
1469
+ const k = t.SyntaxKind;
1470
+ const logical = op === k.AmpersandAmpersandToken || op === k.BarBarToken;
1471
+ const arith = op === k.PlusToken || op === k.MinusToken || op === k.AsteriskToken || op === k.SlashToken || op === k.PercentToken || op === k.EqualsEqualsEqualsToken || op === k.ExclamationEqualsEqualsToken || op === k.EqualsEqualsToken || op === k.LessThanToken || op === k.LessThanEqualsToken || op === k.GreaterThanToken || op === k.GreaterThanEqualsToken;
1472
+ if (logical && isEast(node.left, ctx) && isEast(node.right, ctx)) {
1473
+ REPORT(ctx, node, "Host `&&`/`||` on East booleans \u2014 use East's `.and(() => \u2026)` / `.or(() => \u2026)`.");
1474
+ } else if (arith && (isEast(node.left, ctx) || isEast(node.right, ctx))) {
1475
+ REPORT(ctx, node, "Host operator on an East value \u2014 use the East method (`.add`/`.subtract`/`.multiply`/`.divide`) or `East.equal`/`East.less`/`East.greater`.");
1476
+ }
1477
+ return;
1478
+ }
1479
+ if (t.isPrefixUnaryExpression(node) && (node.operator === t.SyntaxKind.MinusToken || node.operator === t.SyntaxKind.ExclamationToken)) {
1480
+ if (isEast(node.operand, ctx)) {
1481
+ REPORT(ctx, node, "Host unary operator on an East value \u2014 use `.negate()` / `East.not`.");
1482
+ }
1483
+ return;
1484
+ }
1485
+ if (t.isElementAccessExpression(node)) {
1486
+ if (isEast(node.expression, ctx))
1487
+ return;
1488
+ REPORT(ctx, node, "Host index access on a JS value inside an East block \u2014 model the data as an East collection and read it with `.get(...)` / East ops, not `[i]`.");
1489
+ return;
1490
+ }
1491
+ if (t.isTemplateExpression(node) && !(node.parent !== void 0 && t.isTaggedTemplateExpression(node.parent))) {
1492
+ REPORT(ctx, node, "Host string interpolation inside an East block \u2014 build the string in East with `East.str`\u2026`` (or `str`\u2026``).");
1493
+ return;
1494
+ }
1495
+ if (t.isCallExpression(node)) {
1496
+ if (isEastCall(node, ctx))
1497
+ return;
1498
+ const callee = node.expression;
1499
+ const KEY_ACCESSORS = /* @__PURE__ */ new Set(["get", "tryGet", "has", "insert", "insertOrUpdate", "update", "remove"]);
1500
+ REPORT(ctx, node, t.isPropertyAccessExpression(callee) && KEY_ACCESSORS.has(callee.name.text) ? "Host call inside an East block \u2014 make it a real `East.function` (`$.const(East.function(...))`) or inline it as East." : "Host call inside an East block \u2014 this is an authoring-time macro over East. Make it a real `East.function` (`$.const(East.function(...))`), inline it as East, or use the East stdlib.");
1501
+ }
1502
+ }
1503
+ };
1504
+
1505
+ // ../east-diagnostics/dist/src/rules/no-module-scope-east-macro.js
1506
+ var NAME16 = "no-module-scope-east-macro";
1507
+ var CODE16 = 990011;
1508
+ var VALUE_CONSTRUCTORS = /* @__PURE__ */ new Set(["variant", "some"]);
1509
+ function unparen(e, t) {
1510
+ let cur = e;
1511
+ while (t.isParenthesizedExpression(cur))
1512
+ cur = cur.expression;
1513
+ return cur;
1514
+ }
1515
+ function isJsx2(node, t) {
1516
+ return t.isJsxElement(node) || t.isJsxFragment(node) || t.isJsxSelfClosingElement(node) || t.isParenthesizedExpression(node) && isJsx2(node.expression, t);
1517
+ }
1518
+ function isHostTemplate(e, t) {
1519
+ return t.isTemplateExpression(unparen(e, t));
1520
+ }
1521
+ function hasIrArgument(call, ctx) {
1522
+ return call.arguments.some((a) => isEastExprType(ctx.checker.getTypeAtLocation(a)) || containsEastBuilder(a, ctx));
1523
+ }
1524
+ function isEastValueConstructor(expr, ctx) {
1525
+ const t = ctx.ts;
1526
+ if (t.isCallExpression(expr)) {
1527
+ const callee = expr.expression;
1528
+ if (t.isIdentifier(callee) && VALUE_CONSTRUCTORS.has(callee.text))
1529
+ return hasIrArgument(expr, ctx);
1530
+ return t.isPropertyAccessExpression(callee) && t.isIdentifier(callee.expression) && callee.expression.text === "East" && callee.name.text === "value";
1531
+ }
1532
+ return false;
1533
+ }
1534
+ function isEastBuilderCall(call, ctx) {
1535
+ const t = ctx.ts;
1536
+ const callee = call.expression;
1537
+ if (t.isIdentifier(callee) && VALUE_CONSTRUCTORS.has(callee.text))
1538
+ return hasIrArgument(call, ctx);
1539
+ const root = chainRootReceiver(callee, ctx);
1540
+ if (t.isIdentifier(root) && root.text === "East")
1541
+ return true;
1542
+ return isBlockBuilderType(ctx.checker.getTypeAtLocation(root));
1543
+ }
1544
+ function containsEastBuilder(expr, ctx) {
1545
+ const t = ctx.ts;
1546
+ let found = false;
1547
+ const visit = (n) => {
1548
+ if (found)
1549
+ return;
1550
+ if (t.isCallExpression(n) && isEastBuilderCall(n, ctx)) {
1551
+ found = true;
1552
+ return;
1553
+ }
1554
+ t.forEachChild(n, visit);
1555
+ };
1556
+ visit(expr);
1557
+ return found;
1558
+ }
1559
+ function returnBuildsEast(r, ctx) {
1560
+ const t = ctx.ts;
1561
+ if (isJsx2(r, t))
1562
+ return false;
1563
+ if (isEastDefinitionType(ctx.checker.getTypeAtLocation(r)))
1564
+ return false;
1565
+ if (isEastValueConstructor(r, ctx))
1566
+ return true;
1567
+ if (isEastExprType(ctx.checker.getTypeAtLocation(r)))
1568
+ return true;
1569
+ const root = chainRootReceiver(r, ctx);
1570
+ const rootType = ctx.checker.getTypeAtLocation(root);
1571
+ if (isEastExprType(rootType) || isBlockBuilderType(rootType))
1572
+ return true;
1573
+ return containsEastBuilder(r, ctx);
1574
+ }
1575
+ function buildsEastProgram(root, ctx) {
1576
+ const t = ctx.ts;
1577
+ if (!t.isIdentifier(root))
1578
+ return false;
1579
+ if (isBlockBuilderType(ctx.checker.getTypeAtLocation(root)))
1580
+ return true;
1581
+ if (!resolvesToEastImport(root, ctx.checker, t))
1582
+ return false;
1583
+ if (root.text === "East")
1584
+ return true;
1585
+ const imp = importDeclarationOf(ctx.checker.getSymbolAtLocation(root), t);
1586
+ return imp !== void 0 && t.isStringLiteral(imp.moduleSpecifier) && imp.moduleSpecifier.text === "@elaraai/e3";
1587
+ }
1588
+ function flowsIntoEastProgram(call, ctx) {
1589
+ const t = ctx.ts;
1590
+ let node = call;
1591
+ for (; ; ) {
1592
+ const parent = node.parent;
1593
+ if (parent === void 0)
1594
+ return false;
1595
+ if (t.isArrayLiteralExpression(parent) || t.isObjectLiteralExpression(parent) || t.isPropertyAssignment(parent) || t.isParenthesizedExpression(parent) || t.isSpreadElement(parent) || t.isTemplateSpan(parent) || t.isTemplateExpression(parent) || t.isNewExpression(parent)) {
1596
+ node = parent;
1597
+ continue;
1598
+ }
1599
+ if (t.isCallExpression(parent) && parent.expression !== node) {
1600
+ return buildsEastProgram(chainRootReceiver(parent.expression, ctx), ctx);
1601
+ }
1602
+ return false;
1603
+ }
1604
+ }
1605
+ function feedsEastProgram(name, ctx) {
1606
+ const t = ctx.ts;
1607
+ const symbol = ctx.checker.getSymbolAtLocation(name);
1608
+ if (symbol === void 0)
1609
+ return false;
1610
+ let found = false;
1611
+ const visit = (n) => {
1612
+ if (found)
1613
+ return;
1614
+ if (t.isCallExpression(n) && t.isIdentifier(n.expression) && ctx.checker.getSymbolAtLocation(n.expression) === symbol) {
1615
+ if (insideBlockScope(n, ctx) || flowsIntoEastProgram(n, ctx)) {
1616
+ found = true;
1617
+ return;
1618
+ }
1619
+ }
1620
+ t.forEachChild(n, visit);
1621
+ };
1622
+ visit(ctx.sourceFile);
1623
+ return found;
1624
+ }
1625
+ function isValueConstruction(e, t) {
1626
+ const r = unparen(e, t);
1627
+ if (t.isIdentifier(r))
1628
+ return r.text === "none";
1629
+ return t.isCallExpression(r) && t.isIdentifier(r.expression) && VALUE_CONSTRUCTORS.has(r.expression.text);
1630
+ }
1631
+ function returnExpressions2(fn, t) {
1632
+ if (fn.body === void 0)
1633
+ return [];
1634
+ if (!t.isBlock(fn.body))
1635
+ return [fn.body];
1636
+ const out = [];
1637
+ const visit = (n) => {
1638
+ if (t.isFunctionDeclaration(n) || t.isFunctionExpression(n) || t.isArrowFunction(n))
1639
+ return;
1640
+ if (t.isReturnStatement(n) && n.expression !== void 0)
1641
+ out.push(n.expression);
1642
+ t.forEachChild(n, visit);
1643
+ };
1644
+ t.forEachChild(fn.body, visit);
1645
+ return out;
1646
+ }
1647
+ var noModuleScopeEastMacro = {
1648
+ name: NAME16,
1649
+ code: CODE16,
1650
+ description: "Flag a module-scope TS helper that builds East values/IR or a composite string key \u2014 make it a real East.function or model typed/nested East data.",
1651
+ check(node, ctx) {
1652
+ const t = ctx.ts;
1653
+ if (!importsEastPackage(ctx.sourceFile, t))
1654
+ return;
1655
+ let fn;
1656
+ let reportNode;
1657
+ let nameNode;
1658
+ if (t.isFunctionDeclaration(node) && node.body !== void 0) {
1659
+ fn = node;
1660
+ reportNode = node.name ?? node;
1661
+ nameNode = node.name;
1662
+ } else if (t.isVariableDeclaration(node) && node.initializer !== void 0 && (t.isArrowFunction(node.initializer) || t.isFunctionExpression(node.initializer))) {
1663
+ fn = node.initializer;
1664
+ reportNode = node.name;
1665
+ if (t.isIdentifier(node.name))
1666
+ nameNode = node.name;
1667
+ }
1668
+ if (fn === void 0 || reportNode === void 0)
1669
+ return;
1670
+ if (insideBlockScope(fn, ctx))
1671
+ return;
1672
+ const first = fn.parameters[0];
1673
+ if (first !== void 0 && isBlockBuilderType(ctx.checker.getTypeAtLocation(first.name)))
1674
+ return;
1675
+ const rs = returnExpressions2(fn, t);
1676
+ if (rs.some((r) => isJsx2(r, t)))
1677
+ return;
1678
+ if (rs.length === 0)
1679
+ return;
1680
+ const everyBuildsIr = rs.every((r) => returnBuildsEast(r, ctx));
1681
+ const everyBuildsValue = !everyBuildsIr && rs.every((r) => returnBuildsEast(r, ctx) || isValueConstruction(r, t));
1682
+ const everyHostKey = !everyBuildsIr && !everyBuildsValue && rs.every((r) => isHostTemplate(r, t));
1683
+ if (!everyBuildsIr && !((everyBuildsValue || everyHostKey) && nameNode !== void 0 && feedsEastProgram(nameNode, ctx)))
1684
+ return;
1685
+ const sf = ctx.sourceFile;
1686
+ const start = reportNode.getStart(sf);
1687
+ ctx.report({
1688
+ ruleName: NAME16,
1689
+ code: CODE16,
1690
+ start,
1691
+ length: reportNode.getEnd() - start,
1692
+ messageText: everyHostKey ? "This helper builds a composite string key from a host template literal \u2014 the signature of a string-keyed data model. Model the data with typed keys / nested East structures instead." : "This module-scope TS helper builds East values/IR \u2014 an authoring-time macro that expands inline and can't be serialized. Make it a real `East.function`, or inline it.",
1693
+ category: "warning"
1694
+ });
1695
+ }
1696
+ };
1697
+
1698
+ // ../east-diagnostics/dist/src/rules/require-runner-platforms.js
1699
+ var NAME17 = "require-runner-platforms";
1700
+ var CODE17 = 990022;
1701
+ function isE3TaskCall(node, ctx) {
1702
+ const t = ctx.ts;
1703
+ const callee = node.expression;
1704
+ if (!t.isPropertyAccessExpression(callee) || callee.name.text !== "task")
1705
+ return false;
1706
+ if (!t.isIdentifier(callee.expression))
1707
+ return false;
1708
+ const imp = importDeclarationOf(ctx.checker.getSymbolAtLocation(callee.expression), t);
1709
+ return imp !== void 0 && t.isStringLiteral(imp.moduleSpecifier) && imp.moduleSpecifier.text === "@elaraai/e3";
1710
+ }
1711
+ function projectPlatformCalls(fnArg, ctx) {
1712
+ const t = ctx.ts;
1713
+ const names = [];
1714
+ const visit = (n) => {
1715
+ if (t.isCallExpression(n) && isEastPlatformDefinitionType(ctx.checker.getTypeAtLocation(n.expression))) {
1716
+ const callee = n.expression;
1717
+ const id = t.isIdentifier(callee) ? callee : t.isPropertyAccessExpression(callee) ? callee.name : void 0;
1718
+ const sym = id !== void 0 ? ctx.checker.getSymbolAtLocation(id) : void 0;
1719
+ const resolved = sym !== void 0 && (sym.flags & t.SymbolFlags.Alias) !== 0 ? ctx.checker.getAliasedSymbol(sym) : sym;
1720
+ const declaredInProject = (resolved?.declarations ?? []).some((d) => !d.getSourceFile().isDeclarationFile);
1721
+ if (declaredInProject && id !== void 0)
1722
+ names.push(id.text);
1723
+ }
1724
+ t.forEachChild(n, visit);
1725
+ };
1726
+ visit(fnArg);
1727
+ return names;
1728
+ }
1729
+ function hasCustomPlatformsEntry(options, t) {
1730
+ if (options === void 0)
1731
+ return false;
1732
+ if (!t.isObjectLiteralExpression(options))
1733
+ return void 0;
1734
+ const runnerProp = options.properties.find((p) => t.isPropertyAssignment(p) && t.isIdentifier(p.name) && p.name.text === "runner");
1735
+ if (runnerProp === void 0 || !t.isPropertyAssignment(runnerProp))
1736
+ return false;
1737
+ if (!t.isObjectLiteralExpression(runnerProp.initializer))
1738
+ return void 0;
1739
+ const platformsProp = runnerProp.initializer.properties.find((p) => t.isPropertyAssignment(p) && t.isIdentifier(p.name) && p.name.text === "platforms");
1740
+ if (platformsProp === void 0 || !t.isPropertyAssignment(platformsProp))
1741
+ return false;
1742
+ if (!t.isArrayLiteralExpression(platformsProp.initializer))
1743
+ return void 0;
1744
+ return platformsProp.initializer.elements.some((el) => t.isObjectLiteralExpression(el) && el.properties.some((p) => t.isPropertyAssignment(p) && t.isIdentifier(p.name) && p.name.text === "custom"));
1745
+ }
1746
+ var requireRunnerPlatforms = {
1747
+ name: NAME17,
1748
+ code: CODE17,
1749
+ description: "An e3.task calling project-declared platform functions must declare a runner.platforms custom module \u2014 otherwise it fails only at dataflow runtime.",
1750
+ check(node, ctx) {
1751
+ const t = ctx.ts;
1752
+ if (!t.isCallExpression(node) || !isE3TaskCall(node, ctx))
1753
+ return;
1754
+ const fnArg = node.arguments[2];
1755
+ if (fnArg === void 0)
1756
+ return;
1757
+ const calls = projectPlatformCalls(fnArg, ctx);
1758
+ if (calls.length === 0)
1759
+ return;
1760
+ const ok = hasCustomPlatformsEntry(node.arguments[3], t);
1761
+ if (ok === true || ok === void 0)
1762
+ return;
1763
+ const nameArg = node.arguments[0];
1764
+ const taskName = nameArg !== void 0 && t.isStringLiteralLike(nameArg) ? nameArg.text : "\u2026";
1765
+ const unique = [...new Set(calls)].join(", ");
1766
+ const sf = ctx.sourceFile;
1767
+ const target = node.arguments[3] ?? node.expression;
1768
+ const start = target.getStart(sf);
1769
+ ctx.report({
1770
+ ruleName: NAME17,
1771
+ code: CODE17,
1772
+ start,
1773
+ length: target.getEnd() - start,
1774
+ messageText: `Task "${taskName}" calls project platform function(s) ${unique} but its runner declares no custom platform module \u2014 it will fail at dataflow runtime with "Platform function \u2026 is not available". Add the module to the runner, e.g. \`{ runner: { runtime: "east-py", platforms: [{ custom: "platform_module" }] } }\`.`,
1775
+ category: "warning"
1776
+ });
1777
+ }
1778
+ };
1779
+
1780
+ // ../east-diagnostics/dist/src/rules/no-cross-block-builder.js
1781
+ var NAME18 = "no-cross-block-builder";
1782
+ var CODE18 = 990023;
1783
+ function nearestBlockCallback(node, ctx) {
1784
+ let cur = node.parent;
1785
+ while (cur !== void 0) {
1786
+ if (isBlockBuilderCallback(cur, ctx))
1787
+ return cur;
1788
+ cur = cur.parent;
1789
+ }
1790
+ return void 0;
1791
+ }
1792
+ function referencesCrossedScope(call, root, owner, ctx) {
1793
+ const t = ctx.ts;
1794
+ const isFnLike = (n) => t.isArrowFunction(n) || t.isFunctionExpression(n) || t.isFunctionDeclaration(n) || t.isMethodDeclaration(n);
1795
+ const enclosingFn = (n) => {
1796
+ let cur = n.parent;
1797
+ while (cur !== void 0 && !isFnLike(cur))
1798
+ cur = cur.parent;
1799
+ return cur;
1800
+ };
1801
+ const contains = (outer, inner) => outer.pos <= inner.pos && inner.end <= outer.end;
1802
+ let crossed = false;
1803
+ const visit = (n) => {
1804
+ if (crossed)
1805
+ return;
1806
+ if (t.isIdentifier(n) && n !== root) {
1807
+ const p = n.parent;
1808
+ const isLabel = p !== void 0 && (t.isPropertyAccessExpression(p) && p.name === n || t.isPropertyAssignment(p) && p.name === n || t.isJsxAttribute(p) && p.name === n);
1809
+ if (!isLabel) {
1810
+ const decl = ctx.checker.getSymbolAtLocation(n)?.valueDeclaration;
1811
+ if (decl !== void 0) {
1812
+ const declFn = enclosingFn(decl);
1813
+ if (declFn !== void 0 && declFn !== owner && contains(owner, declFn) && contains(declFn, call)) {
1814
+ crossed = true;
1815
+ return;
1816
+ }
1817
+ }
1818
+ }
1819
+ }
1820
+ t.forEachChild(n, visit);
1821
+ };
1822
+ visit(call);
1823
+ return crossed;
1824
+ }
1825
+ var noCrossBlockBuilder = {
1826
+ name: NAME18,
1827
+ code: CODE18,
1828
+ description: "Inside a nested East block callback, an outer-`$` emission referencing inner-scope values puts the binding where those values don't exist.",
1829
+ check(node, ctx) {
1830
+ const t = ctx.ts;
1831
+ if (!t.isCallExpression(node))
1832
+ return;
1833
+ const root = chainRootReceiver(node.expression, ctx);
1834
+ if (!t.isIdentifier(root))
1835
+ return;
1836
+ if (!isBlockBuilderType(ctx.checker.getTypeAtLocation(root)))
1837
+ return;
1838
+ const sym = ctx.checker.getSymbolAtLocation(root);
1839
+ const decl = sym?.valueDeclaration;
1840
+ if (decl === void 0 || !t.isParameter(decl))
1841
+ return;
1842
+ const owner = decl.parent;
1843
+ if (!isBlockBuilderCallback(owner, ctx))
1844
+ return;
1845
+ const nearest = nearestBlockCallback(node, ctx);
1846
+ if (nearest === void 0 || nearest === owner)
1847
+ return;
1848
+ if (!referencesCrossedScope(node, root, owner, ctx))
1849
+ return;
1850
+ const sf = ctx.sourceFile;
1851
+ const start = root.getStart(sf);
1852
+ ctx.report({
1853
+ ruleName: NAME18,
1854
+ code: CODE18,
1855
+ start,
1856
+ length: node.getEnd() - start,
1857
+ messageText: "This call uses an OUTER block's `$` inside a nested East callback while referencing inner-callback values \u2014 the binding is emitted into the outer block, where those values don't exist. Use the callback's own builder (name it `$`, not `_$`).",
1858
+ category: "error"
1859
+ });
1860
+ }
1861
+ };
1862
+
1863
+ // ../east-diagnostics/dist/src/rules/no-state-outside-reactive.js
1864
+ var NAME19 = "no-state-outside-reactive";
1865
+ var CODE19 = 990024;
1866
+ function atUiSurfaceRoot(node, ctx) {
1867
+ const t = ctx.ts;
1868
+ const outermost = enclosingBlockScope(node, ctx);
1869
+ if (outermost === void 0 || !t.isCallExpression(outermost))
1870
+ return false;
1871
+ const parent = outermost.parent;
1872
+ if (parent === void 0 || !t.isCallExpression(parent))
1873
+ return false;
1874
+ if (!parent.arguments.some((a) => a === outermost))
1875
+ return false;
1876
+ const callee = parent.expression;
1877
+ return t.isIdentifier(callee) && callee.text === "ui" && resolvesToEastImport(callee, ctx.checker, t);
1878
+ }
1879
+ var noStateOutsideReactive = {
1880
+ name: NAME19,
1881
+ code: CODE19,
1882
+ description: "east-ui State.* must live inside a <Reactive> builder \u2014 outside one the UI function becomes async and is rejected at deploy time.",
1883
+ check(node, ctx) {
1884
+ const t = ctx.ts;
1885
+ if (!t.isCallExpression(node))
1886
+ return;
1887
+ const callee = node.expression;
1888
+ if (!t.isPropertyAccessExpression(callee))
1889
+ return;
1890
+ if (!t.isIdentifier(callee.expression) || callee.expression.text !== "State")
1891
+ return;
1892
+ if (!resolvesToEastImport(callee.expression, ctx.checker, t))
1893
+ return;
1894
+ if (!atUiSurfaceRoot(node, ctx))
1895
+ return;
1896
+ if (insideReactive(node, t))
1897
+ return;
1898
+ const sf = ctx.sourceFile;
1899
+ const start = node.getStart(sf);
1900
+ ctx.report({
1901
+ ruleName: NAME19,
1902
+ code: CODE19,
1903
+ start,
1904
+ length: node.getEnd() - start,
1905
+ messageText: `\`State.${callee.name.text}\` outside a \`<Reactive>\` builder makes this UI function async at analysis time \u2014 the deploy analyzer rejects it (or the surface never re-renders). Move all \`State.*\` into the \`<Reactive>{$ => \u2026}\` inner builder.`,
1906
+ category: "warning"
1907
+ });
1908
+ }
1909
+ };
1910
+
1911
+ // ../east-diagnostics/dist/src/rules/prefer-const-ui-callbacks.js
1912
+ var NAME20 = "prefer-const-ui-callbacks";
1913
+ var CODE20 = 990025;
1914
+ var preferConstUiCallbacks = {
1915
+ name: NAME20,
1916
+ code: CODE20,
1917
+ description: "Inside <Reactive>, bind JSX event handlers with $.const and pass the handle \u2014 an inline East.function prop is rebuilt each re-render and memoized renderers can't see the swap.",
1918
+ check(node, ctx) {
1919
+ const t = ctx.ts;
1920
+ if (!t.isCallExpression(node))
1921
+ return;
1922
+ const callee = node.expression;
1923
+ if (!t.isPropertyAccessExpression(callee))
1924
+ return;
1925
+ if (!t.isIdentifier(callee.expression) || callee.expression.text !== "East")
1926
+ return;
1927
+ if (callee.name.text !== "function" && callee.name.text !== "asyncFunction")
1928
+ return;
1929
+ const parent = node.parent;
1930
+ if (parent === void 0 || !t.isJsxExpression(parent) || parent.expression !== node)
1931
+ return;
1932
+ const attr = parent.parent;
1933
+ if (attr === void 0 || !t.isJsxAttribute(attr))
1934
+ return;
1935
+ if (!insideBlockScope(node, ctx))
1936
+ return;
1937
+ if (!insideReactive(node, t))
1938
+ return;
1939
+ const sf = ctx.sourceFile;
1940
+ const start = callee.getStart(sf);
1941
+ ctx.report({
1942
+ ruleName: NAME20,
1943
+ code: CODE20,
1944
+ start,
1945
+ length: callee.getEnd() - start,
1946
+ messageText: `Inline \`East.${callee.name.text}\` in the \`${attr.name.getText(sf)}\` prop is rebuilt on every render, and \`equalFor\` treats all functions as equal so memoized renderers can't see the swap. Bind it once \u2014 \`const handler = $.const(East.${callee.name.text}(\u2026))\` \u2014 and pass the handle.`,
1947
+ category: "suggestion"
1948
+ });
1949
+ }
1950
+ };
1951
+
1952
+ // ../east-diagnostics/dist/src/rules/no-dynamic-bind-path.js
1953
+ var NAME21 = "no-dynamic-bind-path";
1954
+ var CODE21 = 990026;
1955
+ var KEY_ARG_INDEX = {
1956
+ Data: 0,
1957
+ State: 1
1958
+ };
1959
+ var noDynamicBindPath = {
1960
+ name: NAME21,
1961
+ code: CODE21,
1962
+ description: "Data.bind / State.bind keys must be IR-build constants \u2014 an East-computed key can't be captured in the ui() manifest.",
1963
+ check(node, ctx) {
1964
+ const t = ctx.ts;
1965
+ if (!t.isCallExpression(node))
1966
+ return;
1967
+ const callee = node.expression;
1968
+ if (!t.isPropertyAccessExpression(callee) || callee.name.text !== "bind")
1969
+ return;
1970
+ if (!t.isIdentifier(callee.expression))
1971
+ return;
1972
+ const ns = callee.expression.text;
1973
+ const argIndex = KEY_ARG_INDEX[ns];
1974
+ if (argIndex === void 0)
1975
+ return;
1976
+ if (!resolvesToEastImport(callee.expression, ctx.checker, t))
1977
+ return;
1978
+ const keyArg = node.arguments[argIndex];
1979
+ if (keyArg === void 0)
1980
+ return;
1981
+ if (!isEastExprType(ctx.checker.getTypeAtLocation(keyArg)))
1982
+ return;
1983
+ const sf = ctx.sourceFile;
1984
+ const start = keyArg.getStart(sf);
1985
+ ctx.report({
1986
+ ruleName: NAME21,
1987
+ code: CODE21,
1988
+ start,
1989
+ length: keyArg.getEnd() - start,
1990
+ messageText: `The \`${ns}.bind\` key is an East expression \u2014 bind keys must be JS-side constants captured at IR-build time, or the binding is missing from the ui() manifest (no subscription/permission). Bind each candidate as a constant and select the VALUE in East (\`cond.ifElse(() => a.read(), () => b.read())\`).`,
1991
+ category: "error"
1992
+ });
1993
+ }
1994
+ };
1995
+
1996
+ // ../east-diagnostics/dist/src/rules/no-build-time-clock.js
1997
+ var NAME22 = "no-build-time-clock";
1998
+ var CODE22 = 990027;
1999
+ function insideFunction(node, t) {
2000
+ let cur = node.parent;
2001
+ while (cur !== void 0) {
2002
+ if (t.isArrowFunction(cur) || t.isFunctionExpression(cur) || t.isFunctionDeclaration(cur) || t.isMethodDeclaration(cur) || t.isConstructorDeclaration(cur) || t.isGetAccessorDeclaration(cur) || t.isSetAccessorDeclaration(cur)) {
2003
+ return true;
2004
+ }
2005
+ cur = cur.parent;
2006
+ }
2007
+ return false;
2008
+ }
2009
+ var noBuildTimeClock = {
2010
+ name: NAME22,
2011
+ code: CODE22,
2012
+ description: "Flag Date.now() / argless new Date() at module scope of East/e3 source \u2014 the build clock gets baked into the deployed program.",
2013
+ check(node, ctx) {
2014
+ const t = ctx.ts;
2015
+ let target;
2016
+ if (t.isCallExpression(node) && t.isPropertyAccessExpression(node.expression) && t.isIdentifier(node.expression.expression) && node.expression.expression.text === "Date" && node.expression.name.text === "now") {
2017
+ target = node;
2018
+ } else if (t.isNewExpression(node) && t.isIdentifier(node.expression) && node.expression.text === "Date" && (node.arguments === void 0 || node.arguments.length === 0)) {
2019
+ target = node;
2020
+ }
2021
+ if (target === void 0)
2022
+ return;
2023
+ if (!importsEastPackage(ctx.sourceFile, t))
2024
+ return;
2025
+ if (insideFunction(target, t))
2026
+ return;
2027
+ const sf = ctx.sourceFile;
2028
+ const start = target.getStart(sf);
2029
+ ctx.report({
2030
+ ruleName: NAME22,
2031
+ code: CODE22,
2032
+ start,
2033
+ length: target.getEnd() - start,
2034
+ messageText: 'Module-scope clock read in East/e3 source \u2014 this bakes the BUILD moment into the deployed program. Author a constant datetime (`new Date("2026-06-30T07:00:00Z")`), or read time at runtime inside a task (the `Time` platform).',
2035
+ category: "warning"
2036
+ });
2037
+ }
2038
+ };
2039
+
2040
+ // ../east-diagnostics/dist/src/east-value.js
2041
+ function declaredByEast(decl) {
2042
+ const file = decl.getSourceFile().fileName.replace(/\\/g, "/");
2043
+ return /(?:@elaraai\/east|\/libs\/east)\/(?:dist\/)?src\//.test(file);
2044
+ }
2045
+ function declaredByEastPackage(decl) {
2046
+ const sf = decl.getSourceFile();
2047
+ return sf.isDeclarationFile && /(?:\/@elaraai\/|\/libs\/)/.test(sf.fileName.replace(/\\/g, "/"));
2048
+ }
2049
+ function constituents(type, t) {
2050
+ const members = type.isUnion() ? type.types : [type];
2051
+ return members.filter((m) => (m.flags & (t.TypeFlags.Null | t.TypeFlags.Undefined | t.TypeFlags.Void)) === 0);
2052
+ }
2053
+ function isStructConstituent(type, t) {
2054
+ return (type.symbol?.declarations ?? []).some((d) => t.isMappedTypeNode(d) && declaredByEast(d));
2055
+ }
2056
+ function isVariantConstituent(type, checker) {
2057
+ if ((type.flags & 1) !== 0)
2058
+ return false;
2059
+ for (const prop of checker.getPropertiesOfType(type)) {
2060
+ if (!String(prop.escapedName).startsWith("__@variant_symbol"))
2061
+ continue;
2062
+ if ((prop.declarations ?? []).some(declaredByEast))
2063
+ return true;
2064
+ }
2065
+ return false;
2066
+ }
2067
+ function isSortedConstituent(type) {
2068
+ const name = type.symbol?.name;
2069
+ return (name === "SortedSet" || name === "SortedMap") && (type.symbol?.declarations ?? []).some(declaredByEast);
2070
+ }
2071
+ function isEastValueShape(type, ctx) {
2072
+ if (isEastExprType(type))
2073
+ return false;
2074
+ return constituents(type, ctx.ts).some((m) => isStructConstituent(m, ctx.ts) || isVariantConstituent(m, ctx.checker) || isSortedConstituent(m));
2075
+ }
2076
+ function isRecordShape(type, ctx) {
2077
+ return constituents(type, ctx.ts).some((m) => isStructConstituent(m, ctx.ts) || isVariantConstituent(m, ctx.checker));
2078
+ }
2079
+ function jsPrintDiffers(type, t) {
2080
+ const same = t.TypeFlags.StringLike | t.TypeFlags.BigIntLike | t.TypeFlags.BooleanLike;
2081
+ return constituents(type, t).some((m) => (m.flags & same) === 0);
2082
+ }
2083
+ function isGlobalBuiltin(id, ctx) {
2084
+ const declarations = ctx.checker.getSymbolAtLocation(id)?.declarations ?? [];
2085
+ return declarations.length > 0 && declarations.every((d) => {
2086
+ const file = d.getSourceFile();
2087
+ return ctx.program?.isSourceFileDefaultLibrary(file) ?? /\/typescript\/lib\/lib\.[^/]*\.d\.ts$/.test(file.fileName.replace(/\\/g, "/"));
2088
+ });
2089
+ }
2090
+ function skipValueWrappers(e, t) {
2091
+ let cur = e;
2092
+ for (; ; ) {
2093
+ if (t.isParenthesizedExpression(cur) || t.isNonNullExpression(cur) || t.isAsExpression(cur) || t.isTypeAssertionExpression(cur) || t.isSatisfiesExpression(cur)) {
2094
+ cur = cur.expression;
2095
+ } else {
2096
+ return cur;
2097
+ }
2098
+ }
2099
+ }
2100
+ var ELEMENT_READS = /* @__PURE__ */ new Set(["get", "at"]);
2101
+ function isEastValueExpression(e, ctx) {
2102
+ return eastValueExpression(e, ctx, 0);
2103
+ }
2104
+ function eastValueExpression(e, ctx, depth) {
2105
+ const t = ctx.ts;
2106
+ const expr = skipValueWrappers(e, t);
2107
+ const type = ctx.checker.getTypeAtLocation(expr);
2108
+ if (isEastExprType(type))
2109
+ return false;
2110
+ if (isEastValueShape(type, ctx))
2111
+ return true;
2112
+ if (t.isPropertyAccessExpression(expr)) {
2113
+ return isRecordShape(ctx.checker.getTypeAtLocation(expr.expression), ctx);
2114
+ }
2115
+ if (t.isElementAccessExpression(expr)) {
2116
+ return eastValueExpression(expr.expression, ctx, depth);
2117
+ }
2118
+ if (t.isCallExpression(expr) && t.isPropertyAccessExpression(expr.expression) && ELEMENT_READS.has(expr.expression.name.text)) {
2119
+ return eastValueExpression(expr.expression.expression, ctx, depth);
2120
+ }
2121
+ if (t.isIdentifier(expr) && depth < 3) {
2122
+ const decl = ctx.checker.getSymbolAtLocation(expr)?.valueDeclaration;
2123
+ if (decl !== void 0 && t.isVariableDeclaration(decl) && decl.initializer !== void 0 && t.isVariableDeclarationList(decl.parent) && (decl.parent.flags & t.NodeFlags.Const) !== 0) {
2124
+ return eastValueExpression(decl.initializer, ctx, depth + 1);
2125
+ }
2126
+ }
2127
+ return false;
2128
+ }
2129
+ function isValueConstructorCall(call, ctx) {
2130
+ const t = ctx.ts;
2131
+ const callee = call.expression;
2132
+ return t.isIdentifier(callee) && (callee.text === "variant" || callee.text === "some") && resolvesToEastImport(callee, ctx.checker, t);
2133
+ }
2134
+ function mentionsEastValueType(node, ctx, seen) {
2135
+ const t = ctx.ts;
2136
+ if (node.kind === t.SyntaxKind.AnyKeyword || node.kind === t.SyntaxKind.UnknownKeyword)
2137
+ return true;
2138
+ if (t.isTypeReferenceNode(node)) {
2139
+ const named = ctx.checker.getSymbolAtLocation(node.typeName);
2140
+ const symbol = named !== void 0 && (named.flags & t.SymbolFlags.Alias) !== 0 ? ctx.checker.getAliasedSymbol(named) : named;
2141
+ const declarations = symbol?.declarations ?? [];
2142
+ if (declarations.some((d) => declaredByEast(d) || t.isTypeParameterDeclaration(d)))
2143
+ return true;
2144
+ if (symbol !== void 0 && !seen.has(symbol)) {
2145
+ seen.add(symbol);
2146
+ if (declarations.some((d) => t.isTypeAliasDeclaration(d) && mentionsEastValueType(d.type, ctx, seen)))
2147
+ return true;
2148
+ }
2149
+ }
2150
+ return t.forEachChild(node, (child) => mentionsEastValueType(child, ctx, seen) ? true : void 0) === true;
2151
+ }
2152
+ function writtenInEastValues(signature, index, ctx) {
2153
+ const params = signature.getParameters();
2154
+ const declaration = params[Math.min(index, params.length - 1)]?.valueDeclaration;
2155
+ if (declaration === void 0 || !ctx.ts.isParameter(declaration) || declaration.type === void 0)
2156
+ return true;
2157
+ return mentionsEastValueType(declaration.type, ctx, /* @__PURE__ */ new Set());
2158
+ }
2159
+ function parameterTypeAt(signature, index, call, ctx) {
2160
+ const t = ctx.ts;
2161
+ const params = signature.getParameters();
2162
+ if (params.length === 0)
2163
+ return void 0;
2164
+ const param = params[Math.min(index, params.length - 1)];
2165
+ const type = ctx.checker.getTypeOfSymbolAtLocation(param, call);
2166
+ const declaration = param.valueDeclaration;
2167
+ if (declaration !== void 0 && t.isParameter(declaration) && declaration.dotDotDotToken !== void 0) {
2168
+ return ctx.checker.getTypeArguments(type)[0];
2169
+ }
2170
+ return type;
2171
+ }
2172
+ function flowOf(e, ctx) {
2173
+ const t = ctx.ts;
2174
+ if (insideBlockScope(e, ctx))
2175
+ return "program";
2176
+ let node = e;
2177
+ let east = false;
2178
+ for (; ; ) {
2179
+ const parent = node.parent;
2180
+ if (parent === void 0)
2181
+ return east ? "value" : "host";
2182
+ if (t.isParenthesizedExpression(parent) || t.isAsExpression(parent) || t.isSatisfiesExpression(parent) || t.isNonNullExpression(parent) || t.isTypeAssertionExpression(parent) || t.isArrayLiteralExpression(parent) || t.isSpreadElement(parent)) {
2183
+ node = parent;
2184
+ continue;
2185
+ }
2186
+ if (t.isPropertyAssignment(parent) && parent.initializer === node || t.isShorthandPropertyAssignment(parent)) {
2187
+ const literal = parent.parent;
2188
+ const contextual = ctx.checker.getContextualType(literal);
2189
+ if (contextual !== void 0 && isRecordShape(contextual, ctx))
2190
+ east = true;
2191
+ node = literal;
2192
+ continue;
2193
+ }
2194
+ const args = t.isCallExpression(parent) || t.isNewExpression(parent) ? parent.arguments ?? [] : [];
2195
+ if ((t.isCallExpression(parent) || t.isNewExpression(parent)) && args.includes(node)) {
2196
+ if (t.isCallExpression(parent) && isValueConstructorCall(parent, ctx)) {
2197
+ east = true;
2198
+ node = parent;
2199
+ continue;
2200
+ }
2201
+ const signature = ctx.checker.getResolvedSignature(parent);
2202
+ const declaration = signature?.getDeclaration();
2203
+ if (signature !== void 0 && declaration !== void 0 && declaredByEastPackage(declaration)) {
2204
+ const index = args.indexOf(node);
2205
+ const param = parameterTypeAt(signature, index, parent, ctx);
2206
+ if (param !== void 0 && isEastExprType(param))
2207
+ return "program";
2208
+ if (declaredByEast(declaration) || writtenInEastValues(signature, index, ctx))
2209
+ return "value";
2210
+ }
2211
+ return east ? "value" : "host";
2212
+ }
2213
+ return east ? "value" : "host";
2214
+ }
2215
+ }
2216
+ function landsInEastSlot(e, ctx) {
2217
+ return flowOf(e, ctx) === "value";
2218
+ }
2219
+
2220
+ // ../east-diagnostics/dist/src/rules/no-handrolled-value-type-mirror.js
2221
+ var NAME23 = "no-handrolled-value-type-mirror";
2222
+ var CODE23 = 990028;
2223
+ function eastTypeValueInFile(name, ctx) {
2224
+ const t = ctx.ts;
2225
+ for (const stmt of ctx.sourceFile.statements) {
2226
+ let ident;
2227
+ if (t.isImportDeclaration(stmt) && stmt.importClause?.namedBindings !== void 0 && t.isNamedImports(stmt.importClause.namedBindings)) {
2228
+ for (const spec of stmt.importClause.namedBindings.elements) {
2229
+ if (spec.name.text === name && !spec.isTypeOnly)
2230
+ ident = spec.name;
2231
+ }
2232
+ } else if (t.isVariableStatement(stmt)) {
2233
+ for (const d of stmt.declarationList.declarations) {
2234
+ if (t.isIdentifier(d.name) && d.name.text === name)
2235
+ ident = d.name;
2236
+ }
2237
+ }
2238
+ if (ident !== void 0) {
2239
+ const type = ctx.checker.getTypeAtLocation(ident);
2240
+ const typeName = type.aliasSymbol?.name ?? type.symbol?.name;
2241
+ if (typeName !== void 0 && typeName.endsWith("Type"))
2242
+ return true;
2243
+ }
2244
+ }
2245
+ return false;
2246
+ }
2247
+ function membersOf2(node) {
2248
+ return node.members;
2249
+ }
2250
+ function mentionsEastImport(typeNode, ctx) {
2251
+ const t = ctx.ts;
2252
+ let found = false;
2253
+ const visit = (n) => {
2254
+ if (found)
2255
+ return;
2256
+ if (t.isTypeReferenceNode(n)) {
2257
+ const name = t.isIdentifier(n.typeName) ? n.typeName : t.isQualifiedName(n.typeName) ? leftmost(n.typeName, t) : void 0;
2258
+ if (name !== void 0 && resolvesToEastImport(name, ctx.checker, t)) {
2259
+ found = true;
2260
+ return;
2261
+ }
2262
+ }
2263
+ t.forEachChild(n, visit);
2264
+ };
2265
+ visit(typeNode);
2266
+ return found;
2267
+ }
2268
+ function leftmost(q, t) {
2269
+ let cur = q;
2270
+ while (t.isQualifiedName(cur))
2271
+ cur = cur.left;
2272
+ return cur;
2273
+ }
2274
+ function holdsEastValue(shape, ctx) {
2275
+ const t = ctx.ts;
2276
+ return membersOf2(shape).some((m) => t.isPropertySignature(m) && m.type !== void 0 && isEastValueShape(ctx.checker.getTypeFromTypeNode(m.type), ctx));
2277
+ }
2278
+ function isFactoryInput(node, ctx) {
2279
+ const t = ctx.ts;
2280
+ const sf = ctx.sourceFile;
2281
+ return membersOf2(node).some((m) => {
2282
+ const type = t.isPropertySignature(m) ? m.type : void 0;
2283
+ return type !== void 0 && /\b(?:SubtypeExprOrValue|ExprType)</.test(type.getText(sf));
2284
+ });
2285
+ }
2286
+ function isVariantShapedLiteral(node, t) {
2287
+ if (!t.isTypeLiteralNode(node))
2288
+ return false;
2289
+ const names = new Set(node.members.flatMap((m) => m.name !== void 0 && t.isIdentifier(m.name) ? [m.name.text] : []));
2290
+ return names.has("type") && names.has("value");
2291
+ }
2292
+ function report2(ctx, node, messageText) {
2293
+ const start = node.getStart(ctx.sourceFile);
2294
+ ctx.report({ ruleName: NAME23, code: CODE23, start, length: node.getEnd() - start, messageText, category: "suggestion" });
2295
+ }
2296
+ var noHandrolledValueTypeMirror = {
2297
+ name: NAME23,
2298
+ code: CODE23,
2299
+ description: "A hand-authored type mirroring an East type (Foo beside FooType, a *Like stand-in, an `as { type; value }` assertion) \u2014 derive it with ValueTypeOf<typeof XType> instead.",
2300
+ check(node, ctx) {
2301
+ const t = ctx.ts;
2302
+ if (t.isAsExpression(node) || t.isTypeAssertionExpression(node)) {
2303
+ if (!isVariantShapedLiteral(node.type, t))
2304
+ return;
2305
+ if (!importsEastPackage(ctx.sourceFile, t))
2306
+ return;
2307
+ report2(ctx, node.type, "This `{ type, value }` assertion hand-mirrors an East variant \u2014 it hides the value's real type. Narrow the typed value on its tag (`v.type === \u2026`), or type it with `ValueTypeOf<typeof XType>`.");
2308
+ return;
2309
+ }
2310
+ let name;
2311
+ let shape;
2312
+ if (t.isInterfaceDeclaration(node)) {
2313
+ name = node.name;
2314
+ shape = node;
2315
+ } else if (t.isTypeAliasDeclaration(node) && t.isTypeLiteralNode(node.type)) {
2316
+ name = node.name;
2317
+ shape = node.type;
2318
+ }
2319
+ if (name === void 0 || shape === void 0)
2320
+ return;
2321
+ if (!importsEastPackage(ctx.sourceFile, t))
2322
+ return;
2323
+ if (isFactoryInput(shape, ctx))
2324
+ return;
2325
+ if (name.text.length > "Like".length && name.text.endsWith("Like") && (mentionsEastImport(shape, ctx) || holdsEastValue(shape, ctx))) {
2326
+ report2(ctx, name, `\`${name.text}\` is a loose stand-in for an East value's type \u2014 it drifts silently when the East type changes. Type the value with \`ValueTypeOf<typeof XType>\` of the East type it holds.`);
2327
+ return;
2328
+ }
2329
+ const base = name.text.endsWith("Value") ? name.text.slice(0, -"Value".length) : name.text;
2330
+ const counterpart = `${base}Type`;
2331
+ if (counterpart === name.text)
2332
+ return;
2333
+ if (!eastTypeValueInFile(counterpart, ctx))
2334
+ return;
2335
+ report2(ctx, name, `\`${name.text}\` hand-mirrors the East type \`${counterpart}\` \u2014 it drifts silently when the East type gains a field. Derive it: \`type ${name.text} = ValueTypeOf<typeof ${counterpart}>\`.`);
2336
+ }
2337
+ };
2338
+
2339
+ // ../east-diagnostics/dist/src/rules/no-host-comparison-on-east-values.js
2340
+ var NAME24 = "no-host-comparison-on-east-values";
2341
+ var CODE24 = 990029;
2342
+ function isNullish(e, t) {
2343
+ return e.kind === t.SyntaxKind.NullKeyword || t.isIdentifier(e) && e.text === "undefined";
2344
+ }
2345
+ function isEastObject(e, ctx) {
2346
+ const type = ctx.checker.getTypeAtLocation(e);
2347
+ if (isEastValueShape(type, ctx))
2348
+ return true;
2349
+ const objectLike = (type.flags & ctx.ts.TypeFlags.Object) !== 0 || type.isUnion() && type.types.some((m) => (m.flags & ctx.ts.TypeFlags.Object) !== 0);
2350
+ return objectLike && isEastValueExpression(e, ctx);
2351
+ }
2352
+ function returnedExpressions(fn, t) {
2353
+ if (!t.isBlock(fn.body))
2354
+ return [fn.body];
2355
+ const out = [];
2356
+ const visit = (n) => {
2357
+ if (t.isFunctionLike(n))
2358
+ return;
2359
+ if (t.isReturnStatement(n) && n.expression !== void 0)
2360
+ out.push(n.expression);
2361
+ t.forEachChild(n, visit);
2362
+ };
2363
+ t.forEachChild(fn.body, visit);
2364
+ return out;
2365
+ }
2366
+ function subtractingComparator(call, ctx) {
2367
+ const t = ctx.ts;
2368
+ const callee = call.expression;
2369
+ if (!t.isPropertyAccessExpression(callee) || callee.name.text !== "sort" && callee.name.text !== "toSorted")
2370
+ return void 0;
2371
+ const fn = call.arguments[0];
2372
+ if (fn === void 0 || !t.isArrowFunction(fn) && !t.isFunctionExpression(fn))
2373
+ return void 0;
2374
+ for (const r of returnedExpressions(fn, t)) {
2375
+ const e = skipValueWrappers(r, t);
2376
+ if (t.isBinaryExpression(e) && e.operatorToken.kind === t.SyntaxKind.MinusToken && (isEastValueExpression(e.left, ctx) || isEastValueExpression(e.right, ctx))) {
2377
+ return e;
2378
+ }
2379
+ }
2380
+ return void 0;
2381
+ }
2382
+ var noHostComparisonOnEastValues = {
2383
+ name: NAME24,
2384
+ code: CODE24,
2385
+ description: "Flag ===/!==/</> and subtracting sort comparators on decoded East values \u2014 use equalFor(T) / compareFor(T).",
2386
+ check(node, ctx) {
2387
+ const t = ctx.ts;
2388
+ const sf = ctx.sourceFile;
2389
+ if (t.isCallExpression(node)) {
2390
+ if (!importsEastPackage(sf, t))
2391
+ return;
2392
+ const subtraction = subtractingComparator(node, ctx);
2393
+ if (subtraction === void 0)
2394
+ return;
2395
+ const start2 = subtraction.getStart(sf);
2396
+ ctx.report({
2397
+ ruleName: NAME24,
2398
+ code: CODE24,
2399
+ start: start2,
2400
+ length: subtraction.getEnd() - start2,
2401
+ messageText: "A comparator that subtracts East values mis-orders them \u2014 a `NaN` makes it inconsistent and an Integer past 2^53 rounds. Order with `compareFor(T)` (`xs.sort((a, b) => compare(a.v, b.v))`).",
2402
+ category: "warning"
2403
+ });
2404
+ return;
2405
+ }
2406
+ if (!t.isBinaryExpression(node))
2407
+ return;
2408
+ const k = t.SyntaxKind;
2409
+ const op = node.operatorToken.kind;
2410
+ const equality = op === k.EqualsEqualsEqualsToken || op === k.ExclamationEqualsEqualsToken || op === k.EqualsEqualsToken || op === k.ExclamationEqualsToken;
2411
+ const relational = op === k.LessThanToken || op === k.LessThanEqualsToken || op === k.GreaterThanToken || op === k.GreaterThanEqualsToken;
2412
+ if (!equality && !relational)
2413
+ return;
2414
+ if (!importsEastPackage(sf, t))
2415
+ return;
2416
+ if (isNullish(node.left, t) || isNullish(node.right, t))
2417
+ return;
2418
+ const flagged = equality ? isEastObject(node.left, ctx) || isEastObject(node.right, ctx) : isEastValueShape(ctx.checker.getTypeAtLocation(node.left), ctx) || isEastValueShape(ctx.checker.getTypeAtLocation(node.right), ctx);
2419
+ if (!flagged)
2420
+ return;
2421
+ const start = node.getStart(sf);
2422
+ ctx.report({
2423
+ ruleName: NAME24,
2424
+ code: CODE24,
2425
+ start,
2426
+ length: node.getEnd() - start,
2427
+ messageText: equality ? "Host equality on a decoded East value compares object identity \u2014 two equal structs, variants, DateTimes or Sets are never `===`. Use `equalFor(T)(a, b)`, or `Object.is(a, b)` where you mean the same object." : "Host ordering on a decoded East value compares the wrong representation. Use `compareFor(T)` / `lessFor(T)` (e.g. `arr.sort(compareFor(T))`).",
2428
+ category: "warning"
2429
+ });
2430
+ }
2431
+ };
2432
+
2433
+ // ../east-diagnostics/dist/src/rules/require-example-returns.js
2434
+ var NAME25 = "require-example-returns";
2435
+ var CODE25 = 990030;
2436
+ var RETURNS_EXEMPT = /* @__PURE__ */ new Set(["NullType", "UIComponentType"]);
2437
+ function propNamed(obj, name, t) {
2438
+ for (const p of obj.properties) {
2439
+ if (t.isPropertyAssignment(p) && (t.isIdentifier(p.name) || t.isStringLiteralLike(p.name)) && p.name.text === name) {
2440
+ return p;
2441
+ }
2442
+ }
2443
+ return void 0;
2444
+ }
2445
+ var requireExampleReturns = {
2446
+ name: NAME25,
2447
+ code: CODE25,
2448
+ description: "example() must declare `returns` unless the fn output is NullType/UIComponentType \u2014 omitting it false-passes the example's assertion.",
2449
+ check(node, ctx) {
2450
+ const t = ctx.ts;
2451
+ if (!t.isCallExpression(node))
2452
+ return;
2453
+ const callee = node.expression;
2454
+ if (!t.isIdentifier(callee) || callee.text !== "example")
2455
+ return;
2456
+ if (!resolvesToEastImport(callee, ctx.checker, t))
2457
+ return;
2458
+ const arg = node.arguments[0];
2459
+ if (arg === void 0 || !t.isObjectLiteralExpression(arg))
2460
+ return;
2461
+ if (propNamed(arg, "returns", t) !== void 0)
2462
+ return;
2463
+ const fnProp = propNamed(arg, "fn", t);
2464
+ if (fnProp === void 0 || !t.isCallExpression(fnProp.initializer))
2465
+ return;
2466
+ const outputArg = fnProp.initializer.arguments[1];
2467
+ if (outputArg !== void 0 && t.isIdentifier(outputArg) && RETURNS_EXEMPT.has(outputArg.text))
2468
+ return;
2469
+ const sf = ctx.sourceFile;
2470
+ const start = callee.getStart(sf);
2471
+ ctx.report({
2472
+ ruleName: NAME25,
2473
+ code: CODE25,
2474
+ start,
2475
+ length: callee.getEnd() - start,
2476
+ messageText: "This `example()` has no `returns` \u2014 the harness runs `fn` as a bare statement and the assertion false-passes. Add the hand-verified `returns` value (omit it ONLY for NullType / UIComponentType outputs).",
2477
+ category: "warning"
2478
+ });
2479
+ }
2480
+ };
2481
+
2482
+ // ../east-diagnostics/dist/src/rules/no-duplicate-definition-name.js
2483
+ var NAME26 = "no-duplicate-definition-name";
2484
+ var CODE26 = 990031;
2485
+ var DEFINITION_KINDS = /* @__PURE__ */ new Map([
2486
+ ["input", "input"],
2487
+ ["task", "task"],
2488
+ ["customTask", "task"],
2489
+ ["function", "function"],
2490
+ ["record", "record"],
2491
+ ["mutation", "mutation"]
2492
+ ]);
2493
+ function e3Definition(node, ctx) {
2494
+ const t = ctx.ts;
2495
+ if (!t.isCallExpression(node))
2496
+ return void 0;
2497
+ const callee = node.expression;
2498
+ if (!t.isPropertyAccessExpression(callee) || !t.isIdentifier(callee.expression))
2499
+ return void 0;
2500
+ const kind = DEFINITION_KINDS.get(callee.name.text);
2501
+ if (kind === void 0)
2502
+ return void 0;
2503
+ const imp = importDeclarationOf(ctx.checker.getSymbolAtLocation(callee.expression), t);
2504
+ if (imp === void 0 || !t.isStringLiteral(imp.moduleSpecifier) || imp.moduleSpecifier.text !== "@elaraai/e3")
2505
+ return void 0;
2506
+ const nameArg = node.arguments[0];
2507
+ if (nameArg === void 0 || !t.isStringLiteralLike(nameArg))
2508
+ return void 0;
2509
+ return { kind, nameArg };
2510
+ }
2511
+ var noDuplicateDefinitionName = {
2512
+ name: NAME26,
2513
+ code: CODE26,
2514
+ description: "Two e3 definitions of the same kind with the same name string collide at deploy time \u2014 names must be unique per kind.",
2515
+ check(node, ctx) {
2516
+ const t = ctx.ts;
2517
+ if (!t.isSourceFile(node))
2518
+ return;
2519
+ const seen = /* @__PURE__ */ new Map();
2520
+ const visit = (n) => {
2521
+ const def = e3Definition(n, ctx);
2522
+ if (def !== void 0) {
2523
+ const key = `${def.kind}:${def.nameArg.text}`;
2524
+ const first = seen.get(key);
2525
+ if (first === void 0) {
2526
+ seen.set(key, def.nameArg);
2527
+ } else {
2528
+ const sf = ctx.sourceFile;
2529
+ const start = def.nameArg.getStart(sf);
2530
+ ctx.report({
2531
+ ruleName: NAME26,
2532
+ code: CODE26,
2533
+ start,
2534
+ length: def.nameArg.getEnd() - start,
2535
+ messageText: `Duplicate e3 ${def.kind} name "${def.nameArg.text}" \u2014 it collides with the earlier definition at deploy time. Definition names must be unique per kind.`,
2536
+ category: "error"
2537
+ });
2538
+ }
2539
+ }
2540
+ t.forEachChild(n, visit);
2541
+ };
2542
+ visit(node);
2543
+ }
2544
+ };
2545
+
2546
+ // ../east-diagnostics/dist/src/rules/no-inline-credentials.js
2547
+ var NAME27 = "no-inline-credentials";
2548
+ var CODE27 = 990032;
2549
+ var CREDENTIAL_FIELDS = /* @__PURE__ */ new Set([
2550
+ "password",
2551
+ "passphrase",
2552
+ "privateKey",
2553
+ "secretAccessKey",
2554
+ "accessKeyId",
2555
+ "apiKey",
2556
+ "token",
2557
+ "accessToken",
2558
+ "refreshToken",
2559
+ "sessionToken",
2560
+ "secretKey",
2561
+ "clientSecret"
2562
+ ]);
2563
+ var HOST_FIELDS = /* @__PURE__ */ new Set(["host", "hostname", "endpoint", "url", "server", "address"]);
2564
+ var LOCAL_HOSTS = ["localhost", "127.0.0.1", "::1"];
2565
+ function isStringy(node, t) {
2566
+ return t.isStringLiteral(node) || t.isNoSubstitutionTemplateLiteral(node);
2567
+ }
2568
+ function literalCredential(init2, t) {
2569
+ if (isStringy(init2, t) && init2.text.length > 0)
2570
+ return init2;
2571
+ if (!t.isCallExpression(init2))
2572
+ return void 0;
2573
+ const callee = init2.expression;
2574
+ const calleeName = t.isIdentifier(callee) ? callee.text : t.isPropertyAccessExpression(callee) ? callee.name.text : void 0;
2575
+ if (calleeName !== "some" && calleeName !== "variant")
2576
+ return void 0;
2577
+ const args = calleeName === "variant" ? init2.arguments.slice(1) : init2.arguments;
2578
+ for (const arg of args) {
2579
+ if (isStringy(arg, t) && arg.text.length > 0)
2580
+ return arg;
2581
+ }
2582
+ return void 0;
2583
+ }
2584
+ function mentionsLocalHost(node, t) {
2585
+ if (isStringy(node, t) && LOCAL_HOSTS.some((h) => node.text.includes(h)))
2586
+ return true;
2587
+ let found = false;
2588
+ t.forEachChild(node, (child) => {
2589
+ if (!found && mentionsLocalHost(child, t))
2590
+ found = true;
2591
+ });
2592
+ return found;
2593
+ }
2594
+ function targetsLocalHost(obj, t) {
2595
+ for (const prop of obj.properties) {
2596
+ if (!t.isPropertyAssignment(prop))
2597
+ continue;
2598
+ const name = t.isIdentifier(prop.name) || t.isStringLiteral(prop.name) ? prop.name.text : void 0;
2599
+ if (name !== void 0 && HOST_FIELDS.has(name) && mentionsLocalHost(prop.initializer, t))
2600
+ return true;
2601
+ }
2602
+ return false;
2603
+ }
2604
+ var noInlineCredentials = {
2605
+ name: NAME27,
2606
+ code: CODE27,
2607
+ description: "Flag literal string credentials (password, secretAccessKey, token, \u2026) in East/e3 source \u2014 use Env.get so the IR carries the variable name, not the secret.",
2608
+ check(node, ctx) {
2609
+ const t = ctx.ts;
2610
+ if (!t.isPropertyAssignment(node))
2611
+ return;
2612
+ const name = t.isIdentifier(node.name) || t.isStringLiteral(node.name) ? node.name.text : void 0;
2613
+ if (name === void 0 || !CREDENTIAL_FIELDS.has(name))
2614
+ return;
2615
+ if (!importsEastPackage(ctx.sourceFile, t))
2616
+ return;
2617
+ const literal = literalCredential(node.initializer, t);
2618
+ if (literal === void 0)
2619
+ return;
2620
+ if (t.isObjectLiteralExpression(node.parent) && targetsLocalHost(node.parent, t))
2621
+ return;
2622
+ const sf = ctx.sourceFile;
2623
+ const start = literal.getStart(sf);
2624
+ ctx.report({
2625
+ ruleName: NAME27,
2626
+ code: CODE27,
2627
+ start,
2628
+ length: literal.getEnd() - start,
2629
+ messageText: `Literal credential in \`${name}\` \u2014 East source compiles to content-addressed IR that is stored, exported, and replicated, so a secret here is effectively unredactable. Use \`Env.get("YOUR_VAR")\` (east-node-std) and supply the value per environment: your shell locally, the deployment's secret store in hosted runtimes.`,
2630
+ category: "warning"
2631
+ });
2632
+ }
2633
+ };
2634
+
2635
+ // ../east-diagnostics/dist/src/rules/no-host-print-of-east-values.js
2636
+ var NAME28 = "no-host-print-of-east-values";
2637
+ var CODE28 = 990033;
2638
+ var PRINTING_METHODS = /* @__PURE__ */ new Set(["toString", "toISOString", "toJSON"]);
2639
+ var CSS_UNIT = /^(?:px|r?em|ch|fr|deg|turn|[sdl]?v(?:h|w|min|max))(?![A-Za-z])/;
2640
+ function writesCssLength(span, ctx) {
2641
+ if (!CSS_UNIT.test(span.literal.text))
2642
+ return false;
2643
+ const type = ctx.checker.getTypeAtLocation(span.expression);
2644
+ const members = type.isUnion() ? type.types : [type];
2645
+ return members.every((m) => (m.flags & ctx.ts.TypeFlags.NumberLike) !== 0);
2646
+ }
2647
+ function printedValue(node, ctx) {
2648
+ const t = ctx.ts;
2649
+ if (t.isCallExpression(node)) {
2650
+ const callee = node.expression;
2651
+ if (t.isIdentifier(callee) && callee.text === "String" && node.arguments.length === 1 && isGlobalBuiltin(callee, ctx)) {
2652
+ return [node.arguments[0]];
2653
+ }
2654
+ if (t.isPropertyAccessExpression(callee)) {
2655
+ if (t.isIdentifier(callee.expression) && callee.expression.text === "JSON" && callee.name.text === "stringify" && node.arguments.length > 0 && isGlobalBuiltin(callee.expression, ctx)) {
2656
+ return [node.arguments[0]];
2657
+ }
2658
+ if (PRINTING_METHODS.has(callee.name.text))
2659
+ return [callee.expression];
2660
+ }
2661
+ return [];
2662
+ }
2663
+ if (t.isTemplateExpression(node) && !t.isTaggedTemplateExpression(node.parent)) {
2664
+ return node.templateSpans.filter((span) => !writesCssLength(span, ctx)).map((span) => span.expression);
2665
+ }
2666
+ if (t.isBinaryExpression(node) && node.operatorToken.kind === t.SyntaxKind.PlusToken) {
2667
+ const stringy = (e) => (ctx.checker.getTypeAtLocation(e).flags & t.TypeFlags.StringLike) !== 0;
2668
+ if (stringy(node.left))
2669
+ return [node.right];
2670
+ if (stringy(node.right))
2671
+ return [node.left];
2672
+ }
2673
+ return [];
2674
+ }
2675
+ var noHostPrintOfEastValues = {
2676
+ name: NAME28,
2677
+ code: CODE28,
2678
+ description: "Flag String()/toString()/toISOString()/JSON.stringify/template printing of a decoded East value JavaScript prints differently \u2014 use printFor(T) or the locale Formatters.",
2679
+ check(node, ctx) {
2680
+ const t = ctx.ts;
2681
+ if (!t.isCallExpression(node) && !t.isTemplateExpression(node) && !t.isBinaryExpression(node))
2682
+ return;
2683
+ if (!importsEastPackage(ctx.sourceFile, t))
2684
+ return;
2685
+ for (const value of printedValue(node, ctx)) {
2686
+ if (!jsPrintDiffers(ctx.checker.getTypeAtLocation(value), t))
2687
+ continue;
2688
+ if (!isEastValueExpression(value, ctx))
2689
+ continue;
2690
+ const sf = ctx.sourceFile;
2691
+ const start = value.getStart(sf);
2692
+ ctx.report({
2693
+ ruleName: NAME28,
2694
+ code: CODE28,
2695
+ start,
2696
+ length: value.getEnd() - start,
2697
+ messageText: "JavaScript prints this East value its own way \u2014 `5` for East's `5.0`, a DateTime in local time or with a `Z`, `[object Object]` for a struct. Print it with `printFor(T)`, or in the viewer's language with the locale `Formatters`.",
2698
+ category: "warning"
2699
+ });
2700
+ }
2701
+ }
2702
+ };
2703
+
2704
+ // ../east-diagnostics/dist/src/rules/no-host-parse-to-east-values.js
2705
+ var NAME29 = "no-host-parse-to-east-values";
2706
+ var CODE29 = 990034;
2707
+ var PARSERS = /* @__PURE__ */ new Set(["BigInt", "Number", "parseFloat", "parseInt"]);
2708
+ function isText(e, ctx) {
2709
+ return (ctx.checker.getTypeAtLocation(e).flags & ctx.ts.TypeFlags.StringLike) !== 0;
2710
+ }
2711
+ function literalText(e, t) {
2712
+ return t.isStringLiteral(e) || t.isNoSubstitutionTemplateLiteral(e) ? e.text : void 0;
2713
+ }
2714
+ var ZONELESS_DATE_TIME = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?$/;
2715
+ function parsesText(node, ctx) {
2716
+ const t = ctx.ts;
2717
+ const misread = (text, date) => {
2718
+ if (!isText(text, ctx))
2719
+ return false;
2720
+ const literal = literalText(text, t);
2721
+ return literal === void 0 || date && ZONELESS_DATE_TIME.test(literal);
2722
+ };
2723
+ if (t.isCallExpression(node)) {
2724
+ const callee = node.expression;
2725
+ const text = node.arguments[0];
2726
+ if (text === void 0)
2727
+ return false;
2728
+ if (t.isIdentifier(callee))
2729
+ return PARSERS.has(callee.text) && isGlobalBuiltin(callee, ctx) && misread(text, false);
2730
+ if (!t.isPropertyAccessExpression(callee) || !t.isIdentifier(callee.expression) || !isGlobalBuiltin(callee.expression, ctx))
2731
+ return false;
2732
+ if (callee.expression.text === "JSON" && callee.name.text === "parse")
2733
+ return misread(text, false);
2734
+ if (callee.expression.text === "Date" && callee.name.text === "parse")
2735
+ return misread(text, true);
2736
+ return false;
2737
+ }
2738
+ if (t.isNewExpression(node) && t.isIdentifier(node.expression) && node.expression.text === "Date") {
2739
+ const text = node.arguments?.[0];
2740
+ return node.arguments?.length === 1 && text !== void 0 && isGlobalBuiltin(node.expression, ctx) && misread(text, true);
2741
+ }
2742
+ return false;
2743
+ }
2744
+ var noHostParseToEastValues = {
2745
+ name: NAME29,
2746
+ code: CODE29,
2747
+ description: "Flag BigInt()/Number()/parseFloat()/parseInt()/JSON.parse()/new Date() reading text into an East slot \u2014 use parseFor(T) or East's datetime format.",
2748
+ check(node, ctx) {
2749
+ const t = ctx.ts;
2750
+ if (!t.isCallExpression(node) && !t.isNewExpression(node))
2751
+ return;
2752
+ if (!importsEastPackage(ctx.sourceFile, t))
2753
+ return;
2754
+ if (!parsesText(node, ctx))
2755
+ return;
2756
+ if (!landsInEastSlot(node, ctx))
2757
+ return;
2758
+ const sf = ctx.sourceFile;
2759
+ const start = node.getStart(sf);
2760
+ ctx.report({
2761
+ ruleName: NAME29,
2762
+ code: CODE29,
2763
+ start,
2764
+ length: node.getEnd() - start,
2765
+ messageText: 'A JavaScript parser reads this text into an East value wrongly \u2014 `BigInt("")` is 0, `BigInt("0x10")` is 16, `new Date(text)` reads local time. Read it with `parseFor(T)` (or East\'s datetime format) and act on its `success`.',
2766
+ category: "warning"
2767
+ });
2768
+ }
2769
+ };
2770
+
2771
+ // ../east-diagnostics/dist/src/rules/no-js-type-dispatch-on-east-values.js
2772
+ var NAME30 = "no-js-type-dispatch-on-east-values";
2773
+ var CODE30 = 990035;
2774
+ var noJsTypeDispatchOnEastValues = {
2775
+ name: NAME30,
2776
+ code: CODE30,
2777
+ description: "Flag typeof / instanceof on a decoded East value \u2014 dispatch on its East type (isValueOf) or its variant tag.",
2778
+ check(node, ctx) {
2779
+ const t = ctx.ts;
2780
+ let target;
2781
+ if (t.isTypeOfExpression(node))
2782
+ target = node.expression;
2783
+ else if (t.isBinaryExpression(node) && node.operatorToken.kind === t.SyntaxKind.InstanceOfKeyword)
2784
+ target = node.left;
2785
+ if (target === void 0)
2786
+ return;
2787
+ if (!importsEastPackage(ctx.sourceFile, t))
2788
+ return;
2789
+ if (!isEastValueExpression(target, ctx))
2790
+ return;
2791
+ const sf = ctx.sourceFile;
2792
+ const start = node.getStart(sf);
2793
+ ctx.report({
2794
+ ruleName: NAME30,
2795
+ code: CODE30,
2796
+ start,
2797
+ length: node.getEnd() - start,
2798
+ messageText: "`typeof` / `instanceof` asks JavaScript what this East value is, and loses its East type. Dispatch on its East type (`isValueOf(v, T)`, or the type it already has) or on its variant tag (`v.type`).",
2799
+ category: "warning"
2800
+ });
2801
+ }
2802
+ };
2803
+
2804
+ // ../east-diagnostics/dist/src/rules/no-js-collection-for-east-collection.js
2805
+ var NAME31 = "no-js-collection-for-east-collection";
2806
+ var CODE31 = 990036;
2807
+ function keyTypeOf(node, ctx) {
2808
+ const t = ctx.ts;
2809
+ const type = ctx.checker.getTypeAtLocation(node);
2810
+ if ((type.flags & t.TypeFlags.Object) === 0 || (type.objectFlags & t.ObjectFlags.Reference) === 0)
2811
+ return void 0;
2812
+ return ctx.checker.getTypeArguments(type)[0];
2813
+ }
2814
+ function keyedByIdentity(type, t) {
2815
+ const primitive = t.TypeFlags.StringLike | t.TypeFlags.NumberLike | t.TypeFlags.BigIntLike | t.TypeFlags.BooleanLike | t.TypeFlags.EnumLike | t.TypeFlags.ESSymbolLike | t.TypeFlags.Null | t.TypeFlags.Undefined;
2816
+ const members = type.isUnion() ? type.types : [type];
2817
+ return members.some((m) => {
2818
+ if (m.isIntersection())
2819
+ return m.types.every((part) => (part.flags & primitive) === 0);
2820
+ return (m.flags & (t.TypeFlags.Object | t.TypeFlags.NonPrimitive)) !== 0;
2821
+ });
2822
+ }
2823
+ var noJsCollectionForEastCollection = {
2824
+ name: NAME31,
2825
+ code: CODE31,
2826
+ description: "Flag new Set()/new Map() of object keys (structs, variants, DateTimes, Blobs) landing in an East Set or Dict \u2014 build SortedSet/SortedMap with compareFor(K).",
2827
+ check(node, ctx) {
2828
+ const t = ctx.ts;
2829
+ if (!t.isNewExpression(node) || !t.isIdentifier(node.expression))
2830
+ return;
2831
+ const kind = node.expression.text;
2832
+ if (kind !== "Set" && kind !== "Map")
2833
+ return;
2834
+ if (!importsEastPackage(ctx.sourceFile, t))
2835
+ return;
2836
+ if (!isGlobalBuiltin(node.expression, ctx))
2837
+ return;
2838
+ const key = keyTypeOf(node, ctx);
2839
+ if (key === void 0 || !keyedByIdentity(key, t))
2840
+ return;
2841
+ if (!landsInEastSlot(node, ctx))
2842
+ return;
2843
+ const sf = ctx.sourceFile;
2844
+ const start = node.getStart(sf);
2845
+ ctx.report({
2846
+ ruleName: NAME31,
2847
+ code: CODE31,
2848
+ start,
2849
+ length: node.getEnd() - start,
2850
+ messageText: kind === "Set" ? "A JavaScript `Set` finds a struct, variant, DateTime or Blob member by identity, so an equal value built elsewhere misses it. Build `new SortedSet(values, compareFor(K))`." : "A JavaScript `Map` finds a struct, variant, DateTime or Blob key by identity, so an equal key built elsewhere misses its entry. Build `new SortedMap(entries, compareFor(K))`.",
2851
+ category: "warning"
2852
+ });
2853
+ }
2854
+ };
2855
+
2856
+ // ../east-diagnostics/dist/src/rules/index.js
2857
+ var allRules = [
2858
+ // East-side idiom hygiene (original set)
2859
+ noRedundantEastCast,
2860
+ preferExplicitEastType,
2861
+ preferSomeNone,
2862
+ noHandrolledVariant,
2863
+ noEastNamespacedType,
2864
+ preferLetConstOverEastValue,
2865
+ noRelativeSrcImport,
2866
+ noLetConstInExpression,
2867
+ noUnexecutedEastExpression,
2868
+ noReinlinedEastBinding,
2869
+ preferJsxOverFactoryCall,
2870
+ noUntrackedEastData,
2871
+ // host-vs-East family: the general block rule + the module-scope macro rule,
2872
+ // plus the separate build-time-data concerns (ingestion primitives, and
2873
+ // host-computed e3.input seed data)
2874
+ noHostInEastBlock,
2875
+ noModuleScopeEastMacro,
2876
+ noCompileTimeDataInjection,
2877
+ noCompileTimeSeedData,
2878
+ // deploy/runtime-failure classes that type-check clean (epic #208)
2879
+ requireRunnerPlatforms,
2880
+ noCrossBlockBuilder,
2881
+ noStateOutsideReactive,
2882
+ preferConstUiCallbacks,
2883
+ noDynamicBindPath,
2884
+ noBuildTimeClock,
2885
+ noHandrolledValueTypeMirror,
2886
+ noHostComparisonOnEastValues,
2887
+ requireExampleReturns,
2888
+ noDuplicateDefinitionName,
2889
+ // secrets hygiene: IR is content-addressed and replicated — no literal creds
2890
+ noInlineCredentials,
2891
+ // host code holding DECODED East values: print, read, dispatch and collect
2892
+ // them through East (#963) — with noHostComparisonOnEastValues and
2893
+ // noHandrolledValueTypeMirror above
2894
+ noHostPrintOfEastValues,
2895
+ noHostParseToEastValues,
2896
+ noJsTypeDispatchOnEastValues,
2897
+ noJsCollectionForEastCollection
2898
+ ];
2899
+
2900
+ // ../east-diagnostics/dist/src/run.js
2901
+ function runEastRules(tsModule, program, sourceFile, checker, options = {}, rules = allRules) {
2902
+ if (unresolvedEastImport(sourceFile, checker, tsModule))
2903
+ return [];
2904
+ const diagnostics = [];
2905
+ const ctx = {
2906
+ ts: tsModule,
2907
+ sourceFile,
2908
+ checker,
2909
+ program,
2910
+ options,
2911
+ report: (d) => diagnostics.push(d)
2912
+ };
2913
+ const disabled = new Set(options.disabled ?? []);
2914
+ const only = options.only === void 0 ? void 0 : new Set(options.only);
2915
+ const active = rules.filter((rule) => !disabled.has(rule.name) && (only === void 0 || only.has(rule.name)));
2916
+ const visit = (node) => {
2917
+ for (const rule of active)
2918
+ rule.check(node, ctx);
2919
+ tsModule.forEachChild(node, visit);
2920
+ };
2921
+ visit(sourceFile);
2922
+ return diagnostics;
2923
+ }
2924
+
2925
+ // ../east-diagnostics/dist/src/service.js
2926
+ import { createRequire as createRequire2 } from "node:module";
2927
+ import { existsSync as existsSync2, readFileSync } from "node:fs";
2928
+ import { dirname as dirname2, join as join3, resolve as resolve2 } from "node:path";
2929
+
2930
+ // ../east-diagnostics/dist/src/east-module.js
2931
+ import { createRequire } from "node:module";
2932
+ import { join as join2 } from "node:path";
2933
+ import { pathToFileURL } from "node:url";
2934
+ var cache = /* @__PURE__ */ new Map();
2935
+ var pendingImports = /* @__PURE__ */ new Set();
2936
+ function validate(candidate) {
2937
+ const m = candidate;
2938
+ const mod = (typeof m?.["diffTypes"] === "function" ? m : m?.["default"]) ?? void 0;
2939
+ if (mod === void 0)
2940
+ return null;
2941
+ const fns = ["diffTypes", "renderTypeDiff", "StructType", "VariantType", "ArrayType", "RecursiveType", "FunctionType", "TypeUnion"];
2942
+ for (const f of fns)
2943
+ if (typeof mod[f] !== "function")
2944
+ return null;
2945
+ if (mod["IntegerType"] === void 0)
2946
+ return null;
2947
+ return mod;
2948
+ }
2949
+ function getEastModule(projectDir) {
2950
+ const cached = cache.get(projectDir);
2951
+ if (cached !== void 0)
2952
+ return cached ?? void 0;
2953
+ const require_ = createRequire(join2(projectDir, "_.js"));
2954
+ let entry;
2955
+ try {
2956
+ entry = require_.resolve("@elaraai/east");
2957
+ } catch {
2958
+ cache.set(projectDir, null);
2959
+ return void 0;
2960
+ }
2961
+ try {
2962
+ const mod = validate(require_(entry));
2963
+ cache.set(projectDir, mod);
2964
+ return mod ?? void 0;
2965
+ } catch {
2966
+ if (!pendingImports.has(projectDir)) {
2967
+ pendingImports.add(projectDir);
2968
+ import(pathToFileURL(entry).href).then((m) => cache.set(projectDir, validate(m)), () => cache.set(projectDir, null));
2969
+ }
2970
+ return void 0;
2971
+ }
2972
+ }
2973
+
2974
+ // ../east-diagnostics/dist/src/type-reify.js
2975
+ var PRIMITIVE_TAGS = /* @__PURE__ */ new Set(["Never", "Null", "Boolean", "Integer", "Float", "String", "DateTime", "Blob"]);
2976
+ var MAX_DEPTH = 32;
2977
+ var Bail = class extends Error {
2978
+ };
2979
+ function bail() {
2980
+ throw new Bail();
2981
+ }
2982
+ function propType(ctx, type, name) {
2983
+ const symbol = ctx.checker.getPropertyOfType(type, name);
2984
+ if (symbol === void 0)
2985
+ return void 0;
2986
+ return ctx.checker.getTypeOfSymbol(symbol);
2987
+ }
2988
+ function literalString(type) {
2989
+ return type !== void 0 && type.isStringLiteral() ? type.value : void 0;
2990
+ }
2991
+ function typeArguments(ctx, type) {
2992
+ const { t, checker } = ctx;
2993
+ if ((type.flags & t.TypeFlags.Object) === 0)
2994
+ return [];
2995
+ if ((type.objectFlags & t.ObjectFlags.Reference) === 0)
2996
+ return [];
2997
+ return checker.getTypeArguments(type);
2998
+ }
2999
+ function stripAbsent(ctx, type) {
3000
+ const members = type.isUnion() ? type.types : [type];
3001
+ return members.filter((m) => (m.flags & (ctx.t.TypeFlags.Undefined | ctx.t.TypeFlags.Void)) === 0);
3002
+ }
3003
+ function reifyUnion(ctx, members) {
3004
+ const reified = [];
3005
+ for (const m of members) {
3006
+ try {
3007
+ reified.push(walk(ctx, m));
3008
+ } catch (e) {
3009
+ if (!(e instanceof Bail))
3010
+ throw e;
3011
+ }
3012
+ }
3013
+ if (reified.length === 0)
3014
+ bail();
3015
+ const distinct = [...new Set(reified)];
3016
+ const nonNever = distinct.filter((r) => r !== ctx.east.NeverType);
3017
+ const candidates = nonNever.length > 0 ? nonNever : distinct;
3018
+ if (candidates.length === 1)
3019
+ return candidates[0];
3020
+ try {
3021
+ return candidates.reduce((a, b) => ctx.east.TypeUnion(a, b));
3022
+ } catch {
3023
+ bail();
3024
+ }
3025
+ }
3026
+ function reifyEncoding(ctx, type, tag) {
3027
+ const { east, checker } = ctx;
3028
+ if (PRIMITIVE_TAGS.has(tag))
3029
+ return east[`${tag}Type`];
3030
+ switch (tag) {
3031
+ case "Ref": {
3032
+ const v = propType(ctx, type, "value") ?? bail();
3033
+ return east.RefType(walk(ctx, v));
3034
+ }
3035
+ case "Array": {
3036
+ const v = propType(ctx, type, "value") ?? bail();
3037
+ return east.ArrayType(walk(ctx, v));
3038
+ }
3039
+ case "Set": {
3040
+ const k = propType(ctx, type, "key") ?? bail();
3041
+ return east.SetType(walk(ctx, k));
3042
+ }
3043
+ case "Dict": {
3044
+ const k = propType(ctx, type, "key") ?? bail();
3045
+ const v = propType(ctx, type, "value") ?? bail();
3046
+ return east.DictType(walk(ctx, k), walk(ctx, v));
3047
+ }
3048
+ case "Vector": {
3049
+ const e = propType(ctx, type, "element") ?? bail();
3050
+ return east.VectorType(walk(ctx, e));
3051
+ }
3052
+ case "Matrix": {
3053
+ const e = propType(ctx, type, "element") ?? bail();
3054
+ return east.MatrixType(walk(ctx, e));
3055
+ }
3056
+ case "Struct": {
3057
+ const fieldsType = propType(ctx, type, "fields") ?? bail();
3058
+ const fields = {};
3059
+ for (const prop of checker.getPropertiesOfType(fieldsType)) {
3060
+ const name = prop.getName();
3061
+ if (name.startsWith("__@"))
3062
+ continue;
3063
+ fields[name] = reifyUnion(ctx, stripAbsent(ctx, checker.getTypeOfSymbol(prop)));
3064
+ }
3065
+ return east.StructType(fields);
3066
+ }
3067
+ case "Variant": {
3068
+ const casesType = propType(ctx, type, "cases") ?? bail();
3069
+ const cases = {};
3070
+ for (const prop of checker.getPropertiesOfType(casesType)) {
3071
+ const name = prop.getName();
3072
+ if (name.startsWith("__@"))
3073
+ continue;
3074
+ cases[name] = reifyUnion(ctx, stripAbsent(ctx, checker.getTypeOfSymbol(prop)));
3075
+ }
3076
+ return east.VariantType(cases);
3077
+ }
3078
+ case "Function":
3079
+ case "AsyncFunction": {
3080
+ const inputsType = propType(ctx, type, "inputs") ?? bail();
3081
+ if (!checker.isTupleType(inputsType))
3082
+ bail();
3083
+ const inputs = typeArguments(ctx, inputsType).map((i) => walk(ctx, i));
3084
+ const output = walk(ctx, propType(ctx, type, "output") ?? bail());
3085
+ return tag === "Function" ? east.FunctionType(inputs, output) : east.AsyncFunctionType(inputs, output);
3086
+ }
3087
+ case "Recursive": {
3088
+ const node = propType(ctx, type, "node");
3089
+ if (node === void 0) {
3090
+ if (ctx.selves.length === 0)
3091
+ bail();
3092
+ return ctx.selves[ctx.selves.length - 1];
3093
+ }
3094
+ return ctx.east.RecursiveType((self) => {
3095
+ ctx.selves.push(self);
3096
+ try {
3097
+ return walk(ctx, node);
3098
+ } finally {
3099
+ ctx.selves.pop();
3100
+ }
3101
+ });
3102
+ }
3103
+ default:
3104
+ bail();
3105
+ }
3106
+ }
3107
+ function reifyRawValue(ctx, type) {
3108
+ const { t, east, checker } = ctx;
3109
+ const f = type.flags;
3110
+ if (f & (t.TypeFlags.BigInt | t.TypeFlags.BigIntLiteral))
3111
+ return east.IntegerType;
3112
+ if (f & (t.TypeFlags.Number | t.TypeFlags.NumberLiteral))
3113
+ return east.FloatType;
3114
+ if (f & (t.TypeFlags.String | t.TypeFlags.StringLiteral | t.TypeFlags.TemplateLiteral))
3115
+ return east.StringType;
3116
+ if (f & (t.TypeFlags.Boolean | t.TypeFlags.BooleanLiteral))
3117
+ return east.BooleanType;
3118
+ if (f & t.TypeFlags.Null)
3119
+ return east.NullType;
3120
+ if ((f & t.TypeFlags.Object) === 0)
3121
+ bail();
3122
+ const name = type.getSymbol()?.getName();
3123
+ switch (name) {
3124
+ case "Date":
3125
+ return east.DateTimeType;
3126
+ case "Uint8Array":
3127
+ return east.BlobType;
3128
+ case "Float64Array":
3129
+ return east.VectorType(east.FloatType);
3130
+ case "BigInt64Array":
3131
+ return east.VectorType(east.IntegerType);
3132
+ case "Uint8ClampedArray":
3133
+ return east.VectorType(east.BooleanType);
3134
+ case "Array":
3135
+ case "ReadonlyArray": {
3136
+ const [el] = typeArguments(ctx, type);
3137
+ if (el === void 0)
3138
+ bail();
3139
+ return east.ArrayType(reifyUnion(ctx, stripAbsent(ctx, el)));
3140
+ }
3141
+ case "Set":
3142
+ case "ReadonlySet": {
3143
+ const [el] = typeArguments(ctx, type);
3144
+ if (el === void 0)
3145
+ bail();
3146
+ return east.SetType(reifyUnion(ctx, stripAbsent(ctx, el)));
3147
+ }
3148
+ case "Map":
3149
+ case "ReadonlyMap": {
3150
+ const [k, v] = typeArguments(ctx, type);
3151
+ if (k === void 0 || v === void 0)
3152
+ bail();
3153
+ return east.DictType(reifyUnion(ctx, stripAbsent(ctx, k)), reifyUnion(ctx, stripAbsent(ctx, v)));
3154
+ }
3155
+ default:
3156
+ break;
3157
+ }
3158
+ if (checker.isTupleType(type)) {
3159
+ const elements = typeArguments(ctx, type).map((e) => reifyUnion(ctx, stripAbsent(ctx, e)));
3160
+ const distinct = new Set(elements);
3161
+ if (distinct.size !== 1)
3162
+ bail();
3163
+ return east.ArrayType(elements[0]);
3164
+ }
3165
+ if (type.getCallSignatures().length > 0 || type.getConstructSignatures().length > 0)
3166
+ bail();
3167
+ if (checker.getIndexInfosOfType(type).length > 0)
3168
+ bail();
3169
+ const props = checker.getPropertiesOfType(type);
3170
+ if (props.length === 0)
3171
+ bail();
3172
+ const fields = {};
3173
+ for (const prop of props) {
3174
+ const propName = prop.getName();
3175
+ if (propName.startsWith("__@"))
3176
+ continue;
3177
+ fields[propName] = reifyUnion(ctx, stripAbsent(ctx, checker.getTypeOfSymbol(prop)));
3178
+ }
3179
+ return east.StructType(fields);
3180
+ }
3181
+ function walk(ctx, type) {
3182
+ if (++ctx.depth > MAX_DEPTH)
3183
+ bail();
3184
+ try {
3185
+ if (type.isUnion())
3186
+ return reifyUnion(ctx, stripAbsent(ctx, type));
3187
+ const properties = type.getProperties();
3188
+ const exprTypeProp = properties.find((p) => p.getName().startsWith("__@TypeSymbol"));
3189
+ if (exprTypeProp !== void 0) {
3190
+ ctx.sawEastShape = true;
3191
+ return walk(ctx, ctx.checker.getTypeOfSymbol(exprTypeProp));
3192
+ }
3193
+ if (properties.some((p) => p.getName().startsWith("__@variant_symbol"))) {
3194
+ const caseName = literalString(propType(ctx, type, "type")) ?? bail();
3195
+ const payload = propType(ctx, type, "value") ?? bail();
3196
+ ctx.sawEastShape = true;
3197
+ return ctx.east.VariantType({ [caseName]: reifyUnion(ctx, stripAbsent(ctx, payload)) });
3198
+ }
3199
+ if (properties.some((p) => p.getName().startsWith("__@ref_symbol"))) {
3200
+ const v = propType(ctx, type, "value") ?? bail();
3201
+ ctx.sawEastShape = true;
3202
+ return ctx.east.RefType(reifyUnion(ctx, stripAbsent(ctx, v)));
3203
+ }
3204
+ const tag = literalString(propType(ctx, type, "type"));
3205
+ if (tag !== void 0) {
3206
+ try {
3207
+ const result = reifyEncoding(ctx, type, tag);
3208
+ ctx.sawEastShape = true;
3209
+ return result;
3210
+ } catch (e) {
3211
+ if (!(e instanceof Bail))
3212
+ throw e;
3213
+ }
3214
+ }
3215
+ return reifyRawValue(ctx, type);
3216
+ } finally {
3217
+ ctx.depth--;
3218
+ }
3219
+ }
3220
+ function reifyEastType(t, checker, type, east) {
3221
+ const ctx = { t, checker, east, depth: 0, selves: [], sawEastShape: false };
3222
+ try {
3223
+ return { type: walk(ctx, type), eastShaped: ctx.sawEastShape };
3224
+ } catch (e) {
3225
+ if (e instanceof Bail)
3226
+ return void 0;
3227
+ return void 0;
3228
+ }
3229
+ }
3230
+
3231
+ // ../east-diagnostics/dist/src/type-diff-rewrite.js
3232
+ var ASSIGNABILITY_CODES = /* @__PURE__ */ new Set([
3233
+ 2322,
3234
+ // Type 'X' is not assignable to type 'Y'.
3235
+ 2345,
3236
+ // Argument of type 'X' is not assignable to parameter of type 'Y'.
3237
+ 2375,
3238
+ // Type 'X' is not assignable to type 'Y' with exactOptionalPropertyTypes.
3239
+ 2379,
3240
+ // Getter/setter assignability variant of 2322.
3241
+ 2412,
3242
+ // Property assignability with exactOptionalPropertyTypes.
3243
+ 2719,
3244
+ // Type 'X' is not assignable to type 'Y'. Two different types with this name exist.
3245
+ 2739,
3246
+ // Type 'X' is missing the following properties from type 'Y'.
3247
+ 2740,
3248
+ // Type 'X' is missing the following properties from type 'Y' (array forms).
3249
+ 2741
3250
+ // Property 'p' is missing in type 'X' but required in type 'Y'.
3251
+ ]);
3252
+ function innermostNodeAt(t, sourceFile, position) {
3253
+ function find(node) {
3254
+ if (position < node.getStart(sourceFile) || position >= node.getEnd())
3255
+ return void 0;
3256
+ return t.forEachChild(node, find) ?? node;
3257
+ }
3258
+ return find(sourceFile);
3259
+ }
3260
+ function resolveTypePair(t, checker, node) {
3261
+ let current = node;
3262
+ for (let hops = 0; current !== void 0 && hops < 6; current = current.parent, hops++) {
3263
+ if (t.isVariableDeclaration(current) && current.type !== void 0 && current.initializer !== void 0) {
3264
+ return {
3265
+ actual: checker.getTypeAtLocation(current.initializer),
3266
+ expected: checker.getTypeFromTypeNode(current.type)
3267
+ };
3268
+ }
3269
+ if (t.isPropertyAssignment(current)) {
3270
+ const expected = checker.getContextualType(current.initializer);
3271
+ if (expected !== void 0) {
3272
+ return { actual: checker.getTypeAtLocation(current.initializer), expected };
3273
+ }
3274
+ }
3275
+ if (t.isExpression(current)) {
3276
+ const expected = checker.getContextualType(current);
3277
+ if (expected !== void 0) {
3278
+ return { actual: checker.getTypeAtLocation(current), expected };
3279
+ }
3280
+ }
3281
+ }
3282
+ return void 0;
3283
+ }
3284
+ function rewriteEastAssignability(t, program, sourceFile, diagnostic, east) {
3285
+ if (diagnostic.start === void 0 || !ASSIGNABILITY_CODES.has(diagnostic.code))
3286
+ return void 0;
3287
+ const checker = program.getTypeChecker();
3288
+ const node = innermostNodeAt(t, sourceFile, diagnostic.start);
3289
+ if (node === void 0)
3290
+ return void 0;
3291
+ const pair = resolveTypePair(t, checker, node);
3292
+ if (pair === void 0)
3293
+ return void 0;
3294
+ const actual = reifyEastType(t, checker, pair.actual, east);
3295
+ const expected = reifyEastType(t, checker, pair.expected, east);
3296
+ if (actual === void 0 || expected === void 0)
3297
+ return void 0;
3298
+ if (!actual.eastShaped && !expected.eastShaped)
3299
+ return void 0;
3300
+ if (expected.type === east.NeverType && actual.type !== east.NeverType)
3301
+ return void 0;
3302
+ let rendered;
3303
+ try {
3304
+ const diffs = east.diffTypes(actual.type, expected.type);
3305
+ if (!Array.isArray(diffs) || diffs.length === 0)
3306
+ return void 0;
3307
+ rendered = east.renderTypeDiff(diffs);
3308
+ } catch {
3309
+ return void 0;
3310
+ }
3311
+ if (rendered.length === 0)
3312
+ return void 0;
3313
+ return `East type mismatch: ${rendered.split("\n").join("; ")}`;
3314
+ }
3315
+
3316
+ // ../east-diagnostics/dist/src/service.js
3317
+ var MAX_MESSAGE_LENGTH = 300;
3318
+ var MAX_REWRITTEN_LENGTH = 600;
3319
+ function findNearestTsconfig(fromPath) {
3320
+ let dir = dirname2(resolve2(fromPath));
3321
+ for (; ; ) {
3322
+ const candidate = join3(dir, "tsconfig.json");
3323
+ if (existsSync2(candidate))
3324
+ return candidate;
3325
+ const parent = dirname2(dir);
3326
+ if (parent === dir)
3327
+ return void 0;
3328
+ dir = parent;
3329
+ }
3330
+ }
3331
+ function loadTypeScript(projectDir) {
3332
+ try {
3333
+ return createRequire2(join3(projectDir, "_.js"))("typescript");
3334
+ } catch {
3335
+ return createRequire2(import.meta.url)("typescript");
3336
+ }
3337
+ }
3338
+ function toCategory(t, category) {
3339
+ if (category === t.DiagnosticCategory.Error)
3340
+ return "error";
3341
+ if (category === t.DiagnosticCategory.Warning)
3342
+ return "warning";
3343
+ return "suggestion";
3344
+ }
3345
+ function createDiagnosticsService(options = {}) {
3346
+ const projects = /* @__PURE__ */ new Map();
3347
+ const overlays = /* @__PURE__ */ new Map();
3348
+ function getProject(tsconfigPath) {
3349
+ const existing = projects.get(tsconfigPath);
3350
+ if (existing !== void 0)
3351
+ return existing;
3352
+ const projectDir = dirname2(tsconfigPath);
3353
+ const t = loadTypeScript(projectDir);
3354
+ const configFile = t.readConfigFile(tsconfigPath, t.sys.readFile);
3355
+ const parsed = t.parseJsonConfigFileContent(configFile.config ?? {}, t.sys, projectDir);
3356
+ const project = {
3357
+ ts: t,
3358
+ service: void 0,
3359
+ rootFileNames: new Set(parsed.fileNames.map((f) => resolve2(f))),
3360
+ adHoc: /* @__PURE__ */ new Set(),
3361
+ versions: /* @__PURE__ */ new Map()
3362
+ };
3363
+ const host = {
3364
+ getScriptFileNames: () => [...project.rootFileNames, ...project.adHoc],
3365
+ getScriptVersion: (f) => String(project.versions.get(resolve2(f)) ?? 0),
3366
+ getScriptSnapshot: (f) => {
3367
+ const path = resolve2(f);
3368
+ const overlay = overlays.get(path);
3369
+ if (overlay !== void 0)
3370
+ return t.ScriptSnapshot.fromString(overlay);
3371
+ if (!existsSync2(path))
3372
+ return void 0;
3373
+ return t.ScriptSnapshot.fromString(readFileSync(path, "utf-8"));
3374
+ },
3375
+ getCurrentDirectory: () => projectDir,
3376
+ getCompilationSettings: () => parsed.options,
3377
+ getDefaultLibFileName: (o) => t.getDefaultLibFilePath(o),
3378
+ fileExists: (f) => overlays.has(resolve2(f)) || t.sys.fileExists(f),
3379
+ readFile: t.sys.readFile,
3380
+ readDirectory: t.sys.readDirectory,
3381
+ directoryExists: t.sys.directoryExists,
3382
+ getDirectories: t.sys.getDirectories
3383
+ };
3384
+ if (t.sys.realpath !== void 0)
3385
+ host.realpath = t.sys.realpath;
3386
+ project.service = t.createLanguageService(host, t.createDocumentRegistry());
3387
+ projects.set(tsconfigPath, project);
3388
+ return project;
3389
+ }
3390
+ function analyze(filePath) {
3391
+ const file = resolve2(filePath);
3392
+ const tsconfigPath = findNearestTsconfig(file);
3393
+ if (tsconfigPath === void 0)
3394
+ return void 0;
3395
+ const project = getProject(tsconfigPath);
3396
+ const t = project.ts;
3397
+ if (!project.rootFileNames.has(file))
3398
+ project.adHoc.add(file);
3399
+ project.versions.set(file, (project.versions.get(file) ?? 0) + 1);
3400
+ const program = project.service.getProgram();
3401
+ const sourceFile = program?.getSourceFile(file);
3402
+ if (program === void 0 || sourceFile === void 0)
3403
+ return void 0;
3404
+ const native = [
3405
+ ...project.service.getSemanticDiagnostics(file),
3406
+ ...project.service.getSyntacticDiagnostics(file)
3407
+ ];
3408
+ const projectDir = dirname2(tsconfigPath);
3409
+ const nativeDiagnostics = native.flatMap((d) => {
3410
+ if (d.start === void 0 || d.length === void 0)
3411
+ return [];
3412
+ let message = t.flattenDiagnosticMessageText(d.messageText, " ");
3413
+ let maxLength = MAX_MESSAGE_LENGTH;
3414
+ if (ASSIGNABILITY_CODES.has(d.code)) {
3415
+ const east = getEastModule(projectDir);
3416
+ const rewritten = east !== void 0 ? rewriteEastAssignability(t, program, sourceFile, d, east) : void 0;
3417
+ if (rewritten !== void 0) {
3418
+ message = rewritten;
3419
+ maxLength = MAX_REWRITTEN_LENGTH;
3420
+ }
3421
+ }
3422
+ return [{
3423
+ ruleName: "tsc",
3424
+ code: d.code,
3425
+ start: d.start,
3426
+ length: d.length,
3427
+ messageText: message.length > maxLength ? `${message.slice(0, maxLength)}\u2026` : message,
3428
+ category: toCategory(t, d.category)
3429
+ }];
3430
+ });
3431
+ const ruleDiagnostics = runEastRules(t, program, sourceFile, program.getTypeChecker(), options.rulesOptions ?? {}, options.rules);
3432
+ const diagnostics = [...nativeDiagnostics, ...ruleDiagnostics].sort((a, b) => a.start - b.start);
3433
+ return { diagnostics, sourceFile };
3434
+ }
3435
+ return {
3436
+ diagnose(filePath) {
3437
+ return analyze(filePath)?.diagnostics ?? [];
3438
+ },
3439
+ diagnoseText(filePath) {
3440
+ const result = analyze(filePath);
3441
+ if (result === void 0 || result.diagnostics.length === 0)
3442
+ return "";
3443
+ const { diagnostics, sourceFile } = result;
3444
+ const lines = diagnostics.map((d) => {
3445
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(d.start);
3446
+ const label = d.ruleName === "tsc" ? `TS${d.code}` : d.ruleName;
3447
+ return `- [${d.category}] ${line + 1}:${character + 1} (${label}) ${d.messageText}`;
3448
+ });
3449
+ return ["<east-code-review>", "## East issues in this file", "", ...lines, "</east-code-review>"].join("\n");
3450
+ },
3451
+ warm(fromDir) {
3452
+ const tsconfigPath = findNearestTsconfig(join3(resolve2(fromDir), "_.ts"));
3453
+ if (tsconfigPath === void 0)
3454
+ return false;
3455
+ const project = getProject(tsconfigPath);
3456
+ const [firstRoot] = project.rootFileNames;
3457
+ if (firstRoot !== void 0)
3458
+ project.service.getSemanticDiagnostics(firstRoot);
3459
+ else
3460
+ project.service.getProgram();
3461
+ return true;
3462
+ },
3463
+ setOverlay(filePath, content) {
3464
+ overlays.set(resolve2(filePath), content);
3465
+ },
3466
+ clearOverlay(filePath) {
3467
+ overlays.delete(resolve2(filePath));
3468
+ },
3469
+ dispose() {
3470
+ projects.clear();
3471
+ overlays.clear();
3472
+ }
3473
+ };
3474
+ }
3475
+
3476
+ // ../east-diagnostics/dist/src/lsp.js
3477
+ import { readFileSync as readFileSync2 } from "node:fs";
3478
+ import { fileURLToPath } from "node:url";
3479
+
3480
+ // ../east-diagnostics/dist/src/jsonrpc-stdio.js
3481
+ function frame(message) {
3482
+ const body = JSON.stringify({ jsonrpc: "2.0", ...message });
3483
+ return `Content-Length: ${Buffer.byteLength(body, "utf8")}\r
3484
+ \r
3485
+ ${body}`;
3486
+ }
3487
+ var FrameReader = class {
3488
+ onMessage;
3489
+ buffer = Buffer.alloc(0);
3490
+ constructor(onMessage) {
3491
+ this.onMessage = onMessage;
3492
+ }
3493
+ push(chunk) {
3494
+ this.buffer = Buffer.concat([this.buffer, chunk]);
3495
+ for (; ; ) {
3496
+ const headerEnd = this.buffer.indexOf("\r\n\r\n");
3497
+ if (headerEnd < 0)
3498
+ return;
3499
+ const header = this.buffer.subarray(0, headerEnd).toString("utf8");
3500
+ const match = /Content-Length:\s*(\d+)/i.exec(header);
3501
+ if (match === null) {
3502
+ this.buffer = this.buffer.subarray(headerEnd + 4);
3503
+ continue;
3504
+ }
3505
+ const length = Number(match[1]);
3506
+ const bodyStart = headerEnd + 4;
3507
+ if (this.buffer.length < bodyStart + length)
3508
+ return;
3509
+ const body = this.buffer.subarray(bodyStart, bodyStart + length).toString("utf8");
3510
+ this.buffer = this.buffer.subarray(bodyStart + length);
3511
+ let message;
3512
+ try {
3513
+ message = JSON.parse(body);
3514
+ } catch {
3515
+ continue;
3516
+ }
3517
+ this.onMessage(message);
3518
+ }
3519
+ }
3520
+ reset() {
3521
+ this.buffer = Buffer.alloc(0);
3522
+ }
3523
+ };
3524
+
3525
+ // ../east-diagnostics/dist/src/lsp.js
3526
+ var EAST_IMPORT_PATTERN = /@elaraai\//;
3527
+ var SKIP_PATH = /[/\\](node_modules|dist|build|\.venv|\.git)[/\\]/;
3528
+ var DEBOUNCE_MS = 100;
3529
+ var SEVERITY = {
3530
+ error: 1,
3531
+ warning: 2,
3532
+ suggestion: 3
3533
+ };
3534
+ function lineStarts(content) {
3535
+ const starts = [0];
3536
+ for (let i = 0; i < content.length; i++) {
3537
+ if (content[i] === "\n")
3538
+ starts.push(i + 1);
3539
+ }
3540
+ return starts;
3541
+ }
3542
+ function offsetToPosition(starts, offset) {
3543
+ let low = 0;
3544
+ let high = starts.length - 1;
3545
+ while (low < high) {
3546
+ const mid = low + high + 1 >> 1;
3547
+ if (starts[mid] <= offset)
3548
+ low = mid;
3549
+ else
3550
+ high = mid - 1;
3551
+ }
3552
+ return { line: low, character: offset - starts[low] };
3553
+ }
3554
+ function uriToPath(uri) {
3555
+ if (!uri.startsWith("file://"))
3556
+ return void 0;
3557
+ try {
3558
+ return fileURLToPath(uri);
3559
+ } catch {
3560
+ return void 0;
3561
+ }
3562
+ }
3563
+ function runEastLsp(options = {}) {
3564
+ const service = options.service ?? createDiagnosticsService();
3565
+ const input = options.input ?? process.stdin;
3566
+ const output = options.output ?? process.stdout;
3567
+ const exit = options.exit ?? ((code) => process.exit(code));
3568
+ const open = /* @__PURE__ */ new Map();
3569
+ const pending = /* @__PURE__ */ new Map();
3570
+ let shuttingDown = false;
3571
+ function send(message) {
3572
+ output.write(frame(message));
3573
+ }
3574
+ function publish(path) {
3575
+ const content = open.get(path) ?? (() => {
3576
+ try {
3577
+ return readFileSync2(path, "utf-8");
3578
+ } catch {
3579
+ return void 0;
3580
+ }
3581
+ })();
3582
+ let diagnostics = [];
3583
+ if (content !== void 0 && !SKIP_PATH.test(path) && EAST_IMPORT_PATTERN.test(content)) {
3584
+ const starts = lineStarts(content);
3585
+ diagnostics = service.diagnose(path).map((d) => ({
3586
+ range: {
3587
+ start: offsetToPosition(starts, d.start),
3588
+ end: offsetToPosition(starts, d.start + d.length)
3589
+ },
3590
+ severity: SEVERITY[d.category],
3591
+ code: d.ruleName === "tsc" ? `TS${d.code}` : d.ruleName,
3592
+ source: "east",
3593
+ message: d.messageText
3594
+ }));
3595
+ }
3596
+ send({ method: "textDocument/publishDiagnostics", params: { uri: `file://${path}`, diagnostics } });
3597
+ }
3598
+ function schedule(path) {
3599
+ const existing = pending.get(path);
3600
+ if (existing !== void 0)
3601
+ clearTimeout(existing);
3602
+ pending.set(path, setTimeout(() => {
3603
+ pending.delete(path);
3604
+ try {
3605
+ publish(path);
3606
+ } catch {
3607
+ }
3608
+ }, DEBOUNCE_MS));
3609
+ }
3610
+ function notOurs(path) {
3611
+ if (!path.endsWith(".py"))
3612
+ return false;
3613
+ send({ method: "textDocument/publishDiagnostics", params: { uri: `file://${path}`, diagnostics: [] } });
3614
+ return true;
3615
+ }
3616
+ function handle(message) {
3617
+ const { method, id, params } = message;
3618
+ if (method === void 0)
3619
+ return;
3620
+ switch (method) {
3621
+ case "initialize": {
3622
+ const folders = [];
3623
+ const root = params?.rootUri ?? params?.rootPath;
3624
+ if (typeof root === "string") {
3625
+ const p = root.startsWith("file://") ? uriToPath(root) : root;
3626
+ if (p !== void 0)
3627
+ folders.push(p);
3628
+ }
3629
+ for (const f of params?.workspaceFolders ?? []) {
3630
+ const p = uriToPath(f?.uri ?? "");
3631
+ if (p !== void 0)
3632
+ folders.push(p);
3633
+ }
3634
+ send({
3635
+ id,
3636
+ result: {
3637
+ capabilities: {
3638
+ textDocumentSync: { openClose: true, change: 1, save: { includeText: true } }
3639
+ },
3640
+ serverInfo: { name: "east-diagnostics" }
3641
+ }
3642
+ });
3643
+ setImmediate(() => {
3644
+ for (const folder of folders) {
3645
+ try {
3646
+ service.warm(folder);
3647
+ } catch {
3648
+ }
3649
+ }
3650
+ });
3651
+ return;
3652
+ }
3653
+ case "initialized":
3654
+ return;
3655
+ case "shutdown":
3656
+ shuttingDown = true;
3657
+ send({ id, result: null });
3658
+ return;
3659
+ case "exit":
3660
+ shutdown(shuttingDown ? 0 : 1);
3661
+ return;
3662
+ case "textDocument/didOpen": {
3663
+ const path = uriToPath(params?.textDocument?.uri ?? "");
3664
+ const text = params?.textDocument?.text;
3665
+ if (path === void 0 || typeof text !== "string")
3666
+ return;
3667
+ if (notOurs(path))
3668
+ return;
3669
+ open.set(path, text);
3670
+ service.setOverlay(path, text);
3671
+ schedule(path);
3672
+ return;
3673
+ }
3674
+ case "textDocument/didChange": {
3675
+ const path = uriToPath(params?.textDocument?.uri ?? "");
3676
+ const text = params?.contentChanges?.at?.(-1)?.text;
3677
+ if (path === void 0 || typeof text !== "string")
3678
+ return;
3679
+ if (notOurs(path))
3680
+ return;
3681
+ open.set(path, text);
3682
+ service.setOverlay(path, text);
3683
+ schedule(path);
3684
+ return;
3685
+ }
3686
+ case "textDocument/didSave": {
3687
+ const path = uriToPath(params?.textDocument?.uri ?? "");
3688
+ if (path === void 0)
3689
+ return;
3690
+ if (notOurs(path))
3691
+ return;
3692
+ const text = params?.text;
3693
+ if (typeof text === "string") {
3694
+ open.set(path, text);
3695
+ service.setOverlay(path, text);
3696
+ } else {
3697
+ open.delete(path);
3698
+ service.clearOverlay(path);
3699
+ }
3700
+ schedule(path);
3701
+ return;
3702
+ }
3703
+ case "textDocument/didClose": {
3704
+ const path = uriToPath(params?.textDocument?.uri ?? "");
3705
+ if (path === void 0)
3706
+ return;
3707
+ open.delete(path);
3708
+ if (!path.endsWith(".py"))
3709
+ service.clearOverlay(path);
3710
+ const timer = pending.get(path);
3711
+ if (timer !== void 0)
3712
+ clearTimeout(timer);
3713
+ pending.delete(path);
3714
+ send({ method: "textDocument/publishDiagnostics", params: { uri: `file://${path}`, diagnostics: [] } });
3715
+ return;
3716
+ }
3717
+ default:
3718
+ if (id !== void 0) {
3719
+ send({ id, error: { code: -32601, message: `Method not found: ${method}` } });
3720
+ }
3721
+ return;
3722
+ }
3723
+ }
3724
+ const reader = new FrameReader((message) => {
3725
+ try {
3726
+ handle(message);
3727
+ } catch {
3728
+ }
3729
+ });
3730
+ input.on("data", (chunk) => reader.push(chunk));
3731
+ const shutdown = (code) => exit(code);
3732
+ input.on("close", () => shutdown(0));
3733
+ input.on("end", () => shutdown(0));
3734
+ }
3735
+
3736
+ // ../east-plugin/dist/daemon/lsp.js
3737
+ runEastLsp();