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