npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

hazo_debug

v3.1.0

Published

Debug toolkit for hazo_* packages - permission-gated UI for inspecting runtime state, API calls, and configuration

Downloads

219

Readme

hazo_debug

Permission-gated debug toolkit for hazo_* packages. Provides a floating DevTools-like panel with 10 pluggable feature tabs for inspecting runtime state, API calls, errors, database queries, LLM prompts, file operations, and more.

Installation

npm install hazo_debug

Peer Dependencies (required)

npm install hazo_ui react react-dom

Optional Peer Dependencies

  • hazo_auth — Permission-gated access in production
  • hazo_config — INI config file reading
  • hazo_connect — Database query logging
  • hazo_files — File operation logging
  • hazo_llm_api — LLM prompt/response logging
  • hazo_logs (>=1.0.13) — Structured logging with on_log callback
  • lucide-react — Icons

Quick Start

1. Wrap your app with DebugProvider

// app/layout.tsx
import { DebugProvider } from 'hazo_debug/client';

export default function Layout({ children }) {
  return (
    <DebugProvider
      force_enabled={process.env.NODE_ENV === 'development'}
      hazo_logs_endpoint="/api/hazo_logs/client-log"
      hazo_logs_api="/api/logs"
    >
      {children}
    </DebugProvider>
  );
}

2. The debug panel appears automatically

Press Ctrl+Shift+D or click the floating bug icon in the bottom-right corner.

3. Log with hazo_debug_console

import { use_debug_log } from 'hazo_debug/client';

function MyComponent({ data }) {
  const { hazo_debug_console, log_event } = use_debug_log('MyComponent');

  function handleClick() {
    hazo_debug_console('info', 'Button clicked', { data });
    log_event('user_action', 'Button clicked', { data });
  }

  return <button onClick={handleClick}>Do something</button>;
}

hazo_debug_console() entries appear in both the hazo_logs and hazo_console tabs, and are dual-written to the server when hazo_logs_endpoint is configured.

4. Add debug icons to components

import { DebugIcon } from 'hazo_debug/client';

function MyComponent({ data }) {
  return (
    <div>
      <DebugIcon data={data} label="Props" component_name="MyComponent" />
    </div>
  );
}

5. Set up the server API (optional)

// app/api/hazo_debug/[...path]/route.ts
import { create_debug_api_handler } from 'hazo_debug/server';
export const { GET } = create_debug_api_handler();

Debug Panel Tabs

| Tab | Description | |-----|-------------| | Network | Intercepts all fetch() calls. Shows URL, method, status, timing, headers, body. | | Events | Chronological log of user actions, navigation, state changes. Filterable by category. | | Errors | Catches errors via <DebugErrorBoundary>, window.onerror, and unhandledrejection. | | hazo_auth | Displays current auth state, permissions, and user info. | | hazo_config | Shows INI config values (with secrets masked) and environment variables. | | hazo_connect | Database query log — operation, table, WHERE conditions, timing, rows, errors. | | hazo_llm_api | LLM prompt/response viewer — provider, model, timing, errors. Click to see full prompt and response. | | hazo_files | File operation log — upload, download, delete, move, extract with size, storage, timing. | | hazo_logs | Server-side logs (polled via hazo_logs_api) + hazo_debug_console() entries with level filter. | | hazo_console | Filtered view showing only hazo_debug_console() entries — the console.log replacement. |

Copy Debug Context for AI

The toolbar's clipboard button (📋) — or the keyboard shortcut Ctrl/Cmd+Shift+X — opens a dialog that captures a snapshot of every tab within a chosen time window and copies it to the clipboard. Use this when you want to hand a bug to Claude/ChatGPT/a teammate without manually screenshotting tabs.

The dialog:

  • Surfaces the most recent error (across error_log, debug_log[level=error], and request_log[status>=500]) and uses its timestamp as the default anchor.
  • Lets you pick a window: 5s / 30s / 60s / since panel opened / all buffered.
  • Includes a Notes field — free-text so the receiver knows what you were trying to do.
  • Redacts authorization, cookie, set-cookie, and proxy-authorization headers/keys recursively (toggleable).
  • Supports two output formats:
    • AI prompt (markdown) (default) — wraps the JSON in a Markdown frame with role/instruction text and a self-describing description field, ready to paste into a chat.
    • JSON only — raw snapshot.
  • Copy to clipboard + Download .md / .json.

Custom tabs in snapshots

To include a custom tab's data in copy-context output, provide get_snapshot on the registration. It receives the full DebugContextState and a { since, until } window and returns any JSON-serializable value — typically { entries: [...], total_in_buffer: N }.

use_register_debug_tab({
  id: 'orders',
  label: 'Orders',
  render: () => <OrdersPanel />,
  get_snapshot: (state, { since, until }) => ({
    entries: orders_log.filter(o => o.timestamp >= since && o.timestamp <= until),
    total_in_buffer: orders_log.length,
  }),
});

Tabs without get_snapshot appear in the snapshot as null so the receiver knows they exist but didn't expose state.

Hazo Package Integration Hooks

import {
  use_debug_query,   // hazo_connect: SQL queries
  use_debug_llm,     // hazo_llm_api: prompts/responses
  use_debug_files,   // hazo_files: file operations
  use_debug_log,     // hazo_logs: structured logging
} from 'hazo_debug/client';

// In components:
const { log_query } = use_debug_query();
const { log_llm_call } = use_debug_llm();
const { log_file_op } = use_debug_files();
const { hazo_debug_console } = use_debug_log('MyComponent');

Wire hazo_logs on_log callback

