@appaflytech/zeyrek-ai-mcp 0.0.4 → 0.0.6

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 (101) hide show
  1. package/.env.example +8 -3
  2. package/.env.production.example +2 -0
  3. package/README.md +229 -193
  4. package/dist/config.js +20 -2
  5. package/dist/knowledge/backendConstraints.js +897 -0
  6. package/dist/knowledge/componentCatalog.js +196 -42
  7. package/dist/knowledge/coverage.js +43 -0
  8. package/dist/knowledge/flowGuards.js +30 -0
  9. package/dist/knowledge/guideSections.js +49 -0
  10. package/dist/knowledge/hydrate.js +97 -0
  11. package/dist/knowledge/languageCodes.js +36 -0
  12. package/dist/knowledge/languages.js +105 -0
  13. package/dist/knowledge/layoutSummary.js +10 -0
  14. package/dist/knowledge/localization.js +51 -0
  15. package/dist/knowledge/normalize.js +449 -16
  16. package/dist/knowledge/outlines.js +136 -12
  17. package/dist/knowledge/propTypes.js +80 -0
  18. package/dist/knowledge/rules.js +618 -43
  19. package/dist/knowledge/schemaGuard.js +199 -0
  20. package/dist/knowledge/styleResolve.js +63 -4
  21. package/dist/observability/trace.js +27 -3
  22. package/dist/platform/errors.js +46 -4
  23. package/dist/platform/http.js +33 -4
  24. package/dist/platform/patch.js +27 -0
  25. package/dist/platform/refs.js +104 -0
  26. package/dist/platform/responses.js +9 -2
  27. package/dist/platform/screenshot.js +527 -16
  28. package/dist/platform/secrets.js +40 -0
  29. package/dist/platform/tokenVault.js +89 -0
  30. package/dist/platform/writeDiff.js +281 -0
  31. package/dist/resources/examples/layout-app-shell.json +1 -1
  32. package/dist/resources/examples/microservice-table-list.json +2 -4
  33. package/dist/resources/examples/page-dynamic-form.json +2 -2
  34. package/dist/resources/examples/page-flex-sections.json +99 -0
  35. package/dist/resources/examples/page-sign-in.json +3 -2
  36. package/dist/resources/guides/component.md +69 -8
  37. package/dist/resources/guides/entity.md +404 -16
  38. package/dist/resources/guides/expressions.md +44 -2
  39. package/dist/resources/guides/external-component.md +9 -0
  40. package/dist/resources/guides/getting-started.md +77 -7
  41. package/dist/resources/guides/layout.md +53 -10
  42. package/dist/resources/guides/microservice.md +226 -13
  43. package/dist/resources/guides/middleware.md +89 -1
  44. package/dist/resources/guides/page.md +383 -46
  45. package/dist/resources/guides/translation.md +126 -8
  46. package/dist/resources/guides/view.md +16 -1
  47. package/dist/resources/guides/workflow.md +198 -27
  48. package/dist/resources/knowledge.js +5 -0
  49. package/dist/resources/rules.js +27 -0
  50. package/dist/resources/schema-fingerprint.json +8 -0
  51. package/dist/resources/schemas/CreateBulkRowCommand.json +33 -0
  52. package/dist/resources/schemas/CreateDatasourceCommand.json +15 -6
  53. package/dist/resources/schemas/CreateDiscoveredEntitiesCommand.json +19 -8
  54. package/dist/resources/schemas/CreateEntityCommand.json +52 -12
  55. package/dist/resources/schemas/CreateMicroserviceCommand.json +26 -2
  56. package/dist/resources/schemas/CreateQueryCommand.json +56 -3
  57. package/dist/resources/schemas/CreateRowCommand.json +38 -0
  58. package/dist/resources/schemas/CreateViewCommand.json +13 -10
  59. package/dist/resources/schemas/CreateWorkflowCommand.json +95 -14
  60. package/dist/resources/schemas/GetRowsQuery.json +3 -0
  61. package/dist/resources/schemas/PreviewMicroserviceCommand.json +16 -0
  62. package/dist/resources/schemas/PreviewQueryCommand.json +5 -2
  63. package/dist/resources/schemas/PreviewWorkflowCommand.json +34 -9
  64. package/dist/resources/schemas/StepDto.json +23 -3
  65. package/dist/resources/schemas/UpdateBulkRowCommand.json +33 -0
  66. package/dist/resources/schemas/UpdateDatasourceCommand.json +15 -6
  67. package/dist/resources/schemas/UpdateEntityCommand.json +49 -10
  68. package/dist/resources/schemas/UpdateMicroserviceCommand.json +28 -3
  69. package/dist/resources/schemas/UpdateQueryCommand.json +13 -3
  70. package/dist/resources/schemas/UpdateRowCommand.json +40 -0
  71. package/dist/resources/schemas/UpdateViewCommand.json +15 -10
  72. package/dist/resources/schemas/UpdateWorkflowCommand.json +95 -14
  73. package/dist/server.js +4 -0
  74. package/dist/tools/access.js +3 -3
  75. package/dist/tools/applications.js +1 -1
  76. package/dist/tools/automations.js +63 -30
  77. package/dist/tools/common.js +39 -0
  78. package/dist/tools/components.js +16 -7
  79. package/dist/tools/datasources.js +83 -21
  80. package/dist/tools/deployments.js +34 -2
  81. package/dist/tools/dtos.js +25 -12
  82. package/dist/tools/entities.js +113 -28
  83. package/dist/tools/externalComponents.js +9 -3
  84. package/dist/tools/files.js +20 -6
  85. package/dist/tools/flows.js +110 -11
  86. package/dist/tools/folders.js +7 -2
  87. package/dist/tools/globalFunctions.js +63 -0
  88. package/dist/tools/layouts.js +103 -29
  89. package/dist/tools/microservices.js +229 -38
  90. package/dist/tools/organizations.js +5 -6
  91. package/dist/tools/pages.js +365 -100
  92. package/dist/tools/platformInfo.js +152 -11
  93. package/dist/tools/projects.js +183 -33
  94. package/dist/tools/queries.js +32 -10
  95. package/dist/tools/rows.js +159 -45
  96. package/dist/tools/screenWrite.js +59 -0
  97. package/dist/tools/screens.js +28 -0
  98. package/dist/tools/translations.js +24 -8
  99. package/dist/tools/views.js +20 -10
  100. package/dist/tools/workflows.js +33 -16
  101. package/package.json +6 -3
