pm-csv 2026.6.2 → 2026.6.5
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 +29 -1
- package/README.md +136 -22
- package/dist/index.d.ts +189 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +775 -166
- package/dist/index.js.map +1 -1
- package/manifest.json +3 -3
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 2026.
|
|
3
|
+
## 2026.06.04 - 2026-06-04
|
|
4
|
+
|
|
5
|
+
### Other
|
|
6
|
+
|
|
7
|
+
- Import row-filtering \(--status/--type/--priority\) and custom-field export discovery \(--all-fields\) ([pm-csv-dk6h](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-dk6h.toon))
|
|
8
|
+
|
|
9
|
+
## 2026.06.02-1 - 2026-06-02
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Deepen SDK surface: relational columns, validate, encoding, excel, csv\_source schema field ([pm-csv-aoox](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/features/pm-csv-aoox.toon))
|
|
14
|
+
- New command: pm csv validate <file\> ([pm-csv-rq5q](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-rq5q.toon))
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Fix --key dedup duplication \(pm tag case-folding\) ([pm-csv-bvz5](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-bvz5.toon))
|
|
19
|
+
|
|
20
|
+
### Other
|
|
21
|
+
|
|
22
|
+
- validate exit-code policy ([pm-csv-yhp9](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/decisions/pm-csv-yhp9.toon))
|
|
23
|
+
- csv\_source persisted as tag, not scalar field ([pm-csv-vp1u](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/decisions/pm-csv-vp1u.toon))
|
|
24
|
+
- Which extra pm fields to round-trip ([pm-csv-ry94](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/decisions/pm-csv-ry94.toon))
|
|
25
|
+
- Unit tests + functional test with real data ([pm-csv-z5f5](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-z5f5.toon))
|
|
26
|
+
- Register csv\_source schema field \(schema capability\) ([pm-csv-w1k3](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-w1k3.toon))
|
|
27
|
+
- Export --excel \(CRLF + UTF-8 BOM\) ([pm-csv-vxz6](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-vxz6.toon))
|
|
28
|
+
- Import --encoding \(utf-8/utf16le/latin1\) ([pm-csv-z3lo](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-z3lo.toon))
|
|
29
|
+
- Round-trip parent/assignee/sprint/release/blocked\_by columns ([pm-csv-6kyh](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-6kyh.toon))
|
|
30
|
+
|
|
31
|
+
## 2026.06.02 - 2026-06-02
|
|
4
32
|
|
|
5
33
|
### Added
|
|
6
34
|
|
package/README.md
CHANGED
|
@@ -29,6 +29,11 @@ Read a CSV file and create or update pm items.
|
|
|
29
29
|
```
|
|
30
30
|
pm csv import tasks.csv
|
|
31
31
|
pm csv import backlog.csv --delimiter ';'
|
|
32
|
+
pm csv import data.tsv --delimiter tab
|
|
33
|
+
pm csv import jira.csv --map 'Summary=title,Owner=assignee'
|
|
34
|
+
pm csv import items.csv --key title # idempotent re-import (no duplicates)
|
|
35
|
+
pm csv import legacy.csv --encoding latin1 # non-UTF-8 source
|
|
36
|
+
pm csv import sprint12.csv --source 'jira-export-2026-06'
|
|
32
37
|
pm csv import items.csv --dry-run
|
|
33
38
|
```
|
|
34
39
|
|
|
@@ -36,12 +41,60 @@ pm csv import items.csv --dry-run
|
|
|
36
41
|
|
|
37
42
|
| Flag | Type | Default | Description |
|
|
38
43
|
|---|---|---|---|
|
|
39
|
-
| `--delimiter <char>` | string | `,` |
|
|
44
|
+
| `--delimiter <char>` | string | `,` | Field delimiter, or alias `tab` / `comma` / `semicolon` / `pipe` |
|
|
45
|
+
| `--map <col=field>` | string | — | Remap a CSV header to a pm field (repeatable, comma-joined), e.g. `--map 'Summary=title'` |
|
|
46
|
+
| `--key <field>` | string | — | Dedup key column: a re-import **updates** the matching item instead of creating a duplicate |
|
|
47
|
+
| `--encoding <enc>` | string | `utf-8` | Source file encoding: `utf-8` \| `utf16le` \| `latin1` |
|
|
48
|
+
| `--source <label>` | string | — | Record an import-provenance label in the `csv_source` field of created/updated items |
|
|
49
|
+
| `--status <filter>` | string | — | Import **only** rows whose (normalized) status matches; non-matching rows are skipped |
|
|
50
|
+
| `--type <type>` | string | — | Import **only** rows whose type matches (case-insensitive) |
|
|
51
|
+
| `--priority <n>` | integer | — | Import **only** rows whose integer priority equals this value |
|
|
40
52
|
| `--dry-run` | boolean | false | Preview what would be imported without writing any data |
|
|
41
53
|
|
|
54
|
+
#### Row filtering on import
|
|
55
|
+
|
|
56
|
+
`--status`, `--type` and `--priority` filter the CSV rows **before** any items
|
|
57
|
+
are created — non-matching rows are skipped, never written. They mirror the
|
|
58
|
+
`csv export` filter semantics exactly (status is normalized through the same
|
|
59
|
+
alias table, so `--status open` matches a row whose status cell is `todo`).
|
|
60
|
+
Multiple criteria are ANDed. The result reports how many rows were filtered out:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
pm csv import tasks.csv --status open # import open rows only
|
|
64
|
+
pm csv import tasks.csv --type Feature --priority 1 # AND: Feature *and* priority 1
|
|
65
|
+
# → Imported 1, updated 0, skipped 5 (5 filtered out).
|
|
66
|
+
```
|
|
67
|
+
|
|
42
68
|
**Required column:** `title`
|
|
43
69
|
|
|
44
|
-
**Optional columns:** `type`, `status`, `priority`, `tags`, `
|
|
70
|
+
**Optional columns:** `type`, `status`, `priority`, `tags`, `deadline`, `body`, `parent`, `assignee`, `sprint`, `release`, `blocked_by`
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
### `pm csv validate <file>`
|
|
75
|
+
|
|
76
|
+
Parse a CSV and report data-quality issues **without importing**. Exits non-zero
|
|
77
|
+
(usage error) when there is a structural problem (no `title` column after `--map`
|
|
78
|
+
or an empty file); otherwise exits `0` even when it reports row-level warnings.
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
pm csv validate tasks.csv
|
|
82
|
+
pm csv validate jira.csv --map 'Summary=title'
|
|
83
|
+
pm csv validate data.tsv --delimiter tab --json
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The report includes: row count, detected columns, mapped columns (after `--map`),
|
|
87
|
+
whether the required `title` column is present, and counts of rows missing a
|
|
88
|
+
title, rows with an unrecognized status, and rows with a non-integer priority.
|
|
89
|
+
|
|
90
|
+
**Flags**
|
|
91
|
+
|
|
92
|
+
| Flag | Type | Default | Description |
|
|
93
|
+
|---|---|---|---|
|
|
94
|
+
| `--delimiter <char>` | string | `,` | Field delimiter, or alias `tab` / `comma` / `semicolon` / `pipe` |
|
|
95
|
+
| `--map <col=field>` | string | — | Remap a CSV header to a pm field before validating |
|
|
96
|
+
| `--encoding <enc>` | string | `utf-8` | Source file encoding: `utf-8` \| `utf16le` \| `latin1` |
|
|
97
|
+
| `--json` | boolean | false | Emit the report as JSON |
|
|
45
98
|
|
|
46
99
|
---
|
|
47
100
|
|
|
@@ -53,8 +106,9 @@ Export all pm items (or a filtered subset) to CSV. Without `--output` the CSV is
|
|
|
53
106
|
pm csv export
|
|
54
107
|
pm csv export --output items.csv
|
|
55
108
|
pm csv export --output backlog.csv --delimiter ';'
|
|
56
|
-
pm csv export --status
|
|
109
|
+
pm csv export --status open --output todos.csv
|
|
57
110
|
pm csv export --type Feature --output features.csv
|
|
111
|
+
pm csv export --excel --output for-excel.csv
|
|
58
112
|
```
|
|
59
113
|
|
|
60
114
|
**Flags**
|
|
@@ -62,12 +116,36 @@ pm csv export --type Feature --output features.csv
|
|
|
62
116
|
| Flag | Type | Default | Description |
|
|
63
117
|
|---|---|---|---|
|
|
64
118
|
| `--output <file>` | string | — | Write CSV to this file path instead of returning it |
|
|
65
|
-
| `--delimiter <char>` | string | `,` |
|
|
66
|
-
| `--status <status>` | string | — | Filter: `
|
|
119
|
+
| `--delimiter <char>` | string | `,` | Field delimiter, or alias `tab` / `comma` / `semicolon` / `pipe` |
|
|
120
|
+
| `--status <status>` | string | — | Filter: `open` \| `in_progress` \| `blocked` \| `closed` \| `canceled` \| `draft` |
|
|
67
121
|
| `--type <type>` | string | — | Filter by item type |
|
|
122
|
+
| `--columns <list>` | string | all | Comma-separated columns to export, in order (custom fields selectable when `--all-fields` is set) |
|
|
123
|
+
| `--all-fields` | boolean | false | Discover custom item fields registered in the workspace schema and append them as columns |
|
|
124
|
+
| `--discover-fields` | boolean | false | Alias for `--all-fields` |
|
|
125
|
+
| `--no-header` | boolean | false | Omit the CSV header row |
|
|
126
|
+
| `--crlf` | boolean | false | Use CRLF line endings (RFC-4180 / Excel) |
|
|
127
|
+
| `--excel` | boolean | false | Excel-friendly output: CRLF line endings **and** a UTF-8 BOM prefix |
|
|
68
128
|
|
|
69
129
|
**Export columns (fixed order):**
|
|
70
|
-
`id, title, type, status, priority, tags,
|
|
130
|
+
`id, title, type, status, priority, tags, deadline, body, parent, assignee, sprint, release, blocked_by, csv_source, created_at, updated_at`
|
|
131
|
+
|
|
132
|
+
#### Custom-field discovery (`--all-fields`)
|
|
133
|
+
|
|
134
|
+
By default only the built-in columns above are exported. `--all-fields` (alias
|
|
135
|
+
`--discover-fields`) discovers any **custom item fields** registered in the
|
|
136
|
+
workspace runtime schema and appends them as extra columns — the default column
|
|
137
|
+
set is otherwise unchanged, so the flag is strictly additive.
|
|
138
|
+
|
|
139
|
+
Discovery reads the same inputs the SDK's `resolveRuntimeFieldRegistry` consumes
|
|
140
|
+
(the workspace `settings.json` `schema.fields` plus the file it points at via
|
|
141
|
+
`schema.files.fields`, default `schema/fields.json`). A standalone-installed
|
|
142
|
+
extension only loads its own `dist/`, so the SDK function isn't importable at
|
|
143
|
+
runtime; reading its inputs directly is the runtime-safe equivalent.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
pm csv export --all-fields --output full.csv
|
|
147
|
+
# header gains your custom columns, e.g. …,updated_at,story_points,team
|
|
148
|
+
```
|
|
71
149
|
|
|
72
150
|
---
|
|
73
151
|
|
|
@@ -94,7 +172,11 @@ Register the importer in your pm-cli config to automatically pull from a CSV fil
|
|
|
94
172
|
| Key | Type | Required | Description |
|
|
95
173
|
|---|---|---|---|
|
|
96
174
|
| `file` | string | yes | Path to the CSV file to import |
|
|
97
|
-
| `delimiter` | string | no (default `,`) | CSV field delimiter |
|
|
175
|
+
| `delimiter` | string | no (default `,`) | CSV field delimiter (or alias `tab`/`comma`/`semicolon`/`pipe`) |
|
|
176
|
+
| `map` | string | no | Header remap, e.g. `Summary=title` |
|
|
177
|
+
| `key` | string | no | Dedup key column for idempotent re-import |
|
|
178
|
+
| `encoding` | string | no (default `utf-8`) | `utf-8` \| `utf16le` \| `latin1` |
|
|
179
|
+
| `source` | string | no | Provenance label recorded in `csv_source` |
|
|
98
180
|
|
|
99
181
|
---
|
|
100
182
|
|
|
@@ -105,10 +187,10 @@ Register the importer in your pm-cli config to automatically pull from a CSV fil
|
|
|
105
187
|
The first row must be a header row. Column names are **case-insensitive**. Column order does not matter. Only `title` is required.
|
|
106
188
|
|
|
107
189
|
```csv
|
|
108
|
-
title,type,status,priority,tags,
|
|
109
|
-
"Add login page",Feature,open,2,"auth,ui",
|
|
110
|
-
"Fix navbar bug",Issue,in_progress,1,"bug,ui"
|
|
111
|
-
"Write API docs",Task,
|
|
190
|
+
title,type,status,priority,tags,deadline,body,parent,assignee,sprint,release,blocked_by
|
|
191
|
+
"Add login page",Feature,open,2,"auth,ui",2026-05-30,"Landing page with email+password login",,alice,Sprint-12,v1.0,
|
|
192
|
+
"Fix navbar bug",Issue,in_progress,1,"bug,ui",,"Navbar collapses on mobile Safari",,bob,Sprint-12,v1.0,
|
|
193
|
+
"Write API docs",Task,open,3,docs,,,,,Sprint-13,v1.1,Fix navbar bug
|
|
112
194
|
```
|
|
113
195
|
|
|
114
196
|
### Column reference
|
|
@@ -116,13 +198,19 @@ title,type,status,priority,tags,milestone,due_date,body
|
|
|
116
198
|
| Column | Description | Notes |
|
|
117
199
|
|---|---|---|
|
|
118
200
|
| `title` | Item title | **Required** |
|
|
119
|
-
| `type` | Item type | Any string, e.g. `Feature`, `
|
|
201
|
+
| `type` | Item type | Any string, e.g. `Feature`, `Issue`, `Task` |
|
|
120
202
|
| `status` | Item status | See status mapping below |
|
|
121
203
|
| `priority` | Numeric priority | Integer |
|
|
122
204
|
| `tags` | Comma-separated tags | Quote the field if tags contain commas |
|
|
123
|
-
| `
|
|
124
|
-
| `due_date` | Due date | ISO 8601 format recommended, e.g. `2026-05-30` |
|
|
205
|
+
| `deadline` | Deadline | ISO 8601, e.g. `2026-05-30` (legacy `due_date` header accepted) |
|
|
125
206
|
| `body` | Description / body text | Supports multiline when quoted |
|
|
207
|
+
| `parent` | Parent item id | Maps to `pm create --parent` |
|
|
208
|
+
| `assignee` | Assignee | Maps to `pm create --assignee` |
|
|
209
|
+
| `sprint` | Sprint identifier | Maps to `pm create --sprint` |
|
|
210
|
+
| `release` | Release identifier | Maps to `pm create --release` |
|
|
211
|
+
| `blocked_by` | Blocked-by item id or reason | Maps to `pm create --blocked-by` (legacy `blocked-by` header accepted) |
|
|
212
|
+
|
|
213
|
+
All columns except `title` are optional. Round-tripping (`export` then `import --key`) is lossless for these fields.
|
|
126
214
|
|
|
127
215
|
### Status mapping
|
|
128
216
|
|
|
@@ -130,24 +218,50 @@ The importer accepts common status strings and maps them to pm-cli statuses:
|
|
|
130
218
|
|
|
131
219
|
| Input values | pm-cli status |
|
|
132
220
|
|---|---|
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
135
|
-
| `wip`, `in_progress`, `in progress`, `doing` | `wip` |
|
|
221
|
+
| `open`, `todo`, `new` | `open` |
|
|
222
|
+
| `in_progress`, `wip`, `in progress`, `doing` | `in_progress` |
|
|
136
223
|
| `blocked`, `on_hold`, `on hold` | `blocked` |
|
|
224
|
+
| `closed`, `done`, `complete`, `completed` | `closed` |
|
|
225
|
+
| `canceled`, `cancelled` | `canceled` |
|
|
226
|
+
| `draft` | `draft` |
|
|
137
227
|
|
|
138
|
-
Unrecognized values default to `
|
|
228
|
+
Unrecognized values default to `open`.
|
|
139
229
|
|
|
140
230
|
### Export format
|
|
141
231
|
|
|
142
|
-
Exports use the same CSV format and can be re-imported
|
|
232
|
+
Exports use the same CSV format and can be re-imported. An extra read-only
|
|
233
|
+
`csv_source` column surfaces the import-provenance label (see `--source`); it is
|
|
234
|
+
ignored on import.
|
|
143
235
|
|
|
144
236
|
```csv
|
|
145
|
-
id,title,type,status,priority,tags,
|
|
146
|
-
|
|
237
|
+
id,title,type,status,priority,tags,deadline,body,parent,assignee,sprint,release,blocked_by,csv_source,created_at,updated_at
|
|
238
|
+
pm-abc123,Add login page,Feature,open,2,"auth,ui",2026-05-30,Landing page,,alice,Sprint-12,v1.0,,jira-export,2026-05-01T10:00:00Z,2026-05-09T12:00:00Z
|
|
147
239
|
```
|
|
148
240
|
|
|
149
241
|
---
|
|
150
242
|
|
|
243
|
+
## Idempotent re-import (`--key`)
|
|
244
|
+
|
|
245
|
+
`--key <field>` makes re-imports update existing items instead of creating
|
|
246
|
+
duplicates. The first import tags each created item with an internal
|
|
247
|
+
`csv-key:<value>` provenance tag; a later import keyed on the same column finds
|
|
248
|
+
and updates the matching item. Key matching is case-insensitive (pm folds tag
|
|
249
|
+
case on storage). The internal `csv-key:` and `csv-source:` tags are stripped
|
|
250
|
+
from exports so round-trips stay clean.
|
|
251
|
+
|
|
252
|
+
## Provenance & the `csv_source` schema field (`--source`)
|
|
253
|
+
|
|
254
|
+
The extension registers an optional `csv_source` schema item field (via the
|
|
255
|
+
`schema` capability). When you import with `--source <label>`, the label is
|
|
256
|
+
recorded on each created/updated item and is surfaced back in the `csv_source`
|
|
257
|
+
export column. Note: as of pm 2026.5.31 the CLI does not expose a scalar setter
|
|
258
|
+
for extension-registered fields, so the value is persisted as an internal
|
|
259
|
+
`csv-source:<label>` tag (stripped from the normal `tags` export column). On
|
|
260
|
+
hosts whose SDK lacks `registerItemFields`, schema registration degrades to a
|
|
261
|
+
no-op without breaking any other behavior.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
151
265
|
## CSV parsing rules
|
|
152
266
|
|
|
153
267
|
- Fields containing the delimiter, double-quotes, or newlines must be wrapped in double-quotes.
|
|
@@ -178,7 +292,7 @@ pm csv export --columns id,title,status --output todos.csv
|
|
|
178
292
|
pm csv-export export --columns title,priority # native export pipeline
|
|
179
293
|
```
|
|
180
294
|
|
|
181
|
-
Valid columns: id, title, type, status, priority, tags, deadline, body, created_at, updated_at.
|
|
295
|
+
Valid columns: id, title, type, status, priority, tags, deadline, body, parent, assignee, sprint, release, blocked_by, csv_source, created_at, updated_at.
|
|
182
296
|
|
|
183
297
|
## License
|
|
184
298
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,196 @@
|
|
|
1
|
+
type ItemStatus = "open" | "in_progress" | "blocked" | "closed" | "canceled" | "draft";
|
|
2
|
+
interface PmItem {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
body?: string;
|
|
6
|
+
status: ItemStatus;
|
|
7
|
+
priority?: number;
|
|
8
|
+
type?: string;
|
|
9
|
+
tags?: string[];
|
|
10
|
+
created_at?: string;
|
|
11
|
+
updated_at?: string;
|
|
12
|
+
deadline?: string;
|
|
13
|
+
parent?: string;
|
|
14
|
+
assignee?: string;
|
|
15
|
+
sprint?: string;
|
|
16
|
+
release?: string;
|
|
17
|
+
blocked_by?: string;
|
|
18
|
+
/** Derived on export from the csv-source: provenance tag (not a stored field). */
|
|
19
|
+
csv_source?: string;
|
|
20
|
+
}
|
|
21
|
+
declare const IMPORT_COLUMNS: readonly ["title", "type", "status", "priority", "tags", "deadline", "body", "parent", "assignee", "sprint", "release", "blocked_by"];
|
|
22
|
+
declare const EXPORT_COLUMNS: Array<keyof PmItem>;
|
|
23
|
+
/** Supported file encodings for `--encoding` on import. */
|
|
24
|
+
declare const SUPPORTED_ENCODINGS: readonly ["utf-8", "utf8", "utf16le", "latin1"];
|
|
25
|
+
type SupportedEncoding = (typeof SUPPORTED_ENCODINGS)[number];
|
|
26
|
+
/**
|
|
27
|
+
* Parse a full CSV string into rows of string arrays.
|
|
28
|
+
* Handles:
|
|
29
|
+
* - Quoted fields (double-quotes), including embedded newlines inside quotes
|
|
30
|
+
* - Escaped quotes ("" inside a quoted field → single ")
|
|
31
|
+
* - Custom delimiter
|
|
32
|
+
* - CRLF and LF line endings
|
|
33
|
+
*/
|
|
34
|
+
declare function parseCSV(text: string, delimiter?: string): string[][];
|
|
35
|
+
/**
|
|
36
|
+
* Strip a leading UTF-8 BOM (U+FEFF) if present. Files exported by Excel and
|
|
37
|
+
* many Windows tools start with a BOM; without removing it the first header
|
|
38
|
+
* name silently becomes "title" and the required-column check fails.
|
|
39
|
+
*/
|
|
40
|
+
declare function stripBOM(text: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Serialize a single field value for CSV output.
|
|
43
|
+
* Wraps in double-quotes when the value contains the delimiter, quotes, or newlines.
|
|
44
|
+
*/
|
|
45
|
+
declare function serializeField(value: string, delimiter: string): string;
|
|
46
|
+
interface SerializeOptions {
|
|
47
|
+
delimiter: string;
|
|
48
|
+
/** Line terminator. RFC-4180 mandates CRLF; we default to LF for unix-friendliness. */
|
|
49
|
+
eol?: "\n" | "\r\n";
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Serialize a full array of rows into a CSV string.
|
|
53
|
+
*/
|
|
54
|
+
declare function serializeCSV(rows: string[][], delimiterOrOpts: string | SerializeOptions): string;
|
|
55
|
+
/**
|
|
56
|
+
* Resolve a user-supplied delimiter, accepting friendly aliases so TSV is easy:
|
|
57
|
+
* --delimiter tab --delimiter "\t" --delimiter ";"
|
|
58
|
+
* A literal backslash-t is interpreted as a tab.
|
|
59
|
+
*/
|
|
60
|
+
declare function resolveDelimiter(raw: string | undefined): string;
|
|
61
|
+
/**
|
|
62
|
+
* Normalize a dedup key value for stable matching. pm lower-cases tags on
|
|
63
|
+
* storage, so a `csv-key:` tag written from "Fix Bug" comes back as
|
|
64
|
+
* "fix bug"; we therefore fold the key to lower-case on BOTH write and lookup
|
|
65
|
+
* so re-imports match (and thus update) instead of duplicating.
|
|
66
|
+
*/
|
|
67
|
+
declare function normalizeKeyValue(value: string): string;
|
|
68
|
+
declare function encodeKeyTagValue(value: string): string;
|
|
69
|
+
declare function decodeKeyTagValue(value: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* Parse a `--map csvHeader=field` spec (repeatable / comma-joined) into a
|
|
72
|
+
* lookup from a normalized CSV header name to the canonical pm field name.
|
|
73
|
+
* Example: `--map "Summary=title,Owner=tags"`.
|
|
74
|
+
*/
|
|
75
|
+
declare function parseFieldMap(spec: string | string[] | undefined): Record<string, string>;
|
|
76
|
+
/**
|
|
77
|
+
* Apply a field map to a list of header names, producing the effective
|
|
78
|
+
* (canonical) header used for column lookup.
|
|
79
|
+
*/
|
|
80
|
+
declare function applyFieldMap(headers: string[], fieldMap: Record<string, string>): string[];
|
|
81
|
+
/**
|
|
82
|
+
* Map an arbitrary status string (from the CSV) to a valid SDK status.
|
|
83
|
+
* Falls back to "open".
|
|
84
|
+
*/
|
|
85
|
+
declare function normalizeStatus(raw: string): ItemStatus;
|
|
86
|
+
/**
|
|
87
|
+
* Parse a comma-separated tags string into an array, stripping whitespace.
|
|
88
|
+
*/
|
|
89
|
+
declare function parseTags(raw: string): string[];
|
|
90
|
+
/**
|
|
91
|
+
* Stringify a tags array back to a semicolon-free comma-separated string
|
|
92
|
+
* (safe to embed in a single CSV field).
|
|
93
|
+
*/
|
|
94
|
+
declare function stringifyTags(tags: string[] | undefined): string;
|
|
95
|
+
/**
|
|
96
|
+
* Validate and normalize a user-supplied `--encoding` value to a Node-supported
|
|
97
|
+
* BufferEncoding. Accepts utf-8/utf8, utf16le, latin1. Throws USAGE otherwise.
|
|
98
|
+
*/
|
|
99
|
+
declare function resolveEncoding(raw: string | undefined): SupportedEncoding;
|
|
100
|
+
/**
|
|
101
|
+
* Row-level import filter. Mirrors the `csv export` filter semantics exactly:
|
|
102
|
+
* - `status` matches the row's *normalized* SDK status (so `done` matches
|
|
103
|
+
* `--status closed`, just like export filters on the stored status).
|
|
104
|
+
* - `type` matches the row's raw `type` value case-insensitively.
|
|
105
|
+
* - `priority` matches the row's parsed integer priority.
|
|
106
|
+
* Any unset criterion is a wildcard. Rows that fail are skipped (not imported)
|
|
107
|
+
* and counted in the result's `skipped` total.
|
|
108
|
+
*/
|
|
109
|
+
interface ImportRowFilter {
|
|
110
|
+
status?: ItemStatus;
|
|
111
|
+
type?: string;
|
|
112
|
+
priority?: number;
|
|
113
|
+
}
|
|
114
|
+
interface ParsedRow {
|
|
115
|
+
title: string;
|
|
116
|
+
status: ItemStatus;
|
|
117
|
+
priority?: number;
|
|
118
|
+
tags: string[];
|
|
119
|
+
type?: string;
|
|
120
|
+
deadline?: string;
|
|
121
|
+
body?: string;
|
|
122
|
+
parent?: string;
|
|
123
|
+
assignee?: string;
|
|
124
|
+
sprint?: string;
|
|
125
|
+
release?: string;
|
|
126
|
+
blocked_by?: string;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Parse the `--status`/`--type`/`--priority` import filter flags into a
|
|
130
|
+
* normalized {@link ImportRowFilter}. Mirrors export filter semantics:
|
|
131
|
+
* - status is normalized through {@link normalizeStatus} so the same alias
|
|
132
|
+
* vocabulary as a CSV `status` cell applies (e.g. `--status done` matches
|
|
133
|
+
* rows whose status normalizes to `closed`).
|
|
134
|
+
* - priority must be an integer; a non-integer is a USAGE error.
|
|
135
|
+
* - type is matched case-insensitively (lower-cased here and at compare time).
|
|
136
|
+
* Returns `undefined` when no filter flag is set (the common no-filter path).
|
|
137
|
+
*/
|
|
138
|
+
declare function parseImportFilter(statusRaw: string | undefined, typeRaw: string | undefined, priorityRaw: string | undefined): ImportRowFilter | undefined;
|
|
139
|
+
/**
|
|
140
|
+
* Pure predicate: does a parsed row satisfy every set filter criterion?
|
|
141
|
+
* Unset criteria are wildcards. Exposed for unit testing.
|
|
142
|
+
*/
|
|
143
|
+
declare function rowMatchesFilter(row: ParsedRow, filter: ImportRowFilter | undefined): boolean;
|
|
144
|
+
interface CsvValidateReport {
|
|
145
|
+
ok: boolean;
|
|
146
|
+
rowCount: number;
|
|
147
|
+
detectedColumns: string[];
|
|
148
|
+
mappedColumns: string[];
|
|
149
|
+
hasTitleColumn: boolean;
|
|
150
|
+
rowsMissingTitle: number;
|
|
151
|
+
rowsWithUnknownStatus: number;
|
|
152
|
+
rowsWithNonIntegerPriority: number;
|
|
153
|
+
issues: string[];
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Core validation logic over already-parsed headers + rows. Pure and
|
|
157
|
+
* side-effect-free so it can be unit tested directly.
|
|
158
|
+
*/
|
|
159
|
+
declare function validateParsedCSV(rawHeaders: string[], dataRows: string[][], fieldMap: Record<string, string>): CsvValidateReport;
|
|
160
|
+
/**
|
|
161
|
+
* A custom (workspace-registered) item field discovered from the runtime
|
|
162
|
+
* schema. `key` is the human-facing column name; `metadataKey` is the property
|
|
163
|
+
* name the value is stored under on the item JSON (usually identical).
|
|
164
|
+
*/
|
|
165
|
+
interface DiscoveredField {
|
|
166
|
+
key: string;
|
|
167
|
+
metadataKey: string;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Discover custom item fields registered in the workspace runtime schema and
|
|
171
|
+
* return those that are NOT already covered by the built-in export columns
|
|
172
|
+
* (or the provenance `csv_source` column).
|
|
173
|
+
*
|
|
174
|
+
* This is the standalone-extension-safe equivalent of the SDK's
|
|
175
|
+
* `resolveRuntimeFieldRegistry(settings.schema)`: a standalone-installed
|
|
176
|
+
* extension only loads its own `dist/`, so `@unbrained/pm-cli` is not
|
|
177
|
+
* resolvable at runtime and the SDK function cannot be imported. We instead
|
|
178
|
+
* read the very same inputs that function consumes — the workspace
|
|
179
|
+
* `settings.json` `schema.fields` plus the file it points at
|
|
180
|
+
* (`schema.files.fields`, default `schema/fields.json`) — and merge them by
|
|
181
|
+
* field key. The shape matches the SDK `RuntimeFieldDefinition` type.
|
|
182
|
+
*
|
|
183
|
+
* Never throws: any read/parse problem yields an empty list so export still
|
|
184
|
+
* works on hosts without a runtime field schema.
|
|
185
|
+
*/
|
|
186
|
+
declare function discoverCustomFields(pmRoot: string): DiscoveredField[];
|
|
187
|
+
declare function selectExportColumns(spec: string | undefined, extraValid?: ReadonlyArray<string>): string[];
|
|
1
188
|
declare const _default: {
|
|
2
189
|
name: string;
|
|
3
190
|
version: string;
|
|
4
191
|
activate(api: import("@unbrained/pm-cli/sdk").ExtensionApi): void;
|
|
5
192
|
};
|
|
6
193
|
export default _default;
|
|
194
|
+
export { parseCSV, serializeCSV, serializeField, stripBOM, resolveDelimiter, parseFieldMap, applyFieldMap, normalizeStatus, parseTags, stringifyTags, encodeKeyTagValue, decodeKeyTagValue, normalizeKeyValue, selectExportColumns, resolveEncoding, validateParsedCSV, parseImportFilter, rowMatchesFilter, discoverCustomFields, EXPORT_COLUMNS, IMPORT_COLUMNS, };
|
|
195
|
+
export type { ParsedRow, ImportRowFilter, DiscoveredField };
|
|
7
196
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|