@builder.io/ai-utils 0.95.0 → 0.96.1

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.
@@ -121,6 +121,7 @@ interface OrganizationSettings {
121
121
  /** Default single tenancy config ID for this space. References a document in the singleTenancyConfigurations collection.
122
122
  * Projects can override this with their own singleTenancyConfig setting. */
123
123
  defaultSingleTenancyConfig?: string;
124
+ aiFeatures?: boolean;
124
125
  controlModelAvailability?: boolean;
125
126
  allowedAiModels?: string[];
126
127
  autoModelOverride?: string;
package/src/projects.d.ts CHANGED
@@ -251,6 +251,16 @@ export declare const matchesAgentNativeStarter: (repo: {
251
251
  repoName?: string | null;
252
252
  templateRepoUrl?: string | null;
253
253
  }) => boolean;
254
+ export declare function getManagedDatabasePackageJsonError(content: string): string | undefined;
255
+ export declare function getAgentNativeRootPackageJsonWriteError(args: {
256
+ repo: {
257
+ repoName?: string | null;
258
+ templateRepoUrl?: string | null;
259
+ };
260
+ repoPath: string;
261
+ resolvedPath: string;
262
+ content: string;
263
+ }): string | undefined;
254
264
  export declare const EXAMPLE_OR_STARTER_REPOS: string[];
255
265
  export declare const EXAMPLE_OR_STARTER_REPOS_URLS: string[];
256
266
  export interface GitBackupUploadUrlResult {
@@ -981,10 +991,11 @@ export declare const ProjectSettingsSchema: z.ZodObject<{
981
991
  "org-worker": "org-worker";
982
992
  "project-configuration": "project-configuration";
983
993
  "projects-scheduler-memory-extraction": "projects-scheduler-memory-extraction";
994
+ "publish-agent": "publish-agent";
984
995
  "repo-indexing": "repo-indexing";
985
996
  "setup-project": "setup-project";
986
997
  unknown: "unknown";
987
- }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
998
+ }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "publish-agent-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
988
999
  needDevServer: z.ZodOptional<z.ZodBoolean>;
989
1000
  needValidation: z.ZodOptional<z.ZodBoolean>;
990
1001
  includeMemories: z.ZodOptional<z.ZodBoolean>;
@@ -1321,10 +1332,11 @@ export declare const ProjectSettingsExternalSchema: z.ZodObject<{
1321
1332
  "org-worker": "org-worker";
1322
1333
  "project-configuration": "project-configuration";
1323
1334
  "projects-scheduler-memory-extraction": "projects-scheduler-memory-extraction";
1335
+ "publish-agent": "publish-agent";
1324
1336
  "repo-indexing": "repo-indexing";
1325
1337
  "setup-project": "setup-project";
1326
1338
  unknown: "unknown";
1327
- }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
1339
+ }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "publish-agent-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
1328
1340
  needDevServer: z.ZodOptional<z.ZodBoolean>;
1329
1341
  needValidation: z.ZodOptional<z.ZodBoolean>;
1330
1342
  includeMemories: z.ZodOptional<z.ZodBoolean>;
@@ -2522,10 +2534,11 @@ export declare const UpdateProjectOptionsSchema: z.ZodObject<{
2522
2534
  "org-worker": "org-worker";
2523
2535
  "project-configuration": "project-configuration";
2524
2536
  "projects-scheduler-memory-extraction": "projects-scheduler-memory-extraction";
2537
+ "publish-agent": "publish-agent";
2525
2538
  "repo-indexing": "repo-indexing";
2526
2539
  "setup-project": "setup-project";
2527
2540
  unknown: "unknown";
2528
- }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
2541
+ }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "publish-agent-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
2529
2542
  needDevServer: z.ZodOptional<z.ZodBoolean>;
2530
2543
  needValidation: z.ZodOptional<z.ZodBoolean>;
2531
2544
  includeMemories: z.ZodOptional<z.ZodBoolean>;
@@ -2800,6 +2813,62 @@ export type UpdateProjectOptions = z.infer<typeof UpdateProjectOptionsSchema>;
2800
2813
  /**
2801
2814
  * A single deploy record, stored at `deploys/{deployId}`. The Deploy.id is the document key.
2802
2815
  */
