@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.
- package/README.md +5 -5
- package/dist/apps/acik-mcp/src/araclar.js +7 -5
- package/dist/apps/acik-mcp/src/bologna.d.ts +91 -9
- package/dist/apps/acik-mcp/src/bologna.js +479 -107
- package/dist/apps/acik-mcp/src/genel-ayristir.d.ts +10 -1
- package/dist/apps/acik-mcp/src/genel-ayristir.js +85 -7
- package/dist/apps/acik-mcp/src/http.d.ts +31 -3
- package/dist/apps/acik-mcp/src/http.js +86 -15
- package/dist/apps/acik-mcp/src/index.d.ts +1 -0
- package/dist/apps/acik-mcp/src/index.js +1 -0
- package/dist/apps/acik-mcp/src/kaynak-dogrula.d.ts +51 -4
- package/dist/apps/acik-mcp/src/kaynak-dogrula.js +199 -58
- package/dist/apps/acik-mcp/src/kisisel-veri.d.ts +3 -1
- package/dist/apps/acik-mcp/src/kisisel-veri.js +24 -9
- package/dist/apps/acik-mcp/src/not-tablosu.d.ts +6 -0
- package/dist/apps/acik-mcp/src/not-tablosu.js +43 -18
- package/dist/apps/acik-mcp/src/promptlar.d.ts +44 -0
- package/dist/apps/acik-mcp/src/promptlar.js +144 -57
- package/dist/apps/acik-mcp/src/sunucu.d.ts +3 -1
- package/dist/apps/acik-mcp/src/sunucu.js +17 -5
- package/dist/apps/acik-mcp/src/temel.d.ts +5 -0
- package/dist/apps/acik-mcp/src/yardim.js +28 -18
- package/dist/packages/cekirdek/src/bologna/taslak.d.ts +19 -3
- package/dist/packages/cekirdek/src/bologna/taslak.js +70 -9
- package/dist/packages/cekirdek/src/turler.d.ts +8 -0
- package/package.json +3 -3
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
// Bologna ders sayfası taslağı denetimi (K1-K12 ve diğer kurallar).
|
|
2
2
|
// apps/cli/lib/bologna-taslak.mjs `taslakDenetle` işlevinin saf, tipli taşıması. Mesajlar aynen korunur:
|
|
3
3
|
// CLI'deki "K8: metin" dizesi burada { kural: "K8", aciklama: "metin" } olur.
|
|
4
|
+
//
|
|
5
|
+
// İki kural seti vardır (dış inceleme 2026-11-05):
|
|
6
|
+
// - "cli" (varsayılan): CLI ile birebir eşdeğer, eşdeğerlik testleri bunu sınar.
|
|
7
|
+
// - "guncel": açık MCP'nin kullandığı set. ÖÇ sayısı 4-10 geçerli (5-8 önerilir), "-ebilme/-abilme" kabul,
|
|
8
|
+
// "sahip ol/farkında ol/haberdar ol/vakıf ol" ölçülemez, AKTS iş yükü 25-30 saat/AKTS aralığı (kurum değeri
|
|
9
|
+
// verilirse tam o değer). Her bulgu kuralTuru ve dayanak taşır; resmî olduğu doğrulanamayan kural resmî sayılmaz.
|
|
10
|
+
/** Kuralların dayanak notları. Hiçbiri resmî belgeyle doğrulanmadı; bu yüzden hiçbiri "resmî" değildir. */
|
|
11
|
+
export const TASLAK_DAYANAK = {
|
|
12
|
+
akredit: "Akredit iç kuralı (packages/cekirdek/src/bologna/taslak.ts); resmî dayanağı DOĞRULANMADI.",
|
|
13
|
+
akts: "AKTS başına 25-30 saat yaygın uygulamadır; resmî metinle DOĞRULANMADI. Kurumun yönergesi önceliklidir.",
|
|
14
|
+
kurum: "Kurumun verdiği AKTS başına saat değeri.",
|
|
15
|
+
};
|
|
16
|
+
const ONERILEN_CIKTI = [5, 8];
|
|
17
|
+
const GECERLI_CIKTI = [4, 10];
|
|
4
18
|
const kelime = (s) => String(s ?? "")
|
|
5
19
|
.trim()
|
|
6
20
|
.split(/\s+/)
|
|
@@ -13,7 +27,13 @@ const OLCULEMEZ = /(bilgi sahibi olur|hakkında bilgi|fikir sahibi olur|(^|\s)(
|
|
|
13
27
|
const ZAYIF = /farkındalık/i;
|
|
14
28
|
// Türkçe çekimli fiille biten çıktı: açıklar, uygular, tasarlar, geliştirebilir…
|
|
15
29
|
const FIILLE_BITER = /(ar|er|ır|ir|ur|ür)\.?\s*$/i;
|
|
16
|
-
|
|
30
|
+
// "guncel" set: "-ebilme/-abilme" kalıbı da kabul (tasarlayabilme, analiz edebilme).
|
|
31
|
+
const FIILLE_BITER_GUNCEL = /(ar|er|ır|ir|ur|ür|abilme|ebilme)\.?\s*$/iu;
|
|
32
|
+
// "guncel" set: "sahip olur", "farkında olur", "haberdar olur", "vakıf olur" (ve -abilir, -ma biçimleri) ölçülemez.
|
|
33
|
+
const OLCULEMEZ_GUNCEL = /(sahibi? ol|sahip ol|farkında ol|haberdar ol|vakıf ol)\p{L}*\.?\s*$/iu;
|
|
34
|
+
export function taslakDenetle(t, secenek = {}) {
|
|
35
|
+
const { bolen = 30 } = secenek;
|
|
36
|
+
const guncel = secenek.kuralSeti === "guncel";
|
|
17
37
|
const bulgular = [];
|
|
18
38
|
const hata = (kural, aciklama) => bulgular.push({ duzey: "hata", kural, aciklama });
|
|
19
39
|
const uyari = (kural, aciklama) => bulgular.push({ duzey: "uyari", kural, aciklama });
|
|
@@ -56,9 +76,35 @@ export function taslakDenetle(t, { bolen = 30 } = {}) {
|
|
|
56
76
|
const isyuku = t.isyuku ?? [];
|
|
57
77
|
const isToplam = isyuku.reduce((s, x) => s + Number(x.sayi || 0) * Number(x.sure || 0), 0);
|
|
58
78
|
const carpan = t.bolen || bolen;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
79
|
+
let hedef = Number(t.akts) * carpan;
|
|
80
|
+
let hedefAraligi;
|
|
81
|
+
if (!guncel) {
|
|
82
|
+
if (isToplam !== hedef)
|
|
83
|
+
hata("K8", `Toplam iş yükü ${isToplam} saat, AKTS ${t.akts} × ${carpan} = ${hedef} olmalı. AKTS'yi değil saat dağılımını değiştir.`);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const kurum = secenek.kurumBoleni ?? t.bolen;
|
|
87
|
+
const [alt, ust] = secenek.aktsSaat ?? [25, 30];
|
|
88
|
+
const akts = Number(t.akts);
|
|
89
|
+
hedefAraligi = kurum ? [akts * kurum, akts * kurum] : [akts * alt, akts * ust];
|
|
90
|
+
hedef = kurum ? akts * kurum : akts * ust;
|
|
91
|
+
if (kurum && isToplam !== hedef)
|
|
92
|
+
bulgular.push({
|
|
93
|
+
duzey: "hata",
|
|
94
|
+
kural: "K8",
|
|
95
|
+
aciklama: `Toplam iş yükü ${isToplam} saat, AKTS ${t.akts} × ${kurum} (kurum değeri) = ${hedef} olmalı. AKTS'yi değil saat dağılımını değiştir.`,
|
|
96
|
+
kuralTuru: "kurum",
|
|
97
|
+
dayanak: TASLAK_DAYANAK.kurum,
|
|
98
|
+
});
|
|
99
|
+
else if (!kurum && (isToplam < hedefAraligi[0] || isToplam > hedefAraligi[1]))
|
|
100
|
+
bulgular.push({
|
|
101
|
+
duzey: "hata",
|
|
102
|
+
kural: "K8",
|
|
103
|
+
aciklama: `Toplam iş yükü ${isToplam} saat, AKTS ${t.akts} için ${hedefAraligi[0]}-${hedefAraligi[1]} saat (AKTS başına ${alt}-${ust}) olmalı. AKTS'yi değil saat dağılımını değiştir.`,
|
|
104
|
+
kuralTuru: "Akredit önerisi",
|
|
105
|
+
dayanak: TASLAK_DAYANAK.akts,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
62
108
|
const dersSuresi = isyuku.find((x) => /ders süresi/i.test(x.ad));
|
|
63
109
|
if (dersSuresi && Number(dersSuresi.sure) !== teorik + uygulama + lab) {
|
|
64
110
|
uyari("K8", `Ders süresi satırı haftada ${dersSuresi.sure} saat, T+U+L toplamı ${teorik + uygulama + lab}.`);
|
|
@@ -69,14 +115,22 @@ export function taslakDenetle(t, { bolen = 30 } = {}) {
|
|
|
69
115
|
hata("K6", `Ders yapısı yüzdeleri toplamı %${yapiToplam}, tam %100 olmalı.`);
|
|
70
116
|
// K4, K5: öğrenme çıktıları.
|
|
71
117
|
const cik = t.ciktilar ?? [];
|
|
72
|
-
if (
|
|
73
|
-
|
|
118
|
+
if (!guncel) {
|
|
119
|
+
if (cik.length < 8 || cik.length > 12)
|
|
120
|
+
hata("K5", `${cik.length} öğrenme çıktısı var, 8-12 olmalı.`);
|
|
121
|
+
}
|
|
122
|
+
else if (cik.length < GECERLI_CIKTI[0] || cik.length > GECERLI_CIKTI[1])
|
|
123
|
+
hata("K5", `${cik.length} öğrenme çıktısı var, ${GECERLI_CIKTI[0]}-${GECERLI_CIKTI[1]} olmalı (${ONERILEN_CIKTI[0]}-${ONERILEN_CIKTI[1]} önerilir).`);
|
|
124
|
+
else if (cik.length < ONERILEN_CIKTI[0] || cik.length > ONERILEN_CIKTI[1])
|
|
125
|
+
uyari("K5", `${cik.length} öğrenme çıktısı var; ${ONERILEN_CIKTI[0]}-${ONERILEN_CIKTI[1]} önerilir.`);
|
|
126
|
+
const olculemez = (m) => OLCULEMEZ.test(m) || (guncel && OLCULEMEZ_GUNCEL.test(m));
|
|
127
|
+
const fiilleBiter = (m) => (guncel ? FIILLE_BITER_GUNCEL : FIILLE_BITER).test(m);
|
|
74
128
|
cik.forEach((c, i) => {
|
|
75
129
|
if (c.kod !== `Ö${i + 1}`)
|
|
76
130
|
hata("K5", `Çıktı numaralandırması kesintili: ${i + 1}. sırada "${c.kod}" var.`);
|
|
77
131
|
if (bos(c.tr))
|
|
78
132
|
hata("K3", `${c.kod} boş.`);
|
|
79
|
-
else if (
|
|
133
|
+
else if (olculemez(c.tr) || !fiilleBiter(c.tr.trim()))
|
|
80
134
|
hata("K4", `${c.kod} ölçülebilir bir eylem fiiliyle bitmiyor: "${c.tr}"`);
|
|
81
135
|
else if (ZAYIF.test(c.tr))
|
|
82
136
|
uyari("K4", `${c.kod} "farkındalık" ifadesi ölçmesi zor. Gözlenebilir bir eylemle yazmayı düşün.`);
|
|
@@ -164,6 +218,13 @@ export function taslakDenetle(t, { bolen = 30 } = {}) {
|
|
|
164
218
|
if (ascii.length)
|
|
165
219
|
hata("Türkçe", `Türkçe karakteri düşürülmüş kelimeler: ${ascii.slice(0, 10).join(", ")}.`);
|
|
166
220
|
// CLI hataları önce, uyarıları sonra listeler; sıra korunur.
|
|
167
|
-
const
|
|
168
|
-
|
|
221
|
+
const etiketli = guncel
|
|
222
|
+
? bulgular.map((b) => ({
|
|
223
|
+
...b,
|
|
224
|
+
kuralTuru: b.kuralTuru ?? "Akredit önerisi",
|
|
225
|
+
dayanak: b.dayanak ?? TASLAK_DAYANAK.akredit,
|
|
226
|
+
}))
|
|
227
|
+
: bulgular;
|
|
228
|
+
const sirali = [...etiketli.filter((b) => b.duzey === "hata"), ...etiketli.filter((b) => b.duzey !== "hata")];
|
|
229
|
+
return { bulgular: sirali, isToplam, hedef, ...(hedefAraligi ? { hedefAraligi } : {}) };
|
|
169
230
|
}
|
|
@@ -187,4 +187,12 @@ export interface Bulgu {
|
|
|
187
187
|
/** Bulgunun konusu: ders kodu, çıktı kodu, paragraf numarası. */
|
|
188
188
|
konu?: string;
|
|
189
189
|
aciklama: string;
|
|
190
|
+
/**
|
|
191
|
+
* Kuralın dayanağının türü. "resmî" yalnız resmî belgeyle doğrulanmış kuraldır; doğrulanamayan kural resmî
|
|
192
|
+
* sayılmaz. "kurum": kurumun verdiği değer (ör. AKTS başına saat). "Akredit önerisi": iç kural.
|
|
193
|
+
*/
|
|
194
|
+
kuralTuru?: KuralTuru;
|
|
195
|
+
/** Kuralın kaynağı (belge, kod yolu ya da "DOĞRULANMADI" notu). */
|
|
196
|
+
dayanak?: string;
|
|
190
197
|
}
|
|
198
|
+
export type KuralTuru = "resmî" | "kurum" | "Akredit önerisi";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akredit/acik-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"description": "Herkese açık Akredit MCP sunucusu: hesapsız, salt okuma, deterministik araçlar (ölçüt, Bologna denetimi, ÇK/PÇ hesabı, rapor dil denetimi). Kurum verisine erişmez, model çağırmaz.",
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@akredit/baglayicilar": "0.1.0",
|
|
39
39
|
"@akredit/cekirdek": "0.1.0",
|
|
40
|
-
"@akredit/cerceveler": "0.1.0",
|
|
41
40
|
"@akredit/olcme": "0.1.0",
|
|
42
|
-
"@akredit/yz": "0.1.0"
|
|
41
|
+
"@akredit/yz": "0.1.0",
|
|
42
|
+
"@akredit/cerceveler": "0.1.0"
|
|
43
43
|
},
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public"
|