@sequenceholdings/studio-cli 0.1.13 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +258 -38
  2. package/dist/agents/apply-chunks.d.ts +13 -0
  3. package/dist/agents/apply-chunks.js +43 -0
  4. package/dist/agents/commands.d.ts +10 -0
  5. package/dist/agents/commands.js +218 -0
  6. package/dist/agents/scaffold.d.ts +2 -0
  7. package/dist/agents/scaffold.js +77 -0
  8. package/dist/agents/source.d.ts +18 -0
  9. package/dist/agents/source.js +121 -0
  10. package/dist/artifact/delegate.d.ts +2 -2
  11. package/dist/artifact/delegate.js +31 -73
  12. package/dist/atlas-client.js +52 -37
  13. package/dist/auth-cmds/commands.d.ts +1 -1
  14. package/dist/auth-cmds/commands.js +12 -7
  15. package/dist/auth.d.ts +104 -24
  16. package/dist/auth.js +456 -94
  17. package/dist/config.d.ts +3 -3
  18. package/dist/config.js +18 -13
  19. package/dist/env-catalog.js +13 -3
  20. package/dist/env-flags.d.ts +2 -0
  21. package/dist/env-flags.js +2 -0
  22. package/dist/env-registry.d.ts +27 -0
  23. package/dist/env-registry.js +204 -0
  24. package/dist/envs/commands.d.ts +1 -1
  25. package/dist/envs/commands.js +41 -3
  26. package/dist/file-lock.d.ts +5 -0
  27. package/dist/file-lock.js +187 -0
  28. package/dist/functions/commands.d.ts +10 -10
  29. package/dist/functions/commands.js +87 -53
  30. package/dist/functions/manifest.d.ts +1 -0
  31. package/dist/functions/manifest.js +36 -0
  32. package/dist/functions/source-selection.d.ts +24 -0
  33. package/dist/functions/source-selection.js +67 -0
  34. package/dist/login.d.ts +8 -3
  35. package/dist/login.js +46 -34
  36. package/dist/main.d.ts +3 -1
  37. package/dist/main.js +41 -12
  38. package/dist/orm/delegate.js +25 -7
  39. package/dist/pat-hints.js +2 -2
  40. package/dist/pipeline/commands.d.ts +58 -0
  41. package/dist/pipeline/commands.js +330 -0
  42. package/dist/pipeline/lifecycle.d.ts +58 -0
  43. package/dist/pipeline/lifecycle.js +348 -0
  44. package/dist/pipeline/pinning.d.ts +5 -0
  45. package/dist/pipeline/pinning.js +9 -0
  46. package/dist/pipeline/templates.d.ts +11 -0
  47. package/dist/pipeline/templates.js +166 -0
  48. package/dist/process/build.d.ts +4 -0
  49. package/dist/process/build.js +33 -2
  50. package/dist/process/codegen.js +19 -1
  51. package/dist/process/commands.js +97 -47
  52. package/dist/process/compiler-subprocess.d.ts +29 -0
  53. package/dist/process/compiler-subprocess.js +99 -0
  54. package/dist/process/compiler-worker.d.ts +1 -0
  55. package/dist/process/compiler-worker.js +38 -0
  56. package/dist/process/lint.d.ts +8 -0
  57. package/dist/process/lint.js +84 -29
  58. package/dist/process/repo-install.js +18 -2
  59. package/dist/repos/commands.d.ts +1 -1
  60. package/dist/repos/commands.js +17 -12
  61. package/dist/secrets/commands.d.ts +1 -1
  62. package/dist/secrets/commands.js +18 -18
  63. package/package.json +12 -5
package/README.md CHANGED
@@ -1,21 +1,27 @@
1
1
  # `@sequenceholdings/studio-cli` — `seq-studio`
2
2
 
3
- Standalone CLI for the Sequence platform: Lattice processes, Artifact Studio
4
- apps, Managed Functions, Managed Secrets, and platform git repos. Runs from
5
- any repo against the platform over HTTP — no monorepo checkout required.
3
+ Standalone CLI for the Sequence platform: typed agents, Lattice processes, Artifact Studio
4
+ apps, Managed Functions, Managed Secrets, ORM namespaces, Data Pipelines stage
5
+ specs, and platform git repos. Runs from any repo against the platform over
6
+ HTTP — no monorepo checkout required.
6
7
 
7
8
  ```
8
9
  seq-studio process lint
9
10
  seq-studio process plan -e <env>
10
11
  seq-studio process apply -e <env>
12
+ seq-studio agents validate
13
+ seq-studio agents plan -e <env>
11
14
  seq-studio artifact deploy -e <env>
15
+ seq-studio orm init lending
16
+ seq-studio pipeline validate
12
17
  seq-studio envs list
13
18
  seq-studio doctor
14
19
  ```
