@hartvig/developer-control-center 0.8.6 → 0.8.8

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 (103) hide show
  1. package/.developer-control-center/metrics.json +1 -1
  2. package/.developer-control-center/status.json +1 -1
  3. package/.developer-control-center/timings.jsonl +25 -0
  4. package/.github/workflows/ci.yml +1 -7
  5. package/coverage/Developer Control Center/dcc.config.js.html +628 -0
  6. package/coverage/Developer Control Center/index.html +116 -0
  7. package/coverage/Developer Control Center/src/config/index.html +116 -0
  8. package/coverage/Developer Control Center/src/config/loader.ts.html +454 -0
  9. package/coverage/Developer Control Center/src/core/ci.ts.html +163 -0
  10. package/coverage/Developer Control Center/src/core/event-bus.ts.html +187 -0
  11. package/coverage/Developer Control Center/src/core/index.html +191 -0
  12. package/coverage/Developer Control Center/src/core/notifier.ts.html +187 -0
  13. package/coverage/Developer Control Center/src/core/persistence.ts.html +88 -0
  14. package/coverage/Developer Control Center/src/core/task-runner.ts.html +1498 -0
  15. package/coverage/Developer Control Center/src/core/workspaces.ts.html +304 -0
  16. package/coverage/Developer Control Center/src/plugins/index.html +116 -0
  17. package/coverage/Developer Control Center/src/plugins/manager.ts.html +259 -0
  18. package/coverage/Developer Control Center/src/status/index.html +116 -0
  19. package/coverage/Developer Control Center/src/status/store.ts.html +349 -0
  20. package/coverage/Developer Control Center/src/ui/command-list.tsx.html +574 -0
  21. package/coverage/Developer Control Center/src/ui/index.html +161 -0
  22. package/coverage/Developer Control Center/src/ui/metrics-panel.tsx.html +787 -0
  23. package/coverage/Developer Control Center/src/ui/panel.tsx.html +313 -0
  24. package/coverage/Developer Control Center/src/ui/status-panel.tsx.html +565 -0
  25. package/coverage/base.css +224 -0
  26. package/coverage/block-navigation.js +87 -0
  27. package/coverage/clover.xml +588 -0
  28. package/coverage/coverage-final.json +15 -0
  29. package/coverage/favicon.png +0 -0
  30. package/coverage/index.html +191 -0
  31. package/coverage/prettify.css +1 -0
  32. package/coverage/prettify.js +2 -0
  33. package/coverage/sort-arrow-sprite.png +0 -0
  34. package/coverage/sorter.js +210 -0
  35. package/dcc.config.js +2 -2
  36. package/dist/cli.js +1 -1
  37. package/dist/core/persistence.d.ts +2 -0
  38. package/dist/core/persistence.d.ts.map +1 -0
  39. package/dist/core/persistence.js +2 -0
  40. package/dist/core/persistence.js.map +1 -0
  41. package/dist/core/runtime.d.ts.map +1 -1
  42. package/dist/core/runtime.js +5 -3
  43. package/dist/core/runtime.js.map +1 -1
  44. package/dist/core/task-runner.d.ts +1 -0
  45. package/dist/core/task-runner.d.ts.map +1 -1
  46. package/dist/core/task-runner.js +81 -24
  47. package/dist/core/task-runner.js.map +1 -1
  48. package/dist/core/task-runner.test.d.ts +2 -0
  49. package/dist/core/task-runner.test.d.ts.map +1 -0
  50. package/dist/core/task-runner.test.js +326 -0
  51. package/dist/core/task-runner.test.js.map +1 -0
  52. package/dist/core/timer-plugin.d.ts.map +1 -1
  53. package/dist/core/timer-plugin.js +2 -1
  54. package/dist/core/timer-plugin.js.map +1 -1
  55. package/dist/plugins/manager.d.ts +2 -0
  56. package/dist/plugins/manager.d.ts.map +1 -1
  57. package/dist/plugins/manager.js +6 -2
  58. package/dist/plugins/manager.js.map +1 -1
  59. package/dist/plugins/manager.test.js +5 -2
  60. package/dist/plugins/manager.test.js.map +1 -1
  61. package/dist/ui/app.d.ts.map +1 -1
  62. package/dist/ui/app.js +124 -30
  63. package/dist/ui/app.js.map +1 -1
  64. package/dist/ui/app.test.d.ts +2 -0
  65. package/dist/ui/app.test.d.ts.map +1 -0
  66. package/dist/ui/app.test.js +157 -0
  67. package/dist/ui/app.test.js.map +1 -0
  68. package/dist/ui/command-list.test.d.ts +2 -0
  69. package/dist/ui/command-list.test.d.ts.map +1 -0
  70. package/dist/ui/command-list.test.js +104 -0
  71. package/dist/ui/command-list.test.js.map +1 -0
  72. package/dist/ui/metrics-panel.d.ts.map +1 -1
  73. package/dist/ui/metrics-panel.js +10 -9
  74. package/dist/ui/metrics-panel.js.map +1 -1
  75. package/dist/ui/metrics-panel.test.d.ts +2 -0
  76. package/dist/ui/metrics-panel.test.d.ts.map +1 -0
  77. package/dist/ui/metrics-panel.test.js +111 -0
  78. package/dist/ui/metrics-panel.test.js.map +1 -0
  79. package/dist/ui/panel.test.d.ts +2 -0
  80. package/dist/ui/panel.test.d.ts.map +1 -0
  81. package/dist/ui/panel.test.js +51 -0
  82. package/dist/ui/panel.test.js.map +1 -0
  83. package/dist/ui/status-panel.test.d.ts +2 -0
  84. package/dist/ui/status-panel.test.d.ts.map +1 -0
  85. package/dist/ui/status-panel.test.js +88 -0
  86. package/dist/ui/status-panel.test.js.map +1 -0
  87. package/package.json +4 -2
  88. package/src/cli.ts +1 -1
  89. package/src/core/persistence.ts +1 -0
  90. package/src/core/runtime.ts +7 -3
  91. package/src/core/task-runner.test.ts +395 -0
  92. package/src/core/task-runner.ts +80 -24
  93. package/src/core/timer-plugin.ts +2 -1
  94. package/src/plugins/manager.test.ts +5 -2
  95. package/src/plugins/manager.ts +6 -2
  96. package/src/ui/app.test.tsx +177 -0
  97. package/src/ui/app.tsx +167 -41
  98. package/src/ui/command-list.test.tsx +124 -0
  99. package/src/ui/metrics-panel.test.tsx +128 -0
  100. package/src/ui/metrics-panel.tsx +10 -10
  101. package/src/ui/panel.test.tsx +84 -0
  102. package/src/ui/status-panel.test.tsx +116 -0
  103. package/vitest.config.ts +1 -1
