@xfey/tutti 0.1.52 → 0.1.54

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 (47) hide show
  1. package/dist/artifacts/candidate-validator.d.ts +2 -3
  2. package/dist/artifacts/candidate-validator.js +0 -40
  3. package/dist/artifacts/index.d.ts +3 -3
  4. package/dist/artifacts/index.js +3 -3
  5. package/dist/artifacts/live-manifest.d.ts +23 -0
  6. package/dist/artifacts/live-manifest.js +115 -0
  7. package/dist/artifacts/preview-runtime.d.ts +34 -36
  8. package/dist/artifacts/preview-runtime.js +215 -273
  9. package/dist/artifacts/static-preview.d.ts +2 -1
  10. package/dist/artifacts/static-preview.js +19 -21
  11. package/dist/control-plane/index.d.ts +1 -0
  12. package/dist/control-plane/index.js +13 -2
  13. package/dist/control-plane/types.d.ts +4 -0
  14. package/dist/run-pipeline/openai.js +7 -12
  15. package/dist/server-shell/cli/host-server-runtime.js +20 -0
  16. package/dist/server-shell/http/routes/project-api/artifacts-routes.js +43 -110
  17. package/dist/server-shell/http/routes/project-api/openapi-artifacts-routes.d.ts +5 -8
  18. package/dist/server-shell/http/routes/project-api/openapi-artifacts-routes.js +5 -33
  19. package/dist/server-shell/http/routes/project-api/openapi.d.ts +17 -8
  20. package/dist/server-shell/http/routes/project-api/types.d.ts +3 -2
  21. package/dist/workspace-ops/index.d.ts +1 -1
  22. package/dist/workspace-ops/index.js +1 -1
  23. package/dist/workspace-ops/project-workspace.d.ts +0 -1
  24. package/dist/workspace-ops/project-workspace.js +0 -20
  25. package/dist/workspace-ops/types.d.ts +0 -2
  26. package/node_modules/@tutti/shared/dist/schemas/api/artifacts.d.ts +7 -88
  27. package/node_modules/@tutti/shared/dist/schemas/api/artifacts.js +3 -48
  28. package/node_modules/@tutti/shared/dist/schemas/api/index.d.ts +1 -1
  29. package/node_modules/@tutti/shared/dist/schemas/api/index.js +1 -1
  30. package/node_modules/@tutti/shared/dist/schemas/api/types.d.ts +1 -10
  31. package/package.json +1 -1
  32. package/prompts/prompt-flow-map.md +4 -4
  33. package/prompts/runs/README.md +2 -1
  34. package/prompts/runs/task-continuation.md +1 -0
  35. package/prompts/runs/task-retry.md +3 -2
  36. package/prompts/runs/task-run.md +1 -0
  37. package/web/assets/{homepage-motion-scene-ENUzAyyp.js → homepage-motion-scene-C96Na8TV.js} +1 -1
  38. package/web/assets/{index-DK8LBgHp.js → index-CM41hrQd.js} +3 -3
  39. package/web/assets/index-nWy1QP97.css +1 -0
  40. package/web/assets/tutti_avatar-_0Yc-cMJ.png +0 -0
  41. package/web/index.html +2 -2
  42. package/dist/artifacts/manifest.d.ts +0 -41
  43. package/dist/artifacts/manifest.js +0 -169
  44. package/dist/run-pipeline/candidate-diff.d.ts +0 -3
  45. package/dist/run-pipeline/candidate-diff.js +0 -4
  46. package/web/assets/index-CWWkCr48.css +0 -1
  47. package/web/assets/tutti_avatar-BBhaZGi3.png +0 -0
@@ -1,8 +1,8 @@
1
1
  import type { ChildProcessWithoutNullStreams } from "node:child_process";
2
2
  import { type ValidatedArtifactContract } from "./manifest-contract.js";
3
3
  import { type ArtifactPreviewProcessPlan } from "./process-boundary.js";
