@plantnet/planttaxomatcher 0.2.0 → 0.3.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/package.json CHANGED
@@ -1,43 +1,44 @@
1
1
  {
2
- "name": "@plantnet/planttaxomatcher",
3
- "version": "0.2.0",
4
- "description": "PlantTaxoMatcher CLI — reconcile plant names against WCVP via the PlantTaxoMatcher API.",
5
- "type": "module",
6
- "engines": {
7
- "node": ">=24"
8
- },
9
- "bin": {
10
- "planttaxomatcher": "./dist/index.js"
11
- },
12
- "files": [
13
- "dist"
14
- ],
15
- "publishConfig": {
16
- "access": "public"
17
- },
18
- "dependencies": {
19
- "@inquirer/prompts": "^8.5.0",
20
- "commander": "^14.0.0",
21
- "kleur": "^4.1.5",
22
- "ora": "^9.0.0",
23
- "papaparse": "^5.5.3",
24
- "undici": "^8.0.0",
25
- "zod": "^4.0.0"
26
- },
27
- "devDependencies": {
28
- "@types/node": "^24.12.4",
29
- "@types/papaparse": "^5.5.2",
30
- "tsup": "^8.5.1",
31
- "tsx": "^4.20.0",
32
- "typescript": "^6.0.0",
33
- "vitest": "^4.1.7",
34
- "@planttaxomatcher/shared": "0.0.0"
35
- },
36
- "scripts": {
37
- "dev": "tsx src/index.ts",
38
- "build": "tsup",
39
- "typecheck": "tsc -p tsconfig.json --noEmit",
40
- "test": "vitest run --passWithNoTests",
41
- "lint": "echo \"no lint yet\" && exit 0"
42
- }
43
- }
2
+ "name": "@plantnet/planttaxomatcher",
3
+ "version": "0.3.0",
4
+ "description": "PlantTaxoMatcher CLI — reconcile plant names against WCVP via the PlantTaxoMatcher API.",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=24"
8
+ },
9
+ "bin": {
10
+ "planttaxomatcher": "./dist/index.js"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "skills"
15
+ ],
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "scripts": {
20
+ "dev": "tsx src/index.ts",
21
+ "build": "tsup",
22
+ "typecheck": "tsc -p tsconfig.json --noEmit",
23
+ "test": "vitest run --passWithNoTests",
24
+ "lint": "echo \"no lint yet\" && exit 0",
25
+ "prepublishOnly": "pnpm run build"
26
+ },
27
+ "dependencies": {
28
+ "@inquirer/prompts": "^8.5.0",
29
+ "commander": "^14.0.0",
30
+ "kleur": "^4.1.5",
31
+ "papaparse": "^5.5.3",
32
+ "undici": "^8.0.0",
33
+ "zod": "^4.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "@planttaxomatcher/shared": "workspace:*",
37
+ "@types/node": "^24.12.4",
38
+ "@types/papaparse": "^5.5.2",
39
+ "tsup": "^8.5.1",
40
+ "tsx": "^4.20.0",
41
+ "typescript": "^6.0.0",
42
+ "vitest": "^4.1.7"
43
+ }
44
+ }
@@ -0,0 +1,117 @@
1
+ ---
2
+ name: planttaxomatcher
3
+ description: >-
4
+ Reconcile plant scientific names against the World Checklist of Vascular
5
+ Plants (WCVP) with the PlantTaxoMatcher CLI. Use when the user wants to
6
+ match, clean, standardise or validate a list of plant names (CSV, XLSX or
7
+ JSON), find the accepted name behind a synonym, attach WCVP, IPNI or POWO
8
+ identifiers, see which names need taxonomic review, or check, download,
9
+ pause or cancel a PlantTaxoMatcher job.
10
+ compatibility: Needs Node.js 24+ and network access to a PlantTaxoMatcher server.
11
+ metadata:
12
+ cli-version: '{{version}}'
13
+ ---
14
+
15
+ # PlantTaxoMatcher
16
+
17
+ PlantTaxoMatcher matches each plant name in a file against a WCVP snapshot
18
+ through a cascade of exact, fuzzy and external lookups, then grades every
19
+ match. Confident matches (grade A) are accepted automatically; the rest wait
20
+ for a human in the review queue of the web app. You drive it with the CLI.
21
+
22
+ ## Running the CLI
23
+
24
+ Run `planttaxomatcher --version`. Use `planttaxomatcher` only if it prints
25
+ {{version}} or newer; otherwise (not installed, or an older version) use
26
+ `npx -y @plantnet/planttaxomatcher@{{version}}` in its place everywhere below.
27
+
28
+ - Pass `--json`: stdout then carries only JSON, and progress or hints go to stderr.
29
+ - Branch on the exit code:
30
+
31
+ | Exit | Meaning | What to do |
32
+ | ---- | ------------------------------------- | ----------------------------------------------------- |
33
+ | 0 | Success | Continue |
34
+ | 1 | API or network error | Read stderr; retry once if it names a network problem |
35
+ | 2 | Bad flag or argument | Check `planttaxomatcher <command> --help` |
36
+ | 3 | Not signed in, or token rejected | Follow **Sign-in** below |
37
+ | 4 | A watched job failed or was cancelled | Report it with the job link |
38
+ | 5 | A watched job was paused | Ask the user whether to resume it |
39
+
40
+ ## 1. Sign-in
41
+
42
+ Run `planttaxomatcher whoami --json` first.
43
+
44
+ - Exit 0: signed in. Note `server` and `appUrl` for links.
45
+ - Exit 3: not signed in. **Do not run `planttaxomatcher login` yourself.** It
46
+ waits for someone to approve a code in a browser and will outlast your
47
+ command timeout. Tell the user to run `planttaxomatcher login` in their own
48
+ terminal (in Claude Code they can type `! planttaxomatcher login`), approve
49
+ the code in the browser page it opens, and tell you when it is done. Then
50
+ run `planttaxomatcher whoami --json` again.
51
+
52
+ Never ask for, print, or pass a token on the command line. CI jobs use the
53
+ `PLANTTAXOMATCHER_TOKEN` environment variable, set by the user.
54
+
55
+ ## 2. Look at the file
56
+
57
+ Read the header row (first line of a CSV; the keys of a JSON array; the first
58
+ row of an XLSX sheet) and choose the columns:
59
+
60
+ - `--name-column` (required): the scientific name, with its author if the file has it.
61
+ - `--author-column` when authorship sits in its own column.
62
+ - `--family-column`, `--genus-column`, `--rank-column` when present: they help break ties.
63
+ - `--id-column` when rows already carry an identifier, with `--id-type wcvp` or `--id-type gbif` if you know which.
64
+
65
+ Ask the user when the name column is not obvious. Keep the defaults for
66
+ everything else unless the user asks; `references/submit-options.md` lists
67
+ every option (author handling, species-level roll-up, snapshot, row filter, LLM).
68
+
69
+ ## 3. Submit
70
+
71
+ ```bash
72
+ planttaxomatcher submit plants.csv --name-column scientific_name --no-watch --json
73
+ ```
74
+
75
+ This prints a JSON array with one job per file: `id`, `name`, `file`,
76
+ `status`, `totalRows`, `uniqueQueries`, `url`. Several paths, or a quoted glob
77
+ such as `"data/*.csv"`, create one job each. Keep the ids.
78
+
79
+ ## 4. Wait
80
+
81
+ Run `planttaxomatcher status <jobId>` (it always prints JSON) every 15 to 30
82
+ seconds until `status` is `completed`, `failed` or `cancelled`. If it is
83
+ `paused`, ask the user. Large files take minutes. The useful counts are
84
+ `totalRows`, `matchedRows`, `ambiguousRows`, `needsReviewRows` and `errorRows`.
85
+
86
+ `planttaxomatcher watch <jobId> --json` blocks until the job stops instead:
87
+ use it only when your command timeout allows.
88
+
89
+ ## 5. Download
90
+
91
+ ```bash
92
+ planttaxomatcher download <jobId> --format csv --output results.csv --json
93
+ ```
94
+
95
+ The export keeps every column of the user's file and adds `planttaxomatcher_*`
96
+ and `wcvp_*` columns; `references/results.md` explains them, the grades and the
97
+ review states. Useful options: `--confirmed-only`, `--dedupe`,
98
+ `--wcvp-extra ipni_id,powo_id`, `--format xlsx`, and `--bundle` for a ZIP with
99
+ a NOTICE.md that cites the WCVP snapshot. `--list-columns --json` shows every
100
+ available column.
101
+
102
+ ## 6. Report back
103
+
104
+ Summarise from the status counts and the export:
105
+
106
+ - rows matched and accepted automatically (grade A),
107
+ - rows waiting for review (grade B or C, ambiguous),
108
+ - rows with no match or an error, with a few examples.
109
+
110
+ Give the job's `url`: reviewing happens in the web app, not the CLI. Call a
111
+ name accepted only when `planttaxomatcher_review_status` is `not_required`,
112
+ `accepted` or `overridden`.
113
+
114
+ ## Other commands
115
+
116
+ - `planttaxomatcher list --json`: recent jobs (`--status completed`, `--limit 50`).
117
+ - `planttaxomatcher pause <jobId>`, `planttaxomatcher resume <jobId>`, `planttaxomatcher cancel <jobId>`: control a running job; each takes `--json`. Cancelling keeps the rows already matched. Ask before cancelling.
@@ -0,0 +1,55 @@
1
+ # Reading the export
2
+
3
+ Every row of the user's file comes back with its original columns, plus the
4
+ columns below. `planttaxomatcher download <jobId> --list-columns --json` lists
5
+ them all for a given job.
6
+
7
+ ## Match columns
8
+
9
+ | Column | Meaning |
10
+ | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11
+ | `planttaxomatcher_match_status` | `matched`, `ambiguous` (several candidates), `no_match`, `error`, `skipped` (filtered out by `--filter-column`, or no usable name) |
12
+ | `planttaxomatcher_grade` | `A`, `B` or `C` (see below); empty without a match |
13
+ | `planttaxomatcher_review_status` | `not_required`, `pending`, `accepted`, `rejected`, `overridden` (see below) |
14
+ | `planttaxomatcher_evidence_type` | How the match was found: `local_exact`, `local_canonical_unique`, `local_fuzzy`, `external_validated`, `external_fuzzy`, `team_history`, `cross_backbone`, `llm` |
15
+ | `planttaxomatcher_confidence` | Score between 0 and 1 |
16
+ | `planttaxomatcher_flags` | Why a match needs a look, e.g. `author-unconfirmed`, `author-mismatch` |
17
+ | `planttaxomatcher_reason` | One-line explanation of the decision |
18
+ | `planttaxomatcher_alternatives` | Other candidates, for ambiguous rows |
19
+ | `planttaxomatcher_input_normalized` | The name as matched, after cleaning |
20
+ | `planttaxomatcher_input_qualifier` | A qualifier found in the input (`cf`, `aff`, `sp`, `aggregate`…) |
21
+
22
+ ## WCVP columns
23
+
24
+ | Column | Meaning |
25
+ | ------------------------------------------------------------------------------ | -------------------------------------------------- |
26
+ | `wcvp_matched_name` | The WCVP name the input matched (may be a synonym) |
27
+ | `wcvp_matched_taxonomic_status` | Its status in WCVP: `Accepted`, `Synonym`, … |
28
+ | `wcvp_accepted_name`, `wcvp_accepted_author`, `wcvp_accepted_name_with_author` | The accepted name the match resolves to |
29
+ | `wcvp_accepted_taxon_id` | WCVP id of the accepted taxon |
30
+ | `wcvp_family`, `wcvp_rank` | Family and rank of the accepted taxon |
31
+ | `ipni_lsid`, `powo_url` | Links to IPNI and Plants of the World Online |
32
+
33
+ `--wcvp-extra` appends more WCVP fields as `wcvp_<key>`, for example
34
+ `ipni_id`, `powo_id`, `geographic_area`, `lifeform_description`,
35
+ `first_published`.
36
+
37
+ ## Grades
38
+
39
+ - **A**: a confident match: exact, or a unique name whose author is confirmed.
40
+ Accepted automatically: review status `not_required`.
41
+ - **B**: plausible, but a person should look: an author that could not be
42
+ confirmed or that disagrees, a fuzzy spelling, an external provider's
43
+ answer, or one pick among several candidates. Waits for review.
44
+ - **C**: the weakest evidence: a language-model suggestion, or only the genus
45
+ could be settled. Waits for review.
46
+
47
+ ## Review states
48
+
49
+ - `not_required`: grade A, accepted automatically.
50
+ - `pending`: waiting for a person in the web app's review queue.
51
+ - `accepted` / `rejected`: a reviewer confirmed or refused the proposed match.
52
+ - `overridden`: a reviewer picked another taxon by hand.
53
+
54
+ Only `not_required`, `accepted` and `overridden` rows carry a name the user
55
+ can rely on. `--confirmed-only` exports just those.
@@ -0,0 +1,40 @@
1
+ # `planttaxomatcher submit` options
2
+
3
+ Only `--name-column` is required. Keep the defaults unless the user asks for
4
+ something else; they are what the web app uses.
5
+
6
+ ## Columns
7
+
8
+ | Option | Use |
9
+ | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
10
+ | `--name-column <name>` | Column holding the scientific name (required) |
11
+ | `--author-column <name>` | Authorship, when it is not part of the name |
12
+ | `--family-column <name>` | Family, used to break ties between homonyms |
13
+ | `--genus-column <name>` | Genus |
14
+ | `--rank-column <name>` | Rank |
15
+ | `--id-column <name>` | An identifier the rows already carry |
16
+ | `--id-type <type>` | What `--id-column` holds: `auto` (default), `wcvp`, `gbif` |
17
+ | `--filter-column <name>` and `--filter-value <value>` | Only match rows whose column equals the value (trimmed, case-insensitive), e.g. `--filter-column kingdom --filter-value Plantae` |
18
+
19
+ ## Matching
20
+
21
+ | Option | Default | Effect |
22
+ | ------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
23
+ | `--author-mode <mode>` | `prefer` | `ignore`, `prefer` or `strict` handling of authorship |
24
+ | `--ignore-author` | off | Accept a unique name match whose author could not be confirmed, instead of sending it to review. A conflicting author still goes to review |
25
+ | `--species-level` | off | Roll varieties, subspecies and forms up to their accepted species |
26
+ | `--referential <version>` | team default | WCVP snapshot to match against, e.g. `wcvp-v14` |
27
+ | `--allow-llm` | off | Let a language model break ties between competing matches |
28
+ | `--llm-cap-cents <cents>` | `500` | Spending cap for `--allow-llm` |
29
+ | `--review-mode <mode>` | `recommended` | `off`, `recommended` or `strict` |
30
+ | `--parallel <n>` | `4` | Parallelism within the job, 1 to 10 |
31
+
32
+ ## Submission
33
+
34
+ | Option | Effect |
35
+ | ------------------------ | -------------------------------------------------------------------------------------------- |
36
+ | `--name <label>` | Job name for a single file; otherwise each job is named after its file |
37
+ | `--no-watch` | Return as soon as the jobs exist (use this, then poll `status`) |
38
+ | `--json` | Print the created jobs as a JSON array |
39
+ | `--dry-run` with `--yes` | Print a local normalisation preview of the first rows (to stderr with `--json`), then upload |
40
+ | `--dry-run-rows <n>` | How many rows the preview shows |