@kody-ade/kody-engine 0.4.597 → 0.4.599

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 +54 -26
  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.597",
18
+ version: "0.4.599",
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",
@@ -861,8 +861,30 @@ function createOutputContractPostWriteHook(contract) {
861
861
  };
862
862
  }
863
863
  function createOutputContractStopHook(contract) {
864
- return async () => {
864
+ return async (input = {}) => {
865
865
  if (!fs4.existsSync(contract.path)) {
866
+ const message = input.last_assistant_message;
867
+ if (typeof message === "string" && message.trim()) {
868
+ let value;
869
+ try {
870
+ value = JSON.parse(message);
871
+ } catch {
872
+ value = void 0;
873
+ }
874
+ if (value !== void 0) {
875
+ try {
876
+ validateCapabilityContractOutput(contract.schema, value);
877
+ fs4.mkdirSync(path5.dirname(contract.path), { recursive: true });
878
+ fs4.writeFileSync(contract.path, JSON.stringify(value), { mode: 384 });
879
+ return {};
880
+ } catch (error2) {
881
+ return {
882
+ decision: "block",
883
+ reason: `The final JSON response does not match its required contract: ${error2 instanceof Error ? error2.message : String(error2)}. Return one corrected JSON value and finish.`
884
+ };
885
+ }
886
+ }
887
+ }
866
888
  return {
867
889
  decision: "block",
868
890
  reason: "Continue the Journey from the current page and complete the next unresolved user outcome. Do not write the result merely because you paused; write it only after the Journey passes, fails, or cannot safely continue."
@@ -18327,8 +18349,7 @@ function githubRepositoryParts(repoUrl) {
18327
18349
  if (!parts[0] || !repo) throw new Error("repository URL is incomplete");
18328
18350
  return { owner: parts[0], repo };
18329
18351
  }
18330
- function browserOrigin(ctx) {
18331
- const raw = typeof ctx.data.previewUrl === "string" ? ctx.data.previewUrl : "";
18352
+ function browserOrigin(raw) {
18332
18353
  if (!raw) throw new Error("QA target URL is unavailable");
18333
18354
  const parsed = new URL(raw);
18334
18355
  if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
@@ -18413,6 +18434,17 @@ async function prepareMethod(ctx, profile, method) {
18413
18434
  const { repositoryKey, credentialKey } = fieldsForKodyRepository(method);
18414
18435
  const variables = readKodyVariables(ctx.cwd);
18415
18436
  const repositoryUrl = variables[repositoryKey]?.trim() ?? "";
18437
+ const targetUrl = typeof ctx.data.previewUrl === "string" ? ctx.data.previewUrl : "";
18438
+ return prepareKodyRepositoryBrowserAuth(ctx, profile, {
18439
+ repositoryUrl,
18440
+ repositoryKey,
18441
+ credentialKey,
18442
+ methodName: method.name,
18443
+ targetUrl
18444
+ });
18445
+ }
18446
+ async function prepareKodyRepositoryBrowserAuth(ctx, profile, input) {
18447
+ const { repositoryUrl, credentialKey } = input;
18416
18448
  const credential = await resolveRuntimeSecret(credentialKey, ctx);
18417
18449
  ctx.data.qaAuthSecretSources = {
18418
18450
  ...ctx.data.qaAuthSecretSources ?? {},
@@ -18426,14 +18458,14 @@ async function prepareMethod(ctx, profile, method) {
18426
18458
  if (!repositoryUrl) {
18427
18459
  appendAuthMessage(
18428
18460
  ctx,
18429
- `Auth: ${method.name} is incomplete because no \`${repositoryKey}\` variable was found. Note this authenticated surface as a gap.`
18461
+ `Auth: ${input.methodName} is incomplete because no \`${input.repositoryKey ?? "repository"}\` variable was found. Note this authenticated surface as a gap.`
18430
18462
  );
18431
18463
  return false;
18432
18464
  }
18433
18465
  if (!credential.value) {
18434
18466
  appendAuthMessage(
18435
18467
  ctx,
18436
- `Auth: ${method.name} is incomplete because no \`${credentialKey}\` secret was found. Note this authenticated surface as a gap.`
18468
+ `Auth: ${input.methodName} is incomplete because no \`${credentialKey}\` secret was found. Note this authenticated surface as a gap.`
18437
18469
  );
18438
18470
  return false;
18439
18471
  }
@@ -18452,7 +18484,7 @@ async function prepareMethod(ctx, profile, method) {
18452
18484
  throw new Error("GitHub returned incomplete identity data");
18453
18485
  }
18454
18486
  state = writeKodyStorageState({
18455
- origin: browserOrigin(ctx),
18487
+ origin: browserOrigin(input.targetUrl),
18456
18488
  repoUrl: `https://github.com/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`,
18457
18489
  owner,
18458
18490
  repo,
@@ -18466,7 +18498,7 @@ async function prepareMethod(ctx, profile, method) {
18466
18498
  });
18467
18499
  appendAuthMessage(
18468
18500
  ctx,
18469
- `Auth: ${method.name} is already authenticated by the engine-provided browser session. The credential is not available to you; never request, reveal, or report it.`
18501
+ `Auth: ${input.methodName} is already authenticated by the engine-provided browser session. The credential is not available to you; never request, reveal, or report it.`
18470
18502
  );
18471
18503
  return true;
18472
18504
  } catch (error) {
@@ -18474,7 +18506,7 @@ async function prepareMethod(ctx, profile, method) {
18474
18506
  const reason = error instanceof Error ? error.message : String(error);
18475
18507
  appendAuthMessage(
18476
18508
  ctx,
18477
- `Auth: the engine could not prepare ${method.name} (${reason}). Note this authenticated surface as a gap.`
18509
+ `Auth: the engine could not prepare ${input.methodName} (${reason}). Note this authenticated surface as a gap.`
18478
18510
  );
18479
18511
  return false;
18480
18512
  }
@@ -18693,7 +18725,7 @@ var init_prepareSimpleCapabilityRuntime = __esm({
18693
18725
  "src/scripts/prepareSimpleCapabilityRuntime.ts"() {
18694
18726
  "use strict";
18695
18727
  init_loadQaContext();
18696
- init_runtimeSecrets();
18728
+ init_prepareBrowserAuth();
18697
18729
  PLAYWRIGHT_SERVER = {
18698
18730
  name: "playwright",
18699
18731
  command: "npx",
@@ -18705,6 +18737,18 @@ var init_prepareSimpleCapabilityRuntime = __esm({
18705
18737
  configureBrowser(ctx, profile, requirements);
18706
18738
  if (requirements.qaCredentials) {
18707
18739
  await loadQaContext(ctx, profile);
18740
+ }
18741
+ if (requirements.githubTestToken) {
18742
+ const capabilityInput = ctx.data.capabilityInput && typeof ctx.data.capabilityInput === "object" && !Array.isArray(ctx.data.capabilityInput) ? ctx.data.capabilityInput : {};
18743
+ const targetUrl = typeof capabilityInput.url === "string" ? capabilityInput.url : typeof capabilityInput.targetUrl === "string" ? capabilityInput.targetUrl : "";
18744
+ await prepareKodyRepositoryBrowserAuth(ctx, profile, {
18745
+ repositoryUrl: `https://github.com/${ctx.config.github.owner}/${ctx.config.github.repo}`,
18746
+ credentialKey: "E2E_GITHUB_TOKEN",
18747
+ methodName: "Kody protected QA login",
18748
+ targetUrl
18749
+ });
18750
+ }
18751
+ if (requirements.qaCredentials || requirements.githubTestToken) {
18708
18752
  appendPrompt(
18709
18753
  ctx,
18710
18754
  [
@@ -18716,22 +18760,6 @@ var init_prepareSimpleCapabilityRuntime = __esm({
18716
18760
  ].join("\n")
18717
18761
  );
18718
18762
  }
18719
- if (requirements.githubTestToken) {
18720
- const token = await resolveRuntimeSecret("E2E_GITHUB_TOKEN", ctx);
18721
- appendPrompt(
18722
- ctx,
18723
- token.value ? [
18724
- "## Protected GitHub test login",
18725
- "",
18726
- `A protected GitHub test token is available: \`${token.value}\``,
18727
- "Use it only if the target application asks for a GitHub personal access token; never include the token in screenshots, output, logs, files, or messages."
18728
- ].join("\n") : [
18729
- "## Protected GitHub test login",
18730
- "",
18731
- "E2E_GITHUB_TOKEN is not configured. If this Quality Scenario requires GitHub token authentication, return a blocked result."
18732
- ].join("\n")
18733
- );
18734
- }
18735
18763
  };
18736
18764
  }
18737
18765
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.597",
3
+ "version": "0.4.599",
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",