@agent-native/core 0.146.0 → 0.146.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.
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/analytics/actions/compose-dashboard.ts +2 -27
- package/corpus/templates/analytics/actions/get-sql-dashboard.ts +7 -8
- package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +18 -2
- package/corpus/templates/analytics/actions/mutate-dashboard.ts +16 -24
- package/corpus/templates/analytics/actions/rename-dashboard.ts +2 -24
- package/corpus/templates/analytics/actions/reorder-dashboard-panels.ts +2 -24
- package/corpus/templates/analytics/actions/restore-dashboard-revision.ts +2 -25
- package/corpus/templates/analytics/actions/update-dashboard.ts +4 -32
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +1 -40
- package/corpus/templates/analytics/changelog/2026-08-07-language-selection-now-lives-in-settings-instead-of-the-comm.md +6 -0
- package/corpus/templates/analytics/netlify.toml +7 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +13 -13
- package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +4 -2
- package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +0 -35
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +5 -3
- package/corpus/templates/analytics/server/lib/dashboard-collab-sync.ts +77 -0
- package/corpus/templates/analytics/server/lib/demo-dashboards.ts +2 -23
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +28 -74
- package/corpus/templates/analytics/server/routes/api/dashboard-agent-context.json.get.ts +5 -9
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/assets/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/clips/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +1 -1
- package/corpus/templates/clips/changelog/2026-08-07-fixed-trimmed-clips-durations-so-the-main-player-display-mat.md +6 -0
- package/corpus/templates/clips/chrome-extension/STORE_DRAFT.md +1 -1
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/content/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/crm/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/design/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/dispatch/changelog/2026-08-07-language-selection-now-lives-in-settings-instead-of-the-disp.md +6 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +59 -22
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/forms/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/macros/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/mail/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +10 -1
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +10 -3
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/slides/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/corpus/templates/slides/actions/generate-image-api.ts +123 -0
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -2
- package/corpus/templates/slides/app/components/editor/ImageGenPanel.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-08-07-deleting-a-deck-no-longer-freezes-the-slides-browser.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-07-slides-verify-generated-images-are-persisted-on-the-target-s.md +6 -0
- package/corpus/templates/slides/server/lib/slide-image-insertion.ts +141 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/dist/client/AgentPanel.d.ts +10 -4
- package/dist/client/AgentPanel.js +29 -82
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/migrations.js +22 -4
- package/dist/deploy/build.d.ts +1 -0
- package/dist/deploy/build.js +27 -22
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/builder-browser.d.ts +34 -0
- package/dist/server/builder-browser.js +179 -0
- package/dist/server/core-routes-plugin.d.ts +5 -0
- package/dist/server/core-routes-plugin.js +24 -8
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/shared/cache-control.d.ts +2 -2
- package/dist/shared/cache-control.js +2 -2
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/dist/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/dist/vite/client.js +13 -1
- package/docs/content/drop-in-agent.mdx +3 -3
- package/docs/content/getting-started-actions.mdx +1 -2
- package/docs/content/getting-started-pages.mdx +1 -2
- package/docs/content/getting-started.mdx +0 -4
- package/docs/content/what-is-agent-native.mdx +4 -4
- package/package.json +3 -3
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/src/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/src/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/src/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +4 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +8 -0
- package/docs/content/getting-started-database.mdx +0 -173
package/dist/deploy/build.js
CHANGED
|
@@ -23,7 +23,7 @@ import { INTEGRATION_RECOVERY_RUNTIME_MARKER, INTEGRATION_RETRY_SWEEP_PATH, INTE
|
|
|
23
23
|
import { isValidCron } from "../jobs/cron.js";
|
|
24
24
|
import { RECURRING_JOBS_SWEEP_PATH, RECURRING_JOBS_SWEEP_TOKEN_SUBJECT, } from "../jobs/scheduler-dispatch.js";
|
|
25
25
|
import { normalizeAppBasePath } from "../server/app-base-path.js";
|
|
26
|
-
import { DEFAULT_SPECULATION_RULES_PATH, resolveSsrCacheHeaders, } from "../shared/cache-control.js";
|
|
26
|
+
import { DEFAULT_SPECULATION_RULES_PATH, resolveSsrCacheHeaders, resolveSsrCacheKeyHeaders, } from "../shared/cache-control.js";
|
|
27
27
|
import { mcpEmbedStaticAssetRouteRules } from "../shared/mcp-embed-headers.js";
|
|
28
28
|
import { AGENT_NATIVE_SOCIAL_IMAGE_ALT, AGENT_NATIVE_SOCIAL_IMAGE_CACHE_BUSTER, AGENT_NATIVE_SOCIAL_IMAGE_HEIGHT, AGENT_NATIVE_SOCIAL_IMAGE_PATH, AGENT_NATIVE_SOCIAL_IMAGE_TYPE, AGENT_NATIVE_SOCIAL_IMAGE_WIDTH, } from "../shared/social-meta.js";
|
|
29
29
|
import { generateActionRegistryForProject } from "../vite/action-types-plugin.js";
|
|
@@ -652,6 +652,7 @@ export function generateWorkerEntry(routes, pluginPaths, defaultPluginStems = []
|
|
|
652
652
|
// The worker ships as a static bundle with no access to runtime env, so the
|
|
653
653
|
// deployment-wide SSR cache policy is baked in from this build's env.
|
|
654
654
|
const ssrCacheHeaders = resolveSsrCacheHeaders();
|
|
655
|
+
const ssrCacheKeyHeaders = resolveSsrCacheKeyHeaders();
|
|
655
656
|
const routeImports = [];
|
|
656
657
|
const routeRegistrations = [];
|
|
657
658
|
for (let i = 0; i < routes.length; i++) {
|
|
@@ -971,9 +972,8 @@ function injectHeadScript(html, script) {
|
|
|
971
972
|
}
|
|
972
973
|
|
|
973
974
|
// Resolved from AGENT_NATIVE_SSR_CACHE at build time.
|
|
974
|
-
const
|
|
975
|
-
const
|
|
976
|
-
const SSR_NETLIFY_CDN_CACHE_CONTROL = ${JSON.stringify(ssrCacheHeaders["netlify-cdn-cache-control"])};
|
|
975
|
+
const SSR_CACHE_HEADERS = ${JSON.stringify(ssrCacheHeaders)};
|
|
976
|
+
const SSR_CACHE_KEY_HEADERS = ${JSON.stringify(ssrCacheKeyHeaders)};
|
|
977
977
|
const DEFAULT_SPECULATION_RULES_PATH = ${JSON.stringify(DEFAULT_SPECULATION_RULES_PATH)};
|
|
978
978
|
const IMMUTABLE_ASSET_CACHE_CONTROL = ${JSON.stringify(IMMUTABLE_ASSET_CACHE_CONTROL)};
|
|
979
979
|
const IMMUTABLE_ASSET_PATHS = new Set(${JSON.stringify([...new Set(immutableAssetPaths)].sort())});
|
|
@@ -1057,13 +1057,12 @@ function applyDefaultSsrCacheHeader(headers, status, pathname) {
|
|
|
1057
1057
|
else headers.delete("vary");
|
|
1058
1058
|
}
|
|
1059
1059
|
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
headers.set("netlify-cdn-cache-control", SSR_NETLIFY_CDN_CACHE_CONTROL);
|
|
1060
|
+
for (const [name, value] of Object.entries(SSR_CACHE_HEADERS)) {
|
|
1061
|
+
headers.set(name, value);
|
|
1062
|
+
}
|
|
1063
|
+
for (const [name, value] of Object.entries(SSR_CACHE_KEY_HEADERS)) {
|
|
1064
|
+
headers.set(name, value);
|
|
1065
|
+
}
|
|
1067
1066
|
}
|
|
1068
1067
|
|
|
1069
1068
|
function applyDefaultSpeculationRulesHeader(headers, status, basePath) {
|
|
@@ -3464,6 +3463,22 @@ function createBrowserOnlyServerStubPlugin() {
|
|
|
3464
3463
|
},
|
|
3465
3464
|
};
|
|
3466
3465
|
}
|
|
3466
|
+
export function resolveNitroBuildReplacements(env = process.env) {
|
|
3467
|
+
return {
|
|
3468
|
+
// Netlify exposes DEPLOY_ID only while building. Embed it into the Nitro
|
|
3469
|
+
// function so preview OAuth relays can target this immutable deployment
|
|
3470
|
+
// even though the value is unavailable in the function runtime.
|
|
3471
|
+
"process.env.AGENT_NATIVE_BUILD_ID": JSON.stringify(env.DEPLOY_ID?.trim() || env.AGENT_NATIVE_BUILD_ID?.trim() || ""),
|
|
3472
|
+
"process.env.AGENT_NATIVE_BUILD_GA_MEASUREMENT_ID": JSON.stringify(env.GA_MEASUREMENT_ID?.trim() || ""),
|
|
3473
|
+
"process.env.AGENT_NATIVE_BUILD_GTM_CONTAINER_ID": JSON.stringify(env.GTM_CONTAINER_ID?.trim() || ""),
|
|
3474
|
+
// Netlify's netlify.toml environment is available while this deploy
|
|
3475
|
+
// build runs, but is not injected into the deployed Function. Nitro is
|
|
3476
|
+
// a separate server build, so embed release migration ownership here as
|
|
3477
|
+
// well as in the Vite server bundle.
|
|
3478
|
+
"process.env.AGENT_NATIVE_RELEASE_MIGRATIONS": JSON.stringify(env.AGENT_NATIVE_RELEASE_MIGRATIONS?.trim() || ""),
|
|
3479
|
+
"process.env.AGENT_NATIVE_BUILD_DEPLOY_CONTEXT": JSON.stringify(env.CONTEXT?.trim() || ""),
|
|
3480
|
+
};
|
|
3481
|
+
}
|
|
3467
3482
|
async function buildWithNitro() {
|
|
3468
3483
|
console.log(`[deploy] Building for preset "${preset}" via Nitro...`);
|
|
3469
3484
|
const appBasePath = normalizeConfiguredAppBasePath();
|
|
@@ -3547,17 +3562,7 @@ export default bundle;
|
|
|
3547
3562
|
virtual: {
|
|
3548
3563
|
"virtual:agents-bundle": agentsBundleModuleSource,
|
|
3549
3564
|
},
|
|
3550
|
-
replace:
|
|
3551
|
-
// Netlify exposes DEPLOY_ID only while building. Embed it into the Nitro
|
|
3552
|
-
// function so preview OAuth relays can target this immutable deployment
|
|
3553
|
-
// even though the value is unavailable in the function runtime.
|
|
3554
|
-
"process.env.AGENT_NATIVE_BUILD_ID": JSON.stringify(process.env.DEPLOY_ID?.trim() ||
|
|
3555
|
-
process.env.AGENT_NATIVE_BUILD_ID?.trim() ||
|
|
3556
|
-
""),
|
|
3557
|
-
"process.env.AGENT_NATIVE_BUILD_GA_MEASUREMENT_ID": JSON.stringify(process.env.GA_MEASUREMENT_ID?.trim() || ""),
|
|
3558
|
-
"process.env.AGENT_NATIVE_BUILD_GTM_CONTAINER_ID": JSON.stringify(process.env.GTM_CONTAINER_ID?.trim() || ""),
|
|
3559
|
-
"process.env.AGENT_NATIVE_BUILD_DEPLOY_CONTEXT": JSON.stringify(process.env.CONTEXT?.trim() || ""),
|
|
3560
|
-
},
|
|
3565
|
+
replace: resolveNitroBuildReplacements(),
|
|
3561
3566
|
// Replace browser-only renderers (Excalidraw/Mermaid) with an inert proxy in
|
|
3562
3567
|
// the server bundle. Without this, Nitro's Rolldown build pulls the real
|
|
3563
3568
|
// Excalidraw into a shared vendor chunk imported statically by the SSR render
|
|
@@ -17,11 +17,11 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
17
17
|
id?: undefined;
|
|
18
18
|
provider?: undefined;
|
|
19
19
|
} | {
|
|
20
|
+
error?: undefined;
|
|
20
21
|
configured?: undefined;
|
|
21
22
|
connectPath?: undefined;
|
|
22
23
|
url: string;
|
|
23
24
|
id: string;
|
|
24
25
|
provider: string;
|
|
25
|
-
error?: undefined;
|
|
26
26
|
}>;
|
|
27
27
|
export default _default;
|
|
@@ -48,8 +48,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
|
|
|
48
48
|
}>;
|
|
49
49
|
/** DELETE /_agent-native/resources/:id — delete a resource */
|
|
50
50
|
export declare function handleDeleteResource(event: any): Promise<{
|
|
51
|
-
error: string;
|
|
52
51
|
ok?: undefined;
|
|
52
|
+
error: string;
|
|
53
53
|
} | {
|
|
54
54
|
error?: undefined;
|
|
55
55
|
ok: boolean;
|
|
@@ -328,6 +328,40 @@ export interface RunBuilderAgentResult {
|
|
|
328
328
|
url: string;
|
|
329
329
|
status: string;
|
|
330
330
|
}
|
|
331
|
+
export interface BuilderProjectLookupArgs {
|
|
332
|
+
repoUrl: string;
|
|
333
|
+
}
|
|
334
|
+
export interface BuilderProjectResult {
|
|
335
|
+
projectId: string;
|
|
336
|
+
name: string;
|
|
337
|
+
repoUrl: string;
|
|
338
|
+
browserUrl: string;
|
|
339
|
+
created: boolean;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Find an existing Builder project connected to a repository. Dispatch uses
|
|
343
|
+
* this before provisioning so a first app request cannot create a duplicate
|
|
344
|
+
* workspace project when the project id has not been saved yet.
|
|
345
|
+
*/
|
|
346
|
+
export declare function findBuilderProjectForRepo(args: BuilderProjectLookupArgs): Promise<BuilderProjectResult | null>;
|
|
347
|
+
/**
|
|
348
|
+
* Create a Builder project connected to a repository through the public
|
|
349
|
+
* projects API. This is the server-side bridge used by Dispatch; online
|
|
350
|
+
* Claude and ChatGPT hosts do not need a separate Builder CMS MCP connector.
|
|
351
|
+
*/
|
|
352
|
+
export declare function createBuilderProject(args: {
|
|
353
|
+
name: string;
|
|
354
|
+
repoUrl: string;
|
|
355
|
+
}): Promise<BuilderProjectResult>;
|
|
356
|
+
/**
|
|
357
|
+
* Reuse a connected Builder project or create it once when Dispatch is first
|
|
358
|
+
* used for a workspace. The lookup and create calls intentionally stay in
|
|
359
|
+
* this shared server helper so all callers use the same authenticated path.
|
|
360
|
+
*/
|
|
361
|
+
export declare function ensureBuilderProject(args: {
|
|
362
|
+
name: string;
|
|
363
|
+
repoUrl: string;
|
|
364
|
+
}): Promise<BuilderProjectResult>;
|
|
331
365
|
/**
|
|
332
366
|
* POST a prompt to the Builder agents-run API. The Builder agent runs in a
|
|
333
367
|
* cloud sandbox and writes code to a branch; the returned URL opens that
|
|
@@ -1283,6 +1283,185 @@ function normalizeBuilderApiString(value, fieldName) {
|
|
|
1283
1283
|
}
|
|
1284
1284
|
return trimmed;
|
|
1285
1285
|
}
|
|
1286
|
+
function normalizeBuilderProjectString(value, fieldName) {
|
|
1287
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
1288
|
+
throw new Error(`Builder project response returned a blank ${fieldName}`);
|
|
1289
|
+
}
|
|
1290
|
+
const trimmed = value.trim();
|
|
1291
|
+
if (/[\u0000-\u001f\u007f]/.test(trimmed)) {
|
|
1292
|
+
throw new Error(`Builder project response returned a malformed ${fieldName}`);
|
|
1293
|
+
}
|
|
1294
|
+
return trimmed;
|
|
1295
|
+
}
|
|
1296
|
+
function normalizeBuilderRepoUrl(value) {
|
|
1297
|
+
const trimmed = value.trim();
|
|
1298
|
+
let parsed;
|
|
1299
|
+
try {
|
|
1300
|
+
parsed = new URL(trimmed);
|
|
1301
|
+
}
|
|
1302
|
+
catch {
|
|
1303
|
+
throw new Error("Builder project repository URL is malformed");
|
|
1304
|
+
}
|
|
1305
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
1306
|
+
throw new Error("Builder project repository URL must use HTTP or HTTPS");
|
|
1307
|
+
}
|
|
1308
|
+
return trimmed;
|
|
1309
|
+
}
|
|
1310
|
+
function comparableBuilderRepoUrl(value) {
|
|
1311
|
+
try {
|
|
1312
|
+
const parsed = new URL(value);
|
|
1313
|
+
const pathname = parsed.pathname.replace(/\/+$/, "").replace(/\.git$/, "");
|
|
1314
|
+
return `${parsed.hostname.toLowerCase()}${pathname.toLowerCase()}`;
|
|
1315
|
+
}
|
|
1316
|
+
catch {
|
|
1317
|
+
return value
|
|
1318
|
+
.trim()
|
|
1319
|
+
.replace(/\/+$/, "")
|
|
1320
|
+
.replace(/\.git$/, "")
|
|
1321
|
+
.toLowerCase();
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
function builderProjectBrowserUrl(projectId) {
|
|
1325
|
+
return `${getBuilderAppHost().replace(/\/$/, "")}/app/projects/${encodeURIComponent(projectId)}`;
|
|
1326
|
+
}
|
|
1327
|
+
function builderProjectFromRecord(value, fallbackRepoUrl, created) {
|
|
1328
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
1329
|
+
return null;
|
|
1330
|
+
const record = value;
|
|
1331
|
+
const projectId = typeof record.id === "string" && record.id.trim() ? record.id.trim() : null;
|
|
1332
|
+
if (!projectId)
|
|
1333
|
+
return null;
|
|
1334
|
+
const name = typeof record.name === "string" && record.name.trim()
|
|
1335
|
+
? record.name.trim()
|
|
1336
|
+
: "Agent-Native Workspace";
|
|
1337
|
+
const repoUrl = typeof record.repoUrl === "string" && record.repoUrl.trim()
|
|
1338
|
+
? record.repoUrl.trim()
|
|
1339
|
+
: fallbackRepoUrl;
|
|
1340
|
+
if (!repoUrl)
|
|
1341
|
+
return null;
|
|
1342
|
+
return {
|
|
1343
|
+
projectId: normalizeBuilderProjectString(projectId, "project id"),
|
|
1344
|
+
name: normalizeBuilderProjectString(name, "project name"),
|
|
1345
|
+
repoUrl: normalizeBuilderRepoUrl(repoUrl),
|
|
1346
|
+
browserUrl: builderProjectBrowserUrl(projectId),
|
|
1347
|
+
created,
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
async function resolveBuilderApiCredentials() {
|
|
1351
|
+
const { resolveBuilderCredentials } = await import("./credential-provider.js");
|
|
1352
|
+
const creds = await resolveBuilderCredentials();
|
|
1353
|
+
if (!creds.privateKey || !creds.publicKey) {
|
|
1354
|
+
throw new Error("Builder keys are not configured");
|
|
1355
|
+
}
|
|
1356
|
+
return {
|
|
1357
|
+
...creds,
|
|
1358
|
+
privateKey: creds.privateKey,
|
|
1359
|
+
publicKey: creds.publicKey,
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
async function readBuilderApiObject(response, operation) {
|
|
1363
|
+
let parsed;
|
|
1364
|
+
try {
|
|
1365
|
+
parsed = await response.json();
|
|
1366
|
+
}
|
|
1367
|
+
catch (error) {
|
|
1368
|
+
throw new Error("Builder " +
|
|
1369
|
+
operation +
|
|
1370
|
+
" returned an invalid JSON response (" +
|
|
1371
|
+
response.status +
|
|
1372
|
+
")", { cause: error });
|
|
1373
|
+
}
|
|
1374
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1375
|
+
throw new Error("Builder " +
|
|
1376
|
+
operation +
|
|
1377
|
+
" returned an invalid JSON response (" +
|
|
1378
|
+
response.status +
|
|
1379
|
+
")");
|
|
1380
|
+
}
|
|
1381
|
+
return parsed;
|
|
1382
|
+
}
|
|
1383
|
+
function builderApiErrorMessage(parsed, fallback) {
|
|
1384
|
+
if (typeof parsed.error === "string" && parsed.error.trim()) {
|
|
1385
|
+
return parsed.error.trim();
|
|
1386
|
+
}
|
|
1387
|
+
if (typeof parsed.message === "string" && parsed.message.trim()) {
|
|
1388
|
+
return parsed.message.trim();
|
|
1389
|
+
}
|
|
1390
|
+
return fallback;
|
|
1391
|
+
}
|
|
1392
|
+
/**
|
|
1393
|
+
* Find an existing Builder project connected to a repository. Dispatch uses
|
|
1394
|
+
* this before provisioning so a first app request cannot create a duplicate
|
|
1395
|
+
* workspace project when the project id has not been saved yet.
|
|
1396
|
+
*/
|
|
1397
|
+
export async function findBuilderProjectForRepo(args) {
|
|
1398
|
+
const repoUrl = normalizeBuilderRepoUrl(args.repoUrl);
|
|
1399
|
+
const creds = await resolveBuilderApiCredentials();
|
|
1400
|
+
const url = new URL("/projects", getBuilderApiHost());
|
|
1401
|
+
url.searchParams.set("apiKey", creds.publicKey);
|
|
1402
|
+
url.searchParams.set("includeHidden", "true");
|
|
1403
|
+
const response = await fetch(url, {
|
|
1404
|
+
method: "GET",
|
|
1405
|
+
headers: { Authorization: `Bearer ${creds.privateKey}` },
|
|
1406
|
+
});
|
|
1407
|
+
const parsed = await readBuilderApiObject(response, "project lookup");
|
|
1408
|
+
if (!response.ok) {
|
|
1409
|
+
throw new Error(builderApiErrorMessage(parsed, `Builder project lookup failed (${response.status})`));
|
|
1410
|
+
}
|
|
1411
|
+
if (!Array.isArray(parsed.projects)) {
|
|
1412
|
+
throw new Error("Builder project lookup returned no projects list");
|
|
1413
|
+
}
|
|
1414
|
+
const comparableRepoUrl = comparableBuilderRepoUrl(repoUrl);
|
|
1415
|
+
for (const project of parsed.projects) {
|
|
1416
|
+
const normalized = builderProjectFromRecord(project, null, false);
|
|
1417
|
+
if (normalized &&
|
|
1418
|
+
comparableBuilderRepoUrl(normalized.repoUrl) === comparableRepoUrl) {
|
|
1419
|
+
return normalized;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
return null;
|
|
1423
|
+
}
|
|
1424
|
+
/**
|
|
1425
|
+
* Create a Builder project connected to a repository through the public
|
|
1426
|
+
* projects API. This is the server-side bridge used by Dispatch; online
|
|
1427
|
+
* Claude and ChatGPT hosts do not need a separate Builder CMS MCP connector.
|
|
1428
|
+
*/
|
|
1429
|
+
export async function createBuilderProject(args) {
|
|
1430
|
+
const name = normalizeBuilderProjectString(args.name, "project name");
|
|
1431
|
+
const repoUrl = normalizeBuilderRepoUrl(args.repoUrl);
|
|
1432
|
+
const creds = await resolveBuilderApiCredentials();
|
|
1433
|
+
const url = new URL("/projects/create", getBuilderApiHost());
|
|
1434
|
+
url.searchParams.set("apiKey", creds.publicKey);
|
|
1435
|
+
const response = await fetch(url, {
|
|
1436
|
+
method: "POST",
|
|
1437
|
+
headers: {
|
|
1438
|
+
Authorization: `Bearer ${creds.privateKey}`,
|
|
1439
|
+
"Content-Type": "application/json",
|
|
1440
|
+
},
|
|
1441
|
+
body: JSON.stringify({
|
|
1442
|
+
source: { kind: "repo", repoUrl },
|
|
1443
|
+
name,
|
|
1444
|
+
}),
|
|
1445
|
+
});
|
|
1446
|
+
const parsed = await readBuilderApiObject(response, "project creation");
|
|
1447
|
+
if (!response.ok) {
|
|
1448
|
+
throw new Error(builderApiErrorMessage(parsed, `Builder project creation failed (${response.status})`));
|
|
1449
|
+
}
|
|
1450
|
+
const project = builderProjectFromRecord(parsed.project, repoUrl, true);
|
|
1451
|
+
if (!project) {
|
|
1452
|
+
throw new Error("Builder project creation returned no project id");
|
|
1453
|
+
}
|
|
1454
|
+
return project;
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* Reuse a connected Builder project or create it once when Dispatch is first
|
|
1458
|
+
* used for a workspace. The lookup and create calls intentionally stay in
|
|
1459
|
+
* this shared server helper so all callers use the same authenticated path.
|
|
1460
|
+
*/
|
|
1461
|
+
export async function ensureBuilderProject(args) {
|
|
1462
|
+
const existing = await findBuilderProjectForRepo({ repoUrl: args.repoUrl });
|
|
1463
|
+
return existing ?? createBuilderProject(args);
|
|
1464
|
+
}
|
|
1286
1465
|
function normalizeBuilderBranchUrl(value) {
|
|
1287
1466
|
const urlString = normalizeBuilderApiString(value, "url");
|
|
1288
1467
|
let parsed;
|
|
@@ -288,6 +288,11 @@ interface LegacyCoreRouteInitSettings {
|
|
|
288
288
|
}
|
|
289
289
|
type CoreRouteSettingReader = (key: string) => Promise<Record<string, unknown> | null>;
|
|
290
290
|
export declare function readLegacyCoreRouteInitSettings(readSetting?: CoreRouteSettingReader): Promise<LegacyCoreRouteInitSettings>;
|
|
291
|
+
/**
|
|
292
|
+
* Production release jobs own schema setup. Request functions must not spend
|
|
293
|
+
* their cold-start budget on legacy cleanup or best-effort table warmups.
|
|
294
|
+
*/
|
|
295
|
+
export declare function shouldRunCoreRouteBootDatabaseWork(env?: NodeJS.ProcessEnv): boolean;
|
|
291
296
|
export declare function createCoreRoutesPlugin(options?: CoreRoutesPluginOptions): NitroPluginDef;
|
|
292
297
|
/**
|
|
293
298
|
* Default core routes plugin — mount with no configuration needed.
|
|
@@ -8,7 +8,7 @@ import { canUpdateAgentLoopSettings, readAgentLoopSettings, resetAgentLoopSettin
|
|
|
8
8
|
import { getState, putState, deleteState, listComposeDrafts, getComposeDraft, putComposeDraft, deleteComposeDraft, deleteAllComposeDrafts, getStateMany, } from "../application-state/handlers.js";
|
|
9
9
|
import { mountBrowserSessionRoutes } from "../browser-sessions/routes.js";
|
|
10
10
|
import { mountDbAdminRoutes } from "../db-admin/routes.js";
|
|
11
|
-
import { getDbExec } from "../db/client.js";
|
|
11
|
+
import { getDbExec, isProductionServerlessFunctionRuntime, } from "../db/client.js";
|
|
12
12
|
import { getDatabaseRuntimeFingerprint, getRuntimeDebugFingerprint, runDatabaseSchemaHealthCheck, } from "../db/runtime-diagnostics.js";
|
|
13
13
|
import { ssrfSafeFetch } from "../extensions/url-safety.js";
|
|
14
14
|
import { uploadFile, getActiveFileUploadProviderForRequest, listFileUploadProviders, } from "../file-upload/index.js";
|
|
@@ -814,6 +814,13 @@ export async function readLegacyCoreRouteInitSettings(readSetting = getSetting)
|
|
|
814
814
|
builderDisconnected: builderDisconnected,
|
|
815
815
|
};
|
|
816
816
|
}
|
|
817
|
+
/**
|
|
818
|
+
* Production release jobs own schema setup. Request functions must not spend
|
|
819
|
+
* their cold-start budget on legacy cleanup or best-effort table warmups.
|
|
820
|
+
*/
|
|
821
|
+
export function shouldRunCoreRouteBootDatabaseWork(env = process.env) {
|
|
822
|
+
return !isProductionServerlessFunctionRuntime(env);
|
|
823
|
+
}
|
|
817
824
|
/**
|
|
818
825
|
* Creates a Nitro plugin that mounts all standard agent-native framework routes.
|
|
819
826
|
*
|
|
@@ -913,7 +920,10 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
913
920
|
return EMPTY_SPECULATION_RULES;
|
|
914
921
|
}));
|
|
915
922
|
await awaitBootstrap(nitroApp);
|
|
916
|
-
const
|
|
923
|
+
const runBootDatabaseWork = shouldRunCoreRouteBootDatabaseWork();
|
|
924
|
+
const { persistedEnvVars, builderDisconnected } = runBootDatabaseWork
|
|
925
|
+
? await readLegacyCoreRouteInitSettings()
|
|
926
|
+
: { persistedEnvVars: null, builderDisconnected: null };
|
|
917
927
|
// Legacy cleanup: key saves now go to scoped app_secrets rows. Do not
|
|
918
928
|
// rehydrate the old deployment-global `persisted-env-vars` row into
|
|
919
929
|
// process.env; keep only the Builder scrub so stale leaked keys self-heal.
|
|
@@ -996,7 +1006,8 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
996
1006
|
try {
|
|
997
1007
|
const { createObservabilityHandler } = await import("../observability/routes.js");
|
|
998
1008
|
const { ensureObservabilityTables } = await import("../observability/store.js");
|
|
999
|
-
|
|
1009
|
+
if (runBootDatabaseWork)
|
|
1010
|
+
ensureObservabilityTables().catch(() => { });
|
|
1000
1011
|
getH3App(nitroApp).use(`${FRAMEWORK_ROUTE_PREFIX}/observability`, createObservabilityHandler());
|
|
1001
1012
|
}
|
|
1002
1013
|
catch {
|
|
@@ -1009,8 +1020,10 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1009
1020
|
try {
|
|
1010
1021
|
const { ensureAuditTables } = await import("../audit/store.js");
|
|
1011
1022
|
const { startAuditCleanupJob } = await import("../audit/cleanup-job.js");
|
|
1012
|
-
|
|
1013
|
-
|
|
1023
|
+
if (runBootDatabaseWork) {
|
|
1024
|
+
ensureAuditTables().catch(() => { });
|
|
1025
|
+
startAuditCleanupJob();
|
|
1026
|
+
}
|
|
1014
1027
|
}
|
|
1015
1028
|
catch {
|
|
1016
1029
|
// Audit module not available — skip
|
|
@@ -2880,7 +2893,8 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2880
2893
|
try {
|
|
2881
2894
|
const { ensureExtensionsTables, registerExtensionsShareable } = await import("../extensions/store.js");
|
|
2882
2895
|
const { createExtensionsHandler } = await import("../extensions/routes.js");
|
|
2883
|
-
|
|
2896
|
+
if (runBootDatabaseWork)
|
|
2897
|
+
ensureExtensionsTables().catch(() => { });
|
|
2884
2898
|
registerExtensionsShareable();
|
|
2885
2899
|
const extensionsHandler = createExtensionsHandler({
|
|
2886
2900
|
extensionTools: options.extensionTools,
|
|
@@ -2893,7 +2907,8 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2893
2907
|
// Extension-point slots — sub-system of extensions.
|
|
2894
2908
|
const { ensureSlotTables } = await import("../extensions/slots/store.js");
|
|
2895
2909
|
const { createSlotsHandler } = await import("../extensions/slots/routes.js");
|
|
2896
|
-
|
|
2910
|
+
if (runBootDatabaseWork)
|
|
2911
|
+
ensureSlotTables().catch(() => { });
|
|
2897
2912
|
getH3App(nitroApp).use(`${P}/slots`, createSlotsHandler());
|
|
2898
2913
|
}
|
|
2899
2914
|
catch {
|
|
@@ -2902,7 +2917,8 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2902
2917
|
// ─── Data programs (stored server-side JS scripts + run cache) ─────
|
|
2903
2918
|
try {
|
|
2904
2919
|
const { ensureDataProgramTables, registerDataProgramsShareable } = await import("../data-programs/store.js");
|
|
2905
|
-
|
|
2920
|
+
if (runBootDatabaseWork)
|
|
2921
|
+
ensureDataProgramTables().catch(() => { });
|
|
2906
2922
|
registerDataProgramsShareable();
|
|
2907
2923
|
}
|
|
2908
2924
|
catch {
|
package/dist/server/index.d.ts
CHANGED
|
@@ -70,7 +70,7 @@ export { isElectron, isMobile, getOrigin, getAppBasePath, getAppUrl, resolveOAut
|
|
|
70
70
|
export { buildWorkspaceProviderAuthorizationUrl, createWorkspaceProviderOAuthHandler, exchangeWorkspaceProviderOAuthCode, handleWorkspaceProviderOAuthCallback, handleWorkspaceProviderOAuthStart, isWorkspaceProviderOAuthFlowValid, mergeWorkspaceOAuthValues, resolveWorkspaceProviderIdentity, workspaceProviderOAuthPath, type GenericWorkspaceOAuthProvider, type WorkspaceProviderOAuthFlow, } from "./workspace-provider-oauth.js";
|
|
71
71
|
export { FeatureNotConfiguredError, hasBuilderPrivateKey, isBuilderEnvManaged, getBuilderProxyOrigin, getBuilderImageGenerationBaseUrl, getBuilderWebSearchBaseUrl, getBuilderAuthHeader, resolveBuilderPrivateKey, resolveBuilderAuthHeader, resolveHasBuilderPrivateKey, resolveHasCompleteBuilderConnection, resolveBuilderCredentials, resolveBuilderCredentialsDetailed, resolveBuilderCredentialSource, resolveBuilderCredential, readDeployCredentialEnv, writeBuilderCredentials, deleteBuilderCredentials, resolveSecret, type BuilderCredentialsDetailed, } from "./credential-provider.js";
|
|
72
72
|
export { builderDesignSystemUrl, builderProjectBranchUrl, buildBuilderDesignSystemIndexFiles, createBuilderDesignSystemProxyFields, fetchBuilderDesignSystemDecodeJobStatus, fetchBuilderDesignSystemDocs, getBuilderDesignSystemsBaseUrl, hydrateBuilderDesignSystemReference, indexBuilderDesignSystem, localBuilderDesignSystemId, mimeTypeForBuilderDesignSystemFilename, parseBuilderDesignSystemProxyReference, startBuilderDesignSystemIndex, startBuilderDesignSystemUpload, type BuildBuilderDesignSystemIndexFilesOptions, type BuilderDesignSystemCodeFileInput, type BuilderDesignSystemDecodeJobStatus, type BuilderDesignSystemDocsOptions, type BuilderDesignSystemDocument, type BuilderDesignSystemHydratedReference, type BuilderDesignSystemIndexFile, type BuilderDesignSystemIndexFromSourcesOptions, type BuilderDesignSystemIndexOptions, type BuilderDesignSystemIndexResult, type BuilderDesignSystemUploadAttachment, type BuilderDesignSystemUploadSlot, type BuilderDesignSystemProxyFields, type BuilderDesignSystemProxyFieldsOptions, type BuilderDesignSystemProxyReference, type BuilderDesignSystemSourceKind, } from "./builder-design-systems.js";
|
|
73
|
-
export { getBuilderBranchProjectId, isBuilderBranchingEnabled, requestBuilderBrowserConnection, resolveBuilderBranchProjectId, resolveIsBuilderBranchingEnabled, runBuilderAgent, type RunBuilderAgentResult, } from "./builder-browser.js";
|
|
73
|
+
export { createBuilderProject, ensureBuilderProject, findBuilderProjectForRepo, getBuilderBranchProjectId, isBuilderBranchingEnabled, requestBuilderBrowserConnection, resolveBuilderBranchProjectId, resolveIsBuilderBranchingEnabled, runBuilderAgent, type BuilderProjectResult, type RunBuilderAgentResult, } from "./builder-browser.js";
|
|
74
74
|
export { ensureFusionContainer, sendFusionBranchMessage, pushFusionBranch, reserveFusionHostingSlug, deployFusionProject, getFusionDeploys, getFusionBranchEditorUrl, getFusionHostingUrl, type FusionBranchRef, type EnsureFusionContainerResult, type SendFusionMessageResult, } from "./fusion-app.js";
|
|
75
75
|
export { sendEmail, isEmailConfigured, getEmailReadiness, getEmailProvider, type EmailAttachment, type EmailReadiness, type EmailProvider, type SendEmailArgs, } from "./email.js";
|
|
76
76
|
export { defineTransactionalEmail, listTransactionalEmails, getTransactionalEmail, renderTransactionalEmailPreview, type TransactionalEmailDefinition, type RegisteredTransactionalEmail, } from "../email-catalog/registry.js";
|
package/dist/server/index.js
CHANGED
|
@@ -75,7 +75,7 @@ export { isElectron, isMobile, getOrigin, getAppBasePath, getAppUrl, resolveOAut
|
|
|
75
75
|
export { buildWorkspaceProviderAuthorizationUrl, createWorkspaceProviderOAuthHandler, exchangeWorkspaceProviderOAuthCode, handleWorkspaceProviderOAuthCallback, handleWorkspaceProviderOAuthStart, isWorkspaceProviderOAuthFlowValid, mergeWorkspaceOAuthValues, resolveWorkspaceProviderIdentity, workspaceProviderOAuthPath, } from "./workspace-provider-oauth.js";
|
|
76
76
|
export { FeatureNotConfiguredError, hasBuilderPrivateKey, isBuilderEnvManaged, getBuilderProxyOrigin, getBuilderImageGenerationBaseUrl, getBuilderWebSearchBaseUrl, getBuilderAuthHeader, resolveBuilderPrivateKey, resolveBuilderAuthHeader, resolveHasBuilderPrivateKey, resolveHasCompleteBuilderConnection, resolveBuilderCredentials, resolveBuilderCredentialsDetailed, resolveBuilderCredentialSource, resolveBuilderCredential, readDeployCredentialEnv, writeBuilderCredentials, deleteBuilderCredentials, resolveSecret, } from "./credential-provider.js";
|
|
77
77
|
export { builderDesignSystemUrl, builderProjectBranchUrl, buildBuilderDesignSystemIndexFiles, createBuilderDesignSystemProxyFields, fetchBuilderDesignSystemDecodeJobStatus, fetchBuilderDesignSystemDocs, getBuilderDesignSystemsBaseUrl, hydrateBuilderDesignSystemReference, indexBuilderDesignSystem, localBuilderDesignSystemId, mimeTypeForBuilderDesignSystemFilename, parseBuilderDesignSystemProxyReference, startBuilderDesignSystemIndex, startBuilderDesignSystemUpload, } from "./builder-design-systems.js";
|
|
78
|
-
export { getBuilderBranchProjectId, isBuilderBranchingEnabled, requestBuilderBrowserConnection, resolveBuilderBranchProjectId, resolveIsBuilderBranchingEnabled, runBuilderAgent, } from "./builder-browser.js";
|
|
78
|
+
export { createBuilderProject, ensureBuilderProject, findBuilderProjectForRepo, getBuilderBranchProjectId, isBuilderBranchingEnabled, requestBuilderBrowserConnection, resolveBuilderBranchProjectId, resolveIsBuilderBranchingEnabled, runBuilderAgent, } from "./builder-browser.js";
|
|
79
79
|
export { ensureFusionContainer, sendFusionBranchMessage, pushFusionBranch, reserveFusionHostingSlug, deployFusionProject, getFusionDeploys, getFusionBranchEditorUrl, getFusionHostingUrl, } from "./fusion-app.js";
|
|
80
80
|
export { sendEmail, isEmailConfigured, getEmailReadiness, getEmailProvider, } from "./email.js";
|
|
81
81
|
export { defineTransactionalEmail, listTransactionalEmails, getTransactionalEmail, renderTransactionalEmailPreview, } from "../email-catalog/registry.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export declare const DEFAULT_PUBLIC_CACHE_CONTROL = "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
|
|
2
2
|
export declare const DEFAULT_SSR_CACHE_CONTROL = "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
|
|
3
3
|
export declare const DEFAULT_SSR_CDN_CACHE_CONTROL = "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
|
|
4
|
-
export declare const DEFAULT_SSR_NETLIFY_CDN_CACHE_CONTROL = "public, durable,
|
|
4
|
+
export declare const DEFAULT_SSR_NETLIFY_CDN_CACHE_CONTROL = "public, durable, s-maxage=31536000, stale-while-revalidate=604800, stale-if-error=3600";
|
|
5
5
|
export declare const DEFAULT_SSR_CACHE_HEADERS: {
|
|
6
6
|
readonly "cache-control": "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
|
|
7
7
|
readonly "cdn-cache-control": "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
|
|
8
|
-
readonly "netlify-cdn-cache-control": "public, durable,
|
|
8
|
+
readonly "netlify-cdn-cache-control": "public, durable, s-maxage=31536000, stale-while-revalidate=604800, stale-if-error=3600";
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
11
11
|
* Deployment-wide override for the SSR shell cache policy.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const DEFAULT_PUBLIC_CACHE_CONTROL = "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
|
|
2
2
|
export const DEFAULT_SSR_CACHE_CONTROL = DEFAULT_PUBLIC_CACHE_CONTROL;
|
|
3
3
|
export const DEFAULT_SSR_CDN_CACHE_CONTROL = DEFAULT_SSR_CACHE_CONTROL;
|
|
4
|
-
export const DEFAULT_SSR_NETLIFY_CDN_CACHE_CONTROL = "public, durable,
|
|
4
|
+
export const DEFAULT_SSR_NETLIFY_CDN_CACHE_CONTROL = "public, durable, s-maxage=31536000, stale-while-revalidate=604800, stale-if-error=3600";
|
|
5
5
|
export const DEFAULT_SSR_CACHE_HEADERS = {
|
|
6
6
|
"cache-control": DEFAULT_SSR_CACHE_CONTROL,
|
|
7
7
|
"cdn-cache-control": DEFAULT_SSR_CDN_CACHE_CONTROL,
|
|
@@ -85,7 +85,7 @@ export function ssrCacheHeadersForPolicy(policy) {
|
|
|
85
85
|
// the 7-day default SWR here would hand back the staleness they opted out of.
|
|
86
86
|
const control = `public, max-age=${policy.seconds}, ` +
|
|
87
87
|
`stale-while-revalidate=${policy.seconds}, stale-if-error=3600`;
|
|
88
|
-
const netlifyControl = `public, durable,
|
|
88
|
+
const netlifyControl = `public, durable, s-maxage=${policy.seconds}, ` +
|
|
89
89
|
`stale-while-revalidate=${policy.seconds}, stale-if-error=3600`;
|
|
90
90
|
return {
|
|
91
91
|
"cache-control": control,
|
|
@@ -27,6 +27,10 @@ The build location depends on the host. Treat this as a hard routing rule:
|
|
|
27
27
|
`resourceIds` when available. This is the Builder handoff.
|
|
28
28
|
- Do not substitute the generic `create_workspace_app` MCP tool in an online
|
|
29
29
|
host. That tool is a local workspace scaffolder, not the Builder handoff.
|
|
30
|
+
- Connect the Agent-Native Dispatch MCP connector only. Dispatch uses the
|
|
31
|
+
authenticated Builder Projects API to reuse or provision the workspace
|
|
32
|
+
project before starting the Builder Cloud Agent; a separate Builder CMS MCP
|
|
33
|
+
connection is not required for this workflow.
|
|
30
34
|
- If `start-workspace-app-creation` is not available or Dispatch is not
|
|
31
35
|
authenticated, stop with the connector setup needed. Do not fall back to a
|
|
32
36
|
local build or claim that the app exists.
|
|
@@ -50,6 +50,14 @@ skills. For a ChatGPT Project or any host that exposes only the MCP connector,
|
|
|
50
50
|
also place the skill instructions or this reference in the Project
|
|
51
51
|
instructions/knowledge files. Then add and authenticate the Dispatch MCP
|
|
52
52
|
connector from the packaged `adapters/chatgpt-mcp/connector.json`.
|
|
53
|
+
This single connector is enough: Dispatch provisions or reuses the Builder
|
|
54
|
+
project through the Builder Projects API, so do not ask the user to add a
|
|
55
|
+
separate Builder CMS MCP for app creation.
|
|
56
|
+
Builder's separate Fusion MCP is available as a custom remote connector at
|
|
57
|
+
`https://mcp.builder.io/mcp/fusion` for direct Builder work. It can run an
|
|
58
|
+
existing project, but it cannot provision the repo-backed Agent-Native
|
|
59
|
+
workspace project, so it is optional and not a replacement for the Dispatch
|
|
60
|
+
handoff in this skill. Do not add Builder's CMS MCP for this workflow.
|
|
53
61
|
|
|
54
62
|
For Claude Web, ChatGPT Web, and their web Projects, the host is an
|
|
55
63
|
orchestrator, not the build environment. After forming the source brief, call
|
|
@@ -27,6 +27,10 @@ The build location depends on the host. Treat this as a hard routing rule:
|
|
|
27
27
|
`resourceIds` when available. This is the Builder handoff.
|
|
28
28
|
- Do not substitute the generic `create_workspace_app` MCP tool in an online
|
|
29
29
|
host. That tool is a local workspace scaffolder, not the Builder handoff.
|
|
30
|
+
- Connect the Agent-Native Dispatch MCP connector only. Dispatch uses the
|
|
31
|
+
authenticated Builder Projects API to reuse or provision the workspace
|
|
32
|
+
project before starting the Builder Cloud Agent; a separate Builder CMS MCP
|
|
33
|
+
connection is not required for this workflow.
|
|
30
34
|
- If `start-workspace-app-creation` is not available or Dispatch is not
|
|
31
35
|
authenticated, stop with the connector setup needed. Do not fall back to a
|
|
32
36
|
local build or claim that the app exists.
|
|
@@ -50,6 +50,14 @@ skills. For a ChatGPT Project or any host that exposes only the MCP connector,
|
|
|
50
50
|
also place the skill instructions or this reference in the Project
|
|
51
51
|
instructions/knowledge files. Then add and authenticate the Dispatch MCP
|
|
52
52
|
connector from the packaged `adapters/chatgpt-mcp/connector.json`.
|
|
53
|
+
This single connector is enough: Dispatch provisions or reuses the Builder
|
|
54
|
+
project through the Builder Projects API, so do not ask the user to add a
|
|
55
|
+
separate Builder CMS MCP for app creation.
|
|
56
|
+
Builder's separate Fusion MCP is available as a custom remote connector at
|
|
57
|
+
`https://mcp.builder.io/mcp/fusion` for direct Builder work. It can run an
|
|
58
|
+
existing project, but it cannot provision the repo-backed Agent-Native
|
|
59
|
+
workspace project, so it is optional and not a replacement for the Dispatch
|
|
60
|
+
handoff in this skill. Do not add Builder's CMS MCP for this workflow.
|
|
53
61
|
|
|
54
62
|
For Claude Web, ChatGPT Web, and their web Projects, the host is an
|
|
55
63
|
orchestrator, not the build environment. After forming the source brief, call
|
|
@@ -27,6 +27,10 @@ The build location depends on the host. Treat this as a hard routing rule:
|
|
|
27
27
|
`resourceIds` when available. This is the Builder handoff.
|
|
28
28
|
- Do not substitute the generic `create_workspace_app` MCP tool in an online
|
|
29
29
|
host. That tool is a local workspace scaffolder, not the Builder handoff.
|
|
30
|
+
- Connect the Agent-Native Dispatch MCP connector only. Dispatch uses the
|
|
31
|
+
authenticated Builder Projects API to reuse or provision the workspace
|
|
32
|
+
project before starting the Builder Cloud Agent; a separate Builder CMS MCP
|
|
33
|
+
connection is not required for this workflow.
|
|
30
34
|
- If `start-workspace-app-creation` is not available or Dispatch is not
|
|
31
35
|
authenticated, stop with the connector setup needed. Do not fall back to a
|
|
32
36
|
local build or claim that the app exists.
|
|
@@ -50,6 +50,14 @@ skills. For a ChatGPT Project or any host that exposes only the MCP connector,
|
|
|
50
50
|
also place the skill instructions or this reference in the Project
|
|
51
51
|
instructions/knowledge files. Then add and authenticate the Dispatch MCP
|
|
52
52
|
connector from the packaged `adapters/chatgpt-mcp/connector.json`.
|
|
53
|
+
This single connector is enough: Dispatch provisions or reuses the Builder
|
|
54
|
+
project through the Builder Projects API, so do not ask the user to add a
|
|
55
|
+
separate Builder CMS MCP for app creation.
|
|
56
|
+
Builder's separate Fusion MCP is available as a custom remote connector at
|
|
57
|
+
`https://mcp.builder.io/mcp/fusion` for direct Builder work. It can run an
|
|
58
|
+
existing project, but it cannot provision the repo-backed Agent-Native
|
|
59
|
+
workspace project, so it is optional and not a replacement for the Dispatch
|
|
60
|
+
handoff in this skill. Do not add Builder's CMS MCP for this workflow.
|
|
53
61
|
|
|
54
62
|
For Claude Web, ChatGPT Web, and their web Projects, the host is an
|
|
55
63
|
orchestrator, not the build environment. After forming the source brief, call
|
|
@@ -27,6 +27,10 @@ The build location depends on the host. Treat this as a hard routing rule:
|
|
|
27
27
|
`resourceIds` when available. This is the Builder handoff.
|
|
28
28
|
- Do not substitute the generic `create_workspace_app` MCP tool in an online
|
|
29
29
|
host. That tool is a local workspace scaffolder, not the Builder handoff.
|
|
30
|
+
- Connect the Agent-Native Dispatch MCP connector only. Dispatch uses the
|
|
31
|
+
authenticated Builder Projects API to reuse or provision the workspace
|
|
32
|
+
project before starting the Builder Cloud Agent; a separate Builder CMS MCP
|
|
33
|
+
connection is not required for this workflow.
|
|
30
34
|
- If `start-workspace-app-creation` is not available or Dispatch is not
|
|
31
35
|
authenticated, stop with the connector setup needed. Do not fall back to a
|
|
32
36
|
local build or claim that the app exists.
|
package/dist/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md
CHANGED
|
@@ -50,6 +50,14 @@ skills. For a ChatGPT Project or any host that exposes only the MCP connector,
|
|
|
50
50
|
also place the skill instructions or this reference in the Project
|
|
51
51
|
instructions/knowledge files. Then add and authenticate the Dispatch MCP
|
|
52
52
|
connector from the packaged `adapters/chatgpt-mcp/connector.json`.
|
|
53
|
+
This single connector is enough: Dispatch provisions or reuses the Builder
|
|
54
|
+
project through the Builder Projects API, so do not ask the user to add a
|
|
55
|
+
separate Builder CMS MCP for app creation.
|
|
56
|
+
Builder's separate Fusion MCP is available as a custom remote connector at
|
|
57
|
+
`https://mcp.builder.io/mcp/fusion` for direct Builder work. It can run an
|
|
58
|
+
existing project, but it cannot provision the repo-backed Agent-Native
|
|
59
|
+
workspace project, so it is optional and not a replacement for the Dispatch
|
|
60
|
+
handoff in this skill. Do not add Builder's CMS MCP for this workflow.
|
|
53
61
|
|
|
54
62
|
For Claude Web, ChatGPT Web, and their web Projects, the host is an
|
|
55
63
|
orchestrator, not the build environment. After forming the source brief, call
|