@akredit/acik-mcp 0.4.0 → 0.6.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.
@@ -12,6 +12,8 @@ export declare const GIRIS_BILGISI_KURALI: string;
12
12
  /** Akıllı doldurma kısayolu: bütün menülerde aynı numara ve aynı anlam. */
13
13
  export declare const AKILLI_DOLDURMA_SECENEGI = "4) Hepsini ak\u0131ll\u0131ca doldur (\u00F6nerilen)";
14
14
  /** "4) Hepsini akıllıca doldur" seçildiğinde (ya da hoca "sen seç", "hepsi" derse) izlenecek yol. */
15
+ /** Bilinmesi mümkün olmayan ve resmî taahhüt olan bilgiler: sayfadan okunur, yoksa tek mesajda sorulur. */
16
+ export declare const TEYIT_SORULARI: string;
15
17
  export declare const AKILLI_DOLDURMA: string;
16
18
  /** Bütün istemlerde ortak çalışma biçimi. */
17
19
  export declare const ORTAK_KURALLAR: string;
@@ -21,5 +23,47 @@ export declare const AKREDIT_ODAKLARI: readonly {
21
23
  ad: string;
22
24
  }[];
23
25
  export declare const ACIK_ISTEMLER: readonly AcikIstem[];
26
+ /** Kısa kurallar: akredit_basla yanıtında (istem desteklemeyen istemciler için) yer alır. */
27
+ export declare const KISA_KURALLAR: string[];
28
+ /** akredit_basla aracının yanıtı: menü, kısa kurallar ve her seçimin akışı (istem desteklemeyen istemciler için). */
29
+ export declare function baslangic(): {
30
+ hocayaGoster: string;
31
+ menu: ({
32
+ no: "1" | "2" | "3" | "4" | "5";
33
+ ad: "Bologna ders paketini denetle ve boş alanları doldur" | "Ders öğrenme çıktısı yaz ya da iyileştir" | "ÇK ve PÇ sağlanma düzeyini hesapla" | "YÖKAK, MÜDEK, FEDEK, EPDAD ya da SABAK ölçüt ve kanıt rehberi" | "Öz değerlendirme metninin dil denetimi";
34
+ istem: "bologna_doldur" | "cikti_yaz" | "ck_pc_hesabi" | "olcut_rehberi" | "dil_denetimi";
35
+ } | {
36
+ no: string;
37
+ ad: string;
38
+ istem: null;
39
+ })[];
40
+ kisaKurallar: string[];
41
+ akislar: {
42
+ [k: string]: string;
43
+ };
44
+ ortakKurallar: string;
45
+ };
46
+ /** Kullanıcı niyetini zaten yazdıysa menü atlanır; yalnız o odağın akışı ve kurallar döner. */
47
+ export declare function odakBaslangici(no: string): {
48
+ hocayaGoster: string;
49
+ odak: {
50
+ no: "1" | "2" | "3" | "4" | "5";
51
+ ad: "Bologna ders paketini denetle ve boş alanları doldur" | "Ders öğrenme çıktısı yaz ya da iyileştir" | "ÇK ve PÇ sağlanma düzeyini hesapla" | "YÖKAK, MÜDEK, FEDEK, EPDAD ya da SABAK ölçüt ve kanıt rehberi" | "Öz değerlendirme metninin dil denetimi";
52
+ istem: "bologna_doldur" | "cikti_yaz" | "ck_pc_hesabi" | "olcut_rehberi" | "dil_denetimi";
53
+ } | null;
54
+ kisaKurallar: string[];
55
+ akis: string;
56
+ ortakKurallar: string;
57
+ };
58
+ export declare const akreditBaslaAraci: import("./temel.ts").AcikArac<z.ZodObject<{
59
+ odak: z.ZodDefault<z.ZodEnum<{
60
+ 1: "1";
61
+ 2: "2";
62
+ 3: "3";
63
+ 4: "4";
64
+ 5: "5";
65
+ menu: "menu";
66
+ }>>;
67
+ }, z.core.$strip>>;
24
68
  /** SDK için bağımsız değişken şeması: hepsi isteğe bağlı, kısa metin. */
25
69
  export declare const istemSemasi: (i: AcikIstem) => Record<string, z.ZodOptional<z.ZodString>>;
@@ -4,10 +4,17 @@
4
4
  // geçmeyeni düzeltip yeniden denetler, sonunda tek bir özet gösterir. Hoca isterse numarayla düzeltir.
5
5
  // Halüsinasyona yer yok: kitap, kişi, tarih, sayı uydurulmaz; kaynaklar kaynak_dogrula'dan geçmeden önerilmez.
6
6
  //
7
+ // Dış inceleme 2026-11-05: akıllı doldurma kalır, ama bilinmesi mümkün olmayan ve resmî taahhüt olan bilgiler
8
+ // (değerlendirme yöntemi ve yüzdeleri, uygulama/lab, kullanılan kaynaklar, sayfada yoksa amaç ve içerik) sayfadan
9
+ // okunur; yoksa asistan bunları TEK mesajda, numaralı ve varsayılan seçenekli sorar, uydurmaz. Ders adından
10
+ // üretilen her şey "öneri" etiketiyle gösterilir. OBS'ye yazmadan önce alan alan önceki/yeni değer özeti gösterilir,
11
+ // hoca bir kez "kaydet" der; kayıttan sonra sayfa geri okunur ve obs_karsilastir ile doğrulanır.
12
+ //
7
13
  // İstem metni veri değil asistana yönergedir; içinde hocanın girdisi yalnız isteğe bağlı kısa bağımsız
8
14
  // değişkenler olarak yer alır (ders kodu, çerçeve) ve sınırlanır. Giriş bilgisi (parola, doğrulama kodu,
9
- // çerez) asistana asla verilmez (ilke 8).
15
+ // çerez) istenmez; görülürse reddedilir ve kaydedilmez (ilke 8).
10
16
  import { z } from "zod";
17
+ import { arac, KOD_KAYNAGI } from "./temel.js";
11
18
  import { GIRIS_KURALI_HOCAYA } from "./yardim.js";
12
19
  /** Giriş bilgisi kuralı: bütün istemlerde aynen yer alır. */
