@friggframework/devtools 2.0.0--canary.517.35ee143.0 → 2.0.0--canary.524.06156322a.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 (147) hide show
  1. package/infrastructure/domains/shared/types/app-definition.js +0 -21
  2. package/infrastructure/domains/shared/utilities/base-definition-factory.js +15 -1
  3. package/infrastructure/infrastructure-composer.js +0 -2
  4. package/package.json +15 -7
  5. package/.eslintrc.json +0 -3
  6. package/CHANGELOG.md +0 -132
  7. package/infrastructure/domains/admin-scripts/admin-script-builder.js +0 -200
  8. package/infrastructure/domains/admin-scripts/admin-script-builder.test.js +0 -499
  9. package/infrastructure/domains/admin-scripts/index.js +0 -5
  10. package/layers/prisma/.build-complete +0 -3
  11. package/layers/prisma/nodejs/package.json +0 -8
  12. package/management-ui/.eslintrc.js +0 -22
  13. package/management-ui/components.json +0 -21
  14. package/management-ui/docs/phase2-integration-guide.md +0 -320
  15. package/management-ui/index.html +0 -13
  16. package/management-ui/package.json +0 -76
  17. package/management-ui/packages/devtools/frigg-cli/ui-command/index.js +0 -302
  18. package/management-ui/postcss.config.js +0 -6
  19. package/management-ui/server/api/backend.js +0 -256
  20. package/management-ui/server/api/cli.js +0 -315
  21. package/management-ui/server/api/codegen.js +0 -663
  22. package/management-ui/server/api/connections.js +0 -857
  23. package/management-ui/server/api/discovery.js +0 -185
  24. package/management-ui/server/api/environment/index.js +0 -1
  25. package/management-ui/server/api/environment/router.js +0 -378
  26. package/management-ui/server/api/environment.js +0 -328
  27. package/management-ui/server/api/integrations.js +0 -876
  28. package/management-ui/server/api/logs.js +0 -248
  29. package/management-ui/server/api/monitoring.js +0 -282
  30. package/management-ui/server/api/open-ide.js +0 -31
  31. package/management-ui/server/api/project.js +0 -1029
  32. package/management-ui/server/api/users/sessions.js +0 -371
  33. package/management-ui/server/api/users/simulation.js +0 -254
  34. package/management-ui/server/api/users.js +0 -362
  35. package/management-ui/server/api-contract.md +0 -275
  36. package/management-ui/server/index.js +0 -873
  37. package/management-ui/server/middleware/errorHandler.js +0 -93
  38. package/management-ui/server/middleware/security.js +0 -32
  39. package/management-ui/server/processManager.js +0 -296
  40. package/management-ui/server/server.js +0 -346
  41. package/management-ui/server/services/aws-monitor.js +0 -413
  42. package/management-ui/server/services/npm-registry.js +0 -347
  43. package/management-ui/server/services/template-engine.js +0 -538
  44. package/management-ui/server/utils/cliIntegration.js +0 -220
  45. package/management-ui/server/utils/environment/auditLogger.js +0 -471
  46. package/management-ui/server/utils/environment/awsParameterStore.js +0 -275
  47. package/management-ui/server/utils/environment/encryption.js +0 -278
  48. package/management-ui/server/utils/environment/envFileManager.js +0 -286
  49. package/management-ui/server/utils/import-commonjs.js +0 -28
  50. package/management-ui/server/utils/response.js +0 -83
  51. package/management-ui/server/websocket/handler.js +0 -325
  52. package/management-ui/src/App.jsx +0 -25
  53. package/management-ui/src/assets/FriggLogo.svg +0 -1
  54. package/management-ui/src/components/AppRouter.jsx +0 -65
  55. package/management-ui/src/components/Button.jsx +0 -70
  56. package/management-ui/src/components/Card.jsx +0 -97
  57. package/management-ui/src/components/EnvironmentCompare.jsx +0 -400
  58. package/management-ui/src/components/EnvironmentEditor.jsx +0 -372
  59. package/management-ui/src/components/EnvironmentImportExport.jsx +0 -469
  60. package/management-ui/src/components/EnvironmentSchema.jsx +0 -491
  61. package/management-ui/src/components/EnvironmentSecurity.jsx +0 -463
  62. package/management-ui/src/components/ErrorBoundary.jsx +0 -73
  63. package/management-ui/src/components/IntegrationCard.jsx +0 -481
  64. package/management-ui/src/components/IntegrationCardEnhanced.jsx +0 -770
  65. package/management-ui/src/components/IntegrationExplorer.jsx +0 -379
  66. package/management-ui/src/components/IntegrationStatus.jsx +0 -336
  67. package/management-ui/src/components/Layout.jsx +0 -716
  68. package/management-ui/src/components/LoadingSpinner.jsx +0 -113
  69. package/management-ui/src/components/RepositoryPicker.jsx +0 -248
  70. package/management-ui/src/components/SessionMonitor.jsx +0 -350
  71. package/management-ui/src/components/StatusBadge.jsx +0 -208
  72. package/management-ui/src/components/UserContextSwitcher.jsx +0 -212
  73. package/management-ui/src/components/UserSimulation.jsx +0 -327
  74. package/management-ui/src/components/Welcome.jsx +0 -434
  75. package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +0 -637
  76. package/management-ui/src/components/codegen/APIModuleSelector.jsx +0 -227
  77. package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +0 -247
  78. package/management-ui/src/components/codegen/CodePreviewEditor.jsx +0 -316
  79. package/management-ui/src/components/codegen/DynamicModuleForm.jsx +0 -271
  80. package/management-ui/src/components/codegen/FormBuilder.jsx +0 -737
  81. package/management-ui/src/components/codegen/IntegrationGenerator.jsx +0 -855
  82. package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +0 -797
  83. package/management-ui/src/components/codegen/SchemaBuilder.jsx +0 -303
  84. package/management-ui/src/components/codegen/TemplateSelector.jsx +0 -586
  85. package/management-ui/src/components/codegen/index.js +0 -10
  86. package/management-ui/src/components/connections/ConnectionConfigForm.jsx +0 -362
  87. package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +0 -182
  88. package/management-ui/src/components/connections/ConnectionTester.jsx +0 -200
  89. package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +0 -292
  90. package/management-ui/src/components/connections/OAuthFlow.jsx +0 -204
  91. package/management-ui/src/components/connections/index.js +0 -5
  92. package/management-ui/src/components/index.js +0 -21
  93. package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +0 -222
  94. package/management-ui/src/components/monitoring/LambdaMetrics.jsx +0 -169
  95. package/management-ui/src/components/monitoring/MetricsChart.jsx +0 -197
  96. package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +0 -393
  97. package/management-ui/src/components/monitoring/SQSMetrics.jsx +0 -246
  98. package/management-ui/src/components/monitoring/index.js +0 -6
  99. package/management-ui/src/components/monitoring/monitoring.css +0 -218
  100. package/management-ui/src/components/theme-provider.jsx +0 -52
  101. package/management-ui/src/components/theme-toggle.jsx +0 -39
  102. package/management-ui/src/components/ui/badge.tsx +0 -36
  103. package/management-ui/src/components/ui/button.test.jsx +0 -56
  104. package/management-ui/src/components/ui/button.tsx +0 -57
  105. package/management-ui/src/components/ui/card.tsx +0 -76
  106. package/management-ui/src/components/ui/dropdown-menu.tsx +0 -199
  107. package/management-ui/src/components/ui/select.tsx +0 -157
  108. package/management-ui/src/components/ui/skeleton.jsx +0 -15
  109. package/management-ui/src/hooks/useFrigg.jsx +0 -387
  110. package/management-ui/src/hooks/useSocket.jsx +0 -58
  111. package/management-ui/src/index.css +0 -193
  112. package/management-ui/src/lib/utils.ts +0 -6
  113. package/management-ui/src/main.jsx +0 -10
  114. package/management-ui/src/pages/CodeGeneration.jsx +0 -14
  115. package/management-ui/src/pages/Connections.jsx +0 -252
  116. package/management-ui/src/pages/ConnectionsEnhanced.jsx +0 -633
  117. package/management-ui/src/pages/Dashboard.jsx +0 -311
  118. package/management-ui/src/pages/Environment.jsx +0 -314
  119. package/management-ui/src/pages/IntegrationConfigure.jsx +0 -669
  120. package/management-ui/src/pages/IntegrationDiscovery.jsx +0 -567
  121. package/management-ui/src/pages/IntegrationTest.jsx +0 -742
  122. package/management-ui/src/pages/Integrations.jsx +0 -253
  123. package/management-ui/src/pages/Monitoring.jsx +0 -17
  124. package/management-ui/src/pages/Simulation.jsx +0 -155
  125. package/management-ui/src/pages/Users.jsx +0 -492
  126. package/management-ui/src/services/api.js +0 -41
  127. package/management-ui/src/services/apiModuleService.js +0 -193
  128. package/management-ui/src/services/websocket-handlers.js +0 -120
  129. package/management-ui/src/test/api/project.test.js +0 -273
  130. package/management-ui/src/test/components/Welcome.test.jsx +0 -378
  131. package/management-ui/src/test/mocks/server.js +0 -178
  132. package/management-ui/src/test/setup.js +0 -61
  133. package/management-ui/src/test/utils/test-utils.jsx +0 -134
  134. package/management-ui/src/utils/repository.js +0 -98
  135. package/management-ui/src/utils/repository.test.js +0 -118
  136. package/management-ui/src/workflows/phase2-integration-workflows.js +0 -884
  137. package/management-ui/tailwind.config.js +0 -63
  138. package/management-ui/tsconfig.json +0 -37
  139. package/management-ui/tsconfig.node.json +0 -10
  140. package/management-ui/vite.config.js +0 -26
  141. package/management-ui/vitest.config.js +0 -38
  142. package/test/auther-definition-method-tester.js +0 -45
  143. package/test/index.js +0 -9
  144. package/test/integration-validator.js +0 -2
  145. package/test/mock-api-readme.md +0 -102
  146. package/test/mock-api.js +0 -284
  147. package/test/mock-integration.js +0 -78
