@appaflytech/zeyrek-ai-mcp 0.0.24 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/.env.example +0 -15
  2. package/dist/config.js +0 -11
  3. package/dist/index.js +0 -2
  4. package/dist/knowledge/componentCatalog.js +25 -13
  5. package/dist/knowledge/componentEvents.js +6 -13
  6. package/dist/knowledge/normalize.js +17 -68
  7. package/dist/knowledge/rules.js +19 -112
  8. package/dist/knowledge/styleResolve.js +4 -50
  9. package/dist/knowledge/themeResolve.js +3 -3
  10. package/dist/observability/trace.js +1 -1
  11. package/dist/platform/diagnostics.js +4 -10
  12. package/dist/platform/domSummary.js +1 -1
  13. package/dist/platform/http.js +7 -23
  14. package/dist/platform/responses.js +2 -6
  15. package/dist/platform/{capture/capture.js → screenshot.js} +514 -52
  16. package/dist/platform/secrets.js +0 -9
  17. package/dist/platform/strictArguments.js +12 -68
  18. package/dist/platform/tokenVault.js +4 -187
  19. package/dist/resources/examples/workflow-http-step.json +2 -2
  20. package/dist/resources/guides/component.md +1 -6
  21. package/dist/resources/guides/expressions.md +2 -2
  22. package/dist/resources/guides/functions.md +1 -1
  23. package/dist/resources/guides/layout.md +7 -11
  24. package/dist/resources/guides/microservice.md +4 -10
  25. package/dist/resources/guides/middleware.md +1 -5
  26. package/dist/resources/guides/page.md +55 -215
  27. package/dist/resources/guides/theme.md +1 -4
  28. package/dist/resources/guides/translation.md +1 -1
  29. package/dist/resources/guides/workflow.md +7 -11
  30. package/dist/resources/schema-fingerprint.json +2 -2
  31. package/dist/resources/schemas/CreateWorkflowCommand.json +3 -0
  32. package/dist/resources/schemas/PreviewWorkflowCommand.json +3 -0
  33. package/dist/resources/schemas/StepDto.json +12 -9
  34. package/dist/resources/schemas/UpdateWorkflowCommand.json +3 -0
  35. package/dist/server.js +1 -3
  36. package/dist/tools/applications.js +3 -60
  37. package/dist/tools/components.js +10 -50
  38. package/dist/tools/datasources.js +1 -1
  39. package/dist/tools/designSchemaPatch.js +6 -16
  40. package/dist/tools/externalComponents.js +4 -25
  41. package/dist/tools/flows.js +6 -79
  42. package/dist/tools/layouts.js +12 -44
  43. package/dist/tools/microservices.js +10 -26
  44. package/dist/tools/pages.js +67 -303
  45. package/dist/tools/platformInfo.js +2 -6
  46. package/dist/tools/rows.js +1 -7
  47. package/dist/tools/schemaOps.js +1 -1
  48. package/dist/tools/screenWrite.js +5 -6
  49. package/dist/tools/screens.js +3 -90
  50. package/dist/tools/workflows.js +1 -1
  51. package/package.json +1 -1
  52. package/dist/knowledge/mobileComponentCatalog.js +0 -801
  53. package/dist/knowledge/mobileComponentEvents.js +0 -225
  54. package/dist/knowledge/platform/lint.js +0 -312
  55. package/dist/knowledge/platform/mobile.js +0 -78
  56. package/dist/knowledge/platform/mobileRules.js +0 -182
  57. package/dist/knowledge/platform/mobileTabs.js +0 -108
  58. package/dist/knowledge/platform/profile.js +0 -20
  59. package/dist/knowledge/platform/resolve.js +0 -122
  60. package/dist/knowledge/platform/web.js +0 -38
  61. package/dist/knowledge/styleResolveNative.js +0 -510
  62. package/dist/platform/argumentAliases.js +0 -128
  63. package/dist/platform/bodyFile.js +0 -103
  64. package/dist/platform/capture/actions.js +0 -333
  65. package/dist/platform/capture/browser.js +0 -1
  66. package/dist/platform/capture/console-log.js +0 -80
  67. package/dist/platform/capture/index.js +0 -11
  68. package/dist/platform/capture/readiness.js +0 -103
  69. package/dist/platform/capture/summary.js +0 -77
  70. package/dist/platform/capture/target.js +0 -5
  71. package/dist/platform/capture/targets/studio-mobile.js +0 -15
  72. package/dist/platform/capture/targets/studio-web.js +0 -5
  73. package/dist/platform/schemaReadMemory.js +0 -60
  74. package/dist/resources/examples/mobile-app-shell-drawer.json +0 -209
  75. package/dist/resources/examples/mobile-app-shell-stack.json +0 -123
  76. package/dist/resources/examples/mobile-app-shell-tab.json +0 -174
  77. package/dist/resources/examples/mobile-list-detail-form.json +0 -656
  78. package/dist/resources/guides/mobile.md +0 -419
  79. package/dist/tools/mobile.js +0 -203
  80. package/dist/tools/profileWrite.js +0 -45
@@ -137,14 +137,11 @@ export function readsBeforeGuard(source, root) {
137
137
  * code.ts:49). Eşleşme yoksa flow-engine.ts:79 sessizce durur. Studio tarafında da zincir
138
138
  * `sourceBranch === 'always'` ile çizilir (EventActionsStart.svelte:47, EventActionsItem.svelte:298).
