Skip to content
Draft
66 changes: 66 additions & 0 deletions src/commands/contents/cvf-chat-command-content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
export const chatCommandContent = `---
description: Start an extended CodeVF engineer chat session with full context
---

# CodeVF Engineer Chat

Please start an extended debugging session with a CodeVF engineer using the \`codevf-chat\` MCP tool.

**Current context (include relevant logs, errors, and recent changes):**
{{PROMPT}}

---

**Instructions for Claude:**

1. Ask a short clarifying question if needed: "What's the issue?"
2. Call \`codevf-chat\` with:
- \`message\`: include the user's issue and any gathered context
- \`maxCredits\`: suggest 240 (or adjust if user specifies)
3. **IMPORTANT: Every time you successfully execute a command, run a task, or complete an action**, immediately call \`codevf-chat\` again with a JSON thought process in this format:
\`\`\`json
{
"type": "thought_process",
"action": "brief description of what was done",
"status": "success|in_progress|error",
"result": "what happened and outcome",
"next_step": "what to do next"
}
\`\`\`
Include this JSON in your message to the engineer. Example: "Executed command \\\`npm install\\\`. \`\`\`json {\"type\": \"thought_process\", \"action\": \"install dependencies\", \"status\": \"success\", \"result\": \"All packages installed\", \"next_step\": \"Run the dev server\"} \`\`\`"

4. **When running commands that produce output**, redirect the output of the logs to \`logs.txt\` so the engineer can review results. For example:
- \`bun dev > logs.txt\`
- \`npm run dev > logs.txt\`
- \`npm test > logs.txt\`
- \`node script.js > logs.txt\`

Always use the filename \`logs.txt\` for consistency.

5. **IMPORTANT: Whenever the user requests the server to be up** (e.g., "start the dev server", "run the server", "get the app running", etc.), you MUST also start log streaming immediately after. Run one of these commands in a separate process:
- \`codevf watch-logs <task-id>\`
- \`bun x codevf watch-logs <task-id>\` (if codevf is not installed globally)
- \`npx codevf watch-logs <task-id>\` (if needed)

Replace \`<task-id>\` with the actual task ID. This ensures the engineer sees all logs from the running server in real-time. Start this in a background process or separate terminal so it doesn't block the server from running.

6. **When sending files to the engineer**, format your message as JSON in this structure:
\`\`\`json
{
"type": "file_message",
"message": "Brief description of what this file is or why you're sending it",
"file": {
"name": "filename.ext",
"path": "relative/path/to/file",
"content": "file content here (can be large)"
}
}
\`\`\`
The frontend will automatically detect this JSON structure and render the file as a badge with the ability to open the content in a dialog with markdown rendering. Example: \`\`\`json {\"type\": \"file_message\", \"message\": \"Here's the error log for debugging:\", \"file\": {\"name\": \"error.log\", \"path\": \"logs/error.log\", \"content\": \"[ERROR] Connection failed...\"}} \`\`\`
7. Return the engineer response or session link directly.

**Notes:**
- The engineer interface will render thought process JSON blocks as formatted thought processes to help track progress
- File message JSON blocks will be detected and rendered as interactive file badges with dialog viewers
- Keep JSON formatting consistent - use valid JSON within markdown code blocks
`;
21 changes: 0 additions & 21 deletions src/commands/cvf-chat-command-content.ts

This file was deleted.

112 changes: 112 additions & 0 deletions src/commands/log-wrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/usr/bin/env node

/**
* Log Wrapper - Intercepts console output and writes properly formatted logs to logs.txt
*
* Usage:
* tsx src/commands/log-wrapper.ts "npm run dev"
* OR
* node log-wrapper.js "npm run build"
*
* This script:
* 1. Runs the specified command
* 2. Intercepts console.log/error/warn/info
* 3. Properly serializes objects with JSON.stringify
* 4. Writes to logs.txt with timestamps
*/

import { spawn } from 'child_process';
import * as fs from 'fs';
import * as path from 'path';

const logsPath = path.join(process.cwd(), 'logs.txt');

// Clear or create logs file
fs.writeFileSync(logsPath, '', 'utf-8');

function writeLog(level: string, args: any[]): void {
const timestamp = new Date().toISOString();

// Serialize each argument properly
const formattedArgs = args.map((arg) => {
if (typeof arg === 'string') {
return arg;
} else if (arg === null) {
return 'null';
} else if (arg === undefined) {
return 'undefined';
} else if (typeof arg === 'object') {
try {
return JSON.stringify(arg, null, 2);
} catch {
return String(arg);
}
} else {
return String(arg);
}
});

const message = formattedArgs.join(' ');
const logLine = `[${timestamp}] [${level}] ${message}\n`;

// Append to logs.txt
fs.appendFileSync(logsPath, logLine, 'utf-8');

// Also output to console for real-time feedback
console.log(logLine.trim());
}

// Get the command from arguments
const command = process.argv[2];
if (!command) {
console.error('Usage: log-wrapper <command>');
console.error('Example: log-wrapper "npm run dev"');
process.exit(1);
}

// Parse command and arguments
const [cmd, ...cmdArgs] = command.split(' ');

console.log(`Starting command: ${command}`);
console.log(`Logs will be written to: ${logsPath}\n`);

// Spawn the child process
const child = spawn(cmd, cmdArgs, {
stdio: ['inherit', 'pipe', 'pipe'],
shell: true,
});

// Intercept stdout
if (child.stdout) {
child.stdout.on('data', (data: Buffer) => {
const lines = data.toString().split('\n');
for (const line of lines) {
if (line.trim()) {
writeLog('stdout', [line]);
}
}
});
}

// Intercept stderr
if (child.stderr) {
child.stderr.on('data', (data: Buffer) => {
const lines = data.toString().split('\n');
for (const line of lines) {
if (line.trim()) {
writeLog('stderr', [line]);
}
}
});
}

// Handle process exit
child.on('exit', (code) => {
writeLog('info', [`Process exited with code ${code}`]);
process.exit(code || 0);
});

child.on('error', (err) => {
writeLog('error', [`Failed to start process: ${err.message}`]);
process.exit(1);
});
4 changes: 2 additions & 2 deletions src/commands/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import path from 'path';
import os from 'os';
import { ConfigManager } from '../lib/config/manager.js';
import { OAuthFlow } from '../lib/auth/oauth-flow.js';
import { commandContent } from './cvf-command-content.js';
import { chatCommandContent } from './cvf-chat-command-content.js';
import { commandContent } from './contents/cvf-command-content.js';
import { chatCommandContent } from './contents/cvf-chat-command-content.js';

/**
* Get Claude Code config path based on platform
Expand Down
Loading