@roll-agent/core 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import{defineCommand as s}from"citty";import{existsSync as e,lstatSync as r,rmSync as o}from"node:fs";import{homedir as t}from"node:os";import{isAbsolute as n,join as i,parse as a,relative as l,resolve as c}from"node:path";import{loadConfig as f}from"../../config/loader.js";import{getAgentPid as u}from"../../registry/process-manager.js";import{log as d}from"../utils/output.js";const p="browser-use-agent",g=i(t(),".roll-agent","browser","sessions"),w=["profiles","sessions"];export default s({meta:{description:"清理 browser.instances 声明的 Chrome profile / Roll session 数据"},args:{instance:{type:"positional",description:"可选 browserInstance;不传则处理所有已声明实例",required:!1},profiles:{type:"boolean",description:"只清理 Chrome profile 目录(browser.instances[*].user-data-dir)",default:!1},sessions:{type:"boolean",description:"只清理 Roll session 快照目录(browser.instances[*].sessions-dir)",default:!1},all:{type:"boolean",description:"清理 profile + sessions;未指定 --profiles/--sessions 时默认就是 all",default:!1},yes:{type:"boolean",alias:"y",description:"确认执行删除;不加时只输出 dry-run 计划",default:!1},force:{type:"boolean",description:"browser-use-agent 仍在运行时也继续删除(不建议)",default:!1},json:{type:"boolean",description:"JSON 格式输出",default:!1}},async run({args:s}){try{const{config:e}=f(),r=$(s.instance,"instance"),o=resolveBrowserDataKinds({all:!0===s.all,profiles:!0===s.profiles,sessions:!0===s.sessions}),t=buildBrowserDataClearPlan(e.browser,{...void 0!==r?{instanceId:r}:{},kinds:o});if(!0===s.yes){const r=u(e.agents.dataDir,p);if(void 0!==r&&!0!==s.force){const e=`${p} 仍在运行 (PID: ${String(r)}),请先运行 \`roll agent stop browser-use-agent\`,或确认风险后加 --force`;return s.json?console.log(JSON.stringify({ok:!1,message:e,targets:t},null,2)):d.error(e),void(process.exitCode=1)}const o=clearBrowserDataTargets(t,{protectedSubtreeRoots:[e.agents.dataDir]});return s.json?console.log(JSON.stringify({ok:o.every(s=>"failed"!==s.status),results:o},null,2)):v(o),void(o.some(s=>"failed"===s.status)&&(process.exitCode=1))}s.json?console.log(JSON.stringify({dryRun:!0,targets:t},null,2)):D(t)}catch(e){const r=e instanceof Error?e.message:String(e);s.json?console.log(JSON.stringify({ok:!1,message:r},null,2)):d.error(r),process.exitCode=1}}});export function resolveBrowserDataKinds(s){return s.all||!s.profiles&&!s.sessions?w:[...s.profiles?["profiles"]:[],...s.sessions?["sessions"]:[]]}export function buildBrowserDataClearPlan(s,e){if(0===Object.entries(s.instances).length)return[];return b(s,e.instanceId).flatMap(([s,r])=>{const o=[];return e.kinds.includes("profiles")&&o.push(y(s,"profiles",r.userDataDir)),e.kinds.includes("sessions")&&o.push(y(s,"sessions",r.sessionsDir??i(g,s))),o})}export function clearBrowserDataTargets(s,t={}){const n=new Set;return s.map(s=>{try{if(assertSafeBrowserDataPath(s.path,t),n.has(s.path))return{...s,status:"skipped",message:"同一路径已在本次命令中处理"};if(n.add(s.path),!e(s.path))return{...s,status:"missing"};const i=r(s.path);if(!i.isDirectory()&&!i.isSymbolicLink())throw new Error(`拒绝删除非目录路径: ${s.path}`);return o(s.path,{recursive:!0,force:!0}),{...s,exists:!1,status:"deleted"}}catch(e){return{...s,status:"failed",message:e instanceof Error?e.message:String(e)}}})}export function assertSafeBrowserDataPath(s,e={}){const r=c(s),o=a(r).root,n=c(t(),".roll-agent"),i=c(n,"browser"),l=[o,c(t()),c(process.cwd()),n,i,c(i,"profiles"),c(i,"sessions")];for(const s of l)if(m(r,s))throw new Error(`拒绝删除危险路径: ${r}`);for(const s of e.protectedSubtreeRoots??[])if(h(r,c(s)))throw new Error(`拒绝删除受保护数据目录下的路径: ${r}`)}function m(s,e){return h(e,s)}function h(s,e){const r=l(e,s);return""===r||!r.startsWith("..")&&!n(r)}function b(s,e){if(void 0===e)return Object.entries(s.instances);const r=s.instances[e];if(void 0===r){const r=Object.keys(s.instances);throw new Error(`browserInstance "${e}" 未声明`+(r.length>0?`;可用实例: ${r.join(", ")}`:""))}return[[e,r]]}function y(s,r,o){const t=c(o);return{instanceId:s,kind:r,path:t,exists:e(t)}}function $(s,e){if(void 0===s)return;if("string"!=typeof s)throw new Error(`${e} 必须是字符串`);const r=s.trim();return r.length>0?r:void 0}function D(s){if(0!==s.length){d.info("Browser data clear plan (dry-run, 未删除任何文件):");for(const e of s)d.info(S(e));d.info("确认无误后追加 --yes 执行删除;运行中的 browser-use-agent 建议先 stop。")}else d.warn("未配置 browser.instances,没有可清理的 browser 数据目录。")}function v(s){if(0===s.length)return void d.warn("未配置 browser.instances,没有可清理的 browser 数据目录。");for(const e of s){const s=`${S(e)} -> ${e.status}${void 0!==e.message?` (${e.message})`:""}`;"failed"===e.status?d.error(s):d.info(s)}0===s.filter(s=>"failed"===s.status).length&&d.success("Browser 数据清理完成。")}function S(s){return`${s.instanceId} ${s.kind}: ${s.path} [${s.exists?"exists":"missing"}]`}
1
+ import{defineCommand as s}from"citty";import{existsSync as e,lstatSync as r,rmSync as o}from"node:fs";import{homedir as t}from"node:os";import{isAbsolute as n,join as i,parse as a,relative as l,resolve as c}from"node:path";import{loadConfig as f}from"../../config/loader.js";import{getAgentPid as u}from"../../registry/process-manager.js";import{log as d}from"../utils/output.js";const p="browser-use-agent",g=i(t(),".roll-agent","browser","sessions"),w=["profiles","sessions"];export default s({meta:{description:"清理 browser.instances 声明的 Chrome profile / Roll session 数据"},args:{instance:{type:"positional",description:"可选 browserInstance;不传则处理所有已声明实例",required:!1},profiles:{type:"boolean",description:"只清理 Chrome profile 目录(browser.instances[*].user-data-dir)",default:!1},sessions:{type:"boolean",description:"只清理 Roll session 快照目录(browser.instances[*].sessions-dir)",default:!1},all:{type:"boolean",description:"清理 profile + sessions;未指定 --profiles/--sessions 时默认就是 all",default:!1},yes:{type:"boolean",alias:"y",description:"确认执行删除;不加时只输出 dry-run 计划",default:!1},force:{type:"boolean",description:"browser-use-agent 仍在运行时也继续删除(不建议)",default:!1},json:{type:"boolean",description:"JSON 格式输出",default:!1}},async run({args:s}){try{const{config:e}=f(),r=$(s.instance,"instance"),o=resolveBrowserDataKinds({all:!0===s.all,profiles:!0===s.profiles,sessions:!0===s.sessions}),t=buildBrowserDataClearPlan(e.browser,{...void 0!==r?{instanceId:r}:{},kinds:o});if(!0===s.yes){const o=u(e.agents.dataDir,p);if(void 0!==o&&!0!==s.force){const e=void 0!==r?`roll browser stop ${r}`:"roll browser stop --all",n=`${p} 仍在运行 (PID: ${String(o)}),请先运行 \`${e}\`,或确认风险后加 --force`;return s.json?console.log(JSON.stringify({ok:!1,message:n,targets:t},null,2)):d.error(n),void(process.exitCode=1)}const n=clearBrowserDataTargets(t,{protectedSubtreeRoots:[e.agents.dataDir]});return s.json?console.log(JSON.stringify({ok:n.every(s=>"failed"!==s.status),results:n},null,2)):D(n),void(n.some(s=>"failed"===s.status)&&(process.exitCode=1))}s.json?console.log(JSON.stringify({dryRun:!0,targets:t},null,2)):v(t)}catch(e){const r=e instanceof Error?e.message:String(e);s.json?console.log(JSON.stringify({ok:!1,message:r},null,2)):d.error(r),process.exitCode=1}}});export function resolveBrowserDataKinds(s){return s.all||!s.profiles&&!s.sessions?w:[...s.profiles?["profiles"]:[],...s.sessions?["sessions"]:[]]}export function buildBrowserDataClearPlan(s,e){if(0===Object.entries(s.instances).length)return[];return h(s,e.instanceId).flatMap(([s,r])=>{const o=[];return e.kinds.includes("profiles")&&o.push(y(s,"profiles",r.userDataDir)),e.kinds.includes("sessions")&&o.push(y(s,"sessions",r.sessionsDir??i(g,s))),o})}export function clearBrowserDataTargets(s,t={}){const n=new Set;return s.map(s=>{try{if(assertSafeBrowserDataPath(s.path,t),n.has(s.path))return{...s,status:"skipped",message:"同一路径已在本次命令中处理"};if(n.add(s.path),!e(s.path))return{...s,status:"missing"};const i=r(s.path);if(!i.isDirectory()&&!i.isSymbolicLink())throw new Error(`拒绝删除非目录路径: ${s.path}`);return o(s.path,{recursive:!0,force:!0}),{...s,exists:!1,status:"deleted"}}catch(e){return{...s,status:"failed",message:e instanceof Error?e.message:String(e)}}})}export function assertSafeBrowserDataPath(s,e={}){const r=c(s),o=a(r).root,n=c(t(),".roll-agent"),i=c(n,"browser"),l=[o,c(t()),c(process.cwd()),n,i,c(i,"profiles"),c(i,"sessions")];for(const s of l)if(m(r,s))throw new Error(`拒绝删除危险路径: ${r}`);for(const s of e.protectedSubtreeRoots??[])if(b(r,c(s)))throw new Error(`拒绝删除受保护数据目录下的路径: ${r}`)}function m(s,e){return b(e,s)}function b(s,e){const r=l(e,s);return""===r||!r.startsWith("..")&&!n(r)}function h(s,e){if(void 0===e)return Object.entries(s.instances);const r=s.instances[e];if(void 0===r){const r=Object.keys(s.instances);throw new Error(`browserInstance "${e}" 未声明`+(r.length>0?`;可用实例: ${r.join(", ")}`:""))}return[[e,r]]}function y(s,r,o){const t=c(o);return{instanceId:s,kind:r,path:t,exists:e(t)}}function $(s,e){if(void 0===s)return;if("string"!=typeof s)throw new Error(`${e} 必须是字符串`);const r=s.trim();return r.length>0?r:void 0}function v(s){if(0!==s.length){d.info("Browser data clear plan (dry-run, 未删除任何文件):");for(const e of s)d.info(S(e));d.info("确认无误后追加 --yes 执行删除;运行中的 browser-use-agent 建议先 stop。")}else d.warn("未配置 browser.instances,没有可清理的 browser 数据目录。")}function D(s){if(0===s.length)return void d.warn("未配置 browser.instances,没有可清理的 browser 数据目录。");for(const e of s){const s=`${S(e)} -> ${e.status}${void 0!==e.message?` (${e.message})`:""}`;"failed"===e.status?d.error(s):d.info(s)}0===s.filter(s=>"failed"===s.status).length&&d.success("Browser 数据清理完成。")}function S(s){return`${s.instanceId} ${s.kind}: ${s.path} [${s.exists?"exists":"missing"}]`}
@@ -0,0 +1,81 @@
1
+ import { z } from "zod";
2
+ import type { BrowserConfig } from "../../config/schema.ts";
3
+ export declare const BROWSER_STOP_COMMAND_DESCRIPTION = "\u5173\u95ED browser-use-agent \u5F53\u524D\u6258\u7BA1\u7684\u6D4F\u89C8\u5668\u5B9E\u4F8B\uFF1B\u4E0D\u4F1A\u505C\u6B62 browser-use-agent \u670D\u52A1\u8FDB\u7A0B\u3002";
4
+ export declare const BROWSER_STOP_INSTANCE_DESCRIPTION = "\u4E00\u4E2A\u6216\u591A\u4E2A browserInstance\uFF1B\u4E0D\u4F20\u65F6\u5FC5\u987B\u663E\u5F0F\u4F7F\u7528 --all\u3002";
5
+ export declare const BROWSER_STOP_ALL_DESCRIPTION = "\u5173\u95ED\u6240\u6709\u5DF2\u542F\u52A8\u7684\u6D4F\u89C8\u5668\u5B9E\u4F8B\uFF0C\u4F46\u4FDD\u7559 browser-use-agent \u8FDB\u7A0B\u7EE7\u7EED\u8FD0\u884C\uFF1B\u4E0D\u540C\u4E8E roll agent stop browser-use-agent\u3002";
6
+ export declare const BROWSER_USE_AGENT_NOT_RUNNING_MESSAGE = "browser-use-agent \u672A\u8FD0\u884C\uFF1B\u6CA1\u6709\u7531\u5F53\u524D agent \u6258\u7BA1\u7684\u6D4F\u89C8\u5668\u5B9E\u4F8B\u53EF\u5173\u95ED\u3002\u4E0D\u4F1A\u626B\u63CF\u6216\u67E5\u6740\u7CFB\u7EDF Chrome \u8FDB\u7A0B\u3002";
7
+ declare const BrowserStopToolResultSchema: z.ZodObject<{
8
+ ok: z.ZodBoolean;
9
+ stopped: z.ZodNumber;
10
+ results: z.ZodArray<z.ZodObject<{
11
+ browserInstance: z.ZodString;
12
+ status: z.ZodEnum<["stopped", "not_running", "not_found", "failed"]>;
13
+ mode: z.ZodOptional<z.ZodEnum<["managed-cdp", "remote-cdp", "existing-session"]>>;
14
+ message: z.ZodOptional<z.ZodString>;
15
+ }, "strip", z.ZodTypeAny, {
16
+ status: "stopped" | "failed" | "not_running" | "not_found";
17
+ browserInstance: string;
18
+ message?: string | undefined;
19
+ mode?: "managed-cdp" | "remote-cdp" | "existing-session" | undefined;
20
+ }, {
21
+ status: "stopped" | "failed" | "not_running" | "not_found";
22
+ browserInstance: string;
23
+ message?: string | undefined;
24
+ mode?: "managed-cdp" | "remote-cdp" | "existing-session" | undefined;
25
+ }>, "many">;
26
+ }, "strip", z.ZodTypeAny, {
27
+ stopped: number;
28
+ ok: boolean;
29
+ results: {
30
+ status: "stopped" | "failed" | "not_running" | "not_found";
31
+ browserInstance: string;
32
+ message?: string | undefined;
33
+ mode?: "managed-cdp" | "remote-cdp" | "existing-session" | undefined;
34
+ }[];
35
+ }, {
36
+ stopped: number;
37
+ ok: boolean;
38
+ results: {
39
+ status: "stopped" | "failed" | "not_running" | "not_found";
40
+ browserInstance: string;
41
+ message?: string | undefined;
42
+ mode?: "managed-cdp" | "remote-cdp" | "existing-session" | undefined;
43
+ }[];
44
+ }>;
45
+ type BrowserStopToolResult = z.infer<typeof BrowserStopToolResultSchema>;
46
+ export interface BrowserStopRequest {
47
+ readonly all: boolean;
48
+ readonly instances: readonly string[];
49
+ readonly toolInput: Readonly<Record<string, unknown>>;
50
+ }
51
+ export interface BrowserStopJsonOutput extends BrowserStopToolResult {
52
+ readonly agentRunning: boolean;
53
+ readonly message?: string;
54
+ }
55
+ declare const _default: import("citty").CommandDef<{
56
+ instance: {
57
+ type: "positional";
58
+ description: string;
59
+ required: false;
60
+ };
61
+ all: {
62
+ type: "boolean";
63
+ description: string;
64
+ default: false;
65
+ };
66
+ json: {
67
+ type: "boolean";
68
+ description: string;
69
+ default: false;
70
+ };
71
+ }>;
72
+ export default _default;
73
+ export declare function resolveBrowserStopRequest(input: {
74
+ readonly rawArgs: readonly string[];
75
+ readonly all: boolean;
76
+ }): BrowserStopRequest;
77
+ export declare function parseBrowserStopInstances(rawArgs: readonly string[]): readonly string[];
78
+ export declare function parseBrowserStopToolResult(result: unknown): BrowserStopToolResult;
79
+ export declare function validateDeclaredBrowserStopInstances(browserConfig: BrowserConfig, request: BrowserStopRequest): void;
80
+ export declare function createBrowserStopAgentNotRunningOutput(): BrowserStopJsonOutput;
81
+ export declare function createBrowserStopTextLines(output: BrowserStopJsonOutput, request: BrowserStopRequest): readonly string[];
@@ -0,0 +1 @@
1
+ import{defineCommand as e}from"citty";import{z as t}from"zod";import{getAgentEnv as n}from"../../config/helpers.js";import{loadConfig as r}from"../../config/loader.js";import{McpClientManager as s}from"../../mcp/client-manager.js";import{getAgentPid as o}from"../../registry/process-manager.js";import{resolveTransportWithDevSpawnSpec as a}from"../../registry/dev-spawn.js";import{AgentStore as i}from"../../registry/store.js";import{formatMissingToolMessage as c,normalizeListedTools as l}from"../utils/agent-tools.js";import{extractTextContent as u,formatToolResultForJsonOutput as p,isToolErrorResult as g}from"../utils/tool-results.js";import{log as w}from"../utils/output.js";const f="browser-use-agent",m="browser_stop",d=new Set(["config"]);export const BROWSER_STOP_COMMAND_DESCRIPTION="关闭 browser-use-agent 当前托管的浏览器实例;不会停止 browser-use-agent 服务进程。";export const BROWSER_STOP_INSTANCE_DESCRIPTION="一个或多个 browserInstance;不传时必须显式使用 --all。";export const BROWSER_STOP_ALL_DESCRIPTION="关闭所有已启动的浏览器实例,但保留 browser-use-agent 进程继续运行;不同于 roll agent stop browser-use-agent。";export const BROWSER_USE_AGENT_NOT_RUNNING_MESSAGE="browser-use-agent 未运行;没有由当前 agent 托管的浏览器实例可关闭。不会扫描或查杀系统 Chrome 进程。";const S=t.enum(["stopped","not_running","not_found","failed"]),b=t.object({browserInstance:t.string(),status:S,mode:t.enum(["managed-cdp","remote-cdp","existing-session"]).optional(),message:t.string().optional()}),_=t.object({ok:t.boolean(),stopped:t.number().int().nonnegative(),results:t.array(b)});export default e({meta:{description:BROWSER_STOP_COMMAND_DESCRIPTION},args:{instance:{type:"positional",description:BROWSER_STOP_INSTANCE_DESCRIPTION,required:!1},all:{type:"boolean",description:BROWSER_STOP_ALL_DESCRIPTION,default:!1},json:{type:"boolean",description:"JSON 格式输出",default:!1}},async run({args:e,rawArgs:t}){const o=!0===e.json,p=new s;try{const s=resolveBrowserStopRequest({rawArgs:t,all:!0===e.all}),{config:w}=r();validateDeclaredBrowserStopInstances(w.browser,s);const d=new i(w.agents.dataDir).findByName(f);if(void 0===d)throw new Error(`Agent "${f}" 未注册。使用 \`roll agent list\` 查看已注册 Agent。`);if(I(d,w.agents.dataDir)){return void E(createBrowserStopAgentNotRunningOutput(),s,o)}if("on-demand"===d.runtime.ownership)throw new Error(`${f} 不是常驻服务,无法执行实例级 browser runtime stop。`);const S=n(w,d.skill.name),b=a(d);let _;try{_=await p.connect(d.skill.name,b,d.installPath,{timeoutMs:5e3,...S?{env:S}:{}})}catch(e){if("external-managed"===d.runtime.ownership){return void E(createBrowserStopAgentNotRunningOutput(),s,o)}throw new Error(`${f} 正在运行但无法连接。`,{cause:e})}const R=l((await _.listTools()).tools);if(void 0===R.find(e=>e.name===m))throw new Error(c(d.skill.name,m,R));const N=await _.callTool({name:m,arguments:s.toolInput});if(g(N))throw new Error(u(N.content).join("\n")||"browser_stop 返回 isError=true");const O=parseBrowserStopToolResult(N);E({...O,agentRunning:!0},s,o),h(O.results)&&(process.exitCode=1)}catch(e){const t=e instanceof Error?e.message:String(e);o?console.log(JSON.stringify({ok:!1,message:t},null,2)):w.error(t),process.exitCode=1}finally{await p.disconnectAll()}}});export function resolveBrowserStopRequest(e){const t=parseBrowserStopInstances(e.rawArgs);if(e.all&&t.length>0)throw new Error("--all 不能和 browserInstance 位置参数同时使用。");if(!e.all&&0===t.length)throw new Error("请提供一个或多个 browserInstance,或显式使用 --all。");return e.all?{all:!0,instances:[],toolInput:{all:!0}}:{all:!1,instances:t,toolInput:1===t.length?{browserInstance:t[0]}:{browserInstances:t}}}export function parseBrowserStopInstances(e){const t=[];let n=0;for(;n<e.length;){const r=e[n];if(void 0===r){n+=1;continue}if("--"===r){t.push(...e.slice(n+1).map(e=>e.trim()).filter(Boolean));break}if(r.startsWith("--")){const e=r.slice(2).split("=",1)[0]??"";n+=d.has(e)&&!r.includes("=")?2:1;continue}if(r.startsWith("-")){n+=1;continue}const s=r.trim();s.length>0&&t.push(s),n+=1}return[...new Set(t)]}export function parseBrowserStopToolResult(e){return _.parse(p(e))}export function validateDeclaredBrowserStopInstances(e,t){if(t.all||0===t.instances.length)return;const n=Object.keys(e.instances);if(0===n.length)return;const r=t.instances.filter(t=>void 0===e.instances[t]);if(0!==r.length)throw new Error(`browserInstance ${r.map(e=>`"${e}"`).join(", ")} 未声明;可用实例: ${n.join(", ")}`)}export function createBrowserStopAgentNotRunningOutput(){return{ok:!0,agentRunning:!1,stopped:0,results:[],message:BROWSER_USE_AGENT_NOT_RUNNING_MESSAGE}}export function createBrowserStopTextLines(e,t){if(!e.agentRunning)return[e.message??BROWSER_USE_AGENT_NOT_RUNNING_MESSAGE];const n=[];t.all?n.push(e.stopped>0?"已关闭所有已启动 browser instances;browser-use-agent 仍在运行。":"没有已启动 browser instances 需要关闭;browser-use-agent 仍在运行。"):1===t.instances.length&&"stopped"===e.results[0]?.status?n.push(`已关闭 browser instance "${t.instances[0]}";browser-use-agent 仍在运行。`):n.push(`已处理 ${String(e.results.length)} 个 browser instances;已关闭 ${String(e.stopped)} 个;browser-use-agent 仍在运行。`);for(const t of e.results)"stopped"!==t.status&&n.push(R(t));return n}function E(e,t,n){if(n)return void console.log(JSON.stringify(e,null,2));const r=createBrowserStopTextLines(e,t);for(const t of r)e.ok?w.success(t):w.error(t)}function R(e){const t=void 0!==e.message?`:${e.message}`:"";switch(e.status){case"not_running":return`browser instance "${e.browserInstance}" 当前未运行。`;case"not_found":return`browser instance "${e.browserInstance}" 不存在${t}`;case"failed":return`browser instance "${e.browserInstance}" 关闭失败${t}`;case"stopped":return`已关闭 browser instance "${e.browserInstance}"。`}}function h(e){return e.some(e=>"not_found"===e.status||"failed"===e.status)}function I(e,t){return"core-managed"===e.runtime.ownership&&void 0===o(t,e.skill.name)}
@@ -1 +1 @@
1
- var t=this&&this.__rewriteRelativeImportExtension||function(t,e){return"string"==typeof t&&/^\.\.?\//.test(t)?t.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i,function(t,r,s,n,o){return r?e?".jsx":".js":!s||n&&o?s+n+"."+o.toLowerCase()+"js":t}):t};import{defineCommand as e}from"citty";const r=import.meta.url.endsWith(".ts")?"ts":"js";function s(e){const s=new URL(`./${e}.${r}`,import.meta.url).href;return import(t(s)).then(t=>t.default)}export default e({meta:{description:"管理浏览器运行时数据"},subCommands:{"clear-data":()=>s("browser-clear-data")}});
1
+ var t=this&&this.__rewriteRelativeImportExtension||function(t,e){return"string"==typeof t&&/^\.\.?\//.test(t)?t.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i,function(t,r,s,o,n){return r?e?".jsx":".js":!s||o&&n?s+o+"."+n.toLowerCase()+"js":t}):t};import{defineCommand as e}from"citty";const r=import.meta.url.endsWith(".ts")?"ts":"js";function s(e){const s=new URL(`./${e}.${r}`,import.meta.url).href;return import(t(s)).then(t=>t.default)}export default e({meta:{description:"管理浏览器运行时数据"},subCommands:{"clear-data":()=>s("browser-clear-data"),stop:()=>s("browser-stop")}});
@@ -1,4 +1,4 @@
1
1
  import type { BrowserConfig } from "./schema.ts";
2
- export declare const LEGACY_BROWSER_IDENTITY_ENV_KEYS: readonly ["BROWSER_CDP_PORT", "BROWSER_USER_DATA_DIR", "BROWSER_CDP_URL", "BROWSER_SESSIONS_DIR"];
2
+ export declare const LEGACY_BROWSER_IDENTITY_ENV_KEYS: readonly ["BROWSER_CDP_PORT", "BROWSER_USER_DATA_DIR", "BROWSER_CDP_URL", "BROWSER_SESSIONS_DIR", "BROWSER_PROFILE_COLOR"];
3
3
  export type LegacyBrowserIdentityEnvKey = (typeof LEGACY_BROWSER_IDENTITY_ENV_KEYS)[number];
4
4
  export declare function collectBrowserConfigWarnings(browserConfig: BrowserConfig, agentEnv: Readonly<Record<string, string>> | undefined, inheritedEnv?: NodeJS.ProcessEnv): readonly string[];
@@ -1 +1 @@
1
- export const LEGACY_BROWSER_IDENTITY_ENV_KEYS=["BROWSER_CDP_PORT","BROWSER_USER_DATA_DIR","BROWSER_CDP_URL","BROWSER_SESSIONS_DIR"];export function collectBrowserConfigWarnings(n,e,t=process.env){const s=Object.keys(n.instances);if(0===s.length)return[];const r=[];s.length>1&&void 0===n.defaultInstance&&r.push(`browser.instances 声明了 ${String(s.length)} 个实例,但未配置 browser.default-instance;未显式传 browserInstance 的 tool 调用会返回 needs_input`);const o=LEGACY_BROWSER_IDENTITY_ENV_KEYS.filter(n=>{const s=e?.[n],r=t[n];return void 0!==s&&s.length>0||void 0!==r&&r.length>0});return o.length>0&&r.push(`browser.instances 已配置,agents.env 或 shell 中的 ${o.join(", ")} 会被忽略;实例身份以 browser.instances 为准`),r}
1
+ export const LEGACY_BROWSER_IDENTITY_ENV_KEYS=["BROWSER_CDP_PORT","BROWSER_USER_DATA_DIR","BROWSER_CDP_URL","BROWSER_SESSIONS_DIR","BROWSER_PROFILE_COLOR"];export function collectBrowserConfigWarnings(n,e,t=process.env){const s=Object.keys(n.instances);if(0===s.length)return[];const r=[];s.length>1&&void 0===n.defaultInstance&&r.push(`browser.instances 声明了 ${String(s.length)} 个实例,但未配置 browser.default-instance;未显式传 browserInstance 的 tool 调用会返回 needs_input`);const o=LEGACY_BROWSER_IDENTITY_ENV_KEYS.filter(n=>{const s=e?.[n],r=t[n];return void 0!==s&&s.length>0||void 0!==r&&r.length>0});return o.length>0&&r.push(`browser.instances 已配置,agents.env 或 shell 中的 ${o.join(", ")} 会被忽略;实例身份以 browser.instances 为准`),r}
@@ -1 +1 @@
1
- const e={kind:"leaf"},r={kind:"object",fields:{apiKey:e,baseUrl:e}},o={kind:"object",fields:{platform:e,mode:e,headless:e,cdpUrl:e,cdpHost:e,cdpPort:e,channel:e,executablePath:e,userDataDir:e,sessionsDir:e,args:e,profileName:e,windowBounds:{kind:"object",fields:{x:e,y:e,width:e,height:e}},trackingAgentId:e}};export const CONFIG_KEY_CODEC={kind:"object",fields:{llm:{kind:"object",fields:{defaultProvider:e,defaultModel:e,providers:{kind:"record",value:r}}},ask:{kind:"object",fields:{llmModel:e,confirmThreshold:e}},agents:{kind:"object",fields:{dataDir:e,env:{kind:"record",value:{kind:"record",value:e}}}},browser:{kind:"object",fields:{defaultInstance:e,instances:{kind:"record",value:o}}}}};export function kebabToCamel(e){return e.replace(/-([a-z])/g,(e,r)=>r.toUpperCase())}export function camelToKebab(e){return e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function t(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}export function decodeFromYaml(r,o=CONFIG_KEY_CODEC){if(Array.isArray(r))return r.map(e=>decodeFromYaml(e,o));if(!t(r))return r;if("object"===o.kind){const t={};for(const[n,d]of Object.entries(r)){const r=kebabToCamel(n),a=o.fields[r]??e;t[r]=decodeFromYaml(d,a)}return t}if("record"===o.kind){const e={};for(const[t,n]of Object.entries(r))e[t]=decodeFromYaml(n,o.value);return e}return r}function n(r,o){const t=[];let n=CONFIG_KEY_CODEC;for(const d of r)if("object"===n.kind){const r=kebabToCamel(d),a=n.fields[r];a?(t.push("camel"===o?r:camelToKebab(r)),n=a):(t.push(d),n=e)}else"record"===n.kind?(t.push(d),n=n.value):t.push(d);return t}export function encodePathToYaml(e){return n(e,"kebab")}export function normalizeUserPath(e){return n(e,"camel")}
1
+ const e={kind:"leaf"},o={kind:"object",fields:{apiKey:e,baseUrl:e}},r={kind:"object",fields:{platform:e,mode:e,headless:e,cdpUrl:e,cdpHost:e,cdpPort:e,channel:e,executablePath:e,userDataDir:e,sessionsDir:e,args:e,profileName:e,profileColor:e,windowBounds:{kind:"object",fields:{x:e,y:e,width:e,height:e}},trackingAgentId:e}};export const CONFIG_KEY_CODEC={kind:"object",fields:{llm:{kind:"object",fields:{defaultProvider:e,defaultModel:e,providers:{kind:"record",value:o}}},ask:{kind:"object",fields:{llmModel:e,confirmThreshold:e}},agents:{kind:"object",fields:{dataDir:e,env:{kind:"record",value:{kind:"record",value:e}}}},browser:{kind:"object",fields:{defaultInstance:e,instances:{kind:"record",value:r}}}}};export function kebabToCamel(e){return e.replace(/-([a-z])/g,(e,o)=>o.toUpperCase())}export function camelToKebab(e){return e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function t(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}export function decodeFromYaml(o,r=CONFIG_KEY_CODEC){if(Array.isArray(o))return o.map(e=>decodeFromYaml(e,r));if(!t(o))return o;if("object"===r.kind){const t={};for(const[n,d]of Object.entries(o)){const o=kebabToCamel(n),a=r.fields[o]??e;t[o]=decodeFromYaml(d,a)}return t}if("record"===r.kind){const e={};for(const[t,n]of Object.entries(o))e[t]=decodeFromYaml(n,r.value);return e}return o}function n(o,r){const t=[];let n=CONFIG_KEY_CODEC;for(const d of o)if("object"===n.kind){const o=kebabToCamel(d),a=n.fields[o];a?(t.push("camel"===r?o:camelToKebab(o)),n=a):(t.push(d),n=e)}else"record"===n.kind?(t.push(d),n=n.value):t.push(d);return t}export function encodePathToYaml(e){return n(e,"kebab")}export function normalizeUserPath(e){return n(e,"camel")}
@@ -1 +1 @@
1
- import{createHash as e}from"node:crypto";import{z as n}from"zod";export const DIAGNOSTIC_TOOL_CANDIDATES=["diagnostic_status","browser_status"];const t=new Set(DIAGNOSTIC_TOOL_CANDIDATES),i=/^[0-9a-f]{8}$/;export const EffectiveEnvSourceSchema=n.object({present:n.boolean(),fingerprint:n.string().regex(i).optional()});export const BrowserSecurityDiagnosticSchema=n.object({domainAllowlist:n.array(n.string()),maxPageContentBytes:n.number(),maxSnapshotNodes:n.number(),actionPolicy:n.enum(["log","deny","confirm"]),foregroundPolicy:n.enum(["when-minimized","always","never"]).default("when-minimized")});export const BrowserUseToolPolicyDiagnosticSchema=n.object({approvalTtlMs:n.number(),tools:n.record(n.object({policy:n.enum(["log","deny","confirm"])}))});export const BrowserUsePolicyWarningDiagnosticSchema=n.object({code:n.string(),message:n.string()});export const BrowserInstanceStatusDiagnosticSchema=n.object({id:n.string(),platform:n.enum(["zhipin","yupao"]).optional(),mode:n.enum(["managed-cdp","remote-cdp","existing-session"]),cdp:n.object({endpoint:n.string(),port:n.number().int().min(1).max(65535).optional(),versionReachable:n.boolean(),listReachable:n.boolean()}),profile:n.object({userDataDir:n.string().optional(),exists:n.boolean(),writable:n.boolean()}),tracking:n.object({source:n.enum(["instance","default-env","missing"]),agentIdFingerprint:n.string().regex(i).optional()})});export const AgentRuntimeEnvDiagnosticPayloadSchema=n.object({effectiveEnvSources:n.record(EffectiveEnvSourceSchema),security:BrowserSecurityDiagnosticSchema.optional(),toolPolicy:BrowserUseToolPolicyDiagnosticSchema.optional(),policyWarnings:n.array(BrowserUsePolicyWarningDiagnosticSchema).optional(),defaultInstanceId:n.string().optional(),primaryInstanceId:n.string().optional(),instances:n.array(BrowserInstanceStatusDiagnosticSchema).optional()});export function shouldSkipRuntimeReadinessForTool(e){return t.has(e)}export function inspectAgentRuntimeEnvRequirements(e,n,t){const i=e.items.map(e=>{const i=n?.[e.name],r=void 0!==i;if("unverified"===t.status)return{...e,configuredInAgentsEnv:r,runtime:{verified:!1,reason:t.reason,message:t.message}};const o=t.payload.effectiveEnvSources[e.name];return o?.present?{...e,configuredInAgentsEnv:r,runtime:{verified:!0,present:!0,...void 0!==o.fingerprint?{fingerprint:o.fingerprint}:{},matchesAgentsEnv:void 0!==i&&void 0!==o.fingerprint&&s(i)===o.fingerprint}}:{...e,configuredInAgentsEnv:r,runtime:{verified:!0,present:!1}}});return{items:i,inspection:t,missingRequired:i.filter(e=>e.required&&r(e)),ephemeralItems:i.filter(o)}}export function summarizeAgentRuntimeEnvReport(e){if(e.missingRequired.length>0){const n=c(e.missingRequired);return"verified"===e.inspection.status?{status:"fail",message:`运行态缺失: ${n}`}:{status:"fail",message:`${a(e)};${e.inspection.message}`}}if(e.ephemeralItems.length>0)return{status:"warn",message:`运行态漂移: ${c(e.ephemeralItems)}`};if("verified"===e.inspection.status)return{status:"ok",message:`声明的必填项已在运行态生效(${e.inspection.toolName})`};const n=e.items.filter(e=>e.required&&"process.env"===e.source);return n.length>0?{status:"warn",message:`依赖当前 shell 环境: ${c(n)};${e.inspection.message}`}:"diagnostic-tool-unavailable"===e.inspection.reason?{status:"ok",message:`声明的必填项已满足(${e.inspection.message})`}:{status:"warn",message:`声明的必填项已满足;${e.inspection.message}`}}export function formatAgentEnvDeclarationSource(e){switch(e.source){case"agents.env":return"已配置于 agents.env";case"process.env":return"仅当前 shell 环境";case"default":return`默认值 (${e.default})`;case"missing":return"缺失"}}export function formatAgentRuntimeVerification(e){return"verified"===e.inspection.status?`已验证(${e.inspection.toolName})`:`未校验(${e.inspection.message})`}export function formatAgentEnvRuntimeStatus(e){if(e.runtime.verified)return e.runtime.present?e.runtime.matchesAgentsEnv?"✓ from yaml (stable)":e.configuredInAgentsEnv?"⚠ differs from yaml (ephemeral)":"⚠ from shell (ephemeral)":"default"===e.source?"未设置(使用默认值)":"process.env"===e.source?"✗ 当前运行 agent 未看到该变量":"✗ missing"}function s(n){return e("sha256").update(n).digest("hex").slice(0,8)}function r(e){return e.runtime.verified?!e.runtime.present&&"default"!==e.source:"missing"===e.source}function o(e){return e.runtime.verified&&e.runtime.present&&!e.runtime.matchesAgentsEnv}function a(e){return`缺少必填项: ${c(e.missingRequired)}`}function c(e){return e.map(e=>e.name).join(", ")}
1
+ import{createHash as e}from"node:crypto";import{z as n}from"zod";export const DIAGNOSTIC_TOOL_CANDIDATES=["diagnostic_status","browser_status"];const t=[...DIAGNOSTIC_TOOL_CANDIDATES,"browser_stop"],i=new Set(t),s=/^[0-9a-f]{8}$/;export const EffectiveEnvSourceSchema=n.object({present:n.boolean(),fingerprint:n.string().regex(s).optional()});export const BrowserSecurityDiagnosticSchema=n.object({domainAllowlist:n.array(n.string()),maxPageContentBytes:n.number(),maxSnapshotNodes:n.number(),actionPolicy:n.enum(["log","deny","confirm"]),foregroundPolicy:n.enum(["when-minimized","always","never"]).default("when-minimized")});export const BrowserUseToolPolicyDiagnosticSchema=n.object({approvalTtlMs:n.number(),tools:n.record(n.object({policy:n.enum(["log","deny","confirm"])}))});export const BrowserUsePolicyWarningDiagnosticSchema=n.object({code:n.string(),message:n.string()});export const BrowserInstanceStatusDiagnosticSchema=n.object({id:n.string(),platform:n.enum(["zhipin","yupao"]).optional(),mode:n.enum(["managed-cdp","remote-cdp","existing-session"]),cdp:n.object({endpoint:n.string(),port:n.number().int().min(1).max(65535).optional(),versionReachable:n.boolean(),listReachable:n.boolean()}),profile:n.object({userDataDir:n.string().optional(),exists:n.boolean(),writable:n.boolean()}),tracking:n.object({source:n.enum(["instance","default-env","missing"]),agentIdFingerprint:n.string().regex(s).optional()})});export const AgentRuntimeEnvDiagnosticPayloadSchema=n.object({effectiveEnvSources:n.record(EffectiveEnvSourceSchema),security:BrowserSecurityDiagnosticSchema.optional(),toolPolicy:BrowserUseToolPolicyDiagnosticSchema.optional(),policyWarnings:n.array(BrowserUsePolicyWarningDiagnosticSchema).optional(),defaultInstanceId:n.string().optional(),primaryInstanceId:n.string().optional(),instances:n.array(BrowserInstanceStatusDiagnosticSchema).optional()});export function shouldSkipRuntimeReadinessForTool(e){return i.has(e)}export function inspectAgentRuntimeEnvRequirements(e,n,t){const i=e.items.map(e=>{const i=n?.[e.name],s=void 0!==i;if("unverified"===t.status)return{...e,configuredInAgentsEnv:s,runtime:{verified:!1,reason:t.reason,message:t.message}};const o=t.payload.effectiveEnvSources[e.name];return o?.present?{...e,configuredInAgentsEnv:s,runtime:{verified:!0,present:!0,...void 0!==o.fingerprint?{fingerprint:o.fingerprint}:{},matchesAgentsEnv:void 0!==i&&void 0!==o.fingerprint&&r(i)===o.fingerprint}}:{...e,configuredInAgentsEnv:s,runtime:{verified:!0,present:!1}}});return{items:i,inspection:t,missingRequired:i.filter(e=>e.required&&o(e)),ephemeralItems:i.filter(a)}}export function summarizeAgentRuntimeEnvReport(e){if(e.missingRequired.length>0){const n=u(e.missingRequired);return"verified"===e.inspection.status?{status:"fail",message:`运行态缺失: ${n}`}:{status:"fail",message:`${c(e)};${e.inspection.message}`}}if(e.ephemeralItems.length>0)return{status:"warn",message:`运行态漂移: ${u(e.ephemeralItems)}`};if("verified"===e.inspection.status)return{status:"ok",message:`声明的必填项已在运行态生效(${e.inspection.toolName})`};const n=e.items.filter(e=>e.required&&"process.env"===e.source);return n.length>0?{status:"warn",message:`依赖当前 shell 环境: ${u(n)};${e.inspection.message}`}:"diagnostic-tool-unavailable"===e.inspection.reason?{status:"ok",message:`声明的必填项已满足(${e.inspection.message})`}:{status:"warn",message:`声明的必填项已满足;${e.inspection.message}`}}export function formatAgentEnvDeclarationSource(e){switch(e.source){case"agents.env":return"已配置于 agents.env";case"process.env":return"仅当前 shell 环境";case"default":return`默认值 (${e.default})`;case"missing":return"缺失"}}export function formatAgentRuntimeVerification(e){return"verified"===e.inspection.status?`已验证(${e.inspection.toolName})`:`未校验(${e.inspection.message})`}export function formatAgentEnvRuntimeStatus(e){if(e.runtime.verified)return e.runtime.present?e.runtime.matchesAgentsEnv?"✓ from yaml (stable)":e.configuredInAgentsEnv?"⚠ differs from yaml (ephemeral)":"⚠ from shell (ephemeral)":"default"===e.source?"未设置(使用默认值)":"process.env"===e.source?"✗ 当前运行 agent 未看到该变量":"✗ missing"}function r(n){return e("sha256").update(n).digest("hex").slice(0,8)}function o(e){return e.runtime.verified?!e.runtime.present&&"default"!==e.source:"missing"===e.source}function a(e){return e.runtime.verified&&e.runtime.present&&!e.runtime.matchesAgentsEnv}function c(e){return`缺少必填项: ${u(e.missingRequired)}`}function u(e){return e.map(e=>e.name).join(", ")}
@@ -87,6 +87,7 @@ export declare const browserInstanceConfigSchema: z.ZodEffects<z.ZodObject<{
87
87
  sessionsDir: z.ZodOptional<z.ZodString>;
88
88
  args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
89
89
  profileName: z.ZodOptional<z.ZodString>;
90
+ profileColor: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
90
91
  windowBounds: z.ZodOptional<z.ZodObject<{
91
92
  x: z.ZodOptional<z.ZodNumber>;
92
93
  y: z.ZodOptional<z.ZodNumber>;
@@ -117,6 +118,7 @@ export declare const browserInstanceConfigSchema: z.ZodEffects<z.ZodObject<{
117
118
  sessionsDir?: string | undefined;
118
119
  args?: string[] | undefined;
119
120
  profileName?: string | undefined;
121
+ profileColor?: string | undefined;
120
122
  windowBounds?: {
121
123
  x?: number | undefined;
122
124
  y?: number | undefined;
@@ -137,6 +139,7 @@ export declare const browserInstanceConfigSchema: z.ZodEffects<z.ZodObject<{
137
139
  sessionsDir?: string | undefined;
138
140
  args?: string[] | undefined;
139
141
  profileName?: string | undefined;
142
+ profileColor?: string | undefined;
140
143
  windowBounds?: {
141
144
  x?: number | undefined;
142
145
  y?: number | undefined;
@@ -157,6 +160,7 @@ export declare const browserInstanceConfigSchema: z.ZodEffects<z.ZodObject<{
157
160
  sessionsDir?: string | undefined;
158
161
  args?: string[] | undefined;
159
162
  profileName?: string | undefined;
163
+ profileColor?: string | undefined;
160
164
  windowBounds?: {
161
165
  x?: number | undefined;
162
166
  y?: number | undefined;
@@ -177,6 +181,7 @@ export declare const browserInstanceConfigSchema: z.ZodEffects<z.ZodObject<{
177
181
  sessionsDir?: string | undefined;
178
182
  args?: string[] | undefined;
179
183
  profileName?: string | undefined;
184
+ profileColor?: string | undefined;
180
185
  windowBounds?: {
181
186
  x?: number | undefined;
182
187
  y?: number | undefined;
@@ -200,6 +205,7 @@ export declare const browserConfigSchema: z.ZodEffects<z.ZodObject<{
200
205
  sessionsDir: z.ZodOptional<z.ZodString>;
201
206
  args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
202
207
  profileName: z.ZodOptional<z.ZodString>;
208
+ profileColor: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
203
209
  windowBounds: z.ZodOptional<z.ZodObject<{
204
210
  x: z.ZodOptional<z.ZodNumber>;
205
211
  y: z.ZodOptional<z.ZodNumber>;
@@ -230,6 +236,7 @@ export declare const browserConfigSchema: z.ZodEffects<z.ZodObject<{
230
236
  sessionsDir?: string | undefined;
231
237
  args?: string[] | undefined;
232
238
  profileName?: string | undefined;
239
+ profileColor?: string | undefined;
233
240
  windowBounds?: {
234
241
  x?: number | undefined;
235
242
  y?: number | undefined;
@@ -250,6 +257,7 @@ export declare const browserConfigSchema: z.ZodEffects<z.ZodObject<{
250
257
  sessionsDir?: string | undefined;
251
258
  args?: string[] | undefined;
252
259
  profileName?: string | undefined;
260
+ profileColor?: string | undefined;
253
261
  windowBounds?: {
254
262
  x?: number | undefined;
255
263
  y?: number | undefined;
@@ -270,6 +278,7 @@ export declare const browserConfigSchema: z.ZodEffects<z.ZodObject<{
270
278
  sessionsDir?: string | undefined;
271
279
  args?: string[] | undefined;
272
280
  profileName?: string | undefined;
281
+ profileColor?: string | undefined;
273
282
  windowBounds?: {
274
283
  x?: number | undefined;
275
284
  y?: number | undefined;
@@ -290,6 +299,7 @@ export declare const browserConfigSchema: z.ZodEffects<z.ZodObject<{
290
299
  sessionsDir?: string | undefined;
291
300
  args?: string[] | undefined;
292
301
  profileName?: string | undefined;
302
+ profileColor?: string | undefined;
293
303
  windowBounds?: {
294
304
  x?: number | undefined;
295
305
  y?: number | undefined;
@@ -312,6 +322,7 @@ export declare const browserConfigSchema: z.ZodEffects<z.ZodObject<{
312
322
  sessionsDir?: string | undefined;
313
323
  args?: string[] | undefined;
314
324
  profileName?: string | undefined;
325
+ profileColor?: string | undefined;
315
326
  windowBounds?: {
316
327
  x?: number | undefined;
317
328
  y?: number | undefined;
@@ -336,6 +347,7 @@ export declare const browserConfigSchema: z.ZodEffects<z.ZodObject<{
336
347
  sessionsDir?: string | undefined;
337
348
  args?: string[] | undefined;
338
349
  profileName?: string | undefined;
350
+ profileColor?: string | undefined;
339
351
  windowBounds?: {
340
352
  x?: number | undefined;
341
353
  y?: number | undefined;
@@ -358,6 +370,7 @@ export declare const browserConfigSchema: z.ZodEffects<z.ZodObject<{
358
370
  sessionsDir?: string | undefined;
359
371
  args?: string[] | undefined;
360
372
  profileName?: string | undefined;
373
+ profileColor?: string | undefined;
361
374
  windowBounds?: {
362
375
  x?: number | undefined;
363
376
  y?: number | undefined;
@@ -382,6 +395,7 @@ export declare const browserConfigSchema: z.ZodEffects<z.ZodObject<{
382
395
  sessionsDir?: string | undefined;
383
396
  args?: string[] | undefined;
384
397
  profileName?: string | undefined;
398
+ profileColor?: string | undefined;
385
399
  windowBounds?: {
386
400
  x?: number | undefined;
387
401
  y?: number | undefined;
@@ -456,6 +470,7 @@ export declare const rollConfigSchema: z.ZodObject<{
456
470
  sessionsDir: z.ZodOptional<z.ZodString>;
457
471
  args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
458
472
  profileName: z.ZodOptional<z.ZodString>;
473
+ profileColor: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
459
474
  windowBounds: z.ZodOptional<z.ZodObject<{
460
475
  x: z.ZodOptional<z.ZodNumber>;
461
476
  y: z.ZodOptional<z.ZodNumber>;
@@ -486,6 +501,7 @@ export declare const rollConfigSchema: z.ZodObject<{
486
501
  sessionsDir?: string | undefined;
487
502
  args?: string[] | undefined;
488
503
  profileName?: string | undefined;
504
+ profileColor?: string | undefined;
489
505
  windowBounds?: {
490
506
  x?: number | undefined;
491
507
  y?: number | undefined;
@@ -506,6 +522,7 @@ export declare const rollConfigSchema: z.ZodObject<{
506
522
  sessionsDir?: string | undefined;
507
523
  args?: string[] | undefined;
508
524
  profileName?: string | undefined;
525
+ profileColor?: string | undefined;
509
526
  windowBounds?: {
510
527
  x?: number | undefined;
511
528
  y?: number | undefined;
@@ -526,6 +543,7 @@ export declare const rollConfigSchema: z.ZodObject<{
526
543
  sessionsDir?: string | undefined;
527
544
  args?: string[] | undefined;
528
545
  profileName?: string | undefined;
546
+ profileColor?: string | undefined;
529
547
  windowBounds?: {
530
548
  x?: number | undefined;
531
549
  y?: number | undefined;
@@ -546,6 +564,7 @@ export declare const rollConfigSchema: z.ZodObject<{
546
564
  sessionsDir?: string | undefined;
547
565
  args?: string[] | undefined;
548
566
  profileName?: string | undefined;
567
+ profileColor?: string | undefined;
549
568
  windowBounds?: {
550
569
  x?: number | undefined;
551
570
  y?: number | undefined;
@@ -568,6 +587,7 @@ export declare const rollConfigSchema: z.ZodObject<{
568
587
  sessionsDir?: string | undefined;
569
588
  args?: string[] | undefined;
570
589
  profileName?: string | undefined;
590
+ profileColor?: string | undefined;
571
591
  windowBounds?: {
572
592
  x?: number | undefined;
573
593
  y?: number | undefined;
@@ -592,6 +612,7 @@ export declare const rollConfigSchema: z.ZodObject<{
592
612
  sessionsDir?: string | undefined;
593
613
  args?: string[] | undefined;
594
614
  profileName?: string | undefined;
615
+ profileColor?: string | undefined;
595
616
  windowBounds?: {
596
617
  x?: number | undefined;
597
618
  y?: number | undefined;
@@ -614,6 +635,7 @@ export declare const rollConfigSchema: z.ZodObject<{
614
635
  sessionsDir?: string | undefined;
615
636
  args?: string[] | undefined;
616
637
  profileName?: string | undefined;
638
+ profileColor?: string | undefined;
617
639
  windowBounds?: {
618
640
  x?: number | undefined;
619
641
  y?: number | undefined;
@@ -638,6 +660,7 @@ export declare const rollConfigSchema: z.ZodObject<{
638
660
  sessionsDir?: string | undefined;
639
661
  args?: string[] | undefined;
640
662
  profileName?: string | undefined;
663
+ profileColor?: string | undefined;
641
664
  windowBounds?: {
642
665
  x?: number | undefined;
643
666
  y?: number | undefined;
@@ -666,6 +689,7 @@ export declare const rollConfigSchema: z.ZodObject<{
666
689
  sessionsDir?: string | undefined;
667
690
  args?: string[] | undefined;
668
691
  profileName?: string | undefined;
692
+ profileColor?: string | undefined;
669
693
  windowBounds?: {
670
694
  x?: number | undefined;
671
695
  y?: number | undefined;
@@ -720,6 +744,7 @@ export declare const rollConfigSchema: z.ZodObject<{
720
744
  sessionsDir?: string | undefined;
721
745
  args?: string[] | undefined;
722
746
  profileName?: string | undefined;
747
+ profileColor?: string | undefined;
723
748
  windowBounds?: {
724
749
  x?: number | undefined;
725
750
  y?: number | undefined;
@@ -1 +1 @@
1
- import{z as e}from"zod";const o=["zhipin","yupao"],t=["managed-cdp","remote-cdp","existing-session"],n=["chrome","chromium","msedge"];export const browserWindowBoundsSchema=e.object({x:e.number().int().optional(),y:e.number().int().optional(),width:e.number().int().positive().optional(),height:e.number().int().positive().optional()});export const providerConfigSchema=e.object({apiKey:e.string(),baseUrl:e.string().optional()});export const llmConfigSchema=e.object({defaultProvider:e.string(),defaultModel:e.string(),providers:e.record(e.string(),providerConfigSchema)});export const askConfigSchema=e.object({llmModel:e.string().optional(),confirmThreshold:e.number().optional()});export const agentsConfigSchema=e.object({dataDir:e.string(),env:e.record(e.string(),e.record(e.string(),e.string())).optional()});export const browserInstanceConfigSchema=e.object({platform:e.enum(o).optional(),mode:e.enum(t).default("managed-cdp"),headless:e.boolean().optional(),cdpUrl:e.string().optional(),cdpHost:e.string().default("127.0.0.1"),cdpPort:e.number().int().min(1).max(65535).optional(),channel:e.enum(n).default("chrome"),executablePath:e.string().optional(),userDataDir:e.string().trim().min(1),sessionsDir:e.string().trim().min(1).optional(),args:e.array(e.string()).optional(),profileName:e.string().trim().min(1).optional(),windowBounds:browserWindowBoundsSchema.optional(),trackingAgentId:e.string().trim().min(1).optional()}).superRefine((o,t)=>{"managed-cdp"===o.mode&&void 0===o.cdpPort&&t.addIssue({code:e.ZodIssueCode.custom,path:["cdpPort"],message:"managed-cdp browser instance requires cdpPort"}),"remote-cdp"!==o.mode&&"existing-session"!==o.mode||void 0!==o.cdpUrl||t.addIssue({code:e.ZodIssueCode.custom,path:["cdpUrl"],message:`${o.mode} browser instance requires cdpUrl`})});export const browserConfigSchema=e.object({defaultInstance:e.string().trim().min(1).optional(),instances:e.record(e.string(),browserInstanceConfigSchema).default({})}).superRefine((o,t)=>{const n=Object.entries(o.instances);void 0!==o.defaultInstance&&void 0===o.instances[o.defaultInstance]&&t.addIssue({code:e.ZodIssueCode.custom,path:["defaultInstance"],message:`defaultInstance "${o.defaultInstance}" is not declared in browser.instances`});const s=new Map,r=new Map;for(const[o,i]of n){if(void 0!==i.cdpPort){const n=s.get(i.cdpPort);void 0!==n?t.addIssue({code:e.ZodIssueCode.custom,path:["instances",o,"cdpPort"],message:`cdpPort ${String(i.cdpPort)} is already used by browser instance "${n}"`}):s.set(i.cdpPort,o)}const n=r.get(i.userDataDir);void 0!==n?t.addIssue({code:e.ZodIssueCode.custom,path:["instances",o,"userDataDir"],message:`userDataDir is already used by browser instance "${n}"`}):r.set(i.userDataDir,o)}});export const rollConfigSchema=e.object({llm:llmConfigSchema,ask:askConfigSchema,agents:agentsConfigSchema,browser:browserConfigSchema.default({})});
1
+ import{z as e}from"zod";const o=["zhipin","yupao"],t=["managed-cdp","remote-cdp","existing-session"],n=["chrome","chromium","msedge"],s=e.string().trim().regex(/^#[\da-fA-F]{6}$/,"profileColor must be a hex RGB color such as #2563EB").transform(e=>e.toUpperCase());export const browserWindowBoundsSchema=e.object({x:e.number().int().optional(),y:e.number().int().optional(),width:e.number().int().positive().optional(),height:e.number().int().positive().optional()});export const providerConfigSchema=e.object({apiKey:e.string(),baseUrl:e.string().optional()});export const llmConfigSchema=e.object({defaultProvider:e.string(),defaultModel:e.string(),providers:e.record(e.string(),providerConfigSchema)});export const askConfigSchema=e.object({llmModel:e.string().optional(),confirmThreshold:e.number().optional()});export const agentsConfigSchema=e.object({dataDir:e.string(),env:e.record(e.string(),e.record(e.string(),e.string())).optional()});export const browserInstanceConfigSchema=e.object({platform:e.enum(o).optional(),mode:e.enum(t).default("managed-cdp"),headless:e.boolean().optional(),cdpUrl:e.string().optional(),cdpHost:e.string().default("127.0.0.1"),cdpPort:e.number().int().min(1).max(65535).optional(),channel:e.enum(n).default("chrome"),executablePath:e.string().optional(),userDataDir:e.string().trim().min(1),sessionsDir:e.string().trim().min(1).optional(),args:e.array(e.string()).optional(),profileName:e.string().trim().min(1).optional(),profileColor:s.optional(),windowBounds:browserWindowBoundsSchema.optional(),trackingAgentId:e.string().trim().min(1).optional()}).superRefine((o,t)=>{"managed-cdp"===o.mode&&void 0===o.cdpPort&&t.addIssue({code:e.ZodIssueCode.custom,path:["cdpPort"],message:"managed-cdp browser instance requires cdpPort"}),"remote-cdp"!==o.mode&&"existing-session"!==o.mode||void 0!==o.cdpUrl||t.addIssue({code:e.ZodIssueCode.custom,path:["cdpUrl"],message:`${o.mode} browser instance requires cdpUrl`})});export const browserConfigSchema=e.object({defaultInstance:e.string().trim().min(1).optional(),instances:e.record(e.string(),browserInstanceConfigSchema).default({})}).superRefine((o,t)=>{const n=Object.entries(o.instances);void 0!==o.defaultInstance&&void 0===o.instances[o.defaultInstance]&&t.addIssue({code:e.ZodIssueCode.custom,path:["defaultInstance"],message:`defaultInstance "${o.defaultInstance}" is not declared in browser.instances`});const s=new Map,r=new Map;for(const[o,i]of n){if(void 0!==i.cdpPort){const n=s.get(i.cdpPort);void 0!==n?t.addIssue({code:e.ZodIssueCode.custom,path:["instances",o,"cdpPort"],message:`cdpPort ${String(i.cdpPort)} is already used by browser instance "${n}"`}):s.set(i.cdpPort,o)}const n=r.get(i.userDataDir);void 0!==n?t.addIssue({code:e.ZodIssueCode.custom,path:["instances",o,"userDataDir"],message:`userDataDir is already used by browser instance "${n}"`}):r.set(i.userDataDir,o)}});export const rollConfigSchema=e.object({llm:llmConfigSchema,ask:askConfigSchema,agents:agentsConfigSchema,browser:browserConfigSchema.default({})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roll-agent/core",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",