@mattstack/rt-client 0.10.1 → 0.11.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.
@@ -4,7 +4,7 @@
4
4
  * its functions against this map so a new command only needs an entry here
5
5
  * plus one function, never a change to the transport itself.
6
6
  */
7
- import type { PullRequest, MRDetail } from "@mattstack/glance";
7
+ import type { PullRequest, MRDetail, Pipeline } from "@mattstack/glance";
8
8
  export type Discussion = MRDetail["discussions"][number];
9
9
  /** What a caller declares it needs, so the daemon can size the sync to cover it. */
10
10
  export interface DemandDecl {
@@ -289,6 +289,254 @@ export interface AgentRecord {
289
289
  lastResumedAt?: number;
290
290
  finishedAt?: number;
291
291
  }
292
+ /** Duplicated shape on purpose (see EventsBusEvent above): mirrors lib/daemon/health.ts's HealthSnapshot. */
293
+ export type HealthLevel = "ok" | "degraded" | "unhealthy";
294
+ export interface HealthMetrics {
295
+ rss: number;
296
+ heapUsed: number;
297
+ external: number;
298
+ uptimeMs: number;
299
+ wsClients: number;
300
+ watchers: number;
301
+ }
302
+ export interface HealthEventLoop {
303
+ maxLagMs: number;
304
+ lastStallAt: number | null;
305
+ lastStallCmd: string | null;
306
+ stalls: number;
307
+ }
308
+ export interface DaemonIdentity {
309
+ flavor: "dev" | "prod";
310
+ version: string;
311
+ sourceRev: string | null;
312
+ startedAt: number;
313
+ }
314
+ export interface PingData extends DaemonIdentity {
315
+ uptime: number;
316
+ pid: number;
317
+ health: HealthLevel;
318
+ eventLoop: HealthEventLoop;
319
+ heartbeatSeq: number;
320
+ supervision: {
321
+ bootAttempts: number;
322
+ lastReadyAt: number | null;
323
+ recentFailures: unknown[];
324
+ lastExit: unknown;
325
+ };
326
+ }
327
+ export interface StatusData {
328
+ pid: number;
329
+ uptime: number;
330
+ watchedRepos: number;
331
+ cacheEntries: number;
332
+ portsCached: number;
333
+ portCacheAge: number | null;
334
+ freshness: unknown;
335
+ identity: DaemonIdentity;
336
+ health: {
337
+ level: HealthLevel;
338
+ reasons: string[];
339
+ };
340
+ metrics: HealthMetrics;
341
+ eventLoop: HealthEventLoop;
342
+ worktreePool: {
343
+ dormant: true;
344
+ repos: string[];
345
+ message: string;
346
+ } | {
347
+ dormant: false;
348
+ };
349
+ }
350
+ export interface TrayStatusData {
351
+ pid: number;
352
+ uptime: number;
353
+ memoryUsage: number;
354
+ watchedRepos: number;
355
+ cacheEntries: number;
356
+ portsCached: number;
357
+ portCacheAge: number | null;
358
+ lastRefresh: number | null;
359
+ portsByRepo: Record<string, number>;
360
+ pendingNotifications: number;
361
+ health: {
362
+ level: HealthLevel;
363
+ reasons: string[];
364
+ };
365
+ metrics: HealthMetrics;
366
+ eventLoop: HealthEventLoop;
367
+ }
368
+ /** Duplicated shape on purpose: mirrors lib/port-scanner.ts's PortEntry. */
369
+ export interface PortEntry {
370
+ port: number;
371
+ pid: number;
372
+ command: string;
373
+ cwd: string;
374
+ repo: string | null;
375
+ worktree: string | null;
376
+ branch: string | null;
377
+ relativeDir: string;
378
+ uptime: string;
379
+ }
380
+ export interface PortsData {
381
+ ports: PortEntry[];
382
+ grouped: Record<string, Record<string, PortEntry[]>>;
383
+ updatedAt: number;
384
+ age: number | null;
385
+ }
386
+ /** Duplicated shape on purpose: mirrors lib/state/notifier-store.ts's NotificationEvent. */
387
+ export interface RtNotificationEvent {
388
+ id: string;
389
+ title: string;
390
+ message: string;
391
+ url?: string;
392
+ category: string;
393
+ timestamp: number;
394
+ pids?: number[];
395
+ }
396
+ export interface ReposData {
397
+ repos: Record<string, {
398
+ path: string;
399
+ worktrees: Array<{
400
+ path: string;
401
+ branch: string;
402
+ }>;
403
+ }>;
404
+ watched: string[];
405
+ }
406
+ export interface TccCheckData {
407
+ blocked: Array<{
408
+ name: string;
409
+ path: string;
410
+ error: string;
411
+ }>;
412
+ accessible: string[];
413
+ totalRepos: number;
414
+ daemonPid: number;
415
+ }
416
+ export interface WorktreeTreeRow {
417
+ name: string;
418
+ kind: string;
419
+ state: string;
420
+ path: string;
421
+ branch: string | null;
422
+ repoName: string;
423
+ mr: {
424
+ iid: number;
425
+ state: string;
426
+ title: string;
427
+ } | null;
428
+ duplicateBranch?: true;
429
+ [extra: string]: unknown;
430
+ }
431
+ export interface WorktreeListData {
432
+ trees: WorktreeTreeRow[];
433
+ dormant?: true;
434
+ dormantRepos?: string[];
435
+ message?: string;
436
+ readyHeld?: true;
437
+ readyHeldRepos?: string[];
438
+ }
439
+ export interface WorktreeProvisionData {
440
+ tree: string;
441
+ path: string;
442
+ branch: string;
443
+ wasOnDeck: boolean;
444
+ readyAt: string | null;
445
+ branchState: "new" | "tracking-remote" | "existing-clean" | "diverged" | "behind";
446
+ readyFailed?: true;
447
+ failedStep?: string;
448
+ }
449
+ export interface WorktreeCreateData {
450
+ tree: string;
451
+ path: string;
452
+ }
453
+ export interface WorktreeDisposeData {
454
+ disposed: string[];
455
+ refused: Array<{
456
+ tree: string;
457
+ reason: string;
458
+ }>;
459
+ recoverable: Array<{
460
+ tree: string;
461
+ path: string;
462
+ until: string;
463
+ }>;
464
+ }
465
+ export interface WorktreeRestoreData {
466
+ restored: true;
467
+ path: string;
468
+ tree: string;
469
+ readyFailed?: true;
470
+ failedStep?: string;
471
+ }
472
+ export interface WorktreeFreshenData {
473
+ ran: string[];
474
+ }
475
+ export interface WorktreeAdoptData {
476
+ main: string;
477
+ claimed: string[];
478
+ unmanaged: string[];
479
+ disposed: string[];
480
+ refused: Array<{
481
+ tree: string;
482
+ reason: string;
483
+ }>;
484
+ }
485
+ /** Duplicated shape on purpose: mirrors lib/endpoint/store.ts's EndpointClaim. */
486
+ export interface EndpointClaim {
487
+ worktree: string;
488
+ role: string;
489
+ port: number;
490
+ ts: number;
491
+ }
492
+ export interface EndpointRoleRef {
493
+ port: number;
494
+ url: string;
495
+ running: boolean;
496
+ }
497
+ export interface EndpointClaimData {
498
+ role: string;
499
+ port: number;
500
+ url: string;
501
+ refs: Record<string, EndpointRoleRef>;
502
+ }
503
+ export interface EndpointLookupData {
504
+ claimed: boolean;
505
+ port: number | null;
506
+ url: string | null;
507
+ running: boolean;
508
+ }
509
+ export interface EndpointReleaseData {
510
+ released: number;
511
+ }
512
+ export interface EndpointStatusData {
513
+ repos: Record<string, Array<EndpointClaim & {
514
+ running: boolean;
515
+ }>>;
516
+ }
517
+ /**
518
+ * Duplicated shape on purpose: mirrors @mattstack/glance's `JobDetail`
519
+ * (types.ts), which the package does not re-export from its index.
520
+ */
521
+ export type MrJobDetail = {
522
+ type: "trace";
523
+ content: string;
524
+ } | {
525
+ type: "bridge";
526
+ downstreamPipeline: Pipeline;
527
+ };
528
+ export interface DiscussionsWriteData {
529
+ discussions: Discussion[];
530
+ fetchedAt: number;
531
+ }
532
+ export interface DiscussionsDiffsData {
533
+ diffs: Array<{
534
+ newPath: string;
535
+ diff: string;
536
+ }>;
537
+ truncated: boolean;
538
+ }
539
+ export type MRActionName = "merge" | "rebase" | "approve" | "unapprove" | "setAutoMerge" | "cancelAutoMerge" | "retryJob" | "retryPipeline" | "toggleDraft" | "requestReReview";
292
540
  export interface Commands {
293
541
  "project-mrs:read": {
294
542
  payload: {
@@ -728,6 +976,270 @@ export interface Commands {
728
976
  };
729
977
  data: PaneFocusResult;
730
978
  };
979
+ "cache:read": {
980
+ payload: {
981
+ branches?: string[];
982
+ maxAgeMs?: number;
983
+ repoIdentity?: string;
984
+ };
985
+ data: Record<string, BranchEnrichment>;
986
+ };
987
+ /** `source` ("cache"|"fresh"|"empty") rides alongside `data` on the wire, not nested under it. */
988
+ "branch:enrich": {
989
+ payload: {
990
+ branch: string;
991
+ repoPath?: string;
992
+ remoteUrl?: string;
993
+ repoIdentity?: string;
994
+ };
995
+ data: BranchEnrichment | null;
996
+ };
997
+ /** Fire-and-forget kickoff; wire reply is `{ok, message}`, not `{ok,data}`. */
998
+ "cache:refresh": {
999
+ payload: Record<string, never>;
1000
+ data: {
1001
+ message: string;
1002
+ };
1003
+ };
1004
+ "daemon:log-level": {
1005
+ payload: {
1006
+ level?: "trace" | "debug" | "info" | "warn" | "error";
1007
+ };
1008
+ data: {
1009
+ level: string;
1010
+ };
1011
+ };
1012
+ "ping": {
1013
+ payload: Record<string, never>;
1014
+ data: PingData;
1015
+ };
1016
+ "status": {
1017
+ payload: Record<string, never>;
1018
+ data: StatusData;
1019
+ };
1020
+ "tray:status": {
1021
+ payload: Record<string, never>;
1022
+ data: TrayStatusData;
1023
+ };
1024
+ "tcc:check": {
1025
+ payload: Record<string, never>;
1026
+ data: TccCheckData;
1027
+ };
1028
+ "repos": {
1029
+ payload: Record<string, never>;
1030
+ data: ReposData;
1031
+ };
1032
+ "ports": {
1033
+ payload: {
1034
+ repo?: string;
1035
+ refresh?: boolean;
1036
+ };
1037
+ data: PortsData;
1038
+ };
1039
+ "notifications": {
1040
+ payload: Record<string, never>;
1041
+ data: RtNotificationEvent[];
1042
+ };
1043
+ "discussions:refresh": {
1044
+ payload: {
1045
+ repoName: string;
1046
+ iid: number;
1047
+ };
1048
+ data: DiscussionsWriteData;
1049
+ };
1050
+ "discussions:resolve": {
1051
+ payload: {
1052
+ repoName: string;
1053
+ iid: number;
1054
+ discussionId: string;
1055
+ resolved?: boolean;
1056
+ };
1057
+ data: DiscussionsWriteData;
1058
+ };
1059
+ "discussions:reply": {
1060
+ payload: {
1061
+ repoName: string;
1062
+ iid: number;
1063
+ discussionId: string;
1064
+ body: string;
1065
+ };
1066
+ data: DiscussionsWriteData;
1067
+ };
1068
+ "discussions:diffs": {
1069
+ payload: {
1070
+ repoName: string;
1071
+ iid: number;
1072
+ };
1073
+ data: DiscussionsDiffsData;
1074
+ };
1075
+ /** Wire reply is `{ok:true}` on success (no `data`); a failure is `{ok:false,error}`. */
1076
+ "mr:action": {
1077
+ payload: {
1078
+ repoName: string;
1079
+ iid: number;
1080
+ action: MRActionName;
1081
+ args?: unknown[];
1082
+ };
1083
+ data: Record<string, never>;
1084
+ };
1085
+ "mr:fetch-job-detail": {
1086
+ payload: {
1087
+ repoName: string;
1088
+ iid: number;
1089
+ jobId: number;
1090
+ pipelineId?: number;
1091
+ };
1092
+ data: MrJobDetail;
1093
+ };
1094
+ "mr:fetch-job-trace": {
1095
+ payload: {
1096
+ repoName: string;
1097
+ iid: number;
1098
+ jobId: number;
1099
+ };
1100
+ data: string;
1101
+ };
1102
+ "endpoint:claim": {
1103
+ payload: {
1104
+ repo: string;
1105
+ worktree: string;
1106
+ role: string;
1107
+ pid?: number;
1108
+ };
1109
+ data: EndpointClaimData;
1110
+ };
1111
+ "endpoint:lookup": {
1112
+ payload: {
1113
+ repo: string;
1114
+ worktree: string;
1115
+ role: string;
1116
+ };
1117
+ data: EndpointLookupData;
1118
+ };
1119
+ "endpoint:release": {
1120
+ payload: {
1121
+ repo: string;
1122
+ worktree: string;
1123
+ role?: string;
1124
+ };
1125
+ data: EndpointReleaseData;
1126
+ };
1127
+ "endpoint:status": {
1128
+ payload: {
1129
+ repo?: string;
1130
+ };
1131
+ data: EndpointStatusData;
1132
+ };
1133
+ "repos:locate": {
1134
+ payload: {
1135
+ newPath: string;
1136
+ repo?: string;
1137
+ dryRun?: boolean;
1138
+ };
1139
+ data: unknown;
1140
+ };
1141
+ "freshness:reconcile": {
1142
+ payload: Record<string, never>;
1143
+ data: unknown;
1144
+ };
1145
+ /** Wire reply on success is always `{ok:true, repaired}` (no `data`
1146
+ * wrapper) — `data` here documents the extra field the same way PingData
1147
+ * does for `ping`, not the literal wire nesting (R3). */
1148
+ "hooks:repair": {
1149
+ payload: {
1150
+ repo: string;
1151
+ };
1152
+ data: {
1153
+ repaired: boolean;
1154
+ };
1155
+ };
1156
+ "hooks:watch": {
1157
+ payload: {
1158
+ repo: string;
1159
+ };
1160
+ data: Record<string, never>;
1161
+ };
1162
+ "sdm:catalog": {
1163
+ payload: {
1164
+ refresh?: boolean;
1165
+ };
1166
+ data: unknown;
1167
+ };
1168
+ "sdm:snapshot": {
1169
+ payload: {
1170
+ force?: boolean;
1171
+ };
1172
+ data: unknown;
1173
+ };
1174
+ "sdm:recents": {
1175
+ payload: Record<string, never>;
1176
+ data: unknown;
1177
+ };
1178
+ "sdm:reconnect": {
1179
+ payload: {
1180
+ key: string;
1181
+ };
1182
+ data: unknown;
1183
+ };
1184
+ "system-processes": {
1185
+ payload: Record<string, never>;
1186
+ data: unknown;
1187
+ };
1188
+ "worktree:provision": {
1189
+ payload: {
1190
+ repoName: string;
1191
+ branch?: string;
1192
+ ticket?: string;
1193
+ ticketTitle?: string;
1194
+ disposal?: "job" | "merge";
1195
+ owner?: string;
1196
+ };
1197
+ data: WorktreeProvisionData;
1198
+ };
1199
+ "worktree:create": {
1200
+ payload: {
1201
+ repoName: string;
1202
+ onDeck?: boolean;
1203
+ };
1204
+ data: WorktreeCreateData;
1205
+ };
1206
+ "worktree:dispose": {
1207
+ payload: {
1208
+ repoName?: string;
1209
+ owner?: string;
1210
+ tree?: string;
1211
+ force?: boolean;
1212
+ callerPid?: number;
1213
+ };
1214
+ data: WorktreeDisposeData;
1215
+ };
1216
+ "worktree:list": {
1217
+ payload: {
1218
+ repoName?: string;
1219
+ };
1220
+ data: WorktreeListData;
1221
+ };
1222
+ "worktree:restore": {
1223
+ payload: {
1224
+ repoName: string;
1225
+ tree: string;
1226
+ };
1227
+ data: WorktreeRestoreData;
1228
+ };
1229
+ "worktree:freshen": {
1230
+ payload: {
1231
+ repoName?: string;
1232
+ tree?: string;
1233
+ };
1234
+ data: WorktreeFreshenData;
1235
+ };
1236
+ "worktree:adopt": {
1237
+ payload: {
1238
+ repoName: string;
1239
+ claim?: boolean;
1240
+ };
1241
+ data: WorktreeAdoptData;
1242
+ };
731
1243
  }
732
1244
  export type CommandName = keyof Commands;
733
1245
  export declare const COMMAND_NAMES: readonly CommandName[];
package/dist/index.d.ts CHANGED
@@ -7,7 +7,9 @@ export { subscribe, createRelay, DEFAULT_WS_URL } from "./relay.ts";
7
7
  export type { RelayEventType } from "./relay.ts";
8
8
  export { daemonHealth } from "./health.ts";
9
9
  export { repoNameForPath } from "./repos.ts";
10
- export { getSetting, listSettings, explainSetting, expandVariables, SCOPE_ORDER } from "./settings/resolve.ts";
10
+ export { decidePlacement, openSmartPane } from "./smart-pane.ts";
11
+ export type { Placement, PlacementOpts, HerdrCall } from "./smart-pane.ts";
12
+ export { getSetting, listSettings, explainSetting, expandVariables, SCOPE_ORDER, setSettingsWarnSink } from "./settings/resolve.ts";
11
13
  export type { Scope, Provenance, ResolveOpts, Resolved, InvalidScope, ListedSetting, ExplainRow, ExpandCtx, } from "./settings/resolve.ts";
12
14
  export { setSetting, unsetSetting } from "./settings/write.ts";
13
15
  export type { SetSettingOpts } from "./settings/write.ts";