open-index/open-npm huggingface dataset:
npm package: @simmir/koishi-plugin-ouline-subscriber
Description: Outline subscribe plugin to dingtalk
Latest version: 0.0.5

# Koishi Plugin: Outline Subscriber

一个用于连接聊天平台与Outline文档系统的Koishi插件。在群聊中订阅Outline文档变动，当文档发生变化时自动发送通知到群组。支持钉钉、QQ、微信等多种聊天平台。

## 功能特色

- ✅ **实时通知**: 通过Webhook机制实时接收文档变动通知
- ✅ **轮询备选**: 当Webhook不可用时，提供轮询机制作为备选方案
- ✅ **多平台支持**: 支持钉钉、QQ、微信等多种聊天平台
- ✅ **安全验证**: 支持Webhook签名验证，确保数据安全
- ✅ **智能存储**: 自动保存和恢复订阅数据
- ✅ **易用命令**: 简单的命令管理订阅

## 安装

1. 将此插件放入你的Koishi项目的 `external` 目录
2. 无需安装额外依赖（使用Koishi内置HTTP客户端）
3. 在 `koishi.yml` 中启用此插件：

```yaml
plugins:
  group:custom:
    ouline-subscriber:
      outlineApiUrl: https://app.getoutline.com/api
      outlineApiToken: your_outline_api_token
      webhookPath: /webhook/outline
      enablePolling: false
      pollingInterval: 5
```

## 配置说明

### 必需配置

- `outlineApiToken`: Outline API访问令牌
  - 获取方式：在Outline设置中创建API密钥

### 可选配置

- `outlineApiUrl`: Outline API地址 (默认: `https://app.getoutline.com/api`)
- `outlineWebhookSecret`: Webhook签名密钥，用于验证请求安全性
- `webhookPath`: Webhook接收路径 (默认: `/webhook/outline`)
- `enablePolling`: 是否启用轮询模式 (默认: `false`)
- `pollingInterval`: 轮询间隔，单位分钟 (默认: `5`)

## 使用方法

### 1. 在Outline中设置Webhook（推荐）

1. 登录Outline管理界面
2. 进入 **Settings → Webhooks**
3. 添加新的Webhook：
   - **Name**: `钉钉通知`
   - **URL**: `http://your-koishi-server:port/webhook/outline`
   - **Events**: 选择 `documents.publish`, `documents.update`, `documents.delete`
   - **Secret**: 设置签名密钥（可选，但推荐）

### 2. 在聊天群中使用命令

#### 订阅文档
```
outline.subscribe https://your-outline.com/doc/document-id
```

#### 取消订阅
```
outline.unsubscribe https://your-outline.com/doc/document-id
```

#### 查看订阅列表
```
outline.list
```

## 支持的事件类型

- 📝 `documents.publish` - 文档发布
- 📝 `documents.update` - 文档更新
- 🗑️ `documents.delete` - 文档删除

## 故障排除

### Webhook不工作？

1. **检查HTTP插件**: 确保Koishi启用了HTTP插件
2. **检查端口**: 确认Koishi服务器可以从外网访问
3. **检查路径**: 验证Webhook URL路径是否正确
4. **查看日志**: 检查Koishi日志中的错误信息

### 备用方案：启用轮询

如果Webhook无法正常工作，可以启用轮询模式：

```yaml
ouline-subscriber:
  enablePolling: true
  pollingInterval: 5  # 每5分钟检查一次
```

### 权限问题

确保Outline API Token有足够的权限：
- 读取文档信息
- 访问工作区设置

## 开发说明

### 文件结构
```
external/ouline-subscriber/
├── src/
│   └── index.ts          # 主要插件代码
├── data/
│   └── subscriptions.json # 订阅数据存储
├── package.json
└── README.md
```

### 开发模式

1. 克隆项目
2. 安装依赖：`npm install`
3. 启动Koishi开发模式：`npm run dev`

### 贡献

欢迎提交Issue和Pull Request！

## 许可证

MIT License

## 更新日志

