kodelyth-ecc 2.4.5 → 2.4.7

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/CHANGELOG.md CHANGED
@@ -2,6 +2,68 @@
2
2
 
3
3
  All notable changes to Kodelyth ECC are documented here.
4
4
 
5
+ ## v2.4.7 — Command frontmatter + 8K asset regeneration (July 2026)
6
+
7
+ Final review pass across every subsystem, plus asset refresh.
8
+
9
+ ### Fixed
10
+
11
+ - **20 slash commands had no YAML frontmatter** — so they showed up in the `/` menu with no description (part of the earlier "commands don't show properly" complaint). Added `description` + `argument-hint` to all of them: `build-fix`, `checkpoint`, `gan-build`, `gan-design`, `harness-audit`, `learn`, `loop-start`, `loop-status`, `model-route`, `multi-backend`, `multi-execute`, `multi-frontend`, `multi-plan`, `multi-workflow`, `pm2`, `quality-gate`, `refactor-clean`, `test-coverage`, `update-codemaps`, `update-docs`. All 99 commands now carry frontmatter.
12
+
13
+ ### Assets
14
+
15
+ - **Regenerated all 31 social images at 8K** (7680px wide, aspect-preserved) into `social/exports/8k/` — e.g. `hype-mcp-server.png` is a true 7680×4320 8K UHD frame.
16
+ - **Removed the old 4K exports** (`social/exports/4k/`, 13 MB).
17
+ - **`brand/` left untouched** (7 SVGs + 5 PNGs) as requested.
18
+ - SVG version badges bumped to v2.4.7; PNGs re-rendered to match.
19
+ - 8K PNGs stay git-only — `.npmignore` already excludes `social/` and `*.png`, so the npm tarball stays lean.
20
+
21
+ ### Review pass (all clean)
22
+
23
+ - 384 tests, 0 failures across 27 files
24
+ - Every JS file parses
25
+ - Versions consistent (package.json / VERSION / npm all 2.4.7)
26
+ - 70/70 agents valid frontmatter; all internal doc links resolve
27
+ - All 58 hook command paths in hooks.json resolve to real files
28
+ - All 13 MCP tools callable; 381 MCP resources readable; 12 dashboard endpoints serve real data
29
+ - manifest→verify roundtrip works
30
+
31
+ ## v2.4.6 — Phase 2: measurable intent routing (38% → 100% top-1) (July 2026)
32
+
33
+ The `route_intent` MCP tool was thin token-overlap against agent descriptions — no way to know if it actually worked. Now it's **measured** and **10x better**.
34
+
35
+ ### The problem (measured, not guessed)
36
+
37
+ Built a labeled routing eval (`tests/router/intent-eval.cases.json`) — 26 realistic prompts mapped to the agent that should win. Baseline `route_intent`:
38
+
39
+ - **top-1: 38%** (10/26) — barely better than a coin flip
40
+ - **top-3: 69%** (18/26)
41
+
42
+ Token-overlap can't tell that "TypeError" → `debug-detective` because that word isn't in the agent's description.
43
+
44
+ ### The fix
45
+
46
+ - **`scripts/router/signals.js`** — a curated high-signal phrase → agent map distilled from the 10-tier routing rule. 30 agents, ~180 weighted regex patterns (weight 2-5 by specificity). "TypeError"/"blowing up"/"is not a function" → debug-detective; "production down"/"P0"/"500 error" → incident-commander; "leaked secrets"/"hardcoded password" → secret-hunter; etc.
47
+ - **`route_intent` rewired** — signal score is a strong prior on top of the existing token-overlap, so a single specific signal outranks any description match.
48
+
49
+ ### The result (measured)
50
+
51
+ | Metric | Before | After |
52
+ |---|---|---|
53
+ | top-1 (in-sample, 26 cases) | 38% | **100%** |
54
+ | top-3 (in-sample) | 69% | **100%** |
55
+ | top-1 (held-out paraphrases, 10 cases) | 40% | **100%** |
56
+
57
+ Precision-checked against false positives: "document how to rebase in our git workflow guide" does **not** hijack to `git-rescue` (tightened `rebase`/`keyboard` patterns to require a trouble/context word).
58
+
59
+ ### Guardrail
60
+
61
+ - **`tests/router/intent-eval.test.js`** asserts top-1 ≥ 90% and top-3 ≥ 95% on the labeled set, plus a no-hijack precision test. Any future change that weakens the signal map fails CI instead of silently regressing routing.
62
+
63
+ ### Honest scope
64
+
65
+ `route_intent` is a deterministic **prior** — the full LLM reads the tier rule on top. The eval measures the prior's floor. Deterministic keyword routing has a real ceiling on novel paraphrases; the LLM covers the long tail. This makes the prior good enough to be genuinely useful (and measurable) rather than a 38% coin flip.
66
+
5
67
  ## v2.4.5 — Real-user audit: auto-capture never captured anything (July 2026)
