@tenonhq/dovetail-core 0.0.105 → 0.0.107
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/dist/appUtils.js +22 -16
- package/dist/commander.js +2 -2
- package/dist/reconcile/applyPlan.js +4 -3
- package/dist/reconcile/multiPass.js +55 -0
- package/dist/reconcileCommand.js +178 -16
- package/dist/snClient.js +10 -0
- package/dist/tests/reconcileApplyPlan.test.js +2 -2
- package/dist/tests/reconcileMultiPass.test.js +74 -0
- package/dist/tests/updateSetConfig.test.js +126 -0
- package/dist/updateSetCommands.js +61 -0
- package/dist/updateSetConfig.js +55 -0
- package/package.json +3 -3
- package/release-manifest.json +190 -225
- package/skills/dove-manage-update-sets.md +6 -0
- package/dist/reconcile/deleteOrder.js +0 -52
- package/dist/tests/reconcileDeleteOrder.test.js +0 -70
package/release-manifest.json
CHANGED
|
@@ -1,7 +1,196 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "dovetail-manifest/v1",
|
|
3
|
-
"generated_at": "2026-06-
|
|
3
|
+
"generated_at": "2026-06-16T01:18:07.747Z",
|
|
4
4
|
"events": [
|
|
5
|
+
{
|
|
6
|
+
"$schema": "dovetail-release-event/v1",
|
|
7
|
+
"event_id": "dovetail-babel-plugin@0.0.11",
|
|
8
|
+
"package": "@tenonhq/dovetail-babel-plugin",
|
|
9
|
+
"version": "0.0.11",
|
|
10
|
+
"prev_version": "0.0.10",
|
|
11
|
+
"published_at": "2026-06-16T01:18:07.728Z",
|
|
12
|
+
"git": {
|
|
13
|
+
"sha": "edabc263bd89f08b5c7a075f270c2172e82da4da",
|
|
14
|
+
"tag": "dovetail-babel-plugin@0.0.11"
|
|
15
|
+
},
|
|
16
|
+
"semver_bump": "patch",
|
|
17
|
+
"commits": [
|
|
18
|
+
{
|
|
19
|
+
"sha": "edabc263b",
|
|
20
|
+
"subject": "chore(deps): bump @babel/core from 7.29.0 to 7.29.6 (#181)",
|
|
21
|
+
"pr": 181
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"sha": "de9d77971",
|
|
25
|
+
"subject": "chore(release): publish 14 packages [skip ci]"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"exports_delta": null,
|
|
29
|
+
"narrative": null
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"$schema": "dovetail-release-event/v1",
|
|
33
|
+
"event_id": "dovetail-babel-plugin-remove-modules@0.0.11",
|
|
34
|
+
"package": "@tenonhq/dovetail-babel-plugin-remove-modules",
|
|
35
|
+
"version": "0.0.11",
|
|
36
|
+
"prev_version": "0.0.10",
|
|
37
|
+
"published_at": "2026-06-16T01:18:07.728Z",
|
|
38
|
+
"git": {
|
|
39
|
+
"sha": "edabc263bd89f08b5c7a075f270c2172e82da4da",
|
|
40
|
+
"tag": "dovetail-babel-plugin-remove-modules@0.0.11"
|
|
41
|
+
},
|
|
42
|
+
"semver_bump": "patch",
|
|
43
|
+
"commits": [
|
|
44
|
+
{
|
|
45
|
+
"sha": "edabc263b",
|
|
46
|
+
"subject": "chore(deps): bump @babel/core from 7.29.0 to 7.29.6 (#181)",
|
|
47
|
+
"pr": 181
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"sha": "de9d77971",
|
|
51
|
+
"subject": "chore(release): publish 14 packages [skip ci]"
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"exports_delta": null,
|
|
55
|
+
"narrative": null
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"$schema": "dovetail-release-event/v1",
|
|
59
|
+
"event_id": "dovetail-babel-preset-servicenow@0.0.11",
|
|
60
|
+
"package": "@tenonhq/dovetail-babel-preset-servicenow",
|
|
61
|
+
"version": "0.0.11",
|
|
62
|
+
"prev_version": "0.0.10",
|
|
63
|
+
"published_at": "2026-06-16T01:18:07.728Z",
|
|
64
|
+
"git": {
|
|
65
|
+
"sha": "edabc263bd89f08b5c7a075f270c2172e82da4da",
|
|
66
|
+
"tag": "dovetail-babel-preset-servicenow@0.0.11"
|
|
67
|
+
},
|
|
68
|
+
"semver_bump": "patch",
|
|
69
|
+
"commits": [
|
|
70
|
+
{
|
|
71
|
+
"sha": "edabc263b",
|
|
72
|
+
"subject": "chore(deps): bump @babel/core from 7.29.0 to 7.29.6 (#181)",
|
|
73
|
+
"pr": 181
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"sha": "de9d77971",
|
|
77
|
+
"subject": "chore(release): publish 14 packages [skip ci]"
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"exports_delta": null,
|
|
81
|
+
"narrative": null
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"$schema": "dovetail-release-event/v1",
|
|
85
|
+
"event_id": "dovetail-servicenow@0.0.21",
|
|
86
|
+
"package": "@tenonhq/dovetail-servicenow",
|
|
87
|
+
"version": "0.0.21",
|
|
88
|
+
"prev_version": "0.0.20",
|
|
89
|
+
"published_at": "2026-06-15T17:59:30.698Z",
|
|
90
|
+
"git": {
|
|
91
|
+
"sha": "51e4e4592d491cd337f5bc1aa93d04f582f555a1",
|
|
92
|
+
"tag": "dovetail-servicenow@0.0.21"
|
|
93
|
+
},
|
|
94
|
+
"semver_bump": "patch",
|
|
95
|
+
"commits": [
|
|
96
|
+
{
|
|
97
|
+
"sha": "51e4e4592",
|
|
98
|
+
"subject": "feat(mcp): per-call instance retarget for servicenow_query_table (#180)",
|
|
99
|
+
"pr": 180
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"sha": "c5d9106c4",
|
|
103
|
+
"subject": "chore(release): publish 2 packages [skip ci]"
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"exports_delta": null,
|
|
107
|
+
"narrative": null
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"$schema": "dovetail-release-event/v1",
|
|
111
|
+
"event_id": "dovetail-mcp@0.0.16",
|
|
112
|
+
"package": "@tenonhq/dovetail-mcp",
|
|
113
|
+
"version": "0.0.16",
|
|
114
|
+
"prev_version": "0.0.15",
|
|
115
|
+
"published_at": "2026-06-15T17:59:30.698Z",
|
|
116
|
+
"git": {
|
|
117
|
+
"sha": "51e4e4592d491cd337f5bc1aa93d04f582f555a1",
|
|
118
|
+
"tag": "dovetail-mcp@0.0.16"
|
|
119
|
+
},
|
|
120
|
+
"semver_bump": "patch",
|
|
121
|
+
"commits": [
|
|
122
|
+
{
|
|
123
|
+
"sha": "51e4e4592",
|
|
124
|
+
"subject": "feat(mcp): per-call instance retarget for servicenow_query_table (#180)",
|
|
125
|
+
"pr": 180
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"sha": "c5d9106c4",
|
|
129
|
+
"subject": "chore(release): publish 2 packages [skip ci]"
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
"exports_delta": null,
|
|
133
|
+
"narrative": null
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"$schema": "dovetail-release-event/v1",
|
|
137
|
+
"event_id": "dovetail-servicenow@0.0.20",
|
|
138
|
+
"package": "@tenonhq/dovetail-servicenow",
|
|
139
|
+
"version": "0.0.20",
|
|
140
|
+
"prev_version": "0.0.19",
|
|
141
|
+
"published_at": "2026-06-14T00:08:21.397Z",
|
|
142
|
+
"git": {
|
|
143
|
+
"sha": "41295667a526f32eb7a5763ec1b416c19ef49bee",
|
|
144
|
+
"tag": "dovetail-servicenow@0.0.20"
|
|
145
|
+
},
|
|
146
|
+
"semver_bump": "patch",
|
|
147
|
+
"commits": [
|
|
148
|
+
{
|
|
149
|
+
"sha": "41295667a",
|
|
150
|
+
"subject": "chore(servicenow): release 0.0.20 — ship create-table fix to npm (#179)",
|
|
151
|
+
"pr": 179
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
"exports_delta": null,
|
|
155
|
+
"narrative": null
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"$schema": "dovetail-release-event/v1",
|
|
159
|
+
"event_id": "dovetail-mcp@0.0.15",
|
|
160
|
+
"package": "@tenonhq/dovetail-mcp",
|
|
161
|
+
"version": "0.0.15",
|
|
162
|
+
"prev_version": "0.0.14",
|
|
163
|
+
"published_at": "2026-06-14T00:08:21.397Z",
|
|
164
|
+
"git": {
|
|
165
|
+
"sha": "41295667a526f32eb7a5763ec1b416c19ef49bee",
|
|
166
|
+
"tag": "dovetail-mcp@0.0.15"
|
|
167
|
+
},
|
|
168
|
+
"semver_bump": "patch",
|
|
169
|
+
"commits": [],
|
|
170
|
+
"exports_delta": null,
|
|
171
|
+
"narrative": null
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"$schema": "dovetail-release-event/v1",
|
|
175
|
+
"event_id": "dovetail-eslint-plugin@0.0.13",
|
|
176
|
+
"package": "@tenonhq/dovetail-eslint-plugin",
|
|
177
|
+
"version": "0.0.13",
|
|
178
|
+
"prev_version": "0.0.12",
|
|
179
|
+
"published_at": "2026-06-14T00:02:00.641Z",
|
|
180
|
+
"git": {
|
|
181
|
+
"sha": "ff9d18fd2c1a7305862cefdc942bbbf35ee155e8",
|
|
182
|
+
"tag": "dovetail-eslint-plugin@0.0.13"
|
|
183
|
+
},
|
|
184
|
+
"semver_bump": "patch",
|
|
185
|
+
"commits": [
|
|
186
|
+
{
|
|
187
|
+
"sha": "ff9d18fd2",
|
|
188
|
+
"subject": "docs(eslint-plugin): tighten overview wording"
|
|
189
|
+
}
|
|
190
|
+
],
|
|
191
|
+
"exports_delta": null,
|
|
192
|
+
"narrative": null
|
|
193
|
+
},
|
|
5
194
|
{
|
|
6
195
|
"$schema": "dovetail-release-event/v1",
|
|
7
196
|
"event_id": "dovetail-claude-plans@0.0.23",
|
|
@@ -1183,230 +1372,6 @@
|
|
|
1183
1372
|
],
|
|
1184
1373
|
"exports_delta": null,
|
|
1185
1374
|
"narrative": null
|
|
1186
|
-
},
|
|
1187
|
-
{
|
|
1188
|
-
"$schema": "dovetail-release-event/v1",
|
|
1189
|
-
"event_id": "dovetail-schema@0.0.9",
|
|
1190
|
-
"package": "@tenonhq/dovetail-schema",
|
|
1191
|
-
"version": "0.0.9",
|
|
1192
|
-
"prev_version": "0.0.8",
|
|
1193
|
-
"published_at": "2026-05-29T21:30:43.647Z",
|
|
1194
|
-
"git": {
|
|
1195
|
-
"sha": "dac76cc7b8e6a346aa54a84c7b50c442323301fb",
|
|
1196
|
-
"tag": "dovetail-schema@0.0.9"
|
|
1197
|
-
},
|
|
1198
|
-
"semver_bump": "patch",
|
|
1199
|
-
"commits": [
|
|
1200
|
-
{
|
|
1201
|
-
"sha": "dac76cc7b",
|
|
1202
|
-
"subject": "feat(schema): snapshots + structured drift diff for dove schema (#122)",
|
|
1203
|
-
"pr": 122
|
|
1204
|
-
},
|
|
1205
|
-
{
|
|
1206
|
-
"sha": "9332fdf7a",
|
|
1207
|
-
"subject": "chore(release): publish 20 packages [skip ci]"
|
|
1208
|
-
},
|
|
1209
|
-
{
|
|
1210
|
-
"sha": "9046da774",
|
|
1211
|
-
"subject": "chore(release): publish 19 packages [skip ci]"
|
|
1212
|
-
}
|
|
1213
|
-
],
|
|
1214
|
-
"exports_delta": null,
|
|
1215
|
-
"narrative": null
|
|
1216
|
-
},
|
|
1217
|
-
{
|
|
1218
|
-
"$schema": "dovetail-release-event/v1",
|
|
1219
|
-
"event_id": "dovetail-core@0.0.95",
|
|
1220
|
-
"package": "@tenonhq/dovetail-core",
|
|
1221
|
-
"version": "0.0.95",
|
|
1222
|
-
"prev_version": "0.0.94",
|
|
1223
|
-
"published_at": "2026-05-29T21:30:43.647Z",
|
|
1224
|
-
"git": {
|
|
1225
|
-
"sha": "dac76cc7b8e6a346aa54a84c7b50c442323301fb",
|
|
1226
|
-
"tag": "dovetail-core@0.0.95"
|
|
1227
|
-
},
|
|
1228
|
-
"semver_bump": "patch",
|
|
1229
|
-
"commits": [
|
|
1230
|
-
{
|
|
1231
|
-
"sha": "dac76cc7b",
|
|
1232
|
-
"subject": "feat(schema): snapshots + structured drift diff for dove schema (#122)",
|
|
1233
|
-
"pr": 122
|
|
1234
|
-
},
|
|
1235
|
-
{
|
|
1236
|
-
"sha": "da705804d",
|
|
1237
|
-
"subject": "chore(release): @tenonhq/dovetail-dashboard@0.0.33 [skip ci]"
|
|
1238
|
-
},
|
|
1239
|
-
{
|
|
1240
|
-
"sha": "92213e1f8",
|
|
1241
|
-
"subject": "chore(release): publish 2 packages [skip ci]"
|
|
1242
|
-
},
|
|
1243
|
-
{
|
|
1244
|
-
"sha": "1d43f9122",
|
|
1245
|
-
"subject": "chore(release): @tenonhq/dovetail-core@0.0.94 [skip ci]"
|
|
1246
|
-
}
|
|
1247
|
-
],
|
|
1248
|
-
"exports_delta": null,
|
|
1249
|
-
"narrative": null
|
|
1250
|
-
},
|
|
1251
|
-
{
|
|
1252
|
-
"$schema": "dovetail-release-event/v1",
|
|
1253
|
-
"event_id": "dovetail-dashboard@0.0.33",
|
|
1254
|
-
"package": "@tenonhq/dovetail-dashboard",
|
|
1255
|
-
"version": "0.0.33",
|
|
1256
|
-
"prev_version": "0.0.32",
|
|
1257
|
-
"published_at": "2026-05-29T16:55:37.729Z",
|
|
1258
|
-
"git": {
|
|
1259
|
-
"sha": "3aaef1ba92364c119ece69369c5cc3379da0ed73",
|
|
1260
|
-
"tag": "dovetail-dashboard@0.0.33"
|
|
1261
|
-
},
|
|
1262
|
-
"semver_bump": "patch",
|
|
1263
|
-
"commits": [
|
|
1264
|
-
{
|
|
1265
|
-
"sha": "3aaef1ba9",
|
|
1266
|
-
"subject": "fix: legible inline code in Claude Plans dark mode (#120)",
|
|
1267
|
-
"pr": 120
|
|
1268
|
-
},
|
|
1269
|
-
{
|
|
1270
|
-
"sha": "92213e1f8",
|
|
1271
|
-
"subject": "chore(release): publish 2 packages [skip ci]"
|
|
1272
|
-
}
|
|
1273
|
-
],
|
|
1274
|
-
"exports_delta": null,
|
|
1275
|
-
"narrative": null
|
|
1276
|
-
},
|
|
1277
|
-
{
|
|
1278
|
-
"$schema": "dovetail-release-event/v1",
|
|
1279
|
-
"event_id": "dovetail-claude-plans@0.0.20",
|
|
1280
|
-
"package": "@tenonhq/dovetail-claude-plans",
|
|
1281
|
-
"version": "0.0.20",
|
|
1282
|
-
"prev_version": "0.0.19",
|
|
1283
|
-
"published_at": "2026-05-29T02:18:11.229Z",
|
|
1284
|
-
"git": {
|
|
1285
|
-
"sha": "6a12c10733b64732855a8125c84f0d4846ced256",
|
|
1286
|
-
"tag": "dovetail-claude-plans@0.0.20"
|
|
1287
|
-
},
|
|
1288
|
-
"semver_bump": "patch",
|
|
1289
|
-
"commits": [
|
|
1290
|
-
{
|
|
1291
|
-
"sha": "6a12c1073",
|
|
1292
|
-
"subject": "feat: claude-plans version history, feature score, selected-state + deep-link hardening (#118)",
|
|
1293
|
-
"pr": 118
|
|
1294
|
-
},
|
|
1295
|
-
{
|
|
1296
|
-
"sha": "578d6fb2a",
|
|
1297
|
-
"subject": "chore(release): publish 2 packages [skip ci]"
|
|
1298
|
-
}
|
|
1299
|
-
],
|
|
1300
|
-
"exports_delta": null,
|
|
1301
|
-
"narrative": null
|
|
1302
|
-
},
|
|
1303
|
-
{
|
|
1304
|
-
"$schema": "dovetail-release-event/v1",
|
|
1305
|
-
"event_id": "dovetail-dashboard@0.0.32",
|
|
1306
|
-
"package": "@tenonhq/dovetail-dashboard",
|
|
1307
|
-
"version": "0.0.32",
|
|
1308
|
-
"prev_version": "0.0.31",
|
|
1309
|
-
"published_at": "2026-05-29T02:18:11.229Z",
|
|
1310
|
-
"git": {
|
|
1311
|
-
"sha": "6a12c10733b64732855a8125c84f0d4846ced256",
|
|
1312
|
-
"tag": "dovetail-dashboard@0.0.32"
|
|
1313
|
-
},
|
|
1314
|
-
"semver_bump": "patch",
|
|
1315
|
-
"commits": [
|
|
1316
|
-
{
|
|
1317
|
-
"sha": "6a12c1073",
|
|
1318
|
-
"subject": "feat: claude-plans version history, feature score, selected-state + deep-link hardening (#118)",
|
|
1319
|
-
"pr": 118
|
|
1320
|
-
},
|
|
1321
|
-
{
|
|
1322
|
-
"sha": "578d6fb2a",
|
|
1323
|
-
"subject": "chore(release): publish 2 packages [skip ci]"
|
|
1324
|
-
}
|
|
1325
|
-
],
|
|
1326
|
-
"exports_delta": null,
|
|
1327
|
-
"narrative": null
|
|
1328
|
-
},
|
|
1329
|
-
{
|
|
1330
|
-
"$schema": "dovetail-release-event/v1",
|
|
1331
|
-
"event_id": "dovetail-core@0.0.94",
|
|
1332
|
-
"package": "@tenonhq/dovetail-core",
|
|
1333
|
-
"version": "0.0.94",
|
|
1334
|
-
"prev_version": "0.0.93",
|
|
1335
|
-
"published_at": "2026-05-28T23:46:03.175Z",
|
|
1336
|
-
"git": {
|
|
1337
|
-
"sha": "8a76deffc38892321c92ae538fee3bc6b8f90d76",
|
|
1338
|
-
"tag": "dovetail-core@0.0.94"
|
|
1339
|
-
},
|
|
1340
|
-
"semver_bump": "patch",
|
|
1341
|
-
"commits": [
|
|
1342
|
-
{
|
|
1343
|
-
"sha": "8a76deffc",
|
|
1344
|
-
"subject": "fix: filesystem-safe record folder names (sys_id fallback for Windows) (#117)",
|
|
1345
|
-
"pr": 117
|
|
1346
|
-
},
|
|
1347
|
-
{
|
|
1348
|
-
"sha": "578d6fb2a",
|
|
1349
|
-
"subject": "chore(release): publish 2 packages [skip ci]"
|
|
1350
|
-
},
|
|
1351
|
-
{
|
|
1352
|
-
"sha": "3faeec43f",
|
|
1353
|
-
"subject": "chore(release): @tenonhq/dovetail-core@0.0.93 [skip ci]"
|
|
1354
|
-
}
|
|
1355
|
-
],
|
|
1356
|
-
"exports_delta": null,
|
|
1357
|
-
"narrative": null
|
|
1358
|
-
},
|
|
1359
|
-
{
|
|
1360
|
-
"$schema": "dovetail-release-event/v1",
|
|
1361
|
-
"event_id": "dovetail-claude-plans@0.0.19",
|
|
1362
|
-
"package": "@tenonhq/dovetail-claude-plans",
|
|
1363
|
-
"version": "0.0.19",
|
|
1364
|
-
"prev_version": "0.0.18",
|
|
1365
|
-
"published_at": "2026-05-28T15:54:22.483Z",
|
|
1366
|
-
"git": {
|
|
1367
|
-
"sha": "0247ef6e75093c95359413725977df07bd5bff70",
|
|
1368
|
-
"tag": "dovetail-claude-plans@0.0.19"
|
|
1369
|
-
},
|
|
1370
|
-
"semver_bump": "patch",
|
|
1371
|
-
"commits": [
|
|
1372
|
-
{
|
|
1373
|
-
"sha": "0247ef6e7",
|
|
1374
|
-
"subject": "feat(dashboard): Prompt Lints filters + merged-PR filter for Claude Plans (#116)",
|
|
1375
|
-
"pr": 116
|
|
1376
|
-
},
|
|
1377
|
-
{
|
|
1378
|
-
"sha": "5f14a3421",
|
|
1379
|
-
"subject": "chore(release): @tenonhq/dovetail-claude-plans@0.0.18 [skip ci]"
|
|
1380
|
-
}
|
|
1381
|
-
],
|
|
1382
|
-
"exports_delta": null,
|
|
1383
|
-
"narrative": null
|
|
1384
|
-
},
|
|
1385
|
-
{
|
|
1386
|
-
"$schema": "dovetail-release-event/v1",
|
|
1387
|
-
"event_id": "dovetail-dashboard@0.0.31",
|
|
1388
|
-
"package": "@tenonhq/dovetail-dashboard",
|
|
1389
|
-
"version": "0.0.31",
|
|
1390
|
-
"prev_version": "0.0.30",
|
|
1391
|
-
"published_at": "2026-05-28T15:54:22.483Z",
|
|
1392
|
-
"git": {
|
|
1393
|
-
"sha": "0247ef6e75093c95359413725977df07bd5bff70",
|
|
1394
|
-
"tag": "dovetail-dashboard@0.0.31"
|
|
1395
|
-
},
|
|
1396
|
-
"semver_bump": "patch",
|
|
1397
|
-
"commits": [
|
|
1398
|
-
{
|
|
1399
|
-
"sha": "0247ef6e7",
|
|
1400
|
-
"subject": "feat(dashboard): Prompt Lints filters + merged-PR filter for Claude Plans (#116)",
|
|
1401
|
-
"pr": 116
|
|
1402
|
-
},
|
|
1403
|
-
{
|
|
1404
|
-
"sha": "c35d549c4",
|
|
1405
|
-
"subject": "chore(release): @tenonhq/dovetail-dashboard@0.0.30 [skip ci]"
|
|
1406
|
-
}
|
|
1407
|
-
],
|
|
1408
|
-
"exports_delta": null,
|
|
1409
|
-
"narrative": null
|
|
1410
1375
|
}
|
|
1411
1376
|
]
|
|
1412
1377
|
}
|
|
@@ -62,6 +62,12 @@ Launches at `http://localhost:3456` (configurable via `DASHBOARD_PORT` in `.env`
|
|
|
62
62
|
|
|
63
63
|
The dashboard reads scopes from `dove.config.js` and stores selections in `.dove-update-sets.json`.
|
|
64
64
|
|
|
65
|
+
### How `dove push` chooses an update set (precedence)
|
|
66
|
+
|
|
67
|
+
`dove push` routes each record's capture by the per-scope map in **`.dove-update-sets.json`**, keyed on the record's scope — **not** by the instance's currently-active update set. When a scope has an entry, the push captures into that set via `pushWithUpdateSet`; when it has none, the push falls back to a plain update that lands in whatever set is active on the instance.
|
|
68
|
+
|
|
69
|
+
`createUpdateSet`, `switchUpdateSet`, and `push --updateSet` now write the affected scope's entry into `.dove-update-sets.json` as part of activating the set, so the routing file, the active set, and the push destination stay consistent. Each prints the resolved destination, e.g. `Push routing updated: x_cadso_core -> FEAT-123 (sys_id)`, and every push prints `Update set routing (from .dove-update-sets.json): <scope> -> <name> (<sys_id>)` so you can see exactly where captures land. If you edit `.dove-update-sets.json` by hand, that entry wins until you switch sets again.
|
|
70
|
+
|
|
65
71
|
### Multi-Scope Update Set Monitoring
|
|
66
72
|
|
|
67
73
|
When using `npx dove watchAllScopes`, update set status is automatically checked every 2 minutes. It warns if any scope is using the DEFAULT update set (a common mistake that puts changes in the wrong place).
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// FK-safe deletion without building a dependency graph. ServiceNow refuses to
|
|
3
|
-
// delete a record another record still references; the safe order is therefore
|
|
4
|
-
// children before parents. Rather than model the foreign-key graph, delete in
|
|
5
|
-
// passes: attempt every pending record, keep whatever succeeded, and retry the
|
|
6
|
-
// failures on the next pass. A record blocked by a still-present dependent
|
|
7
|
-
// succeeds once that dependent is gone. Stop when a full pass makes no progress
|
|
8
|
-
// (a genuine, non-ordering failure — e.g. ACL) and report the stragglers.
|
|
9
|
-
//
|
|
10
|
-
// Pure control flow: the actual delete is injected, so the loop is unit-tested
|
|
11
|
-
// with a fake executor that encodes "B cannot delete until A is gone."
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.runMultiPassDeletes = runMultiPassDeletes;
|
|
14
|
-
async function runMultiPassDeletes(changes, attemptDelete) {
|
|
15
|
-
const succeeded = [];
|
|
16
|
-
let pending = changes.slice();
|
|
17
|
-
let lastError = new Map();
|
|
18
|
-
while (pending.length > 0) {
|
|
19
|
-
const stillPending = [];
|
|
20
|
-
let progressed = false;
|
|
21
|
-
lastError = new Map();
|
|
22
|
-
for (const change of pending) {
|
|
23
|
-
let result;
|
|
24
|
-
try {
|
|
25
|
-
result = await attemptDelete(change);
|
|
26
|
-
}
|
|
27
|
-
catch (e) {
|
|
28
|
-
result = { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
29
|
-
}
|
|
30
|
-
if (result.ok) {
|
|
31
|
-
succeeded.push({ change, ok: true });
|
|
32
|
-
progressed = true;
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
stillPending.push(change);
|
|
36
|
-
lastError.set(change.sys_id, result.error || "delete failed");
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
pending = stillPending;
|
|
40
|
-
if (!progressed) {
|
|
41
|
-
// A full pass deleted nothing — the remaining failures are not ordering
|
|
42
|
-
// problems. Report them and stop.
|
|
43
|
-
break;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
const failures = pending.map((change) => ({
|
|
47
|
-
change,
|
|
48
|
-
ok: false,
|
|
49
|
-
error: lastError.get(change.sys_id) || "delete failed",
|
|
50
|
-
}));
|
|
51
|
-
return succeeded.concat(failures);
|
|
52
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Tests for the multi-pass delete loop: clean deletes, emergent FK ordering
|
|
3
|
-
// (a record blocked until its dependent is gone), and a genuine failure that
|
|
4
|
-
// survives a no-progress pass and is reported.
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const deleteOrder_1 = require("../reconcile/deleteOrder");
|
|
7
|
-
const del = (sys_id) => ({
|
|
8
|
-
kind: "delete",
|
|
9
|
-
table: "sys_script",
|
|
10
|
-
scope: "x_cadso_core",
|
|
11
|
-
sys_id,
|
|
12
|
-
name: sys_id,
|
|
13
|
-
fieldDeltas: [],
|
|
14
|
-
deleteDisposition: "tracked",
|
|
15
|
-
});
|
|
16
|
-
describe("runMultiPassDeletes", () => {
|
|
17
|
-
it("deletes everything in a single clean pass", async () => {
|
|
18
|
-
const calls = [];
|
|
19
|
-
const exec = async (c) => {
|
|
20
|
-
calls.push(c.sys_id);
|
|
21
|
-
return { ok: true };
|
|
22
|
-
};
|
|
23
|
-
const out = await (0, deleteOrder_1.runMultiPassDeletes)([del("a"), del("b")], exec);
|
|
24
|
-
expect(out.every((o) => o.ok)).toBe(true);
|
|
25
|
-
expect(calls.sort()).toEqual(["a", "b"]);
|
|
26
|
-
});
|
|
27
|
-
it("resolves FK ordering: parent succeeds only after the child is gone", async () => {
|
|
28
|
-
// "parent" cannot delete while "child" still exists.
|
|
29
|
-
const deleted = new Set();
|
|
30
|
-
const exec = async (c) => {
|
|
31
|
-
if (c.sys_id === "parent" && !deleted.has("child")) {
|
|
32
|
-
return { ok: false, error: "still referenced by child" };
|
|
33
|
-
}
|
|
34
|
-
deleted.add(c.sys_id);
|
|
35
|
-
return { ok: true };
|
|
36
|
-
};
|
|
37
|
-
// parent is attempted first, fails, then succeeds on the pass after child.
|
|
38
|
-
const out = await (0, deleteOrder_1.runMultiPassDeletes)([del("parent"), del("child")], exec);
|
|
39
|
-
expect(out.filter((o) => o.ok).map((o) => o.change.sys_id).sort()).toEqual([
|
|
40
|
-
"child",
|
|
41
|
-
"parent",
|
|
42
|
-
]);
|
|
43
|
-
expect(out.every((o) => o.ok)).toBe(true);
|
|
44
|
-
});
|
|
45
|
-
it("reports a record that fails for a non-ordering reason", async () => {
|
|
46
|
-
const exec = async (c) => {
|
|
47
|
-
if (c.sys_id === "locked") {
|
|
48
|
-
return { ok: false, error: "ACL blocked" };
|
|
49
|
-
}
|
|
50
|
-
return { ok: true };
|
|
51
|
-
};
|
|
52
|
-
const out = await (0, deleteOrder_1.runMultiPassDeletes)([del("ok"), del("locked")], exec);
|
|
53
|
-
const failed = out.filter((o) => !o.ok);
|
|
54
|
-
expect(failed).toHaveLength(1);
|
|
55
|
-
expect(failed[0].change.sys_id).toBe("locked");
|
|
56
|
-
expect(failed[0].error).toBe("ACL blocked");
|
|
57
|
-
});
|
|
58
|
-
it("treats a thrown executor error as a failure", async () => {
|
|
59
|
-
const exec = async () => {
|
|
60
|
-
throw new Error("network down");
|
|
61
|
-
};
|
|
62
|
-
const out = await (0, deleteOrder_1.runMultiPassDeletes)([del("a")], exec);
|
|
63
|
-
expect(out[0].ok).toBe(false);
|
|
64
|
-
expect(out[0].error).toBe("network down");
|
|
65
|
-
});
|
|
66
|
-
it("returns [] for no changes", async () => {
|
|
67
|
-
const out = await (0, deleteOrder_1.runMultiPassDeletes)([], async () => ({ ok: true }));
|
|
68
|
-
expect(out).toEqual([]);
|
|
69
|
-
});
|
|
70
|
-
});
|