@downcity/city 1.1.29 → 1.1.39

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 (153) hide show
  1. package/README.md +5 -11
  2. package/bin/cli/Index.js +10 -5
  3. package/bin/cli/Index.js.map +1 -1
  4. package/bin/cli/agent/AgentChat.js +1 -1
  5. package/bin/cli/agent/AgentChat.js.map +1 -1
  6. package/bin/cli/agent/AgentManager.js +3 -3
  7. package/bin/cli/agent/AgentManager.js.map +1 -1
  8. package/bin/cli/agent/Init.d.ts.map +1 -1
  9. package/bin/cli/agent/Init.js +14 -14
  10. package/bin/cli/agent/Init.js.map +1 -1
  11. package/bin/cli/agent/Restart.js +1 -1
  12. package/bin/cli/agent/Restart.js.map +1 -1
  13. package/bin/cli/agent/Run.d.ts.map +1 -1
  14. package/bin/cli/agent/Run.js +12 -19
  15. package/bin/cli/agent/Run.js.map +1 -1
  16. package/bin/cli/agent/Start.js +1 -1
  17. package/bin/cli/agent/Start.js.map +1 -1
  18. package/bin/cli/control-plane/ControlPlaneProcess.d.ts.map +1 -1
  19. package/bin/cli/control-plane/ControlPlaneProcess.js +2 -3
  20. package/bin/cli/control-plane/ControlPlaneProcess.js.map +1 -1
  21. package/bin/cli/model/ModelSupport.d.ts +1 -1
  22. package/bin/cli/model/ModelSupport.d.ts.map +1 -1
  23. package/bin/cli/model/ModelSupport.js +1 -1
  24. package/bin/cli/model/ModelSupport.js.map +1 -1
  25. package/bin/cli/shared/Chat.d.ts +1 -1
  26. package/bin/cli/shared/Chat.js +1 -1
  27. package/bin/cli/shared/ChatAuth.d.ts.map +1 -1
  28. package/bin/cli/shared/ChatAuth.js +5 -7
  29. package/bin/cli/shared/ChatAuth.js.map +1 -1
  30. package/bin/cli/shared/ChatManager.d.ts +1 -1
  31. package/bin/cli/shared/ChatManager.d.ts.map +1 -1
  32. package/bin/cli/shared/ChatManager.js +20 -21
  33. package/bin/cli/shared/ChatManager.js.map +1 -1
  34. package/bin/cli/shared/Config.js +1 -1
  35. package/bin/cli/shared/Config.js.map +1 -1
  36. package/bin/cli/shared/ManagedPluginActionCommands.d.ts +15 -0
  37. package/bin/cli/shared/ManagedPluginActionCommands.d.ts.map +1 -0
  38. package/bin/cli/shared/{PluginRuntimeActionCommands.js → ManagedPluginActionCommands.js} +13 -12
  39. package/bin/cli/shared/ManagedPluginActionCommands.js.map +1 -0
  40. package/bin/cli/shared/{PluginRuntimeRemote.d.ts → ManagedPluginRemote.d.ts} +6 -6
  41. package/bin/cli/shared/{PluginRuntimeRemote.d.ts.map → ManagedPluginRemote.d.ts.map} +1 -1
  42. package/bin/cli/shared/{PluginRuntimeRemote.js → ManagedPluginRemote.js} +14 -14
  43. package/bin/cli/shared/ManagedPluginRemote.js.map +1 -0
  44. package/bin/cli/shared/PluginScheduleCommand.d.ts +3 -2
  45. package/bin/cli/shared/PluginScheduleCommand.d.ts.map +1 -1
  46. package/bin/cli/shared/PluginScheduleCommand.js +12 -11
  47. package/bin/cli/shared/PluginScheduleCommand.js.map +1 -1
  48. package/bin/cli/shared/{PluginRuntimeSupport.d.ts → PluginTargetSupport.d.ts} +7 -7
  49. package/bin/cli/shared/PluginTargetSupport.d.ts.map +1 -0
  50. package/bin/cli/shared/{PluginRuntimeSupport.js → PluginTargetSupport.js} +7 -8
  51. package/bin/cli/shared/{PluginRuntimeSupport.js.map → PluginTargetSupport.js.map} +1 -1
  52. package/bin/cli/shared/Plugins.d.ts.map +1 -1
  53. package/bin/cli/shared/Plugins.js +30 -21
  54. package/bin/cli/shared/Plugins.js.map +1 -1
  55. package/bin/cli/shared/PortHints.js +1 -1
  56. package/bin/config/DowncitySchema.d.ts.map +1 -1
  57. package/bin/config/DowncitySchema.js +2 -8
  58. package/bin/config/DowncitySchema.js.map +1 -1
  59. package/bin/config/Paths.d.ts +2 -2
  60. package/bin/config/Paths.js +2 -2
  61. package/bin/control/AgentStatusApiRoutes.js +2 -2
  62. package/bin/control/AgentStatusApiRoutes.js.map +1 -1
  63. package/bin/control/ChannelAccountApiRoutes.d.ts.map +1 -1
  64. package/bin/control/ChannelAccountApiRoutes.js +6 -7
  65. package/bin/control/ChannelAccountApiRoutes.js.map +1 -1
  66. package/bin/control/ControlGateway.d.ts.map +1 -1
  67. package/bin/control/ControlGateway.js +3 -2
  68. package/bin/control/ControlGateway.js.map +1 -1
  69. package/bin/control/PluginApiRoutes.d.ts.map +1 -1
  70. package/bin/control/PluginApiRoutes.js +38 -30
  71. package/bin/control/PluginApiRoutes.js.map +1 -1
  72. package/bin/control/gateway/AgentActions.d.ts.map +1 -1
  73. package/bin/control/gateway/AgentActions.js +16 -11
  74. package/bin/control/gateway/AgentActions.js.map +1 -1
  75. package/bin/control/gateway/AgentCatalog.js +1 -1
  76. package/bin/control/gateway/AgentCatalog.js.map +1 -1
  77. package/bin/control/instant/InstantApiRoutes.d.ts +3 -3
  78. package/bin/control/instant/InstantApiRoutes.d.ts.map +1 -1
  79. package/bin/control/instant/InstantApiRoutes.js +5 -5
  80. package/bin/control/instant/InstantApiRoutes.js.map +1 -1
  81. package/bin/control/instant/{InstantSessionService.d.ts → InstantSessionRunner.d.ts} +7 -7
  82. package/bin/control/instant/InstantSessionRunner.d.ts.map +1 -0
  83. package/bin/control/instant/{InstantSessionService.js → InstantSessionRunner.js} +4 -4
  84. package/bin/control/instant/InstantSessionRunner.js.map +1 -0
  85. package/bin/http/auth/RoutePolicy.js +4 -4
  86. package/bin/http/auth/RoutePolicy.js.map +1 -1
  87. package/bin/model/runtime/CreateRuntimeModel.d.ts +2 -10
  88. package/bin/model/runtime/CreateRuntimeModel.d.ts.map +1 -1
  89. package/bin/model/runtime/CreateRuntimeModel.js +1 -16
  90. package/bin/model/runtime/CreateRuntimeModel.js.map +1 -1
  91. package/bin/model/runtime/ExecutionModelBinding.d.ts +46 -0
  92. package/bin/model/runtime/ExecutionModelBinding.d.ts.map +1 -0
  93. package/bin/model/runtime/ExecutionModelBinding.js +96 -0
  94. package/bin/model/runtime/ExecutionModelBinding.js.map +1 -0
  95. package/bin/process/daemon/Api.d.ts +2 -2
  96. package/bin/process/daemon/Api.js +1 -1
  97. package/bin/process/registry/AgentHostRuntime.d.ts +1 -9
  98. package/bin/process/registry/AgentHostRuntime.d.ts.map +1 -1
  99. package/bin/process/registry/AgentHostRuntime.js +2 -156
  100. package/bin/process/registry/AgentHostRuntime.js.map +1 -1
  101. package/package.json +3 -2
  102. package/src/cli/Index.ts +13 -5
  103. package/src/cli/agent/AgentChat.ts +1 -1
  104. package/src/cli/agent/AgentManager.ts +3 -3
  105. package/src/cli/agent/Init.ts +15 -14
  106. package/src/cli/agent/Restart.ts +1 -1
  107. package/src/cli/agent/Run.ts +12 -18
  108. package/src/cli/agent/Start.ts +1 -1
  109. package/src/cli/control-plane/ControlPlaneProcess.ts +2 -3
  110. package/src/cli/model/ModelSupport.ts +1 -1
  111. package/src/cli/shared/Chat.ts +1 -1
  112. package/src/cli/shared/ChatAuth.ts +10 -11
  113. package/src/cli/shared/ChatManager.ts +21 -22
  114. package/src/cli/shared/Config.ts +1 -1
  115. package/src/cli/shared/{PluginRuntimeActionCommands.ts → ManagedPluginActionCommands.ts} +18 -15
  116. package/src/cli/shared/{PluginRuntimeRemote.ts → ManagedPluginRemote.ts} +15 -15
  117. package/src/cli/shared/PluginScheduleCommand.ts +12 -11
  118. package/src/cli/shared/{PluginRuntimeSupport.ts → PluginTargetSupport.ts} +8 -9
  119. package/src/cli/shared/Plugins.ts +38 -28
  120. package/src/cli/shared/PortHints.ts +1 -1
  121. package/src/config/DowncitySchema.ts +2 -8
  122. package/src/config/Paths.ts +2 -2
  123. package/src/control/AgentStatusApiRoutes.ts +5 -5
  124. package/src/control/ChannelAccountApiRoutes.ts +6 -7
  125. package/src/control/ControlGateway.ts +3 -2
  126. package/src/control/PluginApiRoutes.ts +42 -32
  127. package/src/control/gateway/AgentActions.ts +16 -11
  128. package/src/control/gateway/AgentCatalog.ts +1 -1
  129. package/src/control/instant/InstantApiRoutes.ts +8 -8
  130. package/src/control/instant/{InstantSessionService.ts → InstantSessionRunner.ts} +7 -7
  131. package/src/http/auth/RoutePolicy.ts +4 -4
  132. package/src/model/runtime/CreateRuntimeModel.ts +1 -26
  133. package/src/model/runtime/ExecutionModelBinding.ts +120 -0
  134. package/src/process/daemon/Api.ts +2 -2
  135. package/src/process/registry/AgentHostRuntime.ts +2 -164
  136. package/tsconfig.json +2 -1
  137. package/bin/cli/shared/PluginRuntimeActionCommands.d.ts +0 -14
  138. package/bin/cli/shared/PluginRuntimeActionCommands.d.ts.map +0 -1
  139. package/bin/cli/shared/PluginRuntimeActionCommands.js.map +0 -1
  140. package/bin/cli/shared/PluginRuntimeRemote.js.map +0 -1
  141. package/bin/cli/shared/PluginRuntimeSupport.d.ts.map +0 -1
  142. package/bin/control/instant/InstantSessionService.d.ts.map +0 -1
  143. package/bin/control/instant/InstantSessionService.js.map +0 -1
  144. package/bin/platform/chatAuthorization/Store.d.ts +0 -31
  145. package/bin/platform/chatAuthorization/Store.d.ts.map +0 -1
  146. package/bin/platform/chatAuthorization/Store.js +0 -145
  147. package/bin/platform/chatAuthorization/Store.js.map +0 -1
  148. package/bin/process/registry/PluginRuntime.d.ts +0 -24
  149. package/bin/process/registry/PluginRuntime.d.ts.map +0 -1
  150. package/bin/process/registry/PluginRuntime.js +0 -31
  151. package/bin/process/registry/PluginRuntime.js.map +0 -1
  152. package/src/platform/chatAuthorization/Store.ts +0 -181
  153. package/src/process/registry/PluginRuntime.ts +0 -42
