@appaflytech/zeyrek-ai-mcp 0.0.23 → 0.0.25

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 (61) hide show
  1. package/dist/config.js +0 -2
  2. package/dist/knowledge/componentCatalog.js +24 -12
  3. package/dist/knowledge/componentEvents.js +6 -13
  4. package/dist/knowledge/normalize.js +11 -52
  5. package/dist/knowledge/rules.js +12 -56
  6. package/dist/knowledge/styleResolve.js +1 -1
  7. package/dist/knowledge/themeResolve.js +3 -3
  8. package/dist/platform/domSummary.js +1 -1
  9. package/dist/platform/{capture/capture.js → screenshot.js} +509 -23
  10. package/dist/resources/examples/workflow-http-step.json +2 -2
  11. package/dist/resources/guides/component.md +1 -6
  12. package/dist/resources/guides/expressions.md +1 -1
  13. package/dist/resources/guides/functions.md +1 -1
  14. package/dist/resources/guides/layout.md +7 -11
  15. package/dist/resources/guides/microservice.md +2 -1
  16. package/dist/resources/guides/page.md +16 -69
  17. package/dist/resources/guides/translation.md +1 -1
  18. package/dist/resources/guides/workflow.md +6 -4
  19. package/dist/resources/schema-fingerprint.json +2 -2
  20. package/dist/resources/schemas/CreateWorkflowCommand.json +3 -0
  21. package/dist/resources/schemas/PreviewWorkflowCommand.json +3 -0
  22. package/dist/resources/schemas/StepDto.json +12 -9
  23. package/dist/resources/schemas/UpdateWorkflowCommand.json +3 -0
  24. package/dist/server.js +0 -2
  25. package/dist/tools/applications.js +3 -60
  26. package/dist/tools/components.js +10 -50
  27. package/dist/tools/designSchemaPatch.js +4 -13
  28. package/dist/tools/externalComponents.js +4 -25
  29. package/dist/tools/flows.js +2 -9
  30. package/dist/tools/layouts.js +9 -41
  31. package/dist/tools/pages.js +35 -115
  32. package/dist/tools/platformInfo.js +1 -2
  33. package/dist/tools/screenWrite.js +2 -2
  34. package/dist/tools/screens.js +3 -9
  35. package/dist/tools/workflows.js +1 -1
  36. package/package.json +1 -1
  37. package/dist/knowledge/mobileComponentCatalog.js +0 -628
  38. package/dist/knowledge/mobileComponentEvents.js +0 -110
  39. package/dist/knowledge/platform/lint.js +0 -205
  40. package/dist/knowledge/platform/mobile.js +0 -78
  41. package/dist/knowledge/platform/mobileRules.js +0 -126
  42. package/dist/knowledge/platform/mobileTabs.js +0 -108
  43. package/dist/knowledge/platform/profile.js +0 -20
  44. package/dist/knowledge/platform/resolve.js +0 -122
  45. package/dist/knowledge/platform/web.js +0 -38
  46. package/dist/knowledge/styleResolveNative.js +0 -410
  47. package/dist/platform/capture/actions.js +0 -333
  48. package/dist/platform/capture/browser.js +0 -1
  49. package/dist/platform/capture/index.js +0 -10
  50. package/dist/platform/capture/readiness.js +0 -103
  51. package/dist/platform/capture/summary.js +0 -77
  52. package/dist/platform/capture/target.js +0 -5
  53. package/dist/platform/capture/targets/studio-mobile.js +0 -15
  54. package/dist/platform/capture/targets/studio-web.js +0 -5
  55. package/dist/resources/examples/mobile-app-shell-drawer.json +0 -209
  56. package/dist/resources/examples/mobile-app-shell-stack.json +0 -123
  57. package/dist/resources/examples/mobile-app-shell-tab.json +0 -174
  58. package/dist/resources/examples/mobile-list-detail-form.json +0 -656
  59. package/dist/resources/guides/mobile.md +0 -283
  60. package/dist/tools/mobile.js +0 -203
  61. package/dist/tools/profileWrite.js +0 -45
@@ -1,40 +1,25 @@
1
1
  import { guid, projectParam, environmentParam, readOnly, writes, updates, destructive } from './common.js';
2
- import { normalizeComponentDefaults, componentDefaultsNote, clampBlockSizes, blockSizeNote, normalizeHeightTypes, heightTypeNote, normalizeSizeStrings, sizeStringNote, normalizeDroppableStates, withNormalization } from '../knowledge/normalize.js';
2
+ import { normalizeComponentDefaults, componentDefaultsNote, clampBlockSizes, blockSizeNote, normalizeHeightTypes, heightTypeNote, normalizeSizeStrings, sizeStringNote, withNormalization } from '../knowledge/normalize.js';
3
3
  import { eventContractsFor, eventPayloadNote } from '../knowledge/componentEvents.js';
