braeburn 1.4.2 → 1.4.3
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/commands/update.js +19 -2
- package/dist/ui/activityIndicator.d.ts +1 -0
- package/dist/ui/activityIndicator.js +5 -0
- package/dist/ui/currentStep.d.ts +1 -0
- package/dist/ui/currentStep.js +3 -1
- package/dist/ui/header.d.ts +2 -1
- package/dist/ui/header.js +7 -5
- package/dist/ui/screen.d.ts +1 -0
- package/dist/ui/screen.js +5 -0
- package/package.json +1 -1
package/dist/commands/update.js
CHANGED
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
import { collectVersions } from "../update/versionCollector.js";
|
|
2
2
|
import { captureYesNo } from "../ui/prompt.js";
|
|
3
|
-
import { buildScreen, createScreenRenderer } from "../ui/screen.js";
|
|
3
|
+
import { buildScreen, buildScreenWithAnimationFrame, createScreenRenderer } from "../ui/screen.js";
|
|
4
4
|
import { hideCursorDuringExecution } from "../ui/terminal.js";
|
|
5
5
|
import { runUpdateEngine } from "../update/engine.js";
|
|
6
6
|
export async function runUpdateCommand(options) {
|
|
7
7
|
const renderScreen = createScreenRenderer();
|
|
8
8
|
const restoreCursor = hideCursorDuringExecution({ screenBuffer: "alternate" });
|
|
9
9
|
let finalScreen = "";
|
|
10
|
+
let latestState = undefined;
|
|
11
|
+
let animationFrameIndex = 0;
|
|
12
|
+
const animationTimer = setInterval(() => {
|
|
13
|
+
if (!latestState) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (latestState.runCompletion === "finished") {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (latestState.currentPhase !== "running" && latestState.currentPhase !== "installing") {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
animationFrameIndex += 1;
|
|
23
|
+
renderScreen(buildScreenWithAnimationFrame(latestState, animationFrameIndex));
|
|
24
|
+
}, 100);
|
|
10
25
|
try {
|
|
11
26
|
const finalState = await runUpdateEngine({
|
|
12
27
|
steps: options.steps,
|
|
@@ -16,12 +31,14 @@ export async function runUpdateCommand(options) {
|
|
|
16
31
|
askForConfirmation: captureYesNo,
|
|
17
32
|
collectVersions,
|
|
18
33
|
onStateChanged: (state) => {
|
|
19
|
-
|
|
34
|
+
latestState = state;
|
|
35
|
+
renderScreen(buildScreenWithAnimationFrame(state, animationFrameIndex));
|
|
20
36
|
},
|
|
21
37
|
});
|
|
22
38
|
finalScreen = buildScreen(finalState);
|
|
23
39
|
}
|
|
24
40
|
finally {
|
|
41
|
+
clearInterval(animationTimer);
|
|
25
42
|
restoreCursor();
|
|
26
43
|
}
|
|
27
44
|
if (finalScreen) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getActivityIndicatorFrame(frameIndex: number): string;
|
package/dist/ui/currentStep.d.ts
CHANGED
package/dist/ui/currentStep.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
+
import { getActivityIndicatorFrame } from "./activityIndicator.js";
|
|
2
3
|
export function buildActiveStepLines(options) {
|
|
3
4
|
const { step, stepNumber, totalSteps, phase } = options;
|
|
5
|
+
const activityFrameIndex = options.activityFrameIndex ?? 0;
|
|
4
6
|
const isRunning = phase === "running" || phase === "installing";
|
|
5
7
|
const lines = [
|
|
6
8
|
chalk.dim(` ${"─".repeat(3)} Step ${stepNumber}/${totalSteps} `) +
|
|
@@ -10,7 +12,7 @@ export function buildActiveStepLines(options) {
|
|
|
10
12
|
];
|
|
11
13
|
if (isRunning) {
|
|
12
14
|
const label = phase === "installing" ? "Installing..." : "Running...";
|
|
13
|
-
lines.push(` ${chalk.blue(
|
|
15
|
+
lines.push(` ${chalk.blue(getActivityIndicatorFrame(activityFrameIndex))} ${label}`);
|
|
14
16
|
}
|
|
15
17
|
return lines;
|
|
16
18
|
}
|
package/dist/ui/header.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { DisplayStep, StepPhase, CompletedStepRecord, LogoVisibility } from
|
|
|
2
2
|
import type { TerminalDimensions } from "./outputBox.js";
|
|
3
3
|
type LogoLayout = "side-by-side" | "stacked" | "none";
|
|
4
4
|
export declare function determineLogoLayout(logoLines: string[], dimensions?: TerminalDimensions): LogoLayout;
|
|
5
|
-
export declare function stepTrackerIcon(phase: StepPhase): string;
|
|
5
|
+
export declare function stepTrackerIcon(phase: StepPhase, activityFrameIndex?: number): string;
|
|
6
6
|
export declare function isActivePhase(phase: StepPhase): boolean;
|
|
7
7
|
export declare function deriveAllStepPhases(steps: DisplayStep[], currentStepIndex: number, currentPhase: StepPhase, completedStepRecords: CompletedStepRecord[]): StepPhase[];
|
|
8
8
|
type BuildHeaderOptions = {
|
|
@@ -12,6 +12,7 @@ type BuildHeaderOptions = {
|
|
|
12
12
|
currentStepIndex: number;
|
|
13
13
|
currentPhase: StepPhase;
|
|
14
14
|
completedStepRecords: CompletedStepRecord[];
|
|
15
|
+
activityFrameIndex?: number;
|
|
15
16
|
terminalDimensions?: TerminalDimensions;
|
|
16
17
|
};
|
|
17
18
|
export declare function buildHeaderLines(options: BuildHeaderOptions): string[];
|
package/dist/ui/header.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { LOGO_ART } from "../logo.js";
|
|
3
|
+
import { getActivityIndicatorFrame } from "./activityIndicator.js";
|
|
3
4
|
const LOGO_COLUMN_WIDTH = 32;
|
|
4
5
|
const LOGO_SEPARATOR = " ";
|
|
5
6
|
const MIN_SIDE_BY_SIDE_COLS = LOGO_COLUMN_WIDTH + LOGO_SEPARATOR.length + 20; // 56
|
|
@@ -14,16 +15,16 @@ export function determineLogoLayout(logoLines, dimensions) {
|
|
|
14
15
|
}
|
|
15
16
|
return "none";
|
|
16
17
|
}
|
|
17
|
-
export function stepTrackerIcon(phase) {
|
|
18
|
+
export function stepTrackerIcon(phase, activityFrameIndex = 0) {
|
|
18
19
|
if (phase === "complete")
|
|
19
20
|
return chalk.green("✓ ");
|
|
20
21
|
if (phase === "failed")
|
|
21
22
|
return chalk.red("✗ ");
|
|
22
23
|
if (phase === "skipped" || phase === "not-available")
|
|
23
24
|
return chalk.dim("– ");
|
|
24
|
-
if (phase === "running" ||
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
if (phase === "running" || phase === "installing")
|
|
26
|
+
return chalk.cyan(`${getActivityIndicatorFrame(activityFrameIndex)} `);
|
|
27
|
+
if (phase === "prompting-to-run" ||
|
|
27
28
|
phase === "prompting-to-install" ||
|
|
28
29
|
phase === "checking-availability")
|
|
29
30
|
return chalk.cyan("→ ");
|
|
@@ -47,6 +48,7 @@ export function deriveAllStepPhases(steps, currentStepIndex, currentPhase, compl
|
|
|
47
48
|
}
|
|
48
49
|
export function buildHeaderLines(options) {
|
|
49
50
|
const { steps, version, logoVisibility, currentStepIndex, currentPhase, completedStepRecords } = options;
|
|
51
|
+
const activityFrameIndex = options.activityFrameIndex ?? 0;
|
|
50
52
|
const phases = deriveAllStepPhases(steps, currentStepIndex, currentPhase, completedStepRecords);
|
|
51
53
|
const hasRuntimeSteps = steps.some((step) => step.stage === "runtime");
|
|
52
54
|
const hasToolsSteps = steps.some((step) => step.stage === "tools");
|
|
@@ -64,7 +66,7 @@ export function buildHeaderLines(options) {
|
|
|
64
66
|
stepLines.push(chalk.dim("Tools"));
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
|
-
const icon = stepTrackerIcon(phases[stepIndex]);
|
|
69
|
+
const icon = stepTrackerIcon(phases[stepIndex], activityFrameIndex);
|
|
68
70
|
const name = isActivePhase(phases[stepIndex]) ? chalk.white(step.name) : chalk.dim(step.name);
|
|
69
71
|
stepLines.push(`${icon}${name}`);
|
|
70
72
|
}
|
package/dist/ui/screen.d.ts
CHANGED
|
@@ -3,3 +3,4 @@ import type { AppState } from "./state.js";
|
|
|
3
3
|
export type ScreenRenderer = (content: string) => void;
|
|
4
4
|
export declare function createScreenRenderer(output?: NodeJS.WritableStream): ScreenRenderer;
|
|
5
5
|
export declare function buildScreen(state: AppState, terminalDimensions?: TerminalDimensions): string;
|
|
6
|
+
export declare function buildScreenWithAnimationFrame(state: AppState, activityFrameIndex: number, terminalDimensions?: TerminalDimensions): string;
|
package/dist/ui/screen.js
CHANGED
|
@@ -10,6 +10,9 @@ export function createScreenRenderer(output = process.stdout) {
|
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
export function buildScreen(state, terminalDimensions) {
|
|
13
|
+
return buildScreenWithAnimationFrame(state, 0, terminalDimensions);
|
|
14
|
+
}
|
|
15
|
+
export function buildScreenWithAnimationFrame(state, activityFrameIndex, terminalDimensions) {
|
|
13
16
|
const lines = [];
|
|
14
17
|
const failedStepIds = state.completedStepRecords.flatMap((record, stepIndex) => {
|
|
15
18
|
if (record.phase !== "failed") {
|
|
@@ -28,6 +31,7 @@ export function buildScreen(state, terminalDimensions) {
|
|
|
28
31
|
currentStepIndex: state.currentStepIndex,
|
|
29
32
|
currentPhase: state.currentPhase,
|
|
30
33
|
completedStepRecords: state.completedStepRecords,
|
|
34
|
+
activityFrameIndex,
|
|
31
35
|
terminalDimensions,
|
|
32
36
|
}));
|
|
33
37
|
lines.push("");
|
|
@@ -50,6 +54,7 @@ export function buildScreen(state, terminalDimensions) {
|
|
|
50
54
|
stepNumber: state.currentStepIndex + 1,
|
|
51
55
|
totalSteps: state.steps.length,
|
|
52
56
|
phase: state.currentPhase,
|
|
57
|
+
activityFrameIndex,
|
|
53
58
|
}));
|
|
54
59
|
const isShowingOutput = (state.currentPhase === "running" || state.currentPhase === "installing") &&
|
|
55
60
|
state.currentOutputLines.length > 0;
|