karajan-code 1.2.0

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 (98) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +441 -0
  3. package/docs/karajan-code-logo-small.png +0 -0
  4. package/package.json +60 -0
  5. package/scripts/install.js +898 -0
  6. package/scripts/install.sh +7 -0
  7. package/scripts/postinstall.js +117 -0
  8. package/scripts/setup-multi-instance.sh +150 -0
  9. package/src/activity-log.js +59 -0
  10. package/src/agents/aider-agent.js +25 -0
  11. package/src/agents/availability.js +32 -0
  12. package/src/agents/base-agent.js +27 -0
  13. package/src/agents/claude-agent.js +24 -0
  14. package/src/agents/codex-agent.js +27 -0
  15. package/src/agents/gemini-agent.js +25 -0
  16. package/src/agents/index.js +19 -0
  17. package/src/agents/resolve-bin.js +60 -0
  18. package/src/cli.js +200 -0
  19. package/src/commands/code.js +32 -0
  20. package/src/commands/config.js +74 -0
  21. package/src/commands/doctor.js +155 -0
  22. package/src/commands/init.js +181 -0
  23. package/src/commands/plan.js +67 -0
  24. package/src/commands/report.js +340 -0
  25. package/src/commands/resume.js +39 -0
  26. package/src/commands/review.js +26 -0
  27. package/src/commands/roles.js +117 -0
  28. package/src/commands/run.js +91 -0
  29. package/src/commands/scan.js +18 -0
  30. package/src/commands/sonar.js +53 -0
  31. package/src/config.js +322 -0
  32. package/src/git/automation.js +100 -0
  33. package/src/mcp/progress.js +69 -0
  34. package/src/mcp/run-kj.js +87 -0
  35. package/src/mcp/server-handlers.js +259 -0
  36. package/src/mcp/server.js +37 -0
  37. package/src/mcp/tool-arg-normalizers.js +16 -0
  38. package/src/mcp/tools.js +184 -0
  39. package/src/orchestrator.js +1277 -0
  40. package/src/planning-game/adapter.js +105 -0
  41. package/src/planning-game/client.js +81 -0
  42. package/src/prompts/coder.js +60 -0
  43. package/src/prompts/planner.js +26 -0
  44. package/src/prompts/reviewer.js +45 -0
  45. package/src/repeat-detector.js +77 -0
  46. package/src/review/diff-generator.js +22 -0
  47. package/src/review/parser.js +93 -0
  48. package/src/review/profiles.js +66 -0
  49. package/src/review/schema.js +31 -0
  50. package/src/review/tdd-policy.js +57 -0
  51. package/src/roles/base-role.js +127 -0
  52. package/src/roles/coder-role.js +60 -0
  53. package/src/roles/commiter-role.js +94 -0
  54. package/src/roles/index.js +12 -0
  55. package/src/roles/planner-role.js +81 -0
  56. package/src/roles/refactorer-role.js +66 -0
  57. package/src/roles/researcher-role.js +134 -0
  58. package/src/roles/reviewer-role.js +132 -0
  59. package/src/roles/security-role.js +128 -0
  60. package/src/roles/solomon-role.js +199 -0
  61. package/src/roles/sonar-role.js +65 -0
  62. package/src/roles/tester-role.js +114 -0
  63. package/src/roles/triage-role.js +128 -0
  64. package/src/session-store.js +80 -0
  65. package/src/sonar/api.js +78 -0
  66. package/src/sonar/enforcer.js +19 -0
  67. package/src/sonar/manager.js +163 -0
  68. package/src/sonar/project-key.js +83 -0
  69. package/src/sonar/scanner.js +267 -0
  70. package/src/utils/agent-detect.js +32 -0
  71. package/src/utils/budget.js +123 -0
  72. package/src/utils/display.js +346 -0
  73. package/src/utils/events.js +23 -0
  74. package/src/utils/fs.js +19 -0
  75. package/src/utils/git.js +101 -0
  76. package/src/utils/logger.js +86 -0
  77. package/src/utils/paths.js +18 -0
  78. package/src/utils/pricing.js +28 -0
  79. package/src/utils/process.js +67 -0
  80. package/src/utils/wizard.js +41 -0
  81. package/templates/coder-rules.md +24 -0
  82. package/templates/docker-compose.sonar.yml +60 -0
  83. package/templates/kj.config.yml +82 -0
  84. package/templates/review-rules.md +11 -0
  85. package/templates/roles/coder.md +42 -0
  86. package/templates/roles/commiter.md +44 -0
  87. package/templates/roles/planner.md +45 -0
  88. package/templates/roles/refactorer.md +39 -0
  89. package/templates/roles/researcher.md +37 -0
  90. package/templates/roles/reviewer-paranoid.md +38 -0
  91. package/templates/roles/reviewer-relaxed.md +34 -0
  92. package/templates/roles/reviewer-strict.md +37 -0
  93. package/templates/roles/reviewer.md +55 -0
  94. package/templates/roles/security.md +54 -0
  95. package/templates/roles/solomon.md +106 -0
  96. package/templates/roles/sonar.md +49 -0
  97. package/templates/roles/tester.md +41 -0
  98. package/templates/roles/triage.md +25 -0
