/** * * Read-side companion to the `peaks standards init` / `peaks standards update` * writers in `./project-standards-service.ts`. The writer KNOWS how to scaffold * `.peaks/standards/{common,}/` (2.0 canonical) from the curated * baseline; this module detects when the consumer project's rules tree is * missing or empty and emits a copy-pasteable diagnostic for the operator. * * Why a separate read module: the writer is `apply`-gated and write-bounded * (it touches the filesystem via `prevalidateWrites`/`assertNotHomedirBaseline`). * The detector is read-only and platform-aware (win32 path separators for * Windows consumers) — coupling the two would force the writer to grow a * read-only flag and a platform-switching argument. * * Cross-platform path rendering (AC6): the detector switches on * `process.platform` and renders the project path with `path.sep` so Windows * consumers see `C:\Users\\project\.claude\rules\` verbatim rather than the * POSIX form. The detection logic itself (readdirSync on `node:fs`) is * platform-neutral. * * Once-per-session dedup (AC7): `peaks workspace init` writes a marker at * `.peaks/_runtime//.standards-checked` after the first detection * pass. `detectMissingProjectStandards` does NOT consult the marker — that's * the caller's responsibility (the CLI command decides whether to skip per * AC7's "once per session" contract). */ import type { StandardsLanguage } from './project-standards-service.js'; export type MissingProjectStandardsDiagnostic = { readonly missing: boolean; /** * Absolute path to the rules root (`/.claude/rules`). Rendered * with the platform-native separator so Windows consumers see * `C:\...\.claude\rules` verbatim. */ readonly path: string; /** * Copy-pasteable remediation hint for the operator. Always present, even * when `missing: false`, so downstream callers can show "if you ever need * to re-scaffold: ..." as a nextAction without re-running the detector. */ readonly remediation: string; readonly language: StandardsLanguage; }; /** * List which standards tree components are missing vs populated. * * Returns one of three stable shapes: * - { kind: 'complete' } — both common + language overlay populated * - { kind: 'common-missing' } — common dir absent/empty (universal) * - { kind: 'language-missing', language } — common ok, language overlay absent/empty * * The detector previously returned a single boolean that flipped to * "missing: true" the moment the language overlay was empty, but printed * the remediation as if BOTH common AND language were missing — a UX bug * that surfaced in ice-cola (common=4 .md files; typescript=1 .md file; * javascript overlay absent → label said "no project-local standards found" * even though common was clearly populated). This split lets the CLI emit * a precise remediation string per kind. */ export type StandardsTreeDiagnostic = { readonly kind: 'complete'; } | { readonly kind: 'common-missing'; } | { readonly kind: 'language-missing'; readonly language: StandardsLanguage; }; export declare function diagnoseStandardsTree(projectRoot: string, language: StandardsLanguage): StandardsTreeDiagnostic; /** * Detect whether a consumer project's `.peaks/standards/` tree (2.0 * canonical) is missing or empty. * * - `.peaks/standards/common/` MUST exist AND contain at least one * `.md` file. * - `.peaks/standards//` MUST exist AND contain at least one * `.md` file — except for `generic`, where the language dir is * OPTIONAL. * * Returns `{ missing: true, ... }` when either required dir is absent or * empty. The diagnostic is always populated so the caller can surface the * remediation hint unconditionally (the CLI uses the same string for both * the stderr banner and the JSON envelope warning). */ export declare function detectMissingProjectStandards(projectRoot: string, language: StandardsLanguage): MissingProjectStandardsDiagnostic; /** * Once-per-session marker file path. The CLI writes this file under * `.peaks/_runtime//` after the first diagnostic pass so that * subsequent `peaks workspace init` invocations within the same session * skip the stderr banner (the diagnostic is still computable for * programmatic consumers via `detectMissingProjectStandards`). */ export declare function getStandardsCheckedMarkerPath(projectRoot: string, sessionId: string): string; /** * Mark this session as "standards checked" so subsequent invocations can * skip the stderr diagnostic. Idempotent: existing marker is left as-is. * Returns true if the marker was newly created, false if it already existed. */ export declare function markStandardsChecked(projectRoot: string, sessionId: string): boolean; /** * Test seam: check whether the once-per-session marker exists. Caller is * responsible for routing the result into the AC7 dedup logic. */ export declare function hasStandardsCheckedMarker(projectRoot: string, sessionId: string): boolean; export declare const platformPathSeparator: "\\" | "/";