release-skill 0.2.0 → 0.2.1

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 (45) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codebuddy-plugin/plugin.json +10 -0
  4. package/.codex-plugin/plugin.json +2 -2
  5. package/.kimi-plugin/plugin.json +1 -1
  6. package/CHANGELOG.md +14 -0
  7. package/INSTALL.md +24 -4
  8. package/INSTALL.zh-CN.md +22 -4
  9. package/README.md +15 -13
  10. package/README.zh-CN.md +10 -13
  11. package/adapters/claude/.claude-plugin/marketplace.json +1 -1
  12. package/adapters/claude/.claude-plugin/plugin.json +1 -1
  13. package/adapters/claude/bin/release-skill.bundle.mjs +1 -1
  14. package/adapters/codex/.codex-plugin/plugin.json +2 -2
  15. package/adapters/codex/bin/release-skill.bundle.mjs +1 -1
  16. package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
  17. package/adapters/kimi/bin/release-skill.bundle.mjs +1 -1
  18. package/adapters/workbuddy/.codebuddy-plugin/plugin.json +10 -0
  19. package/adapters/workbuddy/bin/release-skill.bundle.mjs +85363 -0
  20. package/adapters/workbuddy/bin/release-skill.mjs +54 -0
  21. package/adapters/workbuddy/native/safe-write/binding.gyp +41 -0
  22. package/adapters/workbuddy/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
  23. package/adapters/workbuddy/native/safe-write/prebuilds.json +24 -0
  24. package/adapters/workbuddy/native/safe-write/src/safe_write.cc +2032 -0
  25. package/adapters/workbuddy/schemas/.render-manifest.json +37 -0
  26. package/adapters/workbuddy/schemas/approval-record.schema.json +115 -0
  27. package/adapters/workbuddy/schemas/artifact-lock.schema.json +111 -0
  28. package/adapters/workbuddy/schemas/artifact-plan.schema.json +52 -0
  29. package/adapters/workbuddy/schemas/artifact-policy.schema.json +76 -0
  30. package/adapters/workbuddy/schemas/evidence-event.schema.json +89 -0
  31. package/adapters/workbuddy/schemas/release-plan.schema.json +882 -0
  32. package/adapters/workbuddy/schemas/release-project.schema.json +909 -0
  33. package/adapters/workbuddy/schemas/release-run.schema.json +343 -0
  34. package/adapters/workbuddy/skills/release-assess/SKILL.md +51 -0
  35. package/adapters/workbuddy/skills/release-help/SKILL.md +77 -0
  36. package/adapters/workbuddy/skills/release-prepare/SKILL.md +92 -0
  37. package/adapters/workbuddy/skills/release-publish/SKILL.md +57 -0
  38. package/adapters/workbuddy/skills/release-reconcile/SKILL.md +73 -0
  39. package/adapters/workbuddy/skills/release-setup/SKILL.md +95 -0
  40. package/adapters/workbuddy/skills/release-verify/SKILL.md +70 -0
  41. package/bin/release-skill.bundle.mjs +1 -1
  42. package/package.json +2 -1
  43. package/references/06-adapter-contract.md +1 -1
  44. package/scripts/sync-public-files.mjs +21 -2
  45. package/src/producers/build-adapters.mjs +38 -4
