@hyperdrive.bot/gut 0.1.3

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 +809 -0
  2. package/bin/dev +16 -0
  3. package/bin/run +5 -0
  4. package/dist/base-command.d.ts +21 -0
  5. package/dist/base-command.js +110 -0
  6. package/dist/commands/add.d.ts +13 -0
  7. package/dist/commands/add.js +73 -0
  8. package/dist/commands/affected.d.ts +23 -0
  9. package/dist/commands/affected.js +326 -0
  10. package/dist/commands/audit.d.ts +33 -0
  11. package/dist/commands/audit.js +593 -0
  12. package/dist/commands/back.d.ts +6 -0
  13. package/dist/commands/back.js +29 -0
  14. package/dist/commands/commit.d.ts +11 -0
  15. package/dist/commands/commit.js +113 -0
  16. package/dist/commands/context.d.ts +6 -0
  17. package/dist/commands/context.js +36 -0
  18. package/dist/commands/contexts.d.ts +7 -0
  19. package/dist/commands/contexts.js +92 -0
  20. package/dist/commands/deps.d.ts +10 -0
  21. package/dist/commands/deps.js +104 -0
  22. package/dist/commands/entity/add.d.ts +16 -0
  23. package/dist/commands/entity/add.js +105 -0
  24. package/dist/commands/entity/clone-all.d.ts +17 -0
  25. package/dist/commands/entity/clone-all.js +135 -0
  26. package/dist/commands/entity/clone.d.ts +15 -0
  27. package/dist/commands/entity/clone.js +109 -0
  28. package/dist/commands/entity/list.d.ts +11 -0
  29. package/dist/commands/entity/list.js +82 -0
  30. package/dist/commands/entity/remove.d.ts +12 -0
  31. package/dist/commands/entity/remove.js +58 -0
  32. package/dist/commands/focus.d.ts +19 -0
  33. package/dist/commands/focus.js +139 -0
  34. package/dist/commands/graph.d.ts +18 -0
  35. package/dist/commands/graph.js +238 -0
  36. package/dist/commands/init.d.ts +11 -0
  37. package/dist/commands/init.js +84 -0
  38. package/dist/commands/insights.d.ts +21 -0
  39. package/dist/commands/insights.js +434 -0
  40. package/dist/commands/patterns.d.ts +40 -0
  41. package/dist/commands/patterns.js +412 -0
  42. package/dist/commands/pull.d.ts +11 -0
  43. package/dist/commands/pull.js +121 -0
  44. package/dist/commands/push.d.ts +11 -0
  45. package/dist/commands/push.js +101 -0
  46. package/dist/commands/quick-setup.d.ts +20 -0
  47. package/dist/commands/quick-setup.js +422 -0
  48. package/dist/commands/recent.d.ts +9 -0
  49. package/dist/commands/recent.js +55 -0
  50. package/dist/commands/related.d.ts +23 -0
  51. package/dist/commands/related.js +257 -0
  52. package/dist/commands/repos.d.ts +14 -0
  53. package/dist/commands/repos.js +185 -0
  54. package/dist/commands/stack.d.ts +10 -0
  55. package/dist/commands/stack.js +83 -0
  56. package/dist/commands/status.d.ts +14 -0
  57. package/dist/commands/status.js +246 -0
  58. package/dist/commands/sync.d.ts +11 -0
  59. package/dist/commands/sync.js +142 -0
  60. package/dist/commands/unfocus.d.ts +6 -0
  61. package/dist/commands/unfocus.js +23 -0
  62. package/dist/commands/used-by.d.ts +10 -0
  63. package/dist/commands/used-by.js +111 -0
  64. package/dist/commands/workspace.d.ts +20 -0
  65. package/dist/commands/workspace.js +365 -0
  66. package/dist/index.d.ts +1 -0
  67. package/dist/index.js +5 -0
  68. package/dist/models/entity.model.d.ts +81 -0
  69. package/dist/models/entity.model.js +2 -0
  70. package/dist/services/config.service.d.ts +34 -0
  71. package/dist/services/config.service.js +230 -0
  72. package/dist/services/entity.service.d.ts +19 -0
  73. package/dist/services/entity.service.js +130 -0
  74. package/dist/services/focus.service.d.ts +70 -0
  75. package/dist/services/focus.service.js +587 -0
  76. package/dist/services/git.service.d.ts +37 -0
  77. package/dist/services/git.service.js +180 -0
  78. package/dist/utils/display.d.ts +25 -0
  79. package/dist/utils/display.js +150 -0
  80. package/dist/utils/filesystem.d.ts +32 -0
  81. package/dist/utils/filesystem.js +220 -0
  82. package/dist/utils/index.d.ts +13 -0
  83. package/dist/utils/index.js +18 -0
  84. package/dist/utils/validation.d.ts +22 -0
  85. package/dist/utils/validation.js +196 -0
  86. package/oclif.manifest.json +1463 -0
  87. package/package.json +76 -0
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfigService = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const fs = tslib_1.__importStar(require("fs"));
6
+ const path = tslib_1.__importStar(require("path"));
7
+ class ConfigService {
8
+ workspaceRoot;
9
+ gutDir;
10
+ focusFile;
11
+ configFile;
12
+ historyFile;
13
+ focusContextFile;
14
+ focusDir;
15
+ config = null;
16
+ focus = null;
17
+ history = [];
18
+ constructor(workspaceRoot) {
19
+ this.workspaceRoot = workspaceRoot || process.env.DS_WORKSPACE || process.cwd();
20
+ this.gutDir = path.join(this.workspaceRoot, '.gut');
21
+ this.focusDir = path.join(this.workspaceRoot, 'focus');
22
+ this.focusFile = path.join(this.gutDir, 'focus.json');
23
+ this.configFile = path.join(this.gutDir, 'config.json');
24
+ this.historyFile = path.join(this.gutDir, 'history.json');
25
+ this.focusContextFile = path.join(this.focusDir, 'context.yaml');
26
+ this.ensureDirectories();
27
+ this.loadAll();
28
+ }
29
+ ensureDirectories() {
30
+ if (!fs.existsSync(this.gutDir)) {
31
+ fs.mkdirSync(this.gutDir, { recursive: true });
32
+ }
33
+ if (!fs.existsSync(this.focusDir)) {
34
+ fs.mkdirSync(this.focusDir, { recursive: true });
35
+ }
36
+ }
37
+ loadAll() {
38
+ this.config = this.loadConfigSync();
39
+ this.focus = this.loadFocus();
40
+ this.history = this.loadHistory();
41
+ }
42
+ async loadConfig() {
43
+ try {
44
+ if (fs.existsSync(this.configFile)) {
45
+ const content = fs.readFileSync(this.configFile, 'utf8');
46
+ return JSON.parse(content);
47
+ }
48
+ }
49
+ catch (error) {
50
+ console.warn('⚠️ Could not load config:', error.message);
51
+ }
52
+ return { initialized: false, entities: [], workspace: this.workspaceRoot };
53
+ }
54
+ loadConfigSync() {
55
+ try {
56
+ if (fs.existsSync(this.configFile)) {
57
+ const content = fs.readFileSync(this.configFile, 'utf8');
58
+ return JSON.parse(content);
59
+ }
60
+ }
61
+ catch (error) {
62
+ console.warn('⚠️ Could not load config:', error.message);
63
+ }
64
+ return { initialized: false, entities: [] };
65
+ }
66
+ loadFocus() {
67
+ try {
68
+ if (fs.existsSync(this.focusFile)) {
69
+ const content = fs.readFileSync(this.focusFile, 'utf8');
70
+ return JSON.parse(content);
71
+ }
72
+ }
73
+ catch (error) {
74
+ console.warn('⚠️ Could not load focus state:', error.message);
75
+ }
76
+ return null;
77
+ }
78
+ loadHistory() {
79
+ try {
80
+ if (fs.existsSync(this.historyFile)) {
81
+ const content = fs.readFileSync(this.historyFile, 'utf8');
82
+ return JSON.parse(content);
83
+ }
84
+ }
85
+ catch (error) {
86
+ console.warn('⚠️ Could not load history:', error.message);
87
+ }
88
+ return [];
89
+ }
90
+ getConfig() {
91
+ if (!this.config) {
92
+ this.config = this.loadConfigSync();
93
+ }
94
+ return this.config || { initialized: false, entities: [] };
95
+ }
96
+ saveConfig(config) {
97
+ try {
98
+ fs.writeFileSync(this.configFile, JSON.stringify(config, null, 2));
99
+ this.config = config;
100
+ }
101
+ catch (error) {
102
+ throw new Error(`Could not save config: ${error.message}`);
103
+ }
104
+ }
105
+ getFocus() {
106
+ return this.focus;
107
+ }
108
+ saveFocus(focus) {
109
+ try {
110
+ // Save to history before changing focus
111
+ if (this.focus && focus) {
112
+ this.addToHistory(this.focus);
113
+ }
114
+ if (focus) {
115
+ fs.writeFileSync(this.focusFile, JSON.stringify(focus, null, 2));
116
+ }
117
+ else if (fs.existsSync(this.focusFile)) {
118
+ fs.unlinkSync(this.focusFile);
119
+ }
120
+ this.focus = focus;
121
+ }
122
+ catch (error) {
123
+ throw new Error(`Could not save focus state: ${error.message}`);
124
+ }
125
+ }
126
+ getHistory() {
127
+ return this.history;
128
+ }
129
+ addToHistory(focus) {
130
+ try {
131
+ if (!this.history)
132
+ this.history = [];
133
+ // Convert focus entities to string array for history
134
+ const entityNames = focus.entities ? focus.entities.map(e => e.name) : [focus.name];
135
+ // Don't add duplicate consecutive entries
136
+ const lastEntry = this.history[this.history.length - 1];
137
+ if (lastEntry &&
138
+ lastEntry.entities.length === entityNames.length &&
139
+ lastEntry.entities.every(e => entityNames.includes(e))) {
140
+ return;
141
+ }
142
+ // Add timestamp and limit history to 10 entries
143
+ const entry = {
144
+ entities: entityNames,
145
+ timestamp: Date.now()
146
+ };
147
+ this.history.push(entry);
148
+ if (this.history.length > 10) {
149
+ this.history = this.history.slice(-10);
150
+ }
151
+ fs.writeFileSync(this.historyFile, JSON.stringify(this.history, null, 2));
152
+ }
153
+ catch (error) {
154
+ console.warn('⚠️ Could not save history:', error.message);
155
+ }
156
+ }
157
+ clearHistory() {
158
+ this.history = [];
159
+ try {
160
+ if (fs.existsSync(this.historyFile)) {
161
+ fs.unlinkSync(this.historyFile);
162
+ }
163
+ }
164
+ catch (error) {
165
+ console.warn('⚠️ Could not clear history:', error.message);
166
+ }
167
+ }
168
+ isInitialized() {
169
+ return this.config?.initialized || false;
170
+ }
171
+ getWorkspaceRoot() {
172
+ return this.workspaceRoot;
173
+ }
174
+ async initWorkspace(workspacePath) {
175
+ const config = {
176
+ initialized: true,
177
+ entities: [],
178
+ workspace: workspacePath
179
+ };
180
+ this.saveConfig(config);
181
+ }
182
+ getGutDir() {
183
+ return this.gutDir;
184
+ }
185
+ async saveFocusContext(context) {
186
+ try {
187
+ // Convert to YAML format (simplified - would use a YAML library in production)
188
+ const yamlContent = this.convertToYaml(context);
189
+ fs.writeFileSync(this.focusContextFile, yamlContent);
190
+ }
191
+ catch (error) {
192
+ console.warn('⚠️ Could not save focus context:', error.message);
193
+ }
194
+ }
195
+ convertToYaml(obj, indent = 0) {
196
+ // Simple YAML converter - in production would use js-yaml library
197
+ const spaces = ' '.repeat(indent);
198
+ let yaml = '';
199
+ for (const [key, value] of Object.entries(obj)) {
200
+ if (value === null || value === undefined) {
201
+ continue;
202
+ }
203
+ if (typeof value === 'object' && !Array.isArray(value)) {
204
+ yaml += `${spaces}${key}:\n`;
205
+ yaml += this.convertToYaml(value, indent + 1);
206
+ }
207
+ else if (Array.isArray(value)) {
208
+ yaml += `${spaces}${key}:\n`;
209
+ for (const item of value) {
210
+ if (typeof item === 'object') {
211
+ yaml += `${spaces} -\n`;
212
+ yaml += this.convertToYaml(item, indent + 2);
213
+ }
214
+ else {
215
+ yaml += `${spaces} - ${item}\n`;
216
+ }
217
+ }
218
+ }
219
+ else {
220
+ const valueStr = typeof value === 'string' ? `"${value}"` : String(value);
221
+ yaml += `${spaces}${key}: ${valueStr}\n`;
222
+ }
223
+ }
224
+ return yaml;
225
+ }
226
+ getFocusDir() {
227
+ return this.focusDir;
228
+ }
229
+ }
230
+ exports.ConfigService = ConfigService;
@@ -0,0 +1,19 @@
1
+ import { Entity, EntityType } from '../models/entity.model';
2
+ import { ConfigService } from './config.service';
3
+ export declare class EntityService {
4
+ private configService;
5
+ constructor(configService: ConfigService);
6
+ getAllEntities(): Entity[];
7
+ listEntities(): Promise<Entity[]>;
8
+ getEntity(name: string): Promise<Entity | null>;
9
+ findEntity(name: string): Entity | undefined;
10
+ findEntityByTypeAndName(type: EntityType, name: string): Entity | undefined;
11
+ addEntity(name: string, type: EntityType, entityPath: string, repository?: string): Promise<void>;
12
+ removeEntity(name: string): void;
13
+ updateEntity(name: string, updates: Partial<Entity>): Promise<void>;
14
+ discoverEntities(): Entity[];
15
+ getEntitiesByType(type: EntityType): Entity[];
16
+ resolveEntityPath(entity: Entity): string;
17
+ validateEntityName(name: string): boolean;
18
+ getEntityByPath(searchPath: string): Entity | undefined;
19
+ }
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EntityService = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const fs = tslib_1.__importStar(require("fs"));
6
+ const path = tslib_1.__importStar(require("path"));
7
+ class EntityService {
8
+ configService;
9
+ constructor(configService) {
10
+ this.configService = configService;
11
+ }
12
+ getAllEntities() {
13
+ const config = this.configService.getConfig();
14
+ return config.entities || [];
15
+ }
16
+ async listEntities() {
17
+ return this.getAllEntities();
18
+ }
19
+ async getEntity(name) {
20
+ const entity = this.findEntity(name);
21
+ return entity || null;
22
+ }
23
+ findEntity(name) {
24
+ const entities = this.getAllEntities();
25
+ return entities.find(e => e.name === name);
26
+ }
27
+ findEntityByTypeAndName(type, name) {
28
+ const entities = this.getAllEntities();
29
+ return entities.find(e => e.type === type && e.name === name);
30
+ }
31
+ async addEntity(name, type, entityPath, repository) {
32
+ const entity = { name, type, path: entityPath, repository };
33
+ const config = this.configService.getConfig();
34
+ // Check if entity already exists
35
+ if (this.findEntity(entity.name)) {
36
+ throw new Error(`Entity '${entity.name}' already exists`);
37
+ }
38
+ // Validate path
39
+ const absolutePath = path.isAbsolute(entityPath)
40
+ ? entityPath
41
+ : path.join(this.configService.getWorkspaceRoot(), entityPath);
42
+ if (!fs.existsSync(absolutePath)) {
43
+ // Create directory if it doesn't exist
44
+ fs.mkdirSync(absolutePath, { recursive: true });
45
+ }
46
+ // Add entity
47
+ config.entities = config.entities || [];
48
+ config.entities.push(entity);
49
+ this.configService.saveConfig(config);
50
+ }
51
+ removeEntity(name) {
52
+ const config = this.configService.getConfig();
53
+ if (!this.findEntity(name)) {
54
+ throw new Error(`Entity '${name}' not found`);
55
+ }
56
+ config.entities = config.entities.filter(e => e.name !== name);
57
+ this.configService.saveConfig(config);
58
+ }
59
+ async updateEntity(name, updates) {
60
+ const config = this.configService.getConfig();
61
+ const entityIndex = config.entities.findIndex(e => e.name === name);
62
+ if (entityIndex === -1) {
63
+ throw new Error(`Entity '${name}' not found`);
64
+ }
65
+ config.entities[entityIndex] = {
66
+ ...config.entities[entityIndex],
67
+ ...updates
68
+ };
69
+ this.configService.saveConfig(config);
70
+ }
71
+ discoverEntities() {
72
+ const discovered = [];
73
+ const workspaceRoot = this.configService.getWorkspaceRoot();
74
+ // Common patterns for entity discovery
75
+ const patterns = [
76
+ { dir: 'apps', type: 'delivery' },
77
+ { dir: 'packages', type: 'module' },
78
+ { dir: 'libs', type: 'module' },
79
+ { dir: 'services', type: 'service' },
80
+ { dir: 'tools', type: 'tool' }
81
+ ];
82
+ for (const pattern of patterns) {
83
+ const dirPath = path.join(workspaceRoot, pattern.dir);
84
+ if (fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) {
85
+ const subdirs = fs.readdirSync(dirPath)
86
+ .filter(item => {
87
+ const itemPath = path.join(dirPath, item);
88
+ return fs.statSync(itemPath).isDirectory() && !item.startsWith('.');
89
+ });
90
+ for (const subdir of subdirs) {
91
+ const entityPath = path.join(pattern.dir, subdir);
92
+ const fullPath = path.join(workspaceRoot, entityPath);
93
+ // Check if it's a git repository or has package.json
94
+ const hasGit = fs.existsSync(path.join(fullPath, '.git'));
95
+ const hasPackageJson = fs.existsSync(path.join(fullPath, 'package.json'));
96
+ if (hasGit || hasPackageJson) {
97
+ discovered.push({
98
+ name: subdir,
99
+ type: pattern.type,
100
+ path: `./${entityPath}`
101
+ });
102
+ }
103
+ }
104
+ }
105
+ }
106
+ return discovered;
107
+ }
108
+ getEntitiesByType(type) {
109
+ return this.getAllEntities().filter(e => e.type === type);
110
+ }
111
+ resolveEntityPath(entity) {
112
+ if (path.isAbsolute(entity.path)) {
113
+ return entity.path;
114
+ }
115
+ return path.join(this.configService.getWorkspaceRoot(), entity.path);
116
+ }
117
+ validateEntityName(name) {
118
+ // Entity names should be alphanumeric with hyphens/underscores
119
+ return /^[a-zA-Z0-9-_]+$/.test(name);
120
+ }
121
+ getEntityByPath(searchPath) {
122
+ const entities = this.getAllEntities();
123
+ const absoluteSearchPath = path.resolve(searchPath);
124
+ return entities.find(entity => {
125
+ const entityPath = this.resolveEntityPath(entity);
126
+ return path.resolve(entityPath) === absoluteSearchPath;
127
+ });
128
+ }
129
+ }
130
+ exports.EntityService = EntityService;
@@ -0,0 +1,70 @@
1
+ import { Entity, Focus, HistoryEntry, FocusMode, EntityType } from '../models/entity.model';
2
+ import { ConfigService } from './config.service';
3
+ export interface FocusOptions {
4
+ entityType?: EntityType;
5
+ mode?: FocusMode;
6
+ duration?: string;
7
+ }
8
+ export declare class FocusService {
9
+ private configService;
10
+ private entityService;
11
+ private focusStack;
12
+ constructor(configService: ConfigService);
13
+ getCurrentFocus(): Promise<Focus | null>;
14
+ getFocusedEntities(): Promise<Entity[]>;
15
+ setFocus(entityNames: string[], options?: FocusOptions): Promise<void>;
16
+ addToFocus(entityNames: string[], options?: FocusOptions): Promise<void>;
17
+ clearFocus(): Promise<void>;
18
+ switchToPrevious(): Promise<void>;
19
+ getRecentFocus(limit?: number): HistoryEntry[];
20
+ isFocused(entityName: string): Promise<boolean>;
21
+ getFocusDescription(): Promise<string>;
22
+ pushFocusToStack(): Promise<void>;
23
+ popFocusFromStack(): Promise<Focus | null>;
24
+ getFocusStack(): Focus[];
25
+ private generateFocusContext;
26
+ private generateAIContext;
27
+ private getPersonaForMode;
28
+ private getKnowledgeScopeForMode;
29
+ private getAvailableDataForEntity;
30
+ private getSuggestedActionsForMode;
31
+ private getRestrictedKnowledgeForMode;
32
+ private generateContextIntelligence;
33
+ private generateLearningInsights;
34
+ private generateAdaptiveSuggestions;
35
+ private generateCollaborationContext;
36
+ private generatePerformanceContext;
37
+ private getRecentActivity;
38
+ private getTeamMembers;
39
+ private getPerformanceMetrics;
40
+ private getRelatedEntities;
41
+ private getRecentPatterns;
42
+ private getBusinessContext;
43
+ private getTechnicalContext;
44
+ private determineContextType;
45
+ private assessComplexity;
46
+ private estimateFocusDuration;
47
+ private assessInterruptionRisk;
48
+ private assessSuccessProbability;
49
+ private getRecommendedApproach;
50
+ private getHistoricalPatterns;
51
+ private getSimilarEntityLessons;
52
+ private getCommonPitfalls;
53
+ private getSuccessFactors;
54
+ private getLearningOpportunities;
55
+ private getTimeBasedSuggestions;
56
+ private getDayBasedSuggestions;
57
+ private getContextSpecificTips;
58
+ private getProductivityOptimizations;
59
+ private getWorkflowSuggestions;
60
+ private getActiveTeamMembers;
61
+ private getCollaborationPatterns;
62
+ private getCommunicationPreferences;
63
+ private getSharedResources;
64
+ private getCoordinationNeeds;
65
+ private getCurrentVelocity;
66
+ private getPerformanceTrends;
67
+ private identifyBottlenecks;
68
+ private getOptimizationOpportunities;
69
+ private getBenchmarks;
70
+ }