@botbotgo/agent-harness 0.0.308 → 0.0.310

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 (195) hide show
  1. package/README.md +17 -1
  2. package/README.zh.md +17 -1
  3. package/dist/acp.d.ts +1 -116
  4. package/dist/acp.js +1 -310
  5. package/dist/api.d.ts +4 -2
  6. package/dist/api.js +4 -1
  7. package/dist/cli/chat-interactive.d.ts +24 -0
  8. package/dist/cli/chat-interactive.js +244 -0
  9. package/dist/cli/chat-rendering.d.ts +9 -0
  10. package/dist/cli/chat-rendering.js +102 -0
  11. package/dist/cli/chat-stream.d.ts +23 -0
  12. package/dist/cli/chat-stream.js +330 -0
  13. package/dist/cli/chat-ui.d.ts +20 -0
  14. package/dist/cli/chat-ui.js +198 -0
  15. package/dist/cli/chat-workspace.d.ts +15 -0
  16. package/dist/cli/chat-workspace.js +205 -0
  17. package/dist/cli/main.d.ts +52 -0
  18. package/dist/cli/main.js +323 -0
  19. package/dist/cli/managed-service-commands.d.ts +23 -0
  20. package/dist/cli/managed-service-commands.js +63 -0
  21. package/dist/cli/managed-service.d.ts +27 -0
  22. package/dist/cli/managed-service.js +61 -0
  23. package/dist/cli/options-init-chat.d.ts +16 -0
  24. package/dist/cli/options-init-chat.js +108 -0
  25. package/dist/cli/options-runtime.d.ts +27 -0
  26. package/dist/cli/options-runtime.js +158 -0
  27. package/dist/cli/options-serve.d.ts +24 -0
  28. package/dist/cli/options-serve.js +166 -0
  29. package/dist/cli/options.d.ts +5 -0
  30. package/dist/cli/options.js +47 -0
  31. package/dist/cli/process-guards.d.ts +14 -0
  32. package/dist/cli/process-guards.js +139 -0
  33. package/dist/cli/request-tree.d.ts +12 -0
  34. package/dist/cli/request-tree.js +296 -0
  35. package/dist/cli/runtime-commands.d.ts +15 -0
  36. package/dist/cli/runtime-commands.js +247 -0
  37. package/dist/cli/runtime-output.d.ts +5 -0
  38. package/dist/cli/runtime-output.js +124 -0
  39. package/dist/cli/server-commands.d.ts +36 -0
  40. package/dist/cli/server-commands.js +250 -0
  41. package/dist/cli/workspace.d.ts +6 -0
  42. package/dist/cli/workspace.js +71 -0
  43. package/dist/cli.d.ts +1 -67
  44. package/dist/cli.js +2 -2734
  45. package/dist/client/acp.d.ts +1 -50
  46. package/dist/client/acp.js +1 -219
  47. package/dist/client/in-process.d.ts +5 -5
  48. package/dist/client/index.d.ts +2 -2
  49. package/dist/client/index.js +1 -1
  50. package/dist/contracts/runtime-evaluation.d.ts +103 -0
  51. package/dist/contracts/runtime-evaluation.js +1 -0
  52. package/dist/contracts/runtime-memory.d.ts +162 -0
  53. package/dist/contracts/runtime-memory.js +1 -0
  54. package/dist/contracts/runtime-observability.d.ts +248 -0
  55. package/dist/contracts/runtime-observability.js +1 -0
  56. package/dist/contracts/runtime-requests.d.ts +342 -0
  57. package/dist/contracts/runtime-requests.js +1 -0
  58. package/dist/contracts/runtime-scheduling.d.ts +146 -0
  59. package/dist/contracts/runtime-scheduling.js +1 -0
  60. package/dist/contracts/runtime.d.ts +5 -1042
  61. package/dist/contracts/runtime.js +27 -1
  62. package/dist/flow/build-flow-graph.js +4 -875
  63. package/dist/flow/flow-graph-normalization.d.ts +56 -0
  64. package/dist/flow/flow-graph-normalization.js +214 -0
  65. package/dist/flow/flow-graph-runtime.d.ts +8 -0
  66. package/dist/flow/flow-graph-runtime.js +107 -0
  67. package/dist/flow/flow-graph-upstream.d.ts +18 -0
  68. package/dist/flow/flow-graph-upstream.js +498 -0
  69. package/dist/flow/types.d.ts +1 -1
  70. package/dist/index.d.ts +4 -4
  71. package/dist/index.js +2 -2
  72. package/dist/init-project.d.ts +1 -12
  73. package/dist/init-project.js +1 -651
  74. package/dist/{procedural → knowledge/procedural}/manager.d.ts +3 -3
  75. package/dist/{procedural → knowledge/procedural}/manager.js +6 -6
  76. package/dist/mcp.d.ts +2 -62
  77. package/dist/mcp.js +2 -253
  78. package/dist/package-version.d.ts +1 -1
  79. package/dist/package-version.js +1 -1
  80. package/dist/persistence/file-store.js +1 -1
  81. package/dist/persistence/sqlite-runtime.d.ts +19 -0
  82. package/dist/persistence/sqlite-runtime.js +86 -0
  83. package/dist/persistence/sqlite-store.js +11 -99
  84. package/dist/{request-events.d.ts → projections/request-events.d.ts} +1 -1
  85. package/dist/{upstream-events.js → projections/upstream-events.js} +1 -1
  86. package/dist/protocol/a2a/http-discovery.d.ts +39 -0
  87. package/dist/protocol/a2a/http-discovery.js +178 -0
  88. package/dist/protocol/a2a/http-rpc.d.ts +28 -0
  89. package/dist/protocol/a2a/http-rpc.js +623 -0
  90. package/dist/protocol/a2a/http.d.ts +72 -1
  91. package/dist/protocol/a2a/http.js +14 -1124
  92. package/dist/protocol/a2a/task-state.d.ts +29 -0
  93. package/dist/protocol/a2a/task-state.js +317 -0
  94. package/dist/protocol/acp/client.js +1 -1
  95. package/dist/protocol/acp/harness-client.d.ts +50 -0
  96. package/dist/protocol/acp/harness-client.js +219 -0
  97. package/dist/protocol/acp/server.d.ts +116 -0
  98. package/dist/protocol/acp/server.js +310 -0
  99. package/dist/protocol/ag-ui/http.js +1 -1
  100. package/dist/protocol/mcp/server.d.ts +76 -0
  101. package/dist/protocol/mcp/server.js +428 -0
  102. package/dist/resource/backend/workspace-scoped-backend.d.ts +40 -0
  103. package/dist/resource/backend/workspace-scoped-backend.js +296 -0
  104. package/dist/resource/mcp/tool-support.d.ts +35 -0
  105. package/dist/resource/mcp/tool-support.js +296 -0
  106. package/dist/resource/mcp-tool-support.d.ts +2 -35
  107. package/dist/resource/mcp-tool-support.js +2 -296
  108. package/dist/resource/providers/resource-provider.d.ts +22 -0
  109. package/dist/resource/providers/resource-provider.js +215 -0
  110. package/dist/resource/resource-impl.d.ts +3 -33
  111. package/dist/resource/resource-impl.js +2 -808
  112. package/dist/resource/resource-types.d.ts +33 -0
  113. package/dist/resource/resource-types.js +1 -0
  114. package/dist/resource/tools/function-tool-resolver.d.ts +2 -0
  115. package/dist/resource/tools/function-tool-resolver.js +306 -0
  116. package/dist/runtime/adapter/middleware-assembly.js +1 -1
  117. package/dist/runtime/adapter/model/invocation-request.js +2 -2
  118. package/dist/runtime/adapter/model/message-assembly.js +1 -1
  119. package/dist/runtime/agent-runtime-adapter.d.ts +3 -63
  120. package/dist/runtime/agent-runtime-adapter.js +5 -233
  121. package/dist/runtime/agent-runtime-assembly.d.ts +67 -0
  122. package/dist/runtime/agent-runtime-assembly.js +211 -0
  123. package/dist/runtime/harness/background-runtime.d.ts +1 -1
  124. package/dist/runtime/harness/events/event-sink.js +1 -1
  125. package/dist/runtime/harness/events/runtime-event-operations.d.ts +1 -1
  126. package/dist/runtime/harness/events/streaming.js +1 -1
  127. package/dist/runtime/harness/public-shapes.d.ts +43 -0
  128. package/dist/runtime/harness/public-shapes.js +186 -0
  129. package/dist/runtime/harness/run/inspection.js +2 -2
  130. package/dist/runtime/harness/run/resources.js +1 -1
  131. package/dist/runtime/harness/run/surface-semantics.js +1 -1
  132. package/dist/runtime/harness/system/inventory.d.ts +1 -1
  133. package/dist/runtime/harness/system/inventory.js +2 -2
  134. package/dist/runtime/harness/system/policy-engine.js +1 -1
  135. package/dist/runtime/harness/system/runtime-memory-manager.js +1 -1
  136. package/dist/runtime/harness/system/skill-requirements.d.ts +1 -1
  137. package/dist/runtime/harness/system/skill-requirements.js +1 -1
  138. package/dist/runtime/harness.d.ts +3 -2
  139. package/dist/runtime/harness.js +11 -191
  140. package/dist/runtime/maintenance/checkpoint-maintenance.js +1 -1
  141. package/dist/runtime/maintenance/runtime-record-maintenance.js +1 -1
  142. package/dist/runtime/parsing/output-content.d.ts +11 -0
  143. package/dist/runtime/parsing/output-content.js +442 -0
  144. package/dist/runtime/parsing/output-parsing.d.ts +3 -29
  145. package/dist/runtime/parsing/output-parsing.js +3 -806
  146. package/dist/runtime/parsing/output-recovery.d.ts +14 -0
  147. package/dist/runtime/parsing/output-recovery.js +288 -0
  148. package/dist/runtime/parsing/output-tool-args.d.ts +4 -0
  149. package/dist/runtime/parsing/output-tool-args.js +120 -0
  150. package/dist/runtime/support/runtime-factories.js +1 -1
  151. package/dist/scaffold/init-project.d.ts +12 -0
  152. package/dist/scaffold/init-project.js +651 -0
  153. package/dist/{extensions.d.ts → tooling/extensions.d.ts} +1 -1
  154. package/dist/{extensions.js → tooling/extensions.js} +3 -3
  155. package/dist/{tool-modules.d.ts → tooling/module-loader.d.ts} +1 -1
  156. package/dist/{tool-modules.js → tooling/module-loader.js} +2 -2
  157. package/dist/workspace/agent-binding-compiler.js +2 -2
  158. package/dist/workspace/compile.js +2 -2
  159. package/dist/workspace/object-loader-paths.d.ts +11 -0
  160. package/dist/workspace/object-loader-paths.js +75 -0
  161. package/dist/workspace/object-loader-readers.d.ts +21 -0
  162. package/dist/workspace/object-loader-readers.js +187 -0
  163. package/dist/workspace/object-loader.d.ts +0 -1
  164. package/dist/workspace/object-loader.js +6 -260
  165. package/dist/workspace/resource-compilers.js +1 -1
  166. package/dist/workspace/support/discovery.js +1 -1
  167. package/package.json +1 -1
  168. package/dist/runtime/adapter/index.d.ts +0 -13
  169. package/dist/runtime/adapter/index.js +0 -13
  170. package/dist/runtime/harness/index.d.ts +0 -19
  171. package/dist/runtime/harness/index.js +0 -19
  172. package/dist/runtime/maintenance/index.d.ts +0 -4
  173. package/dist/runtime/maintenance/index.js +0 -4
  174. package/dist/runtime/parsing/index.d.ts +0 -2
  175. package/dist/runtime/parsing/index.js +0 -2
  176. package/dist/runtime/support/index.d.ts +0 -4
  177. package/dist/runtime/support/index.js +0 -4
  178. package/dist/workspace/support/index.d.ts +0 -2
  179. package/dist/workspace/support/index.js +0 -2
  180. /package/dist/{procedural → knowledge/procedural}/config.d.ts +0 -0
  181. /package/dist/{procedural → knowledge/procedural}/config.js +0 -0
  182. /package/dist/{procedural → knowledge/procedural}/index.d.ts +0 -0
  183. /package/dist/{procedural → knowledge/procedural}/index.js +0 -0
  184. /package/dist/{presentation.d.ts → projections/presentation.d.ts} +0 -0
  185. /package/dist/{presentation.js → projections/presentation.js} +0 -0
  186. /package/dist/{request-events.js → projections/request-events.js} +0 -0
  187. /package/dist/{upstream-events.d.ts → projections/upstream-events.d.ts} +0 -0
  188. /package/dist/runtime/{support → env}/runtime-env.d.ts +0 -0
  189. /package/dist/runtime/{support → env}/runtime-env.js +0 -0
  190. /package/dist/runtime/{support → layout}/runtime-layout.d.ts +0 -0
  191. /package/dist/runtime/{support → layout}/runtime-layout.js +0 -0
  192. /package/dist/runtime/{support → prompts}/runtime-prompts.d.ts +0 -0
  193. /package/dist/runtime/{support → prompts}/runtime-prompts.js +0 -0
  194. /package/dist/runtime/{support → skills}/skill-metadata.d.ts +0 -0
  195. /package/dist/runtime/{support → skills}/skill-metadata.js +0 -0
