claude-autopm 2.2.2 ā 2.3.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.
|
@@ -396,6 +396,21 @@ class ClaudeProvider extends AbstractAIProvider {
|
|
|
396
396
|
// BACKWARD COMPATIBILITY METHODS
|
|
397
397
|
// ============================================================
|
|
398
398
|
|
|
399
|
+
/**
|
|
400
|
+
* Generate text completion (alias for complete)
|
|
401
|
+
*
|
|
402
|
+
* Provides a more generic interface name for consistency with other services.
|
|
403
|
+
* This is an alias for complete() with identical functionality.
|
|
404
|
+
*
|
|
405
|
+
* @param {string} prompt - The prompt to complete
|
|
406
|
+
* @param {Object} [options={}] - Optional configuration
|
|
407
|
+
* @returns {Promise<string>} The completed text
|
|
408
|
+
* @throws {AIProviderError} On API errors
|
|
409
|
+
*/
|
|
410
|
+
async generate(prompt, options = {}) {
|
|
411
|
+
return await this.complete(prompt, options);
|
|
412
|
+
}
|
|
413
|
+
|
|
399
414
|
/**
|
|
400
415
|
* Get the current model being used (legacy method for backward compatibility)
|
|
401
416
|
*
|
package/lib/cli/commands/prd.js
CHANGED
|
@@ -13,11 +13,13 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
const PRDService = require('../../services/PRDService');
|
|
16
|
+
const ClaudeProvider = require('../../ai-providers/ClaudeProvider');
|
|
16
17
|
const fs = require('fs-extra');
|
|
17
18
|
const ora = require('ora');
|
|
18
19
|
const chalk = require('chalk');
|
|
19
20
|
const path = require('path');
|
|
20
21
|
const { spawn } = require('child_process');
|
|
22
|
+
const readline = require('readline');
|
|
21
23
|
|
|
22
24
|
/**
|
|
23
25
|
* Get PRD file path
|
|
@@ -304,6 +306,12 @@ async function prdStatus(argv) {
|
|
|
304
306
|
* @param {Object} argv - Command arguments
|
|
305
307
|
*/
|
|
306
308
|
async function prdNew(argv) {
|
|
309
|
+
// Check if AI mode is enabled
|
|
310
|
+
if (argv.ai) {
|
|
311
|
+
return await prdNewWithAI(argv);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Standard mode: spawn prd-new.js
|
|
307
315
|
const spinner = ora(`Creating PRD: ${argv.name}`).start();
|
|
308
316
|
|
|
309
317
|
try {
|
|
@@ -397,6 +405,171 @@ async function prdNew(argv) {
|
|
|
397
405
|
}
|
|
398
406
|
}
|
|
399
407
|
|
|
408
|
+
/**
|
|
409
|
+
* Create new PRD with AI assistance
|
|
410
|
+
* @param {Object} argv - Command arguments
|
|
411
|
+
*/
|
|
412
|
+
async function prdNewWithAI(argv) {
|
|
413
|
+
console.log(chalk.cyan(`\nš¤ AI-Powered PRD Creation: ${argv.name}`));
|
|
414
|
+
console.log(chalk.cyan('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n'));
|
|
415
|
+
|
|
416
|
+
const spinner = ora('Initializing...').start();
|
|
417
|
+
|
|
418
|
+
try {
|
|
419
|
+
// Check if PRD already exists
|
|
420
|
+
const prdPath = getPrdPath(argv.name);
|
|
421
|
+
const exists = await fs.pathExists(prdPath);
|
|
422
|
+
if (exists) {
|
|
423
|
+
spinner.fail(chalk.red('PRD already exists'));
|
|
424
|
+
console.error(chalk.red(`\nError: PRD file already exists: ${prdPath}`));
|
|
425
|
+
console.error(chalk.yellow('Use: autopm prd edit ' + argv.name + ' to modify it'));
|
|
426
|
+
process.exit(1);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Create PRDs directory if needed
|
|
430
|
+
const prdsDir = path.join(process.cwd(), '.claude', 'prds');
|
|
431
|
+
await fs.ensureDir(prdsDir);
|
|
432
|
+
|
|
433
|
+
spinner.stop();
|
|
434
|
+
|
|
435
|
+
// Gather information from user
|
|
436
|
+
const rl = readline.createInterface({
|
|
437
|
+
input: process.stdin,
|
|
438
|
+
output: process.stdout
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
const prompt = (question) => new Promise((resolve) => {
|
|
442
|
+
rl.question(question, resolve);
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
console.log(chalk.cyan('š§ Let\'s gather some information for AI...\n'));
|
|
446
|
+
|
|
447
|
+
const context = {};
|
|
448
|
+
|
|
449
|
+
// Product Vision
|
|
450
|
+
console.log(chalk.bold('š Product Vision'));
|
|
451
|
+
console.log(chalk.gray('What problem are you solving? What\'s the vision?'));
|
|
452
|
+
context.vision = await prompt(chalk.cyan('Vision: '));
|
|
453
|
+
|
|
454
|
+
// Target Users
|
|
455
|
+
console.log(chalk.bold('\nš„ Target Users'));
|
|
456
|
+
console.log(chalk.gray('Who will use this? What are their needs?'));
|
|
457
|
+
context.users = await prompt(chalk.cyan('Target users: '));
|
|
458
|
+
|
|
459
|
+
// Key Features (simplified - just high level)
|
|
460
|
+
console.log(chalk.bold('\n⨠Key Features'));
|
|
461
|
+
console.log(chalk.gray('What are the main capabilities? (brief description)'));
|
|
462
|
+
context.features = await prompt(chalk.cyan('Features: '));
|
|
463
|
+
|
|
464
|
+
// Success Metrics
|
|
465
|
+
console.log(chalk.bold('\nš Success Metrics'));
|
|
466
|
+
console.log(chalk.gray('How will you measure success?'));
|
|
467
|
+
context.metrics = await prompt(chalk.cyan('Metrics: '));
|
|
468
|
+
|
|
469
|
+
// Priority
|
|
470
|
+
console.log(chalk.bold('\nšÆ Priority'));
|
|
471
|
+
const priority = await prompt(chalk.cyan('Priority (P0/P1/P2/P3) [P2]: '));
|
|
472
|
+
context.priority = priority || 'P2';
|
|
473
|
+
|
|
474
|
+
// Timeline
|
|
475
|
+
console.log(chalk.bold('\nā° Timeline'));
|
|
476
|
+
const timeline = await prompt(chalk.cyan('Timeline [Q1 2025]: '));
|
|
477
|
+
context.timeline = timeline || 'Q1 2025';
|
|
478
|
+
|
|
479
|
+
rl.close();
|
|
480
|
+
|
|
481
|
+
// Build AI prompt
|
|
482
|
+
const aiPrompt = `Generate a comprehensive Product Requirements Document (PRD) based on the following information:
|
|
483
|
+
|
|
484
|
+
**PRD Name**: ${argv.name}
|
|
485
|
+
**Priority**: ${context.priority}
|
|
486
|
+
**Timeline**: ${context.timeline}
|
|
487
|
+
|
|
488
|
+
**Product Vision**:
|
|
489
|
+
${context.vision}
|
|
490
|
+
|
|
491
|
+
**Target Users**:
|
|
492
|
+
${context.users}
|
|
493
|
+
|
|
494
|
+
**Key Features**:
|
|
495
|
+
${context.features}
|
|
496
|
+
|
|
497
|
+
**Success Metrics**:
|
|
498
|
+
${context.metrics}
|
|
499
|
+
|
|
500
|
+
Please generate a complete, professional PRD with the following sections:
|
|
501
|
+
1. Executive Summary
|
|
502
|
+
2. Problem Statement (with Background, Current State, Desired State)
|
|
503
|
+
3. Target Users (with User Personas and User Stories)
|
|
504
|
+
4. Key Features (organized by priority: Must Have, Should Have, Nice to Have)
|
|
505
|
+
5. Success Metrics (with KPIs and Measurement Plan)
|
|
506
|
+
6. Technical Requirements (Architecture, Non-Functional Requirements, Dependencies)
|
|
507
|
+
7. Implementation Plan (broken into phases)
|
|
508
|
+
8. Risks and Mitigation
|
|
509
|
+
9. Open Questions
|
|
510
|
+
10. Appendix (References, Glossary, Changelog)
|
|
511
|
+
|
|
512
|
+
Format the output as a proper markdown document with frontmatter (status, priority, created, author, timeline).
|
|
513
|
+
|
|
514
|
+
Make it comprehensive, actionable, and professional. Expand on the provided information with industry best practices.`;
|
|
515
|
+
|
|
516
|
+
// Initialize AI provider and PRD service
|
|
517
|
+
const provider = new ClaudeProvider();
|
|
518
|
+
const prdService = new PRDService({ provider });
|
|
519
|
+
let prdContent = '';
|
|
520
|
+
|
|
521
|
+
if (argv.stream) {
|
|
522
|
+
// Streaming mode
|
|
523
|
+
const genSpinner = ora('Generating PRD with AI...').start();
|
|
524
|
+
genSpinner.stop();
|
|
525
|
+
|
|
526
|
+
console.log(chalk.cyan('\n\nš¤ AI is generating your PRD...\n'));
|
|
527
|
+
console.log(chalk.gray('ā'.repeat(80)) + '\n');
|
|
528
|
+
|
|
529
|
+
for await (const chunk of prdService.generatePRDStream(aiPrompt)) {
|
|
530
|
+
process.stdout.write(chunk);
|
|
531
|
+
prdContent += chunk;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
console.log('\n\n' + chalk.gray('ā'.repeat(80)));
|
|
535
|
+
} else {
|
|
536
|
+
// Non-streaming mode
|
|
537
|
+
const genSpinner = ora('Generating PRD with AI...').start();
|
|
538
|
+
prdContent = await prdService.generatePRD(aiPrompt);
|
|
539
|
+
genSpinner.succeed(chalk.green('PRD generated'));
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Save to file
|
|
543
|
+
const saveSpinner = ora('Saving PRD...').start();
|
|
544
|
+
await fs.writeFile(prdPath, prdContent);
|
|
545
|
+
saveSpinner.succeed(chalk.green('PRD saved'));
|
|
546
|
+
|
|
547
|
+
console.log(chalk.green('\nā
AI-powered PRD created successfully!'));
|
|
548
|
+
console.log(chalk.cyan(`š File: ${prdPath}\n`));
|
|
549
|
+
|
|
550
|
+
// Show next steps
|
|
551
|
+
console.log(chalk.bold('š What You Can Do Next:\n'));
|
|
552
|
+
console.log(` ${chalk.cyan('1.')} Review and edit: ${chalk.yellow('autopm prd edit ' + argv.name)}`);
|
|
553
|
+
console.log(` ${chalk.cyan('2.')} Check status: ${chalk.yellow('autopm prd status ' + argv.name)}`);
|
|
554
|
+
console.log(` ${chalk.cyan('3.')} Parse to epic: ${chalk.yellow('autopm prd parse ' + argv.name + ' --ai')}`);
|
|
555
|
+
console.log(` ${chalk.cyan('4.')} Extract epics: ${chalk.yellow('autopm prd extract-epics ' + argv.name)}\n`);
|
|
556
|
+
|
|
557
|
+
} catch (error) {
|
|
558
|
+
console.error(chalk.red(`\nā Error: ${error.message}`));
|
|
559
|
+
|
|
560
|
+
if (error.message.includes('ANTHROPIC_API_KEY') || error.message.includes('API key')) {
|
|
561
|
+
console.error(chalk.red('\nā Error: API key not configured'));
|
|
562
|
+
console.error(chalk.yellow('\nš” Set your API key in .env file:'));
|
|
563
|
+
console.error(chalk.cyan(' ANTHROPIC_API_KEY=sk-ant-api03-...'));
|
|
564
|
+
} else if (process.env.DEBUG) {
|
|
565
|
+
console.error(chalk.gray('\nStack trace:'));
|
|
566
|
+
console.error(chalk.gray(error.stack));
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
process.exit(1);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
400
573
|
/**
|
|
401
574
|
* Parse PRD with AI
|
|
402
575
|
* @param {Object} argv - Command arguments
|
|
@@ -642,8 +815,20 @@ function builder(yargs) {
|
|
|
642
815
|
type: 'string',
|
|
643
816
|
alias: 't'
|
|
644
817
|
})
|
|
818
|
+
.option('ai', {
|
|
819
|
+
describe: 'Use AI to generate PRD content (requires ANTHROPIC_API_KEY)',
|
|
820
|
+
type: 'boolean',
|
|
821
|
+
default: false
|
|
822
|
+
})
|
|
823
|
+
.option('stream', {
|
|
824
|
+
describe: 'Stream AI output in real-time (only with --ai)',
|
|
825
|
+
type: 'boolean',
|
|
826
|
+
default: false
|
|
827
|
+
})
|
|
645
828
|
.example('autopm prd new my-feature', 'Create PRD with wizard')
|
|
646
|
-
.example('autopm prd new payment-api --template api-feature', 'Create PRD from template')
|
|
829
|
+
.example('autopm prd new payment-api --template api-feature', 'Create PRD from template')
|
|
830
|
+
.example('autopm prd new my-feature --ai', 'AI-powered PRD generation')
|
|
831
|
+
.example('autopm prd new my-feature --ai --stream', 'AI generation with streaming');
|
|
647
832
|
},
|
|
648
833
|
prdNew // Handler
|
|
649
834
|
)
|
|
@@ -880,6 +880,55 @@ ${content}`;
|
|
|
880
880
|
// TIER 4: AI STREAMING METHODS
|
|
881
881
|
// ==========================================
|
|
882
882
|
|
|
883
|
+
/**
|
|
884
|
+
* Generate PRD from prompt (non-streaming)
|
|
885
|
+
*
|
|
886
|
+
* Uses AI to generate a complete PRD from a high-level description or prompt.
|
|
887
|
+
* Returns the generated PRD as markdown text.
|
|
888
|
+
*
|
|
889
|
+
* @param {string} prompt - Prompt describing what PRD to generate
|
|
890
|
+
* @param {Object} [options] - Generation options
|
|
891
|
+
* @returns {Promise<string>} Generated PRD markdown
|
|
892
|
+
* @throws {Error} If provider is not available
|
|
893
|
+
*
|
|
894
|
+
* @example
|
|
895
|
+
* const prd = await service.generatePRD('Create a PRD for user authentication');
|
|
896
|
+
* console.log(prd); // Full PRD markdown
|
|
897
|
+
*/
|
|
898
|
+
async generatePRD(prompt, options = {}) {
|
|
899
|
+
if (!this.provider || !this.provider.generate) {
|
|
900
|
+
throw new Error('PRD generation requires an AI provider with generate() support');
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
return await this.provider.generate(prompt, options);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Generate PRD from prompt with streaming output
|
|
908
|
+
*
|
|
909
|
+
* Uses AI to generate a complete PRD from a high-level description,
|
|
910
|
+
* streaming the output in real-time as it's generated.
|
|
911
|
+
*
|
|
912
|
+
* @param {string} prompt - Prompt describing what PRD to generate
|
|
913
|
+
* @param {Object} [options] - Streaming options
|
|
914
|
+
* @returns {AsyncGenerator<string>} Stream of PRD markdown chunks
|
|
915
|
+
* @throws {Error} If provider is not available or lacks stream() support
|
|
916
|
+
*
|
|
917
|
+
* @example
|
|
918
|
+
* for await (const chunk of service.generatePRDStream('Create a PRD for...')) {
|
|
919
|
+
* process.stdout.write(chunk); // Display PRD as it's generated
|
|
920
|
+
* }
|
|
921
|
+
*/
|
|
922
|
+
async *generatePRDStream(prompt, options = {}) {
|
|
923
|
+
if (!this.provider || !this.provider.stream) {
|
|
924
|
+
throw new Error('Streaming PRD generation requires an AI provider with stream() support');
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
for await (const chunk of this.provider.stream(prompt, options)) {
|
|
928
|
+
yield chunk;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
|
|
883
932
|
/**
|
|
884
933
|
* Parse PRD with streaming AI analysis
|
|
885
934
|
*
|