@hyperdrive.bot/gut 0.1.4 ā 0.1.6
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 -779
- package/bin/run.js +5 -0
- package/package.json +10 -10
- package/bin/run +0 -5
- package/dist/base-command.d.ts +0 -21
- package/dist/base-command.js +0 -110
- package/dist/commands/add.d.ts +0 -13
- package/dist/commands/add.js +0 -73
- package/dist/commands/affected.d.ts +0 -23
- package/dist/commands/affected.js +0 -326
- package/dist/commands/audit.d.ts +0 -33
- package/dist/commands/audit.js +0 -593
- package/dist/commands/back.d.ts +0 -6
- package/dist/commands/back.js +0 -29
- package/dist/commands/commit.d.ts +0 -11
- package/dist/commands/commit.js +0 -113
- package/dist/commands/context.d.ts +0 -6
- package/dist/commands/context.js +0 -36
- package/dist/commands/contexts.d.ts +0 -7
- package/dist/commands/contexts.js +0 -92
- package/dist/commands/deps.d.ts +0 -10
- package/dist/commands/deps.js +0 -104
- package/dist/commands/entity/add.d.ts +0 -16
- package/dist/commands/entity/add.js +0 -105
- package/dist/commands/entity/clone-all.d.ts +0 -17
- package/dist/commands/entity/clone-all.js +0 -135
- package/dist/commands/entity/clone.d.ts +0 -15
- package/dist/commands/entity/clone.js +0 -109
- package/dist/commands/entity/list.d.ts +0 -11
- package/dist/commands/entity/list.js +0 -82
- package/dist/commands/entity/remove.d.ts +0 -12
- package/dist/commands/entity/remove.js +0 -58
- package/dist/commands/focus.d.ts +0 -19
- package/dist/commands/focus.js +0 -139
- package/dist/commands/graph.d.ts +0 -18
- package/dist/commands/graph.js +0 -238
- package/dist/commands/init.d.ts +0 -11
- package/dist/commands/init.js +0 -84
- package/dist/commands/insights.d.ts +0 -21
- package/dist/commands/insights.js +0 -434
- package/dist/commands/patterns.d.ts +0 -40
- package/dist/commands/patterns.js +0 -412
- package/dist/commands/pull.d.ts +0 -11
- package/dist/commands/pull.js +0 -121
- package/dist/commands/push.d.ts +0 -11
- package/dist/commands/push.js +0 -101
- package/dist/commands/quick-setup.d.ts +0 -20
- package/dist/commands/quick-setup.js +0 -422
- package/dist/commands/recent.d.ts +0 -9
- package/dist/commands/recent.js +0 -55
- package/dist/commands/related.d.ts +0 -23
- package/dist/commands/related.js +0 -257
- package/dist/commands/repos.d.ts +0 -14
- package/dist/commands/repos.js +0 -185
- package/dist/commands/stack.d.ts +0 -10
- package/dist/commands/stack.js +0 -83
- package/dist/commands/status.d.ts +0 -14
- package/dist/commands/status.js +0 -246
- package/dist/commands/sync.d.ts +0 -11
- package/dist/commands/sync.js +0 -142
- package/dist/commands/unfocus.d.ts +0 -6
- package/dist/commands/unfocus.js +0 -23
- package/dist/commands/used-by.d.ts +0 -10
- package/dist/commands/used-by.js +0 -111
- package/dist/commands/workspace.d.ts +0 -20
- package/dist/commands/workspace.js +0 -365
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -5
- package/dist/models/entity.model.d.ts +0 -81
- package/dist/models/entity.model.js +0 -2
- package/dist/services/config.service.d.ts +0 -34
- package/dist/services/config.service.js +0 -230
- package/dist/services/entity.service.d.ts +0 -19
- package/dist/services/entity.service.js +0 -130
- package/dist/services/focus.service.d.ts +0 -70
- package/dist/services/focus.service.js +0 -587
- package/dist/services/git.service.d.ts +0 -37
- package/dist/services/git.service.js +0 -180
- package/dist/utils/display.d.ts +0 -25
- package/dist/utils/display.js +0 -150
- package/dist/utils/filesystem.d.ts +0 -32
- package/dist/utils/filesystem.js +0 -220
- package/dist/utils/index.d.ts +0 -13
- package/dist/utils/index.js +0 -18
- package/dist/utils/validation.d.ts +0 -22
- package/dist/utils/validation.js +0 -196
- package/oclif.manifest.json +0 -1463
package/dist/commands/status.js
DELETED
|
@@ -1,246 +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
|
-
class Status extends base_command_1.BaseCommand {
|
|
8
|
-
static description = 'Show git status for focused entities';
|
|
9
|
-
static examples = [
|
|
10
|
-
'<%= config.bin %> <%= command.id %>',
|
|
11
|
-
'<%= config.bin %> <%= command.id %> --all',
|
|
12
|
-
'<%= config.bin %> <%= command.id %> --verbose',
|
|
13
|
-
];
|
|
14
|
-
static flags = {
|
|
15
|
-
all: core_1.Flags.boolean({
|
|
16
|
-
char: 'a',
|
|
17
|
-
description: 'show status for all entities',
|
|
18
|
-
}),
|
|
19
|
-
verbose: core_1.Flags.boolean({
|
|
20
|
-
char: 'v',
|
|
21
|
-
description: 'show detailed status',
|
|
22
|
-
}),
|
|
23
|
-
json: core_1.Flags.boolean({
|
|
24
|
-
description: 'output as JSON',
|
|
25
|
-
}),
|
|
26
|
-
};
|
|
27
|
-
async run() {
|
|
28
|
-
const { flags } = await this.parse(Status);
|
|
29
|
-
// Get entities to check
|
|
30
|
-
let entities = flags.all
|
|
31
|
-
? this.entityService.getAllEntities()
|
|
32
|
-
: await this.focusService.getFocusedEntities();
|
|
33
|
-
if (entities.length === 0) {
|
|
34
|
-
if (flags.all) {
|
|
35
|
-
this.error('No entities configured');
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
this.error('No entities focused. Use "gut focus <entity>" first.');
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
// Collect status for each entity
|
|
42
|
-
const statuses = [];
|
|
43
|
-
for (const entity of entities) {
|
|
44
|
-
const entityPath = this.entityService.resolveEntityPath(entity);
|
|
45
|
-
try {
|
|
46
|
-
// Check if it's a git repository
|
|
47
|
-
const isRepo = await this.gitService.isRepository(entityPath);
|
|
48
|
-
if (isRepo) {
|
|
49
|
-
const status = await this.gitService.getStatus(entityPath);
|
|
50
|
-
statuses.push({
|
|
51
|
-
...status,
|
|
52
|
-
entity: entity.name,
|
|
53
|
-
type: entity.type,
|
|
54
|
-
hasChanges: status.hasChanges,
|
|
55
|
-
error: undefined
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
statuses.push({
|
|
60
|
-
entity: entity.name,
|
|
61
|
-
type: entity.type,
|
|
62
|
-
path: entityPath,
|
|
63
|
-
branch: '',
|
|
64
|
-
ahead: 0,
|
|
65
|
-
behind: 0,
|
|
66
|
-
changes: [],
|
|
67
|
-
untracked: [],
|
|
68
|
-
hasChanges: false,
|
|
69
|
-
error: 'Not a git repository'
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
catch (error) {
|
|
74
|
-
statuses.push({
|
|
75
|
-
entity: entity.name,
|
|
76
|
-
type: entity.type,
|
|
77
|
-
path: entityPath,
|
|
78
|
-
branch: '',
|
|
79
|
-
ahead: 0,
|
|
80
|
-
behind: 0,
|
|
81
|
-
changes: [],
|
|
82
|
-
untracked: [],
|
|
83
|
-
hasChanges: false,
|
|
84
|
-
error: error.message
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
// Output results
|
|
89
|
-
if (flags.json) {
|
|
90
|
-
this.log(JSON.stringify(statuses, null, 2));
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
// Enhanced workspace-style display
|
|
94
|
-
await this.displayEnhancedStatus(statuses, flags.verbose, flags.json);
|
|
95
|
-
}
|
|
96
|
-
displayStatus(status, verbose) {
|
|
97
|
-
const icon = this.getTypeEmoji(status.type);
|
|
98
|
-
const statusIcon = status.error
|
|
99
|
-
? 'ā'
|
|
100
|
-
: status.hasChanges
|
|
101
|
-
? 'ā'
|
|
102
|
-
: 'ā';
|
|
103
|
-
this.log(`${icon} ${status.entity} ${statusIcon}`);
|
|
104
|
-
if (status.error) {
|
|
105
|
-
this.log(` Error: ${status.error}`);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
this.log(` Branch: ${status.branch}`);
|
|
109
|
-
// Show ahead/behind
|
|
110
|
-
if (status.ahead > 0 || status.behind > 0) {
|
|
111
|
-
const ahead = status.ahead > 0 ? `ā${status.ahead}` : '';
|
|
112
|
-
const behind = status.behind > 0 ? `ā${status.behind}` : '';
|
|
113
|
-
this.log(` Remote: ${ahead} ${behind}`.trim());
|
|
114
|
-
}
|
|
115
|
-
// Show changes
|
|
116
|
-
if (status.changes.length > 0) {
|
|
117
|
-
this.log(` Modified: ${status.changes.length} files`);
|
|
118
|
-
if (verbose) {
|
|
119
|
-
status.changes.slice(0, 5).forEach((change) => {
|
|
120
|
-
this.log(` ${change}`);
|
|
121
|
-
});
|
|
122
|
-
if (status.changes.length > 5) {
|
|
123
|
-
this.log(` ... and ${status.changes.length - 5} more`);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
// Show untracked
|
|
128
|
-
if (status.untracked.length > 0) {
|
|
129
|
-
this.log(` Untracked: ${status.untracked.length} files`);
|
|
130
|
-
if (verbose) {
|
|
131
|
-
status.untracked.slice(0, 5).forEach((file) => {
|
|
132
|
-
this.log(` ${file}`);
|
|
133
|
-
});
|
|
134
|
-
if (status.untracked.length > 5) {
|
|
135
|
-
this.log(` ... and ${status.untracked.length - 5} more`);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
if (!status.hasChanges && status.ahead === 0 && status.behind === 0) {
|
|
140
|
-
this.log(` Clean and up to date`);
|
|
141
|
-
}
|
|
142
|
-
this.log(''); // Empty line between entities
|
|
143
|
-
}
|
|
144
|
-
async displayEnhancedStatus(statuses, verbose, json) {
|
|
145
|
-
const currentFocus = await this.focusService.getCurrentFocus();
|
|
146
|
-
const focusedEntities = await this.focusService.getFocusedEntities();
|
|
147
|
-
// Header with workspace context
|
|
148
|
-
this.log(chalk_1.default.bold('\n=== DevSquad Workspace Status ==='));
|
|
149
|
-
if (currentFocus) {
|
|
150
|
-
const focusDescription = await this.focusService.getFocusDescription();
|
|
151
|
-
this.log(`š Current focus: ${chalk_1.default.cyan(focusDescription)}`);
|
|
152
|
-
if (currentFocus.mode) {
|
|
153
|
-
this.log(`šÆ Mode: ${chalk_1.default.yellow(currentFocus.mode)}`);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
this.log(`š Current focus: ${chalk_1.default.dim('none')}`);
|
|
158
|
-
}
|
|
159
|
-
// Last sync info (placeholder for now)
|
|
160
|
-
this.log(`š Last sync: ${chalk_1.default.dim('just now')}`);
|
|
161
|
-
this.log('');
|
|
162
|
-
// Group statuses by entity type
|
|
163
|
-
const byType = statuses.reduce((acc, status) => {
|
|
164
|
-
if (!acc[status.type])
|
|
165
|
-
acc[status.type] = [];
|
|
166
|
-
acc[status.type].push(status);
|
|
167
|
-
return acc;
|
|
168
|
-
}, {});
|
|
169
|
-
// Display entities by type
|
|
170
|
-
const typeOrder = ['client', 'prospect', 'company', 'initiative', 'system', 'delivery', 'module', 'service', 'tool'];
|
|
171
|
-
for (const type of typeOrder) {
|
|
172
|
-
if (!byType[type] || byType[type].length === 0)
|
|
173
|
-
continue;
|
|
174
|
-
const entities = byType[type];
|
|
175
|
-
const dirtyCount = entities.filter((e) => e.hasChanges).length;
|
|
176
|
-
if (dirtyCount > 0) {
|
|
177
|
-
this.log(chalk_1.default.bold(`${type.toUpperCase()}:`));
|
|
178
|
-
for (const status of entities) {
|
|
179
|
-
if (status.hasChanges) {
|
|
180
|
-
this.displayEntityStatus(status, verbose);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
this.log('');
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
// Show clean entities if verbose
|
|
187
|
-
if (verbose) {
|
|
188
|
-
const cleanEntities = statuses.filter(s => !s.hasChanges && !s.error);
|
|
189
|
-
if (cleanEntities.length > 0) {
|
|
190
|
-
this.log(chalk_1.default.dim('CLEAN:'));
|
|
191
|
-
for (const status of cleanEntities) {
|
|
192
|
-
this.log(` ${this.getTypeEmoji(status.type)} ${status.entity}/ ${chalk_1.default.dim('(clean)')}`);
|
|
193
|
-
}
|
|
194
|
-
this.log('');
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
// Enhanced summary
|
|
198
|
-
const dirtyRepos = statuses.filter(s => s.hasChanges).length;
|
|
199
|
-
const totalRepos = statuses.filter(s => !s.error).length;
|
|
200
|
-
const readyToCommit = statuses.filter(s => s.hasChanges).map(s => s.entity);
|
|
201
|
-
this.log(chalk_1.default.bold('=== Summary ==='));
|
|
202
|
-
if (dirtyRepos === 0) {
|
|
203
|
-
this.log(`⨠All ${totalRepos} repositories are clean`);
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
this.log(`⨠${dirtyRepos} ${dirtyRepos === 1 ? 'repo' : 'repos'} with changes`);
|
|
207
|
-
if (readyToCommit.length > 0) {
|
|
208
|
-
this.log(`š Ready to commit across: ${chalk_1.default.cyan(readyToCommit.join(', '))}`);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
// Suggested actions
|
|
212
|
-
if (dirtyRepos > 0) {
|
|
213
|
-
this.log('');
|
|
214
|
-
this.log(chalk_1.default.dim('Suggested actions:'));
|
|
215
|
-
this.log(chalk_1.default.dim(`⢠gut add . # Stage all changes`));
|
|
216
|
-
this.log(chalk_1.default.dim(`⢠gut commit -m "..." # Commit across repos`));
|
|
217
|
-
this.log(chalk_1.default.dim(`⢠gut push # Push to remotes`));
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
displayEntityStatus(status, verbose) {
|
|
221
|
-
const changesText = status.changes.length > 0 ? `${status.changes.length} changes` : '';
|
|
222
|
-
const untrackedText = status.untracked.length > 0 ? `${status.untracked.length} untracked` : '';
|
|
223
|
-
const statusText = [changesText, untrackedText].filter(Boolean).join(', ');
|
|
224
|
-
this.log(` ${status.entity}/ ${chalk_1.default.green('š¢')} ${statusText}`);
|
|
225
|
-
if (verbose) {
|
|
226
|
-
// Show specific files
|
|
227
|
-
if (status.changes.length > 0) {
|
|
228
|
-
status.changes.slice(0, 3).forEach((change) => {
|
|
229
|
-
this.log(` M ${change}`);
|
|
230
|
-
});
|
|
231
|
-
if (status.changes.length > 3) {
|
|
232
|
-
this.log(` ... and ${status.changes.length - 3} more`);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
if (status.untracked.length > 0) {
|
|
236
|
-
status.untracked.slice(0, 2).forEach((file) => {
|
|
237
|
-
this.log(` A ${file}`);
|
|
238
|
-
});
|
|
239
|
-
if (status.untracked.length > 2) {
|
|
240
|
-
this.log(` ... and ${status.untracked.length - 2} more`);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
exports.default = Status;
|
package/dist/commands/sync.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../base-command';
|
|
2
|
-
export default class Sync extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static flags: {
|
|
6
|
-
rebase: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
7
|
-
force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
8
|
-
'no-push': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
|
-
};
|
|
10
|
-
run(): Promise<void>;
|
|
11
|
-
}
|
package/dist/commands/sync.js
DELETED
|
@@ -1,142 +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 ora_1 = tslib_1.__importDefault(require("ora"));
|
|
8
|
-
class Sync extends base_command_1.BaseCommand {
|
|
9
|
-
static description = 'Synchronize repositories with remote (fetch, merge/rebase, push)';
|
|
10
|
-
static examples = [
|
|
11
|
-
'<%= config.bin %> <%= command.id %>',
|
|
12
|
-
'<%= config.bin %> <%= command.id %> --rebase',
|
|
13
|
-
'<%= config.bin %> <%= command.id %> --force',
|
|
14
|
-
];
|
|
15
|
-
static flags = {
|
|
16
|
-
rebase: core_1.Flags.boolean({
|
|
17
|
-
char: 'r',
|
|
18
|
-
description: 'Use rebase instead of merge',
|
|
19
|
-
default: false,
|
|
20
|
-
}),
|
|
21
|
-
force: core_1.Flags.boolean({
|
|
22
|
-
char: 'f',
|
|
23
|
-
description: 'Force push after sync',
|
|
24
|
-
default: false,
|
|
25
|
-
}),
|
|
26
|
-
'no-push': core_1.Flags.boolean({
|
|
27
|
-
description: 'Skip the push step',
|
|
28
|
-
default: false,
|
|
29
|
-
}),
|
|
30
|
-
};
|
|
31
|
-
async run() {
|
|
32
|
-
const { flags } = await this.parse(Sync);
|
|
33
|
-
const focusedEntities = await this.focusService.getFocusedEntities();
|
|
34
|
-
if (focusedEntities.length === 0) {
|
|
35
|
-
this.error('No entities are focused. Use "gut focus <entity>" first.');
|
|
36
|
-
}
|
|
37
|
-
this.log(chalk_1.default.bold('\nš Synchronizing repositories with remote\n'));
|
|
38
|
-
const results = {
|
|
39
|
-
success: [],
|
|
40
|
-
failed: [],
|
|
41
|
-
partial: [],
|
|
42
|
-
};
|
|
43
|
-
for (const entity of focusedEntities) {
|
|
44
|
-
const spinner = (0, ora_1.default)(`Syncing ${chalk_1.default.cyan(entity.name)}`).start();
|
|
45
|
-
let currentStep = 'fetch';
|
|
46
|
-
try {
|
|
47
|
-
// Check if there's a remote configured
|
|
48
|
-
const remoteOutput = await this.gitService.exec(['remote', '-v'], { cwd: entity.path });
|
|
49
|
-
if (!remoteOutput || remoteOutput.trim().length === 0) {
|
|
50
|
-
spinner.warn(chalk_1.default.yellow(`${entity.name}: No remote configured`));
|
|
51
|
-
results.failed.push({ repo: entity.name, error: 'No remote configured', step: 'check' });
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
// Step 1: Fetch
|
|
55
|
-
spinner.text = `${chalk_1.default.cyan(entity.name)}: Fetching from remote...`;
|
|
56
|
-
await this.gitService.fetch(entity.path);
|
|
57
|
-
// Step 2: Check status
|
|
58
|
-
currentStep = 'status';
|
|
59
|
-
const status = await this.gitService.getStatus(entity.path);
|
|
60
|
-
const hasUncommitted = status.changes.length > 0;
|
|
61
|
-
if (hasUncommitted) {
|
|
62
|
-
spinner.warn(chalk_1.default.yellow(`${entity.name}: Has uncommitted changes (fetch completed)`));
|
|
63
|
-
results.partial.push({ repo: entity.name, step: 'Fetched only - uncommitted changes present' });
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
// Step 3: Pull (merge or rebase)
|
|
67
|
-
currentStep = 'pull';
|
|
68
|
-
spinner.text = `${chalk_1.default.cyan(entity.name)}: ${flags.rebase ? 'Rebasing' : 'Merging'}...`;
|
|
69
|
-
const pullOptions = {
|
|
70
|
-
rebase: flags.rebase,
|
|
71
|
-
};
|
|
72
|
-
await this.gitService.pull(entity.path, pullOptions);
|
|
73
|
-
// Step 4: Push (if not skipped)
|
|
74
|
-
if (!flags['no-push']) {
|
|
75
|
-
currentStep = 'push';
|
|
76
|
-
spinner.text = `${chalk_1.default.cyan(entity.name)}: Pushing to remote...`;
|
|
77
|
-
const pushOptions = {
|
|
78
|
-
force: flags.force,
|
|
79
|
-
};
|
|
80
|
-
await this.gitService.push(entity.path, pushOptions);
|
|
81
|
-
}
|
|
82
|
-
spinner.succeed(chalk_1.default.green(`ā ${entity.name}: Fully synchronized`));
|
|
83
|
-
results.success.push(entity.name);
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
const errorMessage = error.message || error.toString();
|
|
87
|
-
if (errorMessage.includes('Already up to date') && currentStep === 'pull') {
|
|
88
|
-
// Not an error, just nothing to pull
|
|
89
|
-
if (!flags['no-push']) {
|
|
90
|
-
try {
|
|
91
|
-
currentStep = 'push';
|
|
92
|
-
spinner.text = `${chalk_1.default.cyan(entity.name)}: Pushing to remote...`;
|
|
93
|
-
const pushOptions = { force: flags.force };
|
|
94
|
-
await this.gitService.push(entity.path, pushOptions);
|
|
95
|
-
spinner.succeed(chalk_1.default.green(`ā ${entity.name}: Fully synchronized`));
|
|
96
|
-
results.success.push(entity.name);
|
|
97
|
-
}
|
|
98
|
-
catch (pushError) {
|
|
99
|
-
spinner.warn(chalk_1.default.yellow(`${entity.name}: Up-to-date locally, push failed`));
|
|
100
|
-
results.partial.push({ repo: entity.name, step: `Pull up-to-date, push failed: ${pushError.message}` });
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
spinner.succeed(chalk_1.default.green(`ā ${entity.name}: Up-to-date`));
|
|
105
|
-
results.success.push(entity.name);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
spinner.fail(chalk_1.default.red(`ā ${entity.name}: Failed at ${currentStep}`));
|
|
110
|
-
results.failed.push({ repo: entity.name, error: errorMessage, step: currentStep });
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
// Summary
|
|
115
|
-
this.log(chalk_1.default.bold('\nš Sync Summary'));
|
|
116
|
-
this.log(chalk_1.default.dim('ā'.repeat(50)));
|
|
117
|
-
if (results.success.length > 0) {
|
|
118
|
-
this.log(chalk_1.default.green(`ā Fully synced: ${results.success.length} entities`));
|
|
119
|
-
for (const repo of results.success) {
|
|
120
|
-
this.log(chalk_1.default.green(` - ${repo}`));
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
if (results.partial.length > 0) {
|
|
124
|
-
this.log(chalk_1.default.yellow(`ā Partially synced: ${results.partial.length} entities`));
|
|
125
|
-
for (const partial of results.partial) {
|
|
126
|
-
this.log(chalk_1.default.yellow(` - ${partial.repo}: ${partial.step}`));
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (results.failed.length > 0) {
|
|
130
|
-
this.log(chalk_1.default.red(`ā Failed: ${results.failed.length} entities`));
|
|
131
|
-
for (const failure of results.failed) {
|
|
132
|
-
this.log(chalk_1.default.red(` - ${failure.repo}: ${failure.error} (at ${failure.step})`));
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
this.log(chalk_1.default.dim('\nā'.repeat(50)));
|
|
136
|
-
this.log(chalk_1.default.dim('Sync performs: fetch ā pull ā push'));
|
|
137
|
-
if (results.partial.length > 0 || results.failed.length > 0) {
|
|
138
|
-
this.log(chalk_1.default.dim('Tip: Use "gut status" to check repository states'));
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
exports.default = Sync;
|
package/dist/commands/unfocus.js
DELETED
|
@@ -1,23 +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 Unfocus extends base_command_1.BaseCommand {
|
|
7
|
-
static description = 'Clear the current focus';
|
|
8
|
-
static examples = [
|
|
9
|
-
'<%= config.bin %> <%= command.id %>',
|
|
10
|
-
];
|
|
11
|
-
async run() {
|
|
12
|
-
await this.parse(Unfocus);
|
|
13
|
-
const focusedEntities = await this.focusService.getFocusedEntities();
|
|
14
|
-
if (focusedEntities.length === 0) {
|
|
15
|
-
this.log(chalk_1.default.yellow('No entities are currently focused'));
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
await this.focusService.clearFocus();
|
|
19
|
-
const entities = focusedEntities.map(e => e.name).join(', ');
|
|
20
|
-
this.log(chalk_1.default.green(`ā Cleared focus from: ${entities}`));
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
exports.default = Unfocus;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../base-command';
|
|
2
|
-
export default class UsedBy extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static args: {
|
|
6
|
-
entity: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
-
};
|
|
8
|
-
run(): Promise<void>;
|
|
9
|
-
private analyzeUsage;
|
|
10
|
-
}
|
package/dist/commands/used-by.js
DELETED
|
@@ -1,111 +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
|
-
class UsedBy extends base_command_1.BaseCommand {
|
|
8
|
-
static description = 'Show what entities depend on current focus or specified entity';
|
|
9
|
-
static examples = [
|
|
10
|
-
'<%= config.bin %> <%= command.id %>',
|
|
11
|
-
'<%= config.bin %> <%= command.id %> api',
|
|
12
|
-
];
|
|
13
|
-
static args = {
|
|
14
|
-
entity: core_1.Args.string({
|
|
15
|
-
name: 'entity',
|
|
16
|
-
required: false,
|
|
17
|
-
description: 'Entity name to analyze usage for',
|
|
18
|
-
}),
|
|
19
|
-
};
|
|
20
|
-
async run() {
|
|
21
|
-
const { args } = await this.parse(UsedBy);
|
|
22
|
-
let targetEntities = [];
|
|
23
|
-
if (args.entity) {
|
|
24
|
-
// Analyze specific entity
|
|
25
|
-
const entity = this.entityService.findEntity(args.entity);
|
|
26
|
-
if (!entity) {
|
|
27
|
-
this.error(`Entity '${args.entity}' not found`);
|
|
28
|
-
}
|
|
29
|
-
targetEntities = [entity];
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
// Analyze current focus
|
|
33
|
-
targetEntities = await this.focusService.getFocusedEntities();
|
|
34
|
-
if (targetEntities.length === 0) {
|
|
35
|
-
this.error('No entities in focus. Use "gut focus <entity>" first or specify an entity name.');
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
this.log(chalk_1.default.bold('\nš Usage Analysis'));
|
|
39
|
-
this.log(chalk_1.default.dim('ā'.repeat(50)));
|
|
40
|
-
for (const entity of targetEntities) {
|
|
41
|
-
this.log(`\n${chalk_1.default.green('āø')} ${chalk_1.default.bold(entity.name)} (${entity.type})`);
|
|
42
|
-
const usage = await this.analyzeUsage(entity);
|
|
43
|
-
if (usage.direct.length > 0) {
|
|
44
|
-
this.log(`\n ${chalk_1.default.yellow('Direct Dependents:')}`);
|
|
45
|
-
usage.direct.forEach(dep => {
|
|
46
|
-
this.log(` ${this.getTypeEmoji(dep.type)} ${dep.name} (${dep.type})`);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
if (usage.clients.length > 0) {
|
|
50
|
-
this.log(`\n ${chalk_1.default.blue('Client Dependencies:')}`);
|
|
51
|
-
usage.clients.forEach(dep => {
|
|
52
|
-
this.log(` ${this.getTypeEmoji(dep.type)} ${dep.name} (${dep.type})`);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
if (usage.inferred.length > 0) {
|
|
56
|
-
this.log(`\n ${chalk_1.default.dim('Inferred Usage:')}`);
|
|
57
|
-
usage.inferred.forEach(dep => {
|
|
58
|
-
this.log(` ${this.getTypeEmoji(dep.type)} ${dep.name} (${dep.type}) ${chalk_1.default.dim('- pattern based')}`);
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
if (usage.direct.length === 0 && usage.clients.length === 0 && usage.inferred.length === 0) {
|
|
62
|
-
this.log(` ${chalk_1.default.dim('No dependents found')}`);
|
|
63
|
-
}
|
|
64
|
-
// Show impact assessment
|
|
65
|
-
const totalDependents = usage.direct.length + usage.clients.length + usage.inferred.length;
|
|
66
|
-
if (totalDependents > 0) {
|
|
67
|
-
this.log(`\n ${chalk_1.default.cyan('Impact Assessment:')}`);
|
|
68
|
-
this.log(` ${chalk_1.default.dim('Total dependents:')} ${totalDependents}`);
|
|
69
|
-
const criticalDependents = usage.direct.filter(e => e.type === 'client').length;
|
|
70
|
-
if (criticalDependents > 0) {
|
|
71
|
-
this.log(` ${chalk_1.default.red('Critical client dependencies:')} ${criticalDependents}`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
this.log(chalk_1.default.dim('\nā'.repeat(50)));
|
|
76
|
-
this.log(chalk_1.default.dim('Usage analysis helps assess impact of changes'));
|
|
77
|
-
}
|
|
78
|
-
async analyzeUsage(entity) {
|
|
79
|
-
const allEntities = this.entityService.getAllEntities();
|
|
80
|
-
// Direct dependents (entities that explicitly list this as dependency)
|
|
81
|
-
const directDependents = allEntities.filter(e => e.metadata?.relationships?.dependent_systems?.includes(entity.name) ||
|
|
82
|
-
e.metadata?.relationships?.similar_entities?.includes(entity.name));
|
|
83
|
-
// Client dependencies (if this is a system, all clients likely depend on it)
|
|
84
|
-
const clientDependents = [];
|
|
85
|
-
if (entity.type === 'system' || entity.type === 'module' || entity.type === 'service') {
|
|
86
|
-
clientDependents.push(...allEntities.filter(e => e.type === 'client'));
|
|
87
|
-
}
|
|
88
|
-
// Inferred usage based on patterns
|
|
89
|
-
const inferredDependents = [];
|
|
90
|
-
// If this is a design system or shared module
|
|
91
|
-
if (entity.name.includes('design') || entity.name.includes('shared') || entity.type === 'module') {
|
|
92
|
-
const potentialUsers = allEntities.filter(e => (e.type === 'client' || e.type === 'delivery') &&
|
|
93
|
-
!clientDependents.includes(e) &&
|
|
94
|
-
!directDependents.includes(e));
|
|
95
|
-
inferredDependents.push(...potentialUsers);
|
|
96
|
-
}
|
|
97
|
-
// If this is an API system
|
|
98
|
-
if (entity.name.includes('api') || entity.type === 'service') {
|
|
99
|
-
const apiUsers = allEntities.filter(e => e.type === 'client' &&
|
|
100
|
-
!clientDependents.includes(e) &&
|
|
101
|
-
!directDependents.includes(e));
|
|
102
|
-
inferredDependents.push(...apiUsers);
|
|
103
|
-
}
|
|
104
|
-
return {
|
|
105
|
-
direct: directDependents,
|
|
106
|
-
clients: clientDependents.filter(e => !directDependents.includes(e)),
|
|
107
|
-
inferred: inferredDependents.slice(0, 5) // Limit to avoid clutter
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
exports.default = UsedBy;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../base-command';
|
|
2
|
-
export default class Workspace extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static args: {
|
|
6
|
-
action: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
-
};
|
|
8
|
-
static flags: {
|
|
9
|
-
force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
-
'entity-type': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
-
};
|
|
12
|
-
run(): Promise<void>;
|
|
13
|
-
private initWorkspaceStructure;
|
|
14
|
-
private showWorkspaceStructure;
|
|
15
|
-
private showDirectoryTree;
|
|
16
|
-
private generateEntityMetadata;
|
|
17
|
-
private generateWorkspaceConfig;
|
|
18
|
-
private generateContextsConfig;
|
|
19
|
-
private generateEntityMetadataContent;
|
|
20
|
-
}
|