@appaflytech/zeyrek-ai-mcp 0.0.1 → 0.0.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/README.md +3 -3
- package/dist/config.js +2 -1
- package/dist/knowledge/componentCatalog.js +2 -1
- package/dist/knowledge/componentEvents.js +5 -1
- package/dist/knowledge/outlines.js +3 -2
- package/dist/resources/guides/entity.md +33 -1
- package/dist/resources/guides/page.md +5 -1
- package/dist/resources/guides/translation.md +80 -0
- package/dist/server.js +2 -0
- package/dist/tools/platformInfo.js +1 -1
- package/dist/tools/projects.js +7 -2
- package/dist/tools/translations.js +37 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# zeyrek-ai-mcp
|
|
2
2
|
|
|
3
3
|
NgApps platformunu MCP tool'ları olarak sunan bağımsız gateway — veri/mantık tarafı (project,
|
|
4
4
|
application, datasource, entity, row, microservice, query, workflow, automation, dto, view) ve
|
|
@@ -96,7 +96,7 @@ claude mcp add ngapps --transport http http://localhost:5100/mcp
|
|
|
96
96
|
stdio alternatifi (port gerekmez, sunucuyu istemci başlatır):
|
|
97
97
|
|
|
98
98
|
```bash
|
|
99
|
-
claude mcp add
|
|
99
|
+
claude mcp add zeyrek-ai -- npx tsx <repo>/zeyrek-mcp/src/index.ts --stdio
|
|
100
100
|
```
|
|
101
101
|
|
|
102
102
|
İlk doğrulama: oturumda `platform_whoami` tool'unu çağırtın — kimlik ve org çözümü tek seferde
|
|
@@ -110,7 +110,7 @@ Repoyu klonlamadan, yayınlanmış paketle. Tüm ayarlar `.mcp.json`'ın `env` b
|
|
|
110
110
|
```json
|
|
111
111
|
{
|
|
112
112
|
"mcpServers": {
|
|
113
|
-
"
|
|
113
|
+
"zeyrek-ai": {
|
|
114
114
|
"type": "stdio",
|
|
115
115
|
"command": "npx",
|
|
116
116
|
"args": ["-y", "@appaflytech/zeyrek-ai-mcp@latest", "--stdio"],
|
package/dist/config.js
CHANGED
|
@@ -20,6 +20,7 @@ export const moduleNames = [
|
|
|
20
20
|
'folder',
|
|
21
21
|
'file',
|
|
22
22
|
'access',
|
|
23
|
+
'translation',
|
|
23
24
|
'template',
|
|
24
25
|
'organization',
|
|
25
26
|
'dependency',
|
|
@@ -27,7 +28,7 @@ export const moduleNames = [
|
|
|
27
28
|
];
|
|
28
29
|
export const modulePresets = {
|
|
29
30
|
core: ['platform', 'project', 'application', 'datasource', 'entity', 'row', 'microservice', 'query', 'workflow', 'automation', 'dto', 'view', 'dependency'],
|
|
30
|
-
studio: ['platform', 'page', 'component', 'flow', 'layout', 'variable', 'folder', 'file', 'access'],
|
|
31
|
+
studio: ['platform', 'page', 'component', 'flow', 'layout', 'variable', 'folder', 'file', 'access', 'translation'],
|
|
31
32
|
admin: ['platform', 'template', 'organization', 'deployment']
|
|
32
33
|
};
|
|
33
34
|
function expandModuleNames(entries) {
|
|
@@ -328,7 +328,8 @@ export const componentKnowledge = {
|
|
|
328
328
|
behavior: [
|
|
329
329
|
"change olayında runtime machine.setLanguage(value) çağırır: seçim localStorage'a (zeyrek:{appSlug}:lang) yazılır ve çeviri bağlı bütün prop'lar SAYFA YENİLENMEDEN yeniden çözülür.",
|
|
330
330
|
'Projede dil tanımlı değilse liste boş çizilir — önce proje dillerini (Translations paneli) kur.'
|
|
331
|
-
]
|
|
331
|
+
],
|
|
332
|
+
guide: 'translation'
|
|
332
333
|
},
|
|
333
334
|
otpinput: {
|
|
334
335
|
summary: 'Tek haneli kutulardan oluşan tek kullanımlık kod girişi (2–12 hane); yapıştırma kutulara dağılır.',
|
|
@@ -71,7 +71,10 @@ export const componentEventContracts = {
|
|
|
71
71
|
// — 2026-08-25 eşleme turu: ng-apps-ui'da olay YAYAN ama burada kaydı olmayan komponentler.
|
|
72
72
|
// Yükler kaynaktaki dispatch('emit', { name, data }) / machine.onEmit(id, { event, data })
|
|
73
73
|
// çağrılarından birebir çıkarıldı. Olay yaymayan komponentler (badge · breadcrumb · jsonviewer ·
|
|
74
|
-
//
|
|
74
|
+
// progress · qrcode · slot · tags · text) bilinçli olarak kayıtsızdır. `notification` bu listede
|
|
75
|
+
// YANLIŞLIKLA yer almıştı — Notification.svelte hem timeout'ta hem kapatma tıklamasında
|
|
76
|
+
// dispatch('emit', { name:'toggled', data:{isHidden:true}, setter:true }) çağırıyor (düzeltme
|
|
77
|
+
// 2026-08-25c, `docs/20-komponent-bilgi-katmani.md` §9).
|
|
75
78
|
autocomplete: {
|
|
76
79
|
mount: NO_DATA,
|
|
77
80
|
change: valueChange('string (YAZILAN metin — option değeri değil)'),
|
|
@@ -107,6 +110,7 @@ export const componentEventContracts = {
|
|
|
107
110
|
emptystate: { actionClick: { payload: { text: 'string (aksiyonun metni)', index: 'number' }, reads: "aksiyonun kendi flow'u zaten doğrudan çalışır" } },
|
|
108
111
|
iframe: { mount: NO_DATA },
|
|
109
112
|
'language-selector': { change: { payload: { value: 'string (dil kodu)' }, reads: 'runtime ayrıca machine.setLanguage(value) çağırır' } },
|
|
113
|
+
notification: { toggled: { payload: { isHidden: 'boolean' } } },
|
|
110
114
|
otpinput: {
|
|
111
115
|
mount: NO_DATA,
|
|
112
116
|
change: valueChange('string (birleşik kod)'),
|
|
@@ -64,10 +64,11 @@ export function entityOutline(definition) {
|
|
|
64
64
|
dbType: field.dbType,
|
|
65
65
|
nullable: field.nullable,
|
|
66
66
|
relationType: field.relationType ?? 'none',
|
|
67
|
-
relationId: field.relationId ?? null
|
|
67
|
+
relationId: field.relationId ?? null,
|
|
68
|
+
isLocalized: Boolean(field.isLocalized)
|
|
68
69
|
})),
|
|
69
70
|
view: 'outline',
|
|
70
|
-
hint: "Bir alanın tam gövdesi için view:'part', part:'fields[slug=<slug>]'; değişiklik için entity_patch."
|
|
71
|
+
hint: "Bir alanın tam gövdesi için view:'part', part:'fields[slug=<slug>]'; değişiklik için entity_patch. isLocalized alanlar için platform_guide('entity') §'Çoklu dilli alan'."
|
|
71
72
|
};
|
|
72
73
|
}
|
|
73
74
|
const segmentPattern = /^(\w+)(?:\[(?:(\d+)|(\w+)=([^\]]+))\])?$/;
|
|
@@ -186,7 +186,39 @@ Girdi sınırları (`IncrementalCodeInput.TryParse`; ihlal edilirse nesne geçer
|
|
|
186
186
|
- `datasource_list.dataTypes` çıktısında bu tipi ayrı bir grup olarak görürsün; listede
|
|
187
187
|
görmezsen yine de geçerlidir (rehberdeki "dataTypes'a güvenme" uyarısı burada da geçerli).
|
|
188
188
|
|
|
189
|
-
##
|
|
189
|
+
## Çoklu dilli alan (`isLocalized`)
|
|
190
|
+
|
|
191
|
+
Bir alanı çoklu dilli yapmak için `dbType`/`commonType` değişmez — alan tanımına `"isLocalized":
|
|
192
|
+
true` eklenir (`FieldDto.IsLocalized`, generic `definition` içinde geçer, gateway'de ayrı bir
|
|
193
|
+
parametre YOKTUR). Kısıt (`FieldDtoValidator`): `isLocalized: true` iken `primaryKey` · `identity`
|
|
194
|
+
· `unique` `false` olmalı ve `relationType: 'none'` olmalı — bunlardan biri doluysa platform
|
|
195
|
+
reddeder.
|
|
196
|
+
|
|
197
|
+
**Platform bunun için ayrı bir uç açmaz.** Bir entity'de `isLocalized` alanı olduğunda (create ya
|
|
198
|
+
da update'te) platform otomatik olarak `{entity_slug}_localization` adlı **companion bir entity**
|
|
199
|
+
kurar/genişletir:
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
id Guid, PK, identity
|
|
203
|
+
{entity_slug}_{parent_pk_slug} RELATION (one-to-many → ana entity, otomatik FK)
|
|
204
|
+
language Text
|
|
205
|
+
...isLocalized:true olan alanlar (ana tanımdan BİREBİR taşınır)
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
artı `(relation, language)` üzerinde unique index. Yani bir satırın Türkçe/İngilizce değerleri
|
|
209
|
+
**ayrı satırlardır**, ana tabloda değil bu companion entity'de yaşar.
|
|
210
|
+
|
|
211
|
+
**Kullanım (tamamı mevcut genel araçlarla, yeni tool GEREKMEZ):**
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
1. entity_get (ana entity, view:'outline') → isLocalized alanları görürsün
|
|
215
|
+
2. entity_list (aynı datasource) → "{slug}_localization" entity'sini bul, id'sini al
|
|
216
|
+
3. row_create/row_update (companion entity) → { "<fk_slug>": "<ana satır id>", "language": "tr", "<alan_slug>": "..." }
|
|
217
|
+
4. row_list (companion entity, filtre yok — selectedFields ile daralt) → dile göre satırları oku
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
`{fk_slug}` companion entity'nin `entity_get`'inde görünen ilişki alanının slug'ıdır (ana entity
|
|
221
|
+
adından türetilir); satırı elle kurmadan önce mutlaka `entity_get` ile doğrula, tahmin etme.
|
|
190
222
|
|
|
191
223
|
```jsonc
|
|
192
224
|
// GUID anahtar
|
|
@@ -74,6 +74,10 @@ mümkündür ama doğrulama duvarı ve canlı canvas yalnız `page_schema_patch`
|
|
|
74
74
|
`Data = RedirectPage.Slug`). Sabit `'/hastalar'` yazarsan sayfa slug'ı değişince bağlantı
|
|
75
75
|
sessizce kırılır; `pageId` referansı değişiklikten etkilenmez. Aynısı `flow` prop'u için
|
|
76
76
|
`type: 'flow'` + `ref: <flowId>`, dosya için `type: 'file'` + `ref: <fileId>`.
|
|
77
|
+
- **Çoklu dilli metin için `type: 'translation'` + `ref: <çeviri anahtarı>`.** Runtime `data`'yı
|
|
78
|
+
her turda çözümlenmiş metinle EZER — anahtar yalnız `ref`'te yaşar, `data`'ya yazıp
|
|
79
|
+
güvenme (`code` prop'uyla aynı davranış). Tam şekil, fallback zinciri ve `translation_*`
|
|
80
|
+
tool'ları için `platform_guide('translation')`.
|
|
77
81
|
- **`blocks[].size`, komponentin `component_get`'teki `maxSize`'ını aşamaz.** Dikkat: katalog
|
|
78
82
|
varsayılanı aşabiliyor (`page-header` default `h:8`, `maxSize` `h:4`) — varsayılanı körü körüne
|
|
79
83
|
kopyalama, doğrulayıcı `"Height of 'page-header' must be between 1 and 4."` ile reddeder.
|
|
@@ -1339,7 +1343,7 @@ bağlanır, filtre `source:'expression'` + `value:'user.id'` olur.
|
|
|
1339
1343
|
| Kart görünümü | `card` — **kapsayıcı DEĞİLDİR**, çocuk kabul etmez (`not-droppable`) ve yüksekliği 10-50 aralığındadır. Kutu içinde serbest içerik için `container` kullan. |
|
|
1340
1344
|
| Katman | `modal` · `drawer` (şema kökünde — Kural 1d) |
|
|
1341
1345
|
| Geri bildirim | `notification` (sayfa içi kutu) · `toast` (geçici bildirim; isOpen yükselen kenarı) · `form-validation-errors` · `confirm-bar` · `result` (işlem sonucu ekranı) · `emptystate` (boş liste; ikon YA DA görsel + aksiyon düğmeleri) |
|
|
1342
|
-
| Gezinme / başlık | `breadcrumb` · `breadcrumb-title` (başlık + daralan iz) · `page-header` · `header` · `sidebar` · `auth-layout` · `language-selector` (dil değiştirici) |
|
|
1346
|
+
| Gezinme / başlık | `breadcrumb` · `breadcrumb-title` (başlık + daralan iz) · `page-header` · `header` · `sidebar` · `auth-layout` · `language-selector` (dil değiştirici — çoklu dil kurulumu `platform_guide('translation')`) |
|
|
1343
1347
|
| Sunum | `text` · `html` · `image` · `video` · `icon` · `qrcode` · `tags` · `avatar` · `badge` (sayaç “99+” / nokta / durum metni) · `carousel` · `iframe` (sandbox’lı gömme) · `jsonviewer` (katlanabilir JSON; JSON METNİNİ de parse eder) · `audit-basic` · `audit-history` |
|
|
1344
1348
|
|
|
1345
1349
|
> **`chart` komponenti VAR (2026-08-25 ölçümü) — bu satır düzeltildi.** Rehberin önceki hâli
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Çoklu Dil Rehberi (page/content translations)
|
|
2
|
+
|
|
3
|
+
Sayfa içeriğini (metin, buton etiketi, placeholder…) çoklu dilli yapan özellik. Studio panelinin
|
|
4
|
+
kendi arayüz dili (`i18n.md`, yalnız frontend'i ilgilendirir) ile **karıştırma** — bu rehber
|
|
5
|
+
**son kullanıcının gördüğü sayfa metnini** kapsar. Kaynak: `TranslationsController.cs`
|
|
6
|
+
(`zeyrek-backend/src/NgApps.Tenant.API/Controllers/`) + `zeyrek-frontend/docs/features/page-translations.md`.
|
|
7
|
+
|
|
8
|
+
## Model
|
|
9
|
+
|
|
10
|
+
- Çeviri kaydı **application başına** tutulur (`(applicationId, language, key)` başına bir satır);
|
|
11
|
+
aynı application'daki tüm sayfalar aynı anahtar kümesini paylaşır.
|
|
12
|
+
- Bir kayıt isteğe bağlı bir **`componentId`**'ye bağlanabilir — o komponent silinince kaydı da
|
|
13
|
+
kademeli silinir. Salt organizasyon amaçlıdır; runtime çözümlemeyi etkilemez (çözümleme yalnız
|
|
14
|
+
`key`'e bakar).
|
|
15
|
+
- Proje **dilleri** ve **varsayılan dil** application değil **proje** düzeyinde ayardır
|
|
16
|
+
(`project_get`/`project_update` `languages`/`defaultLanguage`) ve tam **ISO 639-1** kod
|
|
17
|
+
kümesinden seçilir (`ProjectConstants.SupportedLanguages`, ~184 kod). `translation_update`'e
|
|
18
|
+
proje dillerinde olmayan bir kod verirsen platform isteği reddeder — önce `project_update` ile
|
|
19
|
+
dili ekle.
|
|
20
|
+
|
|
21
|
+
## Araçlar
|
|
22
|
+
|
|
23
|
+
| Tool | Ne yapar |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `translation_list` | Application'ın tüm `(language, key, value)` kayıtlarını düz liste döner |
|
|
26
|
+
| `translation_update` | `keys` (ekle/güncelle, `componentId` opsiyonel) ve/veya `deletedKeys` (sil) — ikisi de aynı çağrıda verilebilir, en az biri dolu olmalı |
|
|
27
|
+
| `project_update` | `languages`/`defaultLanguage` — proje dillerini kurar/değiştirir |
|
|
28
|
+
|
|
29
|
+
```jsonc
|
|
30
|
+
// yeni anahtar aç / var olanı güncelle
|
|
31
|
+
{ "applicationId": "<app id>", "keys": [
|
|
32
|
+
{ "key": "home.welcome", "values": { "tr": "Hoş geldiniz", "en": "Welcome" } }
|
|
33
|
+
] }
|
|
34
|
+
|
|
35
|
+
// bir anahtarı sil, bir başkasını aynı çağrıda güncelle
|
|
36
|
+
{ "applicationId": "<app id>",
|
|
37
|
+
"keys": [{ "key": "home.title", "values": { "tr": "Ana sayfa" } }],
|
|
38
|
+
"deletedKeys": ["home.old_banner"] }
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Bir prop'u çeviriye bağlamak
|
|
42
|
+
|
|
43
|
+
Sayfa şemasında (`platform_guide('page')` Kural 1) çeviriye bağlı bir prop **Prop nesnesinin**
|
|
44
|
+
`type:'translation'` varyantıdır — `PropValueType.Translation` (`DesignComponentProperty.cs`)
|
|
45
|
+
backend'de zaten tanımlı, Studio'nun "Translate" aksiyonunun ürettiği şekil budur:
|
|
46
|
+
|
|
47
|
+
```jsonc
|
|
48
|
+
{ "op": "replace_prop", "target": "welcome_text", "prop": "text",
|
|
49
|
+
"value": { "type": "translation", "ref": "home.welcome", "data": "Hoş geldiniz" } }
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
- **Anahtar `ref`'tedir, `data` DEĞİL.** Runtime her `getNodeProps` turunda `data`'yı
|
|
53
|
+
`resolveTranslation(...)` sonucuyla EZER (`code` prop'larıyla aynı davranış — `page.md` Kural 1c
|
|
54
|
+
bunun `code` karşılığını anlatır). `ref`'i okumadan/yazmadan `data`'ya güvenme; `data` yalnız
|
|
55
|
+
Studio'nun sakladığı önceki statik değerdir (fallback/geri dönüş amaçlı, çözümlemeyi ETKİLEMEZ).
|
|
56
|
+
- **Fallback zinciri:** aktif dil → projenin varsayılan dili → anahtarın kendisi. Boş string de
|
|
57
|
+
"eksik" sayılır ve zincirde bir alt basamağa düşer — bir anahtar hiçbir zaman boş render olmaz.
|
|
58
|
+
- Hangi prop'lar çeviriye bağlanabilir platformca kısıtlanmaz (Studio'da yalnız `text`/`long-text`
|
|
59
|
+
tipli prop'larda "Translate" aksiyonu gösterilir, ama şema düzeyinde her static prop aynı Prop
|
|
60
|
+
şeklini kabul eder).
|
|
61
|
+
|
|
62
|
+
## Dil değiştirme: `language-selector`
|
|
63
|
+
|
|
64
|
+
Son kullanıcı dili `language-selector` komponentiyle değiştirir (`platform_guide('component')`
|
|
65
|
+
+ `componentCatalog` içindeki `language-selector` kaydı): `change` olayı `machine.setLanguage(value)`
|
|
66
|
+
çağırır, seçim `localStorage`'a (`zeyrek:{appSlug}:lang`) yazılır ve çeviriye bağlı **bütün**
|
|
67
|
+
prop'lar sayfa yenilenmeden yeniden çözülür — ayrı bir akış kurmana gerek yok, komponenti sayfaya
|
|
68
|
+
eklemen yeterli. Projede dil tanımlı değilse (`languages` boşsa) liste boş çizilir.
|
|
69
|
+
|
|
70
|
+
## Bilinen sınırlar
|
|
71
|
+
|
|
72
|
+
- **Flow adımlarında Translation kaynağı YOK.** `value.type` sözlüğünde (`platform_guide('page')`
|
|
73
|
+
Kural 1c sonundaki tablo) `translation` yoktur — bir flow adımının **değerini** doğrudan bir
|
|
74
|
+
çeviri anahtarına bağlayamazsın, yalnız sayfa şemasındaki statik prop'lar bağlanabilir. İfadeden
|
|
75
|
+
okumak gerekiyorsa `t('anahtar')` Jexl fonksiyonu kullanılır (`platform_guide('expressions')`).
|
|
76
|
+
- **Runtime sayfa yanıtı sunucu tarafında önbelleklidir** (Postgres `caches` tablosu). Bir
|
|
77
|
+
`translation_update`/`project_update(languages)` çağrısından hemen sonra `page_runtime_get`
|
|
78
|
+
eski değerleri gösterebilir — önbellek süresi dolana kadar. Acil doğrulama gerekiyorsa
|
|
79
|
+
`translation_list` ile yazma tarafını, `page_runtime_get` ile okuma tarafını AYRI doğrula.
|
|
80
|
+
- Mobil runtime (`apps/mobile`) bu özelliği henüz beslemiyor — yalnız web.
|
package/dist/server.js
CHANGED
|
@@ -11,6 +11,7 @@ import { registerTemplateTools } from './tools/templates.js';
|
|
|
11
11
|
import { registerWorkflowTools } from './tools/workflows.js';
|
|
12
12
|
import { registerLayoutTools } from './tools/layouts.js';
|
|
13
13
|
import { registerAccessTools } from './tools/access.js';
|
|
14
|
+
import { registerTranslationTools } from './tools/translations.js';
|
|
14
15
|
import { registerFlowTools } from './tools/flows.js';
|
|
15
16
|
import { registerKnowledgeResources } from './resources/knowledge.js';
|
|
16
17
|
import { registerSchemaResources } from './resources/schemas.js';
|
|
@@ -47,6 +48,7 @@ const moduleRegistrations = {
|
|
|
47
48
|
folder: registerFolderTools,
|
|
48
49
|
file: registerFileTools,
|
|
49
50
|
access: registerAccessTools,
|
|
51
|
+
translation: registerTranslationTools,
|
|
50
52
|
template: registerTemplateTools,
|
|
51
53
|
organization: registerOrganizationTools,
|
|
52
54
|
dependency: registerDependencyTools,
|
|
@@ -13,7 +13,7 @@ export function registerPlatformTools(server, platform) {
|
|
|
13
13
|
}, handle(config, () => platform.org('GET', '/connect/userinfo')));
|
|
14
14
|
server.registerTool('platform_guide', {
|
|
15
15
|
title: 'Platform rehberi oku',
|
|
16
|
-
description: "Modülün iş kuralları rehberini döner (workflow, microservice, entity, page, component, html, middleware, view, expressions, getting-started, modify-existing). Bir modülde İLK yazma işleminden önce ilgili rehberi okuyun; sayfa/layout/flow işleri için page, komponent modeli/olay sözleşmeleri için component, hazır komponentler yetmediğinde HTML kaçış kapısı (Mustache, fireEvent, script kuralları) için html, auth/oturum/yetki için middleware, tam metin arama indeksi için view, ifade yazarken kullanılabilir fonksiyon/bağlam sözlüğü (system.*, file.*, Page.*, state.*, Steps…) için expressions rehberi. Örnek gövdeler için ngapps://examples kaynaklarına bakın.",
|
|
16
|
+
description: "Modülün iş kuralları rehberini döner (workflow, microservice, entity, page, component, html, middleware, view, expressions, translation, getting-started, modify-existing). Bir modülde İLK yazma işleminden önce ilgili rehberi okuyun; sayfa/layout/flow işleri için page, komponent modeli/olay sözleşmeleri için component, hazır komponentler yetmediğinde HTML kaçış kapısı (Mustache, fireEvent, script kuralları) için html, auth/oturum/yetki için middleware, tam metin arama indeksi için view, ifade yazarken kullanılabilir fonksiyon/bağlam sözlüğü (system.*, file.*, Page.*, state.*, Steps…) için expressions, sayfa/içerik çevirileri (çoklu dil) için translation rehberi. Örnek gövdeler için ngapps://examples kaynaklarına bakın.",
|
|
17
17
|
inputSchema: {
|
|
18
18
|
guide: z.string().describe('Rehber adı; bilinmeyen ad verilirse mevcut rehberler listelenir')
|
|
19
19
|
},
|
package/dist/tools/projects.js
CHANGED
|
@@ -79,12 +79,14 @@ export function registerProjectTools(server, platform) {
|
|
|
79
79
|
}));
|
|
80
80
|
server.registerTool('project_update', {
|
|
81
81
|
title: 'Proje güncelle',
|
|
82
|
-
description: 'Proje adını, slug\'
|
|
82
|
+
description: 'Proje adını, slug\'ını, temasını ve dil ayarlarını günceller. languages/defaultLanguage verilmezse mevcut değerlerine dokunulmaz. LoaderImage bu tool\'da desteklenmez.',
|
|
83
83
|
inputSchema: {
|
|
84
84
|
id: guid,
|
|
85
85
|
name: z.string().min(1),
|
|
86
86
|
slug: z.string().optional(),
|
|
87
|
-
theme: z.string().optional()
|
|
87
|
+
theme: z.string().optional(),
|
|
88
|
+
languages: z.array(z.string().min(1)).min(1).optional().describe('ISO 639-1 kod listesi (proje dilleri); sayfa çevirileri bu kodlarla doğrulanır'),
|
|
89
|
+
defaultLanguage: z.string().min(1).optional().describe("languages içinde olmalı — proje dilleri hiç kurulmadıysa (ilk kurulumda) tek başına verilebilir")
|
|
88
90
|
},
|
|
89
91
|
annotations: updates
|
|
90
92
|
}, handle(config, args => {
|
|
@@ -93,6 +95,9 @@ export function registerProjectTools(server, platform) {
|
|
|
93
95
|
form.set('Slug', args.slug);
|
|
94
96
|
if (args.theme)
|
|
95
97
|
form.set('Theme', args.theme);
|
|
98
|
+
args.languages?.forEach(language => form.append('Languages', language));
|
|
99
|
+
if (args.defaultLanguage)
|
|
100
|
+
form.set('DefaultLanguage', args.defaultLanguage);
|
|
96
101
|
return platform.org('PUT', `/projects/${args.id}`, { form });
|
|
97
102
|
}));
|
|
98
103
|
server.registerTool('project_delete', {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { guid, projectParam, environmentParam, readOnly, updates } from './common.js';
|
|
2
|
+
import { handle } from '../platform/responses.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
const translationKeyInput = z.object({
|
|
5
|
+
key: z.string().min(1),
|
|
6
|
+
values: z.record(z.string()).describe("Dil kodu (ISO 639-1) → çeviri metni; kodlar projenin languages listesinde (project_get/project_update) tanımlı olmalı"),
|
|
7
|
+
componentId: guid.optional().describe("Çeviriyi belirli bir komponente bağlar; o komponent silinince kaydı da silinir")
|
|
8
|
+
});
|
|
9
|
+
export function registerTranslationTools(server, platform) {
|
|
10
|
+
const config = platform.config;
|
|
11
|
+
server.registerTool('translation_list', {
|
|
12
|
+
title: 'Çevirileri listele',
|
|
13
|
+
description: "Application'ın tüm çeviri kayıtlarını (dil × anahtar × değer) düz liste olarak döner. Proje dilleri/varsayılan dil için project_get; sayfada bir prop'u çeviriye bağlamak için platform_guide('translation').",
|
|
14
|
+
inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid },
|
|
15
|
+
annotations: readOnly
|
|
16
|
+
}, handle(config, ({ project, environment, applicationId }) => platform.tenant('GET', project, `/translations/${applicationId}`, { environment })));
|
|
17
|
+
server.registerTool('translation_update', {
|
|
18
|
+
title: 'Çevirileri güncelle',
|
|
19
|
+
description: "Bir ya da daha çok çeviri anahtarını toplu ekler/günceller (keys) ve/veya siler (deletedKeys) — tek çağrıda ikisi de verilebilir. 'keys' üzerinden yeni bir anahtar da açılabilir (upsert). 'values'taki dil kodları projenin languages listesinde tanımlı olmalı, aksi hâlde platform reddeder.",
|
|
20
|
+
inputSchema: {
|
|
21
|
+
project: projectParam,
|
|
22
|
+
environment: environmentParam,
|
|
23
|
+
applicationId: guid,
|
|
24
|
+
keys: z.array(translationKeyInput).optional().describe('Eklenecek/güncellenecek anahtarlar'),
|
|
25
|
+
deletedKeys: z.array(z.string().min(1)).optional().describe('Silinecek anahtar adları')
|
|
26
|
+
},
|
|
27
|
+
annotations: updates
|
|
28
|
+
}, handle(config, ({ project, environment, applicationId, keys, deletedKeys }) => {
|
|
29
|
+
if (!keys?.length && !deletedKeys?.length) {
|
|
30
|
+
throw new Error("'keys' ya da 'deletedKeys' parametrelerinden en az biri dolu olmalı.");
|
|
31
|
+
}
|
|
32
|
+
return platform.tenant('PUT', project, `/translations/${applicationId}`, {
|
|
33
|
+
environment,
|
|
34
|
+
body: { keys: keys ?? [], deletedKeys: deletedKeys ?? [] }
|
|
35
|
+
});
|
|
36
|
+
}));
|
|
37
|
+
}
|