resolve-solo 0.7.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-progress/index.d.ts +9 -0
- package/dist/cli-progress/index.d.ts.map +1 -0
- package/dist/cli-progress/index.js +9 -0
- package/dist/cli-progress/index.js.map +1 -0
- package/dist/cli-progress/progress-bar.d.ts +12 -0
- package/dist/cli-progress/progress-bar.d.ts.map +1 -0
- package/dist/cli-progress/progress-bar.js +29 -0
- package/dist/cli-progress/progress-bar.js.map +1 -0
- package/dist/cli-progress/spinner.d.ts +21 -0
- package/dist/cli-progress/spinner.d.ts.map +1 -0
- package/dist/cli-progress/spinner.js +35 -0
- package/dist/cli-progress/spinner.js.map +1 -0
- package/dist/cli-progress/task-renderer.d.ts +57 -0
- package/dist/cli-progress/task-renderer.d.ts.map +1 -0
- package/dist/cli-progress/task-renderer.js +177 -0
- package/dist/cli-progress/task-renderer.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +135 -24
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/data-sources/alerts-generator.d.ts +12 -0
- package/dist/data-sources/alerts-generator.d.ts.map +1 -0
- package/dist/data-sources/alerts-generator.js +168 -0
- package/dist/data-sources/alerts-generator.js.map +1 -0
- package/dist/data-sources/index.d.ts +10 -0
- package/dist/data-sources/index.d.ts.map +1 -0
- package/dist/data-sources/index.js +10 -0
- package/dist/data-sources/index.js.map +1 -0
- package/dist/data-sources/metrics-generator.d.ts +12 -0
- package/dist/data-sources/metrics-generator.d.ts.map +1 -0
- package/dist/data-sources/metrics-generator.js +169 -0
- package/dist/data-sources/metrics-generator.js.map +1 -0
- package/dist/data-sources/pipeline-generator.d.ts +12 -0
- package/dist/data-sources/pipeline-generator.d.ts.map +1 -0
- package/dist/data-sources/pipeline-generator.js +157 -0
- package/dist/data-sources/pipeline-generator.js.map +1 -0
- package/dist/data-sources/sla-generator.d.ts +12 -0
- package/dist/data-sources/sla-generator.d.ts.map +1 -0
- package/dist/data-sources/sla-generator.js +84 -0
- package/dist/data-sources/sla-generator.js.map +1 -0
- package/dist/demo-generator.d.ts +6 -2
- package/dist/demo-generator.d.ts.map +1 -1
- package/dist/demo-generator.js +40 -30
- package/dist/demo-generator.js.map +1 -1
- package/dist/demo-schema.d.ts +49 -0
- package/dist/demo-schema.d.ts.map +1 -1
- package/dist/findings/aggregator.d.ts +26 -0
- package/dist/findings/aggregator.d.ts.map +1 -0
- package/dist/findings/aggregator.js +149 -0
- package/dist/findings/aggregator.js.map +1 -0
- package/dist/findings/formatter.d.ts +50 -0
- package/dist/findings/formatter.d.ts.map +1 -0
- package/dist/findings/formatter.js +393 -0
- package/dist/findings/formatter.js.map +1 -0
- package/dist/findings/index.d.ts +4 -0
- package/dist/findings/index.d.ts.map +1 -0
- package/dist/findings/index.js +7 -0
- package/dist/findings/index.js.map +1 -0
- package/dist/findings/prioritizer.d.ts +15 -0
- package/dist/findings/prioritizer.d.ts.map +1 -0
- package/dist/findings/prioritizer.js +107 -0
- package/dist/findings/prioritizer.js.map +1 -0
- package/dist/handlers.d.ts +38 -0
- package/dist/handlers.d.ts.map +1 -1
- package/dist/handlers.js +135 -1
- package/dist/handlers.js.map +1 -1
- package/dist/investigation-engine/example.d.ts +9 -0
- package/dist/investigation-engine/example.d.ts.map +1 -0
- package/dist/investigation-engine/example.js +88 -0
- package/dist/investigation-engine/example.js.map +1 -0
- package/dist/investigation-engine/index.d.ts +9 -0
- package/dist/investigation-engine/index.d.ts.map +1 -0
- package/dist/investigation-engine/index.js +9 -0
- package/dist/investigation-engine/index.js.map +1 -0
- package/dist/investigation-engine/task-definitions.d.ts +10 -0
- package/dist/investigation-engine/task-definitions.d.ts.map +1 -0
- package/dist/investigation-engine/task-definitions.js +86 -0
- package/dist/investigation-engine/task-definitions.js.map +1 -0
- package/dist/investigation-engine/task-executor.d.ts +58 -0
- package/dist/investigation-engine/task-executor.d.ts.map +1 -0
- package/dist/investigation-engine/task-executor.js +211 -0
- package/dist/investigation-engine/task-executor.js.map +1 -0
- package/dist/investigation-engine/task-progress.d.ts +51 -0
- package/dist/investigation-engine/task-progress.d.ts.map +1 -0
- package/dist/investigation-engine/task-progress.js +107 -0
- package/dist/investigation-engine/task-progress.js.map +1 -0
- package/dist/investigation-engine/task-types.d.ts +44 -0
- package/dist/investigation-engine/task-types.d.ts.map +1 -0
- package/dist/investigation-engine/task-types.js +2 -0
- package/dist/investigation-engine/task-types.js.map +1 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +22 -2
- package/dist/mcp/tools.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +10 -0
- package/dist/parser.js.map +1 -1
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +143 -19
- package/dist/repl.js.map +1 -1
- package/dist/seeded-random.d.ts +15 -0
- package/dist/seeded-random.d.ts.map +1 -0
- package/dist/seeded-random.js +32 -0
- package/dist/seeded-random.js.map +1 -0
- package/dist/storage.d.ts +9 -5
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +75 -8
- package/dist/storage.js.map +1 -1
- package/dist/tool-config.d.ts +36 -0
- package/dist/tool-config.d.ts.map +1 -0
- package/dist/tool-config.js +83 -0
- package/dist/tool-config.js.map +1 -0
- package/dist/tool-discovery.d.ts +27 -0
- package/dist/tool-discovery.d.ts.map +1 -0
- package/dist/tool-discovery.js +150 -0
- package/dist/tool-discovery.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Progress Display System
|
|
3
|
+
*
|
|
4
|
+
* Terminal-friendly progress display with spinners and timing
|
|
5
|
+
*/
|
|
6
|
+
export { Spinner } from './spinner.js';
|
|
7
|
+
export { TaskRenderer, type RenderableTask, type TaskRendererOptions } from './task-renderer.js';
|
|
8
|
+
export { renderProgressBar } from './progress-bar.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli-progress/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACjG,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Progress Display System
|
|
3
|
+
*
|
|
4
|
+
* Terminal-friendly progress display with spinners and timing
|
|
5
|
+
*/
|
|
6
|
+
export { Spinner } from './spinner.js';
|
|
7
|
+
export { TaskRenderer } from './task-renderer.js';
|
|
8
|
+
export { renderProgressBar } from './progress-bar.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli-progress/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,YAAY,EAAiD,MAAM,oBAAoB,CAAC;AACjG,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple progress bar renderer
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Render a simple progress bar
|
|
6
|
+
* @param current - Current progress value
|
|
7
|
+
* @param total - Total/max value
|
|
8
|
+
* @param width - Width of the progress bar (default: 20)
|
|
9
|
+
* @returns Formatted progress bar string, e.g., "[=====> ] 50%"
|
|
10
|
+
*/
|
|
11
|
+
export declare function renderProgressBar(current: number, total: number, width?: number): string;
|
|
12
|
+
//# sourceMappingURL=progress-bar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-bar.d.ts","sourceRoot":"","sources":["../../src/cli-progress/progress-bar.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,MAAM,CAmB5F"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple progress bar renderer
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Render a simple progress bar
|
|
6
|
+
* @param current - Current progress value
|
|
7
|
+
* @param total - Total/max value
|
|
8
|
+
* @param width - Width of the progress bar (default: 20)
|
|
9
|
+
* @returns Formatted progress bar string, e.g., "[=====> ] 50%"
|
|
10
|
+
*/
|
|
11
|
+
export function renderProgressBar(current, total, width = 20) {
|
|
12
|
+
if (total <= 0) {
|
|
13
|
+
return `[${''.padEnd(width)}] 0%`;
|
|
14
|
+
}
|
|
15
|
+
const percentage = Math.min(100, Math.max(0, Math.round((current / total) * 100)));
|
|
16
|
+
const filledWidth = Math.round((percentage / 100) * width);
|
|
17
|
+
let bar = '';
|
|
18
|
+
if (filledWidth === 0) {
|
|
19
|
+
bar = ''.padEnd(width);
|
|
20
|
+
}
|
|
21
|
+
else if (filledWidth >= width) {
|
|
22
|
+
bar = '='.repeat(width);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
bar = '='.repeat(filledWidth - 1) + '>' + ' '.repeat(width - filledWidth);
|
|
26
|
+
}
|
|
27
|
+
return `[${bar}] ${percentage}%`;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=progress-bar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-bar.js","sourceRoot":"","sources":["../../src/cli-progress/progress-bar.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,KAAa,EAAE,QAAgB,EAAE;IAClF,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,OAAO,IAAI,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;IACpC,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IAE3D,IAAI,GAAG,GAAG,EAAE,CAAC;IAEb,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;QACtB,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;SAAM,IAAI,WAAW,IAAI,KAAK,EAAE,CAAC;QAChC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;SAAM,CAAC;QACN,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,WAAW,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,IAAI,GAAG,KAAK,UAAU,GAAG,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple spinner for CLI progress indication
|
|
3
|
+
*/
|
|
4
|
+
export declare class Spinner {
|
|
5
|
+
private frames;
|
|
6
|
+
private interval;
|
|
7
|
+
private frameIndex;
|
|
8
|
+
/**
|
|
9
|
+
* Start the spinner animation
|
|
10
|
+
*/
|
|
11
|
+
start(): void;
|
|
12
|
+
/**
|
|
13
|
+
* Stop the spinner animation
|
|
14
|
+
*/
|
|
15
|
+
stop(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Get the current spinner frame
|
|
18
|
+
*/
|
|
19
|
+
getFrame(): string;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=spinner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/cli-progress/spinner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,UAAU,CAAa;IAE/B;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACH,QAAQ,IAAI,MAAM;CAGnB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple spinner for CLI progress indication
|
|
3
|
+
*/
|
|
4
|
+
export class Spinner {
|
|
5
|
+
frames = ['|', '/', '-', '\\'];
|
|
6
|
+
interval = null;
|
|
7
|
+
frameIndex = 0;
|
|
8
|
+
/**
|
|
9
|
+
* Start the spinner animation
|
|
10
|
+
*/
|
|
11
|
+
start() {
|
|
12
|
+
if (this.interval) {
|
|
13
|
+
return; // Already running
|
|
14
|
+
}
|
|
15
|
+
this.interval = setInterval(() => {
|
|
16
|
+
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
17
|
+
}, 100);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Stop the spinner animation
|
|
21
|
+
*/
|
|
22
|
+
stop() {
|
|
23
|
+
if (this.interval) {
|
|
24
|
+
clearInterval(this.interval);
|
|
25
|
+
this.interval = null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get the current spinner frame
|
|
30
|
+
*/
|
|
31
|
+
getFrame() {
|
|
32
|
+
return this.frames[this.frameIndex];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/cli-progress/spinner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,OAAO,OAAO;IACV,MAAM,GAAa,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACzC,QAAQ,GAA0B,IAAI,CAAC;IACvC,UAAU,GAAW,CAAC,CAAC;IAE/B;;OAEG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,kBAAkB;QAC5B,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;YAC/B,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QAC/D,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACtC,CAAC;CACF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task renderer for CLI progress display
|
|
3
|
+
*/
|
|
4
|
+
export interface RenderableTask {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
status: 'pending' | 'running' | 'completed' | 'failed';
|
|
8
|
+
duration?: number;
|
|
9
|
+
findingsCount?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface TaskRendererOptions {
|
|
12
|
+
stream?: NodeJS.WriteStream;
|
|
13
|
+
showFindings?: boolean;
|
|
14
|
+
useColor?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare class TaskRenderer {
|
|
17
|
+
private stream;
|
|
18
|
+
private showFindings;
|
|
19
|
+
private useColor;
|
|
20
|
+
private isTTY;
|
|
21
|
+
private header;
|
|
22
|
+
private footer;
|
|
23
|
+
private tasks;
|
|
24
|
+
private spinner;
|
|
25
|
+
private renderInterval;
|
|
26
|
+
private lastRenderedLines;
|
|
27
|
+
constructor(options?: TaskRendererOptions);
|
|
28
|
+
/**
|
|
29
|
+
* Set the header text
|
|
30
|
+
*/
|
|
31
|
+
setHeader(text: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Set footer message (e.g., "Found 3 issues")
|
|
34
|
+
*/
|
|
35
|
+
setFooter(text: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Add or update a task
|
|
38
|
+
*/
|
|
39
|
+
updateTask(task: RenderableTask): void;
|
|
40
|
+
/**
|
|
41
|
+
* Render current state to terminal (TTY only)
|
|
42
|
+
*/
|
|
43
|
+
render(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Show final state and stop updates
|
|
46
|
+
*/
|
|
47
|
+
complete(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Format a task line for display
|
|
50
|
+
*/
|
|
51
|
+
private formatTaskLine;
|
|
52
|
+
/**
|
|
53
|
+
* Print a single task line (for non-TTY mode)
|
|
54
|
+
*/
|
|
55
|
+
private printTaskLine;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=task-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-renderer.d.ts","sourceRoot":"","sources":["../../src/cli-progress/task-renderer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAcD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,KAAK,CAA0C;IACvD,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,iBAAiB,CAAa;gBAE1B,OAAO,CAAC,EAAE,mBAAmB;IAiBzC;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK7B;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK7B;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAatC;;OAEG;IACH,MAAM,IAAI,IAAI;IAwCd;;OAEG;IACH,QAAQ,IAAI,IAAI;IAchB;;OAEG;IACH,OAAO,CAAC,cAAc;IAmDtB;;OAEG;IACH,OAAO,CAAC,aAAa;CAGtB"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task renderer for CLI progress display
|
|
3
|
+
*/
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { Spinner } from './spinner.js';
|
|
6
|
+
/**
|
|
7
|
+
* Format duration in milliseconds to human-readable string
|
|
8
|
+
*/
|
|
9
|
+
function formatDuration(ms) {
|
|
10
|
+
if (ms < 1000)
|
|
11
|
+
return `${ms}ms`;
|
|
12
|
+
const seconds = ms / 1000;
|
|
13
|
+
if (seconds === Math.floor(seconds)) {
|
|
14
|
+
return `${seconds}s`;
|
|
15
|
+
}
|
|
16
|
+
return `${seconds.toFixed(1)}s`.replace('.0s', 's');
|
|
17
|
+
}
|
|
18
|
+
export class TaskRenderer {
|
|
19
|
+
stream;
|
|
20
|
+
showFindings;
|
|
21
|
+
useColor;
|
|
22
|
+
isTTY;
|
|
23
|
+
header = '';
|
|
24
|
+
footer = '';
|
|
25
|
+
tasks = new Map();
|
|
26
|
+
spinner;
|
|
27
|
+
renderInterval = null;
|
|
28
|
+
lastRenderedLines = 0;
|
|
29
|
+
constructor(options) {
|
|
30
|
+
this.stream = options?.stream ?? process.stdout;
|
|
31
|
+
this.isTTY = this.stream.isTTY ?? false;
|
|
32
|
+
this.showFindings = options?.showFindings ?? true;
|
|
33
|
+
this.useColor = options?.useColor ?? this.isTTY;
|
|
34
|
+
this.spinner = new Spinner();
|
|
35
|
+
// Start spinner animation only in TTY mode
|
|
36
|
+
if (this.isTTY) {
|
|
37
|
+
this.spinner.start();
|
|
38
|
+
// Auto-render every 100ms for spinner animation
|
|
39
|
+
this.renderInterval = setInterval(() => {
|
|
40
|
+
this.render();
|
|
41
|
+
}, 100);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Set the header text
|
|
46
|
+
*/
|
|
47
|
+
setHeader(text) {
|
|
48
|
+
this.header = text;
|
|
49
|
+
this.render();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Set footer message (e.g., "Found 3 issues")
|
|
53
|
+
*/
|
|
54
|
+
setFooter(text) {
|
|
55
|
+
this.footer = text;
|
|
56
|
+
this.render();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Add or update a task
|
|
60
|
+
*/
|
|
61
|
+
updateTask(task) {
|
|
62
|
+
this.tasks.set(task.id, task);
|
|
63
|
+
// In non-TTY mode, print completed tasks immediately
|
|
64
|
+
if (!this.isTTY && task.status === 'completed') {
|
|
65
|
+
this.printTaskLine(task);
|
|
66
|
+
}
|
|
67
|
+
else if (!this.isTTY && task.status === 'failed') {
|
|
68
|
+
this.printTaskLine(task);
|
|
69
|
+
}
|
|
70
|
+
else if (this.isTTY) {
|
|
71
|
+
this.render();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Render current state to terminal (TTY only)
|
|
76
|
+
*/
|
|
77
|
+
render() {
|
|
78
|
+
if (!this.isTTY) {
|
|
79
|
+
return; // Non-TTY mode uses line-by-line output
|
|
80
|
+
}
|
|
81
|
+
// Move cursor up to overwrite previous output
|
|
82
|
+
if (this.lastRenderedLines > 0) {
|
|
83
|
+
this.stream.write('\x1b[' + this.lastRenderedLines + 'A');
|
|
84
|
+
// Clear from cursor to end of screen
|
|
85
|
+
this.stream.write('\x1b[J');
|
|
86
|
+
}
|
|
87
|
+
const lines = [];
|
|
88
|
+
// Header
|
|
89
|
+
if (this.header) {
|
|
90
|
+
lines.push('');
|
|
91
|
+
lines.push(this.useColor ? chalk.bold(this.header) : this.header);
|
|
92
|
+
lines.push('');
|
|
93
|
+
}
|
|
94
|
+
// Tasks
|
|
95
|
+
for (const task of this.tasks.values()) {
|
|
96
|
+
lines.push(this.formatTaskLine(task));
|
|
97
|
+
}
|
|
98
|
+
// Footer
|
|
99
|
+
if (this.footer) {
|
|
100
|
+
lines.push('');
|
|
101
|
+
lines.push(this.useColor ? chalk.dim(this.footer) : this.footer);
|
|
102
|
+
}
|
|
103
|
+
// Add empty line at end for spacing
|
|
104
|
+
lines.push('');
|
|
105
|
+
const output = lines.join('\n');
|
|
106
|
+
this.stream.write(output);
|
|
107
|
+
this.lastRenderedLines = lines.length;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Show final state and stop updates
|
|
111
|
+
*/
|
|
112
|
+
complete() {
|
|
113
|
+
// Stop spinner and render interval
|
|
114
|
+
this.spinner.stop();
|
|
115
|
+
if (this.renderInterval) {
|
|
116
|
+
clearInterval(this.renderInterval);
|
|
117
|
+
this.renderInterval = null;
|
|
118
|
+
}
|
|
119
|
+
// Final render for TTY mode
|
|
120
|
+
if (this.isTTY) {
|
|
121
|
+
this.render();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Format a task line for display
|
|
126
|
+
*/
|
|
127
|
+
formatTaskLine(task) {
|
|
128
|
+
let statusIcon;
|
|
129
|
+
let taskText = task.name;
|
|
130
|
+
let suffix = '';
|
|
131
|
+
// Format based on status
|
|
132
|
+
switch (task.status) {
|
|
133
|
+
case 'pending':
|
|
134
|
+
statusIcon = '[ ]';
|
|
135
|
+
if (this.useColor) {
|
|
136
|
+
statusIcon = chalk.dim(statusIcon);
|
|
137
|
+
taskText = chalk.dim(taskText);
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
case 'running':
|
|
141
|
+
statusIcon = `[${this.spinner.getFrame()}]`;
|
|
142
|
+
break;
|
|
143
|
+
case 'completed':
|
|
144
|
+
statusIcon = '[*]';
|
|
145
|
+
if (this.useColor) {
|
|
146
|
+
statusIcon = chalk.green(statusIcon);
|
|
147
|
+
}
|
|
148
|
+
// Add duration if available
|
|
149
|
+
if (task.duration !== undefined) {
|
|
150
|
+
const duration = formatDuration(task.duration);
|
|
151
|
+
suffix += this.useColor ? chalk.dim(` ${duration}`) : ` ${duration}`;
|
|
152
|
+
}
|
|
153
|
+
// Add findings count if available and enabled
|
|
154
|
+
if (this.showFindings && task.findingsCount !== undefined && task.findingsCount > 0) {
|
|
155
|
+
const findings = `(${task.findingsCount} issue${task.findingsCount === 1 ? '' : 's'})`;
|
|
156
|
+
suffix += this.useColor ? ` ${chalk.yellow(findings)}` : ` ${findings}`;
|
|
157
|
+
}
|
|
158
|
+
break;
|
|
159
|
+
case 'failed':
|
|
160
|
+
statusIcon = '[!]';
|
|
161
|
+
if (this.useColor) {
|
|
162
|
+
statusIcon = chalk.red(statusIcon);
|
|
163
|
+
taskText = chalk.red(taskText);
|
|
164
|
+
}
|
|
165
|
+
suffix = this.useColor ? chalk.red(' error') : ' error';
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
return ` ${statusIcon} ${taskText}${suffix}`;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Print a single task line (for non-TTY mode)
|
|
172
|
+
*/
|
|
173
|
+
printTaskLine(task) {
|
|
174
|
+
this.stream.write(this.formatTaskLine(task) + '\n');
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=task-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-renderer.js","sourceRoot":"","sources":["../../src/cli-progress/task-renderer.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;GAIG;AAiBH,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,iBAmBhE"}
|
package/dist/cli.js
CHANGED
|
@@ -10,6 +10,7 @@ import { displayInvestigation, promptTimeSaved } from './demo-output.js';
|
|
|
10
10
|
import { getStorageInfo } from './storage.js';
|
|
11
11
|
import chalk from 'chalk';
|
|
12
12
|
import * as handlers from './handlers.js';
|
|
13
|
+
import { TaskRenderer } from './cli-progress/task-renderer.js';
|
|
13
14
|
export async function main(args = process.argv.slice(2)) {
|
|
14
15
|
// Mode detection
|
|
15
16
|
// MCP server mode (stdio transport for Claude Code)
|
|
@@ -71,6 +72,9 @@ async function handleCliMode(args) {
|
|
|
71
72
|
case 'doctor':
|
|
72
73
|
await handleDoctorCommand(context);
|
|
73
74
|
break;
|
|
75
|
+
case 'discover':
|
|
76
|
+
await handleDiscoverCommand(context);
|
|
77
|
+
break;
|
|
74
78
|
case 'uninstall':
|
|
75
79
|
await handleUninstallCommand(parsed.args, context);
|
|
76
80
|
break;
|
|
@@ -116,37 +120,93 @@ async function handleDemoCommand(context) {
|
|
|
116
120
|
}
|
|
117
121
|
/**
|
|
118
122
|
* CLI wrapper for investigate command
|
|
123
|
+
* Uses multi-agent investigation with live progress display
|
|
119
124
|
*/
|
|
120
125
|
async function handleInvestigateCommand(query, context) {
|
|
121
126
|
console.log();
|
|
122
|
-
console.log(chalk.cyan(
|
|
123
|
-
console.log();
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
console.log(chalk.bold.cyan(`Investigating: ${query}`));
|
|
128
|
+
console.log();
|
|
129
|
+
// Create task renderer for live progress
|
|
130
|
+
const renderer = new TaskRenderer({
|
|
131
|
+
stream: process.stdout,
|
|
132
|
+
showFindings: true,
|
|
133
|
+
});
|
|
134
|
+
renderer.setHeader(`🔍 Gathering data from observability tools...`);
|
|
135
|
+
// Track task state for rendering
|
|
136
|
+
const taskState = new Map();
|
|
137
|
+
try {
|
|
138
|
+
// Run multi-agent investigation with progress callback
|
|
139
|
+
const result = await handlers.handleMultiAgentInvestigate(query, context, {
|
|
140
|
+
parallel: true,
|
|
141
|
+
simulatedDelay: true,
|
|
142
|
+
onProgress: (event) => {
|
|
143
|
+
// Convert TaskProgressEvent to RenderableTask
|
|
144
|
+
const currentTask = taskState.get(event.taskId) || { name: event.taskName, status: 'pending' };
|
|
145
|
+
if (event.type === 'start') {
|
|
146
|
+
currentTask.status = 'running';
|
|
147
|
+
currentTask.name = event.taskName;
|
|
148
|
+
}
|
|
149
|
+
else if (event.type === 'complete') {
|
|
150
|
+
currentTask.status = 'completed';
|
|
151
|
+
currentTask.duration = event.duration;
|
|
152
|
+
currentTask.findingsCount = event.findingsCount;
|
|
153
|
+
}
|
|
154
|
+
else if (event.type === 'error') {
|
|
155
|
+
currentTask.status = 'failed';
|
|
156
|
+
currentTask.duration = event.duration;
|
|
157
|
+
}
|
|
158
|
+
taskState.set(event.taskId, currentTask);
|
|
159
|
+
renderer.updateTask({
|
|
160
|
+
id: event.taskId,
|
|
161
|
+
name: currentTask.name,
|
|
162
|
+
status: currentTask.status,
|
|
163
|
+
duration: currentTask.duration,
|
|
164
|
+
findingsCount: currentTask.findingsCount,
|
|
165
|
+
});
|
|
166
|
+
// Update footer with progress
|
|
167
|
+
const completed = Array.from(taskState.values()).filter(t => t.status === 'completed' || t.status === 'failed').length;
|
|
168
|
+
const total = taskState.size;
|
|
169
|
+
const findings = Array.from(taskState.values()).reduce((sum, t) => sum + (t.findingsCount || 0), 0);
|
|
170
|
+
if (findings > 0) {
|
|
171
|
+
renderer.setFooter(`Progress: ${completed}/${total} tasks | Found ${findings} issue${findings === 1 ? '' : 's'} so far...`);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
renderer.setFooter(`Progress: ${completed}/${total} tasks`);
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
// Complete the renderer
|
|
179
|
+
renderer.complete();
|
|
180
|
+
if (!result.success) {
|
|
181
|
+
console.log();
|
|
182
|
+
console.log(chalk.yellow('⚠️ '), result.message);
|
|
183
|
+
if (result.error) {
|
|
184
|
+
console.log(chalk.gray(result.error));
|
|
185
|
+
}
|
|
186
|
+
console.log();
|
|
187
|
+
console.log(chalk.gray('Try:'));
|
|
188
|
+
console.log(chalk.gray(' resolveai demo'));
|
|
130
189
|
console.log();
|
|
190
|
+
return;
|
|
131
191
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
console.log(
|
|
192
|
+
const data = result.data;
|
|
193
|
+
// Display the executive summary
|
|
194
|
+
console.log();
|
|
195
|
+
console.log(data.formattedOutput.cli);
|
|
196
|
+
// Show timing info
|
|
197
|
+
console.log(chalk.gray(`Investigation completed in ${(data.timing.totalDuration / 1000).toFixed(1)}s`));
|
|
198
|
+
console.log();
|
|
199
|
+
// Suggest next commands
|
|
200
|
+
console.log(chalk.bold('Next steps:'));
|
|
201
|
+
console.log(chalk.cyan(' resolveai show details for item 1'));
|
|
202
|
+
console.log(chalk.cyan(' resolveai note investigating the timeout issue'));
|
|
203
|
+
console.log(chalk.cyan(' resolveai close fixed connection pool size'));
|
|
135
204
|
console.log();
|
|
136
|
-
return;
|
|
137
205
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
displayInvestigation(investigation);
|
|
143
|
-
// Suggest next commands
|
|
144
|
-
console.log();
|
|
145
|
-
console.log(chalk.bold('Next steps:'));
|
|
146
|
-
console.log(chalk.cyan(' resolveai show details for item 1'));
|
|
147
|
-
console.log(chalk.cyan(' resolveai note investigating the timeout issue'));
|
|
148
|
-
console.log(chalk.cyan(' resolveai close fixed connection pool size'));
|
|
149
|
-
console.log();
|
|
206
|
+
catch (error) {
|
|
207
|
+
renderer.complete();
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
150
210
|
}
|
|
151
211
|
/**
|
|
152
212
|
* CLI wrapper for details command
|
|
@@ -564,6 +624,57 @@ async function handleDoctorCommand(context) {
|
|
|
564
624
|
console.log();
|
|
565
625
|
}
|
|
566
626
|
}
|
|
627
|
+
/**
|
|
628
|
+
* CLI wrapper for tool discovery command - M13
|
|
629
|
+
*/
|
|
630
|
+
async function handleDiscoverCommand(context) {
|
|
631
|
+
console.log();
|
|
632
|
+
console.log(chalk.cyan('🔍 Tool Discovery'));
|
|
633
|
+
console.log();
|
|
634
|
+
console.log(' Checking for observability tools...');
|
|
635
|
+
console.log();
|
|
636
|
+
const result = await handlers.handleToolDiscovery(context);
|
|
637
|
+
if (!result.success) {
|
|
638
|
+
console.log(chalk.red('✗'), result.message);
|
|
639
|
+
console.log();
|
|
640
|
+
if (result.error) {
|
|
641
|
+
console.log(chalk.gray(result.error));
|
|
642
|
+
}
|
|
643
|
+
console.log();
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
const data = result.data;
|
|
647
|
+
// Display installed tools
|
|
648
|
+
if (data.discovered.length > 0) {
|
|
649
|
+
console.log(chalk.bold(' Installed:'));
|
|
650
|
+
for (const tool of data.discovered) {
|
|
651
|
+
console.log(chalk.green(` [*] ${tool.name} (${tool.category})`));
|
|
652
|
+
}
|
|
653
|
+
console.log();
|
|
654
|
+
}
|
|
655
|
+
// Display missing tools
|
|
656
|
+
if (data.missing.length > 0) {
|
|
657
|
+
console.log(chalk.bold(' Not Installed:'));
|
|
658
|
+
for (const tool of data.missing) {
|
|
659
|
+
console.log(chalk.yellow(` [ ] ${tool.name} (${tool.category})`));
|
|
660
|
+
console.log(chalk.gray(` ${tool.installGuide}`));
|
|
661
|
+
}
|
|
662
|
+
console.log();
|
|
663
|
+
}
|
|
664
|
+
// Display recommendations
|
|
665
|
+
if (data.recommendations.length > 0) {
|
|
666
|
+
console.log(chalk.bold(' Recommendations:'));
|
|
667
|
+
for (const rec of data.recommendations) {
|
|
668
|
+
console.log(chalk.gray(` - ${rec}`));
|
|
669
|
+
}
|
|
670
|
+
console.log();
|
|
671
|
+
}
|
|
672
|
+
// Show config path
|
|
673
|
+
const { getResolveaiDir } = await import('./storage.js');
|
|
674
|
+
const configPath = `${getResolveaiDir()}/tool-config.json`;
|
|
675
|
+
console.log(chalk.gray(` Config saved to ${configPath}`));
|
|
676
|
+
console.log();
|
|
677
|
+
}
|
|
567
678
|
// Only run if called directly (not imported)
|
|
568
679
|
// Always run main() when this file is executed (not imported as a module)
|
|
569
680
|
main().catch((error) => {
|