@vee-stack/delta-cli 2.0.7 → 2.0.9

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 (109) hide show
  1. package/dist/adapters/analysis.adapter.js +42 -0
  2. package/dist/analyzer/commands/analyze.js +74 -114
  3. package/dist/auth/device-auth.js +261 -0
  4. package/dist/auth/secure-auth.js +45 -16
  5. package/dist/commands/analyze.js +30 -27
  6. package/dist/commands/auth.js +13 -16
  7. package/dist/commands/status.js +2 -2
  8. package/dist/commands/whoami.js +6 -6
  9. package/dist/components/Dashboard.js +3 -5
  10. package/dist/components/DeltaApp.js +1 -1
  11. package/dist/components/UnifiedManager.js +48 -20
  12. package/dist/core/completion.js +14 -3
  13. package/dist/core/engine.js +10 -4
  14. package/dist/core/exit-codes.js +12 -4
  15. package/dist/core/wizard.js +1 -1
  16. package/dist/index.js +21 -5
  17. package/dist/providers/remote-provider.js +2 -2
  18. package/dist/telemetry/wrapper.js +114 -0
  19. package/dist/ui.js +9 -2
  20. package/dist/welcome.js +14 -4
  21. package/package.json +3 -1
  22. package/dist/apps/cli/src/analyzer/commands/analyze.js +0 -256
  23. package/dist/apps/cli/src/analyzer/commands/config.js +0 -83
  24. package/dist/apps/cli/src/analyzer/commands/report.js +0 -38
  25. package/dist/apps/cli/src/analyzer/generators/report.generator.js +0 -123
  26. package/dist/apps/cli/src/analyzer/index.js +0 -44
  27. package/dist/apps/cli/src/analyzer/scanners/project.scanner.js +0 -92
  28. package/dist/apps/cli/src/analyzer/validators/contracts.validator.js +0 -42
  29. package/dist/apps/cli/src/analyzer/validators/maintainability.validator.js +0 -40
  30. package/dist/apps/cli/src/analyzer/validators/observability.validator.js +0 -39
  31. package/dist/apps/cli/src/analyzer/validators/performance.validator.js +0 -42
  32. package/dist/apps/cli/src/analyzer/validators/security.validator.js +0 -66
  33. package/dist/apps/cli/src/analyzer/validators/soc.validator.js +0 -75
  34. package/dist/apps/cli/src/auth/secure-auth.js +0 -312
  35. package/dist/apps/cli/src/commands/analyze.js +0 -286
  36. package/dist/apps/cli/src/commands/auth-new.js +0 -37
  37. package/dist/apps/cli/src/commands/auth.js +0 -122
  38. package/dist/apps/cli/src/commands/config.js +0 -49
  39. package/dist/apps/cli/src/commands/deploy.js +0 -6
  40. package/dist/apps/cli/src/commands/init.js +0 -47
  41. package/dist/apps/cli/src/commands/logout.js +0 -23
  42. package/dist/apps/cli/src/commands/plugins.js +0 -21
  43. package/dist/apps/cli/src/commands/status.js +0 -80
  44. package/dist/apps/cli/src/commands/sync.js +0 -6
  45. package/dist/apps/cli/src/commands/whoami.js +0 -115
  46. package/dist/apps/cli/src/components/Dashboard.js +0 -168
  47. package/dist/apps/cli/src/components/DeltaApp.js +0 -56
  48. package/dist/apps/cli/src/components/UnifiedManager.js +0 -324
  49. package/dist/apps/cli/src/core/audit.js +0 -184
  50. package/dist/apps/cli/src/core/completion.js +0 -294
  51. package/dist/apps/cli/src/core/contracts.js +0 -6
  52. package/dist/apps/cli/src/core/engine.js +0 -124
  53. package/dist/apps/cli/src/core/exit-codes.js +0 -71
  54. package/dist/apps/cli/src/core/hooks.js +0 -181
  55. package/dist/apps/cli/src/core/index.js +0 -7
  56. package/dist/apps/cli/src/core/policy.js +0 -115
  57. package/dist/apps/cli/src/core/profiles.js +0 -161
  58. package/dist/apps/cli/src/core/wizard.js +0 -203
  59. package/dist/apps/cli/src/index.js +0 -636
  60. package/dist/apps/cli/src/interactive/index.js +0 -11
  61. package/dist/apps/cli/src/plugins/GitStatusPlugin.js +0 -99
  62. package/dist/apps/cli/src/providers/ai-provider.js +0 -74
  63. package/dist/apps/cli/src/providers/local-provider.js +0 -302
  64. package/dist/apps/cli/src/providers/remote-provider.js +0 -100
  65. package/dist/apps/cli/src/types/api.js +0 -3
  66. package/dist/apps/cli/src/ui.js +0 -219
  67. package/dist/apps/cli/src/welcome.js +0 -81
  68. package/dist/bundle.js +0 -504
  69. package/dist/packages/domain/src/constitution/contracts/index.js +0 -43
  70. package/dist/packages/domain/src/constitution/contracts/ts.rules.js +0 -268
  71. package/dist/packages/domain/src/constitution/index.js +0 -139
  72. package/dist/packages/domain/src/constitution/maintainability/index.js +0 -43
  73. package/dist/packages/domain/src/constitution/maintainability/ts.rules.js +0 -344
  74. package/dist/packages/domain/src/constitution/observability/index.js +0 -43
  75. package/dist/packages/domain/src/constitution/observability/ts.rules.js +0 -307
  76. package/dist/packages/domain/src/constitution/performance/index.js +0 -43
  77. package/dist/packages/domain/src/constitution/performance/ts.rules.js +0 -325
  78. package/dist/packages/domain/src/constitution/security/index.js +0 -50
  79. package/dist/packages/domain/src/constitution/security/ts.rules.js +0 -267
  80. package/dist/packages/domain/src/constitution/soc/index.js +0 -43
  81. package/dist/packages/domain/src/constitution/soc/ts.rules.js +0 -360
  82. package/dist/packages/domain/src/contracts/analysis.contract.js +0 -18
  83. package/dist/packages/domain/src/contracts/index.js +0 -7
  84. package/dist/packages/domain/src/contracts/projects.contract.js +0 -18
  85. package/dist/packages/domain/src/control/registry/rules.registry.js +0 -29
  86. package/dist/packages/domain/src/control/schemas/policies.js +0 -6
  87. package/dist/packages/domain/src/core/analysis/discovery.js +0 -163
  88. package/dist/packages/domain/src/core/analysis/engine.contract.js +0 -298
  89. package/dist/packages/domain/src/core/analysis/engine.js +0 -77
  90. package/dist/packages/domain/src/core/analysis/index.js +0 -14
  91. package/dist/packages/domain/src/core/analysis/orchestrator.js +0 -242
  92. package/dist/packages/domain/src/core/comparison/engine.js +0 -29
  93. package/dist/packages/domain/src/core/comparison/index.js +0 -5
  94. package/dist/packages/domain/src/core/documentation/index.js +0 -5
  95. package/dist/packages/domain/src/core/documentation/pipeline.js +0 -41
  96. package/dist/packages/domain/src/core/fs/adapter.js +0 -111
  97. package/dist/packages/domain/src/core/fs/index.js +0 -5
  98. package/dist/packages/domain/src/core/parser/unified-parser.js +0 -166
  99. package/dist/packages/domain/src/index.js +0 -33
  100. package/dist/packages/domain/src/plugin/registry.js +0 -195
  101. package/dist/packages/domain/src/plugin/types.js +0 -6
  102. package/dist/packages/domain/src/ports/analysis.engine.js +0 -7
  103. package/dist/packages/domain/src/ports/audit.logger.js +0 -7
  104. package/dist/packages/domain/src/ports/project.repository.js +0 -7
  105. package/dist/packages/domain/src/rules/index.js +0 -134
  106. package/dist/packages/domain/src/types/analysis.js +0 -6
  107. package/dist/packages/domain/src/types/errors.js +0 -53
  108. package/dist/packages/domain/src/types/fs.js +0 -6
  109. package/dist/packages/domain/src/types/index.js +0 -7
