kubechart 0.1.0 → 0.2.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.
Files changed (60) hide show
  1. package/README.md +17 -1
  2. package/dist/cli.js +68 -9
  3. package/dist/cli.js.map +1 -1
  4. package/dist/graph/builder.d.ts +19 -0
  5. package/dist/graph/builder.d.ts.map +1 -0
  6. package/dist/graph/builder.js +140 -0
  7. package/dist/graph/builder.js.map +1 -0
  8. package/dist/output/serializer.d.ts +42 -0
  9. package/dist/output/serializer.d.ts.map +1 -0
  10. package/dist/output/serializer.js +42 -0
  11. package/dist/output/serializer.js.map +1 -0
  12. package/dist/render/BlockView.d.ts +8 -0
  13. package/dist/render/BlockView.d.ts.map +1 -0
  14. package/dist/render/BlockView.js +53 -0
  15. package/dist/render/BlockView.js.map +1 -0
  16. package/dist/render/GraphNode.d.ts +8 -0
  17. package/dist/render/GraphNode.d.ts.map +1 -0
  18. package/dist/render/GraphNode.js +48 -0
  19. package/dist/render/GraphNode.js.map +1 -0
  20. package/dist/render/GraphView.d.ts +8 -0
  21. package/dist/render/GraphView.d.ts.map +1 -0
  22. package/dist/render/GraphView.js +221 -0
  23. package/dist/render/GraphView.js.map +1 -0
  24. package/dist/render/NamespaceBlock.d.ts +9 -0
  25. package/dist/render/NamespaceBlock.d.ts.map +1 -0
  26. package/dist/render/NamespaceBlock.js +84 -0
  27. package/dist/render/NamespaceBlock.js.map +1 -0
  28. package/dist/render/StatusBar.d.ts +12 -0
  29. package/dist/render/StatusBar.d.ts.map +1 -0
  30. package/dist/render/StatusBar.js +43 -0
  31. package/dist/render/StatusBar.js.map +1 -0
  32. package/dist/render/TreeView.d.ts +2 -1
  33. package/dist/render/TreeView.d.ts.map +1 -1
  34. package/dist/render/TreeView.js +13 -12
  35. package/dist/render/TreeView.js.map +1 -1
  36. package/dist/render/WatchView.d.ts +12 -0
  37. package/dist/render/WatchView.d.ts.map +1 -0
  38. package/dist/render/WatchView.js +92 -0
  39. package/dist/render/WatchView.js.map +1 -0
  40. package/dist/render/WorkloadBlock.d.ts +9 -0
  41. package/dist/render/WorkloadBlock.d.ts.map +1 -0
  42. package/dist/render/WorkloadBlock.js +47 -0
  43. package/dist/render/WorkloadBlock.js.map +1 -0
  44. package/dist/render/ascii/box.d.ts +8 -0
  45. package/dist/render/ascii/box.d.ts.map +1 -0
  46. package/dist/render/ascii/box.js +25 -0
  47. package/dist/render/ascii/box.js.map +1 -0
  48. package/dist/render/colors.d.ts +1 -0
  49. package/dist/render/colors.d.ts.map +1 -1
  50. package/dist/render/colors.js +1 -0
  51. package/dist/render/colors.js.map +1 -1
  52. package/dist/watch/differ.d.ts +8 -0
  53. package/dist/watch/differ.d.ts.map +1 -0
  54. package/dist/watch/differ.js +113 -0
  55. package/dist/watch/differ.js.map +1 -0
  56. package/dist/watch/flash.d.ts +2 -0
  57. package/dist/watch/flash.d.ts.map +1 -0
  58. package/dist/watch/flash.js +13 -0
  59. package/dist/watch/flash.js.map +1 -0
  60. package/package.json +3 -1
@@ -0,0 +1,92 @@
1
+ import React, { useState, useEffect, useCallback, useRef } from 'react';
2
+ import { Box, Text, useInput } from 'ink';
3
+ import { fetchClusterData } from '../k8s/fetcher.js';
4
+ import { buildTree } from '../tree/builder.js';
5
+ import { diffTrees } from '../watch/differ.js';
6
+ import { useFlash } from '../watch/flash.js';
7
+ import { TreeView } from './TreeView.js';
8
+ import { StatusBar } from './StatusBar.js';
9
+ export function WatchView({ opts }) {
10
+ const [tree, setTree] = useState(null);
11
+ const [diff, setDiff] = useState({ added: [], removed: [], changed: [] });
12
+ const [status, setStatus] = useState('fetching');
13
+ const [lastUpdated, setLastUpdated] = useState();
14
+ const [refreshTrigger, setRefreshTrigger] = useState(0);
15
+ const [timeUntilRefresh, setTimeUntilRefresh] = useState(opts.interval);
16
+ const flashing = useFlash(diff.changed);
17
+ const fetchTree = useCallback(async () => {
18
+ try {
19
+ setStatus('fetching');
20
+ const rawData = await fetchClusterData(opts.client, opts.fetchOpts);
21
+ const newTree = buildTree(rawData, opts.client.contextName, {
22
+ showErrors: opts.fetchOpts.showErrors,
23
+ selector: opts.fetchOpts.selector,
24
+ });
25
+ if (tree) {
26
+ const newDiff = diffTrees(tree, newTree);
27
+ setDiff(newDiff);
28
+ }
29
+ setTree(newTree);
30
+ setLastUpdated(new Date());
31
+ setTimeUntilRefresh(opts.interval);
32
+ setStatus('idle');
33
+ }
34
+ catch (error) {
35
+ console.error(`Error fetching cluster data: ${error instanceof Error ? error.message : String(error)}`);
36
+ setStatus('idle');
37
+ }
38
+ }, [tree, opts.client, opts.fetchOpts, opts.interval]);
39
+ const fetchTreeRef = useRef(fetchTree);
40
+ fetchTreeRef.current = fetchTree;
41
+ // Initial fetch
42
+ useEffect(() => {
43
+ fetchTreeRef.current();
44
+ }, []);
45
+ // Auto-refresh interval
46
+ useEffect(() => {
47
+ const id = setInterval(() => {
48
+ fetchTreeRef.current();
49
+ }, opts.interval * 1000);
50
+ return () => clearInterval(id);
51
+ }, [opts.interval]);
52
+ // Countdown timer
53
+ useEffect(() => {
54
+ if (status === 'fetching') {
55
+ setTimeUntilRefresh(opts.interval);
56
+ return;
57
+ }
58
+ const id = setInterval(() => {
59
+ setTimeUntilRefresh((prev) => {
60
+ if (prev <= 1) {
61
+ return opts.interval;
62
+ }
63
+ return prev - 1;
64
+ });
65
+ }, 1000);
66
+ return () => clearInterval(id);
67
+ }, [status, opts.interval]);
68
+ // Manual refresh trigger
69
+ useEffect(() => {
70
+ if (refreshTrigger > 0) {
71
+ fetchTreeRef.current();
72
+ }
73
+ }, [refreshTrigger]);
74
+ // Keyboard input
75
+ useInput((input, key) => {
76
+ if (input === 'r') {
77
+ setRefreshTrigger((prev) => prev + 1);
78
+ }
79
+ if (input === 'q' || (key.ctrl && input === 'c')) {
80
+ process.exit(0);
81
+ }
82
+ });
83
+ if (!tree) {
84
+ return (React.createElement(Box, null,
85
+ React.createElement(Box, { marginBottom: 1 },
86
+ React.createElement(Text, { color: "yellow" }, "\u280B Fetching cluster data..."))));
87
+ }
88
+ return (React.createElement(Box, { flexDirection: "column" },
89
+ React.createElement(TreeView, { tree: tree, flashing: flashing }),
90
+ React.createElement(StatusBar, { status: status, diff: diff, interval: opts.interval, lastUpdated: lastUpdated, timeUntilRefresh: timeUntilRefresh })));
91
+ }
92
+ //# sourceMappingURL=WatchView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WatchView.js","sourceRoot":"","sources":["../../src/render/WatchView.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import type { WorkloadNode } from '../tree/types.js';
3
+ interface WorkloadBlockProps {
4
+ workload: WorkloadNode;
5
+ width: number;
6
+ }
7
+ export declare function WorkloadBlock({ workload, width }: WorkloadBlockProps): React.ReactElement;
8
+ export {};
9
+ //# sourceMappingURL=WorkloadBlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkloadBlock.d.ts","sourceRoot":"","sources":["../../src/render/WorkloadBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAmCzF"}
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import { Box, Text } from 'ink';
3
+ import { drawBox } from './ascii/box.js';
4
+ export function WorkloadBlock({ workload, width }) {
5
+ const lines = [];
6
+ // Ready count
7
+ lines.push(`ready: ${workload.ready}`);
8
+ // Image
9
+ lines.push(`image: ${workload.image}`);
10
+ // Pods
11
+ for (const pod of workload.pods) {
12
+ const statusSymbol = getPodStatusSymbol(pod.phase, pod.ready);
13
+ const restartInfo = pod.restarts > 0 ? ` ${pod.restarts}↺` : ' 0↺';
14
+ const reasonInfo = pod.reason ? ` ${pod.reason}` : '';
15
+ lines.push(`${statusSymbol} ${pod.name} ${pod.nodeName}${restartInfo}${reasonInfo}`);
16
+ }
17
+ // Check if degraded
18
+ const [ready, desired] = workload.ready.split('/').map(Number);
19
+ const isDegraded = ready < desired;
20
+ const boxLines = drawBox({
21
+ title: `${workload.kind}: ${workload.name}`,
22
+ lines,
23
+ width,
24
+ warning: isDegraded,
25
+ });
26
+ return (React.createElement(Box, { flexDirection: "column" }, boxLines.map((line, index) => (React.createElement(Text, { key: index }, line)))));
27
+ }
28
+ function getPodStatusSymbol(phase, ready) {
29
+ if (phase === 'Running') {
30
+ const [readyContainers, totalContainers] = ready.split('/').map(Number);
31
+ if (readyContainers < totalContainers) {
32
+ return '◑';
33
+ }
34
+ return '●';
35
+ }
36
+ switch (phase) {
37
+ case 'Pending':
38
+ return '◌';
39
+ case 'Failed':
40
+ return '✖';
41
+ case 'Succeeded':
42
+ return '○';
43
+ default:
44
+ return '?';
45
+ }
46
+ }
47
+ //# sourceMappingURL=WorkloadBlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkloadBlock.js","sourceRoot":"","sources":["../../src/render/WorkloadBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAQzC,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAsB;IACnE,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,cAAc;IACd,KAAK,CAAC,IAAI,CAAC,UAAU,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAEvC,QAAQ;IACR,KAAK,CAAC,IAAI,CAAC,UAAU,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAEvC,OAAO;IACP,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,YAAY,GAAG,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9D,MAAM,WAAW,GAAG,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;QACrE,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,QAAQ,GAAG,WAAW,GAAG,UAAU,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,oBAAoB;IACpB,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,KAAK,GAAG,OAAO,CAAC;IAEnC,MAAM,QAAQ,GAAG,OAAO,CAAC;QACvB,KAAK,EAAE,GAAG,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAE;QAC3C,KAAK;QACL,KAAK;QACL,OAAO,EAAE,UAAU;KACpB,CAAC,CAAC;IAEH,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,IACxB,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC7B,oBAAC,IAAI,IAAC,GAAG,EAAE,KAAK,IAAG,IAAI,CAAQ,CAChC,CAAC,CACE,CACP,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa,EAAE,KAAa;IACtD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxE,IAAI,eAAe,GAAG,eAAe,EAAE,CAAC;YACtC,OAAO,GAAG,CAAC;QACb,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IACD,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,GAAG,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,GAAG,CAAC;QACb,KAAK,WAAW;YACd,OAAO,GAAG,CAAC;QACb;YACE,OAAO,GAAG,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface BoxOptions {
2
+ title: string;
3
+ lines: string[];
4
+ width: number;
5
+ warning?: boolean;
6
+ }
7
+ export declare function drawBox(opts: BoxOptions): string[];
8
+ //# sourceMappingURL=box.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../../src/render/ascii/box.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,CA8BlD"}
@@ -0,0 +1,25 @@
1
+ export function drawBox(opts) {
2
+ const { title, lines, width, warning = false } = opts;
3
+ if (width < 10) {
4
+ throw new Error('Box width must be at least 10');
5
+ }
6
+ const result = [];
7
+ // Top border with title
8
+ const titleText = warning ? `⚠ ${title}` : title;
9
+ const titleLength = titleText.length;
10
+ const padding = Math.max(2, width - titleLength - 4);
11
+ const leftPad = Math.floor(padding / 2);
12
+ const rightPad = padding - leftPad;
13
+ const topBorder = `┌─${' '.repeat(leftPad)}${titleText}${' '.repeat(rightPad)}─┐`;
14
+ result.push(topBorder.slice(0, width)); // Ensure exact width
15
+ // Content lines
16
+ for (const line of lines) {
17
+ const truncated = line.length > width - 4 ? line.slice(0, width - 7) + '...' : line;
18
+ const padded = truncated.padEnd(width - 4, ' ');
19
+ result.push(`│ ${padded} │`);
20
+ }
21
+ // Bottom border
22
+ result.push(`└${'─'.repeat(width - 2)}┘`);
23
+ return result;
24
+ }
25
+ //# sourceMappingURL=box.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"box.js","sourceRoot":"","sources":["../../../src/render/ascii/box.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,OAAO,CAAC,IAAgB;IACtC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC;IAEtD,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,wBAAwB;IACxB,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACjD,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;IAEnC,MAAM,SAAS,GAAG,KAAK,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;IAClF,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,qBAAqB;IAE7D,gBAAgB;IAChB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QACpF,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,gBAAgB;IAChB,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAE1C,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -9,6 +9,7 @@ export declare const colors: {
9
9
  daemonSet: string;
