@sequenceholdings/artifact-studio 0.10.1 → 0.11.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/README.md +35 -0
- package/dist/active-deploy-policy.d.ts +15 -2
- package/dist/active-deploy-policy.js +31 -7
- package/dist/build.js +6 -0
- package/dist/cli.js +43 -7
- package/dist/manifest-static.d.ts +5 -0
- package/dist/manifest-static.js +14 -0
- package/dist/manifest.d.ts +5 -0
- package/dist/platform-client.d.ts +838 -0
- package/dist/platform-client.js +47 -0
- package/dist/preview-key.d.ts +8 -0
- package/dist/preview-key.js +12 -0
- package/dist/sdk-processes.d.ts +28 -0
- package/dist/sdk-processes.js +30 -0
- package/dist/sdk.d.ts +33 -26
- package/dist/sdk.js +4 -1
- package/dist/server/broker-contract.d.ts +1 -1
- package/dist/server/client.d.ts +4 -1
- package/dist/server/client.js +3 -1
- package/dist/server/platform-client.d.ts +870 -0
- package/dist/server/platform-client.js +34 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +1 -0
- package/dist/templates/nextjs/pnpm-workspace.yaml +1 -0
- package/dist/templates/react-vite/package.json +1 -1
- package/package.json +5 -4
- package/templates/nextjs/pnpm-workspace.yaml +1 -0
- package/templates/react-vite/package.json +1 -1
package/README.md
CHANGED
|
@@ -156,6 +156,41 @@ deployer provide generic application capabilities; each deployed artifact owns
|
|
|
156
156
|
its product behavior. Primitive code must not branch on an artifact ID or import
|
|
157
157
|
an application's services. See [Platform primitive boundaries](../../../docs/platform/platform-primitives.md).
|
|
158
158
|
|
|
159
|
+
## Lattice processes from a static app (awaiting publication)
|
|
160
|
+
|
|
161
|
+
A static (React/Vite) artifact starts, reads and acts on Lattice runs with the
|
|
162
|
+
same operations a Next.js server uses. Declare each process id in
|
|
163
|
+
`artifact.bundle.yml`:
|
|
164
|
+
|
|
165
|
+
```yaml
|
|
166
|
+
capabilities:
|
|
167
|
+
processes:
|
|
168
|
+
start: [maintenance-request] # start runs
|
|
169
|
+
read: [maintenance-request] # list and show runs, describe the process, the user's own tasks
|
|
170
|
+
act: [maintenance-request] # complete or reassign human steps, cancel, share runs
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { createArtifactProcesses } from '@sequenceholdings/artifact-studio'
|
|
175
|
+
|
|
176
|
+
const processes = createArtifactProcesses()
|
|
177
|
+
const run = await processes.start({ process: 'maintenance-request', metadata: { unit: '4B' } })
|
|
178
|
+
const snapshot = await processes.getRun(run.run_id)
|
|
179
|
+
const tasks = await processes.listTasks()
|
|
180
|
+
await processes.advance({ runId: run.run_id, payload: { approved: true } })
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Atlas checks every call against the deployed manifest's `capabilities.processes`,
|
|
184
|
+
not the browser's copy. A process it does not declare is refused with 403
|
|
185
|
+
before any grant is checked; declaring `/api/lattice/runs` under
|
|
186
|
+
`capabilities.api.write` is not a substitute, because that path is not scoped to
|
|
187
|
+
a process. The signed-in user's own grants then decide: Invoker to start,
|
|
188
|
+
Viewer to read, Advancer to complete a step, Owner to reassign or share.
|
|
189
|
+
Refusals raise `ArtifactServerError`, with Atlas's `detail` and `code` on
|
|
190
|
+
`error.atlas`. Group task pages, task assignments, batch describe and the
|
|
191
|
+
human-completion readers stay Next.js-only. This needs the matching Atlas
|
|
192
|
+
release; on an older host `createArtifactProcesses()` throws `processes_unavailable`.
|
|
193
|
+
|
|
159
194
|
## Lattice run lists and collaboration (internal prerelease)
|
|
160
195
|
|
|
161
196
|
The server entry point remains an **internal** surface. These methods describe
|
|
@@ -20,6 +20,11 @@ export interface ActiveDeployProvenance {
|
|
|
20
20
|
gitCommit?: string | null;
|
|
21
21
|
gitBranch?: string | null;
|
|
22
22
|
gitDirty?: boolean | null;
|
|
23
|
+
/**
|
|
24
|
+
* The target deployment's own environment (its Atlas `APP_ENV`). A CLI `-e`
|
|
25
|
+
* name is only a local alias (`sandbox` in an agent sandbox, or whatever
|
|
26
|
+
* `envs add` chose), so the CLI never supplies it.
|
|
27
|
+
*/
|
|
23
28
|
environment?: string | null;
|
|
24
29
|
}
|
|
25
30
|
/** Canonical default branch name for official artifact deploys. */
|
|
@@ -36,7 +41,15 @@ export declare function isActiveDeployDefaultBranch(branch: string | null | unde
|
|
|
36
41
|
/** Recognize first-party and provisioned staging environment names. */
|
|
37
42
|
export declare function isStagingEnvironment(environment: string | null | undefined): boolean;
|
|
38
43
|
/**
|
|
39
|
-
* Throw if provenance is not eligible for an official (active) deploy
|
|
40
|
-
* Preview callers must not
|
|
44
|
+
* Throw if provenance is not eligible for an official (active) deploy to the
|
|
45
|
+
* deployment named by `provenance.environment`. Preview callers must not
|
|
46
|
+
* invoke this.
|
|
41
47
|
*/
|
|
42
48
|
export declare function assertActiveDeployProvenance(provenance: ActiveDeployProvenance): void;
|
|
49
|
+
/**
|
|
50
|
+
* The CLI's check before it builds or uploads. Only Atlas knows whether the
|
|
51
|
+
* target deployment is a staging environment, so this admits `staging` and
|
|
52
|
+
* leaves that decision to Atlas, which repeats the full check with its own
|
|
53
|
+
* environment.
|
|
54
|
+
*/
|
|
55
|
+
export declare function assertActiveDeploySourceBeforeUpload(provenance: Omit<ActiveDeployProvenance, 'environment'>): void;
|
|
@@ -44,11 +44,31 @@ export function isStagingEnvironment(environment) {
|
|
|
44
44
|
const normalized = environment?.trim().toLowerCase();
|
|
45
45
|
return normalized === 'staging' || normalized?.endsWith('_staging') === true || normalized?.endsWith('-staging') === true;
|
|
46
46
|
}
|
|
47
|
+
/** The preview deploy an official-deploy refusal points at. */
|
|
48
|
+
function previewHint(ref) {
|
|
49
|
+
return `Deploy it as a preview instead: \`seq-studio artifact deploy --repo <ns>/<name> --ref ${ref} --preview\``;
|
|
50
|
+
}
|
|
47
51
|
/**
|
|
48
|
-
* Throw if provenance is not eligible for an official (active) deploy
|
|
49
|
-
* Preview callers must not
|
|
52
|
+
* Throw if provenance is not eligible for an official (active) deploy to the
|
|
53
|
+
* deployment named by `provenance.environment`. Preview callers must not
|
|
54
|
+
* invoke this.
|
|
50
55
|
*/
|
|
51
56
|
export function assertActiveDeployProvenance(provenance) {
|
|
57
|
+
assertOfficialSource({
|
|
58
|
+
provenance,
|
|
59
|
+
target: { staging: isStagingEnvironment(provenance.environment), environment: provenance.environment },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The CLI's check before it builds or uploads. Only Atlas knows whether the
|
|
64
|
+
* target deployment is a staging environment, so this admits `staging` and
|
|
65
|
+
* leaves that decision to Atlas, which repeats the full check with its own
|
|
66
|
+
* environment.
|
|
67
|
+
*/
|
|
68
|
+
export function assertActiveDeploySourceBeforeUpload(provenance) {
|
|
69
|
+
assertOfficialSource({ provenance, target: { staging: 'decided-by-atlas' } });
|
|
70
|
+
}
|
|
71
|
+
function assertOfficialSource({ provenance, target }) {
|
|
52
72
|
// Require an explicit clean source-directory recording — omitting gitDirty
|
|
53
73
|
// must not pass. The local source resolver scopes this value to the
|
|
54
74
|
// artifact directory, so unrelated changes elsewhere in a containing
|
|
@@ -66,12 +86,16 @@ export function assertActiveDeployProvenance(provenance) {
|
|
|
66
86
|
'`seq-studio artifact deploy --repo <ns>/<slug>` (defaults to the repo default branch). ' +
|
|
67
87
|
'Feature branches and detached HEAD (unless at the tip of `main`) are preview-only.');
|
|
68
88
|
}
|
|
69
|
-
|
|
70
|
-
|
|
89
|
+
if (branch === ACTIVE_DEPLOY_STAGING_BRANCH && target.staging === false) {
|
|
90
|
+
const environment = target.environment?.trim();
|
|
91
|
+
throw new ActiveDeployPolicyError(`The \`${ACTIVE_DEPLOY_STAGING_BRANCH}\` branch deploys officially only to a staging deployment, ` +
|
|
92
|
+
`and this deployment${environment ? ` (\`${environment}\`)` : ''} is not one. ` +
|
|
93
|
+
`Deploy \`${ACTIVE_DEPLOY_DEFAULT_BRANCH}\` here. ${previewHint(branch)}`);
|
|
94
|
+
}
|
|
95
|
+
if (branch !== ACTIVE_DEPLOY_DEFAULT_BRANCH && branch !== ACTIVE_DEPLOY_STAGING_BRANCH) {
|
|
71
96
|
throw new ActiveDeployPolicyError(`Active (official) artifact deploys must use \`${ACTIVE_DEPLOY_DEFAULT_BRANCH}\` ` +
|
|
72
|
-
`or \`${ACTIVE_DEPLOY_STAGING_BRANCH}\`
|
|
73
|
-
`
|
|
74
|
-
'use a preview channel for feature-branch or dirty local work.');
|
|
97
|
+
`(or \`${ACTIVE_DEPLOY_STAGING_BRANCH}\` on a staging deployment); got branch/ref \`${branch}\`. ` +
|
|
98
|
+
`Merge it via a Pull, then redeploy from \`${ACTIVE_DEPLOY_DEFAULT_BRANCH}\`. ${previewHint(branch)}`);
|
|
75
99
|
}
|
|
76
100
|
if (!provenance.gitCommit?.trim()) {
|
|
77
101
|
throw new ActiveDeployPolicyError('Active (official) artifact deploys require a resolved git commit on `main` ' +
|
package/dist/build.js
CHANGED
|
@@ -83,6 +83,12 @@ function createPeerResolveAlias({ atlasUiPackageDir = atlasUiDir } = {}) {
|
|
|
83
83
|
'@tanstack/react-query': reactQueryDir,
|
|
84
84
|
'react-router-dom': reactRouterDomDir,
|
|
85
85
|
sonner: sonnerDir,
|
|
86
|
+
// The CLI pins the shared SDK just as it pins ORM/Storage. Explicit subpaths
|
|
87
|
+
// precede the package root because Vite aliases also match prefixes.
|
|
88
|
+
'@sequenceholdings/platform/browser': cliRequire.resolve('@sequenceholdings/platform/browser'),
|
|
89
|
+
'@sequenceholdings/platform/contracts': cliRequire.resolve('@sequenceholdings/platform/contracts'),
|
|
90
|
+
'@sequenceholdings/platform/storage': cliRequire.resolve('@sequenceholdings/platform/storage'),
|
|
91
|
+
'@sequenceholdings/platform': cliRequire.resolve('@sequenceholdings/platform'),
|
|
86
92
|
'@sequenceholdings/storage': cliRequire.resolve('@sequenceholdings/storage'),
|
|
87
93
|
'@sequenceholdings/orm/client': cliRequire.resolve('@sequenceholdings/orm/client'),
|
|
88
94
|
'@sequenceholdings/artifact-studio/offline': offlineRuntimeEntry,
|
package/dist/cli.js
CHANGED
|
@@ -16,11 +16,12 @@ import { acquireDevLock } from './dev-lock.js';
|
|
|
16
16
|
import { runWatchLoop } from './watch-loop.js';
|
|
17
17
|
import { hashLinkedSources, hasLinkedAtlasUiToolchain, parseLinks, rebuildLinkedDep, resolveLinkedDeps, syncLinkedDist, } from './dev-link.js';
|
|
18
18
|
import { lintArtifactSandbox, reportSandboxWarnings } from './sandbox-lint.js';
|
|
19
|
-
import {
|
|
19
|
+
import { assertActiveDeploySourceBeforeUpload } from './active-deploy-policy.js';
|
|
20
20
|
import { assertArtifactEnvironmentBindings } from './artifact-env-bindings.js';
|
|
21
21
|
import { normalizeArtifactPath } from './paths.js';
|
|
22
22
|
import yaml from 'js-yaml';
|
|
23
23
|
import { warnOnRoleDefinitions } from './role-definitions-notice.js';
|
|
24
|
+
import { branchPreviewKey } from './preview-key.js';
|
|
24
25
|
const COMMANDS = [
|
|
25
26
|
'init', 'whoami', 'link', 'env', 'status', 'list', 'show',
|
|
26
27
|
'content-readers', 'validate', 'build', 'plan', 'deploy', 'dev', 'promote', 'pull', 'rollback',
|
|
@@ -37,6 +38,7 @@ const USAGE = `usage:
|
|
|
37
38
|
seq-studio artifact build [dir | --repo <ns>/<name> | --git-url <url>] [--ref <ref>] [--path <dir>] [--source-env <env>] [--out dist/artifact-bundle.json]
|
|
38
39
|
seq-studio artifact plan [dir | --repo <ns>/<name> | --git-url <url>] [--ref <ref>] [--path <dir>] [--source-env <env>] --env <env>
|
|
39
40
|
seq-studio artifact deploy [dir | --repo <ns>/<name> | --git-url <url>] [--ref <ref>] [--path <dir>] [--source-env <env>] --env <env> [--skip-unchanged] [--no-create] [--project <id>]
|
|
41
|
+
seq-studio artifact deploy --repo <ns>/<name> --ref <branch> --preview [--key <key>] --env <env>
|
|
40
42
|
seq-studio artifact dev [dir] --env <env> [--once] [--key default] [--link <pkgDir>[,<pkgDir>]] [--port <port>]
|
|
41
43
|
seq-studio artifact promote <deployment-id> --env <env>
|
|
42
44
|
seq-studio artifact pull <project-id> --env <env> --out <dir>
|
|
@@ -60,6 +62,15 @@ const USAGE = `usage:
|
|
|
60
62
|
trees; feature branches and dirty source trees remain preview-only for
|
|
61
63
|
deployed environments (\`artifact dev\` / preview channel).
|
|
62
64
|
|
|
65
|
+
A preview is a private test copy of the app. deploy --preview builds any
|
|
66
|
+
branch, tag, or commit and prints a link that opens it inside Atlas for people
|
|
67
|
+
who can edit the project; the live app and its users are unaffected. For a
|
|
68
|
+
static app each --key (default: the --ref name, else "default") keeps one
|
|
69
|
+
preview, replaced by the next deploy with that key. Each Next.js preview is
|
|
70
|
+
its own immutable build with its own link, so --key does not apply. A
|
|
71
|
+
preview is never promoted: merge the branch and deploy main (or staging) to
|
|
72
|
+
go live.
|
|
73
|
+
|
|
63
74
|
Interactive --repo builds clone over smart-HTTP using your seq-studio login
|
|
64
75
|
and repository read access. No PAT is needed. Headless M2M builds use JSON
|
|
65
76
|
materialize and accept only platform-managed --repo sources. Use --env to
|
|
@@ -127,7 +138,7 @@ function validateKnownOptions(args) {
|
|
|
127
138
|
show: { values: ['env'], booleans: ['json'] }, validate: { values: [], booleans: [] },
|
|
128
139
|
build: { values: ['source-env', 'env', 'repo', 'git-url', 'ref', 'path', 'out'], booleans: [] },
|
|
129
140
|
plan: { values: ['source-env', 'env', 'repo', 'git-url', 'ref', 'path'], booleans: [] },
|
|
130
|
-
deploy: { values: ['source-env', 'env', 'repo', 'git-url', 'ref', 'path', 'project', 'out'], booleans: ['skip-unchanged', 'no-create'] },
|
|
141
|
+
deploy: { values: ['source-env', 'env', 'repo', 'git-url', 'ref', 'path', 'project', 'out', 'key'], booleans: ['skip-unchanged', 'no-create', 'preview'] },
|
|
131
142
|
dev: { values: ['env', 'key', 'link', 'port'], booleans: ['once'] },
|
|
132
143
|
promote: { values: ['env'], booleans: [] }, pull: { values: ['env', 'out'], booleans: [] },
|
|
133
144
|
rollback: { values: ['env'], booleans: [] },
|
|
@@ -565,6 +576,7 @@ async function planCommand(args) {
|
|
|
565
576
|
}
|
|
566
577
|
}
|
|
567
578
|
async function deployCommand(args) {
|
|
579
|
+
const preview = isPreviewDeploy(args);
|
|
568
580
|
const env = await envFromArgs(args);
|
|
569
581
|
const auth = await getRequiredAuth(args);
|
|
570
582
|
const { token } = auth;
|
|
@@ -580,16 +592,19 @@ async function deployCommand(args) {
|
|
|
580
592
|
try {
|
|
581
593
|
// Fail closed before build / project create for deployed environments.
|
|
582
594
|
// Local Atlas is a developer's own target, so it intentionally accepts
|
|
583
|
-
// the current branch and dirty working tree.
|
|
584
|
-
if (env.name !== 'local') {
|
|
585
|
-
|
|
595
|
+
// the current branch and dirty working tree. A preview accepts any ref.
|
|
596
|
+
if (env.name !== 'local' && !preview) {
|
|
597
|
+
assertActiveDeploySourceBeforeUpload(source.provenance);
|
|
586
598
|
}
|
|
587
599
|
const manifest = await readArtifactStudioManifest(source.dir);
|
|
588
600
|
// After source resolution, so --repo / --git-url deploys check the fetched manifest.
|
|
589
601
|
warnOnRoleDefinitions(manifest);
|
|
590
602
|
await assertArtifactEnvironmentBindings({ directory: source.dir, environment: env, token });
|
|
591
603
|
if (isNextArtifactManifest(manifest)) {
|
|
592
|
-
|
|
604
|
+
if (preview && args.flags.key !== undefined) {
|
|
605
|
+
throw new Error('--key names a static preview. Each Next.js preview is its own immutable build with its own link; omit --key.');
|
|
606
|
+
}
|
|
607
|
+
return await buildNextCommand({ args, source, active: !preview });
|
|
593
608
|
}
|
|
594
609
|
assertSourceEnvironmentSupportsManifest(args);
|
|
595
610
|
// --skip-unchanged: hash the raw source (no build needed) and no-op when
|
|
@@ -631,6 +646,8 @@ async function deployCommand(args) {
|
|
|
631
646
|
allowCreate: args.flags['no-create'] !== true,
|
|
632
647
|
explicitProjectId,
|
|
633
648
|
});
|
|
649
|
+
if (preview)
|
|
650
|
+
return await uploadPreview({ args, envUrl: env.url, token, project, result, provenance: source.provenance });
|
|
634
651
|
const deployment = await uploadDeployment({ env: env.url, token, projectId: project.id, result, channel: 'active', provenance: source.provenance });
|
|
635
652
|
console.log(`[seq-studio] deployed ${project.title} ${deployment.version}`);
|
|
636
653
|
console.log(`${env.url}/artifact-studio/projects/${project.id}/deployments/${deployment.id}`);
|
|
@@ -640,6 +657,25 @@ async function deployCommand(args) {
|
|
|
640
657
|
await source.cleanup();
|
|
641
658
|
}
|
|
642
659
|
}
|
|
660
|
+
/** `deploy --preview`: any ref, never the live app. --key belongs to it, --skip-unchanged does not. */
|
|
661
|
+
function isPreviewDeploy(args) {
|
|
662
|
+
const preview = args.flags.preview === true;
|
|
663
|
+
if (!preview && args.flags.key !== undefined)
|
|
664
|
+
throw new Error('--key names a preview; add --preview, or omit --key for an official deploy.');
|
|
665
|
+
if (preview && args.flags['skip-unchanged'] === true)
|
|
666
|
+
throw new Error('--skip-unchanged compares against the official deployment; it does not apply to --preview.');
|
|
667
|
+
return preview;
|
|
668
|
+
}
|
|
669
|
+
async function uploadPreview({ args, envUrl, token, project, result, provenance }) {
|
|
670
|
+
const previewKey = branchPreviewKey({ key: args.flags.key, ref: args.flags.ref });
|
|
671
|
+
const deployment = await uploadDeployment({
|
|
672
|
+
env: envUrl, token, projectId: project.id, result, channel: 'preview', previewKey, provenance,
|
|
673
|
+
message: `Preview of ${provenance.gitBranch ?? provenance.gitCommit?.slice(0, 12) ?? 'local source'}`,
|
|
674
|
+
});
|
|
675
|
+
console.log(`[seq-studio] preview ${deployment.version} of ${project.title} (key ${previewKey}); the live app is unchanged`);
|
|
676
|
+
console.log(`${envUrl}/artifact-studio/projects/${project.id}/preview?key=${encodeURIComponent(previewKey)}`);
|
|
677
|
+
return 0;
|
|
678
|
+
}
|
|
643
679
|
async function buildNextCommand({ args, source, active }) {
|
|
644
680
|
const env = await envFromArgs(args);
|
|
645
681
|
const token = await getRequiredToken(args);
|
|
@@ -650,7 +686,7 @@ async function buildNextCommand({ args, source, active }) {
|
|
|
650
686
|
const spec = parseSourceSpec(args);
|
|
651
687
|
const repository = nextSourceRepository({ spec, root: source.dir });
|
|
652
688
|
if (active) {
|
|
653
|
-
|
|
689
|
+
assertActiveDeploySourceBeforeUpload(source.provenance);
|
|
654
690
|
}
|
|
655
691
|
const sourceEnvironment = sourceEnvironmentFromArgs(args);
|
|
656
692
|
const sourceToken = sourceEnvironment ? (await getSourceAuth(args)).token : token;
|
|
@@ -77,6 +77,11 @@ export declare const artifactStudioStaticManifestSchema: z.ZodObject<{
|
|
|
77
77
|
functions: z.ZodDefault<z.ZodObject<{
|
|
78
78
|
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
79
79
|
}, z.core.$strip>>;
|
|
80
|
+
processes: z.ZodDefault<z.ZodObject<{
|
|
81
|
+
start: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
82
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
83
|
+
act: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
84
|
+
}, z.core.$strip>>;
|
|
80
85
|
allow_downloads: z.ZodDefault<z.ZodBoolean>;
|
|
81
86
|
allow_popups: z.ZodDefault<z.ZodBoolean>;
|
|
82
87
|
roles: z.ZodOptional<z.ZodObject<{
|
package/dist/manifest-static.js
CHANGED
|
@@ -3,6 +3,7 @@ import { ontologyContractSchema } from '@sequenceholdings/orm/canonical';
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { capabilityPinsSchema, customRolesBlockSchema, validateCapabilityPins, } from './manifest-custom-roles.js';
|
|
5
5
|
import { normalizeArtifactPath } from './paths.js';
|
|
6
|
+
import { latticeProcessRef } from './manifest-next-reach.js';
|
|
6
7
|
export { CUSTOM_CAPABILITY_PIN_RE, CUSTOM_ROLE_KEY_RE, capabilityPinsSchema, customRolesBlockSchema, customRolesDeclared, parseCapabilityPin, validateCapabilityPins, } from './manifest-custom-roles.js';
|
|
7
8
|
const apiCapabilityPathSchema = z.string().min(1).refine((path) => path.startsWith('/api/') && path !== '/api/' && path !== '/api/*', 'API capability paths must be scoped below /api/');
|
|
8
9
|
const apiCapabilitiesSchema = z.object({
|
|
@@ -91,6 +92,18 @@ export const artifactStudioStaticManifestSchema = z.object({
|
|
|
91
92
|
functions: z.object({
|
|
92
93
|
invoke: z.array(z.string().min(1)).default([]),
|
|
93
94
|
}).default({ invoke: [] }),
|
|
95
|
+
/**
|
|
96
|
+
* Lattice processes `createArtifactProcesses()` may reach, as in a Next.js
|
|
97
|
+
* manifest: `start` runs of, `read` runs, templates and the user's own steps
|
|
98
|
+
* of, and `act` on (complete or reassign human steps, cancel, share runs).
|
|
99
|
+
* Exact process ids; Atlas checks them against the deployed manifest, then
|
|
100
|
+
* the user's own Invoker / Viewer / Advancer / Owner grants decide.
|
|
101
|
+
*/
|
|
102
|
+
processes: z.object({
|
|
103
|
+
start: z.array(latticeProcessRef).max(256).default([]),
|
|
104
|
+
read: z.array(latticeProcessRef).max(256).default([]),
|
|
105
|
+
act: z.array(latticeProcessRef).max(256).default([]),
|
|
106
|
+
}).default({ start: [], read: [], act: [] }),
|
|
94
107
|
/** Opt-in: enables iframe `allow-downloads`. Default false. */
|
|
95
108
|
allow_downloads: z.boolean().default(false),
|
|
96
109
|
/**
|
|
@@ -117,6 +130,7 @@ export const artifactStudioStaticManifestSchema = z.object({
|
|
|
117
130
|
data: { read: [], write: [] },
|
|
118
131
|
api: { read: [], write: [] },
|
|
119
132
|
functions: { invoke: [] },
|
|
133
|
+
processes: { start: [], read: [], act: [] },
|
|
120
134
|
allow_downloads: false,
|
|
121
135
|
allow_popups: false,
|
|
122
136
|
uses: [],
|
package/dist/manifest.d.ts
CHANGED
|
@@ -48,6 +48,11 @@ export declare const artifactStudioManifestSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
48
48
|
functions: z.ZodDefault<z.ZodObject<{
|
|
49
49
|
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
50
50
|
}, z.core.$strip>>;
|
|
51
|
+
processes: z.ZodDefault<z.ZodObject<{
|
|
52
|
+
start: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
53
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
54
|
+
act: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
55
|
+
}, z.core.$strip>>;
|
|
51
56
|
allow_downloads: z.ZodDefault<z.ZodBoolean>;
|
|
52
57
|
allow_popups: z.ZodDefault<z.ZodBoolean>;
|
|
53
58
|
roles: z.ZodOptional<z.ZodObject<{
|