release-skill 0.1.3 → 0.1.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.
Files changed (97) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +2 -2
  3. package/.codex-plugin/plugin.json +3 -3
  4. package/CHANGELOG.md +56 -0
  5. package/INSTALL.md +69 -32
  6. package/INSTALL.zh-CN.md +64 -26
  7. package/README.md +111 -37
  8. package/README.zh-CN.md +95 -28
  9. package/adapters/claude/.claude-plugin/marketplace.json +1 -1
  10. package/adapters/claude/.claude-plugin/plugin.json +1 -1
  11. package/adapters/claude/bin/release-skill.bundle.mjs +79371 -0
  12. package/adapters/claude/bin/release-skill.mjs +34 -0
  13. package/adapters/claude/native/safe-write/binding.gyp +40 -0
  14. package/adapters/claude/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
  15. package/adapters/claude/native/safe-write/prebuilds.json +24 -0
  16. package/adapters/claude/native/safe-write/src/safe_write.cc +2032 -0
  17. package/adapters/claude/schemas/.render-manifest.json +37 -0
  18. package/adapters/claude/schemas/approval-record.schema.json +115 -0
  19. package/adapters/claude/schemas/artifact-lock.schema.json +111 -0
  20. package/adapters/claude/schemas/artifact-plan.schema.json +52 -0
  21. package/adapters/claude/schemas/artifact-policy.schema.json +76 -0
  22. package/adapters/claude/schemas/evidence-event.schema.json +89 -0
  23. package/adapters/claude/schemas/release-plan.schema.json +860 -0
  24. package/adapters/claude/schemas/release-project.schema.json +759 -0
  25. package/adapters/claude/schemas/release-run.schema.json +342 -0
  26. package/adapters/claude/skills/release-assess/SKILL.md +5 -6
  27. package/adapters/claude/skills/release-help/SKILL.md +11 -18
  28. package/adapters/claude/skills/release-prepare/SKILL.md +6 -6
  29. package/adapters/claude/skills/release-publish/SKILL.md +1 -4
  30. package/adapters/claude/skills/release-reconcile/SKILL.md +5 -5
  31. package/adapters/claude/skills/release-setup/SKILL.md +64 -80
  32. package/adapters/claude/skills/release-verify/SKILL.md +4 -7
  33. package/adapters/codex/.codex-plugin/plugin.json +2 -2
  34. package/adapters/codex/bin/release-skill.bundle.mjs +79371 -0
  35. package/adapters/codex/bin/release-skill.mjs +34 -0
  36. package/adapters/codex/native/safe-write/binding.gyp +40 -0
  37. package/adapters/codex/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
  38. package/adapters/codex/native/safe-write/prebuilds.json +24 -0
  39. package/adapters/codex/native/safe-write/src/safe_write.cc +2032 -0
  40. package/adapters/codex/schemas/.render-manifest.json +37 -0
  41. package/adapters/codex/schemas/approval-record.schema.json +115 -0
  42. package/adapters/codex/schemas/artifact-lock.schema.json +111 -0
  43. package/adapters/codex/schemas/artifact-plan.schema.json +52 -0
  44. package/adapters/codex/schemas/artifact-policy.schema.json +76 -0
  45. package/adapters/codex/schemas/evidence-event.schema.json +89 -0
  46. package/adapters/codex/schemas/release-plan.schema.json +860 -0
  47. package/adapters/codex/schemas/release-project.schema.json +759 -0
  48. package/adapters/codex/schemas/release-run.schema.json +342 -0
  49. package/adapters/codex/skills/release-assess/SKILL.md +12 -6
  50. package/adapters/codex/skills/release-help/SKILL.md +18 -18
  51. package/adapters/codex/skills/release-prepare/SKILL.md +13 -6
  52. package/adapters/codex/skills/release-publish/SKILL.md +8 -4
  53. package/adapters/codex/skills/release-reconcile/SKILL.md +12 -5
  54. package/adapters/codex/skills/release-setup/SKILL.md +71 -80
  55. package/adapters/codex/skills/release-verify/SKILL.md +11 -7
  56. package/bin/release-skill-cli.mjs +807 -0
  57. package/bin/release-skill.bundle.mjs +79371 -0
  58. package/bin/release-skill.mjs +23 -788
  59. package/package.json +6 -2
  60. package/references/02-project-config.md +2 -2
  61. package/schemas/release-plan.schema.json +7 -1
  62. package/schemas/release-project.schema.json +31 -0
  63. package/scripts/build-bundle.mjs +133 -0
  64. package/skills/release-assess/SKILL.md +5 -6
  65. package/skills/release-help/SKILL.md +11 -18
  66. package/skills/release-prepare/SKILL.md +6 -6
  67. package/skills/release-publish/SKILL.md +1 -4
  68. package/skills/release-reconcile/SKILL.md +5 -5
  69. package/skills/release-setup/SKILL.md +64 -80
  70. package/skills/release-verify/SKILL.md +4 -7
  71. package/skills-src/release-assess/SKILL.md +5 -6
  72. package/skills-src/release-help/SKILL.md +11 -18
  73. package/skills-src/release-prepare/SKILL.md +6 -6
  74. package/skills-src/release-publish/SKILL.md +1 -4
  75. package/skills-src/release-reconcile/SKILL.md +5 -5
  76. package/skills-src/release-setup/SKILL.md +64 -80
  77. package/skills-src/release-verify/SKILL.md +4 -7
  78. package/src/adapters/npm.mjs +5 -13
  79. package/src/adapters/plugin-marketplace.mjs +137 -34
  80. package/src/artifacts/policy.mjs +4 -7
  81. package/src/artifacts/safe-fs-backend-internal.mjs +69 -21
  82. package/src/commands/prepare.mjs +30 -1
  83. package/src/commands/publish.mjs +1 -0
  84. package/src/commands/reconcile.mjs +4 -1
  85. package/src/commands/setup.mjs +667 -28
  86. package/src/commands/verify.mjs +4 -1
  87. package/src/core/approval.mjs +4 -6
  88. package/src/core/config.mjs +8 -8
  89. package/src/core/pkg-root.mjs +22 -0
  90. package/src/core/plan.mjs +68 -5
  91. package/src/core/run.mjs +4 -4
  92. package/src/core/trusted-resource.mjs +96 -0
  93. package/src/docs/version-gate.mjs +164 -0
  94. package/src/producers/build-adapters.mjs +512 -55
  95. package/src/snapshot/frozen.mjs +133 -3
  96. package/src/snapshot/public-map.mjs +7 -4
  97. package/src/snapshot/scan.mjs +2 -1
