Skip to main content

A CLI tool for collecting and forwarding AI prompts/responses to API / 收集和转发 AI Prompt 与响应的 CLI 工具

Project description

Prompt Collector

PyPI version Python 3.8+

一个 CLI 工具,用于收集 Prompt 和 AI 响应,并推送到远程 API 服务。

功能特点

  • 支持发送 promptresult 两种类型的事件
  • 从环境变量读取配置,支持静默失败
  • 从 stdin 或命令行参数读取内容
  • 内容自动截断(最大 10000 字符)
  • 错误日志写入 /tmp/prompt_collector_error.log

安装

从 PyPI 安装(推荐)

# 使用 pip 安装
pip install prompt-collector

# 或使用 uv 安装
uv pip install prompt-collector

从源码安装

# 克隆仓库
git clone https://github.com/yourusername/prompt-collector.git
cd prompt-collector

# 安装依赖
pip install -e ".[dev]"

# 或使用生产依赖
pip install -e .

配置

通过环境变量配置:

export PROMPT_COLLECTOR_API_URL="https://your-api.com"  # API 基础 URL(必需)
export PROMPT_COLLECTOR_USERNAME="your-username"         # 用户名(必需)
export PROMPT_COLLECTOR_API_KEY="your-api-key"          # API Key(可选)
export PROMPT_COLLECTOR_TIMEOUT="5"                     # 超时时间,默认 5 秒(可选)

使用方法

基本用法

# 发送 Prompt(从 stdin 读取)
echo '{"session_id": "sess_abc123", "content": "Hello AI"}' | prompt-collector --type prompt

# 发送 Result(从 stdin 读取)
echo '{"session_id": "sess_abc123", "content": "AI response"}' | prompt-collector --type result

# 发送原始文本
printf "Hello AI" | prompt-collector --type prompt --session-id "sess_abc123"

# 使用命令行参数
prompt-collector --type prompt --session-id "sess_abc123" --content "Hello AI"

与 Claude Code 集成

Claude Code 支持通过 hooks 在特定事件触发时执行自定义命令。

配置步骤

  1. 在项目根目录或用户主目录创建 .claude/settings.json
# 项目级配置(推荐)
mkdir -p .claude
touch .claude/settings.json

# 或全局配置
mkdir -p ~/.claude
touch ~/.claude/settings.json
  1. 添加 hooks 配置:
{
  "hooks": {
    "UserPromptSubmit": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "prompt-collector --type prompt"
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "prompt-collector --type result"
          }
        ]
      }
    ]
  }
}

可用的 Claude Code 环境变量

变量名 说明 示例值
CLAUDE_SESSION_ID 当前会话唯一标识 abc123-def456
CLAUDE_LAST_MESSAGE 最后一条消息内容 "Hello AI"
CLAUDE_PROJECT_DIR 当前项目目录 /home/user/myproject

可用的 Hooks 类型

Hook 名称 触发时机
UserPromptSubmit 用户提交消息时
Stop 会话结束或 AI 响应完成时

完整配置示例

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "prompt-collector --type prompt"
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "prompt-collector --type result"
          }
        ]
      }
    ]
  }
}

验证配置

配置完成后,启动 Claude Code 并输入任意消息,检查数据是否被正确收集:

# 查看错误日志
tail -f /tmp/prompt_collector_error.log

# 测试配置是否正确加载
python -c "from prompt_collector.config import get_api_base_url; print(get_api_base_url())"

与 Cursor 集成

提示: Cursor 完全兼容 Claude Code 的 hooks 配置格式。你不需要单独配置 Cursor,只需创建 .claude/settings.json 文件即可(即使你没有安装 Claude Code)。Cursor 会自动读取并应用此配置。

Cursor 支持加载 Claude Code 的 hooks 配置,实现无缝兼容。

配置示例

在项目根目录创建 .claude/settings.json

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "prompt-collector --type prompt"
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "prompt-collector --type result"
          }
        ]
      }
    ]
  }
}

详细配置说明请参考 Cursor 第三方 Hook 官方文档

CLI 参数

usage: prompt-collector [-h] --type {prompt,result} [--session-id SESSION_ID] [--content CONTENT]

options:
  -h, --help            show this help message and exit
  --type {prompt,result}
                        Type of event to send: 'prompt' for user input, 'result' for AI response
  --session-id SESSION_ID
                        Session identifier (can also be read from stdin JSON)
  --content CONTENT     Content to send (can also be read from stdin)

API 接口

工具会向 POST {API_URL}/api/sessions 发送请求:

Request:

{
  "username": "your-username",
  "session_id": "session-identifier",
  "prompt": "user prompt content (仅当 type=prompt)",
  "result": "ai response content (仅当 type=result)"
}

测试

# 运行所有测试
pytest

# 运行特定测试
pytest tests/test_parser.py

# 带覆盖率报告
pytest --cov=prompt_collector

错误排查

