evolcore 0.0.23 → 0.0.24

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 (84) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +3 -1
  3. package/bin/codex-managed-acl.ps1 +7 -2
  4. package/bin/codex-managed-hook.mjs +127 -10
  5. package/bin/ec-safe-output.js +85 -3
  6. package/bin/install-codex-managed-hooks.mjs +17 -6
  7. package/dist/agents/baseagent-availability.js +4 -4
  8. package/dist/agents/baseagent.js +29 -1
  9. package/dist/agents/claude-runner.js +148 -13
  10. package/dist/agents/codex/app-server-client.js +18 -8
  11. package/dist/agents/codex/catalog.js +1 -1
  12. package/dist/agents/codex/diagnostics.js +215 -0
  13. package/dist/agents/codex-runner.js +438 -59
  14. package/dist/agents/ecagent-runner.js +17 -3
  15. package/dist/agents/gemini-runner.js +60 -2
  16. package/dist/agents/runner-types.js +1 -1
  17. package/dist/aun/aid/managed-operation.js +28 -6
  18. package/dist/aun/aid/store.js +41 -0
  19. package/dist/aun/msg/managed-operation.js +6 -1
  20. package/dist/aun/outbox.js +56 -18
  21. package/dist/aun/rpc/client.js +4 -5
  22. package/dist/channels/aun.js +147 -76
  23. package/dist/channels/daemon.js +7 -1
  24. package/dist/channels/dingtalk.js +1 -0
  25. package/dist/channels/feishu.js +10 -4
  26. package/dist/channels/wecom.js +2 -1
  27. package/dist/cli/agent-command.js +29 -3
  28. package/dist/cli/agent-create.js +538 -0
  29. package/dist/cli/agent.js +26 -675
  30. package/dist/cli/aun-commands.js +60 -20
  31. package/dist/cli/ctl-command.js +2 -0
  32. package/dist/cli/daemon-commands.js +148 -17
  33. package/dist/cli/index.js +2 -2
  34. package/dist/cli/managed-command-guard.js +3 -0
  35. package/dist/cli/restart-monitor.js +432 -8
  36. package/dist/cli/stats.js +110 -0
  37. package/dist/config/builtin-roles.js +2 -0
  38. package/dist/core/auth/auth-gateway.js +3 -2
  39. package/dist/core/auth/authorization-audit.js +72 -19
  40. package/dist/core/auth/operation-authorizer.js +63 -3
  41. package/dist/core/auth/operation-catalog.js +10 -2
  42. package/dist/core/auth/remote-access-store.js +3 -2
  43. package/dist/core/baseagent-loader.js +4 -4
  44. package/dist/core/bootstrap-messages.js +39 -18
  45. package/dist/core/bootstrap-service.js +32 -26
  46. package/dist/core/capability/capability-manager.js +8 -4
  47. package/dist/core/capability/providers/codex-capability-provider.js +1 -1
  48. package/dist/core/command/agent-control.js +7 -2
  49. package/dist/core/command/command-handler.js +87 -25
  50. package/dist/core/command/menu-catalog.js +3 -1
  51. package/dist/core/command/menu-handler.js +274 -70
  52. package/dist/core/command/menu-protocol.js +6 -2
  53. package/dist/core/command/slash-gate.js +1 -3
  54. package/dist/core/command/slash-handler.js +157 -48
  55. package/dist/core/data-migration.js +5 -15
  56. package/dist/core/event-catalog.js +3 -0
  57. package/dist/core/handoff/runtime.js +3 -1
  58. package/dist/core/handoff/store.js +7 -1
  59. package/dist/core/message/im-renderer.js +13 -6
  60. package/dist/core/message/message-bridge.js +5 -36
  61. package/dist/core/message/message-utils.js +6 -3
  62. package/dist/core/message/response-engine.js +73 -21
  63. package/dist/core/model/catalog-service.js +3 -1
  64. package/dist/core/model/model-catalog.js +10 -0
  65. package/dist/core/model/model-permission.js +4 -1
  66. package/dist/core/permission/approval-gateway.js +169 -33
  67. package/dist/core/permission/tool-policy.js +13 -6
  68. package/dist/core/session/adapters/codex-session-file-adapter.js +71 -3
  69. package/dist/core/session/session-manager.js +49 -13
  70. package/dist/core/session/session-renew.js +1 -0
  71. package/dist/index.js +174 -28
  72. package/dist/ipc.js +68 -21
  73. package/dist/paths.js +23 -1
  74. package/dist/stats/billing.js +18 -4
  75. package/dist/utils/atomic-write.js +26 -2
  76. package/dist/utils/cross-platform.js +436 -1
  77. package/dist/utils/error-utils.js +11 -4
  78. package/dist/utils/model-prices.jsonl +23 -20
  79. package/dist/utils/npm-ops.js +24 -1
  80. package/dist/utils/windows-autostart.js +1 -1
  81. package/kits/templates/roles/admin.json +2 -0
  82. package/package.json +7 -3
  83. package/AGENTS.md +0 -62
  84. package/dist/utils/codex-cli.js +0 -43