@@ -1,302 +0,0 @@
1
- <<<<<<< HEAD
2
- <<<<<<< HEAD
3
- const open = require('open');
4
- const chalk = require('chalk');
5
- const path = require('path');
6
- const ProcessManager = require('../utils/process-manager');
7
- const {
8
- getCurrentRepositoryInfo,
9
- discoverFriggRepositories,
10
- promptRepositorySelection,
11
- formatRepositoryInfo
12
- } = require('../utils/repo-detection');
13
-
14
- async function uiCommand(options) {
15
- const { port = 3001, open: shouldOpen = true, repo: specifiedRepo } = options;
16
-
17
- let targetRepo = null;
18
- let workingDirectory = process.cwd();
19
-
20
- // If a specific repo path is provided, use it
21
- if (specifiedRepo) {
22
- const repoPath = path.resolve(specifiedRepo);
23
- console.log(chalk.blue(`Using specified repository: ${repoPath}`));
24
- workingDirectory = repoPath;
25
- targetRepo = { path: repoPath, name: path.basename(repoPath) };
26
- } else {
27
- // Check if we're already in a Frigg repository
28
- console.log(chalk.blue('Detecting Frigg repository...'));
29
- const currentRepo = await getCurrentRepositoryInfo();
30
-
31
- if (currentRepo) {
32
- console.log(chalk.green(`✓ Found Frigg repository: ${formatRepositoryInfo(currentRepo)}`));
33
- if (currentRepo.currentSubPath) {
34
- console.log(chalk.gray(` Currently in subdirectory: ${currentRepo.currentSubPath}`));
35
- }
36
- targetRepo = currentRepo;
37
- workingDirectory = currentRepo.path;
38
- } else {
39
- // Discover Frigg repositories
40
- console.log(chalk.yellow('Current directory is not a Frigg repository.'));
41
- console.log(chalk.blue('Searching for Frigg repositories...'));
42
-
43
- const discoveredRepos = await discoverFriggRepositories();
44
- targetRepo = await promptRepositorySelection(discoveredRepos);
45
-
46
- if (!targetRepo) {
47
- console.log(chalk.red('No Frigg repository selected. Exiting.'));
48
- process.exit(1);
49
- }
50
-
51
- workingDirectory = targetRepo.path;
52
- }
53
- }
54
-
55
- console.log(chalk.blue('🚀 Starting Frigg Management UI...'));
56
-
57
- const processManager = new ProcessManager();
58
-
59
- try {
60
- const managementUiPath = path.join(__dirname, '../../management-ui');
61
-
62
- // Check if we're in development mode (no dist folder)
63
- const distPath = path.join(managementUiPath, 'dist');
64
- const fs = require('fs');
65
- const isDevelopment = !fs.existsSync(distPath);
66
-
67
- if (isDevelopment) {
68
- const env = {
69
- ...process.env,
70
- VITE_API_URL: `http://localhost:${port}`,
71
- PORT: port,
72
- PROJECT_ROOT: workingDirectory,
73
- REPOSITORY_INFO: JSON.stringify(targetRepo)
74
- };
75
-
76
- // Start backend server
77
- processManager.spawnProcess(
78
- 'backend',
79
- 'npm',
80
- ['run', 'server'],
81
- { cwd: managementUiPath, env }
82
- );
83
-
84
- // Start frontend dev server
85
- processManager.spawnProcess(
86
- 'frontend',
87
- 'npm',
88
- ['run', 'dev'],
89
- { cwd: managementUiPath, env }
90
- );
91
-
92
- // Wait for servers to start
93
- await new Promise(resolve => setTimeout(resolve, 2000));
94
-
95
- // Display clean status
96
- processManager.printStatus(
97
- 'http://localhost:5173',
98
- `http://localhost:${port}`,
99
- targetRepo.name
100
- );
101
-
102
- // Open browser if requested
103
- if (shouldOpen) {
104
- setTimeout(() => {
105
- open('http://localhost:5173');
106
- }, 1000);
107
- }
108
-
109
- } else {
110
- // Production mode - just start the backend server
111
- const { FriggManagementServer } = await import('../../management-ui/server/index.js');
112
-
113
- const server = new FriggManagementServer({
114
- port,
115
- projectRoot: workingDirectory,
116
- repositoryInfo: targetRepo
117
- });
118
- await server.start();
119
-
120
- processManager.printStatus(
121
- `http://localhost:${port}`,
122
- `http://localhost:${port}/api`,
123
- targetRepo.name
124
- );
125
-
126
- if (shouldOpen) {
127
- setTimeout(() => {
128
- open(`http://localhost:${port}`);
129
- }, 1000);
130
- }
131
- }
132
-
133
- // Keep the process running
134
- process.stdin.resume();
135
-
136
- } catch (error) {
137
- console.error(chalk.red('Failed to start Management UI:'), error.message);
138
- if (error.code === 'EADDRINUSE') {
139
- console.log(chalk.yellow(`Port ${port} is already in use. Try using a different port with --port <number>`));
140
- }
141
- =======
142
- const { FriggManagementServer } = require('../../management-ui/server');
143
- =======
144
- >>>>>>> f153939e (refactor: clean up CLI help display and remove unused dependencies)
145
- const open = require('open');
146
- const chalk = require('chalk');
147
- const path = require('path');
148
- const ProcessManager = require('../utils/process-manager');
149
- const {
150
- getCurrentRepositoryInfo,
151
- discoverFriggRepositories,
152
- promptRepositorySelection,
153
- formatRepositoryInfo
154
- } = require('../utils/repo-detection');
155
-
156
- async function uiCommand(options) {
157
- const { port = 3001, open: shouldOpen = true, repo: specifiedRepo, dev = false } = options;
158
-
159
- let targetRepo = null;
160
- let workingDirectory = process.cwd();
161
-
162
- // If a specific repo path is provided, use it
163
- if (specifiedRepo) {
164
- const repoPath = path.resolve(specifiedRepo);
165
- console.log(chalk.blue(`Using specified repository: ${repoPath}`));
166
- workingDirectory = repoPath;
167
- targetRepo = { path: repoPath, name: path.basename(repoPath) };
168
- } else {
169
- // Check if we're already in a Frigg repository
170
- console.log(chalk.blue('Detecting Frigg repository...'));
171
- const currentRepo = await getCurrentRepositoryInfo();
172
-
173
- if (currentRepo) {
174
- console.log(chalk.green(`✓ Found Frigg repository: ${formatRepositoryInfo(currentRepo)}`));
175
- if (currentRepo.currentSubPath) {
176
- console.log(chalk.gray(` Currently in subdirectory: ${currentRepo.currentSubPath}`));
177
- }
178
- targetRepo = currentRepo;
179
- workingDirectory = currentRepo.path;
180
- } else {
181
- // Discover Frigg repositories
182
- console.log(chalk.yellow('Current directory is not a Frigg repository.'));
183
- console.log(chalk.blue('Searching for Frigg repositories...'));
184
-
185
- const discoveredRepos = await discoverFriggRepositories();
186
-
187
- if (discoveredRepos.length === 0) {
188
- console.log(chalk.red('No Frigg repositories found. Please create one first.'));
189
- process.exit(1);
190
- }
191
-
192
- // For UI command, we'll let the UI handle repository selection
193
- // Set a placeholder and pass the discovered repos via environment
194
- targetRepo = {
195
- name: 'Multiple Repositories Available',
196
- path: process.cwd(),
197
- isMultiRepo: true,
198
- availableRepos: discoveredRepos
199
- };
200
- workingDirectory = process.cwd();
201
-
202
- console.log(chalk.blue(`Found ${discoveredRepos.length} Frigg repositories. You'll be able to select one in the UI.`));
203
- }
204
- }
205
-
206
- console.log(chalk.blue('🚀 Starting Frigg Management UI...'));
207
-
208
- const processManager = new ProcessManager();
209
-
210
- try {
211
- const managementUiPath = path.join(__dirname, '../../management-ui');
212
-
213
- // Check if we're in development mode
214
- // For CLI usage, we prefer development mode unless explicitly set to production
215
- const fs = require('fs');
216
- const isDevelopment = dev || process.env.NODE_ENV !== 'production';
217
-
218
- if (isDevelopment) {
219
- const env = {
220
- ...process.env,
221
- VITE_API_URL: `http://localhost:${port}`,
222
- PORT: port,
223
- PROJECT_ROOT: workingDirectory,
224
- REPOSITORY_INFO: JSON.stringify(targetRepo),
225
- AVAILABLE_REPOSITORIES: targetRepo.isMultiRepo ? JSON.stringify(targetRepo.availableRepos) : null
226
- };
227
-
228
- // Start backend server
229
- processManager.spawnProcess(
230
- 'backend',
231
- 'npm',
232
- ['run', 'server'],
233
- { cwd: managementUiPath, env }
234
- );
235
-
236
- // Start frontend dev server
237
- processManager.spawnProcess(
238
- 'frontend',
239
- 'npm',
240
- ['run', 'dev'],
241
- { cwd: managementUiPath, env }
242
- );
243
-
244
- // Wait for servers to start
245
- await new Promise(resolve => setTimeout(resolve, 2000));
246
-
247
- // Display clean status
248
- processManager.printStatus(
249
- 'http://localhost:5173',
250
- `http://localhost:${port}`,
251
- targetRepo.name
252
- );
253
-
254
- // Open browser if requested
255
- if (shouldOpen) {
256
- setTimeout(() => {
257
- open('http://localhost:5173');
258
- }, 1000);
259
- }
260
-
261
- } else {
262
- // Production mode - just start the backend server
263
- const { FriggManagementServer } = await import('../../management-ui/server/index.js');
264
-
265
- const server = new FriggManagementServer({
266
- port,
267
- projectRoot: workingDirectory,
268
- repositoryInfo: targetRepo,
269
- availableRepositories: targetRepo.isMultiRepo ? targetRepo.availableRepos : null
270
- });
271
- await server.start();
272
-
273
- processManager.printStatus(
274
- `http://localhost:${port}`,
275
- `http://localhost:${port}/api`,
276
- targetRepo.name
277
- );
278
-
279
- if (shouldOpen) {
280
- setTimeout(() => {
281
- open(`http://localhost:${port}`);
282
- }, 1000);
283
- }
284
- }
285
-
286
- // Keep the process running
287
- process.stdin.resume();
288
-
289
- } catch (error) {
290
- console.error(chalk.red('Failed to start Management UI:'), error.message);
291
- <<<<<<< HEAD
292
- >>>>>>> 652520a5 (Claude Flow RFC related development)
293
- =======
294
- if (error.code === 'EADDRINUSE') {
295
- console.log(chalk.yellow(`Port ${port} is already in use. Try using a different port with --port <number>`));
296
- }
297
- >>>>>>> f153939e (refactor: clean up CLI help display and remove unused dependencies)
298
- process.exit(1);
299
- }
300
- }
301
-
302
- module.exports = { uiCommand };
@@ -1,6 +0,0 @@
1
- export default {
2
- plugins: {
3
- tailwindcss: {},
4
- autoprefixer: {},
5
- },
6
- }
@@ -1,256 +0,0 @@
1
- import express from 'express';
2
- import { spawn } from 'child_process';
3
- import path from 'path';
4
- import fs from 'fs-extra';
5
- import { wsHandler } from '../websocket/handler.js';
6
-
7
- const router = express.Router();
8
-
9
- // Track backend process
10
- let backendProcess = null;
11
- let backendStatus = 'stopped';
12
- let backendLogs = [];
13
- const MAX_LOGS = 1000;
14
-
15
- // Helper function to find the backend directory
16
- async function findBackendDirectory() {
17
- const cwd = process.cwd();
18
- const possiblePaths = [
19
- path.join(cwd, 'backend'),
20
- path.join(cwd, '../../../backend'),
21
- path.join(cwd, '../../backend'),
22
- path.join(process.env.HOME || '', 'frigg', 'backend')
23
- ];
24
-
25
- for (const backendPath of possiblePaths) {
26
- if (await fs.pathExists(backendPath)) {
27
- return backendPath;
28
- }
29
- }
30
-
31
- throw new Error('Backend directory not found');
32
- }
33
-
34
- // Get backend status
35
- router.get('/status', (req, res) => {
36
- res.json({
37
- status: backendStatus,
38
- pid: backendProcess ? backendProcess.pid : null,
39
- uptime: backendProcess ? process.uptime() : 0,
40
- logs: backendLogs.slice(-100) // Return last 100 logs
41
- });
42
- });
43
-
44
- // Start backend
45
- router.post('/start', async (req, res) => {
46
- if (backendProcess && backendStatus === 'running') {
47
- return res.status(400).json({
48
- error: 'Backend is already running'
49
- });
50
- }
51
-
52
- try {
53
- const backendPath = await findBackendDirectory();
54
- const { stage = 'dev', verbose = false } = req.body;
55
-
56
- // Clear previous logs
57
- backendLogs = [];
58
- backendStatus = 'starting';
59
-
60
- // Broadcast status update
61
- wsHandler.broadcast('backend-status', {
62
- status: 'starting',
63
- message: 'Starting Frigg backend...'
64
- });
65
-
66
- // Start the backend process
67
- const args = ['run', 'start'];
68
- if (stage !== 'dev') {
69
- args.push('--stage', stage);
70
- }
71
- if (verbose) {
72
- args.push('--verbose');
73
- }
74
-
75
- backendProcess = spawn('npm', args, {
76
- cwd: backendPath,
77
- env: { ...process.env, NODE_ENV: stage === 'production' ? 'production' : 'development' },
78
- shell: true
79
- });
80
-
81
- // Handle stdout
82
- backendProcess.stdout.on('data', (data) => {
83
- const log = {
84
- type: 'stdout',
85
- message: data.toString(),
86
- timestamp: new Date().toISOString()
87
- };
88
- backendLogs.push(log);
89
- if (backendLogs.length > MAX_LOGS) {
90
- backendLogs.shift();
91
- }
92
- wsHandler.broadcast('backend-log', log);
93
- });
94
-
95
- // Handle stderr
96
- backendProcess.stderr.on('data', (data) => {
97
- const log = {
98
- type: 'stderr',
99
- message: data.toString(),
100
- timestamp: new Date().toISOString()
101
- };
102
- backendLogs.push(log);
103
- if (backendLogs.length > MAX_LOGS) {
104
- backendLogs.shift();
105
- }
106
- wsHandler.broadcast('backend-log', log);
107
- });
108
-
109
- // Handle process exit
110
- backendProcess.on('exit', (code, signal) => {
111
- backendStatus = 'stopped';
112
- backendProcess = null;
113
-
114
- const message = {
115
- status: 'stopped',
116
- code,
117
- signal,
118
- message: `Backend process exited with code ${code}`
119
- };
120
-
121
- wsHandler.broadcast('backend-status', message);
122
- });
123
-
124
- // Wait a bit to ensure process started
125
- await new Promise(resolve => setTimeout(resolve, 2000));
126
-
127
- if (backendProcess && !backendProcess.killed) {
128
- backendStatus = 'running';
129
- wsHandler.broadcast('backend-status', {
130
- status: 'running',
131
- message: 'Backend started successfully'
132
- });
133
-
134
- res.json({
135
- status: 'success',
136
- message: 'Backend started',
137
- pid: backendProcess.pid
138
- });
139
- } else {
140
- throw new Error('Failed to start backend process');
141
- }
142
-
143
- } catch (error) {
144
- backendStatus = 'stopped';
145
- res.status(500).json({
146
- error: error.message,
147
- details: 'Failed to start backend'
148
- });
149
- }
150
- });
151
-
152
- // Stop backend
153
- router.post('/stop', (req, res) => {
154
- if (!backendProcess || backendStatus !== 'running') {
155
- return res.status(400).json({
156
- error: 'Backend is not running'
157
- });
158
- }
159
-
160
- try {
161
- backendStatus = 'stopping';
162
- wsHandler.broadcast('backend-status', {
163
- status: 'stopping',
164
- message: 'Stopping Frigg backend...'
165
- });
166
-
167
- // Kill the process group
168
- if (process.platform === 'win32') {
169
- spawn('taskkill', ['/pid', backendProcess.pid, '/T', '/F']);
170
- } else {
171
- process.kill(-backendProcess.pid, 'SIGTERM');
172
- }
173
-
174
- // Give it time to shut down gracefully
175
- setTimeout(() => {
176
- if (backendProcess && !backendProcess.killed) {
177
- backendProcess.kill('SIGKILL');
178
- }
179
- }, 5000);
180
-
181
- res.json({
182
- status: 'success',
183
- message: 'Backend stopping'
184
- });
185
-
186
- } catch (error) {
187
- res.status(500).json({
188
- error: error.message,
189
- details: 'Failed to stop backend'
190
- });
191
- }
192
- });
193
-
194
- // Restart backend
195
- router.post('/restart', async (req, res) => {
196
- try {
197
- // Stop if running
198
- if (backendProcess && backendStatus === 'running') {
199
- await new Promise((resolve) => {
200
- backendProcess.on('exit', resolve);
201
-
202
- if (process.platform === 'win32') {
203
- spawn('taskkill', ['/pid', backendProcess.pid, '/T', '/F']);
204
- } else {
205
- process.kill(-backendProcess.pid, 'SIGTERM');
206
- }
207
- });
208
- }
209
-
210
- // Wait a moment
211
- await new Promise(resolve => setTimeout(resolve, 1000));
212
-
213
- // Start again
214
- const response = await fetch('http://localhost:3001/api/backend/start', {
215
- method: 'POST',
216
- headers: { 'Content-Type': 'application/json' },
217
- body: JSON.stringify(req.body)
218
- });
219
-
220
- const result = await response.json();
221
- res.json(result);
222
-
223
- } catch (error) {
224
- res.status(500).json({
225
- error: error.message,
226
- details: 'Failed to restart backend'
227
- });
228
- }
229
- });
230
-
231
- // Get logs
232
- router.get('/logs', (req, res) => {
233
- const { limit = 100, type } = req.query;
234
-
235
- let logs = backendLogs;
236
-
237
- if (type && ['stdout', 'stderr'].includes(type)) {
238
- logs = logs.filter(log => log.type === type);
239
- }
240
-
241
- res.json({
242
- logs: logs.slice(-parseInt(limit)),
243
- total: logs.length
244
- });
245
- });
246
-
247
- // Clear logs
248
- router.delete('/logs', (req, res) => {
249
- backendLogs = [];
250
- res.json({
251
- status: 'success',
252
- message: 'Logs cleared'
253
- });
254
- });
255
-
256
- export default router;