diff --git a/server/dev-server.mjs b/server/dev-server.mjs
index 65a654a..21b5e65 100644
--- a/server/dev-server.mjs
+++ b/server/dev-server.mjs
@@ -2545,12 +2545,16 @@ function isPublicPoolUser(data, user) {
function resolveUserServiceModules(data, user, serviceSlug, clientId) {
if (!user?.id) return {};
- const normalizedClientId = normalizeOptionalText(clientId);
- if (!normalizedClientId) return {};
const service = data.services.find(
(candidate) => candidate.slug === serviceSlug || candidate.authentikApplicationSlug === serviceSlug
);
if (!service?.id) return {};
+ if (hasSystemServiceModuleEntitlement(user, service, "codex_agents")) {
+ return { codex_agents: true };
+ }
+
+ const normalizedClientId = normalizeOptionalText(clientId);
+ if (!normalizedClientId) return {};
return Object.fromEntries(
(data.serviceModuleEntitlements ?? [])
@@ -2565,6 +2569,10 @@ function resolveUserServiceModules(data, user, serviceSlug, clientId) {
);
}
+function hasSystemServiceModuleEntitlement(user, service, moduleId) {
+ return user?.id === "user_root" && moduleId === "codex_agents" && service?.slug === "task-manager";
+}
+
function getFrontchannelLogoutUrls() {
const urls = [config.taskLogoutUrl];
const launcherData = readLauncherData();
diff --git a/src/widgets/admin-overlay/AdminOverlay.tsx b/src/widgets/admin-overlay/AdminOverlay.tsx
index 079b1ff..34c24b1 100644
--- a/src/widgets/admin-overlay/AdminOverlay.tsx
+++ b/src/widgets/admin-overlay/AdminOverlay.tsx
@@ -3425,7 +3425,8 @@ function OperationalCoreAccessModal({
{operationalCoreModules.map((module) => {
- const enabled = hasServiceModuleEntitlement(data, client.id, user.id, service.id, module.id);
+ const systemEnabled = hasSystemServiceModuleEntitlement(user, module.id);
+ const enabled = systemEnabled || hasServiceModuleEntitlement(data, client.id, user.id, service.id, module.id);
const pendingKey = serviceModuleEntitlementKey(client.id, user.id, service.id, module.id);
const pending = Boolean(pendingServiceModuleEntitlements[pendingKey]);
@@ -3435,7 +3436,7 @@ function OperationalCoreAccessModal({
className={cn("task-module-access-row", enabled && "task-module-access-row--enabled", pending && "task-module-access-row--pending")}
type="button"
aria-pressed={enabled}
- disabled={pending}
+ disabled={pending || systemEnabled}
onClick={() =>
onSetServiceModuleEntitlement({
clientId: client.id,
@@ -3454,7 +3455,7 @@ function OperationalCoreAccessModal({
{enabled ? : null}
- {pending ? "Сохраняем..." : enabled ? module.enabledLabel : module.disabledLabel}
+ {pending ? "Сохраняем..." : systemEnabled ? "Системно включён" : enabled ? module.enabledLabel : module.disabledLabel}
);
@@ -4813,6 +4814,10 @@ function hasServiceModuleEntitlement(data: LauncherData, clientId: string, userI
);
}
+function hasSystemServiceModuleEntitlement(user: LauncherUser, moduleId: ServiceModuleId): boolean {
+ return user.id === "user_root" && moduleId === "codex_agents";
+}
+
function isOperationalCoreService(service: Service): boolean {
return service.slug === "task-manager" || service.authentikApplicationSlug === "task-manager";
}