@@ -16,8 +16,7 @@ import {
16
16
  readDaemonPid,
17
17
  stopDaemonProcess,
18
18
  } from "@/process/daemon/Manager.js";
19
- import { ensureRuntimeExecutionBindingReady } from "@downcity/agent";
20
- import { createAgentPlatformRuntime } from "@/process/registry/AgentHostRuntime.js";
19
+ import { assertProjectExecutionModelReady } from "@/model/runtime/ExecutionModelBinding.js";
21
20
  import { allocateAvailablePort } from "@/process/daemon/PortAllocator.js";
22
21
  import {
23
22
  ensureManagedAgentRegistry,
@@ -469,7 +468,7 @@ export async function prepareForegroundAgent(
469
468
 
470
469
  injectAgentContext(cwd);
471
470
  const projectRoot = resolve(String(cwd || "."));
472
- ensureRuntimeExecutionBindingReady(projectRoot, createAgentPlatformRuntime());
471
+ assertProjectExecutionModelReady(projectRoot);
473
472
 
474
473
  const shouldForeground = options.foreground === true;
475
474
  if (!shouldForeground) {
@@ -181,7 +181,7 @@ export async function discoverProviderModels(params: {
181
181
  }
182
182
  }
183
183
 
184
- export { resolveProjectRoot } from "../shared/PluginRuntimeSupport.js";
184
+ export { resolveProjectRoot } from "../shared/PluginTargetSupport.js";
185
185
 
186
186
  /**
187
187
  * 设置项目 `downcity.json.execution.modelId`。
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 这里先注册裸 `city chat` 的交互式入口。
6
- * - 具体 runtime plugin actions/lifecycle 命令仍由 runtime plugin 注册器补充到同一个命令组。
6
+ * - 具体 plugin runtime actions/lifecycle 命令仍由 plugin runtime 注册器补充到同一个命令组。
7
7
  */
8
8
 
9
9
  import type { Command } from "commander";
@@ -11,18 +11,16 @@ import path from "node:path";
11
11
  import prompts from "prompts";
12
12
  import type { Command } from "commander";
13
13
  import {
14
+ isChatAuthorizationChannel,
14
15
  listChatAuthorizationRoles,
16
+ readChatAuthorizationConfigSync,
15
17
  resolveAuthorizedUserRole,
16
- } from "@downcity/agent";
17
- import { emitCliBlock } from "./CliReporter.js";
18
- import { parseBoolean } from "./IndexSupport.js";
19
- import {
20
- isChatAuthorizationChannel,
18
+ setChatAuthorizationUserRole,
21
19
  type ChatAuthorizationChannel,
22
20
  type ChatAuthorizationRole,
23
- } from "@downcity/agent";
24
- import { createAgentPlatformRuntime } from "@/process/registry/AgentHostRuntime.js";
25
- import { readChatAuthorizationConfigSync } from "@/platform/chatAuthorization/Store.js";
21
+ } from "@downcity/plugins";
22
+ import { emitCliBlock } from "./CliReporter.js";
23
+ import { parseBoolean } from "./IndexSupport.js";
26
24
 
27
25
  type ChatAuthSetOptions = {
28
26
  /**
@@ -141,9 +139,10 @@ export async function runChatAuthSet(params: {
141
139
 
142
140
  if (!nextRole) return;
143
141
 
144
- const platform = createAgentPlatformRuntime();
145
- await platform.setChatAuthorizationUserRole({
146
- projectRoot,
142
+ await setChatAuthorizationUserRole({
143
+ context: {
144
+ rootPath: projectRoot,
145
+ },
147
146
  channel: principal.channel,
148
147
  userId: principal.userId,
149
148
  roleId: nextRole.roleId,
@@ -2,7 +2,7 @@
2
2
  * `city chat` 交互式管理器。
3
3
  *
4
4
  * 关键点(中文)
5
- * - 裸 `city chat` 进入 chat service 管理,而不是只输出静态 help。
5
+ * - 裸 `city chat` 进入 chat plugin 管理,而不是只输出静态 help。
6
6
  * - chat channel account 属于 city 级配置,在这里通过“配置 channel”管理。
7
7
  * - agent 只绑定 channel account,不在 agent 流程中维护密钥。
8
8
  */
@@ -10,23 +10,22 @@
10
10
  import prompts from "prompts";
11
11
  import type { PromptObject } from "prompts";
12
12
  import {
13
- ChatChannelAccountService,
13
+ ChatChannelAccountManager,
14
14
  type ChatChannelAccountListItem,
15
- } from "@downcity/agent";
15
+ } from "@downcity/plugins";
16
16
  import { emitCliBlock, emitCliList } from "./CliReporter.js";
17
- import { runPluginRuntimeControlCommand } from "./PluginRuntimeRemote.js";
17
+ import { runManagedPluginControlCommand } from "./ManagedPluginRemote.js";
18
18
  import type { StoredChannelAccountChannel } from "@downcity/agent";
19
19
  import type {
20
20
  ChatChannelAccountAction,
21
21
  ChatManagerRootAction,
22
22
  } from "./ChatManagerTypes.js";
23
23
  import { runInteractiveChatAuthSetFlow } from "./ChatAuth.js";
24
- import { createAgentPlatformRuntime } from "@/process/registry/AgentHostRuntime.js";
25
24
 
26
25
  const CHAT_CHANNELS: StoredChannelAccountChannel[] = ["telegram", "feishu", "qq"];
27
26
 
28
- function createChannelAccountService(): ChatChannelAccountService {
29
- return new ChatChannelAccountService(createAgentPlatformRuntime());
27
+ function createChannelAccountManager(): ChatChannelAccountManager {
28
+ return new ChatChannelAccountManager();
30
29
  }
31
30
 
32
31
  function isInteractiveTerminal(): boolean {
@@ -49,8 +48,8 @@ function formatCredentialSummary(account: ChatChannelAccountListItem): string {
49
48
  }
50
49
 
51
50
  async function promptRootAction(): Promise<ChatManagerRootAction | null> {
52
- const service = createChannelAccountService();
53
- const accounts = await service.list();
51
+ const manager = createChannelAccountManager();
52
+ const accounts = await manager.list();
54
53
  const response = (await prompts({
55
54
  type: "select",
56
55
  name: "action",
@@ -94,8 +93,8 @@ async function promptRootAction(): Promise<ChatManagerRootAction | null> {
94
93
  }
95
94
 
96
95
  async function promptChannelAccountAction(): Promise<ChatChannelAccountAction | null> {
97
- const service = createChannelAccountService();
98
- const accounts = await service.list();
96
+ const manager = createChannelAccountManager();
97
+ const accounts = await manager.list();
99
98
  const response = (await prompts({
100
99
  type: "select",
101
100
  name: "action",
@@ -139,8 +138,8 @@ async function promptChannelAccountAction(): Promise<ChatChannelAccountAction |
139
138
  }
140
139
 
141
140
  async function emitChannelAccountList(): Promise<void> {
142
- const service = createChannelAccountService();
143
- const { items } = await service.list();
141
+ const manager = createChannelAccountManager();
142
+ const { items } = await manager.list();
144
143
  if (items.length === 0) {
145
144
  emitCliBlock({
146
145
  tone: "info",
@@ -182,8 +181,8 @@ async function chooseChannel(): Promise<StoredChannelAccountChannel | null> {
182
181
  }
183
182
 
184
183
  async function chooseAccount(): Promise<ChatChannelAccountListItem | null> {
185
- const service = createChannelAccountService();
186
- const { items } = await service.list();
184
+ const manager = createChannelAccountManager();
185
+ const { items } = await manager.list();
187
186
  if (items.length === 0) {
188
187
  emitCliBlock({
189
188
  tone: "info",
@@ -296,8 +295,8 @@ async function addChannelAccount(): Promise<void> {
296
295
  initial: true,
297
296
  })) as { probe?: boolean };
298
297
 
299
- const service = createChannelAccountService();
300
- const result = await service.create({
298
+ const manager = createChannelAccountManager();
299
+ const result = await manager.create({
301
300
  channel,
302
301
  name,
303
302
  botToken: input.botToken,
@@ -324,8 +323,8 @@ async function editChannelAccount(): Promise<void> {
324
323
  channel: account.channel,
325
324
  current: account,
326
325
  });
327
- const service = createChannelAccountService();
328
- await service.upsert({
326
+ const manager = createChannelAccountManager();
327
+ await manager.upsert({
329
328
  id: account.id,
330
329
  channel: account.channel,
331
330
  name: String(input.name || account.name).trim(),
@@ -356,8 +355,8 @@ async function removeChannelAccount(): Promise<void> {
356
355
 
357
356
  if (response.remove !== true) return;
358
357
 
359
- const service = createChannelAccountService();
360
- service.remove(account.id);
358
+ const manager = createChannelAccountManager();
359
+ await manager.remove(account.id);
361
360
  emitCliBlock({
362
361
  tone: "success",
363
362
  title: "Channel account removed",
@@ -403,7 +402,7 @@ async function runChannelAccountManager(): Promise<void> {
403
402
  async function runChatLifecycleAction(
404
403
  action: "start" | "stop" | "restart" | "status",
405
404
  ): Promise<void> {
406
- await runPluginRuntimeControlCommand({
405
+ await runManagedPluginControlCommand({
407
406
  pluginName: "chat",
408
407
  action,
409
408
  options: {
@@ -14,7 +14,7 @@ import { getDowncityJsonPath } from "@/config/Paths.js";
14
14
  import { printResult } from "@/utils/cli/CliOutput.js";
15
15
  import { aliasCommand } from "./Alias.js";
16
16
  import { parseBoolean } from "./IndexSupport.js";
17
- import { resolveProjectRoot } from "./PluginRuntimeSupport.js";
17
+ import { resolveProjectRoot } from "./PluginTargetSupport.js";
18
18
  import type { DowncityConfig } from "@downcity/agent";
19
19
 
20
20
  function isPlainObject(value: unknown): value is Record<string, unknown> {
@@ -1,27 +1,27 @@
1
1
  /**
2
- * Runtime plugin action CLI 注册器。
2
+ * agent 托管的 plugin action CLI 注册器。
3
3
  *
4
4
  * 关键点(中文)
5
- * - 负责把 runtime plugin actions 挂到 commander(`city <plugin> <action>`)。
5
+ * - 负责把需要运行中 agent 承载的 plugin actions 挂到 commander(`city <plugin> <action>`)。
6
6
  * - 仅处理 CLI 参数映射与远程调用,不承载 plugin 状态机逻辑。
7
- * - runtime plugin 注册表与调度时间解析统一复用 agent 包实现,避免 city 维护第二套事实源。
7
+ * - 命令注册表与调度时间解析统一复用 agent 包实现,避免 city 维护第二套事实源。
8
8
  */
9
9
 
10
10
  import path from "node:path";
11
11
  import type { Command } from "commander";
12
12
  import {
13
13
  callAgentTransport,
14
- listRegisteredPlugins,
15
- parseScheduledRunAtMsOrThrow,
14
+ parseActionScheduleRunAtMsOrThrow,
16
15
  } from "@downcity/agent";
16
+ import { listPluginsWithLifecycle } from "@downcity/agent";
17
17
  import type { BasePlugin, PluginAction } from "@downcity/agent";
18
18
  import type { JsonObject, JsonValue } from "@downcity/agent";
19
- import type { PluginCommandScheduleInput } from "@downcity/agent";
19
+ import type { PluginActionScheduleInput } from "@downcity/agent";
20
20
  import type { PluginCommandResponse } from "@downcity/agent";
21
21
  import type { PluginCliBaseOptions } from "@downcity/agent";
22
22
  import { printResult } from "@/utils/cli/CliOutput.js";
23
23
  import { parseBoolean, parsePort } from "./IndexSupport.js";
24
- import { runPluginRuntimeControlCommand } from "./PluginRuntimeRemote.js";
24
+ import { runManagedPluginControlCommand } from "./ManagedPluginRemote.js";
25
25
 
26
26
  const CHAT_PLUGIN_HELP_TEXT = [
27
27
  "",
@@ -160,8 +160,8 @@ function hasLongOption(command: Command, longFlag: string): boolean {
160
160
  */
161
161
  function extractCommandScheduleInput(
162
162
  options: Record<string, unknown>,
163
- ): PluginCommandScheduleInput | undefined {
164
- const runAtMs = parseScheduledRunAtMsOrThrow({
163
+ ): PluginActionScheduleInput | undefined {
164
+ const runAtMs = parseActionScheduleRunAtMsOrThrow({
165
165
  delay: options.delay as string | number | undefined,
166
166
  time: options.time as string | number | undefined,
167
167
  });
@@ -245,7 +245,7 @@ function registerPluginActionCommand(params: {
245
245
  })();
246
246
  const actionOptions = toPluginActionCommandOpts(allOptions);
247
247
  const bridgeOptions = toPluginCliBridgeOptions(allOptions);
248
- let schedule: PluginCommandScheduleInput | undefined;
248
+ let schedule: PluginActionScheduleInput | undefined;
249
249
  try {
250
250
  schedule = extractCommandScheduleInput(allOptions);
251
251
  } catch (error) {
@@ -280,7 +280,7 @@ function registerPluginActionCommand(params: {
280
280
 
281
281
  const remote = await callAgentTransport<PluginCommandResponse>({
282
282
  projectRoot: resolveProjectRoot(bridgeOptions.path),
283
- path: "/api/plugins/runtime/command",
283
+ path: "/api/plugins/command",
284
284
  method: "POST",
285
285
  host: bridgeOptions.host,
286
286
  port: bridgeOptions.port,
@@ -383,7 +383,7 @@ function registerPluginLifecycleCommands(params: {
383
383
  .description(item.description)
384
384
  .helpOption("--help", "display help for command"),
385
385
  ).action(async (options: PluginCliBaseOptions) => {
386
- await runPluginRuntimeControlCommand({
386
+ await runManagedPluginControlCommand({
387
387
  pluginName: params.plugin.name,
388
388
  action: item.action,
389
389
  options,
@@ -393,10 +393,13 @@ function registerPluginLifecycleCommands(params: {
393
393
  }
394
394
 
395
395
  /**
396
- * 注册所有 runtime plugin actions CLI 命令。
396
+ * 注册所有受 agent 托管的 plugin actions CLI 命令。
397
397
  */
398
- export function registerAllRuntimePluginsForCli(program: Command): void {
399
- const plugins = listRegisteredPlugins();
398
+ export function registerManagedPluginCommandsForCli(
399
+ program: Command,
400
+ pluginsInput: BasePlugin[],
401
+ ): void {
402
+ const plugins = listPluginsWithLifecycle(pluginsInput);
400
403
  for (const plugin of plugins) {
401
404
  for (const [actionName, action] of Object.entries(plugin.actions)) {
402
405
  registerPluginActionCommand({
@@ -2,7 +2,7 @@
2
2
  * `city plugin` 运行态远程 Agent server 调用辅助。
3
3
  *
4
4
  * 关键点(中文)
5
- * - 统一处理 runtime list/control/command 三类需要访问 Agent server 的命令。
5
+ * - 统一处理 list/control/command 三类需要访问 Agent server 的命令。
6
6
  * - 这里不负责命令注册,只负责 transport 调用与结果输出。
7
7
  */
8
8
 
@@ -13,26 +13,26 @@ import type {
13
13
  PluginCommandResponse,
14
14
  PluginControlAction,
15
15
  PluginControlResponse,
16
- PluginListResponse,
16
+ PluginStateListResponse,
17
17
  } from "@downcity/agent";
18
18
  import {
19
19
  parseCommandPayload,
20
20
  resolvePluginProjectRoot,
21
21
  validateAgentProjectRoot,
22
- } from "./PluginRuntimeSupport.js";
22
+ } from "./PluginTargetSupport.js";
23
23
 
24
24
  const PLUGIN_COMMAND_TIMEOUT_MS = 120_000;
25
25
 
26
26
  /**
27
- * 执行 `plugin list --runtime`。
27
+ * 执行 `plugin list`。
28
28
  */
29
- export async function runPluginRuntimeListCommand(options: PluginCliBaseOptions): Promise<void> {
29
+ export async function runManagedPluginListCommand(options: PluginCliBaseOptions): Promise<void> {
30
30
  const resolved = await resolvePluginProjectRoot(options);
31
31
  if (!resolved.projectRoot) {
32
32
  printResult({
33
33
  asJson: options.json,
34
34
  success: false,
35
- title: "plugin runtime list failed",
35
+ title: "plugin list failed",
36
36
  payload: {
37
37
  error: resolved.error || "Failed to resolve agent project path",
38
38
  },
@@ -45,16 +45,16 @@ export async function runPluginRuntimeListCommand(options: PluginCliBaseOptions)
45
45
  printResult({
46
46
  asJson: options.json,
47
47
  success: false,
48
- title: "plugin runtime list failed",
48
+ title: "plugin list failed",
49
49
  payload: {
50
50
  error: pathError,
51
51
  },
52
52
  });
53
53
  return;
54
54
  }
55
- const remote = await callAgentTransport<PluginListResponse>({
55
+ const remote = await callAgentTransport<PluginStateListResponse>({
56
56
  projectRoot,
57
- path: "/api/plugins/runtime/list",
57
+ path: "/api/plugins/list",
58
58
  method: "GET",
59
59
  host: options.host,
60
60
  port: options.port,
@@ -65,7 +65,7 @@ export async function runPluginRuntimeListCommand(options: PluginCliBaseOptions)
65
65
  printResult({
66
66
  asJson: options.json,
67
67
  success: Boolean(remote.data.success),
68
- title: remote.data.success ? "plugin runtime listed" : "plugin runtime list failed",
68
+ title: remote.data.success ? "plugin listed" : "plugin list failed",
69
69
  payload: {
70
70
  ...(Array.isArray(remote.data.plugins) ? { plugins: remote.data.plugins } : {}),
71
71
  ...(remote.data.error ? { error: remote.data.error } : {}),
@@ -77,7 +77,7 @@ export async function runPluginRuntimeListCommand(options: PluginCliBaseOptions)
77
77
  printResult({
78
78
  asJson: options.json,
79
79
  success: false,
80
- title: "plugin runtime list failed",
80
+ title: "plugin list failed",
81
81
  payload: {
82
82
  error: remote.error || "Unknown error",
83
83
  },
@@ -87,7 +87,7 @@ export async function runPluginRuntimeListCommand(options: PluginCliBaseOptions)
87
87
  /**
88
88
  * 执行 `plugin status/start/stop/restart`。
89
89
  */
90
- export async function runPluginRuntimeControlCommand(params: {
90
+ export async function runManagedPluginControlCommand(params: {
91
91
  pluginName: string;
92
92
  action: PluginControlAction;
93
93
  options: PluginCliBaseOptions;
@@ -119,7 +119,7 @@ export async function runPluginRuntimeControlCommand(params: {
119
119
  }
120
120
  const remote = await callAgentTransport<PluginControlResponse>({
121
121
  projectRoot,
122
- path: "/api/plugins/runtime/control",
122
+ path: "/api/plugins/control",
123
123
  method: "POST",
124
124
  host: params.options.host,
125
125
  port: params.options.port,
@@ -156,7 +156,7 @@ export async function runPluginRuntimeControlCommand(params: {
156
156
  /**
157
157
  * 执行 `plugin command` 桥接。
158
158
  */
159
- export async function runPluginRuntimeCommandBridge(params: {
159
+ export async function runManagedPluginCommandBridge(params: {
160
160
  pluginName: string;
161
161
  command: string;
162
162
  payloadRaw?: string;
@@ -189,7 +189,7 @@ export async function runPluginRuntimeCommandBridge(params: {
189
189
  }
190
190
  const remote = await callAgentTransport<PluginCommandResponse>({
191
191
  projectRoot,
192
- path: "/api/plugins/runtime/command",
192
+ path: "/api/plugins/command",
193
193
  method: "POST",
194
194
  timeoutMs: PLUGIN_COMMAND_TIMEOUT_MS,
195
195
  host: params.options.host,
@@ -2,12 +2,13 @@
2
2
  * `city plugin schedule` 命令。
3
3
  *
4
4
  * 关键点(中文)
5
- * - schedule 管理命令只依赖项目本地 schedule SQLite,不要求 runtime 在线。
6
- * - 这里同时承载 schedule 子命令注册与本地存储读写流程。
5
+ * - 命令名保留 schedule,是用户侧“延迟执行任务”的操作语义。
6
+ * - 内部使用 Agent 的 ActionScheduleStore,不依赖独立 schedule plugin。
7
+ * - 这里同时承载 schedule 子命令注册与 ActionSchedule 本地存储读写流程。
7
8
  */
8
9
 
9
10
  import type { Command } from "commander";
10
- import { PluginScheduleStore } from "@downcity/agent";
11
+ import { ActionScheduleStore } from "@downcity/agent";
11
12
  import { printResult } from "@/utils/cli/CliOutput.js";
12
13
  import type { PluginCliBaseOptions } from "@downcity/agent";
13
14
  import {
@@ -16,7 +17,7 @@ import {
16
17
  parsePositiveIntOption,
17
18
  resolvePluginScheduleProjectRoot,
18
19
  validateAgentProjectRoot,
19
- } from "./PluginRuntimeSupport.js";
20
+ } from "./PluginTargetSupport.js";
20
21
 
21
22
  /**
22
23
  * 执行 `plugin schedule list`。
@@ -57,7 +58,7 @@ export async function runPluginScheduleListCommand(params: {
57
58
  const limit = params.limitRaw
58
59
  ? parsePositiveIntOption(params.limitRaw, "limit")
59
60
  : 100;
60
- const store = new PluginScheduleStore(projectRoot);
61
+ const store = new ActionScheduleStore(projectRoot);
61
62
  try {
62
63
  const jobs = store.listJobs({ status, limit });
63
64
  printResult({
@@ -132,7 +133,7 @@ export async function runPluginScheduleInfoCommand(params: {
132
133
  return;
133
134
  }
134
135
 
135
- const store = new PluginScheduleStore(projectRoot);
136
+ const store = new ActionScheduleStore(projectRoot);
136
137
  try {
137
138
  const job = store.getJobById(jobId);
138
139
  if (!job) {
@@ -205,7 +206,7 @@ export async function runPluginScheduleCancelCommand(params: {
205
206
  return;
206
207
  }
207
208
 
208
- const store = new PluginScheduleStore(projectRoot);
209
+ const store = new ActionScheduleStore(projectRoot);
209
210
  try {
210
211
  const current = store.getJobById(jobId);
211
212
  if (!current) {
@@ -264,13 +265,13 @@ export async function runPluginScheduleCancelCommand(params: {
264
265
  export function registerPluginScheduleCommands(plugin: Command): void {
265
266
  const schedule = plugin
266
267
  .command("schedule")
267
- .description("查看和管理持久化 schedule 任务")
268
+ .description("查看和管理持久化延迟 action 任务")
268
269
  .helpOption("--help", "display help for command");
269
270
 
270
271
  addPluginScheduleOptions(
271
272
  schedule
272
273
  .command("list")
273
- .description("列出当前 agent 的调度任务")
274
+ .description("列出当前 agent 的延迟 action 任务")
274
275
  .option("--status <status>", "状态过滤(pending|running|succeeded|failed|cancelled)")
275
276
  .option("--limit <n>", "返回条数(默认 100)"),
276
277
  ).action(async (opts: PluginCliBaseOptions & { status?: string; limit?: string }) => {
@@ -284,7 +285,7 @@ export function registerPluginScheduleCommands(plugin: Command): void {
284
285
  addPluginScheduleOptions(
285
286
  schedule
286
287
  .command("info <jobId>")
287
- .description("查看单个调度任务详情"),
288
+ .description("查看单个延迟 action 任务详情"),
288
289
  ).action(async (jobId: string, opts: PluginCliBaseOptions) => {
289
290
  await runPluginScheduleInfoCommand({
290
291
  jobId,
@@ -295,7 +296,7 @@ export function registerPluginScheduleCommands(plugin: Command): void {
295
296
  addPluginScheduleOptions(
296
297
  schedule
297
298
  .command("cancel <jobId>")
298
- .description("取消一个尚未执行的调度任务"),
299
+ .description("取消一个尚未执行的延迟 action 任务"),
299
300
  ).action(async (jobId: string, opts: PluginCliBaseOptions) => {
300
301
  await runPluginScheduleCancelCommand({
301
302
  jobId,
@@ -2,7 +2,7 @@
2
2
  * `city plugin` 运行态命令共享辅助 + Agent 预检。
3
3
  *
4
4
  * 关键点(中文)
5
- * - 统一承载 runtime plugin 命令的参数解析、目标 agent 路径解析与项目目录校验。
5
+ * - 统一承载 plugin runtime 命令的参数解析、目标 agent 路径解析与项目目录校验。
6
6
  * - 提供 `checkAgentPreflight` 供 start/restart/status 等命令统一使用。
7
7
  * - 保持 command 注册层只关注命令树,不再直接承载路径解析细节。
8
8
  */
@@ -13,14 +13,13 @@ import type { Command } from "commander";
13
13
  import { getProfileMdPath, getDowncityJsonPath } from "@/config/Paths.js";
14
14
  import { listManagedAgentEntries } from "@/process/registry/CityRegistry.js";
15
15
  import { isCityRunning } from "@/process/registry/CityRuntime.js";
16
- import { ensureRuntimeExecutionBindingReady } from "@downcity/agent";
17
16
  import type { JsonValue } from "@downcity/agent";
18
17
  import { parsePort, resolveAgentName } from "./IndexSupport.js";
19
18
  import { CliError } from "./CliError.js";
20
- import type { ScheduledJobStatus } from "@downcity/agent";
19
+ import type { ActionScheduleJobStatus } from "@downcity/agent";
21
20
  import type { PluginCliBaseOptions } from "@downcity/agent";
22
21
  import { parseBoolean } from "./IndexSupport.js";
23
- import { createAgentPlatformRuntime } from "@/process/registry/AgentHostRuntime.js";
22
+ import { assertProjectExecutionModelReady } from "@/model/runtime/ExecutionModelBinding.js";
24
23
 
25
24
  export function isRegistryEntryRunning(
26
25
  entry: { status?: "running" | "stopped" },
@@ -77,7 +76,7 @@ export async function checkAgentPreflight(
77
76
  }
78
77
 
79
78
  // 关键点(中文):提前校验 execution binding,避免"启动成功后秒退"。
80
- ensureRuntimeExecutionBindingReady(projectRoot, createAgentPlatformRuntime());
79
+ assertProjectExecutionModelReady(projectRoot);
81
80
  }
82
81
 
83
82
  /**
@@ -96,7 +95,7 @@ export function parsePositiveIntOption(value: string, fieldName: string): number
96
95
  */
97
96
  export function normalizeScheduledJobStatus(
98
97
  value: string | undefined,
99
- ): ScheduledJobStatus | undefined {
98
+ ): ActionScheduleJobStatus | undefined {
100
99
  const text = String(value || "").trim().toLowerCase();
101
100
  if (!text) return undefined;
102
101
  if (
@@ -164,7 +163,7 @@ export async function resolveProjectRootByAgentName(agentName: string): Promise<
164
163
  }
165
164
 
166
165
  /**
167
- * 统一解析 runtime plugin 命令目标路径(agent 优先于 path)。
166
+ * 统一解析 plugin runtime 命令目标路径(agent 优先于 path)。
168
167
  */
169
168
  export async function resolvePluginProjectRoot(options: PluginCliBaseOptions): Promise<{
170
169
  projectRoot?: string;
@@ -206,7 +205,7 @@ export async function resolvePluginProjectRoot(options: PluginCliBaseOptions): P
206
205
  }
207
206
 
208
207
  /**
209
- * 解析 schedule 管理命令目标路径。
208
+ * 解析 ActionSchedule 管理命令目标路径。
210
209
  */
211
210
  export async function resolvePluginScheduleProjectRoot(options: PluginCliBaseOptions): Promise<{
212
211
  projectRoot?: string;
@@ -266,7 +265,7 @@ export function addPluginTargetOptions(command: Command): Command {
266
265
  }
267
266
 
268
267
  /**
269
- * 注入 plugin schedule 管理命令通用选项。
268
+ * 注入 ActionSchedule 管理命令通用选项。
270
269
  */
271
270
  export function addPluginScheduleOptions(command: Command): Command {
272
271
  return command