@kody-ade/kody-engine 0.4.520 → 0.4.522
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.
- package/dist/bin/kody.js +182 -38
- 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.
|
|
18
|
+
version: "0.4.522",
|
|
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",
|
|
@@ -4638,7 +4638,8 @@ function normalizeWorkflowDefinition(value) {
|
|
|
4638
4638
|
}
|
|
4639
4639
|
const workflow = parseCapabilityWorkflow({
|
|
4640
4640
|
steps: raw.steps,
|
|
4641
|
-
startAt: raw.startAt
|
|
4641
|
+
startAt: raw.startAt,
|
|
4642
|
+
report: raw.report
|
|
4642
4643
|
});
|
|
4643
4644
|
const steps = workflow?.steps;
|
|
4644
4645
|
const capabilities = steps ? steps.map((step) => step.capability) : normalizeWorkflowCapabilities(raw.capabilities);
|
|
@@ -4650,6 +4651,7 @@ function normalizeWorkflowDefinition(value) {
|
|
|
4650
4651
|
...raw.runWithoutApproval === true ? { runWithoutApproval: true } : {},
|
|
4651
4652
|
...steps ? { steps } : {},
|
|
4652
4653
|
...workflow?.startAt ? { startAt: workflow.startAt } : {},
|
|
4654
|
+
...workflow?.report ? { report: workflow.report } : {},
|
|
4653
4655
|
...typeof raw.createdAt === "string" ? { createdAt: raw.createdAt } : {},
|
|
4654
4656
|
...typeof raw.updatedAt === "string" ? { updatedAt: raw.updatedAt } : {}
|
|
4655
4657
|
};
|
|
@@ -4702,7 +4704,8 @@ function normalizeWorkflowCapabilities(value) {
|
|
|
4702
4704
|
function workflowDefinitionToConfig(workflow) {
|
|
4703
4705
|
return {
|
|
4704
4706
|
steps: workflow.steps ?? workflow.capabilities.map((capability) => ({ capability })),
|
|
4705
|
-
...workflow.startAt ? { startAt: workflow.startAt } : {}
|
|
4707
|
+
...workflow.startAt ? { startAt: workflow.startAt } : {},
|
|
4708
|
+
...workflow.report ? { report: workflow.report } : {}
|
|
4706
4709
|
};
|
|
4707
4710
|
}
|
|
4708
4711
|
function parseWorkflowDefinition(content) {
|
|
@@ -17881,27 +17884,171 @@ var init_promoteQaGoal = __esm({
|
|
|
17881
17884
|
|
|
17882
17885
|
// src/scripts/publishReport.ts
|
|
17883
17886
|
function buildRuntimeReportMarkdown(input) {
|
|
17884
|
-
|
|
17885
|
-
"---",
|
|
17886
|
-
`generatedAt: ${yamlString(input.generatedAt)}`,
|
|
17887
|
-
`reportType: ${input.reportType}`,
|
|
17888
|
-
`reportTypeVersion: ${input.reportTypeVersion}`,
|
|
17889
|
-
"producer:",
|
|
17890
|
-
` model: ${input.owner}`,
|
|
17891
|
-
` capability: ${input.capability}`,
|
|
17892
|
-
...input.reviewStatus ? [`reviewStatus: ${input.reviewStatus}`] : [],
|
|
17893
|
-
...input.reviewArea ? [`reviewArea: ${input.reviewArea}`] : [],
|
|
17894
|
-
"---",
|
|
17887
|
+
const lines = [
|
|
17895
17888
|
`# ${input.title}`,
|
|
17896
17889
|
"",
|
|
17897
17890
|
input.summary,
|
|
17898
17891
|
"",
|
|
17899
|
-
"##
|
|
17900
|
-
"
|
|
17901
|
-
|
|
17902
|
-
"
|
|
17903
|
-
""
|
|
17904
|
-
|
|
17892
|
+
"## About",
|
|
17893
|
+
markdownField("Type", input.reportType),
|
|
17894
|
+
markdownField("Version", input.reportTypeVersion),
|
|
17895
|
+
markdownField("Generated", input.generatedAt),
|
|
17896
|
+
markdownField("Owner", input.owner),
|
|
17897
|
+
markdownField("Capability", input.capability),
|
|
17898
|
+
...input.reviewStatus ? [markdownField("Review status", input.reviewStatus)] : [],
|
|
17899
|
+
...input.reviewArea ? [markdownField("Review area", input.reviewArea)] : [],
|
|
17900
|
+
"",
|
|
17901
|
+
...renderReportData(input.data)
|
|
17902
|
+
];
|
|
17903
|
+
return `${lines.join("\n").trimEnd()}
|
|
17904
|
+
`;
|
|
17905
|
+
}
|
|
17906
|
+
function renderReportData(data) {
|
|
17907
|
+
const lines = [];
|
|
17908
|
+
const workflow = recordField4(data.workflow);
|
|
17909
|
+
const finding = recordField4(data.finding);
|
|
17910
|
+
const observation = recordField4(data.observation);
|
|
17911
|
+
const learning = recordField4(data.learning);
|
|
17912
|
+
if (workflow) lines.push(...renderWorkflow(workflow));
|
|
17913
|
+
if (finding) lines.push(...renderFinding(finding));
|
|
17914
|
+
if (observation) lines.push(...renderObservation(observation));
|
|
17915
|
+
if (learning) lines.push(...renderLearning(learning));
|
|
17916
|
+
const rest = omitKeys(data, ["workflow", "finding", "observation", "learning"]);
|
|
17917
|
+
if (Object.keys(rest).length > 0) {
|
|
17918
|
+
lines.push("## Results", ...renderObjectFields(rest, 3), "");
|
|
17919
|
+
}
|
|
17920
|
+
return lines;
|
|
17921
|
+
}
|
|
17922
|
+
function renderWorkflow(workflow) {
|
|
17923
|
+
const lines = ["## Run"];
|
|
17924
|
+
pushField(lines, "Status", workflow.status);
|
|
17925
|
+
pushField(lines, "Blocker", workflow.blocker);
|
|
17926
|
+
const completed = stringArray3(workflow.completedStepIds);
|
|
17927
|
+
if (completed.length > 0) {
|
|
17928
|
+
lines.push("", "## Completed checks", ...completed.map((step) => `- ${humanize(step)}`));
|
|
17929
|
+
}
|
|
17930
|
+
const facts = recordField4(workflow.facts) ?? {};
|
|
17931
|
+
const finding = recordField4(facts.finding);
|
|
17932
|
+
const observation = recordField4(facts.observation);
|
|
17933
|
+
if (finding) lines.push("", ...renderFinding(finding));
|
|
17934
|
+
if (observation) lines.push("", ...renderObservation(observation));
|
|
17935
|
+
const remainingFacts = omitKeys(facts, ["finding", "observation"]);
|
|
17936
|
+
if (Object.keys(remainingFacts).length > 0) {
|
|
17937
|
+
lines.push("", "## Results", ...renderObjectFields(remainingFacts, 3));
|
|
17938
|
+
}
|
|
17939
|
+
const artifacts = Array.isArray(workflow.artifacts) ? workflow.artifacts : [];
|
|
17940
|
+
const evidence = renderEvidence(artifacts);
|
|
17941
|
+
if (evidence.length > 0) lines.push("", "## Evidence", ...evidence);
|
|
17942
|
+
lines.push("");
|
|
17943
|
+
return lines;
|
|
17944
|
+
}
|
|
17945
|
+
function renderFinding(finding) {
|
|
17946
|
+
const lines = ["## Finding"];
|
|
17947
|
+
for (const [label, key] of [
|
|
17948
|
+
["ID", "id"],
|
|
17949
|
+
["Status", "status"],
|
|
17950
|
+
["Severity", "severity"],
|
|
17951
|
+
["Observer", "observerId"],
|
|
17952
|
+
["Subject", "subject"],
|
|
17953
|
+
["Expected", "expectation"],
|
|
17954
|
+
["Actual", "actual"],
|
|
17955
|
+
["Observation ID", "observationId"],
|
|
17956
|
+
["Observed", "observedAt"],
|
|
17957
|
+
["Operator activity", "operatorActivityAt"]
|
|
17958
|
+
]) {
|
|
17959
|
+
pushField(lines, label, finding[key]);
|
|
17960
|
+
}
|
|
17961
|
+
lines.push("");
|
|
17962
|
+
return lines;
|
|
17963
|
+
}
|
|
17964
|
+
function renderObservation(observation) {
|
|
17965
|
+
const lines = ["## Observation"];
|
|
17966
|
+
for (const [label, key] of [
|
|
17967
|
+
["ID", "id"],
|
|
17968
|
+
["Status", "status"],
|
|
17969
|
+
["Summary", "summary"],
|
|
17970
|
+
["Observer", "observerId"],
|
|
17971
|
+
["Capability", "capability"],
|
|
17972
|
+
["Subject", "subject"],
|
|
17973
|
+
["Observed", "observedAt"]
|
|
17974
|
+
]) {
|
|
17975
|
+
pushField(lines, label, observation[key]);
|
|
17976
|
+
}
|
|
17977
|
+
const evidence = renderEvidence(Array.isArray(observation.evidence) ? observation.evidence : []);
|
|
17978
|
+
if (evidence.length > 0) lines.push("", "### Evidence", ...evidence);
|
|
17979
|
+
lines.push("");
|
|
17980
|
+
return lines;
|
|
17981
|
+
}
|
|
17982
|
+
function renderLearning(learning) {
|
|
17983
|
+
const lines = ["## Learning"];
|
|
17984
|
+
for (const [label, key] of [
|
|
17985
|
+
["ID", "id"],
|
|
17986
|
+
["Finding ID", "findingId"],
|
|
17987
|
+
["Summary", "summary"],
|
|
17988
|
+
["Change", "change"],
|
|
17989
|
+
["Evidence", "evidence"]
|
|
17990
|
+
]) {
|
|
17991
|
+
pushField(lines, label, learning[key]);
|
|
17992
|
+
}
|
|
17993
|
+
lines.push("");
|
|
17994
|
+
return lines;
|
|
17995
|
+
}
|
|
17996
|
+
function renderObjectFields(value, headingLevel) {
|
|
17997
|
+
const lines = [];
|
|
17998
|
+
for (const [key, item] of Object.entries(value)) {
|
|
17999
|
+
const label = humanize(key);
|
|
18000
|
+
if (isScalar(item)) {
|
|
18001
|
+
lines.push(markdownField(label, item));
|
|
18002
|
+
continue;
|
|
18003
|
+
}
|
|
18004
|
+
if (Array.isArray(item)) {
|
|
18005
|
+
if (item.length === 0) continue;
|
|
18006
|
+
lines.push(`${"#".repeat(Math.min(headingLevel, 6))} ${label}`);
|
|
18007
|
+
for (const entry of item) {
|
|
18008
|
+
if (isScalar(entry)) lines.push(`- ${markdownValue(entry)}`);
|
|
18009
|
+
else if (recordField4(entry)) lines.push(...renderObjectFields(recordField4(entry), headingLevel + 1));
|
|
18010
|
+
}
|
|
18011
|
+
continue;
|
|
18012
|
+
}
|
|
18013
|
+
const record2 = recordField4(item);
|
|
18014
|
+
if (!record2 || Object.keys(record2).length === 0) continue;
|
|
18015
|
+
lines.push(`${"#".repeat(Math.min(headingLevel, 6))} ${label}`, ...renderObjectFields(record2, headingLevel + 1));
|
|
18016
|
+
}
|
|
18017
|
+
return lines;
|
|
18018
|
+
}
|
|
18019
|
+
function renderEvidence(items) {
|
|
18020
|
+
return items.flatMap((item) => {
|
|
18021
|
+
const record2 = recordField4(item);
|
|
18022
|
+
if (!record2) return [];
|
|
18023
|
+
const label = stringValue5(record2.label) ?? stringValue5(record2.kind) ?? "Evidence";
|
|
18024
|
+
const url = stringValue5(record2.url);
|
|
18025
|
+
const status = stringValue5(record2.status);
|
|
18026
|
+
const suffix = status ? ` \u2014 ${humanize(status)}` : "";
|
|
18027
|
+
return [`- ${url ? `[${label}](${url})` : label}${suffix}`];
|
|
18028
|
+
});
|
|
18029
|
+
}
|
|
18030
|
+
function omitKeys(value, keys) {
|
|
18031
|
+
const omitted = new Set(keys);
|
|
18032
|
+
return Object.fromEntries(Object.entries(value).filter(([key]) => !omitted.has(key)));
|
|
18033
|
+
}
|
|
18034
|
+
function stringArray3(value) {
|
|
18035
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
18036
|
+
}
|
|
18037
|
+
function isScalar(value) {
|
|
18038
|
+
return value === null || value === void 0 || ["string", "number", "boolean"].includes(typeof value);
|
|
18039
|
+
}
|
|
18040
|
+
function pushField(lines, label, value) {
|
|
18041
|
+
if (isScalar(value) && value !== void 0 && value !== null && value !== "") {
|
|
18042
|
+
lines.push(markdownField(label, value));
|
|
18043
|
+
}
|
|
18044
|
+
}
|
|
18045
|
+
function markdownField(label, value) {
|
|
18046
|
+
return `- **${label}:** ${markdownValue(value)}`;
|
|
18047
|
+
}
|
|
18048
|
+
function markdownValue(value) {
|
|
18049
|
+
if (value === null || value === void 0) return "None";
|
|
18050
|
+
if (typeof value === "boolean") return value ? "Yes" : "No";
|
|
18051
|
+
return String(value).replace(/\r?\n/g, " ").trim();
|
|
17905
18052
|
}
|
|
17906
18053
|
async function publishWorkflowReport(input) {
|
|
17907
18054
|
const slug = input.publication.slug;
|
|
@@ -17983,10 +18130,7 @@ function stringValue5(value) {
|
|
|
17983
18130
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
17984
18131
|
}
|
|
17985
18132
|
function humanize(value) {
|
|
17986
|
-
return value.split(/[-_]+/).filter(Boolean).map((part) => part[0].toUpperCase() + part.slice(1)).join(" ");
|
|
17987
|
-
}
|
|
17988
|
-
function yamlString(value) {
|
|
17989
|
-
return JSON.stringify(value);
|
|
18133
|
+
return value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[-_]+/).filter(Boolean).map((part) => part[0].toUpperCase() + part.slice(1)).join(" ");
|
|
17990
18134
|
}
|
|
17991
18135
|
var SAFE_SLUG, publishReport;
|
|
17992
18136
|
var init_publishReport = __esm({
|
|
@@ -19702,7 +19846,7 @@ function validateOneModel(rawModel, files, label, strictSingleModel, failures, e
|
|
|
19702
19846
|
const slug = stringField5(model.slug);
|
|
19703
19847
|
if (!isSlug(slug)) failures.push(`${label}.slug must be a lowercase slug`);
|
|
19704
19848
|
if (isModelKind(kind)) {
|
|
19705
|
-
const docsUsed =
|
|
19849
|
+
const docsUsed = stringArray4(model.docsUsed);
|
|
19706
19850
|
for (const doc of REQUIRED_DOCS[kind]) {
|
|
19707
19851
|
if (!docsUsed.includes(doc)) failures.push(`${label} docsUsed missing ${doc}`);
|
|
19708
19852
|
}
|
|
@@ -19800,12 +19944,12 @@ function validateModelShape(kind, model, files, slug, failures) {
|
|
|
19800
19944
|
if (!isFiniteNumber(intent?.priority)) failures.push("intent file must declare numeric priority");
|
|
19801
19945
|
if (!hasScope(model.scope)) failures.push("intent model scope must include a repo or area");
|
|
19802
19946
|
if (!hasScope(intent?.scope)) failures.push("intent file scope must include a repo or area");
|
|
19803
|
-
if (
|
|
19804
|
-
if (
|
|
19805
|
-
if (
|
|
19947
|
+
if (stringArray4(model.principles).length === 0) failures.push("intent model principles must be non-empty");
|
|
19948
|
+
if (stringArray4(intent?.principles).length === 0) failures.push("intent file principles must be non-empty");
|
|
19949
|
+
if (stringArray4(model.successMeasures).length === 0) {
|
|
19806
19950
|
failures.push("intent model successMeasures must be non-empty");
|
|
19807
19951
|
}
|
|
19808
|
-
if (
|
|
19952
|
+
if (stringArray4(intent?.metrics).length === 0) failures.push("intent file metrics must be non-empty");
|
|
19809
19953
|
if (!recordField5(model.policy)) failures.push("intent model must declare policy");
|
|
19810
19954
|
if (!recordField5(intent?.policy)) failures.push("intent file must declare policy");
|
|
19811
19955
|
if (stringField5(model.status) !== "paused" || stringField5(intent?.status) !== "paused") {
|
|
@@ -19820,10 +19964,10 @@ function validateModelShape(kind, model, files, slug, failures) {
|
|
|
19820
19964
|
const operation = parseJsonFile(files, `operations/${slug}/operation.json`, failures);
|
|
19821
19965
|
if (!stringField5(model.responsibility)) failures.push("operation model must declare responsibility");
|
|
19822
19966
|
if (!stringField5(operation?.responsibility)) failures.push("operation file must declare responsibility");
|
|
19823
|
-
if (
|
|
19824
|
-
if (
|
|
19825
|
-
if (
|
|
19826
|
-
if (
|
|
19967
|
+
if (stringArray4(model.intentIds).length === 0) failures.push("operation model intentIds must be non-empty");
|
|
19968
|
+
if (stringArray4(operation?.intentIds).length === 0) failures.push("operation file intentIds must be non-empty");
|
|
19969
|
+
if (stringArray4(model.doesNotOwn).length === 0) failures.push("operation model doesNotOwn must be non-empty");
|
|
19970
|
+
if (stringArray4(operation?.doesNotOwn).length === 0) failures.push("operation file doesNotOwn must be non-empty");
|
|
19827
19971
|
if (stringField5(model.status) !== "proposed" || stringField5(operation?.status) !== "proposed") {
|
|
19828
19972
|
failures.push("operation proposal status must be proposed");
|
|
19829
19973
|
}
|
|
@@ -19832,7 +19976,7 @@ function validateModelShape(kind, model, files, slug, failures) {
|
|
|
19832
19976
|
}
|
|
19833
19977
|
if (kind === "agent") {
|
|
19834
19978
|
const agentFile = textFile(files, `agents/${slug}.md`);
|
|
19835
|
-
if (!
|
|
19979
|
+
if (!stringArray4(model.owns).includes("identity") && !containsWord(agentFile, "identity")) {
|
|
19836
19980
|
failures.push("agent owns must include identity");
|
|
19837
19981
|
}
|
|
19838
19982
|
requireStringArrayIncludes(model.doesNotOwn, "tasks", "agent doesNotOwn", failures);
|
|
@@ -19875,7 +20019,7 @@ function validateModelShape(kind, model, files, slug, failures) {
|
|
|
19875
20019
|
}
|
|
19876
20020
|
}
|
|
19877
20021
|
function capabilityRefs(value) {
|
|
19878
|
-
return [...
|
|
20022
|
+
return [...stringArray4(value?.capabilities), ...stringArray4(value?.allowedCapabilities)];
|
|
19879
20023
|
}
|
|
19880
20024
|
function evidenceRefs(value) {
|
|
19881
20025
|
if (!value) return [];
|
|
@@ -19947,7 +20091,7 @@ function normalizeBundlePath(filePath) {
|
|
|
19947
20091
|
function stringField5(value) {
|
|
19948
20092
|
return typeof value === "string" ? value.trim() : "";
|
|
19949
20093
|
}
|
|
19950
|
-
function
|
|
20094
|
+
function stringArray4(value) {
|
|
19951
20095
|
if (!Array.isArray(value)) return [];
|
|
19952
20096
|
return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
|
|
19953
20097
|
}
|
|
@@ -19959,10 +20103,10 @@ function isFiniteNumber(value) {
|
|
|
19959
20103
|
}
|
|
19960
20104
|
function hasScope(value) {
|
|
19961
20105
|
const scope = recordField5(value);
|
|
19962
|
-
return
|
|
20106
|
+
return stringArray4(scope?.repos).length > 0 || stringArray4(scope?.areas).length > 0;
|
|
19963
20107
|
}
|
|
19964
20108
|
function requireStringArrayIncludes(value, expected, label, failures) {
|
|
19965
|
-
if (!
|
|
20109
|
+
if (!stringArray4(value).includes(expected)) failures.push(`${label} must include ${expected}`);
|
|
19966
20110
|
}
|
|
19967
20111
|
function isSlug(value) {
|
|
19968
20112
|
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.
|
|
3
|
+
"version": "0.4.522",
|
|
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",
|