@openacp/cli 2026.414.3 → 2026.414.5

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
@@ -2663,6 +2663,19 @@ function registerSetupRoutes(app, deps) {
2663
2663
  return service.getUser(entry.userId);
2664
2664
  }
2665
2665
  if (!body?.displayName) return reply.status(400).send({ error: "displayName is required" });
2666
+ const USERNAME_RE = /^[a-zA-Z0-9_.-]+$/;
2667
+ if (body.username !== void 0 && body.username !== null) {
2668
+ const u = String(body.username);
2669
+ if (!u || !USERNAME_RE.test(u)) {
2670
+ return reply.status(400).send({ error: "Invalid username. Only letters, numbers, _ . - allowed." });
2671
+ }
2672
+ }
2673
+ if (body.username) {
2674
+ const existing = await service.getUserByUsername(String(body.username));
2675
+ if (existing) {
2676
+ return reply.status(409).send({ error: "Username already taken" });
2677
+ }
2678
+ }
2666
2679
  const { user } = await service.createUserWithIdentity({
2667
2680
  displayName: body.displayName,
2668
2681
  username: body.username,
@@ -9573,9 +9586,14 @@ async function sessionRoutes(app, deps) {
9573
9586
  const userId = request.auth?.tokenId ?? "api";
9574
9587
  const result = await deps.core.handleMessageInSession(
9575
9588
  session,
9576
- { channelId: sourceAdapterId, userId, text: body.prompt, attachments },
9577
- { channelUser: { channelId: "sse", userId } },
9578
- { externalTurnId: body.turnId, responseAdapterId: body.responseAdapterId }
9589
+ { channelId: "api", userId, text: body.prompt, attachments },
9590
+ { channelUser: { channelId: "api", userId } },
9591
+ {
9592
+ externalTurnId: body.turnId,
9593
+ // Preserve null (suppress response) but fall back to sourceAdapterId when
9594
+ // responseAdapterId is not specified, since 'api' has no adapter to route to.
9595
+ responseAdapterId: body.responseAdapterId !== void 0 ? body.responseAdapterId : sourceAdapterId
9596
+ }
9579
9597
  );
9580
9598
  if (!result) {
9581
9599
  throw new AuthError("MESSAGE_BLOCKED", "Message was blocked by a middleware plugin.", 403);
@@ -10750,7 +10768,7 @@ async function commandRoutes(app, deps) {
10750
10768
  const result = await deps.commandRegistry.execute(commandString, {
10751
10769
  raw: "",
10752
10770
  sessionId: body.sessionId ?? null,
10753
- channelId: "sse",
10771
+ channelId: "api",
10754
10772
  userId: request.auth?.tokenId ?? "api",
10755
10773
  reply: async () => {
10756
10774
  }
@@ -12200,8 +12218,11 @@ async function sseRoutes(app, deps) {
12200
12218
  const userId = request.auth?.tokenId ?? "api";
12201
12219
  const { turnId, queueDepth } = await deps.core.handleMessageInSession(
12202
12220
  session,
12203
- { channelId: "sse", userId, text: body.prompt, attachments },
12204
- { channelUser: { channelId: "sse", userId } }
12221
+ { channelId: "api", userId, text: body.prompt, attachments },
12222
+ { channelUser: { channelId: "api", userId } },
12223
+ // Route response back to the SSE adapter; 'api' is the identity namespace,
12224
+ // not an adapter name, so responseAdapterId must be explicit.
12225
+ { responseAdapterId: "sse" }
12205
12226
  );
12206
12227
  return { ok: true, sessionId, queueDepth, turnId };
12207
12228
  }
@@ -12262,7 +12283,7 @@ async function sseRoutes(app, deps) {
12262
12283
  const result = await deps.commandRegistry.execute(commandString, {
12263
12284
  raw: "",
12264
12285
  sessionId,
12265
- channelId: "sse",
12286
+ channelId: "api",
12266
12287
  userId: request.auth?.tokenId ?? "api",
12267
12288
  reply: async () => {
12268
12289
  }
@@ -18459,7 +18480,6 @@ var init_adapter2 = __esm({
18459
18480
  return prev(method, payload, signal);
18460
18481
  });
18461
18482
  const onCommandsReady = ({ commands }) => {
18462
- this.core.eventBus.off(BusEvent.SYSTEM_COMMANDS_READY, onCommandsReady);
18463
18483
  this.syncCommandsWithRetry(commands);
18464
18484
  };
18465
18485
  this.core.eventBus.on(BusEvent.SYSTEM_COMMANDS_READY, onCommandsReady);
@@ -19995,8 +20015,6 @@ var init_core_plugins = __esm({
19995
20015
  corePlugins = [
19996
20016
  // Service plugins (no adapter dependencies)
19997
20017
  security_default,
19998
- identity_default,
19999
- // Must boot after security (blocked users rejected before identity records are created)
20000
20018
  file_service_default,
20001
20019
  context_default,
20002
20020
  speech_default,
@@ -20004,6 +20022,11 @@ var init_core_plugins = __esm({
20004
20022
  // Infrastructure plugins
20005
20023
  tunnel_default,
20006
20024
  api_server_default,
20025
+ // Identity boots after api-server so it can register REST routes via
20026
+ // apiServer.registerPlugin(). If booted before, ctx.getService('api-server')
20027
+ // returns null and the /identity/setup route is never registered.
20028
+ // Security is already up at this point, satisfying the priority-100 requirement.
20029
+ identity_default,
20007
20030
  // Adapter plugins (depend on security, notifications, etc.)
20008
20031
  sse_adapter_default,
20009
20032
  telegram_default
@@ -30126,6 +30149,7 @@ async function startServer(opts) {
30126
30149
  const fieldRegistry = new PluginFieldRegistry();
30127
30150
  serviceRegistry.register("field-registry", fieldRegistry, "core");
30128
30151
  registerSystemCommands(commandRegistry, core);
30152
+ let loadedDevPlugin;
30129
30153
  try {
30130
30154
  core.eventBus.emit(BusEvent.KERNEL_BOOTED);
30131
30155
  core.lifecycleManager.settingsManager = settingsManager;
@@ -30202,6 +30226,7 @@ async function startServer(opts) {
30202
30226
  try {
30203
30227
  const devPlugin = await devLoader.load();
30204
30228
  await core.lifecycleManager.boot([devPlugin]);
30229
+ loadedDevPlugin = { name: devPlugin.name, version: devPlugin.version };
30205
30230
  log.info({ plugin: devPlugin.name, version: devPlugin.version }, "Dev plugin loaded");
30206
30231
  if (!opts.noWatch) {
30207
30232
  const distPath = devLoader.getDistPath();
@@ -30216,6 +30241,7 @@ async function startServer(opts) {
30216
30241
  const reloaded = await devLoader.load();
30217
30242
  await core.lifecycleManager.boot([reloaded]);
30218
30243
  log.info({ plugin: reloaded.name, version: reloaded.version }, "Dev plugin reloaded");
30244
+ core.eventBus.emit(BusEvent.SYSTEM_COMMANDS_READY, { commands: commandRegistry.getAll() });
30219
30245
  } catch (err) {
30220
30246
  log.error({ err }, "Dev plugin reload failed");
30221
30247
  }
@@ -30375,6 +30401,9 @@ async function startServer(opts) {
30375
30401
  for (const [name] of core.adapters) {
30376
30402
  ok3(`${name.charAt(0).toUpperCase() + name.slice(1)} connected`);
30377
30403
  }
30404
+ if (loadedDevPlugin) {
30405
+ ok3(`Dev plugin: ${loadedDevPlugin.name} v${loadedDevPlugin.version}`);
30406
+ }
30378
30407
  const apiSvc = core.lifecycleManager.serviceRegistry.get("api-server");
30379
30408
  let apiPort = apiSvc ? apiSvc.getPort() : 21420;
30380
30409
  if (apiSvc && apiPort === 0) {