karajan-code 4.62.0 → 4.62.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "karajan-code",
3
- "version": "4.62.0",
3
+ "version": "4.62.1",
4
4
  "description": "Local multi-agent coding orchestrator with TDD, SonarQube, and code review pipeline",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0",
@@ -133,7 +133,9 @@ export async function huCommand({ config = null, action, args = [], flags = {},
133
133
  if (rows.length === 0) console.log("no HUs yet — create one with: kj hu add \"<story>\"");
134
134
  return rows;
135
135
  }
136
- if (board.backend === "github" && action === "move") return moveOnTeamBoard({ repo: board.repo, args, flags, deps, emit, who: deps.who === undefined ? workerOf(projectDir) : deps.who });
136
+ // KJC-BUG-0392: a zero-padded id (HU-0104) is a local HU from before the shared board: it stays local.
137
+ const legacyLocal = /^HU-0\d+$/i.test(String(args[0] ?? ""));
138
+ if (board.backend === "github" && action === "move" && !legacyLocal) return moveOnTeamBoard({ repo: board.repo, args, flags, deps, emit, who: deps.who === undefined ? workerOf(projectDir) : deps.who });
137
139
 
138
140
  if (action === "list") {
139
141
  const plans = await listPlans(projectDir);
@@ -29,8 +29,11 @@ async function gh(run, args) {
29
29
  throw new Kind(`gh ${args.slice(0, 2).join(" ")} failed: ${why}`);
30
30
  }
31
31
 
32
+ // KJC-BUG-0393: a --json listing that matches nothing prints nothing at all, not "[]".
33
+ const listOf = (stdout) => (stdout.trim() === "" ? [] : JSON.parse(stdout));
34
+
32
35
  async function ensureLabels(repo, run) {
33
- const existing = new Set(JSON.parse(await gh(run, ["label", "list", "-R", repo, "--search", "kj:", "--json", "name", "--limit", "100"])).map((l) => l.name));
36
+ const existing = new Set(listOf(await gh(run, ["label", "list", "-R", repo, "--search", "kj:", "--json", "name", "--limit", "100"])).map((l) => l.name));
34
37
  for (const name of [HU_LABEL, ...STATUSES.map(statusLabel)].filter((n) => !existing.has(n))) {
35
38
  await gh(run, ["label", "create", name, "-R", repo, "--color", "1f6feb", "--description", "Karajan HU Board"]);
36
39
  }
@@ -50,7 +53,7 @@ export async function createHu({ repo, title, acceptanceCriteria = [], tests = [
50
53
 
51
54
  /** Every HU of the repo, with its status and who holds it. */
52
55
  export async function listHus({ repo, run = runCommand }) {
53
- const issues = JSON.parse(await gh(run, ["issue", "list", "-R", repo, "--label", HU_LABEL, "--state", "all", "--limit", "1000", "--json", "number,title,state,labels,assignees"]));
56
+ const issues = listOf(await gh(run, ["issue", "list", "-R", repo, "--label", HU_LABEL, "--state", "all", "--limit", "1000", "--json", "number,title,state,labels,assignees"]));
54
57
  return issues.map((i) => ({ short_id: `HU-${i.number}`, number: i.number, title: i.title, status: statusOf(i), claimed_by: i.assignees[0]?.login ?? null }));
55
58
  }
56
59
 
@@ -63,6 +66,8 @@ function statusOf(issue) {
63
66
 
64
67
  async function view(repo, number, run) {
65
68
  const issue = JSON.parse(await gh(run, ["issue", "view", String(number), "-R", repo, "--json", "state,labels,assignees"]));
69
+ // KJC-BUG-0392: only issues kj created as HUs are its to move; any other issue is left alone.
70
+ if (!issue.labels.some((l) => l.name === HU_LABEL)) throw new BoardRejectedError(`issue #${number} is not a kj HU (no ${HU_LABEL} label): kj does not touch it`);
66
71
  return { ...issue, number, status: statusOf({ ...issue, number }), holders: issue.assignees.map((a) => a.login) };
67
72
  }
68
73