### v0.0.1
- 初始版本发布
- 支持基本的文档订阅功能
- 实现Webhook和轮询两种模式
- 添加钉钉命令支持

---

**注意**: 确保你的Koishi实例启用了HTTP插件和相应的聊天平台适配器。
npm package: @simmo/task
Description: JavaScript utility that provides a consistent, clean return from promises. Particularly helpful when using await/async.
Author: Mike Simmonds
Latest version: 0.0.1

# Task

[![Travis][img-travis]][url-travis] [![npm][img-npm]][url-npm] [![downloads][img-downloads]][url-npm] [![License][img-license]][url-license]

[img-travis]: https://img.shields.io/travis/com/simmo/task.svg?style=flat-square
[url-travis]: https://travis-ci.com/simmo/task
[img-npm]: https://img.shields.io/npm/v/@simmo/task.svg?style=flat-square
[url-npm]: https://npmjs.org/package/@simmo/task
[img-license]: https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square
[url-license]: https://github.com/simmo/task/blob/master/LICENSE
[img-downloads]: https://img.shields.io/npm/dm/@simmo/task.svg?style=flat-square

JavaScript utility that provides a consistent, clean return from promises. Particularly helpful when using await/async.

## Install

### NPM

`npm install @simmo/task`

### Yarn

`yarn add @simmo/task`

## Usage

### `task(<Promise>) => { error: <Any>, data: <Any> }`

`task` always returns an object. The object will contain two properties; `error` and `data`.

If the promise is resolved, `error` will be `null` and `data` will contain anything the promise has returned. If the promise is rejected, `error` will return the error provided by the promise and `data` will be `null`.

```javascript
import task from '@simmo/task'

const { error, data } = await task(fetch('/some-api'))

if (error) {
  // Failure
  console.error(error)
} else {
  // Success
  console.log(data)
}
```

## License

