@kody-ade/kody-engine 0.4.521 → 0.4.523

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 +178 -39
  2. package/package.json +1 -1
package/dist/bin/kody.js CHANGED
@@ -15,7 +15,7 @@ var init_package = __esm({
15
15
  "package.json"() {
16
16
  package_default = {
17
17
  name: "@kody-ade/kody-engine",
18
- version: "0.4.521",
18
+ version: "0.4.523",
19
19
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
20
20
  license: "MIT",
21
21
  type: "module",
@@ -13760,9 +13760,7 @@ function dueSlot(loop, now) {
13760
13760
  return `${year}-${month}-${day}T${loop.trigger.at.time}[${loop.trigger.at.timezone}]`;
13761
13761
  }
13762
13762
  function loopJob(loop) {
13763
- const cliArgs = Object.fromEntries(
13764
- Object.entries(loop.input).map(([key, value]) => [key, typeof value === "string" ? value : JSON.stringify(value)])
13765
- );
13763
+ const cliArgs = { ...loop.input };
13766
13764
  return loop.target.kind === "workflow" ? { workflow: loop.target.id, cliArgs, flavor: "scheduled" } : { capability: loop.target.id, cliArgs, flavor: "scheduled" };
13767
13765
  }
13768
13766
  function repositoryTenant(config) {
@@ -17884,27 +17882,171 @@ var init_promoteQaGoal = __esm({
17884
17882
 
17885
17883
  // src/scripts/publishReport.ts
17886
17884
  function buildRuntimeReportMarkdown(input) {
17887
- return [
17888
- "---",
17889
- `generatedAt: ${yamlString(input.generatedAt)}`,
17890
- `reportType: ${input.reportType}`,
17891
- `reportTypeVersion: ${input.reportTypeVersion}`,
17892
- "producer:",
17893
- ` model: ${input.owner}`,
17894
- ` capability: ${input.capability}`,
17895
- ...input.reviewStatus ? [`reviewStatus: ${input.reviewStatus}`] : [],
17896
- ...input.reviewArea ? [`reviewArea: ${input.reviewArea}`] : [],
17897
- "---",
17885
+ const lines = [
17898
17886
  `# ${input.title}`,
17899
17887
  "",
17900
17888
  input.summary,
17901
17889
  "",
17902
- "## Report data",
17903
- "```json",
17904
- JSON.stringify(input.data, null, 2),
17905
- "```",
17906
- ""
17907
- ].join("\n");
17890
+ "## About",
17891
+ markdownField("Type", input.reportType),
17892
+ markdownField("Version", input.reportTypeVersion),
17893
+ markdownField("Generated", input.generatedAt),
17894
+ markdownField("Owner", input.owner),
17895
+ markdownField("Capability", input.capability),
17896
+ ...input.reviewStatus ? [markdownField("Review status", input.reviewStatus)] : [],
17897
+ ...input.reviewArea ? [markdownField("Review area", input.reviewArea)] : [],
17898
+ "",
17899
+ ...renderReportData(input.data)
17900
+ ];
17901
+ return `${lines.join("\n").trimEnd()}
17902
+ `;
17903
+ }
17904
+ function renderReportData(data) {
17905
+ const lines = [];
17906
+ const workflow = recordField4(data.workflow);
17907
+ const finding = recordField4(data.finding);
17908
+ const observation = recordField4(data.observation);
17909
+ const learning = recordField4(data.learning);
17910
+ if (workflow) lines.push(...renderWorkflow(workflow));
17911
+ if (finding) lines.push(...renderFinding(finding));
17912
+ if (observation) lines.push(...renderObservation(observation));
17913
+ if (learning) lines.push(...renderLearning(learning));
17914
+ const rest = omitKeys(data, ["workflow", "finding", "observation", "learning"]);
17915
+ if (Object.keys(rest).length > 0) {
17916
+ lines.push("## Results", ...renderObjectFields(rest, 3), "");
17917
+ }
17918
+ return lines;
17919
+ }
17920
+ function renderWorkflow(workflow) {
17921
+ const lines = ["## Run"];
17922
+ pushField(lines, "Status", workflow.status);
17923
+ pushField(lines, "Blocker", workflow.blocker);
17924
+ const completed = stringArray3(workflow.completedStepIds);
17925
+ if (completed.length > 0) {
17926
+ lines.push("", "## Completed checks", ...completed.map((step) => `- ${humanize(step)}`));
17927
+ }
17928
+ const facts = recordField4(workflow.facts) ?? {};
17929
+ const finding = recordField4(facts.finding);
17930
+ const observation = recordField4(facts.observation);
17931
+ if (finding) lines.push("", ...renderFinding(finding));
17932
+ if (observation) lines.push("", ...renderObservation(observation));
17933
+ const remainingFacts = omitKeys(facts, ["finding", "observation"]);
17934
+ if (Object.keys(remainingFacts).length > 0) {
17935
+ lines.push("", "## Results", ...renderObjectFields(remainingFacts, 3));
17936
+ }
17937
+ const artifacts = Array.isArray(workflow.artifacts) ? workflow.artifacts : [];
17938
+ const evidence = renderEvidence(artifacts);
17939
+ if (evidence.length > 0) lines.push("", "## Evidence", ...evidence);
17940
+ lines.push("");
17941
+ return lines;
17942
+ }
17943
+ function renderFinding(finding) {
17944
+ const lines = ["## Finding"];
17945
+ for (const [label, key] of [
17946
+ ["ID", "id"],
17947
+ ["Status", "status"],
17948
+ ["Severity", "severity"],
17949
+ ["Observer", "observerId"],
17950
+ ["Subject", "subject"],
17951
+ ["Expected", "expectation"],
17952
+ ["Actual", "actual"],
17953
+ ["Observation ID", "observationId"],
17954
+ ["Observed", "observedAt"],
17955
+ ["Operator activity", "operatorActivityAt"]
17956
+ ]) {
17957
+ pushField(lines, label, finding[key]);
17958
+ }
17959
+ lines.push("");
17960
+ return lines;
17961
+ }
17962
+ function renderObservation(observation) {
17963
+ const lines = ["## Observation"];
17964
+ for (const [label, key] of [
17965
+ ["ID", "id"],
17966
+ ["Status", "status"],
17967
+ ["Summary", "summary"],
17968
+ ["Observer", "observerId"],
17969
+ ["Capability", "capability"],
17970
+ ["Subject", "subject"],
17971
+ ["Observed", "observedAt"]
17972
+ ]) {
17973
+ pushField(lines, label, observation[key]);
17974
+ }
17975
+ const evidence = renderEvidence(Array.isArray(observation.evidence) ? observation.evidence : []);
17976
+ if (evidence.length > 0) lines.push("", "### Evidence", ...evidence);
17977
+ lines.push("");
17978
+ return lines;
17979
+ }
17980
+ function renderLearning(learning) {
17981
+ const lines = ["## Learning"];
17982
+ for (const [label, key] of [
17983
+ ["ID", "id"],
17984
+ ["Finding ID", "findingId"],
17985
+ ["Summary", "summary"],
17986
+ ["Change", "change"],
17987
+ ["Evidence", "evidence"]
17988
+ ]) {
17989
+ pushField(lines, label, learning[key]);
17990
+ }
17991
+ lines.push("");
17992
+ return lines;
17993
+ }
17994
+ function renderObjectFields(value, headingLevel) {
17995
+ const lines = [];
17996
+ for (const [key, item] of Object.entries(value)) {
17997
+ const label = humanize(key);
17998
+ if (isScalar(item)) {
17999
+ lines.push(markdownField(label, item));
18000
+ continue;
18001
+ }
18002
+ if (Array.isArray(item)) {
18003
+ if (item.length === 0) continue;
18004
+ lines.push(`${"#".repeat(Math.min(headingLevel, 6))} ${label}`);
18005
+ for (const entry of item) {
18006
+ if (isScalar(entry)) lines.push(`- ${markdownValue(entry)}`);
18007
+ else if (recordField4(entry)) lines.push(...renderObjectFields(recordField4(entry), headingLevel + 1));
18008
+ }
18009
+ continue;
18010
+ }
18011
+ const record2 = recordField4(item);
18012
+ if (!record2 || Object.keys(record2).length === 0) continue;
18013
+ lines.push(`${"#".repeat(Math.min(headingLevel, 6))} ${label}`, ...renderObjectFields(record2, headingLevel + 1));
18014
+ }
18015
+ return lines;
18016
+ }
18017
+ function renderEvidence(items) {
18018
+ return items.flatMap((item) => {
18019
+ const record2 = recordField4(item);
18020
+ if (!record2) return [];
18021
+ const label = stringValue5(record2.label) ?? stringValue5(record2.kind) ?? "Evidence";
18022
+ const url = stringValue5(record2.url);
18023
+ const status = stringValue5(record2.status);
18024
+ const suffix = status ? ` \u2014 ${humanize(status)}` : "";
18025
+ return [`- ${url ? `[${label}](${url})` : label}${suffix}`];
18026
+ });
18027
+ }
18028
+ function omitKeys(value, keys) {
18029
+ const omitted = new Set(keys);
18030
+ return Object.fromEntries(Object.entries(value).filter(([key]) => !omitted.has(key)));
18031
+ }
18032
+ function stringArray3(value) {
18033
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
18034
+ }
18035
+ function isScalar(value) {
18036
+ return value === null || value === void 0 || ["string", "number", "boolean"].includes(typeof value);
18037
+ }
18038
+ function pushField(lines, label, value) {
18039
+ if (isScalar(value) && value !== void 0 && value !== null && value !== "") {
18040
+ lines.push(markdownField(label, value));
18041
+ }
18042
+ }
18043
+ function markdownField(label, value) {
18044
+ return `- **${label}:** ${markdownValue(value)}`;
18045
+ }
18046
+ function markdownValue(value) {
18047
+ if (value === null || value === void 0) return "None";
18048
+ if (typeof value === "boolean") return value ? "Yes" : "No";
18049
+ return String(value).replace(/\r?\n/g, " ").trim();
17908
18050
  }
17909
18051
  async function publishWorkflowReport(input) {
17910
18052
  const slug = input.publication.slug;
@@ -17986,10 +18128,7 @@ function stringValue5(value) {
17986
18128
  return typeof value === "string" && value.trim() ? value.trim() : null;
17987
18129
  }
17988
18130
  function humanize(value) {
17989
- return value.split(/[-_]+/).filter(Boolean).map((part) => part[0].toUpperCase() + part.slice(1)).join(" ");
17990
- }
17991
- function yamlString(value) {
17992
- return JSON.stringify(value);
18131
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[-_]+/).filter(Boolean).map((part) => part[0].toUpperCase() + part.slice(1)).join(" ");
17993
18132
  }
17994
18133
  var SAFE_SLUG, publishReport;
17995
18134
  var init_publishReport = __esm({
@@ -19705,7 +19844,7 @@ function validateOneModel(rawModel, files, label, strictSingleModel, failures, e
19705
19844
  const slug = stringField5(model.slug);
19706
19845
  if (!isSlug(slug)) failures.push(`${label}.slug must be a lowercase slug`);
19707
19846
  if (isModelKind(kind)) {
19708
- const docsUsed = stringArray3(model.docsUsed);
19847
+ const docsUsed = stringArray4(model.docsUsed);
19709
19848
  for (const doc of REQUIRED_DOCS[kind]) {
19710
19849
  if (!docsUsed.includes(doc)) failures.push(`${label} docsUsed missing ${doc}`);
19711
19850
  }
@@ -19803,12 +19942,12 @@ function validateModelShape(kind, model, files, slug, failures) {
19803
19942
  if (!isFiniteNumber(intent?.priority)) failures.push("intent file must declare numeric priority");
19804
19943
  if (!hasScope(model.scope)) failures.push("intent model scope must include a repo or area");
19805
19944
  if (!hasScope(intent?.scope)) failures.push("intent file scope must include a repo or area");
19806
- if (stringArray3(model.principles).length === 0) failures.push("intent model principles must be non-empty");
19807
- if (stringArray3(intent?.principles).length === 0) failures.push("intent file principles must be non-empty");
19808
- if (stringArray3(model.successMeasures).length === 0) {
19945
+ if (stringArray4(model.principles).length === 0) failures.push("intent model principles must be non-empty");
19946
+ if (stringArray4(intent?.principles).length === 0) failures.push("intent file principles must be non-empty");
19947
+ if (stringArray4(model.successMeasures).length === 0) {
19809
19948
  failures.push("intent model successMeasures must be non-empty");
19810
19949
  }
19811
- if (stringArray3(intent?.metrics).length === 0) failures.push("intent file metrics must be non-empty");
19950
+ if (stringArray4(intent?.metrics).length === 0) failures.push("intent file metrics must be non-empty");
19812
19951
  if (!recordField5(model.policy)) failures.push("intent model must declare policy");
19813
19952
  if (!recordField5(intent?.policy)) failures.push("intent file must declare policy");
19814
19953
  if (stringField5(model.status) !== "paused" || stringField5(intent?.status) !== "paused") {
@@ -19823,10 +19962,10 @@ function validateModelShape(kind, model, files, slug, failures) {
19823
19962
  const operation = parseJsonFile(files, `operations/${slug}/operation.json`, failures);
19824
19963
  if (!stringField5(model.responsibility)) failures.push("operation model must declare responsibility");
19825
19964
  if (!stringField5(operation?.responsibility)) failures.push("operation file must declare responsibility");
19826
- if (stringArray3(model.intentIds).length === 0) failures.push("operation model intentIds must be non-empty");
19827
- if (stringArray3(operation?.intentIds).length === 0) failures.push("operation file intentIds must be non-empty");
19828
- if (stringArray3(model.doesNotOwn).length === 0) failures.push("operation model doesNotOwn must be non-empty");
19829
- if (stringArray3(operation?.doesNotOwn).length === 0) failures.push("operation file doesNotOwn must be non-empty");
19965
+ if (stringArray4(model.intentIds).length === 0) failures.push("operation model intentIds must be non-empty");
19966
+ if (stringArray4(operation?.intentIds).length === 0) failures.push("operation file intentIds must be non-empty");
19967
+ if (stringArray4(model.doesNotOwn).length === 0) failures.push("operation model doesNotOwn must be non-empty");
19968
+ if (stringArray4(operation?.doesNotOwn).length === 0) failures.push("operation file doesNotOwn must be non-empty");
19830
19969
  if (stringField5(model.status) !== "proposed" || stringField5(operation?.status) !== "proposed") {
19831
19970
  failures.push("operation proposal status must be proposed");
19832
19971
  }
@@ -19835,7 +19974,7 @@ function validateModelShape(kind, model, files, slug, failures) {
19835
19974
  }
19836
19975
  if (kind === "agent") {
19837
19976
  const agentFile = textFile(files, `agents/${slug}.md`);
19838
- if (!stringArray3(model.owns).includes("identity") && !containsWord(agentFile, "identity")) {
19977
+ if (!stringArray4(model.owns).includes("identity") && !containsWord(agentFile, "identity")) {
19839
19978
  failures.push("agent owns must include identity");
19840
19979
  }
19841
19980
  requireStringArrayIncludes(model.doesNotOwn, "tasks", "agent doesNotOwn", failures);
@@ -19878,7 +20017,7 @@ function validateModelShape(kind, model, files, slug, failures) {
19878
20017
  }
19879
20018
  }
19880
20019
  function capabilityRefs(value) {
19881
- return [...stringArray3(value?.capabilities), ...stringArray3(value?.allowedCapabilities)];
20020
+ return [...stringArray4(value?.capabilities), ...stringArray4(value?.allowedCapabilities)];
19882
20021
  }
19883
20022
  function evidenceRefs(value) {
19884
20023
  if (!value) return [];
@@ -19950,7 +20089,7 @@ function normalizeBundlePath(filePath) {
19950
20089
  function stringField5(value) {
19951
20090
  return typeof value === "string" ? value.trim() : "";
19952
20091
  }
19953
- function stringArray3(value) {
20092
+ function stringArray4(value) {
19954
20093
  if (!Array.isArray(value)) return [];
19955
20094
  return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
19956
20095
  }
@@ -19962,10 +20101,10 @@ function isFiniteNumber(value) {
19962
20101
  }
19963
20102
  function hasScope(value) {
19964
20103
  const scope = recordField5(value);
19965
- return stringArray3(scope?.repos).length > 0 || stringArray3(scope?.areas).length > 0;
20104
+ return stringArray4(scope?.repos).length > 0 || stringArray4(scope?.areas).length > 0;
19966
20105
  }
19967
20106
  function requireStringArrayIncludes(value, expected, label, failures) {
19968
- if (!stringArray3(value).includes(expected)) failures.push(`${label} must include ${expected}`);
20107
+ if (!stringArray4(value).includes(expected)) failures.push(`${label} must include ${expected}`);
19969
20108
  }
19970
20109
  function isSlug(value) {
19971
20110
  return /^[a-z][a-z0-9-]{0,63}$/.test(value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.521",
3
+ "version": "0.4.523",
4
4
  "description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
5
5
  "license": "MIT",
6
6
  "type": "module",