@downcity/agent 1.1.175 → 1.1.179

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 (139) hide show
  1. package/bin/agent/local/AgentPluginFactory.d.ts +4 -2
  2. package/bin/agent/local/AgentPluginFactory.d.ts.map +1 -1
  3. package/bin/agent/local/AgentPluginFactory.js +4 -6
  4. package/bin/agent/local/AgentPluginFactory.js.map +1 -1
  5. package/bin/agent/local/AgentRuntimeAssembly.d.ts.map +1 -1
  6. package/bin/agent/local/AgentRuntimeAssembly.js +3 -8
  7. package/bin/agent/local/AgentRuntimeAssembly.js.map +1 -1
  8. package/bin/agent/local/ProjectSetup.d.ts +1 -1
  9. package/bin/agent/local/ProjectSetup.d.ts.map +1 -1
  10. package/bin/agent/local/ProjectSetup.js +2 -6
  11. package/bin/agent/local/ProjectSetup.js.map +1 -1
  12. package/bin/agent/local/services/AgentAssemblyService.d.ts +2 -3
  13. package/bin/agent/local/services/AgentAssemblyService.d.ts.map +1 -1
  14. package/bin/agent/local/services/AgentAssemblyService.js +9 -14
  15. package/bin/agent/local/services/AgentAssemblyService.js.map +1 -1
  16. package/bin/agent/local/services/AgentBackgroundService.d.ts.map +1 -1
  17. package/bin/agent/local/services/AgentBackgroundService.js +5 -6
  18. package/bin/agent/local/services/AgentBackgroundService.js.map +1 -1
  19. package/bin/agent/local/services/AgentSessionManager.d.ts +2 -2
  20. package/bin/agent/local/services/AgentSessionManager.d.ts.map +1 -1
  21. package/bin/agent/local/services/AgentSessionManager.js +1 -28
  22. package/bin/agent/local/services/AgentSessionManager.js.map +1 -1
  23. package/bin/config/AgentInitializer.d.ts +4 -4
  24. package/bin/config/AgentInitializer.d.ts.map +1 -1
  25. package/bin/config/AgentInitializer.js +7 -49
  26. package/bin/config/AgentInitializer.js.map +1 -1
  27. package/bin/config/DowncitySchema.d.ts +3 -4
  28. package/bin/config/DowncitySchema.d.ts.map +1 -1
  29. package/bin/config/DowncitySchema.js +1 -2
  30. package/bin/config/DowncitySchema.js.map +1 -1
  31. package/bin/executor/composer/system/default/SystemDomain.d.ts.map +1 -1
  32. package/bin/executor/composer/system/default/SystemDomain.js +1 -2
  33. package/bin/executor/composer/system/default/SystemDomain.js.map +1 -1
  34. package/bin/executor/composer/system/default/assets/core.prompt.d.ts +1 -1
  35. package/bin/executor/composer/system/default/assets/core.prompt.d.ts.map +1 -1
  36. package/bin/executor/composer/system/default/assets/core.prompt.js +1 -1
  37. package/bin/executor/composer/system/default/assets/core.prompt.js.map +1 -1
  38. package/bin/index.d.ts +0 -2
  39. package/bin/index.d.ts.map +1 -1
  40. package/bin/index.js +1 -4
  41. package/bin/index.js.map +1 -1
  42. package/bin/plugin/core/Activation.d.ts +6 -5
  43. package/bin/plugin/core/Activation.d.ts.map +1 -1
  44. package/bin/plugin/core/Activation.js +9 -9
  45. package/bin/plugin/core/Activation.js.map +1 -1
  46. package/bin/plugin/core/BasePlugin.d.ts +5 -4
  47. package/bin/plugin/core/BasePlugin.d.ts.map +1 -1
  48. package/bin/plugin/core/BasePlugin.js +7 -4
  49. package/bin/plugin/core/BasePlugin.js.map +1 -1
  50. package/bin/plugin/core/HookRegistry.d.ts +4 -0
  51. package/bin/plugin/core/HookRegistry.d.ts.map +1 -1
  52. package/bin/plugin/core/HookRegistry.js +40 -0
  53. package/bin/plugin/core/HookRegistry.js.map +1 -1
  54. package/bin/plugin/core/Manager.d.ts +1 -1
  55. package/bin/plugin/core/Manager.d.ts.map +1 -1
  56. package/bin/plugin/core/Manager.js +1 -1
  57. package/bin/plugin/core/Manager.js.map +1 -1
  58. package/bin/plugin/core/PluginActionRunner.d.ts +13 -7
  59. package/bin/plugin/core/PluginActionRunner.d.ts.map +1 -1
  60. package/bin/plugin/core/PluginActionRunner.js +46 -111
  61. package/bin/plugin/core/PluginActionRunner.js.map +1 -1
  62. package/bin/plugin/core/PluginCatalog.d.ts +1 -1
  63. package/bin/plugin/core/PluginCatalog.d.ts.map +1 -1
  64. package/bin/plugin/core/PluginCatalog.js +1 -21
  65. package/bin/plugin/core/PluginCatalog.js.map +1 -1
  66. package/bin/plugin/core/PluginLocalExecution.d.ts +12 -2
  67. package/bin/plugin/core/PluginLocalExecution.d.ts.map +1 -1
  68. package/bin/plugin/core/PluginLocalExecution.js +18 -24
  69. package/bin/plugin/core/PluginLocalExecution.js.map +1 -1
  70. package/bin/plugin/core/PluginRegistry.d.ts +60 -7
  71. package/bin/plugin/core/PluginRegistry.d.ts.map +1 -1
  72. package/bin/plugin/core/PluginRegistry.js +269 -42
  73. package/bin/plugin/core/PluginRegistry.js.map +1 -1
  74. package/bin/plugin/core/PluginStateController.d.ts +11 -36
  75. package/bin/plugin/core/PluginStateController.d.ts.map +1 -1
  76. package/bin/plugin/core/PluginStateController.js +45 -190
  77. package/bin/plugin/core/PluginStateController.js.map +1 -1
  78. package/bin/plugin/types/Plugin.d.ts +1 -1
  79. package/bin/plugin/types/Plugin.d.ts.map +1 -1
  80. package/bin/plugin/types/PluginState.d.ts +1 -1
  81. package/bin/plugin/types/PluginState.d.ts.map +1 -1
  82. package/bin/plugin/types/Plugins.d.ts +12 -12
  83. package/bin/plugin/types/Plugins.d.ts.map +1 -1
  84. package/bin/types/agent/AgentOptions.d.ts +12 -3
  85. package/bin/types/agent/AgentOptions.d.ts.map +1 -1
  86. package/bin/types/agent/AgentRuntimeAssembly.d.ts +1 -1
  87. package/bin/types/config/AgentProject.d.ts +6 -14
  88. package/bin/types/config/AgentProject.d.ts.map +1 -1
  89. package/bin/types/plugin/PluginRuntime.d.ts +23 -2
  90. package/bin/types/plugin/PluginRuntime.d.ts.map +1 -1
  91. package/bin/types/plugin/PluginState.d.ts +47 -36
  92. package/bin/types/plugin/PluginState.d.ts.map +1 -1
  93. package/bin/types/plugin/PluginState.js +4 -3
  94. package/bin/types/plugin/PluginState.js.map +1 -1
  95. package/bin/types/runtime/agent/AgentContext.d.ts +3 -3
  96. package/bin/types/runtime/agent/AgentContext.d.ts.map +1 -1
  97. package/bin/types/runtime/agent/AgentContext.js.map +1 -1
  98. package/package.json +3 -3
  99. package/src/agent/local/AgentPluginFactory.ts +8 -8
  100. package/src/agent/local/AgentRuntimeAssembly.ts +3 -9
  101. package/src/agent/local/ProjectSetup.ts +1 -8
  102. package/src/agent/local/services/AgentAssemblyService.ts +13 -23
  103. package/src/agent/local/services/AgentBackgroundService.ts +5 -6
  104. package/src/agent/local/services/AgentSessionManager.ts +4 -26
  105. package/src/config/AgentInitializer.ts +7 -57
  106. package/src/config/DowncitySchema.ts +3 -4
  107. package/src/executor/composer/system/default/SystemDomain.ts +1 -2
  108. package/src/executor/composer/system/default/assets/core.prompt.ts +1 -1
  109. package/src/executor/composer/system/default/assets/core.prompt.ts.txt +1 -1
  110. package/src/index.ts +1 -8
  111. package/src/plugin/core/Activation.ts +10 -10
  112. package/src/plugin/core/BasePlugin.ts +9 -6
  113. package/src/plugin/core/HookRegistry.ts +41 -0
  114. package/src/plugin/core/Manager.ts +0 -2
  115. package/src/plugin/core/PluginActionRunner.ts +52 -133
  116. package/src/plugin/core/PluginCatalog.ts +1 -23
  117. package/src/plugin/core/PluginLocalExecution.ts +30 -25
  118. package/src/plugin/core/PluginRegistry.ts +298 -44
  119. package/src/plugin/core/PluginStateController.ts +45 -235
  120. package/src/plugin/types/Plugin.ts +2 -1
  121. package/src/plugin/types/PluginState.ts +2 -1
  122. package/src/plugin/types/Plugins.ts +12 -12
  123. package/src/types/agent/AgentOptions.ts +13 -3
  124. package/src/types/agent/AgentRuntimeAssembly.ts +1 -1
  125. package/src/types/config/AgentProject.ts +7 -15
  126. package/src/types/plugin/PluginRuntime.ts +23 -2
  127. package/src/types/plugin/PluginState.ts +50 -43
  128. package/src/types/runtime/agent/AgentContext.ts +3 -3
  129. package/tsconfig.tsbuildinfo +1 -1
  130. package/bin/config/Defaults.d.ts +0 -21
  131. package/bin/config/Defaults.d.ts.map +0 -1
  132. package/bin/config/Defaults.js +0 -47
  133. package/bin/config/Defaults.js.map +0 -1
  134. package/bin/plugin/core/ProjectConfigStore.d.ts +0 -84
  135. package/bin/plugin/core/ProjectConfigStore.d.ts.map +0 -1
  136. package/bin/plugin/core/ProjectConfigStore.js +0 -89
  137. package/bin/plugin/core/ProjectConfigStore.js.map +0 -1
  138. package/src/config/Defaults.ts +0 -49
  139. package/src/plugin/core/ProjectConfigStore.ts +0 -155
