@satanwagen/reviewkit 0.1.1 → 0.1.2
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/cli/emblema-sync.mjs +36 -6
- package/package.json +3 -3
package/cli/emblema-sync.mjs
CHANGED
|
@@ -296,11 +296,15 @@ export function cmdServe(cwd) {
|
|
|
296
296
|
findings.set(item.id, toFinding(item, seq));
|
|
297
297
|
queuePush(item);
|
|
298
298
|
};
|
|
299
|
+
// Tombstone unconditionally: a delete for an id this process never saw (a
|
|
300
|
+
// ghost row left in the Emblema tile by an older/restarted agent) must still
|
|
301
|
+
// be reportable under `deleted`, or the row can never be cleared.
|
|
299
302
|
const dropItem = (id) => {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
303
|
+
// Already tombstoned and not live: nothing changed — don't churn the
|
|
304
|
+
// cursor (rooms replay their `deleted` list on every reconnect).
|
|
305
|
+
if (!findings.delete(id) && deletedIds.has(id)) return;
|
|
306
|
+
seq += 1;
|
|
307
|
+
deletedIds.set(id, seq);
|
|
304
308
|
};
|
|
305
309
|
|
|
306
310
|
/* -- realtime push to the Emblema intake (headers per contract v2) -- */
|
|
@@ -438,7 +442,7 @@ export function cmdServe(cwd) {
|
|
|
438
442
|
/* -- HTTP API -- */
|
|
439
443
|
const CORS = {
|
|
440
444
|
'access-control-allow-origin': '*',
|
|
441
|
-
'access-control-allow-methods': 'GET, POST, OPTIONS',
|
|
445
|
+
'access-control-allow-methods': 'GET, POST, DELETE, OPTIONS',
|
|
442
446
|
'access-control-allow-headers': 'content-type, authorization, x-reviewkit-key-id',
|
|
443
447
|
};
|
|
444
448
|
const send = (res, status, body) => {
|
|
@@ -555,7 +559,15 @@ export function cmdServe(cwd) {
|
|
|
555
559
|
return send(res, 400, { ok: false, error: 'invalid JSON' });
|
|
556
560
|
}
|
|
557
561
|
const mapped = STATUS_MAP[status];
|
|
558
|
-
if (!mapped)
|
|
562
|
+
if (!mapped) {
|
|
563
|
+
// Echo what arrived: the live 400s on `open` were an OLD installed
|
|
564
|
+
// agent, and a bare "must be …" message made that undiagnosable.
|
|
565
|
+
return send(res, 400, {
|
|
566
|
+
ok: false,
|
|
567
|
+
error: `status must be open|accepted|dismissed|fixed (received ${JSON.stringify(status ?? null)})`,
|
|
568
|
+
received: status ?? null,
|
|
569
|
+
});
|
|
570
|
+
}
|
|
559
571
|
const finding = findings.get(decodeURIComponent(statusMatch[1]));
|
|
560
572
|
if (!finding) return send(res, 404, { ok: false, error: 'unknown finding' });
|
|
561
573
|
const ws = sockets.get(finding._route);
|
|
@@ -567,6 +579,24 @@ export function cmdServe(cwd) {
|
|
|
567
579
|
});
|
|
568
580
|
return;
|
|
569
581
|
}
|
|
582
|
+
// DELETE /findings/{id} (POST …/delete for clients that cannot send DELETE).
|
|
583
|
+
// IDEMPOTENT: an unknown id still answers 200 and is tombstoned, so a ghost
|
|
584
|
+
// row left in the tile by an older/restarted agent can always be cleared.
|
|
585
|
+
// No body is read — the id is entirely in the path.
|
|
586
|
+
const deleteMatch =
|
|
587
|
+
(req.method === 'DELETE' && url.pathname.match(/^\/api\/emblema\/findings\/([^/]+)$/)) ||
|
|
588
|
+
(req.method === 'POST' && url.pathname.match(/^\/api\/emblema\/findings\/([^/]+)\/delete$/));
|
|
589
|
+
if (deleteMatch) {
|
|
590
|
+
const id = decodeURIComponent(deleteMatch[1]);
|
|
591
|
+
const finding = findings.get(id);
|
|
592
|
+
// Write-back first, while _route is still known: the site pin must
|
|
593
|
+
// disappear for every reviewer, not just in the tile.
|
|
594
|
+
const ws = finding && sockets.get(finding._route);
|
|
595
|
+
if (ws && ws.readyState === 1) ws.send(JSON.stringify({ t: 'item:delete', id }));
|
|
596
|
+
dropItem(id);
|
|
597
|
+
send(res, 200, { ok: true, id, known: !!finding });
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
570
600
|
send(res, 404, { ok: false, error: 'not found' });
|
|
571
601
|
});
|
|
572
602
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@satanwagen/reviewkit",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Drop-in visual review & feedback layer for React sites. Reviewers annotate the live page; nothing is ever applied
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Drop-in visual review & feedback layer for React sites. Reviewers annotate the live page; nothing is ever applied — changes are recorded as a portable session for a coding agent.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": false,
|
|
@@ -69,4 +69,4 @@
|
|
|
69
69
|
"bin": {
|
|
70
70
|
"reviewkit-emblema": "./cli/emblema-sync.mjs"
|
|
71
71
|
}
|
|
72
|
-
}
|
|
72
|
+
}
|