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

This commit is contained in:
oss-sync
2026-07-06 01:04:12 +00:00
parent 747377bef9
commit b1292e34b2
322 changed files with 28001 additions and 4686 deletions
+55 -1
View File
@@ -1,5 +1,5 @@
import express, { Request, Response, NextFunction, RequestHandler } from 'express';
import { existsSync } from 'fs';
import { existsSync, readFileSync } from 'fs';
import { join, resolve, dirname } from 'path';
import { fileURLToPath } from 'url';
import { Repository, BrowserSessionRepo } from '../db/repository.js';
@@ -67,6 +67,12 @@ import type { AuthConfig } from '../config.js';
import { attachConsoleWs } from './console-ws-api.js';
import { mountGateway, type GatewayMountHandle } from './gateway-mount.js';
import { readGatewayConfig } from '../gateway/config.js';
import { createA2aOidcProvider, mountA2aOidc } from './a2a/oidc-provider.js';
import { createA2aClientsAdminRouter } from './a2a/a2a-clients-admin-api.js';
import { createA2aRouter, createSpaceA2aAdminRouter } from './a2a/a2a-api.js';
import { mountA2aRequestHandler } from './a2a/request-handler.js';
import { A2aTaskReconciler } from './a2a/reconciler.js';
import { createUserDelegationsRouter, createAdminDelegationsRouter } from './a2a/delegations-api.js';
import { createAdminGatewayStatusRouter } from './admin-gateway-status-api.js';
import { createServer as createHttpsServer } from 'https';
import { X509Certificate } from 'crypto';
@@ -492,6 +498,53 @@ export function createCoreServer(opts: CoreServerOptions): {
// 横断(全スペース)カレンダー: GET /api/calendar/cross
app.use('/api/calendar', createCrossCalendarApi({ repo, authActive }));
// --- A2A OAuth2 Authorization Server ---
const a2aCfg = (loadConfig() as any).a2a ?? {};
if (a2aCfg.enabled) {
if (!authActive) {
logger.warn('[a2a-oidc] a2a.enabled but auth is not active; consent flow requires login and will reject all requests');
}
try {
const sessionSecretPath = loadConfig()?.secrets?.sessionSecretPath ?? DEFAULT_SESSION_SECRET_PATH;
const cookieKeys = [readFileSync(sessionSecretPath, 'utf-8').trim()];
const secretsDir = dirname(resolve(sessionSecretPath));
const provider = createA2aOidcProvider({
repo,
secretsDir,
issuer: a2aCfg.issuer,
resourceAudience: a2aCfg.resourceAudience,
cookieKeys,
});
mountA2aOidc(app, provider, { repo, resourceAudience: a2aCfg.resourceAudience });
app.use('/api/admin/a2a/clients', express.json(), requireAdmin, createA2aClientsAdminRouter(repo, authActive));
// Agent Card ルータ (base card = public, extended card = self-authenticates via Bearer)
// baseUrl は resourceAudience の origin から導く(例: https://maestro.example.com/a2a → https://maestro.example.com)
// version は '1.0.0' 固定(生成済みバージョンファイルが存在しないため定数を使用)
const a2aBaseUrl = (() => {
try { return new URL(String(a2aCfg.resourceAudience)).origin; } catch { return String(a2aCfg.issuer); }
})();
app.use(createA2aRouter({ provider, repo, baseUrl: a2aBaseUrl, issuer: String(a2aCfg.issuer), version: '1.0.0' }));
// JSON-RPC エンドポイント /a2a(SDK DefaultRequestHandler 経由)
// /a2a は /api 配下でないため requireAuth に掛からない。認証は UserBuilder が担う。
mountA2aRequestHandler(app, { provider, repo, baseUrl: a2aBaseUrl, issuer: String(a2aCfg.issuer), version: '1.0.0' });
// bridge は単一プロセス前提。複数プロセスが同一 DB を共有する構成では
// lease が必要になる(将来課題)。
const a2aReconciler = new A2aTaskReconciler({ repo });
a2aReconciler.start();
registerShutdownHook('a2a-reconciler', async () => { a2aReconciler.stop(); });
logger.info('[a2a] task reconciler started');
// スペース A2A スキル許可リスト管理 API (/api/local は requireAuth 配下)
app.use('/api/local/spaces', createSpaceA2aAdminRouter(repo, authActive));
// A2A 委任一覧・取消 API
// /api/local は L329 で requireAuth 済みのため追加ゲート不要
app.use('/api/local/a2a/delegations', express.json(), createUserDelegationsRouter(repo, authActive));
app.use('/api/admin/a2a/delegations', express.json(), requireAdmin, createAdminDelegationsRouter(repo, authActive));
logger.info('[a2a-oidc] a2a authorization server enabled');
} catch (err) {
logger.warn(`[a2a-oidc] failed to mount a2a authorization server: ${err}`);
}
}
// --- Subtask files API (listing MUST come before wildcard) ---
mountSubtaskFilesApi(app, repo);
@@ -723,6 +776,7 @@ export function createCoreServer(opts: CoreServerOptions): {
dataRoot: userFolderRoot,
worktreeDir: loadConfig().worktreeDir ?? './data/worktrees',
authActive,
getPythonPackagesConfig: () => loadConfig().pythonPackages,
}));
// BackendStatusRegistry singleton — probes every configured worker