@@ -1,11 +1,16 @@
1
- import { guid, projectParam, environmentParam, definitionParam, pagingParams, readOnly, writes, updates, destructive } from './common.js';
1
+ import { guid, projectParam, environmentParam, definitionParam, pagingParams, readOnly, writes, updates, destructive, microOps, languageParam } from './common.js';
2
2
  import { normalizeWorkflowDefinition, withNormalization } from '../knowledge/normalize.js';
3
3
  import { evaluatePolicy, enforcePolicy, attachFindings } from '../knowledge/policy.js';
4
4
  import { workflowOutline, resolvePart, resolvePatchOperations } from '../knowledge/outlines.js';
5
+ import { patchResult, baseVersionOf } from '../platform/patch.js';
6
+ import { writeDiff, withWriteDiff } from '../platform/writeDiff.js';
5
7
  import { policyRules } from '../knowledge/rules.js';
8
+ import { languageHeader } from '../knowledge/languageCodes.js';
6
9
  import { handle } from '../platform/responses.js';
7
10
  import fastJsonPatch from 'fast-json-patch';
8
11
  import { z } from 'zod';
12
+ import { constraintSummary } from '../knowledge/backendConstraints.js';
13
+ import { unmappedMembers, introducedUnmappedMembers, withUnmappedMembers } from '../knowledge/schemaGuard.js';
9
14
  const policyOverrideParam = z.boolean().optional()
10
15
  .describe('true: politika block bulgularını warn\'a indirir (bilinçli istisna; yanıtta işaretlenir)');
11
16
  const patchOperationsParam = z.array(z.record(z.unknown())).min(1)
@@ -106,44 +111,56 @@ export function registerWorkflowTools(server, platform) {
106
111
  }));
