@appaflytech/zeyrek-ai-mcp 0.0.33 → 0.0.35

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 (170) 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/boxSections.js +184 -0
  5. package/dist/knowledge/componentCatalog.js +634 -255
  6. package/dist/knowledge/componentEvents.js +38 -32
  7. package/dist/knowledge/layoutSummary.js +2 -140
  8. package/dist/knowledge/normalize.js +144 -117
  9. package/dist/knowledge/rules.js +42 -291
  10. package/dist/knowledge/styleResolve.js +53 -58
  11. package/dist/knowledge/themeResolve.js +4 -4
  12. package/dist/knowledge/themeSchema.js +2 -1
  13. package/dist/observability/trace.js +1 -1
  14. package/dist/platform/diagnostics.js +4 -10
  15. package/dist/platform/domSummary.js +1 -1
  16. package/dist/platform/http.js +7 -23
  17. package/dist/platform/responses.js +2 -6
  18. package/dist/platform/screenshot.js +1162 -0
  19. package/dist/platform/secrets.js +0 -9
  20. package/dist/platform/strictArguments.js +12 -68
  21. package/dist/platform/tokenVault.js +4 -187
  22. package/dist/resources/examples/layout-app-shell.json +707 -229
  23. package/dist/resources/examples/page-flex-sections.json +1 -1
  24. package/dist/resources/guides/component.md +6 -14
  25. package/dist/resources/guides/entity.md +5 -3
  26. package/dist/resources/guides/expressions.md +5 -14
  27. package/dist/resources/guides/functions.md +1 -1
  28. package/dist/resources/guides/layout.md +58 -55
  29. package/dist/resources/guides/microservice.md +2 -9
  30. package/dist/resources/guides/middleware.md +2 -34
  31. package/dist/resources/guides/page.md +179 -256
  32. package/dist/resources/guides/theme.md +3 -8
  33. package/dist/resources/guides/translation.md +1 -1
  34. package/dist/resources/guides/workflow.md +1 -7
  35. package/dist/resources/schema-fingerprint.json +4 -4
  36. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +1 -3
  37. package/dist/resources/schemas/MicroserviceDto.json +2 -2
  38. package/dist/server.js +1 -7
  39. package/dist/tools/applications.js +3 -60
  40. package/dist/tools/components.js +16 -103
  41. package/dist/tools/datasources.js +1 -1
  42. package/dist/tools/designSchemaPatch.js +19 -23
  43. package/dist/tools/externalComponents.js +4 -25
  44. package/dist/tools/flows.js +13 -80
  45. package/dist/tools/layouts.js +20 -48
  46. package/dist/tools/microservices.js +10 -32
  47. package/dist/tools/pages.js +115 -396
  48. package/dist/tools/platformInfo.js +2 -7
  49. package/dist/tools/rows.js +1 -7
  50. package/dist/tools/schemaOps.js +4 -35
  51. package/dist/tools/screenWrite.js +37 -25
  52. package/dist/tools/screens.js +4 -91
  53. package/dist/tools/variables.js +5 -11
  54. package/package.json +2 -2
  55. package/dist/knowledge/access.js +0 -802
  56. package/dist/knowledge/case.js +0 -41
  57. package/dist/knowledge/connectDataBind.js +0 -819
  58. package/dist/knowledge/connectDataDefinition.js +0 -341
  59. package/dist/knowledge/connectDataExecute.js +0 -93
  60. package/dist/knowledge/connectDataRules.js +0 -128
  61. package/dist/knowledge/decision.js +0 -121
  62. package/dist/knowledge/expressionPrelude.js +0 -59
  63. package/dist/knowledge/microserviceParameters.js +0 -58
  64. package/dist/knowledge/mining.js +0 -94
  65. package/dist/knowledge/mobileComponentCatalog.js +0 -864
  66. package/dist/knowledge/mobileComponentEvents.js +0 -239
  67. package/dist/knowledge/mobileStore.js +0 -227
  68. package/dist/knowledge/platform/lint.js +0 -385
  69. package/dist/knowledge/platform/mobile.js +0 -142
  70. package/dist/knowledge/platform/mobileLayoutLint.js +0 -324
  71. package/dist/knowledge/platform/mobileRules.js +0 -231
  72. package/dist/knowledge/platform/mobileSpacing.js +0 -82
  73. package/dist/knowledge/platform/mobileTabs.js +0 -108
  74. package/dist/knowledge/platform/nativeBoxModel.js +0 -44
  75. package/dist/knowledge/platform/profile.js +0 -25
  76. package/dist/knowledge/platform/resolve.js +0 -122
  77. package/dist/knowledge/platform/web.js +0 -39
  78. package/dist/knowledge/process.js +0 -510
  79. package/dist/knowledge/rowFilter.js +0 -43
  80. package/dist/knowledge/styleResolveNative.js +0 -527
  81. package/dist/platform/argumentAliases.js +0 -128
  82. package/dist/platform/bodyFile.js +0 -103
  83. package/dist/platform/capture/actions.js +0 -333
  84. package/dist/platform/capture/browser.js +0 -1
  85. package/dist/platform/capture/capture.js +0 -659
  86. package/dist/platform/capture/console-log.js +0 -122
  87. package/dist/platform/capture/index.js +0 -11
  88. package/dist/platform/capture/readiness.js +0 -103
  89. package/dist/platform/capture/summary.js +0 -77
  90. package/dist/platform/capture/target.js +0 -5
  91. package/dist/platform/capture/targets/studio-mobile.js +0 -15
  92. package/dist/platform/capture/targets/studio-web.js +0 -5
  93. package/dist/platform/impersonation.js +0 -45
  94. package/dist/platform/jsonArray.js +0 -24
  95. package/dist/platform/schemaReadMemory.js +0 -60
  96. package/dist/resources/examples/bpm-gorev-kontrol.json +0 -294
  97. package/dist/resources/examples/bpm-iso-dokuman.json +0 -228
  98. package/dist/resources/examples/bpm-satinalma.json +0 -376
  99. package/dist/resources/examples/connect-data-convert-verify.json +0 -107
  100. package/dist/resources/examples/connect-data-dropdown-roles.json +0 -66
  101. package/dist/resources/examples/connect-data-edit-m2m.json +0 -73
  102. package/dist/resources/examples/connect-data-query-params.json +0 -50
  103. package/dist/resources/examples/connect-data-table-entity.json +0 -147
  104. package/dist/resources/examples/connect-data-workflow-microservice.json +0 -65
  105. package/dist/resources/examples/mobile-app-shell-drawer.json +0 -244
  106. package/dist/resources/examples/mobile-app-shell-stack.json +0 -157
  107. package/dist/resources/examples/mobile-app-shell-tab.json +0 -208
  108. package/dist/resources/examples/mobile-form-screen.json +0 -365
  109. package/dist/resources/examples/mobile-list-detail-form.json +0 -703
  110. package/dist/resources/guides/access.md +0 -796
  111. package/dist/resources/guides/bpm.md +0 -686
  112. package/dist/resources/guides/case.md +0 -153
  113. package/dist/resources/guides/decision.md +0 -185
  114. package/dist/resources/guides/mobile-layout.md +0 -193
  115. package/dist/resources/guides/mobile.md +0 -578
  116. package/dist/resources/read.js +0 -41
  117. package/dist/resources/schemas/AccessExplanationDto.json +0 -144
  118. package/dist/resources/schemas/AccessMatrixDto.json +0 -170
  119. package/dist/resources/schemas/AccessPermissionDto.json +0 -57
  120. package/dist/resources/schemas/AccessPolicyDto.json +0 -223
  121. package/dist/resources/schemas/AccessResourceDto.json +0 -86
  122. package/dist/resources/schemas/AppSessionDto.json +0 -53
  123. package/dist/resources/schemas/ConnectDataDescribeDto.json +0 -344
  124. package/dist/resources/schemas/ConnectDataRequestModel.json +0 -202
  125. package/dist/resources/schemas/ConnectDataResultDto.json +0 -421
  126. package/dist/resources/schemas/ConnectorCredentialDto.json +0 -70
  127. package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +0 -37
  128. package/dist/resources/schemas/CreateAccessPolicyCommand.json +0 -209
  129. package/dist/resources/schemas/CreateDecisionCommand.json +0 -221
  130. package/dist/resources/schemas/CreateProcessDefinitionCommand.json +0 -1337
  131. package/dist/resources/schemas/DecisionDto.json +0 -302
  132. package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +0 -28
  133. package/dist/resources/schemas/ExplainAccessQuery.json +0 -33
  134. package/dist/resources/schemas/GenerateProcessDocumentCommand.json +0 -116
  135. package/dist/resources/schemas/OrganizationProjectDto.json +0 -335
  136. package/dist/resources/schemas/OrganizationSchemaDto.json +0 -196
  137. package/dist/resources/schemas/OrganizationSchemaVersionDto.json +0 -207
  138. package/dist/resources/schemas/PatchProcessDefinitionCommand.json +0 -76
  139. package/dist/resources/schemas/ProcessDefinitionDto.json +0 -1480
  140. package/dist/resources/schemas/ProcessSimulationDto.json +0 -96
  141. package/dist/resources/schemas/SaveConnectorCredentialCommand.json +0 -90
  142. package/dist/resources/schemas/SaveProcessEventSourceCommand.json +0 -61
  143. package/dist/resources/schemas/SaveProcessMailSourceCommand.json +0 -89
  144. package/dist/resources/schemas/SignProcessTaskCommand.json +0 -73
  145. package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +0 -92
  146. package/dist/resources/schemas/StartMobileBuildCommand.json +0 -54
  147. package/dist/resources/schemas/UpdateAccessPolicyCommand.json +0 -209
  148. package/dist/resources/schemas/UpdateDecisionCommand.json +0 -216
  149. package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +0 -1357
  150. package/dist/resources/schemas/UpsertMobileStoreSettingsCommand.json +0 -259
  151. package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +0 -1339
  152. package/dist/tools/accessOperations.js +0 -135
  153. package/dist/tools/accessPolicies.js +0 -170
  154. package/dist/tools/accessRuntime.js +0 -203
  155. package/dist/tools/bpm.js +0 -343
  156. package/dist/tools/bpmGovernance.js +0 -266
  157. package/dist/tools/bpmOperations.js +0 -230
  158. package/dist/tools/bpmReporting.js +0 -154
  159. package/dist/tools/bpmRouting.js +0 -150
  160. package/dist/tools/bpmRuntime.js +0 -396
  161. package/dist/tools/case.js +0 -178
  162. package/dist/tools/caseRuntime.js +0 -89
  163. package/dist/tools/connectData.js +0 -449
  164. package/dist/tools/connectors.js +0 -193
  165. package/dist/tools/decisions.js +0 -206
  166. package/dist/tools/mobile.js +0 -221
  167. package/dist/tools/mobileStore.js +0 -268
  168. package/dist/tools/modules.js +0 -48
  169. package/dist/tools/organizationStructure.js +0 -137
  170. package/dist/tools/profileWrite.js +0 -92