15
20
 
16
21
  > **Note:** all network commands require a Sequence platform account with the
17
22
  > appropriate permissions. Without one, only the offline commands
18
- > (`init`, `lint`, `simulate`, `build`, `bundle inspect`) work.
23
+ > (`init`, `lint`, `simulate`, `build`, `bundle inspect`, `agents init`,
24
+ > `agents validate`, offline `agents plan`, `pipeline init`, `pipeline validate`) work.
19
25
  > Sequence-internal contributors: see `INTERNAL.md` in the monorepo for
20
26
  > rollout SOPs, preview environments, and publishing docs.
21
27
 
@@ -44,34 +50,43 @@ releases install immediately.)
44
50
 
45
51
  ## Authenticate
46
52
 
47
- Run the built-in browser login once. `seq-studio` and `seqapi` share the
48
- resulting tokens at `~/.config/sequence-api/tokens.json`, so logging in with
49
- either CLI authenticates both.
53
+ Run the built-in browser login. `seq-studio` and `seqapi` share short-lived
54
+ access tokens at `~/.config/sequence-api/tokens.json`, so logging in with either
55
+ CLI authenticates both. Refresh tokens are neither requested nor persisted;
56
+ interactive commands perform a bounded PKCE login again after expiry.
50
57
 
51
58
  ```bash
52
- seq-studio login
53
- seq-studio doctor # confirms config + auth + authorization
59
+ seq-studio login # built-in Sequence environments
60
+ seq-studio envs add bsm-staging <tenant-url> # one-time tenant registration
61
+ seq-studio login --env bsm-staging # registered OpCo tenant realm
62
+ seq-studio doctor # confirms config + auth + authorization
54
63
  ```
55
64
 
56
- Use `seq-studio logout` to remove the shared cached tokens.
65
+ Use `seq-studio logout` to remove the shared Sequence session, or
66
+ `seq-studio logout --env bsm-staging` to remove only that OpCo realm's session.
57
67
 
58
68
  ### Headless auth (CI) — M2M
59
69
 
60
70
  When there's no interactive login (CI, automation), set the service-account
61
- secret and `seq-studio` mints a token via the Auth0 client-credentials grant
62
- (M2M wins when the secret is set, otherwise the cached user token is used):
71
+ secret and `seq-studio` mints a token via the Auth0 client-credentials grant.
72
+ A valid cached user session wins over an ambient M2M secret (common under
73
+ Doppler `atlas/dev`); force the service account with `SEQAPI_AUTH_MODE=m2m`:
63
74
 
64
75
  ```bash
65
- export AUTH0_M2M_CLIENT_SECRET=... # provided by your platform administrator
76
+ export AUTH0_M2M_CLIENT_SECRET=... # built-in Sequence environments
77
+ export AUTH0_M2M_CLIENT_SECRET_BSM_STAGING=... # registered bsm-staging realm
78
+ export SEQAPI_AUTH_MODE=m2m # optional: ignore a leftover user session
66
79
  seq-studio artifact deploy -e <env>
67
80
  ```
68
81
 
69
- The secret is read at runtime never commit it. M2M carries app scopes but
82
+ Registered OpCo environment names are upper-snaked in the variable suffix
83
+ (`bsm-staging` → `BSM_STAGING`). Secrets are read at runtime — never commit them.
84
+ M2M carries app access but
70
85
  **no user identity / workspace membership**, so it's blind to
71
86
  user-scoped/private resources.
72
87
 
73
- **Manual escape hatch:** any `artifact` command also accepts an explicit
74
- `--token <jwt>`, which wins over both the M2M and cached-user paths.
88
+ Artifact commands do not accept bearer tokens through argv or environment.
89
+ Use interactive login or the realm-specific M2M secret above.
75
90
 
76
91
  ## Environments
77
92
 
@@ -82,7 +97,7 @@ environment-discovery endpoint and caches the result at
82
97
  `~/.config/lattice/environments.json`.
83
98
 
84
99
  ```bash
85
- seq-studio login # or: export AUTH0_M2M_CLIENT_SECRET=...
100
+ seq-studio login # or use the matching M2M secret described above
86
101
  seq-studio envs refresh # fetch the environments visible to your identity
87
102
  seq-studio envs list # show them (name, URL, source)
88
103
  ```
@@ -93,8 +108,12 @@ see depends on who you are — unauthenticated installs get `local` only, and
93
108
  authenticated identities get the deployments they're entitled to. Visibility
94
109
  is not access control: every request is still authorized server-side.
95
110
 
96
- You can always add or override environments yourself in
97
- `~/.config/lattice/config.toml` (user entries win over discovered ones):
111
+ You can add or override trusted environments yourself in
112
+ `~/.config/lattice/config.toml` (user entries win over discovered ones).
113
+ Authenticated requests accept only HTTPS origins at `seqholdings.com` or its
114
+ subdomains, plus HTTP loopback origins for local development. The CLI
115
+ revalidates that exact origin immediately before attaching credentials and
116
+ never follows authenticated redirects.
98
117
 
