open-index/open-npm huggingface dataset:
npm package: @rovn-ai/cli
Description: Rovn CLI — governance toolkit for AI agents
Latest version: 0.3.0

# @rovn/cli

**Governance toolkit for AI agents** — monitor activities, check policies, and manage trust from the terminal.

## Install

```bash
npm install -g @rovn/cli
```

## Quick Start

```bash
# Register an agent
rovn init --name "My Agent" --email owner@example.com

# Log activities
rovn log --push "Deployed v2.1" --type deployment

# View recent activities
rovn log

# Pre-flight check
rovn check send_email --urgency high

# View trust score
rovn trust

# View report card
rovn report
```

## Multi-Agent Profiles

```bash
# Register multiple agents
rovn init --name "Claude Code" --as claude
rovn init --name "Cursor Agent" --as cursor

# Switch between agents
rovn use claude
rovn use cursor

# Check current agent
rovn whoami

# List all agents
rovn agents
```

## Commands

| Command | Description |
|---------|-------------|
| `rovn init` | Register a new agent |
| `rovn log` | View recent activities |
| `rovn log --push "title"` | Log a new activity |
| `rovn tasks` | View assigned tasks |
| `rovn tasks done <id>` | Mark task as completed |
| `rovn check <action>` | Pre-flight policy check |
| `rovn approve` | List pending approvals |
| `rovn approve request "title"` | Request approval |
| `rovn trust` | View trust score |
| `rovn report` | View report card |
| `rovn status` | Agent overview |
| `rovn agents` | List all registered agents |
| `rovn use <profile>` | Switch active agent |
| `rovn whoami` | Show current agent |

## Configuration

Agent credentials are stored in `~/.rovnrc`. This file is created automatically by `rovn init`.

## License

MIT
npm package: @rovn-ai/mcp-server
Description: Rovn MCP Server — governance tools for Claude, GPT, and any MCP-compatible agent
Latest version: 0.3.0

# @rovn/mcp-server

MCP (Model Context Protocol) server for [Rovn](https://rovn.io) — AI Agent governance tools for Claude, GPT, Cursor, and any MCP-compatible agent.

## Quick Start

```bash
npx @rovn/mcp-server --url https://rovn.io --email you@example.com
```

Or with an existing API key:

```bash
npx @rovn/mcp-server --url https://rovn.io --api-key rovn_...
```

## Claude Desktop / Claude Code Config

Add to your MCP configuration:

```json
{
  "mcpServers": {
    "rovn": {
      "command": "npx",
      "args": ["@rovn/mcp-server", "--url", "https://rovn.io", "--email", "you@example.com"]
    }
  }
}
```

## Available Tools

| Tool | Description |
|------|-------------|
| `rovn_register` | Register agent with Rovn. Returns API key and agent ID. |
| `rovn_log_activity` | Log what the agent has done. |
| `rovn_check_action` | Pre-flight check — is this action allowed? |
| `rovn_request_approval` | Request owner approval for risky actions. |
| `rovn_get_tasks` | Get tasks assigned to this agent. |
| `rovn_update_task` | Update task status. |
| `rovn_get_report_card` | Get performance report card with grades. |
| `rovn_get_trust_score` | Get Trust Score (0-100). |

## Features

- **Zero dependencies** — uses only Node.js built-in APIs
- **Auto-logging** — governance tool calls are automatically recorded
- **HTTP hardening** — 15s timeout, status-specific error messages, safe JSON parsing
- **Register reuse** — validates existing credentials before re-registering
- **29 tests** — comprehensive test coverage

## CLI Arguments

| Flag | Env Variable | Default | Description |
|------|-------------|---------|-------------|
| `--url` | `ROVN_URL` | `https://rovn.io` | Rovn server URL |
| `--email` | `ROVN_OWNER_EMAIL` | — | Owner email for agent registration |
| `--api-key` | `ROVN_API_KEY` | — | Existing API key |
| `--agent-id` | `ROVN_AGENT_ID` | — | Existing agent ID |

## License

MIT
npm package: @rovzashop/reviews
Description: A reusable React review component for modern eCommerce apps.
Author: Arvymo
Latest version: 2.0.3

# @rovzashop/rovza-reviews
A React Rating & Reviews component for modern e-commerce apps.

<!-- 🚀 COMING SOON -->

You must have an account in https://www.rovza.shop

## 🚀 Installation
```bash
npm install @rovzashop/reviews
```

or

```bash
yarn add @rovzashop/reviews
```

## 💡 Usage
```jsx
import { RovzaReviews, RovzaInlineRating } from '@rovzashop/reviews';

// Add the Reviews component to your Product Page
<RovzaReviews 
    brand={BRAND_NAME}
    environment={ROVZA_ENVIRONMENT} // development | production
    appId={APP_ID}
    apiKey={API_KEY}
    productData={{
        id: PRODUCT_ID,
        name: PRODUCT_NAME,
        imageUrl: PRODUCT_IMAGE,
        link: PRODUCT_LINK
    }}
/>

// Add the Inline Rating component near the product name
<RovzaInlineRating 
    brand={BRAND_NAME}
    environment={ROVZA_ENVIRONMENT} // development | production
    appId={APP_ID}
    apiKey={API_KEY}
    productId={PRODUCT_ID}
/>
```
npm package: @rovzashop/reviews-dev
Description: A reusable React review component for modern eCommerce apps.
Author: Arvymo
Latest version: 1.8.3

# @rovzashop/rovza-reviews
A React Rating & Reviews component for modern e-commerce apps.

<!-- 🚀 COMING SOON -->

You must have an account in http://localhost:5050

## 🚀 Installation
```bash
npm install @rovzashop/reviews-dev
```

or

```bash
yarn add @rovzashop/reviews-dev
```

## 💡 Usage
```jsx
import { RovzaReviews, RovzaInlineRating } from '@rovzashop/reviews-dev';

// Add the Reviews component to your Product Page
<RovzaReviews 
    brand={BRAND_NAME}
    environment={ROVZA_ENVIRONMENT} // development | production
    appId={APP_ID}
    apiKey={API_KEY}
    productData={{
        id: PRODUCT_ID,
        name: PRODUCT_NAME,
        imageUrl: PRODUCT_IMAGE,
        link: PRODUCT_LINK
    }}
/>

// Add the Inline Rating component near the product name
<RovzaInlineRating 
    brand={BRAND_NAME}
    environment={ROVZA_ENVIRONMENT} // development | production
    appId={APP_ID}
    apiKey={API_KEY}
    productId={PRODUCT_ID}
/>
```
npm package: @rowan287630/ui
Description: RW React UI 组件库 - 现代化的 React 组件集合
Author: rowan
Latest version: 0.1.0

# @rw/ui

现代化的 React UI 组件库，基于 TypeScript 构建，支持 Tailwind CSS。

## 🚀 特性

* 💪 **TypeScript** - 完整的类型支持
* 🎨 **Tailwind CSS** - 现代化的样式系统
* 📦 **Tree Shaking** - 按需加载，优化包体积
* 🔧 **易于定制** - 支持自定义样式和主题
* ⚡ **轻量级** - 小巧精简，性能优越

## 📦 安装

```bash
# npm
npm install @rowan287630/ui

# yarn
yarn add @rowan287630/ui

# pnpm
pnpm add @rowan287630/ui
```

## 🔧 使用

### 基本用法

```tsx
import React from 'react'
import { Button } from '@rw/ui'

function App() {
  return (
    <div>
      <Button onClick={() => console.log('Hello!')}>
        点击我
      </Button>
    </div>
  )
}
```

### Button 组件

```tsx
import { Button } from '@rw/ui'

// 基本按钮
<Button>默认按钮</Button>

// 不同类型
<Button type="primary">主按钮</Button>
<Button type="secondary">次要按钮</Button>
<Button type="outline">轮廓按钮</Button>

// 不同尺寸
<Button size="small">小按钮</Button>
<Button size="medium">中等按钮</Button>
<Button size="large">大按钮</Button>

// 禁用状态
<Button disabled>禁用按钮</Button>

// 自定义样式
<Button className="bg-red-500 hover:bg-red-600">
  自定义按钮
</Button>
```

## 📋 API 文档

### Button


| 属性      | 类型                                                   | 默认值      | 说明             |
| --------- | ------------------------------------------------------ | ----------- | ---------------- |
| type      | `'primary'                                             | 'secondary' | 'outline'`       |
| size      | `'small'                                               | 'medium'    | 'large'`         |
| disabled  | `boolean`                                              | `false`     | 是否禁用         |
| onClick   | `(event: React.MouseEvent<HTMLButtonElement>) => void` | -           | 点击事件处理函数 |
| className | `string`                                               | -           | 自定义 CSS 类名  |
| children  | `React.ReactNode`                                      | -           | 按钮内容         |

## 🎨 样式依赖

本组件库基于 Tailwind CSS 构建。如果你的项目中还没有 Tailwind CSS，请先安装：

```bash
npm install tailwindcss
```

或者你可以通过 CDN 引入基础样式：

```html
<link href="https://cdn.tailwindcss.com" rel="stylesheet">
```

## 📦 开发

```bash
# 克隆项目
git clone https://github.com/你的用户名/rw-ui.git

# 安装依赖
pnpm install

# 构建组件库
pnpm build

# 开发模式
pnpm dev
```

## 🤝 贡献

欢迎提交 Issue 和 Pull Request！

## 📄 许可证

MIT License - 详见 [LICENSE](https://claude.ai/chat/LICENSE) 文件

## 🔗 相关链接

* [GitHub](https://github.com/%E4%BD%A0%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D/rw-ui)
* [npm](https://www.npmjs.com/package/@rw/ui)
* [文档](https://github.com/%E4%BD%A0%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D/rw-ui#readme)

## 更新日志

### 0.1.0

* ✨ 新增 Button 组件
* 🎨 支持多种样式和尺寸
* 📦 初始版本发布
npm package: @rowan287630/zhui
Description: 基于 Element UI 的 Vue 2 组件库
Author: rowan287630
Latest version: 0.2.1

# @rowan287630/zhui

基于 Element UI 的 Vue 2 组件库

[![npm version](https://img.shields.io/npm/v/@rowan287630/zhui.svg)](https://www.npmjs.com/package/@rowan287630/zhui)
[![npm downloads](https://img.shields.io/npm/dm/@rowan287630/zhui.svg)](https://www.npmjs.com/package/@rowan287630/zhui)
[![license](https://img.shields.io/npm/l/@rowan287630/zhui.svg)](https://github.com/rowan766/zhui-library/blob/main/LICENSE)

## ✨ 特性

- 基于 Element UI 二次封装
- 保持 Element UI 原有 API
- 支持完整引入和按需引入
- 提供 ES Module、CommonJS、UMD 三种格式

## 📦 安装

```bash
# npm
npm install @rowan287630/zhui element-ui vue

# pnpm
pnpm add @rowan287630/zhui element-ui vue

# yarn
yarn add @rowan287630/zhui element-ui vue
```

## 🚀 使用

### 完整引入

```js
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import Zhui from '@rowan287630/zhui'

Vue.use(ElementUI)
Vue.use(Zhui)
```

### 按需引入

```js
import { MyButton } from '@rowan287630/zhui'

Vue.component(MyButton.name, MyButton)
```

### CDN 引入

```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/element-ui@2.15.14/lib/theme-chalk/index.css">
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/element-ui@2.15.14/lib/index.js"></script>
<script src="https://unpkg.com/@rowan287630/zhui@latest/dist/index.js"></script>

<script>
  Vue.use(ELEMENT)
  Vue.use(Zhui)
</script>
```

## 📚 组件

### MyButton

基于 `el-button` 封装的按钮组件，支持所有 Element UI Button 的属性和事件。

```vue
<template>
  <div>
    <my-button>默认按钮</my-button>
    <my-button type="primary">主要按钮</my-button>
    <my-button type="success" size="small">成功按钮</my-button>
  </div>
</template>
```

#### Props

| 参数 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| type | 按钮类型 | string | default |
| size | 按钮尺寸 | string | medium |
| ... | 支持所有 el-button 的属性 | - | - |

#### Events

继承 `el-button` 的所有事件，如 `click`、`focus` 等。

## 🔨 开发

```bash
# 构建
pnpm build

# 清理
pnpm clean
```

## 📝 Changelog

详见 [CHANGELOG.md](./CHANGELOG.md)

## 📄 License

[MIT](../../LICENSE)
npm package: @rowana/core
Description: Core package for Rowana GEO - Automates Schema.org JSON-LD generation during build time.
Author: Jaymin West
Latest version: 0.1.0

# @rowana/core

Core package for Rowana GEO - Automates Schema.org JSON-LD generation during build time.

## Installation

```bash
npm install @rowana/core
```

(More details to come)
npm package: @rowana/rowana-core
Description: Core package for Rowana GEO - Automates Schema.org JSON-LD generation during build time.
Author: Rowana
Latest version: 0.1.1

# @rowana-ai/rowana-core

Stay tuned :)

Core package for Rowana GEO - Automates JSON-LD generation during build time.

## Installation

Install the package using npm:

```bash
npm install @rowana/rowana-core
```

Or using yarn:

```bash
yarn add @rowana/rowana-core
```

## Usage

Import the `generateJsonLd` function and use it to create your JSON-LD strings.

```typescript
import { generateJsonLd } from '@rowana/rowana-core';

// Example data (replace with your actual data structure)
const myData = {
  pageTitle: "My Awesome Page",
  description: "This page is truly awesome."
};

const jsonLdString = generateJsonLd(myData);

console.log(jsonLdString);
// Output (currently placeholder): {"@context":"https://schema.org","@type":"WebPage","name":"Placeholder"}

// You can then inject this string into a <script type="application/ld+json"> tag in your HTML.
```

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
npm package: @rowanmanning/biome-config
Description: Shared Biome linting/formatting configurations for my projects
Author: Rowan Manning
Latest version: 3.1.0


# Biome Config

Shared [Biome](https://biomejs.dev/) linting/formatting configurations for my projects.

* [Requirements](#requirements)
* [Usage](#usage)
* [Contributing](#contributing)
* [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install with [npm](https://www.npmjs.com/) (`biome` will be included):

```sh
npm install --save-dev @rowanmanning/biome-config
```

Add this to your `biome.json` file:

```json
{
    "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
    "extends": ["./node_modules/@rowanmanning/biome-config/config.json"]
}
```


## Contributing

Genuinely unless you're Rowan Manning, you probably don't need to contribute to this. However, if you decide you really need to, then [the contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2024, Rowan Manning
npm package: @rowanmanning/dedent
Description: An ES6 string tag that strips indentation from multi-line strings
Author: Desmond Brand
Latest version: 0.7.0

# Dedent

An ES6 string tag that strips indentation from multi-line strings.

## Usage

```js
import dedent from "dedent";

function usageExample() {
  const first = dedent`A string that gets so long you need to break it over
                       multiple lines. Luckily dedent is here to keep it
                       readable without lots of spaces ending up in the string
                       itself.`;

  const second = dedent`
    Leading and trailing lines will be trimmed, so you can write something like
    this and have it work as you expect:

      * how convenient it is
      * that I can use an indented list
         - and still have it do the right thing

    That's all.
  `;

  const third = dedent(`
    Wait! I lied. Dedent can also be used as a function.
  `);

  return first + "\n\n" + second + "\n\n" + third;
}
```

```js
> console.log(usageExample());
```

```
A string that gets so long you need to break it over
multiple lines. Luckily dedent is here to keep it
readable without lots of spaces ending up in the string
itself.

Leading and trailing lines will be trimmed, so you can write something like
this and have it work as you expect:

  * how convenient it is
  * that I can use an indented list
    - and still have it do the right thing

That's all.

Wait! I lied. Dedent can also be used as a function.
```

## License

MIT
npm package: @rowanmanning/eslint-config
Description: Shared linter configurations for my projects
Author: Rowan Manning
Latest version: 8.1.0
Deprecated: This module is no longer maintained.


# ESLint Config

A shared [ESLint](https://eslint.org/) config for my open source projects.


## Table of Contents

  * [Requirements](#requirements)
  * [Usage](#usage)
  * [Contributing](#contributing)
  * [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 18+


## Usage

Install with [npm](https://www.npmjs.com/) alongside `eslint`:

```sh
npm install --save-dev eslint @rowanmanning/eslint-config
```

Add this to your `.eslintrc` file:

```json
{
    "extends": "@rowanmanning/eslint-config"
}
```

If your project uses JSX via Preact, add this instead:

```json
{
    "extends": [
        "@rowanmanning/eslint-config",
        "@rowanmanning/eslint-config/jsx"
    ]
}
```


## Contributing

Genuinely unless you're Rowan Manning, you probably don't need to contribute to this. However if you decide you really need to, then [the contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

ESLint Config is licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2020, Rowan Manning
npm package: @rowanmanning/get-all-emoji-in-a-slack-channel
Description: Get all emoji in a public Slack channel
Author: Rowan Manning
Latest version: 6.1.0


# @rowanmanning/get-all-emoji-in-a-slack-channel

Get all emoji in a public Slack channel.

* [Requirements](#requirements)
* [Usage](#usage)
* [Migration](#migration)
* [Contributing](#contributing)
* [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install alongside the Slack web API with [npm](https://www.npmjs.com/):

```sh
npm install @slack/web-api @rowanmanning/get-all-emoji-in-a-slack-channel
```

Load the library into your code with a `require` call (you'll also need the Slack `WebClient` class):

```js
const { WebClient } = require('@slack/web-api');
const { getAllEmojiInASlackChannel } = require('@rowanmanning/get-all-emoji-in-a-slack-channel');
```

Get all occurrences of an emoji in a Slack channel:

```js
const slackWebClient = new WebClient('YOUR-SLACK-TOKEN');
const emojiOccurrences = await getAllEmojiInASlackChannel(slackWebClient, 'YOUR-CHANNEL-ID');
```

`emojiOccurrences` will be an array of objects which look like this:

```js
{
    emoji: String,         // The name of the emoji that was used (excluding wrapping colons)
    modifierEmoji: String, // The name of any modifier emoji (currently only skin-tone modifiers)
    user: String,          // The Slack user ID of the person who used this emoji
    ts: String,            // The Slack timestamp for the message that this emoji appear in
    isReaction: Boolean    // Whether the emoji was a reaction rather than part of the message
}
```


## Migration

A new major version of this project is released if breaking changes are introduced. We maintain a [migration guide](docs/migration.md) to help users migrate between these versions.


## Contributing

[The contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2019, Rowan Manning
npm package: @rowanmanning/get-all-messages-in-a-slack-channel
Description: Get all messages in a public Slack channel
Author: Rowan Manning
Latest version: 6.1.0


# @rowanmanning/get-all-messages-in-a-slack-channel

Get all messages in a public Slack channel.

* [Requirements](#requirements)
* [Usage](#usage)
* [Migration](#migration)
* [Contributing](#contributing)
* [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install alongside the Slack web API with [npm](https://www.npmjs.com/):

```sh
npm install @slack/web-api @rowanmanning/get-all-messages-in-a-slack-channel
```

Load the library into your code with a `require` call (you'll also need the Slack `WebClient` class):

```js
const { WebClient } = require('@slack/web-api');
const { getAllMessagesInASlackChannel } = require('@rowanmanning/get-all-messages-in-a-slack-channel');
```

Get all the messages in a Slack channel:

```js
const slackWebClient = new WebClient('YOUR-SLACK-TOKEN');
const messages = await getAllMessagesInASlackChannel(slackWebClient, 'YOUR-CHANNEL-ID');
```

See the [Slack `channels.history` response documentation](https://api.slack.com/methods/channels.history#response) for info on what the messages look like.


## Migration

A new major version of this project is released if breaking changes are introduced. We maintain a [migration guide](docs/migration.md) to help users migrate between these versions.


## Contributing

[The contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2019, Rowan Manning
npm package: @rowanmanning/get-error-http-status
Description: Get the HTTP status code for an error object
Author: Rowan Manning
Latest version: 4.2.0


# @rowanmanning/get-error-http-status

Get the HTTP status code for an error object.

* [Requirements](#requirements)
* [Usage](#usage)
  * [`getErrorHttpStatus`](#geterrorhttpstatus)
  * [`isErrorHttpStatus`](#iserrorhttpstatus)
* [Migration](#migration)
* [Contributing](#contributing)
* [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install with [npm](https://www.npmjs.com/):

```sh
npm install @rowanmanning/get-error-http-status
```

Load the library into your code with a `require` call:

```js
const { getErrorHttpStatus } = require('@rowanmanning/get-error-http-status');
```

### `getErrorHttpStatus`

Call the method with an error object to get the status code:

```js
const notFoundError = new Error('Not Found');
notFoundError.status = 404;

const status = getErrorHttpStatus(error); // 404
```

If there is no `status` property present on the error, then we fall back to the `statusCode` property:

```js
const notFoundError = new Error('Not Found');
notFoundError.statusCode = 404;

const status = getErrorHttpStatus(error); // 404
```

If the `status` or `statusCode` property is a string, it will be parsed as an number before continuing.

In any of the following scenarios, the function will return a default status code of `500`:

  * The error is not an error object or a plain JavaScript object
  * The error status property is less than `400` or greater than `599`
  * The error status property is a decimal
  * The error status property is a non-numeric string

### `isErrorHttpStatus`

This library exposes a second method named `isErrorHttpStatus`. You can use this to determine whether a given value is a valid error HTTP status (integer, `400` to `599`):

```js
const { isErrorHttpStatus } = require('@rowanmanning/get-error-http-status');

isErrorHttpStatus(500); // true
isErrorHttpStatus(200); // false
isErrorHttpStatus('abc'); // false
```

## Migration

A new major version of this project is released if breaking changes are introduced. We maintain a [migration guide](docs/migration.md) to help users migrate between these versions.


## Contributing

[The contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2024, Rowan Manning
npm package: @rowanmanning/hijack-express-render
Description: Override an Express application's render methods
Author: Rowan Manning
Latest version: 4.0.0
Deprecated: This module is no longer maintained.


# @rowanmanning/hijack-express-render

Override an [Express](https://expressjs.com) (4.x) application's render methods. This function replaces the `app.render` and `response.render` methods of an Express application, allowing you to bypass Express view rendering entirely.

This allows you to implement your own template resolution and caching, but retain the standard Express API.

**:warning: This is probably a bad idea, and prone to breaking if Express changes the way it renders things**


## Table of Contents

  * [Requirements](#requirements)
  * [Usage](#usage)
  * [Contributing](#contributing)
  * [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 18+


## Usage

Install with [npm](https://www.npmjs.com/):

```sh
npm install @rowanmanning/hijack-express-render
```

Load the library into your code with a `require` call:

```js
const hijackExpressRender = require('@rowanmanning/hijack-express-render');
```

Create an [Express](https://expressjs.com) application and call `hijackExpressRender` with this and a new render method (see [Render Methods](#render-methods) below):

```js
const express = require('express');
const hijackExpressRender = require('@rowanmanning/hijack-express-render');

const app = express();
hijackExpressRender(app, yourRenderMethod);
```

The `hijackExpressRender` also returns the Express application, so you can do this in one line:

```js
const app = hijackExpressRender(express(), yourRenderMethod);
```

Hijacking of the render methods must happen before any middleware that uses `app.render` or `response.render`. It's safest to hijack immediately after creating the Express application.

### Render Methods

The render method you can pass into `hijackExpressRender` must:

  1. Accept two parameters…
      1. **`view`:** The name of the view to render (normally a string). This will not be relative to the Express "view" directory – it is exactly what was passed into `app.render` or `response.render`. Your method must handle its own template resolution and caching. You may also use a non-string here if your renderer supports this
      2. **`context`:** The render context (as an object). This will be defaulted using `app.locals` and `response.locals` in the same way as the default Express rendering engine
  2. Return a `Promise` which resolves with the rendered template. This is normally a string but can be any type that's accepted by `response.send`

Example with a Promise:

```js
function renderMethod(view, context) {
    return Promise.resolve('result');
}
```

Example with an async function:

```js
async function renderMethod(view, context) {
    return 'result';
}
```


## Contributing

[The contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2019, Rowan Manning
npm package: @rowanmanning/list-all-files
Description: List all files in a directory
Author: Rowan Manning
Latest version: 5.1.0
Deprecated: This library has been deprecated and will no longer receive feature updates or security patches.


# @rowanmanning/list-all-files

List all files in a directory recursively.

> [!WARNING]
> This library will be deprecated in April 2026 to coincide with the end-of-life date for Node.js 20. This is because the native [`fs.glob`](https://nodejs.org/api/fs.html#fspromisesglobpattern-options) and [`fs.globSync`](https://nodejs.org/api/fs.html#fsglobsyncpattern-options) methods in Node.js 22 and above provide the same functionality.

* [Requirements](#requirements)
* [Usage](#usage)
  * [Asynchronous Interface](#asynchronous-interface)
  * [Synchronous Interface](#synchronous-interface)
* [Migration](#migration)
* [Contributing](#contributing)
* [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install with [npm](https://www.npmjs.com/):

```sh
npm install @rowanmanning/list-all-files
```

### Asynchronous Interface

Load the library into your code with `require`:

```js
const { listAllFiles } = require('@rowanmanning/list-all-files');
```

List all files in a directory asynchronously, using promises or `async`/`await`:

```js
listAllFiles('./directory-path').then(files => {
    // files is an array of strings, each being the path to a file
});
```

or

```js
const files = await listAllFiles('./directory-path');
// files is an array of strings, each being the path to a file
```

### Synchronous Interface

Load the library into your code with `require`:

```js
const { listAllFilesSync } = require('@rowanmanning/list-all-files');
```

List all files in a directory synchronously:

```js
const files = listAllFilesSync('./directory-path');
// files is an array of strings, each being the path to a file
```


## Migration

A new major version of this project is released if breaking changes are introduced. We maintain a [migration guide](docs/migration.md) to help users migrate between these versions.


## Contributing

[The contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2020, Rowan Manning
npm package: @rowanmanning/minecraft-inventory-inspector
Description: Inspect the inventories and ender chests of players on a Vanilla Minecraft server, rendering results as Markdown.
Author: Rowan Manning
Latest version: 4.0.0
Deprecated: This library has been deprecated and will no longer receive feature updates or security patches.


# Minecraft Inventory Inspector

Inspect the inventories and ender chests of players on a Vanilla Minecraft server, rendering results as Markdown.

Caveats:

1. I probably don't maintain this any more, I needed it once and don't care about it a lot
2. I tested this with Minecraft 1.15, 1.16, 1.17, and 1.18. It may break in future
3. This only works for servers, it will ignore the player data for single player worlds and probably output nothing


## Table of Contents

  * [Requirements](#requirements)
  * [Usage](#usage)
  * [Contributing](#contributing)
  * [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install globally with [npm](https://www.npmjs.com/):

```sh
npm install -g @rowanmanning/minecraft-inventory-inspector
```

Then run:

```sh
mii /path/to/minecraft/world/save
```

Alternatively use `npx`:

```sh
npx @rowanmanning/minecraft-inventory-inspector /path/to/minecraft/world/save
```

These commands will output Markdown which represents the player inventories. To view this nicely rendered, you'll need to process it yourself or paste it in a [Gist](https://gist.github.com/) or something.


## Contributing

[The contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2020, Rowan Manning
npm package: @rowanmanning/not-found
Description: Create Express middleware which results in an HTTP 404 Not Found error
Author: Rowan Manning
Latest version: 6.1.0


# @rowanmanning/not-found

Create Express middleware which results in an HTTP 404 Not Found error.

* [Requirements](#requirements)
* [Usage](#usage)
* [Migration](#migration)
* [Contributing](#contributing)
* [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install with [npm](https://www.npmjs.com/):

```sh
npm install @rowanmanning/not-found
```

Load the library into your code with a `require` call:

```js
const { notFound } = require('@rowanmanning/not-found');
```

Create middleware which results in an HTTP 404 error in [Express](https://expressjs.com):

```js
const express = require('express');
const { notFound } = require('@rowanmanning/not-found');

const app = express();

app.use(notFound());
```

Handle the 404 error like you would any other error in Express:

```js
app.use((error, request, response, next) => {
    response.status(error.status); // 404
    response.send(error.message); // Not Found
});
```

Customise the error message with an option:

```js
app.use(notFound({
    message: 'This page does not exist'
}));

app.use((error, request, response, next) => {
    response.status(error.status); // 404
    response.send(error.message); // This page does not exist
});
```


## Migration

A new major version of this project is released if breaking changes are introduced. We maintain a [migration guide](docs/migration.md) to help users migrate between these versions.


## Contributing

[The contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2019, Rowan Manning
npm package: @rowanmanning/npm-workspaces
Description: Get a list of all the npm workspaces found in a package lock file
Author: Rowan Manning
Latest version: 2.1.0


# @rowanmanning/npm-workspaces

Get a list of all the npm workspaces found in a `package-lock.json` file.

* [Requirements](#requirements)
* [Usage](#usage)
  * [`getPackageWorkspaces()`](#getpackageworkspaces)
* [Contributing](#contributing)
* [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install with [npm](https://www.npmjs.com/):

```sh
npm install @rowanmanning/npm-workspaces
```

Load one of the methods into your code with `import` or `require`:

```js
import { getPackageWorkspaces } from '@rowanmanning/npm-workspaces';
// or
const { getPackageWorkspaces } = require('@rowanmanning/npm-workspaces');
```

The following exports are available.

### `getPackageWorkspaces()`

A function to list the npm workspaces that a `package-lock.json` file defines. This function has the following signature:

```ts
(packageLock: PackageLock) => string[]
```

`PackageLock` must be a JavaScript object that is a valid `package-lock.json` or `package-lock.json` file. We recommend using [@rowanmanning/package-json](../package-json#readme) or [@npmcli/package-json](https://github.com/npm/package-json#readme).

```js
const workspaces = getPackageWorkspaces(require('./package-lock.json'));
// ['', 'packages/example-1', 'packages/example-2']
```


## Contributing

[See the central README for a contribution guide and code of conduct](https://github.com/rowanmanning/repo-tools#contributing).


## License

Licensed under the [MIT](https://github.com/rowanmanning/repo-tools/blob/main/LICENSE) license.<br/>
Copyright &copy; 2024, Rowan Manning
npm package: @rowanmanning/package-json-github
Description: Load and parse package.json and package-lock.json files from GitHub repositories
Author: Rowan Manning
Latest version: 2.1.0


# @rowanmanning/package-json-github

Load and parse `package.json` and `package-lock.json` files from GitHub repositories.

* [Requirements](#requirements)
* [Usage](#usage)
  * [`packageJson.fromGitHub()`](#packagejsonfromgithub)
  * [`packageLock.fromGitHub()`](#packagelockfromgithub)
  * [Options](#options)
* [Contributing](#contributing)
* [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install with [npm](https://www.npmjs.com/):

```sh
npm install @rowanmanning/package-json-github
```

Load into your code with `import` or `require`:

```js
import { packageJson, packageLock } from '@rowanmanning/package-json-github';
// or
const { packageJson, packageLock } = require('@rowanmanning/package-json-github');
```

The following exports are available.

### `packageJson.fromGitHub()`

Load the `package.json` file present in a GitHub repo.

```ts
(options: GitHubOptions) => Promise<PackageJson>
```

The `options` argument must be an object. [The available options are documented here](#options).

```js
const pkg = await packageJson.fromGitHub({
    auth: process.env.GITHUB_AUTH_TOKEN,
    owner: 'rowanmanning',
    repo: 'yeehaw'
});
// { name: '@rowanmanning/yeehaw', version: '2.0.0', ... }
```

### `packageLock.fromGitHub()`

Load the `package-lock.json` file present in a GitHub repo.

```ts
(options: GitHubOptions) => Promise<PackageLock>
```

The `options` argument must be an object. [The available options are documented here](#options).

```js
const pkg = await packageLock.fromGitHub({
    auth: process.env.GITHUB_AUTH_TOKEN,
    owner: 'rowanmanning',
    repo: 'yeehaw'
});
// { lockfileVersion: 2, name: '@rowanmanning/yeehaw', version: '2.0.0', ... }
```

### Options

The `options` argument must be an object. It's required and has the following properties. These are passed directly to the GitHub REST API, please [consult the API documentation for more information](https://docs.github.com/en/rest/repos/contents?apiVersion=2022-11-28#get-repository-content).

  * `auth` (`string`, required). A [GitHub token](https://docs.github.com/en/rest/authentication/authenticating-to-the-rest-api) with read access to the repo you specify

  * `owner` (`string`, required). The name of the GitHub user or organisation that the repo belongs to

  * `repo` (`string`, required). The name of the GitHub repo

  * `path` (`string`, optional). The path to the file you'd like to read. Defaults to `package.json` or `package-lock.json` depending on the method you're using

  * `ref` (`string`, optional). The name of the commit, branch, or tag to fetch the file from. Defaults to the repo's default branch


## Contributing

[See the central README for a contribution guide and code of conduct](https://github.com/rowanmanning/repo-tools#contributing).


## License

Licensed under the [MIT](https://github.com/rowanmanning/repo-tools/blob/main/LICENSE) license.<br/>
Copyright &copy; 2024, Rowan Manning
npm package: @rowanmanning/require-all
Description: Require all modules in a directory recursively
Author: Rowan Manning
Latest version: 5.1.0
Deprecated: This library has been deprecated and will no longer receive feature updates or security patches.


# @rowanmanning/require-all

Require all modules in a directory recursively.

* [Requirements](#requirements)
* [Usage](#usage)
* [Migration](#migration)
* [Contributing](#contributing)
* [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install with [npm](https://www.npmjs.com/):

```sh
npm install @rowanmanning/require-all
```

Load the library into your code with a `require` call:

```js
const { requireAll } = require('@rowanmanning/require-all');
```

Require all modules in a directory. **Note:** this loads modules synchronously, so it's best used only where blocking doesn't matter, e.g. in your application's startup process:

```js
const modules = requireAll('./directory-path');
```

`modules` is an array of objects, each being information about the module:

```js
{
    // The name of the file, this is relative to the given directory path
    // and does not include the file extension or a leading slash.
    name: String,

    // The full path to the module.
    fullPath: String,

    // The module file extension, including the leading period, and lower-cased
    extension: String,

    // The required module's exports
    moduleExports: Object
}
```


## Migration

A new major version of this project is released if breaking changes are introduced. We maintain a [migration guide](docs/migration.md) to help users migrate between these versions.


## Contributing

[The contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2020, Rowan Manning
npm package: @rowanmanning/require-first
Description: Require and return the first available module
Author: Rowan Manning
Latest version: 5.1.0
Deprecated: This library has been deprecated and will no longer receive feature updates or security patches.


# @rowanmanning/require-first

Require and return the first available module.

* [Requirements](#requirements)
* [Usage](#usage)
* [Migration](#migration)
* [Contributing](#contributing)
* [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install with [npm](https://www.npmjs.com/):

```sh
npm install @rowanmanning/require-first
```

Load the library into your code with a `require` call:

```js
const { requireFirst } = require('@rowanmanning/require-first');
```

Require modules by passing in an array of paths. The first one that successfully resolves will be returned.

```js
const thing = requireFirst(['thing1', './thing2', '~/../example/thing3']);
```

By default, an error will be thrown if none of the modules are found. You can change this behaviour to return a default value specified by you:

```js
const thing = requireFirst(['thing1', './thing2', '~/../example/thing3'], {
  example: true
});
```


## Migration

A new major version of this project is released if breaking changes are introduced. We maintain a [migration guide](docs/migration.md) to help users migrate between these versions.


## Contributing

[The contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2019, Rowan Manning
npm package: @rowanmanning/response-redirect-middleware
Description: A small convenience utility to generate Express middleware which redirects a request
Author: Rowan Manning
Latest version: 5.0.0
Deprecated: This library has been deprecated and will no longer receive feature updates or security patches.


# @rowanmanning/response-redirect-middleware

A small convenience utility to generate [Express](https://expressjs.com/) middleware which redirects a request.

```js
app.get('/', redirect('/login'));
```


## Table of Contents

  * [Requirements](#requirements)
  * [Usage](#usage)
  * [Contributing](#contributing)
  * [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install with [npm](https://www.npmjs.com/):

```sh
npm install @rowanmanning/response-redirect-middleware
```

Load the library into your code with a `require` call:

```js
const redirect = require('@rowanmanning/response-redirect-middleware');
```

Use it to generate middleware to redirect a view:

```js
const app = express();

app.get('/', redirect('/login'));
```

The following are equivalent:

```js
app.get('/', redirect('/login'));
app.get('/', (request, response) => response.redirect('/login'));
```

```js
app.get('/posts', redirect(301, '/blog'));
app.get('/posts', (request, response) => response.redirect(301, '/blog'));
```

If you need to pass dynamic information into the redirect, don't use this middleware.


## Contributing

[The contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2020, Rowan Manning
npm package: @rowanmanning/response-render-middleware
Description: A small convenience utility to generate Express middleware which renders a view
Author: Rowan Manning
Latest version: 5.0.0
Deprecated: This library has been deprecated and will no longer receive feature updates or security patches.


# @rowanmanning/response-render-middleware

A small convenience utility to generate [Express](https://expressjs.com/) middleware which renders a view.

```js
app.get('/', render('home'));
```


## Table of Contents

  * [Requirements](#requirements)
  * [Usage](#usage)
  * [Contributing](#contributing)
  * [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 20+


## Usage

Install with [npm](https://www.npmjs.com/):

```sh
npm install @rowanmanning/response-render-middleware
```

Load the library into your code with a `require` call:

```js
const render = require('@rowanmanning/response-render-middleware');
```

Use it to generate middleware to render a view:

```js
const app = express();

app.get('/', render('home'));
```

The following are equivalent:

```js
app.get('/', render('home'));
app.get('/', (request, response) => response.render('home'));
```

```js
app.get('/blog', render('blog', {title: 'My Blog'}));
app.get('/blog', (request, response) => response.render('blog', {title: 'My Blog'}));
```

If you need to pass dynamic information into the view, either don't use this middleware, or make use of `response.locals` in a previous middleware:

```js
function getPostById(request, response, next) {
    response.locals.post = await getPostFromDatabase(request.params.postId);
    next();
}

app.get('/blog/:postId', [
    getPostById,
    render('post')
]);
``` 


## Contributing

[The contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2020, Rowan Manning
npm package: @rowanmanning/sparse-matrix
Description: Represent a matrix with as little stored data as possible
Author: Rowan Manning
Latest version: 1.0.0-beta.5
Deprecated: This module is no longer maintained. If you're interested in taking over maintenance of this repo, please contact the author


# @rowanmanning/sparse-matrix

Represent a matrix with as little stored data as possible.

**:warning: This is pre-release software and also I haven't written docs yet**
npm package: @rowanmanning/validate-project
Description: A tool to validate my coding projects
Author: Rowan Manning
Latest version: 3.1.4


# Validate Project

This is just a tool to validate my coding projects. It forces me to be consistent in the way my repos are organised. It's probably not worth trying to use it.

## Table of Contents

  * [Requirements](#requirements)
  * [Usage](#usage)
  * [Contributing](#contributing)
  * [License](#license)


## Requirements

This library requires the following to run:

  * [Node.js](https://nodejs.org/) 18+


## Usage

Install with [npm](https://www.npmjs.com/):

```sh
npm install -g @rowanmanning/validate-project
```

Alternatively use the `npx` command bundled with npm. The rest of the examples assume you're doing this.

Basics:

```bash
npx @rowanmanning/validate-project
```

Validate a general Git repo:

```bash
npx @rowanmanning/validate-project --type git
```

Validate a general Git repo + Node.js project:

```bash
npx @rowanmanning/validate-project --type git node
```

Validate a general Git repo + Node.js project, and then auto-fix issues:

```bash
npx @rowanmanning/validate-project --type git node --fix
```

### Types

The valid types are:

  - `git`: the basics for a Git-based project
  - `node`: the basics for a Node.js-based project
  - `node-arc-app`: a Node.js Architect-based application
  - `node-express-app`: a Node.js Express-based application
  - `node-library`: a Node.js project published to npm


## Contributing

Genuinely unless you're Rowan Manning, you probably don't need to contribute to this. However if you decide you really need to, then [the contributing guide is available here](docs/contributing.md). All contributors must follow [this library's code of conduct](docs/code_of_conduct.md).


## License

Licensed under the [MIT](LICENSE) license.<br/>
Copyright &copy; 2022, Rowan Manning
npm package: @rowanmanning/webmention-io
Description: A Node.js Webmention.io client
Author: Rowan Manning
Latest version: 1.0.0


# @rowanmanning/webmention-io

A Node.js Webmention.io client.


## Contributing

[The contributing guide is available here](https://github.com/rowanmanning/indieweb-tools/blob/main/docs/contributing.md). All contributors must follow [this library's code of conduct](https://github.com/rowanmanning/indieweb-tools/blob/main/docs/code_of_conduct.md).


## License

Licensed under the [MIT](https://github.com/rowanmanning/indieweb-tools/blob/main/LICENSE) license.<br/>
Copyright &copy; 2022, Rowan Manning