feat(server): browser module with DB-backed sessions, takeover lease and browser.* capabilities

/browser/providers, /browser/sessions (open/close/list), navigate/snapshot/screenshot/
click/type/scroll/select/extract/download and control acquire/release. Human input
needs an active lease; expiry or captcha moves the session to waiting with a decision;
release forces a fresh snapshot. Downloads are staged under DATA_DIR/tmp, verified by
infohash and submitted through POST /acquisition-plans. Capability count 21 -> 25.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 20:17:46 +08:00
1 parent c17d4b90bd
commit adffe36846
12 files changed
+2133 -5

No files matched your search

+41
View File
@@ -0,0 +1,41 @@
import { sourcesIdentityModule } from "../sources-identity/index.ts";
import type { ServerContext, ServerModule } from "../types.ts";
import { registerBrowserCapabilities } from "./capabilities.ts";
import { registerBrowserRoutes } from "./routes.ts";
import { type BrowserModuleOptions, BrowserService } from "./service.ts";
/**
* C1-E 浏览器:BrowserProvider(camofox)之上的站点浏览器会话、原站视图与人工接管、Agent 浏览器能力。
* 会话/标签/租约以数据库(0023 四张表)为准;站点限流与 sources-identity 共享;下载产物只进后端暂存核验,
* 提交走 POST /acquisition-plans 同一流程。运维与真实实例核验见 docs/runbook/browser.md。
*/
export function createBrowserModule(opts: BrowserModuleOptions = {}): ServerModule & {
service(ctx: ServerContext): BrowserService;
} {
const services = new WeakMap<ServerContext, BrowserService>();
const options: BrowserModuleOptions = {
runtime: (ctx) => sourcesIdentityModule.runtime(ctx),
...opts,
};
const service = (ctx: ServerContext) => {
let s = services.get(ctx);
if (!s) {
s = new BrowserService(ctx, options);
services.set(ctx, s);
}
return s;
};
return {
name: "browser",
service,
registerRoutes(app, ctx) {
registerBrowserRoutes(app, () => service(ctx));
},
registerTasks() {},
registerCapabilities(registry, ctx) {
registerBrowserCapabilities(registry, () => service(ctx));
},
};
}
export const browserModule = createBrowserModule();