viewinline 0.5.0__tar.gz → 0.5.1__tar.gz

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.
@@ -0,0 +1,5 @@
1
+ __pycache__/
2
+ .pytest_cache/
3
+ dist/
4
+ *.egg-info/
5
+ .DS_Store
@@ -19,8 +19,8 @@ authors:
19
19
  repository-code: "https://github.com/nkeikon/inlineviewer"
20
20
  url: "https://github.com/nkeikon/inlineviewer"
21
21
  license: Apache-2.0
22
- version: 0.5.0
23
- date-released: 2026-10-21
22
+ version: 0.5.1
23
+ date-released: 2026-11-10
24
24
  # ---------------------------------------------------------------------------
25
25
  # The DOI below is the VERSION DOI for v0.3.2 (a specific archived snapshot).
26
26
  # To make citations always resolve to your LATEST release, replace it with the
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: viewinline
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: Quick look geospatial viewer for the terminal, with inline image previews
5
5
  Project-URL: Homepage, https://github.com/nkeikon/viewinline
6
6
  Project-URL: Repository, https://github.com/nkeikon/viewinline
@@ -109,6 +109,15 @@ viewinline counties.shp --table --unique STATE_NAME
109
109
  viewinline data.geoparquet --table --where "POP > 100000" --sort POP --desc
110
110
  ```
111
111
 
112
+ ## Use with Claude Code
113
+
114
+ viewinline includes a skill that lets Claude Code inspect files with `--info` and offer quick-look previews with `--export`. To install:
115
+
116
+ ```
117
+ mkdir -p ~/.claude/skills/viewinline
118
+ curl -o ~/.claude/skills/viewinline/SKILL.md https://raw.githubusercontent.com/nkeikon/inlineviewer/main/skills/viewinline/SKILL.md
119
+ ```
120
+
112
121
  ## Compatible terminals
113
122
 
114
123
  Native (no extra install required): images render via the iTerm2 inline image protocol on:
@@ -76,6 +76,15 @@ viewinline counties.shp --table --unique STATE_NAME
76
76
  viewinline data.geoparquet --table --where "POP > 100000" --sort POP --desc
77
77
  ```
78
78
 
79
+ ## Use with Claude Code
80
+
81
+ viewinline includes a skill that lets Claude Code inspect files with `--info` and offer quick-look previews with `--export`. To install:
82
+
83
+ ```
84
+ mkdir -p ~/.claude/skills/viewinline
85
+ curl -o ~/.claude/skills/viewinline/SKILL.md https://raw.githubusercontent.com/nkeikon/inlineviewer/main/skills/viewinline/SKILL.md
86
+ ```
87
+
79
88
  ## Compatible terminals
80
89
 
81
90
  Native (no extra install required): images render via the iTerm2 inline image protocol on:
@@ -1,4 +1,3 @@
1
- ```json
2
1
  {
3
2
  "$schema": "https://context7.com/schema/context7.json",
4
3
  "projectTitle": "viewinline",
@@ -14,7 +13,7 @@
14
13
  "Use inline terminal image rendering instead of GUI workflows.",
15
14
  "Highlight support for GeoTIFF, NetCDF, GeoJSON, and GeoParquet.",
16
15
  "Emphasize compatibility limitations for terminal graphics protocols.",
17
- "For programmatic or AI-agent use, note --info (JSON metadata) and --export (save rendered image)."
16
+ "For programmatic or AI-agent use, note --info (JSON metadata) and --export (save rendered image).",
17
+ "For Claude Code users, mention the viewinline skill at skills/viewinline/SKILL.md and how to install it."
18
18
  ]
19
19
  }
20
- ```
@@ -7,7 +7,7 @@
7
7
  - Command name: `viewinline`
8
8
  - Requires: Python 3.9+
9
9
  - License: Apache-2.0 © 2026 Keiko Nomura
10
- - Latest release: v0.5.0 (2026-10-21)
10
+ - Latest release: v0.5.1 (2026-11-10)
11
11
  - Combines the core display logic of `viewtif` and `viewgeom`, but is **non-interactive**: no zoom/pan/colormap-switching on the fly. Everything is controlled via CLI options (e.g. `--display`, `--color-by`, `--colormap`).
12
12
 
13
13
  ## Installation
@@ -24,6 +24,17 @@ Optional extras (install only if needed):
24
24
  - `h5py` — fallback for HDF5 if GDAL lacks HDF5 support (usually unnecessary). `pip install h5py`
25
25
  - `chafa` — system binary (not a Python package); strongly recommended for terminal coverage beyond the native list. See "Terminals".
26
26
 