@@ -26,6 +26,13 @@ const MAX_TOOL_OUTPUT = 200_000;
26
26
  const MAX_SCAN_FILES = 5_000;
27
27
  const MAX_SEARCH_RESULTS = 500;
28
28
  const DEFAULT_BASH_TIMEOUT_MS = 120_000;
29
+ /**
30
+ * 规范化模型 ID:去掉 Claude Code SDK 专有的上下文窗口后缀 [1m]/[200k]
31
+ * Ecagent/OpenAI API 不认识这些后缀,必须传入标准模型 ID
32
+ */
33
+ function stripContextWindowSuffix(modelId) {
34
+ return modelId.replace(/\[(?:1m|200k)\]$/i, '');
35
+ }
29
36
  class AsyncEventQueue {
30
37
  values = [];
31
38
  waiters = [];
@@ -714,7 +721,7 @@ export class EcagentRunner {
714
721
  configuredHeaders: config.headers,
715
722
  }),
716
723
  };
717
- this.model = config.model;
724
+ this.model = stripContextWindowSuffix(config.model);
718
725
  this.effort = config.effort;
719
726
  this.agentAid = runtime?.agentAid;
720
727
  this.onSessionIdUpdate = callbacks?.onSessionIdUpdate;
@@ -724,7 +731,7 @@ export class EcagentRunner {
724
731
  throw new Error('ecagent requires an EvolCore Agent AID');
725
732
  return agentSessionsDir(this.agentAid);
726
733
  }
727
- setModel(model) { this.model = model; }
734
+ setModel(model) { this.model = stripContextWindowSuffix(model); }
728
735
  getModel() { return this.model; }
729
736
  resolveModelId(model) { return model; }
730
737
  setEffort(effort) { this.effort = effort; }
@@ -995,6 +1002,13 @@ export class EcagentRunner {
995
1002
  return runtime;
996
1003
  }
