Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# CameraCapture Agent Entry

This repository includes a publish-ready ClawHub/OpenClaw skill for `ccap`.

If you need to install or use `ccap` as a tool for camera capture, device inspection, image capture, or video metadata inspection, read the published skill folder first:

- [skills/ccap/SKILL.md](skills/ccap/SKILL.md)

Use that skill when the task involves any of the following:

- install ccap on the current machine
- build CameraCapture from source
- use Homebrew to install ccap on macOS
- download and run a release binary when no build toolchain is available
- list camera devices
- inspect device capabilities
- capture frames with the CLI
- inspect video metadata

The `.github/skills/` directory is for repository-local development workflows.
The `skills/ccap/` directory is the standalone skill bundle intended for ClawHub/OpenClaw distribution.

Prefer the `ccap` CLI over calling internal source files directly.
Prefer structured JSON output when the command supports `--json`.
Do not assume camera permission, GUI availability, or video file playback support on every platform.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ A high-performance, lightweight cross-platform camera capture library with hardw

## Quick Start

### AI Agent Skill

This repository also includes a publish-ready skill bundle for ClawHub/OpenClaw.

- Agent entry: [AGENTS.md](./AGENTS.md)
- Publishable skill folder: [skills/ccap](./skills/ccap)
- Skill definition: [skills/ccap/SKILL.md](./skills/ccap/SKILL.md)

The skill is structured as a standalone skill folder with a top-level `SKILL.md`, optional supporting text files, and instructions that guide agents to choose among an existing installation, Homebrew on macOS, source builds, and release-binary fallback, then prefer the `ccap` CLI with `--json` where supported.

If you want to publish the skill to ClawHub, publish the skill folder itself rather than the repository root:

```bash
clawhub publish ./skills/ccap --slug ccap --name "ccap" --version 0.1.0 --tags latest --changelog "Initial ClawHub release"
```

### Installation

1. Build and install from source (on Windows, use git-bash):
Expand Down
16 changes: 16 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@

## 快速开始

### AI Agent 技能入口

本仓库现在也包含了一个可发布到 ClawHub/OpenClaw 的独立技能包,可将 `ccap` 当作实际可用的相机与视频输入工具来使用。

- Agent 入口: [AGENTS.md](./AGENTS.md)
- 可发布技能目录: [skills/ccap](./skills/ccap)
- 技能定义: [skills/ccap/SKILL.md](./skills/ccap/SKILL.md)

该技能按照可发布的独立 skill folder 组织:顶层 `SKILL.md` 加可选辅助文本文件。它会指导 Agent 在已有安装、macOS Homebrew、源码构建和 release 二进制回退之间做选择,并在支持时优先使用带 `--json` 的 `ccap` CLI。

如果要发布到 ClawHub,应发布技能目录本身,而不是整个仓库根目录:

```bash
clawhub publish ./skills/ccap --slug ccap --name "ccap" --version 0.1.0 --tags latest --changelog "Initial ClawHub release"
```

### 安装

1. 从源码编译并安装 (在 Windows 下需要 git-bash 执行)
Expand Down
11 changes: 11 additions & 0 deletions cli/args_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ void printUsage(const char* programName) {
<< "Global options:\n"
<< " --verbose enable verbose logging (shows all messages)\n"
<< " -q, --quiet quiet mode (only show errors, equivalent to log level Error)\n"
<< " --json emit structured JSON output for supported commands\n"
<< " --schema-version version schema version for JSON output (default: 1.0)\n"
<< " --timeout seconds program timeout (auto-exit after N seconds)\n"
<< " --timeout-exit-code code exit code when timeout occurs (default: 0)\n"
<< "\n"
Expand Down Expand Up @@ -342,6 +344,15 @@ CLIOptions parseArgs(int argc, char* argv[]) {
opts.showVersion = true;
} else if (arg == "--verbose") {
opts.verbose = true;
} else if (arg == "--json") {
opts.jsonOutput = true;
} else if (arg == "--schema-version") {
if (i + 1 >= argc || argv[i + 1][0] == '-') {
std::cerr << "Error: --schema-version requires a value.\n\n";
printUsage(argv[0]);
std::exit(1);
}
opts.schemaVersion = argv[++i];
} else if (arg == "-l" || arg == "--list-devices") {
opts.listDevices = true;
} else if (arg == "-I" || arg == "--device-info") {
Expand Down
2 changes: 2 additions & 0 deletions cli/args_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ struct CLIOptions {
bool listDevices = false;
bool showDeviceInfo = false;
bool verbose = false;
bool jsonOutput = false;
std::string schemaVersion = "1.0";

// Windows camera backend override
std::string windowsCameraBackend;
Expand Down
11 changes: 7 additions & 4 deletions cli/ccap_cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,15 @@ int main(int argc, char* argv[]) {
return ccap_cli::convertYuvToImage(opts);
}

// Check if we should just print info (no action specified)
bool hasAction = opts.enablePreview || opts.saveFrames || opts.captureCountSpecified || !opts.outputDir.empty();

// Check if video file playback is requested but not supported on Linux
#if defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
if (!opts.videoFilePath.empty()) {
if (!hasAction) {
return ccap_cli::printVideoInfo(opts, opts.videoFilePath);
}
std::cerr << "Error: Video file playback is not supported on Linux.\n"
<< "\n"
<< "Video file playback is currently only available on:\n"
Expand All @@ -142,12 +148,9 @@ int main(int argc, char* argv[]) {
}
#endif

// Check if we should just print info (no action specified)
bool hasAction = opts.enablePreview || opts.saveFrames || opts.captureCountSpecified || !opts.outputDir.empty();

// If video file specified without action, print video info
if (!opts.videoFilePath.empty() && !hasAction) {
return ccap_cli::printVideoInfo(opts.videoFilePath);
return ccap_cli::printVideoInfo(opts, opts.videoFilePath);
Comment on lines 151 to +153
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Linux, the early videoFilePath check returns a plain-text error to stderr and exits before calling printVideoInfo. When --json is set, this breaks the new JSON CLI contract for video-info (and any video-file usage). Consider emitting a JSON error when opts.jsonOutput is true, or moving this platform gate into printVideoInfo so JSON output remains consistent.

Copilot uses AI. Check for mistakes.
}

// If camera device specified without action, print camera info
Expand Down
Loading
Loading