byterover-cli 3.11.0 → 3.12.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.
- package/dist/agent/infra/tools/implementations/curate-tool.js +18 -8
- package/dist/server/constants.d.ts +6 -0
- package/dist/server/constants.js +11 -0
- package/dist/server/core/domain/entities/task-history-entry.d.ts +775 -0
- package/dist/server/core/domain/entities/task-history-entry.js +88 -0
- package/dist/server/core/domain/transport/schemas.d.ts +1403 -11
- package/dist/server/core/domain/transport/schemas.js +157 -6
- package/dist/server/core/domain/transport/task-info.d.ts +18 -0
- package/dist/server/core/interfaces/process/i-task-lifecycle-hook.d.ts +7 -0
- package/dist/server/core/interfaces/storage/i-task-history-store.d.ts +62 -0
- package/dist/server/core/interfaces/storage/i-task-history-store.js +1 -0
- package/dist/server/infra/daemon/brv-server.js +43 -18
- package/dist/server/infra/dream/dream-response-schemas.d.ts +24 -0
- package/dist/server/infra/dream/dream-response-schemas.js +7 -0
- package/dist/server/infra/dream/operations/consolidate.js +21 -8
- package/dist/server/infra/dream/operations/synthesize.js +35 -8
- package/dist/server/infra/process/task-history-entry-builder.d.ts +36 -0
- package/dist/server/infra/process/task-history-entry-builder.js +101 -0
- package/dist/server/infra/process/task-history-hook.d.ts +37 -0
- package/dist/server/infra/process/task-history-hook.js +70 -0
- package/dist/server/infra/process/task-history-store-cache.d.ts +25 -0
- package/dist/server/infra/process/task-history-store-cache.js +106 -0
- package/dist/server/infra/process/task-router.d.ts +72 -0
- package/dist/server/infra/process/task-router.js +690 -15
- package/dist/server/infra/process/transport-handlers.d.ts +8 -0
- package/dist/server/infra/process/transport-handlers.js +2 -0
- package/dist/server/infra/storage/file-task-history-store.d.ts +294 -0
- package/dist/server/infra/storage/file-task-history-store.js +912 -0
- package/dist/shared/transport/events/index.d.ts +5 -0
- package/dist/shared/transport/events/task-events.d.ts +204 -1
- package/dist/shared/transport/events/task-events.js +11 -0
- package/dist/tui/features/tasks/hooks/use-task-subscriptions.js +7 -0
- package/dist/tui/features/tasks/stores/tasks-store.d.ts +4 -16
- package/dist/tui/features/tasks/stores/tasks-store.js +7 -0
- package/dist/tui/types/messages.d.ts +2 -9
- package/dist/webui/assets/index-DyVvFoM6.css +1 -0
- package/dist/webui/assets/index-lr0byHh9.js +130 -0
- package/dist/webui/index.html +2 -2
- package/dist/webui/sw.js +1 -1
- package/oclif.manifest.json +665 -665
- package/package.json +1 -1
- package/dist/webui/assets/index--sXE__bc.css +0 -1
- package/dist/webui/assets/index-Bkkx961b.js +0 -130
|
@@ -146,10 +146,15 @@ export declare const AllEventGroups: readonly [{
|
|
|
146
146
|
readonly ACK: "task:ack";
|
|
147
147
|
readonly CANCEL: "task:cancel";
|
|
148
148
|
readonly CANCELLED: "task:cancelled";
|
|
149
|
+
readonly CLEAR_COMPLETED: "task:clearCompleted";
|
|
149
150
|
readonly COMPLETED: "task:completed";
|
|
150
151
|
readonly CREATE: "task:create";
|
|
151
152
|
readonly CREATED: "task:created";
|
|
153
|
+
readonly DELETE: "task:delete";
|
|
154
|
+
readonly DELETE_BULK: "task:deleteBulk";
|
|
155
|
+
readonly DELETED: "task:deleted";
|
|
152
156
|
readonly ERROR: "task:error";
|
|
157
|
+
readonly GET: "task:get";
|
|
153
158
|
readonly LIST: "task:list";
|
|
154
159
|
readonly STARTED: "task:started";
|
|
155
160
|
}, {
|
|
@@ -1,11 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persisted-entry schema version. Bumped only on shape-breaking changes to
|
|
3
|
+
* `TaskHistoryEntry`. The Zod schema in `server/core/domain/entities/` uses
|
|
4
|
+
* `z.literal(TASK_HISTORY_SCHEMA_VERSION)` to refuse mismatched on-disk lines.
|
|
5
|
+
*/
|
|
6
|
+
export declare const TASK_HISTORY_SCHEMA_VERSION = 1;
|
|
1
7
|
export declare const TaskEvents: {
|
|
2
8
|
readonly ACK: "task:ack";
|
|
3
9
|
readonly CANCEL: "task:cancel";
|
|
4
10
|
readonly CANCELLED: "task:cancelled";
|
|
11
|
+
readonly CLEAR_COMPLETED: "task:clearCompleted";
|
|
5
12
|
readonly COMPLETED: "task:completed";
|
|
6
13
|
readonly CREATE: "task:create";
|
|
7
14
|
readonly CREATED: "task:created";
|
|
15
|
+
readonly DELETE: "task:delete";
|
|
16
|
+
readonly DELETE_BULK: "task:deleteBulk";
|
|
17
|
+
readonly DELETED: "task:deleted";
|
|
8
18
|
readonly ERROR: "task:error";
|
|
19
|
+
readonly GET: "task:get";
|
|
9
20
|
readonly LIST: "task:list";
|
|
10
21
|
readonly STARTED: "task:started";
|
|
11
22
|
};
|
|
@@ -30,6 +41,33 @@ export interface TaskCancelResponse {
|
|
|
30
41
|
success: boolean;
|
|
31
42
|
}
|
|
32
43
|
export type TaskListItemStatus = 'cancelled' | 'completed' | 'created' | 'error' | 'started';
|
|
44
|
+
/**
|
|
45
|
+
* Reasoning/thinking content item with timestamp for ordering.
|
|
46
|
+
* Shared between webui, tui, and the server-side TaskHistoryEntry.
|
|
47
|
+
*/
|
|
48
|
+
export type ReasoningContentItem = {
|
|
49
|
+
content: string;
|
|
50
|
+
/** Whether this reasoning item is still being streamed */
|
|
51
|
+
isThinking?: boolean;
|
|
52
|
+
timestamp: number;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Persisted tool-call lifecycle entry — distinct from the wire-payload
|
|
56
|
+
* `LlmToolCallEventSchema` in `core/domain/transport/schemas.ts`. This shape
|
|
57
|
+
* carries the `running | completed | error` state machine and is the form
|
|
58
|
+
* stored in `TaskHistoryEntry.toolCalls`.
|
|
59
|
+
*/
|
|
60
|
+
export type ToolCallEvent = {
|
|
61
|
+
args: Record<string, unknown>;
|
|
62
|
+
callId?: string;
|
|
63
|
+
error?: string;
|
|
64
|
+
errorType?: string;
|
|
65
|
+
result?: unknown;
|
|
66
|
+
sessionId: string;
|
|
67
|
+
status: 'completed' | 'error' | 'running';
|
|
68
|
+
timestamp: number;
|
|
69
|
+
toolName: string;
|
|
70
|
+
};
|
|
33
71
|
export interface TaskListItem {
|
|
34
72
|
completedAt?: number;
|
|
35
73
|
content: string;
|
|
@@ -37,22 +75,187 @@ export interface TaskListItem {
|
|
|
37
75
|
error?: {
|
|
38
76
|
code?: string;
|
|
39
77
|
message: string;
|
|
40
|
-
name
|
|
78
|
+
name: string;
|
|
41
79
|
};
|
|
42
80
|
/** Optional file paths from `curate --files` */
|
|
43
81
|
files?: string[];
|
|
44
82
|
/** Folder path for `curate-folder` tasks */
|
|
45
83
|
folderPath?: string;
|
|
84
|
+
/** Active model id at task creation time */
|
|
85
|
+
model?: string;
|
|
46
86
|
projectPath?: string;
|
|
87
|
+
/** Active provider id at task creation time */
|
|
88
|
+
provider?: string;
|
|
47
89
|
result?: string;
|
|
48
90
|
startedAt?: number;
|
|
49
91
|
status: TaskListItemStatus;
|
|
50
92
|
taskId: string;
|
|
51
93
|
type: string;
|
|
52
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* task:list request — numbered pagination + filter/search (M2.16).
|
|
97
|
+
* All filter dims are optional; AND-combined when multiple are set.
|
|
98
|
+
*/
|
|
53
99
|
export interface TaskListRequest {
|
|
100
|
+
/** createdAt >= this epoch ms */
|
|
101
|
+
createdAfter?: number;
|
|
102
|
+
/** createdAt <= this epoch ms */
|
|
103
|
+
createdBefore?: number;
|
|
104
|
+
/** Maximum elapsed time (ms) for terminal tasks. */
|
|
105
|
+
maxDurationMs?: number;
|
|
106
|
+
/** Minimum elapsed time (ms); only matches startedAt+completedAt rows. */
|
|
107
|
+
minDurationMs?: number;
|
|
108
|
+
/** Filter to these model ids (exact match). */
|
|
109
|
+
model?: string[];
|
|
110
|
+
/** 1-based page index; defaults to 1. */
|
|
111
|
+
page?: number;
|
|
112
|
+
/** Page size 1..1000; defaults to 50. */
|
|
113
|
+
pageSize?: number;
|
|
54
114
|
projectPath?: string;
|
|
115
|
+
/** Filter to these provider ids (exact match). */
|
|
116
|
+
provider?: string[];
|
|
117
|
+
/** Case-insensitive substring on content + result + error.message. */
|
|
118
|
+
searchText?: string;
|
|
119
|
+
status?: TaskListItemStatus[];
|
|
120
|
+
type?: string[];
|
|
121
|
+
}
|
|
122
|
+
/** Status histogram used by FE filter-bar breakdown (M2.16). */
|
|
123
|
+
export interface TaskListCounts {
|
|
124
|
+
all: number;
|
|
125
|
+
cancelled: number;
|
|
126
|
+
completed: number;
|
|
127
|
+
/** Tasks with status === 'error'. */
|
|
128
|
+
failed: number;
|
|
129
|
+
/** Tasks with status === 'created' || 'started'. */
|
|
130
|
+
running: number;
|
|
131
|
+
}
|
|
132
|
+
/** (providerId, modelId) pair from history (M2.16). */
|
|
133
|
+
export interface TaskListAvailableModel {
|
|
134
|
+
modelId: string;
|
|
135
|
+
providerId: string;
|
|
55
136
|
}
|
|
56
137
|
export interface TaskListResponse {
|
|
138
|
+
/** Distinct (providerId, modelId) pairs seen in candidate set. */
|
|
139
|
+
availableModels: TaskListAvailableModel[];
|
|
140
|
+
/** Distinct providerId values seen in candidate set. */
|
|
141
|
+
availableProviders: string[];
|
|
142
|
+
/**
|
|
143
|
+
* Status histogram matching current filter scope (Model A — post-filter).
|
|
144
|
+
* `counts.all === total` invariant. When user picks `status: ['error']`,
|
|
145
|
+
* `counts.failed === total` and other buckets are 0.
|
|
146
|
+
*/
|
|
147
|
+
counts: TaskListCounts;
|
|
148
|
+
/**
|
|
149
|
+
* 1-based page index, echoed back as-sent. Server clamps the LOWER bound
|
|
150
|
+
* (page < 1 → 1) but does NOT clamp against `pageCount`. A request with
|
|
151
|
+
* `page=9999` against a 1-page result returns `page: 9999, tasks: []` so
|
|
152
|
+
* the caller can detect an out-of-range page.
|
|
153
|
+
*/
|
|
154
|
+
page: number;
|
|
155
|
+
/** ceil(total / pageSize), min 1. */
|
|
156
|
+
pageCount: number;
|
|
157
|
+
/** Page size echoed back, clamped to [1, 1000]. */
|
|
158
|
+
pageSize: number;
|
|
57
159
|
tasks: TaskListItem[];
|
|
160
|
+
/** Total items matching ALL filters (incl. status). */
|
|
161
|
+
total: number;
|
|
58
162
|
}
|
|
163
|
+
export type TaskClearCompletedRequest = {
|
|
164
|
+
projectPath?: string;
|
|
165
|
+
};
|
|
166
|
+
export type TaskClearCompletedResponse = {
|
|
167
|
+
deletedCount: number;
|
|
168
|
+
error?: string;
|
|
169
|
+
};
|
|
170
|
+
export type TaskDeleteBulkRequest = {
|
|
171
|
+
taskIds: string[];
|
|
172
|
+
};
|
|
173
|
+
export type TaskDeleteBulkResponse = {
|
|
174
|
+
deletedCount: number;
|
|
175
|
+
error?: string;
|
|
176
|
+
};
|
|
177
|
+
export type TaskDeleteRequest = {
|
|
178
|
+
taskId: string;
|
|
179
|
+
};
|
|
180
|
+
export type TaskDeleteResponse = {
|
|
181
|
+
error?: string;
|
|
182
|
+
/**
|
|
183
|
+
* `true` when the task was actually removed (was live or persisted),
|
|
184
|
+
* `false` when the call was a no-op (taskId unknown or already tombstoned).
|
|
185
|
+
* `task:deleteBulk` uses this to compute an accurate `deletedCount`.
|
|
186
|
+
*/
|
|
187
|
+
removed?: boolean;
|
|
188
|
+
success: boolean;
|
|
189
|
+
};
|
|
190
|
+
export type TaskDeletedEvent = {
|
|
191
|
+
taskId: string;
|
|
192
|
+
};
|
|
193
|
+
export type TaskGetRequest = {
|
|
194
|
+
taskId: string;
|
|
195
|
+
};
|
|
196
|
+
export type TaskGetResponse = {
|
|
197
|
+
task: null | TaskHistoryEntry;
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Full per-task error payload — superset of `TaskListItem.error`, adds the
|
|
201
|
+
* optional `details` bag. Mirrors `TaskErrorDataSchema` in
|
|
202
|
+
* `src/server/core/domain/entities/task-history-entry.ts`; the server schema
|
|
203
|
+
* carries `satisfies z.ZodType<TaskErrorData>` to keep them aligned.
|
|
204
|
+
*/
|
|
205
|
+
export type TaskErrorData = {
|
|
206
|
+
code?: string;
|
|
207
|
+
details?: Record<string, unknown>;
|
|
208
|
+
message: string;
|
|
209
|
+
name: string;
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* Discriminated-union shape for a persisted task. The server-side Zod schema
|
|
213
|
+
* (`TaskHistoryEntrySchema`) is the runtime source of truth and carries
|
|
214
|
+
* `satisfies z.ZodType<TaskHistoryEntry>` so any drift between the two
|
|
215
|
+
* representations is a typecheck error.
|
|
216
|
+
*
|
|
217
|
+
* Lives in `shared/` so webui + tui can consume it without inverting the
|
|
218
|
+
* dependency direction onto `server/`.
|
|
219
|
+
*/
|
|
220
|
+
type TaskHistoryEntryBase = {
|
|
221
|
+
clientCwd?: string;
|
|
222
|
+
content: string;
|
|
223
|
+
createdAt: number;
|
|
224
|
+
files?: string[];
|
|
225
|
+
folderPath?: string;
|
|
226
|
+
id: string;
|
|
227
|
+
logId?: string;
|
|
228
|
+
model?: string;
|
|
229
|
+
projectPath: string;
|
|
230
|
+
provider?: string;
|
|
231
|
+
reasoningContents?: ReasoningContentItem[];
|
|
232
|
+
responseContent?: string;
|
|
233
|
+
schemaVersion: typeof TASK_HISTORY_SCHEMA_VERSION;
|
|
234
|
+
sessionId?: string;
|
|
235
|
+
taskId: string;
|
|
236
|
+
toolCalls?: ToolCallEvent[];
|
|
237
|
+
type: string;
|
|
238
|
+
worktreeRoot?: string;
|
|
239
|
+
};
|
|
240
|
+
export type TaskHistoryEntry = (TaskHistoryEntryBase & {
|
|
241
|
+
completedAt: number;
|
|
242
|
+
error: TaskErrorData;
|
|
243
|
+
startedAt?: number;
|
|
244
|
+
status: 'error';
|
|
245
|
+
}) | (TaskHistoryEntryBase & {
|
|
246
|
+
completedAt: number;
|
|
247
|
+
result?: string;
|
|
248
|
+
startedAt?: number;
|
|
249
|
+
status: 'completed';
|
|
250
|
+
}) | (TaskHistoryEntryBase & {
|
|
251
|
+
completedAt: number;
|
|
252
|
+
startedAt?: number;
|
|
253
|
+
status: 'cancelled';
|
|
254
|
+
}) | (TaskHistoryEntryBase & {
|
|
255
|
+
startedAt: number;
|
|
256
|
+
status: 'started';
|
|
257
|
+
}) | (TaskHistoryEntryBase & {
|
|
258
|
+
status: 'created';
|
|
259
|
+
});
|
|
260
|
+
export type TaskHistoryStatus = TaskHistoryEntry['status'];
|
|
261
|
+
export {};
|
|
@@ -1,11 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persisted-entry schema version. Bumped only on shape-breaking changes to
|
|
3
|
+
* `TaskHistoryEntry`. The Zod schema in `server/core/domain/entities/` uses
|
|
4
|
+
* `z.literal(TASK_HISTORY_SCHEMA_VERSION)` to refuse mismatched on-disk lines.
|
|
5
|
+
*/
|
|
6
|
+
export const TASK_HISTORY_SCHEMA_VERSION = 1;
|
|
1
7
|
export const TaskEvents = {
|
|
2
8
|
ACK: 'task:ack',
|
|
3
9
|
CANCEL: 'task:cancel',
|
|
4
10
|
CANCELLED: 'task:cancelled',
|
|
11
|
+
CLEAR_COMPLETED: 'task:clearCompleted',
|
|
5
12
|
COMPLETED: 'task:completed',
|
|
6
13
|
CREATE: 'task:create',
|
|
7
14
|
CREATED: 'task:created',
|
|
15
|
+
DELETE: 'task:delete',
|
|
16
|
+
DELETE_BULK: 'task:deleteBulk',
|
|
17
|
+
DELETED: 'task:deleted',
|
|
8
18
|
ERROR: 'task:error',
|
|
19
|
+
GET: 'task:get',
|
|
9
20
|
LIST: 'task:list',
|
|
10
21
|
STARTED: 'task:started',
|
|
11
22
|
};
|
|
@@ -23,6 +23,13 @@ export function useTaskSubscriptions() {
|
|
|
23
23
|
store.setError(data.taskId, data.error);
|
|
24
24
|
}), client.on('task:cancelled', (data) => {
|
|
25
25
|
store.setCancelled(data.taskId);
|
|
26
|
+
}),
|
|
27
|
+
// task:deleted is broadcast by the daemon when ANY client (this TUI, the
|
|
28
|
+
// WebUI, or another tab) removes a task via task:delete /
|
|
29
|
+
// task:deleteBulk / task:clearCompleted. Drop the row locally so all
|
|
30
|
+
// surfaces stay in sync without polling.
|
|
31
|
+
client.on('task:deleted', (data) => {
|
|
32
|
+
store.removeTask(data.taskId);
|
|
26
33
|
}), client.on('llmservice:toolCall', (data) => {
|
|
27
34
|
if (!data.taskId)
|
|
28
35
|
return;
|
|
@@ -4,24 +4,10 @@
|
|
|
4
4
|
* Zustand store for task lifecycle state.
|
|
5
5
|
* Subscribes to task:* and llmservice:* transport events.
|
|
6
6
|
*/
|
|
7
|
+
import type { ReasoningContentItem, ToolCallEvent } from '../../../../shared/transport/events/task-events.js';
|
|
7
8
|
import type { TaskStats } from '../../../types/ui.js';
|
|
8
9
|
export type TaskStatus = 'cancelled' | 'completed' | 'created' | 'error' | 'started';
|
|
9
|
-
export
|
|
10
|
-
args: Record<string, unknown>;
|
|
11
|
-
callId?: string;
|
|
12
|
-
error?: string;
|
|
13
|
-
errorType?: string;
|
|
14
|
-
result?: unknown;
|
|
15
|
-
sessionId: string;
|
|
16
|
-
status: 'completed' | 'error' | 'running';
|
|
17
|
-
timestamp: number;
|
|
18
|
-
toolName: string;
|
|
19
|
-
}
|
|
20
|
-
export interface ReasoningContentItem {
|
|
21
|
-
content: string;
|
|
22
|
-
isThinking?: boolean;
|
|
23
|
-
timestamp: number;
|
|
24
|
-
}
|
|
10
|
+
export type { ReasoningContentItem, ToolCallEvent } from '../../../../shared/transport/events/task-events.js';
|
|
25
11
|
export interface TaskErrorData {
|
|
26
12
|
code?: string;
|
|
27
13
|
message: string;
|
|
@@ -76,6 +62,8 @@ export interface TasksActions {
|
|
|
76
62
|
createTask: (taskId: string, type: 'curate' | 'query', content: string, files?: string[]) => void;
|
|
77
63
|
/** Get a task by ID */
|
|
78
64
|
getTask: (taskId: string) => Task | undefined;
|
|
65
|
+
/** Remove a task from local state (driven by `task:deleted` broadcast). */
|
|
66
|
+
removeTask: (taskId: string) => void;
|
|
79
67
|
/** Set task to cancelled */
|
|
80
68
|
setCancelled: (taskId: string) => void;
|
|
81
69
|
/** Set task to completed with result */
|
|
@@ -127,6 +127,13 @@ export const useTasksStore = create()((set, get) => ({
|
|
|
127
127
|
return { stats: computeStats(tasks), tasks };
|
|
128
128
|
}),
|
|
129
129
|
getTask: (taskId) => get().tasks.get(taskId),
|
|
130
|
+
removeTask: (taskId) => set((state) => {
|
|
131
|
+
if (!state.tasks.has(taskId))
|
|
132
|
+
return state;
|
|
133
|
+
const tasks = new Map(state.tasks);
|
|
134
|
+
tasks.delete(taskId);
|
|
135
|
+
return { stats: computeStats(tasks), tasks };
|
|
136
|
+
}),
|
|
130
137
|
setCancelled: (taskId) => set((state) => {
|
|
131
138
|
const task = state.tasks.get(taskId);
|
|
132
139
|
if (!task) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Message and activity log types
|
|
3
3
|
*/
|
|
4
|
+
import type { ReasoningContentItem } from '../../shared/transport/events/task-events.js';
|
|
4
5
|
/**
|
|
5
6
|
* Status of an execution (curate/query job)
|
|
6
7
|
*/
|
|
@@ -54,15 +55,7 @@ export interface ToolProgressItem {
|
|
|
54
55
|
/** Tool name */
|
|
55
56
|
toolCallName: string;
|
|
56
57
|
}
|
|
57
|
-
|
|
58
|
-
* Reasoning content item with timestamp for sorting
|
|
59
|
-
*/
|
|
60
|
-
export interface ReasoningContentItem {
|
|
61
|
-
content: string;
|
|
62
|
-
/** Whether this reasoning item is still being streamed */
|
|
63
|
-
isThinking?: boolean;
|
|
64
|
-
timestamp: number;
|
|
65
|
-
}
|
|
58
|
+
export type { ReasoningContentItem } from '../../shared/transport/events/task-events.js';
|
|
66
59
|
/**
|
|
67
60
|
* Activity log item for displaying in logs view
|
|
68
61
|
*/
|