evolcore 0.0.10 → 0.0.12

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 (131) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +3 -3
  3. package/bin/codex-managed-hook.mjs +80 -0
  4. package/dist/agents/baseagent.js +4 -0
  5. package/dist/agents/claude-runner.js +158 -44
  6. package/dist/agents/codex-app-server-client.js +153 -23
  7. package/dist/agents/codex-runner.js +331 -43
  8. package/dist/agents/ecagent-runner.js +53 -6
  9. package/dist/agents/gemini-runner.js +1 -0
  10. package/dist/agents/request-identity.js +55 -0
  11. package/dist/aun/aid/client.js +11 -21
  12. package/dist/aun/aid/managed-operation.js +107 -0
  13. package/dist/aun/msg/group.js +81 -12
  14. package/dist/aun/msg/managed-operation.js +804 -0
  15. package/dist/aun/msg/mention-schema.js +20 -0
  16. package/dist/aun/msg/p2p.js +7 -0
  17. package/dist/aun/outbox.js +28 -31
  18. package/dist/channels/aun.js +418 -235
  19. package/dist/channels/daemon.js +13 -0
  20. package/dist/cli/agent-command.js +72 -17
  21. package/dist/cli/agent.js +249 -22
  22. package/dist/cli/aun-commands.js +270 -69
  23. package/dist/cli/bench.js +12 -3
  24. package/dist/cli/daemon-commands.js +52 -33
  25. package/dist/cli/fs-command.js +60 -0
  26. package/dist/cli/handoff-command.js +3 -0
  27. package/dist/cli/index.js +106 -63
  28. package/dist/cli/init-cancel.js +208 -0
  29. package/dist/cli/init-channel.js +343 -195
  30. package/dist/cli/init.js +21 -9
  31. package/dist/cli/managed-command-guard.js +41 -0
  32. package/dist/cli/model.js +11 -4
  33. package/dist/cli/queue-command.js +11 -1
  34. package/dist/cli/response.js +71 -0
  35. package/dist/cli/restart-monitor.js +4 -18
  36. package/dist/cli/trigger-command.js +4 -0
  37. package/dist/config/builtin-roles.js +5 -0
  38. package/dist/config/contact-book-store.js +11 -3
  39. package/dist/config/contact-request-service.js +161 -15
  40. package/dist/config/gateway-config.js +26 -10
  41. package/dist/config/mention-mode.js +8 -24
  42. package/dist/core/agent-reload-coordinator.js +53 -0
  43. package/dist/core/auth/agent-delegation.js +0 -1
  44. package/dist/core/auth/operation-authorizer.js +62 -154
  45. package/dist/core/auth/operation-catalog.js +264 -22
  46. package/dist/core/bootstrap-messages.js +68 -0
  47. package/dist/core/bootstrap-service.js +144 -10
  48. package/dist/core/capability/providers/claude-capability-provider.js +9 -31
  49. package/dist/core/capability/providers/codex-capability-provider.js +4 -15
  50. package/dist/core/capability/skill-discovery.js +55 -0
  51. package/dist/core/channel-loader.js +24 -7
  52. package/dist/core/command/agent-control.js +14 -11
  53. package/dist/core/command/cli-intent-parser.js +9 -0
  54. package/dist/core/command/command-handler.js +467 -6
  55. package/dist/core/command/connect-menu.js +15 -0
  56. package/dist/core/command/group-menu.js +4 -4
  57. package/dist/core/command/menu-catalog.js +366 -0
  58. package/dist/core/command/menu-handler.js +213 -110
  59. package/dist/core/command/menu-protocol.js +71 -0
  60. package/dist/core/command/slash-gate.js +5 -2
  61. package/dist/core/command/slash-handler.js +45 -25
  62. package/dist/core/daemon-file-cache.js +2 -1
  63. package/dist/core/data-migration.js +9 -2
  64. package/dist/core/evolagent-registry.js +125 -35
  65. package/dist/core/evolagent.js +12 -5
  66. package/dist/core/handoff/dispatcher.js +5 -2
  67. package/dist/core/handoff/runtime.js +145 -21
  68. package/dist/core/handoff/store.js +24 -0
  69. package/dist/core/handoff/types.js +1 -0
  70. package/dist/core/inference/text-inference.js +38 -4
  71. package/dist/core/message/logical-queue-bridge.js +1 -0
  72. package/dist/core/message/mention-schema.js +126 -0
  73. package/dist/core/message/message-bridge.js +237 -79
  74. package/dist/core/message/message-log.js +23 -0
  75. package/dist/core/message/message-queue.js +20 -4
  76. package/dist/core/message/response-engine.js +54 -36
  77. package/dist/core/model/model-catalog.js +143 -24
  78. package/dist/core/model/model-diagnostics.js +28 -10
  79. package/dist/core/permission/ec-command-parser.js +156 -10
  80. package/dist/core/permission/index.js +1 -0
  81. package/dist/core/permission/readonly-shell-query.js +532 -0
  82. package/dist/core/permission/sandbox-runtime.js +22 -1
  83. package/dist/core/permission/shell-environment.js +46 -0
  84. package/dist/core/permission/tool-policy.js +292 -111
  85. package/dist/core/protected-paths.js +17 -9
  86. package/dist/core/runner-reload-transaction.js +57 -0
  87. package/dist/core/session/session-manager.js +21 -2
  88. package/dist/eck/manifest-engine.js +39 -13
  89. package/dist/index.js +644 -180
  90. package/dist/ipc.js +246 -19
  91. package/dist/response-system/coordinator.js +6 -4
  92. package/dist/response-system/engines/v1/proactive-flow.js +26 -8
  93. package/dist/response-system/modes/single-session/index.js +14 -1
  94. package/dist/response-system/selector.js +6 -5
  95. package/dist/trigger/anomaly-store.js +4 -0
  96. package/dist/trigger/script-executor.js +1 -0
  97. package/dist/utils/aid-bind.js +3 -8
  98. package/dist/utils/codex-app-server-registry.js +90 -0
  99. package/dist/utils/codex-cli.js +5 -1
  100. package/dist/utils/cross-platform.js +15 -0
  101. package/dist/utils/log-writer.js +6 -10
  102. package/dist/utils/logger.js +5 -5
  103. package/dist/utils/npm-ops.js +5 -12
  104. package/dist/utils/tool-summary.js +11 -0
  105. package/kits/docs/channels/aun.md +1 -1
  106. package/kits/docs/context-assembly.md +2 -2
  107. package/kits/docs/evolcore/agent.md +11 -6
  108. package/kits/docs/evolcore/aid.md +14 -0
  109. package/kits/docs/evolcore/msg.md +13 -0
  110. package/kits/docs/prompt-loading-architecture.md +1 -2
  111. package/kits/docs/venues/group.md +1 -1
  112. package/kits/eck_manifest.json +0 -12
  113. package/kits/rules/01-overview.md +9 -0
  114. package/kits/rules/04-relation.md +1 -1
  115. package/kits/rules/05-venue.md +2 -2
  116. package/kits/schemas/agent-config.schema.3.json +1 -1
  117. package/kits/schemas/agent-config.schema.4.json +1 -1
  118. package/kits/schemas/relation-config.schema.2.json +1 -1
  119. package/kits/schemas/role-config.schema.1.json +1 -1
  120. package/kits/schemas/single-session.schema.1.json +3 -3
  121. package/kits/schemas/single-session.schema.2.json +3 -3
  122. package/kits/templates/roles/admin.json +27 -0
  123. package/kits/templates/roles/member.json +44 -0
  124. package/kits/templates/roles/visitor.json +40 -2
  125. package/kits/templates/system-fragments/bootstrap.md +12 -6
  126. package/kits/templates/system-fragments/channel.md +6 -0
  127. package/kits/templates/system-fragments/session.md +2 -0
  128. package/package.json +3 -2
  129. package/skills/eclink/SKILL.md +15 -3
  130. package/skills/eclink/agents/openai.yaml +3 -3
  131. package/dist/core/command/evol-menu-version-gate.js +0 -39
