claude-flow-novice 2.0.3 → 2.0.4
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/dist/src/cli/commands/guidance.js +487 -668
- package/dist/src/cli/commands/index-validate.js +18 -29
- package/dist/src/cli/commands/mcp-troubleshoot.js +230 -282
- package/dist/src/cli/commands/neural-goal-init.js +92 -125
- package/dist/src/cli/commands/swarm-exec.js +317 -393
- package/dist/src/cli/commands/swarm.js +1 -1
- package/dist/src/cli/commands/validate-framework.js +983 -1100
- package/dist/src/cli/commands/validate.js +144 -223
- package/dist/src/cli/simple-commands/__tests__/agent.test.js +265 -277
- package/dist/src/cli/simple-commands/__tests__/memory.test.js +6 -7
- package/dist/src/cli/simple-commands/__tests__/swarm.test.js +373 -356
- package/dist/src/cli/simple-commands/__tests__/task.test.js +6 -7
- package/dist/src/cli/simple-commands/agent.js +157 -193
- package/dist/src/cli/simple-commands/analysis.js +336 -446
- package/dist/src/cli/simple-commands/automation-executor.js +1095 -1339
- package/dist/src/cli/simple-commands/automation.js +481 -469
- package/dist/src/cli/simple-commands/batch-manager.js +261 -313
- package/dist/src/cli/simple-commands/claude-telemetry.js +241 -267
- package/dist/src/cli/simple-commands/claude-track.js +68 -90
- package/dist/src/cli/simple-commands/concurrent-display.js +266 -320
- package/dist/src/cli/simple-commands/config.js +245 -290
- package/dist/src/cli/simple-commands/coordination.js +182 -234
- package/dist/src/cli/simple-commands/enhanced-ui-views.js +812 -615
- package/dist/src/cli/simple-commands/enhanced-webui-complete.js +922 -981
- package/dist/src/cli/simple-commands/fix-hook-variables.js +274 -294
- package/dist/src/cli/simple-commands/github/gh-coordinator.js +378 -457
- package/dist/src/cli/simple-commands/github/github-api.js +535 -574
- package/dist/src/cli/simple-commands/github/init.js +276 -303
- package/dist/src/cli/simple-commands/github.js +222 -247
- package/dist/src/cli/simple-commands/goal.js +51 -63
- package/dist/src/cli/simple-commands/hive-mind/auto-save-middleware.js +208 -278
- package/dist/src/cli/simple-commands/hive-mind/communication.js +601 -696
- package/dist/src/cli/simple-commands/hive-mind/core.js +907 -979
- package/dist/src/cli/simple-commands/hive-mind/db-optimizer.js +406 -655
- package/dist/src/cli/simple-commands/hive-mind/mcp-wrapper.js +1125 -1245
- package/dist/src/cli/simple-commands/hive-mind/memory.js +854 -1090
- package/dist/src/cli/simple-commands/hive-mind/performance-optimizer.js +459 -574
- package/dist/src/cli/simple-commands/hive-mind/performance-test.js +263 -347
- package/dist/src/cli/simple-commands/hive-mind/queen.js +727 -768
- package/dist/src/cli/simple-commands/hive-mind/session-manager.js +745 -1049
- package/dist/src/cli/simple-commands/hive-mind-optimize.js +227 -283
- package/dist/src/cli/simple-commands/hive-mind-wizard.js +174 -217
- package/dist/src/cli/simple-commands/hive-mind.js +1842 -2283
- package/dist/src/cli/simple-commands/hive.js +90 -79
- package/dist/src/cli/simple-commands/hook-safety.js +431 -521
- package/dist/src/cli/simple-commands/hooks/session-start-soul.js +203 -254
- package/dist/src/cli/simple-commands/hooks.js +1064 -1204
- package/dist/src/cli/simple-commands/init/agent-copier.js +294 -319
- package/dist/src/cli/simple-commands/init/batch-init.js +496 -562
- package/dist/src/cli/simple-commands/init/claude-commands/claude-flow-commands.js +13 -19
- package/dist/src/cli/simple-commands/init/claude-commands/optimized-claude-flow-commands.js +13 -19
- package/dist/src/cli/simple-commands/init/claude-commands/optimized-slash-commands.js +61 -88
- package/dist/src/cli/simple-commands/init/claude-commands/optimized-sparc-commands.js +125 -150
- package/dist/src/cli/simple-commands/init/claude-commands/slash-commands.js +42 -49
- package/dist/src/cli/simple-commands/init/claude-commands/sparc-commands.js +43 -61
- package/dist/src/cli/simple-commands/init/copy-revised-templates.js +141 -147
- package/dist/src/cli/simple-commands/init/executable-wrapper.js +31 -44
- package/dist/src/cli/simple-commands/init/gitignore-updater.js +64 -90
- package/dist/src/cli/simple-commands/init/help.js +104 -107
- package/dist/src/cli/simple-commands/init/hive-mind-init.js +509 -528
- package/dist/src/cli/simple-commands/init/index.js +1510 -1759
- package/dist/src/cli/simple-commands/init/performance-monitor.js +234 -317
- package/dist/src/cli/simple-commands/init/rollback/backup-manager.js +441 -504
- package/dist/src/cli/simple-commands/init/rollback/index.js +289 -364
- package/dist/src/cli/simple-commands/init/rollback/recovery-manager.js +652 -728
- package/dist/src/cli/simple-commands/init/rollback/rollback-executor.js +416 -481
- package/dist/src/cli/simple-commands/init/rollback/state-tracker.js +369 -448
- package/dist/src/cli/simple-commands/init/sparc/roo-readme.js +1 -2
- package/dist/src/cli/simple-commands/init/sparc/roomodes-config.js +122 -99
- package/dist/src/cli/simple-commands/init/sparc/workflows.js +32 -37
- package/dist/src/cli/simple-commands/init/sparc-structure.js +55 -62
- package/dist/src/cli/simple-commands/init/template-copier.js +421 -533
- package/dist/src/cli/simple-commands/init/templates/coordination-md.js +3 -6
- package/dist/src/cli/simple-commands/init/templates/enhanced-templates.js +344 -318
- package/dist/src/cli/simple-commands/init/templates/github-safe-enhanced.js +173 -218
- package/dist/src/cli/simple-commands/init/templates/github-safe.js +65 -75
- package/dist/src/cli/simple-commands/init/templates/memory-bank-md.js +3 -6
- package/dist/src/cli/simple-commands/init/templates/readme-files.js +2 -4
- package/dist/src/cli/simple-commands/init/templates/safe-hook-patterns.js +187 -230
- package/dist/src/cli/simple-commands/init/templates/sparc-modes.js +53 -80
- package/dist/src/cli/simple-commands/init/templates/verification-claude-md.js +101 -85
- package/dist/src/cli/simple-commands/init/validation/config-validator.js +283 -330
- package/dist/src/cli/simple-commands/init/validation/health-checker.js +495 -561
- package/dist/src/cli/simple-commands/init/validation/index.js +302 -358
- package/dist/src/cli/simple-commands/init/validation/mode-validator.js +308 -359
- package/dist/src/cli/simple-commands/init/validation/post-init-validator.js +389 -366
- package/dist/src/cli/simple-commands/init/validation/pre-init-validator.js +270 -268
- package/dist/src/cli/simple-commands/init/validation/test-runner.js +427 -447
- package/dist/src/cli/simple-commands/init.js +1 -2
- package/dist/src/cli/simple-commands/mcp-health.js +131 -158
- package/dist/src/cli/simple-commands/mcp-integration-layer.js +533 -634
- package/dist/src/cli/simple-commands/mcp.js +345 -400
- package/dist/src/cli/simple-commands/memory-consolidation.js +426 -537
- package/dist/src/cli/simple-commands/memory.js +247 -311
- package/dist/src/cli/simple-commands/migrate-hooks.js +39 -46
- package/dist/src/cli/simple-commands/monitor.js +294 -363
- package/dist/src/cli/simple-commands/neural.js +51 -65
- package/dist/src/cli/simple-commands/pair-autofix-only.js +538 -662
- package/dist/src/cli/simple-commands/pair-basic.js +528 -656
- package/dist/src/cli/simple-commands/pair-old.js +430 -543
- package/dist/src/cli/simple-commands/pair-working.js +615 -751
- package/dist/src/cli/simple-commands/pair.js +615 -751
- package/dist/src/cli/simple-commands/performance-hooks.js +83 -111
- package/dist/src/cli/simple-commands/performance-metrics.js +348 -433
- package/dist/src/cli/simple-commands/process-ui-enhanced.js +708 -787
- package/dist/src/cli/simple-commands/process-ui.js +230 -254
- package/dist/src/cli/simple-commands/realtime-update-system.js +525 -611
- package/dist/src/cli/simple-commands/sparc/architecture.js +1704 -1530
- package/dist/src/cli/simple-commands/sparc/commands.js +438 -516
- package/dist/src/cli/simple-commands/sparc/completion.js +1224 -1481
- package/dist/src/cli/simple-commands/sparc/coordinator.js +913 -978
- package/dist/src/cli/simple-commands/sparc/index.js +241 -298
- package/dist/src/cli/simple-commands/sparc/phase-base.js +314 -390
- package/dist/src/cli/simple-commands/sparc/pseudocode.js +965 -869
- package/dist/src/cli/simple-commands/sparc/refinement.js +980 -1273
- package/dist/src/cli/simple-commands/sparc/specification.js +559 -645
- package/dist/src/cli/simple-commands/sparc-modes/architect.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/ask.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/code.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/debug.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/devops.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/docs-writer.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/generic.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/index.js +47 -55
- package/dist/src/cli/simple-commands/sparc-modes/integration.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/mcp.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/monitoring.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/optimization.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/security-review.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/sparc-orchestrator.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/spec-pseudocode.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/supabase-admin.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/swarm.js +101 -87
- package/dist/src/cli/simple-commands/sparc-modes/tdd.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/tutorial.js +1 -1
- package/dist/src/cli/simple-commands/sparc.js +465 -493
- package/dist/src/cli/simple-commands/start-ui.js +108 -132
- package/dist/src/cli/simple-commands/start-wrapper.js +240 -268
- package/dist/src/cli/simple-commands/start.js +1 -1
- package/dist/src/cli/simple-commands/status.js +254 -275
- package/dist/src/cli/simple-commands/stream-chain-clean.js +128 -171
- package/dist/src/cli/simple-commands/stream-chain-fixed.js +61 -82
- package/dist/src/cli/simple-commands/stream-chain-real.js +267 -331
- package/dist/src/cli/simple-commands/stream-chain-working.js +211 -263
- package/dist/src/cli/simple-commands/stream-chain.js +260 -318
- package/dist/src/cli/simple-commands/stream-processor.js +290 -315
- package/dist/src/cli/simple-commands/swarm-executor.js +189 -222
- package/dist/src/cli/simple-commands/swarm-metrics-integration.js +208 -300
- package/dist/src/cli/simple-commands/swarm-ui.js +623 -703
- package/dist/src/cli/simple-commands/swarm-webui-integration.js +258 -286
- package/dist/src/cli/simple-commands/swarm.js +887 -1082
- package/dist/src/cli/simple-commands/task.js +161 -206
- package/dist/src/cli/simple-commands/timestamp-fix.js +59 -89
- package/dist/src/cli/simple-commands/token-tracker.js +258 -316
- package/dist/src/cli/simple-commands/tool-execution-framework.js +433 -519
- package/dist/src/cli/simple-commands/train-and-stream.js +275 -331
- package/dist/src/cli/simple-commands/training-pipeline.js +619 -725
- package/dist/src/cli/simple-commands/training.js +170 -227
- package/dist/src/cli/simple-commands/verification-hooks.js +261 -284
- package/dist/src/cli/simple-commands/verification-integration.js +389 -417
- package/dist/src/cli/simple-commands/verification-training-integration.js +486 -606
- package/dist/src/cli/simple-commands/verification.js +493 -513
- package/dist/src/cli/simple-commands/web-server.js +766 -836
- package/dist/src/cli/simple-commands/webui-validator.js +106 -124
- package/dist/src/coordination/event-bus/demo-wasm-integration.js +212 -251
- package/dist/src/coordination/event-bus/qe-event-bus.js +608 -748
- package/dist/src/coordination/event-bus/qe-event-bus.test.js +379 -454
- package/dist/src/coordination/iteration-tracker.js +363 -454
- package/dist/src/enterprise/analytics-manager.js +1135 -0
- package/dist/src/enterprise/audit-manager.js +1115 -0
- package/dist/src/enterprise/cloud-manager.js +891 -0
- package/dist/src/enterprise/deployment-manager.js +966 -0
- package/dist/src/enterprise/index.js +6 -0
- package/dist/src/enterprise/project-manager.js +584 -0
- package/dist/src/enterprise/security-manager.js +991 -0
- package/dist/src/index.js +1 -1
- package/dist/src/mcp/DEPRECATED.js +46 -60
- package/dist/src/mcp/fixes/mcp-error-fixes.js +115 -134
- package/dist/src/mcp/implementations/agent-tracker.js +114 -128
- package/dist/src/mcp/implementations/daa-tools.js +292 -350
- package/dist/src/mcp/implementations/workflow-tools.js +329 -361
- package/dist/src/mcp/mcp-config-manager.js +1183 -1331
- package/dist/src/mcp/mcp-server-novice-simplified.js +11 -17
- package/dist/src/mcp/mcp-server-novice.js +11 -17
- package/dist/src/mcp/mcp-server-sdk.js +11 -17
- package/dist/src/mcp/mcp-server.js +1620 -1484
- package/dist/src/mcp/ruv-swarm-wrapper.js +209 -239
- package/dist/src/memory/advanced-serializer.js +609 -589
- package/dist/src/memory/enhanced-examples.js +220 -305
- package/dist/src/memory/enhanced-memory.js +295 -336
- package/dist/src/memory/enhanced-session-serializer.js +408 -492
- package/dist/src/memory/fallback-memory-system.js +900 -1021
- package/dist/src/memory/fallback-store.js +93 -131
- package/dist/src/memory/high-performance-serialization.js +592 -730
- package/dist/src/memory/in-memory-store.js +161 -213
- package/dist/src/memory/index.js +123 -157
- package/dist/src/memory/lock-free-structures.js +578 -764
- package/dist/src/memory/memory-mapped-persistence.js +585 -766
- package/dist/src/memory/memory-pressure-manager.js +569 -707
- package/dist/src/memory/migration.js +358 -445
- package/dist/src/memory/shared-memory.js +641 -768
- package/dist/src/memory/sqlite-store.js +245 -325
- package/dist/src/memory/sqlite-wrapper.js +122 -151
- package/dist/src/memory/swarm-memory.js +470 -603
- package/dist/src/memory/test-example.js +126 -134
- package/dist/src/memory/ultra-fast-memory-store.js +622 -821
- package/dist/src/memory/unified-memory-manager.js +356 -437
- package/dist/src/migration/index.js +92 -0
- package/dist/src/migration/logger.js +121 -0
- package/dist/src/migration/migration-analyzer.js +268 -0
- package/dist/src/migration/migration-runner.js +522 -0
- package/dist/src/migration/migration-validator.js +285 -0
- package/dist/src/migration/progress-reporter.js +150 -0
- package/dist/src/migration/rollback-manager.js +321 -0
- package/dist/src/migration/tests/migration-system.test.js +7 -0
- package/dist/src/migration/types.js +3 -0
- package/dist/src/swarm/CodeRefactoringSwarm.js +777 -952
- package/dist/src/swarm/__tests__/integration.test.js +227 -0
- package/dist/src/swarm/__tests__/prompt-copier.test.js +344 -0
- package/dist/src/swarm/advanced-orchestrator.js +1095 -0
- package/dist/src/swarm/claude-code-interface.js +961 -0
- package/dist/src/swarm/claude-flow-executor.js +229 -0
- package/dist/src/swarm/consensus-coordinator.js +475 -0
- package/dist/src/swarm/coordinator.js +2993 -0
- package/dist/src/swarm/direct-executor.js +1180 -0
- package/dist/src/swarm/error-recovery/advanced-error-detection.js +691 -0
- package/dist/src/swarm/error-recovery/automated-recovery-workflows.js +998 -0
- package/dist/src/swarm/error-recovery/error-recovery-coordinator.js +1197 -0
- package/dist/src/swarm/error-recovery/recovery-monitoring.js +772 -0
- package/dist/src/swarm/error-recovery/resilience-architecture.js +714 -0
- package/dist/src/swarm/error-recovery/self-healing-mechanisms.js +1319 -0
- package/dist/src/swarm/error-recovery/test-error-recovery-effectiveness.js +808 -0
- package/dist/src/swarm/executor-v2.js +322 -0
- package/dist/src/swarm/executor.js +815 -0
- package/dist/src/swarm/hive-mind-integration.js +703 -0
- package/dist/src/swarm/index.js +41 -0
- package/dist/src/swarm/json-output-aggregator.js +267 -0
- package/dist/src/swarm/large-scale-coordinator.js +542 -0
- package/dist/src/swarm/mcp-integration-wrapper.js +628 -0
- package/dist/src/swarm/memory.js +1117 -0
- package/dist/src/swarm/optimizations/__tests__/optimization.test.js +348 -0
- package/dist/src/swarm/optimizations/async-file-manager.js +285 -0
- package/dist/src/swarm/optimizations/circular-buffer.js +162 -0
- package/dist/src/swarm/optimizations/connection-pool.js +244 -0
- package/dist/src/swarm/optimizations/index.js +28 -0
- package/dist/src/swarm/optimizations/optimized-executor.js +320 -0
- package/dist/src/swarm/optimizations/ttl-map.js +234 -0
- package/dist/src/swarm/prompt-cli.js +200 -0
- package/dist/src/swarm/prompt-copier-enhanced.js +202 -0
- package/dist/src/swarm/prompt-copier.js +381 -0
- package/dist/src/swarm/prompt-manager.js +295 -0
- package/dist/src/swarm/prompt-utils.js +310 -0
- package/dist/src/swarm/result-aggregator.js +718 -0
- package/dist/src/swarm/sparc-executor.js +1568 -0
- package/dist/src/swarm/strategies/auto.js +758 -0
- package/dist/src/swarm/strategies/base.js +128 -0
- package/dist/src/swarm/strategies/research.js +914 -0
- package/dist/src/swarm/strategies/strategy-metrics-patch.js +2 -0
- package/dist/src/swarm/types.js +52 -0
- package/dist/src/swarm/workers/copy-worker.js +56 -0
- package/dist/src/utils/__tests__/github-cli-safety-wrapper.test.js +332 -400
- package/dist/src/utils/github-cli-safe.js +56 -64
- package/dist/src/utils/github-cli-safety-wrapper.js +451 -546
- package/dist/src/utils/npx-isolated-cache.js +104 -119
- package/dist/src/utils/preference-manager.js +622 -652
- package/dist/src/utils/timezone-utils.js +86 -105
- package/dist/src/validators/epic-config-schema.js +214 -0
- package/dist/src/validators/index.js +10 -0
- package/dist/src/validators/swarm-init-validator.js +259 -0
- package/dist/src/validators/todowrite-batching-validator.js +215 -0
- package/dist/src/validators/todowrite-integration.js +187 -0
- package/package.json +2 -2
|
@@ -1,542 +1,479 @@
|
|
|
1
1
|
// backup-manager.js - Backup creation and management
|
|
2
|
-
|
|
3
2
|
// Node.js compatible import
|
|
4
|
-
import fs from
|
|
5
|
-
import { errors } from
|
|
6
|
-
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import { errors } from "../../../node-compat.js";
|
|
7
5
|
// Polyfill for Deno's ensureDirSync
|
|
8
6
|
function ensureDirSync(dirPath) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
try {
|
|
8
|
+
fs.mkdirSync(dirPath, {
|
|
9
|
+
recursive: true
|
|
10
|
+
});
|
|
11
|
+
} catch (error) {
|
|
12
|
+
if (error.code !== 'EEXIST') throw error;
|
|
13
|
+
}
|
|
14
14
|
}
|
|
15
|
-
|
|
16
15
|
export class BackupManager {
|
|
17
|
-
|
|
18
|
-
this.workingDir = workingDir;
|
|
19
|
-
this.backupDir = `${workingDir}/.claude-flow-backups`;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
16
|
+
/**
|
|
23
17
|
* Create a backup of the current state
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
18
|
+
*/ async createBackup(type = 'manual', description = '') {
|
|
19
|
+
const result = {
|
|
20
|
+
success: true,
|
|
21
|
+
id: null,
|
|
22
|
+
location: null,
|
|
23
|
+
errors: [],
|
|
24
|
+
warnings: [],
|
|
25
|
+
files: []
|
|
26
|
+
};
|
|
27
|
+
try {
|
|
28
|
+
// Generate backup ID
|
|
29
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
30
|
+
const backupId = `${type}-${timestamp}`;
|
|
31
|
+
result.id = backupId;
|
|
32
|
+
// Create backup directory
|
|
33
|
+
const backupPath = `${this.backupDir}/${backupId}`;
|
|
34
|
+
result.location = backupPath;
|
|
35
|
+
await this.ensureBackupDir();
|
|
36
|
+
await Deno.mkdir(backupPath, {
|
|
37
|
+
recursive: true
|
|
38
|
+
});
|
|
39
|
+
// Create backup manifest
|
|
40
|
+
const manifest = {
|
|
41
|
+
id: backupId,
|
|
42
|
+
type,
|
|
43
|
+
description,
|
|
44
|
+
timestamp: Date.now(),
|
|
45
|
+
workingDir: this.workingDir,
|
|
46
|
+
files: [],
|
|
47
|
+
directories: []
|
|
48
|
+
};
|
|
49
|
+
// Backup critical files
|
|
50
|
+
const criticalFiles = await this.getCriticalFiles();
|
|
51
|
+
for (const file of criticalFiles){
|
|
52
|
+
const backupResult = await this.backupFile(file, backupPath);
|
|
53
|
+
if (backupResult.success) {
|
|
54
|
+
manifest.files.push(backupResult.fileInfo);
|
|
55
|
+
result.files.push(file);
|
|
56
|
+
} else {
|
|
57
|
+
result.warnings.push(`Failed to backup file: ${file}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Backup critical directories
|
|
61
|
+
const criticalDirs = await this.getCriticalDirectories();
|
|
62
|
+
for (const dir of criticalDirs){
|
|
63
|
+
const backupResult = await this.backupDirectory(dir, backupPath);
|
|
64
|
+
if (backupResult.success) {
|
|
65
|
+
manifest.directories.push(backupResult.dirInfo);
|
|
66
|
+
} else {
|
|
67
|
+
result.warnings.push(`Failed to backup directory: ${dir}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Save manifest
|
|
71
|
+
await Deno.writeTextFile(`${backupPath}/manifest.json`, JSON.stringify(manifest, null, 2));
|
|
72
|
+
// Create backup metadata
|
|
73
|
+
const metadata = {
|
|
74
|
+
created: Date.now(),
|
|
75
|
+
size: await this.calculateBackupSize(backupPath),
|
|
76
|
+
fileCount: manifest.files.length,
|
|
77
|
+
dirCount: manifest.directories.length
|
|
78
|
+
};
|
|
79
|
+
await Deno.writeTextFile(`${backupPath}/metadata.json`, JSON.stringify(metadata, null, 2));
|
|
80
|
+
console.log(` ✓ Backup created: ${backupId}`);
|
|
81
|
+
console.log(` 📁 Files backed up: ${result.files.length}`);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
result.success = false;
|
|
84
|
+
result.errors.push(`Backup creation failed: ${error.message}`);
|
|
79
85
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// Save manifest
|
|
83
|
-
await Deno.writeTextFile(`${backupPath}/manifest.json`, JSON.stringify(manifest, null, 2));
|
|
84
|
-
|
|
85
|
-
// Create backup metadata
|
|
86
|
-
const metadata = {
|
|
87
|
-
created: Date.now(),
|
|
88
|
-
size: await this.calculateBackupSize(backupPath),
|
|
89
|
-
fileCount: manifest.files.length,
|
|
90
|
-
dirCount: manifest.directories.length,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
await Deno.writeTextFile(`${backupPath}/metadata.json`, JSON.stringify(metadata, null, 2));
|
|
94
|
-
|
|
95
|
-
console.log(` ✓ Backup created: ${backupId}`);
|
|
96
|
-
console.log(` 📁 Files backed up: ${result.files.length}`);
|
|
97
|
-
} catch (error) {
|
|
98
|
-
result.success = false;
|
|
99
|
-
result.errors.push(`Backup creation failed: ${error.message}`);
|
|
86
|
+
return result;
|
|
100
87
|
}
|
|
101
|
-
|
|
102
|
-
return result;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
88
|
+
/**
|
|
106
89
|
* Restore from backup
|
|
107
|
-
*/
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
90
|
+
*/ async restoreBackup(backupId) {
|
|
91
|
+
const result = {
|
|
92
|
+
success: true,
|
|
93
|
+
errors: [],
|
|
94
|
+
warnings: [],
|
|
95
|
+
restored: []
|
|
96
|
+
};
|
|
97
|
+
try {
|
|
98
|
+
const backupPath = `${this.backupDir}/${backupId}`;
|
|
99
|
+
// Check if backup exists
|
|
100
|
+
try {
|
|
101
|
+
await Deno.stat(backupPath);
|
|
102
|
+
} catch {
|
|
103
|
+
result.success = false;
|
|
104
|
+
result.errors.push(`Backup not found: ${backupId}`);
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
// Read manifest
|
|
108
|
+
const manifestPath = `${backupPath}/manifest.json`;
|
|
109
|
+
const manifestContent = await fs.readFile(manifestPath, 'utf8');
|
|
110
|
+
const manifest = JSON.parse(manifestContent);
|
|
111
|
+
// Restore files
|
|
112
|
+
for (const fileInfo of manifest.files){
|
|
113
|
+
const restoreResult = await this.restoreFile(fileInfo, backupPath);
|
|
114
|
+
if (restoreResult.success) {
|
|
115
|
+
result.restored.push(fileInfo.originalPath);
|
|
116
|
+
} else {
|
|
117
|
+
result.warnings.push(`Failed to restore file: ${fileInfo.originalPath}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Restore directories
|
|
121
|
+
for (const dirInfo of manifest.directories){
|
|
122
|
+
const restoreResult = await this.restoreDirectory(dirInfo, backupPath);
|
|
123
|
+
if (restoreResult.success) {
|
|
124
|
+
result.restored.push(dirInfo.originalPath);
|
|
125
|
+
} else {
|
|
126
|
+
result.warnings.push(`Failed to restore directory: ${dirInfo.originalPath}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
console.log(` ✓ Backup restored: ${backupId}`);
|
|
130
|
+
console.log(` 📁 Items restored: ${result.restored.length}`);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
result.success = false;
|
|
133
|
+
result.errors.push(`Backup restoration failed: ${error.message}`);
|
|
140
134
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
// Restore directories
|
|
144
|
-
for (const dirInfo of manifest.directories) {
|
|
145
|
-
const restoreResult = await this.restoreDirectory(dirInfo, backupPath);
|
|
146
|
-
if (restoreResult.success) {
|
|
147
|
-
result.restored.push(dirInfo.originalPath);
|
|
148
|
-
} else {
|
|
149
|
-
result.warnings.push(`Failed to restore directory: ${dirInfo.originalPath}`);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
console.log(` ✓ Backup restored: ${backupId}`);
|
|
154
|
-
console.log(` 📁 Items restored: ${result.restored.length}`);
|
|
155
|
-
} catch (error) {
|
|
156
|
-
result.success = false;
|
|
157
|
-
result.errors.push(`Backup restoration failed: ${error.message}`);
|
|
135
|
+
return result;
|
|
158
136
|
}
|
|
159
|
-
|
|
160
|
-
return result;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
137
|
+
/**
|
|
164
138
|
* List available backups
|
|
165
|
-
*/
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
139
|
+
*/ async listBackups() {
|
|
140
|
+
const backups = [];
|
|
141
|
+
try {
|
|
142
|
+
await this.ensureBackupDir();
|
|
143
|
+
for await (const entry of Deno.readDir(this.backupDir)){
|
|
144
|
+
if (entry.isDirectory) {
|
|
145
|
+
try {
|
|
146
|
+
const metadataPath = `${this.backupDir}/${entry.name}/metadata.json`;
|
|
147
|
+
const manifestPath = `${this.backupDir}/${entry.name}/manifest.json`;
|
|
148
|
+
const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf8'));
|
|
149
|
+
const manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8'));
|
|
150
|
+
backups.push({
|
|
151
|
+
id: entry.name,
|
|
152
|
+
type: manifest.type,
|
|
153
|
+
description: manifest.description,
|
|
154
|
+
created: metadata.created,
|
|
155
|
+
size: metadata.size,
|
|
156
|
+
fileCount: metadata.fileCount,
|
|
157
|
+
dirCount: metadata.dirCount
|
|
158
|
+
});
|
|
159
|
+
} catch {
|
|
160
|
+
// Skip invalid backup directories
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
} catch {
|
|
165
|
+
// Backup directory doesn't exist or can't be read
|
|
193
166
|
}
|
|
194
|
-
|
|
195
|
-
} catch {
|
|
196
|
-
// Backup directory doesn't exist or can't be read
|
|
167
|
+
return backups.sort((a, b)=>b.created - a.created);
|
|
197
168
|
}
|
|
198
|
-
|
|
199
|
-
return backups.sort((a, b) => b.created - a.created);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
169
|
+
/**
|
|
203
170
|
* Delete a backup
|
|
204
|
-
*/
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
171
|
+
*/ async deleteBackup(backupId) {
|
|
172
|
+
const result = {
|
|
173
|
+
success: true,
|
|
174
|
+
errors: []
|
|
175
|
+
};
|
|
176
|
+
try {
|
|
177
|
+
const backupPath = `${this.backupDir}/${backupId}`;
|
|
178
|
+
await Deno.remove(backupPath, {
|
|
179
|
+
recursive: true
|
|
180
|
+
});
|
|
181
|
+
console.log(` 🗑️ Deleted backup: ${backupId}`);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
result.success = false;
|
|
184
|
+
result.errors.push(`Failed to delete backup: ${error.message}`);
|
|
185
|
+
}
|
|
186
|
+
return result;
|
|
218
187
|
}
|
|
219
|
-
|
|
220
|
-
return result;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
188
|
+
/**
|
|
224
189
|
* Clean up old backups
|
|
225
|
-
*/
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
190
|
+
*/ async cleanupOldBackups(keepCount = 5) {
|
|
191
|
+
const result = {
|
|
192
|
+
success: true,
|
|
193
|
+
cleaned: [],
|
|
194
|
+
errors: []
|
|
195
|
+
};
|
|
196
|
+
try {
|
|
197
|
+
const backups = await this.listBackups();
|
|
198
|
+
if (backups.length > keepCount) {
|
|
199
|
+
const toDelete = backups.slice(keepCount);
|
|
200
|
+
for (const backup of toDelete){
|
|
201
|
+
const deleteResult = await this.deleteBackup(backup.id);
|
|
202
|
+
if (deleteResult.success) {
|
|
203
|
+
result.cleaned.push(backup.id);
|
|
204
|
+
} else {
|
|
205
|
+
result.errors.push(...deleteResult.errors);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
} catch (error) {
|
|
210
|
+
result.success = false;
|
|
211
|
+
result.errors.push(`Cleanup failed: ${error.message}`);
|
|
246
212
|
}
|
|
247
|
-
|
|
248
|
-
} catch (error) {
|
|
249
|
-
result.success = false;
|
|
250
|
-
result.errors.push(`Cleanup failed: ${error.message}`);
|
|
213
|
+
return result;
|
|
251
214
|
}
|
|
252
|
-
|
|
253
|
-
return result;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
215
|
+
/**
|
|
257
216
|
* Validate backup system
|
|
258
|
-
*/
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
result.success = false;
|
|
287
|
-
result.errors.push(`Backup system validation failed: ${error.message}`);
|
|
217
|
+
*/ async validateBackupSystem() {
|
|
218
|
+
const result = {
|
|
219
|
+
success: true,
|
|
220
|
+
errors: [],
|
|
221
|
+
warnings: []
|
|
222
|
+
};
|
|
223
|
+
try {
|
|
224
|
+
// Check backup directory
|
|
225
|
+
await this.ensureBackupDir();
|
|
226
|
+
// Test backup creation
|
|
227
|
+
const testBackup = await this.createTestBackup();
|
|
228
|
+
if (!testBackup.success) {
|
|
229
|
+
result.success = false;
|
|
230
|
+
result.errors.push('Cannot create test backup');
|
|
231
|
+
} else {
|
|
232
|
+
// Clean up test backup
|
|
233
|
+
await this.deleteBackup(testBackup.id);
|
|
234
|
+
}
|
|
235
|
+
// Check disk space
|
|
236
|
+
const spaceCheck = await this.checkBackupDiskSpace();
|
|
237
|
+
if (!spaceCheck.adequate) {
|
|
238
|
+
result.warnings.push('Low disk space for backups');
|
|
239
|
+
}
|
|
240
|
+
} catch (error) {
|
|
241
|
+
result.success = false;
|
|
242
|
+
result.errors.push(`Backup system validation failed: ${error.message}`);
|
|
243
|
+
}
|
|
244
|
+
return result;
|
|
288
245
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
throw error;
|
|
301
|
-
}
|
|
246
|
+
// Helper methods
|
|
247
|
+
async ensureBackupDir() {
|
|
248
|
+
try {
|
|
249
|
+
await Deno.mkdir(this.backupDir, {
|
|
250
|
+
recursive: true
|
|
251
|
+
});
|
|
252
|
+
} catch (error) {
|
|
253
|
+
if (!(error instanceof errors.AlreadyExists)) {
|
|
254
|
+
throw error;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
302
257
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
258
|
+
async getCriticalFiles() {
|
|
259
|
+
const files = [];
|
|
260
|
+
const potentialFiles = [
|
|
261
|
+
'CLAUDE.md',
|
|
262
|
+
'memory-bank.md',
|
|
263
|
+
'coordination.md',
|
|
264
|
+
'package.json',
|
|
265
|
+
'package-lock.json',
|
|
266
|
+
'.roomodes',
|
|
267
|
+
'claude-flow',
|
|
268
|
+
'memory/claude-flow-data.json'
|
|
269
|
+
];
|
|
270
|
+
for (const file of potentialFiles){
|
|
271
|
+
try {
|
|
272
|
+
const stat = await Deno.stat(`${this.workingDir}/${file}`);
|
|
273
|
+
if (stat.isFile) {
|
|
274
|
+
files.push(file);
|
|
275
|
+
}
|
|
276
|
+
} catch {
|
|
277
|
+
// File doesn't exist
|
|
278
|
+
}
|
|
323
279
|
}
|
|
324
|
-
|
|
325
|
-
// File doesn't exist
|
|
326
|
-
}
|
|
280
|
+
return files;
|
|
327
281
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
282
|
+
async getCriticalDirectories() {
|
|
283
|
+
const dirs = [];
|
|
284
|
+
const potentialDirs = [
|
|
285
|
+
'.claude',
|
|
286
|
+
'.roo',
|
|
287
|
+
'memory/agents',
|
|
288
|
+
'memory/sessions',
|
|
289
|
+
'coordination'
|
|
290
|
+
];
|
|
291
|
+
for (const dir of potentialDirs){
|
|
292
|
+
try {
|
|
293
|
+
const stat = await Deno.stat(`${this.workingDir}/${dir}`);
|
|
294
|
+
if (stat.isDirectory) {
|
|
295
|
+
dirs.push(dir);
|
|
296
|
+
}
|
|
297
|
+
} catch {
|
|
298
|
+
// Directory doesn't exist
|
|
299
|
+
}
|
|
341
300
|
}
|
|
342
|
-
|
|
343
|
-
// Directory doesn't exist
|
|
344
|
-
}
|
|
301
|
+
return dirs;
|
|
345
302
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
};
|
|
375
|
-
} catch (error) {
|
|
376
|
-
result.success = false;
|
|
377
|
-
result.error = error.message;
|
|
303
|
+
async backupFile(relativePath, backupPath) {
|
|
304
|
+
const result = {
|
|
305
|
+
success: true,
|
|
306
|
+
fileInfo: null
|
|
307
|
+
};
|
|
308
|
+
try {
|
|
309
|
+
const sourcePath = `${this.workingDir}/${relativePath}`;
|
|
310
|
+
const destPath = `${backupPath}/${relativePath}`;
|
|
311
|
+
// Ensure destination directory exists
|
|
312
|
+
const destDir = destPath.split('/').slice(0, -1).join('/');
|
|
313
|
+
await Deno.mkdir(destDir, {
|
|
314
|
+
recursive: true
|
|
315
|
+
});
|
|
316
|
+
// Copy file
|
|
317
|
+
await Deno.copyFile(sourcePath, destPath);
|
|
318
|
+
// Get file info
|
|
319
|
+
const stat = await Deno.stat(sourcePath);
|
|
320
|
+
result.fileInfo = {
|
|
321
|
+
originalPath: relativePath,
|
|
322
|
+
backupPath: destPath,
|
|
323
|
+
size: stat.size,
|
|
324
|
+
modified: stat.mtime?.getTime() || 0
|
|
325
|
+
};
|
|
326
|
+
} catch (error) {
|
|
327
|
+
result.success = false;
|
|
328
|
+
result.error = error.message;
|
|
329
|
+
}
|
|
330
|
+
return result;
|
|
378
331
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
};
|
|
403
|
-
} catch (error) {
|
|
404
|
-
result.success = false;
|
|
405
|
-
result.error = error.message;
|
|
332
|
+
async backupDirectory(relativePath, backupPath) {
|
|
333
|
+
const result = {
|
|
334
|
+
success: true,
|
|
335
|
+
dirInfo: null
|
|
336
|
+
};
|
|
337
|
+
try {
|
|
338
|
+
const sourcePath = `${this.workingDir}/${relativePath}`;
|
|
339
|
+
const destPath = `${backupPath}/${relativePath}`;
|
|
340
|
+
// Create destination directory
|
|
341
|
+
await Deno.mkdir(destPath, {
|
|
342
|
+
recursive: true
|
|
343
|
+
});
|
|
344
|
+
// Copy directory contents recursively
|
|
345
|
+
await this.copyDirectoryRecursive(sourcePath, destPath);
|
|
346
|
+
result.dirInfo = {
|
|
347
|
+
originalPath: relativePath,
|
|
348
|
+
backupPath: destPath
|
|
349
|
+
};
|
|
350
|
+
} catch (error) {
|
|
351
|
+
result.success = false;
|
|
352
|
+
result.error = error.message;
|
|
353
|
+
}
|
|
354
|
+
return result;
|
|
406
355
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
await this.copyDirectoryRecursive(sourcePath, destPath);
|
|
421
|
-
}
|
|
356
|
+
async copyDirectoryRecursive(source, dest) {
|
|
357
|
+
for await (const entry of Deno.readDir(source)){
|
|
358
|
+
const sourcePath = `${source}/${entry.name}`;
|
|
359
|
+
const destPath = `${dest}/${entry.name}`;
|
|
360
|
+
if (entry.isFile) {
|
|
361
|
+
await Deno.copyFile(sourcePath, destPath);
|
|
362
|
+
} else if (entry.isDirectory) {
|
|
363
|
+
await Deno.mkdir(destPath, {
|
|
364
|
+
recursive: true
|
|
365
|
+
});
|
|
366
|
+
await this.copyDirectoryRecursive(sourcePath, destPath);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
422
369
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
result.error = error.message;
|
|
370
|
+
async restoreFile(fileInfo, backupPath) {
|
|
371
|
+
const result = {
|
|
372
|
+
success: true
|
|
373
|
+
};
|
|
374
|
+
try {
|
|
375
|
+
const sourcePath = fileInfo.backupPath;
|
|
376
|
+
const destPath = `${this.workingDir}/${fileInfo.originalPath}`;
|
|
377
|
+
// Ensure destination directory exists
|
|
378
|
+
const destDir = destPath.split('/').slice(0, -1).join('/');
|
|
379
|
+
await Deno.mkdir(destDir, {
|
|
380
|
+
recursive: true
|
|
381
|
+
});
|
|
382
|
+
// Copy file back
|
|
383
|
+
await Deno.copyFile(sourcePath, destPath);
|
|
384
|
+
} catch (error) {
|
|
385
|
+
result.success = false;
|
|
386
|
+
result.error = error.message;
|
|
387
|
+
}
|
|
388
|
+
return result;
|
|
443
389
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
result.success = false;
|
|
471
|
-
result.error = error.message;
|
|
390
|
+
async restoreDirectory(dirInfo, backupPath) {
|
|
391
|
+
const result = {
|
|
392
|
+
success: true
|
|
393
|
+
};
|
|
394
|
+
try {
|
|
395
|
+
const sourcePath = dirInfo.backupPath;
|
|
396
|
+
const destPath = `${this.workingDir}/${dirInfo.originalPath}`;
|
|
397
|
+
// Remove existing directory if it exists
|
|
398
|
+
try {
|
|
399
|
+
await Deno.remove(destPath, {
|
|
400
|
+
recursive: true
|
|
401
|
+
});
|
|
402
|
+
} catch {
|
|
403
|
+
// Directory might not exist
|
|
404
|
+
}
|
|
405
|
+
// Create destination directory
|
|
406
|
+
await Deno.mkdir(destPath, {
|
|
407
|
+
recursive: true
|
|
408
|
+
});
|
|
409
|
+
// Copy directory contents back
|
|
410
|
+
await this.copyDirectoryRecursive(sourcePath, destPath);
|
|
411
|
+
} catch (error) {
|
|
412
|
+
result.success = false;
|
|
413
|
+
result.error = error.message;
|
|
414
|
+
}
|
|
415
|
+
return result;
|
|
472
416
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
} else if (stat.isDirectory) {
|
|
488
|
-
totalSize += await this.calculateBackupSize(entryPath);
|
|
417
|
+
async calculateBackupSize(backupPath) {
|
|
418
|
+
let totalSize = 0;
|
|
419
|
+
try {
|
|
420
|
+
for await (const entry of Deno.readDir(backupPath)){
|
|
421
|
+
const entryPath = `${backupPath}/${entry.name}`;
|
|
422
|
+
const stat = await Deno.stat(entryPath);
|
|
423
|
+
if (stat.isFile) {
|
|
424
|
+
totalSize += stat.size;
|
|
425
|
+
} else if (stat.isDirectory) {
|
|
426
|
+
totalSize += await this.calculateBackupSize(entryPath);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
} catch {
|
|
430
|
+
// Error calculating size
|
|
489
431
|
}
|
|
490
|
-
|
|
491
|
-
} catch {
|
|
492
|
-
// Error calculating size
|
|
432
|
+
return totalSize;
|
|
493
433
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
success: false,
|
|
504
|
-
error: error.message,
|
|
505
|
-
};
|
|
434
|
+
async createTestBackup() {
|
|
435
|
+
try {
|
|
436
|
+
return await this.createBackup('test', 'System validation test');
|
|
437
|
+
} catch (error) {
|
|
438
|
+
return {
|
|
439
|
+
success: false,
|
|
440
|
+
error: error.message
|
|
441
|
+
};
|
|
442
|
+
}
|
|
506
443
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
444
|
+
async checkBackupDiskSpace() {
|
|
445
|
+
const result = {
|
|
446
|
+
adequate: true,
|
|
447
|
+
available: 0
|
|
448
|
+
};
|
|
449
|
+
try {
|
|
450
|
+
const command = new Deno.Command('df', {
|
|
451
|
+
args: [
|
|
452
|
+
'-k',
|
|
453
|
+
this.backupDir
|
|
454
|
+
],
|
|
455
|
+
stdout: 'piped'
|
|
456
|
+
});
|
|
457
|
+
const { stdout, success } = await command.output();
|
|
458
|
+
if (success) {
|
|
459
|
+
const output = new TextDecoder().decode(stdout);
|
|
460
|
+
const lines = output.trim().split('\n');
|
|
461
|
+
if (lines.length >= 2) {
|
|
462
|
+
const parts = lines[1].split(/\s+/);
|
|
463
|
+
if (parts.length >= 4) {
|
|
464
|
+
result.available = parseInt(parts[3]) / 1024; // MB
|
|
465
|
+
result.adequate = result.available > 500; // At least 500MB for backups
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
} catch {
|
|
470
|
+
// Can't check - assume adequate
|
|
471
|
+
result.adequate = true;
|
|
533
472
|
}
|
|
534
|
-
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
|
|
473
|
+
return result;
|
|
474
|
+
}
|
|
475
|
+
constructor(workingDir){
|
|
476
|
+
this.workingDir = workingDir;
|
|
477
|
+
this.backupDir = `${workingDir}/.claude-flow-backups`;
|
|
538
478
|
}
|
|
539
|
-
|
|
540
|
-
return result;
|
|
541
|
-
}
|
|
542
479
|
}
|