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.
Files changed (213) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +37 -3
  3. package/dist/agents/baseagent.js +111 -19
  4. package/dist/agents/claude-runner.js +30 -2
  5. package/dist/agents/codex-app-server-client.js +31 -0
  6. package/dist/agents/codex-runner.js +3 -0
  7. package/dist/aun/msg/group.js +9 -9
  8. package/dist/aun/msg/p2p.js +11 -6
  9. package/dist/aun/msg/upload.js +43 -29
  10. package/dist/aun/outbox.js +48 -5
  11. package/dist/channels/aun.js +199 -50
  12. package/dist/cli/aun-commands.js +10 -7
  13. package/dist/cli/daemon-commands.js +19 -4
  14. package/dist/cli/index.js +11 -1
  15. package/dist/cli/init.js +103 -4
  16. package/dist/cli/model.js +5 -5
  17. package/dist/config/builtin-role-templates.js +4 -3
  18. package/dist/config/config-field-policy.js +6 -2
  19. package/dist/config/config-manager.js +48 -11
  20. package/dist/config/role-schema.js +18 -3
  21. package/dist/config/role-service.js +3 -3
  22. package/dist/config/role-store.js +4 -3
  23. package/dist/config-store.js +4 -0
  24. package/dist/core/auth/operation-authorizer.js +3 -1
  25. package/dist/core/bootstrap-service.js +0 -12
  26. package/dist/core/channel-loader.js +5 -1
  27. package/dist/core/command/command-handler.js +1 -1
  28. package/dist/core/command/evol-menu-version-gate.js +3 -2
  29. package/dist/core/command/menu-handler.js +33 -22
  30. package/dist/core/command/menu-protocol.js +7 -4
  31. package/dist/core/command/slash-handler.js +4 -4
  32. package/dist/core/inference/text-inference.js +18 -5
  33. package/dist/core/message/message-bridge.js +17 -6
  34. package/dist/core/message/response-engine.js +22 -3
  35. package/dist/core/model/config-scope.js +3 -3
  36. package/dist/core/permission/tool-policy.js +18 -0
  37. package/dist/index.js +43 -26
  38. package/dist/ipc.js +1 -1
  39. package/dist/product.js +1 -0
  40. package/dist/utils/autostart.js +27 -0
  41. package/dist/utils/ecweb-utils.js +15 -2
  42. package/dist/utils/macos-autostart.js +179 -0
  43. package/dist/utils/windows-autostart.js +130 -0
  44. package/ecagent/dist/agent-loop.d.ts +1 -1
  45. package/ecagent/dist/agent-loop.js +1 -1
  46. package/ecagent/dist/agent.d.ts +1 -1
  47. package/ecagent/dist/agent.js +1 -1
  48. package/ecagent/dist/harness/agent-harness.d.ts +1 -1
  49. package/ecagent/dist/harness/compaction/branch-summarization.d.ts +1 -1
  50. package/ecagent/dist/harness/compaction/compaction.d.ts +1 -1
  51. package/ecagent/dist/harness/compaction/utils.d.ts +1 -1
  52. package/ecagent/dist/harness/messages.d.ts +1 -1
  53. package/ecagent/dist/harness/session/session.d.ts +1 -1
  54. package/ecagent/dist/harness/types.d.ts +1 -1
  55. package/ecagent/dist/proxy.d.ts +1 -1
  56. package/ecagent/dist/proxy.js +1 -1
  57. package/ecagent/dist/types.d.ts +1 -1
  58. package/kits/migrations/migrate-role-config-v5.mjs +27 -2
  59. package/kits/schemas/agent-config.schema.10.json +19 -1
  60. package/kits/schemas/daemon.schema.4.json +4 -0
  61. package/kits/schemas/defaults.schema.4.json +15 -1
  62. package/kits/schemas/relation-config.schema.8.json +22 -1
  63. package/kits/schemas/role-config.schema.1.json +2 -2
  64. package/package.json +2 -4
  65. package/ecagent/dist/agent-loop.d.ts.map +0 -1
  66. package/ecagent/dist/agent-loop.js.map +0 -1
  67. package/ecagent/dist/agent.d.ts.map +0 -1
  68. package/ecagent/dist/agent.js.map +0 -1
  69. package/ecagent/dist/harness/agent-harness.d.ts.map +0 -1
  70. package/ecagent/dist/harness/agent-harness.js.map +0 -1
  71. package/ecagent/dist/harness/compaction/branch-summarization.d.ts.map +0 -1
  72. package/ecagent/dist/harness/compaction/branch-summarization.js.map +0 -1
  73. package/ecagent/dist/harness/compaction/compaction.d.ts.map +0 -1
  74. package/ecagent/dist/harness/compaction/compaction.js.map +0 -1
  75. package/ecagent/dist/harness/compaction/utils.d.ts.map +0 -1
  76. package/ecagent/dist/harness/compaction/utils.js.map +0 -1
  77. package/ecagent/dist/harness/env/nodejs.d.ts.map +0 -1
  78. package/ecagent/dist/harness/env/nodejs.js.map +0 -1
  79. package/ecagent/dist/harness/messages.d.ts.map +0 -1
  80. package/ecagent/dist/harness/messages.js.map +0 -1
  81. package/ecagent/dist/harness/prompt-templates.d.ts.map +0 -1
  82. package/ecagent/dist/harness/prompt-templates.js.map +0 -1
  83. package/ecagent/dist/harness/session/jsonl-repo.d.ts.map +0 -1
  84. package/ecagent/dist/harness/session/jsonl-repo.js.map +0 -1
  85. package/ecagent/dist/harness/session/jsonl-storage.d.ts.map +0 -1
  86. package/ecagent/dist/harness/session/jsonl-storage.js.map +0 -1
  87. package/ecagent/dist/harness/session/memory-repo.d.ts.map +0 -1
  88. package/ecagent/dist/harness/session/memory-repo.js.map +0 -1
  89. package/ecagent/dist/harness/session/memory-storage.d.ts.map +0 -1
  90. package/ecagent/dist/harness/session/memory-storage.js.map +0 -1
  91. package/ecagent/dist/harness/session/repo-utils.d.ts.map +0 -1
  92. package/ecagent/dist/harness/session/repo-utils.js.map +0 -1
  93. package/ecagent/dist/harness/session/session.d.ts.map +0 -1
  94. package/ecagent/dist/harness/session/session.js.map +0 -1
  95. package/ecagent/dist/harness/session/uuid.d.ts.map +0 -1
  96. package/ecagent/dist/harness/session/uuid.js.map +0 -1
  97. package/ecagent/dist/harness/skills.d.ts.map +0 -1
  98. package/ecagent/dist/harness/skills.js.map +0 -1
  99. package/ecagent/dist/harness/system-prompt.d.ts.map +0 -1
  100. package/ecagent/dist/harness/system-prompt.js.map +0 -1
  101. package/ecagent/dist/harness/types.d.ts.map +0 -1
  102. package/ecagent/dist/harness/types.js.map +0 -1
  103. package/ecagent/dist/harness/utils/shell-output.d.ts.map +0 -1
  104. package/ecagent/dist/harness/utils/shell-output.js.map +0 -1
  105. package/ecagent/dist/harness/utils/truncate.d.ts.map +0 -1
  106. package/ecagent/dist/harness/utils/truncate.js.map +0 -1
  107. package/ecagent/dist/index.d.ts.map +0 -1
  108. package/ecagent/dist/index.js.map +0 -1
  109. package/ecagent/dist/node.d.ts.map +0 -1
  110. package/ecagent/dist/node.js.map +0 -1
  111. package/ecagent/dist/proxy.d.ts.map +0 -1
  112. package/ecagent/dist/proxy.js.map +0 -1
  113. package/ecagent/dist/runtime/api/lazy.d.ts.map +0 -1
  114. package/ecagent/dist/runtime/api/lazy.js.map +0 -1
  115. package/ecagent/dist/runtime/api/pi-messages.d.ts.map +0 -1
  116. package/ecagent/dist/runtime/api/pi-messages.js.map +0 -1
  117. package/ecagent/dist/runtime/api/pi-messages.lazy.d.ts.map +0 -1
  118. package/ecagent/dist/runtime/api/pi-messages.lazy.js.map +0 -1
  119. package/ecagent/dist/runtime/auth/context.d.ts.map +0 -1
  120. package/ecagent/dist/runtime/auth/context.js.map +0 -1
  121. package/ecagent/dist/runtime/auth/credential-store.d.ts.map +0 -1
  122. package/ecagent/dist/runtime/auth/credential-store.js.map +0 -1
  123. package/ecagent/dist/runtime/auth/helpers.d.ts.map +0 -1
  124. package/ecagent/dist/runtime/auth/helpers.js.map +0 -1
  125. package/ecagent/dist/runtime/auth/resolve.d.ts.map +0 -1
  126. package/ecagent/dist/runtime/auth/resolve.js.map +0 -1
  127. package/ecagent/dist/runtime/auth/types.d.ts.map +0 -1
  128. package/ecagent/dist/runtime/auth/types.js.map +0 -1
  129. package/ecagent/dist/runtime/compat.d.ts.map +0 -1
  130. package/ecagent/dist/runtime/compat.js.map +0 -1
  131. package/ecagent/dist/runtime/index.d.ts.map +0 -1
  132. package/ecagent/dist/runtime/index.js.map +0 -1
  133. package/ecagent/dist/runtime/models.d.ts.map +0 -1
  134. package/ecagent/dist/runtime/models.js.map +0 -1
  135. package/ecagent/dist/runtime/oauth.d.ts.map +0 -1
  136. package/ecagent/dist/runtime/oauth.js.map +0 -1
  137. package/ecagent/dist/runtime/providers/faux.d.ts.map +0 -1
  138. package/ecagent/dist/runtime/providers/faux.js.map +0 -1
  139. package/ecagent/dist/runtime/types.d.ts.map +0 -1
  140. package/ecagent/dist/runtime/types.js.map +0 -1
  141. package/ecagent/dist/runtime/utils/diagnostics.d.ts.map +0 -1
  142. package/ecagent/dist/runtime/utils/diagnostics.js.map +0 -1
  143. package/ecagent/dist/runtime/utils/event-stream.d.ts.map +0 -1
  144. package/ecagent/dist/runtime/utils/event-stream.js.map +0 -1
  145. package/ecagent/dist/runtime/utils/headers.d.ts.map +0 -1
  146. package/ecagent/dist/runtime/utils/headers.js.map +0 -1
  147. package/ecagent/dist/runtime/utils/json-parse.d.ts.map +0 -1
  148. package/ecagent/dist/runtime/utils/json-parse.js.map +0 -1
  149. package/ecagent/dist/runtime/utils/oauth/types.d.ts.map +0 -1
  150. package/ecagent/dist/runtime/utils/oauth/types.js.map +0 -1
  151. package/ecagent/dist/runtime/utils/overflow.d.ts.map +0 -1
  152. package/ecagent/dist/runtime/utils/overflow.js.map +0 -1
  153. package/ecagent/dist/runtime/utils/provider-env.d.ts.map +0 -1
  154. package/ecagent/dist/runtime/utils/provider-env.js.map +0 -1
  155. package/ecagent/dist/runtime/utils/retry.d.ts.map +0 -1
  156. package/ecagent/dist/runtime/utils/retry.js.map +0 -1
  157. package/ecagent/dist/runtime/utils/typebox-helpers.d.ts.map +0 -1
  158. package/ecagent/dist/runtime/utils/typebox-helpers.js.map +0 -1
  159. package/ecagent/dist/runtime/utils/validation.d.ts.map +0 -1
  160. package/ecagent/dist/runtime/utils/validation.js.map +0 -1
  161. package/ecagent/dist/types.d.ts.map +0 -1
  162. package/ecagent/dist/types.js.map +0 -1
  163. package/ecagent/package.json +0 -93
  164. package/ecagent/src/agent-loop.ts +0 -792
  165. package/ecagent/src/agent.ts +0 -575
  166. package/ecagent/src/harness/agent-harness.ts +0 -1029
  167. package/ecagent/src/harness/compaction/branch-summarization.ts +0 -261
  168. package/ecagent/src/harness/compaction/compaction.ts +0 -753
  169. package/ecagent/src/harness/compaction/utils.ts +0 -144
  170. package/ecagent/src/harness/env/nodejs.ts +0 -569
  171. package/ecagent/src/harness/messages.ts +0 -164
  172. package/ecagent/src/harness/prompt-templates.ts +0 -267
  173. package/ecagent/src/harness/session/jsonl-repo.ts +0 -179
  174. package/ecagent/src/harness/session/jsonl-storage.ts +0 -314
  175. package/ecagent/src/harness/session/memory-repo.ts +0 -50
  176. package/ecagent/src/harness/session/memory-storage.ts +0 -133
  177. package/ecagent/src/harness/session/repo-utils.ts +0 -51
  178. package/ecagent/src/harness/session/session.ts +0 -338
  179. package/ecagent/src/harness/session/uuid.ts +0 -54
  180. package/ecagent/src/harness/skills.ts +0 -375
  181. package/ecagent/src/harness/system-prompt.ts +0 -34
  182. package/ecagent/src/harness/types.ts +0 -838
  183. package/ecagent/src/harness/utils/shell-output.ts +0 -135
  184. package/ecagent/src/harness/utils/truncate.ts +0 -344
  185. package/ecagent/src/index.ts +0 -46
  186. package/ecagent/src/node.ts +0 -2
  187. package/ecagent/src/proxy.ts +0 -367
  188. package/ecagent/src/runtime/api/lazy.ts +0 -70
  189. package/ecagent/src/runtime/api/pi-messages.lazy.ts +0 -4
  190. package/ecagent/src/runtime/api/pi-messages.ts +0 -436
  191. package/ecagent/src/runtime/auth/context.ts +0 -45
  192. package/ecagent/src/runtime/auth/credential-store.ts +0 -47
  193. package/ecagent/src/runtime/auth/helpers.ts +0 -46
  194. package/ecagent/src/runtime/auth/resolve.ts +0 -141
  195. package/ecagent/src/runtime/auth/types.ts +0 -182
  196. package/ecagent/src/runtime/compat.ts +0 -158
  197. package/ecagent/src/runtime/index.ts +0 -31
  198. package/ecagent/src/runtime/models.ts +0 -452
  199. package/ecagent/src/runtime/oauth.ts +0 -1
  200. package/ecagent/src/runtime/providers/faux.ts +0 -538
  201. package/ecagent/src/runtime/types.ts +0 -718
  202. package/ecagent/src/runtime/utils/diagnostics.ts +0 -45
  203. package/ecagent/src/runtime/utils/event-stream.ts +0 -88
  204. package/ecagent/src/runtime/utils/headers.ts +0 -18
  205. package/ecagent/src/runtime/utils/json-parse.ts +0 -124
  206. package/ecagent/src/runtime/utils/oauth/types.ts +0 -79
  207. package/ecagent/src/runtime/utils/overflow.ts +0 -165
  208. package/ecagent/src/runtime/utils/provider-env.ts +0 -52
  209. package/ecagent/src/runtime/utils/retry.ts +0 -101
  210. package/ecagent/src/runtime/utils/typebox-helpers.ts +0 -24
  211. package/ecagent/src/runtime/utils/validation.ts +0 -310
  212. package/ecagent/src/types.ts +0 -430
  213. package/ecagent/tsconfig.build.json +0 -32
