open-index/open-npm huggingface dataset:
npm package: @nodesandbox/async-storage
Description: A TypeScript service for managing asynchronous storage using AsyncLocalStorage.
Author: ATARMLA Abdou-Raouf
Latest version: 0.2.1

# @nodesandbox/async-storage

A TypeScript service for managing asynchronous storage using `AsyncLocalStorage`.

## Installation

You can install the package via npm:

```bash
npm install @nodesandbox/async-storage
```

## Usage

Here is an example of how to use the `AsyncStorageService`:

```typescript
import { AsyncStorageService } from '@nodesandbox/async-storage';

const storage = AsyncStorageService.getInstance();

storage.run(() => {
  storage.set('key', 'value');
  console.log(storage.get('key')); // Output: value
});
```

## API

### `AsyncStorageService`

- **`getInstance(): AsyncStorageService`**: Returns the singleton instance of `AsyncStorageService`.

- **`set(key: string, value: any): void`**: Sets a value in the asynchronous storage.

- **`get(key: string): any`**: Retrieves a value from the asynchronous storage.

- **`run(callback: () => void, initialValue?: Map<string, any>): void`**: Runs a callback function with a new storage context.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.
npm package: @nodesandbox/logger
Description: A singleton logging utility for Node.js applications using Winston.
Author: ATARMLA Abdou-Raouf
Latest version: 0.1.2

# @nodesandbox/logger

`@nodesandbox/logger` is a singleton logging utility for Node.js applications built using the `winston` library. It provides structured logging formats, supports multiple transports, and offers a simple API for logging messages at different levels.

## Features

- **Singleton Pattern**: Ensures only one instance of the logger is created.
- **Custom Log Format**: Combines timestamps, error stack traces, and other relevant information into structured logs.
- **Multiple Transports**: Logs to both the console and files (error logs and combined logs).
- **Exception Handling**: Automatically logs uncaught exceptions to a separate file.
- **File Logging**: Supports writing specific log messages to individual files.

## Installation

You can install `@nodesandbox/logger` via npm:

```bash
npm install @nodesandbox/logger
```

## Usage

```typescript
import { LoggerService } from '@nodesandbox/logger';

const logger = LoggerService.getInstance();

// Logging at different levels
logger.info('Application has started');
logger.warn('This is a warning message');
logger.error('An error occurred', new Error('Sample error'));

// Logging to a specific file
logger.file('custom-log', 'This is a log message for a custom log file');
```

## Configuration

### Log Levels

You can use the following log levels:
- `info`: General information messages
- `warn`: Warning messages
- `error`: Error messages with optional stack trace

### File Structure

By default, logs are saved in the `logs` directory:
- `logs/error.log`: Contains error messages
- `logs/combined.log`: Contains all messages
- `logs/exceptions.log`: Contains uncaught exceptions
- `logs/browser`: Contains custom logs

## License

This project is licensed under the [MIT License](LICENSE).
npm package: @nodesandbox/response-kit
Description: A collection of TypeScript response and error handlers for Node.js (express) applications.
Author: ATARMLA Abdou-Raouf
Latest version: 0.2.0

# @nodesandbox/response-kit

`@nodesandbox/response-kit` is a collection of TypeScript-based handlers for building robust APIs using Express.js. This package is designed to simplify error handling and response formatting in your Node.js applications.

## Features

- **TypeScript Support:** Built with TypeScript for type safety and improved development experience.
- **Express.js Integration:** Seamlessly integrates with Express.js to manage API responses and errors.
- **Modular Structure:** Organized handlers for different types of responses and errors.

## Installation

You can install the package via npm:

```bash
npm install @nodesandbox/response-kit
```

### Peer Dependency

Please note that this package requires `express` to function properly. You need to install `express` in your project as well:

```bash
npm install express @types/express
```

## Usage

Here's a quick example of how to use the response and error handlers in your Express application:

```typescript
import express from 'express';
import { GlobalErrorHandler, NotFoundHandler } from '@nodesandbox/response-kit';

const app = express();

// Your routes go here

// Use the global error handler
app.use(GlobalErrorHandler);

// Use the not found handler
app.use(NotFoundHandler);

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`Server is running on http://localhost:${PORT}`);
});
```

## Scripts

- `npm run build`: Compiles TypeScript files to JavaScript.
- `npm test`: Run tests (currently not specified).

## Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
npm package: @nodesecure/cache
Description: NodeSecure cache module
Author: GENTILHOMME Thomas
Latest version: 1.0.0

# `cache`

[![version](https://img.shields.io/github/package-json/v/NodeSecure/Cli?filename=workspaces%2Fcache%2Fpackage.json&style=for-the-badge)](https://www.npmjs.com/package/@nodesecure/cache)
[![OpenSSF
Scorecard](https://api.securityscorecards.dev/projects/github.com/NodeSecure/cli/badge?style=for-the-badge)](https://api.securityscorecards.dev/projects/github.com/NodeSecure/cli)
[![mit](https://img.shields.io/github/license/NodeSecure/Cli?style=for-the-badge)](https://github.com/NodeSecure/cli/blob/master/LICENSE)
![size](https://img.shields.io/github/languages/code-size/NodeSecure/cache?style=for-the-badge)
[![build](https://img.shields.io/github/actions/workflow/status/NodeSecure/cli/cache.yml?style=for-the-badge)](https://github.com/NodeSecure/cli/actions?query=workflow%3A%cache+CI%22)

Caching layer for NodeSecure CLI and server, handling configuration, analysis payloads, and cache state management.

## Requirements

- [Node.js](https://nodejs.org/en/) v24 or higher

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/cache
# or
$ yarn add @nodesecure/cache
```

## Features

- Stores and retrieves configuration and analysis payloads.
- Manages a Most Recently Used (MRU) and Least Recently Used (LRU) list for payloads.
- Supports cache initialization, reset, and removal of old payloads.
- Handles payloads for multiple packages, including local and remote analysis results.

## Usage example

