evolcore 0.0.38 → 0.0.39
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 +15 -0
- package/dist/agents/codex-runner.js +3 -3
- package/dist/aun/aid/agentmd.js +21 -0
- package/dist/aun/aid/client.js +1 -1
- package/dist/aun/aid/ownership-operation.js +34 -9
- package/dist/cli/agent-create.js +7 -2
- package/dist/cli/agent.js +30 -37
- package/dist/cli/aid-bind-command.js +12 -1
- package/dist/cli/aun-commands.js +31 -23
- package/dist/cli/config.js +15 -18
- package/dist/cli/contact.js +9 -12
- package/dist/cli/ctl-command.js +3 -3
- package/dist/cli/diag.js +7 -3
- package/dist/cli/fs-command.js +5 -4
- package/dist/cli/handoff-command.js +11 -11
- package/dist/cli/help.js +18 -0
- package/dist/cli/init-channel.js +2 -1
- package/dist/cli/memory-command.js +14 -13
- package/dist/cli/model.js +5 -4
- package/dist/cli/queue-command.js +3 -3
- package/dist/cli/response.js +5 -4
- package/dist/cli/skill-command.js +13 -13
- package/dist/cli/task-command.js +3 -3
- package/dist/cli/thread-command.js +5 -3
- package/dist/cli/trigger-command.js +3 -3
- package/dist/cli/version.js +6 -2
- package/dist/core/auth/operation-catalog.js +1 -1
- package/dist/core/bootstrap-service.js +20 -12
- package/dist/core/command/cli-intent-parser.js +5 -2
- package/dist/core/command/command-handler.js +13 -4
- package/dist/core/command/menu-handler.js +2 -2
- package/dist/core/ownership/owner-resolver.js +121 -2
- package/dist/core/permission/protected-paths.js +51 -0
- package/dist/utils/welcome.js +18 -24
- package/kits/docs/evolcore/aid.md +33 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@
|
|
|
5
5
|
|
|
6
6
|
## Unreleased
|
|
7
7
|
|
|
8
|
+
## 0.0.39 (2026-10-24)
|
|
9
|
+
|
|
10
|
+
### Ownership 与 Agent 初始化
|
|
11
|
+
|
|
12
|
+
- 支持通过 `ec aid bind status` 查看经 SDK 验证的 Ownership 邀约,并按具体操作 ID 接受或拒绝。
|
|
13
|
+
- 按绑定任务上下文校验审批结果,避免处理不相关或已失效的邀约。
|
|
14
|
+
- Bootstrap 会验证本地 `agent.md`;已验签的名片不再重复发布,无效或未签名内容会阻止不安全的重发。
|
|
15
|
+
- 更新 AUN Owner 欢迎文案,更清晰地介绍 Agent 可提供的帮助与个性化设置。
|
|
16
|
+
|
|
17
|
+
### 权限与兼容性
|
|
18
|
+
|
|
19
|
+
- 优化 Codex 在 Linux 上的文件权限规则,减少被父目录拒绝规则覆盖的冗余子规则,同时保留必要的读写例外。
|
|
20
|
+
- 将 AUN SDK 最低兼容版本提升至 `0.5.23`,以支持 Ownership 邀约审批。
|
|
21
|
+
- 改进 daemon IPC 连接失败诊断,相关命令现在会保留具体的连接错误信息。
|
|
22
|
+
|
|
8
23
|
## 0.0.38 (2026-10-24)
|
|
9
24
|
|
|
10
25
|
### npm 升级稳定性
|
|
@@ -6,7 +6,7 @@ import { requestDangerousCommandPermission } from '../core/permission/approval-g
|
|
|
6
6
|
import { checkReadonly, checkDangerousCommand, evaluateToolPreflight } from '../core/permission/tool-policy.js';
|
|
7
7
|
import { isShellToolName } from '../core/permission/tool-canonical.js';
|
|
8
8
|
import { normalizeExecutionPermissionMode, normalizePermissionMode, resolvePhaseOneExecutionSandbox } from '../core/permission/mode.js';
|
|
9
|
-
import { assertWindowsCodexFilesystemRuleBudget, buildCodexProtectedFilesystemRules, getExistingRelationAttachmentDirs, isSameOrDescendant, resolveProtectedCandidate, } from '../core/permission/protected-paths.js';
|
|
9
|
+
import { assertWindowsCodexFilesystemRuleBudget, buildCodexProtectedFilesystemRules, compactCodexLinuxFilesystemRules, getExistingRelationAttachmentDirs, isSameOrDescendant, resolveProtectedCandidate, } from '../core/permission/protected-paths.js';
|
|
10
10
|
import { CODEX_THREAD_ACTIVE_WRITER, CodexAppServerClient, } from './codex/app-server-client.js';
|
|
11
11
|
import { resolveOpenaiConfig, resolveCodexCliPath, resolveCodexPowerShellShimPath, } from './baseagent.js';
|
|
12
12
|
import { logger } from '../utils/logger.js';
|
|
@@ -1428,7 +1428,7 @@ export class CodexRunner {
|
|
|
1428
1428
|
onlyOtherAgents: true,
|
|
1429
1429
|
}))
|
|
1430
1430
|
relationAttachmentDenies[directory] = 'deny';
|
|
1431
|
-
const filesystem = {
|
|
1431
|
+
const filesystem = compactCodexLinuxFilesystemRules({
|
|
1432
1432
|
...buildCodexProtectedFilesystemRules(resolveRoot(), {
|
|
1433
1433
|
selfAid: this.resolvedConfig.agentAid,
|
|
1434
1434
|
denyLClassRead: mode === 'readonly',
|
|
@@ -1455,7 +1455,7 @@ export class CodexRunner {
|
|
|
1455
1455
|
[path.join(managedTempDir, 'locks')]: 'write',
|
|
1456
1456
|
[path.join(managedTempDir, 'locks') + '/**']: 'write',
|
|
1457
1457
|
} : {}),
|
|
1458
|
-
};
|
|
1458
|
+
});
|
|
1459
1459
|
// Codex resolves this complete profile before serializing the Windows
|
|
1460
1460
|
// helper payload. Check after all runner-owned additions, not merely the
|
|
1461
1461
|
// protected-path base projection, so Git and managed-temp rules cannot
|
package/dist/aun/aid/agentmd.js
CHANGED
|
@@ -538,6 +538,27 @@ function verifyLocal(store, aid, content) {
|
|
|
538
538
|
return { status: 'invalid', reason: `certificate not available: ${String(e?.message || e).slice(0, 100)}` };
|
|
539
539
|
}
|
|
540
540
|
}
|
|
541
|
+
/** Verify a locally stored agent.md without contacting the AUN gateway. */
|
|
542
|
+
export async function verifyLocalAgentMd(aid, opts = {}) {
|
|
543
|
+
const aunPath = resolveAgentMdAunPath(opts);
|
|
544
|
+
const localPath = agentMdPath(aid, aunPath);
|
|
545
|
+
if (!fs.existsSync(localPath))
|
|
546
|
+
return { status: 'missing' };
|
|
547
|
+
const store = opts.store ?? await getAidStore({ slotId: SLOT.cli, aunPath });
|
|
548
|
+
const ownStore = !opts.store;
|
|
549
|
+
try {
|
|
550
|
+
const content = fs.readFileSync(localPath, 'utf-8');
|
|
551
|
+
const result = verifyLocal(store, aid, content);
|
|
552
|
+
return { status: result.status, ...(result.reason ? { reason: result.reason } : {}) };
|
|
553
|
+
}
|
|
554
|
+
finally {
|
|
555
|
+
if (ownStore)
|
|
556
|
+
try {
|
|
557
|
+
store.close();
|
|
558
|
+
}
|
|
559
|
+
catch { /* ignore */ }
|
|
560
|
+
}
|
|
561
|
+
}
|
|
541
562
|
export async function agentmdGet(aid, opts) {
|
|
542
563
|
const aunPath = resolveAgentMdAunPath(opts);
|
|
543
564
|
const store = opts?.store ?? await getAidStore({ slotId: SLOT.cli, aunPath });
|
package/dist/aun/aid/client.js
CHANGED
|
@@ -39,7 +39,7 @@ export function suppressSdkLogs() {
|
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
// ==================== SDK package ====================
|
|
42
|
-
export const MIN_AUN_CORE_SDK = [0, 5,
|
|
42
|
+
export const MIN_AUN_CORE_SDK = [0, 5, 23];
|
|
43
43
|
export const AUN_CORE_SDK_PKG = '@agentunion/fastaun';
|
|
44
44
|
function compareVersion(a, min) {
|
|
45
45
|
const parts = a.split('.').map(n => parseInt(n, 10));
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { isValidAid } from './validation.js';
|
|
2
2
|
import { ownerResolver, OwnershipError } from '../../core/ownership/owner-resolver.js';
|
|
3
3
|
import { logger } from '../../utils/logger.js';
|
|
4
|
+
import { MAIN_CLI_BIN } from '../../product.js';
|
|
5
|
+
const OWNERSHIP_OPERATION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
4
6
|
export function ownershipFailure(error) {
|
|
5
7
|
const details = error && typeof error === 'object' ? error : {};
|
|
6
8
|
return {
|
|
@@ -14,22 +16,42 @@ export function ownershipFailure(error) {
|
|
|
14
16
|
export function parseOwnershipCommand(argv) {
|
|
15
17
|
const args = argv[0] === 'aid' ? argv.slice(1) : [...argv];
|
|
16
18
|
if (args[0] !== 'bind' || !args[1]) {
|
|
17
|
-
throw new OwnershipError('INVALID_ARGUMENT',
|
|
19
|
+
throw new OwnershipError('INVALID_ARGUMENT', `Use ${MAIN_CLI_BIN} aid bind <ownerAid>, status, accept, or reject`);
|
|
18
20
|
}
|
|
19
|
-
const action =
|
|
21
|
+
const action = ['status', 'accept', 'reject'].includes(args[1]) ? args[1] : 'bind';
|
|
20
22
|
if (action === 'bind' && !isValidAid(args[1]))
|
|
21
23
|
throw new OwnershipError('INVALID_AID', 'A valid owner AID is required');
|
|
24
|
+
if ((action === 'accept' || action === 'reject') && !OWNERSHIP_OPERATION_ID.test(args[2] ?? '')) {
|
|
25
|
+
throw new OwnershipError('INVALID_OPERATION', 'A valid ownership operation ID is required');
|
|
26
|
+
}
|
|
22
27
|
let subjectAid;
|
|
28
|
+
let reason;
|
|
23
29
|
let formatSeen = false;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
const positionalEnd = action === 'bind' || action === 'status' ? 2 : 3;
|
|
31
|
+
for (let index = positionalEnd; index < args.length; index += 2) {
|
|
32
|
+
const flag = args[index];
|
|
33
|
+
const value = args[index + 1];
|
|
34
|
+
if (flag === '--subject' && !subjectAid && isValidAid(value ?? '')) {
|
|
35
|
+
subjectAid = value;
|
|
36
|
+
}
|
|
37
|
+
else if (flag === '--format' && value === 'json' && !formatSeen) {
|
|
28
38
|
formatSeen = true;
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
}
|
|
40
|
+
else if (flag === '--reason' && action === 'reject' && reason === undefined
|
|
41
|
+
&& value !== undefined && !value.startsWith('--')) {
|
|
42
|
+
reason = value;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
throw new OwnershipError('INVALID_ARGUMENT', 'Supported options are --subject <subjectAid>, --reason <text>, and --format json');
|
|
46
|
+
}
|
|
31
47
|
}
|
|
32
|
-
|
|
48
|
+
if (action === 'status')
|
|
49
|
+
return { action, subjectAid };
|
|
50
|
+
if (action === 'accept')
|
|
51
|
+
return { action, operationId: args[2], subjectAid };
|
|
52
|
+
if (action === 'reject')
|
|
53
|
+
return { action, operationId: args[2], ...(reason !== undefined ? { reason } : {}), subjectAid };
|
|
54
|
+
return { action, subjectAid, ownerAid: args[1] };
|
|
33
55
|
}
|
|
34
56
|
export async function executeOwnershipCommand(command, defaultSubjectAid) {
|
|
35
57
|
const subjectAid = command.subjectAid ?? defaultSubjectAid;
|
|
@@ -39,6 +61,9 @@ export async function executeOwnershipCommand(command, defaultSubjectAid) {
|
|
|
39
61
|
ownerResolver.assertLocalSubject(subjectAid);
|
|
40
62
|
return ownerResolver.refresh(subjectAid);
|
|
41
63
|
}
|
|
64
|
+
if (command.action === 'accept' || command.action === 'reject') {
|
|
65
|
+
return ownerResolver.decide(subjectAid, command.operationId, command.action, command.action === 'reject' ? command.reason : undefined);
|
|
66
|
+
}
|
|
42
67
|
logger.info(`[ownership] bind requested subject=${subjectAid} owner=${command.ownerAid}`);
|
|
43
68
|
try {
|
|
44
69
|
ownerResolver.assertLocalSubject(subjectAid);
|
package/dist/cli/agent-create.js
CHANGED
|
@@ -6,6 +6,7 @@ import { parse } from 'yaml';
|
|
|
6
6
|
import { resolvePaths, aunPath as defaultAunPath, agentConfig, agentDataDir, agentPersonalDir, aidLocalDir, agentMdPath } from '../paths.js';
|
|
7
7
|
import { loadDefaults, loadAgent, saveAgent, ensureAgentDirSkeleton } from '../config-store.js';
|
|
8
8
|
import { ConfigTarget, write as cfgWrite, ensureFile as cfgEnsure, read as cfgRead } from '../config/config-manager.js';
|
|
9
|
+
import { daemonUnavailableMessage, queryDaemon } from './help.js';
|
|
9
10
|
import { ipcQuery } from '../ipc.js';
|
|
10
11
|
import { CONFIG_SCHEMA_VERSION } from '../types.js';
|
|
11
12
|
import { ensureInitialRoleRegistry } from '../config/role-service.js';
|
|
@@ -1220,9 +1221,13 @@ export async function runInitializationCommand(args) {
|
|
|
1220
1221
|
return initializationCommandResult(result);
|
|
1221
1222
|
}
|
|
1222
1223
|
const request = async (poll) => {
|
|
1223
|
-
|
|
1224
|
+
const { response, transportError } = await queryDaemon(resolvePaths().socket, {
|
|
1224
1225
|
type: 'evolagent.initialize', argv, poll,
|
|
1225
|
-
}, 10_000)
|
|
1226
|
+
}, 10_000);
|
|
1227
|
+
return response ?? {
|
|
1228
|
+
ok: false, code: 'DAEMON_UNAVAILABLE',
|
|
1229
|
+
error: daemonUnavailableMessage(transportError, 'Initialization requires a running daemon'),
|
|
1230
|
+
};
|
|
1226
1231
|
};
|
|
1227
1232
|
let result = await request(false);
|
|
1228
1233
|
if (parsed.dryRun)
|
package/dist/cli/agent.js
CHANGED
|
@@ -8,6 +8,7 @@ import { initConfigManager } from '../config/config-manager.js';
|
|
|
8
8
|
import { resolveConfigCommand } from '../config/resolved-config-op.js';
|
|
9
9
|
import { executeResolvedConfigCommandAsync } from '../config/config-operation-service.js';
|
|
10
10
|
import { ipcQuery, IpcTransportError } from '../ipc.js';
|
|
11
|
+
import { daemonUnavailableMessage, queryDaemon } from './help.js';
|
|
11
12
|
import { CONFIG_SCHEMA_VERSION } from '../types.js';
|
|
12
13
|
import { ensureInitialRoleRegistry } from '../config/role-service.js';
|
|
13
14
|
import { agentProjectRootFromDefaults, deriveAgentProjectPath } from '../utils/project-path.js';
|
|
@@ -30,22 +31,20 @@ export async function runManagedAgentOperation(argv, timeoutMs = 60_000) {
|
|
|
30
31
|
if (!delegationToken) {
|
|
31
32
|
return { ok: false, code: 'DELEGATION_REQUIRED', error: `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task` };
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return { ok: false, code: 'DAEMON_UNAVAILABLE', error: error instanceof Error ? error.message : String(error) };
|
|
48
|
-
}
|
|
34
|
+
const { response, transportError } = await queryDaemon(resolvePaths().socket, {
|
|
35
|
+
type: 'agent.op',
|
|
36
|
+
argv: ['agent', ...argv],
|
|
37
|
+
sessionId,
|
|
38
|
+
delegationToken,
|
|
39
|
+
}, timeoutMs);
|
|
40
|
+
if (!response)
|
|
41
|
+
return {
|
|
42
|
+
ok: false, code: 'DAEMON_UNAVAILABLE',
|
|
43
|
+
error: daemonUnavailableMessage(transportError, 'Unable to connect to the evolcore daemon'),
|
|
44
|
+
};
|
|
45
|
+
if (!response.ok)
|
|
46
|
+
return { ok: false, code: response.code, error: response.error || 'agent operation failed', ...(response.data ? { data: response.data } : {}) };
|
|
47
|
+
return response.result ?? { ok: true, ...(response.data ?? {}) };
|
|
49
48
|
}
|
|
50
49
|
function getAgentMdPath(aid) {
|
|
51
50
|
return getAgentMdPathFromPaths(aid);
|
|
@@ -761,29 +760,23 @@ export async function agentReady(aid, commandArgs) {
|
|
|
761
760
|
};
|
|
762
761
|
}
|
|
763
762
|
const p = resolvePaths();
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
return { ok: false, code: 'DELEGATION_REQUIRED', error: `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task` };
|
|
768
|
-
}
|
|
769
|
-
const result = await ipcQuery(p.socket, {
|
|
770
|
-
type: 'evolagent.bootstrapComplete',
|
|
771
|
-
aid,
|
|
772
|
-
...(managedSessionId ? { argv: ['agent', ...(commandArgs ?? ['ready', aid])] } : {}),
|
|
773
|
-
...(managedSessionId ? { sessionId: managedSessionId, delegationToken } : {}),
|
|
774
|
-
}, 30_000);
|
|
775
|
-
if (!result)
|
|
776
|
-
return { ok: false, code: 'DAEMON_UNAVAILABLE', error: 'Unable to connect to the EvolCore daemon; agent ready requires daemon IPC' };
|
|
777
|
-
if (!result.ok) {
|
|
778
|
-
return { ok: false, code: result.code, error: result.error || 'Failed to complete bootstrap' };
|
|
779
|
-
}
|
|
780
|
-
return { ...result, ok: true, aid, reloaded: result.reloaded === true };
|
|
763
|
+
const delegationToken = managedSessionId ? readDelegationCredential() : undefined;
|
|
764
|
+
if (managedSessionId && !delegationToken) {
|
|
765
|
+
return { ok: false, code: 'DELEGATION_REQUIRED', error: `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task` };
|
|
781
766
|
}
|
|
782
|
-
|
|
767
|
+
const { response: result, transportError } = await queryDaemon(p.socket, {
|
|
768
|
+
type: 'evolagent.bootstrapComplete',
|
|
769
|
+
aid,
|
|
770
|
+
...(managedSessionId ? { argv: ['agent', ...(commandArgs ?? ['ready', aid])] } : {}),
|
|
771
|
+
...(managedSessionId ? { sessionId: managedSessionId, delegationToken } : {}),
|
|
772
|
+
}, 30_000);
|
|
773
|
+
if (!result)
|
|
783
774
|
return {
|
|
784
|
-
ok: false,
|
|
785
|
-
|
|
786
|
-
error: e instanceof Error ? e.message : 'Unable to connect to the EvolCore daemon',
|
|
775
|
+
ok: false, code: 'DAEMON_UNAVAILABLE',
|
|
776
|
+
error: daemonUnavailableMessage(transportError, 'Unable to connect to the EvolCore daemon; agent ready requires daemon IPC'),
|
|
787
777
|
};
|
|
778
|
+
if (!result.ok) {
|
|
779
|
+
return { ok: false, code: result.code, error: result.error || 'Failed to complete bootstrap' };
|
|
788
780
|
}
|
|
781
|
+
return { ...result, ok: true, aid, reloaded: result.reloaded === true };
|
|
789
782
|
}
|
|
@@ -2,9 +2,15 @@ import { ipcQuery } from '../ipc.js';
|
|
|
2
2
|
import { resolvePaths } from '../paths.js';
|
|
3
3
|
import { parseOwnershipCommand, ownershipFailure } from '../aun/aid/ownership-operation.js';
|
|
4
4
|
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
5
|
+
import { MAIN_CLI_BIN } from '../product.js';
|
|
5
6
|
export async function cmdAidBind(args) {
|
|
6
7
|
if (args.includes('--help') || args.includes('-h')) {
|
|
7
|
-
console.log(
|
|
8
|
+
console.log([
|
|
9
|
+
`用法: ${MAIN_CLI_BIN} aid bind <ownerAid> [--subject <subjectAid>] [--format json]`,
|
|
10
|
+
`${MAIN_CLI_BIN} aid bind status [--subject <subjectAid>] [--format json]`,
|
|
11
|
+
`${MAIN_CLI_BIN} aid bind accept <operationId> [--subject <subjectAid>] [--format json]`,
|
|
12
|
+
`${MAIN_CLI_BIN} aid bind reject <operationId> [--reason <text>] [--subject <subjectAid>] [--format json]`,
|
|
13
|
+
].join('\n'));
|
|
8
14
|
return;
|
|
9
15
|
}
|
|
10
16
|
const formatJson = args.includes('--format') && args[args.indexOf('--format') + 1] === 'json';
|
|
@@ -32,6 +38,11 @@ export async function cmdAidBind(args) {
|
|
|
32
38
|
console.log(`运行态同步: ${state.synchronization.status}`);
|
|
33
39
|
if (state.task)
|
|
34
40
|
console.log(`绑定任务: ${state.task.operation_id} (${state.task.status}/${state.task.step})`);
|
|
41
|
+
if (state.decisionTask)
|
|
42
|
+
console.log(`审批任务: ${state.decisionTask.operation_id} (${state.decisionTask.status}/${state.decisionTask.step})`);
|
|
43
|
+
for (const request of state.requests ?? []) {
|
|
44
|
+
console.log(`待确认邀约: ${request.operation_id} (sub=${request.sub_aid}, owner=${request.owner_aid}, 本端=${request.local_role})`);
|
|
45
|
+
}
|
|
35
46
|
if (state.requestedOwnerAid)
|
|
36
47
|
console.log(`请求绑定: ${state.requestedOwnerAid}`);
|
|
37
48
|
if (state.requestStatus)
|
package/dist/cli/aun-commands.js
CHANGED
|
@@ -4,7 +4,7 @@ import crypto from 'crypto';
|
|
|
4
4
|
import { agentMdPath, resolvePaths, resolveRoot } from '../paths.js';
|
|
5
5
|
import { isExplicitGroupId, normalizeGroupAid, sameGroupAid } from '../aun/group/index.js';
|
|
6
6
|
import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
|
|
7
|
-
import {
|
|
7
|
+
import { daemonUnavailableMessage, queryDaemon } from './help.js';
|
|
8
8
|
import { isValidAid as validSendAid } from '../aun/aid/validation.js';
|
|
9
9
|
import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
10
10
|
import { isManagementRole } from '../config/builtin-roles.js';
|
|
@@ -137,14 +137,15 @@ async function runManagedAid(args, formatJson) {
|
|
|
137
137
|
if (requiresSelfAid && runtime?.selfAid && parsed.command.aid !== runtime.selfAid.replace(/^@/, '')) {
|
|
138
138
|
failManagedAid(formatJson, 'SCOPE_MISMATCH', `托管任务只能操作当前 self AID:${runtime.selfAid}`);
|
|
139
139
|
}
|
|
140
|
-
const response = await
|
|
140
|
+
const { response, transportError } = await queryDaemon(resolvePaths().socket, {
|
|
141
141
|
type: 'aid.op',
|
|
142
142
|
argv: ['aid', ...args],
|
|
143
143
|
sessionId,
|
|
144
144
|
delegationToken,
|
|
145
145
|
}, 30_000);
|
|
146
|
-
if (!response)
|
|
147
|
-
failManagedAid(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
|
|
146
|
+
if (!response) {
|
|
147
|
+
failManagedAid(formatJson, 'DAEMON_UNAVAILABLE', daemonUnavailableMessage(transportError, 'Unable to connect to the evolcore daemon'));
|
|
148
|
+
}
|
|
148
149
|
if (!response.ok || !response.result) {
|
|
149
150
|
const error = response.error || 'AID operation failed';
|
|
150
151
|
const aid = args[0] === 'agentmd' ? args[2] : args[1];
|
|
@@ -220,14 +221,15 @@ async function runManagedGroup(args, formatJson) {
|
|
|
220
221
|
failManagedGroup(formatJson, parsed.code, parsed.reason);
|
|
221
222
|
const runtime = await readBestTaskRuntimeContext();
|
|
222
223
|
validateManagedGroupScope(parsed.command.from, parsed.command.groupId, runtime, formatJson);
|
|
223
|
-
const response = await
|
|
224
|
+
const { response, transportError } = await queryDaemon(resolvePaths().socket, {
|
|
224
225
|
type: 'group.op',
|
|
225
226
|
argv: ['group', ...args],
|
|
226
227
|
sessionId,
|
|
227
228
|
delegationToken,
|
|
228
229
|
}, 60_000);
|
|
229
|
-
if (!response)
|
|
230
|
-
failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
|
|
230
|
+
if (!response) {
|
|
231
|
+
failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', daemonUnavailableMessage(transportError, 'Unable to connect to the evolcore daemon'));
|
|
232
|
+
}
|
|
231
233
|
if (!response.ok || !response.result) {
|
|
232
234
|
failManagedGroup(formatJson, response.code || 'GROUP_OPERATION_FAILED', response.error || 'Group operation failed');
|
|
233
235
|
}
|
|
@@ -277,14 +279,15 @@ async function runManagedMsg(args, formatJson) {
|
|
|
277
279
|
failManagedGroup(formatJson, 'SCOPE_MISMATCH', `只能读取当前 AUN 私聊对端:${runtime.channelId}`);
|
|
278
280
|
}
|
|
279
281
|
}
|
|
280
|
-
const response = await
|
|
282
|
+
const { response, transportError } = await queryDaemon(resolvePaths().socket, {
|
|
281
283
|
type: 'msg.op',
|
|
282
284
|
argv: ['msg', ...args],
|
|
283
285
|
sessionId,
|
|
284
286
|
delegationToken,
|
|
285
287
|
}, 30_000);
|
|
286
|
-
if (!response)
|
|
287
|
-
failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
|
|
288
|
+
if (!response) {
|
|
289
|
+
failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', daemonUnavailableMessage(transportError, 'Unable to connect to the evolcore daemon'));
|
|
290
|
+
}
|
|
288
291
|
if (!response.ok || !response.result) {
|
|
289
292
|
failManagedGroup(formatJson, response.code || 'MSG_OPERATION_FAILED', response.error || 'Msg operation failed');
|
|
290
293
|
}
|
|
@@ -469,6 +472,8 @@ Commands:
|
|
|
469
472
|
avatar <aid> --file <path> | --url <https-url> 上传头像并更新 agent.md
|
|
470
473
|
bind <ownerAid> [--subject <subjectAid>] 发起 Ownership 2.1 绑定
|
|
471
474
|
bind status [--subject <subjectAid>] 核验协议 Owner、任务和同步状态
|
|
475
|
+
bind accept <operationId> [--subject <subjectAid>] 接受绑定邀约
|
|
476
|
+
bind reject <operationId> [--reason <text>] [--subject <subjectAid>] 拒绝绑定邀约
|
|
472
477
|
|
|
473
478
|
Options:
|
|
474
479
|
--format json 输出 JSON 格式
|
|
@@ -1159,7 +1164,7 @@ Options:
|
|
|
1159
1164
|
console.error('用法: ec storage upload <aid> <local-file> <remote-path> [--public]');
|
|
1160
1165
|
process.exit(1);
|
|
1161
1166
|
}
|
|
1162
|
-
const result = await
|
|
1167
|
+
const { response: result, transportError } = await queryDaemon(resolvePaths().socket, {
|
|
1163
1168
|
type: 'storage.upload',
|
|
1164
1169
|
argv: ['storage', ...args],
|
|
1165
1170
|
aid,
|
|
@@ -1169,8 +1174,9 @@ Options:
|
|
|
1169
1174
|
sessionId: process.env.EVOLCORE_SESSION_ID,
|
|
1170
1175
|
delegationToken,
|
|
1171
1176
|
}, null);
|
|
1172
|
-
if (!result)
|
|
1173
|
-
failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
|
|
1177
|
+
if (!result) {
|
|
1178
|
+
failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', daemonUnavailableMessage(transportError, 'Unable to connect to the evolcore daemon'));
|
|
1179
|
+
}
|
|
1174
1180
|
if (!result.ok)
|
|
1175
1181
|
failManagedGroup(formatJson, result.code || 'STORAGE_UPLOAD_FAILED', result.error || 'Storage upload failed');
|
|
1176
1182
|
if (formatJson)
|
|
@@ -1185,11 +1191,12 @@ Options:
|
|
|
1185
1191
|
}
|
|
1186
1192
|
return;
|
|
1187
1193
|
}
|
|
1188
|
-
const authorization = await
|
|
1194
|
+
const { response: authorization, transportError } = await queryDaemon(resolvePaths().socket, {
|
|
1189
1195
|
type: 'storage.auth', argv: ['storage', ...args], operation, aid, sessionId: process.env.EVOLCORE_SESSION_ID, delegationToken,
|
|
1190
1196
|
}, 10_000);
|
|
1191
|
-
if (!authorization)
|
|
1192
|
-
failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
|
|
1197
|
+
if (!authorization) {
|
|
1198
|
+
failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', daemonUnavailableMessage(transportError, 'Unable to connect to the evolcore daemon'));
|
|
1199
|
+
}
|
|
1193
1200
|
if (!authorization.ok)
|
|
1194
1201
|
failManagedGroup(formatJson, authorization.code || 'STORAGE_AUTH_FAILED', authorization.error || 'Storage operation denied');
|
|
1195
1202
|
if (sub === 'ls') {
|
|
@@ -1531,7 +1538,7 @@ async function applyCrossThreadSendEffects(input) {
|
|
|
1531
1538
|
originThreadName,
|
|
1532
1539
|
targetThreadName,
|
|
1533
1540
|
});
|
|
1534
|
-
const triggerRes = await
|
|
1541
|
+
const { response: triggerRes, transportError } = await queryDaemon(resolvePaths().socket, {
|
|
1535
1542
|
type: 'trigger.create',
|
|
1536
1543
|
definition: triggerDef,
|
|
1537
1544
|
files: [],
|
|
@@ -1543,7 +1550,7 @@ async function applyCrossThreadSendEffects(input) {
|
|
|
1543
1550
|
delegationToken: readDelegationCredential(),
|
|
1544
1551
|
}, 30_000);
|
|
1545
1552
|
if (!triggerRes?.ok) {
|
|
1546
|
-
process.stderr.write(`⚠ Trigger 创建失败: ${triggerRes?.error ?? 'unknown'}(inbox 仍会写入)\n`);
|
|
1553
|
+
process.stderr.write(`⚠ Trigger 创建失败: ${triggerRes?.error ?? daemonUnavailableMessage(transportError, 'unknown')}(inbox 仍会写入)\n`);
|
|
1547
1554
|
}
|
|
1548
1555
|
else {
|
|
1549
1556
|
// 以 daemon 落盘的结果为准(definition 已带 id,正常应与预设值相同;
|
|
@@ -1691,13 +1698,13 @@ Options:
|
|
|
1691
1698
|
console.error(`request status is limited to the delegated self AID: ${runtime.selfAid}`);
|
|
1692
1699
|
process.exit(1);
|
|
1693
1700
|
}
|
|
1694
|
-
const result = await
|
|
1701
|
+
const { response: result, transportError } = await queryDaemon(resolvePaths().socket, {
|
|
1695
1702
|
type: 'aun-msg-request-get', aid, requestId,
|
|
1696
1703
|
sessionId: process.env.EVOLCORE_SESSION_ID,
|
|
1697
1704
|
delegationToken: readDelegationCredential(),
|
|
1698
1705
|
}, 10_000);
|
|
1699
1706
|
if (!result) {
|
|
1700
|
-
console.error('unable to connect to the EvolCore daemon');
|
|
1707
|
+
console.error(daemonUnavailableMessage(transportError, 'unable to connect to the EvolCore daemon'));
|
|
1701
1708
|
process.exit(1);
|
|
1702
1709
|
}
|
|
1703
1710
|
if (formatJson)
|
|
@@ -3388,12 +3395,13 @@ async function runManagedSend(argv, formatJson) {
|
|
|
3388
3395
|
if (!delegationToken)
|
|
3389
3396
|
failManagedGroup(formatJson, 'DELEGATION_REQUIRED', 'Managed send requires delegation');
|
|
3390
3397
|
const runtime = await readBestTaskRuntimeContext();
|
|
3391
|
-
const result = await
|
|
3398
|
+
const { response: result, transportError } = await queryDaemon(resolvePaths().socket, {
|
|
3392
3399
|
type: 'aun-msg-send', argv, delegationToken,
|
|
3393
3400
|
originSessionId: process.env.EVOLCORE_SESSION_ID, originMessageId: runtime?.messageId,
|
|
3394
3401
|
}, null);
|
|
3395
|
-
if (!result)
|
|
3396
|
-
failManagedGroup(formatJson, 'AUN_DAEMON_UNAVAILABLE', 'Unable to connect to the EvolCore daemon');
|
|
3402
|
+
if (!result) {
|
|
3403
|
+
failManagedGroup(formatJson, 'AUN_DAEMON_UNAVAILABLE', daemonUnavailableMessage(transportError, 'Unable to connect to the EvolCore daemon'));
|
|
3404
|
+
}
|
|
3397
3405
|
if (!result.ok)
|
|
3398
3406
|
failManagedGroup(formatJson, result.code ?? 'AUN_SEND_FAILED', `${result.error ?? 'Send failed'}${result.request_id ? ` request_id=${result.request_id}` : ''}`, {
|
|
3399
3407
|
...(typeof result.detail_code === 'string' ? { detail_code: result.detail_code } : {}),
|
package/dist/cli/config.js
CHANGED
|
@@ -2,7 +2,7 @@ import { isHelpFlag, wantsHelp, getArgValue } from './help.js';
|
|
|
2
2
|
import { initConfigManager } from '../config/config-manager.js';
|
|
3
3
|
import { resolveConfigCommand } from '../config/resolved-config-op.js';
|
|
4
4
|
import { AUTHENTICATED_CONFIG_ROLE_ENV, executeResolvedConfigCommandAsync, } from '../config/config-operation-service.js';
|
|
5
|
-
import {
|
|
5
|
+
import { daemonUnavailableMessage, queryDaemon } from './help.js';
|
|
6
6
|
import { resolvePaths } from '../paths.js';
|
|
7
7
|
import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
8
8
|
import { splitConfigBatchGetArgv } from './cli-argv.js';
|
|
@@ -135,23 +135,19 @@ function managedSession(formatJson) {
|
|
|
135
135
|
return { sessionId, delegationToken };
|
|
136
136
|
}
|
|
137
137
|
async function managedConfigQuery(args, sessionId, delegationToken) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}, 10_000);
|
|
145
|
-
}
|
|
146
|
-
catch {
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
138
|
+
return queryDaemon(resolvePaths().socket, {
|
|
139
|
+
type: 'config.op',
|
|
140
|
+
argv: ['config', ...args],
|
|
141
|
+
sessionId,
|
|
142
|
+
delegationToken,
|
|
143
|
+
}, 10_000);
|
|
149
144
|
}
|
|
150
145
|
async function runManagedConfig(args, formatJson) {
|
|
151
146
|
const { sessionId, delegationToken } = managedSession(formatJson);
|
|
152
|
-
const response = await managedConfigQuery(args, sessionId, delegationToken);
|
|
153
|
-
if (!response)
|
|
154
|
-
fail(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
|
|
147
|
+
const { response, transportError } = await managedConfigQuery(args, sessionId, delegationToken);
|
|
148
|
+
if (!response) {
|
|
149
|
+
fail(formatJson, 'DAEMON_UNAVAILABLE', daemonUnavailableMessage(transportError, 'Unable to connect to the evolcore daemon'));
|
|
150
|
+
}
|
|
155
151
|
if (!response.ok || !response.result) {
|
|
156
152
|
fail(formatJson, response.code || 'CONFIG_AUTH_FAILED', response.error || 'config operation failed', response.data);
|
|
157
153
|
}
|
|
@@ -197,9 +193,10 @@ async function runDirectBatchGet(fields, rest, formatJson) {
|
|
|
197
193
|
}
|
|
198
194
|
async function runManagedBatchGet(fields, rest, formatJson) {
|
|
199
195
|
const { sessionId, delegationToken } = managedSession(formatJson);
|
|
200
|
-
const response = await managedConfigQuery(['get', ...fields, ...rest], sessionId, delegationToken);
|
|
201
|
-
if (!response)
|
|
202
|
-
fail(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
|
|
196
|
+
const { response, transportError } = await managedConfigQuery(['get', ...fields, ...rest], sessionId, delegationToken);
|
|
197
|
+
if (!response) {
|
|
198
|
+
fail(formatJson, 'DAEMON_UNAVAILABLE', daemonUnavailableMessage(transportError, 'Unable to connect to the evolcore daemon'));
|
|
199
|
+
}
|
|
203
200
|
if (!response.ok || !response.result) {
|
|
204
201
|
fail(formatJson, response.code || 'CONFIG_AUTH_FAILED', response.error || 'config operation failed', response.data);
|
|
205
202
|
}
|
package/dist/cli/contact.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolvePaths } from '../paths.js';
|
|
2
2
|
import { loadAllAgents } from '../config-store.js';
|
|
3
3
|
import { executeResolvedContactCommand, resolveContactCommand, } from '../config/contact-operation-service.js';
|
|
4
|
-
import {
|
|
4
|
+
import { daemonUnavailableMessage, queryDaemon } from './help.js';
|
|
5
5
|
import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
6
6
|
import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
|
|
7
7
|
export async function cmdContact(args) {
|
|
@@ -48,18 +48,15 @@ async function runManaged(args, json) {
|
|
|
48
48
|
const delegationToken = readDelegationCredential();
|
|
49
49
|
if (!delegationToken)
|
|
50
50
|
fail(`${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`, 'DELEGATION_REQUIRED');
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
const { response, transportError } = await queryDaemon(resolvePaths().socket, {
|
|
52
|
+
type: 'contact.op',
|
|
53
|
+
argv: ['contact', ...args],
|
|
54
|
+
sessionId,
|
|
55
|
+
delegationToken,
|
|
56
|
+
}, 10_000);
|
|
57
|
+
if (!response) {
|
|
58
|
+
fail(daemonUnavailableMessage(transportError, 'Unable to connect to the evolcore daemon'), 'DAEMON_UNAVAILABLE');
|
|
59
59
|
}
|
|
60
|
-
catch { }
|
|
61
|
-
if (!response)
|
|
62
|
-
fail('Unable to connect to the evolcore daemon', 'DAEMON_UNAVAILABLE');
|
|
63
60
|
if (!response.ok || !response.result) {
|
|
64
61
|
fail(response.error || 'contact operation failed', response.code || 'CONTACT_AUTH_FAILED', response.data);
|
|
65
62
|
}
|
package/dist/cli/ctl-command.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolvePaths } from '../paths.js';
|
|
2
|
-
import {
|
|
2
|
+
import { daemonUnavailableMessage, queryDaemon } from './help.js';
|
|
3
3
|
import { isHelpFlag, wantsHelp } from './help.js';
|
|
4
4
|
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
5
5
|
// ==================== Ctl ====================
|
|
@@ -44,14 +44,14 @@ export async function cmdCtl(args) {
|
|
|
44
44
|
process.exit(1);
|
|
45
45
|
}
|
|
46
46
|
const socketPath = resolvePaths().socket;
|
|
47
|
-
const result = await
|
|
47
|
+
const { response: result, transportError } = await queryDaemon(socketPath, {
|
|
48
48
|
type: 'ctl',
|
|
49
49
|
argv: ['ctl', ...args],
|
|
50
50
|
sessionId,
|
|
51
51
|
delegationToken: readDelegationCredential(),
|
|
52
52
|
}, 10_000);
|
|
53
53
|
if (!result) {
|
|
54
|
-
console.error('
|
|
54
|
+
console.error(`错误: ${daemonUnavailableMessage(transportError, '无法连接 evolcore 服务')}`);
|
|
55
55
|
process.exit(1);
|
|
56
56
|
}
|
|
57
57
|
const ctlResult = result;
|
package/dist/cli/diag.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { daemonUnavailableMessage, queryDaemon } from './help.js';
|
|
2
2
|
import { resolvePaths } from '../paths.js';
|
|
3
3
|
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
4
4
|
import { parseDiagArgs } from '../core/command/diag-service.js';
|
|
@@ -13,13 +13,17 @@ export async function cmdDiag(args) {
|
|
|
13
13
|
let result;
|
|
14
14
|
try {
|
|
15
15
|
parseDiagArgs(args);
|
|
16
|
-
|
|
16
|
+
const { response, transportError } = await queryDaemon(resolvePaths().socket, {
|
|
17
17
|
type: 'diag', argv,
|
|
18
18
|
...(process.env.EVOLCORE_SESSION_ID ? {
|
|
19
19
|
sessionId: process.env.EVOLCORE_SESSION_ID,
|
|
20
20
|
delegationToken: readDelegationCredential(),
|
|
21
21
|
} : {}),
|
|
22
|
-
}, 30_000)
|
|
22
|
+
}, 30_000);
|
|
23
|
+
result = response ?? {
|
|
24
|
+
ok: false, code: 'DAEMON_UNAVAILABLE',
|
|
25
|
+
message: daemonUnavailableMessage(transportError, 'daemon 未返回结果,请检查其运行状态;发送结果尚未确认'),
|
|
26
|
+
};
|
|
23
27
|
}
|
|
24
28
|
catch (error) {
|
|
25
29
|
result = { ok: false, code: 'INVALID_ARGUMENT', message: error.message };
|