@@ -0,0 +1,759 @@
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
+ ]
143
+ },
144
+ "package": {
145
+ "type": "string",
146
+ "minLength": 1,
147
+ "maxLength": 214,
148
+ "pattern": "^(?:@[a-z0-9][a-z0-9._-]*/[a-z0-9][a-z0-9._-]*|[a-z0-9][a-z0-9._-]*)$"
149
+ },
150
+ "access": {
151
+ "type": "string",
152
+ "enum": [
153
+ "public",
154
+ "restricted"
155
+ ]
156
+ },
157
+ "provenance": {
158
+ "type": "boolean"
159
+ },
160
+ "tag": {
161
+ "type": "string",
162
+ "minLength": 1
163
+ },
164
+ "registry": {
165
+ "type": "string",
166
+ "minLength": 1,
167
+ "pattern": "^https://[^\\s]+$",
168
+ "description": "Normalized HTTPS URL of the npm registry"
169
+ },
170
+ "publisher": {
171
+ "type": "string",
172
+ "minLength": 1,
173
+ "pattern": "^[a-z0-9][a-z0-9._-]*$",
174
+ "description": "Expected npm whoami username for this registry"
175
+ },
176
+ "plugin": {
177
+ "type": "string",
178
+ "minLength": 1,
179
+ "pattern": "^[a-z0-9][a-z0-9._-]*$"
180
+ },
181
+ "marketplace": {
182
+ "type": "string",
183
+ "minLength": 1,
184
+ "pattern": "^[a-z0-9][a-z0-9._-]*$"
185
+ },
186
+ "entrySkill": {
187
+ "type": "string",
188
+ "minLength": 1,
189
+ "pattern": "^[a-z0-9][a-z0-9-]*$"
190
+ },
191
+ "smokeBin": {
192
+ "type": "string",
193
+ "minLength": 1
194
+ },
195
+ "smokeArgs": {
196
+ "type": "array",
197
+ "items": {
198
+ "type": "string"
199
+ }
200
+ },
201
+ "smokeExpectedJson": {
202
+ "type": "object"
203
+ },
204
+ "timeoutMs": {
205
+ "type": "integer",
206
+ "minimum": 30000,
207
+ "maximum": 900000,
208
+ "description": "Timeout in milliseconds for plugin marketplace install commands. Only valid for claude-plugin and codex-plugin distributions."
209
+ }
210
+ },
211
+ "allOf": [
212
+ {
213
+ "if": {
214
+ "properties": {
215
+ "type": {
216
+ "const": "npm"
217
+ }
218
+ }
219
+ },
220
+ "then": {
221
+ "required": [
222
+ "package",
223
+ "registry",
224
+ "publisher"
225
+ ]
226
+ }
227
+ },
228
+ {
229
+ "if": {
230
+ "required": [
231
+ "timeoutMs"
232
+ ]
233
+ },
234
+ "then": {
235
+ "properties": {
236
+ "type": {
237
+ "enum": [
238
+ "claude-plugin",
239
+ "codex-plugin"
240
+ ]
241
+ }
242
+ }
243
+ }
244
+ },
245
+ {
246
+ "if": {
247
+ "properties": {
248
+ "type": {
249
+ "enum": [
250
+ "claude-plugin",
251
+ "codex-plugin"
252
+ ]
253
+ }
254
+ }
255
+ },
256
+ "then": {
257
+ "required": [
258
+ "plugin",
259
+ "marketplace",
260
+ "entrySkill"
261
+ ]
262
+ }
263
+ },
264
+ {
265
+ "if": {
266
+ "required": [
267
+ "smokeExpectedJson"
268
+ ],
269
+ "properties": {
270
+ "smokeBin": {
271
+ "minLength": 1
272
+ }
273
+ }
274
+ },
275
+ "then": {
276
+ "required": [
277
+ "smokeBin"
278
+ ]
279
+ }
280
+ },
281
+ {
282
+ "if": {
283
+ "required": [
284
+ "smokeArgs"
285
+ ],
286
+ "properties": {
287
+ "smokeBin": {
288
+ "minLength": 1
289
+ }
290
+ }
291
+ },
292
+ "then": {
293
+ "required": [
294
+ "smokeBin"
295
+ ]
296
+ }
297
+ }
298
+ ]
299
+ }
300
+ },
301
+ "publicFiles": {
302
+ "type": "array",
303
+ "minItems": 1,
304
+ "items": {
305
+ "type": "object",
306
+ "required": [
307
+ "from",
308
+ "to",
309
+ "mode"
310
+ ],
311
+ "additionalProperties": false,
312
+ "properties": {
313
+ "sourceScope": {
314
+ "type": "string",
315
+ "enum": [
316
+ "unit",
317
+ "workspace"
318
+ ],
319
+ "default": "unit"
320
+ },
321
+ "from": {
322
+ "type": "string",
323
+ "minLength": 1,
324
+ "pattern": "^(?!/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(/|$))(?!\\.$)(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/$).*$"
325
+ },
326
+ "to": {
327
+ "type": "string",
328
+ "minLength": 1,
329
+ "pattern": "^(?!/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(/|$))(?!\\.$)(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/$).*$"
330
+ },
331
+ "mode": {
332
+ "type": "string",
333
+ "enum": [
334
+ "preserve"
335
+ ]
336
+ }
337
+ }
338
+ }
339
+ },
340
+ "requiredPublicFiles": {
341
+ "type": "array",
342
+ "uniqueItems": true,
343
+ "items": {
344
+ "type": "string",
345
+ "minLength": 1,
346
+ "pattern": "^(?!/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(/|$))(?!\\.$)(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/$).*$"
347
+ }
348
+ },
349
+ "previousPublicBaseline": {
350
+ "type": "object",
351
+ "required": [
352
+ "mode"
353
+ ],
354
+ "additionalProperties": false,
355
+ "properties": {
356
+ "mode": {
357
+ "type": "string",
358
+ "enum": [
359
+ "none",
360
+ "bound"
361
+ ]
362
+ },
363
+ "githubHost": {
364
+ "type": "string",
365
+ "pattern": "^[a-zA-Z0-9.-]+$"
366
+ },
367
+ "repo": {
368
+ "type": "string",
369
+ "pattern": "^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$"
370
+ },
371
+ "ref": {
372
+ "type": "string",
373
+ "minLength": 1
374
+ },
375
+ "commit": {
376
+ "type": "string",
377
+ "pattern": "^[a-f0-9]{40,64}$"
378
+ },
379
+ "tree": {
380
+ "type": "string",
381
+ "pattern": "^[a-f0-9]{40,64}$"
382
+ },
383
+ "manifestDigest": {
384
+ "type": "string",
385
+ "pattern": "^[a-f0-9]{64}$"
386
+ }
387
+ },
388
+ "if": {
389
+ "properties": {
390
+ "mode": {
391
+ "const": "bound"
392
+ }
393
+ }
394
+ },
395
+ "then": {
396
+ "required": [
397
+ "repo",
398
+ "ref",
399
+ "commit"
400
+ ]
401
+ },
402
+ "else": {
403
+ "allOf": [
404
+ {
405
+ "not": {
406
+ "required": [
407
+ "repo"
408
+ ]
409
+ }
410
+ },
411
+ {
412
+ "not": {
413
+ "required": [
414
+ "githubHost"
415
+ ]
416
+ }
417
+ },
418
+ {
419
+ "not": {
420
+ "required": [
421
+ "ref"
422
+ ]
423
+ }
424
+ },
425
+ {
426
+ "not": {
427
+ "required": [
428
+ "commit"
429
+ ]
430
+ }
431
+ },
432
+ {
433
+ "not": {
434
+ "required": [
435
+ "tree"
436
+ ]
437
+ }
438
+ },
439
+ {
440
+ "not": {
441
+ "required": [
442
+ "manifestDigest"
443
+ ]
444
+ }
445
+ }
446
+ ]
447
+ }
448
+ }
449
+ },
450
+ "allOf": [
451
+ {
452
+ "if": {
453
+ "required": [
454
+ "production"
455
+ ],
456
+ "properties": {
457
+ "production": {
458
+ "required": [
459
+ "branchStrategy"
460
+ ],
461
+ "properties": {
462
+ "branchStrategy": {
463
+ "enum": [
464
+ "advance-existing-branch",
465
+ "initialize-default-branch"
466
+ ]
467
+ }
468
+ }
469
+ }
470
+ }
471
+ },
472
+ "then": {
473
+ "properties": {
474
+ "previousPublicBaseline": {
475
+ "properties": {
476
+ "mode": {
477
+ "const": "bound"
478
+ }
479
+ },
480
+ "required": [
481
+ "mode"
482
+ ]
483
+ }
484
+ }
485
+ }
486
+ },
487
+ {
488
+ "if": {
489
+ "required": [
490
+ "production"
491
+ ],
492
+ "properties": {
493
+ "production": {
494
+ "required": [
495
+ "branchStrategy"
496
+ ],
497
+ "properties": {
498
+ "branchStrategy": {
499
+ "const": "initialize-default-branch"
500
+ }
501
+ }
502
+ }
503
+ }
504
+ },
505
+ "then": {
506
+ "properties": {
507
+ "production": {
508
+ "required": [
509
+ "setAsDefaultBranch",
510
+ "expectedCurrentDefaultBranch"
511
+ ],
512
+ "properties": {
513
+ "setAsDefaultBranch": {
514
+ "const": true
515
+ }
516
+ }
517
+ }
518
+ }
519
+ }
520
+ },
521
+ {
522
+ "if": {
523
+ "required": [
524
+ "production"
525
+ ],
526
+ "properties": {
527
+ "production": {
528
+ "required": [
529
+ "setAsDefaultBranch"
530
+ ],
531
+ "properties": {
532
+ "setAsDefaultBranch": {
533
+ "const": true
534
+ }
535
+ }
536
+ }
537
+ }
538
+ },
539
+ "then": {
540
+ "properties": {
541
+ "production": {
542
+ "required": [
543
+ "branchStrategy"
544
+ ],
545
+ "properties": {
546
+ "branchStrategy": {
547
+ "const": "initialize-default-branch"
548
+ }
549
+ }
550
+ }
551
+ }
552
+ }
553
+ }
554
+ ]
555
+ }
556
+ },
557
+ "verificationGates": {
558
+ "type": "array",
559
+ "items": {
560
+ "$ref": "#/definitions/verificationGate"
561
+ }
562
+ },
563
+ "hooks": {
564
+ "type": "object",
565
+ "additionalProperties": false,
566
+ "properties": {
567
+ "docs": {
568
+ "$ref": "#/definitions/hook"
569
+ },
570
+ "build": {
571
+ "$ref": "#/definitions/hook"
572
+ },
573
+ "test": {
574
+ "$ref": "#/definitions/hook"
575
+ },
576
+ "typecheck": {
577
+ "$ref": "#/definitions/hook"
578
+ },
579
+ "lint": {
580
+ "$ref": "#/definitions/hook"
581
+ }
582
+ }
583
+ },
584
+ "policy": {
585
+ "type": "object",
586
+ "additionalProperties": false,
587
+ "properties": {
588
+ "forbiddenPaths": {
589
+ "type": "array",
590
+ "items": {
591
+ "type": "string"
592
+ }
593
+ },
594
+ "forbiddenContentPatterns": {
595
+ "type": "array",
596
+ "items": {
597
+ "type": "string"
598
+ }
599
+ }
600
+ }
601
+ }
602
+ },
603
+ "definitions": {
604
+ "hook": {
605
+ "type": "object",
606
+ "required": [
607
+ "command"
608
+ ],
609
+ "additionalProperties": false,
610
+ "properties": {
611
+ "command": {
612
+ "type": "array",
613
+ "minItems": 1,
614
+ "items": {
615
+ "type": "string"
616
+ }
617
+ },
618
+ "cwd": {
619
+ "type": "string",
620
+ "pattern": "^(?:\\.$|(?!\\/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(?:\\/|$))(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/\\/$)(?!.*\\/$).*)$"
621
+ },
622
+ "timeoutMs": {
623
+ "type": "integer",
624
+ "minimum": 1000,
625
+ "maximum": 7200000
626
+ },
627
+ "envAllowlist": {
628
+ "type": "array",
629
+ "items": {
630
+ "type": "string",
631
+ "pattern": "^[A-Z_][A-Z0-9_]*$"
632
+ },
633
+ "uniqueItems": true
634
+ }
635
+ }
636
+ },
637
+ "verificationGate": {
638
+ "type": "object",
639
+ "required": [
640
+ "id",
641
+ "phase",
642
+ "scope",
643
+ "command",
644
+ "cwd",
645
+ "timeoutMs",
646
+ "envAllowlist"
647
+ ],
648
+ "additionalProperties": false,
649
+ "properties": {
650
+ "id": {
651
+ "type": "string",
652
+ "pattern": "^[a-z0-9][a-z0-9._-]*$"
653
+ },
654
+ "phase": {
655
+ "type": "string",
656
+ "enum": [
657
+ "snapshot-verify",
658
+ "consumer-verify"
659
+ ]
660
+ },
661
+ "scope": {
662
+ "type": "object",
663
+ "required": [
664
+ "unit"
665
+ ],
666
+ "additionalProperties": false,
667
+ "properties": {
668
+ "unit": {
669
+ "type": "string",
670
+ "pattern": "^(?!\\.{1,2}$)[A-Za-z0-9][A-Za-z0-9._-]*$"
671
+ },
672
+ "distribution": {
673
+ "type": "string",
674
+ "enum": [
675
+ "npm",
676
+ "claude-plugin",
677
+ "codex-plugin"
678
+ ]
679
+ }
680
+ }
681
+ },
682
+ "command": {
683
+ "type": "array",
684
+ "minItems": 1,
685
+ "items": {
686
+ "type": "string"
687
+ }
688
+ },
689
+ "cwd": {
690
+ "type": "string",
691
+ "pattern": "^(?:\\.$|(?!\\/)(?!\\.\\/)(?!.*\\\\)(?!.*:)(?!\\.\\.(?:\\/|$))(?!.*\\/\\.\\.\\/)(?!.*\\/\\.\\.$)(?!.*\\/\\.\\/)(?!.*\\/\\/)(?!.*\\0)(?!.*\\/\\.$)(?!.*\\/\\/$)(?!.*\\/$).*)$"
692
+ },
693
+ "timeoutMs": {
694
+ "type": "integer",
695
+ "minimum": 1000,
696
+ "maximum": 7200000
697
+ },
698
+ "envAllowlist": {
699
+ "type": "array",
700
+ "items": {
701
+ "type": "string",
702
+ "pattern": "^[A-Z_][A-Z0-9_]*$"
703
+ },
704
+ "uniqueItems": true
705
+ },
706
+ "expectedJson": {
707
+ "type": "object"
708
+ }
709
+ },
710
+ "allOf": [
711
+ {
712
+ "if": {
713
+ "properties": {
714
+ "phase": {
715
+ "const": "consumer-verify"
716
+ }
717
+ },
718
+ "required": [
719
+ "phase"
720
+ ]
721
+ },
722
+ "then": {
723
+ "properties": {
724
+ "scope": {
725
+ "required": [
726
+ "unit",
727
+ "distribution"
728
+ ]
729
+ }
730
+ }
731
+ }
732
+ },
733
+ {
734
+ "if": {
735
+ "properties": {
736
+ "phase": {
737
+ "const": "snapshot-verify"
738
+ }
739
+ },
740
+ "required": [
741
+ "phase"
742
+ ]
743
+ },
744
+ "then": {
745
+ "properties": {
746
+ "scope": {
747
+ "not": {
748
+ "required": [
749
+ "distribution"
750
+ ]
751
+ }
752
+ }
753
+ }
754
+ }
755
+ }
756
+ ]
757
+ }
758
+ }
759
+ }