/** * opencode wrapper generation for dossier skills. * * Background: opencode (https://opencode.ai) reads `~/.claude/skills/` but its * frontmatter parser only accepts standard YAML (`---`). Dossier skills use * `---dossier` (JSON) frontmatter for signature + checksum coverage, so opencode * silently skips them. We solve this by writing a slim YAML wrapper to * `~/.config/opencode/skills//SKILL.md` — same `name`, same body, opencode-native * frontmatter. The signed source in `~/.claude/skills/` is never touched. * * This module owns: * - target resolution from the `--for` flag (claude / opencode / both) * - detecting when a source is already YAML (already loadable, no wrapper needed) * - wrapper generation (with `allowedTools` for delegating skills) * - idempotent write / remove of wrappers * * See install-skill.ts and sync-skills.ts for the two callers. */ export type SyncTarget = 'claude' | 'opencode' | 'both'; export interface ResolvedTargets { writeClaude: boolean; writeOpencode: boolean; } /** ~/.claude/skills — the primary install location, read by both Claude Code and opencode. */ export declare const CLAUDE_SKILLS_DIR: string; /** ~/.config/opencode — opencode's config root. Its existence gates auto-wrapping. */ export declare const OPENCODE_CONFIG_DIR: string; /** ~/.config/opencode/skills — where we write generated YAML wrappers. */ export declare const OPENCODE_SKILLS_DIR: string; /** True when opencode appears installed on this machine (auto-detect trigger). */ export declare function opencodeConfigExists(): boolean; /** * Resolve --for flag to concrete write targets. * * - undefined → claude + auto-detect opencode * - 'claude' → claude only (even if opencode is present) * - 'opencode' → opencode only (rare; still installs to claude for the source) * - 'both' → both, regardless of opencode-dir presence */ export declare function resolveTargets(forOpt: SyncTarget | undefined): ResolvedTargets; /** True if the raw content starts with `---dossier` (needs wrapping for opencode). */ export declare function isDossierFrontmatter(content: string): boolean; /** * Build a YAML-wrapped SKILL.md string from a dossier-frontmatter source. * * Returns null if the source is already YAML (opencode reads it fine, no wrapper needed) * or if parsing fails (best-effort, no throw). * * `skillName` is the filesystem directory name — used as a fallback when the JSON * has no `name` field (edge case: scaffold-project). */ export declare function buildOpencodeWrapper(rawContent: string, skillName: string): string | null; /** * Write an opencode wrapper for a skill. Idempotent: no-op when content matches. * * Returns: * 'created' — new file written * 'updated' — existing file overwritten with new content * 'unchanged' — file already matched, no write * 'skipped' — source is YAML-native, opencode reads it directly (no wrapper needed) */ export type WriteResult = 'created' | 'updated' | 'unchanged' | 'skipped'; export declare function writeOpencodeWrapper(skillName: string, rawContent: string): WriteResult; /** * Remove a skill's opencode wrapper if present. Best-effort: no error when missing. * Returns true if a wrapper was removed. */ export declare function removeOpencodeWrapper(skillName: string): boolean; /** * List skill names currently present in the opencode skills dir. * Used by --list to show a dual-install badge and by sync-skills to prune. */ export declare function listOpencodeSkills(): string[]; //# sourceMappingURL=opencode-sync.d.ts.map