evolcore 0.0.8 → 0.0.9
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/CHANGELOG.md +24 -0
- package/README.md +37 -3
- package/dist/agents/baseagent.js +111 -19
- package/dist/agents/claude-runner.js +30 -2
- package/dist/agents/codex-app-server-client.js +31 -0
- package/dist/agents/codex-runner.js +3 -0
- package/dist/aun/msg/group.js +9 -9
- package/dist/aun/msg/p2p.js +11 -6
- package/dist/aun/msg/upload.js +43 -29
- package/dist/aun/outbox.js +48 -5
- package/dist/channels/aun.js +199 -50
- package/dist/cli/aun-commands.js +10 -7
- package/dist/cli/daemon-commands.js +19 -4
- package/dist/cli/index.js +11 -1
- package/dist/cli/init.js +103 -4
- package/dist/cli/model.js +5 -5
- package/dist/config/builtin-role-templates.js +4 -3
- package/dist/config/config-field-policy.js +6 -2
- package/dist/config/config-manager.js +48 -11
- package/dist/config/role-schema.js +18 -3
- package/dist/config/role-service.js +3 -3
- package/dist/config/role-store.js +4 -3
- package/dist/config-store.js +4 -0
- package/dist/core/auth/operation-authorizer.js +3 -1
- package/dist/core/bootstrap-service.js +0 -12
- package/dist/core/channel-loader.js +5 -1
- package/dist/core/command/command-handler.js +1 -1
- package/dist/core/command/evol-menu-version-gate.js +3 -2
- package/dist/core/command/menu-handler.js +33 -22
- package/dist/core/command/menu-protocol.js +7 -4
- package/dist/core/command/slash-handler.js +4 -4
- package/dist/core/inference/text-inference.js +18 -5
- package/dist/core/message/message-bridge.js +17 -6
- package/dist/core/message/response-engine.js +22 -3
- package/dist/core/model/config-scope.js +3 -3
- package/dist/core/permission/tool-policy.js +18 -0
- package/dist/index.js +43 -26
- package/dist/ipc.js +1 -1
- package/dist/product.js +1 -0
- package/dist/utils/autostart.js +27 -0
- package/dist/utils/ecweb-utils.js +15 -2
- package/dist/utils/macos-autostart.js +179 -0
- package/dist/utils/windows-autostart.js +130 -0
- package/ecagent/dist/agent-loop.d.ts +1 -1
- package/ecagent/dist/agent-loop.js +1 -1
- package/ecagent/dist/agent.d.ts +1 -1
- package/ecagent/dist/agent.js +1 -1
- package/ecagent/dist/harness/agent-harness.d.ts +1 -1
- package/ecagent/dist/harness/compaction/branch-summarization.d.ts +1 -1
- package/ecagent/dist/harness/compaction/compaction.d.ts +1 -1
- package/ecagent/dist/harness/compaction/utils.d.ts +1 -1
- package/ecagent/dist/harness/messages.d.ts +1 -1
- package/ecagent/dist/harness/session/session.d.ts +1 -1
- package/ecagent/dist/harness/types.d.ts +1 -1
- package/ecagent/dist/proxy.d.ts +1 -1
- package/ecagent/dist/proxy.js +1 -1
- package/ecagent/dist/types.d.ts +1 -1
- package/kits/migrations/migrate-role-config-v5.mjs +27 -2
- package/kits/schemas/agent-config.schema.10.json +19 -1
- package/kits/schemas/daemon.schema.4.json +4 -0
- package/kits/schemas/defaults.schema.4.json +15 -1
- package/kits/schemas/relation-config.schema.8.json +22 -1
- package/kits/schemas/role-config.schema.1.json +2 -2
- package/package.json +2 -4
- package/ecagent/dist/agent-loop.d.ts.map +0 -1
- package/ecagent/dist/agent-loop.js.map +0 -1
- package/ecagent/dist/agent.d.ts.map +0 -1
- package/ecagent/dist/agent.js.map +0 -1
- package/ecagent/dist/harness/agent-harness.d.ts.map +0 -1
- package/ecagent/dist/harness/agent-harness.js.map +0 -1
- package/ecagent/dist/harness/compaction/branch-summarization.d.ts.map +0 -1
- package/ecagent/dist/harness/compaction/branch-summarization.js.map +0 -1
- package/ecagent/dist/harness/compaction/compaction.d.ts.map +0 -1
- package/ecagent/dist/harness/compaction/compaction.js.map +0 -1
- package/ecagent/dist/harness/compaction/utils.d.ts.map +0 -1
- package/ecagent/dist/harness/compaction/utils.js.map +0 -1
- package/ecagent/dist/harness/env/nodejs.d.ts.map +0 -1
- package/ecagent/dist/harness/env/nodejs.js.map +0 -1
- package/ecagent/dist/harness/messages.d.ts.map +0 -1
- package/ecagent/dist/harness/messages.js.map +0 -1
- package/ecagent/dist/harness/prompt-templates.d.ts.map +0 -1
- package/ecagent/dist/harness/prompt-templates.js.map +0 -1
- package/ecagent/dist/harness/session/jsonl-repo.d.ts.map +0 -1
- package/ecagent/dist/harness/session/jsonl-repo.js.map +0 -1
- package/ecagent/dist/harness/session/jsonl-storage.d.ts.map +0 -1
- package/ecagent/dist/harness/session/jsonl-storage.js.map +0 -1
- package/ecagent/dist/harness/session/memory-repo.d.ts.map +0 -1
- package/ecagent/dist/harness/session/memory-repo.js.map +0 -1
- package/ecagent/dist/harness/session/memory-storage.d.ts.map +0 -1
- package/ecagent/dist/harness/session/memory-storage.js.map +0 -1
- package/ecagent/dist/harness/session/repo-utils.d.ts.map +0 -1
- package/ecagent/dist/harness/session/repo-utils.js.map +0 -1
- package/ecagent/dist/harness/session/session.d.ts.map +0 -1
- package/ecagent/dist/harness/session/session.js.map +0 -1
- package/ecagent/dist/harness/session/uuid.d.ts.map +0 -1
- package/ecagent/dist/harness/session/uuid.js.map +0 -1
- package/ecagent/dist/harness/skills.d.ts.map +0 -1
- package/ecagent/dist/harness/skills.js.map +0 -1
- package/ecagent/dist/harness/system-prompt.d.ts.map +0 -1
- package/ecagent/dist/harness/system-prompt.js.map +0 -1
- package/ecagent/dist/harness/types.d.ts.map +0 -1
- package/ecagent/dist/harness/types.js.map +0 -1
- package/ecagent/dist/harness/utils/shell-output.d.ts.map +0 -1
- package/ecagent/dist/harness/utils/shell-output.js.map +0 -1
- package/ecagent/dist/harness/utils/truncate.d.ts.map +0 -1
- package/ecagent/dist/harness/utils/truncate.js.map +0 -1
- package/ecagent/dist/index.d.ts.map +0 -1
- package/ecagent/dist/index.js.map +0 -1
- package/ecagent/dist/node.d.ts.map +0 -1
- package/ecagent/dist/node.js.map +0 -1
- package/ecagent/dist/proxy.d.ts.map +0 -1
- package/ecagent/dist/proxy.js.map +0 -1
- package/ecagent/dist/runtime/api/lazy.d.ts.map +0 -1
- package/ecagent/dist/runtime/api/lazy.js.map +0 -1
- package/ecagent/dist/runtime/api/pi-messages.d.ts.map +0 -1
- package/ecagent/dist/runtime/api/pi-messages.js.map +0 -1
- package/ecagent/dist/runtime/api/pi-messages.lazy.d.ts.map +0 -1
- package/ecagent/dist/runtime/api/pi-messages.lazy.js.map +0 -1
- package/ecagent/dist/runtime/auth/context.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/context.js.map +0 -1
- package/ecagent/dist/runtime/auth/credential-store.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/credential-store.js.map +0 -1
- package/ecagent/dist/runtime/auth/helpers.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/helpers.js.map +0 -1
- package/ecagent/dist/runtime/auth/resolve.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/resolve.js.map +0 -1
- package/ecagent/dist/runtime/auth/types.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/types.js.map +0 -1
- package/ecagent/dist/runtime/compat.d.ts.map +0 -1
- package/ecagent/dist/runtime/compat.js.map +0 -1
- package/ecagent/dist/runtime/index.d.ts.map +0 -1
- package/ecagent/dist/runtime/index.js.map +0 -1
- package/ecagent/dist/runtime/models.d.ts.map +0 -1
- package/ecagent/dist/runtime/models.js.map +0 -1
- package/ecagent/dist/runtime/oauth.d.ts.map +0 -1
- package/ecagent/dist/runtime/oauth.js.map +0 -1
- package/ecagent/dist/runtime/providers/faux.d.ts.map +0 -1
- package/ecagent/dist/runtime/providers/faux.js.map +0 -1
- package/ecagent/dist/runtime/types.d.ts.map +0 -1
- package/ecagent/dist/runtime/types.js.map +0 -1
- package/ecagent/dist/runtime/utils/diagnostics.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/diagnostics.js.map +0 -1
- package/ecagent/dist/runtime/utils/event-stream.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/event-stream.js.map +0 -1
- package/ecagent/dist/runtime/utils/headers.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/headers.js.map +0 -1
- package/ecagent/dist/runtime/utils/json-parse.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/json-parse.js.map +0 -1
- package/ecagent/dist/runtime/utils/oauth/types.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/oauth/types.js.map +0 -1
- package/ecagent/dist/runtime/utils/overflow.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/overflow.js.map +0 -1
- package/ecagent/dist/runtime/utils/provider-env.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/provider-env.js.map +0 -1
- package/ecagent/dist/runtime/utils/retry.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/retry.js.map +0 -1
- package/ecagent/dist/runtime/utils/typebox-helpers.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/typebox-helpers.js.map +0 -1
- package/ecagent/dist/runtime/utils/validation.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/validation.js.map +0 -1
- package/ecagent/dist/types.d.ts.map +0 -1
- package/ecagent/dist/types.js.map +0 -1
- package/ecagent/package.json +0 -93
- package/ecagent/src/agent-loop.ts +0 -792
- package/ecagent/src/agent.ts +0 -575
- package/ecagent/src/harness/agent-harness.ts +0 -1029
- package/ecagent/src/harness/compaction/branch-summarization.ts +0 -261
- package/ecagent/src/harness/compaction/compaction.ts +0 -753
- package/ecagent/src/harness/compaction/utils.ts +0 -144
- package/ecagent/src/harness/env/nodejs.ts +0 -569
- package/ecagent/src/harness/messages.ts +0 -164
- package/ecagent/src/harness/prompt-templates.ts +0 -267
- package/ecagent/src/harness/session/jsonl-repo.ts +0 -179
- package/ecagent/src/harness/session/jsonl-storage.ts +0 -314
- package/ecagent/src/harness/session/memory-repo.ts +0 -50
- package/ecagent/src/harness/session/memory-storage.ts +0 -133
- package/ecagent/src/harness/session/repo-utils.ts +0 -51
- package/ecagent/src/harness/session/session.ts +0 -338
- package/ecagent/src/harness/session/uuid.ts +0 -54
- package/ecagent/src/harness/skills.ts +0 -375
- package/ecagent/src/harness/system-prompt.ts +0 -34
- package/ecagent/src/harness/types.ts +0 -838
- package/ecagent/src/harness/utils/shell-output.ts +0 -135
- package/ecagent/src/harness/utils/truncate.ts +0 -344
- package/ecagent/src/index.ts +0 -46
- package/ecagent/src/node.ts +0 -2
- package/ecagent/src/proxy.ts +0 -367
- package/ecagent/src/runtime/api/lazy.ts +0 -70
- package/ecagent/src/runtime/api/pi-messages.lazy.ts +0 -4
- package/ecagent/src/runtime/api/pi-messages.ts +0 -436
- package/ecagent/src/runtime/auth/context.ts +0 -45
- package/ecagent/src/runtime/auth/credential-store.ts +0 -47
- package/ecagent/src/runtime/auth/helpers.ts +0 -46
- package/ecagent/src/runtime/auth/resolve.ts +0 -141
- package/ecagent/src/runtime/auth/types.ts +0 -182
- package/ecagent/src/runtime/compat.ts +0 -158
- package/ecagent/src/runtime/index.ts +0 -31
- package/ecagent/src/runtime/models.ts +0 -452
- package/ecagent/src/runtime/oauth.ts +0 -1
- package/ecagent/src/runtime/providers/faux.ts +0 -538
- package/ecagent/src/runtime/types.ts +0 -718
- package/ecagent/src/runtime/utils/diagnostics.ts +0 -45
- package/ecagent/src/runtime/utils/event-stream.ts +0 -88
- package/ecagent/src/runtime/utils/headers.ts +0 -18
- package/ecagent/src/runtime/utils/json-parse.ts +0 -124
- package/ecagent/src/runtime/utils/oauth/types.ts +0 -79
- package/ecagent/src/runtime/utils/overflow.ts +0 -165
- package/ecagent/src/runtime/utils/provider-env.ts +0 -52
- package/ecagent/src/runtime/utils/retry.ts +0 -101
- package/ecagent/src/runtime/utils/typebox-helpers.ts +0 -24
- package/ecagent/src/runtime/utils/validation.ts +0 -310
- package/ecagent/src/types.ts +0 -430
- package/ecagent/tsconfig.build.json +0 -32
package/dist/cli/aun-commands.js
CHANGED
|
@@ -808,7 +808,7 @@ Options:
|
|
|
808
808
|
--app <name> 指定应用 slot(独立消费通道,不影响 daemon)
|
|
809
809
|
--aun-path <path> 指定 AUN keystore 根
|
|
810
810
|
--format json 输出 JSON 格式
|
|
811
|
-
--encrypt
|
|
811
|
+
--encrypt 强制端到端加密(未指定时使用 daemon 默认值)
|
|
812
812
|
--no-encrypt 强制明文发送(优先于 --encrypt)
|
|
813
813
|
--thread <id> 指定话题 ID(用于多话题路由)
|
|
814
814
|
--session <latest|all|id> 按 EvolCore 逻辑会话过滤历史(默认 latest)
|
|
@@ -1048,9 +1048,10 @@ Options:
|
|
|
1048
1048
|
}
|
|
1049
1049
|
body = { mode: 'text', text };
|
|
1050
1050
|
}
|
|
1051
|
-
//
|
|
1052
|
-
|
|
1053
|
-
|
|
1051
|
+
// 显式 flag 覆盖 daemon 默认值;未指定时保留 undefined。
|
|
1052
|
+
const encrypt = args.includes('--no-encrypt')
|
|
1053
|
+
? false
|
|
1054
|
+
: args.includes('--encrypt') ? true : undefined;
|
|
1054
1055
|
const thread = getArgValue(args, '--thread');
|
|
1055
1056
|
const returnPolicyRaw = getArgValue(args, '--return');
|
|
1056
1057
|
if (returnPolicyRaw && returnPolicyRaw !== 'required' && returnPolicyRaw !== 'none') {
|
|
@@ -1292,7 +1293,7 @@ Options:
|
|
|
1292
1293
|
--app <name> 指定应用 slot(独立消费通道,不影响 daemon)
|
|
1293
1294
|
--aun-path <path> 指定 AUN keystore 根
|
|
1294
1295
|
--format json 输出 JSON 格式
|
|
1295
|
-
--encrypt
|
|
1296
|
+
--encrypt 强制端到端加密(未指定时使用 daemon 默认值;仅 send)
|
|
1296
1297
|
--no-encrypt 强制明文发送(优先于 --encrypt;仅 send)
|
|
1297
1298
|
--thread <id> 指定话题 ID(仅 send)
|
|
1298
1299
|
--return <none|required> 跨会话发送必填(仅 send;Trigger 只能使用 none)
|
|
@@ -1469,8 +1470,10 @@ Options:
|
|
|
1469
1470
|
body = { mode: 'text', text };
|
|
1470
1471
|
}
|
|
1471
1472
|
const mentions = collectMentions();
|
|
1472
|
-
//
|
|
1473
|
-
const encryptGroup = args.includes('--
|
|
1473
|
+
// 显式 flag 覆盖 daemon 默认值;未指定时保留 undefined。
|
|
1474
|
+
const encryptGroup = args.includes('--no-encrypt')
|
|
1475
|
+
? false
|
|
1476
|
+
: args.includes('--encrypt') ? true : undefined;
|
|
1474
1477
|
const thread = getArgValue(args, '--thread');
|
|
1475
1478
|
const returnPolicyRaw = getArgValue(args, '--return');
|
|
1476
1479
|
if (returnPolicyRaw && returnPolicyRaw !== 'required' && returnPolicyRaw !== 'none') {
|
|
@@ -15,9 +15,8 @@ import { cmdInit, needsControlAidInit, initTail } from './init.js';
|
|
|
15
15
|
import * as platform from '../utils/cross-platform.js';
|
|
16
16
|
import { EventBus } from '../core/event-bus.js';
|
|
17
17
|
import { tryUpgrade, tryUpgradeAunSdk, tryUpgradeGlobalPkg, resolveGlobalPkg } from '../utils/npm-ops.js';
|
|
18
|
-
import { fetchEcwebPairCode } from '../utils/ecweb-utils.js';
|
|
18
|
+
import { ecwebVersionRequirementError, fetchEcwebPairCode, resolveEcwebLaunchCommand } from '../utils/ecweb-utils.js';
|
|
19
19
|
import { isHostChinese } from '../utils/locale.js';
|
|
20
|
-
import { resolveEcwebLaunchCommand } from '../utils/ecweb-utils.js';
|
|
21
20
|
import { resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG } from '../aun/aid/client.js';
|
|
22
21
|
import { scanInstances, cleanupInstances, findOrphanProcesses, killOrphans } from '../utils/instance-registry.js';
|
|
23
22
|
import { filterLogFiles, deriveLogTypes, computePreChecked, validateLogTypes, shortLogName as shortLogNameLocal } from './watch-logs.js';
|
|
@@ -2619,6 +2618,22 @@ export async function startEcwebIfEnabled(p) {
|
|
|
2619
2618
|
const cfg = loadDaemonConfig();
|
|
2620
2619
|
if (!cfg.ecweb?.enabled)
|
|
2621
2620
|
return false;
|
|
2621
|
+
const installedPkg = resolveGlobalPkg(WEB_PACKAGE_NAME);
|
|
2622
|
+
if (!installedPkg) {
|
|
2623
|
+
console.log(`⚠ EC Web 未安装,跳过启动(运行 npm i -g ${WEB_PACKAGE_NAME}@latest 后可用)`);
|
|
2624
|
+
return false;
|
|
2625
|
+
}
|
|
2626
|
+
const versionError = ecwebVersionRequirementError(installedPkg.version);
|
|
2627
|
+
if (versionError) {
|
|
2628
|
+
try {
|
|
2629
|
+
await stopEcwebIfRunning(p);
|
|
2630
|
+
}
|
|
2631
|
+
catch (error) {
|
|
2632
|
+
console.log(`⚠ EC Web 旧进程未清理干净: ${error instanceof Error ? error.message : String(error)}`);
|
|
2633
|
+
}
|
|
2634
|
+
console.log(`❌ ${versionError}`);
|
|
2635
|
+
return false;
|
|
2636
|
+
}
|
|
2622
2637
|
let wasRunning = false;
|
|
2623
2638
|
try {
|
|
2624
2639
|
wasRunning = await stopEcwebIfRunning(p); // 先停旧进程(有则停),保证加载最新代码
|
|
@@ -2629,9 +2644,9 @@ export async function startEcwebIfEnabled(p) {
|
|
|
2629
2644
|
}
|
|
2630
2645
|
const port = cfg.ecweb.port ?? 42705;
|
|
2631
2646
|
const args = ['--home', p.root, '--port', String(port)];
|
|
2632
|
-
const launch = resolveEcwebLaunchCommand(args);
|
|
2647
|
+
const launch = resolveEcwebLaunchCommand(args, { installedPkg });
|
|
2633
2648
|
if (!launch) {
|
|
2634
|
-
console.log(`⚠ EC Web
|
|
2649
|
+
console.log(`⚠ EC Web 启动入口不存在,请重新安装: npm i -g ${WEB_PACKAGE_NAME}@latest`);
|
|
2635
2650
|
return false;
|
|
2636
2651
|
}
|
|
2637
2652
|
// 防御性检查:确保 command 和 args 有效
|
package/dist/cli/index.js
CHANGED
|
@@ -113,6 +113,8 @@ export async function main(args) {
|
|
|
113
113
|
--baseagent <claude|codex|gemini|ecagent> 可选。默认从 PATH 检测,ecagent 需显式选择
|
|
114
114
|
--projectpath <abs-path> 可选。默认项目目录(必须绝对路径,自动创建)
|
|
115
115
|
--ecweb 可选。安装 EC Web 并启用自启动
|
|
116
|
+
--auto-start Windows/macOS 上启用 EvolCore 登录自启动
|
|
117
|
+
--no-auto-start Windows/macOS 上禁用 EvolCore 登录自启动
|
|
116
118
|
--format json 可选但推荐。stdout 输出 init.result JSON
|
|
117
119
|
--force 已有不同 owner 时强制覆盖
|
|
118
120
|
|
|
@@ -162,14 +164,22 @@ export async function main(args) {
|
|
|
162
164
|
const { suppressSdkLogs } = await import('../aun/aid/index.js');
|
|
163
165
|
suppressSdkLogs();
|
|
164
166
|
const nonInteractive = args.includes('--non-interactive');
|
|
167
|
+
const wantsAutoStart = args.includes('--auto-start');
|
|
168
|
+
const wantsNoAutoStart = args.includes('--no-auto-start');
|
|
169
|
+
if (wantsAutoStart && wantsNoAutoStart) {
|
|
170
|
+
console.error('❌ --auto-start 与 --no-auto-start 不能同时使用');
|
|
171
|
+
process.exitCode = 1;
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
165
174
|
const initialized = await cmdInit({
|
|
166
175
|
nonInteractive,
|
|
167
176
|
baseagent: getArgValue(args, '--baseagent'),
|
|
168
177
|
force: args.includes('--force'),
|
|
169
178
|
owner: getArgValue(args, '--owner'),
|
|
170
179
|
projectpath: getArgValue(args, '--projectpath'),
|
|
171
|
-
ecweb: args.includes('--ecweb'),
|
|
180
|
+
ecweb: args.includes('--ecweb') ? true : undefined,
|
|
172
181
|
format: getArgValue(args, '--format'),
|
|
182
|
+
autoStart: wantsAutoStart ? true : wantsNoAutoStart ? false : undefined,
|
|
173
183
|
});
|
|
174
184
|
if (!initialized)
|
|
175
185
|
process.exitCode = 1;
|
package/dist/cli/init.js
CHANGED
|
@@ -11,6 +11,7 @@ import { getCodexAppServerAvailability, isCodexAppServerAvailable } from '../age
|
|
|
11
11
|
import { resolveEcagentConfig } from '../agents/baseagent.js';
|
|
12
12
|
import { defaultProjectsRoot } from '../utils/project-path.js';
|
|
13
13
|
import { WEB_CLI_BIN, WEB_PACKAGE_LATEST } from '../product.js';
|
|
14
|
+
import { autostartInstalled, autostartPlatformLabel, configureAutostart } from '../utils/autostart.js';
|
|
14
15
|
// ==================== Helpers ====================
|
|
15
16
|
function ask(rl, question) {
|
|
16
17
|
return new Promise(resolve => rl.question(question, resolve));
|
|
@@ -66,6 +67,40 @@ function buildDefaults(chosen, available, projectsDefaultPath) {
|
|
|
66
67
|
function writeDefaults(chosen, available, projectsDefaultPath) {
|
|
67
68
|
saveDefaultsSafe(buildDefaults(chosen, available, projectsDefaultPath));
|
|
68
69
|
}
|
|
70
|
+
function hasCompletedInitConfig() {
|
|
71
|
+
const p = resolvePaths();
|
|
72
|
+
const daemon = loadDaemonConfig();
|
|
73
|
+
if (!daemon.aid || !Array.isArray(daemon.owners) || daemon.owners.length === 0)
|
|
74
|
+
return false;
|
|
75
|
+
try {
|
|
76
|
+
const defaults = JSON.parse(fs.readFileSync(p.defaultsConfig, 'utf8'));
|
|
77
|
+
return typeof defaults?.active_baseagent === 'string' && defaults.active_baseagent.trim().length > 0;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function isAutostartOnlyRequest(options) {
|
|
84
|
+
return options?.autoStart !== undefined
|
|
85
|
+
&& !options.baseagent
|
|
86
|
+
&& !options.force
|
|
87
|
+
&& !options.owner
|
|
88
|
+
&& options.projectpath === undefined
|
|
89
|
+
&& options.ecweb === undefined
|
|
90
|
+
&& options.format === undefined;
|
|
91
|
+
}
|
|
92
|
+
function applyExplicitAutostart(enabled, runtimeRoot) {
|
|
93
|
+
const result = configureAutostart(enabled, runtimeRoot);
|
|
94
|
+
if (!result.ok) {
|
|
95
|
+
console.log(`❌ ${autostartPlatformLabel() || '登录自启'}配置失败: ${result.error || '未知错误'}`);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
console.log(enabled
|
|
99
|
+
? `✓ 已启用 ${autostartPlatformLabel() || '登录'}自启`
|
|
100
|
+
: `✓ 已禁用 ${autostartPlatformLabel() || '登录'}自启`);
|
|
101
|
+
}
|
|
102
|
+
return result.ok;
|
|
103
|
+
}
|
|
69
104
|
/** 启动门禁判定:缺控制 AID 且处于交互式终端时,应进 init 向导补全。
|
|
70
105
|
* 非 TTY(restart-monitor/systemd/管道)即使缺 aid 也不进 init(无法交互),由 daemon 侧 warn 兜底。 */
|
|
71
106
|
export function needsControlAidInit(aid, isTty) {
|
|
@@ -128,14 +163,29 @@ export async function cmdInit(options) {
|
|
|
128
163
|
ecweb: options.ecweb,
|
|
129
164
|
force: options.force,
|
|
130
165
|
format: options.format,
|
|
166
|
+
autoStart: options.autoStart,
|
|
131
167
|
});
|
|
132
168
|
return true;
|
|
133
169
|
}
|
|
170
|
+
if (options?.autoStart === true && !autostartPlatformLabel()) {
|
|
171
|
+
console.log('❌ --auto-start 仅支持 Windows 和 macOS 主机');
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
134
174
|
const p = resolvePaths();
|
|
135
175
|
ensureDataDirs();
|
|
176
|
+
// A bound installation may toggle login autostart independently of the
|
|
177
|
+
// Baseagent setup wizard. This is also the path used by public installers.
|
|
178
|
+
if (isAutostartOnlyRequest(options) && hasCompletedInitConfig()) {
|
|
179
|
+
return applyExplicitAutostart(options.autoStart, p.root);
|
|
180
|
+
}
|
|
136
181
|
// ── 1. 单进程互斥 ──
|
|
137
182
|
const aliveMains = scanInstances().mains.filter(m => m.alive);
|
|
138
183
|
if (aliveMains.length > 0) {
|
|
184
|
+
// Explicit autostart flags only change the login task; they do not need
|
|
185
|
+
// to rewrite init configuration or stop an already running daemon.
|
|
186
|
+
if (isAutostartOnlyRequest(options)) {
|
|
187
|
+
return applyExplicitAutostart(options.autoStart, p.root);
|
|
188
|
+
}
|
|
139
189
|
const pids = aliveMains.map(m => m.record.pid).join(', ');
|
|
140
190
|
console.log(`❌ EvolCore 正在运行 (PID: ${pids}),请先执行 ec stop`);
|
|
141
191
|
return false;
|
|
@@ -207,7 +257,11 @@ export async function cmdInit(options) {
|
|
|
207
257
|
await runInteractive();
|
|
208
258
|
}
|
|
209
259
|
// ── 共享 tail(单一出口):提示创建 agent + 生成控制 AID ──
|
|
210
|
-
return initTail({
|
|
260
|
+
return initTail({
|
|
261
|
+
invokedByStart: options?.invokedByStart,
|
|
262
|
+
nonInteractive: options?.nonInteractive,
|
|
263
|
+
autoStart: options?.autoStart,
|
|
264
|
+
});
|
|
211
265
|
// ── 内部函数 ──
|
|
212
266
|
async function runInteractive() {
|
|
213
267
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -318,6 +372,7 @@ export async function initTail(options = {}) {
|
|
|
318
372
|
// 控制 AID:daemon 进程身份。缺失则生成并写回 daemon.json(幂等:已存在则跳过)。
|
|
319
373
|
const daemonConfig = loadDaemonConfig();
|
|
320
374
|
let controlAidReady = !!daemonConfig.aid;
|
|
375
|
+
let autoStartReady = true;
|
|
321
376
|
if (daemonConfig.aid) {
|
|
322
377
|
console.log(`✓ 控制 AID 已存在: ${daemonConfig.aid}`);
|
|
323
378
|
}
|
|
@@ -335,11 +390,12 @@ export async function initTail(options = {}) {
|
|
|
335
390
|
}
|
|
336
391
|
}
|
|
337
392
|
// 交互式询问:使用单一 readline 实例避免 stdin 状态混乱
|
|
338
|
-
if (process.stdin.isTTY) {
|
|
393
|
+
if (!options.nonInteractive && process.stdin.isTTY) {
|
|
339
394
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
340
395
|
try {
|
|
341
396
|
await handleOwnersPrompt(rl);
|
|
342
397
|
await handleEcwebPrompt(rl);
|
|
398
|
+
await handleAutostartPrompt(rl);
|
|
343
399
|
}
|
|
344
400
|
finally {
|
|
345
401
|
try {
|
|
@@ -348,6 +404,38 @@ export async function initTail(options = {}) {
|
|
|
348
404
|
catch { /* ignore */ }
|
|
349
405
|
}
|
|
350
406
|
}
|
|
407
|
+
else if (options.autoStart !== undefined) {
|
|
408
|
+
autoStartReady = applyAutostart(options.autoStart);
|
|
409
|
+
}
|
|
410
|
+
async function handleAutostartPrompt(rl) {
|
|
411
|
+
if (options.autoStart !== undefined) {
|
|
412
|
+
autoStartReady = applyAutostart(options.autoStart);
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
if (!autostartPlatformLabel())
|
|
416
|
+
return;
|
|
417
|
+
if (autostartInstalled()) {
|
|
418
|
+
console.log(`✓ ${autostartPlatformLabel()} 登录自启已启用`);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
const platform = autostartPlatformLabel();
|
|
422
|
+
const answer = (await ask(rl, `\n是否启用 ${platform} 登录自启?[y/N] `)).trim().toLowerCase();
|
|
423
|
+
if (answer === 'y' || answer === 'yes')
|
|
424
|
+
autoStartReady = applyAutostart(true);
|
|
425
|
+
else
|
|
426
|
+
console.log(` 已跳过 ${platform} 登录自启(可日后重新运行 ec init 开启)`);
|
|
427
|
+
}
|
|
428
|
+
function applyAutostart(enabled) {
|
|
429
|
+
const result = configureAutostart(enabled, resolvePaths().root);
|
|
430
|
+
if (!result.ok) {
|
|
431
|
+
console.log(` ❌ ${autostartPlatformLabel() || '登录自启'}配置失败: ${result.error || '未知错误'}`);
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
console.log(enabled
|
|
435
|
+
? ` ✓ 已启用 ${autostartPlatformLabel() || '登录'}自启`
|
|
436
|
+
: ` ✓ 已禁用 ${autostartPlatformLabel() || '登录'}自启`);
|
|
437
|
+
return true;
|
|
438
|
+
}
|
|
351
439
|
async function handleOwnersPrompt(rl) {
|
|
352
440
|
const daemonConfigForOwners = loadDaemonConfig();
|
|
353
441
|
if (daemonConfigForOwners.aid && (!daemonConfigForOwners.owners || daemonConfigForOwners.owners.length === 0)) {
|
|
@@ -427,11 +515,13 @@ export async function initTail(options = {}) {
|
|
|
427
515
|
}
|
|
428
516
|
// ec start 会接着启动 daemon,并在其 ready 后给出可用的 Agent 创建入口。
|
|
429
517
|
if (options.invokedByStart)
|
|
430
|
-
return controlAidReady;
|
|
518
|
+
return controlAidReady && autoStartReady;
|
|
431
519
|
if (!controlAidReady) {
|
|
432
520
|
console.error('\n❌ EvolCore 初始化未完成:控制 AID 未配置。联网后重新运行 ec init。');
|
|
433
521
|
return false;
|
|
434
522
|
}
|
|
523
|
+
if (!autoStartReady)
|
|
524
|
+
return false;
|
|
435
525
|
// 初始化完成总结
|
|
436
526
|
console.log('\n✓ EvolCore 初始化完成');
|
|
437
527
|
const finalCfg = loadDaemonConfig();
|
|
@@ -525,6 +615,9 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
525
615
|
if (format !== undefined && format !== 'json') {
|
|
526
616
|
fail('INVALID_FORMAT', `--format only supports json: ${format}`, EXIT_USAGE, format);
|
|
527
617
|
}
|
|
618
|
+
if (opts.autoStart === true && !autostartPlatformLabel()) {
|
|
619
|
+
fail('AUTOSTART_UNSUPPORTED', '--auto-start is supported only on Windows and macOS hosts', EXIT_USAGE, format);
|
|
620
|
+
}
|
|
528
621
|
// ── 1. owner 校验 ──
|
|
529
622
|
if (!opts.owner) {
|
|
530
623
|
fail('MISSING_OWNER', '--owner is required in non-interactive mode', EXIT_USAGE, format);
|
|
@@ -649,6 +742,12 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
649
742
|
catch (e) {
|
|
650
743
|
fail('IO_ERROR', `failed to write daemon.json: ${e?.message || e}`, EXIT_RUNTIME, format);
|
|
651
744
|
}
|
|
745
|
+
if (opts.autoStart !== undefined) {
|
|
746
|
+
const autostart = configureAutostart(opts.autoStart, p.root);
|
|
747
|
+
if (!autostart.ok) {
|
|
748
|
+
fail('AUTOSTART_CONFIG_FAILED', autostart.error || 'failed to configure login autostart', EXIT_RUNTIME, format);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
652
751
|
// ── 10. 输出 init.result ──
|
|
653
752
|
const result = {
|
|
654
753
|
type: 'init.result',
|
|
@@ -656,7 +755,7 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
656
755
|
controlAid: controlAid,
|
|
657
756
|
ownerAid,
|
|
658
757
|
owners: [ownerAid],
|
|
659
|
-
ecwebEnabled: opts.ecweb === true,
|
|
758
|
+
ecwebEnabled: opts.ecweb === true || existingCfg.ecweb?.enabled === true,
|
|
660
759
|
baseagent: chosenBaseagent,
|
|
661
760
|
projectsDefaultPath: projectsDefaultPath ?? null,
|
|
662
761
|
defaultsPath: p.defaultsConfig,
|
package/dist/cli/model.js
CHANGED
|
@@ -205,7 +205,7 @@ function modelScopeFromSource(source) {
|
|
|
205
205
|
return undefined;
|
|
206
206
|
}
|
|
207
207
|
function resolveModelConfig(sel, baseagent) {
|
|
208
|
-
const effortKey =
|
|
208
|
+
const effortKey = 'effort';
|
|
209
209
|
const model = resolveEffectiveFieldWithSource(`baseagents.${baseagent}.model`, sel, { cache: true });
|
|
210
210
|
const effort = resolveEffectiveFieldWithSource(`baseagents.${baseagent}.${effortKey}`, sel, { cache: true });
|
|
211
211
|
const modelDecision = sel.role
|
|
@@ -448,12 +448,12 @@ async function cmdUse(args, formatJson) {
|
|
|
448
448
|
const effortVal = effort === 'auto' ? null : (effort ?? undefined);
|
|
449
449
|
if (isManagedTargetedWriteEnv(args)) {
|
|
450
450
|
if (effortVal !== undefined) {
|
|
451
|
-
const effortKey =
|
|
451
|
+
const effortKey = 'effort';
|
|
452
452
|
preflightManagedFieldOverride(sel, role, `baseagents.${ba}.${effortKey}`, effortVal, formatJson);
|
|
453
453
|
}
|
|
454
454
|
await setManagedModelField(sel, `baseagents.${ba}.model`, modelId, formatJson);
|
|
455
455
|
if (effortVal !== undefined) {
|
|
456
|
-
const effortKey =
|
|
456
|
+
const effortKey = 'effort';
|
|
457
457
|
await setManagedModelField(sel, `baseagents.${ba}.${effortKey}`, effortVal, formatJson);
|
|
458
458
|
}
|
|
459
459
|
describeWrite(scope, sel, modelId, effort ?? null, formatJson);
|
|
@@ -490,7 +490,7 @@ async function cmdEffort(args, formatJson) {
|
|
|
490
490
|
const ba = activeBaseagent(sel.self);
|
|
491
491
|
const val = level === 'auto' ? null : level;
|
|
492
492
|
if (isManagedTargetedWriteEnv(args)) {
|
|
493
|
-
const effortKey =
|
|
493
|
+
const effortKey = 'effort';
|
|
494
494
|
preflightManagedFieldOverride(sel, explicitOrDerivedRole(args, sel), `baseagents.${ba}.${effortKey}`, val, formatJson);
|
|
495
495
|
await setManagedModelField(sel, `baseagents.${ba}.${effortKey}`, val, formatJson);
|
|
496
496
|
describeWrite(scope, sel, null, level, formatJson);
|
|
@@ -520,7 +520,7 @@ async function cmdReset(args, formatJson) {
|
|
|
520
520
|
const scope = determineWriteScope(sel, formatJson);
|
|
521
521
|
const ba = activeBaseagent(sel.self);
|
|
522
522
|
if (isManagedTargetedWriteEnv(args)) {
|
|
523
|
-
const effortKey =
|
|
523
|
+
const effortKey = 'effort';
|
|
524
524
|
const role = explicitOrDerivedRole(args, sel);
|
|
525
525
|
preflightManagedFieldOverride(sel, role, `baseagents.${ba}.model`, null, formatJson);
|
|
526
526
|
preflightManagedFieldOverride(sel, role, `baseagents.${ba}.${effortKey}`, null, formatJson);
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { kitsRoleTemplatesDir } from '../paths.js';
|
|
3
3
|
import { createErrorCapturingReader, fileCache } from '../core/daemon-file-cache.js';
|
|
4
|
-
import { validateRoleConfig } from './role-schema.js';
|
|
4
|
+
import { normalizeRoleEffortCompat, validateRoleConfig } from './role-schema.js';
|
|
5
5
|
import { expectedRoleRank } from './role-ranks.js';
|
|
6
6
|
export const BUILTIN_ROLE_IDS = ['owner', 'admin', 'member', 'visitor'];
|
|
7
7
|
export function validateBuiltinRoleTemplateDefinition(roleId, raw) {
|
|
8
|
-
const
|
|
8
|
+
const normalizedRaw = normalizeRoleEffortCompat(raw);
|
|
9
|
+
const issues = validateRoleConfig(normalizedRaw);
|
|
9
10
|
if (issues.length) {
|
|
10
11
|
return {
|
|
11
12
|
definition: null,
|
|
12
13
|
error: `built-in role template failed validation: ${issues.map(issue => `${issue.field} ${issue.message}`).join('; ')}`,
|
|
13
14
|
};
|
|
14
15
|
}
|
|
15
|
-
const { $schema_version: _schemaVersion, ...definition } =
|
|
16
|
+
const { $schema_version: _schemaVersion, ...definition } = normalizedRaw;
|
|
16
17
|
if (BUILTIN_ROLE_IDS.includes(roleId)) {
|
|
17
18
|
const expectedRank = expectedRoleRank(roleId);
|
|
18
19
|
if (definition.rank !== expectedRank) {
|
|
@@ -75,7 +75,7 @@ export function resolveConfigFieldRule(fieldPath) {
|
|
|
75
75
|
const [, baseagent, leaf] = parts;
|
|
76
76
|
if (!SUPPORTED_BASEAGENTS.has(baseagent))
|
|
77
77
|
return { class: 'unknown' };
|
|
78
|
-
const permissionKey = `baseagents.${baseagent}.${leaf}`;
|
|
78
|
+
const permissionKey = `baseagents.${baseagent}.${leaf === 'reasoning' ? 'effort' : leaf}`;
|
|
79
79
|
if (leaf === 'model' && parts.length === 3)
|
|
80
80
|
return scalar(permissionKey, 'string');
|
|
81
81
|
if ((leaf === 'effort' || leaf === 'reasoning') && parts.length === 3)
|
|
@@ -178,7 +178,11 @@ export function resolveRoleFieldPermission(permissions, fieldPath) {
|
|
|
178
178
|
const rule = resolveConfigFieldRule(fieldPath);
|
|
179
179
|
if (!rule.rolePermissionKey)
|
|
180
180
|
return undefined;
|
|
181
|
-
return permissions[fieldPath]
|
|
181
|
+
return permissions[fieldPath]
|
|
182
|
+
?? permissions[rule.rolePermissionKey]
|
|
183
|
+
?? (rule.rolePermissionKey === 'baseagents.codex.effort'
|
|
184
|
+
? permissions['baseagents.codex.reasoning']
|
|
185
|
+
: undefined);
|
|
182
186
|
}
|
|
183
187
|
/**
|
|
184
188
|
* Map relation-scoped config fields back to their public command capability.
|
|
@@ -505,10 +505,40 @@ export function read(target, sel, opts = {}) {
|
|
|
505
505
|
: target === ConfigTarget.Relation
|
|
506
506
|
? foldLegacyProactiveBlock(migrated)
|
|
507
507
|
: migrated;
|
|
508
|
+
// Agent read compatibility may move the legacy top-level `agents` block to
|
|
509
|
+
// `baseagents`, so canonicalize effort after that structural migration.
|
|
510
|
+
const canonicalized = normalizeBaseagentEffortCompat(normalized);
|
|
508
511
|
if (!opts.expand)
|
|
509
|
-
return
|
|
512
|
+
return canonicalized;
|
|
510
513
|
const resolver = buildEnvResolver(envScopeFor(sel));
|
|
511
|
-
return expandVars(
|
|
514
|
+
return expandVars(canonicalized, resolver);
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Canonicalize the legacy Codex `reasoning` config key to the public `effort`
|
|
518
|
+
* key. The runner may still accept `reasoning` as an input alias, but all
|
|
519
|
+
* config scopes resolve and persist the same `effort` field.
|
|
520
|
+
*/
|
|
521
|
+
function normalizeBaseagentEffortCompat(value) {
|
|
522
|
+
const rawBaseagents = value?.baseagents;
|
|
523
|
+
if (!rawBaseagents || typeof rawBaseagents !== 'object' || Array.isArray(rawBaseagents))
|
|
524
|
+
return value;
|
|
525
|
+
const baseagents = { ...rawBaseagents };
|
|
526
|
+
let changed = false;
|
|
527
|
+
for (const [name, rawBlock] of Object.entries(baseagents)) {
|
|
528
|
+
if (!rawBlock || typeof rawBlock !== 'object' || Array.isArray(rawBlock))
|
|
529
|
+
continue;
|
|
530
|
+
const block = { ...rawBlock };
|
|
531
|
+
if (Object.prototype.hasOwnProperty.call(block, 'reasoning')) {
|
|
532
|
+
if (block.effort === undefined)
|
|
533
|
+
block.effort = block.reasoning;
|
|
534
|
+
delete block.reasoning;
|
|
535
|
+
baseagents[name] = block;
|
|
536
|
+
changed = true;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
if (!changed)
|
|
540
|
+
return value;
|
|
541
|
+
return { ...value, baseagents };
|
|
512
542
|
}
|
|
513
543
|
function normalizeAgentConfigForRead(value, aid) {
|
|
514
544
|
const config = foldLegacyProactiveBlock(normalizeAgentLifecycle(value));
|
|
@@ -549,7 +579,7 @@ function groupFor(target, sel) {
|
|
|
549
579
|
return 'config';
|
|
550
580
|
}
|
|
551
581
|
function normalizeAgentConfigForWrite(value) {
|
|
552
|
-
const mutable = { ...value };
|
|
582
|
+
const mutable = normalizeBaseagentEffortCompat({ ...value });
|
|
553
583
|
normalizeShowActivitiesCompat(mutable);
|
|
554
584
|
// AID 格式校验
|
|
555
585
|
if (mutable.aid && !isValidAid(mutable.aid)) {
|
|
@@ -587,7 +617,7 @@ function normalizeProcessConfigForWrite(value) {
|
|
|
587
617
|
}
|
|
588
618
|
}
|
|
589
619
|
function normalizeRelationConfigForWrite(value) {
|
|
590
|
-
const mutable = { ...value };
|
|
620
|
+
const mutable = normalizeBaseagentEffortCompat({ ...value });
|
|
591
621
|
normalizeShowActivitiesCompat(mutable);
|
|
592
622
|
return mutable;
|
|
593
623
|
}
|
|
@@ -653,14 +683,15 @@ export function write(target, value, sel, opts = {}) {
|
|
|
653
683
|
: loadSchema(TARGET_SCHEMA[target]);
|
|
654
684
|
const withVer = ensureSchemaVersion(value, schema.version);
|
|
655
685
|
const migrated = withVer;
|
|
686
|
+
const canonicalized = normalizeBaseagentEffortCompat(migrated);
|
|
656
687
|
// Agent config 写入规范化(aid 校验、projects 字段清理)
|
|
657
688
|
const normalized = target === ConfigTarget.Agent
|
|
658
|
-
? normalizeAgentConfigForWrite(
|
|
689
|
+
? normalizeAgentConfigForWrite(canonicalized)
|
|
659
690
|
: target === ConfigTarget.Relation
|
|
660
|
-
? normalizeRelationConfigForWrite(
|
|
691
|
+
? normalizeRelationConfigForWrite(canonicalized)
|
|
661
692
|
: target === ConfigTarget.Process
|
|
662
|
-
? normalizeProcessConfigForWrite(
|
|
663
|
-
:
|
|
693
|
+
? normalizeProcessConfigForWrite(canonicalized)
|
|
694
|
+
: canonicalized;
|
|
664
695
|
// 1. Schema 校验
|
|
665
696
|
if (!opts.skipValidate) {
|
|
666
697
|
validateOrThrow(schema, normalized, target);
|
|
@@ -870,9 +901,15 @@ function validateOrThrow(schema, value, target) {
|
|
|
870
901
|
function validateProcessOnlyFields(target, value) {
|
|
871
902
|
if (target === ConfigTarget.Process || !value || typeof value !== 'object')
|
|
872
903
|
return [];
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
904
|
+
const errors = [];
|
|
905
|
+
if (Object.prototype.hasOwnProperty.call(value, 'debug')) {
|
|
906
|
+
errors.push('/debug is only allowed in process config');
|
|
907
|
+
}
|
|
908
|
+
const aun = value.aun;
|
|
909
|
+
if (aun && typeof aun === 'object' && Object.prototype.hasOwnProperty.call(aun, 'defaultEncrypt')) {
|
|
910
|
+
errors.push('/aun/defaultEncrypt is only allowed in process config');
|
|
911
|
+
}
|
|
912
|
+
return errors;
|
|
876
913
|
}
|
|
877
914
|
function validateProcessAidDomain(target, value) {
|
|
878
915
|
if (target !== ConfigTarget.Process || !value || typeof value !== 'object')
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import { loadSchema } from './schema-registry.js';
|
|
2
|
+
const LEGACY_CODEX_EFFORT_FIELD = 'baseagents.codex.reasoning';
|
|
3
|
+
const CODEX_EFFORT_FIELD = 'baseagents.codex.effort';
|
|
4
|
+
/** Convert the legacy flattened Codex role permission key to `effort`. */
|
|
5
|
+
export function normalizeRoleEffortCompat(value) {
|
|
6
|
+
if (!isRecord(value) || !isRecord(value.permissions)
|
|
7
|
+
|| !Object.hasOwn(value.permissions, LEGACY_CODEX_EFFORT_FIELD))
|
|
8
|
+
return value;
|
|
9
|
+
const permissions = { ...value.permissions };
|
|
10
|
+
if (!Object.hasOwn(permissions, CODEX_EFFORT_FIELD)) {
|
|
11
|
+
permissions[CODEX_EFFORT_FIELD] = permissions[LEGACY_CODEX_EFFORT_FIELD];
|
|
12
|
+
}
|
|
13
|
+
delete permissions[LEGACY_CODEX_EFFORT_FIELD];
|
|
14
|
+
return { ...value, permissions };
|
|
15
|
+
}
|
|
2
16
|
export function rolePermissionFields() {
|
|
3
17
|
const raw = loadSchema('role-config').raw['x-permission-fields'];
|
|
4
18
|
if (!Array.isArray(raw))
|
|
@@ -41,9 +55,10 @@ export function rolePermissionFieldPatterns(field) {
|
|
|
41
55
|
}
|
|
42
56
|
/** Shared RoleService/Menu validation backed by the published role schema. */
|
|
43
57
|
export function validateRoleConfig(value) {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
:
|
|
58
|
+
const compatible = normalizeRoleEffortCompat(value);
|
|
59
|
+
const normalized = isRecord(compatible) && !Object.hasOwn(compatible, '$schema_version')
|
|
60
|
+
? { ...compatible, $schema_version: 1 }
|
|
61
|
+
: compatible;
|
|
47
62
|
const schema = loadSchema('role-config');
|
|
48
63
|
if (!schema.validate(normalized)) {
|
|
49
64
|
return (schema.validate.errors ?? []).map(error => ({
|
|
@@ -6,7 +6,7 @@ import { loadSchema } from './schema-registry.js';
|
|
|
6
6
|
import { clearRoleStoreCache, getStoredRoleRegistry, isRoleName, readRoleStore, roleRegistryExists, } from './role-store.js';
|
|
7
7
|
import { expectedRoleRank, isManagementRole } from './builtin-roles.js';
|
|
8
8
|
import { readBuiltinRoleTemplate } from './builtin-role-templates.js';
|
|
9
|
-
import { validateRoleConfig } from './role-schema.js';
|
|
9
|
+
import { normalizeRoleEffortCompat, validateRoleConfig } from './role-schema.js';
|
|
10
10
|
export class RoleServiceError extends Error {
|
|
11
11
|
code;
|
|
12
12
|
data;
|
|
@@ -43,7 +43,7 @@ export function writeRoleRegistry(selfAid, value) {
|
|
|
43
43
|
export function writeRoleDefinition(selfAid, roleId, value) {
|
|
44
44
|
if (!isRoleName(roleId))
|
|
45
45
|
throw new RoleServiceError('INVALID_ROLE_ID', `Invalid role id: ${roleId}`);
|
|
46
|
-
const normalized = { ...value, rank: expectedRoleRank(roleId), $schema_version: 1 };
|
|
46
|
+
const normalized = normalizeRoleEffortCompat({ ...value, rank: expectedRoleRank(roleId), $schema_version: 1 });
|
|
47
47
|
validateRoleDefinition(normalized);
|
|
48
48
|
const registry = readRoleRegistry(selfAid);
|
|
49
49
|
if (!registry.roles.includes(roleId)) {
|
|
@@ -93,7 +93,7 @@ export function listRoleDiagnostics(selfAid) {
|
|
|
93
93
|
return readRoleStore(selfAid).diagnostics;
|
|
94
94
|
}
|
|
95
95
|
function writeRoleDefinitionFile(selfAid, roleId, value) {
|
|
96
|
-
const normalized = { ...value, rank: expectedRoleRank(roleId), $schema_version: 1 };
|
|
96
|
+
const normalized = normalizeRoleEffortCompat({ ...value, rank: expectedRoleRank(roleId), $schema_version: 1 });
|
|
97
97
|
validateRoleDefinition(normalized);
|
|
98
98
|
const file = agentRoleConfig(selfAid, roleId);
|
|
99
99
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
@@ -5,7 +5,7 @@ import { agentRoleConfig, agentRolesDir, agentRolesIndex, kitsRoleTemplatesDir,
|
|
|
5
5
|
import { applyManagementRoleCeiling, expectedRoleRank, getManagementRoleDefinition } from './builtin-roles.js';
|
|
6
6
|
import { readBuiltinRoleTemplate } from './builtin-role-templates.js';
|
|
7
7
|
import { loadSchema } from './schema-registry.js';
|
|
8
|
-
import { validateRoleConfig } from './role-schema.js';
|
|
8
|
+
import { normalizeRoleEffortCompat, validateRoleConfig } from './role-schema.js';
|
|
9
9
|
const ROLE_NAME_RE = /^[a-z0-9_-]+$/;
|
|
10
10
|
const BUILTIN_ROLES = ['owner', 'admin', 'member', 'visitor'];
|
|
11
11
|
const cache = new Map();
|
|
@@ -154,9 +154,10 @@ function readDefinition(selfAid, roleId, diagnostics) {
|
|
|
154
154
|
}
|
|
155
155
|
if (raw === null)
|
|
156
156
|
continue;
|
|
157
|
-
const
|
|
157
|
+
const normalizedRaw = normalizeRoleEffortCompat(raw);
|
|
158
|
+
const issues = validateRoleConfig(normalizedRaw);
|
|
158
159
|
if (issues.length === 0) {
|
|
159
|
-
const { $schema_version: _schemaVersion, ...definition } =
|
|
160
|
+
const { $schema_version: _schemaVersion, ...definition } = normalizedRaw;
|
|
160
161
|
const expectedRank = expectedRoleRank(roleId);
|
|
161
162
|
if (definition.rank !== undefined && definition.rank !== expectedRank) {
|
|
162
163
|
diagnostics.push({
|
package/dist/config-store.js
CHANGED
|
@@ -69,6 +69,10 @@ function validateDaemonConfig(value, validateAidDomain) {
|
|
|
69
69
|
if (menuTokenRequired !== undefined && typeof menuTokenRequired !== 'boolean') {
|
|
70
70
|
throw new Error('daemon.json.aun.menuTokenRequired must be a boolean');
|
|
71
71
|
}
|
|
72
|
+
const defaultEncrypt = value.aun?.defaultEncrypt;
|
|
73
|
+
if (defaultEncrypt !== undefined && typeof defaultEncrypt !== 'boolean') {
|
|
74
|
+
throw new Error('daemon.json.aun.defaultEncrypt must be a boolean');
|
|
75
|
+
}
|
|
72
76
|
if (validateAidDomain && value.aun?.defaultAidDomain !== undefined) {
|
|
73
77
|
const defaultAidDomain = normalizeAidDomain(value.aun.defaultAidDomain, 'daemon.json.aun.defaultAidDomain');
|
|
74
78
|
return { ...value, aun: { ...value.aun, defaultAidDomain } };
|
|
@@ -673,7 +673,9 @@ function parseLegacyChannelType(peerKey) {
|
|
|
673
673
|
}
|
|
674
674
|
function checkFieldOverride(ctx, field) {
|
|
675
675
|
const roleDef = getRoleDefinition(ctx.role, ctx.selfAid);
|
|
676
|
-
const fieldPermission = roleDef
|
|
676
|
+
const fieldPermission = roleDef
|
|
677
|
+
? resolveRoleFieldPermission(roleDef.permissions || {}, field)
|
|
678
|
+
: undefined;
|
|
677
679
|
if (!fieldPermission) {
|
|
678
680
|
return { ok: false, reason: `Role ${ctx.role} has no field permission for ${field}` };
|
|
679
681
|
}
|
|
@@ -74,7 +74,6 @@ export class BootstrapService {
|
|
|
74
74
|
agentName: aid,
|
|
75
75
|
}), { kind: 'result.text', text, isFinal: true });
|
|
76
76
|
this.eventBus.publish({ type: 'agent:bootstrap-started', aid, channel: channelType || ctx.channelKey, timestamp: Date.now() });
|
|
77
|
-
await this.sendAunBindingCredentialIfSupported(ctx.adapter, recipientId, agentName, baseagent);
|
|
78
77
|
logger.info(`[Bootstrap] Started for ${aid} via ${ctx.channelKey} (${ctx.source})`);
|
|
79
78
|
return true;
|
|
80
79
|
}
|
|
@@ -154,15 +153,4 @@ export class BootstrapService {
|
|
|
154
153
|
logger.warn(`[Bootstrap] Failed to publish agent.md for ${aid}: ${e instanceof Error ? e.message : String(e)}`);
|
|
155
154
|
}
|
|
156
155
|
}
|
|
157
|
-
async sendAunBindingCredentialIfSupported(adapter, owner, name, baseagent) {
|
|
158
|
-
const sendBinding = adapter._sendBindingCredential;
|
|
159
|
-
if (typeof sendBinding !== 'function')
|
|
160
|
-
return;
|
|
161
|
-
try {
|
|
162
|
-
await sendBinding(owner, name, baseagent);
|
|
163
|
-
}
|
|
164
|
-
catch (e) {
|
|
165
|
-
logger.warn(`[Bootstrap] Binding credential failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
156
|
}
|