@osovv/vv-opencode 1.3.4 → 1.3.6-rc.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.
- package/CHANGELOG.md +37 -0
- package/README.md +378 -384
- package/dist/commands/analytics.js +2 -0
- package/dist/commands/analytics.js.map +1 -1
- package/dist/commands/upgrade.d.ts +13 -6
- package/dist/commands/upgrade.js +31 -25
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/opencode.js +3 -2
- package/dist/lib/opencode.js.map +1 -1
- package/dist/lib/peak-hours.d.ts +53 -0
- package/dist/lib/peak-hours.js +389 -0
- package/dist/lib/peak-hours.js.map +1 -0
- package/dist/lib/plugin-toggle-config.d.ts +71 -1
- package/dist/lib/plugin-toggle-config.js +77 -3
- package/dist/lib/plugin-toggle-config.js.map +1 -1
- package/dist/lib/vvoc-config.d.ts +84 -0
- package/dist/lib/vvoc-config.js +42 -1
- package/dist/lib/vvoc-config.js.map +1 -1
- package/dist/plugins/peak-hours/index.d.ts +31 -0
- package/dist/plugins/peak-hours/index.js +299 -0
- package/dist/plugins/peak-hours/index.js.map +1 -0
- package/dist/tui/analytics/indicator.js.map +1 -1
- package/dist/tui/peak-hours/banner.d.ts +26 -0
- package/dist/tui/peak-hours/banner.js +126 -0
- package/dist/tui/peak-hours/banner.js.map +1 -0
- package/dist/tui.js +13 -6
- package/dist/tui.js.map +1 -1
- package/package.json +7 -3
- package/schemas/vvoc/v3.json +326 -57
- package/templates/skills/vv-execute/SKILL.md +11 -11
- package/templates/skills/vv-plan/SKILL.md +9 -8
- package/templates/skills/vv-plan/references/plan-template.xml +4 -6
package/schemas/vvoc/v3.json
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://cdn.jsdelivr.net/npm/@osovv/vv-opencode@1.3.
|
|
3
|
+
"$id": "https://cdn.jsdelivr.net/npm/@osovv/vv-opencode@1.3.6-rc.0/schemas/vvoc/v3.json",
|
|
4
4
|
"title": "vvoc config",
|
|
5
5
|
"description": "Canonical vvoc configuration document.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
|
-
"required": [
|
|
8
|
+
"required": [
|
|
9
|
+
"$schema",
|
|
10
|
+
"version",
|
|
11
|
+
"roles",
|
|
12
|
+
"guardian",
|
|
13
|
+
"secretsRedaction",
|
|
14
|
+
"presets",
|
|
15
|
+
"plugins"
|
|
16
|
+
],
|
|
9
17
|
"properties": {
|
|
10
18
|
"$schema": {
|
|
11
19
|
"type": "string",
|
|
@@ -31,48 +39,101 @@
|
|
|
31
39
|
"orchestration": {
|
|
32
40
|
"type": "object",
|
|
33
41
|
"additionalProperties": false,
|
|
34
|
-
"required": [
|
|
42
|
+
"required": [
|
|
43
|
+
"profile"
|
|
44
|
+
],
|
|
35
45
|
"properties": {
|
|
36
46
|
"profile": {
|
|
37
47
|
"type": "string",
|
|
38
|
-
"enum": [
|
|
48
|
+
"enum": [
|
|
49
|
+
"single-session",
|
|
50
|
+
"balanced",
|
|
51
|
+
"orchestrated"
|
|
52
|
+
]
|
|
39
53
|
}
|
|
40
54
|
}
|
|
41
55
|
},
|
|
42
56
|
"guardian": {
|
|
43
57
|
"type": "object",
|
|
44
58
|
"additionalProperties": false,
|
|
45
|
-
"required": [
|
|
59
|
+
"required": [
|
|
60
|
+
"timeoutMs",
|
|
61
|
+
"approvalRiskThreshold",
|
|
62
|
+
"reviewToastDurationMs"
|
|
63
|
+
],
|
|
46
64
|
"properties": {
|
|
47
|
-
"model": {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
65
|
+
"model": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"minLength": 1
|
|
68
|
+
},
|
|
69
|
+
"timeoutMs": {
|
|
70
|
+
"type": "integer",
|
|
71
|
+
"minimum": 1
|
|
72
|
+
},
|
|
73
|
+
"approvalRiskThreshold": {
|
|
74
|
+
"type": "integer",
|
|
75
|
+
"minimum": 0,
|
|
76
|
+
"maximum": 100
|
|
77
|
+
},
|
|
78
|
+
"reviewToastDurationMs": {
|
|
79
|
+
"type": "integer",
|
|
80
|
+
"minimum": 1
|
|
81
|
+
}
|
|
51
82
|
}
|
|
52
83
|
},
|
|
53
84
|
"secretsRedaction": {
|
|
54
85
|
"type": "object",
|
|
55
86
|
"additionalProperties": false,
|
|
56
|
-
"required": [
|
|
87
|
+
"required": [
|
|
88
|
+
"secret",
|
|
89
|
+
"ttlMs",
|
|
90
|
+
"maxMappings",
|
|
91
|
+
"patterns",
|
|
92
|
+
"debug"
|
|
93
|
+
],
|
|
57
94
|
"properties": {
|
|
58
|
-
"secret": {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
95
|
+
"secret": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"minLength": 1
|
|
98
|
+
},
|
|
99
|
+
"ttlMs": {
|
|
100
|
+
"type": "integer",
|
|
101
|
+
"minimum": 0
|
|
102
|
+
},
|
|
103
|
+
"maxMappings": {
|
|
104
|
+
"type": "integer",
|
|
105
|
+
"minimum": 1
|
|
106
|
+
},
|
|
107
|
+
"debug": {
|
|
108
|
+
"type": "boolean"
|
|
109
|
+
},
|
|
62
110
|
"patterns": {
|
|
63
111
|
"type": "object",
|
|
64
112
|
"additionalProperties": false,
|
|
65
|
-
"required": [
|
|
113
|
+
"required": [
|
|
114
|
+
"keywords",
|
|
115
|
+
"regex",
|
|
116
|
+
"builtin",
|
|
117
|
+
"exclude"
|
|
118
|
+
],
|
|
66
119
|
"properties": {
|
|
67
120
|
"keywords": {
|
|
68
121
|
"type": "array",
|
|
69
122
|
"items": {
|
|
70
123
|
"type": "object",
|
|
71
124
|
"additionalProperties": false,
|
|
72
|
-
"required": [
|
|
125
|
+
"required": [
|
|
126
|
+
"value"
|
|
127
|
+
],
|
|
73
128
|
"properties": {
|
|
74
|
-
"value": {
|
|
75
|
-
|
|
129
|
+
"value": {
|
|
130
|
+
"type": "string",
|
|
131
|
+
"minLength": 1
|
|
132
|
+
},
|
|
133
|
+
"category": {
|
|
134
|
+
"type": "string",
|
|
135
|
+
"minLength": 1
|
|
136
|
+
}
|
|
76
137
|
}
|
|
77
138
|
}
|
|
78
139
|
},
|
|
@@ -81,20 +142,35 @@
|
|
|
81
142
|
"items": {
|
|
82
143
|
"type": "object",
|
|
83
144
|
"additionalProperties": false,
|
|
84
|
-
"required": [
|
|
145
|
+
"required": [
|
|
146
|
+
"pattern",
|
|
147
|
+
"category"
|
|
148
|
+
],
|
|
85
149
|
"properties": {
|
|
86
|
-
"pattern": {
|
|
87
|
-
|
|
150
|
+
"pattern": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"minLength": 1
|
|
153
|
+
},
|
|
154
|
+
"category": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"minLength": 1
|
|
157
|
+
}
|
|
88
158
|
}
|
|
89
159
|
}
|
|
90
160
|
},
|
|
91
161
|
"builtin": {
|
|
92
162
|
"type": "array",
|
|
93
|
-
"items": {
|
|
163
|
+
"items": {
|
|
164
|
+
"type": "string",
|
|
165
|
+
"minLength": 1
|
|
166
|
+
}
|
|
94
167
|
},
|
|
95
168
|
"exclude": {
|
|
96
169
|
"type": "array",
|
|
97
|
-
"items": {
|
|
170
|
+
"items": {
|
|
171
|
+
"type": "string",
|
|
172
|
+
"minLength": 1
|
|
173
|
+
}
|
|
98
174
|
}
|
|
99
175
|
}
|
|
100
176
|
}
|
|
@@ -102,13 +178,20 @@
|
|
|
102
178
|
},
|
|
103
179
|
"presets": {
|
|
104
180
|
"type": "object",
|
|
105
|
-
"propertyNames": {
|
|
181
|
+
"propertyNames": {
|
|
182
|
+
"minLength": 1
|
|
183
|
+
},
|
|
106
184
|
"additionalProperties": {
|
|
107
185
|
"type": "object",
|
|
108
186
|
"additionalProperties": false,
|
|
109
|
-
"required": [
|
|
187
|
+
"required": [
|
|
188
|
+
"agents"
|
|
189
|
+
],
|
|
110
190
|
"properties": {
|
|
111
|
-
"description": {
|
|
191
|
+
"description": {
|
|
192
|
+
"type": "string",
|
|
193
|
+
"minLength": 1
|
|
194
|
+
},
|
|
112
195
|
"agents": {
|
|
113
196
|
"type": "object",
|
|
114
197
|
"propertyNames": {
|
|
@@ -116,16 +199,25 @@
|
|
|
116
199
|
"pattern": "^[a-z][a-z0-9-]*$"
|
|
117
200
|
},
|
|
118
201
|
"minProperties": 1,
|
|
119
|
-
"additionalProperties": {
|
|
202
|
+
"additionalProperties": {
|
|
203
|
+
"type": "string",
|
|
204
|
+
"minLength": 1
|
|
205
|
+
}
|
|
120
206
|
},
|
|
121
207
|
"orchestration": {
|
|
122
208
|
"type": "object",
|
|
123
209
|
"additionalProperties": false,
|
|
124
|
-
"required": [
|
|
210
|
+
"required": [
|
|
211
|
+
"profile"
|
|
212
|
+
],
|
|
125
213
|
"properties": {
|
|
126
214
|
"profile": {
|
|
127
215
|
"type": "string",
|
|
128
|
-
"enum": [
|
|
216
|
+
"enum": [
|
|
217
|
+
"single-session",
|
|
218
|
+
"balanced",
|
|
219
|
+
"orchestrated"
|
|
220
|
+
]
|
|
129
221
|
}
|
|
130
222
|
}
|
|
131
223
|
}
|
|
@@ -134,29 +226,47 @@
|
|
|
134
226
|
},
|
|
135
227
|
"plugins": {
|
|
136
228
|
"type": "object",
|
|
137
|
-
"propertyNames": {
|
|
229
|
+
"propertyNames": {
|
|
230
|
+
"minLength": 1
|
|
231
|
+
},
|
|
138
232
|
"additionalProperties": {
|
|
139
233
|
"anyOf": [
|
|
140
|
-
{
|
|
234
|
+
{
|
|
235
|
+
"type": "boolean"
|
|
236
|
+
},
|
|
141
237
|
{
|
|
142
238
|
"type": "object",
|
|
143
239
|
"additionalProperties": false,
|
|
144
240
|
"properties": {
|
|
145
|
-
"enabled": {
|
|
241
|
+
"enabled": {
|
|
242
|
+
"type": "boolean"
|
|
243
|
+
},
|
|
146
244
|
"routing": {
|
|
147
245
|
"type": "object",
|
|
148
246
|
"additionalProperties": false,
|
|
149
247
|
"properties": {
|
|
150
248
|
"default": {
|
|
151
249
|
"type": "string",
|
|
152
|
-
"enum": [
|
|
250
|
+
"enum": [
|
|
251
|
+
"hashline",
|
|
252
|
+
"replace",
|
|
253
|
+
"str_replace_editor",
|
|
254
|
+
"passthrough"
|
|
255
|
+
]
|
|
153
256
|
},
|
|
154
257
|
"rules": {
|
|
155
258
|
"type": "object",
|
|
156
|
-
"propertyNames": {
|
|
259
|
+
"propertyNames": {
|
|
260
|
+
"minLength": 1
|
|
261
|
+
},
|
|
157
262
|
"additionalProperties": {
|
|
158
263
|
"type": "string",
|
|
159
|
-
"enum": [
|
|
264
|
+
"enum": [
|
|
265
|
+
"hashline",
|
|
266
|
+
"replace",
|
|
267
|
+
"str_replace_editor",
|
|
268
|
+
"passthrough"
|
|
269
|
+
]
|
|
160
270
|
}
|
|
161
271
|
}
|
|
162
272
|
}
|
|
@@ -167,17 +277,124 @@
|
|
|
167
277
|
"type": "object",
|
|
168
278
|
"additionalProperties": false,
|
|
169
279
|
"properties": {
|
|
170
|
-
"enabled": {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
"
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
"
|
|
178
|
-
|
|
179
|
-
|
|
280
|
+
"enabled": {
|
|
281
|
+
"type": "boolean"
|
|
282
|
+
},
|
|
283
|
+
"protectLastCalls": {
|
|
284
|
+
"type": "integer",
|
|
285
|
+
"minimum": 0
|
|
286
|
+
},
|
|
287
|
+
"protectRecentMessages": {
|
|
288
|
+
"type": "integer",
|
|
289
|
+
"minimum": 0
|
|
290
|
+
},
|
|
291
|
+
"savePrunedOutput": {
|
|
292
|
+
"type": "boolean"
|
|
293
|
+
},
|
|
294
|
+
"minSavingsChars": {
|
|
295
|
+
"type": "integer",
|
|
296
|
+
"minimum": 0
|
|
297
|
+
},
|
|
298
|
+
"outputMaxChars": {
|
|
299
|
+
"type": "integer",
|
|
300
|
+
"minimum": 0
|
|
301
|
+
},
|
|
302
|
+
"headChars": {
|
|
303
|
+
"type": "integer",
|
|
304
|
+
"minimum": 0
|
|
305
|
+
},
|
|
306
|
+
"tailChars": {
|
|
307
|
+
"type": "integer",
|
|
308
|
+
"minimum": 0
|
|
309
|
+
},
|
|
310
|
+
"readSlim": {
|
|
311
|
+
"type": "boolean"
|
|
312
|
+
},
|
|
313
|
+
"retainTools": {
|
|
314
|
+
"type": "array",
|
|
315
|
+
"items": {
|
|
316
|
+
"type": "string",
|
|
317
|
+
"minLength": 1
|
|
318
|
+
}
|
|
319
|
+
}
|
|
180
320
|
}
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"type": "object",
|
|
324
|
+
"description": "peak-hours plugin entry: enabled, mode, graceActiveSessions, and provider peak-window schedules.",
|
|
325
|
+
"properties": {
|
|
326
|
+
"enabled": {
|
|
327
|
+
"type": "boolean"
|
|
328
|
+
},
|
|
329
|
+
"mode": {
|
|
330
|
+
"type": "string",
|
|
331
|
+
"enum": [
|
|
332
|
+
"soft",
|
|
333
|
+
"hard"
|
|
334
|
+
]
|
|
335
|
+
},
|
|
336
|
+
"graceActiveSessions": {
|
|
337
|
+
"type": "boolean"
|
|
338
|
+
},
|
|
339
|
+
"schedules": {
|
|
340
|
+
"type": "object",
|
|
341
|
+
"propertyNames": {
|
|
342
|
+
"minLength": 1
|
|
343
|
+
},
|
|
344
|
+
"additionalProperties": {
|
|
345
|
+
"type": "object",
|
|
346
|
+
"properties": {
|
|
347
|
+
"mode": {
|
|
348
|
+
"type": "string",
|
|
349
|
+
"enum": [
|
|
350
|
+
"soft",
|
|
351
|
+
"hard"
|
|
352
|
+
]
|
|
353
|
+
},
|
|
354
|
+
"windows": {
|
|
355
|
+
"type": "array",
|
|
356
|
+
"minItems": 1,
|
|
357
|
+
"items": {
|
|
358
|
+
"type": "object",
|
|
359
|
+
"properties": {
|
|
360
|
+
"start": {
|
|
361
|
+
"type": "string",
|
|
362
|
+
"pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
|
|
363
|
+
},
|
|
364
|
+
"end": {
|
|
365
|
+
"type": "string",
|
|
366
|
+
"pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
|
|
367
|
+
},
|
|
368
|
+
"tz": {
|
|
369
|
+
"type": "string",
|
|
370
|
+
"minLength": 1
|
|
371
|
+
},
|
|
372
|
+
"days": {
|
|
373
|
+
"type": "array",
|
|
374
|
+
"minItems": 1,
|
|
375
|
+
"items": {
|
|
376
|
+
"type": "integer",
|
|
377
|
+
"minimum": 0,
|
|
378
|
+
"maximum": 6
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
"required": [
|
|
383
|
+
"start",
|
|
384
|
+
"end"
|
|
385
|
+
],
|
|
386
|
+
"additionalProperties": false
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
"required": [
|
|
391
|
+
"windows"
|
|
392
|
+
],
|
|
393
|
+
"additionalProperties": false
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
"additionalProperties": false
|
|
181
398
|
}
|
|
182
399
|
]
|
|
183
400
|
}
|
|
@@ -190,17 +407,43 @@
|
|
|
190
407
|
"type": "object",
|
|
191
408
|
"additionalProperties": false,
|
|
192
409
|
"properties": {
|
|
193
|
-
"provider": {
|
|
194
|
-
|
|
195
|
-
|
|
410
|
+
"provider": {
|
|
411
|
+
"type": "string",
|
|
412
|
+
"enum": [
|
|
413
|
+
"exa",
|
|
414
|
+
"brave",
|
|
415
|
+
"zai"
|
|
416
|
+
]
|
|
417
|
+
},
|
|
418
|
+
"region": {
|
|
419
|
+
"type": "string",
|
|
420
|
+
"enum": [
|
|
421
|
+
"international",
|
|
422
|
+
"china"
|
|
423
|
+
]
|
|
424
|
+
},
|
|
425
|
+
"apiKey": {
|
|
426
|
+
"type": "string",
|
|
427
|
+
"minLength": 1
|
|
428
|
+
}
|
|
196
429
|
},
|
|
197
430
|
"allOf": [
|
|
198
431
|
{
|
|
199
432
|
"if": {
|
|
200
|
-
"properties": {
|
|
201
|
-
|
|
433
|
+
"properties": {
|
|
434
|
+
"provider": {
|
|
435
|
+
"const": "zai"
|
|
436
|
+
}
|
|
437
|
+
},
|
|
438
|
+
"required": [
|
|
439
|
+
"provider"
|
|
440
|
+
]
|
|
202
441
|
},
|
|
203
|
-
"then": {
|
|
442
|
+
"then": {
|
|
443
|
+
"required": [
|
|
444
|
+
"region"
|
|
445
|
+
]
|
|
446
|
+
}
|
|
204
447
|
}
|
|
205
448
|
]
|
|
206
449
|
},
|
|
@@ -208,17 +451,43 @@
|
|
|
208
451
|
"type": "object",
|
|
209
452
|
"additionalProperties": false,
|
|
210
453
|
"properties": {
|
|
211
|
-
"provider": {
|
|
212
|
-
|
|
213
|
-
|
|
454
|
+
"provider": {
|
|
455
|
+
"type": "string",
|
|
456
|
+
"enum": [
|
|
457
|
+
"native",
|
|
458
|
+
"spider",
|
|
459
|
+
"zai"
|
|
460
|
+
]
|
|
461
|
+
},
|
|
462
|
+
"region": {
|
|
463
|
+
"type": "string",
|
|
464
|
+
"enum": [
|
|
465
|
+
"international",
|
|
466
|
+
"china"
|
|
467
|
+
]
|
|
468
|
+
},
|
|
469
|
+
"apiKey": {
|
|
470
|
+
"type": "string",
|
|
471
|
+
"minLength": 1
|
|
472
|
+
}
|
|
214
473
|
},
|
|
215
474
|
"allOf": [
|
|
216
475
|
{
|
|
217
476
|
"if": {
|
|
218
|
-
"properties": {
|
|
219
|
-
|
|
477
|
+
"properties": {
|
|
478
|
+
"provider": {
|
|
479
|
+
"const": "zai"
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
"required": [
|
|
483
|
+
"provider"
|
|
484
|
+
]
|
|
220
485
|
},
|
|
221
|
-
"then": {
|
|
486
|
+
"then": {
|
|
487
|
+
"required": [
|
|
488
|
+
"region"
|
|
489
|
+
]
|
|
490
|
+
}
|
|
222
491
|
}
|
|
223
492
|
]
|
|
224
493
|
}
|
|
@@ -45,27 +45,27 @@ Do not mutate files until the execution mode is explicit. In classic mode, deleg
|
|
|
45
45
|
<purpose>List all module names</purpose>
|
|
46
46
|
</helper>
|
|
47
47
|
<helper name="list-tasks">
|
|
48
|
-
<command>grep '<
|
|
48
|
+
<command>grep '<TASK-T-' PLAN_PATH</command>
|
|
49
49
|
<purpose>List all task IDs in document order</purpose>
|
|
50
50
|
</helper>
|
|
51
51
|
<helper name="extract-task">
|
|
52
|
-
<command>sed -n '/<
|
|
53
|
-
<purpose>Extract one full task by ID (replace T-NNN with actual ID
|
|
52
|
+
<command>sed -n '/<TASK-T-NNN>/,/<\/TASK-T-NNN>/p' PLAN_PATH</command>
|
|
53
|
+
<purpose>Extract one full task by ID (replace T-NNN in the TASK-T-NNN element name with the actual ID, e.g. TASK-T-001)</purpose>
|
|
54
54
|
</helper>
|
|
55
55
|
<helper name="extract-snippet">
|
|
56
|
-
<command>sed -n '/<
|
|
56
|
+
<command>sed -n '/<TASK-T-NNN>/,/<\/TASK-T-NNN>/p' PLAN_PATH | sed -n '/<snippet>/,/<\/snippet>/p'</command>
|
|
57
57
|
<purpose>Extract only the code snippet for a specific task</purpose>
|
|
58
58
|
</helper>
|
|
59
59
|
<helper name="extract-acceptance">
|
|
60
|
-
<command>sed -n '/<
|
|
60
|
+
<command>sed -n '/<TASK-T-NNN>/,/<\/TASK-T-NNN>/p' PLAN_PATH | sed -n '/<acceptance>/,/<\/acceptance>/p'</command>
|
|
61
61
|
<purpose>Extract all acceptance criteria for a specific task</purpose>
|
|
62
62
|
</helper>
|
|
63
63
|
<helper name="task-file">
|
|
64
|
-
<command>sed -n '/<
|
|
64
|
+
<command>sed -n '/<TASK-T-NNN>/,/<\/TASK-T-NNN>/p' PLAN_PATH | grep '<file>'</command>
|
|
65
65
|
<purpose>Get the target file for a specific task</purpose>
|
|
66
66
|
</helper>
|
|
67
67
|
<helper name="task-status">
|
|
68
|
-
<command>sed -n '/<
|
|
68
|
+
<command>sed -n '/<TASK-T-NNN>/,/<\/TASK-T-NNN>/p' PLAN_PATH | grep '<status>'</command>
|
|
69
69
|
<purpose>Get current status of a specific task</purpose>
|
|
70
70
|
</helper>
|
|
71
71
|
<helper name="dependency-graph">
|
|
@@ -73,11 +73,11 @@ Do not mutate files until the execution mode is explicit. In classic mode, deleg
|
|
|
73
73
|
<purpose>Show all task dependencies</purpose>
|
|
74
74
|
</helper>
|
|
75
75
|
<helper name="task-deps">
|
|
76
|
-
<command>sed -n '/<
|
|
76
|
+
<command>sed -n '/<TASK-T-NNN>/,/<\/TASK-T-NNN>/p' PLAN_PATH | grep '<task_id>'</command>
|
|
77
77
|
<purpose>List dependencies for a specific task</purpose>
|
|
78
78
|
</helper>
|
|
79
79
|
<helper name="count-tasks">
|
|
80
|
-
<command>grep -c '<
|
|
80
|
+
<command>grep -c '<TASK-T-' PLAN_PATH</command>
|
|
81
81
|
<purpose>Count total tasks in the plan</purpose>
|
|
82
82
|
</helper>
|
|
83
83
|
<helper name="all-files">
|
|
@@ -103,8 +103,8 @@ Do not mutate files until the execution mode is explicit. In classic mode, deleg
|
|
|
103
103
|
<check>Plan contains a non-empty <spec> path pointing to a readable active spec file at .vvoc/specs/<id>/spec.xml. Stop and report if the spec path is under archive/.</check>
|
|
104
104
|
<check>The linked spec's top-level <status> is approved</check>
|
|
105
105
|
<check>If the linked spec status is draft, applied, missing, or invalid, stop and report that vv-execute requires an approved active spec.</check>
|
|
106
|
-
<check>Plan contains <tasks> section with at least one <
|
|
107
|
-
<check>Each task has non-empty <
|
|
106
|
+
<check>Plan contains <tasks> section with at least one <TASK-T-NNN> element grouped under <WAVE-N> elements</check>
|
|
107
|
+
<check>Each task element name matches the TASK-T-NNN pattern and the task has non-empty <title> and <file>. There is no child id element — identity lives in the element name.</check>
|
|
108
108
|
<check>Each task has <snippet> (may be empty but must exist)</check>
|
|
109
109
|
<check>Each task has <acceptance> with at least one <criterion></check>
|
|
110
110
|
<action>If any check fails, stop and report the issue with line numbers. Do not proceed with broken plan.</action>
|
|
@@ -36,8 +36,9 @@ You are the vv-plan skill. Your job is to take an approved spec and write an imp
|
|
|
36
36
|
<rule>When first saving the plan, set the top-level status to <status>draft</status>. Only change it to approved after the user explicitly reads/reviews and approves the final plan. Never set the top-level status to applied yourself; applied is reserved for vv-execute after successful execution.</rule>
|
|
37
37
|
<rule>The plan contains two major sections: architecture (modules, contracts, dependencies) and tasks (implementation steps with code snippets).</rule>
|
|
38
38
|
<rule>Architecture section uses child tags: module, name, purpose, file (path, role), contract, depends_on (module).</rule>
|
|
39
|
-
<rule>Tasks
|
|
40
|
-
<rule>
|
|
39
|
+
<rule>Tasks are grouped into wave elements whose identity is the element name: <WAVE-1>, <WAVE-2>, … Each wave contains a <goal> and its tasks.</rule>
|
|
40
|
+
<rule>A task's identity is its element name in the TASK-T-NNN pattern: <TASK-T-001>…</TASK-T-001>. The identity repeats on both boundaries so long blocks stay addressable. Tasks use child tags: title, file, status, description, depends_on (task_id), snippet (CDATA), acceptance (criterion), verification (command). Do NOT add a child id element — the element name is the single authoritative identity. Task-level <status> values are separate from the top-level plan lifecycle status and may remain pending until execution updates them.</rule>
|
|
41
|
+
<rule>Every XML element is named for grep extraction. Use: `grep '<TASK-T-' plan.xml` to list tasks, `grep '<criterion>' plan.xml` for all criteria, `grep '<task_id>' plan.xml` for dependency graph.</rule>
|
|
41
42
|
<rule>Populate the <spec> element with the path to the spec.xml this plan implements.</rule>
|
|
42
43
|
<rule>If a design-context.xml was found and read as explanatory context, populate the <design-context> element with the path to design-context.xml so execution tools and reviewers can locate it.</rule>
|
|
43
44
|
<location>Save plan.xml as a sibling of spec.xml in the same spec package directory: .vvoc/specs/<id>/plan.xml</location>
|
|
@@ -61,10 +62,9 @@ You are the vv-plan skill. Your job is to take an approved spec and write an imp
|
|
|
61
62
|
</acceptance_criteria_format>
|
|
62
63
|
|
|
63
64
|
<example>
|
|
64
|
-
<rule>Here is a concrete example of one task
|
|
65
|
+
<rule>Here is a concrete example of one task. The task identity is the element name, repeated on both boundaries; every <snippet> uses CDATA, and every <criterion> is testable:</rule>
|
|
65
66
|
<sample-fragment>
|
|
66
|
-
<
|
|
67
|
-
<id>T-001</id>
|
|
67
|
+
<TASK-T-001>
|
|
68
68
|
<title>LRU Cache Store</title>
|
|
69
69
|
<file>src/lib/cache-store.ts</file>
|
|
70
70
|
<status>pending</status>
|
|
@@ -111,9 +111,9 @@ export type CacheStoreOptions = {
|
|
|
111
111
|
<verification>
|
|
112
112
|
<command>bun test src/lib/cache-store.test.ts</command>
|
|
113
113
|
</verification>
|
|
114
|
-
</
|
|
114
|
+
</TASK-T-001>
|
|
115
115
|
</sample-fragment>
|
|
116
|
-
<rule>Notice: the snippet uses CDATA wrapping (mandatory). Every
|
|
116
|
+
<rule>Notice: the task identity TASK-T-001 appears in the opening and closing element names. The snippet uses CDATA wrapping (mandatory). Every field is a child tag (no attributes): title, file, status, description, snippet, acceptance, and verification.</rule>
|
|
117
117
|
</example>
|
|
118
118
|
|
|
119
119
|
<file_structure>
|
|
@@ -142,6 +142,7 @@ export type CacheStoreOptions = {
|
|
|
142
142
|
<forbidden>XML attributes in any tag — use child elements only</forbidden>
|
|
143
143
|
<forbidden>Code outside CDATA — all snippets must be wrapped in CDATA sections</forbidden>
|
|
144
144
|
<forbidden>Numbered criterion tags — use plain <criterion>, not numbered variants</forbidden>
|
|
145
|
+
<forbidden>Generic <task> or <wave> elements with child id/num elements — identity belongs in the element name: <TASK-T-NNN>, <WAVE-N></forbidden>
|
|
145
146
|
</no_placeholders>
|
|
146
147
|
|
|
147
148
|
<self_review>
|
|
@@ -150,7 +151,7 @@ export type CacheStoreOptions = {
|
|
|
150
151
|
<check>Acceptance criteria quality: Is every criterion testable? Could a reviewer or implementer write a failing test for it?</check>
|
|
151
152
|
<check>Type consistency: Do types, signatures, and property names match across tasks? A function called `clearLayers()` in Task 3 but `clearFullLayers()` in Task 7 is a bug.</check>
|
|
152
153
|
<rule>Fix issues inline as you find them. No second review pass needed — just fix and continue.</rule>
|
|
153
|
-
<check>Format compliance: Are there zero XML attributes? Is every snippet in CDATA?
|
|
154
|
+
<check>Format compliance: Are there zero XML attributes? Is every snippet in CDATA? Is every task a <TASK-T-NNN> element with identity in the element name and no child id element?</check>
|
|
154
155
|
<check>Architecture presence: Does the plan have an architecture section with modules, contracts, and dependency graph?</check>
|
|
155
156
|
</self_review>
|
|
156
157
|
|
|
@@ -28,11 +28,9 @@
|
|
|
28
28
|
</architecture>
|
|
29
29
|
|
|
30
30
|
<tasks>
|
|
31
|
-
<
|
|
32
|
-
<num>1</num>
|
|
31
|
+
<WAVE-1>
|
|
33
32
|
<goal></goal>
|
|
34
|
-
<
|
|
35
|
-
<id>T-001</id>
|
|
33
|
+
<TASK-T-001>
|
|
36
34
|
<title></title>
|
|
37
35
|
<file></file>
|
|
38
36
|
<status>pending</status>
|
|
@@ -49,7 +47,7 @@
|
|
|
49
47
|
<verification>
|
|
50
48
|
<command></command>
|
|
51
49
|
</verification>
|
|
52
|
-
</
|
|
53
|
-
</
|
|
50
|
+
</TASK-T-001>
|
|
51
|
+
</WAVE-1>
|
|
54
52
|
</tasks>
|
|
55
53
|
</plan>
|