promptvc 0.1.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.
@@ -0,0 +1,299 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.main = main;
37
+ const child_process_1 = require("child_process");
38
+ const path = __importStar(require("path"));
39
+ const fs = __importStar(require("fs"));
40
+ const git_1 = require("./git");
41
+ const store_1 = require("./store");
42
+ /**
43
+ * Maximum length for prompt and response snippets
44
+ */
45
+ const MAX_PROMPT_LENGTH = 5000;
46
+ const MAX_RESPONSE_LENGTH = 5000;
47
+ /**
48
+ * Truncate a string to a maximum length
49
+ */
50
+ function truncate(str, maxLength) {
51
+ if (str.length <= maxLength) {
52
+ return str;
53
+ }
54
+ return str.substring(0, maxLength) + '... [truncated]';
55
+ }
56
+ /**
57
+ * Extract prompt from command line arguments
58
+ * Looks for the first non-flag argument
59
+ */
60
+ function extractPrompt(args) {
61
+ for (const arg of args) {
62
+ // Skip flags and their values
63
+ if (arg.startsWith('-')) {
64
+ continue;
65
+ }
66
+ // This is likely the prompt
67
+ if (arg.length > 0) {
68
+ return arg;
69
+ }
70
+ }
71
+ return null; // Will be filled in later from output or files
72
+ }
73
+ /**
74
+ * Generate a smart prompt description from files changed
75
+ */
76
+ function generatePromptFromFiles(files) {
77
+ if (files.length === 0) {
78
+ return 'interactive session';
79
+ }
80
+ const fileNames = files.map(f => {
81
+ const parts = f.split('/');
82
+ return parts[parts.length - 1];
83
+ }).join(', ');
84
+ return `Modified ${files.length} file${files.length > 1 ? 's' : ''}: ${fileNames}`;
85
+ }
86
+ /**
87
+ * Check if a prompt is a system prompt that should be filtered out
88
+ */
89
+ function isSystemPrompt(prompt) {
90
+ const systemPatterns = [
91
+ '# AGENTS.md',
92
+ '<INSTRUCTIONS>',
93
+ '<environment_context>',
94
+ '## Skills',
95
+ 'These skills are discovered at startup',
96
+ 'skill-creator:',
97
+ 'skill-installer:',
98
+ ];
99
+ // Check if prompt starts with or contains system patterns
100
+ for (const pattern of systemPatterns) {
101
+ if (prompt.startsWith(pattern) || prompt.includes(pattern)) {
102
+ return true;
103
+ }
104
+ }
105
+ return false;
106
+ }
107
+ /**
108
+ * Read prompts from the latest codex session file
109
+ */
110
+ function readCodexSessionPrompts() {
111
+ try {
112
+ const homeDir = process.env.HOME || process.env.USERPROFILE;
113
+ if (!homeDir)
114
+ return [];
115
+ const sessionsDir = path.join(homeDir, '.codex', 'sessions');
116
+ if (!fs.existsSync(sessionsDir))
117
+ return [];
118
+ // Find all rollout-*.jsonl files recursively
119
+ const findCommand = `find "${sessionsDir}" -name "rollout-*.jsonl" -type f -print0 | xargs -0 ls -t | head -1`;
120
+ const { execSync } = require('child_process');
121
+ const latestSessionFile = execSync(findCommand, { encoding: 'utf-8' }).trim();
122
+ if (!latestSessionFile || !fs.existsSync(latestSessionFile))
123
+ return [];
124
+ // Read and parse the session file
125
+ const sessionContent = fs.readFileSync(latestSessionFile, 'utf-8');
126
+ const lines = sessionContent.split('\n').filter(line => line.trim());
127
+ const prompts = [];
128
+ for (const line of lines) {
129
+ try {
130
+ const entry = JSON.parse(line);
131
+ // Extract user messages
132
+ if (entry.type === 'response_item' &&
133
+ entry.payload?.role === 'user' &&
134
+ entry.payload?.content?.[0]?.text) {
135
+ const promptText = entry.payload.content[0].text;
136
+ // Filter out system prompts
137
+ if (!isSystemPrompt(promptText)) {
138
+ prompts.push(promptText);
139
+ }
140
+ }
141
+ }
142
+ catch (e) {
143
+ // Skip invalid JSON lines
144
+ continue;
145
+ }
146
+ }
147
+ return prompts;
148
+ }
149
+ catch (error) {
150
+ console.error('[PromptVC] Warning: Failed to read codex session:', error);
151
+ return [];
152
+ }
153
+ }
154
+ /**
155
+ * Main function to proxy the Codex CLI
156
+ */
157
+ async function main() {
158
+ const args = process.argv.slice(2);
159
+ let repoRoot;
160
+ let branch;
161
+ let preHash;
162
+ // Get initial git state
163
+ try {
164
+ repoRoot = await (0, git_1.getRepoRoot)();
165
+ branch = await (0, git_1.getBranch)();
166
+ preHash = await (0, git_1.getHeadHash)();
167
+ }
168
+ catch (error) {
169
+ console.error('Error: Not in a git repository or git command failed');
170
+ console.error(error);
171
+ process.exit(1);
172
+ }
173
+ // Extract prompt from args
174
+ let promptFromArgs = extractPrompt(args);
175
+ // Spawn the real codex CLI with inherited stdio
176
+ // This allows codex to detect it's running in a terminal
177
+ // Note: We can't capture output without breaking TTY detection
178
+ const codexProcess = (0, child_process_1.spawn)('codex', args, {
179
+ stdio: 'inherit',
180
+ });
181
+ // Wait for the process to complete
182
+ codexProcess.on('close', async (code) => {
183
+ try {
184
+ // Get post-execution git state
185
+ const postHash = await (0, git_1.getHeadHash)();
186
+ // Check for uncommitted changes first
187
+ let changedFiles = await (0, git_1.getUncommittedFiles)();
188
+ let diff = '';
189
+ if (changedFiles.length > 0) {
190
+ // Uncommitted changes exist
191
+ diff = await (0, git_1.getUncommittedDiff)();
192
+ }
193
+ else {
194
+ // Check for committed changes
195
+ changedFiles = await (0, git_1.getChangedFiles)(preHash, 'HEAD');
196
+ if (changedFiles.length === 0) {
197
+ // No changes at all, don't log session
198
+ process.exit(code ?? 0);
199
+ return;
200
+ }
201
+ // Get the diff for committed changes
202
+ diff = await (0, git_1.getDiff)(preHash, 'HEAD');
203
+ }
204
+ // Try to read prompts from notify hook first (faster, real-time)
205
+ let capturedPrompts = [];
206
+ let perPromptChanges;
207
+ if (!promptFromArgs) {
208
+ const sessionFile = path.join(repoRoot, '.promptvc', 'current_session.json');
209
+ if (fs.existsSync(sessionFile)) {
210
+ try {
211
+ const sessionData = JSON.parse(fs.readFileSync(sessionFile, 'utf-8'));
212
+ if (Array.isArray(sessionData)) {
213
+ // Check if it's the new format (array of PromptChange objects)
214
+ if (sessionData.length > 0 && typeof sessionData[0] === 'object' && 'prompt' in sessionData[0]) {
215
+ // New format: array of PromptChange objects
216
+ perPromptChanges = sessionData;
217
+ capturedPrompts = perPromptChanges.map(pc => pc.prompt);
218
+ }
219
+ else {
220
+ // Old format: array of strings
221
+ capturedPrompts = sessionData;
222
+ }
223
+ }
224
+ // Clean up the session file
225
+ fs.unlinkSync(sessionFile);
226
+ // Also clean up the prompt count file
227
+ const lastPromptFile = path.join(repoRoot, '.promptvc', 'last_prompt_count');
228
+ if (fs.existsSync(lastPromptFile)) {
229
+ fs.unlinkSync(lastPromptFile);
230
+ }
231
+ }
232
+ catch (error) {
233
+ console.error('[PromptVC] Warning: Failed to read session file:', error);
234
+ }
235
+ }
236
+ // Fallback: read directly from codex session files if notify hook didn't run
237
+ if (capturedPrompts.length === 0) {
238
+ capturedPrompts = readCodexSessionPrompts();
239
+ }
240
+ }
241
+ // Determine the final prompt to use
242
+ let finalPrompt;
243
+ let responseSnippet;
244
+ if (promptFromArgs) {
245
+ // Use the command-line argument (one-shot mode)
246
+ finalPrompt = promptFromArgs;
247
+ responseSnippet = `Modified ${changedFiles.length} file(s)`;
248
+ }
249
+ else if (capturedPrompts.length > 0) {
250
+ // Use the latest prompt as the primary (interactive mode)
251
+ // Full history is in perPromptChanges
252
+ finalPrompt = capturedPrompts[capturedPrompts.length - 1];
253
+ responseSnippet = `Interactive session: ${capturedPrompts.length} prompt${capturedPrompts.length > 1 ? 's' : ''}`;
254
+ }
255
+ else {
256
+ // Fallback: generate from files
257
+ finalPrompt = generatePromptFromFiles(changedFiles);
258
+ responseSnippet = `Modified ${changedFiles.length} file(s)`;
259
+ }
260
+ // Determine mode
261
+ const mode = promptFromArgs ? 'oneshot' : 'interactive';
262
+ // Prepare session data
263
+ const sessionData = {
264
+ provider: 'codex',
265
+ repoRoot,
266
+ branch,
267
+ preHash,
268
+ postHash: preHash !== postHash ? postHash : null,
269
+ prompt: truncate(finalPrompt, MAX_PROMPT_LENGTH),
270
+ responseSnippet,
271
+ files: changedFiles,
272
+ diff,
273
+ createdAt: new Date().toISOString(),
274
+ mode,
275
+ autoTagged: true,
276
+ perPromptChanges, // Include per-prompt changes if available
277
+ };
278
+ // Initialize DB and insert session
279
+ (0, store_1.initDb)(repoRoot);
280
+ const sessionId = (0, store_1.insertSession)(sessionData);
281
+ // Log success (optional - you can make this configurable)
282
+ console.error(`\n[PromptVC] Session logged: ${sessionId}`);
283
+ process.exit(code ?? 0);
284
+ }
285
+ catch (error) {
286
+ // Don't fail the original command due to logging errors
287
+ console.error('[PromptVC] Warning: Failed to log session:', error);
288
+ process.exit(code ?? 0);
289
+ }
290
+ });
291
+ // Handle errors in spawning
292
+ codexProcess.on('error', (error) => {
293
+ console.error('Error: Failed to execute codex CLI');
294
+ console.error('Make sure "codex" is installed and available in your PATH');
295
+ console.error(error);
296
+ process.exit(1);
297
+ });
298
+ }
299
+ //# sourceMappingURL=proxyCodex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxyCodex.js","sourceRoot":"","sources":["../src/proxyCodex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { PromptSession } from '@promptvc/types';
2
+ /**
3
+ * Initialize the JSON storage for a given repository
4
+ * Creates the .promptvc directory and sessions.json if they don't exist
5
+ */
6
+ export declare function initDb(repoRoot: string): void;
7
+ /**
8
+ * Initialize PromptVC storage and default settings for a repository
9
+ */
10
+ export declare function initRepoStorage(repoRoot: string): {
11
+ promptvcDir: string;
12
+ sessionsFilePath: string;
13
+ settingsFilePath: string;
14
+ };
15
+ /**
16
+ * Insert a new prompt session into the JSON file
17
+ */
18
+ export declare function insertSession(session: Omit<PromptSession, 'id'>): string;
19
+ /**
20
+ * Get sessions from the JSON file
21
+ * @param limit - Maximum number of sessions to return (default: 50)
22
+ * @param offset - Number of sessions to skip (default: 0)
23
+ */
24
+ export declare function getSessions(limit?: number, offset?: number): PromptSession[];
25
+ /**
26
+ * Get a single session by ID
27
+ */
28
+ export declare function getSessionById(id: string): PromptSession | null;
29
+ /**
30
+ * Get sessions by provider
31
+ */
32
+ export declare function getSessionsByProvider(provider: string, limit?: number): PromptSession[];
33
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAMhD;;;GAGG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAc7C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAgBA;AA8BD;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,MAAM,CAaxE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,aAAa,EAAE,CAGnF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAG/D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,aAAa,EAAE,CAG3F"}
package/dist/store.js ADDED
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.initDb = initDb;
37
+ exports.initRepoStorage = initRepoStorage;
38
+ exports.insertSession = insertSession;
39
+ exports.getSessions = getSessions;
40
+ exports.getSessionById = getSessionById;
41
+ exports.getSessionsByProvider = getSessionsByProvider;
42
+ const fs = __importStar(require("fs"));
43
+ const path = __importStar(require("path"));
44
+ const uuid_1 = require("uuid");
45
+ let sessionsFilePath = null;
46
+ const DEFAULT_SETTINGS = { notifySoundEnabled: true };
47
+ /**
48
+ * Initialize the JSON storage for a given repository
49
+ * Creates the .promptvc directory and sessions.json if they don't exist
50
+ */
51
+ function initDb(repoRoot) {
52
+ const promptvcDir = path.join(repoRoot, '.promptvc');
53
+ // Create .promptvc directory if it doesn't exist
54
+ if (!fs.existsSync(promptvcDir)) {
55
+ fs.mkdirSync(promptvcDir, { recursive: true });
56
+ }
57
+ sessionsFilePath = path.join(promptvcDir, 'sessions.json');
58
+ // Create empty sessions file if it doesn't exist
59
+ if (!fs.existsSync(sessionsFilePath)) {
60
+ fs.writeFileSync(sessionsFilePath, JSON.stringify([], null, 2));
61
+ }
62
+ }
63
+ /**
64
+ * Initialize PromptVC storage and default settings for a repository
65
+ */
66
+ function initRepoStorage(repoRoot) {
67
+ initDb(repoRoot);
68
+ const promptvcDir = path.join(repoRoot, '.promptvc');
69
+ const settingsFilePath = path.join(promptvcDir, 'settings.json');
70
+ const sessionsPath = path.join(promptvcDir, 'sessions.json');
71
+ if (!fs.existsSync(settingsFilePath)) {
72
+ fs.writeFileSync(settingsFilePath, JSON.stringify(DEFAULT_SETTINGS, null, 2));
73
+ }
74
+ return {
75
+ promptvcDir,
76
+ sessionsFilePath: sessionsPath,
77
+ settingsFilePath,
78
+ };
79
+ }
80
+ /**
81
+ * Read all sessions from the JSON file
82
+ */
83
+ function readSessions() {
84
+ if (!sessionsFilePath) {
85
+ throw new Error('Storage not initialized. Call initDb first.');
86
+ }
87
+ try {
88
+ const data = fs.readFileSync(sessionsFilePath, 'utf-8');
89
+ return JSON.parse(data);
90
+ }
91
+ catch (error) {
92
+ console.error('Error reading sessions:', error);
93
+ return [];
94
+ }
95
+ }
96
+ /**
97
+ * Write sessions to the JSON file
98
+ */
99
+ function writeSessions(sessions) {
100
+ if (!sessionsFilePath) {
101
+ throw new Error('Storage not initialized. Call initDb first.');
102
+ }
103
+ fs.writeFileSync(sessionsFilePath, JSON.stringify(sessions, null, 2));
104
+ }
105
+ /**
106
+ * Insert a new prompt session into the JSON file
107
+ */
108
+ function insertSession(session) {
109
+ const id = (0, uuid_1.v4)();
110
+ const sessions = readSessions();
111
+ const newSession = {
112
+ id,
113
+ ...session,
114
+ };
115
+ sessions.unshift(newSession); // Add to beginning for reverse chronological order
116
+ writeSessions(sessions);
117
+ return id;
118
+ }
119
+ /**
120
+ * Get sessions from the JSON file
121
+ * @param limit - Maximum number of sessions to return (default: 50)
122
+ * @param offset - Number of sessions to skip (default: 0)
123
+ */
124
+ function getSessions(limit = 50, offset = 0) {
125
+ const sessions = readSessions();
126
+ return sessions.slice(offset, offset + limit);
127
+ }
128
+ /**
129
+ * Get a single session by ID
130
+ */
131
+ function getSessionById(id) {
132
+ const sessions = readSessions();
133
+ return sessions.find(s => s.id === id) || null;
134
+ }
135
+ /**
136
+ * Get sessions by provider
137
+ */
138
+ function getSessionsByProvider(provider, limit = 50) {
139
+ const sessions = readSessions();
140
+ return sessions.filter(s => s.provider === provider).slice(0, limit);
141
+ }
142
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Start watch mode
3
+ */
4
+ export declare function startWatch(): Promise<void>;
5
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"AAqHA;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAmChD"}
package/dist/watch.js ADDED
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startWatch = startWatch;
4
+ const git_1 = require("./git");
5
+ const store_1 = require("./store");
6
+ /**
7
+ * Configuration for watch mode
8
+ */
9
+ const POLL_INTERVAL_MS = 5000; // Poll every 5 seconds
10
+ const MAX_DIFF_LENGTH = 100000; // Max diff size to log (100KB)
11
+ /**
12
+ * Initialize watch state
13
+ */
14
+ async function initWatchState() {
15
+ const repoRoot = await (0, git_1.getRepoRoot)();
16
+ const branch = await (0, git_1.getBranch)();
17
+ const lastHash = await (0, git_1.getHeadHash)();
18
+ const isClean = await (0, git_1.isWorkingDirClean)();
19
+ return {
20
+ repoRoot,
21
+ branch,
22
+ lastHash,
23
+ hasUncommittedChanges: !isClean,
24
+ lastChangeDetectedAt: null,
25
+ };
26
+ }
27
+ /**
28
+ * Check for changes and log session if appropriate
29
+ */
30
+ async function checkForChanges(state) {
31
+ try {
32
+ const currentHash = await (0, git_1.getHeadHash)();
33
+ const isClean = await (0, git_1.isWorkingDirClean)();
34
+ const hasUncommittedChanges = !isClean;
35
+ // Detect new uncommitted changes
36
+ if (hasUncommittedChanges && !state.hasUncommittedChanges) {
37
+ // New changes appeared
38
+ state.hasUncommittedChanges = true;
39
+ state.lastChangeDetectedAt = Date.now();
40
+ console.log('[PromptVC Watch] Detected new uncommitted changes...');
41
+ }
42
+ // Detect commit (changes disappeared)
43
+ if (!hasUncommittedChanges && state.hasUncommittedChanges) {
44
+ // Changes were committed
45
+ state.hasUncommittedChanges = false;
46
+ // Check if there's a new commit
47
+ if (currentHash !== state.lastHash) {
48
+ console.log('[PromptVC Watch] Changes committed, logging session...');
49
+ try {
50
+ // Get the diff between old and new commit
51
+ const diff = await (0, git_1.getDiff)(state.lastHash, currentHash);
52
+ // Check diff size
53
+ if (diff.length > MAX_DIFF_LENGTH) {
54
+ console.log(`[PromptVC Watch] Warning: Diff too large (${diff.length} bytes), truncating...`);
55
+ }
56
+ // Get changed files
57
+ const changedFiles = await (0, git_1.getChangedFiles)(state.lastHash, currentHash);
58
+ // Create session
59
+ const sessionData = {
60
+ provider: 'interactive',
61
+ repoRoot: state.repoRoot,
62
+ branch: state.branch,
63
+ preHash: state.lastHash,
64
+ postHash: currentHash,
65
+ prompt: 'interactive session',
66
+ responseSnippet: `Committed ${changedFiles.length} file(s)`,
67
+ files: changedFiles,
68
+ diff: diff.length > MAX_DIFF_LENGTH ? diff.substring(0, MAX_DIFF_LENGTH) + '\n... [truncated]' : diff,
69
+ createdAt: new Date().toISOString(),
70
+ mode: 'interactive',
71
+ autoTagged: true,
72
+ };
73
+ (0, store_1.initDb)(state.repoRoot);
74
+ const sessionId = (0, store_1.insertSession)(sessionData);
75
+ console.log(`[PromptVC Watch] Session logged: ${sessionId}`);
76
+ // Update state
77
+ state.lastHash = currentHash;
78
+ }
79
+ catch (error) {
80
+ console.error('[PromptVC Watch] Error logging session:', error);
81
+ }
82
+ }
83
+ state.lastChangeDetectedAt = null;
84
+ }
85
+ // Check for branch changes
86
+ const currentBranch = await (0, git_1.getBranch)();
87
+ if (currentBranch !== state.branch) {
88
+ console.log(`[PromptVC Watch] Branch changed: ${state.branch} -> ${currentBranch}`);
89
+ state.branch = currentBranch;
90
+ }
91
+ }
92
+ catch (error) {
93
+ console.error('[PromptVC Watch] Error checking for changes:', error);
94
+ }
95
+ }
96
+ /**
97
+ * Start watch mode
98
+ */
99
+ async function startWatch() {
100
+ console.log('[PromptVC Watch] Starting watch mode...');
101
+ console.log('[PromptVC Watch] Monitoring for git changes every 5 seconds');
102
+ console.log('[PromptVC Watch] Press Ctrl+C to stop\n');
103
+ try {
104
+ const state = await initWatchState();
105
+ console.log(`[PromptVC Watch] Repository: ${state.repoRoot}`);
106
+ console.log(`[PromptVC Watch] Branch: ${state.branch}`);
107
+ console.log(`[PromptVC Watch] Current commit: ${state.lastHash.substring(0, 7)}\n`);
108
+ // Poll for changes
109
+ const intervalId = setInterval(async () => {
110
+ await checkForChanges(state);
111
+ }, POLL_INTERVAL_MS);
112
+ // Handle graceful shutdown
113
+ process.on('SIGINT', () => {
114
+ console.log('\n[PromptVC Watch] Stopping watch mode...');
115
+ clearInterval(intervalId);
116
+ process.exit(0);
117
+ });
118
+ process.on('SIGTERM', () => {
119
+ console.log('\n[PromptVC Watch] Stopping watch mode...');
120
+ clearInterval(intervalId);
121
+ process.exit(0);
122
+ });
123
+ // Keep the process alive
124
+ await new Promise(() => { });
125
+ }
126
+ catch (error) {
127
+ console.error('[PromptVC Watch] Failed to start watch mode:', error);
128
+ process.exit(1);
129
+ }
130
+ }
131
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ #!/bin/bash
2
+ # Debug script to see what codex provides to notify hooks
3
+
4
+ LOG_FILE="/tmp/codex-notify-debug.log"
5
+
6
+ echo "=== Codex Notify Called ===" >> "$LOG_FILE"
7
+ echo "Date: $(date)" >> "$LOG_FILE"
8
+ echo "PWD: $PWD" >> "$LOG_FILE"
9
+ echo "Arguments: $@" >> "$LOG_FILE"
10
+ echo "Environment:" >> "$LOG_FILE"
11
+ env | grep -i codex >> "$LOG_FILE" 2>&1 || echo "No CODEX env vars" >> "$LOG_FILE"
12
+ echo "" >> "$LOG_FILE"
13
+
14
+ # List codex session directory
15
+ if [ -d "$HOME/.codex/sessions" ]; then
16
+ echo "Latest session files:" >> "$LOG_FILE"
17
+ ls -lt "$HOME/.codex/sessions" | head -5 >> "$LOG_FILE"
18
+ fi
19
+
20
+ echo "---" >> "$LOG_FILE"