@smallpen/cli 0.1.0-alpha.2 → 0.1.0-alpha.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/bin/help.mjs +236 -32
- package/bin/schema.mjs +615 -0
- package/bin/smallpen.mjs +500 -64
- package/bin/warning-output.mjs +8 -1
- package/package.json +3 -3
package/bin/help.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { workedExampleText } from "./schema.mjs";
|
|
2
|
+
|
|
1
3
|
const COMMANDS = [
|
|
2
4
|
["version", "Print the CLI package version without opening a workspace"],
|
|
5
|
+
["schema", "Print the JSON shape and a valid example of every write input"],
|
|
3
6
|
["init", "Persist a guided Brief/Proposal and create Foundation + Product"],
|
|
4
7
|
["validate", "Validate a package and its same-workspace Foundation"],
|
|
5
8
|
["inspect", "Inspect package identity, capabilities, and domain summary"],
|
|
@@ -43,6 +46,14 @@ const DESIGN_SELECTORS = `Design selectors:
|
|
|
43
46
|
--context-profile ID Named Context profile
|
|
44
47
|
--context AXIS=VALUE Repeatable finite Context selection`;
|
|
45
48
|
|
|
49
|
+
const WRITE_REPLY = `Reply size:
|
|
50
|
+
The default reply includes inverseBatch (also repeated in guidance.undo), the
|
|
51
|
+
exact undo for the write; it can run to thousands of lines. --inverse-out FILE
|
|
52
|
+
saves inverseBatch to FILE (only when the batch commits) and returns
|
|
53
|
+
inverseBatchPath. --compact drops inverseBatch and guidance from the reply and
|
|
54
|
+
adds summary and inverseOperationCount; combine both to keep undo:
|
|
55
|
+
smallpen apply PACKAGE --batch FILE --inverse-out FILE.undo.json`;
|
|
56
|
+
|
|
46
57
|
const VIEW_SELECTORS = `${DESIGN_SELECTORS}
|
|
47
58
|
--format FORMAT structure|semantic|wireframe|screenshot`;
|
|
48
59
|
|
|
@@ -54,6 +65,36 @@ const HELP = {
|
|
|
54
65
|
Output:
|
|
55
66
|
The installed CLI package version, or {name,version} with --json.
|
|
56
67
|
No package path is required; design files are unchanged and no services start.`,
|
|
68
|
+
schema: `Usage:
|
|
69
|
+
smallpen schema [TOPIC] [--json]
|
|
70
|
+
smallpen schema operation TYPE [--json]
|
|
71
|
+
|
|
72
|
+
Purpose:
|
|
73
|
+
Print the exact JSON that apply, token, page, flow, and init accept: fields,
|
|
74
|
+
types, allowed values, a valid example, and the inverse each operation
|
|
75
|
+
returns. No package is opened. Field lists come from the validators, and every
|
|
76
|
+
example is tested against a workspace made by smallpen init.
|
|
77
|
+
|
|
78
|
+
Topics:
|
|
79
|
+
operations every operation type, its purpose, Package, required fields
|
|
80
|
+
operation TYPE one operation in full (smallpen schema put-token also works)
|
|
81
|
+
batch batch contract, Foundation vs Product, worked example
|
|
82
|
+
node node fields, textStyle, tokenBindings
|
|
83
|
+
node-types what each node type requires
|
|
84
|
+
token Token definition, contextValues, bindings
|
|
85
|
+
token-types the value each Token type accepts
|
|
86
|
+
component-set Component Set, Axis roles (configuration, state), variants
|
|
87
|
+
instance INSTANCE nodes and overrides
|
|
88
|
+
presentation Presentation fields, size, and resizing
|
|
89
|
+
screen Screen fields
|
|
90
|
+
scenario Scenario fields and viewport
|
|
91
|
+
context Context Axes and theme values (alias: theme)
|
|
92
|
+
init every init question and a complete --answers file
|
|
93
|
+
|
|
94
|
+
Examples:
|
|
95
|
+
smallpen schema operations
|
|
96
|
+
smallpen schema operation update-component-node
|
|
97
|
+
smallpen schema component-set`,
|
|
57
98
|
init: `Usage:
|
|
58
99
|
smallpen init <workspace-directory> [--state FILE] [--answers FILE]
|
|
59
100
|
[--answer QUESTION_ID=JSON]... [--confirm] [--locale LOCALE] [--json]
|
|
@@ -64,7 +105,13 @@ Purpose:
|
|
|
64
105
|
Foundation and one Product; an existing target is never overwritten.
|
|
65
106
|
|
|
66
107
|
Defaults and values:
|
|
67
|
-
--state defaults to <workspace-directory>.smallpen-init.json.
|
|
108
|
+
--state defaults to <workspace-directory>.smallpen-init.json. Answers build up
|
|
109
|
+
only when every call passes the same --state; a call without --state starts
|
|
110
|
+
from no answers (the reply then carries stateNotice).
|
|
111
|
+
--answers FILE answers every question at once: smallpen schema init prints all
|
|
112
|
+
questions and a complete file.
|
|
113
|
+
--locale defaults to the environment (LC_ALL, LC_MESSAGES, LANG): zh* selects
|
|
114
|
+
Chinese labels, anything else English.
|
|
68
115
|
Project kinds: application|motion|custom. Foundation choice: create-new.
|
|
69
116
|
--answer values are JSON (for example projectKind=\"application\").
|
|
70
117
|
|
|
@@ -79,7 +126,20 @@ Output:
|
|
|
79
126
|
<JSON> with your schema-valid answer; if no recommendation is present, supply the
|
|
80
127
|
project's own purpose, audience, or deliverable. status proposal returns the
|
|
81
128
|
persisted Proposal and confirmation args. Only --confirm creates the packages;
|
|
82
|
-
status initialized returns both package paths
|
|
129
|
+
status initialized returns both package paths plus every id the first writes
|
|
130
|
+
need: packages.{foundation,product}.{packageId,path,revision},
|
|
131
|
+
start.{screenId,presentationId,rootNode,scenarioIds,contextAxes}, and seeded
|
|
132
|
+
(the starter Tokens and Component Sets with ids and paths).
|
|
133
|
+
|
|
134
|
+
Seeded content (from the answers):
|
|
135
|
+
Foundation: each initialTokens name becomes a Token tok_<path with _>, for
|
|
136
|
+
example color.brand -> tok_color_brand (#6750a4), spacing.md -> tok_spacing_md
|
|
137
|
+
(8), radius.md -> tok_radius_md (8). Each initialComponents name becomes a
|
|
138
|
+
Component Set cmp_<name> with one plain variant var_<name>_default, no axes
|
|
139
|
+
(Button -> cmp_button). platforms become Context Axis axis_platform, next to
|
|
140
|
+
your contextAxes. Product: Screen scr_<firstScreen> with Presentation
|
|
141
|
+
pres_<firstScreen>_<platform>, root FRAME node_<firstScreen>_root, and one
|
|
142
|
+
Scenario. put-token or put-component-set with a seeded id replaces it whole.
|
|
83
143
|
|
|
84
144
|
Errors and next commands:
|
|
85
145
|
Malformed --answer JSON identifies the question; schema-invalid values also return
|
|
@@ -136,7 +196,8 @@ ${VIEW_SELECTORS}
|
|
|
136
196
|
|
|
137
197
|
Defaults:
|
|
138
198
|
Base Presentation + default Context values + canonical initial state + structure.
|
|
139
|
-
All formats resolve the same selection.
|
|
199
|
+
All formats resolve the same selection. --locale defaults to the environment
|
|
200
|
+
(zh* selects Chinese labels, anything else English).
|
|
140
201
|
|
|
141
202
|
Choose a format:
|
|
142
203
|
wireframe A scaled 2D ASCII canvas for fast spatial reasoning, followed by a
|
|
@@ -192,6 +253,13 @@ Purpose:
|
|
|
192
253
|
execute the owner-scoped command returned by search-components.
|
|
193
254
|
An HTTP(S) Library URL is also accepted and uses the normal Library cache.
|
|
194
255
|
|
|
256
|
+
Shapes:
|
|
257
|
+
smallpen schema component-set axes (role configuration|state) and variants
|
|
258
|
+
smallpen schema instance place a variant on a Screen and override it
|
|
259
|
+
Edit a variant: {"type":"update-component-node","componentSetId":"cmp_button",
|
|
260
|
+
"variantId":"var_button_primary","nodeId":"node_button_label",
|
|
261
|
+
"changes":{"textStyle":{"textAlign":"center"}}}
|
|
262
|
+
|
|
195
263
|
Next:
|
|
196
264
|
Use a returned selection with read-view or inspect-view to review the design.`,
|
|
197
265
|
compare: `Usage:
|
|
@@ -203,11 +271,11 @@ Values:
|
|
|
203
271
|
smallpen compare product.smallpen --selector '{"presentationId":"pres_desktop"}' \\
|
|
204
272
|
--selector '{"presentationId":"pres_mobile"}' --json`,
|
|
205
273
|
tokens: `Usage:
|
|
206
|
-
smallpen tokens <product.smallpen> [--context AXIS=VALUE]... [--json]
|
|
274
|
+
smallpen tokens <product.smallpen> [--context AXIS=VALUE]... [--locale LOCALE] [--json]
|
|
207
275
|
|
|
208
276
|
Purpose:
|
|
209
277
|
List Effective Tokens using Product first, Context specificity within a layer,
|
|
210
|
-
then Foundation fallback.`,
|
|
278
|
+
then Foundation fallback. labels follow --locale or the environment.`,
|
|
211
279
|
"search-tokens": `Usage:
|
|
212
280
|
smallpen search-tokens <product.smallpen> (--color COLOR | --value JSON | --query TEXT | --type TYPE)
|
|
213
281
|
[--context AXIS=VALUE]... [--limit N] [--json]
|
|
@@ -258,6 +326,12 @@ Defaults and limits:
|
|
|
258
326
|
not visual QA. Verify decoded bytes against renderHash (SHA-256), and use the
|
|
259
327
|
accompanying revision and selection. On failure, never open a previous file.
|
|
260
328
|
|
|
329
|
+
Fonts:
|
|
330
|
+
The renderer bundles Source Sans Pro and draws fonts imported with import-font.
|
|
331
|
+
Any other family renders in Source Sans Pro: diagnostics then carries one
|
|
332
|
+
font_render_fallback per missing family with its nodeIds, availableFonts, and
|
|
333
|
+
the import-font command in nextOperations.
|
|
334
|
+
|
|
261
335
|
Wireframe:
|
|
262
336
|
Use smallpen read-view <product.smallpen> --format wireframe --json.
|
|
263
337
|
It returns a scaled 2D ASCII canvas and compact marker key. Use semanticTree
|
|
@@ -268,7 +342,7 @@ Wireframe:
|
|
|
268
342
|
|
|
269
343
|
${DESIGN_SELECTORS}
|
|
270
344
|
--scale N Image scale; default: 1 (requires --include-image to render)
|
|
271
|
-
--locale LOCALE Localized view labels; default:
|
|
345
|
+
--locale LOCALE Localized view labels; default: from the environment
|
|
272
346
|
|
|
273
347
|
Purpose:
|
|
274
348
|
Return one AI-readable view bundle.
|
|
@@ -347,12 +421,16 @@ Errors and recovery:
|
|
|
347
421
|
Corrupt or unsupported bytes exit 1 invalid_media_file and write nothing.
|
|
348
422
|
Reusing --media-id exits duplicate_media_id with the existing descriptor.
|
|
349
423
|
|
|
424
|
+
Output:
|
|
425
|
+
descriptor and revision, plus batchId and the exact inverseBatch for undo.
|
|
426
|
+
|
|
350
427
|
`,
|
|
351
428
|
"remove-media": `Usage:
|
|
352
429
|
smallpen remove-media <package.smallpen> --media-id MEDIA [--json]
|
|
353
430
|
|
|
354
|
-
Removes one Media descriptor from the Asset Library atomically
|
|
355
|
-
|
|
431
|
+
Removes one Media descriptor from the Asset Library atomically. The result
|
|
432
|
+
carries batchId and inverseBatch; smallpen apply with that inverseBatch restores
|
|
433
|
+
the descriptor (the blob is retained). Unknown ids exit missing_media.
|
|
356
434
|
|
|
357
435
|
`,
|
|
358
436
|
"import-font": `Usage:
|
|
@@ -364,7 +442,8 @@ Public Font entry for an existing Product. TTF and OTF are validated by SFNT
|
|
|
364
442
|
signature and converted to WOFF (the renderer loads ttf/otf/woff). WOFF imports
|
|
365
443
|
as-is after table validation. A valid WOFF2 reaches an explicit
|
|
366
444
|
unsupported_font_conversion boundary (no WOFF2 decoder is bundled); corrupt
|
|
367
|
-
fonts fail invalid_font_blob. Either way nothing is written.
|
|
445
|
+
fonts fail invalid_font_blob. Either way nothing is written. Success returns
|
|
446
|
+
fontId, variantId, files, revision, batchId, and the exact inverseBatch.
|
|
368
447
|
|
|
369
448
|
`,
|
|
370
449
|
"library-refresh": `Usage:
|
|
@@ -376,6 +455,13 @@ mismatch exits library_id_mismatch with expected/actual identities and leaves th
|
|
|
376
455
|
previous verified snapshot readable offline. Success reports before/after
|
|
377
456
|
revisions; failures keep the previous revision.
|
|
378
457
|
|
|
458
|
+
When a fetch fails and a verified cache exists, the command exits 0 with
|
|
459
|
+
after.cache "stale", the cached revision, and after.warning naming the cause.
|
|
460
|
+
With no cache the Library cannot resolve: the command exits repair_required
|
|
461
|
+
with a library_unavailable conflict whose message names the cause. Requests
|
|
462
|
+
follow at most five redirects, only within the Library's origin; each file
|
|
463
|
+
is capped at 50 MB.
|
|
464
|
+
|
|
379
465
|
`,
|
|
380
466
|
"import-draft": `Usage:
|
|
381
467
|
smallpen import-draft <new-draft.smallpen> --kind figma|svg|png --input FILE
|
|
@@ -396,7 +482,7 @@ Next:
|
|
|
396
482
|
"import-tokens": `Usage:
|
|
397
483
|
smallpen import-tokens <package.smallpen> --input TOKENS.json [--set-name NAME]
|
|
398
484
|
[--select SET/NAME]... [--apply] [--dry-run]
|
|
399
|
-
[--batch-id ID] [--json]
|
|
485
|
+
[--batch-id ID] [--compact] [--inverse-out FILE] [--json]
|
|
400
486
|
|
|
401
487
|
Purpose:
|
|
402
488
|
Import a DTCG token file (Penpot or Tokens Studio export, single-set, multi-set
|
|
@@ -441,7 +527,8 @@ Output:
|
|
|
441
527
|
This command does not apply the batch. Review it, then use smallpen apply.`,
|
|
442
528
|
flow: `Usage:
|
|
443
529
|
smallpen flow <product.smallpen> --intent INTENT.json [--batch-id ID] [--dry-run]
|
|
444
|
-
[--warning-detail compact|full]
|
|
530
|
+
[--explain] [--diff] [--warning-detail compact|full]
|
|
531
|
+
[--confirm-unmatched] [--compact] [--inverse-out FILE] [--json]
|
|
445
532
|
|
|
446
533
|
Purpose:
|
|
447
534
|
Compile and atomically apply a declarative flowchart intent. The intent contains
|
|
@@ -455,28 +542,91 @@ Intent example:
|
|
|
455
542
|
Node types:
|
|
456
543
|
FRAME|ELLIPSE|GROUP|PATH|RECTANGLE|TEXT. PATH nodes may carry pathData, points,
|
|
457
544
|
strokes, and tokenBindings; arrowheads use stroke cap fields.
|
|
545
|
+
Node fields: smallpen schema node. Every intent node is added as a sibling
|
|
546
|
+
under parentId (default: the Presentation root); nest with a later intent.
|
|
547
|
+
INSTANCE nodes may carry overrides, as in smallpen page --help.
|
|
548
|
+
|
|
549
|
+
Output:
|
|
550
|
+
The normal atomic apply result. Follow with read-view or render to inspect it.
|
|
458
551
|
|
|
459
|
-
|
|
460
|
-
The normal atomic apply result. Follow with read-view or render to inspect it.`,
|
|
552
|
+
${WRITE_REPLY}`,
|
|
461
553
|
page: `Usage:
|
|
462
554
|
smallpen page <product.smallpen> --intent INTENT.json [--batch-id ID] [--dry-run]
|
|
463
|
-
[--warning-detail compact|full]
|
|
555
|
+
[--explain] [--diff] [--warning-detail compact|full]
|
|
556
|
+
[--confirm-unmatched] [--compact] [--inverse-out FILE] [--json]
|
|
464
557
|
|
|
465
558
|
Purpose:
|
|
466
559
|
Compile and atomically apply declarative page nodes. The intent uses the same
|
|
467
560
|
screenId, optional presentationId/parentId, and nodes schema as flow. Use page
|
|
468
561
|
for general UI nodes and flow for flowchart-oriented PATH/ELLIPSE nodes.
|
|
469
|
-
Warning output follows apply; see smallpen apply --help for the compact schema
|
|
562
|
+
Warning output follows apply; see smallpen apply --help for the compact schema.
|
|
563
|
+
Pass the Product. Each node becomes one add-presentation-node, all siblings
|
|
564
|
+
under parentId (default: the Presentation root); x/y are relative to it.
|
|
565
|
+
|
|
566
|
+
Instance overrides:
|
|
567
|
+
An INSTANCE intent node may carry overrides {"<sourceNodeId>:<field>": value}
|
|
568
|
+
(fields: fills, name, opacity, text, visible). Each becomes a
|
|
569
|
+
set-instance-override after the node in the same atomic batch, so a label
|
|
570
|
+
needs no second write; a wrong path or type rejects the whole intent.
|
|
571
|
+
|
|
572
|
+
Intent example (a title and a Button Instance with its label):
|
|
573
|
+
{"screenId":"scr_home","nodes":[
|
|
574
|
+
{"id":"node_title","type":"TEXT","name":"Title","x":24,"y":48,"width":312,
|
|
575
|
+
"height":32,"children":[],"text":"Tasks","textStyle":{"fontSize":24}},
|
|
576
|
+
{"id":"node_add_button","type":"INSTANCE","name":"Add button","x":16,"y":576,
|
|
577
|
+
"width":328,"height":48,"children":[],"instance":{"component":
|
|
578
|
+
{"packageId":"pkg_acme_foundation","assetId":"cmp_button"},
|
|
579
|
+
"variant":{"axis_style":"primary"}},
|
|
580
|
+
"overrides":{"node_button_label:text":"Add task"}}]}
|
|
581
|
+
|
|
582
|
+
Shapes:
|
|
583
|
+
smallpen schema node fields, textStyle, tokenBindings
|
|
584
|
+
smallpen schema instance INSTANCE nodes; search-components prints a ready intent
|
|
585
|
+
|
|
586
|
+
${WRITE_REPLY}`,
|
|
470
587
|
token: `Usage:
|
|
471
|
-
smallpen token <
|
|
472
|
-
[--warning-detail compact|full]
|
|
588
|
+
smallpen token <package.smallpen> --intent INTENT.json [--batch-id ID] [--dry-run]
|
|
589
|
+
[--explain] [--diff] [--warning-detail compact|full]
|
|
590
|
+
[--confirm-unmatched] [--compact] [--inverse-out FILE] [--json]
|
|
591
|
+
|
|
592
|
+
Which Package:
|
|
593
|
+
Pass the Foundation (<name>-foundation.smallpen) for put-token, set-token-value,
|
|
594
|
+
remove-token, and deprecate-token: shared Tokens live there. Pass the Product
|
|
595
|
+
(<name>.smallpen) for set-token-binding, clear-token-binding, and
|
|
596
|
+
set-active-token-themes, which change Product nodes and its Token Library.
|
|
597
|
+
smallpen schema operations lists the Package of every operation.
|
|
473
598
|
|
|
474
599
|
Purpose:
|
|
475
600
|
Apply declarative Token operations through the canonical atomic batch contract.
|
|
476
601
|
Intent JSON contains an operations array using put-token, set-token-value,
|
|
477
602
|
set-active-token-themes, set-token-binding, clear-token-binding, remove-token,
|
|
478
603
|
or deprecate-token. Theme selection uses themePaths such as Product/Dark.
|
|
479
|
-
The current package revision is read immediately before applying the intent
|
|
604
|
+
The current package revision is read immediately before applying the intent.
|
|
605
|
+
Write shared Tokens to the Foundation package; bind them from the Product.
|
|
606
|
+
put-token with an existing tokenId replaces that Token whole (no merge). init
|
|
607
|
+
seeds one Token per initialTokens answer (the recommended answers give
|
|
608
|
+
tok_color_brand, tok_spacing_md, tok_radius_md; the init reply lists them in
|
|
609
|
+
seeded.tokens); put-token with one of those ids redefines it.
|
|
610
|
+
Rerunning with the same --batch-id and intent after success returns
|
|
611
|
+
alreadyApplied:true; see smallpen apply --help for replay rules.
|
|
612
|
+
|
|
613
|
+
Intent example (a color with a dark value, and a typography Token):
|
|
614
|
+
{"operations":[
|
|
615
|
+
{"type":"put-token","filePath":"tokens/foundation.json","path":"color.surface",
|
|
616
|
+
"tokenId":"tok_color_surface","definition":{"$type":"color","$value":"#ffffff",
|
|
617
|
+
"$extensions":{"smallpen":{"id":"tok_color_surface","contextValues":
|
|
618
|
+
[{"when":{"axis_theme":"dark"},"value":"#1c1b1f"}]}}}},
|
|
619
|
+
{"type":"put-token","filePath":"tokens/foundation.json","path":"type.heading",
|
|
620
|
+
"tokenId":"tok_type_heading","definition":{"$type":"typography","$value":
|
|
621
|
+
{"fontFamily":"Inter","fontSize":24,"fontWeight":700},
|
|
622
|
+
"$extensions":{"smallpen":{"id":"tok_type_heading"}}}}]}
|
|
623
|
+
|
|
624
|
+
Shapes:
|
|
625
|
+
smallpen schema token definition, contextValues, bindable fields
|
|
626
|
+
smallpen schema token-types the value each type accepts
|
|
627
|
+
smallpen schema operation set-token-value
|
|
628
|
+
|
|
629
|
+
${WRITE_REPLY}`,
|
|
480
630
|
impact: `Usage:
|
|
481
631
|
smallpen impact <product.smallpen> (--token-id TOK | --path TOKEN.PATH) [--package-id PKG] [--json]
|
|
482
632
|
|
|
@@ -487,16 +637,37 @@ Purpose:
|
|
|
487
637
|
Tokens are resolved through the Product dependency; use --package-id to
|
|
488
638
|
disambiguate a Token ID or path that exists in both Packages.`,
|
|
489
639
|
apply: `Usage:
|
|
490
|
-
smallpen apply <package.smallpen> --batch BATCH.json [--dry-run]
|
|
491
|
-
[--warning-detail compact|full] [--confirm-unmatched]
|
|
640
|
+
smallpen apply <package.smallpen> --batch BATCH.json [--dry-run] [--explain] [--diff]
|
|
641
|
+
[--warning-detail compact|full] [--confirm-unmatched]
|
|
642
|
+
[--compact] [--inverse-out FILE] [--json]
|
|
492
643
|
|
|
493
644
|
Batch contract:
|
|
494
645
|
{"baseRevision":"...","batchId":"unique-id","operations":[...]}
|
|
646
|
+
baseRevision is package.revision from smallpen inspect PACKAGE --json.
|
|
495
647
|
The whole candidate validates and commits atomically. Success returns revision,
|
|
496
|
-
affected stable IDs/files,
|
|
648
|
+
affected stable IDs/files, an exact inverseBatch for Undo/Redo, and changed
|
|
649
|
+
(false, with noChange, when the batch leaves the Package as it was).
|
|
497
650
|
Revisions are content hashes, not increasing counters: restoring the exact
|
|
498
651
|
Canonical content restores its previous revision.
|
|
499
652
|
|
|
653
|
+
Operations:
|
|
654
|
+
smallpen schema operations every type, purpose, Package, required fields
|
|
655
|
+
smallpen schema operation TYPE fields, allowed values, example, inverse
|
|
656
|
+
Unknown operation types and unknown fields are rejected, with a suggestion.
|
|
657
|
+
Tokens, Context Axes, and shared Component Sets go to the Foundation; Screens,
|
|
658
|
+
nodes, Instances, and Scenarios go to the Product.
|
|
659
|
+
Example: {"baseRevision":"<revision>","batchId":"resize-home-1","operations":[
|
|
660
|
+
{"type":"update-presentation-node","screenId":"scr_home",
|
|
661
|
+
"presentationId":"pres_home_mobile","nodeId":"node_home_root",
|
|
662
|
+
"changes":{"width":360,"height":640}}]}
|
|
663
|
+
|
|
664
|
+
Component instance overrides:
|
|
665
|
+
set-instance-override {screenId, presentationId?, nodeId, overridePath, value}
|
|
666
|
+
and clear-instance-override {screenId, presentationId?, nodeId, overridePath}
|
|
667
|
+
change one field of one Instance node without touching the shared component.
|
|
668
|
+
overridePath is "<sourceNodeId>:<field>", or "<nestedInstanceId>__<sourceNodeId>:<field>"
|
|
669
|
+
inside a nested instance. Fields: fills, name, opacity, text, visible.
|
|
670
|
+
|
|
500
671
|
Token references on nodes:
|
|
501
672
|
tokenBindings uses package-qualified references, for example
|
|
502
673
|
{"fill":{"packageId":"pkg_foundation","assetId":"tok_brand"}}.
|
|
@@ -506,7 +677,10 @@ Token references on nodes:
|
|
|
506
677
|
|
|
507
678
|
Raw-value confirmation policy:
|
|
508
679
|
Writes that resolve to no Token return a non-blocking design_token_value_unmatched
|
|
509
|
-
warning; the write itself is not gated.
|
|
680
|
+
warning; the write itself is not gated. Warnings are design advice, not
|
|
681
|
+
validity: validate does not repeat them, and warningSummary.note says so. Raw
|
|
682
|
+
width/height values are listed only when a Token resolves to them or lies within
|
|
683
|
+
10% (at least 2); the rest are counted in warningSummary.suppressed. --confirm-unmatched is an explicit,
|
|
510
684
|
machine-readable acknowledgment: the response marks those warning groups with
|
|
511
685
|
"confirmed": true. Omitting the flag changes nothing about the write.
|
|
512
686
|
|
|
@@ -518,23 +692,36 @@ Warning output:
|
|
|
518
692
|
and summary contextScope, then sort by warningIndex to recover the original list.
|
|
519
693
|
Select --warning-detail full before executing to emit the original flat list.
|
|
520
694
|
Do not replay an already applied batch just to expand warnings: compact output
|
|
521
|
-
already contains every occurrence, and stale-revision checks still apply.
|
|
695
|
+
already contains every listed occurrence, and stale-revision checks still apply.
|
|
696
|
+
|
|
697
|
+
${WRITE_REPLY}
|
|
522
698
|
|
|
523
699
|
Errors and recovery:
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
700
|
+
Committed batch identities are recorded beside the Package. Retrying the same
|
|
701
|
+
batchId with the same baseRevision and operations, from any process, returns the
|
|
702
|
+
recorded confirmation with alreadyApplied:true and writes nothing, as long as
|
|
703
|
+
the Package is still at the recorded revision. If the batch's effect was undone
|
|
704
|
+
(the Package is back at its baseRevision) the retry applies it again as a new
|
|
705
|
+
write. If later writes moved the Package elsewhere the retry exits
|
|
706
|
+
batch_superseded with committedRevision and currentRevision. The same batchId
|
|
707
|
+
with a different baseRevision or operations exits batch_id_conflict.
|
|
708
|
+
flow, page, token, and import-tokens rebuild the batch from the current
|
|
709
|
+
revision; rerunning one with the same --batch-id and input after success
|
|
710
|
+
returns alreadyApplied:true under the same rules.
|
|
527
711
|
stale_revision returns actual/base revisions. Inspect current content first:
|
|
528
712
|
the intended change may already be committed. Rebuild only the remaining intent
|
|
529
713
|
against the actual revision and use a new unique batch ID; do not blindly replay.
|
|
530
|
-
--dry-run validates and returns the result/inverse without writing.
|
|
714
|
+
--dry-run validates and returns the result/inverse without writing. --explain
|
|
715
|
+
adds per-operation targets and --diff a before/after field diff of every
|
|
716
|
+
changed entry; both are previews that never write, with or without --dry-run.
|
|
531
717
|
Invalid batches never write.`,
|
|
532
718
|
watch: `Usage:
|
|
533
719
|
smallpen watch <package.smallpen> [--interval MS] [--max-events N] [--json]
|
|
534
720
|
|
|
535
721
|
Watch is the public live mode: it polls the Canonical Package and emits one NDJSON
|
|
536
722
|
{event:"revision", packageId, revision} line whenever the on-disk revision
|
|
537
|
-
changes
|
|
723
|
+
changes. An unreadable package emits one {event:"invalid", code, message} line
|
|
724
|
+
(again only when the error changes); recovery emits its revision line again.
|
|
538
725
|
The initial revision is emitted immediately. --max-events bounds the run for
|
|
539
726
|
scripted use; Ctrl-C exits 0. Watch never writes.
|
|
540
727
|
|
|
@@ -559,10 +746,14 @@ export function printHelp(command) {
|
|
|
559
746
|
process.stdout.write(`SmallPen ${command}\n\n${HELP[command]}
|
|
560
747
|
|
|
561
748
|
Common output and error contract:
|
|
562
|
-
--json emits stable English keys; localized labels remain additional data
|
|
749
|
+
--json emits stable English keys; localized labels remain additional data and
|
|
750
|
+
follow --locale where offered, else LC_ALL, LC_MESSAGES, or LANG (zh* selects
|
|
751
|
+
Chinese, anything else English). Success
|
|
563
752
|
exits 0. Errors exit 1 as {error:{code,message,details}} and include exact
|
|
564
753
|
nextOperations when recovery requires refresh, replay, Repair, or confirmation.
|
|
565
|
-
Unknown options are not part of the command contract shown above.
|
|
754
|
+
Unknown options are not part of the command contract shown above. Only options
|
|
755
|
+
shown with ..., repeated, or described as repeatable may appear more than once;
|
|
756
|
+
any other option given twice exits duplicate_option.
|
|
566
757
|
|
|
567
758
|
Help / next:
|
|
568
759
|
smallpen --help
|
|
@@ -573,8 +764,16 @@ Help / next:
|
|
|
573
764
|
process.stdout.write(`SmallPen Canonical Package CLI
|
|
574
765
|
|
|
575
766
|
Model:
|
|
576
|
-
One .smallpen directory is one Canonical Package.
|
|
577
|
-
|
|
767
|
+
One .smallpen directory is one Canonical Package. init creates a Foundation
|
|
768
|
+
(<name>-foundation.smallpen: shared Tokens, Context Axes, shared Component Sets)
|
|
769
|
+
and a Product (<name>.smallpen: Screens, Presentations, Scenarios). Write Tokens
|
|
770
|
+
and components to the Foundation; write Screens and nodes to the Product, and
|
|
771
|
+
pass the Product to read-view, render, evidence, tokens, and search-*.
|
|
772
|
+
A Presentation renders at the size of its root node: resize it with
|
|
773
|
+
update-presentation-node; update-presentation {viewport} keeps the declared
|
|
774
|
+
size in step.
|
|
775
|
+
A Product references exactly one same-workspace Foundation by permanent Package
|
|
776
|
+
ID and relative path. Every CLI call
|
|
578
777
|
receives its Package locator and complete selectors explicitly; there is no current
|
|
579
778
|
selection, current page, or cross-call session state. Packages are never merged into
|
|
580
779
|
a synthetic multi-root file. CLI, Desktop, renderer, and Agents share one resolver
|
|
@@ -612,6 +811,11 @@ Common workflow:
|
|
|
612
811
|
smallpen import-draft ./workspace/import-1.smallpen --kind figma --input clipboard.html --json
|
|
613
812
|
smallpen repair ./workspace/product.smallpen --json
|
|
614
813
|
|
|
814
|
+
Worked example (tokens, component set, screen, instance override, render):
|
|
815
|
+
${workedExampleText()}
|
|
816
|
+
|
|
817
|
+
Every write input has a schema and a tested example: smallpen schema
|
|
818
|
+
(operations, node, token, component-set, instance, presentation, batch, init).
|
|
615
819
|
Run smallpen <command> --help for syntax, defaults, values, examples, outputs,
|
|
616
820
|
errors, and relevant next commands.
|
|
617
821
|
`);
|