@appaflytech/zeyrek-ai-mcp 0.0.24 → 0.0.26

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 (81) hide show
  1. package/.env.example +0 -15
  2. package/dist/config.js +0 -11
  3. package/dist/index.js +0 -2
  4. package/dist/knowledge/componentCatalog.js +25 -13
  5. package/dist/knowledge/componentEvents.js +6 -13
  6. package/dist/knowledge/normalize.js +17 -68
  7. package/dist/knowledge/rules.js +49 -137
  8. package/dist/knowledge/styleResolve.js +4 -50
  9. package/dist/knowledge/themeResolve.js +3 -3
  10. package/dist/observability/trace.js +1 -1
  11. package/dist/platform/diagnostics.js +4 -10
  12. package/dist/platform/domSummary.js +1 -1
  13. package/dist/platform/http.js +7 -23
  14. package/dist/platform/responses.js +2 -6
  15. package/dist/platform/{capture/capture.js → screenshot.js} +514 -52
  16. package/dist/platform/secrets.js +0 -9
  17. package/dist/platform/strictArguments.js +12 -68
  18. package/dist/platform/tokenVault.js +4 -187
  19. package/dist/resources/examples/workflow-http-step.json +2 -2
  20. package/dist/resources/guides/component.md +1 -6
  21. package/dist/resources/guides/expressions.md +2 -2
  22. package/dist/resources/guides/functions.md +1 -1
  23. package/dist/resources/guides/layout.md +7 -11
  24. package/dist/resources/guides/microfunction.md +28 -0
  25. package/dist/resources/guides/microservice.md +4 -10
  26. package/dist/resources/guides/middleware.md +1 -5
  27. package/dist/resources/guides/page.md +55 -215
  28. package/dist/resources/guides/theme.md +1 -4
  29. package/dist/resources/guides/translation.md +1 -1
  30. package/dist/resources/guides/workflow.md +9 -12
  31. package/dist/resources/schema-fingerprint.json +2 -2
  32. package/dist/resources/schemas/CreateWorkflowCommand.json +3 -0
  33. package/dist/resources/schemas/PreviewWorkflowCommand.json +3 -0
  34. package/dist/resources/schemas/StepDto.json +12 -9
  35. package/dist/resources/schemas/UpdateWorkflowCommand.json +3 -0
  36. package/dist/server.js +1 -3
  37. package/dist/tools/applications.js +3 -60
  38. package/dist/tools/components.js +10 -50
  39. package/dist/tools/datasources.js +1 -1
  40. package/dist/tools/designSchemaPatch.js +6 -16
  41. package/dist/tools/externalComponents.js +4 -25
  42. package/dist/tools/flows.js +6 -79
  43. package/dist/tools/layouts.js +12 -44
  44. package/dist/tools/microservices.js +10 -26
  45. package/dist/tools/pages.js +67 -303
  46. package/dist/tools/platformInfo.js +2 -6
  47. package/dist/tools/rows.js +1 -7
  48. package/dist/tools/schemaOps.js +1 -1
  49. package/dist/tools/screenWrite.js +5 -6
  50. package/dist/tools/screens.js +3 -90
  51. package/dist/tools/workflows.js +1 -1
  52. package/package.json +1 -1
  53. package/dist/knowledge/mobileComponentCatalog.js +0 -801
  54. package/dist/knowledge/mobileComponentEvents.js +0 -225
  55. package/dist/knowledge/platform/lint.js +0 -312
  56. package/dist/knowledge/platform/mobile.js +0 -78
  57. package/dist/knowledge/platform/mobileRules.js +0 -182
  58. package/dist/knowledge/platform/mobileTabs.js +0 -108
  59. package/dist/knowledge/platform/profile.js +0 -20
  60. package/dist/knowledge/platform/resolve.js +0 -122
  61. package/dist/knowledge/platform/web.js +0 -38
  62. package/dist/knowledge/styleResolveNative.js +0 -510
  63. package/dist/platform/argumentAliases.js +0 -128
  64. package/dist/platform/bodyFile.js +0 -103
  65. package/dist/platform/capture/actions.js +0 -333
  66. package/dist/platform/capture/browser.js +0 -1
  67. package/dist/platform/capture/console-log.js +0 -80
  68. package/dist/platform/capture/index.js +0 -11
  69. package/dist/platform/capture/readiness.js +0 -103
  70. package/dist/platform/capture/summary.js +0 -77
  71. package/dist/platform/capture/target.js +0 -5
  72. package/dist/platform/capture/targets/studio-mobile.js +0 -15
  73. package/dist/platform/capture/targets/studio-web.js +0 -5
  74. package/dist/platform/schemaReadMemory.js +0 -60
  75. package/dist/resources/examples/mobile-app-shell-drawer.json +0 -209
  76. package/dist/resources/examples/mobile-app-shell-stack.json +0 -123
  77. package/dist/resources/examples/mobile-app-shell-tab.json +0 -174
  78. package/dist/resources/examples/mobile-list-detail-form.json +0 -656
  79. package/dist/resources/guides/mobile.md +0 -419
  80. package/dist/tools/mobile.js +0 -203
  81. package/dist/tools/profileWrite.js +0 -45
