@appaflytech/zeyrek-ai-mcp 0.0.7 → 0.0.9

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 (54) hide show
  1. package/README.md +27 -21
  2. package/dist/config.js +2 -0
  3. package/dist/knowledge/backendConstraints.js +3 -0
  4. package/dist/knowledge/componentCatalog.js +172 -33
  5. package/dist/knowledge/componentEvents.js +35 -4
  6. package/dist/knowledge/errorPath.js +1 -1
  7. package/dist/knowledge/normalize.js +474 -23
  8. package/dist/knowledge/propTypes.js +5 -4
  9. package/dist/knowledge/rules.js +113 -6
  10. package/dist/knowledge/styleResolve.js +52 -5
  11. package/dist/knowledge/themeResolve.js +936 -0
  12. package/dist/knowledge/themeRules.js +221 -0
  13. package/dist/knowledge/themeSchema.js +335 -0
  14. package/dist/platform/domSummary.js +144 -0
  15. package/dist/platform/http.js +10 -2
  16. package/dist/platform/screenshot.js +492 -29
  17. package/dist/platform/screenshotMemory.js +55 -0
  18. package/dist/platform/strictArguments.js +32 -0
  19. package/dist/platform/writeDiff.js +6 -3
  20. package/dist/resources/examples/layout-app-shell.json +1 -1
  21. package/dist/resources/examples/page-sign-in.json +1 -1
  22. package/dist/resources/examples/theme-brand.json +162 -0
  23. package/dist/resources/guides/component.md +8 -2
  24. package/dist/resources/guides/expressions.md +6 -0
  25. package/dist/resources/guides/getting-started.md +6 -0
  26. package/dist/resources/guides/layout.md +36 -26
  27. package/dist/resources/guides/microservice.md +160 -6
  28. package/dist/resources/guides/page.md +165 -59
  29. package/dist/resources/guides/theme.md +210 -0
  30. package/dist/resources/guides/translation.md +13 -10
  31. package/dist/resources/guides/workflow.md +141 -7
  32. package/dist/resources/schema-fingerprint.json +2 -2
  33. package/dist/resources/schemas/CreateMicroserviceCommand.json +4 -1
  34. package/dist/resources/schemas/CreateWorkflowCommand.json +4 -1
  35. package/dist/resources/schemas/PreviewMicroserviceCommand.json +4 -1
  36. package/dist/resources/schemas/PreviewWorkflowCommand.json +4 -1
  37. package/dist/resources/schemas/StepDto.json +4 -1
  38. package/dist/resources/schemas/UpdateMicroserviceCommand.json +4 -1
  39. package/dist/resources/schemas/UpdateWorkflowCommand.json +4 -1
  40. package/dist/server.js +52 -42
  41. package/dist/tools/components.js +8 -0
  42. package/dist/tools/designSchemaPatch.js +152 -0
  43. package/dist/tools/flows.js +24 -21
  44. package/dist/tools/layouts.js +8 -8
  45. package/dist/tools/microservices.js +74 -10
  46. package/dist/tools/pages.js +275 -332
  47. package/dist/tools/projects.js +66 -9
  48. package/dist/tools/queries.js +72 -6
  49. package/dist/tools/schemaOps.js +280 -0
  50. package/dist/tools/screenWrite.js +2 -1
  51. package/dist/tools/screens.js +0 -7
  52. package/dist/tools/themes.js +163 -0
  53. package/dist/tools/workflows.js +10 -6
  54. package/package.json +1 -1
@@ -76,6 +76,8 @@ const executeInput = {
76
76
  query: z.record(z.unknown()).optional(),
77
77
  body: z.union([z.record(z.unknown()), z.array(z.record(z.unknown()))]).optional()
78
78
  .describe('İstek gövdesi: tek nesne ya da nesne dizisi (bulk uçlar için)'),
79
+ parameters: z.record(z.unknown()).optional()
80
+ .describe("Ucun çağrı parametreleri (ad → değer) — query kaynaklı ucun sorgu parametreleri ve tablo ucunun filtreleri. Platform değeri body → query-string → header sırasıyla arar; gateway GET/DELETE'te query-string'e, POST/PUT'ta gövdeye koyar ve nereye koyduğunu gatewayNormalized ile söyler. Aynı ad 'query'/'body'de FARKLI değerle de verilirse çağrı gönderilmez. Boş string platformda NULL'a çevrilir."),
79
81
  headers: z.record(z.string()).optional().describe("İsteğe eklenecek header'lar. 'Authorization' verirseniz gateway KENDİ token'ını KOYMAZ — istek tamamen sizin kimliğinizle gider (middleware'li uçları üye token'ıyla test etmenin yolu budur)"),
80
82
  anonymous: z.boolean().optional().describe("true: istek HİÇBİR Authorization header'ı olmadan gider — 'korumalı uç tokensız ne döner?' sorusunun cevabı budur (korumalı uçtan 401, anonim uçtan 200 beklenir). Gateway normalde her çağrıya kendi token'ını koyduğu için bu bayrak olmadan anonim erişim testi yapılamaz."),
81
83
  asUser: asUserParam,
@@ -133,6 +135,56 @@ async function middlewareChain(platform, project, environment, application, micr
133
135
  return { middlewareNote: `Middleware zinciri çözülemedi: ${error instanceof Error ? error.message : String(error)}. Uca bağlı middleware'leri microservice_get ile okuyabilirsiniz.` };
134
136
  }
135
137
  }
