Skip to content

feat: add CLI subcommands for AI-agent access to .wpress archives#23

Merged
yani- merged 7 commits intomasterfrom
feat/cli-subcommands
Mar 28, 2026
Merged

feat: add CLI subcommands for AI-agent access to .wpress archives#23
yani- merged 7 commits intomasterfrom
feat/cli-subcommands

Conversation

@yani-
Copy link
Copy Markdown
Member

@yani- yani- commented Mar 28, 2026

Summary

  • Add 5 CLI subcommands (list, info, extract, cat, verify) with --json output and deterministic exit codes for AI-agent and headless use
  • Two-phase QCoreApplication/QApplication initialization so CLI commands work without a display server (headless servers, CI, Docker)
  • TRAKTOR_PASSWORD environment variable for secure password passing (no shell history exposure)
  • CrcDevice QIODevice subclass for streaming CRC verification without disk writes or memory bloat
  • Path normalization strips ./ prefix for reliable file matching across archive formats
  • v1 archives get structural validation; v2 archives get per-file CRC + whole-archive CRC
  • 22 new tests across 6 groups (74 total), 2 new test fixtures (v2+CRC, zlib-compressed)
  • Backward-compatible: existing --source/--destination/--password flags unchanged

Subcommands

Command Purpose --json output
traktor list <archive> List archive contents NDJSON per file
traktor info <archive> Archive metadata JSON object
traktor extract <archive> [dest] Full extraction JSON summary
traktor cat <archive> <path> Stream single file to stdout N/A (binary)
traktor verify <archive> CRC32 integrity check NDJSON per file

Exit Codes

Code Meaning
0 Success
1 General error
2 Invalid/corrupted archive
3 Wrong/missing password
4 CRC verification failure

Example Usage

# AI agent workflow
traktor list --json backup.wpress | jq '.path'
traktor cat backup.wpress wp-config.php | grep DB_PASSWORD
traktor verify --json backup.wpress && traktor extract backup.wpress ./output/

# Secure password passing
export TRAKTOR_PASSWORD="secret"
traktor list --json encrypted-backup.wpress

Test plan

  • All 74 tests pass (52 existing + 22 new)
  • clang-format clean
  • CI builds on Linux, macOS, Windows
  • Backward compat: --source/--destination flags still work
  • New fixtures (v2crc.wpress, compressed.wpress) generated correctly on all platforms

Add 5 subcommands (list, info, extract, cat, verify) with JSON output
and deterministic exit codes so AI agents can programmatically inspect
and extract .wpress archives. Read-only by design — no archive creation.

Subcommands:
- list: enumerate archive contents (tab-separated or NDJSON)
- info: archive metadata summary (key-value or JSON)
- extract: full extraction with progress on stderr
- cat: stream a single file to stdout (binary, pipe-friendly)
- verify: CRC32 integrity check (per-file for v2, structural for v1)

Features:
- Two-phase QCoreApplication/QApplication init for headless CLI support
- TRAKTOR_PASSWORD env var for secure password passing
- Path normalization (strip ./ prefix) for reliable file matching
- CrcDevice: streaming CRC computation without disk writes
- Backward-compatible: existing --source/--destination flags unchanged

New files: src/clihandler.h/cpp, tests/tst_cli.cpp
New fixtures: v2crc.wpress (v2 format with CRC), compressed.wpress
22 new tests across 6 test groups (74 total, all passing)
@github-actions github-actions bot added test Test suite changes parser Backup file parsing build Build system/project files labels Mar 28, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 28, 2026

Build Artifacts

Platform Download
Linux (x86_64) Traktor-linux-x86_64
macOS (Apple Silicon) Traktor-macOS
Windows (x64) Traktor-windows-x64

Built from a7292f0. Artifacts expire after 90 days.

yani- added 5 commits March 29, 2026 00:52
Extract QCommandLineOption variables before passing to addOption() to
avoid formatting ambiguity between local clang-format and CI v18.
Build QStringList separately before passing to QCommandLineOption
constructor to avoid formatting differences between local clang-format
and CI's clang-format v18.
P1: argv subcommand not stripped — QCommandLineParser saw the subcommand
name (e.g., "list") as the first positional argument, so every handler
tried to open a file named after the subcommand instead of the archive.
Fix: add positionalArgs() helper that strips the subcommand name.

P1: verify double-advanced file pointer — iterateHeaders() unconditionally
seeked past file content after the callback, but the verify callback
already consumed the content via processFileContentStreaming(). The
double-advance corrupted the archive position for subsequent headers.
Fix: iterateHeaders() now checks if the callback already consumed the
content before seeking, by comparing position before and after callback.

P2: getArchiveInfo() now propagates iterateHeaders() success/failure
via a scanComplete field instead of silently ignoring errors.
- Use normalizePath() consistently in extractSingleFile() instead of
  manual ./ stripping (was inconsistent with list and verify handlers)
- Surface processError details in verify's error status instead of
  silently discarding the decryption/decompression error message
- Include error field in verify JSON output when streaming fails
Three workstreams shipping as one coherent "agent-ready" feature:

Help system:
- Custom --help output listing all 7 subcommands with descriptions,
  global options, exit codes, and usage examples
- Intercepted before QApplication to prevent QCommandLineParser's
  auto-help from showing the old GUI-mode help
- argc == 1 (no args) still launches GUI, not help

MCP server (traktor mcp):
- JSON-RPC 2.0 over stdin/stdout per MCP spec 2025-11-25
- Synchronous blocking loop, no Qt event loop needed
- 5 tools: list, info, extract, cat, verify with typed inputSchema
- Calls BackupFile APIs directly (not CLI handler fprintf)
- cat returns file content as text via QBuffer (no size limit)
- verify uses CrcDevice for streaming CRC without disk writes

install-cli (traktor install-cli):
- Creates /usr/local/bin/traktor symlink on macOS
- Uses osascript with administrator privileges for auth dialog
- Pre-flight checks: correct symlink (skip), wrong symlink (overwrite),
  regular file (refuse with error)
- Auto-registers MCP server in ~/.claude.json for Claude Code discovery
- Handles invalid JSON in existing config (backup + create new)
- GUI menu item: Tools > Install Command Line Tool...
- Linux: prints manual symlink instructions
- Windows: notes PATH is set by installer

New files: src/mcpserver.h/cpp, src/installcli.h/cpp
7 new tests (81 total, all passing)
@github-actions github-actions bot added the ui User interface label Mar 28, 2026
@yani- yani- merged commit d013067 into master Mar 28, 2026
7 checks passed
@yani- yani- deleted the feat/cli-subcommands branch March 28, 2026 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Build system/project files parser Backup file parsing test Test suite changes ui User interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant