@appaflytech/zeyrek-ai-mcp 0.0.31 → 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 (205) 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 +233 -568
  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 -366
  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/middleware-authenticate.json +1 -1
  30. package/dist/resources/examples/page-detail-profile.json +1 -2
  31. package/dist/resources/examples/page-dynamic-form.json +2 -3
  32. package/dist/resources/examples/page-flex-sections.json +1 -1
  33. package/dist/resources/examples/page-html-embed.json +1 -1
  34. package/dist/resources/examples/workflow-basic.json +2 -8
  35. package/dist/resources/guides/component.md +5 -92
  36. package/dist/resources/guides/entity.md +8 -50
  37. package/dist/resources/guides/expressions.md +5 -14
  38. package/dist/resources/guides/functions.md +1 -1
  39. package/dist/resources/guides/getting-started.md +1 -38
  40. package/dist/resources/guides/layout.md +58 -55
  41. package/dist/resources/guides/merge.md +3 -37
  42. package/dist/resources/guides/microservice.md +2 -87
  43. package/dist/resources/guides/middleware.md +4 -68
  44. package/dist/resources/guides/page.md +75 -456
  45. package/dist/resources/guides/theme.md +2 -8
  46. package/dist/resources/guides/translation.md +1 -1
  47. package/dist/resources/guides/workflow.md +1 -58
  48. package/dist/resources/rules.js +5 -11
  49. package/dist/resources/schema-fingerprint.json +5 -7
  50. package/dist/resources/schemas/CreateEntityCommand.json +0 -118
  51. package/dist/resources/schemas/CreateMicroserviceCommand.json +1 -13
  52. package/dist/resources/schemas/CreateQueryCommand.json +0 -4
  53. package/dist/resources/schemas/CreateWorkflowCommand.json +1 -146
  54. package/dist/resources/schemas/DataJobDto.json +1 -6
  55. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +1 -21
  56. package/dist/resources/schemas/MicroserviceDto.json +3 -15
  57. package/dist/resources/schemas/PreviewMicroserviceCommand.json +1 -10
  58. package/dist/resources/schemas/PreviewWorkflowCommand.json +1 -25
  59. package/dist/resources/schemas/StepDto.json +1 -25
  60. package/dist/resources/schemas/UpdateEntityCommand.json +0 -118
  61. package/dist/resources/schemas/UpdateMicroserviceCommand.json +1 -13
  62. package/dist/resources/schemas/UpdateQueryCommand.json +0 -4
  63. package/dist/resources/schemas/UpdateViewCommand.json +2 -0
  64. package/dist/resources/schemas/UpdateWorkflowCommand.json +1 -146
  65. package/dist/server.js +1 -27
  66. package/dist/tools/access.js +2 -369
  67. package/dist/tools/applications.js +3 -60
  68. package/dist/tools/common.js +0 -7
  69. package/dist/tools/components.js +14 -118
  70. package/dist/tools/datasources.js +3 -3
  71. package/dist/tools/dependencies.js +1 -1
  72. package/dist/tools/deployments.js +3 -38
  73. package/dist/tools/designSchemaPatch.js +18 -34
  74. package/dist/tools/dtos.js +5 -36
  75. package/dist/tools/entities.js +12 -79
  76. package/dist/tools/externalComponents.js +5 -26
  77. package/dist/tools/flows.js +14 -122
  78. package/dist/tools/folders.js +1 -1
  79. package/dist/tools/imports.js +2 -5
  80. package/dist/tools/layouts.js +17 -50
  81. package/dist/tools/merges.js +2 -2
  82. package/dist/tools/microservices.js +25 -77
  83. package/dist/tools/pages.js +112 -465
  84. package/dist/tools/platformInfo.js +8 -27
  85. package/dist/tools/projects.js +9 -71
  86. package/dist/tools/rows.js +13 -69
  87. package/dist/tools/schemaOps.js +1 -61
  88. package/dist/tools/screenWrite.js +8 -37
  89. package/dist/tools/screens.js +5 -95
  90. package/dist/tools/templates.js +1 -26
  91. package/dist/tools/translations.js +1 -1
  92. package/dist/tools/variables.js +5 -11
  93. package/dist/tools/workflows.js +5 -10
  94. package/package.json +1 -1
  95. package/dist/knowledge/access.js +0 -802
  96. package/dist/knowledge/case.js +0 -41
  97. package/dist/knowledge/connectDataBind.js +0 -819
  98. package/dist/knowledge/connectDataDefinition.js +0 -341
  99. package/dist/knowledge/connectDataExecute.js +0 -93
  100. package/dist/knowledge/connectDataRules.js +0 -128
  101. package/dist/knowledge/decision.js +0 -121
  102. package/dist/knowledge/expressionPrelude.js +0 -59
  103. package/dist/knowledge/microserviceParameters.js +0 -58
  104. package/dist/knowledge/mining.js +0 -94
  105. package/dist/knowledge/mobileComponentCatalog.js +0 -859
  106. package/dist/knowledge/mobileComponentEvents.js +0 -239
  107. package/dist/knowledge/platform/lint.js +0 -385
  108. package/dist/knowledge/platform/mobile.js +0 -142
  109. package/dist/knowledge/platform/mobileLayoutLint.js +0 -324
  110. package/dist/knowledge/platform/mobileRules.js +0 -231
  111. package/dist/knowledge/platform/mobileSpacing.js +0 -82
  112. package/dist/knowledge/platform/mobileTabs.js +0 -108
  113. package/dist/knowledge/platform/nativeBoxModel.js +0 -44
  114. package/dist/knowledge/platform/profile.js +0 -25
  115. package/dist/knowledge/platform/resolve.js +0 -122
  116. package/dist/knowledge/platform/web.js +0 -39
  117. package/dist/knowledge/process.js +0 -510
  118. package/dist/knowledge/rowFilter.js +0 -43
  119. package/dist/knowledge/styleResolveNative.js +0 -527
  120. package/dist/platform/argumentAliases.js +0 -128
  121. package/dist/platform/bodyFile.js +0 -103
  122. package/dist/platform/capture/actions.js +0 -333
  123. package/dist/platform/capture/browser.js +0 -1
  124. package/dist/platform/capture/console-log.js +0 -122
  125. package/dist/platform/capture/index.js +0 -11
  126. package/dist/platform/capture/readiness.js +0 -103
  127. package/dist/platform/capture/summary.js +0 -77
  128. package/dist/platform/capture/target.js +0 -5
  129. package/dist/platform/capture/targets/studio-mobile.js +0 -15
  130. package/dist/platform/capture/targets/studio-web.js +0 -5
  131. package/dist/platform/impersonation.js +0 -45
  132. package/dist/platform/jsonArray.js +0 -24
  133. package/dist/platform/schemaReadMemory.js +0 -60
  134. package/dist/resources/examples/bpm-gorev-kontrol.json +0 -294
  135. package/dist/resources/examples/bpm-iso-dokuman.json +0 -228
  136. package/dist/resources/examples/bpm-satinalma.json +0 -376
  137. package/dist/resources/examples/connect-data-convert-verify.json +0 -107
  138. package/dist/resources/examples/connect-data-dropdown-roles.json +0 -66
  139. package/dist/resources/examples/connect-data-edit-m2m.json +0 -73
  140. package/dist/resources/examples/connect-data-query-params.json +0 -50
  141. package/dist/resources/examples/connect-data-table-entity.json +0 -147
  142. package/dist/resources/examples/connect-data-workflow-microservice.json +0 -65
  143. package/dist/resources/examples/mobile-app-shell-drawer.json +0 -243
  144. package/dist/resources/examples/mobile-app-shell-stack.json +0 -157
  145. package/dist/resources/examples/mobile-app-shell-tab.json +0 -208
  146. package/dist/resources/examples/mobile-form-screen.json +0 -365
  147. package/dist/resources/examples/mobile-list-detail-form.json +0 -672
  148. package/dist/resources/guides/access.md +0 -810
  149. package/dist/resources/guides/bpm.md +0 -691
  150. package/dist/resources/guides/case.md +0 -153
  151. package/dist/resources/guides/decision.md +0 -185
  152. package/dist/resources/guides/mobile-layout.md +0 -193
  153. package/dist/resources/guides/mobile.md +0 -495
  154. package/dist/resources/read.js +0 -41
  155. package/dist/resources/schemas/AccessExplanationDto.json +0 -144
  156. package/dist/resources/schemas/AccessMatrixDto.json +0 -170
  157. package/dist/resources/schemas/AccessPermissionDto.json +0 -57
  158. package/dist/resources/schemas/AccessPolicyDto.json +0 -223
  159. package/dist/resources/schemas/AccessResourceDto.json +0 -86
  160. package/dist/resources/schemas/AppSessionDto.json +0 -53
  161. package/dist/resources/schemas/ConnectDataDescribeDto.json +0 -344
  162. package/dist/resources/schemas/ConnectDataRequestModel.json +0 -202
  163. package/dist/resources/schemas/ConnectDataResultDto.json +0 -421
  164. package/dist/resources/schemas/ConnectorCredentialDto.json +0 -70
  165. package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +0 -37
  166. package/dist/resources/schemas/CreateAccessPolicyCommand.json +0 -209
  167. package/dist/resources/schemas/CreateDecisionCommand.json +0 -221
  168. package/dist/resources/schemas/CreateProcessDefinitionCommand.json +0 -1337
  169. package/dist/resources/schemas/DecisionDto.json +0 -302
  170. package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +0 -28
  171. package/dist/resources/schemas/ExplainAccessQuery.json +0 -33
  172. package/dist/resources/schemas/GenerateProcessDocumentCommand.json +0 -116
  173. package/dist/resources/schemas/OrganizationProjectDto.json +0 -335
  174. package/dist/resources/schemas/OrganizationSchemaDto.json +0 -196
  175. package/dist/resources/schemas/OrganizationSchemaVersionDto.json +0 -207
  176. package/dist/resources/schemas/PatchProcessDefinitionCommand.json +0 -76
  177. package/dist/resources/schemas/ProcessDefinitionDto.json +0 -1480
  178. package/dist/resources/schemas/ProcessSimulationDto.json +0 -96
  179. package/dist/resources/schemas/SaveConnectorCredentialCommand.json +0 -90
  180. package/dist/resources/schemas/SaveProcessEventSourceCommand.json +0 -61
  181. package/dist/resources/schemas/SaveProcessMailSourceCommand.json +0 -89
  182. package/dist/resources/schemas/SignProcessTaskCommand.json +0 -73
  183. package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +0 -92
  184. package/dist/resources/schemas/UpdateAccessPolicyCommand.json +0 -209
  185. package/dist/resources/schemas/UpdateDecisionCommand.json +0 -216
  186. package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +0 -1357
  187. package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +0 -1339
  188. package/dist/tools/accessOperations.js +0 -135
  189. package/dist/tools/accessPolicies.js +0 -170
  190. package/dist/tools/accessRuntime.js +0 -203
  191. package/dist/tools/bpm.js +0 -343
  192. package/dist/tools/bpmGovernance.js +0 -266
  193. package/dist/tools/bpmOperations.js +0 -230
  194. package/dist/tools/bpmReporting.js +0 -154
  195. package/dist/tools/bpmRouting.js +0 -150
  196. package/dist/tools/bpmRuntime.js +0 -396
  197. package/dist/tools/case.js +0 -178
  198. package/dist/tools/caseRuntime.js +0 -89
  199. package/dist/tools/connectData.js +0 -449
  200. package/dist/tools/connectors.js +0 -193
  201. package/dist/tools/decisions.js +0 -206
  202. package/dist/tools/mobile.js +0 -221
  203. package/dist/tools/modules.js +0 -48
  204. package/dist/tools/organizationStructure.js +0 -137
  205. 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
