feat: persist permission auto-accept on server (#2158)

Move per-session permission auto-accept policy ownership from the UI to the
OpenChamber server so enabled sessions continue running when clients disconnect
or the server restarts.

- persist explicit per-session policies in OpenChamber settings
- inherit the nearest explicit policy across subagent session hierarchies
- allow child sessions to opt out of an inherited parent policy
- immediately accept matching global and directory-scoped pending requests
- process future requests without requiring a connected UI client
- reconcile pending permissions after startup and event-stream reconnects
- deduplicate concurrent requests and retry transient reply failures
- synchronize policy updates across connected clients
- migrate existing browser-persisted policies to server storage
- suppress auto-accepted permission cards before they enter UI state
- show deduplicated permission toasts for inactive sessions
- preserve foreground-only permission handling in VS Code
- integrate directory-aware notification routing from main
- add coverage for persistence, inheritance, retries, reconciliation, pending
  requests, client hydration, and inactive-session toasts
This commit is contained in:
Bohdan Triapitsyn
2026-07-12 15:03:16 +03:00
committed by GitHub
parent 3d90eddcaf
commit d738d41574
18 changed files with 795 additions and 387 deletions
@@ -6,6 +6,7 @@ import { registerGitHubRoutes } from '../github/routes.js';
import { registerGitRoutes } from '../git/routes.js';
import { registerMagicPromptRoutes } from '../magic-prompts/routes.js';
import { registerSessionFoldersRoutes } from '../session-folders/routes.js';
import { registerPermissionAutoAcceptRoutes } from '../permission-auto-accept/runtime.js';
import { registerConfigEntityRoutes } from './config-entity-routes.js';
import { registerSettingsUtilityRoutes } from './core-routes.js';
import { registerProjectIconRoutes } from './project-icon-routes.js';
@@ -98,6 +99,7 @@ export const createFeatureRoutesRuntime = (dependencies) => {
scheduledTasksRuntime,
getOpenChamberEventClients,
writeSseEvent,
permissionAutoAcceptRuntime,
} = routeDependencies;
registerSettingsUtilityRoutes(app, {
@@ -106,6 +108,8 @@ export const createFeatureRoutesRuntime = (dependencies) => {
clientReloadDelayMs,
});
registerPermissionAutoAcceptRoutes(app, permissionAutoAcceptRuntime);
registerOpenCodeRoutes(app, {
crypto,
clientReloadDelayMs,