Minor Changes
-
2b6fea3: Fix the Automations page reporting runs that never happened, and add run history and schedule editing.
A scheduler or dispatcher tick that declined to run an automation used to stamp
lastRunwith the current time, so a permanently blocked automation reported a
fresh run every minute while itsnextRunstayed frozen in the past. Skipped
ticks now recordlastCheckinstead, leavelastRunalone, and only rewrite the
resource when the failure state actually changes. The failure reason
(lastError) is surfaced on the row and in the details view instead of being
swallowed behind a bareskippedchip.Schedules are also timezone-aware. Cron expressions used to be read in the
server's zone, so an automation created as "every day at 8am" ran at 8am UTC.
A schedule now stores the IANA zone it was written in, taken from a new
scheduling timezone preference in Account settings and falling back to the
caller's browser zone. Descriptions name their zone ("Every day at 8 AM
(America/New_York)"), and both the agent tools and the schedule editor accept a
timezone. Existing schedules keep their current host-relative meaning until
edited.Also adds:
automation_runshistory for real executions, exposed through a new
list-automation-runsaction and a Past runs section in the details view.- A Details view that shows more than the list row: schedule, next/last run,
last checked, last status, scope, creator and model. - An Edit affordance for changing a scheduled automation's cron expression and
timezone. - A "Manage agent" entry in the sidebar organization switcher.
Run history is bounded and honest about interrupted runs: a row left
running
past the point a run could still be alive is reported asinterruptedrather
than shown as permanently in-flight, and rows are pruned per automation so a
frequent schedule cannot grow the table without limit. Recording a run's
outcome also re-reads the automation first, so a schedule edited while it was
running is no longer reverted by the completion write.Also from review: a completion write no longer recreates an automation deleted
mid-run, a run-history write failure can no longer reclassify a completed
automation as failed, deleting an automation forgets its run history so a new
one reusing the name does not inherit it, an unusableX-User-Timezoneheader
is rejected rather than persisted, and a settings read failure surfaces instead
of silently pinning a schedule to the host zone.Run history never blocks the automation it describes: opening the record,
attaching its thread and closing it out are all non-fatal, so an unwritable
history table costs the record rather than the run.
Patch Changes
-
2b6fea3: Cache peer agent cards instead of re-probing every sibling app on each lookup.
describe-workspace-appsships in the default first-request tool set and the
<available-apps>prompt block names it, so a single turn could probe every
peer and the next turn would do it all again. Against a local dev gateway each
probe also cold-starts the app it touches, so one tool call spawned a dev server
per sibling at once and the machine stalled behind them. Cards are now cached
per caller for 30s with concurrent probes collapsed onto one request; failures
expire after 5s so a peer that was still booting is retried promptly rather than
being reported skill-less. -
2b6fea3: Add
agent-native cleanto reclaim disk from regenerable build caches, and report disk usage inagent-native doctor.cleanis a dry run unless--apply, prints the bytes it reclaims per category, and surfaces any delete it could not complete instead of reporting a clean total. It refuses any root it cannot confirm is an Agent Native project — apackage.jsonthat parses and depends on@agent-native/core, anagent-native.json, or a workspace with an app underapps/that has either; a manifest it cannot read or parse is a refusal naming the file and the reason, never a permit. Every target is a real directory entry matched by exact name, so a hand-writtenBuild/is not selected by thebuildrule on a case-insensitive filesystem, and each one is re-checked against the identity recorded at scan time immediately before the delete, so a parent swapped mid-run is a reported failure rather than a delete somewhere else. It treats an unknown flag or a valueless--cwdas a usage error rather than guessing, and counts a hard-linked file only when every link to it is inside the delete set — one deploy bundle linked into several function directories counts once, and one still linked fromnode_modules/counts nothing, because removing it frees nothing. A byte is credited only where the run observed it removed, so an outcome it could not observe is a typed result rather than a number: a tree another process deleted first — a secondclean, or Vite recreating.vitemid re-optimize — credits nothing instead of two runs both claiming it, a target already gone when re-checked is a no-op rather than a failure, a re-measure that cannot read what survived reports the bytes as unknown rather than as zero, and a scan stopped by the walk-depth cap says so instead of returning a short total. Underapps/, each app must confirm for itself that it is Agent Native before anything inside it is selected, so one app no longer licenses deleting a sibling Rust project'sbuild/or a personal folder'sdist/. Protected names —data/,.git,node_modules,.env*— now match case-insensitively while targets stay case-exact, soData/is not descended into on a case-insensitive filesystem. The walk and the delete stop at a filesystem mount boundary. One unreadable directory is reported once rather than once per pass, a partial run's headline states the exact shortfall rather than rounding to look complete, and--json --helpanswers in JSON.doctornow shows free space on the volume holding the project and flags low free space;doctor --diskalso measures how muchcleancould give back. -
2b6fea3: Keep workspace development lazy by default so unused apps do not build Vite
dependency caches and consume disk and memory. Background prewarming remains
available with--prewarmorWORKSPACE_PREWARM=1. -
2b6fea3: Fail closed when an
ai-sdk:*engine has no provider key, instead of sending an
unauthenticated request. The provider factory was previously built with no
apiKey, so the SDK omitted the Authorization header and the gateway's 401 came
back ashttp_401"Missing Authentication header" — a transport error naming the
wrong cause, which a scheduled job then retried on every tick forever. It now
reportsmissing_credentialsand names the env var it wants, matching what
builder-engineandanthropic-enginealready did.Also stop reaping in-process background automations (scheduler and trigger runs)
at the tight 45s post-claim stale window. That window exists to reach a durable
successor sooner, but these runs carry nodispatch_payloadand have no
successor to reach, so an early reap killed still-working jobs that nothing could
recover. They now get the 90s background window, and the recovery path reports
not_redispatchablerather thanpayload_missing, which read as data loss for
the one case where nothing was ever lost. -
2b6fea3: Stop writing a second full copy of the server bundle for every extra Netlify
function. The durable-background, integration-recovery, workspace
<app>-server, and Vercel<app>-server.funcemits now share one on-disk copy
through hard links, so a build no longer doubles (or, in a workspace, multiplies)
its function output. Each function still ships a complete, independent bundle —
only the wasted disk goes away. Builds also stop emitting the throwaway
dist/<app>/<app>client build for presets that already mountpublicDirat the
app base path. -
2b6fea3: Harden hosted authentication and preview database isolation against account-claim exposure.
-
2b6fea3: Stop writing sourcemaps into the Vite dependency pre-bundle cache, which roughly halves
node_modules/.vite/deps(and the transient double-size peak during a re-optimize) so workspaces stop running out of disk. SetAGENT_NATIVE_DEP_SOURCEMAPS=1to restore them when stepping into third-party code in the debugger. -
2b6fea3: Stop workspaces from accumulating duplicate physical copies of
@agent-native/core.agent-native upgradenow rewrites thelatestspecs it installs back to the
exact resolved versions, so a committed manifest pins one release instead of
re-resolving on every install. If a version cannot be read after a successful
install, upgrade reports which specs are still floating rather than claiming
the upgrade finished. Apackage.jsonthat cannot be parsed is now named in
that report and stops the run, instead of being skipped as if it were clean.Apps added to an existing workspace inherit the framework versions the
workspace root already pins, and freshly scaffolded workspaces resolve
@types/node,esbuild,srvx, andzodonce workspace-wide.typescript
is no longer a peer dependency of core — core never imported it, and the peer
edge forked a separate ~175 MB copy of core per TypeScript version in use. -
2b6fea3: Keep the full Agent workspace reachable from chat-only sidebars, including generated migrated apps. The sidebar link now opens the Agent page where context, resources, connections, automations, and access are managed.
-
2b6fea3: Allow organization owners and admins to require Google sign-in, revoke current sessions when enabled, and enforce the policy across all auth entry points.
-
2b6fea3: Keep local package linking fast and deterministic when scaffolding during framework development.
-
2b6fea3: Keep scaffolded workspaces compatible with the current h3 and srvx releases.
-
2b6fea3: Share the browser's realtime sync transport across feature subscribers and reconnect local SSE streams after terminal failures.
-
2b6fea3: Share one sync stream per origin across browser tabs instead of opening one per
tab. The browser caps HTTP/1.1 connections at roughly six per origin per browser
process, so every extra tab's EventSource permanently consumed one of them and
ordinary requests queued behind the held streams — worst in local development,
where the dev gateway serves every workspace app from a single origin. Tabs now
elect a stream holder through Web Locks and receive its frames over
BroadcastChannel; followers relax to the fallback poll cadence, and Web Locks
promotes a new holder automatically when that tab closes. Browsers without Web
Locks or BroadcastChannel keep the previous per-tab behavior. -
2b6fea3: Make browser Demo mode visible in the shared organization switcher, explain what it changes, and avoid showing the redacted anonymous email as the signed-in identity.
-
2b6fea3: Shrink the published package by roughly 47 MB of allocated disk per install.
Source maps, thecorpus/coreandcorpus/toolkittrees, and thesrc/tree
were three separate copies of source that already ships asdist/,docs/, and
@agent-native/toolkit's ownsrc/. The tarball now ships only the eject
entries and scaffolding templates out ofsrc/, andcorpus/carries the
first-party template source thatsource-searchactually reads. Docs and
source-searchnow point atdist/for framework internals instead of a corpus
path that no longer exists. -
2b6fea3: Forward incremental action input to browser chat surfaces so apps can preview generated content while an action is being prepared.