99
118
  ```toml
100
119
  # Must come before any [env.*] table — TOML attaches bare keys to the
@@ -105,7 +124,7 @@ default_env = "local"
105
124
  url = "http://localhost:5001"
106
125
 
107
126
  [env.my-atlas]
108
- url = "https://atlas.example.com"
127
+ url = "https://my-atlas.seqholdings.com"
109
128
  ```
110
129
 
111
130
  Pass `--env <name>` (or `-e <name>`) on commands that talk to the platform.
@@ -115,6 +134,101 @@ Pass `--env <name>` (or `-e <name>`) on commands that talk to the platform.
115
134
  the artifact folder's `.artifact-studio/config.json` `defaultEnv` (set by
116
135
  `artifact link` / `artifact env use`).
117
136
 
137
+ ## Agent commands
138
+
139
+ Typed agent repositories export one or more `defineAgent(...)` values from files
140
+ named `agent.ts`. Definitions are compiled in a credential-scrubbed child process,
141
+ validated with the published `@sequenceholdings/agent-spec` contract, normalized,
142
+ and hashed before deployment. Apply creates or updates only the definitions in the
143
+ bundle; it never implicitly deletes agents.
144
+
145
+ | Command | What it does |
146
+ |---------|--------------|
147
+ | `seq-studio agents init <dir>` | Scaffold a standalone typed agent repository |
148
+ | `seq-studio agents validate [--dir <dir>] [--target <APP_ENV>]` | Compile and validate locally, without API access |
149
+ | `seq-studio agents plan [--dir <dir>]` | Offline compile/hash plan |
150
+ | `seq-studio agents plan [--dir <dir>] -e <env> [--target <APP_ENV>]` | Diff creates, updates, and unchanged definitions against an environment |
151
+ | `seq-studio agents apply [--dir <dir>] -e <env> [--target <APP_ENV>] [--yes]` | Apply creates and updates after showing the plan |
152
+ | `seq-studio agents list -e <env>` | List visible runtime agents |
153
+ | `seq-studio agents show <id> -e <env>` | Show one runtime agent |
154
+
155
+ An optional `deploy-manifest.json` targets definitions by deployment identity:
156
+
157
+ ```json
158
+ {
159
+ "schemaVersion": 1,
160
+ "definitions": [
161
+ {
162
+ "id": "680000000000000000000001",
163
+ "path": "support/agent.ts",
164
+ "environments": ["local", "staging", "production"]
165
+ }
166
+ ]
167
+ }
168
+ ```
169
+
170
+ Standalone workflow:
171
+
172
+ ```bash
173
+ pnpm dlx @sequenceholdings/studio-cli agents init support-agent
174
+ cd support-agent
175
+ pnpm install
176
+ pnpm exec seq-studio agents validate
177
+ pnpm exec seq-studio agents plan
178
+ # Authenticate only when ready to inspect or apply an environment:
179
+ pnpm exec seq-studio login
180
+ pnpm exec seq-studio agents plan -e <env>
181
+ pnpm exec seq-studio agents apply -e <env>
182
+ ```
183
+
184
+ Use `--repo agents/<name> [--ref <ref>]` or `--git-url <url>` instead of
185
+ `--dir` to materialize reviewed source from the platform git service.
186
+
187
+ ## ORM commands
188
+
189
+ `seq-studio orm` authors and deploys governed ORM v2 namespaces: TypeScript
190
+ table definitions and policies plus named GraphQL documents compiled into
191
+ persisted operations.
192
+
193
+ | Command | What it does |
194
+ |---------|--------------|
195
+ | `seq-studio orm init <dir>` | Scaffold one v2 namespace package (`sequence.config.ts`, `schema/*.ts`, `graphql/**`, and codegen config). |
196
+ | `seq-studio orm generate [dir]` | Generate `schema.graphql`, `operations.manifest.json`, `typePolicies.gen.ts`, and consumer codegen when `codegen.ts` is present. |
197
+ | `seq-studio orm validate [dir]` | Parse and compile the namespace, then verify its committed migration chain is current. |
198
+ | `seq-studio orm plan [dir] -e <env>` | Compare the compiled namespace with registry state without applying database changes. |
199
+ | `seq-studio orm diff [dir] [--check]` | Author the next committed migration, or verify the migration/snapshot chain offline for CI. |
200
+ | `seq-studio orm apply [dir] -e <env>` | Author a migration if needed, register/apply the namespace, activate its operation set, publish roles/capabilities, and refresh generated outputs. |
201
+ | `seq-studio orm migrate-from-yaml <dir>` | Convert a legacy YAML namespace to TypeScript authoring while preserving its committed migrations. |
202
+
203
+ The everyday loop is:
204
+
205
+ ```bash
206
+ seq-studio orm init lending
207
+ cd lending
208
+ pnpm install
209
+
210
+ # Edit sequence.config.ts, schema/*.ts, and graphql/**/*.ts.
211
+ seq-studio orm generate .
212
+ seq-studio orm plan . -e local
213
+ seq-studio orm apply . -e local
214
+ seq-studio orm validate .
215
+ ```
216
+
217
+ `apply --dry-run` rehearses a migration against a disposable branch copy of
218
+ the target environment's data. `apply --no-create` is the CI guard that refuses
219
+ to provision a missing namespace. Destructive DDL requires explicit
220
+ `--allow-destructive` consent.
221
+
222
+ > **ORM v2 branch status:** the scaffold currently depends on
223
+ > `@sequenceholdings/orm@^2.0.0`, which is not published yet; the registry's
224
+ > latest release is the v1 `0.1.1` package. A clean standalone scaffold cannot
225
+ > complete `pnpm install` until the v2 ORM dependency chain is released. Do not
226
+ > use monorepo workspace links as evidence that the external workflow is ready.
227
+ > Sequence contributors should see
228
+ > [`docs/platform/orm-v2.md`](../../../docs/platform/orm-v2.md) for the branch
229
+ > architecture, internal verification workflow, demo, and remaining rollout
230
+ > gates.
231
+
118
232
  ## Process commands