触发记录有但发送不成功时的常见原因

  1. 环境变量在 Cursor 中未生效
    Cursor 执行 hook 时可能不会继承你在终端里配置的环境变量。请确保在 Cursor 能读取到的地方配置:

    • 在项目根目录使用 .env(若 Cursor 支持加载),或
    • 在 Cursor 设置里配置环境变量(如 Settings → 搜索 Environment),或
    • 在启动 Cursor 的终端里先 export 再启动,使当前会话继承变量。
  2. Result(Stop)事件内容为空
    Cursor 的 Stop hook 会传入 transcript_path,本工具从该 JSONL 文件读取 AI 回复。若 transcript_pathnull、文件不存在或格式不符,解析出的 content 为空,工具会静默不发送(不会写错误日志)。

    • 若只配置了 Stop、未配置 beforeSubmitPrompt,或 Cursor 未写入 transcript,就会出现“有触发但没发出去”的情况。
  3. 网络或 API 错误
    超时、4xx/5xx、代理问题等会记录在错误日志中。

查看日志

错误日志路径(与系统临时目录一致,一般为 /tmp 或 macOS 的 /var/folders/.../T):

# 错误日志(HTTP 失败、超时等会写在这里)
tail -f $(python -c "import tempfile; from pathlib import Path; print(Path(tempfile.gettempdir()) / 'prompt_collector_error.log')")

启用调试日志

设置环境变量后,每次运行会在临时目录下写 prompt_collector_debug.log,记录在何处退出(例如:缺少 API URL、缺少 username、content 为空、或 send 失败):

export PROMPT_COLLECTOR_DEBUG=1
# 然后在 Cursor 中触发一次 hook,再查看:
tail -f $(python -c "import tempfile; from pathlib import Path; print(Path(tempfile.gettempdir()) / 'prompt_collector_debug.log')")

看到 exit: content empty (...) 即说明是 Result 内容为空导致未发送;看到 send_event: failed 则需结合上面的 error 日志排查网络或 API。

项目结构

prompt-collector/
├── pyproject.toml              # 项目配置
├── README.md                   # 项目说明
├── src/
│   └── prompt_collector/
│       ├── __init__.py
│       ├── __main__.py         # 模块入口
│       ├── config.py           # 环境变量配置
│       ├── parser.py           # 输入解析
│       ├── formatter.py        # 消息格式化
│       ├── sender.py           # HTTP 发送
│       └── main.py             # CLI 和主流程
└── tests/                      # 测试目录

English Version

Prompt Collector

PyPI version Python 3.8+

A CLI tool for collecting prompts and AI responses, and pushing them to a remote API service.

Features

  • Supports sending prompt and result event types
  • Reads configuration from environment variables with silent failure support
  • Reads content from stdin or command line arguments
  • Automatic content truncation (max 10000 characters)
  • Error logs written to /tmp/prompt_collector_error.log

Installation

Install from PyPI (Recommended)

# Using pip
pip install prompt-collector

# Or using uv
uv pip install prompt-collector

Install from Source

# Clone the repository
git clone https://github.com/yourusername/prompt-collector.git
cd prompt-collector

# Install dependencies
pip install -e ".[dev]"

# Or install production dependencies only
pip install -e .

Configuration

Configure via environment variables:

export PROMPT_COLLECTOR_API_URL="https://your-api.com"  # API base URL (required)
export PROMPT_COLLECTOR_USERNAME="your-username"         # Username (required)
export PROMPT_COLLECTOR_API_KEY="your-api-key"          # API Key (optional)
export PROMPT_COLLECTOR_TIMEOUT="5"                     # Timeout in seconds, default 5 (optional)

Usage

Basic Usage

# Send Prompt (read from stdin)
echo '{"session_id": "sess_abc123", "content": "Hello AI"}' | prompt-collector --type prompt

# Send Result (read from stdin)
echo '{"session_id": "sess_abc123", "content": "AI response"}' | prompt-collector --type result

# Send raw text
printf "Hello AI" | prompt-collector --type prompt --session-id "sess_abc123"

# Using command line arguments
prompt-collector --type prompt --session-id "sess_abc123" --content "Hello AI"

Integration with Claude Code

Claude Code supports executing custom commands when specific events are triggered through hooks.

Configuration Steps

  1. Create .claude/settings.json in the project root or user home directory:
# Project-level configuration (recommended)
mkdir -p .claude
touch .claude/settings.json

# Or global configuration
mkdir -p ~/.claude
touch ~/.claude/settings.json
  1. Add hooks configuration:
{
  "hooks": {
    "UserPromptSubmit": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "prompt-collector --type prompt"
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "prompt-collector --type result"
          }
        ]
      }
    ]
  }
}

Available Claude Code Environment Variables

Variable Name Description Example Value
CLAUDE_SESSION_ID Unique session identifier abc123-def456
CLAUDE_LAST_MESSAGE Content of the last message "Hello AI"
CLAUDE_PROJECT_DIR Current project directory /home/user/myproject

