byterover-cli 1.0.5 → 1.2.0

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 (204) hide show
  1. package/README.md +19 -13
  2. package/dist/commands/hook-prompt-submit.d.ts +27 -0
  3. package/dist/commands/hook-prompt-submit.js +39 -0
  4. package/dist/commands/mcp.d.ts +13 -0
  5. package/dist/commands/mcp.js +61 -0
  6. package/dist/commands/status.js +8 -3
  7. package/dist/constants.d.ts +1 -1
  8. package/dist/constants.js +1 -1
  9. package/dist/core/domain/cipher/agent-events/types.d.ts +44 -1
  10. package/dist/core/domain/cipher/tools/constants.d.ts +1 -0
  11. package/dist/core/domain/cipher/tools/constants.js +1 -0
  12. package/dist/core/domain/entities/agent.d.ts +16 -0
  13. package/dist/core/domain/entities/agent.js +78 -0
  14. package/dist/core/domain/entities/connector-type.d.ts +10 -0
  15. package/dist/core/domain/entities/connector-type.js +9 -0
  16. package/dist/core/domain/entities/event.d.ts +1 -1
  17. package/dist/core/domain/entities/event.js +2 -0
  18. package/dist/core/domain/errors/task-error.d.ts +4 -0
  19. package/dist/core/domain/errors/task-error.js +7 -0
  20. package/dist/core/domain/transport/schemas.d.ts +40 -0
  21. package/dist/core/domain/transport/schemas.js +28 -0
  22. package/dist/core/interfaces/connectors/connector-types.d.ts +70 -0
  23. package/dist/core/interfaces/connectors/i-connector-manager.d.ts +72 -0
  24. package/dist/core/interfaces/connectors/i-connector-manager.js +1 -0
  25. package/dist/core/interfaces/connectors/i-connector.d.ts +54 -0
  26. package/dist/core/interfaces/connectors/i-connector.js +1 -0
  27. package/dist/core/interfaces/i-file-service.d.ts +7 -0
  28. package/dist/core/interfaces/i-mcp-config-writer.d.ts +40 -0
  29. package/dist/core/interfaces/i-mcp-config-writer.js +1 -0
  30. package/dist/core/interfaces/i-rule-template-service.d.ts +4 -2
  31. package/dist/core/interfaces/transport/i-transport-client.d.ts +7 -0
  32. package/dist/core/interfaces/usecase/i-connectors-use-case.d.ts +3 -0
  33. package/dist/core/interfaces/usecase/i-connectors-use-case.js +1 -0
  34. package/dist/hooks/init/update-notifier.d.ts +1 -0
  35. package/dist/hooks/init/update-notifier.js +10 -1
  36. package/dist/infra/cipher/agent/cipher-agent.d.ts +8 -0
  37. package/dist/infra/cipher/agent/cipher-agent.js +16 -0
  38. package/dist/infra/cipher/file-system/binary-utils.d.ts +7 -12
  39. package/dist/infra/cipher/file-system/binary-utils.js +46 -31
  40. package/dist/infra/cipher/llm/context/context-manager.d.ts +10 -2
  41. package/dist/infra/cipher/llm/context/context-manager.js +39 -2
  42. package/dist/infra/cipher/llm/formatters/gemini-formatter.js +48 -9
  43. package/dist/infra/cipher/llm/internal-llm-service.d.ts +4 -0
  44. package/dist/infra/cipher/llm/internal-llm-service.js +40 -12
  45. package/dist/infra/cipher/session/chat-session.d.ts +3 -0
  46. package/dist/infra/cipher/session/chat-session.js +7 -1
  47. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.d.ts +6 -7
  48. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.js +57 -18
  49. package/dist/infra/cipher/tools/implementations/curate-tool.d.ts +1 -8
  50. package/dist/infra/cipher/tools/implementations/curate-tool.js +380 -24
  51. package/dist/infra/cipher/tools/implementations/read-file-tool.js +38 -17
  52. package/dist/infra/cipher/tools/implementations/search-knowledge-tool.d.ts +7 -0
  53. package/dist/infra/cipher/tools/implementations/search-knowledge-tool.js +303 -0
  54. package/dist/infra/cipher/tools/index.d.ts +1 -0
  55. package/dist/infra/cipher/tools/index.js +1 -0
  56. package/dist/infra/cipher/tools/tool-manager.js +1 -0
  57. package/dist/infra/cipher/tools/tool-registry.js +7 -0
  58. package/dist/infra/connectors/connector-manager.d.ts +32 -0
  59. package/dist/infra/connectors/connector-manager.js +158 -0
  60. package/dist/infra/connectors/hook/hook-connector-config.d.ts +52 -0
  61. package/dist/infra/connectors/hook/hook-connector-config.js +41 -0
  62. package/dist/infra/connectors/hook/hook-connector.d.ts +46 -0
  63. package/dist/infra/connectors/hook/hook-connector.js +231 -0
  64. package/dist/infra/connectors/mcp/index.d.ts +4 -0
  65. package/dist/infra/connectors/mcp/index.js +4 -0
  66. package/dist/infra/connectors/mcp/json-mcp-config-writer.d.ts +26 -0
  67. package/dist/infra/connectors/mcp/json-mcp-config-writer.js +71 -0
  68. package/dist/infra/connectors/mcp/mcp-connector-config.d.ts +229 -0
  69. package/dist/infra/connectors/mcp/mcp-connector-config.js +173 -0
  70. package/dist/infra/connectors/mcp/mcp-connector.d.ts +80 -0
  71. package/dist/infra/connectors/mcp/mcp-connector.js +324 -0
  72. package/dist/infra/connectors/mcp/toml-mcp-config-writer.d.ts +45 -0
  73. package/dist/infra/connectors/mcp/toml-mcp-config-writer.js +134 -0
  74. package/dist/infra/{rule → connectors/rules}/legacy-rule-detector.d.ts +2 -2
  75. package/dist/infra/{rule → connectors/rules}/legacy-rule-detector.js +1 -1
  76. package/dist/infra/connectors/rules/rules-connector-config.d.ts +95 -0
  77. package/dist/infra/{rule/agent-rule-config.js → connectors/rules/rules-connector-config.js} +10 -10
  78. package/dist/infra/connectors/rules/rules-connector.d.ts +34 -0
  79. package/dist/infra/connectors/rules/rules-connector.js +139 -0
  80. package/dist/infra/connectors/shared/rule-file-manager.d.ts +72 -0
  81. package/dist/infra/connectors/shared/rule-file-manager.js +119 -0
  82. package/dist/infra/connectors/shared/template-service.d.ts +27 -0
  83. package/dist/infra/connectors/shared/template-service.js +125 -0
  84. package/dist/infra/context-tree/file-context-tree-writer-service.d.ts +5 -2
  85. package/dist/infra/context-tree/file-context-tree-writer-service.js +20 -5
  86. package/dist/infra/core/executors/curate-executor.d.ts +2 -2
  87. package/dist/infra/core/executors/curate-executor.js +7 -7
  88. package/dist/infra/core/executors/query-executor.d.ts +12 -0
  89. package/dist/infra/core/executors/query-executor.js +62 -1
  90. package/dist/infra/file/fs-file-service.d.ts +7 -0
  91. package/dist/infra/file/fs-file-service.js +15 -1
  92. package/dist/infra/mcp/index.d.ts +2 -0
  93. package/dist/infra/mcp/index.js +2 -0
  94. package/dist/infra/mcp/mcp-server.d.ts +58 -0
  95. package/dist/infra/mcp/mcp-server.js +178 -0
  96. package/dist/infra/mcp/tools/brv-curate-tool.d.ts +23 -0
  97. package/dist/infra/mcp/tools/brv-curate-tool.js +68 -0
  98. package/dist/infra/mcp/tools/brv-query-tool.d.ts +17 -0
  99. package/dist/infra/mcp/tools/brv-query-tool.js +68 -0
  100. package/dist/infra/mcp/tools/index.d.ts +3 -0
  101. package/dist/infra/mcp/tools/index.js +3 -0
  102. package/dist/infra/mcp/tools/task-result-waiter.d.ts +30 -0
  103. package/dist/infra/mcp/tools/task-result-waiter.js +56 -0
  104. package/dist/infra/process/agent-worker.d.ts +2 -2
  105. package/dist/infra/process/agent-worker.js +663 -142
  106. package/dist/infra/process/constants.d.ts +1 -1
  107. package/dist/infra/process/constants.js +1 -1
  108. package/dist/infra/process/ipc-types.d.ts +17 -4
  109. package/dist/infra/process/ipc-types.js +3 -3
  110. package/dist/infra/process/parent-heartbeat.d.ts +47 -0
  111. package/dist/infra/process/parent-heartbeat.js +118 -0
  112. package/dist/infra/process/process-manager.d.ts +79 -0
  113. package/dist/infra/process/process-manager.js +277 -3
  114. package/dist/infra/process/task-queue-manager.d.ts +13 -0
  115. package/dist/infra/process/task-queue-manager.js +19 -0
  116. package/dist/infra/process/transport-handlers.d.ts +3 -0
  117. package/dist/infra/process/transport-handlers.js +51 -5
  118. package/dist/infra/process/transport-worker.js +9 -69
  119. package/dist/infra/repl/commands/connectors-command.d.ts +8 -0
  120. package/dist/infra/repl/commands/{gen-rules-command.js → connectors-command.js} +21 -10
  121. package/dist/infra/repl/commands/curate-command.js +2 -2
  122. package/dist/infra/repl/commands/index.js +3 -2
  123. package/dist/infra/repl/commands/init-command.js +11 -7
  124. package/dist/infra/repl/commands/query-command.js +22 -2
  125. package/dist/infra/repl/commands/reset-command.js +1 -1
  126. package/dist/infra/transport/socket-io-transport-client.d.ts +75 -0
  127. package/dist/infra/transport/socket-io-transport-client.js +308 -7
  128. package/dist/infra/transport/socket-io-transport-server.js +4 -0
  129. package/dist/infra/usecase/connectors-use-case.d.ts +63 -0
  130. package/dist/infra/usecase/connectors-use-case.js +222 -0
  131. package/dist/infra/usecase/init-use-case.d.ts +8 -43
  132. package/dist/infra/usecase/init-use-case.js +27 -252
  133. package/dist/infra/usecase/logout-use-case.js +1 -1
  134. package/dist/infra/usecase/pull-use-case.js +5 -5
  135. package/dist/infra/usecase/push-use-case.js +4 -4
  136. package/dist/infra/usecase/reset-use-case.js +3 -4
  137. package/dist/infra/usecase/space-list-use-case.js +3 -3
  138. package/dist/infra/usecase/space-switch-use-case.js +3 -3
  139. package/dist/infra/usecase/status-use-case.d.ts +10 -0
  140. package/dist/infra/usecase/status-use-case.js +53 -0
  141. package/dist/resources/prompts/curate.yml +114 -4
  142. package/dist/resources/prompts/explore.yml +34 -0
  143. package/dist/resources/prompts/query-orchestrator.yml +112 -0
  144. package/dist/resources/prompts/system-prompt.yml +12 -2
  145. package/dist/resources/tools/search_knowledge.txt +32 -0
  146. package/dist/templates/mcp-base.md +1 -0
  147. package/dist/templates/sections/brv-instructions.md +98 -0
  148. package/dist/templates/sections/mcp-workflow.md +13 -0
  149. package/dist/tui/app.js +4 -1
  150. package/dist/tui/components/command-details.js +1 -1
  151. package/dist/tui/components/execution/execution-changes.d.ts +2 -0
  152. package/dist/tui/components/execution/execution-changes.js +5 -1
  153. package/dist/tui/components/execution/execution-content.d.ts +2 -0
  154. package/dist/tui/components/execution/execution-content.js +8 -18
  155. package/dist/tui/components/execution/execution-input.d.ts +2 -0
  156. package/dist/tui/components/execution/execution-input.js +6 -4
  157. package/dist/tui/components/execution/execution-progress.d.ts +2 -0
  158. package/dist/tui/components/execution/execution-progress.js +6 -2
  159. package/dist/tui/components/execution/expanded-log-view.d.ts +20 -0
  160. package/dist/tui/components/execution/expanded-log-view.js +75 -0
  161. package/dist/tui/components/execution/expanded-message-view.d.ts +24 -0
  162. package/dist/tui/components/execution/expanded-message-view.js +68 -0
  163. package/dist/tui/components/execution/index.d.ts +2 -0
  164. package/dist/tui/components/execution/index.js +2 -0
  165. package/dist/tui/components/execution/log-item.d.ts +4 -0
  166. package/dist/tui/components/execution/log-item.js +2 -2
  167. package/dist/tui/components/footer.js +1 -1
  168. package/dist/tui/components/index.d.ts +2 -1
  169. package/dist/tui/components/index.js +2 -1
  170. package/dist/tui/components/init.js +2 -9
  171. package/dist/tui/components/logo.js +4 -3
  172. package/dist/tui/components/markdown.d.ts +13 -0
  173. package/dist/tui/components/markdown.js +88 -0
  174. package/dist/tui/components/message-item.js +1 -1
  175. package/dist/tui/components/onboarding/onboarding-flow.js +14 -11
  176. package/dist/tui/components/onboarding/welcome-box.js +1 -1
  177. package/dist/tui/components/suggestions.js +3 -3
  178. package/dist/tui/contexts/mode-context.js +6 -2
  179. package/dist/tui/contexts/onboarding-context.d.ts +4 -0
  180. package/dist/tui/contexts/onboarding-context.js +14 -2
  181. package/dist/tui/hooks/index.d.ts +1 -0
  182. package/dist/tui/hooks/index.js +1 -0
  183. package/dist/tui/hooks/use-is-latest-version.d.ts +6 -0
  184. package/dist/tui/hooks/use-is-latest-version.js +22 -0
  185. package/dist/tui/views/command-view.d.ts +1 -1
  186. package/dist/tui/views/command-view.js +87 -98
  187. package/dist/tui/views/logs-view.d.ts +8 -0
  188. package/dist/tui/views/logs-view.js +55 -27
  189. package/dist/utils/file-validator.d.ts +1 -1
  190. package/dist/utils/file-validator.js +25 -28
  191. package/dist/utils/type-guards.d.ts +5 -0
  192. package/dist/utils/type-guards.js +7 -0
  193. package/oclif.manifest.json +55 -4
  194. package/package.json +12 -1
  195. package/dist/core/interfaces/usecase/i-generate-rules-use-case.d.ts +0 -3
  196. package/dist/infra/repl/commands/gen-rules-command.d.ts +0 -7
  197. package/dist/infra/rule/agent-rule-config.d.ts +0 -19
  198. package/dist/infra/rule/rule-template-service.d.ts +0 -18
  199. package/dist/infra/rule/rule-template-service.js +0 -88
  200. package/dist/infra/usecase/generate-rules-use-case.d.ts +0 -61
  201. package/dist/infra/usecase/generate-rules-use-case.js +0 -285
  202. /package/dist/core/interfaces/{usecase/i-generate-rules-use-case.js → connectors/connector-types.js} +0 -0
  203. /package/dist/infra/{rule → connectors/shared}/constants.d.ts +0 -0
  204. /package/dist/infra/{rule → connectors/shared}/constants.js +0 -0
