mirror of
https://github.com/nocobase/nocobase.git
synced 2026-10-16 15:07:08 +08:00
chore(projects): merge v3-develop updates
This commit is contained in:
@@ -1,278 +0,0 @@
|
||||
# Plugin CLI Contributions
|
||||
|
||||
Read this reference when a plugin must add commands to an App's `pnpm nocobase` tree or run plugin-owned commands at defined points in the App build or development startup.
|
||||
|
||||
CLI is an explicit composition surface alongside Client and Server. A plugin may contribute any subset of `./client`, `./server`, and `./cli`; the presence of one never implies another.
|
||||
|
||||
## Command ownership and boundaries
|
||||
|
||||
An App CLI assembles three command sources:
|
||||
|
||||
| Command path | Owner |
|
||||
| --------------------------------------- | -------------------------------------------------------------------- |
|
||||
| `package *`, `plugin *`, and `skills *` | Built into `@nocobase/nb3-cli` |
|
||||
| `app *` | The App's `cli/commands/` |
|
||||
| `<plugin-topic> *` | A plugin exported through `./cli` and registered in `cli/plugins.ts` |
|
||||
|
||||
Use plugin CLI commands for work a person or CI invokes explicitly from files and packages, such as validating static declarations or generating artifacts. The plugin declaration is imported while the command tree is assembled, before an App Runtime or ServiceContainer exists. Put runtime operations behind authenticated Server APIs, Services, or Jobs rather than assuming the CLI can resolve a running application.
|
||||
|
||||
Topics share one flat namespace. A plugin topic must be lower-case kebab-case and globally unique; collisions with built-in, App, or other plugin topics fail assembly and name both owners. Command keys are lower-case kebab-case and may use colon-separated nesting: `artifact:build` becomes `nocobase demo artifact build`.
|
||||
|
||||
## Implement an oclif command
|
||||
|
||||
Commands are oclif `Command` subclasses:
|
||||
|
||||
```ts
|
||||
// cli/greet.ts
|
||||
import { Args, Command, Flags } from '@oclif/core';
|
||||
import type { Interfaces } from '@oclif/core';
|
||||
|
||||
export default class DemoGreet extends Command {
|
||||
static override summary = 'Print a greeting.';
|
||||
|
||||
static override examples: Command.Example[] = [
|
||||
'<%= config.bin %> <%= command.id %> world',
|
||||
'<%= config.bin %> <%= command.id %> world --json',
|
||||
];
|
||||
|
||||
static override args: {
|
||||
target: Interfaces.Arg<string, Interfaces.CustomOptions>;
|
||||
} = {
|
||||
target: Args.string({ description: 'Who to greet.', required: true }),
|
||||
};
|
||||
|
||||
static override flags: {
|
||||
loud: Interfaces.BooleanFlag<boolean>;
|
||||
json: Interfaces.BooleanFlag<boolean>;
|
||||
} = {
|
||||
loud: Flags.boolean({
|
||||
default: false,
|
||||
description: 'Upper-case the greeting.',
|
||||
}),
|
||||
json: Flags.boolean({
|
||||
default: false,
|
||||
description: 'Print one JSON result.',
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const { args, flags } = await this.parse(DemoGreet);
|
||||
const message = flags.loud
|
||||
? `HELLO, ${args.target.toUpperCase()}!`
|
||||
: `Hello, ${args.target}.`;
|
||||
|
||||
if (flags.json) {
|
||||
this.logJson({ ok: true, message });
|
||||
return;
|
||||
}
|
||||
this.log(message);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use `<%= config.bin %>` and `<%= command.id %>` in examples so help reflects the actual assembled binary and path.
|
||||
|
||||
Explicit `args`, `flags`, and `examples` types matter because plugin packages emit declarations with `isolatedDeclarations`. Type each flag precisely, such as `Interfaces.BooleanFlag<boolean>`; a broad `Interfaces.FlagInput` can make the parsed result lose its useful type.
|
||||
|
||||
Keep command modules cheap to import. Load heavy SDKs or optional dependencies with `await import()` inside the named `run()` method so `--help` does not initialize them.
|
||||
|
||||
For machine-readable behavior, emit one JSON document on success, send failures to stderr, and preserve a nonzero exit code. Treat exit code `2` as invalid usage and `1` as a runtime error unless the command has a documented, stable extension.
|
||||
|
||||
## Declare the CLI plugin
|
||||
|
||||
Statically import command classes and pass them to `defineCliPlugin()`:
|
||||
|
||||
```ts
|
||||
// cli/index.ts
|
||||
import { defineCliPlugin, type AppCliPlugin } from '@nocobase/nb3-cli/plugins';
|
||||
|
||||
import DemoArtifactBuild from './artifact-build.ts';
|
||||
import DemoGreet from './greet.ts';
|
||||
|
||||
const cliPlugin: AppCliPlugin = defineCliPlugin({
|
||||
packageName: '@nocobase/app-plugin-demo',
|
||||
topic: 'demo',
|
||||
description: 'Commands for the Demo plugin.',
|
||||
commands: {
|
||||
greet: DemoGreet,
|
||||
'artifact:build': DemoArtifactBuild,
|
||||
},
|
||||
});
|
||||
|
||||
export default cliPlugin;
|
||||
```
|
||||
|
||||
The definition validates the scoped package name, topic, command keys, command classes, and hook stages. A plugin may provide hooks without commands. A CLI definition with neither commands nor hooks is allowed but warns because registering it has no effect.
|
||||
|
||||
## Export and publish the entry
|
||||
|
||||
Expose the source and compiled forms of `./cli`:
|
||||
|
||||
```json
|
||||
{
|
||||
"exports": {
|
||||
"./cli": {
|
||||
"types": "./cli/index.ts",
|
||||
"import": "./cli/index.ts"
|
||||
}
|
||||
},
|
||||
"publishConfig": {
|
||||
"exports": {
|
||||
"./cli": {
|
||||
"types": "./dist/cli/index.d.ts",
|
||||
"import": "./dist/cli/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nocobase/nb3-cli": "workspace:^",
|
||||
"@oclif/core": "^4.14.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Follow the repository catalog and peer-dependency rules when the current workspace range changes; do not copy the example version blindly. Both packages are runtime contracts for the contributed entry, and one compatible oclif major keeps parsing and help behavior consistent. Ensure `cli/` is compiled into the published `dist` and the package `files` includes that output.
|
||||
|
||||
## Register the explicit App composition root
|
||||
|
||||
An App owns `cli/plugins.ts`:
|
||||
|
||||
```ts
|
||||
import {
|
||||
defineCliPlugins,
|
||||
type AppCliPlugins,
|
||||
} from '@nocobase/nb3-cli/plugins';
|
||||
import demo from '@nocobase/app-plugin-demo/cli';
|
||||
|
||||
const cliPlugins: AppCliPlugins = defineCliPlugins([demo]);
|
||||
|
||||
export default cliPlugins;
|
||||
```
|
||||
|
||||
`pnpm plugin:register demo` detects the exact `exports["./cli"]` entry and adds this import and array item. A plugin with no `./cli` export is skipped. `--disabled` installs the dependency but skips Client, Server, and CLI wiring; there is no persistent `nocobase.plugins.enabled` flag that later discovers the contribution. The explicit composition files are the active registration state.
|
||||
|
||||
Array order is contribution order. It controls command registration and, within each stage, build and dev hook execution. Removing the import and item removes that plugin's CLI contribution.
|
||||
|
||||
All plugin packages are recorded in the App's `dependencies`, including Client-only and disabled packages, so deployment dependency resolution is consistent. Registration removes a duplicate declaration from `devDependencies`. It does not create `package.json#nocobase.plugins`; unregistration only cleans an old entry there when a legacy manifest already contains one.
|
||||
|
||||
The App assembles its CLI in `cli/index.ts`:
|
||||
|
||||
```ts
|
||||
#!/usr/bin/env node
|
||||
import { runAppCli } from '@nocobase/nb3-cli/runtime';
|
||||
|
||||
import appCommands from './commands/index.js';
|
||||
import cliPlugins from './plugins.js';
|
||||
|
||||
await runAppCli({
|
||||
commands: appCommands,
|
||||
plugins: cliPlugins,
|
||||
});
|
||||
```
|
||||
|
||||
Invoke `pnpm nocobase`, which runs this App-owned entry and therefore includes App and plugin commands. Invoking only the package binary provides built-in management commands and cannot infer App-owned contributions without the App entry.
|
||||
|
||||
The App's `cli/` source is compiled with the server side and runs in the deployed artifact as `node ./cli/index.js`. Use `.js` specifiers between App CLI source files so emitted ESM resolves correctly.
|
||||
|
||||
## Declare build and dev hooks
|
||||
|
||||
A CLI plugin can attach commands to App lifecycle stages:
|
||||
|
||||
```ts
|
||||
const cliPlugin: AppCliPlugin = defineCliPlugin({
|
||||
packageName: '@nocobase/app-plugin-workflow',
|
||||
topic: 'workflow',
|
||||
commands: { build: WorkflowBuild },
|
||||
buildHooks: {
|
||||
afterServerBuild: [
|
||||
{
|
||||
label: 'Build workflow artifacts',
|
||||
command: [
|
||||
'pnpm',
|
||||
'nocobase',
|
||||
'workflow',
|
||||
'build',
|
||||
'--resource-root',
|
||||
'./dist/workflows',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
devHooks: {
|
||||
beforeDev: [
|
||||
{
|
||||
label: 'Prepare workflow artifacts',
|
||||
command: ['pnpm', 'nocobase', 'workflow', 'build'],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Choose a stage by what exists when the hook runs:
|
||||
|
||||
| Stage | Available state |
|
||||
| ------------------ | -------------------------------------------------------------------------- |
|
||||
| `beforeBuild` | `dist` has just been cleared and is empty |
|
||||
| `afterClientBuild` | `dist/client` exists |
|
||||
| `afterServerBuild` | `dist/client` and `dist/server` exist and server paths have been rewritten |
|
||||
| `afterBuild` | The complete deployment artifact and installed dependency tree exist |
|
||||
| `beforeDev` | The long-running development processes have not started |
|
||||
|
||||
There is only one dev stage because concurrent client and server dev processes do not have a meaningful shared “after” point.
|
||||
|
||||
A hook `command` is a non-empty array containing an executable and its arguments. The App spawns it directly without a shell, so arguments containing spaces need no quoting, while `&&`, pipes, redirects, globs, and `FOO=value` prefixes do not work. Declare multiple hooks for ordered commands or call a dedicated script. The working directory is the App root.
|
||||
|
||||
Hooks run in `cli/plugins.ts` order and then declaration order. One failure stops the pipeline. Unknown stage names throw during CLI assembly so a typo cannot silently omit required output.
|
||||
|
||||
Inspect the resolved plan without running hooks:
|
||||
|
||||
```bash
|
||||
pnpm nocobase plugin cli-hooks
|
||||
pnpm nocobase plugin cli-hooks --json
|
||||
```
|
||||
|
||||
The App's plain Node build and dev scripts use this command to obtain hooks because they cannot import TypeScript plugin entries themselves. Failure to resolve hooks must fail the pipeline; continuing would produce an apparently successful build with missing artifacts.
|
||||
|
||||
## Development-only App commands
|
||||
|
||||
Commands that require Vite or Client source cannot run from the server deployment. Keep them in the App's `cli/dev-commands/`, exclude that directory from `tsconfig.server.json`, and load it only when `cli/index.ts` is executing from source. Use the Default Template's guarded dynamic import pattern; a literal import causes TypeScript to include the directory despite `exclude`.
|
||||
|
||||
Deployment-safe plugin commands belong in the plugin's compiled `./cli` entry. A plugin cannot rely on the App's development-only loader for published behavior.
|
||||
|
||||
## Plugin management commands
|
||||
|
||||
Use the App's scripts for normal lifecycle work:
|
||||
|
||||
| Command | Current effect |
|
||||
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `pnpm plugin:register <name>` | Installs the plugin into `dependencies`, wires each exported `./client`, `./server`, and `./cli` root, and synchronizes shipped Skills unless `--no-skills` is set |
|
||||
| `pnpm plugin:inspect <name> --json` | Reads static dependency, explicit composition, and Skill facts without changing files |
|
||||
| `pnpm plugin:unregister <name>` | Removes explicit roots, cleans dependency and legacy metadata, removes synchronized Skills, and uninstalls unless `--no-install` is set |
|
||||
| `pnpm plugin:update [name]` | Updates one or all explicitly registered plugin packages and then synchronizes Skills |
|
||||
| `pnpm skills:sync` | Synchronizes Skills from direct NocoBase dependencies and explicitly registered plugins without upgrading packages |
|
||||
| `pnpm package:remove <package>` | Removes a direct NocoBase package and its synchronized Skills; plugin packages reuse full unregistration |
|
||||
|
||||
Prefer `--dry-run --json` when an Agent needs a plan. If an uninstalled plugin is requested, register dry-run returns `requires-installation` because it cannot inspect exports until the package exists; install it and rerun to compute the wiring plan. Read the JSON `ok` and `status` fields, preserve nonzero failure exits, and treat `success-noop`, `partial-success`, and `requires-installation` as distinct outcomes.
|
||||
|
||||
`plugin:inspect` proves only that readable static registration surfaces agree. It does not execute commands or hooks, start Runtime contributions, evaluate permissions, test behavior, or replace package and App validation.
|
||||
|
||||
Repository root scripts add `--workspace-root .`, select `app-template-default` unless `--app` is supplied, resolve plugin packages from workspace directories, and record `workspace:^`. A generated App runs the same implementation from its own directory, resolves installed packages from `node_modules`, and keeps its installed version range.
|
||||
|
||||
## Verification
|
||||
|
||||
- Run the plugin's focused lint, typecheck, tests, and build; include a test that imports the production `./cli` definition and asserts the real command or hook contract.
|
||||
- Register the plugin in a target App and verify the exact `cli/plugins.ts` import and array entry.
|
||||
- Run `pnpm nocobase <topic> --help`, the command's normal path, its JSON path when offered, invalid input, and a representative failure.
|
||||
- For hooks, inspect `plugin cli-hooks`, then run the affected App build or dev startup and verify the expected artifact or behavior at the selected stage.
|
||||
- Build the target App and run the deployed CLI path for commands intended to work in production.
|
||||
|
||||
Current implementation and maintained examples:
|
||||
|
||||
- [CLI plugin types](../../../../packages/tools/cli/src/plugins/types.ts)
|
||||
- [CLI plugin validation](../../../../packages/tools/cli/src/plugins/define.ts)
|
||||
- [CLI assembly](../../../../packages/tools/cli/src/runtime/assemble.ts)
|
||||
- [CLI example plugin](../../../../packages/examples/app-plugin-cli-example/cli/index.ts)
|
||||
- [Default Template CLI composition](../../../../packages/templates/app-template-default/cli/index.ts)
|
||||
- [Plugin registration implementation](../../../../packages/tools/cli/src/lib/plugin-registration.ts)
|
||||
- [Skills synchronization implementation](../../../../packages/tools/cli/src/lib/skills-sync.ts)
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@nocobase/app-template-default": patch
|
||||
"@nocobase/app-template-examples": patch
|
||||
"@nocobase/app-skills": patch
|
||||
---
|
||||
|
||||
Clarify application access URLs for agents: use the Hono server entry in full-stack development, verify the actual port and base path, and use the local Vite entry only in remote-backend proxy mode.
|
||||
@@ -2,7 +2,7 @@
|
||||
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
|
||||
"changelog": "@changesets/cli/changelog",
|
||||
"commit": false,
|
||||
"fixed": [],
|
||||
"fixed": [["@nocobase/studio", "@nocobase/studio-cli"]],
|
||||
"linked": [],
|
||||
"access": "public",
|
||||
"baseBranch": "v3-develop",
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
'@nocobase/app-plugin-users': patch
|
||||
'@nocobase/app-plugin-projects': patch
|
||||
'@nocobase/app-cli-client': patch
|
||||
'@nocobase/app-plugin-notification': patch
|
||||
'@nocobase/app-plugin-authentication': patch
|
||||
---
|
||||
|
||||
Return invitation links after successful email delivery and let authorized original inviters generate a fresh link without sending email. Show copy controls for newly created and resent invitations, confirm rotation, and explain when a concurrent change makes the link unavailable. Keep scalar URLs complete in CLI text output; structured fields retain their compact display.
|
||||
|
||||
Preserve registration through invitation links without requiring an email channel or configured public origin. Links use app.publicOrigin when configured and otherwise the invitation request origin. Acceptance leaves the new account's email unverified. Existing accounts must sign in with the invited identity, and each token accepts only its own invitation. Only token hashes are stored; rotation invalidates the previous link.
|
||||
|
||||
When no authentication base URL is configured, derive the trusted origin for cookie writes from each request URL using Better Auth's proxy-header policy. This allows same-origin invitation acceptance with unrelated or session cookies while rejecting cross-origin writes and preserving configured origins.
|
||||
|
||||
Retrieve plugin invitations through their domain-authorized endpoint. Recheck the original inviter's current role and project permissions. Other managers may resend email but do not receive credentials; scoped credentials remain email-only. Renewal ignores deleted projects if at least one remains, checking access to each remaining project, and rejects renewal if all selected projects are gone.
|
||||
|
||||
Send invitation credentials through a transient notification attempt without durable message snapshots, automatic retries or raw provider diagnostics. Preserve safe failure categories and submission status. Batches use at most five concurrent sends and a shared 30-second mail-delivery budget. Recheck each link after sending or exhausting the budget so concurrent closure or rotation does not expose invalid links or discard other recipients and existing-account project updates.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@nocobase/app-plugin-agents': patch
|
||||
---
|
||||
|
||||
Normalize formatting of the agent distribution API description without changing its content or behavior.
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
'@nocobase/agent-protocol': minor
|
||||
'@nocobase/app-plugin-agents': minor
|
||||
'@nocobase/agent-runner': minor
|
||||
---
|
||||
|
||||
Give a run's git a repository credential whenever it needs one, instead of one handed out at the claim that a long run outlives, and say why a push failed.
|
||||
|
||||
- Protocol version 9 adds the `gitCredentials` runner feature, `RunGit.onDemand` (repository URLs whose credential the runner asks for), `POST /api/agents/runners/runs/:runId/gitCredentials` (`GitCredentialRequest` → `GitCredential`), the reasons `REPO_ACCESS_UNAVAILABLE` and `REPO_ACCESS_DENIED`, the run failures `repoAccessUnavailable` (retried) and `repoAccessDenied`, and `RepoReport.failure` (`authFailed`, `credentialUnavailable`, `credentialDenied`, `leaseLost`, `rejected`, `error`). Nothing of version 8 changed: an application on this version still hands claim-time credentials to runners without the feature. A runner of this version is refused by an application that does not know version 9, so update the application before its runners.
|
||||
- Repository access providers may implement `issue(request)`. For a runner with the feature the claim tells them `onDemand` (in `forRun`'s context and `prepare(run, { onDemand })`), they list their repositories in `RunGit.onDemand` and mint nothing at the claim; the plugin then calls `issue` outside any transaction, within 15 seconds, only while that runner holds that attempt of the run under a live lease, and only for a URL the claim listed, compared exactly. `issue` answers a credential with its expiry, null when the repository is not its own, or throws `RepoAccessError('unavailable' | 'denied', message)` with a message safe to show; with `refresh` it should issue a new credential rather than a cached one. Each issued credential is added to the run's redaction, and is never stored. A provider without `issue` keeps working as before.
|
||||
- Migration `202610100002_ag_add_run_git_credentials` adds `agRuns.gitCredentialUrls` (the URLs the claim listed) and `agRunRepos.failureReason` and `failureDetail`; a run's repositories (`RunRepo`) gain optional `failure` so existing application schemas remain compatible. The server always supplies it, null when the repository was pushed or not tried. Applications should show it, since a run that completed may still have work that was not pushed.
|
||||
- The runner keeps a run's credentials in the worker's memory and no longer puts any password in the agent's environment. The agent's git gets them through the runner's credential helper, which reaches the worker over a Unix socket private to the run; the runner's own git (checkout, submodules, the end-of-run push, which previously sent no credential) uses the same, never the host's credential helpers, and retries once with a fresh credential when the remote refuses one. The agent is told on stderr why git got no credential, and each failure is recorded as an `error` event with `meta.kind` `gitCredential`.
|
||||
- Host-side operations in task checkouts use the safe Git wrapper, retaining its metadata and configuration checks, protected hooks and fixed push URL/refspec. Run credentials disable restoration of host helpers; the agent environment clears helpers per repository URL before installing the runner's helper. Confirmed pushes update remote-tracking refs and the protected workspace record so cleanup recognizes pushed work.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@nocobase/app-plugin-projects': patch
|
||||
---
|
||||
|
||||
Add pasted image files to the new issue requirements file list while preserving native text paste behavior, and enable image previews for pasted and manually uploaded images with the shared attachment UI.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@nocobase/app-skills': patch
|
||||
---
|
||||
|
||||
Guide agents to the theme-aware React Flow and ELK diagram components from the application and lifecycle Skills. Document execution history, inline labels and end markers, and synchronize the offline UI Library catalog.
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
"@nocobase/app-plugin-lifecycle-example": patch
|
||||
---
|
||||
Improve lifecycle diagram readability with neutral styling and focused current-state highlights and optimized port ordering that reduces edge crossings while preserving every transition. Place transition labels directly on their routed edges with opaque backgrounds to keep their associations clear. Use solid lines for every transition and retain the gear icon to identify automatic transitions.
|
||||
|
||||
Show the current state, visited states, and exact traversed edges with restrained execution highlighting derived from the record transition log.
|
||||
|
||||
Display a separate end marker for each explicitly final state, inheriting execution highlighting without merging terminal branches.
|
||||
|
||||
Use the application primary theme color for execution highlights and the diagram legend.
|
||||
|
||||
Align fractional self-loop bends with their ports to preserve orthogonal routing.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@nocobase/app-plugin-lifecycle-example": patch
|
||||
---
|
||||
|
||||
Translate durable workflow diagram transitions in the example application so English pages no longer fall back to Chinese labels.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@nocobase/app-plugin-lifecycle-example': patch
|
||||
---
|
||||
|
||||
Replace Mermaid rendering in the lifecycle example with interactive React Flow and ELK diagrams that use vertical layout and content-based height, retaining Mermaid source export and record-history highlights. Preserve fixed node geometry during parent refreshes so edges do not disappear during countdown updates.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@nocobase/app-plugin-lifecycle-example": minor
|
||||
---
|
||||
|
||||
Add an electronic invoicing example with signed callbacks, timeout queries, idempotent submission retries, sample PDF downloads, and bilingual pages with independently installable sample records.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
'@nocobase/ai-employee': patch
|
||||
---
|
||||
|
||||
Add a read-only MCP settings page backed by declarative `config.yml` configuration, with connection testing and tool inspection.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Add typed application configuration schemas for declarative AI knowledge-base vector databases and manifest sources.
|
||||
@@ -4,9 +4,7 @@
|
||||
'@nocobase/app-plugin-authentication': minor
|
||||
'@nocobase/app-plugin-authorization': minor
|
||||
'@nocobase/app-plugin-users': patch
|
||||
'@nocobase/app-plugin-hub': minor
|
||||
'@nocobase/app-template-default': minor
|
||||
'@nocobase/app-template-hub': minor
|
||||
'@nocobase/create-app': minor
|
||||
---
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Include the template-print implementation Skill in every official application template.
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
'@nocobase/agent-protocol': patch
|
||||
'@nocobase/agent-runner': patch
|
||||
'@nocobase/app-plugin-agents': patch
|
||||
---
|
||||
|
||||
Claude Code now reports its models and their reasoning efforts through the Agent SDK's `supportedModels()`, without sending a prompt, instead of reporting model detection as unsupported.
|
||||
|
||||
Codex reasoning efforts are now `low`, `medium`, `high`, `xhigh`, `max` and `ultra`, as current Codex releases advertise them: `minimal` is gone, and `max` is passed to Codex as itself rather than as `xhigh`. An agent entry already saved with an effort its tool no longer takes keeps it until the entry is changed.
|
||||
|
||||
In an agent's tools and models, the effort select stays aligned with the rest of its row, and the reported efforts are listed on a line of their own below the entry, naming only efforts that can be chosen. Model suggestions no longer carry a "Built-in" badge. In the agents list, a long description wraps within the name column, two lines at most, with the full text on hover. The agents list now shows the agents everyone can use first, the application's own in the order it added them, then the viewer's own agents, then the ones others share with them, each group by the name shown in the viewer's language; list entries carry `owned`, whether the caller owns the agent.
|
||||
|
||||
The runner now gives agents its own Node.js and pnpm: it ships pnpm 11.7.0 and writes `node` and `pnpm` launchers first on each run's PATH, and keeps pnpm from switching to the version a repository's `packageManager` names, so `pnpm install` works on a machine without pnpm or with another Node.js. `nocobase-runner config set agent-tools system` keeps the machine's own instead. The runner's own `pnpm store prune` also uses the bundled pnpm, so garbage collection no longer needs pnpm on the runner's PATH.
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
'@nocobase/agent-protocol': minor
|
||||
'@nocobase/app-plugin-agents': minor
|
||||
'@nocobase/studio': minor
|
||||
---
|
||||
|
||||
An application can name the runner and its CLI on npm when it has no tarball of them. `agents.dist.npm` maps a product to its npm package and an exact version, such as `{ nocobase-runner: { package: '@nocobase/agent-runner', version: '1.0.0' } }`; a product `agents.dist.dir` has a current version of is still served from there exactly as before. Only callers that say they understand the answer receive it: the resolve route (`/api/agents/dist/products/<product>/targets/<target>`) answers `{ kind: 'npm', product, version, package, channel }` (or `kind=npm` lines with `format=env`) to a request with `accept=npm`, and a heartbeat answer carries `npmUpgrade` instead of `upgrade` only to a runner that declares the new `npm` feature. Every other caller gets what it got before: the artifact when there is a tarball, otherwise a 404 and no update.
|
||||
|
||||
`@nocobase/agent-protocol` adds `DistNpmPackage`, `DistResolution`, `DIST_ACCEPT_NPM`, `NpmUpgradeNotice`, `HeartbeatResponse.npmUpgrade` and the `npm` runner feature (`NPM_UPGRADE_FEATURE`), and moves `PROTOCOL_VERSION` to 8 so that a runner announcing `npm` is refused cleanly by a server that does not know it. Nothing of protocol 7 changed: a server speaking 8 still serves runners speaking 3 to 7. A runner speaking 8 is shown as needing an upgrade by an application that serves only up to 7, so upgrade the application before its runners.
|
||||
|
||||
NocoBase Studio pins the runner it serves to the exact `@nocobase/agent-runner` version it was built with, recorded by `pnpm build` in `dist/server/agents/served-versions.json` (the runner stays out of the deployment's dependencies), and names it on npm when its image carries no runner tarballs. Redeploying Studio moves runners that understand npm updates to that version.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Keep assistant messages, tool messages, and tool-call persistence atomic behind encapsulated conversation provider implementations.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Add human-readable display titles to the built-in data metadata, data query, and business analysis report skills and their data tools. Replace legacy translation markers in all built-in tool titles and about text with plain English metadata so management views display readable text instead of internal resource names or unresolved templates.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Fix an AI chat task that could be silently dropped when it was triggered right after the chat's employees and models loaded. The queued task was taken by an effect of an earlier render, whose stale model selection made the send abort, so the task's context was attached but nothing was sent.
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Use the NocoBase AI chat mark for the floating AI employee chat entry instead of the generic `lucide-react` `Bot` glyph on a solid primary square. The trigger now shows the same brand artwork the Portal template uses for this entry.
|
||||
|
||||
The mark ships as an inlined `NocoBaseAIChatIcon` React component under `shared/icons/` rather than an `.svg` asset import. Registry source is copied into an application and typechecked with plain `tsc`, so an asset import would require shipping a `declare module '*.svg'` declaration into every consuming application alongside it.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Cancel a pending throttled message update when an AI chat stops listening to a conversation. The update used to fire after the chat unmounted, which reached React after the page, or a test environment, had already been torn down.
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Check `ai.llmServices` in `config check`, and warn about a service with no key
|
||||
|
||||
`defineAIConfig`, exported from `@nocobase/app-plugin-ai-employee/server/config`, declares the `ai` section with the plugin's validation, the way `defineAuthConfig` does for `auth`. With it, `pnpm nocobase config check` reports a structural problem in `ai.llmServices` — the list form, a `name` field, a wrong field type or an empty `provider` — as an error by path, instead of the start failing on it later. A service whose built-in provider sends `options.apiKey` and has none is reported as a warning naming that path, with the `config set --from-env` command that sets it; `ollama` and providers an application registers are not checked. An application that keeps a plain `defineAppConfig` for `ai` still starts, with the section unchecked until then; switch `server/config/ai.ts` to `defineAIConfig` to get the checks.
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Add a conversation center to AI settings at `/settings/ai/conversations`. Users who can access AI settings page through every user's conversations, filter them by user, AI employee, and title in any combination, and open one in a routed drawer to read its full history with the chat's read-only message list, loading earlier messages on request. Nothing can be sent, retried, or edited there, and reading does not mark a conversation as read. The filters and the page are kept in the URL, so refreshing, sharing a link, or going back and forward restores them. `conversationCenterPath` is no longer deprecated and points at the new page.
|
||||
|
||||
`GET aiConversations:listAll` accepts `userId` and `aiEmployeeUsername` filters alongside `keyword`, and each row now carries the owning `user` (`id`, `name`, `username`) and the `aiEmployee` (`username`, `nickname`, `avatar`), read in two batched queries per page. It now lists main conversations only: a sub-agent session is shown inside the main conversation that delegated to it and is no longer listed on its own. The new `GET aiConversations:listUsers` suggests users for the user filter, returning only users who own a main conversation, and requires the same AI settings access. The client adds `listConversationUsers` and `listConversationEmployees` to `useAIEmployeeClient()`, and exports the conversation center's types.
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Require a session on every `/api/ai` action, and AI settings access behind the settings page
|
||||
|
||||
**Breaking.** Every `/api/ai` action now requires a signed-in session and answers 401 without one; the actor is read from that session. The actions that configure AI — `llmServices`, `aiMcpServers`, the management actions of `aiEmployees`, `aiTools` and `aiSkills`, and `ai:listProviderModels` — also require access to the AI settings page (`page:ai.settings`) and answer 403 without it. The chat stays open to every signed-in user: conversations, files, `aiEmployees:listByUser` and `updateUserPrompt`, `ai:listAllEnabledModels` and `ai:listLLMServices`.
|
||||
|
||||
- **LLM services are configured in `config.yml`.** `llmServices:create`, `update` and `destroy` are removed; the settings page changes a configured service through `llmServices:updateEnabled` and `llmServices:updateEnabledModels`, which answer 404 for an unknown name. On the client, `updateLLMService()` becomes `updateLLMServiceEnabled()` and `updateLLMServiceEnabledModels()`.
|
||||
- **MCP connection tests.** `aiMcpServers:testConnection` tests a configured server by `name`, or an inline `http` or `sse` server; an inline `stdio` server is rejected.
|
||||
- **File previews.** `aiFiles:preview` returns a file to the user who uploaded it; anyone else, and any file with no recorded uploader, needs AI settings access — not a root flag or a role name on the session. The file's record is authorized before its content is opened, so a refused request reads nothing from storage.
|
||||
- **Data tools.** They authorize as the user with every subject the authorization service resolves, so a collection granted through a team is readable by the assistant as it is on the page.
|
||||
|
||||
Upgrading: an account that manages AI needs AI settings access; code calling `updateLLMService()` switches to the two narrower functions; and a stdio server is tested by its configured `name`.
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
'@nocobase/ai-employee': minor
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Give an agent execution one state, one context and a result contract
|
||||
|
||||
**Breaking.** An agent execution is now described once and reached through public types:
|
||||
|
||||
- **One `AgentState`.** `parseAgentState()` builds it where the request body is parsed, and it reaches `createAIEmployee()` whole. `sessionId` is required, `model` is `{ llmService, model }`, and `messages` is `handoffMessages`, the message a sub-agent receives when the user answers its pending question with a new turn. `AgentServiceFactory` replaces `model` once, against the employee's own policy, and `SubAgentsDispatcher` replaces `sessionId` for a sub-agent's own conversation. `AgentRequest` keeps only what varies per call — `userMessages`, `userDecisions`, `messageId`, `writer`, `signal`, and `runtime` for middleware data — so a request can no longer ask for a model the employee does not allow.
|
||||
- **One `AgentContext`**: `actor`, `state`, `deps`, `runtime` (the host's `logger`, `translate` and `getHeader`) and `availableSkills`. `ai`, `database`, `repositories` and `services` are gone. A tool declares the container tokens it needs in `dependencies` and reads them, resolved and typed, from `ctx.deps`; a token the container cannot resolve fails the run naming the tool and the token. The context is bound when a tool is built, so an `agentContext` key on a request reaches nothing. The data tools declare an authorized, read-only reader rather than the database.
|
||||
- **Required identity.** `CreateEmployeeOptions` and `CreateAgentOptions` require `actor` and `runtime`, and `createAgent()` requires `sessionId`; neither fills in an implicit root any more. `CreateEmployeeOptions.tools`, which nothing could fill, is removed: an employee's tools come from its own `skillSettings`, narrowed by the conversation's `skillSettings`.
|
||||
- **A result contract.** `invoke()`, `resumeInvoke()` and `forkInvoke()` return `AgentInvokeResult`: the assistant turn as `message` in this package's `AIMessageInput` shape, or `null`; `structuredResponse` when the request passes a Zod `responseFormat`; and `interrupt: { id, actions }` when a tool paused the run for approval. An interrupted `invoke()` records the paused calls as `stream()` does, so a decision can be attached to them and the run resumed with `interrupt.id`.
|
||||
- **A conversation to run in.** `AIConversationsManager.create()` resolves to `CreatedAIConversation`, whose `sessionId` is a `string`.
|
||||
- **Exports.** `AgentRequest`, `AgentInvokeRequest`, `AgentInvokeResult`, `AgentInvokeInterrupt`, `AgentInterruptAction`, `AgentStreamEvent` and `CreatedAIConversation` are exported from `@nocobase/app-plugin-ai-employee/server`.
|
||||
|
||||
Migrating: pass `state` and `runtime` to `createAIEmployee()` instead of `sessionId`, `webSearch`, `frontendTools` or `execution`; read `ctx.runtime.logger` rather than `ctx.logger`, and `ctx.state.handoffMessages` rather than `ctx.state.messages`; declare a token in `dependencies` wherever a tool read `ctx.ai`, `ctx.database`, `ctx.repositories` or `ctx.services`; pass the bound context as `buildTool(entity, ctx)`'s second argument; read `result.message` rather than `result.messages`; and pass an `actor` everywhere one was left out.
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Classify agent failures, and report the real one
|
||||
|
||||
An agent failure used to reach the caller as `Agent execution failed` with the code `PROVIDER_ERROR`, whatever had gone wrong, and `invoke()` discarded the underlying message on every run. Failures are now classified by the phase they occur in:
|
||||
|
||||
- Anything thrown while resolving the model, the LLM service or the provider is `CONFIGURATION_ERROR`, a new `AgentServiceErrorCode`. `createAgent()` resolves its model and service completely when the agent is created and rejects there; `createAIEmployee()` rejects at creation only when the employee has no usable model at all, and otherwise when the run starts.
|
||||
- `invoke()` and `stream()` report the same message for the same failure, and `AgentServiceError.rootMessage` returns the deepest message in the cause chain, so a caller no longer walks `cause` itself. A provider without `parseResponseError()` no longer turns the failure being reported into a `TypeError`.
|
||||
- `AgentServiceError` and `AgentServiceErrorCode` are exported from `@nocobase/app-plugin-ai-employee/server`, so a caller can check `instanceof`, read `code` and `retryable`, and decide whether to retry.
|
||||
- Over HTTP the chat actions answer `200` with an SSE body whatever the run does, and a failed run arrives as an `error` event; that event now carries the failure's `code` when it is an `AgentServiceError`.
|
||||
|
||||
**Breaking:** a caller that switches exhaustively over `AgentServiceErrorCode` has to handle `CONFIGURATION_ERROR`, and one that matched the literal message `Agent execution failed` now receives the real message instead.
|
||||
@@ -1,5 +1,4 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
'@nocobase/app-cli': patch
|
||||
---
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Fix the `nocobase-ai` chat Registry item, and hold it to an application's lint rules
|
||||
|
||||
Installed copies of the `nocobase-ai` Registry item get these changes by updating it.
|
||||
|
||||
- **Lint.** Installing the item took a generated application from no lint problems to 118, because this package never linted the Registry source with the rules it lands under. It does now, and what the rules found is fixed: refs written or read during render, effects that set state synchronously, `String(value)` over untyped server fields rendering `[object Object]`, promises passed to event handlers, and list items keyed by index. A module that exports a component now exports only components, with its contexts, hooks and helpers in a sibling module such as `ai-context.ts` or `page-context-utils.ts`. Everything exported from `index.ts`, `providers/index.ts` and `components/index.ts` keeps its name; code that deep-imported a hook from a component module follows it to the sibling.
|
||||
- **A chat mounted before the configuration loaded** dropped every message without an error. Its stored employee now follows the one the chat resolves, and a send reads the current configuration.
|
||||
- **A floating chat opens on the chat's `defaultEmployee`.** `AIChatFloatingTrigger` without `aiEmployee` leaves the choice to the chat instead of opening the first employee, and `AIChatProvider` falls back to `defaultEmployee` when its initial selection cannot be found. `AIEmployeeTaskTrigger.aiEmployee` is optional.
|
||||
- **A web search toggle.** `AIChatWindow`, `AIChatCompact` and `ChatComposer` take `enableWebSearch`, which defaults to `false` and puts a web search toggle in the composer next to the file action. It is usable only when the selected model's `supportWebSearch` is `true`, and it switches off when the user moves to a model that cannot search. `AIChatProvider.webSearch` is where the toggle starts, and `useAIChatBase()` gains `webSearch` and `setWebSearch`; a chat that sets `webSearch` without mounting the toggle sends it as before.
|
||||
- **A form in a message's context no longer hides the employee's tools.** The chat sent `skillSettings: { tools: ['formFiller'] }` when no task named any tools, which the server reads as an allowlist and stores on the conversation, so for the rest of that conversation the employee could use only `formFiller` and the system tools. The chat now adds `formFiller` only to a task's own tool list.
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Release the agent checkpoints of conversations nobody has used for a week, every day at 03:00 UTC, through a recurring job on the application's jobs service. A released conversation keeps all of its messages: its next run rebuilds the context from its latest 50 stored messages onto a fresh thread, and goes on from checkpoints again after that. A conversation waiting on a tool decision is never released, and neither is one a run starts on while the job examines it. The new `ai.checkpointCleanup` section sets `enabled`, `cron`, `tz`, `retentionDays`, `batchSize` and the `jobs` configuration to run on; an invalid section is a `config check` error and the plugin refuses to start on it.
|
||||
|
||||
A new migration changes the default of `aiConversations.thread` from 0 to 1, so a conversation inserted without a thread starts on 1 like one created through `AIConversationsManager`; thread 0 now always means a released conversation. A conversation created on thread 0 before this release replays its stored messages onto thread 1 on its next run, instead of continuing from its checkpoint there.
|
||||
|
||||
The plugin now declares `@nocobase/jobs` as a peer dependency. The application templates already depend on it; an application created before them adds `@nocobase/jobs` to its `dependencies` and `JobExecutorServiceProvider` to `server/app.ts`. Without the jobs service the application still starts, without the cleanup, and logs a warning.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': major
|
||||
---
|
||||
|
||||
The client services no longer share a module-level API client. Each service function takes the application's API client as its first argument, and `createAIEmployeeClient(api)` and `useAIEmployeeClient()` return an `AIEmployeeClient` with all of them bound to one client. The `nocobase-ai` registry's `NocoBaseAIService` requires a client in its constructor, the `nocobaseAIService` singleton is removed, and `AIProvider` requires its `service`; `NocoBaseAIRootProvider` still creates one from `useApiClient()` when none is given.
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Group Settings navigation under AI with separate AI Employees, Conversations, LLM services, and MCP services pages while preserving legacy links. Add a read-only conversation center for searching and inspecting application-wide conversation history, protected by the application's AI settings Permission Set access. Reuse Registry conversation lists, message rendering, and history conversion, with safe read-only tool and sub-agent presentation.
|
||||
|
||||
Make the AI Employees list collapsible and hidden by default, with a localized, accessible icon-only toggle centered on the left divider and no employee count or extra detail toolbar. Preserve the original bordered employee cards, 19rem expanded list, detail header, selection, and unsaved edits, with a reserved control gutter and touch-friendly sizing.
|
||||
|
||||
Keep conversation search, pagination, and selection in the URL; improve responsive metadata, accessible search controls, localized timestamps, independent retries, and scroll anchoring when loading earlier messages. Align the Conversations page with the shared AI settings header, background, spacing, and content container while preserving its read-only controls and independently scrollable list and transcript.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Constrain the AI employee editor to a viewport-responsive height and scroll overflowing tab content, including skills and tools, independently of the employee header, tabs, and save controls.
|
||||
@@ -1,6 +1,4 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
'@nocobase/app-plugin-ai-employee-example': minor
|
||||
'@nocobase/app-template-examples': patch
|
||||
---
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Make a fixed agent follow its Skills and pause on a tool that asks
|
||||
|
||||
- **Skills reach the model.** `createAgent({ skills })` activated the tools those Skills name but never gave the model the Skills themselves. A fixed agent given Skills now gets `getSkill`, bound to exactly those Skills, and its system prompt lists them the way an employee's does.
|
||||
- **A tool that asks pauses.** `createAgent()` ran every tool straight away, so a tool declaring `defaultPermission: 'ASK'` — or declaring nothing, which means the same — skipped review in the one kind of agent with nobody watching. It now runs unattended only when it declares `ALLOW`; otherwise the run pauses, `invoke()` reports `interrupt`, and `resumeInvoke()` continues it, as for an employee.
|
||||
- **Where a pause is kept.** A fixed agent keeps its pauses in the plugin's own checkpoint tables under the default persistence, so a newly created agent for the same session can resume them, and in the process beside a persistence the caller supplies. `createAgent()` accepts a `checkpointer` to choose otherwise, and `AgentServiceFactory` provides `getMemorySaver()` and `getDatabaseCheckpointSaver()` to build one without importing `@langchain/langgraph`. `createAIEmployee()` takes none: the chat and the conversation center resume an employee's run from the plugin's tables.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Count a run towards the parallel conversation limit for ten minutes from when it started, rather than from when its conversation was created, so a run in a conversation created more than ten minutes earlier is counted too. A conversation's `updatedAt` now moves to the start of its latest run, which also reorders conversation lists sorted by it.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Answer a send refused at the parallel conversation limit with the limit message instead of a SQL error: the refused user message is now saved with only its stored columns, so the `key` the chat sends with it no longer reaches the insert.
|
||||
@@ -1,6 +1,4 @@
|
||||
---
|
||||
'@nocobase/ai-employee': minor
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-server': patch
|
||||
---
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
'@nocobase/ai-employee': minor
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Keep LLM services, provider model lists and an employee's model limits consistent
|
||||
|
||||
- **`overrideEnabledModels`.** A configured LLM service kept the `enabledModels` stored in the database once it existed, so a model list in `config.yml` took effect only when the service was first created, and a service created without one stayed at zero models whatever was added later. A service that sets `overrideEnabledModels: true` has its configured list reapplied on every load; edits made in AI settings are then overwritten. It governs the list alone: a service an administrator disabled stays disabled even when its entry says `enabled: true`. It defaults to `false`.
|
||||
- **What `enabledModels` constrains.** It scopes the model selector, `ai:listAllEnabledModels` and the model `resolveModel()` falls back to; a caller that names a model is not checked against it. The documentation now says so, and `ModelService` loses `requireModel()`, an unreachable check that suggested otherwise.
|
||||
- **An employee's own models.** For an employee with its own model settings, the chat offers only the models it lists that are currently enabled, in its order, opens on the first, and sends the one it shows; the server runs no other. When none of them is enabled, the chat offers no model and cannot send, and the server rejects the run with a `CONFIGURATION_ERROR` rather than falling back to another model. Installed copies of the `nocobase-ai` Registry item get the chat half by updating.
|
||||
- **Breaking: provider model lists.** `LLMProviderMeta.models` is typed for embedding model suggestions alone, and `ai:listModels` answers only `model=EMBEDDING`. Chat models are listed from each provider's own API through `ai:listProviderModels`, and the hard-coded chat model lists nothing read are removed, as is the Tongyi provider, which was commented out and exported nothing.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Persist AI employee collection field metadata so Oracle returns booleans and integers with their logical types. Let the database query layer encode and decode JSON once, and use a round-trippable name for the default LLM service field. This changes initialization definitions and requires recreating development databases initialized with the previous definitions.
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
'@nocobase/ai-employee': patch
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Make MCP servers configurable only in `config.yml`, and keep their state
|
||||
|
||||
- **Environment references.** `${NAME}` in `ai.mcpServers` — `headers`, `args`, `env` and `url` — was sent to the server literally; it is now expanded as it is for LLM services, and a missing variable becomes an empty string.
|
||||
- **Persistent state.** The enable switch and tool permissions set in AI settings reset at every start. Servers are now stored in `aiMcpClients`: `enabled` in `config.yml` applies when a server is first created and the switch is the administrator's after that, and tool permissions are saved on the server's row in a new `toolPermissions` column, added by a migration. Both belong to the server's name, so removing or renaming a server in `config.yml` discards them. The row holds the configuration with every `${NAME}` expanded, so a credential in `headers` or `env` is stored in plain text and is part of database backups.
|
||||
- **An unreachable server.** One server that did not answer stopped the application from starting. It is now skipped with a warning naming it, whose reason reduces any URL to its origin, and the other servers keep their tools. Nothing retries until the client is rebuilt — at start, or when a server is switched on or off.
|
||||
- **Unknown tools.** Setting the permission of a tool no connected server exposes answered success and kept nothing; `aiMcpServers:updateToolPermission` now answers 404, and `MCPServerManager.updateMCPToolPermission()` throws.
|
||||
- **Breaking:** `AIResourceRegistrarOptions.mcpDirectory` and the protected `AIResourceRegistrar.loadMCP()` are removed, since the configuration sync deleted any server registered that way on its next run. Move such servers into `config.yml`. `registerAIResources()` runs tools, then Skills, then employees.
|
||||
@@ -1,5 +1,4 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-skills': patch
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Remove the SQL identifier quoting and `DB_UNDERSCORED` naming rules from the AI employee system prompt. AI employees read data only through the Repository-backed data tools, which take Collection and field names and apply the Connection naming strategy themselves, so the instructions to write SQL and convert names to snake_case described a capability they do not have.
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
'@nocobase/ai-employee': minor
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Fix attachments, direct provider calls, and web search on a provider that cannot search
|
||||
|
||||
- **Attachments.** DeepSeek received no images, and a user dropping a screenshot was told the type is unsupported; images now go to the model as content blocks. Ollama failed the whole turn on a PDF; it now sends images as content blocks and documents through the document loader. An uploaded file kept only the ASCII characters of its name, so `客户截图.png` was stored as `.png`, and once a message was sent its attachments came back from history with no preview address, so an image showed as a plain file; `DriveFileStorage` now stores the name as given, minus any directory part, while only the storage key is reduced to safe characters, and history gives every stored attachment the preview address its upload returned.
|
||||
- **Web search that cannot search.** `subAgentWebSearch` asked for built-in search and invoked the model even on a provider that ignores the request, which then answered from training data with sources that looked real, reported as success. It now checks `supportWebSearch` and `webSearchModels` first, and returns an error naming what did not happen and what to use instead.
|
||||
- **Tools on a direct call.** `LLMProvider.prepareChain()` — and so `invoke()` and `stream()` — built `context.tools` with each tool's position in the list where its context belongs, and never resolved its `dependencies`. `AIChatContext` gains an optional `toolContext` (`{ agentContext, container? }`), and tools are built with the new `buildAgentTools()`, giving each the context and resolved `deps` an agent does; `createToolContext()` and `ToolRuntimeContext` are exported beside it, and the plugin's agents use the same function. Without `toolContext` a tool that requires a context fails when called. Built-in web search is meant for a call without tools: passing both now logs a warning, and binding is otherwise unchanged.
|
||||
- **Breaking (types only).** `AIChatContext.systemPrompt`, `decisions` and `middleware`, which a provider never read, are removed, and so is the unused `AIChatContextOptions`. A direct call's system prompt is a `role: 'system'` message at the start of `messages`; a paused run is resumed through `AgentService.resumeInvoke()`.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Treat a credential Better Auth refuses — an expired or revoked API key — as not signed in when resolving the caller, instead of failing the request.
|
||||
@@ -1,8 +1,6 @@
|
||||
---
|
||||
'@nocobase/app-client': patch
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Publish the application-owned AI Employee frontend Registry with its chat components. Plugin-owned development showcases now live under `client/dev`, outside the materialized Registry item, and are excluded from production application builds. The Registry uses the application-scoped `@nocobase/app-client` transport for JSON, upload, and streaming requests instead of the deprecated Portal SDK client. The Default and Hub templates scan plugin Registry source for Tailwind utilities, so materialized components retain their intended responsive layout and sizing.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Remove the unused `knownRoles` option and getter from the AI employee service, together with the `AI_DEFAULT_ROLES` environment variable it read. Nothing passed the option or read the getter, so setting the variable had no effect; AI employees take roles from the requesting actor.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Keep system and custom role editors at the same height, avoid marking an unchanged empty custom editor as modified, and align employee save actions with the editor's right edge.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Expand the employee list by default when multiple AI employees are available, while preserving manual toggling. Let system and custom role editors fill the available detail area above the action bar.
|
||||
@@ -1,5 +1,4 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': major
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
---
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Fit the AI employee and conversation settings pages to the available height on large screens, so the page no longer scrolls around the list, detail and message panes that already scroll on their own. On viewports too short for a usable layout the page keeps a minimum height and scrolls once as a whole.
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
将 AI Employee Plugin Skill 移至插件标准的 `skills/` 源目录,确保发布包可以包含并同步该 Skill。
|
||||
|
||||
Move the AI Employee Plugin Skill into the plugin-standard `skills/` source directory so it can be included in the published package and synchronized correctly.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
The `nocobase-app-plugin-ai-employee` Skill's frontmatter is valid YAML again. Its unquoted `description` contained a colon followed by a space, which YAML reads as the start of a nested mapping, so Skill loaders that parse the frontmatter strictly skipped the Skill entirely.
|
||||
@@ -1,5 +1,4 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
'@nocobase/app-skills': patch
|
||||
---
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Add a standalone, read-only Skills catalog immediately after AI Employees with permission-protected management list and detail endpoints. Display associated tool names in a searchable table and show skill titles, descriptions, safe Markdown, and tool metadata in a detail dialog. Include English and Chinese translations, cancellation-safe loading, and retryable errors without executing tools or changing runtime skills endpoints.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Use the default application template's switch in the AI settings pages, so switches match the rest of the application and their thumb sits evenly in the track in both states under compact themes.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Tool messages and the tool replies written when a tool call is interrupted get their ids from the application's id generator, like every other message. They were given random UUIDs, which the bigint `aiToolMessages.id` and `aiMessages.messageId` columns reject on PostgreSQL and MySQL, so on those databases every agent tool call failed to save and the run stopped with `Tool call messageId is required`. SQLite stored the strings.
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Add a usage statistics page under the AI settings group, reporting token consumption and call volume from the events `aiUsageEvents` already records.
|
||||
|
||||
The page shows range totals against the same window one period earlier — today against the same hours yesterday, not against the stretch that just ended, which a range ending midway through a day would otherwise be measured against — a trend chart of input and output tokens, and a breakdown by model, AI employee, or user that exports to CSV. Cached tokens are already counted inside the input tokens, so the chart splits the input bar into its uncached and cached halves instead of adding a segment that would count them twice. Filters cover the time range, AI employee, and model, and they live in the URL so a view can be shared. It reuses the `ai.settings` page grant rather than introducing a permission of its own, and is built from the plugin's own UI primitives like the other AI settings pages: its trend chart is drawn in the host theme's `--chart-1` to `--chart-3` colors, so it follows theme and color-scheme changes, and carries the same values in a table for assistive technology.
|
||||
|
||||
The four backing actions — `aiUsage:summary`, `aiUsage:series`, `aiUsage:breakdown` and `aiUsage:filterOptions` — aggregate in SQL rather than reading events into memory. Grouping by period needs a column to group by: `occurredAt` is an epoch-millisecond bigint, and the portable query builder exposes no date function, so a migration adds `aiUsageEvents.occurredHour`, a UTC hour index, backfills it from the existing rows, and indexes it. Day, week, and month buckets are folded from those hours in the service, which is also what lets the day boundary follow the viewer's timezone instead of being fixed to UTC; offsets are rounded to whole hours, so a half-hour zone such as +05:30 places its bucket edge up to 30 minutes from local midnight.
|
||||
|
||||
`AIEmployeeClient` gains `fetchUsageSummary`, `fetchUsageSeries`, `fetchUsageBreakdown` and `fetchUsageFilterOptions`, which call those actions through the application's API client.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
'@nocobase/ai-employee': patch
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Fixed knowledge-base document uploads in ESM applications, made parsed-document cache paths filesystem-safe, corrected embedding-model API requests and database boolean handling, and prevented non-image chat attachments from rendering as broken image previews.
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Identify `ai.aiKnowledgeBase.vectorDatabases` entries by `key` instead of `name`. This is a breaking change to the application configuration contract: `key` is now required and must be unique within one configuration, and `name` is now optional.
|
||||
|
||||
`key` is the stable identifier of a record — the knowledge-base plugin matches existing records by it when synchronizing declarative configuration, and its settings page lists it as the UID. `name` is only a display title, shown as the Title, and falls back to `key` when omitted, so two entries may share the same name.
|
||||
|
||||
A configuration written against the previous contract fails to typecheck until each entry's `name` is renamed to `key`. Keep `name` alongside it only when a separate display title is wanted.
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Key `ai.llmServices` by service name, and stop expanding `${NAME}` in AI configuration
|
||||
|
||||
**Breaking.** `ai.llmServices` is now a map keyed by service name, like `ai.mcpServers`, instead of a list of entries that each carry a `name`. The list form, and a `name` field inside an entry, are rejected at startup with a message naming the path. Each service therefore has a stable configuration path, such as `ai.llmServices.openai.options.apiKey`, which `pnpm nocobase config set` can write and an `env` mapping can target; neither can address an item of a list.
|
||||
|
||||
**Breaking.** `${NAME}` in `ai.llmServices` and `ai.mcpServers` is no longer expanded, and `expandEnvironmentReferences` is no longer exported. The plugin read those values from `process.env`, which a built server started with `pnpm start` does not merge `.env` into, so a key kept in `.env` became an empty string there. A key is now written into `config.yml` with `pnpm nocobase config set --from-env`, like a database password. Where a service manager, container or CI injects it instead, the application maps the variable in `env` of `server/config/ai.ts`, which reads the process environment together with `.env` and `.env.local` in development and in a built server alike, and `pnpm nocobase config env` lists it.
|
||||
|
||||
The plugin's Skill follows: an agent writes the service entry without the key and without invented model ids, tells the user the key's path to set rather than asking for the key or building a command that reads one, and has the models picked on the LLM services page, which fetches them from the provider with the configured key.
|
||||
|
||||
To upgrade an application:
|
||||
|
||||
1. In `config.yml`, and in `config.example.yml` if it lists services, move each `ai.llmServices` entry under its name and delete its `name` field — `- name: openai` followed by its fields becomes `openai:` followed by the same fields.
|
||||
2. For each `${NAME}` under `ai.llmServices` or `ai.mcpServers`, write the value into the untracked `config.yml` with `pnpm nocobase config set --from-env <path>=<VARIABLE>`, such as `ai.llmServices.openai.options.apiKey=OPENAI_API_KEY`. Where the environment injects the key instead, remove the value and map the variable in `server/config/ai.ts`, declaring the section with `defineAIConfig` from `@nocobase/app-plugin-ai-employee/server/config` in place of `defineAppConfig`: `env: { OPENAI_API_KEY: envString('llmServices.openai.options.apiKey') }`, with `envString` from `@nocobase/app-server/config`. Either way the value is the whole field, so a header such as `Authorization: Bearer ${TOKEN}` needs `Bearer <token>`.
|
||||
3. Run `pnpm nocobase config check`, which now warns about any `${NAME}` left in either section, and `pnpm nocobase config env` when a variable is mapped.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/ai-employee': patch
|
||||
---
|
||||
|
||||
Replace the legacy translation marker in the commented Tongyi provider metadata example with a plain English title to match the v3 metadata contract.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Sort the Skills and Tools management pages and AI employee skill and tool lists alphabetically by display title, falling back to the name when the title is empty, using a consistent case-insensitive order.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
'@nocobase/ai-employee': patch
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Register AI Employees and Tools explicitly from server-side resource aggregators, and load plugin and configured Skills from `SKILL.md` directories.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Add matching icons to AI employee, skill, tool, LLM service, and MCP service settings navigation entries.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Use plugin-owned PageContainer and PageHeader components to standardize AI settings page spacing and headings.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Align AI settings route authorization contracts with the current application runtime and remove a duplicate conversation type import after integrating develop.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
---
|
||||
|
||||
Add a read-only Tools catalog immediately after Skills in AI settings, with searchable cards and an accessible right-side details drawer. Show tool documentation safely and input schemas as inert JSON without execution controls. Add independently authorized management endpoints while preserving the existing runtime tools response contract.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Align LLM and MCP service settings tables with the standard administration table layout and page gutters, removing redundant card headings and nested padding. Clarify English and Chinese AI administration page descriptions and consolidate service configuration guidance into the LLM and MCP page introductions.
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Align shared application tooling and dependency declarations with Default while preserving Examples demonstrations and Hub management features. Remove duplicate and unused dependencies, correct repository metadata, and remove obsolete global OpenSSL options from Examples.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-hub': patch
|
||||
---
|
||||
|
||||
Align deployment configuration headings with the comparison editor by reserving the same fixed-width change-control gutter between both columns.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-hub': patch
|
||||
---
|
||||
|
||||
Align Hub dialog backdrops with application templates using a light scrim, supported backdrop blur, and fade transitions.
|
||||
@@ -3,7 +3,6 @@
|
||||
'@nocobase/app-skills': patch
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
An application can set global limits for every `/api` request in a new `api` section of `config.yml`. All three are off by default and nothing is installed for one that is unset, so an application that does not set them behaves as before.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
'@nocobase/app-server': minor
|
||||
'@nocobase/app-template-default': minor
|
||||
'@nocobase/app-template-hub': minor
|
||||
---
|
||||
|
||||
Run application migrations and seeds on explicitly selected database connections, with per-connection configuration, startup policies, isolated results and fail-fast execution. Keep plugin tasks on the default system connection and reject task execution against externally managed databases. Preserve legacy configuration and directory support while adopting database/<connectionName> source directories in both application templates; add --connection and --all CLI options and document upgrade rules.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Resolve the development entry point's application root two levels above scripts/dev. Start workflow builds, plugin watchers, Vite and the application server from the application directory so pnpm dev no longer tries to read scripts/package.json or writes workflow artifacts under scripts/dist.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
'@nocobase/app-template-default': minor
|
||||
'@nocobase/app-template-hub': minor
|
||||
'@nocobase/app-plugin-authorization': minor
|
||||
'@nocobase/authorization': patch
|
||||
---
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
'@nocobase/app-server': minor
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Declare database dialect drivers on the application's own database config.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-workflow': patch
|
||||
---
|
||||
|
||||
Translate the built-in workflow pages, as the reference for how a plugin declares its locales and picks up its namespace.
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Declare the packages an application's server, database, and CLI code imports in `dependencies` rather than `devDependencies`, and generate `dist/package.json` from that declaration instead of by scanning the built output.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@nocobase/app-skills': patch
|
||||
---
|
||||
|
||||
Add a record lifecycles reference to the `nocobase-app-development` Skill, telling an agent when to build a staged business record with `@nocobase/lifecycle` instead of a workflow, and how to write its definition, migration, provider, routes, page and tests in an application.
|
||||
@@ -2,7 +2,6 @@
|
||||
'@nocobase/app-server': minor
|
||||
'@nocobase/app-template-default': minor
|
||||
'@nocobase/app-template-examples': minor
|
||||
'@nocobase/app-template-hub': minor
|
||||
---
|
||||
|
||||
A standalone application keeps its data under `APP_STORAGE_DIR` when it is set, absolute or relative to the deployment root, instead of `storage/` in the deployment root. Set it when the deployment root is replaced on every release, as an installer that keeps one directory per release does. Explicit storage paths still take precedence, and embedded applications keep the volume their host provides. The Hub template's own `HUB_STORAGE_DIR` is gone in favour of it: a Hub deployment that sets only `HUB_STORAGE_DIR` must rename it to `APP_STORAGE_DIR` before upgrading, or the Hub starts on an empty storage directory.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@nocobase/app-template-default': patch
|
||||
---
|
||||
|
||||
New applications depend on `@nocobase/lifecycle` by default, so plugins that declare it as a peer dependency resolve in production deployments.
|
||||
@@ -1,10 +1,8 @@
|
||||
---
|
||||
'@nocobase/app-cli': minor
|
||||
'@nocobase/app-host': patch
|
||||
'@nocobase/app-plugin-hub': patch
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Declare `tsx` and `typescript` as peer dependencies of `@nocobase/app-tools`, and stop loading the TypeScript compiler on every `pnpm dev`.
|
||||
|
||||
@@ -2,14 +2,10 @@
|
||||
'@nocobase/app-server': minor
|
||||
'@nocobase/create-app': patch
|
||||
'@nocobase/app-client': patch
|
||||
'@nocobase/app-plugin-ai-employee': minor
|
||||
'@nocobase/app-plugin-notification': minor
|
||||
'@nocobase/app-plugin-workflow': minor
|
||||
'@nocobase/app-plugin-hub': minor
|
||||
'@nocobase/app-plugin-service-provider-example': patch
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Provide editable TypeScript defaults for application modules, assembled by the runtime before services start. Module factories receive the runtime with application paths and plugin metadata; deployment files and environment variables override defaults, and configuration reload preserves code defaults.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
"@nocobase/app-template-default": patch
|
||||
"@nocobase/app-template-examples": patch
|
||||
"@nocobase/app-template-hub": patch
|
||||
---
|
||||
|
||||
Encrypt third-party OAuth tokens at rest by setting Better Auth's `account.encryptOAuthTokens: true` in `server/config/auth.ts`. The `accessToken`, `refreshToken` and `idToken` of an `account` row are encrypted with XChaCha20-Poly1305 under a key derived from `auth.secret`, so changing `auth.secret` makes stored tokens unreadable and the user has to link the provider again. Rows written before the option was on keep working: Better Auth returns a value unchanged when it does not look encrypted (no `$ba$` prefix and not an even-length hex string) and encrypts it on the next write, such as a sign-in or token refresh. An existing application adopts this by adding `account: { encryptOAuthTokens: true }` to the `defaults` of its own `server/config/auth.ts`.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Move the login form's "Forgot password?" link under the password input, so pressing Tab in the username field moves to the password instead of the link.
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
'@nocobase/app-plugin-authentication': minor
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Move the password authentication pages to the application. The authentication plugin keeps only the protocol, session state, guards and headless actions: it no longer declares `/login`, `/register`, `/forgot-password` or `/reset-password`, drops the `client/routes` and `client/route-contracts` entries, and removes the `loginPage`/`registerPage` route override options.
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
'@nocobase/create-app': patch
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Support TypeScript authentication options in application templates and use the native authentication client. Keep authentication plugins and callbacks in editable server and client configuration, with YAML as the default format for deployment settings.
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
'@nocobase/authorization': minor
|
||||
'@nocobase/app-plugin-authorization': minor
|
||||
'@nocobase/app-plugin-authorization-example': minor
|
||||
'@nocobase/app-plugin-hub': patch
|
||||
'@nocobase/app-plugin-users': patch
|
||||
'@nocobase/app-plugin-notification': patch
|
||||
'@nocobase/app-server': patch
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
'@nocobase/app-client': minor
|
||||
---
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
'@nocobase/app-plugin-authz-sharing-rules': patch
|
||||
'@nocobase/app-plugin-authz-restriction-rules': patch
|
||||
'@nocobase/app-plugin-authorization-example': patch
|
||||
'@nocobase/app-plugin-hub': patch
|
||||
'@nocobase/app-plugin-users': patch
|
||||
'@nocobase/app-plugin-notification': patch
|
||||
---
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
---
|
||||
'@nocobase/app-client': patch
|
||||
'@nocobase/app-plugin-authorization': patch
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
'@nocobase/app-plugin-hub': patch
|
||||
'@nocobase/app-plugin-users': patch
|
||||
'@nocobase/app-skills': patch
|
||||
---
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
'@nocobase/app-plugin-authz-restriction-rules': minor
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Support entry-level parent references for settings routes contributed by different plugins. Preserve route ownership and localization while resolving nested groups independently of plugin order.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
---
|
||||
"@nocobase/app-plugin-workflow": patch
|
||||
"@nocobase/app-plugin-scheduler": patch
|
||||
---
|
||||
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
"@nocobase/app-plugin-authorization-example": patch
|
||||
"@nocobase/app-template-default": patch
|
||||
"@nocobase/app-template-examples": patch
|
||||
"@nocobase/app-template-hub": patch
|
||||
"@nocobase/app-plugin-hub": patch
|
||||
"@nocobase/app-plugin-ai-employee": patch
|
||||
"@nocobase/app-plugin-notification-in-app": patch
|
||||
---
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-workflow': patch
|
||||
---
|
||||
|
||||
Render boolean workflow parameters with a Switch in the parameter settings dialog.
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
'@nocobase/app-template-default': patch
|
||||
'@nocobase/app-template-examples': patch
|
||||
'@nocobase/app-template-hub': patch
|
||||
---
|
||||
|
||||
Declare `@nocobase/db` and `@nocobase/service-provider` in `dependencies`, so a generated application can build its server
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@nocobase/app-plugin-ai-employee': patch
|
||||
---
|
||||
|
||||
Expose `AIConversationsManager` through the server service container and allow conversation creation without an AI employee for AgentServiceFactory integrations.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user