zinkee 0.1.44 → 0.1.46

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.
Files changed (94) hide show
  1. package/README.md +4 -0
  2. package/dist/chunk-MHEVRMDX.js +1230 -0
  3. package/dist/chunk-MHEVRMDX.js.map +1 -0
  4. package/{src/utils/examples.ts → dist/examples-67U5IRBS.js} +866 -1141
  5. package/dist/examples-67U5IRBS.js.map +1 -0
  6. package/dist/index.js +1145 -8456
  7. package/dist/index.js.map +1 -1
  8. package/package.json +6 -3
  9. package/.github/workflows/npm-publish.yml +0 -77
  10. package/.github/workflows/pr-checks.yml +0 -36
  11. package/AGENTS.md +0 -110
  12. package/docs/cli-contract.md +0 -41
  13. package/docs/npm-release.md +0 -64
  14. package/docs/superpowers/plans/2026-03-24-zinkee-cli-implementation.md +0 -837
  15. package/docs/superpowers/plans/2026-03-25-cli-backend-error-contract.md +0 -503
  16. package/docs/superpowers/plans/2026-03-26-display-freeform-create.md +0 -389
  17. package/docs/superpowers/specs/2026-03-24-zinkee-cli-backend-blockers.md +0 -172
  18. package/docs/superpowers/specs/2026-03-24-zinkee-cli-design.md +0 -1576
  19. package/docs/superpowers/specs/2026-03-24-zinkee-cli-e2e-checklist.md +0 -215
  20. package/docs/superpowers/specs/2026-03-24-zinkee-cli-e2e-design.md +0 -492
  21. package/docs/superpowers/specs/2026-03-24-zinkee-cli-e2e-status.md +0 -307
  22. package/docs/superpowers/specs/2026-07-30-cli-pr-checks-design.md +0 -37
  23. package/src/api/automations.ts +0 -404
  24. package/src/api/comments.ts +0 -51
  25. package/src/api/displays.ts +0 -337
  26. package/src/api/document-templates.ts +0 -110
  27. package/src/api/files.ts +0 -50
  28. package/src/api/formulas.test.ts +0 -65
  29. package/src/api/formulas.ts +0 -67
  30. package/src/api/logs.ts +0 -34
  31. package/src/api/navigation.ts +0 -70
  32. package/src/api/records.ts +0 -184
  33. package/src/api/schemas.ts +0 -148
  34. package/src/api/teamspace.ts +0 -110
  35. package/src/cli-examples.ts +0 -130
  36. package/src/cli-runner.ts +0 -95
  37. package/src/client.test.ts +0 -189
  38. package/src/client.ts +0 -269
  39. package/src/command-registry.ts +0 -882
  40. package/src/commands/automations.test.ts +0 -1030
  41. package/src/commands/automations.ts +0 -2102
  42. package/src/commands/comments.test.ts +0 -214
  43. package/src/commands/comments.ts +0 -303
  44. package/src/commands/config.test.ts +0 -81
  45. package/src/commands/config.ts +0 -150
  46. package/src/commands/displays.test.ts +0 -1105
  47. package/src/commands/displays.ts +0 -1442
  48. package/src/commands/document-templates.test.ts +0 -569
  49. package/src/commands/document-templates.ts +0 -563
  50. package/src/commands/files.test.ts +0 -284
  51. package/src/commands/files.ts +0 -280
  52. package/src/commands/formulas.test.ts +0 -194
  53. package/src/commands/formulas.ts +0 -243
  54. package/src/commands/logs.test.ts +0 -123
  55. package/src/commands/logs.ts +0 -159
  56. package/src/commands/navigation.test.ts +0 -211
  57. package/src/commands/navigation.ts +0 -348
  58. package/src/commands/profiles.test.ts +0 -191
  59. package/src/commands/profiles.ts +0 -303
  60. package/src/commands/records.test.ts +0 -860
  61. package/src/commands/records.ts +0 -883
  62. package/src/commands/schemas.test.ts +0 -1252
  63. package/src/commands/schemas.ts +0 -890
  64. package/src/commands/teamspace.test.ts +0 -229
  65. package/src/commands/teamspace.ts +0 -546
  66. package/src/completion/engine.test.ts +0 -138
  67. package/src/completion/engine.ts +0 -168
  68. package/src/completion/install.test.ts +0 -179
  69. package/src/completion/install.ts +0 -260
  70. package/src/completion/runtime.ts +0 -150
  71. package/src/completion/scripts.ts +0 -91
  72. package/src/config.test.ts +0 -362
  73. package/src/config.ts +0 -294
  74. package/src/index.test.ts +0 -217
  75. package/src/index.ts +0 -8
  76. package/src/parsers/expressions.test.ts +0 -95
  77. package/src/parsers/expressions.ts +0 -128
  78. package/src/parsers/kv.test.ts +0 -35
  79. package/src/parsers/kv.ts +0 -49
  80. package/src/parsers/selectors.test.ts +0 -23
  81. package/src/parsers/selectors.ts +0 -29
  82. package/src/program.ts +0 -64
  83. package/src/runtime-context.ts +0 -103
  84. package/src/types.ts +0 -76
  85. package/src/utils/argv-rewrite.test.ts +0 -149
  86. package/src/utils/argv-rewrite.ts +0 -269
  87. package/src/utils/errors.test.ts +0 -85
  88. package/src/utils/errors.ts +0 -191
  89. package/src/utils/examples.test.ts +0 -374
  90. package/src/utils/output.test.ts +0 -65
  91. package/src/utils/output.ts +0 -154
  92. package/src/utils/schema-fields.ts +0 -1016
  93. package/tsconfig.json +0 -20
  94. package/tsup.config.ts +0 -13
