@agentuity/cli 1.0.10 → 1.0.12
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/cmd/build/ast.d.ts +1 -1
- package/dist/cmd/build/ast.d.ts.map +1 -1
- package/dist/cmd/build/ast.js +103 -5
- package/dist/cmd/build/ast.js.map +1 -1
- package/dist/cmd/build/vite/config-loader.d.ts.map +1 -1
- package/dist/cmd/build/vite/config-loader.js +1 -1
- package/dist/cmd/build/vite/config-loader.js.map +1 -1
- package/dist/cmd/build/vite/index.d.ts +2 -0
- package/dist/cmd/build/vite/index.d.ts.map +1 -1
- package/dist/cmd/build/vite/index.js +2 -1
- package/dist/cmd/build/vite/index.js.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.d.ts +4 -1
- package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.js +1 -0
- package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
- package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
- package/dist/cmd/build/vite/route-discovery.js +23 -1
- package/dist/cmd/build/vite/route-discovery.js.map +1 -1
- package/dist/cmd/build/vite/vite-builder.d.ts +2 -0
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-builder.js +1 -0
- package/dist/cmd/build/vite/vite-builder.js.map +1 -1
- package/dist/cmd/build/vite-bundler.d.ts +2 -0
- package/dist/cmd/build/vite-bundler.d.ts.map +1 -1
- package/dist/cmd/build/vite-bundler.js +2 -1
- package/dist/cmd/build/vite-bundler.js.map +1 -1
- package/dist/cmd/cloud/db/list.d.ts.map +1 -1
- package/dist/cmd/cloud/db/list.js +14 -1
- package/dist/cmd/cloud/db/list.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +36 -22
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/queue/list.d.ts.map +1 -1
- package/dist/cmd/cloud/queue/list.js +10 -0
- package/dist/cmd/cloud/queue/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/list.js +10 -0
- package/dist/cmd/cloud/sandbox/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/runtime/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/runtime/list.js +10 -0
- package/dist/cmd/cloud/sandbox/runtime/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/list.js +10 -0
- package/dist/cmd/cloud/sandbox/snapshot/list.js.map +1 -1
- package/dist/cmd/cloud/session/get.js +12 -12
- package/dist/cmd/cloud/session/get.js.map +1 -1
- package/dist/cmd/cloud/session/list.d.ts.map +1 -1
- package/dist/cmd/cloud/session/list.js +14 -4
- package/dist/cmd/cloud/session/list.js.map +1 -1
- package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/list.js +14 -1
- package/dist/cmd/cloud/storage/list.js.map +1 -1
- package/dist/cmd/cloud/stream/list.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/list.js +10 -0
- package/dist/cmd/cloud/stream/list.js.map +1 -1
- package/dist/cmd/cloud/thread/list.d.ts.map +1 -1
- package/dist/cmd/cloud/thread/list.js +10 -0
- package/dist/cmd/cloud/thread/list.js.map +1 -1
- package/dist/cmd/project/domain/check.d.ts +2 -0
- package/dist/cmd/project/domain/check.d.ts.map +1 -0
- package/dist/cmd/project/domain/check.js +131 -0
- package/dist/cmd/project/domain/check.js.map +1 -0
- package/dist/cmd/project/domain/index.d.ts +2 -0
- package/dist/cmd/project/domain/index.d.ts.map +1 -0
- package/dist/cmd/project/domain/index.js +20 -0
- package/dist/cmd/project/domain/index.js.map +1 -0
- package/dist/cmd/project/hostname/get.d.ts +2 -0
- package/dist/cmd/project/hostname/get.d.ts.map +1 -0
- package/dist/cmd/project/hostname/get.js +50 -0
- package/dist/cmd/project/hostname/get.js.map +1 -0
- package/dist/cmd/project/hostname/index.d.ts +2 -0
- package/dist/cmd/project/hostname/index.d.ts.map +1 -0
- package/dist/cmd/project/hostname/index.js +18 -0
- package/dist/cmd/project/hostname/index.js.map +1 -0
- package/dist/cmd/project/hostname/set.d.ts +2 -0
- package/dist/cmd/project/hostname/set.d.ts.map +1 -0
- package/dist/cmd/project/hostname/set.js +100 -0
- package/dist/cmd/project/hostname/set.js.map +1 -0
- package/dist/cmd/project/index.d.ts.map +1 -1
- package/dist/cmd/project/index.js +12 -0
- package/dist/cmd/project/index.js.map +1 -1
- package/dist/cmd/upgrade/index.d.ts.map +1 -1
- package/dist/cmd/upgrade/index.js +14 -8
- package/dist/cmd/upgrade/index.js.map +1 -1
- package/dist/cmd/upgrade/npm-availability.d.ts +12 -0
- package/dist/cmd/upgrade/npm-availability.d.ts.map +1 -1
- package/dist/cmd/upgrade/npm-availability.js +85 -6
- package/dist/cmd/upgrade/npm-availability.js.map +1 -1
- package/dist/cmd/upgrade/npm-availability.test.d.ts +2 -0
- package/dist/cmd/upgrade/npm-availability.test.d.ts.map +1 -0
- package/dist/cmd/upgrade/npm-availability.test.js +48 -0
- package/dist/cmd/upgrade/npm-availability.test.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/steps.d.ts +9 -0
- package/dist/steps.d.ts.map +1 -1
- package/dist/steps.js +131 -71
- package/dist/steps.js.map +1 -1
- package/dist/tui.d.ts +2 -2
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +6 -4
- package/dist/tui.js.map +1 -1
- package/dist/version-check.js +3 -6
- package/dist/version-check.js.map +1 -1
- package/package.json +6 -6
- package/src/cmd/build/ast.ts +141 -5
- package/src/cmd/build/vite/config-loader.ts +1 -3
- package/src/cmd/build/vite/index.ts +4 -0
- package/src/cmd/build/vite/metadata-generator.ts +5 -1
- package/src/cmd/build/vite/route-discovery.ts +34 -1
- package/src/cmd/build/vite/vite-builder.ts +3 -0
- package/src/cmd/build/vite-bundler.ts +4 -0
- package/src/cmd/cloud/db/list.ts +14 -1
- package/src/cmd/cloud/deploy.ts +46 -21
- package/src/cmd/cloud/queue/list.ts +10 -0
- package/src/cmd/cloud/sandbox/list.ts +10 -0
- package/src/cmd/cloud/sandbox/runtime/list.ts +10 -0
- package/src/cmd/cloud/sandbox/snapshot/list.ts +10 -0
- package/src/cmd/cloud/session/get.ts +12 -12
- package/src/cmd/cloud/session/list.ts +28 -18
- package/src/cmd/cloud/storage/list.ts +14 -1
- package/src/cmd/cloud/stream/list.ts +18 -8
- package/src/cmd/cloud/thread/list.ts +15 -5
- package/src/cmd/project/domain/check.ts +146 -0
- package/src/cmd/project/domain/index.ts +20 -0
- package/src/cmd/project/hostname/get.ts +54 -0
- package/src/cmd/project/hostname/index.ts +18 -0
- package/src/cmd/project/hostname/set.ts +123 -0
- package/src/cmd/project/index.ts +12 -0
- package/src/cmd/upgrade/index.ts +23 -9
- package/src/cmd/upgrade/npm-availability.test.ts +65 -0
- package/src/cmd/upgrade/npm-availability.ts +103 -6
- package/src/index.ts +1 -1
- package/src/steps.ts +139 -74
- package/src/tui.ts +6 -4
- package/src/version-check.ts +6 -6
package/src/steps.ts
CHANGED
|
@@ -11,6 +11,19 @@ import { ValidationInputError, ValidationOutputError, type IssuesType } from '@a
|
|
|
11
11
|
import { clearLastLines, isTTYLike } from './tui';
|
|
12
12
|
import { appendLog, isLogCollectionEnabled } from './log-collector';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Error thrown when step execution is interrupted by a signal (e.g., Ctrl+C).
|
|
16
|
+
* Callers can catch this to perform cleanup before exiting.
|
|
17
|
+
*/
|
|
18
|
+
export class StepInterruptError extends Error {
|
|
19
|
+
public readonly exitCode: number;
|
|
20
|
+
constructor(exitCode = 130) {
|
|
21
|
+
super('Step execution interrupted');
|
|
22
|
+
this.name = 'StepInterruptError';
|
|
23
|
+
this.exitCode = exitCode;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
14
27
|
// Spinner frames
|
|
15
28
|
const FRAMES = ['◐', '◓', '◑', '◒'];
|
|
16
29
|
|
|
@@ -77,6 +90,7 @@ export const stepError = (message: string, cause?: Error, output?: string[]): St
|
|
|
77
90
|
*/
|
|
78
91
|
export interface StepContext {
|
|
79
92
|
progress: (n: number) => void;
|
|
93
|
+
signal: AbortSignal;
|
|
80
94
|
}
|
|
81
95
|
|
|
82
96
|
/**
|
|
@@ -300,14 +314,6 @@ export function pauseStepUI(clear = false): () => void {
|
|
|
300
314
|
};
|
|
301
315
|
}
|
|
302
316
|
|
|
303
|
-
/**
|
|
304
|
-
* Get exit function (Bun.exit or process.exit)
|
|
305
|
-
*/
|
|
306
|
-
function getExitFn(): (code: number) => never {
|
|
307
|
-
const bunExit = (globalThis as { Bun?: { exit?: (code: number) => never } }).Bun?.exit;
|
|
308
|
-
return typeof bunExit === 'function' ? bunExit : process.exit.bind(process);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
317
|
/**
|
|
312
318
|
* Install interrupt handlers (SIGINT/SIGTERM + raw mode)
|
|
313
319
|
*/
|
|
@@ -367,19 +373,24 @@ async function runStepsTUI(steps: Step[]): Promise<void> {
|
|
|
367
373
|
let currentStepIndex = -1;
|
|
368
374
|
let currentFrameIndex = 0;
|
|
369
375
|
|
|
376
|
+
// Create abort controller for cooperative cancellation
|
|
377
|
+
const abortController = new AbortController();
|
|
378
|
+
|
|
370
379
|
// Hide cursor
|
|
371
380
|
process.stdout.write('\x1B[?25l');
|
|
372
381
|
|
|
373
382
|
// Set up interrupt handler
|
|
374
|
-
|
|
383
|
+
let restoreInterrupts: (() => void) | null = null;
|
|
375
384
|
const onInterrupt = () => {
|
|
376
385
|
if (interrupted) return;
|
|
377
386
|
interrupted = true;
|
|
387
|
+
abortController.abort();
|
|
378
388
|
if (activeInterval) clearInterval(activeInterval);
|
|
389
|
+
restoreInterrupts?.();
|
|
390
|
+
restoreInterrupts = null;
|
|
379
391
|
process.stdout.write('\x1B[?25h\n'); // Show cursor
|
|
380
|
-
exit(130);
|
|
381
392
|
};
|
|
382
|
-
|
|
393
|
+
restoreInterrupts = installInterruptHandlers(onInterrupt);
|
|
383
394
|
|
|
384
395
|
// Force re-render function
|
|
385
396
|
const forceRerender = (skipMove = false) => {
|
|
@@ -476,7 +487,10 @@ async function runStepsTUI(steps: Step[]): Promise<void> {
|
|
|
476
487
|
|
|
477
488
|
// Run the step
|
|
478
489
|
try {
|
|
479
|
-
const outcome = await step.run({
|
|
490
|
+
const outcome = await step.run({
|
|
491
|
+
progress: progressCallback,
|
|
492
|
+
signal: abortController.signal,
|
|
493
|
+
});
|
|
480
494
|
|
|
481
495
|
// Update state from outcome
|
|
482
496
|
if (outcome.status === 'success') {
|
|
@@ -493,6 +507,11 @@ async function runStepsTUI(steps: Step[]): Promise<void> {
|
|
|
493
507
|
stepState.output = outcome.output;
|
|
494
508
|
}
|
|
495
509
|
} catch (err) {
|
|
510
|
+
// If the step was aborted due to cancellation, treat as interrupt
|
|
511
|
+
if (err instanceof Error && err.name === 'AbortError') {
|
|
512
|
+
interrupted = true;
|
|
513
|
+
throw new StepInterruptError();
|
|
514
|
+
}
|
|
496
515
|
stepState.status = 'error';
|
|
497
516
|
stepState.errorMessage = err instanceof Error ? err.message : String(err);
|
|
498
517
|
stepState.errorCause = err instanceof Error ? err : undefined;
|
|
@@ -522,6 +541,14 @@ async function runStepsTUI(steps: Step[]): Promise<void> {
|
|
|
522
541
|
|
|
523
542
|
// Handle errors
|
|
524
543
|
if (stepState.status === 'error') {
|
|
544
|
+
// If the error is due to abort/cancellation, treat as interrupt
|
|
545
|
+
if (
|
|
546
|
+
stepState.errorCause instanceof Error &&
|
|
547
|
+
stepState.errorCause.name === 'AbortError'
|
|
548
|
+
) {
|
|
549
|
+
interrupted = true;
|
|
550
|
+
throw new StepInterruptError();
|
|
551
|
+
}
|
|
525
552
|
const errorColor = getColor('red');
|
|
526
553
|
const errorMsg = stepState.errorMessage || 'An unknown error occurred';
|
|
527
554
|
console.error(`\n${errorColor}Error: ${errorMsg}${COLORS.reset}`);
|
|
@@ -537,13 +564,19 @@ async function runStepsTUI(steps: Step[]): Promise<void> {
|
|
|
537
564
|
}
|
|
538
565
|
}
|
|
539
566
|
|
|
567
|
+
// If interrupted during step execution, throw so callers' finally blocks run
|
|
568
|
+
if (interrupted) {
|
|
569
|
+
throw new StepInterruptError();
|
|
570
|
+
}
|
|
571
|
+
|
|
540
572
|
// Show cursor
|
|
541
573
|
process.stdout.write('\x1B[?25h');
|
|
542
574
|
} catch (err) {
|
|
543
575
|
process.stdout.write('\x1B[?25h');
|
|
544
576
|
throw err;
|
|
545
577
|
} finally {
|
|
546
|
-
restoreInterrupts();
|
|
578
|
+
restoreInterrupts?.();
|
|
579
|
+
restoreInterrupts = null;
|
|
547
580
|
getTotalLinesFn = null; // Clear pause capability
|
|
548
581
|
forceRerenderFn = null;
|
|
549
582
|
}
|
|
@@ -558,76 +591,108 @@ async function runStepsPlain(steps: Step[]): Promise<void> {
|
|
|
558
591
|
const yellowColor = getColor('yellow');
|
|
559
592
|
const redColor = getColor('red');
|
|
560
593
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
cause: err instanceof Error ? err : undefined,
|
|
571
|
-
};
|
|
572
|
-
}
|
|
594
|
+
const abortController = new AbortController();
|
|
595
|
+
let interrupted = false;
|
|
596
|
+
const onInterrupt = () => {
|
|
597
|
+
if (interrupted) return;
|
|
598
|
+
interrupted = true;
|
|
599
|
+
abortController.abort();
|
|
600
|
+
};
|
|
601
|
+
process.on('SIGINT', onInterrupt);
|
|
602
|
+
process.on('SIGTERM', onInterrupt);
|
|
573
603
|
|
|
574
|
-
|
|
575
|
-
const
|
|
576
|
-
|
|
577
|
-
status: outcome.status,
|
|
578
|
-
output: outcome.output,
|
|
579
|
-
skipReason: outcome.status === 'skipped' ? outcome.reason : undefined,
|
|
580
|
-
errorMessage: outcome.status === 'error' ? outcome.message : undefined,
|
|
581
|
-
errorCause: outcome.status === 'error' ? outcome.cause : undefined,
|
|
582
|
-
};
|
|
604
|
+
try {
|
|
605
|
+
for (const step of steps) {
|
|
606
|
+
if (abortController.signal.aborted) break;
|
|
583
607
|
|
|
584
|
-
|
|
585
|
-
emitCleanStepLog(stepState);
|
|
608
|
+
let outcome: StepOutcome;
|
|
586
609
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
610
|
+
try {
|
|
611
|
+
outcome = await step.run({ progress: () => {}, signal: abortController.signal });
|
|
612
|
+
} catch (err) {
|
|
613
|
+
// If the step was aborted due to cancellation, treat as interrupt
|
|
614
|
+
if (err instanceof Error && err.name === 'AbortError') {
|
|
615
|
+
interrupted = true;
|
|
616
|
+
throw new StepInterruptError();
|
|
594
617
|
}
|
|
595
|
-
|
|
596
|
-
|
|
618
|
+
outcome = {
|
|
619
|
+
status: 'error',
|
|
620
|
+
message: err instanceof Error ? err.message : String(err),
|
|
621
|
+
cause: err instanceof Error ? err : undefined,
|
|
622
|
+
};
|
|
597
623
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
624
|
+
|
|
625
|
+
// Build step state for clean log emission
|
|
626
|
+
const stepState: StepState = {
|
|
627
|
+
label: step.label,
|
|
628
|
+
status: outcome.status,
|
|
629
|
+
output: outcome.output,
|
|
630
|
+
skipReason: outcome.status === 'skipped' ? outcome.reason : undefined,
|
|
631
|
+
errorMessage: outcome.status === 'error' ? outcome.message : undefined,
|
|
632
|
+
errorCause: outcome.status === 'error' ? outcome.cause : undefined,
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
// Emit clean log for this step
|
|
636
|
+
emitCleanStepLog(stepState);
|
|
637
|
+
|
|
638
|
+
// Print final state
|
|
639
|
+
if (outcome.status === 'success') {
|
|
640
|
+
console.log(`${greenColor}${ICONS.success}${COLORS.reset} ${step.label}`);
|
|
641
|
+
if (outcome.output && outcome.output.length > 0) {
|
|
642
|
+
console.log(`${grayColor}╭─ Output${COLORS.reset}`);
|
|
643
|
+
for (const line of outcome.output) {
|
|
644
|
+
console.log(`${grayColor}│${COLORS.reset} ${line}`);
|
|
645
|
+
}
|
|
646
|
+
console.log(`${grayColor}╰─${COLORS.reset}`);
|
|
647
|
+
console.log('');
|
|
605
648
|
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
console.log(`${grayColor}
|
|
649
|
+
} else if (outcome.status === 'skipped') {
|
|
650
|
+
const reason = outcome.reason ? ` ${grayColor}(${outcome.reason})${COLORS.reset}` : '';
|
|
651
|
+
console.log(`${yellowColor}${ICONS.skipped}${COLORS.reset} ${step.label}${reason}`);
|
|
652
|
+
if (outcome.output && outcome.output.length > 0) {
|
|
653
|
+
console.log(`${grayColor}╭─ Output${COLORS.reset}`);
|
|
654
|
+
for (const line of outcome.output) {
|
|
655
|
+
console.log(`${grayColor}│${COLORS.reset} ${line}`);
|
|
656
|
+
}
|
|
657
|
+
console.log(`${grayColor}╰─${COLORS.reset}`);
|
|
658
|
+
console.log('');
|
|
615
659
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
outcome.
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
660
|
+
} else {
|
|
661
|
+
// If the error is due to abort/cancellation, treat as interrupt
|
|
662
|
+
if (outcome.cause instanceof Error && outcome.cause.name === 'AbortError') {
|
|
663
|
+
interrupted = true;
|
|
664
|
+
throw new StepInterruptError();
|
|
665
|
+
}
|
|
666
|
+
console.log(`${redColor}${ICONS.error}${COLORS.reset} ${step.label}`);
|
|
667
|
+
if (outcome.output && outcome.output.length > 0) {
|
|
668
|
+
console.log(`${grayColor}╭─ Output${COLORS.reset}`);
|
|
669
|
+
for (const line of outcome.output) {
|
|
670
|
+
console.log(`${grayColor}│${COLORS.reset} ${line}`);
|
|
671
|
+
}
|
|
672
|
+
console.log(`${grayColor}╰─${COLORS.reset}`);
|
|
673
|
+
console.log('');
|
|
674
|
+
}
|
|
675
|
+
const errorColor = getColor('red');
|
|
676
|
+
const errorMsg = outcome.message || 'An unknown error occurred';
|
|
677
|
+
console.error(`\n${errorColor}Error: ${errorMsg}${COLORS.reset}`);
|
|
678
|
+
if (
|
|
679
|
+
outcome.cause instanceof ValidationInputError ||
|
|
680
|
+
outcome.cause instanceof ValidationOutputError
|
|
681
|
+
) {
|
|
682
|
+
printValidationIssues(outcome.cause.issues);
|
|
683
|
+
}
|
|
684
|
+
console.error('');
|
|
685
|
+
process.exit(1);
|
|
627
686
|
}
|
|
628
|
-
console.error('');
|
|
629
|
-
process.exit(1);
|
|
630
687
|
}
|
|
688
|
+
|
|
689
|
+
// If interrupted during step execution, throw so callers' finally blocks run
|
|
690
|
+
if (interrupted) {
|
|
691
|
+
throw new StepInterruptError();
|
|
692
|
+
}
|
|
693
|
+
} finally {
|
|
694
|
+
process.off('SIGINT', onInterrupt);
|
|
695
|
+
process.off('SIGTERM', onInterrupt);
|
|
631
696
|
}
|
|
632
697
|
}
|
|
633
698
|
|
package/src/tui.ts
CHANGED
|
@@ -737,7 +737,7 @@ export function banner(title: string, body: string, options?: BannerOptions): vo
|
|
|
737
737
|
/**
|
|
738
738
|
* Wait for any key press before continuing
|
|
739
739
|
* Displays a prompt message and waits for user input
|
|
740
|
-
*
|
|
740
|
+
* Raises SIGINT if CTRL+C is pressed
|
|
741
741
|
*/
|
|
742
742
|
export async function waitForAnyKey(message = 'Press Enter to continue...'): Promise<void> {
|
|
743
743
|
process.stdout.write(muted(message));
|
|
@@ -765,7 +765,8 @@ export async function waitForAnyKey(message = 'Press Enter to continue...'): Pro
|
|
|
765
765
|
// Check for CTRL+C (character code 3)
|
|
766
766
|
if (data.length === 1 && data[0] === 3) {
|
|
767
767
|
console.log('\n');
|
|
768
|
-
process.
|
|
768
|
+
process.kill(process.pid, 'SIGINT');
|
|
769
|
+
return;
|
|
769
770
|
}
|
|
770
771
|
|
|
771
772
|
console.log('');
|
|
@@ -777,7 +778,7 @@ export async function waitForAnyKey(message = 'Press Enter to continue...'): Pro
|
|
|
777
778
|
/**
|
|
778
779
|
* Prompts user with a yes/no question
|
|
779
780
|
* Returns true for yes, false for no
|
|
780
|
-
*
|
|
781
|
+
* Raises SIGINT if CTRL+C is pressed
|
|
781
782
|
*/
|
|
782
783
|
export async function confirm(message: string, defaultValue = true): Promise<boolean> {
|
|
783
784
|
const suffix = defaultValue ? '[Y/n]' : '[y/N]';
|
|
@@ -805,7 +806,8 @@ export async function confirm(message: string, defaultValue = true): Promise<boo
|
|
|
805
806
|
// Check for CTRL+C (character code 3)
|
|
806
807
|
if (data.length === 1 && data[0] === 3) {
|
|
807
808
|
console.log('\n');
|
|
808
|
-
process.
|
|
809
|
+
process.kill(process.pid, 'SIGINT');
|
|
810
|
+
return;
|
|
809
811
|
}
|
|
810
812
|
|
|
811
813
|
const input = data.toString().trim().toLowerCase();
|
package/src/version-check.ts
CHANGED
|
@@ -4,7 +4,6 @@ import { fetchLatestVersion } from './cmd/upgrade';
|
|
|
4
4
|
import { getVersion, getCompareUrl, getReleaseUrl, toTag } from './version';
|
|
5
5
|
import * as tui from './tui';
|
|
6
6
|
import { saveConfig } from './config';
|
|
7
|
-
import { $ } from 'bun';
|
|
8
7
|
import { tmpdir } from 'node:os';
|
|
9
8
|
import { getExecutingAgent } from './agent-detection';
|
|
10
9
|
|
|
@@ -174,13 +173,14 @@ async function performUpgrade(logger: Logger, targetVersion: string): Promise<vo
|
|
|
174
173
|
|
|
175
174
|
// Use bun to install the specific version globally with retry for CDN propagation delays
|
|
176
175
|
// Run from tmpdir to avoid interference from any local package.json/node_modules
|
|
177
|
-
const { installWithRetry } = await import('./cmd/upgrade/npm-availability');
|
|
176
|
+
const { installWithRetry, spawnWithTimeout } = await import('./cmd/upgrade/npm-availability');
|
|
178
177
|
await installWithRetry(
|
|
179
178
|
async () => {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
179
|
+
// spawnWithTimeout kills the process if it exceeds 30s
|
|
180
|
+
const result = await spawnWithTimeout(
|
|
181
|
+
['bun', 'add', '-g', `@agentuity/cli@${npmVersion}`],
|
|
182
|
+
{ cwd: tmpdir(), timeout: 30_000 }
|
|
183
|
+
);
|
|
184
184
|
return { exitCode: result.exitCode, stderr: result.stderr };
|
|
185
185
|
},
|
|
186
186
|
{
|