2816
+ /**
2817
+ * Pipeline step a deploy died at. Set by the pod, the only place that still
2818
+ * knows, so the server can attribute the failure without reading log text.
2819
+ */
2820
+ export declare const DeployFailureStageSchema: z.ZodEnum<{
2821
+ build: "build";
2822
+ init: "init";
2823
+ migrate: "migrate";
2824
+ package: "package";
2825
+ setup: "setup";
2826
+ upload: "upload";
2827
+ }>;
2828
+ export type DeployFailureStage = z.infer<typeof DeployFailureStageSchema>;
2829
+ /** `app` is the only value that reaches the agent, so unknowns resolve away from it. */
2830
+ export declare const DeployFailureOwnerSchema: z.ZodEnum<{
2831
+ app: "app";
2832
+ platform: "platform";
2833
+ unknown: "unknown";
2834
+ }>;
2835
+ export type DeployFailureOwner = z.infer<typeof DeployFailureOwnerSchema>;
2836
+ /** What the deploy pod reports about a failure. All optional: older pods send none of it. */
2837
+ export declare const DeployFailureReportSchema: z.ZodObject<{
2838
+ stage: z.ZodOptional<z.ZodEnum<{
2839
+ build: "build";
2840
+ init: "init";
2841
+ migrate: "migrate";
2842
+ package: "package";
2843
+ setup: "setup";
2844
+ upload: "upload";
2845
+ }>>;
2846
+ exitCode: z.ZodOptional<z.ZodNumber>;
2847
+ signal: z.ZodOptional<z.ZodString>;
2848
+ excerpt: z.ZodOptional<z.ZodString>;
2849
+ }, z.core.$strip>;
2850
+ export type DeployFailureReport = z.infer<typeof DeployFailureReportSchema>;
2851
+ export declare const DeployFailureSchema: z.ZodObject<{
2852
+ stage: z.ZodOptional<z.ZodEnum<{
2853
+ build: "build";
2854
+ init: "init";
2855
+ migrate: "migrate";
2856
+ package: "package";
2857
+ setup: "setup";
2858
+ upload: "upload";
2859
+ }>>;
2860
+ owner: z.ZodEnum<{
2861
+ app: "app";
2862
+ platform: "platform";
2863
+ unknown: "unknown";
2864
+ }>;
2865
+ code: z.ZodString;
2866
+ summary: z.ZodString;
2867
+ exitCode: z.ZodOptional<z.ZodNumber>;
2868
+ signal: z.ZodOptional<z.ZodString>;
2869
+ fixRequested: z.ZodOptional<z.ZodBoolean>;
2870
+ }, z.core.$strip>;
2871
+ export type DeployFailure = z.infer<typeof DeployFailureSchema>;
2803
2872
  export declare const DeploySchema: z.ZodObject<{
2804
2873
  id: z.ZodString;
2805
2874
  projectId: z.ZodString;
@@ -2829,11 +2898,38 @@ export declare const DeploySchema: z.ZodObject<{
2829
2898
  url: z.ZodOptional<z.ZodString>;
2830
2899
  migrationApplied: z.ZodOptional<z.ZodBoolean>;
2831
2900
  error: z.ZodOptional<z.ZodString>;
2901
+ failure: z.ZodOptional<z.ZodObject<{
2902
+ stage: z.ZodOptional<z.ZodEnum<{
2903
+ build: "build";
2904
+ init: "init";
2905
+ migrate: "migrate";
2906
+ package: "package";
2907
+ setup: "setup";
2908
+ upload: "upload";
2909
+ }>>;
2910
+ owner: z.ZodEnum<{
2911
+ app: "app";
2912
+ platform: "platform";
2913
+ unknown: "unknown";
2914
+ }>;
2915
+ code: z.ZodString;
2916
+ summary: z.ZodString;
2917
+ exitCode: z.ZodOptional<z.ZodNumber>;
2918
+ signal: z.ZodOptional<z.ZodString>;
2919
+ fixRequested: z.ZodOptional<z.ZodBoolean>;
2920
+ }, z.core.$strip>>;
2832
2921
  createdAt: z.ZodNumber;
2833
2922
  completedAt: z.ZodOptional<z.ZodNumber>;
2834
2923
  triggeredBy: z.ZodString;
2835
2924
  }, z.core.$strip>;
2836
2925
  export type Deploy = z.infer<typeof DeploySchema>;
2926
+ /**
2927
+ * The user who asked for this deploy, or `undefined` when nobody did. Lives
2928
+ * with the schema so every caller that needs a real user agrees on what counts.
2929
+ */
2930
+ export declare function deployTriggeringUser(deploy: {
2931
+ triggeredBy?: string;
2932
+ }): string | undefined;
2837
2933
  /**
2838
2934
  * Permanent slug reservation, stored at `hosting-slugs/{slug}` (slug is the document key).
2839
2935
  *
@@ -2928,6 +3024,26 @@ export declare const DeployListItemSchema: z.ZodObject<{
2928
3024
  }>;
2929
3025
  url: z.ZodOptional<z.ZodString>;
2930
3026
  error: z.ZodOptional<z.ZodString>;
3027
+ failure: z.ZodOptional<z.ZodObject<{
3028
+ stage: z.ZodOptional<z.ZodEnum<{
3029
+ build: "build";
3030
+ init: "init";
3031
+ migrate: "migrate";
3032
+ package: "package";
3033
+ setup: "setup";
3034
+ upload: "upload";
3035
+ }>>;
3036
+ owner: z.ZodEnum<{
3037
+ app: "app";
3038
+ platform: "platform";
3039
+ unknown: "unknown";
3040
+ }>;
3041
+ code: z.ZodString;
3042
+ summary: z.ZodString;
3043
+ exitCode: z.ZodOptional<z.ZodNumber>;
3044
+ signal: z.ZodOptional<z.ZodString>;
3045
+ fixRequested: z.ZodOptional<z.ZodBoolean>;
3046
+ }, z.core.$strip>>;
2931
3047
  createdAt: z.ZodNumber;
2932
3048
  completedAt: z.ZodOptional<z.ZodNumber>;
2933
3049
  }, z.core.$strip>;
@@ -2966,6 +3082,31 @@ export declare function builderConfigHostingToBuildOverrides(hosting: BuilderCon
2966
3082
  export declare function mergeBuildConfigOverrides(fromFile: BuildConfigOverrides, fromFirestore: BuildConfigOverrides | undefined): BuildConfigOverrides;
2967
3083
  /** True when merged hosting build config includes at least one build setting. */
2968
3084
  export declare function hasResolvableHostingBuildConfig(overrides?: BuildConfigOverrides): boolean;
3085
+ /**
3086
+ * Env vars every hosted deploy gets unless the project sets them itself.
3087
+ *
3088
+ * Recurring jobs default off because Agent Native ships a Netlify scheduled function
3089
+ * that wakes a background sweep every minute for the life of the deploy, even when the
3090
+ * app defines no jobs — enough to keep a scale-to-zero database from ever suspending.
3091
+ * Set `AGENT_NATIVE_DISABLE_RECURRING_JOBS=false` in the build env to opt back in.
3092
+ */
3093
+ export declare const HOSTED_DEPLOY_ENV_DEFAULTS: Readonly<Record<string, string>>;
3094
+ /**
3095
+ * Layer `HOSTED_DEPLOY_ENV_DEFAULTS` under a build config's env, project values winning.
3096
+ *
3097
+ * Call only after `hasResolvableHostingBuildConfig` — the defaults would otherwise make
3098
+ * a project with no hosting config look deployable. Keys are trimmed so a padded project
3099
+ * key still wins instead of sitting beside the default the build actually reads.
3100
+ */
3101
+ export declare function applyHostedBuildEnvDefaults(overrides: BuildConfigOverrides): BuildConfigOverrides;
3102
+ /**
3103
+ * What a build env resolved each `HOSTED_DEPLOY_ENV_DEFAULTS` key to. The deploy pod
3104
+ * sends this to the service so the runtime env matches what the build compiled against.
3105
+ *
3106
+ * Keys outside `HOSTED_DEPLOY_ENV_DEFAULTS` are dropped, so this is safe to call on an
3107
+ * env record that arrived in an event payload.
3108
+ */
3109
+ export declare function resolveHostedEnvDefaults(environment: Record<string, string> | undefined): Record<string, string>;
2969
3110
  /**
2970
3111
  * Request body for `POST /_builder.io/api/build-and-upload` on the deploy pod.
2971
3112
  */
@@ -3128,6 +3269,26 @@ export declare const GetDeploysResponseSchema: z.ZodObject<{
3128
3269
  }>;
3129
3270
  url: z.ZodOptional<z.ZodString>;
3130
3271
  error: z.ZodOptional<z.ZodString>;
3272
+ failure: z.ZodOptional<z.ZodObject<{
3273
+ stage: z.ZodOptional<z.ZodEnum<{
3274
+ build: "build";
3275
+ init: "init";
3276
+ migrate: "migrate";
3277
+ package: "package";
3278
+ setup: "setup";
3279
+ upload: "upload";
3280
+ }>>;
3281
+ owner: z.ZodEnum<{
3282
+ app: "app";
3283
+ platform: "platform";
3284
+ unknown: "unknown";
3285
+ }>;
3286
+ code: z.ZodString;
3287
+ summary: z.ZodString;
3288
+ exitCode: z.ZodOptional<z.ZodNumber>;
3289
+ signal: z.ZodOptional<z.ZodString>;
3290
+ fixRequested: z.ZodOptional<z.ZodBoolean>;
3291
+ }, z.core.$strip>>;
3131
3292
  createdAt: z.ZodNumber;
3132
3293
  completedAt: z.ZodOptional<z.ZodNumber>;
3133
3294
  }, z.core.$strip>>;