@@ -0,0 +1,909 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://release-skill.dev/schemas/release-project/v1",
4
+ "title": "Release Project Configuration",
5
+ "description": "Schema for .release-skill/project.yaml project configuration file",
6
+ "type": "object",
7
+ "required": [
8
+ "apiVersion",
9
+ "kind",
10
+ "project",
11
+ "releaseUnits"
12
+ ],
13
+ "additionalProperties": false,
14
+ "properties": {
15
+ "apiVersion": {
16
+ "type": "string",
17
+ "const": "release-skill/v1"
18
+ },
19
+ "kind": {
20
+ "type": "string",
21
+ "const": "ReleaseProject"
22
+ },
23
+ "project": {
24
+ "type": "object",
25
+ "required": [
26
+ "name",
27
+ "defaultBranch"
28
+ ],
29
+ "additionalProperties": false,
30
+ "properties": {
31
+ "name": {
32
+ "type": "string",
33
+ "minLength": 1
34
+ },
35
+ "defaultBranch": {
36
+ "type": "string",
37
+ "minLength": 1
38
+ }
39
+ }
40
+ },
41
+ "releaseUnits": {
42
+ "type": "array",
43
+ "minItems": 1,
44
+ "items": {
45
+ "type": "object",
46
+ "required": [
47
+ "id",
48
+ "source",
49
+ "publicRepo",
50
+ "version",
51
+ "distributions",
52
+ "publicFiles",
53
+ "requiredPublicFiles",
54
+ "previousPublicBaseline"
55
+ ],
56
+ "additionalProperties": false,
57
+ "properties": {
58
+ "id": {
59
+ "type": "string",
60
+ "minLength": 1,
61
+ "pattern": "^(?!\\.{1,2}$)[A-Za-z0-9][A-Za-z0-9._-]*$"
62
+ },
63
+ "source": {
64
+ "type": "string",
65
+ "minLength": 1,
66
+ "pattern": "^(?:\\.$|(?!\\/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(?:\\/|$))(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/\\/$)(?!.*\\/$).*)$"
67
+ },
68
+ "publicRepo": {
69
+ "type": "string",
70
+ "pattern": "^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$"
71
+ },
72
+ "production": {
73
+ "type": "object",
74
+ "additionalProperties": false,
75
+ "properties": {
76
+ "githubHost": {
77
+ "type": "string",
78
+ "pattern": "^[a-zA-Z0-9.-]+$"
79
+ },
80
+ "branchTemplate": {
81
+ "type": "string",
82
+ "minLength": 1
83
+ },
84
+ "releaseTitleTemplate": {
85
+ "type": "string",
86
+ "minLength": 1
87
+ },
88
+ "releaseNotes": {
89
+ "type": "string"
90
+ },
91
+ "branchStrategy": {
92
+ "type": "string",
93
+ "enum": [
94
+ "create-release-branch",
95
+ "advance-existing-branch",
96
+ "initialize-default-branch"
97
+ ]
98
+ },
99
+ "setAsDefaultBranch": {
100
+ "type": "boolean"
101
+ },
102
+ "expectedCurrentDefaultBranch": {
103
+ "type": "string",
104
+ "minLength": 1
105
+ }
106
+ }
107
+ },
108
+ "version": {
109
+ "type": "object",
110
+ "required": [
111
+ "source",
112
+ "tagTemplate"
113
+ ],
114
+ "additionalProperties": false,
115
+ "properties": {
116
+ "source": {
117
+ "type": "string",
118
+ "minLength": 1
119
+ },
120
+ "tagTemplate": {
121
+ "type": "string",
122
+ "minLength": 1
123
+ }
124
+ }
125
+ },
126
+ "distributions": {
127
+ "type": "array",
128
+ "minItems": 1,
129
+ "items": {
130
+ "type": "object",
131
+ "required": [
132
+ "type"
133
+ ],
134
+ "additionalProperties": false,
135
+ "properties": {
136
+ "type": {
137
+ "type": "string",
138
+ "enum": [
139
+ "npm",
140
+ "claude-plugin",
141
+ "codex-plugin",
142
+ "kimi-plugin"
143
+ ]
144
+ },
145
+ "package": {
146
+ "type": "string",
147
+ "minLength": 1,
148
+ "maxLength": 214,
149
+ "pattern": "^(?:@[a-z0-9][a-z0-9._-]*/[a-z0-9][a-z0-9._-]*|[a-z0-9][a-z0-9._-]*)$"
150
+ },
151
+ "access": {
152
+ "type": "string",
153
+ "enum": [
154
+ "public",
155
+ "restricted"
156
+ ]
157
+ },
158
+ "provenance": {
159
+ "type": "boolean"
160
+ },
161
+ "tag": {
162
+ "type": "string",
163
+ "minLength": 1
164
+ },
165
+ "registry": {
166
+ "type": "string",
167
+ "minLength": 1,
168
+ "pattern": "^https://[^\\s]+$",
169
+ "description": "Normalized HTTPS URL of the npm registry"
170
+ },
171
+ "publisher": {
172
+ "type": "string",
173
+ "minLength": 1,
174
+ "pattern": "^[a-z0-9][a-z0-9._-]*$",
175
+ "description": "Expected npm whoami username for this registry"
176
+ },
177
+ "plugin": {
178
+ "type": "string",
179
+ "minLength": 1,
180
+ "pattern": "^[a-z0-9][a-z0-9._-]*$"
181
+ },
182
+ "marketplace": {
183
+ "type": "string",
184
+ "minLength": 1,
185
+ "pattern": "^[a-z0-9][a-z0-9._-]*$"
186
+ },
187
+ "entrySkill": {
188
+ "type": "string",
189
+ "minLength": 1,
190
+ "pattern": "^[a-z0-9][a-z0-9-]*$"
191
+ },
192
+ "smokeBin": {
193
+ "type": "string",
194
+ "minLength": 1
195
+ },
196
+ "smokeArgs": {
197
+ "type": "array",
198
+ "items": {
199
+ "type": "string"
200
+ }
201
+ },
202
+ "smokeExpectedJson": {
203
+ "type": "object"
204
+ },
205
+ "timeoutMs": {
206
+ "type": "integer",
207
+ "minimum": 30000,
208
+ "maximum": 900000,
209
+ "description": "Timeout in milliseconds for plugin marketplace install commands (claude-plugin, codex-plugin). Kimi Code has no scriptable install command, so for kimi-plugin this bounds the read-only observation/verification only, not an install command. Only valid for claude-plugin, codex-plugin, and kimi-plugin distributions."
210
+ }
211
+ },
212
+ "allOf": [
213
+ {
214
+ "if": {
215
+ "properties": {
216
+ "type": {
217
+ "const": "npm"
218
+ }
219
+ }
220
+ },
221
+ "then": {
222
+ "required": [
223
+ "package",
224
+ "registry",
225
+ "publisher"
226
+ ]
227
+ }
228
+ },
229
+ {
230
+ "if": {
231
+ "required": [
232
+ "timeoutMs"
233
+ ]
234
+ },
235
+ "then": {
236
+ "properties": {
237
+ "type": {
238
+ "enum": [
239
+ "claude-plugin",
240
+ "codex-plugin",
241
+ "kimi-plugin"
242
+ ]
243
+ }
244
+ }
245
+ }
246
+ },
247
+ {
248
+ "if": {
249
+ "properties": {
250
+ "type": {
251
+ "enum": [
252
+ "claude-plugin",
253
+ "codex-plugin"
254
+ ]
255
+ }
256
+ }
257
+ },
258
+ "then": {
259
+ "required": [
260
+ "plugin",
261
+ "marketplace",
262
+ "entrySkill"
263
+ ]
264
+ }
265
+ },
266
+ {
267
+ "if": {
268
+ "properties": {
269
+ "type": {
270
+ "const": "kimi-plugin"
271
+ }
272
+ }
273
+ },
274
+ "then": {
275
+ "required": [
276
+ "plugin",
277
+ "entrySkill"
278
+ ]
279
+ }
280
+ },
281
+ {
282
+ "if": {
283
+ "required": [
284
+ "smokeExpectedJson"
285
+ ],
286
+ "properties": {
287
+ "smokeBin": {
288
+ "minLength": 1
289
+ }
290
+ }
291
+ },
292
+ "then": {
293
+ "required": [
294
+ "smokeBin"
295
+ ]
296
+ }
297
+ },
298
+ {
299
+ "if": {
300
+ "required": [
301
+ "smokeArgs"
302
+ ],
303
+ "properties": {
304
+ "smokeBin": {
305
+ "minLength": 1
306
+ }
307
+ }
308
+ },
309
+ "then": {
310
+ "required": [
311
+ "smokeBin"
312
+ ]
313
+ }
314
+ }
315
+ ]
316
+ }
317
+ },
318
+ "publicFiles": {
319
+ "type": "array",
320
+ "minItems": 1,
321
+ "items": {
322
+ "type": "object",
323
+ "required": [
324
+ "from",
325
+ "to",
326
+ "mode"
327
+ ],
328
+ "additionalProperties": false,
329
+ "properties": {
330
+ "sourceScope": {
331
+ "type": "string",
332
+ "enum": [
333
+ "unit",
334
+ "workspace"
335
+ ],
336
+ "default": "unit"
337
+ },
338
+ "from": {
339
+ "type": "string",
340
+ "minLength": 1,
341
+ "pattern": "^(?!/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(/|$))(?!\\.$)(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/$).*$"
342
+ },
343
+ "to": {
344
+ "type": "string",
345
+ "minLength": 1,
346
+ "pattern": "^(?!/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(/|$))(?!\\.$)(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/$).*$"
347
+ },
348
+ "mode": {
349
+ "type": "string",
350
+ "enum": [
351
+ "preserve"
352
+ ]
353
+ }
354
+ }
355
+ }
356
+ },
357
+ "requiredPublicFiles": {
358
+ "type": "array",
359
+ "uniqueItems": true,
360
+ "items": {
361
+ "type": "string",
362
+ "minLength": 1,
363
+ "pattern": "^(?!/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(/|$))(?!\\.$)(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/$).*$"
364
+ }
365
+ },
366
+ "previousPublicBaseline": {
367
+ "type": "object",
368
+ "required": [
369
+ "mode"
370
+ ],
371
+ "additionalProperties": false,
372
+ "properties": {
373
+ "mode": {
374
+ "type": "string",
375
+ "enum": [
376
+ "none",
377
+ "bound"
378
+ ]
379
+ },
380
+ "githubHost": {
381
+ "type": "string",
382
+ "pattern": "^[a-zA-Z0-9.-]+$"
383
+ },
384
+ "repo": {
385
+ "type": "string",
386
+ "pattern": "^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$"
387
+ },
388
+ "ref": {
389
+ "type": "string",
390
+ "minLength": 1
391
+ },
392
+ "commit": {
393
+ "type": "string",
394
+ "pattern": "^[a-f0-9]{40,64}$"
395
+ },
396
+ "tree": {
397
+ "type": "string",
398
+ "pattern": "^[a-f0-9]{40,64}$"
399
+ },
400
+ "manifestDigest": {
401
+ "type": "string",
402
+ "pattern": "^[a-f0-9]{64}$"
403
+ }
404
+ },
405
+ "if": {
406
+ "properties": {
407
+ "mode": {
408
+ "const": "bound"
409
+ }
410
+ }
411
+ },
412
+ "then": {
413
+ "required": [
414
+ "repo",
415
+ "ref",
416
+ "commit"
417
+ ]
418
+ },
419
+ "else": {
420
+ "allOf": [
421
+ {
422
+ "not": {
423
+ "required": [
424
+ "repo"
425
+ ]
426
+ }
427
+ },
428
+ {
429
+ "not": {
430
+ "required": [
431
+ "githubHost"
432
+ ]
433
+ }
434
+ },
435
+ {
436
+ "not": {
437
+ "required": [
438
+ "ref"
439
+ ]
440
+ }
441
+ },
442
+ {
443
+ "not": {
444
+ "required": [
445
+ "commit"
446
+ ]
447
+ }
448
+ },
449
+ {
450
+ "not": {
451
+ "required": [
452
+ "tree"
453
+ ]
454
+ }
455
+ },
456
+ {
457
+ "not": {
458
+ "required": [
459
+ "manifestDigest"
460
+ ]
461
+ }
462
+ }
463
+ ]
464
+ }
465
+ },
466
+ "releaseDocuments": {
467
+ "$ref": "#/definitions/releaseDocuments"
468
+ }
469
+ },
470
+ "allOf": [
471
+ {
472
+ "if": {
473
+ "required": [
474
+ "production"
475
+ ],
476
+ "properties": {
477
+ "production": {
478
+ "required": [
479
+ "branchStrategy"
480
+ ],
481
+ "properties": {
482
+ "branchStrategy": {
483
+ "enum": [
484
+ "advance-existing-branch",
485
+ "initialize-default-branch"
486
+ ]
487
+ }
488
+ }
489
+ }
490
+ }
491
+ },
492
+ "then": {
493
+ "properties": {
494
+ "previousPublicBaseline": {
495
+ "properties": {
496
+ "mode": {
497
+ "const": "bound"
498
+ }
499
+ },
500
+ "required": [
501
+ "mode"
502
+ ]
503
+ }
504
+ }
505
+ }
506
+ },
507
+ {
508
+ "if": {
509
+ "required": [
510
+ "production"
511
+ ],
512
+ "properties": {
513
+ "production": {
514
+ "required": [
515
+ "branchStrategy"
516
+ ],
517
+ "properties": {
518
+ "branchStrategy": {
519
+ "const": "initialize-default-branch"
520
+ }
521
+ }
522
+ }
523
+ }
524
+ },
525
+ "then": {
526
+ "properties": {
527
+ "production": {
528
+ "required": [
529
+ "setAsDefaultBranch",
530
+ "expectedCurrentDefaultBranch"
531
+ ],
532
+ "properties": {
533
+ "setAsDefaultBranch": {
534
+ "const": true
535
+ }
536
+ }
537
+ }
538
+ }
539
+ }
540
+ },
541
+ {
542
+ "if": {
543
+ "required": [
544
+ "production"
545
+ ],
546
+ "properties": {
547
+ "production": {
548
+ "required": [
549
+ "setAsDefaultBranch"
550
+ ],
551
+ "properties": {
552
+ "setAsDefaultBranch": {
553
+ "const": true
554
+ }
555
+ }
556
+ }
557
+ }
558
+ },
559
+ "then": {
560
+ "properties": {
561
+ "production": {
562
+ "required": [
563
+ "branchStrategy"
564
+ ],
565
+ "properties": {
566
+ "branchStrategy": {
567
+ "const": "initialize-default-branch"
568
+ }
569
+ }
570
+ }
571
+ }
572
+ }
573
+ }
574
+ ]
575
+ }
576
+ },
577
+ "verificationGates": {
578
+ "type": "array",
579
+ "items": {
580
+ "$ref": "#/definitions/verificationGate"
581
+ }
582
+ },
583
+ "hooks": {
584
+ "type": "object",
585
+ "additionalProperties": false,
586
+ "properties": {
587
+ "docs": {
588
+ "$ref": "#/definitions/hook"
589
+ },
590
+ "build": {
591
+ "$ref": "#/definitions/hook"
592
+ },
593
+ "test": {
594
+ "$ref": "#/definitions/hook"
595
+ },
596
+ "typecheck": {
597
+ "$ref": "#/definitions/hook"
598
+ },
599
+ "lint": {
600
+ "$ref": "#/definitions/hook"
601
+ }
602
+ }
603
+ },
604
+ "policy": {
605
+ "type": "object",
606
+ "additionalProperties": false,
607
+ "properties": {
608
+ "forbiddenPaths": {
609
+ "type": "array",
610
+ "items": {
611
+ "type": "string"
612
+ }
613
+ },
614
+ "forbiddenContentPatterns": {
615
+ "type": "array",
616
+ "items": {
617
+ "type": "string"
618
+ }
619
+ }
620
+ }
621
+ }
622
+ },
623
+ "definitions": {
624
+ "hook": {
625
+ "type": "object",
626
+ "required": [
627
+ "command"
628
+ ],
629
+ "additionalProperties": false,
630
+ "properties": {
631
+ "command": {
632
+ "type": "array",
633
+ "minItems": 1,
634
+ "items": {
635
+ "type": "string"
636
+ }
637
+ },
638
+ "cwd": {
639
+ "type": "string",
640
+ "pattern": "^(?:\\.$|(?!\\/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(?:\\/|$))(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/\\/$)(?!.*\\/$).*)$"
641
+ },
642
+ "timeoutMs": {
643
+ "type": "integer",
644
+ "minimum": 1000,
645
+ "maximum": 7200000
646
+ },
647
+ "envAllowlist": {
648
+ "type": "array",
649
+ "items": {
650
+ "type": "string",
651
+ "pattern": "^[A-Z_][A-Z0-9_]*$"
652
+ },
653
+ "uniqueItems": true
654
+ },
655
+ "cacheable": {
656
+ "type": "boolean",
657
+ "description": "Opt this hook into the incremental result cache: when its cacheInputs fingerprint is unchanged and the last run succeeded, prepare replays the cached outcome instead of re-executing. Absence means the hook always runs in full. cacheable=true requires a non-empty cacheInputs (enforced at runtime)."
658
+ },
659
+ "cacheInputs": {
660
+ "type": "array",
661
+ "minItems": 1,
662
+ "items": {
663
+ "type": "string",
664
+ "minLength": 1
665
+ },
666
+ "uniqueItems": true,
667
+ "description": "Root-relative globs declaring the hook's full input set (source, scripts, config, lockfiles). The cache key fingerprints the content of every matched file; a glob that matches nothing fails closed. Must cover ALL inputs or the cache can return a false hit."
668
+ }
669
+ }
670
+ },
671
+ "releaseDocuments": {
672
+ "type": "object",
673
+ "description": "Optional configuration-driven multilingual release-document refresh for one release unit. Absence preserves legacy behaviour. Lexical layer only; runtime path, locale-membership and collision checks apply additionally.",
674
+ "required": [
675
+ "notesSource",
676
+ "locales",
677
+ "changelogs",
678
+ "readmes"
679
+ ],
680
+ "additionalProperties": false,
681
+ "properties": {
682
+ "notesSource": {
683
+ "type": "string",
684
+ "minLength": 1,
685
+ "pattern": "^(?!/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(/|$))(?!\\.$)(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/$)(?!.*\\{(?!version\\}))(?!.*(?<!\\{version)\\}).+\\.(?:yaml|yml|json)$"
686
+ },
687
+ "locales": {
688
+ "type": "array",
689
+ "minItems": 1,
690
+ "uniqueItems": true,
691
+ "items": {
692
+ "type": "string",
693
+ "pattern": "^[a-zA-Z]{2,3}(?:-[A-Za-z0-9]{2,8})*$"
694
+ }
695
+ },
696
+ "changelogs": {
697
+ "type": "array",
698
+ "minItems": 1,
699
+ "items": {
700
+ "$ref": "#/definitions/releaseDocumentsChangelog"
701
+ }
702
+ },
703
+ "readmes": {
704
+ "type": "array",
705
+ "minItems": 1,
706
+ "items": {
707
+ "$ref": "#/definitions/releaseDocumentsReadme"
708
+ }
709
+ }
710
+ }
711
+ },
712
+ "releaseDocumentsChangelog": {
713
+ "type": "object",
714
+ "required": [
715
+ "path",
716
+ "locale"
717
+ ],
718
+ "additionalProperties": false,
719
+ "properties": {
720
+ "path": {
721
+ "type": "string",
722
+ "minLength": 1,
723
+ "pattern": "^(?!/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(/|$))(?!\\.$)(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/$).*$"
724
+ },
725
+ "locale": {
726
+ "type": "string",
727
+ "pattern": "^[a-zA-Z]{2,3}(?:-[A-Za-z0-9]{2,8})*$"
728
+ }
729
+ }
730
+ },
731
+ "releaseDocumentsReadme": {
732
+ "type": "object",
733
+ "required": [
734
+ "path",
735
+ "locale",
736
+ "regions"
737
+ ],
738
+ "additionalProperties": false,
739
+ "properties": {
740
+ "path": {
741
+ "type": "string",
742
+ "minLength": 1,
743
+ "pattern": "^(?!/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(/|$))(?!\\.$)(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/$).*$"
744
+ },
745
+ "locale": {
746
+ "type": "string",
747
+ "pattern": "^[a-zA-Z]{2,3}(?:-[A-Za-z0-9]{2,8})*$"
748
+ },
749
+ "regions": {
750
+ "type": "array",
751
+ "minItems": 1,
752
+ "uniqueItems": true,
753
+ "items": {
754
+ "type": "string",
755
+ "pattern": "^[a-z0-9][a-z0-9._-]*$"
756
+ }
757
+ },
758
+ "versionMarkers": {
759
+ "type": "array",
760
+ "minItems": 1,
761
+ "uniqueItems": true,
762
+ "items": {
763
+ "$ref": "#/definitions/releaseDocumentsVersionMarker"
764
+ }
765
+ }
766
+ }
767
+ },
768
+ "releaseDocumentsVersionMarker": {
769
+ "type": "object",
770
+ "required": [
771
+ "id",
772
+ "pattern"
773
+ ],
774
+ "additionalProperties": false,
775
+ "properties": {
776
+ "id": {
777
+ "type": "string",
778
+ "pattern": "^[a-z0-9][a-z0-9._-]*$"
779
+ },
780
+ "pattern": {
781
+ "type": "string",
782
+ "minLength": 1
783
+ }
784
+ }
785
+ },
786
+ "verificationGate": {
787
+ "type": "object",
788
+ "required": [
789
+ "id",
790
+ "phase",
791
+ "scope",
792
+ "command",
793
+ "cwd",
794
+ "timeoutMs",
795
+ "envAllowlist"
796
+ ],
797
+ "additionalProperties": false,
798
+ "properties": {
799
+ "id": {
800
+ "type": "string",
801
+ "pattern": "^[a-z0-9][a-z0-9._-]*$"
802
+ },
803
+ "phase": {
804
+ "type": "string",
805
+ "enum": [
806
+ "snapshot-verify",
807
+ "consumer-verify"
808
+ ]
809
+ },
810
+ "scope": {
811
+ "type": "object",
812
+ "required": [
813
+ "unit"
814
+ ],
815
+ "additionalProperties": false,
816
+ "properties": {
817
+ "unit": {
818
+ "type": "string",
819
+ "pattern": "^(?!\\.{1,2}$)[A-Za-z0-9][A-Za-z0-9._-]*$"
820
+ },
821
+ "distribution": {
822
+ "type": "string",
823
+ "enum": [
824
+ "npm",
825
+ "claude-plugin",
826
+ "codex-plugin",
827
+ "kimi-plugin"
828
+ ]
829
+ }
830
+ }
831
+ },
832
+ "command": {
833
+ "type": "array",
834
+ "minItems": 1,
835
+ "items": {
836
+ "type": "string"
837
+ }
838
+ },
839
+ "cwd": {
840
+ "type": "string",
841
+ "pattern": "^(?:\\.$|(?!\\/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(?:\\/|$))(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/\\/$)(?!.*\\/$).*)$"
842
+ },
843
+ "timeoutMs": {
844
+ "type": "integer",
845
+ "minimum": 1000,
846
+ "maximum": 7200000
847
+ },
848
+ "envAllowlist": {
849
+ "type": "array",
850
+ "items": {
851
+ "type": "string",
852
+ "pattern": "^[A-Z_][A-Z0-9_]*$"
853
+ },
854
+ "uniqueItems": true
855
+ },
856
+ "expectedJson": {
857
+ "type": "object"
858
+ }
859
+ },
860
+ "allOf": [
861
+ {
862
+ "if": {
863
+ "properties": {
864
+ "phase": {
865
+ "const": "consumer-verify"
866
+ }
867
+ },
868
+ "required": [
869
+ "phase"
870
+ ]
871
+ },
872
+ "then": {
873
+ "properties": {
874
+ "scope": {
875
+ "required": [
876
+ "unit",
877
+ "distribution"
878
+ ]
879
+ }
880
+ }
881
+ }
882
+ },
883
+ {
884
+ "if": {
885
+ "properties": {
886
+ "phase": {
887
+ "const": "snapshot-verify"
888
+ }
889
+ },
890
+ "required": [
891
+ "phase"
892
+ ]
893
+ },
894
+ "then": {
895
+ "properties": {
896
+ "scope": {
897
+ "not": {
898
+ "required": [
899
+ "distribution"
900
+ ]
901
+ }
902
+ }
903
+ }
904
+ }
905
+ }
906
+ ]
907
+ }
908
+ }
909
+ }