@elaraai/east-plugin 0.0.0-stage → 1.0.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/LICENSE.md +682 -0
  2. package/README.md +104 -2
  3. package/dist/daemon/east-py-lsp.d.ts +2 -0
  4. package/dist/daemon/east-py-lsp.d.ts.map +1 -0
  5. package/dist/daemon/east-py-lsp.js +9 -0
  6. package/dist/daemon/east-py-lsp.js.map +1 -0
  7. package/dist/daemon/lsp.d.ts +2 -0
  8. package/dist/daemon/lsp.d.ts.map +1 -0
  9. package/dist/daemon/lsp.js +7 -0
  10. package/dist/daemon/lsp.js.map +1 -0
  11. package/dist/daemon/server.d.ts +2 -0
  12. package/dist/daemon/server.d.ts.map +1 -0
  13. package/dist/daemon/server.js +71 -0
  14. package/dist/daemon/server.js.map +1 -0
  15. package/dist/hooks/diagnose-bash.d.ts +2 -0
  16. package/dist/hooks/diagnose-bash.d.ts.map +1 -0
  17. package/dist/hooks/diagnose-bash.js +28 -0
  18. package/dist/hooks/diagnose-bash.js.map +1 -0
  19. package/dist/hooks/diagnose.d.ts +2 -0
  20. package/dist/hooks/diagnose.d.ts.map +1 -0
  21. package/dist/hooks/diagnose.js +33 -0
  22. package/dist/hooks/diagnose.js.map +1 -0
  23. package/dist/hooks/pre-read.d.ts +2 -0
  24. package/dist/hooks/pre-read.d.ts.map +1 -0
  25. package/dist/hooks/pre-read.js +11 -0
  26. package/dist/hooks/pre-read.js.map +1 -0
  27. package/dist/hooks/pre-write.d.ts +2 -0
  28. package/dist/hooks/pre-write.d.ts.map +1 -0
  29. package/dist/hooks/pre-write.js +11 -0
  30. package/dist/hooks/pre-write.js.map +1 -0
  31. package/dist/hooks/session-start.d.ts +2 -0
  32. package/dist/hooks/session-start.d.ts.map +1 -0
  33. package/dist/hooks/session-start.js +34 -0
  34. package/dist/hooks/session-start.js.map +1 -0
  35. package/dist/hooks/subagent-start.d.ts +2 -0
  36. package/dist/hooks/subagent-start.d.ts.map +1 -0
  37. package/dist/hooks/subagent-start.js +29 -0
  38. package/dist/hooks/subagent-start.js.map +1 -0
  39. package/dist/lib/bash-writes.d.ts +11 -0
  40. package/dist/lib/bash-writes.d.ts.map +1 -0
  41. package/dist/lib/bash-writes.js +74 -0
  42. package/dist/lib/bash-writes.js.map +1 -0
  43. package/dist/lib/codex-hook.d.ts +64 -0
  44. package/dist/lib/codex-hook.d.ts.map +1 -0
  45. package/dist/lib/codex-hook.js +94 -0
  46. package/dist/lib/codex-hook.js.map +1 -0
  47. package/dist/lib/codex-skills.d.ts +38 -0
  48. package/dist/lib/codex-skills.d.ts.map +1 -0
  49. package/dist/lib/codex-skills.js +80 -0
  50. package/dist/lib/codex-skills.js.map +1 -0
  51. package/dist/lib/codex-tools.d.ts +11 -0
  52. package/dist/lib/codex-tools.d.ts.map +1 -0
  53. package/dist/lib/codex-tools.js +41 -0
  54. package/dist/lib/codex-tools.js.map +1 -0
  55. package/dist/lib/diagnostics-client.d.ts +9 -0
  56. package/dist/lib/diagnostics-client.d.ts.map +1 -0
  57. package/dist/lib/diagnostics-client.js +123 -0
  58. package/dist/lib/diagnostics-client.js.map +1 -0
  59. package/dist/lib/east-index.d.ts +3 -0
  60. package/dist/lib/east-index.d.ts.map +1 -0
  61. package/dist/lib/east-index.js +9 -0
  62. package/dist/lib/east-index.js.map +1 -0
  63. package/dist/lib/east-project.d.ts +49 -0
  64. package/dist/lib/east-project.d.ts.map +1 -0
  65. package/dist/lib/east-project.js +121 -0
  66. package/dist/lib/east-project.js.map +1 -0
  67. package/dist/lib/east-py-lint.d.ts +7 -0
  68. package/dist/lib/east-py-lint.d.ts.map +1 -0
  69. package/dist/lib/east-py-lint.js +22 -0
  70. package/dist/lib/east-py-lint.js.map +1 -0
  71. package/dist/lib/east-rules-context.d.ts +7 -0
  72. package/dist/lib/east-rules-context.d.ts.map +1 -0
  73. package/dist/lib/east-rules-context.js +91 -0
  74. package/dist/lib/east-rules-context.js.map +1 -0
  75. package/dist/lib/hook-io.d.ts +30 -0
  76. package/dist/lib/hook-io.d.ts.map +1 -0
  77. package/dist/lib/hook-io.js +29 -0
  78. package/dist/lib/hook-io.js.map +1 -0
  79. package/dist/lib/host.d.ts +3 -0
  80. package/dist/lib/host.d.ts.map +1 -0
  81. package/dist/lib/host.js +9 -0
  82. package/dist/lib/host.js.map +1 -0
  83. package/dist/lib/lsp-client.d.ts +34 -0
  84. package/dist/lib/lsp-client.d.ts.map +1 -0
  85. package/dist/lib/lsp-client.js +200 -0
  86. package/dist/lib/lsp-client.js.map +1 -0
  87. package/dist/lib/plugin-status.d.ts +9 -0
  88. package/dist/lib/plugin-status.d.ts.map +1 -0
  89. package/dist/lib/plugin-status.js +164 -0
  90. package/dist/lib/plugin-status.js.map +1 -0
  91. package/dist/lib/review.d.ts +16 -0
  92. package/dist/lib/review.d.ts.map +1 -0
  93. package/dist/lib/review.js +74 -0
  94. package/dist/lib/review.js.map +1 -0
  95. package/dist/lib/search-guidance.d.ts +44 -0
  96. package/dist/lib/search-guidance.d.ts.map +1 -0
  97. package/dist/lib/search-guidance.js +73 -0
  98. package/dist/lib/search-guidance.js.map +1 -0
  99. package/dist/lib/search-hooks.d.ts +75 -0
  100. package/dist/lib/search-hooks.d.ts.map +1 -0
  101. package/dist/lib/search-hooks.js +117 -0
  102. package/dist/lib/search-hooks.js.map +1 -0
  103. package/dist/lib/search.d.ts +121 -0
  104. package/dist/lib/search.d.ts.map +1 -0
  105. package/dist/lib/search.js +181 -0
  106. package/dist/lib/search.js.map +1 -0
  107. package/dist/lib/transcript.d.ts +29 -0
  108. package/dist/lib/transcript.d.ts.map +1 -0
  109. package/dist/lib/transcript.js +109 -0
  110. package/dist/lib/transcript.js.map +1 -0
  111. package/dist/mcp/example-tools.d.ts +33 -0
  112. package/dist/mcp/example-tools.d.ts.map +1 -0
  113. package/dist/mcp/example-tools.js +97 -0
  114. package/dist/mcp/example-tools.js.map +1 -0
  115. package/dist/mcp/server.d.ts +2 -0
  116. package/dist/mcp/server.d.ts.map +1 -0
  117. package/dist/mcp/server.js +52 -0
  118. package/dist/mcp/server.js.map +1 -0
  119. package/dist/scripts/examples-file.d.ts +38 -0
  120. package/dist/scripts/examples-file.d.ts.map +1 -0
  121. package/dist/scripts/examples-file.js +224 -0
  122. package/dist/scripts/examples-file.js.map +1 -0
  123. package/dist/scripts/generate-index.d.ts +127 -0
  124. package/dist/scripts/generate-index.d.ts.map +1 -0
  125. package/dist/scripts/generate-index.js +315 -0
  126. package/dist/scripts/generate-index.js.map +1 -0
  127. package/dist/status/report.d.ts +2 -0
  128. package/dist/status/report.d.ts.map +1 -0
  129. package/dist/status/report.js +9 -0
  130. package/dist/status/report.js.map +1 -0
  131. package/index.json +44926 -0
  132. package/package.json +65 -3
  133. package/scripts/render-python.py +67 -0