@@ -3631,10 +3792,11 @@ export declare const ProjectTemplateSchema: z.ZodObject<{
3631
3792
  "org-worker": "org-worker";
3632
3793
  "project-configuration": "project-configuration";
3633
3794
  "projects-scheduler-memory-extraction": "projects-scheduler-memory-extraction";
3795
+ "publish-agent": "publish-agent";
3634
3796
  "repo-indexing": "repo-indexing";
3635
3797
  "setup-project": "setup-project";
3636
3798
  unknown: "unknown";
3637
- }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
3799
+ }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "publish-agent-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
3638
3800
  needDevServer: z.ZodOptional<z.ZodBoolean>;
3639
3801
  needValidation: z.ZodOptional<z.ZodBoolean>;
3640
3802
  includeMemories: z.ZodOptional<z.ZodBoolean>;
@@ -4081,10 +4243,11 @@ export declare const ProjectTemplateOverridesSchema: z.ZodObject<{
4081
4243
  "org-worker": "org-worker";
4082
4244
  "project-configuration": "project-configuration";
4083
4245
  "projects-scheduler-memory-extraction": "projects-scheduler-memory-extraction";
4246
+ "publish-agent": "publish-agent";
4084
4247
  "repo-indexing": "repo-indexing";
4085
4248
  "setup-project": "setup-project";
4086
4249
  unknown: "unknown";
4087
- }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
4250
+ }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "publish-agent-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
4088
4251
  needDevServer: z.ZodOptional<z.ZodBoolean>;
