@hyperdrive.bot/gut 0.1.6 ā 0.1.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.
- package/README.md +1 -1
- package/dist/base-command.d.ts +22 -0
- package/dist/base-command.js +99 -0
- package/dist/commands/add.d.ts +14 -0
- package/dist/commands/add.js +70 -0
- package/dist/commands/affected.d.ts +23 -0
- package/dist/commands/affected.js +323 -0
- package/dist/commands/audit.d.ts +33 -0
- package/dist/commands/audit.js +594 -0
- package/dist/commands/back.d.ts +6 -0
- package/dist/commands/back.js +29 -0
- package/dist/commands/checkout.d.ts +14 -0
- package/dist/commands/checkout.js +124 -0
- package/dist/commands/commit.d.ts +11 -0
- package/dist/commands/commit.js +107 -0
- package/dist/commands/context.d.ts +6 -0
- package/dist/commands/context.js +32 -0
- package/dist/commands/contexts.d.ts +7 -0
- package/dist/commands/contexts.js +88 -0
- package/dist/commands/deps.d.ts +10 -0
- package/dist/commands/deps.js +100 -0
- package/dist/commands/entity/add.d.ts +16 -0
- package/dist/commands/entity/add.js +103 -0
- package/dist/commands/entity/clone-all.d.ts +17 -0
- package/dist/commands/entity/clone-all.js +127 -0
- package/dist/commands/entity/clone.d.ts +15 -0
- package/dist/commands/entity/clone.js +106 -0
- package/dist/commands/entity/list.d.ts +11 -0
- package/dist/commands/entity/list.js +80 -0
- package/dist/commands/entity/remove.d.ts +12 -0
- package/dist/commands/entity/remove.js +54 -0
- package/dist/commands/extract.d.ts +35 -0
- package/dist/commands/extract.js +483 -0
- package/dist/commands/focus.d.ts +19 -0
- package/dist/commands/focus.js +137 -0
- package/dist/commands/graph.d.ts +18 -0
- package/dist/commands/graph.js +273 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.js +75 -0
- package/dist/commands/insights.d.ts +21 -0
- package/dist/commands/insights.js +465 -0
- package/dist/commands/patterns.d.ts +40 -0
- package/dist/commands/patterns.js +405 -0
- package/dist/commands/pull.d.ts +11 -0
- package/dist/commands/pull.js +121 -0
- package/dist/commands/push.d.ts +11 -0
- package/dist/commands/push.js +97 -0
- package/dist/commands/quick-setup.d.ts +20 -0
- package/dist/commands/quick-setup.js +417 -0
- package/dist/commands/recent.d.ts +9 -0
- package/dist/commands/recent.js +51 -0
- package/dist/commands/related.d.ts +23 -0
- package/dist/commands/related.js +255 -0
- package/dist/commands/repos.d.ts +17 -0
- package/dist/commands/repos.js +184 -0
- package/dist/commands/stack.d.ts +10 -0
- package/dist/commands/stack.js +78 -0
- package/dist/commands/status.d.ts +13 -0
- package/dist/commands/status.js +193 -0
- package/dist/commands/sync.d.ts +11 -0
- package/dist/commands/sync.js +139 -0
- package/dist/commands/ticket/focus.d.ts +20 -0
- package/dist/commands/ticket/focus.js +217 -0
- package/dist/commands/ticket/get.d.ts +15 -0
- package/dist/commands/ticket/get.js +168 -0
- package/dist/commands/ticket/hint.d.ts +16 -0
- package/dist/commands/ticket/hint.js +147 -0
- package/dist/commands/ticket/index.d.ts +10 -0
- package/dist/commands/ticket/index.js +60 -0
- package/dist/commands/ticket/list.d.ts +13 -0
- package/dist/commands/ticket/list.js +120 -0
- package/dist/commands/ticket/sync.d.ts +14 -0
- package/dist/commands/ticket/sync.js +85 -0
- package/dist/commands/ticket/update.d.ts +17 -0
- package/dist/commands/ticket/update.js +142 -0
- package/dist/commands/unfocus.d.ts +6 -0
- package/dist/commands/unfocus.js +19 -0
- package/dist/commands/used-by.d.ts +13 -0
- package/dist/commands/used-by.js +110 -0
- package/dist/commands/workspace.d.ts +22 -0
- package/dist/commands/workspace.js +372 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +16 -0
- package/dist/models/entity.model.d.ts +234 -0
- package/dist/models/entity.model.js +1 -0
- package/dist/models/ticket.model.d.ts +117 -0
- package/dist/models/ticket.model.js +43 -0
- package/dist/services/auth.service.d.ts +15 -0
- package/dist/services/auth.service.js +26 -0
- package/dist/services/config.service.d.ts +34 -0
- package/dist/services/config.service.js +234 -0
- package/dist/services/entity.service.d.ts +20 -0
- package/dist/services/entity.service.js +127 -0
- package/dist/services/focus.service.d.ts +71 -0
- package/dist/services/focus.service.js +614 -0
- package/dist/services/git.service.d.ts +39 -0
- package/dist/services/git.service.js +188 -0
- package/dist/services/gut-api.service.d.ts +53 -0
- package/dist/services/gut-api.service.js +99 -0
- package/dist/services/ticket.service.d.ts +84 -0
- package/dist/services/ticket.service.js +207 -0
- package/dist/utils/display.d.ts +26 -0
- package/dist/utils/display.js +145 -0
- package/dist/utils/filesystem.d.ts +32 -0
- package/dist/utils/filesystem.js +198 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.js +14 -0
- package/dist/utils/validation.d.ts +22 -0
- package/dist/utils/validation.js +192 -0
- package/oclif.manifest.json +2008 -0
- 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
|
+
}
|