tribunal-kit 5.8.1 → 5.8.3

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.
@@ -21,7 +21,7 @@ You are a specialist in analyzing test output — not writing tests, but _unders
21
21
  - After a test run with multiple failures.
22
22
  - When the user says "tests are failing", "analyze test results", "what broke?", or "test failed".
23
23
  - During CI/CD pipeline debugging.
24
- - When `test_runner.py` or any test command exits with failures.
24
+ - When `test_runner.js` or any test command exits with failures.
25
25
  - When paired with `systematic-debugging` for deep root-cause investigation.
26
26
 
27
27
  ## Analysis Pipeline
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Auto-fix known issues with lint, formatting, imports, and TypeScript errors. Runs lint_runner.py and auto-fixers. Human approval required before applying any changes. Shows a diff of what will change before writing to disk.
2
+ description: Auto-fix known issues with lint, formatting, imports, and TypeScript errors. Runs lint_runner.js and auto-fixers. Human approval required before applying any changes. Shows a diff of what will change before writing to disk.
3
3
  required-skills: lint-and-validate, clean-code
4
4
  ---
5
5
 
@@ -55,7 +55,7 @@ Read BEFORE fixing:
55
55
 
56
56
  ```bash
57
57
  # 1. Run lint with auto-fix
58
- python .agent/scripts/lint_runner.py . --fix
58
+ node .agent/scripts/lint_runner.js . --fix
59
59
 
60
60
  # 2. Fix remaining TypeScript errors (auto-detectable only)
61
61
  npx tsc --noEmit 2>&1 | grep "error TS"
@@ -128,7 +128,7 @@ complexity-reviewer→ Enforces the Dependency Ladder to prevent over-engineerin
128
128
  | `aria`, `wcag`, `a11y`, `accessibility` | `accessibility-reviewer` + `ui-ux-auditor` |
129
129
  | `import`, `package`, `npm`, `require` | `dependency-reviewer` |
130
130
 
131
- > For maximum safety on critical code: use `/tribunal-full` for all 19 reviewers simultaneously.
131
+ > For maximum safety on critical code: use `/tribunal-full` for all 20 reviewers simultaneously.
132
132
 
133
133
  ---
134
134
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Preview server start, stop, and status check. Local development server management. Uses auto_preview.py for automated lifecycle control. Shows current URL and hot-reload status.
2
+ description: Preview server start, stop, and status check. Local development server management. Uses auto_preview.js for automated lifecycle control. Shows current URL and hot-reload status.
3
3
  required-skills: bash-linux, frontend-specialist
4
4
  ---
5
5
 
@@ -34,16 +34,16 @@ Read BEFORE managing preview:
34
34
 
35
35
  ```bash
36
36
  # Start
37
- python .agent/scripts/auto_preview.py start
37
+ node .agent/scripts/auto_preview.js start
38
38
 
39
39
  # Stop
40
- python .agent/scripts/auto_preview.py stop
40
+ node .agent/scripts/auto_preview.js stop
41
41
 
42
42
  # Restart
43
- python .agent/scripts/auto_preview.py restart
43
+ node .agent/scripts/auto_preview.js restart
44
44
 
45
45
  # Status
