dsh-paper-search 0.1.2 → 0.1.3

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 CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  | dsh-paper-search | DeepSeek Harness | Diuji pada |
6
6
  |---|---|---|
7
- | 0.1.2 | 0.1.7-rc.2 | 28 Sep 2026, Windows, Node 24 |
7
+ | 0.1.3 | 0.1.7-rc.2 | 28 Sep 2026, Windows, Node 24 |
8
8
  | ~~0.1.0~~ | — | **JANGAN DIPAKAI — plugin gagal dimuat, lihat 0.1.1** |
9
9
 
10
10
  Paket ini tidak memakai API internal DSH selain `ctx.tools.register` dan
@@ -12,6 +12,40 @@ Paket ini tidak memakai API internal DSH selain `ctx.tools.register` dan
12
12
  berjalan di profil ini (`dsh-search-cascade`), jadi titik patahnya sama dan sudah
13
13
  diketahui.
14
14
 
15
+ ## [0.1.3] - 2026-09-28
16
+
17
+ ### Fixed
18
+
19
+ - **Portal Indonesia melaporkan GAGAL padahal hasilnya cuma KOSONG.** Ketiga
20
+ konektor Indonesia melempar `markup ... berubah` setiap kali penanda hasil tidak
21
+ ditemukan — termasuk saat portal itu **sah-sah saja menjawab nol hasil**. Itu
22
+ keliru dengan arah berlawanan dari prinsip paket ini: melaporkan kegagalan di
23
+ tempat yang seharusnya kosong sama menyesatkannya dengan menyembunyikan
24
+ kegagalan.
25
+
26
+ Ketahuan dari **uji orkestrasi**, bukan dari uji unit: `Sinta` gagal untuk
27
+ `"literasi digital remaja"` padahal berhasil untuk `"pendidikan karakter"`.
28
+ Setelah halaman kosong dan halaman ber-hasil dibandingkan, ternyata ketiga
29
+ portal punya penanda nol-hasilnya sendiri:
30
+
31
+ | Portal | Penanda nol hasil | Halaman kosong |
32
+ |---|---|---|
33
+ | Garuda | `Found 0 documents` | 11.181 huruf |
34
+ | Sinta | header `Results for "<q>"` tetap ada, tautan profil nol | 34.063 huruf |
35
+ | IOS | `No Results!` | 23.041 huruf |
36
+
37
+ `portalNolHasil()` sekarang membedakan **tiga** kemungkinan — nol hasil (→ `[]`),
38
+ markup berubah (→ error), dan diblokir (→ error) — bukan dua.
39
+
40
+ Akibatnya untuk Sinta: kueri spesifik yang memang nol hasil tidak lagi tampak
41
+ seperti kerusakan. Sinta mendaftar **jurnal**, bukan artikel, jadi nol hasil itu
42
+ wajar dan sekarang dilaporkan sebagai nol.
43
+
44
+ ### Added
45
+
46
+ - 3 asersi regresi: kueri omong kosong ke ketiga portal Indonesia harus
47
+ menghasilkan **0 hasil tanpa error**.
48
+
15
49
  ## [0.1.2] - 2026-09-28
16
50
 
17
51
  ### Fixed
package/lib/sources.js CHANGED
@@ -459,6 +459,29 @@ function ambilHtml(html, pola, batas) {
459
459
  return out;
460
460
  }
461
461
 
