@penpair/core 0.1.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/dist/adapters.d.ts +16 -1
  2. package/dist/adapters.js +62 -19
  3. package/dist/approvals.d.ts +32 -0
  4. package/dist/approvals.js +213 -0
  5. package/dist/atomic-output.d.ts +5 -0
  6. package/dist/atomic-output.js +33 -0
  7. package/dist/audit-rules.d.ts +60 -0
  8. package/dist/audit-rules.js +443 -0
  9. package/dist/backup-note.d.ts +4 -0
  10. package/dist/backup-note.js +49 -0
  11. package/dist/baseline-coverage.d.ts +25 -0
  12. package/dist/baseline-coverage.js +248 -0
  13. package/dist/baselines-config.d.ts +25 -0
  14. package/dist/baselines-config.js +150 -11
  15. package/dist/baselines.d.ts +37 -8
  16. package/dist/baselines.js +362 -59
  17. package/dist/cli-arguments.d.ts +7 -0
  18. package/dist/cli-arguments.js +47 -0
  19. package/dist/cli-main.d.ts +13 -1
  20. package/dist/cli-main.js +2107 -247
  21. package/dist/client.d.ts +30 -6
  22. package/dist/client.js +160 -35
  23. package/dist/command-result.d.ts +159 -0
  24. package/dist/command-result.js +468 -0
  25. package/dist/coordination.d.ts +15 -0
  26. package/dist/coordination.js +184 -0
  27. package/dist/credentials.d.ts +21 -0
  28. package/dist/credentials.js +105 -0
  29. package/dist/deep-check.js +57 -9
  30. package/dist/design-spec.d.ts +55 -0
  31. package/dist/design-spec.js +275 -0
  32. package/dist/endpoint.d.ts +8 -1
  33. package/dist/endpoint.js +133 -21
  34. package/dist/errors.d.ts +2 -1
  35. package/dist/errors.js +8 -4
  36. package/dist/export.d.ts +18 -0
  37. package/dist/export.js +113 -10
  38. package/dist/file-archive.d.ts +16 -0
  39. package/dist/file-archive.js +58 -0
  40. package/dist/file-guard.d.ts +8 -0
  41. package/dist/file-guard.js +58 -0
  42. package/dist/formats.d.ts +4 -0
  43. package/dist/formats.js +229 -0
  44. package/dist/index.d.ts +34 -1
  45. package/dist/index.js +34 -1
  46. package/dist/inspection.d.ts +106 -0
  47. package/dist/inspection.js +657 -0
  48. package/dist/instance/config-schema.d.ts +422 -0
  49. package/dist/instance/config-schema.js +435 -0
  50. package/dist/instance/config.d.ts +29 -0
  51. package/dist/instance/config.js +191 -29
  52. package/dist/instance/connect.d.ts +10 -1
  53. package/dist/instance/connect.js +178 -30
  54. package/dist/instance/connection.d.ts +39 -4
  55. package/dist/instance/connection.js +198 -14
  56. package/dist/instance/gitignore.js +5 -2
  57. package/dist/instance/init.js +32 -7
  58. package/dist/instance/runner.js +32 -10
  59. package/dist/instance/setup.js +46 -13
  60. package/dist/instance/tty.js +28 -8
  61. package/dist/journal.d.ts +87 -0
  62. package/dist/journal.js +423 -0
  63. package/dist/kit-smoke.d.ts +31 -0
  64. package/dist/kit-smoke.js +145 -0
  65. package/dist/kit-source.d.ts +2 -0
  66. package/dist/kit-source.js +279 -0
  67. package/dist/kit.d.ts +25 -0
  68. package/dist/kit.js +158 -0
  69. package/dist/layout-policy.d.ts +2 -0
  70. package/dist/layout-policy.js +86 -0
  71. package/dist/layout.d.ts +21 -0
  72. package/dist/layout.js +36 -0
  73. package/dist/live-smoke.d.ts +8 -0
  74. package/dist/live-smoke.js +23 -0
  75. package/dist/local-profile.js +2 -1
  76. package/dist/mcp-server.d.ts +12 -0
  77. package/dist/mcp-server.js +415 -0
  78. package/dist/native-api.d.ts +15 -0
  79. package/dist/native-api.js +78 -0
  80. package/dist/onboard.d.ts +10 -0
  81. package/dist/onboard.js +41 -0
  82. package/dist/operation.d.ts +22 -3
  83. package/dist/operation.js +341 -31
  84. package/dist/page-session.d.ts +23 -0
  85. package/dist/page-session.js +142 -0
  86. package/dist/png.d.ts +5 -0
  87. package/dist/png.js +22 -0
  88. package/dist/portable-tokens.d.ts +22 -0
  89. package/dist/portable-tokens.js +331 -0
  90. package/dist/probe.d.ts +6 -2
  91. package/dist/probe.js +64 -11
  92. package/dist/project-input.d.ts +6 -0
  93. package/dist/project-input.js +65 -0
  94. package/dist/project-snippets.js +29 -12
  95. package/dist/project-status.d.ts +24 -0
  96. package/dist/project-status.js +188 -0
  97. package/dist/registry.d.ts +2 -1
  98. package/dist/registry.js +224 -53
  99. package/dist/run-file.d.ts +26 -0
  100. package/dist/run-file.js +199 -0
  101. package/dist/shots.d.ts +43 -0
  102. package/dist/shots.js +172 -0
  103. package/dist/skill-instructions.d.ts +13 -0
  104. package/dist/skill-instructions.js +144 -0
  105. package/dist/skills.d.ts +7 -0
  106. package/dist/skills.js +163 -46
  107. package/dist/snippet.d.ts +3 -2
  108. package/dist/snippet.js +33 -9
  109. package/dist/snippets/archive.d.ts +9 -0
  110. package/dist/snippets/archive.js +10 -4
  111. package/dist/snippets/read.d.ts +1 -1
  112. package/dist/snippets/read.js +78 -41
  113. package/dist/structure-snapshot.d.ts +85 -0
  114. package/dist/structure-snapshot.js +525 -0
  115. package/dist/token-edit.d.ts +53 -0
  116. package/dist/token-edit.js +352 -0
  117. package/dist/token-projection.d.ts +56 -0
  118. package/dist/token-projection.js +286 -0
  119. package/dist/tokens-diff.d.ts +19 -6
  120. package/dist/tokens-diff.js +182 -18
  121. package/dist/version.d.ts +1 -1
  122. package/dist/version.js +1 -1
  123. package/package.json +1 -1
  124. package/skills/penpair-design/SKILL.md +20 -45
  125. package/skills/penpair-design/references/penpot-plugin-gotchas.md +58 -2
  126. package/skills/penpair-design/references/project-facts.md +3 -1
  127. package/skills/penpair-design/references/write-protocol.md +15 -3
  128. package/skills/penpair-handoff/SKILL.md +16 -0
  129. package/skills/penpair-handoff/references/comparison-companion.md +13 -0
  130. package/skills/penpair-handoff/references/handoff-flow.md +13 -0
  131. package/skills/penpair-recipes/SKILL.md +21 -0
  132. package/skills/penpair-recipes/references/build-flow.md +11 -0
  133. package/skills/penpair-setup/SKILL.md +8 -2
  134. package/dist/cli.d.ts +0 -2
  135. package/dist/cli.js +0 -3
  136. package/dist/docker/lifecycle.d.ts +0 -96
  137. package/dist/docker/lifecycle.js +0 -273
  138. package/dist/docker/secrets.d.ts +0 -11
  139. package/dist/docker/secrets.js +0 -38
  140. package/dist/docker/template.d.ts +0 -8
  141. package/dist/docker/template.js +0 -158
  142. package/dist/docker-profile.d.ts +0 -114
  143. package/dist/docker-profile.js +0 -18
  144. package/dist/instance/lifecycle.d.ts +0 -129
  145. package/dist/instance/lifecycle.js +0 -336
  146. package/dist/instance/secrets.d.ts +0 -11
  147. package/dist/instance/secrets.js +0 -38
  148. package/dist/instance/template.d.ts +0 -8
  149. package/dist/instance/template.js +0 -158
