karajan-code 2.7.0 → 2.7.2

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/README.md CHANGED
@@ -23,7 +23,7 @@
23
23
 
24
24
  ---
25
25
 
26
- > **v2.6.0 released** — Modular orchestrator + infrastructure DI + Valibot config validation. `src/orchestrator.js` split into a thin barrel + `flow-runner.js` + new `StageExecutor` contract under `src/orchestrator/stages/`. `FileSystemService` and `CommandRunner` adapters let tests swap in mocks instead of spawning real subprocesses. Config now validated with Valibot (catches `review_mode` typos, `max_iterations: 0`, bad ports at load time). HU Board auto-start gate simplified to `hu_board.auto_start` alone with a prominent cyan URL banner at pipeline init. Plus: budget comparison (With-KJ vs Without-KJ), rich session journal (decisions / iterations / summary / tree), Brain decisor with intent-driven routing, and Karajan-wide JSDoc typedefs. See [CHANGELOG.md](./CHANGELOG.md) for full history and [MIGRATION-v2.md](./MIGRATION-v2.md) for v1→v2 breaking changes.
26
+ > **v2.7.2 released** — Skills observability: `summary.md` now shows a "Skills Used" section listing the addyosmani slugs resolved per role + OpenSkills installed/recommended, and `kj-tail` v1.37.0 highlights `[skills:*]` events with a 🎯 icon (magenta on success, yellow on graceful-degradation). Carries the full v2.7 feature set: [`addyosmani/agent-skills`](https://github.com/addyosmani/agent-skills) as Karajan's first-source process catalog (20+ lifecycle workflows — TDD, code-review-and-quality, security-and-hardening, performance-optimization, git-workflow-and-versioning, CI/CD, debugging-and-error-recovery, spec-driven-development, planning-and-task-breakdown…) injected per role **before** OpenSkills stack skills, shallow-cloned into `~/.karajan/agent-skills/` and refreshed weekly via `git pull`. SEA platform binaries (`linux-x64`, `darwin-arm64`, `win-x64`) publish correctly again after the v2.7.1 workflow fix. New CLI: `kj skills sync-addyosmani`, `kj skills list-addyosmani`. New config: `skills.sources`, `skills.addyosmani.{enabled,refreshDays,repoUrl}`. See [CHANGELOG.md](./CHANGELOG.md) for full history and [MIGRATION-v2.md](./MIGRATION-v2.md) for v1→v2 breaking changes.
27
27
 
28
28
  You describe what you want to build. Karajan orchestrates multiple AI agents to plan it, implement it, test it, review it with SonarQube, and iterate. No babysitting required.
29
29
 
package/bin/kj-tail CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  set -euo pipefail
6
6
 
7
- VERSION="1.36.0"
7
+ VERSION="1.37.0"
8
8
 
9
9
  # ── Colors ──────────────────────────────────────────────
10
10
  RED='\033[0;31m'
@@ -248,6 +248,17 @@ filter_line() {
248
248
  return
249
249
  fi
250
250
 
251
+ # Skills (addyosmani catalog + OpenSkills marketplace)
252
+ if [[ "$clean" == *"[skills:"* ]] || [[ "$clean" == *"[skills]"* ]]; then
253
+ # Highlight failures/unavailability in yellow, successes in magenta
254
+ if [[ "$clean" == *"unavailable"* ]] || [[ "$clean" == *"would have used"* ]]; then
255
+ echo -e "${prefix}${YELLOW} ├─ 🎯 ${clean}${RESET}"
256
+ else
257
+ echo -e "${prefix}${MAGENTA} ├─ 🎯 ${clean}${RESET}"
258
+ fi
259
+ return
260
+ fi
261
+
251
262
  # TDD
252
263
  if [[ "$clean" == *"TDD"* ]] || [[ "$clean" == *"tdd"* ]]; then
253
264
  echo -e "${prefix}${GREEN} ├─ 📋 ${clean}${RESET}"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "karajan-code",
3
- "version": "2.7.0",
3
+ "version": "2.7.2",
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",
@@ -61,6 +61,8 @@
61
61
  "devDependencies": {
62
62
  "@changesets/cli": "^2.30.0",
63
63
  "@vitest/coverage-v8": "^4.0.18",
64
+ "esbuild": "^0.28.0",
65
+ "postject": "^1.0.0-alpha.6",
64
66
  "vitest": "^4.0.0"
65
67
  }
66
68
  }
@@ -10,7 +10,7 @@
10
10
  * 4. Inject the blob into the binary with postject
11
11
  * 5. (macOS only) Re-sign the binary with ad-hoc signature
12
12
  *
13
- * Requirements (installed globally or via npx):
13
+ * Requirements (installed as devDependencies — run `npm ci` first):
14
14
  * - esbuild
15
15
  * - postject
16
16
  *
@@ -452,6 +452,14 @@ async function finalizeApprovedSession({ config, gitCtx, task, logger, session,
452
452
  finishedAt: new Date().toISOString(),
453
453
  brainDecisions: Array.isArray(session.brainDecisions) ? session.brainDecisions.length : 0,
454
454
  solomonInvocations: Array.isArray(session.solomonRulings) ? session.solomonRulings.length : 0,
455
+ // KJC-TSK-0327: surface skill-source decisions in the summary so the
456
+ // post-mortem shows which process skills (addyosmani) and stack skills
457
+ // (OpenSkills) actually shaped the role prompts.
458
+ skills: {
459
+ addyosmani: session.addyosmaniSkills,
460
+ installed: session.autoInstalledSkills,
461
+ recommended: session.skillsRecommended,
462
+ },
455
463
  }, { logger });
456
464
  logger.info(`Session journal written to ${journalDir}`);
457
465
  } catch (err) {
@@ -26,6 +26,10 @@ import path from "node:path";
26
26
  * @property {string} [finishedAt] - ISO timestamp (optional)
27
27
  * @property {number} [solomonInvocations]
28
28
  * @property {number} [brainDecisions]
29
+ * @property {Object} [skills] - skill sources used this session (KJC-TSK-0327)
30
+ * @property {Object} [skills.addyosmani] - { available, action, resolvedSlugs, reason }
31
+ * @property {string[]} [skills.installed] - OpenSkills installed this run (session.autoInstalledSkills)
32
+ * @property {string[]} [skills.recommended] - wouldHaveUsed when OpenSkills CLI missing
29
33
  */
30
34
 
31
35
  function esc(text) {
@@ -103,6 +107,48 @@ function renderBreakdownByRole(breakdown) {
103
107
  return ["| Role | Tokens | Cost |", "|---|---|---|", ...rows].join("\n");
104
108
  }
105
109
 
110
+ /**
111
+ * Render the Skills section: which process skills (addyosmani) were resolved
112
+ * for the task, which OpenSkills were installed, and which skills would have
113
+ * helped but couldn't be installed (graceful-degradation path).
114
+ *
115
+ * Returns null when no skill activity happened (no addyosmani, no installs,
116
+ * no recommendations) so the section is elided.
117
+ */
118
+ function renderSkills(skills) {
119
+ if (!skills || typeof skills !== "object") return null;
120
+ const addy = skills.addyosmani;
121
+ const installed = Array.isArray(skills.installed) ? skills.installed : [];
122
+ const recommended = Array.isArray(skills.recommended) ? skills.recommended : [];
123
+
124
+ const hasAddy = addy && (addy.available === true || addy.available === false);
125
+ if (!hasAddy && installed.length === 0 && recommended.length === 0) return null;
126
+
127
+ const lines = [];
128
+
129
+ if (hasAddy) {
130
+ if (addy.available) {
131
+ const action = addy.action || "ready";
132
+ const slugs = Array.isArray(addy.resolvedSlugs) ? addy.resolvedSlugs : [];
133
+ lines.push(`- **addyosmani/agent-skills** (process, 1st source): ${esc(action)}` +
134
+ (slugs.length > 0 ? ` — resolved slugs: ${slugs.map((s) => `\`${esc(s)}\``).join(", ")}` : " — no role/task-specific slugs resolved"));
135
+ } else {
136
+ const reason = addy.reason ? ` — ${esc(addy.reason)}` : "";
137
+ lines.push(`- **addyosmani/agent-skills**: unavailable${reason}`);
138
+ }
139
+ }
140
+
141
+ if (installed.length > 0) {
142
+ lines.push(`- **OpenSkills installed**: ${installed.map((s) => `\`${esc(s)}\``).join(", ")}`);
143
+ }
144
+
145
+ if (recommended.length > 0) {
146
+ lines.push(`- **OpenSkills recommended** (CLI missing, would-have-used): ${recommended.map((s) => `\`${esc(s)}\``).join(", ")}`);
147
+ }
148
+
149
+ return lines.join("\n");
150
+ }
151
+
106
152
  function renderJournalLinks(files) {
107
153
  if (!Array.isArray(files) || files.length === 0) return "_No additional journal files._";
108
154
  return files.map((f) => `- [${esc(f)}](./${f})`).join("\n");
@@ -146,6 +192,11 @@ export function buildSummaryMarkdown(input) {
146
192
  sections.push("", "## Budget breakdown (by role)", "", breakdown);
147
193
  }
148
194
 
195
+ const skillsSection = renderSkills(input.skills);
196
+ if (skillsSection) {
197
+ sections.push("", "## Skills Used", "", skillsSection);
198
+ }
199
+
149
200
  sections.push("", "## Commits", "", renderCommits(input.commits));
150
201
 
151
202
  sections.push("", "## Journal files", "", renderJournalLinks(input.files));