107
112
  server.registerTool('workflow_create', {
108
113
  title: 'Workflow oluştur',
109
- description: "Yeni workflow tanımlar (definition = CreateWorkflowCommand). type: 'workflow' | 'automation' | 'middleware'. İlk kullanımdan önce platform_guide('workflow') okuyun: DTO-önce akışı, branch bağlama (branches[].nextStepId), tip×step matrisi. Her adım ve akışın kendisi 'description' taşımak ZORUNDADIR (WF-024, block): adımın NE İŞE YARADIĞINI 1-2 cümleyle yazın — Studio kanvasında ⓘ ikonu olarak görünür; mekanizmayı değil niyeti yazın. Middleware (istek öncesi koşan guard/setter, user değişkeni, alfabetik sıra) için platform_guide('middleware') + ngapps://examples/middleware-authenticate. Adımın gerçek bir tuzağı varsa (idempotent değil, kapsam adımda değil, dış bağımlılık, sessiz düşen dal) 'caution' alanına yazın — OPSİYONELDİR, tuzak yoksa boş bırakın; doldurma metin yazmayın. Gövde politika kontrolünden geçer.",
114
+ description: "Yeni workflow tanımlar (definition = CreateWorkflowCommand). type: 'workflow' | 'automation' | 'middleware'. İlk kullanımdan önce platform_guide('workflow') okuyun: DTO-önce akışı, branch bağlama (branches[].nextStepId), tip×step matrisi. Her adım ve akışın kendisi 'description' taşımak ZORUNDADIR (WF-024, block): adımın NE İŞE YARADIĞINI 1-2 cümleyle yazın — Studio kanvasında ⓘ ikonu olarak görünür; mekanizmayı değil niyeti yazın. Middleware (istek öncesi koşan guard/setter, user değişkeni, alfabetik sıra) için platform_guide('middleware') + ngapps://examples/middleware-authenticate. Adımın gerçek bir tuzağı varsa (idempotent değil, kapsam adımda değil, dış bağımlılık, sessiz düşen dal) 'caution' alanına yazın — OPSİYONELDİR, tuzak yoksa boş bırakın; doldurma metin yazmayın. Gövde politika kontrolünden geçer. " + constraintSummary('CreateWorkflowCommand'),
110
115
  inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, definition: definitionParam, policyOverride: policyOverrideParam },
111
116
  annotations: writes
112
117
  }, handle(config, async ({ project, environment, applicationId, definition, policyOverride }) => {
113
118
  const normalized = normalizeWorkflowDefinition(definition);
114
119
  const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'workflow', definition, { operation: 'create', workflowKind: definition.type }, policyOverride));
120
+ const drift = unmappedMembers('CreateWorkflowCommand', definition);
115
121
  const payload = await platform.tenant('POST', project, `/workflows/${applicationId}`, { environment, body: definition });
116
- return attachFindings(withNormalization(payload, normalized), findings);
122
+ return attachFindings(withUnmappedMembers(withWriteDiff(withNormalization(payload, normalized), writeDiff(definition, payload)), drift), findings);
117
123
  }));
118
124
  server.registerTool('workflow_update', {
119
125
  title: 'Workflow güncelle',
120
- description: 'Workflow tanımını günceller (definition = UpdateWorkflowCommand, tam gövde). Hedefli değişiklik için workflow_patch tercih edin. Her adım ve akışın kendisi \'description\' taşımak ZORUNDADIR (WF-024, block). Adımın gerçek bir tuzağı varsa (idempotent değil, kapsam adımda değil, dış bağımlılık, sessiz düşen dal) \'caution\' alanına yazın — OPSİYONELDİR, tuzak yoksa boş bırakın; doldurma metin yazmayın. Gövde politika kontrolünden geçer.',
126
+ description: 'Workflow tanımını günceller (definition = UpdateWorkflowCommand, tam gövde). Hedefli değişiklik için workflow_patch tercih edin. Her adım ve akışın kendisi \'description\' taşımak ZORUNDADIR (WF-024, block). Adımın gerçek bir tuzağı varsa (idempotent değil, kapsam adımda değil, dış bağımlılık, sessiz düşen dal) \'caution\' alanına yazın — OPSİYONELDİR, tuzak yoksa boş bırakın; doldurma metin yazmayın. Gövde politika kontrolünden geçer. ' + constraintSummary('UpdateWorkflowCommand'),
121
127
  inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, id: guid, definition: definitionParam, policyOverride: policyOverrideParam },
122
128
  annotations: updates
123
129
  }, handle(config, async ({ project, environment, applicationId, id, definition, policyOverride }) => {
124
130
  const normalized = normalizeWorkflowDefinition(definition);
125
131
  const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'workflow', definition, { operation: 'update', workflowKind: definition.type }, policyOverride));