4
4
  import { componentPresetDefaults, readProjectTheme } from '../knowledge/themeSchema.js';
5
5
  import { knowledgeFor, knowledgeNote, APPEARANCE_TOKEN_SETS, STATE_FLAG_NOTES, INTERNAL_ROLES_BY_TYPE } from '../knowledge/componentCatalog.js';
6
- import { MOBILE_STATE_FLAG_NOTES, mobileComponentKnowledge } from '../knowledge/mobileComponentCatalog.js';
7
- import { mobileComponentEventContracts } from '../knowledge/mobileComponentEvents.js';
8
6
  import { componentUpdateBody, fetchHost, schemaParam, unwrap } from './screens.js';
9
7
  import { PlatformApiError } from '../platform/errors.js';
10
8
  import { handle } from '../platform/responses.js';
11
- import { applicationTypeField, resolveProfile } from '../knowledge/platform/resolve.js';
12
- import { mobileComponentNotes } from '../knowledge/platform/mobileRules.js';
13
9
  import { z } from 'zod';
14
- const typeParam = z.enum(['web', 'mobile']).optional().describe('Hedef platform (ComponentType); verilmezse uygulamanın tipi — mobil uygulamada mobile');
10
+ const typeParam = z.enum(['web', 'mobile']).optional().describe('Hedef platform; varsayılan web');
15
11
  const kindParam = z.enum(['component', 'widget']).optional()
16
12
  .describe("component: sayfaya konan tekil eleman. widget: kendi şeması olan kapsayıcı (container/modal/drawer)");
17
13
  const widgetTypeParam = z.enum(['container', 'modal', 'drawer']).optional()
18
14
  .describe("kind:'widget' iken zorunlu");
19
- /**
20
- * Uç `type` verilmezse WEB kataloğunu döner (`GetComponentsQuery` `Type ?? Web`); mobil uygulamanın
21
- * paleti, doğrulayıcısı ve widget'ları `type=mobile` satırlarıdır. Profil mobil derse sorgu tipi
22
- * taşır; web'de sorgu profil öncesiyle aynıdır (G1 kilidi).
23
- */
24
15
  async function listComponents(platform, project, environment, applicationId, scope) {
25
16
  const path = scope === 'all' ? `/components/${applicationId}/all` : `/components/${applicationId}`;
26
- const catalogType = scope === 'all' ? 'web' : (await resolveProfile(platform, applicationId)).profile.catalogType;
27
17
  const response = await platform.tenant('GET', project, path, {
28
18
  environment,
29
- query: scope === 'all' ? undefined : { pageIndex: 0, pageLength: 999, ...(catalogType === 'mobile' ? { type: 'mobile' } : {}) }
19
+ query: scope === 'all' ? undefined : { pageIndex: 0, pageLength: 999 }
30
20
  });
31
21
  return response?.data ?? [];
32
22
  }
33
- /** Uygulamanın kayıtlı bileşen slug'ları (mobil profilin MOB-003 denetimi). */
34
- export async function fetchCatalogSlugs(platform, project, environment, applicationId) {
35
- const components = await listComponents(platform, project, environment, applicationId);
36
- return new Set(components.map(component => String(component.slug ?? '')).filter(slug => slug.length > 0));
37
- }
38
23
  /**
39
24
  * Yerleşim normalizasyonlarının ikisi de aynı katalog listesinden beslenir; tek okumada
40
25
  * çıkarılır ki yazma yolları fazladan istek atmasın. Uygulamanın kendi sözlüğü okunur
@@ -53,17 +38,12 @@ export async function fetchComponentLayoutRules(platform, project, environment,
53
38
  export function componentLayoutRules(components) {
54
39
  const maxSizes = new Map();
55
40
  const autoHeights = new Map();
56
- const droppable = new Map();
57
41
  for (const component of components) {
58
42
  const slug = typeof component.slug === 'string' ? component.slug : undefined;
59
43
  if (!slug)
60
44
  continue;
61
45
  if (typeof component.isDefaultAutoHeight === 'boolean')
62
46
  autoHeights.set(slug, component.isDefaultAutoHeight);
63
- // Kap bilgisi sözlükten gelir; düğümün `states.isDroppable`ı onu izler (Studio paleti de
64
- // aynı alanı katalogdan yazar). `true` gören tip kap sayılır.
65
- if (typeof component.isDroppable === 'boolean')
66
- droppable.set(slug, component.isDroppable);
67
47
  const blocks = (component.definition ?? {}).blocks;
68
48
  if (!Array.isArray(blocks))
69
49
  continue;
@@ -78,7 +58,7 @@ export function componentLayoutRules(components) {
78
58
  });
79
59
  }
80
60
  }
81
- return { maxSizes, autoHeights, droppable };
61
+ return { maxSizes, autoHeights };
82
62
  }
83
63
  /**
84
64
  * Katalog okuması başarısız olsa da yazma isteği gitmeli, ama iki normalizasyonun düşüş davranışı
@@ -89,21 +69,14 @@ export function componentLayoutRules(components) {
89
69
  * varsayılanını (`fixed`, `DesignComponentManagementSchema.cs:24`) kabul etmek demektir; en fazla
90
70
  * sekiz tipte (auth-layout/html/image/layout/qrcode/table/text-editor/video) fazladan yükseklik
91
71
  * üretir, atlamak ise her tipte içerik kırpar.
92
- * - `states.isDroppable` atlanır — katalog okunamadığında hangi tipin kap olduğu bilinmez ve
93
- * uydurulmaz; düğüm bugünkü hâliyle yazılır.
94
72
  */
