sync: update from private repo (2ef0fa6)
CI / build-and-test (push) Has been cancelled

This commit is contained in:
oss-sync
2026-06-17 05:23:28 +00:00
parent 517142c61d
commit 1602d52510
42 changed files with 3387 additions and 64 deletions
+65
View File
@@ -7,6 +7,13 @@ import { logger } from '../logger.js';
import { loadConfig } from '../config.js';
import { ConfigManager } from '../config-manager.js';
import { mountConfigApi } from './config-api.js';
import {
mountSetupApi,
buildNoAuthConfigGate,
newNoAuthConfigGateState,
ensureSetupToken,
clearSetupToken,
} from './setup-api.js';
import { mountPiecesApi } from './pieces-api.js';
import { mountToolsApi } from './tools-api.js';
import { mountSkillsApi } from './skills-api.js';
@@ -121,6 +128,13 @@ export interface CoreServerOptions {
configuredRepos?: string[];
generateTitle?: (body: string, ownerId?: string) => Promise<string>;
selectPiece?: (body: string, fileNames: string[], userId?: string) => Promise<string>;
/** On-demand prompt coach for the create dialog (stateless draft evaluation). */
evaluatePrompt?: (req: {
instruction: string;
piece?: string;
userId: string;
signal?: AbortSignal;
}) => Promise<unknown>;
configManager?: ConfigManager;
piecesDir?: string;
customPiecesDir?: string;
@@ -911,6 +925,7 @@ export function createCoreServer(opts: CoreServerOptions): {
authActive,
generateTitle: opts.generateTitle,
selectPiece: opts.selectPiece,
evaluatePrompt: opts.evaluatePrompt,
pieceExists: opts.piecesDir
? (name: string, ownerId?: string) => {
// Mirror the worker's per-user → global-custom → builtin resolution order.
@@ -966,7 +981,57 @@ export function createCoreServer(opts: CoreServerOptions): {
// able to dispatch `/health` to the gateway sub-app when running
// (LiteLLM-shape JSON — CRITICAL-3 fix).
// === Browser setup wizard (fresh no-auth install onboarding) ===
// Token lifecycle + endpoints. The no-auth `/api/config` mutation gate
// (Codex P1 #3) must register BEFORE mountConfigApi so it intercepts
// PUT/POST while a setup window is open. See setup-api.ts.
if (opts.configManager) {
const setupDataDir = join(process.cwd(), 'data');
const setupListenPort =
opts.listenPort ?? resolveListenPort(process.env['PORT'], loadConfig().server?.port);
// Synchronously seed the gate state to 'pending' (fail-closed for auth
// writes) BEFORE the async lifecycle below resolves, so a request arriving
// in the boot window can't slip an auth bootstrap through (Codex P1 #2).
const setupGateState = newNoAuthConfigGateState();
// Token lifecycle (needs the async setup-lib import). Created only on a
// fresh no-auth install (needs-setup); cleared otherwise so existing
// configured deployments keep their prior open behavior. On failure the
// gate stays 'pending' (fail-closed), never silently open.
void (async () => {
try {
if (authActive) {
clearSetupToken(setupDataDir);
return;
}
const { isLlmConfigured } = await import('../../scripts/setup-lib.mjs');
const workers = opts.configManager?.getConfig().provider?.workers ?? [];
if (!isLlmConfigured(workers)) {
const token = ensureSetupToken(setupDataDir);
setupGateState.mode = 'token-required';
logger.info(`[setup] open the UI and enter this setup token: ${token}`);
logger.info('[setup] llm configured=false → wizard active');
} else {
clearSetupToken(setupDataDir);
setupGateState.mode = 'open';
logger.info('[setup] llm configured=true → wizard off');
}
} catch (e) {
logger.warn(`[setup] token lifecycle failed: ${String(e)}`);
}
})();
// No-auth /api/config auth-write gate (only mounted in no-auth mode).
if (!authActive) {
app.use('/api/config', buildNoAuthConfigGate(setupDataDir, setupGateState));
}
mountSetupApi(app, opts.configManager, {
authActive,
listenPort: setupListenPort,
dataDir: setupDataDir,
});
mountConfigApi(app, opts.configManager);
}