roboticus-api 0.11.3

HTTP routes, WebSocket, auth, rate limiting, and dashboard for the Roboticus agent runtime
Documentation
  var HINTS_ENABLED_KEY = 'ic_hints_enabled';
  var HINTS_PROMPTED_KEY = 'ic_hints_prompted';
  var HINTS_DISMISSED_KEY = 'ic_hints_dismissed';
  /** Dashboard “Open wiki” target; keep in sync with repo docs. */
  var HELP_WIKI_URL = 'https://github.com/robot-accomplice/roboticus/wiki';
  function hintsEnabled() {
    try {
      var v = window.localStorage.getItem(HINTS_ENABLED_KEY);
      return v !== '0';
    } catch (_) {
      return true;
    }
  }
  function setHintsEnabled(enabled) {
    try { window.localStorage.setItem(HINTS_ENABLED_KEY, enabled ? '1' : '0'); } catch (_) {}
  }
  function loadDismissedHints() {
    try {
      var raw = window.localStorage.getItem(HINTS_DISMISSED_KEY);
      if (!raw) return {};
      var parsed = JSON.parse(raw);
      return parsed && typeof parsed === 'object' ? parsed : {};
    } catch (_) {
      return {};
    }
  }
  function saveDismissedHints(map) {
    try { window.localStorage.setItem(HINTS_DISMISSED_KEY, JSON.stringify(map || {})); } catch (_) {}
  }
  function dismissHint(id) {
    if (!id) return;
    var map = loadDismissedHints();
    map[id] = true;
    saveDismissedHints(map);
  }
  function isHintDismissed(id) {
    if (!id) return false;
    return !!loadDismissedHints()[id];
  }
  function clearHintDismissals() {
    saveDismissedHints({});
  }
  function disableAndClearHints() {
    setHintsEnabled(false);
    clearHintDismissals();
    try { window.localStorage.setItem('ic_sessions_helper_dismissed', '1'); } catch (_) {}
    try { window.localStorage.setItem('ic_dash_onboarding_dismissed', '1'); } catch (_) {}
  }
  function renderHintBanner(id, text) {
    return '<div class="hint-banner" data-hint-id="' + esc(id) + '">'
      + '<div class="hint-main"><span class="hint-icon" aria-hidden="true"><svg width="14" height="14" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" r="7" stroke="currentColor" stroke-width="1.3"/><circle cx="8" cy="4.4" r="0.9" fill="currentColor"/><path d="M8 7v4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/></svg></span><div class="hint-text">' + esc(text) + '</div></div>'
      + '<button class="hint-dismiss" data-dismiss-hint="' + esc(id) + '" title="Dismiss hint" aria-label="Dismiss hint">x</button>'
      + '</div>';
  }
  function maybePromptHintPreference() {
    var prompted = false;
    try { prompted = window.localStorage.getItem(HINTS_PROMPTED_KEY) === '1'; } catch (_) {}
    if (prompted) return;
    if (document.getElementById('hint-pref-overlay')) return;
    var overlay = document.createElement('div');
    overlay.id = 'hint-pref-overlay';
    overlay.className = 'hint-pref-overlay';
    overlay.innerHTML = '<div class="hint-pref-modal">'
      + '<div class="hint-pref-title">Show hints?</div>'
      + '<div class="hint-pref-copy">Hints call out useful next steps. You can change this anytime with the <strong>Help</strong> item in the sidebar (or header on small screens).</div>'
      + '<div class="hint-pref-actions">'
      + '<button class="btn secondary" id="hint-pref-no">No</button>'
      + '<button class="btn" id="hint-pref-yes">Yes</button>'
      + '</div></div>';
    document.body.appendChild(overlay);
    function finalize(enableHints) {
      try { window.localStorage.setItem(HINTS_PROMPTED_KEY, '1'); } catch (_) {}
      if (enableHints) setHintsEnabled(true); else disableAndClearHints();
      overlay.remove();
      if (App && App.page) App.navigate(App.page);
    }
    var noBtn = overlay.querySelector('#hint-pref-no');
    var yesBtn = overlay.querySelector('#hint-pref-yes');
    if (noBtn) noBtn.addEventListener('click', function() { finalize(false); });
    if (yesBtn) yesBtn.addEventListener('click', function() { finalize(true); });
  }
  try {
    if (window.localStorage.getItem('ic_sessions_helper_dismissed') === '1') dismissHint('sessions-helper');
  } catch (_) {}