46
- python .agent/scripts/auto_preview.py status
46
+ node .agent/scripts/auto_preview.js status
47
47
  ```
48
48
 
49
49
  ---
@@ -44,7 +44,7 @@ git log --oneline -5
44
44
  find src/ -name "*.ts" -o -name "*.tsx" -newer package.json 2>/dev/null | head -10
45
45
 
46
46
  # 4. Server status (non-blocking)
47
- python .agent/scripts/auto_preview.py status 2>/dev/null
47
+ node .agent/scripts/auto_preview.js status 2>/dev/null
48
48
 
49
49
  # 5. Quick type check
50
50
  npx tsc --noEmit 2>&1 | tail -5
@@ -68,7 +68,7 @@ Tier 4: Performance Swarm (token-scoped specialists)
68
68
 
69
69
  ## Active Reviewers by Code Type
70
70
 
71
- Not all 19 reviewers produce meaningful findings on all code types. Active reviewers detect their first finding immediately — inactive reviewers auto-pass with "N/A for this code type."
71
+ Not all 20 reviewers produce meaningful findings on all code types. Active reviewers detect their first finding immediately — inactive reviewers auto-pass with "N/A for this code type."
72
72
 
73
73
  | Code Under Review | Critical Reviewers |
74
74
  | :------------------ | :---------------------------------------------------------------- |
@@ -86,7 +86,7 @@ Not all 19 reviewers produce meaningful findings on all code types. Active revie
86
86
  ## Verdict Aggregation
87
87
 
88
88
  ```
89
- All 19 verdicts are collected. Aggregated result:
89
+ All 20 verdicts are collected. Aggregated result:
90
90
 
91
91
  If ANY reviewer = ❌ REJECTED → Global verdict: ❌ REJECTED (must fix before Human Gate)
92
92
  If any reviewer = ⚠️ WARNING → Global verdict: ⚠️ WARNINGS (proceed with attention)
@@ -124,7 +124,7 @@ After 3 failed attempts:
124
124
 
125
125
  | Outcome | Next Command |
126
126
  | :------------------------- | :--------------------------------------------- |
127
- | All 19 reviewers approve | → `/deploy` — highest confidence state |
127
+ | All 20 reviewers approve | → `/deploy` — highest confidence state |
128
128
  | Reject with multiple fixes | → `/fix` for simple issues, `/debug` for logic |
129
129
  | Performance rejection | → `/tribunal-speed` for granular profiling |
130
130
  | Security rejection | → Immediate `/tribunal-backend` to resolve |
@@ -181,7 +181,7 @@ If a specialist fails after 3 retries:
181
181
  | :------------------------- | :------------------------------- | :--------------------- | :--------------------------------------- |
182
182
  | `/tribunal-performance` | logic + performance-reviewer | Generic CWV check | Quick single-file perf scan |
183
183
  | `/tribunal-speed` | vitals + db-latency + throughput | Deep 3-domain parallel | Full-stack perf audit |
184
- | `/tribunal-full` | All 19 agents | Everything | Maximum coverage (security + perf + all) |
184
+ | `/tribunal-full` | All 20 agents | Everything | Maximum coverage (security + perf + all) |
185
185
  | `/performance-benchmarker` | Lighthouse + bundle | Measurement only | Get actual scores, not code review |
186
186
 
187
187
  ---