997
1004
  mapHarnessEvent(queue, event, stats, model, effort) {
1005
+ if (event.type === 'message_update'
1006
+ && (event.assistantMessageEvent.type === 'thinking_start'
1007
+ || event.assistantMessageEvent.type === 'thinking_delta'
1008
+ || event.assistantMessageEvent.type === 'thinking_end')) {
1009
+ queue.push({ type: 'heartbeat', source: 'reasoning', turn: stats.numTurns + 1 });
1010
+ return;
1011
+ }
998
1012
  if (event.type === 'message_update' && event.assistantMessageEvent.type === 'text_delta') {
999
1013
  if (!stats.firstTextAt)
1000
1014
  stats.firstTextAt = Date.now();
@@ -1202,7 +1216,7 @@ export class EcagentRunner {
1202
1216
  ? cached
1203
1217
  : await this.openExistingRuntime(agentSessionId, cwd);
1204
1218
  this.onCompactStart?.(sessionId);
1205
- const compactModel = modelOverride?.model || this.model;
1219
+ const compactModel = stripContextWindowSuffix(modelOverride?.model || this.model);
1206
1220
  const compactEffort = modelOverride?.effortMode === 'model_default'
1207
1221
  ? undefined
1208
1222
  : modelOverride?.effort ?? this.effort;
@@ -24,6 +24,7 @@ import { normalizeExecutionPermissionMode, normalizePermissionMode } from '../co
24
24
  import { workspaceContainsHClassPaths } from '../core/permission/protected-paths.js';
25
25
  import { buildBubblewrapCommand } from '../core/permission/sandbox-runtime.js';
26
26
  import { getManagedTaskTempDir } from '../cli/task-context.js';
27
+ import { auditPermissionLifecycle } from '../core/auth/authorization-audit.js';
27
28
  // Strip ANSI escape codes from Gemini CLI text output.
28
29
  // Gemini embeds raw terminal colors from tool stdout (e.g. vitest, npm)
29
30
  // into its assistant text, unlike Claude SDK which strips them internally.
@@ -32,6 +33,13 @@ const ANSI_RE = /\x1b\[[0-9;]*[a-zA-Z]|\x1b\].*?(?:\x1b\\|\x07)/g;
32
33
  function stripAnsi(text) {
33
34
  return text.replace(ANSI_RE, '');
34
35
  }
36
+ /**
37
+ * 规范化模型 ID:去掉 Claude Code SDK 专有的上下文窗口后缀 [1m]/[200k]
38
+ * Gemini API 不认识这些后缀,必须传入标准模型 ID
39
+ */
40
+ function stripContextWindowSuffix(modelId) {
41
+ return modelId.replace(/\[(?:1m|200k)\]$/i, '');
42
+ }
35
43
  // ── MIME → 扩展名映射 ──
36
44
  const MIME_EXT = {
37
45
  'image/png': '.png',
@@ -286,11 +294,11 @@ export class GeminiRunner {
286
294
  permissionContexts = new Map();
287
295
  constructor(config, callbacks) {
288
296
  this.resolved = resolveGoogleConfig(config);
289
- this.model = this.resolved.model;
297
+ this.model = stripContextWindowSuffix(this.resolved.model);
290
298
  this.onSessionIdUpdate = callbacks.onSessionIdUpdate;
291
299
  }
292
300
  // ── ModelSwitcher ──
293
- setModel(model) { this.model = model; }
301
+ setModel(model) { this.model = stripContextWindowSuffix(model); }
294
302
  getModel() { return this.model; }
295
303
  async listModels() { const catalog = await getCatalog(undefined, 'gemini'); assertCatalogSelectable(catalog); return catalog.models.map(m => m.id); }
296
304
  // ── Effort (not applicable) ──
@@ -687,6 +695,56 @@ export class GeminiRunner {
687
695
  logger.info(`[GeminiRunner] interaction.auto_resolved kind=${normalizeGeminiToolName(toolName)} session=${sessionId}`);
688
696
  return;
689
697
  }
698
+ const lifecycleRequestId = requestId ?? `gemini-approval-${crypto.randomUUID()}`;
699
+ const auditSummary = `${toolName} runtime authorization denied by Gemini headless policy`;
700
+ auditPermissionLifecycle({
701
+ phase: 'request',
702
+ requestId: lifecycleRequestId,
703
+ sessionId,
704
+ toolName,
705
+ decision: 'pending',
706
+ decisionSource: 'approval',
707
+ permissionMode: context.permissionMode,
708
+ agentAid: context.selfAid,
709
+ agentName: context.agentName,
710
+ role: context.role,
711
+ taskId: context.taskId,
712
+ summary: auditSummary,
713
+ });
714
+ auditPermissionLifecycle({
715
+ phase: 'response',
716
+ requestId: lifecycleRequestId,
717
+ sessionId,
718
+ toolName,
719
+ decision: 'deny',
720
+ decisionSource: 'policy',
721
+ policyCode: 'permission_mode_denied',
722
+ reason: auditSummary,
723
+ permissionMode: context.permissionMode,
724
+ agentAid: context.selfAid,
725
+ agentName: context.agentName,
726
+ role: context.role,
727
+ taskId: context.taskId,
728
+ summary: auditSummary,
729
+ response: 'deny',
730
+ });
731
+ auditPermissionLifecycle({
732
+ phase: 'final',
733
+ requestId: lifecycleRequestId,
734
+ sessionId,
735
+ toolName,
736
+ decision: 'deny',
737
+ decisionSource: 'policy',
738
+ policyCode: 'permission_mode_denied',
739
+ reason: auditSummary,
740
+ permissionMode: context.permissionMode,
741
+ agentAid: context.selfAid,
742
+ agentName: context.agentName,
743
+ role: context.role,
744
+ taskId: context.taskId,
745
+ summary: auditSummary,
746
+ response: 'deny',
747
+ });
690
748
  try {
691
749
  await context.recordExecutionAnomaly?.({
692
750
  code: 'runtime_permission_denied',
@@ -63,7 +63,7 @@ export function usageForContext(usage) {
63
63
  return lastIteration ?? usage;
64
64
  }
65
65
  /** Models whose base ID uses a 1M context window when sent to the SDK with [1m]. */
66
- export const ONE_M_CONTEXT_MODEL_PREFIXES = ['claude-opus-4-8', 'claude-sonnet-4-6'];
66
+ export const ONE_M_CONTEXT_MODEL_PREFIXES = ['claude-opus-5', 'claude-opus-4-8', 'claude-sonnet-4-6'];
67
67
  const ONE_M_CONTEXT_MODEL_ALIASES = ['opus', 'sonnet'];
68
68
  const CLAUDE_CONTEXT_MODEL_ALIASES = ['opus', 'sonnet', 'haiku'];
69
69
  export function isClaudeContextUsageModel(model) {
@@ -29,8 +29,9 @@ function parseAid(value) {
29
29
  return { ok: true, aid };
30
30
  }
31
31
  /**
32
- * The daemon accepts only the self-scoped AID commands exposed to managed
33
- * tasks. Parsing here is deliberately narrower than the standalone CLI.
32
+ * The daemon accepts only the narrowly scoped AID commands exposed to managed
33
+ * tasks. Public lookup/get may name any valid AID; local show/publish remain
34
+ * subject to the self-AID boundary enforced by the command handler.
34
35
  */
35
36
  export function resolveManagedAidOperation(argv) {
36
37
  const args = argv[0] === 'aid' ? argv.slice(1) : argv;
@@ -67,7 +68,21 @@ export function resolveManagedAidOperation(argv) {
67
68
  return {
68
69
  ok: false,
69
70
  code: 'NOT_ALLOWED',
70
- reason: 'Managed AID operations only allow exact self-scoped show, lookup, agentmd get, or agentmd put commands with an optional --format json suffix',
71
+ reason: 'Managed AID operations only allow exact show, lookup, agentmd get, or agentmd put commands with an optional --format json suffix',
72
+ };
73
+ }
74
+ export function managedAidShowViewForRole(role) {
75
+ return role === 'owner' || role === 'admin' ? 'full' : 'redacted';
76
+ }
77
+ export function redactAidShowResult(value) {
78
+ return {
79
+ aid: value.aid,
80
+ redacted: true,
81
+ hasAgentMd: value.hasAgentMd,
82
+ certExpiresAt: value.certExpiresAt,
83
+ certSubject: value.certSubject,
84
+ certExpired: value.certExpired,
85
+ agentMdSignature: value.agentMdSignature,
71
86
  };
72
87
  }
73
88
  const defaultDependencies = () => ({
@@ -80,12 +95,19 @@ const defaultDependencies = () => ({
80
95
  readFileSync: fs.readFileSync,
81
96
  });
82
97
  /** Execute a validated AID operation from the daemon-owned host filesystem. */
83
- export async function executeManagedAidOperation(command, overrides = {}) {
98
+ export async function executeManagedAidOperation(command, options = {}) {
99
+ const { showView = 'full', ...overrides } = options;
84
100
  const deps = { ...defaultDependencies(), ...overrides };
85
101
  const aunPath = deps.root;
86
102
  switch (command.kind) {
87
- case 'show':
88
- return { kind: command.kind, aid: command.aid, value: await deps.aidShow(command.aid, { aunPath }) };
103
+ case 'show': {
104
+ const value = await deps.aidShow(command.aid, { aunPath });
105
+ return {
106
+ kind: command.kind,
107
+ aid: command.aid,
108
+ value: showView === 'redacted' ? redactAidShowResult(value) : value,
109
+ };
110
+ }
89
111
  case 'lookup':
90
112
  return { kind: command.kind, aid: command.aid, value: await deps.aidLookup(command.aid) };
91
113
  case 'agentmd.get':
@@ -7,6 +7,7 @@ import { AUN_KEYSTORE_ENCRYPTION_SEED } from './encryption-seed-policy.js';
7
7
  // pages so a large backlog is drained without monopolizing the sync loop.
8
8
  const FULL_GROUP_PULL_MAX_PAGES = 10;
9
9
  const GROUP_PULL_PAGINATION_PATCH = Symbol('evolcore.groupPullPaginationPatch');
10
+ const RELIABLE_MESSAGE_DELIVERY_PATCH = Symbol('evolcore.reliableMessageDeliveryPatch');
10
11
  /**
11
12
  * Slot 命名约定(基于 fastaun 0.4.3 隔离键语义)。
12
13
  *
@@ -106,6 +107,46 @@ export function enableFullGroupPullPagination(client) {
106
107
  target._pullGroupV2 = wrappedPull;
107
108
  return true;
108
109
  }
110
+ /**
111
+ * Make SDK pull delivery wait until EvolCore's application handlers finish.
112
+ *
113
+ * fastaun 0.5.13 publishes message events with dispatcher.enqueue(), then
114
+ * advances its sequence tracker immediately. That is a transport watermark,
115
+ * so a daemon restart can acknowledge a message before the application has
116
+ * durably claimed it. The SDK keeps _publishAppEvent private, but the public
117
+ * client is intentionally adapted here in one place: preserve the SDK's
118
+ * normal publication path and wait for its dispatcher queue for pulled
119
+ * message events before the pull operation commits the sequence.
120
+ */
121
+ export function enableReliableMessageDelivery(client) {
122
+ const target = client;
123
+ if (target[RELIABLE_MESSAGE_DELIVERY_PATCH])
124
+ return false;
125
+ const publish = target._publishAppEvent;
126
+ const dispatcher = target._dispatcher;
127
+ if (typeof publish !== 'function' || !dispatcher || typeof dispatcher.flush !== 'function')
128
+ return false;
129
+ const wrappedPublish = async function (event, payload, source, ...rest) {
130
+ const result = await publish.call(this, event, payload, source, ...rest);
131
+ // Pull/recovery paths must not advance SeqTracker until the application
132
+ // handlers have completed. Push delivery has no pull commit to gate and
133
+ // remains asynchronous as intended by the SDK.
134
+ const reliable = (event === 'message.received' || event === 'group.message_created')
135
+ && source !== 'push'
136
+ && source !== 'inline-push';
137
+ if (reliable)
138
+ await dispatcher.flush();
139
+ return result;
140
+ };
141
+ Object.defineProperty(target, RELIABLE_MESSAGE_DELIVERY_PATCH, {
142
+ configurable: false,
143
+ enumerable: false,
144
+ value: true,
145
+ writable: false,
146
+ });
147
+ target._publishAppEvent = wrappedPublish;
148
+ return true;
149
+ }
109
150
  /** 加载本地 AID 值对象(用于离线签名/验签,无需连接)。load 失败抛 AidLoadError。 */
110
151
  export function loadAid(store, aid) {
111
152
  const r = store.load(aid);
@@ -797,7 +797,12 @@ export function resolveManagedFsOperation(argv) {
797
797
  const destination = remoteOrError(positionals[1]);
798
798
  if (!('groupId' in destination))
799
799
  return destination;
800
- const source = positionals[0].includes(':') ? remoteOrError(positionals[0]) : undefined;
800
+ // Windows absolute paths contain a drive-letter colon, but are local
801
+ // upload sources rather than managed group references.
802
+ const isWindowsAbsolutePath = /^[A-Za-z]:[\\/]/.test(positionals[0]);
803
+ const source = positionals[0].includes(':') && !isWindowsAbsolutePath
804
+ ? remoteOrError(positionals[0])
805
+ : undefined;
801
806
  if (source && !('groupId' in source))
802
807
  return source;
803
808
  if (source && source.groupId !== destination.groupId)
@@ -1,5 +1,6 @@
1
1
  import crypto from 'crypto';
2
- import { agentActivityOutboxPath, agentOutboxPath } from '../paths.js';
2
+ import fs from 'fs';
3
+ import { agentActivityOutboxPath, agentOutboxPath, legacyAgentActivityOutboxPath, legacyAgentOutboxPath, legacyFlatOutboxPath, } from '../paths.js';
3
4
  import { atomicRead, atomicWrite } from '../utils/atomic-write.js';
4
5
  import { isDeliveryTarget, isDeliveryTargetForChannel, sameDeliveryTarget } from '../core/message/message-utils.js';
5
6
  export const DEFAULT_OUTBOX_MAX_ENTRIES = 200;
@@ -10,11 +11,13 @@ const MAX_TERMINAL_ENTRIES_PER_AID = 100;
10
11
  const QUEUE_CONFIG = {
11
12
  default: {
12
13
  file: agentOutboxPath,
14
+ legacyFiles: aid => [legacyAgentOutboxPath(aid), legacyFlatOutboxPath(aid)],
13
15
  maxEntries: DEFAULT_OUTBOX_MAX_ENTRIES,
14
16
  defaultTtl: DEFAULT_OUTBOX_TTL_MS,
15
17
  },
16
18
  activity: {
17
19
  file: agentActivityOutboxPath,
20
+ legacyFiles: aid => [legacyAgentActivityOutboxPath(aid)],
18
21
  maxEntries: ACTIVITY_OUTBOX_MAX_ENTRIES,
19
22
  defaultTtl: ACTIVITY_OUTBOX_TTL_MS,
20
23
  },
@@ -28,6 +31,55 @@ export function defaultTtl(queue = 'default') {
28
31
  function outboxFile(aid, queue = 'default') {
29
32
  return queueConfig(queue).file(aid);
30
33
  }
34
+ const migratedOutboxes = new Set();
35
+ function parseEntriesFile(file) {
36
+ try {
37
+ const content = atomicRead(file)?.trim();
38
+ if (!content)
39
+ return [];
40
+ return content.split('\n').map(line => {
41
+ try {
42
+ return JSON.parse(line);
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ }).filter((entry) => entry !== null);
48
+ }
49
+ catch {
50
+ return [];
51
+ }
52
+ }
53
+ /** Import old outbox layouts without deleting their recovery copies. */
54
+ function ensureOutboxMigrated(aid, queue) {
55
+ const canonical = outboxFile(aid, queue);
56
+ const key = canonical;
57
+ if (migratedOutboxes.has(key))
58
+ return;
59
+ const merged = fs.existsSync(canonical) ? parseEntriesFile(canonical) : [];
60
+ const ids = new Set(merged.map(entry => entry.id));
61
+ let changed = false;
62
+ for (const legacy of queueConfig(queue).legacyFiles(aid)) {
63
+ if (legacy === canonical || !fs.existsSync(legacy))
64
+ continue;
65
+ for (const entry of parseEntriesFile(legacy)) {
66
+ if (ids.has(entry.id))
67
+ continue;
68
+ ids.add(entry.id);
69
+ merged.push(entry);
70
+ changed = true;
71
+ }
72
+ }
73
+ if (!changed) {
74
+ migratedOutboxes.add(key);
75
+ return;
76
+ }
77
+ const content = merged.length > 0
78
+ ? merged.map(entry => JSON.stringify(entry)).join('\n') + '\n'
79
+ : '';
80
+ atomicWrite(canonical, content);
81
+ migratedOutboxes.add(key);
82
+ }
31
83
  function entryQueue(entry) {
32
84
  return entry.queue ?? 'default';
33
85
  }
@@ -50,25 +102,11 @@ export function isDeliveryForChannel(value, channelId) {
50
102
  return isDeliveryTargetForChannel(value, channelId);
51
103
  }
52
104
  function readEntries(aid, queue = 'default') {
53
- const file = outboxFile(aid, queue);
54
- try {
55
- const content = atomicRead(file)?.trim();
56
- if (!content)
57
- return [];
58
- return content.split('\n').map(line => {
59
- try {
60
- return JSON.parse(line);
61
- }
62
- catch {
63
- return null;
64
- }
65
- }).filter((e) => e !== null);
66
- }
67
- catch {
68
- return [];
69
- }
105
+ ensureOutboxMigrated(aid, queue);
106
+ return parseEntriesFile(outboxFile(aid, queue));
70
107
  }
71
108
  function writeEntries(aid, entries, queue = 'default') {
109
+ ensureOutboxMigrated(aid, queue);
72
110
  const file = outboxFile(aid, queue);
73
111
  const boundedEntries = trimFinalEntries(entries);
74
112
  const content = boundedEntries.length > 0
@@ -9,11 +9,10 @@ export async function createShortConnection(aid, opts) {
9
9
  return client.call(method, params);
10
10
  },
11
11
  group: {
12
- inviteMember: (params) => client.group.inviteMember(params),
13
- listMyInvites: (params) => client.group.listMyInvites(params),
14
- acceptInvite: (params) => client.group.acceptInvite(params),
15
- rejectInvite: (params) => client.group.rejectInvite(params),
16
- revokeInvite: (params) => client.group.revokeInvite(params),
12
+ createInviteCode: (params) => client.group.createInviteCode(params),
13
+ listInviteCodes: (params) => client.group.listInviteCodes(params),
14
+ useInviteCode: (params) => client.group.useInviteCode(params),
15
+ revokeInviteCode: (params) => client.group.revokeInviteCode(params),
17
16
  },
18
17
  async close() {
19
18
  try {