@liustack/modlens 2.8.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +194 -0
- package/README.md +31 -72
- package/README.zh-CN.md +46 -87
- package/SECURITY.md +17 -0
- package/dist/main.js +801 -401
- package/docs/commit.md +76 -0
- package/docs/harness-setup.md +49 -0
- package/docs/research-gemini-claude-skills.md +48 -0
- package/docs/security.md +31 -0
- package/docs/testing.md +29 -0
- package/docs/troubleshooting.md +140 -0
- package/package.json +23 -12
- package/skills/modlens/SKILL.md +23 -8
- package/skills/modlens/references/cli.md +77 -0
- package/skills/modlens/references/configure.md +36 -0
- package/skills/modlens/references/runtime.md +95 -0
- package/skills/modlens/scripts/run.ps1 +250 -0
- package/skills/modlens/scripts/run.sh +283 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 3.1.0 - 2026-08-07
|
|
4
|
+
|
|
5
|
+
- Windows joins the CI matrix (Node 22 and 24), so the CLI core, config, `doctor`, harness detection, and OpenCode paste recovery run on a real Windows runner rather than being assumed. The POSIX-only cases (subprocess signal handling, permission-bit assertions, and the Claude Code and Pi JSONL home-layout fixtures) are guarded with `describe.skipIf`, and the OpenCode path normalization from #11 now runs end to end on Windows, not only as an injected-path unit test. A `.gitattributes` pins text files to LF so the Windows checkout matches the other platforms and Biome does not fail on line endings.
|
|
6
|
+
- Two guards that assumed POSIX permissions are fixed for Windows, where files report `0o666`/`0o777` and access is ACL-based. `recover-paste --out-dir` no longer rejects an existing private directory, and `doctor` no longer flags the config file's mode. Both checks now run only where `process.getuid` exists, and the symlink guard on `--out-dir` stays in force everywhere.
|
|
7
|
+
- The skill now launches the CLI through a bundled launcher (`skills/modlens/scripts/run.sh` for macOS/Linux, `run.ps1` for Windows) instead of a hard-coded `npx`, because a Claude Code native install has none of `node`, `npx`, `bun`, or `bunx` on PATH, so a fixed command failed for a whole class of users. Both launchers resolve the same way, forward every argument to the CLI unchanged, and share a `doctor --json` diagnosis: a compatible `modlens` already on PATH (same major version and not older than the pinned one), then the pinned-version `npx`, then `bunx --bun`, then a structured diagnosis on stderr with `nextSteps` and exit 78 when nothing can run. `doctor` is offline and chains the CLI's own provider/config doctor when a CLI is reachable. The native-artifact branch is a phase-B placeholder that reports none is published yet. The two scripts are POSIX sh and PowerShell 5.1, identical apart from their version constants and shell syntax, and a new `references/runtime.md` documents the pin, the compatibility rule, and the diagnostic fields.
|
|
8
|
+
- `SKILL.md` is rewritten to drive the launcher: the usage section runs `run.sh` / `run.ps1`, keeps a plain-language version of the same resolution order for harnesses that forbid running scripts, and drops the bare-`npx` fallback. Its frontmatter is brought in line with the Agent Skills spec: `allowed-tools` becomes the spec's space-separated string (`Bash`) instead of a YAML list, and a `compatibility` field states the runtime requirement.
|
|
9
|
+
- Release tooling stamps the pinned version so it cannot drift. A new `scripts/stamp.mjs` rewrites the version constant in `run.sh`, `run.ps1`, and `runtime.md` from `package.json`, `scripts/release.mjs` calls it on every bump, and `scripts/stamp.test.mjs` fails the build if the three copies ever disagree with `package.json`. The npm `files` list now ships `skills/modlens/scripts`.
|
|
10
|
+
- Root `INSTALL.md`, written for an AI agent installing the skill on a user's behalf, is rebuilt around the launcher and the machine as found. Four ordered, idempotent steps (find the harness's skill directory, copy `skills/modlens` in, give it one vision engine, verify), each with an "if it fails" branch and Windows notes. It installs into the user-global skill directory by default, probes before configuring (the README now has the user prepare an engine first, so an already-ready provider is the common case), prefers the Gemini key for headless reliability with Antigravity as the no-signup path, and verifies through the launcher, including the exit-78 no-runtime diagnosis.
|
|
11
|
+
- The README installation section (both languages) is reordered to match how the install actually flows: step 1 is the only human part, preparing an engine (get a free Gemini key, or install Antigravity and sign in), and step 2 hands one line to the user's AI, which follows `INSTALL.md` and reports back. The hero one-liner above the fold, three highlight bullets, and the how-it-works section are removed, keeping the highlights to evidence output, free start, and install-once-use-everywhere, and the docs table links `INSTALL.md`. The platform line is rewritten to state per-OS support honestly, and the harness and troubleshooting docs gain a Windows section.
|
|
12
|
+
|
|
13
|
+
A code-review pass. Two user-facing bugs, a stack of doc corrections, and the tooling a public repo is expected to carry.
|
|
14
|
+
|
|
15
|
+
- BREAKING: requires Node 22.13+. The floor was Node 18 with a special note that OpenCode paste recovery needed 22.13 for `node:sqlite`. That split is gone: 22.13 is the single minimum, `node:sqlite` is always available, and the CI matrix now runs Node 22 and 24 (dropping 18 and 20). The defensive runtime guard in the OpenCode adapter and the `describe.skipIf` in its tests stay, harmless, in case someone runs below the stated floor. README (both languages), CONTRIBUTING, AGENTS, and the harness doc drop the per-feature Node caveat.
|
|
16
|
+
- New `evals/` scaffolding makes "every experiment leaves a reproducible artifact" a format and a tool rather than a slogan. Seed cases (dense bilingual text, a dense chart, a clean diagram, a stylized banner, and a dependency-free generated prompt-injection image) live under `evals/cases/`, and `pnpm eval` drives the built CLI over them, writing one evidence artifact per case (command, tool version and commit, provider and model, input SHA-256, raw output, expected points and scoring, latency, usage, errors and degradation) to a git-ignored `evals/results/<date>/`. It reports transcription and schema pass rates and a latency summary, and `--dry-run` validates cases without spending quota. Local and on-demand by design: it spends real quota and never runs in CI.
|
|
17
|
+
- New `modlens doctor` command diagnoses local config and routing without spending a byte of provider quota or making a network request. It reports the Node version against the 22.13 floor, node:sqlite availability, each provider's readiness (agy/claude on PATH, and whether each API key comes from env or the config file, with a copy-paste fix for what is missing), which provider will be selected and from which layer (flag, config, or default), the detected harness and whether the verdict came from process ancestry or an environment fingerprint, and the config file's path and permission bits. Add `--json` for a machine-readable report. Troubleshooting now opens by pointing at it.
|
|
18
|
+
- OpenCode paste recovery works on Windows again (issue #11). Matching a session compared `path.resolve(cwd)`, which is backslash-separated on Windows, against opencode's forward-slash `session.directory`, so the equality and both prefix checks missed every row and recovery returned nothing. The v2.8.0 change that turned `--session` into a directory-narrowing filter meant the old `--session` workaround stopped helping too. Both sides are normalized to forward slashes before matching now, with the LIKE wildcard escaping preserved.
|
|
19
|
+
- A provider that ignores SIGTERM on timeout is now actually killed. The SIGKILL backstop checked `child.killed`, which turns true the moment a signal is delivered, not when the process exits, so a child that trapped SIGTERM read as already dead and was never escalated. It now tracks whether the process has exited and sends SIGKILL when it has not.
|
|
20
|
+
- The published npm package now includes `docs/`, `CHANGELOG.md`, and `SECURITY.md`. The README links to the harness, security, and troubleshooting docs, but the `files` allow-list left them out of the tarball, so those links 404'd for anyone reading the package on npm.
|
|
21
|
+
- CI now runs on macOS as well as Linux across the Node 18/20/22 matrix, so a macOS-only regression (path handling, `mkdtemp`, file modes) is caught before release.
|
|
22
|
+
- `vitest` moves to 3.2.7 to match `@vitest/coverage-v8`, silencing the version-mismatch warning `pnpm coverage` printed when the two drifted.
|
|
23
|
+
- The `node:sqlite` requirement for OpenCode paste recovery is stated correctly: Node **22.13+**, not 22.5. The module was added in 22.5 but behind `--experimental-sqlite`, and only became available without a flag in 22.13. Both READMEs, CONTRIBUTING, the harness and troubleshooting docs, the runtime error message, and the CI comment now agree.
|
|
24
|
+
- Publishing happens in exactly one place now. `scripts/release.mjs` and the tag-triggered `release.yml` workflow both ran `npm publish` and created the GitHub Release, a race that could double-publish or leave a half-finished release. `release.mjs` keeps every guard, the version bump, commit, tag, and push, but stops at the tag: pushing it hands off to CI, which publishes with provenance and cuts the GitHub Release from the matching CHANGELOG section.
|
|
25
|
+
- The subprocess providers (`antigravity-cli`, `claude-cli`) now run in a throwaway directory holding only the input image, not in the image's own directory. `agy` runs with `--dangerously-skip-permissions`, so an injection in an image sitting beside other files could in principle steer the agent into reading them. Each call now hardlinks (or copies) the one image into a fresh `mkdtemp` directory, runs there, and removes it afterward. An explicit `--workdir` keeps the old behaviour.
|
|
26
|
+
- Structural schema validation now runs for every provider, not just `openai`. The shape check that caught half-filled results lived inside the OpenAI-compatible path, so a malformed result from gemini, anthropic, agy, or claude-cli could slip through if the server-side schema was not honoured. The check moved into `schema.ts`, and the analyzer runs it over every provider's result, naming the provider when a field is missing.
|
|
27
|
+
- Remote image downloads are now capped at 25 MB and their type is confirmed from the file header rather than guessed. `fetchRemoteImageBase64` read the whole response into memory with no ceiling (a memory-exhaustion vector) and trusted a server's `content-type`, defaulting to `image/jpeg` for anything else. It now rejects an oversized `content-length` up front, enforces the cap while streaming, sniffs the magic bytes (png/jpeg/gif/webp) as the authority over a faked extension or lying header, and refuses a type outside the allow list instead of relabelling it. Local reads go through the same type check.
|
|
28
|
+
- `recover-paste` no longer writes to a fixed, shared `<tmpdir>/modlens-paste` by default. A `recursive` mkdir does not re-apply its mode to a directory that already exists, so on a shared machine another user could pre-create that path and read every screenshot recovered into it. Each run now mints a private `mkdtemp` directory instead. An explicit `--out-dir` is still honoured, but an existing one is rejected unless it is a real directory (not a symlink), owned by the current user, with no group or world access. Recovered files are deliberately left in place for `modlens -i` to read.
|
|
29
|
+
|
|
30
|
+
- `config show` prints the effective config now, merging environment variables over the file and tagging each value file or env. Reading only the file hid keys set through `GEMINI_API_KEY` and the other bound vars, so the value modlens actually used never appeared.
|
|
31
|
+
- Local image paths containing `#` or `?` keep their real extension. Routing them through `new URL()` read the character as a fragment or query and dropped the extension, mislabelling the type as JPEG.
|
|
32
|
+
- The disclaimer no longer contradicts the MIT license it ships beside. It withholds warranty and endorsement without withholding the commercial-use right MIT grants, and points at the upstream engines' own terms.
|
|
33
|
+
- Docs caught up with the code. Both READMEs gained `--provider-bin`, `--workdir`, a per-provider default-model table, a full `recover-paste` flag table, and the `meta` output fields, with `MODLENS_HARNESS` and `--out-dir` written up in troubleshooting. The anthropic recipe warns that `ANTHROPIC_BASE_URL` can silently reroute a vision request to a text-only gateway. AGENTS.md drops three claims that had gone stale.
|
|
34
|
+
- Internals, all behavior-preserving: the duplicated JSON helpers (parse, extract, truncate) collapsed into one `util/json` module, and the 710-line `recoverPaste` split into per-harness modules. An always-true branch and a few lint findings cleared.
|
|
35
|
+
- Tooling: Biome for formatting and linting on the repo's 4-space style, a Node 18/20/22 CI matrix that skips the `node:sqlite` tests where the module is unavailable, `@vitest/coverage-v8` with a `coverage` script, tests for the CLI assembly, and a tag-triggered release workflow that publishes with provenance. Adds the collaboration files a public repo expects: CONTRIBUTING, SECURITY, CODE_OF_CONDUCT, issue and pull-request templates, and Dependabot.
|
|
36
|
+
- The Chinese README's plug now invites readers to the WeChat public account rather than installing the liustack skills.
|
|
37
|
+
- `release.mjs` matches the CHANGELOG again: version dots are escaped literally and the section ends at end of file, so the newest entry (and versions like `2.8.0`) match instead of being missed.
|
|
38
|
+
|
|
39
|
+
## 2.8.0 - 2026-08-06
|
|
40
|
+
|
|
41
|
+
- README rebuilt against how widely used projects actually write theirs: install command inside the first screen, a nav row and badges in the hero, short scannable highlights, and roughly 1,000 words instead of a long read. Harness specifics and security detail moved into `docs/harness-setup.md` and `docs/security.md`, with a Documentation table pointing at them.
|
|
42
|
+
|
|
43
|
+
## 2.7.11 - 2026-08-06
|
|
44
|
+
|
|
45
|
+
- Stops calling it OCR. A vision model reading an image is not OCR, which is a specific and different technology, and the word was borrowed for convenience across the README, the skill, and both articles. The prose now says what actually happens: every word in the image is transcribed. The `ocr` field in the output contract keeps its familiar name, with a note that a vision model does the reading.
|
|
46
|
+
|
|
47
|
+
## 2.7.10 - 2026-08-06
|
|
48
|
+
|
|
49
|
+
- README rewritten rather than patched again. The hero buried the one thing that sets this apart (you can paste) under a generic pitch, then repeated it in a feature list and again in its own section. The opening now leads with pasting, the feature list is gone as duplication, and the comparison against swapping models or running a vision MCP server sits where a reader weighing options will find it.
|
|
50
|
+
|
|
51
|
+
## 2.7.9 - 2026-08-06
|
|
52
|
+
|
|
53
|
+
- The flow diagram says something again. Replacing ASCII art with an abstract illustration removed the labels along with the alignment chore, which was a bad trade. It is now a rendered diagram with real labels, one per language, generated from HTML so nothing drifts.
|
|
54
|
+
|
|
55
|
+
## 2.7.8 - 2026-08-06
|
|
56
|
+
|
|
57
|
+
- Releases are now one command: `pnpm release <version|patch|minor|major>` refuses a dirty tree, a non-main branch, a duplicate tag, or a version with no CHANGELOG entry, then runs typecheck, tests, and build before anything irreversible happens, and finishes with tag, push, npm publish, and a GitHub release. Publishing by hand is how a version once reached npm with no changelog and no tag behind it.
|
|
58
|
+
- Every previously published version now has a git tag, reconstructed from the commit that carried it.
|
|
59
|
+
|
|
60
|
+
## 2.7.7 - 2026-08-05
|
|
61
|
+
|
|
62
|
+
- README: leads with a scannable feature block (paste support, evidence rather than a description, honest uncertainty, no model swap, zero-key start, four harnesses) and states requirements. Adds a comparison against swapping in a multimodal model and against vision MCP servers, our own weaknesses included.
|
|
63
|
+
- New `docs/troubleshooting.md`: every error this CLI prints, with cause and fix, linked from the README and the skill.
|
|
64
|
+
- The ASCII flow diagram is now a real illustration. Its alignment had needed repair across several releases, which is a poor trade for a picture.
|
|
65
|
+
- The Gemini CLI era research doc is marked historical so it is not read as current design.
|
|
66
|
+
|
|
67
|
+
## 2.7.6 - 2026-08-05
|
|
68
|
+
|
|
69
|
+
- `config init` now writes only the shape (`{"provider": "", "providers": {}}`) instead of all five providers with their fields pre-filled. Baked-in defaults in a config file silently outrank later changes to those defaults, and the placeholders hid the one decision that matters. The command prints what can be set instead.
|
|
70
|
+
|
|
71
|
+
## 2.7.5 - 2026-08-05
|
|
72
|
+
|
|
73
|
+
A verification pass on the 2.7.4 fixes (same external reviewer) found four that did not hold and three bugs the fixes themselves introduced. All seven are addressed here.
|
|
74
|
+
|
|
75
|
+
**Fixes that did not hold**
|
|
76
|
+
|
|
77
|
+
- Unreadable config files still became empty configs: the 2.7.4 edit never applied, because this file is indented differently from its sibling project. Permissions errors now surface.
|
|
78
|
+
- Harness detection still matched a flag's value: `node --require pi app.js` read as Pi. The script behind a node shim must now look like a path to a script.
|
|
79
|
+
- agy log evidence was scoped by file mtime alone, so a concurrent call or an older failure in the same file still misdiagnosed this run. Lines are now filtered by their own glog timestamps.
|
|
80
|
+
- The openai schema check only looked at top-level keys, so `{"ocr":{}}` passed. Nested required fields are checked.
|
|
81
|
+
|
|
82
|
+
**Bugs introduced by the 2.7.4 fixes**
|
|
83
|
+
|
|
84
|
+
- `transcriptBelongsTo` returned on the first recorded cwd, so a transcript whose first line matched could still hand over another project's images. Any matching line now decides, and a transcript with cwd lines that all mismatch is rejected.
|
|
85
|
+
- That check also read every transcript in full, then the image scan read it again. Each file is read once.
|
|
86
|
+
- The alias table added for config lookups was written by hand and did not match the real provider aliases (`claude` resolves to `anthropic`, not `claude-cli`, and `claude-code` and `openai-compat` were missing), so settings landed on the wrong provider. The table now comes from the provider registry.
|
|
87
|
+
- `--transcript` skipped harness validation, so `--harness bogus` silently parsed the file as Claude Code.
|
|
88
|
+
|
|
89
|
+
## 2.7.4 - 2026-08-05
|
|
90
|
+
|
|
91
|
+
Correctness and privacy pass after an external review (gpt-5.6-sol) that proved every finding with a probe.
|
|
92
|
+
|
|
93
|
+
**Recovering the wrong project's images**
|
|
94
|
+
|
|
95
|
+
- OpenCode directory matching passed the project path straight into SQL `LIKE`, where `_` and `%` are wildcards, so a path containing either matched other projects. Patterns are escaped now.
|
|
96
|
+
- `--session <id>` dropped the directory condition entirely, and session slugs are not unique across projects. The reviewer found two colliding slugs in a real local database. A session now narrows the directory match instead of replacing it.
|
|
97
|
+
- Claude Code and Pi directory slugs are lossy: `/tmp/project.alpha` and `/tmp/project-alpha` produce the same slug. Both harnesses record the real cwd inside the transcript, which is now checked before a transcript is trusted.
|
|
98
|
+
|
|
99
|
+
**Privacy**
|
|
100
|
+
|
|
101
|
+
- Recovered images landed as 0644 inside a 0755 directory, so on a shared `/tmp` any local user could read them. They are written 0600 into a 0700 directory, and re-chmodded because the filenames are content hashes and an existing file keeps its old mode.
|
|
102
|
+
|
|
103
|
+
**Correctness**
|
|
104
|
+
|
|
105
|
+
- A successful run could be reported as a timeout: the timer stayed armed while output drained, so a slow drain turned exit code 0 into a timeout error. It is cleared when the child exits.
|
|
106
|
+
- A timeout sent one SIGTERM and then waited, so an engine ignoring signals hung the CLI. It now settles immediately and escalates to SIGKILL.
|
|
107
|
+
- Output decoding kept no state across chunks, so a multi-byte character split across a chunk boundary became replacement characters.
|
|
108
|
+
- The OpenCode "needs Node 22.5" message was swallowed by an empty catch, leaving only "no pasted images". Setup problems now travel with the error.
|
|
109
|
+
- `--harness` was ignored when `--transcript` was given, so a copied Pi transcript was parsed as Claude Code. `--transcript <db>` also ignored `--cwd`.
|
|
110
|
+
- Harness detection scanned the first eight command tokens, so a command that merely mentioned "pi" in its arguments was detected as Pi. Only the executable, plus the script path behind a node shim, is read now.
|
|
111
|
+
- agy log evidence was accepted if the file was under two minutes old, which let a previous quota failure or a concurrent agy call misdiagnose an unrelated error. Evidence must now postdate the start of this run.
|
|
112
|
+
- The `claude-cli` provider inherited a 30 second kill grace meant for agy's own `--print-timeout`, silently extending `--timeout`. The grace applies only to engines with an internal deadline.
|
|
113
|
+
- The openai provider's "schema validation" accepted `{"summary":"x","ocr":null}` and anything missing layout, semantics, visual, or uncertainty. All required fields are checked.
|
|
114
|
+
- Settings saved under a provider alias (`config set gemini.apiKey`) were invisible once the name resolved to `gemini-api`.
|
|
115
|
+
- An unmapped image type was relabelled `.png`, so downstream tools reading the extension got the wrong type.
|
|
116
|
+
- `ENOENT` from spawn was always reported as a missing CLI, even when the real cause was a missing working directory.
|
|
117
|
+
- A config file that exists but cannot be read (permissions) silently became an empty config.
|
|
118
|
+
|
|
119
|
+
## 2.7.3 - 2026-08-05
|
|
120
|
+
|
|
121
|
+
- Fix: a failing `antigravity-cli` run now explains itself instead of reporting a bare exit code ([#3](https://github.com/liustack/modlens/issues/3), thanks @mtongle). Providers gained a `describeFailure` hook, and the agy provider uses it to surface agy's own error text and classify the two failures users actually hit: a locked OS keyring in headless sessions (the report's case, where agy claims to be signed out) and an exhausted weekly quota. Both messages end with the exact commands to switch to a keyless, quota-independent provider. Diagnosis only reads agy's log when this run produced an agy error envelope and the log is fresh, so stale logs cannot misdiagnose an unrelated failure.
|
|
122
|
+
- Docs: README leads with paste support, recommends the free AI Studio key over the slower agy default, and documents that the skill configures modlens for you on request.
|
|
123
|
+
|
|
124
|
+
## 2.7.2 - 2026-08-05
|
|
125
|
+
|
|
126
|
+
- Fix: runs with the `antigravity-cli` provider hung until the timeout killed them ([#1](https://github.com/liustack/modlens/issues/1), thanks @hawkmor for the diagnosis). agy exits cleanly but leaves a language server holding the inherited stdout pipe, so the child's `close` event never fires. The provider run now settles on `exit` plus a short drain window, and releases the pipes afterwards so a lingering descendant cannot keep the CLI process alive either.
|
|
127
|
+
|
|
128
|
+
## 2.7.1 - 2026-08-04
|
|
129
|
+
|
|
130
|
+
- Docs: per-harness skill discovery paths (`~/.claude/skills/`, `~/.codex/skills/`, `~/.agents/skills/` for Pi and OpenCode), OpenCode + DeepSeek setup recipe, and the four-harness live verification matrix (Claude Code session-id recovery, OpenCode full skill loop on DeepSeek, Pi store isolation, Codex refusal).
|
|
131
|
+
|
|
132
|
+
## 2.7.0 - 2026-08-04
|
|
133
|
+
|
|
134
|
+
- `recover-paste` now identifies the harness it is running inside before touching any storage: process ancestry first (the nearest known harness among parent processes, which also resolves nested setups to the innermost tool), env fingerprints second (`CLAUDECODE`, `PI_CODING_AGENT`, `CODEX_THREAD_ID`). Detection scopes recovery to that harness's store only, so another tool's stale sessions can never hijack a paste; Codex is refused outright with path-tag guidance. `--harness <name|none>` overrides, output gains a `detected` field.
|
|
135
|
+
- In Claude Code, recovery auto-targets the exact session from the injected `CLAUDE_CODE_SESSION_ID`, falling back to newest-image scanning when that transcript holds no images (subagent sessions).
|
|
136
|
+
|
|
137
|
+
## 2.6.1 - 2026-08-03
|
|
138
|
+
|
|
139
|
+
- Fix: opencode runs shell commands at the repo root while sessions record the directory they were launched in. Exact directory matching made recovery miss the real paste and fall through to stale Claude Code transcripts of the same project, recovering the wrong images (caught in a live session). Directories now match by prefix in both directions, and recovery is scoped to the single opencode session owning the newest image.
|
|
140
|
+
- Recovered entries report `filename` (the original attachment name) when the harness stored one.
|
|
141
|
+
- Skill: recovered paths are oldest to newest so analyze the last one first, match `filename` when present, run every command yourself instead of delegating to the user, and treat a `harness` value that differs from the harness you are running in as suspect.
|
|
142
|
+
|
|
143
|
+
## 2.6.0 - 2026-08-03
|
|
144
|
+
|
|
145
|
+
- `recover-paste` now supports OpenCode: pasted/attached images are read from its SQLite store (`~/.local/share/opencode/opencode.db`) via node:sqlite (Node 22.5+, lazy-loaded so older Nodes keep the JSONL harnesses). Recovery internals refactored into per-harness adapters (Claude Code, Pi, OpenCode) sharing one newest-image picker. Verified against a real opencode + deepseek session.
|
|
146
|
+
|
|
147
|
+
## 2.5.0 - 2026-08-03
|
|
148
|
+
|
|
149
|
+
- `recover-paste` now supports Pi (Armin Ronacher's coding agent) alongside Claude Code: both store pasted images as base64 in per-session JSONL files, and recovery auto-detects which harness owns the newest pasted image. Verified live against a real pi + deepseek session. Result JSON gains a `harness` field.
|
|
150
|
+
|
|
151
|
+
## 2.4.3 - 2026-08-03
|
|
152
|
+
|
|
153
|
+
- Docs: the Claude Code paste-recovery loop is now marked as verified end to end in a real DeepSeek-gateway session (placeholder spotted, file recovered by session id, image answered in full).
|
|
154
|
+
|
|
155
|
+
## 2.4.2 - 2026-08-03
|
|
156
|
+
|
|
157
|
+
- Project hygiene: CHANGELOG, GitHub Actions CI, AGENTS.md rewrite, testing guide rewrite, recover-paste and config command reference in READMEs, dead code removal, auto-externalized Node built-ins in the build.
|
|
158
|
+
|
|
159
|
+
## 2.4.1 - 2026-08-03
|
|
160
|
+
|
|
161
|
+
- Skill: path-finding is now a per-harness decision tree. Codex path tags never trigger transcript recovery, unknown harnesses are told to ask for a path instead of guessing.
|
|
162
|
+
|
|
163
|
+
## 2.4.0 - 2026-08-03
|
|
164
|
+
|
|
165
|
+
- `recover-paste --session <id>`: exact transcript targeting. Skills relay `${CLAUDE_SESSION_ID}` (substituted by Claude Code since v2.1.9); without it, recovery falls back to newest-image-timestamp scanning.
|
|
166
|
+
|
|
167
|
+
## 2.3.2 - 2026-08-03
|
|
168
|
+
|
|
169
|
+
- Tests co-located with sources, one module one `.test.ts` (31 to 50 tests). First direct coverage for `prompt` and `imageInput`.
|
|
170
|
+
- Skill explains why `recover-paste` takes no session id.
|
|
171
|
+
|
|
172
|
+
## 2.3.1 - 2026-08-03
|
|
173
|
+
|
|
174
|
+
- `recover-paste` locates the session by newest pasted-image timestamp instead of file mtime, immune to concurrent sessions in the same project.
|
|
175
|
+
|
|
176
|
+
## 2.3.0 - 2026-08-03
|
|
177
|
+
|
|
178
|
+
- New `recover-paste` command: recovers images pasted into Claude Code from the local session transcript (they never hit a regular temp file), prints real file paths as JSON.
|
|
179
|
+
|
|
180
|
+
## 2.2.0 - 2026-08-03
|
|
181
|
+
|
|
182
|
+
- New `claude-cli` provider: rides an existing Claude Code login, `--allowedTools Read` only, `--json-schema` enforced, haiku default.
|
|
183
|
+
- Skill routes configuration questions to `references/configure.md`.
|
|
184
|
+
|
|
185
|
+
## 2.1.0 - 2026-08-02
|
|
186
|
+
|
|
187
|
+
- Three direct-API providers: `gemini-api` (free AI Studio key, `responseJsonSchema`), `openai` (any OpenAI-compatible multimodal endpoint), `anthropic` (forced tool call, Claude Haiku default). 3-10s per image versus 15-40s agent loops.
|
|
188
|
+
- Layered config: `~/.modlens/config.json` via `config init/set/show` (0600, masked), env vars override the file, flags override everything.
|
|
189
|
+
|
|
190
|
+
## 2.0.0 - 2026-08-01
|
|
191
|
+
|
|
192
|
+
- Breaking: vision engine migrated from the discontinued Gemini CLI free tier to Antigravity CLI (`agy`).
|
|
193
|
+
- Provider layer (`buildInvocation` + `parseOutput`), schema-enforced structured output via `--json-schema`, no markdown scraping.
|
|
194
|
+
- Output contract v2: `result`/`meta` envelope; fabricated bbox and confidence fields dropped.
|
package/README.md
CHANGED
|
@@ -17,113 +17,65 @@
|
|
|
17
17
|
|
|
18
18
|
<p align="center">
|
|
19
19
|
<a href="https://www.npmjs.com/package/@liustack/modlens"><img src="https://img.shields.io/npm/v/@liustack/modlens?style=flat-square&label=npm&color=cb3837" alt="npm"></a>
|
|
20
|
-
<a href="https://github.com/liustack/modlens/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/liustack/modlens/ci.yml?branch=main&style=flat-square&label=ci" alt="CI"></a>
|
|
21
20
|
<a href="https://nodejs.org"><img src="https://img.shields.io/node/v/@liustack/modlens?style=flat-square" alt="Node.js"></a>
|
|
22
21
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License"></a>
|
|
23
22
|
</p>
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
npx -y skills add liustack/modlens # install the skill
|
|
27
|
-
npx @liustack/modlens -i screenshot.png # or just use the CLI
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Models like DeepSeek-V4-Flash are cheap, fast, capable, and blind. Throw one a screenshot of an error and it sees nothing. ModLens turns the image into evidence it can quote, and **you just paste**: every other bridge makes you save a file and report its path, while ModLens pulls the pasted image back out of session storage.
|
|
24
|
+
DeepSeek-V4-Flash has no vision capability and cannot process screenshots or images. ModLens is a plug-in vision engine that gives a text-only model sight. **ModLens reads images pasted straight into the chat**, no saving to a file and passing a path first.
|
|
31
25
|
|
|
32
26
|
## Highlights
|
|
33
27
|
|
|
34
|
-
- **
|
|
35
|
-
- **Evidence, not an impression.**
|
|
36
|
-
- **
|
|
37
|
-
- **Keep your model.** You picked it for price and reasoning, not eyesight. That choice stays.
|
|
38
|
-
- **Starts with no key.** agy needs none. A free Gemini key makes it 5 to 10 seconds per image.
|
|
39
|
-
- **Install once, works everywhere.** Verified on real machines in Claude Code, Codex, Pi, and OpenCode.
|
|
28
|
+
- **Completely free.** The default channel is Antigravity CLI, no API key needed. A free Gemini key brings a read down to 5-10 seconds.
|
|
29
|
+
- **Evidence, not an impression.** Full transcription, reading-order layout regions, entity and relation lists. The model quotes specifics.
|
|
30
|
+
- **Install once, use everywhere.** Verified on real machines in Claude Code, Codex, Pi, and OpenCode.
|
|
40
31
|
|
|
41
32
|
## Installation
|
|
42
33
|
|
|
43
|
-
|
|
44
|
-
npx -y skills add liustack/modlens
|
|
45
|
-
```
|
|
34
|
+
**Step 1, set up a vision engine (the only part that needs your hands).** The recommended choice is a free Gemini API key: get one at [Google AI Studio](https://aistudio.google.com), about three minutes, no credit card.
|
|
46
35
|
|
|
47
|
-
|
|
36
|
+
A free API key in the OpenAI-compatible format from another platform is also a good option.
|
|
48
37
|
|
|
49
|
-
|
|
38
|
+
To avoid any sign-up, install Antigravity CLI instead, then sign in:
|
|
50
39
|
|
|
51
40
|
```bash
|
|
52
|
-
|
|
53
|
-
|
|
41
|
+
curl -fsSL https://antigravity.google/cli/install.sh | bash
|
|
42
|
+
agy # sign in, then exit
|
|
54
43
|
```
|
|
55
44
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
curl -fsSL https://antigravity.google/cli/install.sh | bash && agy # sign in, then exit
|
|
60
|
-
```
|
|
45
|
+
**Step 2, hand the rest to your AI.** Send it this line, along with the key if you chose the Gemini API key:
|
|
61
46
|
|
|
62
|
-
|
|
47
|
+
> Install and configure the modlens skill following https://github.com/liustack/modlens/blob/main/INSTALL.md, then run the health check and tell me the result.
|
|
63
48
|
|
|
64
49
|
## Usage
|
|
65
50
|
|
|
66
|
-
|
|
51
|
+
Once installed, just chat. Paste an image or drop a path, ask anything, and the skill triggers on its own: the image goes to a vision engine and the answer comes back grounded in what it read.
|
|
67
52
|
|
|
68
|
-
|
|
69
|
-
modlens -i screenshot.png # local image
|
|
70
|
-
modlens -i https://example.com/chart.png # remote image
|
|
71
|
-
modlens -i chart.png --prompt "focus on axes" # extra focus
|
|
72
|
-
modlens recover-paste # pull a pasted image into a file
|
|
73
|
-
```
|
|
53
|
+
## See it work
|
|
74
54
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
```json
|
|
78
|
-
{
|
|
79
|
-
"image": "/path/to/screenshot.png",
|
|
80
|
-
"provider": "gemini-api",
|
|
81
|
-
"result": {
|
|
82
|
-
"summary": "A workflow diagram with four nodes connected by labeled arrows.",
|
|
83
|
-
"ocr": { "full_text": "/shaping\nBEFORE YOU BUILD\n...", "lines": [] },
|
|
84
|
-
"layout": { "regions": [{ "reading_order": 1, "type": "title", "text": "/shaping" }] },
|
|
85
|
-
"uncertainty": []
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
```
|
|
55
|
+
Unedited runs, all driving a text-only DeepSeek-V4-Flash.
|
|
89
56
|
|
|
90
|
-
|
|
57
|
+
A tweet screenshot in the Codex desktop app. It reads the caption, the engagement numbers (2.9K replies, 270K likes, 5M views), even the image's alt text. Where the resolution runs out, it says so instead of guessing.
|
|
91
58
|
|
|
92
59
|

|
|
93
60
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-

|
|
61
|
+
Three images pasted at once. The model queues them up and reads them one by one, design intent included.
|
|
97
62
|
|
|
98
|
-
|
|
63
|
+

|
|
99
64
|
|
|
100
|
-
|
|
101
|
-
| :-- | :-- | :-- | :-- |
|
|
102
|
-
| Your chosen model | has to change | stays | stays |
|
|
103
|
-
| An image pasted into the chat | visible if the model supports it | out of reach | handled directly |
|
|
104
|
-
| What you get back | the model's own reading | usually a description | transcription, layout regions, entities |
|
|
105
|
-
| Where it cannot read | may invent | may invent | says so in `uncertainty` |
|
|
106
|
-
| Cost | multimodal model pricing | usually per API call | agy's free quota or a free Gemini key |
|
|
65
|
+
The stress test: a scatter plot of 128 models. It identifies the chart, both axes, the log scale, and picks the one highlighted point out of the crowd with its coordinates (about $0.028, intelligence score 50). Dense charts are where vision models most often fail.
|
|
107
66
|
|
|
108
|
-
The
|
|
67
|
+

|
|
109
68
|
|
|
110
|
-
|
|
69
|
+
And the paste path, end to end: Claude Code on a DeepSeek gateway, two images pasted straight into the chat. The UI shows nothing but placeholders, the skill recovers both from session storage and reads them, down to the color values on a slide cover.
|
|
111
70
|
|
|
112
|
-
|
|
113
|
-
| :-- | :-- | :-- |
|
|
114
|
-
| `-i, --input <path\|url>` | Image to analyze (required) | |
|
|
115
|
-
| `-p, --provider <name>` | Vision provider | `antigravity-cli` |
|
|
116
|
-
| `-m, --model <name>` | Provider model | `gemini-3.6-flash-low` |
|
|
117
|
-
| `-o, --output <path>` | Also write JSON to a file | |
|
|
118
|
-
| `--prompt <text>` | Extra focus | |
|
|
119
|
-
| `--timeout <ms>` | Provider timeout | `180000` |
|
|
120
|
-
|
|
121
|
-
Five providers: `antigravity-cli` (default, no key), `gemini-api` (fastest free route), `openai` (any OpenAI-compatible multimodal endpoint), `anthropic`, and `claude-cli` (rides your Claude subscription). Two more subcommands: `modlens config <init|set|show>` and `modlens recover-paste`.
|
|
71
|
+

|
|
122
72
|
|
|
123
73
|
## Documentation
|
|
124
74
|
|
|
125
75
|
| Doc | Read it when |
|
|
126
76
|
| :-- | :-- |
|
|
77
|
+
| [INSTALL.md](INSTALL.md) | Installing the skill step by step (written for an agent) |
|
|
78
|
+
| [CLI manual](skills/modlens/references/cli.md) | The CLI the skill drives: flags, config, doctor |
|
|
127
79
|
| [Troubleshooting](docs/troubleshooting.md) | A command failed and the message needs decoding |
|
|
128
80
|
| [Configuration](skills/modlens/references/configure.md) | Setting a key, switching providers, fixing config |
|
|
129
81
|
| [Output contract](skills/modlens/references/output-schema.md) | Parsing the JSON or building on it |
|
|
@@ -132,6 +84,13 @@ Five providers: `antigravity-cli` (default, no key), `gemini-api` (fastest free
|
|
|
132
84
|
| [CHANGELOG](CHANGELOG.md) | Finding what changed in a version |
|
|
133
85
|
| [AGENTS.md](AGENTS.md) | Working on this codebase |
|
|
134
86
|
|
|
87
|
+
## Contributing
|
|
88
|
+
|
|
89
|
+
ModLens does not accept pull requests. The project is maintained by a single author who reviews every line, which is a deliberate choice for reliability. Two effective ways to contribute:
|
|
90
|
+
|
|
91
|
+
- **[Open an issue](https://github.com/liustack/modlens/issues).** Bugs, suggestions, confusing errors, unclear docs. Issues are read and shape what gets built next.
|
|
92
|
+
- **Fork it.** Under MIT your copy is fully yours to modify and publish.
|
|
93
|
+
|
|
135
94
|
## Shameless plug
|
|
136
95
|
|
|
137
96
|
This project runs on LIUSTACK Skills: `shaping` before you build, `coding` while you build, `dig` when it breaks, `snapshot` when you hand off. Lighter than Superpowers, and stronger.
|
|
@@ -144,7 +103,7 @@ npx -y skills add liustack/liustack -g
|
|
|
144
103
|
|
|
145
104
|
## Disclaimer
|
|
146
105
|
|
|
147
|
-
|
|
106
|
+
Provided as-is under the MIT License below. The author makes no warranty and gives no endorsement for any particular use, commercial use included. Your use of upstream engines (Antigravity CLI, the Gemini, OpenAI, and Anthropic APIs, and any OpenAI-compatible endpoint) is governed by their own terms and quotas, which you are responsible for.
|
|
148
107
|
|
|
149
108
|
## License
|
|
150
109
|
|
package/README.zh-CN.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<h1 align="center">ModLens</h1>
|
|
6
6
|
|
|
7
|
-
<p align="center"><b
|
|
7
|
+
<p align="center"><b>为纯文本模型补上视觉能力,直接粘贴图片就能识别。</b></p>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
10
|
<a href="./README.md">English</a> ·
|
|
@@ -17,134 +17,93 @@
|
|
|
17
17
|
|
|
18
18
|
<p align="center">
|
|
19
19
|
<a href="https://www.npmjs.com/package/@liustack/modlens"><img src="https://img.shields.io/npm/v/@liustack/modlens?style=flat-square&label=npm&color=cb3837" alt="npm"></a>
|
|
20
|
-
<a href="https://github.com/liustack/modlens/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/liustack/modlens/ci.yml?branch=main&style=flat-square&label=ci" alt="CI"></a>
|
|
21
20
|
<a href="https://nodejs.org"><img src="https://img.shields.io/node/v/@liustack/modlens?style=flat-square" alt="Node.js"></a>
|
|
22
21
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License"></a>
|
|
23
22
|
</p>
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
npx -y skills add liustack/modlens # 装 skill
|
|
27
|
-
npx @liustack/modlens -i screenshot.png # 或者直接当 CLI 用
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
DeepSeek-V4-Flash 这类模型便宜、快、能打,唯独看不见图。你甩过去一张报错截图,它一片漆黑。ModLens 把图读成能引用的证据交给它,而且**你直接粘贴就行**:别的方案都要你先存成文件再报路径,ModLens 从会话存储里把粘贴的图捞回来。
|
|
24
|
+
DeepSeek-V4-Flash 没有视觉能力,无法处理截图和图片。ModLens 借助外挂视觉引擎,为纯文本模型补上视觉能力。**ModLens 支持直接粘贴图片识别**,无需先保存成文件再提供路径。
|
|
31
25
|
|
|
32
26
|
## 亮点
|
|
33
27
|
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
- **模型不用换。** 你选 DeepSeek 图的是价格和推理,不是视力,这个选择不用动。
|
|
38
|
-
- **零 key 起步。** agy 不要 key;想快就领个免费 Gemini key,识图 5 到 10 秒。
|
|
39
|
-
- **一次装好,处处能用。** Claude Code、Codex、Pi、OpenCode 都在真机上验证过。
|
|
28
|
+
- **完全免费。** 默认走 Antigravity CLI 通道,无需 api key。配一个免费的 Gemini key 可将识别耗时降至 5 到 10 秒。
|
|
29
|
+
- **返回证据,而非印象。** 全文转录、按阅读顺序划分的版面区块、实体与关系列表,模型引用的是具体内容。
|
|
30
|
+
- **一次安装,多端可用。** Claude Code、Codex、Pi、OpenCode 均经真机验证。
|
|
40
31
|
|
|
41
32
|
## 安装
|
|
42
33
|
|
|
43
|
-
|
|
44
|
-
npx -y skills add liustack/modlens
|
|
45
|
-
```
|
|
34
|
+
**第一步,准备一个视觉引擎(唯一需要你亲手做的)。** 推荐免费的 Gemini api key:到 [Google AI Studio](https://aistudio.google.com) 领取,约三分钟,无需信用卡。
|
|
46
35
|
|
|
47
|
-
|
|
36
|
+
也推荐申请其他平台免费的 openai api 兼容格式的 api key。
|
|
48
37
|
|
|
49
|
-
|
|
38
|
+
想完全免注册就改装 Antigravity CLI,然后完成登录:
|
|
50
39
|
|
|
51
40
|
```bash
|
|
52
|
-
|
|
53
|
-
|
|
41
|
+
curl -fsSL https://antigravity.google/cli/install.sh | bash
|
|
42
|
+
agy # 浏览器完成登录后退出
|
|
54
43
|
```
|
|
55
44
|
|
|
56
|
-
|
|
45
|
+
**第二步,剩下的交给你的 AI。** 把这句话发给它,用 Gemini api key 的话把 key 一起发:
|
|
57
46
|
|
|
58
|
-
|
|
59
|
-
curl -fsSL https://antigravity.google/cli/install.sh | bash && agy # 浏览器登录后退出
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
需要 Node 18+(OpenCode 的粘贴恢复需要 22.5+),macOS 或 Linux。
|
|
47
|
+
> 按 https://github.com/liustack/modlens 的 INSTALL.md 安装并配置 modlens skill,完成后运行体检并把结果告诉我。
|
|
63
48
|
|
|
64
49
|
## 用法
|
|
65
50
|
|
|
66
|
-
|
|
51
|
+
装好之后不需要记任何命令。正常聊天,粘贴图片或给出图片路径,提问即可,skill 自动触发:图片交给视觉引擎,答案基于读到的内容返回。
|
|
67
52
|
|
|
68
|
-
|
|
69
|
-
modlens -i screenshot.png # 本地图片
|
|
70
|
-
modlens -i https://example.com/chart.png # 远程图片
|
|
71
|
-
modlens -i chart.png --prompt "重点看数据轴" # 指定关注点
|
|
72
|
-
modlens recover-paste # 把刚粘贴的图捞成文件
|
|
73
|
-
```
|
|
53
|
+
## 实测
|
|
74
54
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
```json
|
|
78
|
-
{
|
|
79
|
-
"image": "/path/to/screenshot.png",
|
|
80
|
-
"provider": "gemini-api",
|
|
81
|
-
"result": {
|
|
82
|
-
"summary": "四个节点的工作流图,箭头带标注。",
|
|
83
|
-
"ocr": { "full_text": "/shaping\nBEFORE YOU BUILD\n...", "lines": [] },
|
|
84
|
-
"layout": { "regions": [{ "reading_order": 1, "type": "title", "text": "/shaping" }] },
|
|
85
|
-
"uncertainty": []
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
```
|
|
55
|
+
以下均为原样记录,驱动的都是纯文本的 DeepSeek-V4-Flash。
|
|
89
56
|
|
|
90
|
-
Codex 桌面 App
|
|
57
|
+
Codex 桌面 App 中识别一张推文截图。配文、互动数据(2.9K 回复、270K 点赞、5M 浏览)以及图片的 alt 文字全部读出。分辨率不足的部分明确说明无法确认,没有编造。
|
|
91
58
|
|
|
92
59
|

|
|
93
60
|
|
|
94
|
-
|
|
61
|
+
一次粘贴三张图。模型依次读取,包括对设计意图的判断。
|
|
95
62
|
|
|
96
|
-

|
|
97
64
|
|
|
98
|
-
|
|
65
|
+
压力测试:128 个模型的散点图。图表类型、双轴定义、对数刻度全部识别,并从密集点群中准确读出高亮点的位置(成本约 $0.028,智能指数 50)。密集图表是视觉模型最容易出错的场景。
|
|
99
66
|
|
|
100
|
-
|
|
101
|
-
| :-- | :-- | :-- | :-- |
|
|
102
|
-
| 你选的模型 | 得换掉 | 不用换 | 不用换 |
|
|
103
|
-
| 粘贴进对话的图 | 模型支持才看得见 | 接不住 | 直接接住 |
|
|
104
|
-
| 拿到手的是什么 | 模型自己的理解 | 通常一段描述 | 全文转录、版面区块、实体关系 |
|
|
105
|
-
| 读不准的地方 | 可能编 | 可能编 | 进 `uncertainty` |
|
|
106
|
-
| 花费 | 多模态模型的价格 | 多数按 API 计费 | agy 免费额度或免费 Gemini key |
|
|
67
|
+

|
|
107
68
|
|
|
108
|
-
|
|
69
|
+
粘贴链路的端到端记录:接入 DeepSeek 的 Claude Code,两张图直接粘贴进对话。界面中只显示占位符,skill 从会话存储恢复两张图片并逐一读出,包括 PPT 封面的配色色值。
|
|
109
70
|
|
|
110
|
-
|
|
71
|
+

|
|
111
72
|
|
|
112
|
-
|
|
113
|
-
| :-- | :-- | :-- |
|
|
114
|
-
| `-i, --input <path\|url>` | 要解析的图片(必填) | |
|
|
115
|
-
| `-p, --provider <name>` | 视觉 provider | `antigravity-cli` |
|
|
116
|
-
| `-m, --model <name>` | provider 模型 | `gemini-3.6-flash-low` |
|
|
117
|
-
| `-o, --output <path>` | 同时把 JSON 写入文件 | |
|
|
118
|
-
| `--prompt <text>` | 额外关注点 | |
|
|
119
|
-
| `--timeout <ms>` | provider 超时 | `180000` |
|
|
73
|
+
## 文档
|
|
120
74
|
|
|
121
|
-
|
|
75
|
+
| 文档 | 适用场景 |
|
|
76
|
+
| :----------------------------------------------------- | :----------------------------------------- |
|
|
77
|
+
| [INSTALL.md](INSTALL.md) | 一步步安装 skill(为 agent 编写) |
|
|
78
|
+
| [CLI 手册](skills/modlens/references/cli.md) | skill 所驱动的 CLI:参数、配置与体检 |
|
|
79
|
+
| [故障排查](docs/troubleshooting.md) | 命令报错,查成因和解法 |
|
|
80
|
+
| [配置手册](skills/modlens/references/configure.md) | 配置 key、切换 provider、排查配置 |
|
|
81
|
+
| [输出契约](skills/modlens/references/output-schema.md) | 解析 JSON 或构建下游工具 |
|
|
82
|
+
| [宿主接入](docs/harness-setup.md) | 在 Codex、Claude Code、Pi、OpenCode 中配置 |
|
|
83
|
+
| [安全说明](docs/security.md) | 恢复文件的权限、图片内容作为不可信输入 |
|
|
84
|
+
| [更新日志](CHANGELOG.md) | 查询版本变更 |
|
|
85
|
+
| [AGENTS.md](AGENTS.md) | 修改本项目代码 |
|
|
122
86
|
|
|
123
|
-
##
|
|
87
|
+
## 参与方式
|
|
124
88
|
|
|
125
|
-
|
|
126
|
-
| :-- | :-- |
|
|
127
|
-
| [故障排查](docs/troubleshooting.md) | 命令报错,想知道成因和解法 |
|
|
128
|
-
| [配置手册](skills/modlens/references/configure.md) | 配 key、换 provider、排查配置 |
|
|
129
|
-
| [输出契约](skills/modlens/references/output-schema.md) | 要解析 JSON 或写下游工具 |
|
|
130
|
-
| [宿主接入](docs/harness-setup.md) | 在 Codex、Claude Code、Pi、OpenCode 里配置 |
|
|
131
|
-
| [安全说明](docs/security.md) | 恢复文件的权限、图片内容作为不可信输入 |
|
|
132
|
-
| [更新日志](CHANGELOG.md) | 想知道某个版本改了什么 |
|
|
133
|
-
| [AGENTS.md](AGENTS.md) | 要改这个项目的代码 |
|
|
89
|
+
本仓库不接受 PR。项目由作者独立维护,所有代码经作者本人审阅,这是它可靠性的前提。两种有效的参与方式:
|
|
134
90
|
|
|
135
|
-
|
|
91
|
+
- **[提交 issue](https://github.com/liustack/modlens/issues)。** bug、建议、难以理解的报错或文档都欢迎。issue 会被认真阅读,并影响后续开发方向。
|
|
92
|
+
- **Fork。** MIT 协议下你的副本完全归你,修改和发布不受限制。
|
|
136
93
|
|
|
137
|
-
|
|
94
|
+
## 插入硬广一条
|
|
138
95
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
96
|
+
关注微信公众号「liustack」:AI 工具、实践与想法,第一时间推送。微信扫码,或搜一搜「liustack」:
|
|
97
|
+
|
|
98
|
+
<p align="center">
|
|
99
|
+
<img src="https://raw.githubusercontent.com/liustack/modlens/main/assets/wechat-qrcode.png" width="420" alt="微信公众号 liustack" />
|
|
100
|
+
</p>
|
|
142
101
|
|
|
143
|
-
⭐
|
|
102
|
+
⭐ 如果它对你有用,请给 [ModLens](https://github.com/liustack/modlens) 一个 star,这是其他开发者找到它的方式。
|
|
144
103
|
|
|
145
104
|
## 免责声明
|
|
146
105
|
|
|
147
|
-
|
|
106
|
+
本项目依下方 MIT 协议按现状提供。作者不对任何特定用途(含商业使用)提供保证或背书。上游引擎(Antigravity CLI,Gemini、OpenAI、Anthropic 的 API,以及任何 OpenAI 兼容端点)的使用受各自条款和额度约束,由使用者负责。
|
|
148
107
|
|
|
149
108
|
## License
|
|
150
109
|
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a vulnerability
|
|
4
|
+
|
|
5
|
+
Please report security issues privately, not in a public issue.
|
|
6
|
+
|
|
7
|
+
Use [GitHub Security Advisories](https://github.com/liustack/modlens/security/advisories/new) to open a private report. That keeps the details between you and the maintainers until a fix is out.
|
|
8
|
+
|
|
9
|
+
Include the exact command, the full output, and the modlens and Node versions, the same detail a bug report needs. We will acknowledge the report, work on a fix, and credit you unless you prefer otherwise.
|
|
10
|
+
|
|
11
|
+
## Supported versions
|
|
12
|
+
|
|
13
|
+
This is a fast-moving CLI. Fixes land on the latest published version on npm (`@liustack/modlens`), so upgrade to the newest release before reporting.
|
|
14
|
+
|
|
15
|
+
## What to keep in mind
|
|
16
|
+
|
|
17
|
+
modlens runs vision engines over images on your machine and can recover pasted image bytes from local session storage. The security model, what it runs, how recovered images are protected, and why image content is untrusted input, is documented in [docs/security.md](docs/security.md). Read it before reporting behavior that may be working as intended.
|