@@ -1,1576 +0,0 @@
1
- # Zinkee CLI Design
2
-
3
- ## Context
4
-
5
- This repository will host a new CLI for Zinkee that replaces a previous, outdated CLI.
6
-
7
- The new CLI must:
8
-
9
- - target Zinkee Public API v2
10
- - be designed for general users but especially optimized for AI agents
11
- - follow the same stack and a very similar project structure to the reference CLI in `/Users/david/dev/pichardo-projects/store-manager`
12
- - preserve compatibility with the existing user configuration file at `/Users/david/.config/zinkee/config.toml`
13
-
14
- This document captures the design decisions agreed during the analysis and specification phase before implementation starts.
15
-
16
- ## Source References
17
-
18
- Primary references used for this design:
19
-
20
- - Reference CLI: `/Users/david/dev/pichardo-projects/store-manager`
21
- - Zinkee backend API v2: `/Users/david/dev/z2/z2-backend/api`
22
- - Public docs: `doc.zinkee.com`
23
-
24
- ## Design Direction
25
-
26
- The CLI will be:
27
-
28
- - resource-oriented, not endpoint-oriented
29
- - complete across all Zinkee API v2 domains
30
- - optimized for legible command flags first
31
- - compatible with advanced JSON payload injection where needed
32
- - safe to run in read-only environments used by AI agents
33
-
34
- The implementation may later be executed by domain, but the specification covers the full CLI surface from the start.
35
-
36
- ## Global Contract
37
-
38
- ### Command Shape
39
-
40
- The CLI will use this general structure:
41
-
42
- ```bash
43
- zinkee [global-options] <domain> <command> [args] [options]
44
- ```
45
-
46
- ### Top-Level Domains
47
-
48
- Proposed top-level command groups:
49
-
50
- - `config`
51
- - `profiles`
52
- - `schemas`
53
- - `records`
54
- - `comments`
55
- - `files`
56
- - `navigation`
57
- - `teamspace`
58
- - `displays`
59
- - `automations`
60
-
61
- ### Global Options
62
-
63
- Initial global options agreed so far:
64
-
65
- - `--profile <name>`: select a profile from config
66
- - `--base-url <url>`: override the profile base URL for the current invocation
67
- - `--api-key <token>`: override the profile API key for the current invocation
68
- - `--json`: return stable JSON output for agents
69
- - `--read-only`: block any command classified as write or destructive
70
- - `--verbose`: show richer operational context
71
- - `--debug`: print low-level debugging context
72
- - `--no-color`: disable colored terminal output
73
-
74
- ### Output Model
75
-
76
- Agreed output behavior:
77
-
78
- - default output format is `table`
79
- - `--json` enables stable machine-readable output for agents
80
- - JSON output should prefer a stable envelope over raw backend passthrough
81
-
82
- Target JSON shape:
83
-
84
- ```json
85
- {
86
- "data": {},
87
- "meta": {}
88
- }
89
- ```
90
-
91
- The exact envelope can be refined later, but the contract should remain stable for agents.
92
-
93
- ### Examples
94
-
95
- The CLI should expose example usage directly from commands.
96
-
97
- Agreed convention:
98
-
99
- - `--help` explains the command contract
100
- - `--example` prints one or more realistic command examples
101
- - `--json --example` should return examples in a structured format suitable for agents
102
-
103
- Rules:
104
-
105
- - every command should have at least one example
106
- - complex commands should expose multiple examples
107
- - examples should use realistic values instead of placeholder noise
108
-
109
- ## Configuration Compatibility
110
-
111
- The new CLI must preserve compatibility with the existing config file:
112
-
113
- - `/Users/david/.config/zinkee/config.toml`
114
-
115
- Observed current shape:
116
-
117
- ```toml
118
- default_profile = "default"
119
-
120
- [profiles.default]
121
- api_key = ""
122
-
123
- [profiles.local]
124
- api_key = "..."
125
- base_url = "http://localhost:8088"
126
- ```
127
-
128
- ### Compatibility Rules
129
-
130
- Agreed rules:
131
-
132
- - the current TOML format must continue working without migration
133
- - new optional keys may be added in the future
134
- - existing keys must not be broken or reinterpreted incompatibly
135
- - `default_profile` remains the default profile selector
136
-
137
- The new CLI may extend the config format with optional fields later, but backward compatibility is mandatory.
138
-
139
- ## Read-Only Execution Model
140
-
141
- AI agents are expected to run the CLI in read-only mode in many deployments.
142
-
143
- The agreed design is:
144
-
145
- - read-only is an execution context, not a persisted profile property
146
- - it should be enabled globally per invocation
147
- - it should not be stored in `config.toml`
148
-
149
- ### Read-Only Activation
150
-
151
- Agreed activation mechanisms:
152
-
153
- - global CLI flag: `--read-only`
154
- - optional environment variable: `ZINKEE_READ_ONLY=1`
155
-
156
- Resolution precedence:
157
-
158
- 1. CLI flag
159
- 2. environment variable
160
- 3. default behavior: read-write
161
-
162
- ### Command Access Levels
163
-
164
- Every command will be classified internally as one of:
165
-
166
- - `read`
167
- - `write`
168
- - `destructive`
169
-
170
- Behavior:
171
-
172
- - read-only mode allows only `read`
173
- - `write` and `destructive` commands fail before calling the API
174
-
175
- Example error:
176
-
177
- ```text
178
- Error: Command "records create" is not allowed in read-only mode.
179
- ```
180
-
181
- Example JSON error:
182
-
183
- ```json
184
- {
185
- "error": {
186
- "code": "command_not_allowed_in_read_only_mode",
187
- "message": "Command \"records create\" is not allowed in read-only mode.",
188
- "commandMode": "write",
189
- "executionMode": "read-only"
190
- }
191
- }
192
- ```
193
-
194
- ## UX Philosophy
195
-
196
- Core UX decisions agreed so far:
197
-
198
- - the primary interface should use legible flags
199
- - `--raw` is a fallback for advanced or highly structured payloads
200
- - the CLI should optimize for agent clarity, not just HTTP completeness
201
- - the CLI should be complete across all supported v2 domains
202
- - there is no rush to ship a partial CLI if the contract is not well designed yet
203
-
204
- ## Pending Sections
205
-
206
- The following sections still need to be specified in detail:
207
-
208
- - examples policy per domain
209
- - implementation phasing by domain
210
-
211
- ## Domain Surface: Core Resources
212
-
213
- This section defines the first functional block of the CLI contract:
214
-
215
- - `config`
216
- - `profiles`
217
- - `schemas`
218
- - `records`
219
- - `comments`
220
-
221
- These domains establish the naming and command patterns that the rest of the CLI should follow.
222
-
223
- ### Profiles and Config
224
-
225
- The CLI should separate profile management from generic configuration utilities.
226
-
227
- #### `profiles`
228
-
229
- Proposed commands:
230
-
231
- - `profiles list`
232
- - `profiles get <profile>`
233
- - `profiles use <profile>`
234
- - `profiles add <profile> --api-key <token> [--base-url <url>]`
235
- - `profiles update <profile> [--api-key <token>] [--base-url <url>]`
236
- - `profiles remove <profile>`
237
-
238
- Responsibilities:
239
-
240
- - manage `profiles.<name>` blocks in `config.toml`
241
- - update `default_profile` when `profiles use` is called
242
- - preserve backward compatibility with the existing TOML shape
243
-
244
- #### `config`
245
-
246
- Proposed commands:
247
-
248
- - `config path`
249
- - `config show`
250
- - `config validate`
251
-
252
- Responsibilities:
253
-
254
- - `config path`: print the effective config file path
255
- - `config show`: print the resolved config with secrets redacted by default
256
- - `config validate`: verify that the TOML is parseable and contains a resolvable profile configuration
257
-
258
- ### Schemas
259
-
260
- The `schemas` domain should expose both schema management and field management.
261
-
262
- #### Schema Commands
263
-
264
- Proposed commands:
265
-
266
- - `schemas list`
267
- - `schemas get <schema>`
268
- - `schemas create --name <name> --slug <slug> [--auditable] [--commentable]`
269
- - `schemas update <schema> [--name <name>] [--slug <slug>] [--auditable <bool>] [--commentable <bool>]`
270
- - `schemas delete <schema>`
271
-
272
- #### Schema Field Commands
273
-
274
- Proposed commands:
275
-
276
- - `schemas fields list <schema>`
277
- - `schemas fields get <schema> <field>`
278
- - `schemas fields create <schema> --type <type> --slug <slug> --label <label> [field-config-options]`
279
- - `schemas fields update <schema> <field> [--label <label>] [--required <bool>] [field-config-options]`
280
- - `schemas fields delete <schema> <field>`
281
-
282
- #### Identifier Rules
283
-
284
- Agreed identifier resolution rules:
285
-
286
- - `<schema>` should accept either UUID or slug
287
- - `<field>` should accept either UUID or slug
288
- - if the value parses as UUID, resolve as UUID
289
- - otherwise resolve as slug
290
-
291
- This makes the CLI friendlier than a UUID-only interface while preserving direct access to exact identifiers.
292
-
293
- ### Records
294
-
295
- Although records are nested under schemas in the HTTP API, the CLI should expose them as a top-level domain because they are a primary workflow surface for both users and agents.
296
-
297
- #### Record Commands
298
-
299
- Proposed commands:
300
-
301
- - `records list <schema>`
302
- - `records query <schema>`
303
- - `records get <schema> <record>`
304
- - `records create <schema> ...`
305
- - `records update <schema> <record> ...`
306
- - `records delete <schema> <record>`
307
-
308
- #### `records list`
309
-
310
- `records list` should provide a lightweight listing/query surface for common use cases.
311
-
312
- Proposed flags:
313
-
314
- - `--select <fields>` where fields are comma-separated
315
- - `--sort <field:direction>`
316
- - `--limit <n>`
317
- - `--offset <n>`
318
-
319
- #### `records query`
320
-
321
- `records query` should be the richer query surface for advanced search and filtering.
322
-
323
- Proposed flags:
324
-
325
- - `--select <fields>`
326
- - `--where <expression>` repeatable
327
- - `--sort <field:direction>` repeatable or comma-separated
328
- - `--limit <n>`
329
- - `--offset <n>`
330
- - `--raw <json>`
331
- - `--raw-file <path>`
332
-
333
- Example expressions to support:
334
-
335
- - `--where "status eq active"`
336
- - `--where "email contains @acme.com"`
337
- - `--where "amount gt 1000"`
338
- - `--where "closedAt is-null"`
339
- - `--where "ownerId in a,b,c"`
340
-
341
- `records list` and `records query` should share the same internal execution path, with `list` acting as the simpler contract.
342
-
343
- #### `records get`
344
-
345
- Proposed command:
346
-
347
- - `records get <schema> <record>`
348
-
349
- Identifier rule:
350
-
351
- - `<record>` should be treated as UUID
352
-
353
- #### `records create`
354
-
355
- The main interface should be based on repeatable field assignment flags rather than requiring raw JSON for every write.
356
-
357
- Agreed write interface:
358
-
359
- - `--set <field=value>` repeatable
360
- - `--set-json <field=json>` repeatable
361
- - `--raw <json>`
362
- - `--raw-file <path>`
363
-
364
- Example:
365
-
366
- ```bash
367
- zinkee records create contacts --set name="Ana" --set email="ana@acme.com"
368
- ```
369
-
370
- #### `records update`
371
-
372
- The update interface should support assignment, removal, and structured values.
373
-
374
- Agreed update interface:
375
-
376
- - `--set <field=value>` repeatable
377
- - `--set-json <field=json>` repeatable
378
- - `--unset <field>` repeatable
379
- - `--raw <json>`
380
- - `--raw-file <path>`
381
-
382
- Example:
383
-
384
- ```bash
385
- zinkee records update contacts 550e8400-e29b-41d4-a716-446655440000 --set status=active --unset legacyCode
386
- ```
387
-
388
- #### `records delete`
389
-
390
- Proposed command:
391
-
392
- - `records delete <schema> <record>`
393
-
394
- ### Comments
395
-
396
- Comments should be exposed as a top-level domain, while still following the schema/record context model of the backend.
397
-
398
- #### Comment Commands
399
-
400
- Proposed commands:
401
-
402
- - `comments list <schema> <record>`
403
- - `comments create <schema> <record> --text <text>`
404
-
405
- #### Comment Write Contract
406
-
407
- The initial user-friendly interface should be text-first:
408
-
409
- - `--text <text>` for standard comments
410
- - `--raw <json>` and `--raw-file <path>` for future typed content extensions
411
-
412
- This keeps the common case simple while preserving compatibility with richer comment payloads if the backend evolves.
413
-
414
- ### Naming Conventions Agreed in This Section
415
-
416
- The following naming rules are now part of the design:
417
-
418
- - prefer simple verbs: `list`, `get`, `create`, `update`, `delete`
419
- - use `query` only for operations that are materially richer than `list`
420
- - accept friendly selectors such as slugs wherever the domain supports them
421
- - avoid mirroring awkward HTTP route naming when a clearer CLI contract exists
422
-
423
- ## Domain Surface: Files, Navigation, Teamspace
424
-
425
- This section defines the next functional block:
426
-
427
- - `files`
428
- - `navigation`
429
- - `teamspace`
430
-
431
- These domains mix CRUD operations with more action-oriented workflows such as moving, publishing, unpublishing, and downloading.
432
-
433
- ### Files
434
-
435
- The backend exposes upload, storage info, download, and delete capabilities. The CLI should model them in a more intention-oriented shape.
436
-
437
- #### File Commands
438
-
439
- Proposed commands:
440
-
441
- - `files upload <path>`
442
- - `files download <file> [--output <path>]`
443
- - `files delete <file>`
444
- - `files storage`
445
-
446
- #### File Design Rules
447
-
448
- Agreed rules:
449
-
450
- - `<file>` should accept UUID
451
- - `files upload <path>` is the canonical upload form
452
- - `files storage` is preferred over a more HTTP-shaped name like `storage-info`
453
-
454
- Reasoning:
455
-
456
- - `files download` should represent binary content retrieval
457
- - the CLI should not blur binary download behavior into normal JSON output semantics
458
-
459
- #### Binary Output Rule
460
-
461
- When `files download` is used:
462
-
463
- - default behavior should write bytes to stdout or to a provided output path, depending on the final CLI policy chosen later
464
- - `--json` should not emit raw binary
465
- - if needed, `--json` should require `--output` and return structured metadata about the download result
466
-
467
- ### Navigation
468
-
469
- The navigation domain represents internal workspace organization.
470
-
471
- The CLI should structure it around folders and resource moves rather than around backend payload shapes.
472
-
473
- #### Navigation Commands
474
-
475
- Proposed commands:
476
-
477
- - `navigation folders list`
478
- - `navigation folders get <folder>`
479
- - `navigation folders create --name <name> [--order <n>] [--props <json>]`
480
- - `navigation folders update <folder> [--name <name>] [--order <n>] [--props <json>]`
481
- - `navigation folders delete <folder>`
482
- - `navigation resources move <resource> --type <type> --to <folder>`
483
-
484
- #### Navigation Design Rules
485
-
486
- Agreed rules:
487
-
488
- - expose `folders` and `resources` as explicit subtrees
489
- - support `navigation folders get <folder>` in the CLI even if implemented internally via list resolution
490
- - use `--props` or `--props-file` rather than exposing the backend term `additionalProperties` directly
491
- - resource moves should be modeled in terms of source resource plus destination folder
492
-
493
- Example:
494
-
495
- ```bash
496
- zinkee navigation resources move 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --type schema --to "Sales"
497
- ```
498
-
499
- ### Teamspace
500
-
501
- The teamspace domain is conceptually similar to navigation, but semantically distinct because it governs published/shared resources rather than internal workspace organization.
502
-
503
- #### Teamspace Commands
504
-
505
- Proposed commands:
506
-
507
- - `teamspace folders list [--include-resources]`
508
- - `teamspace folders get <folder> [--include-resources]`
509
- - `teamspace folders create --name <name> [--order <n>] [--props <json>]`
510
- - `teamspace folders update <folder> [--name <name>] [--order <n>] [--props <json>]`
511
- - `teamspace folders delete <folder>`
512
- - `teamspace resources publish <resource> --to <folder>`
513
- - `teamspace resources unpublish <resource>`
514
-
515
- #### Teamspace Design Rules
516
-
517
- Agreed rules:
518
-
519
- - use `folders` and `resources` as the main subtrees
520
- - expose `--include-resources` instead of backend-style query values such as `include=resources`
521
- - use `publish` and `unpublish` directly as verbs
522
- - if backend ambiguity requires it later, resource type may be added explicitly, but it is not part of the default CLI contract for now
523
-
524
- Example:
525
-
526
- ```bash
527
- zinkee teamspace folders list --include-resources
528
- zinkee teamspace resources publish 0f6f062f-1478-4df2-96a1-c495d037d260 --to "Customer Success"
529
- zinkee teamspace resources unpublish 0f6f062f-1478-4df2-96a1-c495d037d260
530
- ```
531
-
532
- ### Naming Conventions Agreed in This Section
533
-
534
- The following rules are now part of the design:
535
-
536
- - use `download` explicitly for binary retrieval
537
- - use `folders` and `resources` as subtrees for organization domains
538
- - rename backend-specific payload names like `additionalProperties` into clearer CLI flags such as `--props`
539
- - prefer intention-driven verbs like `move`, `publish`, and `unpublish` over backend route naming
540
-
541
- ## Domain Surface: Displays
542
-
543
- The `displays` domain is a composed resource area with nested subresources and multiple configuration sections. The CLI should expose it through a stable hierarchy while keeping the most common operations legible.
544
-
545
- ### Display Commands
546
-
547
- Proposed top-level commands:
548
-
549
- - `displays list`
550
- - `displays get <display>`
551
- - `displays create --name <name> --template <template>`
552
- - `displays update <display> [--name <name>]`
553
- - `displays delete <display>`
554
-
555
- ### Display Layout Commands
556
-
557
- Proposed commands:
558
-
559
- - `displays layout get <display>`
560
- - `displays layout update <display> --template <template> [--freeform-layouts <json>] [--freeform-layouts-file <path>]`
561
-
562
- Design rule:
563
-
564
- - distinguish display-level layout from widget placement
565
-
566
- ### Display Tab Commands
567
-
568
- Proposed commands:
569
-
570
- - `displays tabs list <display>`
571
- - `displays tabs create <display> [--name <name>] [--orientation <orientation>]`
572
- - `displays tabs update <display> <tab> [--name <name>] [--orientation <orientation>]`
573
- - `displays tabs delete <display> <tab>`
574
-
575
- Identifier rule:
576
-
577
- - `<tab>` should be treated as a string identifier, not assumed to be UUID
578
-
579
- ### Display Variable Commands
580
-
581
- Proposed commands:
582
-
583
- - `displays variables list <display>`
584
- - `displays variables get <display> <variable>`
585
- - `displays variables create <display> --type <type> --name <name> [flags]`
586
- - `displays variables update <display> <variable> [flags]`
587
- - `displays variables delete <display> <variable>`
588
-
589
- #### Variable Flags
590
-
591
- Common flags:
592
-
593
- - `--type <type>`
594
- - `--name <name>`
595
- - `--allow-multiple`
596
- - `--static`
597
- - `--default <value>`
598
- - `--default-value <value>` repeatable
599
-
600
- Reference-variable flags:
601
-
602
- - `--source-schema <id>`
603
- - `--source-field <id>`
604
- - `--filter <expression>` repeatable
605
-
606
- Date-variable flags:
607
-
608
- - `--date-mode <mode>`
609
- - `--date-dynamic-option <option>`
610
- - `--date-specific <iso-date>`
611
- - `--date-range-start <iso-date>`
612
- - `--date-range-end <iso-date>`
613
-
614
- ### Display Widget Commands
615
-
616
- Proposed commands:
617
-
618
- - `displays widgets list <display>`
619
- - `displays widgets get <display> <widget>`
620
- - `displays widgets create <display> --type <type> [flags]`
621
- - `displays widgets update <display> <widget> [flags]`
622
- - `displays widgets delete <display> <widget>`
623
-
624
- #### Widget Design Rule
625
-
626
- Agreed design:
627
-
628
- - use generic `widgets create/update` commands with `--type`
629
- - do not create a separate subcommand per widget type
630
- - use `--raw` as the fallback when widget configuration becomes too rich for the legible flags
631
-
632
- #### Widget Base Flags
633
-
634
- Common widget flags:
635
-
636
- - `--type table|detail|kpi|chart|timeline|kanban|hierarchy`
637
- - `--name <name>`
638
- - `--description <text>`
639
- - `--icon <icon>`
640
- - `--color <color>`
641
- - `--origin-resource <uuid>`
642
- - `--origin-subschema`
643
- - `--tab <tabId>`
644
- - `--slot <slotId>`
645
- - `--layout <json>`
646
- - `--layout-file <path>`
647
-
648
- View/query-oriented flags:
649
-
650
- - `--field <field>` repeatable
651
- - `--sort <field:direction>` repeatable
652
- - `--filter <expression>` repeatable
653
-
654
- Behavior flags:
655
-
656
- - `--widget-read-only`
657
- - `--hide-add-button`
658
- - `--hide-delete-button`
659
- - `--hide-sort-button`
660
- - `--hide-filter-button`
661
- - `--hide-see-button`
662
-
663
- KPI flags:
664
-
665
- - `--calc <type>`
666
- - `--calc-field <uuid>`
667
- - `--kpi-config <json>`
668
-
669
- Chart flags:
670
-
671
- - `--chart-type <type>`
672
- - `--x-axis-field <uuid>`
673
- - `--x-axis-date-format <granularity>`
674
- - `--x-axis-time-series`
675
- - `--y-axis-serie <json>` repeatable
676
- - `--legend <json>`
677
-
678
- ### Display Navigation Target Commands
679
-
680
- Proposed commands:
681
-
682
- - `displays navigation-targets list <display>`
683
- - `displays navigation-targets create <display> --source-widget <id> --target-display <id> --target-variable <id> [--label <label>]`
684
- - `displays navigation-targets update <display> <target> [--source-widget <id>] [--target-display <id>] [--target-variable <id>] [--label <label>]`
685
- - `displays navigation-targets delete <display> <target>`
686
-
687
- Identifier rules:
688
-
689
- - `<target>` should be treated as a string identifier
690
-
691
- ### Display Cross-Widget Filter Commands
692
-
693
- Proposed commands:
694
-
695
- - `displays cross-widget-filter get <display>`
696
- - `displays cross-widget-filter set <display> --source-widget <id> --source-field <id> --target <widgetId:fieldId>...`
697
- - `displays cross-widget-filter delete <display>`
698
-
699
- ### Display Design Rules
700
-
701
- Agreed rules:
702
-
703
- - distinguish between display-level layout and widget placement
704
- - keep high-level operations flag-driven for common use cases
705
- - allow `--raw` and `--raw-file` for advanced configurations such as layout, widget internals, bindings, and rich chart/KPI config
706
- - model widgets generically with `--type` instead of one subcommand per widget type
707
-
708
- ### Naming Conventions Agreed in This Section
709
-
710
- The following rules are now part of the design:
711
-
712
- - use nested subresources such as `layout`, `tabs`, `variables`, `widgets`, `navigation-targets`, and `cross-widget-filter`
713
- - treat tabs and navigation targets as non-UUID identifiers unless implementation later proves otherwise
714
- - model configuration-rich widgets with generic commands plus type-specific flags and raw JSON fallback
715
-
716
- ## Domain Surface: Automations
717
-
718
- The `automations` domain contains folders, automation resources, trigger configuration, actions, flow wiring, webhook endpoints, plugins, and reusable connections. The CLI should expose these parts explicitly rather than hiding them inside a single opaque payload model.
719
-
720
- ### Automation Folder Commands
721
-
722
- Proposed commands:
723
-
724
- - `automations folders list`
725
- - `automations folders create --name <name>`
726
- - `automations folders update <folder> --name <name>`
727
- - `automations folders delete <folder>`
728
- - `automations folders move <automation> --to <folder>`
729
-
730
- ### Automation Commands
731
-
732
- Proposed commands:
733
-
734
- - `automations list [--folder <id>] [--status <status>] [--trigger-type <type>] [--action-type <type>] [--plugin <id>] [--search <text>]`
735
- - `automations get <automation>`
736
- - `automations create --name <name> [--description <text>] [--folder <id>] [trigger flags]`
737
- - `automations update <automation> [--name <name>] [--description <text>] [--folder <id>]`
738
- - `automations delete <automation>`
739
- - `automations activate <automation>`
740
- - `automations deactivate <automation>`
741
-
742
- Design rule:
743
-
744
- - `automations create` should support creating the resource together with its trigger, because the backend create contract already includes trigger configuration
745
-
746
- ### Automation Trigger Commands
747
-
748
- Proposed commands:
749
-
750
- - `automations trigger get <automation>`
751
- - `automations trigger set <automation> [flags]`
752
-
753
- Supported trigger types:
754
-
755
- - `scheduled`
756
- - `record_created`
757
- - `record_changed`
758
- - `webhook`
759
-
760
- #### Trigger Flags
761
-
762
- Common:
763
-
764
- - `--trigger-type <type>`
765
-
766
- Scheduled:
767
-
768
- - `--cron <expression>`
769
-
770
- Record created:
771
-
772
- - `--trigger-schema <uuid>`
773
- - `--condition <field:comparator:value>` repeatable
774
-
775
- Record changed:
776
-
777
- - `--trigger-schema <uuid>`
778
- - `--trigger-field <uuid>` repeatable
779
- - `--condition <field:comparator:value>` repeatable
780
-
781
- Webhook:
782
-
783
- - `--webhook-endpoint-id <uuid>`
784
-
785
- Fallbacks:
786
-
787
- - `--raw <json>`
788
- - `--raw-file <path>`
789
-
790
- ### Automation Action Commands
791
-
792
- Proposed commands:
793
-
794
- - `automations actions list <automation>`
795
- - `automations actions add <automation> --type <type> [flags]`
796
- - `automations actions update <automation> <action> [flags]`
797
- - `automations actions delete <automation> <action>`
798
-
799
- Supported action types:
800
-
801
- - `create_record`
802
- - `update_record`
803
- - `search_records`
804
- - `send_message`
805
- - `http_request`
806
- - `execute_plugin`
807
-
808
- #### Action Design Rule
809
-
810
- Agreed design:
811
-
812
- - actions are modeled with generic `add/update` commands plus `--type`
813
- - do not create dedicated subcommands per action type
814
- - use `--raw` and `--raw-file` for advanced or highly nested action configuration
815
-
816
- #### Action Base Flags
817
-
818
- Common:
819
-
820
- - `--type <type>`
821
- - `--name <name>`
822
-
823
- Create record:
824
-
825
- - `--target-schema <uuid>`
826
- - `--map <field=value>` repeatable
827
- - `--map-json <field=json>` repeatable
828
-
829
- Update record:
830
-
831
- - `--target-schema <uuid>`
832
- - `--map <field=value>` repeatable
833
- - `--map-json <field=json>` repeatable
834
- - `--condition <field:comparator:value>` repeatable
835
- - `--use-trigger-record`
836
-
837
- Search records:
838
-
839
- - `--target-schema <uuid>`
840
- - `--condition <field:comparator:value>` repeatable
841
- - `--use-trigger-record`
842
-
843
- Send message:
844
-
845
- - `--map <field=value>` repeatable
846
- - `--map-json <field=json>` repeatable
847
-
848
- HTTP request:
849
-
850
- - `--method GET|POST|PUT|PATCH|DELETE`
851
- - `--url <url>`
852
- - `--header <key=value>` repeatable
853
- - `--body <json>`
854
- - `--body-file <path>`
855
- - `--content-type <type>`
856
- - `--timeout-ms <n>`
857
- - `--var <key=value>` repeatable
858
- - `--auth-mode <mode>`
859
- - `--connection <uuid>`
860
-
861
- Execute plugin:
862
-
863
- - `--plugin <id>`
864
- - `--arg <key=value>` repeatable
865
- - `--arg-json <key=json>` repeatable
866
-
867
- Fallbacks:
868
-
869
- - `--raw <json>`
870
- - `--raw-file <path>`
871
-
872
- ### Automation Flow Commands
873
-
874
- Proposed commands:
875
-
876
- - `automations flow get <automation>`
877
- - `automations flow set <automation> [--entry <actionId>]... [--transition <from:to>]...`
878
- - `automations flow auto <automation>`
879
-
880
- Design rule:
881
-
882
- - the explicit contract is `flow set` with entry actions and transitions
883
- - `flow auto` may exist later as a helper, but it is not the core execution contract
884
-
885
- ### Automation Webhook Commands
886
-
887
- Proposed commands:
888
-
889
- - `automations webhook get <automation>`
890
- - `automations webhook set <automation> [flags]`
891
- - `automations webhook delete <automation>`
892
-
893
- Webhook flags:
894
-
895
- - `--active`
896
- - `--idempotency-key-path <jsonpath>`
897
- - `--event-type-path <jsonpath>`
898
- - `--allowed-event-type <value>` repeatable
899
- - `--field-mapping <json>` repeatable
900
- - `--field-mapping-file <path>`
901
- - `--raw <json>`
902
- - `--raw-file <path>`
903
-
904
- ### Automation Plugin Commands
905
-
906
- Proposed commands:
907
-
908
- - `automations plugins list`
909
- - `automations plugins get <plugin>`
910
-
911
- Plugins are read-only resources in the CLI contract.
912
-
913
- ### Automation Connection Commands
914
-
915
- Proposed commands:
916
-
917
- - `automations connections list`
918
- - `automations connections get <connection>`
919
- - `automations connections create --name <name> --type <type> --scope <scope> [--owner-member <uuid>] [--config <json>] [--secret <key=value>]... [--active]`
920
- - `automations connections update <connection> [--set <path=value>]... [--unset <path>]...`
921
- - `automations connections delete <connection>`
922
-
923
- #### Connection Design Rules
924
-
925
- Agreed rules:
926
-
927
- - keep `config` and `secret` conceptually separate during creation
928
- - model update as patch-like set/unset because the backend patch contract is generic
929
- - avoid forcing users to pass the entire connection payload just to adjust one field
930
-
931
- ### Naming Conventions Agreed in This Section
932
-
933
- The following rules are now part of the design:
934
-
935
- - expose `folders`, `trigger`, `actions`, `flow`, `webhook`, `plugins`, and `connections` as first-class automation subresources
936
- - model trigger and action polymorphism with generic commands plus `--type`
937
- - use explicit verbs like `activate`, `deactivate`, `move`, and `set`
938
- - prefer structured flags for common cases and `--raw` for advanced nested payloads
939
-
940
- ## Mutation Safety Policy
941
-
942
- The current agreed mutation policy is intentionally simple.
943
-
944
- ### Global Safety Guard
945
-
946
- The main safety mechanism is the global read-only execution mode:
947
-
948
- - `--read-only`
949
- - `ZINKEE_READ_ONLY=1`
950
-
951
- When read-only mode is active:
952
-
953
- - commands classified as `write` or `destructive` must fail before calling the API
954
-
955
- ### Confirmation Policy
956
-
957
- For now, the CLI will not require extra confirmation flags such as `--force` or interactive prompts as a general rule.
958
-
959
- That means:
960
-
961
- - `delete`
962
- - `unpublish`
963
- - `publish`
964
- - `move`
965
- - `activate`
966
- - `deactivate`
967
- - `update`
968
-
969
- all execute directly when the CLI is not in read-only mode.
970
-
971
- This policy can be revisited later if real usage shows a need for additional safety rails, but it is not part of the initial contract.
972
-
973
- ## JSON Output, Errors, and Exit Codes
974
-
975
- The CLI is designed for both humans and agents.
976
-
977
- For humans:
978
-
979
- - default output is `table`
980
-
981
- For agents:
982
-
983
- - `--json` is the stable machine-readable contract
984
-
985
- ### JSON Success Envelope
986
-
987
- Agreed decision:
988
-
989
- - the CLI should use a consistent success envelope
990
- - success payloads should not be returned as bare top-level values
991
-
992
- Canonical shape:
993
-
994
- ```json
995
- {
996
- "data": {},
997
- "meta": {}
998
- }
999
- ```
1000
-
1001
- Reasoning:
1002
-
1003
- - agents can always parse the same top-level structure
1004
- - metadata can evolve without changing the shape of `data`
1005
- - pagination, profile resolution, and execution context can be surfaced consistently
1006
-
1007
- Example:
1008
-
1009
- ```json
1010
- {
1011
- "data": [
1012
- {
1013
- "id": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
1014
- "name": "Contacts",
1015
- "slug": "contacts"
1016
- }
1017
- ],
1018
- "meta": {
1019
- "profile": "prod",
1020
- "baseUrl": "https://api.zinkee.com",
1021
- "command": "schemas list",
1022
- "readOnly": false
1023
- }
1024
- }
1025
- ```
1026
-
1027
- ### Pagination in JSON
1028
-
1029
- When a command produces paginated results, pagination metadata should live in `meta.page`.
1030
-
1031
- Canonical shape:
1032
-
1033
- ```json
1034
- {
1035
- "data": [],
1036
- "meta": {
1037
- "page": {
1038
- "offset": 0,
1039
- "limit": 50,
1040
- "total": 120,
1041
- "count": 50,
1042
- "hasMore": true
1043
- }
1044
- }
1045
- }
1046
- ```
1047
-
1048
- This keeps the CLI JSON contract more uniform than mirroring each backend response shape directly.
1049
-
1050
- ### JSON Error Envelope
1051
-
1052
- Agreed decision:
1053
-
1054
- - the CLI should also use a consistent error envelope
1055
- - backend error fields should be preserved whenever available
1056
-
1057
- Canonical shape:
1058
-
1059
- ```json
1060
- {
1061
- "error": {
1062
- "status": 400,
1063
- "error": "BAD_REQUEST",
1064
- "reason": "schema_id_invalid",
1065
- "message": "Schema identifier is invalid.",
1066
- "action": "Use a valid UUID in the schemaId field.",
1067
- "retryable": false,
1068
- "path": "/api/v2/schemas/...",
1069
- "requestId": "req-123",
1070
- "timestamp": "2026-03-24T12:00:00Z"
1071
- },
1072
- "meta": {
1073
- "profile": "prod",
1074
- "baseUrl": "https://api.zinkee.com",
1075
- "command": "schemas get"
1076
- }
1077
- }
1078
- ```
1079
-
1080
- For CLI-native errors, the same envelope model should be used:
1081
-
1082
- ```json
1083
- {
1084
- "error": {
1085
- "status": 1,
1086
- "error": "CLI_ERROR",
1087
- "reason": "command_not_allowed_in_read_only_mode",
1088
- "message": "Command \"records create\" is not allowed in read-only mode.",
1089
- "action": "Run the command without --read-only if write access is intended.",
1090
- "retryable": false
1091
- },
1092
- "meta": {
1093
- "profile": "prod",
1094
- "command": "records create"
1095
- }
1096
- }
1097
- ```
1098
-
1099
- ### JSON Output Rules
1100
-
1101
- When `--json` is active:
1102
-
1103
- - stdout must contain only structured JSON
1104
- - no tables
1105
- - no color
1106
- - no banners
1107
- - no stray explanatory text
1108
- - debug or diagnostic noise must not be printed to stdout
1109
-
1110
- If debugging output is enabled, it must go to stderr or be explicitly structured.
1111
-
1112
- ### Example Output in JSON
1113
-
1114
- When `--example --json` is used, the CLI should return structured examples.
1115
-
1116
- Canonical shape:
1117
-
1118
- ```json
1119
- {
1120
- "data": {
1121
- "examples": [
1122
- {
1123
- "description": "Query records with a text filter",
1124
- "command": "zinkee records query contacts --where \"email contains @acme.com\""
1125
- }
1126
- ]
1127
- },
1128
- "meta": {
1129
- "command": "records query"
1130
- }
1131
- }
1132
- ```
1133
-
1134
- ### Binary Output Rule
1135
-
1136
- Binary-producing commands such as `files download` must not dump raw bytes into a JSON response.
1137
-
1138
- Rule:
1139
-
1140
- - if `--json` is used with a binary command, the CLI should require `--output`
1141
- - the JSON response should then describe the result, not embed the binary payload
1142
-
1143
- ### Exit Codes
1144
-
1145
- The CLI should use a small, stable exit code taxonomy.
1146
-
1147
- Agreed mapping:
1148
-
1149
- - `0`: success
1150
- - `1`: general CLI error
1151
- - `2`: invalid usage or invalid local arguments
1152
- - `3`: authentication or authorization error
1153
- - `4`: resource not found
1154
- - `5`: conflict or invalid resource state
1155
- - `6`: network, timeout, or backend availability error
1156
- - `7`: command blocked by read-only mode
1157
-
1158
- ### Exit Code Mapping Rules
1159
-
1160
- Recommended mapping:
1161
-
1162
- - local parsing, flag validation, config validation: `2`
1163
- - backend `401` or `403`: `3`
1164
- - backend `404`: `4`
1165
- - backend `409`: `5`
1166
- - backend `5xx`, timeouts, connection failures: `6`
1167
- - local read-only enforcement: `7`
1168
- - uncategorized or generic failures: `1`
1169
-
1170
- ## Naming Conventions
1171
-
1172
- The CLI should be highly predictable across domains.
1173
-
1174
- ### Global Naming Rules
1175
-
1176
- Agreed rules:
1177
-
1178
- - commands and subcommands use `kebab-case`
1179
- - long flags use `kebab-case`
1180
- - resource command groups use plural nouns
1181
- - verbs should remain small and consistent
1182
-
1183
- Preferred verbs:
1184
-
1185
- - `list`
1186
- - `get`
1187
- - `create`
1188
- - `update`
1189
- - `delete`
1190
- - `query`
1191
- - `set`
1192
- - `add`
1193
- - `move`
1194
- - `publish`
1195
- - `unpublish`
1196
- - `activate`
1197
- - `deactivate`
1198
-
1199
- ### Boolean Flags
1200
-
1201
- Boolean design rules:
1202
-
1203
- - activation-style booleans use bare flags
1204
- - booleans that may need explicit true/false during update operations may accept a value
1205
-
1206
- Examples:
1207
-
1208
- - `--json`
1209
- - `--read-only`
1210
- - `--active`
1211
- - `--allow-multiple`
1212
- - `--static`
1213
- - `--commentable true`
1214
- - `--auditable false`
1215
-
1216
- ### Resource Selectors
1217
-
1218
- Selector rules:
1219
-
1220
- - use UUID or slug where the domain naturally supports slugs
1221
- - use UUID where slugs do not clearly exist or could be ambiguous
1222
-
1223
- Current selector policy:
1224
-
1225
- - `schemas`: UUID or slug
1226
- - `schema fields`: UUID or slug
1227
- - `records`: schema by UUID or slug, record by UUID
1228
- - `files`: UUID
1229
- - `navigation folders`: UUID or exact folder name
1230
- - `teamspace folders`: UUID or exact folder name
1231
- - `displays`: UUID for now
1232
- - `widgets`: UUID
1233
- - `variables`: UUID
1234
- - `tabs`: string
1235
- - `automations`: UUID
1236
- - `automation folders`: UUID or exact folder name
1237
- - `actions`: UUID
1238
- - `connections`: UUID
1239
- - `plugins`: string id
1240
-
1241
- Folder resolution rule:
1242
-
1243
- - folder selectors may resolve by UUID or exact name
1244
- - if an exact-name lookup matches more than one folder, the CLI must fail with an ambiguity error and ask for UUID
1245
-
1246
- ### Lists and Repeated Flags
1247
-
1248
- The CLI should prefer repeated flags for complex or structured lists, and CSV only for simple ergonomic cases.
1249
-
1250
- Use repeated flags for:
1251
-
1252
- - `--where`
1253
- - `--filter`
1254
- - `--condition`
1255
- - `--set`
1256
- - `--unset`
1257
- - `--header`
1258
- - `--entry`
1259
- - `--transition`
1260
-
1261
- Use CSV for:
1262
-
1263
- - `--select id,name,email`
1264
-
1265
- ### JSON Payload Conventions
1266
-
1267
- For command-wide structured input:
1268
-
1269
- - `--raw <json>`
1270
- - `--raw-file <path>`
1271
-
1272
- For sub-sections:
1273
-
1274
- - `--layout <json>` / `--layout-file <path>`
1275
- - `--props <json>` / `--props-file <path>`
1276
- - `--body <json>` / `--body-file <path>`
1277
-
1278
- Rule:
1279
-
1280
- - when a JSON inline flag is expected to carry non-trivial payloads, a file-based variant should also exist
1281
-
1282
- ### Key-Value Conventions
1283
-
1284
- Simple mappings should use `key=value`.
1285
-
1286
- Examples:
1287
-
1288
- - `--set field=value`
1289
- - `--header Authorization=Bearer-token`
1290
- - `--secret client_secret=abc`
1291
- - `--arg retries=3`
1292
-
1293
- Structured mappings should use explicit JSON forms.
1294
-
1295
- Examples:
1296
-
1297
- - `--set-json field='{"a":1}'`
1298
- - `--arg-json payload='{"x":2}'`
1299
-
1300
- ### Expression Conventions
1301
-
1302
- The CLI should reuse the same human-readable expression style across filter-like features whenever possible.
1303
-
1304
- Target style:
1305
-
1306
- - `--where "status eq active"`
1307
- - `--condition "amount gt 1000"`
1308
- - `--filter "ownerId in a,b,c"`
1309
-
1310
- These should ideally share a common parser internally.
1311
-
1312
- ### Reserved Global Flags
1313
-
1314
- The following names are reserved globally and should not be repurposed locally:
1315
-
1316
- - `--profile`
1317
- - `--base-url`
1318
- - `--api-key`
1319
- - `--json`
1320
- - `--read-only`
1321
- - `--verbose`
1322
- - `--debug`
1323
- - `--no-color`
1324
- - `--example`
1325
-
1326
- Command-local advanced payload flags:
1327
-
1328
- - `--raw`
1329
- - `--raw-file`
1330
-
1331
- These are not root-level global flags. They are available only on commands that explicitly support structured payload fallback.
1332
-
1333
- ## Internal Architecture
1334
-
1335
- The CLI should follow the same stack and almost the same structure as the reference CLI in `/Users/david/dev/pichardo-projects/store-manager`, while adapting from Shopify GraphQL to Zinkee REST API v2.
1336
-
1337
- ### Technology Stack
1338
-
1339
- Agreed stack direction:
1340
-
1341
- - Node.js 20+
1342
- - TypeScript
1343
- - ESM
1344
- - `commander` for CLI command modeling
1345
- - `chalk` for human-friendly terminal output
1346
- - `cli-table3` for table output
1347
- - `tsup` for builds
1348
- - `tsx` for local development
1349
- - `vitest` for tests
1350
- - native `fetch` for HTTP
1351
-
1352
- ### Project Structure
1353
-
1354
- Proposed structure:
1355
-
1356
- ```text
1357
- src/
1358
- index.ts
1359
- client.ts
1360
- config.ts
1361
- types.ts
1362
- command-registry.ts
1363
- commands/
1364
- config.ts
1365
- profiles.ts
1366
- schemas.ts
1367
- records.ts
1368
- comments.ts
1369
- files.ts
1370
- navigation.ts
1371
- teamspace.ts
1372
- displays.ts
1373
- automations.ts
1374
- api/
1375
- schemas.ts
1376
- records.ts
1377
- comments.ts
1378
- files.ts
1379
- navigation.ts
1380
- teamspace.ts
1381
- displays.ts
1382
- automations.ts
1383
- utils/
1384
- output.ts
1385
- errors.ts
1386
- examples.ts
1387
- identifiers.ts
1388
- flags.ts
1389
- json.ts
1390
- parsers/
1391
- expressions.ts
1392
- kv.ts
1393
- selectors.ts
1394
- ```
1395
-
1396
- This keeps the same mental model as the reference:
1397
-
1398
- - one command module per domain
1399
- - one transport-facing module per domain
1400
- - shared helpers centralized in utils/parsers/config/client
1401
-
1402
- ### Entry Point
1403
-
1404
- `src/index.ts` should:
1405
-
1406
- - create the root `Command`
1407
- - register global options
1408
- - register every domain command module
1409
- - enable `showHelpAfterError`
1410
- - centralize top-level error handling
1411
-
1412
- ### Config Layer
1413
-
1414
- `src/config.ts` should:
1415
-
1416
- - read and write `/Users/david/.config/zinkee/config.toml`
1417
- - resolve the effective profile
1418
- - apply runtime overrides from flags
1419
- - preserve backward compatibility with the legacy TOML contract
1420
-
1421
- ### HTTP Client Layer
1422
-
1423
- `src/client.ts` should:
1424
-
1425
- - encapsulate `fetch`
1426
- - handle auth headers
1427
- - enforce request timeout
1428
- - normalize HTTP and JSON parsing failures
1429
- - preserve backend error fields when available
1430
- - expose a small REST-friendly API for domain modules
1431
-
1432
- Recommended client responsibilities:
1433
-
1434
- - build request URL from `baseUrl`
1435
- - add bearer token from resolved profile or override
1436
- - parse JSON success and error responses
1437
- - detect non-JSON payloads where applicable
1438
- - support binary download paths for file commands
1439
-
1440
- ### Domain API Modules
1441
-
1442
- `src/api/*.ts` should:
1443
-
1444
- - map domain operations to concrete API v2 HTTP calls
1445
- - contain minimal transport shaping logic
1446
- - avoid owning CLI parsing concerns
1447
-
1448
- Examples:
1449
-
1450
- - `src/api/schemas.ts`: `/api/v2/schemas`, `/fields`
1451
- - `src/api/records.ts`: `/api/v2/schemas/{schemaId}/records`
1452
- - `src/api/displays.ts`: `/api/v2/displays` and subresources
1453
- - `src/api/automations.ts`: `/api/v2/automations`, folders, trigger, actions, flow, webhook, plugins, connections
1454
-
1455
- ### Command Modules
1456
-
1457
- `src/commands/*.ts` should:
1458
-
1459
- - register commander commands
1460
- - parse and validate CLI arguments
1461
- - resolve selectors
1462
- - call domain API helpers
1463
- - format output
1464
-
1465
- They should not:
1466
-
1467
- - own low-level fetch logic
1468
- - duplicate generic error formatting
1469
- - parse TOML directly
1470
-
1471
- ### Command Registry
1472
-
1473
- The new CLI needs a central registry that the reference CLI does not currently need as explicitly.
1474
-
1475
- `src/command-registry.ts` should define metadata such as:
1476
-
1477
- - canonical command name
1478
- - access level: `read`, `write`, `destructive`
1479
- - whether `--example` is supported
1480
- - whether `--raw` is supported
1481
- - output capabilities such as table/json/binary
1482
-
1483
- This registry should power:
1484
-
1485
- - read-only enforcement
1486
- - example generation
1487
- - consistent metadata in `--json`
1488
- - future documentation extraction
1489
-
1490
- ### Parsing Utilities
1491
-
1492
- The CLI will benefit from explicit parser helpers for repeated mini-languages.
1493
-
1494
- `src/parsers/expressions.ts` should parse:
1495
-
1496
- - `--where`
1497
- - `--filter`
1498
- - `--condition`
1499
-
1500
- `src/parsers/kv.ts` should parse:
1501
-
1502
- - `--set`
1503
- - `--set-json`
1504
- - `--arg`
1505
- - `--arg-json`
1506
- - `--header`
1507
- - `--secret`
1508
-
1509
- `src/parsers/selectors.ts` should parse and normalize:
1510
-
1511
- - UUID-or-slug selectors
1512
- - typed resource selectors where needed
1513
-
1514
- ### Output Utilities
1515
-
1516
- `src/utils/output.ts` should centralize:
1517
-
1518
- - table rendering
1519
- - JSON success envelope rendering
1520
- - JSON error envelope rendering
1521
- - binary command output metadata
1522
-
1523
- ### Error Utilities
1524
-
1525
- `src/utils/errors.ts` should centralize:
1526
-
1527
- - CLI-native error classes
1528
- - mapping backend errors to exit codes
1529
- - mapping local validation failures to stable reasons
1530
- - formatting human-readable error output
1531
-
1532
- ### Example Utilities
1533
-
1534
- `src/utils/examples.ts` should centralize:
1535
-
1536
- - command examples
1537
- - JSON example rendering
1538
- - example lookup by command identity
1539
-
1540
- This avoids scattering example strings across unrelated command logic.
1541
-
1542
- ### Testing Strategy
1543
-
1544
- The testing model should stay close to the reference CLI:
1545
-
1546
- - favor unit tests for pure helpers, parsers, selector resolution, and command input normalization
1547
- - avoid unnecessarily heavy end-to-end mocking where pure tests are enough
1548
- - add focused transport tests for client error handling and JSON envelope behavior
1549
-
1550
- Suggested test files:
1551
-
1552
- - `src/config.test.ts`
1553
- - `src/client.test.ts`
1554
- - `src/parsers/expressions.test.ts`
1555
- - `src/parsers/kv.test.ts`
1556
- - `src/commands/schemas.test.ts`
1557
- - `src/commands/records.test.ts`
1558
- - `src/commands/displays.test.ts`
1559
- - `src/commands/automations.test.ts`
1560
-
1561
- ### Agent-Facing Documentation
1562
-
1563
- In line with the reference CLI, the repository should include agent-oriented documentation close to the codebase.
1564
-
1565
- Recommended artifacts:
1566
-
1567
- - `README.md`
1568
- - `AGENTS.md`
1569
- - a CLI contract reference file
1570
- - examples that match the true command help
1571
-
1572
- The source of truth order should be:
1573
-
1574
- 1. live `--help`
1575
- 2. command modules
1576
- 3. repository docs