ModLens CLI manual

August 16, 2026 · View on GitHub

English | 中文

The skill drives this CLI through its launcher. This page is for running it directly.

Direct usage

With the skill installed you do not type commands: paste an image or drop a path, ask anything, and it fires on its own. By hand:

modlens -i screenshot.png                       # local image
modlens -i https://example.com/chart.png        # remote image
modlens -i chart.png --prompt "focus on axes"   # extra focus
modlens recover-paste                           # pull a pasted image into a file

Output is a fixed JSON shape:

{
  "image": "/path/to/screenshot.png",
  "provider": "gemini-api",
  "result": {
    "summary": "A workflow diagram with four nodes connected by labeled arrows.",
    "ocr": { "full_text": "/shaping\nBEFORE YOU BUILD\n...", "lines": [] },
    "layout": { "regions": [{ "reading_order": 1, "type": "title", "text": "/shaping" }] },
    "semantics": { "scene": "workflow diagram", "entities": [], "relations": [] },
    "visual": { "dominant_colors": ["white", "black"], "style": "flat", "notes": [] },
    "uncertainty": []
  },
  "meta": {
    "generatedAt": "2026-08-06T12:00:00.000Z",
    "model": "gemini-3.6-flash",
    "conversationId": null,
    "durationSeconds": 6.4,
    "usage": { "promptTokenCount": 1234, "candidatesTokenCount": 567 },
    "attempts": [{ "provider": "gemini-api", "ok": true, "durationSeconds": 6.4 }],
    "warnings": []
  }
}

meta records how the result was produced: when (generatedAt), which model (null when the provider ran one it never named, as kimi-cli does with kimi's own default), the provider's conversationId when it has one, wall-clock durationSeconds, and the raw usage the provider reported (shape varies by provider, null when none). attempts lists every provider the failover chain tried, in order, with failure reasons; warnings carries routing notices (failovers, ignored extraBody, whose quota an auto-mode read spent).

Flags

modlens analyze (the default command):

FlagMeaningDefault
-i, --input <path|url>Image to analyze (required)
-p, --provider <name>Pin exactly one provider, no fallbackthe failover chain (below)
-m, --model <name>Provider modelper provider (below)
-o, --output <path>Also write JSON to a file
--prompt <text>Extra focus
--timeout <ms>Provider timeout180000
--provider-bin <path>Provider binary pathagy / claude
--workdir <path>Working directory for the providera fresh isolated directory per run
--extra-body <json>JSON merged into the API request body, e.g. '{"thinking":{"type":"disabled"}}'the provider's extraBody from the config

--extra-body is how vendor-specific knobs get through, turning thinking off being the common one. It applies to the three API providers and replaces the configured extraBody for that run. Per-vendor spellings and the fields it refuses to touch are in Configuration.

The default -m model depends on the provider:

ProviderDefault model
antigravity-cli (default)gemini-3.6-flash-low
gemini-apigemini-3.6-flash
anthropicclaude-haiku-4-5-20251001
claude-clihaiku
kimi-cliwhatever kimi is configured with
openainone, -m is required

modlens recover-paste:

FlagMeaningDefault
--count <n>How many recent pasted images to recover1
--out-dir <path>Where to write recovered imagesa fresh private <tmpdir>/modlens-paste-* per run
--session <id>Session id for exact targetingauto-detect
--transcript <path>Explicit transcript .jsonl or .db (overrides --session)
--harness <name>Force storage scope: claude-code, pi, opencode, noneauto-detect
--cwd <path>Project directory the image was pasted incurrent directory

Six providers: antigravity-cli (no key), gemini-api (fastest free route), openai (any OpenAI-compatible multimodal endpoint), anthropic, claude-cli (uses your existing Claude subscription), and kimi-cli (uses your existing Kimi Code subscription, and runs only when named, never as a failover peer). Without -p, a run tries every provider that is set up, inline API providers first (5-10s), then the agents; the first good result wins and meta.attempts records the rest. Harnesses granted via reuse.<harness> contribute reused engines to the same regions (pi credentials inline, agent CLIs behind), with no priority over the user's own; details and the guards deny/allow lists are in Configuration.

Other subcommands:

  • modlens guard [--model <id>]: should the engine run for the active model at all? Exit 0 allow, 1 deny, verdict as JSON.
  • modlens config <init|set|show>: set with the value omitted on an apiKey field prompts for it with the echo hidden, so the key never enters argv, shell history, or the conversation with an agent driving the terminal. It also accepts one piped line (pbpaste | modlens config set openai.apiKey), which keeps the key out of argv, though whatever produced that pipe is still your own command to keep out of history. Keys are provider, proxy (HTTP/HTTPS proxy for the API providers, HTTPS_PROXY/HTTP_PROXY also honored), reuse.<claude|codex|opencode|pi|grok>, guards.<denyModels|allowModels|denyWhenUnknown>, and <provider>.<apiKey|baseUrl|model|proxy|extraBody>, plus openai.structuredOutput (that route only).
  • modlens doctor: Node and node:sqlite, provider readiness, the failover chains for this machine, the detected harness, the guard's rules with a live verdict, and the Reuse section with per-harness grant decisions and discovered vision. Spends no quota; --json for a machine-readable report.