@@ -1,106 +1,56 @@
1
1
  /**
2
- * PluginActionRunner:主动型 plugin action/command 执行模块。
2
+ * PluginActionRunnerplugin command/action 兼容执行模块。
3
+ *
4
+ * 关键点(中文)
5
+ * - 新模型中注册即生效,不再要求 plugin 处于 running 状态。
6
+ * - `command` 仅作为 CLI/RPC 对 action 的兼容入口;优先执行同名 action。
7
+ * - 延迟调度仍复用本模块,保证 schedule 到点后走统一 action 规则。
3
8
  */
4
9
 
5
10
  import type { AgentContext } from "@/types/runtime/agent/AgentContext.js";
6
- import type { BasePlugin } from "@/plugin/core/BasePlugin.js";
7
11
  import type {
8
12
  PluginAction,
9
13
  PluginActionResult,
10
14
  PluginCommandResult,
11
- PluginStateControlAction,
12
15
  PluginStateSnapshot,
13
16
  } from "@/plugin/types/Plugin.js";
14
17
  import type { PluginActionScheduleInput } from "@/plugin/types/ActionSchedule.js";
15
18
  import type { JsonValue } from "@/types/common/Json.js";
16
19
  import { ActionScheduleStore } from "@/plugin/core/ActionScheduleStore.js";
