@bolloon/bolloon-agent 0.5.5 → 0.6.1
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.
- package/dist/agents/execution-entry.js +10 -0
- package/dist/agents/goal-flywheel/wiring/seams.js +5 -1
- package/dist/agents/parse-tool-call.js +6 -1
- package/dist/agents/pi-sdk-session-factory.js +36 -3
- package/dist/agents/pi-sdk-tools.js +18 -8
- package/dist/agents/pi-sdk.js +749 -1390
- package/dist/agents/run-context.js +20 -0
- package/dist/agents/runner-resolver.js +3 -1
- package/dist/agents/tool-capability/index.js +51 -0
- package/dist/agents/workflow-pivot-loop.js +31 -10
- package/dist/agents/write-verify.js +60 -0
- package/dist/bollharness-integration/integration.js +8 -0
- package/dist/bollharness-integration/skill-adapter.js +32 -3
- package/dist/electron-build/agents/goal-flywheel/wiring/seams.js +5 -1
- package/dist/electron-build/agents/goal-flywheel/wiring/seams.js.map +1 -1
- package/dist/electron-build/agents/parse-tool-call.js +6 -1
- package/dist/electron-build/agents/parse-tool-call.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-session-factory.js +36 -3
- package/dist/electron-build/agents/pi-sdk-session-factory.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-tools.js +21 -11
- package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-types.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk.js +750 -1389
- package/dist/electron-build/agents/pi-sdk.js.map +1 -1
- package/dist/electron-build/agents/run-context.js +24 -0
- package/dist/electron-build/agents/run-context.js.map +1 -0
- package/dist/electron-build/agents/runner-resolver.js +3 -1
- package/dist/electron-build/agents/runner-resolver.js.map +1 -1
- package/dist/electron-build/agents/tool-capability/index.js +90 -0
- package/dist/electron-build/agents/tool-capability/index.js.map +1 -0
- package/dist/electron-build/agents/workflow-pivot-loop.js +31 -10
- package/dist/electron-build/agents/workflow-pivot-loop.js.map +1 -1
- package/dist/electron-build/agents/write-verify.js +99 -0
- package/dist/electron-build/agents/write-verify.js.map +1 -0
- package/dist/electron-build/bollharness-integration/integration.js +8 -0
- package/dist/electron-build/bollharness-integration/integration.js.map +1 -1
- package/dist/electron-build/bollharness-integration/skill-adapter.js +32 -3
- package/dist/electron-build/bollharness-integration/skill-adapter.js.map +1 -1
- package/dist/electron-build/kernel/channel-actor.js +339 -0
- package/dist/electron-build/kernel/channel-actor.js.map +1 -0
- package/dist/electron-build/kernel/control.js +102 -0
- package/dist/electron-build/kernel/control.js.map +1 -0
- package/dist/electron-build/kernel/model-runtime.js +508 -0
- package/dist/electron-build/kernel/model-runtime.js.map +1 -0
- package/dist/electron-build/kernel/run-lifecycle.js +146 -0
- package/dist/electron-build/kernel/run-lifecycle.js.map +1 -0
- package/dist/electron-build/kernel/transport.js +119 -0
- package/dist/electron-build/kernel/transport.js.map +1 -0
- package/dist/electron-build/llm/native-adapter.js +122 -0
- package/dist/electron-build/llm/native-adapter.js.map +1 -0
- package/dist/index.js +43 -19
- package/dist/ios/bolloon-web.json +3 -3
- package/dist/ios/client.js +13 -7
- package/dist/ios/mobile-core.js +7762 -6289
- package/dist/ios/mobile.js +64 -0
- package/dist/ios/routes-mobile-tasks.js +2 -1
- package/dist/ios/routes-tasks.js +16 -1
- package/dist/ios/routes-x402-info.js +28 -1
- package/dist/ios/server-storage.js +26 -5
- package/dist/ios/server.js +840 -862
- package/dist/ios/sw.js +1 -1
- package/dist/ios/ui/message-renderer.js +473 -29
- package/dist/ios/ui/step-timeline.js +13 -12
- package/dist/kernel/channel-actor.js +321 -0
- package/dist/kernel/control.js +95 -0
- package/dist/kernel/gate-scan.js +1350 -0
- package/dist/kernel/model-runtime.js +494 -0
- package/dist/kernel/plan-channel-actor.js +305 -0
- package/dist/kernel/plan-communication.js +163 -0
- package/dist/kernel/plan-constraint.js +152 -0
- package/dist/kernel/plan-deletion.js +32 -0
- package/dist/kernel/plan-harness.js +78 -0
- package/dist/kernel/plan-modelruntime.js +60 -0
- package/dist/kernel/plan-runcontext.js +163 -0
- package/dist/kernel/plan.js +149 -0
- package/dist/kernel/roster.js +244 -0
- package/dist/kernel/run-lifecycle.js +138 -0
- package/dist/kernel/transport.js +111 -0
- package/dist/llm/native-adapter.js +117 -0
- package/dist/web/bolloon-web.json +3 -3
- package/dist/web/client.js +12 -7
- package/dist/web/routes-tasks.js +16 -1
- package/dist/web/server.js +838 -862
- package/dist/web/sw.js +1 -1
- package/dist/web/ui/message-renderer.js +473 -29
- package/dist/web/ui/step-timeline.js +13 -12
- package/package.json +1 -1
- package/scripts/build-web.ts +74 -1
- package/dist/constraint-runtime/_archive_helper.d.ts +0 -1
- package/dist/constraint-runtime/_archive_helper.js +0 -9
- package/dist/constraint-runtime/assistant/index.d.ts +0 -11
- package/dist/constraint-runtime/assistant/index.js +0 -12
- package/dist/constraint-runtime/bootstrap/index.d.ts +0 -11
- package/dist/constraint-runtime/bootstrap/index.js +0 -12
- package/dist/constraint-runtime/bridge/index.d.ts +0 -11
- package/dist/constraint-runtime/bridge/index.js +0 -12
- package/dist/constraint-runtime/buddy/index.d.ts +0 -11
- package/dist/constraint-runtime/buddy/index.js +0 -12
- package/dist/constraint-runtime/cli/index.d.ts +0 -11
- package/dist/constraint-runtime/cli/index.js +0 -12
- package/dist/constraint-runtime/components/index.d.ts +0 -11
- package/dist/constraint-runtime/components/index.js +0 -12
- package/dist/constraint-runtime/constants/index.d.ts +0 -11
- package/dist/constraint-runtime/constants/index.js +0 -12
- package/dist/constraint-runtime/coordinator/index.d.ts +0 -11
- package/dist/constraint-runtime/coordinator/index.js +0 -12
- package/dist/constraint-runtime/cost_hook.d.ts +0 -2
- package/dist/constraint-runtime/cost_hook.js +0 -4
- package/dist/constraint-runtime/entrypoints/index.d.ts +0 -11
- package/dist/constraint-runtime/entrypoints/index.js +0 -12
- package/dist/constraint-runtime/execution_registry.d.ts +0 -20
- package/dist/constraint-runtime/execution_registry.js +0 -44
- package/dist/constraint-runtime/hooks/index.d.ts +0 -11
- package/dist/constraint-runtime/hooks/index.js +0 -12
- package/dist/constraint-runtime/ink.d.ts +0 -1
- package/dist/constraint-runtime/ink.js +0 -4
- package/dist/constraint-runtime/keybindings/index.d.ts +0 -11
- package/dist/constraint-runtime/keybindings/index.js +0 -12
- package/dist/constraint-runtime/memdir/index.d.ts +0 -11
- package/dist/constraint-runtime/memdir/index.js +0 -12
- package/dist/constraint-runtime/migrations/index.d.ts +0 -11
- package/dist/constraint-runtime/migrations/index.js +0 -12
- package/dist/constraint-runtime/moreright/index.d.ts +0 -11
- package/dist/constraint-runtime/moreright/index.js +0 -12
- package/dist/constraint-runtime/native_ts/index.d.ts +0 -11
- package/dist/constraint-runtime/native_ts/index.js +0 -12
- package/dist/constraint-runtime/output_styles/index.d.ts +0 -11
- package/dist/constraint-runtime/output_styles/index.js +0 -12
- package/dist/constraint-runtime/plugins/index.d.ts +0 -11
- package/dist/constraint-runtime/plugins/index.js +0 -12
- package/dist/constraint-runtime/port_manifest.d.ts +0 -7
- package/dist/constraint-runtime/port_manifest.js +0 -11
- package/dist/constraint-runtime/query.d.ts +0 -6
- package/dist/constraint-runtime/query.js +0 -1
- package/dist/constraint-runtime/remote/index.d.ts +0 -11
- package/dist/constraint-runtime/remote/index.js +0 -12
- package/dist/constraint-runtime/schemas/index.d.ts +0 -11
- package/dist/constraint-runtime/schemas/index.js +0 -12
- package/dist/constraint-runtime/screens/index.d.ts +0 -11
- package/dist/constraint-runtime/screens/index.js +0 -12
- package/dist/constraint-runtime/server/index.d.ts +0 -11
- package/dist/constraint-runtime/server/index.js +0 -12
- package/dist/constraint-runtime/services/index.d.ts +0 -11
- package/dist/constraint-runtime/services/index.js +0 -12
- package/dist/constraint-runtime/state/index.d.ts +0 -11
- package/dist/constraint-runtime/state/index.js +0 -12
- package/dist/constraint-runtime/system_init.d.ts +0 -1
- package/dist/constraint-runtime/system_init.js +0 -20
- package/dist/constraint-runtime/types/index.d.ts +0 -11
- package/dist/constraint-runtime/types/index.js +0 -12
- package/dist/constraint-runtime/upstream_proxy/index.d.ts +0 -11
- package/dist/constraint-runtime/upstream_proxy/index.js +0 -12
- package/dist/constraint-runtime/utils/index.d.ts +0 -11
- package/dist/constraint-runtime/utils/index.js +0 -12
- package/dist/constraint-runtime/vim/index.d.ts +0 -11
- package/dist/constraint-runtime/vim/index.js +0 -12
- package/dist/constraint-runtime/voice/index.d.ts +0 -11
- package/dist/constraint-runtime/voice/index.js +0 -12
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 取该 session 的唯一执行入口; 取不到就**响亮失败** (绝不静默回落直呼 `prompt`)。
|
|
3
|
+
* 注意返回的是**绑定过的**函数 —— 见文件头那个坑。
|
|
4
|
+
*/
|
|
5
|
+
export function requireRunExecution(agent) {
|
|
6
|
+
if (typeof agent.runExecution !== 'function') {
|
|
7
|
+
throw new Error('K8: 该 session 未提供 runExecution (唯一执行入口) ⇒ 拒绝直呼 prompt');
|
|
8
|
+
}
|
|
9
|
+
return agent.runExecution.bind(agent);
|
|
10
|
+
}
|
|
@@ -352,7 +352,11 @@ export const TERMINAL_PATHS = [
|
|
|
352
352
|
{
|
|
353
353
|
path: '失败 / 中断恢复 (Runner 内 finishRun)',
|
|
354
354
|
file: 'src/agents/pi-sdk.ts',
|
|
355
|
-
|
|
355
|
+
// 2026-10-02 (K10 ①): 该终止动作**改经内核生命周期端口** —— 直接 `await finishRun(` 已不存在,
|
|
356
|
+
// 现在写作 `submitRunLifecycle({ op: 'finish-run', runId, payload }, { finishRun })` + `assertLifecycleOk`。
|
|
357
|
+
// 登记项**跟着改形状, 不是放宽**: 端口未注入/被拒 ⇒ `assertLifecycleOk` 抛 ⇒ 终止照样走到收尾漏斗;
|
|
358
|
+
// 而"不许再出现直接调用"由 `src/test/k10-run-lifecycle-port.test.ts` 的反向断言钉住 (两处一起才成立)。
|
|
359
|
+
marker: /submitRunLifecycle\(\{[^}]*op:\s*'finish-run'/,
|
|
356
360
|
via: FUNNEL_CALL_RE,
|
|
357
361
|
},
|
|
358
362
|
{
|
|
@@ -285,7 +285,12 @@ function resolve(ctx, name) {
|
|
|
285
285
|
return defaultResolveAlias(name, ctx.tools);
|
|
286
286
|
}
|
|
287
287
|
/** 诊断开关 (2026-10-01): 默认关 —— 这条 diag 在热路径上且上屏, 默认开会刷屏 */
|
|
288
|
-
|
|
288
|
+
// 2026-10-02: 必须守卫 process —— 本文件被浏览器侧模块链引用
|
|
289
|
+
// (/ui/message-renderer.js → /agents/chat-segmenter.js → 这里);
|
|
290
|
+
// 顶层裸读 process.env 会让该模块在浏览器抛 ReferenceError, 静默废掉整条渲染链。
|
|
291
|
+
const _parseEnv = typeof process !== 'undefined' ? process.env : undefined;
|
|
292
|
+
const PARSE_DIAG_ON = !!_parseEnv
|
|
293
|
+
&& (_parseEnv.BOLLOON_PARSE_DIAG === '1' || _parseEnv.BOLLOON_VERBOSE === '1');
|
|
289
294
|
export function parseToolCall(content, ctx) {
|
|
290
295
|
if (!content)
|
|
291
296
|
return null;
|
|
@@ -16,6 +16,39 @@ import { getBranchPrefix, getCooldownMs } from './shell-guard.js';
|
|
|
16
16
|
* - lastSelfImproveAt: 自改冷却期
|
|
17
17
|
*/
|
|
18
18
|
import { PiAgentSession } from './pi-sdk.js';
|
|
19
|
+
import { getOrCreateActor } from '../kernel/channel-actor.js';
|
|
20
|
+
/**
|
|
21
|
+
* **K5 第 3 步**: 会话创建时绑定它所属 channel 的 Actor —— 只做**归属**。
|
|
22
|
+
* · **注册键取会话身份** (`loadSessionKey` 优先, 否则整条 `peerId`); `channelId` 另取 `peerId` 的 `:` 前段;
|
|
23
|
+
* · 没有身份 ⇒ **不绑定** (不许有 default 兜底桶);
|
|
24
|
+
* · 状态 (messageHistory / channelId / agentId / goalId) **仍在 Pi 实例字段上**, 逐项迁入见 8 步台账;
|
|
25
|
+
* · 绑定是**幂等**的: 同一 channelId 永远拿到同一个 actor (`getOrCreateActor`)。
|
|
26
|
+
*/
|
|
27
|
+
function attachActor(session, config) {
|
|
28
|
+
// **注册键 = 会话身份** (SessionStore key 优先, 否则整条 peerId)。
|
|
29
|
+
// 不许取 `:` 前段: 同一 channel 下不同会话会落进同一个桶 ⇒ history 串台
|
|
30
|
+
// (2026-10-02 全量回归实证: 5 红)。
|
|
31
|
+
const identity = String(config.loadSessionKey || config.peerId || '');
|
|
32
|
+
// **没有身份就不归属** —— 没有 'default' 兜底桶, 宁可不共享也不许串台。
|
|
33
|
+
if (!identity)
|
|
34
|
+
return session;
|
|
35
|
+
// 只预置 agentId (它是构造入参, 本来就属于会话); **channelId 不预置** —— 等 prompt/入口设置
|
|
36
|
+
const actor = getOrCreateActor(identity, { agentId: config.agentId || '' });
|
|
37
|
+
if (typeof session.attachActor === 'function')
|
|
38
|
+
session.attachActor(actor);
|
|
39
|
+
else
|
|
40
|
+
session.actor = actor;
|
|
41
|
+
return session;
|
|
42
|
+
}
|
|
43
|
+
function withActor(config) {
|
|
44
|
+
// **K5 步骤⑧**: 先把会话身份算出来、把 actor 取好, 再构造 session ——
|
|
45
|
+
// 这样构造期的异步回灌 (`loadSessionKey`) 直接落在身份 actor 上, 不会先落进私有 actor 再换家。
|
|
46
|
+
// 没身份 ⇒ 不注入 (session 自己用私有 actor)。
|
|
47
|
+
const identity = String(config.loadSessionKey || config.peerId || '');
|
|
48
|
+
if (!identity)
|
|
49
|
+
return config;
|
|
50
|
+
return { ...config, actor: getOrCreateActor(identity, { agentId: config.agentId || '' }) };
|
|
51
|
+
}
|
|
19
52
|
let sessionInstance = null;
|
|
20
53
|
let lastIdentityDid = null;
|
|
21
54
|
const independentSessions = new Map();
|
|
@@ -29,7 +62,7 @@ export async function createAgentSession(config, forceNew) {
|
|
|
29
62
|
await existing.whenReady();
|
|
30
63
|
return existing;
|
|
31
64
|
}
|
|
32
|
-
const session = new PiAgentSession(config);
|
|
65
|
+
const session = attachActor(new PiAgentSession(withActor(config)), config);
|
|
33
66
|
independentSessions.set(key, session);
|
|
34
67
|
console.log(`[createAgentSession] 创建独立 session, key=${key}, DID=${incomingDid}`);
|
|
35
68
|
await session.whenReady();
|
|
@@ -37,7 +70,7 @@ export async function createAgentSession(config, forceNew) {
|
|
|
37
70
|
}
|
|
38
71
|
if (forceNew) {
|
|
39
72
|
const key = `force:${Date.now()}`;
|
|
40
|
-
const session = new PiAgentSession(config);
|
|
73
|
+
const session = attachActor(new PiAgentSession(withActor(config)), config);
|
|
41
74
|
independentSessions.set(key, session);
|
|
42
75
|
console.log(`[createAgentSession] 创建强制新 session, key=${key}`);
|
|
43
76
|
await session.whenReady();
|
|
@@ -61,7 +94,7 @@ export async function createAgentSession(config, forceNew) {
|
|
|
61
94
|
await sessionInstance.whenReady();
|
|
62
95
|
return sessionInstance;
|
|
63
96
|
}
|
|
64
|
-
const newSession = new PiAgentSession(config);
|
|
97
|
+
const newSession = attachActor(new PiAgentSession(withActor(config)), config);
|
|
65
98
|
sessionInstance = newSession;
|
|
66
99
|
lastIdentityDid = config.identityDoc?.did || null;
|
|
67
100
|
console.log(`[createAgentSession] 新建 session, DID=${lastIdentityDid}`);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs/promises';
|
|
2
|
+
import { loadDomainModule } from './tool-capability/index.js'; // K1 ④: 领域能力唯一入口
|
|
2
3
|
import { loadWalletTool } from './wallet-tools.js';
|
|
4
|
+
import { withWriteVerified } from './write-verify.js'; // K10 ⑦: 写类工具成功后拼读回事实
|
|
3
5
|
import * as fsSync from 'fs';
|
|
4
6
|
import * as path from 'path';
|
|
5
7
|
import * as os from 'os';
|
|
@@ -1052,7 +1054,11 @@ export function registerBuiltinTools(ctx) {
|
|
|
1052
1054
|
await stageWrite(relPath, before, content, action, ctx.cwd).catch(() => { });
|
|
1053
1055
|
await fs.mkdir(path.dirname(absPath), { recursive: true });
|
|
1054
1056
|
await fs.writeFile(absPath, content, 'utf-8');
|
|
1055
|
-
|
|
1057
|
+
// K10 ⑦: 写成功 ≠ 任务成功 —— 拼上读回事实 (`[已核对] …` / `[未核对] …`)
|
|
1058
|
+
return withWriteVerified('write_file', { path: relPath }, ctx.cwd, {
|
|
1059
|
+
success: true,
|
|
1060
|
+
output: `✅ wrote ${relPath} (${content.length} bytes)`,
|
|
1061
|
+
});
|
|
1056
1062
|
}
|
|
1057
1063
|
catch (e) {
|
|
1058
1064
|
return { success: false, error: `写文件失败: ${String(e)}` };
|
|
@@ -1086,7 +1092,11 @@ export function registerBuiltinTools(ctx) {
|
|
|
1086
1092
|
const { stageWrite } = await import('./write-staging.js');
|
|
1087
1093
|
await stageWrite(relPath, original, updated, 'edit', ctx.cwd).catch(() => { });
|
|
1088
1094
|
await fs.writeFile(absPath, updated, 'utf-8');
|
|
1089
|
-
|
|
1095
|
+
// K10 ⑦: 同上, 编辑也读回自证
|
|
1096
|
+
return withWriteVerified('edit_file', { path: relPath }, ctx.cwd, {
|
|
1097
|
+
success: true,
|
|
1098
|
+
output: `✅ edited ${relPath} (${oldText.length} → ${newText.length} 字节)`,
|
|
1099
|
+
});
|
|
1090
1100
|
}
|
|
1091
1101
|
catch (e) {
|
|
1092
1102
|
return { success: false, error: `编辑文件失败: ${String(e)}` };
|
|
@@ -3829,7 +3839,7 @@ export function registerWalletTools(ctx) {
|
|
|
3829
3839
|
parameters: { limit: '可选 数量 (默认 50)', offset: '可选 偏移', closed: '可选 是否只显示已关闭' },
|
|
3830
3840
|
execute: async (args) => {
|
|
3831
3841
|
try {
|
|
3832
|
-
const { listMarkets } = await
|
|
3842
|
+
const { listMarkets } = await loadDomainModule('PolymarketSDK/listMarkets');
|
|
3833
3843
|
const markets = await listMarkets({
|
|
3834
3844
|
limit: args.limit ? Number(args.limit) : 50,
|
|
3835
3845
|
offset: args.offset ? Number(args.offset) : 0,
|
|
@@ -3852,7 +3862,7 @@ export function registerWalletTools(ctx) {
|
|
|
3852
3862
|
parameters: { marketId: '市场 ID (必填)' },
|
|
3853
3863
|
execute: async (args) => {
|
|
3854
3864
|
try {
|
|
3855
|
-
const mod = await
|
|
3865
|
+
const mod = await loadDomainModule('PolymarketSDK/getMarket');
|
|
3856
3866
|
const fn = mod.getMarket || mod.default;
|
|
3857
3867
|
const m = await fn(String(args.marketId));
|
|
3858
3868
|
if (!m)
|
|
@@ -3877,7 +3887,7 @@ export function registerWalletTools(ctx) {
|
|
|
3877
3887
|
},
|
|
3878
3888
|
execute: async (args) => {
|
|
3879
3889
|
try {
|
|
3880
|
-
const { getOrders } = await
|
|
3890
|
+
const { getOrders } = await loadDomainModule('PolymarketSDK/getOrders');
|
|
3881
3891
|
const orders = await getOrders({
|
|
3882
3892
|
privateKey: String(args.privateKey),
|
|
3883
3893
|
marketId: args.marketId ? String(args.marketId) : undefined,
|
|
@@ -3912,7 +3922,7 @@ export function registerWalletTools(ctx) {
|
|
|
3912
3922
|
},
|
|
3913
3923
|
execute: async (args) => {
|
|
3914
3924
|
try {
|
|
3915
|
-
const { createOrder } = await
|
|
3925
|
+
const { createOrder } = await loadDomainModule('PolymarketSDK/createOrder');
|
|
3916
3926
|
const r = await createOrder({
|
|
3917
3927
|
privateKey: String(args.privateKey),
|
|
3918
3928
|
marketId: String(args.marketId),
|
|
@@ -3949,7 +3959,7 @@ export function registerWalletTools(ctx) {
|
|
|
3949
3959
|
},
|
|
3950
3960
|
execute: async (args) => {
|
|
3951
3961
|
try {
|
|
3952
|
-
const { cancelOrder } = await
|
|
3962
|
+
const { cancelOrder } = await loadDomainModule('PolymarketSDK/cancelOrder');
|
|
3953
3963
|
const r = await cancelOrder({
|
|
3954
3964
|
privateKey: String(args.privateKey),
|
|
3955
3965
|
orderId: String(args.orderId),
|
|
@@ -4123,7 +4133,7 @@ export function registerWalletTools(ctx) {
|
|
|
4123
4133
|
parameters: { owners: 'JSON 数组 owner 地址 (必填)', threshold: '需要几个签名 (必填)' },
|
|
4124
4134
|
execute: async (args) => {
|
|
4125
4135
|
try {
|
|
4126
|
-
const { deploySafe } = await
|
|
4136
|
+
const { deploySafe } = await loadDomainModule('SafeSDK/deploySafe');
|
|
4127
4137
|
const owners = Array.isArray(args.owners) ? args.owners : JSON.parse(String(args.owners));
|
|
4128
4138
|
const r = await deploySafe({ owners, threshold: Number(args.threshold) });
|
|
4129
4139
|
return { success: true, output: `✅ Safe 部署: ${JSON.stringify(r)}` };
|