@@ -1,51 +1,16 @@
1
1
  import { guid, readOnly, writes } from './common.js';
2
2
  import { handle } from '../platform/responses.js';
3
- // Koşu 42 S-21: promote yayınlanmamış taslağı taşımaz (sözleşme) ve saga bunu hiçbir yerde söylemez.
4
- // Liste kaynak environment'ın şemasından okunur; okunamazsa deployment yine başlar, uyarı düşer.
5
- async function readUnpublishedDrafts(platform, projectId, sourceEnvironmentId) {
6
- const project = await platform.org('GET', `/projects/${projectId}`);
7
- const slug = project?.data?.slug;
8
- const environment = project?.data?.environments?.find(entry => entry.id === sourceEnvironmentId)?.name;
9
- if (!slug || !environment)
10
- return undefined;
11
- const drafts = [];
12
- for (let pageIndex = 0; pageIndex < 50; pageIndex++) {
13
- const page = await platform.tenant('GET', slug, '/bpm/definitions', { environment, query: { pageIndex, pageLength: 200 } });
14
- for (const definition of page?.data ?? []) {
15
- if (definition.hasDraft !== true)
16
- continue;
17
- // Taslak numarası 2026-09-25'ten eski platformda gelmez; yeni taslak her zaman en son sürümdür.
18
- drafts.push({ slug: definition.slug, name: definition.name, draftVersionNumber: definition.draftVersionNumber ?? definition.latestVersionNumber ?? null, activeVersionNumber: definition.activeVersionNumber ?? null });
19
- }
20
- if (pageIndex + 1 >= (page?.meta?.totalPage ?? 1))
21
- break;
22
- }
23
- return drafts;
24
- }
25
3
  export function registerDeploymentTools(server, platform) {
26
4
  const config = platform.config;
27
5
  server.registerTool('deployment_start', {
28
6
  title: 'Deployment başlat',
29
- 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. KAYNAK YALNIZ DEVELOPMENT\'TIR: dal ya da production kaynak verilirse 400 (CantDeployFromBranchException) — dalı önce development\'a merge edin. ÖN DENETİM: deploy başlamadan production verisi denetlenir; veriyi bozacak ya da silecek her değişiklik 400 (DeploymentDataRiskException) ile listelenir ve deploy BAŞLAMAZ — biçim \'tablo.alan: tür (satır)\', türler not-null | unique | field-removed | table-removed | localization-move. Kayıt taşıması \'all\' olan tabloda production development\'ın AYNASIDIR (kaynakta olmayan satır ve çevirisi silinir). Microfunction\'ın yalnız YAYINLANMIŞ kodu taşınır ve hedefte yayınlanır; hiç yayınlanmamış olan hedefte taslak kalır. Zamanlanmış işin duraklatma durumu taşınır. YAYINLANMAMIŞ TASLAK TAŞINMAZ: kaynakta taslağı olan süreçler yanıtta unpublishedDrafts ({ slug, name, draftVersionNumber, activeVersionNumber }) ve note ile listelenir; hedefte aktif sürüm kalır. Taşımak için taslağı kaynakta yayınlayın (requireGreenScenarios açıksa önce senaryoları taslak üzerinde koşun), sonra yeniden deploy edin.',
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.',
30
8
  inputSchema: { projectId: guid, sourceEnvironmentId: guid, targetEnvironmentId: guid },
31
9
  annotations: writes
32
- }, handle(config, async ({ projectId, ...body }) => {
33
- const unpublishedDrafts = await readUnpublishedDrafts(platform, projectId, body.sourceEnvironmentId).catch(() => undefined);
34
- const payload = await platform.org('POST', `/deployments/${projectId}/deploy`, { body });
35
- if (!unpublishedDrafts?.length || !payload || typeof payload !== 'object')
36
- return payload;
37
- const listed = unpublishedDrafts
38
- .map(draft => `${String(draft.slug)} (taslak v${String(draft.draftVersionNumber)}, aktif ${draft.activeVersionNumber === null ? 'yok' : `v${String(draft.activeVersionNumber)}`})`)
39
- .join(', ');
40
- return {
41
- ...payload,
42
- unpublishedDrafts,
43
- note: `Kaynakta yayınlanmamış taslağı olan ${unpublishedDrafts.length} süreç var; promote taslak taşımaz, hedefte aktif sürüm kalır: ${listed}. Taşımak için taslağı kaynakta yayınlayın (requireGreenScenarios açıksa önce senaryoları taslak üzerinde koşun), sonra yeniden deploy edin.`
44
- };
45
- }));
10
+ }, handle(config, ({ projectId, ...body }) => platform.org('POST', `/deployments/${projectId}/deploy`, { body })));
46
11
  server.registerTool('deployment_status', {
47
12
  title: 'Deployment durumu',
48
- 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. type 'error' ise 'error' alanı düşüş nedenini taşır (DefinitionInvalid'de bulgular 'yol: mesaj | …' olarak eklenir); aktarım atomiktir, hedef değişmemiştir.",
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.",
49
14
  inputSchema: { projectId: guid },
50
15
  annotations: readOnly
51
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',