17
20
  import { normalizeRunAtMsOrThrow } from "@/plugin/core/ActionScheduleTime.js";
18
- import {
19
- controlPluginState,
20
- ensurePluginStateRecord,
21
- markPluginCommand,
22
- markPluginState,
23
- resolvePluginByName,
24
- toPluginStateSnapshot,
25
- } from "@/plugin/core/PluginStateController.js";
26
-
27
- function resolveLifecycle(plugin: BasePlugin) {
28
- return plugin.lifecycle;
29
- }
30
21
 
31
22
  /**
32
- * 按名称解析主动型 plugin action。
23
+ * 按名称解析 plugin action。
33
24
  */
34
25
  export function resolvePluginAction(
35
- plugin: BasePlugin,
26
+ plugin: {
27
+ actions?: Record<string, PluginAction<JsonValue, JsonValue>>;
28
+ },
36
29
  actionName: string,
37
30
  ): PluginAction<JsonValue, JsonValue> | null {
38
31
  const key = String(actionName || "").trim();
39
32
  if (!key) return null;
40
- return plugin.actions[key] || null;
33
+ return plugin.actions?.[key] || null;
41
34
  }
42
35
 
43
36
  /**
44
- * 执行一个主动型 plugin action。
37
+ * 执行一个 plugin action。
45
38
  */
