rackmind-cli 0.1.2
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 +179 -0
- package/bin/rackmind.js +6 -0
- package/dist/ai/client.d.ts +71 -0
- package/dist/ai/client.d.ts.map +1 -0
- package/dist/ai/client.js +198 -0
- package/dist/ai/client.js.map +1 -0
- package/dist/ai/system-prompt.d.ts +20 -0
- package/dist/ai/system-prompt.d.ts.map +1 -0
- package/dist/ai/system-prompt.js +169 -0
- package/dist/ai/system-prompt.js.map +1 -0
- package/dist/ai/tool-executor.d.ts +27 -0
- package/dist/ai/tool-executor.d.ts.map +1 -0
- package/dist/ai/tool-executor.js +184 -0
- package/dist/ai/tool-executor.js.map +1 -0
- package/dist/ai/tools.d.ts +7 -0
- package/dist/ai/tools.d.ts.map +1 -0
- package/dist/ai/tools.js +203 -0
- package/dist/ai/tools.js.map +1 -0
- package/dist/commands/config.d.ts +21 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +169 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/connect.d.ts +7 -0
- package/dist/commands/connect.d.ts.map +1 -0
- package/dist/commands/connect.js +117 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/containers.d.ts +5 -0
- package/dist/commands/containers.d.ts.map +1 -0
- package/dist/commands/containers.js +83 -0
- package/dist/commands/containers.js.map +1 -0
- package/dist/commands/exec.d.ts +5 -0
- package/dist/commands/exec.d.ts.map +1 -0
- package/dist/commands/exec.js +133 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/lifecycle.d.ts +7 -0
- package/dist/commands/lifecycle.d.ts.map +1 -0
- package/dist/commands/lifecycle.js +213 -0
- package/dist/commands/lifecycle.js.map +1 -0
- package/dist/commands/logs.d.ts +5 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +117 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/report.d.ts +6 -0
- package/dist/commands/report.d.ts.map +1 -0
- package/dist/commands/report.js +203 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/servers.d.ts +17 -0
- package/dist/commands/servers.d.ts.map +1 -0
- package/dist/commands/servers.js +116 -0
- package/dist/commands/servers.js.map +1 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +174 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/vms.d.ts +5 -0
- package/dist/commands/vms.d.ts.map +1 -0
- package/dist/commands/vms.js +83 -0
- package/dist/commands/vms.js.map +1 -0
- package/dist/config/crypto.d.ts +20 -0
- package/dist/config/crypto.d.ts.map +1 -0
- package/dist/config/crypto.js +78 -0
- package/dist/config/crypto.js.map +1 -0
- package/dist/config/index.d.ts +21 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +158 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/types.d.ts +263 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +83 -0
- package/dist/config/types.js.map +1 -0
- package/dist/globals.d.ts +22 -0
- package/dist/globals.d.ts.map +1 -0
- package/dist/globals.js +43 -0
- package/dist/globals.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +399 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive/App.d.ts +3 -0
- package/dist/interactive/App.d.ts.map +1 -0
- package/dist/interactive/App.js +103 -0
- package/dist/interactive/App.js.map +1 -0
- package/dist/interactive/components/Header.d.ts +8 -0
- package/dist/interactive/components/Header.d.ts.map +1 -0
- package/dist/interactive/components/Header.js +20 -0
- package/dist/interactive/components/Header.js.map +1 -0
- package/dist/interactive/components/InputBar.d.ts +9 -0
- package/dist/interactive/components/InputBar.d.ts.map +1 -0
- package/dist/interactive/components/InputBar.js +89 -0
- package/dist/interactive/components/InputBar.js.map +1 -0
- package/dist/interactive/components/MessageList.d.ts +9 -0
- package/dist/interactive/components/MessageList.d.ts.map +1 -0
- package/dist/interactive/components/MessageList.js +28 -0
- package/dist/interactive/components/MessageList.js.map +1 -0
- package/dist/interactive/components/Spinner.d.ts +7 -0
- package/dist/interactive/components/Spinner.d.ts.map +1 -0
- package/dist/interactive/components/Spinner.js +19 -0
- package/dist/interactive/components/Spinner.js.map +1 -0
- package/dist/interactive/components/StatusBar.d.ts +10 -0
- package/dist/interactive/components/StatusBar.d.ts.map +1 -0
- package/dist/interactive/components/StatusBar.js +7 -0
- package/dist/interactive/components/StatusBar.js.map +1 -0
- package/dist/interactive/components/StreamingMessage.d.ts +7 -0
- package/dist/interactive/components/StreamingMessage.d.ts.map +1 -0
- package/dist/interactive/components/StreamingMessage.js +9 -0
- package/dist/interactive/components/StreamingMessage.js.map +1 -0
- package/dist/interactive/components/ToolIndicator.d.ts +7 -0
- package/dist/interactive/components/ToolIndicator.d.ts.map +1 -0
- package/dist/interactive/components/ToolIndicator.js +10 -0
- package/dist/interactive/components/ToolIndicator.js.map +1 -0
- package/dist/interactive/components/ToolOutput.d.ts +8 -0
- package/dist/interactive/components/ToolOutput.d.ts.map +1 -0
- package/dist/interactive/components/ToolOutput.js +9 -0
- package/dist/interactive/components/ToolOutput.js.map +1 -0
- package/dist/interactive/components/WelcomeScreen.d.ts +9 -0
- package/dist/interactive/components/WelcomeScreen.d.ts.map +1 -0
- package/dist/interactive/components/WelcomeScreen.js +8 -0
- package/dist/interactive/components/WelcomeScreen.js.map +1 -0
- package/dist/interactive/launch.d.ts +6 -0
- package/dist/interactive/launch.d.ts.map +1 -0
- package/dist/interactive/launch.js +30 -0
- package/dist/interactive/launch.js.map +1 -0
- package/dist/interactive/slashCommands.d.ts +13 -0
- package/dist/interactive/slashCommands.d.ts.map +1 -0
- package/dist/interactive/slashCommands.js +102 -0
- package/dist/interactive/slashCommands.js.map +1 -0
- package/dist/interactive/useRackMind.d.ts +30 -0
- package/dist/interactive/useRackMind.d.ts.map +1 -0
- package/dist/interactive/useRackMind.js +241 -0
- package/dist/interactive/useRackMind.js.map +1 -0
- package/dist/oneshot/run.d.ts +2 -0
- package/dist/oneshot/run.d.ts.map +1 -0
- package/dist/oneshot/run.js +195 -0
- package/dist/oneshot/run.js.map +1 -0
- package/dist/server/client.d.ts +89 -0
- package/dist/server/client.d.ts.map +1 -0
- package/dist/server/client.js +239 -0
- package/dist/server/client.js.map +1 -0
- package/dist/server/proxmox.d.ts +160 -0
- package/dist/server/proxmox.d.ts.map +1 -0
- package/dist/server/proxmox.js +219 -0
- package/dist/server/proxmox.js.map +1 -0
- package/dist/server/ssh.d.ts +80 -0
- package/dist/server/ssh.d.ts.map +1 -0
- package/dist/server/ssh.js +262 -0
- package/dist/server/ssh.js.map +1 -0
- package/dist/utils/ascii.d.ts +3 -0
- package/dist/utils/ascii.d.ts.map +1 -0
- package/dist/utils/ascii.js +16 -0
- package/dist/utils/ascii.js.map +1 -0
- package/dist/utils/format.d.ts +7 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +20 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/history.d.ts +23 -0
- package/dist/utils/history.d.ts.map +1 -0
- package/dist/utils/history.js +107 -0
- package/dist/utils/history.js.map +1 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +51 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/markdown.d.ts +12 -0
- package/dist/utils/markdown.d.ts.map +1 -0
- package/dist/utils/markdown.js +76 -0
- package/dist/utils/markdown.js.map +1 -0
- package/dist/utils/prompt.d.ts +25 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +133 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/retry.d.ts +37 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +122 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/shutdown.d.ts +22 -0
- package/dist/utils/shutdown.d.ts.map +1 -0
- package/dist/utils/shutdown.js +94 -0
- package/dist/utils/shutdown.js.map +1 -0
- package/dist/utils/table.d.ts +38 -0
- package/dist/utils/table.d.ts.map +1 -0
- package/dist/utils/table.js +150 -0
- package/dist/utils/table.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render a markdown string to terminal-formatted output.
|
|
3
|
+
* Handles code blocks, bold, italic, lists, headers, links, etc.
|
|
4
|
+
*/
|
|
5
|
+
export declare function renderMarkdown(text: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Render markdown for streaming output — handles partial markdown gracefully.
|
|
8
|
+
* This is less aggressive than full rendering to avoid broken partial blocks.
|
|
9
|
+
* Applies inline formatting only (bold, italic, code spans).
|
|
10
|
+
*/
|
|
11
|
+
export declare function renderMarkdownInline(text: string): string;
|
|
12
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"AA4CA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiBnD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYzD"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Markdown rendering — converts AI markdown responses to terminal output
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Uses `marked` + `marked-terminal` for rendering markdown with proper
|
|
5
|
+
// formatting: headers, bold, italic, lists, code blocks with syntax
|
|
6
|
+
// highlighting via `marked-terminal`.
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
import { marked } from 'marked';
|
|
9
|
+
import { markedTerminal } from 'marked-terminal';
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Initialization — configure marked with terminal renderer
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
let initialized = false;
|
|
15
|
+
function ensureInitialized() {
|
|
16
|
+
if (initialized)
|
|
17
|
+
return;
|
|
18
|
+
// marked-terminal returns an object with { renderer, useNewRenderer }
|
|
19
|
+
// but @types/marked-terminal declares it as returning TerminalRenderer.
|
|
20
|
+
// Cast to MarkedExtension to satisfy TypeScript — runtime is correct.
|
|
21
|
+
const terminalExtension = markedTerminal({
|
|
22
|
+
// Style overrides for terminal rendering
|
|
23
|
+
strong: chalk.bold,
|
|
24
|
+
em: chalk.italic,
|
|
25
|
+
heading: chalk.cyan.bold,
|
|
26
|
+
hr: () => chalk.dim('-'.repeat(60)),
|
|
27
|
+
tableOptions: {
|
|
28
|
+
style: { head: ['cyan'] },
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
marked.use(terminalExtension);
|
|
32
|
+
initialized = true;
|
|
33
|
+
}
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Public API
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
/**
|
|
38
|
+
* Render a markdown string to terminal-formatted output.
|
|
39
|
+
* Handles code blocks, bold, italic, lists, headers, links, etc.
|
|
40
|
+
*/
|
|
41
|
+
export function renderMarkdown(text) {
|
|
42
|
+
ensureInitialized();
|
|
43
|
+
try {
|
|
44
|
+
const rendered = marked.parse(text);
|
|
45
|
+
if (typeof rendered !== 'string') {
|
|
46
|
+
// marked.parse can return a Promise if async extensions are used;
|
|
47
|
+
// we only use synchronous extensions, so this shouldn't happen
|
|
48
|
+
return text;
|
|
49
|
+
}
|
|
50
|
+
// Trim trailing whitespace but preserve structure
|
|
51
|
+
return rendered.replace(/\n{3,}/g, '\n\n').trimEnd();
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// If rendering fails, return the raw text
|
|
55
|
+
return text;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Render markdown for streaming output — handles partial markdown gracefully.
|
|
60
|
+
* This is less aggressive than full rendering to avoid broken partial blocks.
|
|
61
|
+
* Applies inline formatting only (bold, italic, code spans).
|
|
62
|
+
*/
|
|
63
|
+
export function renderMarkdownInline(text) {
|
|
64
|
+
ensureInitialized();
|
|
65
|
+
try {
|
|
66
|
+
const rendered = marked.parseInline(text);
|
|
67
|
+
if (typeof rendered !== 'string') {
|
|
68
|
+
return text;
|
|
69
|
+
}
|
|
70
|
+
return rendered;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return text;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,yEAAyE;AACzE,8EAA8E;AAC9E,uEAAuE;AACvE,oEAAoE;AACpE,sCAAsC;AACtC,8EAA8E;AAE9E,OAAO,EAAE,MAAM,EAAwB,MAAM,QAAQ,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,8EAA8E;AAC9E,2DAA2D;AAC3D,8EAA8E;AAE9E,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,SAAS,iBAAiB;IACtB,IAAI,WAAW;QAAE,OAAO;IAExB,sEAAsE;IACtE,wEAAwE;IACxE,sEAAsE;IACtE,MAAM,iBAAiB,GAAG,cAAc,CAAC;QACrC,yCAAyC;QACzC,MAAM,EAAE,KAAK,CAAC,IAAI;QAClB,EAAE,EAAE,KAAK,CAAC,MAAM;QAChB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI;QACxB,EAAE,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnC,YAAY,EAAE;YACV,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE;SAC5B;KACJ,CAA+B,CAAC;IAEjC,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAE9B,WAAW,GAAG,IAAI,CAAC;AACvB,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACvC,iBAAiB,EAAE,CAAC;IAEpB,IAAI,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC/B,kEAAkE;YAClE,+DAA+D;YAC/D,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,kDAAkD;QAClD,OAAO,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACL,0CAA0C;QAC1C,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC7C,iBAAiB,EAAE,CAAC;IAEpB,IAAI,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,QAAQ,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt for a text value. Returns the trimmed input or the default value.
|
|
3
|
+
*/
|
|
4
|
+
export declare function promptText(message: string, defaultValue?: string): Promise<string>;
|
|
5
|
+
/**
|
|
6
|
+
* Prompt for a number. Returns the parsed number or the default value.
|
|
7
|
+
*/
|
|
8
|
+
export declare function promptNumber(message: string, defaultValue: number): Promise<number>;
|
|
9
|
+
/**
|
|
10
|
+
* Prompt for a secret value (password, token). Masks input with asterisks.
|
|
11
|
+
*/
|
|
12
|
+
export declare function promptSecret(message: string): Promise<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Prompt for a yes/no confirmation. Returns true for yes.
|
|
15
|
+
*/
|
|
16
|
+
export declare function promptConfirm(message: string, defaultYes?: boolean): Promise<boolean>;
|
|
17
|
+
/**
|
|
18
|
+
* Prompt for a selection from a list of options.
|
|
19
|
+
* Returns the selected option value.
|
|
20
|
+
*/
|
|
21
|
+
export declare function promptSelect<T extends string>(message: string, options: Array<{
|
|
22
|
+
label: string;
|
|
23
|
+
value: T;
|
|
24
|
+
}>, defaultValue?: T): Promise<T>;
|
|
25
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"AAgBA;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAWlF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIzF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkE7D;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,UAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAMzF;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC/C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC,EAC3C,YAAY,CAAC,EAAE,CAAC,GACjB,OAAO,CAAC,CAAC,CAAC,CAsBZ"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Interactive prompts — minimal readline-based prompts for CLI flows
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Uses Node's built-in readline module. No external deps needed.
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
import readline from 'node:readline';
|
|
7
|
+
function createInterface() {
|
|
8
|
+
return readline.createInterface({
|
|
9
|
+
input: process.stdin,
|
|
10
|
+
output: process.stderr, // prompts go to stderr so stdout stays pipeable
|
|
11
|
+
terminal: true,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Prompt for a text value. Returns the trimmed input or the default value.
|
|
16
|
+
*/
|
|
17
|
+
export function promptText(message, defaultValue) {
|
|
18
|
+
const rl = createInterface();
|
|
19
|
+
const suffix = defaultValue ? ` (${defaultValue})` : '';
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
rl.question(`${message}${suffix}: `, (answer) => {
|
|
22
|
+
rl.close();
|
|
23
|
+
const trimmed = answer.trim();
|
|
24
|
+
resolve(trimmed || defaultValue || '');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Prompt for a number. Returns the parsed number or the default value.
|
|
30
|
+
*/
|
|
31
|
+
export async function promptNumber(message, defaultValue) {
|
|
32
|
+
const raw = await promptText(message, String(defaultValue));
|
|
33
|
+
const parsed = parseInt(raw, 10);
|
|
34
|
+
return isNaN(parsed) ? defaultValue : parsed;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Prompt for a secret value (password, token). Masks input with asterisks.
|
|
38
|
+
*/
|
|
39
|
+
export function promptSecret(message) {
|
|
40
|
+
return new Promise((resolve) => {
|
|
41
|
+
const rl = readline.createInterface({
|
|
42
|
+
input: process.stdin,
|
|
43
|
+
output: process.stderr,
|
|
44
|
+
terminal: true,
|
|
45
|
+
});
|
|
46
|
+
// Mask input characters
|
|
47
|
+
const originalWrite = rl.write.bind(rl);
|
|
48
|
+
let masked = false;
|
|
49
|
+
process.stderr.write(`${message}: `);
|
|
50
|
+
masked = true;
|
|
51
|
+
// We need to handle the raw mode ourselves for masking
|
|
52
|
+
if (process.stdin.isTTY) {
|
|
53
|
+
process.stdin.setRawMode(true);
|
|
54
|
+
}
|
|
55
|
+
let secret = '';
|
|
56
|
+
const onData = (key) => {
|
|
57
|
+
const char = key.toString('utf8');
|
|
58
|
+
if (char === '\n' || char === '\r') {
|
|
59
|
+
// Enter pressed
|
|
60
|
+
process.stderr.write('\n');
|
|
61
|
+
if (process.stdin.isTTY) {
|
|
62
|
+
process.stdin.setRawMode(false);
|
|
63
|
+
}
|
|
64
|
+
process.stdin.removeListener('data', onData);
|
|
65
|
+
rl.close();
|
|
66
|
+
resolve(secret);
|
|
67
|
+
}
|
|
68
|
+
else if (char === '\u0003') {
|
|
69
|
+
// Ctrl+C
|
|
70
|
+
process.stderr.write('\n');
|
|
71
|
+
if (process.stdin.isTTY) {
|
|
72
|
+
process.stdin.setRawMode(false);
|
|
73
|
+
}
|
|
74
|
+
process.stdin.removeListener('data', onData);
|
|
75
|
+
rl.close();
|
|
76
|
+
process.exit(130);
|
|
77
|
+
}
|
|
78
|
+
else if (char === '\u007F' || char === '\b') {
|
|
79
|
+
// Backspace
|
|
80
|
+
if (secret.length > 0) {
|
|
81
|
+
secret = secret.slice(0, -1);
|
|
82
|
+
process.stderr.write('\b \b');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else if (masked && char.length === 1 && char.charCodeAt(0) >= 32) {
|
|
86
|
+
secret += char;
|
|
87
|
+
process.stderr.write('*');
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
// Suppress the default readline behavior when in raw mode
|
|
91
|
+
rl.write = (...args) => {
|
|
92
|
+
if (!masked) {
|
|
93
|
+
return originalWrite(...args);
|
|
94
|
+
}
|
|
95
|
+
// Suppress default output during masked input
|
|
96
|
+
return undefined;
|
|
97
|
+
};
|
|
98
|
+
process.stdin.on('data', onData);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Prompt for a yes/no confirmation. Returns true for yes.
|
|
103
|
+
*/
|
|
104
|
+
export async function promptConfirm(message, defaultYes = false) {
|
|
105
|
+
const hint = defaultYes ? '[Y/n]' : '[y/N]';
|
|
106
|
+
const raw = await promptText(`${message} ${hint}`);
|
|
107
|
+
if (!raw)
|
|
108
|
+
return defaultYes;
|
|
109
|
+
return raw.toLowerCase().startsWith('y');
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Prompt for a selection from a list of options.
|
|
113
|
+
* Returns the selected option value.
|
|
114
|
+
*/
|
|
115
|
+
export async function promptSelect(message, options, defaultValue) {
|
|
116
|
+
process.stderr.write(`\n${message}\n`);
|
|
117
|
+
for (let i = 0; i < options.length; i++) {
|
|
118
|
+
const marker = options[i].value === defaultValue ? ' (default)' : '';
|
|
119
|
+
process.stderr.write(` ${i + 1}. ${options[i].label}${marker}\n`);
|
|
120
|
+
}
|
|
121
|
+
const raw = await promptText('Select', defaultValue ? '1' : undefined);
|
|
122
|
+
const index = parseInt(raw, 10) - 1;
|
|
123
|
+
if (index >= 0 && index < options.length) {
|
|
124
|
+
return options[index].value;
|
|
125
|
+
}
|
|
126
|
+
// Try matching by value
|
|
127
|
+
const match = options.find((o) => o.value === raw || o.label.toLowerCase() === raw.toLowerCase());
|
|
128
|
+
if (match)
|
|
129
|
+
return match.value;
|
|
130
|
+
// Fall back to default
|
|
131
|
+
return defaultValue ?? options[0].value;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface RetryOptions {
|
|
2
|
+
/** Maximum number of attempts (including the first) */
|
|
3
|
+
maxAttempts: number;
|
|
4
|
+
/** Initial delay in milliseconds before first retry */
|
|
5
|
+
initialDelayMs: number;
|
|
6
|
+
/** Maximum delay in milliseconds between retries */
|
|
7
|
+
maxDelayMs: number;
|
|
8
|
+
/** Multiplier for exponential backoff (default: 2) */
|
|
9
|
+
backoffMultiplier?: number;
|
|
10
|
+
/** Optional predicate to decide if an error is retryable */
|
|
11
|
+
isRetryable?: (error: unknown) => boolean;
|
|
12
|
+
/** Optional callback called before each retry */
|
|
13
|
+
onRetry?: (attempt: number, error: unknown, delayMs: number) => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Check if an error is likely a transient failure worth retrying.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isTransientError(error: unknown): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Check if an error is an Anthropic rate limit specifically.
|
|
21
|
+
* These get special treatment with longer backoff.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isRateLimitError(error: unknown): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Execute a function with retry logic and exponential backoff.
|
|
26
|
+
*
|
|
27
|
+
* @param fn - The async function to execute
|
|
28
|
+
* @param options - Retry configuration
|
|
29
|
+
* @returns The result of the function
|
|
30
|
+
* @throws The last error if all attempts fail
|
|
31
|
+
*/
|
|
32
|
+
export declare function withRetry<T>(fn: () => Promise<T>, options: RetryOptions): Promise<T>;
|
|
33
|
+
/** Retry options for Claude API calls (rate limit + overload) */
|
|
34
|
+
export declare const CLAUDE_API_RETRY: RetryOptions;
|
|
35
|
+
/** Retry options for SSH reconnection */
|
|
36
|
+
export declare const SSH_RECONNECT_RETRY: RetryOptions;
|
|
37
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,YAAY;IACzB,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,cAAc,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;IAC1C,iDAAiD;IACjD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACxE;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA+BxD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIxD;AAMD;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAuC1F;AAcD,iEAAiE;AACjE,eAAO,MAAM,gBAAgB,EAAE,YAK9B,CAAC;AAEF,yCAAyC;AACzC,eAAO,MAAM,mBAAmB,EAAE,YAejC,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Retry utility — exponential backoff for transient failures
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Used for Claude API rate limits, SSH reconnects, and Proxmox API retries.
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
import { logger } from './logger.js';
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Default retryable error detection
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/**
|
|
11
|
+
* Check if an error is likely a transient failure worth retrying.
|
|
12
|
+
*/
|
|
13
|
+
export function isTransientError(error) {
|
|
14
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
15
|
+
const lc = message.toLowerCase();
|
|
16
|
+
// Rate limits
|
|
17
|
+
if (lc.includes('429') || lc.includes('rate_limit') || lc.includes('rate limit')) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
// API overloaded
|
|
21
|
+
if (lc.includes('overloaded') || lc.includes('529') || lc.includes('503')) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
// Network errors
|
|
25
|
+
if (lc.includes('econnreset') ||
|
|
26
|
+
lc.includes('etimedout') ||
|
|
27
|
+
lc.includes('socket hang up') ||
|
|
28
|
+
lc.includes('epipe') ||
|
|
29
|
+
lc.includes('network')) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
// Server errors (5xx)
|
|
33
|
+
if (lc.includes('500') || lc.includes('502') || lc.includes('504')) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if an error is an Anthropic rate limit specifically.
|
|
40
|
+
* These get special treatment with longer backoff.
|
|
41
|
+
*/
|
|
42
|
+
export function isRateLimitError(error) {
|
|
43
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
44
|
+
const lc = message.toLowerCase();
|
|
45
|
+
return lc.includes('429') || lc.includes('rate_limit') || lc.includes('rate limit');
|
|
46
|
+
}
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Retry function
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
/**
|
|
51
|
+
* Execute a function with retry logic and exponential backoff.
|
|
52
|
+
*
|
|
53
|
+
* @param fn - The async function to execute
|
|
54
|
+
* @param options - Retry configuration
|
|
55
|
+
* @returns The result of the function
|
|
56
|
+
* @throws The last error if all attempts fail
|
|
57
|
+
*/
|
|
58
|
+
export async function withRetry(fn, options) {
|
|
59
|
+
const { maxAttempts, initialDelayMs, maxDelayMs, backoffMultiplier = 2 } = options;
|
|
60
|
+
const isRetryable = options.isRetryable ?? isTransientError;
|
|
61
|
+
let lastError;
|
|
62
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
63
|
+
try {
|
|
64
|
+
return await fn();
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
lastError = error;
|
|
68
|
+
// Don't retry if we've exhausted attempts or error isn't retryable
|
|
69
|
+
if (attempt >= maxAttempts || !isRetryable(error)) {
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
// Calculate delay with exponential backoff + jitter
|
|
73
|
+
const baseDelay = initialDelayMs * Math.pow(backoffMultiplier, attempt - 1);
|
|
74
|
+
const jitter = Math.random() * 0.3 * baseDelay; // 0-30% jitter
|
|
75
|
+
const delay = Math.min(baseDelay + jitter, maxDelayMs);
|
|
76
|
+
logger.info('Retrying after transient error', {
|
|
77
|
+
attempt,
|
|
78
|
+
maxAttempts,
|
|
79
|
+
delayMs: Math.round(delay),
|
|
80
|
+
error: error instanceof Error ? error.message : String(error),
|
|
81
|
+
});
|
|
82
|
+
if (options.onRetry) {
|
|
83
|
+
options.onRetry(attempt, error, Math.round(delay));
|
|
84
|
+
}
|
|
85
|
+
await sleep(delay);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Should not reach here, but TypeScript needs it
|
|
89
|
+
throw lastError;
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Helpers
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
function sleep(ms) {
|
|
95
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
96
|
+
}
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Presets
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
/** Retry options for Claude API calls (rate limit + overload) */
|
|
101
|
+
export const CLAUDE_API_RETRY = {
|
|
102
|
+
maxAttempts: 3,
|
|
103
|
+
initialDelayMs: 2000,
|
|
104
|
+
maxDelayMs: 30_000,
|
|
105
|
+
isRetryable: isTransientError,
|
|
106
|
+
};
|
|
107
|
+
/** Retry options for SSH reconnection */
|
|
108
|
+
export const SSH_RECONNECT_RETRY = {
|
|
109
|
+
maxAttempts: 3,
|
|
110
|
+
initialDelayMs: 1000,
|
|
111
|
+
maxDelayMs: 10_000,
|
|
112
|
+
isRetryable: (error) => {
|
|
113
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
114
|
+
return (msg.includes('ECONNRESET') ||
|
|
115
|
+
msg.includes('ECONNREFUSED') ||
|
|
116
|
+
msg.includes('ETIMEDOUT') ||
|
|
117
|
+
msg.includes('not connected') ||
|
|
118
|
+
msg.includes('SSH') ||
|
|
119
|
+
msg.includes('socket hang up'));
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type CleanupFn = () => void | Promise<void>;
|
|
2
|
+
/**
|
|
3
|
+
* Register a cleanup function to be called on shutdown.
|
|
4
|
+
* Functions are called in reverse order (LIFO).
|
|
5
|
+
*/
|
|
6
|
+
export declare function onShutdown(fn: CleanupFn): void;
|
|
7
|
+
/**
|
|
8
|
+
* Remove a previously registered cleanup function.
|
|
9
|
+
*/
|
|
10
|
+
export declare function removeShutdownHandler(fn: CleanupFn): void;
|
|
11
|
+
/**
|
|
12
|
+
* Run all cleanup functions. Called automatically on SIGINT/SIGTERM,
|
|
13
|
+
* but can also be called manually for controlled shutdown.
|
|
14
|
+
*/
|
|
15
|
+
export declare function runCleanup(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Register SIGINT and SIGTERM signal handlers for graceful shutdown.
|
|
18
|
+
* Call once at application startup. Safe to call multiple times.
|
|
19
|
+
*/
|
|
20
|
+
export declare function registerSignalHandlers(): void;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=shutdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../src/utils/shutdown.ts"],"names":[],"mappings":"AAaA,KAAK,SAAS,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAS5C;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI,CAE9C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI,CAKzD;AAED;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAoBhD;AAQD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAqC7C"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Graceful shutdown — clean up resources on exit
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Registers SIGINT/SIGTERM handlers and tracks resources that need cleanup.
|
|
5
|
+
// Ensures SSH connections are closed and optional conversation history is saved.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
import { logger } from './logger.js';
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Cleanup registry
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
const cleanupFns = [];
|
|
12
|
+
let shutdownInitiated = false;
|
|
13
|
+
/**
|
|
14
|
+
* Register a cleanup function to be called on shutdown.
|
|
15
|
+
* Functions are called in reverse order (LIFO).
|
|
16
|
+
*/
|
|
17
|
+
export function onShutdown(fn) {
|
|
18
|
+
cleanupFns.push(fn);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Remove a previously registered cleanup function.
|
|
22
|
+
*/
|
|
23
|
+
export function removeShutdownHandler(fn) {
|
|
24
|
+
const index = cleanupFns.indexOf(fn);
|
|
25
|
+
if (index >= 0) {
|
|
26
|
+
cleanupFns.splice(index, 1);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Run all cleanup functions. Called automatically on SIGINT/SIGTERM,
|
|
31
|
+
* but can also be called manually for controlled shutdown.
|
|
32
|
+
*/
|
|
33
|
+
export async function runCleanup() {
|
|
34
|
+
if (shutdownInitiated)
|
|
35
|
+
return;
|
|
36
|
+
shutdownInitiated = true;
|
|
37
|
+
logger.info('Running shutdown cleanup', { handlerCount: cleanupFns.length });
|
|
38
|
+
// Run in reverse order (LIFO)
|
|
39
|
+
const fns = [...cleanupFns].reverse();
|
|
40
|
+
for (const fn of fns) {
|
|
41
|
+
try {
|
|
42
|
+
await fn();
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
46
|
+
logger.error('Cleanup handler failed', { error: message });
|
|
47
|
+
// Continue with other cleanup handlers
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
cleanupFns.length = 0;
|
|
51
|
+
}
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Signal handlers
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
let handlersRegistered = false;
|
|
56
|
+
/**
|
|
57
|
+
* Register SIGINT and SIGTERM signal handlers for graceful shutdown.
|
|
58
|
+
* Call once at application startup. Safe to call multiple times.
|
|
59
|
+
*/
|
|
60
|
+
export function registerSignalHandlers() {
|
|
61
|
+
if (handlersRegistered)
|
|
62
|
+
return;
|
|
63
|
+
handlersRegistered = true;
|
|
64
|
+
const handleSignal = (signal) => {
|
|
65
|
+
logger.info('Received signal', { signal });
|
|
66
|
+
runCleanup()
|
|
67
|
+
.then(() => {
|
|
68
|
+
process.exit(0);
|
|
69
|
+
})
|
|
70
|
+
.catch(() => {
|
|
71
|
+
process.exit(1);
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
process.on('SIGINT', () => handleSignal('SIGINT'));
|
|
75
|
+
process.on('SIGTERM', () => handleSignal('SIGTERM'));
|
|
76
|
+
// Handle uncaught exceptions gracefully
|
|
77
|
+
process.on('uncaughtException', (error) => {
|
|
78
|
+
logger.error('Uncaught exception', { error: error.message, stack: error.stack });
|
|
79
|
+
runCleanup()
|
|
80
|
+
.then(() => {
|
|
81
|
+
process.exit(1);
|
|
82
|
+
})
|
|
83
|
+
.catch(() => {
|
|
84
|
+
process.exit(1);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
// Handle unhandled promise rejections
|
|
88
|
+
process.on('unhandledRejection', (reason) => {
|
|
89
|
+
const message = reason instanceof Error ? reason.message : String(reason);
|
|
90
|
+
logger.error('Unhandled rejection', { error: message });
|
|
91
|
+
// Don't exit on unhandled rejections — log and continue
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=shutdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/utils/shutdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import Table from 'cli-table3';
|
|
2
|
+
export declare const TABLE_CHARS: Table.TableConstructorOptions['chars'];
|
|
3
|
+
/**
|
|
4
|
+
* Format bytes into a human-readable string (e.g., 1.23 GiB).
|
|
5
|
+
* Uses binary units (1 GiB = 1024^3 bytes).
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatBytes(bytes: number): string;
|
|
8
|
+
/**
|
|
9
|
+
* Format a ratio (0-1) as a colored percentage string.
|
|
10
|
+
* Green: 0-59%, Yellow: 60-84%, Red: 85-100%
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatPercent(ratio: number): string;
|
|
13
|
+
/**
|
|
14
|
+
* Format a usage bar with percentage (e.g., "45% [████████░░░░░░░]").
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatUsageBar(ratio: number, width?: number): string;
|
|
17
|
+
/**
|
|
18
|
+
* Format uptime in seconds into a human-readable string (e.g., "3d 12h 5m").
|
|
19
|
+
*/
|
|
20
|
+
export declare function formatUptime(seconds: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Color-code a guest status string.
|
|
23
|
+
* running = green, stopped = yellow, paused = cyan, error/unknown = red
|
|
24
|
+
*/
|
|
25
|
+
export declare function colorStatus(status: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Truncate a string to the given max length, appending an ellipsis if needed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function truncate(str: string, maxLen: number): string;
|
|
30
|
+
/**
|
|
31
|
+
* Create a styled cli-table3 instance with consistent formatting.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createTable(head: string[]): Table.Table;
|
|
34
|
+
/**
|
|
35
|
+
* Print a section header with a title and optional count.
|
|
36
|
+
*/
|
|
37
|
+
export declare function printSectionHeader(title: string, count?: number): void;
|
|
38
|
+
//# sourceMappingURL=table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/utils/table.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,MAAM,YAAY,CAAC;AAM/B,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,uBAAuB,CAAC,OAAO,CAgB9D,CAAC;AAMF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUjD;AAMD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,CAQhE;AAMD;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAapD;AAMD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAclD;AAMD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAG5D;AAMD;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAMvD;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAGtE"}
|