13
20
  export const GIRIS_BILGISI_KURALI = [
@@ -16,19 +23,36 @@ export const GIRIS_BILGISI_KURALI = [
16
23
  "- Hoca bunları kendisi yalnız OBS'nin kendi giriş ekranına yazar. Bunu hocaya ilk adımda açıkça söyle.",
17
24
  "- Hoca yine de sohbete parola yazarsa kullanma, hiçbir araca gönderme; silmesini ve OBS'de parolasını değiştirmesini öner.",
18
25
  "- CAPTCHA'yı sen çözmezsin, hoca çözer.",
19
- '- OBS\'de Kaydet düğmesine yalnız hocanın açık izniyle basarsın (ya o sekme için "evet", ya bir kez verilen "hepsini kaydet" izni). İzin yoksa basmazsın. Onaya ya da dış kuruma Gönder düğmesine hiç basmazsın; onu hoca basar.',
26
+ '- OBS\'de Kaydet düğmesine yalnız hocanın açık izniyle basarsın: önce alan alan önceki ve yeni değer özetini gösterirsin, hoca bir kez "kaydet" der. İzin yoksa basmazsın. Onaya ya da dış kuruma Gönder düğmesine hiç basmazsın; onu hoca basar.',
20
27
  ].join("\n");
21
28
  /** Akıllı doldurma kısayolu: bütün menülerde aynı numara ve aynı anlam. */
22
29
  export const AKILLI_DOLDURMA_SECENEGI = "4) Hepsini akıllıca doldur (önerilen)";
23
30
  /** "4) Hepsini akıllıca doldur" seçildiğinde (ya da hoca "sen seç", "hepsi" derse) izlenecek yol. */
31
+ /** Bilinmesi mümkün olmayan ve resmî taahhüt olan bilgiler: sayfadan okunur, yoksa tek mesajda sorulur. */
32
+ export const TEYIT_SORULARI = [
33
+ "Teyit gerektiren bilgiler (asla tahmin etme):",
34
+ "- Değerlendirme yöntemleri ve yüzdeleri (vize, final, ödev, proje...).",
35
+ "- Derste gerçekten kullanılan kaynaklar ve ders notları.",
36
+ "Bunları önce sayfadan oku; sayfada doluysa SORMA. Uygulama/lab sorulmaz: T+U+L'den okunur (U+L > 0 ise var). Amaç ve içerik sayfada yoksa önden sorulmaz; 'öneri' olarak yazılıp son özette teyide sunulur.",
37
+ "Sayfada olmayan değerlendirme ve kaynakları hocaya TEK mesajda sor. Değerlendirme yüzdesine varsayılan uydurma; hoca yazar. Örnek:",
38
+ ' "İki bilgiyi yalnız siz bilebilirsiniz:',
39
+ " 1) Değerlendirme yöntemleri ve yüzdeleri: yazın (ör. Vize 40, Final 60)",
40
+ ' 2) Kaynaklar: a) katalogdan doğrulayıp önereyim (önerilen) b) şunları kullanıyorum: yazın"',
41
+ "Yanıt gelmeden değerlendirme yüzdesi yazma paketine girmez (degerlendirmeDayanagi: 'hoca').",
42
+ ].join("\n");
24
43
  export const AKILLI_DOLDURMA = [
25
44
  "Hepsini akıllıca doldur (seçenek 4):",
26
- "- Kalan her alan için seçeneklerini kendin yaz ve en iyisini kendin seç. Hocaya ara soru sorma.",
45
+ "- Önce teyit gerektiren bilgileri sayfadan oku; sayfada olmayanları hocaya TEK mesajda birlikte sor (aşağıdaki kural). Bundan sonra ara soru sorma.",
46
+ "- Kalan her alan için seçeneklerini kendin yaz ve en iyisini kendin seç. Ders adından ve program çıktılarından ürettiğin her şeyi 'öneri' etiketiyle göster.",
27
47
  "- Her seçimi ilgili araçla denetle (bologna_taslak_denetle, bologna_durum, rapor_dil_denetle). Geçmeyeni düzelt ve yeniden denetle; geçene kadar hocaya gösterme. Üç denemede geçmezse o alanı EKSİK bırak.",
28
48
  "- Sayıları (toplam, yüzde, iş yükü, sağlanma düzeyi) yalnız araç yanıtından al.",
29
49
  "- Uydurma yok: hocanın vermediği ve doğrulayamadığın bilgi (kişi, kitap, tarih, sayı, toplantı) EKSİK kalır. Kaynaklar yalnız kaynak_dogrula'dan 'dogrulandi' dönenlerdir.",
30
- "- Bitince tek bir özet göster: numara, alan, ne yazdığın (ilk cümle ya da kısa özet), denetim sonucu. Altına şunu yaz:",
31
- ' "Şu alanları şöyle doldurdum. Değiştirmek istediğiniz alanın numarasını yazın; yoksa devam diyebilirsiniz. Bunları daha sonra da kolayca güncelleyebilirsiniz."',
50
+ "- Araç sonucunu 'geçer' diye sunma: 'biçim denetiminden geçti; içerik teyidi: hoca' de.",
51
+ "- Bitince tek bir özet göster: numara, alan, ne yazdığın (ilk cümle ya da kısa özet), kaynağı (sayfa, hoca ya da öneri), biçim denetimi sonucu. Altına şunu yaz:",
52
+ "- Ara özet gösterip 'devam' bekleme: OBS'ye yazılacaksa özet, yazma onayıyla aynı mesajdadır (OBS'ye yazma adımı). Özetin altına yaz:",
53
+ " \"Öneri yazanlar benim önerimdir, içeriği siz teyit edersiniz. 1) OBS'ye yaz ve kaydet 2) formu doldur, Kaydet'e ben basayım 3) kopya metni ver. Değiştirmek istediğiniz alan varsa numarasını yazın.\"",
54
+ "",
55
+ TEYIT_SORULARI,
32
56
  ].join("\n");
33
57
  /** Bütün istemlerde ortak çalışma biçimi. */
34
58
  export const ORTAK_KURALLAR = [
@@ -41,9 +65,9 @@ export const ORTAK_KURALLAR = [
41
65
  "- Sunucu metin üretmez. Seçenek metinlerini sen yazarsın; sunucu kural verir, denetler ve sayıları hesaplar.",
42
66
  "- Sayıları (toplam, yüzde, iş yükü, sağlanma düzeyi) yalnız araç yanıtından al, kendin toplama.",
43
67
  "- Uydurma yok: kişi, kitap, ISBN, DOI, tarih, toplantı, sayı uydurma. Bilinmeyen bilgi EKSİK kalır.",
44
- "- Kaynak önerirken: hocaya kitabın adını sorma. Ders içeriğine uygun kaynakları kendi web arama aracınla bul, her birini kaynak_dogrula ile doğrula ve yalnız 'dogrulandi' dönenleri künyesi ve bağlantısıyla göster. Doğrulanamayan kaynağı asla önerme.",
68
+ "- Kaynak: önce sayfadaki ve hocanın kullandığı kaynakları al. Öneri gerekiyorsa kendi web arama aracınla aday bul, her birini kaynak_dogrula ile sorgula ve yalnız 'katalogda_bulundu' dönenleri künyesi ve bağlantısıyla 'öneri' olarak göster; uygunluğuna hoca karar verir. Katalogda bulunmayan kaynağı kendin önerme; hoca kullandığını söylerse 'hoca_beyani' olarak yaz.",
45
69
  "- Bologna sayfasındaki Dersi Verenler, Yardımcılar ve Koordinatör satırları hocanın yayımlanmış görev bilgisidir: olduğu gibi oku, koru, değiştirme.",
46
- "- Öğrenci adı ve numarası içeren not tablolarında öğrencilere o1, o2 gibi takma ad verilir (not tablosu aracı bunu kendisi yapar).",
70
+ "- Öğrenci adı ya da numarası sohbete yapıştırılmaz: hoca Excel'de Ad, Soyad, Numara sütunlarını silip yalnız not sütunlarını yapıştırır ya da https://akredit.org/deneyin hesaplayıcısını kullanır. Not tablosu aracı kimlik sütunu görürse tabloyu işlemez.",
47
71
  "- Engel çıkarsa (tarayıcı aracı yok, site açılmıyor, giriş ekranı, CAPTCHA, çerçeve, oturum düştü) engel_coz ile adımları al ve hocaya tek tek göster.",
48
72
  "- Her araç yanıtındaki sonrakiAdim önerisine uy.",
49
73
  "- Sonunda kopyalanabilir bir çıktı ver. Onaya ya da dış kuruma gönderimi hoca yapar.",
@@ -72,33 +96,41 @@ const obsGirisi = () => [
72
96
  "Adım 0. OBS'ye giriş (tarayıcı).",
73
97
  ` Hocaya önce şunu aynen söyle: "${GIRIS_KURALI_HOCAYA}"`,
74
98
  " Tarayıcı aracın varsa (Claude in Chrome, Claude masaüstü tarayıcı paneli, ChatGPT ajan modu gibi):",
75
- " a) Hocaya OBS ya da Bologna sisteminin adresini sor (kurumun sitesindeki bağlantı). Adresi kenardaki tarayıcıda aç.",
99
+ " a) İLK İŞ: tarayıcıda açık sekmelere bak. Açık bir OBS ya da Bologna sayfası varsa adres ve giriş sorma, doğrudan d) adımına geç. Yoksa hocaya yalnız şunu sor: \"OBS'nizin adresini yazın (bilmiyorsanız üniversitenizin adını yazın).\" Ders adını ya da paketi sorma; onları OBS'den okuyacaksın. Adres gelince hemen tarayıcıda aç. Üniversite adı gelirse kurumun OBS ya da Bologna sayfasını web aramasıyla bul ve aç.",
76
100
  ' b) Giriş ekranı gelince dur ve şunu yaz: "Kullanıcı adınızı ve parolanızı şimdi açılan OBS ekranına kendiniz yazın. Bitince bana yalnız girdim yazın."',
77
101
  " c) CAPTCHA ya da doğrulama kodu gelirse hocanın kendisinin girmesini bekle; sen girme.",
78
- " d) Hoca girdim deyince ders listesini oku ve numaralı göster. Sor: hangi ders? Hoca numara yazar.",
102
+ " d) Hoca girdim deyince hangi dersi incelemek istediğini SORMA. Önce kendin tara: listedeki her dersin Bologna sayfasını sırayla aç, bologna_ayristir ve bologna_durum ile eksik ve kurala uymayan alanları say (en çok 15 ders; fazlası varsa ilk 15'i tara ve kaç ders kaldığını söyle).",
103
+ " Sonra tek mesajda kısa bir özet ver: her ders için bir satır, eksik alan sayısı (en eksikten en tamama). Aynı mesajda, eksik derslerin sayfasında olmayan değerlendirme yüzdelerini ve kaynakları da sor (Adım 3; ayrı tur açma). Altına numaralı seçenekler koy:",
104
+ " 1) Eksikleri en çok olandan başlayarak hepsini sırayla kapatalım (önerilen)",
105
+ " 2) Yalnız en eksik dersi tamamlayalım",
106
+ " 3) Dersi ben seçeyim",
107
+ " Hiç eksik yoksa bunu söyle ve dil ile kaynak denetimini öner. Hoca yalnız numara yazar.",
79
108
  " e) Dersin Bologna (ders bilgi paketi) sayfasını oku. Okuduğun metni ya da HTML'i bologna_ayristir'e ver.",
80
- " Tarayıcı aracın yoksa: hocaya sor: 1) kurulumu birlikte yapalım (önerilen) 2) sayfayı kopyalayıp yapıştırayım 3) sıfırdan başlayalım.",
81
- " 1 seçilirse kurulum_yardimi'nı hocanın asistanıyla (istemci) çağır, adımları tek tek göster.",
82
- ' 2 seçilirse şunu yaz: "OBS\'de dersinizin Bologna sayfasını açın. Sayfada Ctrl+A ile hepsini seçin, Ctrl+C ile kopyalayın, buraya Ctrl+V ile yapıştırın."',
109
+ ' Tarayıcı aracın yoksa sormadan şunu yaz: "OBS\'de dersinizin Bologna sayfasını açın, Ctrl+A ile seçip Ctrl+C ile kopyalayın ve buraya yapıştırın. Tarayıcı kurulumunu birlikte yapmak isterseniz 1 yazın." 1 gelirse aşağıdaki kurulum adımını izle.',
110
+ " 1 gelirse kurulum_yardimi'nı hocanın asistanıyla (istemci) çağır, adımları tek tek göster.",
83
111
  " Herhangi bir engelde engel_coz'u ilgili engel türüyle çağır.",
84
112
  ].join("\n");
85
- /** Kaynak bulma: hocaya sormadan, web aramasıyla, kaynak_dogrula'dan geçirerek. */
113
+ /** Kaynak: önce sayfadaki ve hocanın kullandığı; öneri yalnız katalogda bulunan, "öneri" etiketiyle. */
86
114
  const KAYNAK_ADIMI = [
87
- " Kaynaklar: hocaya kitabın adını sorma. Ders adı, içerik ve haftalık konulara göre kendi web arama aracınla 4-6 aday eser bul (ders kitabı, temel makale).",
88
- " Her adayı DOI, ISBN ya da başlık ile yazar olarak kaynak_dogrula'ya ver. Yalnız 'dogrulandi' dönenleri kullan; künyeyi aracın verdiği gibi yaz, bağlantısıyla birlikte göster.",
89
- " Doğrulanamayan adayı asla önerme, künyesini yazma. Web arama aracın yoksa bunu hocaya söyle; hoca bir eser adı verirse onu da kaynak_dogrula'dan geçir, geçmezse kaynaklar alanı EKSİK kalır.",
115
+ " Kaynaklar: önce sayfadaki kaynakları al; derste kullanılan kaynakları teyit sorularıyla birlikte (tek mesajda) sor.",
116
+ " Öneri gerekiyorsa kendi web arama aracınla 4-6 aday eser bul; her adayı DOI, ISBN ya da başlık, yazar, tür ve biliniyorsa yılla kaynak_dogrula'ya ver (çağrı başına en çok 5).",
117
+ " Yalnız 'katalogda_bulundu' dönenleri 'öneri' etiketiyle, künyesi ve bağlantısıyla göster; uygunluğuna hoca karar verir. Bologna araçlarına kaynağı { kunye, dogrulama: { durum, baglanti, imza } } olarak aynen ver.",
118
+ " Katalogda bulunmayan eseri kendin önerme. Hoca bir eseri kullandığını söylerse (çoğu Türkçe kitap katalogda yoktur) künyeyi yalnız hocanın verdiği bilgiyle yaz ve dogrulama: 'hoca_beyani' ver; eksik alanı uydurma, EKSİK bırak.",
90
119
  ].join("\n");
91
- /** OBS'ye yazma menüsü: tarayıcı aracı yoksa 3'e düşer. */
120
+ /** OBS'ye yazma: önce önceki/yeni özeti, tek "kaydet", sonra geri okuma ve obs_karsilastir. */
92
121
  const OBS_YAZMA = [
93
- "6. OBS'ye yazma. Tarayıcı aracın yoksa doğrudan 3'ü uygula. Varsa sor:",
94
- " 1) Formu ben doldurayım, Kaydet'e siz basın",
95
- " 2) Formu ben doldurup kaydedeyim (her sekmeden önce kısa özet gösterip evet isterim)",
96
- " 3) Alan alan kopyalayın",
97
- ` ${AKILLI_DOLDURMA_SECENEGI.replace("doldur", "doldur ve kaydet")}: bütün sekmeleri doldurup kaydederim; başlamadan bir kez "hepsini kaydet" izninizi alırım, sonunda tek özet gösteririm.`,
98
- " 1: OBS düzenleme ekranında sekme sekme ilgili kutulara yaz. Her sekmeden sonra dur ve hocadan gözle denetleyip Kaydet'e basmasını iste.",
99
- ' 2: Her sekmeyi doldur, kaydetmeden önce o sekmede ne yazdığını kısa özetle ve "Kaydedeyim mi? evet / hayır" diye sor. Yalnız "evet" gelirse Kaydet\'e bas.',
100
- ' 4: Önce şunu sor: "Bütün sekmeleri doldurup kaydetmem için izin veriyor musunuz? hepsini kaydet / hayır". Yalnız "hepsini kaydet" gelirse sekme sekme doldur ve kaydet; sonunda neyi nereye yazdığını tek özetle göster.',
101
- " 3: bologna_kopya_metni ile metni al; her alanı ayrı kod bloğunda ver, hangi sekmedeki hangi kutuya yapıştırılacağını yaz.",
122
+ "6. OBS'ye yazma.",
123
+ " Önce bologna_kopya_metni'ni çağır (OBS'deki şimdiki değerleri oncekiDegerler olarak ver). Yazma paketine alınmayanları (doğrulanmamış kaynak, teyitsiz değerlendirme yüzdesi) hocaya söyle; onları yazma.",
124
+ " Ara özet gösterip 'devam' bekleme. TEK mesajda degisiklikOzeti'ni göster (numara, sekme, alan, önceki değer, yeni değer, kaynağı: sayfa, hoca ya da öneri; toplu modda bütün dersler tek tabloda) ve altına sor:",
125
+ " 1) OBS'ye yaz ve kaydet (bu seçim, yukarıdaki özete 'kaydet' onayıdır)",
126
+ " 2) Formu doldur, Kaydet'e ben basayım",
127
+ " 3) Alan alan kopya metni ver",
128
+ " Değiştirmek istediğiniz alan varsa numarasını yazın.",
129
+ " Tarayıcı aracın yoksa yalnız 3'ü sun.",
130
+ " 1: Yalnız hoca 1 ya da 'kaydet' yazdıysa, yalnız özetteki alanları yaz ve kaydet. Her sekmeden önce ders kodunu ve dönemi sayfada denetle; beklenenden farklıysa yazmayı durdur ve hocaya söyle.",
131
+ " 2: OBS düzenleme ekranında sekme sekme ilgili kutulara yaz. Her sekmeden sonra dur ve hocadan gözle denetleyip Kaydet'e basmasını iste.",
132
+ " 3: bologna_kopya_metni metnini her alan ayrı kod bloğunda ver, hangi sekmedeki hangi kutuya yapıştırılacağını yaz.",
133
+ " Kayıttan sonra (1 ve 2): sayfayı geri oku, obs_karsilastir'e obsKarsilastirGirdisi'ni ve okuduğun metni ver. dur true ise yazmayı bırak, nedenini söyle. Farklı alanları hocaya göster.",
102
134
  " Her durumda: Dersin Yetkilileri satırlarına dokunma, OBS'deki hâliyle kalsın. Parolayı asla isteme; o yalnız hocadadır. Onaya gönderme (Gönder) düğmesine sen basma.",
103
135
  ].join("\n");
104
136
  const bolognaAkisi = (dersKodu) => [
@@ -106,58 +138,54 @@ const bolognaAkisi = (dersKodu) => [
106
138
  "",
107
139
  "Akış:",
108
140
  obsGirisi(),
109
- "1. Ayrıştır. bologna_ayristir önce Proliz biçimini, olmazsa genel ayrıştırıcıyı dener. Bulunamayan alanları not al.",
141
+ "1. Ayrıştır. bologna_ayristir önce Proliz biçimini, olmazsa genel ayrıştırıcıyı dener (sekmeli düz metin de olur). Bulunamayan alanları ve ingilizce değerini not al; sonraki araçlara ingilizce değerini aynen ver.",
110
142
  " Dersi Verenler, Yardımcılar ve Koordinatör satırları yetkililer alanında olduğu gibi gelir; onları değiştirme, sonraki çağrılarda aynen geri ver.",
111
143
  " Program çıktıları sayfası da varsa onu da ayrıştır ve P kodlarını sakla; P kodlarını asla ezberden yazma.",
112
- "2. Denetle. bologna_denetle'yi çağır. Sonucu tek tabloda göster: numara, alan, durum (boş, zayıf, tamam), kısa neden. Kalan alan sayısını söyle.",
113
- ` Sor: 1) alan alan seçenek göstererek dolduralım 2) yalnız boş olanlar 3) numaraları kendim seçeyim ${AKILLI_DOLDURMA_SECENEGI}.`,
114
- "3. Bağlam. Amaç ya da içerik yoksa dersin odağını ders adından ve program çıktılarından çıkar. Akıllı doldurmada sorma; 1-3 seçildiyse tek soru sor: 1) [1. öneri] 2) [2. öneri] 3) kendim yazayım.",
115
- "4. Her alan için: bologna_alan_rehberi'ni çağır. Kurala uyan 2-3 kısa seçenek yaz.",
116
- " Seçenekleri bologna_taslak_denetle ile denetle; geçmeyeni düzelt ve yeniden denetle, yalnız geçenleri kullan. Uzun metinlerde ilk cümleyi ve kelime sayısını göster.",
144
+ "2. Denetle. bologna_denetle'yi çağır. Nasıl doldurulacağını SORMA: varsayılan her zaman akıllı doldurmadır.",
145
+ "3. Teyit. Yalnız sayfada olmayan değerlendirme yüzdeleri ve kaynaklar için hocaya TEK mesaj (toplu modda bütün dersler için tek mesaj). Uygulama/lab T+U+L'den okunur. Uydurma.",
146
+ " Amaç ve içerik için hocanın verdiği kısa odak yoksa ders adından ve program çıktılarından 'öneri' yaz ve öneri olduğunu söyle.",
147
+ "4. bologna_alan_rehberi'ni alan='hepsi' ile bir kez çağır, bütün alanları tek seferde yaz.",
148
+ " Seçenekleri bologna_taslak_denetle ile denetle; biçim denetiminden geçmeyeni düzelt ve yeniden denetle. Uzun metinlerde ilk cümleyi ve kelime sayısını göster. Sonucu 'biçim denetiminden geçti; içerik teyidi: hoca' diye sun.",
117
149
  " Akıllı doldurmada (4) en iyi seçeneği kendin seç ve hocaya alan alan sorma; sonunda tek özet göster.",
118
- " Haftalık konular: 14 hafta, ara sınav ve yarıyıl sonu haftası görünür. Değerlendirme: yüzdeler toplamı 100.",
119
- " AKTS iş yükü: is_yuku_oner'i çağır; üç dağılımın toplamı hedefe tam eşittir. AKTS'yi değiştirme.",
150
+ " Haftalık konular: 14 hafta, ara sınav ve yarıyıl sonu haftası görünür. Değerlendirme: yalnız sayfadan ya da hocadan; degerlendirmeDayanagi'ni ('sayfa' ya da 'hoca') ver.",
151
+ " AKTS iş yükü: is_yuku_oner'i sayfadaki değerlendirme kalemleriyle çağır; derste olmayan etkinliğe satır açılmaz. Sayfadan okunan iş yüküyle öneriyi ayrı göster. AKTS'yi değiştirme.",
120
152
  " Öğrenme çıktısı ile program çıktısı katkı tablosu: yalnız ayrıştırılan P kodlarıyla öner.",
121
153
  KAYNAK_ADIMI,
122
- '5. Her alandan sonra bologna_durum\'u çağır. Alan alan ilerliyorsan kalan alan sayısını tek cümleyle söyle: "Kalan 3 alan."',
154
+ "5. Hepsini yazınca bologna_durum'u çağır; geçmeyeni düzelt. Ara adımda hocaya rapor verme.",
123
155
  OBS_YAZMA,
124
- '7. Tamamlandı denetimi. Kayıttan sonra sayfayı yeniden oku (tarayıcı varsa) ya da yeniden yapıştırmasını iste; bologna_ayristir ve bologna_denetle ile denetle. Eksik yoksa "Tamamlandı" de.',
125
- " Sor: 1) başka ders 2) bir alanı değiştir 3) bitir.",
156
+ '7. Doğrulama. Kayıttan sonra sayfayı yeniden oku (tarayıcı varsa) ya da yeniden yapıştırmasını iste; obs_karsilastir ve bologna_denetle ile denetle. Fark yoksa "Kaydedildi ve geri okunarak doğrulandı; içerik teyidi sizde" de.',
157
+ " Toplu modda sormadan sıradaki derse geç. Tek derste kısa bir sonuç cümlesiyle bitir.",
126
158
  ].join("\n");
127
159
  const ciktiAkisi = (dersKodu) => [
128
160
  `Odak: ders öğrenme çıktısı yaz ya da iyileştir.${dersKodu ? ` Ders: ${dersKodu}.` : ""}`,
129
161
  "",
130
162
  "Akış:",
131
163
  "1. Sor: 1) OBS'deki mevcut çıktılarımı okuyalım (tarayıcı aracın varsa OBS girişi için Bologna akışındaki Adım 0'ı izle) 2) çıktılarımı yapıştırayım 3) sıfırdan yaz: ders adı, AKTS, T+U+L ve kısa içerik vereyim.",
132
- "2. bologna_alan_rehberi'ni alan=ciktilar ile çağır: kurallar, Bloom fiilleri, 8-12 sınırı.",
133
- `3. Sor: 1) her çıktı için seçenek göstereyim 2) yalnız zayıf olanları iyileştireyim 3) numaraları kendim seçeyim ${AKILLI_DOLDURMA_SECENEGI}.`,
134
- " 1-3: her çıktı için 2-3 seçenek yaz (farklı Bloom düzeyi ya da ölçme biçimi), türünü (Bilgi, Beceri, Yetkinlik) yaz.",
135
- " 4: her çıktı için en iyi ifadeyi kendin seç; hocaya ara soru sorma.",
164
+ "2. bologna_alan_rehberi'ni alan=ciktilar ile çağır: kurallar, Bloom fiilleri, 4-10 sınırı (5-8 önerilir).",
165
+ "3. Nasıl yazılacağını SORMA: 5-8 ölçülebilir çıktıyı kendin yaz, türünü (Bilgi, Beceri, Yetkinlik) belirt; hocaya ara soru sorma.",
136
166
  "4. Bütün listeyi bologna_taslak_denetle ile denetle (ciktilar alanı; İngilizce isteniyorsa en alanıyla). Geçmeyeni düzelt ve yeniden denetle.",
137
- "5. Tek özet göster: numara, çıktı, tür, denetim sonucu. Değiştirmek istediği numarayı sor.",
138
- " Program çıktısı katkısı: P kodları ayrıştırıldıysa onlarla doldur; yoksa P kodu uydurma, hocadan program çıktıları sayfasını iste.",
167
+ "5. Tek özet göster: numara, çıktı, tür, denetim sonucu; kopya metni de aynı mesajda ver. Değiştirmek istenen numara yazılır.",
168
+ " Program çıktısı katkısı: P kodları ayrıştırıldıysa onlarla doldur; tarayıcın varsa program çıktıları sayfasını kendin oku. Yoksa P kodu uydurma; katkı tablosunu EKSİK bırak, akışı durdurma.",
139
169
  "6. bologna_kopya_metni ile Öğrenme Çıktıları sekmesine kopyalanacak metni ver ya da Bologna akışındaki OBS'ye yazma adımını izle.",
140
170
  ].join("\n");
141
171
  const ckPcAkisi = (dersKodu) => [
142
172
  `Odak: ÇK ve PÇ sağlanma düzeyi hesabı.${dersKodu ? ` Ders: ${dersKodu}.` : ""}`,
143
173
  "",
144
174
  "Akış:",
145
- "1. Hocadan Excel not tablosunu kopyalayıp yapıştırmasını iste. İlk satır başlık, her soru bir sütun; başlıkta sınav, soru, ÇK ve tam puan olursa iş biter (ör. Vize S1 (ÇK1) /20).",
146
- " Ad ve numara sütunlarını araç ayrıştırmadan önce atar ve o1, o2 takma adı verir; bunu hocaya tek cümleyle söyle.",
175
+ '1. Hocaya önce şunu söyle: "Kişisel veriyi yapay zekâ sohbetine yapıştırmayın: Excel\'de Ad, Soyad, Numara sütunlarını silip yalnız not sütunlarını yapıştırın ya da verinin tarayıcınızdan çıkmadığı hesaplayıcıyı kullanın: https://akredit.org/deneyin"',
176
+ " Sonra yalnız not sütunlarını yapıştırmasını iste. İlk satır başlık, her soru bir sütun; başlıkta sınav, soru, ÇK ve tam puan olursa iş biter (ör. Vize S1 (ÇK1) /20). Öğrenciler o1, o2 takma adı alır.",
147
177
  "2. Tabloyu not_tablosu_ayristir'e ver.",
148
- `3. Sor: 1) eşlemeyi tek tek gözden geçirelim 2) yalnız eksikleri soralım 3) eşlemeyi kendim yazayım ${AKILLI_DOLDURMA_SECENEGI}.`,
149
- " 4: başlıktan okunan eşlemeyi ve varsayılanları kullan: eşik 60, sınav ağırlıkları tablodan. Başlıkta olmayan soru-çıktı eşlemesini ve tam puanı tahmin etme; bunları tek mesajda topluca sor.",
178
+ "3. Eşleme tamamsa SORMA, doğrudan hesapla (eşik 60). Başlıkta olmayan soru-çıktı eşlemesi, tam puan ya da sınav ağırlığı varsa tahmin etme; hepsini TEK mesajda sor.",
150
179
  "4. Hazır olunca ck_pc_hesapla'yı çağır. Sonucu tablo olarak göster; sayıları yalnız yanıttan al.",
151
- "5. Tek özet: hangi eşlemeyi ve eşiği kullandığını, eşiğin altında kalan çıktıları yaz. Değiştirmek istediği numarayı sor.",
152
- "6. Sor: 1) eşiğin altındaki çıktılar için iyileştirme notu taslağı 2) farklı eşikle yeniden hesapla 3) bitir. Not taslağında sayı uydurma; sonucu kopyalanabilir tablo olarak ver.",
180
+ "5. Tek mesaj: kullanılan eşleme ve eşik, sonuç tablosu, eşiğin altındaki çıktılar için kısa iyileştirme notu taslağı (sayı uydurmadan). Ayrıca soru sorma.",
153
181
  ].join("\n");
154
182
  const olcutAkisi = (cerceve) => [
155
183
  `Odak: ölçüt ve kanıt rehberi.${cerceve ? ` Çerçeve: ${cerceve}.` : ""}`,
156
184
  "",
157
185
  "Akış:",
158
- `1. ${cerceve ? "Çerçeve verildi, sorma." : "Sor: hangi çerçeve? 1) YÖKAK kurumsal 2) program akreditasyonu: MÜDEK, FEDEK, EPDAD ya da SABAK. Hoca söylemezse YÖKAK kurumsal ile başla."}`,
159
- `2. Sor: 1) bir ölçütün resmî metni 2) bir konuda hangi ölçütler var 3) öz değerlendirme iskeleti ${AKILLI_DOLDURMA_SECENEGI.replace("doldur", "hazırla")}: konuya uyan ölçütleri bulup resmî metinleri ve kanıt kontrol listesini tek seferde çıkarırım.`,
160
- "3. olcut_ara ile ara, en uygun sonuçları al. olcut_getir ile resmî metni kaynağıyla göster. Akıllı hazırlamada en uygun 2-3 ölçütü kendin seç.",
186
+ `1. ${cerceve ? "Çerçeve verildi, sorma." : "Tek soru sor: hangi çerçeve ve konu? 1) YÖKAK 2) MÜDEK 3) FEDEK 4) EPDAD 5) SABAK; konu ya da ölçüt kodunu yanına yazabilirsiniz. Hoca çerçeve söylemezse YÖKAK ile başla."}`,
187
+ "2. Ne istendiğini ayrıca SORMA: her zaman hepsini hazırla (resmî metin, düzeyler, kanıt kontrol listesi).",
188
+ "3. olcut_ara ile ara; en uygun 1-2 ölçüt için hemen olcut_getir'i çağır. Resmî metni kaynağıyla göster.",
161
189
  "4. YÖKAK alt ölçütüyse olgunluk_duzeyleri ile düzeyleri ve örnek kanıtları al. Kanıtın kurumda olup olmadığını tahmin etme: kontrol listesinde 'hocaya sorulacak' yaz; hoca isterse tek mesajda 'var olanların numaraları' diye sor.",
162
190
  "5. Programın disiplinini ya da programa özgü bölümünü sen tahmin etme; bilmiyorsan tek soruyla sor.",
163
191
  "6. Ölçüt metnini yalnız araç yanıtından alıntıla. DOĞRULANMADI işaretli metni tahminle doldurma.",
@@ -168,12 +196,11 @@ const dilAkisi = () => [
168
196
  "",
169
197
  "Akış:",
170
198
  "1. Hocadan metni yapıştırmasını iste. Öğrenci adı ya da numarası varsa göndermeden önce o1, o2 gibi takma adla değiştir.",
171
- "2. Rapor dönemini metinden çıkar; çıkaramazsan tek soruyla sor.",
199
+ "2. Rapor dönemini metinden çıkar; çıkaramazsan sorma, dönemsiz denetle.",
172
200
  "3. rapor_dil_denetle'yi çağır.",
173
- `4. Sor: 1) bulguları tek tek göstereyim 2) yalnız önemli olanları düzelteyim 3) numaraları kendim seçeyim ${AKILLI_DOLDURMA_SECENEGI.replace("doldur", "düzelt")}.`,
174
- " 4: her bulgu için en iyi düzeltmeyi kendin seç. Kanıt ya da sayı gerektiren düzeltmede bilgi uydurma; o yere EKSİK yaz.",
201
+ "4. Nasıl düzeltileceğini SORMA: her bulguyu kendin düzelt. Kanıt ya da sayı gerektiren yerde bilgi uydurma; [EKSİK: ...] yaz.",
175
202
  "5. Düzeltilmiş metni yeniden rapor_dil_denetle ile denetle; kalan bulguları düzelt.",
176
- "6. Tek özet göster: numara, eski ifade, yeni ifade. Değiştirmek istediği numarayı sor. Sonunda düzeltilmiş metnin tamamını kopyalanabilir biçimde ver.",
203
+ "6. Tek mesaj: numaralı eski → yeni tablosu ve düzeltilmiş metnin tamamı (kopyalanabilir). Değiştirmek istenen numara yazılır.",
177
204
  ].join("\n");
178
205
  const AKISLAR = {
179
206
  bologna_doldur: (a) => bolognaAkisi(kisa(a.ders_kodu)),
@@ -192,7 +219,7 @@ const akreditMenusu = (odak) => {
192
219
  "",
193
220
  "Hocaya tam olarak şunu göster ve yanıtını bekle:",
194
221
  "",
195
- "Merhaba. Bugün neye odaklanalım? Numarasını yazmanız yeter.",
222
+ "Merhaba. Neye odaklanalım? Numarasını yazmanız yeter.",
196
223
  ...ODAKLAR.map(([no, ad]) => `${no}) ${ad}`),
197
224
  `${ODAKLAR.length + 1}) Başka bir şey: tüm araçları kısaca listele`,
198
225
  "",
@@ -249,5 +276,65 @@ export const ACIK_ISTEMLER = [
249
276
  metin: () => ile(dilAkisi()),
250
277
  },
251
278
  ];
279
+ /** Kısa kurallar: akredit_basla yanıtında (istem desteklemeyen istemciler için) yer alır. */
280
+ export const KISA_KURALLAR = [
281
+ "Hoca yalnız 'akredit' yazdıysa menüyü aynen göster ve numara bekle. Niyetini yazdıysa menüyü atla, o akışa başla.",
282
+ "Her soruyu numaralı seçeneklerle sor; hoca yalnız numara yazarak ilerleyebilsin.",
283
+ "Bologna (1) seçilince tarayıcın varsa ilk iş OBS adresini isteyip açmak; ders adını sorma, OBS'den oku.",
284
+ "Hocaya 'hangisi?' diye sormadan önce kendin tara ve öner: bütün dersleri denetle, eksikleri say, 'önerilen' seçenekle gel.",
285
+ "Kısa, sade Türkçe yaz; araç adı, JSON ve teknik terim gösterme. Her mesajda tek iş iste.",
286
+ "Uydurma yok: kişi, kitap, ISBN, DOI, tarih, sayı uydurma. Bilinmeyen EKSİK kalır.",
287
+ "Değerlendirme yöntem ve yüzdeleri, uygulama/lab, kullanılan kaynaklar ve sayfada yoksa amaç/içerik sayfadan okunur; yoksa hocaya TEK mesajda, numaralı ve varsayılan seçenekli sorulur.",
288
+ "Ders adından ürettiğin her şeyi 'öneri' etiketiyle göster. Araç sonucu 'biçim denetiminden geçti; içerik teyidi: hoca' diye sunulur.",
289
+ "Sayıları yalnız araç yanıtından al.",
290
+ "Kaynak yalnız 'katalogda_bulundu' ise öneri olarak, ya da hoca kullandığını söylerse 'hoca_beyani' olarak yazılır.",
291
+ "Giriş bilgisi (parola, doğrulama kodu, çerez) istenmez; hoca yazarsa kullanma, araçlara gönderme.",
292
+ "OBS'ye yazmadan önce alan alan önceki/yeni değer özeti göster; hoca bir kez 'kaydet' der. Kayıttan sonra geri oku ve obs_karsilastir ile doğrula. Gönder düğmesine hoca basar.",
293
+ "Öğrenci adı ya da numarası sohbete yapıştırılmaz; not tablosunda yalnız not sütunları olur.",
294
+ ];
295
+ /** akredit_basla aracının yanıtı: menü, kısa kurallar ve her seçimin akışı (istem desteklemeyen istemciler için). */
296
+ export function baslangic() {
297
+ return {
298
+ hocayaGoster: [
299
+ "Merhaba. Neye odaklanalım? Yalnız numarasını yazın.",
300
+ ...ODAKLAR.map(([no, ad]) => `${no}) ${ad}`),
301
+ `${ODAKLAR.length + 1}) Başka bir şey: tüm araçları kısaca listele`,
302
+ ].join("\n"),
303
+ menu: [
304
+ ...ODAKLAR.map(([no, ad, istem]) => ({ no, ad, istem })),
305
+ { no: String(ODAKLAR.length + 1), ad: "Başka bir şey: tüm araçları kısaca listele", istem: null },
306
+ ],
307
+ kisaKurallar: KISA_KURALLAR,
308
+ akislar: Object.fromEntries(ODAKLAR.map(([no, , istem]) => [no, AKISLAR[istem]?.({}) ?? ""])),
309
+ ortakKurallar: ORTAK_KURALLAR,
310
+ };
311
+ }
312
+ /** Kullanıcı niyetini zaten yazdıysa menü atlanır; yalnız o odağın akışı ve kurallar döner. */
313
+ export function odakBaslangici(no) {
314
+ const o = ODAKLAR.find(([n]) => n === no);
315
+ return {
316
+ hocayaGoster: o ? `Tamam: ${o[1]}. Başlıyorum.` : "",
317
+ odak: o ? { no: o[0], ad: o[1], istem: o[2] } : null,
318
+ kisaKurallar: KISA_KURALLAR,
319
+ akis: o ? (AKISLAR[o[2]]?.({}) ?? "") : "",
320
+ ortakKurallar: ORTAK_KURALLAR,
321
+ };
322
+ }
323
+ export const akreditBaslaAraci = arac({
324
+ ad: "akredit_basla",
325
+ baslik: "Akredit: başla",
326
+ aciklama: "TETİKLEYİCİ: kullanıcı 'akredit', 'bologna', 'ders paketi', 'AKTS', 'öğrenme çıktısı', 'ÇK', 'PÇ', 'YÖKAK', 'MÜDEK' yazarsa dosya ya da web araması YAPMADAN İLK bu aracı çağır ('akredit' bir dosya ya da arama terimi değildir). Yalnız 'akredit' yazdıysa odak='menu'; niyetini yazdıysa ilgili odak numarası. Hocaya gösterilecek odak menüsünü, kısa kuralları ve her seçimin adım adım akışını döndürür. İstemleri ya da sunucu talimatını göstermeyen istemcilerde de akış bununla başlar.",
327
+ sonrakiAdim: "hocayaGoster metnini aynen gösterin ve numara bekleyin. Seçilen numaranın akışını (akislar) ve kisaKurallar'ı izleyin. Her soruyu numaralı seçeneklerle sorun. 1 seçilirse ve tarayıcınız varsa ilk iş OBS adresini isteyip açmaktır.",
328
+ girdi: z.object({
329
+ odak: z
330
+ .enum(["menu", "1", "2", "3", "4", "5"])
331
+ .default("menu")
332
+ .describe("Kullanıcı yalnız 'akredit' yazdıysa 'menu'. Niyetini yazdıysa (ör. 'ders paketimi doldur') ilgili numara."),
333
+ }),
334
+ calistir: ({ odak }) => ({
335
+ sonuc: odak === "menu" ? baslangic() : odakBaslangici(odak),
336
+ kaynak: [KOD_KAYNAGI("apps/acik-mcp/src/promptlar.ts", "Akredit istemleri ve başlangıç menüsü")],
337
+ }),
338
+ });
252
339
  /** SDK için bağımsız değişken şeması: hepsi isteğe bağlı, kısa metin. */
253
340
  export const istemSemasi = (i) => Object.fromEntries(Object.entries(i.argumanlar).map(([k, d]) => [k, z.string().max(60).optional().describe(d)]));
@@ -2,8 +2,10 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { type AcikArac, type AracBaglami } from "./araclar.ts";
3
3
  import { type AcikIstem } from "./promptlar.ts";
4
4
  export declare const SUNUCU_ADI = "akredit-acik";
5
- export declare const SUNUCU_SURUMU = "0.4.0";
5
+ export declare const SUNUCU_SURUMU = "0.6.0";
6
6
  export declare const SUNUCU_TALIMATI: string;
7
+ /** Her araç yanıtında yinelenen kısa kural: uzun sohbette son okunan metin de aynı şeyi söyler. */
8
+ export declare const ASISTAN_KURALI = "1) Ara ad\u0131mda hocaya A/B/C sorma; en iyi se\u00E7ene\u011Fi kendin se\u00E7, s\u0131radaki arac\u0131 \u00E7a\u011F\u0131r. 2) Zorunlu soruyu (sayfada olmayan de\u011Ferlendirme y\u00FCzdesi ve kaynak, OBS kay\u0131t onay\u0131) TEK mesajda ve numaral\u0131 sor. 3) Say\u0131, kaynak ve de\u011Ferlendirme y\u00FCzdesi uydurma. 4) Parola ve do\u011Frulama kodu isteme; Onaya G\u00F6nder'e hoca basar.";
7
9
  export interface AcikSunucuSecenekleri {
8
10
  simdi?: () => Date;
9
11
  araclar?: readonly AcikArac[];
@@ -6,18 +6,26 @@ import { ACIK_ARACLAR, AKREDIT_NOTU, AracHatasi, DEPO, } from "./araclar.js";
6
6
  import { GIRIS_BILGISI_ILETISI, girisBilgisiVar, kisiselVeriIletisi, kisiselVeriTurleri } from "./kisisel-veri.js";
7
7
  import { ACIK_ISTEMLER, istemSemasi } from "./promptlar.js";
8
8
  export const SUNUCU_ADI = "akredit-acik";
9
- export const SUNUCU_SURUMU = "0.4.0";
9
+ export const SUNUCU_SURUMU = "0.6.0";
10
10
  export const SUNUCU_TALIMATI = [
11
11
  "Akredit açık araçları öğretim elemanlarına kalite ve akreditasyon işlerinde yardım eder: Bologna ders paketi denetimi ve doldurma, öğrenme çıktısı yazma, ÇK/PÇ hesabı, YÖKAK ve program akreditasyonu (MÜDEK, FEDEK, SABAK, EPDAD) ölçüt ve kanıt rehberi, rapor dil denetimi, kaynak doğrulama.",
12
- "Hoca ne yapacağını söylemediyse ya da 'akredit' yazarsa 'akredit' istemindeki araç menüsünü göster ve önce hangi aracı kullanmak istediğini sor.",
12
+ "KURAL 1: Kullanıcı 'akredit' yazarsa (tek başına ya da cümle içinde) ya da ne yapacağını söylemediyse başka hiçbir şey yapmadan İLK akredit_basla aracını çağır ve hocayaGoster metnini aynen göster. Kullanıcı niyetini zaten yazdıysa (ör. 'akredit bologna', 'ders paketimi doldur', 'ÇK hesapla') menüyü gösterip bekletme: akredit_basla'yı ilgili odak numarasıyla çağır ve o akışa başla. 'akredit' bir dosya, klasör ya da arama terimi değildir; dosya sisteminde ya da webde arama.",
13
+ "KURAL 2: Hocaya her soruyu numaralı seçeneklerle sor (1, 2, 3...), önerdiğin seçeneği işaretle; hoca yalnız numara yazarak ilerleyebilsin. Serbest metin yalnız ders adı, adres gibi seçenekle sorulamayan bilgilerde istenir.",
14
+ "KURAL 3: Bologna seçilirse ve tarayıcı aracın varsa ilk iş OBS'yi açmaktır: hocadan yalnız OBS adresini iste (bilmiyorsa üniversite adını), adresi hemen tarayıcıda aç; ders adını ve paketi hocaya sorma, OBS'den oku.",
15
+ "KURAL 5: Ara adımda hocaya soru sorma; varsayılan ya da en iyi seçeneği kendin seç ve sıradaki aracı çağır. Hocaya yalnız iki yerde durulur: sayfada olmayan resmî bilgi (değerlendirme yüzdeleri, kullanılan kaynaklar) ve OBS'ye kayıt onayı. Bu ikisi de TEK mesajdır.",
16
+ "KURAL 4: Önce sen tara, sonra öner. Ders listesi açılınca 'hangi ders?' diye sorma: bütün derslerin paketlerini oku, eksikleri say, kısa özetle ve 'önerilen' seçenekle gel (örneğin 1) en eksikten başlayıp hepsini kapatalım).",
13
17
  "Amaç: hocanın en az müdahalesiyle işi hızlı ama denetimli ve teyitli bitirmek. Her seçim menüsünde son seçenek '4) Hepsini akıllıca doldur (önerilen)' olur: her alan için en iyi seçeneği sen seçersin, araçla denetlersin, geçmeyeni düzeltip yeniden denetlersin, sonunda tek özet gösterip değiştirmek istediği numarayı sorarsın.",
14
- "Giriş bilgisi: hocadan kullanıcı adı, parola, doğrulama kodu ya da çerez asla isteme; hoca yazarsa kullanma, araçlara gönderme, silmesini ve parolasını değiştirmesini öner. Hoca giriş bilgisini yalnız OBS'nin kendi ekranına kendisi yazar. CAPTCHA'yı hoca çözer. OBS'de Kaydet'e yalnız hocanın açık izniyle basarsın; onaya Gönder düğmesine hoca basar.",
18
+ "Yalnız hocanın bilebileceği ve resmî taahhüt olan bilgiler (değerlendirme yöntem ve yüzdeleri, uygulama/lab, kullanılan kaynaklar, sayfada yoksa amaç ve içerik) sayfadan okunur; yoksa hocaya TEK mesajda, numaralı ve varsayılan seçenekli sorulur, uydurulmaz. Ders adından üretilen her şey 'öneri' etiketiyle gösterilir. Araç sonucu 'biçim denetiminden geçti; içerik teyidi: hoca' diye sunulur.",
19
+ "Giriş bilgisi: hocadan kullanıcı adı, parola, doğrulama kodu ya da çerez asla isteme. Sunucu bunları istemez; görülürse çağrıyı reddeder ve kaydetmez. Hoca yazarsa kullanma, araçlara gönderme, silmesini ve parolasını değiştirmesini öner. Hoca giriş bilgisini yalnız OBS'nin kendi ekranına kendisi yazar. CAPTCHA'yı hoca çözer.",
20
+ "OBS'ye yazma: önce alan alan önceki ve yeni değer özetini göster, hoca bir kez 'kaydet' ya da özetin altındaki 1'i (OBS'ye yaz ve kaydet) yazar; ancak ondan sonra Kaydet'e basarsın. Kayıttan sonra sayfayı geri okuyup obs_karsilastir ile doğrula; ders kodu ya da dönem değişmişse yazmayı durdur. Doğrulanmamış kaynak ve teyitsiz değerlendirme yüzdesi yazılmaz. Onaya Gönder düğmesine hoca basar.",
15
21
  "Tarayıcı aracın varsa OBS sayfasını okuyup formu doldurabilirsin; yoksa ya da engel çıkarsa engel_coz ve kurulum_yardimi araçlarının adımlarını hocaya sırayla, tek tek göster. Tarayıcı yoksa OBS'ye yazma alan alan kopyalamaya düşer.",
16
22
  "Sunucu model çağırmaz ve metin üretmez: seçenekleri sen yazarsın, sunucu kural ve kalıp verir, denetler ve sayıları hesaplar. Sayıları yalnız araç sonucundan al.",
17
- "Bologna sayfasındaki Dersi Verenler, Yardımcılar ve Koordinatör satırları yayımlanmış görev bilgisidir: olduğu gibi okunur, korunur, değiştirilmez. Öğrenci adı ve numarası içeren not tabloları takma adla işlenir. Sunucu istek içeriğini günlüğe yazmaz.",
18
- "Kaynak önerirken hocaya kitap adını sorma: kendi web arama aracınla ders içeriğine uygun eserleri bul, kaynak_dogrula ile doğrula, yalnız doğrulananları künyesi ve bağlantısıyla göster. Doğrulanamayan kaynağı asla önerme. Ölçüt metnini yalnız olcut_getir sonucundan alıntılayın; DOĞRULANMADI ya da 'Belgeden okunamadı' işaretli metni tahminle doldurmayın. Programın disiplinini kurum seçer. Kanıtı olmayan cümle EKSİK kalır. Kitap, kişi, tarih uydurmayın.",
23
+ "Bologna sayfasındaki Dersi Verenler, Yardımcılar ve Koordinatör satırları yayımlanmış görev bilgisidir: olduğu gibi okunur, korunur, değiştirilmez. Öğrenci adı ve numarası sohbete yapıştırılmaz: not tablosunda yalnız not sütunları olur; kimlik sütunu görülürse tablo işlenmez. Sunucu istek içeriğini günlüğe yazmaz.",
24
+ "Kaynak: önce sayfadaki ve hocanın kullandığı kaynaklar. Öneri gerekirse kendi web arama aracınla aday bul, kaynak_dogrula ile sorgula, yalnız 'katalogda_bulundu' dönenleri künyesi ve bağlantısıyla 'öneri' olarak göster; uygunluğuna hoca karar verir. Katalogda bulunmayanı kendin önerme; hoca kullandığını söylerse 'hoca_beyani' olarak yaz. Ölçüt metnini yalnız olcut_getir sonucundan alıntılayın; DOĞRULANMADI ya da 'Belgeden okunamadı' işaretli metni tahminle doldurmayın. Programın disiplinini kurum seçer. Kanıtı olmayan cümle EKSİK kalır. Kitap, kişi, tarih uydurmayın.",
19
25
  "Sunucu kullanıcıdan adres çekmez: Bologna sayfasını hoca yapıştırır ya da siz kendi web aracınızla okursunuz. Tek dış istek kaynak_dogrula'nın sabit katalog adresleridir (Crossref, Open Library, Google Books). Onay ve dış kuruma gönderim hocadadır. Akredit'in YÖKAK ile bağı yoktur.",
20
26
  ].join(" ");
27
+ /** Her araç yanıtında yinelenen kısa kural: uzun sohbette son okunan metin de aynı şeyi söyler. */
28
+ export const ASISTAN_KURALI = "1) Ara adımda hocaya A/B/C sorma; en iyi seçeneği kendin seç, sıradaki aracı çağır. 2) Zorunlu soruyu (sayfada olmayan değerlendirme yüzdesi ve kaynak, OBS kayıt onayı) TEK mesajda ve numaralı sor. 3) Sayı, kaynak ve değerlendirme yüzdesi uydurma. 4) Parola ve doğrulama kodu isteme; Onaya Gönder'e hoca basar.";
21
29
  const metinSonuc = (veri, isError = false) => ({
22
30
  content: [{ type: "text", text: JSON.stringify(veri, null, 2) }],
23
31
  structuredContent: veri,
@@ -29,6 +37,9 @@ function hazirla(a, girdi) {
29
37
  girdi = ayik.girdi;
30
38
  if (girisBilgisiVar(girdi))
31
39
  return { hata: { veri: { hata: GIRIS_BILGISI_ILETISI, kod: "giris_bilgisi", not: AKREDIT_NOTU }, hata: true } };
40
+ const red = a.onDenetim?.(girdi);
41
+ if (red)
42
+ return { hata: { veri: { hata: red, kod: "kisisel_veri", not: AKREDIT_NOTU }, hata: true } };
32
43
  const turler = kisiselVeriTurleri(girdi, a.kunyeAlanlari, a.kisiselVeriKapsami ?? "ogrenci");
33
44
  if (turler.length)
34
45
  return {
@@ -63,6 +74,7 @@ function basari(a, s, atilan, ileti) {
63
74
  veri: {
64
75
  sonuc: s.sonuc,
65
76
  sonrakiAdim: s.sonrakiAdim ?? a.sonrakiAdim,
77
+ asistanKurali: ASISTAN_KURALI,
66
78
  ...(atilan.length
67
79
  ? { atilan: ileti ?? `Şu kısımlar okunmadan atıldı, hiçbir yere yazılmadı: ${atilan.join(", ")}.` }
68
80
  : {}),
@@ -39,6 +39,11 @@ export interface AcikArac<S extends z.ZodObject = z.ZodObject> {
39
39
  atilan: string[];
40
40
  ileti?: string;
41
41
  };
42
+ /**
43
+ * Kişisel veri taramasından önce çalışan red denetimi. İleti dönerse çağrı işlenmeden "kisisel_veri" koduyla
44
+ * reddedilir; değerler hiçbir yere yazılmaz.
45
+ */
46
+ onDenetim?: (girdi: unknown) => string | null;
42
47
  /** Kişisel veri denetiminin kapsamı; varsayılan "ogrenci" (bkz. kisisel-veri.ts). */
43
48
  kisiselVeriKapsami?: KisiselVeriKapsami;
44
49
  /** Araç dış ağa (yalnız izinli hostlara) istek atar mı. */
@@ -34,31 +34,35 @@ const ISTEMCI_ADI = {
34
34
  claude_code: "Claude Code",
35
35
  };
36
36
  const BAGLAYICI = {
37
+ // Anthropic yardım belgesi "Get started with custom connectors using remote MCP" (erişim 2026-11-05).
37
38
  claude_web: [
38
39
  ["claude.ai adresine girin ve oturum açın.", "Sol tarafta sohbet listesi, ortada yazı kutusu."],
39
- ["Sol alttaki adınıza tıklayın, Settings (Ayarlar) seçin.", "Ayarlar sayfası açılır.", true],
40
- ["Connectors (Bağlayıcılar) bölümünü açın.", "Bağlı araçların listesi.", true],
41
- ["Add custom connector (Özel bağlayıcı ekle) düğmesine basın.", "Ad ve adres soran küçük bir pencere.", true],
42
- [`Ad olarak Akredit, adres olarak ${MCP_ADRESI} yazın ve Add (Ekle) deyin.`, "Listede Akredit görünür."],
40
+ ["Customize (Özelleştir), ardından Connectors (Bağlayıcılar) bölümünü açın.", "Bağlı araçların listesi."],
41
+ ["+ Add düğmesine, ardından Add custom connector seçeneğine basın.", "Ad ve adres soran pencere."],
42
+ [`Ad olarak Akredit, adres olarak ${MCP_ADRESI} yazın ve Continue deyin.`, "Kimlik doğrulama seçenekleri."],
43
+ ["Authentication altında No sign in seçin ve Add deyin.", "Listede Akredit görünür."],
44
+ [
45
+ "Ücretsiz planda tek özel bağlayıcı eklenebilir. Team ve Enterprise planlarında bağlayıcıyı kuruluş sahibi ekler; siz Connectors listesinde Akredit'i bulup Connect dersiniz.",
46
+ undefined,
47
+ ],
43
48
  [
44
49
  "Yeni sohbet açın. Yazı kutusunun altındaki + düğmesinden Akredit'in açık olduğunu denetleyin.",
45
50
  "Akredit'in yanında açık anahtar.",
46
51
  true,
47
52
  ],
48
53
  [
49
- "Yazı kutusuna akredit yazın ya da + menüsünden Akredit altındaki akredit başlangıcını seçin.",
50
- "Odak menüsü: 1-5 arası seçenek.",
54
+ "akredit yazın. Menü gelmezse Akredit araçlarıyla Bologna paketimi denetle yazın.",
55
+ "Odak menüsü: numaralı seçenekler.",
51
56
  ],
52
57
  ],
53
58
  claude_masaustu: [
54
59
  ["Claude masaüstü uygulamasını açın ve oturum açın.", "claude.ai ile aynı görünüm."],
60
+ ["Customize (Özelleştir), ardından Connectors (Bağlayıcılar) bölümünü açın.", "Bağlayıcı listesi."],
55
61
  [
56
- "Sol alttaki adınızdan Settings (Ayarlar), ardından Connectors (Bağlayıcılar) bölümüne girin.",
57
- "Bağlayıcı listesi.",
58
- true,
62
+ `+ Add, Add custom connector ile ad Akredit, adres ${MCP_ADRESI} yazın; Authentication altında No sign in seçip Add deyin.`,
63
+ "Listede Akredit görünür.",
59
64
  ],
60
- [`Add custom connector ile ad Akredit, adres ${MCP_ADRESI} olarak ekleyin.`, "Listede Akredit görünür.", true],
61
- ["Yeni sohbette akredit yazın.", "Odak menüsü."],
65
+ ["Yeni sohbette akredit yazın. Menü gelmezse Akredit araçlarıyla Bologna paketimi denetle yazın.", "Odak menüsü."],
62
66
  ],
63
67
  claude_chrome: [
64
68
  ["Önce Claude'a Akredit bağlayıcısını ekleyin (Claude web adımları).", "Sohbette Akredit açık."],
@@ -80,20 +84,26 @@ const BAGLAYICI = {
80
84
  true,
81
85
  ],
82
86
  ],
87
+ // OpenAI geliştirici belgesi "Custom MCP server" (erişim 2026-11-05). Hangi planlarda açık olduğu belgede yazmıyor.
83
88
  chatgpt: [
84
- ["chatgpt.com adresinde oturum açın.", "Sohbet ekranı."],
89
+ ["chatgpt.com adresinde, web tarayıcısında oturum açın.", "Sohbet ekranı."],
90
+ ["chatgpt.com/plugins adresini açın; + düğmesine basıp Add custom MCP server seçin.", "Ad ve bağlantı soran form."],
85
91
  [
86
- "Settings (Ayarlar), Apps (Uygulamalar), Advanced settings altında Developer mode (geliştirici kipi) seçeneğini açın.",
87
- "Uygulama oluşturma düğmesi görünür.",
92
+ `Ad olarak Akredit yazın; Connection altında Server URL olarak ${MCP_ADRESI} girin; kimlik doğrulama olarak no authentication seçin.`,
93
+ undefined,
88
94
  true,
89
95
  ],
90
96
  [
91
- `Create (Oluştur) ile yeni uygulama ekleyin: ad Akredit, adres ${MCP_ADRESI}, kimlik doğrulama yok.`,
92
- "Akredit araçları listelenir.",
97
+ "Uyarıyı okuyup I understand and want to continue, ardından Create as a plugin deyin; sonra eklentiyi kurun.",
98
+ "Akredit eklentilerinizde görünür.",
99
+ true,
100
+ ],
101
+ [
102
+ "Bu özelliğin açık olup olmadığı planınıza göre değişebilir. Kurum hesabında çalışma alanı izinleri yöneticiye bağlıdır.",
103
+ undefined,
93
104
  true,
94
105
  ],
95
- ["İş ve kurum hesaplarında bu ayarı yönetici açar; açamıyorsanız yöneticinize sorun.", undefined, true],
96
- ["Yeni sohbette Akredit'i seçin ve akredit yazın.", "Odak menüsü."],
106
+ ["Yeni sohbette @ yazıp Akredit'i seçin, sonra akredit yazın.", "Odak menüsü."],
97
107
  ],
98
108
  cursor: [
99
109
  ["Cursor'da Settings (Ayarlar), ardından MCP bölümünü açın.", "MCP sunucu listesi.", true],
@@ -4,9 +4,25 @@ export interface TaslakDenetimSonucu {
4
4
  bulgular: Bulgu[];
5
5
  isToplam: number;
6
6
  hedef: number;
7
+ /** "guncel" kural setinde iş yükünün kabul aralığı (saat). Kurum değeri verildiyse alt ve üst eşittir. */
8
+ hedefAraligi?: [number, number];
7
9
  }
10
+ export type TaslakKuralSeti = "cli" | "guncel";
11
+ export interface TaslakDenetimSecenekleri {
12
+ /** "cli" kural setinde AKTS başına saat (varsayılan 30). */
13
+ bolen?: number;
14
+ kuralSeti?: TaslakKuralSeti;
15
+ /** "guncel" sette kurumun AKTS başına saati; verilirse iş yükü tam AKTS × bu değer olmalı. */
16
+ kurumBoleni?: number | undefined;
17
+ /** "guncel" sette kurum değeri yoksa AKTS başına saat aralığı; varsayılan [25, 30]. */
18
+ aktsSaat?: readonly [number, number];
19
+ }
20
+ /** Kuralların dayanak notları. Hiçbiri resmî belgeyle doğrulanmadı; bu yüzden hiçbiri "resmî" değildir. */
21
+ export declare const TASLAK_DAYANAK: {
22
+ readonly akredit: "Akredit iç kuralı (packages/cekirdek/src/bologna/taslak.ts); resmî dayanağı DOĞRULANMADI.";
23
+ readonly akts: "AKTS başına 25-30 saat yaygın uygulamadır; resmî metinle DOĞRULANMADI. Kurumun yönergesi önceliklidir.";
24
+ readonly kurum: "Kurumun verdiği AKTS başına saat değeri.";
25
+ };
8
26
  /** Kısmi ya da dışarıdan gelmiş taslak da denetlenebilir; eksik alanlar bulgu üretir. */
9
27
  export type DenetlenecekTaslak = Partial<BolognaTaslagi>;
10
- export declare function taslakDenetle(t: DenetlenecekTaslak, { bolen }?: {
11
- bolen?: number;
12
- }): TaslakDenetimSonucu;
28
+ export declare function taslakDenetle(t: DenetlenecekTaslak, secenek?: TaslakDenetimSecenekleri): TaslakDenetimSonucu;