UNPKG

prompt-version-manager

Version:

Centralized prompt management system for Human Behavior AI agents

436 lines 16.2 kB
#!/usr/bin/env node "use strict"; /** * PVM CLI - Git-like version control for AI prompts (TypeScript) */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.main = main; const commander_1 = require("commander"); const fs = __importStar(require("fs/promises")); const path = __importStar(require("path")); const operations_1 = require("../versioning/operations"); const branches_1 = require("../versioning/branches"); // Core exceptions imported as needed class PVMCLI { versioning; branchManager; constructor(repoPath = '.pvm') { this.versioning = new operations_1.VersioningEngine(repoPath); this.branchManager = new branches_1.BranchManager(repoPath); } async init(_options = {}) { try { await this.versioning.init(); console.log(`Initialized empty PVM repository in ${path.resolve('.pvm')}`); console.log("\nCreated example files:"); console.log(" .pvm/prompts/template.md - Example prompt template"); console.log(" example.ts - TypeScript example using simplified API"); console.log("\nRun 'npx tsx example.ts' to see the simplified API in action!"); return 0; } catch (error) { console.error(`Error: ${error.message}`); return 1; } } async add(options) { try { let content; if (options.file) { content = await fs.readFile(options.file, 'utf-8'); content = content.trim(); } else if (options.content) { content = options.content; } else { console.error('Error: No content provided. Use --content or --file'); return 1; } if (!content) { console.error('Error: Content is empty'); return 1; } // Create message from content const messages = [ { role: 'user', content, metadata: {} } ]; // Parse model config const modelConfig = {}; if (options.temperature !== undefined) { modelConfig.temperature = options.temperature; } if (options.maxTokens !== undefined) { modelConfig.max_tokens = options.maxTokens; } if (options.model) { modelConfig.model = options.model; } // Parse metadata const metadata = {}; if (options.metadata) { for (const item of options.metadata) { if (item.includes('=')) { const [key, value] = item.split('=', 2); metadata[key] = value; } } } const tags = options.tag ? [options.tag] : []; const promptHash = await this.versioning.add(content, messages, modelConfig, metadata, tags); console.log(`Added prompt ${promptHash.substring(0, 8)}`); return 0; } catch (error) { if (error.code === 'ENOENT') { console.error(`Error: File '${options.file}' not found`); } else { console.error(`Error: ${error.message}`); } return 1; } } async commit(message, options = {}) { try { const commitHash = await this.versioning.commit(message, options.author || 'PVM User'); const currentBranch = await this.branchManager.getCurrentBranch(); const branchInfo = currentBranch || 'detached'; console.log(`[${branchInfo}] ${commitHash.substring(0, 8)} ${message}`); return 0; } catch (error) { console.error(`Error: ${error.message}`); return 1; } } async status(_options = {}) { try { const statusInfo = await this.versioning.status(); const currentBranch = statusInfo.currentBranch; if (currentBranch) { console.log(`On branch ${currentBranch}`); } else { console.log('HEAD detached'); } const stagedCount = statusInfo.stagedChanges; if (stagedCount > 0) { console.log('\nChanges to be committed:'); console.log(` ${stagedCount} prompt(s) staged`); } else { console.log('\nNothing to commit, working tree clean'); } return 0; } catch (error) { console.error(`Error: ${error.message}`); return 1; } } async log(options = {}) { try { const commits = await this.versioning.log(options.limit || 10); if (commits.length === 0) { console.log('No commits found'); return 0; } for (const commit of commits) { console.log(`commit ${commit.hash}`); console.log(`Author: ${commit.author}`); console.log(`Date: ${commit.timestamp.toDateString()}`); console.log(`\n ${commit.message}\n`); if (options.showPrompts && commit.promptVersions) { commit.promptVersions.forEach((promptHash, i) => { console.log(` Prompt ${i + 1}: ${promptHash.substring(0, 8)}`); console.log(); }); } } return 0; } catch (error) { console.error(`Error: ${error.message}`); return 1; } } async branch(branchName, options = {}) { try { if (options.delete) { // Delete branch await this.branchManager.deleteBranch(options.delete, options.force); console.log(`Deleted branch ${options.delete}`); } else if (branchName) { // Create branch const commitHash = await this.branchManager.createBranch(branchName, options.startPoint, options.force); console.log(`Created branch ${branchName} -> ${commitHash.substring(0, 8)}`); } else { // List branches const branches = await this.branchManager.listBranches(); const currentBranch = await this.branchManager.getCurrentBranch(); if (Object.keys(branches).length === 0) { console.log('No branches found'); return 0; } for (const [branchNameLocal, commitHash] of Object.entries(branches)) { const marker = branchNameLocal === currentBranch ? '* ' : ' '; if (options.verbose) { try { const info = await this.branchManager.getBranchInfo(branchNameLocal); console.log(`${marker}${branchNameLocal} ${commitHash.substring(0, 8)} ${info.commitMessage || ''}`); } catch { console.log(`${marker}${branchNameLocal} ${commitHash.substring(0, 8)}`); } } else { console.log(`${marker}${branchNameLocal}`); } } } return 0; } catch (error) { console.error(`Error: ${error.message}`); return 1; } } async checkout(target, options = {}) { try { const commitHash = await this.branchManager.checkout(target, options.createBranch, options.force); const currentBranch = await this.branchManager.getCurrentBranch(); if (currentBranch) { console.log(`Switched to branch '${currentBranch}'`); } else { console.log(`HEAD is now at ${commitHash.substring(0, 8)}`); } return 0; } catch (error) { console.error(`Error: ${error.message}`); return 1; } } async merge(branch, options = {}) { try { const result = await this.branchManager.merge(branch, options.message, options.noFf); if (result === null) { console.log(`Fast-forward merge of ${branch}`); } else { console.log(`Merge commit ${result.substring(0, 8)} created`); } return 0; } catch (error) { console.error(`Error: ${error.message}`); return 1; } } async diff(commit1, commit2) { try { if (!commit1 && !commit2) { console.error('Error: Please specify commits to compare'); return 1; } const diffResult = await this.versioning.diff(commit1, commit2); const hasChanges = diffResult.added.length > 0 || diffResult.removed.length > 0 || diffResult.modified.length > 0; if (!hasChanges) { console.log('No differences found'); return 0; } if (diffResult.added.length > 0) { console.log('\nADDED:'); diffResult.added.forEach(hash => { console.log(` ${hash.substring(0, 8)}`); }); } if (diffResult.removed.length > 0) { console.log('\nREMOVED:'); diffResult.removed.forEach(hash => { console.log(` ${hash.substring(0, 8)}`); }); } if (diffResult.modified.length > 0) { console.log('\nMODIFIED:'); diffResult.modified.forEach(hash => { console.log(` ${hash.substring(0, 8)}`); }); } return 0; } catch (error) { console.error(`Error: ${error.message}`); return 1; } } async close() { await this.versioning.close(); await this.branchManager.close(); } } async function main() { const program = new commander_1.Command(); program .name('pvm') .description('PVM - Git-like version control for AI prompts') .version('0.1.0'); const cli = new PVMCLI(); // pvm init program .command('init') .description('Initialize a new PVM repository') .option('--force', 'Reinitialize existing repository') .action(async (options) => { const exitCode = await cli.init(options); await cli.close(); process.exit(exitCode); }); // pvm add program .command('add') .description('Add a prompt to the staging area') .option('-c, --content <content>', 'Prompt content') .option('-f, --file <file>', 'Read prompt from file') .option('-t, --tag <tag>', 'Tag for the prompt') .option('--temperature <temperature>', 'Model temperature', parseFloat) .option('--max-tokens <maxTokens>', 'Maximum tokens', parseInt) .option('--model <model>', 'Model name') .option('-m, --metadata <metadata>', 'Metadata key=value pairs', (value, previous = []) => { return [...previous, value]; }) .action(async (options) => { const exitCode = await cli.add(options); await cli.close(); process.exit(exitCode); }); // pvm commit program .command('commit <message>') .description('Create a commit') .option('-a, --author <author>', 'Author name') .action(async (message, options) => { const exitCode = await cli.commit(message, options); await cli.close(); process.exit(exitCode); }); // pvm status program .command('status') .description('Show repository status') .option('-v, --verbose', 'Show detailed status') .action(async (options) => { const exitCode = await cli.status(options); await cli.close(); process.exit(exitCode); }); // pvm log program .command('log') .description('Show commit history') .option('-n, --limit <limit>', 'Limit number of commits', parseInt, 10) .option('-b, --branch <branch>', 'Branch to show history for') .option('-p, --show-prompts', 'Show prompt content') .action(async (options) => { const exitCode = await cli.log(options); await cli.close(); process.exit(exitCode); }); // pvm branch program .command('branch [branchName]') .description('Branch operations') .option('-d, --delete <branch>', 'Delete branch') .option('-f, --force', 'Force operation') .option('-s, --start-point <startPoint>', 'Starting point for new branch') .option('-v, --verbose', 'Show commit messages') .action(async (branchName, options) => { const exitCode = await cli.branch(branchName, options); await cli.close(); process.exit(exitCode); }); // pvm checkout program .command('checkout <target>') .description('Checkout branch or commit') .option('-b, --create-branch', 'Create new branch') .option('-f, --force', 'Force checkout') .action(async (target, options) => { const exitCode = await cli.checkout(target, options); await cli.close(); process.exit(exitCode); }); // pvm merge program .command('merge <branch>') .description('Merge a branch') .option('-m, --message <message>', 'Merge commit message') .option('--no-ff', 'Force merge commit') .action(async (branch, options) => { const exitCode = await cli.merge(branch, options); await cli.close(); process.exit(exitCode); }); // pvm diff program .command('diff [commit1] [commit2]') .description('Show differences') .action(async (commit1, commit2) => { const exitCode = await cli.diff(commit1, commit2); await cli.close(); process.exit(exitCode); }); try { await program.parseAsync(process.argv); await cli.close(); return 0; } catch (error) { console.error(`Error: ${error.message}`); await cli.close(); return 1; } } if (require.main === module) { main().then(code => process.exit(code)); } //# sourceMappingURL=main.js.map