@openacp/cli 2026.406.5 → 2026.408.1

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/cli.js CHANGED
@@ -362,7 +362,7 @@ async function runUpdate() {
362
362
  });
363
363
  }
364
364
  async function checkAndPromptUpdate() {
365
- if (process.env.OPENACP_DEV_LOOP || process.env.OPENACP_SKIP_UPDATE_CHECK) return;
365
+ if (process.env.OPENACP_DEV_LOOP || process.env.OPENACP_SKIP_UPDATE_CHECK || !process.stdin.isTTY) return;
366
366
  const current = getCurrentVersion();
367
367
  if (current === "0.0.0-dev") return;
368
368
  const latest = await getLatestVersion();
@@ -4879,15 +4879,6 @@ function stripPythonPackageVersion(pkg) {
4879
4879
  async function installAgent(agent, store, progress, agentsDir) {
4880
4880
  const agentKey = getAgentAlias(agent.id);
4881
4881
  await progress?.onStart(agent.id, agent.name);
4882
- await progress?.onStep("Checking requirements...");
4883
- const depResult = checkDependencies(agent.id);
4884
- if (!depResult.available) {
4885
- const hints = depResult.missing.map((m) => ` ${m.label}: ${m.installHint}`).join("\n");
4886
- const msg = `${agent.name} needs some tools installed first:
4887
- ${hints}`;
4888
- await progress?.onError(msg);
4889
- return { ok: false, agentKey, error: msg };
4890
- }
4891
4882
  const dist = resolveDistribution(agent);
4892
4883
  if (!dist) {
4893
4884
  const platformKey = getPlatformKey();
@@ -4901,6 +4892,7 @@ Install it with: pip install uv`;
4901
4892
  await progress?.onError(msg, "pip install uv");
4902
4893
  return { ok: false, agentKey, error: msg, hint: "pip install uv" };
4903
4894
  }
4895
+ const depResult = checkDependencies(agent.id);
4904
4896
  let binaryPath;
4905
4897
  if (dist.type === "binary") {
4906
4898
  try {
@@ -4916,8 +4908,9 @@ Install it with: pip install uv`;
4916
4908
  const installed = buildInstalledAgent(agent.id, agent.name, agent.version, dist, binaryPath);
4917
4909
  store.addAgent(agentKey, installed);
4918
4910
  const setup = getAgentSetup(agent.id);
4911
+ const setupSteps = setup?.setupSteps ?? (depResult.missing?.map((m) => `${m.label}: ${m.installHint}`) ?? []);
4919
4912
  await progress?.onSuccess(agent.name);
4920
- return { ok: true, agentKey, setupSteps: setup?.setupSteps };
4913
+ return { ok: true, agentKey, setupSteps: setupSteps.length > 0 ? setupSteps : void 0 };
4921
4914
  }
4922
4915
  async function downloadAndExtract(agentId, archiveUrl, progress, agentsDir) {
4923
4916
  const destDir = path15.join(agentsDir ?? DEFAULT_AGENTS_DIR, agentId);
@@ -7555,7 +7548,9 @@ var init_config_registry = __esm({
7555
7548
  displayName: "Default Agent",
7556
7549
  group: "agent",
7557
7550
  type: "select",
7558
- options: () => {
7551
+ options: (config) => {
7552
+ const configAgents = Object.keys(config.agents ?? {});
7553
+ if (configAgents.length > 0) return configAgents;
7559
7554
  try {
7560
7555
  const agentsPath = path24.join(getGlobalRoot(), "agents.json");
7561
7556
  if (fs19.existsSync(agentsPath)) {
@@ -8335,6 +8330,7 @@ var sessions_exports = {};
8335
8330
  __export(sessions_exports, {
8336
8331
  sessionRoutes: () => sessionRoutes
8337
8332
  });
8333
+ import { nanoid as nanoid2 } from "nanoid";
8338
8334
  async function sessionRoutes(app, deps) {
8339
8335
  app.get("/", { preHandler: requireScopes("sessions:read") }, async () => {
8340
8336
  const summaries = deps.core.sessionManager.listAllSessions();
@@ -8493,14 +8489,26 @@ async function sessionRoutes(app, deps) {
8493
8489
  }
8494
8490
  attachments = await resolveAttachments(fileService, sessionId, body.attachments);
8495
8491
  }
8492
+ const sourceAdapterId = body.sourceAdapterId ?? "api";
8493
+ const turnId = nanoid2(8);
8494
+ deps.core.eventBus.emit(BusEvent.MESSAGE_QUEUED, {
8495
+ sessionId,
8496
+ turnId,
8497
+ text: body.prompt,
8498
+ sourceAdapterId,
8499
+ attachments,
8500
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8501
+ queueDepth: session.queueDepth
8502
+ });
8496
8503
  await session.enqueuePrompt(body.prompt, attachments, {
8497
- sourceAdapterId: body.sourceAdapterId ?? "api",
8504
+ sourceAdapterId,
8498
8505
  responseAdapterId: body.responseAdapterId
8499
- });
8506
+ }, turnId);
8500
8507
  return {
8501
8508
  ok: true,
8502
8509
  sessionId,
8503
- queueDepth: session.queueDepth
8510
+ queueDepth: session.queueDepth,
8511
+ turnId
8504
8512
  };
8505
8513
  }
8506
8514
  );
@@ -8763,6 +8771,7 @@ var init_sessions2 = __esm({
8763
8771
  init_error_handler();
8764
8772
  init_auth();
8765
8773
  init_attachment_utils();
8774
+ init_events();
8766
8775
  init_sessions();
8767
8776
  }
8768
8777
  });
@@ -11877,6 +11886,50 @@ async function createSessionDirect(ctx, core, chatId, agentName, workspace, onCo
11877
11886
  return null;
11878
11887
  }
11879
11888
  }
11889
+ function _pruneExpiredForceReplies() {
11890
+ const cutoff = Date.now() - 10 * 60 * 1e3;
11891
+ for (const [msgId, entry] of _forceReplyMap) {
11892
+ if (entry.createdAt < cutoff) _forceReplyMap.delete(msgId);
11893
+ }
11894
+ }
11895
+ async function _sendCustomPathPrompt(ctx, chatId, agentKey) {
11896
+ const threadId = ctx.message?.message_thread_id ?? ctx.callbackQuery?.message?.message_thread_id;
11897
+ const sent = await ctx.api.sendMessage(
11898
+ chatId,
11899
+ `Please type the workspace path.
11900
+
11901
+ Examples:
11902
+ \u2022 <code>/absolute/path/to/project</code>
11903
+ \u2022 <code>~/my-project</code>
11904
+ \u2022 <code>project-name</code> (created under your base directory)
11905
+
11906
+ Reply to this message with your path.`,
11907
+ {
11908
+ parse_mode: "HTML",
11909
+ reply_markup: { force_reply: true },
11910
+ ...threadId !== void 0 ? { message_thread_id: threadId } : {}
11911
+ }
11912
+ );
11913
+ _forceReplyMap.set(sent.message_id, { agentKey, chatId, createdAt: Date.now() });
11914
+ }
11915
+ async function _handleCustomPathReply(ctx, core, chatId, entry) {
11916
+ const input2 = (ctx.message.text ?? "").trim();
11917
+ let resolvedPath;
11918
+ try {
11919
+ resolvedPath = core.configManager.resolveWorkspace(input2);
11920
+ } catch (err) {
11921
+ const message = err instanceof Error ? err.message : String(err);
11922
+ await ctx.reply(`\u274C ${escapeHtml4(message)}
11923
+
11924
+ Please try again:`, {
11925
+ parse_mode: "HTML"
11926
+ }).catch(() => {
11927
+ });
11928
+ await _sendCustomPathPrompt(ctx, chatId, entry.agentKey);
11929
+ return;
11930
+ }
11931
+ await createSessionDirect(ctx, core, chatId, entry.agentKey, resolvedPath);
11932
+ }
11880
11933
  function cacheWorkspace(agentKey, workspace) {
11881
11934
  const now = Date.now();
11882
11935
  for (const [id2, entry] of workspaceCache) {
@@ -11957,7 +12010,16 @@ Select workspace:`;
11957
12010
  }
11958
12011
  }
11959
12012
  }
11960
- function setupNewSessionCallbacks(bot, core, chatId, getAssistantSession) {
12013
+ function setupNewSessionCallbacks(bot, core, chatId) {
12014
+ bot.on("message:text", async (ctx, next) => {
12015
+ _pruneExpiredForceReplies();
12016
+ const replyToId = ctx.message.reply_to_message?.message_id;
12017
+ if (replyToId === void 0) return next();
12018
+ const entry = _forceReplyMap.get(replyToId);
12019
+ if (!entry || entry.chatId !== ctx.message.chat.id) return next();
12020
+ _forceReplyMap.delete(replyToId);
12021
+ await _handleCustomPathReply(ctx, core, chatId, entry);
12022
+ });
11961
12023
  bot.callbackQuery("ns:start", async (ctx) => {
11962
12024
  try {
11963
12025
  await ctx.answerCallbackQuery();
@@ -12034,33 +12096,20 @@ Try again with /new or /menu`,
12034
12096
  await ctx.answerCallbackQuery();
12035
12097
  } catch {
12036
12098
  }
12037
- const assistant = getAssistantSession?.();
12038
- if (assistant) {
12039
- try {
12040
- await ctx.editMessageText(
12041
- `<b>\u{1F195} New Session</b>
12099
+ try {
12100
+ await ctx.editMessageText(
12101
+ `<b>\u{1F195} New Session</b>
12042
12102
  Agent: <code>${escapeHtml4(agentKey)}</code>
12043
12103
 
12044
- \u{1F4AC} Type your workspace path in the chat below.`,
12045
- { parse_mode: "HTML" }
12046
- );
12047
- } catch {
12048
- }
12049
- await assistant.enqueuePrompt(
12050
- `User wants to create a new session with agent "${agentKey}". Ask them for the workspace (project directory) path, then create the session.`
12104
+ \u2328\uFE0F Waiting for workspace path...`,
12105
+ { parse_mode: "HTML" }
12051
12106
  );
12052
- } else {
12053
- try {
12054
- await ctx.editMessageText(
12055
- `Usage: <code>/new ${escapeHtml4(agentKey)} &lt;workspace-path&gt;</code>`,
12056
- { parse_mode: "HTML" }
12057
- );
12058
- } catch {
12059
- }
12107
+ } catch {
12060
12108
  }
12109
+ await _sendCustomPathPrompt(ctx, chatId, agentKey);
12061
12110
  });
12062
12111
  }
12063
- var log18, WS_CACHE_MAX, workspaceCache, nextWsId;
12112
+ var log18, WS_CACHE_MAX, workspaceCache, nextWsId, _forceReplyMap;
12064
12113
  var init_new_session = __esm({
12065
12114
  "src/plugins/telegram/commands/new-session.ts"() {
12066
12115
  "use strict";
@@ -12072,6 +12121,7 @@ var init_new_session = __esm({
12072
12121
  WS_CACHE_MAX = 50;
12073
12122
  workspaceCache = /* @__PURE__ */ new Map();
12074
12123
  nextWsId = 0;
12124
+ _forceReplyMap = /* @__PURE__ */ new Map();
12075
12125
  }
12076
12126
  });
12077
12127
 
@@ -14666,7 +14716,7 @@ function setupAllCallbacks(bot, core, chatId, systemTopicIds, getAssistantSessio
14666
14716
  core.configManager.get().workspace.baseDir
14667
14717
  );
14668
14718
  });
14669
- setupNewSessionCallbacks(bot, core, chatId, getAssistantSession);
14719
+ setupNewSessionCallbacks(bot, core, chatId);
14670
14720
  bot.callbackQuery(/^ar:/, (ctx) => handleArchiveConfirm(ctx, core, chatId));
14671
14721
  bot.callbackQuery(/^m:/, async (ctx) => {
14672
14722
  const itemId = ctx.callbackQuery.data.replace("m:", "");
@@ -14823,7 +14873,7 @@ var init_commands3 = __esm({
14823
14873
 
14824
14874
  // src/plugins/telegram/permissions.ts
14825
14875
  import { InlineKeyboard as InlineKeyboard11 } from "grammy";
14826
- import { nanoid as nanoid2 } from "nanoid";
14876
+ import { nanoid as nanoid3 } from "nanoid";
14827
14877
  var log26, PermissionHandler;
14828
14878
  var init_permissions = __esm({
14829
14879
  "src/plugins/telegram/permissions.ts"() {
@@ -14842,7 +14892,7 @@ var init_permissions = __esm({
14842
14892
  pending = /* @__PURE__ */ new Map();
14843
14893
  async sendPermissionRequest(session, request) {
14844
14894
  const threadId = Number(session.threadId);
14845
- const callbackKey = nanoid2(8);
14895
+ const callbackKey = nanoid3(8);
14846
14896
  this.pending.set(callbackKey, {
14847
14897
  sessionId: session.id,
14848
14898
  requestId: request.id,
@@ -20044,10 +20094,10 @@ var init_permission_gate = __esm({
20044
20094
  });
20045
20095
 
20046
20096
  // src/core/sessions/turn-context.ts
20047
- import { nanoid as nanoid3 } from "nanoid";
20097
+ import { nanoid as nanoid4 } from "nanoid";
20048
20098
  function createTurnContext(sourceAdapterId, responseAdapterId, turnId) {
20049
20099
  return {
20050
- turnId: turnId ?? nanoid3(8),
20100
+ turnId: turnId ?? nanoid4(8),
20051
20101
  sourceAdapterId,
20052
20102
  responseAdapterId
20053
20103
  };
@@ -20075,7 +20125,7 @@ var init_turn_context = __esm({
20075
20125
  });
20076
20126
 
20077
20127
  // src/core/sessions/session.ts
20078
- import { nanoid as nanoid4 } from "nanoid";
20128
+ import { nanoid as nanoid5 } from "nanoid";
20079
20129
  import * as fs41 from "fs";
20080
20130
  var moduleLog, TTS_PROMPT_INSTRUCTION, TTS_BLOCK_REGEX, TTS_MAX_LENGTH, TTS_TIMEOUT_MS, VALID_TRANSITIONS, Session;
20081
20131
  var init_session2 = __esm({
@@ -20153,7 +20203,7 @@ Additionally, include a [TTS]...[/TTS] block with a spoken-friendly summary of y
20153
20203
  pendingContext = null;
20154
20204
  constructor(opts) {
20155
20205
  super();
20156
- this.id = opts.id || nanoid4(12);
20206
+ this.id = opts.id || nanoid5(12);
20157
20207
  this.channelId = opts.channelId;
20158
20208
  this.attachedAdapters = [opts.channelId];
20159
20209
  this.agentName = opts.agentName;
@@ -20255,7 +20305,7 @@ Additionally, include a [TTS]...[/TTS] block with a spoken-friendly summary of y
20255
20305
  }
20256
20306
  // --- Public API ---
20257
20307
  async enqueuePrompt(text6, attachments, routing, externalTurnId) {
20258
- const turnId = externalTurnId ?? nanoid4(8);
20308
+ const turnId = externalTurnId ?? nanoid5(8);
20259
20309
  if (this.middlewareChain) {
20260
20310
  const payload = { text: text6, attachments, sessionId: this.id, sourceAdapterId: routing?.sourceAdapterId };
20261
20311
  const result = await this.middlewareChain.execute(Hook.AGENT_BEFORE_PROMPT, payload, async (p2) => p2);
@@ -20984,7 +21034,7 @@ var init_session_bridge = __esm({
20984
21034
  this.deps.sessionManager.patchRecord(this.session.id, { currentPromptCount: count });
20985
21035
  });
20986
21036
  this.listen(this.session, SessionEv.TURN_STARTED, (ctx) => {
20987
- if (ctx.sourceAdapterId !== "sse" && ctx.sourceAdapterId !== "api") {
21037
+ if (ctx.sourceAdapterId !== "sse") {
20988
21038
  this.deps.eventBus?.emit(BusEvent.MESSAGE_PROCESSING, {
20989
21039
  sessionId: this.session.id,
20990
21040
  turnId: ctx.turnId,
@@ -22665,7 +22715,7 @@ var init_agent_catalog = __esm({
22665
22715
  description: agent.description,
22666
22716
  distribution: dist?.type ?? "binary",
22667
22717
  installed: false,
22668
- available: dist !== null && availability.available,
22718
+ available: dist !== null,
22669
22719
  missingDeps: availability.missing?.map((m) => m.label)
22670
22720
  });
22671
22721
  }
@@ -24074,7 +24124,7 @@ var init_core_items = __esm({
24074
24124
  // src/core/core.ts
24075
24125
  import path51 from "path";
24076
24126
  import os23 from "os";
24077
- import { nanoid as nanoid5 } from "nanoid";
24127
+ import { nanoid as nanoid6 } from "nanoid";
24078
24128
  var log42, OpenACPCore;
24079
24129
  var init_core = __esm({
24080
24130
  "src/core/core.ts"() {
@@ -24389,7 +24439,7 @@ ${text6}`;
24389
24439
  const sourceAdapterId = message.routing?.sourceAdapterId ?? message.channelId;
24390
24440
  const routing = sourceAdapterId !== message.routing?.sourceAdapterId ? { ...message.routing, sourceAdapterId } : message.routing;
24391
24441
  if (sourceAdapterId && sourceAdapterId !== "sse" && sourceAdapterId !== "api") {
24392
- const turnId = nanoid5(8);
24442
+ const turnId = nanoid6(8);
24393
24443
  this.eventBus.emit(BusEvent.MESSAGE_QUEUED, {
24394
24444
  sessionId: session.id,
24395
24445
  turnId,
@@ -30668,13 +30718,18 @@ async function buildInstanceListEntries() {
30668
30718
  };
30669
30719
  });
30670
30720
  }
30671
- async function cmdInstances(args2 = []) {
30721
+ async function cmdInstances(args2 = [], parentFlags) {
30672
30722
  if (wantsHelp(args2)) {
30673
30723
  printInstancesHelp();
30674
30724
  return;
30675
30725
  }
30676
30726
  const sub = args2[0];
30677
30727
  const subArgs = args2.slice(1);
30728
+ if (parentFlags) {
30729
+ if (parentFlags.dir && !subArgs.includes("--dir")) subArgs.push("--dir", parentFlags.dir);
30730
+ if (parentFlags.from && !subArgs.includes("--from")) subArgs.push("--from", parentFlags.from);
30731
+ if (parentFlags.name && !subArgs.includes("--name")) subArgs.push("--name", parentFlags.name);
30732
+ }
30678
30733
  if (!sub || sub === "list") return cmdInstancesList(subArgs);
30679
30734
  if (sub === "create") return cmdInstancesCreate(subArgs);
30680
30735
  console.error(`Unknown subcommand: instances ${sub}`);
@@ -30774,19 +30829,33 @@ async function cmdInstancesCreate(args2) {
30774
30829
  try {
30775
30830
  const config = JSON.parse(fs53.readFileSync(configPath, "utf-8"));
30776
30831
  config.instanceName = name;
30832
+ if (!config.workspace) config.workspace = {};
30833
+ config.workspace.baseDir = resolvedDir;
30777
30834
  fs53.writeFileSync(configPath, JSON.stringify(config, null, 2));
30778
30835
  } catch {
30779
30836
  }
30780
30837
  } else if (noInteractive || !process.stdin.isTTY) {
30781
30838
  fs53.mkdirSync(instanceRoot, { recursive: true });
30782
- const config = { instanceName: name, runMode: "daemon" };
30783
- if (agent) config.defaultAgent = agent;
30839
+ const config = {
30840
+ channels: { sse: { enabled: true } },
30841
+ defaultAgent: agent || "claude",
30842
+ workspace: { baseDir: resolvedDir },
30843
+ runMode: "daemon",
30844
+ autoStart: false,
30845
+ instanceName: name
30846
+ };
30784
30847
  fs53.writeFileSync(path62.join(instanceRoot, "config.json"), JSON.stringify(config, null, 2));
30785
30848
  fs53.writeFileSync(path62.join(instanceRoot, "plugins.json"), JSON.stringify({ version: 1, installed: {} }, null, 2));
30786
30849
  } else {
30787
30850
  fs53.mkdirSync(instanceRoot, { recursive: true });
30788
- const config = { instanceName: name, runMode: "daemon" };
30789
- if (agent) config.defaultAgent = agent;
30851
+ const config = {
30852
+ channels: { sse: { enabled: true } },
30853
+ defaultAgent: agent || "claude",
30854
+ workspace: { baseDir: resolvedDir },
30855
+ runMode: "daemon",
30856
+ autoStart: false,
30857
+ instanceName: name
30858
+ };
30790
30859
  fs53.writeFileSync(path62.join(instanceRoot, "config.json"), JSON.stringify(config, null, 2));
30791
30860
  fs53.writeFileSync(path62.join(instanceRoot, "plugins.json"), JSON.stringify({ version: 1, installed: {} }, null, 2));
30792
30861
  console.log(`Instance created at ${resolvedDir}. Run 'openacp setup' inside that directory to configure it.`);
@@ -32193,7 +32262,7 @@ var noInstanceCommands = {
32193
32262
  "-v": () => cmdVersion(args),
32194
32263
  "update": () => cmdUpdate(args),
32195
32264
  "adopt": () => cmdAdopt(args),
32196
- "instances": async () => cmdInstances(args),
32265
+ "instances": async () => cmdInstances(args, flags),
32197
32266
  "integrate": () => cmdIntegrate(args),
32198
32267
  "dev": () => cmdDev(args)
32199
32268
  };