@@ -64,8 +64,7 @@ const guideRouting = {
64
64
  microfunction: 'kendi runtime\'ında koşan Node/Python fonksiyonu: protokol, yayın döngüsü, step kullanımı',
65
65
  entity: "alan tipleri, ilişkiler, hazır entity'ler",
66
66
  page: 'sayfa/flow işleri; flex düzen prop grubu ve boyut modları (Kural 1f-2)',
67
- layout: 'yerleşim kabuğu: tek slot, views, dar ekranda yığılma, widthType fill/fixed/auto',
68
- mobile: "mobil UYGULAMA (type:'mobile'): kurulum sırası (mobile_app_create), flex-only yerleşim, tipli stil, sekmeler (properties.mobile.tabs) ve çekmece, adım sözlüğü, MOB-* bulguları, page_screenshot device",
67
+ layout: 'yerleşim kabuğu: tek slot, views, mobil yığılma, widthType fill/fixed/auto',
69
68
  component: 'komponent modeli, olay sözleşmeleri, appearance boyut sözlüğü (widthString/heightString)',
70
69
  html: 'hazır komponent yetmediğinde tek seferlik kaçış kapısı (Mustache, fireEvent, script kuralları)',
71
70
  'external-component': 'kalıcı ihtiyaçta kendi komponentini yazıp yayınlama',
@@ -93,7 +92,6 @@ export function registerPlatformTools(server, platform) {
93
92
  'Modülün iş kuralları rehberini döner. Bir modülde İLK yazma işleminden önce ilgili rehberi okuyun:',
94
93
  ...guides.map(name => `- ${name}${guideRouting[name] ? `: ${guideRouting[name]}` : ''}`),
95
94
  "Büyük rehberler (page ~120 KB) section'sız çağrıda TAM METİN DÖNMEZ: giriş + bölüm listesi (outline) döner, truncated: true olur. Gövdeyi section ile bölüm bölüm alın.",
96
- "Büyük gövdeyi (sayfa şeması, akış adımları, uç/workflow tanımı, patch op'ları) dosyaya yazıp bodyFile ile verin: gövde bağlamınızdan geçmez, satır içiyle aynı doğrulamadan geçer (page_*/flow_*/microservice_*/workflow_* create/update/patch). microservice_execute yanıt başlıkları varsayılan kısadır; ucun kendi başlığı için includeHeaders:'all'.",
97
95
  'Örnek gövdeler için ngapps://examples kaynaklarına bakın.'
98
96
  ].join('\n');
99
97
  server.registerTool('platform_whoami', {
@@ -156,7 +154,6 @@ export function registerPlatformTools(server, platform) {
156
154
  title: 'Kabiliyet boşluğu bildir',
157
155
  description: "Yapmak İSTEDİĞİNİZ ama platform desteklemediği için yapamadığınız her noktada BUNU ÇAĞIRIN — tasarımı sessizce küçültmeyin. Bu çağrı platforma gitmez, yalnızca günlüğe 'KABİLİYET BOŞLUĞU' bloğu yazar; hata günlüğünde görünmeyen bu kayıtlar ürün yol haritasının girdisidir. Önce rehbere bakıp (platform_guide; hazır komponent yetmiyorsa tek seferlik için 'html' kaçış kapısı, kalıcı bir ihtiyaç içinse 'external-component' — kendi komponentinizi yazıp yayınlayabilirsiniz) gerçekten desteklenmediğinden emin olun: desteklenen bir şeyi 'yok' diye bildirmek yanlış yol haritası üretir.",
158
156
  inputSchema: {
159
- project: z.string().min(1).optional().describe("Boşluğun görüldüğü proje (ad ya da slug); kayda yazılır. Bu çağrı platforma gitmez, proje yalnız bağlamdır"),
160
157
  goal: z.string().min(1).optional().describe('Ne yapmak istediniz — kullanıcıya görünen sonuç olarak yazın ("randevu listesini hasta adına göre süzmek"). Eşanlamlı kabul edilir: title · summary · what.'),
161
158
  blocker: z.string().min(1).optional().describe('Neden yapamadınız — hangi kabiliyetin eksik olduğu ("uçta X yok", "komponentte Y prop\'u yok"). Eşanlamlı kabul edilir: reason · problem · missing · description.'),
162
159
  severity: z.string().optional().describe("YOL HARİTASINDAKİ SIRAYI BU ALAN BELİRLER, doldurun. blocker: özellik hiç yapılamadı · workaround: daha kötü bir yolla yapıldı · cosmetic: yalnız görsel/ergonomik kayıp. Eşanlamlılar çevrilir (critical/high/blocking→blocker, medium/major→workaround, low/minor/nit→cosmetic). TANINMAYAN değer reddedilir; verilmezse kayıt düşer ama yanıt 'incomplete' ile uyarır ve bildirim orta kovaya yazılır."),
@@ -174,10 +171,9 @@ export function registerPlatformTools(server, platform) {
174
171
  annotations: readOnly
175
172
  }, handle(config, async (input) => {
176
173
  const gap = normalizeGapReport(input);
177
- logCapabilityGap({ goal: gap.goal, blocker: gap.blocker, severity: gap.severity, module: gap.module, attempted: gap.attempted, workaround: gap.workaround, project: input.project });
174
+ logCapabilityGap({ goal: gap.goal, blocker: gap.blocker, severity: gap.severity, module: gap.module, attempted: gap.attempted, workaround: gap.workaround });
178
175
  return {
179
176
  recorded: true,
180
- ...(input.project ? { project: input.project } : {}),
181
177
  severity: gap.severity,
182
178
  module: gap.module ?? null,
183
179
  ...(Object.keys(gap.normalizedFrom).length > 0 ? { normalizedFrom: gap.normalizedFrom } : {}),
@@ -4,7 +4,7 @@ import { unmappedMembers, withUnmappedMembers } from '../knowledge/schemaGuard.j
4
4
  import { withNormalization } from '../knowledge/normalize.js';
5
5
  import { RefResolver } from '../platform/refs.js';
6
6
  import { attachFindings, evaluatePolicy, enforcePolicy } from '../knowledge/policy.js';
7
- import { filterOperatorError, policyRules } from '../knowledge/rules.js';
7
+ import { policyRules } from '../knowledge/rules.js';
8
8
  import { languageHeader } from '../knowledge/languageCodes.js';
9
9
  import { handle } from '../platform/responses.js';
10
10
  import { uploadFile } from './files.js';
@@ -224,9 +224,6 @@ export function registerRowTools(server, platform) {
224
224
  },
225
225
  annotations: readOnly
226
226
  }, handle(config, async ({ project, environment, entityId, language, ...body }) => {
227
- const operatorError = filterOperatorError('row_list', body.filters);
228
- if (operatorError)
229
- throw new PlatformApiError(operatorError, 400);
230
227
  const notes = [];
231
228
  const headers = languageHeader(language, notes);
232
229
  const resolver = new RefResolver(platform, project, environment);
@@ -403,9 +400,6 @@ export function registerRowTools(server, platform) {
403
400
  if ((scope?.rowIds?.length ?? 0) > maxSelectedRowIds) {
404
401
  throw new PlatformApiError(`row_export: ${scope?.rowIds?.length} satır id'si, ${maxSelectedRowIds} sınırının üstünde. Bu kadar satırı seçerek değil filtreyle verin: scope { kind: 'view', filters: [...] }.`);
405
402
  }
406
- const operatorError = filterOperatorError('row_export', scope?.filters);
407
- if (operatorError)
408
- throw new PlatformApiError(operatorError, 400);
409
403
  const resolvedFormat = format ?? 'xlsx';
410
404
  const notes = [];
411
405
  const resolver = new RefResolver(platform, project, environment);
@@ -24,7 +24,7 @@ export function outlineWriteResponse(response) {
24
24
  if (Array.isArray(container.appliedPatch))
25
25
  container.appliedPatch = outlineAppliedPatch(container.appliedPatch);
26
26
  }
27
- export const opsParam = z.array(z.record(z.unknown())).describe("Micro-op listesi. Op sözlüğü: replace_prop {target, prop, value} (value ham değer, code sarmalı {type: 'code', ref: '{{ … }}'} ya da translation sarmalı {type: 'translation', ref: '<çeviri anahtarı>'} — prop tipini değiştirmek için komponenti silip yeniden EKLEMEYİN, ona yazan setter'ların hedefi silinir (FLOW-018); platform replace_prop'ta expression alanını OKUMAZ — gateway onu code sarmalına çevirir) | set_binding {target, prop, expression: '{{ Page.variables.x }}'} | add_component {parent (üst elementId ya da 'root'), index?, component} | remove_component {target} | move_component {target, parent, index?, position: {x, y}} (index ÇİZİM sırası değildir, runtime çocukları blocks.position'a göre (y, sonra x) çizer. page_schema_patch'te flex kapta gateway index'i görünen sıraya çevirir ve kardeş konumlarını yeniden yazar; ızgara kapta sırayı position.y verir, sona eklemeyen index PAGE-033 uyarısıdır. layout_schema_patch ve component_schema_patch bu çeviriyi YAPMAZ: orada sırayı position.y ile verin) | set_event {target, event, eventValue, replaceBoundFlows?} (olayın BÜTÜN bağlarını bu tek akışa indirir; olayda başka akış bağlıysa gateway PAGE-034 ile reddeder — bilerek değiştirmek için replaceBoundFlows: true) | add_event {target, event, eventValue} (olaya bir akış DAHA bağlar; bağlı akışların hepsi paralel ve birbirinden bağımsız koşar, sıra garantisi yoktur — sıra gerekiyorsa flow-trigger. Aynı akışı ikinci kez bağlamak etkisizdir (unchanged; tekrar güvenli). Mobil runtime yalnız İLK akışı koşar) | remove_event {target, event, eventValue?} (olayı diziden çıkarır; target: 'page' sayfa düzeyi olaylar. Olaya birden fazla akış bağlıysa eventValue ile hangisi olduğunu verin, yoksa 422 ambiguous-event. set_event ile eventValue: null olay SİLMEZ, değersiz ölü kayıt bırakır. Olmayan olay 422 missing-event) | set_validations {target, validations: [{type, message, value, isActive}]} (komponentin validation listesini TAMAMEN değiştirir; boş dizi hepsini siler) | set_appearance {target, appearance: {heightType?, widthType?, tooltip?, background?, …}} (kurulu düğümün appearance'ına YALNIZ verilen alanları yazar, gerisini korur; null alanı temizler; bilinmeyen alan unknown-appearance-field ile reddedilir. GÖRÜNÜRLÜK appearance'ta DEĞİLDİR: gizlemek için replace_prop {target, prop: 'isHidden', value: true}, koşul için set_binding {prop: 'isHidden'} — add_component gövdesindeki appearance.isHidden'ı gateway props.isHidden'a taşır) | resize_component {target, size?: {w,h}, appearance?: {widthType,widthString,heightType,heightString}, states?: {isWrapper,isScrollable,isSticky,isDroppable,isFloating,isQuickStack}, breakpoint?: 1024} (gateway adı: platforma set_block {target, breakpoint, size} + set_appearance {target, appearance} + set_states {target, states} olarak gider — o üç op'u doğrudan da gönderebilirsiniz. move_component'e konan size reddedilir. Izgarada blocks[].size, flex'te appearance geçerlidir; ebeveynin düzeni yazılanı etkisiz kılıyorsa PAGE-019 uyarısı çıkar. states bir PROP DEĞİL düğüm alanıdır ve replace_prop onu yazamaz — düğümü silmeden isWrapper bayrağını değiştirmenin yolu budur). set_prop_type {target, prop, propType: 'static'|'code'|'translation', ref?, data?} (replace_prop sarmalıyla aynı sonucu verir ve mevcut data'yı tasarım yedeği olarak taşır. Bu op prop'un TİPİNİ yerinde değiştirir. Taşıyıcı alan tipe göre: static → data, code ve translation → ref (runtime data'yı her turda ezer, anahtar yalnız ref'te yaşar). Eksik taşıyıcı istek gönderilmeden reddedilir; page_schema_validate aynı kararı verir) | reorder {parent ('root' ya da elementId), order: [çocuk elementId'lerinin TAMAMI, yeni sırada]} (yalnız DİZİ sırasını değiştirir; çizim sırası blocks.position'dır — görünen sırayı değiştirmek için konumları set_block/move_component ile de yazın) | set_state_binding {target, binding: {name, expression, targets}} (ada göre ekler/değiştirir) | remove_state_binding {target, name} | batch {gestureId?, label?, ops: [...]} (iç içe batch yok). target = elementId. İstek atomiktir: tek op reddedilirse hiçbiri yazılmaz.");
27
+ export const opsParam = z.array(z.record(z.unknown())).describe("Micro-op listesi. Op sözlüğü: replace_prop {target, prop, value} (value ham değer, code sarmalı {type: 'code', ref: '{{ … }}'} ya da translation sarmalı {type: 'translation', ref: '<çeviri anahtarı>'} — prop tipini değiştirmek için komponenti silip yeniden EKLEMEYİN, ona yazan setter'ların hedefi silinir (FLOW-018); platform replace_prop'ta expression alanını OKUMAZ — gateway onu code sarmalına çevirir) | set_binding {target, prop, expression: '{{ Page.variables.x }}'} | add_component {parent (üst elementId ya da 'root'), index?, component} | remove_component {target} | move_component {target, parent, index?, position: {x, y}} (index ÇİZİM sırası değildir, runtime çocukları blocks.position'a göre (y, sonra x) çizer. page_schema_patch'te flex kapta gateway index'i görünen sıraya çevirir ve kardeş konumlarını yeniden yazar; ızgara kapta sırayı position.y verir, sona eklemeyen index PAGE-033 uyarısıdır. layout_schema_patch ve component_schema_patch bu çeviriyi YAPMAZ: orada sırayı position.y ile verin) | set_event {target, event, eventValue, replaceBoundFlows?} (olayın BÜTÜN bağlarını bu tek akışa indirir; olayda başka akış bağlıysa gateway PAGE-034 ile reddeder — bilerek değiştirmek için replaceBoundFlows: true) | add_event {target, event, eventValue} (olaya bir akış DAHA bağlar; bağlı akışların hepsi paralel ve birbirinden bağımsız koşar, sıra garantisi yoktur — sıra gerekiyorsa flow-trigger. Aynı akış iki kez 422 duplicate-event. Mobil runtime yalnız İLK akışı koşar) | remove_event {target, event, eventValue?} (olayı diziden çıkarır; target: 'page' sayfa düzeyi olaylar. Olaya birden fazla akış bağlıysa eventValue ile hangisi olduğunu verin, yoksa 422 ambiguous-event. set_event ile eventValue: null olay SİLMEZ, değersiz ölü kayıt bırakır. Olmayan olay 422 missing-event) | set_validations {target, validations: [{type, message, value, isActive}]} (komponentin validation listesini TAMAMEN değiştirir; boş dizi hepsini siler) | set_appearance {target, appearance: {heightType?, widthType?, tooltip?, background?, …}} (kurulu düğümün appearance'ına YALNIZ verilen alanları yazar, gerisini korur; null alanı temizler; bilinmeyen alan unknown-appearance-field ile reddedilir. GÖRÜNÜRLÜK appearance'ta DEĞİLDİR: gizlemek için replace_prop {target, prop: 'isHidden', value: true}, koşul için set_binding {prop: 'isHidden'} — add_component gövdesindeki appearance.isHidden'ı gateway props.isHidden'a taşır) | resize_component {target, size?: {w,h}, appearance?: {widthType,widthString,heightType,heightString}, states?: {isWrapper,isScrollable,isSticky,isDroppable,isFloating,isQuickStack}, breakpoint?: 1024} (gateway adı: platforma set_block {target, breakpoint, size} + set_appearance {target, appearance} + set_states {target, states} olarak gider — o üç op'u doğrudan da gönderebilirsiniz. move_component'e konan size reddedilir. Izgarada blocks[].size, flex'te appearance geçerlidir; ebeveynin düzeni yazılanı etkisiz kılıyorsa PAGE-019 uyarısı çıkar. states bir PROP DEĞİL düğüm alanıdır ve replace_prop onu yazamaz — düğümü silmeden isWrapper bayrağını değiştirmenin yolu budur). set_prop_type {target, prop, propType: 'static'|'code'|'translation', ref?, data?} (replace_prop sarmalıyla aynı sonucu verir ve mevcut data'yı tasarım yedeği olarak taşır. Bu op prop'un TİPİNİ yerinde değiştirir. Taşıyıcı alan tipe göre: static → data, code ve translation → ref (runtime data'yı her turda ezer, anahtar yalnız ref'te yaşar). Eksik taşıyıcı istek gönderilmeden reddedilir; page_schema_validate aynı kararı verir) | reorder {parent ('root' ya da elementId), order: [çocuk elementId'lerinin TAMAMI, yeni sırada]} (yalnız DİZİ sırasını değiştirir; çizim sırası blocks.position'dır — görünen sırayı değiştirmek için konumları set_block/move_component ile de yazın) | set_state_binding {target, binding: {name, expression, targets}} (ada göre ekler/değiştirir) | remove_state_binding {target, name} | batch {gestureId?, label?, ops: [...]} (iç içe batch yok). target = elementId. İstek atomiktir: tek op reddedilirse hiçbiri yazılmaz.");
28
28
  /**
29
29
  * PAGE-008 — `set_event` uydurma bir olay adıyla 200 döner ve bağ SESSİZCE ölü kalır: motor olayı
30
30
  * komponentin yaydığı adla eşleştirir, eşleşme yoksa akış hiç çalışmaz. Kontrol yalnız hedefin
@@ -1,4 +1,4 @@
1
- import { invalidScreenEventNames, invalidWidgetTypeNodes, nestedRepeaterNodes, nestedRepeaterMessage, blockSizeNote, heightTypeNote, sizeStringNote, droppableStatesNote } from '../knowledge/normalize.js';
1
+ import { invalidScreenEventNames, invalidWidgetTypeNodes, nestedRepeaterNodes, nestedRepeaterMessage, blockSizeNote, heightTypeNote, sizeStringNote } from '../knowledge/normalize.js';
2
2
  import { FUNCTIONS_NAMESPACE } from '../knowledge/functionGuards.js';
3
3
  import { applyCatalogLayoutRules } from './components.js';
4
4
  import { PlatformApiError } from '../platform/errors.js';
@@ -35,10 +35,9 @@ export function invalidComponentNames(nodes) {
35
35
  * PAGE-009 ve PAGE-013'ün layout ayağı 2026-09-09'da eklendi: ikisi de yalnız sayfa yollarında
36
36
  * koşuyordu, oysa layout `views`'ü aynı runtime'dan geçer — bozuk ad o layout'a bağlı HER
37
37
  * sayfanın ifadelerini öldürür, iç içe repeater'ın geri yazma kırılması ise yapısaldır ve
38
- * barındıranın sayfa mı layout mu olduğuna bakmaz. `platform` yalnız PAGE-013 mesajının önerisini seçer
39
- * (mobilde `grouped-list`); denetimlerin kendisi iki platformda aynıdır.
38
+ * barındıranın sayfa mı layout mu olduğuna bakmaz.
40
39
  */
41
- export function assertScreenWriteGuards(kind, screen, platform) {
40
+ export function assertScreenWriteGuards(kind, screen) {
42
41
  const codes = GUARD_CODES[kind];
43
42
  const badEvents = invalidScreenEventNames(screen.events, codes.events);
44
43
  if (badEvents.length > 0)
@@ -55,7 +54,7 @@ export function assertScreenWriteGuards(kind, screen, platform) {
55
54
  }
56
55
  const nested = nestedRepeaterNodes(screen.schema);
57
56
  if (nested.length > 0)
58
- throw new PlatformApiError(nestedRepeaterMessage(nested, platform), 400);
57
+ throw new PlatformApiError(nestedRepeaterMessage(nested), 400);
59
58
  }
60
59
  /**
61
60
  * Katalog kurallarını (blok sınırı · auto-height · boyut string'i) ağaca uygular ve
@@ -66,5 +65,5 @@ export async function screenCatalogNotes(platform, project, environment, applica
66
65
  if (!Array.isArray(nodes) || nodes.length === 0)
67
66
  return [];
68
67
  const catalog = await applyCatalogLayoutRules(platform, project, environment, applicationId, nodes);
69
- return [...blockSizeNote(catalog.clamped), ...heightTypeNote(catalog.heights), ...sizeStringNote(catalog.sizes), ...droppableStatesNote(catalog.states)];
68
+ return [...blockSizeNote(catalog.clamped), ...heightTypeNote(catalog.heights), ...sizeStringNote(catalog.sizes)];
70
69
  }
@@ -1,6 +1,5 @@
1
1
  import { PlatformApiError } from '../platform/errors.js';
2
2
  import { resolveNodeStyleReport } from '../knowledge/styleResolve.js';
3
- import { nodeNativeStyle } from '../knowledge/styleResolveNative.js';
4
3
  import { z } from 'zod';
5
4
  export const hostParam = z.enum(['page', 'layout', 'component'])
6
5
  .describe("Akışın barındırıcısı: page | layout | component (widget de component'tir)");
@@ -9,106 +8,26 @@ export const schemaParam = z.array(z.record(z.unknown()))
9
8
  export const eventsParam = z.array(z.record(z.unknown()))
10
9
  .describe("Sayfa/layout düzeyi olaylar: [{ name, value }] — value bir flow id'sidir");
11
10
  export const modeParam = z.enum(['summary', 'subtree', 'full']).optional().describe("summary (varsayılan): yalnız id/elementId/name/type ağacı — hedef bulmak için bunu kullanın. subtree: componentId ile tek alt ağaç. full: tüm şema.");
12
- /**
13
- * Şema ağacındaki TÜM düğümler (kök + iç içe çocuklar); page_get, page_create özeti, page_update
14
- * ve page_schema_get aynı sayımı kullanır. Parçalı okumanın `deferred` yer tutucuları düğüm değildir.
15
- */
16
- export function countSchemaNodes(nodes) {
17
- return (nodes ?? []).reduce((total, node) => node.deferred === true ? total : total + 1 + countSchemaNodes(node.children), 0);
18
- }
19
- function schemaNodeKey(node) {
20
- return typeof node.elementId === 'string' ? node.elementId : String(node.id);
21
- }
22
- function schemaNodeKeys(nodes) {
23
- return (nodes ?? []).flatMap(node => [schemaNodeKey(node), ...schemaNodeKeys(node.children)]);
24
- }
25
- /** `stored` ağacında olup `sent` ağacında olmayan düğümlerin elementId'leri, ön-sırayla (PAGE-037). */
26
- export function missingElementIds(stored, sent) {
27
- const kept = new Set(schemaNodeKeys(sent));
28
- return schemaNodeKeys(stored).filter(key => !kept.has(key));
29
- }
30
- /**
31
- * ZM-28: şemayı her biri `budgetChars` karakteri (JSON uzunluğu, `shrink` ile aynı ölçü) aşmayan
32
- * parçalara böler. Ön-sıra ve deterministik: alt ağacı sığan düğüm BÜTÜN alınır, sığmayan kabuk olarak
33
- * yazılır ve çocuklarına inilir; parçaların birleşimi orijinal şemanın birebir aynısıdır.
34
- */
35
- export function splitSchemaIntoParts(schema, budgetChars) {
36
- const parts = [];
37
- let current = [];
38
- let currentChars = 2;
39
- const place = (item, chars) => {
40
- if (current.length > 0 && currentChars + 1 + chars > budgetChars) {
41
- parts.push(current);
42
- current = [];
43
- currentChars = 2;
44
- }
45
- currentChars += (current.length > 0 ? 1 : 0) + chars;
46
- current.push(item);
47
- };
48
- const visit = (node, parentElementId, index) => {
49
- const whole = { parentElementId, index, node };
50
- const wholeChars = JSON.stringify(whole).length;
51
- if (2 + wholeChars <= budgetChars) {
52
- place(whole, wholeChars);
53
- return;
54
- }
55
- const children = Array.isArray(node.children) ? node.children : [];
56
- const shell = {
57
- parentElementId,
58
- index,
59
- node: { ...node, children: children.map(child => ({ elementId: schemaNodeKey(child), deferred: true })) }
60
- };
61
- const shellChars = JSON.stringify(shell).length;
62
- if (children.length === 0 || 2 + shellChars > budgetChars) {
63
- throw new PlatformApiError(`'${schemaNodeKey(node)}' (${String(node.type)}) düğümünün kendi gövdesi ${children.length === 0 ? wholeChars : shellChars} karakter; parça bütçesi ${budgetChars} karakter olduğu için tek düğüm bile bir yanıta sığmıyor. Düğümün büyük prop'unu page_schema_patch (replace_prop) ile küçültün ya da parçalara bölün; sonra cursor:'0' ile yeniden okuyun.`, 400);
64
- }
65
- place(shell, shellChars);
66
- children.forEach((child, childIndex) => visit(child, schemaNodeKey(node), childIndex));
67
- };
68
- schema.forEach((node, index) => visit(node, null, index));
69
- if (current.length > 0 || parts.length === 0)
70
- parts.push(current);
71
- return parts;
72
- }
73
- /** Opak parçalı okuma cursor'ı: sürüm değişince eski cursor reddedilir. */
74
- export function encodeSchemaCursor(version, partIndex) {
75
- return `${version}:${partIndex}`;
76
- }
77
- /** `'0'` sürümsüz ilk parçadır; `<sürüm>:<parça>` sürümü taşır. Çözülemeyen cursor `undefined`. */
78
- export function decodeSchemaCursor(cursor) {
79
- if (/^\d+$/.test(cursor))
80
- return { partIndex: Number(cursor) };
81
- const separator = cursor.lastIndexOf(':');
82
- const partIndex = cursor.slice(separator + 1);
83
- if (separator < 0 || !/^\d+$/.test(partIndex))
84
- return undefined;
85
- return { version: cursor.slice(0, separator), partIndex: Number(partIndex) };
86
- }
87
11
  /**
88
12
  * Ağacı yalnız kimlik alanlarına indirger; hedef aramak için okunur boyutta tutar.
89
13
  * `styleSource` verilirse (undefined DEĞİLSE) her düğüme efektif stil raporu da
90
14
  * yazılır: tema componentStyles → preset → düğümün kendi stili kaskadı.
91
15
  */
92
- export function summarize(node, styleSource, nativeTheme) {
16
+ export function summarize(node, styleSource) {
93
17
  const summary = {
94
18
  id: node.id,
95
19
  elementId: node.elementId,
96
20
  name: node.name,
97
21
  type: node.type
98
22
  };
99
- // Mobil uygulama: stil CSS değil React Native nesnesidir (`shell` kutu, `text` metin).
100
- if (nativeTheme !== undefined) {
101
- const { shell, text, warnings } = nodeNativeStyle(node, nativeTheme);
102
- summary.nativeStyle = { shell, text, ...(warnings.length > 0 ? { warnings } : {}) };
103
- }
104
- else if (styleSource !== undefined) {
23
+ if (styleSource !== undefined) {
105
24
  const report = resolveNodeStyleReport(node, styleSource ?? undefined);
106
25
  if (report.resolvedStyle !== undefined)
107
26
  summary.resolvedStyle = report.resolvedStyle;
108
27
  summary.styleLayers = report.styleLayers;
109
28
  }
110
29
  if (Array.isArray(node.children) && node.children.length > 0) {
111
- summary.children = node.children.map(child => summarize(child, styleSource, nativeTheme));
30
+ summary.children = node.children.map(child => summarize(child, styleSource));
112
31
  }
113
32
  return summary;
114
33
  }
@@ -177,11 +96,6 @@ export function flowPath(host, applicationId, hostId, flowId) {
177
96
  : `/components/${applicationId}/${hostId}/flows`;
178
97
  return flowId ? `${root}/${flowId}` : root;
179
98
  }
180
- /**
181
- * Sayfa PUT gövdesi okunan sayfadan kurulur ve o sayfanın sürümünü `baseVersion` olarak taşır:
182
- * platform sürümsüz sayfa PUT'unu reddeder (`plans/mobil-plantcare-acigi` b-05, K11). Gövde
183
- * okunduğu andaki sayfanın üstüne yazar; ajanın planladığı sürümü `page_update` kendisi koyar.
184
- */
185
99
  export function pageUpdateBody(page, overrides = {}) {
186
100
  const layout = (page.layout ?? {});
187
101
  return {
@@ -196,7 +110,6 @@ export function pageUpdateBody(page, overrides = {}) {
196
110
  middlewareIds: page.middlewareIds ?? [],
197
111
  roleIds: Array.isArray(page.roleIds) ? page.roleIds : identifiers(page.roles),
198
112
  layoutId: page.layoutId ?? layout.id ?? null,
199
- baseVersion: page.version === undefined || page.version === null ? undefined : String(page.version),
200
113
  ...overrides
201
114
  };
202
115
  }
@@ -240,7 +240,7 @@ export function registerWorkflowTools(server, platform) {
240
240
  }));
241
241
  server.registerTool('workflow_step_schema', {
242
242
  title: 'Step şeması üret',
243
- description: "Verilen step tanımı için girdi/çıktı şemasını üretir (parameterScheme / returnScheme); step yazarken definition'ı doğrulamanın en hızlı yolu. type:'workflow' adımında (rule.workflowId) çağrılan akışın parametre ve dönüş DTO'sunu döner — alt akışa girdi YALNIZ rule.expression ile geçer, nesne literalinin anahtarları bu parameterScheme'in alanlarıdır (WF-032; platform_guide('workflow') §Workflow adımı). ŞEMA ALAN ADLARINI VERİR, HANGİ ALANIN ÇALIŞTIĞINI DEĞİL — üç ölçülmüş sapma (2026-09-16): (1) 'http' adımının returnScheme'i kök seviyede { httpStatusCode, data } der, koşumda ise adım { data, meta: { httpStatusCode }, error }'dır, yani <adım>.httpStatusCode UNDEFINED, doğrusu <adım>.meta.httpStatusCode; (2) 'workflow' adımında workflowId boşken parameterScheme/returnScheme boş döner ve şema girdinin rule.expression ile bağlandığını söylemez; (3) 'email' adımında şemanın gösterdiği alıcı adı çalışmaz (36/W-6). Sözleşmenin ölçülmüş hâli: ngapps://examples/workflow-http-step · workflow-call-workflow · workflow-loop-step ve platform_guide('workflow').",
243
+ description: "Verilen step tanımı için girdi/çıktı şemasını üretir (parameterScheme / returnScheme); step yazarken definition'ı doğrulamanın en hızlı yolu. type:'workflow' adımında (rule.workflowId) çağrılan akışın parametre ve dönüş DTO'sunu döner — alt akışa girdi YALNIZ rule.expression ile geçer, nesne literalinin anahtarları bu parameterScheme'in alanlarıdır (WF-032; platform_guide('workflow') §Workflow adımı). 'workflow' adımında returnBehavior çağrılan akışın dönüş biçimidir (array → liste). returnScheme adımın GÖVDESİDİR; koşumda her adım { data, meta, error } zarfındadır — 'http' adımında gövde tipsizdir (<adım>.data), durum kodu <adım>.meta.httpStatusCode. ŞEMA ALAN ADLARINI VERİR, HANGİ ALANIN ÇALIŞTIĞINI DEĞİL — iki ölçülmüş sapma (2026-09-16): (1) 'workflow' adımında workflowId boşken parameterScheme/returnScheme boş döner ve şema girdinin rule.expression ile bağlandığını söylemez; (2) 'email' adımında şemanın gösterdiği alıcı adı çalışmaz (36/W-6). Sözleşmenin ölçülmüş hâli: ngapps://examples/workflow-http-step · workflow-call-workflow · workflow-loop-step ve platform_guide('workflow').",
244
244
  inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, id: guid, step: definitionParam },
245
245
  annotations: readOnly
246
246
  }, handle(config, ({ project, environment, applicationId, id, step }) => platform.tenant('POST', project, `/workflows/${applicationId}/${id}/steps/schema`, { environment, body: step })));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appaflytech/zeyrek-ai-mcp",
3
- "version": "0.0.24",
3
+ "version": "0.0.26",
4
4
  "type": "module",
5
5
  "description": "Zeyrek (NgApps) platform APIs as MCP tools — data, logic and Studio design surface in one gateway",
6
6
  "license": "UNLICENSED",