```js
import { AppCache } from "@nodesecure/cache";

const cache = new AppCache();

await cache.initPayloadsList();
await cache.setRootPayload(payload);
```

## API

- [AppCache](./docs/AppCache.md)
- [FilePersistanceProvider](./docs/FilePersistanceProvider.md)
npm package: @nodesecure/contact
Description: Utilities to extract/fetch data on NPM contacts (author, maintainers ..)
Author: GENTILHOMME Thomas
Latest version: 3.1.0

<p align="center"><h1 align="center">
  @nodesecure/contact
</h1>

<p align="center">
  Utilities to extract/fetch data on NPM contacts (author, maintainers etc..)
</p>

## Requirements
- [Node.js](https://nodejs.org/en/) v24 or higher

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/contact
# or
$ yarn add @nodesecure/contact
```

## Usage example

Here is an example of usage from the Scanner. In this case, we are using **dependenciesMap**, which is a `Record<string, Dependency>`. However, you can build your own record of `ContactExtractorPackageMetadata`.

```ts
import {
  ContactExtractor,
  type ContactExtractorPackageMetadata
} from "@nodesecure/contact";

const dependencies: Record<string, ContactExtractorPackageMetadata> = Object.create(null);
for (const [packageName, dependency] of dependenciesMap) {
  const { author, maintainers } = dependency.metadata;

  dependencies[packageName] = {
    maintainers,
    ...( author === null ? {} : { author } )
  }
}

const extractor = new ContactExtractor({
  highlight: [
    {
      name: "Sindre Sorhus"
    }
  ]
});
const { illuminated, expired } = extractor.fromDependencies(
  dependencies
);
console.log({ illuminated, expired });
```

## API

- [NsResolver](./docs/NsResolver.md)

Contact is defined by the following TypeScript interface:
```ts
interface Contact {
  email?: string;
  url?: string;
  name: string;
}
```

### ContactExtractor

The constructor take a list of contacts you want to find/extract.

```ts
interface ContactExtractorOptions {
  highlight: EnforcedContact[];
}

type EnforcedContact = RequireAtLeastOne<
  Contact,
  "name" | "email"
>;
```

> [!TIP]
> This package authorizes literal RegExp in the name property of `highlight` contacts

The methods **fromDependencies and fromManifest** will return an Array of IlluminatedContact objects if any are found in the provided dependencies and the list of expired email domains.

```ts
interface ContactExtractorFromDependenciesResult {
  illuminated: IlluminatedContact[];
  /**
   * List of email domains that are expired
   */
  expired: string[];
}

type IlluminatedContact = Contact & {
  dependencies: string[];
}
```

### compareContact(contactA: Partial< Contact >, contactB: Partial< Contact >, options?: CompareOptions): boolean

Compare two contacts and return `true` if they are the same person

```ts
import {
  compareContact
} from "@nodesecure/contact";
import assert from "node:assert";

assert.ok(
  compareContact(
    { name: "john doe" },
    { name: "John  Doe" }
  )
);
```

Each string is trimmed, converted to lowercase, and any multiple spaces are reduced to a single space.

#### Options

```ts
interface CompareOptions {
  /**
   * @default true
   */
  compareName?: boolean;
}
```

## License
MIT
npm package: @nodesecure/dependa
Description: Identify and categorize Node.js dependencies (builtins, third parties..)
Author: GENTILHOMME Thomas
Latest version: 1.0.0
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# Dependa
Identify and categorize Node.js dependencies (builtins, alias, third parties..). The module and the code has been inspired by [builtins](https://github.com/juliangruber/builtins) and [builtin-modules](https://github.com/sindresorhus/builtin-modules).

## Features
- Several ways to use the API (**get** and **is**) to allow any kind of custom code.
- First class support of Node.js protocol `node:`.
- Wider API not limited or restricted to Node.js core modules.

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/dependa
# or
$ yarn add @nodesecure/dependa
```

## Usage example

```js
import * as dependa from "@nodesecure/dependa";

console.log(dependa.is.builtins("node:fs/promises"));
console.log(dependa.is.builtins("stream"));

const builtins = dependa.get.builtins();
console.log(builtins);
```

## API

### is.builtins(moduleName: string): boolean
Return true if the given moduleName is a Node.js core dependency.

### is.subpath(moduleName: string): boolean
Return true if the given moduleName is a Subpath import (starting with `#`).

### is.filesystem(moduleName: string): boolean
Return true if the given moduleName is a filesystem dependency (starting with `/`, `./` or `../`).

### is.thirdparty(moduleName: string): boolean
Return true if the given moduleName is a third-party dependency (which mean the module is not a subpath, builtins or filesystem).

### get.builtins(options): Set< string >
Return an ES6 Set of all Node.js builtins (core dependency).

### get.kind(moduleName: string): "subpath" | "filesystem" | "builtins" | "thirdparty"
Return the kind of the given module name.

## Contributors ✨

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
  <tr>
    <td align="center"><a href="https://www.linkedin.com/in/thomas-gentilhomme/"><img src="https://avatars.githubusercontent.com/u/4438263?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gentilhomme</b></sub></a><br /><a href="https://github.com/NodeSecure/dependa/commits?author=fraxken" title="Code">💻</a></td>
  </tr>
</table>

<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

## License
MIT
npm package: @nodesecure/domain-check
Description: NodeSecure (npm) domain-check analysis package
Latest version: 1.0.1
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# NodeSecure domain-check
![version](https://img.shields.io/badge/dynamic/json.svg?url=https://raw.githubusercontent.com/NodeSecure/domain-check/main/package.json&query=$.version&label=Version)
[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/NodeSecure/domain-check/commit-activity)
[![mit](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](https://github.com/NodeSecure/domain-check/blob/main/LICENSE)
![build](https://img.shields.io/github/actions/workflow/status/NodeSecure/domain-check/main.yml)

NodeSecure (npm) domain-check analysis package

## Requirements
- [Node.js](https://nodejs.org/en/) v16 or higher

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/domain-check
# or
$ yarn add @nodesecure/domain-check
```

## Usage example

```js
import { whois, resolveMxRecords } from '@nodesecure/domain-check';

const myDomain = 'google.com';

const domainExpirationDate = await whois(myDomain);
const mxRecords = await resolveMxRecords(myDomain);
```

## Contributors ✨

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
  <tr>
    <td align="center"><a href="https://github.com/Kawacrepe"><img src="https://avatars.githubusercontent.com/u/40260517?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vincent Dhennin</b></sub></a><br /><a href="https://github.com/NodeSecure/domain-check/commits?author=Kawacrepe" title="Code">💻</a> <a href="https://github.com/NodeSecure/domain-check/pulls?q=is%3Apr+reviewed-by%3AKawacrepe" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/NodeSecure/domain-check/commits?author=Kawacrepe" title="Documentation">📖</a> <a href="https://github.com/NodeSecure/domain-check/issues?q=author%3AKawacrepe" title="Bug reports">🐛</a></td>
    <td align="center"><a href="https://www.linkedin.com/in/thomas-gentilhomme/"><img src="https://avatars.githubusercontent.com/u/4438263?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gentilhomme</b></sub></a><br /><a href="https://github.com/NodeSecure/domain-check/commits?author=fraxken" title="Code">💻</a></td>
  </tr>
</table>

<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->
npm package: @nodesecure/github
Description: Download repository from github
Author: GENTILHOMME Thomas
Latest version: 2.1.0

<p align="center"><h1 align="center">
  @nodesecure/github
</h1>

<p align="center">
  Download and (optionaly) extract GitHub repository archive.
</p>

## Requirements

- [Node.js](https://nodejs.org/en/) v20 or higher

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/github
# or
$ yarn add @nodesecure/github
```

## Usage example

```js
import * as github from "@nodesecure/github";

const utils = await github.download("NodeSecure.utils");
console.log(utils.location);

const scanner = await github.downloadAndExtract("NodeSecure.scanner");
console.log(scanner.location);
```

## API

Both `download` and `downloadAndExtract` functions use the same set of options.

```ts
interface DownloadOptions {
  /**
   * The destination (location) to extract the tar.gz
   *
   * @default process.cwd()
   */
  dest?: string;
  /**
   * The default github branch name (master, main ...)
   *
   * @default main
   */
  branch?: string;
  /**
   * Authentication token for private repositories
   *
   * @default process.env.GITHUB_TOKEN
   */
  token?: string;
}
```

### download(repository: string, options?: DownloadOptions): Promise< DownloadResult >
Download the tar.gz archive of the GIT repository.

```ts
interface DownloadResult {
  /** Archive or repository location on disk */
  location: string;
  /** Github repository name */
  repository: string;
  /** Github organization name */
  organization: string;
    /** Github branch name */
  branch: string;
}
```

### downloadAndExtract(repository: string, options?: DownloadExtractOptions): Promise< DownloadResult >
Use download but extract the tar.gz archive.

```ts
interface DownloadExtractOptions extends DownloadOptions {
  /**
   * Remove the tar.gz archive after a succesfull extraction
   *
   * @default true
   */
  removeArchive?: boolean;
}
```

## License

MIT
npm package: @nodesecure/gitlab
Description: Download and extract gitlab repository
Author: GENTILHOMME Thomas
Latest version: 2.1.0

<p align="center"><h1 align="center">
  @nodesecure/gitlab
</h1>

<p align="center">
  Download and (optionaly) extract GitLab repository archive.
</p>

## Requirements

- [Node.js](https://nodejs.org/en/) v20 or higher

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/gitlab
# or
$ yarn add @nodesecure/gitlab
```

## Usage example

```js
import * as gitlab from "@nodesecure/gitlab";

// Note: repository can be either namespace path or repository ID
const result = await gitlab.download(
  "NodeSecure.utils"
);
console.log(result);
```

## API

Both `download` and `downloadAndExtract` functions use the same set of options.

```ts
interface DownloadOptions {
  /**
   * The destination (location) to extract the tar.gz
   *
   * @default process.cwd()
   */
  dest?: string;
  /**
   * The default gitlab branch name (master, main ...).
   * By default it fetch the "default" gitlab branch.
   *
   * @default null
   */
  branch?: string | null;
  /**
   * Authentication token for private repositories
   *
   * @default process.env.GITLAB_TOKEN
   */
  token?: string;
  /**
   * @default https://gitlab.com/api/v4/projects/
   */
  gitlab?: string;
}
```

### download(repository: string, options?: DownloadOptions): Promise< DownloadResult >
Download the tar.gz archive of the GIT repository.

```ts
interface DownloadResult {
  /** Archive or repository location on disk */
  location: string;
  /** Gitlab repository name */
  repository: string;
  /** Gitlab organization name */
  organization: string;
  /** Gitlab branch name */
  branch: string;
}
```

### downloadAndExtract(repository: string, options?: DownloadExtractOptions): Promise< DownloadResult >
Use download but extract the tar.gz archive.

```ts
interface DownloadExtractOptions extends DownloadOptions {
  /**
   * Remove the tar.gz archive after a succesfull extraction
   *
   * @default true
   */
  removeArchive?: boolean;
}
```

## License

MIT
npm package: @nodesecure/i18n
Description: NodeSecure Internationalization
Author: GENTILHOMME Thomas
Latest version: 4.1.0

<p align="center">
  <img src="https://user-images.githubusercontent.com/4438263/226019205-7d86a8d5-345f-416f-bc8d-c4aef6f12868.jpg" alt="@nodesecure/i18n">
</p>

<p align="center">
  Internationalization (**i18n**) utilities for NodeSecure tools like [CLI](https://github.com/NodeSecure/cli). 
</p>

## Requirements
- [Node.js](https://nodejs.org/en/) v24 or higher

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/i18n
# or
$ yarn add @nodesecure/i18n
```

## Usage example

```js
import * as i18n from "@nodesecure/i18n";

await i18n.setLocalLang("french");

console.log(i18n.getToken("depWalker.dep_tree"));

// Using parameters
console.log(i18n.getToken("depWalker.success_tarball", "14", "15ms"));
```

You can consult the real use case of the API in the following codes: [here](https://github.com/NodeSecure/cli/blob/master/src/commands/lang.js) and [here](https://github.com/NodeSecure/cli/blob/master/src/commands/vulnerability.js).

## Supported languages

- french
- english

> [!NOTE]
> Feel free to open a PR to push a new language

## API

See TypeScript definition file.

```ts
type languages = "french" | "english";

interface SetLocalLangOptions {
  /** If true, calls getLocalLang() after setting and returns the language. */
  force?: boolean;
}

export function getLocalLang(): Promise<languages>;
export function setLocalLang(newLanguage: languages, options?: SetLocalLangOptions): Promise<languages | void>;
export function getToken(token: string, ...parameters): Promise<string>;
export function getTokenSync(token: string, ...parameters): string;
export function getLanguages(): Promise<languages[]>;
export function taggedString(str: string, ...keys: any[]): (...keys: any[]) => string;
export function extend(language: string, tokens: Record<string, any>): void;
export function extendFromSystemPath(path: string): Promise<void>;
```

### Using the `force` option

Instead of calling `setLocalLang` and `getLocalLang` separately:

```js
await i18n.setLocalLang("french");
await i18n.getLocalLang();
```

You can use the `force` option to do it in one call:

```js
await i18n.setLocalLang("french", { force: true });
```

> [!NOTE]
> Local lang must be updated otherwise `getTokenSync()` will throws. Make sure to use `await i18n.getLocalLang()` or `await i18n.setLocalLang(lang, { force: true })` before any synchronous usage.

## Generate documentation

You can generate a static webpage by using the `build:documentation` npm script:

```bash
$ npm run build:documentation
```

## Contributing
Feel free to add a new language. You need to take inspiration from the two supported languages and replicate the same keys.

Then export it in the `index.js` file (example if we want to add a chinese translation).

```js
export * as chinese  from "./chinese.js";
```
## License
MIT
npm package: @nodesecure/js-x-ray-ai
Description: <p align="center">   <h1 align="center">     @nodesecure/js-x-ray-ai   </h1> </p>
Author: GOMBAULD Clément
Latest version: 1.0.5

<p align="center">
  <h1 align="center">
    @nodesecure/js-x-ray-ai
  </h1>
</p>

<p align="center">
  JavaScript AST analysis powered by AI
</p>

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/js-x-ray-ai
# or
$ yarn add @nodesecure/js-x-ray-ai
```

## Usage example

```javascript
import { AiAstAnalyser } from "@nodesecure/js-x-ray-ai";

async function main() {
  const analyzer = new AiAstAnalyser({
    provider: "openai",
    apiKey: process.env.API_KEY
  });

  const code = `
  const http = require("http");
  http.get("http://example.com");
  `;

  const { llm, jsXRay } = await analyzer.analyze(code, "gpt-5");

  console.log(llm);
  console.log(jsXRay);
}
main().catch(console.error);
```

## API

```ts
export type Indicator = {
  id: string;
  type: string;
  description: string;
  evidence: string;
  severity: "Critical" | "High" | "Medium" | "Low";
};

export type LlmReport = {
  tldr: string;
  behavior: string;
  indicators: Indicator[];
  impact: string;
  remediation: string;
  remediationSummary: string;
  confidence: "High" | "Medium" | "Low";
  confidenceReason: string;
  metadata: {
    linesReferenced: string;
    redactedSecrets: {
      label: string;
      hash: string;
    };
  };
};

export type Analyses = {
  llm: LlmReport;
  jsXRay: Report; // from @nodesecure/js-x-ray
};

export type AiAstAnalyzerOptions = {
  model: string;
  runtimeOptions?: RuntimeOptions; // from @nodesecure/js-x-ray
};

export type LlmOptions = {
  provider: "google" | "openai";
  apiKey: string;
};

export class AiAstAnalyser {
  constructor(
    llmOptions: LlmOptions,
    astAnalyzerOptions?: AiAstAnalyzerOptions
  );
  analyze(
    code: string,
    model: string,
    options?: RuntimeOptions // from @nodesecure/js-x-ray
  ): Promise<Analyses>;
}
```

## License

MIT
npm package: @nodesecure/opencode-nodesecure
Description: A plugin for OpenCode that leverage NodeSecure packages.
Author: GOMBAULD Clément
Latest version: 1.0.0

<p align="center"><h1 align="center">
  @nodesecure/opencode-nodesecure
</h1>

<p align="center">
Opencode Nodesecure
</p>


## Getting Started

This package is available in the Node Package Repository.

Add the plugin to your [OpenCode config](https://opencode.ai/docs/config/):

```json
{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["opencode-nodesecure"]
}
```

That's it. OpenCode will automatically install the plugin on next run.

## Updating

> [!WARNING]
> OpenCode does NOT auto-update plugins.

To get the latest version, clear the cached plugin and let OpenCode reinstall it:

```bash
rm -rf ~/.cache/opencode/node_modules/opencode-nodesecure
opencode
```

## Tools Provided

| Tool        | Description                                                                 |
| ----------- | --------------------------------------------------------------------------- |
| `cwd_scanner` | Perform a security scan on the current working directory |
| `remote_packages_scanner` | Perform a security scan on the given npm packages.         |

## Usage

Use natural language (e.g. i want to make a security scan on the current working directory, i want to perform a security scan on this dependency: react@19.0.0).
npm package: @nodesecure/sec-literal
Description: Package created to analyze JavaScript literals
Author: GENTILHOMME Thomas
Latest version: 1.4.0

<p align="center">
  <h1 align="center">
    @nodesecure/sec-literal
  </h1>
</p>

<p align="center">
  This package is a security utilities library created to analyze <a href="https://github.com/estree/estree/blob/master/es5.md#literal">ESTree Literal</a> and JavaScript string primitive.
</p>

## Features

- Detect Hexadecimal, Base64, Hexa and Unicode sequences.
- Detect patterns (prefix, suffix) on groups of identifiers.
- Detect suspicious string and return advanced metrics on it (char diversity etc).

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/sec-literal
# or
$ yarn add @nodesecure/sec-literal
```

## API

## Hex

### isHex(anyValue): boolean
Detect if the given string is an Hexadecimal value

### isSafe(anyValue): boolean
Detect if the given string is a safe Hexadecimal value. The goal of this method is to eliminate false-positive.

```js
Hex.isSafe("1234"); // true
Hex.isSafe("abcdef"); // true
```

## Literal

### isLiteral(anyValue): boolean
### toValue(anyValue): string
### toRaw(anyValue): string
### defaultAnalysis(literalValue)

## Utils

### isSvg(strValue): boolean

### isSvgPath(strValue): boolean
Detect if a given string is a svg path or not.

### stringCharDiversity(str): number
Get the number of unique chars in a given string

### stringSuspicionScore(str): number
Analyze a given string an give it a suspicion score (higher than 1 or 2 mean that the string is highly suspect).

## Patterns

### commonStringPrefix(leftStr, rightStr): string | null
### commonStringSuffix(leftStr, rightStr): string | null
### commonHexadecimalPrefix(identifiersArray: string[])

## License
MIT
npm package: @nodesecure/tarball
Description: NodeSecure tarball scanner
Author: GENTILHOMME Thomas
Latest version: 4.1.0

<p align="center"><h1 align="center">
  @nodesecure/tarball
</h1>

<p align="center">
  Utilities to extract and deeply analyze NPM tarball
</p>

## Requirements
- [Node.js](https://nodejs.org/en/) v24 or higher

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/tarball
# or
$ yarn add @nodesecure/tarball
```

## Usage example

```ts
import * as tarball from "@nodesecure/tarball";

const scanResult = await tarball.scanPackage(
  process.cwd()
);
console.log(scanResult);
```

> [!NOTE]
> This package has been designed to be used by the Scanner package/workspace.

## API

- [SourceCode](./docs/SourceCode.md)
- [NpmTarball](./docs/NpmTarball.md)
- [NpmTarballWorkerPool](./docs/NpmTarballWorkerPool.md)
- [DependencyCollectableSet](./docs/DependencyCollectableSet.md)

---

> [!CAUTION]
> The following APIs are considered legacy and are waiting for deprecation in future releases.

### scanDirOrArchive(locationOrManifest: string | ManifestManager, ref: DependencyRef, options?: ScanOptions): Promise< void >

Scan a given local project or tarball (by providing the path or directly the ManifestManager instance).

`options` allow to customize the behavior of JS-X-Ray

```ts
export interface ScanOptions {
  astAnalyserOptions?: AstAnalyserOptions;
}
```

### scanPackage(manifestOrLocation: string | ManifestManager, options?: ScanOptions): Promise< ScannedPackageResult > 

Scan a given local project containing a Manifest (package.json).

```ts
interface ScannedPackageResult {
  files: {
    /** Complete list of files for the given package */
    list: string[];
    /** Complete list of extensions (.js, .md etc.) */
    extensions: string[];
    /** List of minified javascript files */
    minified: string[];
  };
  /** Size of the directory in bytes */
  directorySize: number;
  /** Unique license contained in the tarball (MIT, ISC ..) */
  uniqueLicenseIds: string[];
  /** All licenses with their SPDX */
  licenses: conformance.SpdxFileLicenseConformance[];
  ast: {
    dependencies: Record<string, Record<string, Dependency>>;
    warnings: Warning[];
  };
}
```

### extractAndResolve(location: string, options: TarballResolutionOptions): Promise< ManifestManager >

Extract a given remote package.

## License
MIT
npm package: @nodesecure/tracer
Description: JS-X-Ray variables and assignments tracer
Author: GENTILHOMME Thomas
Latest version: 4.0.0

<p align="center">
  <h1 align="center">
    @nodesecure/tracer
  </h1>
</p>

<p align="center">
  JS-X-Ray variables and assignments tracer
</p>

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/tracer
# or
$ yarn add @nodesecure/tracer
```

## Usage example

```js
import { VariableTracer } from "@nodesecure/tracer";

const tracer = new VariableTracer().enableDefaultTracing();

const data = tracer.getDataFromIdentifier("identifier...here");
console.log(data);
```

## API

```ts
export interface DataIdentifierOptions {
  /**
   * @default false
   */
  removeGlobalIdentifier?: boolean;
}

declare class VariableTracer extends EventEmitter {
  static AssignmentEvent: Symbol;

  literalIdentifiers: Map<string, string>;
  importedModules: Set<string>;

  enableDefaultTracing(): VariableTracer;
  debug(): void;
  trace(identifierOrMemberExpr: string, options?: {
    followConsecutiveAssignment?: boolean;
    moduleName?: string;
    name?: string;
  }): VariableTracer;
  removeGlobalIdentifier(identifierOrMemberExpr: string): string;
  getDataFromIdentifier(identifierOrMemberExpr: string, options: DataIdentifierOptions): null | {
    name: string;
    identifierOrMemberExpr: string;
    assignmentMemory: string[];
  };
  walk(node: any): void;
}
```

## License

MIT
npm package: @nodesecure/ts-source-parser
Description: TypeScript parser for AST XRay analysis
Author: Michelet Jean
Latest version: 1.1.0

<p align="center">
  <h1 align="center">
    @nodesecure/ts-source-parser
  </h1>
</p>

<p align="center">
  This package provide a TypeScript source parser for the `@nodesecure/js-x-ray` project.
</p>

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/ts-source-parser
# or
$ yarn add @nodesecure/ts-source-parser
```

## Usage example

```js
import { TsSourceParser } from "@nodesecure/ts-source-parser";

const parser = new TsSourceParser();
const body = parser.parse("const x: number = 5;");

console.log(body);
```

## Usage with `js-x-ray` 

```js
import { AstAnalyser } from "@nodesecure/js-x-ray";
import { TsSourceParser } from "@nodesecure/ts-source-parser";

const scanner = new AstAnalyser();

const result = scanner.analyse("const x: number = 5;", {
  customParser: new TsSourceParser()
});
console.log(result);
```
npm package: @nodesecure/utils
Description: NodeSecure utilities
Author: GENTILHOMME Thomas
Latest version: 2.3.0

<p align="center">
  <img src="https://user-images.githubusercontent.com/4438263/287494046-1121d658-3adb-4cca-9751-659e530f5a93.jpg" alt="@nodesecure/utils">
</p>

<p align="center">
    <a href="https://github.com/NodeSecure/blob/master/workspaces/utils">
      <img src="https://img.shields.io/badge/dynamic/json.svg?style=for-the-badge&url=https://raw.githubusercontent.com/NodeSecure/scanner/refs/heads/master/workspaces/utils/package.json&query=$.version&label=Version" alt="npm version">
    </a>
    <a href="https://github.com/NodeSecure/blob/master/workspaces/utils/graphs/commit-activity">
      <img src="https://img.shields.io/badge/Maintained%3F-yes-green.svg?style=for-the-badge" alt="maintenance">
    </a>
    <a href="https://api.securityscorecards.dev/projects/github.com/NodeSecure/utils">
      <img src="https://api.securityscorecards.dev/projects/github.com/NodeSecure/scanner/badge?style=for-the-badge" alt="ossf scorecard">
    </a>
    <a href="https://github.com/NodeSecure/blob/master/workspaces/utils/blob/master/LICENSE">
      <img src="https://img.shields.io/github/license/NodeSecure/scanner.svg?style=for-the-badge" alt="license">
    </a>
    <a href="https://github.com/NodeSecure/blob/master/workspaces/utils/actions?query=workflow%3A%22Node.js+CI%22">
      <img src="https://img.shields.io/github/actions/workflow/status/NodeSecure/scanner/node.js.yml?style=for-the-badge" alt="github ci workflow">
    </a>
</p>

NodeSecure utilities.

## Requirements

- [Node.js](https://nodejs.org/en/) v20 or higher

## Getting Started

This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).

```bash
$ npm i @nodesecure/utils
# or
$ yarn add @nodesecure/utils
```

## Usage example

```js
import * as utils from "@nodesecure/utils";

console.log(utils.parseAuthor("GENTILHOMME Thomas <foo.bar@gmail.com>"));
```

## API

See TypeScript definition file.

## License

MIT
npm package: @nodeskai/genehub
Description: GeneHub CLI - AI 员工基因管理命令行工具
Latest version: 2026.3.5-1

# @nodeskai/genehub - GeneHub CLI

AI 员工基因管理命令行工具，用于搜索、安装、发布基因到 GeneHub Registry。

## 安装

```bash
npm install -g @nodeskai/genehub
```

## 配置

### 配置文件

```bash
genehub config set registry https://genehub.nodeskai.com
genehub config set token <your-token>
genehub config get
```

配置文件存储在 `~/.genehub/config.json`。

### 环境变量

环境变量优先级高于配置文件：

| 环境变量 | 说明 | 对应配置项 |
|---|---|---|
| `GENEHUB_REGISTRY_URL` | Registry 地址 | `registry` |
| `GENEHUB_REGISTRY` | Registry 地址（别名） | `registry` |
| `GENEHUB_TOKEN` | 认证 Token | `token` |

本地开发示例：

```bash
GENEHUB_REGISTRY_URL=http://localhost:3000 GENEHUB_TOKEN=dev genehub publish ./my-gene
```

## 认证

使用 GitHub OAuth 登录，自动创建 API Key：

```bash
genehub auth login      # 打开浏览器完成 GitHub 登录，自动保存 token
genehub auth status     # 查看当前登录状态
genehub auth logout     # 退出登录（清除本地 token）
```

## 命令

| 命令 | 说明 |
|---|---|
| `genehub auth login` | GitHub OAuth 登录 |
| `genehub auth status` | 查看登录状态 |
| `genehub auth logout` | 退出登录 |
| `genehub search [keyword]` | 搜索基因库 |
| `genehub install <slug>` | 安装基因到当前 Agent 环境 |
| `genehub uninstall <slug>` | 卸载基因 |
| `genehub publish <path>` | 发布基因到 Registry（自动检测 CLAUDE.md / SKILL.md / AGENTS.md） |
| `genehub publish <path> -y` | 非交互模式发布（使用默认值） |
| `genehub list` | 列出已安装的基因 |
| `genehub learn <slug>` | 触发基因深度学习（L2） |
| `genehub init` | 初始化基因项目 |
| `genehub config` | 管理配置 |

## 自动检测发布

`genehub publish` 支持直接发布包含 skill 文件的目录，无需预先创建 `gene.yaml`：

```bash
# 目录中有 CLAUDE.md / SKILL.md / AGENTS.md 等文件即可
genehub publish ./my-claude-project
```

**检测优先级**：`CLAUDE.md` > `SKILL.md` > `AGENTS.md` > `.cursorrules` > `.clinerules` > `instructions.md` > `*.md`

自动推断的字段：
- **slug**：从目录名生成（kebab-case）
- **name**：从文件 H1 标题或 frontmatter 提取
- **description**：从文件首段内容提取
- **skill.content**：完整文件内容

需要交互确认的字段（`-y` 可跳过）：
- category（默认 `development`）
- tags（默认 `ability`）

首次发布后会自动生成 `gene.yaml` 保存到目录中，后续发布可直接使用。

## 目录结构

```
packages/cli/
├── src/
│   ├── index.ts          # 入口，注册所有命令
│   ├── config.ts         # 配置管理（文件 + 环境变量）
│   ├── output.ts         # 格式化输出工具
│   ├── utils/
│   │   ├── detect-skill.ts         # Skill 文件自动检测
│   │   └── interactive-manifest.ts # 交互式 manifest 构建
│   └── commands/
│       ├── auth.ts       # GitHub OAuth 登录
│       ├── config.ts     # config set / get
│       ├── init.ts       # 初始化基因项目
│       ├── install.ts    # 安装基因
│       ├── learn.ts      # 深度学习
│       ├── list.ts       # 列出已安装基因
│       ├── publish.ts    # 发布基因（支持自动检测）
│       ├── search.ts     # 搜索基因
│       └── uninstall.ts  # 卸载基因
├── dist/                 # 构建产物
├── package.json
└── tsup.config.ts
```

## 开发

```bash
cd packages/cli
pnpm install
pnpm build          # 构建
pnpm dev            # 开发模式
pnpm test           # 测试
```
npm package: @nodeskai/genehub-sdk
Description: GeneHub TypeScript SDK - API 客户端与产品适配器
Latest version: 2026.3.5-1

# @nodeskai/genehub-sdk

GeneHub TypeScript SDK -- API 客户端、产品适配器和学习引擎。

## 安装

```bash
npm install @nodeskai/genehub-sdk
```

## 使用

### API 客户端

```typescript
import { GeneHubClient } from '@nodeskai/genehub-sdk';

const client = new GeneHubClient({
  registryUrl: 'https://genehub.nodeskai.com',
  token: 'ghb_...',
});

const genes = await client.searchGenes({ q: 'code-review' });
const gene = await client.getGene('code-review');
const manifest = await client.getManifest('code-review');
```

### 产品适配器

为不同 AI 产品提供统一的基因安装/卸载接口：

```typescript
import { OpenClawAdapter } from '@nodeskai/genehub-sdk';

const adapter = new OpenClawAdapter({ workspaceDir: '/path/to/workspace' });
await adapter.install(manifest);
await adapter.uninstall('code-review');
const installed = await adapter.list();
```

支持的适配器：

| 适配器 | 产品 | 说明 |
|---|---|---|
| `OpenClawAdapter` | OpenClaw | AGENTS.md + memory + MCP 配置 |
| `NanobotAdapter` | nanobot | memory 记录、版本解析 |
| `GenericAdapter` | 通用 | 基础文件写入 |

### 学习引擎

```typescript
import { LearningEngine } from '@nodeskai/genehub-sdk';

const engine = new LearningEngine(client, adapter);
const task = await engine.createTask('code-review');
const result = await engine.checkResult('code-review');
```

## 目录结构

```
packages/sdk/typescript/
├── src/
│   ├── index.ts              # 导出入口
│   ├── client.ts             # GeneHubClient API 客户端
│   ├── adapters/             # 产品适配器
│   │   ├── base.ts
│   │   ├── openclaw.ts
│   │   ├── nanobot.ts
│   │   └── generic.ts
│   └── learning/
│       └── engine.ts         # L2 深度学习引擎
├── dist/                     # 构建产物
└── package.json
```

## 开发

```bash
pnpm build          # 构建
pnpm dev            # 开发模式（watch）
pnpm test           # 运行测试
```
npm package: @nodeskai/genehub-types
Description: GeneHub 共享类型定义与 Zod schemas
Latest version: 2026.3.5-1

# @nodeskai/genehub-types

GeneHub 共享类型定义与 Zod schemas，供 Registry、SDK、CLI 共用。

## 安装

```bash
npm install @nodeskai/genehub-types
```

## 导出内容

### Zod Schemas

- `GeneManifestSchema` -- 基因 Manifest 完整校验
- `AuthorSchema` -- 作者信息
- `CompatibilityEntrySchema` -- 产品兼容性
- `SkillSchema` / `RuleSchema` / `McpServerSchema` -- 技能、规则、MCP 配置

### 枚举

- `GeneCategory` -- `development` | `data` | `operations` | `network` | `creative` | `communication` | `security` | `efficiency`
- `GeneTag` -- `ability` | `personality` | `knowledge` | `tool`
- `GeneSource` -- `official` | `clawhub` | `evomap` | `community` | `agent` | `github`
- `ReviewStatus` -- `draft` | `pending` | `approved` | `rejected` | `flagged`
- `ProductId` -- `openclaw` | `nanobot` | `deskclaw`

### 实体类型

- `Gene` / `GeneVersion` / `GeneManifest` -- 基因相关
- `Genome` / `GenomeVersion` -- 基因组相关
- `Author` -- 作者

### API 类型

- `GeneListParams` / `GenomeListParams` -- 列表查询参数
- `GeneUpdateInput` / `GenomeUpdateInput` -- 更新输入
- `FederatedSearchParams` / `FederatedSearchResult` -- 联邦搜索
- `ResolveResult` -- 依赖解析结果

### 适配器接口

- `GeneAdapter` -- 产品适配器标准接口（`install` / `uninstall` / `list` / `detect`）

## 开发

```bash
pnpm build          # 构建
pnpm dev            # 开发模式（watch）
pnpm test           # 运行测试
```
npm package: @nodeskai/n8n-nodes-langfuse-prompt
Description: n8n community node to fetch and render prompts from Langfuse
Author: xzq-xu
Latest version: 0.3.0

# n8n-nodes-langfuse-prompt

This is an n8n community node. It lets you use Langfuse in your n8n workflows.

Langfuse is an open-source LLM engineering platform that helps with tracing, evaluations, prompt management, and metrics for LLM applications.

[n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/reference/license/) workflow automation platform.

[Installation](#installation)
[Operations](#operations)
[Credentials](#credentials)
[Compatibility](#compatibility)
[Usage](#usage)
[Resources](#resources)
[Version history](#version-history)

## Installation

Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community nodes documentation.

## Operations

- **Langfuse Prompt**: Fetch a prompt from Langfuse and render it with variables

## Credentials

You need to authenticate with your Langfuse instance:

1. Sign up for a Langfuse account or set up a self-hosted instance
2. Get your Public Key and Secret Key from the Langfuse dashboard
3. In n8n, create new credentials using the "Langfuse API (Basic Auth)" credential type
4. Enter your:
   - **Base URL**: Your Langfuse instance URL ()
   - **Public Key**: Your Langfuse public key (used as username)
   - **Secret Key**: Your Langfuse secret key (used as password)

## Compatibility

This node is compatible with n8n version 1.0.0 and above.

## Usage

### Langfuse Prompt Node

1. Add the Langfuse Prompt node to your workflow
2. Configure your Langfuse credentials
3. Set the **Prompt Name** to fetch from Langfuse
4. Optionally set a **Prompt Label** (defaults to "production")
5. Provide **Variables** using n8n's assignment collection for template rendering
6. Configure **Keep Original on Error** behavior (new in v0.2.0)

The node will:
- Fetch the prompt template from Langfuse
- Render the template with your provided variables using `{{variable}}` syntax
- Return the rendered prompt along with metadata

## Resources

* [n8n community nodes documentation](https://docs.n8n.io/integrations/#community-nodes)
* [Langfuse documentation](https://langfuse.com/docs)

## Version history

### 0.2.0

**New Features:**
- Added **Keep Original on Error** option for template rendering
- Improved variable handling with proper n8n assignments support
- Enhanced type safety with TypeScript interfaces

**Improvements:**
- Better error handling with n8n standard error types
- Cleaner code structure with extracted utility functions
- More robust variable parsing for different input formats

### 0.1.0

Initial release with Langfuse Prompt node functionality.
npm package: @nodeskai/skillshub
Description: SkillsHub CLI — publish, search, and install AI agent skills
Latest version: 0.4.0

# @nodeskai/skillshub

SkillsHub CLI — 搜索、安装和发布 AI Agent Skills 的命令行工具。

## 安装

```bash
# 全局安装
npm install -g @nodeskai/skillshub

# 或直接通过 npx 使用（无需安装）
npx @nodeskai/skillshub <command>
```

## 快速开始

```bash
# 搜索 skills
skillshub search agent

# 安装 skill（默认安装到 ~/.openclaw/skills/<slug>/）
skillshub install free-ride

# 安装指定版本
skillshub install free-ride -v 1.0.0

# 安装到自定义目录
skillshub install free-ride -d ./my-skills/free-ride

# 查看当前登录用户
skillshub whoami

# 查看 skill 详情
skillshub inspect free-ride

# 列出本地已安装的 skills
skillshub list
```

## 命令一览

### 搜索

```bash
skillshub search <关键词>
```

在 SkillsHub 平台搜索 skills，返回名称、描述、下载量和收藏数。

### 安装

```bash
skillshub install <slug> [选项]
```

下载 skill 并自动解压到本地。默认安装到 `~/.openclaw/skills/<slug>/`。

| 选项 | 说明 |
|------|------|
| `-d, --dir <目录>` | 安装到自定义目录 |
| `-v, --version <版本>` | 安装指定版本（默认最新） |
| `--cwd` | 安装到当前工作目录下的 `<slug>/` |

### 查看详情

```bash
skillshub inspect <slug>
```

查看 skill 的详细信息，包括版本列表、文件、标签、下载量和收藏数。

### 查看当前用户

```bash
skillshub whoami
```

显示当前登录用户的 handle、昵称和角色。

### 本地管理

```bash
skillshub list              # 列出本地已安装的 skills（别名: ls）
skillshub list -d ./my-skills  # 指定 Skills 目录
skillshub uninstall <slug>  # 卸载本地 skill（别名: rm）
skillshub uninstall <slug> -f  # 跳过确认直接卸载
skillshub uninstall <slug> -d ./my-skills  # 从指定目录卸载
```

默认扫描 `~/.openclaw/skills/` 目录，可通过 `-d` 指定其他目录。

### 检查更新

```bash
skillshub outdated          # 检查所有已安装 skill 是否有可用更新
skillshub outdated -d ./my-skills  # 检查指定目录
```

批量比对本地版本与远端最新版本，列出有更新的 skills。

### 更新

```bash
skillshub update <slug>     # 更新指定 skill 到最新版本
skillshub update --all      # 更新所有有可用更新的 skills
skillshub update <slug> -d ./my-skills  # 更新到指定目录
```

### 发布

```bash
skillshub publish [目录]
```

将本地目录发布为一个 skill。目录下必须包含 `SKILL.md` 文件，且 frontmatter 中需包含 `slug` 和 `version` 字段。

**SKILL.md 示例：**

```markdown
---
slug: my-awesome-skill
version: 1.0.0
displayName: My Awesome Skill
summary: 一个示例 skill
tags: example, demo
---

# My Awesome Skill

Skill 的详细说明...
```

### 同步

```bash
skillshub sync [目录]
```

比较本地 SKILL.md 的版本和远端版本，如果不一致则自动发布。适合 CI/CD 场景。

### 收藏

```bash
skillshub star <slug>      # 收藏
skillshub unstar <slug>    # 取消收藏
```

### 删除

```bash
skillshub delete <slug> [-f]
```

删除你发布的 skill。加 `-f` 跳过确认提示。删除后 slug 将保留 90 天。

### Token 管理

```bash
skillshub token create <名称>   # 创建 API Token
skillshub token list             # 列出所有 Token
skillshub token revoke <id>      # 撤销 Token
```

## 认证

需要登录的命令（publish、sync、star、delete、token、whoami）需要先配置认证：

1. 在 [SkillsHub](https://skills.nodeskai.com) 网站登录
2. 进入用户中心，创建 API Token
3. 在终端执行：

```bash
skillshub login <你的token>
```

Token 保存在 `~/.skillshub/config.json`。

## 配置

默认连接 `https://skills.nodeskai.com`。如需切换到其他环境：

```bash
skillshub config --api-url https://your-server.com
```

## License

MIT