@@ -0,0 +1,435 @@
1
+ const viewportSchema = {
2
+ type: "object",
3
+ required: [
4
+ "width",
5
+ "height",
6
+ ],
7
+ additionalProperties: false,
8
+ properties: {
9
+ width: {
10
+ type: "integer",
11
+ minimum: 1,
12
+ maximum: 16384,
13
+ },
14
+ height: {
15
+ type: "integer",
16
+ minimum: 1,
17
+ maximum: 16384,
18
+ },
19
+ },
20
+ };
21
+ const caseFields = {
22
+ viewport: viewportSchema,
23
+ theme: {
24
+ type: "string",
25
+ minLength: 1,
26
+ maxLength: 200,
27
+ },
28
+ state: {
29
+ type: "string",
30
+ minLength: 1,
31
+ maxLength: 200,
32
+ },
33
+ fixture: {
34
+ type: "string",
35
+ minLength: 1,
36
+ maxLength: 200,
37
+ },
38
+ };
39
+ const baselineCaseSchema = {
40
+ type: "object",
41
+ required: [
42
+ "viewport",
43
+ "theme",
44
+ "state",
45
+ "fixture",
46
+ ],
47
+ additionalProperties: false,
48
+ properties: {
49
+ ...caseFields,
50
+ fonts: {
51
+ type: "array",
52
+ maxItems: 100,
53
+ uniqueItems: true,
54
+ items: {
55
+ type: "string",
56
+ minLength: 1,
57
+ },
58
+ },
59
+ activeThemeIds: {
60
+ type: "array",
61
+ maxItems: 100,
62
+ uniqueItems: true,
63
+ items: {
64
+ type: "string",
65
+ minLength: 1,
66
+ },
67
+ },
68
+ },
69
+ };
70
+ const requiredCaseSchema = {
71
+ type: "object",
72
+ required: [
73
+ "route",
74
+ "viewport",
75
+ "theme",
76
+ "state",
77
+ "fixture",
78
+ ],
79
+ additionalProperties: false,
80
+ properties: {
81
+ route: {
82
+ type: "string",
83
+ minLength: 1,
84
+ },
85
+ ...caseFields,
86
+ },
87
+ };
88
+ /** Editor hints for the core settings. Adapter-owned properties remain open; `config check` also checks semantic constraints. */
89
+ export const projectConfigSchema = {
90
+ $schema: "https://json-schema.org/draft/2020-12/schema",
91
+ title: "penpair project configuration",
92
+ type: "object",
93
+ required: [
94
+ "instance",
95
+ ],
96
+ properties: {
97
+ schemaVersion: {
98
+ const: 1,
99
+ },
100
+ connection: {
101
+ type: "object",
102
+ additionalProperties: false,
103
+ required: [
104
+ "credential",
105
+ ],
106
+ properties: {
107
+ credential: {
108
+ oneOf: [
109
+ {
110
+ type: "object",
111
+ additionalProperties: false,
112
+ required: [
113
+ "type",
114
+ "path",
115
+ ],
116
+ properties: {
117
+ type: {
118
+ const: "file",
119
+ },
120
+ path: {
121
+ type: "string",
122
+ minLength: 1,
123
+ },
124
+ },
125
+ },
126
+ {
127
+ type: "object",
128
+ additionalProperties: false,
129
+ required: [
130
+ "type",
131
+ "service",
132
+ "account",
133
+ ],
134
+ properties: {
135
+ type: {
136
+ const: "keychain",
137
+ },
138
+ service: {
139
+ type: "string",
140
+ minLength: 1,
141
+ },
142
+ account: {
143
+ type: "string",
144
+ minLength: 1,
145
+ },
146
+ },
147
+ },
148
+ ],
149
+ },
150
+ },
151
+ },
152
+ audit: {
153
+ type: "object",
154
+ additionalProperties: false,
155
+ properties: {
156
+ contrast: {
157
+ type: "boolean",
158
+ },
159
+ library: {
160
+ type: "boolean",
161
+ },
162
+ touchTargets: {
163
+ type: "boolean",
164
+ },
165
+ names: {
166
+ type: "boolean",
167
+ },
168
+ blankText: {
169
+ type: "boolean",
170
+ },
171
+ interactiveIds: {
172
+ type: "array",
173
+ maxItems: 1000,
174
+ items: {
175
+ type: "string",
176
+ },
177
+ },
178
+ allowBlank: {
179
+ type: "array",
180
+ maxItems: 1000,
181
+ items: {
182
+ type: "string",
183
+ },
184
+ },
185
+ nameSegments: {
186
+ type: "integer",
187
+ minimum: 1,
188
+ maximum: 10,
189
+ },
190
+ suppressions: {
191
+ type: "array",
192
+ maxItems: 1000,
193
+ items: {
194
+ type: "object",
195
+ required: [
196
+ "rule",
197
+ "nodeId",
198
+ "reason",
199
+ ],
200
+ properties: {
201
+ rule: {
202
+ enum: [
203
+ "contrast",
204
+ "library",
205
+ "touch-target",
206
+ "names",
207
+ "blank-text",
208
+ ],
209
+ },
210
+ nodeId: {
211
+ type: "string",
212
+ },
213
+ reason: {
214
+ type: "string",
215
+ minLength: 1,
216
+ },
217
+ },
218
+ },
219
+ },
220
+ },
221
+ },
222
+ backup: {
223
+ type: "object",
224
+ required: [
225
+ "noteFile",
226
+ "remindAfterDays",
227
+ ],
228
+ properties: {
229
+ noteFile: {
230
+ type: "string",
231
+ minLength: 1,
232
+ pattern: "^(?![/\\\\])(?!.*(?:^|[/\\\\])\\.\\.(?:[/\\\\]|$)).+$",
233
+ },
234
+ remindAfterDays: {
235
+ type: "integer",
236
+ minimum: 1,
237
+ },
238
+ },
239
+ },
240
+ file: {
241
+ type: "object",
242
+ required: [
243
+ "id",
244
+ ],
245
+ properties: {
246
+ id: {
247
+ type: "string",
248
+ minLength: 1,
249
+ pattern: "\\S",
250
+ },
251
+ name: {
252
+ type: "string",
253
+ },
254
+ },
255
+ },
256
+ instance: {
257
+ type: "string",
258
+ pattern: "^[a-z][a-z0-9-]{0,30}$",
259
+ },
260
+ snippets: {
261
+ type: "array",
262
+ items: {
263
+ type: "string",
264
+ minLength: 1,
265
+ pattern: "^(?![/\\\\])(?![A-Za-z]:[/\\\\])(?!.*(?:^|[/\\\\])\\.\\.(?:[/\\\\]|$)).+$",
266
+ },
267
+ },
268
+ adapters: {
269
+ type: "array",
270
+ items: {
271
+ type: "string",
272
+ minLength: 1,
273
+ },
274
+ },
275
+ baselines: {
276
+ type: "object",
277
+ required: [
278
+ "page",
279
+ "root",
280
+ "frames",
281
+ ],
282
+ properties: {
283
+ page: {
284
+ type: "string",
285
+ minLength: 1,
286
+ },
287
+ root: {
288
+ type: "string",
289
+ minLength: 1,
290
+ pattern: "^(?![/\\\\])(?![A-Za-z]:[/\\\\])(?!.*(?:^|[/\\\\])\\.\\.(?:[/\\\\]|$)).+$",
291
+ },
292
+ coverage: {
293
+ type: "object",
294
+ required: [
295
+ "required",
296
+ ],
297
+ properties: {
298
+ required: {
299
+ type: "array",
300
+ minItems: 1,
301
+ maxItems: 1000,
302
+ items: requiredCaseSchema,
303
+ },
304
+ unsupported: {
305
+ type: "array",
306
+ maxItems: 1000,
307
+ items: {
308
+ ...requiredCaseSchema,
309
+ required: [
310
+ ...requiredCaseSchema.required,
311
+ "reason",
312
+ ],
313
+ properties: {
314
+ ...requiredCaseSchema.properties,
315
+ reason: {
316
+ type: "string",
317
+ minLength: 1,
318
+ },
319
+ },
320
+ },
321
+ },
322
+ },
323
+ },
324
+ threshold: {
325
+ type: "number",
326
+ minimum: 0,
327
+ maximum: 1,
328
+ },
329
+ frames: {
330
+ type: "array",
331
+ minItems: 1,
332
+ maxItems: 1000,
333
+ items: {
334
+ type: "object",
335
+ required: [
336
+ "frame",
337
+ "id",
338
+ ],
339
+ dependentRequired: {
340
+ case: [
341
+ "route",
342
+ ],
343
+ },
344
+ properties: {
345
+ frame: {
346
+ type: "string",
347
+ minLength: 1,
348
+ },
349
+ id: {
350
+ type: "string",
351
+ pattern: "^[a-z0-9][a-z0-9_-]{0,63}$",
352
+ },
353
+ route: {
354
+ type: "string",
355
+ minLength: 1,
356
+ },
357
+ case: baselineCaseSchema,
358
+ },
359
+ },
360
+ },
361
+ },
362
+ },
363
+ },
364
+ oneOf: [
365
+ {
366
+ required: [
367
+ "profile",
368
+ ],
369
+ properties: {
370
+ profile: {
371
+ type: "object",
372
+ required: [
373
+ "type",
374
+ "origin",
375
+ ],
376
+ properties: {
377
+ type: {
378
+ const: "external",
379
+ },
380
+ origin: {
381
+ type: "string",
382
+ pattern: "^https?://[^/?#]+$",
383
+ },
384
+ },
385
+ },
386
+ },
387
+ },
388
+ {
389
+ required: [
390
+ "penpotVersion",
391
+ "ports",
392
+ "directory",
393
+ ],
394
+ not: {
395
+ required: [
396
+ "profile",
397
+ ],
398
+ },
399
+ properties: {
400
+ penpotVersion: {
401
+ type: "string",
402
+ pattern: "^\\d+\\.\\d+(\\.\\d+)?$",
403
+ },
404
+ ports: {
405
+ type: "object",
406
+ required: [
407
+ "frontend",
408
+ "mail",
409
+ ],
410
+ properties: {
411
+ frontend: {
412
+ type: "integer",
413
+ minimum: 1024,
414
+ maximum: 65535,
415
+ },
416
+ mail: {
417
+ type: "integer",
418
+ minimum: 1024,
419
+ maximum: 65535,
420
+ },
421
+ },
422
+ },
423
+ directory: {
424
+ type: "string",
425
+ minLength: 1,
426
+ pattern: "^(?!/).+$",
427
+ },
428
+ composeProject: {
429
+ type: "string",
430
+ pattern: "^[a-z0-9][a-z0-9_-]*$",
431
+ },
432
+ },
433
+ },
434
+ ],
435
+ };
@@ -1,6 +1,23 @@
1
+ import { type CredentialReference } from "../credentials.js";
2
+ import { type AuditRules } from "../audit-rules.js";
1
3
  import { type BaselinesConfig } from "../baselines-config.js";