139
139
  * condition dalları rule id'sidir (serbest), microservice'te 'success' yalnız eski şema için
140
- * yaşatılır (microservice.ts:174 `isHasSuccess`). 'error' dalı 2026-09-26'dan beri motorun
141
- * KENDİSİ tanır (ADR 0004, ZM-07/g-02): bağlıysa hata anında `always` hiç koşmaz, sürer
142
- * (microservice.ts:182 `hasBranch`) — eski motor tanımadığı dalı hiç aramadığı için bu ekleme
143
- * geriye dönük zararsızdır.
140
+ * yaşatılır (microservice.ts:144).
144
141
  */
145
142
  const flowBranchNames = {
146
143
  start: ['always'],
147
- microservice: ['always', 'success', 'error'],
144
+ microservice: ['always', 'success'],
148
145
  confirm: ['yes', 'no', 'always'],
149
146
  function: ['always'],
150
147
  end: []
@@ -157,7 +154,7 @@ const flowBranchNames = {
157
154
  */
158
155
  export const knownFlowStepTypes = new Set([
159
156
  'start', 'end', 'query', 'setter', 'download', 'condition', 'redirect', 'setcookie', 'alert', 'confirm',
160
- 'microservice', 'validation', 'flow-trigger', 'storage', 'navigate', 'code', 'function', 'share'
157
+ 'microservice', 'validation', 'flow-trigger', 'storage', 'navigate', 'code', 'function'
161
158
  ]);
162
159
  const flowFreeBranchTypes = new Set(['condition']);
163
160
  /** `condition.types.ts` ConditionArgumentRuleType — motorun tanıdığı üçlü. */
@@ -170,15 +167,16 @@ const conditionRuleIdPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}
170
167
  // Runtime.svelte'de HAM verilir (`argument: step.args`), yani bu alanlarda ifade değerlendirilmez.
171
168
  const flowLiteralTextFields = new Map([
172
169
  ['alert', ['message', 'description']],
173
- ['confirm', ['message', 'title', 'confirmText', 'cancelText']],
174
- ['share', ['title']]
170
+ ['confirm', ['message', 'title', 'confirmText', 'cancelText']]
175
171
  ]);
176
172
  const flowExpressionLooking = /\$\{|\b(?:Steps|Page|Row|Widget|LocalStorage|state|self|item|event|error|cookie)\s*(?:\?\.|\.|\[)/;
177
- // Barındırıcıya özel tipler BURADA kural üretmez. `navigate`i gateway normalizasyonu zaten
178
- // `redirect`e çeviriyor (normalize.ts `normalizeFlowHostGaps`) — `redirect` iki barındırıcıda da
179
- // koşar, yani vaka uyarılmaz, ORTADAN KALKAR. Gateway uygulamanın tipini platform profilinden bilir
180
- // ve barındırıcı sözlüğü `platform/*.ts`'tedir (`profile.steps`); mobil farkları orada `MOB-005`
181
- // olarak konuşulur (`platform/lint.ts`). Yeni mobil runtime `confirm`/`download`'ı kaydeder.
173
+ // Barındırıcıya özel tipler (`navigate` web'de, `confirm`/`download` mobilde register edilmez)
174
+ // BURADA kural üretmez. `navigate`i gateway normalizasyonu zaten `redirect`e çeviriyor
175
+ // (normalize.ts `normalizeFlowHostGaps`) — `redirect` iki barındırıcıda da koşar, yani vaka
176
+ // uyarılmaz, ORTADAN KALKAR. Geriye kalan `confirm`/`download` tek başına kusur değildir: sayfa
177
+ // tek bir uygulamaya aittir (`Page.ApplicationId`), uygulamanın tipi web ya da mobile'dır
178
+ // (`ApplicationType.cs`) ve gateway hangisi olduğunu bilmez. Mobil ayağı uygulama tarafında
179
+ // kapanır (`ScreenRuntime.tsx`), lint'te değil.
182
180
  const flowUnregisteredStepTypes = new Set(['end', 'query']);
183
181
  const flowSetterIterateeTypes = new Set(['change', 'fill']);
184
182
  function flowStepList(value) {
@@ -298,71 +296,25 @@ function writesRolesWithoutSlug(entityId, parameters) {
298
296
  }
299
297
  const rolesSlugMessage = "Built-in 'roles' entity'sine slug YAZMADAN rol satırı ÜRETİLİYOR (operation create/upsert). Insert 200 döner, satır role_list'te görünür ve page.roleIds ile bağlanır — ama yetkilendirme SLUG karşılaştırır: platformun get-user sorgusu roles+user_roles join'inden slug dizisi üretir ve Authorized(user.roles) o rol için hiçbir zaman tutmaz. fields'a slug'ı ekleyin ('super-admin' slug'ını vermeyin — platform süper yöneticiyi o slug ile arar). Upsert'te slug'ı İFADEYLE üretmeyin: UPDATE yolunda ifade yeniden değerlendirilir ve var olan rolün slug'ı sessizce değişir (MS-016) — üretilen slug'ı yalnız create ucunda yazın. Rolü kullanıcıya bağlamak ayrı bir user_roles satırıdır.";
300
298
  const contractKeys = ['returnDtoId', 'parameterDtoId', 'returnBehavior', 'parameterBehavior'];
301
- /**
302
- * Filtre işleci sözlüğü — backend `OperatorType` enum'u (paketlenmiş `Filter` şeması; eşitliği
303
- * `test/filter-operators.test.ts` kilitler). Studio filtre ARAYÜZÜNÜN sözlüğü (`notContains`, `between`…,
304
- * `componentCatalog.ts`) ayrı bir kavramdır: arayüz onları bu işleçlere çevirir.
305
- */
306
- export const filterOperators = new Set(['eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'contains', 'icontains', 'in', 'notin', 'startswith', 'endswith', 'istartswith', 'iendswith', 'isnull', 'isnotnull']);
307
- /** Ajanların sık yazdığı yanlış adlar → doğru işleç. Yalnız ÖNERİLİR, sessizce çevrilmez. */
308
- const filterOperatorSuggestions = {
309
- ne: 'neq', '!=': 'neq', '<>': 'neq', noteq: 'neq', notequal: 'neq', notequals: 'neq', not_eq: 'neq',
310
- '=': 'eq', '==': 'eq', equal: 'eq', equals: 'eq',
311
- '<': 'lt', '<=': 'lte', '>': 'gt', '>=': 'gte',
312
- like: 'contains', ilike: 'icontains', nin: 'notin', 'not in': 'notin', not_in: 'notin'
313
- };
299
+ const filterOperators = new Set(['eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'contains', 'icontains', 'in', 'notin', 'startswith', 'endswith', 'istartswith', 'iendswith', 'isnull', 'isnotnull']);
314
300
  function flattenFilterTree(filters) {
315
301
  return filters
316
302
  .filter((filter) => Boolean(filter) && typeof filter === 'object')
317
303
  .flatMap(filter => [filter, ...flattenFilterTree(asArray(filter.children))]);
318
304
  }
319
- /**
320
- * Bilinmeyen işleçler, öneriyle: `status: 'ne' (neq mı demek istedin?)`. Grup çocukları da okunur. Ad
321
- * büyük/küçük harfe DUYARLI eşlenir — backend de öyle eşler (`GetValueFromDescription` `==`); `NEQ`
322
- * bilinmeyendir ve küçük harfli adı önerilir.
323
- */
324
- function unknownFilterOperators(filters) {
325
- return flattenFilterTree(filters)
326
- .filter(filter => filter.operator !== undefined && filter.operator !== null && !filterOperators.has(String(filter.operator)))
327
- .map(filter => {
328
- const operator = String(filter.operator);
329
- const lower = operator.toLowerCase();
330
- const suggestion = filterOperators.has(lower) ? lower : filterOperatorSuggestions[lower];
331
- return `${String(filter.fieldSlug ?? filter.fieldId ?? '?')}: '${operator}'${suggestion ? ` (${suggestion} mı demek istedin?)` : ''}`;
332
- });
333
- }
334
- const unknownOperatorConsequence = "Bilinmeyen işleç yola ve backend sürümüne göre ya 400 alır ya sessizce 'eq'e düşer ve sorgu yanlış sonuç döner (2026-09-27'den sonraki backend uç çağrısının `filters` parametresini 400 ile reddeder; workflow tablo adımı hâlâ sessizce 'eq' yapar); ad büyük/küçük harfe duyarlıdır — doğru işleci yazın";
335
305
  function unknownOperatorFindings(ruleId, owner, filters) {
336
- const unknownOperators = unknownFilterOperators(filters);
306
+ const unknownOperators = flattenFilterTree(filters)
307
+ .filter(filter => filter.operator !== undefined && filter.operator !== null && !filterOperators.has(String(filter.operator).toLowerCase()))
308
+ .map(filter => `${String(filter.fieldSlug ?? filter.fieldId ?? '?')}: '${String(filter.operator)}'`);
337
309
  return unknownOperators.length > 0
338
310
  ? [{
339
311
  ruleId,
340
312
  severity: 'block',
341
- message: `${owner}: bilinmeyen filtre işleci — ${unknownOperators.join(', ')}. ${unknownOperatorConsequence}. Geçerli sözlük: ${[...filterOperators].join(' · ')} ('like' yok — metin araması için 'contains'/'icontains').`,
313
+ message: `${owner}: bilinmeyen filtre operatörü — ${unknownOperators.join(', ')}. Platform bilinmeyen operatörü 400 ile REDDETMEZ, sessizce 'eq'e düşürür (EnumExtensions.GetValueFromDescription null → default) ve uç testten geçip yanlış çalışır. Geçerli sözlük: ${[...filterOperators].join(' · ')} ('like' yok — metin araması için 'contains'/'icontains').`,
342
314
  guide: 'ngapps://guides/microservice'
343
315
  }]
344
316
  : [];
345
317
  }
346
- /**
347
- * Çalışma anında gelen filtre (`row_list.filters`, `microservice_execute` `filters` parametresi): dizi ya
348
- * da JSON dizesi. Bilinmeyen işleç varsa hata METNİ döner — araç isteği göndermeden 400 verir
349
- * (plans/mobil-plantcare-acigi g-03). Ayrıştırılamayan değer backend'e bırakılır.
350
- */
351
- export function filterOperatorError(owner, filters) {
352
- let parsed = filters;
353
- if (typeof filters === 'string') {
354
- try {
355
- parsed = JSON.parse(filters);
356
- }
357
- catch {
358
- return undefined;
359
- }
360
- }
361
- const unknownOperators = Array.isArray(parsed) ? unknownFilterOperators(parsed) : [];
362
- return unknownOperators.length > 0
363
- ? `${owner}: bilinmeyen filtre işleci — ${unknownOperators.join(', ')}. İstek GÖNDERİLMEDİ. ${unknownOperatorConsequence}. Geçerli sözlük: ${[...filterOperators].join(' · ')}.`
364
- : undefined;
365
- }
366
318
  function isReadOperation(parameters) {
367
319
  const operation = String(parameters?.operation ?? '').toLowerCase();
368
320
  return !writeOperations.has(operation);
@@ -2415,7 +2367,7 @@ export const policyRules = [
2415
2367
  id: 'FLOW-022',
2416
2368
  module: 'flow',
2417
2369
  appliesTo: ['create', 'update'],
2418
- sourceRef: "alert.ts `const { message, alertType, description } = task.argument` → toast.error(message, { description }) / dialog.alert(message); confirm.ts `dialog.confirm(message, { title, confirmText, cancelText })` (boş çerçeve metni dialog.functions.ts resolveDialogFrame'de sabit metne düşer). Argüman Runtime.svelte'de HAM geçer (`argument: step.args`) — bu alanlarda hiçbir ifade değerlendirilmez, yazılan metin ekranda harfi harfine görünür (2026-09-06·2 koşusu S-13'ün ikinci turu: rehber hata mesajını göstermek için alert adımını öneriyordu). share adımında (2026-09-25) yalnız `title` düz metindir: @ng-apps/flow resolveShareContent onu olduğu gibi verir, `message` ve `path` ifadedir",
2370
+ sourceRef: "alert.ts `const { message, alertType, description } = task.argument` → toast.error(message, { description }) / dialog.alert(message); confirm.ts `dialog.confirm(message, { title, confirmText, cancelText })` (boş çerçeve metni dialog.functions.ts resolveDialogFrame'de sabit metne düşer). Argüman Runtime.svelte'de HAM geçer (`argument: step.args`) — bu alanlarda hiçbir ifade değerlendirilmez, yazılan metin ekranda harfi harfine görünür (2026-09-06·2 koşusu S-13'ün ikinci turu: rehber hata mesajını göstermek için alert adımını öneriyordu)",
2419
2371
  check: definition => flowAllSteps(definition)
2420
2372
  .flatMap((step) => {
2421
2373
  const type = String(step.type ?? '');
@@ -2428,61 +2380,16 @@ export const policyRules = [
2428
2380
  .map(field => ({
2429
2381
  ruleId: 'FLOW-022',
2430
2382
  severity: 'warn',
2431
- message: type === 'share'
2432
- ? `'${flowStepLabel(step)}' share adımının '${field}' alanı ifade içeriyor ama bu alan DÜZ METİNDİR: başlık paylaşım penceresine olduğu gibi gider (iOS'ta e-posta konusu, Android'de seçici başlığı), ifade değerlendirilmez. Değişen içeriği ifade olan 'message' alanına yazın — ör. message: "'Şuna bak: ' + Page.properties.name"; bağlantı 'path' alanındadır.`
2433
- : `'${flowStepLabel(step)}' ${type} adımının '${field}' alanı ifade içeriyor ama bu alan DÜZ METİNDİR: ${type}.ts task.argument.${field}'i doğrudan ekrana geçirir ve args hiçbir yerde değerlendirilmez (Runtime.svelte \`argument: step.args\`). Kullanıcı ifadenin sonucunu değil ifadenin KENDİSİNİ görür. Ucun mesajını göstermek için bir setter (ya da code) adımı kullanın — value { type: 'code', ref: 'Steps.error?.message' }; hata metninin nerede durduğu page.md §hata yolu'nda.`,
2383
+ message: `'${flowStepLabel(step)}' ${type} adımının '${field}' alanı ifade içeriyor ama bu alan DÜZ METİNDİR: ${type}.ts task.argument.${field}'i doğrudan ekrana geçirir ve args hiçbir yerde değerlendirilmez (Runtime.svelte \`argument: step.args\`). Kullanıcı ifadenin sonucunu değil ifadenin KENDİSİNİ görür. Ucun mesajını göstermek için bir setter (ya da code) adımı kullanın — value { type: 'code', ref: 'Steps.error?.message' }; hata metninin nerede durduğu page.md §hata yolu'nda.`,
2434
2384
  guide: 'ngapps://guides/page'
2435
2385
  }));
2436
2386
  })
2437
2387
  },
2438
- {
2439
- id: 'FLOW-027',
2440
- module: 'flow',
2441
- appliesTo: ['create', 'update'],
2442
- sourceRef: "share adımının argümanı StepManagementArgument'ın Title/Message/Path alanlarında saklanır (StepType.cs `share`, kök docs/adr/0001-share-akis-adimi.md); url/link/text gibi anahtarlar sözleşmede YOKTUR ve platform onları 200 ile sessizce düşürür — adım hiçbir şey paylaşmadan akış sürer. `message` ve `path` İFADEDİR (@ng-apps/flow resolveShareContent → runCode): tırnaksız 'https://…' JS'te etiket + yorumdur, undefined döner",
2443
- check: definition => flowAllSteps(definition)
2444
- .filter(step => step.type === 'share')
2445
- .flatMap((step) => {
2446
- const args = (step.args ?? {});
2447
- const filled = (key) => typeof args[key] === 'string' && String(args[key]).trim().length > 0;
2448
- const findings = [];
2449
- const strayLinks = ['url', 'link', 'href'].filter(filled);
2450
- const strayTexts = ['text', 'body', 'content'].filter(filled);
2451
- if (strayLinks.length > 0) {
2452
- findings.push({
2453
- ruleId: 'FLOW-027',
2454
- severity: filled('path') ? 'warn' : 'block',
2455
- message: `'${flowStepLabel(step)}' share adımının bağlantısı args.${strayLinks.join('/args.')} alanında: bu anahtar StepManagementArgument sözleşmesinde YOK, platform onu 200 ile sessizce düşürür ve adım bağlantısız kalır. Bağlantıyı args.path'e ifade olarak yazın — ör. "'https://ornek.app/urun/' + Page.queryParams.id".`,
2456
- guide: 'ngapps://guides/page'
2457
- });
2458
- }
2459
- if (strayTexts.length > 0) {
2460
- findings.push({
2461
- ruleId: 'FLOW-027',
2462
- severity: filled('message') ? 'warn' : 'block',
2463
- message: `'${flowStepLabel(step)}' share adımının metni args.${strayTexts.join('/args.')} alanında: bu anahtar StepManagementArgument sözleşmesinde YOK, platform onu sessizce düşürür. Metni args.message'a ifade olarak yazın — ör. "'Şuna bak: ' + Page.properties.name".`,
2464
- guide: 'ngapps://guides/page'
2465
- });
2466
- }
2467
- for (const key of ['message', 'path']) {
2468
- const value = typeof args[key] === 'string' ? String(args[key]).trim() : '';
2469
- if (/^[a-z][a-z\d+\-.]*:\/\//i.test(value)) {
2470
- findings.push({
2471
- ruleId: 'FLOW-027',
2472
- severity: 'block',
2473
- message: `'${flowStepLabel(step)}' share adımının '${key}' alanı tırnaksız bir adres: '${value}'. Bu alan İFADEDİR — tırnaksız adres JS'te etiket + yorumdur, undefined döner ve hiçbir şey paylaşılmaz. Dize olarak yazın: "'${value}'".`,
2474
- guide: 'ngapps://guides/page'
2475
- });
2476
- }
2477
- }
2478
- return findings;
2479
- })
2480
- },
2481
2388
  {
2482
2389
  id: 'FLOW-023',
2483
2390
  module: 'flow',
2484
2391
  appliesTo: ['create', 'update'],
2485
- sourceRef: "Adım tipi sözlüğü backend'indir (StepType.cs) ama koşan tipler barındırıcıdan gelir: flow-engine.ts start·setter·code·condition·microservice·validation·flow-trigger register eder, web Runtime.svelte alert·confirm·redirect·download·storage·setcookie ekler, mobil @ng-apps/ui-native runtime-tasks.ts alert·confirm·redirect·navigate·storage·setcookie·download ekler. navigate web'de YOKTUR; end ve query hiçbir barındırıcıda yoktur (Studio kataloğu da bunu visibility ile söyler: navigate 'mobile', End eklenebilir adımlar arasında değil — EventActionsAdd.svelte). Register edilmemiş tipe gelen akış SESSİZCE durur: flow-engine.ts process() callback bulamazsa hiçbir şey yapmaz (next yok, completed/stopped yok, hata yok, log yok), run() Promise'i çözülmez ve flowRunFinished() hiç koşmaz — __ngAppsFlowActivity.running sıfıra inmez, page_screenshot'ın hazır bekleyişi her eylemde bütçesini sonuna kadar yakar",
2392
+ sourceRef: "Adım tipi sözlüğü backend'indir (StepType.cs) ama koşan tipler barındırıcıdan gelir: flow-engine.ts start·setter·code·condition·microservice·validation·flow-trigger register eder, web Runtime.svelte alert·confirm·redirect·download·storage·setcookie ekler, mobil ScreenRuntime.tsx alert·redirect·navigate·storage·setcookie ekler. navigate web'de, confirm/download mobilde YOKTUR; end ve query hiçbir barındırıcıda yoktur (Studio kataloğu da bunu visibility ile söyler: navigate 'mobile', confirm/download 'web'; End eklenebilir adımlar arasında değil — EventActionsAdd.svelte). Register edilmemiş tipe gelen akış SESSİZCE durur: flow-engine.ts process() callback bulamazsa hiçbir şey yapmaz (next yok, completed/stopped yok, hata yok, log yok), run() Promise'i çözülmez ve flowRunFinished() hiç koşmaz — __ngAppsFlowActivity.running sıfıra inmez, page_screenshot'ın hazır bekleyişi her eylemde bütçesini sonuna kadar yakar",
2486
2393
  check: definition => {
2487
2394
  const steps = flowAllSteps(definition);
2488
2395
  // Studio her akış tuvaline dekoratif bir End düğümü koyar ve onu sildirmez; zararlı olan
@@ -154,24 +154,6 @@ const resolveShadow = (shadow) => {
154
154
  return undefined;
155
155
  return SHADOW_VALUES[shadow] ?? String(shadow);
156
156
  };
157
- /**
158
- * Döndür / ölçekle / kaydır alanlarının kabul aralığı — frontend `style-groups/transform-fields.ts`
159
- * `TRANSFORM_RANGES`'in kopyası (altın vakalar kilitler). Aralık dışı ve birimli değer yazılmaz.
160
- */
161
- export const TRANSFORM_RANGES = {
162
- rotate: [-360, 360],
163
- scale: [10, 500],
164
- translateX: [-1000, 1000],
165
- translateY: [-1000, 1000]
166
- };
167
- /** Sayı ya da sayısal metin, aralığın içinde; aksi `undefined` — frontend `transformValue`. */
168
- export const transformValue = (value, field) => {
169
- if (typeof value !== 'number' && (typeof value !== 'string' || value.trim() === ''))
170
- return undefined;
171
- const parsed = Number(value);
172
- const [min, max] = TRANSFORM_RANGES[field];
173
- return Number.isFinite(parsed) && parsed >= min && parsed <= max ? parsed : undefined;
174
- };
175
157
  /**
176
158
  * Grupların alan listeleri — frontend `style-groups/style-group-schemas.ts`
177
159
  * `STYLE_GROUP_FIELDS`'in kopyası. Parite testi `components.json`'daki gerçek
@@ -188,11 +170,7 @@ export const STYLE_GROUP_FIELDS = {
188
170
  'borderLeft',
189
171
  'shadow',
190
172
  'contentOverflow',
191
- 'opacity',
192
- 'rotate',
193
- 'scale',
194
- 'translateX',
195
- 'translateY'
173
+ 'opacity'
196
174
  ],
197
175
  typographyStyle: [
198
176
  'textColor',
@@ -242,21 +220,6 @@ export function composeTypedStyle(input, ext) {
242
220
  if (opacity !== undefined && opacity >= 0 && opacity < 100) {
243
221
  groups.opacity = String(opacity / 100);
244
222
  }
245
- // Döndür / ölçekle / kaydır (ADR 0005): kaydır → döndür → ölçekle, köken merkez;
246
- // ölçek yüzdedir, nötr değer ve aralık dışı yazılmaz — frontend `composeSurfaceTransform`.
247
- const transform = [];
248
- const x = transformValue(surface.translateX, 'translateX') ?? 0;
249
- const y = transformValue(surface.translateY, 'translateY') ?? 0;
250
- if (x !== 0 || y !== 0)
251
- transform.push(`translate(${x}px, ${y}px)`);
252
- const rotate = transformValue(surface.rotate, 'rotate');
253
- if (rotate !== undefined && rotate !== 0)
254
- transform.push(`rotate(${rotate}deg)`);
255
- const scale = transformValue(surface.scale, 'scale');
256
- if (scale !== undefined && scale !== 100)
257
- transform.push(`scale(${scale / 100})`);
258
- if (transform.length)
259
- groups.transform = transform.join(' ');
260
223
  // `ROOT_TARGET` (`&`) kökün kendisidir: kendi derleyicisi olmayan kaplarda
261
224
  // yüzey düğüm kutusuna yazılır ve kaydırılan da odur.
262
225
  if (isSet(surface.contentOverflow) && ext?.overflowTarget) {
@@ -288,10 +251,8 @@ export function composeTypedStyle(input, ext) {
288
251
  assign(rules, 'borderColor', hover.borderColor);
289
252
  assign(rules, 'boxShadow', resolveShadow(hover.shadow));
290
253
  const lift = asDimension(hover.lift);
291
- // Kaldırma düğümün kendi transform'unu ezmez, önüne eklenir.
292
- if (lift !== undefined) {
293
- rules.transform = `translateY(calc(-1 * ${lift}))${typeof groups.transform === 'string' ? ` ${groups.transform}` : ''}`;
294
- }
254
+ if (lift !== undefined)
255
+ rules.transform = `translateY(calc(-1 * ${lift}))`;
295
256
  if (Object.keys(rules).length) {
296
257
  const duration = asNumber(hover.transitionMs) ?? 160;
297
258
  groups.transition = `background-color ${duration}ms ease, border-color ${duration}ms ease, box-shadow ${duration}ms ease, transform ${duration}ms ease`;
@@ -539,13 +500,6 @@ export const NODE_SURFACE_TYPES = new Set([
539
500
  'qm-sidebar',
540
501
  'auth-layout'
541
502
  ]);
542
- /**
543
- * `style`'ı kendi içeriğinin CSS'i olarak alan tipler: `html`in `style`'ı uzun metindir ve yazarın
544
- * işaretlemesine kapsamlı girer — web'de emotion sınıfı (`html.functions.ts` `resolveHtmlStyleClass`),
545
- * mobilde korumalı belgenin stil bloğu (plans/mobil-plantcare-acigi f-20). "Düz CSS string style"
546
- * (PAGE-014) ve "ham CSS çizilmez" (MOB-002) uyarıları bu tiplerde yanlıştır.
547
- */
548
- export const DOCUMENT_STYLE_TYPES = new Set(['html']);
549
503
  const NODE_SURFACE_EXTENSION = { overflowTarget: ROOT_TARGET };
550
504
  /** Düğüm kutusuna inen yüzey; kap tipi değilse ya da grup boşsa yok. */
551
505
  export function composeNodeSurfaceStyle(type, surfaceStyle) {
@@ -585,7 +539,7 @@ const unwrapProp = (value) => {
585
539
  result[key] = unwrapProp(item);
586
540
  return result;
587
541
  };
588
- export const rawProp = (props, name) => {
542
+ const rawProp = (props, name) => {
589
543
  const prop = props?.[name];
590
544
  // İfadeye bağlı prop'un değeri çalışma anında oluşur, burada çözülemez.
591
545
  return prop && typeof prop === 'object' && 'data' in prop ? unwrapProp(prop.data) : undefined;
@@ -332,8 +332,8 @@ export function buildSpacingScaleVars(scale) {
332
332
  .join('\n\t');
333
333
  }
334
334
  /**
335
- * Bir seviyenin dar ekran karşılığının masaüstüne oranı — bugünkü breakpoint değerlerinden türer.
336
- * Kullanıcı tek çarpan ayarlar, dar ekran ona orantılı hareket eder.
335
+ * Bir seviyenin mobil karşılığının masaüstüne oranı — bugünkü breakpoint değerlerinden türer.
336
+ * Kullanıcı tek çarpan ayarlar, mobil ona orantılı hareket eder.
337
337
  */
338
338
  const TYPE_SCALE_MOBILE_RATIO = {
339
339
  h1: 1.7 / 2.25,
@@ -363,7 +363,7 @@ export function mergeTypeScale(overrides) {
363
363
  }
364
364
  return result;
365
365
  }
366
- /** Ölçekten `--ng-font-size-*` değişkenlerini üretir (masaüstü + dar ekran). */
366
+ /** Ölçekten `--ng-font-size-*` değişkenlerini üretir (masaüstü + mobil). */
367
367
  export function buildTypeScaleVars(scale) {
368
368
  const lines = [];
369
369
  for (const [level, factor] of Object.entries(scale)) {
@@ -351,7 +351,7 @@ export function logGatewayEvent(message) {
351
351
  */
352
352
  export function logCapabilityGap(gap) {
353
353
  const lines = [
354
- `┌─ ${clockOf(new Date())} · KABİLİYET BOŞLUĞU · ${gap.severity}${gap.module ? ` · ${gap.module}` : ''}${gap.project ? ` · proje ${gap.project}` : ''}`,
354
+ `┌─ ${clockOf(new Date())} · KABİLİYET BOŞLUĞU · ${gap.severity}${gap.module ? ` · ${gap.module}` : ''}`,
355
355
  `│ hedef : ${condense(gap.goal, maxBodyChars)}`,
356
356
  `│ engel : ${condense(gap.blocker, maxBodyChars)}`
357
357
  ];
@@ -5,9 +5,8 @@ const MAX_NOTES = 8;
5
5
  const MAX_NOTE_CHARS = 240;
6
6
  const MAX_DROPS = 5;
7
7
  export const diagnosticsParam = z.enum(['compact', 'full']).optional().describe("Yanıttaki gatewayNormalized / silentlyDropped listelerinin boyu. compact (varsayılan): aynı not tekilleşir, uzun not kısalır (en fazla 8); aynı yolun düşmeleri tek satırda sayıyla toplanır (en fazla 5 grup); droppedCount her zaman tam sayıdır. full: listelerin tamamı.");
8
- /** `adjustable`: tool `diagnostics` parametresini alıyor mu — kısaltma notu yalnız alan tool'a onu önerir (g-08). */
9
- export function runWithDiagnostics(mode, run, adjustable = true) {
10
- return activeMode.run({ mode, adjustable }, run);
8
+ export function runWithDiagnostics(mode, run) {
9
+ return activeMode.run(mode, run);
11
10
  }
12
11
  /**
13
12
  * Tanılama listeleri her yazma çağrısında yanıta girer ve aynı gerekçe cümlesi çağrı başına tekrar
@@ -19,7 +18,7 @@ export function runWithDiagnostics(mode, run, adjustable = true) {
19
18
  * listeyi görür; kısaltma yalnız `diagnostics` parametresini taşıyan yazma tool'larında devreye girer.
20
19
  */
21
20
  export function compactDiagnostics(payload) {
22
- if (activeMode.getStore()?.mode !== 'compact')
21
+ if (activeMode.getStore() !== 'compact')
23
22
  return payload;
24
23
  if (!payload || typeof payload !== 'object' || Array.isArray(payload))
25
24
  return payload;
@@ -59,12 +58,7 @@ export function compactDiagnostics(payload) {
59
58
  }
60
59
  if (hidden.length === 0)
61
60
  return result;
62
- return {
63
- ...result,
64
- diagnosticsNote: activeMode.getStore()?.adjustable === false
65
- ? 'Kısaltıldı; tam liste gateway günlüğünde (bu tool diagnostics parametresi almaz).'
66
- : "Kısaltıldı; yazmayı tekrarlamayın. Tam liste: sonraki çağrıda diagnostics:'full'."
67
- };
61
+ return { ...result, diagnosticsNote: "Kısaltıldı; yazmayı tekrarlamayın. Tam liste: sonraki çağrıda diagnostics:'full'." };
68
62
  }
69
63
  /**
70
64
  * Aynı yolun farklı öğelerindeki düşmeler (`selectFields[fieldId=a].path`, `selectFields[fieldId=b].path`, …)
@@ -7,7 +7,7 @@
7
7
  * (card) · GİZLİ" 200 karakterdir.
8
8
  *
9
9
  * Katman saftır: tarayıcıdan gelen anlık görüntüyü doğrular ve biçimler. Toplama işi
10
- * `capture/summary.ts` `domSummaryScript`'te, sunum `pages.ts`'te.
10
+ * `screenshot.ts` `domSummaryScript`'te, sunum `pages.ts`'te.
11
11
  */
12
12
  function text(value) {
13
13
  return typeof value === 'string' && value.length > 0 ? value : undefined;
@@ -6,20 +6,6 @@ import { randomUUID } from 'node:crypto';
6
6
  import { request } from 'undici';
7
7
  export const requestAuthStorage = new AsyncLocalStorage();
8
8
  const hiddenResponseHeaders = new Set(['set-cookie', 'authorization', 'proxy-authorization']);
9
- /**
10
- * g-08: yürütme yanıtının varsayılan başlıkları — işin okuduğu olanlar. `total-count` sayfalı tablo
11
- * akışlarının sözleşmesidir (İK koşusu M-8), `location` yönlendirmenin, `x-request-id`/`traceparent`
12
- * platform günlüğünde aynı isteği bulmanın anahtarıdır. Cloudflare ve sunucu başlıkları (`cf-ray`,
13
- * `server`, `alt-svc`, `date` …) ajan bağlamında yer kaplıyordu ve hiçbir karar onlara bakmıyordu.
14
- */
15
- const essentialResponseHeaders = new Set(['content-type', 'content-length', 'content-disposition', 'location', 'total-count', 'x-request-id', 'traceparent']);
16
- export function headersForMode(headers, mode) {
17
- if (mode === 'none')
18
- return undefined;
19
- if (mode === 'all')
20
- return headers;
21
- return Object.fromEntries(Object.entries(headers).filter(([name]) => essentialResponseHeaders.has(name)));
22
- }
23
9
  /**
24
10
  * Sayfalı tablo akışları `Total-Count` header'ına bağlı ama execute ailesi yalnız gövdeyi
25
11
  * döndürüyordu; sözleşme hiçbir tool'dan doğrulanamıyordu (İK koşusu M-8). Gizli header'lar
@@ -167,15 +153,13 @@ export class Platform {
167
153
  body = JSON.stringify(options.body);
168
154
  }
169
155
  const startedAt = Date.now();
170
- logStep('istek →', `${method} ${url.href} · ${api} api${options.environment ? ` · env=${options.environment}` : ''}${options.anonymous ? ' · ANONİM (Authorization header YOK)' : ''}${isRetry ? ' · 401 sonrası tekrar' : ''}`, options.hideRequestBody === true
171
- ? ['gövde: (gizli — kimlik bilgisi taşıyor, günlüğe yazılmaz)']
172
- : logsDetail() && (options.multipart || options.form || options.body !== undefined)
173
- ? [`gövde: ${renderJson(options.multipart
174
- ? describeMultipart(options.multipart)
175
- : options.form
176
- ? Object.fromEntries(options.form)
177
- : options.body)}`]
178
- : []);
156
+ logStep('istek →', `${method} ${url.href} · ${api} api${options.environment ? ` · env=${options.environment}` : ''}${options.anonymous ? ' · ANONİM (Authorization header YOK)' : ''}${isRetry ? ' · 401 sonrası tekrar' : ''}`, logsDetail() && (options.multipart || options.form || options.body !== undefined)
157
+ ? [`gövde: ${renderJson(options.multipart
158
+ ? describeMultipart(options.multipart)
159
+ : options.form
160
+ ? Object.fromEntries(options.form)
161
+ : options.body)}`]
162
+ : []);
179
163
  let statusCode;
180
164
  let payload;
181
165
  let responseBytes = 0;
@@ -1,6 +1,4 @@
1
1
  import { compactDiagnostics } from './diagnostics.js';
2
- import { argumentNotes } from './argumentAliases.js';
3
- import { tokenTtlMinutes } from './tokenVault.js';
4
2
  import { logError, logStep } from '../observability/trace.js';
5
3
  import { PlatformApiError, describeErrorBody } from './errors.js';
6
4
  import { PolicyBlockError } from '../knowledge/policy.js';
@@ -164,10 +162,8 @@ export function toolResult(payload, config, expectFailure) {
164
162
  ...(runtimeErrors.length > 0 ? { runtimeErrors } : {}),
165
163
  ...(runtimeErrors.length > 0 && expectFailure === true ? { expectedFailure: true } : {}),
166
164
  ...(masked.length > 0 ? { gatewayMasked: masked } : {}),
167
- ...(Object.keys(tokenRefs).length > 0 ? { tokenRefs, tokenRefNote: `Maskelenen JWT'ler gateway içinde tutuldu; bu referansları page_screenshot / page_runtime_get 'asUser' alanına verebilirsiniz (${tokenTtlMinutes()} dk geçerli). Jetonun kendisi yanıta ve günlüğe hiç girmez.` } : {}),
168
- ...(truncated ? { truncated: true, truncationNote: 'Liste, yanıt boyutu sınırı nedeniyle kırpıldı; sayfalama ya da daha dar filtre kullanın.' } : {}),
169
- ...(argumentNotes().aliasesApplied.length > 0 ? { aliasesApplied: argumentNotes().aliasesApplied } : {}),
170
- ...(argumentNotes().bodyFile ? { bodyFile: argumentNotes().bodyFile } : {})
165
+ ...(Object.keys(tokenRefs).length > 0 ? { tokenRefs, tokenRefNote: "Maskelenen JWT'ler gateway içinde tutuldu; bu referansları page_screenshot / page_runtime_get 'asUser' alanına verebilirsiniz (15 dk geçerli). Jetonun kendisi yanıta ve günlüğe hiç girmez." } : {}),
166
+ ...(truncated ? { truncated: true, truncationNote: 'Liste, yanıt boyutu sınırı nedeniyle kırpıldı; sayfalama ya da daha dar filtre kullanın.' } : {})
171
167
  };
172
168
  return {
173
169
  content: [{ type: 'text', text: JSON.stringify(enriched) }],