@@ -0,0 +1,157 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
3
+ import { act } from 'react';
4
+ import { render } from 'ink-testing-library';
5
+ import { App } from './app.js';
6
+ import { EventBus } from '../core/event-bus.js';
7
+ import { StatusStore } from '../status/store.js';
8
+ function createMockRuntime() {
9
+ const eventBus = new EventBus();
10
+ const statusStore = new StatusStore();
11
+ const taskRunner = {
12
+ run: vi.fn().mockResolvedValue(undefined),
13
+ stop: vi.fn(),
14
+ abortAll: vi.fn(),
15
+ setCommands: vi.fn(),
16
+ abort: vi.fn(),
17
+ };
18
+ return {
19
+ eventBus,
20
+ statusStore,
21
+ taskRunner,
22
+ pluginManager: { register: vi.fn(), executeHook: vi.fn(), loadFromConfig: vi.fn() },
23
+ gitBranch: 'main',
24
+ workspaces: [],
25
+ ci: { isCI: false, name: undefined },
26
+ stop: vi.fn(),
27
+ };
28
+ }
29
+ const baseConfig = {
30
+ name: 'test-project',
31
+ commands: [
32
+ { id: 'build', label: 'Build', command: 'npm run build', description: 'Build the project' },
33
+ { id: 'test', label: 'Test', command: 'npm test' },
34
+ ],
35
+ };
36
+ describe('App', () => {
37
+ let runtime;
38
+ beforeEach(() => {
39
+ runtime = createMockRuntime();
40
+ });
41
+ afterEach(() => {
42
+ vi.restoreAllMocks();
43
+ });
44
+ it('renders the project name in the header', () => {
45
+ const { lastFrame } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
46
+ expect(lastFrame()).toContain('test-project');
47
+ });
48
+ it('shows the git branch', () => {
49
+ const { lastFrame } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
50
+ expect(lastFrame()).toContain('⎇ main');
51
+ });
52
+ it('renders command items', () => {
53
+ const { lastFrame } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
54
+ const frame = lastFrame();
55
+ expect(frame).toContain('Build');
56
+ expect(frame).toContain('Test');
57
+ });
58
+ it('shows no tasks yet in output panel', () => {
59
+ const { lastFrame } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
60
+ expect(lastFrame()).toContain('No tasks yet');
61
+ });
62
+ it('shows selected command description in footer', () => {
63
+ const { lastFrame } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
64
+ expect(lastFrame()).toContain('Build the project');
65
+ });
66
+ it('renders with groups', () => {
67
+ const config = {
68
+ name: 'test',
69
+ commands: [
70
+ { id: 'build', label: 'Build', command: 'npm run build', group: 'Build' },
71
+ { id: 'test', label: 'Test', command: 'npm test', group: 'Test' },
72
+ ],
73
+ };
74
+ const { lastFrame } = render(_jsx(App, { config: config, runtime: runtime }));
75
+ expect(lastFrame()).toContain('▶ Build');
76
+ expect(lastFrame()).toContain('▶ Test');
77
+ });
78
+ it('shows active profile in header', () => {
79
+ const config = {
80
+ name: 'test',
81
+ commands: [{ id: 'build', label: 'Build', command: 'npm run build' }],
82
+ profiles: { prod: { commands: [] } },
83
+ profile: 'prod',
84
+ };
85
+ const { lastFrame } = render(_jsx(App, { config: config, runtime: runtime }));
86
+ expect(lastFrame()).toContain('⚙ prod');
87
+ });
88
+ it('shows workspace count when present', () => {
89
+ runtime.workspaces = [{ name: 'pkg-a', path: '/pkg-a' }];
90
+ const { lastFrame } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
91
+ expect(lastFrame()).toContain('⊞ 1');
92
+ });
93
+ it('handles status store updates', () => {
94
+ const { lastFrame } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
95
+ act(() => {
96
+ runtime.statusStore.updateTask('build', {
97
+ id: 'build',
98
+ label: 'Build',
99
+ status: 'running',
100
+ output: 'compiling...',
101
+ });
102
+ });
103
+ const frame = lastFrame();
104
+ expect(frame).toContain('compiling...');
105
+ });
106
+ it('shows confirm prompt for confirm commands', () => {
107
+ const config = {
108
+ name: 'test',
109
+ commands: [
110
+ { id: 'deploy', label: 'Deploy', command: 'npm run deploy', confirm: true },
111
+ ],
112
+ };
113
+ const { lastFrame, stdin } = render(_jsx(App, { config: config, runtime: runtime }));
114
+ act(() => { stdin.write('\r'); });
115
+ const frame = lastFrame();
116
+ expect(frame).toContain('⚠');
117
+ });
118
+ it('shows DCC in header', () => {
119
+ const { lastFrame } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
120
+ expect(lastFrame()).toContain('DCC');
121
+ });
122
+ it('shows status pane (middle panel)', () => {
123
+ const { lastFrame } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
124
+ expect(lastFrame()).toContain('Status');
125
+ });
126
+ it('shows output pane (right panel)', () => {
127
+ const { lastFrame } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
128
+ expect(lastFrame()).toContain('Output');
129
+ });
130
+ it('shows CI badge when in CI environment', () => {
131
+ runtime.ci = { isCI: true, name: 'GitHub Actions' };
132
+ const { lastFrame } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
133
+ expect(lastFrame()).toContain('⊡ GitHub Actions');
134
+ });
135
+ it('switches pane focus on Tab', () => {
136
+ const { lastFrame, stdin } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
137
+ act(() => { stdin.write('\t'); });
138
+ const frame = lastFrame();
139
+ expect(frame).toContain('Output');
140
+ });
141
+ it('enters search mode on / key', () => {
142
+ const { lastFrame, stdin } = render(_jsx(App, { config: baseConfig, runtime: runtime }));
143
+ act(() => { stdin.write('/'); });
144
+ expect(lastFrame()).toContain('🔍');
145
+ });
146
+ it('shows default footer hint for command without description', () => {
147
+ const config = {
148
+ name: 'test',
149
+ commands: [
150
+ { id: 'foo', label: 'Foo', command: 'echo foo' },
151
+ ],
152
+ };
153
+ const { lastFrame } = render(_jsx(App, { config: config, runtime: runtime }));
154
+ expect(lastFrame()).toContain('Enter to run');
155
+ });
156
+ });
157
+ //# sourceMappingURL=app.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.test.js","sourceRoot":"","sources":["../../src/ui/app.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=command-list.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-list.test.d.ts","sourceRoot":"","sources":["../../src/ui/command-list.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,104 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, it, expect } from 'vitest';
3
+ import { render } from 'ink-testing-library';
4
+ import { CommandList } from './command-list.js';
5
+ const baseProps = {
6
+ items: [],
7
+ selectedIndex: 0,
8
+ width: 50,
9
+ menuRows: 10,
10
+ };
11
+ describe('CommandList', () => {
12
+ it('shows no commands configured when empty', () => {
13
+ const { lastFrame } = render(_jsx(CommandList, { ...baseProps }));
14
+ expect(lastFrame()).toContain('No commands configured');
15
+ });
16
+ it('renders command items', () => {
17
+ const items = [
18
+ { id: 'build', label: 'Build', command: 'npm run build' },
19
+ { id: 'test', label: 'Test', command: 'npm test' },
20
+ ];
21
+ const { lastFrame } = render(_jsx(CommandList, { ...baseProps, items: items }));
22
+ const frame = lastFrame();
23
+ expect(frame).toContain('Build');
24
+ expect(frame).toContain('Test');
25
+ });
26
+ it('shows cursor on selected item', () => {
27
+ const items = [
28
+ { id: 'build', label: 'Build', command: 'npm run build' },
29
+ { id: 'test', label: 'Test', command: 'npm test' },
30
+ ];
31
+ const { lastFrame } = render(_jsx(CommandList, { ...baseProps, items: items, selectedIndex: 0 }));
32
+ expect(lastFrame()).toContain('❯');
33
+ });
34
+ it('shows group headers', () => {
35
+ const items = [
36
+ { id: 'dev', label: 'Development', count: 2 },
37
+ { id: 'build', label: 'Build', command: 'npm run build' },
38
+ ];
39
+ const { lastFrame } = render(_jsx(CommandList, { ...baseProps, items: items }));
40
+ const frame = lastFrame();
41
+ expect(frame).toContain('▶ Development');
42
+ });
43
+ it('renders profile options', () => {
44
+ const items = [
45
+ { kind: 'profile', id: 'p1', label: 'Production', active: false },
46
+ ];
47
+ const { lastFrame } = render(_jsx(CommandList, { ...baseProps, items: items }));
48
+ const frame = lastFrame();
49
+ expect(frame).toContain('Production');
50
+ expect(frame).toContain('○');
51
+ });
52
+ it('shows active profile with filled circle', () => {
53
+ const items = [
54
+ { kind: 'profile', id: 'p1', label: 'Default', active: true },
55
+ ];
56
+ const { lastFrame } = render(_jsx(CommandList, { ...baseProps, items: items }));
57
+ expect(lastFrame()).toContain('●');
58
+ });
59
+ it('shows multi-select checkboxes', () => {
60
+ const items = [
61
+ { id: 'a', label: 'A', command: 'echo a' },
62
+ { id: 'b', label: 'B', command: 'echo b' },
63
+ ];
64
+ const { lastFrame } = render(_jsx(CommandList, { ...baseProps, items: items, multiSelected: new Set(['a']) }));
65
+ expect(lastFrame()).toContain('[✓]');
66
+ });
67
+ it('shows cwd badge when present', () => {
68
+ const items = [
69
+ { id: 'build', label: 'Build', command: 'npm run build', cwd: '/tmp' },
70
+ ];
71
+ const { lastFrame } = render(_jsx(CommandList, { ...baseProps, items: items }));
72
+ expect(lastFrame()).toContain('/tmp');
73
+ });
74
+ it('shows pipeline badge', () => {
75
+ const items = [
76
+ { id: 'pipe', label: 'Pipeline', command: '', pipelineSteps: ['a', 'b'] },
77
+ ];
78
+ const { lastFrame } = render(_jsx(CommandList, { ...baseProps, items: items }));
79
+ expect(lastFrame()).toContain('pipeline');
80
+ });
81
+ it('shows watch badge', () => {
82
+ const items = [
83
+ { id: 'w', label: 'Watch', command: 'npm run dev', watch: true },
84
+ ];
85
+ const { lastFrame } = render(_jsx(CommandList, { ...baseProps, items: items }));
86
+ expect(lastFrame()).toContain('watch');
87
+ });
88
+ it('shows focused border color when focused', () => {
89
+ const items = [
90
+ { id: 'build', label: 'Build', command: 'npm run build' },
91
+ ];
92
+ const { lastFrame } = render(_jsx(CommandList, { ...baseProps, items: items, focused: true }));
93
+ expect(lastFrame()).toContain('Commands');
94
+ });
95
+ it('shows selection count in title', () => {
96
+ const items = [
97
+ { id: 'a', label: 'A', command: 'echo a' },
98
+ { id: 'b', label: 'B', command: 'echo b' },
99
+ ];
100
+ const { lastFrame } = render(_jsx(CommandList, { ...baseProps, items: items, selCount: 2, multiSelected: new Set(['a', 'b']) }));
101
+ expect(lastFrame()).toContain('(2 selected)');
102
+ });
103
+ });
104
+ //# sourceMappingURL=command-list.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-list.test.js","sourceRoot":"","sources":["../../src/ui/command-list.test.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"metrics-panel.d.ts","sourceRoot":"","sources":["../../src/ui/metrics-panel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAc,MAAM,oBAAoB,CAAC;AAG3D,UAAU,iBAAiB;IACzB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAqGD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAyHpD,CAAC"}
1
+ {"version":3,"file":"metrics-panel.d.ts","sourceRoot":"","sources":["../../src/ui/metrics-panel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAc,MAAM,oBAAoB,CAAC;AAI3D,UAAU,iBAAiB;IACzB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAoGD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAyHpD,CAAC"}
@@ -3,13 +3,9 @@ import fs from 'fs';
3
3
  import path from 'path';
4
4
  import { useEffect, useState } from 'react';
5
5
  import { Box, Text } from 'ink';
6
+ import { PERSISTENCE_DIR } from '../core/persistence.js';
6
7
  import { Panel } from './panel.js';
7
- const METRICS_FILE = path.join(process.cwd(), '.developer-control-center', 'metrics.json');
8
- const INITIAL_METRICS = {
9
- projectRunning: false,
10
- activeTasks: 0,
11
- packageVersion: loadPackageVersion(),
12
- };
8
+ const METRICS_FILE = path.join(process.cwd(), PERSISTENCE_DIR, 'metrics.json');
13
9
  function loadPackageVersion() {
14
10
  try {
15
11
  const packageJson = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8'));
@@ -20,17 +16,22 @@ function loadPackageVersion() {
20
16
  }
21
17
  }
22
18
  function loadMetrics() {
19
+ const base = {
20
+ projectRunning: false,
21
+ activeTasks: 0,
22
+ packageVersion: loadPackageVersion(),
23
+ };
23
24
  try {
24
25
  const persisted = JSON.parse(fs.readFileSync(METRICS_FILE, 'utf-8'));
25
26
  return {
26
- ...INITIAL_METRICS,
27
+ ...base,
27
28
  latestTest: persisted.latestTest,
28
29
  latestBuild: persisted.latestBuild,
29
30
  lastGitPush: persisted.lastGitPush,
30
31
  };
31
32
  }
32
33
  catch {
33
- return INITIAL_METRICS;
34
+ return base;
34
35
  }
35
36
  }
36
37
  function isBumpTask(task) {
@@ -126,7 +127,7 @@ export const MetricsPanel = ({ tasks, menuRows, width }) => {
126
127
  return next;
127
128
  });
128
129
  }, [tasks]);