138
+ /**
139
+ * G-13 — üst düzey `parameters` isteğin platformun okuduğu yerine bağlanır.
140
+ *
141
+ * Platform çağrı parametresini `MicroserviceExecuteParameter.FindValue` ile body → query-string →
142
+ * header sırasıyla arar. GET/DELETE isteğinde gövde taşınmadığı için değer query-string'e, yazan
143
+ * yöntemde gövdeye (tek nesne) konur; gövdede tipi (sayı, bool) korunur. Aynı ad çağrıda iki
144
+ * farklı değerle geldiğinde hangisinin kazanacağını tahmin ettirmek yerine istek gönderilmez.
145
+ */
146
+ function bindCallParameters(method, parameters, query, body, notes) {
147
+ const names = Object.keys(parameters ?? {});
148
+ if (parameters === undefined || names.length === 0)
149
+ return { query, body };
150
+ const intoQuery = method === 'GET' || method === 'DELETE';
151
+ if (!intoQuery && Array.isArray(body)) {
152
+ throw new PlatformApiError(`parameters (${names.join(', ')}) ${method} isteğinde gövdeye bağlanır, ama body bir DİZİ (bulk). Platform parametreyi yalnız gövdenin İLK öğesinden okur — değerleri body[0]'a yazın ya da parameters'ı kaldırın.`, 400);
153
+ }
154
+ const target = (intoQuery ? query : body) ?? {};
155
+ const conflicts = names.filter(name => name in target && JSON.stringify(target[name]) !== JSON.stringify(parameters[name]));
156
+ if (conflicts.length > 0) {
157
+ throw new PlatformApiError(`parameters ile ${intoQuery ? 'query' : 'body'} aynı adı farklı değerle taşıyor: ${conflicts.map(name => `'${name}'`).join(', ')}. Değeri tek yerde verin.`, 400);
158
+ }
159
+ const merged = { ...target, ...parameters };
160
+ notes.push(`parameters ${intoQuery ? "query-string'e" : 'gövdeye'} bağlandı (${method}): ${names.join(', ')}`);
161
+ return intoQuery ? { query: merged, body } : { query, body: merged };
162
+ }
163
+ /**
164
+ * Debug ağacında query düğümünün parametre satırı değer NULL bağlandığında `value` taşır ama
165
+ * gateway yanıtı `prune` ile null alanlardan temizlediği için satır ANAHTARSIZ görünür — G-13'te
166
+ * kökü veren tek iz bu yokluktu. Yokluğu okumak zorunda kalmamak için satırlar adıyla listelenir.
167
+ */
168
+ function unboundQueryParameters(value, into = []) {
169
+ if (Array.isArray(value)) {
170
+ for (const entry of value)
171
+ unboundQueryParameters(entry, into);
172
+ return into;
173
+ }
174
+ if (!value || typeof value !== 'object')
175
+ return into;
176
+ const node = value;
177
+ if (node.type === 'query' && Array.isArray(node.input)) {
178
+ for (const row of node.input) {
179
+ if (row?.source === 'query' && row.member === 'parameter' && (row.value === null || row.value === undefined || row.value === '')) {
180
+ into.push({ step: String(node.name ?? '(adsız query)'), parameter: String(row.expression ?? '') });
181
+ }
182
+ }
183
+ }
184
+ for (const entry of Object.values(node))
185
+ unboundQueryParameters(entry, into);
186
+ return into;
187
+ }
136
188
  function executePath(prefix, application, microservice, routeParams) {
137
189
  const routeSuffix = routeParams && routeParams.length > 0
138
190
  ? `/${routeParams.map(encodeURIComponent).join('/')}`
@@ -325,25 +377,37 @@ export function registerMicroserviceTools(server, platform) {
325
377
  description: "Kayıtlı microservice'i gerçek runtime yolundan çalıştırır (POST /{project}/m/{application}/{microservice SLUG'ı}). Dönen httpStatus microservice'in kendi sonucudur (hata da geçerli çıktıdır); beklenmedik sonuçta microservice_debug ile adım adım inceleyin. Anonim erişim testi için anonymous: true. Yanıt 'headers' alanında platformun döndüğü header'ları taşır (küçük harf; ör. headers['total-count'] — sayfalı tablo akışlarının okuduğu sözleşme; set-cookie/authorization elenir).",
326
378
  inputSchema: executeInput,
327
379
  annotations: writes
328
- }, handle(config, async ({ project, environment, application, microservice, method, routeParams, query, body, headers, anonymous, asUser, cookies, language }) => {
380
+ }, handle(config, async ({ project, environment, application, microservice, method, routeParams, query, body, parameters, headers, anonymous, asUser, cookies, language }) => {
329
381
  const notes = [];
330
382
  const requestHeaders = { ...runIdentity(anonymous, asUser, cookies, headers), ...languageHeader(language, notes) };
331
- return withNormalization(await platform.tenantRaw(method, project, executePath('m', application, microservice, routeParams), { environment, query, body, headers: requestHeaders, anonymous, mirrorAuthorizationCookie: true }), notes);
383
+ const bound = bindCallParameters(method, parameters, query, body, notes);
384
+ return withNormalization(await platform.tenantRaw(method, project, executePath('m', application, microservice, routeParams), { environment, query: bound.query, body: bound.body, headers: requestHeaders, anonymous, mirrorAuthorizationCookie: true }), notes);
332
385
  }));
333
386
  server.registerTool('microservice_debug', {
334
387
  title: 'Microservice debug',
335
- description: "Microservice'i debug modunda çalıştırır; yanıtta adım adım executionItems ağacı döner (her adımın girdi/çıktısı). executionItems YALNIZ ucun kendi adımlarını kapsar — ucun ÖNÜNDE koşan middleware'ler ayrıca 'middlewares' alanında adım özetiyle listelenir (09-04 Y-04).",
388
+ description: "Microservice'i debug modunda çalıştırır; yanıtta adım adım executionItems ağacı döner (her adımın girdi/çıktısı). executionItems YALNIZ ucun kendi adımlarını kapsar — ucun ÖNÜNDE koşan middleware'ler ayrıca 'middlewares' alanında adım özetiyle listelenir (09-04 Y-04). Değeri NULL bağlanan query parametreleri 'unboundParameters' alanında adıyla listelenir (ağaçta bu satırların value anahtarı görünmez). Preview semantiğiyle koşar: tek transaction + sonunda rollback, kalıcı satır yazmaz. httpStatus akışın kendi sonucudur (4xx/5xx'te runtimeErrors eklenir); ağaç düğümlerinde hata bayrağı YOKTUR — patlayan adımın output'u boştur, hata gövdesi hata dalındaki response adımının çıktısındadır. Zamanlanmış (schedule-job) uçlar da slug yoluyla debug edilir (method: 'POST', parametresiz): job geçmişi hatayı yalnız mesaj olarak yazar, adım adım girdi/çıktı burada görülür (platform_guide('microservice') §Zamanlanmış işin gerçek sonucunu görmek).",
336
389
  inputSchema: executeInput,
337
390
  annotations: writes
338
- }, handle(config, async ({ project, environment, application, microservice, method, routeParams, query, body, headers, anonymous, asUser, cookies, language }) => {
391
+ }, handle(config, async ({ project, environment, application, microservice, method, routeParams, query, body, parameters, headers, anonymous, asUser, cookies, language }) => {
339
392
  const notes = [];
340
393
  const requestHeaders = { ...runIdentity(anonymous, asUser, cookies, headers), ...languageHeader(language, notes) };
341
- const payload = await platform.tenantRaw(method, project, executePath('debug', application, microservice, routeParams), { environment, query, body, headers: requestHeaders, anonymous, mirrorAuthorizationCookie: true });
342
- return withNormalization({ ...payload, ...await middlewareChain(platform, project, environment, application, microservice, payload?.httpStatus) }, notes);
394
+ const bound = bindCallParameters(method, parameters, query, body, notes);
395
+ const payload = await platform.tenantRaw(method, project, executePath('debug', application, microservice, routeParams), { environment, query: bound.query, body: bound.body, headers: requestHeaders, anonymous, mirrorAuthorizationCookie: true });
396
+ const unbound = unboundQueryParameters(payload.body);
397
+ return withNormalization({
398
+ ...payload,
399
+ ...(unbound.length > 0
400
+ ? {
401
+ unboundParameters: unbound,
402
+ unboundParametersNote: "Bu query parametreleri NULL bağlandı: çağrıda yoklar ya da değerleri boş string'di (platform boş string'i NULL'a çevirir). Parametreyi 'parameters' (ya da GET'te 'query', POST/PUT'ta 'body') ile verin; ad sorgunun parametre adıyla birebir aynı olmalı."
403
+ }
404
+ : {}),
405
+ ...await middlewareChain(platform, project, environment, application, microservice, payload.httpStatus)
406
+ }, notes);
343
407
  }));
344
408
  server.registerTool('microservice_preview', {
345
409
  title: 'Microservice önizle',
346
- description: "Microservice tanımını çalıştırır: kaydedilmemiş gövde için definition, KAYITLI bir uç için yalnız id verin (gateway tanımı kendisi çeker — tam gövdeyi bağlama almanız gerekmez). previewParameters ayrı alandır ve ikisiyle de çalışır. Preview tek transaction'da koşar ve sonunda ROLLBACK edilir — kalıcı satır yazmaz; code step'teki dış HTTP çağrıları istisnadır. Davranış kuralları: platform_guide('microservice').",
410
+ description: "Microservice tanımını çalıştırır: kaydedilmemiş gövde için definition, KAYITLI bir uç için yalnız id verin (gateway tanımı kendisi çeker — tam gövdeyi bağlama almanız gerekmez). previewParameters ayrı alandır ve ikisiyle de çalışır. Preview tek transaction'da koşar ve sonunda ROLLBACK edilir — kalıcı satır yazmaz; code step'teki dış HTTP çağrıları istisnadır. Yanıt httpStatus (akışın KENDİ sonucu; 4xx/5xx'te gateway runtimeErrors ekler) + gövdeden ibarettir, adım ağacı DÖNMEZ — adım adım girdi/çıktı için microservice_debug, adım başına hata alanı için workflow_preview. Zamanlanmış (schedule-job) ucu id ile parametresiz önizleyin: zamanlanmış koşu da girdisiz koşar. Davranış kuralları: platform_guide('microservice').",
347
411
  inputSchema: {
348
412
  project: projectParam,
349
413
  environment: environmentParam,
@@ -383,7 +447,7 @@ export function registerMicroserviceTools(server, platform) {
383
447
  }));
384
448
  server.registerTool('microservice_job_history', {
385
449
  title: 'Job geçmişi',
386
- description: 'Zamanlanmış (job tipli) microservice\'in çalışma geçmişini listeler. status ile yalnız running | completed | failed koşular süzülür; order TriggeredAt | CompletedAt | ExecutionStatus | DurationMs.',
450
+ description: "Zamanlanmış (schedule-job) microservice'in çalışma geçmişini listeler: satır başına { status: running | completed | failed, triggeredAt, completedAt, durationMs, errorMessage }. failed satırın errorMessage'ı patlayan adımı ve sebebini taşır: bağlanmamış fail dalında \"Step 'x' failed: <sebep>\", bağlı global-error dalıyla 2xx dışı sonuçta \"The job's workflow returned 500 (<code>): <mesaj>\"; iki durumda da yazmalar geri alınmıştır (2026-09-16 öncesi imajlar bu ikisini completed yazardı). completed = akış 2xx ile bitti ve yazmalar commit edildi. Adım adım girdi/çıktı burada YOK: aynı akışı workflow_preview (adım başına hata alanı) ya da microservice_debug (executionItems) ile koşturun — platform_guide('microservice') §Zamanlanmış işin gerçek sonucunu görmek. status ile yalnız running | completed | failed koşular süzülür; order TriggeredAt | CompletedAt | ExecutionStatus | DurationMs.",
387
451
  inputSchema: {
388
452
  project: projectParam,
389
453
  environment: environmentParam,
@@ -395,7 +459,7 @@ export function registerMicroserviceTools(server, platform) {
395
459
  }, handle(config, ({ project, environment, id, ...query }) => platform.tenant('GET', project, `/microservices/${id}/job-history`, { environment, query })));
396
460
  server.registerTool('microservice_schedule_get', {
397
461
  title: 'Zamanlama durumu',
398
- description: 'Zamanlanmış (schedule-job) microservice\'in canlı zamanlama durumunu döner: state (scheduled | paused | notScheduled | error | ended), isRunning, nextFireTimeUtc, previousFireTimeUtc, sıradaki 5 koşu (upcomingFireTimesUtc), cron + timeZoneId, serverTimeUtc ve son koşunun özeti (lastExecution). "Bir sonraki sefer ne zaman koşacak?" sorusunu cron\'u yorumlamadan buradan cevaplayın. paused iken nextFireTimeUtc null ve upcoming boştur. notScheduled: kayıt var ama zamanlayıcıda trigger yok — en geç 5 dk içinde uzlaştırma kurar ya da servisi kaydedin (microservice_update). ended: tanımın sonraki koşusu yok (once geçti, end on/after doldu). schedule alanı tanımın kendisidir. Schedule tipli olmayan servis 400 döner.',
462
+ description: 'Zamanlanmış (schedule-job) microservice\'in canlı zamanlama durumunu döner: state (scheduled | paused | notScheduled | error | ended), isRunning, nextFireTimeUtc, previousFireTimeUtc, sıradaki 5 koşu (upcomingFireTimesUtc), cron + timeZoneId, serverTimeUtc ve son koşunun özeti (lastExecution — geçmiş satırının aynısı: failed ise errorMessage patlayan adımı ve sebebini taşır; bkz. microservice_job_history). "Bir sonraki sefer ne zaman koşacak?" sorusunu cron\'u yorumlamadan buradan cevaplayın. paused iken nextFireTimeUtc null ve upcoming boştur. notScheduled: kayıt var ama zamanlayıcıda trigger yok — en geç 5 dk içinde uzlaştırma kurar ya da servisi kaydedin (microservice_update). ended: tanımın sonraki koşusu yok (once geçti, end on/after doldu). schedule alanı tanımın kendisidir. Schedule tipli olmayan servis 400 döner.',
399
463
  inputSchema: { project: projectParam, environment: environmentParam, id: guid },
400
464
  annotations: readOnly
401
465
  }, handle(config, ({ project, environment, id }) => platform.tenant('GET', project, `/microservices/${id}/schedule`, { environment })));
@@ -411,7 +475,7 @@ export function registerMicroserviceTools(server, platform) {
411
475
  }, handle(config, ({ project, environment, schedule }) => platform.tenant('POST', project, '/microservices/schedule/preview', { environment, body: { schedule } })));
412
476
  server.registerTool('microservice_schedule_control', {
413
477
  title: 'Zamanlamayı yönet',
414
- description: 'Zamanlanmış microservice\'i duraklatır (pause), sürdürür (resume) ya da cron\'u beklemeden bir kez koşturur (trigger). pause/resume yalnız zamanlayıcıdaki durumu değiştirir, tanımı değil; duraklatma cron güncellemesi ve deployment senkronundan sonra da korunur. resume: duraklatılmışken bir koşu kaçırıldıysa iş bir kez hemen koşar. trigger KUYRUĞA ALIR, sonucu beklemez: deployment ya da template kurulumu sürüyorsa koşu veto edilir ve geçmişe hiç düşmez — sonucu microservice_job_history ile doğrulayın. Zamanlayıcıda kaydı olmayan iş 400 (ScheduleJobNotRegisteredException) döner. Production ortamında üç eylem de 400 CantWriteInProductionException ile reddedilir; trigger ayrıca deployment/template kurulumu sürerken reddedilir.',
478
+ description: 'Zamanlanmış microservice\'i duraklatır (pause), sürdürür (resume) ya da cron\'u beklemeden bir kez koşturur (trigger). pause/resume yalnız zamanlayıcıdaki durumu değiştirir, tanımı değil; duraklatma cron güncellemesi ve deployment senkronundan sonra da korunur. resume: duraklatılmışken bir koşu kaçırıldıysa iş bir kez hemen koşar. trigger KUYRUĞA ALIR, sonucu beklemez: deployment ya da template kurulumu sürüyorsa koşu veto edilir ve geçmişe hiç düşmez — sonucu microservice_job_history ile doğrulayın. Geçmiş failed satırında patlayan adımı ve sebebini yazar ama adım izi vermez; tetiklemeden ÖNCE akışı workflow_preview / microservice_debug ile koşturun. Zamanlayıcıda kaydı olmayan iş 400 (ScheduleJobNotRegisteredException) döner. Production ortamında üç eylem de 400 CantWriteInProductionException ile reddedilir; trigger ayrıca deployment/template kurulumu sürerken reddedilir.',
415
479
  inputSchema: {
416
480
  project: projectParam,
417
481
  environment: environmentParam,