tribunal-kit 5.7.0 → 5.8.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 (56) hide show
  1. package/.agent/ARCHITECTURE.md +6 -7
  2. package/.agent/agents/frontend-reviewer.md +13 -0
  3. package/.agent/agents/frontend-specialist.md +14 -0
  4. package/.agent/agents/logic-reviewer.md +11 -0
  5. package/.agent/agents/orchestrator.md +15 -0
  6. package/.agent/agents/security-auditor.md +13 -0
  7. package/.agent/agents/ui-ux-auditor.md +7 -31
  8. package/.agent/history/memory/.memory.idx +766 -0
  9. package/.agent/history/memory/MEMORY.md +62 -0
  10. package/.agent/routing_index.json +694 -714
  11. package/.agent/rules/GEMINI.md +58 -8
  12. package/.agent/scripts/_colors.js +131 -89
  13. package/.agent/scripts/_utils.js +163 -128
  14. package/.agent/scripts/auto_preview.js +207 -197
  15. package/.agent/scripts/bundle_analyzer.js +227 -192
  16. package/.agent/scripts/case_law_manager.js +991 -689
  17. package/.agent/scripts/checklist.js +233 -190
  18. package/.agent/scripts/context_broker.js +930 -605
  19. package/.agent/scripts/dependency_analyzer.js +275 -184
  20. package/.agent/scripts/graph_builder.js +412 -341
  21. package/.agent/scripts/graph_visualizer.js +392 -390
  22. package/.agent/scripts/graph_zoom.js +198 -156
  23. package/.agent/scripts/inner_loop_validator.js +523 -445
  24. package/.agent/scripts/lint_runner.js +199 -157
  25. package/.agent/scripts/marathon_harness.js +819 -661
  26. package/.agent/scripts/minify_context.js +115 -100
  27. package/.agent/scripts/mutation_runner.js +321 -280
  28. package/.agent/scripts/prompt_compiler.js +62 -42
  29. package/.agent/scripts/schema_validator.js +373 -280
  30. package/.agent/scripts/security_scan.js +333 -190
  31. package/.agent/scripts/session_manager.js +306 -270
  32. package/.agent/scripts/skill_evolution.js +810 -637
  33. package/.agent/scripts/skill_integrator.js +327 -307
  34. package/.agent/scripts/strengthen_skills.js +203 -193
  35. package/.agent/scripts/swarm_dispatcher.js +558 -457
  36. package/.agent/scripts/test_runner.js +178 -152
  37. package/.agent/scripts/verify_all.js +200 -168
  38. package/.agent/skills/fabel-protocol/SKILL.md +235 -0
  39. package/.agent/skills/thinking-protocol/SKILL.md +27 -0
  40. package/.agent/workflows/generate.md +1 -1
  41. package/.agent/workflows/tribunal-speed.md +1 -1
  42. package/README.md +53 -53
  43. package/bin/mcp-server.js +460 -175
  44. package/bin/tribunal-kit.js +1245 -987
  45. package/bin/wrapper.js +104 -74
  46. package/dist/cli.js +31 -0
  47. package/dist/commands/case.js +23 -0
  48. package/dist/commands/compile.js +84 -0
  49. package/dist/commands/init.js +42 -0
  50. package/dist/commands/learn.js +57 -0
  51. package/dist/commands/memory.js +456 -0
  52. package/package.json +2 -2
  53. package/scripts/benchmark.js +162 -125
  54. package/scripts/changelog.js +196 -168
  55. package/scripts/sync-version.js +94 -81
  56. package/scripts/validate-payload.js +85 -78
package/bin/wrapper.js CHANGED
@@ -1,108 +1,138 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * Tribunal-Kit Core Wrapper
4
- *
4
+ *
5
5
  * This script routes commands to the ultra-fast Rust binary if available and supported.