27
+ ## Use with Claude Code
28
+
29
+ viewinline has a Claude Code skill. It is a separate install from the pip package:
30
+
31
+ ```
32
+ mkdir -p ~/.claude/skills/viewinline
33
+ curl -o ~/.claude/skills/viewinline/SKILL.md https://raw.githubusercontent.com/nkeikon/inlineviewer/main/skills/viewinline/SKILL.md
34
+ ```
35
+
36
+ Start a new Claude Code session after installing. The skill is at skills/viewinline/SKILL.md in the GitHub repository.
37
+
27
38
  ## How display works (rendering engines)
28
39
 
29
40
  - Uses the **iTerm2 inline image protocol (OSC 1337)** natively in supported terminals.
@@ -239,6 +250,7 @@ Optional: `chafa` (terminal coverage; system binary), `duckdb` (filter/sort/SQL)
239
250
  - **v0.1.5 (2026-02-13):** Fixed duplicate band-display prints; optimized uint8 normalization; minor perf.
240
251
  - **v0.4.0 (2026-08-23):** New agent-facing inspection commands: `--info` (file metadata + statistics as JSON, for rasters and vectors; lists variables for NetCDF/HDF with `--subset`; always returns JSON including structured errors) and `--export` (save the rendered image to PNG/JPEG, works with any display flag). Existing viewer behavior unchanged.
241
252
  - **v0.5.0 (2026-10-21):** New `--grid [N]` flag: axis ticks and a light grid overlay. Georeferenced rasters and vectors are labelled in real CRS coordinates; photos, NetCDF, and non-georeferenced files in pixel positions. Grid contributed by @luismanriqueruiz.
