@hyperdrive.bot/gut 0.1.4 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +1 -779
  2. package/bin/run.js +5 -0
  3. package/package.json +10 -10
  4. package/bin/run +0 -5
  5. package/dist/base-command.d.ts +0 -21
  6. package/dist/base-command.js +0 -110
  7. package/dist/commands/add.d.ts +0 -13
  8. package/dist/commands/add.js +0 -73
  9. package/dist/commands/affected.d.ts +0 -23
  10. package/dist/commands/affected.js +0 -326
  11. package/dist/commands/audit.d.ts +0 -33
  12. package/dist/commands/audit.js +0 -593
  13. package/dist/commands/back.d.ts +0 -6
  14. package/dist/commands/back.js +0 -29
  15. package/dist/commands/commit.d.ts +0 -11
  16. package/dist/commands/commit.js +0 -113
  17. package/dist/commands/context.d.ts +0 -6
  18. package/dist/commands/context.js +0 -36
  19. package/dist/commands/contexts.d.ts +0 -7
  20. package/dist/commands/contexts.js +0 -92
  21. package/dist/commands/deps.d.ts +0 -10
  22. package/dist/commands/deps.js +0 -104
  23. package/dist/commands/entity/add.d.ts +0 -16
  24. package/dist/commands/entity/add.js +0 -105
  25. package/dist/commands/entity/clone-all.d.ts +0 -17
  26. package/dist/commands/entity/clone-all.js +0 -135
  27. package/dist/commands/entity/clone.d.ts +0 -15
  28. package/dist/commands/entity/clone.js +0 -109
  29. package/dist/commands/entity/list.d.ts +0 -11
  30. package/dist/commands/entity/list.js +0 -82
  31. package/dist/commands/entity/remove.d.ts +0 -12
  32. package/dist/commands/entity/remove.js +0 -58
  33. package/dist/commands/focus.d.ts +0 -19
  34. package/dist/commands/focus.js +0 -139
  35. package/dist/commands/graph.d.ts +0 -18
  36. package/dist/commands/graph.js +0 -238
  37. package/dist/commands/init.d.ts +0 -11
  38. package/dist/commands/init.js +0 -84
  39. package/dist/commands/insights.d.ts +0 -21
  40. package/dist/commands/insights.js +0 -434
  41. package/dist/commands/patterns.d.ts +0 -40
  42. package/dist/commands/patterns.js +0 -412
  43. package/dist/commands/pull.d.ts +0 -11
  44. package/dist/commands/pull.js +0 -121
  45. package/dist/commands/push.d.ts +0 -11
  46. package/dist/commands/push.js +0 -101
  47. package/dist/commands/quick-setup.d.ts +0 -20
  48. package/dist/commands/quick-setup.js +0 -422
  49. package/dist/commands/recent.d.ts +0 -9
  50. package/dist/commands/recent.js +0 -55
  51. package/dist/commands/related.d.ts +0 -23
  52. package/dist/commands/related.js +0 -257
  53. package/dist/commands/repos.d.ts +0 -14
  54. package/dist/commands/repos.js +0 -185
  55. package/dist/commands/stack.d.ts +0 -10
  56. package/dist/commands/stack.js +0 -83
  57. package/dist/commands/status.d.ts +0 -14
  58. package/dist/commands/status.js +0 -246
  59. package/dist/commands/sync.d.ts +0 -11
  60. package/dist/commands/sync.js +0 -142
  61. package/dist/commands/unfocus.d.ts +0 -6
  62. package/dist/commands/unfocus.js +0 -23
  63. package/dist/commands/used-by.d.ts +0 -10
  64. package/dist/commands/used-by.js +0 -111
  65. package/dist/commands/workspace.d.ts +0 -20
  66. package/dist/commands/workspace.js +0 -365
  67. package/dist/index.d.ts +0 -1
  68. package/dist/index.js +0 -5
  69. package/dist/models/entity.model.d.ts +0 -81
  70. package/dist/models/entity.model.js +0 -2
  71. package/dist/services/config.service.d.ts +0 -34
  72. package/dist/services/config.service.js +0 -230
  73. package/dist/services/entity.service.d.ts +0 -19
  74. package/dist/services/entity.service.js +0 -130
  75. package/dist/services/focus.service.d.ts +0 -70
  76. package/dist/services/focus.service.js +0 -587
  77. package/dist/services/git.service.d.ts +0 -37
  78. package/dist/services/git.service.js +0 -180
  79. package/dist/utils/display.d.ts +0 -25
  80. package/dist/utils/display.js +0 -150
  81. package/dist/utils/filesystem.d.ts +0 -32
  82. package/dist/utils/filesystem.js +0 -220
  83. package/dist/utils/index.d.ts +0 -13
  84. package/dist/utils/index.js +0 -18
  85. package/dist/utils/validation.d.ts +0 -22
  86. package/dist/utils/validation.js +0 -196
  87. package/oclif.manifest.json +0 -1463
