@elaraai/e3-cloud-claude-plugin 1.0.94 → 1.0.97

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.
@@ -1,4 +1,4 @@
1
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/host.js
1
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/host.js
2
2
  import { existsSync } from "node:fs";
3
3
  import { fileURLToPath } from "node:url";
4
4
  var isCodex = existsSync(fileURLToPath(new URL("../../.codex-plugin/plugin.json", import.meta.url)));
@@ -6,7 +6,7 @@ function hostText(text) {
6
6
  return isCodex ? text.replaceAll("mcp__plugin_east_east__", "").replaceAll("/east:", "$east-codex-plugin:").replaceAll("Claude Code", "Codex") : text;
7
7
  }
8
8
 
9
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/hook-io.js
9
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/hook-io.js
10
10
  async function readHookInput() {
11
11
  let input = "";
12
12
  for await (const chunk of process.stdin) {
@@ -34,10 +34,10 @@ function writeHookDecision(hookEventName, decision, reason) {
34
34
  process.stdout.write(JSON.stringify(output));
35
35
  }
36
36
 
37
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/transcript.js
37
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/transcript.js
38
38
  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"];
39
39
 
40
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-guidance.js
40
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-guidance.js
41
41
  var EAST_GUIDANCE = {
42
42
  searchTool: "mcp__plugin_east_east__search_east_examples",
43
43
  getTool: "mcp__plugin_east_east__get_east_example",
@@ -79,7 +79,7 @@ var GATE_TEXT = gateText(EAST_GUIDANCE);
79
79
  var READ_TEXT = readText(EAST_GUIDANCE);
80
80
  var isExampleCorpusRead = corpusReadFor(EAST_GUIDANCE.scope);
81
81
 
82
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-hooks.js
82
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-hooks.js
83
83
  function preReadReminder(event, options) {
84
84
  return options.isCorpusRead(event.tool_name ?? "", event.tool_input ?? {}) ? { decision: "context", text: options.readText } : null;
85
85
  }
@@ -1,10 +1,10 @@
1
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-hooks.js
1
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-hooks.js
2
2
  import { readFile as readFile2 } from "node:fs/promises";
3
3
  import { existsSync as existsSync2, writeFileSync } from "node:fs";
4
4
  import { tmpdir } from "node:os";
5
5
  import { join } from "node:path";
6
6
 
7
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/host.js
7
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/host.js
8
8
  import { existsSync } from "node:fs";
9
9
  import { fileURLToPath } from "node:url";
10
10
  var isCodex = existsSync(fileURLToPath(new URL("../../.codex-plugin/plugin.json", import.meta.url)));
@@ -12,7 +12,7 @@ function hostText(text) {
12
12
  return isCodex ? text.replaceAll("mcp__plugin_east_east__", "").replaceAll("/east:", "$east-codex-plugin:").replaceAll("Claude Code", "Codex") : text;
13
13
  }
14
14
 
15
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/hook-io.js
15
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/hook-io.js
16
16
  async function readHookInput() {
17
17
  let input = "";
18
18
  for await (const chunk of process.stdin) {
@@ -40,7 +40,7 @@ function writeHookDecision(hookEventName, decision, reason) {
40
40
  process.stdout.write(JSON.stringify(output));
41
41
  }
42
42
 
43
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/transcript.js
43
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/transcript.js
44
44
  import { readFile } from "node:fs/promises";
45
45
  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"];
46
46
  async function searchedInTranscript(transcriptPath, tools = SEARCH_TOOLS) {
@@ -53,7 +53,7 @@ async function searchedInTranscript(transcriptPath, tools = SEARCH_TOOLS) {
53
53
  return tools.some((tool) => raw.includes(`"name":"${tool}"`) || raw.includes(`"name": "${tool}"`));
54
54
  }
55
55
 
56
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-guidance.js
56
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-guidance.js
57
57
  var EAST_GUIDANCE = {
58
58
  searchTool: "mcp__plugin_east_east__search_east_examples",
59
59
  getTool: "mcp__plugin_east_east__get_east_example",
@@ -95,7 +95,7 @@ var GATE_TEXT = gateText(EAST_GUIDANCE);
95
95
  var READ_TEXT = readText(EAST_GUIDANCE);
96
96
  var isExampleCorpusRead = corpusReadFor(EAST_GUIDANCE.scope);
97
97
 
98
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-hooks.js
98
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-hooks.js
99
99
  async function preWriteGate(event, options) {
100
100
  const cwd = event.cwd || process.cwd();
101
101
  const filePath = event.tool_input?.file_path;
@@ -3098,9 +3098,9 @@ var require_data = __commonJS({
3098
3098
  }
3099
3099
  });
3100
3100
 
3101
- // ../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/lib/utils.js
3101
+ // ../../node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/lib/utils.js
3102
3102
  var require_utils = __commonJS({
3103
- "../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/lib/utils.js"(exports, module) {
3103
+ "../../node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/lib/utils.js"(exports, module) {
3104
3104
  "use strict";
3105
3105
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
3106
3106
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
@@ -3332,6 +3332,37 @@ var require_utils = __commonJS({
3332
3332
  }
3333
3333
  return output.join("");
3334
3334
  }
3335
+ function removeDotSegmentsRelative(path) {
3336
+ if (path === "" || path[0] === "/") {
3337
+ return removeDotSegments(path);
3338
+ }
3339
+ const segments = path.split("/");
3340
+ const last2 = segments.length - 1;
3341
+ const output = [];
3342
+ let trailingDirectory = false;
3343
+ for (let i = 0; i <= last2; i++) {
3344
+ const segment = segments[i];
3345
+ if (segment === "." || segment === "..") {
3346
+ if (segment === "..") {
3347
+ if (output.length !== 0 && output[output.length - 1] !== "..") {
3348
+ output.pop();
3349
+ } else {
3350
+ output.push("..");
3351
+ }
3352
+ }
3353
+ trailingDirectory = i === last2;
3354
+ } else {
3355
+ output.push(segment);
3356
+ }
3357
+ }
3358
+ if (trailingDirectory && output[output.length - 1] !== "..") {
3359
+ output.push("");
3360
+ }
3361
+ if (output.length === 0 || output[0] === "" || output[0].includes(":")) {
3362
+ output.unshift(".");
3363
+ }
3364
+ return output.join("/");
3365
+ }
3335
3366
  var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
3336
3367
  var HOST_DELIM_RE = /[@/?#:]/g;
3337
3368
  var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
@@ -3592,6 +3623,7 @@ var require_utils = __commonJS({
3592
3623
  encodeFragment,
3593
3624
  escapePreservingEscapes,
3594
3625
  removeDotSegments,
3626
+ removeDotSegmentsRelative,
3595
3627
  isIPv4,
3596
3628
  isUUID,
3597
3629
  normalizeIPv6,
@@ -3600,9 +3632,9 @@ var require_utils = __commonJS({
3600
3632
  }
3601
3633
  });
3602
3634
 
3603
- // ../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/lib/schemes.js
3635
+ // ../../node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/lib/schemes.js
3604
3636
  var require_schemes = __commonJS({
3605
- "../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/lib/schemes.js"(exports, module) {
3637
+ "../../node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/lib/schemes.js"(exports, module) {
3606
3638
  "use strict";
3607
3639
  var { isUUID } = require_utils();
3608
3640
  var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
@@ -3811,20 +3843,22 @@ var require_schemes = __commonJS({
3811
3843
  }
3812
3844
  });
3813
3845
 
3814
- // ../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/index.js
3846
+ // ../../node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/index.js
3815
3847
  var require_fast_uri = __commonJS({
3816
- "../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/index.js"(exports, module) {
3848
+ "../../node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/index.js"(exports, module) {
3817
3849
  "use strict";
3818
- var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3850
+ var { normalizeIPv6, removeDotSegments, removeDotSegmentsRelative, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3819
3851
  var { SCHEMES, getSchemeHandler } = require_schemes();
3820
3852
  var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
3821
3853
  var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
3822
- function decodeValidScheme(scheme) {
3823
- const decodedScheme = unescape(String(scheme));
3824
- if (!VALID_SCHEME.test(decodedScheme)) {
3854
+ var MALFORMED_HOST_ERROR = "URI host is malformed.";
3855
+ var FORBIDDEN_DOMAIN_HOST_CHARACTER = /[\0-\x20"#/:<>?@[\\\]^`{|}\x7F]/u;
3856
+ function validateScheme(scheme) {
3857
+ const stringScheme = String(scheme);
3858
+ if (!VALID_SCHEME.test(stringScheme)) {
3825
3859
  throw new TypeError(MALFORMED_SCHEME_ERROR);
3826
3860
  }
3827
- return decodedScheme;
3861
+ return stringScheme;
3828
3862
  }
3829
3863
  function normalize(uri, options) {
3830
3864
  if (typeof uri === "string") {
@@ -3861,6 +3895,9 @@ var require_fast_uri = __commonJS({
3861
3895
  const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
3862
3896
  const resolvedHost = resolved.host;
3863
3897
  const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
3898
+ if (hasForbiddenDomainHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP)) {
3899
+ throw new Error(MALFORMED_HOST_ERROR);
3900
+ }
3864
3901
  canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
3865
3902
  const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !/\P{ASCII}/u.test(resolvedHost);
3866
3903
  if (resolved.error && !encodedASCIIHost) {
@@ -3902,14 +3939,15 @@ var require_fast_uri = __commonJS({
3902
3939
  if (relative.path[0] === "/") {
3903
3940
  target.path = removeDotSegments(relative.path);
3904
3941
  } else {
3905
- if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
3942
+ const baseHasAuthority = base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0;
3943
+ if (baseHasAuthority && !base.path) {
3906
3944
  target.path = "/" + relative.path;
3907
3945
  } else if (!base.path) {
3908
3946
  target.path = relative.path;
3909
3947
  } else {
3910
3948
  target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative.path;
3911
3949
  }
3912
- target.path = removeDotSegments(target.path);
3950
+ target.path = base.scheme === void 0 && !baseHasAuthority && target.path[0] !== "/" ? removeDotSegmentsRelative(target.path) : removeDotSegments(target.path);
3913
3951
  }
3914
3952
  target.query = relative.query;
3915
3953
  }
@@ -3947,12 +3985,13 @@ var require_fast_uri = __commonJS({
3947
3985
  const options = Object.assign({}, opts);
3948
3986
  const uriTokens = [];
3949
3987
  if (component.scheme) {
3950
- component.scheme = decodeValidScheme(component.scheme);
3988
+ component.scheme = validateScheme(component.scheme);
3951
3989
  }
3952
3990
  const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
3953
3991
  if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
3954
3992
  const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
3955
- const pathNoScheme = !options.skipEscape && component.scheme === void 0 && !hasAuthority;
3993
+ const schemelessReference = (component.scheme === void 0 || options.reference === "suffix") && !hasAuthority;
3994
+ const pathNoScheme = !options.skipEscape && schemelessReference;
3956
3995
  if (component.path !== void 0) {
3957
3996
  if (!options.skipEscape) {
3958
3997
  component.path = serializePathEncoding(component.path, pathNoScheme);
@@ -3961,7 +4000,7 @@ var require_fast_uri = __commonJS({
3961
4000
  }
3962
4001
  }
3963
4002
  if (options.reference !== "suffix" && component.scheme) {
3964
- component.scheme = decodeValidScheme(component.scheme);
4003
+ component.scheme = validateScheme(component.scheme);
3965
4004
  uriTokens.push(component.scheme, ":");
3966
4005
  }
3967
4006
  const authority = recomposeAuthority(component);
@@ -3977,9 +4016,9 @@ var require_fast_uri = __commonJS({
3977
4016
  if (component.path !== void 0) {
3978
4017
  let s = component.path;
3979
4018
  if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
3980
- s = removeDotSegments(s);
4019
+ s = schemelessReference && s[0] !== "/" ? removeDotSegmentsRelative(s) : removeDotSegments(s);
3981
4020
  }
3982
- if (pathNoScheme) {
4021
+ if (schemelessReference) {
3983
4022
  s = serializePathEncoding(s, true);
3984
4023
  }
3985
4024
  if (authority === void 0 && s[0] === "/" && s[1] === "/") {
@@ -4026,16 +4065,34 @@ var require_fast_uri = __commonJS({
4026
4065
  return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
4027
4066
  }
4028
4067
  function canonicalizeHost(parsed, options, schemeHandler, isIP) {
4068
+ if (hasForbiddenDomainHost(parsed, options, schemeHandler, isIP)) {
4069
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR;
4070
+ return true;
4071
+ }
4029
4072
  if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
4073
+ let url;
4030
4074
  try {
4031
- parsed.host = new URL("http://" + parsed.host).hostname;
4075
+ url = new URL("http://" + parsed.host);
4032
4076
  } catch (e) {
4033
4077
  parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
4034
4078
  return true;
4035
4079
  }
4080
+ if (!isHostOnlyURL(url)) {
4081
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR;
4082
+ return true;
4083
+ }
4084
+ parsed.host = url.hostname;
4036
4085
  }
4037
4086
  return false;
4038
4087
  }
4088
+ function hasForbiddenDomainHost(parsed, options, schemeHandler, isIP) {
4089
+ return Boolean(
4090
+ parsed.host && isIP === false && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && FORBIDDEN_DOMAIN_HOST_CHARACTER.test(parsed.host)
4091
+ );
4092
+ }
4093
+ function isHostOnlyURL(url) {
4094
+ return url.username === "" && url.password === "" && url.port === "" && url.pathname === "/" && url.search === "" && url.hash === "" && url.hostname !== "";
4095
+ }
4039
4096
  function parseWithStatus(uri, opts) {
4040
4097
  const options = Object.assign({}, opts);
4041
4098
  const parsed = {
@@ -4090,9 +4147,8 @@ var require_fast_uri = __commonJS({
4090
4147
  parsed.query = matches[7];
4091
4148
  parsed.fragment = matches[8];
4092
4149
  if (parsed.scheme !== void 0) {
4093
- const decodedScheme = unescape(parsed.scheme);
4094
- if (VALID_SCHEME.test(decodedScheme)) {
4095
- parsed.scheme = decodedScheme.toLowerCase();
4150
+ if (VALID_SCHEME.test(parsed.scheme)) {
4151
+ parsed.scheme = parsed.scheme.toLowerCase();
4096
4152
  } else {
4097
4153
  parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
4098
4154
  malformedScheme = true;
@@ -4120,7 +4176,7 @@ var require_fast_uri = __commonJS({
4120
4176
  malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
4121
4177
  parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
4122
4178
  if (malformedIPLiteral) {
4123
- parsed.error = parsed.error || "URI host is malformed.";
4179
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR;
4124
4180
  malformedAuthorityOrPort = true;
4125
4181
  }
4126
4182
  } else {
@@ -4148,7 +4204,7 @@ var require_fast_uri = __commonJS({
4148
4204
  if (!isIP) {
4149
4205
  host = normalizePercentEncoding(host.toLowerCase());
4150
4206
  }
4151
- parsed.host = reescapeHostDelimiters(host, isIP);
4207
+ parsed.host = isIP || options.scheme !== "null" ? reescapeHostDelimiters(host, isIP) : host;
4152
4208
  }
4153
4209
  if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
4154
4210
  if (parsed.path) {
@@ -21491,7 +21547,7 @@ var StdioServerTransport = class {
21491
21547
  }
21492
21548
  };
21493
21549
 
21494
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search.js
21550
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search.js
21495
21551
  import { readFile } from "node:fs/promises";
21496
21552
 
21497
21553
  // ../../node_modules/.pnpm/minisearch@7.2.0/node_modules/minisearch/dist/es/index.js
@@ -23304,7 +23360,7 @@ var objectToNumericMapAsync = async (object3) => {
23304
23360
  var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
23305
23361
  var SPACE_OR_PUNCTUATION = /[\n\r\p{Z}\p{P}]+/u;
23306
23362
 
23307
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-guidance.js
23363
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-guidance.js
23308
23364
  var EAST_GUIDANCE = {
23309
23365
  searchTool: "mcp__plugin_east_east__search_east_examples",
23310
23366
  getTool: "mcp__plugin_east_east__get_east_example",
@@ -23346,7 +23402,7 @@ var GATE_TEXT = gateText(EAST_GUIDANCE);
23346
23402
  var READ_TEXT = readText(EAST_GUIDANCE);
23347
23403
  var isExampleCorpusRead = corpusReadFor(EAST_GUIDANCE.scope);
23348
23404
 
23349
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search.js
23405
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search.js
23350
23406
  var MIN_SCORE = 5;
23351
23407
  async function loadIndexes(indexPaths) {
23352
23408
  const entries = [];
@@ -23471,7 +23527,7 @@ function getEntry(index, id) {
23471
23527
  return stored === void 0 ? null : stored;
23472
23528
  }
23473
23529
 
23474
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/mcp/example-tools.js
23530
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/mcp/example-tools.js
23475
23531
  var EAST_PACKAGES = ["east", "east-node-std", "east-node-io", "east-py-datascience", "east-ui", "e3-ui", "e3", "e3-ui-cli", "e3-create"];
23476
23532
  function isLoaded(index) {
23477
23533
  return typeof index.then === "function";
@@ -23544,7 +23600,7 @@ function registerExampleTools(server2, options) {
23544
23600
  import { fileURLToPath } from "node:url";
23545
23601
  var E3_CLOUD_INDEX_PATH = fileURLToPath(new URL("../../index.json", import.meta.url));
23546
23602
 
23547
- // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.94_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/transcript.js
23603
+ // ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.97_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/transcript.js
23548
23604
  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"];
23549
23605
 
23550
23606
  // ../e3-cloud-plugin/dist/lib/names.js
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "e3-cloud",
3
- "version": "1.0.94",
3
+ "version": "1.0.97",
4
4
  "description": "e3 cloud - apps for hosted e3 workspaces with @elaraai/e3-cloud-ui, files from buckets as inputs with @elaraai/e3-cloud-files, the e3-cloud CLI and @elaraai/e3-cloud-client: skills, example search and the search-first hooks",
5
5
  "author": {
6
6
  "name": "Elara AI",
package/index.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "version": 2,
3
3
  "stats": {
4
- "totalEntries": 38,
4
+ "totalEntries": 40,
5
5
  "totalFiles": 2,
6
6
  "packages": {
7
7
  "e3-cloud-ui": 12,
8
- "e3-cloud-files": 10,
9
- "e3-cloud-cli": 12,
8
+ "e3-cloud-files": 11,
9
+ "e3-cloud-cli": 13,
10
10
  "e3-cloud-client": 4
11
11
  }
12
12
  },
@@ -592,6 +592,40 @@
592
592
  "typescript"
593
593
  ]
594
594
  },
595
+ {
596
+ "id": "e3-cloud-files:static:typed",
597
+ "skill": "e3-cloud-files",
598
+ "package": "e3-cloud-files",
599
+ "file": "static",
600
+ "suite": "Files",
601
+ "test": "A beast2 file as an input of its type with no task in between (file or latest with a type), and a record's mutation fed by each new file: the declarations, the package, and what a sync does with them",
602
+ "keywords": [
603
+ "Files",
604
+ "type",
605
+ "beast2",
606
+ "typed",
607
+ "ArrayType",
608
+ "upload.file",
609
+ "upload.latest",
610
+ "upload.mutation",
611
+ "mutation",
612
+ "feed",
613
+ "record",
614
+ "e3.mutation.reduce",
615
+ "encodeBeast2For",
616
+ "collection",
617
+ "e3-cloud-files"
618
+ ],
619
+ "imports": [
620
+ "import { East, ArrayType, DictType, FloatType, IntegerType, StringType, StructType } from '@elaraai/east';",
621
+ "import e3, { type Runner } from '@elaraai/e3';",
622
+ "import { Files } from '@elaraai/e3-cloud-files';"
623
+ ],
624
+ "source": "// src/package.ts\nconst Price = StructType({ sku: StringType, price: FloatType });\nconst PriceBook = DictType(StringType, FloatType);\nexport const upload = Files.source('upload');\n// A beast2 file of Array<Price> (encodeBeast2For(ArrayType(Price)), east-py, e3 convert): an input of that type, taken in as the\n// value it holds, a collection of any size, its header checked first; a file of another type is refused naming both types\nexport const prices = upload.file('prices', { key: 'prices.beast2', type: ArrayType(Price) });\nexport const stock = upload.latest('stock', { prefix: 'stock/', include: '*.beast2', type: ArrayType(Price) }); // the greatest key, typed\n// A record the app's users edit, and a mutation of one argument that loads a delivery into it\nexport const priceBook = e3.record('price_book', PriceBook, new Map());\nexport const loadPrices = e3.mutation.reduce('load_prices', priceBook, East.function([PriceBook, ArrayType(Price)], PriceBook, ($, state, rows) => {\n const next = $.let(state.copy()); // the book as it is (a mutation's state is immutable), each delivered price over its sku's\n $.for(rows, ($, row) => { $(next.insertOrUpdate(row.sku, row.price, (_$, _existing, delivered) => delivered)); });\n return next;\n}));\nconst runner: Runner = { runtime: 'east-c', platforms: ['east-c-std'] };\nexport const summary = e3.task('price_summary', [prices, priceBook], East.function([ArrayType(Price), PriceBook], IntegerType, (_$, rows, book) => rows.size().add(book.size())), { runner });\nexport default e3.package('typed', '1.0.0', summary, loadPrices);\n\n// src/files.ts: each new delta file under deltas/ calls load_prices once with its value, by the file's hash; a refused file is\n// tried again only once it changes; a feed of a record with no state yet waits for it\nupload.mutation(loadPrices, { prefix: 'deltas/', include: '*.beast2' });\nexport default Files.manifest([upload]);",
625
+ "languages": [
626
+ "typescript"
627
+ ]
628
+ },
595
629
  {
596
630
  "id": "e3-cloud-files:static:test-sync",
597
631
  "skill": "e3-cloud-files",
@@ -925,12 +959,41 @@
925
959
  "--profile",
926
960
  "--latest",
927
961
  "--dry-run",
928
- "--input",
929
962
  "e3 dataflow run",
963
+ "e3-cloud",
964
+ "--target",
965
+ "--reset"
966
+ ],
967
+ "imports": [],
968
+ "source": "e3 workspace deploy ./repo dev --from-source src/package.ts\ne3-cloud files deploy ./repo dev src/files.ts --dry-run # checked against the package dev runs; changes nothing\ne3-cloud files deploy ./repo dev src/files.ts\ne3-cloud files bind ./repo dev upload s3://partner-drop/orders/ --profile partner --latest 30 # locally: your own profile, each folder's 30 newest\ne3-cloud files sync ./repo dev --dry-run # what a sync would take\ne3-cloud files sync ./repo dev # reads only files whose ETag or size changed\ne3-cloud files status ./repo dev # each mapping, its type, what it holds (pending for an unseeded record), bindings, the last sync\ne3 dataflow run ./repo dev # a sync doesn't run the dataflow\n# <repo> may be a repository URL instead (https://e3.example.com/repos/acme): the same commands, run by the platform",
969
+ "languages": [
970
+ "typescript"
971
+ ]
972
+ },
973
+ {
974
+ "id": "e3-cloud-cli:static:files-push",
975
+ "skill": "e3-cloud-cli",
976
+ "package": "e3-cloud-cli",
977
+ "file": "static",
978
+ "suite": "e3-cloud files",
979
+ "test": "Pushing files from disk into a source and taking them in: each file matched to the mapping that takes it (by its name, or --as), checked against its type and limit, put with your e3 login alone where the source is the deployment's own bucket, then synced; unchanged once it is there; --dry-run plans and puts nothing",
980
+ "keywords": [
981
+ "files",
982
+ "push",
983
+ "upload",
984
+ "put",
985
+ "--as",
986
+ "--dry-run",
987
+ "--profile",
988
+ "--reset",
989
+ "--target",
990
+ "beast2",
991
+ "typed",
992
+ "unchanged",
930
993
  "e3-cloud"
931
994
  ],
932
995
  "imports": [],
933
- "source": "e3 workspace deploy ./repo dev --from-source src/package.ts\ne3-cloud files deploy ./repo dev src/files.ts --dry-run # checked against the package dev runs; changes nothing\ne3-cloud files deploy ./repo dev src/files.ts\ne3-cloud files bind ./repo dev upload s3://partner-drop/orders/ --profile partner --latest 30 # locally: your own profile, each folder's 30 newest\ne3-cloud files sync ./repo dev --dry-run # what a sync would take\ne3-cloud files sync ./repo dev # reads only files whose ETag or size changed\ne3-cloud files status ./repo dev # declarations, bindings, the last sync\ne3 dataflow run ./repo dev # a sync doesn't run the dataflow\n# <repo> may be a repository URL instead (https://e3.example.com/repos/acme): the same commands, run by the platform",
996
+ "source": "# A file by its name (a file mapping's key, or the newest under a latest prefix), a directory to a folder mapping; a row per file\ne3-cloud files push https://e3.example.com/repos/acme dev ./data/prices.beast2 ./data/deltas/2026-10-19.beast2\n# prices.beast2 → prices Array<Struct{sku, price}> 38 MiB put taken in 412,310 rows\n# 2026-10-19.beast2 → mutation:price_book.load_prices load_prices 1 MiB put committed 9f2c1a0b7e3d\n# Next: e3 dataflow run https://e3.example.com/repos/acme dev\ne3-cloud files push ./repo dev ./data/orders/ --as orders # a directory's files into the orders folder, each at its path\ne3-cloud files push ./repo dev ./data/prices.beast2 --dry-run # the plan alone: put, unchanged or refused, and why\ne3-cloud files push ./repo dev ./data/x.beast2 --profile partner # a bucket the platform does not write: your own credentials\ne3-cloud files sync ./repo dev --target prices --target mutation:price_book.load_prices # only these targets\ne3-cloud files sync ./repo dev --reset price_book # a seeded record's file taken as its state again, mutations since or not",
934
997
  "languages": [
935
998
  "typescript"
936
999
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elaraai/e3-cloud-claude-plugin",
3
- "version": "1.0.94",
3
+ "version": "1.0.97",
4
4
  "description": "e3 cloud - apps for hosted e3 workspaces with @elaraai/e3-cloud-ui, files from buckets as inputs with @elaraai/e3-cloud-files, the e3-cloud CLI and @elaraai/e3-cloud-client: skills, example search and the search-first hooks",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "type": "module",
@@ -1,16 +1,18 @@
1
1
  ---
2
2
  name: e3-cloud-files
3
- description: "Files for e3 cloud — a solution's inputs that come from files in a bucket (s3://bucket/prefix/), declared in its code and synced when asked, the same on a local repository and a deployed workspace. Use when: (1) Declaring which inputs a bucket's files fill with Files.source(name) and its file, latest, folder and listing, then Files.manifest([...]) as a module's default export, (2) Decoding what arrives in a task: a Blob (file, latest), a Dict of path to Blob (folder) or a listing of sizes, times and ETags, as East's JSON, CSV or text, (3) Deploying the declarations to a workspace and binding each source to s3://bucket/prefix/ with e3-cloud files deploy and bind, (4) Syncing what changed with e3-cloud files sync, locally with your own cloud profile (--profile, --latest), then running the dataflow with e3 dataflow run, (5) Reading a refusal: declarations that don't fit the package (FilesDeclarationError, a deploy's problems), an unbound source, a file over its limit, a protected workspace (workspace_protected), (6) Moving declarations to production through staging: a release carries them with the package and apps, a rollback restores them, a copy brings bindings and what each input took, and production's bindings stay its own, (7) Reading Files' East types (FilesManifestType, FilesBindingType, FilesSyncReportType — @elaraai/e3-cloud-types)."
3
+ description: "Files for e3 cloud — a solution's inputs that come from files in a bucket (s3://bucket/prefix/), declared in its code and synced when asked, the same on a local repository and a deployed workspace. Use when: (1) Declaring which inputs a bucket's files fill with Files.source(name) and its file, latest, folder and listing, then Files.manifest([...]) as a module's default export, (2) Decoding what arrives in a task: a Blob (file, latest), a Dict of path to Blob (folder) or a listing of sizes, times and ETags, as East's JSON, CSV or text, (3) Deploying the declarations to a workspace and binding each source to s3://bucket/prefix/ with e3-cloud files deploy and bind, (4) Syncing what changed with e3-cloud files sync, locally with your own cloud profile (--profile, --latest), then running the dataflow with e3 dataflow run, (5) Reading a refusal: declarations that don't fit the package (FilesDeclarationError, a deploy's problems), an unbound source, a file over its limit, a protected workspace (workspace_protected), (6) Moving declarations to production through staging: a release carries them with the package and apps, a rollback restores them, a copy brings bindings and what each input took, and production's bindings stay its own, (7) Reading Files' East types (FilesManifestType, FilesBindingType, FilesSyncReportType — @elaraai/e3-cloud-types), (8) Taking a beast2 file in as an input of its type with no task in between: file or latest with a type, a collection of any size, (9) Feeding a record's mutation from files with source.mutation(def, spec), each new file applied once, (10) Pushing files from disk into a source and taking them in with e3-cloud files push, matched by name or --as, dry-run, unchanged, (11) Syncing or resetting particular targets with --target and --reset."
4
4
  ---
5
5
 
6
6
  # e3-cloud-files — files as e3 inputs
7
7
 
8
- A solution says in its code which of its inputs come from files in a bucket. Each
9
- workspace says where those files are, a bucket and a prefix, and
10
- `e3-cloud files sync` brings in what changed: on a local repository with your
11
- own cloud credentials, in the cloud with the platform's read-only role. A file
12
- arrives as it is, a `Blob`, and a task decodes it. Nothing polls: a sync runs
13
- when someone asks.
8
+ A solution says in its code which of its inputs come from files in a bucket,
9
+ and which records are fed from them. Each workspace says where those files
10
+ are, a bucket and a prefix, and `e3-cloud files sync` brings in what changed:
11
+ on a local repository with your own cloud credentials, in the cloud with the
12
+ platform's read-only role. A file arrives as it is, a `Blob`, and a task
13
+ decodes it; or, named with a type, a beast2 file arrives as the value it
14
+ holds, with no task in between. `e3-cloud files push` puts files from disk
15
+ into a source and takes them in. Nothing polls: a sync runs when someone asks.
14
16
 
15
17
  Read `README.md` for the author's guide; this file is the short form.
16
18
 
@@ -65,7 +67,10 @@ What do you need?
65
67
  ├─ Declare which inputs a bucket's files fill (src/files.ts)
66
68
  │ ├─ A place files come from → Files.source(name) — each workspace binds it to s3://bucket/prefix/
67
69
  │ ├─ One known file → source.file(input, { key }) input: Blob
70
+ │ ├─ A beast2 file as its value → source.file(input, { key, type: ArrayType(Row) }) input: Array<Row>, no task between
68
71
  │ ├─ The newest of a folder → source.latest(input, { prefix, include? }) input: Blob, the greatest key
72
+ │ ├─ The newest, typed → source.latest(input, { prefix, include?, type })
73
+ │ ├─ Feed a record's mutation → source.mutation(def, { key } | { prefix, include? }) each new file calls it once
69
74
  │ ├─ Every file of a folder → source.folder(input, { prefix, include? }) input: Dict<String, Blob> by path
70
75
  │ ├─ A folder's files, not bytes → source.listing(input, { prefix, include? }) input: Dict<String, {size, modified, etag}>
71
76
  │ ├─ Subfolders' files too → include: '**/*.csv' ('*.csv' is the top level only)
@@ -81,8 +86,9 @@ What do you need?
81
86
  │ ├─ Deploy the declarations → e3-cloud files deploy <repo> <ws> src/files.ts [--dry-run]
82
87
  │ ├─ Say where a source's files are → e3-cloud files bind <repo> <ws> <source> s3://bucket/prefix/ [--region r]
83
88
  │ │ └─ Locally only → --profile <aws profile>, --latest <n> (each folder's n greatest keys)
84
- │ ├─ Bring in what changed → e3-cloud files sync <repo> <ws> [--input name…] [--dry-run]
85
- │ ├─ What is declared, bound, synced → e3-cloud files status <repo> <ws>
89
+ │ ├─ Bring in what changed → e3-cloud files sync <repo> <ws> [--target t…] [--reset record…] [--dry-run]
90
+ │ ├─ Put files from disk → e3-cloud files push <repo> <ws> <file|dir>… [--as target] [--dry-run] [--profile p]
91
+ │ ├─ What is declared, bound, held → e3-cloud files status <repo> <ws> (each mapping, its type, what it holds, pending)
86
92
  │ └─ Run the dataflow on it → e3 dataflow run <repo> <ws> (a sync doesn't run it)
87
93
  ├─ Production: a workspace with a staging (a deployed repository's URL)
88
94
  │ ├─ Change its declarations → files deploy to the staging, then e3-cloud release <url> <staging> <production>
@@ -94,8 +100,8 @@ What do you need?
94
100
  │ └─ Rehearse on production's files → e3-cloud staging add … (a copy: declarations, bindings, what each input took)
95
101
  ├─ Keep synced inputs across a package deploy → e3 workspace deploy … --inputs keep-edited
96
102
  └─ Drive it from code
97
- ├─ The checks → @elaraai/e3-cloud-files/check: checkFiles, checkBindings, readPackageInputs
98
- ├─ The sync over your own ports → @elaraai/e3-cloud-files/sync: syncFiles (FilesReader, FilesWriter, FilesLedger)
103
+ ├─ The checks → @elaraai/e3-cloud-files/check: checkFiles, checkBindings, readPackageSurface
104
+ ├─ The sync over your own ports → @elaraai/e3-cloud-files/sync: syncFiles (FilesReader, FilesWriter, FilesLedger), planPush
99
105
  ├─ Writing an e3 store → @elaraai/e3-cloud-files/storage: storageWriter(storage, repo, ws)
100
106
  └─ Reading a bucket → @elaraai/e3-cloud-files/s3: s3FilesReader(client, { bucket, prefix })
101
107
  ```
@@ -117,7 +123,13 @@ export default Files.manifest([upload]); // what e3-cloud files deploy dep
117
123
  ```
118
124
 
119
125
  - Each shape is an ordinary `e3.input`, unassigned until a sync sets it: use
120
- it in tasks as any input, and give the tasks to `e3.package` as usual.
126
+ it in tasks as any input, and give the tasks to `e3.package` as usual. A
127
+ `file` or `latest` with a `type` is an input of that type: the file must be
128
+ beast2 of it (`encodeBeast2For(T)`, east-py, `e3 convert`), a collection of
129
+ any size, checked by its header before any other byte is read.
130
+ - `source.mutation(def, spec)` feeds a record's mutation: `def` is the
131
+ package's `e3.mutation.reduce` or `edit` taking exactly one argument, and
132
+ each new file is applied once, by its hash.
121
133
  - Keys and prefixes are relative to where a workspace binds the source; a
122
134
  prefix is `''` or ends with `/`.
123
135
  - `include` is a glob over the path under the prefix: `*` within one folder,
@@ -145,11 +157,19 @@ file's path under the prefix, in path order.
145
157
  ```
146
158
  e3-cloud files deploy <repo> <workspace> src/files.ts [--dry-run]
147
159
  e3-cloud files bind <repo> <workspace> upload s3://bucket/prefix/ [--region r] [--profile p] [--latest n]
148
- e3-cloud files sync <repo> <workspace> [--input name...] [--dry-run]
160
+ e3-cloud files sync <repo> <workspace> [--target name|record:r|mutation:r.m ...] [--reset record...] [--dry-run]
161
+ e3-cloud files push <repo> <workspace> <file|dir>... [--as target] [--reset record...] [--dry-run] [--profile p]
149
162
  e3-cloud files status <repo> <workspace>
150
163
  e3 dataflow run <repo> <workspace>
151
164
  ```
152
165
 
166
+ `files push` matches each file to the mapping that takes it (a `file` by its
167
+ name, a `latest` under its prefix, a directory to the `folder`; `--as` names
168
+ one), checks its type and size, puts it where the source is bound (the
169
+ platform signs the upload into the deployment's own bucket, bound to the
170
+ file's SHA-256; your own credentials elsewhere), then syncs what was put. A
171
+ file the source holds already is `unchanged`.
172
+
153
173
  `<repo>` is a local repository's path or a repository URL. Deploy the package
154
174
  first (`e3 workspace deploy`), then the declarations, which are checked
155
175
  against it. A sync reads only files whose ETag or size changed, writes only
@@ -161,9 +181,17 @@ keeps only each folder's n greatest keys.
161
181
  ## Traps
162
182
 
163
183
  - An input a mapping fills must be writable and of exactly its shape's type:
164
- `Blob`, `Dict<String, Blob>` (`FilesFolderType`) or the listing's
165
- (`FilesListingType`). Declare it through the shape; never write it with
166
- `e3.input` yourself.
184
+ `Blob`, the `type` it names, `Dict<String, Blob>` (`FilesFolderType`) or
185
+ the listing's (`FilesListingType`). Declare it through the shape; never
186
+ write it with `e3.input` yourself. A fed mutation takes exactly one
187
+ argument, of the file's type; a `patch` mutation cannot be fed.
188
+ - A typed file of another type, or no beast2, is refused by its header
189
+ (`type_mismatch` with both types, `not_beast2`): the input keeps its value.
190
+ A typed value that is no collection is at most 1 GiB; a collection's
191
+ segments at most 64 MiB (`segment_too_large`: write it again).
192
+ - A seeded record (`upload.record`) waits for the e3 release that lets a
193
+ record be declared with no initial value; the rest of typed files, feeds
194
+ and push is here now.
167
195
  - A file over 1 GiB less 64 KiB (`file`, `latest`), or over 64 MiB less
168
196
  64 KiB in a folder, is refused and named in the report, never truncated.
169
197
  So is a file the sync can't read (archived, under a key it may not use,