@actant/core 0.1.2 → 0.2.0

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/dist/index.js CHANGED
@@ -1061,11 +1061,13 @@ var DomainContextSchema = z2.object({
1061
1061
  extensions: z2.record(z2.string(), z2.array(z2.unknown())).optional()
1062
1062
  });
1063
1063
  var AgentBackendSchema = z2.object({
1064
- type: z2.enum(["cursor", "claude-code", "custom"]),
1064
+ type: z2.enum(["cursor", "cursor-agent", "claude-code", "custom", "pi"]),
1065
1065
  config: z2.record(z2.string(), z2.unknown()).optional()
1066
1066
  });
1067
1067
  var ModelProviderSchema = z2.object({
1068
- type: z2.enum(["anthropic", "openai", "custom"]),
1068
+ type: z2.enum(["anthropic", "openai", "openai-compatible", "custom"]),
1069
+ protocol: z2.enum(["http", "websocket", "grpc"]).optional().default("http"),
1070
+ baseUrl: z2.string().optional(),
1069
1071
  config: z2.record(z2.string(), z2.unknown()).optional()
1070
1072
  });
1071
1073
  var InitializerStepSchema = z2.object({
@@ -1721,9 +1723,9 @@ import { createLogger as createLogger12 } from "@actant/shared";
1721
1723
  var logger11 = createLogger12("template-file-watcher");
1722
1724
  var DEFAULT_DEBOUNCE_MS = 300;
1723
1725
  var TemplateFileWatcher = class {
1724
- constructor(templatesDir, registry, options) {
1726
+ constructor(templatesDir, registry3, options) {
1725
1727
  this.templatesDir = templatesDir;
1726
- this.registry = registry;
1728
+ this.registry = registry3;
1727
1729
  this.debounceMs = options?.debounceMs ?? DEFAULT_DEBOUNCE_MS;
1728
1730
  }
1729
1731
  watcher = null;
@@ -1846,7 +1848,7 @@ var LaunchModeSchema = z3.enum([
1846
1848
  ]);
1847
1849
  var ProcessOwnershipSchema = z3.enum(["managed", "external"]);
1848
1850
  var WorkspacePolicySchema = z3.enum(["persistent", "ephemeral"]);
1849
- var AgentBackendTypeSchema = z3.enum(["cursor", "claude-code", "custom"]);
1851
+ var AgentBackendTypeSchema = z3.enum(["cursor", "cursor-agent", "claude-code", "custom", "pi"]);
1850
1852
  var PermissionModeSchema2 = z3.enum([
1851
1853
  "default",
1852
1854
  "acceptEdits",
@@ -1947,12 +1949,12 @@ async function updateInstanceMeta(workspaceDir, patch) {
1947
1949
  await writeInstanceMeta(workspaceDir, updated);
1948
1950
  return updated;
1949
1951
  }
1950
- async function scanInstances(instancesBaseDir, registry) {
1952
+ async function scanInstances(instancesBaseDir, registry3) {
1951
1953
  const valid = [];
1952
1954
  const corrupted = [];
1953
1955
  const validNames = /* @__PURE__ */ new Set();
1954
- if (registry) {
1955
- for (const entry of registry.list()) {
1956
+ if (registry3) {
1957
+ for (const entry of registry3.list()) {
1956
1958
  if (entry.status === "orphaned") continue;
1957
1959
  try {
1958
1960
  const st = await stat5(entry.workspacePath);
@@ -2143,8 +2145,8 @@ var logger13 = createLogger14("initialization-pipeline");
2143
2145
  var DEFAULT_STEP_TIMEOUT_MS = 6e4;
2144
2146
  var DEFAULT_TOTAL_TIMEOUT_MS = 3e5;
2145
2147
  var InitializationPipeline = class {
2146
- constructor(registry, options) {
2147
- this.registry = registry;
2148
+ constructor(registry3, options) {
2149
+ this.registry = registry3;
2148
2150
  this.stepTimeoutMs = options?.defaultStepTimeoutMs ?? DEFAULT_STEP_TIMEOUT_MS;
2149
2151
  this.totalTimeoutMs = options?.totalTimeoutMs ?? DEFAULT_TOTAL_TIMEOUT_MS;
2150
2152
  this.onProgress = options?.onProgress;
@@ -2273,6 +2275,9 @@ var AgentInitializer = class {
2273
2275
  }
2274
2276
  builder;
2275
2277
  pipeline;
2278
+ get workspaceBuilder() {
2279
+ return this.builder;
2280
+ }
2276
2281
  /**
2277
2282
  * Create a new Agent Instance.
2278
2283
  * 1. Resolve template from registry
@@ -2462,7 +2467,9 @@ import { createLogger as createLogger16 } from "@actant/shared";
2462
2467
  var logger15 = createLogger16("context-materializer");
2463
2468
  var BACKEND_CONFIG_DIR = {
2464
2469
  cursor: ".cursor",
2470
+ "cursor-agent": ".cursor",
2465
2471
  "claude-code": ".claude",
2472
+ pi: ".pi",
2466
2473
  custom: ".cursor"
2467
2474
  };
2468
2475
  var ContextMaterializer = class {
@@ -2871,10 +2878,10 @@ var NpmInstallStep = class extends InitializerStepExecutor {
2871
2878
  return { valid: issues.length === 0, issues };
2872
2879
  }
2873
2880
  async execute(context, config) {
2874
- const { packageManager = "npm", cwd = ".", args = [], registry } = config;
2881
+ const { packageManager = "npm", cwd = ".", args = [], registry: registry3 } = config;
2875
2882
  const workDir = join16(context.workspaceDir, cwd);
2876
2883
  const cmdArgs = ["install", ...args];
2877
- if (registry) cmdArgs.push("--registry", registry);
2884
+ if (registry3) cmdArgs.push("--registry", registry3);
2878
2885
  context.logger.debug({ packageManager, cwd: workDir, args: cmdArgs }, "Installing dependencies");
2879
2886
  const result = await runInstall(packageManager, cmdArgs, workDir);
2880
2887
  if (result.exitCode !== 0) {
@@ -2916,13 +2923,13 @@ function runInstall(pm, args, cwd) {
2916
2923
 
2917
2924
  // src/initializer/steps/index.ts
2918
2925
  function createDefaultStepRegistry() {
2919
- const registry = new StepRegistry();
2920
- registry.register(new MkdirStep());
2921
- registry.register(new ExecStep());
2922
- registry.register(new FileCopyStep());
2923
- registry.register(new GitCloneStep());
2924
- registry.register(new NpmInstallStep());
2925
- return registry;
2926
+ const registry3 = new StepRegistry();
2927
+ registry3.register(new MkdirStep());
2928
+ registry3.register(new ExecStep());
2929
+ registry3.register(new FileCopyStep());
2930
+ registry3.register(new GitCloneStep());
2931
+ registry3.register(new NpmInstallStep());
2932
+ return registry3;
2926
2933
  }
2927
2934
 
2928
2935
  // src/manager/agent-manager.ts
@@ -2936,36 +2943,120 @@ import {
2936
2943
  createLogger as createLogger23
2937
2944
  } from "@actant/shared";
2938
2945
 
2939
- // src/manager/launcher/backend-resolver.ts
2940
- var IS_WINDOWS = process.platform === "win32";
2941
- var DEFAULT_COMMANDS = {
2942
- cursor: () => IS_WINDOWS ? "cursor.cmd" : "cursor",
2943
- "claude-code": () => IS_WINDOWS ? "claude-agent-acp.cmd" : "claude-agent-acp",
2944
- custom: () => {
2945
- throw new Error("Custom backend requires explicit executablePath in backend config");
2946
+ // src/manager/launcher/backend-registry.ts
2947
+ var registry = /* @__PURE__ */ new Map();
2948
+ function registerBackend(descriptor) {
2949
+ registry.set(descriptor.type, descriptor);
2950
+ }
2951
+ function getBackendDescriptor(type) {
2952
+ const desc = registry.get(type);
2953
+ if (!desc) {
2954
+ throw new Error(
2955
+ `Backend "${type}" is not registered. Ensure the backend package is installed and registerBackend() was called at startup.`
2956
+ );
2946
2957
  }
2947
- };
2958
+ return desc;
2959
+ }
2960
+ function supportsMode(type, mode) {
2961
+ const desc = registry.get(type);
2962
+ return desc != null && desc.supportedModes.includes(mode);
2963
+ }
2964
+ function requireMode(type, mode) {
2965
+ const desc = getBackendDescriptor(type);
2966
+ if (!desc.supportedModes.includes(mode)) {
2967
+ const supported = desc.supportedModes.join(", ");
2968
+ throw new Error(
2969
+ `Backend "${type}" does not support "${mode}" mode. Supported modes: [${supported}]. ` + (mode === "resolve" ? `Use \`agent start\` or \`agent run\` instead.` : mode === "open" ? `This backend has no native TUI/UI to open.` : `Use \`agent resolve\` or \`agent open\` instead.`)
2970
+ );
2971
+ }
2972
+ }
2973
+ function getPlatformCommand(cmd) {
2974
+ return process.platform === "win32" ? cmd.win32 : cmd.default;
2975
+ }
2976
+
2977
+ // src/manager/launcher/builtin-backends.ts
2978
+ function registerBuiltinBackends() {
2979
+ registerBackend({
2980
+ type: "cursor",
2981
+ supportedModes: ["resolve", "open"],
2982
+ resolveCommand: { win32: "cursor.cmd", default: "cursor" },
2983
+ openCommand: { win32: "cursor.cmd", default: "cursor" }
2984
+ });
2985
+ registerBackend({
2986
+ type: "cursor-agent",
2987
+ supportedModes: ["resolve", "open", "acp"],
2988
+ resolveCommand: { win32: "cursor.cmd", default: "cursor" },
2989
+ openCommand: { win32: "cursor.cmd", default: "cursor" }
2990
+ });
2991
+ registerBackend({
2992
+ type: "claude-code",
2993
+ supportedModes: ["resolve", "acp"],
2994
+ resolveCommand: { win32: "claude-agent-acp.cmd", default: "claude-agent-acp" }
2995
+ });
2996
+ registerBackend({
2997
+ type: "custom",
2998
+ supportedModes: ["resolve"]
2999
+ });
3000
+ }
3001
+ registerBuiltinBackends();
3002
+
3003
+ // src/manager/launcher/backend-resolver.ts
2948
3004
  function isAcpBackend(backendType) {
2949
- return backendType === "claude-code";
3005
+ return supportsMode(backendType, "acp");
3006
+ }
3007
+ function isAcpOnlyBackend(backendType) {
3008
+ const desc = getBackendDescriptor(backendType);
3009
+ return supportsMode(backendType, "acp") && desc.acpOwnsProcess === true;
2950
3010
  }
2951
3011
  function buildArgs(backendType, workspaceDir, backendConfig) {
2952
- switch (backendType) {
2953
- case "cursor":
2954
- return [workspaceDir];
2955
- case "claude-code":
2956
- return [];
2957
- case "custom": {
2958
- const configArgs = backendConfig?.args;
2959
- if (Array.isArray(configArgs)) {
2960
- return configArgs.map(String);
2961
- }
2962
- return [workspaceDir];
2963
- }
3012
+ const desc = getBackendDescriptor(backendType);
3013
+ if (backendType === "custom") {
3014
+ const configArgs = backendConfig?.args;
3015
+ if (Array.isArray(configArgs)) return configArgs.map(String);
3016
+ return [workspaceDir];
3017
+ }
3018
+ if (desc.supportedModes.includes("open") && !desc.supportedModes.includes("acp")) {
3019
+ return [workspaceDir];
3020
+ }
3021
+ if (desc.supportedModes.includes("acp")) {
3022
+ return [];
2964
3023
  }
3024
+ return [workspaceDir];
2965
3025
  }
2966
3026
  function resolveBackend(backendType, workspaceDir, backendConfig) {
3027
+ requireMode(backendType, "resolve");
3028
+ const desc = getBackendDescriptor(backendType);
3029
+ const explicitPath = backendConfig?.executablePath;
3030
+ const command = typeof explicitPath === "string" && explicitPath.length > 0 ? explicitPath : desc.resolveCommand ? getPlatformCommand(desc.resolveCommand) : (() => {
3031
+ throw new Error(`Backend "${backendType}" has no resolveCommand configured.`);
3032
+ })();
3033
+ return {
3034
+ command,
3035
+ args: buildArgs(backendType, workspaceDir, backendConfig)
3036
+ };
3037
+ }
3038
+ function openBackend(backendType, workspaceDir) {
3039
+ requireMode(backendType, "open");
3040
+ const desc = getBackendDescriptor(backendType);
3041
+ if (!desc.openCommand) {
3042
+ throw new Error(`Backend "${backendType}" has no openCommand configured.`);
3043
+ }
3044
+ return {
3045
+ command: getPlatformCommand(desc.openCommand),
3046
+ args: [workspaceDir]
3047
+ };
3048
+ }
3049
+ function resolveAcpBackend(backendType, workspaceDir, backendConfig) {
3050
+ requireMode(backendType, "acp");
3051
+ const desc = getBackendDescriptor(backendType);
3052
+ if (desc.acpResolver) {
3053
+ return desc.acpResolver(workspaceDir, backendConfig);
3054
+ }
2967
3055
  const explicitPath = backendConfig?.executablePath;
2968
- const command = typeof explicitPath === "string" && explicitPath.length > 0 ? explicitPath : DEFAULT_COMMANDS[backendType]();
3056
+ const commandSource = desc.acpCommand ?? desc.resolveCommand;
3057
+ const command = typeof explicitPath === "string" && explicitPath.length > 0 ? explicitPath : commandSource ? getPlatformCommand(commandSource) : (() => {
3058
+ throw new Error(`Backend "${backendType}" has no command configured for ACP spawn.`);
3059
+ })();
2969
3060
  return {
2970
3061
  command,
2971
3062
  args: buildArgs(backendType, workspaceDir, backendConfig)
@@ -3384,16 +3475,27 @@ var CursorCommunicator = class {
3384
3475
  };
3385
3476
 
3386
3477
  // src/communicator/create-communicator.ts
3387
- function createCommunicator(backendType) {
3478
+ var registry2 = /* @__PURE__ */ new Map();
3479
+ function registerCommunicator(backendType, factory) {
3480
+ registry2.set(backendType, factory);
3481
+ }
3482
+ function createCommunicator(backendType, backendConfig) {
3483
+ const registered = registry2.get(backendType);
3484
+ if (registered) return registered(backendConfig);
3388
3485
  switch (backendType) {
3389
3486
  case "claude-code":
3390
3487
  return new ClaudeCodeCommunicator();
3391
3488
  case "cursor":
3489
+ case "cursor-agent":
3392
3490
  return new CursorCommunicator();
3393
3491
  case "custom":
3394
3492
  throw new Error(
3395
3493
  "Custom backend communicator not yet supported. Implement AgentCommunicator for your backend."
3396
3494
  );
3495
+ case "pi":
3496
+ throw new Error(
3497
+ "Pi backend communicator not registered. Ensure @actant/pi is installed and initialized."
3498
+ );
3397
3499
  }
3398
3500
  }
3399
3501
 
@@ -3486,13 +3588,16 @@ var AgentManager = class {
3486
3588
  return { meta, created };
3487
3589
  }
3488
3590
  /**
3489
- * Start an agent — launch the backend process.
3490
- * For ACP backends, also establishes ACP connection (initialize + session/new).
3591
+ * Start an agent — launch the backend process via ACP.
3592
+ * Requires the backend to support "acp" mode.
3593
+ * For acpOwnsProcess backends, ProcessLauncher is skipped.
3491
3594
  * @throws {AgentNotFoundError} if agent is not in cache
3492
3595
  * @throws {AgentAlreadyRunningError} if agent is already running
3596
+ * @throws {Error} if backend does not support "acp" mode
3493
3597
  */
3494
3598
  async startAgent(name) {
3495
3599
  const meta = this.requireAgent(name);
3600
+ requireMode(meta.backendType, "acp");
3496
3601
  if (meta.status === "running" || meta.status === "starting") {
3497
3602
  throw new AgentAlreadyRunningError(name);
3498
3603
  }
@@ -3500,23 +3605,34 @@ var AgentManager = class {
3500
3605
  const starting = await updateInstanceMeta(dir, { status: "starting" });
3501
3606
  this.cache.set(name, starting);
3502
3607
  try {
3503
- const proc = await this.launcher.launch(dir, starting);
3504
- this.processes.set(name, proc);
3505
- if (isAcpBackend(meta.backendType) && this.acpManager) {
3506
- const { command, args } = resolveBackend(meta.backendType, dir, meta.backendConfig);
3507
- await this.acpManager.connect(name, {
3608
+ const acpOnly = isAcpOnlyBackend(meta.backendType);
3609
+ let pid;
3610
+ if (!acpOnly) {
3611
+ const proc = await this.launcher.launch(dir, starting);
3612
+ this.processes.set(name, proc);
3613
+ pid = proc.pid;
3614
+ }
3615
+ if (this.acpManager) {
3616
+ const { command, args } = resolveAcpBackend(meta.backendType, dir, meta.backendConfig);
3617
+ const connResult = await this.acpManager.connect(name, {
3508
3618
  command,
3509
3619
  args,
3510
3620
  cwd: dir,
3511
3621
  connectionOptions: { autoApprove: true }
3512
3622
  });
3513
- logger22.info({ name }, "ACP connection established");
3623
+ logger22.info({ name, acpOnly }, "ACP connection established");
3624
+ if (acpOnly && "pid" in connResult && typeof connResult.pid === "number") {
3625
+ pid = connResult.pid;
3626
+ this.processes.set(name, { pid, workspaceDir: dir, instanceName: name });
3627
+ }
3514
3628
  }
3515
- const running = await updateInstanceMeta(dir, { status: "running", pid: proc.pid });
3629
+ const running = await updateInstanceMeta(dir, { status: "running", pid });
3516
3630
  this.cache.set(name, running);
3517
- this.watcher.watch(name, proc.pid);
3631
+ if (pid) {
3632
+ this.watcher.watch(name, pid);
3633
+ }
3518
3634
  this.restartTracker.recordStart(name);
3519
- logger22.info({ name, pid: proc.pid, launchMode: starting.launchMode, acp: isAcpBackend(meta.backendType) }, "Agent started");
3635
+ logger22.info({ name, pid, launchMode: starting.launchMode, acp: true }, "Agent started");
3520
3636
  } catch (err) {
3521
3637
  if (this.acpManager?.has(name)) {
3522
3638
  await this.acpManager.disconnect(name).catch(() => {
@@ -3611,6 +3727,17 @@ var AgentManager = class {
3611
3727
  created
3612
3728
  };
3613
3729
  }
3730
+ /**
3731
+ * Open an agent's native TUI/UI (e.g. `cursor <dir>`).
3732
+ * Requires the backend to support "open" mode.
3733
+ * @throws if backend does not support "open" mode
3734
+ */
3735
+ async openAgent(name) {
3736
+ const meta = this.requireAgent(name);
3737
+ const dir = join17(this.instancesBaseDir, name);
3738
+ const resolved = openBackend(meta.backendType, dir);
3739
+ return resolved;
3740
+ }
3614
3741
  /**
3615
3742
  * Register an externally-spawned process with the manager.
3616
3743
  * Sets processOwnership to "external" and registers ProcessWatcher monitoring.
@@ -3685,14 +3812,46 @@ var AgentManager = class {
3685
3812
  }
3686
3813
  /**
3687
3814
  * Send a prompt to an agent and stream the response.
3688
- * Uses ACP connection if available, otherwise falls back to CLI pipe mode.
3815
+ * Uses ACP connection if available, otherwise falls back to communicator.
3689
3816
  */
3690
3817
  streamPrompt(name, prompt, options) {
3691
3818
  const meta = this.requireAgent(name);
3819
+ if (this.acpManager?.has(name)) {
3820
+ const conn = this.acpManager.getConnection(name);
3821
+ const sessionId = this.acpManager.getPrimarySessionId(name);
3822
+ if (conn && sessionId) {
3823
+ logger22.debug({ name, sessionId }, "Streaming prompt via ACP");
3824
+ return this.streamFromAcp(conn, sessionId, prompt);
3825
+ }
3826
+ }
3692
3827
  const dir = join17(this.instancesBaseDir, name);
3693
3828
  const communicator = createCommunicator(meta.backendType);
3694
3829
  return communicator.streamPrompt(dir, prompt, options);
3695
3830
  }
3831
+ async *streamFromAcp(conn, sessionId, prompt) {
3832
+ try {
3833
+ for await (const event of conn.streamPrompt(sessionId, prompt)) {
3834
+ const record = event;
3835
+ const type = record["type"];
3836
+ if (type === "text" || type === "assistant") {
3837
+ const content = record["content"] ?? record["message"] ?? "";
3838
+ yield { type: "text", content };
3839
+ } else if (type === "tool_use") {
3840
+ const toolName = record["name"];
3841
+ yield { type: "tool_use", content: toolName ? `[Tool: ${toolName}]` : "" };
3842
+ } else if (type === "result") {
3843
+ yield { type: "result", content: record["result"] ?? "" };
3844
+ } else if (type === "error") {
3845
+ const errMsg = record["error"]?.["message"];
3846
+ yield { type: "error", content: errMsg ?? "Unknown error" };
3847
+ } else if (typeof record["content"] === "string") {
3848
+ yield { type: "text", content: record["content"] };
3849
+ }
3850
+ }
3851
+ } catch (err) {
3852
+ yield { type: "error", content: err instanceof Error ? err.message : String(err) };
3853
+ }
3854
+ }
3696
3855
  /**
3697
3856
  * Send a message to a running agent via its ACP session.
3698
3857
  * Unlike runPrompt, this requires the agent to be started with ACP.
@@ -4901,11 +5060,13 @@ var SourceManager = class {
4901
5060
  homeDir;
4902
5061
  sourcesFilePath;
4903
5062
  cacheDir;
4904
- constructor(homeDir, managers) {
5063
+ skipDefaultSource;
5064
+ constructor(homeDir, managers, options) {
4905
5065
  this.homeDir = homeDir;
4906
5066
  this.managers = managers;
4907
5067
  this.sourcesFilePath = join21(homeDir, "sources.json");
4908
5068
  this.cacheDir = join21(homeDir, "sources-cache");
5069
+ this.skipDefaultSource = options?.skipDefaultSource ?? false;
4909
5070
  }
4910
5071
  // ---------------------------------------------------------------------------
4911
5072
  // Source CRUD
@@ -5039,14 +5200,13 @@ var SourceManager = class {
5039
5200
  // Initialization (load persisted sources on startup)
5040
5201
  // ---------------------------------------------------------------------------
5041
5202
  async initialize() {
5042
- let entries;
5203
+ let entries = [];
5043
5204
  try {
5044
5205
  const raw = await readFile7(this.sourcesFilePath, "utf-8");
5045
5206
  const data = JSON.parse(raw);
5046
5207
  entries = Object.entries(data.sources ?? {}).map(([name, config]) => ({ name, config }));
5047
5208
  } catch {
5048
5209
  logger30.debug("No sources.json found, starting with empty sources");
5049
- return;
5050
5210
  }
5051
5211
  for (const entry of entries) {
5052
5212
  try {
@@ -5059,6 +5219,21 @@ var SourceManager = class {
5059
5219
  logger30.warn({ name: entry.name, error: err }, "Failed to restore source, skipping");
5060
5220
  }
5061
5221
  }
5222
+ await this.ensureDefaultSource();
5223
+ }
5224
+ /**
5225
+ * Registers the official actant-hub as the default source if not already present.
5226
+ * Fails silently when offline or the repo is unreachable.
5227
+ */
5228
+ async ensureDefaultSource() {
5229
+ if (this.skipDefaultSource) return;
5230
+ if (this.sources.has(DEFAULT_SOURCE_NAME)) return;
5231
+ try {
5232
+ await this.addSource(DEFAULT_SOURCE_NAME, DEFAULT_SOURCE_CONFIG);
5233
+ logger30.info("Default source registered: %s", DEFAULT_SOURCE_NAME);
5234
+ } catch (err) {
5235
+ logger30.debug({ error: err }, "Failed to register default source (offline?), skipping");
5236
+ }
5062
5237
  }
5063
5238
  // ---------------------------------------------------------------------------
5064
5239
  // Internals
@@ -5300,16 +5475,24 @@ export {
5300
5475
  createCommunicator,
5301
5476
  createDefaultStepRegistry,
5302
5477
  createLauncher,
5478
+ getBackendDescriptor,
5303
5479
  getLaunchModeHandler,
5304
5480
  globMatch,
5305
5481
  isAcpBackend,
5482
+ isAcpOnlyBackend,
5306
5483
  isProcessAlive,
5307
5484
  metaFilePath,
5485
+ openBackend,
5308
5486
  readInstanceMeta,
5487
+ registerBackend,
5488
+ registerCommunicator,
5489
+ requireMode,
5490
+ resolveAcpBackend,
5309
5491
  resolveBackend,
5310
5492
  resolvePermissions,
5311
5493
  resolvePermissionsWithMcp,
5312
5494
  scanInstances,
5495
+ supportsMode,
5313
5496
  toAgentTemplate,
5314
5497
  updateInstanceMeta,
5315
5498
  validateBackendConfig,