@kody-ade/kody-engine 0.4.34 → 0.4.36

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 +85 -8
  2. package/package.json +1 -1
package/dist/bin/kody.js CHANGED
@@ -3,7 +3,7 @@
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@kody-ade/kody-engine",
6
- version: "0.4.34",
6
+ version: "0.4.36",
7
7
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
8
8
  license: "MIT",
9
9
  type: "module",
@@ -1101,6 +1101,18 @@ function parseGenericFlags(argv) {
1101
1101
  }
1102
1102
 
1103
1103
  // src/dispatch.ts
1104
+ var POLITE_WORDS = /* @__PURE__ */ new Set([
1105
+ "please",
1106
+ "kindly",
1107
+ "hi",
1108
+ "hey",
1109
+ "hello",
1110
+ "thanks",
1111
+ "thank",
1112
+ "plz",
1113
+ "pls",
1114
+ "yo"
1115
+ ]);
1104
1116
  function autoDispatch(opts) {
1105
1117
  const explicit = opts?.explicit;
1106
1118
  if (explicit?.issueNumber && explicit.issueNumber > 0) {
@@ -1135,7 +1147,8 @@ function autoDispatch(opts) {
1135
1147
  const isPr = !!event.issue?.pull_request;
1136
1148
  if (!targetNum) return null;
1137
1149
  const afterTag = extractAfterTag(body);
1138
- const firstToken = extractSubcommand(afterTag);
1150
+ const firstTokenRaw = extractSubcommand(afterTag);
1151
+ const firstToken = firstTokenRaw && POLITE_WORDS.has(firstTokenRaw) ? null : firstTokenRaw;
1139
1152
  const aliases = opts?.config?.aliases ?? BUILTIN_ALIASES;
1140
1153
  const aliased = firstToken ? aliases[firstToken] ?? firstToken : null;
1141
1154
  let executable = null;
@@ -1151,7 +1164,7 @@ function autoDispatch(opts) {
1151
1164
  );
1152
1165
  }
1153
1166
  }
1154
- if (!executable) {
1167
+ if (!executable && !firstToken) {
1155
1168
  executable = isPr ? opts?.config?.defaultPrExecutable ?? "fix" : opts?.config?.defaultExecutable ?? null;
1156
1169
  }
1157
1170
  if (!executable) {
@@ -1178,6 +1191,45 @@ function autoDispatch(opts) {
1178
1191
  }
1179
1192
  return { executable, cliArgs: args, target: targetNum };
1180
1193
  }
1194
+ function autoDispatchTyped(opts) {
1195
+ const legacy = autoDispatch(opts);
1196
+ if (legacy) return { kind: "route", ...legacy };
1197
+ const eventName = process.env.GITHUB_EVENT_NAME;
1198
+ const eventPath = process.env.GITHUB_EVENT_PATH;
1199
+ if (!eventName || !eventPath || !fs7.existsSync(eventPath)) {
1200
+ return { kind: "silent", reason: "no GHA event context" };
1201
+ }
1202
+ if (eventName !== "issue_comment") {
1203
+ return { kind: "silent", reason: `event ${eventName} has no comment to inspect` };
1204
+ }
1205
+ let event = {};
1206
+ try {
1207
+ event = JSON.parse(fs7.readFileSync(eventPath, "utf-8"));
1208
+ } catch {
1209
+ return { kind: "silent", reason: "GHA event payload unreadable" };
1210
+ }
1211
+ const rawBody = String(event.comment?.body ?? "");
1212
+ const authorLogin = String(event.comment?.user?.login ?? "");
1213
+ const authorType = String(event.comment?.user?.type ?? "");
1214
+ if (!rawBody.toLowerCase().includes("@kody")) {
1215
+ return { kind: "silent", reason: "comment does not mention @kody" };
1216
+ }
1217
+ if (authorLogin === "kody-bot" || authorType === "Bot") {
1218
+ return { kind: "silent", reason: `bot-authored comment (${authorLogin || authorType})` };
1219
+ }
1220
+ const targetNum = Number(event.issue?.number ?? 0);
1221
+ const isPr = !!event.issue?.pull_request;
1222
+ if (!targetNum) {
1223
+ return { kind: "silent", reason: "comment has no associated issue/PR number" };
1224
+ }
1225
+ const afterTag = extractAfterTag(rawBody.toLowerCase());
1226
+ const tokenRaw = extractSubcommand(afterTag) ?? "";
1227
+ if (!tokenRaw || POLITE_WORDS.has(tokenRaw)) {
1228
+ return { kind: "silent", reason: tokenRaw ? `polite-word lead-in '${tokenRaw}', no default executable configured` : "no subcommand token, no default executable configured" };
1229
+ }
1230
+ const available = listExecutables().map((e) => e.name).filter((n) => !n.startsWith("goal-") && !n.startsWith("job-")).sort();
1231
+ return { kind: "unrecognized", token: tokenRaw, target: targetNum, isPr, available };
1232
+ }
1181
1233
  function dispatchScheduledWatches(opts) {
1182
1234
  const now = opts?.now ?? /* @__PURE__ */ new Date();
1183
1235
  const envWindow = Number(process.env.KODY_SCHEDULE_WINDOW_SEC);
@@ -1298,11 +1350,6 @@ function coerceBare(spec, value) {
1298
1350
  return value;
1299
1351
  }
1300
1352
 
1301
- // src/executor.ts
1302
- import { execFileSync as execFileSync30, spawn as spawn5 } from "child_process";
1303
- import * as fs28 from "fs";
1304
- import * as path26 from "path";
1305
-
1306
1353
  // src/issue.ts
1307
1354
  import { execFileSync as execFileSync3 } from "child_process";
1308
1355
  var API_TIMEOUT_MS = 3e4;
@@ -1444,6 +1491,11 @@ function postPrReviewComment(prNumber, body, cwd) {
1444
1491
  }
1445
1492
  }
1446
1493
 
1494
+ // src/executor.ts
1495
+ import { execFileSync as execFileSync30, spawn as spawn5 } from "child_process";
1496
+ import * as fs28 from "fs";
1497
+ import * as path26 from "path";
1498
+
1447
1499
  // src/profile.ts
1448
1500
  import * as fs8 from "fs";
1449
1501
  import * as path7 from "path";
@@ -10100,6 +10152,31 @@ async function runCi(argv) {
10100
10152
  return runScheduledFanOut(cwd, args, { force: manualWorkflowDispatch });
10101
10153
  }
10102
10154
  if (!args.issueNumber && !autoFallback && process.env.GITHUB_EVENT_NAME) {
10155
+ const outcome = autoDispatchTyped({ config: earlyConfig });
10156
+ if (outcome.kind === "unrecognized") {
10157
+ const tokenLabel = outcome.token ? `\`${outcome.token}\`` : "an empty subcommand";
10158
+ const top = outcome.available.slice(0, 12).join(", ");
10159
+ const more = outcome.available.length > 12 ? `, \u2026 (${outcome.available.length - 12} more)` : "";
10160
+ const body = [
10161
+ `\u26A0\uFE0F kody: I don't recognize ${tokenLabel}.`,
10162
+ "",
10163
+ `Available subcommands: ${top}${more}`,
10164
+ "",
10165
+ "Examples: `@kody`, `@kody fix`, `@kody plan`, `@kody review`."
10166
+ ].join("\n");
10167
+ try {
10168
+ if (outcome.isPr) postPrReviewComment(outcome.target, body, cwd);
10169
+ else postIssueComment(outcome.target, body, cwd);
10170
+ } catch (err) {
10171
+ process.stderr.write(`[kody] dispatch: failed to post unrecognized-token feedback: ${err instanceof Error ? err.message : String(err)}
10172
+ `);
10173
+ }
10174
+ process.stdout.write(
10175
+ `\u2192 kody: unrecognized subcommand "${outcome.token}" on #${outcome.target} \u2014 feedback comment posted, exiting cleanly
10176
+ `
10177
+ );
10178
+ return 0;
10179
+ }
10103
10180
  process.stdout.write(`\u2192 kody: no action for event ${process.env.GITHUB_EVENT_NAME} \u2014 exiting cleanly
10104
10181
  `);
10105
10182
  return 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.34",
3
+ "version": "0.4.36",
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",