@watermarkws/cli 0.1.0 → 0.1.1

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/README.md CHANGED
@@ -12,6 +12,15 @@ npx @watermarkws/cli image process https://example.com/photo.jpg \
12
12
 
13
13
  Node 18+, no dependencies.
14
14
 
15
+ ## Install
16
+
17
+ ```bash
18
+ brew install watermarkws/tap/watermark # Homebrew, macOS and Linux
19
+ npm install -g @watermarkws/cli # npm
20
+ ```
21
+
22
+ Either way the command is `watermark`. Homebrew brings its own Node; `npx @watermarkws/cli` runs it without installing.
23
+
15
24
  ## Commands
16
25
 
17
26
  ```
@@ -59,6 +68,10 @@ The CLI passes every error code through as the API sends it: `Error 422 validati
59
68
 
60
69
  Rate limits (429) and server errors are retried twice with the same `Idempotency-Key`, so a retry never runs a request twice.
61
70
 
71
+ ## For AI agents
72
+
73
+ `SKILL.md` is an [Agent Skill](https://agentskills.io) for this CLI: when to use it, the commands, the output shape, exit codes and the rules an agent should follow (ask before a big batch, never paste file bytes). Save it as `.claude/skills/watermark/SKILL.md` in a project for Claude Code, or paste it into any agent's instructions. The API's own guide for agents, with its MCP server and plain HTTP, is at https://api.watermark.ws/docs/agents.md.
74
+
62
75
  ## Development
63
76
 
64
77
  ```bash
package/SKILL.md ADDED
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: watermark
3
+ description: Watermark, resize, crop, convert and stamp text on images, videos and PDF or Word documents with the Watermark API from the shell, through the `watermark` CLI. Use it when a user wants a logo or text placed on files, a batch of photos resized or converted (JPEG, PNG, WebP, HEIC, camera RAW and more), a video watermarked or trimmed to a preview, a frame or a page saved as an image, or every page of a PDF stamped while it stays a PDF. Sources can be public URLs, local files (uploaded automatically) or files an earlier request made. Needs a WATERMARK_API_KEY from https://watermark.ws/developers.
4
+ ---
5
+
6
+ # Watermark CLI
7
+
8
+ The `watermark` command sends a file and a list of operations to the Watermark API, waits for the result and downloads it. Use it instead of a local image library for batches, video, PDF/DOCX, camera formats (HEIC, CR3, NEF, ARW, DNG), text in real fonts, and when the result should be a link the user can download.
9
+
10
+ ## Install and set the key
11
+
12
+ ```bash
13
+ npm install -g @watermarkws/cli # or: brew install watermarkws/tap/watermark
14
+ npx @watermarkws/cli --version # or run it once without installing (Node 18+)
15
+ export WATERMARK_API_KEY=wm_test_… # keys: https://watermark.ws/developers
16
+ ```
17
+
18
+ `wm_test_…` keys are free and return real results within small limits (10 requests a minute, 100 a day, sources up to 10 MB, no video). `wm_live_…` keys spend the account's prepaid credit. If the user has no key, send them to https://watermark.ws/developers; new accounts start with $1 of free credit.
19
+
20
+ ## Core commands
21
+
22
+ A `<source>` is a public http(s) URL, a local file path (uploaded first, automatically), an upload id `upl_…`, a file an earlier request made `file_…`, or `stg_7a:path/key` in a connected bucket. Operations run in the order given: `--op type:param=value,param=value`; numbers and `true`/`false` are typed, everything else is text.
23
+
24
+ ```bash
25
+ watermark image process photo.jpg --op resize:width=1600,height=1600 --op watermark:image_url=https://example.com/logo.png,x=40,y=40 --format webp --out photo.webp
26
+ watermark image read photo.jpg --json # width, height, format; add --level for the angle that levels the horizon
27
+ watermark image create --width 1200 --height 300 --op 'text:text=Lena Hart,font=inter-bold,size=96,color=#202020,position=center' --op trim --format png --out logo.png
28
+ watermark video process clip.mp4 --op watermark:image_url=https://example.com/logo.png,x=24,y=24 --max-duration 30 --out preview.mp4
29
+ watermark video screenshot clip.mp4 --seconds 5 --format png --out frame.png
30
+ watermark document process contract.pdf --op watermark:image_url=https://example.com/stamp.png,x=20,y=230 --out contract-stamped.pdf
31
+ watermark document snapshot contract.pdf --page 1 --format png --out page-1.png
32
+ watermark operations image # every operation and parameter, live from the API (also video, document)
33
+ watermark fonts # font names a text operation accepts
34
+ watermark request get 1234 # follow a request started with --no-wait
35
+ watermark account # balance and limits
36
+ ```
37
+
38
+ Useful options on processing commands: `--out <file>` (wait, then download), `--no-wait` (print the queued request and return), `--timeout <seconds>` (default 300), `--format <fmt>`, `--ops-json '[…]'` instead of `--op`, `--max-duration <s>` (video), `--max-pages <n>` (documents), `--customer <id>`, `--metadata key=value`, `--json`.
39
+
40
+ Operations that exist: images `resize`, `crop`, `rotate`, `flip`, `grayscale`, `border`, `watermark`, `thumbnail`, `compress`, `sepia`, `exposure`, `filter`, `remove_background`, `orient`, `text`, `trim`, `color`, `frame`, `protect`, `shave`, `line`, `adjust`, `color_profile`; videos `resize`, `crop`, `rotate`, `flip`, `grayscale`, `border`, `watermark`; documents `watermark` only (an image on every page; make a text stamp with `image create` first). `watermark` takes `image_url` or `image` (a `file_…` id), `x`, `y` from the top left, `tile_spacing_x`/`tile_spacing_y` to repeat it, `diagonal_lines_color`/`diagonal_lines_opacity`. Run `watermark operations image` before using a parameter you are not sure of.
41
+
42
+ ## A folder of files
43
+
44
+ Prepare the watermark once and reuse its `file_…` id; one request per file after that.
45
+
46
+ ```bash
47
+ logo=$(watermark image process logo.png --op orient --format png --json | jq -r '.result.files[0].id')
48
+ mkdir -p out
49
+ for f in photos/*; do
50
+ name=$(basename "${f%.*}")
51
+ watermark image process "$f" --op resize:width=1600,height=1600 --op "watermark:image=$logo,x=40,y=40" --format webp --out "out/$name.webp"
52
+ done
53
+ ```
54
+
55
+ Stamp text across every page of a PDF: make the stamp, then watermark the document with it.
56
+
57
+ ```bash
58
+ stamp=$(watermark image create --width 800 --height 800 --op 'text:text=CONFIDENTIAL,font=inter-bold,size=80,color=#c0392b,opacity=35,position=center,rotation=-30' --op trim --format png --json | jq -r '.result.files[0].id')
59
+ watermark document process contract.pdf --op "watermark:image=$stamp,x=20,y=230" --out contract-confidential.pdf
60
+ ```
61
+
62
+ ## Output and exit codes
63
+
64
+ With `--json`, stdout is only the finished request as the API returns it (progress goes to stderr):
65
+
66
+ ```json
67
+ {"id": 1234, "object": "request", "endpoint": "images/process", "status": "succeeded",
68
+ "result": {"data": {"width": 1600, "height": 1067, "format": "WEBP"},
69
+ "files": [{"id": "file_…", "url": "https://…", "url_expires_at": "2026-10-18T15:00:04Z", "format": "webp", "size": 183021}]},
70
+ "price": {"amount": "0.002000", "currency": "usd"}, "saved_to": "photo.webp"}
71
+ ```
72
+
73
+ A failed request has `"status": "failed"` and `error.code` / `error.message`. An API error with `--json` prints `{"error": {"status": 422, "type": "…", "code": "…", "message": "…", "errors": {…}}}` on stdout. Without `--json`, the result is human-readable lines (`Request 1234 (images/process): succeeded`, `File: https://…`, `Saved to …`, `Price: $0.002000`).
74
+
75
+ | Exit | Meaning |
76
+ | --- | --- |
77
+ | 0 | The request succeeded (or was queued, with `--no-wait`). |
78
+ | 1 | The API refused the call, or the request failed or was aborted. The error code is printed. |
79
+ | 2 | The command was used wrongly (bad source, missing `--op`, unknown command). |
80
+
81
+ ## Rules
82
+
83
+ - Never paste file contents or base64 into a command; give the path and the CLI uploads it. Never ask the user to host a local file first.
84
+ - Credit is prepaid and every finished request is charged ($0.002 an image, $0.004 a document page, $0.02 a started minute of video). Before more than about 20 files, a video over about 10 minutes, or a document with hundreds of pages, tell the user the cost and ask.
85
+ - Failed and aborted requests are free; fix the cause (the message names the field) and run again. Rate limits and server errors are retried by the CLI itself.
86
+ - Always pass `--out` when the user wants the file, and `--json` when a script reads the result. Download links in `result.files[].url` last 7 days; `watermark file get <file_id>` gives a fresh one while the file is kept.
87
+ - Video needs a live key on an account that has bought credit; a test key gets `402 paid_account_required`.
88
+ - Check a file before guessing parameters: `watermark image read`, `watermark video read` and `watermark document read` give dimensions, duration and page count.
89
+
90
+ ## Common errors
91
+
92
+ | Error | Fix |
93
+ | --- | --- |
94
+ | `Set WATERMARK_API_KEY or pass --api-key`, `401 missing_api_key`, `401 invalid_api_key` | No key, or a wrong or revoked key. Export `WATERMARK_API_KEY` from https://watermark.ws/developers. |
95
+ | `402 insufficient_credits` | The account has no credit left. Buy credit at https://watermark.ws/developers. |
96
+ | `402 paid_account_required` | Video, or writing to your own storage, needs an account that has bought credit; a test key cannot. |
97
+ | `422 validation_failed` | A parameter is wrong; the invalid fields are listed under the message. Check `watermark operations <media>`. |
98
+ | `429 rate_limited` / `429 concurrency_limited` | Too many requests a minute, or too many running at once. The CLI retries twice; otherwise wait and run fewer in parallel. |
99
+ | `is not a URL, an id, stg_…:key, or a file here` | The source path does not exist or is not a file. |
100
+ | `Request … was still processing after 300 seconds` | A long video. Rerun with `--timeout 1800`, or `--no-wait` and later `watermark request get <id>`. |
101
+
102
+ ## More
103
+
104
+ - Agent guide, with MCP server, HTTP and worked examples: https://api.watermark.ws/docs/agents.md
105
+ - Every operation and parameter: https://api.watermark.ws/docs/operations.md
106
+ - Every command and option: `watermark --help`, or https://api.watermark.ws/docs/cli.md
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@watermarkws/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Watermark, resize and convert images, videos and PDFs from the command line with the Watermark API.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "watermark": "bin/watermark.js"
8
8
  },
9
- "files": ["bin", "src", "README.md", "LICENSE"],
9
+ "files": ["bin", "src", "README.md", "SKILL.md", "LICENSE"],
10
10
  "engines": {
11
11
  "node": ">=18"
12
12
  },
package/src/api.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // retries for 429 (after Retry-After), 5xx and dropped connections, with an
3
3
  // Idempotency-Key on every POST so a retried POST never runs twice.
4
4
 
5
- export const VERSION = '0.1.0';
5
+ export const VERSION = '0.1.1';
6
6
 
7
7
  export class ApiError extends Error {
8
8
  constructor(status, error = {}) {