@@ -0,0 +1,247 @@
1
+ import { renderApprovalList, renderHealthSnapshot, renderJson, renderOperatorOverview, renderRequestList } from "./runtime-output.js";
2
+ import { parseRuntimeExportOptions, parseRuntimeInspectOptions, parseScheduledRunOptions, renderUsage } from "./options.js";
3
+ import { resolveCliWorkspaceRoot, validateCliWorkspaceRoot } from "./workspace.js";
4
+ function resolveValidatedWorkspace(cwd, workspaceRoot, stderr) {
5
+ const workspacePath = resolveCliWorkspaceRoot(cwd, workspaceRoot);
6
+ const workspaceError = validateCliWorkspaceRoot(workspacePath, workspaceRoot);
7
+ if (workspaceError) {
8
+ stderr(`${workspaceError}\n`);
9
+ return undefined;
10
+ }
11
+ return workspacePath;
12
+ }
13
+ export async function handleRuntimeCommand(subcommandAndArgs, io, deps) {
14
+ const { cwd, stdout, stderr } = io;
15
+ const { createHarness, createClient } = deps;
16
+ const [subcommand, possibleNestedCommand, possibleThirdCommand, ...remainingArgs] = subcommandAndArgs;
17
+ if (!subcommand) {
18
+ stderr(renderUsage());
19
+ return 1;
20
+ }
21
+ if (subcommand === "scheduled-run") {
22
+ const parsed = parseScheduledRunOptions([possibleNestedCommand, possibleThirdCommand, ...remainingArgs].filter((item) => typeof item === "string"));
23
+ if (parsed.error) {
24
+ stderr(`${parsed.error}\n`);
25
+ stderr(renderUsage());
26
+ return 1;
27
+ }
28
+ if (!parsed.scheduleId) {
29
+ stderr("Missing value for --schedule\n");
30
+ stderr(renderUsage());
31
+ return 1;
32
+ }
33
+ try {
34
+ const workspacePath = resolveValidatedWorkspace(cwd, parsed.workspaceRoot, stderr);
35
+ if (!workspacePath) {
36
+ return 1;
37
+ }
38
+ const runtime = await createHarness(workspacePath);
39
+ try {
40
+ const result = await runtime.runScheduledTask(parsed.scheduleId);
41
+ stdout(`${String(result.output ?? "").trim()}\n`);
42
+ }
43
+ finally {
44
+ await runtime.stop();
45
+ }
46
+ return 0;
47
+ }
48
+ catch (error) {
49
+ const message = error instanceof Error ? error.message : String(error);
50
+ stderr(`${message}\n`);
51
+ return 1;
52
+ }
53
+ }
54
+ if (subcommand === "export") {
55
+ const exportTarget = possibleNestedCommand;
56
+ const parsed = parseRuntimeExportOptions([possibleThirdCommand, ...remainingArgs].filter((item) => typeof item === "string"));
57
+ if (parsed.error) {
58
+ stderr(`${parsed.error}\n`);
59
+ stderr(renderUsage());
60
+ return 1;
61
+ }
62
+ if (!parsed.sessionId) {
63
+ stderr("Missing value for --session\n");
64
+ stderr(renderUsage());
65
+ return 1;
66
+ }
67
+ if (exportTarget !== "request" && exportTarget !== "session") {
68
+ stderr(renderUsage());
69
+ return 1;
70
+ }
71
+ if (exportTarget === "request" && !parsed.requestId) {
72
+ stderr("Missing value for --request\n");
73
+ stderr(renderUsage());
74
+ return 1;
75
+ }
76
+ try {
77
+ const workspacePath = resolveValidatedWorkspace(cwd, parsed.workspaceRoot, stderr);
78
+ if (!workspacePath) {
79
+ return 1;
80
+ }
81
+ const runtime = await createHarness(workspacePath);
82
+ try {
83
+ if (exportTarget === "request") {
84
+ const pkg = await runtime.exportRequestPackage({
85
+ sessionId: parsed.sessionId,
86
+ requestId: parsed.requestId,
87
+ includeArtifacts: parsed.includeArtifacts,
88
+ includeArtifactContents: parsed.includeArtifactContents,
89
+ includeRuntimeHealth: parsed.includeRuntimeHealth,
90
+ });
91
+ stdout(renderJson(pkg));
92
+ }
93
+ else {
94
+ const pkg = await runtime.exportSessionPackage({
95
+ sessionId: parsed.sessionId,
96
+ includeArtifacts: parsed.includeArtifacts,
97
+ includeArtifactContents: parsed.includeArtifactContents,
98
+ includeRuntimeHealth: parsed.includeRuntimeHealth,
99
+ });
100
+ stdout(renderJson(pkg));
101
+ }
102
+ }
103
+ finally {
104
+ await runtime.stop();
105
+ }
106
+ return 0;
107
+ }
108
+ catch (error) {
109
+ const message = error instanceof Error ? error.message : String(error);
110
+ stderr(`${message}\n`);
111
+ return 1;
112
+ }
113
+ }
114
+ const nestedCommand = (subcommand === "approvals" || subcommand === "requests") && possibleNestedCommand
115
+ ? possibleNestedCommand
116
+ : undefined;
117
+ const subcommandArgs = nestedCommand
118
+ ? [possibleThirdCommand, ...remainingArgs].filter((item) => typeof item === "string")
119
+ : [possibleNestedCommand, possibleThirdCommand, ...remainingArgs].filter((item) => typeof item === "string");
120
+ const parsed = parseRuntimeInspectOptions(subcommandArgs);
121
+ if (parsed.error) {
122
+ stderr(`${parsed.error}\n`);
123
+ stderr(renderUsage());
124
+ return 1;
125
+ }
126
+ try {
127
+ const workspacePath = resolveValidatedWorkspace(cwd, parsed.workspaceRoot, stderr);
128
+ if (!workspacePath) {
129
+ return 1;
130
+ }
131
+ const shouldUseClient = subcommand === "health"
132
+ || subcommand === "overview"
133
+ || (subcommand === "approvals" && (nestedCommand === "list" || nestedCommand === "watch"))
134
+ || (subcommand === "requests" && (nestedCommand === "list" || nestedCommand === "tail"));
135
+ if (shouldUseClient && createClient) {
136
+ const client = await createClient(workspacePath);
137
+ try {
138
+ if (subcommand === "health") {
139
+ const snapshot = await client.getHealth();
140
+ stdout(parsed.json ? renderJson(snapshot) : renderHealthSnapshot(snapshot, workspacePath));
141
+ return 0;
142
+ }
143
+ if (subcommand === "overview") {
144
+ const overview = await client.getOperatorOverview({ limit: parsed.limit });
145
+ stdout(parsed.json ? renderJson(overview) : renderOperatorOverview(overview, workspacePath));
146
+ return 0;
147
+ }
148
+ if (subcommand === "approvals" && (nestedCommand === "list" || nestedCommand === "watch")) {
149
+ const renderApprovals = async () => {
150
+ const approvals = await client.listApprovals(parsed.status ? { status: parsed.status } : undefined);
151
+ stdout(parsed.json ? renderJson(approvals) : renderApprovalList(approvals));
152
+ };
153
+ await renderApprovals();
154
+ if (nestedCommand === "watch" && !parsed.once) {
155
+ for (;;) {
156
+ await deps.sleep(parsed.pollMs);
157
+ await renderApprovals();
158
+ }
159
+ }
160
+ return 0;
161
+ }
162
+ if (subcommand === "requests" && (nestedCommand === "list" || nestedCommand === "tail")) {
163
+ const renderRequests = async () => {
164
+ const requests = await client.listRequests({
165
+ ...(parsed.agentId ? { agentId: parsed.agentId } : {}),
166
+ ...(parsed.sessionId ? { sessionId: parsed.sessionId } : {}),
167
+ ...(parsed.state ? { state: parsed.state } : {}),
168
+ });
169
+ stdout(parsed.json ? renderJson(requests) : renderRequestList(requests));
170
+ };
171
+ await renderRequests();
172
+ if (nestedCommand === "tail" && !parsed.once) {
173
+ for (;;) {
174
+ await deps.sleep(parsed.pollMs);
175
+ await renderRequests();
176
+ }
177
+ }
178
+ return 0;
179
+ }
180
+ }
181
+ finally {
182
+ await client.stop();
183
+ }
184
+ }
185
+ if (shouldUseClient) {
186
+ const runtime = await createHarness(workspacePath);
187
+ try {
188
+ if (subcommand === "health") {
189
+ const snapshot = await runtime.getHealth();
190
+ stdout(parsed.json ? renderJson(snapshot) : renderHealthSnapshot(snapshot, workspacePath));
191
+ return 0;
192
+ }
193
+ if (subcommand === "overview") {
194
+ const overview = await runtime.getOperatorOverview({ limit: parsed.limit });
195
+ stdout(parsed.json ? renderJson(overview) : renderOperatorOverview(overview, workspacePath));
196
+ return 0;
197
+ }
198
+ if (subcommand === "approvals" && (nestedCommand === "list" || nestedCommand === "watch")) {
199
+ const renderApprovals = async () => {
200
+ const approvals = await runtime.listApprovals(parsed.status ? { status: parsed.status } : undefined);
201
+ stdout(parsed.json ? renderJson(approvals) : renderApprovalList(approvals));
202
+ };
203
+ await renderApprovals();
204
+ if (nestedCommand === "watch" && !parsed.once) {
205
+ for (;;) {
206
+ await deps.sleep(parsed.pollMs);
207
+ await renderApprovals();
208
+ }
209
+ }
210
+ return 0;
211
+ }
212
+ if (subcommand === "requests" && (nestedCommand === "list" || nestedCommand === "tail")) {
213
+ const renderRequests = async () => {
214
+ const listRequests = runtime.listRequests?.bind(runtime);
215
+ if (!listRequests) {
216
+ throw new Error("Runtime does not support request listing");
217
+ }
218
+ const requests = await listRequests({
219
+ ...(parsed.agentId ? { agentId: parsed.agentId } : {}),
220
+ ...(parsed.sessionId ? { sessionId: parsed.sessionId } : {}),
221
+ ...(parsed.state ? { state: parsed.state } : {}),
222
+ });
223
+ stdout(parsed.json ? renderJson(requests) : renderRequestList(requests));
224
+ };
225
+ await renderRequests();
226
+ if (nestedCommand === "tail" && !parsed.once) {
227
+ for (;;) {
228
+ await deps.sleep(parsed.pollMs);
229
+ await renderRequests();
230
+ }
231
+ }
232
+ return 0;
233
+ }
234
+ }
235
+ finally {
236
+ await runtime.stop();
237
+ }
238
+ }
239
+ stderr(renderUsage());
240
+ return 1;
241
+ }
242
+ catch (error) {
243
+ const message = error instanceof Error ? error.message : String(error);
244
+ stderr(`${message}\n`);
245
+ return 1;
246
+ }
247
+ }
@@ -0,0 +1,5 @@
1
+ export declare function renderJson(value: unknown): string;
2
+ export declare function renderHealthSnapshot(snapshot: Record<string, unknown>, workspacePath: string): string;
3
+ export declare function renderApprovalList(approvals: Array<Record<string, unknown>>): string;
4
+ export declare function renderRequestList(requests: Array<Record<string, unknown>>): string;
5
+ export declare function renderOperatorOverview(overview: Record<string, unknown>, workspacePath: string): string;
@@ -0,0 +1,124 @@
1
+ function isObject(value) {
2
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3
+ }
4
+ function formatTimestamp(value) {
5
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
6
+ }
7
+ export function renderJson(value) {
8
+ return `${JSON.stringify(value, null, 2)}\n`;
9
+ }
10
+ export function renderHealthSnapshot(snapshot, workspacePath) {
11
+ const lines = [];
12
+ const status = typeof snapshot.status === "string" ? snapshot.status : "unknown";
13
+ lines.push(`Runtime health ${workspacePath}: ${status}`);
14
+ const checks = isObject(snapshot.checks) ? snapshot.checks : {};
15
+ const checkEntries = Object.entries(checks)
16
+ .filter(([, value]) => isObject(value))
17
+ .map(([name, value]) => {
18
+ const check = value;
19
+ const reason = typeof check.reason === "string" && check.reason.trim().length > 0 ? ` (${check.reason})` : "";
20
+ return ` - ${name}: ${typeof check.status === "string" ? check.status : "unknown"}${reason}`;
21
+ });
22
+ if (checkEntries.length > 0) {
23
+ lines.push("Checks:");
24
+ lines.push(...checkEntries);
25
+ }
26
+ const stats = isObject(snapshot.stats) ? snapshot.stats : {};
27
+ const statEntries = [
28
+ ["activeRequestSlots", stats.activeRequestSlots],
29
+ ["pendingRequestSlots", stats.pendingRequestSlots],
30
+ ["pendingApprovals", stats.pendingApprovals],
31
+ ["stuckRequests", stats.stuckRequests],
32
+ ["llmSuccessRate1m", stats.llmSuccessRate1m],
33
+ ["llmP95LatencyMs1m", stats.llmP95LatencyMs1m],
34
+ ]
35
+ .filter(([, value]) => typeof value === "number")
36
+ .map(([name, value]) => ` - ${name}: ${value}`);
37
+ if (statEntries.length > 0) {
38
+ lines.push("Stats:");
39
+ lines.push(...statEntries);
40
+ }
41
+ const symptoms = Array.isArray(snapshot.symptoms) ? snapshot.symptoms.filter(isObject) : [];
42
+ if (symptoms.length > 0) {
43
+ lines.push("Symptoms:");
44
+ lines.push(...symptoms.map((symptom) => {
45
+ const code = typeof symptom.code === "string" ? symptom.code : "unknown";
46
+ const severity = typeof symptom.severity === "string" ? symptom.severity : "unknown";
47
+ const message = typeof symptom.message === "string" ? symptom.message : "";
48
+ return ` - ${code}: ${severity}${message ? ` (${message})` : ""}`;
49
+ }));
50
+ }
51
+ return `${lines.join("\n")}\n`;
52
+ }
53
+ export function renderApprovalList(approvals) {
54
+ if (approvals.length === 0) {
55
+ return "No approvals matched.\n";
56
+ }
57
+ return approvals.map((approval) => {
58
+ const status = typeof approval.status === "string" ? approval.status : "unknown";
59
+ const toolName = typeof approval.toolName === "string" ? approval.toolName : "unknown_tool";
60
+ const approvalId = typeof approval.approvalId === "string" ? approval.approvalId : "unknown";
61
+ const sessionId = typeof approval.sessionId === "string" ? ` session=${approval.sessionId}` : "";
62
+ const requestId = typeof approval.requestId === "string" ? ` request=${approval.requestId}` : "";
63
+ const reason = typeof approval.approvalReason === "string" ? ` reason=${approval.approvalReason}` : "";
64
+ const requestedAt = formatTimestamp(approval.requestedAt);
65
+ const resolvedAt = formatTimestamp(approval.resolvedAt);
66
+ const requested = requestedAt ? ` requested=${requestedAt}` : "";
67
+ const resolved = resolvedAt ? ` resolved=${resolvedAt}` : "";
68
+ return `${approvalId} status=${status} tool=${toolName}${sessionId}${requestId}${reason}${requested}${resolved}`;
69
+ }).join("\n") + "\n";
70
+ }
71
+ export function renderRequestList(requests) {
72
+ if (requests.length === 0) {
73
+ return "No requests matched.\n";
74
+ }
75
+ return requests.map((request) => {
76
+ const requestId = typeof request.requestId === "string" ? request.requestId : "unknown";
77
+ const sessionId = typeof request.sessionId === "string" ? request.sessionId : "unknown";
78
+ const agentId = typeof request.agentId === "string" ? request.agentId : "unknown";
79
+ const state = typeof request.state === "string" ? request.state : "unknown";
80
+ const currentAgent = typeof request.currentAgentId === "string" ? ` current=${request.currentAgentId}` : "";
81
+ const resumable = typeof request.resumable === "boolean" ? ` resumable=${request.resumable}` : "";
82
+ const updatedAt = formatTimestamp(request.updatedAt);
83
+ const lastActivityAt = formatTimestamp(request.lastActivityAt);
84
+ const updated = updatedAt ? ` updated=${updatedAt}` : "";
85
+ const lastActivity = lastActivityAt ? ` activity=${lastActivityAt}` : "";
86
+ return `${requestId} session=${sessionId} agent=${agentId}${currentAgent} state=${state}${resumable}${updated}${lastActivity}`;
87
+ }).join("\n") + "\n";
88
+ }
89
+ export function renderOperatorOverview(overview, workspacePath) {
90
+ const lines = [];
91
+ const summary = typeof overview.summary === "string" ? overview.summary : "";
92
+ lines.push(`Runtime overview ${workspacePath}`);
93
+ if (summary) {
94
+ lines.push(`Summary: ${summary}`);
95
+ }
96
+ const health = isObject(overview.health) ? overview.health : {};
97
+ if (Object.keys(health).length > 0) {
98
+ lines.push("");
99
+ lines.push(renderHealthSnapshot(health, workspacePath).trimEnd());
100
+ }
101
+ const queue = isObject(overview.queue) ? overview.queue : {};
102
+ if (Object.keys(queue).length > 0) {
103
+ lines.push("");
104
+ lines.push(`Queue: ${typeof queue.summary === "string" ? queue.summary : "unavailable"}`);
105
+ }
106
+ const governance = isObject(overview.governance) ? overview.governance : {};
107
+ if (Object.keys(governance).length > 0) {
108
+ lines.push("Governance:");
109
+ lines.push(` - ${typeof governance.summary === "string" ? governance.summary : "unavailable"}`);
110
+ }
111
+ const approvals = isObject(overview.approvals) ? overview.approvals : {};
112
+ const approvalItems = Array.isArray(approvals.items) ? approvals.items.filter(isObject) : [];
113
+ lines.push(`Pending approvals: ${typeof approvals.total === "number" ? approvals.total : approvalItems.length}`);
114
+ if (approvalItems.length > 0) {
115
+ lines.push(renderApprovalList(approvalItems).trimEnd());
116
+ }
117
+ const requests = isObject(overview.requests) ? overview.requests : {};
118
+ const requestItems = Array.isArray(requests.items) ? requests.items.filter(isObject) : [];
119
+ lines.push(`Active requests: ${typeof requests.total === "number" ? requests.total : requestItems.length}`);
120
+ if (requestItems.length > 0) {
121
+ lines.push(renderRequestList(requestItems).trimEnd());
122
+ }
123
+ return `${lines.join("\n")}\n`;
124
+ }
@@ -0,0 +1,36 @@
1
+ import { createAgentHarness } from "../api.js";
2
+ import { serveA2aOverHttp } from "../protocol/a2a/http.js";
3
+ import { serveAgUiOverHttp } from "../protocol/ag-ui/http.js";
4
+ import { serveAcpOverHttp } from "../protocol/acp/http.js";
5
+ import { serveAcpOverStdio } from "../protocol/acp/stdio.js";
6
+ import { serveRuntimeMcpOverStdio, serveRuntimeMcpOverStreamableHttp } from "../mcp.js";
7
+ type CommandIo = {
8
+ cwd: string;
9
+ stderr: (message: string) => void;
10
+ };
11
+ type ManagedDeps = {
12
+ spawnManagedCliProcess: (input: {
13
+ args: string[];
14
+ cwd: string;
15
+ stdoutPath: string;
16
+ stderrPath: string;
17
+ }) => Promise<{
18
+ pid?: number;
19
+ }>;
20
+ isManagedProcessRunning: (pid: number) => boolean;
21
+ signalManagedProcess: (pid: number, signal?: NodeJS.Signals) => void;
22
+ };
23
+ type ServerDeps = ManagedDeps & {
24
+ createHarness: typeof createAgentHarness;
25
+ serveA2a: typeof serveA2aOverHttp;
26
+ serveAgUi: typeof serveAgUiOverHttp;
27
+ serveAcpHttp: typeof serveAcpOverHttp;
28
+ serveAcp: typeof serveAcpOverStdio;
29
+ serveRuntimeMcp: typeof serveRuntimeMcpOverStdio;
30
+ serveRuntimeMcpStreamableHttp: typeof serveRuntimeMcpOverStreamableHttp;
31
+ };
32
+ export declare function handleAcpCommand(subcommandAndArgs: string[], io: CommandIo, deps: ServerDeps): Promise<number>;
33
+ export declare function handleAgUiCommand(subcommandAndArgs: string[], io: CommandIo, deps: Pick<ServerDeps, "createHarness" | "serveAgUi">): Promise<number>;
34
+ export declare function handleA2aCommand(subcommandAndArgs: string[], io: CommandIo, deps: Pick<ServerDeps, "createHarness" | "serveA2a"> & ManagedDeps): Promise<number>;
35
+ export declare function handleMcpCommand(subcommandAndArgs: string[], io: CommandIo, deps: Pick<ServerDeps, "createHarness" | "serveRuntimeMcp" | "serveRuntimeMcpStreamableHttp"> & ManagedDeps): Promise<number>;
36
+ export {};
@@ -0,0 +1,250 @@
1
+ import { parseAcpServeOptions, parseHttpServeOptions, parseRuntimeMcpServeOptions, parseWorkspaceOnlyOptions, renderUsage } from "./options.js";
2
+ import { startManagedHttpService, stopManagedHttpService } from "./managed-service-commands.js";
3
+ import { resolveCliWorkspaceRoot, validateCliWorkspaceRoot } from "./workspace.js";
4
+ function resolveValidatedWorkspace(cwd, workspaceRoot, stderr) {
5
+ const workspacePath = resolveCliWorkspaceRoot(cwd, workspaceRoot);
6
+ const workspaceError = validateCliWorkspaceRoot(workspacePath, workspaceRoot);
7
+ if (workspaceError) {
8
+ stderr(`${workspaceError}\n`);
9
+ return undefined;
10
+ }
11
+ return workspacePath;
12
+ }
13
+ export async function handleAcpCommand(subcommandAndArgs, io, deps) {
14
+ const [subcommand, ...subcommandArgs] = subcommandAndArgs;
15
+ const { cwd, stderr } = io;
16
+ const { createHarness, serveAcp, serveAcpHttp, spawnManagedCliProcess, isManagedProcessRunning, signalManagedProcess } = deps;
17
+ if (subcommand !== "serve" && subcommand !== "start" && subcommand !== "stop") {
18
+ stderr(renderUsage());
19
+ return 1;
20
+ }
21
+ const parsedStop = subcommand === "stop" ? parseWorkspaceOnlyOptions(subcommandArgs) : undefined;
22
+ const parsedServe = subcommand !== "stop"
23
+ ? parseAcpServeOptions(subcommandArgs, subcommand === "start" ? "http" : "stdio")
24
+ : undefined;
25
+ const parseError = parsedStop?.error ?? parsedServe?.error;
26
+ if (parseError) {
27
+ stderr(`${parseError}\n`);
28
+ stderr(renderUsage());
29
+ return 1;
30
+ }
31
+ try {
32
+ const workspaceRoot = parsedStop?.workspaceRoot ?? parsedServe?.workspaceRoot;
33
+ const workspacePath = resolveValidatedWorkspace(cwd, workspaceRoot, stderr);
34
+ if (!workspacePath) {
35
+ return 1;
36
+ }
37
+ if (subcommand === "start") {
38
+ if (!parsedServe) {
39
+ stderr(renderUsage());
40
+ return 1;
41
+ }
42
+ if (parsedServe.transport !== "http") {
43
+ stderr("ACP start only supports --transport http. Use `acp serve --transport stdio` for stdio clients.\n");
44
+ return 1;
45
+ }
46
+ const args = ["acp", "serve", "--workspace", workspacePath, "--transport", "http"];
47
+ if (parsedServe.hostname) {
48
+ args.push("--host", parsedServe.hostname);
49
+ }
50
+ if (typeof parsedServe.port === "number") {
51
+ args.push("--port", String(parsedServe.port));
52
+ }
53
+ return startManagedHttpService({ service: "acp", workspacePath, args, stderr, spawnManagedCliProcess, isManagedProcessRunning });
54
+ }
55
+ if (subcommand === "stop") {
56
+ return stopManagedHttpService({ service: "acp", workspacePath, stderr, isManagedProcessRunning, signalManagedProcess });
57
+ }
58
+ if (!parsedServe) {
59
+ stderr(renderUsage());
60
+ return 1;
61
+ }
62
+ const runtime = await createHarness(workspacePath);
63
+ if (parsedServe.transport === "http") {
64
+ const server = await serveAcpHttp(runtime, {
65
+ hostname: parsedServe.hostname,
66
+ port: parsedServe.port,
67
+ });
68
+ stderr(`Serving ACP over http from ${workspacePath} at ${server.rpcUrl} (events ${server.eventsUrl})\n`);
69
+ await server.completed;
70
+ }
71
+ else {
72
+ stderr(`Serving ACP over stdio from ${workspacePath}\n`);
73
+ const server = serveAcp(runtime);
74
+ await server.completed;
75
+ }
76
+ await runtime.stop();
77
+ return 0;
78
+ }
79
+ catch (error) {
80
+ const message = error instanceof Error ? error.message : String(error);
81
+ stderr(`${message}\n`);
82
+ return 1;
83
+ }
84
+ }
85
+ export async function handleAgUiCommand(subcommandAndArgs, io, deps) {
86
+ const [subcommand, ...subcommandArgs] = subcommandAndArgs;
87
+ const { cwd, stderr } = io;
88
+ const { createHarness, serveAgUi } = deps;
89
+ if (subcommand !== "serve") {
90
+ stderr(renderUsage());
91
+ return 1;
92
+ }
93
+ const parsed = parseHttpServeOptions(subcommandArgs, "AG-UI");
94
+ if (parsed.error) {
95
+ stderr(`${parsed.error}\n`);
96
+ stderr(renderUsage());
97
+ return 1;
98
+ }
99
+ try {
100
+ const workspacePath = resolveValidatedWorkspace(cwd, parsed.workspaceRoot, stderr);
101
+ if (!workspacePath) {
102
+ return 1;
103
+ }
104
+ const runtime = await createHarness(workspacePath);
105
+ const server = await serveAgUi(runtime, {
106
+ hostname: parsed.hostname,
107
+ port: parsed.port,
108
+ });
109
+ stderr(`Serving AG-UI over http from ${workspacePath} at ${server.runUrl}\n`);
110
+ await server.completed;
111
+ await runtime.stop();
112
+ return 0;
113
+ }
114
+ catch (error) {
115
+ const message = error instanceof Error ? error.message : String(error);
116
+ stderr(`${message}\n`);
117
+ return 1;
118
+ }
119
+ }
120
+ export async function handleA2aCommand(subcommandAndArgs, io, deps) {
121
+ const [subcommand, ...subcommandArgs] = subcommandAndArgs;
122
+ const { cwd, stderr } = io;
123
+ const { createHarness, serveA2a, spawnManagedCliProcess, isManagedProcessRunning, signalManagedProcess } = deps;
124
+ if (subcommand !== "serve" && subcommand !== "start" && subcommand !== "stop") {
125
+ stderr(renderUsage());
126
+ return 1;
127
+ }
128
+ const parsedStop = subcommand === "stop" ? parseWorkspaceOnlyOptions(subcommandArgs) : undefined;
129
+ const parsedServe = subcommand !== "stop" ? parseHttpServeOptions(subcommandArgs, "A2A") : undefined;
130
+ const parseError = parsedStop?.error ?? parsedServe?.error;
131
+ if (parseError) {
132
+ stderr(`${parseError}\n`);
133
+ stderr(renderUsage());
134
+ return 1;
135
+ }
136
+ try {
137
+ const workspaceRoot = parsedStop?.workspaceRoot ?? parsedServe?.workspaceRoot;
138
+ const workspacePath = resolveValidatedWorkspace(cwd, workspaceRoot, stderr);
139
+ if (!workspacePath) {
140
+ return 1;
141
+ }
142
+ if (subcommand === "start") {
143
+ const args = ["a2a", "serve", "--workspace", workspacePath];
144
+ if (parsedServe?.hostname) {
145
+ args.push("--host", parsedServe.hostname);
146
+ }
147
+ if (typeof parsedServe?.port === "number") {
148
+ args.push("--port", String(parsedServe.port));
149
+ }
150
+ return startManagedHttpService({ service: "a2a", workspacePath, args, stderr, spawnManagedCliProcess, isManagedProcessRunning });
151
+ }
152
+ if (subcommand === "stop") {
153
+ return stopManagedHttpService({ service: "a2a", workspacePath, stderr, isManagedProcessRunning, signalManagedProcess });
154
+ }
155
+ if (!parsedServe) {
156
+ stderr(renderUsage());
157
+ return 1;
158
+ }
159
+ const runtime = await createHarness(workspacePath);
160
+ const server = await serveA2a(runtime, {
161
+ hostname: parsedServe.hostname,
162
+ port: parsedServe.port,
163
+ });
164
+ stderr(`Serving A2A over http from ${workspacePath} at ${server.rpcUrl} (card ${server.agentCardUrl})\n`);
165
+ await server.completed;
166
+ await runtime.stop();
167
+ return 0;
168
+ }
169
+ catch (error) {
170
+ const message = error instanceof Error ? error.message : String(error);
171
+ stderr(`${message}\n`);
172
+ return 1;
173
+ }
174
+ }
175
+ export async function handleMcpCommand(subcommandAndArgs, io, deps) {
176
+ const [subcommand, ...subcommandArgs] = subcommandAndArgs;
177
+ const { cwd, stderr } = io;
178
+ const { createHarness, serveRuntimeMcp, serveRuntimeMcpStreamableHttp, spawnManagedCliProcess, isManagedProcessRunning, signalManagedProcess } = deps;
179
+ if (subcommand !== "serve" && subcommand !== "start" && subcommand !== "stop") {
180
+ stderr(renderUsage());
181
+ return 1;
182
+ }
183
+ const parsedStop = subcommand === "stop" ? parseWorkspaceOnlyOptions(subcommandArgs) : undefined;
184
+ const parsedServe = subcommand !== "stop"
185
+ ? parseRuntimeMcpServeOptions(subcommandArgs, subcommand === "start" ? "streamable-http" : "stdio")
186
+ : undefined;
187
+ const parseError = parsedStop?.error ?? parsedServe?.error;
188
+ if (parseError) {
189
+ stderr(`${parseError}\n`);
190
+ stderr(renderUsage());
191
+ return 1;
192
+ }
193
+ try {
194
+ const workspaceRoot = parsedStop?.workspaceRoot ?? parsedServe?.workspaceRoot;
195
+ const workspacePath = resolveValidatedWorkspace(cwd, workspaceRoot, stderr);
196
+ if (!workspacePath) {
197
+ return 1;
198
+ }
199
+ if (subcommand === "start") {
200
+ if (!parsedServe) {
201
+ stderr(renderUsage());
202
+ return 1;
203
+ }
204
+ if (parsedServe.transport !== "streamable-http") {
205
+ stderr("MCP start only supports --transport streamable-http. Use `mcp serve --transport stdio` for stdio clients.\n");
206
+ return 1;
207
+ }
208
+ const args = ["mcp", "serve", "--workspace", workspacePath, "--transport", "streamable-http"];
209
+ if (parsedServe.hostname) {
210
+ args.push("--host", parsedServe.hostname);
211
+ }
212
+ if (typeof parsedServe.port === "number") {
213
+ args.push("--port", String(parsedServe.port));
214
+ }
215
+ return startManagedHttpService({ service: "mcp", workspacePath, args, stderr, spawnManagedCliProcess, isManagedProcessRunning });
216
+ }
217
+ if (subcommand === "stop") {
218
+ return stopManagedHttpService({ service: "mcp", workspacePath, stderr, isManagedProcessRunning, signalManagedProcess });
219
+ }
220
+ if (!parsedServe) {
221
+ stderr(renderUsage());
222
+ return 1;
223
+ }
224
+ const runtime = await createHarness(workspacePath);
225
+ if (parsedServe.transport === "streamable-http") {
226
+ const server = await serveRuntimeMcpStreamableHttp(runtime, {
227
+ hostname: parsedServe.hostname,
228
+ port: parsedServe.port,
229
+ });
230
+ stderr(`Serving runtime MCP over streamable HTTP from ${workspacePath} at ${server.url}\n`);
231
+ await server.completed;
232
+ }
233
+ else {
234
+ stderr(`Serving runtime MCP over stdio from ${workspacePath}\n`);
235
+ const server = await serveRuntimeMcp(runtime);
236
+ await new Promise((resolve, reject) => {
237
+ process.stdin.on("end", resolve);
238
+ process.stdin.on("error", reject);
239
+ });
240
+ await server.close();
241
+ }
242
+ await runtime.stop();
243
+ return 0;
244
+ }
245
+ catch (error) {
246
+ const message = error instanceof Error ? error.message : String(error);
247
+ stderr(`${message}\n`);
248
+ return 1;
249
+ }
250
+ }
@@ -0,0 +1,6 @@
1
+ export declare function resolveCliWorkspaceRoot(cwd: string, inputPath?: string): string;
2
+ export declare function getWorkspaceConfigPath(workspaceRoot: string): string;
3
+ export declare function hasCliConfigYaml(configRoot: string): boolean;
4
+ export declare function validateCliWorkspaceRoot(workspaceRoot: string, inputPath?: string): string | undefined;
5
+ export declare function resolveCliConfigRoot(workspaceRoot: string): string;
6
+ export declare function frameworkCliWorkspaceRoot(): string;