package/dist/ipc.js CHANGED
@@ -519,7 +519,7 @@ export class IpcServer {
519
519
  mentions: Array.isArray(cmd.mentions)
520
520
  ? cmd.mentions.filter((entry) => !!entry && typeof entry === 'object' && !Array.isArray(entry))
521
521
  : undefined,
522
- encrypt: cmd.encrypt === true,
522
+ encrypt: typeof cmd.encrypt === 'boolean' ? cmd.encrypt : undefined,
523
523
  thread: typeof cmd.thread === 'string' ? cmd.thread : undefined,
524
524
  returnPolicy: cmd.returnPolicy === 'required' || cmd.returnPolicy === 'none' ? cmd.returnPolicy : undefined,
525
525
  originSessionId: typeof cmd.originSessionId === 'string' ? cmd.originSessionId : undefined,
package/dist/product.js CHANGED
@@ -10,6 +10,7 @@ export const MAIN_CLI_BIN = 'ec';
10
10
  export const WEB_PACKAGE_NAME = 'ec-web';
11
11
  export const WEB_CLI_BIN = 'ec-web';
12
12
  export const WEB_PACKAGE_LATEST = `${WEB_PACKAGE_NAME}@latest`;
13
+ export const MIN_ECWEB_VERSION = '0.0.8';
13
14
  export const DAEMON_CONFIG_FILENAME = 'daemon.json';
14
15
  export const DAEMON_SCHEMA_NAME = 'daemon';
15
16
  export const RUNTIME_HOME_ENV = 'EVOLCORE_HOME';
@@ -0,0 +1,27 @@
1
+ import { configureMacosAutostart, macosAutostartInstalled } from './macos-autostart.js';
2
+ import { configureWindowsAutostart, windowsAutostartInstalled } from './windows-autostart.js';
3
+ export function autostartInstalled() {
4
+ if (process.platform === 'win32')
5
+ return windowsAutostartInstalled();
6
+ if (process.platform === 'darwin')
7
+ return macosAutostartInstalled();
8
+ return false;
9
+ }
10
+ export function configureAutostart(enabled, runtimeRoot) {
11
+ if (process.platform === 'win32')
12
+ return configureWindowsAutostart(enabled, runtimeRoot);
13
+ if (process.platform === 'darwin')
14
+ return configureMacosAutostart(enabled, runtimeRoot);
15
+ return {
16
+ ok: !enabled,
17
+ enabled: false,
18
+ ...(!enabled ? {} : { error: '登录自启仅支持 Windows 和 macOS 主机' }),
19
+ };
20
+ }
21
+ export function autostartPlatformLabel() {
22
+ if (process.platform === 'win32')
23
+ return 'Windows';
24
+ if (process.platform === 'darwin')
25
+ return 'macOS';
26
+ return undefined;
27
+ }
@@ -1,8 +1,21 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import { resolveGlobalPkg } from './npm-ops.js';
3
+ import { compareVersions, resolveGlobalPkg } from './npm-ops.js';
4
4
  import { isWindows as platformIsWindows, resolveCommandPath } from './cross-platform.js';
5
- import { WEB_CLI_BIN, WEB_PACKAGE_NAME } from '../product.js';
5
+ import { MIN_ECWEB_VERSION, WEB_CLI_BIN, WEB_PACKAGE_NAME } from '../product.js';
6
+ /** EC Web owns the session-log reader, so older builds cannot safely serve a newer daemon. */
7
+ export function isEcwebVersionSupported(version) {
8
+ const normalized = version?.trim();
9
+ if (!normalized || !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(normalized))
10
+ return false;
11
+ return compareVersions(normalized, MIN_ECWEB_VERSION) >= 0;
12
+ }
13
+ export function ecwebVersionRequirementError(version) {
14
+ if (isEcwebVersionSupported(version))
15
+ return null;
16
+ const detected = version?.trim() || 'unknown';
17
+ return `EC Web ${detected} 低于最低要求 ${MIN_ECWEB_VERSION},拒绝启动。请运行: npm install -g ${WEB_PACKAGE_NAME}@latest`;
18
+ }
6
19
  function readEcwebPackageEntry(pkgJsonPath) {
7
20
  try {
8
21
  const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
@@ -0,0 +1,179 @@
1
+ import fs from 'fs';
2
+ import os from 'os';
3
+ import path from 'path';
4
+ import { spawnSync } from 'child_process';
5
+ import { getPackageRoot } from '../paths.js';
6
+ export const MACOS_AUTOSTART_LABEL = 'cn.evolai.evolcore';
7
+ function isMacos() {
8
+ return process.platform === 'darwin';
9
+ }
10
+ function plistPath() {
11
+ return path.join(os.homedir(), 'Library', 'LaunchAgents', `${MACOS_AUTOSTART_LABEL}.plist`);
12
+ }
13
+ function launchctl(args) {
14
+ return spawnSync('/bin/launchctl', args, {
15
+ encoding: 'utf8',
16
+ timeout: 15_000,
17
+ });
18
+ }
19
+ function commandError(result, fallback) {
20
+ return String(result.error?.message || result.stderr || result.stdout || fallback).trim();
21
+ }
22
+ function guiDomain() {
23
+ const uid = process.getuid?.();
24
+ return uid === undefined ? undefined : `gui/${uid}`;
25
+ }
26
+ function xmlLiteral(value) {
27
+ return value
28
+ .replace(/&/g, '&')
29
+ .replace(/</g, '&lt;')
30
+ .replace(/>/g, '&gt;')
31
+ .replace(/"/g, '&quot;')
32
+ .replace(/'/g, '&apos;');
33
+ }
34
+ function createPlist(runtimeRoot) {
35
+ const absoluteRoot = path.resolve(runtimeRoot);
36
+ const cliEntry = path.join(getPackageRoot(), 'dist', 'cli', 'index.js');
37
+ if (!fs.existsSync(cliEntry)) {
38
+ throw new Error(`找不到 EvolCore CLI 入口: ${cliEntry}`);
39
+ }
40
+ const environment = [
41
+ ['EVOLCORE_HOME', absoluteRoot],
42
+ ['HOME', os.homedir()],
43
+ ['PATH', Array.from(new Set([
44
+ path.dirname(process.execPath),
45
+ ...(process.env.PATH ?? '').split(path.delimiter).filter(Boolean),
46
+ ])).join(path.delimiter)],
47
+ ];
48
+ const environmentXml = environment
49
+ .map(([key, value]) => ` <key>${xmlLiteral(key)}</key>\n <string>${xmlLiteral(value)}</string>`)
50
+ .join('\n');
51
+ const args = [process.execPath, '--no-warnings=ExperimentalWarning', cliEntry, 'start']
52
+ .map(value => ` <string>${xmlLiteral(value)}</string>`)
53
+ .join('\n');
54
+ return `<?xml version="1.0" encoding="UTF-8"?>
55
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
56
+ <plist version="1.0">
57
+ <dict>
58
+ <key>Label</key>
59
+ <string>${xmlLiteral(MACOS_AUTOSTART_LABEL)}</string>
60
+ <key>ProgramArguments</key>
61
+ <array>
62
+ ${args}
63
+ </array>
64
+ <key>EnvironmentVariables</key>
65
+ <dict>
66
+ ${environmentXml}
67
+ </dict>
68
+ <key>RunAtLoad</key>
69
+ <true/>
70
+ <key>StandardOutPath</key>
71
+ <string>${xmlLiteral(path.join(absoluteRoot, 'logs', 'autostart.stdout.log'))}</string>
72
+ <key>StandardErrorPath</key>
73
+ <string>${xmlLiteral(path.join(absoluteRoot, 'logs', 'autostart.stderr.log'))}</string>
74
+ </dict>
75
+ </plist>
76
+ `;
77
+ }
78
+ function restorePlist(file, previous) {
79
+ try {
80
+ if (previous === undefined)
81
+ fs.rmSync(file, { force: true });
82
+ else
83
+ fs.writeFileSync(file, previous, { encoding: 'utf8', mode: 0o600 });
84
+ return undefined;
85
+ }
86
+ catch (error) {
87
+ return error instanceof Error ? error.message : String(error);
88
+ }
89
+ }
90
+ export function macosAutostartInstalled() {
91
+ if (!isMacos())
92
+ return false;
93
+ const domain = guiDomain();
94
+ if (!domain)
95
+ return false;
96
+ const result = launchctl(['print', `${domain}/${MACOS_AUTOSTART_LABEL}`]);
97
+ return result.status === 0;
98
+ }
99
+ export function configureMacosAutostart(enabled, runtimeRoot) {
100
+ if (!isMacos()) {
101
+ return {
102
+ ok: !enabled,
103
+ enabled: false,
104
+ ...(!enabled ? {} : { error: 'macOS 登录自启仅支持 macOS 主机' }),
105
+ };
106
+ }
107
+ const domain = guiDomain();
108
+ if (!domain) {
109
+ return { ok: false, enabled: false, error: '无法确定当前 macOS 用户 UID' };
110
+ }
111
+ const file = plistPath();
112
+ if (!enabled) {
113
+ const result = launchctl(['bootout', `${domain}/${MACOS_AUTOSTART_LABEL}`]);
114
+ if (result.status !== 0 && macosAutostartInstalled()) {
115
+ return {
116
+ ok: false,
117
+ enabled: true,
118
+ error: commandError(result, '删除 macOS 登录自启失败'),
119
+ };
120
+ }
121
+ try {
122
+ fs.rmSync(file, { force: true });
123
+ }
124
+ catch (error) {
125
+ // Keep the previous state coherent: a LaunchAgents plist that cannot be
126
+ // removed would otherwise silently re-enable the job at the next login.
127
+ const restored = launchctl(['bootstrap', domain, file]);
128
+ return {
129
+ ok: false,
130
+ enabled: restored.status === 0 || macosAutostartInstalled(),
131
+ error: `删除 macOS 登录自启配置失败: ${error instanceof Error ? error.message : String(error)}`,
132
+ };
133
+ }
134
+ return { ok: true, enabled: false };
135
+ }
136
+ let previousPlist;
137
+ let previouslyInstalled = false;
138
+ try {
139
+ const absoluteRoot = path.resolve(runtimeRoot);
140
+ if (fs.existsSync(file)) {
141
+ previousPlist = fs.readFileSync(file, 'utf8');
142
+ previouslyInstalled = macosAutostartInstalled();
143
+ }
144
+ fs.mkdirSync(path.join(absoluteRoot, 'logs'), { recursive: true });
145
+ fs.mkdirSync(path.dirname(file), { recursive: true });
146
+ fs.writeFileSync(file, createPlist(absoluteRoot), { encoding: 'utf8', mode: 0o600 });
147
+ // Re-bootstrap so repeated `ec init --auto-start` updates the command and paths.
148
+ launchctl(['bootout', `${domain}/${MACOS_AUTOSTART_LABEL}`]);
149
+ const result = launchctl(['bootstrap', domain, file]);
150
+ if (result.status !== 0) {
151
+ const restoreError = restorePlist(file, previousPlist);
152
+ let restored = false;
153
+ if (!restoreError && previouslyInstalled && previousPlist !== undefined) {
154
+ const restoreResult = launchctl(['bootstrap', domain, file]);
155
+ restored = restoreResult.status === 0 || macosAutostartInstalled();
156
+ }
157
+ else if (!previouslyInstalled) {
158
+ // A failed bootstrap may still have partially loaded the job.
159
+ launchctl(['bootout', `${domain}/${MACOS_AUTOSTART_LABEL}`]);
160
+ }
161
+ const rollbackSuffix = restoreError ? `; 恢复原配置失败: ${restoreError}` : '';
162
+ return {
163
+ ok: false,
164
+ enabled: restored,
165
+ error: `${commandError(result, '创建 macOS 登录自启失败')}${rollbackSuffix}`,
166
+ };
167
+ }
168
+ return { ok: true, enabled: true };
169
+ }
170
+ catch (error) {
171
+ const restoreError = restorePlist(file, previousPlist);
172
+ const rollbackSuffix = restoreError ? `; 恢复原配置失败: ${restoreError}` : '';
173
+ return {
174
+ ok: false,
175
+ enabled: previouslyInstalled,
176
+ error: `${error instanceof Error ? error.message : String(error)}${rollbackSuffix}`,
177
+ };
178
+ }
179
+ }
@@ -0,0 +1,130 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { spawnSync } from 'child_process';
4
+ import { getPackageRoot } from '../paths.js';
5
+ export const WINDOWS_AUTOSTART_TASK_NAME = 'EvolCore';
6
+ function isWindows() {
7
+ return process.platform === 'win32';
8
+ }
9
+ function runSchtasks(args) {
10
+ return spawnSync('schtasks.exe', args, {
11
+ encoding: 'utf8',
12
+ windowsHide: true,
13
+ timeout: 15_000,
14
+ });
15
+ }
16
+ function commandError(result, fallback) {
17
+ return String(result.error?.message || result.stderr || result.stdout || fallback).trim();
18
+ }
19
+ function powershellLiteral(value) {
20
+ return `'${value.replace(/'/g, "''")}'`;
21
+ }
22
+ function windowsCommandLiteral(value) {
23
+ return `"${value}"`;
24
+ }
25
+ function wrapperPath(runtimeRoot) {
26
+ return path.join(runtimeRoot, 'data', 'evolcore-autostart.ps1');
27
+ }
28
+ export function windowsAutostartInstalled() {
29
+ if (!isWindows())
30
+ return false;
31
+ const result = runSchtasks(['/Query', '/TN', WINDOWS_AUTOSTART_TASK_NAME]);
32
+ return result.status === 0;
33
+ }
34
+ function createWrapper(runtimeRoot) {
35
+ const scriptPath = wrapperPath(runtimeRoot);
36
+ const cliEntry = path.join(getPackageRoot(), 'dist', 'cli', 'index.js');
37
+ if (!fs.existsSync(cliEntry)) {
38
+ throw new Error(`找不到 EvolCore CLI 入口: ${cliEntry}`);
39
+ }
40
+ const pathValue = process.env.PATH ?? '';
41
+ const script = [
42
+ `$env:EVOLCORE_HOME = ${powershellLiteral(runtimeRoot)}`,
43
+ `$env:Path = ${powershellLiteral(pathValue)}`,
44
+ `& ${powershellLiteral(process.execPath)} --no-warnings=ExperimentalWarning ${powershellLiteral(cliEntry)} start`,
45
+ 'exit $LASTEXITCODE',
46
+ '',
47
+ ].join('\r\n');
48
+ fs.mkdirSync(path.dirname(scriptPath), { recursive: true });
49
+ fs.writeFileSync(scriptPath, script, 'utf8');
50
+ return scriptPath;
51
+ }
52
+ function restoreWrapper(file, previous) {
53
+ try {
54
+ if (previous === undefined)
55
+ fs.rmSync(file, { force: true });
56
+ else
57
+ fs.writeFileSync(file, previous, 'utf8');
58
+ return undefined;
59
+ }
60
+ catch (error) {
61
+ return error instanceof Error ? error.message : String(error);
62
+ }
63
+ }
64
+ export function configureWindowsAutostart(enabled, runtimeRoot) {
65
+ if (!isWindows()) {
66
+ return {
67
+ ok: !enabled,
68
+ enabled: false,
69
+ ...(!enabled ? {} : { error: 'Windows 开机自启仅支持 Windows 主机' }),
70
+ };
71
+ }
72
+ const absoluteRoot = path.resolve(runtimeRoot);
73
+ const scriptPath = wrapperPath(absoluteRoot);
74
+ if (!enabled) {
75
+ const result = runSchtasks(['/Delete', '/TN', WINDOWS_AUTOSTART_TASK_NAME, '/F']);
76
+ if (result.status !== 0 && windowsAutostartInstalled()) {
77
+ return {
78
+ ok: false,
79
+ enabled: true,
80
+ error: commandError(result, '删除 Windows 开机自启任务失败'),
81
+ };
82
+ }
83
+ try {
84
+ fs.rmSync(scriptPath, { force: true });
85
+ }
86
+ catch { }
87
+ return { ok: true, enabled: false };
88
+ }
89
+ let previousWrapper;
90
+ let previouslyInstalled = false;
91
+ try {
92
+ if (fs.existsSync(scriptPath))
93
+ previousWrapper = fs.readFileSync(scriptPath, 'utf8');
94
+ previouslyInstalled = windowsAutostartInstalled();
95
+ const taskScript = createWrapper(absoluteRoot);
96
+ const systemRoot = process.env.SystemRoot || 'C:\\Windows';
97
+ const powershell = path.join(systemRoot, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe');
98
+ const taskCommand = `${windowsCommandLiteral(powershell)} -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File ${windowsCommandLiteral(taskScript)}`;
99
+ // Omitting /RU keeps the task attached to the user creating it and avoids a password prompt.
100
+ const args = [
101
+ '/Create',
102
+ '/TN', WINDOWS_AUTOSTART_TASK_NAME,
103
+ '/SC', 'ONLOGON',
104
+ '/TR', taskCommand,
105
+ '/RL', 'LIMITED',
106
+ '/F',
107
+ ];
108
+ const result = runSchtasks(args);
109
+ if (result.status !== 0) {
110
+ const restoreError = restoreWrapper(scriptPath, previousWrapper);
111
+ const stillInstalled = windowsAutostartInstalled();
112
+ const rollbackSuffix = restoreError ? `; 恢复原启动脚本失败: ${restoreError}` : '';
113
+ return {
114
+ ok: false,
115
+ enabled: stillInstalled,
116
+ error: `${commandError(result, '创建 Windows 开机自启任务失败')}${rollbackSuffix}`,
117
+ };
118
+ }
119
+ return { ok: true, enabled: true };
120
+ }
121
+ catch (error) {
122
+ const restoreError = restoreWrapper(scriptPath, previousWrapper);
123
+ const rollbackSuffix = restoreError ? `; 恢复原启动脚本失败: ${restoreError}` : '';
124
+ return {
125
+ ok: false,
126
+ enabled: previouslyInstalled,
127
+ error: `${error instanceof Error ? error.message : String(error)}${rollbackSuffix}`,
128
+ };
129
+ }
130
+ }
@@ -2,7 +2,7 @@
2
2
  * Agent loop that works with AgentMessage throughout.
3
3
  * Transforms to Message[] only at the LLM call boundary.
4
4
  */
5
- import { EventStream } from "ecagent/runtime/compat";
5
+ import { EventStream } from "./runtime/compat.ts";
6
6
  import type { AgentContext, AgentEvent, AgentLoopConfig, AgentMessage, StreamFn } from "./types.ts";
7
7
  export type AgentEventSink = (event: AgentEvent) => Promise<void> | void;
8
8
  /**
@@ -2,7 +2,7 @@
2
2
  * Agent loop that works with AgentMessage throughout.
3
3
  * Transforms to Message[] only at the LLM call boundary.
4
4
  */
5
- import { EventStream, streamSimple, validateToolArguments, } from "ecagent/runtime/compat";
5
+ import { EventStream, streamSimple, validateToolArguments, } from "./runtime/compat.js";
6
6
  /**
7
7
  * Start an agent loop with a new prompt message.
8
8
  * The prompt is added to the context and events are emitted for it.
@@ -1,4 +1,4 @@
1
- import { type ImageContent, type Message, type SimpleStreamOptions, type ThinkingBudgets, type Transport } from "ecagent/runtime/compat";
1
+ import { type ImageContent, type Message, type SimpleStreamOptions, type ThinkingBudgets, type Transport } from "./runtime/compat.ts";
2
2
  import type { AfterToolCallContext, AfterToolCallResult, AgentEvent, AgentLoopTurnUpdate, AgentMessage, AgentState, BeforeToolCallContext, BeforeToolCallResult, PrepareNextTurnContext, QueueMode, StreamFn, ToolExecutionMode } from "./types.ts";
3
3
  export type { QueueMode } from "./types.ts";
4
4
  /** Options for constructing an {@link Agent}. */
@@ -1,4 +1,4 @@
1
- import { streamSimple, } from "ecagent/runtime/compat";
1
+ import { streamSimple, } from "./runtime/compat.js";
2
2
  import { runAgentLoop, runAgentLoopContinue } from "./agent-loop.js";
3
3
  function defaultConvertToLlm(messages) {
4
4
  return messages.filter((message) => message.role === "user" || message.role === "assistant" || message.role === "toolResult");
@@ -1,4 +1,4 @@
1
- import type { AssistantMessage, ImageContent, Model, Models } from "ecagent/runtime";
1
+ import type { AssistantMessage, ImageContent, Model, Models } from "../runtime/index.ts";
2
2
  import type { AgentMessage, AgentTool, QueueMode, ThinkingLevel } from "../types.ts";
3
3
  import type { AbortResult, AgentHarnessEvent, AgentHarnessEventResultMap, AgentHarnessOptions, AgentHarnessOwnEvent, AgentHarnessResources, AgentHarnessStreamOptions, ExecutionEnv, NavigateTreeResult, PromptTemplate, Skill } from "./types.ts";
4
4
  export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate extends PromptTemplate = PromptTemplate, TTool extends AgentTool = AgentTool> {
@@ -1,4 +1,4 @@
1
- import type { Model, Models } from "ecagent/runtime";
1
+ import type { Model, Models } from "../../runtime/index.ts";
2
2
  import type { AgentMessage } from "../../types.ts";
3
3
  import type { BranchSummaryResult, Session, SessionTreeEntry } from "../types.ts";
4
4
  import { BranchSummaryError, type Result } from "../types.ts";
@@ -1,4 +1,4 @@
1
- import type { Model, Models, Usage } from "ecagent/runtime";
1
+ import type { Model, Models, Usage } from "../../runtime/index.ts";
2
2
  import type { AgentMessage, ThinkingLevel } from "../../types.ts";
3
3
  import { CompactionError, type Result, type SessionTreeEntry } from "../types.ts";
4
4
  import { type FileOperations } from "./utils.ts";
@@ -1,4 +1,4 @@
1
- import type { Message } from "ecagent/runtime";
1
+ import type { Message } from "../../runtime/index.ts";
2
2
  import type { AgentMessage } from "../../types.ts";
3
3
  /** File paths touched by a session branch or compaction range. */
4
4
  export interface FileOperations {
@@ -1,4 +1,4 @@
1
- import type { ImageContent, Message, TextContent } from "ecagent/runtime";
1
+ import type { ImageContent, Message, TextContent } from "../runtime/index.ts";
2
2
  import type { AgentMessage } from "../types.ts";
3
3
  export declare const COMPACTION_SUMMARY_PREFIX = "The conversation history before this point was compacted into the following summary:\n\n<summary>\n";
4
4
  export declare const COMPACTION_SUMMARY_SUFFIX = "\n</summary>";
@@ -1,4 +1,4 @@
1
- import type { ImageContent, TextContent } from "ecagent/runtime";
1
+ import type { ImageContent, TextContent } from "../../runtime/index.ts";
2
2
  import type { AgentMessage } from "../../types.ts";
3
3
  import type { CustomEntry, SessionContext, SessionMetadata, SessionStorage, SessionTreeEntry } from "../types.ts";
4
4
  export type ContextEntryTransform = (entries: readonly SessionTreeEntry[]) => readonly SessionTreeEntry[];
@@ -1,4 +1,4 @@
1
- import type { ImageContent, Model, Models, SimpleStreamOptions, TextContent, Transport } from "ecagent/runtime";
1
+ import type { ImageContent, Model, Models, SimpleStreamOptions, TextContent, Transport } from "../runtime/index.ts";
2
2
  import type { AgentEvent, AgentMessage, AgentTool, QueueMode, ThinkingLevel } from "../index.ts";
3
3
  import type { Session } from "./session/session.ts";
4
4
  /** Result of a fallible operation. Expected failures are returned as `ok: false` instead of thrown. */
@@ -2,7 +2,7 @@
2
2
  * Proxy stream function for apps that route LLM calls through a server.
3
3
  * The server manages auth and proxies requests to LLM providers.
4
4
  */
5
- import { type AssistantMessage, type AssistantMessageEvent, type Context, EventStream, type Model, type SimpleStreamOptions, type StopReason } from "ecagent/runtime";
5
+ import { type AssistantMessage, type AssistantMessageEvent, type Context, EventStream, type Model, type SimpleStreamOptions, type StopReason } from "./runtime/index.ts";
6
6
  declare class ProxyMessageEventStream extends EventStream<AssistantMessageEvent, AssistantMessage> {
7
7
  constructor();
8
8
  }
@@ -3,7 +3,7 @@
3
3
  * The server manages auth and proxies requests to LLM providers.
4
4
  */
5
5
  // Internal import for JSON parsing utility
6
- import { EventStream, parseStreamingJson, } from "ecagent/runtime";
6
+ import { EventStream, parseStreamingJson, } from "./runtime/index.js";
7
7
  // Create stream class matching ProxyMessageEventStream
8
8
  class ProxyMessageEventStream extends EventStream {
9
9
  constructor() {
@@ -1,4 +1,4 @@
1
- import type { Api, AssistantMessage, AssistantMessageEvent, AssistantMessageEventStream, Context, ImageContent, Message, Model, SimpleStreamOptions, TextContent, Tool, ToolResultMessage } from "ecagent/runtime";
1
+ import type { Api, AssistantMessage, AssistantMessageEvent, AssistantMessageEventStream, Context, ImageContent, Message, Model, SimpleStreamOptions, TextContent, Tool, ToolResultMessage } from "./runtime/index.ts";
2
2
  import type { Static, TSchema } from "typebox";
3
3
  /**
4
4
  * Stream function used by the agent loop. `Models.streamSimple` satisfies
@@ -45,6 +45,17 @@ function isRecord(value) {
45
45
  return !!value && typeof value === 'object' && !Array.isArray(value);
46
46
  }
47
47
 
48
+ function normalizeRoleEffortCompat(value) {
49
+ if (!isRecord(value) || !isRecord(value.permissions)
50
+ || !Object.prototype.hasOwnProperty.call(value.permissions, 'baseagents.codex.reasoning')) return value;
51
+ const permissions = { ...value.permissions };
52
+ if (!Object.prototype.hasOwnProperty.call(permissions, 'baseagents.codex.effort')) {
53
+ permissions['baseagents.codex.effort'] = permissions['baseagents.codex.reasoning'];
54
+ }
55
+ delete permissions['baseagents.codex.reasoning'];
56
+ return { ...value, permissions };
57
+ }
58
+
48
59
  function isValidAid(name) {
49
60
  const labels = name.split('.');
50
61
  return labels.length >= 3 && labels.every(label => /^[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/.test(label));
@@ -111,7 +122,21 @@ function planMigration(home) {
111
122
  if (fs.existsSync(registryFile) && input.roles !== undefined) {
112
123
  throw new Error(`${agentFile}: both config.roles and roles/index.json exist; resolve the ambiguous role source before migration`);
113
124
  }
114
- if (input.$schema_version === 5 && input.roles === undefined && fs.existsSync(registryFile)) continue;
125
+ if (input.$schema_version === 5 && input.roles === undefined && fs.existsSync(registryFile)) {
126
+ const { value: registry } = readJson(registryFile);
127
+ validateOrThrow(validators.registry, registry, registryFile);
128
+ for (const roleId of registry.roles) {
129
+ const roleFile = path.join(rolesDir, `${roleId}.json`);
130
+ if (!fs.existsSync(roleFile)) continue;
131
+ const { value: roleValue, text: roleText } = readJson(roleFile);
132
+ const normalizedRole = normalizeRoleEffortCompat(roleValue);
133
+ validateRoleOrThrow(validators.role, normalizedRole, roleFile);
134
+ if (appendChange(changes, roleFile, 'role-config', roleText, normalizedRole)) {
135
+ summary.rolesWritten += 1;
136
+ }
137
+ }
138
+ continue;
139
+ }
115
140
 
116
141
  const policy = isRecord(input.roles) ? input.roles : {};
117
142
  const definitions = isRecord(policy.definitions) ? policy.definitions : {};
@@ -156,7 +181,7 @@ function planMigration(home) {
156
181
  appendChange(changes, registryFile, 'role-registry', existingRegistry, registry);
157
182
  for (const [roleId, definition] of Object.entries(definitions)) {
158
183
  const roleFile = path.join(rolesDir, `${roleId}.json`);
159
- const roleValue = { $schema_version: 1, ...definition };
184
+ const roleValue = normalizeRoleEffortCompat({ $schema_version: 1, ...definition });
160
185
  validateRoleOrThrow(validators.role, roleValue, roleFile);
161
186
  if (appendChange(changes, roleFile, 'role-config', fs.existsSync(roleFile) ? fs.readFileSync(roleFile, 'utf8') : null, roleValue)) {
162
187
  summary.rolesWritten += 1;
@@ -144,7 +144,13 @@
144
144
  "aun": {
145
145
  "type": "object",
146
146
  "x-merge": "dict",
147
- "description": "Agent 级 AUN 通信配置"
147
+ "description": "Agent 级 AUN 通信配置",
148
+ "properties": {
149
+ "defaultEncrypt": {
150
+ "not": {},
151
+ "description": "不支持在 Agent 配置;请使用 daemon.json.aun.defaultEncrypt"
152
+ }
153
+ }
148
154
  },
149
155
  "models": {
150
156
  "type": "object",
@@ -164,6 +170,18 @@
164
170
  "not": {
165
171
  "type": "object",
166
172
  "required": ["fallbackModels"]
173
+ },
174
+ "properties": {
175
+ "headers": {
176
+ "type": "object",
177
+ "propertyNames": { "pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]+$" },
178
+ "additionalProperties": { "type": "string", "pattern": "^[^\\u0000\\r\\n]*$" }
179
+ },
180
+ "queryParams": {
181
+ "type": "object",
182
+ "propertyNames": { "minLength": 1 },
183
+ "additionalProperties": { "type": "string" }
184
+ }
167
185
  }
168
186
  }
169
187
  },
@@ -82,6 +82,10 @@
82
82
  "type": "boolean",
83
83
  "default": false,
84
84
  "description": "是否要求普通 AUN Menu 请求携带有效 menu_token;默认 false"
85
+ },
86
+ "defaultEncrypt": {
87
+ "type": "boolean",
88
+ "description": "所有 daemon 管理的 AUN 通道共用的出站默认加密值;省略时为 true"
85
89
  }
86
90
  }
87
91
  },
@@ -35,6 +35,16 @@
35
35
  "type": "object",
36
36
  "additionalProperties": true,
37
37
  "properties": {
38
+ "headers": {
39
+ "type": "object",
40
+ "propertyNames": { "pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]+$" },
41
+ "additionalProperties": { "type": "string", "pattern": "^[^\\u0000\\r\\n]*$" }
42
+ },
43
+ "queryParams": {
44
+ "type": "object",
45
+ "propertyNames": { "minLength": 1 },
46
+ "additionalProperties": { "type": "string" }
47
+ },
38
48
  "fallbackModels": {
39
49
  "type": "array",
40
50
  "maxItems": 3,
@@ -68,7 +78,11 @@
68
78
  "properties": {
69
79
  "keystorePath": { "type": "string" },
70
80
  "encryptionSeed": { "type": "string" },
71
- "gatewayUrl": { "type": "string" }
81
+ "gatewayUrl": { "type": "string" },
82
+ "defaultEncrypt": {
83
+ "not": {},
84
+ "description": "不支持在 Agent defaults 配置;请使用 daemon.json.aun.defaultEncrypt"
85
+ }
72
86
  }
73
87
  },
74
88
  "responseMode": { "type": "string", "x-merge": "scalar" },