@pennyfarthing/cyclist 10.4.0 → 11.0.0-alpha.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/api/agent-load.d.ts +1 -2
- package/dist/api/agent-load.d.ts.map +1 -1
- package/dist/api/agent-load.js +2 -123
- package/dist/api/agent-load.js.map +1 -1
- package/dist/api/audit-log.d.ts +1 -17
- package/dist/api/audit-log.d.ts.map +1 -1
- package/dist/api/audit-log.js +2 -162
- package/dist/api/audit-log.js.map +1 -1
- package/dist/api/background-tasks.d.ts +1 -26
- package/dist/api/background-tasks.d.ts.map +1 -1
- package/dist/api/background-tasks.js +2 -55
- package/dist/api/background-tasks.js.map +1 -1
- package/dist/api/bell.d.ts +1 -18
- package/dist/api/bell.d.ts.map +1 -1
- package/dist/api/bell.js +2 -33
- package/dist/api/bell.js.map +1 -1
- package/dist/api/code-markers.d.ts +1 -8
- package/dist/api/code-markers.d.ts.map +1 -1
- package/dist/api/code-markers.js +2 -61
- package/dist/api/code-markers.js.map +1 -1
- package/dist/api/complexity.d.ts +1 -2
- package/dist/api/complexity.d.ts.map +1 -1
- package/dist/api/complexity.js +2 -46
- package/dist/api/complexity.js.map +1 -1
- package/dist/api/context.d.ts +1 -37
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +2 -143
- package/dist/api/context.js.map +1 -1
- package/dist/api/dead-code.d.ts +1 -2
- package/dist/api/dead-code.d.ts.map +1 -1
- package/dist/api/dead-code.js +2 -69
- package/dist/api/dead-code.js.map +1 -1
- package/dist/api/dependencies.d.ts +1 -2
- package/dist/api/dependencies.d.ts.map +1 -1
- package/dist/api/dependencies.js +2 -42
- package/dist/api/dependencies.js.map +1 -1
- package/dist/api/evaluation.d.ts +1 -19
- package/dist/api/evaluation.d.ts.map +1 -1
- package/dist/api/evaluation.js +2 -127
- package/dist/api/evaluation.js.map +1 -1
- package/dist/api/file-browser.d.ts +1 -8
- package/dist/api/file-browser.d.ts.map +1 -1
- package/dist/api/file-browser.js +2 -114
- package/dist/api/file-browser.js.map +1 -1
- package/dist/api/git.d.ts +1 -46
- package/dist/api/git.d.ts.map +1 -1
- package/dist/api/git.js +2 -354
- package/dist/api/git.js.map +1 -1
- package/dist/api/health-score.d.ts +1 -2
- package/dist/api/health-score.d.ts.map +1 -1
- package/dist/api/health-score.js +2 -46
- package/dist/api/health-score.js.map +1 -1
- package/dist/api/hook-request.d.ts +1 -40
- package/dist/api/hook-request.d.ts.map +1 -1
- package/dist/api/hook-request.js +2 -277
- package/dist/api/hook-request.js.map +1 -1
- package/dist/api/hotspots.d.ts +1 -2
- package/dist/api/hotspots.d.ts.map +1 -1
- package/dist/api/hotspots.js +2 -61
- package/dist/api/hotspots.js.map +1 -1
- package/dist/api/identity.d.ts +1 -16
- package/dist/api/identity.d.ts.map +1 -1
- package/dist/api/identity.js +2 -78
- package/dist/api/identity.js.map +1 -1
- package/dist/api/index.d.ts +1 -34
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -44
- package/dist/api/index.js.map +1 -1
- package/dist/api/mode.d.ts +1 -22
- package/dist/api/mode.d.ts.map +1 -1
- package/dist/api/mode.js +2 -37
- package/dist/api/mode.js.map +1 -1
- package/dist/api/otlp.d.ts +1 -2
- package/dist/api/otlp.d.ts.map +1 -1
- package/dist/api/otlp.js +2 -46
- package/dist/api/otlp.js.map +1 -1
- package/dist/api/permissions.d.ts +1 -15
- package/dist/api/permissions.d.ts.map +1 -1
- package/dist/api/permissions.js +2 -66
- package/dist/api/permissions.js.map +1 -1
- package/dist/api/persona.d.ts +1 -8
- package/dist/api/persona.d.ts.map +1 -1
- package/dist/api/persona.js +2 -67
- package/dist/api/persona.js.map +1 -1
- package/dist/api/portrait.d.ts +1 -5
- package/dist/api/portrait.d.ts.map +1 -1
- package/dist/api/portrait.js +2 -27
- package/dist/api/portrait.js.map +1 -1
- package/dist/api/settings.d.ts +1 -53
- package/dist/api/settings.d.ts.map +1 -1
- package/dist/api/settings.js +2 -464
- package/dist/api/settings.js.map +1 -1
- package/dist/api/spans.d.ts +1 -16
- package/dist/api/spans.d.ts.map +1 -1
- package/dist/api/spans.js +2 -244
- package/dist/api/spans.js.map +1 -1
- package/dist/api/stats.d.ts +1 -12
- package/dist/api/stats.d.ts.map +1 -1
- package/dist/api/stats.js +2 -84
- package/dist/api/stats.js.map +1 -1
- package/dist/api/story.d.ts +1 -2
- package/dist/api/story.d.ts.map +1 -1
- package/dist/api/story.js +2 -14
- package/dist/api/story.js.map +1 -1
- package/dist/api/telemetry.d.ts +1 -18
- package/dist/api/telemetry.d.ts.map +1 -1
- package/dist/api/telemetry.js +2 -164
- package/dist/api/telemetry.js.map +1 -1
- package/dist/api/theme-agents.d.ts +1 -60
- package/dist/api/theme-agents.d.ts.map +1 -1
- package/dist/api/theme-agents.js +2 -213
- package/dist/api/theme-agents.js.map +1 -1
- package/dist/api/todos.d.ts +1 -32
- package/dist/api/todos.d.ts.map +1 -1
- package/dist/api/todos.js +2 -43
- package/dist/api/todos.js.map +1 -1
- package/dist/api/token-stats.d.ts +1 -7
- package/dist/api/token-stats.d.ts.map +1 -1
- package/dist/api/token-stats.js +2 -35
- package/dist/api/token-stats.js.map +1 -1
- package/dist/api/welcome.d.ts +1 -21
- package/dist/api/welcome.d.ts.map +1 -1
- package/dist/api/welcome.js +2 -34
- package/dist/api/welcome.js.map +1 -1
- package/dist/env.d.ts +6 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +10 -0
- package/dist/env.js.map +1 -0
- package/dist/focus.d.ts +53 -0
- package/dist/focus.d.ts.map +1 -0
- package/dist/focus.js +122 -0
- package/dist/focus.js.map +1 -0
- package/dist/menu-builder.d.ts.map +1 -1
- package/dist/menu-builder.js +0 -1
- package/dist/menu-builder.js.map +1 -1
- package/dist/public/css/react.css +1 -1
- package/dist/public/js/react/react.js +51 -59
- package/dist/server.d.ts +16 -85
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +38 -409
- package/dist/server.js.map +1 -1
- package/dist/sprint-data.d.ts +1 -1
- package/dist/sprint-data.d.ts.map +1 -1
- package/dist/sprint-data.js +2 -2
- package/dist/sprint-data.js.map +1 -1
- package/dist/websocket.d.ts +2 -0
- package/dist/websocket.d.ts.map +1 -1
- package/dist/websocket.js +42 -75
- package/dist/websocket.js.map +1 -1
- package/package.json +3 -6
- package/portraits/hogans-heroes/large/burkhalter-35312.png +0 -0
- package/portraits/hogans-heroes/large/carter-34352.png +0 -0
- package/portraits/hogans-heroes/large/hochstetter-45314.png +0 -0
- package/portraits/hogans-heroes/large/hogan-44541.png +0 -0
- package/portraits/hogans-heroes/large/kinch-35241.png +0 -0
- package/portraits/hogans-heroes/large/klink-23434.png +0 -0
- package/portraits/hogans-heroes/large/lebeau-45443.png +0 -0
- package/portraits/hogans-heroes/large/marya-53543.png +0 -0
- package/portraits/hogans-heroes/large/newkirk-54432.png +0 -0
- package/portraits/hogans-heroes/large/schultz-42453.png +0 -0
- package/portraits/hogans-heroes/large/underground-55131.png +0 -0
- package/portraits/hogans-heroes/medium/burkhalter-35312.png +0 -0
- package/portraits/hogans-heroes/medium/carter-34352.png +0 -0
- package/portraits/hogans-heroes/medium/hochstetter-45314.png +0 -0
- package/portraits/hogans-heroes/medium/hogan-44541.png +0 -0
- package/portraits/hogans-heroes/medium/kinch-35241.png +0 -0
- package/portraits/hogans-heroes/medium/klink-23434.png +0 -0
- package/portraits/hogans-heroes/medium/lebeau-45443.png +0 -0
- package/portraits/hogans-heroes/medium/marya-53543.png +0 -0
- package/portraits/hogans-heroes/medium/newkirk-54432.png +0 -0
- package/portraits/hogans-heroes/medium/schultz-42453.png +0 -0
- package/portraits/hogans-heroes/medium/underground-55131.png +0 -0
- package/portraits/monty-python/large/announcer-44441.png +0 -0
- package/portraits/monty-python/large/arguer-35412.png +0 -0
- package/portraits/monty-python/large/bicycle-repair-man-35241.png +0 -0
- package/portraits/monty-python/large/colonel-35423.png +0 -0
- package/portraits/monty-python/large/counsellor-45341.png +0 -0
- package/portraits/monty-python/large/gumbys-23524.png +0 -0
- package/portraits/monty-python/large/nudge-43533.png +0 -0
- package/portraits/monty-python/large/praline-45413.png +0 -0
- package/portraits/monty-python/large/silly-walks-55322.png +0 -0
- package/portraits/monty-python/large/wensleydale-54451.png +0 -0
- package/portraits/monty-python/large/xim-nez-43534.png +0 -0
- package/portraits/monty-python/medium/announcer-44441.png +0 -0
- package/portraits/monty-python/medium/arguer-35412.png +0 -0
- package/portraits/monty-python/medium/bicycle-repair-man-35241.png +0 -0
- package/portraits/monty-python/medium/colonel-35423.png +0 -0
- package/portraits/monty-python/medium/counsellor-45341.png +0 -0
- package/portraits/monty-python/medium/gumbys-23524.png +0 -0
- package/portraits/monty-python/medium/nudge-43533.png +0 -0
- package/portraits/monty-python/medium/praline-45413.png +0 -0
- package/portraits/monty-python/medium/silly-walks-55322.png +0 -0
- package/portraits/monty-python/medium/wensleydale-54451.png +0 -0
- package/portraits/monty-python/medium/xim-nez-43534.png +0 -0
- package/portraits/stephen-king/large/andy-55231.png +0 -0
- package/portraits/stephen-king/large/christine-25112.png +0 -0
- package/portraits/stephen-king/large/danny-53243.png +0 -0
- package/portraits/stephen-king/large/flagg-55311.png +0 -0
- package/portraits/stephen-king/large/gaunt-54421.png +0 -0
- package/portraits/stephen-king/large/jack-44224.png +0 -0
- package/portraits/stephen-king/large/johnny-44353.png +0 -0
- package/portraits/stephen-king/large/margaret-15415.png +0 -0
- package/portraits/stephen-king/large/paul-45233.png +0 -0
- package/portraits/stephen-king/large/pennywise-54411.png +0 -0
- package/portraits/stephen-king/large/roland-35121.png +0 -0
- package/portraits/stephen-king/medium/andy-55231.png +0 -0
- package/portraits/stephen-king/medium/christine-25112.png +0 -0
- package/portraits/stephen-king/medium/danny-53243.png +0 -0
- package/portraits/stephen-king/medium/flagg-55311.png +0 -0
- package/portraits/stephen-king/medium/gaunt-54421.png +0 -0
- package/portraits/stephen-king/medium/jack-44224.png +0 -0
- package/portraits/stephen-king/medium/johnny-44353.png +0 -0
- package/portraits/stephen-king/medium/margaret-15415.png +0 -0
- package/portraits/stephen-king/medium/paul-45233.png +0 -0
- package/portraits/stephen-king/medium/pennywise-54411.png +0 -0
- package/portraits/stephen-king/medium/roland-35121.png +0 -0
- package/src/public/App.tsx +21 -5
- package/src/public/components/BikeRackIndex.tsx +0 -1
- package/src/public/components/BikeRackWorkspace.tsx +86 -11
- package/src/public/components/DockviewWorkspace.tsx +19 -8
- package/src/public/components/StandalonePanel.tsx +1 -3
- package/src/public/components/panel-registry.ts +3 -1
- package/src/public/components/panels/AuditLogPanel.tsx +28 -4
- package/src/public/components/panels/GitPanel.tsx +1 -20
- package/src/public/components/panels/SettingsPanel.tsx +0 -1
- package/src/public/components/panels/SprintPanel.tsx +32 -1
- package/src/public/components/panels/index.ts +0 -2
- package/src/public/hooks/useFocusPanel.ts +137 -0
- package/src/public/hooks/useLayoutPersistence.ts +8 -5
- package/src/public/styles/dockview-theme.css +1 -84
- package/src/public/styles/tailwind.css +27 -32
- package/src/public/utils/slash-commands.ts +122 -98
- package/dist/hooks/cyclist-pretooluse-hook.d.ts +0 -60
- package/dist/hooks/cyclist-pretooluse-hook.d.ts.map +0 -1
- package/dist/hooks/cyclist-pretooluse-hook.js +0 -57
- package/dist/hooks/cyclist-pretooluse-hook.js.map +0 -1
- package/dist/hooks/pretooluse-hook.d.ts +0 -89
- package/dist/hooks/pretooluse-hook.d.ts.map +0 -1
- package/dist/hooks/pretooluse-hook.js +0 -235
- package/dist/hooks/pretooluse-hook.js.map +0 -1
- package/dist/notification-sound.d.ts +0 -59
- package/dist/notification-sound.d.ts.map +0 -1
- package/dist/notification-sound.js +0 -219
- package/dist/notification-sound.js.map +0 -1
- package/dist/plugin-loader.test.d.ts +0 -17
- package/dist/plugin-loader.test.d.ts.map +0 -1
- package/dist/plugin-loader.test.js +0 -407
- package/dist/plugin-loader.test.js.map +0 -1
- package/portraits/star-trek-tng/large/beverly-44352.png +0 -0
- package/portraits/star-trek-tng/large/data-55241.png +0 -0
- package/portraits/star-trek-tng/large/deanna-43353.png +0 -0
- package/portraits/star-trek-tng/large/geordi-54342.png +0 -0
- package/portraits/star-trek-tng/large/jean-luc-45342.png +0 -0
- package/portraits/star-trek-tng/large/kathryn-45332.png +0 -0
- package/portraits/star-trek-tng/large/miles-35342.png +0 -0
- package/portraits/star-trek-tng/large/q-53521.png +0 -0
- package/portraits/star-trek-tng/large/spock-45231.png +0 -0
- package/portraits/star-trek-tng/large/troi-44352.png +0 -0
- package/portraits/star-trek-tng/medium/beverly-44352.png +0 -0
- package/portraits/star-trek-tng/medium/data-55241.png +0 -0
- package/portraits/star-trek-tng/medium/deanna-43353.png +0 -0
- package/portraits/star-trek-tng/medium/geordi-54342.png +0 -0
- package/portraits/star-trek-tng/medium/jean-luc-45342.png +0 -0
- package/portraits/star-trek-tng/medium/kathryn-45332.png +0 -0
- package/portraits/star-trek-tng/medium/miles-35342.png +0 -0
- package/portraits/star-trek-tng/medium/q-53521.png +0 -0
- package/portraits/star-trek-tng/medium/spock-45231.png +0 -0
- package/portraits/star-trek-tng/medium/troi-44352.png +0 -0
- package/src/public/components/panels/TTYPanel.tsx +0 -299
- package/src/public/types/electron.d.ts +0 -18
package/dist/api/file-browser.js
CHANGED
|
@@ -1,115 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* REST endpoints for file browser functionality in web mode.
|
|
5
|
-
* Mirrors the IPC handlers from main.ts for browser compatibility.
|
|
6
|
-
*/
|
|
7
|
-
import { Router } from 'express';
|
|
8
|
-
import { spawn } from 'child_process';
|
|
9
|
-
import { existsSync } from 'fs';
|
|
10
|
-
import { resolve, isAbsolute } from 'path';
|
|
11
|
-
import { listDirectory, readFile } from '../file-browser.js';
|
|
12
|
-
export function createFileBrowserRouter(getProjectDir) {
|
|
13
|
-
const router = Router();
|
|
14
|
-
// List directory contents
|
|
15
|
-
router.get('/', (req, res) => {
|
|
16
|
-
try {
|
|
17
|
-
const projectDir = getProjectDir();
|
|
18
|
-
const requestedPath = req.query.path || '';
|
|
19
|
-
const listing = listDirectory(requestedPath, projectDir);
|
|
20
|
-
res.json(listing);
|
|
21
|
-
}
|
|
22
|
-
catch (err) {
|
|
23
|
-
console.error('[FileBrowser API] Error listing directory:', err);
|
|
24
|
-
res.status(400).json({
|
|
25
|
-
error: err instanceof Error ? err.message : 'Failed to list directory'
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
// Open/read a file
|
|
30
|
-
router.post('/open', (req, res) => {
|
|
31
|
-
try {
|
|
32
|
-
const projectDir = getProjectDir();
|
|
33
|
-
const { path: filePath } = req.body;
|
|
34
|
-
if (!filePath) {
|
|
35
|
-
return res.status(400).json({ error: 'Missing path parameter' });
|
|
36
|
-
}
|
|
37
|
-
const content = readFile(filePath, projectDir);
|
|
38
|
-
res.json({ path: filePath, content });
|
|
39
|
-
}
|
|
40
|
-
catch (err) {
|
|
41
|
-
console.error('[FileBrowser API] Error reading file:', err);
|
|
42
|
-
res.status(400).json({
|
|
43
|
-
error: err instanceof Error ? err.message : 'Failed to read file'
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
// Open file in GUI editor
|
|
48
|
-
// Story MSSCI-12467: DIFFS panel file opener
|
|
49
|
-
// Preference: Windsurf → VS Code → Notepad (ignores $EDITOR which may be terminal-based)
|
|
50
|
-
router.post('/edit', async (req, res) => {
|
|
51
|
-
try {
|
|
52
|
-
const projectDir = getProjectDir();
|
|
53
|
-
const { path: filePath, lineNumber } = req.body;
|
|
54
|
-
if (!filePath) {
|
|
55
|
-
return res.status(400).json({ success: false, error: 'Missing path parameter' });
|
|
56
|
-
}
|
|
57
|
-
// Resolve path (absolute or relative to project)
|
|
58
|
-
const absolutePath = isAbsolute(filePath) ? filePath : resolve(projectDir, filePath);
|
|
59
|
-
// Verify file exists
|
|
60
|
-
if (!existsSync(absolutePath)) {
|
|
61
|
-
return res.status(404).json({ success: false, error: 'File not found' });
|
|
62
|
-
}
|
|
63
|
-
// GUI editor preference order (ignores $EDITOR which may be vim/nano)
|
|
64
|
-
const editorCandidates = ['windsurf', 'code', 'notepad'];
|
|
65
|
-
// Find first available editor
|
|
66
|
-
let editor = null;
|
|
67
|
-
for (const candidate of editorCandidates) {
|
|
68
|
-
try {
|
|
69
|
-
const { execSync } = await import('child_process');
|
|
70
|
-
// Check if command exists (works on macOS/Linux with 'which', Windows with 'where')
|
|
71
|
-
const whichCmd = process.platform === 'win32' ? 'where' : 'which';
|
|
72
|
-
execSync(`${whichCmd} ${candidate}`, { stdio: 'ignore' });
|
|
73
|
-
editor = candidate;
|
|
74
|
-
break;
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
// Command not found, try next
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (!editor) {
|
|
81
|
-
return res.status(500).json({
|
|
82
|
-
success: false,
|
|
83
|
-
error: 'No GUI editor found. Install Windsurf, VS Code, or Notepad.'
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
// Build command arguments (all these editors use similar syntax)
|
|
87
|
-
let args;
|
|
88
|
-
if (editor === 'windsurf' || editor === 'code') {
|
|
89
|
-
// Windsurf / VS Code: --goto file:line
|
|
90
|
-
args = lineNumber ? ['--goto', `${absolutePath}:${lineNumber}`] : [absolutePath];
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
// Notepad: just the file path
|
|
94
|
-
args = [absolutePath];
|
|
95
|
-
}
|
|
96
|
-
console.log(`[FileBrowser API] Opening in editor: ${editor} ${args.join(' ')}`);
|
|
97
|
-
// Spawn editor detached so it doesn't block the server
|
|
98
|
-
const child = spawn(editor, args, {
|
|
99
|
-
detached: true,
|
|
100
|
-
stdio: 'ignore',
|
|
101
|
-
});
|
|
102
|
-
child.unref();
|
|
103
|
-
res.json({ success: true, editor, path: absolutePath });
|
|
104
|
-
}
|
|
105
|
-
catch (err) {
|
|
106
|
-
console.error('[FileBrowser API] Error opening editor:', err);
|
|
107
|
-
res.status(500).json({
|
|
108
|
-
success: false,
|
|
109
|
-
error: err instanceof Error ? err.message : 'Failed to open editor'
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
return router;
|
|
114
|
-
}
|
|
1
|
+
// Re-export from @pennyfarthing/core (Story 98-17)
|
|
2
|
+
export * from '@pennyfarthing/core/dist/server/api/file-browser.js';
|
|
115
3
|
//# sourceMappingURL=file-browser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-browser.js","sourceRoot":"","sources":["../../src/api/file-browser.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"file-browser.js","sourceRoot":"","sources":["../../src/api/file-browser.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,cAAc,qDAAqD,CAAC"}
|
package/dist/api/git.d.ts
CHANGED
|
@@ -1,47 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export interface DirtyFile {
|
|
3
|
-
status: string;
|
|
4
|
-
path: string;
|
|
5
|
-
}
|
|
6
|
-
export interface GitInfo {
|
|
7
|
-
branch: string;
|
|
8
|
-
clean: boolean;
|
|
9
|
-
ahead: number | null;
|
|
10
|
-
behind: number | null;
|
|
11
|
-
dirtyFiles: DirtyFile[];
|
|
12
|
-
/** Commits that origin/develop has that local branch doesn't (needs pull/rebase) */
|
|
13
|
-
developBehind: number | null;
|
|
14
|
-
}
|
|
15
|
-
export interface RepoGitInfo extends GitInfo {
|
|
16
|
-
name: string;
|
|
17
|
-
path: string;
|
|
18
|
-
}
|
|
19
|
-
interface RepoConfig {
|
|
20
|
-
name: string;
|
|
21
|
-
path: string;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Get repos from repos.yaml
|
|
25
|
-
* Checks project root first, then .claude/project/ fallback.
|
|
26
|
-
* Returns array of repo configs, falls back to single repo (current dir) if none configured.
|
|
27
|
-
*/
|
|
28
|
-
export declare function getReposFromConfig(projectDir: string): RepoConfig[];
|
|
29
|
-
/**
|
|
30
|
-
* Get git status for all configured repos (sync - blocks event loop, use getAllReposGitInfoAsync when possible)
|
|
31
|
-
*/
|
|
32
|
-
export declare function getAllReposGitInfo(projectDir: string): RepoGitInfo[];
|
|
33
|
-
/**
|
|
34
|
-
* Get git status for all configured repos (async - does not block event loop)
|
|
35
|
-
*/
|
|
36
|
-
export declare function getAllReposGitInfoAsync(projectDir: string): Promise<RepoGitInfo[]>;
|
|
37
|
-
export declare function getGitInfo(projectDir: string): GitInfo | null;
|
|
38
|
-
/**
|
|
39
|
-
* Get git status for project (async - does not block event loop)
|
|
40
|
-
* This should be preferred over getGitInfo for WebSocket broadcasts and polling
|
|
41
|
-
* Uses a per-repo mutex to prevent git lock conflicts from concurrent operations
|
|
42
|
-
*/
|
|
43
|
-
export declare function getGitInfoAsync(projectDir: string): Promise<GitInfo | null>;
|
|
44
|
-
export declare function setForceRefreshCallback(callback: (projectDir: string) => Promise<void>): void;
|
|
45
|
-
export declare function createGitRouter(getProjectDir: () => string): Router;
|
|
46
|
-
export {};
|
|
1
|
+
export * from '@pennyfarthing/core/dist/server/api/git.js';
|
|
47
2
|
//# sourceMappingURL=git.d.ts.map
|
package/dist/api/git.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/api/git.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/api/git.ts"],"names":[],"mappings":"AACA,cAAc,4CAA4C,CAAC"}
|
package/dist/api/git.js
CHANGED
|
@@ -1,355 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { promisify } from 'util';
|
|
4
|
-
import { existsSync, readFileSync } from 'fs';
|
|
5
|
-
import { join } from 'path';
|
|
6
|
-
import { parse as parseYaml } from 'yaml';
|
|
7
|
-
import { detectPennyfarthingProject } from '../pennyfarthing.js';
|
|
8
|
-
const execAsync = promisify(exec);
|
|
9
|
-
/**
|
|
10
|
-
* Per-repo mutex to prevent concurrent git operations that cause lock conflicts
|
|
11
|
-
* Maps repo path to a promise that resolves when the current operation completes
|
|
12
|
-
*/
|
|
13
|
-
const repoLocks = new Map();
|
|
14
|
-
/**
|
|
15
|
-
* Acquire a lock for a repo, ensuring only one git operation runs at a time
|
|
16
|
-
* Returns a release function to call when done
|
|
17
|
-
*/
|
|
18
|
-
async function acquireRepoLock(repoPath) {
|
|
19
|
-
// Wait for any existing operation to complete
|
|
20
|
-
const existingLock = repoLocks.get(repoPath);
|
|
21
|
-
if (existingLock) {
|
|
22
|
-
await existingLock;
|
|
23
|
-
}
|
|
24
|
-
// Create a new lock
|
|
25
|
-
let releaseLock;
|
|
26
|
-
const lockPromise = new Promise(resolve => {
|
|
27
|
-
releaseLock = resolve;
|
|
28
|
-
});
|
|
29
|
-
repoLocks.set(repoPath, lockPromise);
|
|
30
|
-
return () => {
|
|
31
|
-
releaseLock();
|
|
32
|
-
// Clean up the lock after a short delay to allow batched requests
|
|
33
|
-
setTimeout(() => {
|
|
34
|
-
if (repoLocks.get(repoPath) === lockPromise) {
|
|
35
|
-
repoLocks.delete(repoPath);
|
|
36
|
-
}
|
|
37
|
-
}, 100);
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Get repos from repos.yaml
|
|
42
|
-
* Checks project root first, then .claude/project/ fallback.
|
|
43
|
-
* Returns array of repo configs, falls back to single repo (current dir) if none configured.
|
|
44
|
-
*/
|
|
45
|
-
export function getReposFromConfig(projectDir) {
|
|
46
|
-
// Check .pennyfarthing/ first (canonical runtime location), then project root fallback
|
|
47
|
-
const candidates = [
|
|
48
|
-
join(projectDir, '.pennyfarthing', 'repos.yaml'),
|
|
49
|
-
join(projectDir, 'repos.yaml'),
|
|
50
|
-
];
|
|
51
|
-
const configPath = candidates.find(p => existsSync(p));
|
|
52
|
-
if (!configPath) {
|
|
53
|
-
const dirName = projectDir.split('/').pop() || 'project';
|
|
54
|
-
return [{ name: dirName, path: '.' }];
|
|
55
|
-
}
|
|
56
|
-
try {
|
|
57
|
-
const configContent = readFileSync(configPath, 'utf-8');
|
|
58
|
-
const config = parseYaml(configContent);
|
|
59
|
-
if (!config?.repos || typeof config.repos !== 'object') {
|
|
60
|
-
const dirName = projectDir.split('/').pop() || 'project';
|
|
61
|
-
return [{ name: dirName, path: '.' }];
|
|
62
|
-
}
|
|
63
|
-
const repos = [];
|
|
64
|
-
for (const [name, repoConfig] of Object.entries(config.repos)) {
|
|
65
|
-
const rc = repoConfig;
|
|
66
|
-
repos.push({
|
|
67
|
-
name,
|
|
68
|
-
path: rc?.path || name,
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
return repos.length > 0 ? repos : [{ name: projectDir.split('/').pop() || 'project', path: '.' }];
|
|
72
|
-
}
|
|
73
|
-
catch (err) {
|
|
74
|
-
console.warn('[Git API] Failed to parse repos.yaml:', err);
|
|
75
|
-
const dirName = projectDir.split('/').pop() || 'project';
|
|
76
|
-
return [{ name: dirName, path: '.' }];
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Get git status for all configured repos (sync - blocks event loop, use getAllReposGitInfoAsync when possible)
|
|
81
|
-
*/
|
|
82
|
-
export function getAllReposGitInfo(projectDir) {
|
|
83
|
-
const repos = getReposFromConfig(projectDir);
|
|
84
|
-
return repos.map(repo => {
|
|
85
|
-
const repoPath = join(projectDir, repo.path);
|
|
86
|
-
const gitInfo = getGitInfo(repoPath);
|
|
87
|
-
return {
|
|
88
|
-
name: repo.name,
|
|
89
|
-
path: repo.path,
|
|
90
|
-
branch: gitInfo?.branch || 'unknown',
|
|
91
|
-
clean: gitInfo?.clean ?? true,
|
|
92
|
-
ahead: gitInfo?.ahead ?? null,
|
|
93
|
-
behind: gitInfo?.behind ?? null,
|
|
94
|
-
developBehind: gitInfo?.developBehind ?? null,
|
|
95
|
-
dirtyFiles: gitInfo?.dirtyFiles ?? [],
|
|
96
|
-
};
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Get git status for all configured repos (async - does not block event loop)
|
|
101
|
-
*/
|
|
102
|
-
export async function getAllReposGitInfoAsync(projectDir) {
|
|
103
|
-
const repos = getReposFromConfig(projectDir);
|
|
104
|
-
const results = await Promise.all(repos.map(async (repo) => {
|
|
105
|
-
const repoPath = join(projectDir, repo.path);
|
|
106
|
-
const gitInfo = await getGitInfoAsync(repoPath);
|
|
107
|
-
return {
|
|
108
|
-
name: repo.name,
|
|
109
|
-
path: repo.path,
|
|
110
|
-
branch: gitInfo?.branch || 'unknown',
|
|
111
|
-
clean: gitInfo?.clean ?? true,
|
|
112
|
-
ahead: gitInfo?.ahead ?? null,
|
|
113
|
-
behind: gitInfo?.behind ?? null,
|
|
114
|
-
developBehind: gitInfo?.developBehind ?? null,
|
|
115
|
-
dirtyFiles: gitInfo?.dirtyFiles ?? [],
|
|
116
|
-
};
|
|
117
|
-
}));
|
|
118
|
-
return results;
|
|
119
|
-
}
|
|
120
|
-
// Get git status for project (sync - blocks event loop)
|
|
121
|
-
export function getGitInfo(projectDir) {
|
|
122
|
-
try {
|
|
123
|
-
// Get current branch
|
|
124
|
-
const branch = execSync('git rev-parse --abbrev-ref HEAD', {
|
|
125
|
-
cwd: projectDir,
|
|
126
|
-
encoding: 'utf-8',
|
|
127
|
-
}).trim();
|
|
128
|
-
// Get dirty files using --porcelain for parseable output
|
|
129
|
-
let dirtyFiles = [];
|
|
130
|
-
let clean = true;
|
|
131
|
-
try {
|
|
132
|
-
const statusOutput = execSync('git status --porcelain', {
|
|
133
|
-
cwd: projectDir,
|
|
134
|
-
encoding: 'utf-8',
|
|
135
|
-
}).trim();
|
|
136
|
-
if (statusOutput) {
|
|
137
|
-
clean = false;
|
|
138
|
-
dirtyFiles = statusOutput.split('\n').map(line => {
|
|
139
|
-
const status = line.substring(0, 2).trim() || '?';
|
|
140
|
-
const path = line.substring(3);
|
|
141
|
-
return { status, path };
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
catch {
|
|
146
|
-
// Fall back to diff-index check if porcelain fails
|
|
147
|
-
try {
|
|
148
|
-
execSync('git diff-index --quiet HEAD --', {
|
|
149
|
-
cwd: projectDir,
|
|
150
|
-
encoding: 'utf-8',
|
|
151
|
-
});
|
|
152
|
-
clean = true;
|
|
153
|
-
}
|
|
154
|
-
catch {
|
|
155
|
-
clean = false;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
// Get ahead/behind counts (suppress stderr for branches without upstream)
|
|
159
|
-
let ahead = null;
|
|
160
|
-
let behind = null;
|
|
161
|
-
try {
|
|
162
|
-
const aheadOutput = execSync('git rev-list --count @{u}..HEAD', {
|
|
163
|
-
cwd: projectDir,
|
|
164
|
-
encoding: 'utf-8',
|
|
165
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
166
|
-
});
|
|
167
|
-
ahead = parseInt(aheadOutput.trim(), 10);
|
|
168
|
-
const behindOutput = execSync('git rev-list --count HEAD..@{u}', {
|
|
169
|
-
cwd: projectDir,
|
|
170
|
-
encoding: 'utf-8',
|
|
171
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
172
|
-
});
|
|
173
|
-
behind = parseInt(behindOutput.trim(), 10);
|
|
174
|
-
}
|
|
175
|
-
catch {
|
|
176
|
-
// No upstream configured - leave as null
|
|
177
|
-
}
|
|
178
|
-
// Get commits that origin/develop has that current branch doesn't
|
|
179
|
-
let developBehind = null;
|
|
180
|
-
try {
|
|
181
|
-
const developBehindOutput = execSync('git rev-list --count HEAD..origin/develop', {
|
|
182
|
-
cwd: projectDir,
|
|
183
|
-
encoding: 'utf-8',
|
|
184
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
185
|
-
});
|
|
186
|
-
developBehind = parseInt(developBehindOutput.trim(), 10);
|
|
187
|
-
}
|
|
188
|
-
catch {
|
|
189
|
-
// origin/develop doesn't exist - leave as null
|
|
190
|
-
}
|
|
191
|
-
return { branch, clean, ahead, behind, dirtyFiles, developBehind };
|
|
192
|
-
}
|
|
193
|
-
catch (error) {
|
|
194
|
-
// Not a git repo or git command failed - return null gracefully
|
|
195
|
-
// Handles: not a git repository, EPIPE, ENOENT, etc.
|
|
196
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
197
|
-
const errorCode = error?.code;
|
|
198
|
-
// Log non-trivial errors for debugging but don't crash
|
|
199
|
-
if (!errorMessage.includes('not a git repository')) {
|
|
200
|
-
console.warn(`getGitInfo failed (${errorCode || 'unknown'}): ${errorMessage}`);
|
|
201
|
-
}
|
|
202
|
-
return null;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Get git status for project (async - does not block event loop)
|
|
207
|
-
* This should be preferred over getGitInfo for WebSocket broadcasts and polling
|
|
208
|
-
* Uses a per-repo mutex to prevent git lock conflicts from concurrent operations
|
|
209
|
-
*/
|
|
210
|
-
export async function getGitInfoAsync(projectDir) {
|
|
211
|
-
// Acquire lock to prevent concurrent git operations on the same repo
|
|
212
|
-
const releaseLock = await acquireRepoLock(projectDir);
|
|
213
|
-
try {
|
|
214
|
-
// Fetch latest refs from remote (quiet, no output)
|
|
215
|
-
// This ensures ahead/behind counts are accurate against remote state
|
|
216
|
-
try {
|
|
217
|
-
await execAsync('git fetch --quiet', {
|
|
218
|
-
cwd: projectDir,
|
|
219
|
-
encoding: 'utf-8',
|
|
220
|
-
timeout: 10000, // 10s timeout for network operation
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
catch {
|
|
224
|
-
// Fetch failed (offline, no remote, etc.) - continue with local refs
|
|
225
|
-
}
|
|
226
|
-
// Get current branch
|
|
227
|
-
const { stdout: branchOutput } = await execAsync('git rev-parse --abbrev-ref HEAD', {
|
|
228
|
-
cwd: projectDir,
|
|
229
|
-
encoding: 'utf-8',
|
|
230
|
-
});
|
|
231
|
-
const branch = branchOutput.trim();
|
|
232
|
-
// Get dirty files using --porcelain for parseable output
|
|
233
|
-
let dirtyFiles = [];
|
|
234
|
-
let clean = true;
|
|
235
|
-
try {
|
|
236
|
-
const { stdout: statusOutput } = await execAsync('git status --porcelain', {
|
|
237
|
-
cwd: projectDir,
|
|
238
|
-
encoding: 'utf-8',
|
|
239
|
-
});
|
|
240
|
-
if (statusOutput.trim()) {
|
|
241
|
-
clean = false;
|
|
242
|
-
dirtyFiles = statusOutput.trim().split('\n').map(line => {
|
|
243
|
-
const status = line.substring(0, 2).trim() || '?';
|
|
244
|
-
const path = line.substring(3);
|
|
245
|
-
return { status, path };
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
catch {
|
|
250
|
-
// Fall back to diff-index check if porcelain fails
|
|
251
|
-
try {
|
|
252
|
-
await execAsync('git diff-index --quiet HEAD --', {
|
|
253
|
-
cwd: projectDir,
|
|
254
|
-
encoding: 'utf-8',
|
|
255
|
-
});
|
|
256
|
-
clean = true;
|
|
257
|
-
}
|
|
258
|
-
catch {
|
|
259
|
-
clean = false;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
// Get ahead/behind counts vs tracking branch
|
|
263
|
-
let ahead = null;
|
|
264
|
-
let behind = null;
|
|
265
|
-
try {
|
|
266
|
-
const { stdout: aheadOutput } = await execAsync('git rev-list --count @{u}..HEAD', {
|
|
267
|
-
cwd: projectDir,
|
|
268
|
-
encoding: 'utf-8',
|
|
269
|
-
});
|
|
270
|
-
ahead = parseInt(aheadOutput.trim(), 10);
|
|
271
|
-
const { stdout: behindOutput } = await execAsync('git rev-list --count HEAD..@{u}', {
|
|
272
|
-
cwd: projectDir,
|
|
273
|
-
encoding: 'utf-8',
|
|
274
|
-
});
|
|
275
|
-
behind = parseInt(behindOutput.trim(), 10);
|
|
276
|
-
}
|
|
277
|
-
catch {
|
|
278
|
-
// No upstream configured - leave as null
|
|
279
|
-
}
|
|
280
|
-
// Get commits that origin/develop has that current branch doesn't
|
|
281
|
-
// This alerts when develop has moved ahead (work done in another clone)
|
|
282
|
-
let developBehind = null;
|
|
283
|
-
try {
|
|
284
|
-
const { stdout: developBehindOutput } = await execAsync('git rev-list --count HEAD..origin/develop', { cwd: projectDir, encoding: 'utf-8' });
|
|
285
|
-
developBehind = parseInt(developBehindOutput.trim(), 10);
|
|
286
|
-
}
|
|
287
|
-
catch {
|
|
288
|
-
// origin/develop doesn't exist or other error - leave as null
|
|
289
|
-
}
|
|
290
|
-
releaseLock();
|
|
291
|
-
return { branch, clean, ahead, behind, dirtyFiles, developBehind };
|
|
292
|
-
}
|
|
293
|
-
catch (error) {
|
|
294
|
-
releaseLock();
|
|
295
|
-
// Not a git repo or git command failed - return null gracefully
|
|
296
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
297
|
-
const errorCode = error?.code;
|
|
298
|
-
// Log non-trivial errors for debugging but don't crash
|
|
299
|
-
if (!errorMessage.includes('not a git repository')) {
|
|
300
|
-
console.warn(`getGitInfoAsync failed (${errorCode || 'unknown'}): ${errorMessage}`);
|
|
301
|
-
}
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
// Callback for forcing git refresh (set by websocket.ts)
|
|
306
|
-
let forceRefreshCallback = null;
|
|
307
|
-
export function setForceRefreshCallback(callback) {
|
|
308
|
-
forceRefreshCallback = callback;
|
|
309
|
-
}
|
|
310
|
-
// Create git API router
|
|
311
|
-
export function createGitRouter(getProjectDir) {
|
|
312
|
-
const router = Router();
|
|
313
|
-
// Git API - POST to force refresh (debugging/manual trigger)
|
|
314
|
-
router.post('/refresh', async (_req, res) => {
|
|
315
|
-
const projectDir = getProjectDir();
|
|
316
|
-
console.log('[Git API] POST /refresh called, projectDir:', projectDir);
|
|
317
|
-
if (!detectPennyfarthingProject(projectDir)) {
|
|
318
|
-
console.log('[Git API] Not a Pennyfarthing project');
|
|
319
|
-
return res.status(404).json({ error: 'Not a Pennyfarthing project' });
|
|
320
|
-
}
|
|
321
|
-
if (forceRefreshCallback) {
|
|
322
|
-
console.log('[Git API] Calling forceRefreshCallback...');
|
|
323
|
-
await forceRefreshCallback(projectDir);
|
|
324
|
-
console.log('[Git API] forceRefreshCallback complete');
|
|
325
|
-
res.json({ success: true, message: 'Git cache refreshed and broadcast sent' });
|
|
326
|
-
}
|
|
327
|
-
else {
|
|
328
|
-
console.log('[Git API] No forceRefreshCallback registered!');
|
|
329
|
-
res.status(500).json({ error: 'Refresh callback not registered' });
|
|
330
|
-
}
|
|
331
|
-
});
|
|
332
|
-
// Git API - GET current git status (async to avoid blocking event loop)
|
|
333
|
-
router.get('/', async (_req, res) => {
|
|
334
|
-
const projectDir = getProjectDir();
|
|
335
|
-
if (!detectPennyfarthingProject(projectDir)) {
|
|
336
|
-
return res.status(404).json({ error: 'Not a Pennyfarthing project' });
|
|
337
|
-
}
|
|
338
|
-
const gitInfo = await getGitInfoAsync(projectDir);
|
|
339
|
-
if (!gitInfo) {
|
|
340
|
-
return res.status(404).json({ error: 'Not a git repository' });
|
|
341
|
-
}
|
|
342
|
-
res.json(gitInfo);
|
|
343
|
-
});
|
|
344
|
-
// Git API - GET status for all configured repos (async to avoid blocking event loop)
|
|
345
|
-
router.get('/all', async (_req, res) => {
|
|
346
|
-
const projectDir = getProjectDir();
|
|
347
|
-
if (!detectPennyfarthingProject(projectDir)) {
|
|
348
|
-
return res.status(404).json({ error: 'Not a Pennyfarthing project' });
|
|
349
|
-
}
|
|
350
|
-
const allReposInfo = await getAllReposGitInfoAsync(projectDir);
|
|
351
|
-
res.json(allReposInfo);
|
|
352
|
-
});
|
|
353
|
-
return router;
|
|
354
|
-
}
|
|
1
|
+
// Re-export from @pennyfarthing/core (Story 98-17)
|
|
2
|
+
export * from '@pennyfarthing/core/dist/server/api/git.js';
|
|
355
3
|
//# sourceMappingURL=git.js.map
|
package/dist/api/git.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/api/git.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/api/git.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,cAAc,4CAA4C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health-score.d.ts","sourceRoot":"","sources":["../../src/api/health-score.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"health-score.d.ts","sourceRoot":"","sources":["../../src/api/health-score.ts"],"names":[],"mappings":"AACA,cAAc,qDAAqD,CAAC"}
|
package/dist/api/health-score.js
CHANGED
|
@@ -1,47 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { join } from 'path';
|
|
4
|
-
export function createHealthScoreRouter(getProjectDir) {
|
|
5
|
-
const router = Router();
|
|
6
|
-
router.get('/', (req, res) => {
|
|
7
|
-
const projectDir = getProjectDir();
|
|
8
|
-
const args = ['-m', 'pennyfarthing_scripts.healthscore', 'analyze', '--format', 'json', '--no-cache'];
|
|
9
|
-
const pythonPath = join(projectDir, 'pennyfarthing');
|
|
10
|
-
console.log('[HealthScore] Starting analysis, cwd=%s, PYTHONPATH=%s', pythonPath, pythonPath);
|
|
11
|
-
execFile('python3', args, {
|
|
12
|
-
cwd: pythonPath,
|
|
13
|
-
env: { ...process.env, PYTHONPATH: pythonPath },
|
|
14
|
-
timeout: 60000,
|
|
15
|
-
}, (err, stdout, stderr) => {
|
|
16
|
-
// Always log stderr — it contains per-dimension probe logs
|
|
17
|
-
if (stderr) {
|
|
18
|
-
console.log('[HealthScore] Python stderr:\n%s', stderr);
|
|
19
|
-
}
|
|
20
|
-
if (err) {
|
|
21
|
-
console.error('[HealthScore] Analysis failed:', err.message);
|
|
22
|
-
res.status(500).json({
|
|
23
|
-
success: false,
|
|
24
|
-
error: stderr || err.message,
|
|
25
|
-
});
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
try {
|
|
29
|
-
const data = JSON.parse(stdout);
|
|
30
|
-
const dims = data.dimensions || [];
|
|
31
|
-
const scored = dims.filter((d) => d.score !== null).length;
|
|
32
|
-
console.log('[HealthScore] Success: composite=%.1f, %d/%d dimensions scored', data.composite_score, scored, dims.length);
|
|
33
|
-
res.json(data);
|
|
34
|
-
}
|
|
35
|
-
catch (parseErr) {
|
|
36
|
-
console.error('[HealthScore] JSON parse failed:', parseErr);
|
|
37
|
-
console.error('[HealthScore] Raw stdout: %s', stdout.slice(0, 500));
|
|
38
|
-
res.status(500).json({
|
|
39
|
-
success: false,
|
|
40
|
-
error: 'Failed to parse health score output',
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
return router;
|
|
46
|
-
}
|
|
1
|
+
// Re-export from @pennyfarthing/core (Story 98-17)
|
|
2
|
+
export * from '@pennyfarthing/core/dist/server/api/health-score.js';
|
|
47
3
|
//# sourceMappingURL=health-score.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health-score.js","sourceRoot":"","sources":["../../src/api/health-score.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"health-score.js","sourceRoot":"","sources":["../../src/api/health-score.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,cAAc,qDAAqD,CAAC"}
|