open-index/open-npm huggingface dataset:
npm package: @limxdynamics/gm-cli
Description: Gradmotion CLI — 训练任务管理命令行工具，支持 Agent 集成
Author: LimX Dynamics
Latest version: 0.1.12

# Gradmotion CLI

Cross-platform CLI for managing training tasks and projects on [Gradmotion](https://gm-spaces.limxdynamics.com). It outputs structured JSON by default and is designed for AI Agent integration.


## Features

- **Cross-platform binary** — macOS / Linux / Windows (amd64 & arm64)
- **Secure authentication** — API key stored in system keychain (macOS Keychain / Windows Credential Manager / Linux Secret Service)
- **Multi-profile config** — switch quickly between dev / staging / prod environments
- **Full task lifecycle** — create, edit, run, stop, delete, logs, hyperparameters, and batch operations
- **Agent-friendly output** — JSON by default + JSONL request logs for automation
- **Resilient requests** — built-in retry with exponential backoff, configurable timeout and concurrency

## Installation

```bash
npm install -g @limxdynamics/gm-cli
```

> Requires Node.js >= 16. The installer auto-selects the correct binary for your OS/architecture.

### Verify

```bash
gm --version
```

## Quick Start

```bash
# 1. Login (API key saved to system keychain)
gm auth login --api-key "gm_sk_your_key"

# 2. Verify connection
gm auth status        # local check
gm auth whoami        # server check

# 3. Start using
gm task list
gm project list
```

> Create API keys in Gradmotion: avatar menu (bottom-left) → **API Key Management**. The full key is shown only once at creation time.

## Command Overview

```text
gm
├── auth        login / logout / status / whoami
├── config      set / get / profile (list / set / use)
├── project     list / create / info / edit / delete
└── task        create / edit / copy / list / info / run / stop / delete
                logs / resource / image / storage / data / hp / env
                params / tag / batch / model
```

Use `gm --help` or `gm <command> --help` for details.

## Common Examples

```bash
# Task management
gm task list --page 1 --limit 50
gm task info --task-id "task_xxx"
gm task create --file ./create.json
gm task run --task-id "task_xxx"
gm task logs --task-id "task_xxx" --follow --interval 2s --timeout 5m
gm task stop --task-id "task_xxx"

# Project management
gm project list --page 1 --limit 50
gm project create --file ./project-create.json

# Profile switching
gm config profile set dev --base-url "https://dev.example.com/prod-api" --timeout 30s
gm config profile use dev

# Output control
gm task list --human          # human-readable table
gm task list --quiet          # key fields only
gm task list --debug          # debug logs
```

## Configuration

**Priority:** CLI flags > Environment variables > Config file

| Variable | Description |
|----------|-------------|
| `GM_BASE_URL` | Service endpoint |
| `GM_API_KEY` | API key (temporary, not persisted) |
| `GM_TIMEOUT` | Request timeout (e.g. `30s`) |
| `GM_RETRY` | Retry count |
| `GM_CONCURRENCY` | Concurrency limit |
| `GM_PROFILE` | Temporary profile |

Config file location:
- **macOS / Linux**: `~/.config/gradmotion/config.yaml`
- **Windows**: `%APPDATA%\gradmotion\config.yaml`
npm package: @limxdynatic-gradmotion/gradmotion-cli
Description: Gradmotion CLI — 训练任务管理命令行工具，支持 Agent 集成
Author: LimX Dynamics
Latest version: 0.1.7
Deprecated: This package has been moved to @limxdynamics/gm-cli. Please install: npm install -g @limxdynamics/gm-cli

ERROR: No README data found!
npm package: @lin-media/contextmenu
Description: contextmenu
Author: c10342
Latest version: 1.0.3

# 右键菜单

## 安装

```bash
npm i @lin-media/contextmenu
```

## 初始化

```javascript
import MediaPlayer from "@lin-media/player";
import Contextmenu from "@lin-media/contextmenu";
MediaPlayer.use(Contextmenu);

const contextMenuList = [
  {
    label: "播放",
    desc: "描述信息",
    type: "MenuItem",
    callback: () => {
      player.play();
    },
    eventName: "click-play"
  },
  {
    label: "暂停",
    type: "MenuItem",
    callback: () => {
      player.pause();
    }
  },
  {
    label: "播放/暂停",
    type: "MenuItem",
    callback: () => {
      player.toggle();
    }
  },
  {
    type: "MenuLine"
  },
  {
    type: "SubMenuItem",
    label: "倍数",
    subMenuList: [
      {
        label: "0.5x",
        callback: () => {
          player.setSpeed(0.5);
        }
      },
      {
        label: "1x",
        callback: () => {
          player.setSpeed(1);
        }
      },
      {
        label: "1.5x",
        callback: () => {
          player.setSpeed(1.5);
        }
      }
    ]
  },
  {
    type: "SubMenuItem",
    label: "清晰度",
    subMenuList: [
      {
        label: "标清",
        callback: () => {
          player.switchDefinition(0);
        }
      },
      {
        label: "高清",
        callback: () => {
          player.switchDefinition(1);
        }
      }
    ]
  }
];
const player = new MediaPlayer({
  // ...
  Contextmenu: {
    // 一级菜单宽度
    menuItemWidth: "300px",
    // 二级菜单宽度
    subMenuItemWidth: "100px"
  }
});

player.$on("click-play", (item) => {
  console.log(item);
});
```

## Contextmenu 参数

| 参数             | 说明                 | 类型   | 可选值 | 默认值 |
| ---------------- | -------------------- | ------ | ------ | ------ |
| menuList         | 菜单列表，格式见下方 | Array  | —      | —      |
| menuItemWidth    | 一级菜单宽度         | string | —      | 250px  |
| subMenuItemWidth | 二级菜单宽度         | string | —      | 80%    |

## menuList 参数格式

菜单项分为三种格式，分别是：MenuItem，MenuItemLine，SubMenuItem

MenuItem：

| 字段      | 说明                                                           | 类型   |
| --------- | -------------------------------------------------------------- | ------ |
| type      | 菜单类型，值为:`MenuItem`                                      | string |
| label     | 菜单文本                                                       | string |
| callback  | 回调函数，可选。存在时，点击菜单项会执行，回调参数：`MenuItem` | Function |
| eventName | 自定义事件，可选。存在时，点击菜单项会广播事件                 | string |
| desc      | 描述信息，可选。                                               | string |

MenuItemLine：

| 字段 | 说明                      | 类型   |
| ---- | ------------------------- | ------ |
| type | 菜单类型，值为:`MenuLine` | string |

SubMenuItem：

| 字段        | 说明                                   | 类型   |
| ----------- | -------------------------------------- | ------ |
| type        | 菜单类型，值为:`SubMenuItem`           | string |
| label       | 菜单文本                               | string |
| subMenuList | 二级菜单列表，列表项请参考：`MenuItem` | Array&lt;MenuItem&gt; |
npm package: @lin-media/danmaku
Description: danmaku
Author: c10342
Latest version: 1.0.3

# 弹幕

## 安装

```bash
npm i @lin-media/danmaku
```

## 初始化

```javascript
import MediaPlayer from "@lin-media/player";
import Danmaku from "@lin-media/danmaku";
MediaPlayer.use(Danmaku);

const player = new MediaPlayer({
  // ...
  Danmaku: {
    // 弹幕字体颜色，随机
    fontColors: ["blue", "red", "green", "#fff"],
    // 弹幕字体大小随机
    fontSizes: [16, 18, 20, 22, 24, 26, 28]
  }
});
```

## Danmaku 参数

| 参数           | 说明                             | 类型          | 可选值 | 默认值        |
| -------------- | -------------------------------- | ------------- | ------ | ------------- |
| trackSize      | 轨道高度                         | number        | —      | 12            |
| renderInterval | 弹幕数据队列默认轮询间隔时间     | number        | —      | 150           |
| speedArg       | 移动速率                         | number        | —      | 0.0058        |
| discardTime    | 弹幕的超时时间，超过时间会被丢弃 | number        | —      | 5 _ 60 _ 1000 |
| fontColors     | 弹幕字体颜色，随机               | Array<string> | —      | —             |
| fontSizes      | 弹幕字体大小,随机                | Array<number> | —      | —             |

## API

- `player.danmaku.send(message)`：发送消息弹幕，message 格式见下方
- `player.danmaku.play()`：开始弹幕
- `player.danmaku.pause()`：暂停弹幕
- `player.danmaku.resize()`：容器发生变化时调用
- `player.danmaku.clearScreen()`：清屏，移除所有弹幕
- `player.danmaku.close()`：关闭弹幕
- `player.danmaku.open()`：打开弹幕

## message 格式

- `player.danmaku.send('你好')`
- `player.danmaku.send({text:'你好',fontColor:30})`
- `player.danmaku.send([{text:'你好',fontColor:30},{text:'世界',fontColor:'blue'}])`

当参数是`Object`或者`Array`类型时，下列字段可选

| 字段      | 说明                 | 类型   |
| --------- | -------------------- | ------ |
| text      | 弹幕文本             | string |
| fontSize  | 字体大小             | number |
| fontColor | 字体颜色             | string |
| rollTime  | 弹幕移动时间，单位秒 | number |

## 自定义语言包

```javascript
MediaPlayer.useLang({
  danmaku: {
    full: "全屏",
    top: "顶部",
    bottom: "底部",
    pause: "暂停弹幕",
    show: "显示弹幕",
    opacity: "透明度",
    speed: "弹幕速度",
    showArea: "显示区域"
  }
});
```
npm package: @lin-media/highlight
Description: highlight
Author: c10342
Latest version: 1.0.3

# 自定义进度条提示点

## 安装

```bash
npm i @lin-media/highlight
```

## 初始化

```javascript
import MediaPlayer from "@lin-media/player";
import Highlight from "@lin-media/highlight";
MediaPlayer.use(Highlight);

const highlightList = [
  {
    time: 20,
    text: "这是第 20 秒"
  }
];
const player = new MediaPlayer({
  // ...
  Highlight: {
    // 点击跳转到提示点的时间点，默认true
    jump: true,
    // 显示点击的提示点的文本，默认true
    showTip: true
    // 提示点列表，直接通过options参数传入，或者调用set()
    list:highlightList
  }
});

// 或者通过 `player.highlight.set()` 设置。
player.highlight.set(highlightList);

// 销毁提示点
player.highlight.destroy();

// 监听提示点点击事件
player.$on("highlight-click", (item) => {
  console.log(item);
});
```

## Highlight 参数

| 参数    | 说明                         | 类型    | 可选值 | 默认值 |
| ------- | ---------------------------- | ------- | ------ | ------ |
| jump    | 点击是否跳转到提示点的时间点 | boolean | —      | true   |
| showTip | 是否显示点击的提示点的文本   | boolean | —      | true   |
| list    | 提示点列表，格式见下方       | Array   | —      | —      |

## 事件

| 事件名称        | 说明                 | 回调参数 |
| --------------- | -------------------- | -------- |
| highlight-click | 点击提示点的时候触发 | event    |

## API

- `player.highlight.set(list:Array)` : 设置提示点列表

- `player.highlight.destroy()` : 销毁提示点

## list 格式

| 字段 | 说明     | 类型    |
| ---- | -------- | ------- |
| time | 时间点   | number |
| text | 显示文本 | string  |
npm package: @lin-media/preview
Description: preview
Author: c10342
Latest version: 1.0.3

# 视频缩略图预览

## 安装

```bash
npm i @lin-media/preview
```

## 初始化

```javascript
import MediaPlayer from "@lin-media/player";
import Preview from "@lin-media/preview";
MediaPlayer.use(Preview);
```

缩略图有 2 中形式，一种是通过列表传入对应时间点的缩略图，另一种是传入整个视频的缩略图地址（这种是可以查看任意时间点的缩略图，但是缩略图必须是完整的）

第一种：

```javascript
const previewList = [
  {
    time: 40,
    url: "http://xxx/demo1.png"
  },
  {
    time: 80,
    url: "http://xxx/demo2.png"
  }
];
const player = new MediaPlayer({
  // ...
  Preview: {
    // 通过参数传入或者通过setPreview方法设置
    list: previewList
  }
});

// player.preview.setPreview(previewList)

player.$on("preview-click", (item: any) => {
  console.log(item);
});
```

第二种：

```javascript
const player = new MediaPlayer({
  // ...
  Preview: {
    // 通过参数传入或者通过setBarView方法设置
    barPreviewUrl: "https://xxx/demo.jpg"
  }
});
// player.preview.setBarView('https://xxx/demo.jpg')
```

## Preview 参数

| 参数          | 说明                         | 类型   | 可选值 | 默认值 |
| ------------- | ---------------------------- | ------ | ------ | ------ |
| list          | 时间点缩略图列表，格式见下方 | Array  | —      | —      |
| barPreviewUrl | 完整的视频缩略图地址         | string | —      | —      |

## 事件

| 事件名称      | 说明             | 回调参数 |
| ------------- | ---------------- | -------- |
| preview-click | 点击缩略点时触发 | item     |

## API

- `player.preview.setPreview(list:Array)` : 设置时间点缩略图列表

- `player.preview.destroyPreview()` : 销毁时间点缩略图列表

- `player.preview.setBarView(barPreviewUrl:string)` : 设置进度条预览

- `player.preview.destroyBarView()` : 销毁进度条预览

## list 格式

| 字段 | 说明     | 类型   |
| ---- | -------- | ------ |
| time | 时间点   | number |
| url  | 图片地址 | string |
| alt  | alt 属性 | string |
npm package: @lin-media/screenshot
Description: screenshot
Author: c10342
Latest version: 1.0.3

# 截图

## 安装

```bash
npm i @lin-media/screenshot
```

## 初始化

```javascript
import MediaPlayer from "@lin-media/player";
import Screenshot from "@lin-media/screenshot";
MediaPlayer.use(Screenshot);

const player = new MediaPlayer({
  // ...
  Screenshot: {
    // 点击后自动下载,默认true，你可以设置为false，然后通过事件监听来自定义点击之后的操作
    download: true
  }
});

// 监听点击事件
player.$on("screenshot", (imageBase64) => {
  console.log(imageBase64);
});

// 调用截图方法，请务必当open为true是才能使用该方法，false的是时候是不会往实例上面挂载该方法的
player.screenshot.snapshot();
```

注意：该插件需要视频开启跨域功能，否则无法截图

## Screenshot 参数

| 参数     | 说明                                                        | 类型    | 可选值 | 默认值 |
| -------- | ----------------------------------------------------------- | ------- | ------ | ------ |
| download | 是否点击后自动下载                                          | boolean | —      | true   |
| picName | 下载的图片名称                                          | string | —      | screenshot.png   |

## 事件

| 事件名称   | 说明           | 回调参数    |
| ---------- | -------------- | ----------- |
| screenshot | 截图的时候触发 | base64 图片 |

## API

- `player.screenshot.snapshot()` : 调用截图方法
npm package: @lin-media/zoom
Description: zoom
Author: c10342
Latest version: 1.0.3

# 缩放

## 安装

```bash
npm i @lin-media/zoom
```

## 初始化

```javascript
import MediaPlayer from "@lin-media/player";
import Zoom from "@lin-media/zoom";
MediaPlayer.use(Zoom);

const player = new MediaPlayer({
  // ...
  Zoom: {
    // 是否允许横向缩放，默认true
    x: true,
    // 是否允许纵向缩放，默认true
    y: true,
    // 最大缩放宽度
    maxWidth: 400,
    // 最大缩放高度
    maxHeight: 400,
    // 最小缩放高度
    minHeight: 100,
    // 最小缩放宽度
    minWidth: 100
  }
});

// 监听缩放事件
player.$on("zoom", (item) => {
  console.log(item);
});
```

## Zoom 参数

| 参数      | 说明              | 类型    | 可选值 | 默认值 |
| --------- | ----------------- | ------- | ------ | ------ |
| x         | 是否允许 x 轴缩放 | boolean | —      | true   |
| y         | 是否允许 y 轴缩放 | boolean | —      | true   |
| maxWidth  | 最大缩放宽度      | number  | —      | —      |
| maxHeight | 最大缩放高度      | number  | —      | —      |
| minHeight | 最小缩放高度      | number  | —      | 0      |
| minWidth  | 最小缩放宽度      | number  | —      | 0      |

## 事件

| 事件名称 | 说明       | 回调参数                     |
| -------- | ---------- | ---------------------------- |
| zoom     | 缩放时触发 | {width:number,height:number} |