2
4
  /** What a project keeps in `penpair.config.json`: no secrets, so it can be committed. */
5
+ export interface ProjectFile {
6
+ id: string;
7
+ name?: string;
8
+ }
9
+ export interface BackupReminder {
10
+ noteFile: string;
11
+ remindAfterDays: number;
12
+ }
3
13
  export interface InstanceConfig {
14
+ schemaVersion?: 1;
15
+ audit?: AuditRules;
16
+ connection?: {
17
+ credential: CredentialReference;
18
+ };
19
+ file?: ProjectFile;
20
+ backup?: BackupReminder;
4
21
  /** Short name; it becomes part of the compose project, so containers and volumes of two instances never collide. */
5
22
  instance: string;
6
23
  /** Pinned Penpot image version. Run the smoke test before changing it. */
@@ -22,6 +39,13 @@ export interface InstanceConfig {
22
39
  }
23
40
  /** A project that uses a Penpot someone else runs (a team server or the hosted service): no Docker here, only the connection. */
24
41
  export interface ExternalConfig {
42
+ schemaVersion?: 1;
43
+ audit?: AuditRules;
44
+ connection?: {
45
+ credential: CredentialReference;
46
+ };
47
+ file?: ProjectFile;
48
+ backup?: BackupReminder;
25
49
  instance: string;
26
50
  profile: {
27
51
  type: "external";
@@ -36,6 +60,8 @@ export declare const isExternal: (config: ProjectConfig) => config is ExternalCo
36
60
  export declare const configFileName = "penpair.config.json";
37
61
  export declare const testedPenpotVersion = "2.18.3";
38
62
  export declare class ConfigError extends Error {
63
+ readonly code: "missing" | "unreadable" | "invalid-json" | "invalid-config";
64
+ constructor(message: string, code?: "missing" | "unreadable" | "invalid-json" | "invalid-config");
39
65
  }
40
66
  export declare function composeProjectOf(config: InstanceConfig): string;
41
67
  export declare function validateConfig(value: unknown): InstanceConfig;
@@ -43,6 +69,9 @@ export declare function validateConfig(value: unknown): InstanceConfig;
43
69
  export declare function validateProjectConfig(value: unknown): ProjectConfig;
44
70
  /** The config of a project that runs its own Penpot; anything else cannot start, stop or back up containers. */
45
71
  export declare function requireLocal(config: ProjectConfig): InstanceConfig;
72
+ /** Missing is optional; unreadable, malformed or invalid project files always stop the caller. */
73
+ export declare function readProjectConfig(root: string): Promise<Record<string, unknown> | undefined>;
74
+ export declare function loadOptionalConfig(root: string): Promise<ProjectConfig | undefined>;
46
75
  export declare function loadConfig(root: string): Promise<ProjectConfig>;
47
76
  export declare const instancePaths: (root: string, config: InstanceConfig) => {
48
77
  directory: string;