@sequenceholdings/artifact-studio 0.8.1 → 0.9.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 CHANGED
@@ -500,3 +500,17 @@ streaming and file-transfer helpers retain their ordinary host tracing behavior.
500
500
  Tracing does not grant permissions, change service-account behavior or guarantee
501
501
  that every transport is instrumented. Traces availability depends on the deployed
502
502
  platform version and your app/resource permissions.
503
+
504
+
505
+ ### Microphone dictation in an isolated application
506
+
507
+ Explicitly declare browser API read `/api/files/speech/config/get` and write
508
+ `/api/files/speech/stt` to opt an isolated application iframe into microphone
509
+ requests. Both exact paths are required; broad API wildcards do not enable it.
510
+ The browser still asks the user for permission. Existing sandbox origin privileges
511
+ are unchanged, and camera/geolocation remain unavailable. Legacy opaque-origin
512
+ static frames do not receive microphone delegation.
513
+ Upload with `api.upload` option `{ fieldName: 'audio' }`; ordinary uploads still
514
+ default to `file`. Atlas transcription trims silence by default; multipart
515
+ `trimSilence=false` opts out. Speech uses the declared host paths without requiring
516
+ the separate general Next host API rollout flag.
package/dist/api.d.ts CHANGED
@@ -12,11 +12,12 @@ export declare function getJson<T>({ baseUrl, token, path }: ApiClientOptions &
12
12
  export declare function getJsonOr404<T>({ baseUrl, token, path }: ApiClientOptions & {
13
13
  path: string;
14
14
  }): Promise<T | null>;
15
- export declare function postJson<T>({ baseUrl, token, path, body, retry503, signal, }: ApiClientOptions & {
15
+ export declare function postJson<T>({ baseUrl, token, path, body, retry503, signal, headers, }: ApiClientOptions & {
16
16
  path: string;
17
17
  body?: unknown;
18
18
  retry503?: boolean;
19
19
  signal?: AbortSignal;
20
+ headers?: Record<string, string>;
20
21
  }): Promise<T>;
21
22
  export declare function deleteJson({ baseUrl, token, path, signal }: ApiClientOptions & {
22
23
  path: string;
package/dist/api.js CHANGED
@@ -19,7 +19,17 @@ const DEFAULT_RETRY_AFTER_SECONDS = 2;
19
19
  * Content-Type) always win over anything here. Malformed JSON is ignored — a
20
20
  * bad bypass header should never crash a deploy before the request is even made.
21
21
  */
22
- function extraHeaders() {
22
+ function extraHeaders(baseUrl) {
23
+ // Preview gateway credentials belong only to the target, never to a separately
24
+ // authenticated source repository. An unbound header set fails closed.
25
+ const target = process.env.ARTIFACT_STUDIO_BASE_URL;
26
+ try {
27
+ if (!target || new URL(target).origin !== new URL(baseUrl).origin)
28
+ return {};
29
+ }
30
+ catch {
31
+ return {};
32
+ }
23
33
  const raw = process.env.ARTIFACT_STUDIO_EXTRA_HEADERS?.trim();
24
34
  if (!raw)
25
35
  return {};
@@ -33,7 +43,7 @@ function extraHeaders() {
33
43
  // Prevent case-variant duplicates from being merged by Headers/fetch
34
44
  // (e.g. `authorization` + `Authorization` => "a, b"). The client always
35
45
  // sets these explicitly below, so ignore any env-supplied variants.
36
- if (lower === 'authorization' || lower === 'content-type')
46
+ if (lower === 'authorization' || lower === 'content-type' || lower === 'x-sequence-source-authorization')
37
47
  continue;
38
48
  if (typeof value === 'string')
39
49
  headers[key] = value;
@@ -64,7 +74,7 @@ async function authenticatedFetch({ baseUrl, init = {}, path, token, retry503 =
64
74
  ...init,
65
75
  redirect: 'manual',
66
76
  headers: {
67
- ...extraHeaders(),
77
+ ...extraHeaders(baseUrl),
68
78
  ...init.headers,
69
79
  Authorization: `Bearer ${token}`,
70
80
  },
@@ -84,7 +94,7 @@ export async function getJsonOr404({ baseUrl, token, path }) {
84
94
  throw new ArtifactApiError(await responseError('GET', path, response), response.status);
85
95
  return response.json();
86
96
  }
87
- export async function postJson({ baseUrl, token, path, body, retry503 = true, signal, }) {
97
+ export async function postJson({ baseUrl, token, path, body, retry503 = true, signal, headers, }) {
88
98
  const response = await authenticatedFetch({
89
99
  baseUrl,
90
100
  token,
@@ -92,7 +102,7 @@ export async function postJson({ baseUrl, token, path, body, retry503 = true, si
92
102
  retry503,
93
103
  init: {
94
104
  method: 'POST',
95
- headers: { 'Content-Type': 'application/json' },
105
+ headers: { ...headers, 'Content-Type': 'application/json' },
96
106
  body: body === undefined ? undefined : JSON.stringify(body),
97
107
  ...(signal ? { signal } : {}),
98
108
  },
package/dist/cli.d.ts CHANGED
@@ -32,6 +32,8 @@ export declare function getConfiguredDefaultEnv(): Promise<string | undefined>;
32
32
  */
33
33
  export interface TokenProviderOptions {
34
34
  allowInteractiveLogin: boolean;
35
+ /** A separate source session; omitted for target requests. Never a caller URL. */
36
+ sourceEnvironment?: string;
35
37
  }
36
38
  export interface ProvidedToken {
37
39
  authMode: SourceAuthMode;
package/dist/cli.js CHANGED
@@ -3,7 +3,7 @@ import { constants, existsSync } from 'node:fs';
3
3
  import { dirname, join, relative, resolve } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import { getJson, getJsonOr404, postJson } from './api.js';
6
- import { ENV_URLS, readLocalConfig, resolveEnvironment, writeLocalConfig, } from './config.js';
6
+ import { ENV_URLS, knownEnvUrls, readLocalConfig, resolveEnvironment, writeLocalConfig, } from './config.js';
7
7
  import { writeBuildArtifact } from './build.js';
8
8
  import { buildArtifactStudioProjectIsolated } from './build-subprocess.js';
9
9
  import { resolveArtifactStudioPeerVersions, } from './peer-versions.js';
@@ -33,9 +33,9 @@ const USAGE = `usage:
33
33
  seq-studio artifact list --env <env> [--json]
34
34
  seq-studio artifact show <slug-or-id> --env <env> [--json]
35
35
  seq-studio artifact validate [dir]
36
- seq-studio artifact build [dir | --repo <ns>/<name> | --git-url <url>] [--ref <ref>] [--path <dir>] [--out dist/artifact-bundle.json]
37
- seq-studio artifact plan [dir | --repo <ns>/<name> | --git-url <url>] [--ref <ref>] [--path <dir>] --env <env>
38
- seq-studio artifact deploy [dir | --repo <ns>/<name> | --git-url <url>] [--ref <ref>] [--path <dir>] --env <env> [--skip-unchanged] [--no-create] [--project <id>]
36
+ seq-studio artifact build [dir | --repo <ns>/<name> | --git-url <url>] [--ref <ref>] [--path <dir>] [--source-env <env>] [--out dist/artifact-bundle.json]
37
+ seq-studio artifact plan [dir | --repo <ns>/<name> | --git-url <url>] [--ref <ref>] [--path <dir>] [--source-env <env>] --env <env>
38
+ 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>]
39
39
  seq-studio artifact dev [dir] --env <env> [--once] [--key default] [--link <pkgDir>[,<pkgDir>]] [--port <port>]
40
40
  seq-studio artifact promote <deployment-id> --env <env>
41
41
  seq-studio artifact pull <project-id> --env <env> --out <dir>
@@ -51,7 +51,7 @@ const USAGE = `usage:
51
51
  --repo / --git-url repository (default: its root). The target project comes from
52
52
  the source's artifact.bundle.yml project_id.
53
53
 
54
- Official (active) deploys to deployed environments require \`main\` with a
54
+ Official (active) deploys require \`main\` (or \`staging\` for staging targets) with a
55
55
  resolved git commit and a clean artifact source directory. Dirty files
56
56
  outside a nested local source directory are ignored with a warning.
57
57
  Deployments targeting \`local\` may use any branch, including dirty working
@@ -61,7 +61,11 @@ const USAGE = `usage:
61
61
  Interactive --repo builds clone over smart-HTTP using your seq-studio login
62
62
  and repository read access. No PAT is needed. Headless M2M builds use JSON
63
63
  materialize and accept only platform-managed --repo sources. Use --env to
64
- select the same environment for source and deployment.
64
+ select the target environment. Next.js build/plan/deploy accept --source-env
65
+ to read a Git Service repository from a separately authenticated environment.
66
+ Log in to both environments; source read and target deploy permissions apply.
67
+ The target must support verified cross-environment builds. Source credentials
68
+ are used only to fetch source, never passed to the build or stored with it.
65
69
 
66
70
  Next.js: init --template nextjs, then pnpm install with Node.js 24. dev starts
67
71
  a local Next server and an owner-only Atlas preview tunnel (no cloud credentials).
@@ -114,9 +118,9 @@ function validateKnownOptions(args) {
114
118
  link: { values: ['env', 'project'], booleans: [] }, env: { values: [], booleans: [] },
115
119
  status: { values: ['env'], booleans: [] }, list: { values: ['env'], booleans: ['json'] },
116
120
  show: { values: ['env'], booleans: ['json'] }, validate: { values: [], booleans: [] },
117
- build: { values: ['env', 'repo', 'git-url', 'ref', 'path', 'out'], booleans: [] },
118
- plan: { values: ['env', 'repo', 'git-url', 'ref', 'path'], booleans: [] },
119
- deploy: { values: ['env', 'repo', 'git-url', 'ref', 'path', 'project', 'out'], booleans: ['skip-unchanged', 'no-create'] },
121
+ build: { values: ['source-env', 'env', 'repo', 'git-url', 'ref', 'path', 'out'], booleans: [] },
122
+ plan: { values: ['source-env', 'env', 'repo', 'git-url', 'ref', 'path'], booleans: [] },
123
+ deploy: { values: ['source-env', 'env', 'repo', 'git-url', 'ref', 'path', 'project', 'out'], booleans: ['skip-unchanged', 'no-create'] },
120
124
  dev: { values: ['env', 'key', 'link', 'port'], booleans: ['once'] },
121
125
  promote: { values: ['env'], booleans: [] }, pull: { values: ['env', 'out'], booleans: [] },
122
126
  rollback: { values: ['env'], booleans: [] },
@@ -441,16 +445,17 @@ function reportBuildDiagnostics(result) {
441
445
  }
442
446
  async function buildCommand(args) {
443
447
  const spec = parseSourceSpec(args);
448
+ const sourceEnvironment = sourceEnvironmentFromArgs(args);
444
449
  // Local builds stay offline. Public git URLs need no bearer token, but an
445
450
  // optional auth lookup still identifies a selected M2M principal so the
446
451
  // source policy can reject arbitrary CI input before cloning.
447
- const auth = spec.kind === 'git-service'
448
- ? await getRequiredAuth(args)
452
+ const auth = spec.kind === 'git-service' || sourceEnvironment
453
+ ? await getSourceAuth(args)
449
454
  : spec.kind === 'git-url'
450
455
  ? await getOptionalAuth(args)
451
456
  : null;
452
457
  const remote = spec.kind === 'git-service' && auth
453
- ? { authMode: auth.authMode, baseUrl: (await envFromArgs(args)).url, token: auth.token }
458
+ ? { authMode: auth.authMode, baseUrl: (sourceEnvironment ?? await envFromArgs(args)).url, token: auth.token }
454
459
  : auth
455
460
  ? { authMode: auth.authMode }
456
461
  : {};
@@ -459,6 +464,7 @@ async function buildCommand(args) {
459
464
  if (isNextArtifactManifest(await readArtifactStudioManifest(source.dir))) {
460
465
  return await buildNextCommand({ args, source, active: false });
461
466
  }
467
+ assertSourceEnvironmentSupportsManifest(args);
462
468
  const result = await buildPreparedArtifactSource(source);
463
469
  reportBuildDiagnostics(result);
464
470
  // A remote source's dir is a temp dir we tear down below, so default the
@@ -483,10 +489,12 @@ async function planCommand(args) {
483
489
  const auth = await getOptionalAuth(args);
484
490
  const token = auth?.token ?? null;
485
491
  const spec = parseSourceSpec(args);
492
+ const sourceEnvironment = sourceEnvironmentFromArgs(args);
493
+ const sourceAuth = sourceEnvironment ? await getSourceAuth(args) : auth;
486
494
  const source = await resolveArtifactSource(spec, {
487
- ...(auth ? { authMode: auth.authMode } : {}),
488
- baseUrl: env.url,
489
- token,
495
+ ...(sourceAuth ? { authMode: sourceAuth.authMode } : {}),
496
+ baseUrl: (sourceEnvironment ?? env).url,
497
+ token: sourceAuth?.token ?? null,
490
498
  });
491
499
  try {
492
500
  const manifest = await readArtifactStudioManifest(source.dir);
@@ -494,6 +502,7 @@ async function planCommand(args) {
494
502
  const { planNextProject } = await import('./next-build.js');
495
503
  return await planNextProject({ root: source.dir, manifest, environment: env.name });
496
504
  }
505
+ assertSourceEnvironmentSupportsManifest(args);
497
506
  const result = await buildPreparedArtifactSource(source);
498
507
  reportBuildDiagnostics(result);
499
508
  console.log(`[seq-studio] plan ${result.manifest.artifact.project_id} -> ${env.name}`);
@@ -539,10 +548,12 @@ async function deployCommand(args) {
539
548
  const { token } = auth;
540
549
  const spec = parseSourceSpec(args);
541
550
  const explicitProjectId = typeof args.flags.project === 'string' ? args.flags.project : null;
551
+ const sourceEnvironment = sourceEnvironmentFromArgs(args);
552
+ const sourceAuth = sourceEnvironment ? await getSourceAuth(args) : auth;
542
553
  const source = await resolveArtifactSource(spec, {
543
- authMode: auth.authMode,
544
- baseUrl: env.url,
545
- token,
554
+ authMode: sourceAuth.authMode,
555
+ baseUrl: (sourceEnvironment ?? env).url,
556
+ token: sourceAuth.token,
546
557
  });
547
558
  try {
548
559
  // Fail closed before build / project create for deployed environments.
@@ -558,6 +569,7 @@ async function deployCommand(args) {
558
569
  if (isNextArtifactManifest(manifest)) {
559
570
  return await buildNextCommand({ args, source, active: true });
560
571
  }
572
+ assertSourceEnvironmentSupportsManifest(args);
561
573
  // --skip-unchanged: hash the raw source (no build needed) and no-op when
562
574
  // the remote active deployment already matches *and* was built with the
563
575
  // same CLI/atlas-ui pin. Lets CI redeploy every artifact on every release
@@ -618,8 +630,10 @@ async function buildNextCommand({ args, source, active }) {
618
630
  if (active) {
619
631
  assertActiveDeployProvenance({ ...source.provenance, environment: env.name });
620
632
  }
621
- const repositoryId = active || spec.kind === 'git-service'
622
- ? await resolveNextRepositoryId({ spec, repository, baseUrl: env.url, token })
633
+ const sourceEnvironment = sourceEnvironmentFromArgs(args);
634
+ const sourceToken = sourceEnvironment ? (await getSourceAuth(args)).token : token;
635
+ const repositoryId = active || spec.kind === 'git-service' || sourceEnvironment
636
+ ? await resolveNextRepositoryId({ spec, repository, baseUrl: (sourceEnvironment ?? env).url, token: sourceToken })
623
637
  : undefined;
624
638
  const project = await ensureRemoteProject({
625
639
  env: env.url, token, result: { manifest }, linkConfigDir: spec.kind === 'local' ? source.dir : null,
@@ -632,6 +646,7 @@ async function buildNextCommand({ args, source, active }) {
632
646
  return submitNextBuild({
633
647
  root: source.dir, sourceRoot: source.sourceRoot, manifest, projectId: project.id, baseUrl: env.url,
634
648
  getToken: () => getRequiredToken(args), provenance: source.provenance, repository, repositoryId,
649
+ ...(sourceEnvironment ? { sourceEnvironment: sourceEnvironment.name, sourceToken } : {}),
635
650
  channel: active ? 'active' : 'preview', out: typeof args.flags.out === 'string' ? resolve(args.flags.out) : undefined,
636
651
  });
637
652
  }
@@ -1027,6 +1042,29 @@ export async function getConfiguredDefaultEnv() {
1027
1042
  async function envFromArgs(args) {
1028
1043
  return resolveEnvironment(typeof args.flags.env === 'string' ? args.flags.env : undefined, await getConfiguredDefaultEnv());
1029
1044
  }
1045
+ /** Source selection must never inherit the target URL override. */
1046
+ function sourceEnvironmentFromArgs(args) {
1047
+ const name = args.flags['source-env'];
1048
+ if (typeof name !== 'string')
1049
+ return undefined;
1050
+ const url = knownEnvUrls()[name];
1051
+ if (typeof url !== 'string' || !url)
1052
+ throw new Error(`Unknown source environment "${name}". Run seq-studio envs list and login to the source environment.`);
1053
+ return { name, url };
1054
+ }
1055
+ async function getSourceAuth(args) {
1056
+ const source = sourceEnvironmentFromArgs(args);
1057
+ if (!source)
1058
+ return getRequiredAuth(args);
1059
+ const auth = await resolveAuth({ allowInteractiveLogin: true, sourceEnvironment: source.name });
1060
+ if (!auth)
1061
+ throw new Error(`Authenticate to the source with seq-studio login -e ${source.name}.`);
1062
+ return auth;
1063
+ }
1064
+ function assertSourceEnvironmentSupportsManifest(args) {
1065
+ if (args.flags['source-env'])
1066
+ throw new Error('--source-env is supported for Next.js repository builds only.');
1067
+ }
1030
1068
  let tokenProvider = null;
1031
1069
  export function setTokenProvider(provider) {
1032
1070
  tokenProvider = provider;
@@ -15,7 +15,7 @@ export declare function resolveNextRepositoryId({ spec, repository, baseUrl, tok
15
15
  baseUrl: string;
16
16
  token: string;
17
17
  }): Promise<string>;
18
- export declare function submitNextBuild({ root, sourceRoot, manifest, projectId, baseUrl, getToken, provenance, repository, repositoryId, channel, out }: {
18
+ export declare function submitNextBuild({ root, sourceRoot, manifest, projectId, baseUrl, getToken, provenance, repository, repositoryId, sourceEnvironment, sourceToken, channel, out }: {
19
19
  root: string;
20
20
  sourceRoot: string;
21
21
  manifest: ArtifactStudioNextManifest;
@@ -25,6 +25,8 @@ export declare function submitNextBuild({ root, sourceRoot, manifest, projectId,
25
25
  provenance: SourceProvenance;
26
26
  repository: string;
27
27
  repositoryId?: string;
28
+ sourceEnvironment?: string;
29
+ sourceToken?: string;
28
30
  channel: 'active' | 'preview';
29
31
  out?: string;
30
32
  }): Promise<number>;
@@ -58,16 +58,16 @@ export async function resolveNextRepositoryId({ spec, repository, baseUrl, token
58
58
  return match[1];
59
59
  }
60
60
  catch { /* Opaque labels/SSH origins are valid preview provenance but cannot attest a release. */ }
61
- throw new Error('Official Next.js releases require a Git Service repository in this Atlas environment. Push the reviewed revision, then run artifact deploy --repo <namespace>/<name> --ref main --env <env> (or --ref staging for a staging environment).');
61
+ throw new Error('Official Next.js releases require a Git Service repository in the selected source environment. Use --source-env <env> when its repository lives in another environment. Push the reviewed revision, then run artifact deploy --repo <namespace>/<name> --ref main --env <env> (or --ref staging for a staging environment).');
62
62
  }
63
63
  /**
64
64
  * A verified repository build names a commit and the application's directory in it;
65
65
  * anything else uploads the committed source snapshot. The repository root is omitted
66
66
  * so the request stays valid for Atlas versions that predate `sourceRoot`.
67
67
  */
68
- function nextBuildRequestBody({ manifest, files, commit, provenance, repository, repositoryId, sourceRoot, channel }) {
68
+ function nextBuildRequestBody({ manifest, files, commit, provenance, repository, repositoryId, sourceEnvironment, sourceRoot, channel }) {
69
69
  if (repositoryId)
70
- return { repositoryId, commit, ...(sourceRoot === '.' ? {} : { sourceRoot }), idempotencyKey: randomUUID(), channel };
70
+ return { repositoryId, ...(sourceEnvironment ? { sourceEnvironment } : {}), commit, ...(sourceRoot === '.' ? {} : { sourceRoot }), idempotencyKey: randomUUID(), channel };
71
71
  return {
72
72
  manifest,
73
73
  files: files.map(({ path, content, encoding }) => ({ path, content, encoding: encoding ?? 'utf8' })),
@@ -75,7 +75,7 @@ function nextBuildRequestBody({ manifest, files, commit, provenance, repository,
75
75
  idempotencyKey: randomUUID(), channel,
76
76
  };
77
77
  }
78
- export async function submitNextBuild({ root, sourceRoot, manifest, projectId, baseUrl, getToken, provenance, repository, repositoryId, channel, out }) {
78
+ export async function submitNextBuild({ root, sourceRoot, manifest, projectId, baseUrl, getToken, provenance, repository, repositoryId, sourceEnvironment, sourceToken, channel, out }) {
79
79
  if (!provenance.gitCommit || !/^[a-f0-9]{40}$/i.test(provenance.gitCommit)) {
80
80
  throw new Error('Commit the application source before requesting a hosted build. Use artifact dev for uncommitted local development.');
81
81
  }
@@ -84,8 +84,12 @@ export async function submitNextBuild({ root, sourceRoot, manifest, projectId, b
84
84
  if (channel === 'active' && !repositoryId)
85
85
  throw new Error('An official release requires a verified Git Service repository.');
86
86
  const path = `/api/artifact-studio/projects/${encodeURIComponent(projectId)}/next`;
87
- const body = nextBuildRequestBody({ manifest, files: source.files, commit: provenance.gitCommit, provenance, repository, repositoryId, sourceRoot, channel });
88
- const response = operationSchema.parse(await postJson({ baseUrl, token: await getToken(), path: `${path}/builds${repositoryId ? '/from-repository' : ''}`, body }));
87
+ const body = nextBuildRequestBody({ manifest, files: source.files, commit: provenance.gitCommit, provenance, repository, repositoryId, sourceEnvironment, sourceRoot, channel });
88
+ if (sourceEnvironment && !sourceToken)
89
+ throw new Error('Cross-environment builds require a separately authenticated source session.');
90
+ const response = operationSchema.parse(await postJson({ baseUrl, token: await getToken(), path: `${path}/builds${repositoryId ? '/from-repository' : ''}`, body, ...(sourceEnvironment ? { headers: { 'x-sequence-source-authorization': `Bearer ${sourceToken}` } } : {}) }));
91
+ if (sourceEnvironment)
92
+ console.log(`[seq-studio] source: ${sourceEnvironment} / ${repository} -> target: ${baseUrl}`);
89
93
  const directory = repositoryId && sourceRoot !== '.' ? ` (${sourceRoot})` : '';
90
94
  console.log(`[seq-studio] Atlas build ${response.operation.id} (${channel}) from ${provenance.gitCommit.slice(0, 12)}${directory}`);
91
95
  console.log(`${baseUrl}/artifact-studio/projects/${projectId}`);
package/dist/sdk.d.ts CHANGED
@@ -44,6 +44,8 @@ export interface SequenceApiFetchResponse<TBody = unknown> {
44
44
  headers?: Record<string, string>;
45
45
  }
46
46
  export interface SequenceApiUploadOptions {
47
+ /** Multipart binary field name. Defaults to file. */
48
+ fieldName?: string;
47
49
  timeoutMs?: number;
48
50
  /**
49
51
  * HTTP method for the multipart request. Defaults to POST; PUT is allowed
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {},
12
12
  "devDependencies": {
13
- "@sequenceholdings/artifact-studio": "^0.8.0",
13
+ "@sequenceholdings/artifact-studio": "^0.9.0",
14
14
  "@sequenceholdings/atlas-ui": "^3.1.1",
15
15
  "@tailwindcss/postcss": "^4.2.2",
16
16
  "@tailwindcss/vite": "^4.2.2",
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "publishConfig": {
10
10
  "access": "public"
11
11
  },
12
- "version": "0.8.1",
12
+ "version": "0.9.0",
13
13
  "description": "SDK types and CLI library for building Artifact Studio apps. Driven via `seq-studio artifact <sub>` (@sequenceholdings/studio-cli), which runs the `./cli` runCli export.",
14
14
  "type": "module",
15
15
  "exports": {
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {},
12
12
  "devDependencies": {
13
- "@sequenceholdings/artifact-studio": "^0.8.0",
13
+ "@sequenceholdings/artifact-studio": "^0.9.0",
14
14
  "@sequenceholdings/atlas-ui": "^3.1.1",
15
15
  "@tailwindcss/postcss": "^4.2.2",
16
16
  "@tailwindcss/vite": "^4.2.2",