faf-cli 2.4.19 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +244 -129
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/auto.d.ts.map +1 -1
- package/dist/commands/auto.js +63 -2
- package/dist/commands/auto.js.map +1 -1
- package/dist/commands/bi-sync.d.ts +9 -6
- package/dist/commands/bi-sync.d.ts.map +1 -1
- package/dist/commands/bi-sync.js +31 -16
- package/dist/commands/bi-sync.js.map +1 -1
- package/dist/commands/index.js +1 -6
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +17 -2
- package/dist/commands/status.js.map +1 -1
- package/dist/engines/c-mirror/broadcast/terminal-display.d.ts +23 -0
- package/dist/engines/c-mirror/broadcast/terminal-display.d.ts.map +1 -0
- package/dist/engines/c-mirror/broadcast/terminal-display.js +193 -0
- package/dist/engines/c-mirror/broadcast/terminal-display.js.map +1 -0
- package/dist/engines/c-mirror/core/claude-to-faf.d.ts +28 -0
- package/dist/engines/c-mirror/core/claude-to-faf.d.ts.map +1 -0
- package/dist/engines/c-mirror/core/claude-to-faf.js +222 -0
- package/dist/engines/c-mirror/core/claude-to-faf.js.map +1 -0
- package/dist/engines/c-mirror/core/events/event-emitter.d.ts +36 -0
- package/dist/engines/c-mirror/core/events/event-emitter.d.ts.map +1 -0
- package/dist/engines/c-mirror/core/events/event-emitter.js +71 -0
- package/dist/engines/c-mirror/core/events/event-emitter.js.map +1 -0
- package/dist/engines/c-mirror/core/events/mirror-events.d.ts +103 -0
- package/dist/engines/c-mirror/core/events/mirror-events.d.ts.map +1 -0
- package/dist/engines/c-mirror/core/events/mirror-events.js +65 -0
- package/dist/engines/c-mirror/core/events/mirror-events.js.map +1 -0
- package/dist/engines/c-mirror/core/faf-to-claude.d.ts +18 -0
- package/dist/engines/c-mirror/core/faf-to-claude.d.ts.map +1 -0
- package/dist/engines/c-mirror/core/faf-to-claude.js +193 -0
- package/dist/engines/c-mirror/core/faf-to-claude.js.map +1 -0
- package/dist/engines/c-mirror/core/interfaces.d.ts +153 -0
- package/dist/engines/c-mirror/core/interfaces.d.ts.map +1 -0
- package/dist/engines/c-mirror/core/interfaces.js +8 -0
- package/dist/engines/c-mirror/core/interfaces.js.map +1 -0
- package/dist/engines/c-mirror/core/mirror-engine.d.ts +48 -0
- package/dist/engines/c-mirror/core/mirror-engine.d.ts.map +1 -0
- package/dist/engines/c-mirror/core/mirror-engine.js +272 -0
- package/dist/engines/c-mirror/core/mirror-engine.js.map +1 -0
- package/dist/engines/c-mirror/faf-extensions/faf-mirror.d.ts +31 -0
- package/dist/engines/c-mirror/faf-extensions/faf-mirror.d.ts.map +1 -0
- package/dist/engines/c-mirror/faf-extensions/faf-mirror.js +101 -0
- package/dist/engines/c-mirror/faf-extensions/faf-mirror.js.map +1 -0
- package/dist/engines/c-mirror/strategies/atomic-write.d.ts +34 -0
- package/dist/engines/c-mirror/strategies/atomic-write.d.ts.map +1 -0
- package/dist/engines/c-mirror/strategies/atomic-write.js +132 -0
- package/dist/engines/c-mirror/strategies/atomic-write.js.map +1 -0
- package/dist/utils/championship-core.d.ts +127 -0
- package/dist/utils/championship-core.d.ts.map +1 -0
- package/dist/utils/championship-core.js +203 -0
- package/dist/utils/championship-core.js.map +1 -0
- package/dist/utils/championship-style.d.ts.map +1 -1
- package/dist/utils/championship-style.js +3 -1
- package/dist/utils/championship-style.js.map +1 -1
- package/dist/utils/color-utils.d.ts.map +1 -1
- package/dist/utils/color-utils.js +29 -11
- package/dist/utils/color-utils.js.map +1 -1
- package/dist/utils/yaml-generator.d.ts.map +1 -1
- package/dist/utils/yaml-generator.js +9 -4
- package/dist/utils/yaml-generator.js.map +1 -1
- package/package.json +18 -3
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 🔗 Mirror Engine - The Orchestrator
|
|
4
|
+
* Coordinates all C-Mirror operations
|
|
5
|
+
*
|
|
6
|
+
* This is the main engine that:
|
|
7
|
+
* - Detects which files need syncing
|
|
8
|
+
* - Calls the transformation functions
|
|
9
|
+
* - Uses atomic writes for safety
|
|
10
|
+
* - Emits events for broadcasting
|
|
11
|
+
* - Ensures zero slippage
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* const engine = new MirrorEngine(config);
|
|
15
|
+
* const result = await engine.sync();
|
|
16
|
+
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
34
|
+
var ownKeys = function(o) {
|
|
35
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
36
|
+
var ar = [];
|
|
37
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
38
|
+
return ar;
|
|
39
|
+
};
|
|
40
|
+
return ownKeys(o);
|
|
41
|
+
};
|
|
42
|
+
return function (mod) {
|
|
43
|
+
if (mod && mod.__esModule) return mod;
|
|
44
|
+
var result = {};
|
|
45
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
46
|
+
__setModuleDefault(result, mod);
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
exports.MirrorEngine = void 0;
|
|
52
|
+
const YAML = __importStar(require("yaml"));
|
|
53
|
+
const faf_to_claude_1 = require("./faf-to-claude");
|
|
54
|
+
const claude_to_faf_1 = require("./claude-to-faf");
|
|
55
|
+
const atomic_write_1 = require("../strategies/atomic-write");
|
|
56
|
+
const event_emitter_1 = require("./events/event-emitter");
|
|
57
|
+
const mirror_events_1 = require("./events/mirror-events");
|
|
58
|
+
class MirrorEngine {
|
|
59
|
+
config;
|
|
60
|
+
projectPath;
|
|
61
|
+
constructor(config) {
|
|
62
|
+
this.config = {
|
|
63
|
+
atomicWrites: true, // Default to safe writes
|
|
64
|
+
selfHealing: true, // Default to auto-recovery
|
|
65
|
+
...config
|
|
66
|
+
};
|
|
67
|
+
this.projectPath = config.projectPath || process.cwd();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Main sync operation
|
|
71
|
+
* Intelligently syncs .faf ↔ CLAUDE.md
|
|
72
|
+
*/
|
|
73
|
+
async sync() {
|
|
74
|
+
const startTime = Date.now();
|
|
75
|
+
const result = {
|
|
76
|
+
success: false,
|
|
77
|
+
direction: 'none',
|
|
78
|
+
filesChanged: [],
|
|
79
|
+
conflicts: [],
|
|
80
|
+
duration: 0,
|
|
81
|
+
integrity: 'perfect'
|
|
82
|
+
};
|
|
83
|
+
try {
|
|
84
|
+
// Step 1: Analyze file states
|
|
85
|
+
const analysis = await this.analyzeFiles();
|
|
86
|
+
// Step 2: Determine sync strategy
|
|
87
|
+
const strategy = this.determineSyncStrategy(analysis);
|
|
88
|
+
result.direction = strategy;
|
|
89
|
+
// Step 3: Execute sync based on strategy
|
|
90
|
+
if (strategy === 'none') {
|
|
91
|
+
// No sync needed
|
|
92
|
+
result.success = true;
|
|
93
|
+
result.duration = Date.now() - startTime;
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
if (strategy === 'faf-to-claude') {
|
|
97
|
+
await this.syncFafToClaude(analysis);
|
|
98
|
+
result.filesChanged.push(this.config.readableFile);
|
|
99
|
+
}
|
|
100
|
+
else if (strategy === 'claude-to-faf') {
|
|
101
|
+
await this.syncClaudeToFaf(analysis);
|
|
102
|
+
result.filesChanged.push(this.config.structuredFile);
|
|
103
|
+
}
|
|
104
|
+
else if (strategy === 'bidirectional') {
|
|
105
|
+
// Both files changed - attempt intelligent merge
|
|
106
|
+
// For now, faf wins (can be enhanced later)
|
|
107
|
+
await this.syncFafToClaude(analysis);
|
|
108
|
+
result.filesChanged.push(this.config.readableFile);
|
|
109
|
+
result.conflicts.push('Both files modified - .faf took precedence');
|
|
110
|
+
}
|
|
111
|
+
// Step 4: Verify integrity
|
|
112
|
+
const integrityCheck = await this.verifyIntegrity();
|
|
113
|
+
result.integrity = integrityCheck.status;
|
|
114
|
+
// Step 5: Success
|
|
115
|
+
result.success = true;
|
|
116
|
+
result.duration = Date.now() - startTime;
|
|
117
|
+
// EMIT: Score update (if available)
|
|
118
|
+
if (integrityCheck.score) {
|
|
119
|
+
event_emitter_1.mirrorEvents.emitMirrorEvent((0, mirror_events_1.createMirrorEvent)(mirror_events_1.MirrorEventType.SCORE_UPDATE, {
|
|
120
|
+
score: integrityCheck.score
|
|
121
|
+
}, {
|
|
122
|
+
projectPath: this.projectPath,
|
|
123
|
+
score: integrityCheck.score,
|
|
124
|
+
duration: result.duration
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
result.success = false;
|
|
131
|
+
result.error = error instanceof Error ? error.message : String(error);
|
|
132
|
+
result.duration = Date.now() - startTime;
|
|
133
|
+
result.integrity = 'failed';
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Analyze file states to determine what needs syncing
|
|
139
|
+
*/
|
|
140
|
+
async analyzeFiles() {
|
|
141
|
+
const fafPath = this.config.structuredFile;
|
|
142
|
+
const claudePath = this.config.readableFile;
|
|
143
|
+
const fafExists = await (0, atomic_write_1.fileExists)(fafPath);
|
|
144
|
+
const claudeExists = await (0, atomic_write_1.fileExists)(claudePath);
|
|
145
|
+
const fafModified = fafExists ? await (0, atomic_write_1.getFileModifiedTime)(fafPath) : null;
|
|
146
|
+
const claudeModified = claudeExists ? await (0, atomic_write_1.getFileModifiedTime)(claudePath) : null;
|
|
147
|
+
const fafState = {
|
|
148
|
+
path: fafPath,
|
|
149
|
+
exists: fafExists,
|
|
150
|
+
modified: fafModified || undefined
|
|
151
|
+
};
|
|
152
|
+
const claudeState = {
|
|
153
|
+
path: claudePath,
|
|
154
|
+
exists: claudeExists,
|
|
155
|
+
modified: claudeModified || undefined
|
|
156
|
+
};
|
|
157
|
+
return { fafState, claudeState };
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Determine sync strategy based on file states
|
|
161
|
+
*/
|
|
162
|
+
determineSyncStrategy(analysis) {
|
|
163
|
+
const { fafState, claudeState } = analysis;
|
|
164
|
+
// If neither exists, nothing to sync
|
|
165
|
+
if (!fafState.exists && !claudeState.exists) {
|
|
166
|
+
return 'none';
|
|
167
|
+
}
|
|
168
|
+
// If only .faf exists, create CLAUDE.md
|
|
169
|
+
if (fafState.exists && !claudeState.exists) {
|
|
170
|
+
return 'faf-to-claude';
|
|
171
|
+
}
|
|
172
|
+
// If only CLAUDE.md exists, create .faf (unusual but handle it)
|
|
173
|
+
if (!fafState.exists && claudeState.exists) {
|
|
174
|
+
return 'claude-to-faf';
|
|
175
|
+
}
|
|
176
|
+
// Both exist - check modification times
|
|
177
|
+
if (fafState.modified && claudeState.modified) {
|
|
178
|
+
const fafTime = fafState.modified.getTime();
|
|
179
|
+
const claudeTime = claudeState.modified.getTime();
|
|
180
|
+
// If .faf is newer, sync to CLAUDE.md
|
|
181
|
+
if (fafTime > claudeTime) {
|
|
182
|
+
return 'faf-to-claude';
|
|
183
|
+
}
|
|
184
|
+
// If CLAUDE.md is newer, sync to .faf
|
|
185
|
+
if (claudeTime > fafTime) {
|
|
186
|
+
return 'claude-to-faf';
|
|
187
|
+
}
|
|
188
|
+
// If same time, no sync needed
|
|
189
|
+
return 'none';
|
|
190
|
+
}
|
|
191
|
+
// Default: faf to claude
|
|
192
|
+
return 'faf-to-claude';
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Sync .faf → CLAUDE.md
|
|
196
|
+
*/
|
|
197
|
+
async syncFafToClaude(analysis) {
|
|
198
|
+
const fafContent = await (0, atomic_write_1.safeRead)(this.config.structuredFile, this.projectPath);
|
|
199
|
+
const claudeMdContent = await (0, faf_to_claude_1.fafToClaudeMd)(fafContent, this.projectPath);
|
|
200
|
+
if (this.config.atomicWrites) {
|
|
201
|
+
await (0, atomic_write_1.atomicWrite)(this.config.readableFile, claudeMdContent, this.projectPath);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
// Direct write (not recommended)
|
|
205
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
206
|
+
await fs.writeFile(this.config.readableFile, claudeMdContent, 'utf-8');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Sync CLAUDE.md → .faf
|
|
211
|
+
*/
|
|
212
|
+
async syncClaudeToFaf(analysis) {
|
|
213
|
+
const claudeContent = await (0, atomic_write_1.safeRead)(this.config.readableFile, this.projectPath);
|
|
214
|
+
// Load existing .faf data (or create minimal structure)
|
|
215
|
+
let existingFafData = {};
|
|
216
|
+
if (analysis.fafState.exists) {
|
|
217
|
+
const fafContent = await (0, atomic_write_1.safeRead)(this.config.structuredFile, this.projectPath);
|
|
218
|
+
existingFafData = YAML.parse(fafContent);
|
|
219
|
+
}
|
|
220
|
+
const updatedFafContent = await (0, claude_to_faf_1.claudeMdToFaf)(claudeContent, existingFafData, this.projectPath);
|
|
221
|
+
if (this.config.atomicWrites) {
|
|
222
|
+
await (0, atomic_write_1.atomicWrite)(this.config.structuredFile, updatedFafContent, this.projectPath);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
// Direct write (not recommended)
|
|
226
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
227
|
+
await fs.writeFile(this.config.structuredFile, updatedFafContent, 'utf-8');
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Verify integrity after sync
|
|
232
|
+
* Ensures mirror is perfect
|
|
233
|
+
*/
|
|
234
|
+
async verifyIntegrity() {
|
|
235
|
+
try {
|
|
236
|
+
// Check both files exist
|
|
237
|
+
const fafExists = await (0, atomic_write_1.fileExists)(this.config.structuredFile);
|
|
238
|
+
const claudeExists = await (0, atomic_write_1.fileExists)(this.config.readableFile);
|
|
239
|
+
if (!fafExists || !claudeExists) {
|
|
240
|
+
return { status: 'failed' };
|
|
241
|
+
}
|
|
242
|
+
// Parse .faf to get score
|
|
243
|
+
const fafContent = await (0, atomic_write_1.safeRead)(this.config.structuredFile, this.projectPath);
|
|
244
|
+
const fafData = YAML.parse(fafContent);
|
|
245
|
+
const score = fafData.ai_score !== undefined && fafData.human_score !== undefined ? {
|
|
246
|
+
ai: fafData.ai_score,
|
|
247
|
+
human: fafData.human_score,
|
|
248
|
+
total: fafData.faf_score ? parseInt(fafData.faf_score) : fafData.ai_score + fafData.human_score
|
|
249
|
+
} : undefined;
|
|
250
|
+
// Basic validation passed
|
|
251
|
+
event_emitter_1.mirrorEvents.emitMirrorEvent((0, mirror_events_1.createMirrorEvent)(mirror_events_1.MirrorEventType.INTEGRITY_PERFECT, {
|
|
252
|
+
message: 'Mirror integrity verified'
|
|
253
|
+
}, {
|
|
254
|
+
projectPath: this.projectPath,
|
|
255
|
+
integrity: 'perfect',
|
|
256
|
+
score
|
|
257
|
+
}));
|
|
258
|
+
return { status: 'perfect', score };
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
event_emitter_1.mirrorEvents.emitMirrorEvent((0, mirror_events_1.createMirrorEvent)(mirror_events_1.MirrorEventType.INTEGRITY_FAILED, {
|
|
262
|
+
error: error instanceof Error ? error.message : String(error)
|
|
263
|
+
}, {
|
|
264
|
+
projectPath: this.projectPath,
|
|
265
|
+
integrity: 'failed'
|
|
266
|
+
}));
|
|
267
|
+
return { status: 'failed' };
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
exports.MirrorEngine = MirrorEngine;
|
|
272
|
+
//# sourceMappingURL=mirror-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirror-engine.js","sourceRoot":"","sources":["../../../../src/engines/c-mirror/core/mirror-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🩵 FAF Mirror - Convenience Wrapper
|
|
3
|
+
* Simple FAF-specific interface for C-Mirror
|
|
4
|
+
*
|
|
5
|
+
* This wrapper:
|
|
6
|
+
* - Uses FAF defaults (.faf and CLAUDE.md)
|
|
7
|
+
* - Includes FAF-specific validators
|
|
8
|
+
* - Integrates with FAF DNA chain
|
|
9
|
+
* - Provides championship communication
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* const mirror = new FAFMirror();
|
|
13
|
+
* await mirror.sync();
|
|
14
|
+
*/
|
|
15
|
+
import { IMirrorConfig, IMirrorResult } from '../core/interfaces';
|
|
16
|
+
export declare class FAFMirror {
|
|
17
|
+
private engine;
|
|
18
|
+
private projectPath;
|
|
19
|
+
private displayStarted;
|
|
20
|
+
constructor(projectPath?: string, options?: Partial<IMirrorConfig>);
|
|
21
|
+
/**
|
|
22
|
+
* Sync .faf ↔ CLAUDE.md
|
|
23
|
+
* With championship terminal display
|
|
24
|
+
*/
|
|
25
|
+
sync(): Promise<IMirrorResult>;
|
|
26
|
+
/**
|
|
27
|
+
* Stop display (cleanup)
|
|
28
|
+
*/
|
|
29
|
+
stop(): void;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=faf-mirror.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"faf-mirror.d.ts","sourceRoot":"","sources":["../../../../src/engines/c-mirror/faf-extensions/faf-mirror.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGlE,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAkB;gBAE5B,WAAW,GAAE,MAAsB,EAAE,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM;IAqBrF;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC;IAapC;;OAEG;IACH,IAAI,IAAI,IAAI;CAMb"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 🩵 FAF Mirror - Convenience Wrapper
|
|
4
|
+
* Simple FAF-specific interface for C-Mirror
|
|
5
|
+
*
|
|
6
|
+
* This wrapper:
|
|
7
|
+
* - Uses FAF defaults (.faf and CLAUDE.md)
|
|
8
|
+
* - Includes FAF-specific validators
|
|
9
|
+
* - Integrates with FAF DNA chain
|
|
10
|
+
* - Provides championship communication
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* const mirror = new FAFMirror();
|
|
14
|
+
* await mirror.sync();
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
+
var ownKeys = function(o) {
|
|
34
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
+
var ar = [];
|
|
36
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
+
return ar;
|
|
38
|
+
};
|
|
39
|
+
return ownKeys(o);
|
|
40
|
+
};
|
|
41
|
+
return function (mod) {
|
|
42
|
+
if (mod && mod.__esModule) return mod;
|
|
43
|
+
var result = {};
|
|
44
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
+
__setModuleDefault(result, mod);
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
})();
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.FAFMirror = void 0;
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
const mirror_engine_1 = require("../core/mirror-engine");
|
|
53
|
+
const terminal_display_1 = require("../broadcast/terminal-display");
|
|
54
|
+
class FAFMirror {
|
|
55
|
+
engine;
|
|
56
|
+
projectPath;
|
|
57
|
+
displayStarted = false;
|
|
58
|
+
constructor(projectPath = process.cwd(), options = {}) {
|
|
59
|
+
this.projectPath = projectPath;
|
|
60
|
+
// FAF defaults
|
|
61
|
+
const config = {
|
|
62
|
+
structuredFile: path.join(projectPath, '.faf'),
|
|
63
|
+
readableFile: path.join(projectPath, 'CLAUDE.md'),
|
|
64
|
+
projectPath,
|
|
65
|
+
atomicWrites: true, // Always use safe writes
|
|
66
|
+
selfHealing: true, // Always auto-recover
|
|
67
|
+
dnaChain: {
|
|
68
|
+
enabled: true, // DNA logging
|
|
69
|
+
path: path.join(projectPath, '.faf-dna.json'),
|
|
70
|
+
logLevel: 'standard'
|
|
71
|
+
},
|
|
72
|
+
...options
|
|
73
|
+
};
|
|
74
|
+
this.engine = new mirror_engine_1.MirrorEngine(config);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Sync .faf ↔ CLAUDE.md
|
|
78
|
+
* With championship terminal display
|
|
79
|
+
*/
|
|
80
|
+
async sync() {
|
|
81
|
+
// Start terminal display (listens to events)
|
|
82
|
+
if (!this.displayStarted) {
|
|
83
|
+
(0, terminal_display_1.startTerminalDisplay)();
|
|
84
|
+
this.displayStarted = true;
|
|
85
|
+
}
|
|
86
|
+
// Run the sync
|
|
87
|
+
const result = await this.engine.sync();
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Stop display (cleanup)
|
|
92
|
+
*/
|
|
93
|
+
stop() {
|
|
94
|
+
if (this.displayStarted) {
|
|
95
|
+
(0, terminal_display_1.stopTerminalDisplay)();
|
|
96
|
+
this.displayStarted = false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.FAFMirror = FAFMirror;
|
|
101
|
+
//# sourceMappingURL=faf-mirror.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"faf-mirror.js","sourceRoot":"","sources":["../../../../src/engines/c-mirror/faf-extensions/faf-mirror.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,2CAA6B;AAC7B,yDAAqD;AAErD,oEAA0F;AAE1F,MAAa,SAAS;IACZ,MAAM,CAAe;IACrB,WAAW,CAAS;IACpB,cAAc,GAAY,KAAK,CAAC;IAExC,YAAY,cAAsB,OAAO,CAAC,GAAG,EAAE,EAAE,UAAkC,EAAE;QACnF,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAE/B,eAAe;QACf,MAAM,MAAM,GAAkB;YAC5B,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC;YAC9C,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC;YACjD,WAAW;YACX,YAAY,EAAE,IAAI,EAAS,yBAAyB;YACpD,WAAW,EAAE,IAAI,EAAW,sBAAsB;YAClD,QAAQ,EAAE;gBACR,OAAO,EAAE,IAAI,EAAa,cAAc;gBACxC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC;gBAC7C,QAAQ,EAAE,UAAU;aACrB;YACD,GAAG,OAAO;SACX,CAAC;QAEF,IAAI,CAAC,MAAM,GAAG,IAAI,4BAAY,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,6CAA6C;QAC7C,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,IAAA,uCAAoB,GAAE,CAAC;YACvB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QAED,eAAe;QACf,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAExC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAA,sCAAmB,GAAE,CAAC;YACtB,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC9B,CAAC;IACH,CAAC;CACF;AApDD,8BAoDC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ⚛️ Atomic File Writer
|
|
3
|
+
* All-or-nothing file operations - Zero slippage guarantee
|
|
4
|
+
*
|
|
5
|
+
* Strategy:
|
|
6
|
+
* 1. Write to .tmp file first
|
|
7
|
+
* 2. Validate the write succeeded
|
|
8
|
+
* 3. Atomic rename (OS-level guarantee)
|
|
9
|
+
* 4. If ANY step fails, original file is untouched
|
|
10
|
+
*
|
|
11
|
+
* User NEVER sees partial state
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Atomic file write
|
|
15
|
+
* Guarantees all-or-nothing operation
|
|
16
|
+
*
|
|
17
|
+
* @param filePath - Target file path
|
|
18
|
+
* @param content - Content to write
|
|
19
|
+
* @param projectPath - Project root (for events)
|
|
20
|
+
*/
|
|
21
|
+
export declare function atomicWrite(filePath: string, content: string, projectPath?: string): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Safe file read with error handling
|
|
24
|
+
*/
|
|
25
|
+
export declare function safeRead(filePath: string, projectPath?: string): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Check if file exists
|
|
28
|
+
*/
|
|
29
|
+
export declare function fileExists(filePath: string): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Get file modification time
|
|
32
|
+
*/
|
|
33
|
+
export declare function getFileModifiedTime(filePath: string): Promise<Date | null>;
|
|
34
|
+
//# sourceMappingURL=atomic-write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-write.d.ts","sourceRoot":"","sources":["../../../../src/engines/c-mirror/strategies/atomic-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,IAAI,CAAC,CAqFf;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,MAAM,EAChB,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEnE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAOhF"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ⚛️ Atomic File Writer
|
|
4
|
+
* All-or-nothing file operations - Zero slippage guarantee
|
|
5
|
+
*
|
|
6
|
+
* Strategy:
|
|
7
|
+
* 1. Write to .tmp file first
|
|
8
|
+
* 2. Validate the write succeeded
|
|
9
|
+
* 3. Atomic rename (OS-level guarantee)
|
|
10
|
+
* 4. If ANY step fails, original file is untouched
|
|
11
|
+
*
|
|
12
|
+
* User NEVER sees partial state
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.atomicWrite = atomicWrite;
|
|
16
|
+
exports.safeRead = safeRead;
|
|
17
|
+
exports.fileExists = fileExists;
|
|
18
|
+
exports.getFileModifiedTime = getFileModifiedTime;
|
|
19
|
+
const fs_1 = require("fs");
|
|
20
|
+
const event_emitter_1 = require("../core/events/event-emitter");
|
|
21
|
+
const mirror_events_1 = require("../core/events/mirror-events");
|
|
22
|
+
/**
|
|
23
|
+
* Atomic file write
|
|
24
|
+
* Guarantees all-or-nothing operation
|
|
25
|
+
*
|
|
26
|
+
* @param filePath - Target file path
|
|
27
|
+
* @param content - Content to write
|
|
28
|
+
* @param projectPath - Project root (for events)
|
|
29
|
+
*/
|
|
30
|
+
async function atomicWrite(filePath, content, projectPath = process.cwd()) {
|
|
31
|
+
const tmpPath = `${filePath}.tmp`;
|
|
32
|
+
const backupPath = `${filePath}.backup`;
|
|
33
|
+
try {
|
|
34
|
+
// EMIT: Starting write
|
|
35
|
+
event_emitter_1.mirrorEvents.emitMirrorEvent((0, mirror_events_1.createMirrorEvent)(mirror_events_1.MirrorEventType.FILE_WRITE, {
|
|
36
|
+
file: filePath,
|
|
37
|
+
step: 'start'
|
|
38
|
+
}, { projectPath }));
|
|
39
|
+
// Step 1: Create backup of existing file (if exists)
|
|
40
|
+
const fileExists = await fs_1.promises.access(filePath).then(() => true).catch(() => false);
|
|
41
|
+
if (fileExists) {
|
|
42
|
+
await fs_1.promises.copyFile(filePath, backupPath);
|
|
43
|
+
event_emitter_1.mirrorEvents.emitMirrorEvent((0, mirror_events_1.createMirrorEvent)(mirror_events_1.MirrorEventType.FILE_BACKUP, {
|
|
44
|
+
original: filePath,
|
|
45
|
+
backup: backupPath
|
|
46
|
+
}, { projectPath }));
|
|
47
|
+
}
|
|
48
|
+
// Step 2: Write to temporary file
|
|
49
|
+
await fs_1.promises.writeFile(tmpPath, content, 'utf-8');
|
|
50
|
+
// Step 3: Validate the temporary file
|
|
51
|
+
const writtenContent = await fs_1.promises.readFile(tmpPath, 'utf-8');
|
|
52
|
+
if (writtenContent !== content) {
|
|
53
|
+
throw new Error('File validation failed: written content does not match');
|
|
54
|
+
}
|
|
55
|
+
// Step 4: Atomic rename (OS-level guarantee)
|
|
56
|
+
await fs_1.promises.rename(tmpPath, filePath);
|
|
57
|
+
// Step 5: Clean up backup
|
|
58
|
+
if (fileExists) {
|
|
59
|
+
await fs_1.promises.unlink(backupPath).catch(() => {
|
|
60
|
+
// Ignore backup cleanup errors
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// EMIT: Success
|
|
64
|
+
event_emitter_1.mirrorEvents.emitMirrorEvent((0, mirror_events_1.createMirrorEvent)(mirror_events_1.MirrorEventType.FILE_WRITE, {
|
|
65
|
+
file: filePath,
|
|
66
|
+
step: 'complete',
|
|
67
|
+
success: true
|
|
68
|
+
}, { projectPath }));
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
// Cleanup temporary file if it exists
|
|
72
|
+
await fs_1.promises.unlink(tmpPath).catch(() => {
|
|
73
|
+
// Ignore cleanup errors
|
|
74
|
+
});
|
|
75
|
+
// Restore from backup if we have one
|
|
76
|
+
const backupExists = await fs_1.promises.access(backupPath).then(() => true).catch(() => false);
|
|
77
|
+
if (backupExists) {
|
|
78
|
+
await fs_1.promises.rename(backupPath, filePath).catch(() => {
|
|
79
|
+
// If restore fails, emit error but don't throw
|
|
80
|
+
event_emitter_1.mirrorEvents.emitMirrorEvent((0, mirror_events_1.createMirrorEvent)(mirror_events_1.MirrorEventType.ERROR, {
|
|
81
|
+
message: 'Failed to restore backup',
|
|
82
|
+
file: filePath
|
|
83
|
+
}, { projectPath }));
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// EMIT: Error
|
|
87
|
+
event_emitter_1.mirrorEvents.emitMirrorEvent((0, mirror_events_1.createMirrorEvent)(mirror_events_1.MirrorEventType.ERROR, {
|
|
88
|
+
message: error instanceof Error ? error.message : String(error),
|
|
89
|
+
file: filePath,
|
|
90
|
+
recoverable: backupExists
|
|
91
|
+
}, { projectPath }));
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Safe file read with error handling
|
|
97
|
+
*/
|
|
98
|
+
async function safeRead(filePath, projectPath = process.cwd()) {
|
|
99
|
+
try {
|
|
100
|
+
event_emitter_1.mirrorEvents.emitMirrorEvent((0, mirror_events_1.createMirrorEvent)(mirror_events_1.MirrorEventType.FILE_READ, {
|
|
101
|
+
file: filePath
|
|
102
|
+
}, { projectPath }));
|
|
103
|
+
const content = await fs_1.promises.readFile(filePath, 'utf-8');
|
|
104
|
+
return content;
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
event_emitter_1.mirrorEvents.emitMirrorEvent((0, mirror_events_1.createMirrorEvent)(mirror_events_1.MirrorEventType.ERROR, {
|
|
108
|
+
message: `Failed to read ${filePath}: ${error instanceof Error ? error.message : String(error)}`,
|
|
109
|
+
file: filePath
|
|
110
|
+
}, { projectPath }));
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Check if file exists
|
|
116
|
+
*/
|
|
117
|
+
async function fileExists(filePath) {
|
|
118
|
+
return fs_1.promises.access(filePath).then(() => true).catch(() => false);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get file modification time
|
|
122
|
+
*/
|
|
123
|
+
async function getFileModifiedTime(filePath) {
|
|
124
|
+
try {
|
|
125
|
+
const stats = await fs_1.promises.stat(filePath);
|
|
126
|
+
return stats.mtime;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=atomic-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-write.js","sourceRoot":"","sources":["../../../../src/engines/c-mirror/strategies/atomic-write.ts"],"names":[],"mappings":"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"}
|