@@ -0,0 +1,121 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join, dirname } from "node:path";
3
+ const PACKAGE_SKILL_MAP = {
4
+ "@elaraai/east": "east",
5
+ "@elaraai/east-node-std": "east-node-std",
6
+ "@elaraai/east-node-io": "east-node-io",
7
+ "@elaraai/east-py-datascience": "east-py-datascience",
8
+ "@elaraai/east-ui": "east-ui",
9
+ "@elaraai/e3": "e3",
10
+ "@elaraai/e3-ui": "e3-ui",
11
+ };
12
+ // The python distributions, matched against pyproject.toml / uv.lock text.
13
+ // Ordered longest-first and anchored with a non-name lookahead so
14
+ // `elaraai-east-py-std` never also counts as `elaraai-east-py`.
15
+ const PYTHON_SKILL_MAP = [
16
+ [/elaraai-east-py-datascience(?![\w-])/, "east-py-datascience"],
17
+ [/elaraai-east-py-std(?![\w-])/, "east-py-std"],
18
+ [/elaraai-east-py-io(?![\w-])/, "east-py-io"],
19
+ [/elaraai-east-py(?![\w-])/, "east-py"],
20
+ ];
21
+ export async function findPackageJson(startDir) {
22
+ let dir = startDir;
23
+ while (true) {
24
+ try {
25
+ const content = await readFile(join(dir, "package.json"), "utf-8");
26
+ return JSON.parse(content);
27
+ }
28
+ catch {
29
+ const parent = dirname(dir);
30
+ if (parent === dir)
31
+ return null;
32
+ dir = parent;
33
+ }
34
+ }
35
+ }
36
+ /**
37
+ * The `pyproject.toml` that governs `startDir`, as text: the nearest one at
38
+ * or above it that depends on an east-py distribution, else the nearest one
39
+ * at all. A uv workspace member has its own pyproject — that is what makes it
40
+ * a member — and it usually says nothing about East, so stopping at the first
41
+ * file found would call every member a non-East project while the root
42
+ * declares otherwise; the walk continues past a pyproject that does not
43
+ * mention east-py (the same rule `east.diagnostics.config` applies).
44
+ *
45
+ * `uv.lock` is deliberately NOT read. This runs on a hot path — every session
46
+ * start, every subagent start, every gated write, and every reviewed file — and
47
+ * a lockfile is large (~1 MB in this repo), so reading one per call to
48
+ * substring-match it was real work repeated constantly. It was also wrong:
49
+ * a lockfile lists TRANSITIVE resolutions, so a TypeScript-only project that
50
+ * merely resolved an East distribution somewhere in its graph was reported as
51
+ * a python East project and handed the python cheat-sheet. A project that
52
+ * authors East in python declares it in a `pyproject.toml` of its own.
53
+ */
54
+ export async function findPyProject(startDir) {
55
+ let dir = startDir;
56
+ let nearest = null;
57
+ while (true) {
58
+ try {
59
+ const text = await readFile(join(dir, "pyproject.toml"), "utf-8");
60
+ if (PYTHON_SKILL_MAP.some(([pattern]) => pattern.test(text)))
61
+ return text;
62
+ nearest ??= text;
63
+ }
64
+ catch {
65
+ /* no pyproject here: keep walking */
66
+ }
67
+ const parent = dirname(dir);
68
+ if (parent === dir)
69
+ return nearest;
70
+ dir = parent;
71
+ }
72
+ }
73
+ export function detectEastSkills(pkg) {
74
+ if (!pkg)
75
+ return [];
76
+ const allDeps = {
77
+ ...pkg.dependencies,
78
+ ...pkg.devDependencies,
79
+ };
80
+ const skills = [];
81
+ for (const [packageName, skillName] of Object.entries(PACKAGE_SKILL_MAP)) {
82
+ if (packageName in allDeps) {
83
+ skills.push(skillName);
84
+ }
85
+ }
86
+ return skills;
87
+ }
88
+ /** The east-py skills a pyproject.toml text depends on. */
89
+ export function detectPythonSkills(pyproject) {
90
+ if (pyproject === null)
91
+ return [];
92
+ const skills = [];
93
+ for (const [pattern, skill] of PYTHON_SKILL_MAP) {
94
+ if (pattern.test(pyproject))
95
+ skills.push(skill);
96
+ }
97
+ return skills;
98
+ }
99
+ /**
100
+ * What kind of East project `cwd` sits in.
101
+ *
102
+ * Both ecosystems count. A project whose East dependency is declared only in
103
+ * `pyproject.toml` — no package.json anywhere — is an East project, and used
104
+ * to report `isEast: false`, so the session and subagent hooks injected
105
+ * nothing at all for it: no skill list, no rule cheat-sheet. (The diagnose and
106
+ * pre-write hooks never consulted this, gating on an `import east` instead,
107
+ * which is why diagnostics worked there while orientation did not.)
108
+ */
109
+ export async function getEastProjectInfo(cwd) {
110
+ const pkg = await findPackageJson(cwd);
111
+ const tsSkills = detectEastSkills(pkg);
112
+ const pySkills = detectPythonSkills(await findPyProject(cwd));
113
+ const languages = [];
114
+ if (tsSkills.length > 0)
115
+ languages.push("typescript");
116
+ if (pySkills.length > 0)
117
+ languages.push("python");
118
+ const skills = [...tsSkills, ...pySkills.filter((s) => !tsSkills.includes(s))];
119
+ return { isEast: skills.length > 0, skills, languages, pkg };
120
+ }
121
+ //# sourceMappingURL=east-project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"east-project.js","sourceRoot":"","sources":["../../lib/east-project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /** The `<east-code-review>` text for a python file: `""` when clean, `null`
2
+ * when no east-py answered (absent, failed, or over `budgetMs`) — callers
3
+ * degrade to a silent no-op, as for the TypeScript daemon. The build tier's
4
+ * absence is never a failure: its records are merged when the project asked
5
+ * for them and the check answered in time. */
6
+ export declare function getPythonDiagnosticsText(file: string, budgetMs?: number): Promise<string | null>;
7
+ //# sourceMappingURL=east-py-lint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"east-py-lint.d.ts","sourceRoot":"","sources":["../../lib/east-py-lint.ts"],"names":[],"mappings":"AAYA;;;;8CAI8C;AAC9C,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIpG"}
@@ -0,0 +1,22 @@
1
+ import { renderPythonReview, runEastPyCheck, runEastPyLint } from "@elaraai/east-diagnostics";
2
+ // The python twin of the daemon's review (#648): a python file that imports
3
+ // `east` is reviewed by the east-py rules — `east-py lint --format json`, run
4
+ // through the project's own environment (the nearest `.venv` above the file),
5
+ // else `east-py` on PATH, `EAST_PY_LINT` naming the command outright — and,
6
+ // where the project has opted into the build tier (`[tool.east-py] check =
7
+ // true`), by `east-py check` too, so the hook shows what the language server
8
+ // shows (#653). The resolver and the JSON readers live in
9
+ // @elaraai/east-diagnostics, where the plugin's python language server uses
10
+ // the same ones.
11
+ /** The `<east-code-review>` text for a python file: `""` when clean, `null`
12
+ * when no east-py answered (absent, failed, or over `budgetMs`) — callers
13
+ * degrade to a silent no-op, as for the TypeScript daemon. The build tier's
14
+ * absence is never a failure: its records are merged when the project asked
15
+ * for them and the check answered in time. */
16
+ export async function getPythonDiagnosticsText(file, budgetMs = 4000) {
17
+ const [rules, build] = await Promise.all([runEastPyLint(file, undefined, budgetMs), runEastPyCheck(file, budgetMs)]);
18
+ if (rules === null)
19
+ return null;
20
+ return renderPythonReview([...rules, ...(build ?? [])]);
21
+ }
22
+ //# sourceMappingURL=east-py-lint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"east-py-lint.js","sourceRoot":"","sources":["../../lib/east-py-lint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE9F,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,4EAA4E;AAC5E,2EAA2E;AAC3E,6EAA6E;AAC7E,0DAA0D;AAC1D,4EAA4E;AAC5E,iBAAiB;AAEjB;;;;8CAI8C;AAC9C,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,IAAY,EAAE,QAAQ,GAAG,IAAI;IAC1E,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrH,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,kBAAkB,CAAC,CAAC,GAAG,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare const EAST_RULES_CONTEXT: string;
2
+ export declare const EAST_RULES_CONTEXT_PY: string;
3
+ /** The cheat-sheet(s) for the detected language(s) — both, for a project that
4
+ * is both. An unknown/empty language list falls back to TypeScript, which is
5
+ * what a project with an `@elaraai/*` dependency and no python is. */
6
+ export declare function eastRulesContextFor(languages: readonly string[]): string;
7
+ //# sourceMappingURL=east-rules-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"east-rules-context.d.ts","sourceRoot":"","sources":["../../lib/east-rules-context.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,kBAAkB,EAAE,MAwBrB,CAAC;AAQb,eAAO,MAAM,qBAAqB,EAAE,MAqCxB,CAAC;AAEb;;sEAEsE;AACtE,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAOxE"}
@@ -0,0 +1,91 @@
1
+ // A compact "author to the rules up front" cheat-sheet, injected at session /
2
+ // subagent start so an agent writes idiomatic East BEFORE the preemptive
3
+ // `<east-code-review>` (and the editor language server / ESLint `east/east-rules`)
4
+ // start flagging it. One `avoid … → use …` line per rule.
5
+ //
6
+ // Keep in sync with libs/east-diagnostics/src/rules. The linter self-gates on
7
+ // East-ness (an East type/block, an `e3` construct, or an `@elaraai/*` import), so
8
+ // these only apply to actual East code.
9
+ export const EAST_RULES_CONTEXT = [
10
+ "What the East linter checks — the editor language server, ESLint `east/east-rules`, and the preemptive `<east-code-review>` all run the SAME rule set, so author to these from the start. Inside an `East.function` / `$`-block, the code must be East all the way down:",
11
+ "",
12
+ "Host-vs-East (most common):",
13
+ "- no-host-in-east-block — avoid host TypeScript inside a block (`a + b`, `cond ? a : b`, `a && b`, `arr[i]`, a JS `for`/`if` that builds IR, a TS helper/closure call, a `${x}` string template); use East instead: `a.add(b)`, `cond.ifElse(() => a, () => b)`, `a.and(() => b)`, `coll.get(i)`, `$.for(...)` / `data.map(($, x) => …)`, `East.str`.",
14
+ "- no-module-scope-east-macro — avoid a module-scope TS helper that returns East IR or a composite string key like `(o, l) => `${o}|${l}``; make a real `East.function`, or model typed / nested East data.",
15
+ "- no-compile-time-data-injection — avoid reading data at module load (`node:fs`, `readFileSync`, `JSON.parse`, `process.env`); load at runtime via `e3.input` / datasets / a platform task.",
16
+ "- no-compile-time-seed-data — avoid computing an `e3.input` seed in host code (a Map filled by loops, `{ a: num(cfg.x) }`); pass a small literal / empty default and parse real data at runtime (`blob.decodeCsv` in a task).",
17
+ "",
18
+ "Bindings & values:",
19
+ "- no-let-const-in-expression — avoid burying `$.let`/`$.const` mid-expression (a struct-field value, call argument, array element); declare it on its own line and reuse the binding.",
20
+ "- no-redundant-east-cast — avoid a cast / generic / wrapper the East type already governs: `$.let(x as T, T)`, `$.let(new Map<K, V>(), DictType(...))`, `$.let(East.value(x, T), T)`; drop it.",
21
+ "- prefer-explicit-east-type — avoid an under-determined `$.let([])` / `$.let({})` / `$.let(new Map())`; give the East type, e.g. `$.let([], ArrayType(IntegerType))`.",
22
+ "- no-untracked-east-data — avoid a bare JS literal in an East-typed slot inside a block; bind it with `$.const`/`$.let`.",
23
+ "- no-reinlined-east-binding — avoid reusing an East `Expr` held in a JS `const` across a block (it re-inlines per use); bind it once with `$.let`/`$.const`.",
24
+ "- no-unexecuted-east-expression — avoid a bare East expression statement; execute it with `$(expr)` or bind it.",
25
+ "",
26
+ "Variants, types, imports, UI:",
27
+ "- prefer-some-none — avoid `variant(\"some\", x)` / `variant(\"none\", null)`; use `some(x)` / `none`.",
28
+ "- no-handrolled-variant — avoid a hand-rolled `{ type: \"x\", value: v }`; use `variant(\"x\", v)`.",
29
+ "- no-east-namespaced-type — avoid `East.IntegerType`; import `IntegerType` and use it bare.",
30
+ "- prefer-let-const-over-east-value — avoid `East.value(...)` inside a block; use `$.let`/`$.const`.",
31
+ "- prefer-jsx-over-factory-call — in a `.tsx` file, avoid `Foo.Root(...)`; author the `<Foo>` tag.",
32
+ "- no-relative-src-import — avoid importing another package via `../src` or `@elaraai/x/src`; use its published package name.",
33
+ ].join("\n");
34
+ // The python twin, covering `east.diagnostics` (`east-py lint`, the flake8
35
+ // plugin, the language server). Spelled in python: the block is `b`, not `$`;
36
+ // bodies take the block first; the strict expression surface (#625) REFUSES
37
+ // most of these at build time rather than merely discouraging them.
38
+ //
39
+ // Keep in sync with libs/east-py/packages/east-py/east/diagnostics/rules.
40
+ export const EAST_RULES_CONTEXT_PY = [
41
+ "What the East python linter checks — `east-py lint`, the flake8 `EAS` codes and the language server all run the SAME rules, so author to these from the start. Inside an `East.function` body the code must be East all the way down, and most of these are BUILD-TIME REFUSALS said early, not style notes:",
42
+ "",
43
+ "Body shape (the strict surface):",
44
+ "- body-takes-block-first — every body takes the block first: `lambda b, x: …` / `def f(b, x)`, never `lambda x: …`; the block is for statements, so `b.price` is not a field read.",
45
+ "- no-statement-on-outer-block — inside a nested body use THAT body's block: `lambda b: b.assign(...)`, not `lambda _b: b.assign(...)` reaching outward.",
46
+ "- no-discarded-expression — a bare expression statement is built and thrown away; append it with `b.do(...)` or return it.",
47
+ "",
48
+ "Python that cannot be traced (the build refuses these):",
49
+ "- no-python-boolean — avoid `and` / `or` / `not` / `if` / `in` / `len()` / iteration / `int()` / `float()` over an expression; use `&`, `|`, `~`, `b.if_(...)` / `East.if_else(...)`, and the expression's own methods.",
50
+ "- no-python-formatting — avoid f-strings / `str()` / `format()` / `%` over an expression; build strings with `+`, or `East.String.print(T, value)`.",
51
+ "- no-operator-fork — avoid `//`, `%`, `**` and `a[-1]` on an expression; call `East.Integer.divide` / `remainder` / `pow`, and spell the element you mean.",
52
+ "- no-python-round — avoid `round(x)` (ties-to-even); call `East.Float.round_half` / `round_floor` / `round_ceil` / `round_trunc`.",
53
+ "- no-python-work — avoid an eager callback reaching for a module, an installed package, or a python `def` doing work; express it in East.",
54
+ "- no-deprecated-alias — use the canonical spelling (e.g. `.reduce()`, not `.fold()`).",
55
+ "",
56
+ "Bindings & values:",
57
+ "- no-let-const-in-expression — give `b.let` / `b.const` its own statement; don't bury a declaration inside an expression.",
58
+ "- prefer-explicit-east-type — a bare python list / set / tuple in `b.let(...)` / `b.const(...)` cannot be lifted (the build refuses it, empty or not); pass the East type, e.g. `b.let([], ArrayType(IntegerType))`, or build it with `East.new_array`.",
59
+ "- no-untracked-east-data — avoid a plain python literal local reaching an expression's method; bind it with `b.const(rows, Type)`.",
60
+ "- no-redundant-east-cast — avoid `b.let(East.value(x, T), T)`; pass the value and type to `b.let` directly.",
61
+ "- prefer-let-const-over-east-value — inside a body declare with `b.const(value, Type)` / `b.let`, not `East.value(...)`.",
62
+ "",
63
+ "Variants & comparison:",
64
+ "- prefer-some-none — avoid `variant(\"some\", x)` / `variant(\"none\", None)`; use `some(x)` / `none`.",
65
+ "- no-handrolled-variant — avoid a `{\"type\": …, \"value\": …}` dict reaching East (a body, `East.value`, `coerce_to`, `array`); use `variant(\"Tag\", value, Type)` — the encoder needs what it constructs.",
66
+ "- no-host-comparison-on-east-values — outside a body, never `<` / `>` a decoded variant or option: it raises TypeError; use `compare_for(T)` / `less_for(T)` (and `make_east_key(T)` for `sorted`). `==` is structural and fine.",
67
+ "",
68
+ "Build time vs runtime (python computing what East should declare):",
69
+ "- no-build-time-clock — avoid `datetime.now()` / `time.time()` at module scope; author the constant, or read the clock at runtime (a platform function, or `east_py_std`'s `time_now()` in a body).",
70
+ "- no-compile-time-data-injection — avoid `open()` / `json.load` / `os.environ` at module import when the result reaches East; load at runtime (an e3 input, a dataset, a platform function, `east_py_std`'s `env_get`).",
71
+ "- no-inline-credentials — avoid a literal password / token; read it at runtime — `east_py_std`'s `env_get(\"YOUR_VAR\")` in a body, `os.environ` in a platform function — since IR is content-addressed and replicated.",
72
+ "- no-module-scope-east-macro — avoid a module-scope helper a body calls to build IR, or to assemble a composite `f\"{a}|{b}\"` key; make it an `East.function`, or model typed / nested East data.",
73
+ "- no-python-east-data — avoid assembling East rows with a module-scope comprehension or loop; write them out, or produce them at runtime.",
74
+ "- no-python-string-building — avoid an f-string assembling an East string constant (a regex, a template, a key); spell the constant out.",
75
+ "- no-derived-struct-fields — avoid declaring a type from another type's fields; a declaration is a wire format, so spell the fields.",
76
+ "- no-python-data-work — avoid a python helper doing the parse / strip / null-check / coerce work on an expression a body hands it; express it in East.",
77
+ ].join("\n");
78
+ /** The cheat-sheet(s) for the detected language(s) — both, for a project that
79
+ * is both. An unknown/empty language list falls back to TypeScript, which is
80
+ * what a project with an `@elaraai/*` dependency and no python is. */
81
+ export function eastRulesContextFor(languages) {
82
+ const python = languages.includes("python");
83
+ const typescript = languages.includes("typescript") || !python;
84
+ const parts = [];
85
+ if (typescript)
86
+ parts.push(EAST_RULES_CONTEXT);
87
+ if (python)
88
+ parts.push(EAST_RULES_CONTEXT_PY);
89
+ return parts.join("\n\n");
90
+ }
91
+ //# sourceMappingURL=east-rules-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"east-rules-context.js","sourceRoot":"","sources":["../../lib/east-rules-context.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,yEAAyE;AACzE,mFAAmF;AACnF,0DAA0D;AAC1D,EAAE;AACF,8EAA8E;AAC9E,mFAAmF;AACnF,wCAAwC;AACxC,MAAM,CAAC,MAAM,kBAAkB,GAAW;IACxC,0QAA0Q;IAC1Q,EAAE;IACF,6BAA6B;IAC7B,uVAAuV;IACvV,4MAA4M;IAC5M,6LAA6L;IAC7L,+NAA+N;IAC/N,EAAE;IACF,oBAAoB;IACpB,uLAAuL;IACvL,gMAAgM;IAChM,uKAAuK;IACvK,0HAA0H;IAC1H,8JAA8J;IAC9J,iHAAiH;IACjH,EAAE;IACF,+BAA+B;IAC/B,wGAAwG;IACxG,qGAAqG;IACrG,6FAA6F;IAC7F,qGAAqG;IACrG,mGAAmG;IACnG,8HAA8H;CAC/H,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,oEAAoE;AACpE,EAAE;AACF,0EAA0E;AAC1E,MAAM,CAAC,MAAM,qBAAqB,GAAW;IAC3C,8SAA8S;IAC9S,EAAE;IACF,kCAAkC;IAClC,oLAAoL;IACpL,yJAAyJ;IACzJ,4HAA4H;IAC5H,EAAE;IACF,yDAAyD;IACzD,yNAAyN;IACzN,qJAAqJ;IACrJ,4JAA4J;IAC5J,mIAAmI;IACnI,2IAA2I;IAC3I,uFAAuF;IACvF,EAAE;IACF,oBAAoB;IACpB,2HAA2H;IAC3H,yPAAyP;IACzP,oIAAoI;IACpI,6GAA6G;IAC7G,0HAA0H;IAC1H,EAAE;IACF,wBAAwB;IACxB,wGAAwG;IACxG,8MAA8M;IAC9M,kOAAkO;IAClO,EAAE;IACF,oEAAoE;IACpE,qMAAqM;IACrM,yNAAyN;IACzN,yNAAyN;IACzN,oMAAoM;IACpM,2IAA2I;IAC3I,0IAA0I;IAC1I,sIAAsI;IACtI,wJAAwJ;CACzJ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb;;sEAEsE;AACtE,MAAM,UAAU,mBAAmB,CAAC,SAA4B;IAC9D,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;IAC/D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC/C,IAAI,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,30 @@
1
+ export interface HookInput {
2
+ session_id: string;
3
+ transcript_path: string;
4
+ cwd: string;
5
+ permission_mode: string;
6
+ hook_event_name: string;
7
+ agent_id?: string;
8
+ agent_type?: string;
9
+ source?: string;
10
+ model?: string;
11
+ prompt?: string;
12
+ tool_name?: string;
13
+ tool_input?: {
14
+ file_path?: string;
15
+ content?: string;
16
+ old_string?: string;
17
+ new_string?: string;
18
+ command?: string;
19
+ prompt?: string;
20
+ subagent_type?: string;
21
+ [key: string]: unknown;
22
+ };
23
+ tool_response?: Record<string, unknown>;
24
+ tool_use_id?: string;
25
+ }
26
+ export declare function readHookInput(): Promise<HookInput>;
27
+ export declare function writeHookOutput(hookEventName: string, additionalContext: string): void;
28
+ /** A PreToolUse permission decision (`deny` refuses the call; `reason` is shown to the agent). */
29
+ export declare function writeHookDecision(hookEventName: string, decision: "allow" | "deny" | "ask", reason: string): void;
30
+ //# sourceMappingURL=hook-io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-io.d.ts","sourceRoot":"","sources":["../../lib/hook-io.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE;QACX,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,SAAS,CAAC,CAMxD;AAED,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAQtF;AAED,kGAAkG;AAClG,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CASjH"}
@@ -0,0 +1,29 @@
1
+ import { hostText } from "./host.js";
2
+ export async function readHookInput() {
3
+ let input = "";
4
+ for await (const chunk of process.stdin) {
5
+ input += chunk;
6
+ }
7
+ return JSON.parse(input);
8
+ }
9
+ export function writeHookOutput(hookEventName, additionalContext) {
10
+ const output = {
11
+ hookSpecificOutput: {
12
+ hookEventName,
13
+ additionalContext: hostText(additionalContext),
14
+ },
15
+ };
16
+ process.stdout.write(JSON.stringify(output));
17
+ }
18
+ /** A PreToolUse permission decision (`deny` refuses the call; `reason` is shown to the agent). */
19
+ export function writeHookDecision(hookEventName, decision, reason) {
20
+ const output = {
21
+ hookSpecificOutput: {
22
+ hookEventName,
23
+ permissionDecision: decision,
24
+ permissionDecisionReason: hostText(reason),
25
+ },
26
+ };
27
+ process.stdout.write(JSON.stringify(output));
28
+ }
29
+ //# sourceMappingURL=hook-io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-io.js","sourceRoot":"","sources":["../../lib/hook-io.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AA2BrC,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,KAAK,IAAI,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAc,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,aAAqB,EAAE,iBAAyB;IAC9E,MAAM,MAAM,GAAG;QACb,kBAAkB,EAAE;YAClB,aAAa;YACb,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB,CAAC;SAC/C;KACF,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,iBAAiB,CAAC,aAAqB,EAAE,QAAkC,EAAE,MAAc;IACzG,MAAM,MAAM,GAAG;QACb,kBAAkB,EAAE;YAClB,aAAa;YACb,kBAAkB,EAAE,QAAQ;YAC5B,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC;SAC3C;KACF,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const isCodex: boolean;
2
+ export declare function hostText(text: string): string;
3
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../lib/host.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,OAAO,SAAyF,CAAC;AAC9G,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C"}
@@ -0,0 +1,9 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { fileURLToPath } from 'node:url';
3
+ // Bundled entry points all live in .build/<component>; shared dist entries use the same depth.
4
+ export const isCodex = existsSync(fileURLToPath(new URL('../../.codex-plugin/plugin.json', import.meta.url)));
5
+ export function hostText(text) {
6
+ return isCodex ? text.replaceAll('mcp__plugin_east_east__', '')
7
+ .replaceAll('/east:', '$east-codex-plugin:').replaceAll('Claude Code', 'Codex') : text;
8
+ }
9
+ //# sourceMappingURL=host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.js","sourceRoot":"","sources":["../../lib/host.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,+FAA+F;AAC/F,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,iCAAiC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC9G,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,yBAAyB,EAAE,EAAE,CAAC;SAC5D,UAAU,CAAC,QAAQ,EAAE,qBAAqB,CAAC,CAAC,UAAU,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3F,CAAC"}
@@ -0,0 +1,34 @@
1
+ export interface Publication {
2
+ uri: string;
3
+ diagnostics: unknown[];
4
+ version?: number;
5
+ }
6
+ /** A real stdio LSP connection, kept warm for the MCP process lifetime. */
7
+ export declare class EastLspClient {
8
+ private child;
9
+ private buffer;
10
+ private nextId;
11
+ private requests;
12
+ private publications;
13
+ private waiters;
14
+ private versions;
15
+ private failure;
16
+ private stderr;
17
+ private closing;
18
+ private queue;
19
+ readonly ready: Promise<void>;
20
+ constructor(entry: string, cwd: string);
21
+ private fail;
22
+ private send;
23
+ private request;
24
+ private receive;
25
+ /** Serialize document operations so concurrent MCP calls cannot mix publications. */
26
+ diagnostics(file: string, timeoutMs: number, refresh?: boolean): Promise<Publication | null>;
27
+ close(): void;
28
+ }
29
+ export declare class EastLspPool {
30
+ private clients;
31
+ diagnostics(file: string, timeoutMs?: number, refresh?: boolean): Promise<Publication | null>;
32
+ close(): void;
33
+ }
34
+ //# sourceMappingURL=lsp-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp-client.d.ts","sourceRoot":"","sources":["../../lib/lsp-client.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;AACtF,2EAA2E;AAC3E,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAA4F;IAC5G,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,OAAO,CAAqE;IACpF,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAuC;IACpD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;gBAElB,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IAUtC,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,OAAO;IA6Bf,qFAAqF;IACrF,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,UAAO,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAgCzF,KAAK;CAaN;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAoC;IAC7C,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAQ,EAAE,OAAO,UAAO;IAkBjE,KAAK;CACN"}
@@ -0,0 +1,200 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { existsSync } from 'node:fs';
4
+ import { dirname, resolve, join } from 'node:path';
5
+ import { fileURLToPath, pathToFileURL } from 'node:url';
6
+ /** A real stdio LSP connection, kept warm for the MCP process lifetime. */
7
+ export class EastLspClient {
8
+ child;
9
+ buffer = Buffer.alloc(0);
10
+ nextId = 0;
11
+ requests = new Map();
12
+ publications = new Map();
13
+ waiters = new Map();
14
+ versions = new Map();
15
+ failure;
16
+ stderr = '';
17
+ closing = false;
18
+ queue = Promise.resolve();
19
+ ready;
20
+ constructor(entry, cwd) {
21
+ this.child = spawn(process.execPath, [entry], { cwd, stdio: 'pipe' });
22
+ this.child.stderr.on('data', (data) => { this.stderr = (this.stderr + data.toString()).slice(-4000); });
23
+ this.child.stdout.on('data', (data) => this.receive(data));
24
+ this.child.stdin.on('error', error => this.fail(error));
25
+ this.child.on('error', error => this.fail(error));
26
+ this.child.on('exit', code => this.fail(new Error(`East LSP exited (${code}): ${this.stderr}`)));
27
+ this.ready = this.request('initialize', { processId: process.pid, rootUri: pathToFileURL(cwd).href, capabilities: {} })
28
+ .then(() => { this.send({ method: 'initialized', params: {} }); });
29
+ }
30
+ fail(error) {
31
+ this.failure = error;
32
+ for (const request of this.requests.values())
33
+ request.reject(error);
34
+ this.requests.clear();
35
+ for (const waiters of this.waiters.values())
36
+ for (const notify of waiters)
37
+ notify(null);
38
+ this.waiters.clear();
39
+ }
40
+ send(message) {
41
+ if (this.failure)
42
+ throw this.failure;
43
+ const body = JSON.stringify({ jsonrpc: '2.0', ...message });
44
+ this.child.stdin.write(`Content-Length: ${Buffer.byteLength(body)}\r\n\r\n${body}`);
45
+ }
46
+ request(method, params) {
47
+ const id = ++this.nextId;
48
+ return new Promise((resolveResult, reject) => {
49
+ const timer = setTimeout(() => { this.requests.delete(id); reject(new Error(`LSP ${method} timed out`)); this.close(); }, 15000);
50
+ this.requests.set(id, {
51
+ resolve: value => { clearTimeout(timer); resolveResult(value); },
52
+ reject: error => { clearTimeout(timer); reject(error); },
53
+ });
54
+ try {
55
+ this.send({ id, method, params });
56
+ }
57
+ catch (error) {
58
+ this.requests.get(id)?.reject(error);
59
+ this.requests.delete(id);
60
+ }
61
+ });
62
+ }
63
+ receive(chunk) {
64
+ this.buffer = Buffer.concat([this.buffer, chunk]);
65
+ for (;;) {
66
+ const end = this.buffer.indexOf('\r\n\r\n');
67
+ if (end < 0)
68
+ return;
69
+ const match = /Content-Length:\s*(\d+)/i.exec(this.buffer.subarray(0, end).toString());
70
+ if (!match) {
71
+ this.fail(new Error('Invalid LSP header'));
72
+ this.close();
73
+ return;
74
+ }
75
+ const length = Number(match[1]);
76
+ if (this.buffer.length < end + 4 + length)
77
+ return;
78
+ const body = this.buffer.subarray(end + 4, end + 4 + length);
79
+ this.buffer = this.buffer.subarray(end + 4 + length);
80
+ let message;
81
+ try {
82
+ message = JSON.parse(body.toString());
83
+ }
84
+ catch {
85
+ continue;
86
+ }
87
+ if (message.id !== undefined && !message.method) {
88
+ const pending = this.requests.get(message.id);
89
+ if (message.error)
90
+ pending?.reject(new Error(JSON.stringify(message.error)));
91
+ else
92
+ pending?.resolve(message.result);
93
+ this.requests.delete(message.id);
94
+ }
95
+ else if (message.method === 'textDocument/publishDiagnostics' && typeof message.params?.['uri'] === 'string') {
96
+ const publication = message.params;
97
+ // Some servers publish unescaped file URIs; normalize both sides.
98
+ const uri = pathToFileURL(fileURLToPath(publication.uri)).href;
99
+ this.publications.set(uri, publication);
100
+ for (const notify of this.waiters.get(uri) ?? [])
101
+ notify(publication);
102
+ }
103
+ else if (message.id !== undefined) {
104
+ this.send({ id: message.id, result: null });
105
+ }
106
+ }
107
+ }
108
+ /** Serialize document operations so concurrent MCP calls cannot mix publications. */
109
+ diagnostics(file, timeoutMs, refresh = true) {
110
+ const operation = this.queue.catch(() => { }).then(async () => {
111
+ await this.ready;
112
+ if (this.failure)
113
+ throw this.failure;
114
+ const path = resolve(file);
115
+ const uri = pathToFileURL(path).href;
116
+ if (!refresh)
117
+ return this.publications.get(uri) ?? null;
118
+ const text = await readFile(path, 'utf8');
119
+ const version = (this.versions.get(uri) ?? 0) + 1;
120
+ this.publications.delete(uri);
121
+ const result = new Promise((done) => {
122
+ const listeners = this.waiters.get(uri) ?? new Set();
123
+ let timer;
124
+ const notify = (publication) => {
125
+ clearTimeout(timer);
126
+ listeners.delete(notify);
127
+ if (listeners.size === 0)
128
+ this.waiters.delete(uri);
129
+ done(publication);
130
+ };
131
+ timer = setTimeout(() => notify(null), timeoutMs);
132
+ listeners.add(notify);
133
+ this.waiters.set(uri, listeners);
134
+ });
135
+ this.versions.set(uri, version);
136
+ if (version === 1)
137
+ this.send({ method: 'textDocument/didOpen', params: { textDocument: { uri, languageId: path.endsWith('.py') ? 'python' : path.endsWith('.tsx') ? 'typescriptreact' : 'typescript', version, text } } });
138
+ else {
139
+ this.send({ method: 'textDocument/didChange', params: { textDocument: { uri, version }, contentChanges: [{ text }] } });
140
+ this.send({ method: 'textDocument/didSave', params: { textDocument: { uri }, text } });
141
+ }
142
+ return result;
143
+ });
144
+ this.queue = operation;
145
+ return operation;
146
+ }
147
+ close() {
148
+ if (this.closing)
149
+ return;
150
+ this.closing = true;
151
+ if (this.failure) {
152
+ this.child.stdin.end();
153
+ this.child.kill();
154
+ return;
155
+ }
156
+ // Let the Python launcher dispose its own child before forcing termination.
157
+ const force = setTimeout(() => this.child.kill(), 1000);
158
+ force.unref();
159
+ this.child.once('exit', () => clearTimeout(force));
160
+ void this.request('shutdown', {}).then(() => {
161
+ this.send({ method: 'exit' });
162
+ this.child.stdin.end();
163
+ }).catch(() => { this.child.stdin.end(); this.child.kill(); });
164
+ }
165
+ }
166
+ export class EastLspPool {
167
+ clients = new Map();
168
+ async diagnostics(file, timeoutMs = 15000, refresh = true) {
169
+ file = resolve(file);
170
+ if (!/\.(ts|tsx|py)$/.test(file))
171
+ throw new Error('East LSP supports .ts, .tsx and .py files');
172
+ let cwd = dirname(file);
173
+ for (let dir = cwd;; dir = dirname(dir)) {
174
+ if (existsSync(join(dir, file.endsWith('.py') ? 'pyproject.toml' : 'tsconfig.json'))) {
175
+ cwd = dir;
176
+ break;
177
+ }
178
+ if (dirname(dir) === dir)
179
+ break;
180
+ }
181
+ const entry = file.endsWith('.py') ? 'east-py-lsp.js' : 'lsp.js';
182
+ const key = `${cwd}\0${entry}`;
183
+ let client = this.clients.get(key);
184
+ if (!client) {
185
+ client = new EastLspClient(fileURLToPath(new URL(`../daemon/${entry}`, import.meta.url)), cwd);
186
+ this.clients.set(key, client);
187
+ }
188
+ try {
189
+ return await client.diagnostics(file, timeoutMs, refresh);
190
+ }
191
+ catch (error) {
192
+ client.close();
193
+ this.clients.delete(key);
194
+ throw error;
195
+ }
196
+ }
197
+ close() { for (const client of this.clients.values())
198
+ client.close(); this.clients.clear(); }
199
+ }
200
+ //# sourceMappingURL=lsp-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp-client.js","sourceRoot":"","sources":["../../lib/lsp-client.ts"],"names":[],"mappings":"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"}