46
39
  export async function invokePluginAction(params: {
47
- plugin: BasePlugin;
40
+ pluginName: string;
48
41
  actionName: string;
49
42
  payload?: JsonValue;
50
43
  context: AgentContext;
51
44
  }): Promise<PluginActionResult<JsonValue>> {
52
- const action = resolvePluginAction(params.plugin, params.actionName);
53
- if (!action) {
54
- return {
55
- success: false,
56
- error: `Plugin "${params.plugin.name}" does not implement action "${params.actionName}"`,
57
- };
58
- }
59
-
60
- try {
61
- const payload = (params.payload ?? {}) as JsonValue;
62
- const schema = action.input_schema?.zod;
63
- const parsed_payload = schema ? schema.safeParse(payload) : null;
64
- if (parsed_payload && !parsed_payload.success) {
65
- return {
66
- success: false,
67
- error: `Invalid payload for ${params.plugin.name}.${params.actionName}: ${parsed_payload.error.message}`,
68
- };
69
- }
70
- const input_payload = parsed_payload?.success
71
- ? parsed_payload.data as JsonValue
72
- : payload;
73
- return await action.execute({
74
- context: params.context,
75
- payload: input_payload,
76
- input: input_payload,
77
- pluginName: params.plugin.name,
78
- actionName: params.actionName,
79
- });
80
- } catch (error) {
81
- return {
82
- success: false,
83
- error: String(error),
84
- };
85
- }
86
- }
87
-
88
- function toControlCommandAction(
89
- command: string,
90
- ): PluginStateControlAction | null {
91
- if (
92
- command === "status" ||
93
- command === "start" ||
94
- command === "stop" ||
95
- command === "restart"
96
- ) {
97
- return command;
98
- }
99
- return null;
45
+ return await params.context.plugins.runAction({
46
+ plugin: params.pluginName,
47
+ action: params.actionName,
48
+ payload: params.payload,
49
+ });
100
50
  }
101
51
 
