@iservu-inc/adf-cli 0.11.0 → 0.12.9
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/.adf/feature-audit.md +208 -0
- package/.adf/final-summary.md +347 -0
- package/.adf/implementation-plan.md +244 -0
- package/.adf/implementation-progress.md +203 -0
- package/.adf/learning/answer-history.json +995 -0
- package/.adf/learning/config.json +25 -0
- package/.adf/learning/learned-rules.json +59 -0
- package/.adf/learning/patterns.json +277 -0
- package/.adf/learning/skip-history.json +1451 -0
- package/.adf/learning/stats.json +9 -0
- package/.claude/settings.local.json +12 -5
- package/CHANGELOG.md +110 -0
- package/CLAUDE.md +479 -0
- package/bin/adf.js +339 -1
- package/lib/ai/ai-client.js +161 -44
- package/lib/ai/ai-config.js +249 -105
- package/lib/commands/deploy.js +73 -6
- package/lib/generators/agents-md-generator.js +431 -161
- package/lib/generators/antigravity-generator.js +140 -0
- package/lib/generators/deepagent-generator.js +144 -0
- package/lib/generators/gemini-cli-generator.js +241 -0
- package/lib/generators/index.js +55 -0
- package/lib/generators/opencode-generator.js +153 -0
- package/lib/generators/zed-generator.js +252 -0
- package/lib/templates/shared/agents/architect.md +24 -24
- package/lib/templates/shared/agents/dev.md +25 -20
- package/lib/templates/shared/agents/pm.md +14 -4
- package/lib/templates/shared/agents/sm.md +18 -14
- package/lib/templates/shared/templates/openspec-delta.md +16 -0
- package/lib/templates/shared/templates/openspec-proposal.md +18 -0
- package/lib/templates/shared/templates/openspec-tasks.md +21 -0
- package/lib/utils/context-manager.js +484 -0
- package/package.json +6 -1
- package/tests/agents-md-generator.test.js +47 -10
package/lib/ai/ai-config.js
CHANGED
|
@@ -43,19 +43,18 @@ const AI_PROVIDERS = {
|
|
|
43
43
|
website: 'https://ai.google.dev/',
|
|
44
44
|
setup: 'Get your API key from https://aistudio.google.com/app/apikey',
|
|
45
45
|
defaultModels: [
|
|
46
|
-
// Gemini 2.
|
|
47
|
-
'gemini-2.
|
|
48
|
-
'gemini-2.
|
|
49
|
-
|
|
50
|
-
'gemini-
|
|
51
|
-
// Gemini 2.0 Series (Stable)
|
|
52
|
-
'gemini-2.0-flash',
|
|
53
|
-
'gemini-2.0-flash-lite',
|
|
54
|
-
// Gemini 1.5 Series (Legacy - still supported)
|
|
46
|
+
// Gemini 2.0 Series (Latest - Experimental)
|
|
47
|
+
'gemini-2.0-flash-exp',
|
|
48
|
+
'gemini-2.0-flash-thinking-exp',
|
|
49
|
+
// Gemini 1.5 Series (Stable - Recommended)
|
|
50
|
+
'gemini-1.5-pro',
|
|
55
51
|
'gemini-1.5-pro-latest',
|
|
52
|
+
'gemini-1.5-flash',
|
|
56
53
|
'gemini-1.5-flash-latest',
|
|
57
|
-
'gemini-1.5-
|
|
58
|
-
|
|
54
|
+
'gemini-1.5-flash-8b',
|
|
55
|
+
// Gemini 1.0 Series (Legacy)
|
|
56
|
+
'gemini-pro',
|
|
57
|
+
'gemini-pro-vision'
|
|
59
58
|
]
|
|
60
59
|
},
|
|
61
60
|
OPENROUTER: {
|
|
@@ -192,6 +191,67 @@ function loadEnvIntoProcess(envPath) {
|
|
|
192
191
|
require('dotenv').config({ path: envPath });
|
|
193
192
|
}
|
|
194
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Validate API key with provider by making a simple API call
|
|
196
|
+
*/
|
|
197
|
+
async function validateAPIKeyWithProvider(provider, apiKey) {
|
|
198
|
+
switch (provider.id) {
|
|
199
|
+
case 'anthropic':
|
|
200
|
+
const Anthropic = require('@anthropic-ai/sdk');
|
|
201
|
+
const anthropicClient = new Anthropic({ apiKey });
|
|
202
|
+
// Make a minimal request to validate the key
|
|
203
|
+
await anthropicClient.messages.create({
|
|
204
|
+
model: 'claude-3-haiku-20240307',
|
|
205
|
+
max_tokens: 10,
|
|
206
|
+
messages: [{ role: 'user', content: 'test' }]
|
|
207
|
+
});
|
|
208
|
+
break;
|
|
209
|
+
|
|
210
|
+
case 'openai':
|
|
211
|
+
const OpenAI = require('openai');
|
|
212
|
+
const openaiClient = new OpenAI({ apiKey });
|
|
213
|
+
// List models is a simple GET request that validates the key
|
|
214
|
+
await openaiClient.models.list();
|
|
215
|
+
break;
|
|
216
|
+
|
|
217
|
+
case 'google':
|
|
218
|
+
const fetchGoogle = require('node-fetch');
|
|
219
|
+
// Validate by fetching models list (validates key and shows available models)
|
|
220
|
+
const googleResponse = await fetchGoogle(
|
|
221
|
+
`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
if (!googleResponse.ok) {
|
|
225
|
+
const errorText = await googleResponse.text();
|
|
226
|
+
throw new Error(`HTTP ${googleResponse.status}: ${errorText || googleResponse.statusText}`);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const googleData = await googleResponse.json();
|
|
230
|
+
if (!googleData.models || !Array.isArray(googleData.models) || googleData.models.length === 0) {
|
|
231
|
+
throw new Error('No models available for this API key');
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
|
|
235
|
+
case 'openrouter':
|
|
236
|
+
const fetchOR = require('node-fetch');
|
|
237
|
+
const response = await fetchOR('https://openrouter.ai/api/v1/models', {
|
|
238
|
+
headers: {
|
|
239
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
240
|
+
'Content-Type': 'application/json'
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
if (!response.ok) {
|
|
245
|
+
const errorText = await response.text();
|
|
246
|
+
throw new Error(`HTTP ${response.status}: ${errorText || response.statusText}`);
|
|
247
|
+
}
|
|
248
|
+
break;
|
|
249
|
+
|
|
250
|
+
default:
|
|
251
|
+
throw new Error(`Validation not implemented for provider: ${provider.id}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
195
255
|
/**
|
|
196
256
|
* Fetch available models from provider API
|
|
197
257
|
*/
|
|
@@ -202,9 +262,53 @@ async function fetchAvailableModels(provider, apiKey) {
|
|
|
202
262
|
try {
|
|
203
263
|
switch (provider.id) {
|
|
204
264
|
case 'anthropic':
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
265
|
+
try {
|
|
266
|
+
const Anthropic = require('@anthropic-ai/sdk');
|
|
267
|
+
const anthropic = new Anthropic({ apiKey });
|
|
268
|
+
|
|
269
|
+
// Try to fetch models from Anthropic API
|
|
270
|
+
// Note: As of SDK v0.65.0, models endpoint may not be available
|
|
271
|
+
// If it exists, it would be similar to OpenAI's API
|
|
272
|
+
try {
|
|
273
|
+
const response = await anthropic.models.list();
|
|
274
|
+
const models = response.data
|
|
275
|
+
.map(m => m.id)
|
|
276
|
+
.sort();
|
|
277
|
+
|
|
278
|
+
if (models.length > 0) {
|
|
279
|
+
spinner.succeed(`Found ${models.length} Anthropic models`);
|
|
280
|
+
return models;
|
|
281
|
+
}
|
|
282
|
+
} catch (listError) {
|
|
283
|
+
// Models endpoint not available, use comprehensive default list
|
|
284
|
+
spinner.warn('Model listing not available, using curated list');
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Comprehensive list of known Anthropic models
|
|
288
|
+
const knownModels = [
|
|
289
|
+
// Claude 4.5 (Latest)
|
|
290
|
+
'claude-sonnet-4-5-20250929',
|
|
291
|
+
'claude-opus-4-5-20251101',
|
|
292
|
+
// Claude 3.5
|
|
293
|
+
'claude-3-5-sonnet-20241022',
|
|
294
|
+
'claude-3-5-sonnet-20240620',
|
|
295
|
+
'claude-3-5-haiku-20241022',
|
|
296
|
+
// Claude 3
|
|
297
|
+
'claude-3-opus-20240229',
|
|
298
|
+
'claude-3-sonnet-20240229',
|
|
299
|
+
'claude-3-haiku-20240307',
|
|
300
|
+
// Claude 2 (Legacy)
|
|
301
|
+
'claude-2.1',
|
|
302
|
+
'claude-2.0',
|
|
303
|
+
'claude-instant-1.2'
|
|
304
|
+
];
|
|
305
|
+
|
|
306
|
+
return knownModels;
|
|
307
|
+
} catch (error) {
|
|
308
|
+
spinner.fail(`Failed to load Anthropic models: ${error.message}`);
|
|
309
|
+
console.log(chalk.yellow(' Using default model list\n'));
|
|
310
|
+
return provider.defaultModels;
|
|
311
|
+
}
|
|
208
312
|
|
|
209
313
|
case 'openai':
|
|
210
314
|
const OpenAI = require('openai');
|
|
@@ -224,33 +328,81 @@ async function fetchAvailableModels(provider, apiKey) {
|
|
|
224
328
|
|
|
225
329
|
case 'google':
|
|
226
330
|
try {
|
|
227
|
-
const
|
|
228
|
-
const genAI = new GoogleGenerativeAI(apiKey);
|
|
331
|
+
const fetch = require('node-fetch');
|
|
229
332
|
|
|
230
|
-
//
|
|
231
|
-
|
|
232
|
-
|
|
333
|
+
// Use Google's REST API to list available models
|
|
334
|
+
const response = await fetch(
|
|
335
|
+
`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
if (!response.ok) {
|
|
339
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
340
|
+
}
|
|
233
341
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
342
|
+
const data = await response.json();
|
|
343
|
+
|
|
344
|
+
if (data.models && Array.isArray(data.models)) {
|
|
345
|
+
// Filter for models that support generateContent
|
|
346
|
+
const availableModels = data.models
|
|
347
|
+
.filter(m =>
|
|
348
|
+
m.supportedGenerationMethods &&
|
|
349
|
+
m.supportedGenerationMethods.includes('generateContent')
|
|
350
|
+
)
|
|
351
|
+
.map(m => m.name.replace('models/', ''))
|
|
352
|
+
.sort();
|
|
353
|
+
|
|
354
|
+
if (availableModels.length > 0) {
|
|
355
|
+
spinner.succeed(`Found ${availableModels.length} Google Gemini models`);
|
|
356
|
+
return availableModels;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Fallback to default list
|
|
361
|
+
spinner.warn('No models found via API, using curated list');
|
|
237
362
|
return provider.defaultModels;
|
|
238
363
|
} catch (error) {
|
|
239
|
-
spinner.
|
|
364
|
+
spinner.fail(`Failed to fetch Google models: ${error.message}`);
|
|
365
|
+
console.log(chalk.yellow(' Using default model list\n'));
|
|
240
366
|
return provider.defaultModels;
|
|
241
367
|
}
|
|
242
368
|
|
|
243
369
|
case 'openrouter':
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
370
|
+
try {
|
|
371
|
+
const fetch = require('node-fetch');
|
|
372
|
+
const orResponse = await fetch('https://openrouter.ai/api/v1/models', {
|
|
373
|
+
headers: {
|
|
374
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
375
|
+
'Content-Type': 'application/json'
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
if (!orResponse.ok) {
|
|
380
|
+
throw new Error(`HTTP ${orResponse.status}: ${orResponse.statusText}`);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const orData = await orResponse.json();
|
|
384
|
+
|
|
385
|
+
if (!orData.data || !Array.isArray(orData.data)) {
|
|
386
|
+
throw new Error('Invalid response format from OpenRouter API');
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const orModels = orData.data
|
|
390
|
+
.map(m => m.id)
|
|
391
|
+
.filter(id => id) // Remove any null/undefined IDs
|
|
392
|
+
.sort();
|
|
393
|
+
|
|
394
|
+
if (orModels.length > 0) {
|
|
395
|
+
spinner.succeed(`Found ${orModels.length} OpenRouter models`);
|
|
396
|
+
return orModels;
|
|
397
|
+
} else {
|
|
398
|
+
spinner.warn('No models found, using defaults');
|
|
399
|
+
return provider.defaultModels;
|
|
248
400
|
}
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
401
|
+
} catch (error) {
|
|
402
|
+
spinner.fail(`Failed to fetch OpenRouter models: ${error.message}`);
|
|
403
|
+
console.log(chalk.yellow(' Using default model list\n'));
|
|
404
|
+
return provider.defaultModels;
|
|
405
|
+
}
|
|
254
406
|
|
|
255
407
|
default:
|
|
256
408
|
spinner.warn('Model fetching not supported, using defaults');
|
|
@@ -416,7 +568,36 @@ async function configureAIProvider(projectPath = process.cwd()) {
|
|
|
416
568
|
console.log(chalk.green(`\n✓ Using API key from ${keySource}`));
|
|
417
569
|
}
|
|
418
570
|
|
|
419
|
-
//
|
|
571
|
+
// Validate API key by testing basic connectivity
|
|
572
|
+
const ora = require('ora');
|
|
573
|
+
const validationSpinner = ora('Validating API key...').start();
|
|
574
|
+
|
|
575
|
+
try {
|
|
576
|
+
await validateAPIKeyWithProvider(selectedProvider, apiKey);
|
|
577
|
+
validationSpinner.succeed(chalk.green('API key validated successfully'));
|
|
578
|
+
} catch (error) {
|
|
579
|
+
validationSpinner.fail(chalk.red('API key validation failed'));
|
|
580
|
+
console.log(chalk.red(`\nError: ${error.message}\n`));
|
|
581
|
+
console.log(chalk.yellow('The API key appears to be invalid or has connectivity issues.'));
|
|
582
|
+
console.log(chalk.gray('Please check your API key and try again.\n'));
|
|
583
|
+
|
|
584
|
+
const { retry } = await inquirer.prompt([
|
|
585
|
+
{
|
|
586
|
+
type: 'confirm',
|
|
587
|
+
name: 'retry',
|
|
588
|
+
message: 'Try again with a different API key?',
|
|
589
|
+
default: true
|
|
590
|
+
}
|
|
591
|
+
]);
|
|
592
|
+
|
|
593
|
+
if (retry) {
|
|
594
|
+
return configureAIProvider(projectPath);
|
|
595
|
+
} else {
|
|
596
|
+
process.exit(1);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// Fetch available models (only after successful validation)
|
|
420
601
|
const availableModels = await fetchAvailableModels(selectedProvider, apiKey);
|
|
421
602
|
|
|
422
603
|
// Show helpful tip about model selection
|
|
@@ -454,81 +635,44 @@ async function configureAIProvider(projectPath = process.cwd()) {
|
|
|
454
635
|
envPath
|
|
455
636
|
};
|
|
456
637
|
|
|
457
|
-
//
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
type: 'confirm',
|
|
461
|
-
name: 'testConnection',
|
|
462
|
-
message: 'Test AI connection before starting?',
|
|
463
|
-
default: true
|
|
464
|
-
}
|
|
465
|
-
]);
|
|
466
|
-
|
|
467
|
-
if (testConnection) {
|
|
468
|
-
const ora = require('ora');
|
|
469
|
-
const spinner = ora('Testing AI connection...').start();
|
|
470
|
-
|
|
471
|
-
try {
|
|
472
|
-
const AIClient = require('./ai-client');
|
|
473
|
-
const client = new AIClient(config);
|
|
474
|
-
await client.test();
|
|
475
|
-
spinner.succeed(chalk.green('AI connection successful!'));
|
|
476
|
-
} catch (error) {
|
|
477
|
-
spinner.fail(chalk.red('AI connection failed'));
|
|
478
|
-
console.log(chalk.red(`\nError: ${error.message}\n`));
|
|
479
|
-
|
|
480
|
-
// Provide specific guidance for common errors
|
|
481
|
-
const errorMsg = error.message.toLowerCase();
|
|
482
|
-
|
|
483
|
-
if (errorMsg.includes('data policy') || errorMsg.includes('privacy')) {
|
|
484
|
-
console.log(chalk.yellow('📋 Privacy/Data Policy Issue:\n'));
|
|
485
|
-
if (selectedProvider.id === 'openrouter') {
|
|
486
|
-
console.log(chalk.gray(' OpenRouter: Free models require specific privacy settings.'));
|
|
487
|
-
console.log(chalk.cyan(' Solutions:'));
|
|
488
|
-
console.log(chalk.gray(' 1. Configure privacy: https://openrouter.ai/settings/privacy'));
|
|
489
|
-
console.log(chalk.gray(' 2. Select a paid model instead (recommended)'));
|
|
490
|
-
console.log(chalk.gray(' 3. Enable "Free model publication" in settings\n'));
|
|
491
|
-
} else {
|
|
492
|
-
console.log(chalk.gray(' The selected model may require specific account settings.'));
|
|
493
|
-
console.log(chalk.gray(' Try selecting a different model or check your provider settings.\n'));
|
|
494
|
-
}
|
|
495
|
-
} else if (errorMsg.includes('404') || errorMsg.includes('not found') || errorMsg.includes('no endpoints')) {
|
|
496
|
-
console.log(chalk.yellow('📋 Model Not Available:\n'));
|
|
497
|
-
console.log(chalk.gray(' The selected model may no longer be available or accessible.'));
|
|
498
|
-
console.log(chalk.cyan(' Solutions:'));
|
|
499
|
-
console.log(chalk.gray(' 1. Select a different, more widely supported model'));
|
|
500
|
-
console.log(chalk.gray(' 2. Check the provider\'s model availability'));
|
|
501
|
-
console.log(chalk.gray(' 3. Some models require specific API endpoints or settings\n'));
|
|
502
|
-
} else if (errorMsg.includes('400') || errorMsg.includes('unsupported parameter')) {
|
|
503
|
-
console.log(chalk.yellow('📋 Model Parameter Incompatibility:\n'));
|
|
504
|
-
console.log(chalk.gray(' The selected model may use different API parameters.'));
|
|
505
|
-
console.log(chalk.cyan(' Solutions:'));
|
|
506
|
-
console.log(chalk.gray(' 1. Try a more standard model (e.g., gpt-4-turbo, claude-3-5-sonnet)'));
|
|
507
|
-
console.log(chalk.gray(' 2. Some newer/experimental models may not be fully supported yet\n'));
|
|
508
|
-
} else if (errorMsg.includes('401') || errorMsg.includes('invalid') || errorMsg.includes('unauthorized')) {
|
|
509
|
-
console.log(chalk.yellow('📋 Invalid API Key:\n'));
|
|
510
|
-
console.log(chalk.gray(' Please check that your API key is correct and active.\n'));
|
|
511
|
-
} else if (errorMsg.includes('429') || errorMsg.includes('rate limit')) {
|
|
512
|
-
console.log(chalk.yellow('📋 Rate Limit:\n'));
|
|
513
|
-
console.log(chalk.gray(' You\'ve hit the API rate limit. Please wait a moment and try again.\n'));
|
|
514
|
-
} else {
|
|
515
|
-
console.log(chalk.yellow('💡 Tip: Try selecting a more widely supported model\n'));
|
|
516
|
-
}
|
|
638
|
+
// Verify the selected model is operational
|
|
639
|
+
console.log('');
|
|
640
|
+
const modelTestSpinner = ora(`Testing model ${model}...`).start();
|
|
517
641
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
]);
|
|
642
|
+
try {
|
|
643
|
+
const AIClient = require('./ai-client');
|
|
644
|
+
const testClient = new AIClient({
|
|
645
|
+
provider: selectedProvider.id,
|
|
646
|
+
model,
|
|
647
|
+
apiKey
|
|
648
|
+
});
|
|
526
649
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
650
|
+
await testClient.test();
|
|
651
|
+
modelTestSpinner.succeed(chalk.green(`Model ${model} verified successfully`));
|
|
652
|
+
} catch (error) {
|
|
653
|
+
modelTestSpinner.fail(chalk.red(`Model ${model} test failed`));
|
|
654
|
+
console.log(chalk.red(`\nError: ${error.message}\n`));
|
|
655
|
+
console.log(chalk.yellow('⚠️ This model appears to be listed but not operational.'));
|
|
656
|
+
console.log(chalk.gray('Possible reasons:'));
|
|
657
|
+
console.log(chalk.gray(' • Model requires higher API tier or special access'));
|
|
658
|
+
console.log(chalk.gray(' • Model is experimental or in preview'));
|
|
659
|
+
console.log(chalk.gray(' • Model has specific parameter requirements'));
|
|
660
|
+
console.log(chalk.gray(' • Provider-side issue or rate limiting\n'));
|
|
661
|
+
|
|
662
|
+
const { retry } = await inquirer.prompt([
|
|
663
|
+
{
|
|
664
|
+
type: 'confirm',
|
|
665
|
+
name: 'retry',
|
|
666
|
+
message: 'Try selecting a different model?',
|
|
667
|
+
default: true
|
|
531
668
|
}
|
|
669
|
+
]);
|
|
670
|
+
|
|
671
|
+
if (retry) {
|
|
672
|
+
// Recursively retry model selection (keep same provider)
|
|
673
|
+
return configureAIProvider(projectPath);
|
|
674
|
+
} else {
|
|
675
|
+
process.exit(1);
|
|
532
676
|
}
|
|
533
677
|
}
|
|
534
678
|
|
package/lib/commands/deploy.js
CHANGED
|
@@ -6,19 +6,32 @@ const {
|
|
|
6
6
|
generateAgentsMd,
|
|
7
7
|
generateWindsurf,
|
|
8
8
|
generateCursor,
|
|
9
|
-
generateVSCode
|
|
9
|
+
generateVSCode,
|
|
10
|
+
generateZed,
|
|
11
|
+
generateAntigravity,
|
|
12
|
+
generateOpenCode,
|
|
13
|
+
generateGeminiCLI,
|
|
14
|
+
generateDeepAgent
|
|
10
15
|
} = require('../generators');
|
|
16
|
+
const ContextManager = require('../utils/context-manager');
|
|
11
17
|
|
|
12
18
|
const TOOLS = {
|
|
19
|
+
// IDEs
|
|
13
20
|
windsurf: { name: 'Windsurf', configFile: '.windsurfrules' },
|
|
14
21
|
cursor: { name: 'Cursor', configFile: '.cursorrules' },
|
|
15
22
|
vscode: { name: 'VS Code', configFile: '.vscode/settings.json' },
|
|
16
23
|
'vscode-insider': { name: 'VS Code Insider', configFile: '.vscode-insider/settings.json' },
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
'
|
|
24
|
+
zed: { name: 'Zed Editor', configFile: '.zed/settings.json' },
|
|
25
|
+
antigravity: { name: 'Google Antigravity', configFile: '.antigravity/agents.yaml' },
|
|
26
|
+
|
|
27
|
+
// CLI Tools
|
|
28
|
+
'claude-code': { name: 'Claude Code', configFile: '.framework/agents/' },
|
|
29
|
+
'opencode': { name: 'OpenCode CLI', configFile: '.opencode.json' },
|
|
30
|
+
'gemini-cli': { name: 'Gemini CLI', configFile: 'GEMINI.md' },
|
|
31
|
+
'deepagent': { name: 'DeepAgent (Abacus.ai)', configFile: '.deepagent/agents/' },
|
|
32
|
+
|
|
33
|
+
// Generic
|
|
34
|
+
generic: { name: 'Generic AI Tools', configFile: '.framework/agents/' }
|
|
22
35
|
};
|
|
23
36
|
|
|
24
37
|
/**
|
|
@@ -108,6 +121,24 @@ async function deployToTool(tool, options = {}) {
|
|
|
108
121
|
const spinner = options.silent ? null : ora(`Deploying to ${TOOLS[tool]?.name || tool}...`).start();
|
|
109
122
|
|
|
110
123
|
try {
|
|
124
|
+
// Create .context/ directory structure (ANDF standard)
|
|
125
|
+
if (spinner) spinner.text = 'Creating .context/ structure...';
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
const contextManager = new ContextManager(cwd);
|
|
129
|
+
await contextManager.createStructure();
|
|
130
|
+
await contextManager.generateArchitecture(sessionPath, framework);
|
|
131
|
+
await contextManager.generateGlossary(sessionPath, framework);
|
|
132
|
+
|
|
133
|
+
if (!options.silent && !spinner) {
|
|
134
|
+
console.log(chalk.green('✓ Created .context/ structure'));
|
|
135
|
+
console.log(chalk.gray(' - .context/memory/architecture.md'));
|
|
136
|
+
console.log(chalk.gray(' - .context/memory/glossary.md'));
|
|
137
|
+
}
|
|
138
|
+
} catch (error) {
|
|
139
|
+
console.warn(chalk.yellow(`\n⚠️ Warning: Could not create .context/ structure: ${error.message}`));
|
|
140
|
+
}
|
|
141
|
+
|
|
111
142
|
// Generate AGENTS.md (universal standard)
|
|
112
143
|
if (!options.silent) {
|
|
113
144
|
if (spinner) spinner.text = 'Generating AGENTS.md...';
|
|
@@ -150,6 +181,42 @@ async function deployToTool(tool, options = {}) {
|
|
|
150
181
|
console.log(chalk.gray(` - .github/copilot-instructions.md`));
|
|
151
182
|
console.log(chalk.gray(` - .vscode/settings.json (custom chat modes)`));
|
|
152
183
|
}
|
|
184
|
+
} else if (tool === 'zed') {
|
|
185
|
+
generatedFiles = await generateZed(sessionPath, cwd, framework);
|
|
186
|
+
if (!options.silent && !spinner) {
|
|
187
|
+
console.log(chalk.green('✓ Generated Zed Editor configurations'));
|
|
188
|
+
console.log(chalk.gray(` - .zed/settings.json (MCP servers, agent config)`));
|
|
189
|
+
console.log(chalk.gray(` - .zed/keymap.json (agent shortcuts)`));
|
|
190
|
+
if (generatedFiles.rules) {
|
|
191
|
+
const linkType = generatedFiles.rules.type === 'symlink' ? 'symlink' : 'copy';
|
|
192
|
+
console.log(chalk.gray(` - .zed/rules (${linkType} -> AGENTS.md)`));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
} else if (tool === 'antigravity') {
|
|
196
|
+
generatedFiles = await generateAntigravity(sessionPath, cwd, framework);
|
|
197
|
+
if (!options.silent && !spinner) {
|
|
198
|
+
console.log(chalk.green('✓ Generated Antigravity configurations'));
|
|
199
|
+
console.log(chalk.gray(` - .antigravity/agents.yaml (AGENTS.md mount, .context access)`));
|
|
200
|
+
}
|
|
201
|
+
} else if (tool === 'opencode') {
|
|
202
|
+
generatedFiles = await generateOpenCode(sessionPath, cwd, framework);
|
|
203
|
+
if (!options.silent && !spinner) {
|
|
204
|
+
console.log(chalk.green('✓ Generated OpenCode CLI configurations'));
|
|
205
|
+
console.log(chalk.gray(` - .opencode.json (project config, agents, MCP servers)`));
|
|
206
|
+
}
|
|
207
|
+
} else if (tool === 'gemini-cli') {
|
|
208
|
+
generatedFiles = await generateGeminiCLI(sessionPath, cwd, framework);
|
|
209
|
+
if (!options.silent && !spinner) {
|
|
210
|
+
console.log(chalk.green('✓ Generated Gemini CLI configurations'));
|
|
211
|
+
console.log(chalk.gray(` - GEMINI.md (project context and instructions)`));
|
|
212
|
+
}
|
|
213
|
+
} else if (tool === 'deepagent') {
|
|
214
|
+
generatedFiles = await generateDeepAgent(sessionPath, cwd, framework);
|
|
215
|
+
if (!options.silent && !spinner) {
|
|
216
|
+
console.log(chalk.green('✓ Generated DeepAgent configurations'));
|
|
217
|
+
console.log(chalk.gray(` - .deepagent/agents/ (agent markdown files)`));
|
|
218
|
+
console.log(chalk.gray(` - .deepagent/README.md (project overview)`));
|
|
219
|
+
}
|
|
153
220
|
}
|
|
154
221
|
} catch (error) {
|
|
155
222
|
console.warn(chalk.yellow(`\n⚠️ Warning: Could not generate ${TOOLS[tool]?.name || tool} configurations: ${error.message}`));
|