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,227 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as os from "os";
|
|
4
|
+
import { PromptManager } from "../prompt-manager.js";
|
|
5
|
+
import { PromptConfigManager } from "../prompt-utils.js";
|
|
6
|
+
describe('Prompt Copying Integration Tests', ()=>{
|
|
7
|
+
let tempDir;
|
|
8
|
+
let testManager;
|
|
9
|
+
beforeEach(async ()=>{
|
|
10
|
+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'integration-test-'));
|
|
11
|
+
// Create test structure
|
|
12
|
+
const sourceDir = path.join(tempDir, 'source');
|
|
13
|
+
const destDir = path.join(tempDir, 'dest');
|
|
14
|
+
await fs.mkdir(sourceDir, {
|
|
15
|
+
recursive: true
|
|
16
|
+
});
|
|
17
|
+
await fs.mkdir(destDir, {
|
|
18
|
+
recursive: true
|
|
19
|
+
});
|
|
20
|
+
// Create test files
|
|
21
|
+
await createTestPromptStructure(sourceDir);
|
|
22
|
+
// Initialize manager
|
|
23
|
+
testManager = new PromptManager({
|
|
24
|
+
basePath: tempDir,
|
|
25
|
+
configPath: '.test-config.json',
|
|
26
|
+
autoDiscovery: false
|
|
27
|
+
});
|
|
28
|
+
// Configure manager
|
|
29
|
+
await testManager.updateConfig({
|
|
30
|
+
sourceDirectories: [
|
|
31
|
+
'source'
|
|
32
|
+
],
|
|
33
|
+
destinationDirectory: 'dest'
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
afterEach(async ()=>{
|
|
37
|
+
await fs.rm(tempDir, {
|
|
38
|
+
recursive: true,
|
|
39
|
+
force: true
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
async function createTestPromptStructure(sourceDir) {
|
|
43
|
+
const structure = {
|
|
44
|
+
'sparc/architect.md': '# Architect\nSystem design expert.',
|
|
45
|
+
'sparc/tdd.md': '# TDD\nTest-driven development.',
|
|
46
|
+
'sparc/code.md': '# Code\nImplementation expert.',
|
|
47
|
+
'templates/api.md': '# API Template\n{{endpoint}}',
|
|
48
|
+
'rules/general.md': '# Rules\nGeneral guidelines.',
|
|
49
|
+
'invalid.md': '',
|
|
50
|
+
'large.md': 'Large content\n'.repeat(100)
|
|
51
|
+
};
|
|
52
|
+
for (const [filePath, content] of Object.entries(structure)){
|
|
53
|
+
const fullPath = path.join(sourceDir, filePath);
|
|
54
|
+
const dir = path.dirname(fullPath);
|
|
55
|
+
await fs.mkdir(dir, {
|
|
56
|
+
recursive: true
|
|
57
|
+
});
|
|
58
|
+
await fs.writeFile(fullPath, content);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
test('should initialize and auto-discover prompt directories', async ()=>{
|
|
62
|
+
const discoveryManager = new PromptManager({
|
|
63
|
+
basePath: tempDir,
|
|
64
|
+
autoDiscovery: true
|
|
65
|
+
});
|
|
66
|
+
await discoveryManager.initialize();
|
|
67
|
+
const config = discoveryManager.getConfig();
|
|
68
|
+
expect(config.sourceDirectories.length).toBeGreaterThan(0);
|
|
69
|
+
});
|
|
70
|
+
test('should copy prompts using different profiles', async ()=>{
|
|
71
|
+
await testManager.initialize();
|
|
72
|
+
// Test with safe profile
|
|
73
|
+
const safeResult = await testManager.copyPrompts({
|
|
74
|
+
conflictResolution: 'skip',
|
|
75
|
+
parallel: false
|
|
76
|
+
});
|
|
77
|
+
expect(safeResult.success).toBe(true);
|
|
78
|
+
expect(safeResult.copiedFiles).toBeGreaterThan(0);
|
|
79
|
+
// Verify files exist
|
|
80
|
+
const destFiles = await fs.readdir(path.join(tempDir, 'dest'), {
|
|
81
|
+
recursive: true
|
|
82
|
+
});
|
|
83
|
+
expect(destFiles.length).toBeGreaterThan(0);
|
|
84
|
+
});
|
|
85
|
+
test('should validate prompts and generate reports', async ()=>{
|
|
86
|
+
await testManager.initialize();
|
|
87
|
+
// Copy files first
|
|
88
|
+
await testManager.copyPrompts();
|
|
89
|
+
// Validate prompts
|
|
90
|
+
const validation = await testManager.validatePrompts();
|
|
91
|
+
expect(validation.totalFiles).toBeGreaterThan(0);
|
|
92
|
+
expect(validation.validFiles).toBeGreaterThan(0);
|
|
93
|
+
expect(validation.invalidFiles).toBeGreaterThan(0); // Should find the empty file
|
|
94
|
+
// Check that empty file is flagged as invalid
|
|
95
|
+
const emptyFileIssue = validation.issues.find((issue)=>issue.file.includes('invalid.md'));
|
|
96
|
+
expect(emptyFileIssue).toBeDefined();
|
|
97
|
+
expect(emptyFileIssue.issues).toContain('File is empty');
|
|
98
|
+
});
|
|
99
|
+
test('should handle multiple sources', async ()=>{
|
|
100
|
+
// Create second source
|
|
101
|
+
const source2Dir = path.join(tempDir, 'source2');
|
|
102
|
+
await fs.mkdir(source2Dir, {
|
|
103
|
+
recursive: true
|
|
104
|
+
});
|
|
105
|
+
await fs.writeFile(path.join(source2Dir, 'extra.md'), '# Extra\nExtra prompt.');
|
|
106
|
+
// Update config
|
|
107
|
+
await testManager.updateConfig({
|
|
108
|
+
sourceDirectories: [
|
|
109
|
+
'source',
|
|
110
|
+
'source2'
|
|
111
|
+
]
|
|
112
|
+
});
|
|
113
|
+
await testManager.initialize();
|
|
114
|
+
// Copy from multiple sources
|
|
115
|
+
const results = await testManager.copyFromMultipleSources();
|
|
116
|
+
expect(results.length).toBe(2);
|
|
117
|
+
expect(results.every((r)=>r.success)).toBe(true);
|
|
118
|
+
// Verify files from both sources
|
|
119
|
+
const destFiles = await fs.readdir(path.join(tempDir, 'dest'), {
|
|
120
|
+
recursive: true
|
|
121
|
+
});
|
|
122
|
+
expect(destFiles).toContain('extra.md');
|
|
123
|
+
});
|
|
124
|
+
test('should generate comprehensive system report', async ()=>{
|
|
125
|
+
await testManager.initialize();
|
|
126
|
+
await testManager.copyPrompts();
|
|
127
|
+
const report = await testManager.generateReport();
|
|
128
|
+
expect(report.configuration).toBeDefined();
|
|
129
|
+
expect(report.sources).toBeDefined();
|
|
130
|
+
expect(report.sources.length).toBeGreaterThan(0);
|
|
131
|
+
// Check source analysis
|
|
132
|
+
const sourceInfo = report.sources[0];
|
|
133
|
+
expect(sourceInfo.exists).toBe(true);
|
|
134
|
+
expect(sourceInfo.fileCount).toBeGreaterThan(0);
|
|
135
|
+
expect(sourceInfo.totalSize).toBeGreaterThan(0);
|
|
136
|
+
});
|
|
137
|
+
test('should handle configuration persistence', async ()=>{
|
|
138
|
+
const configManager = new PromptConfigManager(path.join(tempDir, '.test-config.json'));
|
|
139
|
+
// Save custom config
|
|
140
|
+
await configManager.saveConfig({
|
|
141
|
+
destinationDirectory: './custom-dest',
|
|
142
|
+
defaultOptions: {
|
|
143
|
+
maxWorkers: 8,
|
|
144
|
+
conflictResolution: 'merge'
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
// Load config in new instance
|
|
148
|
+
const newConfigManager = new PromptConfigManager(path.join(tempDir, '.test-config.json'));
|
|
149
|
+
const config = await newConfigManager.loadConfig();
|
|
150
|
+
expect(config.destinationDirectory).toBe('./custom-dest');
|
|
151
|
+
expect(config.defaultOptions.maxWorkers).toBe(8);
|
|
152
|
+
expect(config.defaultOptions.conflictResolution).toBe('merge');
|
|
153
|
+
});
|
|
154
|
+
test('should handle errors gracefully', async ()=>{
|
|
155
|
+
// Test with invalid source directory
|
|
156
|
+
await testManager.updateConfig({
|
|
157
|
+
sourceDirectories: [
|
|
158
|
+
'nonexistent'
|
|
159
|
+
]
|
|
160
|
+
});
|
|
161
|
+
await testManager.initialize();
|
|
162
|
+
// Should not throw but return failed result
|
|
163
|
+
const result = await testManager.copyPrompts();
|
|
164
|
+
// The result should indicate failure or no files copied
|
|
165
|
+
expect(result.copiedFiles).toBe(0);
|
|
166
|
+
});
|
|
167
|
+
test('should support incremental sync', async ()=>{
|
|
168
|
+
await testManager.initialize();
|
|
169
|
+
// Initial copy
|
|
170
|
+
const firstResult = await testManager.copyPrompts();
|
|
171
|
+
expect(firstResult.success).toBe(true);
|
|
172
|
+
// Modify source file
|
|
173
|
+
const sourceFile = path.join(tempDir, 'source', 'sparc', 'architect.md');
|
|
174
|
+
await fs.writeFile(sourceFile, '# Modified Architect\nUpdated content.');
|
|
175
|
+
// Sync should detect changes
|
|
176
|
+
const syncResult = await testManager.syncPrompts({
|
|
177
|
+
incrementalOnly: true,
|
|
178
|
+
compareHashes: true
|
|
179
|
+
});
|
|
180
|
+
expect(syncResult.forward.success).toBe(true);
|
|
181
|
+
});
|
|
182
|
+
test('should respect include/exclude patterns', async ()=>{
|
|
183
|
+
await testManager.initialize();
|
|
184
|
+
// Copy only .md files from sparc directory
|
|
185
|
+
const result = await testManager.copyPrompts({
|
|
186
|
+
includePatterns: [
|
|
187
|
+
'**/sparc/*.md'
|
|
188
|
+
],
|
|
189
|
+
excludePatterns: [
|
|
190
|
+
'**/tdd.md'
|
|
191
|
+
]
|
|
192
|
+
});
|
|
193
|
+
expect(result.success).toBe(true);
|
|
194
|
+
// Check that only architect.md and code.md were copied
|
|
195
|
+
const sparcDir = path.join(tempDir, 'dest', 'sparc');
|
|
196
|
+
const sparcFiles = await fs.readdir(sparcDir).catch(()=>[]);
|
|
197
|
+
expect(sparcFiles).toContain('architect.md');
|
|
198
|
+
expect(sparcFiles).toContain('code.md');
|
|
199
|
+
expect(sparcFiles).not.toContain('tdd.md');
|
|
200
|
+
});
|
|
201
|
+
test('should handle concurrent operations', async ()=>{
|
|
202
|
+
await testManager.initialize();
|
|
203
|
+
// Start multiple copy operations
|
|
204
|
+
const operations = [
|
|
205
|
+
testManager.copyPrompts({
|
|
206
|
+
destination: path.join(tempDir, 'dest1')
|
|
207
|
+
}),
|
|
208
|
+
testManager.copyPrompts({
|
|
209
|
+
destination: path.join(tempDir, 'dest2')
|
|
210
|
+
}),
|
|
211
|
+
testManager.copyPrompts({
|
|
212
|
+
destination: path.join(tempDir, 'dest3')
|
|
213
|
+
})
|
|
214
|
+
];
|
|
215
|
+
const results = await Promise.all(operations);
|
|
216
|
+
// All operations should succeed
|
|
217
|
+
expect(results.every((r)=>r.success)).toBe(true);
|
|
218
|
+
// Verify all destinations have files
|
|
219
|
+
for(let i = 1; i <= 3; i++){
|
|
220
|
+
const destDir = path.join(tempDir, `dest${i}`);
|
|
221
|
+
const files = await fs.readdir(destDir, {
|
|
222
|
+
recursive: true
|
|
223
|
+
});
|
|
224
|
+
expect(files.length).toBeGreaterThan(0);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
});
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as os from "os";
|
|
4
|
+
import { copyPrompts } from "../prompt-copier.js";
|
|
5
|
+
import { copyPromptsEnhanced } from "../prompt-copier-enhanced.js";
|
|
6
|
+
import { PromptConfigManager, PromptValidator } from "../prompt-utils.js";
|
|
7
|
+
describe('PromptCopier', ()=>{
|
|
8
|
+
let tempDir;
|
|
9
|
+
let sourceDir;
|
|
10
|
+
let destDir;
|
|
11
|
+
beforeEach(async ()=>{
|
|
12
|
+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'prompt-test-'));
|
|
13
|
+
sourceDir = path.join(tempDir, 'source');
|
|
14
|
+
destDir = path.join(tempDir, 'dest');
|
|
15
|
+
await fs.mkdir(sourceDir, {
|
|
16
|
+
recursive: true
|
|
17
|
+
});
|
|
18
|
+
await fs.mkdir(destDir, {
|
|
19
|
+
recursive: true
|
|
20
|
+
});
|
|
21
|
+
// Create test files
|
|
22
|
+
await createTestFiles();
|
|
23
|
+
});
|
|
24
|
+
afterEach(async ()=>{
|
|
25
|
+
await fs.rm(tempDir, {
|
|
26
|
+
recursive: true,
|
|
27
|
+
force: true
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
async function createTestFiles() {
|
|
31
|
+
const testFiles = [
|
|
32
|
+
{
|
|
33
|
+
path: 'test1.md',
|
|
34
|
+
content: '# Test Prompt 1\nThis is a test prompt.'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
path: 'test2.txt',
|
|
38
|
+
content: 'Test prompt content'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
path: 'subdir/test3.md',
|
|
42
|
+
content: '## Nested Prompt\nNested content'
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
path: 'large.md',
|
|
46
|
+
content: 'Large content\n'.repeat(1000)
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
path: 'empty.md',
|
|
50
|
+
content: ''
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
path: 'rules.md',
|
|
54
|
+
content: '# Rules\nYou are an AI assistant.'
|
|
55
|
+
}
|
|
56
|
+
];
|
|
57
|
+
for (const file of testFiles){
|
|
58
|
+
const filePath = path.join(sourceDir, file.path);
|
|
59
|
+
const dir = path.dirname(filePath);
|
|
60
|
+
await fs.mkdir(dir, {
|
|
61
|
+
recursive: true
|
|
62
|
+
});
|
|
63
|
+
await fs.writeFile(filePath, file.content);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
describe('Basic copying functionality', ()=>{
|
|
67
|
+
test('should copy all matching files', async ()=>{
|
|
68
|
+
const result = await copyPrompts({
|
|
69
|
+
source: sourceDir,
|
|
70
|
+
destination: destDir
|
|
71
|
+
});
|
|
72
|
+
expect(result.success).toBe(true);
|
|
73
|
+
expect(result.copiedFiles).toBe(6);
|
|
74
|
+
expect(result.failedFiles).toBe(0);
|
|
75
|
+
// Verify files exist
|
|
76
|
+
const destFiles = await fs.readdir(destDir, {
|
|
77
|
+
recursive: true
|
|
78
|
+
});
|
|
79
|
+
expect(destFiles).toHaveLength(6);
|
|
80
|
+
});
|
|
81
|
+
test('should respect include patterns', async ()=>{
|
|
82
|
+
const result = await copyPrompts({
|
|
83
|
+
source: sourceDir,
|
|
84
|
+
destination: destDir,
|
|
85
|
+
includePatterns: [
|
|
86
|
+
'*.md'
|
|
87
|
+
]
|
|
88
|
+
});
|
|
89
|
+
expect(result.success).toBe(true);
|
|
90
|
+
expect(result.copiedFiles).toBe(5); // Only .md files
|
|
91
|
+
});
|
|
92
|
+
test('should respect exclude patterns', async ()=>{
|
|
93
|
+
const result = await copyPrompts({
|
|
94
|
+
source: sourceDir,
|
|
95
|
+
destination: destDir,
|
|
96
|
+
excludePatterns: [
|
|
97
|
+
'**/subdir/**'
|
|
98
|
+
]
|
|
99
|
+
});
|
|
100
|
+
expect(result.success).toBe(true);
|
|
101
|
+
expect(result.copiedFiles).toBe(5); // Excluding subdir files
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
describe('Conflict resolution', ()=>{
|
|
105
|
+
test('should skip existing files when conflict resolution is skip', async ()=>{
|
|
106
|
+
// Create existing file
|
|
107
|
+
await fs.writeFile(path.join(destDir, 'test1.md'), 'Existing content');
|
|
108
|
+
const result = await copyPrompts({
|
|
109
|
+
source: sourceDir,
|
|
110
|
+
destination: destDir,
|
|
111
|
+
conflictResolution: 'skip'
|
|
112
|
+
});
|
|
113
|
+
expect(result.success).toBe(true);
|
|
114
|
+
expect(result.skippedFiles).toBeGreaterThan(0);
|
|
115
|
+
// Verify original content preserved
|
|
116
|
+
const content = await fs.readFile(path.join(destDir, 'test1.md'), 'utf-8');
|
|
117
|
+
expect(content).toBe('Existing content');
|
|
118
|
+
});
|
|
119
|
+
test('should backup existing files when conflict resolution is backup', async ()=>{
|
|
120
|
+
// Create existing file
|
|
121
|
+
await fs.writeFile(path.join(destDir, 'test1.md'), 'Existing content');
|
|
122
|
+
const result = await copyPrompts({
|
|
123
|
+
source: sourceDir,
|
|
124
|
+
destination: destDir,
|
|
125
|
+
conflictResolution: 'backup'
|
|
126
|
+
});
|
|
127
|
+
expect(result.success).toBe(true);
|
|
128
|
+
expect(result.backupLocation).toBeDefined();
|
|
129
|
+
// Verify backup directory exists
|
|
130
|
+
const backupDir = path.join(destDir, '.prompt-backups');
|
|
131
|
+
const backupExists = await fs.access(backupDir).then(()=>true).catch(()=>false);
|
|
132
|
+
expect(backupExists).toBe(true);
|
|
133
|
+
});
|
|
134
|
+
test('should merge files when conflict resolution is merge', async ()=>{
|
|
135
|
+
// Create existing file
|
|
136
|
+
await fs.writeFile(path.join(destDir, 'test1.md'), 'Existing content');
|
|
137
|
+
const result = await copyPrompts({
|
|
138
|
+
source: sourceDir,
|
|
139
|
+
destination: destDir,
|
|
140
|
+
conflictResolution: 'merge'
|
|
141
|
+
});
|
|
142
|
+
expect(result.success).toBe(true);
|
|
143
|
+
// Verify merged content
|
|
144
|
+
const content = await fs.readFile(path.join(destDir, 'test1.md'), 'utf-8');
|
|
145
|
+
expect(content).toContain('Existing content');
|
|
146
|
+
expect(content).toContain('MERGED CONTENT');
|
|
147
|
+
expect(content).toContain('# Test Prompt 1');
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
describe('Verification', ()=>{
|
|
151
|
+
test('should verify copied files when verification is enabled', async ()=>{
|
|
152
|
+
const result = await copyPrompts({
|
|
153
|
+
source: sourceDir,
|
|
154
|
+
destination: destDir,
|
|
155
|
+
verify: true
|
|
156
|
+
});
|
|
157
|
+
expect(result.success).toBe(true);
|
|
158
|
+
expect(result.failedFiles).toBe(0);
|
|
159
|
+
});
|
|
160
|
+
test('should detect verification failures', async ()=>{
|
|
161
|
+
// Mock fs.stat to simulate size mismatch
|
|
162
|
+
const originalStat = fs.stat;
|
|
163
|
+
jest.spyOn(fs, 'stat').mockImplementation(async (filePath)=>{
|
|
164
|
+
const stats = await originalStat(filePath);
|
|
165
|
+
if (filePath.includes('dest') && filePath.includes('test1.md')) {
|
|
166
|
+
return {
|
|
167
|
+
...stats,
|
|
168
|
+
size: stats.size + 1
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return stats;
|
|
172
|
+
});
|
|
173
|
+
const result = await copyPrompts({
|
|
174
|
+
source: sourceDir,
|
|
175
|
+
destination: destDir,
|
|
176
|
+
verify: true
|
|
177
|
+
});
|
|
178
|
+
expect(result.errors.length).toBeGreaterThan(0);
|
|
179
|
+
expect(result.errors[0].phase).toBe('verify');
|
|
180
|
+
fs.stat.mockRestore();
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
describe('Dry run mode', ()=>{
|
|
184
|
+
test('should not create files in dry run mode', async ()=>{
|
|
185
|
+
const result = await copyPrompts({
|
|
186
|
+
source: sourceDir,
|
|
187
|
+
destination: destDir,
|
|
188
|
+
dryRun: true
|
|
189
|
+
});
|
|
190
|
+
expect(result.success).toBe(true);
|
|
191
|
+
expect(result.totalFiles).toBe(6);
|
|
192
|
+
// Verify no files were actually copied
|
|
193
|
+
const destFiles = await fs.readdir(destDir);
|
|
194
|
+
expect(destFiles).toHaveLength(0);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
describe('Progress reporting', ()=>{
|
|
198
|
+
test('should report progress during copy', async ()=>{
|
|
199
|
+
const progressUpdates = [];
|
|
200
|
+
await copyPrompts({
|
|
201
|
+
source: sourceDir,
|
|
202
|
+
destination: destDir,
|
|
203
|
+
progressCallback: (progress)=>{
|
|
204
|
+
progressUpdates.push(progress);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
expect(progressUpdates.length).toBeGreaterThan(0);
|
|
208
|
+
expect(progressUpdates[progressUpdates.length - 1].percentage).toBe(100);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
describe('EnhancedPromptCopier', ()=>{
|
|
213
|
+
let tempDir;
|
|
214
|
+
let sourceDir;
|
|
215
|
+
let destDir;
|
|
216
|
+
beforeEach(async ()=>{
|
|
217
|
+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'enhanced-test-'));
|
|
218
|
+
sourceDir = path.join(tempDir, 'source');
|
|
219
|
+
destDir = path.join(tempDir, 'dest');
|
|
220
|
+
await fs.mkdir(sourceDir, {
|
|
221
|
+
recursive: true
|
|
222
|
+
});
|
|
223
|
+
await fs.mkdir(destDir, {
|
|
224
|
+
recursive: true
|
|
225
|
+
});
|
|
226
|
+
// Create test files
|
|
227
|
+
for(let i = 0; i < 20; i++){
|
|
228
|
+
await fs.writeFile(path.join(sourceDir, `test${i}.md`), `# Test ${i}\nContent for test ${i}`);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
afterEach(async ()=>{
|
|
232
|
+
await fs.rm(tempDir, {
|
|
233
|
+
recursive: true,
|
|
234
|
+
force: true
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
test('should copy files using worker threads', async ()=>{
|
|
238
|
+
const result = await copyPromptsEnhanced({
|
|
239
|
+
source: sourceDir,
|
|
240
|
+
destination: destDir,
|
|
241
|
+
parallel: true,
|
|
242
|
+
maxWorkers: 4
|
|
243
|
+
});
|
|
244
|
+
expect(result.success).toBe(true);
|
|
245
|
+
expect(result.copiedFiles).toBe(20);
|
|
246
|
+
expect(result.failedFiles).toBe(0);
|
|
247
|
+
// Verify all files were copied
|
|
248
|
+
const destFiles = await fs.readdir(destDir);
|
|
249
|
+
expect(destFiles).toHaveLength(20);
|
|
250
|
+
}, 10000);
|
|
251
|
+
});
|
|
252
|
+
describe('PromptConfigManager', ()=>{
|
|
253
|
+
let tempDir;
|
|
254
|
+
let configPath;
|
|
255
|
+
beforeEach(async ()=>{
|
|
256
|
+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'config-test-'));
|
|
257
|
+
configPath = path.join(tempDir, '.prompt-config.json');
|
|
258
|
+
});
|
|
259
|
+
afterEach(async ()=>{
|
|
260
|
+
await fs.rm(tempDir, {
|
|
261
|
+
recursive: true,
|
|
262
|
+
force: true
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
test('should load default config when file does not exist', async ()=>{
|
|
266
|
+
const manager = new PromptConfigManager(configPath);
|
|
267
|
+
const config = await manager.loadConfig();
|
|
268
|
+
expect(config).toBeDefined();
|
|
269
|
+
expect(config.defaultOptions).toBeDefined();
|
|
270
|
+
expect(config.profiles).toBeDefined();
|
|
271
|
+
});
|
|
272
|
+
test('should save and load custom config', async ()=>{
|
|
273
|
+
const manager = new PromptConfigManager(configPath);
|
|
274
|
+
await manager.saveConfig({
|
|
275
|
+
destinationDirectory: './custom-prompts'
|
|
276
|
+
});
|
|
277
|
+
const config = await manager.loadConfig();
|
|
278
|
+
expect(config.destinationDirectory).toBe('./custom-prompts');
|
|
279
|
+
});
|
|
280
|
+
test('should get profile options', async ()=>{
|
|
281
|
+
const manager = new PromptConfigManager(configPath);
|
|
282
|
+
await manager.loadConfig();
|
|
283
|
+
const sparcProfile = manager.getProfile('sparc');
|
|
284
|
+
expect(sparcProfile).toBeDefined();
|
|
285
|
+
expect(sparcProfile.includePatterns).toContain('*.md');
|
|
286
|
+
});
|
|
287
|
+
test('should list available profiles', async ()=>{
|
|
288
|
+
const manager = new PromptConfigManager(configPath);
|
|
289
|
+
await manager.loadConfig();
|
|
290
|
+
const profiles = manager.listProfiles();
|
|
291
|
+
expect(profiles).toContain('sparc');
|
|
292
|
+
expect(profiles).toContain('templates');
|
|
293
|
+
expect(profiles).toContain('safe');
|
|
294
|
+
expect(profiles).toContain('fast');
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
describe('PromptValidator', ()=>{
|
|
298
|
+
let tempDir;
|
|
299
|
+
beforeEach(async ()=>{
|
|
300
|
+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'validator-test-'));
|
|
301
|
+
});
|
|
302
|
+
afterEach(async ()=>{
|
|
303
|
+
await fs.rm(tempDir, {
|
|
304
|
+
recursive: true,
|
|
305
|
+
force: true
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
test('should validate valid prompt file', async ()=>{
|
|
309
|
+
const filePath = path.join(tempDir, 'valid.md');
|
|
310
|
+
await fs.writeFile(filePath, '# Test Prompt\nYou are an AI assistant.');
|
|
311
|
+
const result = await PromptValidator.validatePromptFile(filePath);
|
|
312
|
+
expect(result.valid).toBe(true);
|
|
313
|
+
expect(result.issues).toHaveLength(0);
|
|
314
|
+
});
|
|
315
|
+
test('should detect empty files', async ()=>{
|
|
316
|
+
const filePath = path.join(tempDir, 'empty.md');
|
|
317
|
+
await fs.writeFile(filePath, '');
|
|
318
|
+
const result = await PromptValidator.validatePromptFile(filePath);
|
|
319
|
+
expect(result.valid).toBe(false);
|
|
320
|
+
expect(result.issues).toContain('File is empty');
|
|
321
|
+
});
|
|
322
|
+
test('should extract front matter metadata', async ()=>{
|
|
323
|
+
const filePath = path.join(tempDir, 'with-metadata.md');
|
|
324
|
+
const content = `---
|
|
325
|
+
title: Test Prompt
|
|
326
|
+
version: 1.0
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
# Test Prompt
|
|
330
|
+
Content here`;
|
|
331
|
+
await fs.writeFile(filePath, content);
|
|
332
|
+
const result = await PromptValidator.validatePromptFile(filePath);
|
|
333
|
+
expect(result.metadata).toBeDefined();
|
|
334
|
+
expect(result.metadata.title).toBe('Test Prompt');
|
|
335
|
+
expect(result.metadata.version).toBe('1.0');
|
|
336
|
+
});
|
|
337
|
+
test('should warn about large files', async ()=>{
|
|
338
|
+
const filePath = path.join(tempDir, 'large.md');
|
|
339
|
+
const largeContent = '# Large Prompt\n' + 'x'.repeat(200 * 1024); // 200KB
|
|
340
|
+
await fs.writeFile(filePath, largeContent);
|
|
341
|
+
const result = await PromptValidator.validatePromptFile(filePath);
|
|
342
|
+
expect(result.issues).toContain('File is unusually large for a prompt');
|
|
343
|
+
});
|
|
344
|
+
});
|