@sequenceholdings/artifact-studio 0.2.5 → 0.3.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.
Files changed (187) hide show
  1. package/README.md +35 -0
  2. package/VERSION-PIN.md +14 -3
  3. package/dist/api.d.ts +11 -1
  4. package/dist/api.js +26 -9
  5. package/dist/atlas-ui-css-plugin.d.ts +11 -7
  6. package/dist/atlas-ui-css-plugin.js +38 -10
  7. package/dist/build.d.ts +2 -2
  8. package/dist/build.js +14 -6
  9. package/dist/cli.d.ts +1 -1
  10. package/dist/cli.js +108 -37
  11. package/dist/dev-link.d.ts +1 -1
  12. package/dist/dev-link.js +2 -1
  13. package/dist/gateway/admission.d.ts +55 -0
  14. package/dist/gateway/admission.js +132 -0
  15. package/dist/gateway/control.d.ts +91 -0
  16. package/dist/gateway/control.js +113 -0
  17. package/dist/gateway/hosted-proxy.d.ts +36 -0
  18. package/dist/gateway/hosted-proxy.js +347 -0
  19. package/dist/gateway/release-admission.d.ts +23 -0
  20. package/dist/gateway/release-admission.js +259 -0
  21. package/dist/gateway/server.d.ts +29 -0
  22. package/dist/gateway/server.js +298 -0
  23. package/dist/gateway/session.d.ts +71 -0
  24. package/dist/gateway/session.js +143 -0
  25. package/dist/gateway/usage.d.ts +37 -0
  26. package/dist/gateway/usage.js +46 -0
  27. package/dist/gateway-main.d.ts +1 -0
  28. package/dist/gateway-main.js +84 -0
  29. package/dist/git-clone.d.ts +23 -1
  30. package/dist/git-clone.js +32 -15
  31. package/dist/manifest-next.d.ts +217 -0
  32. package/dist/manifest-next.js +120 -0
  33. package/dist/manifest-static.d.ts +76 -0
  34. package/dist/manifest-static.js +124 -0
  35. package/dist/manifest.d.ts +124 -19
  36. package/dist/manifest.js +12 -118
  37. package/dist/next/bridge.d.ts +47 -0
  38. package/dist/next/bridge.js +229 -0
  39. package/dist/next/browser-logs.d.ts +7 -0
  40. package/dist/next/browser-logs.js +51 -0
  41. package/dist/next/browser.d.ts +6 -0
  42. package/dist/next/browser.js +57 -0
  43. package/dist/next/protocol.d.ts +73 -0
  44. package/dist/next/protocol.js +56 -0
  45. package/dist/next/release.d.ts +15 -0
  46. package/dist/next/release.js +46 -0
  47. package/dist/next/requests.d.ts +15 -0
  48. package/dist/next/requests.js +59 -0
  49. package/dist/next/routes.d.ts +4 -0
  50. package/dist/next/routes.js +21 -0
  51. package/dist/next/streams.d.ts +16 -0
  52. package/dist/next/streams.js +132 -0
  53. package/dist/next/theme.d.ts +10 -0
  54. package/dist/next/theme.js +45 -0
  55. package/dist/next/transport.d.ts +15 -0
  56. package/dist/next/transport.js +13 -0
  57. package/dist/next-build.d.ts +29 -0
  58. package/dist/next-build.js +129 -0
  59. package/dist/next-cache/adapter-runtime.d.ts +51 -0
  60. package/dist/next-cache/adapter-runtime.js +73 -0
  61. package/dist/next-cache/component-handler.d.ts +3 -0
  62. package/dist/next-cache/component-handler.js +10 -0
  63. package/dist/next-cache/components.d.ts +20 -0
  64. package/dist/next-cache/components.js +113 -0
  65. package/dist/next-cache/config.d.ts +9 -0
  66. package/dist/next-cache/config.js +78 -0
  67. package/dist/next-cache/incremental-handler.d.ts +18 -0
  68. package/dist/next-cache/incremental-handler.js +17 -0
  69. package/dist/next-cache/incremental.d.ts +27 -0
  70. package/dist/next-cache/incremental.js +99 -0
  71. package/dist/next-cache/index.d.ts +18 -0
  72. package/dist/next-cache/index.js +16 -0
  73. package/dist/next-cache/memory-store.d.ts +27 -0
  74. package/dist/next-cache/memory-store.js +118 -0
  75. package/dist/next-cache/redis-scripts.d.ts +3 -0
  76. package/dist/next-cache/redis-scripts.js +85 -0
  77. package/dist/next-cache/redis-store.d.ts +18 -0
  78. package/dist/next-cache/redis-store.js +56 -0
  79. package/dist/next-cache/runtime.d.ts +29 -0
  80. package/dist/next-cache/runtime.js +63 -0
  81. package/dist/next-cache/serialization.d.ts +39 -0
  82. package/dist/next-cache/serialization.js +333 -0
  83. package/dist/next-cache/store.d.ts +54 -0
  84. package/dist/next-cache/store.js +45 -0
  85. package/dist/next-cache/valkey-transport.d.ts +52 -0
  86. package/dist/next-cache/valkey-transport.js +189 -0
  87. package/dist/next-dev-control.d.ts +48 -0
  88. package/dist/next-dev-control.js +63 -0
  89. package/dist/next-dev-process.d.ts +17 -0
  90. package/dist/next-dev-process.js +110 -0
  91. package/dist/next-dev.d.ts +12 -0
  92. package/dist/next-dev.js +267 -0
  93. package/dist/next-image-config.d.ts +9 -0
  94. package/dist/next-image-config.js +101 -0
  95. package/dist/next-project.d.ts +22 -0
  96. package/dist/next-project.js +64 -0
  97. package/dist/next-public-fonts-local.d.ts +7 -0
  98. package/dist/next-public-fonts-local.js +64 -0
  99. package/dist/next-public-fonts.d.ts +13 -0
  100. package/dist/next-public-fonts.js +49 -0
  101. package/dist/next-source-hash.d.ts +14 -0
  102. package/dist/next-source-hash.js +18 -0
  103. package/dist/next-source.d.ts +35 -0
  104. package/dist/next-source.js +155 -0
  105. package/dist/next.d.ts +9 -0
  106. package/dist/next.js +5 -0
  107. package/dist/project.d.ts +3 -0
  108. package/dist/project.js +9 -1
  109. package/dist/runtime-contracts.d.ts +229 -0
  110. package/dist/runtime-contracts.js +224 -0
  111. package/dist/sdk.d.ts +420 -1
  112. package/dist/sdk.js +35 -0
  113. package/dist/server/broker-contract.d.ts +68 -0
  114. package/dist/server/broker-contract.js +33 -0
  115. package/dist/server/client.d.ts +67 -0
  116. package/dist/server/client.js +159 -0
  117. package/dist/server/logger.d.ts +26 -0
  118. package/dist/server/logger.js +24 -0
  119. package/dist/server/release-forms.d.ts +13 -0
  120. package/dist/server/release-forms.js +124 -0
  121. package/dist/server/request-context.d.ts +74 -0
  122. package/dist/server/request-context.js +103 -0
  123. package/dist/server/runtime-config.d.ts +53 -0
  124. package/dist/server/runtime-config.js +64 -0
  125. package/dist/server.d.ts +8 -0
  126. package/dist/server.js +4 -0
  127. package/dist/templates/nextjs/.artifactignore +14 -0
  128. package/dist/templates/nextjs/README.md +151 -0
  129. package/dist/templates/nextjs/app/about/page.tsx +26 -0
  130. package/dist/templates/nextjs/app/actions.ts +18 -0
  131. package/dist/templates/nextjs/app/api/health/route.ts +6 -0
  132. package/dist/templates/nextjs/app/components/counter.tsx +19 -0
  133. package/dist/templates/nextjs/app/components/greeting-form.tsx +38 -0
  134. package/dist/templates/nextjs/app/globals.css +4 -0
  135. package/dist/templates/nextjs/app/layout.tsx +27 -0
  136. package/dist/templates/nextjs/app/page.tsx +51 -0
  137. package/dist/templates/nextjs/app/providers.tsx +107 -0
  138. package/dist/templates/nextjs/artifact.bundle.yml +55 -0
  139. package/dist/templates/nextjs/next.config.mjs +27 -0
  140. package/dist/templates/nextjs/package.json +32 -0
  141. package/dist/templates/nextjs/pnpm-workspace.yaml +8 -0
  142. package/dist/templates/nextjs/postcss.config.mjs +5 -0
  143. package/dist/templates/nextjs/tsconfig.json +20 -0
  144. package/dist/templates/react-vite/artifact.bundle.yml +0 -1
  145. package/dist/templates/react-vite/package.json +1 -1
  146. package/dist/tunnel/broker.d.ts +75 -0
  147. package/dist/tunnel/broker.js +451 -0
  148. package/dist/tunnel/client.d.ts +22 -0
  149. package/dist/tunnel/client.js +177 -0
  150. package/dist/tunnel/index.d.ts +6 -0
  151. package/dist/tunnel/index.js +4 -0
  152. package/dist/tunnel/io.d.ts +33 -0
  153. package/dist/tunnel/io.js +108 -0
  154. package/dist/tunnel/peer.d.ts +25 -0
  155. package/dist/tunnel/peer.js +147 -0
  156. package/dist/tunnel/protocol.d.ts +69 -0
  157. package/dist/tunnel/protocol.js +196 -0
  158. package/dist/tunnel/redis-ownership.d.ts +38 -0
  159. package/dist/tunnel/redis-ownership.js +100 -0
  160. package/dist/tunnel/redis-socket.d.ts +13 -0
  161. package/dist/tunnel/redis-socket.js +48 -0
  162. package/dist/tunnel/redis-types.d.ts +70 -0
  163. package/dist/tunnel/redis-types.js +9 -0
  164. package/dist/tunnel/redis.d.ts +53 -0
  165. package/dist/tunnel/redis.js +391 -0
  166. package/dist/tunnel/transport.d.ts +17 -0
  167. package/dist/tunnel/transport.js +1 -0
  168. package/package.json +68 -4
  169. package/templates/nextjs/.artifactignore +14 -0
  170. package/templates/nextjs/README.md +151 -0
  171. package/templates/nextjs/app/about/page.tsx +26 -0
  172. package/templates/nextjs/app/actions.ts +18 -0
  173. package/templates/nextjs/app/api/health/route.ts +6 -0
  174. package/templates/nextjs/app/components/counter.tsx +19 -0
  175. package/templates/nextjs/app/components/greeting-form.tsx +38 -0
  176. package/templates/nextjs/app/globals.css +4 -0
  177. package/templates/nextjs/app/layout.tsx +27 -0
  178. package/templates/nextjs/app/page.tsx +51 -0
  179. package/templates/nextjs/app/providers.tsx +107 -0
  180. package/templates/nextjs/artifact.bundle.yml +55 -0
  181. package/templates/nextjs/next.config.mjs +27 -0
  182. package/templates/nextjs/package.json +32 -0
  183. package/templates/nextjs/pnpm-workspace.yaml +8 -0
  184. package/templates/nextjs/postcss.config.mjs +5 -0
  185. package/templates/nextjs/tsconfig.json +20 -0
  186. package/templates/react-vite/artifact.bundle.yml +0 -1
  187. package/templates/react-vite/package.json +1 -1