4089
4252
  needValidation: z.ZodOptional<z.ZodBoolean>;
4090
4253
  includeMemories: z.ZodOptional<z.ZodBoolean>;
@@ -4487,10 +4650,11 @@ export declare const CreateProjectTemplateFromProjectOptionsSchema: z.ZodObject<
4487
4650
  "org-worker": "org-worker";
4488
4651
  "project-configuration": "project-configuration";
4489
4652
  "projects-scheduler-memory-extraction": "projects-scheduler-memory-extraction";
4653
+ "publish-agent": "publish-agent";
4490
4654
  "repo-indexing": "repo-indexing";
4491
4655
  "setup-project": "setup-project";
4492
4656
  unknown: "unknown";
4493
- }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
4657
+ }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "publish-agent-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
4494
4658
  needDevServer: z.ZodOptional<z.ZodBoolean>;
4495
4659
  needValidation: z.ZodOptional<z.ZodBoolean>;
4496
4660
  includeMemories: z.ZodOptional<z.ZodBoolean>;
package/src/projects.js CHANGED
@@ -62,6 +62,43 @@ export const matchesAgentNativeStarter = (repo) => {
62
62
  return true;
63
63
  return !!((_a = repo.templateRepoUrl) === null || _a === void 0 ? void 0 : _a.includes(AGENT_NATIVE_STARTER_REPO));
64
64
  };
