faf-cli 3.4.6 → 3.4.7
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 +21 -11
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +52 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/conductor.d.ts +15 -0
- package/dist/commands/conductor.d.ts.map +1 -0
- package/dist/commands/conductor.js +339 -0
- package/dist/commands/conductor.js.map +1 -0
- package/dist/commands/gemini.d.ts +15 -0
- package/dist/commands/gemini.d.ts.map +1 -0
- package/dist/commands/gemini.js +357 -0
- package/dist/commands/gemini.js.map +1 -0
- package/dist/utils/conductor-parser.d.ts +86 -0
- package/dist/utils/conductor-parser.d.ts.map +1 -0
- package/dist/utils/conductor-parser.js +292 -0
- package/dist/utils/conductor-parser.js.map +1 -0
- package/dist/utils/gemini-parser.d.ts +58 -0
- package/dist/utils/gemini-parser.d.ts.map +1 -0
- package/dist/utils/gemini-parser.js +263 -0
- package/dist/utils/gemini-parser.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Conductor Format Parser
|
|
4
|
+
*
|
|
5
|
+
* Parses Google's Conductor extension format (conductor/ directory)
|
|
6
|
+
* for bidirectional interoperability with FAF.
|
|
7
|
+
*
|
|
8
|
+
* @see /specs/FAF-CONDUCTOR-INTEROP.md
|
|
9
|
+
*/
|
|
10
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
11
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.parseMarkdownSections = parseMarkdownSections;
|
|
15
|
+
exports.extractBulletPoints = extractBulletPoints;
|
|
16
|
+
exports.parseProductMd = parseProductMd;
|
|
17
|
+
exports.parseTechStackMd = parseTechStackMd;
|
|
18
|
+
exports.parseWorkflowMd = parseWorkflowMd;
|
|
19
|
+
exports.parseGuidelinesMd = parseGuidelinesMd;
|
|
20
|
+
exports.conductorImport = conductorImport;
|
|
21
|
+
exports.conductorExport = conductorExport;
|
|
22
|
+
exports.detectConductor = detectConductor;
|
|
23
|
+
const fs_1 = require("fs");
|
|
24
|
+
const path_1 = __importDefault(require("path"));
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Markdown Parsing
|
|
27
|
+
// ============================================================================
|
|
28
|
+
/**
|
|
29
|
+
* Parse markdown content and extract sections by heading
|
|
30
|
+
*/
|
|
31
|
+
function parseMarkdownSections(content) {
|
|
32
|
+
const sections = {};
|
|
33
|
+
const lines = content.split('\n');
|
|
34
|
+
let currentSection = '_intro';
|
|
35
|
+
let currentContent = [];
|
|
36
|
+
for (const line of lines) {
|
|
37
|
+
const headingMatch = line.match(/^##\s+(.+)$/);
|
|
38
|
+
if (headingMatch) {
|
|
39
|
+
if (currentContent.length > 0) {
|
|
40
|
+
sections[currentSection] = currentContent.join('\n').trim();
|
|
41
|
+
}
|
|
42
|
+
currentSection = headingMatch[1].toLowerCase().replace(/\s+/g, '_');
|
|
43
|
+
currentContent = [];
|
|
44
|
+
}
|
|
45
|
+
else if (line.match(/^#\s+(.+)$/)) {
|
|
46
|
+
const titleMatch = line.match(/^#\s+(.+)$/);
|
|
47
|
+
if (titleMatch) {
|
|
48
|
+
sections['_title'] = titleMatch[1];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
currentContent.push(line);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (currentContent.length > 0) {
|
|
56
|
+
sections[currentSection] = currentContent.join('\n').trim();
|
|
57
|
+
}
|
|
58
|
+
return sections;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Extract bullet points from markdown content
|
|
62
|
+
*/
|
|
63
|
+
function extractBulletPoints(content) {
|
|
64
|
+
const lines = content.split('\n');
|
|
65
|
+
const bullets = [];
|
|
66
|
+
for (const line of lines) {
|
|
67
|
+
const bulletMatch = line.match(/^[-*]\s+(.+)$/);
|
|
68
|
+
if (bulletMatch) {
|
|
69
|
+
bullets.push(bulletMatch[1].trim());
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return bullets;
|
|
73
|
+
}
|
|
74
|
+
// ============================================================================
|
|
75
|
+
// File Parsers
|
|
76
|
+
// ============================================================================
|
|
77
|
+
function parseProductMd(content) {
|
|
78
|
+
const sections = parseMarkdownSections(content);
|
|
79
|
+
return {
|
|
80
|
+
title: sections['_title'] || 'Unknown Project',
|
|
81
|
+
description: sections['overview'] || '',
|
|
82
|
+
goals: extractBulletPoints(sections['goals'] || ''),
|
|
83
|
+
users: extractBulletPoints(sections['target_users'] || ''),
|
|
84
|
+
features: extractBulletPoints(sections['key_features'] || ''),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function parseTechStackMd(content) {
|
|
88
|
+
const sections = parseMarkdownSections(content);
|
|
89
|
+
return {
|
|
90
|
+
languages: extractBulletPoints(sections['languages'] || ''),
|
|
91
|
+
frameworks: extractBulletPoints(sections['frameworks'] || ''),
|
|
92
|
+
databases: extractBulletPoints(sections['databases'] || ''),
|
|
93
|
+
infrastructure: extractBulletPoints(sections['infrastructure'] || ''),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function parseWorkflowMd(content) {
|
|
97
|
+
const sections = parseMarkdownSections(content);
|
|
98
|
+
return {
|
|
99
|
+
developmentProcess: extractBulletPoints(sections['development_process'] || ''),
|
|
100
|
+
commitStrategy: extractBulletPoints(sections['commit_strategy'] || ''),
|
|
101
|
+
reviewProcess: extractBulletPoints(sections['review_process'] || ''),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function parseGuidelinesMd(content) {
|
|
105
|
+
const sections = parseMarkdownSections(content);
|
|
106
|
+
return {
|
|
107
|
+
proseStyle: extractBulletPoints(sections['prose_style'] || ''),
|
|
108
|
+
brandingRules: extractBulletPoints(sections['branding_rules'] || ''),
|
|
109
|
+
visualIdentity: extractBulletPoints(sections['visual_identity'] || ''),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// ============================================================================
|
|
113
|
+
// Import: Conductor → FAF
|
|
114
|
+
// ============================================================================
|
|
115
|
+
async function conductorImport(conductorPath) {
|
|
116
|
+
const warnings = [];
|
|
117
|
+
const filesProcessed = [];
|
|
118
|
+
const faf = {
|
|
119
|
+
project: {
|
|
120
|
+
name: 'Unknown',
|
|
121
|
+
description: '',
|
|
122
|
+
type: 'conductor-import',
|
|
123
|
+
goals: [],
|
|
124
|
+
stack: {
|
|
125
|
+
languages: [],
|
|
126
|
+
frameworks: [],
|
|
127
|
+
databases: [],
|
|
128
|
+
infrastructure: [],
|
|
129
|
+
},
|
|
130
|
+
rules: [],
|
|
131
|
+
guidelines: [],
|
|
132
|
+
},
|
|
133
|
+
metadata: {
|
|
134
|
+
source: 'conductor',
|
|
135
|
+
imported: new Date().toISOString(),
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
// Parse product.md
|
|
139
|
+
const productPath = path_1.default.join(conductorPath, 'product.md');
|
|
140
|
+
try {
|
|
141
|
+
const content = await fs_1.promises.readFile(productPath, 'utf-8');
|
|
142
|
+
const product = parseProductMd(content);
|
|
143
|
+
faf.project.name = product.title;
|
|
144
|
+
faf.project.description = product.description;
|
|
145
|
+
faf.project.goals = product.goals;
|
|
146
|
+
filesProcessed.push('product.md');
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
warnings.push('product.md not found - using defaults');
|
|
150
|
+
}
|
|
151
|
+
// Parse tech-stack.md
|
|
152
|
+
const techStackPath = path_1.default.join(conductorPath, 'tech-stack.md');
|
|
153
|
+
try {
|
|
154
|
+
const content = await fs_1.promises.readFile(techStackPath, 'utf-8');
|
|
155
|
+
const techStack = parseTechStackMd(content);
|
|
156
|
+
faf.project.stack = techStack;
|
|
157
|
+
filesProcessed.push('tech-stack.md');
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
warnings.push('tech-stack.md not found - stack will be empty');
|
|
161
|
+
}
|
|
162
|
+
// Parse workflow.md
|
|
163
|
+
const workflowPath = path_1.default.join(conductorPath, 'workflow.md');
|
|
164
|
+
try {
|
|
165
|
+
const content = await fs_1.promises.readFile(workflowPath, 'utf-8');
|
|
166
|
+
const workflow = parseWorkflowMd(content);
|
|
167
|
+
faf.project.rules = [
|
|
168
|
+
...workflow.developmentProcess,
|
|
169
|
+
...workflow.commitStrategy,
|
|
170
|
+
...workflow.reviewProcess,
|
|
171
|
+
];
|
|
172
|
+
filesProcessed.push('workflow.md');
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
warnings.push('workflow.md not found - rules will be empty');
|
|
176
|
+
}
|
|
177
|
+
// Parse product-guidelines.md
|
|
178
|
+
const guidelinesPath = path_1.default.join(conductorPath, 'product-guidelines.md');
|
|
179
|
+
try {
|
|
180
|
+
const content = await fs_1.promises.readFile(guidelinesPath, 'utf-8');
|
|
181
|
+
const guidelines = parseGuidelinesMd(content);
|
|
182
|
+
faf.project.guidelines = [
|
|
183
|
+
...guidelines.proseStyle,
|
|
184
|
+
...guidelines.brandingRules,
|
|
185
|
+
...guidelines.visualIdentity,
|
|
186
|
+
];
|
|
187
|
+
filesProcessed.push('product-guidelines.md');
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
warnings.push('product-guidelines.md not found - guidelines will be empty');
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
success: filesProcessed.length > 0,
|
|
194
|
+
faf,
|
|
195
|
+
warnings,
|
|
196
|
+
filesProcessed,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
// ============================================================================
|
|
200
|
+
// Export: FAF → Conductor
|
|
201
|
+
// ============================================================================
|
|
202
|
+
async function conductorExport(faf, outputPath) {
|
|
203
|
+
const filesGenerated = [];
|
|
204
|
+
const warnings = [];
|
|
205
|
+
// Ensure output directory exists
|
|
206
|
+
try {
|
|
207
|
+
await fs_1.promises.mkdir(outputPath, { recursive: true });
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
return {
|
|
211
|
+
success: false,
|
|
212
|
+
filesGenerated: [],
|
|
213
|
+
warnings: [`Failed to create output directory: ${err}`],
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
// Generate product.md
|
|
217
|
+
const productContent = `# ${faf.project.name}
|
|
218
|
+
|
|
219
|
+
## Overview
|
|
220
|
+
${faf.project.description}
|
|
221
|
+
|
|
222
|
+
## Goals
|
|
223
|
+
${faf.project.goals.map(g => `- ${g}`).join('\n')}
|
|
224
|
+
`;
|
|
225
|
+
await fs_1.promises.writeFile(path_1.default.join(outputPath, 'product.md'), productContent);
|
|
226
|
+
filesGenerated.push('product.md');
|
|
227
|
+
// Generate tech-stack.md
|
|
228
|
+
const techStackContent = `# Tech Stack
|
|
229
|
+
|
|
230
|
+
## Languages
|
|
231
|
+
${faf.project.stack.languages.map(l => `- ${l}`).join('\n')}
|
|
232
|
+
|
|
233
|
+
## Frameworks
|
|
234
|
+
${faf.project.stack.frameworks.map(f => `- ${f}`).join('\n')}
|
|
235
|
+
|
|
236
|
+
## Databases
|
|
237
|
+
${faf.project.stack.databases.map(d => `- ${d}`).join('\n')}
|
|
238
|
+
|
|
239
|
+
## Infrastructure
|
|
240
|
+
${faf.project.stack.infrastructure.map(i => `- ${i}`).join('\n')}
|
|
241
|
+
`;
|
|
242
|
+
await fs_1.promises.writeFile(path_1.default.join(outputPath, 'tech-stack.md'), techStackContent);
|
|
243
|
+
filesGenerated.push('tech-stack.md');
|
|
244
|
+
// Generate workflow.md
|
|
245
|
+
const workflowContent = `# Workflow
|
|
246
|
+
|
|
247
|
+
## Rules
|
|
248
|
+
${faf.project.rules.map(r => `- ${r}`).join('\n')}
|
|
249
|
+
`;
|
|
250
|
+
await fs_1.promises.writeFile(path_1.default.join(outputPath, 'workflow.md'), workflowContent);
|
|
251
|
+
filesGenerated.push('workflow.md');
|
|
252
|
+
// Generate product-guidelines.md
|
|
253
|
+
const guidelinesContent = `# Product Guidelines
|
|
254
|
+
|
|
255
|
+
## Guidelines
|
|
256
|
+
${faf.project.guidelines.map(g => `- ${g}`).join('\n')}
|
|
257
|
+
`;
|
|
258
|
+
await fs_1.promises.writeFile(path_1.default.join(outputPath, 'product-guidelines.md'), guidelinesContent);
|
|
259
|
+
filesGenerated.push('product-guidelines.md');
|
|
260
|
+
return {
|
|
261
|
+
success: true,
|
|
262
|
+
filesGenerated,
|
|
263
|
+
warnings,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// ============================================================================
|
|
267
|
+
// Detection
|
|
268
|
+
// ============================================================================
|
|
269
|
+
async function detectConductor(basePath) {
|
|
270
|
+
const conductorPath = path_1.default.join(basePath, 'conductor');
|
|
271
|
+
try {
|
|
272
|
+
const stat = await fs_1.promises.stat(conductorPath);
|
|
273
|
+
if (!stat.isDirectory())
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
// Check for at least one required file
|
|
280
|
+
const requiredFiles = ['product.md', 'tech-stack.md', 'workflow.md'];
|
|
281
|
+
for (const file of requiredFiles) {
|
|
282
|
+
try {
|
|
283
|
+
await fs_1.promises.access(path_1.default.join(conductorPath, file));
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=conductor-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conductor-parser.js","sourceRoot":"","sources":["../../src/utils/conductor-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GEMINI.md Parser
|
|
3
|
+
*
|
|
4
|
+
* Parses Google Gemini CLI GEMINI.md files for bidirectional
|
|
5
|
+
* interoperability with FAF.
|
|
6
|
+
*
|
|
7
|
+
* GEMINI.md Structure:
|
|
8
|
+
* - H1: Project name
|
|
9
|
+
* - H2: Section headers (General Instructions, Coding Style, etc.)
|
|
10
|
+
* - Bullets: Specific guidelines
|
|
11
|
+
*
|
|
12
|
+
* @see https://google-gemini.github.io/gemini-cli/docs/cli/gemini-md.html
|
|
13
|
+
*/
|
|
14
|
+
export interface GeminiMdSection {
|
|
15
|
+
title: string;
|
|
16
|
+
content: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface GeminiMdFile {
|
|
19
|
+
projectName: string;
|
|
20
|
+
sections: GeminiMdSection[];
|
|
21
|
+
}
|
|
22
|
+
export interface FafFromGemini {
|
|
23
|
+
project: {
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
type: string;
|
|
27
|
+
rules: string[];
|
|
28
|
+
guidelines: string[];
|
|
29
|
+
codingStyle: string[];
|
|
30
|
+
};
|
|
31
|
+
metadata: {
|
|
32
|
+
source: string;
|
|
33
|
+
imported: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface GeminiImportResult {
|
|
37
|
+
success: boolean;
|
|
38
|
+
faf: FafFromGemini;
|
|
39
|
+
warnings: string[];
|
|
40
|
+
sectionsFound: string[];
|
|
41
|
+
}
|
|
42
|
+
export interface GeminiExportResult {
|
|
43
|
+
success: boolean;
|
|
44
|
+
filePath: string;
|
|
45
|
+
warnings: string[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Parse GEMINI.md file content
|
|
49
|
+
*/
|
|
50
|
+
export declare function parseGeminiMd(content: string): GeminiMdFile;
|
|
51
|
+
export declare function geminiImport(geminiPath: string): Promise<GeminiImportResult>;
|
|
52
|
+
export declare function geminiExport(fafContent: any, outputPath: string): Promise<GeminiExportResult>;
|
|
53
|
+
export declare function detectGeminiMd(basePath: string): Promise<string | null>;
|
|
54
|
+
/**
|
|
55
|
+
* Check for global GEMINI.md
|
|
56
|
+
*/
|
|
57
|
+
export declare function detectGlobalGeminiMd(): Promise<string | null>;
|
|
58
|
+
//# sourceMappingURL=gemini-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-parser.d.ts","sourceRoot":"","sources":["../../src/utils/gemini-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,WAAW,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;IACF,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,aAAa,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAwC3D;AAkCD,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA8ClF;AAuBD,wBAAsB,YAAY,CAChC,UAAU,EAAE,GAAG,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,kBAAkB,CAAC,CAuF7B;AAMD,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgB7E;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUnE"}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GEMINI.md Parser
|
|
4
|
+
*
|
|
5
|
+
* Parses Google Gemini CLI GEMINI.md files for bidirectional
|
|
6
|
+
* interoperability with FAF.
|
|
7
|
+
*
|
|
8
|
+
* GEMINI.md Structure:
|
|
9
|
+
* - H1: Project name
|
|
10
|
+
* - H2: Section headers (General Instructions, Coding Style, etc.)
|
|
11
|
+
* - Bullets: Specific guidelines
|
|
12
|
+
*
|
|
13
|
+
* @see https://google-gemini.github.io/gemini-cli/docs/cli/gemini-md.html
|
|
14
|
+
*/
|
|
15
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.parseGeminiMd = parseGeminiMd;
|
|
20
|
+
exports.geminiImport = geminiImport;
|
|
21
|
+
exports.geminiExport = geminiExport;
|
|
22
|
+
exports.detectGeminiMd = detectGeminiMd;
|
|
23
|
+
exports.detectGlobalGeminiMd = detectGlobalGeminiMd;
|
|
24
|
+
const fs_1 = require("fs");
|
|
25
|
+
const path_1 = __importDefault(require("path"));
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// Parsing
|
|
28
|
+
// ============================================================================
|
|
29
|
+
/**
|
|
30
|
+
* Parse GEMINI.md file content
|
|
31
|
+
*/
|
|
32
|
+
function parseGeminiMd(content) {
|
|
33
|
+
const lines = content.split('\n');
|
|
34
|
+
let projectName = 'Unknown Project';
|
|
35
|
+
const sections = [];
|
|
36
|
+
let currentSection = null;
|
|
37
|
+
for (const line of lines) {
|
|
38
|
+
// H1 = Project name
|
|
39
|
+
const h1Match = line.match(/^#\s+(?:Project:\s*)?(.+)$/);
|
|
40
|
+
if (h1Match) {
|
|
41
|
+
projectName = h1Match[1].trim();
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
// H2 = Section header
|
|
45
|
+
const h2Match = line.match(/^##\s+(.+)$/);
|
|
46
|
+
if (h2Match) {
|
|
47
|
+
if (currentSection) {
|
|
48
|
+
sections.push(currentSection);
|
|
49
|
+
}
|
|
50
|
+
currentSection = {
|
|
51
|
+
title: h2Match[1].trim(),
|
|
52
|
+
content: [],
|
|
53
|
+
};
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
// Bullet point
|
|
57
|
+
const bulletMatch = line.match(/^[-*]\s+(.+)$/);
|
|
58
|
+
if (bulletMatch && currentSection) {
|
|
59
|
+
currentSection.content.push(bulletMatch[1].trim());
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Push last section
|
|
63
|
+
if (currentSection) {
|
|
64
|
+
sections.push(currentSection);
|
|
65
|
+
}
|
|
66
|
+
return { projectName, sections };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Convert GEMINI.md sections to FAF structure
|
|
70
|
+
*/
|
|
71
|
+
function categorizeSections(sections) {
|
|
72
|
+
const rules = [];
|
|
73
|
+
const guidelines = [];
|
|
74
|
+
const codingStyle = [];
|
|
75
|
+
for (const section of sections) {
|
|
76
|
+
const titleLower = section.title.toLowerCase();
|
|
77
|
+
if (titleLower.includes('coding') || titleLower.includes('style') || titleLower.includes('format')) {
|
|
78
|
+
codingStyle.push(...section.content);
|
|
79
|
+
}
|
|
80
|
+
else if (titleLower.includes('rule') || titleLower.includes('constraint') || titleLower.includes('requirement')) {
|
|
81
|
+
rules.push(...section.content);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
// Default to guidelines
|
|
85
|
+
guidelines.push(...section.content);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return { rules, guidelines, codingStyle };
|
|
89
|
+
}
|
|
90
|
+
// ============================================================================
|
|
91
|
+
// Import: GEMINI.md → FAF
|
|
92
|
+
// ============================================================================
|
|
93
|
+
async function geminiImport(geminiPath) {
|
|
94
|
+
const warnings = [];
|
|
95
|
+
// Check if file exists
|
|
96
|
+
try {
|
|
97
|
+
await fs_1.promises.access(geminiPath);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
faf: createEmptyFaf(),
|
|
103
|
+
warnings: [`GEMINI.md not found: ${geminiPath}`],
|
|
104
|
+
sectionsFound: [],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// Read and parse
|
|
108
|
+
const content = await fs_1.promises.readFile(geminiPath, 'utf-8');
|
|
109
|
+
const parsed = parseGeminiMd(content);
|
|
110
|
+
if (parsed.sections.length === 0) {
|
|
111
|
+
warnings.push('No sections found in GEMINI.md');
|
|
112
|
+
}
|
|
113
|
+
const { rules, guidelines, codingStyle } = categorizeSections(parsed.sections);
|
|
114
|
+
const faf = {
|
|
115
|
+
project: {
|
|
116
|
+
name: parsed.projectName,
|
|
117
|
+
description: `Imported from GEMINI.md`,
|
|
118
|
+
type: 'gemini-import',
|
|
119
|
+
rules,
|
|
120
|
+
guidelines,
|
|
121
|
+
codingStyle,
|
|
122
|
+
},
|
|
123
|
+
metadata: {
|
|
124
|
+
source: 'gemini',
|
|
125
|
+
imported: new Date().toISOString(),
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
return {
|
|
129
|
+
success: true,
|
|
130
|
+
faf,
|
|
131
|
+
warnings,
|
|
132
|
+
sectionsFound: parsed.sections.map(s => s.title),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function createEmptyFaf() {
|
|
136
|
+
return {
|
|
137
|
+
project: {
|
|
138
|
+
name: 'Unknown',
|
|
139
|
+
description: '',
|
|
140
|
+
type: 'gemini-import',
|
|
141
|
+
rules: [],
|
|
142
|
+
guidelines: [],
|
|
143
|
+
codingStyle: [],
|
|
144
|
+
},
|
|
145
|
+
metadata: {
|
|
146
|
+
source: 'gemini',
|
|
147
|
+
imported: new Date().toISOString(),
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
// ============================================================================
|
|
152
|
+
// Export: FAF → GEMINI.md
|
|
153
|
+
// ============================================================================
|
|
154
|
+
async function geminiExport(fafContent, outputPath) {
|
|
155
|
+
const warnings = [];
|
|
156
|
+
// Build GEMINI.md content
|
|
157
|
+
const lines = [];
|
|
158
|
+
// Project header
|
|
159
|
+
const projectName = fafContent.project?.name || fafContent.name || 'My Project';
|
|
160
|
+
lines.push(`# Project: ${projectName}`);
|
|
161
|
+
lines.push('');
|
|
162
|
+
// Description as intro paragraph if exists
|
|
163
|
+
const description = fafContent.project?.description || fafContent.description;
|
|
164
|
+
if (description) {
|
|
165
|
+
lines.push(description);
|
|
166
|
+
lines.push('');
|
|
167
|
+
}
|
|
168
|
+
// General Instructions section
|
|
169
|
+
const guidelines = fafContent.project?.guidelines || fafContent.guidelines || [];
|
|
170
|
+
const rules = fafContent.project?.rules || fafContent.rules || [];
|
|
171
|
+
const generalInstructions = [...guidelines, ...rules];
|
|
172
|
+
if (generalInstructions.length > 0) {
|
|
173
|
+
lines.push('## General Instructions');
|
|
174
|
+
lines.push('');
|
|
175
|
+
for (const item of generalInstructions) {
|
|
176
|
+
lines.push(`- ${item}`);
|
|
177
|
+
}
|
|
178
|
+
lines.push('');
|
|
179
|
+
}
|
|
180
|
+
// Coding Style section
|
|
181
|
+
const codingStyle = fafContent.project?.codingStyle || fafContent.codingStyle || [];
|
|
182
|
+
const stack = fafContent.project?.stack || {};
|
|
183
|
+
// Add languages/frameworks to coding style context
|
|
184
|
+
const styleItems = [...codingStyle];
|
|
185
|
+
if (stack.languages?.length > 0) {
|
|
186
|
+
styleItems.push(`Languages: ${stack.languages.join(', ')}`);
|
|
187
|
+
}
|
|
188
|
+
if (stack.frameworks?.length > 0) {
|
|
189
|
+
styleItems.push(`Frameworks: ${stack.frameworks.join(', ')}`);
|
|
190
|
+
}
|
|
191
|
+
if (styleItems.length > 0) {
|
|
192
|
+
lines.push('## Coding Style');
|
|
193
|
+
lines.push('');
|
|
194
|
+
for (const item of styleItems) {
|
|
195
|
+
lines.push(`- ${item}`);
|
|
196
|
+
}
|
|
197
|
+
lines.push('');
|
|
198
|
+
}
|
|
199
|
+
// Tech Stack section (if detailed)
|
|
200
|
+
if (stack.databases?.length > 0 || stack.infrastructure?.length > 0) {
|
|
201
|
+
lines.push('## Tech Stack');
|
|
202
|
+
lines.push('');
|
|
203
|
+
if (stack.databases?.length > 0) {
|
|
204
|
+
lines.push(`- Databases: ${stack.databases.join(', ')}`);
|
|
205
|
+
}
|
|
206
|
+
if (stack.infrastructure?.length > 0) {
|
|
207
|
+
lines.push(`- Infrastructure: ${stack.infrastructure.join(', ')}`);
|
|
208
|
+
}
|
|
209
|
+
lines.push('');
|
|
210
|
+
}
|
|
211
|
+
// Goals section
|
|
212
|
+
const goals = fafContent.project?.goals || [];
|
|
213
|
+
if (goals.length > 0) {
|
|
214
|
+
lines.push('## Project Goals');
|
|
215
|
+
lines.push('');
|
|
216
|
+
for (const goal of goals) {
|
|
217
|
+
lines.push(`- ${goal}`);
|
|
218
|
+
}
|
|
219
|
+
lines.push('');
|
|
220
|
+
}
|
|
221
|
+
// Write file
|
|
222
|
+
const content = lines.join('\n');
|
|
223
|
+
await fs_1.promises.writeFile(outputPath, content);
|
|
224
|
+
return {
|
|
225
|
+
success: true,
|
|
226
|
+
filePath: outputPath,
|
|
227
|
+
warnings,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
// ============================================================================
|
|
231
|
+
// Detection
|
|
232
|
+
// ============================================================================
|
|
233
|
+
async function detectGeminiMd(basePath) {
|
|
234
|
+
const possiblePaths = [
|
|
235
|
+
path_1.default.join(basePath, 'GEMINI.md'),
|
|
236
|
+
path_1.default.join(basePath, 'gemini.md'),
|
|
237
|
+
];
|
|
238
|
+
for (const p of possiblePaths) {
|
|
239
|
+
try {
|
|
240
|
+
await fs_1.promises.access(p);
|
|
241
|
+
return p;
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Check for global GEMINI.md
|
|
251
|
+
*/
|
|
252
|
+
async function detectGlobalGeminiMd() {
|
|
253
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
254
|
+
const globalPath = path_1.default.join(home, '.gemini', 'GEMINI.md');
|
|
255
|
+
try {
|
|
256
|
+
await fs_1.promises.access(globalPath);
|
|
257
|
+
return globalPath;
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=gemini-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-parser.js","sourceRoot":"","sources":["../../src/utils/gemini-parser.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "faf-cli",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.7",
|
|
4
4
|
"description": "Anthropic-Approved codebase that powers claude-faf-mcp • Persistent project context, on-demand • Format-driven CLI • Open Source Universal Standard • MIT License",
|
|
5
5
|
"icon": "https://faf.one/orange-smiley.svg",
|
|
6
6
|
"logo": "https://faf.one/orange-smiley.svg",
|