95
73
  export async function applyCatalogLayoutRules(platform, project, environment, applicationId, nodes) {
96
74
  try {
97
75
  const rules = await fetchComponentLayoutRules(platform, project, environment, applicationId);
98
- return {
99
- clamped: clampBlockSizes(nodes, rules.maxSizes),
100
- heights: normalizeHeightTypes(nodes, rules.autoHeights),
101
- sizes: normalizeSizeStrings(nodes),
102
- states: normalizeDroppableStates(nodes, rules.droppable)
103
- };
76
+ return { clamped: clampBlockSizes(nodes, rules.maxSizes), heights: normalizeHeightTypes(nodes, rules.autoHeights), sizes: normalizeSizeStrings(nodes) };
104
77
  }
105
78
  catch {
106
- return { clamped: [], heights: normalizeHeightTypes(nodes, new Map()), sizes: normalizeSizeStrings(nodes), states: [] };
79
+ return { clamped: [], heights: normalizeHeightTypes(nodes, new Map()), sizes: normalizeSizeStrings(nodes) };
107
80
  }
108
81
  }
109
82
  /**
@@ -143,7 +116,6 @@ export function registerComponentTools(server, platform) {
143
116
  }, handle(config, async ({ project, environment, applicationId, scope, includeHidden }) => {
144
117
  const components = await listComponents(platform, project, environment, applicationId, scope);
145
118
  return {
146
- ...applicationTypeField(await resolveProfile(platform, applicationId)),
147
119
  components: components
148
120
  .filter(component => includeHidden === true || component.isHide !== true)
149
121
  .map(component => ({
@@ -189,15 +161,6 @@ export function registerComponentTools(server, platform) {
189
161
  : [];
190
162
  const componentSlug = typeof component.slug === 'string' ? component.slug : undefined;
191
163
  const knowledge = knowledgeFor(componentSlug);
192
- // Mobil uygulamada kayıt mobil kataloğun satırıdır (`listComponents` type=mobile); davranış
193
- // notları web runtime'ından gelir (`knowledge` — mobil şema web sınıfını genişletir), bileşenin
194
- // mobil farkları `mobileKnowledge`'ta, bütün mobil bileşenlere geçen notlar `mobileNotes`'ta (G4).
195
- // Web ikizi olmayan bileşende (`app-bar`, `tooltip`…) bilgi yalnız `mobileKnowledge`'tadır; olay
196
- // yükleri de önce mobil sözlükten okunur (`mobileComponentEvents.ts`).
197
- const mobile = (await resolveProfile(platform, applicationId)).profile.platform === 'mobile';
198
- const mobileKnowledge = mobile && componentSlug !== undefined && Object.hasOwn(mobileComponentKnowledge, componentSlug)
199
- ? mobileComponentKnowledge[componentSlug]
200
- : undefined;
201
164
  // S-3 — `defaults` HAM katalogdur; Studio'da bırakılan düğüm ise temanın bileşen preseti
202
165
  // kaplanmış katalogdan kurulur (`withThemeComponentDefaults`). Tema okunamazsa (uç düşer,
203
166
  // yetki yoksa) alan yanıta HİÇ girmez: uydurulmuş bir varsayılan yanlış bilgidir.
@@ -214,7 +177,7 @@ export function registerComponentTools(server, platform) {
214
177
  isDroppable: component.isDroppable,
215
178
  props: definition.props,
216
179
  defaults: definition.defaults,
217
- events: eventContractsFor(componentSlug, eventNames, mobile ? mobileComponentEventContracts : undefined),
180
+ events: eventContractsFor(componentSlug, eventNames),
218
181
  eventPayloadNote,
219
182
  ...(knowledge
220
183
  ? {
@@ -225,7 +188,7 @@ export function registerComponentTools(server, platform) {
225
188
  },
226
189
  ...(knowledge.guide ? { guide: knowledge.guide } : {})
227
190
  }
228
- : mobileKnowledge ? {} : { knowledgeNote }),
191
+ : { knowledgeNote }),
229
192
  ...(componentSlug && INTERNAL_ROLES_BY_TYPE[componentSlug]
230
193
  ? {
231
194
  internalRoles: INTERNAL_ROLES_BY_TYPE[componentSlug],
@@ -233,9 +196,8 @@ export function registerComponentTools(server, platform) {
233
196
  }
234
197
  : {}),
235
198
  ...(themeDefaults ? { themeDefaults } : {}),
236
- ...(mobile ? { platform: 'mobile', ...(mobileKnowledge ? { mobileKnowledge } : {}), mobileNotes: mobileComponentNotes(componentSlug) } : {}),
237
199
  appearanceValues: APPEARANCE_TOKEN_SETS,
238
- stateFlags: mobile ? { ...STATE_FLAG_NOTES, ...MOBILE_STATE_FLAG_NOTES } : STATE_FLAG_NOTES,
200
+ stateFlags: STATE_FLAG_NOTES,
239
201
  validations: definition.validations,
240
202
  sizes: definition.blocks
241
203
  };
@@ -272,13 +234,11 @@ export function registerComponentTools(server, platform) {
272
234
  const catalog = (body.schema ?? []).length > 0
273
235
  ? await applyCatalogLayoutRules(platform, project, environment, applicationId, body.schema)
274
236
  : { clamped: [], heights: [], sizes: [] };
275
- // Mobil uygulamanın widget'ı mobil katalog satırıdır; tip verilmezse uygulamanın tipi.
276
- const defaultType = body.type ?? (await resolveProfile(platform, applicationId)).profile.catalogType;
277
237
  return platform.tenant('POST', project, `/components/${applicationId}`, {
278
238
  environment,
279
239
  body: {
280
240
  kind: 'component',
281
- type: defaultType,
241
+ type: 'web',
282
242
  categories: [],
283
243
  definition: {},
284
244
  schema: [],
@@ -8,8 +8,6 @@ import { fetchComponentEventNames } from './components.js';
8
8
  import { PlatformApiError } from '../platform/errors.js';
9
9
  import { handle } from '../platform/responses.js';
10
10
  import { slotWarning } from './layouts.js';
11
- import { applicationTypeField, resolveProfile } from '../knowledge/platform/resolve.js';
12
- import { boundFlowSteps, screenProfileWarnings } from './profileWrite.js';
13
11
  import { z } from 'zod';
14
12
  const HOSTS = {
15
13
  layout: {
@@ -103,18 +101,12 @@ export function registerDesignSchemaPatchTool(server, platform, host) {
103
101
  const nested = simulatable ? nestedRepeaterNodes(simulated) : [];
104
102
  if (nested.length > 0)
105
103
  throw new PlatformApiError(nestedRepeaterMessage(nested), 400);
106
- const resolved = await resolveProfile(platform, applicationId);
107
104
  const reshaped = simulatable || opRecords.some(entry => entry.op === 'remove_component');
108
- const profileWarnings = await screenProfileWarnings(platform, resolved, project, environment, applicationId, {
109
- kind: spec.kind,
110
- ops: [...opRecords, ...propTypeOps],
111
- steps: await boundFlowSteps(platform, resolved, project, environment, host, applicationId, id, opRecords)
112
- });
113
105
  const layoutWarnings = reshaped
114
106
  ? [
115
- ...(resolved.profile.layout.blocksMeaningful ? verticalGapWarnings(simulated, spec.codes.gap, touched) : []),
107
+ ...verticalGapWarnings(simulated, spec.codes.gap, touched),
116
108
  ...stringStyleWarning(stringStyleNodes(simulated)),
117
- ...(resolved.profile.layout.modes.has('grid') ? inertFlexPropWarning(inertFlexPropNodes(simulated)) : []),
109
+ ...inertFlexPropWarning(inertFlexPropNodes(simulated)),
118
110
  ...flexSizeWarnings(simulated, spec.codes.flexMismatch, spec.codes.flexInvalid),
119
111
  ...(host === 'layout' ? slotWarning(simulated) : [])
120
112
  ]
@@ -141,9 +133,8 @@ export function registerDesignSchemaPatchTool(server, platform, host) {
141
133
  response.deletedFlows = deletedFlows;
142
134
  if (flowWarnings.length > 0)
143
135
  response.flowWarnings = flowWarnings;
144
- if (layoutWarnings.length > 0 || profileWarnings.length > 0)
145
- response.layoutWarnings = [...layoutWarnings, ...profileWarnings];
146
- Object.assign(response, applicationTypeField(resolved));
136
+ if (layoutWarnings.length > 0)
137
+ response.layoutWarnings = layoutWarnings;
147
138
  const contentOps = opRecords.filter(entry => entry.op === 'add_component' || entry.op === 'replace_prop');
148
139
  let opDrops = emptyWriteDiff();
149
140
  if (contentOps.length > 0) {
@@ -7,23 +7,6 @@ import { z } from 'zod';
7
7
  import { evaluatePolicy, enforcePolicy } from '../knowledge/policy.js';
8
8
  import { policyRules } from '../knowledge/rules.js';
9
9
  import { EXTERNAL_COMPONENT_PROTOCOL_VERSION } from '../knowledge/backendConstraints.js';
10
- import { resolveProfile } from '../knowledge/platform/resolve.js';
11
- import { findingLine } from '../knowledge/platform/profile.js';
12
- /**
13
- * MOB-006 — harici bileşen protokolü v1 tarayıcıda koşan `.mjs` custom element'tir; mobil
14
- * uygulamanın native çizeri onu yükleyemez (mobil protokol v2 Faz 3). Profil kapalı derse çağrı
15
- * platforma GİTMEZ: yüklenen paket hiçbir ekranda çizilmeyecekti.
16
- */
17
- async function assertExternalComponentsAllowed(platform, applicationId, tool) {
18
- const resolved = await resolveProfile(platform, applicationId);
19
- if (resolved.profile.externalComponents)
20
- return;
21
- throw new PlatformApiError(`${tool}: ${findingLine({
22
- code: 'MOB-006',
23
- severity: 'warn',
24
- message: "harici bileşen mobil uygulamada desteklenmiyor — protokol v1 tarayıcıda koşan .mjs custom element'tir, native çizer onu yükleyemez (mobil protokol v2 Faz 3). Çağrı platforma gönderilmedi; mobil ekranı katalog bileşenleriyle kurun (component_list)."
25
- })}`, 400);
26
- }
27
10
  /** Platformun köprü protokolü; scaffold ve publish bu sürüme göre üretir/doğrular (backend ExternalComponentRules.CurrentProtocolVersion) */
