lean-ctx 3.9.19

Context Runtime for AI Agents with CCP. 79 MCP tools, 10 read modes, 95+ compression patterns, cross-session memory (CCP), persistent AI knowledge with temporal facts + contradiction detection, multi-agent context sharing, LITM-aware positioning, AAAK compact format, adaptive compression with Thompson Sampling bandits. Supports 24+ AI tools. Reduces LLM token consumption by up to 99%.
var SOLUTION_REFRESH_MS = 15000;

function csolEsc(value) {
  return String(value == null ? '' : value).replace(/[&<>"']/g, function (character) {
    return '&#' + character.charCodeAt(0) + ';';
  });
}

function csolNumber(value) {
  if (value && typeof value === 'object') value = value.count != null ? value.count : value.value;
  return Number(value) || 0;
}

function csolFormat(value) {
  return Math.round(csolNumber(value)).toLocaleString();
}

function csolPercent(value) {
  return Math.max(0, Math.min(100, Math.round(csolNumber(value)))) + '%';
}

function csolTrendChart(trend) {
  if (!trend.length) {
    return '<div style="color:var(--text-tertiary);font-size:12px;padding:18px 0;">No daily solution decisions recorded.</div>';
  }
  var max = Math.max.apply(null, trend.map(function (day) {
    return Math.max(csolNumber(day.decisions), Math.abs(csolNumber(day.loc_reduced)));
  }).concat([1]));
  return '<div style="display:grid;grid-template-columns:repeat(' + trend.length + ',minmax(28px,1fr));align-items:end;gap:8px;height:152px;padding-top:12px;">' + trend.map(function (day) {
    var decisions = csolNumber(day.decisions);
    var locReduced = csolNumber(day.loc_reduced);
    var decisionHeight = Math.max(4, Math.round((decisions / max) * 96));
    var locHeight = Math.max(4, Math.round((Math.abs(locReduced) / max) * 96));
    var date = String(day.date || '').slice(5) || '';
    return '<div title="' + csolEsc(String(day.date || date) + ': ' + decisions + ' decisions, ' + locReduced + ' LOC reduced') + '" style="min-width:0;text-align:center;">' +
      '<div style="height:112px;display:flex;align-items:end;justify-content:center;gap:3px;">' +
        '<span aria-label="' + csolEsc(String(decisions) + ' decisions') + '" style="display:block;width:42%;height:' + decisionHeight + 'px;background:#4f9dff;border-radius:3px 3px 0 0;"></span>' +
        '<span aria-label="' + csolEsc(String(locReduced) + ' LOC reduced') + '" style="display:block;width:42%;height:' + locHeight + 'px;background:var(--accent-green);border-radius:3px 3px 0 0;"></span>' +
      '</div>' +
      '<div style="color:var(--text-tertiary);font-size:10px;margin-top:6px;white-space:nowrap;">' + csolEsc(date) + '</div>' +
    '</div>';
  }).join('') + '</div>' +
    '<div style="display:flex;gap:12px;color:var(--text-tertiary);font-size:10px;margin-top:8px;">' +
      '<span><i style="display:inline-block;width:7px;height:7px;background:#4f9dff;border-radius:2px;"></i> decisions</span>' +
      '<span><i style="display:inline-block;width:7px;height:7px;background:var(--accent-green);border-radius:2px;"></i> LOC reduced</span>' +
    '</div>';
}

class CockpitSolution extends HTMLElement {
  constructor() {
    super();
    this._data = null;
    this._loading = true;
    this._timer = null;
    this._onRefresh = this._onRefresh.bind(this);
  }

  connectedCallback() {
    if (this._ready) return;
    this._ready = true;
    this.addEventListener('lctx:refresh', this._onRefresh);
    this._timer = setInterval(this._onRefresh, SOLUTION_REFRESH_MS);
    this.loadData();
  }

  disconnectedCallback() {
    this.removeEventListener('lctx:refresh', this._onRefresh);
    if (this._timer) clearInterval(this._timer);
    this._timer = null;
    this._ready = false;
  }

  _onRefresh() {
    if (this.offsetParent !== null) this.loadData();
  }