132
+ const drift = unmappedMembers('UpdateWorkflowCommand', definition);
126
133
  const payload = await platform.tenant('PUT', project, `/workflows/${applicationId}/${id}`, { environment, body: definition });
127
- return attachFindings(withNormalization(payload, normalized), findings);
134
+ return attachFindings(withUnmappedMembers(withWriteDiff(withNormalization(payload, normalized), writeDiff(definition, payload)), drift), findings);
128
135
  }));
129
136
  server.registerTool('workflow_patch', {
130
137
  title: 'Workflow\'a patch uygula',
131
- description: 'Tam gövdeyi bağlama almadan hedefli değişiklik: gateway mevcut workflow\'u çeker, JSON Patch işlemlerini uygular, politika kontrolünden geçirir, tam gövdeyi geri yazar. Değişiklik hedefli ama yazma değil: hata yolu olmayan bir workflow/middleware kaydına patch atmak o kaydın grafiğini de düzeltir — start adımına global-error dalı + 500 dönen response adımı eklenir ve yanıtta gatewayNormalized ile bildirilir. Yanıt outline özetidir.',
132
- inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, id: guid, operations: patchOperationsParam, policyOverride: policyOverrideParam },
138
+ description: 'Tam gövdeyi bağlama almadan hedefli değişiklik: gateway mevcut workflow\'u çeker, JSON Patch işlemlerini uygular, politika kontrolünden geçirir ve FARKI platformun PATCH /workflows/{app}/{id} ucuna `{ baseVersion, ops }` olarak yazar — tam gövde PUT\'u ATILMAZ. `baseVersion` okunan kaydın `version` alanıdır; kayıt bu arada değiştiyse platform 409 döner ve hiçbir op uygulanmaz. Değişiklik hedefli ama yazma değil: hata yolu olmayan bir workflow/middleware kaydına patch atmak o kaydın grafiğini de düzeltir — start adımına global-error dalı + 500 dönen response adımı eklenir ve yanıtta gatewayNormalized ile bildirilir. Yanıt outline özetidir.',
139
+ inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, id: guid, operations: patchOperationsParam.optional(), ops: patchOperationsParam.optional().describe("'operations' ile aynı alan (eşanlamlı) — sayfa micro-op tool'larıyla aynı adı kullanabilmeniz için"), policyOverride: policyOverrideParam },
133
140
  annotations: updates
134
- }, handle(config, async ({ project, environment, applicationId, id, operations, policyOverride }) => {
141
+ }, handle(config, async ({ project, environment, applicationId, id, operations: givenOperations, ops, policyOverride }) => {
142
+ const operations = microOps('workflow_patch', ops, givenOperations);
135
143
  const current = await platform.tenant('GET', project, `/workflows/${applicationId}/${id}`, { environment });
136
144
  const definition = structuredClone((current?.data ?? current));
137
145
  const resolved = resolvePatchOperations(definition, operations);
138
146
  const patched = fastJsonPatch.applyPatch(definition, resolved.operations, true, false).newDocument;
139
147
  const normalized = normalizeWorkflowDefinition(patched);
140
148
  const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'workflow', patched, { operation: 'update', workflowKind: patched.type }, policyOverride));
141
- await platform.tenant('PUT', project, `/workflows/${applicationId}/${id}`, { environment, body: patched });
142
- return attachFindings(withNormalization({
149
+ const drift = introducedUnmappedMembers('UpdateWorkflowCommand', (current?.data ?? current), patched);
150
+ // Gövde değil FARK gönderilir: gateway normalizasyonları da op'a çevrilsin diye net diff
151
+ // okunan kayıt ile son hâl arasından hesaplanır (tam PUT yok, yalnız değişen alanlar yazılır).
152
+ const netOps = fastJsonPatch.compare(definition, patched);
153
+ const saved = await platform.tenant('PATCH', project, `/workflows/${applicationId}/${id}`, {
154
+ environment,
155
+ body: { baseVersion: baseVersionOf(definition, 'workflow_get'), ops: netOps }
156
+ });
157
+ const written = patchResult(saved, patched);
158
+ return attachFindings(withUnmappedMembers(withNormalization({
143
159
  applied: operations.length,
160
+ newVersion: written.newVersion,
144
161
  patchTargets: resolved.targets,
145
- outline: workflowOutline(patched)
146
- }, [...normalized, ...resolved.notes.map(note => `patch yolu seçiciden indekse çözüldü: ${note}`)]), findings);
162
+ outline: workflowOutline(written.data)
163
+ }, [...normalized, ...resolved.notes.map(note => `patch yolu seçiciden indekse çözüldü: ${note}`)]), drift), findings);
147
164
  }));