253
+ - **v0.5.1 (2026-11-10):** Bug fix: viewinline now exits with code 1 (instead of 0) when an input file is missing or unreadable — PNG/JPG, GeoTIFF, vectors (.shp, .geojson, .gpkg), and NetCDF — so scripts and agents can detect the failure. Missing PNG/JPG fix contributed by @Qrytics (#8).
242
254
 
243
255
  ## Support & links
244
256
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "viewinline"
7
- version = "0.5.0"
7
+ version = "0.5.1"
8
8
  description = "Quick look geospatial viewer for the terminal, with inline image previews"
9
9
  readme = "README.md"
10
10
  license = { text = "Apache-2.0" }
@@ -10,6 +10,15 @@ Quick-look terminal viewer for geospatial and tabular data. Think of it as `ls`
10
10
 
11
11
  Renders natively in iTerm2, WezTerm, Konsole, Rio, and Contour. Falls back to `chafa` (ASCII art with 24-bit color) in other terminals like kitty, Ghostty, Terminal.app, VS Code, and Linux terminals. Works over SSH without X11 forwarding or VNC.
12
12
 
13
+ ## Inside Claude Code
14
+
15
+ To show the user an image, use `--export`. It saves a PNG and opens it in the user's default image viewer, and you can read the same PNG. Ask before running it, e.g. "Want to see a quick-look of `ndvi.tif`?" If the user asks to see a file, run it directly. If they say to always or never show images, follow that for the rest of the session.
16
+
17
+ - Use `--info` freely for your own checks. It prints JSON and opens nothing.
18
+ - A plain `viewinline file.tif` run from the shell does not reach the user, because the output is captured as text. Don't claim you showed them an image that way.
19
+ - CSV and Parquet previews with more than 10 rows ask `[first/all]`. Pipe the answer in: `echo first | viewinline data.csv`.
20
+ - Delete exported PNGs once they're no longer needed, unless the user wants to keep them.
21
+
13
22
  ## When to Use
14
23
 
15
24
  - **File browsing**: `find . -name "*.jpg" | xargs -n1 viewinline` to visually scan results
@@ -59,9 +68,9 @@ Note: `--info` and `--export` report what a file *is* and what it *looks like*
59
68
 
60
69
  ## Core Flags
61
70
 
62
- **Inspection (JSON output, no image):**
71
+ **Inspection:**
63
72
  - `--info` — print metadata + statistics as JSON, then exit (rasters and vectors; lists variables for NetCDF/HDF with `--subset N`)
64
- - `--export PATH` — save the rendered image to PATH (`.png`/`.jpg`); prints `{"path": "..."}`
73
+ - `--export PATH` — save the rendered image to PATH (`.png`/`.jpg`), open it in the default image viewer, and print `{"path": "..."}`
65
74
  - `--grid [N]` — overlay axis ticks and a light grid (N divisions, default 5). Labels are in the file's CRS units for georeferenced rasters and vectors, pixel positions otherwise. Combine with `--export` to save a quick-look with readable coordinates, e.g. to check a file covers the expected area.
66
75
 
67
76
  **Raster Display:**
@@ -35,7 +35,7 @@ warnings.filterwarnings("ignore", message="invalid scale_factor or add_offset at
35
35
  _EXPORT_PATH = None
36
36
  _EXPORT_RESULT = None
37
37
 
38
- __version__ = "0.5.0"
38
+ __version__ = "0.5.1"
39
39
 
40
40
  AVAILABLE_COLORMAPS = [
41
41
  "viridis", "inferno", "magma", "plasma",
@@ -1068,6 +1068,11 @@ def render_simple_image(filepath: str, args) -> None:
1068
1068
 
1069
1069
  show_image_auto(img_array, getattr(args, "display", None), is_vector=False)
1070
1070
 
1071
+ except FileNotFoundError:
1072
+ # A missing file is not a damaged-but-readable image: let the
1073
+ # caller report it with a nonzero exit instead of falling back
1074
+ # to the rasterio path.
1075
+ raise
1071
1076
  except Exception as e:
1072
1077
  print(f"[ERROR] Failed to load image: {e}")
1073
1078
 
@@ -1087,7 +1092,7 @@ def render_netcdf_via_netcdf4(path, args):
1087
1092
  nc = netCDF4.Dataset(path)
1088
1093
  except Exception as e:
1089
1094
  print(f"[ERROR] Could not open NetCDF file: {e}")
1090
- return
1095
+ sys.exit(1)
1091
1096
 
1092
1097
  # Recursively collect (path, variable) pairs across all groups
1093
1098
  def collect_vars(group, prefix=""):
@@ -1536,6 +1541,7 @@ def render_raster(paths: list[str], args) -> None:
1536
1541
  print("[INFO] viewinline only supports 2D or 3D NetCDF variables")
1537
1542
  else:
1538
1543
  print(f"[ERROR] Inline render failed: {e}")
1544
+ sys.exit(1)
1539
1545
 
1540
1546
 
1541
1547
  def render_gallery(folder: str, grid: str = "4x4", display_scale=None, is_vector=False) -> None:
@@ -1750,7 +1756,7 @@ def render_vector(path, args):
1750
1756
  return
1751
1757
  except Exception as e:
1752
1758
  print(f"[ERROR] Failed to read vector: {e}")
1753
- return
1759
+ sys.exit(1)
1754
1760
 
1755
1761
  # Detect non-geometry columns
1756
1762
  all_cols = [c for c in gdf.columns if c != gdf.geometry.name]
@@ -2292,6 +2298,9 @@ def main() -> None:
2292
2298
  try:
2293
2299
  render_simple_image(paths[0], args)
2294
2300
  return
2301
+ except FileNotFoundError as e:
2302
+ print(f"[ERROR] Failed to read file: {e}")
2303
+ sys.exit(1)
2295
2304
  except Exception:
2296
2305
  pass
2297
2306
  render_raster(paths, args)
@@ -0,0 +1,39 @@
1
+ """A missing PNG/JPG must exit nonzero, not report an error with exit 0."""
2
+
3
+ import sys
4
+
5
+ import pytest
6
+
7
+ from viewinline.viewinline import main
8
+
9
+
10
+ def _run(argv, capsys):
11
+ sys.argv = argv
12
+ with pytest.raises(SystemExit) as exc:
13
+ main()
14
+ out = capsys.readouterr().out
15
+ return exc.value.code, out
16
+
17
+
18
+ def test_missing_png_exits_nonzero(capsys):
19
+ code, out = _run(["viewinline", "/nonexistent-xyz-440.png"], capsys)
20
+ assert code == 1
21
+ assert "[ERROR]" in out
22
+
23
+
24
+ def test_missing_jpg_exits_nonzero(capsys):
25
+ code, out = _run(["viewinline", "/nonexistent-xyz-440.jpg"], capsys)
26
+ assert code == 1
27
+ assert "[ERROR]" in out
28
+
29
+
30
+ @pytest.mark.parametrize("path", [
31
+ "/nonexistent-xyz-440.tif",
32
+ "/nonexistent-xyz-440.shp",
33
+ "/nonexistent-xyz-440.geojson",
34
+ "/nonexistent-xyz-440.nc",
35
+ ])
36
+ def test_missing_raster_or_vector_exits_nonzero(path, capsys):
37
+ code, out = _run(["viewinline", path], capsys)
38
+ assert code == 1
39
+ assert "[ERROR]" in out
@@ -1,4 +0,0 @@
1
- dist/
2
- build/
3
- *.egg-info
4
- *.DS_Store
File without changes