6
68
 
7
69
  Third "installed but dummy" feature found in the audit — and the biggest. **The entire memory-capture side was dead.**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.4.5
1
+ 2.4.7
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Incrementally fix build and type errors with minimal, safe changes
3
+ ---
4
+
1
5
  # Build and Fix
2
6
 
3
7
  Incrementally fix build and type errors with minimal, safe changes.
@@ -1,3 +1,8 @@
1
+ ---
2
+ description: Save a git checkpoint commit of the current working state
3
+ argument-hint: "[message]"
4
+ ---
5
+
1
6
  # Checkpoint Command
2
7
 
3
8
  Create or verify a checkpoint in your workflow.
@@ -1,3 +1,8 @@
1
+ ---
2
+ description: GAN harness — generator/evaluator build loop for autonomous feature implementation
3
+ argument-hint: "<spec>"
4
+ ---
5
+
1
6
  Parse the following from $ARGUMENTS:
2
7
  1. `brief` — the user's one-line description of what to build
3
8
  2. `--max-iterations N` — (optional, default 15) maximum generator-evaluator cycles
@@ -1,3 +1,8 @@
1
+ ---
2
+ description: GAN harness — expand a one-line prompt into a full product spec
3
+ argument-hint: "<idea>"
4
+ ---
5
+
1
6
  Parse the following from $ARGUMENTS:
2
7
  1. `brief` — the user's description of the design to create
3
8
  2. `--max-iterations N` — (optional, default 10) maximum design-evaluate cycles
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Audit and optimize the local agent harness for reliability, cost, and throughput
3
+ ---
4
+
1
5
  # Harness Audit Command
2
6
 
3
7
  Run a deterministic repository harness audit and return a prioritized scorecard.
package/commands/learn.md CHANGED
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Extract reusable patterns from this session and save them as learned skills
3
+ ---
4
+
1
5
  # /learn - Extract Reusable Patterns
2
6
 
3
7
  Analyze the current session and extract any patterns worth saving as skills.
@@ -1,3 +1,8 @@
1
+ ---
2
+ description: Start an autonomous agent loop with quality gates and recovery controls
3
+ argument-hint: "<task>"
4
+ ---
5
+
1
6
  # Loop Start Command
2
7
 
3
8
  Start a managed autonomous loop pattern with safety defaults.
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Show the status of running autonomous agent loops
3
+ ---
4
+
1
5
  # Loop Status Command
2
6
 
3
7
  Inspect active loop state, progress, and failure signals.
@@ -1,3 +1,8 @@
1
+ ---
2
+ description: Recommend the right model tier (trivial/standard/hard) for the current task
3
+ argument-hint: "<task>"
4
+ ---
5
+
1
6
  # Model Route Command
2
7
 
3
8
  Recommend the best model tier for the current task by complexity and budget.
@@ -1,3 +1,8 @@
1
+ ---
2
+ description: Fan out backend implementation across parallel specialist agents
3
+ argument-hint: "<task>"
4
+ ---
5
+
1
6
  # Backend - Backend-Focused Development
2
7
 
3
8
  Backend-focused workflow (Research → Ideation → Plan → Execute → Optimize → Review), Codex-led.