@@ -0,0 +1,35 @@
1
+ export interface NextSourceLimits {
2
+ maxFiles: number;
3
+ maxFileBytes: number;
4
+ maxTotalBytes: number;
5
+ }
6
+ export declare const NEXT_SOURCE_LIMITS: Readonly<NextSourceLimits>;
7
+ export interface NextSourceFile {
8
+ path: string;
9
+ content: string;
10
+ encoding: 'base64';
11
+ contentType: string;
12
+ sha256: string;
13
+ sizeBytes: number;
14
+ }
15
+ export interface NextSourceSnapshot<Manifest, Provenance = never> {
16
+ root: string;
17
+ manifest: Manifest;
18
+ files: NextSourceFile[];
19
+ sourceHash: string;
20
+ totalSizeBytes: number;
21
+ ignorePatterns: string[];
22
+ provenance?: Provenance;
23
+ }
24
+ /**
25
+ * Captures raw source, including binary assets. The manifest is returned for
26
+ * callers; source identity includes the raw artifact.bundle.yml file bytes.
27
+ * This is an upload payload, not attested build provenance. Atlas must validate
28
+ * it again before materializing source in an isolated build sandbox.
29
+ */
30
+ export declare function readNextSourceSnapshot<Manifest, Provenance = never>({ root: inputRoot, manifest, provenance, limits: overrides, }: {
31
+ root: string;
32
+ manifest: Manifest;
33
+ provenance?: Provenance;
34
+ limits?: Partial<NextSourceLimits>;
35
+ }): Promise<NextSourceSnapshot<Manifest, Provenance>>;
@@ -0,0 +1,155 @@
1
+ import { constants } from 'node:fs';
2
+ import { lstat, open, readdir, realpath } from 'node:fs/promises';
3
+ import { extname, join, resolve } from 'node:path';
4
+ import { ARTIFACT_IGNORE_FILE, isArtifactIgnoredPath, parseArtifactIgnore } from './artifact-ignore.js';
5
+ import { sha256Hex } from './hash.js';
6
+ import { computeNextSourceHash } from './next-source-hash.js';
7
+ import { ARTIFACT_NEXT_SOURCE_LIMITS, artifactSourcePathSchema, isExcludedArtifactSourcePath, } from './runtime-contracts.js';
8
+ export const NEXT_SOURCE_LIMITS = ARTIFACT_NEXT_SOURCE_LIMITS;
9
+ /**
10
+ * Captures raw source, including binary assets. The manifest is returned for
11
+ * callers; source identity includes the raw artifact.bundle.yml file bytes.
12
+ * This is an upload payload, not attested build provenance. Atlas must validate
13
+ * it again before materializing source in an isolated build sandbox.
14
+ */
15
+ export async function readNextSourceSnapshot({ root: inputRoot, manifest, provenance, limits: overrides = {}, }) {
16
+ const limits = { ...NEXT_SOURCE_LIMITS, ...overrides };
17
+ const limitNames = ['maxFiles', 'maxFileBytes', 'maxTotalBytes'];
18
+ for (const name of limitNames) {
19
+ const value = limits[name];
20
+ if (!Number.isSafeInteger(value) || value <= 0 || value > NEXT_SOURCE_LIMITS[name]) {
21
+ throw new Error(`Invalid source limit: ${name}; overrides may only lower the platform limit`);
22
+ }
23
+ }
24
+ const input = resolve(inputRoot);
25
+ const rootStat = await lstat(input);
26
+ if (rootStat.isSymbolicLink())
27
+ throw new Error('Source root cannot be a symbolic link');
28
+ if (!rootStat.isDirectory())
29
+ throw new Error('Source root must be a directory');
30
+ const root = await realpath(input);
31
+ const ignore = await readIgnorePatterns({ root, limits });
32
+ const ignorePatterns = ignore.patterns;
33
+ const files = [];
34
+ let totalSizeBytes = 0;
35
+ let visited = 0;
36
+ async function walk(directory, prefix = '') {
37
+ const before = await lstat(directory);
38
+ if (!before.isDirectory() || before.isSymbolicLink() || await realpath(directory) !== directory) {
39
+ throw new Error(`Source directory changed or is a symbolic link: ${prefix || '.'}`);
40
+ }
41
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
42
+ // Excluded trees may contain platform-controlled links (node_modules).
43
+ // Do not inspect or traverse them, and never include them in the payload.
44
+ if (isExcludedArtifactSourcePath({ path: entry.name }))
45
+ continue;
46
+ if (++visited > limits.maxFiles * 4)
47
+ throw new Error('Source directory entry count exceeds limit');
48
+ const path = prefix ? `${prefix}/${entry.name}` : entry.name;
49
+ validateCanonicalPath(path);
50
+ if (isArtifactIgnoredPath(path, ignorePatterns))
51
+ continue;
52
+ const absolute = join(directory, entry.name);
53
+ if (entry.isSymbolicLink())
54
+ throw new Error(`Source symbolic link is not allowed: ${path}`);
55
+ if (entry.isDirectory()) {
56
+ await walk(absolute, path);
57
+ continue;
58
+ }
59
+ if (!entry.isFile())
60
+ throw new Error(`Source path must be a regular file: ${path}`);
61
+ await capture({ absolute, path });
62
+ }
63
+ const after = await lstat(directory);
64
+ if (after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino || before.mtimeMs !== after.mtimeMs) {
65
+ throw new Error(`Source directory changed while capturing snapshot: ${prefix || '.'}; retry the build`);
66
+ }
67
+ }
68
+ async function capture({ absolute, path }) {
69
+ if (files.length >= limits.maxFiles)
70
+ throw new Error(`Source file count exceeds limit (${limits.maxFiles})`);
71
+ const bytes = await readBoundedFile({ absolute, path, limits, remaining: limits.maxTotalBytes - totalSizeBytes });
72
+ if (path === ARTIFACT_IGNORE_FILE && sha256Hex(bytes) !== ignore.sha256) {
73
+ throw new Error('.artifactignore changed while capturing snapshot; retry the build');
74
+ }
75
+ files.push({ path, content: bytes.toString('base64'), encoding: 'base64',
76
+ contentType: inferContentType(path), sha256: sha256Hex(bytes), sizeBytes: bytes.length });
77
+ totalSizeBytes += bytes.length;
78
+ }
79
+ await walk(root);
80
+ for (const required of ['artifact.bundle.yml', 'package.json', 'pnpm-lock.yaml']) {
81
+ if (!files.some((file) => file.path === required)) {
82
+ throw new Error(`Next.js builds require ${required} at the source root; it cannot be excluded by .artifactignore`);
83
+ }
84
+ }
85
+ files.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
86
+ return { root, manifest, files, sourceHash: computeNextSourceHash({ files }), totalSizeBytes, ignorePatterns,
87
+ ...(provenance === undefined ? {} : { provenance }) };
88
+ }
89
+ function validateCanonicalPath(path) {
90
+ if (path.trim() !== path || !artifactSourcePathSchema.safeParse(path).success) {
91
+ throw new Error(`Source path must be a canonical relative POSIX path: ${JSON.stringify(path)}`);
92
+ }
93
+ }
94
+ async function readIgnorePatterns({ root, limits }) {
95
+ const absolute = join(root, ARTIFACT_IGNORE_FILE);
96
+ try {
97
+ const bytes = await readBoundedFile({ absolute, path: ARTIFACT_IGNORE_FILE, limits, remaining: limits.maxTotalBytes });
98
+ return { patterns: parseArtifactIgnore(bytes.toString('utf8')), sha256: sha256Hex(bytes) };
99
+ }
100
+ catch (error) {
101
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT')
102
+ return { patterns: [] };
103
+ throw error;
104
+ }
105
+ }
106
+ async function readBoundedFile({ absolute, path, limits, remaining }) {
107
+ const expected = await lstat(absolute);
108
+ if (expected.isSymbolicLink())
109
+ throw new Error(`Source symbolic link is not allowed: ${path}`);
110
+ if (!expected.isFile())
111
+ throw new Error(`Source path must be a regular file: ${path}`);
112
+ if (expected.nlink > 1)
113
+ throw new Error(`Source hard link is not allowed: ${path}`);
114
+ if (expected.size > limits.maxFileBytes)
115
+ throw new Error(`Source file exceeds byte limit: ${path}`);
116
+ if (expected.size > remaining)
117
+ throw new Error(`Source total bytes exceed limit (${limits.maxTotalBytes})`);
118
+ const handle = await open(absolute, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
119
+ try {
120
+ const before = await handle.stat();
121
+ if (!before.isFile() || before.dev !== expected.dev || before.ino !== expected.ino || before.size !== expected.size) {
122
+ throw new Error(`Source file changed before capture: ${path}; retry the build`);
123
+ }
124
+ // A growing file cannot bypass the pre-read limit or allocate unbounded memory.
125
+ const bytes = Buffer.alloc(before.size + 1);
126
+ let length = 0;
127
+ while (length < bytes.length) {
128
+ const read = await handle.read(bytes, length, bytes.length - length, length);
129
+ if (read.bytesRead === 0)
130
+ break;
131
+ length += read.bytesRead;
132
+ }
133
+ const after = await handle.stat();
134
+ const current = await lstat(absolute);
135
+ if (length !== before.size || before.size !== after.size || before.mtimeMs !== after.mtimeMs ||
136
+ before.ctimeMs !== after.ctimeMs || current.isSymbolicLink() || current.dev !== after.dev || current.ino !== after.ino) {
137
+ throw new Error(`Source file changed while capturing snapshot: ${path}; retry the build`);
138
+ }
139
+ return bytes.subarray(0, length);
140
+ }
141
+ finally {
142
+ await handle.close();
143
+ }
144
+ }
145
+ function inferContentType(path) {
146
+ const types = {
147
+ '.ts': 'text/typescript', '.tsx': 'text/typescript', '.js': 'text/javascript', '.jsx': 'text/javascript',
148
+ '.mjs': 'text/javascript', '.cjs': 'text/javascript', '.json': 'application/json', '.css': 'text/css',
149
+ '.html': 'text/html', '.md': 'text/markdown', '.yml': 'text/yaml', '.yaml': 'text/yaml', '.svg': 'image/svg+xml',
150
+ '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.webp': 'image/webp', '.gif': 'image/gif',
151
+ '.ico': 'image/x-icon', '.avif': 'image/avif', '.woff': 'font/woff', '.woff2': 'font/woff2', '.ttf': 'font/ttf',
152
+ '.otf': 'font/otf', '.txt': 'text/plain', '.wasm': 'application/wasm',
153
+ };
154
+ return types[extname(path).toLowerCase()] ?? 'application/octet-stream';
155
+ }
package/dist/next.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export { createNextArtifactBridge } from './next/bridge.js';
2
+ export type { NextArtifactBridge, NextArtifactBridgeOptions, NextArtifactBridgeSnapshot } from './next/bridge.js';
3
+ export { createNextArtifactThemeApplier } from './next/theme.js';
4
+ export { installNextArtifactBrowserIntegration } from './next/browser.js';
5
+ export { NEXT_ARTIFACT_BRIDGE_TYPE, NEXT_ARTIFACT_BRIDGE_VERSION, createNextArtifactBridgeEnvelope, parseNextArtifactBridgeEnvelope, validateNextArtifactBootstrap, isNextArtifactRelativePath, nextArtifactInitialContextSchema, nextArtifactThemeSchema, nextArtifactLatticeContextSchema, } from './next/protocol.js';
6
+ export type { NextArtifactBridgeBootstrap, NextArtifactBridgeEnvelope, NextArtifactInitialContext, NextArtifactTheme, NextArtifactRuntimeLog } from './next/protocol.js';
7
+ export type { NextArtifactMessageEvent, NextArtifactMessageTransport } from './next/transport.js';
8
+ export type { NextArtifactBridgeRequest } from './next/requests.js';
9
+ export type { NextArtifactStreamRequest } from './next/streams.js';
package/dist/next.js ADDED
@@ -0,0 +1,5 @@
1
+ 'use client';
2
+ export { createNextArtifactBridge } from './next/bridge.js';
3
+ export { createNextArtifactThemeApplier } from './next/theme.js';
4
+ export { installNextArtifactBrowserIntegration } from './next/browser.js';
5
+ export { NEXT_ARTIFACT_BRIDGE_TYPE, NEXT_ARTIFACT_BRIDGE_VERSION, createNextArtifactBridgeEnvelope, parseNextArtifactBridgeEnvelope, validateNextArtifactBootstrap, isNextArtifactRelativePath, nextArtifactInitialContextSchema, nextArtifactThemeSchema, nextArtifactLatticeContextSchema, } from './next/protocol.js';
package/dist/project.d.ts CHANGED
@@ -3,6 +3,8 @@ export interface ArtifactStudioSourceFile {
3
3
  path: string;
4
4
  content: string;
5
5
  contentType: string;
6
+ /** Next source snapshots preserve binary assets; static sources remain UTF-8. */
7
+ encoding?: 'utf8' | 'base64';
6
8
  }
7
9
  export interface ArtifactStudioSource {
8
10
  root: string;
@@ -13,5 +15,6 @@ export interface ArtifactStudioSource {
13
15
  ignorePatterns: string[];
14
16
  }
15
17
  export declare function hasArtifactStudioManifest(rootDir: string): boolean;
18
+ export declare function readArtifactStudioManifest(rootDir: string): Promise<ArtifactStudioManifest>;
16
19
  export declare function readArtifactStudioSource(rootDir: string): Promise<ArtifactStudioSource>;
17
20
  export declare function loadArtifactIgnorePatterns(root: string): Promise<string[]>;
package/dist/project.js CHANGED
@@ -4,7 +4,8 @@ import { join, relative, resolve } from 'node:path';
4
4
  import yaml from 'js-yaml';
5
5
  import { ARTIFACT_IGNORE_FILE, isArtifactIgnoredPath, parseArtifactIgnore, } from './artifact-ignore.js';
6
6
  import { computeSourceHash } from './hash.js';
7
- import { parseArtifactStudioManifest } from './manifest.js';
7
+ import { isNextArtifactManifest, parseArtifactStudioManifest } from './manifest.js';
8
+ import { readNextSourceSnapshot } from './next-source.js';
8
9
  import { normalizeArtifactPath } from './paths.js';
9
10
  const IGNORED_DIRS = new Set(['node_modules', '.git', 'dist', '.next', '.artifact-studio']);
10
11
  const TEXT_EXTENSIONS = new Set([
@@ -13,10 +14,17 @@ const TEXT_EXTENSIONS = new Set([
13
14
  export function hasArtifactStudioManifest(rootDir) {
14
15
  return existsSync(join(resolve(rootDir), 'artifact.bundle.yml'));
15
16
  }
17
+ export async function readArtifactStudioManifest(rootDir) {
18
+ return parseArtifactStudioManifest(yaml.load(await readFile(join(resolve(rootDir), 'artifact.bundle.yml'), 'utf8')));
19
+ }
16
20
  export async function readArtifactStudioSource(rootDir) {
17
21
  const root = resolve(rootDir);
18
22
  const rawManifest = yaml.load(await readFile(join(root, 'artifact.bundle.yml'), 'utf8'));
19
23
  const manifest = parseArtifactStudioManifest(rawManifest);
24
+ if (isNextArtifactManifest(manifest)) {
25
+ const snapshot = await readNextSourceSnapshot({ root, manifest: rawManifest });
26
+ return { ...snapshot, manifest };
27
+ }
20
28
  const ignorePatterns = await loadArtifactIgnorePatterns(root);
21
29
  const files = await collectSourceFiles(root, ignorePatterns);
22
30
  if (!files.some((file) => file.path === manifest.artifact.entrypoint)) {
@@ -0,0 +1,229 @@
1
+ import { z } from 'zod';
2
+ export { resolveArtifactNextImages } from './next-image-config.js';
3
+ /** Shared by local collection, repository collection and the bounded source-upload API. */
4
+ export declare const ARTIFACT_NEXT_SOURCE_LIMITS: Readonly<{
5
+ maxFiles: 2000;
6
+ maxFileBytes: number;
7
+ maxTotalBytes: number;
8
+ }>;
9
+ export declare const artifactSha256DigestSchema: z.ZodString;
10
+ /** Immutable Next deploymentId from compiled output; distinct from the Atlas activation ID. */
11
+ export declare const artifactNextFrameworkBuildIdSchema: z.ZodString;
12
+ /** Shared upload exclusion policy. Content scanning and filesystem containment remain separate checks. */
13
+ export declare function isExcludedArtifactSourcePath({ path }: {
14
+ path: string;
15
+ }): boolean;
16
+ /** POSIX source paths only; filesystem readers must additionally reject symlink escapes. */
17
+ export declare const artifactSourcePathSchema: z.ZodString;
18
+ /** An exact browser origin, not a URL prefix or an allowlist wildcard. */
19
+ export declare const artifactRuntimeOriginSchema: z.ZodString;
20
+ /** Metadata points to an immutable snapshot; file bytes travel through the source-upload API. */
21
+ export declare const artifactNextBuildInputSchema: z.ZodObject<{
22
+ schemaVersion: z.ZodLiteral<1>;
23
+ framework: z.ZodLiteral<"nextjs">;
24
+ projectId: z.ZodString;
25
+ source: z.ZodObject<{
26
+ snapshotId: z.ZodString;
27
+ sha256: z.ZodString;
28
+ git: z.ZodObject<{
29
+ repositoryId: z.ZodString;
30
+ commitSha: z.ZodString;
31
+ }, z.core.$strict>;
32
+ files: z.ZodArray<z.ZodObject<{
33
+ path: z.ZodString;
34
+ sha256: z.ZodString;
35
+ sizeBytes: z.ZodNumber;
36
+ }, z.core.$strict>>;
37
+ }, z.core.$strict>;
38
+ lockfile: z.ZodObject<{
39
+ path: z.ZodLiteral<"pnpm-lock.yaml">;
40
+ sha256: z.ZodString;
41
+ }, z.core.$strict>;
42
+ toolchain: z.ZodObject<{
43
+ node: z.ZodString;
44
+ next: z.ZodString;
45
+ react: z.ZodString;
46
+ packageManager: z.ZodObject<{
47
+ name: z.ZodLiteral<"pnpm">;
48
+ version: z.ZodString;
49
+ }, z.core.$strict>;
50
+ builderImageDigest: z.ZodString;
51
+ }, z.core.$strict>;
52
+ }, z.core.$strict>;
53
+ export declare const artifactDeploymentOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
54
+ kind: z.ZodLiteral<"static">;
55
+ bundle: z.ZodObject<{
56
+ objectId: z.ZodString;
57
+ sha256: z.ZodString;
58
+ }, z.core.$strict>;
59
+ }, z.core.$strict>, z.ZodObject<{
60
+ kind: z.ZodLiteral<"next-server">;
61
+ frameworkBuildId: z.ZodString;
62
+ imageRef: z.ZodString;
63
+ assets: z.ZodObject<{
64
+ objectId: z.ZodString;
65
+ sha256: z.ZodString;
66
+ }, z.core.$strict>;
67
+ buildInputSha256: z.ZodString;
68
+ }, z.core.$strict>], "kind">;
69
+ export declare const artifactOperationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
70
+ status: z.ZodLiteral<"queued">;
71
+ id: z.ZodString;
72
+ projectId: z.ZodString;
73
+ environment: z.ZodString;
74
+ kind: z.ZodEnum<{
75
+ preview: "preview";
76
+ build: "build";
77
+ deploy: "deploy";
78
+ rollback: "rollback";
79
+ suspend: "suspend";
80
+ delete: "delete";
81
+ }>;
82
+ deploymentId: z.ZodOptional<z.ZodString>;
83
+ createdAt: z.ZodISODateTime;
84
+ updatedAt: z.ZodISODateTime;
85
+ }, z.core.$strict>, z.ZodObject<{
86
+ status: z.ZodLiteral<"running">;
87
+ progress: z.ZodOptional<z.ZodObject<{
88
+ stage: z.ZodString;
89
+ percent: z.ZodOptional<z.ZodNumber>;
90
+ }, z.core.$strict>>;
91
+ id: z.ZodString;
92
+ projectId: z.ZodString;
93
+ environment: z.ZodString;
94
+ kind: z.ZodEnum<{
95
+ preview: "preview";
96
+ build: "build";
97
+ deploy: "deploy";
98
+ rollback: "rollback";
99
+ suspend: "suspend";
100
+ delete: "delete";
101
+ }>;
102
+ deploymentId: z.ZodOptional<z.ZodString>;
103
+ createdAt: z.ZodISODateTime;
104
+ updatedAt: z.ZodISODateTime;
105
+ }, z.core.$strict>, z.ZodObject<{
106
+ status: z.ZodLiteral<"succeeded">;
107
+ completedAt: z.ZodISODateTime;
108
+ id: z.ZodString;
109
+ projectId: z.ZodString;
110
+ environment: z.ZodString;
111
+ kind: z.ZodEnum<{
112
+ preview: "preview";
113
+ build: "build";
114
+ deploy: "deploy";
115
+ rollback: "rollback";
116
+ suspend: "suspend";
117
+ delete: "delete";
118
+ }>;
119
+ deploymentId: z.ZodOptional<z.ZodString>;
120
+ createdAt: z.ZodISODateTime;
121
+ updatedAt: z.ZodISODateTime;
122
+ }, z.core.$strict>, z.ZodObject<{
123
+ status: z.ZodLiteral<"failed">;
124
+ completedAt: z.ZodISODateTime;
125
+ error: z.ZodObject<{
126
+ code: z.ZodString;
127
+ message: z.ZodString;
128
+ }, z.core.$strict>;
129
+ id: z.ZodString;
130
+ projectId: z.ZodString;
131
+ environment: z.ZodString;
132
+ kind: z.ZodEnum<{
133
+ preview: "preview";
134
+ build: "build";
135
+ deploy: "deploy";
136
+ rollback: "rollback";
137
+ suspend: "suspend";
138
+ delete: "delete";
139
+ }>;
140
+ deploymentId: z.ZodOptional<z.ZodString>;
141
+ createdAt: z.ZodISODateTime;
142
+ updatedAt: z.ZodISODateTime;
143
+ }, z.core.$strict>, z.ZodObject<{
144
+ status: z.ZodLiteral<"cancelled">;
145
+ completedAt: z.ZodISODateTime;
146
+ id: z.ZodString;
147
+ projectId: z.ZodString;
148
+ environment: z.ZodString;
149
+ kind: z.ZodEnum<{
150
+ preview: "preview";
151
+ build: "build";
152
+ deploy: "deploy";
153
+ rollback: "rollback";
154
+ suspend: "suspend";
155
+ delete: "delete";
156
+ }>;
157
+ deploymentId: z.ZodOptional<z.ZodString>;
158
+ createdAt: z.ZodISODateTime;
159
+ updatedAt: z.ZodISODateTime;
160
+ }, z.core.$strict>], "status">;
161
+ /** Runtime bootstrap is ephemeral. Do not persist bootstrap URLs in deployment history. */
162
+ export declare const artifactRuntimeSessionSchema: z.ZodObject<{
163
+ id: z.ZodString;
164
+ projectId: z.ZodString;
165
+ environment: z.ZodString;
166
+ mode: z.ZodEnum<{
167
+ preview: "preview";
168
+ published: "published";
169
+ local: "local";
170
+ }>;
171
+ origin: z.ZodString;
172
+ parentOrigin: z.ZodString;
173
+ bootstrapUrl: z.ZodURL;
174
+ bridge: z.ZodObject<{
175
+ protocolVersion: z.ZodLiteral<1>;
176
+ channelId: z.ZodString;
177
+ }, z.core.$strict>;
178
+ expiresAt: z.ZodISODateTime;
179
+ }, z.core.$strict>;
180
+ /** Public session metadata contains no tunnel bearer, local credentials or managed secrets. */
181
+ export declare const artifactLocalDevSessionSchema: z.ZodObject<{
182
+ id: z.ZodString;
183
+ ownerId: z.ZodString;
184
+ projectId: z.ZodString;
185
+ environment: z.ZodString;
186
+ origin: z.ZodString;
187
+ sourceRevision: z.ZodOptional<z.ZodString>;
188
+ revision: z.ZodNumber;
189
+ state: z.ZodEnum<{
190
+ failed: "failed";
191
+ starting: "starting";
192
+ compiling: "compiling";
193
+ ready: "ready";
194
+ reconnecting: "reconnecting";
195
+ offline: "offline";
196
+ revoked: "revoked";
197
+ expired: "expired";
198
+ }>;
199
+ lease: z.ZodObject<{
200
+ id: z.ZodString;
201
+ fence: z.ZodNumber;
202
+ expiresAt: z.ZodISODateTime;
203
+ }, z.core.$strict>;
204
+ createdAt: z.ZodISODateTime;
205
+ updatedAt: z.ZodISODateTime;
206
+ expiresAt: z.ZodISODateTime;
207
+ }, z.core.$strict>;
208
+ export declare const artifactActivationSchema: z.ZodObject<{
209
+ id: z.ZodString;
210
+ projectId: z.ZodString;
211
+ environment: z.ZodString;
212
+ deploymentId: z.ZodString;
213
+ configurationSha256: z.ZodString;
214
+ policySha256: z.ZodString;
215
+ secretVersions: z.ZodArray<z.ZodObject<{
216
+ binding: z.ZodString;
217
+ secretId: z.ZodString;
218
+ version: z.ZodNumber;
219
+ }, z.core.$strict>>;
220
+ cacheGeneration: z.ZodString;
221
+ activatedAt: z.ZodISODateTime;
222
+ activatedBy: z.ZodString;
223
+ }, z.core.$strict>;
224
+ export type ArtifactNextBuildInput = z.infer<typeof artifactNextBuildInputSchema>;
225
+ export type ArtifactDeploymentOutput = z.infer<typeof artifactDeploymentOutputSchema>;
226
+ export type ArtifactOperation = z.infer<typeof artifactOperationSchema>;
227
+ export type ArtifactRuntimeSession = z.infer<typeof artifactRuntimeSessionSchema>;
228
+ export type ArtifactLocalDevSession = z.infer<typeof artifactLocalDevSessionSchema>;
229
+ export type ArtifactActivation = z.infer<typeof artifactActivationSchema>;