@@ -0,0 +1,23 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { z } from 'zod';
3
+ import type { ITransportClient } from '../../../core/interfaces/transport/index.js';
4
+ export declare const BrvCurateInputSchema: z.ZodObject<{
5
+ context: z.ZodString;
6
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
7
+ }, "strip", z.ZodTypeAny, {
8
+ context: string;
9
+ files?: string[] | undefined;
10
+ }, {
11
+ context: string;
12
+ files?: string[] | undefined;
13
+ }>;
14
+ /**
15
+ * Registers the brv-curate tool with the MCP server.
16
+ *
17
+ * This tool allows coding agents to store context to the ByteRover context tree.
18
+ * Use it to save patterns, architectural decisions, error solutions, or insights.
19
+ *
20
+ * Uses fire-and-forget pattern: returns immediately after queueing the task.
21
+ * The curation is processed asynchronously by the ByteRover agent.
22
+ */
23
+ export declare function registerBrvCurateTool(server: McpServer, getClient: () => ITransportClient | undefined, getWorkingDirectory: () => string): void;
@@ -0,0 +1,68 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ export const BrvCurateInputSchema = z.object({
4
+ context: z.string().describe('Knowledge to store: patterns, decisions, errors, or insights about the codebase'),
5
+ files: z
6
+ .array(z.string())
7
+ .max(5)
8
+ .optional()
9
+ .describe('Optional file paths with critical context to include (max 5 files)'),
10
+ });
11
+ /**
12
+ * Registers the brv-curate tool with the MCP server.
13
+ *
14
+ * This tool allows coding agents to store context to the ByteRover context tree.
15
+ * Use it to save patterns, architectural decisions, error solutions, or insights.
16
+ *
17
+ * Uses fire-and-forget pattern: returns immediately after queueing the task.
18
+ * The curation is processed asynchronously by the ByteRover agent.
19
+ */
20
+ export function registerBrvCurateTool(server, getClient, getWorkingDirectory) {
21
+ server.registerTool('brv-curate', {
22
+ description: 'Store context to the ByteRover context tree. Save patterns, decisions, or insights.',
23
+ inputSchema: BrvCurateInputSchema,
24
+ title: 'ByteRover Curate',
25
+ }, async ({ context, files }) => {
26
+ const client = getClient();
27
+ if (!client) {
28
+ return {
29
+ content: [{ text: 'Error: Not connected to ByteRover instance. Run "brv" first.', type: 'text' }],
30
+ isError: true,
31
+ };
32
+ }
33
+ // Check connection state before making request
34
+ const state = client.getState();
35
+ if (state !== 'connected') {
36
+ return {
37
+ content: [{ text: `Error: Socket not connected. Current state: ${state}. Ensure "brv" is running.`, type: 'text' }],
38
+ isError: true,
39
+ };
40
+ }
41
+ try {
42
+ const taskId = randomUUID();
43
+ // Create task via transport (same pattern as brv curate command)
44
+ await client.request('task:create', {
45
+ clientCwd: getWorkingDirectory(),
46
+ content: context,
47
+ taskId,
48
+ type: 'curate',
49
+ ...(files?.length ? { files } : {}),
50
+ });
51
+ // Fire-and-forget: return immediately after task is queued
52
+ // Curation is processed asynchronously by the ByteRover agent
53
+ return {
54
+ content: [{
55
+ text: `✓ Context queued for curation (taskId: ${taskId}). The curation will be processed asynchronously.`,
56
+ type: 'text',
57
+ }],
58
+ };
59
+ }
60
+ catch (error) {
61
+ const message = error instanceof Error ? error.message : String(error);
62
+ return {
63
+ content: [{ text: `Error: ${message}`, type: 'text' }],
64
+ isError: true,
65
+ };
66
+ }
67
+ });
68
+ }
@@ -0,0 +1,17 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { z } from 'zod';
3
+ import type { ITransportClient } from '../../../core/interfaces/transport/index.js';
4
+ export declare const BrvQueryInputSchema: z.ZodObject<{
5
+ query: z.ZodString;
6
+ }, "strip", z.ZodTypeAny, {
7
+ query: string;
8
+ }, {
9
+ query: string;
10
+ }>;
11
+ /**
12
+ * Registers the brv-query tool with the MCP server.
13
+ *
14
+ * This tool allows coding agents to query the ByteRover context tree
15
+ * for patterns, decisions, implementation details, or any stored knowledge.
16
+ */
17
+ export declare function registerBrvQueryTool(server: McpServer, getClient: () => ITransportClient | undefined, getWorkingDirectory: () => string): void;
@@ -0,0 +1,68 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ import { waitForTaskResult } from './task-result-waiter.js';
4
+ export const BrvQueryInputSchema = z.object({
5
+ query: z.string().describe('Natural language question about the codebase or project'),
6
+ });
7
+ /**
8
+ * Registers the brv-query tool with the MCP server.
9
+ *
10
+ * This tool allows coding agents to query the ByteRover context tree
11
+ * for patterns, decisions, implementation details, or any stored knowledge.
12
+ */
13
+ export function registerBrvQueryTool(server, getClient, getWorkingDirectory) {
14
+ server.registerTool('brv-query', {
15
+ description: 'Query the ByteRover context tree for patterns, decisions, or implementation details.',
16
+ inputSchema: BrvQueryInputSchema,
17
+ title: 'ByteRover Query',
18
+ }, async ({ query }) => {
19
+ const timestamp = new Date().toISOString();
20
+ process.stderr.write(`[brv-mcp] [${timestamp}] brv-query tool called with query: ${query.slice(0, 50)}...\n`);
21
+ const client = getClient();
22
+ process.stderr.write(`[brv-mcp] [${timestamp}] Client exists: ${client}\n`);
23
+ if (!client) {
24
+ process.stderr.write(`[brv-mcp] [${timestamp}] ERROR: Client is undefined\n`);
25
+ return {
26
+ content: [{ text: 'Error: Not connected to ByteRover instance. Run "brv" first.', type: 'text' }],
27
+ isError: true,
28
+ };
29
+ }
30
+ // Check connection state before making request
31
+ const state = client.getState();
32
+ process.stderr.write(`[brv-mcp] [${timestamp}] Client state: ${state}, Client ID: ${client.getClientId()}\n`);
33
+ if (state !== 'connected') {
34
+ process.stderr.write(`[brv-mcp] [${timestamp}] ERROR: Socket not connected\n`);
35
+ return {
36
+ content: [
37
+ {
38
+ text: `Error: Socket not connected. Current state: ${state}. Ensure "brv" is running.`,
39
+ type: 'text',
40
+ },
41
+ ],
42
+ isError: true,
43
+ };
44
+ }
45
+ try {
46
+ const taskId = randomUUID();
47
+ // Create task via transport (same pattern as brv query command)
48
+ await client.request('task:create', {
49
+ clientCwd: getWorkingDirectory(),
50
+ content: query,
51
+ taskId,
52
+ type: 'query',
53
+ });
54
+ // Wait for task completion and return result
55
+ const result = await waitForTaskResult(client, taskId);
56
+ return {
57
+ content: [{ text: result, type: 'text' }],
58
+ };
59
+ }
60
+ catch (error) {
61
+ const message = error instanceof Error ? error.message : String(error);
62
+ return {
63
+ content: [{ text: `Error: ${message}`, type: 'text' }],
64
+ isError: true,
65
+ };
66
+ }
67
+ });
68
+ }
@@ -0,0 +1,3 @@
1
+ export { registerBrvCurateTool } from './brv-curate-tool.js';
2
+ export { registerBrvQueryTool } from './brv-query-tool.js';
3
+ export { waitForTaskResult } from './task-result-waiter.js';
@@ -0,0 +1,3 @@
1
+ export { registerBrvCurateTool } from './brv-curate-tool.js';
2
+ export { registerBrvQueryTool } from './brv-query-tool.js';
3
+ export { waitForTaskResult } from './task-result-waiter.js';
@@ -0,0 +1,30 @@
1
+ import type { ITransportClient } from '../../../core/interfaces/transport/index.js';
2
+ export interface TaskCompletedPayload {
3
+ result: string;
4
+ taskId: string;
5
+ }
6
+ export interface TaskErrorPayload {
7
+ error: {
8
+ code?: string;
9
+ details?: Record<string, unknown>;
10
+ message: string;
11
+ name: string;
12
+ };
13
+ taskId: string;
14
+ }
15
+ export interface LlmResponsePayload {
16
+ content: string;
17
+ taskId: string;
18
+ }
19
+ /**
20
+ * Waits for a task to complete and returns the result.
21
+ *
22
+ * Unlike the fire-and-forget pattern used by `brv curate`, MCP tools need
23
+ * to wait for the task to finish and return the result to the coding agent.
24
+ *
25
+ * This function listens for:
26
+ * - llmservice:response: Captures the LLM's text response
27
+ * - task:completed: Task finished successfully
28
+ * - task:error: Task failed with an error
29
+ */
30
+ export declare function waitForTaskResult(client: ITransportClient, taskId: string, timeoutMs?: number): Promise<string>;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Waits for a task to complete and returns the result.
3
+ *
4
+ * Unlike the fire-and-forget pattern used by `brv curate`, MCP tools need
5
+ * to wait for the task to finish and return the result to the coding agent.
6
+ *
7
+ * This function listens for:
8
+ * - llmservice:response: Captures the LLM's text response
9
+ * - task:completed: Task finished successfully
10
+ * - task:error: Task failed with an error
11
+ */
12
+ export async function waitForTaskResult(client, taskId, timeoutMs = 120_000) {
13
+ return new Promise((resolve, reject) => {
14
+ let result = '';
15
+ let completed = false;
16
+ const unsubscribers = [];
17
+ const cleanup = () => {
18
+ clearTimeout(timeout);
19
+ for (const unsub of unsubscribers) {
20
+ unsub();
21
+ }
22
+ };
23
+ const timeout = setTimeout(() => {
24
+ if (!completed) {
25
+ completed = true;
26
+ cleanup();
27
+ reject(new Error(`Task timeout after ${timeoutMs}ms`));
28
+ }
29
+ }, timeoutMs);
30
+ // Set up all event listeners
31
+ unsubscribers.push(
32
+ // Listen for LLM response content
33
+ client.on('llmservice:response', (payload) => {
34
+ if (payload.taskId === taskId && payload.content) {
35
+ result = payload.content;
36
+ }
37
+ }),
38
+ // Listen for task completion
39
+ client.on('task:completed', (payload) => {
40
+ if (payload.taskId === taskId && !completed) {
41
+ completed = true;
42
+ cleanup();
43
+ // Use the result from the event if available, otherwise use accumulated result
44
+ resolve(payload.result || result);
45
+ }
46
+ }),
47
+ // Listen for task error
48
+ client.on('task:error', (payload) => {
49
+ if (payload.taskId === taskId && !completed) {
50
+ completed = true;
51
+ cleanup();
52
+ reject(new Error(payload.error.message));
53
+ }
54
+ }));
55
+ });
56
+ }
@@ -9,8 +9,8 @@
9
9
  * - NO Socket.IO server (Transport is the only server)
10
10
  *
11
11
  * IPC messages:
12
- * - Receives: 'ping', 'shutdown'
13
- * - Sends: 'ready', 'pong', 'stopped', 'error'
12
+ * - Receives: 'ping', 'shutdown', 'health-check'
13
+ * - Sends: 'ready', 'pong', 'stopped', 'error', 'health-check-result'
14
14
  *
15
15
  * Socket.IO events (as client):
16
16
  * - Sends: 'agent:register' (identify as Agent)