Available Hook Types

Hook Name Trigger Timing
UserPromptSubmit When user submits a message
Stop When session ends or AI response completes

Complete Configuration Example

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "prompt-collector --type prompt"
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "prompt-collector --type result"
          }
        ]
      }
    ]
  }
}

Verify Configuration

After configuration, start Claude Code and type any message to check if data is being collected correctly:

# View error logs
tail -f /tmp/prompt_collector_error.log

# Test if configuration is loaded correctly
python -c "from prompt_collector.config import get_api_base_url; print(get_api_base_url())"

Integration with Cursor

Tip: Cursor is fully compatible with Claude Code's hooks configuration format. You don't need a separate configuration for Cursor—simply create a .claude/settings.json file (even if you don't have Claude Code installed). Cursor will automatically read and apply this configuration.

Cursor supports loading Claude Code hooks configuration for seamless compatibility.

Configuration Example

Create .claude/settings.json in the project root:

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "prompt-collector --type prompt"
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "prompt-collector --type result"
          }
        ]
      }
    ]
  }
}

For detailed configuration instructions, please refer to the Cursor Third-Party Hooks Documentation.

CLI Parameters

usage: prompt-collector [-h] --type {prompt,result} [--session-id SESSION_ID] [--content CONTENT]

options:
  -h, --help            show this help message and exit
  --type {prompt,result}
                        Type of event to send: 'prompt' for user input, 'result' for AI response
  --session-id SESSION_ID
                        Session identifier (can also be read from stdin JSON)
  --content CONTENT     Content to send (can also be read from stdin)

API Interface

The tool sends requests to POST {API_URL}/api/sessions:

Request:

{
  "username": "your-username",
  "session_id": "session-identifier",
  "prompt": "user prompt content (only when type=prompt)",
  "result": "ai response content (only when type=result)"
}

Testing

# Run all tests
pytest

# Run specific test
pytest tests/test_parser.py

# With coverage report
pytest --cov=prompt_collector

Troubleshooting

When hooks fire but nothing is sent

  1. Env vars not visible to Cursor
    Cursor may not inherit your shell env. Set PROMPT_COLLECTOR_API_URL and PROMPT_COLLECTOR_USERNAME in a place Cursor sees (e.g. project .env or Cursor settings).

  2. Result (Stop) content is empty
    The Stop hook sends transcript_path; we read the AI reply from that JSONL file. If transcript_path is null, the file is missing, or format differs, we skip sending without writing to the error log.
    If only Stop is configured or Cursor does not write the transcript, you get “triggered but not sent”.

  3. Network/API errors
    Timeouts, 4xx/5xx, or proxy issues are written to the error log.

View logs

Error log path (under the system temp dir):

tail -f $(python -c "import tempfile; from pathlib import Path; print(Path(tempfile.gettempdir()) / 'prompt_collector_error.log')")

Enable debug log

With PROMPT_COLLECTOR_DEBUG=1, each run appends to prompt_collector_debug.log in the temp dir, showing where the run exited (e.g. missing API URL, empty content, or send failed):

export PROMPT_COLLECTOR_DEBUG=1
# Trigger a hook in Cursor, then:
tail -f $(python -c "import tempfile; from pathlib import Path; print(Path(tempfile.gettempdir()) / 'prompt_collector_debug.log')")

exit: content empty (...) means result content was empty; send_event: failed means check the error log for HTTP/API issues.

Project Structure

prompt-collector/
├── pyproject.toml              # Project configuration
├── README.md                   # Project documentation
├── src/
│   └── prompt_collector/
│       ├── __init__.py
│       ├── __main__.py         # Module entry point
│       ├── config.py           # Environment variable configuration
│       ├── parser.py           # Input parsing
│       ├── formatter.py        # Message formatting
│       ├── sender.py           # HTTP sending
│       └── main.py             # CLI and main workflow
└── tests/                      # Test directory

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

prompt_collector-0.1.3.tar.gz (22.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

prompt_collector-0.1.3-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file prompt_collector-0.1.3.tar.gz.

File metadata

  • Download URL: prompt_collector-0.1.3.tar.gz
  • Upload date:
  • Size: 22.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for prompt_collector-0.1.3.tar.gz
Algorithm Hash digest
SHA256 01e82ac36a960a218a4766b785ac102e6b4db3bd45c595b42027a106342b326a
MD5 72babeb998f5592b6b3926315f70a8d9
BLAKE2b-256 5b2e7ab54dcb17ce2c388aa7671e85e575b5913972e841478f498a9fa6859174

See more details on using hashes here.

File details

Details for the file prompt_collector-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for prompt_collector-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 bdf077aea295eb12adf3657289359b8ad73a95870206fa705d9818a02e50b1a4
MD5 ec2da0ac250ce6881bd33b03d1e88e88
BLAKE2b-256 327286118997ccaeaa3838f0f6fff1587f4dd5bb9882f8cb1c4c85b721c75de6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page