28
11
  const PROTOCOL_VERSION = EXTERNAL_COMPONENT_PROTOCOL_VERSION;
29
12
  /** Backend `ExternalComponentRules.MaxBundleSizeBytes` ile aynı sınır */
@@ -216,7 +199,6 @@ export function registerExternalComponentTools(server, platform) {
216
199
  },
217
200
  annotations: writes
218
201
  }, handle(config, async ({ project, environment, applicationId, bundlePath, manifestPath, version }) => {
219
- await assertExternalComponentsAllowed(platform, applicationId, 'external_component_publish');
220
202
  const manifestFile = resolve(manifestPath);
221
203
  const bundleFile = resolve(bundlePath);
222
204
  let manifest;
@@ -280,13 +262,10 @@ export function registerExternalComponentTools(server, platform) {
280
262
  acknowledgeWarnings: z.boolean().optional().describe('Doğrulama uyarılarını okuyup kabul ettiğinizi bildirir; uyarısı olan sürümlerde zorunlu')
281
263
  },
282
264
  annotations: updates
283
- }, handle(config, async ({ project, environment, applicationId, slug, version, acknowledgeWarnings }) => {
284
- await assertExternalComponentsAllowed(platform, applicationId, 'external_component_activate');
285
- return platform.tenant('POST', project, `/components/${applicationId}/external/${slug}/activate`, {
286
- environment,
287
- body: { version, acknowledgeWarnings: acknowledgeWarnings === true }
288
- });
289
- }));
265
+ }, handle(config, ({ project, environment, applicationId, slug, version, acknowledgeWarnings }) => platform.tenant('POST', project, `/components/${applicationId}/external/${slug}/activate`, {
266
+ environment,
267
+ body: { version, acknowledgeWarnings: acknowledgeWarnings === true }
268
+ })));
290
269
  server.registerTool('external_component_versions', {
291
270
  title: 'Paket sürümlerini listele',
292
271
  description: 'Bir harici komponentin yayınlanmış paket sürümlerini, hangisinin aktif olduğunu ve her sürümün doğrulama raporunu listeler. Geri alınacak sürümü buradan seçin.',
@@ -13,7 +13,6 @@ import { policyRules, flowExpressionSites } from '../knowledge/rules.js';
13
13
  import { functionCallRefs } from '../knowledge/functionGuards.js';
14
14
  import { existingMatch, ifExistsParam, platformRename, withRename } from '../platform/ifExists.js';
15
15
  import { randomUUID } from 'node:crypto';
16
- import { flowProfileWarnings } from './profileWrite.js';
17
16
  import { z } from 'zod';
18
17
  /**
19
18
  * Akış yazması yanıtında gövdeyi geri döndürmüyor, bu yüzden diff için akışı bir kez okuruz.
@@ -383,7 +382,6 @@ export function registerFlowTools(server, platform) {
383
382
  // Diff YALNIZ çağıranın yazdığı alanları kapsar; `id` ve barındırıcı bağı (`pageId` vb.)
384
383
  // gövdeye gateway koyar, kullanıcının düzeltebileceği bir şey değildir.
385
384
  const drops = await flowWriteDrops(platform, host, project, environment, applicationId, hostId, writtenFlowId, { name: flow.name, slug: flow.slug, steps: flow.steps, errorSteps: flow.errorSteps }, ifExists === 'duplicate');
386
- const platformWarnings = await flowProfileWarnings(platform, applicationId, [...(flow.steps ?? []), ...(flow.errorSteps ?? [])]);
387
385
  return attachFindings(withWriteDiff(withRename(withNormalization({
388
386
  host,
389
387
  hostId,
@@ -395,7 +393,6 @@ export function registerFlowTools(server, platform) {
395
393
  steps: steps.length
396
394
  },
397
395
  ...(parameterWarnings.length > 0 ? { parameterWarnings } : {}),
398
- ...(platformWarnings.length > 0 ? { platformWarnings } : {}),
399
396
  hint: "Akışı bir olaya bağlamak için: page_schema_patch (layout'ta layout_schema_patch, widget'ta component_schema_patch) ops:[{op:'set_event', target:<elementId>, event:'<component_get events listesindeki ad>', eventValue:<flow id>}]; olayda zaten akış bağlıysa ikinciyi add_event ile ekleyin (set_event bağlı akışı değiştirir, PAGE-034). Olay adları komponente özeldir ve 'on' ÖNEKİ ALMAZ (button → 'click', form → 'submit', table → 'mount'/'select'/'sort'…); uydurma ad 200 döner ama bağ sessizce ölü kalır — gateway PAGE-008 ile yakalar."
400
397
  }, normalized), drops.renamed), drops), findings);
401
398
  }));
@@ -449,9 +446,7 @@ export function registerFlowTools(server, platform) {
449
446
  ...(steps === undefined ? {} : { steps }),
450
447
  ...(errorSteps === undefined ? {} : { errorSteps })
451
448
  });
452
- const platformWarnings = await flowProfileWarnings(platform, applicationId, [...(flow.steps ?? []), ...(flow.errorSteps ?? [])]);
453
- return attachFindings(withWriteDiff(withNormalization({ host, hostId, flow: flowSummary(flow), ...(parameterWarnings.length > 0 ? { parameterWarnings } : {}),
454
- ...(platformWarnings.length > 0 ? { platformWarnings } : {}) }, normalized), drops), findings);
449
+ return attachFindings(withWriteDiff(withNormalization({ host, hostId, flow: flowSummary(flow), ...(parameterWarnings.length > 0 ? { parameterWarnings } : {}) }, normalized), drops), findings);
455
450
  }));
456
451
  server.registerTool('flow_patch', {
457
452
  title: "Akışa patch uygula",
@@ -500,7 +495,6 @@ export function registerFlowTools(server, platform) {
500
495
  });
501
496
  const written = patchResult(saved, flow);
502
497
  const drops = await flowWriteDrops(platform, host, project, environment, applicationId, hostId, flowId, { steps: flow.steps, errorSteps: flow.errorSteps });
503
- const platformWarnings = await flowProfileWarnings(platform, applicationId, [...(flow.steps ?? []), ...(flow.errorSteps ?? [])]);
504
498
  return attachFindings(withWriteDiff(withNormalization({
505
499
  host,
506
500
  hostId,
@@ -508,8 +502,7 @@ export function registerFlowTools(server, platform) {
508
502
  newVersion: written.newVersion,
509
503
  patchTargets: resolved.targets,
510
504
  flow: flowSummary(written.data),
511
- ...(parameterWarnings.length > 0 ? { parameterWarnings } : {}),
512
- ...(platformWarnings.length > 0 ? { platformWarnings } : {})
505
+ ...(parameterWarnings.length > 0 ? { parameterWarnings } : {})
513
506
  }, [...normalized, ...resolved.notes.map(note => `patch yolu seçiciden indekse çözüldü: ${note}`)]), drops), findings);
514
507
  }));
515
508
  server.registerTool('flow_delete', {
@@ -9,8 +9,6 @@ import { applyPropTypesToSchema, isSetPropTypeOp, setPropTypeErrors } from '../k
9
9
  import { writeDiff, withWriteDiff } from '../platform/writeDiff.js';
10
10
  import { PlatformApiError } from '../platform/errors.js';
11
11
  import { handle } from '../platform/responses.js';
12
- import { applicationTypeField, resolveProfile } from '../knowledge/platform/resolve.js';
13
- import { screenProfileWarnings } from './profileWrite.js';
14
12
  import { z } from 'zod';
15
13
  const patchOperationsParam = z.array(z.record(z.unknown())).min(1)
16
14
  .describe("JSON Patch listesi (RFC 6902): { op, path, value }. Yol seçici alabilir — '/views/0/children[elementId=baslik]/props/content/data'.");
@@ -48,13 +46,7 @@ export function registerLayoutTools(server, platform) {
48
46
  description: "Layout'u komponent ağacı (views), widget'ları, akışları ve olaylarıyla getirir.",
49
47
  inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, id: guid },
50
48
  annotations: readOnly
51
- }, handle(config, async ({ project, environment, applicationId, id }) => {
52
- const response = await platform.tenant('GET', project, `/layouts/${applicationId}/${id}`, { environment });
53
- const typeField = applicationTypeField(await resolveProfile(platform, applicationId));
54
- return response && typeof response === 'object' && !Array.isArray(response) && Object.keys(typeField).length > 0
55
- ? { ...response, ...typeField }
56
- : response;
57
- }));
49
+ }, handle(config, ({ project, environment, applicationId, id }) => platform.tenant('GET', project, `/layouts/${applicationId}/${id}`, { environment })));
58
50
  server.registerTool('layout_schema_get', {
59
51
  title: "Layout komponent ağacını oku",
60
52
  description: "Layout'un komponent ağacını (views) okur — page_schema_get'in layout karşılığı. Ağaçta hedefli değişiklik için layout_schema_patch (sayfa ile aynı micro-op sözlüğü, PATCH /layouts/{app}/{id}/schema). Ad/parametre/olay alanlarında ya da düz JSON Patch yolu gerektiğinde layout_patch — o araç buradaki updatedAt'i expectedUpdatedAt olarak kabul eder. Tam ağacı kendiniz yazacaksanız layout_update.",
@@ -69,21 +61,20 @@ export function registerLayoutTools(server, platform) {
69
61
  annotations: readOnly
70
62
  }, handle(config, async ({ project, environment, applicationId, id, mode, componentId }) => {
71
63
  const layout = await fetchHost(platform, 'layout', project, environment, applicationId, id);
72
- const typeField = applicationTypeField(await resolveProfile(platform, applicationId));
73
64
  const audit = layout.audit;
74
65
  const updatedAt = audit?.updatedAt ?? audit?.createdAt;
75
66
  const views = (layout.views ?? []);
76
67
  if (mode === 'full')
77
- return { updatedAt, ...typeField, views };
68
+ return { updatedAt, views };
78
69
  if (mode === 'subtree') {
79
70
  if (!componentId)
80
71
  throw new PlatformApiError("mode='subtree' için componentId zorunludur.");
81
72
  const subtree = findNode(views, componentId);
82
73
  if (!subtree)
83
74
  throw new PlatformApiError(`Layout'ta '${componentId}' id'li bir komponent yok; layout_schema_get'i summary kipinde çağırıp hedefi doğrulayın.`);
84
- return { updatedAt, ...typeField, views: subtree };
75
+ return { updatedAt, views: subtree };
85
76
  }
86
- return { updatedAt, ...typeField, views: views.map(node => summarize(node)) };
77
+ return { updatedAt, views: views.map(node => summarize(node)) };
87
78
  }));
88
79
  server.registerTool('layout_create', {
89
80
  title: 'Layout oluştur',
@@ -100,27 +91,18 @@ export function registerLayoutTools(server, platform) {
100
91
  annotations: writes
101
92
  }, handle(config, async ({ project, environment, applicationId, name, views, events, parameters }) => {
102
93
  assertScreenWriteGuards('layout', { schema: views, events });
103
- const resolved = await resolveProfile(platform, applicationId);
104
94
  const fixed = normalizeComponentDefaults(views);
105
95
  const catalogNotes = await screenCatalogNotes(platform, project, environment, applicationId, views);
106
- const gaps = [
107
- ...(resolved.profile.layout.blocksMeaningful ? verticalGapWarnings(views ?? [], 'LAY-003 (uyarı)') : []),
108
- ...flexSizeWarnings(views ?? [], 'LAY-007 (uyarı)', 'LAY-008 (uyarı)'),
109
- ...spacingLayerWarnings(views ?? [], 'LAY-010 (uyarı)', 'LAY-011 (uyarı)'),
110
- ...await screenProfileWarnings(platform, resolved, project, environment, applicationId, { kind: 'layout', nodes: views ?? [] })
111
- ];
96
+ const gaps = [...verticalGapWarnings(views ?? [], 'LAY-003 (uyarı)'), ...flexSizeWarnings(views ?? [], 'LAY-007 (uyarı)', 'LAY-008 (uyarı)'), ...spacingLayerWarnings(views ?? [], 'LAY-010 (uyarı)', 'LAY-011 (uyarı)')];
112
97
  const response = await platform.tenant('POST', project, `/layouts/${applicationId}`, {
113
98
  environment,
114
99
  body: { name, views: views ?? [], events: events ?? [], parameters: parameters ?? null }
115
100
  });
116
101
  const drops = writeDiff({ name, views: views ?? [], events: events ?? [] }, response);
117
102
  const normalized = withWriteDiff(withNormalization(response, [...componentDefaultsNote(fixed), ...catalogNotes, ...slotWarning(views)]), drops);
118
- const typeField = applicationTypeField(resolved);
119
- if (!normalized || typeof normalized !== 'object')
103
+ if (gaps.length === 0 || !normalized || typeof normalized !== 'object')
120
104
  return normalized;
121
- if (gaps.length === 0)
122
- return Object.keys(typeField).length === 0 ? normalized : { ...normalized, ...typeField };
123
- return { ...normalized, ...typeField, layoutWarnings: gaps };
105
+ return { ...normalized, layoutWarnings: gaps };
124
106
  }));
125
107
  server.registerTool('layout_update', {
126
108
  title: 'Layout güncelle',
@@ -144,15 +126,7 @@ export function registerLayoutTools(server, platform) {
144
126
  const catalogNotes = await screenCatalogNotes(platform, project, environment, applicationId, overrides.views);
145
127
  const body = layoutUpdateBody({ ...current, applicationId }, overrides);
146
128
  await platform.tenant('PUT', project, `/layouts/${applicationId}/${id}`, { environment, body });
147
- const resolved = overrides.views === undefined ? undefined : await resolveProfile(platform, applicationId);
148
- const gaps = overrides.views === undefined || !resolved
149
- ? []
150
- : [
151
- ...(resolved.profile.layout.blocksMeaningful ? verticalGapWarnings(body.views, 'LAY-003 (uyarı)') : []),
152
- ...flexSizeWarnings(body.views, 'LAY-007 (uyarı)', 'LAY-008 (uyarı)'),
153
- ...spacingLayerWarnings(body.views, 'LAY-010 (uyarı)', 'LAY-011 (uyarı)'),
154
- ...await screenProfileWarnings(platform, resolved, project, environment, applicationId, { kind: 'layout', nodes: body.views })
155
- ];
129
+ const gaps = overrides.views === undefined ? [] : [...verticalGapWarnings(body.views, 'LAY-003 (uyarı)'), ...flexSizeWarnings(body.views, 'LAY-007 (uyarı)', 'LAY-008 (uyarı)'), ...spacingLayerWarnings(body.views, 'LAY-010 (uyarı)', 'LAY-011 (uyarı)')];
156
130
  const summary = { id, changed: Object.keys(overrides), preserved: { viewNodes: body.views.length } };
157
131
  if (gaps.length > 0)
158
132
  summary.layoutWarnings = gaps;
@@ -219,13 +193,7 @@ export function registerLayoutTools(server, platform) {
219
193
  body: { baseVersion: baseVersionOf(document, 'layout_get'), ops: netOps }
220
194
  });
221
195
  const written = patchResult(saved, finalDocument);
222
- const profile = await resolveProfile(platform, applicationId);
223
- const gaps = [
224
- ...(profile.profile.layout.blocksMeaningful ? verticalGapWarnings(body.views, 'LAY-003 (uyarı)') : []),
225
- ...flexSizeWarnings(body.views, 'LAY-007 (uyarı)', 'LAY-008 (uyarı)'),
226
- ...spacingLayerWarnings(body.views, 'LAY-010 (uyarı)', 'LAY-011 (uyarı)'),
227
- ...await screenProfileWarnings(platform, profile, project, environment, applicationId, { kind: 'layout', nodes: body.views })
228
- ];
196
+ const gaps = [...verticalGapWarnings(body.views, 'LAY-003 (uyarı)'), ...flexSizeWarnings(body.views, 'LAY-007 (uyarı)', 'LAY-008 (uyarı)'), ...spacingLayerWarnings(body.views, 'LAY-010 (uyarı)', 'LAY-011 (uyarı)')];
229
197
  const summary = {
230
198
  id,
231
199
  applied: patchOps.length,