Ctrl K
ComunidadGuías…

skills/activation-rule.mjs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// activation-rule.mjs — derives the always-on activation rule from
// skills/caveman/SKILL.md: thesis line plus each `### N.` rule headline with the
// first sentence of its body.
//
// compile.mjs writes the result to src/rules/caveman-activate.md (IDE rules via
// caveman-init.js, opencode AGENTS.md via installer/install.js) and into the
// RULE_BODY fallback of src/tools/caveman-init.js. Edit the skill or the tail
// below, never the copies; tests/installer/rule-copies.test.mjs fails on drift.

const SENTINEL = "Respond terse like smart caveman";

const TAIL = `Switch: /caveman (default), /ultracave (fragments, each fact once), /megacave (Classical Chinese 文言文)
Stop: "stop caveman" or "normal mode"

Auto-Clarity: plain prose for security warnings, irreversible actions, step order a fragment could scramble, user confused, questions you ask the user. Resume after.

Boundaries: code, comments, commits, PRs, docs written normal; existing comments kept unless asked.
Floor: code, commands, paths, numbers and error strings verbatim; never drop not/never/no/only.
`;

export function activationRule(skill) {
  const lines = skill.split(/\r?\n/);
  const heading = lines.indexOf("# caveman");
  const thesis = heading < 0 ? undefined : lines.slice(heading + 1).find((line) => line.trim() !== "");
  const rules = [];
  lines.forEach((line, i) => {
    if (!/^### \d+\. /.test(line)) return;
    const body = lines.slice(i + 1).find((l) => l.trim() !== "" && !l.startsWith("#")) || "";
    const first = body.split(/(?<=\.)\s/)[0].trim();
    rules.push(`- ${line.replace(/^### \d+\. /, "")}${first ? `: ${first}` : ""}`);
  });
  if (!thesis || !thesis.startsWith(SENTINEL)) throw new Error(`caveman SKILL.md: thesis line after "# caveman" must start with "${SENTINEL}"`);
  if (rules.length === 0) throw new Error("caveman SKILL.md: no `### N. ` rule headlines found");
  return `${thesis}\n\nRules:\n${rules.join("\n")}\n\n${TAIL}`;
}

// Replace the `const RULE_BODY = \`...\`;` template literal in caveman-init.js.
export function embedRuleBody(source, body) {
  const literal = /^const RULE_BODY = `(?:\\[\s\S]|[^`\\])*`;$/m;
  if (!literal.test(source)) throw new Error("caveman-init.js: `const RULE_BODY = `...`;` not found");
  const escaped = body.replace(/[\\`]/g, "\\$&").replace(/\$\{/g, "\\${");
  return source.replace(literal, () => `const RULE_BODY = \`${escaped}\`;`);
}