Skip to content

[Duplicate Code] Log directory path construction duplicated in config-writer.ts and compose-generator.ts #3658

@github-actions

Description

@github-actions

Duplicate Code Opportunity

Summary

  • Pattern: Log directory path construction with conditional proxyLogsDir/workDir logic
  • Locations: src/config-writer.ts lines 65-96 and src/compose-generator.ts lines 48-68
  • Impact: ~35 lines of duplicated path resolution logic that must be kept synchronized

Evidence

The exact same conditional logic for resolving log directory paths appears in both files:

compose-generator.ts (lines 48-68):

// Squid logs path: use proxyLogsDir if specified (direct write), otherwise workDir/squid-logs
const squidLogsPath = config.proxyLogsDir || `${config.workDir}/squid-logs`;

// Session state path: use sessionStateDir if specified (timeout-safe, predictable path),
// otherwise workDir/agent-session-state (will be moved to /tmp after cleanup)
const sessionStatePath = config.sessionStateDir || `${config.workDir}/agent-session-state`;

// Agent logs path: always workDir/agent-logs (moved to /tmp after cleanup)
const agentLogsPath = `${config.workDir}/agent-logs`;

// API proxy logs path: if proxyLogsDir is specified, write inside it as a subdirectory
// so that token-usage.jsonl is included in the firewall-audit-logs artifact automatically.
// Otherwise, write to workDir/api-proxy-logs (will be moved to /tmp after cleanup)
const apiProxyLogsPath = config.proxyLogsDir
  ? path.join(config.proxyLogsDir, 'api-proxy-logs')
  : path.join(config.workDir, 'api-proxy-logs');

// CLI proxy logs path: write to workDir/cli-proxy-logs (will be moved to /tmp after cleanup)
const cliProxyLogsPath = config.proxyLogsDir
  ? path.join(config.proxyLogsDir, 'cli-proxy-logs')
  : path.join(config.workDir, 'cli-proxy-logs');

config-writer.ts (lines 65-96):

const squidLogsDir = config.proxyLogsDir || path.join(config.workDir, 'squid-logs');
// ... mkdir + chown logic ...

const apiProxyLogsDir = config.proxyLogsDir
  ? path.join(config.proxyLogsDir, 'api-proxy-logs')
  : path.join(config.workDir, 'api-proxy-logs');
// ... mkdir + chown logic ...

const cliProxyLogsDir = config.proxyLogsDir
  ? path.join(config.proxyLogsDir, 'cli-proxy-logs')
  : path.join(config.workDir, 'cli-proxy-logs');
// ... mkdir + chown logic ...

Both files implement the same conditional path resolution:

  • squidLogsDir/Path: proxyLogsDir || workDir/squid-logs
  • sessionStatePath/Dir: sessionStateDir || workDir/agent-session-state
  • agentLogsPath/Dir: always workDir/agent-logs
  • apiProxyLogsPath/Dir: conditional subdirectory under proxyLogsDir or workDir
  • cliProxyLogsPath/Dir: conditional subdirectory under proxyLogsDir or workDir

Suggested Refactoring

Extract log path resolution into a shared module (e.g., src/log-paths.ts):

import * as path from 'path';
import { WrapperConfig } from './types';

export interface LogPaths {
  squidLogs: string;
  sessionState: string;
  agentLogs: string;
  apiProxyLogs: string;
  cliProxyLogs: string;
}

/**
 * Resolves all log directory paths based on config.
 * Centralizes the conditional proxyLogsDir/workDir logic.
 */
export function resolveLogPaths(config: WrapperConfig): LogPaths {
  return {
    squidLogs: config.proxyLogsDir || path.join(config.workDir, 'squid-logs'),
    sessionState: config.sessionStateDir || path.join(config.workDir, 'agent-session-state'),
    agentLogs: path.join(config.workDir, 'agent-logs'),
    apiProxyLogs: config.proxyLogsDir
      ? path.join(config.proxyLogsDir, 'api-proxy-logs')
      : path.join(config.workDir, 'api-proxy-logs'),
    cliProxyLogs: config.proxyLogsDir
      ? path.join(config.proxyLogsDir, 'cli-proxy-logs')
      : path.join(config.workDir, 'cli-proxy-logs'),
  };
}

Usage in config-writer.ts:

const logPaths = resolveLogPaths(config);
// Create directories with appropriate permissions
if (!fs.existsSync(logPaths.squidLogs)) {
  fs.mkdirSync(logPaths.squidLogs, { recursive: true, mode: 0o755 });
  // ... chown logic ...
}

Usage in compose-generator.ts:

const logPaths = resolveLogPaths(config);
// Pass to service builders
const squidService = buildSquidService(config, networkConfig, sslConfig, squidConfigContent, logPaths.squidLogs);

Why This Matters

  1. Maintenance burden: Changes to log path logic must be synchronized across two files
  2. Bug risk: Path construction bugs ([Duplicate Code] Log directory creation pattern repeated 6 times in container-lifecycle.ts #2711 closed) demonstrate the risk of scattered path logic
  3. Consistency: The same config inputs should always produce the same paths, but subtle differences could emerge

Affected Files

  • src/compose-generator.ts — lines 48-68
  • src/config-writer.ts — lines 65-96

Effort Estimate

Low — Extract to a shared module with 2 call sites


Detected by Duplicate Code Detector workflow. Run date: 2026-05-23

Note

🔒 Integrity filter blocked 1 item

The following item was blocked because it doesn't meet the GitHub integrity level.

  • #1812 search_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".

To allow these resources, lower min-integrity in your GitHub frontmatter:

tools:
  github:
    min-integrity: approved  # merged | approved | unapproved | none

Generated by Duplicate Code Detector · ● 11.3M ·

  • expires on Jun 22, 2026, 9:59 PM UTC

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions