@appaflytech/zeyrek-ai-mcp 0.0.30 → 0.0.32

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 (203) hide show
  1. package/.env.example +0 -15
  2. package/README.md +5 -5
  3. package/dist/config.js +0 -37
  4. package/dist/index.js +0 -2
  5. package/dist/knowledge/backendConstraints.js +1 -18
  6. package/dist/knowledge/boxSections.js +184 -0
  7. package/dist/knowledge/componentCatalog.js +232 -562
  8. package/dist/knowledge/componentEvents.js +21 -141
  9. package/dist/knowledge/layoutSummary.js +2 -140
  10. package/dist/knowledge/normalize.js +67 -236
  11. package/dist/knowledge/outlines.js +0 -36
  12. package/dist/knowledge/policy.js +4 -18
  13. package/dist/knowledge/reservedTables.js +0 -79
  14. package/dist/knowledge/rules.js +21 -319
  15. package/dist/knowledge/schemaGuard.js +0 -11
  16. package/dist/knowledge/styleResolve.js +38 -55
  17. package/dist/knowledge/themeResolve.js +3 -3
  18. package/dist/observability/trace.js +3 -6
  19. package/dist/platform/diagnostics.js +4 -10
  20. package/dist/platform/domSummary.js +1 -1
  21. package/dist/platform/errors.js +10 -162
  22. package/dist/platform/http.js +8 -29
  23. package/dist/platform/responses.js +5 -39
  24. package/dist/platform/{capture/capture.js → screenshot.js} +519 -105
  25. package/dist/platform/secrets.js +1 -17
  26. package/dist/platform/strictArguments.js +12 -68
  27. package/dist/platform/tokenVault.js +4 -187
  28. package/dist/resources/examples/layout-app-shell.json +707 -229
  29. package/dist/resources/examples/page-detail-profile.json +1 -2
  30. package/dist/resources/examples/page-dynamic-form.json +2 -3
  31. package/dist/resources/examples/page-flex-sections.json +1 -1
  32. package/dist/resources/examples/page-html-embed.json +1 -1
  33. package/dist/resources/examples/workflow-basic.json +2 -8
  34. package/dist/resources/guides/component.md +4 -91
  35. package/dist/resources/guides/entity.md +8 -50
  36. package/dist/resources/guides/expressions.md +5 -14
  37. package/dist/resources/guides/functions.md +1 -1
  38. package/dist/resources/guides/getting-started.md +1 -38
  39. package/dist/resources/guides/layout.md +58 -55
  40. package/dist/resources/guides/microservice.md +2 -81
  41. package/dist/resources/guides/middleware.md +2 -44
  42. package/dist/resources/guides/page.md +75 -454
  43. package/dist/resources/guides/theme.md +2 -8
  44. package/dist/resources/guides/translation.md +1 -1
  45. package/dist/resources/guides/workflow.md +1 -58
  46. package/dist/resources/rules.js +5 -11
  47. package/dist/resources/schema-fingerprint.json +5 -7
  48. package/dist/resources/schemas/CreateEntityCommand.json +0 -118
  49. package/dist/resources/schemas/CreateMicroserviceCommand.json +1 -13
  50. package/dist/resources/schemas/CreateQueryCommand.json +0 -4
  51. package/dist/resources/schemas/CreateWorkflowCommand.json +1 -143
  52. package/dist/resources/schemas/DataJobDto.json +1 -6
  53. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +1 -21
  54. package/dist/resources/schemas/MicroserviceDto.json +3 -15
  55. package/dist/resources/schemas/PreviewMicroserviceCommand.json +1 -10
  56. package/dist/resources/schemas/PreviewWorkflowCommand.json +1 -22
  57. package/dist/resources/schemas/StepDto.json +1 -22
  58. package/dist/resources/schemas/UpdateEntityCommand.json +0 -118
  59. package/dist/resources/schemas/UpdateMicroserviceCommand.json +1 -13
  60. package/dist/resources/schemas/UpdateQueryCommand.json +0 -4
  61. package/dist/resources/schemas/UpdateViewCommand.json +2 -0
  62. package/dist/resources/schemas/UpdateWorkflowCommand.json +1 -143
  63. package/dist/server.js +1 -27
  64. package/dist/tools/access.js +2 -369
  65. package/dist/tools/applications.js +3 -60
  66. package/dist/tools/common.js +0 -7
  67. package/dist/tools/components.js +14 -118
  68. package/dist/tools/datasources.js +3 -3
  69. package/dist/tools/dependencies.js +1 -1
  70. package/dist/tools/deployments.js +2 -2
  71. package/dist/tools/designSchemaPatch.js +18 -34
  72. package/dist/tools/dtos.js +5 -36
  73. package/dist/tools/entities.js +12 -79
  74. package/dist/tools/externalComponents.js +5 -26
  75. package/dist/tools/flows.js +14 -122
  76. package/dist/tools/folders.js +1 -1
  77. package/dist/tools/imports.js +2 -5
  78. package/dist/tools/layouts.js +17 -50
  79. package/dist/tools/merges.js +1 -1
  80. package/dist/tools/microservices.js +25 -77
  81. package/dist/tools/pages.js +112 -465
  82. package/dist/tools/platformInfo.js +8 -27
  83. package/dist/tools/projects.js +9 -71
  84. package/dist/tools/rows.js +13 -69
  85. package/dist/tools/schemaOps.js +1 -61
  86. package/dist/tools/screenWrite.js +8 -37
  87. package/dist/tools/screens.js +5 -95
  88. package/dist/tools/templates.js +1 -26
  89. package/dist/tools/translations.js +1 -1
  90. package/dist/tools/variables.js +5 -11
  91. package/dist/tools/workflows.js +5 -10
  92. package/package.json +2 -2
  93. package/dist/knowledge/access.js +0 -802
  94. package/dist/knowledge/case.js +0 -41
  95. package/dist/knowledge/connectDataBind.js +0 -819
  96. package/dist/knowledge/connectDataDefinition.js +0 -341
  97. package/dist/knowledge/connectDataExecute.js +0 -93
  98. package/dist/knowledge/connectDataRules.js +0 -128
  99. package/dist/knowledge/decision.js +0 -121
  100. package/dist/knowledge/expressionPrelude.js +0 -59
  101. package/dist/knowledge/microserviceParameters.js +0 -58
  102. package/dist/knowledge/mining.js +0 -94
  103. package/dist/knowledge/mobileComponentCatalog.js +0 -859
  104. package/dist/knowledge/mobileComponentEvents.js +0 -239
  105. package/dist/knowledge/platform/lint.js +0 -385
  106. package/dist/knowledge/platform/mobile.js +0 -142
  107. package/dist/knowledge/platform/mobileLayoutLint.js +0 -324
  108. package/dist/knowledge/platform/mobileRules.js +0 -231
  109. package/dist/knowledge/platform/mobileSpacing.js +0 -82
  110. package/dist/knowledge/platform/mobileTabs.js +0 -108
  111. package/dist/knowledge/platform/nativeBoxModel.js +0 -44
  112. package/dist/knowledge/platform/profile.js +0 -25
  113. package/dist/knowledge/platform/resolve.js +0 -122
  114. package/dist/knowledge/platform/web.js +0 -39
  115. package/dist/knowledge/process.js +0 -510
  116. package/dist/knowledge/rowFilter.js +0 -43
  117. package/dist/knowledge/styleResolveNative.js +0 -527
  118. package/dist/platform/argumentAliases.js +0 -128
  119. package/dist/platform/bodyFile.js +0 -103
  120. package/dist/platform/capture/actions.js +0 -333
  121. package/dist/platform/capture/browser.js +0 -1
  122. package/dist/platform/capture/console-log.js +0 -122
  123. package/dist/platform/capture/index.js +0 -11
  124. package/dist/platform/capture/readiness.js +0 -103
  125. package/dist/platform/capture/summary.js +0 -77
  126. package/dist/platform/capture/target.js +0 -5
  127. package/dist/platform/capture/targets/studio-mobile.js +0 -15
  128. package/dist/platform/capture/targets/studio-web.js +0 -5
  129. package/dist/platform/impersonation.js +0 -45
  130. package/dist/platform/jsonArray.js +0 -24
  131. package/dist/platform/schemaReadMemory.js +0 -60
  132. package/dist/resources/examples/bpm-gorev-kontrol.json +0 -294
  133. package/dist/resources/examples/bpm-iso-dokuman.json +0 -228
  134. package/dist/resources/examples/bpm-satinalma.json +0 -376
  135. package/dist/resources/examples/connect-data-convert-verify.json +0 -107
  136. package/dist/resources/examples/connect-data-dropdown-roles.json +0 -66
  137. package/dist/resources/examples/connect-data-edit-m2m.json +0 -73
  138. package/dist/resources/examples/connect-data-query-params.json +0 -50
  139. package/dist/resources/examples/connect-data-table-entity.json +0 -147
  140. package/dist/resources/examples/connect-data-workflow-microservice.json +0 -65
  141. package/dist/resources/examples/mobile-app-shell-drawer.json +0 -243
  142. package/dist/resources/examples/mobile-app-shell-stack.json +0 -157
  143. package/dist/resources/examples/mobile-app-shell-tab.json +0 -208
  144. package/dist/resources/examples/mobile-form-screen.json +0 -365
  145. package/dist/resources/examples/mobile-list-detail-form.json +0 -672
  146. package/dist/resources/guides/access.md +0 -796
  147. package/dist/resources/guides/bpm.md +0 -686
  148. package/dist/resources/guides/case.md +0 -153
  149. package/dist/resources/guides/decision.md +0 -185
  150. package/dist/resources/guides/mobile-layout.md +0 -193
  151. package/dist/resources/guides/mobile.md +0 -495
  152. package/dist/resources/read.js +0 -41
  153. package/dist/resources/schemas/AccessExplanationDto.json +0 -144
  154. package/dist/resources/schemas/AccessMatrixDto.json +0 -170
  155. package/dist/resources/schemas/AccessPermissionDto.json +0 -57
  156. package/dist/resources/schemas/AccessPolicyDto.json +0 -223
  157. package/dist/resources/schemas/AccessResourceDto.json +0 -86
  158. package/dist/resources/schemas/AppSessionDto.json +0 -53
  159. package/dist/resources/schemas/ConnectDataDescribeDto.json +0 -344
  160. package/dist/resources/schemas/ConnectDataRequestModel.json +0 -202
  161. package/dist/resources/schemas/ConnectDataResultDto.json +0 -421
  162. package/dist/resources/schemas/ConnectorCredentialDto.json +0 -70
  163. package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +0 -37
  164. package/dist/resources/schemas/CreateAccessPolicyCommand.json +0 -209
  165. package/dist/resources/schemas/CreateDecisionCommand.json +0 -221
  166. package/dist/resources/schemas/CreateProcessDefinitionCommand.json +0 -1337
  167. package/dist/resources/schemas/DecisionDto.json +0 -302
  168. package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +0 -28
  169. package/dist/resources/schemas/ExplainAccessQuery.json +0 -33
  170. package/dist/resources/schemas/GenerateProcessDocumentCommand.json +0 -116
  171. package/dist/resources/schemas/OrganizationProjectDto.json +0 -335
  172. package/dist/resources/schemas/OrganizationSchemaDto.json +0 -196
  173. package/dist/resources/schemas/OrganizationSchemaVersionDto.json +0 -207
  174. package/dist/resources/schemas/PatchProcessDefinitionCommand.json +0 -76
  175. package/dist/resources/schemas/ProcessDefinitionDto.json +0 -1480
  176. package/dist/resources/schemas/ProcessSimulationDto.json +0 -96
  177. package/dist/resources/schemas/SaveConnectorCredentialCommand.json +0 -90
  178. package/dist/resources/schemas/SaveProcessEventSourceCommand.json +0 -61
  179. package/dist/resources/schemas/SaveProcessMailSourceCommand.json +0 -89
  180. package/dist/resources/schemas/SignProcessTaskCommand.json +0 -73
  181. package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +0 -92
  182. package/dist/resources/schemas/UpdateAccessPolicyCommand.json +0 -209
  183. package/dist/resources/schemas/UpdateDecisionCommand.json +0 -216
  184. package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +0 -1357
  185. package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +0 -1339
  186. package/dist/tools/accessOperations.js +0 -135
  187. package/dist/tools/accessPolicies.js +0 -170
  188. package/dist/tools/accessRuntime.js +0 -203
  189. package/dist/tools/bpm.js +0 -343
  190. package/dist/tools/bpmGovernance.js +0 -266
  191. package/dist/tools/bpmOperations.js +0 -230
  192. package/dist/tools/bpmReporting.js +0 -154
  193. package/dist/tools/bpmRouting.js +0 -150
  194. package/dist/tools/bpmRuntime.js +0 -396
  195. package/dist/tools/case.js +0 -178
  196. package/dist/tools/caseRuntime.js +0 -89
  197. package/dist/tools/connectData.js +0 -449
  198. package/dist/tools/connectors.js +0 -193
  199. package/dist/tools/decisions.js +0 -206
  200. package/dist/tools/mobile.js +0 -221
  201. package/dist/tools/modules.js +0 -48
  202. package/dist/tools/organizationStructure.js +0 -137
  203. package/dist/tools/profileWrite.js +0 -92
@@ -1,81 +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
- import { randomUUID } from 'node:crypto';
14
9
  import { z } from 'zod';
15
- 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');
16
11
  const kindParam = z.enum(['component', 'widget']).optional()
17
12
  .describe("component: sayfaya konan tekil eleman. widget: kendi şeması olan kapsayıcı (container/modal/drawer)");
18
13
  const widgetTypeParam = z.enum(['container', 'modal', 'drawer']).optional()
19
14
  .describe("kind:'widget' iken zorunlu");
20
- /**
21
- * Uç `type` verilmezse WEB kataloğunu döner (`GetComponentsQuery` `Type ?? Web`); mobil uygulamanın
22
- * paleti, doğrulayıcısı ve widget'ları `type=mobile` satırlarıdır. Profil mobil derse sorgu tipi
23
- * taşır; web'de sorgu profil öncesiyle aynıdır (G1 kilidi).
24
- */
25
- export async function listComponents(platform, project, environment, applicationId, scope) {
15
+ async function listComponents(platform, project, environment, applicationId, scope) {
26
16
  const path = scope === 'all' ? `/components/${applicationId}/all` : `/components/${applicationId}`;
27
- const catalogType = scope === 'all' ? 'web' : (await resolveProfile(platform, applicationId)).profile.catalogType;
28
17
  const response = await platform.tenant('GET', project, path, {
29
18
  environment,
30
- query: scope === 'all' ? undefined : { pageIndex: 0, pageLength: 999, ...(catalogType === 'mobile' ? { type: 'mobile' } : {}) }
19
+ query: scope === 'all' ? undefined : { pageIndex: 0, pageLength: 999 }
31
20
  });
32
21
  return response?.data ?? [];
33
22
  }
34
- /**
35
- * CMP-002 (ARC-081) — runtime widget'ın kökünü yalnız `widget-area` (container) ya da `modal`/`drawer`
36
- * tipinden tanır (`runtime-compose.ts` `getRuntimeWidgetRootNode`); düz `container` kökle kaydedilen
37
- * widget her yüzeyde boş çizilir. Tipli kök yoksa düğümler Studio'nun `createWidgetRootNode`'u
38
- * (`widget.functions.ts`) ile aynı şekilde bir köke sarılır: prop'lar uygulamanın kataloğundaki kök
39
- * tipinin `definition.defaults`'ı, yükseklik `fixed`, kök bırakılabilir.
40
- */
41
- function wrapWidgetRoot(schema, widgetType, components) {
42
- const rootType = widgetType === 'container' ? 'widget-area' : widgetType;
43
- // Runtime istenen tipin kökü yoksa öteki tipli köklere de düşer (`legacyRoot()`); tip değiştiren
44
- // güncellemenin eski kökü ikinci kez sarılmaz.
45
- const hasRoot = schema.some(node => node?.kind === 'component' && ['widget-area', 'modal', 'drawer'].includes(String(node.type)));
46
- if (hasRoot)
47
- return { schema, notes: [] };
48
- const definition = (components.find(component => component.slug === rootType)?.definition ?? {});
49
- const desktopBlock = Array.isArray(definition.blocks)
50
- ? definition.blocks.find(block => block?.breakpoint === 1024)
51
- : undefined;
52
- const elementId = `${rootType}${randomUUID().slice(0, 4)}`;
53
- const root = {
54
- id: randomUUID(),
55
- elementId,
56
- name: widgetType === 'container' ? 'container' : elementId,
57
- widgetType,
58
- kind: 'component',
59
- type: rootType,
60
- children: schema,
61
- events: [],
62
- props: { ...(definition.defaults ?? {}) },
63
- blocks: desktopBlock ? [{ breakpoint: 1024, size: desktopBlock.size, position: { x: 0, y: 0 } }] : [],
64
- validations: [],
65
- appearance: { heightType: 'fixed' },
66
- states: { isDroppable: true },
67
- stateBindings: []
68
- };
69
- return {
70
- schema: [root],
71
- notes: [`CMP-002: widget şemasında '${rootType}' kökü yoktu; ${schema.length} düğüm '${elementId}' köküne sarıldı (Studio'nun kurduğu şekil). Runtime widget'ı yalnız widget-area/modal/drawer kökünden çizer.`]
72
- };
73
- }
74
- /** Uygulamanın kayıtlı bileşen slug'ları (mobil profilin MOB-003 denetimi). */
75
- export async function fetchCatalogSlugs(platform, project, environment, applicationId) {
76
- const components = await listComponents(platform, project, environment, applicationId);
77
- return new Set(components.map(component => String(component.slug ?? '')).filter(slug => slug.length > 0));
78
- }
79
23
  /**
80
24
  * Yerleşim normalizasyonlarının ikisi de aynı katalog listesinden beslenir; tek okumada
81
25
  * çıkarılır ki yazma yolları fazladan istek atmasın. Uygulamanın kendi sözlüğü okunur
@@ -90,33 +34,16 @@ export async function fetchCatalogSlugs(platform, project, environment, applicat
90
34
  export async function fetchComponentLayoutRules(platform, project, environment, applicationId) {
91
35
  return componentLayoutRules(await listComponents(platform, project, environment, applicationId));
92
36
  }
93
- /**
94
- * Uygulamanın komponent sözlüğü, TEK okumada. Katalog gövdesi büyüktür (101 kayıt ≈ yüzlerce KB):
95
- * hem TB-123 doğrulaması hem yerleşim normalizasyonu aynı listeden beslenir, iki istek atılmaz.
96
- */
97
- export async function fetchCatalogComponents(platform, project, environment, applicationId) {
98
- return listComponents(platform, project, environment, applicationId);
99
- }
100
- /** Katalog listesi elde varken yerleşim kurallarını uygular (ikinci okuma yapmaz). */
101
- export function applyCatalogLayoutRulesFrom(components, nodes) {
102
- const rules = componentLayoutRules(components);
103
- return { clamped: clampBlockSizes(nodes, rules.maxSizes), heights: normalizeHeightTypes(nodes, rules.autoHeights), sizes: normalizeSizeStrings(nodes), states: normalizeDroppableStates(nodes, rules.droppable) };
104
- }
105
37
  /** Katalog listesini zaten okumuş çağıranlar (component_update) ikinci istek atmasın diye ayrı. */
106
38
  export function componentLayoutRules(components) {
107
39
  const maxSizes = new Map();
108
40
  const autoHeights = new Map();
109
- const droppable = new Map();
110
41
  for (const component of components) {
111
42
  const slug = typeof component.slug === 'string' ? component.slug : undefined;
112
43
  if (!slug)
113
44
  continue;
114
45
  if (typeof component.isDefaultAutoHeight === 'boolean')
115
46
  autoHeights.set(slug, component.isDefaultAutoHeight);
116
- // Kap bilgisi sözlükten gelir; düğümün `states.isDroppable`ı onu izler (Studio paleti de
117
- // aynı alanı katalogdan yazar). `true` gören tip kap sayılır.
118
- if (typeof component.isDroppable === 'boolean')
119
- droppable.set(slug, component.isDroppable);
120
47
  const blocks = (component.definition ?? {}).blocks;
121
48
  if (!Array.isArray(blocks))
122
49
  continue;
@@ -131,7 +58,7 @@ export function componentLayoutRules(components) {
131
58
  });
132
59
  }
133
60
  }
134
- return { maxSizes, autoHeights, droppable };
61
+ return { maxSizes, autoHeights };
135
62
  }
136
63
  /**
137
64
  * Katalog okuması başarısız olsa da yazma isteği gitmeli, ama iki normalizasyonun düşüş davranışı
@@ -142,21 +69,14 @@ export function componentLayoutRules(components) {
142
69
  * varsayılanını (`fixed`, `DesignComponentManagementSchema.cs:24`) kabul etmek demektir; en fazla
143
70
  * sekiz tipte (auth-layout/html/image/layout/qrcode/table/text-editor/video) fazladan yükseklik
144
71
  * üretir, atlamak ise her tipte içerik kırpar.
145
- * - `states.isDroppable` atlanır — katalog okunamadığında hangi tipin kap olduğu bilinmez ve
146
- * uydurulmaz; düğüm bugünkü hâliyle yazılır.
147
72
  */
148
73
  export async function applyCatalogLayoutRules(platform, project, environment, applicationId, nodes) {
149
74
  try {
150
75
  const rules = await fetchComponentLayoutRules(platform, project, environment, applicationId);
151
- return {
152
- clamped: clampBlockSizes(nodes, rules.maxSizes),
153
- heights: normalizeHeightTypes(nodes, rules.autoHeights),
154
- sizes: normalizeSizeStrings(nodes),
155
- states: normalizeDroppableStates(nodes, rules.droppable)
156
- };
76
+ return { clamped: clampBlockSizes(nodes, rules.maxSizes), heights: normalizeHeightTypes(nodes, rules.autoHeights), sizes: normalizeSizeStrings(nodes) };
157
77
  }
158
78
  catch {
159
- return { clamped: [], heights: normalizeHeightTypes(nodes, new Map()), sizes: normalizeSizeStrings(nodes), states: [] };
79
+ return { clamped: [], heights: normalizeHeightTypes(nodes, new Map()), sizes: normalizeSizeStrings(nodes) };
160
80
  }
161
81
  }
162
82
  /**
@@ -196,7 +116,6 @@ export function registerComponentTools(server, platform) {
196
116
  }, handle(config, async ({ project, environment, applicationId, scope, includeHidden }) => {
197
117
  const components = await listComponents(platform, project, environment, applicationId, scope);
198
118
  return {
199
- ...applicationTypeField(await resolveProfile(platform, applicationId)),
200
119
  components: components
201
120
  .filter(component => includeHidden === true || component.isHide !== true)
202
121
  .map(component => ({
@@ -242,15 +161,6 @@ export function registerComponentTools(server, platform) {
242
161
  : [];
243
162
  const componentSlug = typeof component.slug === 'string' ? component.slug : undefined;
244
163
  const knowledge = knowledgeFor(componentSlug);
245
- // Mobil uygulamada kayıt mobil kataloğun satırıdır (`listComponents` type=mobile); davranış
246
- // notları web runtime'ından gelir (`knowledge` — mobil şema web sınıfını genişletir), bileşenin
247
- // mobil farkları `mobileKnowledge`'ta, bütün mobil bileşenlere geçen notlar `mobileNotes`'ta (G4).
248
- // Web ikizi olmayan bileşende (`app-bar`, `tooltip`…) bilgi yalnız `mobileKnowledge`'tadır; olay
249
- // yükleri de önce mobil sözlükten okunur (`mobileComponentEvents.ts`).
250
- const mobile = (await resolveProfile(platform, applicationId)).profile.platform === 'mobile';
251
- const mobileKnowledge = mobile && componentSlug !== undefined && Object.hasOwn(mobileComponentKnowledge, componentSlug)
252
- ? mobileComponentKnowledge[componentSlug]
253
- : undefined;
254
164
  // S-3 — `defaults` HAM katalogdur; Studio'da bırakılan düğüm ise temanın bileşen preseti
255
165
  // kaplanmış katalogdan kurulur (`withThemeComponentDefaults`). Tema okunamazsa (uç düşer,
256
166
  // yetki yoksa) alan yanıta HİÇ girmez: uydurulmuş bir varsayılan yanlış bilgidir.
@@ -267,7 +177,7 @@ export function registerComponentTools(server, platform) {
267
177
  isDroppable: component.isDroppable,
268
178
  props: definition.props,
269
179
  defaults: definition.defaults,
270
- events: eventContractsFor(componentSlug, eventNames, mobile ? mobileComponentEventContracts : undefined),
180
+ events: eventContractsFor(componentSlug, eventNames),
271
181
  eventPayloadNote,
272
182
  ...(knowledge
273
183
  ? {
@@ -278,7 +188,7 @@ export function registerComponentTools(server, platform) {
278
188
  },
279
189
  ...(knowledge.guide ? { guide: knowledge.guide } : {})
280
190
  }
281
- : mobileKnowledge ? {} : { knowledgeNote }),
191
+ : { knowledgeNote }),
282
192
  ...(componentSlug && INTERNAL_ROLES_BY_TYPE[componentSlug]
283
193
  ? {
284
194
  internalRoles: INTERNAL_ROLES_BY_TYPE[componentSlug],
@@ -286,12 +196,10 @@ export function registerComponentTools(server, platform) {
286
196
  }
287
197
  : {}),
288
198
  ...(themeDefaults ? { themeDefaults } : {}),
289
- ...(mobile ? { platform: 'mobile', ...(mobileKnowledge ? { mobileKnowledge } : {}), mobileNotes: mobileComponentNotes(componentSlug) } : {}),
290
199
  appearanceValues: APPEARANCE_TOKEN_SETS,
291
- stateFlags: mobile ? { ...STATE_FLAG_NOTES, ...MOBILE_STATE_FLAG_NOTES } : STATE_FLAG_NOTES,
200
+ stateFlags: STATE_FLAG_NOTES,
292
201
  validations: definition.validations,
293
- sizes: definition.blocks,
294
- ...(definition.connectData ? { connectData: definition.connectData } : { connectDataNote: "Bu komponentin veri kaynağına bağlanabilir prop kaydı yok (ya da katalog henüz eşitlenmedi): connect_data_bind bu tipte CD-001 döner." })
202
+ sizes: definition.blocks
295
203
  };
296
204
  }));
297
205
  server.registerTool('component_create', {
@@ -322,27 +230,21 @@ export function registerComponentTools(server, platform) {
322
230
  if (body.kind === 'widget' && !body.widgetType) {
323
231
  throw new PlatformApiError("kind:'widget' için widgetType (container | modal | drawer) zorunludur.");
324
232
  }
325
- const wrapped = body.kind === 'widget' && body.widgetType && (body.schema ?? []).length > 0
326
- ? wrapWidgetRoot(body.schema ?? [], body.widgetType, await listComponents(platform, project, environment, applicationId).catch(() => []))
327
- : { schema: body.schema, notes: [] };
328
- body.schema = wrapped.schema;
329
233
  const fixed = normalizeComponentDefaults(body.schema);
330
234
  const catalog = (body.schema ?? []).length > 0
331
235
  ? await applyCatalogLayoutRules(platform, project, environment, applicationId, body.schema)
332
236
  : { clamped: [], heights: [], sizes: [] };
333
- // Mobil uygulamanın widget'ı mobil katalog satırıdır; tip verilmezse uygulamanın tipi.
334
- const defaultType = body.type ?? (await resolveProfile(platform, applicationId)).profile.catalogType;
335
237
  return platform.tenant('POST', project, `/components/${applicationId}`, {
336
238
  environment,
337
239
  body: {
338
240
  kind: 'component',
339
- type: defaultType,
241
+ type: 'web',
340
242
  categories: [],
341
243
  definition: {},
342
244
  schema: [],
343
245
  ...Object.fromEntries(Object.entries(body).filter(([, value]) => value !== undefined))
344
246
  }
345
- }).then(response => withNormalization(response, [...wrapped.notes, ...componentDefaultsNote(fixed), ...blockSizeNote(catalog.clamped), ...heightTypeNote(catalog.heights), ...sizeStringNote(catalog.sizes)]));
247
+ }).then(response => withNormalization(response, [...componentDefaultsNote(fixed), ...blockSizeNote(catalog.clamped), ...heightTypeNote(catalog.heights), ...sizeStringNote(catalog.sizes)]));
346
248
  }));
347
249
  server.registerTool('component_update', {
348
250
  title: 'Komponent güncelle',
@@ -377,12 +279,6 @@ export function registerComponentTools(server, platform) {
377
279
  ? await fetchHost(platform, 'component', project, environment, applicationId, String(current.id))
378
280
  : current;
379
281
  const overrides = Object.fromEntries(Object.entries(changes).filter(([, value]) => value !== undefined));
380
- const widgetType = changes.widgetType ?? detailed.widgetType;
381
- const wrapped = detailed.kind === 'widget' && typeof widgetType === 'string' && changes.schema !== undefined && changes.schema.length > 0
382
- ? wrapWidgetRoot(changes.schema, widgetType, components)
383
- : { schema: changes.schema, notes: [] };
384
- if (overrides.schema !== undefined)
385
- overrides.schema = wrapped.schema;
386
282
  const fixed = normalizeComponentDefaults(overrides.schema);
387
283
  const rules = componentLayoutRules(components);
388
284
  const clamped = overrides.schema === undefined ? [] : clampBlockSizes(overrides.schema, rules.maxSizes);
@@ -390,7 +286,7 @@ export function registerComponentTools(server, platform) {
390
286
  const sizes = overrides.schema === undefined ? [] : normalizeSizeStrings(overrides.schema);
391
287
  const body = componentUpdateBody({ ...detailed, applicationId }, overrides);
392
288
  await platform.tenant('PUT', project, `/components/${applicationId}/${slug}`, { environment, body });
393
- return withNormalization({ slug, changed: Object.keys(overrides), preserved: { schemaNodes: body.schema.length } }, [...wrapped.notes, ...componentDefaultsNote(fixed), ...blockSizeNote(clamped), ...heightTypeNote(heights), ...sizeStringNote(sizes)]);
289
+ return withNormalization({ slug, changed: Object.keys(overrides), preserved: { schemaNodes: body.schema.length } }, [...componentDefaultsNote(fixed), ...blockSizeNote(clamped), ...heightTypeNote(heights), ...sizeStringNote(sizes)]);
394
290
  }));
395
291
  server.registerTool('component_delete', {
396
292
  title: 'Komponent sil',
@@ -75,7 +75,7 @@ export function registerDatasourceTools(server, platform) {
75
75
  inputSchema: { project: projectParam, environment: environmentParam, ...connectionInput },
76
76
  annotations: writes
77
77
  }, handle(config, async ({ project, environment, ...body }) => {
78
- const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'datasource', body, { operation: 'create' }), false);
78
+ const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'datasource', body, { operation: 'create' }));
79
79
  return attachFindings(await platform.tenant('POST', project, '/datasources', { environment, body }), findings);
80
80
  }));
81
81
  server.registerTool('datasource_update', {
@@ -84,7 +84,7 @@ export function registerDatasourceTools(server, platform) {
84
84
  inputSchema: { project: projectParam, environment: environmentParam, id: guid, ...connectionInput },
85
85
  annotations: updates
86
86
  }, handle(config, async ({ project, environment, id, ...body }) => {
87
- const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'datasource', body, { operation: 'update' }), false);
87
+ const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'datasource', body, { operation: 'update' }));
88
88
  return attachFindings(await platform.tenant('PUT', project, `/datasources/${id}`, { environment, body }), findings);
89
89
  }));
90
90
  server.registerTool('datasource_delete', {
@@ -118,7 +118,7 @@ export function registerDatasourceTools(server, platform) {
118
118
  }, handle(config, ({ project, environment }) => platform.tenant('GET', project, '/datasources/resources', { environment })));
119
119
  server.registerTool('datasource_configuration_options', {
120
120
  title: 'Yapılandırma seçenekleri',
121
- description: "Datasource'un alan tipi kataloğunu döner: commonType başına dbType listesi, varsayılan tip, tipin kabul ettiği seçenek anahtarları (length/precision/collation/...) ve dönüştürülebilir tipler; ayrıca ilişki kuralları (onUpdate/onDelete) ve identity generation tipleri. İlişki alanına yazarken kuralı SAYI olarak verin (`None` 0 · `Cascade` 1 · `SetNull` 2 · `SetDefault` 3 — `Rule` sırası): her backend sürümünde çalışır. Katalog adı listeler; `onDelete` adı (`Cascade`) 2026-09-27'den sonraki backend'de de kabul edilir, `onUpdate` adı hâlâ reddedilir (500). VARSAYILAN YANIT ÖZETTİR (~5 KB): collation DEĞER listesi (816 kayıt, tam yanıtın %79'u) dışarıdadır — tipin collation kabul edip etmediği zaten options'ta yazar. Collation değerleri gerçekten gerekiyorsa includeCollations: true ile tam yanıtı isteyin (~45 KB).",
121
+ description: "Datasource'un alan tipi kataloğunu döner: commonType başına dbType listesi, varsayılan tip, tipin kabul ettiği seçenek anahtarları (length/precision/collation/...) ve dönüştürülebilir tipler; ayrıca ilişki kuralları (onUpdate/onDelete) ve identity generation tipleri. VARSAYILAN YANIT ÖZETTİR (~5 KB): collation DEĞER listesi (816 kayıt, tam yanıtın %79'u) dışarıdadır — tipin collation kabul edip etmediği zaten options'ta yazar. Collation değerleri gerçekten gerekiyorsa includeCollations: true ile tam yanıtı isteyin (~45 KB).",
122
122
  inputSchema: {
123
123
  project: projectParam,
124
124
  environment: environmentParam,
@@ -9,7 +9,7 @@ export function registerDependencyTools(server, platform) {
9
9
  inputSchema: {
10
10
  project: projectParam,
11
11
  environment: environmentParam,
12
- module: z.string().describe('Modül adı: entity | field | microservice | workflow | query | view | dataTransferObject | process-definition (depends: tanımın başvurduğu entity/workflow/sayfa/DTO/rol/pozisyon/birim/takvim/karar/alt süreç; depended: onu alt süreç olarak çağıran tanımlar — entity ve workflow grafiği de kullanan tanımları gösterir, silmeleri 422 ReferencedByProcess) | global-function (fonksiyon, iki kaynak: onu çağıran flow/workflow listesi; flow düğümü sahibini hostModule/hostId/hostName, bağlandığı komponenti ve olayı componentName/eventName/eventTitle ile taşır) vb. (platform Module enum değeri)'),
12
+ module: z.string().describe('Modül adı: entity | field | microservice | workflow | query | view | dataTransferObject | global-function (fonksiyon, iki kaynak: onu çağıran flow/workflow listesi; flow düğümü sahibini hostModule/hostId/hostName, bağlandığı komponenti ve olayı componentName/eventName/eventTitle ile taşır) vb. (platform Module enum değeri)'),
13
13
  id: guid
14
14
  },
15
15
  annotations: readOnly
@@ -4,13 +4,13 @@ export function registerDeploymentTools(server, platform) {
4
4
  const config = platform.config;
5
5
  server.registerTool('deployment_start', {
6
6
  title: 'Deployment başlat',
7
- description: 'Projeyi kaynak environment\'tan hedef environment\'a deploy eder. Asenkron bir saga\'dır: sonuç bu yanıtta bitmez, deployment_status ile izleyin. Environment id\'lerini project_get çıktısından alın. BPM: süreç tanımları ve iş takvimleri taşınır — hedefte farklı aktif model yeni sürüm olarak yayınlanır (production\'da gelişte aktif), hedefin uyarlaması korunur; uyarlama, örnek, görev ve defter taşınmaz; kaynakta olmayan tanım silinir, açık örneği varsa emekliye ayrılır.',
7
+ description: 'Projeyi kaynak environment\'tan hedef environment\'a deploy eder. Asenkron bir saga\'dır: sonuç bu yanıtta bitmez, deployment_status ile izleyin. Environment id\'lerini project_get çıktısından alın.',
8
8
  inputSchema: { projectId: guid, sourceEnvironmentId: guid, targetEnvironmentId: guid },
9
9
  annotations: writes
10
10
  }, handle(config, ({ projectId, ...body }) => platform.org('POST', `/deployments/${projectId}/deploy`, { body })));
11
11
  server.registerTool('deployment_status', {
12
12
  title: 'Deployment durumu',
13
- description: "Projenin son deployment durumunu döner. 'projectId' ZORUNLUDUR (project_list/project_get'ten alın) — verilmezse çağrı MCP şema katmanında reddedilir, platforma hiç gitmez. Hiç deployment yapılmamış projede yanıt BOŞ gelir; o durumda tool 'hiç deployment kaydı yok' bilgisini açıkça döner, yani boş yanıtı 'tool çalışmadı' diye okumayın. Durum satırı modül başına ayrılmaz: süreç tanımları ve iş takvimleri sayfa ve workflow'lardan sonra aynı saga adımında aktarılır; hedefte çalışamayan (eksik workflow/entity/rol) tanım aktarımı DefinitionInvalid ile düşürür.",
13
+ description: "Projenin son deployment durumunu döner. 'projectId' ZORUNLUDUR (project_list/project_get'ten alın) — verilmezse çağrı MCP şema katmanında reddedilir, platforma hiç gitmez. Hiç deployment yapılmamış projede yanıt BOŞ gelir; o durumda tool 'hiç deployment kaydı yok' bilgisini açıkça döner, yani boş yanıtı 'tool çalışmadı' diye okumayın.",
14
14
  inputSchema: { projectId: guid },
15
15
  annotations: readOnly
16
16
  }, handle(config, async ({ projectId }) => {
@@ -1,16 +1,14 @@
1
1
  import { orphanedFlowWarnings, orphanedFlowPlan, orphanedFlowMessage, boundEventOps, stripGatewayEventFields, staleSetterWarnings, normalizeSchemaOps, validationNote, componentDefaultsNote, replacePropNote, flexSizeWarnings, nestedRepeaterNodes, nestedRepeaterMessage, stringStyleNodes, stringStyleWarning, inertFlexPropNodes, inertFlexPropWarning, verticalGapWarnings, withNormalization, FLEX_LAYOUT_PROP_NAMES } from '../knowledge/normalize.js';
2
- import { opsParam, writeViewParam, outlineWriteResponse, unknownEventOps, collectTypes, styleTargetTypesFrom, simulateLayoutOps, removeNodeFromTree, planEventRemovals, planResizes, planPropTypes, assertOpBodies, applySkeletonOps, reshapesSkeleton } from './schemaOps.js';
2
+ import { opsParam, writeViewParam, outlineWriteResponse, unknownEventOps, collectTypes, simulateLayoutOps, removeNodeFromTree, planEventRemovals, planResizes, planPropTypes, assertOpBodies } from './schemaOps.js';
3
3
  import { guid, projectParam, environmentParam, updates, microOps } from './common.js';
4
4
  import { fetchHost, hostPath } from './screens.js';
5
5
  import { assertScreenWriteGuards, screenCatalogNotes } from './screenWrite.js';
6
6
  import { emptyWriteDiff, schemaOpDrops, withWriteDiff } from '../platform/writeDiff.js';
7
7
  import { fetchComponentEventNames } from './components.js';
8
+ import { boxSectionNote, collectIds, ensureBoxSections, expandSectionToggles } from '../knowledge/boxSections.js';
8
9
  import { PlatformApiError } from '../platform/errors.js';
9
- import { connectDataOpIssues, connectedPropKeys } from '../knowledge/connectDataDefinition.js';
10
10
  import { handle } from '../platform/responses.js';
11
11
  import { slotWarning } from './layouts.js';
12
- import { applicationTypeField, resolveProfile } from '../knowledge/platform/resolve.js';
13
- import { boundFlowSteps, layoutPatchWarnings, screenProfileWarnings } from './profileWrite.js';
14
12
  import { z } from 'zod';
15
13
  const HOSTS = {
16
14
  layout: {
@@ -61,6 +59,8 @@ export function registerDesignSchemaPatchTool(server, platform, host) {
61
59
  const resizeOps = allOps.filter(entry => entry.op === 'resize_component');
62
60
  const propTypeOps = allOps.filter(entry => entry.op === 'set_prop_type');
63
61
  const opRecords = allOps.filter(entry => !['remove_event', 'resize_component', 'set_prop_type'].includes(String(entry.op)));
62
+ const normalized = normalizeSchemaOps(opRecords);
63
+ assertOpBodies(opRecords, propTypeOps);
64
64
  const record = await fetchHost(platform, host, project, environment, applicationId, id);
65
65
  // Platform ucu kaydın türüne bakmaz: sıradan bir komponentin id'si verilirse kataloğundaki
66
66
  // tanımın yanına bir şema yazılırdı.
@@ -68,18 +68,14 @@ export function registerDesignSchemaPatchTool(server, platform, host) {
68
68
  throw new PlatformApiError(`component_schema_patch yalnız widget kaydına yazar; '${String(record.slug ?? id)}' bir widget değil (kind: ${String(record.kind ?? 'yok')}). Komponent kaydını component_update ile güncelleyin.`, 400);
69
69
  }
70
70
  const nodes = (record[spec.tree] ?? []);
71
+ // BX-002: bölge anahtarı Studio'da düğüm kurar; layout ve widget ağaçlarında da aynısı.
72
+ const sectionIds = collectIds(nodes, new Set());
73
+ const addedBodies = opRecords.filter(entry => entry.op === 'add_component').map(entry => entry.component);
74
+ collectIds(addedBodies, sectionIds);
75
+ const createdSections = ensureBoxSections(addedBodies, sectionIds);
76
+ const sectionToggles = expandSectionToggles(opRecords, nodes, sectionIds);
77
+ const sectionNotes = boxSectionNote([...createdSections, ...sectionToggles.created], sectionToggles.removed);
71
78
  const events = host === 'layout' ? record.events : undefined;
72
- // Normalizasyon kayıttan SONRA koşar: stil anahtarı çevirisi hedefin komponent TİPİNE bakar
73
- // (TB-129, table.style.th/td kebab-case kalır) ve tip yalnız okunan ağaçta var. Gövde hataları
74
- // bu yüzden bir okuma sonrasında rapor edilir; karar hiç değişmez, yalnız sıra değişti.
75
- const normalized = normalizeSchemaOps(opRecords, styleTargetTypesFrom(opRecords, nodes));
76
- assertOpBodies(opRecords, propTypeOps);
77
- // CD-005 layout ve widget host'unda da: bağlı prop'u (iç içe yol dahil) ezen yazma ve bağlı olmayan prop'ta
78
- // remove_connect_data okunan ağaca bakarak reddedilir (gövde denetimi assertOpBodies'te koştu).
79
- const connectedProps = connectedPropKeys(nodes);
80
- const connectionIssues = opRecords.flatMap(entry => connectDataOpIssues(entry, connectedProps).map(issue => `${issue.code} — ${issue.message}`));
81
- if (connectionIssues.length > 0)
82
- throw new PlatformApiError(`Connect Data op gövdesi geçersiz (istek gönderilmedi): ${connectionIssues.join(' · ')}`, 400);
83
79
  if (opRecords.some(entry => entry.op === 'set_event' || entry.op === 'add_event')) {
84
80
  const bound = boundEventOps(nodes, opRecords);
85
81
  if (bound.length > 0)
@@ -97,8 +93,7 @@ export function registerDesignSchemaPatchTool(server, platform, host) {
97
93
  if (deletedFlows.length > 0 && allowFlowDeletion !== true)
98
94
  throw new PlatformApiError(orphanedFlowMessage(deletedFlows), 400);
99
95
  const added = opRecords.filter(entry => entry.op === 'add_component').map(entry => entry.component);
100
- const resolved = await resolveProfile(platform, applicationId);
101
- assertScreenWriteGuards(spec.kind, { schema: added }, resolved.profile.platform);
96
+ assertScreenWriteGuards(spec.kind, { schema: added });
102
97
  const catalogNotes = await screenCatalogNotes(platform, project, environment, applicationId, added);
103
98
  const flowWarnings = opRecords.some(entry => entry.op === 'remove_component')
104
99
  ? [...orphanedFlowWarnings(nodes, events, opRecords), ...staleSetterWarnings(Array.isArray(record.flows) ? record.flows : [], opRecords, nodes)]
@@ -113,28 +108,17 @@ export function registerDesignSchemaPatchTool(server, platform, host) {
113
108
  || (entry.op === 'replace_prop' && FLEX_LAYOUT_PROP_NAMES.has(String(entry.prop ?? ''))));
114
109
  const nested = simulatable ? nestedRepeaterNodes(simulated) : [];
115
110
  if (nested.length > 0)
116
- throw new PlatformApiError(nestedRepeaterMessage(nested, resolved.profile.platform), 400);
111
+ throw new PlatformApiError(nestedRepeaterMessage(nested), 400);
117
112
  const reshaped = simulatable || opRecords.some(entry => entry.op === 'remove_component');
118
- const profileWarnings = await screenProfileWarnings(platform, resolved, project, environment, applicationId, {
119
- kind: spec.kind,
120
- ops: [...opRecords, ...propTypeOps],
121
- savedNodes: nodes,
122
- steps: await boundFlowSteps(platform, resolved, project, environment, host, applicationId, id, opRecords)
123
- });
124
113
  const layoutWarnings = reshaped
125
114
  ? [
126
- ...(resolved.profile.layout.blocksMeaningful ? verticalGapWarnings(simulated, spec.codes.gap, touched) : []),
115
+ ...verticalGapWarnings(simulated, spec.codes.gap, touched),
127
116
  ...stringStyleWarning(stringStyleNodes(simulated)),
128
- ...(resolved.profile.layout.modes.has('grid') ? inertFlexPropWarning(inertFlexPropNodes(simulated)) : []),
117
+ ...inertFlexPropWarning(inertFlexPropNodes(simulated)),
129
118
  ...flexSizeWarnings(simulated, spec.codes.flexMismatch, spec.codes.flexInvalid),
130
119
  ...(host === 'layout' ? slotWarning(simulated) : [])
131
120
  ]
132
121
  : [];
133
- if (host === 'layout' && reshapesSkeleton(opRecords)) {
134
- const skeleton = structuredClone(simulated);
135
- applySkeletonOps(skeleton, opRecords);
136
- layoutWarnings.push(...layoutPatchWarnings(resolved, nodes, skeleton));
137
- }
138
122
  const removedEvents = planEventRemovals(removeEventOps);
139
123
  const resized = resizeOps.length > 0 ? planResizes(nodes, resizeOps, spec.readTool) : { serverOps: [], applied: [], warnings: [] };
140
124
  const propTypes = propTypeOps.length > 0 ? planPropTypes(nodes, propTypeOps, spec.readTool) : { serverOps: [], applied: [] };
@@ -157,9 +141,8 @@ export function registerDesignSchemaPatchTool(server, platform, host) {
157
141
  response.deletedFlows = deletedFlows;
158
142
  if (flowWarnings.length > 0)
159
143
  response.flowWarnings = flowWarnings;
160
- if (layoutWarnings.length > 0 || profileWarnings.length > 0)
161
- response.layoutWarnings = [...layoutWarnings, ...profileWarnings];
162
- Object.assign(response, applicationTypeField(resolved));
144
+ if (layoutWarnings.length > 0)
145
+ response.layoutWarnings = layoutWarnings;
163
146
  const contentOps = opRecords.filter(entry => entry.op === 'add_component' || entry.op === 'replace_prop');
164
147
  let opDrops = emptyWriteDiff();
165
148
  if (contentOps.length > 0) {
@@ -172,6 +155,7 @@ export function registerDesignSchemaPatchTool(server, platform, host) {
172
155
  }
173
156
  }
174
157
  return withWriteDiff(withNormalization(response, [
158
+ ...sectionNotes,
175
159
  ...componentDefaultsNote(normalized.components),
176
160
  ...validationNote(normalized.validations),
177
161
  ...catalogNotes,
@@ -1,6 +1,5 @@
1
1
  import { guid, projectParam, environmentParam, definitionParam, pagingParams, readOnly, writes, updates, destructive } from './common.js';
2
2
  import { writeDiff, withWriteDiff } from '../platform/writeDiff.js';
3
- import { withNormalization } from '../knowledge/normalize.js';
4
3
  import { handle } from '../platform/responses.js';
5
4
  import { z } from 'zod';
6
5
  import { evaluatePolicy, enforcePolicy, attachFindings } from '../knowledge/policy.js';
@@ -30,46 +29,16 @@ export function registerDtoTools(server, platform) {
30
29
  }, handle(config, ({ project, environment, id }) => platform.tenant('GET', project, `/datatransferobjects/${id}/scheme`, { environment })));
31
30
  server.registerTool('dto_create', {
32
31
  title: 'DTO oluştur',
33
- description: "Yeni DataTransferObject tanımlar (definition = CreateDataTransferObjectCommand). Workflow'un parameterDtoId/returnDtoId sözleşmeleri buradan çıkar; şablon için dto_get kullanın. ALAN LİSTESİ 'children' alanındadır ve create gövdesinde YAZILIR; eşanlamlı olarak 'fields' de kabul edilir (gateway 'children'a çevirir — komut şemasında 'fields' yoktur ve platform onu sessizce düşürürdü, DTO-003). " + constraintSummary('CreateDataTransferObjectCommand'),
32
+ description: "Yeni DataTransferObject tanımlar (definition = CreateDataTransferObjectCommand). Workflow'un parameterDtoId/returnDtoId sözleşmeleri buradan çıkar; şablon için dto_get kullanın. " + constraintSummary('CreateDataTransferObjectCommand'),
34
33
  inputSchema: { project: projectParam, environment: environmentParam, definition: definitionParam, policyOverride: policyOverrideParam },
35
34
  annotations: writes
36
35
  }, handle(config, async ({ project, environment, definition, policyOverride }) => {
37
- const body = { ...definition };
38
- const notes = [];
39
- // DTO-003 / S2-28 — alan listesi 'fields' adıyla gelirse SESSİZCE kaybolurdu: komut şemasında
40
- // öyle bir üye yok, platform bilinmeyen üyeyi atıyor ve yanıt children:[] dönüyor. Ad eşlenir.
41
- if (Object.hasOwn(body, 'fields')) {
42
- const alias = body.fields;
43
- delete body.fields;
44
- if (body.children === undefined && alias !== undefined && alias !== null) {
45
- body.children = alias;
46
- notes.push("'fields' → 'children' olarak yazıldı: create gövdesinde alan listesinin adı 'children'dır, 'fields' sessizce düşerdi (DTO-003)");
47
- }
48
- else if (alias !== undefined && alias !== null) {
49
- notes.push("'fields' yok sayıldı: gövde zaten 'children' taşıyor (DTO-003)");
50
- }
51
- }
52
36
  // G-23: 09-05 koşusunda çocuk alanın `type: "text"` değeri sessizce `object`'e çevrildi ve
53
37
  // bu ancak platformun kendi ürettiği bir DTO okunarak fark edildi. Doğrusu `"string"` —
54
- // DTO-001 tip sözlüğünü artık istek gitmeden denetler. Denetim eşlemeden SONRA koşar ki
55
- // 'fields' ile gelen çocuklar da (slug zorunluluğu dâhil) ilk adımda yakalansın.
56
- const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'dto', body, { operation: 'create' }, policyOverride));
57
- let payload = await platform.tenant('POST', project, '/datatransferobjects', { environment, body });
58
- // İkinci adım EMNİYET KEMERİDİR, kural değil: 2026-09-20 ölçümünde create çocukları yazdı.
59
- // Yazmayan bir platform sürümünde (ya da bir alt kümeyi düşürdüğünde) gateway aynı yanıt
60
- // içinde update ile tamamlar — çağıran iki adımı görmez.
61
- const requested = Array.isArray(body.children) ? body.children : [];
62
- const created = (payload?.data ?? payload);
63
- const savedChildren = created?.children;
64
- const createdId = typeof created?.id === 'string' ? created.id : undefined;
65
- if (requested.length > 0 && createdId !== undefined && (!Array.isArray(savedChildren) || savedChildren.length < requested.length)) {
66
- payload = await platform.tenant('PUT', project, `/datatransferobjects/${createdId}`, {
67
- environment,
68
- body: { ...body, id: createdId }
69
- });
70
- notes.push(`alan listesi ikinci adımda update ile yazıldı: create ${requested.length} çocuğun ${Array.isArray(savedChildren) ? savedChildren.length : 0} tanesini kaydetti (DTO-003)`);
71
- }
72
- return attachFindings(withNormalization(withWriteDiff(payload, writeDiff(body, payload)), notes), findings);
38
+ // DTO-001 tip sözlüğünü artık istek gitmeden denetler.
39
+ const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'dto', definition, { operation: 'create' }, policyOverride));
40
+ const payload = await platform.tenant('POST', project, '/datatransferobjects', { environment, body: definition });
41
+ return attachFindings(withWriteDiff(payload, writeDiff(definition, payload)), findings);
73
42
  }));
74
43
  server.registerTool('dto_update', {
75
44
  title: 'DTO güncelle',