148
165
  server.registerTool('workflow_delete', {
149
166
  title: 'Workflow sil',
@@ -159,13 +176,13 @@ export function registerWorkflowTools(server, platform) {
159
176
  }, handle(config, ({ project, environment, id }) => platform.tenant('POST', project, `/workflows/clone/${id}`, { environment })));
160
177
  server.registerTool('workflow_preview', {
161
178
  title: 'Workflow önizle',
162
- description: "Kaydedilmemiş workflow tanımını çalıştırır; kaydetmeden önce her akışı preview ile doğrulayın. definition = PreviewWorkflowCommand gövdesi. Test girdisi 'previewPayload' anahtarıyla verilir ('parameters'/'input' ÇALIŞMAZ), değişkenler 'previewVariables'. previewPayload STRING olmalıdır (JSON.stringify(...) ya da \"({ id: 1 })\") — nesne gönderilirse platform 'Unexpected end of input' ile 500 döner. Preview kuru çalıştırma değildir: table create/update step'leri kalıcı satır yazar.",
163
- inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, definition: definitionParam, policyOverride: policyOverrideParam },
179
+ description: "Kaydedilmemiş workflow tanımını çalıştırır; kaydetmeden önce her akışı preview ile doğrulayın. definition = PreviewWorkflowCommand gövdesi. Test girdisi 'previewPayload' anahtarıyla verilir ('parameters'/'input' ÇALIŞMAZ), değişkenler 'previewVariables'. previewPayload STRING olmalıdır (JSON.stringify(...) ya da \"({ id: 1 })\") — nesne gönderilirse platform 'Unexpected end of input' ile 500 döner. Preview tek transaction'da koşar ve sonunda ROLLBACK edilir: table create/update step'leri kalıcı satır YAZMAZ (ölçüldü, İK koşusu W-1). Tek istisna code step içindeki dış HTTP çağrılarıdır — onlar geri alınamaz. Davranış kuralları: platform_guide('workflow'). " + constraintSummary('PreviewWorkflowCommand'),
180
+ inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, definition: definitionParam, policyOverride: policyOverrideParam, language: languageParam },
164
181
  annotations: writes
165
- }, handle(config, async ({ project, environment, applicationId, definition, policyOverride }) => {
182
+ }, handle(config, async ({ project, environment, applicationId, definition, policyOverride, language }) => {
166
183
  const normalized = normalizeWorkflowDefinition(definition);
167
184
  const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'workflow', definition, { operation: 'preview', workflowKind: definition.type }, policyOverride));
168
- const payload = await platform.tenant('POST', project, `/workflows/${applicationId}/preview`, { environment, body: definition });
185
+ const payload = await platform.tenant('POST', project, `/workflows/${applicationId}/preview`, { environment, body: definition, headers: languageHeader(language, normalized) });
169
186
  return attachFindings(withNormalization(payload, normalized), findings);
170
187
  }));
171
188
  server.registerTool('workflow_step_schema', {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@appaflytech/zeyrek-ai-mcp",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "type": "module",
5
- "description": "MCP gateway exposing the NgApps platform APIs as tools",
5
+ "description": "Zeyrek (NgApps) platform APIs as MCP tools — data, logic and Studio design surface in one gateway",
6
6
  "license": "UNLICENSED",
7
7
  "engines": {
8
8
  "node": ">=20"
@@ -29,8 +29,11 @@
29
29
  "test": "vitest run",
30
30
  "docs:lint": "tsx scripts/docs-lint.ts",
31
31
  "generate-schemas": "tsx scripts/generate-schemas.ts",
32
+ "refresh-schemas": "scripts/refresh-schemas.sh",
33
+ "schema:check": "tsx scripts/schemaFingerprint.ts",
32
34
  "generate-reserved-tables": "tsx scripts/generate-reserved-tables.ts",
33
- "harvest-examples": "tsx scripts/harvest-examples.ts"
35
+ "harvest-examples": "tsx scripts/harvest-examples.ts",
36
+ "benchmark:report": "tsx scripts/benchmark-report.ts"
34
37
  },
35
38
  "dependencies": {
36
39
  "@modelcontextprotocol/sdk": "^1.12.0",