65
+ function isStringRecord(value) {
66
+ return typeof value === "object" && value !== null && !Array.isArray(value);
67
+ }
68
+ export function getManagedDatabasePackageJsonError(content) {
69
+ let packageJson;
70
+ try {
71
+ packageJson = JSON.parse(content);
72
+ }
73
+ catch (_a) {
74
+ return "The managed database root package.json must remain valid JSON.";
75
+ }
76
+ if (!isStringRecord(packageJson)) {
77
+ return "The managed database root package.json must contain a JSON object.";
78
+ }
79
+ const dependencies = packageJson.dependencies;
80
+ const devDependencies = packageJson.devDependencies;
81
+ const hasDrizzleOrm = isStringRecord(dependencies) &&
82
+ typeof dependencies["drizzle-orm"] === "string";
83
+ const hasDrizzleKit = isStringRecord(devDependencies) &&
84
+ typeof devDependencies["drizzle-kit"] === "string";
85
+ if (hasDrizzleOrm && hasDrizzleKit) {
86
+ return undefined;
87
+ }
88
+ return ("Managed database projects require drizzle-orm in root dependencies and drizzle-kit " +
89
+ "in root devDependencies. Preserve both declarations when editing package.json.");
90
+ }
91
+ export function getAgentNativeRootPackageJsonWriteError(args) {
92
+ if (!matchesAgentNativeStarter(args.repo)) {
93
+ return undefined;
94
+ }
95
+ const normalizePath = (value) => value.replace(/\\/g, "/").replace(/\/$/, "");
96
+ const rootPackageJsonPath = `${normalizePath(args.repoPath)}/package.json`;
97
+ if (normalizePath(args.resolvedPath) !== rootPackageJsonPath) {
98
+ return undefined;
99
+ }
100
+ return getManagedDatabasePackageJsonError(args.content);
101
+ }
65
102
  export const EXAMPLE_OR_STARTER_REPOS = [
66
103
  ...EXAMPLE_REPOS,
67
104
  STARTER_REPO,
@@ -1193,6 +1230,44 @@ export const UpdateProjectOptionsSchema = z.object({
1193
1230
  /**
1194
1231
  * A single deploy record, stored at `deploys/{deployId}`. The Deploy.id is the document key.
1195
1232
  */
1233
+ /**
1234
+ * Pipeline step a deploy died at. Set by the pod, the only place that still
1235
+ * knows, so the server can attribute the failure without reading log text.
1236
+ */
1237
+ export const DeployFailureStageSchema = z.enum([
1238
+ "init",
1239
+ "setup",
1240
+ "migrate",
1241
+ "build",
1242
+ "package",
1243
+ "upload",
1244
+ ]);
1245
+ /** `app` is the only value that reaches the agent, so unknowns resolve away from it. */
1246
+ export const DeployFailureOwnerSchema = z.enum(["app", "platform", "unknown"]);
1247
+ /** What the deploy pod reports about a failure. All optional: older pods send none of it. */
1248
+ export const DeployFailureReportSchema = z.object({
1249
+ stage: DeployFailureStageSchema.optional(),
1250
+ exitCode: z.number().optional(),
1251
+ signal: z.string().optional(),
1252
+ excerpt: z.string().optional().meta({
1253
+ description: "Head-and-tail excerpt of the failing output, cut on line boundaries. Event only, never persisted.",
1254
+ }),
1255
+ });
1256
+ export const DeployFailureSchema = z.object({
1257
+ stage: DeployFailureStageSchema.optional(),
1258
+ owner: DeployFailureOwnerSchema,
1259
+ code: z.string().meta({
1260
+ description: "Classifier rule that produced the verdict, e.g. build-command-failed, build-killed, install-network.",
1261
+ }),
1262
+ summary: z.string().meta({
1263
+ description: "One line naming the failure, safe to render in a list row.",
1264
+ }),
1265
+ exitCode: z.number().optional(),
1266
+ signal: z.string().optional(),
1267
+ fixRequested: z.boolean().optional().meta({
1268
+ description: "Whether a Fusion agent fix was dispatched for this failure.",
1269
+ }),
1270
+ });
1196
1271
  export const DeploySchema = z.object({
1197
1272
  id: z.string(),
1198
1273
  projectId: z.string(),
@@ -1247,7 +1322,10 @@ export const DeploySchema = z.object({
1247
1322
  description: "Whether Drizzle migrations were applied during this deploy. Absent when no migration ran.",
1248
1323
  }),
1249
1324
  error: z.string().optional().meta({
1250
- description: "Single human-readable line on failure; raw build logs not surfaced in v0",
1325
+ description: "Head-and-tail excerpt of the failing step's output, ANSI stripped. Bounded because it rides in every deploy-list response.",
1326
+ }),
1327
+ failure: DeployFailureSchema.optional().meta({
1328
+ description: "Structured verdict for a failed deploy: which stage failed and whether the failure is the app's or ours. Absent on deploys from pods that predate it.",
1251
1329
  }),
1252
1330
  createdAt: z.number(),
1253
1331
  completedAt: z.number().optional(),
@@ -1255,6 +1333,19 @@ export const DeploySchema = z.object({
1255
1333
  description: 'user ID for manual publish, or "auto-deploy" (v1)',
1256
1334
  }),
1257
1335
  });
1336
+ /** Values of `Deploy.triggeredBy` that name no real user. */
1337
+ const UNATTENDED_DEPLOY_TRIGGERS = new Set(["auto-deploy", "unknown"]);
1338
+ /**
1339
+ * The user who asked for this deploy, or `undefined` when nobody did. Lives
1340
+ * with the schema so every caller that needs a real user agrees on what counts.
1341
+ */
1342
+ export function deployTriggeringUser(deploy) {
1343
+ var _a;
1344
+ const triggered = (_a = deploy.triggeredBy) === null || _a === void 0 ? void 0 : _a.trim();
1345
+ return triggered && !UNATTENDED_DEPLOY_TRIGGERS.has(triggered)
1346
+ ? triggered
1347
+ : undefined;
1348
+ }
1258
1349
  /**
1259
1350
  * Permanent slug reservation, stored at `hosting-slugs/{slug}` (slug is the document key).
1260
1351
  *
@@ -1348,6 +1439,7 @@ export const DeployListItemSchema = DeploySchema.pick({
1348
1439
  createdAt: true,
1349
1440
  completedAt: true,
1350
1441
  error: true,
1442
+ failure: true,
1351
1443
  checkoutBranch: true,
1352
1444
  checkoutCommit: true,
1353
1445
  builtCommit: true,
@@ -1482,6 +1574,60 @@ export function hasResolvableHostingBuildConfig(overrides) {
1482
1574
  }
1483
1575
  return false;
1484
1576
  }
1577
+ /**
1578
+ * Env vars every hosted deploy gets unless the project sets them itself.
1579
+ *
1580
+ * Recurring jobs default off because Agent Native ships a Netlify scheduled function
1581
+ * that wakes a background sweep every minute for the life of the deploy, even when the
1582
+ * app defines no jobs — enough to keep a scale-to-zero database from ever suspending.
1583
+ * Set `AGENT_NATIVE_DISABLE_RECURRING_JOBS=false` in the build env to opt back in.
1584
+ */
1585
+ export const HOSTED_DEPLOY_ENV_DEFAULTS = {
1586
+ AGENT_NATIVE_DISABLE_RECURRING_JOBS: "true",
1587
+ };
1588
+ /**
1589
+ * Layer `HOSTED_DEPLOY_ENV_DEFAULTS` under a build config's env, project values winning.
1590
+ *
1591
+ * Call only after `hasResolvableHostingBuildConfig` — the defaults would otherwise make
1592
+ * a project with no hosting config look deployable. Keys are trimmed so a padded project
1593
+ * key still wins instead of sitting beside the default the build actually reads.
1594
+ */
1595
+ export function applyHostedBuildEnvDefaults(overrides) {
1596
+ return {
1597
+ ...overrides,
1598
+ environment: {
1599
+ ...HOSTED_DEPLOY_ENV_DEFAULTS,
1600
+ ...normalizeEnvRecordKeys(overrides.environment),
1601
+ },
1602
+ };
1603
+ }
1604
+ /** Trim env keys and drop blank ones, so both env scopes compare keys the same way. */
1605
+ function normalizeEnvRecordKeys(environment) {
1606
+ const normalized = {};
1607
+ for (const [key, value] of Object.entries(environment !== null && environment !== void 0 ? environment : {})) {
1608
+ const trimmed = key.trim();
1609
+ if (trimmed) {
1610
+ normalized[trimmed] = value;
1611
+ }
1612
+ }
1613
+ return normalized;
1614
+ }
1615
+ /**
1616
+ * What a build env resolved each `HOSTED_DEPLOY_ENV_DEFAULTS` key to. The deploy pod
1617
+ * sends this to the service so the runtime env matches what the build compiled against.
1618
+ *
1619
+ * Keys outside `HOSTED_DEPLOY_ENV_DEFAULTS` are dropped, so this is safe to call on an
1620
+ * env record that arrived in an event payload.
1621
+ */
1622
+ export function resolveHostedEnvDefaults(environment) {
1623
+ const resolved = {};
1624
+ for (const [key, value] of Object.entries(normalizeEnvRecordKeys(environment))) {
1625
+ if (Object.hasOwn(HOSTED_DEPLOY_ENV_DEFAULTS, key)) {
1626
+ resolved[key] = value;
1627
+ }
1628
+ }
1629
+ return resolved;
1630
+ }
1485
1631
  /**
1486
1632
  * Request body for `POST /_builder.io/api/build-and-upload` on the deploy pod.
1487
1633
  */
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { AGENT_NATIVE_STARTER_REPO, matchesAgentNativeStarter, ProjectHostingExternalSchema, ProjectHostingSchema, } from "./projects";
2
+ import { AGENT_NATIVE_STARTER_REPO, getAgentNativeRootPackageJsonWriteError, getManagedDatabasePackageJsonError, matchesAgentNativeStarter, ProjectHostingExternalSchema, ProjectHostingSchema, } from "./projects";
3
3
  describe("project hosting schemas", () => {
4
4
  it("accepts the canonical published branch route", () => {
5
5
  expect(ProjectHostingSchema.parse({ publishedBranchId: "branch-live" })).toEqual({ publishedBranchId: "branch-live" });
@@ -31,3 +31,59 @@ describe("matchesAgentNativeStarter", () => {
31
31
  expect(matchesAgentNativeStarter({})).toBe(false);
32
32
  });
33
33
  });
34
+ describe("getManagedDatabasePackageJsonError", () => {
35
+ it("accepts the required root Drizzle dependencies", () => {
36
+ expect(getManagedDatabasePackageJsonError(JSON.stringify({
37
+ dependencies: { "drizzle-orm": "0.45.2" },
38
+ devDependencies: { "drizzle-kit": "0.31.10" },
39
+ }))).toBeUndefined();
40
+ });
41
+ it.each([
42
+ {
43
+ dependencies: {},
44
+ devDependencies: { "drizzle-kit": "0.31.10" },
45
+ },
46
+ {
47
+ dependencies: { "drizzle-orm": "0.45.2", "drizzle-kit": "0.31.10" },
48
+ devDependencies: {},
49
+ },
50
+ {
51
+ dependencies: {},
52
+ devDependencies: {
53
+ "drizzle-orm": "0.45.2",
54
+ "drizzle-kit": "0.31.10",
55
+ },
56
+ },
57
+ ])("rejects missing or misplaced dependencies", (packageJson) => {
58
+ expect(getManagedDatabasePackageJsonError(JSON.stringify(packageJson))).toContain("Preserve both declarations");
59
+ });
60
+ it("rejects invalid package.json content", () => {
61
+ expect(getManagedDatabasePackageJsonError("not json")).toContain("valid JSON");
62
+ });
63
+ });
64
+ describe("getAgentNativeRootPackageJsonWriteError", () => {
65
+ const repo = { repoName: AGENT_NATIVE_STARTER_REPO };
66
+ const invalidManifest = JSON.stringify({ dependencies: {} });
67
+ it("rejects an invalid resolved root manifest", () => {
68
+ expect(getAgentNativeRootPackageJsonWriteError({
69
+ repo,
70
+ repoPath: "/workspace",
71
+ resolvedPath: "/workspace/package.json",
72
+ content: invalidManifest,
73
+ })).toContain("drizzle-orm");
74
+ });
75
+ it("allows nested and unrelated repository manifests", () => {
76
+ expect(getAgentNativeRootPackageJsonWriteError({
77
+ repo,
78
+ repoPath: "/workspace",
79
+ resolvedPath: "/workspace/apps/web/package.json",
80
+ content: invalidManifest,
81
+ })).toBeUndefined();
82
+ expect(getAgentNativeRootPackageJsonWriteError({
83
+ repo: { repoName: "acme/dashboard" },
84
+ repoPath: "/workspace",
85
+ resolvedPath: "/workspace/package.json",
86
+ content: invalidManifest,
87
+ })).toBeUndefined();
88
+ });
89
+ });