prpm 0.1.4 → 0.1.6

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.
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ /**
3
+ * Buy Credits command - Purchase one-time playground credits
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleBuyCredits = handleBuyCredits;
7
+ exports.createBuyCreditsCommand = createBuyCreditsCommand;
8
+ const commander_1 = require("commander");
9
+ const user_config_1 = require("../core/user-config");
10
+ const telemetry_1 = require("../core/telemetry");
11
+ const child_process_1 = require("child_process");
12
+ const util_1 = require("util");
13
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
14
+ /**
15
+ * Make authenticated API call
16
+ */
17
+ async function apiCall(endpoint) {
18
+ const config = await (0, user_config_1.getConfig)();
19
+ const baseUrl = (config.registryUrl || 'https://registry.prpm.dev').replace(/\/$/, '');
20
+ if (!config.token) {
21
+ throw new Error('Authentication required. Please run `prpm login` first.');
22
+ }
23
+ const response = await fetch(`${baseUrl}${endpoint}`, {
24
+ headers: {
25
+ Authorization: `Bearer ${config.token}`,
26
+ },
27
+ });
28
+ if (!response.ok) {
29
+ const errorData = await response.json().catch(() => ({}));
30
+ throw new Error(errorData.message || `API request failed: ${response.statusText}`);
31
+ }
32
+ return response;
33
+ }
34
+ /**
35
+ * Get current credits balance
36
+ */
37
+ async function getBalance() {
38
+ const response = await apiCall('/api/v1/playground/credits');
39
+ return response.json();
40
+ }
41
+ /**
42
+ * Open URL in default browser
43
+ */
44
+ async function openBrowser(url) {
45
+ const platform = process.platform;
46
+ let command;
47
+ if (platform === 'darwin') {
48
+ command = `open "${url}"`;
49
+ }
50
+ else if (platform === 'win32') {
51
+ command = `start "" "${url}"`;
52
+ }
53
+ else {
54
+ // Linux and other Unix-like systems
55
+ command = `xdg-open "${url}"`;
56
+ }
57
+ try {
58
+ await execAsync(command);
59
+ }
60
+ catch (error) {
61
+ // If automatic opening fails, just show the URL
62
+ console.log(`\nšŸ”— Please open this URL in your browser:`);
63
+ console.log(` ${url}`);
64
+ }
65
+ }
66
+ /**
67
+ * Poll for credits balance increase
68
+ */
69
+ async function pollForPurchase(initialBalance, maxAttempts = 60, intervalMs = 2000) {
70
+ console.log('\nā³ Waiting for purchase confirmation...');
71
+ console.log(' (This may take a minute. Press Ctrl+C to cancel)');
72
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
73
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
74
+ try {
75
+ const status = await getBalance();
76
+ if (status.balance > initialBalance) {
77
+ return status.balance - initialBalance;
78
+ }
79
+ // Show progress indicator
80
+ if (attempt % 5 === 0 && attempt > 0) {
81
+ process.stdout.write('.');
82
+ }
83
+ }
84
+ catch (error) {
85
+ // Continue polling even if there's an error
86
+ continue;
87
+ }
88
+ }
89
+ return null;
90
+ }
91
+ /**
92
+ * Handle the buy-credits command
93
+ */
94
+ async function handleBuyCredits(options) {
95
+ const startTime = Date.now();
96
+ let success = false;
97
+ let error;
98
+ try {
99
+ const config = await (0, user_config_1.getConfig)();
100
+ if (!config.token) {
101
+ console.error('āŒ Authentication required');
102
+ console.log('\nšŸ’” Please login first:');
103
+ console.log(' prpm login');
104
+ process.exit(1);
105
+ }
106
+ // Get current balance
107
+ console.log('šŸ” Checking current credits balance...');
108
+ const initialStatus = await getBalance();
109
+ console.log(` Current balance: ${initialStatus.balance} credits`);
110
+ console.log('\nšŸ’° Available credit packages:');
111
+ console.log(' Small: 100 credits - $5.00 ($0.05 per credit)');
112
+ console.log(' Medium: 250 credits - $11.25 ($0.045 per credit) - 10% savings');
113
+ console.log(' Large: 600 credits - $24.00 ($0.04 per credit) - 20% savings');
114
+ console.log('\n✨ These credits never expire!');
115
+ console.log('šŸ’” Tip: Subscribe to PRPM+ for 100 monthly credits at just $6/month');
116
+ // Build URL with package parameter if specified
117
+ const baseUrl = (config.registryUrl || 'https://registry.prpm.dev').replace(/api\/?$/, '');
118
+ let purchaseUrl = `${baseUrl}/playground/credits/buy`;
119
+ if (options.package) {
120
+ const validPackages = ['small', 'medium', 'large'];
121
+ if (!validPackages.includes(options.package)) {
122
+ console.error(`\nāŒ Invalid package: ${options.package}`);
123
+ console.log(' Valid options: small, medium, large');
124
+ process.exit(1);
125
+ }
126
+ purchaseUrl += `?package=${options.package}`;
127
+ }
128
+ // Open purchase page
129
+ console.log(`\n🌐 Opening purchase page in your browser...`);
130
+ await openBrowser(purchaseUrl);
131
+ // Poll for purchase confirmation
132
+ const creditsAdded = await pollForPurchase(initialStatus.balance);
133
+ if (creditsAdded !== null) {
134
+ const updatedStatus = await getBalance();
135
+ console.log('\n\nšŸŽ‰ Successfully purchased credits!');
136
+ console.log('\nšŸ“Š Credits added:');
137
+ console.log(` + ${creditsAdded} credits`);
138
+ console.log(` šŸ’³ New balance: ${updatedStatus.balance} credits`);
139
+ console.log('\nāœ… You can now:');
140
+ console.log(' - Test packages: prpm playground <package> "<input>"');
141
+ console.log(' - Check balance: prpm credits');
142
+ console.log(' - View history: prpm credits --history');
143
+ success = true;
144
+ }
145
+ else {
146
+ console.log('\n\nā±ļø Purchase process timed out or was canceled.');
147
+ console.log('\nšŸ’” If you completed the purchase, run this to verify:');
148
+ console.log(' prpm credits');
149
+ console.log('\nšŸ’” Or check your transaction history:');
150
+ console.log(' prpm credits --history');
151
+ }
152
+ }
153
+ catch (err) {
154
+ error = err instanceof Error ? err.message : String(err);
155
+ console.error(`\nāŒ Purchase failed: ${error}`);
156
+ process.exit(1);
157
+ }
158
+ finally {
159
+ await telemetry_1.telemetry.track({
160
+ command: 'buy-credits',
161
+ success,
162
+ error,
163
+ duration: Date.now() - startTime,
164
+ data: {
165
+ package: options.package,
166
+ },
167
+ });
168
+ await telemetry_1.telemetry.shutdown();
169
+ }
170
+ }
171
+ /**
172
+ * Create the buy-credits command
173
+ */
174
+ function createBuyCreditsCommand() {
175
+ const command = new commander_1.Command('buy-credits');
176
+ command
177
+ .description('Purchase one-time playground credits (never expire)')
178
+ .option('-p, --package <package>', 'Credit package to purchase (small, medium, large)')
179
+ .addHelpText('after', `
180
+ Credit Packages:
181
+ Small: 100 credits - $5.00 ($0.05 per credit)
182
+ Medium: 250 credits - $11.25 ($0.045 per credit) - 10% savings
183
+ Large: 600 credits - $24.00 ($0.04 per credit) - 20% savings
184
+
185
+ Credits Usage:
186
+ - Testing packages in playground uses 1-5 credits per request
187
+ - Token-based pricing: 1 credit = 5,000 tokens
188
+ - Model multipliers apply (Opus 5x, GPT-4o 2x, etc.)
189
+ - Credits never expire
190
+
191
+ How it works:
192
+ 1. Opens purchase page in your browser
193
+ 2. Select package and complete payment with Stripe
194
+ 3. Credits are added to your account immediately
195
+ 4. Start testing packages right away
196
+
197
+ Examples:
198
+ # Browse all packages
199
+ $ prpm buy-credits
200
+
201
+ # Pre-select a specific package
202
+ $ prpm buy-credits --package small
203
+ $ prpm buy-credits --package medium
204
+ $ prpm buy-credits --package large
205
+
206
+ # After purchase, check balance
207
+ $ prpm credits
208
+
209
+ # Test packages in playground
210
+ $ prpm playground @user/prompt "test input"
211
+
212
+ šŸ’” Better Value:
213
+ Subscribe to PRPM+ for 100 monthly credits at just $6/month
214
+ Run: prpm subscribe
215
+
216
+ Note: Purchased credits are one-time and never expire, unlike monthly credits.
217
+ `)
218
+ .action(async (options) => {
219
+ await handleBuyCredits(options);
220
+ process.exit(0);
221
+ });
222
+ return command;
223
+ }
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ /**
3
+ * Credits command - Check and manage playground credits
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleCredits = handleCredits;
7
+ exports.createCreditsCommand = createCreditsCommand;
8
+ const commander_1 = require("commander");
9
+ const user_config_1 = require("../core/user-config");
10
+ const telemetry_1 = require("../core/telemetry");
11
+ /**
12
+ * Make authenticated API call
13
+ */
14
+ async function apiCall(endpoint) {
15
+ const config = await (0, user_config_1.getConfig)();
16
+ const baseUrl = (config.registryUrl || "https://registry.prpm.dev").replace(/\/$/, '');
17
+ if (!config.token) {
18
+ throw new Error('Authentication required. Please run `prpm login` first.');
19
+ }
20
+ const response = await fetch(`${baseUrl}${endpoint}`, {
21
+ headers: {
22
+ Authorization: `Bearer ${config.token}`,
23
+ },
24
+ });
25
+ if (!response.ok) {
26
+ const errorData = await response.json().catch(() => ({}));
27
+ throw new Error(errorData.message || `API request failed: ${response.statusText}`);
28
+ }
29
+ return response;
30
+ }
31
+ /**
32
+ * Display credits balance
33
+ */
34
+ async function showBalance() {
35
+ console.log('šŸ’³ Fetching playground credits balance...\n');
36
+ const response = await apiCall('/api/v1/playground/credits');
37
+ const balance = await response.json();
38
+ console.log('═'.repeat(5));
39
+ console.log(' PLAYGROUND CREDITS BALANCE');
40
+ console.log('═'.repeat(5));
41
+ // Total balance
42
+ console.log(`\nšŸ’° Total Balance: ${balance.balance} credits`);
43
+ // Breakdown
44
+ console.log('\nšŸ“Š Breakdown:');
45
+ if (balance.monthly_credits > 0) {
46
+ const monthlyRemaining = balance.monthly_credits - balance.monthly_credits_used;
47
+ console.log(` Monthly (PRPM+): ${monthlyRemaining}/${balance.monthly_credits} credits`);
48
+ if (balance.monthly_reset_at) {
49
+ const resetDate = new Date(balance.monthly_reset_at).toLocaleDateString();
50
+ console.log(` (Resets: ${resetDate})`);
51
+ }
52
+ }
53
+ if (balance.rollover_credits > 0) {
54
+ console.log(` Rollover: ${balance.rollover_credits} credits`);
55
+ if (balance.rollover_expires_at) {
56
+ const expiresDate = new Date(balance.rollover_expires_at).toLocaleDateString();
57
+ console.log(` (Expires: ${expiresDate})`);
58
+ }
59
+ }
60
+ if (balance.purchased_credits > 0) {
61
+ console.log(` Purchased: ${balance.purchased_credits} credits`);
62
+ console.log(` (Never expire)`);
63
+ }
64
+ // PRPM+ Status
65
+ if (balance.prpm_plus_status === 'active') {
66
+ console.log('\n✨ PRPM+ Active - You get 100 monthly credits!');
67
+ }
68
+ else {
69
+ console.log('\nšŸ’” Upgrade to PRPM+ for 100 monthly credits');
70
+ console.log(' Visit: https://prpm.dev/pricing');
71
+ }
72
+ console.log('\n═'.repeat(5));
73
+ }
74
+ /**
75
+ * Display recent credit transactions
76
+ */
77
+ async function showHistory(limit = 10) {
78
+ console.log(`šŸ’³ Fetching recent credit transactions...\n`);
79
+ const response = await apiCall(`/api/v1/playground/credits/history?limit=${limit}`);
80
+ const data = await response.json();
81
+ if (data.transactions.length === 0) {
82
+ console.log('No transaction history yet.');
83
+ return;
84
+ }
85
+ console.log('═'.repeat(5));
86
+ console.log(' CREDIT TRANSACTION HISTORY');
87
+ console.log('═'.repeat(5));
88
+ console.log();
89
+ for (const tx of data.transactions) {
90
+ const date = new Date(tx.created_at).toLocaleString();
91
+ const amount = tx.amount >= 0 ? `+${tx.amount}` : `${tx.amount}`;
92
+ const emoji = tx.amount >= 0 ? 'šŸ’°' : 'šŸ’ø';
93
+ console.log(`${emoji} ${date}`);
94
+ console.log(` Type: ${tx.transaction_type}`);
95
+ console.log(` Amount: ${amount} credits`);
96
+ console.log(` Balance: ${tx.balance_after} credits`);
97
+ console.log(` Details: ${tx.description}`);
98
+ console.log();
99
+ }
100
+ console.log('═'.repeat(5));
101
+ }
102
+ /**
103
+ * Handle the credits command
104
+ */
105
+ async function handleCredits(options) {
106
+ const startTime = Date.now();
107
+ let success = false;
108
+ let error;
109
+ try {
110
+ const config = await (0, user_config_1.getConfig)();
111
+ if (!config.token) {
112
+ console.error('āŒ Authentication required');
113
+ console.log('\nšŸ’” Please login first:');
114
+ console.log(' prpm login');
115
+ process.exit(1);
116
+ }
117
+ if (options.history) {
118
+ await showHistory(options.limit || 10);
119
+ }
120
+ else {
121
+ await showBalance();
122
+ }
123
+ console.log('\nšŸ’” Tips:');
124
+ console.log(' - Test packages: prpm playground <package> "<input>"');
125
+ console.log(' - View history: prpm credits --history');
126
+ console.log(' - Purchase credits: prpm buy-credits');
127
+ console.log(' - Subscribe to PRPM+: prpm subscribe');
128
+ success = true;
129
+ }
130
+ catch (err) {
131
+ error = err instanceof Error ? err.message : String(err);
132
+ console.error(`\nāŒ Failed to fetch credits: ${error}`);
133
+ process.exit(1);
134
+ }
135
+ finally {
136
+ await telemetry_1.telemetry.track({
137
+ command: 'credits',
138
+ success,
139
+ error,
140
+ duration: Date.now() - startTime,
141
+ data: {
142
+ showHistory: options.history || false,
143
+ },
144
+ });
145
+ await telemetry_1.telemetry.shutdown();
146
+ }
147
+ }
148
+ /**
149
+ * Create the credits command
150
+ */
151
+ function createCreditsCommand() {
152
+ const command = new commander_1.Command('credits');
153
+ command
154
+ .description('Check playground credits balance and transaction history')
155
+ .option('-h, --history', 'Show transaction history instead of balance', false)
156
+ .option('-l, --limit <number>', 'Number of transactions to show in history', '10')
157
+ .addHelpText('after', `
158
+ Examples:
159
+ # Check current balance
160
+ $ prpm credits
161
+
162
+ # View transaction history
163
+ $ prpm credits --history
164
+
165
+ # View last 20 transactions
166
+ $ prpm credits --history --limit 20
167
+
168
+ Credits are used for:
169
+ - Testing packages in the playground
170
+ - Running prompts with AI models
171
+ - Comparing packages against baselines
172
+
173
+ Get more credits:
174
+ - PRPM+ subscribers get 100 monthly credits
175
+ - Purchase additional credits at https://prpm.dev/playground/credits/buy
176
+ - Free tier gets 5 trial credits
177
+ `)
178
+ .action(async (options) => {
179
+ await handleCredits({
180
+ history: options.history,
181
+ limit: options.limit ? parseInt(options.limit, 10) : undefined,
182
+ });
183
+ process.exit(0);
184
+ });
185
+ return command;
186
+ }
@@ -0,0 +1,280 @@
1
+ "use strict";
2
+ /**
3
+ * Hooks command - Manage git hooks for running agents
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createHooksCommand = createHooksCommand;
10
+ const commander_1 = require("commander");
11
+ const fs_1 = require("fs");
12
+ const path_1 = require("path");
13
+ const child_process_1 = require("child_process");
14
+ const chalk_1 = __importDefault(require("chalk"));
15
+ /**
16
+ * Check if we're in a git repository
17
+ */
18
+ function isGitRepo() {
19
+ try {
20
+ (0, child_process_1.execSync)('git rev-parse --git-dir', { stdio: 'ignore' });
21
+ return true;
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
27
+ /**
28
+ * Get the git hooks directory
29
+ */
30
+ function getGitHooksDir() {
31
+ try {
32
+ const gitDir = (0, child_process_1.execSync)('git rev-parse --git-dir', { encoding: 'utf-8' }).trim();
33
+ return (0, path_1.join)(gitDir, 'hooks');
34
+ }
35
+ catch (error) {
36
+ throw new Error('Not in a git repository');
37
+ }
38
+ }
39
+ /**
40
+ * Create hooks configuration file template
41
+ */
42
+ function createHooksConfig() {
43
+ const configDir = '.prpm';
44
+ const configPath = (0, path_1.join)(configDir, 'hooks.json');
45
+ if ((0, fs_1.existsSync)(configPath)) {
46
+ console.log(chalk_1.default.yellow(`āš ļø Hooks configuration already exists at ${configPath}`));
47
+ return;
48
+ }
49
+ // Create .prpm directory if it doesn't exist
50
+ if (!(0, fs_1.existsSync)(configDir)) {
51
+ (0, fs_1.mkdirSync)(configDir, { recursive: true });
52
+ }
53
+ const template = {
54
+ hooks: {
55
+ 'pre-commit': {
56
+ enabled: true,
57
+ agents: [
58
+ {
59
+ name: '@pre-commit/security-scanner',
60
+ files: '**/*.{js,ts,py}',
61
+ severity: 'error',
62
+ autoFix: false,
63
+ },
64
+ ],
65
+ },
66
+ },
67
+ settings: {
68
+ enabled: true,
69
+ timeout: 30000,
70
+ cache: {
71
+ enabled: true,
72
+ ttl: 3600,
73
+ },
74
+ },
75
+ };
76
+ (0, fs_1.writeFileSync)(configPath, JSON.stringify(template, null, 2));
77
+ console.log(chalk_1.default.green(`āœ“ Created hooks configuration at ${configPath}`));
78
+ console.log(chalk_1.default.dim('\nEdit this file to configure which agents run on git hooks.'));
79
+ console.log(chalk_1.default.dim('Install agents with: prpm install @pre-commit/security-scanner\n'));
80
+ }
81
+ /**
82
+ * Install git hooks
83
+ */
84
+ async function handleInstall() {
85
+ if (!isGitRepo()) {
86
+ console.error(chalk_1.default.red('āœ— Not in a git repository'));
87
+ console.log(chalk_1.default.dim('Run this command from the root of your git repository.\n'));
88
+ process.exit(1);
89
+ }
90
+ const hooksDir = getGitHooksDir();
91
+ const configPath = (0, path_1.join)('.prpm', 'hooks.json');
92
+ // Create hooks config if it doesn't exist
93
+ if (!(0, fs_1.existsSync)(configPath)) {
94
+ createHooksConfig();
95
+ }
96
+ // Create hooks directory if it doesn't exist
97
+ if (!(0, fs_1.existsSync)(hooksDir)) {
98
+ (0, fs_1.mkdirSync)(hooksDir, { recursive: true });
99
+ }
100
+ // Create pre-commit hook
101
+ const preCommitHook = (0, path_1.join)(hooksDir, 'pre-commit');
102
+ const hookScript = `#!/bin/sh
103
+ # PRPM pre-commit hook
104
+ # Generated by prpm hooks install
105
+
106
+ # Run PRPM hooks command
107
+ prpm hooks run pre-commit
108
+
109
+ # Exit with the same code as the hooks command
110
+ exit $?
111
+ `;
112
+ (0, fs_1.writeFileSync)(preCommitHook, hookScript);
113
+ (0, fs_1.chmodSync)(preCommitHook, 0o755);
114
+ console.log(chalk_1.default.green('āœ“ Git hooks installed successfully'));
115
+ console.log(chalk_1.default.dim(`\nInstalled hooks:`));
116
+ console.log(chalk_1.default.dim(` - pre-commit → ${preCommitHook}`));
117
+ console.log(chalk_1.default.dim(`\nConfiguration: ${configPath}`));
118
+ console.log(chalk_1.default.dim('\nRun ') + chalk_1.default.cyan('prpm hooks uninstall') + chalk_1.default.dim(' to remove hooks.\n'));
119
+ }
120
+ /**
121
+ * Uninstall git hooks
122
+ */
123
+ async function handleUninstall() {
124
+ if (!isGitRepo()) {
125
+ console.error(chalk_1.default.red('āœ— Not in a git repository'));
126
+ process.exit(1);
127
+ }
128
+ const hooksDir = getGitHooksDir();
129
+ const preCommitHook = (0, path_1.join)(hooksDir, 'pre-commit');
130
+ if ((0, fs_1.existsSync)(preCommitHook)) {
131
+ // Check if it's a PRPM hook
132
+ const content = (0, fs_1.readFileSync)(preCommitHook, 'utf-8');
133
+ if (content.includes('PRPM pre-commit hook')) {
134
+ (0, fs_1.unlinkSync)(preCommitHook);
135
+ console.log(chalk_1.default.green('āœ“ PRPM git hooks uninstalled successfully'));
136
+ console.log(chalk_1.default.dim(`\nRemoved: ${preCommitHook}\n`));
137
+ }
138
+ else {
139
+ console.log(chalk_1.default.yellow('āš ļø Pre-commit hook exists but was not installed by PRPM'));
140
+ console.log(chalk_1.default.dim('Will not remove it. Please remove manually if needed.\n'));
141
+ }
142
+ }
143
+ else {
144
+ console.log(chalk_1.default.yellow('āš ļø No PRPM hooks found'));
145
+ console.log(chalk_1.default.dim('Hooks may have already been removed.\n'));
146
+ }
147
+ }
148
+ /**
149
+ * Run hooks for a specific event (pre-commit, pre-push, etc.)
150
+ */
151
+ async function handleRun(hookType) {
152
+ const configPath = (0, path_1.join)('.prpm', 'hooks.json');
153
+ if (!(0, fs_1.existsSync)(configPath)) {
154
+ console.error(chalk_1.default.red('āœ— Hooks configuration not found'));
155
+ console.log(chalk_1.default.dim(`Run ${chalk_1.default.cyan('prpm hooks install')} to set up hooks.\n`));
156
+ process.exit(1);
157
+ }
158
+ // Read configuration
159
+ const config = JSON.parse((0, fs_1.readFileSync)(configPath, 'utf-8'));
160
+ // Check if hooks are globally enabled
161
+ if (config.settings?.enabled === false) {
162
+ console.log(chalk_1.default.dim('ā„¹ļø Hooks are disabled in configuration'));
163
+ process.exit(0);
164
+ }
165
+ // Get hook configuration
166
+ const hookConfig = config.hooks?.[hookType];
167
+ if (!hookConfig || !hookConfig.enabled) {
168
+ console.log(chalk_1.default.dim(`ā„¹ļø ${hookType} hook is not enabled`));
169
+ process.exit(0);
170
+ }
171
+ // Check if any agents are configured
172
+ if (!hookConfig.agents || hookConfig.agents.length === 0) {
173
+ console.log(chalk_1.default.dim(`ā„¹ļø No agents configured for ${hookType}`));
174
+ process.exit(0);
175
+ }
176
+ console.log(chalk_1.default.blue(`\nšŸ” Running ${hookType} checks...\n`));
177
+ // TODO: Implement agent execution
178
+ // For now, just show what would be executed
179
+ let hasErrors = false;
180
+ for (const agent of hookConfig.agents) {
181
+ if (!agent.enabled) {
182
+ continue;
183
+ }
184
+ console.log(chalk_1.default.dim(` Checking with ${agent.name}...`));
185
+ // TODO: Execute agent here
186
+ // This is a placeholder - actual implementation will:
187
+ // 1. Get staged files (for pre-commit) using git diff --cached --name-only
188
+ // 2. Filter files by glob pattern (agent.files)
189
+ // 3. Load agent package
190
+ // 4. Execute agent via Anthropic SDK
191
+ // 5. Process results and show output
192
+ console.log(chalk_1.default.yellow(` āš ļø Not implemented yet - would check files matching: ${agent.files}`));
193
+ if (agent.severity === 'error') {
194
+ // hasErrors = true; // Uncomment when implemented
195
+ }
196
+ }
197
+ if (hasErrors) {
198
+ console.log(chalk_1.default.red('\nāœ— Checks failed. Please fix the issues above.\n'));
199
+ process.exit(1);
200
+ }
201
+ console.log(chalk_1.default.green('\nāœ“ All checks passed\n'));
202
+ process.exit(0);
203
+ }
204
+ /**
205
+ * Show status of installed hooks
206
+ */
207
+ async function handleStatus() {
208
+ if (!isGitRepo()) {
209
+ console.error(chalk_1.default.red('āœ— Not in a git repository'));
210
+ process.exit(1);
211
+ }
212
+ const hooksDir = getGitHooksDir();
213
+ const configPath = (0, path_1.join)('.prpm', 'hooks.json');
214
+ const preCommitHook = (0, path_1.join)(hooksDir, 'pre-commit');
215
+ console.log(chalk_1.default.blue('\nšŸ“‹ PRPM Hooks Status\n'));
216
+ // Check if hooks are installed
217
+ let hooksInstalled = false;
218
+ if ((0, fs_1.existsSync)(preCommitHook)) {
219
+ const content = (0, fs_1.readFileSync)(preCommitHook, 'utf-8');
220
+ if (content.includes('PRPM pre-commit hook')) {
221
+ hooksInstalled = true;
222
+ console.log(chalk_1.default.green('āœ“ Git hooks: Installed'));
223
+ }
224
+ else {
225
+ console.log(chalk_1.default.yellow('āš ļø Git hooks: Other hook exists'));
226
+ }
227
+ }
228
+ else {
229
+ console.log(chalk_1.default.red('āœ— Git hooks: Not installed'));
230
+ }
231
+ // Check if config exists
232
+ if ((0, fs_1.existsSync)(configPath)) {
233
+ console.log(chalk_1.default.green(`āœ“ Configuration: ${configPath}`));
234
+ const config = JSON.parse((0, fs_1.readFileSync)(configPath, 'utf-8'));
235
+ const enabled = config.settings?.enabled !== false;
236
+ console.log(chalk_1.default.dim(` Enabled: ${enabled ? 'yes' : 'no'}`));
237
+ // Show configured hooks
238
+ if (config.hooks) {
239
+ const hookTypes = Object.keys(config.hooks);
240
+ if (hookTypes.length > 0) {
241
+ console.log(chalk_1.default.dim(`\n Configured hooks:`));
242
+ for (const hookType of hookTypes) {
243
+ const hookConfig = config.hooks[hookType];
244
+ const agentCount = hookConfig.agents?.length || 0;
245
+ const hookEnabled = hookConfig.enabled !== false;
246
+ const status = hookEnabled ? chalk_1.default.green('enabled') : chalk_1.default.dim('disabled');
247
+ console.log(chalk_1.default.dim(` - ${hookType}: ${status}, ${agentCount} agent(s)`));
248
+ }
249
+ }
250
+ }
251
+ }
252
+ else {
253
+ console.log(chalk_1.default.yellow('āš ļø Configuration: Not found'));
254
+ }
255
+ console.log();
256
+ }
257
+ /**
258
+ * Create the hooks command
259
+ */
260
+ function createHooksCommand() {
261
+ const hooksCommand = new commander_1.Command('hooks')
262
+ .description('Manage git hooks for running agents on code changes');
263
+ hooksCommand
264
+ .command('install')
265
+ .description('Install PRPM git hooks')
266
+ .action(handleInstall);
267
+ hooksCommand
268
+ .command('uninstall')
269
+ .description('Uninstall PRPM git hooks')
270
+ .action(handleUninstall);
271
+ hooksCommand
272
+ .command('run <hook-type>')
273
+ .description('Run agents for a specific hook (used internally by git)')
274
+ .action(handleRun);
275
+ hooksCommand
276
+ .command('status')
277
+ .description('Show status of installed hooks and configuration')
278
+ .action(handleStatus);
279
+ return hooksCommand;
280
+ }