462
+ /**
463
+ * Saat penanda hasil tidak ditemukan, ada TIGA kemungkinan yang BERBEDA:
464
+ * 1. portal menjawab "nol hasil" -> `[]`, itu hasil yang SAH
465
+ * 2. markup portal berubah -> error
466
+ * 3. portal memblokir/mengalihkan -> error
467
+ *
468
+ * Sebelum ini (1) dan (2) diperlakukan sama, sehingga portal yang benar-benar
469
+ * kosong dilaporkan sebagai **GAGAL**. Itu keliru dengan arah berlawanan:
470
+ * melaporkan kegagalan padahal hasilnya sah-sah saja kosong — sama
471
+ * menyesatkannya dengan menyembunyikan kegagalan.
472
+ *
473
+ * Penanda nol-hasil diukur 28 Sep 2026 memakai kueri omong kosong, lalu
474
+ * dibandingkan dengan kueri yang ada hasilnya:
475
+ *
476
+ * Garuda : "Found 0 documents" (halaman 11.181 huruf)
477
+ * Sinta : header `Results for "<q>"` tetap ada, tautan profil nol
478
+ * (halaman 34.063 huruf) — Sinta TIDAK menulis pesan kosong
479
+ * IOS : "No Results!" (halaman 23.041 huruf)
480
+ */
481
+ function portalNolHasil(html, ...penanda) {
482
+ return penanda.some((re) => re.test(html));
483
+ }
484
+
462
485
  const GARUDA_BASE = 'https://garuda.kemdiktisaintek.go.id';
463
486
 
464
487
  /** Garuda — indeks artikel jurnal Indonesia (Kemdiktisaintek). */
@@ -472,9 +495,10 @@ async function garuda(query, { rows }) {
472
495
  journal: 'Garuda (jurnal Indonesia)',
473
496
  openAccess: true,
474
497
  })).filter((p) => p.title);
475
- // Penguraian HTML yang tidak menemukan satu pun pola = kemungkinan markup
476
- // berubah. Laporkan sebagai error, JANGAN sebagai "tidak ada hasil".
498
+ // Penguraian HTML yang tidak menemukan satu pun pola bisa berarti DUA hal yang
499
+ // berlawanan. Bedakan: Garuda menulis "Found 0 documents" saat memang kosong.
477
500
  if (hasil.length === 0 && !/title-article/.test(html)) {
501
+ if (portalNolHasil(html, /Found\s+0\s+document/i)) return [];
478
502
  throw new Error('markup Garuda berubah: penanda "title-article" tidak ditemukan lagi');
479
503
  }
480
504
  return hasil;
@@ -491,7 +515,12 @@ async function sinta(query, { rows }) {
491
515
  journal: 'Sinta (jurnal terakreditasi)',
492
516
  openAccess: true,
493
517
  })).filter((p) => p.title);
518
+ // Sinta TIDAK menulis pesan kosong — ia tetap menampilkan header
519
+ // `Results for "<kueri>"` lalu daftar yang kosong. Jadi header itu yang
520
+ // dipakai sebagai bukti "halaman dimuat, hasilnya memang nol".
521
+ // (Sinta mendaftar JURNAL, bukan artikel, jadi kueri spesifik memang sering nol.)
494
522
  if (hasil.length === 0 && !/journals\/profile\//.test(html)) {
523
+ if (portalNolHasil(html, /Results for/i)) return [];
495
524
  throw new Error('markup Sinta berubah: tautan "journals/profile" tidak ditemukan lagi');
496
525
  }
497
526
  return hasil;
@@ -509,6 +538,7 @@ async function ios(query, { rows }) {
509
538
  openAccess: true,
510
539
  })).filter((p) => p.title);
511
540
  if (hasil.length === 0 && !/class="title"/.test(html)) {
541
+ if (portalNolHasil(html, /No Results!/i)) return [];
512
542
  throw new Error('markup IOS berubah: tautan hasil ber-class "title" tidak ditemukan lagi');
513
543
  }
514
544
  return hasil;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-paper-search",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Literature search for DeepSeek Harness: thirteen international sources (Crossref, OpenAlex, DOAJ, Europe PMC, PubMed, PubMed Central, arXiv, Semantic Scholar, CORE, Zenodo, HAL, IACR ePrint, Unpaywall) and three Indonesian journal portals (Garuda, Sinta, IOS OneSearch), all native HTTP with no external CLI required, plus a status tool that reports which sources answer and which credentials are configured.",
5
5
  "license": "MIT",
6
6
  "type": "module",