@@ -1,593 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const core_1 = require("@oclif/core");
5
- const base_command_1 = require("../base-command");
6
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
- const fs = tslib_1.__importStar(require("fs"));
8
- const path = tslib_1.__importStar(require("path"));
9
- class Audit extends base_command_1.BaseCommand {
10
- static description = 'Access and change audit across workspace';
11
- static examples = [
12
- '<%= config.bin %> <%= command.id %>',
13
- '<%= config.bin %> <%= command.id %> --entity mindtools',
14
- '<%= config.bin %> <%= command.id %> --security',
15
- '<%= config.bin %> <%= command.id %> --compliance',
16
- ];
17
- static flags = {
18
- entity: core_1.Flags.string({
19
- char: 'e',
20
- description: 'audit specific entity',
21
- }),
22
- security: core_1.Flags.boolean({
23
- char: 's',
24
- description: 'focus on security audit',
25
- default: false,
26
- }),
27
- compliance: core_1.Flags.boolean({
28
- char: 'c',
29
- description: 'focus on compliance audit',
30
- default: false,
31
- }),
32
- access: core_1.Flags.boolean({
33
- char: 'a',
34
- description: 'audit access patterns and permissions',
35
- default: false,
36
- }),
37
- changes: core_1.Flags.boolean({
38
- description: 'audit recent changes and activity',
39
- default: false,
40
- }),
41
- json: core_1.Flags.boolean({
42
- description: 'output as JSON',
43
- default: false,
44
- }),
45
- };
46
- async run() {
47
- const { flags } = await this.parse(Audit);
48
- let entities = [];
49
- if (flags.entity) {
50
- const entity = this.entityService.findEntity(flags.entity);
51
- if (!entity) {
52
- this.error(`Entity '${flags.entity}' not found`);
53
- }
54
- entities = [entity];
55
- }
56
- else {
57
- entities = this.entityService.getAllEntities();
58
- }
59
- if (entities.length === 0) {
60
- this.error('No entities found to audit');
61
- }
62
- const auditResults = await this.performAudit(entities, flags);
63
- if (flags.json) {
64
- this.log(JSON.stringify(auditResults, null, 2));
65
- return;
66
- }
67
- this.displayAuditResults(auditResults, flags);
68
- }
69
- async performAudit(entities, flags) {
70
- const results = {
71
- timestamp: new Date().toISOString(),
72
- scope: {
73
- entities: entities.map(e => e.name),
74
- audit_types: this.getAuditTypes(flags)
75
- },
76
- findings: [],
77
- summary: {
78
- total_entities: entities.length,
79
- issues_found: 0,
80
- security_issues: 0,
81
- compliance_issues: 0,
82
- access_issues: 0
83
- }
84
- };
85
- for (const entity of entities) {
86
- const entityAudit = await this.auditEntity(entity, flags);
87
- results.findings.push(entityAudit);
88
- // Update summary
89
- results.summary.issues_found += entityAudit.issues.length;
90
- results.summary.security_issues += entityAudit.security_issues.length;
91
- results.summary.compliance_issues += entityAudit.compliance_issues.length;
92
- results.summary.access_issues += entityAudit.access_issues.length;
93
- }
94
- return results;
95
- }
96
- async auditEntity(entity, flags) {
97
- const entityPath = this.entityService.resolveEntityPath(entity);
98
- const audit = {
99
- entity: entity.name,
100
- type: entity.type,
101
- path: entity.path,
102
- timestamp: new Date().toISOString(),
103
- exists: fs.existsSync(entityPath),
104
- issues: [],
105
- security_issues: [],
106
- compliance_issues: [],
107
- access_issues: [],
108
- metadata_audit: {},
109
- git_audit: {},
110
- file_audit: {}
111
- };
112
- if (!audit.exists) {
113
- audit.issues.push({
114
- type: 'missing_entity',
115
- severity: 'high',
116
- message: 'Entity path does not exist',
117
- path: entityPath
118
- });
119
- return audit;
120
- }
121
- // Metadata audit
122
- audit.metadata_audit = await this.auditMetadata(entity);
123
- // Git audit
124
- if (await this.gitService.isRepository(entityPath)) {
125
- audit.git_audit = await this.auditGitRepository(entityPath);
126
- }
127
- // File structure audit
128
- audit.file_audit = await this.auditFileStructure(entityPath, entity.type);
129
- // Security audit
130
- if (flags.security || !this.hasSpecificAuditType(flags)) {
131
- audit.security_issues = await this.performSecurityAudit(entityPath, entity);
132
- }
133
- // Compliance audit
134
- if (flags.compliance || !this.hasSpecificAuditType(flags)) {
135
- audit.compliance_issues = await this.performComplianceAudit(entity);
136
- }
137
- // Access audit
138
- if (flags.access || !this.hasSpecificAuditType(flags)) {
139
- audit.access_issues = await this.performAccessAudit(entity);
140
- }
141
- return audit;
142
- }
143
- async auditMetadata(entity) {
144
- const issues = [];
145
- const metadata = entity.metadata || {};
146
- // Check required metadata fields
147
- if (entity.type === 'client') {
148
- if (!metadata.business?.primary_contact) {
149
- issues.push({
150
- type: 'missing_metadata',
151
- field: 'business.primary_contact',
152
- severity: 'medium',
153
- message: 'Client entity missing primary contact information'
154
- });
155
- }
156
- if (!metadata.business?.contract_value) {
157
- issues.push({
158
- type: 'missing_metadata',
159
- field: 'business.contract_value',
160
- severity: 'low',
161
- message: 'Client entity missing contract value'
162
- });
163
- }
164
- }
165
- // Check metadata file existence
166
- const entityPath = this.entityService.resolveEntityPath(entity);
167
- const metadataPath = path.join(entityPath, '.entity.yaml');
168
- return {
169
- has_metadata_file: fs.existsSync(metadataPath),
170
- metadata_completeness: this.calculateMetadataCompleteness(metadata, entity.type),
171
- issues: issues
172
- };
173
- }
174
- async auditGitRepository(repoPath) {
175
- const audit = {
176
- is_git_repo: true,
177
- issues: []
178
- };
179
- try {
180
- // Check git status
181
- const status = await this.gitService.getStatus(repoPath);
182
- audit.status = status;
183
- // Check for uncommitted changes
184
- if (status.hasChanges) {
185
- audit.issues.push({
186
- type: 'uncommitted_changes',
187
- severity: 'low',
188
- message: `Repository has ${status.changes.length} uncommitted changes`
189
- });
190
- }
191
- // Check remote configuration
192
- try {
193
- const remotes = await this.gitService.exec(['remote', '-v'], { cwd: repoPath });
194
- audit.has_remote = remotes.length > 0;
195
- if (!audit.has_remote) {
196
- audit.issues.push({
197
- type: 'no_remote',
198
- severity: 'medium',
199
- message: 'Repository has no remote configured'
200
- });
201
- }
202
- }
203
- catch {
204
- audit.has_remote = false;
205
- }
206
- // Check branch information
207
- try {
208
- const branch = await this.gitService.exec(['branch', '--show-current'], { cwd: repoPath });
209
- audit.current_branch = branch.trim();
210
- if (audit.current_branch === 'master' || audit.current_branch === 'main') {
211
- // Check if working directly on main branch
212
- if (status.hasChanges) {
213
- audit.issues.push({
214
- type: 'working_on_main',
215
- severity: 'medium',
216
- message: 'Working directly on main/master branch with uncommitted changes'
217
- });
218
- }
219
- }
220
- }
221
- catch {
222
- // Ignore branch check errors
223
- }
224
- }
225
- catch (error) {
226
- audit.issues.push({
227
- type: 'git_error',
228
- severity: 'high',
229
- message: `Git audit failed: ${error.message}`
230
- });
231
- }
232
- return audit;
233
- }
234
- async auditFileStructure(entityPath, entityType) {
235
- const audit = {
236
- structure_score: 0,
237
- issues: [],
238
- recommendations: []
239
- };
240
- try {
241
- const files = fs.readdirSync(entityPath);
242
- // Check for common files based on entity type
243
- const expectedFiles = this.getExpectedFiles(entityType);
244
- for (const expectedFile of expectedFiles) {
245
- if (!files.includes(expectedFile.name)) {
246
- audit.issues.push({
247
- type: 'missing_file',
248
- severity: expectedFile.required ? 'medium' : 'low',
249
- message: `Missing ${expectedFile.description}: ${expectedFile.name}`
250
- });
251
- }
252
- }
253
- // Check for documentation
254
- const hasReadme = files.some(f => f.toLowerCase().startsWith('readme'));
255
- if (!hasReadme) {
256
- audit.recommendations.push('Add README.md file for documentation');
257
- }
258
- // Check for configuration files
259
- const hasConfig = files.some(f => f.includes('config') || f.includes('.env'));
260
- audit.has_configuration = hasConfig;
261
- audit.structure_score = this.calculateStructureScore(files, expectedFiles);
262
- }
263
- catch (error) {
264
- audit.issues.push({
265
- type: 'file_audit_error',
266
- severity: 'high',
267
- message: `File structure audit failed: ${error.message}`
268
- });
269
- }
270
- return audit;
271
- }
272
- async performSecurityAudit(entityPath, entity) {
273
- const issues = [];
274
- // Check for sensitive files
275
- const sensitivePatterns = [
276
- '.env',
277
- 'secrets',
278
- 'private',
279
- 'credentials',
280
- 'password',
281
- 'key',
282
- 'token'
283
- ];
284
- try {
285
- const files = this.getAllFiles(entityPath);
286
- for (const file of files) {
287
- const fileName = path.basename(file).toLowerCase();
288
- for (const pattern of sensitivePatterns) {
289
- if (fileName.includes(pattern)) {
290
- issues.push({
291
- type: 'sensitive_file',
292
- severity: 'high',
293
- message: `Potentially sensitive file found: ${file}`,
294
- file: file
295
- });
296
- }
297
- }
298
- }
299
- // Check for .gitignore
300
- const gitignorePath = path.join(entityPath, '.gitignore');
301
- if (!fs.existsSync(gitignorePath)) {
302
- issues.push({
303
- type: 'missing_gitignore',
304
- severity: 'medium',
305
- message: 'No .gitignore file found'
306
- });
307
- }
308
- }
309
- catch (error) {
310
- issues.push({
311
- type: 'security_audit_error',
312
- severity: 'high',
313
- message: `Security audit failed: ${error.message}`
314
- });
315
- }
316
- return issues;
317
- }
318
- async performComplianceAudit(entity) {
319
- const issues = [];
320
- const metadata = entity.metadata || {};
321
- // Check business compliance for client entities
322
- if (entity.type === 'client') {
323
- if (!metadata.business?.status) {
324
- issues.push({
325
- type: 'missing_business_status',
326
- severity: 'medium',
327
- message: 'Client entity missing business status'
328
- });
329
- }
330
- // Check for required documentation
331
- const entityPath = this.entityService.resolveEntityPath(entity);
332
- const requiredDocs = ['README.md', '.entity.yaml'];
333
- for (const doc of requiredDocs) {
334
- const docPath = path.join(entityPath, doc);
335
- if (!fs.existsSync(docPath)) {
336
- issues.push({
337
- type: 'missing_documentation',
338
- severity: 'medium',
339
- message: `Required documentation missing: ${doc}`
340
- });
341
- }
342
- }
343
- }
344
- // Check metadata completeness
345
- const completeness = this.calculateMetadataCompleteness(metadata, entity.type);
346
- if (completeness < 0.7) {
347
- issues.push({
348
- type: 'incomplete_metadata',
349
- severity: 'low',
350
- message: `Entity metadata only ${Math.round(completeness * 100)}% complete`
351
- });
352
- }
353
- return issues;
354
- }
355
- async performAccessAudit(entity) {
356
- const issues = [];
357
- // Check path accessibility
358
- const entityPath = this.entityService.resolveEntityPath(entity);
359
- try {
360
- const stats = fs.statSync(entityPath);
361
- // Check if path is accessible
362
- if (!stats.isDirectory()) {
363
- issues.push({
364
- type: 'invalid_path',
365
- severity: 'high',
366
- message: 'Entity path is not a directory'
367
- });
368
- }
369
- // Check permissions (basic check)
370
- try {
371
- fs.accessSync(entityPath, fs.constants.R_OK | fs.constants.W_OK);
372
- }
373
- catch {
374
- issues.push({
375
- type: 'permission_issue',
376
- severity: 'high',
377
- message: 'Insufficient permissions for entity path'
378
- });
379
- }
380
- }
381
- catch (error) {
382
- issues.push({
383
- type: 'access_error',
384
- severity: 'high',
385
- message: `Cannot access entity path: ${error.message}`
386
- });
387
- }
388
- // Check for private/business separation
389
- if (entity.type === 'client') {
390
- const hasPrivate = entity.path.includes('private') || entity.path.includes('business');
391
- const metadata = entity.metadata || {};
392
- if (metadata.business && !hasPrivate) {
393
- issues.push({
394
- type: 'missing_private_separation',
395
- severity: 'medium',
396
- message: 'Client entity with business data should have private/business separation'
397
- });
398
- }
399
- }
400
- return issues;
401
- }
402
- displayAuditResults(results, flags) {
403
- this.log(chalk_1.default.bold('\n🔍 Workspace Audit Report'));
404
- this.log(chalk_1.default.dim('─'.repeat(50)));
405
- this.log(`📅 Generated: ${new Date(results.timestamp).toLocaleString()}`);
406
- this.log(`📊 Scope: ${results.scope.entities.length} entities`);
407
- this.log(`🎯 Audit Types: ${results.scope.audit_types.join(', ')}`);
408
- this.log('');
409
- // Summary
410
- this.log(chalk_1.default.bold('📋 Summary:'));
411
- const summary = results.summary;
412
- if (summary.issues_found === 0) {
413
- this.log(chalk_1.default.green('✅ No issues found'));
414
- }
415
- else {
416
- this.log(`⚠️ Total Issues: ${chalk_1.default.yellow(summary.issues_found)}`);
417
- if (summary.security_issues > 0) {
418
- this.log(`🔒 Security Issues: ${chalk_1.default.red(summary.security_issues)}`);
419
- }
420
- if (summary.compliance_issues > 0) {
421
- this.log(`📋 Compliance Issues: ${chalk_1.default.yellow(summary.compliance_issues)}`);
422
- }
423
- if (summary.access_issues > 0) {
424
- this.log(`🔐 Access Issues: ${chalk_1.default.red(summary.access_issues)}`);
425
- }
426
- }
427
- this.log('');
428
- // Detailed findings
429
- for (const finding of results.findings) {
430
- this.displayEntityAudit(finding);
431
- }
432
- // Recommendations
433
- this.displayRecommendations(results);
434
- }
435
- displayEntityAudit(audit) {
436
- const emoji = this.getTypeEmoji(audit.type);
437
- const issueCount = audit.issues.length + audit.security_issues.length +
438
- audit.compliance_issues.length + audit.access_issues.length;
439
- const statusIcon = issueCount === 0 ? chalk_1.default.green('✅') :
440
- issueCount < 3 ? chalk_1.default.yellow('⚠️') : chalk_1.default.red('❌');
441
- this.log(`${emoji} ${chalk_1.default.bold(audit.entity)} ${statusIcon}`);
442
- if (!audit.exists) {
443
- this.log(` ${chalk_1.default.red('❌ Entity path does not exist')}`);
444
- return;
445
- }
446
- // Show critical issues
447
- const criticalIssues = [
448
- ...audit.issues,
449
- ...audit.security_issues,
450
- ...audit.compliance_issues,
451
- ...audit.access_issues
452
- ].filter(issue => issue.severity === 'high');
453
- if (criticalIssues.length > 0) {
454
- this.log(` ${chalk_1.default.red('🚨 Critical Issues:')}`);
455
- criticalIssues.forEach(issue => {
456
- this.log(` • ${issue.message}`);
457
- });
458
- }
459
- // Show metadata completeness
460
- if (audit.metadata_audit?.metadata_completeness !== undefined) {
461
- const completeness = Math.round(audit.metadata_audit.metadata_completeness * 100);
462
- const color = completeness >= 80 ? chalk_1.default.green : completeness >= 60 ? chalk_1.default.yellow : chalk_1.default.red;
463
- this.log(` 📊 Metadata: ${color(`${completeness}% complete`)}`);
464
- }
465
- // Show git status
466
- if (audit.git_audit?.is_git_repo) {
467
- const gitStatus = audit.git_audit.status?.hasChanges ?
468
- chalk_1.default.yellow('uncommitted changes') : chalk_1.default.green('clean');
469
- this.log(` 📁 Git: ${gitStatus}`);
470
- }
471
- this.log('');
472
- }
473
- displayRecommendations(results) {
474
- const allRecommendations = [];
475
- // Collect recommendations from all findings
476
- for (const finding of results.findings) {
477
- if (finding.file_audit?.recommendations) {
478
- allRecommendations.push(...finding.file_audit.recommendations);
479
- }
480
- }
481
- if (allRecommendations.length > 0) {
482
- this.log(chalk_1.default.bold('💡 Recommendations:'));
483
- const uniqueRecommendations = [...new Set(allRecommendations)];
484
- uniqueRecommendations.forEach(rec => {
485
- this.log(` • ${rec}`);
486
- });
487
- }
488
- }
489
- // Helper methods
490
- getAuditTypes(flags) {
491
- const types = [];
492
- if (flags.security)
493
- types.push('security');
494
- if (flags.compliance)
495
- types.push('compliance');
496
- if (flags.access)
497
- types.push('access');
498
- if (flags.changes)
499
- types.push('changes');
500
- if (types.length === 0)
501
- types.push('general');
502
- return types;
503
- }
504
- hasSpecificAuditType(flags) {
505
- return flags.security || flags.compliance || flags.access || flags.changes;
506
- }
507
- calculateMetadataCompleteness(metadata, entityType) {
508
- const requiredFields = this.getRequiredMetadataFields(entityType);
509
- let completedFields = 0;
510
- for (const field of requiredFields) {
511
- if (this.hasNestedField(metadata, field)) {
512
- completedFields++;
513
- }
514
- }
515
- return requiredFields.length > 0 ? completedFields / requiredFields.length : 1;
516
- }
517
- getRequiredMetadataFields(entityType) {
518
- const fields = {
519
- client: ['business.primary_contact', 'business.status', 'relationships.dependent_systems'],
520
- prospect: ['business.status', 'relationships.similar_entities'],
521
- company: ['business.status'],
522
- initiative: ['relationships.related_initiatives'],
523
- system: ['relationships.dependent_systems']
524
- };
525
- return fields[entityType] || [];
526
- }
527
- hasNestedField(obj, fieldPath) {
528
- const parts = fieldPath.split('.');
529
- let current = obj;
530
- for (const part of parts) {
531
- if (!current || typeof current !== 'object' || !(part in current)) {
532
- return false;
533
- }
534
- current = current[part];
535
- }
536
- return current !== undefined && current !== null && current !== '';
537
- }
538
- getExpectedFiles(entityType) {
539
- const common = [
540
- { name: '.entity.yaml', required: true, description: 'Entity metadata' },
541
- { name: 'README.md', required: false, description: 'Documentation' }
542
- ];
543
- const typeSpecific = {
544
- client: [
545
- { name: 'package.json', required: false, description: 'Project configuration' },
546
- { name: '.gitignore', required: true, description: 'Git ignore rules' }
547
- ],
548
- system: [
549
- { name: 'package.json', required: true, description: 'Project configuration' },
550
- { name: '.gitignore', required: true, description: 'Git ignore rules' }
551
- ]
552
- };
553
- return [...common, ...(typeSpecific[entityType] || [])];
554
- }
555
- calculateStructureScore(files, expectedFiles) {
556
- let score = 0;
557
- const totalExpected = expectedFiles.length;
558
- for (const expected of expectedFiles) {
559
- if (files.includes(expected.name)) {
560
- score += expected.required ? 2 : 1;
561
- }
562
- }
563
- return totalExpected > 0 ? score / (totalExpected * 2) : 1;
564
- }
565
- getAllFiles(dirPath, maxDepth = 2) {
566
- const files = [];
567
- const traverse = (currentPath, depth) => {
568
- if (depth > maxDepth)
569
- return;
570
- try {
571
- const items = fs.readdirSync(currentPath);
572
- for (const item of items) {
573
- if (item.startsWith('.') && item !== '.entity.yaml')
574
- continue;
575
- const itemPath = path.join(currentPath, item);
576
- const stats = fs.statSync(itemPath);
577
- if (stats.isFile()) {
578
- files.push(path.relative(dirPath, itemPath));
579
- }
580
- else if (stats.isDirectory()) {
581
- traverse(itemPath, depth + 1);
582
- }
583
- }
584
- }
585
- catch {
586
- // Ignore permission errors
587
- }
588
- };
589
- traverse(dirPath, 0);
590
- return files;
591
- }
592
- }
593
- exports.default = Audit;
@@ -1,6 +0,0 @@
1
- import { BaseCommand } from '../base-command';
2
- export default class Back extends BaseCommand {
3
- static description: string;
4
- static examples: string[];
5
- run(): Promise<void>;
6
- }
@@ -1,29 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const base_command_1 = require("../base-command");
5
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
- class Back extends base_command_1.BaseCommand {
7
- static description = 'Navigate back to the previous focus';
8
- static examples = [
9
- '<%= config.bin %> <%= command.id %>',
10
- ];
11
- async run() {
12
- await this.parse(Back);
13
- const focusedEntities = await this.focusService.getFocusedEntities();
14
- const history = await this.configService.getHistory();
15
- if (history.length < 2) {
16
- this.log(chalk_1.default.yellow('No previous focus available'));
17
- this.log(chalk_1.default.dim('Focus history is empty or has only the current focus'));
18
- return;
19
- }
20
- const previousEntry = history[1];
21
- const currentEntities = focusedEntities.map(e => e.name).join(', ') || 'none';
22
- const previousEntities = previousEntry.entities.join(', ');
23
- await this.focusService.switchToPrevious();
24
- this.log(chalk_1.default.green('✓ Switched to previous focus'));
25
- this.log(chalk_1.default.dim(` From: ${currentEntities}`));
26
- this.log(chalk_1.default.dim(` To: ${previousEntities}`));
27
- }
28
- }
29
- exports.default = Back;
@@ -1,11 +0,0 @@
1
- import { BaseCommand } from '../base-command';
2
- export default class Commit extends BaseCommand {
3
- static description: string;
4
- static examples: string[];
5
- static flags: {
6
- message: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
7
- all: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
- amend: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
- };
10
- run(): Promise<void>;
11
- }