4
- export type ArtifactValidationReasonCode = "artifact_applicability_failed" | "artifact_manifest_missing" | "artifact_manifest_invalid" | "artifact_static_entry_invalid" | "artifact_preview_script_missing" | "artifact_preview_start_failed" | "artifact_preview_not_ready" | "artifact_preview_entry_invalid" | "artifact_preview_modified_candidate";
5
- export type ArtifactValidationDiagnosticSource = "applicability_judge" | "manifest_parser" | "package_json" | "preview_process" | "ready_probe" | "candidate_diff";
4
+ export type ArtifactValidationReasonCode = "artifact_applicability_failed" | "artifact_manifest_missing" | "artifact_manifest_invalid" | "artifact_static_entry_invalid" | "artifact_preview_script_missing" | "artifact_preview_start_failed" | "artifact_preview_not_ready" | "artifact_preview_entry_invalid";
5
+ export type ArtifactValidationDiagnosticSource = "applicability_judge" | "manifest_parser" | "package_json" | "preview_process" | "ready_probe";
6
6
  export type ArtifactValidationDiagnostic = {
7
7
  source: ArtifactValidationDiagnosticSource;
8
8
  text: string;
@@ -30,7 +30,6 @@ export type ValidateCandidateArtifactOptions = {
30
30
  allocatePort?: () => Promise<number>;
31
31
  fetchImpl?: typeof fetch;
32
32
  terminateProcess?: (child: ChildProcessWithoutNullStreams) => Promise<void>;
33
- fingerprintCandidate?: (repoRoot: string) => string;
34
33
  readyTimeoutMs?: number;
35
34
  probeIntervalMs?: number;
36
35
  probeRequestTimeoutMs?: number;
@@ -1,6 +1,5 @@
1
1
  import { lstatSync, readFileSync, realpathSync } from "node:fs";
2
2
  import { isAbsolute, join, relative, resolve } from "node:path";
3
- import { fingerprintProjectSourceState } from "../workspace-ops/index.js";
4
3
  import { ARTIFACT_MANIFEST_PATH, MAX_ARTIFACT_MANIFEST_BYTES, parseArtifactManifestContract, } from "./manifest-contract.js";
5
4
  import { allocateArtifactPreviewPort, ArtifactDiagnosticBuffer, cleanupArtifactProcessRuntime, createArtifactPreviewEnv, createArtifactProcessRuntime, spawnArtifactPreviewProcess, terminateArtifactProcessTree, } from "./process-boundary.js";
6
5
  const MAX_PACKAGE_JSON_BYTES = 1024 * 1024;
@@ -290,21 +289,6 @@ async function validateServerCandidate(repoRealPath, contract, options) {
290
289
  sensitive: { repoRoot: repoRealPath, extra: [cwd.path] },
291
290
  });
292
291
  }
293
- const fingerprint = options.fingerprintCandidate ?? fingerprintProjectSourceState;
294
- let beforeFingerprint;
295
- try {
296
- beforeFingerprint = fingerprint(repoRealPath);
297
- }
298
- catch (error) {
299
- return failure({
300
- reasonCode: "artifact_preview_modified_candidate",
301
- summary: "Tutti could not capture the candidate state before preview validation.",
302
- guidance: "Keep the candidate project directory in a valid Git repository and retry.",
303
- source: "candidate_diff",
304
- detail: error instanceof Error ? error.message : "Candidate state capture failed",
305
- sensitive: { repoRoot: repoRealPath },
306
- });
307
- }
308
292
  const processRuntime = createArtifactProcessRuntime();
309
293
  const diagnostics = new ArtifactDiagnosticBuffer();
310
294
  let child;
@@ -439,30 +423,6 @@ async function validateServerCandidate(repoRealPath, contract, options) {
439
423
  }
440
424
  cleanupArtifactProcessRuntime(processRuntime);
441
425
  }
