diff --git a/docs/usage.md b/docs/usage.md index 278bdb62..4f17525c 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -845,6 +845,12 @@ sudo awf \ - Location: `/tmp/awf-agent-logs-/` - View with: `cat /tmp/awf-agent-logs-/*.log` +**Agent Session State:** +- Contains structured conversation data written by Copilot CLI (e.g., `events.jsonl`) +- Location: `/tmp/awf-agent-session-state-/` +- View with: `cat /tmp/awf-agent-session-state-/events.jsonl` +- Useful for triage dashboards, benchmarking, and debugging Copilot CLI runs + **Squid Logs:** - Contains all HTTP/HTTPS traffic (allowed and denied) - Location: `/tmp/squid-logs-/` @@ -859,9 +865,15 @@ sudo cat /tmp/squid-logs-/access.log ``` **How it works:** -- GitHub Copilot CLI writes to `~/.copilot/logs/`, Squid writes to `/var/log/squid/` -- Volume mounts map these to `${workDir}/agent-logs/` and `${workDir}/squid-logs/` -- Before cleanup, logs are automatically moved to `/tmp/awf-agent-logs-/` and `/tmp/squid-logs-/` (if they exist) +- GitHub Copilot CLI writes to `~/.copilot/logs/` and `~/.copilot/session-state/`; Squid writes to `/var/log/squid/` +- Volume mounts map container paths to: + - `${workDir}/agent-logs/` → `~/.copilot/logs/` + - `${workDir}/agent-session-state/` → `~/.copilot/session-state/` + - `${workDir}/squid-logs/` → `/var/log/squid/` +- Before cleanup, non-empty directories are automatically moved to timestamped `/tmp` paths: + - `/tmp/awf-agent-logs-/` + - `/tmp/awf-agent-session-state-/` + - `/tmp/squid-logs-/` - Empty log directories are not preserved (avoids cluttering /tmp) ### Keep Containers for Inspection diff --git a/package-lock.json b/package-lock.json index d34952f6..59aeed5f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4061,9 +4061,9 @@ } }, "node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5406,9 +5406,9 @@ "license": "ISC" }, "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/src/docker-manager.ts b/src/docker-manager.ts index 27e60965..9af94140 100644 --- a/src/docker-manager.ts +++ b/src/docker-manager.ts @@ -736,6 +736,8 @@ export function generateDockerCompose( `${workspaceDir}:${workspaceDir}:rw`, // Mount agent logs directory to workDir for persistence `${config.workDir}/agent-logs:${effectiveHome}/.copilot/logs:rw`, + // Mount agent session-state directory to workDir for persistence (events.jsonl) + `${config.workDir}/agent-session-state:${effectiveHome}/.copilot/session-state:rw`, // Init signal volume for iptables init container coordination `${initSignalDir}:/tmp/awf-init:rw`, ]; @@ -1548,6 +1550,13 @@ export async function writeConfigs(config: WrapperConfig): Promise { } logger.debug(`Agent logs directory created at: ${agentLogsDir}`); + // Create agent session-state directory for persistence (events.jsonl written by Copilot CLI) + const agentSessionStateDir = path.join(config.workDir, 'agent-session-state'); + if (!fs.existsSync(agentSessionStateDir)) { + fs.mkdirSync(agentSessionStateDir, { recursive: true }); + } + logger.debug(`Agent session-state directory created at: ${agentSessionStateDir}`); + // Create squid logs directory for persistence // If proxyLogsDir is specified, write directly there (timeout-safe) // Otherwise, use workDir/squid-logs (will be moved to /tmp after cleanup) @@ -2104,6 +2113,18 @@ export async function cleanup(workDir: string, keepFiles: boolean, proxyLogsDir? } } + // Preserve agent session-state before cleanup (contains events.jsonl from Copilot CLI) + const agentSessionStateDir = path.join(workDir, 'agent-session-state'); + const agentSessionStateDestination = path.join(os.tmpdir(), `awf-agent-session-state-${timestamp}`); + if (fs.existsSync(agentSessionStateDir) && fs.readdirSync(agentSessionStateDir).length > 0) { + try { + fs.renameSync(agentSessionStateDir, agentSessionStateDestination); + logger.info(`Agent session state preserved at: ${agentSessionStateDestination}`); + } catch (error) { + logger.debug('Could not preserve agent session state:', error); + } + } + // Preserve api-proxy logs before cleanup if (proxyLogsDir) { // Logs were written directly to sibling of proxyLogsDir during runtime (timeout-safe)