mirror of
https://github.com/KeygraphHQ/shannon.git
synced 2026-09-14 05:59:06 +02:00
105 lines
4.2 KiB
TypeScript
105 lines
4.2 KiB
TypeScript
/** Centralized path constants for the worker package */
|
|
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
|
|
/** Worker package root (apps/worker/) resolved from compiled dist/ files */
|
|
const WORKER_ROOT = path.resolve(import.meta.dirname, '..');
|
|
|
|
export const PROMPTS_DIR = path.join(WORKER_ROOT, 'prompts');
|
|
export const CONFIGS_DIR = path.join(WORKER_ROOT, 'configs');
|
|
|
|
/** Bundled Typst template that renders report.json into the PDF report. */
|
|
export const TYPST_TEMPLATE = path.join(WORKER_ROOT, 'templates', 'typst', 'report.typ');
|
|
|
|
/** Compiled pi extension dir that enforces bounded `bash` timeouts (resolved from dist/) */
|
|
export const BASH_TIMEOUT_EXTENSION_DIR = path.join(import.meta.dirname, 'ai', 'extensions', 'bash-timeout');
|
|
|
|
/**
|
|
* Where the CLI mounts a pi model config passed with `--models-config`; its presence is
|
|
* what enables models.json. Must match MODELS_CONFIG_CONTAINER_PATH in the CLI package.
|
|
*/
|
|
export const MODELS_CONFIG_PATH = '/app/models.json';
|
|
|
|
/** Default deliverables subdirectory relative to repoPath */
|
|
export const DEFAULT_DELIVERABLES_SUBDIR = '.shannon/deliverables';
|
|
|
|
/** Default audit log directory */
|
|
export const DEFAULT_AUDIT_DIR = './workspaces';
|
|
|
|
/**
|
|
* Hidden subdirectory inside each run directory that holds all internals
|
|
* (logs, prompts, session state, deliverables, browser artifacts). Keeps the
|
|
* run folder's top level clean so only the final report is visible.
|
|
*/
|
|
export const INTERNAL_DIR = '.shannon';
|
|
|
|
/** Filename of the assembled report inside the deliverables dir (internal, source of the surfaced copy) */
|
|
export const ASSEMBLED_REPORT_FILENAME = 'comprehensive_security_assessment_report.md';
|
|
|
|
/** Filename of the compiled PDF report inside the deliverables dir (internal, source of the surfaced copy) */
|
|
export const ASSEMBLED_REPORT_PDF_FILENAME = 'comprehensive_security_assessment_report.pdf';
|
|
|
|
/** Filename of the human-facing PDF report surfaced at the run directory root */
|
|
export const FINAL_REPORT_PDF_FILENAME = 'Security-Assessment-Report.pdf';
|
|
|
|
/** Filename of the human-facing markdown report surfaced at the run directory root, alongside the PDF */
|
|
export const FINAL_REPORT_MD_FILENAME = 'Security-Assessment-Report.md';
|
|
|
|
/** Structured findings the report agent emits; the markdown report is rendered from it. */
|
|
export const REPORT_JSON_FILENAME = 'report.json';
|
|
|
|
/** SARIF 2.1.0 log, written for exploit=true runs unless report.sarif is set to false. */
|
|
export const SARIF_FILENAME = 'report.sarif';
|
|
|
|
/** Deterministic receipt for the canonical report finalization commit. */
|
|
export const REPORT_FINALIZATION_MANIFEST_FILENAME = 'report_finalization_manifest.json';
|
|
|
|
/**
|
|
* Resolve the session.json path for a run directory, preferring the current
|
|
* `.shannon/` location and falling back to the legacy run-root location so
|
|
* pre-restructure workspaces remain listable and resumable.
|
|
*/
|
|
export function resolveSessionJsonPath(runDir: string): string {
|
|
const current = path.join(runDir, INTERNAL_DIR, 'session.json');
|
|
if (fs.existsSync(current)) {
|
|
return current;
|
|
}
|
|
const legacy = path.join(runDir, 'session.json');
|
|
if (fs.existsSync(legacy)) {
|
|
return legacy;
|
|
}
|
|
return current;
|
|
}
|
|
|
|
/**
|
|
* Resolve the deliverables directory for a given repoPath and optional subdir override.
|
|
* @param repoPath - Absolute path to the target repository
|
|
* @param subdir - Subdirectory relative to repoPath (default: '.shannon/deliverables')
|
|
*/
|
|
export function deliverablesDir(repoPath: string, subdir: string = DEFAULT_DELIVERABLES_SUBDIR): string {
|
|
return path.join(repoPath, ...subdir.split('/'));
|
|
}
|
|
|
|
/**
|
|
* Repository root — walk up from WORKER_ROOT looking for pnpm-workspace.yaml.
|
|
* Falls back to two levels up (apps/worker/ → repo root) if not found.
|
|
*/
|
|
function findRepoRoot(): string {
|
|
let dir = WORKER_ROOT;
|
|
for (let i = 0; i < 5; i++) {
|
|
if (fs.existsSync(path.join(dir, 'pnpm-workspace.yaml'))) {
|
|
return dir;
|
|
}
|
|
const parent = path.dirname(dir);
|
|
if (parent === dir) break;
|
|
dir = parent;
|
|
}
|
|
return path.resolve(WORKER_ROOT, '..', '..');
|
|
}
|
|
|
|
const REPO_ROOT = findRepoRoot();
|
|
|
|
/** Default root for named scan workspaces; each session's audit directory nests under here. */
|
|
export const WORKSPACES_DIR = path.join(REPO_ROOT, 'workspaces');
|