@kody-ade/kody-engine 0.4.559 → 0.4.560
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 +219 -76
- package/package.json +2 -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.560",
|
|
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",
|
|
@@ -40,6 +40,7 @@ var init_package = __esm({
|
|
|
40
40
|
posttest: "tsx scripts/check-coverage-floor.ts",
|
|
41
41
|
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
42
42
|
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
43
|
+
"verify:live-release": "tsx scripts/live-release-gate.ts",
|
|
43
44
|
"test:runtime-services": 'node --test "tests/runtime-services/*.test.mjs"',
|
|
44
45
|
"test:all": "vitest run tests --no-coverage",
|
|
45
46
|
typecheck: "tsc --noEmit",
|
|
@@ -3105,6 +3106,39 @@ function createStateBackendFromEnv(env = process.env, client) {
|
|
|
3105
3106
|
state,
|
|
3106
3107
|
updatedAt
|
|
3107
3108
|
});
|
|
3109
|
+
},
|
|
3110
|
+
async acquireWorkflowRunLease(tenantId2, workflowId, runId, ownerId, nowMs, leaseDurationMs) {
|
|
3111
|
+
const result = await transport.mutation(anyApi.workflowRunLeases.acquire, {
|
|
3112
|
+
tenantId: requireTenant(tenantId2),
|
|
3113
|
+
workflowId: requireNonEmpty(workflowId, "workflowId"),
|
|
3114
|
+
runId: requireNonEmpty(runId, "runId"),
|
|
3115
|
+
ownerId: requireNonEmpty(ownerId, "ownerId"),
|
|
3116
|
+
nowMs,
|
|
3117
|
+
leaseDurationMs
|
|
3118
|
+
});
|
|
3119
|
+
return result;
|
|
3120
|
+
},
|
|
3121
|
+
async renewWorkflowRunLease(tenantId2, workflowId, runId, ownerId, nowMs, leaseDurationMs) {
|
|
3122
|
+
return Boolean(
|
|
3123
|
+
await transport.mutation(anyApi.workflowRunLeases.renew, {
|
|
3124
|
+
tenantId: requireTenant(tenantId2),
|
|
3125
|
+
workflowId: requireNonEmpty(workflowId, "workflowId"),
|
|
3126
|
+
runId: requireNonEmpty(runId, "runId"),
|
|
3127
|
+
ownerId: requireNonEmpty(ownerId, "ownerId"),
|
|
3128
|
+
nowMs,
|
|
3129
|
+
leaseDurationMs
|
|
3130
|
+
})
|
|
3131
|
+
);
|
|
3132
|
+
},
|
|
3133
|
+
async releaseWorkflowRunLease(tenantId2, workflowId, runId, ownerId) {
|
|
3134
|
+
return Boolean(
|
|
3135
|
+
await transport.mutation(anyApi.workflowRunLeases.release, {
|
|
3136
|
+
tenantId: requireTenant(tenantId2),
|
|
3137
|
+
workflowId: requireNonEmpty(workflowId, "workflowId"),
|
|
3138
|
+
runId: requireNonEmpty(runId, "runId"),
|
|
3139
|
+
ownerId: requireNonEmpty(ownerId, "ownerId")
|
|
3140
|
+
})
|
|
3141
|
+
);
|
|
3108
3142
|
}
|
|
3109
3143
|
};
|
|
3110
3144
|
}
|
|
@@ -22711,6 +22745,90 @@ var init_simpleCapabilityRuntime = __esm({
|
|
|
22711
22745
|
}
|
|
22712
22746
|
});
|
|
22713
22747
|
|
|
22748
|
+
// src/workflowDefinitionIdentity.ts
|
|
22749
|
+
import { createHash as createHash8 } from "crypto";
|
|
22750
|
+
function workflowDefinitionHash(workflow) {
|
|
22751
|
+
return createHash8("sha256").update(stableJson(workflow)).digest("hex");
|
|
22752
|
+
}
|
|
22753
|
+
function workflowResumeBlocker(state, workflow) {
|
|
22754
|
+
if (!state || state.status === "done") return null;
|
|
22755
|
+
if (!state.definitionHash) return null;
|
|
22756
|
+
if (state.definitionHash !== workflowDefinitionHash(workflow)) {
|
|
22757
|
+
return "The Workflow definition changed after this run started. Start a new run instead of resuming it.";
|
|
22758
|
+
}
|
|
22759
|
+
return null;
|
|
22760
|
+
}
|
|
22761
|
+
function stableJson(value) {
|
|
22762
|
+
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
|
|
22763
|
+
if (value && typeof value === "object") {
|
|
22764
|
+
return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${stableJson(item)}`).join(",")}}`;
|
|
22765
|
+
}
|
|
22766
|
+
return JSON.stringify(value) ?? "undefined";
|
|
22767
|
+
}
|
|
22768
|
+
var init_workflowDefinitionIdentity = __esm({
|
|
22769
|
+
"src/workflowDefinitionIdentity.ts"() {
|
|
22770
|
+
"use strict";
|
|
22771
|
+
}
|
|
22772
|
+
});
|
|
22773
|
+
|
|
22774
|
+
// src/workflowRunLease.ts
|
|
22775
|
+
async function acquireWorkflowRunLease(store, input) {
|
|
22776
|
+
const result = await store.acquireWorkflowRunLease(
|
|
22777
|
+
input.tenantId,
|
|
22778
|
+
input.workflowId,
|
|
22779
|
+
input.runId,
|
|
22780
|
+
input.ownerId,
|
|
22781
|
+
input.nowMs,
|
|
22782
|
+
WORKFLOW_RUN_LEASE_MS
|
|
22783
|
+
);
|
|
22784
|
+
if (!result.acquired) return result;
|
|
22785
|
+
return { acquired: true, lease: new WorkflowRunLease(store, input) };
|
|
22786
|
+
}
|
|
22787
|
+
var WORKFLOW_RUN_LEASE_MS, WorkflowRunLeaseLostError, WorkflowRunLease;
|
|
22788
|
+
var init_workflowRunLease = __esm({
|
|
22789
|
+
"src/workflowRunLease.ts"() {
|
|
22790
|
+
"use strict";
|
|
22791
|
+
WORKFLOW_RUN_LEASE_MS = 8 * 60 * 60 * 1e3;
|
|
22792
|
+
WorkflowRunLeaseLostError = class extends Error {
|
|
22793
|
+
constructor() {
|
|
22794
|
+
super("Workflow run ownership was lost; execution stopped to prevent duplicate work.");
|
|
22795
|
+
this.name = "WorkflowRunLeaseLostError";
|
|
22796
|
+
}
|
|
22797
|
+
};
|
|
22798
|
+
WorkflowRunLease = class {
|
|
22799
|
+
constructor(store, identity) {
|
|
22800
|
+
this.store = store;
|
|
22801
|
+
this.identity = identity;
|
|
22802
|
+
}
|
|
22803
|
+
store;
|
|
22804
|
+
identity;
|
|
22805
|
+
released = false;
|
|
22806
|
+
async checkpoint(nowMs = Date.now()) {
|
|
22807
|
+
if (this.released) throw new WorkflowRunLeaseLostError();
|
|
22808
|
+
const renewed = await this.store.renewWorkflowRunLease(
|
|
22809
|
+
this.identity.tenantId,
|
|
22810
|
+
this.identity.workflowId,
|
|
22811
|
+
this.identity.runId,
|
|
22812
|
+
this.identity.ownerId,
|
|
22813
|
+
nowMs,
|
|
22814
|
+
WORKFLOW_RUN_LEASE_MS
|
|
22815
|
+
);
|
|
22816
|
+
if (!renewed) throw new WorkflowRunLeaseLostError();
|
|
22817
|
+
}
|
|
22818
|
+
async release() {
|
|
22819
|
+
if (this.released) return;
|
|
22820
|
+
this.released = true;
|
|
22821
|
+
await this.store.releaseWorkflowRunLease(
|
|
22822
|
+
this.identity.tenantId,
|
|
22823
|
+
this.identity.workflowId,
|
|
22824
|
+
this.identity.runId,
|
|
22825
|
+
this.identity.ownerId
|
|
22826
|
+
);
|
|
22827
|
+
}
|
|
22828
|
+
};
|
|
22829
|
+
}
|
|
22830
|
+
});
|
|
22831
|
+
|
|
22714
22832
|
// src/workflowRunState.ts
|
|
22715
22833
|
function workflowRunStatePath(workflowId, runId) {
|
|
22716
22834
|
if (!SAFE_ID.test(workflowId)) throw new Error(`invalid workflow id ${workflowId}`);
|
|
@@ -22770,21 +22888,21 @@ function parseWorkflowSteps(value) {
|
|
|
22770
22888
|
return Object.keys(steps).length > 0 ? steps : void 0;
|
|
22771
22889
|
}
|
|
22772
22890
|
async function readWorkflowRunState(config, _cwd, workflowId, runId) {
|
|
22773
|
-
const tenantId2 =
|
|
22891
|
+
const tenantId2 = workflowRuntimeTenant(config);
|
|
22774
22892
|
const row = await createStateBackendFromEnv().getWorkflowRun(tenantId2, workflowId, runId);
|
|
22775
22893
|
return row ? parseWorkflowRunState(row.state) : null;
|
|
22776
22894
|
}
|
|
22777
22895
|
async function writeWorkflowRunState(config, _cwd, workflowId, runId, state) {
|
|
22778
22896
|
workflowRunStatePath(workflowId, runId);
|
|
22779
22897
|
await createStateBackendFromEnv().saveWorkflowRun(
|
|
22780
|
-
|
|
22898
|
+
workflowRuntimeTenant(config),
|
|
22781
22899
|
workflowId,
|
|
22782
22900
|
runId,
|
|
22783
22901
|
state,
|
|
22784
22902
|
(/* @__PURE__ */ new Date()).toISOString()
|
|
22785
22903
|
);
|
|
22786
22904
|
}
|
|
22787
|
-
function
|
|
22905
|
+
function workflowRuntimeTenant(config) {
|
|
22788
22906
|
if (config.github?.owner && config.github.repo) return `${config.github.owner}/${config.github.repo}`;
|
|
22789
22907
|
const tenantId2 = process.env.GITHUB_REPOSITORY?.trim();
|
|
22790
22908
|
if (!tenantId2) throw new Error("Repository identity is required for workflow run state");
|
|
@@ -22811,7 +22929,7 @@ __export(job_exports, {
|
|
|
22811
22929
|
stableJobKey: () => stableJobKey,
|
|
22812
22930
|
validateJob: () => validateJob
|
|
22813
22931
|
});
|
|
22814
|
-
import {
|
|
22932
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
22815
22933
|
function newJobId(flavor) {
|
|
22816
22934
|
localJobSeq += 1;
|
|
22817
22935
|
const runId = process.env.GITHUB_RUN_ID;
|
|
@@ -22901,75 +23019,100 @@ async function runJob(job, base) {
|
|
|
22901
23019
|
const capabilitySelectedImplementation = simpleCapabilityRuntime?.implementation ?? resolvedCapability?.implementation ?? capabilityContext?.config.implementation ?? capabilityContext?.config.implementations?.[0] ?? (capabilityContext?.config.role ? capabilityContext.slug : void 0) ?? (capabilityContext?.config.tickScript ? "capability-tick-scripted" : void 0);
|
|
22902
23020
|
const profileName = explicitImplementation ?? capabilitySelectedImplementation;
|
|
22903
23021
|
if (workflow && shouldRunCapabilityWorkflow(valid, workflow, workflowIdentity, capabilitySelectedImplementation, base)) {
|
|
22904
|
-
const
|
|
22905
|
-
|
|
22906
|
-
|
|
22907
|
-
|
|
22908
|
-
|
|
22909
|
-
|
|
22910
|
-
};
|
|
22911
|
-
|
|
22912
|
-
|
|
22913
|
-
|
|
22914
|
-
|
|
22915
|
-
|
|
22916
|
-
id: parentRunId,
|
|
22917
|
-
subjectType: "workflow",
|
|
22918
|
-
subjectId: workflowIdentity,
|
|
22919
|
-
subjectLabel: workflowCapability.title,
|
|
22920
|
-
status: "running",
|
|
22921
|
-
title: workflowCapability.title,
|
|
22922
|
-
startedAt,
|
|
22923
|
-
updatedAt: startedAt,
|
|
22924
|
-
workflow: workflowIdentity,
|
|
22925
|
-
kodyRunId: valid.workflowRunId,
|
|
22926
|
-
parentRunId: typeof base.preloadedData?.parentRunId === "string" ? base.preloadedData.parentRunId : void 0,
|
|
22927
|
-
sourceType: "job"
|
|
22928
|
-
};
|
|
22929
|
-
const persistRun = Boolean(base.config && !base.skipConfig && hasStateBackendConfig());
|
|
22930
|
-
if (base.config && persistRun) {
|
|
22931
|
-
await upsertRunIndexRowBestEffortAsync(base.config, base.cwd, parentRow);
|
|
23022
|
+
const leaseResult = valid.workflowRunId && workflowIdentity && base.config && hasStateBackendConfig() ? await acquireWorkflowRunLease(createStateBackendFromEnv(), {
|
|
23023
|
+
tenantId: workflowRuntimeTenant(base.config),
|
|
23024
|
+
workflowId: workflowIdentity,
|
|
23025
|
+
runId: valid.workflowRunId,
|
|
23026
|
+
ownerId: `${process.env.GITHUB_RUN_ID ?? "local"}:${process.env.GITHUB_RUN_ATTEMPT ?? "1"}:${randomUUID3()}`,
|
|
23027
|
+
nowMs: Date.now()
|
|
23028
|
+
}) : null;
|
|
23029
|
+
if (leaseResult && !leaseResult.acquired) {
|
|
23030
|
+
return {
|
|
23031
|
+
exitCode: 75,
|
|
23032
|
+
reason: `Workflow ${workflowIdentity} run ${valid.workflowRunId} is already running.`
|
|
23033
|
+
};
|
|
22932
23034
|
}
|
|
22933
|
-
const
|
|
22934
|
-
...base,
|
|
22935
|
-
preloadedData: { ...base.preloadedData ?? {}, parentRunId }
|
|
22936
|
-
};
|
|
22937
|
-
let result;
|
|
23035
|
+
const lease = leaseResult?.acquired ? leaseResult.lease : null;
|
|
22938
23036
|
try {
|
|
22939
|
-
|
|
22940
|
-
|
|
23037
|
+
const workflowCapability = capabilityContext ?? workflowContext;
|
|
23038
|
+
const persistedState = valid.workflowRunId && workflowIdentity && base.config ? await readWorkflowRunState(base.config, base.cwd, workflowIdentity, valid.workflowRunId) : null;
|
|
23039
|
+
const workflowJob = {
|
|
23040
|
+
...workflowContext && !valid.why ? { ...valid, why: workflowContext.body } : valid,
|
|
23041
|
+
...workflowCapability.config.agent ? { agent: workflowCapability.config.agent } : {},
|
|
23042
|
+
...valid.workflowState ?? persistedState ? { workflowState: valid.workflowState ?? persistedState ?? void 0 } : {}
|
|
23043
|
+
};
|
|
23044
|
+
const checkpoint = valid.workflowRunId && workflowIdentity && base.config ? async (state) => {
|
|
23045
|
+
await lease?.checkpoint();
|
|
23046
|
+
await writeWorkflowRunState(base.config, base.cwd, workflowIdentity, valid.workflowRunId, state);
|
|
23047
|
+
} : void 0;
|
|
23048
|
+
const parentRunId = `workflow:${workflowIdentity}:${valid.workflowRunId ?? newJobId(valid.flavor)}`;
|
|
23049
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
23050
|
+
const parentRow = {
|
|
23051
|
+
version: 1,
|
|
23052
|
+
id: parentRunId,
|
|
23053
|
+
subjectType: "workflow",
|
|
23054
|
+
subjectId: workflowIdentity,
|
|
23055
|
+
subjectLabel: workflowCapability.title,
|
|
23056
|
+
status: "running",
|
|
23057
|
+
title: workflowCapability.title,
|
|
23058
|
+
startedAt,
|
|
23059
|
+
updatedAt: startedAt,
|
|
23060
|
+
workflow: workflowIdentity,
|
|
23061
|
+
kodyRunId: valid.workflowRunId,
|
|
23062
|
+
parentRunId: typeof base.preloadedData?.parentRunId === "string" ? base.preloadedData.parentRunId : void 0,
|
|
23063
|
+
sourceType: "job"
|
|
23064
|
+
};
|
|
23065
|
+
const persistRun = Boolean(base.config && !base.skipConfig && hasStateBackendConfig());
|
|
23066
|
+
if (base.config && persistRun) {
|
|
23067
|
+
await upsertRunIndexRowBestEffortAsync(base.config, base.cwd, parentRow);
|
|
23068
|
+
}
|
|
23069
|
+
const workflowBase = {
|
|
23070
|
+
...base,
|
|
23071
|
+
preloadedData: { ...base.preloadedData ?? {}, parentRunId }
|
|
23072
|
+
};
|
|
23073
|
+
let result;
|
|
23074
|
+
try {
|
|
23075
|
+
result = await runCapabilityWorkflow(workflowJob, workflow, workflowCapability, workflowBase, checkpoint);
|
|
23076
|
+
} catch (error) {
|
|
23077
|
+
if (base.config && persistRun) {
|
|
23078
|
+
await upsertRunIndexRowBestEffortAsync(base.config, base.cwd, {
|
|
23079
|
+
...parentRow,
|
|
23080
|
+
status: "failed",
|
|
23081
|
+
summary: error instanceof Error ? error.message : String(error),
|
|
23082
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
23083
|
+
});
|
|
23084
|
+
}
|
|
23085
|
+
throw error;
|
|
23086
|
+
}
|
|
22941
23087
|
if (base.config && persistRun) {
|
|
22942
23088
|
await upsertRunIndexRowBestEffortAsync(base.config, base.cwd, {
|
|
22943
23089
|
...parentRow,
|
|
22944
|
-
status: "failed",
|
|
22945
|
-
summary:
|
|
23090
|
+
status: result.exitCode === 0 ? "success" : "failed",
|
|
23091
|
+
summary: result.reason,
|
|
22946
23092
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
22947
23093
|
});
|
|
22948
23094
|
}
|
|
22949
|
-
|
|
22950
|
-
|
|
22951
|
-
|
|
22952
|
-
|
|
22953
|
-
|
|
22954
|
-
|
|
22955
|
-
|
|
22956
|
-
|
|
22957
|
-
|
|
22958
|
-
|
|
22959
|
-
|
|
22960
|
-
|
|
22961
|
-
|
|
22962
|
-
|
|
22963
|
-
|
|
22964
|
-
|
|
22965
|
-
|
|
22966
|
-
|
|
22967
|
-
|
|
22968
|
-
...result.reason ? { summary: result.reason } : {},
|
|
22969
|
-
...Object.keys(facts).length > 0 ? { output: facts } : {}
|
|
23095
|
+
if (valid.workflowRunId && workflowIdentity && base.config && result.workflowState) {
|
|
23096
|
+
await lease?.checkpoint();
|
|
23097
|
+
await writeWorkflowRunState(base.config, base.cwd, workflowIdentity, valid.workflowRunId, result.workflowState);
|
|
23098
|
+
}
|
|
23099
|
+
if (valid.workflowRunId && workflowIdentity && hasGitHubActionsIdentity()) {
|
|
23100
|
+
const facts = result.workflowState?.facts ?? {};
|
|
23101
|
+
await notifyWorkflowCompleted({
|
|
23102
|
+
workflowId: workflowIdentity,
|
|
23103
|
+
runId: valid.workflowRunId,
|
|
23104
|
+
status: result.workflowState?.status === "blocked" ? "blocked" : result.exitCode === 0 ? "success" : "failed",
|
|
23105
|
+
...result.reason ? { summary: result.reason } : {},
|
|
23106
|
+
...Object.keys(facts).length > 0 ? { output: facts } : {}
|
|
23107
|
+
});
|
|
23108
|
+
}
|
|
23109
|
+
return result;
|
|
23110
|
+
} finally {
|
|
23111
|
+
await lease?.release().catch((error) => {
|
|
23112
|
+
process.stderr.write(`warning: failed to release Workflow run ownership: ${String(error)}
|
|
23113
|
+
`);
|
|
22970
23114
|
});
|
|
22971
23115
|
}
|
|
22972
|
-
return result;
|
|
22973
23116
|
}
|
|
22974
23117
|
if (!profileName) {
|
|
22975
23118
|
throw new InvalidJobError(`job capability resolves to no implementation: ${capabilityIdentity ?? action}`);
|
|
@@ -23072,6 +23215,14 @@ async function runCapabilityWorkflow(parent, workflow, capability, base, checkpo
|
|
|
23072
23215
|
}
|
|
23073
23216
|
return { exitCode: 64, reason: invalid };
|
|
23074
23217
|
}
|
|
23218
|
+
const resumeBlocker = workflowResumeBlocker(parent.workflowState, workflow);
|
|
23219
|
+
if (resumeBlocker) {
|
|
23220
|
+
const state = initialWorkflowState(parent, workflow);
|
|
23221
|
+
state.status = "blocked";
|
|
23222
|
+
state.blocker = resumeBlocker;
|
|
23223
|
+
await checkpoint?.(state);
|
|
23224
|
+
return { exitCode: 64, reason: resumeBlocker, workflowState: state };
|
|
23225
|
+
}
|
|
23075
23226
|
if (isGraphWorkflow(workflow)) {
|
|
23076
23227
|
const result = await runGraphCapabilityWorkflow(parent, workflow, capability, base, checkpoint);
|
|
23077
23228
|
if (workflow.report && result.workflowState) {
|
|
@@ -23548,16 +23699,6 @@ function capabilityInputNames(folder) {
|
|
|
23548
23699
|
if (!properties || typeof properties !== "object" || Array.isArray(properties)) return /* @__PURE__ */ new Set();
|
|
23549
23700
|
return new Set(Object.keys(properties));
|
|
23550
23701
|
}
|
|
23551
|
-
function workflowDefinitionHash(workflow) {
|
|
23552
|
-
return createHash8("sha256").update(stableJson(workflow)).digest("hex");
|
|
23553
|
-
}
|
|
23554
|
-
function stableJson(value) {
|
|
23555
|
-
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
|
|
23556
|
-
if (value && typeof value === "object") {
|
|
23557
|
-
return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${stableJson(item)}`).join(",")}}`;
|
|
23558
|
-
}
|
|
23559
|
-
return JSON.stringify(value);
|
|
23560
|
-
}
|
|
23561
23702
|
function cloneWorkflowSteps(steps) {
|
|
23562
23703
|
return Object.fromEntries(Object.entries(steps).map(([id, step]) => [id, { ...step }]));
|
|
23563
23704
|
}
|
|
@@ -23779,7 +23920,9 @@ var init_job = __esm({
|
|
|
23779
23920
|
init_publishReport();
|
|
23780
23921
|
init_simpleCapabilityRuntime();
|
|
23781
23922
|
init_state_backend();
|
|
23923
|
+
init_workflowDefinitionIdentity();
|
|
23782
23924
|
init_workflowDefinitions();
|
|
23925
|
+
init_workflowRunLease();
|
|
23783
23926
|
init_workflowRunState();
|
|
23784
23927
|
init_workflowValidation();
|
|
23785
23928
|
init_jobIdentity();
|
|
@@ -27476,7 +27619,7 @@ init_config();
|
|
|
27476
27619
|
init_fetchRepoMcp();
|
|
27477
27620
|
|
|
27478
27621
|
// src/servers/mcpHttpServer.ts
|
|
27479
|
-
import { randomUUID as
|
|
27622
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
27480
27623
|
import { createServer as createServer4 } from "http";
|
|
27481
27624
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
27482
27625
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
@@ -27485,7 +27628,7 @@ function buildMcpHttpServer(opts) {
|
|
|
27485
27628
|
const transports = /* @__PURE__ */ new Map();
|
|
27486
27629
|
for (const route of opts.routes) {
|
|
27487
27630
|
const transport = new StreamableHTTPServerTransport({
|
|
27488
|
-
sessionIdGenerator: () =>
|
|
27631
|
+
sessionIdGenerator: () => randomUUID4()
|
|
27489
27632
|
});
|
|
27490
27633
|
transports.set(route.path, transport);
|
|
27491
27634
|
routes.set(route.path, route.name);
|
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.560",
|
|
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",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"posttest": "tsx scripts/check-coverage-floor.ts",
|
|
53
53
|
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
54
54
|
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
55
|
+
"verify:live-release": "tsx scripts/live-release-gate.ts",
|
|
55
56
|
"test:runtime-services": "node --test \"tests/runtime-services/*.test.mjs\"",
|
|
56
57
|
"test:all": "vitest run tests --no-coverage",
|
|
57
58
|
"typecheck": "tsc --noEmit",
|