@@ -0,0 +1,86 @@
1
+ import { EventEmitter } from "node:events";
2
+
3
+ const LEVELS = ["debug", "info", "warn", "error"];
4
+
5
+ const ANSI = {
6
+ reset: "\x1b[0m",
7
+ dim: "\x1b[2m",
8
+ cyan: "\x1b[36m",
9
+ yellow: "\x1b[33m",
10
+ red: "\x1b[31m",
11
+ gray: "\x1b[90m"
12
+ };
13
+
14
+ const LEVEL_COLORS = {
15
+ debug: ANSI.gray,
16
+ info: ANSI.cyan,
17
+ warn: ANSI.yellow,
18
+ error: ANSI.red
19
+ };
20
+
21
+ function timestamp() {
22
+ return new Date().toISOString().slice(11, 23);
23
+ }
24
+
25
+ function formatContext(ctx) {
26
+ const parts = [];
27
+ if (ctx.iteration !== undefined) parts.push(`iter=${ctx.iteration}`);
28
+ if (ctx.stage) parts.push(`stage=${ctx.stage}`);
29
+ return parts.length ? `[${parts.join(" ")}] ` : "";
30
+ }
31
+
32
+ export function createLogger(level = "info", mode = "cli") {
33
+ const min = LEVELS.indexOf(level);
34
+ const minIdx = min === -1 ? 1 : min;
35
+ const emitter = new EventEmitter();
36
+ let context = {};
37
+
38
+ function canLog(target) {
39
+ return LEVELS.indexOf(target) >= minIdx;
40
+ }
41
+
42
+ function emit(lvl, args) {
43
+ const entry = {
44
+ level: lvl,
45
+ timestamp: new Date().toISOString(),
46
+ context: { ...context },
47
+ message: args.map((a) => (typeof a === "string" ? a : JSON.stringify(a))).join(" ")
48
+ };
49
+ emitter.emit("log", entry);
50
+ }
51
+
52
+ function log(lvl, ...args) {
53
+ if (!canLog(lvl)) return;
54
+ emit(lvl, args);
55
+ if (mode === "silent") return;
56
+ if (mode === "mcp") return;
57
+ const color = LEVEL_COLORS[lvl] || "";
58
+ const ts = `${ANSI.dim}${timestamp()}${ANSI.reset}`;
59
+ const prefix = `${color}[${lvl}]${ANSI.reset}`;
60
+ const ctx = formatContext(context);
61
+ const stream = lvl === "error" ? console.error : lvl === "warn" ? console.warn : console.log;
62
+ stream(`${ts} ${prefix} ${ctx}${args.map((a) => (typeof a === "string" ? a : JSON.stringify(a))).join(" ")}`);
63
+ }
64
+
65
+ return {
66
+ debug: (...args) => log("debug", ...args),
67
+ info: (...args) => log("info", ...args),
68
+ warn: (...args) => log("warn", ...args),
69
+ error: (...args) => log("error", ...args),
70
+ setContext(ctx) {
71
+ context = { ...context, ...ctx };
72
+ },
73
+ resetContext() {
74
+ context = {};
75
+ },
76
+ onLog(callback) {
77
+ emitter.on("log", callback);
78
+ },
79
+ offLog(callback) {
80
+ emitter.off("log", callback);
81
+ },
82
+ get mode() {
83
+ return mode;
84
+ }
85
+ };
86
+ }
@@ -0,0 +1,18 @@
1
+ import os from "node:os";
2
+ import path from "node:path";
3
+
4
+ export function getKarajanHome() {
5
+ if (process.env.KJ_HOME) {
6
+ return path.resolve(process.env.KJ_HOME);
7
+ }
8
+
9
+ return path.join(os.homedir(), ".karajan");
10
+ }
11
+
12
+ export function getSessionRoot() {
13
+ return path.join(getKarajanHome(), "sessions");
14
+ }
15
+
16
+ export function getSonarComposePath() {
17
+ return path.join(getKarajanHome(), "docker-compose.sonar.yml");
18
+ }
@@ -0,0 +1,28 @@
1
+ export const DEFAULT_MODEL_PRICING = {
2
+ "claude": { input_per_million: 3, output_per_million: 15 },
3
+ "claude/sonnet": { input_per_million: 3, output_per_million: 15 },
4
+ "claude/opus": { input_per_million: 15, output_per_million: 75 },
5
+ "claude/haiku": { input_per_million: 0.25, output_per_million: 1.25 },
6
+ "codex": { input_per_million: 1.5, output_per_million: 4 },
7
+ "codex/o4-mini": { input_per_million: 1.5, output_per_million: 4 },
8
+ "codex/o3": { input_per_million: 10, output_per_million: 40 },
9
+ "gemini": { input_per_million: 1.25, output_per_million: 5 },
10
+ "gemini/pro": { input_per_million: 1.25, output_per_million: 5 },
11
+ "gemini/flash": { input_per_million: 0.075, output_per_million: 0.3 },
12
+ "aider": { input_per_million: 3, output_per_million: 15 }
13
+ };
14
+
15
+ export function calculateUsageCostUsd({ model, tokens_in, tokens_out, pricing }) {
16
+ const table = pricing || DEFAULT_MODEL_PRICING;
17
+ const entry = table[model] || null;
18
+ if (!entry) return 0;
19
+
20
+ const inputCost = (tokens_in * entry.input_per_million) / 1_000_000;
21
+ const outputCost = (tokens_out * entry.output_per_million) / 1_000_000;
22
+ return inputCost + outputCost;
23
+ }
24
+
25
+ export function mergePricing(defaults, overrides) {
26
+ if (!overrides || typeof overrides !== "object") return { ...defaults };
27
+ return { ...defaults, ...overrides };
28
+ }
@@ -0,0 +1,67 @@
1
+ import { execa } from "execa";
2
+
3
+ export async function runCommand(command, args = [], options = {}) {
4
+ const { timeout, onOutput, ...rest } = options;
5
+ const subprocess = execa(command, args, {
6
+ reject: false,
7
+ ...rest
8
+ });
9
+
10
+ if (onOutput) {
11
+ const handler = (stream) => {
12
+ let partial = "";
13
+ return (chunk) => {
14
+ partial += chunk.toString();
15
+ const lines = partial.split("\n");
16
+ partial = lines.pop();
17
+ for (const line of lines) {
18
+ if (line) onOutput({ stream, line });
19
+ }
20
+ };
21
+ };
22
+ if (subprocess.stdout) subprocess.stdout.on("data", handler("stdout"));
23
+ if (subprocess.stderr) subprocess.stderr.on("data", handler("stderr"));
24
+ }
25
+
26
+ try {
27
+ if (!timeout) {
28
+ return await subprocess;
29
+ }
30
+
31
+ let timer = null;
32
+ const timeoutResult = new Promise((resolve) => {
33
+ timer = setTimeout(() => {
34
+ try {
35
+ subprocess.kill("SIGKILL", { forceKillAfterDelay: 1000 });
36
+ } catch {
37
+ // no-op
38
+ }
39
+ resolve({
40
+ exitCode: 143,
41
+ stdout: "",
42
+ stderr: `Command timed out after ${timeout}ms`
43
+ });
44
+ }, timeout);
45
+ });
46
+
47
+ const result = await Promise.race([subprocess, timeoutResult]);
48
+ if (timer) clearTimeout(timer);
49
+ return result;
50
+ } catch (error) {
51
+ const details = [
52
+ error?.shortMessage,
53
+ error?.originalMessage,
54
+ error?.stderr,
55
+ error?.stdout,
56
+ error?.message
57
+ ]
58
+ .filter(Boolean)
59
+ .join("\n");
60
+
61
+ return {
62
+ exitCode: 1,
63
+ stdout: error?.stdout || "",
64
+ stderr: details || String(error)
65
+ };
66
+ }
67
+ }
@@ -0,0 +1,41 @@
1
+ import readline from "node:readline";
2
+
3
+ export function createWizard(input = process.stdin, output = process.stdout) {
4
+ const rl = readline.createInterface({ input, output });
5
+
6
+ function ask(question) {
7
+ return new Promise((resolve) => {
8
+ rl.question(question, (answer) => resolve(answer.trim()));
9
+ });
10
+ }
11
+
12
+ async function confirm(question, defaultValue = true) {
13
+ const hint = defaultValue ? "[Y/n]" : "[y/N]";
14
+ const answer = await ask(`${question} ${hint} `);
15
+ if (answer === "") return defaultValue;
16
+ return /^y(es)?$/i.test(answer);
17
+ }
18
+
19
+ async function select(question, options) {
20
+ output.write(`${question}\n`);
21
+ for (let i = 0; i < options.length; i++) {
22
+ const opt = options[i];
23
+ const label = opt.available === false ? `${opt.label} (not installed)` : opt.label;
24
+ output.write(` ${i + 1}) ${label}\n`);
25
+ }
26
+ const answer = await ask(`Choose [1-${options.length}]: `);
27
+ const idx = Number(answer) - 1;
28
+ if (idx >= 0 && idx < options.length) return options[idx].value;
29
+ return options[0].value;
30
+ }
31
+
32
+ function close() {
33
+ rl.close();
34
+ }
35
+
36
+ return { ask, confirm, select, close };
37
+ }
38
+
39
+ export function isTTY() {
40
+ return Boolean(process.stdin.isTTY);
41
+ }
@@ -0,0 +1,24 @@
1
+ # Coder Rules
2
+
3
+ ## File modification safety
4
+
5
+ - NEVER overwrite existing files entirely. Always make targeted, minimal edits.
6
+ - When adding new code to an existing file, insert only the new lines at the correct location.
7
+ - After each edit, verify with `git diff` that ONLY the intended lines changed.
8
+ - If unintended changes are detected, revert immediately with `git checkout -- <file>`.
9
+ - Pay special attention to CSS, HTML, and config files where full rewrites destroy prior work (brand colors, layouts, styles).
10
+
11
+ ## Multi-agent / multi-developer environment
12
+
13
+ - Multiple developers and AI agents may be committing and modifying code simultaneously.
14
+ - ALWAYS run `git fetch origin main` and check recent commits before starting work.
15
+ - Before pushing or merging, rebase on the latest main: `git rebase origin/main`.
16
+ - If a commit or push fails, check whether someone else pushed in the meantime.
17
+ - Never assume main is unchanged since the last check — always verify.
18
+ - Create a dedicated branch per task (`feat/` or `fix/`) and merge via PR, never push directly to main.
19
+
20
+ ## General
21
+
22
+ - Keep changes minimal and focused on the task.
23
+ - Do not modify code unrelated to the task.
24
+ - Follow existing code conventions and patterns in the repository.
@@ -0,0 +1,60 @@
1
+ # SonarQube Community Edition + PostgreSQL
2
+ # Karajan Code - Geniova Technologies
3
+ #
4
+ # Prerequisite (Linux):
5
+ # sudo sysctl -w vm.max_map_count=262144
6
+ # echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
7
+ #
8
+ # Usage:
9
+ # docker compose -f docker-compose.sonar.yml up -d
10
+ # Open http://localhost:9000 (admin/admin on first access)
11
+
12
+ services:
13
+ sonarqube:
14
+ image: sonarqube:community
15
+ container_name: karajan-sonarqube
16
+ depends_on:
17
+ sonarqube-db:
18
+ condition: service_healthy
19
+ ports:
20
+ - "9000:9000"
21
+ environment:
22
+ - SONAR_JDBC_URL=jdbc:postgresql://sonarqube-db:5432/sonar
23
+ - SONAR_JDBC_USERNAME=sonar
24
+ - SONAR_JDBC_PASSWORD=sonar
25
+ - SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true
26
+ volumes:
27
+ - sonarqube_data:/opt/sonarqube/data
28
+ - sonarqube_extensions:/opt/sonarqube/extensions
29
+ - sonarqube_logs:/opt/sonarqube/logs
30
+ networks:
31
+ - sonarnet
32
+ restart: unless-stopped
33
+
34
+ sonarqube-db:
35
+ image: postgres:17
36
+ container_name: karajan-sonarqube-db
37
+ healthcheck:
38
+ test: ["CMD-SHELL", "pg_isready -U sonar"]
39
+ interval: 10s
40
+ timeout: 5s
41
+ retries: 5
42
+ environment:
43
+ - POSTGRES_USER=sonar
44
+ - POSTGRES_PASSWORD=sonar
45
+ - POSTGRES_DB=sonar
46
+ volumes:
47
+ - postgresql_data:/var/lib/postgresql/data
48
+ networks:
49
+ - sonarnet
50
+ restart: unless-stopped
51
+
52
+ volumes:
53
+ sonarqube_data:
54
+ sonarqube_extensions:
55
+ sonarqube_logs:
56
+ postgresql_data:
57
+
58
+ networks:
59
+ sonarnet:
60
+ driver: bridge
@@ -0,0 +1,82 @@
1
+ # AI Agents
2
+ coder: claude
3
+ reviewer: codex
4
+
5
+ # Review settings
6
+ review_mode: standard
7
+ max_iterations: 5
8
+ review_rules: ./review-rules.md
9
+ coder_rules: ./coder-rules.md
10
+ base_branch: main
11
+
12
+ # Coder settings
13
+ coder_options:
14
+ model: null
15
+ auto_approve: true
16
+
17
+ # Reviewer settings
18
+ reviewer_options:
19
+ output_format: json
20
+ require_schema: true
21
+ model: null
22
+ deterministic: true
23
+ retries: 1
24
+ fallback_reviewer: codex
25
+
26
+ # Development methodology
27
+ development:
28
+ methodology: tdd
29
+ require_test_changes: true
30
+ test_file_patterns:
31
+ - /tests/
32
+ - /__tests__/
33
+ - .test.
34
+ - .spec.
35
+
36
+ # SonarQube settings
37
+ sonarqube:
38
+ enabled: true
39
+ host: http://localhost:9000
40
+ token: null
41
+ quality_gate: true
42
+ enforcement_profile: pragmatic
43
+ gate_block_on:
44
+ - new_reliability_rating=E
45
+ - new_security_rating=E
46
+ - new_maintainability_rating=E
47
+ - new_coverage<80
48
+ - new_duplicated_lines_density>5
49
+ fail_on:
50
+ - BLOCKER
51
+ - CRITICAL
52
+ ignore_on:
53
+ - INFO
54
+ max_scan_retries: 3
55
+ scanner:
56
+ sources: "src,public,lib"
57
+ exclusions: "**/node_modules/**,**/fake-apps/**,**/scripts/**,**/playground/**,**/dist/**,**/build/**,**/*.min.js"
58
+ test_inclusions: "**/*.test.js,**/*.spec.js,**/tests/**,**/__tests__/**"
59
+ coverage_exclusions: "**/tests/**,**/__tests__/**,**/*.test.js,**/*.spec.js"
60
+ disabled_rules:
61
+ - "javascript:S1116"
62
+ - "javascript:S3776"
63
+
64
+ # Git (post-approval)
65
+ git:
66
+ auto_commit: false
67
+ auto_push: false
68
+ auto_pr: false
69
+ auto_rebase: true
70
+ branch_prefix: feat/
71
+
72
+ # Output
73
+ output:
74
+ report_dir: ./.reviews
75
+ log_level: info
76
+
77
+ # Session limits
78
+ session:
79
+ max_iteration_minutes: 15
80
+ max_total_minutes: 120
81
+ max_budget_usd: null
82
+ fail_fast_repeats: 2
@@ -0,0 +1,11 @@
1
+ # Review Rules
2
+
3
+ - Focus on security, correctness, and tests first.
4
+ - Only raise blocking issues for concrete production risks.
5
+ - Keep non-blocking suggestions separate.
6
+
7
+ ## File overwrite detection (BLOCKING)
8
+
9
+ - If the diff shows an entire file was replaced (massive deletions + additions instead of targeted edits), flag it as BLOCKING.
10
+ - Check specifically for: reverted brand colors, lost CSS styles, removed existing functionality, overwritten config values.
11
+ - A diff where most lines of a file are removed and re-added with minor changes is a sign of full-file overwrite.
@@ -0,0 +1,42 @@
1
+ # Coder Role
2
+
3
+ You are the **Coder** in a multi-role AI pipeline. Your job is to write code and tests that fulfill the given task.
4
+
5
+ ## Constraints
6
+
7
+ - Follow TDD methodology when `methodology=tdd` is configured.
8
+ - Write tests BEFORE implementation when using TDD.
9
+ - Keep changes minimal and focused on the task.
10
+ - Do not modify code unrelated to the task.
11
+ - Follow existing code conventions and patterns in the repository.
12
+
13
+ ## File modification safety
14
+
15
+ - NEVER overwrite existing files entirely. Always make targeted, minimal edits.
16
+ - When adding new code to an existing file, insert only the new lines at the correct location.
17
+ - After each edit, verify with `git diff` that ONLY the intended lines changed.
18
+ - If unintended changes are detected, revert immediately with `git checkout -- <file>`.
19
+ - Pay special attention to CSS, HTML, and config files where full rewrites destroy prior work.
20
+
21
+ ## Multi-agent environment
22
+
23
+ - Multiple developers and AI agents may be committing and modifying code simultaneously.
24
+ - ALWAYS run `git fetch origin main` and check recent commits before starting work.
25
+ - Before pushing or merging, rebase on the latest main: `git rebase origin/main`.
26
+ - Create a dedicated branch per task and merge via PR, never push directly to main.
27
+
28
+ ## Output format
29
+
30
+ Return a JSON object:
31
+ ```json
32
+ {
33
+ "ok": true,
34
+ "result": {
35
+ "files_modified": ["path/to/file.js"],
36
+ "files_created": ["path/to/new-file.js"],
37
+ "tests_added": ["path/to/test.js"],
38
+ "approach": "Brief description of what was done"
39
+ },
40
+ "summary": "Human-readable summary of changes"
41
+ }
42
+ ```
@@ -0,0 +1,44 @@
1
+ # Commiter Role
2
+
3
+ You are the **Commiter** in a multi-role AI pipeline. Your job is to handle all git operations: commits, branches, pushes, and pull requests.
4
+
5
+ ## Rules
6
+
7
+ ### Commit messages
8
+ - Follow **Conventional Commits**: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:`
9
+ - First line < 70 characters
10
+ - NEVER include references to AI, Claude, Copilot, or any AI tool in commit messages
11
+ - Be specific: "fix: prevent null pointer in user lookup" not "fix: bug fix"
12
+
13
+ ### Branching
14
+ - One branch per task: `feat/{CARD-ID}-description` or `fix/{CARD-ID}-description`
15
+ - Always branch from latest main
16
+ - Never push directly to main
17
+
18
+ ### Commits
19
+ - Atomic commits: one logical change per commit
20
+ - Each commit should compile and pass tests on its own
21
+ - Maximum ~300 lines changed per PR (ideal < 200)
22
+
23
+ ### Pull requests
24
+ - One PR per task/bug
25
+ - Title < 70 characters
26
+ - Description includes: summary, test plan
27
+ - NEVER include AI references in PR descriptions
28
+
29
+ ## Output format
30
+
31
+ ```json
32
+ {
33
+ "ok": true,
34
+ "result": {
35
+ "branch": "feat/KJC-TSK-0042-add-widget",
36
+ "commits": [
37
+ { "hash": "abc1234", "message": "feat: add widget base class" }
38
+ ],
39
+ "pr_url": "https://github.com/org/repo/pull/42",
40
+ "pr_number": 42
41
+ },
42
+ "summary": "Created PR #42 with 1 commit on branch feat/KJC-TSK-0042-add-widget"
43
+ }
44
+ ```
@@ -0,0 +1,45 @@
1
+ # Planner Role
2
+
3
+ You are the **Planner** in a multi-role AI pipeline. Your job is to create an implementation plan based on the task requirements and research findings.
4
+
5
+ ## When activated
6
+
7
+ - Tasks with `devPoints >= 3`
8
+ - Tasks affecting more than 2 files
9
+ - Tasks requiring architectural decisions
10
+
11
+ ## Plan structure
12
+
13
+ 1. **Approach** — High-level strategy (1-2 sentences)
14
+ 2. **Steps** — Ordered list of implementation steps (1 step = 1 commit ideally)
15
+ 3. **Data model changes** — Any schema/model modifications
16
+ 4. **API changes** — New or modified endpoints/interfaces
17
+ 5. **Risks** — What could go wrong, mitigation strategies
18
+ 6. **Out of scope** — What this task explicitly does NOT cover
19
+
20
+ ## Rules
21
+
22
+ - Each step should be small and independently verifiable.
23
+ - Identify the testing strategy (unit, integration, E2E).
24
+ - Consider backward compatibility.
25
+ - Reference research findings when available.
26
+
27
+ ## Output format
28
+
29
+ ```json
30
+ {
31
+ "ok": true,
32
+ "result": {
33
+ "approach": "Add new module with factory pattern, integrate into orchestrator",
34
+ "steps": [
35
+ { "order": 1, "description": "Create BaseWidget class", "files": ["src/widgets/base.js"] },
36
+ { "order": 2, "description": "Add unit tests", "files": ["tests/base-widget.test.js"] }
37
+ ],
38
+ "data_model_changes": [],
39
+ "api_changes": [],
40
+ "risks": ["Changing orchestrator loop may affect existing flows"],
41
+ "out_of_scope": ["UI changes", "Migration of existing widgets"]
42
+ },
43
+ "summary": "Plan: 4 steps, estimated 2 files modified, 1 new file"
44
+ }
45
+ ```
@@ -0,0 +1,39 @@
1
+ # Refactorer Role
2
+
3
+ You are the **Refactorer** in a multi-role AI pipeline. Your job is to improve code clarity, structure, and maintainability without changing external behavior.
4
+
5
+ ## Constraints
6
+
7
+ - Do NOT change any observable behavior or API contracts.
8
+ - Do NOT expand the scope of changes beyond what was already modified.
9
+ - Keep all existing tests passing — run tests after every change.
10
+ - Follow existing code conventions and patterns in the repository.
11
+ - Do NOT add new features or fix unrelated bugs.
12
+
13
+ ## Focus areas
14
+
15
+ 1. **Naming** — Rename variables, functions, and classes for clarity.
16
+ 2. **Structure** — Extract functions, reduce nesting, simplify conditionals.
17
+ 3. **Duplication** — Eliminate repeated code with shared helpers.
18
+ 4. **Readability** — Improve flow, reduce cognitive complexity.
19
+ 5. **Dead code** — Remove unused imports, variables, and unreachable branches.
20
+
21
+ ## File modification safety
22
+
23
+ - NEVER overwrite existing files entirely. Always make targeted, minimal edits.
24
+ - After each edit, verify with `git diff` that ONLY the intended lines changed.
25
+ - If unintended changes are detected, revert immediately with `git checkout -- <file>`.
26
+
27
+ ## Output format
28
+
29
+ ```json
30
+ {
31
+ "ok": true,
32
+ "result": {
33
+ "files_modified": ["src/module.js"],
34
+ "changes": ["Extracted helper function", "Renamed variable for clarity"],
35
+ "tests_status": "all passing"
36
+ },
37
+ "summary": "Refactored 2 files: extracted helper, improved naming"
38
+ }
39
+ ```
@@ -0,0 +1,37 @@
1
+ # Researcher Role
2
+
3
+ You are the **Researcher** in a multi-role AI pipeline. Your job is to investigate the codebase, architecture, dependencies, and existing patterns before planning or coding begins.
4
+
5
+ ## Responsibilities
6
+
7
+ - Analyze the project structure and identify relevant files for the task.
8
+ - Identify existing patterns, conventions, and architectural decisions.
9
+ - Find prior implementations of similar features.
10
+ - Document constraints, dependencies, and potential risks.
11
+ - Review ADRs and documentation for context.
12
+
13
+ ## What to investigate
14
+
15
+ 1. **Affected files** — Which files will need changes?
16
+ 2. **Dependencies** — What modules/packages are involved?
17
+ 3. **Patterns** — What conventions does the codebase follow?
18
+ 4. **Prior decisions** — Are there ADRs or comments explaining design choices?
19
+ 5. **Test coverage** — What tests exist for the affected area?
20
+ 6. **Risks** — What could break? What are the edge cases?
21
+
22
+ ## Output format
23
+
24
+ ```json
25
+ {
26
+ "ok": true,
27
+ "result": {
28
+ "affected_files": ["src/module.js", "tests/module.test.js"],
29
+ "patterns": ["Uses factory pattern for agents", "ES modules throughout"],
30
+ "constraints": ["Must maintain backward compatibility with config.yml"],
31
+ "prior_decisions": ["ADR-001 defines role-based architecture"],
32
+ "risks": ["Changing X may break Y"],
33
+ "test_coverage": "Module has 80% coverage, missing edge case tests"
34
+ },
35
+ "summary": "Research complete: 5 files affected, 2 risks identified"
36
+ }
37
+ ```
@@ -0,0 +1,38 @@
1
+ # Reviewer Role — Paranoid Mode
2
+
3
+ You are the **Reviewer** in paranoid mode. Every change is suspect until proven safe. Be extremely thorough.
4
+
5
+ ## Review priorities (in order)
6
+
7
+ 1. **Security** — treat every input as hostile; check for injection, SSRF, path traversal, prototype pollution, secret leaks
8
+ 2. **Correctness** — trace every code path; verify edge cases, null/undefined, integer overflow, race conditions
9
+ 3. **Tests** — demand high coverage; reject if critical paths lack assertions
10
+ 4. **Data integrity** — validate schemas, migrations, backwards compatibility
11
+ 5. **Architecture** — coupling, abstraction leaks, violation of established patterns
12
+ 6. **Style** — flag inconsistencies that could hide bugs
13
+
14
+ ## Rules
15
+
16
+ - **Default to rejection.** Approve only when you are highly confident there are zero risks.
17
+ - Flag any file that was entirely replaced (not surgically edited) as BLOCKING.
18
+ - Flag missing error handling as BLOCKING.
19
+ - Flag missing input validation as BLOCKING.
20
+ - Require explicit tests for every new public function.
21
+ - If confidence < 0.85, reject and explain what you cannot verify.
22
+ - Style issues are BLOCKING only when they obscure logic (ambiguous names, deeply nested ternaries).
23
+
24
+ ## Output format
25
+
26
+ Return a strict JSON object:
27
+ ```json
28
+ {
29
+ "ok": true,
30
+ "result": {
31
+ "approved": boolean,
32
+ "blocking_issues": [],
33
+ "non_blocking_suggestions": [],
34
+ "confidence": number,
35
+ "summary": "string"
36
+ }
37
+ }
38
+ ```