@elaraai/e3-cloud-codex-plugin 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.build/hooks/codex-tools.js +9 -9
- package/.build/mcp/server.js +5 -5
- package/.codex-plugin/plugin.json +1 -1
- package/index.json +105 -8
- package/package.json +1 -1
- package/skills/e3-cloud-cli/SKILL.md +20 -4
- package/skills/e3-cloud-client/SKILL.md +32 -8
- package/skills/e3-cloud-files/SKILL.md +36 -5
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
1
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/codex-hook.js
|
|
2
2
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
3
3
|
import { existsSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { join, resolve as resolve3 } from "node:path";
|
|
7
7
|
|
|
8
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
8
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/codex-tools.js
|
|
9
9
|
import { resolve } from "node:path";
|
|
10
10
|
function patchFiles(command, cwd) {
|
|
11
11
|
const files = [];
|
|
@@ -43,7 +43,7 @@ function shellReadPaths(command, cwd) {
|
|
|
43
43
|
return [...paths];
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
46
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/bash-writes.js
|
|
47
47
|
import { resolve as resolve2 } from "node:path";
|
|
48
48
|
function isRealPath(token) {
|
|
49
49
|
if (token === "" || token.startsWith("&"))
|
|
@@ -92,7 +92,7 @@ function writtenPaths(command, cwd) {
|
|
|
92
92
|
return [...found];
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
95
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/transcript.js
|
|
96
96
|
import { readFile } from "node:fs/promises";
|
|
97
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
98
|
async function searchedInTranscript(transcriptPath, tools = SEARCH_TOOLS) {
|
|
@@ -105,7 +105,7 @@ async function searchedInTranscript(transcriptPath, tools = SEARCH_TOOLS) {
|
|
|
105
105
|
return tools.some((tool) => raw.includes(`"name":"${tool}"`) || raw.includes(`"name": "${tool}"`));
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
108
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-guidance.js
|
|
109
109
|
var EAST_GUIDANCE = {
|
|
110
110
|
searchTool: "mcp__plugin_east_east__search_east_examples",
|
|
111
111
|
getTool: "mcp__plugin_east_east__get_east_example",
|
|
@@ -147,7 +147,7 @@ var GATE_TEXT = gateText(EAST_GUIDANCE);
|
|
|
147
147
|
var READ_TEXT = readText(EAST_GUIDANCE);
|
|
148
148
|
var isExampleCorpusRead = corpusReadFor(EAST_GUIDANCE.scope);
|
|
149
149
|
|
|
150
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
150
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/codex-hook.js
|
|
151
151
|
function codexToolCall(event) {
|
|
152
152
|
const cwd = event.cwd || process.cwd();
|
|
153
153
|
const input = event.tool_input ?? {};
|
|
@@ -199,7 +199,7 @@ async function codexSearchGate(event, options, call = codexToolCall(event)) {
|
|
|
199
199
|
return context.length > 0 ? { decision: "context", text: context.join("\n\n") } : null;
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
202
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/host.js
|
|
203
203
|
import { existsSync as existsSync2 } from "node:fs";
|
|
204
204
|
import { fileURLToPath } from "node:url";
|
|
205
205
|
var isCodex = existsSync2(fileURLToPath(new URL("../../.codex-plugin/plugin.json", import.meta.url)));
|
|
@@ -207,7 +207,7 @@ function hostText(text) {
|
|
|
207
207
|
return isCodex ? text.replaceAll("mcp__plugin_east_east__", "").replaceAll("/east:", "$east-codex-plugin:").replaceAll("Claude Code", "Codex") : text;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
210
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/hook-io.js
|
|
211
211
|
async function readHookInput() {
|
|
212
212
|
let input = "";
|
|
213
213
|
for await (const chunk of process.stdin) {
|
|
@@ -235,7 +235,7 @@ function writeHookDecision(hookEventName, decision, reason) {
|
|
|
235
235
|
process.stdout.write(JSON.stringify(output));
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
238
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-hooks.js
|
|
239
239
|
function writeSearchHookReply(hookEventName, reply) {
|
|
240
240
|
if (reply.decision === "deny")
|
|
241
241
|
writeHookDecision(hookEventName, "deny", reply.text);
|
package/.build/mcp/server.js
CHANGED
|
@@ -21556,7 +21556,7 @@ var StdioServerTransport = class {
|
|
|
21556
21556
|
}
|
|
21557
21557
|
};
|
|
21558
21558
|
|
|
21559
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
21559
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search.js
|
|
21560
21560
|
import { readFile } from "node:fs/promises";
|
|
21561
21561
|
|
|
21562
21562
|
// ../../node_modules/.pnpm/minisearch@7.2.0/node_modules/minisearch/dist/es/index.js
|
|
@@ -23369,7 +23369,7 @@ var objectToNumericMapAsync = async (object3) => {
|
|
|
23369
23369
|
var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
23370
23370
|
var SPACE_OR_PUNCTUATION = /[\n\r\p{Z}\p{P}]+/u;
|
|
23371
23371
|
|
|
23372
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
23372
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search-guidance.js
|
|
23373
23373
|
var EAST_GUIDANCE = {
|
|
23374
23374
|
searchTool: "mcp__plugin_east_east__search_east_examples",
|
|
23375
23375
|
getTool: "mcp__plugin_east_east__get_east_example",
|
|
@@ -23411,7 +23411,7 @@ var GATE_TEXT = gateText(EAST_GUIDANCE);
|
|
|
23411
23411
|
var READ_TEXT = readText(EAST_GUIDANCE);
|
|
23412
23412
|
var isExampleCorpusRead = corpusReadFor(EAST_GUIDANCE.scope);
|
|
23413
23413
|
|
|
23414
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
23414
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/search.js
|
|
23415
23415
|
var MIN_SCORE = 5;
|
|
23416
23416
|
async function loadIndexes(indexPaths) {
|
|
23417
23417
|
const entries = [];
|
|
@@ -23537,7 +23537,7 @@ function getEntry(index, id) {
|
|
|
23537
23537
|
return stored === void 0 ? null : stored;
|
|
23538
23538
|
}
|
|
23539
23539
|
|
|
23540
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
23540
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/mcp/example-tools.js
|
|
23541
23541
|
var EAST_PACKAGES = ["east", "east-node-std", "east-node-io", "east-py-datascience", "east-ui", "e3-ui", "e3", "e3-ui-cli", "e3-create"];
|
|
23542
23542
|
function isLoaded(index) {
|
|
23543
23543
|
return typeof index.then === "function";
|
|
@@ -23610,7 +23610,7 @@ function registerExampleTools(server2, options) {
|
|
|
23610
23610
|
import { fileURLToPath } from "node:url";
|
|
23611
23611
|
var E3_CLOUD_INDEX_PATH = fileURLToPath(new URL("../../index.json", import.meta.url));
|
|
23612
23612
|
|
|
23613
|
-
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.
|
|
23613
|
+
// ../../node_modules/.pnpm/@elaraai+east-plugin@1.0.102_typescript@5.9.3/node_modules/@elaraai/east-plugin/dist/lib/transcript.js
|
|
23614
23614
|
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"];
|
|
23615
23615
|
|
|
23616
23616
|
// ../e3-cloud-plugin/dist/lib/names.js
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "e3-cloud-codex-plugin",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
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,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 2,
|
|
3
3
|
"stats": {
|
|
4
|
-
"totalEntries":
|
|
4
|
+
"totalEntries": 47,
|
|
5
5
|
"totalFiles": 2,
|
|
6
6
|
"packages": {
|
|
7
7
|
"e3-cloud-ui": 12,
|
|
8
8
|
"e3-cloud-files": 14,
|
|
9
|
-
"e3-cloud-cli":
|
|
10
|
-
"e3-cloud-client":
|
|
9
|
+
"e3-cloud-cli": 15,
|
|
10
|
+
"e3-cloud-client": 6
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
"entries": [
|
|
@@ -758,7 +758,7 @@
|
|
|
758
758
|
"package": "e3-cloud-cli",
|
|
759
759
|
"file": "static",
|
|
760
760
|
"suite": "e3-cloud",
|
|
761
|
-
"test": "Signing in to a deployment, and who you are there: the e3 CLI's sign-in (`e3 auth login`; there is no `e3 login`), whose credentials the e3-cloud CLI shares",
|
|
761
|
+
"test": "Signing in to a deployment, and who you are there: the e3 CLI's sign-in (`e3 auth login`; there is no `e3 login`), whose credentials the e3-cloud CLI shares; whoami names the e3 cloud release and e3 the deployment runs beside this CLI's",
|
|
762
762
|
"keywords": [
|
|
763
763
|
"login",
|
|
764
764
|
"sign in",
|
|
@@ -771,7 +771,36 @@
|
|
|
771
771
|
"e3-cloud"
|
|
772
772
|
],
|
|
773
773
|
"imports": [],
|
|
774
|
-
"source": "npm install -g @elaraai/e3-cloud-cli @elaraai/e3-cli\ne3 auth login https://e3.example.com # the device flow; e3-cloud reads the same credentials\ne3-cloud whoami https://e3.example.com # your identity there,
|
|
774
|
+
"source": "npm install -g @elaraai/e3-cloud-cli @elaraai/e3-cli\ne3 auth login https://e3.example.com # the device flow; e3-cloud reads the same credentials\ne3-cloud whoami https://e3.example.com # your identity there, whether you are an admin, and the releases (e3-cloud --version, below)",
|
|
775
|
+
"languages": [
|
|
776
|
+
"typescript"
|
|
777
|
+
]
|
|
778
|
+
},
|
|
779
|
+
{
|
|
780
|
+
"id": "e3-cloud-cli:static:versions",
|
|
781
|
+
"skill": "e3-cloud-cli",
|
|
782
|
+
"package": "e3-cloud-cli",
|
|
783
|
+
"file": "static",
|
|
784
|
+
"suite": "e3-cloud --version / whoami",
|
|
785
|
+
"test": "Which releases a push or a deploy depends on: this CLI's e3 cloud release and the east and e3 it is built with (--version, --json), and the deployment's release and e3 (whoami), with a note where their e3s differ: a package exported with a newer e3 than the deployment's is refused",
|
|
786
|
+
"keywords": [
|
|
787
|
+
"version",
|
|
788
|
+
"--version",
|
|
789
|
+
"-V",
|
|
790
|
+
"--json",
|
|
791
|
+
"whoami",
|
|
792
|
+
"release",
|
|
793
|
+
"e3 version",
|
|
794
|
+
"east version",
|
|
795
|
+
"deployment",
|
|
796
|
+
"platform",
|
|
797
|
+
"lockstep",
|
|
798
|
+
"compatible",
|
|
799
|
+
"staged for",
|
|
800
|
+
"e3-cloud"
|
|
801
|
+
],
|
|
802
|
+
"imports": [],
|
|
803
|
+
"source": "e3-cloud --version # e3-cloud 1.1.1 (east 1.0.101, e3 1.0.101): this CLI, and the east and e3 it is built with\ne3-cloud --version --json # {\"e3Cloud\":\"1.1.1\",\"east\":\"1.0.101\",\"e3\":\"1.0.101\"}\ne3-cloud whoami https://e3.example.com\n# sub: … email: … admin: false\n# deployment: e3-cloud 1.1.1, e3 1.0.101\n# staged for: e3 1.0.102 (apps deployed with --for-platform) (only when a bundle is staged for a next e3)\n# cli: e3-cloud 1.1.1 (east 1.0.101, e3 1.0.101)\n# note: … only where the CLI's e3 and the deployment's differ: a package exported with a newer e3 than the deployment's is refused\n# A project builds with the e3 cloud release the deployment runs, beside the east and e3 it pins (npm view @elaraai/e3-cloud-files@1.1.1 peerDependencies)",
|
|
775
804
|
"languages": [
|
|
776
805
|
"typescript"
|
|
777
806
|
]
|
|
@@ -1090,6 +1119,7 @@
|
|
|
1090
1119
|
"beast2",
|
|
1091
1120
|
"typed",
|
|
1092
1121
|
"unchanged",
|
|
1122
|
+
"dataset",
|
|
1093
1123
|
"e3-cloud"
|
|
1094
1124
|
],
|
|
1095
1125
|
"imports": [],
|
|
@@ -1098,6 +1128,42 @@
|
|
|
1098
1128
|
"typescript"
|
|
1099
1129
|
]
|
|
1100
1130
|
},
|
|
1131
|
+
{
|
|
1132
|
+
"id": "e3-cloud-cli:static:files-push-dataset",
|
|
1133
|
+
"skill": "e3-cloud-cli",
|
|
1134
|
+
"package": "e3-cloud-cli",
|
|
1135
|
+
"file": "static",
|
|
1136
|
+
"suite": "e3-cloud files",
|
|
1137
|
+
"test": "Pushing a workspace's dataset (a task's output, an input or a record) into a source as the file of its value, with no file kept by hand: dataset:<workspace>.<name>, read from the repository --from names (a local path or a repository URL), matched by its name or --as, unchanged for the same stored value, refused in its row when unassigned or not found; a seed's history names the dataset",
|
|
1138
|
+
"keywords": [
|
|
1139
|
+
"files",
|
|
1140
|
+
"push",
|
|
1141
|
+
"dataset",
|
|
1142
|
+
"dataset:",
|
|
1143
|
+
"--from",
|
|
1144
|
+
"task output",
|
|
1145
|
+
"input",
|
|
1146
|
+
"record",
|
|
1147
|
+
"seed",
|
|
1148
|
+
"$seed",
|
|
1149
|
+
"--reset",
|
|
1150
|
+
"--as",
|
|
1151
|
+
"unchanged",
|
|
1152
|
+
"unassigned",
|
|
1153
|
+
"not_found",
|
|
1154
|
+
"local repository",
|
|
1155
|
+
"local workspace",
|
|
1156
|
+
"e3 dataset get",
|
|
1157
|
+
"beast2",
|
|
1158
|
+
"e3-dataset",
|
|
1159
|
+
"e3-cloud"
|
|
1160
|
+
],
|
|
1161
|
+
"imports": [],
|
|
1162
|
+
"source": "# A local workspace's task output seeding a deployed workspace's record: matched by its name (record:customers), put at its mapping's key\ne3-cloud files push https://e3.example.com/repos/acme dev dataset:dev.customers --from ./archive\n# dataset:dev.customers (task output) → record:customers seed 3 MiB put $init #1 12,004 rows\ne3-cloud files push https://e3.example.com/repos/acme dev dataset:dev.customers --from ./archive # the same stored value again: unchanged\ne3 dataflow run ./archive dev # its value changes\ne3-cloud files push https://e3.example.com/repos/acme dev dataset:dev.customers --from ./archive # $seed #2 while nothing has mutated the record; kept once something has\ne3-cloud files push https://e3.example.com/repos/acme dev dataset:dev.customers --from ./archive --reset customers # its state again, over its mutations\n# --from defaults as e3's [repo] does ($E3_REPO, then .); a repository URL reads a deployed workspace's dataset with your e3 login\ne3-cloud files push ./repo dev dataset:production.price_list --from https://e3.example.com/repos/acme --as prices # any file or latest mapping, by --as\n# Its bytes are the value's beast2, as `e3 dataset get -f beast2` writes it, read a segment at a time and checked against the mapping's type\n# before anything is put; under a latest prefix it is put as <name>.beast2; a folder or a listing takes no dataset. Refused in its row, the\n# rest going on: unassigned (a task output not produced since the last deploy, an input never set, a record with no state), not_found, ambiguous.\n# The object carries e3-dataset and e3-dataset-hash metadata; the history reads\n# \"Initialised from customers.beast2 (12,004 rows), from dev.customers at 3f9a2b1c4d5e\"",
|
|
1163
|
+
"languages": [
|
|
1164
|
+
"typescript"
|
|
1165
|
+
]
|
|
1166
|
+
},
|
|
1101
1167
|
{
|
|
1102
1168
|
"id": "e3-cloud-client:static:basics",
|
|
1103
1169
|
"skill": "e3-cloud-client",
|
|
@@ -1123,6 +1189,32 @@
|
|
|
1123
1189
|
"typescript"
|
|
1124
1190
|
]
|
|
1125
1191
|
},
|
|
1192
|
+
{
|
|
1193
|
+
"id": "e3-cloud-client:static:versions",
|
|
1194
|
+
"skill": "e3-cloud-client",
|
|
1195
|
+
"package": "e3-cloud-client",
|
|
1196
|
+
"file": "static",
|
|
1197
|
+
"suite": "@elaraai/e3-cloud-client platform",
|
|
1198
|
+
"test": "Which releases a deployment runs, from code: its e3 cloud release, the e3 its platform and runners run, and each next e3 an app's bundle is staged for; null from a deployment that predates it",
|
|
1199
|
+
"keywords": [
|
|
1200
|
+
"platformVersions",
|
|
1201
|
+
"PlatformVersions",
|
|
1202
|
+
"version",
|
|
1203
|
+
"release",
|
|
1204
|
+
"e3 version",
|
|
1205
|
+
"e3Cloud",
|
|
1206
|
+
"staged",
|
|
1207
|
+
"deployment",
|
|
1208
|
+
"/api/platform"
|
|
1209
|
+
],
|
|
1210
|
+
"imports": [
|
|
1211
|
+
"import { platformVersions } from '@elaraai/e3-cloud-client';"
|
|
1212
|
+
],
|
|
1213
|
+
"source": "const versions = await platformVersions(url, options); // anyone signed in may ask\nif (versions === null) console.log('the deployment predates it: it names no release');\nelse {\n console.log(versions.e3Cloud.type === 'some' ? versions.e3Cloud.value : 'release not stated', versions.e3, versions.staged.join(', '));\n // A package exported with a newer e3 than versions.e3 is refused: build with the e3 cloud release the deployment runs\n}",
|
|
1214
|
+
"languages": [
|
|
1215
|
+
"typescript"
|
|
1216
|
+
]
|
|
1217
|
+
},
|
|
1126
1218
|
{
|
|
1127
1219
|
"id": "e3-cloud-client:static:app-deploy",
|
|
1128
1220
|
"skill": "e3-cloud-client",
|
|
@@ -1216,7 +1308,7 @@
|
|
|
1216
1308
|
"file": "static",
|
|
1217
1309
|
"id": "e3-cloud-client:static:files",
|
|
1218
1310
|
"suite": "@elaraai/e3-cloud-client files",
|
|
1219
|
-
"test": "Files from code: deploy a workspace's declarations, bind a source, sync named targets (a seeded record reset) and wait for the sync's report, read what each mapping holds, and plan a
|
|
1311
|
+
"test": "Files from code: deploy a workspace's declarations, bind a source, sync named targets (a seeded record reset) and wait for the sync's report, read what each mapping holds, and push a file from disk (plan, upload through the platform, sync), or a workspace's dataset as the file of its value",
|
|
1220
1312
|
"keywords": [
|
|
1221
1313
|
"getFiles",
|
|
1222
1314
|
"deployFiles",
|
|
@@ -1225,6 +1317,8 @@
|
|
|
1225
1317
|
"filesSyncWait",
|
|
1226
1318
|
"planFilesPush",
|
|
1227
1319
|
"completeFilesPush",
|
|
1320
|
+
"FilesPushBytes",
|
|
1321
|
+
"uploadFilesPush",
|
|
1228
1322
|
"FilesTarget",
|
|
1229
1323
|
"targets",
|
|
1230
1324
|
"reset",
|
|
@@ -1233,18 +1327,21 @@
|
|
|
1233
1327
|
"record",
|
|
1234
1328
|
"mutation",
|
|
1235
1329
|
"push",
|
|
1330
|
+
"dataset",
|
|
1236
1331
|
"unchanged",
|
|
1237
1332
|
"refused",
|
|
1238
1333
|
"retaken",
|
|
1239
1334
|
"workspace_protected"
|
|
1240
1335
|
],
|
|
1241
1336
|
"imports": [
|
|
1337
|
+
"import { createReadStream } from 'node:fs';",
|
|
1338
|
+
"import { stat } from 'node:fs/promises';",
|
|
1242
1339
|
"import { none, some, variant } from '@elaraai/east';",
|
|
1243
|
-
"import { bindFilesSource,
|
|
1340
|
+
"import { bindFilesSource, deployFiles, filesSyncWait, getFiles, planFilesPush, startFilesSync, uploadFilesPush, type FilesPushBytes } from '@elaraai/e3-cloud-client';",
|
|
1244
1341
|
"import { filesPushRefusalText, filesTargetText } from '@elaraai/e3-cloud-types';",
|
|
1245
1342
|
"import manifest from './files.js'; // export default Files.manifest([upload])"
|
|
1246
1343
|
],
|
|
1247
|
-
"source": "// The declarations (checked against the package the workspace runs), then where the source's files are\nconst deployed = await deployFiles(url, 'acme', 'staging', manifest, options);\nif (deployed.type === 'refused') throw new Error(deployed.value.problems.map((p) => p.type).join(', '));\nawait bindFilesSource(url, 'acme', 'staging', { source: 'upload', url: 's3://partner-drop/acme/', region: none, profile: none, latest: none }, options);\n\n// A sync of two targets: the seeded record's file taken as its state again (reset), and the fed mutation's new files\nconst start = await startFilesSync(url, 'acme', 'staging', {\n targets: [variant('record', 'customers'), variant('mutation', { record: 'price_book', mutation: 'load_prices' })],\n reset: ['customers'],\n}, options);\nconst id = start.value; // started, or running: the sync under way, waited on the same way\nconst job = await filesSyncWait(url, 'acme', 'staging', id, options, { deadlineMs: 10 * 60_000 });\nfor (const m of job.report.type === 'some' ? job.report.value.mappings : []) {\n console.log(filesTargetText(m.target), m.updated ? `written (commit ${m.commit.type === 'some' ? m.commit.value.slice(0, 12) : 'none'})` : 'as it was', m.refused.length === 0 ? '' : `refused ${m.refused[0]!.key}`);\n}\n\n// What each mapping holds now; a record not yet seeded is pending\nconst files = await getFiles(url, 'acme', 'staging', options);\nconsole.log(files.status.mappings.map((m) => `${filesTargetText(m.target)}: ${m.pending ? 'pending' : m.holds.type === 'some' ? m.holds.value.key : 'nothing yet'}`).join(' · '));\n\n// A push from disk: the plan says per file where it goes and how to upload it (a
|
|
1344
|
+
"source": "// The declarations (checked against the package the workspace runs), then where the source's files are\nconst deployed = await deployFiles(url, 'acme', 'staging', manifest, options);\nif (deployed.type === 'refused') throw new Error(deployed.value.problems.map((p) => p.type).join(', '));\nawait bindFilesSource(url, 'acme', 'staging', { source: 'upload', url: 's3://partner-drop/acme/', region: none, profile: none, latest: none }, options);\n\n// A sync of two targets: the seeded record's file taken as its state again (reset), and the fed mutation's new files\nconst start = await startFilesSync(url, 'acme', 'staging', {\n targets: [variant('record', 'customers'), variant('mutation', { record: 'price_book', mutation: 'load_prices' })],\n reset: ['customers'],\n}, options);\nconst id = start.value; // started, or running: the sync under way, waited on the same way\nconst job = await filesSyncWait(url, 'acme', 'staging', id, options, { deadlineMs: 10 * 60_000 });\nfor (const m of job.report.type === 'some' ? job.report.value.mappings : []) {\n console.log(filesTargetText(m.target), m.updated ? `written (commit ${m.commit.type === 'some' ? m.commit.value.slice(0, 12) : 'none'})` : 'as it was', m.refused.length === 0 ? '' : `refused ${m.refused[0]!.key}`);\n}\n\n// What each mapping holds now; a record not yet seeded is pending\nconst files = await getFiles(url, 'acme', 'staging', options);\nconsole.log(files.status.mappings.map((m) => `${filesTargetText(m.target)}: ${m.pending ? 'pending' : m.holds.type === 'some' ? m.holds.value.key : 'nothing yet'}`).join(' · '));\n\n// A push from disk: the plan says per file where it goes and how to upload it; uploadFilesPush puts it through the platform\n// (one PUT bound to its SHA-256, or a multipart upload it completes), then one sync of the targets put\nconst path = 'data/customers.beast2';\nconst size = (await stat(path)).size;\nconst plan = await planFilesPush(url, 'acme', 'staging', {\n files: [{ name: 'customers.beast2', directory: none, size: BigInt(size), sha256, type: some(customerBookType), dataset: none }], // sha256: hex; type: its beast2 header's\n as: none,\n}, options);\nconst bytes: FilesPushBytes = { size, ranged: true, read: (start) => createReadStream(path, { start }) }; // a file reads from any offset\nfor (const f of plan.files) {\n if (f.outcome.type === 'refused') console.warn(f.name, filesPushRefusalText(f.outcome.value));\n else if (f.outcome.type === 'put') await uploadFilesPush(url, 'acme', 'staging', plan, f.outcome.value, bytes, options); // an `external` put throws: your own credentials\n}\nawait startFilesSync(url, 'acme', 'staging', { targets: plan.files.flatMap((f) => (f.outcome.type === 'put' ? [f.outcome.value.target] : [])) }, options);\n// A workspace's dataset is offered as the file of its value: dataset: some({ workspace: 'dev', name: 'customers', hash }), its type the value's,\n// its bytes the value's beast2 as `e3 dataset get -f beast2` writes it, streamed (ranged: false: never held whole) and matched by its name.\n// `e3-cloud files push … dataset:dev.customers --from <repo>` does all of it",
|
|
1248
1345
|
"languages": [
|
|
1249
1346
|
"typescript"
|
|
1250
1347
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elaraai/e3-cloud-codex-plugin",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
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,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: e3-cloud-cli
|
|
3
|
-
description: "The e3-cloud CLI — run an e3 cloud deployment from the shell. Use when: (1) Signing in (`e3 auth login` to a server, whose credentials e3-cloud shares)
|
|
3
|
+
description: "The e3-cloud CLI — run an e3 cloud deployment from the shell. Use when: (1) Signing in (`e3 auth login` to a server, whose credentials e3-cloud shares), checking who you are and which e3 cloud release and e3 the deployment runs (`e3-cloud whoami SERVER`), and which this CLI is built with (`e3-cloud --version`, `--json`), (2) Building and deploying apps — `e3-cloud app build`, `app deploy` (UI-only, or with its package, `--dry-run`, several together, `--from-source`), `app list`, `app versions`, `app remove` (an app is developed in the cloud: deployed to a workspace of one's own and opened there), (3) Staging an app for the platform's next e3 (`app deploy --for-platform VERSION`, `app list-all`), (4) Staging and releases — `e3-cloud staging add|stop|list` (a staging protects the workspace it releases to: it then changes only by a release from it, or a rollback; `--force` on `app deploy` and `app remove` is an admin's… See the detailed scope below."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
## Detailed skill scope
|
|
7
7
|
|
|
8
|
-
The e3-cloud CLI — run an e3 cloud deployment from the shell. Use when: (1) Signing in (`e3 auth login` to a server, whose credentials e3-cloud shares)
|
|
8
|
+
The e3-cloud CLI — run an e3 cloud deployment from the shell. Use when: (1) Signing in (`e3 auth login` to a server, whose credentials e3-cloud shares), checking who you are and which e3 cloud release and e3 the deployment runs (`e3-cloud whoami SERVER`), and which this CLI is built with (`e3-cloud --version`, `--json`), (2) Building and deploying apps — `e3-cloud app build`, `app deploy` (UI-only, or with its package, `--dry-run`, several together, `--from-source`), `app list`, `app versions`, `app remove` (an app is developed in the cloud: deployed to a workspace of one's own and opened there), (3) Staging an app for the platform's next e3 (`app deploy --for-platform VERSION`, `app list-all`), (4) Staging and releases — `e3-cloud staging add|stop|list` (a staging protects the workspace it releases to: it then changes only by a release from it, or a rollback; `--force` on `app deploy` and `app remove` is an admin's override), `e3 workspace copy` for the rehearsal, `e3-cloud release URL FROM TO` with `--plan`, `--carry` and `--remove-apps` (a release carries the package, the apps and the Files declarations; the target keeps its data and bindings), `e3-cloud history`, `e3-cloud rollback`, (5) A repository's people and business roles — `e3-cloud user list|add|remove` (`--role owner`, or a user with `--roles 'Rostering,Finance'`), `e3-cloud role list|show|set|rm` (`--grant WORKSPACE/APP[:page,page]`), and for admins `user list-all|disable|enable|invitations|uninvite`, (6) Secrets (`e3-cloud secrets set|list|rm`), schedules (`schedule set|get|list|remove`), each task's compute size and timeout (`compute`, `timeout`), people's workspace settings (`settings`), (7) Records' history, rollback and backups (`e3-cloud records …`) and feedback (`e3-cloud feedback …`), (8) Files — a solution's inputs from files in a bucket: `e3-cloud files deploy|bind|sync|push|status`, given a local repository's path or a repository URL, and `files push` of files from disk or of a workspace's dataset as the file of its value (`dataset:WORKSPACE.NAME`, `--from` a local repository or a URL) (the e3-cloud-files skill declares and decodes them), (9) Walking a solution through its life, step by step — starting it, adding a staging, developing an app's pages, changing the package's tasks and inputs, migrating a record, Files, rehearsing and releasing, rolling back, an emergency change to production, people and roles, schedules, secrets and compute, feedback, the platform's next e3, and retiring an app or a workspace.
|
|
9
9
|
|
|
10
10
|
# e3-cloud — the e3 cloud CLI (@elaraai/e3-cloud-cli)
|
|
11
11
|
|
|
@@ -42,7 +42,7 @@ Nothing is injected for you; the search is the step.
|
|
|
42
42
|
```bash
|
|
43
43
|
npm install -g @elaraai/e3-cloud-cli @elaraai/e3-cli
|
|
44
44
|
e3 auth login https://e3.example.com
|
|
45
|
-
e3-cloud whoami https://e3.example.com
|
|
45
|
+
e3-cloud whoami https://e3.example.com # you, the release and e3 the deployment runs, and this CLI's
|
|
46
46
|
|
|
47
47
|
# An app: build its bundle, check it, deploy it
|
|
48
48
|
e3-cloud app build src/apps/ops.tsx
|
|
@@ -194,6 +194,7 @@ e3-cloud files deploy URL staging src/files.ts
|
|
|
194
194
|
e3-cloud files bind URL staging upload s3://bucket/acme/staging/
|
|
195
195
|
e3-cloud files sync URL staging
|
|
196
196
|
e3-cloud files push URL staging ./data/prices.beast2 ./data/customers.beast2 # from disk: matched by name (or --as), put, synced
|
|
197
|
+
e3-cloud files push URL staging dataset:dev.customers --from ./repo # a local workspace's dataset, as the file of its value
|
|
197
198
|
e3-cloud files sync URL staging --target record:customers --reset customers # named targets; a seeded record's file as its state again
|
|
198
199
|
e3 dataflow run URL staging
|
|
199
200
|
```
|
|
@@ -418,6 +419,16 @@ a repository URL:
|
|
|
418
419
|
- `files sync <repo> <ws>` reads only files whose ETag or size changed and
|
|
419
420
|
writes only inputs whose files changed; `--target`, `--reset`, `--dry-run`. It doesn't
|
|
420
421
|
run the dataflow: `e3 dataflow run` does, and the sync prints the command.
|
|
422
|
+
- `files push <repo> <ws> <path…>` puts files from disk, or datasets
|
|
423
|
+
(`dataset:<ws>.<name>`: a task's output, an input or a record, read from
|
|
424
|
+
the repository `--from` names, a local path or a URL, default `$E3_REPO`
|
|
425
|
+
then `.`), into the source each one's mapping reads, then syncs what was
|
|
426
|
+
put: matched by name or `--as`, checked against the mapping's type before
|
|
427
|
+
anything is put, `unchanged` when the source holds it already, refused in
|
|
428
|
+
its row otherwise (`unassigned`, `not_found`, `no_mapping`, `type_mismatch`,
|
|
429
|
+
…); `--reset`, `--dry-run`, `--profile` (a bucket the platform doesn't
|
|
430
|
+
write). A seed's or feed's history names the file, and the dataset it was
|
|
431
|
+
pushed from.
|
|
421
432
|
- `files status <repo> <ws>`: the declarations, the bindings, the last sync.
|
|
422
433
|
|
|
423
434
|
## Traps
|
|
@@ -436,4 +447,9 @@ a repository URL:
|
|
|
436
447
|
next run reads the new value.
|
|
437
448
|
- The version is e3 cloud's own, not e3's: use the CLI of the e3 cloud
|
|
438
449
|
release your deployment runs, beside e3's CLI of the e3 that release is
|
|
439
|
-
built with (its dependencies pin it).
|
|
450
|
+
built with (its dependencies pin it). `e3-cloud --version` prints
|
|
451
|
+
`e3-cloud 1.1.1 (east 1.0.101, e3 1.0.101)` (`--json`:
|
|
452
|
+
`{"e3Cloud":…,"east":…,"e3":…}`); `e3-cloud whoami <server>` prints the
|
|
453
|
+
deployment's `deployment: e3-cloud 1.1.1, e3 1.0.101` beside it, and a
|
|
454
|
+
`note:` where the e3s differ: a package exported with a newer e3 than the
|
|
455
|
+
deployment's is refused.
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: e3-cloud-client
|
|
3
|
-
description: "@elaraai/e3-cloud-client — drive an e3 cloud deployment from TypeScript. Use when: (1) Calling a deployment from code with a token (`whoami`, `RequestOptions`, `ApiError`), (2) Managing a repository's people and business roles (`repoUsers`, `addUser`, `removeUser`, `repoInvitations`, `listRoles`, `putRole`, `myAccess`), (3) Deploying apps from code — `appUpload`, `appDeploy` / `appsDeploy` and `appDeployWait`, `appList`, `appGet`, `appVersions`, `appRemove` — and reading a refusal (`appProblemsText`), (4) Staging, releasing and rolling back — `addStaging` / `stopStaging` (a staging protects the workspace it releases to), `releaseWorkspace`, `rollbackWorkspace` (a plan first, `releasePlanRefusalLines`), `workspaceHistory`, `getRepositoryReleaseSettings`, (5) Secrets, schedules and task configs (`putSecret`, `listSecrets`, `setSchedule`, `setCompute`, `setTimeout`), (6) Records' history and backups (`recordAudit
|
|
3
|
+
description: "@elaraai/e3-cloud-client — drive an e3 cloud deployment from TypeScript. Use when: (1) Calling a deployment from code with a token (`whoami`, `RequestOptions`, `ApiError`), (2) Managing a repository's people and business roles (`repoUsers`, `addUser`, `removeUser`, `repoInvitations`, `listRoles`, `putRole`, `myAccess`), (3) Deploying apps from code — `appUpload`, `appDeploy` / `appsDeploy` and `appDeployWait`, `appList`, `appGet`, `appVersions`, `appRemove` — and reading a refusal (`appProblemsText`), (4) Staging, releasing and rolling back — `addStaging` / `stopStaging` (a staging protects the workspace it releases to), `releaseWorkspace`, `rollbackWorkspace` (a plan first, `releasePlanRefusalLines`), `workspaceHistory`, `getRepositoryReleaseSettings`, (5) Secrets, schedules and task configs (`putSecret`, `listSecrets`, `setSchedule`, `setCompute`, `setTimeout`), (6) Records' history and backups (`recordAudit`,… See the detailed scope below."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
## Detailed skill scope
|
|
7
|
+
|
|
8
|
+
@elaraai/e3-cloud-client — drive an e3 cloud deployment from TypeScript. Use when: (1) Calling a deployment from code with a token (`whoami`, `RequestOptions`, `ApiError`), (2) Managing a repository's people and business roles (`repoUsers`, `addUser`, `removeUser`, `repoInvitations`, `listRoles`, `putRole`, `myAccess`), (3) Deploying apps from code — `appUpload`, `appDeploy` / `appsDeploy` and `appDeployWait`, `appList`, `appGet`, `appVersions`, `appRemove` — and reading a refusal (`appProblemsText`), (4) Staging, releasing and rolling back — `addStaging` / `stopStaging` (a staging protects the workspace it releases to), `releaseWorkspace`, `rollbackWorkspace` (a plan first, `releasePlanRefusalLines`), `workspaceHistory`, `getRepositoryReleaseSettings`, (5) Secrets, schedules and task configs (`putSecret`, `listSecrets`, `setSchedule`, `setCompute`, `setTimeout`), (6) Records' history and backups (`recordAudit`, `createRecordBackup`, `restoreRecordBackup`) and feedback (`listFeedback`, `closeFeedback`), (7) Files from code — `getFiles`, `deployFiles`, `bindFilesSource`, `startFilesSync` and `filesSyncWait`, and a push: `planFilesPush`, `uploadFilesPush` (a file from disk by ranges, or a workspace's dataset as its value streams, with its type and where it came from), `completeFilesPush`, (8) Which releases a deployment runs (`platformVersions`: its e3 cloud release, its e3, the next e3s bundles are staged for).
|
|
9
|
+
|
|
6
10
|
# @elaraai/e3-cloud-client
|
|
7
11
|
|
|
8
12
|
The e3 cloud API's client: every call takes the deployment's origin
|
|
@@ -92,13 +96,33 @@ try {
|
|
|
92
96
|
or `variant('mutation', { record, mutation })`; `reset` names seeded
|
|
93
97
|
records whose file is taken as their state again.
|
|
94
98
|
- `planFilesPush(url, repo, ws, { files, as }, options)` plans a push of
|
|
95
|
-
files
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
`
|
|
99
|
-
`external` (your own credentials) —
|
|
100
|
-
(`filesPushRefusalText`).
|
|
101
|
-
`
|
|
99
|
+
files (each offered with its name, size, SHA-256 and beast2 header type,
|
|
100
|
+
and `dataset: some({ workspace, name, hash })` for a workspace's dataset
|
|
101
|
+
offered as the file of its value): per file `put` with its key and how to
|
|
102
|
+
upload it — `single` (one PUT with the plan's headers), `multipart` (a URL
|
|
103
|
+
per part, then a completion) or `external` (your own credentials) —
|
|
104
|
+
`unchanged`, or `refused` with why (`filesPushRefusalText`). A dataset is
|
|
105
|
+
matched by its name, to the `file` or `latest` mapping filling the input
|
|
106
|
+
or record of that name.
|
|
107
|
+
- `uploadFilesPush(url, repo, ws, plan, put, bytes, options, refresh?)`
|
|
108
|
+
uploads one put through the platform, `bytes` a `FilesPushBytes`
|
|
109
|
+
(`{ size, read(start), ranged }`): a file on disk is `ranged` (its parts
|
|
110
|
+
sent four at a time, each read from its start), a dataset's value streams
|
|
111
|
+
from its repository (`ranged: false`, parts one after another, never held
|
|
112
|
+
whole). A multipart upload is completed under the object's key in its
|
|
113
|
+
bucket (`completeFilesPush`); a source that throws as its bytes end (a
|
|
114
|
+
dataset rewritten while it was read) has its last bytes held back, so
|
|
115
|
+
nothing other than the planned bytes is ever stored. Then sync the targets
|
|
116
|
+
put. The CLI's `files push` does all of this.
|
|
117
|
+
|
|
118
|
+
## Versions
|
|
119
|
+
|
|
120
|
+
- `platformVersions(url, options)` answers what a deployment runs:
|
|
121
|
+
`{ e3Cloud: some('1.1.1'), e3: '1.0.101', staged: [...] }` (the next e3s
|
|
122
|
+
an app's bundle is staged for, in the repositories the caller manages), or
|
|
123
|
+
`null` from a deployment that predates it. A package exported with a newer
|
|
124
|
+
e3 than the deployment's is refused: compare it with the e3 your project
|
|
125
|
+
builds with before a deploy.
|
|
102
126
|
|
|
103
127
|
## Traps
|
|
104
128
|
|
|
@@ -5,7 +5,7 @@ description: "Files for e3 cloud — a solution's inputs that come from files in
|
|
|
5
5
|
|
|
6
6
|
## Detailed skill scope
|
|
7
7
|
|
|
8
|
-
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), def one its record declares (priceBook.mutations.load_prices), 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) Seeding a record from a file with source.record(name, type, spec, parts): e3.record with no initial value, declared whole with its indexes, mutations and migrations, pending until its file, its tasks waiting meanwhile, (12) Syncing or resetting particular targets with --target and --reset.
|
|
8
|
+
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), def one its record declares (priceBook.mutations.load_prices), 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, or a workspace's dataset (a task's output, an input, a record) as the file of its value with dataset:workspace.name and --from, local or remote at either end, (11) Seeding a record from a file with source.record(name, type, spec, parts): e3.record with no initial value, declared whole with its indexes, mutations and migrations, pending until its file, its tasks waiting meanwhile, (12) Syncing or resetting particular targets with --target and --reset.
|
|
9
9
|
|
|
10
10
|
# e3-cloud-files — files as e3 inputs
|
|
11
11
|
|
|
@@ -15,8 +15,9 @@ are, a bucket and a prefix, and `e3-cloud files sync` brings in what changed:
|
|
|
15
15
|
on a local repository with your own cloud credentials, in the cloud with the
|
|
16
16
|
platform's read-only role. A file arrives as it is, a `Blob`, and a task
|
|
17
17
|
decodes it; or, named with a type, a beast2 file arrives as the value it
|
|
18
|
-
holds, with no task in between. `e3-cloud files push` puts files from disk
|
|
19
|
-
|
|
18
|
+
holds, with no task in between. `e3-cloud files push` puts files from disk,
|
|
19
|
+
or a workspace's datasets as the files of their values, into a source and
|
|
20
|
+
takes them in. Nothing polls: a sync runs when someone asks.
|
|
20
21
|
|
|
21
22
|
Read `README.md` for the author's guide; this file is the short form.
|
|
22
23
|
|
|
@@ -93,6 +94,7 @@ What do you need?
|
|
|
93
94
|
│ │ └─ Locally only → --profile <aws profile>, --latest <n> (each folder's n greatest keys)
|
|
94
95
|
│ ├─ Bring in what changed → e3-cloud files sync <repo> <ws> [--target t…] [--reset record…] [--dry-run]
|
|
95
96
|
│ ├─ Put files from disk → e3-cloud files push <repo> <ws> <file|dir>… [--as target] [--dry-run] [--profile p]
|
|
97
|
+
│ ├─ Push a workspace's dataset → e3-cloud files push <repo> <ws> dataset:<ws>.<name>… [--from <repo>] (a task's output, an input, a record)
|
|
96
98
|
│ ├─ What is declared, bound, held → e3-cloud files status <repo> <ws> (each mapping, its type, what it holds, pending)
|
|
97
99
|
│ └─ Run the dataflow on it → e3 dataflow run <repo> <ws> (a sync doesn't run it)
|
|
98
100
|
├─ Production: a workspace with a staging (a deployed repository's URL)
|
|
@@ -179,7 +181,7 @@ file's path under the prefix, in path order.
|
|
|
179
181
|
e3-cloud files deploy <repo> <workspace> src/files.ts [--dry-run]
|
|
180
182
|
e3-cloud files bind <repo> <workspace> upload s3://bucket/prefix/ [--region r] [--profile p] [--latest n]
|
|
181
183
|
e3-cloud files sync <repo> <workspace> [--target name|record:r|mutation:r.m ...] [--reset record...] [--dry-run]
|
|
182
|
-
e3-cloud files push <repo> <workspace> <file|dir>... [--as target] [--reset record...] [--dry-run] [--profile p]
|
|
184
|
+
e3-cloud files push <repo> <workspace> <file|dir|dataset:ws.name>... [--from repo] [--as target] [--reset record...] [--dry-run] [--profile p]
|
|
183
185
|
e3-cloud files status <repo> <workspace>
|
|
184
186
|
e3 dataflow run <repo> <workspace>
|
|
185
187
|
```
|
|
@@ -192,7 +194,31 @@ file's SHA-256; your own credentials elsewhere), then syncs what was put. A
|
|
|
192
194
|
file the source holds already is `unchanged`; refused: `no_mapping`,
|
|
193
195
|
`ambiguous` (name the target with `--as`), `not_included` (the mapping's
|
|
194
196
|
glob leaves it out), `not_latest` (a greater key would shadow it), a typed
|
|
195
|
-
mapping's file of another type or no beast2, one over the limit.
|
|
197
|
+
mapping's file of another type or no beast2, one over the limit. The report
|
|
198
|
+
numbers a record's seeds: `$init #1`, `$seed #2`, …
|
|
199
|
+
|
|
200
|
+
`dataset:<workspace>.<name>` pushes a value a workspace holds (a task's
|
|
201
|
+
output, an input or a record, by its name) as the file of its value would,
|
|
202
|
+
with no file kept by hand: its bytes are the value's beast2 (as
|
|
203
|
+
`e3 dataset get -f beast2` writes it), read a segment at a time from the
|
|
204
|
+
repository `--from` names (a local path or a repository URL; default
|
|
205
|
+
`$E3_REPO`, then `.`, as e3's `[repo]`). It goes to the `file` or `latest`
|
|
206
|
+
mapping filling the input or record of its name, else `--as` names one; it
|
|
207
|
+
is put at the `file`'s key, or under the `latest`'s prefix as
|
|
208
|
+
`<name>.beast2`; a `folder` or `listing` takes none. The same stored value
|
|
209
|
+
is `unchanged`; refused in their rows: `unassigned` (a task output not
|
|
210
|
+
produced since the workspace's last deploy, an input never set, a record
|
|
211
|
+
with no state), `not_found`, `ambiguous` (two of the workspace's datasets
|
|
212
|
+
have the name); a dataset a run rewrites while it uploads fails in its row
|
|
213
|
+
(push again). The object carries `e3-dataset` and `e3-dataset-hash`
|
|
214
|
+
metadata, and a seed's or feed's history names the dataset: "Initialised
|
|
215
|
+
from customers.beast2 (12,004 rows), from dev.customers at 3f9a2b1c4d5e".
|
|
216
|
+
Files, directories and datasets mix in one push.
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# A local workspace's task output, seeding a deployed workspace's record
|
|
220
|
+
e3-cloud files push https://e3.example.com/repos/acme dev dataset:dev.customers --from ./archive
|
|
221
|
+
```
|
|
196
222
|
|
|
197
223
|
`--target` names an input, `record:<name>` or `mutation:<record>.<name>`
|
|
198
224
|
(split at its last dot); `--reset <record>` takes a seeded record's file as
|
|
@@ -227,6 +253,11 @@ keeps only each folder's n greatest keys.
|
|
|
227
253
|
its file. A deploy that cannot keep it (its type changed) under
|
|
228
254
|
`--schema reset` unassigns it: pending again, seeded by the next version's
|
|
229
255
|
file.
|
|
256
|
+
- A dataset pushed to a seeded record seeds it like a file: again while
|
|
257
|
+
unmutated (`$seed #n`), `kept` once mutated, over its mutations with
|
|
258
|
+
`--reset`. A dataset whose value is unchanged since the last push is
|
|
259
|
+
`unchanged`, nothing put; one never produced since the workspace's last
|
|
260
|
+
deploy is `unassigned`: run the dataflow first.
|
|
230
261
|
- A record is declared whole: a fed mutation is one its record declares
|
|
231
262
|
(`priceBook.mutations.load_prices`), and a seeded record's indexes,
|
|
232
263
|
mutations and migrations are `upload.record`'s `parts`; an initial value
|