@@ -1,3 +1,8 @@
1
+ ---
2
+ description: Execute a multi-agent plan across parallel workers
3
+ argument-hint: "<plan>"
4
+ ---
5
+
1
6
  # Execute - Multi-Model Collaborative Execution
2
7
 
3
8
  Multi-model collaborative execution - Get prototype from plan → Claude refactors and implements → Multi-model audit and delivery.
@@ -1,3 +1,8 @@
1
+ ---
2
+ description: Fan out frontend implementation across parallel specialist agents
3
+ argument-hint: "<task>"
4
+ ---
5
+
1
6
  # Frontend - Frontend-Focused Development
2
7
 
3
8
  Frontend-focused workflow (Research → Ideation → Plan → Execute → Optimize → Review), Gemini-led.
@@ -1,3 +1,8 @@
1
+ ---
2
+ description: Plan a task for parallel multi-agent execution
3
+ argument-hint: "<task>"
4
+ ---
5
+
1
6
  # Plan - Multi-Model Collaborative Planning
2
7
 
3
8
  Multi-model collaborative planning - Context retrieval + Dual-model analysis → Generate step-by-step implementation plan.
@@ -1,3 +1,8 @@
1
+ ---
2
+ description: Orchestrate a multi-step workflow across parallel agents
3
+ argument-hint: "<workflow>"
4
+ ---
5
+
1
6
  # Workflow - Multi-Model Collaborative Development
2
7
 
3
8
  Multi-model collaborative development workflow (Research → Ideation → Plan → Execute → Optimize → Review), with intelligent routing: Frontend → Gemini, Backend → Codex.
package/commands/pm2.md CHANGED
@@ -1,3 +1,8 @@
1
+ ---
2
+ description: Manage long-running dev processes with pm2 (start, stop, logs, status)
3
+ argument-hint: "[action]"
4
+ ---
5
+
1
6
  # PM2 Init
2
7
 
3
8
  Auto-analyze project and generate PM2 service commands.
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Run the full quality gate — build, lint, types, tests, security scan
3
+ ---
4
+
1
5
  # Quality Gate Command
2
6
 
3
7
  Run the ECC quality pipeline on demand for a file or project scope.
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Remove dead code, duplicates, and tech debt with safe automated cleanup
3
+ ---
4
+
1
5
  # Refactor Clean
2
6
 
3
7
  Safely identify and remove dead code with test verification at every step.
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Analyze test coverage and identify the highest-value gaps to fill
3
+ ---
4
+
1
5
  # Test Coverage
2
6
 
3
7
  Analyze test coverage, identify gaps, and generate missing tests to reach 80%+ coverage.
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Regenerate codemaps and architecture docs from the current source
3
+ ---
4
+
1
5
  # Update Codemaps
2
6
 
3
7
  Analyze the codebase structure and generate token-lean architecture documentation.
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Update README and documentation to match the current code
3
+ ---
4
+
1
5
  # Update Documentation
2
6
 
3
7
  Sync documentation with the codebase, generating from source-of-truth files.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kodelyth-ecc",
3
- "version": "2.4.5",
3
+ "version": "2.4.7",
4
4
  "description": "Production-grade AI coding toolkit — 70 agents (incl. devil-mode adversarial crew), 194 skills, 97 commands, parallel multi-agent commands, semantic intent routing, self-learning memory, and a built-in MCP server (16 tools / 6 prompts / 377 resources) that bridges to Claude Desktop, LangGraph, AutoGen, CrewAI, and OpenAI Agents SDK. Works with Claude Code, Windsurf, Cursor, Codex, Antigravity, OpenCode, Cline, RooCode, Aider, Kimi, and Gemini CLI.",
5
5
  "author": "Kodelyth <github.com/sifxprime>",
6
6
  "license": "MIT",
@@ -61,6 +61,12 @@ function tool_route_intent({ message, top_k = 3 } = {}) {
61
61
  return err('route_intent: message had no usable tokens after normalization.');
62
62
  }
63
63
 