442
- let afterFingerprint;
443
- try {
444
- afterFingerprint = fingerprint(repoRealPath);
445
- }
446
- catch (error) {
447
- return failure({
448
- reasonCode: "artifact_preview_modified_candidate",
449
- summary: "Tutti could not verify the candidate state after preview validation.",
450
- guidance: "Ensure artifact:preview exits cleanly without changing repository files.",
451
- source: "candidate_diff",
452
- detail: error instanceof Error ? error.message : "Candidate state capture failed",
453
- sensitive: { repoRoot: repoRealPath },
454
- });
455
- }
456
- if (afterFingerprint !== beforeFingerprint) {
457
- return failure({
458
- reasonCode: "artifact_preview_modified_candidate",
459
- summary: "The server Artifact preview modified the candidate repository.",
460
- guidance: "Make artifact:preview read-only, or generate required tracked files before validation.",
461
- source: "candidate_diff",
462
- detail: "Candidate Git state changed while artifact:preview was running",
463
- sensitive: { repoRoot: repoRealPath },
464
- });
465
- }
466
426
  return (result ??
467
427
  failure({
468
428
  reasonCode: "artifact_preview_start_failed",
@@ -1,6 +1,6 @@
1
- export { ARTIFACT_MANIFEST_PATH, ARTIFACT_PREVIEW_BASE_PATH, buildArtifactPreviewUrl, readArtifactDeclaration, readArtifactProjection, type ArtifactDeclaration, type DeclaredArtifactRuntime, type ReadArtifactDeclarationOptions, } from "./manifest.js";
1
+ export { readLiveArtifactDeclaration, type LiveArtifactDeclaration, } from "./live-manifest.js";
2
2
  export { validateCandidateArtifact, type ArtifactValidationDiagnostic, type ArtifactValidationDiagnosticSource, type ArtifactValidationReasonCode, type CandidateArtifactValidationFailure, type CandidateArtifactValidationResult, type ValidateCandidateArtifactOptions, } from "./candidate-validator.js";
3
- export { parseArtifactManifestContract, type ArtifactContractError, type ArtifactContractResult, type ValidatedArtifactContract, type ValidatedArtifactRuntime, } from "./manifest-contract.js";
4
- export { ARTIFACT_PREVIEW_REQUEST_BODY_LIMIT_BYTES, ARTIFACT_PREVIEW_RESPONSE_BODY_LIMIT_BYTES, ARTIFACT_PREVIEW_DEFAULT_BASE_PATH, ArtifactPreviewManager, isArtifactPreviewHttpMethod, type ArtifactPreviewCommandResult, type ArtifactPreviewHeartbeatResult, type ArtifactPreviewHttpMethod, type ArtifactPreviewManagerOptions, type ArtifactPreviewProcessPlan, type ArtifactPreviewStartResult, type ArtifactPreviewStopResult, type ArtifactServerPreviewResponse, } from "./preview-runtime.js";
3
+ export { ARTIFACT_MANIFEST_PATH, parseArtifactManifestContract, type ArtifactContractError, type ArtifactContractResult, type ValidatedArtifactContract, type ValidatedArtifactRuntime, } from "./manifest-contract.js";
4
+ export { ARTIFACT_PREVIEW_BASE_PATH, ARTIFACT_PREVIEW_REQUEST_BODY_LIMIT_BYTES, ARTIFACT_PREVIEW_RESPONSE_BODY_LIMIT_BYTES, ARTIFACT_PREVIEW_DEFAULT_BASE_PATH, ArtifactPreviewManager, isArtifactPreviewHttpMethod, type ArtifactPreviewLeaseOptions, type ArtifactPreviewHttpMethod, type ArtifactPreviewManagerOptions, type ArtifactPreviewProcessPlan, type ArtifactServerPreviewResponse, } from "./preview-runtime.js";
5
5
  export { ARTIFACT_PREVIEW_CSP, readArtifactStaticPreview, rewriteArtifactPreviewResourceUrls, type ArtifactStaticPreviewFile, type ReadArtifactStaticPreviewOptions, } from "./static-preview.js";
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,6 @@
1
- export { ARTIFACT_MANIFEST_PATH, ARTIFACT_PREVIEW_BASE_PATH, buildArtifactPreviewUrl, readArtifactDeclaration, readArtifactProjection, } from "./manifest.js";
1
+ export { readLiveArtifactDeclaration, } from "./live-manifest.js";
2
2
  export { validateCandidateArtifact, } from "./candidate-validator.js";
3
- export { parseArtifactManifestContract, } from "./manifest-contract.js";
4
- export { ARTIFACT_PREVIEW_REQUEST_BODY_LIMIT_BYTES, ARTIFACT_PREVIEW_RESPONSE_BODY_LIMIT_BYTES, ARTIFACT_PREVIEW_DEFAULT_BASE_PATH, ArtifactPreviewManager, isArtifactPreviewHttpMethod, } from "./preview-runtime.js";
3
+ export { ARTIFACT_MANIFEST_PATH, parseArtifactManifestContract, } from "./manifest-contract.js";
4
+ export { ARTIFACT_PREVIEW_BASE_PATH, ARTIFACT_PREVIEW_REQUEST_BODY_LIMIT_BYTES, ARTIFACT_PREVIEW_RESPONSE_BODY_LIMIT_BYTES, ARTIFACT_PREVIEW_DEFAULT_BASE_PATH, ArtifactPreviewManager, isArtifactPreviewHttpMethod, } from "./preview-runtime.js";
5
5
  export { ARTIFACT_PREVIEW_CSP, readArtifactStaticPreview, rewriteArtifactPreviewResourceUrls, } from "./static-preview.js";
6
6
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,23 @@
1
+ import type { ArtifactManifest, ArtifactProjection } from "@tutti/shared/schemas/api";
2
+ import { type ValidatedArtifactRuntime } from "./manifest-contract.js";
3
+ type ArtifactInvalidProjection = Extract<ArtifactProjection, {
4
+ status: "invalid";
5
+ }>;
6
+ export type LiveArtifactDeclaration = {
7
+ status: "not_declared";
8
+ projection: Extract<ArtifactProjection, {
9
+ status: "not_declared";
10
+ }>;
11
+ } | {
12
+ status: "invalid";
13
+ projection: ArtifactInvalidProjection;
14
+ } | {
15
+ status: "declared";
16
+ manifest: ArtifactManifest;
17
+ runtime: ValidatedArtifactRuntime;
18
+ };
19
+ export declare function readLiveArtifactDeclaration(options: {
20
+ workspaceRoot: string;
21
+ }): LiveArtifactDeclaration;
22
+ export {};
23
+ //# sourceMappingURL=live-manifest.d.ts.map
@@ -0,0 +1,115 @@
1
+ import { lstatSync, readFileSync, realpathSync } from "node:fs";
2
+ import { isAbsolute, join, relative, resolve } from "node:path";
3
+ import { ARTIFACT_MANIFEST_PATH, MAX_ARTIFACT_MANIFEST_BYTES, parseArtifactManifestContract, } from "./manifest-contract.js";
4
+ function truncateMessage(message) {
5
+ const normalized = message.replace(/\s+/gu, " ").trim();
6
+ return normalized.length <= 220 ? normalized : `${normalized.slice(0, 217)}...`;
7
+ }
8
+ function invalidArtifact(code, message) {
9
+ return {
10
+ status: "invalid",
11
+ projection: {
12
+ status: "invalid",
13
+ error: {
14
+ code,
15
+ message: truncateMessage(message),
16
+ },
17
+ },
18
+ };
19
+ }
20
+ function isContainedPath(root, target) {
21
+ const relativePath = relative(root, target);
22
+ return relativePath === "" || (!relativePath.startsWith("..") && !isAbsolute(relativePath));
23
+ }
24
+ function requireContainedPath(options) {
25
+ try {
26
+ const target = realpathSync.native(resolve(options.workspaceRealPath, options.repoPath));
27
+ const stat = lstatSync(target);
28
+ const expectedKind = options.kind === "file" ? stat.isFile() : stat.isDirectory();
29
+ if (!isContainedPath(options.workspaceRealPath, target) || !expectedKind) {
30
+ return invalidArtifact("invalid_path", `${options.label} is not a contained ${options.kind}`);
31
+ }
32
+ return null;
33
+ }
34
+ catch {
35
+ return invalidArtifact("not_found", `${options.label} does not exist`);
36
+ }
37
+ }
38
+ export function readLiveArtifactDeclaration(options) {
39
+ let workspaceRealPath;
40
+ try {
41
+ workspaceRealPath = realpathSync.native(options.workspaceRoot);
42
+ }
43
+ catch {
44
+ return invalidArtifact("workspace_unavailable", "Project workspace is unavailable");
45
+ }
46
+ const manifestPath = join(workspaceRealPath, ARTIFACT_MANIFEST_PATH);
47
+ let manifestStat;
48
+ try {
49
+ manifestStat = lstatSync(manifestPath);
50
+ }
51
+ catch (error) {
52
+ if (error.code === "ENOENT") {
53
+ return {
54
+ status: "not_declared",
55
+ projection: { status: "not_declared" },
56
+ };
57
+ }
58
+ return invalidArtifact("manifest_unavailable", "Artifact manifest cannot be read");
59
+ }
60
+ if (!manifestStat.isFile()) {
61
+ return invalidArtifact("invalid_manifest", "Artifact manifest path is not a regular file");
62
+ }
63
+ if (manifestStat.size > MAX_ARTIFACT_MANIFEST_BYTES) {
64
+ return invalidArtifact("too_large", "Artifact manifest is too large");
65
+ }
66
+ let manifestContent;
67
+ try {
68
+ manifestContent = readFileSync(manifestPath);
69
+ }
70
+ catch {
71
+ return invalidArtifact("manifest_unavailable", "Artifact manifest cannot be read");
72
+ }
73
+ const parsed = parseArtifactManifestContract(manifestContent);
74
+ if (!parsed.ok) {
75
+ return invalidArtifact(parsed.error.code, parsed.error.message);
76
+ }
77
+ const runtime = parsed.declaration.runtime;
78
+ if (runtime.kind === "static") {
79
+ const rootError = requireContainedPath({
80
+ workspaceRealPath,
81
+ repoPath: runtime.root_path,
82
+ kind: "directory",
83
+ label: "Static artifact root",
84
+ });
85
+ if (rootError !== null) {
86
+ return rootError;
87
+ }
88
+ const entryError = requireContainedPath({
89
+ workspaceRealPath,
90
+ repoPath: runtime.entry_repo_path,
91
+ kind: "file",
92
+ label: "Static artifact entry",
93
+ });
94
+ if (entryError !== null) {
95
+ return entryError;
96
+ }
97
+ }
98
+ else {
99
+ const cwdError = requireContainedPath({
100
+ workspaceRealPath,
101
+ repoPath: runtime.cwd_path,
102
+ kind: "directory",
103
+ label: "Server artifact cwd",
104
+ });
105
+ if (cwdError !== null) {
106
+ return cwdError;
107
+ }
108
+ }
109
+ return {
110
+ status: "declared",
111
+ manifest: parsed.declaration.manifest,
112
+ runtime,
113
+ };
114
+ }
115
+ //# sourceMappingURL=live-manifest.js.map
@@ -1,21 +1,7 @@
1
1
  import type { ChildProcessWithoutNullStreams } from "node:child_process";
2
- import type { ArtifactProjection, GetArtifactsResponse, HeartbeatArtifactPreviewDisposition, StartArtifactPreviewDisposition, StopArtifactPreviewDisposition } from "@tutti/shared/schemas/api";
2
+ import type { GetArtifactsResponse } from "@tutti/shared/schemas/api";
3
3
  import { type ArtifactPreviewProcessPlan, type ArtifactProcessRuntime } from "./process-boundary.js";
4
- export type ArtifactPreviewCommandResult = {
5
- artifact: ArtifactProjection;
6
- };
7
- export type ArtifactPreviewStartResult = {
8
- disposition: StartArtifactPreviewDisposition;
9
- result: ArtifactPreviewCommandResult;
10
- };
11
- export type ArtifactPreviewHeartbeatResult = {
12
- disposition: HeartbeatArtifactPreviewDisposition;
13
- result: ArtifactPreviewCommandResult;
14
- };
15
- export type ArtifactPreviewStopResult = {
16
- disposition: StopArtifactPreviewDisposition;
17
- result: ArtifactPreviewCommandResult;
18
- };
4
+ import { type ArtifactStaticPreviewFile } from "./static-preview.js";
19
5
  export type ArtifactServerPreviewResponse = {
20
6
  status_code: number;
21
7
  headers: Record<string, string>;
@@ -23,7 +9,6 @@ export type ArtifactServerPreviewResponse = {
23
9
  };
24
10
  export type ArtifactPreviewHttpMethod = "GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS";
25
11
  export type ArtifactPreviewManagerOptions = {
26
- now?: () => Date;
27
12
  baseEnv?: NodeJS.ProcessEnv;
28
13
  spawnProcess?: (plan: ArtifactPreviewProcessPlan) => ChildProcessWithoutNullStreams;
29
14
  terminateProcess?: (child: ChildProcessWithoutNullStreams) => Promise<void>;
@@ -43,11 +28,15 @@ export type ArtifactPreviewManagerOptions = {
43
28
  responseBodyLimitBytes?: number;
44
29
  idleStopTtlMs?: number;
45
30
  };
31
+ export type ArtifactPreviewLeaseOptions = {
32
+ viewerId: string;
33
+ workspaceRoot: string;
34
+ };
46
35
  export declare const ARTIFACT_PREVIEW_REQUEST_BODY_LIMIT_BYTES: number;
47
36
  export declare const ARTIFACT_PREVIEW_RESPONSE_BODY_LIMIT_BYTES: number;
37
+ export declare const ARTIFACT_PREVIEW_BASE_PATH: "/artifacts/preview";
48
38
  export declare function isArtifactPreviewHttpMethod(method: string): method is ArtifactPreviewHttpMethod;
49
39
  export declare class ArtifactPreviewManager {
50
- private readonly now;
51
40
  private readonly baseEnv;
52
41
  private readonly spawnProcess;
53
42
  private readonly terminateProcess;
@@ -67,25 +56,26 @@ export declare class ArtifactPreviewManager {
67
56
  private readonly responseBodyLimitBytes;
68
57
  private readonly idleStopTtlMs;
69
58
  private readonly pendingTasks;
59
+ private readonly leases;
60
+ private leaseSweepTimer;
70
61
  private state;
71
- private nextInstanceSequence;
62
+ private declaration;
63
+ private lastProjection;
64
+ private workspaceUpdating;
65
+ private nextGenerationSequence;
72
66
  constructor(options?: ArtifactPreviewManagerOptions);
73
- readProjection(options: {
74
- workspaceRoot: string;
67
+ readProjection(options?: {
68
+ workspaceRoot?: string;
75
69
  previewBasePath?: string;
76
70
  }): GetArtifactsResponse;
77
- start(options: {
71
+ initializeWorkspace(options: {
78
72
  workspaceRoot: string;
79
- previewBasePath?: string;
80
- }): ArtifactPreviewStartResult;
81
- heartbeat(options: {
73
+ }): void;
74
+ renewLease(options: ArtifactPreviewLeaseOptions): void;
75
+ beginWorkspaceUpdate(): void;
76
+ settleWorkspaceUpdate(options: {
82
77
  workspaceRoot: string;
83
- previewBasePath?: string;
84
- }): ArtifactPreviewHeartbeatResult;
85
- stop(options: {
86
- workspaceRoot: string;
87
- previewBasePath?: string;
88
- }): ArtifactPreviewStopResult;
78
+ }): void;
89
79
  fetchServerPreview(options: {
90
80
  workspaceRoot: string;
91
81
  path: string | undefined;
@@ -94,22 +84,30 @@ export declare class ArtifactPreviewManager {
94
84
  headers?: Record<string, string | undefined>;
95
85
  body?: Buffer;
96
86
  }): Promise<ArtifactServerPreviewResponse>;
97
- sweepIdle(): void;
87
+ readStaticPreview(options: {
88
+ workspaceRoot: string;
89
+ path: string | undefined;
90
+ query?: string;
91
+ }): ArtifactStaticPreviewFile;
98
92
  stopAll(): Promise<void>;
93
+ private currentProjection;
94
+ private ensurePreview;
95
+ private refreshDeclaration;
96
+ private applyDeclaration;
97
+ private createIdleState;
99
98
  private startProcess;
100
99
  private launchProcess;
101
100
  private attachProcessListeners;
102
101
  private waitUntilReady;
103
102
  private probeReadyEntry;
104
- private recordHeartbeat;
105
- private scheduleIdleSweep;
106
- private stopStaleRuntime;
103
+ private pruneExpiredLeases;
104
+ private scheduleLeaseSweep;
107
105
  private stopCurrentProcess;
108
106
  private failState;
109
107
  private disposeStateProcess;
110
108
  private cleanupStateRuntime;
111
109
  private trackTask;
112
- private nextInstanceId;
110
+ private nextGeneration;
113
111
  }
114
112
  export type { ArtifactPreviewProcessPlan } from "./process-boundary.js";
115
113
  export declare const ARTIFACT_PREVIEW_DEFAULT_BASE_PATH: "/artifacts/preview";