@@ -16,7 +16,7 @@ import { createServer } from 'http';
16
16
  import { URL } from 'url';
17
17
  import crypto from 'crypto';
18
18
  import chalk from 'chalk';
19
- import { printSuccess, printError, printInfo, printWarning, startSpinner, stopSpinner } from '../ui.js';
19
+ import { printSuccess, printError, printInfo, printWarning, startSpinner, stopSpinner, } from '../ui.js';
20
20
  const CONFIG_DIR = path.join(os.homedir(), '.delta');
21
21
  const TOKEN_FILE = path.join(CONFIG_DIR, 'tokens.enc');
22
22
  const KEY_FILE = path.join(CONFIG_DIR, '.key');
@@ -71,10 +71,7 @@ async function decrypt(encryptedData) {
71
71
  // PKCE Code Generator
72
72
  function generatePKCE() {
73
73
  const verifier = crypto.randomBytes(32).toString('base64url');
74
- const challenge = crypto
75
- .createHash('sha256')
76
- .update(verifier)
77
- .digest('base64url');
74
+ const challenge = crypto.createHash('sha256').update(verifier).digest('base64url');
78
75
  return { verifier, challenge };
79
76
  }
80
77
  // Secure Token Storage using encrypted file
@@ -114,8 +111,21 @@ export class SecureTokenStore {
114
111
  return tokens.access;
115
112
  }
116
113
  static async saveRefreshToken(token) {
114
+ // Encrypt token (side effect - encryption happens before storage)
115
+ const encrypted = await encrypt(token);
116
+ void encrypted; // Mark as intentionally used for encryption side effect
117
117
  const tokens = await this.loadTokens();
118
- await this.saveTokens({ refresh: token, access: tokens.access ?? undefined });
118
+ await this.saveTokens({
119
+ access: tokens.access || undefined,
120
+ refresh: token,
121
+ });
122
+ }
123
+ static async saveSessionInfo(sessionInfo) {
124
+ // For now, store session info in a separate file
125
+ // In production, this should be encrypted and stored securely
126
+ const sessionFile = path.join(CONFIG_DIR, 'session.json');
127
+ await fs.mkdir(CONFIG_DIR, { recursive: true });
128
+ await fs.writeFile(sessionFile, JSON.stringify(sessionInfo, null, 2));
119
129
  }
120
130
  static async getRefreshToken() {
121
131
  const tokens = await this.loadTokens();
@@ -123,10 +133,29 @@ export class SecureTokenStore {
123
133
  }
124
134
  static async clearTokens() {
125
135
  try {
136
+ // Check if file exists first
137
+ try {
138
+ await fs.access(TOKEN_FILE);
139
+ }
140
+ catch {
141
+ // File doesn't exist, nothing to clear
142
+ return;
143
+ }
126
144
  await fs.unlink(TOKEN_FILE);
145
+ // Also clear session file if exists
146
+ const sessionFile = path.join(CONFIG_DIR, 'session.json');
147
+ try {
148
+ await fs.access(sessionFile);
149
+ await fs.unlink(sessionFile);
150
+ }
151
+ catch {
152
+ // Session file may not exist
153
+ }
154
+ console.log(' Tokens cleared from:', TOKEN_FILE);
127
155
  }
128
- catch {
129
- // File may not exist
156
+ catch (error) {
157
+ console.error(' Warning: Could not clear tokens:', error.message);
158
+ throw error;
130
159
  }
131
160
  }
132
161
  static async hasTokens() {
@@ -236,7 +265,7 @@ export async function startOAuthFlow(method = 'oauth') {
236
265
  if (!tokenResponse.ok) {
237
266
  throw new Error('Failed to exchange authorization code');
238
267
  }
239
- const tokens = await tokenResponse.json();
268
+ const tokens = (await tokenResponse.json());
240
269
  // Store tokens securely
241
270
  await SecureTokenStore.saveAccessToken(tokens.access_token);
242
271
  await SecureTokenStore.saveRefreshToken(tokens.refresh_token);
@@ -259,13 +288,13 @@ export async function authenticateWithPAT(token) {
259
288
  // Validate token
260
289
  const response = await fetch(`${apiUrl}/api/auth/verify`, {
261
290
  headers: {
262
- 'Authorization': `Bearer ${token}`,
291
+ Authorization: `Bearer ${token}`,
263
292
  },
264
293
  });
265
294
  if (!response.ok) {
266
295
  throw new Error('Invalid token');
267
296
  }
268
- const data = await response.json();
297
+ const data = (await response.json());
269
298
  // Store token
270
299
  await SecureTokenStore.saveAccessToken(token);
271
300
  stopSpinner(true, 'Token validated');
@@ -299,7 +328,7 @@ export async function refreshAccessToken() {
299
328
  if (!response.ok) {
300
329
  throw new Error('Token refresh failed');
301
330
  }
302
- const tokens = await response.json();
331
+ const tokens = (await response.json());
303
332
  await SecureTokenStore.saveAccessToken(tokens.access_token);
304
333
  if (tokens.refresh_token) {
305
334
  await SecureTokenStore.saveRefreshToken(tokens.refresh_token);
@@ -334,7 +363,7 @@ export async function getAuthStatus() {
334
363
  const apiUrl = process.env.DELTA_API_URL || 'http://localhost:3000';
335
364
  const response = await fetch(`${apiUrl}/api/auth/me`, {
336
365
  headers: {
337
- 'Authorization': `Bearer ${token}`,
366
+ Authorization: `Bearer ${token}`,
338
367
  },
339
368
  });
340
369
  if (!response.ok) {
@@ -347,19 +376,19 @@ export async function getAuthStatus() {
347
376
  const newToken = await SecureTokenStore.getAccessToken();
348
377
  const retryResponse = await fetch(`${apiUrl}/api/auth/me`, {
349
378
  headers: {
350
- 'Authorization': `Bearer ${newToken}`,
379
+ Authorization: `Bearer ${newToken}`,
351
380
  },
352
381
  });
353
382
  if (!retryResponse.ok) {
354
383
  return { authenticated: false };
355
384
  }
356
- const userData = await retryResponse.json();
385
+ const userData = (await retryResponse.json());
357
386
  return {
358
387
  authenticated: true,
359
388
  user: userData,
360
389
  };
361
390
  }
362
- const userData = await response.json();
391
+ const userData = (await response.json());
363
392
  return {
364
393
  authenticated: true,
365
394
  user: userData,
@@ -7,7 +7,7 @@ import * as crypto from 'crypto';
7
7
  import { loadConfig } from './auth.js';
8
8
  import { SecureTokenStore } from '../auth/secure-auth.js';
9
9
  import chalk from 'chalk';
10
- import { icons, startSpinner, stopSpinner, printSuccess, printInfo, printWarning, createTable, printDivider } from '../ui.js';
10
+ import { icons, startSpinner, stopSpinner, printSuccess, printInfo, printWarning, createTable, printDivider, } from '../ui.js';
11
11
  function extractApiErrorPayload(payload) {
12
12
  if (!payload || typeof payload !== 'object')
13
13
  return {};
@@ -22,24 +22,27 @@ function extractApiErrorPayload(payload) {
22
22
  }
23
23
  export async function analyzeCommand(projectPath, options) {
24
24
  const targetPath = path.resolve(projectPath);
25
- // Check authentication FIRST if upload is requested
25
+ // Check authentication FIRST for all operations
26
+ printInfo('🔐 Checking authentication...');
27
+ await loadConfig();
28
+ const pat = await SecureTokenStore.getAccessToken();
29
+ if (!pat) {
30
+ console.error();
31
+ console.error(chalk.red('❌ Error: You must be logged in to use Delta CLI.'));
32
+ console.error();
33
+ console.error(chalk.yellow('Please authenticate first:'));
34
+ console.error(chalk.cyan(' delta login'));
35
+ console.error();
36
+ console.error(chalk.dim('Or use a valid PAT:'));
37
+ console.error(chalk.cyan(' delta login --token <your-pat>'));
38
+ console.error();
39
+ process.exit(1);
40
+ }
41
+ printSuccess('✓ Authenticated');
42
+ console.log();
43
+ // Additional check for upload permission
26
44
  if (options.upload) {
27
- printInfo('🔐 Checking authentication...');
28
- const config = await loadConfig();
29
- const pat = await SecureTokenStore.getAccessToken();
30
- if (!pat) {
31
- console.error();
32
- console.error(chalk.red('❌ Error: You must be logged in to upload reports.'));
33
- console.error();
34
- console.error(chalk.yellow('Please authenticate first:'));
35
- console.error(chalk.cyan(' delta login'));
36
- console.error();
37
- console.error(chalk.dim('Or use --upload with a valid PAT:'));
38
- console.error(chalk.cyan(' delta analyze . --upload --token <your-pat>'));
39
- console.error();
40
- process.exit(1);
41
- }
42
- printSuccess('✓ Authenticated');
45
+ printInfo('📤 Upload mode enabled');
43
46
  console.log();
44
47
  }
45
48
  printInfo('🔍 Starting Delta Analysis Engine...');
@@ -50,7 +53,9 @@ export async function analyzeCommand(projectPath, options) {
50
53
  startSpinner('Scanning project files...');
51
54
  const files = await discoverFiles(targetPath, {
52
55
  include: options.include ? [options.include] : ['**/*.{ts,tsx,js,jsx}'],
53
- exclude: options.exclude ? [options.exclude].concat(['node_modules', 'dist', '.git']) : ['node_modules', 'dist', '.git'],
56
+ exclude: options.exclude
57
+ ? [options.exclude].concat(['node_modules', 'dist', '.git'])
58
+ : ['node_modules', 'dist', '.git'],
54
59
  maxSize: parseInt(options.maxSize, 10),
55
60
  });
56
61
  stopSpinner(true, `Found ${files.length} files to analyze`);
@@ -133,9 +138,7 @@ export async function analyzeCommand(projectPath, options) {
133
138
  root_fingerprint: '',
134
139
  path: targetPath,
135
140
  },
136
- tools_used: [
137
- { id: 'delta-core', version: '0.5.0', adapter_version: '0.5.0' },
138
- ],
141
+ tools_used: [{ id: 'delta-core', version: '0.5.0', adapter_version: '0.5.0' }],
139
142
  summary: {
140
143
  total: findings.length,
141
144
  high: findings.filter(f => f.severity === 'high').length,
@@ -209,7 +212,7 @@ async function uploadReport(report) {
209
212
  const initResponse = await fetch(`${apiUrl}/api/upload/init`, {
210
213
  method: 'POST',
211
214
  headers: {
212
- 'Authorization': `Bearer ${pat}`,
215
+ Authorization: `Bearer ${pat}`,
213
216
  'Content-Type': 'application/json',
214
217
  'Idempotency-Key': crypto.randomUUID(),
215
218
  },
@@ -234,7 +237,7 @@ async function uploadReport(report) {
234
237
  const message = apiError.message || `Init failed: ${initResponse.status}`;
235
238
  throw new Error(message + details);
236
239
  }
237
- const initData = await initResponse.json();
240
+ const initData = (await initResponse.json());
238
241
  if (!initData.success) {
239
242
  throw new Error(initData.error?.message || 'Upload init failed');
240
243
  }
@@ -246,7 +249,7 @@ async function uploadReport(report) {
246
249
  const uploadResponse = await fetch(`${apiUrl}/api/upload/${uploadId}`, {
247
250
  method: 'PUT',
248
251
  headers: {
249
- 'Authorization': `Bearer ${pat}`,
252
+ Authorization: `Bearer ${pat}`,
250
253
  'Content-Type': 'application/json',
251
254
  },
252
255
  body: JSON.stringify({
@@ -277,7 +280,7 @@ async function uploadReport(report) {
277
280
  const finalizeResponse = await fetch(`${apiUrl}/api/upload/${uploadId}/finalize`, {
278
281
  method: 'POST',
279
282
  headers: {
280
- 'Authorization': `Bearer ${pat}`,
283
+ Authorization: `Bearer ${pat}`,
281
284
  'Content-Type': 'application/json',
282
285
  'Idempotency-Key': crypto.randomUUID(),
283
286
  },
@@ -296,7 +299,7 @@ async function uploadReport(report) {
296
299
  const message = apiError.message || `Finalize failed: ${finalizeResponse.status}`;
297
300
  throw new Error(message + details);
298
301
  }
299
- const finalizeData = await finalizeResponse.json();
302
+ const finalizeData = (await finalizeResponse.json());
300
303
  if (!finalizeData.success) {
301
304
  throw new Error(finalizeData.error?.message || 'Upload finalize failed');
302
305
  }
@@ -5,7 +5,8 @@ import * as fs from 'fs/promises';
5
5
  import * as path from 'path';
6
6
  import * as os from 'os';
7
7
  import { icons, startSpinner, stopSpinner, printHeader, printSection, printSuccess, printError, printInfo, printKeyValue, printCommandHint, createTable, printWelcome, } from '../ui.js';
8
- import { SecureTokenStore, startOAuthFlow } from '../auth/secure-auth.js';
8
+ import { SecureTokenStore } from '../auth/secure-auth.js';
9
+ import { startDeviceFlow } from '../auth/device-auth.js';
9
10
  const CONFIG_DIR = path.join(os.homedir(), '.delta');
10
11
  const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
11
12
  async function loadConfig() {
@@ -26,24 +27,23 @@ export const authCommands = {
26
27
  printWelcome();
27
28
  printHeader('Authentication');
28
29
  const token = options.token ?? process.env.DELTA_PAT;
29
- // If no token provided, use OAuth2 flow (opens browser)
30
+ // Load existing config to get custom apiUrl if set
31
+ const existingConfig = await loadConfig();
32
+ const apiUrl = process.env.DELTA_API_URL || existingConfig.apiUrl || 'http://localhost:3000';
33
+ // If no token provided, use Device Authorization Flow
30
34
  if (!token) {
31
- printInfo('No token provided. Starting OAuth2 authentication...');
32
- printInfo('A browser window will open for you to sign in.');
35
+ printInfo('No token provided. Starting Device Authorization Flow...');
36
+ printInfo('This will open your browser for secure authentication.');
33
37
  console.log();
34
- const success = await startOAuthFlow('oauth');
38
+ const success = await startDeviceFlow(apiUrl);
35
39
  if (!success) {
36
- printError('Authentication failed');
40
+ printError('Device authorization failed');
37
41
  console.log();
38
42
  printInfo('You can also authenticate using a Personal Access Token:');
39
43
  printCommandHint('delta login --token <your-token>', '');
40
44
  process.exit(1);
41
45
  }
42
- // OAuth flow already saved the token, just show success
43
- printSuccess('Authentication successful! 🎉');
44
- console.log();
45
- printCommandHint('delta whoami', 'to see account details');
46
- printCommandHint('delta analyze', 'to start analyzing code');
46
+ // Device flow already saved the token and showed success
47
47
  process.exit(0);
48
48
  }
49
49
  // PAT Token flow (when token is provided)
@@ -55,9 +55,6 @@ export const authCommands = {
55
55
  printCommandHint('http://localhost:3000/dashboard/cli-tokens', '');
56
56
  process.exit(1);
57
57
  }
58
- // Load existing config to get custom apiUrl if set
59
- const existingConfig = await loadConfig();
60
- const apiUrl = process.env.DELTA_API_URL || existingConfig.apiUrl || 'http://localhost:3000';
61
58
  printSection('Connecting to Platform');
62
59
  printKeyValue('API Endpoint', apiUrl);
63
60
  console.log();
@@ -67,7 +64,7 @@ export const authCommands = {
67
64
  const timeout = setTimeout(() => controller.abort(), 10000);
68
65
  const response = await fetch(`${apiUrl}/api/me/entitlements`, {
69
66
  headers: {
70
- 'Authorization': `Bearer ${token}`,
67
+ Authorization: `Bearer ${token}`,
71
68
  'Content-Type': 'application/json',
72
69
  },
73
70
  signal: controller.signal,
@@ -77,7 +74,7 @@ export const authCommands = {
77
74
  const errorText = await response.text().catch(() => response.statusText);
78
75
  throw new Error(`HTTP ${response.status}: ${errorText}`);
79
76
  }
80
- const data = await response.json();
77
+ const data = (await response.json());
81
78
  if (!data.success) {
82
79
  throw new Error(data.error?.message || 'Authentication failed');
83
80
  }
@@ -47,11 +47,11 @@ export async function statusCommand(projectPath, _options) {
47
47
  startSpinner('Testing connection...');
48
48
  try {
49
49
  const response = await fetch(`${apiUrl}/api/me/entitlements`, {
50
- headers: { 'Authorization': `Bearer ${pat}` },
50
+ headers: { Authorization: `Bearer ${pat}` },
51
51
  });
52
52
  if (response.ok) {
53
53
  stopSpinner(true, 'Connection active');
54
- const data = await response.json();
54
+ const data = (await response.json());
55
55
  if (data.success) {
56
56
  printKeyValue('User', data.data.user.email);
57
57
  printKeyValue('Plan', data.data.user.plan);
@@ -21,7 +21,7 @@ export async function whoamiCommand(_options) {
21
21
  const apiUrl = config.apiUrl || process.env.DELTA_API_URL || 'http://localhost:3000';
22
22
  const response = await fetch(`${apiUrl}/api/auth/me`, {
23
23
  headers: {
24
- 'Authorization': `Bearer ${pat}`,
24
+ Authorization: `Bearer ${pat}`,
25
25
  'Content-Type': 'application/json',
26
26
  },
27
27
  });
@@ -36,7 +36,7 @@ export async function whoamiCommand(_options) {
36
36
  }
37
37
  throw new Error(`API error: ${response.status} ${response.statusText}`);
38
38
  }
39
- const data = await response.json();
39
+ const data = (await response.json());
40
40
  stopSpinner(true);
41
41
  console.log();
42
42
  const user = data;
@@ -62,10 +62,10 @@ export async function whoamiCommand(_options) {
62
62
  }
63
63
  function formatPlan(plan) {
64
64
  const planColors = {
65
- 'individual_free': '🔷 Free',
66
- 'individual_pro': '💎 Pro',
67
- 'individual_team': '👥 Team',
68
- 'enterprise': '🏢 Enterprise',
65
+ individual_free: '🔷 Free',
66
+ individual_pro: '💎 Pro',
67
+ individual_team: '👥 Team',
68
+ enterprise: '🏢 Enterprise',
69
69
  };
70
70
  return planColors[plan] || plan;
71
71
  }
@@ -28,7 +28,7 @@ const Sparkline = ({ data, width = 20 }) => {
28
28
  return _jsx(Text, { color: "cyan", children: display.join('') });
29
29
  };
30
30
  // Progress bar component
31
- const ProgressBar = ({ value, max, width = 20 }) => {
31
+ const ProgressBar = ({ value, max, width = 20, }) => {
32
32
  const percentage = Math.min(Math.max(value / max, 0), 1);
33
33
  const filled = Math.floor(percentage * width);
34
34
  const empty = width - filled;
@@ -44,9 +44,7 @@ const StatusIndicator = ({ status }) => {
44
44
  };
45
45
  // Project row component
46
46
  const ProjectRow = ({ project, isSelected }) => {
47
- const timeAgo = project.lastAnalyze
48
- ? formatTimeAgo(project.lastAnalyze)
49
- : 'never';
47
+ const timeAgo = project.lastAnalyze ? formatTimeAgo(project.lastAnalyze) : 'never';
50
48
  const totalFindings = project.findings.high + project.findings.medium + project.findings.low;
51
49
  const findingsColor = project.findings.high > 0 ? 'red' : project.findings.medium > 0 ? 'yellow' : 'green';
52
50
  return (_jsxs(Box, { flexDirection: "row", gap: 2, children: [_jsx(Box, { width: 3, children: isSelected ? _jsx(Text, { color: "cyan", children: "\u276F" }) : _jsx(Text, { children: " " }) }), _jsx(Box, { width: 12, children: _jsx(StatusIndicator, { status: project.status }) }), _jsx(Box, { width: 20, children: _jsx(Text, { bold: isSelected, children: project.name }) }), _jsx(Box, { width: 12, children: _jsx(Text, { dimColor: true, children: timeAgo }) }), _jsx(Box, { width: 10, children: _jsxs(Text, { color: findingsColor, children: [totalFindings, " (", project.findings.high, "H)"] }) }), _jsx(Box, { width: 10, children: _jsxs(Text, { dimColor: true, children: [project.duration, "ms"] }) })] }));
@@ -163,7 +161,7 @@ export const EnhancedDashboard = () => {
163
161
  const project = data.projects[selectedIndex];
164
162
  return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Text, { bold: true, color: "cyan", children: ["\uD83D\uDCC1 Project Details: ", project.name] }), _jsx(CustomDivider, {}), _jsxs(Box, { flexDirection: "column", gap: 1, marginY: 1, children: [_jsxs(Text, { children: ["Path: ", _jsx(Text, { color: "cyan", children: project.path })] }), _jsxs(Text, { children: ["Status: ", _jsx(StatusIndicator, { status: project.status })] }), _jsxs(Text, { children: ["Files Analyzed: ", _jsx(Text, { bold: true, children: project.filesAnalyzed })] }), _jsxs(Text, { children: ["Duration: ", _jsxs(Text, { bold: true, children: [project.duration, "ms"] })] }), _jsxs(Text, { children: ["Last Analysis: ", project.lastAnalyze?.toLocaleString() || 'never'] })] }), _jsxs(Box, { marginY: 1, children: [_jsx(Text, { bold: true, children: "Findings:" }), _jsxs(Box, { flexDirection: "row", gap: 4, children: [_jsxs(Text, { color: "red", children: ["High: ", project.findings.high] }), _jsxs(Text, { color: "yellow", children: ["Medium: ", project.findings.medium] }), _jsxs(Text, { color: "green", children: ["Low: ", project.findings.low] })] })] }), _jsx(Box, { marginTop: 2, children: _jsx(Text, { dimColor: true, children: "Press Esc or Q to go back" }) })] }));
165
163
  }
166
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "cyan", backgroundColor: "gray", children: [' ', " Delta CLI Dashboard ", ' '] }) }), _jsxs(Box, { flexDirection: "row", gap: 2, marginBottom: 1, children: [_jsx(Box, { width: "50%", children: _jsx(StatsBox, { stats: data.stats }) }), _jsx(Box, { width: "50%", children: _jsx(FindingsChart, { projects: data.projects }) })] }), _jsx(CustomDivider, { title: "Projects" }), _jsxs(Box, { flexDirection: "row", gap: 2, marginY: 1, children: [_jsx(Box, { width: 3, children: _jsx(Text, { children: " " }) }), _jsx(Box, { width: 12, children: _jsx(Text, { dimColor: true, children: "Status" }) }), _jsx(Box, { width: 20, children: _jsx(Text, { dimColor: true, children: "Name" }) }), _jsx(Box, { width: 12, children: _jsx(Text, { dimColor: true, children: "Last" }) }), _jsx(Box, { width: 10, children: _jsx(Text, { dimColor: true, children: "Findings" }) }), _jsx(Box, { width: 10, children: _jsx(Text, { dimColor: true, children: "Duration" }) })] }), _jsx(Box, { flexDirection: "column", children: data.projects.map((project, index) => (_jsx(ProjectRow, { project: project, isSelected: index === selectedIndex }, project.name))) }), _jsx(Box, { marginTop: 2, children: _jsx(Text, { dimColor: true, children: "\u2191\u2193 Navigate \u2022 Enter Details \u2022 Q/Esc Exit" }) })] }));
164
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "cyan", backgroundColor: "gray", children: [' ', "Delta CLI Dashboard", ' '] }) }), _jsxs(Box, { flexDirection: "row", gap: 2, marginBottom: 1, children: [_jsx(Box, { width: "50%", children: _jsx(StatsBox, { stats: data.stats }) }), _jsx(Box, { width: "50%", children: _jsx(FindingsChart, { projects: data.projects }) })] }), _jsx(CustomDivider, { title: "Projects" }), _jsxs(Box, { flexDirection: "row", gap: 2, marginY: 1, children: [_jsx(Box, { width: 3, children: _jsx(Text, { children: " " }) }), _jsx(Box, { width: 12, children: _jsx(Text, { dimColor: true, children: "Status" }) }), _jsx(Box, { width: 20, children: _jsx(Text, { dimColor: true, children: "Name" }) }), _jsx(Box, { width: 12, children: _jsx(Text, { dimColor: true, children: "Last" }) }), _jsx(Box, { width: 10, children: _jsx(Text, { dimColor: true, children: "Findings" }) }), _jsx(Box, { width: 10, children: _jsx(Text, { dimColor: true, children: "Duration" }) })] }), _jsx(Box, { flexDirection: "column", children: data.projects.map((project, index) => (_jsx(ProjectRow, { project: project, isSelected: index === selectedIndex }, project.name))) }), _jsx(Box, { marginTop: 2, children: _jsx(Text, { dimColor: true, children: "\u2191\u2193 Navigate \u2022 Enter Details \u2022 Q/Esc Exit" }) })] }));
167
165
  };
168
166
  export default EnhancedDashboard;
169
167
  //# sourceMappingURL=Dashboard.js.map
@@ -12,7 +12,7 @@ export const DeltaLogo = () => {
12
12
  const frames = ['◐', '◓', '◑', '◒'];
13
13
  useEffect(() => {
14
14
  const timer = setInterval(() => {
15
- setFrame((f) => (f + 1) % frames.length);
15
+ setFrame(f => (f + 1) % frames.length);
16
16
  }, 100);
17
17
  return () => clearInterval(timer);
18
18
  }, []);
@@ -38,13 +38,17 @@ const SHORTCUTS = [
38
38
  ];
39
39
  const getSeverityFromType = (type) => {
40
40
  switch (type) {
41
- case 'error': return 'high';
42
- case 'warning': return 'medium';
43
- case 'success': return 'low';
44
- default: return 'low';
41
+ case 'error':
42
+ return 'high';
43
+ case 'warning':
44
+ return 'medium';
45
+ case 'success':
46
+ return 'low';
47
+ default:
48
+ return 'low';
45
49
  }
46
50
  };
47
- const StatusBadge = ({ status, progress }) => {
51
+ const StatusBadge = ({ status, progress, }) => {
48
52
  const config = {
49
53
  stopped: { color: 'gray', text: 'STOPPED', icon: '○' },
50
54
  running: { color: 'green', text: 'RUNNING', icon: '●' },
@@ -67,7 +71,7 @@ const LogEntry = ({ entry }) => {
67
71
  const icons = { info: 'ℹ', success: '✓', error: '✗', warning: '⚠' };
68
72
  return (_jsxs(Box, { children: [_jsxs(Text, { dimColor: true, children: ["[", entry.timestamp, "] "] }), _jsxs(Text, { color: colors[entry.type], children: [icons[entry.type], " "] }), _jsxs(Text, { children: [entry.service, ": ", entry.message] })] }));
69
73
  };
70
- const MenuItem = ({ item, isSelected }) => {
74
+ const MenuItem = ({ item, isSelected, }) => {
71
75
  return (_jsxs(Box, { paddingX: 1, width: 28, children: [_jsxs(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: [isSelected ? '❯ ' : ' ', isSelected ? '' : ' '] }), _jsx(Text, { color: isSelected ? 'cyan' : 'cyan', bold: isSelected, children: item.num }), _jsx(Text, { children: " " }), _jsx(Text, { color: isSelected ? 'white' : 'gray', children: item.icon }), _jsx(Text, { children: " " }), _jsx(Text, { color: isSelected ? 'white' : 'gray', bold: isSelected, children: item.label }), _jsx(Text, { children: ' '.repeat(28 - item.label.length - 4) })] }));
72
76
  };
73
77
  const HelpModal = ({ onClose }) => {
@@ -75,12 +79,12 @@ const HelpModal = ({ onClose }) => {
75
79
  if (key.escape || key.return)
76
80
  onClose();
77
81
  });
78
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, width: 50, children: [_jsx(Text, { bold: true, color: "cyan", children: "\u2328\uFE0F Keyboard Shortcuts" }), _jsx(Box, { marginY: 1 }), SHORTCUTS.map((s, i) => (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", bold: true, children: s.key.padEnd(10) }), _jsx(Text, { color: "white", children: s.desc })] }, i))), _jsx(Box, { marginY: 1 }), _jsx(Text, { dimColor: true, children: "Press Enter or Esc to close" })] }));
82
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, width: 50, children: [_jsx(Text, { bold: true, color: "cyan", children: "\u2328\uFE0F Keyboard Shortcuts" }), _jsx(Box, { marginY: 1 }), SHORTCUTS.map((s, i) => (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", bold: true, children: s.key.padEnd(10) }), _jsx(Text, { color: "white", children: s.desc })] }, i))), _jsx(Box, { marginY: 1 }), _jsx(Text, { dimColor: true, children: "Press Enter or Esc to close" })] }));
79
83
  };
80
84
  const FilterBar = ({ severity, source, isActive }) => {
81
85
  const severities = ['all', 'high', 'medium', 'low'];
82
86
  const sources = ['all', 'CLI', 'Web', 'Tests', 'Build', 'System'];
83
- return (_jsx(Box, { flexDirection: "column", marginBottom: 1, children: _jsxs(Box, { children: [_jsx(Text, { color: isActive ? 'cyan' : 'gray', bold: isActive, children: "Filter: " }), _jsx(Text, { color: "gray", children: "Severity[" }), severities.map((s, i) => (_jsxs(Text, { color: severity === s ? 'green' : 'gray', bold: severity === s, children: [s, i < severities.length - 1 ? '|' : ''] }, s))), _jsx(Text, { color: "gray", children: "] Source[" }), sources.map((s, i) => (_jsxs(Text, { color: source === s ? 'green' : 'gray', bold: source === s, children: [s, i < sources.length - 1 ? '|' : ''] }, s))), _jsx(Text, { color: "gray", children: "]" })] }) }));
87
+ return (_jsx(Box, { flexDirection: "column", marginBottom: 1, children: _jsxs(Box, { children: [_jsxs(Text, { color: isActive ? 'cyan' : 'gray', bold: isActive, children: ["Filter:", ' '] }), _jsx(Text, { color: "gray", children: "Severity[" }), severities.map((s, i) => (_jsxs(Text, { color: severity === s ? 'green' : 'gray', bold: severity === s, children: [s, i < severities.length - 1 ? '|' : ''] }, s))), _jsx(Text, { color: "gray", children: "] Source[" }), sources.map((s, i) => (_jsxs(Text, { color: source === s ? 'green' : 'gray', bold: source === s, children: [s, i < sources.length - 1 ? '|' : ''] }, s))), _jsx(Text, { color: "gray", children: "]" })] }) }));
84
88
  };
85
89
  const loadUserState = () => {
86
90
  try {
@@ -114,8 +118,22 @@ export const UnifiedManager = () => {
114
118
  const [severityFilter, setSeverityFilter] = useState('all');
115
119
  const [sourceFilter, setSourceFilter] = useState('all');
116
120
  const [services, setServices] = useState([
117
- { id: 'cli', name: 'CLI Dev Server', port: undefined, status: 'stopped', message: 'Ready to start', progress: 0 },
118
- { id: 'web', name: 'Web Dev Server', port: undefined, status: 'stopped', message: 'Ready to start', progress: 0 },
121
+ {
122
+ id: 'cli',
123
+ name: 'CLI Dev Server',
124
+ port: undefined,
125
+ status: 'stopped',
126
+ message: 'Ready to start',
127
+ progress: 0,
128
+ },
129
+ {
130
+ id: 'web',
131
+ name: 'Web Dev Server',
132
+ port: undefined,
133
+ status: 'stopped',
134
+ message: 'Ready to start',
135
+ progress: 0,
136
+ },
119
137
  ]);
120
138
  const serviceProcesses = React.useRef(new Map());
121
139
  const pluginRegistryRef = useRef(null);
@@ -172,12 +190,14 @@ export const UnifiedManager = () => {
172
190
  const service = services.find(s => s.id === serviceId);
173
191
  if (!service)
174
192
  return;
175
- setServices(prev => prev.map(s => s.id === serviceId ? { ...s, status: 'building', message: 'Starting...', progress: 0 } : s));
193
+ setServices(prev => prev.map(s => s.id === serviceId
194
+ ? { ...s, status: 'building', message: 'Starting...', progress: 0 }
195
+ : s));
176
196
  addLog(serviceId, 'Starting service...', 'info');
177
197
  let progress = 0;
178
198
  const progressInterval = setInterval(() => {
179
199
  progress += 10;
180
- setServices(prev => prev.map(s => s.id === serviceId ? { ...s, progress } : s));
200
+ setServices(prev => prev.map(s => (s.id === serviceId ? { ...s, progress } : s)));
181
201
  if (progress >= 100)
182
202
  clearInterval(progressInterval);
183
203
  }, 150);
@@ -199,19 +219,23 @@ export const UnifiedManager = () => {
199
219
  stdio: ['ignore', 'pipe', 'pipe'],
200
220
  });
201
221
  serviceProcesses.current.set(serviceId, proc);
202
- proc.stdout?.on('data', (data) => {
222
+ proc.stdout?.on('data', data => {
203
223
  const output = data.toString().trim();
204
224
  const portMatch = output.match(/localhost:(\d+)/) || output.match(/:(\d+)/);
205
225
  if (portMatch) {
206
226
  const port = parseInt(portMatch[1]);
207
- setServices(prev => prev.map(s => s.id === serviceId ? { ...s, status: 'running', port, message: 'Watching files...', progress: 100 } : s));
227
+ setServices(prev => prev.map(s => s.id === serviceId
228
+ ? { ...s, status: 'running', port, message: 'Watching files...', progress: 100 }
229
+ : s));
208
230
  addLog(serviceId, `Server running on port ${port}`, 'success');
209
231
  }
210
232
  });
211
- proc.stderr?.on('data', (data) => addLog(serviceId, data.toString().trim(), 'error'));
212
- proc.on('exit', (code) => {
233
+ proc.stderr?.on('data', data => addLog(serviceId, data.toString().trim(), 'error'));
234
+ proc.on('exit', code => {
213
235
  clearInterval(progressInterval);
214
- setServices(prev => prev.map(s => s.id === serviceId ? { ...s, status: code === 0 ? 'stopped' : 'error', progress: 0, message: 'Stopped' } : s));
236
+ setServices(prev => prev.map(s => s.id === serviceId
237
+ ? { ...s, status: code === 0 ? 'stopped' : 'error', progress: 0, message: 'Stopped' }
238
+ : s));
215
239
  serviceProcesses.current.delete(serviceId);
216
240
  addLog(serviceId, code === 0 ? 'Service stopped' : 'Service crashed', code === 0 ? 'info' : 'error');
217
241
  });
@@ -222,7 +246,9 @@ export const UnifiedManager = () => {
222
246
  proc.kill('SIGTERM');
223
247
  serviceProcesses.current.delete(serviceId);
224
248
  }
225
- setServices(prev => prev.map(s => s.id === serviceId ? { ...s, status: 'stopped', port: undefined, message: 'Stopped', progress: 0 } : s));
249
+ setServices(prev => prev.map(s => s.id === serviceId
250
+ ? { ...s, status: 'stopped', port: undefined, message: 'Stopped', progress: 0 }
251
+ : s));
226
252
  addLog(serviceId, 'Service stopped', 'info');
227
253
  }, [addLog]);
228
254
  const buildAll = useCallback(() => {
@@ -334,11 +360,13 @@ export const UnifiedManager = () => {
334
360
  }
335
361
  }
336
362
  });
337
- useEffect(() => { addLog('SYSTEM', 'Delta Unified Manager started', 'info'); }, []);
363
+ useEffect(() => {
364
+ addLog('SYSTEM', 'Delta Unified Manager started', 'info');
365
+ }, []);
338
366
  if (showHelp) {
339
367
  return (_jsx(Box, { flexDirection: "column", height: 28, justifyContent: "center", alignItems: "center", children: _jsx(HelpModal, { onClose: () => setShowHelp(false) }) }));
340
368
  }
341
- return (_jsxs(Box, { flexDirection: "column", height: 28, children: [_jsxs(Box, { justifyContent: "space-between", paddingX: 1, paddingY: 0, children: [_jsx(Text, { backgroundColor: "blue", bold: true, color: "white", children: " \uD83D\uDE80 Delta Project Manager " }), _jsx(Text, { backgroundColor: "blue", color: "white", children: " v2.0 " })] }), _jsxs(Box, { flexGrow: 1, children: [_jsx(Box, { flexDirection: "column", width: 30, borderStyle: "single", borderColor: "gray", paddingY: 1, children: MENU_ITEMS.map((item, index) => (_jsx(MenuItem, { item: item, isSelected: index === selectedIndex }, item.id))) }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, paddingX: 1, paddingY: 1, children: [_jsxs(Box, { flexDirection: "row", gap: 2, marginBottom: 1, children: [_jsx(ServiceCard, { service: services[0] }), _jsx(ServiceCard, { service: services[1] })] }), _jsxs(Box, { flexGrow: 1, flexDirection: "column", borderStyle: "round", borderColor: filterMode || searchMode ? 'cyan' : 'gray', paddingX: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "\uD83D\uDCCB Build & Test Logs" }), searchMode && _jsxs(Text, { color: "yellow", children: [" [Search: ", searchQuery, "_]"] }), filterMode && _jsx(Text, { color: "yellow", children: " [Filter Mode - s:severity r:source Enter:done]" })] }), _jsx(FilterBar, { severity: severityFilter, source: sourceFilter, isActive: filterMode }), _jsx(Box, { flexDirection: "column", overflow: "hidden", children: filteredLogs.length === 0 ? (_jsx(Text, { dimColor: true, children: logs.length === 0 ? 'No activity yet...' : 'No logs match current filters' })) : (filteredLogs.slice(-15).map((entry, i) => _jsx(LogEntry, { entry: entry }, i))) })] })] })] }), _jsxs(Box, { justifyContent: "space-between", paddingX: 1, paddingY: 0, children: [_jsxs(Box, { children: [_jsx(Text, { backgroundColor: "gray", color: "white", children: "[" }), _jsx(Text, { backgroundColor: "gray", color: "cyan", children: "\u2191\u2193" }), _jsx(Text, { backgroundColor: "gray", color: "white", children: "] Navigate " }), _jsx(Text, { backgroundColor: "gray", color: "white", children: "[" }), _jsx(Text, { backgroundColor: "gray", color: "cyan", children: "Enter" }), _jsx(Text, { backgroundColor: "gray", color: "white", children: "] Select " }), _jsx(Text, { backgroundColor: "gray", color: "white", children: "[" }), _jsx(Text, { backgroundColor: "gray", color: "cyan", children: "?" }), _jsx(Text, { backgroundColor: "gray", color: "white", children: "] Help " }), _jsx(Text, { backgroundColor: "gray", color: "white", children: "[" }), _jsx(Text, { backgroundColor: "gray", color: "cyan", children: "Q" }), _jsx(Text, { backgroundColor: "gray", color: "white", children: "] Quit" })] }), _jsxs(Box, { children: [_jsx(Text, { backgroundColor: "gray", color: "white", children: " CLI: " }), _jsx(Text, { backgroundColor: "gray", color: services[0].status === 'running' ? 'green' : 'gray', children: services[0].port ? `localhost:${services[0].port} ✓` : '○' }), _jsx(Text, { backgroundColor: "gray", color: "white", children: " | Web: " }), _jsx(Text, { backgroundColor: "gray", color: services[1].status === 'running' ? 'green' : 'gray', children: services[1].port ? `localhost:${services[1].port} ✓` : '○' }), _jsxs(Text, { backgroundColor: "gray", color: "white", children: [" | ", platform()] })] })] })] }));
369
+ return (_jsxs(Box, { flexDirection: "column", height: 28, children: [_jsxs(Box, { justifyContent: "space-between", paddingX: 1, paddingY: 0, children: [_jsxs(Text, { backgroundColor: "blue", bold: true, color: "white", children: [' ', "\uD83D\uDE80 Delta Project Manager", ' '] }), _jsxs(Text, { backgroundColor: "blue", color: "white", children: [' ', "v2.0", ' '] })] }), _jsxs(Box, { flexGrow: 1, children: [_jsx(Box, { flexDirection: "column", width: 30, borderStyle: "single", borderColor: "gray", paddingY: 1, children: MENU_ITEMS.map((item, index) => (_jsx(MenuItem, { item: item, isSelected: index === selectedIndex }, item.id))) }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, paddingX: 1, paddingY: 1, children: [_jsxs(Box, { flexDirection: "row", gap: 2, marginBottom: 1, children: [_jsx(ServiceCard, { service: services[0] }), _jsx(ServiceCard, { service: services[1] })] }), _jsxs(Box, { flexGrow: 1, flexDirection: "column", borderStyle: "round", borderColor: filterMode || searchMode ? 'cyan' : 'gray', paddingX: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "\uD83D\uDCCB Build & Test Logs" }), searchMode && _jsxs(Text, { color: "yellow", children: [" [Search: ", searchQuery, "_]"] }), filterMode && (_jsx(Text, { color: "yellow", children: " [Filter Mode - s:severity r:source Enter:done]" }))] }), _jsx(FilterBar, { severity: severityFilter, source: sourceFilter, isActive: filterMode }), _jsx(Box, { flexDirection: "column", overflow: "hidden", children: filteredLogs.length === 0 ? (_jsx(Text, { dimColor: true, children: logs.length === 0 ? 'No activity yet...' : 'No logs match current filters' })) : (filteredLogs.slice(-15).map((entry, i) => _jsx(LogEntry, { entry: entry }, i))) })] })] })] }), _jsxs(Box, { justifyContent: "space-between", paddingX: 1, paddingY: 0, children: [_jsxs(Box, { children: [_jsx(Text, { backgroundColor: "gray", color: "white", children: "[" }), _jsx(Text, { backgroundColor: "gray", color: "cyan", children: "\u2191\u2193" }), _jsxs(Text, { backgroundColor: "gray", color: "white", children: ["] Navigate", ' '] }), _jsx(Text, { backgroundColor: "gray", color: "white", children: "[" }), _jsx(Text, { backgroundColor: "gray", color: "cyan", children: "Enter" }), _jsxs(Text, { backgroundColor: "gray", color: "white", children: ["] Select", ' '] }), _jsx(Text, { backgroundColor: "gray", color: "white", children: "[" }), _jsx(Text, { backgroundColor: "gray", color: "cyan", children: "?" }), _jsxs(Text, { backgroundColor: "gray", color: "white", children: ["] Help", ' '] }), _jsx(Text, { backgroundColor: "gray", color: "white", children: "[" }), _jsx(Text, { backgroundColor: "gray", color: "cyan", children: "Q" }), _jsx(Text, { backgroundColor: "gray", color: "white", children: "] Quit" })] }), _jsxs(Box, { children: [_jsxs(Text, { backgroundColor: "gray", color: "white", children: [' ', "CLI:", ' '] }), _jsx(Text, { backgroundColor: "gray", color: services[0].status === 'running' ? 'green' : 'gray', children: services[0].port ? `localhost:${services[0].port} ✓` : '○' }), _jsxs(Text, { backgroundColor: "gray", color: "white", children: [' ', "| Web:", ' '] }), _jsx(Text, { backgroundColor: "gray", color: services[1].status === 'running' ? 'green' : 'gray', children: services[1].port ? `localhost:${services[1].port} ✓` : '○' }), _jsxs(Text, { backgroundColor: "gray", color: "white", children: [' ', "| ", platform()] })] })] })] }));
342
370
  };
343
371
  export default UnifiedManager;
344
372
  //# sourceMappingURL=UnifiedManager.js.map
@@ -21,7 +21,11 @@ export const completionDatabase = {
21
21
  globalFlags: [
22
22
  { name: '--json', desc: 'Output as JSON' },
23
23
  { name: '--provider', values: ['local', 'remote', 'ai'], desc: 'Execution provider' },
24
- { name: '--theme', values: ['delta', 'cyber', 'sunset', 'neon', 'ocean', 'fire'], desc: 'Color theme' },
24
+ {
25
+ name: '--theme',
26
+ values: ['delta', 'cyber', 'sunset', 'neon', 'ocean', 'fire'],
27
+ desc: 'Color theme',
28
+ },
25
29
  { name: '--verbose', desc: 'Verbose logging' },
26
30
  { name: '--no-color', desc: 'Disable colors' },
27
31
  { name: '--interactive', alias: '-i', desc: 'Interactive mode' },
@@ -43,7 +47,11 @@ export const completionDatabase = {
43
47
  { name: '--performance', desc: 'Performance analysis' },
44
48
  ],
45
49
  init: [
46
- { name: '--template', values: ['default', 'nextjs', 'react', 'node', 'python'], desc: 'Project template' },
50
+ {
51
+ name: '--template',
52
+ values: ['default', 'nextjs', 'react', 'node', 'python'],
53
+ desc: 'Project template',
54
+ },
47
55
  { name: '--force', alias: '-f', desc: 'Overwrite existing' },
48
56
  { name: '--git', desc: 'Initialize git' },
49
57
  ],
@@ -81,7 +89,10 @@ export function generateCompletionScript(shell) {
81
89
  }
82
90
  function generateBashCompletion(cliName) {
83
91
  const commands = completionDatabase.commands.map(c => c.name).join(' ');
84
- const slashCommands = completionDatabase.commands.flatMap(c => c.alias).filter(a => a.startsWith('/')).join(' ');
92
+ const slashCommands = completionDatabase.commands
93
+ .flatMap(c => c.alias)
94
+ .filter(a => a.startsWith('/'))
95
+ .join(' ');
85
96
  return `#!/bin/bash
86
97
  # Delta CLI Bash Completion
87
98
  # Source this file: source <(delta completion bash)