@kody-ade/kody-engine 0.4.133 → 0.4.135

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin/kody.js +33 -22
  2. package/package.json +1 -1
package/dist/bin/kody.js CHANGED
@@ -880,7 +880,7 @@ var init_loadPriorArt = __esm({
880
880
  // package.json
881
881
  var package_default = {
882
882
  name: "@kody-ade/kody-engine",
883
- version: "0.4.133",
883
+ version: "0.4.135",
884
884
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
885
885
  license: "MIT",
886
886
  type: "module",
@@ -2035,12 +2035,12 @@ async function runChatTurn(opts) {
2035
2035
  taskType: "chat",
2036
2036
  relDir: taskArtifactsPaths.relDir
2037
2037
  });
2038
- const profileBlock = readProfileBlock(opts.cwd);
2038
+ const docsBlock = readDocsBlock(opts.cwd);
2039
2039
  const memoryBlock = readMemoryIndexBlock(opts.cwd);
2040
2040
  const instructionsBlock = readInstructionsBlock(opts.cwd);
2041
2041
  const systemPrompt = [
2042
2042
  basePrompt,
2043
- profileBlock,
2043
+ docsBlock,
2044
2044
  memoryBlock,
2045
2045
  instructionsBlock,
2046
2046
  catalog,
@@ -2158,10 +2158,10 @@ function readMemoryIndexBlock(cwd) {
2158
2158
  body
2159
2159
  ].join("\n");
2160
2160
  }
2161
- var PROFILE_DIR_REL = ".kody/profile";
2162
- var MAX_PROFILE_BYTES = 12e3;
2163
- function readProfileBlock(cwd) {
2164
- const dir = path9.join(cwd, PROFILE_DIR_REL);
2161
+ var DOCS_DIR_REL = ".kody/docs";
2162
+ var MAX_DOCS_BYTES = 12e3;
2163
+ function readDocsBlock(cwd) {
2164
+ const dir = path9.join(cwd, DOCS_DIR_REL);
2165
2165
  let files;
2166
2166
  try {
2167
2167
  files = fs9.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
@@ -2180,11 +2180,11 @@ ${content}`);
2180
2180
  }
2181
2181
  const joined = sections.join("\n\n").trim();
2182
2182
  if (!joined) return "";
2183
- const body = joined.length > MAX_PROFILE_BYTES ? joined.slice(0, MAX_PROFILE_BYTES) + "\n\n_\u2026 (company profile truncated; see `.kody/profile/` for the full text)_" : joined;
2183
+ const body = joined.length > MAX_DOCS_BYTES ? joined.slice(0, MAX_DOCS_BYTES) + "\n\n_\u2026 (documentation truncated; see `.kody/docs/` for the full text)_" : joined;
2184
2184
  return [
2185
- "# Company profile (`.kody/profile/`) \u2014 your default frame",
2185
+ "# Documentation (`.kody/docs/`) \u2014 your default frame",
2186
2186
  "",
2187
- "You are this company's in-house assistant, not a general-purpose chatbot. The text below describes who the company is, what it builds, its domain, customers, and vocabulary. This is your DEFAULT and PRIMARY frame: if a question matches or could refer to the company, its product, this repo, or its domain \u2014 even a single bare word or name, any casing or spacing \u2014 answer about THAT directly from this profile. Such a question is NOT ambiguous: do NOT lead with or also mention the generic/dictionary meaning, and do NOT ask the user 'which one did you mean?'. Just answer about the company's thing. Give a general-knowledge answer only when the question is plainly unrelated to the company, and keep it brief.",
2187
+ "You are this company's in-house assistant, not a general-purpose chatbot. The text below describes who the company is, what it builds, its domain, customers, and vocabulary. This is your DEFAULT and PRIMARY frame: if a question matches or could refer to the company, its product, this repo, or its domain \u2014 even a single bare word or name, any casing or spacing \u2014 answer about THAT directly from these docs. Such a question is NOT ambiguous: do NOT lead with or also mention the generic/dictionary meaning, and do NOT ask the user 'which one did you mean?'. Just answer about the company's thing. Give a general-knowledge answer only when the question is plainly unrelated to the company, and keep it brief.",
2188
2188
  "",
2189
2189
  body
2190
2190
  ].join("\n");
@@ -8623,27 +8623,38 @@ function readKodyVariables(cwd) {
8623
8623
  }
8624
8624
 
8625
8625
  // src/scripts/loadQaContext.ts
8626
- var PROFILE_DIR_REL_PATH = ".kody/profile";
8626
+ var DOCS_DIR_REL_PATH = ".kody/docs";
8627
+ var QA_STAFF = "qa-engineer";
8628
+ var ALL_STAFF = "*";
8629
+ var LEGACY_AUDIENCE_TO_STAFF = { chat: "kody", qa: QA_STAFF };
8627
8630
  var FRONTMATTER_RE2 = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
8628
- function readProfileAudience(raw) {
8631
+ function parseSlugList(value) {
8632
+ const inner = value.startsWith("[") && value.endsWith("]") ? value.slice(1, -1) : value;
8633
+ return inner.split(",").map((s) => s.trim().replace(/^["']|["']$/g, "").toLowerCase()).filter(Boolean);
8634
+ }
8635
+ function readProfileStaff(raw) {
8629
8636
  const m = FRONTMATTER_RE2.exec(raw);
8630
- if (!m) return { audience: ["chat"], body: raw };
8637
+ if (!m) return { staff: ["kody"], body: raw };
8631
8638
  const body = raw.slice(m[0].length);
8639
+ let staff = null;
8640
+ let legacy = null;
8632
8641
  for (const line of (m[1] ?? "").split(/\r?\n/)) {
8633
8642
  const t = line.trim();
8634
8643
  const c = t.indexOf(":");
8635
8644
  if (c < 0) continue;
8636
- if (t.slice(0, c).trim() === "audience") {
8637
- const v = t.slice(c + 1).trim();
8638
- const inner = v.startsWith("[") && v.endsWith("]") ? v.slice(1, -1) : v;
8639
- const audience = inner.split(",").map((s) => s.trim().replace(/^["']|["']$/g, "").toLowerCase()).filter(Boolean);
8640
- return { audience: audience.length > 0 ? audience : ["chat"], body };
8645
+ const key = t.slice(0, c).trim();
8646
+ const value = t.slice(c + 1).trim();
8647
+ if (key === "staff") {
8648
+ staff = parseSlugList(value);
8649
+ } else if (key === "audience" || key === "for") {
8650
+ const mapped = parseSlugList(value).map((tok) => LEGACY_AUDIENCE_TO_STAFF[tok]).filter(Boolean);
8651
+ if (mapped.length > 0) legacy = mapped;
8641
8652
  }
8642
8653
  }
8643
- return { audience: ["chat"], body };
8654
+ return { staff: staff ?? legacy ?? ["kody"], body };
8644
8655
  }
8645
8656
  function readProfile(cwd) {
8646
- const dir = path33.join(cwd, PROFILE_DIR_REL_PATH);
8657
+ const dir = path33.join(cwd, DOCS_DIR_REL_PATH);
8647
8658
  if (!fs34.existsSync(dir)) return "";
8648
8659
  let entries;
8649
8660
  try {
@@ -8655,8 +8666,8 @@ function readProfile(cwd) {
8655
8666
  for (const file of entries) {
8656
8667
  try {
8657
8668
  const raw = fs34.readFileSync(path33.join(dir, file), "utf-8");
8658
- const { audience, body } = readProfileAudience(raw);
8659
- if (!audience.includes("qa")) continue;
8669
+ const { staff, body } = readProfileStaff(raw);
8670
+ if (!staff.includes(QA_STAFF) && !staff.includes(ALL_STAFF)) continue;
8660
8671
  blocks.push(`## ${file}
8661
8672
 
8662
8673
  ${body.trim()}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.133",
3
+ "version": "0.4.135",
4
4
  "description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
5
5
  "license": "MIT",
6
6
  "type": "module",