@@ -0,0 +1,134 @@
1
+ # Contributing to Tribunal Kit
2
+
3
+ Thank you for your interest in contributing to Tribunal Kit! This guide will help you get started.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # Clone the repository
9
+ git clone https://github.com/Harmitx7/tribunal-kit.git
10
+ cd tribunal-kit
11
+
12
+ # Install dependencies
13
+ npm install
14
+
15
+ # Run tests
16
+ npm run test:unit
17
+
18
+ # Run the CLI locally
19
+ node bin/wrapper.js --help
20
+ ```
21
+
22
+ ## Development Setup
23
+
24
+ ### Prerequisites
25
+
26
+ - **Node.js** >= 18.0.0 (LTS recommended)
27
+ - **npm** >= 9
28
+ - **Rust** (optional) — Only needed if modifying the Rust core engine in `crates/`
29
+
30
+ ### Project Structure
31
+
32
+ ```
33
+ tribunal-kit/
34
+ ├── bin/ # CLI entry points (JS monolith + MCP server)
35
+ │ ├── wrapper.js # Main entry: routes to Rust binary or JS fallback
36
+ │ ├── tribunal-kit.js # Legacy JS CLI (1,500+ lines)
37
+ │ └── mcp-server.js # MCP server over JSON-RPC 2.0 / stdio
38
+ ├── dist/ # Modular CLI (lazy-loaded commands)
39
+ │ ├── cli.js # CLI core with command routing
40
+ │ ├── commands/ # Individual command modules
41
+ │ ├── utils/ # Logger, helpers, version checker, hasher
42
+ │ └── index.d.ts # TypeScript declarations
43
+ ├── crates/core/ # Rust core engine (Tokio-based)
44
+ ├── .agent/ # The intelligence payload (agents, skills, workflows)
45
+ │ ├── agents/ # 43 specialist agent definitions
46
+ │ ├── skills/ # Reusable skill packs
47
+ │ ├── workflows/ # 34 workflow definitions
48
+ │ └── scripts/ # Automation scripts
49
+ ├── test/
50
+ │ ├── unit/ # Unit tests (Jest)
51
+ │ └── integration/ # Integration tests
52
+ └── scripts/ # Build & release scripts
53
+ ```
54
+
55
+ ### Running Tests
56
+
57
+ ```bash
58
+ # Unit tests with coverage
59
+ npm run test:unit
60
+
61
+ # All tests
62
+ npm test
63
+
64
+ # Run a specific test file
65
+ npx jest test/unit/memory.test.js
66
+ ```
67
+
68
+ ### Building the Rust Core (Optional)
69
+
70
+ ```bash
71
+ # Build in release mode
72
+ cargo build --release
73
+
74
+ # Run benchmarks comparing Rust vs JS
75
+ npm run benchmark:rust
76
+ ```
77
+
78
+ ## How to Contribute
79
+
80
+ ### Reporting Bugs
81
+
82
+ 1. Check [existing issues](https://github.com/Harmitx7/tribunal-kit/issues) first
83
+ 2. Use the bug report template
84
+ 3. Include: Node.js version, OS, steps to reproduce, expected vs actual behavior
85
+
86
+ ### Suggesting Features
87
+
88
+ 1. Open a [GitHub Discussion](https://github.com/Harmitx7/tribunal-kit/discussions) first
89
+ 2. Describe the use case, not just the solution
90
+ 3. Be specific about which command or workflow this affects
91
+
92
+ ### Submitting Pull Requests
93
+
94
+ 1. **Fork** the repository and create a branch from `main`
95
+ 2. **Write tests** for any new functionality
96
+ 3. **Run the test suite** — all tests must pass: `npm run test:unit`
97
+ 4. **Follow existing code style** — the project uses ESLint
98
+ 5. **Write clear commit messages** following [Conventional Commits](https://www.conventionalcommits.org/):
99
+ ```
100
+ feat: add --json flag to status command
101
+ fix: handle symlinks in init --force
102
+ docs: update CLI reference for memory command
103
+ test: add coverage for marathon harness
104
+ ```
105
+ 6. **Open a PR** with a clear description of what changed and why
106
+
107
+ ### Contributing Agents or Skills
108
+
109
+ Tribunal Kit's value comes from its agent and skill library. To contribute:
110
+
111
+ 1. **Agents** go in `.agent/agents/` as markdown files
112
+ 2. **Skills** go in `.agent/skills/<skill-name>/SKILL.md`
113
+ 3. Follow the existing format — check any existing agent/skill for the structure
114
+ 4. Include the YAML frontmatter (`name`, `description`)
115
+ 5. Add practical, non-obvious guidance — not generic advice
116
+
117
+ ### Code Style
118
+
119
+ - **JavaScript**: CommonJS (`require`/`module.exports`), no transpilation needed
120
+ - **Naming**: `camelCase` for functions/variables, `UPPER_SNAKE` for constants
121
+ - **Error handling**: Always handle errors in async functions
122
+ - **Comments**: Explain *why*, not *what*
123
+ - **No new dependencies**: Zero production dependencies is a feature, not a limitation
124
+
125
+ ## Review Process
126
+
127
+ 1. All PRs are reviewed by a maintainer
128
+ 2. CI must pass (tests + lint)
129
+ 3. Changes to `.agent/` content are reviewed for accuracy and usefulness
130
+ 4. Breaking changes require a discussion before implementation
131
+
132
+ ## License
133
+
134
+ By contributing, you agree that your contributions will be licensed under the [MIT License](LICENSE).
package/SECURITY.md ADDED
@@ -0,0 +1,52 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ | Version | Supported |
6
+ | ------- | ------------------ |
7
+ | 5.x | ✅ Active support |
8
+ | 4.x | ⚠️ Critical fixes only |
9
+ | < 4.0 | ❌ End of life |
10
+
11
+ ## Reporting a Vulnerability
12
+
13
+ **Do not open a public GitHub issue for security vulnerabilities.**
14
+
15
+ Instead, please report vulnerabilities privately using one of these methods:
16
+
17
+ 1. **GitHub Security Advisory** (preferred): Use [GitHub's private vulnerability reporting](https://github.com/Harmitx7/tribunal-kit/security/advisories/new) to submit a confidential report.
18
+
19
+ 2. **Email**: Send details to the maintainer via the email listed in the npm package.
20
+
21
+ ### What to include
22
+
23
+ - Description of the vulnerability
24
+ - Steps to reproduce
25
+ - Affected versions
26
+ - Potential impact
27
+ - Suggested fix (if any)
28
+
29
+ ### Response timeline
30
+
31
+ | Action | Timeline |
32
+ | --- | --- |
33
+ | Acknowledgment | Within 48 hours |
34
+ | Initial assessment | Within 5 business days |
35
+ | Fix release (critical) | Within 7 days |
36
+ | Fix release (moderate) | Within 30 days |
37
+
38
+ ## Security Design
39
+
40
+ Tribunal Kit follows these security principles:
41
+
42
+ - **No network requests at runtime** — The CLI operates entirely offline. The only network call is an optional npm registry version check during `init`/`update`, which can be skipped with `--skip-update-check`.
43
+ - **No code execution from user input** — CLI arguments are parsed without `eval()` or shell interpolation. All subprocess spawning uses array-based arguments (never string concatenation).
44
+ - **No secrets stored** — Tribunal Kit does not store, read, or transmit API keys, tokens, or credentials.
45
+ - **Minimal dependencies** — Zero production dependencies. Only `jest`, `eslint`, and `typescript` as devDependencies.
46
+ - **Platform binaries are optional** — The Rust core binary is distributed as optional dependencies. The CLI falls back to pure JavaScript if binaries are unavailable.
47
+
48
+ ## Supply Chain
49
+
50
+ - All releases are published from CI via GitHub Actions
51
+ - Platform binaries are built in GitHub-hosted runners with pinned action versions
52
+ - The package uses `npm provenance` for verifiable supply chain attestation
@@ -158,6 +158,34 @@ function parseArgs(argv) {
158
158
  if (arg.startsWith("--branch=")) {
159
159
  args.flags.branch = arg.split("=").slice(1).join("=");
160
160
  }
161
+ if (arg.startsWith("--log=")) {
162
+ args.flags.log = arg.split("=").slice(1).join("=");
163
+ }
164
+ if (arg === "--log") {
165
+ const idx = raw.indexOf("--log");
166
+ const nextVal = raw[idx + 1];
167
+ if (!nextVal || nextVal.startsWith("--")) {
168
+ console.error(
169
+ ` \x1b[91m✖ --log requires a file path argument\x1b[0m`,
170
+ );
171
+ process.exit(1);
172
+ }
173
+ args.flags.log = nextVal;
174
+ }
175
+ if (arg.startsWith("--strategy=")) {
176
+ args.flags.strategy = arg.split("=").slice(1).join("=");
177
+ }
178
+ if (arg === "--strategy") {
179
+ const idx = raw.indexOf("--strategy");
180
+ const nextVal = raw[idx + 1];
181
+ if (!nextVal || nextVal.startsWith("--")) {
182
+ console.error(
183
+ ` \x1b[91m✖ --strategy requires a strategy value (balanced/harden/repair-only)\x1b[0m`,
184
+ );
185
+ process.exit(1);
186
+ }
187
+ args.flags.strategy = nextVal;
188
+ }
161
189
  }
162
190
 
163
191
  return args;
@@ -412,8 +440,19 @@ function banner() {
412
440
  const _maxLen = Math.max(...art.map((line) => line.length));
413
441
  for (const line of art) {
414
442
  let gradientLine = " " + C.bold;
415
- for (let i = 0; i < line.length; i++) {
416
- gradientLine += `\x1b[38;2;255;22;55m${line[i]}`;
443
+ const len = line.length;
444
+ for (let i = 0; i < len; i++) {
445
+ const char = line[i];
446
+ if (char === ' ') {
447
+ gradientLine += ' ';
448
+ continue;
449
+ }
450
+ // Horizontal gradient: flame red (left) to coral/orange (right)
451
+ const ratio = i / len;
452
+ const r = 255;
453
+ const g = Math.floor(30 + ratio * 100);
454
+ const b = Math.floor(60 - ratio * 40);
455
+ gradientLine += `\x1b[38;2;${r};${g};${b}m${char}`;
417
456
  }
418
457
  gradientLine += C.reset;
419
458
  log(gradientLine);
@@ -421,16 +460,13 @@ function banner() {
421
460
  console.log();
422
461
  // Subtitle strip
423
462
  const W = 84;
424
- const sub = "Anti-Hallucination Agent System";
425
- const sp = Math.max(0, W - sub.length);
426
- const centred =
427
- " ".repeat(Math.floor(sp / 2)) + sub + " ".repeat(Math.ceil(sp / 2));
428
- const RED_ANSI = "\x1b[38;2;255;22;55m";
429
- console.log(` ${RED_ANSI}╔${"═".repeat(W)}╗${C.reset}`);
430
- console.log(
431
- ` ${RED_ANSI}║${C.reset}${c("gray", centred)}${RED_ANSI}║${C.reset}`,
432
- );
433
- console.log(` ${RED_ANSI}╚${"═".repeat(W)}╝${C.reset}`);
463
+ const plainSub = '🛡️ ANTI-HALLUCINATION AGENT SYSTEM';
464
+ const coloredSub = `${bold(c('white', '🛡️ ANTI-HALLUCINATION AGENT SYSTEM'))}`;
465
+ const sp = Math.max(0, W - plainSub.length);
466
+ const centred = ' '.repeat(Math.floor(sp / 2)) + coloredSub + ' '.repeat(Math.ceil(sp / 2));
467
+ log(` ${c('gray', `✦ ${'━'.repeat(W - 6)} ✦`)}`);
468
+ log(` ${centred}`);
469
+ log(` ${c('gray', `✦ ${'━'.repeat(W - 6)} ✦`)}`);
434
470
  console.log();
435
471
  }
436
472
 
@@ -560,6 +596,7 @@ async function cmdInit(flags) {
560
596
  } else {
561
597
  // ── Success card — W=62, rows padded by plain-text length ──
562
598
  const W = 62;
599
+ const borderCol = "red";
563
600
  const agentsCount = fs.readdirSync(path.join(agentDest, "agents")).length;
564
601
  const workflowsCount = fs.readdirSync(
565
602
  path.join(agentDest, "workflows"),
@@ -569,23 +606,28 @@ async function cmdInit(flags) {
569
606
  path.join(agentDest, "scripts"),
570
607
  ).length;
571
608
 
572
- // Stat rows: compute trailing spaces from plain text so right ║ aligns
573
- const statRow = (icon, label, val, col) => {
574
- // emoji JS .length===2 == terminal display width 2 ✓
575
- const plain = ` ${icon} ${label.padEnd(10)}${String(val).padStart(3)} installed`;
576
- const trail = " ".repeat(Math.max(0, W - plain.length));
577
- return ` ${c("cyan", "║")} ${icon} ${c("white", label.padEnd(10))}${c(col, String(val).padStart(3))} ${c("gray", "installed")}${trail}${c("cyan", "║")}`;
609
+ const drawRow = (plainText, styledText) => {
610
+ const trail = " ".repeat(Math.max(0, W - plainText.length));
611
+ return ` ${c(borderCol, "│")}${styledText}${trail}${c(borderCol, "│")}`;
578
612
  };
579
- // Plain-text rows (header / blank)
580
- const plainRow = (text, wrapFn) => {
581
- const trail = " ".repeat(Math.max(0, W - text.length));
582
- return ` ${c("cyan", "║")}${wrapFn(text)}${trail}${c("cyan", "║")}`;
613
+
614
+ const compRow = (icon, label, count, color) => {
615
+ const leftPlain = ` ${icon} ${label.padEnd(10)} `;
616
+ const rightPlain = ` [ ${String(count).padStart(3)} ]`;
617
+ const numDots = W - leftPlain.length - rightPlain.length - 4; // 4 spaces margin
618
+ const dots = ".".repeat(Math.max(0, numDots));
619
+
620
+ const plain = `${leftPlain}${dots}${rightPlain}`;
621
+ const styled = ` ${icon} ${c("white", label.padEnd(10))} ${c("gray", dots)} ${c("gray", "[")} ${c(color, String(count).padStart(3))} ${c("gray", "]")}`;
622
+ return drawRow(plain, styled);
583
623
  };
584
- // Next-step rows: fixed cmd column + description
624
+
585
625
  const stepRow = (cmd, desc) => {
586
- const plain = ` ${cmd.padEnd(16)}${desc}`;
587
- const trail = " ".repeat(Math.max(0, W - plain.length));
588
- return ` ${c("cyan", "║")} ${c("white", cmd.padEnd(16))}${c("gray", desc)}${trail}${c("cyan", "║")}`;
626
+ const leftPlain = ` ${cmd.padEnd(16)}`;
627
+ const rightPlain = `▸ ${desc}`;
628
+ const plain = `${leftPlain}${rightPlain}`;
629
+ const styled = ` ${c("white", cmd.padEnd(16))}${c("gray", "▸")} ${c("gray", desc)}`;
630
+ return drawRow(plain, styled);
589
631
  };
590
632
 
591
633
  console.log(
@@ -593,27 +635,25 @@ async function cmdInit(flags) {
593
635
  );
594
636
  console.log(` ${c("gray", " ╰─")} ${c("gray", agentDest)}`);
595
637
  console.log();
596
- console.log(` ${c("cyan", "" + "".repeat(W) + "")}`);
597
- console.log(
598
- plainRow(` What's inside:`, (s) => c("bold", c("white", s))),
599
- );
600
- console.log(` ${c("cyan", "" + "".repeat(W) + "")}`);
601
- console.log(statRow("🤖", "Agents", agentsCount, "magenta"));
602
- console.log(statRow("", "Workflows", workflowsCount, "yellow"));
603
- console.log(statRow("🧠", "Skills", skillsCount, "blue"));
604
- console.log(statRow("🔧", "Scripts", scriptsCount, "green"));
605
- console.log(` ${c("cyan", "" + "".repeat(W) + "╣")}`);
606
- console.log(plainRow("", () => ""));
607
- console.log(plainRow(` Next steps:`, (s) => c("gray", s)));
608
- console.log(
609
- stepRow("/generate", "Generate code with anti-hallucination"),
610
- );
638
+ console.log(` ${c(borderCol, "" + "".repeat(W) + "")}`);
639
+ console.log(drawRow(" TRIBUNAL ENVIRONMENT SYNCHRONIZED", `${bold(c("white", " TRIBUNAL ENVIRONMENT SYNCHRONIZED"))}`));
640
+ console.log(` ${c(borderCol, "├" + "─".repeat(W) + "")}`);
641
+ console.log(drawRow(" Guarding: Active & Enforcing", `${c("gray", " Guarding:")} ${c("green", "Active & Enforcing")}`));
642
+ console.log(drawRow(" Manifest: Verified", `${c("gray", " Manifest:")} ${c("cyan", "Verified")}`));
643
+ console.log(drawRow("", ""));
644
+ console.log(drawRow(" Installed Components:", bold(c("white", " Installed Components:"))));
645
+ console.log(compRow("🤖", "Agents", agentsCount, "magenta"));
646
+ console.log(compRow("", "Workflows", workflowsCount, "yellow"));
647
+ console.log(compRow("🧠", "Skills", skillsCount, "blue"));
648
+ console.log(compRow("🔧", "Scripts", scriptsCount, "green"));
649
+ console.log(` ${c(borderCol, "├" + "─".repeat(W) + "")}`);
650
+ console.log(drawRow("", ""));
651
+ console.log(drawRow(" Next Steps:", c("gray", " Next Steps:")));
652
+ console.log(stepRow("/generate", "Generate code with reviews"));
611
653
  console.log(stepRow("/review", "Audit existing code for issues"));
612
- console.log(
613
- stepRow("/tribunal-full", "Run all 16 reviewers in parallel"),
614
- );
615
- console.log(plainRow("", () => ""));
616
- console.log(` ${c("cyan", "╚" + "═".repeat(W) + "╝")}`);
654
+ console.log(stepRow("/tribunal-full", "Run all 20 reviewers in parallel"));
655
+ console.log(drawRow("", ""));
656
+ console.log(` ${c(borderCol, "└" + "─".repeat(W) + "┘")}`);
617
657
  console.log();
618
658
  log(` ${c("gray", "✦ Updating .gitignore...")}`);
619
659
  await updateGitignore(targetDir, dryRun);
@@ -912,6 +952,8 @@ async function cmdLearn(flags) {
912
952
  const evoArgs = ["digest"];
913
953
  if (flags.dryRun) evoArgs.push("--dry-run");
914
954
  if (flags.head) evoArgs.push("--head");
955
+ if (flags.log) evoArgs.push(`--log=${flags.log}`);
956
+ if (flags.strategy) evoArgs.push(`--strategy=${flags.strategy}`);
915
957
 
916
958
  // Phase 1: Skill Evolution
917
959
  log(
@@ -1287,6 +1329,8 @@ function cmdHelp() {
1287
1329
  log(opt("--minimal", "Install core agents/skills only (~13 agents)"));
1288
1330
  log(opt("--skip-update-check", "Skip auto-update version check"));
1289
1331
  log(opt("--head", "(learn) Diff against last commit instead of staged"));
1332
+ log(opt("--log <file>", "(learn) Extract signals and evolve from a log/transcript file"));
1333
+ log(opt("--strategy <val>", "(learn) Evolution strategy: balanced, harden, repair-only"));
1290
1334
  console.log();
1291
1335
  log(bold(" Aliases"));
1292
1336
  log(` ${c("gray", "─".repeat(40))}`);
@@ -1305,6 +1349,8 @@ function cmdHelp() {
1305
1349
  log(ex("tk learn"));
1306
1350
  log(ex("tk learn --dry-run"));
1307
1351
  log(ex("tk learn --head"));
1352
+ log(ex("tk learn --log=run.log"));
1353
+ log(ex("tk learn --log=eslint.log --strategy=harden"));
1308
1354
  log(ex("tk case add"));
1309
1355
  log(ex('tk case search "useEffect"'));
1310
1356
  log(ex("tk case list"));