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
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
function _define_property(obj, key, value) {
|
|
2
|
+
if (key in obj) {
|
|
3
|
+
Object.defineProperty(obj, key, {
|
|
4
|
+
value: value,
|
|
5
|
+
enumerable: true,
|
|
6
|
+
configurable: true,
|
|
7
|
+
writable: true
|
|
8
|
+
});
|
|
9
|
+
} else {
|
|
10
|
+
obj[key] = value;
|
|
11
|
+
}
|
|
12
|
+
return obj;
|
|
13
|
+
}
|
|
14
|
+
import * as fs from "node:fs/promises";
|
|
15
|
+
import * as path from "path";
|
|
16
|
+
import { createHash } from "crypto";
|
|
17
|
+
import { EventEmitter } from "events";
|
|
18
|
+
import { logger } from "../core/logger.js";
|
|
19
|
+
export class PromptCopier extends EventEmitter {
|
|
20
|
+
async copy() {
|
|
21
|
+
const startTime = Date.now();
|
|
22
|
+
try {
|
|
23
|
+
// Phase 1: Discovery
|
|
24
|
+
logger.info('Starting prompt discovery phase...');
|
|
25
|
+
await this.discoverFiles();
|
|
26
|
+
if (this.fileQueue.length === 0) {
|
|
27
|
+
return {
|
|
28
|
+
success: true,
|
|
29
|
+
totalFiles: 0,
|
|
30
|
+
copiedFiles: 0,
|
|
31
|
+
failedFiles: 0,
|
|
32
|
+
skippedFiles: 0,
|
|
33
|
+
duration: Date.now() - startTime,
|
|
34
|
+
errors: []
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// Phase 2: Pre-flight checks
|
|
38
|
+
if (!this.options.dryRun) {
|
|
39
|
+
await this.ensureDestinationDirectories();
|
|
40
|
+
}
|
|
41
|
+
// Phase 3: Copy files
|
|
42
|
+
logger.info(`Copying ${this.fileQueue.length} files...`);
|
|
43
|
+
if (this.options.parallel) {
|
|
44
|
+
await this.copyFilesParallel();
|
|
45
|
+
} else {
|
|
46
|
+
await this.copyFilesSequential();
|
|
47
|
+
}
|
|
48
|
+
// Phase 4: Verification
|
|
49
|
+
if (this.options.verify && !this.options.dryRun) {
|
|
50
|
+
await this.verifyFiles();
|
|
51
|
+
}
|
|
52
|
+
const duration = Date.now() - startTime;
|
|
53
|
+
const result = {
|
|
54
|
+
success: this.errors.length === 0,
|
|
55
|
+
totalFiles: this.fileQueue.length,
|
|
56
|
+
copiedFiles: this.copiedFiles.size,
|
|
57
|
+
failedFiles: this.errors.length,
|
|
58
|
+
skippedFiles: this.fileQueue.length - this.copiedFiles.size - this.errors.length,
|
|
59
|
+
errors: this.errors,
|
|
60
|
+
duration
|
|
61
|
+
};
|
|
62
|
+
if (this.backupMap.size > 0) {
|
|
63
|
+
result.backupLocation = await this.createBackupManifest();
|
|
64
|
+
}
|
|
65
|
+
logger.info(`Copy completed in ${duration}ms`, result);
|
|
66
|
+
return result;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
logger.error('Copy operation failed', error);
|
|
69
|
+
if (!this.options.dryRun) {
|
|
70
|
+
await this.rollback();
|
|
71
|
+
}
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async discoverFiles() {
|
|
76
|
+
const sourceStats = await fs.stat(this.options.source);
|
|
77
|
+
if (!sourceStats.isDirectory()) {
|
|
78
|
+
throw new Error(`Source path ${this.options.source} is not a directory`);
|
|
79
|
+
}
|
|
80
|
+
await this.scanDirectory(this.options.source, '');
|
|
81
|
+
// Sort by size for better parallel distribution
|
|
82
|
+
this.fileQueue.sort((a, b)=>b.size - a.size);
|
|
83
|
+
}
|
|
84
|
+
async scanDirectory(dirPath, relativePath) {
|
|
85
|
+
const entries = await fs.readdir(dirPath, {
|
|
86
|
+
withFileTypes: true
|
|
87
|
+
});
|
|
88
|
+
for (const entry of entries){
|
|
89
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
90
|
+
const relPath = path.join(relativePath, entry.name);
|
|
91
|
+
if (entry.isDirectory()) {
|
|
92
|
+
await this.scanDirectory(fullPath, relPath);
|
|
93
|
+
} else if (entry.isFile() && this.shouldIncludeFile(relPath)) {
|
|
94
|
+
const stats = await fs.stat(fullPath);
|
|
95
|
+
this.fileQueue.push({
|
|
96
|
+
path: fullPath,
|
|
97
|
+
relativePath: relPath,
|
|
98
|
+
size: stats.size,
|
|
99
|
+
permissions: stats.mode
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
shouldIncludeFile(filePath) {
|
|
105
|
+
// Check exclude patterns first
|
|
106
|
+
for (const pattern of this.options.excludePatterns){
|
|
107
|
+
if (this.matchPattern(filePath, pattern)) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Check include patterns
|
|
112
|
+
if (this.options.includePatterns.length === 0) {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
for (const pattern of this.options.includePatterns){
|
|
116
|
+
if (this.matchPattern(filePath, pattern)) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
matchPattern(filePath, pattern) {
|
|
123
|
+
// Simple glob pattern matching
|
|
124
|
+
const regex = pattern.replace(/\./g, '\\.').replace(/\*/g, '.*').replace(/\?/g, '.');
|
|
125
|
+
return new RegExp(regex).test(filePath);
|
|
126
|
+
}
|
|
127
|
+
async ensureDestinationDirectories() {
|
|
128
|
+
const directories = new Set();
|
|
129
|
+
for (const file of this.fileQueue){
|
|
130
|
+
const destDir = path.dirname(path.join(this.options.destination, file.relativePath));
|
|
131
|
+
directories.add(destDir);
|
|
132
|
+
}
|
|
133
|
+
// Create directories in order (parent first)
|
|
134
|
+
const sortedDirs = Array.from(directories).sort((a, b)=>a.length - b.length);
|
|
135
|
+
for (const dir of sortedDirs){
|
|
136
|
+
await fs.mkdir(dir, {
|
|
137
|
+
recursive: true
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async copyFilesSequential() {
|
|
142
|
+
let completed = 0;
|
|
143
|
+
for (const file of this.fileQueue){
|
|
144
|
+
try {
|
|
145
|
+
await this.copyFile(file);
|
|
146
|
+
completed++;
|
|
147
|
+
this.reportProgress(completed);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
this.errors.push({
|
|
150
|
+
file: file.path,
|
|
151
|
+
error: error instanceof Error ? error.message : String(error),
|
|
152
|
+
phase: 'write'
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async copyFilesParallel() {
|
|
158
|
+
const workerCount = Math.min(this.options.maxWorkers, this.fileQueue.length);
|
|
159
|
+
const chunkSize = Math.ceil(this.fileQueue.length / workerCount);
|
|
160
|
+
const workers = [];
|
|
161
|
+
for(let i = 0; i < workerCount; i++){
|
|
162
|
+
const start = i * chunkSize;
|
|
163
|
+
const end = Math.min(start + chunkSize, this.fileQueue.length);
|
|
164
|
+
const chunk = this.fileQueue.slice(start, end);
|
|
165
|
+
if (chunk.length > 0) {
|
|
166
|
+
workers.push(this.processChunk(chunk, i));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
await Promise.all(workers);
|
|
170
|
+
}
|
|
171
|
+
async processChunk(files, workerId) {
|
|
172
|
+
for (const file of files){
|
|
173
|
+
try {
|
|
174
|
+
await this.copyFile(file);
|
|
175
|
+
this.copiedFiles.add(file.path);
|
|
176
|
+
this.reportProgress(this.copiedFiles.size);
|
|
177
|
+
} catch (error) {
|
|
178
|
+
this.errors.push({
|
|
179
|
+
file: file.path,
|
|
180
|
+
error: error instanceof Error ? error.message : String(error),
|
|
181
|
+
phase: 'write'
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async copyFile(file) {
|
|
187
|
+
const destPath = path.join(this.options.destination, file.relativePath);
|
|
188
|
+
if (this.options.dryRun) {
|
|
189
|
+
logger.info(`[DRY RUN] Would copy ${file.path} to ${destPath}`);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
// Check for conflicts
|
|
193
|
+
const destExists = await this.fileExists(destPath);
|
|
194
|
+
if (destExists) {
|
|
195
|
+
switch(this.options.conflictResolution){
|
|
196
|
+
case 'skip':
|
|
197
|
+
logger.info(`Skipping existing file: ${destPath}`);
|
|
198
|
+
return;
|
|
199
|
+
case 'backup':
|
|
200
|
+
await this.backupFile(destPath);
|
|
201
|
+
break;
|
|
202
|
+
case 'merge':
|
|
203
|
+
await this.mergeFiles(file.path, destPath);
|
|
204
|
+
return;
|
|
205
|
+
case 'overwrite':
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// Calculate source hash if verification is enabled
|
|
210
|
+
if (this.options.verify) {
|
|
211
|
+
file.hash = await this.calculateFileHash(file.path);
|
|
212
|
+
}
|
|
213
|
+
// Copy the file
|
|
214
|
+
await fs.copyFile(file.path, destPath);
|
|
215
|
+
// Preserve permissions if requested
|
|
216
|
+
if (this.options.preservePermissions && file.permissions) {
|
|
217
|
+
await fs.chmod(destPath, file.permissions);
|
|
218
|
+
}
|
|
219
|
+
// Add to rollback stack
|
|
220
|
+
this.rollbackStack.push(async ()=>{
|
|
221
|
+
if (destExists && this.backupMap.has(destPath)) {
|
|
222
|
+
// Restore from backup
|
|
223
|
+
const backupPath = this.backupMap.get(destPath);
|
|
224
|
+
await fs.copyFile(backupPath, destPath);
|
|
225
|
+
} else {
|
|
226
|
+
// Remove the copied file
|
|
227
|
+
await fs.unlink(destPath);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
this.copiedFiles.add(file.path);
|
|
231
|
+
}
|
|
232
|
+
async backupFile(filePath) {
|
|
233
|
+
const backupDir = path.join(this.options.destination, '.prompt-backups');
|
|
234
|
+
await fs.mkdir(backupDir, {
|
|
235
|
+
recursive: true
|
|
236
|
+
});
|
|
237
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
238
|
+
const backupName = `${path.basename(filePath)}.${timestamp}.bak`;
|
|
239
|
+
const backupPath = path.join(backupDir, backupName);
|
|
240
|
+
await fs.copyFile(filePath, backupPath);
|
|
241
|
+
this.backupMap.set(filePath, backupPath);
|
|
242
|
+
}
|
|
243
|
+
async mergeFiles(sourcePath, destPath) {
|
|
244
|
+
// Simple merge strategy: append source to destination with separator
|
|
245
|
+
const sourceContent = await fs.readFile(sourcePath, 'utf-8');
|
|
246
|
+
const destContent = await fs.readFile(destPath, 'utf-8');
|
|
247
|
+
const separator = '\n\n--- MERGED CONTENT ---\n\n';
|
|
248
|
+
const mergedContent = destContent + separator + sourceContent;
|
|
249
|
+
await this.backupFile(destPath);
|
|
250
|
+
await fs.writeFile(destPath, mergedContent, 'utf-8');
|
|
251
|
+
}
|
|
252
|
+
async verifyFiles() {
|
|
253
|
+
logger.info('Verifying copied files...');
|
|
254
|
+
for (const file of this.fileQueue){
|
|
255
|
+
if (!this.copiedFiles.has(file.path)) continue;
|
|
256
|
+
try {
|
|
257
|
+
const destPath = path.join(this.options.destination, file.relativePath);
|
|
258
|
+
// Verify file exists
|
|
259
|
+
if (!await this.fileExists(destPath)) {
|
|
260
|
+
throw new Error('Destination file not found');
|
|
261
|
+
}
|
|
262
|
+
// Verify size
|
|
263
|
+
const destStats = await fs.stat(destPath);
|
|
264
|
+
const sourceStats = await fs.stat(file.path);
|
|
265
|
+
if (destStats.size !== sourceStats.size) {
|
|
266
|
+
throw new Error(`Size mismatch: ${destStats.size} != ${sourceStats.size}`);
|
|
267
|
+
}
|
|
268
|
+
// Verify hash if available
|
|
269
|
+
if (file.hash) {
|
|
270
|
+
const destHash = await this.calculateFileHash(destPath);
|
|
271
|
+
if (destHash !== file.hash) {
|
|
272
|
+
throw new Error(`Hash mismatch: ${destHash} != ${file.hash}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
} catch (error) {
|
|
276
|
+
this.errors.push({
|
|
277
|
+
file: file.path,
|
|
278
|
+
error: error instanceof Error ? error.message : String(error),
|
|
279
|
+
phase: 'verify'
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
async calculateFileHash(filePath) {
|
|
285
|
+
const content = await fs.readFile(filePath);
|
|
286
|
+
return createHash('sha256').update(content).digest('hex');
|
|
287
|
+
}
|
|
288
|
+
async fileExists(filePath) {
|
|
289
|
+
try {
|
|
290
|
+
await fs.access(filePath);
|
|
291
|
+
return true;
|
|
292
|
+
} catch {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
async createBackupManifest() {
|
|
297
|
+
const manifestPath = path.join(this.options.destination, '.prompt-backups', `manifest-${Date.now()}.json`);
|
|
298
|
+
const manifest = {
|
|
299
|
+
timestamp: new Date().toISOString(),
|
|
300
|
+
source: this.options.source,
|
|
301
|
+
destination: this.options.destination,
|
|
302
|
+
backups: Array.from(this.backupMap.entries()).map(([original, backup])=>({
|
|
303
|
+
original,
|
|
304
|
+
backup
|
|
305
|
+
}))
|
|
306
|
+
};
|
|
307
|
+
await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2));
|
|
308
|
+
return manifestPath;
|
|
309
|
+
}
|
|
310
|
+
async rollback() {
|
|
311
|
+
logger.warn('Rolling back changes...');
|
|
312
|
+
// Execute rollback operations in reverse order
|
|
313
|
+
for(let i = this.rollbackStack.length - 1; i >= 0; i--){
|
|
314
|
+
try {
|
|
315
|
+
await this.rollbackStack[i]();
|
|
316
|
+
} catch (error) {
|
|
317
|
+
logger.error(`Rollback operation ${i} failed:`, error);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// Clean up backup directory if empty
|
|
321
|
+
try {
|
|
322
|
+
const backupDir = path.join(this.options.destination, '.prompt-backups');
|
|
323
|
+
const entries = await fs.readdir(backupDir);
|
|
324
|
+
if (entries.length === 0) {
|
|
325
|
+
await fs.rmdir(backupDir);
|
|
326
|
+
}
|
|
327
|
+
} catch {
|
|
328
|
+
// Ignore cleanup errors
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
reportProgress(completed) {
|
|
332
|
+
const progress = {
|
|
333
|
+
total: this.fileQueue.length,
|
|
334
|
+
completed,
|
|
335
|
+
failed: this.errors.length,
|
|
336
|
+
skipped: this.fileQueue.length - completed - this.errors.length,
|
|
337
|
+
percentage: Math.round(completed / this.fileQueue.length * 100)
|
|
338
|
+
};
|
|
339
|
+
this.emit('progress', progress);
|
|
340
|
+
this.options.progressCallback(progress);
|
|
341
|
+
}
|
|
342
|
+
// Utility method to restore from backup
|
|
343
|
+
async restoreFromBackup(manifestPath) {
|
|
344
|
+
const manifest = JSON.parse(await fs.readFile(manifestPath, 'utf-8'));
|
|
345
|
+
for (const { original, backup } of manifest.backups){
|
|
346
|
+
try {
|
|
347
|
+
await fs.copyFile(backup, original);
|
|
348
|
+
logger.info(`Restored ${original} from ${backup}`);
|
|
349
|
+
} catch (error) {
|
|
350
|
+
logger.error(`Failed to restore ${original}:`, error);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
constructor(options){
|
|
355
|
+
super(), _define_property(this, "options", void 0), _define_property(this, "fileQueue", []), _define_property(this, "copiedFiles", new Set()), _define_property(this, "errors", []), _define_property(this, "backupMap", new Map()), _define_property(this, "rollbackStack", []);
|
|
356
|
+
this.options = {
|
|
357
|
+
...options,
|
|
358
|
+
backup: options.backup ?? true,
|
|
359
|
+
overwrite: options.overwrite ?? false,
|
|
360
|
+
verify: options.verify ?? true,
|
|
361
|
+
preservePermissions: options.preservePermissions ?? true,
|
|
362
|
+
excludePatterns: options.excludePatterns ?? [],
|
|
363
|
+
includePatterns: options.includePatterns ?? [
|
|
364
|
+
'*.md',
|
|
365
|
+
'*.txt',
|
|
366
|
+
'*.prompt',
|
|
367
|
+
'*.prompts'
|
|
368
|
+
],
|
|
369
|
+
parallel: options.parallel ?? true,
|
|
370
|
+
maxWorkers: options.maxWorkers ?? 4,
|
|
371
|
+
dryRun: options.dryRun ?? false,
|
|
372
|
+
conflictResolution: options.conflictResolution ?? 'backup',
|
|
373
|
+
progressCallback: options.progressCallback ?? (()=>{})
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// Export convenience function
|
|
378
|
+
export async function copyPrompts(options) {
|
|
379
|
+
const copier = new PromptCopier(options);
|
|
380
|
+
return copier.copy();
|
|
381
|
+
}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
function _define_property(obj, key, value) {
|
|
2
|
+
if (key in obj) {
|
|
3
|
+
Object.defineProperty(obj, key, {
|
|
4
|
+
value: value,
|
|
5
|
+
enumerable: true,
|
|
6
|
+
configurable: true,
|
|
7
|
+
writable: true
|
|
8
|
+
});
|
|
9
|
+
} else {
|
|
10
|
+
obj[key] = value;
|
|
11
|
+
}
|
|
12
|
+
return obj;
|
|
13
|
+
}
|
|
14
|
+
import * as path from "path";
|
|
15
|
+
import { EventEmitter } from "events";
|
|
16
|
+
import { copyPromptsEnhanced } from "./prompt-copier-enhanced.js";
|
|
17
|
+
import { PromptConfigManager, PromptPathResolver, PromptValidator } from "./prompt-utils.js";
|
|
18
|
+
import { logger } from "../core/logger.js";
|
|
19
|
+
export class PromptManager extends EventEmitter {
|
|
20
|
+
async initialize() {
|
|
21
|
+
logger.info('Initializing PromptManager...');
|
|
22
|
+
// Load configuration
|
|
23
|
+
await this.configManager.loadConfig();
|
|
24
|
+
// Auto-discover prompt directories if enabled
|
|
25
|
+
if (this.options.autoDiscovery) {
|
|
26
|
+
const discovered = await this.pathResolver.discoverPromptDirectories();
|
|
27
|
+
if (discovered.length > 0) {
|
|
28
|
+
logger.info(`Auto-discovered ${discovered.length} prompt directories`);
|
|
29
|
+
// Update config with discovered directories
|
|
30
|
+
const config = this.configManager.getConfig();
|
|
31
|
+
const uniqueDirs = Array.from(new Set([
|
|
32
|
+
...config.sourceDirectories,
|
|
33
|
+
...discovered.map((dir)=>path.relative(this.options.basePath, dir))
|
|
34
|
+
]));
|
|
35
|
+
await this.configManager.saveConfig({
|
|
36
|
+
sourceDirectories: uniqueDirs
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
this.emit('initialized');
|
|
41
|
+
}
|
|
42
|
+
async copyPrompts(options = {}) {
|
|
43
|
+
const config = this.configManager.getConfig();
|
|
44
|
+
const profile = this.options.defaultProfile;
|
|
45
|
+
// Resolve paths
|
|
46
|
+
const resolved = this.pathResolver.resolvePaths(config.sourceDirectories, config.destinationDirectory);
|
|
47
|
+
if (resolved.sources.length === 0) {
|
|
48
|
+
throw new Error('No valid source directories found');
|
|
49
|
+
}
|
|
50
|
+
// Build copy options
|
|
51
|
+
const copyOptions = {
|
|
52
|
+
source: resolved.sources[0],
|
|
53
|
+
destination: resolved.destination,
|
|
54
|
+
...this.configManager.getProfile(profile),
|
|
55
|
+
...options
|
|
56
|
+
};
|
|
57
|
+
logger.info('Starting prompt copy operation', {
|
|
58
|
+
source: copyOptions.source,
|
|
59
|
+
destination: copyOptions.destination,
|
|
60
|
+
profile
|
|
61
|
+
});
|
|
62
|
+
this.emit('copyStart', copyOptions);
|
|
63
|
+
try {
|
|
64
|
+
const result = await (copyOptions.parallel ? copyPromptsEnhanced(copyOptions) : copyPrompts(copyOptions));
|
|
65
|
+
this.emit('copyComplete', result);
|
|
66
|
+
return result;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
this.emit('copyError', error);
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async copyFromMultipleSources(options = {}) {
|
|
73
|
+
const config = this.configManager.getConfig();
|
|
74
|
+
const resolved = this.pathResolver.resolvePaths(config.sourceDirectories, config.destinationDirectory);
|
|
75
|
+
const results = [];
|
|
76
|
+
for (const source of resolved.sources){
|
|
77
|
+
try {
|
|
78
|
+
const copyOptions = {
|
|
79
|
+
source,
|
|
80
|
+
destination: resolved.destination,
|
|
81
|
+
...this.configManager.getProfile(this.options.defaultProfile),
|
|
82
|
+
...options
|
|
83
|
+
};
|
|
84
|
+
logger.info(`Copying from source: ${source}`);
|
|
85
|
+
const result = await copyPrompts(copyOptions);
|
|
86
|
+
results.push(result);
|
|
87
|
+
this.emit('sourceComplete', {
|
|
88
|
+
source,
|
|
89
|
+
result
|
|
90
|
+
});
|
|
91
|
+
} catch (error) {
|
|
92
|
+
logger.error(`Failed to copy from ${source}:`, error);
|
|
93
|
+
this.emit('sourceError', {
|
|
94
|
+
source,
|
|
95
|
+
error
|
|
96
|
+
});
|
|
97
|
+
// Add error result
|
|
98
|
+
results.push({
|
|
99
|
+
success: false,
|
|
100
|
+
totalFiles: 0,
|
|
101
|
+
copiedFiles: 0,
|
|
102
|
+
failedFiles: 0,
|
|
103
|
+
skippedFiles: 0,
|
|
104
|
+
errors: [
|
|
105
|
+
{
|
|
106
|
+
file: source,
|
|
107
|
+
error: error instanceof Error ? error.message : String(error),
|
|
108
|
+
phase: 'read'
|
|
109
|
+
}
|
|
110
|
+
],
|
|
111
|
+
duration: 0
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return results;
|
|
116
|
+
}
|
|
117
|
+
async validatePrompts(sourcePath) {
|
|
118
|
+
const config = this.configManager.getConfig();
|
|
119
|
+
const sources = sourcePath ? [
|
|
120
|
+
sourcePath
|
|
121
|
+
] : config.sourceDirectories;
|
|
122
|
+
const resolved = this.pathResolver.resolvePaths(sources, config.destinationDirectory);
|
|
123
|
+
let totalFiles = 0;
|
|
124
|
+
let validFiles = 0;
|
|
125
|
+
let invalidFiles = 0;
|
|
126
|
+
const issues = [];
|
|
127
|
+
for (const source of resolved.sources){
|
|
128
|
+
await this.validateDirectory(source, issues);
|
|
129
|
+
}
|
|
130
|
+
totalFiles = issues.length;
|
|
131
|
+
validFiles = issues.filter((issue)=>issue.issues.length === 0).length;
|
|
132
|
+
invalidFiles = totalFiles - validFiles;
|
|
133
|
+
const report = {
|
|
134
|
+
totalFiles,
|
|
135
|
+
validFiles,
|
|
136
|
+
invalidFiles,
|
|
137
|
+
issues: issues.filter((issue)=>issue.issues.length > 0)
|
|
138
|
+
};
|
|
139
|
+
this.emit('validationComplete', report);
|
|
140
|
+
return report;
|
|
141
|
+
}
|
|
142
|
+
async validateDirectory(dirPath, issues) {
|
|
143
|
+
const fs = require('fs').promises;
|
|
144
|
+
try {
|
|
145
|
+
const entries = await fs.readdir(dirPath, {
|
|
146
|
+
withFileTypes: true
|
|
147
|
+
});
|
|
148
|
+
for (const entry of entries){
|
|
149
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
150
|
+
if (entry.isFile() && this.isPromptFile(entry.name)) {
|
|
151
|
+
const result = await PromptValidator.validatePromptFile(fullPath);
|
|
152
|
+
issues.push({
|
|
153
|
+
file: fullPath,
|
|
154
|
+
issues: result.issues,
|
|
155
|
+
metadata: result.metadata
|
|
156
|
+
});
|
|
157
|
+
} else if (entry.isDirectory()) {
|
|
158
|
+
await this.validateDirectory(fullPath, issues);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
} catch (error) {
|
|
162
|
+
logger.error(`Failed to validate directory ${dirPath}:`, error);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
isPromptFile(fileName) {
|
|
166
|
+
const config = this.configManager.getConfig();
|
|
167
|
+
const patterns = config.defaultOptions.includePatterns;
|
|
168
|
+
return patterns.some((pattern)=>{
|
|
169
|
+
const regex = pattern.replace(/\./g, '\\.').replace(/\*/g, '.*');
|
|
170
|
+
return new RegExp(regex).test(fileName);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
async syncPrompts(options = {}) {
|
|
174
|
+
const config = this.configManager.getConfig();
|
|
175
|
+
const resolved = this.pathResolver.resolvePaths(config.sourceDirectories, config.destinationDirectory);
|
|
176
|
+
const syncOptions = {
|
|
177
|
+
bidirectional: false,
|
|
178
|
+
deleteOrphaned: false,
|
|
179
|
+
compareHashes: true,
|
|
180
|
+
incrementalOnly: true,
|
|
181
|
+
...options
|
|
182
|
+
};
|
|
183
|
+
// Forward sync (source to destination)
|
|
184
|
+
const forwardResult = await this.performIncrementalSync(resolved.sources[0], resolved.destination, syncOptions);
|
|
185
|
+
let backwardResult;
|
|
186
|
+
// Backward sync if bidirectional
|
|
187
|
+
if (syncOptions.bidirectional) {
|
|
188
|
+
backwardResult = await this.performIncrementalSync(resolved.destination, resolved.sources[0], syncOptions);
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
forward: forwardResult,
|
|
192
|
+
backward: backwardResult
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
async performIncrementalSync(source, destination, options) {
|
|
196
|
+
// This would implement incremental sync logic
|
|
197
|
+
// For now, we'll use the regular copy with overwrite
|
|
198
|
+
return copyPrompts({
|
|
199
|
+
source,
|
|
200
|
+
destination,
|
|
201
|
+
conflictResolution: 'overwrite',
|
|
202
|
+
verify: options.compareHashes
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
async generateReport() {
|
|
206
|
+
const config = this.configManager.getConfig();
|
|
207
|
+
const resolved = this.pathResolver.resolvePaths(config.sourceDirectories, config.destinationDirectory);
|
|
208
|
+
// Analyze sources
|
|
209
|
+
const sources = await Promise.all(resolved.sources.map(async (sourcePath)=>{
|
|
210
|
+
try {
|
|
211
|
+
const fs = require('fs').promises;
|
|
212
|
+
const stats = await fs.stat(sourcePath);
|
|
213
|
+
if (!stats.isDirectory()) {
|
|
214
|
+
return {
|
|
215
|
+
path: sourcePath,
|
|
216
|
+
exists: false
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
// Count files and calculate total size
|
|
220
|
+
let fileCount = 0;
|
|
221
|
+
let totalSize = 0;
|
|
222
|
+
const scanDir = async (dir)=>{
|
|
223
|
+
const entries = await fs.readdir(dir, {
|
|
224
|
+
withFileTypes: true
|
|
225
|
+
});
|
|
226
|
+
for (const entry of entries){
|
|
227
|
+
const fullPath = path.join(dir, entry.name);
|
|
228
|
+
if (entry.isFile() && this.isPromptFile(entry.name)) {
|
|
229
|
+
const fileStats = await fs.stat(fullPath);
|
|
230
|
+
fileCount++;
|
|
231
|
+
totalSize += fileStats.size;
|
|
232
|
+
} else if (entry.isDirectory()) {
|
|
233
|
+
await scanDir(fullPath);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
await scanDir(sourcePath);
|
|
238
|
+
return {
|
|
239
|
+
path: sourcePath,
|
|
240
|
+
exists: true,
|
|
241
|
+
fileCount,
|
|
242
|
+
totalSize
|
|
243
|
+
};
|
|
244
|
+
} catch {
|
|
245
|
+
return {
|
|
246
|
+
path: sourcePath,
|
|
247
|
+
exists: false
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}));
|
|
251
|
+
return {
|
|
252
|
+
configuration: config,
|
|
253
|
+
sources
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
// Utility methods
|
|
257
|
+
getConfig() {
|
|
258
|
+
return this.configManager.getConfig();
|
|
259
|
+
}
|
|
260
|
+
async updateConfig(updates) {
|
|
261
|
+
await this.configManager.saveConfig(updates);
|
|
262
|
+
}
|
|
263
|
+
getProfiles() {
|
|
264
|
+
return this.configManager.listProfiles();
|
|
265
|
+
}
|
|
266
|
+
getProfile(name) {
|
|
267
|
+
return this.configManager.getProfile(name);
|
|
268
|
+
}
|
|
269
|
+
async discoverPromptDirectories() {
|
|
270
|
+
return this.pathResolver.discoverPromptDirectories();
|
|
271
|
+
}
|
|
272
|
+
constructor(options = {}){
|
|
273
|
+
super(), _define_property(this, "configManager", void 0), _define_property(this, "pathResolver", void 0), _define_property(this, "options", void 0);
|
|
274
|
+
this.options = {
|
|
275
|
+
configPath: options.configPath || '.prompt-config.json',
|
|
276
|
+
basePath: options.basePath || process.cwd(),
|
|
277
|
+
autoDiscovery: options.autoDiscovery ?? true,
|
|
278
|
+
defaultProfile: options.defaultProfile || 'sparc'
|
|
279
|
+
};
|
|
280
|
+
this.configManager = new PromptConfigManager(path.resolve(this.options.basePath, this.options.configPath));
|
|
281
|
+
this.pathResolver = new PromptPathResolver(this.options.basePath);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Export factory function
|
|
285
|
+
export function createPromptManager(options) {
|
|
286
|
+
return new PromptManager(options);
|
|
287
|
+
}
|
|
288
|
+
// Export singleton instance
|
|
289
|
+
let defaultManager = null;
|
|
290
|
+
export function getDefaultPromptManager() {
|
|
291
|
+
if (!defaultManager) {
|
|
292
|
+
defaultManager = new PromptManager();
|
|
293
|
+
}
|
|
294
|
+
return defaultManager;
|
|
295
|
+
}
|