@adhdev/daemon-core 0.9.82-rc.2 → 0.9.82-rc.21
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/boot/daemon-lifecycle.d.ts +2 -0
- package/dist/commands/router.d.ts +3 -0
- package/dist/git/git-commands.d.ts +1 -0
- package/dist/git/git-status.d.ts +5 -0
- package/dist/git/git-types.d.ts +10 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +389 -101
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +388 -101
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events.d.ts +3 -0
- package/dist/providers/chat-message-normalization.d.ts +1 -0
- package/dist/repo-mesh-types.d.ts +122 -0
- package/package.json +1 -1
- package/src/boot/daemon-lifecycle.ts +3 -0
- package/src/commands/router.ts +348 -88
- package/src/git/git-commands.ts +3 -3
- package/src/git/git-status.ts +97 -6
- package/src/git/git-summary.ts +3 -0
- package/src/git/git-types.ts +11 -0
- package/src/index.ts +9 -1
- package/src/mesh/mesh-events.ts +14 -3
- package/src/providers/chat-message-normalization.ts +3 -1
- package/src/repo-mesh-types.ts +132 -0
package/src/git/git-status.ts
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
|
-
import type { GitRepoStatus, GitSubmoduleStatus } from './git-types.js';
|
|
1
|
+
import type { GitRepoStatus, GitSubmoduleStatus, GitUpstreamFreshness } from './git-types.js';
|
|
2
2
|
import { GitCommandError, resolveGitRepository, runGit } from './git-executor.js';
|
|
3
3
|
|
|
4
|
+
type ResolvedGitRepo = { workspace: string; repoRoot: string | null; isGitRepo: boolean };
|
|
5
|
+
|
|
4
6
|
export interface GitStatusOptions {
|
|
5
7
|
timeoutMs?: number;
|
|
6
8
|
/** When true, include submodule status in the result. Defaults to true. */
|
|
7
9
|
includeSubmodules?: boolean;
|
|
8
10
|
/** Optional filter to exclude specific submodule paths from status */
|
|
9
11
|
submoduleIgnorePaths?: string[];
|
|
12
|
+
/**
|
|
13
|
+
* When true, refresh the tracked remote before trusting ahead/behind.
|
|
14
|
+
* Callers should opt into this only for convergence-critical surfaces.
|
|
15
|
+
*/
|
|
16
|
+
refreshUpstream?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface GitUpstreamProbe {
|
|
20
|
+
upstreamStatus: GitUpstreamFreshness;
|
|
21
|
+
upstreamFetchedAt?: number;
|
|
22
|
+
upstreamFetchError?: string;
|
|
10
23
|
}
|
|
11
24
|
|
|
12
25
|
export async function getGitRepoStatus(
|
|
@@ -18,8 +31,16 @@ export async function getGitRepoStatus(
|
|
|
18
31
|
|
|
19
32
|
try {
|
|
20
33
|
const repo = await resolveGitRepository(workspace, options);
|
|
21
|
-
|
|
22
|
-
|
|
34
|
+
let parsed = await readPorcelainStatus(repo, options);
|
|
35
|
+
let upstreamProbe: GitUpstreamProbe = getInitialUpstreamProbe(parsed);
|
|
36
|
+
|
|
37
|
+
if (options.refreshUpstream) {
|
|
38
|
+
upstreamProbe = await refreshTrackedUpstream(repo, parsed, options);
|
|
39
|
+
if (upstreamProbe.upstreamStatus === 'fresh') {
|
|
40
|
+
parsed = await readPorcelainStatus(repo, options);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
23
44
|
const head = await readHead(repo, options);
|
|
24
45
|
const stashCount = await readStashCount(repo, options);
|
|
25
46
|
|
|
@@ -36,6 +57,9 @@ export async function getGitRepoStatus(
|
|
|
36
57
|
headCommit: head.commit,
|
|
37
58
|
headMessage: head.message,
|
|
38
59
|
upstream: parsed.upstream,
|
|
60
|
+
upstreamStatus: parsed.upstream ? upstreamProbe.upstreamStatus : 'no_upstream',
|
|
61
|
+
upstreamFetchedAt: upstreamProbe.upstreamFetchedAt,
|
|
62
|
+
upstreamFetchError: upstreamProbe.upstreamFetchError,
|
|
39
63
|
ahead: parsed.ahead,
|
|
40
64
|
behind: parsed.behind,
|
|
41
65
|
staged: parsed.staged,
|
|
@@ -74,6 +98,72 @@ interface ParsedPorcelainStatus {
|
|
|
74
98
|
conflictFiles: string[];
|
|
75
99
|
}
|
|
76
100
|
|
|
101
|
+
async function readPorcelainStatus(repo: ResolvedGitRepo, options: GitStatusOptions): Promise<ParsedPorcelainStatus> {
|
|
102
|
+
const statusOutput = await runGit(repo, ['status', '--porcelain=v2', '--branch'], options);
|
|
103
|
+
return parsePorcelainV2Status(statusOutput.stdout);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function getInitialUpstreamProbe(parsed: ParsedPorcelainStatus): GitUpstreamProbe {
|
|
107
|
+
return {
|
|
108
|
+
upstreamStatus: parsed.upstream ? 'unchecked' : 'no_upstream',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function refreshTrackedUpstream(
|
|
113
|
+
repo: ResolvedGitRepo,
|
|
114
|
+
parsed: ParsedPorcelainStatus,
|
|
115
|
+
options: GitStatusOptions,
|
|
116
|
+
): Promise<GitUpstreamProbe> {
|
|
117
|
+
if (!parsed.upstream || !parsed.branch) {
|
|
118
|
+
return { upstreamStatus: 'no_upstream' };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const remoteName = (await readBranchRemote(repo, parsed.branch, options)) ?? inferRemoteName(parsed.upstream);
|
|
122
|
+
if (!remoteName) {
|
|
123
|
+
return {
|
|
124
|
+
upstreamStatus: 'stale',
|
|
125
|
+
upstreamFetchError: `Unable to resolve remote for upstream '${parsed.upstream}'`,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
await runGit(repo, ['fetch', '--quiet', '--prune', '--no-tags', remoteName], options);
|
|
131
|
+
return {
|
|
132
|
+
upstreamStatus: 'fresh',
|
|
133
|
+
upstreamFetchedAt: Date.now(),
|
|
134
|
+
};
|
|
135
|
+
} catch (error) {
|
|
136
|
+
return {
|
|
137
|
+
upstreamStatus: 'stale',
|
|
138
|
+
upstreamFetchError: formatGitError(error),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function readBranchRemote(repo: ResolvedGitRepo, branch: string, options: GitStatusOptions): Promise<string | null> {
|
|
144
|
+
try {
|
|
145
|
+
const result = await runGit(repo, ['config', '--get', `branch.${branch}.remote`], options);
|
|
146
|
+
return result.stdout.trim() || null;
|
|
147
|
+
} catch {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function inferRemoteName(upstream: string): string | null {
|
|
153
|
+
const [remoteName] = upstream.split('/');
|
|
154
|
+
return remoteName?.trim() || null;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function formatGitError(error: unknown): string {
|
|
158
|
+
if (error instanceof GitCommandError) {
|
|
159
|
+
return error.stderr || error.message;
|
|
160
|
+
}
|
|
161
|
+
if (error instanceof Error) {
|
|
162
|
+
return error.message;
|
|
163
|
+
}
|
|
164
|
+
return String(error);
|
|
165
|
+
}
|
|
166
|
+
|
|
77
167
|
export function parsePorcelainV2Status(output: string): ParsedPorcelainStatus {
|
|
78
168
|
const parsed: ParsedPorcelainStatus = {
|
|
79
169
|
branch: null,
|
|
@@ -145,7 +235,7 @@ export function parsePorcelainV2Status(output: string): ParsedPorcelainStatus {
|
|
|
145
235
|
}
|
|
146
236
|
|
|
147
237
|
async function readHead(
|
|
148
|
-
repo:
|
|
238
|
+
repo: ResolvedGitRepo,
|
|
149
239
|
options: GitStatusOptions,
|
|
150
240
|
): Promise<{ commit: string | null; message: string | null }> {
|
|
151
241
|
try {
|
|
@@ -163,7 +253,7 @@ async function readHead(
|
|
|
163
253
|
}
|
|
164
254
|
|
|
165
255
|
async function readStashCount(
|
|
166
|
-
repo:
|
|
256
|
+
repo: ResolvedGitRepo,
|
|
167
257
|
options: GitStatusOptions,
|
|
168
258
|
): Promise<number> {
|
|
169
259
|
try {
|
|
@@ -187,6 +277,7 @@ function emptyStatus(workspace: string, lastCheckedAt: number, error: GitCommand
|
|
|
187
277
|
headCommit: null,
|
|
188
278
|
headMessage: null,
|
|
189
279
|
upstream: null,
|
|
280
|
+
upstreamStatus: 'unavailable',
|
|
190
281
|
ahead: 0,
|
|
191
282
|
behind: 0,
|
|
192
283
|
staged: 0,
|
|
@@ -206,7 +297,7 @@ function emptyStatus(workspace: string, lastCheckedAt: number, error: GitCommand
|
|
|
206
297
|
// ─── Submodule Status ───────────────────────────
|
|
207
298
|
|
|
208
299
|
async function getSubmoduleStatuses(
|
|
209
|
-
repo:
|
|
300
|
+
repo: ResolvedGitRepo,
|
|
210
301
|
options: GitStatusOptions,
|
|
211
302
|
): Promise<GitSubmoduleStatus[]> {
|
|
212
303
|
if (!repo.repoRoot) return [];
|
package/src/git/git-summary.ts
CHANGED
|
@@ -22,6 +22,9 @@ export function createGitCompactSummary(status: GitRepoStatus, diffSummary?: Git
|
|
|
22
22
|
isGitRepo: status.isGitRepo,
|
|
23
23
|
repoRoot: status.repoRoot,
|
|
24
24
|
branch: status.branch,
|
|
25
|
+
upstreamStatus: status.upstreamStatus,
|
|
26
|
+
upstreamFetchedAt: status.upstreamFetchedAt,
|
|
27
|
+
upstreamFetchError: status.upstreamFetchError,
|
|
25
28
|
dirty:
|
|
26
29
|
status.staged > 0 ||
|
|
27
30
|
status.modified > 0 ||
|
package/src/git/git-types.ts
CHANGED
|
@@ -40,11 +40,19 @@ export interface GitSubmoduleStatus {
|
|
|
40
40
|
error?: string;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
export type GitUpstreamFreshness = 'fresh' | 'unchecked' | 'stale' | 'no_upstream' | 'unavailable';
|
|
44
|
+
|
|
43
45
|
export interface GitRepoStatus extends GitRepoIdentity {
|
|
44
46
|
branch: string | null;
|
|
45
47
|
headCommit: string | null;
|
|
46
48
|
headMessage: string | null;
|
|
47
49
|
upstream: string | null;
|
|
50
|
+
/** Whether ahead/behind was verified against a freshly fetched upstream ref. */
|
|
51
|
+
upstreamStatus: GitUpstreamFreshness;
|
|
52
|
+
/** Timestamp for the fetch that refreshed upstream refs when upstreamStatus === 'fresh'. */
|
|
53
|
+
upstreamFetchedAt?: number;
|
|
54
|
+
/** Error from the last refresh attempt when upstreamStatus === 'stale'. */
|
|
55
|
+
upstreamFetchError?: string;
|
|
48
56
|
ahead: number;
|
|
49
57
|
behind: number;
|
|
50
58
|
staged: number;
|
|
@@ -134,6 +142,9 @@ export interface GitCompactSummary {
|
|
|
134
142
|
isGitRepo: boolean;
|
|
135
143
|
repoRoot: string | null;
|
|
136
144
|
branch: string | null;
|
|
145
|
+
upstreamStatus: GitUpstreamFreshness;
|
|
146
|
+
upstreamFetchedAt?: number;
|
|
147
|
+
upstreamFetchError?: string;
|
|
137
148
|
dirty: boolean;
|
|
138
149
|
changedFiles: number;
|
|
139
150
|
ahead: number;
|
package/src/index.ts
CHANGED
|
@@ -103,6 +103,14 @@ export type {
|
|
|
103
103
|
LocalMeshNodeEntry,
|
|
104
104
|
RepoMeshStatus,
|
|
105
105
|
RepoMeshNodeStatus,
|
|
106
|
+
RepoMeshSessionStatus,
|
|
107
|
+
RepoMeshQueueTask,
|
|
108
|
+
RepoMeshQueueTaskStatus,
|
|
109
|
+
RepoMeshQueueSummary,
|
|
110
|
+
RepoMeshQueueStatus,
|
|
111
|
+
RepoMeshLedgerEntryStatus,
|
|
112
|
+
RepoMeshLedgerSummaryStatus,
|
|
113
|
+
RepoMeshLedgerStatus,
|
|
106
114
|
} from './repo-mesh-types.js';
|
|
107
115
|
export { DEFAULT_MESH_POLICY } from './repo-mesh-types.js';
|
|
108
116
|
|
|
@@ -168,7 +176,7 @@ export type { MeshWorkQueueEntry, MeshTaskStatus, MeshWorkQueueStats } from './m
|
|
|
168
176
|
// export type { MeshGraph, MeshGraphNode, MeshGraphEdge, MeshGraphNodeType, MeshGraphEdgeType } from './mesh/mesh-visualization.js';
|
|
169
177
|
|
|
170
178
|
// ── Mesh Events ──
|
|
171
|
-
export { triggerMeshQueue, drainPendingMeshCoordinatorEvents, getPendingMeshCoordinatorEvents, clearPendingMeshCoordinatorEvents } from './mesh/mesh-events.js';
|
|
179
|
+
export { triggerMeshQueue, drainPendingMeshCoordinatorEvents, getPendingMeshCoordinatorEvents, clearPendingMeshCoordinatorEvents, queuePendingMeshCoordinatorEvent } from './mesh/mesh-events.js';
|
|
172
180
|
export type { PendingMeshCoordinatorEvent } from './mesh/mesh-events.js';
|
|
173
181
|
|
|
174
182
|
// ── Mesh P2P Relay Failure Classification ──
|
package/src/mesh/mesh-events.ts
CHANGED
|
@@ -32,6 +32,8 @@ export interface PendingMeshCoordinatorEvent {
|
|
|
32
32
|
event: string;
|
|
33
33
|
meshId: string;
|
|
34
34
|
nodeLabel: string;
|
|
35
|
+
nodeId?: string;
|
|
36
|
+
workspace?: string;
|
|
35
37
|
metadataEvent: Record<string, unknown>;
|
|
36
38
|
queuedAt: number;
|
|
37
39
|
}
|
|
@@ -39,6 +41,14 @@ export interface PendingMeshCoordinatorEvent {
|
|
|
39
41
|
const MAX_PENDING_EVENTS = 50;
|
|
40
42
|
const pendingMeshCoordinatorEvents: PendingMeshCoordinatorEvent[] = [];
|
|
41
43
|
|
|
44
|
+
export function queuePendingMeshCoordinatorEvent(event: PendingMeshCoordinatorEvent): boolean {
|
|
45
|
+
if (pendingMeshCoordinatorEvents.length >= MAX_PENDING_EVENTS) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
pendingMeshCoordinatorEvents.push(event);
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
42
52
|
/** Drain and return all pending coordinator events, clearing the queue. */
|
|
43
53
|
export function drainPendingMeshCoordinatorEvents(): PendingMeshCoordinatorEvent[] {
|
|
44
54
|
return pendingMeshCoordinatorEvents.splice(0);
|
|
@@ -781,17 +791,18 @@ function injectMeshSystemMessage(components: DaemonComponents, args: {
|
|
|
781
791
|
|
|
782
792
|
if (coordinatorInstances.length === 0) {
|
|
783
793
|
// No CLI coordinator session found — buffer for MCP-based coordinators.
|
|
784
|
-
if (
|
|
785
|
-
pendingMeshCoordinatorEvents.push({
|
|
794
|
+
if (queuePendingMeshCoordinatorEvent({
|
|
786
795
|
event: args.event,
|
|
787
796
|
meshId: args.meshId,
|
|
788
797
|
nodeLabel: args.nodeLabel,
|
|
798
|
+
nodeId: args.nodeId || undefined,
|
|
799
|
+
workspace: readNonEmptyString(args.metadataEvent.workspace),
|
|
789
800
|
metadataEvent: {
|
|
790
801
|
...args.metadataEvent,
|
|
791
802
|
...(recoveryContext ? { recoveryContext } : {}),
|
|
792
803
|
},
|
|
793
804
|
queuedAt: Date.now(),
|
|
794
|
-
})
|
|
805
|
+
})) {
|
|
795
806
|
LOG.info('MeshEvents', `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
|
|
796
807
|
}
|
|
797
808
|
return { success: true, forwarded: 0 };
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { ChatMessage } from '../types.js';
|
|
2
2
|
import { flattenContent } from './contracts.js';
|
|
3
3
|
|
|
4
|
+
export const DEFAULT_FINAL_SUMMARY_MAX_CHARS = 4_000;
|
|
5
|
+
|
|
4
6
|
export function extractFinalSummaryFromMessages(
|
|
5
7
|
messages: ChatMessage[] | null | undefined,
|
|
6
|
-
maxChars: number =
|
|
8
|
+
maxChars: number = DEFAULT_FINAL_SUMMARY_MAX_CHARS,
|
|
7
9
|
): string {
|
|
8
10
|
if (!Array.isArray(messages) || messages.length === 0) return '';
|
|
9
11
|
|
package/src/repo-mesh-types.ts
CHANGED
|
@@ -259,17 +259,149 @@ export interface RepoMeshStatus {
|
|
|
259
259
|
meshId: string;
|
|
260
260
|
meshName: string;
|
|
261
261
|
repoIdentity: string;
|
|
262
|
+
defaultBranch?: string;
|
|
262
263
|
refreshedAt: string;
|
|
263
264
|
nodes: RepoMeshNodeStatus[];
|
|
265
|
+
queue?: RepoMeshQueueStatus;
|
|
266
|
+
ledger?: RepoMeshLedgerStatus;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export interface RepoMeshSessionStatus {
|
|
270
|
+
sessionId: string;
|
|
271
|
+
providerType?: string;
|
|
272
|
+
state?: string;
|
|
273
|
+
lifecycle?: 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'interrupted';
|
|
274
|
+
surfaceKind?: 'live_runtime' | 'recovery_snapshot' | 'inactive_record';
|
|
275
|
+
recoveryState?: string | null;
|
|
276
|
+
workspace?: string | null;
|
|
277
|
+
title?: string | null;
|
|
278
|
+
lastActivityAt?: string | null;
|
|
279
|
+
isCached?: boolean;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export type RepoMeshPeerConnectionState = 'self' | 'connected' | 'connecting' | 'disconnected' | 'failed' | 'closed' | 'unknown';
|
|
283
|
+
export type RepoMeshPeerConnectionTransport = 'local' | 'direct' | 'relay' | 'unknown';
|
|
284
|
+
|
|
285
|
+
export interface RepoMeshPeerConnectionStatus {
|
|
286
|
+
perspective: 'selected_coordinator';
|
|
287
|
+
source: 'mesh_peer_status' | 'not_reported';
|
|
288
|
+
state: RepoMeshPeerConnectionState;
|
|
289
|
+
transport: RepoMeshPeerConnectionTransport;
|
|
290
|
+
reported: boolean;
|
|
291
|
+
reason?: string;
|
|
292
|
+
lastStateChangeAt?: string;
|
|
293
|
+
lastConnectedAt?: string;
|
|
294
|
+
lastCommandAt?: string;
|
|
264
295
|
}
|
|
265
296
|
|
|
266
297
|
export interface RepoMeshNodeStatus {
|
|
267
298
|
nodeId: string;
|
|
268
299
|
machineLabel: string;
|
|
269
300
|
workspace: string;
|
|
301
|
+
repoRoot?: string;
|
|
302
|
+
daemonId?: string;
|
|
303
|
+
machineId?: string;
|
|
304
|
+
machineStatus?: string;
|
|
305
|
+
isLocalWorktree?: boolean;
|
|
306
|
+
worktreeBranch?: string;
|
|
270
307
|
health: RepoMeshNodeHealth;
|
|
271
308
|
git?: GitRepoStatus;
|
|
272
309
|
providers: string[];
|
|
273
310
|
activeSessions: string[];
|
|
311
|
+
activeSessionDetails?: RepoMeshSessionStatus[];
|
|
312
|
+
providerPriority?: string[];
|
|
313
|
+
launchReady?: boolean;
|
|
314
|
+
lastSeenAt?: string;
|
|
315
|
+
updatedAt?: string;
|
|
316
|
+
connection?: RepoMeshPeerConnectionStatus;
|
|
274
317
|
error?: string;
|
|
275
318
|
}
|
|
319
|
+
|
|
320
|
+
export type RepoMeshQueueTaskStatus = 'pending' | 'assigned' | 'completed' | 'failed' | 'cancelled';
|
|
321
|
+
|
|
322
|
+
export interface RepoMeshQueueTask {
|
|
323
|
+
id: string;
|
|
324
|
+
meshId: string;
|
|
325
|
+
message: string;
|
|
326
|
+
status: RepoMeshQueueTaskStatus;
|
|
327
|
+
targetNodeId?: string;
|
|
328
|
+
targetSessionId?: string;
|
|
329
|
+
assignedNodeId?: string;
|
|
330
|
+
assignedSessionId?: string;
|
|
331
|
+
cancelReason?: string;
|
|
332
|
+
cancelledAt?: string;
|
|
333
|
+
requeueReason?: string;
|
|
334
|
+
requeuedAt?: string;
|
|
335
|
+
requeueCount?: number;
|
|
336
|
+
autoLaunch?: {
|
|
337
|
+
status: 'skipped' | 'started' | 'failed' | 'completed';
|
|
338
|
+
reason?: string;
|
|
339
|
+
nodeId?: string;
|
|
340
|
+
providerType?: string;
|
|
341
|
+
sessionId?: string;
|
|
342
|
+
updatedAt: string;
|
|
343
|
+
};
|
|
344
|
+
dispatchTimestamp?: string;
|
|
345
|
+
createdAt: string;
|
|
346
|
+
updatedAt: string;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export interface RepoMeshQueueSummary {
|
|
350
|
+
total: number;
|
|
351
|
+
active: number;
|
|
352
|
+
historical: number;
|
|
353
|
+
pending: number;
|
|
354
|
+
assigned: number;
|
|
355
|
+
completed: number;
|
|
356
|
+
failed: number;
|
|
357
|
+
cancelled: number;
|
|
358
|
+
activeCounts: {
|
|
359
|
+
pending: number;
|
|
360
|
+
assigned: number;
|
|
361
|
+
};
|
|
362
|
+
historicalCounts: {
|
|
363
|
+
completed: number;
|
|
364
|
+
failed: number;
|
|
365
|
+
cancelled: number;
|
|
366
|
+
};
|
|
367
|
+
activeAssignments: Array<{
|
|
368
|
+
id: string;
|
|
369
|
+
nodeId?: string;
|
|
370
|
+
sessionId?: string;
|
|
371
|
+
message: string;
|
|
372
|
+
}>;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export interface RepoMeshQueueStatus {
|
|
376
|
+
tasks: RepoMeshQueueTask[];
|
|
377
|
+
summary: RepoMeshQueueSummary;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export interface RepoMeshLedgerEntryStatus {
|
|
381
|
+
id: string;
|
|
382
|
+
meshId: string;
|
|
383
|
+
timestamp: string;
|
|
384
|
+
kind: string;
|
|
385
|
+
nodeId?: string;
|
|
386
|
+
sessionId?: string;
|
|
387
|
+
providerType?: string;
|
|
388
|
+
payload: Record<string, unknown>;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
export interface RepoMeshLedgerSummaryStatus {
|
|
392
|
+
meshId: string;
|
|
393
|
+
totalEntries: number;
|
|
394
|
+
taskDispatched: number;
|
|
395
|
+
taskCompleted: number;
|
|
396
|
+
taskFailed: number;
|
|
397
|
+
taskStalled: number;
|
|
398
|
+
sessionLaunched: number;
|
|
399
|
+
checkpointCreated: number;
|
|
400
|
+
lastActivityAt: string | null;
|
|
401
|
+
recentFailures: number;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export interface RepoMeshLedgerStatus {
|
|
405
|
+
entries: RepoMeshLedgerEntryStatus[];
|
|
406
|
+
summary: RepoMeshLedgerSummaryStatus;
|
|
407
|
+
}
|