102
52
  async function schedulePluginAction(params: {
103
- plugin: BasePlugin;
53
+ pluginName: string;
104
54
  command: string;
105
55
  payload?: JsonValue;
106
56
  schedule: JsonValue | PluginActionScheduleInput;
@@ -116,7 +66,7 @@ async function schedulePluginAction(params: {
116
66
  const store = new ActionScheduleStore(params.context.rootPath);
117
67
  try {
118
68
  const job = store.createJob({
119
- pluginName: params.plugin.name,
69
+ pluginName: params.pluginName,
120
70
  actionName: params.command,
121
71
  payload: params.payload ?? null,
122
72
  runAtMs,
@@ -144,7 +94,7 @@ async function schedulePluginAction(params: {
144
94
  }
145
95
 
146
96
  /**
147
- * 统一执行主动型 plugin command。
97
+ * 统一执行 plugin command。
148
98
  */
149
99
  export async function runPluginCommand(params: {
150
100
  pluginName: string;
@@ -153,104 +103,74 @@ export async function runPluginCommand(params: {
153
103
  schedule?: JsonValue | PluginActionScheduleInput;
154
104
  context: AgentContext;
155
105
  }): Promise<PluginCommandResult & { plugin?: PluginStateSnapshot }> {
156
- const plugin = resolvePluginByName(params.pluginName, {
157
- context: params.context,
158
- });
159
- if (!plugin) {
106
+ const pluginName = String(params.pluginName || "").trim();
107
+ const command = String(params.command || "")
108
+ .trim()
109
+ .toLowerCase();
110
+ const plugin = params.context.plugins.get(pluginName);
111
+ const snapshot = params.context.plugins.status(pluginName) || undefined;
112
+
113
+ if (!plugin || !snapshot) {
160
114
  return {
161
115
  success: false,
162
116
  message: `Unknown plugin: ${params.pluginName}`,
163
117
  };
164
118
  }
165
119
 
166
- const record = ensurePluginStateRecord(plugin);
167
- const command = String(params.command || "")
168
- .trim()
169
- .toLowerCase();
170
120
  if (!command) {
171
121
  return {
172
122
  success: false,
173
- plugin: toPluginStateSnapshot(record, plugin),
123
+ plugin: snapshot,
174
124
  message: "command is required",
175
125
  };
176
126
  }
177
127
 
178
- markPluginCommand(record, command);
128
+ if (command === "status") {
129
+ return {
130
+ success: true,
131
+ plugin: snapshot,
132
+ };
133
+ }
179
134
 
180
135
  const action = resolvePluginAction(plugin, command);
181
136
  if (params.schedule !== undefined && params.schedule !== null) {
182
137
  if (!action) {
183
138
  return {
184
139
  success: false,
185
- plugin: toPluginStateSnapshot(record, plugin),
140
+ plugin: snapshot,
186
141
  message: `Scheduling only supports plugin actions. "${plugin.name}.${command}" is not a schedulable action.`,
187
142
  };
188
143
  }
189
144
 
190
145
  return await schedulePluginAction({
191
- plugin,
146
+ pluginName: plugin.name,
192
147
  command,
193
148
  payload: params.payload,
194
149
  schedule: params.schedule,
195
- recordSnapshot: toPluginStateSnapshot(record, plugin),
150
+ recordSnapshot: snapshot,
196
151
  context: params.context,
197
152
  });
198
153
  }
199
154
 
200
155
  if (action) {
201
- if (record.state !== "running") {
202
- return {
203
- success: false,
204
- plugin: toPluginStateSnapshot(record, plugin),
205
- message: `Plugin "${plugin.name}" is not running`,
206
- };
207
- }
208
-
209
- const result = await invokePluginAction({
210
- plugin,
211
- actionName: command,
156
+ const result = await params.context.plugins.runAction({
157
+ plugin: plugin.name,
158
+ action: command,
212
159
  payload: params.payload,
213
- context: params.context,
214
160
  });
215
161
 
216
- if (!result.success) {
217
- return {
218
- success: false,
219
- plugin: toPluginStateSnapshot(record, plugin),
220
- message: result.error || "plugin action failed",
221
- };
222
- }
223
-
224
- return {
225
- success: true,
226
- plugin: toPluginStateSnapshot(record, plugin),
227
- ...(result.data !== undefined ? { data: result.data } : {}),
228
- };
229
- }
230
-
231
- const controlAction = toControlCommandAction(command);
232
- if (controlAction) {
233
- const result = await controlPluginState({
234
- pluginName: plugin.name,
235
- action: controlAction,
236
- context: params.context,
237
- });
238
162
  return {
239
163
  success: result.success,
240
- ...(result.plugin ? { plugin: result.plugin } : {}),
241
- ...(result.error ? { message: result.error } : {}),
242
- };
243
- }
244
-
245
- if (record.state !== "running") {
246
- return {
247
- success: false,
248
- plugin: toPluginStateSnapshot(record, plugin),
249
- message: `Plugin "${plugin.name}" is not running`,
164
+ plugin: params.context.plugins.status(plugin.name) || snapshot,
165
+ ...(result.message || result.error
166
+ ? { message: result.message || result.error }
167
+ : {}),
168
+ ...(result.data !== undefined ? { data: result.data } : {}),
169
+ ...(result.error ? { error: result.error } : {}),
250
170
  };
251
171
  }
252
172
 
253
- const handler = resolveLifecycle(plugin)?.command;
173
+ const handler = plugin.lifecycle?.command;
254
174
  if (handler) {
255
175
  try {
256
176
  const result = await handler({
@@ -260,13 +180,12 @@ export async function runPluginCommand(params: {
260
180
  });
261
181
  return {
262
182
  ...result,
263
- plugin: toPluginStateSnapshot(record, plugin),
183
+ plugin: params.context.plugins.status(plugin.name) || snapshot,
264
184
  };
265
185
  } catch (error) {
266
- markPluginState(record, "error", String(error));
267
186
  return {
268
187
  success: false,
269
- plugin: toPluginStateSnapshot(record, plugin),
188
+ plugin: params.context.plugins.status(plugin.name) || snapshot,
270
189
  message: String(error),
271
190
  };
272
191
  }
@@ -274,7 +193,7 @@ export async function runPluginCommand(params: {
274
193
 
275
194
  return {
276
195
  success: false,
277
- plugin: toPluginStateSnapshot(record, plugin),
196
+ plugin: snapshot,
278
197
  message: `Plugin "${plugin.name}" does not implement command "${command}"`,
279
198
  };
280
199
  }
@@ -7,7 +7,6 @@
7
7
  * - Agent 的视角只有“传入的 plugin”,目录视图和可用性检查都从这些实例推导。
8
8
  */
9
9
 
10
- import { isPluginEnabled } from "@/plugin/core/Activation.js";
11
10
  import type {
12
11
  Plugin,
13
12
  PluginAvailability,
@@ -90,7 +89,7 @@ export function listPluginViews(plugins: Iterable<Plugin>): PluginView[] {
90
89
  *
91
90
  * 关键点(中文)
92
91
  * - 传入 context 时会调用 plugin 自己的 availability。
93
- * - 未传 context 时只做静态启用态检查,适合 Console 或 CLI 的目录回退展示。
92
+ * - 未传 context 时只返回静态目录说明,适合 Console 或 CLI 的目录回退展示。
94
93
  */
95
94
  export async function resolvePluginAvailability(params: {
96
95
  plugins: Iterable<Plugin>;
@@ -111,18 +110,6 @@ export async function resolvePluginAvailability(params: {
111
110
  return await plugin.availability(params.context);
112
111
  }
113
112
 
114
- const enabled = isPluginEnabled({
115
- plugin,
116
- ...(params.context ? { context: params.context } : {}),
117
- });
118
- if (!enabled) {
119
- return {
120
- enabled: false,
121
- available: false,
122
- reasons: [`Plugin "${plugin.name}" is disabled`],
123
- };
124
- }
125
-
126
113
  const agentReason = String(params.agentError || "").trim();
127
114
  if (agentReason || !params.context) {
128
115
  return {
@@ -158,15 +145,6 @@ export function buildStaticPluginAvailability(params: {
158
145
  };
159
146
  }
160
147
 
161
- const enabled = isPluginEnabled({ plugin });
162
- if (!enabled) {
163
- return {
164
- enabled: false,
165
- available: false,
166
- reasons: [`Plugin "${plugin.name}" is disabled`],
167
- };
168
- }
169
-
170
148
  const agentReason = String(params.agentError || "").trim();
171
149
  return {
172
150
  enabled: true,
@@ -4,18 +4,18 @@
4
4
  * 关键点(中文)
5
5
  * - 这里不创建或维护任何全局注册表,调用方必须显式传入 plugin 集合。
6
6
  * - 用于 CLI / 控制面这类没有运行中 Agent 实例、但需要执行 setup action 的场景。
7
- * - 真正运行中的 Agent 仍应优先使用 `PluginRegistry.runAction`。
7
+ * - 真正运行中的 Agent 仍应优先使用 `Agent.plugins.runAction`。
8
8
  */
9
9
 
10
10
  import path from "node:path";
11
11
  import { logger as defaultLogger } from "@/utils/logger/Logger.js";
12
- import { loadDowncityConfig, resolveAgentEnv } from "@/config/Config.js";
13
- import { isPluginEnabled } from "@/plugin/core/Activation.js";
12
+ import { resolveAgentEnv } from "@/config/Config.js";
14
13
  import { findPluginByName } from "@/plugin/core/PluginCatalog.js";
15
14
  import {
16
15
  createAgentPathRuntime,
17
16
  createAgentPluginConfigRuntime,
18
17
  } from "@/agent/local/AgentRuntimeAssembly.js";
18
+ import { createFallbackSdkConfig } from "@/agent/local/AgentInstructions.js";
19
19
  import type { JsonValue } from "@/types/common/Json.js";
20
20
  import type {
21
21
  Plugin,
@@ -24,14 +24,28 @@ import type {
24
24
  PluginCommandContext,
25
25
  } from "@/plugin/types/Plugin.js";
26
26
  import type { AgentContext } from "@/types/runtime/agent/AgentContext.js";
27
+ import type { DowncityConfig } from "@/types/config/DowncityConfig.js";
28
+
29
+ type LocalPluginCommandContextInput = {
30
+ /** 当前项目根目录。 */
31
+ projectRoot: string;
32
+ /** 宿主显式传入的 agent 配置。 */
33
+ config?: DowncityConfig;
34
+ };
27
35
 
28
36
  /**
29
37
  * 创建本地 plugin 命令上下文。
30
38
  */
31
- export function createLocalPluginCommandContext(projectRoot: string): PluginCommandContext {
39
+ export function createLocalPluginCommandContext(
40
+ input: string | LocalPluginCommandContextInput,
41
+ ): PluginCommandContext {
42
+ const projectRoot = typeof input === "string" ? input : input.projectRoot;
32
43
  const rootPath = path.resolve(String(projectRoot || "").trim() || ".");
33
44
  const env = resolveAgentEnv(rootPath);
34
- const config = loadDowncityConfig(rootPath);
45
+ const config = typeof input === "string" || !input.config
46
+ ? createFallbackSdkConfig(path.basename(rootPath) || "agent")
47
+ : input.config;
48
+ const agent_id = String(config.id || "").trim() || path.basename(rootPath) || "agent";
35
49
 
36
50
  defaultLogger.bindProjectRoot(rootPath);
37
51
 
@@ -43,7 +57,7 @@ export function createLocalPluginCommandContext(projectRoot: string): PluginComm
43
57
  env,
44
58
  paths: createAgentPathRuntime(
45
59
  rootPath,
46
- String(config.id || "").trim() || path.basename(rootPath) || "agent",
60
+ agent_id,
47
61
  ),
48
62
  pluginConfig: createAgentPluginConfigRuntime(rootPath),
49
63
  };
@@ -56,6 +70,7 @@ export async function getLocalPluginAvailability(params: {
56
70
  plugins: Iterable<Plugin>;
57
71
  projectRoot: string;
58
72
  pluginName: string;
73
+ config?: DowncityConfig;
59
74
  }): Promise<PluginAvailability> {
60
75
  const plugin = findPluginByName(params.plugins, params.pluginName);
61
76
  if (!plugin) {
@@ -66,20 +81,14 @@ export async function getLocalPluginAvailability(params: {
66
81
  };
67
82
  }
68
83
 
69
- const context = createLocalPluginCommandContext(params.projectRoot);
84
+ const context = createLocalPluginCommandContext({
85
+ projectRoot: params.projectRoot,
86
+ config: params.config,
87
+ });
70
88
  if (plugin.availability) {
71
89
  return await plugin.availability(context);
72
90
  }
73
91
 
74
- const enabled = isPluginEnabled({ plugin, context });
75
- if (!enabled) {
76
- return {
77
- enabled: false,
78
- available: false,
79
- reasons: [`Plugin "${plugin.name}" is disabled`],
80
- };
81
- }
82
-
83
92
  return {
84
93
  enabled: true,
85
94
  available: true,
@@ -96,6 +105,7 @@ export async function runLocalPluginAction(params: {
96
105
  pluginName: string;
97
106
  actionName: string;
98
107
  payload?: JsonValue;
108
+ config?: DowncityConfig;
99
109
  }): Promise<PluginActionResult<JsonValue>> {
100
110
  const plugin = findPluginByName(params.plugins, params.pluginName);
101
111
  if (!plugin) {
@@ -124,15 +134,10 @@ export async function runLocalPluginAction(params: {
124
134
  };
125
135
  }
126
136
 
127
- const context = createLocalPluginCommandContext(params.projectRoot);
128
- const enabled = isPluginEnabled({ plugin, context });
129
- if (!enabled && action.allowWhenDisabled !== true) {
130
- return {
131
- success: false,
132
- error: `Plugin "${plugin.name}" is disabled`,
133
- message: `Plugin "${plugin.name}" is disabled`,
134
- };
135
- }
137
+ const context = createLocalPluginCommandContext({
138
+ projectRoot: params.projectRoot,
139
+ config: params.config,
140
+ });
136
141
 
137
142
  try {
138
143
  const payload = (params.payload ?? {}) as JsonValue;