@@ -38,12 +38,3 @@ export function maskSecrets(payload) {
38
38
  const tokenRefs = {};
39
39
  return { payload: walk(payload, '', masked, tokenRefs, 0), masked, tokenRefs };
40
40
  }
41
- /**
42
- * Serbest METİNDEKİ kimlik parçaları (konsol satırı, hata yığını): JWT biçimli dize ve `Bearer …`.
43
- * `maskSecrets` anahtar adına bakar; tarayıcı konsolu anahtarsız düz metin taşır (g-06).
44
- */
45
- export function maskSecretText(text) {
46
- return text
47
- .replace(/Bearer\s+[A-Za-z0-9._~+/=-]+/gi, `Bearer ${maskedValue}`)
48
- .replace(/\b[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, maskedValue);
49
- }
@@ -1,11 +1,5 @@
1
1
  import { z } from 'zod';
2
2
  import { diagnosticsParam, runWithDiagnostics } from './diagnostics.js';
3
- import { applyArgumentAliases, closestArgument, runWithArgumentNotes } from './argumentAliases.js';
4
- import { BODY_FILE_ARGUMENTS, bodyFileParam, loadBodyFile } from './bodyFile.js';
5
- import { PlatformApiError } from './errors.js';
6
- import { logError } from '../observability/trace.js';
7
- /** Doğrulanmış argümanlara takılan çeviri notları (`ArgumentNotes`); JSON'a ve platform isteğine girmez. */
8
- const ARGUMENT_NOTES = Symbol('argumentNotes');
9
3
  /**
10
4
  * `writes`/`updates` açıklamalı ama KAYIT yazmayan tool'lar: çalıştırma, önizleme, dışa aktarma, indirme,
11
5
  * bağlantı testi. Yanıtlarında yazma tanılaması (silentlyDropped) yoktur; parametre yalnız tool listesini
@@ -31,75 +25,25 @@ function isRawShape(value) {
31
25
  * olmayan bir sorgu kusuruna yönlendirdi. Tek tek tool'lara alan eklemek sınıfı kapatmaz; sessizlik
32
26
  * burada, SDK'ya şema verilmeden önce kaldırılır.
33
27
  */
34
- export function rejectUnknownArguments(server, platform) {
28
+ export function rejectUnknownArguments(server) {
35
29
  const registerTool = server.registerTool.bind(server);
36
- // Zorunlu gövde argümanı `bodyFile` açıkken şemada isteğe bağlı yayınlanır (yoksa şemaya uyan istemci
37
- // gövdeyi satır içinde yollamak zorunda kalır ve `bodyFile` "birlikte verilemez" ile reddedilirdi);
38
- // zorunluluk dosya okunduktan sonra burada denetlenir.
39
- const requiredBodies = new Map();
40
- // g-07/g-08: `bodyFile` ve takma ad tablosu SDK'nın strict doğrulamasından ÖNCE koşmalı — sonra
41
- // koşsa yanlış ad zaten reddedilmiş, dosyadan gelen gövde doğrulanmamış olur. SDK doğrulamayı
42
- // `validateToolInput` içinde yapar; çeviri orada uygulanır ve notlar doğrulanmış argümanlara
43
- // sembol anahtarla takılır.
44
- if (platform) {
45
- const validator = server;
46
- const validate = validator.validateToolInput.bind(server);
47
- validator.validateToolInput = async (tool, args, name) => {
48
- try {
49
- const loaded = await loadBodyFile(name, args, platform.config);
50
- const requiredBody = requiredBodies.get(name);
51
- if (requiredBody && loaded.args?.[requiredBody] === undefined) {
52
- throw new PlatformApiError(`${name}: '${requiredBody}' zorunlu — satır içinde ya da bodyFile ile (.json dosyası) verin. İstek gönderilmedi.`, 400);
53
- }
54
- const { args: aliased, applied } = await applyArgumentAliases(name, loaded.args, { platform, shape: tool.inputSchema?.shape ?? {} });
55
- const parsed = await validate(tool, aliased, name);
56
- const notes = { aliasesApplied: applied, ...(loaded.note ? { bodyFile: loaded.note } : {}) };
57
- return (applied.length > 0 || loaded.note) && parsed && typeof parsed === 'object' ? Object.assign(parsed, { [ARGUMENT_NOTES]: notes }) : parsed;
58
- }
59
- catch (error) {
60
- // Doğrulamadan önceki çeviri (dosya, takma ad) `handle`'ın dışında koşar: hata burada günlüğe yazılır.
61
- if (error instanceof PlatformApiError)
62
- logError(error);
63
- throw error;
64
- }
65
- };
66
- }
67
30
  server.registerTool = ((name, config, callback) => {
68
31
  if (!isRawShape(config.inputSchema))
69
32
  return registerTool(name, config, callback);
70
- // Tanılama notları her tool'da compact döner (g-08: okuma ve çalıştırma yanıtında da 8 not +
71
- // "N not daha"). `diagnostics` parametresi yalnız kayıt yazan tool'lara, microservice_execute'a ve
72
- // *_preview'a açılır — ötekilerde tool listesini büyütmesin diye varsayılan kullanılır. Parametre
73
- // handler'a ULAŞMAZ (gövdeyi `...rest` ile platforma geçiren tool'larda sızardı), yalnız
74
- // toolResult'ın okuduğu bağlama konur.
75
- const writesRecords = config.annotations?.readOnlyHint === false && config.annotations.destructiveHint !== true && !NON_WRITING_TOOLS.has(name);
76
- const exposesDiagnostics = writesRecords || name === 'microservice_execute' || name.endsWith('_preview');
77
- const bodyArgument = BODY_FILE_ARGUMENTS[name];
78
- const bodySchema = bodyArgument ? config.inputSchema[bodyArgument] : undefined;
79
- if (bodyArgument && bodySchema && !bodySchema.isOptional())
80
- requiredBodies.set(name, bodyArgument);
81
- const shape = {
82
- ...config.inputSchema,
83
- ...(bodyArgument && bodySchema ? { [bodyArgument]: bodySchema.optional(), bodyFile: bodyFileParam(bodyArgument) } : {}),
84
- ...(exposesDiagnostics ? { diagnostics: diagnosticsParam } : {})
85
- };
86
- const invoke = (args, extra) => {
87
- const { diagnostics, ...rest } = exposesDiagnostics ? args ?? {} : { ...args, diagnostics: undefined };
88
- return runWithDiagnostics(diagnostics === 'full' ? 'full' : 'compact', () => callback(exposesDiagnostics ? rest : args, extra), exposesDiagnostics);
89
- };
90
- const run = (args, extra) => {
91
- const { [ARGUMENT_NOTES]: notes, ...rest } = args ?? {};
92
- return runWithArgumentNotes(notes ?? { aliasesApplied: [] }, () => invoke(rest, extra));
93
- };
33
+ // Yazma tool'ları tanılama kipini alır; parametre handler'a ULAŞMAZ (gövdeyi `...rest` ile
34
+ // platforma geçiren tool'larda sızardı), yalnız toolResult'ın okuduğu bağlama konur.
35
+ const writesDiagnostics = config.annotations?.readOnlyHint === false && config.annotations.destructiveHint !== true && !NON_WRITING_TOOLS.has(name);
36
+ const shape = writesDiagnostics ? { ...config.inputSchema, diagnostics: diagnosticsParam } : config.inputSchema;
37
+ const run = writesDiagnostics
38
+ ? ((args, extra) => {
39
+ const { diagnostics, ...rest } = args ?? {};
40
+ return runWithDiagnostics(diagnostics === 'full' ? 'full' : 'compact', () => callback(rest, extra));
41
+ })
42
+ : callback;
94
43
  const accepted = Object.keys(shape).join(', ');
95
- const suggestions = (keys) => keys
96
- .map(key => ({ key, near: closestArgument(key, Object.keys(shape)) }))
97
- .filter(entry => entry.near !== undefined)
98
- .map(entry => ` '${entry.key}' → '${entry.near}' mi demek istediniz?`)
99
- .join('');
100
44
  const inputSchema = z.object(shape, {
101
45
  errorMap: (issue, context) => issue.code === 'unrecognized_keys'
102
- ? { message: `${name} şu üst düzey argümanları tanımıyor: ${issue.keys.map(key => `'${key}'`).join(', ')}. Tanınmayan alan sessizce yok sayılmaz — çağrı hiç gönderilmedi. Bu tool'un okuduğu alanlar: ${accepted}.${suggestions(issue.keys)}` }
46
+ ? { message: `${name} şu üst düzey argümanları tanımıyor: ${issue.keys.map(key => `'${key}'`).join(', ')}. Tanınmayan alan sessizce yok sayılmaz — çağrı hiç gönderilmedi. Bu tool'un okuduğu alanlar: ${accepted}.` }
103
47
  : { message: context.defaultError }
104
48
  }).strict();
105
49
  return registerTool(name, { ...config, inputSchema }, run);
@@ -1,8 +1,5 @@
1
1
  import { PlatformApiError } from './errors.js';
2
2
  import { randomBytes } from 'node:crypto';
3
- import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
4
- import { dirname, join } from 'node:path';
5
- import { logStep } from '../observability/trace.js';
6
3
  /**
7
4
  * `page_screenshot`/`page_runtime_get` açıklaması "jetonu uygulamanın kendi giriş ucundan alın
8
5
  * (`microservice_execute`)" diyor, ama gizli alan maskesi `access_token`'ı `***` yapıyor ve o yol
@@ -12,19 +9,10 @@ import { logStep } from '../observability/trace.js';
12
9
  * Kasa bu çelişkiyi jetonu bağlama HİÇ sokmadan çözer: maskelenen JWT gateway sürecinde tutulur,
13
10
  * yanıta yalnız kısa ömürlü bir referans (`tok_…`) döner ve kimlik isteyen tool'lar referansı
14
11
  * çözer. Jeton ne yanıtta ne günlükte açık görünür.
15
- *
16
- * g-09 (`plans/mobil-plantcare-acigi`, K9): kasa süreç sınırını aşar. `.env` `MCP_STATE_DIR`
17
- * verilmişse kayıtlar `token-vault.json`'a (0600) yazılır ve süreç açılışta onu okur; süre
18
- * `MCP_TOKEN_TTL_MINUTES`'tan gelir (verilmezse eski 15 dk). Dosya YALNIZ lokal hedefte yazılır —
19
- * uzak bir org'un jetonu diske inmez. Test kullanıcısının (`asUser: 'test:<ad>'`) jetonu da burada,
20
- * etiketiyle tutulur; aynı kullanıcı TTL boyunca yeniden giriş yapmaz.
21
12
  */
22
- const legacyTtlMinutes = 15;
13
+ const ttlMs = 15 * 60 * 1000;
23
14
  const maxEntries = 64;
24
15
  const vault = new Map();
25
- let ttlMs = legacyTtlMinutes * 60 * 1000;
26
- let vaultFile;
27
- let warnedRemote = false;
28
16
  export const tokenRefPattern = /^tok_[0-9a-f]{16}$/;
29
17
  /** Üç base64url parçalı JWT — parola ya da API anahtarı bu şekle uymaz. */
30
18
  export function looksLikeJwt(value) {
@@ -42,132 +30,29 @@ function sweep(now) {
42
30
  vault.delete(oldest.value);
43
31
  }
44
32
  }
45
- function isLocalTarget(baseUrl) {
46
- try {
47
- const host = new URL(baseUrl).hostname;
48
- return host === 'localhost' || host === '127.0.0.1' || host === '[::1]' || host.endsWith('.localhost');
49
- }
50
- catch {
51
- return false;
52
- }
53
- }
54
- /**
55
- * Aynı dosyayı birden çok gateway süreci paylaşır (her Claude Code oturumu kendi stdio sürecini açar).
56
- * Yazma "son yazan kazanır" olursa bir sürecin kaydı ötekinin yazmasıyla silinirdi: yazmadan önce ve
57
- * bellekte olmayan referans istenince dosya okunur, süresi dolmamış yabancı kayıtlar belleğe katılır.
58
- */
59
- function mergeFromFile() {
60
- if (!vaultFile)
61
- return;
62
- try {
63
- const stored = JSON.parse(readFileSync(vaultFile, 'utf8'));
64
- const now = Date.now();
65
- for (const [ref, entry] of Object.entries(stored.entries ?? {})) {
66
- if (!vault.has(ref) && tokenRefPattern.test(ref) && typeof entry.token === 'string' && typeof entry.expires === 'number' && entry.expires > now) {
67
- vault.set(ref, { token: entry.token, expires: entry.expires, ...(typeof entry.label === 'string' ? { label: entry.label } : {}) });
68
- }
69
- }
70
- }
71
- catch {
72
- // dosya yok ya da okunamadı: bellekteki kasa geçerli
73
- }
74
- }
75
- function persist() {
76
- if (!vaultFile)
77
- return;
78
- mergeFromFile();
79
- sweep(Date.now());
80
- try {
81
- const temporary = `${vaultFile}.${process.pid}.tmp`;
82
- mkdirSync(dirname(vaultFile), { recursive: true, mode: 0o700 });
83
- writeFileSync(temporary, JSON.stringify({ entries: Object.fromEntries(vault) }), { mode: 0o600 });
84
- renameSync(temporary, vaultFile);
85
- }
86
- catch (error) {
87
- logStep('jeton kasası ✕', `kasa dosyası yazılamadı (${vaultFile}) — jetonlar bu süreçte bellekte kalır`, [error instanceof Error ? error.message : String(error)]);
88
- }
89
- }
90
- /**
91
- * Süreç açılışında bir kez çağrılır (`index.ts`); testler yeniden başlamayı `clearTokenVault` +
92
- * bu çağrıyla benzetir. Dosyadaki süresi dolmuş kayıtlar yüklenmez ve dosya onlarsız yeniden yazılır.
93
- */
94
- export function configureTokenVault(config) {
95
- ttlMs = (config.tokenTtlMinutes ?? legacyTtlMinutes) * 60 * 1000;
96
- vaultFile = undefined;
97
- if (!config.stateDirectory)
98
- return;
99
- if (!isLocalTarget(config.orgApiBaseUrl)) {
100
- if (!warnedRemote) {
101
- warnedRemote = true;
102
- logStep('jeton kasası', `ORG_API_BASE_URL lokal değil — kasa dosyaya YAZILMAZ, jetonlar yalnız süreç belleğinde tutulur (MCP_STATE_DIR yok sayıldı)`);
103
- }
104
- return;
105
- }
106
- vaultFile = join(config.stateDirectory, 'token-vault.json');
107
- persist();
108
- }
109
- /** Kasanın geçerli ömrü (dakika) — yanıt notları sabit bir süre yazmasın. */
110
- export const tokenTtlMinutes = () => Math.round(ttlMs / 60000);
111
- export function rememberToken(token, label) {
33
+ export function rememberToken(token) {
112
34
  const now = Date.now();
113
35
  sweep(now);
114
36
  for (const [ref, entry] of vault) {
115
37
  if (entry.token === token) {
116
38
  entry.expires = now + ttlMs;
117
- if (label !== undefined)
118
- entry.label = label;
119
- persist();
120
39
  return ref;
121
40
  }
122
41
  }
123
42
  const ref = `tok_${randomBytes(8).toString('hex')}`;
124
- vault.set(ref, { token, expires: now + ttlMs, ...(label !== undefined ? { label } : {}) });
125
- persist();
43
+ vault.set(ref, { token, expires: now + ttlMs });
126
44
  return ref;
127
45
  }
128
46
  export function resolveToken(reference) {
129
- if (!vault.has(reference))
130
- mergeFromFile();
131
47
  const entry = vault.get(reference);
132
48
  if (!entry)
133
49
  return undefined;
134
50
  if (entry.expires <= Date.now()) {
135
51
  vault.delete(reference);
136
- persist();
137
52
  return undefined;
138
53
  }
139
54
  return entry.token;
140
55
  }
141
- /**
142
- * Jetonun kendi süresi (`exp`) kasanın TTL'inden kısa olabilir: uygulamanın jetonu 15 dk yaşarken kasa
143
- * 60 dk tutuyordu ve süresi dolmuş jetonla çekilen kare sessizce çıkış yapmış sayfayı gösterirdi.
144
- * 30 sn pay bırakılır; `exp` okunamayan jeton geçerli sayılır (karar uygulamanındır).
145
- */
146
- const jwtExpired = (token) => {
147
- try {
148
- const payload = JSON.parse(Buffer.from(token.split('.')[1] ?? '', 'base64url').toString('utf8'));
149
- return typeof payload.exp === 'number' && payload.exp * 1000 <= Date.now() + 30_000;
150
- }
151
- catch {
152
- return false;
153
- }
154
- };
155
- function labeledToken(label) {
156
- const find = () => {
157
- const now = Date.now();
158
- for (const entry of vault.values()) {
159
- if (entry.label === label && entry.expires > now && !jwtExpired(entry.token))
160
- return entry.token;
161
- }
162
- return undefined;
163
- };
164
- const found = find();
165
- if (found || !vaultFile)
166
- return found;
167
- mergeFromFile();
168
- return find();
169
- }
170
- /** Bellekteki kasayı boşaltır (süreç yeniden başlamasının benzetimi); dosyaya dokunmaz. */
171
56
  export function clearTokenVault() {
172
57
  vault.clear();
173
58
  }
@@ -181,76 +66,8 @@ export function resolveIdentityToken(value) {
181
66
  return value;
182
67
  const token = resolveToken(value);
183
68
  if (token === undefined) {
184
- throw new PlatformApiError(`'${value}' referansı geçersiz ya da süresi dolmuş (${Math.round(ttlMs / 60000)} dk). Tercih edilen yol asUser: 'test:<ad>' — gateway kök .env'deki test kullanıcısıyla kendisi giriş yapar. Yoksa uygulamanın giriş ucunu microservice_execute ile yeniden çağırıp yanıttaki tokenRefs değerini kullanın.`, 400);
185
- }
186
- return token;
187
- }
188
- /**
189
- * Giriş yanıtındaki erişim jetonu: yanıt birden çok JWT taşıyabilir (erişim + yenileme). Anahtarı
190
- * `access` içeren önce, sonra `refresh` içermeyen, en son ilk bulunan — yenileme jetonuyla istek atmak
191
- * her uçta 401 demekti.
192
- */
193
- function accessJwt(value) {
194
- const found = [];
195
- const collect = (node, key, depth) => {
196
- if (depth > 12)
197
- return;
198
- if (looksLikeJwt(node)) {
199
- found.push({ key, token: node });
200
- return;
201
- }
202
- if (Array.isArray(node))
203
- node.forEach(entry => collect(entry, key, depth + 1));
204
- else if (node && typeof node === 'object')
205
- Object.entries(node).forEach(([name, entry]) => collect(entry, name, depth + 1));
206
- };
207
- collect(value, '', 0);
208
- return (found.find(entry => /access/i.test(entry.key)) ?? found.find(entry => !/refresh/i.test(entry.key)) ?? found[0])?.token;
209
- }
210
- /**
211
- * g-09: `asUser` üç şekil alır — ham JWT, `tok_…` referansı ve `test:<ad>`. Üçüncüsünde gateway kök
212
- * `.env`'deki `MCP_TEST_USER_<AD>` satırının tarif ettiği giriş ucunu (uygulamanın kendi uç'u)
213
- * anonim çağırır, yanıttaki ilk JWT'yi kasaya etiketiyle koyar ve TTL boyunca yeniden kullanır.
214
- * Parola ne yanıta, ne günlüğe (`hideRequestBody`), ne hata metnine girer; satırın değeri hiçbir
215
- * mesajda gösterilmez. AI `.env`'i düzenlemez: tanımsız kullanıcı, insanın ekleyeceği değişkenin
216
- * adıyla reddedilir.
217
- */
218
- export async function resolveIdentity(value, platform, project, environment) {
219
- if (value === undefined || !value.startsWith('test:'))
220
- return resolveIdentityToken(value);
221
- const name = value.slice('test:'.length).trim().toLowerCase();
222
- const variable = `MCP_TEST_USER_${name.toUpperCase()}`;
223
- const label = `test:${name}@${platform.resolveProject(project)}/${environment ?? platform.config.defaultEnvironment}`;
224
- const cached = labeledToken(label);
225
- if (cached)
226
- return cached;
227
- const raw = platform.config.testUsers[name];
228
- if (!raw) {
229
- const defined = Object.keys(platform.config.testUsers);
230
- throw new PlatformApiError(`Test kullanıcısı '${name}' tanımlı değil. Kök .env'e insan ekler: ${variable}={"application":"<uygulama slug>","microservice":"<giriş ucu slug>","body":{…giriş gövdesi…}} (biçim: docs/ortam.md §Test kullanıcıları); gateway yeniden başlatılır. AI .env'i düzenlemez. Tanımlı olanlar: ${defined.length > 0 ? defined.join(', ') : '(yok)'}.`, 400);
231
- }
232
- let login;
233
- try {
234
- login = JSON.parse(raw);
235
- }
236
- catch {
237
- throw new PlatformApiError(`${variable} JSON olarak okunamadı (değer gösterilmez). Biçim: {"application":"…","microservice":"…","body":{…}} — docs/ortam.md §Test kullanıcıları.`, 400);
238
- }
239
- if (typeof login.application !== 'string' || typeof login.microservice !== 'string') {
240
- throw new PlatformApiError(`${variable} 'application' ve 'microservice' alanlarını taşımalı (değer gösterilmez) — docs/ortam.md §Test kullanıcıları.`, 400);
241
- }
242
- const endpoint = `${login.application}/${login.microservice}`;
243
- const response = await platform.tenantRaw(typeof login.method === 'string' ? login.method : 'POST', project, `/m/${endpoint}`, {
244
- environment,
245
- body: login.body,
246
- anonymous: true,
247
- hideRequestBody: true
248
- });
249
- const token = accessJwt(response.body);
250
- if (!token) {
251
- throw new PlatformApiError(`Test kullanıcısı '${name}' girişi jeton döndürmedi: ${endpoint} HTTP ${response.httpStatus}. Kök .env'deki ${variable} satırını (uç ve gövde) ve kullanıcının uygulamada var olduğunu kontrol edin; gövde ve kimlik bilgisi gösterilmez.`, 400);
69
+ throw new PlatformApiError(`'${value}' referansı geçersiz ya da süresi dolmuş (15 dk). Uygulamanın giriş ucunu microservice_execute ile yeniden çağırıp yanıttaki tokenRefs değerini kullanın.`, 400);
252
70
  }
253
- rememberToken(token, label);
254
71
  return token;
255
72
  }
256
73
  /**