import type { ProjectRegistration } from '../../types'; export { assertProjectCodeIsSafe, isProjectCodeSafe } from '../../security'; export { toContainerApiUrl } from '../../utils'; export { shellQuote } from '../../utils/shell-quote'; /** * Sanitize one tenantCode / projectCode segment for use in generated names: * lowercase, with every character outside `[a-z0-9-]` collapsed to `-`. * * Shared by all three platforms so naming cannot drift: systemd unit names * and per-project log-dir keys (linux), docker container names (all * platforms), and scheduled-task names (win32). `detectInstallCollisions` * relies on its callers deriving names through this same mapping. * * Thin service-layer alias for the canonical `sanitizeNameSegment` in * `utils.ts`; the name is retained so the service-installer call sites read * intentfully ("service name segment"). */ export declare function sanitizeServiceNameSegment(s: string): string; /** * Validate a user-supplied `project.projectDir` for use as a bind mount. * * Returns the original value when the path is acceptable, or `undefined` * when it should be dropped (and the wrapper / supervisor should fall back * to the default per-project dir). Emits a warning so the user is aware * that their configured projectDir was ignored. * * Rejects: empty string, non-existent paths, and paths under * `BLOCKED_PATH_PREFIXES` / `getSensitiveHomePaths` (e.g. `/etc`, * `~/.ssh`). All three reasons end up at the same fallback to keep the * caller code simple. */ export declare function validateProjectDirForMount(projectDir: string | undefined): string | undefined; export interface CollisionInfo { /** The conflicting unit name / plist label (already sanitized). */ name: string; /** Other configured `/` tuples mapping to the same name. */ others: string[]; /** * True when this FQN appears more than once in config (literal * duplicate entry). The caller should surface a different message in * that case ("remove the duplicate row" vs. "rename one of the codes"). * `isDuplicate` and `others.length > 0` can BOTH be true when a config * contains both a literal duplicate AND a sanitize-collision sibling * (e.g. `[mbc/MBC_01, mbc/MBC_01, mbc/MBC-01]`). */ isDuplicate: boolean; } export interface CollisionDetectionResult { /** * FQN (`/`) → sanitized unit-name / plist-label * for every project that passed `isProjectCodeSafe`. Callers that need * the sanitized name later (orphan-protection sets, unit-file paths) * can read it from here instead of recomputing via `nameFn`. */ names: Map; /** * FQN → CollisionInfo for projects that conflict with another * configured entry (sanitize-collision and/or literal duplicate). * Projects without conflict are absent from this map. */ collisions: Map; } /** * Detect sanitizeServiceNameSegment() collisions across configured projects. * * `nameFn` derives the per-platform unit-name / plist-label from * (tenantCode, projectCode). Codes that fail `isProjectCodeSafe` are * skipped from collision counting (they're refused independently by * `writeProjectServiceFiles`, and including them here would falsely * collide with a valid sibling like `MBC;01` + `MBC-01`). * * The returned `names` map covers ALL projects that passed validation * (single source of truth — callers should not recompute via `nameFn` * again). The `collisions` map only includes FQNs with a conflict. * * Shared between linux-service and darwin-service to keep the two * platforms from drifting on collision semantics. */ export declare function detectInstallCollisions(projects: ProjectRegistration[], nameFn: (tenantCode: string, projectCode: string) => string): CollisionDetectionResult; //# sourceMappingURL=wrapper-helpers.d.ts.map