MIT © [Mike Simmonds](https://simmo.me)
npm package: @simmo/widower
Description: JavaScript function to remove widows from text.
Author: Mike Simmonds
Latest version: 1.1.2

# Widower

[![npm][image-npm]][url-npm] [![downloads][image-downloads]][url-npm]

Often when working with responsive designs, text will wrap leaving a widowed word on a new line. This JavaScript function replaces the last space with a non breaking space.

## Install

```bash
npm i @simmo/widower
```

## Usage

```ts
import widower from 'widow-killer';

widower('Hello world');
// => Hello\u00A0world
```

MIT © [Mike Simmonds](https://mike.id)

[image-downloads]: https://img.shields.io/npm/dm/@simmo/widower.svg?style=flat-square
[image-npm]: https://img.shields.io/npm/v/@simmo/widower.svg?style=flat-square
[url-npm]: https://npmjs.org/package/@simmo/widower
npm package: @simnode/clock
Description: Deterministic virtual clock for Node.js. Replaces `Date`, `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, and `performance.now()` with manually-controllable fakes.
Latest version: 0.1.1-alpha.1
Deprecated: DEPRECATED: This package has been renamed. See @crashlab/* and crashlab on npm.

# @simnode/clock

Deterministic virtual clock for Node.js. Replaces `Date`, `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, and `performance.now()` with manually-controllable fakes.

## Usage

```ts
import { VirtualClock, install } from '@simnode/clock';

// Standalone (no global patching)
const clock = new VirtualClock(0);
const order: number[] = [];
clock.setTimeout(() => order.push(1), 100);
clock.setTimeout(() => order.push(2), 200);
clock.advance(200);
// order = [1, 2]

// With global patching
const { clock: c, uninstall } = install(0);
console.log(Date.now()); // 0
c.advance(5000);
console.log(Date.now()); // 5000
uninstall();
```

## Key Features

- **Min-heap timer queue** — O(log n) insertion and removal
- **Deterministic ordering** — same-time timers fire in FIFO order
- **Cascading timers** — timers that schedule sub-timers within the same `advance()` window are picked up and executed in order
- **`freeze()` / `unfreeze()`** — pause time progression
- **`pending()`** — inspect all scheduled timers
npm package: @simnode/core
Description: Simulation harness for SimNode. Orchestrates all modules: virtual clock, seeded PRNG, scheduler, HTTP/TCP interceptors, virtual filesystem, and fault injector. Provides `Simulation` class with `scenario()`, `run({ seeds })`, and `replay({ seed, scenario }
Latest version: 0.1.1-alpha.1
Deprecated: DEPRECATED: This package has been renamed. See @crashlab/* and crashlab on npm.

# @simnode/core

Simulation harness for SimNode. Orchestrates all modules: virtual clock, seeded PRNG, scheduler, HTTP/TCP interceptors, virtual filesystem, and fault injector. Provides `Simulation` class with `scenario()`, `run({ seeds })`, and `replay({ seed, scenario })`. Includes `simnode` CLI with `run` and `replay` commands.
npm package: @simnode/filesystem
Description: In-memory virtual filesystem for SimNode. Patches `fs.readFileSync`, `writeFileSync`, `existsSync`, `mkdirSync`, `readdirSync`, `unlinkSync`, and `statSync`. Supports error injection (ENOSPC, EIO) with optional after-N-writes thresholds.
Latest version: 0.1.1-alpha.1
Deprecated: DEPRECATED: This package has been renamed. See @crashlab/* and crashlab on npm.

# @simnode/filesystem

In-memory virtual filesystem for SimNode. Patches `fs.readFileSync`, `writeFileSync`, `existsSync`, `mkdirSync`, `readdirSync`, `unlinkSync`, and `statSync`. Supports error injection (ENOSPC, EIO) with optional after-N-writes thresholds.
npm package: @simnode/http-proxy
Description: Lightweight HTTP interceptor for deterministic simulation testing. Patches `http.request`/`https.request`, records calls, serves static mocks, and integrates with `@simnode/clock` for virtual latency.
Latest version: 0.1.1-alpha.1
Deprecated: DEPRECATED: This package has been renamed. See @crashlab/* and crashlab on npm.

# @simnode/http-proxy

Lightweight HTTP interceptor for deterministic simulation testing. Patches `http.request`/`https.request`, records calls, serves static mocks, and integrates with `@simnode/clock` for virtual latency.

## Usage

```ts
import { HttpInterceptor } from '@simnode/http-proxy';
import { VirtualClock } from '@simnode/clock';
import * as http from 'node:http';

const clock = new VirtualClock(0);
const interceptor = new HttpInterceptor({ clock });

interceptor.mock('http://api.stripe.com/v1/charges', {
  status: 200,
  body: { id: 'ch_123', status: 'succeeded' },
  latency: 80,
});

interceptor.install();

// Make request — response is delayed by 80 virtual ms
const req = http.request('http://api.stripe.com/v1/charges', (res) => {
  console.log(res.statusCode); // 200
});
req.end();

clock.advance(80); // fires the response synchronously

// Query recorded calls
interceptor.calls('GET', 'http://api.stripe.com');

interceptor.uninstall();
```

## Features

- **Static & dynamic mocks** — respond with fixed data or a handler function
- **Call recording** — inspect all intercepted requests
- **Failure injection** — handler-level error throwing
- **Virtual latency** — integrates with any `IClock` implementation (duck-typed, no hard dependency)
npm package: @simnode/mongo
Description: High-fidelity MongoDB proxy for deterministic simulation testing.
Latest version: 0.1.1-alpha.1
Deprecated: DEPRECATED: This package has been renamed. See @crashlab/* and crashlab on npm.

# @simnode/mongo

High-fidelity MongoDB proxy for deterministic simulation testing. 

Instead of a partial JS-only mock, this package uses a **TCP Proxy model** to route traffic from your application to a real MongoDB binary (`mongodb-memory-server`). This ensures 100% protocol fidelity — including complex aggregation pipelines, transactions, and change streams — while still allowing SimNode to inject deterministic virtual latency.

## Features

- **100% Fidelity:** Since it proxies to a real `mongod` process, every MongoDB feature works exactly as it does in production.
- **Per-Seed Isolation:** Each simulation seed automatically uses a unique database name (`sim_db_<seed>`) which is dropped after the run.
- **Virtual Latency:** Integrated with `@simnode/tcp` and `@simnode/clock` to hold response bytes until the virtual clock advances.
- **Assertion API:** Direct access to the database via `env.mongo.find()` for easy test assertions without needing a separate driver setup in your scenario.

## Installation

```sh
npm install --save-dev @simnode/mongo
```

Note: This package is included by default in the main `simnode` package.

## Usage (Internal SimNode API)

In a SimNode scenario, `@simnode/mongo` is available on the `env` object:

```javascript
export default async function scenario(env) {
  // 1. The environment automatically rewrites MONGODB_URI to point to the proxy
  const client = await MongoClient.connect(process.env.MONGODB_URI);
  const db = client.db();

  // 2. Perform operations (these will be intercepted and proxied)
  await db.collection('users').insertOne({ name: 'Alice' });

  // 3. Advance virtual time (the proxy holds the response until this happens)
  await env.clock.advance(50);

  // 4. Use the assertion API to verify state directly
  const users = await env.mongo.find('users', { name: 'Alice' });
  if (users.length !== 1) throw new Error('User not found');
}
```

## How it Works

1. **Shared Server:** The `Simulation` runner starts one `MongoMemoryServer` process for the entire test run.
2. **TCP Interception:** When your app connects to `localhost:27017`, `@simnode/tcp` intercepts the connection.
3. **Message Framing:** `MongoMock` reassembles raw TCP chunks into valid MongoDB wire-protocol frames (based on the 4-byte length prefix).
4. **Latency Injection:** Complete response frames from the real `mongod` are held by the `Scheduler` and only released to your app when the virtual clock reaches the scheduled time.
5. **Auto-Cleanup:** The `mongo.drop()` method is called after every seed to ensure the shared process stays clean for the next run.

## License

MIT
npm package: @simnode/pg-mock
Description: PostgreSQL wire protocol v3 mock for SimNode. Supports startup handshake (no SSL), simple query protocol, RowDescription/DataRow/CommandComplete, BEGIN/COMMIT/ROLLBACK, and basic SQL patterns (SELECT/INSERT/UPDATE/DELETE with WHERE). Throws `SimNodeUnsupp
Latest version: 0.1.1-alpha.1
Deprecated: DEPRECATED: This package has been renamed. See @crashlab/* and crashlab on npm.

# @simnode/pg-mock

PostgreSQL wire protocol v3 mock for SimNode. Supports startup handshake (no SSL), simple query protocol, RowDescription/DataRow/CommandComplete, BEGIN/COMMIT/ROLLBACK, and basic SQL patterns (SELECT/INSERT/UPDATE/DELETE with WHERE). Throws `SimNodeUnsupportedPGFeature` for unsupported features. Plugs into `@simnode/tcp` as a handler.
npm package: @simnode/random
Description: Deterministic seeded PRNG for Node.js, backed by the Mulberry32 algorithm.
Latest version: 0.1.1-alpha.1
Deprecated: DEPRECATED: This package has been renamed. See @crashlab/* and crashlab on npm.

# @simnode/random

Deterministic seeded PRNG for Node.js, backed by the Mulberry32 algorithm.

## Usage

```ts
import { mulberry32, SeededRandom, patchMathRandom } from '@simnode/random';

// Low-level
const rng = mulberry32(42);
rng(); // always the same first value for seed 42

// Class API
const sr = new SeededRandom(42);
sr.next();              // [0, 1)
sr.intBetween(1, 6);    // dice roll
sr.pick(['a', 'b']);    // random element
sr.shuffle([1, 2, 3]);  // Fisher-Yates

// Scoped Math.random patching
const values = patchMathRandom(42, () => {
  return [Math.random(), Math.random(), Math.random()];
});
// Same seed → same values every time
```
npm package: @simnode/redis-mock
Description: Redis RESP protocol mock for SimNode. Supports 16 commands: GET, SET, DEL, EXPIRE, TTL, INCR, DECR, LPUSH, RPUSH, LPOP, RPOP, HSET, HGET, SMEMBERS, SADD, ZADD, ZRANGE. TTL integrates with virtual clock. Throws `SimNodeUnsupportedRedisCommand` for unsuppor
Latest version: 0.1.1-alpha.1
Deprecated: DEPRECATED: This package has been renamed. See @crashlab/* and crashlab on npm.

# @simnode/redis-mock

Redis RESP protocol mock for SimNode. Supports 16 commands: GET, SET, DEL, EXPIRE, TTL, INCR, DECR, LPUSH, RPUSH, LPOP, RPOP, HSET, HGET, SMEMBERS, SADD, ZADD, ZRANGE. TTL integrates with virtual clock. Throws `SimNodeUnsupportedRedisCommand` for unsupported commands.
npm package: @simnode/scheduler
Description: Cooperative deterministic scheduler for mock I/O boundaries. Holds enqueued completions until their virtual time arrives, then releases them in a PRNG-shuffled order — making all macro-level race conditions fully reproducible with the same seed. Does **no
Latest version: 0.1.1-alpha.1
Deprecated: DEPRECATED: This package has been renamed. See @crashlab/* and crashlab on npm.

# @simnode/scheduler

Cooperative deterministic scheduler for mock I/O boundaries. Holds enqueued completions until their virtual time arrives, then releases them in a PRNG-shuffled order — making all macro-level race conditions fully reproducible with the same seed. Does **not** intercept V8 microtasks or Promise internals.

## Usage

```ts
import { Scheduler } from '@simnode/scheduler';

const sched = new Scheduler({ prngSeed: 42 });

// Mock I/O layer enqueues completions:
sched.enqueueCompletion({ id: 'db-read-1', when: 80, run: () => resolveQuery1() });
sched.enqueueCompletion({ id: 'db-read-2', when: 80, run: () => resolveQuery2() });

// When the virtual clock advances to t=80:
await sched.runTick(80);
// Both completions run in deterministic PRNG-shuffled order.
```

## Clock integration

```ts
import { VirtualClock } from '@simnode/clock';

const clock = new VirtualClock(0);
const sched = new Scheduler({ clock, prngSeed: 42 });
// Contract: when clock.advance() reaches time t, call await sched.runTick(t).
```
npm package: @simnode/tcp
Description: TCP interception layer for SimNode. Patches `net.createConnection`, `net.connect`, and `net.Socket.prototype.connect` to route all outbound TCP connections through registered mock handlers. No real network I/O ever occurs.
Latest version: 0.1.1-alpha.1
Deprecated: DEPRECATED: This package has been renamed. See @crashlab/* and crashlab on npm.

# @simnode/tcp

TCP interception layer for SimNode. Patches `net.createConnection`, `net.connect`, and `net.Socket.prototype.connect` to route all outbound TCP connections through registered mock handlers. No real network I/O ever occurs.

## Usage

```ts
import { TcpInterceptor } from '@simnode/tcp';
import { VirtualClock } from '@simnode/clock';
import { Scheduler } from '@simnode/scheduler';

const clock = new VirtualClock(0);
const scheduler = new Scheduler({ prngSeed: 42 });
const tcp = new TcpInterceptor({ clock, scheduler });

// Register mock — accepts "host:port" or URL strings
tcp.mock('postgres://localhost:5432', {
  handler: (data, ctx) => {
    // data: raw bytes from client
    // return Buffer or Buffer[] as response
    return Buffer.from('response-bytes');
  },
  latency: 80, // virtual ms
});

tcp.install();

// All net.createConnection(5432, 'localhost') calls now
// go through the mock handler. Responses are delivered
// via the scheduler for deterministic ordering.

tcp.uninstall();
```

## Safety

Unmocked connections throw `SimNodeUnmockedTCPConnectionError` — preventing any real network access during simulation.