/** * Shared query helpers — cross-cutting utility functions used across query modules. * * Ported from get-shit-done/bin/lib/core.cjs and state.cjs. * Provides phase name normalization, path handling, regex escaping, * and STATE.md field extraction. * * @example * ```typescript * import { normalizePhaseName, planningPaths } from './helpers.js'; * * normalizePhaseName('9'); // '09' * normalizePhaseName('CK-01'); // '01' * * const paths = planningPaths('/project'); * // { planning: '/project/.planning', state: '/project/.planning/STATE.md', ... } * ``` */ export { SUPPORTED_RUNTIMES, type Runtime } from '../model-catalog.js'; import { type Runtime } from '../model-catalog.js'; import { type PlanningPaths } from './workspace.js'; export { stateExtractField } from './state-document.js'; /** * Resolve the per-runtime config directory, mirroring * `bin/install.js:getGlobalDir()`. Agents live at `/agents`. */ export declare function getRuntimeConfigDir(runtime: Runtime): string; /** * Detect the invoking runtime using issue #2402 precedence: * 1. `GSD_RUNTIME` env var * 2. `config.runtime` field (from `.planning/config.json` when loaded) * 3. Fallback to `'claude'` * * Unknown values fall through to the next tier rather than throwing, so * stale env values don't hard-block workflows. */ export declare function detectRuntime(config?: { runtime?: unknown; }): Runtime; /** * Resolve the GSD agents directory for a given runtime. * * Precedence: * 1. `GSD_AGENTS_DIR` — explicit SDK override (wins over runtime selection) * 2. `/.claude/agents` — project-local install (Claude Code `--local`, * `npx get-shit-done-cc@latest`); checked first to match Claude Code's own * local-first agent resolution at spawn (#3799) * 3. `/agents` — global installer-parity default * * Defaults to Claude when no runtime is passed, matching prior behavior * (see `init-runner.ts`, which is Claude-only by design). * * Local-first resolution was introduced for bug #3799: when both a project-local * `.claude/agents/` and a global `~/.claude/agents/` exist (the global may be * auto-created empty by Claude Code), the SDK must resolve to the project-local * directory to match where the agents are actually installed. * * The repo-local fallback itself was added for bug #3751. */ export declare function resolveAgentsDir(runtime?: Runtime, projectDir?: string): string; /** * Resolve the runtime-global skills base directory. * * Most runtimes store global skills under `/skills`. * `cline` is rules-based and has no global skills directory. */ export declare function resolveGlobalSkillsBase(runtime: Runtime): string | null; /** * Render a human-readable runtime-global skills base path. * Uses `~` when the path lives under the current home dir. * Returns a displayable string for unsupported runtimes (never null). */ export declare function renderGlobalSkillsBaseDisplayPath(runtime: Runtime): string; /** Resolve one runtime-global skill directory, or `null` when unsupported. */ export declare function resolveGlobalSkillDir(runtime: Runtime, skillName: string): string | null; /** Resolve the canonical SKILL.md path for one runtime-global skill. */ export declare function resolveGlobalSkillMarkdownPath(runtime: Runtime, skillName: string): string | null; /** * Render a human-readable global skill path for warnings. * Uses `~` when the path lives under the current home dir. */ export declare function renderGlobalSkillDisplayPath(runtime: Runtime, skillName: string): string; /** Paths to common .planning files. */ export type { PlanningPaths } from './workspace.js'; /** * Escape regex special characters in a string. * * @param value - String to escape * @returns String with regex special characters escaped */ export declare function escapeRegex(value: string): string; /** * Normalize a phase identifier to a canonical form. * * Strips optional project code prefix (e.g., 'CK-01' -> '01'), * pads numeric part to 2 digits, preserves letter suffix and decimal parts. * * @param phase - Phase identifier string * @returns Normalized phase name */ export declare function normalizePhaseName(phase: string): string; /** * Compare two phase directory names for sorting. * * Handles numeric, letter-suffixed, and decimal phases. * Falls back to string comparison for custom IDs. * * @param a - First phase directory name * @param b - Second phase directory name * @returns Negative if a < b, positive if a > b, 0 if equal */ export declare function comparePhaseNum(a: string, b: string): number; /** * Extract the phase token from a directory name. * * Supports: '01-name', '1009A-name', '999.6-name', 'CK-01-name', 'PROJ-42-name'. * * @param dirName - Directory name to extract token from * @returns The token portion (e.g. '01', '1009A', '999.6', 'PROJ-42') */ export declare function extractPhaseToken(dirName: string): string; /** * Check if a directory name's phase token matches the normalized phase exactly. * * Case-insensitive comparison for the token portion. * * @param dirName - Directory name to check * @param normalized - Normalized phase name to match against * @returns True if the directory matches the phase */ export declare function phaseTokenMatches(dirName: string, normalized: string): boolean; /** * Convert a path to POSIX format (forward slashes). * * @param p - Path to convert * @returns Path with all separators as forward slashes */ export declare function toPosixPath(p: string): string; /** * Normalize markdown content for consistent formatting. * * Port of `normalizeMd` from core.cjs lines 434-529. * Applies: CRLF normalization, blank lines around headings/fences/lists, * blank line collapsing (3+ to 2), terminal newline. * * @param content - Markdown content to normalize * @returns Normalized markdown string */ export declare function normalizeMd(content: string): string; /** * Get common .planning file paths for a project directory. * * When `workstream` is provided, all paths are rooted under * `.planning/workstreams/` instead of `.planning`. * All paths returned in POSIX format. * * @param projectDir - Root project directory * @param workstream - Optional workstream name * @returns Object with paths to common .planning files */ export declare function planningPaths(projectDir: string, workstream?: string): PlanningPaths; export { findProjectRoot } from '../project-root/index.js'; /** * Resolve a user-supplied path against the project and ensure it cannot escape * the real project root (prefix checks are insufficient; symlinks are handled * via realpath). * * @param projectDir - Project root directory * @param userPath - Relative or absolute path from user input * @returns Canonical resolved path within the project */ export declare function resolvePathUnderProject(projectDir: string, userPath: string): Promise; /** * Resolve a user-supplied file path the way CJS frontmatter handlers do. * * Mirrors `path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath)` * from get-shit-done/bin/lib/frontmatter.cjs (lines 323, 340, 354, 369). * Does NOT enforce the "under project root" prefix check — frontmatter * verbs accept arbitrary absolute paths (the user is naming a file outside * `.planning/`, often a phase-scoped plan in an external location, or a * tmpdir inside `/var/folders` whose path includes spaces). * * Bug #3509 parity: tests on macOS use `os.tmpdir()` directories that * resolve outside the project root; the project-scoped variant was * rejecting them with "path escapes project directory". Use this helper * for the frontmatter family. Use `resolvePathUnderProject` for commands * that must stay inside the project (e.g. template output, decisions). */ export declare function resolveFrontmatterPath(projectDir: string, userPath: string): string; /** Port of `sanitizeForPrompt` from `security.cjs`. */ export declare function sanitizeForPrompt(text: string): string; /** Port of `sanitizeForDisplay` from `security.cjs` (matches CLI JSON). */ export declare function sanitizeForDisplay(text: string): string; //# sourceMappingURL=helpers.d.ts.map