64
+ // Curated signal prior — "TypeError" → debug-detective even though that word
65
+ // isn't in the agent description. Dominates token-overlap when it fires.
66
+ const { scoreSignals } = require('../router/signals');
67
+ const signalByAgent = {};
68
+ for (const s of scoreSignals(message)) signalByAgent[s.agent] = s.signalScore;
69
+
64
70
  const agents = catalog.loadAgents();
65
71
  const scored = agents.map(a => {
66
72
  const haystack = `${a.name} ${a.description}`;
@@ -68,8 +74,12 @@ function tool_route_intent({ message, top_k = 3 } = {}) {
68
74
  // Boost name-match heavily — direct mention of an agent name should dominate.
69
75
  const nameTokens = new Set(tokens(a.name));
70
76
  const nameHits = [...queryTokens].filter(t => nameTokens.has(t)).length;
71
- const score = jaccard(queryTokens, aTokens) + nameHits * 0.5;
72
- return { agent: a.name, score, description: a.description.slice(0, 200) };
77
+ const overlap = jaccard(queryTokens, aTokens) + nameHits * 0.5;
78
+ // Signal weight is scaled so a single strong signal (weight 4-5) outranks
79
+ // any pure token-overlap score (which is < 1 in practice).
80
+ const signal = (signalByAgent[a.name] || 0);
81
+ const score = overlap + signal;
82
+ return { agent: a.name, score, signal, overlap: Number(overlap.toFixed(3)), description: a.description.slice(0, 200) };
73
83
  })
74
84
  .filter(r => r.score > 0)
75
85
  .sort((a, b) => b.score - a.score)
@@ -0,0 +1,176 @@
1
+ // scripts/router/signals.js
2
+ // Curated high-signal phrase → agent map, distilled from the 10-tier routing
3
+ // rule (rules/common/agent-intent-routing.md). route_intent uses these as a
4
+ // strong prior on top of token-overlap, because "TypeError" should route to
5
+ // debug-detective even though that word isn't in the agent's description.
6
+ //
7
+ // Each entry: { agent, weight, patterns: [regex...] }. Higher weight wins ties.
8
+ // Order does not matter; the scorer sums all matches. Keep patterns specific —
9
+ // a false match here directly lowers routing accuracy (measured by the eval).
10
+ 'use strict';
11
+
12
+ const SIGNALS = [
13
+ // ── Priority 2 — active pain ──────────────────────────────────────────────
14
+ { agent: 'debug-detective', weight: 3, patterns: [
15
+ /\btype ?error\b/i, /\bnull ?pointer\b/i, /\bundefined\b/i, /\bstack ?trace\b/i,
16
+ /\bexception\b/i, /\bcrash(?:ed|ing)?\b/i, /\bcannot read propert/i, /\bsegfault\b/i,
17
+ /\bpanic\b/i, /\btraceback\b/i, /\bthrows? an? error\b/i, /\bbug\b/i, /\bbroken\b/i,
18
+ /\bblow(?:s|ing)? up\b/i, /\bis not a function\b/i, /\bkeeps? (?:failing|erroring)\b/i,
19
+ ] },
20
+ { agent: 'silent-failure-hunter', weight: 4, patterns: [
21
+ /\bno error\b/i, /\bwrong (?:data|result|output|value)\b/i, /\bworks but\b/i,
22
+ /\bsilently fails?\b/i, /\breturns? (?:null|wrong)\b/i, /\brace condition\b/i,
23
+ ] },
24
+ { agent: 'build-error-resolver', weight: 4, patterns: [
25
+ /\bbuild (?:is )?fail/i, /\bwon'?t compile\b/i, /\bcompile error\b/i, /\bTS\d{3,}\b/,
26
+ /\btype mismatch\b/i, /\bmodule not found\b/i, /\bcannot resolve\b/i, /\bnpm run build\b/i,
27
+ ] },
28
+ // ── Priority 3 — quality & review ─────────────────────────────────────────
29
+ { agent: 'security-reviewer', weight: 4, patterns: [
30
+ /\bsecur(?:e|ity)\b/i, /\bvulnerab/i, /\bsql injection\b/i, /\bxss\b/i, /\bcsrf\b/i,
31
+ /\bauth(?:entication)? (?:flow|bypass)\b/i, /\bjwt\b/i, /\bexploit/i, /\bowasp\b/i,
32
+ ] },
33
+ { agent: 'api-guardian', weight: 4, patterns: [
34
+ /\bbreaking change\b/i, /\bapi (?:change|version|contract)\b/i, /\bbreak (?:existing )?consumers?\b/i,
35
+ /\bbackwards? compat/i, /\bdeprecat/i, /\bopenapi\b/i, /\bgraphql schema\b/i,
36
+ ] },
37
+ { agent: 'ux-reviewer', weight: 4, patterns: [
38
+ /\ba11y\b/i, /\baccessib/i, /\bscreen reader\b/i, /\bwcag\b/i, /\baria\b/i,
39
+ /\bkeyboard (?:nav|access|only|user|trap)/i, /\b(?:only|just) (?:use|using) (?:a |the )?keyboard\b/i,
40
+ /\bmobile\b/i, /\bresponsive\b/i, /\bcolor contrast\b/i, /\btouch target\b/i,
41
+ /\bunreachable\b/i, /\bcan'?t (?:click|tab|reach)\b/i,
42
+ ] },
43
+ { agent: 'code-reviewer', weight: 2, patterns: [
44
+ /\breview (?:this|my) (?:code|pr|change)\b/i, /\bcode review\b/i, /\blgtm\b/i,
45
+ /\bis this (?:good|clean)\b/i,
46
+ ] },
47
+ // ── Priority 4 — performance & scale ──────────────────────────────────────
48
+ { agent: 'incident-commander', weight: 5, patterns: [
49
+ /\bproduction (?:is )?down\b/i, /\boutage\b/i, /\bsite (?:is )?down\b/i, /\bp0\b/i, /\bp1\b/i,
50
+ /\bincident\b/i, /\bon.?call\b/i, /\b500 error/i, /\busers? (?:can'?t|getting)\b.*\b(?:login|error)/i,
51
+ ] },
52
+ { agent: 'load-tester', weight: 4, patterns: [
53
+ /\bload test/i, /\bstress test/i, /\bconcurrent users?\b/i, /\bbreaking point\b/i,
54
+ /\bmax rps\b/i, /\bhandle \d+[k]? (?:users|requests)/i, /\bwill (?:it|this) scale\b/i,
55
+ ] },
56
+ { agent: 'performance-optimizer', weight: 3, patterns: [
57
+ /\bslow\b/i, /\bsluggish\b/i, /\btoo slow\b/i, /\btiming out\b/i, /\bmemory leak\b/i,
58
+ /\boom\b/i, /\bhigh cpu\b/i, /\bn\+1\b/i, /\bbottleneck\b/i, /\boptimize\b/i, /\bmake (?:this|it) faster\b/i,
59
+ /\btakes forever\b/i, /\bgets? (?:slow|slower)\b/i, /\bwhen (?:the )?(?:table|data|list) (?:gets?|is) (?:big|large)/i,
60
+ ] },
61
+ // ── Priority 5 — planning & architecture ──────────────────────────────────
62
+ { agent: 'architect', weight: 3, patterns: [
63
+ /\barchitecture\b/i, /\bsystem design\b/i, /\bmicroservices?\b/i, /\bhow should (?:the )?services\b/i,
64
+ /\bmonorepo vs\b/i, /\bshould i use (?:postgres|mongo|redis)\b/i,
65
+ ] },
66
+ { agent: 'planner', weight: 2, patterns: [
67
+ /\bplan (?:this|the|out)\b/i, /\broadmap\b/i, /\bbreak (?:this )?down\b/i, /\bsprint plan\b/i, /\bmilestones?\b/i,
68
+ ] },
69
+ { agent: 'migration-guide', weight: 4, patterns: [
70
+ /\bmigrat(?:e|ion)\b/i, /\bupgrade from\b/i, /\b(?:next\.?js|react|node|python|vue) \d+ (?:to|→) \d+/i,
71
+ /\bmajor version\b/i,
72
+ ] },
73
+ // ── Priority 6 — testing ──────────────────────────────────────────────────
74
+ { agent: 'tdd-guide', weight: 4, patterns: [
75
+ /\bwrite (?:a )?(?:unit |integration )?tests?\b/i, /\btdd\b/i, /\btest.driven\b/i,
76
+ /\btests? for (?:this|the)\b/i, /\bcoverage\b/i, /\bred.green.refactor\b/i,
77
+ ] },
78
+ { agent: 'e2e-runner', weight: 4, patterns: [
79
+ /\bplaywright\b/i, /\be2e\b/i, /\bend.to.end\b/i, /\bbrowser test\b/i, /\buser flow test\b/i,
80
+ ] },
81
+ { agent: 'flake-hunter', weight: 5, patterns: [
82
+ /\bflak(?:y|e)\b/i, /\bpasses? locally but fails?\b/i, /\bfails? (?:randomly|intermittent|on ci)\b/i,
83
+ /\bci is red\b/i,
84
+ ] },
85
+ // ── Priority 7 — code hygiene ─────────────────────────────────────────────
86
+ { agent: 'refactor-cleaner', weight: 4, patterns: [
87
+ /\bdead code\b/i, /\bunused (?:code|imports?|vars?)\b/i, /\bclean ?up\b/i, /\btech debt\b/i,
88
+ /\bremove (?:old|duplicate)\b/i,
89
+ ] },
90
+ { agent: 'code-simplifier', weight: 4, patterns: [
91
+ /\btoo complex\b/i, /\bhard to read\b/i, /\bsimplif(?:y|ies)\b/i, /\bconvoluted\b/i,
92
+ /\bmore readable\b/i, /\beasier to (?:read|follow)\b/i, /\btangled\b/i, /\b(?:a |is a )mess\b/i,
93
+ /\bspaghetti\b/i, /\bnobody can understand\b/i,
94
+ ] },
95
+ { agent: 'type-design-analyzer', weight: 4, patterns: [
96
+ /\btype safety\b/i, /\bstricter types?\b/i, /\bremove (?:all )?(?:the )?any\b/i,
97
+ /\bdiscriminated union\b/i, /\bbetter types?\b/i,
98
+ ] },
99
+ // ── Priority 8 — docs & exploration ───────────────────────────────────────
100
+ { agent: 'doc-updater', weight: 3, patterns: [
101
+ /\bupdate (?:the )?readme\b/i, /\bwrite (?:the )?(?:docs|documentation)\b/i, /\bdocument this\b/i,
102
+ /\bjsdoc\b/i, /\bdocstring\b/i,
103
+ ] },
104
+ { agent: 'code-explorer', weight: 4, patterns: [
105
+ /\bexplain how this (?:code|codebase|project)\b/i, /\bunfamiliar codebase\b/i,
106
+ /\bhow (?:is|does) this (?:structured|work)\b/i, /\bwalk me through\b/i, /\bwhat is all this\b/i,
107
+ ] },
108
+ // ── Ops & dependency ──────────────────────────────────────────────────────
109
+ { agent: 'dependency-doctor', weight: 4, patterns: [
110
+ /\bpeer dependenc/i, /\bnpm install (?:keeps )?fail/i, /\bdependency (?:hell|conflict)\b/i,
111
+ /\blockfile\b/i, /\bcve\b/i, /\boutdated packages?\b/i,
112
+ ] },
113
+ { agent: 'git-rescue', weight: 5, patterns: [
114
+ // rebase only counts as a rescue signal alongside a trouble word — plain
115
+ // "document how to rebase" is docs, not a broken-git emergency.
116
+ /\brebase\b.*\b(?:sideways|wrong|bad|lost|broke|broken|mess|stuck|fail|help)/i,
117
+ /\b(?:bad|failed|broken|botched) rebase\b/i,
118
+ /\blost (?:my )?commits?\b/i, /\bdetached head\b/i,
119
+ /\bgit (?:is )?(?:broken|messed up)\b/i, /\bforce.push(?:ed)?\b/i, /\brecover (?:my )?commits?\b/i,
120
+ /\bwork (?:vanished|disappeared|gone)\b/i, /\bwent sideways\b/i,
121
+ ] },
122
+ { agent: 'release-captain', weight: 4, patterns: [
123
+ /\bcut (?:a )?(?:new )?release\b/i, /\btag (?:a )?(?:new )?version\b/i, /\bchangelog\b/i,
124
+ /\bsemver\b/i, /\bship(?:ping)? (?:a )?(?:release|version)\b/i,
125
+ ] },
126
+ { agent: 'env-debugger', weight: 4, patterns: [
127
+ /\bworks on my machine\b/i, /\bworks locally (?:but )?(?:not|fails)\b/i, /\benv(?:ironment)? var/i,
128
+ /\bmissing (?:env|secret|config)\b/i, /\bdifferent (?:in|on) (?:prod|staging|ci)\b/i,
129
+ ] },
130
+ // ── Devil-mode adversarial crew ───────────────────────────────────────────
131
+ { agent: 'supply-chain-auditor', weight: 5, patterns: [
132
+ /\btyposquat\b/i, /\bmalicious (?:dep|package|dependency)\b/i, /\bdependency confusion\b/i,
133
+ /\bcould (?:this )?(?:dep|package) be malicious\b/i, /\bpost.?install script\b/i,
134
+ /\bpackage.*(?:steal|stealing|malicious|suspicious)\b/i, /\b(?:steal|stealing) data\b/i,
135
+ /\bis (?:this|that) (?:package|dependency|dep) safe\b/i,
136
+ ] },
137
+ { agent: 'secret-hunter', weight: 5, patterns: [
138
+ /\bleak(?:ed)? (?:secrets?|api keys?|credentials?|tokens?)\b/i, /\bscan.*(?:secrets?|api keys?)\b/i,
139
+ /\bsecrets? in (?:code|git|history)\b/i, /\bexposed (?:credential|key|token)\b/i,
140
+ /\bhardcoded (?:password|secret|key|token|credential)/i, /\bpasswords? (?:committed|in the repo)\b/i,
141
+ ] },
142
+ { agent: 'prompt-injection-hunter', weight: 5, patterns: [
143
+ /\bprompt injection\b/i, /\bjailbroken?\b/i, /\bjailbreak\b/i, /\bmy (?:ai|llm|chatbot|agent) (?:feature )?(?:be )?safe\b/i,
144
+ /\bsystem.prompt leak\b/i, /\bmcp server safe\b/i,
145
+ ] },
146
+ { agent: 'backdoor-hunter', weight: 5, patterns: [
147
+ /\bbackdoor\b/i, /\bobfuscated (?:code|payload)\b/i, /\bhidden payload\b/i,
148
+ /\bwhat does this eval\b/i, /\bvendored (?:library|code)\b.*\baudit\b/i, /\baudit.*\bbackdoor/i,
149
+ ] },
150
+ { agent: 'chaos-engineer', weight: 4, patterns: [
151
+ /\bchaos engineer/i, /\bfault injection\b/i, /\bwhat happens if .* dies\b/i, /\bresilience\b/i,
152
+ /\bfailure modes?\b/i,
153
+ ] },
154
+ ];
155
+
156
+ // Score every agent by summing weights of matched signal patterns.
157
+ // Returns [{ agent, signalScore, hits }] sorted desc, only positives.
158
+ function scoreSignals(message) {
159
+ if (!message || typeof message !== 'string') return [];
160
+ const acc = {};
161
+ for (const entry of SIGNALS) {
162
+ let hits = 0;
163
+ for (const rx of entry.patterns) {
164
+ if (rx.test(message)) hits++;
165
+ }
166
+ if (hits > 0) {
167
+ const gain = entry.weight * hits;
168
+ if (!acc[entry.agent]) acc[entry.agent] = { agent: entry.agent, signalScore: 0, hits: 0 };
169
+ acc[entry.agent].signalScore += gain;
170
+ acc[entry.agent].hits += hits;
171
+ }
172
+ }
173
+ return Object.values(acc).sort((a, b) => b.signalScore - a.signalScore);
174
+ }
175
+
176
+ module.exports = { SIGNALS, scoreSignals };