@elaraai/east-claude-plugin 1.0.98 → 1.0.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.build/daemon/lsp.js +40 -3
- package/.build/daemon/server.js +40 -3
- package/.build/mcp/server.js +3 -2
- package/.claude-plugin/plugin.json +1 -1
- package/index.json +13340 -482
- package/package.json +1 -1
- package/skills/e3/SKILL.md +107 -676
- package/skills/e3/reference/browser.md +93 -0
- package/skills/e3/reference/cli.md +120 -0
- package/skills/e3/reference/from-code.md +48 -0
- package/skills/e3/reference/rack.md +139 -0
- package/skills/e3/reference/record-indexes.md +326 -0
- package/skills/e3/reference/record-migrations.md +63 -0
- package/skills/e3/reference/repository.md +25 -0
- package/skills/e3-ui/SKILL.md +426 -259
- package/skills/east/SKILL.md +33 -395
- package/skills/east/reference/beast2.md +71 -0
- package/skills/east/reference/cross-language-and-json-schema.md +87 -0
- package/skills/east/reference/queries.md +46 -0
- package/skills/east/reference/runners-and-ir.md +148 -0
- package/skills/east/reference/trees-and-recursion.md +56 -0
- package/skills/east/reference/values-in-typescript.md +62 -0
- package/skills/east-contribute/SKILL.md +0 -1
- package/skills/east-py/SKILL.md +36 -1613
- package/skills/east-py/reference/beast2.md +108 -0
- package/skills/east-py/reference/cli.md +51 -0
- package/skills/east-py/reference/columns-and-platform-functions.md +87 -0
- package/skills/east-py/reference/control-flow-and-queries.md +147 -0
- package/skills/east-py/reference/cross-language.md +70 -0
- package/skills/east-py/reference/ir-and-diagnostics.md +150 -0
- package/skills/east-py/reference/patterns.md +369 -0
- package/skills/east-py/reference/performance.md +70 -0
- package/skills/east-py/reference/value-methods.md +306 -0
- package/skills/east-py/reference/values-construction-and-json.md +88 -0
- package/skills/east-py/reference/writing-east-functions.md +275 -0
- package/skills/east-py-datascience/SKILL.md +11 -28
- package/skills/east-ui/SKILL.md +5 -5
package/.build/daemon/lsp.js
CHANGED
|
@@ -18,6 +18,12 @@ function isEastExprType(type) {
|
|
|
18
18
|
}
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
|
+
function isEastFunctionExprType(type) {
|
|
22
|
+
return someTypeName(type, (name) => name === "FunctionExpr" || name === "AsyncFunctionExpr");
|
|
23
|
+
}
|
|
24
|
+
function isEastIRType(type) {
|
|
25
|
+
return someTypeName(type, (name) => name === "EastIR" || name === "AsyncEastIR");
|
|
26
|
+
}
|
|
21
27
|
function isBlockBuilderType(type) {
|
|
22
28
|
const name = type.aliasSymbol?.name ?? type.symbol?.name;
|
|
23
29
|
return name === "BlockBuilder";
|
|
@@ -47,8 +53,13 @@ var E3_DEFINITION_NAMES = /* @__PURE__ */ new Set([
|
|
|
47
53
|
"DataTreeDef",
|
|
48
54
|
"FunctionDef",
|
|
49
55
|
"MutationDef",
|
|
56
|
+
"MigrationDef",
|
|
50
57
|
"RecordDef",
|
|
51
|
-
"
|
|
58
|
+
"RecordIndexDef",
|
|
59
|
+
"PackageDef",
|
|
60
|
+
"IndexDraft",
|
|
61
|
+
"MutationDraft",
|
|
62
|
+
"MigrationDraft"
|
|
52
63
|
]);
|
|
53
64
|
function isEastDefinitionType(type) {
|
|
54
65
|
return someTypeName(type, (name) => E3_DEFINITION_NAMES.has(name) || name.endsWith("PlatformDefinition"));
|
|
@@ -745,6 +756,8 @@ var noUnexecutedEastExpression = {
|
|
|
745
756
|
if (!t.isExpressionStatement(node))
|
|
746
757
|
return;
|
|
747
758
|
const expr = node.expression;
|
|
759
|
+
if (t.isBinaryExpression(expr) && expr.operatorToken.kind === t.SyntaxKind.EqualsToken)
|
|
760
|
+
return;
|
|
748
761
|
const root = chainRootReceiver(expr, ctx);
|
|
749
762
|
if (isBlockBuilderType(ctx.checker.getTypeAtLocation(root)))
|
|
750
763
|
return;
|
|
@@ -799,6 +812,7 @@ var REPEATING_METHODS = /* @__PURE__ */ new Set([
|
|
|
799
812
|
"toSet",
|
|
800
813
|
"toArray",
|
|
801
814
|
"toTree",
|
|
815
|
+
"flattenTree",
|
|
802
816
|
"sort",
|
|
803
817
|
"sortInPlace",
|
|
804
818
|
"isSorted",
|
|
@@ -889,6 +903,8 @@ var noReinlinedEastBinding = {
|
|
|
889
903
|
return;
|
|
890
904
|
if (!isEastExprType(ctx.checker.getTypeAtLocation(init2)))
|
|
891
905
|
return;
|
|
906
|
+
if (enclosingBlockScope(node, ctx) === void 0 && isEastFunctionExprType(ctx.checker.getTypeAtLocation(init2)))
|
|
907
|
+
return;
|
|
892
908
|
const declSymbol = ctx.checker.getSymbolAtLocation(node.name);
|
|
893
909
|
if (declSymbol === void 0)
|
|
894
910
|
return;
|
|
@@ -1335,7 +1351,7 @@ var noCompileTimeSeedData = {
|
|
|
1335
1351
|
const nameArg = node.arguments[0];
|
|
1336
1352
|
const name = nameArg !== void 0 && t.isStringLiteralLike(nameArg) ? nameArg.text : "\u2026";
|
|
1337
1353
|
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";
|
|
1338
|
-
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
|
|
1354
|
+
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 declare an \`e3.record(...)\` with its mutations for set-once root state.`);
|
|
1339
1355
|
}
|
|
1340
1356
|
};
|
|
1341
1357
|
|
|
@@ -1671,6 +1687,8 @@ function returnBuildsEast(r, ctx) {
|
|
|
1671
1687
|
return false;
|
|
1672
1688
|
if (isEastDefinitionType(ctx.checker.getTypeAtLocation(r)))
|
|
1673
1689
|
return false;
|
|
1690
|
+
if (isEastIRType(ctx.checker.getTypeAtLocation(r)))
|
|
1691
|
+
return false;
|
|
1674
1692
|
if (isEastValueConstructor(r, ctx))
|
|
1675
1693
|
return true;
|
|
1676
1694
|
if (isEastExprType(ctx.checker.getTypeAtLocation(r)))
|
|
@@ -1737,6 +1755,17 @@ function isValueConstruction(e, t) {
|
|
|
1737
1755
|
return r.text === "none";
|
|
1738
1756
|
return t.isCallExpression(r) && t.isIdentifier(r.expression) && VALUE_CONSTRUCTORS.has(r.expression.text);
|
|
1739
1757
|
}
|
|
1758
|
+
function forwardsParameter(r, fn, ctx) {
|
|
1759
|
+
const t = ctx.ts;
|
|
1760
|
+
let e = r;
|
|
1761
|
+
while (t.isParenthesizedExpression(e) || t.isAsExpression(e) || t.isSatisfiesExpression(e) || t.isNonNullExpression(e) || t.isTypeAssertionExpression(e)) {
|
|
1762
|
+
e = e.expression;
|
|
1763
|
+
}
|
|
1764
|
+
if (!t.isIdentifier(e))
|
|
1765
|
+
return false;
|
|
1766
|
+
const declarations = ctx.checker.getSymbolAtLocation(e)?.declarations ?? [];
|
|
1767
|
+
return declarations.some((d) => t.isParameter(d) && d.parent === fn);
|
|
1768
|
+
}
|
|
1740
1769
|
function returnExpressions2(fn, t) {
|
|
1741
1770
|
if (fn.body === void 0)
|
|
1742
1771
|
return [];
|
|
@@ -1781,11 +1810,19 @@ var noModuleScopeEastMacro = {
|
|
|
1781
1810
|
const first = fn.parameters[0];
|
|
1782
1811
|
if (first !== void 0 && isBlockBuilderType(ctx.checker.getTypeAtLocation(first.name)))
|
|
1783
1812
|
return;
|
|
1784
|
-
|
|
1813
|
+
if (fn.type !== void 0 && isEastDefinitionType(ctx.checker.getTypeFromTypeNode(fn.type)))
|
|
1814
|
+
return;
|
|
1815
|
+
const rs = returnExpressions2(fn, t).filter((r) => !forwardsParameter(r, fn, ctx));
|
|
1785
1816
|
if (rs.some((r) => isJsx2(r, t)))
|
|
1786
1817
|
return;
|
|
1787
1818
|
if (rs.length === 0)
|
|
1788
1819
|
return;
|
|
1820
|
+
const takesEast = fn.parameters.some((p) => {
|
|
1821
|
+
const type = ctx.checker.getTypeAtLocation(p.name);
|
|
1822
|
+
return isEastExprType(type) && !isEastFunctionExprType(type) || isBlockBuilderType(type);
|
|
1823
|
+
});
|
|
1824
|
+
if (!takesEast && rs.every((r) => isEastFunctionExprType(ctx.checker.getTypeAtLocation(r))))
|
|
1825
|
+
return;
|
|
1789
1826
|
const everyBuildsIr = rs.every((r) => returnBuildsEast(r, ctx));
|
|
1790
1827
|
const everyBuildsValue = !everyBuildsIr && rs.every((r) => returnBuildsEast(r, ctx) || isValueConstruction(r, t));
|
|
1791
1828
|
const everyHostKey = !everyBuildsIr && !everyBuildsValue && rs.every((r) => isHostTemplate(r, t));
|
package/.build/daemon/server.js
CHANGED
|
@@ -22,6 +22,12 @@ function isEastExprType(type) {
|
|
|
22
22
|
}
|
|
23
23
|
return false;
|
|
24
24
|
}
|
|
25
|
+
function isEastFunctionExprType(type) {
|
|
26
|
+
return someTypeName(type, (name) => name === "FunctionExpr" || name === "AsyncFunctionExpr");
|
|
27
|
+
}
|
|
28
|
+
function isEastIRType(type) {
|
|
29
|
+
return someTypeName(type, (name) => name === "EastIR" || name === "AsyncEastIR");
|
|
30
|
+
}
|
|
25
31
|
function isBlockBuilderType(type) {
|
|
26
32
|
const name = type.aliasSymbol?.name ?? type.symbol?.name;
|
|
27
33
|
return name === "BlockBuilder";
|
|
@@ -51,8 +57,13 @@ var E3_DEFINITION_NAMES = /* @__PURE__ */ new Set([
|
|
|
51
57
|
"DataTreeDef",
|
|
52
58
|
"FunctionDef",
|
|
53
59
|
"MutationDef",
|
|
60
|
+
"MigrationDef",
|
|
54
61
|
"RecordDef",
|
|
55
|
-
"
|
|
62
|
+
"RecordIndexDef",
|
|
63
|
+
"PackageDef",
|
|
64
|
+
"IndexDraft",
|
|
65
|
+
"MutationDraft",
|
|
66
|
+
"MigrationDraft"
|
|
56
67
|
]);
|
|
57
68
|
function isEastDefinitionType(type) {
|
|
58
69
|
return someTypeName(type, (name) => E3_DEFINITION_NAMES.has(name) || name.endsWith("PlatformDefinition"));
|
|
@@ -749,6 +760,8 @@ var noUnexecutedEastExpression = {
|
|
|
749
760
|
if (!t.isExpressionStatement(node))
|
|
750
761
|
return;
|
|
751
762
|
const expr = node.expression;
|
|
763
|
+
if (t.isBinaryExpression(expr) && expr.operatorToken.kind === t.SyntaxKind.EqualsToken)
|
|
764
|
+
return;
|
|
752
765
|
const root = chainRootReceiver(expr, ctx);
|
|
753
766
|
if (isBlockBuilderType(ctx.checker.getTypeAtLocation(root)))
|
|
754
767
|
return;
|
|
@@ -803,6 +816,7 @@ var REPEATING_METHODS = /* @__PURE__ */ new Set([
|
|
|
803
816
|
"toSet",
|
|
804
817
|
"toArray",
|
|
805
818
|
"toTree",
|
|
819
|
+
"flattenTree",
|
|
806
820
|
"sort",
|
|
807
821
|
"sortInPlace",
|
|
808
822
|
"isSorted",
|
|
@@ -893,6 +907,8 @@ var noReinlinedEastBinding = {
|
|
|
893
907
|
return;
|
|
894
908
|
if (!isEastExprType(ctx.checker.getTypeAtLocation(init2)))
|
|
895
909
|
return;
|
|
910
|
+
if (enclosingBlockScope(node, ctx) === void 0 && isEastFunctionExprType(ctx.checker.getTypeAtLocation(init2)))
|
|
911
|
+
return;
|
|
896
912
|
const declSymbol = ctx.checker.getSymbolAtLocation(node.name);
|
|
897
913
|
if (declSymbol === void 0)
|
|
898
914
|
return;
|
|
@@ -1339,7 +1355,7 @@ var noCompileTimeSeedData = {
|
|
|
1339
1355
|
const nameArg = node.arguments[0];
|
|
1340
1356
|
const name = nameArg !== void 0 && t.isStringLiteralLike(nameArg) ? nameArg.text : "\u2026";
|
|
1341
1357
|
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";
|
|
1342
|
-
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
|
|
1358
|
+
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 declare an \`e3.record(...)\` with its mutations for set-once root state.`);
|
|
1343
1359
|
}
|
|
1344
1360
|
};
|
|
1345
1361
|
|
|
@@ -1675,6 +1691,8 @@ function returnBuildsEast(r, ctx) {
|
|
|
1675
1691
|
return false;
|
|
1676
1692
|
if (isEastDefinitionType(ctx.checker.getTypeAtLocation(r)))
|
|
1677
1693
|
return false;
|
|
1694
|
+
if (isEastIRType(ctx.checker.getTypeAtLocation(r)))
|
|
1695
|
+
return false;
|
|
1678
1696
|
if (isEastValueConstructor(r, ctx))
|
|
1679
1697
|
return true;
|
|
1680
1698
|
if (isEastExprType(ctx.checker.getTypeAtLocation(r)))
|
|
@@ -1741,6 +1759,17 @@ function isValueConstruction(e, t) {
|
|
|
1741
1759
|
return r.text === "none";
|
|
1742
1760
|
return t.isCallExpression(r) && t.isIdentifier(r.expression) && VALUE_CONSTRUCTORS.has(r.expression.text);
|
|
1743
1761
|
}
|
|
1762
|
+
function forwardsParameter(r, fn, ctx) {
|
|
1763
|
+
const t = ctx.ts;
|
|
1764
|
+
let e = r;
|
|
1765
|
+
while (t.isParenthesizedExpression(e) || t.isAsExpression(e) || t.isSatisfiesExpression(e) || t.isNonNullExpression(e) || t.isTypeAssertionExpression(e)) {
|
|
1766
|
+
e = e.expression;
|
|
1767
|
+
}
|
|
1768
|
+
if (!t.isIdentifier(e))
|
|
1769
|
+
return false;
|
|
1770
|
+
const declarations = ctx.checker.getSymbolAtLocation(e)?.declarations ?? [];
|
|
1771
|
+
return declarations.some((d) => t.isParameter(d) && d.parent === fn);
|
|
1772
|
+
}
|
|
1744
1773
|
function returnExpressions2(fn, t) {
|
|
1745
1774
|
if (fn.body === void 0)
|
|
1746
1775
|
return [];
|
|
@@ -1785,11 +1814,19 @@ var noModuleScopeEastMacro = {
|
|
|
1785
1814
|
const first = fn.parameters[0];
|
|
1786
1815
|
if (first !== void 0 && isBlockBuilderType(ctx.checker.getTypeAtLocation(first.name)))
|
|
1787
1816
|
return;
|
|
1788
|
-
|
|
1817
|
+
if (fn.type !== void 0 && isEastDefinitionType(ctx.checker.getTypeFromTypeNode(fn.type)))
|
|
1818
|
+
return;
|
|
1819
|
+
const rs = returnExpressions2(fn, t).filter((r) => !forwardsParameter(r, fn, ctx));
|
|
1789
1820
|
if (rs.some((r) => isJsx2(r, t)))
|
|
1790
1821
|
return;
|
|
1791
1822
|
if (rs.length === 0)
|
|
1792
1823
|
return;
|
|
1824
|
+
const takesEast = fn.parameters.some((p) => {
|
|
1825
|
+
const type = ctx.checker.getTypeAtLocation(p.name);
|
|
1826
|
+
return isEastExprType(type) && !isEastFunctionExprType(type) || isBlockBuilderType(type);
|
|
1827
|
+
});
|
|
1828
|
+
if (!takesEast && rs.every((r) => isEastFunctionExprType(ctx.checker.getTypeAtLocation(r))))
|
|
1829
|
+
return;
|
|
1793
1830
|
const everyBuildsIr = rs.every((r) => returnBuildsEast(r, ctx));
|
|
1794
1831
|
const everyBuildsValue = !everyBuildsIr && rs.every((r) => returnBuildsEast(r, ctx) || isValueConstruction(r, t));
|
|
1795
1832
|
const everyHostKey = !everyBuildsIr && !everyBuildsValue && rs.every((r) => isHostTemplate(r, t));
|
package/.build/mcp/server.js
CHANGED
|
@@ -23131,6 +23131,7 @@ function normalizePackage(filter, scopes = EAST_SCOPES) {
|
|
|
23131
23131
|
const scope = scopes.find((s) => name.startsWith(`${s.toLowerCase()}/`));
|
|
23132
23132
|
return scope === void 0 ? name : name.slice(scope.length + 1);
|
|
23133
23133
|
}
|
|
23134
|
+
var OPT_IN_PACKAGES = /* @__PURE__ */ new Set(["east-values"]);
|
|
23134
23135
|
function searchExamples(index, request) {
|
|
23135
23136
|
const known = index.packages;
|
|
23136
23137
|
const filter = request.package;
|
|
@@ -23140,7 +23141,7 @@ function searchExamples(index, request) {
|
|
|
23140
23141
|
}
|
|
23141
23142
|
const options = {
|
|
23142
23143
|
limit: request.limit,
|
|
23143
|
-
|
|
23144
|
+
filter: (r) => OPT_IN_PACKAGES.has(r.package) ? r.package === pkg : pkg === void 0 || r.package === pkg || r.skill === pkg
|
|
23144
23145
|
};
|
|
23145
23146
|
const hits = index.search.search(request.query, options);
|
|
23146
23147
|
return { entries: hits.filter((r) => r.score >= MIN_SCORE).slice(0, request.limit), known };
|
|
@@ -23235,7 +23236,7 @@ function registerExampleTools(server2, options) {
|
|
|
23235
23236
|
language: languageArg,
|
|
23236
23237
|
format: external_exports.enum(["summary", "full"]).default("summary").describe(`"summary" (default) lists the hits in one line each; "full" includes each hit's code in the requested language`),
|
|
23237
23238
|
limit: external_exports.number().int().min(1).max(20).default(5).describe("Maximum number of results to return (default 5, max 20)"),
|
|
23238
|
-
package: external_exports.string().optional().describe(`Filter results to one package by its bare name \u2014 ${packages.join(", ")} \u2014 ${scopesNamed}; an unknown name is reported with the indexed names`)
|
|
23239
|
+
package: external_exports.string().optional().describe(`Filter results to one package by its bare name \u2014 ${packages.join(", ")} \u2014 ${scopesNamed}; an unknown name is reported with the indexed names${packages.includes("east-values") ? '. "east-values" is east-py code working with East values directly (eager methods on python values, not an East function), and is searched only when named here' : ""}`)
|
|
23239
23240
|
}, async ({ query, language, format, limit, package: packageFilter }) => {
|
|
23240
23241
|
const index = await indexPromise;
|
|
23241
23242
|
const { entries, unknownPackage, known } = searchExamples(index, { query, limit, package: packageFilter, scopes });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "east",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.100",
|
|
4
4
|
"description": "East programming language ecosystem - a statically typed, expression-based language for business logic, data processing, UI definitions, and durable execution",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Elara AI",
|