/** * Argument substitutions for skill bodies. * * Per `knowledge/doc/skills.md` §2.1, a skill body can reference: * * - `$ARGUMENTS` — the full argument string as typed. * - `$ARGUMENTS[N]` — the Nth shell-parsed argument (0-indexed). * - `$N` — shorthand for `$ARGUMENTS[N]`. * - `$` — named argument matched against `arguments:` frontmatter * (positional mapping — the first name maps to argv[0], etc.). * - `${CLAUDE_SESSION_ID}` / `${QODO_SESSION_ID}` — current session ID. * - `${CLAUDE_SKILL_DIR}` / `${QODO_SKILL_DIR}` — canonical absolute path * of the skill directory. * - `${CLAUDE_EFFORT}` / `${QODO_EFFORT}` — active effort level. * * Out-of-bounds indexed references stay literal; the engine emits a * `sdk.skill.substitution_warn` event the caller can wire to telemetry. * * The substitution is intentionally **shape-preserving** for unknown * references — a body with `${LITERAL_DOLLAR_AMOUNT}` (no resolver match) * is passed through verbatim. Authors who want a literal `$ARGUMENTS` * unsubstituted can escape with a non-matching prefix. * * Compatibility: both `CLAUDE_*` and `QODO_*` prefixes resolve to the same * value so OSS skills authored for Anthropic Claude Code render correctly. */ import type { SkillArgument } from './types.js'; /** * Context passed to {@link substitute}. Every field is optional; missing * fields cause the matching reference to remain literal (and emit a * warning). */ export interface SubstitutionContext { /** Skill FQN used for telemetry attribution. */ readonly skill: string; /** The full argument string as typed by the caller. */ readonly argumentsText?: string; /** Shell-parsed argv. Index `0` corresponds to the first argument. */ readonly argv?: readonly string[]; /** Named-argument descriptors from frontmatter. Position-mapped onto argv. */ readonly named?: readonly SkillArgument[]; /** Session identifier resolved by the consumer; powers ${CLAUDE_SESSION_ID}. */ readonly sessionId?: string; /** Canonical absolute path of the skill directory; powers ${CLAUDE_SKILL_DIR}. */ readonly skillDir?: string; /** Effort string (`low|medium|high|max`); powers ${CLAUDE_EFFORT}. */ readonly effort?: string; } /** Warning produced during substitution — caller forwards to telemetry. */ export interface SubstitutionWarning { readonly reference: string; readonly reason: 'out_of_bounds' | 'unknown_named' | 'malformed'; } export interface SubstitutionResult { readonly text: string; readonly warnings: readonly SubstitutionWarning[]; /** * `true` iff `$ARGUMENTS` (or any of its forms) appeared in the body and * was consumed. Callers use this to decide whether to append * `\nARGUMENTS: \n` when an argument string was supplied but no * reference consumed it — matches Claude Code's append-on-absence behavior. */ readonly referencedArguments: boolean; } /** * Apply substitutions to a skill body. Pure function — IO-free, returns * the rendered text plus any warnings. The caller appends the * `ARGUMENTS:` trailer when: * * - the caller supplied a non-empty `argumentsText` AND * - the body did not consume `$ARGUMENTS` / `$N` / `$` in any form. */ export declare function substitute(body: string, ctx: SubstitutionContext): SubstitutionResult; /** * Helper composing `substitute` + the Claude-Code-compatible * append-on-absence behavior. If the caller passed an argument string but * the body never referenced it, append `\nARGUMENTS: \n` to the body. */ export declare function substituteWithArgumentsTrailer(body: string, ctx: SubstitutionContext): SubstitutionResult; /** * Parse a shell-quoted argument string into `argv`. Supports double-quoted * substrings, single-quoted substrings, and backslash escaping inside * double quotes. Intentionally minimal — skill arguments are typed by the * model and not a shell. */ export declare function parseArgv(s: string): string[]; //# sourceMappingURL=substitute.d.ts.map