* feat(studio): pack the runner and nb-studio into every build and serve them
Studio's pnpm build now packs the universal nocobase-runner and nb-studio
packages into dist/runners at the exact versions it records in
served-versions.json, and fails when they differ. Studio serves that
directory by default, after agents.dist.dir and NB_STUDIO_RUNNERS_DIST,
so every deployment serves the runner and CLI it was built with; npm
remains the fallback for a Studio without packages.
The release image workflow no longer builds the packages separately or
uploads them as an artifact, and the Dockerfile drops its runners-dist
stage and rejects a prebuilt dist/ without dist/runners. The published
Studio package now includes ai/, which packing nb-studio needs.
* feat(studio-cli): share Studio's version line
nb-studio was served at Studio's version (1.0.0-beta.51) by earlier Studio
builds, so a CLI versioned 0.0.x would never be offered by `nb-studio update`.
@nocobase/studio-cli now starts at Studio's version and joins it in a fixed
changesets group, so both release as 1.0.0-beta.52 and move together.
A beta release that publishes @nocobase/studio now calls v3-studio-image.yml,
which builds Studio from the release tag without baked runner packages and
pushes nocobase/studio:<version> and :beta to Docker Hub and Aliyun's public
registry, like the v2 release images, instead of dispatching the internal
image workflow in 2013xile/nocobase-ci. It also keeps the release's universal
runner and nb-studio packages as an artifact. Internal images stay in
nocobase-ci.
The dispatch to 2013xile/nocobase-ci now mints a NocoBase App token for that
repository (Actions write), as every other workflow here authenticates,
instead of a separate personal access token. When the App cannot mint it, the
release still warns with the manual command and does not fail.
When a beta release publishes @nocobase/studio, dispatch studio-image.yml in
2013xile/nocobase-ci with the release-beta/<batch> tag and release: true, so
the image is built from the released commit and tagged with the Studio
version and beta. The dispatch needs NOCOBASE_CI_DISPATCH_TOKEN and only
warns when it is missing.
* feat(agent-runner): run agents with full access and the runner's real HOME
The runner no longer sandboxes agents: Codex runs with danger-full-access and every approval accepted, Claude Code with bypassPermissions and no hooks, and the command policy and isolated home are gone.
* feat(agent-runner): drop the push guard
The pre-push hook only stopped mistakes once agents run with full access, so it goes, and an earlier runner's is removed on upgrade; protect default branches on the code host instead.
* test(agent-runner): smoke-test real tools with full access
agents.dist.npm maps a product to its npm package and exact version. It is
used only when agents.dist.dir has no current version of that product, and
only for callers that opt in: the resolve route with accept=npm answers
{ kind: 'npm', product, version, package, channel }, and the heartbeat
carries npmUpgrade to runners declaring the new `npm` feature. Everyone
else gets today's answers (artifact, or 404 and no update).
The protocol moves to version 8 for the new feature, as its compatibility
rules require for a feature an older server's schema does not list;
nothing of version 7 changed and versions 3 to 7 are still served.
Studio pins the runner (and nb-studio once @nocobase/studio-cli is a
devDependency) to the versions it was built with: an afterServerBuild hook
records them in dist/server/agents/served-versions.json, and development
reads the installed packages, so the runner never becomes a runtime
dependency of a deployment.
`nocobase cli build --universal` packs one platform-independent tarball per
product that runs on the machine's Node.js 24 or newer. The agents plugin
serves it to any target without a tarball of its own and marks the answer
`universal: true`; the install script checks Node before downloading, links
`<prefix>/node` for the user service, and hints at `corepack enable` when pnpm
is missing. Updates to a universal version pin the Node they ran on, so a
runner moving off a Node-bundling package keeps starting under its service.
Claude-Session: https://claude.ai/code/session_01XFYuunpkqzgMT8C24A4PvY
@nocobase/studio-cli is nb-studio, NocoBase Studio's command line:
@nocobase/app-cli-client run with Studio's nocobase.cli brand, shipping the
nb-studio-cli Skill under skills/ where the runner looks for a CLI's Skills.
A machine with Node.js 24 can now install it from npm instead of from a
Studio server's standalone tarball.
Studio's nocobase.cli and ai/skills/nb-studio-cli remain what
`nocobase cli build` packs; a script test keeps the package's copies equal
to them.
`202610220010_studio_rename_package` moved Studio's i18n namespace from
`studio` to `@nocobase/studio` in workflow definitions, but the owner
notices those workflows already recorded keep a copy of the message in their
activity details (95 rows in production), which the inbox and an issue's
recent activity translate. A new migration,
202610220020_studio_rename_activity_namespace, rewrites them, and back on
rollback.
actions/setup-node was given registry-url: PRO_NPM_REGISTRY without a scope, so it wrote registry=<Pro registry> as the default registry for every package. The new Pro registry (pkg-v3.nocobase.com) serves only @nocobase/* and does not proxy npmjs, so the pnpm install in "Freeze the OSS ... snapshot and install" failed: the minimumReleaseAge check fetched metadata for lodash, @ai-sdk/* and every other third-party package from the Pro registry and got 401 for all of them. The old npm.nocobase.ai proxied the whole of npmjs, which hid the misconfiguration.
Set scope: '@nocobase' on the setup-node step in the beta and stable Pro release workflows so only @nocobase resolves through the Pro registry and everything else uses npmjs, and pass PRO_NPM_TOKEN as NODE_AUTH_TOKEN to the install step so @nocobase metadata requests carry the token setup-node references in .npmrc. Publishing and dist-tag steps already pass --registry and NODE_AUTH_TOKEN and are unaffected. The promote workflow configures no registry and is left unchanged.
Add a policy test that keeps the Pro registry scoped and the install step authenticated.
NocoBase Studio moves from the private nocobase/studio repository
(archived at e4a18fd) into packages/apps/studio and is published as
@nocobase/studio. The framework submodule, the mirrored workspace file,
the lockfile and the submodule check go away; Studio now resolves the
framework packages and plugins from this workspace.
- packages/apps is a new package category for product applications.
check-openapi checks Studio, and the database test portability check
covers it; Studio's tests now take their databases from
@nocobase/app-testing.
- A new migration, 202610220010_studio_rename_package, moves the
migration and seed history recorded under the old package name
`studio` to `@nocobase/studio` and rewrites the i18n namespace of
workflow definitions copied from the software template. Released
migrations are unchanged.
- Studio follows the framework changes since its last submodule
pointer: the workflow plugin and the client's dev and settings route
surfaces are gone.
- Prepared for publication: internal infrastructure, ticket keys and
references to the predecessor product are removed, the demo data is
in English, and tests are no longer published.
* feat(app-template-default): introduce agent-driven development on the homepage and split template locales
The homepage explains that the application is built by asking a coding agent, with a sample request, and lists the built-in capabilities as cards whose dialogs offer editable, copyable prompts. Both templates move their own copy to client/locales/system/, which the application locale files spread before their own groups.
* feat(app-template-default): align homepage accents with the brand theme
* fix(projects): keep workflow save actions visible and guard unsaved edits
* fix(projects): restore workflow navigation and saved state
* fix(app-client): preserve editors during blocked history navigation
* fix(app-client): preserve navigation guards after native hash changes
* fix(app-client): recover navigation after duplicate history indexes
* fix(app-client): restore navigation across history index resets
* fix(agent-runner): report Claude Code models
Claude Code lists its models and efforts through the Agent SDK's supportedModels(), on a session that is sent no prompt, instead of reporting detection as unsupported.
* fix(agents): match Codex reasoning efforts to current releases
Codex takes low through xhigh, max and ultra, and no longer minimal; max is passed as itself. A saved effort its tool dropped stays until the entry changes.
* fix(agents): keep model effort cells aligned and drop the built-in badge
Reported efforts move to a line under the entry and name only selectable efforts, so the effort select no longer shifts its row. Model suggestions lose the Built-in badge.
* fix(agents): wrap long descriptions in the agents list
The description wraps inside a capped name column, two lines at most with the full text on hover, so other columns keep their widths.
* fix(agents): group the agents list and sort it by shown name
Everyone agents come first, the application's own in the order it added them, then the caller's own, then shared ones, each by translated name. List entries carry owned.
* feat(agent-runner): give agents the runner's Node.js and pnpm
The runner ships pnpm and puts node and pnpm launchers first on each run's PATH, pinned against packageManager switching; config set agent-tools system opts out. Store pruning uses the bundled pnpm.
* fix(agent-protocol): update the coding tools' suggested models
* fix(agent-protocol): suggest Sonnet 5 and Haiku 4.5, the current model ids
* fix(agent-protocol): include current models and qualify Pi suggestions
* feat(agents): suggest models reported by runtimes
* fix(agents): show model suggestions in a wider combobox and drop unpublished models
* fix(agents): expand model suggestions and pluralize runtime counts
* fix(agent-runner): let Codex write each working tree's .agents and skip unchanged skills in skills sync
* fix(agent-runner): validate skill roots and preserve submodule paths
* test(mail): wait for the compose action to become available
* test(mail): control time in credential lease renewal coverage
* fix(agent-runner): restrict writable skill roots to canonical directories
* feat(agents): pass proxy and CA variables, let the runner's owner pass and set variables, and take variables from the runner
* fix(runner): detect local provider keys and preserve service variables
* fix(agents): preserve application notice and enqueue types
* test(mail): control lease time while awaiting refresh heartbeats
* chore: redeploy the Studio preview on a fresh database
* fix(agents): drop the RunnerNotice alias and order the runner variables migration after the workspace usage one
* fix(agent-runner): keep task git metadata in reference clones
* fix(agent-runner): guard host git from writable checkout configuration
* fix(agent-runner): guard host git from writable checkout configuration
* fix(agent-runner): accept standard submodule configuration on resume
* feat(agents): define the runner workspace report and subject settlement contract
* feat(agent-runner): remove working directories once their work is over or over the size limit
* style(agent-runner): format workspace cleanup sources
* fix(agents): order the workspace usage migration after execution history
* fix(agent-runner): keep workspace records out of the agent's reach and never remove unpushed work
* style(agent-runner): format the workspace record reader
* test(agent-protocol): use a neutral subject key in the workspace fixture
* fix(agent-runner): run pnpm in a runner-owned directory and stop sharing store files through hard links
Also replace the workspace size cap with a min-free-disk threshold read from statfs, so collection no longer walks every node_modules.
* fix(agent-runner): probe whether the work root clones and import with clone or copy
pnpm's clone-or-copy falls back to hard links on file systems that cannot clone, so the runner probes the work root once and picks clone or copy itself.
* fix(agent-runner): default min-free-disk to 5G and remove only settled workspaces on a low disk
Pushed workspaces whose work goes on are no longer removed automatically; the runner warns once per pass and points to gc.