// Helpers for locating claude's per-session JSONL transcripts on disk.
//
// Claude Code writes one JSONL file per session at
//
//     ${CLAUDE_CONFIG_DIR or ~/.claude}/projects/<project-slug>/<claude-session-id>.jsonl
//
// where <project-slug> is the cwd at spawn time with every '/' replaced by '-'
// (leading slash included, so /home/foo becomes -home-foo). set
// CLAUDE_CONFIG_DIR on the manager unit so brand isolation holds for
// credentials and JSONL transcripts.
//
// The intrinsic JSONL filename is the canonical `sessionId` Claude Code
// writes into its PID file (`${CLAUDE_CONFIG_DIR}/sessions/<pid>.json`)
// at process init. fs-watcher.ts is the single source of truth. The
// `bridgeSuffixFromUrl` helper is still used by url-capture for the
// operator-facing iframe URL, but is no longer the readiness gate.
import { existsSync, readdirSync } from 'node:fs';
import { homedir } from 'node:os';
import { join } from 'node:path';
export function claudeStateRoot(env = process.env) {
    return env.CLAUDE_CONFIG_DIR ?? join(homedir(), '.claude');
}
export function projectSlugForCwd(cwd) {
    return cwd.replace(/\//g, '-');
}
export function sessionsDir(env = process.env) {
    return join(claudeStateRoot(env), 'sessions');
}
export function projectsDirForCwd(cwd, env = process.env) {
    return join(claudeStateRoot(env), 'projects', projectSlugForCwd(cwd));
}
/** Task 258 — single derivation site for the on-disk path of a session's
 *  JSONL transcript. The JSONL basename IS the sessionId; we never store
 *  a path. `opts.archived` returns the `archive/` variant for the user-
 *  initiated archive route. Callers that need the live-or-archived check
 *  consult both variants. */
export function jsonlPathForSessionId(spawnCwd, sessionId, opts = {}, env = process.env) {
    const dir = projectsDirForCwd(spawnCwd, env);
    return opts.archived
        ? join(dir, 'archive', `${sessionId}.jsonl`)
        : join(dir, `${sessionId}.jsonl`);
}
/** Task 260 — archive subdir for a given spawn cwd. fs-watcher uses this
 *  to enumerate archived JSONLs at boot and to mount a second fs.watch. */
export function archiveDirForCwd(cwd, env = process.env) {
    return join(projectsDirForCwd(cwd, env), 'archive');
}
/** Task 260 — sidecar path for a session's spawn metadata. Lives alongside
 *  the JSONL: archived JSONL → archived sidecar; live JSONL → live sidecar.
 *  The pair moves together on /archive and /unarchive. */
export function sidecarPathForSessionId(spawnCwd, sessionId, opts = {}, env = process.env) {
    const dir = projectsDirForCwd(spawnCwd, env);
    return opts.archived
        ? join(dir, 'archive', `${sessionId}.meta.json`)
        : join(dir, `${sessionId}.meta.json`);
}
/** Task 278 — per-session capture of the binary's `[auto-mode]
 *  verifyAutoModeGateAccess: ...` debug line, written when the spawn passes
 *  `--debug=auto-mode --debug-file=<this>`. The file sits next to the JSONL
 *  and meta sidecar, and `permission-mode-tail.ts` watches it via fs-watcher
 *  to derive `effectivePermissionMode` for the SSE row payload. Single line
 *  on auto spawns; absent on non-auto spawns. */
export function permissionModeLogPathForSessionId(spawnCwd, sessionId, opts = {}, env = process.env) {
    const dir = projectsDirForCwd(spawnCwd, env);
    return opts.archived
        ? join(dir, 'archive', `${sessionId}.permission-mode.log`)
        : join(dir, `${sessionId}.permission-mode.log`);
}
/** Task 547 — walk `<claudeConfigDir>/projects/<slug>/` (and each
 *  `<slug>/archive/`) for `<sessionId>.jsonl`. Returns the first match
 *  or null when no JSONL exists. Used by `/rc-spawn` to decide between
 *  `--resume <sid>` (existing transcript) and `--session-id <sid>`
 *  (fresh conversation under that id). */
export function findExistingJsonlForSessionId(claudeConfigDir, sessionId) {
    const projectsRoot = join(claudeConfigDir, 'projects');
    if (!existsSync(projectsRoot))
        return null;
    let slugs;
    try {
        slugs = readdirSync(projectsRoot, { withFileTypes: true })
            .filter((d) => d.isDirectory())
            .map((d) => d.name);
    }
    catch {
        return null;
    }
    const basename = `${sessionId}.jsonl`;
    for (const slug of slugs) {
        const live = join(projectsRoot, slug, basename);
        if (existsSync(live))
            return live;
        const archived = join(projectsRoot, slug, 'archive', basename);
        if (existsSync(archived))
            return archived;
    }
    return null;
}
/** Extract the bridge-session suffix from a `/remote-control` URL. This is
 *  the part after `session_`, not the intrinsic JSONL filename. Returns
 *  null if the URL has no `session_<...>` component. */
export function bridgeSuffixFromUrl(url) {
    const match = url.match(/session_([A-Za-z0-9_-]+)/);
    return match ? match[1] : null;
}
//# sourceMappingURL=jsonl-path.js.map