129
- return (_jsxs(Panel, { title: "Status", width: width, height: menuRows + 2, children: [_jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { color: metrics.projectRunning ? 'yellow' : 'gray', children: ["Project: ", metrics.projectRunning ? 'running' : 'idle'] }) }), _jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { color: "gray", children: ["Active: ", metrics.activeTasks] }) }), _jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { color: "gray", children: ["Version: ", metrics.packageVersion] }) }), _jsx(Box, { paddingLeft: 1, children: _jsx(Text, { color: "gray", children: '\u2500'.repeat(Math.max(0, width - 4)) }) }), _jsx(Box, { paddingLeft: 1, children: !metrics.latestTest ? (_jsx(Text, { color: "gray", children: "Tests: no run" })) : (_jsxs(Text, { color: metrics.latestTest.status === 'success' ? 'green' :
130
+ return (_jsxs(Panel, { title: "Status", titleColor: "white", width: width, height: menuRows + 2, children: [_jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { color: metrics.projectRunning ? 'yellow' : 'gray', children: ["Project: ", metrics.projectRunning ? 'running' : 'idle'] }) }), _jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { color: "gray", children: ["Active: ", metrics.activeTasks] }) }), _jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { color: "gray", children: ["Version: ", metrics.packageVersion] }) }), _jsx(Box, { paddingLeft: 1, children: _jsx(Text, { color: "gray", children: '\u2500'.repeat(Math.max(0, width - 4)) }) }), _jsx(Box, { paddingLeft: 1, children: !metrics.latestTest ? (_jsx(Text, { color: "gray", children: "Tests: no run" })) : (_jsxs(Text, { color: metrics.latestTest.status === 'success' ? 'green' :
130
131
  metrics.latestTest.status === 'failure' ? 'red' :
131
132
  metrics.latestTest.status === 'running' ? 'yellow' : 'gray', children: ["Tests: ", metrics.latestTest.status === 'success' ? 'passed' :
132
133
  metrics.latestTest.status === 'failure' ? 'failed' :
@@ -1 +1 @@
1
- {"version":3,"file":"metrics-panel.js","sourceRoot":"","sources":["../../src/ui/metrics-panel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"metrics-panel.js","sourceRoot":"","sources":["../../src/ui/metrics-panel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=metrics-panel.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-panel.test.d.ts","sourceRoot":"","sources":["../../src/ui/metrics-panel.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,111 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
3
+ import { act } from 'react';
4
+ import { render } from 'ink-testing-library';
5
+ import fs from 'fs';
6
+ import { MetricsPanel } from './metrics-panel.js';
7
+ function makeMetricsData(overrides = {}) {
8
+ return JSON.stringify({
9
+ version: '1.0.0',
10
+ latestTest: { label: 'Unit Tests', status: 'success', time: Date.now() - 60000 },
11
+ latestBuild: { status: 'failure', time: Date.now() - 120000 },
12
+ ...overrides,
13
+ });
14
+ }
15
+ vi.mock('fs', () => ({
16
+ default: {
17
+ readFileSync: vi.fn(() => makeMetricsData()),
18
+ writeFileSync: vi.fn(),
19
+ mkdirSync: vi.fn(),
20
+ existsSync: vi.fn(),
21
+ },
22
+ readFileSync: vi.fn(() => makeMetricsData()),
23
+ writeFileSync: vi.fn(),
24
+ mkdirSync: vi.fn(),
25
+ existsSync: vi.fn(),
26
+ }));
27
+ const mockReadFileSync = () => vi.mocked(fs).readFileSync;
28
+ const mockTasks = (entries) => new Map(Object.entries(entries));
29
+ describe('MetricsPanel', () => {
30
+ const baseProps = {
31
+ tasks: new Map(),
32
+ width: 28,
33
+ menuRows: 10,
34
+ };
35
+ beforeEach(() => {
36
+ mockReadFileSync().mockReturnValue(makeMetricsData());
37
+ });
38
+ it('shows idle status when no tasks are running', () => {
39
+ const { lastFrame } = render(_jsx(MetricsPanel, { ...baseProps }));
40
+ expect(lastFrame()).toContain('idle');
41
+ });
42
+ it('displays the package version', () => {
43
+ const { lastFrame } = render(_jsx(MetricsPanel, { ...baseProps }));
44
+ expect(lastFrame()).toContain('Version: 1.0.0');
45
+ });
46
+ it('shows active task count for running tasks', async () => {
47
+ const tasks = mockTasks({
48
+ build: { id: 'build', label: 'Build', status: 'running', startTime: Date.now() },
49
+ test: { id: 'test', label: 'Test', status: 'running', startTime: Date.now() },
50
+ });
51
+ const { lastFrame, rerender } = render(_jsx(MetricsPanel, { ...baseProps }));
52
+ await act(async () => {
53
+ rerender(_jsx(MetricsPanel, { ...baseProps, tasks: tasks }));
54
+ });
55
+ const frame = lastFrame();
56
+ expect(frame).toContain('Active: 2');
57
+ expect(frame).toContain('running');
58
+ });
59
+ it('shows test passed status with time ago', () => {
60
+ const { lastFrame } = render(_jsx(MetricsPanel, { ...baseProps }));
61
+ const frame = lastFrame();
62
+ expect(frame).toContain('Tests: passed');
63
+ expect(frame).toContain('1m ago');
64
+ });
65
+ it('shows test failure status', () => {
66
+ mockReadFileSync().mockReturnValue(makeMetricsData({
67
+ latestTest: { label: 'Tests', status: 'failure', time: Date.now() - 30000 },
68
+ }));
69
+ const { lastFrame } = render(_jsx(MetricsPanel, { ...baseProps }));
70
+ expect(lastFrame()).toContain('Tests: failed');
71
+ });
72
+ it('shows no test run when no test data', () => {
73
+ mockReadFileSync().mockReturnValue(makeMetricsData({ latestTest: undefined }));
74
+ const { lastFrame } = render(_jsx(MetricsPanel, { ...baseProps }));
75
+ expect(lastFrame()).toContain('Tests: no run');
76
+ });
77
+ it('shows build failed status', () => {
78
+ const { lastFrame } = render(_jsx(MetricsPanel, { ...baseProps }));
79
+ expect(lastFrame()).toContain('Build: failed');
80
+ });
81
+ it('shows build passed status', () => {
82
+ mockReadFileSync().mockReturnValue(makeMetricsData({
83
+ latestBuild: { status: 'success', time: Date.now() - 300000 },
84
+ }));
85
+ const { lastFrame } = render(_jsx(MetricsPanel, { ...baseProps }));
86
+ expect(lastFrame()).toContain('Build: passed');
87
+ });
88
+ it('shows no build run when no build data', () => {
89
+ mockReadFileSync().mockReturnValue(makeMetricsData({ latestBuild: undefined }));
90
+ const { lastFrame } = render(_jsx(MetricsPanel, { ...baseProps }));
91
+ expect(lastFrame()).toContain('Build: no run');
92
+ });
93
+ it('shows last git push timestamp', () => {
94
+ const pushTime = new Date('2026-06-24T10:00:00').getTime();
95
+ mockReadFileSync().mockReturnValue(makeMetricsData({
96
+ lastGitPush: { label: 'main', time: pushTime },
97
+ }));
98
+ const { lastFrame } = render(_jsx(MetricsPanel, { ...baseProps }));
99
+ expect(lastFrame()).toContain('2026-06-24 10:00');
100
+ });
101
+ it('shows push dash when no push data', () => {
102
+ const { lastFrame } = render(_jsx(MetricsPanel, { ...baseProps }));
103
+ expect(lastFrame()).toContain('Push: -');
104
+ });
105
+ it('shows version dash when package.json is missing', () => {
106
+ mockReadFileSync().mockImplementation(() => { throw new Error('ENOENT'); });
107
+ const { lastFrame } = render(_jsx(MetricsPanel, { ...baseProps }));
108
+ expect(lastFrame()).toContain('Version: -');
109
+ });
110
+ });
111
+ //# sourceMappingURL=metrics-panel.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-panel.test.js","sourceRoot":"","sources":["../../src/ui/metrics-panel.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=panel.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel.test.d.ts","sourceRoot":"","sources":["../../src/ui/panel.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,51 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, it, expect } from 'vitest';
3
+ import React from 'react';
4
+ import { Box, Text } from 'ink';
5
+ import { render } from 'ink-testing-library';
6
+ import { Panel } from './panel.js';
7
+ describe('Panel', () => {
8
+ it('renders the title in the top border', () => {
9
+ const { lastFrame } = render(_jsx(Panel, { title: "Test", width: 20, height: 5, children: _jsx(React.Fragment, {}) }));
10
+ const frame = lastFrame();
11
+ expect(frame).toContain('╭─ Test');
12
+ });
13
+ it('renders proper bottom border', () => {
14
+ const { lastFrame } = render(_jsx(Panel, { title: "Test", width: 20, height: 5, children: _jsx(React.Fragment, {}) }));
15
+ const frame = lastFrame();
16
+ expect(frame).toContain('╰');
17
+ });
18
+ it('renders side borders for each content row', () => {
19
+ const { lastFrame } = render(_jsx(Panel, { title: "Test", width: 20, height: 5, children: _jsx(React.Fragment, {}) }));
20
+ const frame = lastFrame();
21
+ const lines = frame.split('\n');
22
+ expect(lines.length).toBe(5);
23
+ expect(lines[1].startsWith('│')).toBe(true);
24
+ expect(lines[1].endsWith('│')).toBe(true);
25
+ expect(lines[2].startsWith('│')).toBe(true);
26
+ expect(lines[2].endsWith('│')).toBe(true);
27
+ expect(lines[3].startsWith('│')).toBe(true);
28
+ expect(lines[3].endsWith('│')).toBe(true);
29
+ });
30
+ it('renders children in the content area', () => {
31
+ const { lastFrame } = render(_jsx(Panel, { title: "Test", width: 20, height: 5, children: _jsx(Box, { children: _jsx(Text, { children: "hello" }) }) }));
32
+ const frame = lastFrame();
33
+ expect(frame).toContain('hello');
34
+ });
35
+ it('shows "↑N more" when hiddenAbove is set', () => {
36
+ const { lastFrame } = render(_jsx(Panel, { title: "Test", width: 30, height: 5, hiddenAbove: 3, children: _jsx(React.Fragment, {}) }));
37
+ const frame = lastFrame();
38
+ expect(frame).toContain('↑3 more');
39
+ });
40
+ it('shows "↓N more" when hiddenBelow is set', () => {
41
+ const { lastFrame } = render(_jsx(Panel, { title: "Test", width: 30, height: 5, hiddenBelow: 2, children: _jsx(React.Fragment, {}) }));
42
+ const frame = lastFrame();
43
+ expect(frame).toContain('↓2 more');
44
+ });
45
+ it('renders titleExtra next to the title', () => {
46
+ const { lastFrame } = render(_jsx(Panel, { title: "Main", width: 30, height: 5, titleExtra: _jsx(Text, { children: " [extra]" }), children: _jsx(React.Fragment, {}) }));
47
+ const frame = lastFrame();
48
+ expect(frame).toContain('[extra]');
49
+ });
50
+ });
51
+ //# sourceMappingURL=panel.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel.test.js","sourceRoot":"","sources":["../../src/ui/panel.test.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAc,MAAM,QAAQ,CAAC;AAC1D,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAC1B,KAAC,KAAK,IAAC,KAAK,EAAC,MAAM,EAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,YACtC,KAAC,KAAK,CAAC,QAAQ,KAAG,GACZ,CACT,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAC1B,KAAC,KAAK,IAAC,KAAK,EAAC,MAAM,EAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,YACtC,KAAC,KAAK,CAAC,QAAQ,KAAG,GACZ,CACT,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAC1B,KAAC,KAAK,IAAC,KAAK,EAAC,MAAM,EAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,YACtC,KAAC,KAAK,CAAC,QAAQ,KAAG,GACZ,CACT,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,EAAG,CAAC;QAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAC1B,KAAC,KAAK,IAAC,KAAK,EAAC,MAAM,EAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,YACtC,KAAC,GAAG,cAAC,KAAC,IAAI,wBAAa,GAAM,GACvB,CACT,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAC1B,KAAC,KAAK,IAAC,KAAK,EAAC,MAAM,EAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,YACtD,KAAC,KAAK,CAAC,QAAQ,KAAG,GACZ,CACT,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAC1B,KAAC,KAAK,IAAC,KAAK,EAAC,MAAM,EAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,YACtD,KAAC,KAAK,CAAC,QAAQ,KAAG,GACZ,CACT,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAC1B,KAAC,KAAK,IAAC,KAAK,EAAC,MAAM,EAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,KAAC,IAAI,2BAAgB,YACzE,KAAC,KAAK,CAAC,QAAQ,KAAG,GACZ,CACT,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=status-panel.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-panel.test.d.ts","sourceRoot":"","sources":["../../src/ui/status-panel.test.tsx"],"names":[],"mappings":""}