@agent-native/core 0.146.3 → 0.146.5
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/dashboard-management/SKILL.md +13 -10
- package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/analytics/actions/compose-dashboard.ts +53 -6
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +8 -2
- package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +3 -1
- package/corpus/templates/analytics/actions/mutate-dashboard.ts +48 -9
- package/corpus/templates/analytics/actions/update-dashboard.ts +80 -6
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +1 -1
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/analytics/app/pages/Settings.tsx +5 -1
- package/corpus/templates/analytics/app/routes/agent.tsx +7 -5
- package/corpus/templates/analytics/changelog/2026-08-07-dashboard-creation-and-edits-now-save-faster-with-reliable-s.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +19 -19
- package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +21 -2
- package/corpus/templates/analytics/server/lib/bigquery.ts +59 -24
- package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +44 -8
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +3 -5
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +33 -69
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +90 -24
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +1 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +17 -2
- package/corpus/templates/analytics/shared/dashboard-report-timeouts.ts +2 -0
- package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/assets/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/assets/app/routes/agent.tsx +7 -5
- package/corpus/templates/assets/app/routes/settings.tsx +7 -2
- package/corpus/templates/assets/netlify.toml +1 -1
- package/corpus/templates/assets/package.json +1 -0
- package/corpus/templates/assets/scripts/migrate-production.ts +24 -0
- package/corpus/templates/assets/server/plugins/creative-context.ts +1 -1
- package/corpus/templates/assets/server/plugins/db.ts +1 -1
- package/corpus/templates/assets/tsconfig.json +1 -0
- package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/brain/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/brain/app/lib/brain.ts +4 -2
- package/corpus/templates/brain/app/root.tsx +1 -1
- package/corpus/templates/brain/app/routes/agent.tsx +10 -2
- package/corpus/templates/brain/netlify.toml +1 -1
- package/corpus/templates/brain/package.json +2 -0
- package/corpus/templates/brain/scripts/migrate-production.ts +24 -0
- package/corpus/templates/brain/server/plugins/db.ts +1 -1
- package/corpus/templates/brain/tsconfig.json +1 -0
- package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +1 -1
- package/corpus/templates/calendar/app/root.tsx +1 -1
- package/corpus/templates/calendar/app/routes/_app.agent.tsx +8 -16
- package/corpus/templates/calendar/netlify.toml +1 -1
- package/corpus/templates/calendar/package.json +1 -0
- package/corpus/templates/calendar/scripts/migrate-production.ts +24 -0
- package/corpus/templates/calendar/server/plugins/db.ts +1 -1
- package/corpus/templates/calendar/tsconfig.json +1 -0
- package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/chat/app/hooks/use-navigation-state.ts +5 -2
- package/corpus/templates/chat/app/routes/agent.tsx +7 -31
- package/corpus/templates/chat/netlify.toml +1 -1
- package/corpus/templates/chat/package.json +1 -0
- package/corpus/templates/chat/scripts/migrate-production.ts +31 -0
- package/corpus/templates/chat/tsconfig.json +1 -0
- package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
- package/corpus/templates/clips/app/root.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.agent.tsx +9 -7
- package/corpus/templates/clips/netlify.toml +1 -1
- package/corpus/templates/clips/package.json +1 -0
- package/corpus/templates/clips/scripts/migrate-production.ts +24 -0
- package/corpus/templates/clips/server/plugins/db.ts +1 -1
- package/corpus/templates/clips/tsconfig.json +1 -0
- package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/content/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/content/app/root.tsx +1 -1
- package/corpus/templates/content/app/routes/_app.agent.tsx +9 -8
- package/corpus/templates/content/app/routes/_app.settings.tsx +7 -2
- package/corpus/templates/content/netlify.toml +1 -1
- package/corpus/templates/content/package.json +2 -0
- package/corpus/templates/content/scripts/migrate-production.ts +28 -0
- package/corpus/templates/content/server/plugins/creative-context.ts +1 -1
- package/corpus/templates/content/server/plugins/db.ts +2 -2
- package/corpus/templates/crm/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/crm/app/components/crm/RecordActions.tsx +4 -1
- package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +1 -1
- package/corpus/templates/crm/app/routes/agent.tsx +10 -2
- package/corpus/templates/crm/netlify.toml +1 -1
- package/corpus/templates/crm/package.json +2 -0
- package/corpus/templates/crm/scripts/migrate-production.ts +24 -0
- package/corpus/templates/crm/server/plugins/db.ts +1 -1
- package/corpus/templates/crm/tsconfig.json +1 -0
- package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/design/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/design/app/root.tsx +1 -1
- package/corpus/templates/design/app/routes/agent.tsx +9 -7
- package/corpus/templates/design/app/routes/settings.tsx +7 -2
- package/corpus/templates/design/netlify.toml +1 -1
- package/corpus/templates/design/package.json +1 -0
- package/corpus/templates/design/scripts/migrate-production.ts +24 -0
- package/corpus/templates/design/server/plugins/creative-context.ts +1 -1
- package/corpus/templates/design/server/plugins/db.ts +1 -1
- package/corpus/templates/design/tsconfig.json +1 -0
- package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/dispatch/app/root.tsx +5 -2
- package/corpus/templates/dispatch/app/routes/agent.tsx +7 -7
- package/corpus/templates/dispatch/netlify.toml +1 -1
- package/corpus/templates/dispatch/package.json +1 -0
- package/corpus/templates/dispatch/scripts/migrate-production.ts +23 -0
- package/corpus/templates/dispatch/tsconfig.json +1 -0
- package/corpus/templates/factory/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/factory/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/factory/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +5 -2
- package/corpus/templates/factory/app/root.tsx +1 -1
- package/corpus/templates/factory/app/routes/agent.tsx +9 -14
- package/corpus/templates/factory/netlify.toml +1 -1
- package/corpus/templates/factory/package.json +1 -0
- package/corpus/templates/factory/scripts/migrate-production.ts +31 -0
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +2 -0
- package/corpus/templates/factory/tsconfig.json +1 -0
- package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/forms/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/forms/app/root.tsx +1 -1
- package/corpus/templates/forms/app/routes/_app.agent.tsx +9 -7
- package/corpus/templates/forms/netlify.toml +1 -1
- package/corpus/templates/forms/package.json +2 -0
- package/corpus/templates/forms/scripts/migrate-production.ts +24 -0
- package/corpus/templates/forms/server/plugins/db.ts +1 -1
- package/corpus/templates/forms/tsconfig.json +1 -0
- package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +5 -3
- package/corpus/templates/macros/app/root.tsx +1 -1
- package/corpus/templates/macros/app/routes/agent.tsx +9 -6
- package/corpus/templates/macros/netlify.toml +1 -1
- package/corpus/templates/macros/package.json +1 -0
- package/corpus/templates/macros/scripts/migrate-production.ts +24 -0
- package/corpus/templates/macros/server/plugins/db.ts +1 -1
- package/corpus/templates/macros/tsconfig.json +1 -0
- package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +8 -2
- package/corpus/templates/mail/app/components/layout/CommandPalette.tsx +1 -1
- package/corpus/templates/mail/app/routes/agent.tsx +9 -6
- package/corpus/templates/mail/netlify.toml +1 -1
- package/corpus/templates/mail/package.json +1 -0
- package/corpus/templates/mail/scripts/migrate-production.ts +24 -0
- package/corpus/templates/mail/server/plugins/db.ts +1 -1
- package/corpus/templates/mail/tsconfig.json +1 -0
- package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/plan/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/plan/app/root.tsx +1 -1
- package/corpus/templates/plan/app/routes/agent.tsx +9 -6
- package/corpus/templates/plan/netlify.toml +1 -1
- package/corpus/templates/plan/package.json +1 -0
- package/corpus/templates/plan/scripts/migrate-production.ts +24 -0
- package/corpus/templates/plan/server/plugins/00-mcp.ts +3 -2
- package/corpus/templates/plan/server/plugins/db.ts +1 -1
- package/corpus/templates/plan/tsconfig.json +1 -0
- package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/slides/app/components/editor/ImageGenPanel.tsx +8 -12
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +39 -2
- package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +22 -5
- package/corpus/templates/slides/app/pages/Index.tsx +20 -5
- package/corpus/templates/slides/app/root.tsx +1 -1
- package/corpus/templates/slides/app/routes/agent.tsx +6 -9
- package/corpus/templates/slides/app/routes/settings.tsx +7 -2
- package/corpus/templates/slides/netlify.toml +1 -1
- package/corpus/templates/slides/package.json +1 -0
- package/corpus/templates/slides/scripts/migrate-production.ts +24 -0
- package/corpus/templates/slides/server/plugins/creative-context.ts +1 -1
- package/corpus/templates/slides/server/plugins/db.ts +1 -1
- package/corpus/templates/slides/tsconfig.json +1 -0
- package/corpus/templates/tasks/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/corpus/templates/tasks/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/tasks/app/routes/agent.tsx +10 -2
- package/corpus/templates/tasks/netlify.toml +1 -1
- package/corpus/templates/tasks/package.json +1 -0
- package/corpus/templates/tasks/scripts/migrate-production.ts +24 -0
- package/corpus/templates/tasks/server/plugins/db.ts +1 -1
- package/corpus/templates/tasks/tsconfig.json +1 -0
- package/dist/action.d.ts +2 -0
- package/dist/agent/production-agent.d.ts +1 -0
- package/dist/agent/production-agent.js +2 -0
- package/dist/agent/thread-data-builder.d.ts +4 -0
- package/dist/agent/thread-data-builder.js +44 -0
- package/dist/automations/service.d.ts +1 -0
- package/dist/automations/service.js +21 -2
- package/dist/cli/create.js +20 -2
- package/dist/client/agent-page/AgentJobsTab.js +3 -1
- package/dist/client/agent-page/AutomationDetailsDialog.js +9 -2
- package/dist/client/index.d.ts +1 -1
- package/dist/client/navigation/index.d.ts +1 -1
- package/dist/client/navigation/index.js +1 -1
- package/dist/client/org/OrgSwitcher.js +1 -1
- package/dist/client/settings/SettingsPanel.d.ts +8 -0
- package/dist/client/settings/SettingsPanel.js +16 -1
- package/dist/client/settings/index.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/migrations.js +7 -13
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/jobs/actions/list-automation-runs.d.ts +1 -0
- package/dist/jobs/actions/list-automation-runs.js +9 -2
- package/dist/jobs/actions/list-recurring-jobs.js +3 -1
- package/dist/jobs/actions/manage-recurring-job.js +1 -1
- package/dist/jobs/actions/run-automation-now.js +1 -0
- package/dist/jobs/background-automation-runner.js +2 -0
- package/dist/jobs/frontmatter.d.ts +2 -0
- package/dist/jobs/frontmatter.js +4 -0
- package/dist/jobs/run-history.d.ts +4 -0
- package/dist/jobs/run-history.js +28 -8
- package/dist/jobs/run-now.d.ts +4 -1
- package/dist/jobs/run-now.js +4 -3
- package/dist/jobs/scheduler.js +18 -0
- package/dist/jobs/tools.d.ts +3 -2
- package/dist/jobs/tools.js +26 -12
- package/dist/localization/default-messages.d.ts +1 -0
- package/dist/localization/default-messages.js +1 -0
- package/dist/navigation/index.d.ts +1 -0
- package/dist/navigation/index.js +34 -0
- 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/action-routes.d.ts +2 -0
- package/dist/server/action-routes.js +1 -0
- package/dist/server/agent-chat-plugin.js +3 -2
- package/dist/server/builder-browser.js +24 -8
- package/dist/templates/chat/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +5 -2
- package/dist/templates/chat/app/routes/agent.tsx +7 -31
- package/dist/templates/chat/netlify.toml +1 -1
- package/dist/templates/chat/package.json +1 -0
- package/dist/templates/chat/scripts/migrate-production.ts +31 -0
- package/dist/templates/chat/tsconfig.json +1 -0
- package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/dist/templates/default/app/routes/_index.tsx +1 -1
- package/dist/templates/default/app/routes/agent.tsx +7 -25
- package/dist/templates/default/package.json +1 -0
- package/dist/templates/default/scripts/migrate-production.ts +31 -0
- package/dist/templates/default/tsconfig.json +1 -0
- package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/dist/templates/workspace-root/AGENTS.md +2 -1
- package/dist/triggers/actions/list-automations.js +1 -1
- package/dist/triggers/actions/manage-automation.js +5 -1
- package/dist/triggers/actions.d.ts +1 -1
- package/dist/triggers/actions.js +21 -15
- package/dist/triggers/dispatcher.js +17 -2
- package/dist/triggers/routes.d.ts +1 -0
- package/dist/triggers/routes.js +1 -0
- package/package.json +3 -3
- package/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/src/templates/chat/app/hooks/use-navigation-state.ts +5 -2
- package/src/templates/chat/app/routes/agent.tsx +7 -31
- package/src/templates/chat/netlify.toml +1 -1
- package/src/templates/chat/package.json +1 -0
- package/src/templates/chat/scripts/migrate-production.ts +31 -0
- package/src/templates/chat/tsconfig.json +1 -0
- package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/src/templates/default/app/routes/_index.tsx +1 -1
- package/src/templates/default/app/routes/agent.tsx +7 -25
- package/src/templates/default/package.json +1 -0
- package/src/templates/default/scripts/migrate-production.ts +31 -0
- package/src/templates/default/tsconfig.json +1 -0
- package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +7 -3
- package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +5 -2
- package/src/templates/workspace-root/AGENTS.md +2 -1
package/dist/jobs/run-now.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { type AutomationScope } from "../automations/service.js";
|
|
|
2
2
|
export interface RunAutomationNowInput {
|
|
3
3
|
userEmail: string;
|
|
4
4
|
orgId?: string | null;
|
|
5
|
+
appId?: string | null;
|
|
5
6
|
scope: AutomationScope;
|
|
6
7
|
name: string;
|
|
7
8
|
}
|
|
@@ -16,4 +17,6 @@ export declare function queueAutomationRunNow(input: RunAutomationNowInput): Pro
|
|
|
16
17
|
* This is intentionally a redelivery, not a second execution: the worker's
|
|
17
18
|
* claim CAS decides which request owns the run.
|
|
18
19
|
*/
|
|
19
|
-
export declare function redispatchUnclaimedAutomationRuns(
|
|
20
|
+
export declare function redispatchUnclaimedAutomationRuns(options?: {
|
|
21
|
+
appId?: string | null;
|
|
22
|
+
}): Promise<number>;
|
package/dist/jobs/run-now.js
CHANGED
|
@@ -56,7 +56,7 @@ export async function queueAutomationRunNow(input) {
|
|
|
56
56
|
}
|
|
57
57
|
// A manual-run request is a guaranteed app request even on hosts without a
|
|
58
58
|
// durable timer. Use it to recover older rows before adding the new one.
|
|
59
|
-
await redispatchUnclaimedAutomationRuns().catch((error) => {
|
|
59
|
+
await redispatchUnclaimedAutomationRuns({ appId: input.appId }).catch((error) => {
|
|
60
60
|
console.warn("[automations] Could not sweep queued runs before run-now:", error);
|
|
61
61
|
});
|
|
62
62
|
const historyId = await startAutomationRun({
|
|
@@ -65,6 +65,7 @@ export async function queueAutomationRunNow(input) {
|
|
|
65
65
|
path: resource.path,
|
|
66
66
|
scope: input.scope,
|
|
67
67
|
orgId: input.scope === "organization" ? input.orgId : null,
|
|
68
|
+
appId: input.appId,
|
|
68
69
|
dispatchPending: true,
|
|
69
70
|
});
|
|
70
71
|
try {
|
|
@@ -82,8 +83,8 @@ export async function queueAutomationRunNow(input) {
|
|
|
82
83
|
* This is intentionally a redelivery, not a second execution: the worker's
|
|
83
84
|
* claim CAS decides which request owns the run.
|
|
84
85
|
*/
|
|
85
|
-
export async function redispatchUnclaimedAutomationRuns() {
|
|
86
|
-
const runs = await listUnclaimedAutomationRuns();
|
|
86
|
+
export async function redispatchUnclaimedAutomationRuns(options) {
|
|
87
|
+
const runs = await listUnclaimedAutomationRuns({ appId: options?.appId });
|
|
87
88
|
let attempted = 0;
|
|
88
89
|
for (const run of runs) {
|
|
89
90
|
try {
|
package/dist/jobs/scheduler.js
CHANGED
|
@@ -18,6 +18,13 @@ const MAX_IDENTITY_PREFLIGHTS_PER_TICK = MAX_CONCURRENT_SCHEDULED_JOBS * 4;
|
|
|
18
18
|
const IDENTITY_FAILURE_RETRY_MS = 5 * 60_000;
|
|
19
19
|
const _activeScheduledJobs = new Set();
|
|
20
20
|
const _preflightingScheduledJobs = new Set();
|
|
21
|
+
function jobBelongsToApp(meta, appId) {
|
|
22
|
+
const ownerAppId = meta.appId?.trim();
|
|
23
|
+
if (!ownerAppId)
|
|
24
|
+
return true;
|
|
25
|
+
const schedulerAppId = appId?.trim();
|
|
26
|
+
return Boolean(schedulerAppId && ownerAppId === schedulerAppId);
|
|
27
|
+
}
|
|
21
28
|
// Skip the DB query on every tick if we recently confirmed no jobs exist.
|
|
22
29
|
// `_hasJobsCache` is invalidated whenever a `jobs/*` resource is written or
|
|
23
30
|
// deleted (subscribed below), and refreshed at most every 5 minutes.
|
|
@@ -106,6 +113,12 @@ export async function processRecurringJobs(deps) {
|
|
|
106
113
|
if (resource.path.endsWith(".keep"))
|
|
107
114
|
continue;
|
|
108
115
|
const { meta, body } = parseJobFrontmatter(resource.content);
|
|
116
|
+
// Jobs written before app ownership was persisted remain compatible with
|
|
117
|
+
// the shared scheduler. Once a job declares an owner, only that app may
|
|
118
|
+
// evaluate or execute it. Without this boundary every app's scheduled
|
|
119
|
+
// worker can claim the same organization resource.
|
|
120
|
+
if (!jobBelongsToApp(meta, deps.appId))
|
|
121
|
+
continue;
|
|
109
122
|
healthOrgIds.add(meta.orgId ?? null);
|
|
110
123
|
// Skip disabled or missing schedule
|
|
111
124
|
if (!meta.enabled || !meta.schedule)
|
|
@@ -422,6 +435,11 @@ export async function runQueuedAutomation(historyId, deps) {
|
|
|
422
435
|
const queued = await getAutomationRun(historyId);
|
|
423
436
|
if (!queued)
|
|
424
437
|
throw new Error(`Automation run "${historyId}" not found.`);
|
|
438
|
+
const queuedAppId = queued.appId?.trim() || null;
|
|
439
|
+
const workerAppId = deps.appId?.trim() || null;
|
|
440
|
+
if (queuedAppId && queuedAppId !== workerAppId) {
|
|
441
|
+
return { skipped: true };
|
|
442
|
+
}
|
|
425
443
|
if (!(await claimAutomationRun(historyId))) {
|
|
426
444
|
return { skipped: true };
|
|
427
445
|
}
|
package/dist/jobs/tools.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ActionEntry } from "../agent/production-agent.js";
|
|
2
2
|
import { type JobFrontmatter } from "./scheduler.js";
|
|
3
|
+
export declare function jobBelongsToApp(meta: JobFrontmatter, appId?: string): boolean;
|
|
3
4
|
/**
|
|
4
5
|
* Authorise a mutation (update / delete) against a job resource. When the
|
|
5
6
|
* job is in the SHARED scope the caller must either be the original
|
|
@@ -11,5 +12,5 @@ import { type JobFrontmatter } from "./scheduler.js";
|
|
|
11
12
|
* Returns null when the mutation is allowed, or an error string suitable
|
|
12
13
|
* for returning to the caller when not.
|
|
13
14
|
*/
|
|
14
|
-
export declare function authorizeJobMutation(resourceOwner: string, meta: JobFrontmatter): Promise<string | null>;
|
|
15
|
-
export declare function createJobTools(): Record<string, ActionEntry>;
|
|
15
|
+
export declare function authorizeJobMutation(resourceOwner: string, meta: JobFrontmatter, appId?: string): Promise<string | null>;
|
|
16
|
+
export declare function createJobTools(appId?: string): Record<string, ActionEntry>;
|
package/dist/jobs/tools.js
CHANGED
|
@@ -14,6 +14,12 @@ function getOwner() {
|
|
|
14
14
|
function getSharedOwner() {
|
|
15
15
|
return sharedResourceOwner(getRequestOrgId());
|
|
16
16
|
}
|
|
17
|
+
export function jobBelongsToApp(meta, appId) {
|
|
18
|
+
const ownerAppId = meta.appId?.trim();
|
|
19
|
+
if (!ownerAppId)
|
|
20
|
+
return true;
|
|
21
|
+
return ownerAppId === appId?.trim();
|
|
22
|
+
}
|
|
17
23
|
/**
|
|
18
24
|
* Determine if the current request's user is an org owner/admin in the
|
|
19
25
|
* given org. Used to allow privileged users to update or delete shared
|
|
@@ -52,7 +58,10 @@ async function isCurrentUserOrgAdmin(orgId) {
|
|
|
52
58
|
* Returns null when the mutation is allowed, or an error string suitable
|
|
53
59
|
* for returning to the caller when not.
|
|
54
60
|
*/
|
|
55
|
-
export async function authorizeJobMutation(resourceOwner, meta) {
|
|
61
|
+
export async function authorizeJobMutation(resourceOwner, meta, appId) {
|
|
62
|
+
if (!jobBelongsToApp(meta, appId)) {
|
|
63
|
+
return "This job belongs to another app and cannot be changed here.";
|
|
64
|
+
}
|
|
56
65
|
const resourceOrgId = organizationIdFromResourceOwner(resourceOwner);
|
|
57
66
|
if (resourceOwner !== SHARED_OWNER && !resourceOrgId) {
|
|
58
67
|
// Personal-scope job — owner is the request's user. resourceGetByPath is
|
|
@@ -69,7 +78,7 @@ export async function authorizeJobMutation(resourceOwner, meta) {
|
|
|
69
78
|
return null;
|
|
70
79
|
return "Only the job's creator (or an org admin) can update or delete it.";
|
|
71
80
|
}
|
|
72
|
-
async function runCreate(args) {
|
|
81
|
+
async function runCreate(args, appId) {
|
|
73
82
|
const { name, schedule, instructions, scope, runAs, model } = args;
|
|
74
83
|
const requestedTimezone = args.timezone;
|
|
75
84
|
if (!name || !schedule || !instructions) {
|
|
@@ -111,6 +120,7 @@ async function runCreate(args) {
|
|
|
111
120
|
enabled: true,
|
|
112
121
|
createdBy: getOwner(),
|
|
113
122
|
orgId: getRequestOrgId() || undefined,
|
|
123
|
+
appId: appId?.trim() || undefined,
|
|
114
124
|
runAs: runAs === "shared" ? "shared" : "creator",
|
|
115
125
|
nextRun: next.toISOString(),
|
|
116
126
|
...(integration?.scopeId ? { originScopeId: integration.scopeId } : {}),
|
|
@@ -143,7 +153,7 @@ async function runCreate(args) {
|
|
|
143
153
|
...(mcpTools?.length ? { mcpTools } : {}),
|
|
144
154
|
});
|
|
145
155
|
}
|
|
146
|
-
async function runList(args) {
|
|
156
|
+
async function runList(args, appId) {
|
|
147
157
|
const owner = getOwner();
|
|
148
158
|
const sharedOwner = getSharedOwner();
|
|
149
159
|
// Fetch only current user's and shared jobs (not other users')
|
|
@@ -164,6 +174,8 @@ async function runList(args) {
|
|
|
164
174
|
if (classifyJobResource(full.content).kind === "automation")
|
|
165
175
|
return null;
|
|
166
176
|
const { meta } = parseJobFrontmatter(full.content);
|
|
177
|
+
if (!jobBelongsToApp(meta, appId))
|
|
178
|
+
return null;
|
|
167
179
|
return {
|
|
168
180
|
name: r.path.replace(/^jobs\//, "").replace(/\.md$/, ""),
|
|
169
181
|
path: r.path,
|
|
@@ -191,7 +203,7 @@ async function runList(args) {
|
|
|
191
203
|
}
|
|
192
204
|
return JSON.stringify(scheduledJobs, null, 2);
|
|
193
205
|
}
|
|
194
|
-
async function runUpdate(args) {
|
|
206
|
+
async function runUpdate(args, appId) {
|
|
195
207
|
const { name, schedule, instructions, enabled, scope, runAs, model } = args;
|
|
196
208
|
const path = `jobs/${name}.md`;
|
|
197
209
|
// Try to find the resource
|
|
@@ -213,10 +225,12 @@ async function runUpdate(args) {
|
|
|
213
225
|
// `createdBy` is alice@…, and the next cron tick would run the
|
|
214
226
|
// attacker's instructions as alice (creator-runAs schedules in
|
|
215
227
|
// jobs/scheduler.ts line 273-278).
|
|
216
|
-
const denied = await authorizeJobMutation(resource.owner, meta);
|
|
228
|
+
const denied = await authorizeJobMutation(resource.owner, meta, appId);
|
|
217
229
|
if (denied) {
|
|
218
230
|
return JSON.stringify({ error: denied });
|
|
219
231
|
}
|
|
232
|
+
if (!meta.appId && appId?.trim())
|
|
233
|
+
meta.appId = appId.trim();
|
|
220
234
|
if (schedule) {
|
|
221
235
|
if (!isValidCron(schedule)) {
|
|
222
236
|
return JSON.stringify({
|
|
@@ -273,7 +287,7 @@ async function runUpdate(args) {
|
|
|
273
287
|
mcpTools: meta.mcpTools || [],
|
|
274
288
|
});
|
|
275
289
|
}
|
|
276
|
-
async function runDelete(args) {
|
|
290
|
+
async function runDelete(args, appId) {
|
|
277
291
|
const { name, scope } = args;
|
|
278
292
|
const path = `jobs/${name}.md`;
|
|
279
293
|
let resource = await resourceGetByPath(getSharedOwner(), path);
|
|
@@ -292,14 +306,14 @@ async function runDelete(args) {
|
|
|
292
306
|
error: `"${name}" is an automation. Use manage-automations to delete it.`,
|
|
293
307
|
});
|
|
294
308
|
}
|
|
295
|
-
const denied = await authorizeJobMutation(resource.owner, meta);
|
|
309
|
+
const denied = await authorizeJobMutation(resource.owner, meta, appId);
|
|
296
310
|
if (denied) {
|
|
297
311
|
return JSON.stringify({ error: denied });
|
|
298
312
|
}
|
|
299
313
|
await resourceDelete(resource.id);
|
|
300
314
|
return JSON.stringify({ deleted: true, name });
|
|
301
315
|
}
|
|
302
|
-
export function createJobTools() {
|
|
316
|
+
export function createJobTools(appId) {
|
|
303
317
|
return {
|
|
304
318
|
"manage-jobs": {
|
|
305
319
|
tool: {
|
|
@@ -374,13 +388,13 @@ For jobs that use a connected MCP, pass the exact tool names in mcpTools. This b
|
|
|
374
388
|
run: async (args) => {
|
|
375
389
|
switch (args.action) {
|
|
376
390
|
case "create":
|
|
377
|
-
return runCreate(args);
|
|
391
|
+
return runCreate(args, appId);
|
|
378
392
|
case "list":
|
|
379
|
-
return runList(args);
|
|
393
|
+
return runList(args, appId);
|
|
380
394
|
case "update":
|
|
381
|
-
return runUpdate(args);
|
|
395
|
+
return runUpdate(args, appId);
|
|
382
396
|
case "delete":
|
|
383
|
-
return runDelete(args);
|
|
397
|
+
return runDelete(args, appId);
|
|
384
398
|
default:
|
|
385
399
|
return JSON.stringify({
|
|
386
400
|
error: `Unknown action "${args.action}". Use "create", "list", or "update".`,
|
|
@@ -38,6 +38,7 @@ export interface StandardOpenPathResolverOptions {
|
|
|
38
38
|
fallback?: StandardOpenPathRoute;
|
|
39
39
|
}
|
|
40
40
|
export declare function buildSettingsRoute(tab?: StandardSettingsTabId | string | null, basePath?: "/settings"): string;
|
|
41
|
+
export declare function buildLegacyAgentSettingsRoute(hash?: string | null, search?: string): string;
|
|
41
42
|
export declare function buildTeamRoute(options?: Pick<BuildStandardAppRouteOptions, "teamInSettings">): string;
|
|
42
43
|
export declare function buildStandardAppRoute(route: StandardAppRouteId, options?: BuildStandardAppRouteOptions): string;
|
|
43
44
|
export declare function buildResourceRoute(collection: string, resourceId: string, options?: BuildResourceRouteOptions): string;
|
package/dist/navigation/index.js
CHANGED
|
@@ -15,6 +15,21 @@ export const STANDARD_SETTINGS_TABS = {
|
|
|
15
15
|
language: "language",
|
|
16
16
|
whatsNew: "whats-new",
|
|
17
17
|
};
|
|
18
|
+
const LEGACY_AGENT_RESOURCE_TABS = new Set([
|
|
19
|
+
"files",
|
|
20
|
+
"instructions",
|
|
21
|
+
"agents",
|
|
22
|
+
"memory",
|
|
23
|
+
"skills",
|
|
24
|
+
"learnings",
|
|
25
|
+
]);
|
|
26
|
+
const LEGACY_AGENT_SETTINGS_TABS = new Set([
|
|
27
|
+
"llm",
|
|
28
|
+
"app-models",
|
|
29
|
+
"limits",
|
|
30
|
+
"voice",
|
|
31
|
+
"background",
|
|
32
|
+
]);
|
|
18
33
|
function normalizeLeadingPath(path) {
|
|
19
34
|
const trimmed = path.trim();
|
|
20
35
|
if (!trimmed || trimmed === "/")
|
|
@@ -56,6 +71,25 @@ export function buildSettingsRoute(tab, basePath = STANDARD_APP_ROUTES.settings)
|
|
|
56
71
|
.filter(Boolean);
|
|
57
72
|
return `${path}/${segments.join("/")}`;
|
|
58
73
|
}
|
|
74
|
+
export function buildLegacyAgentSettingsRoute(hash, search = "") {
|
|
75
|
+
const legacyTab = hash?.replace(/^#/, "").toLowerCase() ?? "";
|
|
76
|
+
const destination = LEGACY_AGENT_RESOURCE_TABS.has(legacyTab)
|
|
77
|
+
? buildSettingsRoute(`agent:resources:${legacyTab}`)
|
|
78
|
+
: legacyTab === "remote-agents"
|
|
79
|
+
? buildSettingsRoute("agent:agents")
|
|
80
|
+
: legacyTab === "connections"
|
|
81
|
+
? buildSettingsRoute("connections")
|
|
82
|
+
: legacyTab === "jobs"
|
|
83
|
+
? buildSettingsRoute("agent:automations")
|
|
84
|
+
: legacyTab === "library"
|
|
85
|
+
? buildSettingsRoute("library")
|
|
86
|
+
: legacyTab === "access"
|
|
87
|
+
? buildSettingsRoute("agent")
|
|
88
|
+
: LEGACY_AGENT_SETTINGS_TABS.has(legacyTab)
|
|
89
|
+
? buildSettingsRoute(`agent:${legacyTab}`)
|
|
90
|
+
: buildSettingsRoute("agent");
|
|
91
|
+
return `${destination}${search}`;
|
|
92
|
+
}
|
|
59
93
|
export function buildTeamRoute(options = {}) {
|
|
60
94
|
return options.teamInSettings
|
|
61
95
|
? buildSettingsRoute(STANDARD_SETTINGS_TABS.team)
|
|
@@ -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;
|
|
@@ -45,6 +45,8 @@ export interface ActionRouteAuthAdapter {
|
|
|
45
45
|
export interface MountActionRoutesOptions {
|
|
46
46
|
/** Resolve owner email from the H3 event (for data scoping). */
|
|
47
47
|
getOwnerFromEvent?: (event: any) => string | Promise<string>;
|
|
48
|
+
/** Hosting app/template id used for app-owned action resources. */
|
|
49
|
+
appId?: string;
|
|
48
50
|
/** Resolve display name from the H3 event, when available. */
|
|
49
51
|
getUserNameFromEvent?: (event: any) => string | undefined | Promise<string | undefined>;
|
|
50
52
|
/** Resolve org ID from the H3 event (for org scoping). */
|
|
@@ -673,7 +673,7 @@ export function createAgentChatPlugin(options) {
|
|
|
673
673
|
try {
|
|
674
674
|
if (automationGroupEnabled) {
|
|
675
675
|
const { createAutomationToolEntries } = await import("../triggers/actions.js");
|
|
676
|
-
automationTools = createAutomationToolEntries(() => requireCurrentRunOwner("manage automations"));
|
|
676
|
+
automationTools = createAutomationToolEntries(() => requireCurrentRunOwner("manage automations"), options?.appId);
|
|
677
677
|
}
|
|
678
678
|
}
|
|
679
679
|
catch { }
|
|
@@ -1914,6 +1914,7 @@ export function createAgentChatPlugin(options) {
|
|
|
1914
1914
|
mountActionRoutes(nitroApp, httpActions, {
|
|
1915
1915
|
getOwnerFromEvent,
|
|
1916
1916
|
getUserNameFromEvent,
|
|
1917
|
+
appId: options?.appId,
|
|
1917
1918
|
resolveOrgId: options?.resolveOrgId,
|
|
1918
1919
|
actionRouteAuth: options?.actionRouteAuth,
|
|
1919
1920
|
});
|
|
@@ -2243,7 +2244,7 @@ export function createAgentChatPlugin(options) {
|
|
|
2243
2244
|
try {
|
|
2244
2245
|
if (automationGroupEnabled) {
|
|
2245
2246
|
const { createJobTools } = await import("../jobs/tools.js");
|
|
2246
|
-
jobTools = createJobTools();
|
|
2247
|
+
jobTools = createJobTools(options?.appId);
|
|
2247
2248
|
}
|
|
2248
2249
|
}
|
|
2249
2250
|
catch { }
|
|
@@ -5,6 +5,7 @@ import { getAuthSecret, resolveSignupTrackingIdentity, } from "./better-auth-ins
|
|
|
5
5
|
import { getAppBasePath, getOrigin } from "./google-oauth.js";
|
|
6
6
|
const DEFAULT_BUILDER_APP_HOST = "https://builder.io";
|
|
7
7
|
const DEFAULT_BUILDER_API_HOST = "https://api.builder.io";
|
|
8
|
+
const BUILDER_API_REQUEST_TIMEOUT_MS = 30_000;
|
|
8
9
|
const BUILDER_BROWSER_HOST = "agent-native-browser";
|
|
9
10
|
const BUILDER_BROWSER_CLIENT_ID = "Agent Native Browser";
|
|
10
11
|
export const BUILDER_CALLBACK_PATH = "/_agent-native/builder/callback";
|
|
@@ -1359,6 +1360,21 @@ async function resolveBuilderApiCredentials() {
|
|
|
1359
1360
|
publicKey: creds.publicKey,
|
|
1360
1361
|
};
|
|
1361
1362
|
}
|
|
1363
|
+
async function fetchBuilderApi(input, init, operation) {
|
|
1364
|
+
try {
|
|
1365
|
+
return await fetch(input, {
|
|
1366
|
+
...init,
|
|
1367
|
+
signal: AbortSignal.timeout(BUILDER_API_REQUEST_TIMEOUT_MS),
|
|
1368
|
+
});
|
|
1369
|
+
}
|
|
1370
|
+
catch (error) {
|
|
1371
|
+
const errorName = error instanceof Error ? error.name : "";
|
|
1372
|
+
if (errorName === "AbortError" || errorName === "TimeoutError") {
|
|
1373
|
+
throw new Error(`Builder ${operation} timed out after ${BUILDER_API_REQUEST_TIMEOUT_MS}ms`, { cause: error });
|
|
1374
|
+
}
|
|
1375
|
+
throw error;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1362
1378
|
async function readBuilderApiObject(response, operation) {
|
|
1363
1379
|
let parsed;
|
|
1364
1380
|
try {
|
|
@@ -1400,10 +1416,10 @@ export async function findBuilderProjectForRepo(args) {
|
|
|
1400
1416
|
const url = new URL("/projects", getBuilderApiHost());
|
|
1401
1417
|
url.searchParams.set("apiKey", creds.publicKey);
|
|
1402
1418
|
url.searchParams.set("includeHidden", "true");
|
|
1403
|
-
const response = await
|
|
1419
|
+
const response = await fetchBuilderApi(url, {
|
|
1404
1420
|
method: "GET",
|
|
1405
1421
|
headers: { Authorization: `Bearer ${creds.privateKey}` },
|
|
1406
|
-
});
|
|
1422
|
+
}, "project lookup");
|
|
1407
1423
|
const parsed = await readBuilderApiObject(response, "project lookup");
|
|
1408
1424
|
if (!response.ok) {
|
|
1409
1425
|
throw new Error(builderApiErrorMessage(parsed, `Builder project lookup failed (${response.status})`));
|
|
@@ -1432,7 +1448,7 @@ export async function createBuilderProject(args) {
|
|
|
1432
1448
|
const creds = await resolveBuilderApiCredentials();
|
|
1433
1449
|
const url = new URL("/projects/create", getBuilderApiHost());
|
|
1434
1450
|
url.searchParams.set("apiKey", creds.publicKey);
|
|
1435
|
-
const response = await
|
|
1451
|
+
const response = await fetchBuilderApi(url, {
|
|
1436
1452
|
method: "POST",
|
|
1437
1453
|
headers: {
|
|
1438
1454
|
Authorization: `Bearer ${creds.privateKey}`,
|
|
@@ -1442,7 +1458,7 @@ export async function createBuilderProject(args) {
|
|
|
1442
1458
|
source: { kind: "repo", repoUrl },
|
|
1443
1459
|
name,
|
|
1444
1460
|
}),
|
|
1445
|
-
});
|
|
1461
|
+
}, "project creation");
|
|
1446
1462
|
const parsed = await readBuilderApiObject(response, "project creation");
|
|
1447
1463
|
if (!response.ok) {
|
|
1448
1464
|
throw new Error(builderApiErrorMessage(parsed, `Builder project creation failed (${response.status})`));
|
|
@@ -1526,14 +1542,14 @@ export async function runBuilderAgent(args) {
|
|
|
1526
1542
|
body.userEmail = actor.userEmail;
|
|
1527
1543
|
if (actor.userId)
|
|
1528
1544
|
body.userId = actor.userId;
|
|
1529
|
-
const response = await
|
|
1545
|
+
const response = await fetchBuilderApi(url, {
|
|
1530
1546
|
method: "POST",
|
|
1531
1547
|
headers: {
|
|
1532
1548
|
Authorization: `Bearer ${creds.privateKey}`,
|
|
1533
1549
|
"Content-Type": "application/json",
|
|
1534
1550
|
},
|
|
1535
1551
|
body: JSON.stringify(body),
|
|
1536
|
-
});
|
|
1552
|
+
}, "agent run");
|
|
1537
1553
|
const parsed = (await response.json().catch(() => ({})));
|
|
1538
1554
|
return { response, parsed };
|
|
1539
1555
|
};
|
|
@@ -1582,7 +1598,7 @@ export async function requestBuilderBrowserConnection(args) {
|
|
|
1582
1598
|
if (creds.userId) {
|
|
1583
1599
|
url.searchParams.set("userId", creds.userId);
|
|
1584
1600
|
}
|
|
1585
|
-
const response = await
|
|
1601
|
+
const response = await fetchBuilderApi(url, {
|
|
1586
1602
|
method: "POST",
|
|
1587
1603
|
headers: {
|
|
1588
1604
|
Authorization: `Bearer ${creds.privateKey}`,
|
|
@@ -1596,7 +1612,7 @@ export async function requestBuilderBrowserConnection(args) {
|
|
|
1596
1612
|
proxyDefaultOrigin: args.proxyDefaultOrigin || undefined,
|
|
1597
1613
|
proxyDst: args.proxyDestination || undefined,
|
|
1598
1614
|
}),
|
|
1599
|
-
});
|
|
1615
|
+
}, "browser connection request");
|
|
1600
1616
|
const body = (await response.json().catch(() => ({})));
|
|
1601
1617
|
if (!response.ok) {
|
|
1602
1618
|
const error = typeof body.error === "string"
|
|
@@ -36,8 +36,10 @@ Tier 4 includes **all** of the following — not only editing package source:
|
|
|
36
36
|
- Files under `node_modules/@agent-native/*` (core, dispatch, scheduling, …)
|
|
37
37
|
- `pnpm.overrides`, `overrides`, `resolutions`, or `patchedDependencies` that
|
|
38
38
|
target any `@agent-native/*` package
|
|
39
|
-
-
|
|
40
|
-
|
|
39
|
+
- `pnpm patch`, `pnpm patch-commit`, or local package patch artifacts for any
|
|
40
|
+
dependency
|
|
41
|
+
- Invented "dispatch/core behavior" shims meant to paper over a version skew
|
|
42
|
+
or failed upgrade
|
|
41
43
|
|
|
42
44
|
This does not prohibit intentional app-owned UI customization. When public
|
|
43
45
|
props and composition are insufficient, the `customizing-agent-native` skill
|
|
@@ -100,8 +102,10 @@ inline strings in components.
|
|
|
100
102
|
- Don't confuse readable package source with app-owned code: use
|
|
101
103
|
`customizing-agent-native` and `agent-native eject` for supported ownership
|
|
102
104
|
transfer
|
|
105
|
+
- Don't use `pnpm patch` / `pnpm patch-commit`, commit `patches/` artifacts, or
|
|
106
|
+
add `pnpm.patchedDependencies` to "make the app run" after a version bump
|
|
103
107
|
- Don't add `pnpm.overrides` / `patchedDependencies` / `resolutions` for
|
|
104
|
-
`@agent-native/*` to
|
|
108
|
+
`@agent-native/*` to paper over a broken upgrade
|
|
105
109
|
- Don't invent local dispatch/core behavior overrides when upgrade fails —
|
|
106
110
|
run `npx @agent-native/core@latest upgrade`, then fix app-level errors only
|
|
107
111
|
- Don't modify `.agents/skills/` or `AGENTS.md` unless explicitly requested
|
|
@@ -15,8 +15,9 @@ metadata:
|
|
|
15
15
|
|
|
16
16
|
When an older Agent Native app/branch needs to run on current packages, use
|
|
17
17
|
`agent-native upgrade`. Never "fix" upgrade breakage with
|
|
18
|
-
`pnpm
|
|
19
|
-
|
|
18
|
+
`pnpm patch`, `pnpm patch-commit`, `pnpm.patchedDependencies`,
|
|
19
|
+
`pnpm.overrides`, `patchedDependencies`, `resolutions`, local patch artifacts,
|
|
20
|
+
or edits under `node_modules/@agent-native/*` — especially not against
|
|
20
21
|
`@agent-native/core` or `@agent-native/dispatch`.
|
|
21
22
|
|
|
22
23
|
## Why
|
|
@@ -109,6 +110,8 @@ install → refresh scaffold skills → verify, then fix **app** code only.
|
|
|
109
110
|
|
|
110
111
|
- Don't add `pnpm.overrides`, `overrides`, `resolutions`, or
|
|
111
112
|
`patchedDependencies` for any `@agent-native/*` package
|
|
113
|
+
- Don't run `pnpm patch` or `pnpm patch-commit`, or commit files under
|
|
114
|
+
`patches/`, for any dependency
|
|
112
115
|
- Don't edit `node_modules/@agent-native/core` or
|
|
113
116
|
`node_modules/@agent-native/dispatch`
|
|
114
117
|
- Don't invent local "dispatch behavior" shims to paper over version skew
|
|
@@ -42,7 +42,10 @@ function viewForPath(pathname: string): string {
|
|
|
42
42
|
if (pathname.startsWith("/database")) return "database";
|
|
43
43
|
if (pathname.startsWith("/extensions")) return "extensions";
|
|
44
44
|
if (pathname.startsWith("/observability")) return "observability";
|
|
45
|
-
if (pathname.startsWith("/agent")
|
|
45
|
+
if (pathname.startsWith("/settings/agent") || pathname.startsWith("/agent")) {
|
|
46
|
+
return "agent";
|
|
47
|
+
}
|
|
48
|
+
if (pathname.startsWith("/settings")) return "settings";
|
|
46
49
|
if (pathname.startsWith("/team")) return "settings";
|
|
47
50
|
return "chat";
|
|
48
51
|
}
|
|
@@ -60,7 +63,7 @@ function pathForView(view?: string): string {
|
|
|
60
63
|
case "observability":
|
|
61
64
|
return "/observability";
|
|
62
65
|
case "agent":
|
|
63
|
-
return "/agent";
|
|
66
|
+
return "/settings/agent";
|
|
64
67
|
case "settings":
|
|
65
68
|
return "/settings";
|
|
66
69
|
case "team":
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useSetPageTitle } from "@agent-native/toolkit/app-shell";
|
|
1
|
+
import { buildLegacyAgentSettingsRoute } from "@agent-native/core/client/navigation";
|
|
3
2
|
import { Navigate, useLocation } from "react-router";
|
|
4
3
|
|
|
5
4
|
export function meta() {
|
|
@@ -7,34 +6,11 @@ export function meta() {
|
|
|
7
6
|
}
|
|
8
7
|
|
|
9
8
|
export default function AgentRoute() {
|
|
10
|
-
const t = useT();
|
|
11
9
|
const location = useLocation();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"agents",
|
|
19
|
-
"memory",
|
|
20
|
-
"skills",
|
|
21
|
-
"learnings",
|
|
22
|
-
]);
|
|
23
|
-
const destination = resourceTabs.has(legacyTab)
|
|
24
|
-
? `/settings/agent/resources/${legacyTab}`
|
|
25
|
-
: legacyTab === "remote-agents"
|
|
26
|
-
? "/settings/agent/agents"
|
|
27
|
-
: legacyTab === "connections"
|
|
28
|
-
? "/settings/integrations"
|
|
29
|
-
: legacyTab === "jobs"
|
|
30
|
-
? "/settings/agent/automations"
|
|
31
|
-
: legacyTab === "access"
|
|
32
|
-
? "/settings/agent"
|
|
33
|
-
: ["llm", "app-models", "limits", "voice", "background"].includes(
|
|
34
|
-
legacyTab,
|
|
35
|
-
)
|
|
36
|
-
? `/settings/agent/${legacyTab}`
|
|
37
|
-
: "/settings/agent";
|
|
38
|
-
|
|
39
|
-
return <Navigate to={destination} replace />;
|
|
10
|
+
return (
|
|
11
|
+
<Navigate
|
|
12
|
+
to={buildLegacyAgentSettingsRoute(location.hash, location.search)}
|
|
13
|
+
replace
|
|
14
|
+
/>
|
|
15
|
+
);
|
|
40
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[build]
|
|
2
2
|
ignore = "node ./scripts/netlify-ignore-build.mjs chat"
|
|
3
|
-
command = "export DATABASE_URL=${NETLIFY_DATABASE_URL:-$DATABASE_URL} && pnpm install && NITRO_PRESET=netlify pnpm --filter chat build"
|
|
3
|
+
command = "export DATABASE_URL=${NETLIFY_DATABASE_URL:-$DATABASE_URL} && pnpm install && NITRO_PRESET=netlify pnpm --filter chat build && if [ \"${CONTEXT:-}\" = \"production\" ]; then pnpm --filter chat migrate:production; fi"
|
|
4
4
|
publish = "templates/chat/dist"
|
|
5
5
|
functions = "templates/chat/.netlify/functions-internal"
|
|
6
6
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { closeDbExec, withMigrationRuntime } from "@agent-native/core/db";
|
|
2
|
+
import { runFrameworkReleaseMigrations } from "@agent-native/core/server";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Release-time schema entrypoint.
|
|
6
|
+
*
|
|
7
|
+
* Every deploy runs this once, and request functions never touch schema. That
|
|
8
|
+
* ordering is not an optimization: on serverless, "migrate on first use" means
|
|
9
|
+
* migrate on EVERY cold start, and a production incident traced a multi-hour
|
|
10
|
+
* outage to schema introspection running 4-6 times concurrently on the request
|
|
11
|
+
* path.
|
|
12
|
+
*
|
|
13
|
+
* `withMigrationRuntime()` is load-bearing. The Netlify BUILD environment sets
|
|
14
|
+
* NETLIFY=true, so this script looks like a serverless request to the guard in
|
|
15
|
+
* `runMigrations` — it is allowed to migrate only because it claims duty here.
|
|
16
|
+
* A release entrypoint that forgets the wrapper silently does nothing.
|
|
17
|
+
*
|
|
18
|
+
* If this app owns tables of its own, export its migration runner from
|
|
19
|
+
* `server/plugins/db.ts` and call it inside the same block.
|
|
20
|
+
*/
|
|
21
|
+
async function main(): Promise<void> {
|
|
22
|
+
await withMigrationRuntime(async () => {
|
|
23
|
+
await runFrameworkReleaseMigrations(null);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
await main();
|
|
29
|
+
} finally {
|
|
30
|
+
await closeDbExec();
|
|
31
|
+
}
|