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

@ai-setting/roy-plugin-tool-debug

v0.3.0

Published

roy-agent plugin: print compact single-line hook context (EnvContext + payload + project_path) at tool:after.execute and agent:before/after.llm for local debugging.

Readme

@ai-setting/roy-plugin-tool-debug

npm version license

roy-agent plugin that prints compact hook context (EnvContext + payload + project_path) at three hook points during local development. Drop it into any roy-agent host to see exactly what your hooks receive — no setup, no HTTP server, no UI.

What's new in v0.3.0

The plugin was emitting two compact debug boxes per tool invocation (tool:before.execute and tool:after.execute), each with a wide ┌─ … ─┐ / └─ … ┘ border. That's a lot of horizontal padding and visual noise for what is ultimately one logical event.

v0.3.0 collapses this into a single compact block per tool call, adds the related task's project_path (resolved via roy-agent tasks get, cached, with graceful degradation), and uses ASCII-free compact formatting:

[tool:after] bash ✓ 12ms  Task:#2090  Iter:N/A  Path:/home/.../roy-agent
  Args: {"cmd":"ls"}
  Res:  ok

The previous tool:before.execute hook is removed — its payload (args + EnvContext) is already visible in the after hook, so emitting twice per tool call was redundant.

Hook points

| Hook | Purpose | | ------------------- | ---------------------------------------------------------- | | tool:after.execute | EnvContext + args + result + project_path (if a task is associated) | | agent:before.llm | EnvContext + iteration + message count + project_path | | agent:after.llm | EnvContext + LLM content length + tool-call count + project_path |

Output format (v0.3.0+)

tool:after.execute emits a single-line header plus indented payload lines:

[tool:after] bash ✓ 12ms  Task:#2090  Iter:N/A  Sess:session_09617c10-…  Path:/home/dzk/.../roy-agent
  Args: {"cmd":"ls -la"}
  Res:  ok

Failure path uses ✗ in red:

[tool:after] write ✗ 8ms  Task:#2093  Path:/home/dzk/.../roy-agent
  Args: {"path":"/tmp/foo.txt","content":"aaaa…"}
  Res:  bbb…[truncated 36 chars]

When Args / Res exceeds indentWidth (default 100), they wrap onto multiple indented lines. The [truncated N chars] marker stays atomic on the last wrapped line.

agent:before.llm and agent:after.llm use the same compact single- line format with their own field set (iteration, message count, content length, tool-call count).

Color scheme

| Element | Color | SGR code | | ------------------ | -------- | -------- | | Tool name | white | 37 | | Key (label) | cyan | 36 | | Task / Iter / Count | yellow | 33 | | Session / Trace / Req ID | magenta | 35 | | Success (✓) | green | 32 | | Failure (✗) | red | 31 | | Duration (ms) / N/A / (none) | gray | 90 | | Default value | reset | 0 |

Controlling color

| Setting | Result | | ---------------- | --------------------------------------------------- | | color: "auto" | (default) ON when stdout is a TTY; respects NO_COLOR (off) and FORCE_COLOR (on) env vars. | | color: "always"| Force ANSI on (useful for CI logs that render color). | | color: "never" | Strip all ANSI (plain text only). | | NO_COLOR=1 | Disable color regardless of mode. Honors the no-color.org spec. | | FORCE_COLOR=1 | Enable color regardless of TTY. |

Install

bun add @ai-setting/roy-plugin-tool-debug
# or
npm install @ai-setting/roy-plugin-tool-debug

Usage

import { createToolDebugPlugin } from "@ai-setting/roy-plugin-tool-debug";

const plugin = createToolDebugPlugin({
  truncateAt: 500,          // max chars for args preview
  resultTruncateAt: 300,    // max chars for tool:after.execute result output
  bannerOnInit: true,       // print a one-line start banner on init()
  color: "auto",            // "auto" | "always" | "never"
  fieldSeparator: " │ ",    // field separator inside the compact line
  keyColor: "cyan",         // any AnsiColor: cyan | yellow | green | red | magenta | gray | white | reset
  showProjectPath: true,    // resolve and show task project_path (default: true)
  projectPathTtlMs: 60_000, // cache TTL for project_path lookups
  indentWidth: 100,         // wrap width for indented Args/Res/Path lines
});

await plugin.init(env);     // env is the host's BasePluginEnv (provides registerHook)

Config

All fields are optional. Defaults match the values in plugin.json.

| Field | Type | Default | Description | | ------------------ | -------------------------- | ------------- | -------------------------------------------------------- | | truncateAt | number | 500 | Max chars for args / llmOutput preview. | | resultTruncateAt | number | 300 | Override for tool:after.execute result output. | | bannerOnInit | boolean | true | Print a one-line start banner on init(). | | color | "auto" | "always" | "never" | "auto" | Color mode. Honors NO_COLOR / FORCE_COLOR / TTY. | | fieldSeparator | string | " │ " | Separator between fields in the compact line. | | keyColor | AnsiColor | "cyan" | Default ANSI color for keys. | | showProjectPath | boolean | true | Whether to resolve and display the task's project_path. | | projectPathTtlMs | number | 60000 | Cache TTL for project_path lookups (ms). 0 disables cache. | | indentWidth | number | 100 | Wrap width for indented payload lines (Args / Res / Path). |

Project path resolution

When a currentTaskId is present in the EnvContext, the plugin invokes

roy-agent tasks get <id> --json

to read the related task's project_path and renders it as a Path: field on every debug line. The resolver is cached (default TTL 60s) so it adds at most one CLI spawn per task per minute — negligible on real workloads.

The resolver gracefully degrades:

  • Task id missing → no Path: line.
  • CLI binary missing → no Path: line (no exception thrown).
  • Task id unknown / CLI exits non-zero → no Path: line.
  • JSON missing project_path → no Path: line.

You can disable the feature entirely with showProjectPath: false.

Why

When debugging hook semantics, the four things you usually want to know are:

  1. What is in the EnvContext?currentTaskId, iteration, sessionId, traceId, requestId, sourceId, userId, replyChannel.
  2. What payload did the hook receive?args, result, messages, llmOutput.
  3. Which project does this hook belong to?project_path from the related task.
  4. Which path did the value come from? — auto-injected by HookManager, or looked up via AsyncLocalStorage.

This plugin answers all four in one canonical place.

Compatibility

  • @ai-setting/roy-agent-core is an optional peer dependency. When the host ships it, the plugin reads the auto-injected EnvContext from ctx.metadata.envContext. When it doesn't, the plugin falls back to getEnvContext() from AsyncLocalStorage. Both code paths are tested.
  • roy-agent CLI is only invoked for project_path lookup. If the binary is not on PATH, that lookup degrades to "no path" — never a hard failure.

License

MIT