@elaraai/e3-cloud-claude-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.
package/package.json CHANGED
@@ -1,6 +1,32 @@
1
1
  {
2
2
  "name": "@elaraai/e3-cloud-claude-plugin",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.90-alpha.0",
4
+ "description": "e3 cloud - apps for hosted e3 workspaces with @elaraai/e3-cloud-ui, the e3-cloud CLI and @elaraai/e3-cloud-client: skills, example search and the search-first hooks",
5
+ "license": "AGPL-3.0-or-later",
6
+ "type": "module",
7
+ "author": {
8
+ "name": "Elara AI",
9
+ "email": "support@elara.ai",
10
+ "url": "https://elaraai.com"
11
+ },
12
+ "homepage": "https://github.com/elaraai/plugins",
13
+ "keywords": [
14
+ "e3",
15
+ "e3-cloud",
16
+ "east",
17
+ "elara",
18
+ "apps",
19
+ "typescript"
20
+ ],
21
+ "engines": {
22
+ "node": ">=22.0.0"
23
+ },
24
+ "files": [
25
+ ".claude-plugin",
26
+ ".build",
27
+ "hooks",
28
+ "skills",
29
+ ".mcp.json",
30
+ "index.json"
31
+ ]
32
+ }
@@ -0,0 +1,125 @@
1
+ ---
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) and checking who you are (`e3-cloud whoami`), (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`, `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 …`)."
4
+ ---
5
+
6
+ # e3-cloud — the e3 cloud CLI (@elaraai/e3-cloud-cli)
7
+
8
+ `e3-cloud` runs the parts of an e3 cloud deployment that e3's own CLI does not:
9
+ apps, releases, users and roles, secrets, schedules, task configs, records'
10
+ history and backups, and feedback. e3's CLI (`e3`, `@elaraai/e3-cli`) still
11
+ does what it does against any server: repositories, packages, workspaces,
12
+ datasets, dataflow runs and copies. Both sign in with `e3 auth login` and share its
13
+ credentials (`~/.e3/credentials.json`).
14
+
15
+ A command names what it acts on by URL: a server (`https://e3.example.com`),
16
+ a repository (`…/repos/acme`), or a workspace (`…/repos/acme/workspaces/production`),
17
+ as its help says.
18
+
19
+ ## Before writing code — search the example index
20
+
21
+ Every command has an entry in the plugin's index, with the client calls and
22
+ the app library's. Before scripting a deployment or answering how a command
23
+ works:
24
+
25
+ 1. Call `mcp__plugin_e3-cloud_e3-cloud__search_e3_cloud_examples` with what
26
+ you are about to do (`release staging to production`, `give a user a role`).
27
+ Summaries come back first.
28
+ 2. Fetch the one or two that match with
29
+ `mcp__plugin_e3-cloud_e3-cloud__get_e3_cloud_example`.
30
+ 3. Do not read `node_modules/@elaraai/**` instead: the index holds the same
31
+ commands, exact and far cheaper, and `e3-cloud <command> --help` the rest.
32
+
33
+ Nothing is injected for you; the search is the step.
34
+
35
+ ## Quick Start
36
+
37
+ ```bash
38
+ npm install -g @elaraai/e3-cloud-cli @elaraai/e3-cli
39
+ e3 auth login https://e3.example.com
40
+ e3-cloud whoami https://e3.example.com
41
+
42
+ # An app: build its bundle, check it, deploy it
43
+ e3-cloud app build src/apps/ops.tsx
44
+ e3-cloud app deploy https://e3.example.com/repos/acme staging dist/ops.app --dry-run
45
+ e3-cloud app deploy https://e3.example.com/repos/acme staging dist/ops.app
46
+
47
+ # Staging: a copy of production where changes are tried; production is protected from then on
48
+ e3-cloud staging add https://e3.example.com/repos/acme production staging
49
+
50
+ # A release: the plan first, then exactly what staging runs, production's data kept
51
+ e3-cloud release https://e3.example.com/repos/acme staging production --plan
52
+ e3-cloud release https://e3.example.com/repos/acme staging production
53
+ ```
54
+
55
+ ## Apps
56
+
57
+ - `app build <source>` writes the bundle (`dist/<app>.app`): the app and the
58
+ package it was built against. A refusal names each problem.
59
+ - `app deploy <repo-url> <workspace> [bundles…]` imports the bundle's package
60
+ when the repository lacks it, checks every app against it, and deploys: at
61
+ once when the workspace runs that package (UI only); else the package deploys
62
+ first, keeping the inputs people set, and the apps go live as it completes
63
+ (the CLI waits). `--dry-run` checks and changes nothing; `--from-source`
64
+ builds sources instead of bundles; several apps deploy together or not at all.
65
+ - An app is developed in the cloud, not locally: deploy it to a workspace
66
+ of your own (`--from-source` after each change, `--dry-run` to check
67
+ only) and open it in the console. Develop against a staging, never the
68
+ protected workspace it releases to.
69
+ - `app deploy` and `app remove` to a protected workspace are refused, naming
70
+ its staging; an admin alone forces one with `--force`, which warns first and
71
+ which the workspace's history records as forced.
72
+ - `app deploy … --for-platform <version>` stages a bundle built with the
73
+ platform's next e3; `app list-all` (admins) lists every app and which needs
74
+ one.
75
+
76
+ ## Staging
77
+
78
+ A workspace's staging is where changes are tried before they reach the
79
+ workspace people use, which it then **protects**, as a protected branch is
80
+ protected: its package and apps change only by a release from its staging, or
81
+ a rollback. One staging to a workspace; no staging has one of its own.
82
+
83
+ - `staging add <repo-url> <live> <name>` prints what it would do, then adds it:
84
+ a copy of the live workspace as it is now, data included. `--plan` stops at
85
+ the plan; a workspace of the name is used `--as-is`, or replaced whole only
86
+ with `--replace`.
87
+ - `staging list <repo-url>` names each staging and what it protects;
88
+ `staging stop <repo-url> <live>` (admins alone) unprotects it, deleting
89
+ nothing.
90
+ - A protected workspace refuses e3's `workspace deploy`, an app deploy or
91
+ removal, a copy onto it, and its removal or its staging's. Its data goes on:
92
+ inputs, records, runs and schedules.
93
+
94
+ ## Releases
95
+
96
+ A release gives the target exactly the package and app versions the source
97
+ runs, by hash, with the bundles it has staged for the next e3. Only the
98
+ target's staging releases to it. The target keeps the inputs people set in it,
99
+ migrates its records, and runs next by hand or on its schedule. Owners and
100
+ admins release.
101
+
102
+ - `e3 workspace copy <repo-url> production staging` makes staging production
103
+ as it is now, apps included: the rehearsal's first step before each change.
104
+ - `release <repo-url> <from> <to>` prints the plan first, then releases;
105
+ `--plan` stops at the plan. A refused plan prints why and exits 1, changing
106
+ nothing; one that would change nothing is refused. The plan names any change
107
+ an admin forced onto the target since its last release, which it undoes. `--carry <path…>` copies inputs, and records new in the release,
108
+ from the source by reference; `--remove-apps` removes the target's apps the
109
+ source lacks.
110
+ - `history <repo-url> <workspace>` lists each release, deploy, app deploy,
111
+ copy and rollback, with its id; `rollback <repo-url> <workspace> [<id>]`
112
+ releases an entry again, its package and apps exactly.
113
+
114
+ ## Traps
115
+
116
+ - A release deploys the source's package by its version: re-importing a
117
+ package under the same version since the source deployed it refuses the
118
+ release (deploy the source again).
119
+ - A rollback past a record migration is refused: e3's deploy never migrates a
120
+ record back. A rollback stays open on a protected workspace.
121
+ - Sign in with `e3 auth login <server>`: there is no `e3 login`.
122
+ - `secrets set` reads the value from stdin unless `--value` is given; the
123
+ next run reads the new value.
124
+ - The version is the @elaraai lockstep: use the CLI of the release your
125
+ deployment runs.
@@ -0,0 +1,76 @@
1
+ ---
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`, `createRecordBackup`, `restoreRecordBackup`) and feedback (`listFeedback`, `closeFeedback`)."
4
+ ---
5
+
6
+ # @elaraai/e3-cloud-client
7
+
8
+ The e3 cloud API's client: every call takes the deployment's origin
9
+ (`https://e3.example.com`) and request options holding a token, and
10
+ throws `ApiError` on a refusal, its `code` naming it. Values are East values in
11
+ BEAST2 on the wire, typed by `@elaraai/e3-cloud-types`, so a role or a
12
+ response is a variant (`variant('owner', null)`, `response.type`). e3's own
13
+ routes (repositories, packages, workspaces, datasets, runs) are
14
+ `@elaraai/e3-api-client`'s.
15
+
16
+ ## Before writing code — search the example index
17
+
18
+ Every call has an entry in the plugin's index. Before writing code against a
19
+ deployment:
20
+
21
+ 1. Call `mcp__plugin_e3-cloud_e3-cloud__search_e3_cloud_examples` with what
22
+ you are about to do (`deploy an app from code`, `release with a plan`).
23
+ Summaries come back first.
24
+ 2. Fetch the one or two that match with
25
+ `mcp__plugin_e3-cloud_e3-cloud__get_e3_cloud_example` and pattern your code
26
+ on them.
27
+ 3. Do not read `node_modules/@elaraai/**` or reason from `.d.ts` signatures:
28
+ the index holds the same calls, exact and far cheaper.
29
+
30
+ Nothing is injected for you; the search is the step.
31
+
32
+ ## Quick Start
33
+
34
+ ```typescript
35
+ import { variant } from '@elaraai/east';
36
+ import { ApiError, addUser, whoami } from '@elaraai/e3-cloud-client';
37
+
38
+ const url = 'https://e3.example.com';
39
+ const options = { token: process.env.E3_TOKEN! };
40
+
41
+ const me = await whoami(url, options);
42
+ try {
43
+ await addUser(url, 'acme', { email: 'ada@example.com', role: variant('user', { roles: ['All apps'] }) }, options);
44
+ } catch (err) {
45
+ if (err instanceof ApiError) console.error(err.code); // forbidden, not_found, …
46
+ else throw err;
47
+ }
48
+ ```
49
+
50
+ ## Apps and releases
51
+
52
+ - An app deploy uploads the app object (`appUpload`, with
53
+ `@elaraai/e3-cloud-ui`'s `encodeAppObject`), then deploys it
54
+ (`appDeploy`). It answers `refused` with every problem, `checked` for a dry
55
+ run, `live`, `staged`, or `deploying` naming the deploy job its package runs
56
+ in, which `appDeployWait` waits for.
57
+ - A staging (`addStaging(url, repo, live, { name, start, plan })`, `start`
58
+ `variant('copy', null)` or `variant('as_is', null)`) protects the workspace
59
+ it releases to: its package and apps then change only by a release from it,
60
+ or a rollback; an app deploy or removal there throws `workspace_protected`
61
+ unless an admin passes `force`. `stopStaging` (admins) lifts it.
62
+ - A release (`releaseWorkspace(url, repo, target, { from, carry, removeApps, plan })`,
63
+ `from` the target's staging) answers `planned`, `refused` (its problems and
64
+ checks in the plan, `nothing_to_release` among them), `released` (its apps
65
+ switched) or `releasing` (the job `appDeployWait` waits for). Ask for the
66
+ plan first and show it; `releasePlanRefusalLines` says why a plan refuses,
67
+ and its `undoes` lists forced changes it undoes. `rollbackWorkspace` takes
68
+ an entry of `workspaceHistory`.
69
+
70
+ ## Traps
71
+
72
+ - The URL is the deployment's origin, not `…/api`: the client adds the path.
73
+ - A refusal of a release or an app deploy is an answer (`refused`), not a
74
+ throw; a request the server cannot take at all throws `ApiError`.
75
+ - The version is the @elaraai lockstep: use the client of the release the
76
+ deployment runs.
@@ -0,0 +1,108 @@
1
+ ---
2
+ name: e3-cloud-ui
3
+ description: "Apps for e3 cloud — a solution's pages and menu, deployed to a workspace apart from its package and drawn natively by the e3-cloud web app. Use when: (1) Writing an app's pages with Page(name, meta, thunk) — the thunk returning the body, an East.function returning UIComponentType whose one argument is the page's params — or Page.task(name, uiTask, meta) for a ui() task's output, (2) Linking pages with PageLink (to, params) and Nav.go / Nav.back, (3) Declaring the sidebar with Menu.group and the app with App(name, { package, title, logo, home, menu, pages }), (4) Building the bundle an app deploy uploads with buildApp / exportApp, and reading a refusal (AppBuildError) or a deploy's problems, (5) Checking an app against a package with checkApp (@elaraai/e3-cloud-ui/check), (6) Reading an app's East types (AppType, PageType, AppBundleType — @elaraai/e3-cloud-ui/types), (7) Deploying with the e3-cloud CLI: app build, app deploy (UI-only, or with its package), app list / versions / remove."
4
+ ---
5
+
6
+ # e3-cloud-ui — apps for e3 cloud
7
+
8
+ An **app** is a solution's pages and menu. It is deployed to one workspace of a
9
+ hosted e3, apart from the package, and the e3-cloud web app draws it natively:
10
+ each app is a sidebar section, each page a URL, its crumbs its parents. Apps
11
+ share a workspace's data, functions and records; staging and production each
12
+ have their own.
13
+
14
+ Read `README.md` for the author's guide; this file is the short form.
15
+
16
+ ## Before writing code — search the example index
17
+
18
+ Every e3 cloud API has an example in the plugin's index: the page bodies of
19
+ `@elaraai/e3-cloud-ui`, and the hand-written entries for `App`, `Page`,
20
+ `Page.task`, `Menu`, `buildApp` and `checkApp`. A page's body is East and
21
+ e3-ui code, whose examples are the East plugin's. Before writing or changing
22
+ an app:
23
+
24
+ 1. Call `mcp__plugin_e3-cloud_e3-cloud__search_e3_cloud_examples` for the
25
+ part of the app you are about to write. Summaries come back first: id,
26
+ description and keywords, a few hundred bytes each.
27
+ 2. Fetch the one or two that match with
28
+ `mcp__plugin_e3-cloud_e3-cloud__get_e3_cloud_example` and pattern your code
29
+ on them.
30
+ 3. For what a body does with data and components (`Data.bind`, `Func.bind`,
31
+ `Record.bind`, east-ui's components), search East's index too, with the
32
+ East plugin's `search_east_examples` (package `e3-ui` or `east-ui`).
33
+ 4. Do not read `node_modules/@elaraai/**` or `*.examples.tsx` files
34
+ wholesale, and do not reason from `.d.ts` signatures: the index holds the
35
+ same code, exact and far cheaper.
36
+
37
+ Nothing is injected for you; the search is the step.
38
+
39
+ ## Write a page
40
+
41
+ ```tsx
42
+ import { East, NullType } from '@elaraai/east';
43
+ import { Reactive, Stat, Slider, UIComponentType, VStack } from '@elaraai/east-ui';
44
+ import { Data } from '@elaraai/e3-ui';
45
+ import { App, Menu, Nav, Page, PageLink } from '@elaraai/e3-cloud-ui';
46
+
47
+ const overview = Page('overview', { title: 'Overview', icon: 'gauge-high' },
48
+ () => East.function([], UIComponentType, _$ => (
49
+ <Reactive>{$ => {
50
+ const t = $.let(Data.bind(target));
51
+ return (
52
+ <VStack>
53
+ <Stat label="Target" value={East.print(t.read())} />
54
+ <Slider value={t.read()} onChangeEnd={t.write} />
55
+ <PageLink to={line} params={{ site: 'North', line: 'L4' }}>North L4</PageLink>
56
+ </VStack>
57
+ );
58
+ }}</Reactive>
59
+ )));
60
+ ```
61
+
62
+ - The body is a **thunk**, `() => East.function(…)`: pages link both ways, so
63
+ bodies are built when the app builds.
64
+ - The function's **one argument is the page's params** (or none). Never write
65
+ the type separately: TypeScript takes it from the function.
66
+ - Bind data exactly as a `ui()` body does: `Data.bind`, `Data.bindPaged`,
67
+ `Func.bind`, `Record.bind`. Pass the defs, never names.
68
+ - `meta.parent` makes the crumbs and lights the menu item.
69
+ - Bind event handlers once: `const go = $.const(East.function([], NullType, $ => { $(Nav.go(line, key)); }))`.
70
+
71
+ ## Declare the app
72
+
73
+ ```ts
74
+ export default App('ops', {
75
+ package: acme, title: 'Acme Operations', home: overview,
76
+ menu: [Menu.group('Analyse', [overview, lines])],
77
+ pages: [overview, lines, line],
78
+ });
79
+ ```
80
+
81
+ `home` and menu pages take no params. `pages` lists every page.
82
+
83
+ ## Build and deploy
84
+
85
+ ```
86
+ e3-cloud app build src/apps/ops.tsx -o dist/ops.app
87
+ e3-cloud app deploy <repo-url> <workspace> dist/ops.app [--dry-run]
88
+ e3-cloud app deploy <repo-url> <workspace> --from-source src/apps/ops.tsx [--dry-run]
89
+ ```
90
+
91
+ An app is developed in the cloud, not locally: deploy it to a workspace of
92
+ your own (never a protected one: develop against its staging) and open it in
93
+ the console. `--dry-run` checks it against the workspace's package and changes
94
+ nothing; a deploy prints every problem when it is refused.
95
+
96
+ `buildApp` refuses an app that doesn't fit its own package (`AppBuildError`,
97
+ one line per problem). A deploy is UI-only when the workspace runs the bundle's
98
+ package, else it deploys the package too; both are refused unless every app
99
+ on the workspace fits.
100
+
101
+ ## Traps
102
+
103
+ - A body written without the thunk can only link to pages defined above it.
104
+ - A page that writes a task's output or a record through `Data.bind` is
105
+ refused: write inputs; change records through their mutations.
106
+ - `Page.task` needs a task in the `ui` role (`ui()`), and its output shows only
107
+ after the workspace's next dataflow run.
108
+ - The version is the @elaraai lockstep: use the same version as east and e3.