@@ -4,6 +4,13 @@ import { logger } from '../utils/logger.js';
4
4
  import { buildHClassGuardCommand } from '../core/permission/sandbox-runtime.js';
5
5
  import { resolveCodexLaunchCommand } from '../utils/codex-cli.js';
6
6
  import { createHash } from 'crypto';
7
+ import { sanitizeShellExecutionEnvironment } from '../core/permission/shell-environment.js';
8
+ import fs from 'fs';
9
+ import os from 'os';
10
+ import path from 'path';
11
+ import { getPackageRoot, resolvePaths } from '../paths.js';
12
+ import { registerCodexAppServerProcess, unregisterCodexAppServerProcess, } from '../utils/codex-app-server-registry.js';
13
+ const BUILT_IN_CODEX_PROVIDER_IDS = new Set(['openai']);
7
14
  function tomlProviderKey(value) {
8
15
  if (!value || /[\0\r\n]/.test(value)) {
9
16
  throw new Error(`Invalid Codex provider name: ${value}`);
@@ -19,6 +26,10 @@ function codexHeaderEnvName(headerName) {
19
26
  const digest = createHash('sha256').update(headerName).digest('hex').slice(0, 16).toUpperCase();
20
27
  return `EVOLCORE_CODEX_HEADER_${digest}`;
21
28
  }
29
+ function runtimeProviderId(baseUrl) {
30
+ const digest = createHash('sha256').update(baseUrl || 'default').digest('hex').slice(0, 12);
31
+ return `evolcore_runtime_${digest}`;
32
+ }
22
33
  function hasPermissionProfile(config) {
23
34
  if (!config || typeof config.default_permissions !== 'string' || !config.default_permissions)
24
35
  return false;
@@ -35,6 +46,8 @@ export class CodexAppServerClient {
35
46
  initialized = false;
36
47
  initializing = null;
37
48
  stderrBuffer = [];
49
+ managedHookRuntimeDir = null;
50
+ processRegistrationPath = null;
38
51
  constructor(options) {
39
52
  this.options = options;
40
53
  }
@@ -292,25 +305,33 @@ export class CodexAppServerClient {
292
305
  pending.reject(new Error('Codex app-server closed'));
293
306
  }
294
307
  this.pending.clear();
295
- if (!proc)
308
+ if (!proc) {
309
+ this.cleanupManagedHookRuntime();
296
310
  return;
311
+ }
297
312
  // 优雅关闭:先关闭 stdin,然后发送 SIGTERM,等待进程退出
298
313
  proc.stdin.end();
299
314
  proc.kill('SIGTERM');
300
315
  // 等待进程退出,最多等待 5 秒
301
316
  await new Promise((resolve) => {
317
+ let exited = false;
302
318
  const timeout = setTimeout(() => {
303
- if (!proc.killed) {
304
- logger.warn('[CodexAppServer] Process did not exit after SIGTERM, sending SIGKILL');
319
+ if (exited)
320
+ return;
321
+ logger.warn('[CodexAppServer] Process did not exit after SIGTERM, sending SIGKILL');
322
+ try {
305
323
  proc.kill('SIGKILL');
306
324
  }
325
+ catch { }
307
326
  resolve();
308
327
  }, 5000);
309
328
  proc.once('exit', () => {
329
+ exited = true;
310
330
  clearTimeout(timeout);
311
331
  resolve();
312
332
  });
313
333
  });
334
+ this.cleanupManagedHookRuntime();
314
335
  }
315
336
  async ensureStarted() {
316
337
  if (this.initialized)
@@ -341,34 +362,61 @@ export class CodexAppServerClient {
341
362
  }
342
363
  }
343
364
  startProcess() {
344
- const env = { ...process.env, ...this.options.env };
345
- env.CODEX_API_KEY = this.options.apiKey;
346
- for (const [name, value] of Object.entries(this.options.headers ?? {})) {
347
- env[codexHeaderEnvName(name)] = value;
348
- }
349
- if (this.options.baseUrl) {
350
- env.OPENAI_BASE_URL = this.options.baseUrl;
351
- }
365
+ const env = this.buildProcessEnvironment();
352
366
  const args = this.buildProcessArgs();
353
367
  const launchCommand = resolveCodexLaunchCommand(args);
354
368
  if (!launchCommand)
355
369
  throw new Error('Codex CLI not found');
356
- const guardedCommand = buildHClassGuardCommand(launchCommand.command, launchCommand.args);
357
- if (process.platform === 'linux' && !guardedCommand) {
358
- throw new Error('Codex 缺少 EvolCore H 类路径隔离运行时,已拒绝启动 app-server');
370
+ try {
371
+ let command = launchCommand.command;
372
+ let commandArgs = launchCommand.args;
373
+ if (process.platform === 'linux') {
374
+ const managedRequirements = this.ensureManagedHookRuntime();
375
+ const guardedCommand = buildHClassGuardCommand(command, commandArgs, undefined, {
376
+ managedCodexRequirements: managedRequirements,
377
+ });
378
+ if (!guardedCommand) {
379
+ throw new Error('Codex 缺少 EvolCore managed-hook 隔离运行时,已拒绝启动 app-server');
380
+ }
381
+ command = guardedCommand.command;
382
+ commandArgs = guardedCommand.args;
383
+ }
384
+ this.proc = spawn(command, commandArgs, {
385
+ cwd: this.options.cwd,
386
+ env,
387
+ stdio: ['pipe', 'pipe', 'pipe'],
388
+ windowsHide: process.platform === 'win32',
389
+ });
390
+ try {
391
+ this.processRegistrationPath = registerCodexAppServerProcess(this.proc.pid);
392
+ }
393
+ catch (error) {
394
+ logger.warn(`[CodexAppServer] failed to register owned process pid=${this.proc.pid ?? '<unknown>'}: ${error}`);
395
+ }
396
+ }
397
+ catch (error) {
398
+ this.cleanupManagedHookRuntime();
399
+ throw error;
359
400
  }
360
- this.proc = spawn(guardedCommand?.command ?? launchCommand.command, guardedCommand?.args ?? launchCommand.args, {
361
- cwd: this.options.cwd,
362
- env,
363
- stdio: ['pipe', 'pipe', 'pipe'],
401
+ const proc = this.proc;
402
+ const processRegistrationPath = this.processRegistrationPath;
403
+ proc.once('error', error => {
404
+ unregisterCodexAppServerProcess(processRegistrationPath);
405
+ if (this.processRegistrationPath === processRegistrationPath) {
406
+ this.processRegistrationPath = null;
407
+ }
408
+ this.failAll(error);
364
409
  });
365
- this.proc.once('error', error => this.failAll(error));
366
- this.proc.once('exit', (code, signal) => {
410
+ proc.once('exit', (code, signal) => {
411
+ unregisterCodexAppServerProcess(processRegistrationPath);
412
+ if (this.processRegistrationPath === processRegistrationPath) {
413
+ this.processRegistrationPath = null;
414
+ }
367
415
  this.failAll(new Error(`Codex app-server exited: code=${code ?? 'null'} signal=${signal ?? 'null'}`));
368
416
  });
369
- const rl = readline.createInterface({ input: this.proc.stdout, crlfDelay: Infinity });
417
+ const rl = readline.createInterface({ input: proc.stdout, crlfDelay: Infinity });
370
418
  rl.on('line', line => this.handleLine(line));
371
- this.proc.stderr.on('data', chunk => {
419
+ proc.stderr.on('data', chunk => {
372
420
  const text = String(chunk).trim();
373
421
  if (!text)
374
422
  return;
@@ -378,6 +426,76 @@ export class CodexAppServerClient {
378
426
  logger.debug(`[CodexAppServer] ${text}`);
379
427
  });
380
428
  }
429
+ ensureManagedHookRuntime() {
430
+ if (this.managedHookRuntimeDir) {
431
+ return path.join(this.managedHookRuntimeDir, 'requirements.toml');
432
+ }
433
+ const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'evolcore-codex-hooks-'));
434
+ try {
435
+ fs.chmodSync(directory, 0o700);
436
+ const hookPath = path.join(directory, 'pre-tool-use.mjs');
437
+ const sourcePath = path.join(getPackageRoot(), 'bin', 'codex-managed-hook.mjs');
438
+ fs.copyFileSync(sourcePath, hookPath, fs.constants.COPYFILE_EXCL);
439
+ fs.chmodSync(hookPath, 0o500);
440
+ const command = `${this.shellQuote(process.execPath)} ${this.shellQuote(hookPath)} ${this.shellQuote(resolvePaths().instanceSocket)}`;
441
+ const requirementsPath = path.join(directory, 'requirements.toml');
442
+ fs.writeFileSync(requirementsPath, [
443
+ 'allow_managed_hooks_only = true',
444
+ '',
445
+ '[features]',
446
+ 'hooks = true',
447
+ '',
448
+ '[hooks]',
449
+ `managed_dir = ${JSON.stringify(directory)}`,
450
+ '',
451
+ '[[hooks.PreToolUse]]',
452
+ 'matcher = "*"',
453
+ '',
454
+ '[[hooks.PreToolUse.hooks]]',
455
+ 'type = "command"',
456
+ `command = ${JSON.stringify(command)}`,
457
+ 'timeout = 3',
458
+ 'statusMessage = "Checking EvolCore session policy"',
459
+ '',
460
+ ].join('\n'), { mode: 0o400, flag: 'wx' });
461
+ this.managedHookRuntimeDir = directory;
462
+ return requirementsPath;
463
+ }
464
+ catch (error) {
465
+ try {
466
+ fs.rmSync(directory, { recursive: true, force: true });
467
+ }
468
+ catch { }
469
+ throw error;
470
+ }
471
+ }
472
+ shellQuote(value) {
473
+ return `'${value.replace(/'/g, `'"'"'`)}'`;
474
+ }
475
+ cleanupManagedHookRuntime() {
476
+ const directory = this.managedHookRuntimeDir;
477
+ this.managedHookRuntimeDir = null;
478
+ if (!directory || !path.basename(directory).startsWith('evolcore-codex-hooks-'))
479
+ return;
480
+ try {
481
+ fs.rmSync(directory, { recursive: true, force: true });
482
+ }
483
+ catch { }
484
+ }
485
+ buildProcessEnvironment() {
486
+ const env = sanitizeShellExecutionEnvironment({
487
+ ...process.env,
488
+ ...this.options.env,
489
+ });
490
+ env.CODEX_API_KEY = this.options.apiKey;
491
+ for (const [name, value] of Object.entries(this.options.headers ?? {})) {
492
+ env[codexHeaderEnvName(name)] = value;
493
+ }
494
+ if (this.options.baseUrl) {
495
+ env.OPENAI_BASE_URL = this.options.baseUrl;
496
+ }
497
+ return env;
498
+ }
381
499
  buildProcessArgs() {
382
500
  const args = ['app-server', '--listen', 'stdio://'];
383
501
  if (this.options.enableRequestUserInput !== false) {
@@ -390,7 +508,18 @@ export class CodexAppServerClient {
390
508
  const hasHeaders = Object.keys(headerEnvNames).length > 0;
391
509
  const hasQueryParams = Object.keys(this.options.queryParams ?? {}).length > 0;
392
510
  if (hasHeaders || hasQueryParams) {
393
- const provider = tomlProviderKey(this.options.provider || 'openai');
511
+ const configuredProvider = this.options.provider?.trim();
512
+ const useRuntimeProvider = !configuredProvider || BUILT_IN_CODEX_PROVIDER_IDS.has(configuredProvider.toLowerCase());
513
+ const providerName = !useRuntimeProvider
514
+ ? configuredProvider
515
+ : runtimeProviderId(this.options.baseUrl);
516
+ const provider = tomlProviderKey(providerName);
517
+ args.push('--config', `model_provider=${JSON.stringify(providerName)}`);
518
+ args.push('--config', `model_providers.${provider}.name=${JSON.stringify('EvolCore runtime gateway')}`);
519
+ args.push('--config', `model_providers.${provider}.wire_api=${JSON.stringify('responses')}`);
520
+ if (useRuntimeProvider || this.options.baseUrl) {
521
+ args.push('--config', `model_providers.${provider}.base_url=${JSON.stringify(this.options.baseUrl || 'https://api.openai.com/v1')}`);
522
+ }
394
523
  if (hasHeaders) {
395
524
  args.push('--config', `model_providers.${provider}.env_http_headers=${tomlInlineStringTable(headerEnvNames)}`);
396
525
  }
@@ -547,5 +676,6 @@ export class CodexAppServerClient {
547
676
  pending.reject(error);
548
677
  }
549
678
  this.pending.clear();
679
+ this.cleanupManagedHookRuntime();
550
680
  }
551
681
  }