@hyperdrive.bot/gut 0.1.8 → 0.1.10

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 (111) hide show
  1. package/README.md +1048 -1
  2. package/dist/base-command.d.ts +22 -0
  3. package/dist/base-command.js +99 -0
  4. package/dist/commands/add.d.ts +14 -0
  5. package/dist/commands/add.js +70 -0
  6. package/dist/commands/affected.d.ts +23 -0
  7. package/dist/commands/affected.js +323 -0
  8. package/dist/commands/audit.d.ts +33 -0
  9. package/dist/commands/audit.js +594 -0
  10. package/dist/commands/back.d.ts +6 -0
  11. package/dist/commands/back.js +29 -0
  12. package/dist/commands/checkout.d.ts +14 -0
  13. package/dist/commands/checkout.js +124 -0
  14. package/dist/commands/commit.d.ts +11 -0
  15. package/dist/commands/commit.js +107 -0
  16. package/dist/commands/context.d.ts +6 -0
  17. package/dist/commands/context.js +32 -0
  18. package/dist/commands/contexts.d.ts +7 -0
  19. package/dist/commands/contexts.js +88 -0
  20. package/dist/commands/deps.d.ts +10 -0
  21. package/dist/commands/deps.js +100 -0
  22. package/dist/commands/entity/add.d.ts +16 -0
  23. package/dist/commands/entity/add.js +103 -0
  24. package/dist/commands/entity/clone-all.d.ts +18 -0
  25. package/dist/commands/entity/clone-all.js +166 -0
  26. package/dist/commands/entity/clone.d.ts +17 -0
  27. package/dist/commands/entity/clone.js +132 -0
  28. package/dist/commands/entity/list.d.ts +11 -0
  29. package/dist/commands/entity/list.js +80 -0
  30. package/dist/commands/entity/remove.d.ts +12 -0
  31. package/dist/commands/entity/remove.js +54 -0
  32. package/dist/commands/extract.d.ts +35 -0
  33. package/dist/commands/extract.js +483 -0
  34. package/dist/commands/focus.d.ts +19 -0
  35. package/dist/commands/focus.js +137 -0
  36. package/dist/commands/graph.d.ts +18 -0
  37. package/dist/commands/graph.js +273 -0
  38. package/dist/commands/init.d.ts +11 -0
  39. package/dist/commands/init.js +75 -0
  40. package/dist/commands/insights.d.ts +21 -0
  41. package/dist/commands/insights.js +465 -0
  42. package/dist/commands/patterns.d.ts +40 -0
  43. package/dist/commands/patterns.js +405 -0
  44. package/dist/commands/pull.d.ts +11 -0
  45. package/dist/commands/pull.js +121 -0
  46. package/dist/commands/push.d.ts +11 -0
  47. package/dist/commands/push.js +97 -0
  48. package/dist/commands/quick-setup.d.ts +20 -0
  49. package/dist/commands/quick-setup.js +417 -0
  50. package/dist/commands/recent.d.ts +9 -0
  51. package/dist/commands/recent.js +51 -0
  52. package/dist/commands/related.d.ts +23 -0
  53. package/dist/commands/related.js +255 -0
  54. package/dist/commands/repos.d.ts +17 -0
  55. package/dist/commands/repos.js +184 -0
  56. package/dist/commands/stack.d.ts +10 -0
  57. package/dist/commands/stack.js +78 -0
  58. package/dist/commands/status.d.ts +13 -0
  59. package/dist/commands/status.js +193 -0
  60. package/dist/commands/sync.d.ts +11 -0
  61. package/dist/commands/sync.js +139 -0
  62. package/dist/commands/ticket/focus.d.ts +20 -0
  63. package/dist/commands/ticket/focus.js +217 -0
  64. package/dist/commands/ticket/get.d.ts +15 -0
  65. package/dist/commands/ticket/get.js +168 -0
  66. package/dist/commands/ticket/hint.d.ts +16 -0
  67. package/dist/commands/ticket/hint.js +147 -0
  68. package/dist/commands/ticket/index.d.ts +10 -0
  69. package/dist/commands/ticket/index.js +60 -0
  70. package/dist/commands/ticket/list.d.ts +13 -0
  71. package/dist/commands/ticket/list.js +120 -0
  72. package/dist/commands/ticket/sync.d.ts +14 -0
  73. package/dist/commands/ticket/sync.js +85 -0
  74. package/dist/commands/ticket/update.d.ts +17 -0
  75. package/dist/commands/ticket/update.js +142 -0
  76. package/dist/commands/unfocus.d.ts +6 -0
  77. package/dist/commands/unfocus.js +19 -0
  78. package/dist/commands/used-by.d.ts +13 -0
  79. package/dist/commands/used-by.js +110 -0
  80. package/dist/commands/workspace.d.ts +22 -0
  81. package/dist/commands/workspace.js +372 -0
  82. package/dist/index.d.ts +14 -0
  83. package/dist/index.js +16 -0
  84. package/dist/models/entity.model.d.ts +234 -0
  85. package/dist/models/entity.model.js +1 -0
  86. package/dist/models/ticket.model.d.ts +117 -0
  87. package/dist/models/ticket.model.js +43 -0
  88. package/dist/services/auth.service.d.ts +15 -0
  89. package/dist/services/auth.service.js +26 -0
  90. package/dist/services/config.service.d.ts +34 -0
  91. package/dist/services/config.service.js +234 -0
  92. package/dist/services/entity.service.d.ts +20 -0
  93. package/dist/services/entity.service.js +127 -0
  94. package/dist/services/focus.service.d.ts +71 -0
  95. package/dist/services/focus.service.js +614 -0
  96. package/dist/services/git.service.d.ts +39 -0
  97. package/dist/services/git.service.js +188 -0
  98. package/dist/services/gut-api.service.d.ts +53 -0
  99. package/dist/services/gut-api.service.js +99 -0
  100. package/dist/services/ticket.service.d.ts +84 -0
  101. package/dist/services/ticket.service.js +207 -0
  102. package/dist/utils/display.d.ts +26 -0
  103. package/dist/utils/display.js +145 -0
  104. package/dist/utils/filesystem.d.ts +32 -0
  105. package/dist/utils/filesystem.js +198 -0
  106. package/dist/utils/index.d.ts +13 -0
  107. package/dist/utils/index.js +14 -0
  108. package/dist/utils/validation.d.ts +22 -0
  109. package/dist/utils/validation.js +192 -0
  110. package/oclif.manifest.json +2006 -0
  111. package/package.json +11 -2
