@appaflytech/zeyrek-ai-mcp 0.0.7 → 0.0.8
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/knowledge/backendConstraints.js +3 -0
- package/dist/knowledge/componentCatalog.js +59 -15
- package/dist/knowledge/normalize.js +459 -23
- package/dist/knowledge/propTypes.js +5 -4
- package/dist/knowledge/rules.js +110 -5
- package/dist/knowledge/styleResolve.js +6 -1
- package/dist/platform/http.js +10 -2
- package/dist/platform/screenshot.js +80 -8
- package/dist/platform/strictArguments.js +32 -0
- package/dist/platform/writeDiff.js +6 -3
- package/dist/resources/examples/page-sign-in.json +1 -1
- package/dist/resources/guides/component.md +1 -1
- package/dist/resources/guides/expressions.md +6 -0
- package/dist/resources/guides/getting-started.md +2 -0
- package/dist/resources/guides/layout.md +6 -0
- package/dist/resources/guides/microservice.md +105 -5
- package/dist/resources/guides/page.md +81 -18
- package/dist/resources/guides/translation.md +11 -10
- package/dist/resources/guides/workflow.md +50 -1
- package/dist/resources/schema-fingerprint.json +2 -2
- package/dist/resources/schemas/CreateMicroserviceCommand.json +4 -1
- package/dist/resources/schemas/CreateWorkflowCommand.json +4 -1
- package/dist/resources/schemas/PreviewMicroserviceCommand.json +4 -1
- package/dist/resources/schemas/PreviewWorkflowCommand.json +4 -1
- package/dist/resources/schemas/StepDto.json +4 -1
- package/dist/resources/schemas/UpdateMicroserviceCommand.json +4 -1
- package/dist/resources/schemas/UpdateWorkflowCommand.json +4 -1
- package/dist/server.js +2 -1
- package/dist/tools/flows.js +9 -3
- package/dist/tools/layouts.js +4 -4
- package/dist/tools/microservices.js +70 -6
- package/dist/tools/pages.js +127 -57
- package/dist/tools/queries.js +72 -6
- package/dist/tools/workflows.js +9 -5
- package/package.json +1 -1
package/dist/tools/queries.js
CHANGED
|
@@ -6,10 +6,57 @@ import { unmappedMembers, withUnmappedMembers } from '../knowledge/schemaGuard.j
|
|
|
6
6
|
import { handle } from '../platform/responses.js';
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import { evaluatePolicy, enforcePolicy, attachFindings } from '../knowledge/policy.js';
|
|
9
|
-
import { policyRules } from '../knowledge/rules.js';
|
|
9
|
+
import { policyRules, rawQueryParameterNames } from '../knowledge/rules.js';
|
|
10
|
+
import { PlatformApiError } from '../platform/errors.js';
|
|
10
11
|
import { constraintSummary } from '../knowledge/backendConstraints.js';
|
|
11
12
|
const policyOverrideParam = z.boolean().optional()
|
|
12
13
|
.describe('true: politika block bulgularını warn\'a indirir (bilinçli istisna; yanıtta işaretlenir)');
|
|
14
|
+
function inferredParameterType(value) {
|
|
15
|
+
if (typeof value === 'number')
|
|
16
|
+
return Number.isInteger(value) ? 'number' : 'float';
|
|
17
|
+
if (typeof value === 'boolean')
|
|
18
|
+
return 'bool';
|
|
19
|
+
if (Array.isArray(value))
|
|
20
|
+
return 'array';
|
|
21
|
+
if (value !== null && typeof value === 'object')
|
|
22
|
+
return 'object';
|
|
23
|
+
return 'text';
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* G-13 — `PreviewQueryCommand` değeri yalnız `parameters[].value`'dan okur; üst düzey `parameters`
|
|
27
|
+
* argümanı şemada yokken SDK tarafından hata vermeden atılıyordu ve sorgu NULL'la koşuyordu.
|
|
28
|
+
* Argüman artık komutun kendi alanına bağlanır.
|
|
29
|
+
*/
|
|
30
|
+
function bindPreviewParameters(definition, parameters, notes) {
|
|
31
|
+
const names = Object.keys(parameters ?? {});
|
|
32
|
+
if (parameters === undefined || names.length === 0)
|
|
33
|
+
return definition;
|
|
34
|
+
const rows = (Array.isArray(definition.parameters) ? definition.parameters : []);
|
|
35
|
+
const conflicts = names.filter(name => {
|
|
36
|
+
const row = rows.find(entry => entry?.name === name);
|
|
37
|
+
return row !== undefined && row.value !== undefined && JSON.stringify(row.value) !== JSON.stringify(parameters[name]);
|
|
38
|
+
});
|
|
39
|
+
if (conflicts.length > 0) {
|
|
40
|
+
throw new PlatformApiError(`parameters ile definition.parameters aynı adı farklı değerle taşıyor: ${conflicts.map(name => `'${name}'`).join(', ')}. Değeri tek yerde verin.`, 400);
|
|
41
|
+
}
|
|
42
|
+
const bound = rows.map(row => typeof row?.name === 'string' && row.name in parameters ? { ...row, value: parameters[row.name] } : row);
|
|
43
|
+
const added = names.filter(name => !rows.some(row => row?.name === name));
|
|
44
|
+
notes.push(`parameters definition.parameters[].value'ya bağlandı: ${names.join(', ')}${added.length > 0 ? ` (tipi değerden çıkarılıp eklenen satır: ${added.join(', ')})` : ''}`);
|
|
45
|
+
return {
|
|
46
|
+
...definition,
|
|
47
|
+
parameters: [...bound, ...added.map(name => ({ name, type: inferredParameterType(parameters[name]), value: parameters[name] }))]
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** `language` sayılmaz: platform `{{language}}` kullanan sorguya değeri kendisi ekler (`PreviewQueryCommand.cs`). */
|
|
51
|
+
function unboundPreviewParameters(definition) {
|
|
52
|
+
const rows = (Array.isArray(definition.parameters) ? definition.parameters : []);
|
|
53
|
+
return rawQueryParameterNames(definition.rawQuery)
|
|
54
|
+
.filter(name => name.toLowerCase() !== 'language')
|
|
55
|
+
.filter(name => {
|
|
56
|
+
const value = rows.find(row => row?.name === name)?.value;
|
|
57
|
+
return value === undefined || value === null || (typeof value === 'string' && value.trim() === '');
|
|
58
|
+
});
|
|
59
|
+
}
|
|
13
60
|
export function registerQueryTools(server, platform) {
|
|
14
61
|
const config = platform.config;
|
|
15
62
|
server.registerTool('query_list', {
|
|
@@ -26,7 +73,7 @@ export function registerQueryTools(server, platform) {
|
|
|
26
73
|
}, handle(config, ({ project, environment, id }) => platform.tenant('GET', project, `/queries/${id}`, { environment })));
|
|
27
74
|
server.registerTool('query_create', {
|
|
28
75
|
title: 'Query oluştur',
|
|
29
|
-
description: "Yeni query tanımlar (ham SQL). definition = CreateQueryCommand gövdesi. AGREGASYON VE RAPORLAMANIN YOLU BUDUR (SUM/COUNT/AVG/GROUP BY, dönemsel özet, KPI) — view_* bir TAM METİN ARAMA indeksidir, özet üretmez (09-02 M-3). VAR OLAN SATIRLARDAN TÜRETİLEN SATIR YAZMANIN DA YOLU BUDUR: 'INSERT … SELECT' kaydedip query kaynaklı bir uçtan çalıştırmak, geçmiş/hareket/junction tablosunu TEK çağrıda doldurur ve hiçbir id elle taşınmaz (ölçüldü 2026-09-07; reçete platform_guide('entity') §'Toplu ve türetilmiş satır'). Kayıt sırasında gövde bir kez ÇALIŞTIRILIR ama geri alınır — yazan sorguyu kaydetmek satır bırakmaz ve 'returnScheme' boş döner. Kayıtlı query'nin parametreleri parameterScheme ile tanımlanır ve runtime'da bağlanır; tüketimi source:'query' microservice'idir. PARAMETRENİN DEĞERİ HER ZAMAN ÇAĞRIDAN GELİR (body → query-string → header): parametreye ifade kaynağı verilemez (parameters[].source komut şemasında yoktur, platform sessizce atar) ve middleware'in kurduğu user bu yola girmez. Kimlik/tenant kapsamı sunucu tarafında zorlanacaksa sorguyu bir workflow query adımından çağırın — reçete platform_guide('microservice') §'Kimlik kapsaması × uç kaynağı'. BOŞ STRING parametre NULL'a çevrilir: '= @p' koşulu hiçbir satırla eşleşmez ve sorgu sessizce 0 satır döner — 'filtre yok' için (@p IS NULL OR ...) yazın ya da sentinel kullanın. Yorum içindeki belirteç parametre sayılmaz. SQL çalıştırılamazsa kayıt YİNE de oluşur: returnScheme boş kalır ve yanıttaki message nedeni söyler — SQL'i düzeltip query_update ile kaydedin. SORGUNUN KENDİ AÇIKLAMASI VAR: `description` alanını doldurun — sorgu listesinde ad ve slug dışında ipucu yoktur ve ucun açıklaması (MS-014) bunun yerine geçmez, çünkü bir sorgu birden çok uçtan tüketilir; boş bırakılırsa gateway `QRY-006` uyarısı düşürür (yazmayı durdurmaz). " + constraintSummary('CreateQueryCommand'),
|
|
76
|
+
description: "Yeni query tanımlar (ham SQL). definition = CreateQueryCommand gövdesi. AGREGASYON VE RAPORLAMANIN YOLU BUDUR (SUM/COUNT/AVG/GROUP BY, dönemsel özet, KPI) — view_* bir TAM METİN ARAMA indeksidir, özet üretmez (09-02 M-3). VAR OLAN SATIRLARDAN TÜRETİLEN SATIR YAZMANIN DA YOLU BUDUR: 'INSERT … SELECT' kaydedip query kaynaklı bir uçtan çalıştırmak, geçmiş/hareket/junction tablosunu TEK çağrıda doldurur ve hiçbir id elle taşınmaz (ölçüldü 2026-09-07; reçete platform_guide('entity') §'Toplu ve türetilmiş satır'). Kayıt sırasında gövde bir kez ÇALIŞTIRILIR ama geri alınır — yazan sorguyu kaydetmek satır bırakmaz ve 'returnScheme' boş döner. Kayıtlı query'nin parametreleri parameterScheme ile tanımlanır ve runtime'da bağlanır; tüketimi source:'query' microservice'idir. PARAMETRENİN DEĞERİ HER ZAMAN ÇAĞRIDAN GELİR (body → query-string → header): parametreye ifade kaynağı verilemez (parameters[].source komut şemasında yoktur, platform sessizce atar) ve middleware'in kurduğu user bu yola girmez. Kimlik/tenant kapsamı sunucu tarafında zorlanacaksa sorguyu bir workflow query adımından çağırın — reçete platform_guide('microservice') §'Kimlik kapsaması × uç kaynağı'. BOŞ STRING parametre NULL'a çevrilir: '= @p' koşulu hiçbir satırla eşleşmez ve sorgu sessizce 0 satır döner — 'filtre yok' için (@p IS NULL OR ...) yazın ya da sentinel kullanın; (@p = '' OR ...) kalıbı hiçbir zaman eşleşmez ve gateway `QRY-007` uyarısı düşürür. Yorum içindeki belirteç parametre sayılmaz. SQL çalıştırılamazsa kayıt YİNE de oluşur: returnScheme boş kalır ve yanıttaki message nedeni söyler — SQL'i düzeltip query_update ile kaydedin. SORGUNUN KENDİ AÇIKLAMASI VAR: `description` alanını doldurun — sorgu listesinde ad ve slug dışında ipucu yoktur ve ucun açıklaması (MS-014) bunun yerine geçmez, çünkü bir sorgu birden çok uçtan tüketilir; boş bırakılırsa gateway `QRY-006` uyarısı düşürür (yazmayı durdurmaz). " + constraintSummary('CreateQueryCommand'),
|
|
30
77
|
inputSchema: { project: projectParam, environment: environmentParam, definition: definitionParam, policyOverride: policyOverrideParam },
|
|
31
78
|
annotations: writes
|
|
32
79
|
}, handle(config, async ({ project, environment, definition, policyOverride }) => {
|
|
@@ -59,12 +106,31 @@ export function registerQueryTools(server, platform) {
|
|
|
59
106
|
server.registerTool('query_preview', {
|
|
60
107
|
title: 'Query önizle',
|
|
61
108
|
description: "Kaydedilmemiş query tanımını datasource üzerinde çalıştırır. definition = PreviewQueryCommand gövdesi. Preview ROLLBACK edilir: yazan bir sorgu (INSERT/UPDATE/DELETE) çalışır, affectedRowCount gerçek sayıyı döner ama SATIR KALMAZ (ölçüldü, 09-04 Y-19) — yazmayı doğrulamak için sorguyu kaydedip microservice/workflow üzerinden çalıştırın. YANITTA ROLLBACK İŞARETİ YOKTUR: 2026-09-07'de ölçüldü, yazan sorgunun yanıtı yalnız { affectedRowCount, elapsedMilliseconds } taşıyor — sayı başarı gibi görünür, tek kanıt sonradan row_list çekmektir. BOŞ STRING parametre NULL'a çevrilir (üç koşuda ölçüldü): '= @p' hiçbir satırla eşleşmez, 0 satır döner ve hata yoktur. Davranış kuralları: platform_guide('microservice'). " + constraintSummary('PreviewQueryCommand'),
|
|
62
|
-
inputSchema: {
|
|
109
|
+
inputSchema: {
|
|
110
|
+
project: projectParam,
|
|
111
|
+
environment: environmentParam,
|
|
112
|
+
datasourceId: guid,
|
|
113
|
+
definition: definitionParam,
|
|
114
|
+
parameters: z.record(z.unknown()).optional()
|
|
115
|
+
.describe("Önizleme değerleri (ad → değer). definition.parameters[] içindeki aynı adlı satırın value'suna yazılır; satır yoksa tipi değerden çıkarılarak eklenir (tam sayı → number, ondalık → float, true/false → bool, diğerleri → text). Aynı ad definition.parameters'ta FARKLI bir value ile de varsa çağrı gönderilmez."),
|
|
116
|
+
language: languageParam,
|
|
117
|
+
policyOverride: policyOverrideParam
|
|
118
|
+
},
|
|
63
119
|
annotations: writes
|
|
64
|
-
}, handle(config, async ({ project, environment, datasourceId, definition, language, policyOverride }) => {
|
|
65
|
-
const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'query', definition, { operation: 'preview' }, policyOverride));
|
|
120
|
+
}, handle(config, async ({ project, environment, datasourceId, definition: given, parameters, language, policyOverride }) => {
|
|
66
121
|
const notes = [];
|
|
122
|
+
const definition = bindPreviewParameters(given, parameters, notes);
|
|
123
|
+
const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'query', definition, { operation: 'preview' }, policyOverride));
|
|
67
124
|
const headers = languageHeader(language, notes);
|
|
68
|
-
|
|
125
|
+
const payload = await platform.tenant('POST', project, `/queries/${datasourceId}/preview`, { environment, body: definition, headers });
|
|
126
|
+
const unbound = unboundPreviewParameters(definition);
|
|
127
|
+
const withUnbound = unbound.length > 0 && payload && typeof payload === 'object' && !Array.isArray(payload)
|
|
128
|
+
? {
|
|
129
|
+
...payload,
|
|
130
|
+
unboundParameters: unbound,
|
|
131
|
+
unboundParametersNote: "rawQuery bu parametrelere başvuruyor ama değerleri yok ya da boş string (platform boş string'i NULL'a çevirir) — sorgu onları NULL ile koştu. Değeri üst düzey 'parameters' ya da definition.parameters[].value ile verin."
|
|
132
|
+
}
|
|
133
|
+
: payload;
|
|
134
|
+
return attachFindings(withNormalization(withUnbound, notes), findings);
|
|
69
135
|
}));
|
|
70
136
|
}
|
package/dist/tools/workflows.js
CHANGED
|
@@ -4,7 +4,7 @@ import { evaluatePolicy, enforcePolicy, attachFindings } from '../knowledge/poli
|
|
|
4
4
|
import { workflowOutline, resolvePart, resolvePatchOperations } from '../knowledge/outlines.js';
|
|
5
5
|
import { patchResult, baseVersionOf } from '../platform/patch.js';
|
|
6
6
|
import { writeDiff, withWriteDiff } from '../platform/writeDiff.js';
|
|
7
|
-
import { policyRules, microfunctionStepFindings } from '../knowledge/rules.js';
|
|
7
|
+
import { policyRules, microfunctionStepFindings, undefinedInputFieldFindings } from '../knowledge/rules.js';
|
|
8
8
|
import { languageHeader } from '../knowledge/languageCodes.js';
|
|
9
9
|
import { handle } from '../platform/responses.js';
|
|
10
10
|
import fastJsonPatch from 'fast-json-patch';
|
|
@@ -118,7 +118,8 @@ export function registerWorkflowTools(server, platform) {
|
|
|
118
118
|
const normalized = normalizeWorkflowDefinition(definition);
|
|
119
119
|
const findings = enforcePolicy([
|
|
120
120
|
...evaluatePolicy(config, policyRules, 'workflow', definition, { operation: 'create', workflowKind: definition.type }, policyOverride),
|
|
121
|
-
...await microfunctionStepFindings(platform, project, environment, definition, definition.type, policyOverride)
|
|
121
|
+
...await microfunctionStepFindings(platform, project, environment, definition, definition.type, policyOverride),
|
|
122
|
+
...await undefinedInputFieldFindings(platform, project, environment, definition, definition.type, policyOverride)
|
|
122
123
|
]);
|
|
123
124
|
const drift = unmappedMembers('CreateWorkflowCommand', definition);
|
|
124
125
|
const payload = await platform.tenant('POST', project, `/workflows/${applicationId}`, { environment, body: definition });
|
|
@@ -133,7 +134,8 @@ export function registerWorkflowTools(server, platform) {
|
|
|
133
134
|
const normalized = normalizeWorkflowDefinition(definition);
|
|
134
135
|
const findings = enforcePolicy([
|
|
135
136
|
...evaluatePolicy(config, policyRules, 'workflow', definition, { operation: 'update', workflowKind: definition.type }, policyOverride),
|
|
136
|
-
...await microfunctionStepFindings(platform, project, environment, definition, definition.type, policyOverride)
|
|
137
|
+
...await microfunctionStepFindings(platform, project, environment, definition, definition.type, policyOverride),
|
|
138
|
+
...await undefinedInputFieldFindings(platform, project, environment, definition, definition.type, policyOverride)
|
|
137
139
|
]);
|
|
138
140
|
const drift = unmappedMembers('UpdateWorkflowCommand', definition);
|
|
139
141
|
const payload = await platform.tenant('PUT', project, `/workflows/${applicationId}/${id}`, { environment, body: definition });
|
|
@@ -153,7 +155,8 @@ export function registerWorkflowTools(server, platform) {
|
|
|
153
155
|
const normalized = normalizeWorkflowDefinition(patched);
|
|
154
156
|
const findings = enforcePolicy([
|
|
155
157
|
...evaluatePolicy(config, policyRules, 'workflow', patched, { operation: 'update', workflowKind: patched.type }, policyOverride),
|
|
156
|
-
...await microfunctionStepFindings(platform, project, environment, patched, patched.type, policyOverride)
|
|
158
|
+
...await microfunctionStepFindings(platform, project, environment, patched, patched.type, policyOverride),
|
|
159
|
+
...await undefinedInputFieldFindings(platform, project, environment, patched, patched.type, policyOverride)
|
|
157
160
|
]);
|
|
158
161
|
const drift = introducedUnmappedMembers('UpdateWorkflowCommand', (current?.data ?? current), patched);
|
|
159
162
|
// Gövde değil FARK gönderilir: gateway normalizasyonları da op'a çevrilsin diye net diff
|
|
@@ -198,7 +201,8 @@ export function registerWorkflowTools(server, platform) {
|
|
|
198
201
|
}
|
|
199
202
|
const findings = enforcePolicy([
|
|
200
203
|
...evaluatePolicy(config, policyRules, 'workflow', definition, { operation: 'preview', workflowKind: definition.type }, policyOverride),
|
|
201
|
-
...await microfunctionStepFindings(platform, project, environment, definition, definition.type, policyOverride)
|
|
204
|
+
...await microfunctionStepFindings(platform, project, environment, definition, definition.type, policyOverride),
|
|
205
|
+
...await undefinedInputFieldFindings(platform, project, environment, definition, definition.type, policyOverride)
|
|
202
206
|
]);
|
|
203
207
|
const payload = await platform.tenant('POST', project, `/workflows/${applicationId}/preview`, { environment, body: definition, headers: languageHeader(language, normalized) });
|
|
204
208
|
return attachFindings(withNormalization(payload, normalized), findings);
|
package/package.json
CHANGED