import { createClientLogger } from 'hazo_logs/ui';
import { use_debug_log } from 'hazo_debug/client';

const { hazo_debug_console } = use_debug_log('MyApp');
const logger = createClientLogger({
  packageName: 'my_app',
  on_log: hazo_debug_console,  // pipes all logs to debug panel + server
});

Registering Custom Panel Tabs

Any consumer package can add its own tab to the debug panel — or replace a built-in with a richer version — by calling use_register_debug_tab from a component mounted inside a DebugProvider.

'use client';
import { use_register_debug_tab } from 'hazo_debug/client';
import { HazoAuthDebugTab } from '../components/hazo_auth_debug_tab';

export function HazoAuthDebugBridge() {
  use_register_debug_tab({
    id: 'auth_display',
    label: 'hazo_auth',
    icon: 'Shield',
    priority: 50,
    overrides_builtin: true,
    badge: { count: 3, severity: 'warn' },
    render: () => <HazoAuthDebugTab />,
  });
  return null;
}

DebugTabRegistration

| Field | Type | Default | Notes | |---|---|---|---| | id | string | required | Unique identifier. Built-in ids: request_inspector, event_log, error_boundary, auth_display, config_viewer, query_log, llm_log, file_log, hazo_logs, hazo_console. | | label | string | required | Tab strip text. When overriding a built-in, an empty string preserves the built-in label. | | icon | string \| ComponentType | undefined | Lucide icon name (e.g. 'Shield') or a React component accepting { className, size }. | | priority | number | 200 | Lower is earlier. Built-ins use 100..199. | | overrides_builtin | boolean | false | Required to replace a built-in id. Without it the registration is rejected with a console warning. | | badge | { count?: number; severity?: 'info' \| 'warn' \| 'error' } | undefined | Static badge. Wins over get_badge. Omit count for a colored dot. | | get_badge | (state) => DebugTabBadge \| undefined | undefined | Dynamic badge resolver. Built-ins use this to derive counts from buffers. | | render | (ctx) => ReactNode | required | Called only when the tab is active. Receives the debug context value. | | visible | boolean | true | Hide without unregistering. |

Lifecycle

  • The hook dispatches REGISTER_TAB on mount and UNREGISTER_TAB on unmount.
  • When unmounting an override, the original built-in is restored automatically.
  • Field changes (badge count, label, etc.) are dispatched as UPDATE_TAB and do not re-mount the active tab content.
  • When DebugProvider is absent or debug is disabled, the hook is a no-op — no DOM, no state.
  • Two simultaneous registrations with the same id log a warning; the first one wins.

Declarative wrapper

If you prefer JSX:

import { RegisterDebugTab } from 'hazo_debug/client';

<RegisterDebugTab id="metrics" label="Metrics" priority={50}>
  <MyMetricsContent />
</RegisterDebugTab>

Permission Model

| Environment | Behavior | |-------------|----------| | NODE_ENV=development | Debug tools always available | | NODE_ENV=production | Requires debug_permission on user's hazo_auth role | | Config override | Set require_permission = false in hazo_debug_config.ini | | Prop override | Pass force_enabled={true} to <DebugProvider> |

When debug is disabled, all components render nothing and no data is captured (zero overhead).

Configuration

Copy config/hazo_debug_config.example.ini to your project's config/hazo_debug_config.ini:

[hazo_debug]
enabled = true
require_permission = true
permission_name = debug_permission
max_request_entries = 200
max_event_entries = 500
keyboard_shortcut = ctrl+shift+d
panel_position = bottom

Tailwind CSS

No configuration needed. hazo_debug injects its own self-contained stylesheet at runtime, scoped under [data-hazo-debug]. The debug panel works regardless of the consumer's Tailwind setup — no @source directive required.

API Reference

Components

  • <DebugProvider> — Context provider. Wrap your app root. Accepts force_enabled, features, hazo_logs_endpoint, hazo_logs_api, keyboard_shortcut, api_base_path.
  • <DebugIcon> — Bright blue bug icon that opens a debug dialog on click.
  • <DebugDialog> — Modal for structured debug data.
  • <DebugCopyDialog> — Copy-context dialog (rendered automatically inside DebugProvider; opens via toolbar 📋 or Ctrl/Cmd+Shift+X).
  • <DebugJsonView> — Collapsible JSON viewer.
  • <DebugErrorBoundary> — Error boundary that reports to the debug panel.
  • <DebugBadge> — Status/method/count pill (variants: default, success, warning, error, info).

Hooks

  • use_debug_log(source) — Returns { hazo_debug_console, log_debug, log_event }.
  • use_debug_query() — Returns { log_query } for hazo_connect SQL query logging.
  • use_debug_llm() — Returns { log_llm_call } for hazo_llm_api prompt/response logging.
  • use_debug_files() — Returns { log_file_op } for hazo_files operation logging.
  • use_debug_enabled() — Returns true if debug is active.
  • use_debug_context() — Full access to debug state and dispatch.

Server

  • create_debug_api_handler() — Next.js route handler for /api/hazo_debug.
  • get_debug_config() — Read INI config with masked secrets.
  • check_debug_permission() — Server-side auth check.

Types

All entry types are exported from the root hazo_debug import:

import type {
  QueryLogEntry,    // hazo_connect queries
  LlmLogEntry,      // hazo_llm_api calls
  FileLogEntry,     // hazo_files operations
  DebugLogEntry,    // debug log entries
  RequestLogEntry,  // network requests
  DebugEventEntry,  // events
  DebugErrorEntry,  // errors
} from 'hazo_debug';