@elaraai/e3-cloud-codex-plugin 0.0.0-stage → 1.0.90-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,306 @@
1
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.90_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/codex-hook.js
2
+ import { readFile as readFile2 } from "node:fs/promises";
3
+ import { existsSync, writeFileSync } from "node:fs";
4
+ import { createHash } from "node:crypto";
5
+ import { tmpdir } from "node:os";
6
+ import { join, resolve as resolve3 } from "node:path";
7
+
8
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.90_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/codex-tools.js
9
+ import { resolve } from "node:path";
10
+ function patchFiles(command, cwd) {
11
+ const files = [];
12
+ let current;
13
+ for (const line of command.split(/\r?\n/)) {
14
+ const header = /^\*\*\* (Add|Update|Delete) File: (.+)$/.exec(line);
15
+ if (header) {
16
+ const path = resolve(cwd, header[2]);
17
+ current = { path, originalPath: path, code: "", deleted: header[1] === "Delete" };
18
+ files.push(current);
19
+ } else if (line.startsWith("*** Move to: ") && current) {
20
+ current.path = resolve(cwd, line.slice(13));
21
+ } else if (current && (line.startsWith("+") || line.startsWith(" "))) {
22
+ current.code += line.slice(1) + "\n";
23
+ }
24
+ }
25
+ return files;
26
+ }
27
+ function shellReadPaths(command, cwd) {
28
+ const paths = /* @__PURE__ */ new Set();
29
+ let dir = cwd;
30
+ for (const segment of command.split(/&&|;|\n|\|/)) {
31
+ const tokens = [...segment.matchAll(/"([^"\n]*)"|'([^'\n]*)'|([^\s]+)/g)].map((m) => m[1] ?? m[2] ?? m[3]);
32
+ if (tokens[0] === "cd" && tokens[1]) {
33
+ dir = resolve(dir, tokens[1]);
34
+ continue;
35
+ }
36
+ if (!["cat", "head", "tail", "sed", "rg", "grep", "less", "more"].includes(tokens[0] ?? ""))
37
+ continue;
38
+ for (const token of tokens.slice(1)) {
39
+ if (!token.startsWith("-") && !/[*?$`]/.test(token) && /\.(tsx?|js|py)$/.test(token))
40
+ paths.add(resolve(dir, token));
41
+ }
42
+ }
43
+ return [...paths];
44
+ }
45
+
46
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.90_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/bash-writes.js
47
+ import { resolve as resolve2 } from "node:path";
48
+ function isRealPath(token) {
49
+ if (token === "" || token.startsWith("&"))
50
+ return false;
51
+ if (/^\d+$/.test(token))
52
+ return false;
53
+ return !token.startsWith("/dev/");
54
+ }
55
+ function unquote(token) {
56
+ const m = /^(['"])(.*)\1$/.exec(token);
57
+ return m?.[2] ?? token;
58
+ }
59
+ function segments(command) {
60
+ return command.split(/\|\||&&|[;|\n]/);
61
+ }
62
+ function lastToken(segment) {
63
+ const tokens = segment.trim().split(/\s+/).map(unquote).filter((t) => t !== "" && !t.startsWith("-"));
64
+ const last = tokens.at(-1);
65
+ return last !== void 0 && isRealPath(last) ? last : void 0;
66
+ }
67
+ function writtenPaths(command, cwd) {
68
+ const found = /* @__PURE__ */ new Set();
69
+ let dir = cwd;
70
+ const add = (path) => {
71
+ if (!isRealPath(path))
72
+ return;
73
+ found.add(dir === void 0 ? path : resolve2(dir, path));
74
+ };
75
+ for (const segment of segments(command)) {
76
+ const trimmed = segment.trim();
77
+ const moved = /^cd\s+(['"]?)([^\s'";|&<>]+)\1\s*$/.exec(trimmed);
78
+ if (moved !== null && dir !== void 0) {
79
+ dir = resolve2(dir, unquote(moved[2] ?? ""));
80
+ continue;
81
+ }
82
+ for (const match of trimmed.matchAll(/>>?\s*(['"]?)([^\s'";|&<>]+)\1/g))
83
+ add(unquote(match[2] ?? ""));
84
+ for (const match of trimmed.matchAll(/\btee\s+(?:-a\s+)?(['"]?)([^\s'";|&<>]+)\1/g))
85
+ add(unquote(match[2] ?? ""));
86
+ if (/^\s*(sed\s+(-[^\s]*\s+)*-i|cp|mv|install)\b/.test(trimmed)) {
87
+ const path = lastToken(trimmed);
88
+ if (path !== void 0)
89
+ add(path);
90
+ }
91
+ }
92
+ return [...found];
93
+ }
94
+
95
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.90_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/transcript.js
96
+ import { readFile } from "node:fs/promises";
97
+ var SEARCH_TOOLS = ["mcp__plugin_east_east__search_east_examples", "mcp__plugin_east_east__get_east_example", "mcp__east__search_east_examples", "mcp__east__get_east_example"];
98
+ async function searchedInTranscript(transcriptPath, tools = SEARCH_TOOLS) {
99
+ let raw;
100
+ try {
101
+ raw = await readFile(transcriptPath, "utf-8");
102
+ } catch {
103
+ return false;
104
+ }
105
+ return tools.some((tool) => raw.includes(`"name":"${tool}"`) || raw.includes(`"name": "${tool}"`));
106
+ }
107
+
108
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.90_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-guidance.js
109
+ var EAST_GUIDANCE = {
110
+ searchTool: "mcp__plugin_east_east__search_east_examples",
111
+ getTool: "mcp__plugin_east_east__get_east_example",
112
+ corpus: "East",
113
+ scope: "@elaraai"
114
+ };
115
+ function bare(tool) {
116
+ const at = tool.lastIndexOf("__");
117
+ return at < 0 ? tool : tool.slice(at + 2);
118
+ }
119
+ function gateText(g) {
120
+ return [
121
+ `STOP: no ${g.corpus} example search on record in this session, and this is ${g.corpus} code.`,
122
+ `Before writing or changing ${g.corpus} code, search the tested example index \u2014 it is the API reference:`,
123
+ `1. \`${g.searchTool}\` with what you are about to do (language: "python" for east-py, "typescript" otherwise); summaries come back \u2014 id, signature, inputs and result.`,
124
+ `2. \`${g.getTool}\` for the one or two that match, and pattern your code on them.`,
125
+ `Do not read node_modules/${g.scope}/** or *.examples.ts files instead: the index is the same corpus, exact and far cheaper. Every ${g.corpus} skill requires this step.`
126
+ ].join("\n");
127
+ }
128
+ function readText(g) {
129
+ return [
130
+ `Note: the ${g.corpus} example index is the API reference \u2014 \`${g.searchTool}\` (then \`${bare(g.getTool)}\`) returns the same tested programs as the ${g.corpus} packages' examples and type declarations, exact, printed in TypeScript or python, at a fraction of the tokens.`,
131
+ `Reading \`.d.ts\` signatures or sweeping \`*.examples.ts\` files reliably produces broken ${g.corpus} code that still type-checks: the signatures omit the runtime rules. Search instead, and read a specific file only when the search pointed you at it.`
132
+ ].join("\n");
133
+ }
134
+ function corpusReadFor(scope) {
135
+ const escaped = scope.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
136
+ const packagePath = new RegExp(`[/\\\\]node_modules[/\\\\]${escaped}[/\\\\]`);
137
+ const packagePattern = new RegExp(`(^|[/\\\\])node_modules[/\\\\]${escaped}([/\\\\]|$)`);
138
+ const examplesFile = /\.examples\.tsx?$/;
139
+ return (tool, input) => {
140
+ const file = typeof input["file_path"] === "string" ? input["file_path"] : "";
141
+ const dir = typeof input["path"] === "string" ? input["path"] : "";
142
+ const pattern = typeof input["pattern"] === "string" ? input["pattern"] : "";
143
+ return tool === "Read" ? packagePath.test(file) || examplesFile.test(file) : packagePath.test(dir) || packagePattern.test(pattern) || /\.examples\.tsx?/.test(pattern);
144
+ };
145
+ }
146
+ var GATE_TEXT = gateText(EAST_GUIDANCE);
147
+ var READ_TEXT = readText(EAST_GUIDANCE);
148
+ var isExampleCorpusRead = corpusReadFor(EAST_GUIDANCE.scope);
149
+
150
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.90_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/codex-hook.js
151
+ function codexToolCall(event) {
152
+ const cwd = event.cwd || process.cwd();
153
+ const input = event.tool_input ?? {};
154
+ const command = typeof input.command === "string" ? input.command : typeof input["cmd"] === "string" ? input["cmd"] : "";
155
+ const tool = event.tool_name ?? "";
156
+ const patches = tool === "apply_patch" ? patchFiles(command, cwd) : [];
157
+ const shell = ["Bash", "exec_command", "shell_command"].includes(tool);
158
+ const filePath = typeof input.file_path === "string" ? resolve3(cwd, input.file_path) : void 0;
159
+ const paths = [.../* @__PURE__ */ new Set([
160
+ ...patches.filter((p) => !p.deleted).map((p) => p.path),
161
+ ...shell ? [...writtenPaths(command, cwd), ...shellReadPaths(command, cwd)] : [],
162
+ ...filePath ? [filePath] : []
163
+ ])];
164
+ return { tool, command, shell, patches, filePath, paths };
165
+ }
166
+ async function codexSearchGate(event, options, call = codexToolCall(event)) {
167
+ const input = event.tool_input ?? {};
168
+ const marker = join(tmpdir(), options.markerPrefix + createHash("sha256").update(event.session_id ?? "").digest("hex"));
169
+ if (event.hook_event_name === "PostToolUse") {
170
+ if (call.tool.startsWith("mcp__") && options.searchToolName.test(call.tool)) {
171
+ if (event.tool_response?.["isError"] !== true)
172
+ writeFileSync(marker, "searched");
173
+ return "recorded";
174
+ }
175
+ return null;
176
+ }
177
+ const context = [];
178
+ if (options.isCorpusRead(call.tool, input) || call.shell && options.shellSweep.test(call.command)) {
179
+ context.push(options.readText);
180
+ }
181
+ const writes = call.tool === "apply_patch" ? call.patches.filter((p) => !p.deleted) : call.shell ? writtenPaths(call.command, event.cwd || process.cwd()).map((path) => ({ path, originalPath: path, code: call.command })) : call.filePath && ["Edit", "Write"].includes(call.tool) ? [{ path: call.filePath, originalPath: call.filePath, code: input.content ?? input.new_string ?? "" }] : [];
182
+ let corpusWrite = false;
183
+ for (const file of writes) {
184
+ if (!/\.(tsx?|js|py)$/.test(file.path))
185
+ continue;
186
+ let old = "";
187
+ try {
188
+ old = await readFile2(file.originalPath, "utf8");
189
+ } catch {
190
+ }
191
+ if (options.corpusCode.test(old + "\n" + file.code))
192
+ corpusWrite = true;
193
+ }
194
+ if (corpusWrite && !existsSync(marker) && !(event.transcript_path && await searchedInTranscript(event.transcript_path, options.searchTools))) {
195
+ if (process.env[options.requireSearchEnv] === "deny")
196
+ return { decision: "deny", text: options.gateText };
197
+ context.push(options.gateText);
198
+ }
199
+ return context.length > 0 ? { decision: "context", text: context.join("\n\n") } : null;
200
+ }
201
+
202
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.90_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/host.js
203
+ import { existsSync as existsSync2 } from "node:fs";
204
+ import { fileURLToPath } from "node:url";
205
+ var isCodex = existsSync2(fileURLToPath(new URL("../../.codex-plugin/plugin.json", import.meta.url)));
206
+ function hostText(text) {
207
+ return isCodex ? text.replaceAll("mcp__plugin_east_east__", "").replaceAll("/east:", "$east-codex-plugin:").replaceAll("Claude Code", "Codex") : text;
208
+ }
209
+
210
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.90_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/hook-io.js
211
+ async function readHookInput() {
212
+ let input = "";
213
+ for await (const chunk of process.stdin) {
214
+ input += chunk;
215
+ }
216
+ return JSON.parse(input);
217
+ }
218
+ function writeHookOutput(hookEventName, additionalContext) {
219
+ const output = {
220
+ hookSpecificOutput: {
221
+ hookEventName,
222
+ additionalContext: hostText(additionalContext)
223
+ }
224
+ };
225
+ process.stdout.write(JSON.stringify(output));
226
+ }
227
+ function writeHookDecision(hookEventName, decision, reason) {
228
+ const output = {
229
+ hookSpecificOutput: {
230
+ hookEventName,
231
+ permissionDecision: decision,
232
+ permissionDecisionReason: hostText(reason)
233
+ }
234
+ };
235
+ process.stdout.write(JSON.stringify(output));
236
+ }
237
+
238
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.90_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-hooks.js
239
+ function writeSearchHookReply(hookEventName, reply) {
240
+ if (reply.decision === "deny")
241
+ writeHookDecision(hookEventName, "deny", reply.text);
242
+ else
243
+ writeHookOutput(hookEventName, reply.text);
244
+ }
245
+
246
+ // ../e3-cloud-plugin/dist/lib/names.js
247
+ var E3_CLOUD_PLUGIN = "e3-cloud";
248
+ var E3_CLOUD_SERVER = "e3-cloud";
249
+ var E3_CLOUD_SEARCH_TOOL = "search_e3_cloud_examples";
250
+ var E3_CLOUD_GET_TOOL = "get_e3_cloud_example";
251
+ var E3_CLOUD_CORPUS = "e3 cloud";
252
+ var CLAUDE_TOOL_PREFIX = `mcp__plugin_${E3_CLOUD_PLUGIN}_${E3_CLOUD_SERVER}__`;
253
+ var E3_CLOUD_GUIDANCE = {
254
+ searchTool: `${CLAUDE_TOOL_PREFIX}${E3_CLOUD_SEARCH_TOOL}`,
255
+ getTool: `${CLAUDE_TOOL_PREFIX}${E3_CLOUD_GET_TOOL}`,
256
+ corpus: E3_CLOUD_CORPUS,
257
+ scope: "@elaraai"
258
+ };
259
+ var E3_CLOUD_CODE = /@elaraai\/e3-cloud-(?:ui|client)\b/;
260
+ var PACKAGE_PATH = /[/\\]node_modules[/\\]@elaraai[/\\]e3-cloud-(?:ui|cli|client)(?:[/\\]|$)/;
261
+ var PACKAGE_PATTERN = /(?:^|[/\\])node_modules[/\\]@elaraai[/\\]e3-cloud-(?:ui|cli|client)(?:[/\\]|$)/;
262
+ function isE3CloudCorpusRead(tool, input) {
263
+ const text = (key) => typeof input[key] === "string" ? input[key] : "";
264
+ return tool === "Read" ? PACKAGE_PATH.test(text("file_path")) : PACKAGE_PATH.test(text("path")) || PACKAGE_PATTERN.test(text("pattern"));
265
+ }
266
+ var E3_CLOUD_SEARCH_GATE = {
267
+ searchTools: [E3_CLOUD_GUIDANCE.searchTool, E3_CLOUD_GUIDANCE.getTool, ...SEARCH_TOOLS],
268
+ gateText: gateText(E3_CLOUD_GUIDANCE),
269
+ isCorpusCode: (code, python) => !python && E3_CLOUD_CODE.test(code),
270
+ markerPrefix: "e3-cloud-search-seen",
271
+ requireSearchEnv: "E3_CLOUD_REQUIRE_SEARCH"
272
+ };
273
+ var E3_CLOUD_READ_REMINDER = {
274
+ readText: readText(E3_CLOUD_GUIDANCE),
275
+ isCorpusRead: isE3CloudCorpusRead
276
+ };
277
+ var E3_CLOUD_CODEX_SEARCH_GATE = {
278
+ searchTools: E3_CLOUD_SEARCH_GATE.searchTools,
279
+ searchToolName: /__(?:search_e3_cloud_examples|get_e3_cloud_example|search_east_examples|get_east_example)$/,
280
+ gateText: E3_CLOUD_SEARCH_GATE.gateText,
281
+ readText: E3_CLOUD_READ_REMINDER.readText,
282
+ isCorpusRead: isE3CloudCorpusRead,
283
+ shellSweep: /node_modules\/@elaraai\/e3-cloud-(?:ui|cli|client)\b/,
284
+ corpusCode: E3_CLOUD_CODE,
285
+ markerPrefix: "e3-cloud-codex-search-",
286
+ requireSearchEnv: "E3_CLOUD_REQUIRE_SEARCH"
287
+ };
288
+ var E3_CLOUD_SKILL_NAMES = {
289
+ claudeToolPrefix: CLAUDE_TOOL_PREFIX,
290
+ claudeSkillPrefix: `/${E3_CLOUD_PLUGIN}:`,
291
+ codexSkillPrefix: "$e3-cloud-codex-plugin:",
292
+ claudePlugin: "e3-cloud-claude-plugin",
293
+ codexPlugin: "e3-cloud-codex-plugin"
294
+ };
295
+
296
+ // ../e3-cloud-plugin/dist/hooks/codex-tools.js
297
+ async function main() {
298
+ const event = await readHookInput();
299
+ const gate = await codexSearchGate(event, E3_CLOUD_CODEX_SEARCH_GATE, codexToolCall(event));
300
+ if (event.hook_event_name === "PreToolUse" && gate !== null && gate !== "recorded")
301
+ writeSearchHookReply("PreToolUse", gate);
302
+ }
303
+ main().catch((error) => {
304
+ process.stderr.write(`e3 cloud hook: ${String(error)}
305
+ `);
306
+ });