evolcore 0.0.25 → 0.0.27
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 +632 -565
- package/LICENSE +21 -21
- package/README.md +455 -455
- package/bin/codex-managed-acl.ps1 +203 -160
- package/bin/codex-managed-hook.mjs +208 -208
- package/bin/ec-safe-output.js +327 -327
- package/bin/ec.js +40 -29
- package/bin/install-codex-managed-hooks.mjs +582 -555
- package/dist/agents/baseagent-availability.js +68 -0
- package/dist/agents/baseagent.js +96 -46
- package/dist/agents/claude-runner.js +172 -33
- package/dist/agents/codex/app-server-client.js +76 -31
- package/dist/agents/codex/catalog.js +1 -1
- package/dist/agents/codex/diagnostics.js +34 -1
- package/dist/agents/codex-runner.js +434 -446
- package/dist/agents/ecagent-runner.js +174 -34
- package/dist/agents/gemini-runner.js +8 -7
- package/dist/agents/runner-types.js +75 -19
- package/dist/aun/aid/agentmd.js +151 -36
- package/dist/aun/aid/client.js +1 -1
- package/dist/aun/aid/control-aid.js +180 -1
- package/dist/aun/aid/identity.js +4 -4
- package/dist/aun/aid/index.js +1 -1
- package/dist/aun/aid/store.js +17 -13
- package/dist/aun/group/history.js +303 -0
- package/dist/aun/group/identity.js +43 -0
- package/dist/aun/group/index.js +5 -0
- package/dist/aun/{msg/group.js → group/operations.js} +162 -39
- package/dist/aun/{menu-client.js → menu/client.js} +85 -6
- package/dist/aun/menu/index.js +2 -0
- package/dist/aun/menu/transport.js +49 -0
- package/dist/aun/msg/index.js +2 -1
- package/dist/aun/msg/managed-operation.js +85 -19
- package/dist/aun/msg/mention-schema.js +51 -0
- package/dist/aun/msg/p2p.js +19 -9
- package/dist/aun/msg/upload.js +43 -80
- package/dist/aun/outbox.js +29 -7
- package/dist/aun/rpc/client.js +1 -0
- package/dist/aun/storage/client.js +39 -50
- package/dist/channels/aun.js +842 -318
- package/dist/channels/daemon.js +10 -6
- package/dist/cli/agent-command.js +212 -89
- package/dist/cli/agent-create.js +626 -11
- package/dist/cli/agent.js +125 -13
- package/dist/cli/aun-commands.js +487 -337
- package/dist/cli/bench.js +20 -20
- package/dist/cli/config.js +55 -33
- package/dist/cli/contact.js +72 -15
- package/dist/cli/ctl-command.js +24 -24
- package/dist/cli/daemon-commands.js +140 -63
- package/dist/cli/diag.js +31 -0
- package/dist/cli/fs-command.js +70 -70
- package/dist/cli/handoff-command.js +46 -14
- package/dist/cli/index.js +91 -79
- package/dist/cli/init.js +34 -1
- package/dist/cli/link-rules.js +21 -21
- package/dist/cli/managed-command-guard.js +5 -1
- package/dist/cli/menu-client.js +51 -32
- package/dist/cli/model.js +3 -3
- package/dist/cli/net-check.js +22 -22
- package/dist/cli/queue-command.js +31 -31
- package/dist/cli/response.js +32 -32
- package/dist/cli/restart-monitor.js +103 -42
- package/dist/cli/stats.js +51 -51
- package/dist/cli/task-command.js +59 -0
- package/dist/cli/task-context.js +97 -49
- package/dist/cli/trigger-command.js +74 -64
- package/dist/config/builtin-roles.js +11 -0
- package/dist/config/config-field-policy.js +11 -0
- package/dist/config/config-manager.js +32 -4
- package/dist/config/config-operation-service.js +160 -0
- package/dist/config/contact-book-store.js +1 -1
- package/dist/config/contact-book.js +1 -1
- package/dist/config/contact-operation-service.js +97 -8
- package/dist/config/peer-role-resolver.js +1 -1
- package/dist/config/resolved-config-op.js +30 -7
- package/dist/config-store.js +1 -1
- package/dist/core/agent-application-service.js +7 -1
- package/dist/core/audit/event-key.js +17 -2
- package/dist/core/audit/log-integrity.js +34 -8
- package/dist/core/auth/agent-delegation.js +48 -14
- package/dist/core/auth/auth-gateway.js +2 -0
- package/dist/core/auth/authorization-audit.js +53 -49
- package/dist/core/auth/operation-authorizer.js +90 -7
- package/dist/core/auth/operation-catalog.js +145 -4
- package/dist/core/auth/remote-access-store.js +155 -10
- package/dist/core/bootstrap-messages.js +66 -7
- package/dist/core/bootstrap-service.js +111 -20
- package/dist/core/command/agent-control.js +88 -7
- package/dist/core/command/agent-storage-menu.js +443 -0
- package/dist/core/command/cli-intent-parser.js +19 -0
- package/dist/core/command/command-handler.js +159 -65
- package/dist/core/command/data-root-resolver.js +273 -0
- package/dist/core/command/diag-service.js +118 -0
- package/dist/core/command/group-menu.js +7 -2
- package/dist/core/command/menu-catalog.js +46 -7
- package/dist/core/command/menu-handler.js +392 -100
- package/dist/core/command/menu-protocol.js +45 -6
- package/dist/core/command/menu-token-store.js +41 -8
- package/dist/core/command/role-menu.js +2 -2
- package/dist/core/command/slash-gate.js +34 -4
- package/dist/core/command/slash-handler.js +123 -43
- package/dist/core/event-catalog.js +4 -0
- package/dist/core/evolagent-registry.js +28 -2
- package/dist/core/group/invite-service.js +924 -0
- package/dist/core/handoff/runtime.js +205 -27
- package/dist/core/handoff/store.js +193 -4
- package/dist/core/interaction-router.js +22 -8
- package/dist/core/message/im-renderer.js +146 -34
- package/dist/core/message/message-bridge.js +163 -20
- package/dist/core/message/message-log.js +5 -3
- package/dist/core/message/message-queue.js +99 -41
- package/dist/core/message/message-utils.js +1 -0
- package/dist/core/message/response-engine.js +755 -144
- package/dist/core/model/catalog-service.js +79 -49
- package/dist/core/model/context-window-suffix.js +33 -0
- package/dist/core/model/model-catalog.js +1 -1
- package/dist/core/model/model-permission.js +12 -3
- package/dist/core/permission/approval-gateway.js +36 -3
- package/dist/core/permission/ec-command-parser.js +112 -41
- package/dist/core/permission/protected-paths.js +134 -16
- package/dist/core/permission/sandbox-runtime.js +108 -17
- package/dist/core/permission/tool-error-code.js +15 -0
- package/dist/core/permission/tool-policy.js +9 -8
- package/dist/core/relation/peer-identity.js +57 -6
- package/dist/core/relation/shared-data.js +106 -0
- package/dist/core/role/runtime-policy.js +64 -0
- package/dist/core/runtime-lock.js +10 -26
- package/dist/core/session/runner-task-history.js +170 -0
- package/dist/core/session/session-manager.js +34 -6
- package/dist/core/session/session-mapper.js +41 -0
- package/dist/core/session/session-turn-coordinator.js +37 -7
- package/dist/core/session/session-turns.js +48 -7
- package/dist/core/task/task-recovery-service.js +176 -0
- package/dist/core/task/task-resume-operation.js +32 -0
- package/dist/eck/group-rules-sync.js +5 -3
- package/dist/eck/kit-renderer.js +1 -0
- package/dist/index.js +588 -217
- package/dist/ipc.js +193 -15
- package/dist/paths.js +17 -4
- package/dist/product.js +2 -0
- package/dist/response-system/engines/v1/proactive-flow.js +59 -2
- package/dist/stats/billing.js +41 -15
- package/dist/stats/db.js +159 -159
- package/dist/stats/eck-vars.js +9 -9
- package/dist/stats/price-resolver.js +28 -10
- package/dist/stats/query.js +139 -139
- package/dist/stats/role-budget.js +6 -6
- package/dist/stats/writer.js +51 -51
- package/dist/trigger/event-source.js +19 -0
- package/dist/trigger/feedback.js +233 -40
- package/dist/trigger/parser.js +55 -5
- package/dist/trigger/patch.js +9 -0
- package/dist/trigger/scheduler.js +30 -4
- package/dist/trigger/validation.js +20 -3
- package/dist/utils/cross-platform.js +30 -1
- package/dist/utils/ecweb-utils.js +1 -0
- package/dist/utils/error-dict.json +160 -160
- package/dist/utils/error-utils.js +61 -2
- package/dist/utils/evolcore-version.js +129 -0
- package/dist/utils/logger.js +26 -14
- package/dist/utils/macos-autostart.js +22 -22
- package/dist/utils/model-prices.jsonl +23 -23
- package/dist/utils/npm-ops.js +176 -35
- package/dist/utils/tool-summary.js +59 -3
- package/dist/utils/welcome.js +196 -23
- package/ecagent/LICENSE +21 -21
- package/ecagent/NOTICE +11 -11
- package/ecagent/README.md +61 -61
- package/ecagent/dist/harness/agent-harness.js +3 -0
- package/ecagent/dist/harness/compaction/branch-summarization.js +30 -30
- package/ecagent/dist/harness/compaction/compaction.js +83 -83
- package/ecagent/dist/harness/messages.js +7 -7
- package/ecagent/dist/harness/session/jsonl-storage.js +21 -2
- package/kits/docs/GUIDE.md +20 -20
- package/kits/docs/INDEX.md +60 -66
- package/kits/docs/aun/CHEATSHEET.md +19 -19
- package/kits/docs/aun/SYNC_PROTOCOL.md +15 -15
- package/kits/docs/channels/aun.md +69 -56
- package/kits/docs/channels/feishu.md +56 -56
- package/kits/docs/context-assembly.md +379 -367
- package/kits/docs/eck_templates/GUIDE.template.md +22 -22
- package/kits/docs/eck_templates/INDEX.template.md +28 -28
- package/kits/docs/eck_templates/path-registry.template.md +33 -33
- package/kits/docs/eck_templates/runtime.template.md +19 -19
- package/kits/docs/evolcore/INDEX.md +76 -71
- package/kits/docs/evolcore/agent-create.md +202 -165
- package/kits/docs/evolcore/agent.md +99 -67
- package/kits/docs/evolcore/aid.md +68 -60
- package/kits/docs/evolcore/codex-windows-sandbox.md +146 -146
- package/kits/docs/evolcore/config.md +241 -195
- package/kits/docs/evolcore/contact.md +75 -68
- package/kits/docs/evolcore/ctl.md +46 -46
- package/kits/docs/evolcore/event.md +216 -216
- package/kits/docs/evolcore/fs-architecture.md +1215 -1215
- package/kits/docs/evolcore/fs.md +110 -110
- package/kits/docs/evolcore/group-collaboration.md +244 -244
- package/kits/docs/evolcore/group-fs.md +17 -17
- package/kits/docs/evolcore/group-rules.md +251 -251
- package/kits/docs/evolcore/group.md +267 -152
- package/kits/docs/evolcore/menu-client.md +58 -34
- package/kits/docs/evolcore/model.md +50 -50
- package/kits/docs/evolcore/msg.md +169 -165
- package/kits/docs/evolcore/response.md +75 -75
- package/kits/docs/evolcore/rpc.md +37 -37
- package/kits/docs/evolcore/self-summary.md +29 -29
- package/kits/docs/evolcore/stats.md +83 -83
- package/kits/docs/evolcore/storage.md +53 -50
- package/kits/docs/evolcore/task.md +14 -0
- package/kits/docs/evolcore/trigger.md +623 -575
- package/kits/docs/identity/AID_PROFILE_SPEC.md +26 -26
- package/kits/docs/identity/PATH_OPS.md +16 -16
- package/kits/docs/identity/ROLE_DETAIL.md +25 -25
- package/kits/docs/identity/identity-tools.md +26 -26
- package/kits/docs/path-registry.md +62 -62
- package/kits/docs/prompt-loading-architecture.md +269 -269
- package/kits/docs/venues/aun-group.md +45 -45
- package/kits/docs/venues/aun-private.md +10 -10
- package/kits/docs/venues/client-desktop.md +10 -10
- package/kits/docs/venues/client-mobile.md +10 -10
- package/kits/docs/venues/feishu-group.md +13 -13
- package/kits/docs/venues/feishu-private.md +9 -9
- package/kits/docs/venues/group.md +42 -25
- package/kits/docs/venues/private.md +10 -10
- package/kits/eck_manifest.auxiliary.json +43 -43
- package/kits/eck_manifest.json +217 -190
- package/kits/eck_message_manifest.json +74 -74
- package/kits/migrations/README-role-config-v4.md +32 -32
- package/kits/migrations/migrate-contact-book-v2.mjs +748 -748
- package/kits/migrations/migrate-role-config-v4.mjs +614 -614
- package/kits/migrations/migrate-role-config-v5.mjs +365 -365
- package/kits/migrations/rename-config-file.mjs +99 -99
- package/kits/rules/01-overview.md +166 -162
- package/kits/rules/02-navigation.md +96 -96
- package/kits/rules/03-identity.md +36 -36
- package/kits/rules/04-relation.md +76 -75
- package/kits/rules/05-venue.md +60 -60
- package/kits/rules/06-channel.md +65 -63
- package/kits/schemas/_meta.json +53 -53
- package/kits/schemas/agent-config.schema.1.json +177 -177
- package/kits/schemas/agent-config.schema.10.json +395 -395
- package/kits/schemas/agent-config.schema.11.json +421 -421
- package/kits/schemas/agent-config.schema.12.json +451 -427
- package/kits/schemas/agent-config.schema.2.json +239 -239
- package/kits/schemas/agent-config.schema.3.json +119 -119
- package/kits/schemas/agent-config.schema.4.json +208 -208
- package/kits/schemas/agent-config.schema.5.json +326 -326
- package/kits/schemas/agent-config.schema.6.json +322 -322
- package/kits/schemas/agent-config.schema.7.json +303 -303
- package/kits/schemas/agent-config.schema.8.json +304 -304
- package/kits/schemas/agent-config.schema.9.json +364 -364
- package/kits/schemas/contact-book.schema.1.json +36 -36
- package/kits/schemas/contact-book.schema.2.json +43 -43
- package/kits/schemas/contact-book.schema.3.json +67 -67
- package/kits/schemas/daemon.schema.1.json +91 -91
- package/kits/schemas/daemon.schema.2.json +101 -101
- package/kits/schemas/daemon.schema.3.json +123 -123
- package/kits/schemas/daemon.schema.4.json +136 -136
- package/kits/schemas/daemon.schema.5.json +135 -135
- package/kits/schemas/daemon.schema.6.json +131 -131
- package/kits/schemas/defaults.schema.1.json +81 -81
- package/kits/schemas/defaults.schema.2.json +85 -85
- package/kits/schemas/defaults.schema.3.json +73 -73
- package/kits/schemas/defaults.schema.4.json +107 -107
- package/kits/schemas/defaults.schema.5.json +119 -119
- package/kits/schemas/menu-exec-schema-commands.md +208 -208
- package/kits/schemas/migrations/README.md +30 -30
- package/kits/schemas/relation-config.schema.1.json +158 -158
- package/kits/schemas/relation-config.schema.2.json +73 -73
- package/kits/schemas/relation-config.schema.3.json +50 -50
- package/kits/schemas/relation-config.schema.4.json +47 -47
- package/kits/schemas/relation-config.schema.5.json +47 -47
- package/kits/schemas/relation-config.schema.6.json +46 -46
- package/kits/schemas/relation-config.schema.7.json +59 -59
- package/kits/schemas/relation-config.schema.8.json +103 -103
- package/kits/schemas/role-config.schema.1.json +215 -201
- package/kits/schemas/role-registry.schema.1.json +35 -35
- package/kits/schemas/single-session.schema.1.json +31 -31
- package/kits/schemas/single-session.schema.2.json +57 -57
- package/kits/schemas/single-session.schema.3.json +32 -32
- package/kits/templates/bootstrap-welcome.md +17 -17
- package/kits/templates/message-fragments/handoff-context-to-target.md +9 -9
- package/kits/templates/message-fragments/handoff-request-to-target.md +19 -19
- package/kits/templates/message-fragments/handoff-response-to-origin.md +9 -9
- package/kits/templates/message-fragments/inject-default.md +2 -2
- package/kits/templates/message-fragments/item.md +2 -2
- package/kits/templates/roles/admin.json +92 -92
- package/kits/templates/roles/member.json +101 -96
- package/kits/templates/roles/owner.json +9 -9
- package/kits/templates/roles/visitor.json +90 -85
- package/kits/templates/system-fragments/baseagent.md +14 -14
- package/kits/templates/system-fragments/bootstrap.md +53 -34
- package/kits/templates/system-fragments/channel.md +28 -64
- package/kits/templates/system-fragments/commands.md +36 -28
- package/kits/templates/system-fragments/group-unread-history.md +7 -0
- package/kits/templates/system-fragments/identity.md +13 -13
- package/kits/templates/system-fragments/relation.md +19 -19
- package/kits/templates/system-fragments/reply.md +56 -0
- package/kits/templates/system-fragments/session.md +59 -59
- package/kits/templates/system-fragments/venue.md +31 -31
- package/package.json +104 -98
- package/dist/aun/group-identity.js +0 -9
- /package/dist/aun/{group-fs-download.js → group/fs-download.js} +0 -0
- /package/dist/aun/{msg/group-index.js → group/index-rpc.js} +0 -0
|
@@ -51,6 +51,8 @@ export function parseMenuClientProtectedHeaders(value) {
|
|
|
51
51
|
result.client_version = normalized.client_version;
|
|
52
52
|
if (normalized.evol_version !== undefined)
|
|
53
53
|
result.evol_version = normalized.evol_version;
|
|
54
|
+
if (normalized.sdk_version !== undefined)
|
|
55
|
+
result.sdk_version = normalized.sdk_version;
|
|
54
56
|
if (normalized.auth_method === 'daemon-owner' || normalized.auth_method === 'remote-access-token' || normalized.auth_method === 'ecweb-token')
|
|
55
57
|
result.auth_method = normalized.auth_method;
|
|
56
58
|
else if (normalized.auth_method !== undefined)
|
|
@@ -118,11 +120,16 @@ export const MENU_NAME_COMMANDS = Object.freeze({
|
|
|
118
120
|
dispatch: '/dispatch',
|
|
119
121
|
observable: '/observable',
|
|
120
122
|
system: '/system',
|
|
123
|
+
baseagents: '/baseagents',
|
|
121
124
|
cli: '/cli',
|
|
122
125
|
agent: '/agent',
|
|
123
126
|
aid: '/aid',
|
|
124
127
|
trigger: '/trigger',
|
|
125
128
|
file: '/file',
|
|
129
|
+
'agent-data-root': '/agent-data-root',
|
|
130
|
+
'relation-data-root': '/relation-data-root',
|
|
131
|
+
'agent-storage-root': '/agent-storage-root',
|
|
132
|
+
storage: '/storage',
|
|
126
133
|
gateway: '/gateway',
|
|
127
134
|
config: '/config',
|
|
128
135
|
capability: '/capability',
|
|
@@ -208,11 +215,17 @@ export function isEvolMenuVersionGateEnabled() {
|
|
|
208
215
|
export function isAunMenuTokenRequired() {
|
|
209
216
|
return loadDaemonConfig().aun?.menuTokenRequired === true;
|
|
210
217
|
}
|
|
211
|
-
export function evolMenuResponseTransportMetadata() {
|
|
218
|
+
export function evolMenuResponseTransportMetadata(sdkVersion) {
|
|
212
219
|
return {
|
|
213
220
|
// Clear inherited request state so AUNChannel applies daemon aun.defaultEncrypt.
|
|
214
221
|
encrypted: undefined,
|
|
215
|
-
protectedHeaders: {
|
|
222
|
+
protectedHeaders: {
|
|
223
|
+
ec_version: readInstalledEvolcoreVersion(),
|
|
224
|
+
...(typeof sdkVersion === 'string' && sdkVersion.trim() ? { sdk_version: sdkVersion.trim() } : {}),
|
|
225
|
+
},
|
|
226
|
+
...(typeof sdkVersion === 'string' && sdkVersion.trim()
|
|
227
|
+
? { menuClientSdkVersion: sdkVersion.trim() }
|
|
228
|
+
: {}),
|
|
216
229
|
};
|
|
217
230
|
}
|
|
218
231
|
const EXPLICIT_SCOPE_UPDATE_NAMES = new Set([
|
|
@@ -329,6 +342,12 @@ export function validateMenuRequest(request) {
|
|
|
329
342
|
return { code: 'INVALID_ARGUMENT', message: 'File fetch requires args.path' };
|
|
330
343
|
}
|
|
331
344
|
}
|
|
345
|
+
if ((request.name === 'file' || request.cmd === '/file') && request.args !== undefined) {
|
|
346
|
+
const args = request.args;
|
|
347
|
+
if (args.rootId !== undefined && (typeof args.rootId !== 'string' || args.rootId.trim().length === 0)) {
|
|
348
|
+
return { code: 'INVALID_ARGUMENT', message: 'File rootId must be a non-empty string' };
|
|
349
|
+
}
|
|
350
|
+
}
|
|
332
351
|
return null;
|
|
333
352
|
}
|
|
334
353
|
export function menuSuccess(header, data) {
|
|
@@ -371,10 +390,10 @@ export function enforceMenuResponseSize(response, maxBytes = 128 * 1024) {
|
|
|
371
390
|
});
|
|
372
391
|
}
|
|
373
392
|
const INVALID_ARGUMENT_CODES = new Set([
|
|
374
|
-
'ARGUMENT_MISMATCH', '
|
|
393
|
+
'ARGUMENT_MISMATCH', 'INVALID_ARGS', 'INVALID_DELEGATION',
|
|
375
394
|
'INVALID_FIELD', 'INVALID_REVISION', 'INVALID_SCOPE', 'INVALID_TYPE', 'INVALID_VALUE', 'MISSING_AID',
|
|
376
395
|
'MISSING_ARGV', 'MISSING_BASEAGENT', 'MISSING_CMD', 'MISSING_PEER', 'MISSING_VALUE',
|
|
377
|
-
'
|
|
396
|
+
'REVISION_REQUIRED', 'ROLE_VIOLATION',
|
|
378
397
|
]);
|
|
379
398
|
const STABLE_CODES = new Set([
|
|
380
399
|
'ROLE_ACCESS_DENIED', 'PERMISSION_DENIED', 'UNAUTHORIZED', 'FORBIDDEN',
|
|
@@ -386,6 +405,9 @@ const STABLE_CODES = new Set([
|
|
|
386
405
|
'RATE_LIMITED', 'CATALOG_STALE', 'DATA_MIGRATION_REQUIRED',
|
|
387
406
|
'INVALID_CLIENT', 'REMOTE_ACCESS_TOKEN_INVALID', 'ECWEB_TOKEN_INVALID', 'CLIENT_BUSY', 'INVALID_RESPONSE', 'TIMEOUT',
|
|
388
407
|
'RESPONSE_TOO_LARGE',
|
|
408
|
+
'TOPIC_SESSION_NOT_FOUND', 'TOPIC_SESSION_LOOKUP_FAILED',
|
|
409
|
+
'ROOT_NOT_FOUND', 'ROOT_FORBIDDEN', 'ROOT_EXPIRED', 'ROOT_SCOPE_MISMATCH', 'ROOT_PEER_MISMATCH',
|
|
410
|
+
'INVALID_ROOT_ID', 'MISSING_ROOT_ID', 'INVALID_ROOT_PATH', 'NOT_A_DIRECTORY', 'FILE_TOO_LARGE',
|
|
389
411
|
]);
|
|
390
412
|
export function normalizeMenuError(error) {
|
|
391
413
|
const source = error && typeof error === 'object' ? error : {};
|
|
@@ -436,6 +458,16 @@ export class MenuRequestDeduper {
|
|
|
436
458
|
this.ttlMs = ttlMs;
|
|
437
459
|
this.maxEntries = maxEntries;
|
|
438
460
|
}
|
|
461
|
+
/** Replace an acknowledged deferred operation's result after it fails. */
|
|
462
|
+
async replaceResult(key, fingerprint, previous, value) {
|
|
463
|
+
const entry = this.entries.get(key);
|
|
464
|
+
if (!entry || entry.fingerprint !== fingerprint || await entry.promise !== previous)
|
|
465
|
+
return;
|
|
466
|
+
if (this.entries.get(key) !== entry)
|
|
467
|
+
return;
|
|
468
|
+
entry.promise = Promise.resolve(value);
|
|
469
|
+
entry.expiresAt = Date.now() + this.ttlMs;
|
|
470
|
+
}
|
|
439
471
|
async execute(key, fingerprint, operation) {
|
|
440
472
|
this.prune();
|
|
441
473
|
const existing = this.entries.get(key);
|
|
@@ -510,14 +542,16 @@ const MAX_LOG_DEPTH = 8;
|
|
|
510
542
|
const MAX_LOG_KEYS = 100;
|
|
511
543
|
const MAX_LOG_ARRAY_ITEMS = 100;
|
|
512
544
|
const MAX_LOG_STRING_LENGTH = 4096;
|
|
513
|
-
const SENSITIVE_LOG_KEY = /(?:^|[_-])(?:api[_-]?key|access[_-]?token|refresh[_-]?token|menu[_-]?token|token|secret(?:[_-]?key)?|password|passwd|credentials?|authorization|cookie|private[_-]?key|seed)(?:$|[_-])/i;
|
|
545
|
+
const SENSITIVE_LOG_KEY = /(?:^|[_-])(?:api[_-]?key|access[_-]?token|refresh[_-]?token|menu[_-]?token|root[_-]?id|token|secret(?:[_-]?key)?|password|passwd|credentials?|authorization|cookie|private[_-]?key|seed)(?:$|[_-])/i;
|
|
514
546
|
const SENSITIVE_LOG_ARG = /(?:api[_-]?key|access[_-]?token|refresh[_-]?token|menu[_-]?token|token|secret|password|passwd|credential|authorization|cookie|private[_-]?key|seed)/i;
|
|
515
547
|
function isSensitiveLogKey(key) {
|
|
516
548
|
const normalized = key.replace(/([a-z0-9])([A-Z])/g, '$1_$2');
|
|
517
|
-
return SENSITIVE_LOG_KEY.test(normalized);
|
|
549
|
+
return SENSITIVE_LOG_KEY.test(normalized) || /^(?:next[_-]?)?cursor$|^(?:download[_-]?)?url$|^ticket$/i.test(normalized);
|
|
518
550
|
}
|
|
519
551
|
function sanitizeInlineLogSecrets(value) {
|
|
520
552
|
return value
|
|
553
|
+
.replace(/\b(?:sr1|sc1|dr1)\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g, '[REDACTED]')
|
|
554
|
+
.replace(/https?:\/\/[^\s"'<>]*[?&](?:t|token|signature|x-amz-signature)=[^\s"'<>]*/gi, '[REDACTED_URL]')
|
|
521
555
|
.replace(/\b(authorization\s*:\s*Bearer\s+)[^\s"',;]+/gi, '$1[REDACTED]')
|
|
522
556
|
.replace(/\bBearer\s+[^\s,;]+/gi, 'Bearer [REDACTED]')
|
|
523
557
|
.replace(/\b(api[_-]?key|access[_-]?token|refresh[_-]?token|menu[_-]?token|token|password|passwd|secret|credential|authorization|cookie)\s*([=:])\s*(?:"[^"]*"|'[^']*'|\S+)/gi, '$1$2[REDACTED]')
|
|
@@ -567,6 +601,11 @@ function sanitizeLogArgv(value, depth, seen) {
|
|
|
567
601
|
export function sanitizeMenuLogValue(value, key = '', depth = 0, seen = new WeakSet()) {
|
|
568
602
|
if (isSensitiveLogKey(key))
|
|
569
603
|
return '[REDACTED]';
|
|
604
|
+
// Pairing codes are intentionally returned as `code` on the wire for
|
|
605
|
+
// compatibility with /pair and the ECWeb API. Do not persist six-digit
|
|
606
|
+
// credentials in menu-protocol.log.
|
|
607
|
+
if (key === 'code' && typeof value === 'string' && /^\d{6}$/.test(value))
|
|
608
|
+
return '[REDACTED]';
|
|
570
609
|
if (value === null || value === undefined || typeof value === 'number' || typeof value === 'boolean')
|
|
571
610
|
return value;
|
|
572
611
|
if (typeof value === 'bigint')
|
|
@@ -4,6 +4,20 @@ import { agentDataDir } from '../../paths.js';
|
|
|
4
4
|
import { atomicReadJson, atomicWriteJson } from '../../utils/atomic-write.js';
|
|
5
5
|
export const DEFAULT_MENU_TOKEN_IDLE_TIMEOUT_SECONDS = 30 * 24 * 60 * 60;
|
|
6
6
|
export const MAX_MENU_TOKENS_PER_AGENT = 1_000;
|
|
7
|
+
function validInstallationId(value) {
|
|
8
|
+
return value === undefined || (typeof value === 'string' && value.length <= 256
|
|
9
|
+
&& !/[\u0000-\u001f\u007f]/.test(value));
|
|
10
|
+
}
|
|
11
|
+
function normalizeInstallation(value) {
|
|
12
|
+
if (!value || typeof value !== 'object' || !validInstallationId(value.deviceId)
|
|
13
|
+
|| !validInstallationId(value.slotId))
|
|
14
|
+
return null;
|
|
15
|
+
const deviceId = value.deviceId?.trim() || '';
|
|
16
|
+
const slotId = value.slotId?.trim() || '';
|
|
17
|
+
if (slotId && !deviceId)
|
|
18
|
+
return null;
|
|
19
|
+
return { deviceId, slotId };
|
|
20
|
+
}
|
|
7
21
|
function hashToken(token) {
|
|
8
22
|
return createHash('sha256').update(token).digest('hex');
|
|
9
23
|
}
|
|
@@ -13,6 +27,9 @@ function isTokenRecord(value) {
|
|
|
13
27
|
const record = value;
|
|
14
28
|
return typeof record.peerAid === 'string'
|
|
15
29
|
&& record.peerAid.trim().length > 0
|
|
30
|
+
&& validInstallationId(record.peerDeviceId)
|
|
31
|
+
&& validInstallationId(record.peerSlotId)
|
|
32
|
+
&& (!record.peerSlotId?.trim() || !!record.peerDeviceId?.trim())
|
|
16
33
|
&& typeof record.tokenHash === 'string'
|
|
17
34
|
&& /^[a-f0-9]{64}$/.test(record.tokenHash)
|
|
18
35
|
&& typeof record.requestedAt === 'number'
|
|
@@ -28,6 +45,10 @@ function isTokenRecord(value) {
|
|
|
28
45
|
function isExpired(record, now) {
|
|
29
46
|
return now - record.lastUsedAt >= record.idleTimeout * 1000;
|
|
30
47
|
}
|
|
48
|
+
function installationMatches(record, installation) {
|
|
49
|
+
return (record.peerDeviceId?.trim() || '') === (installation.deviceId?.trim() || '')
|
|
50
|
+
&& (record.peerSlotId?.trim() || '') === (installation.slotId?.trim() || '');
|
|
51
|
+
}
|
|
31
52
|
function hashesEqual(left, right) {
|
|
32
53
|
const leftBytes = Buffer.from(left, 'hex');
|
|
33
54
|
const rightBytes = Buffer.from(right, 'hex');
|
|
@@ -41,10 +62,14 @@ export class MenuTokenStore {
|
|
|
41
62
|
constructor(maxRecords = MAX_MENU_TOKENS_PER_AGENT) {
|
|
42
63
|
this.maxRecords = maxRecords;
|
|
43
64
|
}
|
|
44
|
-
issue(selfAid, peerAid, metadata = {}, now = Date.now()) {
|
|
65
|
+
issue(selfAid, peerAid, metadata = {}, installationOrNow = {}, now = Date.now()) {
|
|
66
|
+
const installation = normalizeInstallation(typeof installationOrNow === 'number' ? {} : installationOrNow);
|
|
67
|
+
if (!installation)
|
|
68
|
+
return null;
|
|
69
|
+
const issuedAt = typeof installationOrNow === 'number' ? installationOrNow : now;
|
|
45
70
|
const file = this.read(selfAid);
|
|
46
71
|
const idleTimeout = DEFAULT_MENU_TOKEN_IDLE_TIMEOUT_SECONDS;
|
|
47
|
-
const tokens = file.tokens.filter(record => record.peerAid !== peerAid && !isExpired(record,
|
|
72
|
+
const tokens = file.tokens.filter(record => (record.peerAid !== peerAid || !installationMatches(record, installation)) && !isExpired(record, issuedAt));
|
|
48
73
|
if (tokens.length >= this.maxRecords) {
|
|
49
74
|
if (tokens.length !== file.tokens.length)
|
|
50
75
|
this.write(selfAid, tokens);
|
|
@@ -53,9 +78,11 @@ export class MenuTokenStore {
|
|
|
53
78
|
const menuToken = `mt_${randomBytes(32).toString('base64url')}`;
|
|
54
79
|
tokens.push({
|
|
55
80
|
peerAid,
|
|
81
|
+
...(installation.deviceId?.trim() ? { peerDeviceId: installation.deviceId.trim() } : {}),
|
|
82
|
+
...(installation.slotId?.trim() ? { peerSlotId: installation.slotId.trim() } : {}),
|
|
56
83
|
tokenHash: hashToken(menuToken),
|
|
57
|
-
requestedAt:
|
|
58
|
-
lastUsedAt:
|
|
84
|
+
requestedAt: issuedAt,
|
|
85
|
+
lastUsedAt: issuedAt,
|
|
59
86
|
idleTimeout,
|
|
60
87
|
...(metadata.clientName ? { clientName: metadata.clientName } : {}),
|
|
61
88
|
...(metadata.clientVersion ? { clientVersion: metadata.clientVersion } : {}),
|
|
@@ -64,21 +91,27 @@ export class MenuTokenStore {
|
|
|
64
91
|
this.write(selfAid, tokens);
|
|
65
92
|
return { menuToken, idleTimeout };
|
|
66
93
|
}
|
|
67
|
-
use(selfAid, peerAid, menuToken, now = Date.now()) {
|
|
94
|
+
use(selfAid, peerAid, menuToken, installationOrNow = {}, now = Date.now()) {
|
|
95
|
+
const installation = normalizeInstallation(typeof installationOrNow === 'number' ? {} : installationOrNow);
|
|
96
|
+
if (!installation)
|
|
97
|
+
return false;
|
|
98
|
+
const usedAt = typeof installationOrNow === 'number' ? installationOrNow : now;
|
|
68
99
|
const file = this.read(selfAid);
|
|
69
|
-
const activeTokens = file.tokens.filter(record => !isExpired(record,
|
|
100
|
+
const activeTokens = file.tokens.filter(record => !isExpired(record, usedAt));
|
|
70
101
|
const tokenHash = typeof menuToken === 'string' && menuToken.length > 0 && menuToken.length <= 256
|
|
71
102
|
? hashToken(menuToken)
|
|
72
103
|
: undefined;
|
|
73
104
|
const matchingIndex = tokenHash
|
|
74
|
-
? activeTokens.findIndex(record => record.peerAid === peerAid
|
|
105
|
+
? activeTokens.findIndex(record => record.peerAid === peerAid
|
|
106
|
+
&& installationMatches(record, installation)
|
|
107
|
+
&& hashesEqual(record.tokenHash, tokenHash))
|
|
75
108
|
: -1;
|
|
76
109
|
if (matchingIndex < 0) {
|
|
77
110
|
if (activeTokens.length !== file.tokens.length)
|
|
78
111
|
this.write(selfAid, activeTokens);
|
|
79
112
|
return false;
|
|
80
113
|
}
|
|
81
|
-
activeTokens[matchingIndex] = { ...activeTokens[matchingIndex], lastUsedAt:
|
|
114
|
+
activeTokens[matchingIndex] = { ...activeTokens[matchingIndex], lastUsedAt: usedAt };
|
|
82
115
|
this.write(selfAid, activeTokens);
|
|
83
116
|
return true;
|
|
84
117
|
}
|
|
@@ -16,9 +16,9 @@ import { fileCache } from '../daemon-file-cache.js';
|
|
|
16
16
|
import { currentVersion } from '../../config/schema-registry.js';
|
|
17
17
|
import { loadSchema } from '../../config/schema-registry.js';
|
|
18
18
|
import { rolePermissionFields, rolePermissionFieldOptions, rolePermissionFieldPatterns, validateRoleConfig, } from '../../config/role-schema.js';
|
|
19
|
-
import { groupInfo, groupList, groupDirectoryErrorCode } from '../../aun/
|
|
19
|
+
import { groupInfo, groupList, groupDirectoryErrorCode } from '../../aun/group/index.js';
|
|
20
20
|
import { aidLookup, isValidAid } from '../../aun/aid/identity.js';
|
|
21
|
-
import { isExplicitGroupId } from '../../aun/group
|
|
21
|
+
import { isExplicitGroupId } from '../../aun/group/index.js';
|
|
22
22
|
import { readJsonFile, readLastJsonlLine, scanChatDirs, scanMetaFiles } from '../session/session-fs-store.js';
|
|
23
23
|
import { constrainResolvedModelForRole } from '../model/model-permission.js';
|
|
24
24
|
import { resolveRuntimePermissionMode, resolveRuntimeStringField } from '../role/runtime-policy.js';
|
|
@@ -45,7 +45,8 @@ export function probeSessionActivity(evidence, probes) {
|
|
|
45
45
|
// 支持的命令列表
|
|
46
46
|
const commands = ['/new', '/pwd', '/help', '/evolhelp', '/status', '/restart', '/reload', '/model', '/effort', '/baseagent', '/slist', '/session', '/rename', '/stop', '/pause', '/compact', '/renew', '/repair', '/fork', '/del', '/perm', '/file', '/check', '/rewind', '/activity', '/observable', '/chatmode', '/mentionmode', '/ask', '/resume', '/aid', '/rpc', '/storage', '/agent', '/trigger', '/upgrade', '/pair'];
|
|
47
47
|
const deprecatedCommands = ['/clear'];
|
|
48
|
-
|
|
48
|
+
commands.push('/diag');
|
|
49
|
+
const exactBoundaryCommands = new Set(['/pause', '/resume', '/stop', '/pair', '/diag']);
|
|
49
50
|
/** Parse the execution command without treating it as a quick/result command. */
|
|
50
51
|
export function parseFullAccessCommand(content) {
|
|
51
52
|
const match = content.match(/^\s*(\/fa|\/fullaccess)(?=\s|$)([\s\S]*)$/);
|
|
@@ -64,8 +65,37 @@ const aliases = {
|
|
|
64
65
|
'/rw': '/rewind',
|
|
65
66
|
'/base': '/baseagent',
|
|
66
67
|
};
|
|
68
|
+
const GROUP_READ_ONLY_COMMANDS = new Set(['/mentionmode', '/model', '/effort', '/perm', '/baseagent']);
|
|
69
|
+
const GROUP_TASK_COMMANDS = new Set([
|
|
70
|
+
'/help', '/evolhelp', '/status', '/check', '/ask', '/pause', '/resume', '/stop', '/compact', '/renew',
|
|
71
|
+
]);
|
|
72
|
+
/** Group slash policy applies to every role, including old command-card clicks. */
|
|
73
|
+
export function guardGroupSlashCommand(content, chatType) {
|
|
74
|
+
if (chatType !== 'group' || !content.trim().startsWith('/'))
|
|
75
|
+
return undefined;
|
|
76
|
+
const [inputCommand, ...args] = content.trim().split(/\s+/);
|
|
77
|
+
const command = aliases[inputCommand] ?? inputCommand;
|
|
78
|
+
if (GROUP_READ_ONLY_COMMANDS.has(command)) {
|
|
79
|
+
if (!args.length || (command === '/model' && args.length === 1 && ['current', 'list', 'check'].includes(args[0]))) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
kind: 'command.error',
|
|
84
|
+
text: `❌ 群聊中 ${command} 仅支持查询,请在私聊或管理界面操作`,
|
|
85
|
+
reason: 'GROUP_COMMAND_READ_ONLY',
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (GROUP_TASK_COMMANDS.has(command))
|
|
89
|
+
return undefined;
|
|
90
|
+
return {
|
|
91
|
+
kind: 'command.error',
|
|
92
|
+
text: `❌ 群聊中不支持 ${inputCommand},输入 /help 查看可用命令`,
|
|
93
|
+
reason: 'GROUP_COMMAND_UNSUPPORTED',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
67
96
|
// 命令快速路径前缀(所有命令都不进入消息队列)
|
|
68
97
|
const quickCommandPrefixes = ['/new', '/pwd', '/help', '/evolhelp', '/status', '/restart', '/reload', '/model', '/effort', '/baseagent', '/slist', '/session', '/rename', '/repair', '/fork', '/stop', '/pause', '/clear', '/compact', '/renew', '/del', '/perm', '/file', '/check', '/s ', '/name', '/rewind', '/rw', '/rw ', '/activity', '/observable', '/chatmode', '/mentionmode', '/ask', '/resume', '/base ', '/aid', '/rpc', '/storage', '/agent', '/trigger', '/upgrade', '/pair'];
|
|
98
|
+
quickCommandPrefixes.push('/diag');
|
|
69
99
|
/**
|
|
70
100
|
* 计算两个字符串的 Levenshtein 距离(编辑距离)
|
|
71
101
|
*/
|
|
@@ -95,7 +125,7 @@ function levenshteinDistance(str1, str2) {
|
|
|
95
125
|
return matrix[len1][len2];
|
|
96
126
|
}
|
|
97
127
|
export function isQuickCommand(content) {
|
|
98
|
-
return content === '/s' || quickCommandPrefixes.some(cmd => exactBoundaryCommands.has(cmd)
|
|
128
|
+
return content === '/s' || content === '/base' || quickCommandPrefixes.some(cmd => exactBoundaryCommands.has(cmd)
|
|
99
129
|
? content === cmd || content.startsWith(cmd + ' ')
|
|
100
130
|
: content.startsWith(cmd));
|
|
101
131
|
}
|
|
@@ -131,7 +161,7 @@ export function guardRoleCommand(content, activeChatType, isAdmin) {
|
|
|
131
161
|
const userGroupCommands = [
|
|
132
162
|
'/status', '/help', '/evolhelp', '/check', '/chatmode', '/mentionmode',
|
|
133
163
|
'/model', '/effort', '/baseagent', '/perm', '/activity', '/stop', '/pause',
|
|
134
|
-
'/resume', '/trigger', '/file',
|
|
164
|
+
'/resume', '/trigger', '/file', '/ask',
|
|
135
165
|
];
|
|
136
166
|
const userCommands = activeChatType === 'group' && !isAdmin
|
|
137
167
|
? userGroupCommands
|
|
@@ -146,7 +176,7 @@ export function guardRoleCommand(content, activeChatType, isAdmin) {
|
|
|
146
176
|
return {
|
|
147
177
|
kind: 'command.error',
|
|
148
178
|
text: activeChatType === 'group'
|
|
149
|
-
? '❌
|
|
179
|
+
? '❌ 无权限:此命令仅限管理员使用,输入 /help 查看可用命令'
|
|
150
180
|
: '❌ 无权限:此命令仅限管理员使用',
|
|
151
181
|
};
|
|
152
182
|
}
|