@@ -0,0 +1,405 @@
1
+ import { Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { BaseCommand } from '../base-command.js';
4
+ export default class Patterns extends BaseCommand {
5
+ static description = 'Show learned patterns for current context or entities';
6
+ static examples = [
7
+ '<%= config.bin %> <%= command.id %>',
8
+ '<%= config.bin %> <%= command.id %> --entity mindtools',
9
+ '<%= config.bin %> <%= command.id %> --type client',
10
+ '<%= config.bin %> <%= command.id %> --mode strategy',
11
+ ];
12
+ static flags = {
13
+ entity: Flags.string({
14
+ char: 'e',
15
+ description: 'show patterns for specific entity',
16
+ }),
17
+ json: Flags.boolean({
18
+ default: false,
19
+ description: 'output as JSON',
20
+ }),
21
+ mode: Flags.string({
22
+ char: 'm',
23
+ description: 'show patterns for focus mode',
24
+ options: ['delivery', 'strategy', 'audit', 'debug', 'research', 'proposal'],
25
+ }),
26
+ type: Flags.string({
27
+ char: 't',
28
+ description: 'show patterns for entity type',
29
+ options: ['client', 'prospect', 'company', 'initiative', 'system'],
30
+ }),
31
+ };
32
+ async run() {
33
+ const { flags } = await this.parse(Patterns);
34
+ const currentFocus = await this.focusService.getCurrentFocus();
35
+ const focusedEntities = await this.focusService.getFocusedEntities();
36
+ // Determine what patterns to analyze
37
+ let targetEntity = null;
38
+ let targetType = flags.type;
39
+ const targetMode = (flags.mode || currentFocus?.mode);
40
+ if (flags.entity) {
41
+ const foundEntity = this.entityService.findEntity(flags.entity);
42
+ if (!foundEntity) {
43
+ this.error(`Entity '${flags.entity}' not found`);
44
+ }
45
+ targetEntity = foundEntity;
46
+ }
47
+ else if (focusedEntities.length > 0) {
48
+ targetEntity = focusedEntities[0]; // Use first focused entity
49
+ targetType = targetType || targetEntity.type;
50
+ }
51
+ const patterns = await this.analyzePatterns(targetEntity, targetType, targetMode);
52
+ if (flags.json) {
53
+ this.log(JSON.stringify(patterns, null, 2));
54
+ return;
55
+ }
56
+ this.displayPatterns(patterns, targetEntity, targetType, targetMode);
57
+ }
58
+ analyzeCollaborationPatterns(_entity) {
59
+ // Would analyze commit patterns, PR patterns, etc.
60
+ return ['solo_work', 'pair_programming', 'code_review'];
61
+ }
62
+ async analyzeCrossEntityPatterns(entities) {
63
+ return {
64
+ dependencyChains: this.findDependencyChains(entities),
65
+ sharedSystems: this.findSharedSystems(entities),
66
+ similarEntityClusters: this.findSimilarClusters(entities),
67
+ workflowSimilarities: this.findWorkflowSimilarities(entities),
68
+ };
69
+ }
70
+ async analyzeEntityPatterns(entity) {
71
+ const metadata = entity.metadata || {};
72
+ return {
73
+ collaborationPatterns: this.analyzeCollaborationPatterns(entity),
74
+ commonWorkflows: [
75
+ 'Focus → Edit → Commit → Push',
76
+ 'Research → Document → Review',
77
+ 'Debug → Fix → Test → Deploy',
78
+ ],
79
+ filePatterns: this.analyzeFilePatterns(entity),
80
+ focusIntelligence: {},
81
+ relationships: metadata.relationships || {},
82
+ workingPatterns: metadata.working_patterns || {},
83
+ };
84
+ }
85
+ // Helper methods for pattern analysis
86
+ analyzeFilePatterns(_entity) {
87
+ // Would analyze actual file patterns from git history
88
+ return ['src/', 'docs/', 'tests/'];
89
+ }
90
+ async analyzeModePatterns(mode) {
91
+ return {
92
+ commonTools: this.getCommonTools(mode),
93
+ optimalDuration: this.getOptimalDuration(mode),
94
+ successIndicators: this.getSuccessIndicators(mode),
95
+ transitionPatterns: this.getTransitionPatterns(mode),
96
+ typicalActivities: this.getTypicalActivities(mode),
97
+ };
98
+ }
99
+ async analyzePatterns(entity, type, mode) {
100
+ const allEntities = this.entityService.getAllEntities();
101
+ const patterns = {
102
+ crossEntityPatterns: {},
103
+ entityPatterns: {},
104
+ modePatterns: {},
105
+ productivityPatterns: this.generateProductivityPatterns(entity, type, mode),
106
+ temporalPatterns: this.generateTemporalPatterns(),
107
+ typePatterns: {},
108
+ };
109
+ // Entity-specific patterns
110
+ if (entity) {
111
+ patterns.entityPatterns = await this.analyzeEntityPatterns(entity);
112
+ }
113
+ // Type-based patterns
114
+ if (type) {
115
+ const entitiesOfType = allEntities.filter(e => e.type === type);
116
+ patterns.typePatterns = await this.analyzeTypePatterns(entitiesOfType, type);
117
+ }
118
+ // Mode-based patterns
119
+ if (mode) {
120
+ patterns.modePatterns = await this.analyzeModePatterns(mode);
121
+ }
122
+ // Cross-entity patterns
123
+ patterns.crossEntityPatterns = await this.analyzeCrossEntityPatterns(allEntities);
124
+ return patterns;
125
+ }
126
+ analyzeRelationshipPatterns(_entities) {
127
+ // Would analyze actual relationship patterns
128
+ return {
129
+ commonDependencies: ['systems/api', 'shared/design-system'],
130
+ typicalClusterSize: 3,
131
+ };
132
+ }
133
+ async analyzeTypePatterns(entities, type) {
134
+ const commonPatterns = {
135
+ commonModes: this.getCommonModes(type),
136
+ relationshipPatterns: this.analyzeRelationshipPatterns(entities),
137
+ successMetrics: this.getSuccessMetrics(type),
138
+ typicalDuration: this.calculateTypicalDuration(entities, type),
139
+ };
140
+ return commonPatterns;
141
+ }
142
+ calculateTypicalDuration(_entities, type) {
143
+ // Would calculate from actual usage data
144
+ const durations = {
145
+ client: '2 hours',
146
+ company: '3 hours',
147
+ initiative: '2.5 hours',
148
+ prospect: '1 hour',
149
+ system: '1.5 hours',
150
+ };
151
+ return durations[type] || '1 hour';
152
+ }
153
+ displayEntityPatterns(patterns) {
154
+ if (patterns.commonWorkflows) {
155
+ this.log(` ${chalk.cyan('Common Workflows:')}`);
156
+ for (const workflow of patterns.commonWorkflows) {
157
+ this.log(` • ${workflow}`);
158
+ }
159
+ }
160
+ if (patterns.workingPatterns?.typical_focus_duration) {
161
+ this.log(` ${chalk.cyan('Typical Focus Duration:')} ${patterns.workingPatterns.typical_focus_duration}`);
162
+ }
163
+ if (patterns.relationships?.similar_entities && patterns.relationships.similar_entities.length > 0) {
164
+ this.log(` ${chalk.cyan('Similar Entities:')} ${patterns.relationships.similar_entities.join(', ')}`);
165
+ }
166
+ }
167
+ displayModePatterns(patterns) {
168
+ if (patterns.typicalActivities?.length > 0) {
169
+ this.log(` ${chalk.cyan('Typical Activities:')}`);
170
+ for (const activity of patterns.typicalActivities) {
171
+ this.log(` • ${activity}`);
172
+ }
173
+ }
174
+ if (patterns.optimalDuration) {
175
+ this.log(` ${chalk.cyan('Optimal Duration:')} ${patterns.optimalDuration}`);
176
+ }
177
+ }
178
+ displayPatterns(patterns, entity, type, mode) {
179
+ this.log(chalk.bold('\nšŸ” Pattern Analysis'));
180
+ this.log(chalk.dim('─'.repeat(50)));
181
+ // Context header
182
+ const context = [];
183
+ if (entity)
184
+ context.push(`Entity: ${chalk.cyan(entity.name)}`);
185
+ if (type)
186
+ context.push(`Type: ${chalk.yellow(type)}`);
187
+ if (mode)
188
+ context.push(`Mode: ${chalk.green(mode)}`);
189
+ if (context.length > 0) {
190
+ this.log(`šŸ“ Context: ${context.join(' | ')}`);
191
+ this.log('');
192
+ }
193
+ // Entity patterns
194
+ if (patterns.entityPatterns && Object.keys(patterns.entityPatterns).length > 0) {
195
+ this.log(chalk.bold('šŸŽÆ Entity-Specific Patterns:'));
196
+ this.displayEntityPatterns(patterns.entityPatterns);
197
+ this.log('');
198
+ }
199
+ // Type patterns
200
+ if (patterns.typePatterns && Object.keys(patterns.typePatterns).length > 0) {
201
+ this.log(chalk.bold('šŸ“Š Type-Based Patterns:'));
202
+ this.displayTypePatterns(patterns.typePatterns);
203
+ this.log('');
204
+ }
205
+ // Mode patterns
206
+ if (patterns.modePatterns && Object.keys(patterns.modePatterns).length > 0) {
207
+ this.log(chalk.bold('āš™ļø Mode-Specific Patterns:'));
208
+ this.displayModePatterns(patterns.modePatterns);
209
+ this.log('');
210
+ }
211
+ // Productivity patterns
212
+ if (patterns.productivityPatterns) {
213
+ this.log(chalk.bold('šŸ“ˆ Productivity Patterns:'));
214
+ this.displayProductivityPatterns(patterns.productivityPatterns);
215
+ this.log('');
216
+ }
217
+ // Temporal patterns
218
+ if (patterns.temporalPatterns) {
219
+ this.log(chalk.bold('ā° Temporal Patterns:'));
220
+ this.displayTemporalPatterns(patterns.temporalPatterns);
221
+ }
222
+ }
223
+ displayProductivityPatterns(patterns) {
224
+ if (patterns.highProductivityIndicators?.length > 0) {
225
+ this.log(` ${chalk.green('High Productivity Indicators:')}`);
226
+ for (const indicator of patterns.highProductivityIndicators) {
227
+ this.log(` āœ“ ${indicator}`);
228
+ }
229
+ }
230
+ if (patterns.optimizationSuggestions?.length > 0) {
231
+ this.log(` ${chalk.yellow('Optimization Suggestions:')}`);
232
+ for (const suggestion of patterns.optimizationSuggestions) {
233
+ this.log(` šŸ’” ${suggestion}`);
234
+ }
235
+ }
236
+ }
237
+ displayTemporalPatterns(patterns) {
238
+ if (patterns.peakProductivityHours) {
239
+ this.log(` ${chalk.cyan('Peak Hours:')} ${patterns.peakProductivityHours.join(', ')}`);
240
+ }
241
+ if (patterns.optimalSessionLength) {
242
+ this.log(` ${chalk.cyan('Optimal Session:')} ${patterns.optimalSessionLength}`);
243
+ }
244
+ if (patterns.contextSwitchCost) {
245
+ this.log(` ${chalk.cyan('Context Switch Cost:')} ${patterns.contextSwitchCost}`);
246
+ }
247
+ }
248
+ displayTypePatterns(patterns) {
249
+ if (patterns.typicalDuration) {
250
+ this.log(` ${chalk.cyan('Typical Duration:')} ${patterns.typicalDuration}`);
251
+ }
252
+ if (patterns.commonModes?.length > 0) {
253
+ this.log(` ${chalk.cyan('Common Modes:')} ${patterns.commonModes.join(', ')}`);
254
+ }
255
+ if (patterns.successMetrics?.length > 0) {
256
+ this.log(` ${chalk.cyan('Success Metrics:')}`);
257
+ for (const metric of patterns.successMetrics) {
258
+ this.log(` • ${metric}`);
259
+ }
260
+ }
261
+ }
262
+ findDependencyChains(_entities) {
263
+ // Would analyze actual dependency chains
264
+ return ['client → system → shared'];
265
+ }
266
+ findSharedSystems(_entities) {
267
+ // Would find commonly used systems
268
+ return ['systems/api', 'shared/design-system'];
269
+ }
270
+ findSimilarClusters(_entities) {
271
+ // Would find clusters of similar entities
272
+ return [['mindtools', 'vixting'], ['api', 'shared']];
273
+ }
274
+ findWorkflowSimilarities(_entities) {
275
+ // Would analyze workflow similarities
276
+ return ['React development pattern', 'API integration pattern'];
277
+ }
278
+ generateProductivityPatterns(_entity, type, mode) {
279
+ const basePatterns = {
280
+ highProductivityIndicators: [
281
+ 'Focused sessions > 60 minutes',
282
+ 'Minimal context switching',
283
+ 'Clear objectives set',
284
+ 'Distraction-free environment',
285
+ ],
286
+ optimizationSuggestions: [],
287
+ productivityKillers: [
288
+ 'Frequent interruptions',
289
+ 'Unclear requirements',
290
+ 'Technical debt',
291
+ 'Missing dependencies',
292
+ ],
293
+ };
294
+ // Add context-specific suggestions
295
+ if (mode === 'strategy') {
296
+ basePatterns.optimizationSuggestions = [
297
+ ...basePatterns.optimizationSuggestions,
298
+ 'Schedule 2+ hour blocks for strategic thinking',
299
+ 'Minimize technical distractions',
300
+ 'Include business context in focus',
301
+ ];
302
+ }
303
+ else if (mode === 'delivery') {
304
+ basePatterns.optimizationSuggestions = [
305
+ ...basePatterns.optimizationSuggestions,
306
+ 'Use 90-minute focused coding sessions',
307
+ 'Have clear technical requirements',
308
+ 'Minimize meeting interruptions',
309
+ ];
310
+ }
311
+ if (type === 'client') {
312
+ basePatterns.optimizationSuggestions = [
313
+ ...basePatterns.optimizationSuggestions,
314
+ 'Batch client communication',
315
+ 'Maintain business context awareness',
316
+ 'Regular stakeholder alignment',
317
+ ];
318
+ }
319
+ return basePatterns;
320
+ }
321
+ generateTemporalPatterns() {
322
+ return {
323
+ contextSwitchCost: '8-12 minutes',
324
+ optimalSessionLength: '90 minutes',
325
+ peakProductivityHours: ['9-11am', '2-4pm'],
326
+ seasonalPatterns: {
327
+ q1: 'Planning and architecture',
328
+ q2: 'Development and implementation',
329
+ q3: 'Testing and optimization',
330
+ q4: 'Documentation and review',
331
+ },
332
+ weeklyPatterns: {
333
+ friday: 'Documentation and cleanup',
334
+ monday: 'Planning and strategy',
335
+ thursday: 'Implementation and testing',
336
+ tuesday: 'Deep development work',
337
+ wednesday: 'Collaboration and reviews',
338
+ },
339
+ };
340
+ }
341
+ getCommonModes(type) {
342
+ const modes = {
343
+ client: ['delivery', 'strategy', 'audit'],
344
+ company: ['strategy', 'audit'],
345
+ initiative: ['strategy', 'delivery'],
346
+ prospect: ['research', 'proposal'],
347
+ system: ['delivery', 'debug'],
348
+ };
349
+ return modes[type] || ['delivery'];
350
+ }
351
+ getCommonTools(_mode) {
352
+ // Would return actual tool usage patterns
353
+ return ['VS Code', 'Git', 'Browser', 'Terminal'];
354
+ }
355
+ getOptimalDuration(mode) {
356
+ const durations = {
357
+ audit: '60-90 minutes',
358
+ debug: '45-60 minutes',
359
+ delivery: '90 minutes',
360
+ proposal: '2-4 hours',
361
+ research: '1-2 hours',
362
+ strategy: '2-3 hours',
363
+ };
364
+ return durations[mode] || '1 hour';
365
+ }
366
+ getSuccessIndicators(mode) {
367
+ const indicators = {
368
+ audit: ['Issues identified', 'Compliance verified', 'Risks assessed'],
369
+ debug: ['Issues resolved', 'Root cause found', 'Fix verified'],
370
+ delivery: ['Code committed', 'Tests passing', 'Features completed'],
371
+ proposal: ['Requirements clarified', 'Solution designed', 'Proposal completed'],
372
+ research: ['Insights gathered', 'Options identified', 'Recommendations made'],
373
+ strategy: ['Decisions made', 'Plans documented', 'Alignment achieved'],
374
+ };
375
+ return indicators[mode] || [];
376
+ }
377
+ getSuccessMetrics(type) {
378
+ const metrics = {
379
+ client: ['Client satisfaction', 'Delivery velocity', 'Code quality'],
380
+ company: ['Strategic alignment', 'Operational efficiency', 'Growth metrics'],
381
+ initiative: ['Milestone completion', 'Cross-team adoption', 'Impact measurement'],
382
+ prospect: ['Proposal quality', 'Response time', 'Conversion rate'],
383
+ system: ['Performance metrics', 'Reliability', 'Developer experience'],
384
+ };
385
+ return metrics[type] || [];
386
+ }
387
+ getTransitionPatterns(_mode) {
388
+ // Would analyze actual transition patterns
389
+ return {
390
+ commonNextModes: ['delivery', 'strategy'],
391
+ transitionTriggers: ['completion', 'interruption', 'scheduled'],
392
+ };
393
+ }
394
+ getTypicalActivities(mode) {
395
+ const activities = {
396
+ audit: ['Review', 'Compliance check', 'Risk assessment', 'Documentation'],
397
+ debug: ['Issue investigation', 'Log analysis', 'Testing fixes', 'Root cause analysis'],
398
+ delivery: ['Coding', 'Testing', 'Code review', 'Documentation'],
399
+ proposal: ['Requirements gathering', 'Solution design', 'Pricing', 'Presentation creation'],
400
+ research: ['Market analysis', 'Technology evaluation', 'Competitive research', 'Documentation'],
401
+ strategy: ['Planning', 'Analysis', 'Decision making', 'Roadmap creation'],
402
+ };
403
+ return activities[mode] || [];
404
+ }
405
+ }
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from '../base-command.js';
2
+ export default class Pull extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ 'no-commit': import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ rebase: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,121 @@
1
+ import { Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import { BaseCommand } from '../base-command.js';
5
+ export default class Pull extends BaseCommand {
6
+ static description = 'Pull changes from remote repositories';
7
+ static examples = [
8
+ '<%= config.bin %> <%= command.id %>',
9
+ '<%= config.bin %> <%= command.id %> --rebase',
10
+ '<%= config.bin %> <%= command.id %> --all',
11
+ ];
12
+ static flags = {
13
+ all: Flags.boolean({
14
+ default: false,
15
+ description: 'Fetch all remotes',
16
+ }),
17
+ 'no-commit': Flags.boolean({
18
+ default: false,
19
+ description: 'Perform merge but do not commit',
20
+ }),
21
+ rebase: Flags.boolean({
22
+ char: 'r',
23
+ default: false,
24
+ description: 'Rebase instead of merge',
25
+ }),
26
+ };
27
+ async run() {
28
+ const { flags } = await this.parse(Pull);
29
+ const focusedEntities = await this.focusService.getFocusedEntities();
30
+ if (focusedEntities.length === 0) {
31
+ this.error('No entities are focused. Use "gut focus <entity>" first.');
32
+ }
33
+ this.log(chalk.bold('\nā¬‡ļø Pulling from remote repositories\n'));
34
+ const results = {
35
+ conflicts: [],
36
+ failed: [],
37
+ success: [],
38
+ upToDate: [],
39
+ };
40
+ for (const entity of focusedEntities) {
41
+ const spinner = ora(`Pulling ${chalk.cyan(entity.name)}`).start();
42
+ try {
43
+ // Check if there's a remote configured
44
+ const remoteOutput = await this.gitService.exec(['remote', '-v'], { cwd: entity.path });
45
+ if (!remoteOutput || remoteOutput.trim().length === 0) {
46
+ spinner.warn(chalk.yellow(`${entity.name}: No remote configured`));
47
+ results.failed.push({ error: 'No remote configured', repo: entity.name });
48
+ continue;
49
+ }
50
+ // Fetch all remotes if requested
51
+ if (flags.all) {
52
+ await this.gitService.exec(['fetch', '--all'], { cwd: entity.path });
53
+ }
54
+ // Check for uncommitted changes
55
+ const status = await this.gitService.getStatus(entity.path);
56
+ const hasUncommitted = status.changes.length > 0;
57
+ if (hasUncommitted && !flags['no-commit']) {
58
+ spinner.warn(chalk.yellow(`${entity.name}: Has uncommitted changes`));
59
+ results.failed.push({ error: 'Uncommitted changes. Commit or stash first', repo: entity.name });
60
+ continue;
61
+ }
62
+ // Build pull options
63
+ const options = {
64
+ noFf: flags['no-commit'],
65
+ rebase: flags.rebase,
66
+ };
67
+ await this.gitService.pull(entity.path, options);
68
+ spinner.succeed(chalk.green(`āœ“ ${entity.name}: Pulled successfully`));
69
+ results.success.push(entity.name);
70
+ }
71
+ catch (error) {
72
+ const errorMessage = error instanceof Error ? error.message : String(error);
73
+ if (errorMessage.includes('Already up to date') || errorMessage.includes('Already up-to-date')) {
74
+ spinner.info(chalk.blue(`${entity.name}: Already up-to-date`));
75
+ results.upToDate.push(entity.name);
76
+ }
77
+ else if (errorMessage.includes('CONFLICT')) {
78
+ spinner.fail(chalk.red(`āœ— ${entity.name}: Merge conflicts detected`));
79
+ results.conflicts.push(entity.name);
80
+ }
81
+ else if (errorMessage.includes('no tracking information')) {
82
+ spinner.fail(chalk.red(`āœ— ${entity.name}: No tracking branch configured`));
83
+ results.failed.push({ error: 'No tracking branch. Set upstream first', repo: entity.name });
84
+ }
85
+ else if (errorMessage.includes('diverged')) {
86
+ spinner.fail(chalk.red(`āœ— ${entity.name}: Branches have diverged`));
87
+ results.failed.push({ error: 'Branches diverged. Use --rebase or resolve manually', repo: entity.name });
88
+ }
89
+ else {
90
+ spinner.fail(chalk.red(`āœ— ${entity.name}: ${errorMessage}`));
91
+ results.failed.push({ error: errorMessage, repo: entity.name });
92
+ }
93
+ }
94
+ }
95
+ // Summary
96
+ this.log(chalk.bold('\nšŸ“Š Pull Summary'));
97
+ this.log(chalk.dim('─'.repeat(50)));
98
+ if (results.success.length > 0) {
99
+ this.log(chalk.green(`āœ“ Updated: ${results.success.length} entities`));
100
+ }
101
+ if (results.upToDate.length > 0) {
102
+ this.log(chalk.blue(`ā—‹ Up-to-date: ${results.upToDate.length} entities`));
103
+ }
104
+ if (results.conflicts.length > 0) {
105
+ this.log(chalk.yellow(`⚠ Conflicts: ${results.conflicts.length} entities`));
106
+ this.log(chalk.dim(' Resolve conflicts manually in:'));
107
+ for (const repo of results.conflicts) {
108
+ this.log(chalk.dim(` - ${repo}`));
109
+ }
110
+ }
111
+ if (results.failed.length > 0) {
112
+ this.log(chalk.red(`āœ— Failed: ${results.failed.length} entities`));
113
+ for (const failure of results.failed) {
114
+ this.log(chalk.red(` - ${failure.repo}: ${failure.error}`));
115
+ }
116
+ }
117
+ if (results.success.length > 0) {
118
+ this.log(chalk.dim('\nTip: Use "gut status" to see the current state'));
119
+ }
120
+ }
121
+ }
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from '../base-command.js';
2
+ export default class Push extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ 'set-upstream': import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ tags: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,97 @@
1
+ import { Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import { BaseCommand } from '../base-command.js';
5
+ export default class Push extends BaseCommand {
6
+ static description = 'Push commits to remote repositories';
7
+ static examples = [
8
+ '<%= config.bin %> <%= command.id %>',
9
+ '<%= config.bin %> <%= command.id %> --force',
10
+ '<%= config.bin %> <%= command.id %> --set-upstream',
11
+ ];
12
+ static flags = {
13
+ force: Flags.boolean({
14
+ char: 'f',
15
+ default: false,
16
+ description: 'Force push (use with caution)',
17
+ }),
18
+ 'set-upstream': Flags.boolean({
19
+ char: 'u',
20
+ default: false,
21
+ description: 'Set upstream branch',
22
+ }),
23
+ tags: Flags.boolean({
24
+ default: false,
25
+ description: 'Push tags',
26
+ }),
27
+ };
28
+ async run() {
29
+ const { flags } = await this.parse(Push);
30
+ const focusedEntities = await this.focusService.getFocusedEntities();
31
+ if (focusedEntities.length === 0) {
32
+ this.error('No entities are focused. Use "gut focus <entity>" first.');
33
+ }
34
+ this.log(chalk.bold('\nšŸš€ Pushing to remote repositories\n'));
35
+ const results = {
36
+ failed: [],
37
+ success: [],
38
+ upToDate: [],
39
+ };
40
+ for (const entity of focusedEntities) {
41
+ const spinner = ora(`Pushing ${chalk.cyan(entity.name)}`).start();
42
+ try {
43
+ // Check if there's a remote configured
44
+ const remoteOutput = await this.gitService.exec(['remote', '-v'], { cwd: entity.path });
45
+ if (!remoteOutput || remoteOutput.trim().length === 0) {
46
+ spinner.warn(chalk.yellow(`${entity.name}: No remote configured`));
47
+ results.failed.push({ error: 'No remote configured', repo: entity.name });
48
+ continue;
49
+ }
50
+ // Build push options
51
+ const options = {
52
+ force: flags.force,
53
+ setUpstream: flags['set-upstream'],
54
+ tags: flags.tags,
55
+ };
56
+ await this.gitService.push(entity.path, options);
57
+ spinner.succeed(chalk.green(`āœ“ ${entity.name}: Pushed successfully`));
58
+ results.success.push(entity.name);
59
+ }
60
+ catch (error) {
61
+ const errorMessage = error instanceof Error ? error.message : String(error);
62
+ if (errorMessage.includes('Everything up-to-date')) {
63
+ spinner.info(chalk.blue(`${entity.name}: Already up-to-date`));
64
+ results.upToDate.push(entity.name);
65
+ }
66
+ else if (errorMessage.includes('no upstream branch')) {
67
+ spinner.fail(chalk.red(`āœ— ${entity.name}: No upstream branch. Use --set-upstream`));
68
+ results.failed.push({ error: 'No upstream branch configured', repo: entity.name });
69
+ }
70
+ else if (errorMessage.includes('rejected')) {
71
+ spinner.fail(chalk.red(`āœ— ${entity.name}: Push rejected (remote has changes)`));
72
+ results.failed.push({ error: 'Remote has changes. Pull first or use --force', repo: entity.name });
73
+ }
74
+ else {
75
+ spinner.fail(chalk.red(`āœ— ${entity.name}: ${errorMessage}`));
76
+ results.failed.push({ error: errorMessage, repo: entity.name });
77
+ }
78
+ }
79
+ }
80
+ // Summary
81
+ this.log(chalk.bold('\nšŸ“Š Push Summary'));
82
+ this.log(chalk.dim('─'.repeat(50)));
83
+ if (results.success.length > 0) {
84
+ this.log(chalk.green(`āœ“ Pushed: ${results.success.length} entities`));
85
+ }
86
+ if (results.upToDate.length > 0) {
87
+ this.log(chalk.blue(`ā—‹ Up-to-date: ${results.upToDate.length} entities`));
88
+ }
89
+ if (results.failed.length > 0) {
90
+ this.log(chalk.red(`āœ— Failed: ${results.failed.length} entities`));
91
+ for (const failure of results.failed) {
92
+ this.log(chalk.red(` - ${failure.repo}: ${failure.error}`));
93
+ }
94
+ this.log(chalk.dim('\nTip: Use "gut pull" to sync with remote first'));
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,20 @@
1
+ import { BaseCommand } from '../base-command.js';
2
+ export default class QuickSetup extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ auto: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ 'clone-missing': import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ 'scan-depth': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
10
+ };
11
+ private profiles;
12
+ run(): Promise<void>;
13
+ private categorizeEntities;
14
+ private detectProfile;
15
+ private findMissingEntities;
16
+ private printDetectedEntities;
17
+ private printNextSteps;
18
+ private printSetupSummary;
19
+ private scanWorkspace;
20
+ }