  async loadData() {
    this._loading = true;
    this.render();
    try {
      var api = window.LctxApi;
      if (!api || typeof api.fetchJson !== 'function') throw new Error('Dashboard API unavailable');
      this._data = await api.fetchJson('/api/solution', { timeoutMs: 8000 });
    } catch (error) {
      this._data = { error: (error && error.message) || 'Unable to load solution intelligence' };
    }
    this._loading = false;
    this.render();
  }

  render() {
    var data = this._data || {};
    var output = data.output_savings || {};
    var loc = data.loc || {};
    var decisions = data.decisions || {};
    var trend = Array.isArray(data.trend_7d) ? data.trend_7d.slice(-7) : [];
    var topPatterns = Array.isArray(data.top_patterns) ? data.top_patterns.slice(0, 5) : [];
    var reduction = csolNumber(output.reduction_pct);
    var netReduced = csolNumber(loc.net_reduced);
    var decisionRows = [
      { label: 'STDLIB', value: csolNumber(decisions.stdlib), color: 'var(--accent-green)' },
      { label: 'REUSE', value: csolNumber(decisions.reuse), color: '#ad7cff' },
      { label: 'NATIVE', value: csolNumber(decisions.native), color: '#4f9dff' },
      { label: 'YAGNI', value: csolNumber(decisions.yagni), color: '#ff9d4f' },
      { label: 'DEBT', value: csolNumber(decisions.debt_open), color: 'var(--accent-red)' }
    ];
    var countedDecisions = decisionRows.slice(0, 4).reduce(function (total, row) { return total + row.value; }, 0);
    var totalDecisions = csolNumber(decisions.total) || countedDecisions;
    var maxDecision = Math.max.apply(null, decisionRows.map(function (row) { return row.value; }).concat([1]));
    var decisionHtml = decisionRows.map(function (row) {
      var width = Math.round((row.value / maxDecision) * 100);
      return '<div style="display:grid;grid-template-columns:70px 1fr 42px;gap:10px;align-items:center;margin:10px 0;">' +
        '<span style="color:var(--text-secondary);font-size:11px;letter-spacing:.08em;">' + row.label + '</span>' +
        '<div role="img" aria-label="' + row.label + ': ' + csolFormat(row.value) + '" style="height:8px;background:var(--border);border-radius:999px;overflow:hidden;"><div style="height:100%;width:' + width + '%;background:' + row.color + ';border-radius:inherit;"></div></div>' +
        '<span style="color:var(--text-primary);font-size:12px;text-align:right;">' + csolFormat(row.value) + '</span>' +
      '</div>';
    }).join('');
    var patternsHtml = topPatterns.length ? topPatterns.map(function (item) {
      return '<div style="display:flex;justify-content:space-between;gap:12px;margin:7px 0;font-size:12px;">' +
        '<span style="color:var(--text-secondary);overflow-wrap:anywhere;">' + csolEsc(item.pattern) + '</span>' +
        '<span style="color:var(--text-primary);">' + csolFormat(item.count) + '</span>' +
      '</div>';
    }).join('') : '<div style="color:var(--text-tertiary);font-size:12px;">No patterns recorded.</div>';
    var debtOpen = csolNumber(decisions.debt_open);
    var debtHtml = debtOpen ?
      '<div style="color:var(--accent-red);font-size:20px;font-weight:700;">' + csolFormat(debtOpen) + '</div><div style="color:var(--text-secondary);font-size:12px;margin-top:4px;">Open decision debt needs an explicit follow-up.</div>' :
      '<div style="color:var(--accent-green);font-size:14px;font-weight:600;">No active debt</div><div style="color:var(--text-secondary);font-size:12px;margin-top:4px;">All tracked decisions are resolved.</div>';
    var error = data.error ? '<div role="alert" style="margin-top:14px;color:var(--accent-red);font-size:12px;">' + csolEsc(data.error) + '</div>' : '';
    var loading = this._loading ? '<span style="color:var(--text-tertiary);font-size:11px;">REFRESHING</span>' : '';
    var intensity = String(data.intensity || 'balanced').toLowerCase();

    this.innerHTML = '<section aria-label="Solution Intelligence" style="background:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:20px;color:var(--text-primary);">' +
      '<header style="display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:18px;">' +
        '<h2 style="margin:0;font-size:13px;letter-spacing:.12em;">SOLUTION INTELLIGENCE</h2>' +
        '<label style="display:flex;align-items:center;gap:8px;color:var(--text-secondary);font-size:11px;letter-spacing:.08em;">INTENSITY ' +
          '<select aria-label="Configured solution intensity" disabled style="background:var(--bg);border:1px solid var(--accent-green);border-radius:6px;color:var(--accent-green);padding:4px 7px;text-transform:capitalize;">' +
            ['minimal', 'balanced', 'aggressive'].map(function (value) { return '<option' + (value === intensity ? ' selected' : '') + '>' + value + '</option>'; }).join('') +
          '</select></label>' + loading +
      '</header>' +
      '<div style="display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;">' +
        '<div style="border:1px solid var(--border);border-radius:8px;padding:13px;"><div style="color:var(--text-tertiary);font-size:10px;letter-spacing:.08em;">OUTPUT TOKEN REDUCTION</div><div style="color:var(--accent-green);font-size:25px;font-weight:700;margin-top:6px;">-' + csolPercent(reduction) + '</div><div style="color:var(--text-tertiary);font-size:10px;margin-top:3px;">' + csolFormat(output.tokens_optimized) + ' optimized / ' + csolFormat(output.tokens_total) + '</div></div>' +
        '<div style="border:1px solid var(--border);border-radius:8px;padding:13px;"><div style="color:var(--text-tertiary);font-size:10px;letter-spacing:.08em;">NET LOC IMPACT</div><div style="font-size:25px;font-weight:700;margin-top:6px;">' + (netReduced > 0 ? '-' + csolFormat(netReduced) : '+' + csolFormat(Math.abs(netReduced))) + '</div><div style="color:var(--text-tertiary);font-size:10px;margin-top:3px;">' + csolFormat(loc.added) + ' added / ' + csolFormat(loc.removed) + ' removed</div></div>' +
        '<div style="border:1px solid var(--border);border-radius:8px;padding:13px;"><div style="color:var(--text-tertiary);font-size:10px;letter-spacing:.08em;">DECISIONS</div><div style="font-size:25px;font-weight:700;margin-top:6px;">' + csolFormat(totalDecisions) + '</div><div style="color:var(--text-tertiary);font-size:10px;margin-top:3px;">this session</div></div>' +
      '</div>' +
      '<div style="margin-top:20px;"><div style="color:var(--text-secondary);font-size:11px;letter-spacing:.1em;">DECISION BREAKDOWN</div>' + decisionHtml + '</div>' +
      '<div style="display:grid;grid-template-columns:minmax(0,2fr) minmax(190px,1fr);gap:20px;margin-top:20px;">' +
        '<div style="border-top:1px solid var(--border);padding-top:14px;"><div style="color:var(--text-secondary);font-size:11px;letter-spacing:.1em;">7-DAY TREND</div>' + csolTrendChart(trend) + '</div>' +
        '<div style="border-top:1px solid var(--border);padding-top:14px;"><div style="color:var(--text-secondary);font-size:11px;letter-spacing:.1em;margin-bottom:8px;">ACTIVE DEBT</div>' + debtHtml + '</div>' +
      '</div>' +
      '<div style="border-top:1px solid var(--border);padding-top:14px;margin-top:20px;"><div style="color:var(--text-secondary);font-size:11px;letter-spacing:.1em;margin-bottom:8px;">TOP PATTERNS</div>' + patternsHtml + '</div>' +
      error +
    '</section>';
  }
}

if (!customElements.get('cockpit-solution')) customElements.define('cockpit-solution', CockpitSolution);

(function registerSolutionLoader() {
  function doRegister() {
    var router = window.LctxRouter;
    if (!router || !router.registerLoader) return;
    router.registerLoader('solution', function () {
      var element = document.getElementById('solutionView');
      if (element && typeof element.loadData === 'function') return element.loadData();
    });
  }
  if (window.LctxRouter && window.LctxRouter.registerLoader) doRegister();
  else document.addEventListener('DOMContentLoaded', doRegister);
}());

export { CockpitSolution };