@wundr.io/cli 1.0.1 → 1.0.2-dev.20260530174250.ef0ec927
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/bin/wundr.js +13 -5
- package/package.json +30 -9
- package/src/ai/ai-service.ts +6 -4
- package/src/ai/claude-client.ts +6 -2
- package/src/ai/conversation-manager.ts +12 -5
- package/src/cli.ts +42 -13
- package/src/commands/ai.ts +340 -64
- package/src/commands/alignment.ts +1212 -0
- package/src/commands/analyze-optimized.ts +371 -33
- package/src/commands/analyze.ts +8 -6
- package/src/commands/batch.ts +166 -26
- package/src/commands/chat.ts +20 -10
- package/src/commands/claude-init.ts +31 -27
- package/src/commands/claude-setup.ts +761 -81
- package/src/commands/computer-setup.ts +524 -12
- package/src/commands/create-command.ts +3 -3
- package/src/commands/create.ts +9 -6
- package/src/commands/dashboard.ts +11 -6
- package/src/commands/govern.ts +11 -6
- package/src/commands/governance.ts +1005 -0
- package/src/commands/guardian.ts +887 -0
- package/src/commands/init.ts +104 -11
- package/src/commands/orchestrator.ts +789 -0
- package/src/commands/performance-optimizer.ts +15 -10
- package/src/commands/plugins.ts +8 -5
- package/src/commands/project-update.ts +1156 -0
- package/src/commands/rag.ts +1011 -0
- package/src/commands/session.ts +631 -0
- package/src/commands/setup.ts +42 -344
- package/src/commands/test-init.ts +3 -2
- package/src/commands/test.ts +3 -2
- package/src/commands/watch.ts +21 -11
- package/src/commands/worktree.ts +1057 -0
- package/src/context/context-manager.ts +5 -2
- package/src/context/session-manager.ts +18 -7
- package/src/framework/command-interface.ts +520 -0
- package/src/framework/command-registry.ts +942 -0
- package/src/framework/completion-exporter.ts +383 -0
- package/src/framework/debug-logger.ts +519 -0
- package/src/framework/error-handler.ts +867 -0
- package/src/framework/help-generator.ts +540 -0
- package/src/framework/index.ts +169 -0
- package/src/framework/interactive-repl.ts +703 -0
- package/src/framework/output-formatter.ts +834 -0
- package/src/framework/progress-manager.ts +539 -0
- package/src/index.ts +3 -2
- package/src/interactive/interactive-mode.ts +14 -7
- package/src/lib/conflict-resolution.ts +818 -0
- package/src/lib/merge-strategy.ts +550 -0
- package/src/lib/safety-mechanisms.ts +451 -0
- package/src/lib/state-detection.ts +1030 -0
- package/src/nlp/command-mapper.ts +8 -3
- package/src/nlp/command-parser.ts +5 -2
- package/src/nlp/intent-parser.ts +23 -9
- package/src/plugins/plugin-manager.ts +50 -24
- package/src/tests/computer-setup-integration.test.ts +46 -15
- package/src/types/index.ts +1 -1
- package/src/types/modules.d.ts +425 -1
- package/src/utils/backup-rollback-manager.ts +19 -14
- package/src/utils/claude-config-installer.ts +119 -28
- package/src/utils/config-manager.ts +9 -6
- package/src/utils/error-handler.ts +3 -1
- package/src/utils/logger.ts +35 -12
- package/templates/batch/ci-cd.yaml +7 -7
- package/test-suites/api/health.spec.ts +20 -23
- package/test-suites/helpers/test-config.ts +14 -13
- package/test-suites/ui/accessibility.spec.ts +27 -22
- package/test-suites/ui/smoke.spec.ts +26 -21
- package/src/commands/computer-setup-commands.ts +0 -869
package/src/types/modules.d.ts
CHANGED
|
@@ -1,4 +1,416 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
|
|
2
|
+
/**
|
|
3
|
+
* Ambient module declarations for workspace packages that may not be built.
|
|
4
|
+
*
|
|
5
|
+
* These declarations provide type stubs so the CLI package compiles
|
|
6
|
+
* independently of whether sibling workspace packages have been built.
|
|
7
|
+
* When the real packages are built and resolvable, TypeScript will prefer
|
|
8
|
+
* their actual declarations over these ambient ones.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// @wundr.io/computer-setup
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
declare module '@wundr.io/computer-setup' {
|
|
16
|
+
import { EventEmitter } from 'events';
|
|
17
|
+
|
|
18
|
+
export interface DeveloperProfile {
|
|
19
|
+
name: string;
|
|
20
|
+
email?: string;
|
|
21
|
+
role: string;
|
|
22
|
+
team?: string;
|
|
23
|
+
company?: string;
|
|
24
|
+
preferences?: ProfilePreferences;
|
|
25
|
+
languages?: Record<string, boolean>;
|
|
26
|
+
frameworks?: Record<string, boolean>;
|
|
27
|
+
tools: {
|
|
28
|
+
packageManagers?: Record<string, boolean>;
|
|
29
|
+
containers?: Record<string, boolean>;
|
|
30
|
+
editors?: Record<string, boolean>;
|
|
31
|
+
databases?: Record<string, boolean>;
|
|
32
|
+
cloud?: Record<string, boolean>;
|
|
33
|
+
ci?: Record<string, boolean>;
|
|
34
|
+
languages?: Record<string, boolean>;
|
|
35
|
+
cloudCLIs?: Record<string, boolean>;
|
|
36
|
+
monitoring?: Record<string, boolean>;
|
|
37
|
+
communication?: Record<string, boolean>;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface ProfilePreferences {
|
|
42
|
+
shell: 'bash' | 'zsh' | 'fish';
|
|
43
|
+
editor: 'vscode' | 'vim' | 'neovim' | 'sublime' | 'intellij';
|
|
44
|
+
theme: 'dark' | 'light' | 'auto';
|
|
45
|
+
gitConfig: {
|
|
46
|
+
userName: string;
|
|
47
|
+
userEmail: string;
|
|
48
|
+
signCommits: boolean;
|
|
49
|
+
gpgKey?: string;
|
|
50
|
+
sshKey?: string;
|
|
51
|
+
defaultBranch: string;
|
|
52
|
+
aliases: Record<string, string>;
|
|
53
|
+
};
|
|
54
|
+
aiTools: {
|
|
55
|
+
claudeCode: boolean;
|
|
56
|
+
ruflo: boolean;
|
|
57
|
+
mcpTools: string[];
|
|
58
|
+
swarmAgents: string[];
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface SetupPlatform {
|
|
63
|
+
os: 'darwin' | 'linux' | 'win32';
|
|
64
|
+
arch: 'x64' | 'arm64';
|
|
65
|
+
distro?: string;
|
|
66
|
+
version?: string;
|
|
67
|
+
node?: string;
|
|
68
|
+
shell?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface SetupResult {
|
|
72
|
+
success: boolean;
|
|
73
|
+
completedSteps: string[];
|
|
74
|
+
failedSteps: string[];
|
|
75
|
+
skippedSteps: string[];
|
|
76
|
+
warnings: string[];
|
|
77
|
+
errors: Error[];
|
|
78
|
+
duration: number;
|
|
79
|
+
report?: any;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface SetupProgress {
|
|
83
|
+
totalSteps: number;
|
|
84
|
+
completedSteps: number;
|
|
85
|
+
currentStep: string;
|
|
86
|
+
percentage: number;
|
|
87
|
+
estimatedTimeRemaining: number;
|
|
88
|
+
logs: string[];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface SetupProfile {
|
|
92
|
+
name: string;
|
|
93
|
+
description: string;
|
|
94
|
+
estimatedTimeMinutes: number;
|
|
95
|
+
[key: string]: any;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ComputerSetupManager is the single setup orchestrator. (RealSetupOrchestrator
|
|
99
|
+
// and SetupOrchestrator were retired during the orchestrator consolidation.)
|
|
100
|
+
export class ComputerSetupManager extends EventEmitter {
|
|
101
|
+
static getInstance(): ComputerSetupManager;
|
|
102
|
+
initialize(): Promise<void>;
|
|
103
|
+
validateSetup(profile?: any): Promise<boolean>;
|
|
104
|
+
cleanup(): Promise<void>;
|
|
105
|
+
getProfile(name: string): Promise<DeveloperProfile>;
|
|
106
|
+
getDefaultProfile(): Promise<DeveloperProfile>;
|
|
107
|
+
getAvailableProfiles(): Promise<DeveloperProfile[]>;
|
|
108
|
+
setup(options: any): Promise<SetupResult>;
|
|
109
|
+
on(event: string, callback: Function): this;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// @wundr.io/core (supplement missing RAG exports)
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
|
|
117
|
+
declare module '@wundr.io/core' {
|
|
118
|
+
// Core exports that exist in built dist
|
|
119
|
+
export interface WundrError extends Error {
|
|
120
|
+
code?: string;
|
|
121
|
+
}
|
|
122
|
+
export interface EventBusEvent {
|
|
123
|
+
type: string;
|
|
124
|
+
payload?: unknown;
|
|
125
|
+
}
|
|
126
|
+
export type EventHandler = (event: EventBusEvent) => void | Promise<void>;
|
|
127
|
+
export interface EventBus {
|
|
128
|
+
emit(event: EventBusEvent): void;
|
|
129
|
+
on(type: string, handler: EventHandler): void;
|
|
130
|
+
off(type: string, handler: EventHandler): void;
|
|
131
|
+
}
|
|
132
|
+
export interface ValidationResult {
|
|
133
|
+
valid: boolean;
|
|
134
|
+
errors: string[];
|
|
135
|
+
}
|
|
136
|
+
export type UtilityFunction = (...args: any[]) => any;
|
|
137
|
+
export type AsyncUtilityFunction = (...args: any[]) => Promise<any>;
|
|
138
|
+
export interface Result<T> {
|
|
139
|
+
success: boolean;
|
|
140
|
+
data?: T;
|
|
141
|
+
error?: Error;
|
|
142
|
+
}
|
|
143
|
+
export interface BaseConfig {
|
|
144
|
+
[key: string]: unknown;
|
|
145
|
+
}
|
|
146
|
+
export type CoreEventType = string;
|
|
147
|
+
export const CORE_EVENTS: Record<string, string>;
|
|
148
|
+
|
|
149
|
+
// Logging
|
|
150
|
+
export function getLogger(name: string): any;
|
|
151
|
+
export function log(level: string, message: string, ...args: any[]): void;
|
|
152
|
+
|
|
153
|
+
// Events
|
|
154
|
+
export function getEventBus(): EventBus;
|
|
155
|
+
|
|
156
|
+
// Errors
|
|
157
|
+
export function success<T>(data: T): Result<T>;
|
|
158
|
+
export function failure(error: Error): Result<never>;
|
|
159
|
+
export function isSuccess<T>(result: Result<T>): boolean;
|
|
160
|
+
export function isFailure<T>(result: Result<T>): boolean;
|
|
161
|
+
export class BaseWundrError extends Error {
|
|
162
|
+
code: string;
|
|
163
|
+
constructor(message: string, code: string);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// RAG (not yet in built dist)
|
|
167
|
+
export interface RagInitOptions {
|
|
168
|
+
projectPath?: string;
|
|
169
|
+
projectName?: string;
|
|
170
|
+
force?: boolean;
|
|
171
|
+
skipIndexing?: boolean;
|
|
172
|
+
includePatterns?: string[];
|
|
173
|
+
excludePatterns?: string[];
|
|
174
|
+
chunkSize?: number;
|
|
175
|
+
chunkOverlap?: number;
|
|
176
|
+
embeddingModel?: string;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface RagInitResult {
|
|
180
|
+
success: boolean;
|
|
181
|
+
filesIndexed: number;
|
|
182
|
+
chunksCreated: number;
|
|
183
|
+
storePath: string;
|
|
184
|
+
configPath: string;
|
|
185
|
+
excludePath: string;
|
|
186
|
+
errors: string[];
|
|
187
|
+
warnings: string[];
|
|
188
|
+
framework: {
|
|
189
|
+
name: string;
|
|
190
|
+
projectType: string;
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function initProjectRag(
|
|
195
|
+
projectPathOrOptions: string | RagInitOptions,
|
|
196
|
+
options?: RagInitOptions
|
|
197
|
+
): Promise<RagInitResult>;
|
|
198
|
+
export function isRagInitialized(projectPath: string): Promise<boolean>;
|
|
199
|
+
export function removeRag(projectPath: string): Promise<void>;
|
|
200
|
+
export function reindexProject(projectPath: string): Promise<RagInitResult>;
|
|
201
|
+
|
|
202
|
+
export const version: string;
|
|
203
|
+
export const name: string;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
207
|
+
// @wundr.io/governance
|
|
208
|
+
// ---------------------------------------------------------------------------
|
|
209
|
+
|
|
210
|
+
declare module '@wundr.io/governance' {
|
|
211
|
+
export interface EvaluationContext {
|
|
212
|
+
projectPath?: string;
|
|
213
|
+
configPath?: string;
|
|
214
|
+
environment?: string;
|
|
215
|
+
evaluationId?: string;
|
|
216
|
+
timestamp?: Date;
|
|
217
|
+
source?: string;
|
|
218
|
+
repository?: string;
|
|
219
|
+
metadata?: Record<string, unknown>;
|
|
220
|
+
[key: string]: unknown;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export interface EvaluationResult {
|
|
224
|
+
passed: boolean;
|
|
225
|
+
score: number;
|
|
226
|
+
overallScore: number;
|
|
227
|
+
violations: PolicyViolation[];
|
|
228
|
+
warnings: string[];
|
|
229
|
+
details: EvaluationDetail[];
|
|
230
|
+
results: EvaluationResult[];
|
|
231
|
+
criticalIssues: string[];
|
|
232
|
+
issues: any[];
|
|
233
|
+
recommendations: any[];
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export interface EvaluationDetail {
|
|
237
|
+
evaluator: string;
|
|
238
|
+
passed: boolean;
|
|
239
|
+
score: number;
|
|
240
|
+
message: string;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export interface PolicyViolation {
|
|
244
|
+
rule: string;
|
|
245
|
+
severity: string;
|
|
246
|
+
message: string;
|
|
247
|
+
description: string;
|
|
248
|
+
policyName: string;
|
|
249
|
+
policyId: string;
|
|
250
|
+
file?: string;
|
|
251
|
+
line?: number;
|
|
252
|
+
location: string;
|
|
253
|
+
suggestion?: string;
|
|
254
|
+
suggestedFix: string;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export interface ComplianceResult {
|
|
258
|
+
compliant: boolean;
|
|
259
|
+
score: number;
|
|
260
|
+
violations: PolicyViolation[];
|
|
261
|
+
recommendations: string[];
|
|
262
|
+
passedPolicies: any[];
|
|
263
|
+
skippedPolicies: any[];
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export interface IPREConfig {
|
|
267
|
+
version: string;
|
|
268
|
+
metadata?: {
|
|
269
|
+
name?: string;
|
|
270
|
+
description?: string;
|
|
271
|
+
author?: string;
|
|
272
|
+
};
|
|
273
|
+
intent?: any;
|
|
274
|
+
policies?: any;
|
|
275
|
+
rewards?: any;
|
|
276
|
+
evaluators?: any;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export interface PolicyRule {
|
|
280
|
+
name: string;
|
|
281
|
+
description: string;
|
|
282
|
+
severity: string;
|
|
283
|
+
check: (context: EvaluationContext) => Promise<boolean>;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export interface EvaluatorSuite {
|
|
287
|
+
policyCompliance: EvaluatorAgent & {
|
|
288
|
+
checkPolicyCompliance(
|
|
289
|
+
context: EvaluationContext
|
|
290
|
+
): Promise<ComplianceResult>;
|
|
291
|
+
};
|
|
292
|
+
rewardAlignment: EvaluatorAgent;
|
|
293
|
+
driftDetection: EvaluatorAgent;
|
|
294
|
+
[key: string]: any;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export class EvaluatorAgent {
|
|
298
|
+
constructor(config: any);
|
|
299
|
+
evaluate(context: EvaluationContext): Promise<EvaluationResult>;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export function createEvaluator(config: any): EvaluatorAgent;
|
|
303
|
+
export function createEvaluatorSuite(configs?: any): EvaluatorSuite;
|
|
304
|
+
export function runEvaluatorSuite(
|
|
305
|
+
suite: EvaluatorAgent[] | EvaluatorSuite,
|
|
306
|
+
context: EvaluationContext
|
|
307
|
+
): Promise<EvaluationResult>;
|
|
308
|
+
|
|
309
|
+
export class PolicyEngine {
|
|
310
|
+
constructor(config?: any);
|
|
311
|
+
loadPolicies(path: string): Promise<void>;
|
|
312
|
+
check(context: EvaluationContext): Promise<ComplianceResult>;
|
|
313
|
+
addRule(rule: PolicyRule): void;
|
|
314
|
+
getViolationStats(): {
|
|
315
|
+
total: number;
|
|
316
|
+
bySeverity: Record<string, number>;
|
|
317
|
+
byCategory: Record<string, number>;
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export const version: string;
|
|
322
|
+
export const name: string;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// ---------------------------------------------------------------------------
|
|
326
|
+
// @wundr.io/guardian-dashboard
|
|
327
|
+
// ---------------------------------------------------------------------------
|
|
328
|
+
|
|
329
|
+
declare module '@wundr.io/guardian-dashboard' {
|
|
330
|
+
export type HealthStatus =
|
|
331
|
+
| 'healthy'
|
|
332
|
+
| 'degraded'
|
|
333
|
+
| 'unhealthy'
|
|
334
|
+
| 'unknown'
|
|
335
|
+
| 'HEALTHY'
|
|
336
|
+
| 'CONCERNING'
|
|
337
|
+
| 'CRITICAL'
|
|
338
|
+
| 'DEGRADED'
|
|
339
|
+
| 'UNHEALTHY'
|
|
340
|
+
| 'UNKNOWN';
|
|
341
|
+
export type InterventionSeverity = 'critical' | 'high' | 'medium' | 'low';
|
|
342
|
+
|
|
343
|
+
export interface SessionDriftData {
|
|
344
|
+
sessionId: string;
|
|
345
|
+
driftScore: number;
|
|
346
|
+
timestamp: Date;
|
|
347
|
+
metrics: Record<string, number>;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export interface AggregatedDriftReport {
|
|
351
|
+
averageDrift: number;
|
|
352
|
+
averageScore: number;
|
|
353
|
+
maxDrift: number;
|
|
354
|
+
minScore: number;
|
|
355
|
+
maxScore: number;
|
|
356
|
+
sessionCount: number;
|
|
357
|
+
totalSessions: number;
|
|
358
|
+
overallStatus: HealthStatus;
|
|
359
|
+
trend: string;
|
|
360
|
+
trendDirection: 'improving' | 'stable' | 'degrading';
|
|
361
|
+
sessions: SessionDriftData[];
|
|
362
|
+
criticalSessions: SessionDriftData[];
|
|
363
|
+
concerningSessions: SessionDriftData[];
|
|
364
|
+
timestamp: Date;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export interface InterventionRecommendation {
|
|
368
|
+
id: string;
|
|
369
|
+
severity: InterventionSeverity;
|
|
370
|
+
title: string;
|
|
371
|
+
description: string;
|
|
372
|
+
suggestedAction: string;
|
|
373
|
+
estimatedImpact: number;
|
|
374
|
+
dimension: string;
|
|
375
|
+
action: string;
|
|
376
|
+
rationale: string;
|
|
377
|
+
urgency: number;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export interface AlignmentDriftMetrics {
|
|
381
|
+
overallDrift: number;
|
|
382
|
+
componentDrifts: Record<string, number>;
|
|
383
|
+
healthStatus: HealthStatus;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
export class AlignmentDebtCalculator {
|
|
387
|
+
constructor(config?: any);
|
|
388
|
+
calculate(metrics: AlignmentDriftMetrics): number;
|
|
389
|
+
getDebtTrend(history: AlignmentDriftMetrics[]): string;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export class DriftScoreAggregator {
|
|
393
|
+
constructor(config?: any);
|
|
394
|
+
aggregate(sessions: SessionDriftData[]): AggregatedDriftReport;
|
|
395
|
+
addSessions(sessions: SessionDriftData[]): void;
|
|
396
|
+
aggregateSessionScores(sessions: SessionDriftData[]): AggregatedDriftReport;
|
|
397
|
+
getHealthStatus(score: number): HealthStatus;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
export class InterventionRecommender {
|
|
401
|
+
constructor(config?: any);
|
|
402
|
+
recommend(report: AggregatedDriftReport): InterventionRecommendation[];
|
|
403
|
+
recommendInterventions(data: any): InterventionRecommendation[];
|
|
404
|
+
prioritize(
|
|
405
|
+
recommendations: InterventionRecommendation[]
|
|
406
|
+
): InterventionRecommendation[];
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// ---------------------------------------------------------------------------
|
|
411
|
+
// @wundr/computer-setup (legacy without .io)
|
|
412
|
+
// ---------------------------------------------------------------------------
|
|
413
|
+
|
|
2
414
|
declare module '@wundr/computer-setup' {
|
|
3
415
|
export class ComputerSetupManager {
|
|
4
416
|
static getInstance(): ComputerSetupManager;
|
|
@@ -21,6 +433,10 @@ declare module '@wundr/computer-setup' {
|
|
|
21
433
|
}
|
|
22
434
|
}
|
|
23
435
|
|
|
436
|
+
// ---------------------------------------------------------------------------
|
|
437
|
+
// @wundr/core (legacy without .io)
|
|
438
|
+
// ---------------------------------------------------------------------------
|
|
439
|
+
|
|
24
440
|
declare module '@wundr/core' {
|
|
25
441
|
export interface CoreConfig {
|
|
26
442
|
[key: string]: any;
|
|
@@ -29,6 +445,10 @@ declare module '@wundr/core' {
|
|
|
29
445
|
export function getLogger(name: string): any;
|
|
30
446
|
}
|
|
31
447
|
|
|
448
|
+
// ---------------------------------------------------------------------------
|
|
449
|
+
// @wundr/project-templates
|
|
450
|
+
// ---------------------------------------------------------------------------
|
|
451
|
+
|
|
32
452
|
declare module '@wundr/project-templates' {
|
|
33
453
|
export interface TemplateConfig {
|
|
34
454
|
name: string;
|
|
@@ -41,6 +461,10 @@ declare module '@wundr/project-templates' {
|
|
|
41
461
|
export const projectTemplates: Record<string, any>;
|
|
42
462
|
}
|
|
43
463
|
|
|
464
|
+
// ---------------------------------------------------------------------------
|
|
465
|
+
// open
|
|
466
|
+
// ---------------------------------------------------------------------------
|
|
467
|
+
|
|
44
468
|
declare module 'open' {
|
|
45
469
|
interface Options {
|
|
46
470
|
app?: string | string[];
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
* Handles backup creation and restoration for configuration files
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { existsSync } from 'fs';
|
|
6
7
|
import * as fs from 'fs/promises';
|
|
7
8
|
import * as path from 'path';
|
|
8
|
-
|
|
9
|
+
|
|
9
10
|
import chalk from 'chalk';
|
|
11
|
+
|
|
10
12
|
import { logger } from './logger';
|
|
11
13
|
|
|
12
14
|
export interface BackupMetadata {
|
|
@@ -37,8 +39,7 @@ export class BackupRollbackManager {
|
|
|
37
39
|
|
|
38
40
|
constructor(backupDir?: string) {
|
|
39
41
|
this.homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
40
|
-
this.backupDir =
|
|
41
|
-
backupDir || path.join(this.homeDir, '.wundr', 'backups');
|
|
42
|
+
this.backupDir = backupDir || path.join(this.homeDir, '.wundr', 'backups');
|
|
42
43
|
this.metadataFile = path.join(this.backupDir, 'metadata.json');
|
|
43
44
|
}
|
|
44
45
|
|
|
@@ -104,7 +105,7 @@ export class BackupRollbackManager {
|
|
|
104
105
|
|
|
105
106
|
logger.info('Backed up file', {
|
|
106
107
|
original: expandedPath,
|
|
107
|
-
backup: backupFilePath
|
|
108
|
+
backup: backupFilePath,
|
|
108
109
|
});
|
|
109
110
|
}
|
|
110
111
|
|
|
@@ -120,7 +121,7 @@ export class BackupRollbackManager {
|
|
|
120
121
|
|
|
121
122
|
logger.info('Backup created successfully', {
|
|
122
123
|
backupId,
|
|
123
|
-
filesBackedUp: backupFiles.length
|
|
124
|
+
filesBackedUp: backupFiles.length,
|
|
124
125
|
});
|
|
125
126
|
|
|
126
127
|
return metadata;
|
|
@@ -159,7 +160,7 @@ export class BackupRollbackManager {
|
|
|
159
160
|
logger.info('Rolling back', {
|
|
160
161
|
backupId: metadata.backupId,
|
|
161
162
|
dryRun,
|
|
162
|
-
files: metadata.files.length
|
|
163
|
+
files: metadata.files.length,
|
|
163
164
|
});
|
|
164
165
|
|
|
165
166
|
if (dryRun) {
|
|
@@ -181,7 +182,7 @@ export class BackupRollbackManager {
|
|
|
181
182
|
try {
|
|
182
183
|
// Create directory structure
|
|
183
184
|
await fs.mkdir(path.dirname(file.originalPath), {
|
|
184
|
-
recursive: true
|
|
185
|
+
recursive: true,
|
|
185
186
|
});
|
|
186
187
|
|
|
187
188
|
// Restore file
|
|
@@ -192,7 +193,7 @@ export class BackupRollbackManager {
|
|
|
192
193
|
} catch (error) {
|
|
193
194
|
logger.error('Failed to restore file', {
|
|
194
195
|
file: file.originalPath,
|
|
195
|
-
error
|
|
196
|
+
error,
|
|
196
197
|
});
|
|
197
198
|
failedFiles.push(file.originalPath);
|
|
198
199
|
}
|
|
@@ -201,7 +202,9 @@ export class BackupRollbackManager {
|
|
|
201
202
|
console.log(chalk.green(`\n✅ Restored ${restoredFiles.length} files`));
|
|
202
203
|
|
|
203
204
|
if (failedFiles.length > 0) {
|
|
204
|
-
console.log(
|
|
205
|
+
console.log(
|
|
206
|
+
chalk.red(`❌ Failed to restore ${failedFiles.length} files`)
|
|
207
|
+
);
|
|
205
208
|
failedFiles.forEach(file => {
|
|
206
209
|
console.log(chalk.red(` - ${file}`));
|
|
207
210
|
});
|
|
@@ -222,8 +225,9 @@ export class BackupRollbackManager {
|
|
|
222
225
|
try {
|
|
223
226
|
const content = await fs.readFile(this.metadataFile, 'utf-8');
|
|
224
227
|
const backups = JSON.parse(content) as BackupMetadata[];
|
|
225
|
-
return backups.sort(
|
|
226
|
-
|
|
228
|
+
return backups.sort(
|
|
229
|
+
(a, b) =>
|
|
230
|
+
new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
|
227
231
|
);
|
|
228
232
|
} catch (error) {
|
|
229
233
|
logger.error('Failed to list backups', error);
|
|
@@ -256,7 +260,7 @@ export class BackupRollbackManager {
|
|
|
256
260
|
if (backups.length <= retainCount) {
|
|
257
261
|
logger.info('No backups to clean up', {
|
|
258
262
|
current: backups.length,
|
|
259
|
-
retain: retainCount
|
|
263
|
+
retain: retainCount,
|
|
260
264
|
});
|
|
261
265
|
return;
|
|
262
266
|
}
|
|
@@ -273,7 +277,7 @@ export class BackupRollbackManager {
|
|
|
273
277
|
} catch (error) {
|
|
274
278
|
logger.error('Failed to delete backup', {
|
|
275
279
|
backupId: backup.backupId,
|
|
276
|
-
error
|
|
280
|
+
error,
|
|
277
281
|
});
|
|
278
282
|
}
|
|
279
283
|
}
|
|
@@ -345,7 +349,8 @@ export class BackupRollbackManager {
|
|
|
345
349
|
console.log(chalk.white('Backup ID:'), chalk.green(metadata.backupId));
|
|
346
350
|
console.log(chalk.white('Timestamp:'), chalk.gray(metadata.timestamp));
|
|
347
351
|
console.log(chalk.white('Reason:'), chalk.gray(metadata.reason));
|
|
348
|
-
console.log(
|
|
352
|
+
console.log(
|
|
353
|
+
chalk.white('Status:'),
|
|
349
354
|
metadata.success ? chalk.green('Success') : chalk.red('Failed')
|
|
350
355
|
);
|
|
351
356
|
console.log(chalk.white('Files:'), chalk.cyan(metadata.files.length));
|