6
6
  * For legacy commands (or if the binary isn't available/compiled yet), it gracefully
7
7
  * falls back to the original JavaScript implementation.
8
8
  */
9
9
 
10
- const fs = require('fs');
11
- const path = require('path');
12
- const { spawnSync } = require('child_process');
13
- const os = require('os');
10
+ const fs = require("fs");
11
+ const path = require("path");
12
+ const { spawnSync } = require("child_process");
13
+ const os = require("os");
14
14
 
15
15
  // Commands that have been fully ported to Rust so far
16
- const RUST_COMMANDS = new Set(['init', 'validate', 'status', 'sync', 'hook', 'uninstall']);
16
+ const RUST_COMMANDS = new Set([
17
+ "init",
18
+ "validate",
19
+ "status",
20
+ "sync",
21
+ "hook",
22
+ "uninstall",
23
+ ]);
17
24
 
18
25
  // Determine the path to the compiled Rust binary
19
26
  // In a full production release, this checks optionalDependencies in node_modules
20
27
  // For development, it checks the local target/release folder
21
28
  function getBinaryPath() {
22
- const isWindows = os.platform() === 'win32';
23
- const ext = isWindows ? '.exe' : '';
24
- const platform = os.platform();
25
- const arch = os.arch();
26
-
27
- // First, try production resolution (from optionalDependencies)
28
- const pkgName = `@tribunal-kit/core-${platform}-${arch}`;
29
- try {
30
- // Try to resolve the binary from the optional dependency package
31
- const pkgPath = require.resolve(`${pkgName}/package.json`);
32
- const binPath = path.resolve(path.dirname(pkgPath), `bin/tribunal-core${ext}`);
33
- if (fs.existsSync(binPath)) {
34
- return binPath;
35
- }
36
- } catch (e) {
37
- // Package not found, ignore and fall back to local dev targets
38
- }
29
+ const isWindows = os.platform() === "win32";
30
+ const ext = isWindows ? ".exe" : "";
31
+ const platform = os.platform();
32
+ const arch = os.arch();
39
33
 
40
- // Second, try to find the binary compiled from crates/core/Cargo.toml (Local dev)
41
- const devPath = path.resolve(__dirname, '..', 'target', 'release', `tribunal-core${ext}`);
42
- if (fs.existsSync(devPath)) {
43
- return devPath;
34
+ // First, try production resolution (from optionalDependencies)
35
+ const pkgName = `@tribunal-kit/core-${platform}-${arch}`;
36
+ try {
37
+ // Try to resolve the binary from the optional dependency package
38
+ const pkgPath = require.resolve(`${pkgName}/package.json`);
39
+ const binPath = path.resolve(
40
+ path.dirname(pkgPath),
41
+ `bin/tribunal-core${ext}`,
42
+ );
43
+ if (fs.existsSync(binPath)) {
44
+ return binPath;
44
45
  }
46
+ } catch {
47
+ // Package not found, ignore and fall back to local dev targets
48
+ }
45
49
 
46
- // Third, try target/debug (if they ran `cargo build` instead of `--release`)
47
- const debugPath = path.resolve(__dirname, '..', 'target', 'debug', `tribunal-core${ext}`);
48
- if (fs.existsSync(debugPath)) {
49
- return debugPath;
50
- }
50
+ // Second, try to find the binary compiled from crates/core/Cargo.toml (Local dev)
51
+ const devPath = path.resolve(
52
+ __dirname,
53
+ "..",
54
+ "target",
55
+ "release",
56
+ `tribunal-core${ext}`,
57
+ );
58
+ if (fs.existsSync(devPath)) {
59
+ return devPath;
60
+ }
61
+
62
+ // Third, try target/debug (if they ran `cargo build` instead of `--release`)
63
+ const debugPath = path.resolve(
64
+ __dirname,
65
+ "..",
66
+ "target",
67
+ "debug",
68
+ `tribunal-core${ext}`,
69
+ );
70
+ if (fs.existsSync(debugPath)) {
71
+ return debugPath;
72
+ }
51
73
 
52
- return null;
74
+ return null;
53
75
  }
54
76
 
55
77
  function runRustBinary(binPath, args) {
56
- const stdio = ['inherit', process.stdout.isTTY ? 'ignore' : 'inherit', 'inherit'];
57
- const result = spawnSync(binPath, args, {
58
- stdio: stdio,
59
- env: process.env
60
- });
61
-
62
- if (result.error) {
63
- console.error(`\x1b[91m✖ Failed to execute Rust engine:\x1b[0m ${result.error.message}`);
64
- process.exit(1);
65
- }
78
+ const stdio = [
79
+ "inherit",
80
+ process.stdout.isTTY ? "ignore" : "inherit",
81
+ "inherit",
82
+ ];
83
+ const result = spawnSync(binPath, args, {
84
+ stdio: stdio,
85
+ env: process.env,
86
+ });
87
+
88
+ if (result.error) {
89
+ console.error(
90
+ `\x1b[91m✖ Failed to execute Rust engine:\x1b[0m ${result.error.message}`,
91
+ );
92
+ process.exit(1);
93
+ }
66
94
 
67
- process.exit(result.status || 0);
95
+ process.exit(result.status || 0);
68
96
  }
69
97
 
70
98
  function runLegacyFallback() {
71
- // Use the modular dist/ CLI with lazy-loaded commands for faster cold-start.
72
- // Each command module is require()'d only when invoked (~70% fewer files loaded).
73
- const { main } = require('../dist/cli.js');
74
- main();
99
+ // Use the modular dist/ CLI with lazy-loaded commands for faster cold-start.
100
+ // Each command module is require()'d only when invoked (~70% fewer files loaded).
101
+ const { main } = require("../dist/cli.js");
102
+ main();
75
103
  }
76
104
 
77
105
  function main() {
78
- // Skip 'node' and 'wrapper.js'
79
- const args = process.argv.slice(2);
80
-
81
- // Extract the command (the first non-flag argument)
82
- const command = args.find(a => !a.startsWith('-'));
83
-
84
- if (command && RUST_COMMANDS.has(command)) {
85
- const binPath = getBinaryPath();
86
-
87
- if (binPath) {
88
- // For the init command, Rust needs to know where the .agent template folder is.
89
- if (command === 'init') {
90
- const sourceDir = path.resolve(__dirname, '..', '.agent');
91
- args.push('--source-dir', sourceDir);
92
- }
93
-
94
- // Route to Rust engine
95
- // console.log('\x1b[90m⚡ Executing via Rust Core Engine\x1b[0m');
96
- runRustBinary(binPath, args);
97
- return;
98
- } else {
99
- // Warn if Rust command was requested but binary is missing
100
- console.warn('\x1b[93m⚠ Rust binary not found in target/. Falling back to JS engine.\x1b[0m');
101
- }
106
+ // Skip 'node' and 'wrapper.js'
107
+ const args = process.argv.slice(2);
108
+
109
+ // Extract the command (the first non-flag argument)
110
+ const command = args.find((a) => !a.startsWith("-"));
111
+
112
+ if (command && RUST_COMMANDS.has(command)) {
113
+ const binPath = getBinaryPath();
114
+
115
+ if (binPath) {
116
+ // For the init command, Rust needs to know where the .agent template folder is.
117
+ if (command === "init") {
118
+ const sourceDir = path.resolve(__dirname, "..", ".agent");
119
+ args.push("--source-dir", sourceDir);
120
+ }
121
+
122
+ // Route to Rust engine
123
+ // console.log('\x1b[90m⚡ Executing via Rust Core Engine\x1b[0m');
124
+ runRustBinary(binPath, args);
125
+ return;
126
+ } else {
127
+ // Warn if Rust command was requested but binary is missing
128
+ console.warn(
129
+ "\x1b[93m⚠ Rust binary not found in target/. Falling back to JS engine.\x1b[0m",
130
+ );
102
131
  }
132
+ }
103
133
 
104
- // Fall back to JS logic for un-ported commands (e.g. `learn`, `case`, `marathon`)
105
- runLegacyFallback();
134
+ // Fall back to JS logic for un-ported commands (e.g. `learn`, `case`, `marathon`)
135
+ runLegacyFallback();
106
136
  }
107
137
 
108
138
  main();
package/dist/cli.js CHANGED
@@ -62,6 +62,18 @@ function parseArgs(argv) {
62
62
  }
63
63
  args.flags.path = nextVal;
64
64
  }
65
+ if (arg.startsWith('--target=')) {
66
+ args.flags.target = arg.split('=').slice(1).join('=');
67
+ }
68
+ if (arg === '--target') {
69
+ const idx = raw.indexOf('--target');
70
+ const nextVal = raw[idx + 1];
71
+ if (!nextVal || nextVal.startsWith('--')) {
72
+ console.error(` \x1b[91m✖ --target requires an argument\x1b[0m`);
73
+ process.exit(1);
74
+ }
75
+ args.flags.target = nextVal;
76
+ }
65
77
  if (arg.startsWith('--branch=')) {
66
78
  args.flags.branch = arg.split('=').slice(1).join('=');
67
79
  }
@@ -86,12 +98,15 @@ function cmdHelp(quiet = false) {
86
98
  (0, logger_1.log)(cmd('sync', 'Synchronize IDE bridge files with current rules'));
87
99
  (0, logger_1.log)(cmd('marathon', 'Long-running agent harness (init, status, next, mark)'));
88
100
  (0, logger_1.log)(cmd('hook', 'Install pre-push git hook for auto-learning'));
101
+ (0, logger_1.log)(cmd('compile', 'Compile rules into a static instruction file for terminal agents'));
102
+ (0, logger_1.log)(cmd('memory', '4-Type Taxonomy Persistent Memory Engine (store, recall, gc, stats, export)'));
89
103
  (0, logger_1.log)(cmd('uninstall', 'Remove .agent/ folder from project'));
90
104
  console.log();
91
105
  (0, logger_1.log)((0, logger_1.bold)(' Options'));
92
106
  (0, logger_1.log)(` ${(0, logger_1.c)('gray', '─'.repeat(40))}`);
93
107
  (0, logger_1.log)(opt('--force', 'Overwrite existing .agent/ folder'));
94
108
  (0, logger_1.log)(opt('--path <dir>', 'Install in specific directory'));
109
+ (0, logger_1.log)(opt('--target <name>', 'Target terminal agent for compile (e.g. aider)'));
95
110
  (0, logger_1.log)(opt('--quiet', 'Suppress all output'));
96
111
  (0, logger_1.log)(opt('--verbose', 'Show detailed debug logging'));
97
112
  (0, logger_1.log)(opt('--dry-run', 'Preview actions without executing'));
@@ -128,6 +143,12 @@ function cmdHelp(quiet = false) {
128
143
  (0, logger_1.log)(ex('tk marathon next'));
129
144
  (0, logger_1.log)(ex('tk marathon mark 5 pass'));
130
145
  (0, logger_1.log)(ex('tk hook'));
146
+ (0, logger_1.log)(ex('tk compile'));
147
+ (0, logger_1.log)(ex('tk memory store --type semantic --content "Uses PostgreSQL" --tags db,orm'));
148
+ (0, logger_1.log)(ex('tk memory recall --query "database" --budget 2000'));
149
+ (0, logger_1.log)(ex('tk memory gc'));
150
+ (0, logger_1.log)(ex('tk memory stats'));
151
+ (0, logger_1.log)(ex('tk memory export'));
131
152
  (0, logger_1.log)(ex('tk uninstall'));
132
153
  console.log();
133
154
  }
@@ -205,11 +226,21 @@ async function runWithUpdateCheck(command, flags) {
205
226
  await cmdMarathon(flags, process.argv, quiet);
206
227
  break;
207
228
  }
229
+ case 'compile': {
230
+ const cmdCompile = loadCmd('./commands/compile', 'cmdCompile');
231
+ await cmdCompile(flags, quiet);
232
+ break;
233
+ }
208
234
  case 'uninstall': {
209
235
  const cmdUninstall = loadCmd('./commands/uninstall', 'cmdUninstall');
210
236
  cmdUninstall(flags, quiet);
211
237
  break;
212
238
  }
239
+ case 'memory': {
240
+ const cmdMemory = loadCmd('./commands/memory', 'cmdMemory');
241
+ await cmdMemory(flags, process.argv, quiet);
242
+ break;
243
+ }
213
244
  case 'help':
214
245
  case '--help':
215
246
  case '-h':
@@ -41,6 +41,29 @@ async function cmdCase(flags, processArgs, quiet = false) {
41
41
  pyArgs = pyArgs.replace(/^search/, 'search-cases');
42
42
  try {
43
43
  await (0, helpers_1.runShellAsync)(`node "${caseLawScript}" ${pyArgs}`, { stdio: 'inherit', cwd: targetDir });
44
+ // Memory Bridge: When a case is added, auto-store a SEMANTIC memory
45
+ if (args.startsWith('add')) {
46
+ try {
47
+ const { _memoryStore } = require('./memory');
48
+ // Extract a summary from the add-case args (best effort)
49
+ const contentMatch = args.match(/--violation\s+"([^"]+)"/i) || args.match(/--violation\s+(\S+)/i);
50
+ const domainMatch = args.match(/--domain\s+"([^"]+)"/i) || args.match(/--domain\s+(\S+)/i);
51
+ const violation = contentMatch ? contentMatch[1] : 'Unknown violation';
52
+ const domain = domainMatch ? domainMatch[1] : 'general';
53
+ _memoryStore(
54
+ agentDest,
55
+ 'semantic',
56
+ `CASE LAW REJECTION: ${violation} (domain: ${domain})`,
57
+ ['case-law', domain, 'rejection'],
58
+ null
59
+ );
60
+ if (!quiet) {
61
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', '\u25b8')} Memory bridge: case law rejection stored to memory index`);
62
+ }
63
+ } catch {
64
+ // Non-critical — case law was still saved, memory bridge is a bonus
65
+ }
66
+ }
44
67
  }
45
68
  catch {
46
69
  process.exit(1); // Script already prints errors
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cmdCompile = cmdCompile;
4
+
5
+ const fs = require("fs");
6
+ const path = require("path");
7
+ const { log, err, ok, c, bold, dbg } = require("../utils/logger");
8
+
9
+ async function cmdCompile(flags, quiet) {
10
+ const cwd = process.cwd();
11
+ const agentDir = path.join(cwd, ".agent");
12
+
13
+ if (!fs.existsSync(agentDir)) {
14
+ err("Tribunal Kit is not installed in this directory (.agent folder missing). Run 'tk init' first.");
15
+ process.exit(1);
16
+ }
17
+
18
+ log(bold("Compiling Tribunal Kit rules..."));
19
+
20
+ let compiledContext = "# Tribunal Kit Context\n\n";
21
+ compiledContext += "The following are rules, agents, and skills from the Tribunal Kit.\n\n";
22
+
23
+ // 1. Read GEMINI.md
24
+ const geminiPath = path.join(agentDir, "rules", "GEMINI.md");
25
+ if (fs.existsSync(geminiPath)) {
26
+ compiledContext += "## Global Rules (GEMINI.md)\n\n";
27
+ compiledContext += fs.readFileSync(geminiPath, "utf-8") + "\n\n";
28
+ }
29
+
30
+ // 2. Read Agents
31
+ const agentsDir = path.join(agentDir, "agents");
32
+ if (fs.existsSync(agentsDir)) {
33
+ compiledContext += "## Agents\n\n";
34
+ const agents = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md'));
35
+ for (const file of agents) {
36
+ const content = fs.readFileSync(path.join(agentsDir, file), "utf-8");
37
+ compiledContext += `### Agent: ${file}\n\n`;
38
+ compiledContext += content + "\n\n";
39
+ }
40
+ }
41
+
42
+ // 3. Read Skills
43
+ const skillsDir = path.join(agentDir, "skills");
44
+ if (fs.existsSync(skillsDir)) {
45
+ compiledContext += "## Skills\n\n";
46
+ const skills = fs.readdirSync(skillsDir, { withFileTypes: true });
47
+ for (const dirent of skills) {
48
+ if (dirent.isDirectory()) {
49
+ const skillPath = path.join(skillsDir, dirent.name, "SKILL.md");
50
+ if (fs.existsSync(skillPath)) {
51
+ const content = fs.readFileSync(skillPath, "utf-8");
52
+ compiledContext += `### Skill: ${dirent.name}\n\n`;
53
+ compiledContext += content + "\n\n";
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+ // 4. Read Workflows
60
+ const workflowsDir = path.join(agentDir, "workflows");
61
+ if (fs.existsSync(workflowsDir)) {
62
+ compiledContext += "## Workflows\n\n";
63
+ const workflows = fs.readdirSync(workflowsDir).filter(f => f.endsWith('.md'));
64
+ for (const file of workflows) {
65
+ const content = fs.readFileSync(path.join(workflowsDir, file), "utf-8");
66
+ compiledContext += `### Workflow: ${file}\n\n`;
67
+ compiledContext += content + "\n\n";
68
+ }
69
+ }
70
+
71
+ let targetFile = ".tribunal-compiled.md";
72
+ if (flags.target) {
73
+ if (flags.target === "aider") targetFile = ".aider.conf.yml";
74
+ if (flags.target === "claude") targetFile = ".claude.json";
75
+ }
76
+
77
+ const outputPath = path.join(cwd, targetFile);
78
+ fs.writeFileSync(outputPath, compiledContext, "utf-8");
79
+
80
+ ok(`Compiled rules written to ${c('cyan', targetFile)}`);
81
+ if (!quiet) {
82
+ log(` ${c('gray', 'Load this file into your terminal agent (e.g. Claude Code, Aider, OpenCode)')}`);
83
+ }
84
+ }
@@ -281,6 +281,47 @@ async function generateIDEBridges(targetDir, agentDest, dryRun = false) {
281
281
  # Auto-generated by tribunal-kit init. Do not edit manually.
282
282
  # Source: .agent/rules/GEMINI.md
283
283
 
284
+ ${rulesContent}
285
+ `;
286
+ // ── 2. Windsurf (.windsurfrules) ─────────────────────
287
+ const windsurfRules = `# Tribunal Kit — Windsurf Bridge
288
+ # Auto-generated by tribunal-kit init. Do not edit manually.
289
+ # Source: .agent/rules/GEMINI.md
290
+
291
+ ${rulesContent}
292
+ `;
293
+ // ── 3. Gemini / Antigravity (.gemini/settings.json) ──
294
+ const geminiSettings = JSON.stringify({
295
+ "rules": [
296
+ { "path": "../.agent/rules/GEMINI.md", "trigger": "always_on" }
297
+ ],
298
+ "agents": { "directory": "../.agent/agents" },
299
+ "skills": { "directory": "../.agent/skills" },
300
+ "workflows": { "directory": "../.agent/workflows" }
301
+ }, null, 2) + '\n';
302
+ // ── Also create .gemini/GEMINI.md as a direct rules file ──
303
+ const geminiRulesBridge = `---
304
+ trigger: always_on
305
+ ---
306
+
307
+ # Tribunal Kit — Gemini Bridge
308
+ # Auto-generated by tribunal-kit init.
309
+ # Full rules: .agent/rules/GEMINI.md
310
+
311
+ ${rulesContent}
312
+ `;
313
+ // ── 4. GitHub Copilot (.github/copilot-instructions.md) ──
314
+ const copilotInstructions = `# Tribunal Kit — Copilot Bridge
315
+ # Auto-generated by tribunal-kit init. Do not edit manually.
316
+ # Source: .agent/rules/GEMINI.md
317
+
318
+ ${rulesContent}
319
+ `;
320
+ // ── 5. Claude (.claude/CLAUDE.md) ─────────────────────
321
+ const claudeRules = `# Tribunal Kit — Claude Bridge
322
+ # Auto-generated by tribunal-kit init. Do not edit manually.
323
+ # Source: .agent/rules/GEMINI.md
324
+
284
325
  ${rulesContent}
285
326
  `;
286
327
  // Fire ALL bridge writes concurrently via Promise.all
@@ -295,3 +336,4 @@ ${rulesContent}
295
336
  await Promise.all(bridges.map(b => writeBridge(b.path, b.content, b.label)));
296
337
  console.log();
297
338
  }
339
+
@@ -55,6 +55,63 @@ async function cmdLearn(flags, quiet = false) {
55
55
  (0, logger_1.log)(` ${(0, logger_1.c)('gray', '\u25b8')} Search existing case law:`);
56
56
  (0, logger_1.log)(` ${(0, logger_1.c)('white', 'npx tribunal-kit case search "your query"')}`);
57
57
  console.log();
58
+ // Phase 3: Memory Distillation
59
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', '\u229b')} ${(0, logger_1.bold)('Phase 3')} \u2014 Memory Distillation (storing project knowledge)`);
60
+ try {
61
+ const { _memoryStore } = require('./memory');
62
+ // Auto-extract SEMANTIC memories from project-idioms if it exists
63
+ const idiomsPath = path_1.default.join(agentDest, 'skills', 'project-idioms', 'SKILL.md');
64
+ let memoriesStored = 0;
65
+ if (fs_1.default.existsSync(idiomsPath)) {
66
+ const idiomsContent = fs_1.default.readFileSync(idiomsPath, 'utf8');
67
+ // Extract lines that look like project rules (lines starting with - or * that contain actionable content)
68
+ const ruleLines = idiomsContent.split('\n')
69
+ .filter(line => /^[\s]*[-*]\s+/.test(line) && line.trim().length > 20)
70
+ .map(line => line.replace(/^[\s]*[-*]\s+/, '').trim())
71
+ .slice(0, 10); // Cap at 10 to prevent bloat
72
+
73
+ for (const rule of ruleLines) {
74
+ try {
75
+ _memoryStore(agentDest, 'semantic', rule, ['project-idiom', 'auto-learned'], null);
76
+ memoriesStored++;
77
+ } catch {
78
+ // Skip duplicates or capacity errors silently
79
+ }
80
+ }
81
+ }
82
+ // Auto-extract PROCEDURAL memories from package.json scripts
83
+ const pkgPath = path_1.default.join(targetDir, 'package.json');
84
+ if (fs_1.default.existsSync(pkgPath)) {
85
+ try {
86
+ const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf8'));
87
+ if (pkg.scripts) {
88
+ const importantScripts = ['build', 'test', 'dev', 'start', 'deploy', 'lint'];
89
+ for (const key of importantScripts) {
90
+ if (pkg.scripts[key]) {
91
+ try {
92
+ _memoryStore(agentDest, 'procedural',
93
+ `Run \`${pkg.scripts[key]}\` to ${key} the project`,
94
+ ['build-script', key, 'auto-learned'], null);
95
+ memoriesStored++;
96
+ } catch {
97
+ // Skip
98
+ }
99
+ }
100
+ }
101
+ }
102
+ } catch {
103
+ // Unreadable package.json
104
+ }
105
+ }
106
+ if (memoriesStored > 0) {
107
+ (0, logger_1.log)(` ${(0, logger_1.c)('green', '\u2714')} ${memoriesStored} memories auto-stored (semantic + procedural)`);
108
+ } else {
109
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '\u25b8')} No new memories to distill (run again after committing changes)`);
110
+ }
111
+ } catch (e) {
112
+ (0, logger_1.log)(` ${(0, logger_1.c)('yellow', '\u26a0')} Memory distillation skipped: ${e.message || String(e)}`);
113
+ }
114
+ console.log();
58
115
  (0, logger_1.log)(` ${(0, logger_1.c)('green', '\u2714')} ${(0, logger_1.bold)('Learn cycle complete.')} Your Tribunal grows smarter with every commit.`);
59
116
  console.log();
60
117
  }