@akredit/acik-mcp 0.1.0 → 0.4.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.
Files changed (29) hide show
  1. package/README.md +94 -8
  2. package/dist/apps/acik-mcp/src/araclar.d.ts +2 -28
  3. package/dist/apps/acik-mcp/src/araclar.js +27 -114
  4. package/dist/apps/acik-mcp/src/bologna.d.ts +209 -0
  5. package/dist/apps/acik-mcp/src/bologna.js +1321 -0
  6. package/dist/apps/acik-mcp/src/genel-ayristir.d.ts +83 -0
  7. package/dist/apps/acik-mcp/src/genel-ayristir.js +411 -0
  8. package/dist/apps/acik-mcp/src/http.js +4 -2
  9. package/dist/apps/acik-mcp/src/index.d.ts +6 -0
  10. package/dist/apps/acik-mcp/src/index.js +6 -0
  11. package/dist/apps/acik-mcp/src/kaynak-dogrula.d.ts +47 -0
  12. package/dist/apps/acik-mcp/src/kaynak-dogrula.js +319 -0
  13. package/dist/apps/acik-mcp/src/kaynak.d.ts +72 -0
  14. package/dist/apps/acik-mcp/src/kaynak.js +155 -0
  15. package/dist/apps/acik-mcp/src/kisisel-veri.d.ts +14 -2
  16. package/dist/apps/acik-mcp/src/kisisel-veri.js +63 -15
  17. package/dist/apps/acik-mcp/src/not-tablosu.d.ts +33 -0
  18. package/dist/apps/acik-mcp/src/not-tablosu.js +243 -0
  19. package/dist/apps/acik-mcp/src/promptlar.d.ts +25 -0
  20. package/dist/apps/acik-mcp/src/promptlar.js +253 -0
  21. package/dist/apps/acik-mcp/src/sunucu.d.ts +12 -4
  22. package/dist/apps/acik-mcp/src/sunucu.js +103 -24
  23. package/dist/apps/acik-mcp/src/temel.d.ts +54 -0
  24. package/dist/apps/acik-mcp/src/temel.js +10 -0
  25. package/dist/apps/acik-mcp/src/yardim.d.ts +56 -0
  26. package/dist/apps/acik-mcp/src/yardim.js +371 -0
  27. package/dist/packages/baglayicilar/src/bologna-proliz/ayristir.d.ts +29 -0
  28. package/dist/packages/baglayicilar/src/bologna-proliz/ayristir.js +200 -0
  29. package/package.json +4 -2