119
233
 
120
234
  | Command | What it does |
@@ -123,9 +237,9 @@ the artifact folder's `.artifact-studio/config.json` `defaultEnv` (set by
123
237
  | `seq-studio process lint` | Static checks (graph, return contracts, agent schema, timeouts) |
124
238
  | `seq-studio process plan -e <env>` | Build bundle, diff against currently-active version |
125
239
  | `seq-studio process apply -e <env> [--only <id1,id2>]` | Build → register bundle → promote each process. `--only` promotes just the named process ids (the bundle still contains the whole root — registration is inert) |
126
- | `seq-studio process apply --repo processes/<name> [--ref <r>] -e <env> [--only <id1,id2>]` | Same as above, but materializes the source from a platform git-service repo. Pinned commit SHA is injected as bundle provenance. Requires `ATLAS_GIT_PAT` (or `AUTH0_M2M_CLIENT_SECRET` for CI) |
240
+ | `seq-studio process apply --repo processes/<name> [--ref <r>] -e <env> [--only <id1,id2>]` | Same as above, but materializes the source from a platform git-service repo. Pinned commit SHA is injected as bundle provenance. Requires `ATLAS_GIT_PAT` (or the target realm's M2M secret for CI) |
127
241
  | `seq-studio process test -e <env>` | CI wrapper: lint + plan, non-zero exit on errors or BREAKING diffs |
128
- | `seq-studio process simulate <id>` | In-process walk with stubbed runners (offline) |
242
+ | `seq-studio process simulate <id>` | Isolated child-process walk with stubbed runners (offline) |
129
243
  | `seq-studio process bundle build [-o file.json]` | Build a bundle locally |
130
244
  | `seq-studio process bundle pull <hash> [-e <env>] [-o file.json]` | Fetch a stored bundle |
131
245
  | `seq-studio process bundle inspect <bundle.json>` | Show a saved bundle's summary |
@@ -149,7 +263,16 @@ temp tree is cleaned up — even on error. Only the `processes` namespace is
149
263
  accepted; other namespaces (artifacts, managed-functions) are rejected.
150
264
 
151
265
  Auth: same as `artifact deploy --repo` — `ATLAS_GIT_PAT` for the smart-HTTP
152
- clone path, or `AUTH0_M2M_CLIENT_SECRET` for CI's JSON materialize path.
266
+ clone path, or the target realm's M2M secret for CI's JSON materialize path.
267
+ Those credentials remain in the parent CLI and are not forwarded to dependency
268
+ installation or process build tooling. Each install uses fresh temporary
269
+ package-manager caches that are removed after the invocation.
270
+
271
+ This is ambient-credential isolation, not an OS security sandbox. Build workers
272
+ still run as the caller's uid, so hostile source may inspect other same-uid
273
+ processes or readable files on platforms that permit it (for example, Linux
274
+ `/proc`). Build reviewed source only; use a dedicated ephemeral runner with no
275
+ unrelated credentials when the source is not trusted.
153
276
 
154
277
  ### Process discovery
155
278
 
@@ -171,6 +294,47 @@ cd my-processes
171
294
  seq-studio process lint # finds both processes
172
295
  ```
173
296
 
297
+ ## Managed Function commands
298
+
299
+ | Command | What it does |
300
+ |---------|--------------|
301
+ | `seq-studio functions init <dir>` | Scaffold one standalone TypeScript managed function |
302
+ | `seq-studio functions build [--dir <dir>]` | Validate a local manifest, bundle, lockfile, and size |
303
+ | `seq-studio functions deploy --dir <dir> -e <env>` | Preview secrets and deploy a local function |
304
+ | `seq-studio functions build --repo managed-functions/<name> [--path <dir>] -e <env>` | Materialize and validate a function from the platform Git Service |
305
+ | `seq-studio functions deploy --repo managed-functions/<name> [--path <dir>] -e <env>` | Materialize and deploy a function from the platform Git Service |
306
+
307
+ A normal function repo keeps `managed-function.yml` at its root and omits
308
+ `--path`. A repo may also contain related, independently deployed functions:
309
+
310
+ ```text
311
+ functions/
312
+ get-loan/
313
+ managed-function.yml
314
+ package.json
315
+ pnpm-lock.yaml
316
+ index.ts
317
+ update-loan/
318
+ managed-function.yml
319
+ package.json
320
+ pnpm-lock.yaml
321
+ index.ts
322
+ ```
323
+
324
+ Select exactly one function directory for each build or deploy:
325
+
326
+ ```bash
327
+ seq-studio functions build --repo managed-functions/encompass \
328
+ --path functions/get-loan -e staging
329
+ seq-studio functions deploy --repo managed-functions/encompass \
330
+ --path functions/get-loan -e staging
331
+ ```
332
+
333
+ Each selected directory is a self-contained function package. Functions in the
334
+ same repo share Git review and commit provenance, but keep separate manifests,
335
+ versions, runtime resources, secrets, and permissions. `--path` accepts only a
336
+ canonical relative directory inside a remote repo; use `--dir` for local source.
337
+
174
338
  ## Artifact commands
175
339
 
176
340
  `seq-studio artifact <sub>` is the entry point for Artifact Studio. It runs
@@ -183,11 +347,11 @@ routed through `~/.config/lattice/config.toml` and the shared seqapi token.
183
347
  | `seq-studio artifact link [dir] -e <env> [--project <id>]` | `link [dir] --env <env>` |
184
348
  | `seq-studio artifact build [dir]` | `build [dir]` |
185
349
  | `seq-studio artifact plan [dir] -e <env>` | `plan [dir] --env <env>` |
186
- | `seq-studio artifact deploy [dir] -e <env> [--skip-unchanged] [--no-create] [--project <id>]` | `deploy [dir] --env <env>` — `--skip-unchanged` no-ops (before building) when the remote active deployment's `sourceHash` already matches the local source; `--no-create` errors instead of creating a missing project; `--project <id>` targets a project directly when duplicate slugs make the lookup ambiguous (slug must still match the manifest) |
350
+ | `seq-studio artifact deploy [dir] -e <env> [--skip-unchanged] [--no-create] [--project <id>]` | `deploy [dir] --env <env>` — `--skip-unchanged` no-ops (before building) when the remote active deployment's `sourceHash` **and** CLI/atlas-ui peer versions already match; `--no-create` errors instead of creating a missing project; `--project <id>` targets a project directly when duplicate slugs make the lookup ambiguous (slug must still match the manifest) |
187
351
  | `seq-studio artifact dev [dir] -e <env>` | `dev [dir] --env <env>` |
188
352
  | `seq-studio artifact pull <project-id> -e <env> [--out <dir>]` | `pull <project-id> --env <env> [--out <dir>]` |
189
353
  | `seq-studio artifact list -e <env>` | `list --env <env>` — projects visible on the environment (slug, id, active version, visibility) |
190
- | `seq-studio artifact show <slug-or-id> -e <env>` | `show <slug-or-id> --env <env>` — one project's detail incl. active deployment + git provenance |
354
+ | `seq-studio artifact show <slug-or-id> -e <env>` | `show <slug-or-id> --env <env>` — one project's detail incl. active deployment, git provenance, and (for newer deployments) the building `artifact-studio` / force-aliased `atlas-ui` versions |
191
355
  | `seq-studio artifact promote <deployment-id> -e <env>` | `promote <deployment-id> --env <env>` |
192
356
  | `seq-studio artifact rollback <deployment-id> -e <env>` | `rollback <deployment-id> --env <env>` |
193
357
 
@@ -197,6 +361,18 @@ routed through `~/.config/lattice/config.toml` and the shared seqapi token.
197
361
  directory's `.artifact-studio/config.json` — run them from the linked artifact
198
362
  folder (or run `seq-studio artifact link` first).
199
363
 
364
+ **Active (official) deploys require a clean `main` checkout with a resolved
365
+ git commit** for both Git Service (`--repo`) and local sources. Feature
366
+ branches, dirty trees, non-git sources, and detached checkouts that cannot be
367
+ attributed to `main` are preview-only
368
+ (`seq-studio artifact dev` / preview channel); promotion applies the same
369
+ provenance check.
370
+
371
+ **CLI atlas-ui stamp (DES-254):** builds force-alias `@sequenceholdings/atlas-ui`
372
+ to the CLI's copy — not the artifact's declared semver. Deployments record
373
+ `cliVersion` + `atlasUiVersion`. Contract:
374
+ `@sequenceholdings/artifact-studio` → `VERSION-PIN.md`.
375
+
200
376
  ### Source for `build` / `plan` / `deploy`
201
377
 
202
378
  These three commands read their source tree from one of three places — the rest
@@ -206,14 +382,28 @@ of the pipeline (build → upload) is identical regardless of origin:
206
382
  |------|--------|
207
383
  | _(none)_ / `[dir]` | a local folder (default, unchanged) |
208
384
  | `--repo <ns>/<name>` | a repo in the platform Git Service, e.g. `--repo artifacts/accounts` |
209
- | `--git-url <url>` | any git URL (cloned to a temp dir) |
385
+ | `--git-url <url>` | a public, credential-free HTTPS git URL (cloned to a temp dir) |
210
386
 
211
- `--ref <branch\|tag\|commit>` selects the revision (default: the repo's default
212
- branch). A remote source is materialized to a temp dir, built, and torn down;
387
+ `--ref <branch\|tag\|commit>` selects the revision for `build` and `plan`
388
+ (default: the repo's default branch). Active `deploy` requires `main`; other
389
+ refs are preview-only. A remote source is materialized to a temp dir, built,
390
+ and torn down;
213
391
  the target project is resolved from the source's `artifact.bundle.yml`
214
392
  `project_id`. The deployment records the resolved commit as its `git_commit`
215
- provenance. `--repo` needs `-e <env>` + a platform login; `--git-url` needs git
216
- credentials for private repos. `dev` is local-only.
393
+ provenance. `--repo` needs `-e <env>` + a platform login. M2M/CI builds accept
394
+ only platform-managed `--repo` sources; `--git-url` is interactive-only and
395
+ rejects embedded credentials, query tokens, SSH/file URLs, and Git remote
396
+ helpers. `dev` is local-only.
397
+
398
+ Artifact builds, dependency installs, process-definition imports, and local
399
+ process simulations run in short-lived children with an allowlisted runtime
400
+ environment and a synthetic home/config directory. Parent bearer tokens, Auth0
401
+ M2M secrets, Doppler tokens, cloud credentials, GitHub tokens, and user config
402
+ files are not inherited. The platform Git Service clone path passes only its
403
+ single scoped PAT to `git` through an ephemeral askpass helper.
404
+ This is a credential-inheritance boundary, not an OS filesystem sandbox:
405
+ child code still runs as the invoking user and must be treated as trusted to
406
+ read files that it names explicitly outside the synthetic home.
217
407
 
218
408
  ## Pull / clone / deploy — which path?
219
409
 
@@ -252,7 +442,7 @@ You can also open **Repositories → Access tokens** / the clone popover’s
252
442
  Requires Auth0 login. Same identity as the UI:
253
443
 
254
444
  ```bash
255
- seq-studio login
445
+ seq-studio login # add --env <registered-opco-env> for a tenant realm
256
446
  seq-studio auth pat create --name laptop --scopes repo:read,repo:write -e <env>
257
447
  # optional: --expires 7d|30d|90d|1y|never (default 30d)
258
448
  # optional: --store-credentials # git credential approve for the env host
@@ -270,18 +460,48 @@ JSON API — the same repos `--repo <ns>/<name>` sources build from.
270
460
 
271
461
  | Command | What it does |
272
462
  |---------|--------------|
273
- | `seq-studio repos list [-e <env>] [--namespace <slug>] [--mine]` | repos visible on the environment (permission-filtered) |
274
- | `seq-studio repos namespaces [create <slug>] [-e <env>]` | list namespaces, or create one (creator becomes owner) |
275
- | `seq-studio repos show <ns>/<name> [-e <env>]` | detail: id, branches, clone URL; artifact project id when slug matches |
276
- | `seq-studio repos create <ns>/<name> [-e <env>] [--default-branch <b>]` | create an empty repo (needs namespace write) |
277
- | `seq-studio repos clone <ns>/<name> \| --url <clone-url> \| --id <uuid> [-e <env>] [--ref <r>] [--out <dir>] [--force]` | smart-HTTP `git clone` when `ATLAS_GIT_PAT` is set (`--url`/`--id` need no seqapi); otherwise JSON materialize + PAT hint |
278
- | `seq-studio repos pull <ns>/<name> [-e <env>] [--ref <r>] [--out <dir>] [--force]` | always materialize via JSON API (no `.git` dir); refuses a non-empty destination unless `--force` |
279
- | `seq-studio repos delete <ns>/<name> [-e <env>] [--yes]` | delete a repo — interactive confirm unless `--yes` |
463
+ | `seq-studio repos list -e <env> [--namespace <slug>] [--mine]` | repos visible on the environment (permission-filtered) |
464
+ | `seq-studio repos namespaces [create <slug>] -e <env>` | list namespaces, or create one (creator becomes owner) |
465
+ | `seq-studio repos show <ns>/<name> -e <env>` | detail: id, branches, clone URL; artifact project id when slug matches |
466
+ | `seq-studio repos create <ns>/<name> -e <env> [--default-branch <b>]` | create an empty repo (needs namespace write) |
467
+ | `seq-studio repos clone <ns>/<name> \| --url <clone-url> \| --id <uuid> -e <env> [--ref <r>] [--out <dir>] [--force]` | smart-HTTP `git clone` when `ATLAS_GIT_PAT` is set (`--url`/`--id` need no seqapi); otherwise JSON materialize + PAT hint |
468
+ | `seq-studio repos pull <ns>/<name> -e <env> [--ref <r>] [--out <dir>] [--force]` | always materialize via JSON API (no `.git` dir); refuses a non-empty destination unless `--force` |
469
+ | `seq-studio repos delete <ns>/<name> -e <env> [--yes]` | delete a repo — interactive confirm unless `--yes` |
280
470
 
281
471
  `show` prints the smart-HTTP clone URL (`…/repos/<id>/git`). Basic auth:
282
472
  any username, PAT as password. Prefer `repos clone` over hand-rolling the
283
473
  tree API.
284
474
 
475
+ ## Pipeline commands
476
+
477
+ `seq-studio pipeline <sub>` authors and validates Data Pipelines **stage
478
+ specs** — the typed contracts (`<name>.stage.yml`) a Pipeline repo
479
+ (`pipelines/<domain>`) is made of. Validation logic lives in
480
+ `@sequenceholdings/pipeline-spec` (an optional peer, like `@sequenceholdings/orm`);
481
+ install it alongside the CLI to use this family.
482
+
483
+ | Command | What it does |
484
+ |---------|--------------|
485
+ | `seq-studio pipeline init --type ingestion\|transformation\|serving <name> [--dir <dir>]` | Scaffold `<name>.stage.yml` (commented per-kind template) plus a `src/` entrypoint stub (serving stages are declarative — no stub). Refuses to overwrite an existing spec |
486
+ | `seq-studio pipeline validate [dir] [--assets <file\|url>] [--json]` | Run the full offline spec gate: envelope + body validation, `schema_ref` resolution, and repo-level graph validation (reference resolution, single-writer, cycles, column subsets, serving projection checks). Exit 0/1 |
487
+ | `seq-studio pipeline plan --repo pipelines/<slug> --ref <sha\|branch> -e <env> [--json]` | Plan a Pipeline deploy (materialize → SDK/`validateSpecGraph` → compile → live-diff → provision findings). Does **not** run Databricks `bundle validate` (that is a Trigger deploy-path hard gate). Exit 1 on destructive findings (CI-safe). `--json` emits the stable plan envelope |
488
+ | `seq-studio pipeline deploy --repo pipelines/<slug> --ref <sha> -e <env> [--approved-by <sub>] [--no-wait]` | Plan then enqueue deploy; Trigger runs `bundle validate` then `bundle deploy` against reviewed bytes. Polls to terminal unless `--no-wait`. Production/banksouth require a pinned 40-hex SHA (client + server) |
489
+ | `seq-studio pipeline run-now --stage <slug> -e <env> [--repo pipelines/<slug>] [--json]` | Run the stage's active job or DLT pipeline immediately and print its Databricks run URL |
490
+ | `seq-studio pipeline promote --stage <slug> --version <v> -e <env> [--repo pipelines/<slug>] [--approved-by <you>] [--no-wait]` | Promote a validated version to another environment. Prod/banksouth require `--approved-by` naming the authenticated caller (approvals are self-recorded); `--repo` disambiguates a slug that exists in multiple Pipelines |
491
+ | `seq-studio pipeline rollback --stage <slug> -e <env> [--repo pipelines/<slug>] [--approved-by <you>] [--no-wait]` | Redeploy the previously retired deployment's version. Prod/banksouth require `--approved-by` — approvals are explicit even for rollbacks |
492
+
493
+ `validate` is offline — no network or database. `--assets` supplies a
494
+ registry **asset export** (JSON) so inputs referencing other Pipelines'
495
+ assets resolve; pass a local file or an authenticated URL. `--json` emits a
496
+ stable machine shape (`{ ok, stages, findings[] }` with machine-readable
497
+ finding codes and consumer lists) for CI annotation — the
498
+ `pipeline-verify.yml` workflow runs exactly this on PRs touching
499
+ `pipelines/**`.
500
+
501
+ For local Atlas development, `-e local` uses the server's isolated `dev`
502
+ deployment target. Plan, deploy, and `run-now` therefore operate on the same
503
+ personal dev Databricks catalog and Lakebase branch configured for local Atlas.
504
+
285
505
  ## Authorization
286
506
 
287
507
  The CLI carries no permissions of its own: every request is authorized
@@ -0,0 +1,13 @@
1
+ import { type AgentDefinition } from '@sequenceholdings/agent-spec';
2
+ import { type CommandContext } from '../functions/commands.js';
3
+ export interface ApplySummary {
4
+ created: number;
5
+ updated: number;
6
+ unchanged: number;
7
+ }
8
+ /** Each chunk is hashed over its own definitions — the apply route validates the body it received. */
9
+ export declare function applyInChunks({ context, definitions, source, }: {
10
+ context: CommandContext;
11
+ definitions: AgentDefinition[];
12
+ source: string;
13
+ }): Promise<ApplySummary>;
@@ -0,0 +1,43 @@
1
+ import { hashAgentBundle, } from '@sequenceholdings/agent-spec';
2
+ import { postJson } from '../atlas-client.js';
3
+ import { clientOptions } from '../functions/commands.js';
4
+ const LOG = '[seq-studio]';
5
+ // Chunked to stay inside the HTTP client's timeout; each agent commits independently anyway.
6
+ const APPLY_CHUNK_SIZE = 20;
7
+ /** Each chunk is hashed over its own definitions — the apply route validates the body it received. */
8
+ export async function applyInChunks({ context, definitions, source, }) {
9
+ const chunks = [];
10
+ for (let i = 0; i < definitions.length; i += APPLY_CHUNK_SIZE) {
11
+ chunks.push(definitions.slice(i, i + APPLY_CHUNK_SIZE));
12
+ }
13
+ const total = { created: 0, updated: 0, unchanged: 0 };
14
+ let applied = 0;
15
+ for (const [index, chunk] of chunks.entries()) {
16
+ try {
17
+ const result = await postJson({
18
+ ...clientOptions(context),
19
+ path: '/api/agents/deploy/apply',
20
+ body: {
21
+ definitions: chunk,
22
+ bundleHash: hashAgentBundle({ definitions: chunk }),
23
+ source,
24
+ },
25
+ });
26
+ total.created += result.summary.created;
27
+ total.updated += result.summary.updated;
28
+ total.unchanged += result.summary.unchanged;
29
+ applied += chunk.length;
30
+ if (chunks.length > 1) {
31
+ console.log(`${LOG} batch ${index + 1}/${chunks.length}: ${applied} of ${definitions.length} agents`);
32
+ }
33
+ }
34
+ catch (error) {
35
+ // Name what already landed. Without it a mid-run failure reads as a total
36
+ // failure, and the operator cannot tell which agents are already on the
37
+ // new definition.
38
+ console.error(`${LOG} batch ${index + 1}/${chunks.length} failed after ${applied} of ${definitions.length} agents applied — re-run to resume`);
39
+ throw error;
40
+ }
41
+ }
42
+ return total;
43
+ }
@@ -0,0 +1,10 @@
1
+ import type { ParsedArgs } from '../process/commands.js';
2
+ import { agentsInitCommand } from './scaffold.js';
3
+ export { agentsInitCommand };
4
+ export declare function agentsValidateCommand(args: ParsedArgs): Promise<number>;
5
+ export declare function agentsPlanCommand(args: ParsedArgs): Promise<number>;
6
+ export declare function agentsApplyCommand(args: ParsedArgs): Promise<number>;
7
+ export declare function agentsListCommand(args: ParsedArgs): Promise<number>;
8
+ export declare function agentsShowCommand(args: ParsedArgs): Promise<number>;
9
+ export declare const AGENTS_USAGE = "usage:\n seq-studio agents init <dir> scaffold a typed agent\n seq-studio agents validate [--dir d] [--target app] offline compile + validation\n seq-studio agents plan [--dir d] [-e <env>] offline bundle plan or live diff\n seq-studio agents apply [--dir d] -e <env> [--yes] apply creates/updates; never deletes\n seq-studio agents list -e <env> list visible agents\n seq-studio agents show <id> -e <env> show one agent\n\n Source: local --dir (default .), --repo agents/<name>, or --git-url <url>.\n Use --ref for remote sources. --target selects the deployment APP_ENV when it\n differs from the CLI environment alias (notably OpCo registrations).\n";
10
+ export declare function runAgentsCommand(sub: string | undefined, args: ParsedArgs): Promise<number>;