10
10
  job: string;
11
11
  cronJob: string;
12
+ service: string;
12
13
  clusterIP: string;
13
14
  nodePort: string;
14
15
  loadBalancer: string;
@@ -1 +1 @@
1
- {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/render/colors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;CA+BlB,CAAC;AAIF,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEnD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAevD;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,MAAM,GAAG,MAAM,CAG/D"}
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/render/colors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;CAgClB,CAAC;AAIF,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEnD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAevD;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,MAAM,GAAG,MAAM,CAG/D"}
@@ -14,6 +14,7 @@ export const colors = {
14
14
  job: '#f59e0b', // amber
15
15
  cronJob: '#10b981', // emerald
16
16
  // Service colors
17
+ service: '#3b82f6', // blue
17
18
  clusterIP: '#3b82f6', // blue
18
19
  nodePort: '#22c55e', // green
19
20
  loadBalancer: '#8b5cf6', // purple
@@ -1 +1 @@
1
- {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/render/colors.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,2CAA2C;AAC3C,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,uCAAuC;IACvC,OAAO,EAAE,SAAS,EAAE,QAAQ;IAC5B,OAAO,EAAE,SAAS,EAAE,SAAS;IAC7B,MAAM,EAAE,SAAS,EAAE,MAAM;IACzB,SAAS,EAAE,SAAS,EAAE,OAAO;IAC7B,OAAO,EAAE,SAAS,EAAE,OAAO;IAE3B,kBAAkB;IAClB,UAAU,EAAE,SAAS,EAAE,OAAO;IAC9B,WAAW,EAAE,SAAS,EAAE,SAAS;IACjC,SAAS,EAAE,SAAS,EAAE,MAAM;IAC5B,GAAG,EAAE,SAAS,EAAE,QAAQ;IACxB,OAAO,EAAE,SAAS,EAAE,UAAU;IAE9B,iBAAiB;IACjB,SAAS,EAAE,SAAS,EAAE,OAAO;IAC7B,QAAQ,EAAE,SAAS,EAAE,QAAQ;IAC7B,YAAY,EAAE,SAAS,EAAE,SAAS;IAClC,YAAY,EAAE,SAAS,EAAE,QAAQ;IAEjC,kBAAkB;IAClB,SAAS,EAAE,SAAS,EAAE,OAAO;IAC7B,QAAQ,EAAE,SAAS,EAAE,UAAU;IAC/B,OAAO,EAAE,SAAS,EAAE,OAAO;IAE3B,YAAY;IACZ,MAAM,EAAE,SAAS,EAAE,OAAO;IAC1B,IAAI,EAAE,SAAS,EAAE,OAAO;IACxB,KAAK,EAAE,SAAS,EAAE,MAAM;IACxB,OAAO,EAAE,SAAS,EAAE,SAAS;CAC9B,CAAC;AAEF,IAAI,SAAS,GAAG,IAAI,CAAC;AAErB,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,SAAS,GAAG,OAAO,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IAE1B,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,KAAK,SAAS;YACZ,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC,MAAM,CAAC;QACvB,KAAK,WAAW;YACd,OAAO,MAAM,CAAC,SAAS,CAAC;QAC1B;YACE,OAAO,MAAM,CAAC,OAAO,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,SAA8B;IACrD,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IAC1B,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC;AAC3B,CAAC"}
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/render/colors.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,2CAA2C;AAC3C,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,uCAAuC;IACvC,OAAO,EAAE,SAAS,EAAE,QAAQ;IAC5B,OAAO,EAAE,SAAS,EAAE,SAAS;IAC7B,MAAM,EAAE,SAAS,EAAE,MAAM;IACzB,SAAS,EAAE,SAAS,EAAE,OAAO;IAC7B,OAAO,EAAE,SAAS,EAAE,OAAO;IAE3B,kBAAkB;IAClB,UAAU,EAAE,SAAS,EAAE,OAAO;IAC9B,WAAW,EAAE,SAAS,EAAE,SAAS;IACjC,SAAS,EAAE,SAAS,EAAE,MAAM;IAC5B,GAAG,EAAE,SAAS,EAAE,QAAQ;IACxB,OAAO,EAAE,SAAS,EAAE,UAAU;IAE9B,iBAAiB;IACjB,OAAO,EAAE,SAAS,EAAE,OAAO;IAC3B,SAAS,EAAE,SAAS,EAAE,OAAO;IAC7B,QAAQ,EAAE,SAAS,EAAE,QAAQ;IAC7B,YAAY,EAAE,SAAS,EAAE,SAAS;IAClC,YAAY,EAAE,SAAS,EAAE,QAAQ;IAEjC,kBAAkB;IAClB,SAAS,EAAE,SAAS,EAAE,OAAO;IAC7B,QAAQ,EAAE,SAAS,EAAE,UAAU;IAC/B,OAAO,EAAE,SAAS,EAAE,OAAO;IAE3B,YAAY;IACZ,MAAM,EAAE,SAAS,EAAE,OAAO;IAC1B,IAAI,EAAE,SAAS,EAAE,OAAO;IACxB,KAAK,EAAE,SAAS,EAAE,MAAM;IACxB,OAAO,EAAE,SAAS,EAAE,SAAS;CAC9B,CAAC;AAEF,IAAI,SAAS,GAAG,IAAI,CAAC;AAErB,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,SAAS,GAAG,OAAO,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IAE1B,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,KAAK,SAAS;YACZ,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC,MAAM,CAAC;QACvB,KAAK,WAAW;YACd,OAAO,MAAM,CAAC,SAAS,CAAC;QAC1B;YACE,OAAO,MAAM,CAAC,OAAO,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,SAA8B;IACrD,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IAC1B,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ClusterTree } from '../tree/types.js';
2
+ export interface DiffResult {
3
+ added: string[];
4
+ removed: string[];
5
+ changed: string[];
6
+ }
7
+ export declare function diffTrees(prev: ClusterTree, next: ClusterTree): DiffResult;
8
+ //# sourceMappingURL=differ.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"differ.d.ts","sourceRoot":"","sources":["../../src/watch/differ.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAyB,MAAM,kBAAkB,CAAC;AAY3E,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAyH1E"}
@@ -0,0 +1,113 @@
1
+ // Generate unique key for a pod: namespace/workload/pod
2
+ function podKey(ns, workload, pod) {
3
+ return `${ns}/${workload}/${pod}`;
4
+ }
5
+ // Generate unique key for a workload: namespace/workload
6
+ function workloadKey(ns, workload) {
7
+ return `${ns}/${workload}`;
8
+ }
9
+ export function diffTrees(prev, next) {
10
+ const result = {
11
+ added: [],
12
+ removed: [],
13
+ changed: [],
14
+ };
15
+ const prevPods = new Set();
16
+ const nextPods = new Set();
17
+ const prevWorkloads = new Set();
18
+ const nextWorkloads = new Set();
19
+ // Collect all pods and workloads from previous tree
20
+ for (const ns of prev.namespaces) {
21
+ for (const wl of ns.workloads) {
22
+ const wlKey = workloadKey(ns.name, wl.name);
23
+ prevWorkloads.add(wlKey);
24
+ for (const pod of wl.pods) {
25
+ const key = podKey(ns.name, wl.name, pod.name);
26
+ prevPods.add(key);
27
+ }
28
+ }
29
+ }
30
+ // Collect all pods and workloads from next tree
31
+ for (const ns of next.namespaces) {
32
+ for (const wl of ns.workloads) {
33
+ const wlKey = workloadKey(ns.name, wl.name);
34
+ nextWorkloads.add(wlKey);
35
+ for (const pod of wl.pods) {
36
+ const key = podKey(ns.name, wl.name, pod.name);
37
+ nextPods.add(key);
38
+ }
39
+ }
40
+ }
41
+ // Detect added pods
42
+ for (const pod of nextPods) {
43
+ if (!prevPods.has(pod)) {
44
+ result.added.push(pod);
45
+ }
46
+ }
47
+ // Detect removed pods
48
+ for (const pod of prevPods) {
49
+ if (!nextPods.has(pod)) {
50
+ result.removed.push(pod);
51
+ }
52
+ }
53
+ // Detect added workloads
54
+ for (const wl of nextWorkloads) {
55
+ if (!prevWorkloads.has(wl)) {
56
+ result.added.push(wl);
57
+ }
58
+ }
59
+ // Detect removed workloads
60
+ for (const wl of prevWorkloads) {
61
+ if (!nextWorkloads.has(wl)) {
62
+ result.removed.push(wl);
63
+ }
64
+ }
65
+ // Detect changed pods (phase change)
66
+ const prevPodMap = new Map();
67
+ const nextPodMap = new Map();
68
+ for (const ns of prev.namespaces) {
69
+ for (const wl of ns.workloads) {
70
+ for (const pod of wl.pods) {
71
+ const key = podKey(ns.name, wl.name, pod.name);
72
+ prevPodMap.set(key, pod);
73
+ }
74
+ }
75
+ }
76
+ for (const ns of next.namespaces) {
77
+ for (const wl of ns.workloads) {
78
+ for (const pod of wl.pods) {
79
+ const key = podKey(ns.name, wl.name, pod.name);
80
+ nextPodMap.set(key, pod);
81
+ }
82
+ }
83
+ }
84
+ for (const [key, nextPod] of nextPodMap) {
85
+ const prevPod = prevPodMap.get(key);
86
+ if (prevPod && prevPod.phase !== nextPod.phase) {
87
+ result.changed.push(key);
88
+ }
89
+ }
90
+ // Detect changed workloads (ready count change)
91
+ const prevWlMap = new Map();
92
+ const nextWlMap = new Map();
93
+ for (const ns of prev.namespaces) {
94
+ for (const wl of ns.workloads) {
95
+ const key = workloadKey(ns.name, wl.name);
96
+ prevWlMap.set(key, wl);
97
+ }
98
+ }
99
+ for (const ns of next.namespaces) {
100
+ for (const wl of ns.workloads) {
101
+ const key = workloadKey(ns.name, wl.name);
102
+ nextWlMap.set(key, wl);
103
+ }
104
+ }
105
+ for (const [key, nextWl] of nextWlMap) {
106
+ const prevWl = prevWlMap.get(key);
107
+ if (prevWl && prevWl.ready !== nextWl.ready) {
108
+ result.changed.push(key);
109
+ }
110
+ }
111
+ return result;
112
+ }
113
+ //# sourceMappingURL=differ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"differ.js","sourceRoot":"","sources":["../../src/watch/differ.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function useFlash(changedKeys: string[], duration?: number): Set<string>;
2
+ //# sourceMappingURL=flash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flash.d.ts","sourceRoot":"","sources":["../../src/watch/flash.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,QAAQ,SAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAW3E"}
@@ -0,0 +1,13 @@
1
+ import { useState, useEffect } from 'react';
2
+ export function useFlash(changedKeys, duration = 300) {
3
+ const [flashing, setFlashing] = useState(new Set());
4
+ useEffect(() => {
5
+ if (changedKeys.length === 0)
6
+ return;
7
+ setFlashing(new Set(changedKeys));
8
+ const timer = setTimeout(() => setFlashing(new Set()), duration);
9
+ return () => clearTimeout(timer);
10
+ }, [changedKeys, duration]);
11
+ return flashing;
12
+ }
13
+ //# sourceMappingURL=flash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flash.js","sourceRoot":"","sources":["../../src/watch/flash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5C,MAAM,UAAU,QAAQ,CAAC,WAAqB,EAAE,QAAQ,GAAG,GAAG;IAC5D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IAEjE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACrC,WAAW,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;QACjE,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE5B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kubechart",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "Visualize Kubernetes cluster as ASCII tree in your terminal",
6
6
  "bin": {
@@ -39,10 +39,12 @@
39
39
  "@kubernetes/client-node": "^0.21.0",
40
40
  "commander": "^12.0.0",
41
41
  "ink": "^4.4.1",
42
+ "js-yaml": "^4.1.0",
42
43
  "react": "^18.2.0"
43
44
  },
44
45
  "devDependencies": {
45
46
  "@types/jest": "^29.5.0",
47
+ "@types/js-yaml": "^4.0.0",
46
48
  "@types/node": "^20.0.0",
47
49
  "@types/react": "^18.2.0",
48
50
  "@typescript-eslint/eslint-plugin": "^7.0.0",