@@ -0,0 +1,83 @@
1
+ export type GenelAlan = "kod" | "ad" | "yariyil" | "tul" | "kredi" | "akts" | "dil" | "tur" | "onKosul" | "amac" | "icerik" | "yontem" | "notlar" | "ciktilar" | "haftalar" | "degerlendirme" | "isyuku" | "kaynaklar" | "kisi";
2
+ /** Bir hücre ya da satır başı bir etiket mi? Tam eşleşme (sondaki iki nokta ve parantez yok sayılır). */
3
+ export declare function etiketAlani(s: string): GenelAlan | null;
4
+ export type Satir = string[];
5
+ /** HTML ya da düz metni satır ve hücrelere çevirir. Tablo hücreleri sekmeyle ayrılır. */
6
+ export declare function satirlara(girdi: string): Satir[];
7
+ export interface Bolum {
8
+ alan: GenelAlan;
9
+ /** Sayfadaki etiket, olduğu gibi (ör. "Dersi Verenler"). */
10
+ etiket?: string;
11
+ /** Etiketle aynı satırdaki değer (hücreler). */
12
+ deger: string[];
13
+ /** Etiketten sonraki satırlar. */
14
+ satirlar: Satir[];
15
+ }
16
+ /**
17
+ * Satırları etiketli bölümlere ayırır. Başlık satırı (bütün hücreleri etiket olan) bir sonraki satırla
18
+ * eşlenir: "Ders Kodu | Ders Adı | AKTS" ve altında "KRG101 | ... | 5".
19
+ */
20
+ export declare function bolumlere(satirlar: Satir[]): {
21
+ bolumler: Bolum[];
22
+ sahipsiz: Satir[];
23
+ };
24
+ /**
25
+ * Düz metin ya da HTML'den görev bölümlerini (Dersi Verenler, Koordinatör, iletişim) yetkililer listesine, kaynaklar
26
+ * bölümünü künye listesine ayırır. Değerler olduğu gibi korunur; hiçbir şey atılmaz.
27
+ */
28
+ export declare function genelAyikla(girdi: string): {
29
+ metin: string;
30
+ kaynaklar: string[];
31
+ yetkililer: {
32
+ rol: string;
33
+ deger: string;
34
+ }[];
35
+ };
36
+ export interface GenelDers {
37
+ kod?: string;
38
+ ad?: string;
39
+ yariyil: number | null;
40
+ tul?: string;
41
+ kredi: number | null;
42
+ akts: number | null;
43
+ amac?: string;
44
+ icerik?: string;
45
+ yontem?: string;
46
+ notlar?: string;
47
+ ciktilar: {
48
+ kod: string;
49
+ metin: string;
50
+ }[];
51
+ degerlendirme: {
52
+ ad: string;
53
+ sayi: number | null;
54
+ katki: number | null;
55
+ }[];
56
+ isyuku: {
57
+ ad: string;
58
+ sayi: number | null;
59
+ sure: number | null;
60
+ toplam: number | null;
61
+ }[];
62
+ dersYapisi: {
63
+ alan: string;
64
+ yuzde: number | null;
65
+ }[];
66
+ haftalar: number;
67
+ haftaKonulari: string[];
68
+ katki: Record<string, Record<string, string>>;
69
+ }
70
+ export interface GenelSonuc {
71
+ ders: GenelDers;
72
+ bilgiler: {
73
+ dil?: string;
74
+ tur?: string;
75
+ onKosul?: string;
76
+ };
77
+ bulunan: string[];
78
+ bulunamayan: string[];
79
+ guven: "yüksek" | "orta" | "düşük";
80
+ }
81
+ export declare const GENEL_ALAN_ADLARI: Record<string, string>;
82
+ /** Genel ayrıştırıcı. `kaynakSayisi` bölümü sayısı ayrıca verilir (künyeler ayıklamada ayrılır). */
83
+ export declare function genelAyristir(girdi: string, kaynakSayisi?: number): GenelSonuc;
@@ -0,0 +1,411 @@
1
+ // Proliz dışı Bologna sayfaları için genel ayrıştırıcı. HTML ya da düz metin alır; Türkçe ve İngilizce alan
2
+ // etiketlerine (Amaç/Objective, İçerik/Content, Öğrenme Çıktıları/Learning Outcomes...) göre bölümlere ayırır.
3
+ // Ağ yoktur, model yoktur: yalnız etiket eşleme ve sayı okuma. Bulunamayan alan boş kalır, tahmin edilmez.
4
+ //
5
+ // Kişi satırları (Dersi Veren, Instructor, e-posta, telefon) ayrıştırmadan önce bellekte atılır. Kaynaklar
6
+ // bölümü künye olarak ayrı alınır (yazar adları yayımlanmış künyedir).
7
+ import { metin as htmlMetni, sayi } from "../../../packages/baglayicilar/src/bologna-proliz/ayristir.js";
8
+ /** Etiketler küçük harfle, Türkçe karakterle yazılır. Uzun etiket önce denenir. */
9
+ const ETIKETLER = {
10
+ kod: ["ders kodu", "dersin kodu", "kodu", "kod", "course code", "code"],
11
+ ad: ["ders adı", "dersin adı", "adı", "course name", "course title", "name"],
12
+ yariyil: ["yarıyıl", "dönem", "semester"],
13
+ tul: ["t+u+l", "t+u+l saat", "teori+uygulama+laboratuvar", "t+p+l", "theory+practice+lab"],
14
+ kredi: ["kredi", "ulusal kredi", "yerel kredi", "credit", "credits", "local credit", "national credit"],
15
+ akts: ["akts", "akts kredisi", "ects", "ects credit", "ects credits"],
16
+ dil: ["dersin dili", "öğretim dili", "dil", "language", "language of instruction", "course language"],
17
+ tur: ["dersin türü", "ders türü", "türü", "tür", "course type", "type of course", "type"],
18
+ onKosul: ["ön koşul", "ön koşullar", "ön koşul dersleri", "önkoşul", "önkoşullar", "prerequisite", "prerequisites"],
19
+ amac: [
20
+ "dersin amacı",
21
+ "amaç",
22
+ "amacı",
23
+ "dersin amaçları",
24
+ "objective",
25
+ "objectives",
26
+ "course objective",
27
+ "course objectives",
28
+ "aim",
29
+ "aims",
30
+ ],
31
+ icerik: [
32
+ "dersin içeriği",
33
+ "içerik",
34
+ "içeriği",
35
+ "ders içeriği",
36
+ "content",
37
+ "contents",
38
+ "course content",
39
+ "course contents",
40
+ "course description",
41
+ ],
42
+ yontem: [
43
+ "yöntem ve teknikler",
44
+ "öğretim yöntem ve teknikleri",
45
+ "öğretim yöntemleri",
46
+ "yöntemler",
47
+ "yöntem",
48
+ "teaching methods",
49
+ "methods",
50
+ "learning and teaching methods",
51
+ "planned learning activities and teaching methods",
52
+ ],
53
+ notlar: ["ders notları", "course notes", "lecture notes"],
54
+ ciktilar: [
55
+ "öğrenme çıktıları",
56
+ "dersin öğrenme çıktıları",
57
+ "ders öğrenme çıktıları",
58
+ "learning outcomes",
59
+ "course learning outcomes",
60
+ ],
61
+ haftalar: [
62
+ "haftalık konular",
63
+ "haftalık ders konuları",
64
+ "haftalık ders akışı",
65
+ "haftalık ders planı",
66
+ "ders akışı",
67
+ "weekly topics",
68
+ "weekly schedule",
69
+ "course schedule",
70
+ "weekly subjects",
71
+ ],
72
+ degerlendirme: [
73
+ "değerlendirme",
74
+ "değerlendirme sistemi",
75
+ "değerlendirme yöntemleri",
76
+ "ölçme ve değerlendirme",
77
+ "assessment",
78
+ "assessment methods",
79
+ "evaluation",
80
+ "grading",
81
+ ],
82
+ isyuku: [
83
+ "akts iş yükü",
84
+ "akts iş yükü tablosu",
85
+ "iş yükü",
86
+ "ects workload",
87
+ "workload",
88
+ "ects allocated based on student workload",
89
+ ],
90
+ kaynaklar: [
91
+ "kaynaklar",
92
+ "kaynak",
93
+ "ders kitabı",
94
+ "önerilen kaynaklar",
95
+ "diğer kaynaklar",
96
+ "yardımcı kaynaklar",
97
+ "references",
98
+ "resources",
99
+ "textbook",
100
+ "textbooks",
101
+ "recommended sources",
102
+ "reading list",
103
+ ],
104
+ kisi: [
105
+ "dersi veren",
106
+ "dersi verenler",
107
+ "dersi veren öğretim elemanı",
108
+ "dersi veren öğretim elemanları",
109
+ "öğretim elemanı",
110
+ "öğretim elemanları",
111
+ "öğretim üyesi",
112
+ "dersin sorumlusu",
113
+ "dersin koordinatörü",
114
+ "dersin yardımcıları",
115
+ "dersin yetkilileri",
116
+ "koordinatör",
117
+ "sorumlu",
118
+ "iletişim",
119
+ "e-posta",
120
+ "eposta",
121
+ "telefon",
122
+ "instructor",
123
+ "instructors",
124
+ "lecturer",
125
+ "assistant",
126
+ "assistants",
127
+ "coordinator",
128
+ "course coordinator",
129
+ "contact",
130
+ "e-mail",
131
+ "email",
132
+ "phone",
133
+ ],
134
+ };
135
+ /** Türkçe küçük harf; noktasız ı da i sayılır, böylece "Instructor" ve "AMACI" aynı biçimde eşlenir. */
136
+ const kucuk = (s) => s.toLocaleLowerCase("tr").replace(/ı/gu, "i");
137
+ const sade = (s) => kucuk(s)
138
+ .replace(/[::*•\-–]+\s*$/u, "")
139
+ .replace(/\s*\(.*?\)\s*$/u, "")
140
+ .replace(/\s+/gu, " ")
141
+ .trim();
142
+ const ETIKET_TABLOSU = Object.entries(ETIKETLER)
143
+ .flatMap(([alan, xs]) => xs.map((x) => [kucuk(x), alan]))
144
+ .sort((a, b) => b[0].length - a[0].length);
145
+ /** Bir hücre ya da satır başı bir etiket mi? Tam eşleşme (sondaki iki nokta ve parantez yok sayılır). */
146
+ export function etiketAlani(s) {
147
+ const k = sade(s);
148
+ if (!k || k.length > 60)
149
+ return null;
150
+ return ETIKET_TABLOSU.find(([e]) => e === k)?.[1] ?? null;
151
+ }
152
+ /** "Etiket: değer" biçiminde satır başı etiketi. */
153
+ function onekEtiketi(s) {
154
+ const m = s.match(/^([^::]{2,60})[::]\s*(.*)$/u);
155
+ if (!m?.[1])
156
+ return null;
157
+ const alan = etiketAlani(m[1]);
158
+ return alan ? { alan, kalan: m[2] ?? "" } : null;
159
+ }
160
+ /** HTML ya da düz metni satır ve hücrelere çevirir. Tablo hücreleri sekmeyle ayrılır. */
161
+ export function satirlara(girdi) {
162
+ const htmlMi = /<\/?(table|tr|td|th|p|div|br|li|h\d|body|span)\b/iu.test(girdi);
163
+ const duz = htmlMi
164
+ ? girdi
165
+ .replace(/<(script|style)\b[\s\S]*?<\/\1>/giu, "")
166
+ .replace(/<\/t[dh]>/giu, "\u0001")
167
+ .replace(/<\/tr>|<br\s*\/?>|<\/p>|<\/li>|<\/div>|<\/h\d>|<\/table>/giu, "\n")
168
+ .split("\n")
169
+ .map((s) => s
170
+ .split("\u0001")
171
+ .map((h) => htmlMetni(h))
172
+ .join("\t"))
173
+ .join("\n")
174
+ : girdi;
175
+ return duz
176
+ .split(/\r?\n/u)
177
+ .map((s) => s
178
+ .split("\t")
179
+ .map((h) => h.replace(/\s+/gu, " ").trim())
180
+ .filter(Boolean))
181
+ .filter((r) => r.length > 0);
182
+ }
183
+ /**
184
+ * Satırları etiketli bölümlere ayırır. Başlık satırı (bütün hücreleri etiket olan) bir sonraki satırla
185
+ * eşlenir: "Ders Kodu | Ders Adı | AKTS" ve altında "KRG101 | ... | 5".
186
+ */
187
+ export function bolumlere(satirlar) {
188
+ const bolumler = [];
189
+ const sahipsiz = [];
190
+ let aktif = null;
191
+ for (let i = 0; i < satirlar.length; i++) {
192
+ const r = satirlar[i] ?? [];
193
+ const alanlar = r.map(etiketAlani);
194
+ const sonraki = satirlar[i + 1];
195
+ if (r.length >= 2 &&
196
+ alanlar.every(Boolean) &&
197
+ sonraki &&
198
+ sonraki.length === r.length &&
199
+ !sonraki.some((h) => etiketAlani(h))) {
200
+ r.forEach((_, j) => {
201
+ bolumler.push({ alan: alanlar[j], etiket: r[j] ?? "", deger: [sonraki[j] ?? ""], satirlar: [] });
202
+ });
203
+ aktif = null;
204
+ i++;
205
+ continue;
206
+ }
207
+ const ilk = r[0] ?? "";
208
+ const tam = etiketAlani(ilk);
209
+ const onek = tam ? null : onekEtiketi(ilk);
210
+ if (tam || onek) {
211
+ const deger = tam ? r.slice(1) : [onek?.kalan ?? "", ...r.slice(1)].filter(Boolean);
212
+ const etiket = tam ? ilk : ilk.slice(0, ilk.length - (onek?.kalan.length ?? 0));
213
+ aktif = { alan: (tam ?? onek?.alan), etiket, deger, satirlar: [] };
214
+ bolumler.push(aktif);
215
+ continue;
216
+ }
217
+ if (aktif)
218
+ aktif.satirlar.push(r);
219
+ else
220
+ sahipsiz.push(r);
221
+ }
222
+ return { bolumler, sahipsiz };
223
+ }
224
+ /** Kaynak satırından numara ya da imi atar. */
225
+ const maddeAt = (s) => s.replace(/^\s*(\[\d+\]|\d{1,2}[.)-]|[-•*–])\s*/u, "").trim();
226
+ /**
227
+ * Düz metin ya da HTML'den görev bölümlerini (Dersi Verenler, Koordinatör, iletişim) yetkililer listesine, kaynaklar
228
+ * bölümünü künye listesine ayırır. Değerler olduğu gibi korunur; hiçbir şey atılmaz.
229
+ */
230
+ export function genelAyikla(girdi) {
231
+ const { bolumler, sahipsiz } = bolumlere(satirlara(girdi));
232
+ const kaynaklar = [];
233
+ const yetkililer = [];
234
+ const kalan = sahipsiz.map((r) => r.join("\t"));
235
+ for (const b of bolumler) {
236
+ if (b.alan === "kisi") {
237
+ const deger = [b.deger.join(" "), ...b.satirlar.map((r) => r.join(" "))]
238
+ .map((x) => x.trim())
239
+ .filter(Boolean)
240
+ .join(", ");
241
+ const rol = (b.etiket ?? "").replace(/[:\s]+$/u, "").trim() || "Dersin yetkilileri";
242
+ if (deger)
243
+ yetkililer.push({ rol: rol.slice(0, 80), deger: deger.slice(0, 1000) });
244
+ continue;
245
+ }
246
+ if (b.alan === "kaynaklar") {
247
+ for (const x of [b.deger.join(" "), ...b.satirlar.map((r) => r.join(" "))])
248
+ for (const parca of x.split(/\s*;\s*(?=\S)/u)) {
249
+ const k = maddeAt(parca);
250
+ if (k.length >= 5)
251
+ kaynaklar.push(k);
252
+ }
253
+ continue;
254
+ }
255
+ const etiket = ETIKETLER[b.alan][0] ?? b.alan;
256
+ kalan.push([`${etiket}:`, ...b.deger].join("\t"));
257
+ for (const r of b.satirlar)
258
+ kalan.push(r.join("\t"));
259
+ }
260
+ return { metin: kalan.join("\n"), kaynaklar, yetkililer };
261
+ }
262
+ const ALAN_ADI = {
263
+ kod: "Ders kodu",
264
+ ad: "Ders adı",
265
+ tul: "T+U+L",
266
+ kredi: "Kredi",
267
+ akts: "AKTS",
268
+ dil: "Dersin dili",
269
+ tur: "Dersin türü",
270
+ onKosul: "Ön koşul",
271
+ amac: "Dersin amacı",
272
+ icerik: "Dersin içeriği",
273
+ yontem: "Yöntem ve teknikler",
274
+ notlar: "Ders notları",
275
+ ciktilar: "Öğrenme çıktıları",
276
+ haftalar: "Haftalık konular",
277
+ degerlendirme: "Değerlendirme",
278
+ isyuku: "AKTS iş yükü",
279
+ kaynaklar: "Kaynaklar",
280
+ };
281
+ export const GENEL_ALAN_ADLARI = ALAN_ADI;
282
+ const sayilar = (s) => [...s.replace(/(\d),(\d)/gu, "$1.$2").matchAll(/(?<![\p{L}\d])%?\s*(\d+(?:\.\d+)?)/gu)].map((m) => Number(m[1]));
283
+ const TOPLAM = /^(toplam|total|genel toplam|akts|ects)/iu;
284
+ const HAFTA = /^(?:(\d{1,2})\s*(?:\.|\)|-)?\s*(?:hafta|week)?|(?:hafta|week)\s*(\d{1,2}))(?![\d+])/iu;
285
+ /** Tablo satırı ("Ara Sınav | 1 | %40") ya da düz satır ("Ara Sınav 1 %40"): ad ve sayılar. */
286
+ function adVeSayilar(r) {
287
+ if (r.length > 1)
288
+ return { ad: (r[0] ?? "").trim(), n: sayilar(r.slice(1).join(" ")) };
289
+ const m = (r[0] ?? "").match(/^(.*?\p{L}[^\d%]*?)\s*[:=-]?\s+((?:%?\s*\d+(?:[.,]\d+)?\s*%?\s*[x×]?\s*)+)$/u);
290
+ return m ? { ad: (m[1] ?? "").trim(), n: sayilar(m[2] ?? "") } : { ad: (r[0] ?? "").trim(), n: [] };
291
+ }
292
+ /** Bir bölümün düz metni. */
293
+ const bolumMetni = (b) => [b.deger.join(" "), ...b.satirlar.map((r) => r.join(" "))].filter(Boolean).join("\n").trim();
294
+ /** Genel ayrıştırıcı. `kaynakSayisi` bölümü sayısı ayrıca verilir (künyeler ayıklamada ayrılır). */
295
+ export function genelAyristir(girdi, kaynakSayisi = 0) {
296
+ const satirlar = satirlara(girdi);
297
+ const { bolumler } = bolumlere(satirlar);
298
+ const ilk = (alan) => bolumler.find((b) => b.alan === alan);
299
+ const tekDeger = (alan) => {
300
+ const b = ilk(alan);
301
+ if (!b)
302
+ return undefined;
303
+ const d = (b.deger[0] ?? b.satirlar[0]?.[0] ?? "").trim();
304
+ return d || undefined;
305
+ };
306
+ const metinAlani = (alan) => {
307
+ const b = ilk(alan);
308
+ const m = b ? bolumMetni(b) : "";
309
+ return m || undefined;
310
+ };
311
+ // T+U+L: etiketten ya da metnin herhangi bir yerinden "3+0+0" kalıbı.
312
+ const tulHam = tekDeger("tul") ??
313
+ satirlar
314
+ .flat()
315
+ .join(" ")
316
+ .match(/\b\d{1,2}\s*\+\s*\d{1,2}\s*\+\s*\d{1,2}\b/u)?.[0];
317
+ const tul = tulHam?.match(/\d{1,2}\s*\+\s*\d{1,2}\s*\+\s*\d{1,2}/u)?.[0]?.replace(/\s/gu, "");
318
+ const ciktiBolumu = ilk("ciktilar");
319
+ const ciktiSatirlari = ciktiBolumu ? [ciktiBolumu.deger, ...ciktiBolumu.satirlar].filter((r) => r.length) : [];
320
+ const NUMARA = /^(?:ö|öç|döç|lo|clo)?\s*(\d{1,2})\s*[.):-]?\s*/iu;
321
+ const numarali = ciktiSatirlari.filter((r) => NUMARA.test(r[0] ?? "") && (r.length > 1 || (r[0] ?? "").replace(NUMARA, "").length > 3));
322
+ const ciktilar = (numarali.length ? numarali : ciktiSatirlari.filter((r) => /^[-•*–]/u.test(r[0] ?? "")))
323
+ .map((r) => {
324
+ const ilkHucre = r[0] ?? "";
325
+ const metin = r.length > 1 && /^(?:ö|öç|döç|lo|clo)?\s*\d{1,2}\s*[.):-]?\s*$/iu.test(ilkHucre)
326
+ ? r.slice(1).join(" ")
327
+ : maddeAt(ilkHucre.replace(NUMARA, "")) + (r.length > 1 ? ` ${r.slice(1).join(" ")}` : "");
328
+ return metin.trim();
329
+ })
330
+ .filter((m) => m.length > 3)
331
+ .map((metin, i) => ({ kod: `Ö${i + 1}`, metin }));
332
+ const haftaBolumu = ilk("haftalar");
333
+ const haftaKonulari = haftaBolumu
334
+ ? haftaBolumu.satirlar
335
+ .filter((r) => HAFTA.test(r.join(" ")) && r.join(" ").replace(HAFTA, "").trim().length > 1)
336
+ .map((r) => r
337
+ .join(" ")
338
+ .replace(HAFTA, "")
339
+ .replace(/^[\s.:)-]+/u, "")
340
+ .trim())
341
+ : [];
342
+ const satirTablosu = (alan) => {
343
+ const b = ilk(alan);
344
+ return b ? [b.deger, ...b.satirlar].filter((r) => r.length) : [];
345
+ };
346
+ const degerlendirme = satirTablosu("degerlendirme")
347
+ .map(adVeSayilar)
348
+ .filter((x) => x.ad && /\p{L}/u.test(x.ad) && x.n.length >= 1 && !TOPLAM.test(x.ad))
349
+ .map(({ ad, n }) => ({ ad, sayi: n.length >= 2 ? (n[0] ?? null) : 1, katki: n.at(-1) ?? null }));
350
+ const isyuku = satirTablosu("isyuku")
351
+ .map(adVeSayilar)
352
+ .filter((x) => x.ad && /\p{L}/u.test(x.ad) && x.n.length >= 2 && !TOPLAM.test(x.ad))
353
+ .map(({ ad, n }) => {
354
+ const s = n[0] ?? null;
355
+ const sure = n[1] ?? null;
356
+ return {
357
+ ad,
358
+ sayi: s,
359
+ sure,
360
+ toplam: n.length >= 3 ? (n[2] ?? null) : s !== null && sure !== null ? s * sure : null,
361
+ };
362
+ });
363
+ const bilgiler = {
364
+ ...(tekDeger("dil") ? { dil: tekDeger("dil") } : {}),
365
+ ...(tekDeger("tur") ? { tur: tekDeger("tur") } : {}),
366
+ ...(metinAlani("onKosul") ? { onKosul: metinAlani("onKosul") } : {}),
367
+ };
368
+ const ders = {
369
+ ...(tekDeger("kod") ? { kod: tekDeger("kod") } : {}),
370
+ ...(tekDeger("ad") ? { ad: tekDeger("ad") } : {}),
371
+ yariyil: sayi(tekDeger("yariyil")),
372
+ ...(tul ? { tul } : {}),
373
+ kredi: sayi(tekDeger("kredi")),
374
+ akts: sayi(tekDeger("akts")),
375
+ ...(metinAlani("amac") ? { amac: metinAlani("amac") } : {}),
376
+ ...(metinAlani("icerik") ? { icerik: metinAlani("icerik") } : {}),
377
+ ...(metinAlani("yontem") ? { yontem: metinAlani("yontem") } : {}),
378
+ ...(metinAlani("notlar") ? { notlar: metinAlani("notlar") } : {}),
379
+ ciktilar,
380
+ degerlendirme,
381
+ isyuku,
382
+ dersYapisi: [],
383
+ haftalar: haftaKonulari.length,
384
+ haftaKonulari,
385
+ katki: {},
386
+ };
387
+ const varMi = {
388
+ kod: Boolean(ders.kod),
389
+ ad: Boolean(ders.ad),
390
+ tul: Boolean(ders.tul),
391
+ kredi: ders.kredi !== null,
392
+ akts: ders.akts !== null,
393
+ dil: Boolean(bilgiler.dil),
394
+ tur: Boolean(bilgiler.tur),
395
+ onKosul: Boolean(bilgiler.onKosul),
396
+ amac: Boolean(ders.amac),
397
+ icerik: Boolean(ders.icerik),
398
+ yontem: Boolean(ders.yontem),
399
+ notlar: Boolean(ders.notlar),
400
+ ciktilar: ciktilar.length > 0,
401
+ haftalar: haftaKonulari.length > 0,
402
+ degerlendirme: degerlendirme.length > 0,
403
+ isyuku: isyuku.length > 0,
404
+ kaynaklar: kaynakSayisi > 0,
405
+ };
406
+ const bulunan = Object.keys(varMi).filter((k) => varMi[k]);
407
+ const bulunamayan = Object.keys(varMi).filter((k) => !varMi[k]);
408
+ const temel = ["ad", "akts", "amac", "icerik", "ciktilar", "haftalar", "degerlendirme", "isyuku"].filter((k) => varMi[k]).length;
409
+ const guven = temel >= 7 ? "yüksek" : temel >= 4 ? "orta" : "düşük";
410
+ return { ders, bilgiler, bulunan, bulunamayan, guven };
411
+ }
@@ -48,7 +48,7 @@ export class AdresKovasi {
48
48
  return { izin: true, bekle: 0 };
49
49
  }
