@gowelle/stint-agent 1.2.35 → 1.2.37
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/README.md +31 -4
- package/dist/{StatusDashboard-N3HF2TD3.js → StatusDashboard-AMDPK7EQ.js} +104 -24
- package/dist/api-AFSILC7K.js +7 -0
- package/dist/{chunk-RC7Z6GTK.js → chunk-HPHXBSGB.js} +34 -3
- package/dist/{chunk-H5GHDNXY.js → chunk-IBGWKTT7.js} +67 -20
- package/dist/{chunk-MISINEGG.js → chunk-NODAAPCO.js} +254 -94
- package/dist/{chunk-4655SBXG.js → chunk-XRNTJYCQ.js} +45 -12
- package/dist/daemon/runner.js +160 -51
- package/dist/index.js +714 -316
- package/package.json +1 -1
- package/dist/api-Z3HF3YU7.js +0 -7
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
apiService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IBGWKTT7.js";
|
|
4
4
|
import {
|
|
5
5
|
gitService,
|
|
6
6
|
projectService
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-XRNTJYCQ.js";
|
|
8
8
|
import {
|
|
9
9
|
authService,
|
|
10
10
|
config,
|
|
11
11
|
logger
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-HPHXBSGB.js";
|
|
13
13
|
|
|
14
14
|
// src/utils/notify.ts
|
|
15
15
|
import notifier from "node-notifier";
|
|
@@ -23,21 +23,31 @@ function notify(options) {
|
|
|
23
23
|
logger.debug("notify", "Notifications disabled, skipping notification");
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
|
+
if (options.category && !config.isCategoryEnabled(options.category)) {
|
|
27
|
+
logger.debug(
|
|
28
|
+
"notify",
|
|
29
|
+
`Category "${options.category}" disabled, skipping notification`
|
|
30
|
+
);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
26
33
|
try {
|
|
27
|
-
notifier.notify(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
notifier.notify(
|
|
35
|
+
{
|
|
36
|
+
title: options.title,
|
|
37
|
+
message: options.message,
|
|
38
|
+
open: options.open,
|
|
39
|
+
icon: options.icon || DEFAULT_ICON,
|
|
40
|
+
sound: true,
|
|
41
|
+
wait: false,
|
|
42
|
+
appID: "Stint Agent"
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
44
|
+
},
|
|
45
|
+
(error) => {
|
|
46
|
+
if (error) {
|
|
47
|
+
logger.error("notify", "Failed to send notification", error);
|
|
48
|
+
}
|
|
39
49
|
}
|
|
40
|
-
|
|
50
|
+
);
|
|
41
51
|
} catch (error) {
|
|
42
52
|
logger.error("notify", "Failed to send notification", error);
|
|
43
53
|
}
|
|
@@ -107,7 +117,11 @@ var OutputBuffer = class {
|
|
|
107
117
|
try {
|
|
108
118
|
await apiService.streamCommitOutput(this.commitId, chunk);
|
|
109
119
|
} catch (error) {
|
|
110
|
-
logger.debug(
|
|
120
|
+
logger.debug(
|
|
121
|
+
"stream",
|
|
122
|
+
`Failed to stream output for ${this.commitId}`,
|
|
123
|
+
error
|
|
124
|
+
);
|
|
111
125
|
}
|
|
112
126
|
}
|
|
113
127
|
/**
|
|
@@ -140,12 +154,19 @@ var HookService = class {
|
|
|
140
154
|
const result = await this.executeSingleHook(hook, cwd, onOutput);
|
|
141
155
|
results.push(result);
|
|
142
156
|
if (!result.success && hook.blockOnFailure) {
|
|
143
|
-
logger.warn(
|
|
157
|
+
logger.warn(
|
|
158
|
+
"hooks",
|
|
159
|
+
`Hook "${hook.name}" failed and is blocking. Stopping execution.`
|
|
160
|
+
);
|
|
144
161
|
break;
|
|
145
162
|
}
|
|
146
163
|
} catch (error) {
|
|
147
164
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
148
|
-
logger.error(
|
|
165
|
+
logger.error(
|
|
166
|
+
"hooks",
|
|
167
|
+
`Unexpected error running hook "${hook.name}"`,
|
|
168
|
+
error
|
|
169
|
+
);
|
|
149
170
|
results.push({
|
|
150
171
|
hookId: hook.id,
|
|
151
172
|
hookName: hook.name,
|
|
@@ -247,7 +268,10 @@ var CommitQueueProcessor = class {
|
|
|
247
268
|
*/
|
|
248
269
|
addToQueue(commit, project) {
|
|
249
270
|
this.queue.push({ commit, project });
|
|
250
|
-
logger.info(
|
|
271
|
+
logger.info(
|
|
272
|
+
"queue",
|
|
273
|
+
`Added commit ${commit.id} to queue (position: ${this.queue.length})`
|
|
274
|
+
);
|
|
251
275
|
if (!this.isProcessing) {
|
|
252
276
|
this.processQueue();
|
|
253
277
|
}
|
|
@@ -266,7 +290,11 @@ var CommitQueueProcessor = class {
|
|
|
266
290
|
try {
|
|
267
291
|
await this.executeCommit(item.commit, item.project);
|
|
268
292
|
} catch (error) {
|
|
269
|
-
logger.error(
|
|
293
|
+
logger.error(
|
|
294
|
+
"queue",
|
|
295
|
+
`Failed to execute commit ${item.commit.id}`,
|
|
296
|
+
error
|
|
297
|
+
);
|
|
270
298
|
}
|
|
271
299
|
}
|
|
272
300
|
this.isProcessing = false;
|
|
@@ -286,7 +314,9 @@ var CommitQueueProcessor = class {
|
|
|
286
314
|
onProgress?.("Finding project directory...");
|
|
287
315
|
const projectPath = this.findProjectPath(project.id);
|
|
288
316
|
if (!projectPath) {
|
|
289
|
-
throw new Error(
|
|
317
|
+
throw new Error(
|
|
318
|
+
`Project ${project.id} is not linked to any local directory`
|
|
319
|
+
);
|
|
290
320
|
}
|
|
291
321
|
logger.info("queue", `Executing in directory: ${projectPath}`);
|
|
292
322
|
streamer.append(`> Project directory: ${projectPath}
|
|
@@ -310,22 +340,34 @@ var CommitQueueProcessor = class {
|
|
|
310
340
|
);
|
|
311
341
|
if (failedBlockingHook) {
|
|
312
342
|
const errorMsg = failedBlockingHook.error || "Unknown error";
|
|
313
|
-
logger.error(
|
|
314
|
-
|
|
343
|
+
logger.error(
|
|
344
|
+
"queue",
|
|
345
|
+
`Blocking hook "${failedBlockingHook.hookName}" failed: ${errorMsg}`
|
|
346
|
+
);
|
|
347
|
+
streamer.append(
|
|
348
|
+
`
|
|
315
349
|
Error: Blocking hook "${failedBlockingHook.hookName}" failed: ${errorMsg}
|
|
316
|
-
`
|
|
350
|
+
`
|
|
351
|
+
);
|
|
317
352
|
if (failedBlockingHook.output) {
|
|
318
353
|
logger.warn("queue", `Hook output:
|
|
319
354
|
${failedBlockingHook.output}`);
|
|
320
355
|
}
|
|
321
|
-
throw new Error(
|
|
356
|
+
throw new Error(
|
|
357
|
+
`Pre-commit hook "${failedBlockingHook.hookName}" failed: ${errorMsg}`
|
|
358
|
+
);
|
|
322
359
|
}
|
|
323
360
|
const failedNonBlockingHooks = hookResults.filter((r) => !r.success);
|
|
324
361
|
if (failedNonBlockingHooks.length > 0) {
|
|
325
|
-
logger.warn(
|
|
326
|
-
|
|
362
|
+
logger.warn(
|
|
363
|
+
"queue",
|
|
364
|
+
`${failedNonBlockingHooks.length} hooks failed but were not blocking: ${failedNonBlockingHooks.map((h) => h.hookName).join(", ")}`
|
|
365
|
+
);
|
|
366
|
+
streamer.append(
|
|
367
|
+
`
|
|
327
368
|
Warning: ${failedNonBlockingHooks.length} non-blocking hooks failed.
|
|
328
|
-
`
|
|
369
|
+
`
|
|
370
|
+
);
|
|
329
371
|
}
|
|
330
372
|
}
|
|
331
373
|
onProgress?.("Checking repository status...");
|
|
@@ -351,15 +393,23 @@ Warning: ${failedNonBlockingHooks.length} non-blocking hooks failed.
|
|
|
351
393
|
}
|
|
352
394
|
}
|
|
353
395
|
if (status.staged.length === 0) {
|
|
354
|
-
throw new Error(
|
|
396
|
+
throw new Error(
|
|
397
|
+
"No changes to commit. The working directory is clean."
|
|
398
|
+
);
|
|
355
399
|
}
|
|
356
400
|
logger.info("queue", `Committing ${status.staged.length} staged files.`);
|
|
357
|
-
streamer.append(
|
|
401
|
+
streamer.append(
|
|
402
|
+
`
|
|
358
403
|
> Committing ${status.staged.length} staged files...
|
|
359
|
-
`
|
|
404
|
+
`
|
|
405
|
+
);
|
|
360
406
|
onProgress?.("Creating commit...");
|
|
361
407
|
logger.info("queue", `Creating commit with message: "${commit.message}"`);
|
|
362
|
-
const sha = await gitService.commit(
|
|
408
|
+
const sha = await gitService.commit(
|
|
409
|
+
projectPath,
|
|
410
|
+
commit.message,
|
|
411
|
+
streamOutput
|
|
412
|
+
);
|
|
363
413
|
logger.success("queue", `Commit created successfully: ${sha}`);
|
|
364
414
|
streamer.append(`
|
|
365
415
|
> Commit created: ${sha}
|
|
@@ -373,7 +423,12 @@ Warning: ${failedNonBlockingHooks.length} non-blocking hooks failed.
|
|
|
373
423
|
streamer.append(`
|
|
374
424
|
> Pushing to remote...
|
|
375
425
|
`);
|
|
376
|
-
await gitService.push(
|
|
426
|
+
await gitService.push(
|
|
427
|
+
projectPath,
|
|
428
|
+
void 0,
|
|
429
|
+
void 0,
|
|
430
|
+
streamOutput
|
|
431
|
+
);
|
|
377
432
|
pushed = true;
|
|
378
433
|
logger.success("queue", `Pushed commit ${sha} to remote`);
|
|
379
434
|
streamer.append(`
|
|
@@ -381,7 +436,8 @@ Warning: ${failedNonBlockingHooks.length} non-blocking hooks failed.
|
|
|
381
436
|
`);
|
|
382
437
|
notify({
|
|
383
438
|
title: `Commit Pushed - ${project.name}`,
|
|
384
|
-
message: `Commit "${commit.message}" successfully pushed
|
|
439
|
+
message: `Commit "${commit.message}" successfully pushed.`,
|
|
440
|
+
category: "commits"
|
|
385
441
|
});
|
|
386
442
|
} catch (error) {
|
|
387
443
|
pushError = error.message;
|
|
@@ -390,17 +446,22 @@ Warning: ${failedNonBlockingHooks.length} non-blocking hooks failed.
|
|
|
390
446
|
> Push failed: ${pushError}
|
|
391
447
|
`);
|
|
392
448
|
if (isConflict) {
|
|
393
|
-
logger.warn(
|
|
449
|
+
logger.warn(
|
|
450
|
+
"queue",
|
|
451
|
+
`Push failed due to remote conflict: ${pushError}`
|
|
452
|
+
);
|
|
394
453
|
notify({
|
|
395
454
|
title: `Push Conflict - ${project.name}`,
|
|
396
455
|
message: `Commit "${commit.message}" created but push failed.
|
|
397
|
-
Run "git pull --rebase" to resolve
|
|
456
|
+
Run "git pull --rebase" to resolve.`,
|
|
457
|
+
category: "commits"
|
|
398
458
|
});
|
|
399
459
|
} else {
|
|
400
460
|
logger.error("queue", `Push failed: ${pushError}`);
|
|
401
461
|
notify({
|
|
402
462
|
title: `Push Failed - ${project.name}`,
|
|
403
|
-
message: `Commit created but push failed: ${pushError}
|
|
463
|
+
message: `Commit created but push failed: ${pushError}`,
|
|
464
|
+
category: "commits"
|
|
404
465
|
});
|
|
405
466
|
}
|
|
406
467
|
}
|
|
@@ -414,7 +475,8 @@ Run "git pull --rebase" to resolve.`
|
|
|
414
475
|
if (!pushed && !pushError) {
|
|
415
476
|
notify({
|
|
416
477
|
title: `Commit Created - ${project.name}`,
|
|
417
|
-
message: `Commit "${commit.message}" created locally
|
|
478
|
+
message: `Commit "${commit.message}" created locally.`,
|
|
479
|
+
category: "commits"
|
|
418
480
|
});
|
|
419
481
|
}
|
|
420
482
|
return sha;
|
|
@@ -427,7 +489,8 @@ Run "git pull --rebase" to resolve.`
|
|
|
427
489
|
await streamer.close();
|
|
428
490
|
notify({
|
|
429
491
|
title: `Commit Failed - ${project.name}`,
|
|
430
|
-
message: `Failed to execute commit "${commit.message}": ${msg}
|
|
492
|
+
message: `Failed to execute commit "${commit.message}": ${msg}`,
|
|
493
|
+
category: "commits"
|
|
431
494
|
});
|
|
432
495
|
await this.reportFailure(commit.id, msg);
|
|
433
496
|
throw error;
|
|
@@ -444,9 +507,16 @@ Run "git pull --rebase" to resolve.`
|
|
|
444
507
|
try {
|
|
445
508
|
await apiService.markCommitExecuted(commitId, sha, pushed, pushError);
|
|
446
509
|
const status = pushed ? "executed" : "committed (push failed)";
|
|
447
|
-
logger.success(
|
|
510
|
+
logger.success(
|
|
511
|
+
"queue",
|
|
512
|
+
`Reported commit ${status} to API: ${commitId} -> ${sha}`
|
|
513
|
+
);
|
|
448
514
|
} catch (error) {
|
|
449
|
-
logger.error(
|
|
515
|
+
logger.error(
|
|
516
|
+
"queue",
|
|
517
|
+
"Failed to report commit success to API",
|
|
518
|
+
error
|
|
519
|
+
);
|
|
450
520
|
}
|
|
451
521
|
}
|
|
452
522
|
/**
|
|
@@ -457,7 +527,11 @@ Run "git pull --rebase" to resolve.`
|
|
|
457
527
|
await apiService.markCommitFailed(commitId, error);
|
|
458
528
|
logger.info("queue", `Reported commit failure to API: ${commitId}`);
|
|
459
529
|
} catch (apiError) {
|
|
460
|
-
logger.error(
|
|
530
|
+
logger.error(
|
|
531
|
+
"queue",
|
|
532
|
+
"Failed to report commit failure to API",
|
|
533
|
+
apiError
|
|
534
|
+
);
|
|
461
535
|
}
|
|
462
536
|
}
|
|
463
537
|
/**
|
|
@@ -493,7 +567,12 @@ import Pusher from "pusher-js";
|
|
|
493
567
|
import fs from "fs";
|
|
494
568
|
import os from "os";
|
|
495
569
|
import path2 from "path";
|
|
496
|
-
var STATUS_FILE_PATH = path2.join(
|
|
570
|
+
var STATUS_FILE_PATH = path2.join(
|
|
571
|
+
os.homedir(),
|
|
572
|
+
".config",
|
|
573
|
+
"stint",
|
|
574
|
+
"daemon.status.json"
|
|
575
|
+
);
|
|
497
576
|
function writeStatus(update) {
|
|
498
577
|
try {
|
|
499
578
|
const dir = path2.dirname(STATUS_FILE_PATH);
|
|
@@ -535,7 +614,10 @@ var WebSocketServiceImpl = class {
|
|
|
535
614
|
async connect() {
|
|
536
615
|
this.currentPusherClient = null;
|
|
537
616
|
if (this.echo) {
|
|
538
|
-
logger.debug(
|
|
617
|
+
logger.debug(
|
|
618
|
+
"websocket",
|
|
619
|
+
"Closing existing connection before reconnecting..."
|
|
620
|
+
);
|
|
539
621
|
this.echo.disconnect();
|
|
540
622
|
this.echo = null;
|
|
541
623
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
@@ -563,7 +645,10 @@ var WebSocketServiceImpl = class {
|
|
|
563
645
|
wsPort = 443;
|
|
564
646
|
forceTLS = true;
|
|
565
647
|
}
|
|
566
|
-
logger.info(
|
|
648
|
+
logger.info(
|
|
649
|
+
"websocket",
|
|
650
|
+
`Connecting to ${wsHost}:${wsPort} with key ${reverbAppKey}...`
|
|
651
|
+
);
|
|
567
652
|
const { WebSocket } = await import("ws");
|
|
568
653
|
global.WebSocket = WebSocket;
|
|
569
654
|
const pusherClient = new Pusher(reverbAppKey, {
|
|
@@ -586,8 +671,8 @@ var WebSocketServiceImpl = class {
|
|
|
586
671
|
const response = await fetch(`${apiUrl}/api/broadcasting/auth`, {
|
|
587
672
|
method: "POST",
|
|
588
673
|
headers: {
|
|
589
|
-
|
|
590
|
-
|
|
674
|
+
Authorization: `Bearer ${token}`,
|
|
675
|
+
Accept: "application/json",
|
|
591
676
|
"Content-Type": "application/json"
|
|
592
677
|
},
|
|
593
678
|
body: JSON.stringify({
|
|
@@ -597,7 +682,10 @@ var WebSocketServiceImpl = class {
|
|
|
597
682
|
});
|
|
598
683
|
if (!response.ok) {
|
|
599
684
|
const errorText = await response.text();
|
|
600
|
-
logger.error(
|
|
685
|
+
logger.error(
|
|
686
|
+
"websocket",
|
|
687
|
+
`Auth failed (${response.status}): ${errorText}`
|
|
688
|
+
);
|
|
601
689
|
callback(new Error(`Auth failed: ${response.status}`));
|
|
602
690
|
return;
|
|
603
691
|
}
|
|
@@ -629,7 +717,10 @@ var WebSocketServiceImpl = class {
|
|
|
629
717
|
});
|
|
630
718
|
this.echo = echoInstance;
|
|
631
719
|
this.currentPusherClient = pusherClient;
|
|
632
|
-
logger.info(
|
|
720
|
+
logger.info(
|
|
721
|
+
"websocket",
|
|
722
|
+
"Echo instance created, setting up connection handlers..."
|
|
723
|
+
);
|
|
633
724
|
return new Promise((resolve, reject) => {
|
|
634
725
|
let isSettled = false;
|
|
635
726
|
const safeResolve = () => {
|
|
@@ -655,20 +746,34 @@ var WebSocketServiceImpl = class {
|
|
|
655
746
|
const connectionTimeout = setTimeout(() => {
|
|
656
747
|
if (this.currentPusherClient !== pusherClient) return;
|
|
657
748
|
const state = pusherClient.connection.state || "unknown";
|
|
658
|
-
logger.error(
|
|
749
|
+
logger.error(
|
|
750
|
+
"websocket",
|
|
751
|
+
`Connection timeout after 30s (state: ${state})`
|
|
752
|
+
);
|
|
659
753
|
if (state !== "connected") {
|
|
660
|
-
safeReject(
|
|
754
|
+
safeReject(
|
|
755
|
+
new Error(`Connection timeout - stuck in state: ${state}`)
|
|
756
|
+
);
|
|
661
757
|
}
|
|
662
758
|
}, 3e4);
|
|
663
|
-
pusherClient.connection.bind(
|
|
664
|
-
|
|
665
|
-
|
|
759
|
+
pusherClient.connection.bind(
|
|
760
|
+
"state_change",
|
|
761
|
+
(states) => {
|
|
762
|
+
if (this.currentPusherClient === pusherClient) {
|
|
763
|
+
logger.info(
|
|
764
|
+
"websocket",
|
|
765
|
+
`Connection state: ${states.previous} -> ${states.current}`
|
|
766
|
+
);
|
|
767
|
+
}
|
|
666
768
|
}
|
|
667
|
-
|
|
769
|
+
);
|
|
668
770
|
pusherClient.connection.bind("connected", () => {
|
|
669
771
|
if (this.currentPusherClient !== pusherClient) return;
|
|
670
772
|
clearTimeout(connectionTimeout);
|
|
671
|
-
logger.success(
|
|
773
|
+
logger.success(
|
|
774
|
+
"websocket",
|
|
775
|
+
"\u2705 Connected to Broadcaster via Sanctum"
|
|
776
|
+
);
|
|
672
777
|
writeStatus({ connected: true });
|
|
673
778
|
this.reconnectAttempts = 0;
|
|
674
779
|
this.isManualDisconnect = false;
|
|
@@ -680,7 +785,10 @@ var WebSocketServiceImpl = class {
|
|
|
680
785
|
const errorMessage = error instanceof Error ? error.message : JSON.stringify(error) || "Unknown connection error";
|
|
681
786
|
logger.error("websocket", `WebSocket error: ${errorMessage}`);
|
|
682
787
|
if (error && typeof error === "object" && "data" in error && error.data?.code === 1006) {
|
|
683
|
-
logger.warn(
|
|
788
|
+
logger.warn(
|
|
789
|
+
"websocket",
|
|
790
|
+
"Detected abnormal closure (1006), ensuring reconnection..."
|
|
791
|
+
);
|
|
684
792
|
this.handleDisconnect();
|
|
685
793
|
}
|
|
686
794
|
if (pusherClient.connection.state === "failed") {
|
|
@@ -689,7 +797,10 @@ var WebSocketServiceImpl = class {
|
|
|
689
797
|
});
|
|
690
798
|
pusherClient.connection.bind("disconnected", () => {
|
|
691
799
|
if (this.currentPusherClient !== pusherClient) {
|
|
692
|
-
logger.debug(
|
|
800
|
+
logger.debug(
|
|
801
|
+
"websocket",
|
|
802
|
+
"Ignoring disconnected event from previous connection attempt"
|
|
803
|
+
);
|
|
693
804
|
return;
|
|
694
805
|
}
|
|
695
806
|
logger.warn("websocket", "WebSocket disconnected");
|
|
@@ -706,7 +817,10 @@ var WebSocketServiceImpl = class {
|
|
|
706
817
|
});
|
|
707
818
|
pusherClient.connection.bind("unavailable", () => {
|
|
708
819
|
if (this.currentPusherClient !== pusherClient) return;
|
|
709
|
-
logger.warn(
|
|
820
|
+
logger.warn(
|
|
821
|
+
"websocket",
|
|
822
|
+
"WebSocket connection unavailable, attempting auto-reconnect"
|
|
823
|
+
);
|
|
710
824
|
writeStatus({ connected: false });
|
|
711
825
|
safeReject(new Error("WebSocket connection unavailable"));
|
|
712
826
|
});
|
|
@@ -761,50 +875,90 @@ var WebSocketServiceImpl = class {
|
|
|
761
875
|
logger.info("websocket", `Subscribing to private channel: ${channel}`);
|
|
762
876
|
const privateChannel = this.echo.private(channel);
|
|
763
877
|
writeStatus({ channel });
|
|
764
|
-
privateChannel.listen(
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
878
|
+
privateChannel.listen(
|
|
879
|
+
".commit.approved",
|
|
880
|
+
async (data) => {
|
|
881
|
+
logger.info("websocket", `Commit approved: ${data.pendingCommit.id}`);
|
|
882
|
+
writeStatus({
|
|
883
|
+
lastEvent: "commit.approved",
|
|
884
|
+
lastEventTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
885
|
+
});
|
|
886
|
+
let commit = data.pendingCommit;
|
|
887
|
+
if (commit.has_large_files) {
|
|
888
|
+
try {
|
|
889
|
+
logger.info(
|
|
890
|
+
"websocket",
|
|
891
|
+
`Commit ${commit.id} marked as large, fetching full details...`
|
|
892
|
+
);
|
|
893
|
+
const { apiService: apiService2 } = await import("./api-AFSILC7K.js");
|
|
894
|
+
const fullCommit = await apiService2.getCommit(commit.id);
|
|
895
|
+
commit = {
|
|
896
|
+
...commit,
|
|
897
|
+
files: fullCommit.files,
|
|
898
|
+
has_large_files: false
|
|
899
|
+
// Clear flag as we now have the files
|
|
900
|
+
};
|
|
901
|
+
logger.success(
|
|
902
|
+
"websocket",
|
|
903
|
+
`Fetched full details for commit ${commit.id}`
|
|
904
|
+
);
|
|
905
|
+
} catch (error) {
|
|
906
|
+
logger.error(
|
|
907
|
+
"websocket",
|
|
908
|
+
`Failed to fetch full commit details for ${commit.id}`,
|
|
909
|
+
error
|
|
910
|
+
);
|
|
911
|
+
}
|
|
782
912
|
}
|
|
913
|
+
this.commitApprovedHandlers.forEach(
|
|
914
|
+
(handler) => handler(commit, data.pendingCommit.project)
|
|
915
|
+
// Use the potentially updated commit object
|
|
916
|
+
);
|
|
783
917
|
}
|
|
784
|
-
|
|
785
|
-
(handler) => handler(commit, data.pendingCommit.project)
|
|
786
|
-
// Use the potentially updated commit object
|
|
787
|
-
);
|
|
788
|
-
}).listen(".commit.pending", (data) => {
|
|
918
|
+
).listen(".commit.pending", (data) => {
|
|
789
919
|
logger.info("websocket", `Commit pending: ${data.pendingCommit.id}`);
|
|
790
|
-
writeStatus({
|
|
791
|
-
|
|
920
|
+
writeStatus({
|
|
921
|
+
lastEvent: "commit.pending",
|
|
922
|
+
lastEventTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
923
|
+
});
|
|
924
|
+
this.commitPendingHandlers.forEach(
|
|
925
|
+
(handler) => handler(data.pendingCommit)
|
|
926
|
+
);
|
|
792
927
|
}).listen(".suggestion.created", (data) => {
|
|
793
928
|
logger.info("websocket", `Suggestion created: ${data.suggestion.id}`);
|
|
794
|
-
writeStatus({
|
|
795
|
-
|
|
929
|
+
writeStatus({
|
|
930
|
+
lastEvent: "suggestion.created",
|
|
931
|
+
lastEventTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
932
|
+
});
|
|
933
|
+
this.suggestionCreatedHandlers.forEach(
|
|
934
|
+
(handler) => handler(data.suggestion)
|
|
935
|
+
);
|
|
796
936
|
}).listen(".project.updated", (data) => {
|
|
797
937
|
logger.info("websocket", `Project updated: ${data.project.id}`);
|
|
798
|
-
writeStatus({
|
|
938
|
+
writeStatus({
|
|
939
|
+
lastEvent: "project.updated",
|
|
940
|
+
lastEventTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
941
|
+
});
|
|
799
942
|
this.projectUpdatedHandlers.forEach((handler) => handler(data.project));
|
|
800
943
|
}).listen(".sync.requested", (data) => {
|
|
801
|
-
logger.info(
|
|
802
|
-
|
|
803
|
-
|
|
944
|
+
logger.info(
|
|
945
|
+
"websocket",
|
|
946
|
+
`Sync requested for project: ${data.project.id}`
|
|
947
|
+
);
|
|
948
|
+
writeStatus({
|
|
949
|
+
lastEvent: "sync.requested",
|
|
950
|
+
lastEventTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
951
|
+
});
|
|
952
|
+
this.syncRequestedHandlers.forEach(
|
|
953
|
+
(handler) => handler(data.project.id)
|
|
954
|
+
);
|
|
804
955
|
}).listen(".agent.disconnected", (data) => {
|
|
805
956
|
const reason = data.reason ?? "Server requested disconnect";
|
|
806
957
|
logger.warn("websocket", `Agent disconnected by server: ${reason}`);
|
|
807
|
-
writeStatus({
|
|
958
|
+
writeStatus({
|
|
959
|
+
lastEvent: "agent.disconnected",
|
|
960
|
+
lastEventTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
961
|
+
});
|
|
808
962
|
this.agentDisconnectedHandlers.forEach((handler) => handler(reason));
|
|
809
963
|
});
|
|
810
964
|
logger.success("websocket", `Subscribed to private channel: ${channel}`);
|
|
@@ -846,7 +1000,10 @@ var WebSocketServiceImpl = class {
|
|
|
846
1000
|
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
847
1001
|
const delay = this.getReconnectDelay();
|
|
848
1002
|
this.reconnectAttempts++;
|
|
849
|
-
logger.info(
|
|
1003
|
+
logger.info(
|
|
1004
|
+
"websocket",
|
|
1005
|
+
`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`
|
|
1006
|
+
);
|
|
850
1007
|
this.reconnectTimer = setTimeout(async () => {
|
|
851
1008
|
try {
|
|
852
1009
|
await this.connect();
|
|
@@ -856,7 +1013,10 @@ var WebSocketServiceImpl = class {
|
|
|
856
1013
|
} catch (error) {
|
|
857
1014
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
858
1015
|
if (errorMessage.includes("disconnected during connection")) {
|
|
859
|
-
logger.debug(
|
|
1016
|
+
logger.debug(
|
|
1017
|
+
"websocket",
|
|
1018
|
+
"Connection disconnected during reconnection attempt, will retry"
|
|
1019
|
+
);
|
|
860
1020
|
} else {
|
|
861
1021
|
logger.error("websocket", "Reconnection failed", error);
|
|
862
1022
|
}
|