50
50
  }
51
- /** Gövdeden günlüğe yazılacak tek bilgi: yöntem ve (tools/call ise) araç adı. İçerik okunmaz. */
51
+ /** Gövdeden günlüğe yazılacak tek bilgi: yöntem ve (tools/call ya da prompts/get ise) araç ya da istem adı. İçerik okunmaz. */
52
52
  function yontemVeArac(govde) {
53
53
  const ilk = Array.isArray(govde) ? govde[0] : govde;
54
54
  if (!ilk || typeof ilk !== "object")
@@ -58,7 +58,9 @@ function yontemVeArac(govde) {
58
58
  const ad = ilk.params?.name;
59
59
  return {
60
60
  yontem,
61
- arac: yontem === "tools/call" && typeof ad === "string" ? ad.replace(/[^a-z_]/gu, "").slice(0, 40) : null,
61
+ arac: (yontem === "tools/call" || yontem === "prompts/get") && typeof ad === "string"
62
+ ? ad.replace(/[^a-z_]/gu, "").slice(0, 40)
63
+ : null,
62
64
  };
63
65
  }
64
66
  export function acikMcpIsleyici(s = {}) {
@@ -1,4 +1,10 @@
1
1
  export * from "./araclar.ts";
2
+ export * from "./bologna.ts";
3
+ export * from "./genel-ayristir.ts";
2
4
  export * from "./http.ts";
5
+ export * from "./kaynak.ts";
3
6
  export * from "./kisisel-veri.ts";
7
+ export * from "./not-tablosu.ts";
8
+ export * from "./promptlar.ts";
4
9
  export * from "./sunucu.ts";
10
+ export * from "./yardim.ts";
@@ -1,6 +1,12 @@
1
1
  // @akredit/acik-mcp: herkese açık, hesapsız, salt okuma MCP sunucusu (İP-49).
2
2
  // Kapsam: plan/ip/IP-49-acik-mcp.md
3
3
  export * from "./araclar.js";
4
+ export * from "./bologna.js";
5
+ export * from "./genel-ayristir.js";
4
6
  export * from "./http.js";
7
+ export * from "./kaynak.js";
5
8
  export * from "./kisisel-veri.js";
9
+ export * from "./not-tablosu.js";
10
+ export * from "./promptlar.js";
6
11
  export * from "./sunucu.js";
12
+ export * from "./yardim.js";
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ export declare const IZINLI_HOSTLAR: readonly ["api.crossref.org", "openlibrary.org", "www.googleapis.com"];
3
+ export declare const ZAMAN_ASIMI_MS = 8000;
4
+ export declare const EN_BUYUK_YANIT = 1000000;
5
+ /** "https://doi.org/10.x/y", "doi:10.x/y" ya da "10.x/y" → "10.x/y". Geçersizse null. */
6
+ export declare function doiTemizle(d: string): string | null;
7
+ /** ISBN-10 ya da ISBN-13; tire ve boşluk atılır, denetim basamağı sınanır. Geçersizse null. */
8
+ export declare function isbnTemizle(i: string): string | null;
9
+ /** Karşılaştırma için sadeleştirme: küçük harf, Türkçe harfler düz, noktalama yok. */
10
+ export declare function sadele(s: string): string[];
11
+ /** Sorgu başlığının sözcüklerinin en az %80'i bulunan başlıkta var mı, ve bulunanın en az %60'ı sorguda var mı. */
12
+ export declare function baslikEslesir(sorgu: string, bulunan: string): boolean;
13
+ /** Sorgudaki yazar soyadı (son sözcük ya da virgülden önceki kısım) bulunan yazarlardan birinde geçiyor mu. */
14
+ export declare function yazarEslesir(sorgu: string, yazarlar: string[]): boolean;
15
+ export interface Dogrulanmis {
16
+ durum: "dogrulandi";
17
+ kunye: string;
18
+ eksikler: string[];
19
+ baglanti: string;
20
+ katalog: "Crossref" | "Open Library" | "Google Books";
21
+ baslik: string;
22
+ yazarlar: string[];
23
+ yil?: number | string;
24
+ }
25
+ export interface Dogrulanamadi {
26
+ durum: "dogrulanamadi";
27
+ neden: string;
28
+ }
29
+ export type DogrulamaSonucu = Dogrulanmis | Dogrulanamadi;
30
+ declare const KaynakSorgusu: z.ZodObject<{
31
+ doi: z.ZodOptional<z.ZodString>;
32
+ isbn: z.ZodOptional<z.ZodString>;
33
+ baslik: z.ZodOptional<z.ZodString>;
34
+ yazar: z.ZodOptional<z.ZodString>;
35
+ }, z.core.$strip>;
36
+ type KaynakSorgusuT = z.infer<typeof KaynakSorgusu>;
37
+ /** Tek kaynağı doğrular. DOI önce, sonra ISBN, sonra başlık+yazar. */
38
+ export declare function kaynakDogrula(f: typeof fetch, k: KaynakSorgusuT): Promise<DogrulamaSonucu>;
39
+ export declare const kaynakDogrulaAraci: import("./temel.ts").AcikArac<z.ZodObject<{
40
+ kaynaklar: z.ZodArray<z.ZodObject<{
41
+ doi: z.ZodOptional<z.ZodString>;
42
+ isbn: z.ZodOptional<z.ZodString>;
43
+ baslik: z.ZodOptional<z.ZodString>;
44
+ yazar: z.ZodOptional<z.ZodString>;
45
+ }, z.core.$strip>>;
46
+ }, z.core.$strip>>;
47
+ export {};