genexus-mcp 3.0.0 → 3.0.2

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/README.md CHANGED
@@ -183,6 +183,7 @@ Once installed, here's what unlocks. Try these as your first prompts:
183
183
  - *"Add a menu option 'Customers' to MainMenu that opens CustomerWW."*
184
184
 
185
185
  **WorkWithPlus pattern editing** (full structural + theming control)
186
+ - *"Add a typed tab with variables, an action, and nested responsive tables to a WorkWithPlus WebPanel."*
186
187
  - *"In WorkWithPlusOrder, add a 'Duplicate' button to the transaction view alongside Save/Cancel/Delete."*
187
188
  - *"Group the Customer transaction attributes into a 'Contact Info' section with theme class GroupTelaResp."*
188
189
  - *"On the WorkWithPlusInvoice list, add a new ordering by InvoiceDate descending."*
@@ -217,25 +218,17 @@ Auto-detected and auto-configured by the installer:
217
218
  | OpenCode (CLI) | ✅ | Reads both direct and nested MCP layouts; restart required |
218
219
  | Codex CLI | ✅ | Writes `~/.codex/config.toml` |
219
220
  | VS Code / VS Code Insiders | ✅ | Native MCP (`User/mcp.json`); restart required |
220
- | OpenCode Desktop | Manual setup | Detected and reported with exact local-server fields; add the server from the app's MCP settings |
221
+ | OpenCode Desktop | ✅ | Shares `opencode.jsonc` with OpenCode CLI; restart required |
221
222
  | Any MCP client | Manual | Use the JSON snippet printed by `init` |
222
223
 
223
224
  Run **`npx genexus-mcp clients`** at any time to see which agents are installed, which have `genexus` registered, and whether any point at a stale gateway exe. To (re)register specific ones: `npx genexus-mcp clients add --clients antigravity,vscode`.
224
225
 
225
- ### OpenCode Desktop (manual setup)
226
+ ### OpenCode Desktop
226
227
 
227
- The CLI detects OpenCode Desktop but does not write its app-managed `mcp.json`.
228
- After `init` prints the path to `config.json`, open **Settings → MCP → Add server
229
- → Local** in OpenCode Desktop and enter:
230
-
231
- - Name: `genexus18mcp`
232
- - Command: `npx.cmd` on Windows, `npx` elsewhere
233
- - Arguments: `-y genexus-mcp@latest`
234
- - Environment: `GX_CONFIG_PATH=<the config.json path printed by init>`
235
-
236
- Save the server, fully restart OpenCode Desktop, and call `genexus_whoami` to
237
- verify the GeneXus server and selected KB. The CLI intentionally leaves the
238
- Desktop-managed configuration file untouched.
228
+ OpenCode Desktop shares its MCP configuration file (`opencode.jsonc` or `opencode.json`)
229
+ with OpenCode CLI. Running `genexus-mcp init --write-clients` or `genexus-mcp clients add --clients opencode-desktop`
230
+ automatically registers `genexus18mcp` in the shared config. After registration,
231
+ fully restart OpenCode Desktop so it reloads its MCP configuration.
239
232
 
240
233
  ---
241
234
 
@@ -313,7 +306,7 @@ produced by `DataSelectorStructurePart.ToString()` on U16.
313
306
  **Refactor, patterns & compare**
314
307
  - `genexus_refactor` — rename, extract procedure, WWP condition set
315
308
  - `genexus_apply_pattern` — apply a GeneXus pattern (WorkWith, WorkWithPlus, …); `mode=actions` manages typed WorkWithPlus grid actions and Action Groups
316
- - `genexus_wwp` — WorkWithPlus Action Group / grid-action editing: `list`, `add_action`, `update_action`, `move_action`, `remove_action`
309
+ - `genexus_wwp` — typed WorkWithPlus editing: Action Groups, atomic native `add_grid_attribute`, plus `add_tab`, `move_tab`, and `remove_tab` for WebPanel tabs and typed children
317
310
  - `genexus_compare` — IDE "Compare Objects" parity (`IComparerService`)
318
311
  - `genexus_merge` — 2- or 3-way object merge (`IMergeService`)
319
312
 
@@ -378,6 +371,8 @@ WorkWithPlus patterns are XML documents that drive Transaction-and-Selection scr
378
371
  | Reorganize Transaction view (form layout, action row) | edit under `/instance/transaction/...` | ✅ verified live |
379
372
  | Reorganize Selection view (list/grid, filters, orders) | edit under `/instance/level/selection/...` | ✅ verified live |
380
373
  | Auto-rebuild `childrenOrderedList` from XML order | done implicitly on every write; report under `childrenOrderedListReconciliation` | ✅ verified live |
374
+ | Add / move / remove WebPanel tabs and typed controls | `genexus_wwp` `add_tab` / `move_tab` / `remove_tab` | ✅ native Pattern SDK commands; snapshot + re-read + WebForm projection verification |
375
+ | Add or reconcile one grid Attribute caption | `genexus_wwp` `add_grid_attribute` | ✅ isolated dry-run, full PatternInstance/WebForm snapshots, exact rollback and no implicit lifecycle |
381
376
 
382
377
  **Recommended workflow for a screen redesign:**
383
378
 
@@ -389,6 +384,25 @@ WorkWithPlus patterns are XML documents that drive Transaction-and-Selection scr
389
384
 
390
385
  **Custom buttons use `<userAction>`, not `<standardAction>`.** `Trn_Enter` / `Trn_Cancel` / `Trn_Delete` are the only registered standard actions on a WorkWithPlus transaction; any custom button (Duplicate, Audit, Export, etc.) must be a `<userAction caption="…" name="…" buttonClass="btn ButtonGreen" confirm="False" />`. The MCP's reconciler treats `<userAction>` as a peer of `<standardAction>` (same typeCode 17/18 by context), so they coexist in the same `TableActions` row and the IDE renders them side-by-side.
391
386
 
387
+ For WebPanel tabs, prefer the native typed operation instead of whole-XML replacement:
388
+
389
+ ```json
390
+ {
391
+ "action": "add_tab",
392
+ "name": "SamplePanel",
393
+ "controlName": "IntegrationV3",
394
+ "title": "Integration API V3",
395
+ "position": 5,
396
+ "children": [
397
+ { "type": "variable", "name": "Operation", "basicType": "VarChar", "length": 40 },
398
+ { "type": "userAction", "name": "SendIntegration", "caption": "Send" }
399
+ ],
400
+ "dryRun": true
401
+ }
402
+ ```
403
+
404
+ The dry-run returns a typed diff and `versionToken`. Pass it as `baseVersion` on the persisted call. The write uses Pattern SDK element commands, requires exact PatternInstance/WebForm snapshots, preserves Apply-on-save, re-reads the PatternInstance, projects and re-reads the parent WebForm, and rolls both parts back on any failed confirmation. It never invokes lifecycle operations.
405
+
392
406
  **Things to know (orientation, not gotchas):**
393
407
 
394
408
  - **WorkWithPlus normalizes some attributes after every save.** Certain fields are bound to the underlying transaction (e.g., `title` on top-level groups derives from the transaction's friendly name). When `"Apply this pattern on save"` is enabled on the WorkWithPlus object, the engine recomputes those fields — same behavior whether you edit in the IDE or via MCP. To make a hard override stick, toggle that flag via MCP:
package/cli/lib/config.js CHANGED
@@ -650,13 +650,9 @@ function getClientConfigTargets() {
650
650
  {
651
651
  id: 'opencode-desktop',
652
652
  name: 'OpenCode Desktop',
653
- // Detect-only: the Desktop app's MCP config schema differs from the CLI
654
- // and isn't auto-written yet. We report it so the user knows it's there
655
- // and how to wire it up, but never mutate its config blindly.
656
- format: 'manual',
657
- writeSupported: false,
658
- manualNote: 'OpenCode Desktop manual setup: Settings > MCP > Add server > Local; name genexus18mcp; command npx.cmd on Windows (npx elsewhere); args -y genexus-mcp@latest; environment GX_CONFIG_PATH=<config.json path printed by init>; save, fully restart the app, then call genexus_whoami. The CLI does not write the app-managed Desktop mcp.json.',
659
- path: path.join(appData, 'ai.opencode.desktop', 'mcp.json'),
653
+ format: 'opencode',
654
+ path: resolveOpenCodeConfigPath(xdgConfig),
655
+ detectByMarkerOnly: true,
660
656
  installMarkers: [
661
657
  path.join(localAppData, 'Programs', '@opencode-aidesktop'),
662
658
  path.join(appData, 'ai.opencode.desktop'),
@@ -693,8 +689,9 @@ function detectClientInstalled(client) {
693
689
  break;
694
690
  }
695
691
  }
692
+ const installed = client.detectByMarkerOnly ? (markerHit !== null) : (hasConfig || markerHit !== null);
696
693
  return {
697
- installed: hasConfig || markerHit !== null,
694
+ installed,
698
695
  hasConfig,
699
696
  markerHit,
700
697
  markersChecked: markers
@@ -808,9 +805,8 @@ function patchClientConfig(targetConfigPath, opts = {}) {
808
805
  platform: process.platform
809
806
  });
810
807
 
811
- // A direct gateway path only matters to clients that can be written. A
812
- // detect-only client such as OpenCode Desktop must still receive manual
813
- // setup guidance when its app-managed config is not detectable.
808
+ // A direct gateway path only matters to clients that can be written. Any
809
+ // detect-only client must still receive manual setup guidance when not writable.
814
810
  const writableCandidates = candidates.filter((client) =>
815
811
  client.writeSupported !== false
816
812
  && (!onlyExisting || detectClientInstalled(client).installed)
@@ -831,7 +827,7 @@ function patchClientConfig(targetConfigPath, opts = {}) {
831
827
  const skipped = [];
832
828
 
833
829
  for (const client of candidates) {
834
- // Detect-only agents (e.g. OpenCode Desktop) can't be auto-written; surface
830
+ // Detect-only agents can't be auto-written; surface
835
831
  // the manual step instead of pretending we registered them.
836
832
  if (client.writeSupported === false) {
837
833
  const detection = detectClientInstalled(client);
package/cli/run.test.js CHANGED
@@ -791,7 +791,7 @@ test('clients list returns structured status with summary', () => {
791
791
  assert.equal(typeof row.registered, 'boolean');
792
792
  });
793
793
 
794
- test('clients list reports OpenCode Desktop as manual with exact setup fields', () => {
794
+ test('clients list reports OpenCode Desktop with shared opencode config', () => {
795
795
  const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-opencode-desktop-status-'));
796
796
  try {
797
797
  const env = sandboxHomeEnv(tempRoot);
@@ -803,70 +803,85 @@ test('clients list reports OpenCode Desktop as manual with exact setup fields',
803
803
  assert.ok(row, 'OpenCode Desktop should be listed');
804
804
  assert.equal(row.installed, true);
805
805
  assert.equal(row.registered, false);
806
- assert.equal(row.writeSupported, false);
807
- assert.equal(row.registrationMode, 'manual');
808
- assert.equal(row.manualSetup.transport, 'local');
809
- assert.deepEqual(row.manualSetup.args, ['-y', 'genexus-mcp@latest']);
810
- assert.equal(row.manualSetup.environment.GX_CONFIG_PATH, '<config.json path printed by genexus-mcp init>');
811
- assert.ok(row.manualSetup.steps.some((step) => step.includes('genexus_whoami')));
812
- assert.match(row.note, /does not write/i);
806
+ assert.equal(row.writeSupported, true);
807
+ assert.equal(row.registrationMode, 'automatic');
808
+ assert.equal(row.manualSetup, null);
809
+ assert.equal(row.note, null);
810
+ assert.equal(row.configPath, path.join(env.XDG_CONFIG_HOME, 'opencode', 'opencode.json'));
811
+
812
+ // When the shared opencode.jsonc has the server registered, Desktop is recognized as registered
813
+ const opencodeCfg = path.join(env.XDG_CONFIG_HOME, 'opencode', 'opencode.jsonc');
814
+ fs.mkdirSync(path.dirname(opencodeCfg), { recursive: true });
815
+ fs.writeFileSync(opencodeCfg, JSON.stringify({
816
+ mcp: {
817
+ genexus18mcp: {
818
+ type: 'local',
819
+ command: ['npx.cmd', '-y', 'genexus-mcp@latest'],
820
+ environment: { GX_CONFIG_PATH: 'C:\\test\\config.json' }
821
+ }
822
+ }
823
+ }, null, 2));
824
+
825
+ const resultRegistered = runCli(['clients', '--format', 'json'], { env });
826
+ assert.equal(resultRegistered.status, 0);
827
+ const rowRegistered = JSON.parse(resultRegistered.stdout).ok.clients.find((client) => client.id === 'opencode-desktop');
828
+ assert.equal(rowRegistered.installed, true);
829
+ assert.equal(rowRegistered.registered, true);
830
+ assert.equal(rowRegistered.command, 'npx.cmd');
831
+ assert.equal(rowRegistered.configPath, opencodeCfg);
832
+ assert.equal(rowRegistered.registrationMode, 'automatic');
813
833
  } finally {
814
834
  fs.rmSync(tempRoot, { recursive: true, force: true });
815
835
  }
816
836
  });
817
837
 
818
- test('clients add reports OpenCode Desktop manual skip without mutating its app-managed file', () => {
838
+ test('clients add patches OpenCode Desktop into shared opencode config', () => {
819
839
  const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-opencode-desktop-add-'));
820
840
  try {
821
841
  const env = sandboxHomeEnv(tempRoot);
822
842
  const cfgPath = path.join(tempRoot, 'config.json');
823
843
  const desktopDir = path.join(env.APPDATA, 'ai.opencode.desktop');
824
- const desktopConfig = path.join(desktopDir, 'mcp.json');
825
- const original = { unrelated: { keep: true } };
826
844
  fs.writeFileSync(cfgPath, JSON.stringify({ Environment: { KBPath: tempRoot } }));
827
845
  fs.mkdirSync(desktopDir, { recursive: true });
828
- fs.writeFileSync(desktopConfig, JSON.stringify(original, null, 2));
829
846
 
830
847
  const result = runCli(['clients', 'add', '--clients', 'opencode-desktop', '--format', 'json'], {
831
848
  env: { ...env, GX_CONFIG_PATH: cfgPath }
832
849
  });
833
850
  assert.equal(result.status, 0);
834
851
  const parsed = JSON.parse(result.stdout);
835
- assert.deepEqual(parsed.ok.patchedClients, []);
836
- const skipped = parsed.meta.skippedClients.find((entry) => entry.client === 'OpenCode Desktop');
837
- assert.ok(skipped && /Settings > MCP|manual setup/i.test(skipped.reason));
838
- assert.equal(skipped.registrationMode, 'manual');
839
- assert.equal(skipped.installed, true);
840
- assert.equal(skipped.manualSetup.environment.GX_CONFIG_PATH, cfgPath);
841
- assert.ok(parsed.help.some((entry) => /manual setup/i.test(entry)));
842
- assert.deepEqual(JSON.parse(fs.readFileSync(desktopConfig, 'utf8')), original);
852
+ assert.ok(parsed.ok.patchedClients.includes('OpenCode Desktop'));
853
+ const opencodeCfg = path.join(env.XDG_CONFIG_HOME, 'opencode', 'opencode.json');
854
+ assert.ok(fs.existsSync(opencodeCfg), 'shared opencode config should be created');
855
+ const written = JSON.parse(fs.readFileSync(opencodeCfg, 'utf8'));
856
+ assert.ok(written.mcp.genexus18mcp, 'shared config should contain genexus18mcp entry');
857
+ assert.equal(written.mcp.genexus18mcp.environment.GX_CONFIG_PATH, cfgPath);
858
+
859
+ const listRes = runCli(['clients', '--format', 'json'], { env });
860
+ const row = JSON.parse(listRes.stdout).ok.clients.find((client) => client.id === 'opencode-desktop');
861
+ assert.ok(row && row.registered, 'OpenCode Desktop should now report registered');
843
862
  } finally {
844
863
  fs.rmSync(tempRoot, { recursive: true, force: true });
845
864
  }
846
865
  });
847
866
 
848
- test('clients add always reports undetected OpenCode Desktop manual setup', () => {
867
+ test('OpenCode Desktop is not falsely reported as installed when only CLI config exists', () => {
849
868
  const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-opencode-desktop-undetected-'));
850
869
  try {
851
870
  const env = sandboxHomeEnv(tempRoot);
852
- const cfgPath = path.join(tempRoot, 'config.json');
853
- fs.writeFileSync(cfgPath, JSON.stringify({ Environment: { KBPath: tempRoot } }));
871
+ const opencodeCfg = path.join(env.XDG_CONFIG_HOME, 'opencode', 'opencode.jsonc');
872
+ fs.mkdirSync(path.dirname(opencodeCfg), { recursive: true });
873
+ fs.writeFileSync(opencodeCfg, JSON.stringify({ mcp: {} }));
854
874
 
855
- const result = runCli(['clients', 'add', '--clients', 'opencode-desktop', '--format', 'json'], {
856
- env: {
857
- ...env,
858
- GX_CONFIG_PATH: cfgPath,
859
- GENEXUS_MCP_GATEWAY_EXE: path.join(tempRoot, 'missing', 'GxMcp.Gateway.exe')
860
- }
861
- });
875
+ const result = runCli(['clients', '--format', 'json'], { env });
862
876
  assert.equal(result.status, 0);
863
877
  const parsed = JSON.parse(result.stdout);
864
- assert.deepEqual(parsed.ok.patchedClients, []);
865
- const skipped = parsed.meta.skippedClients.find((entry) => entry.client === 'OpenCode Desktop');
866
- assert.ok(skipped, 'undetected detect-only client should still be actionable');
867
- assert.equal(skipped.installed, false);
868
- assert.equal(skipped.manualSetup.environment.GX_CONFIG_PATH, cfgPath);
869
- assert.equal(skipped.manualSetup.command, process.platform === 'win32' ? 'npx.cmd' : 'npx');
878
+ const desktopRow = parsed.ok.clients.find((client) => client.id === 'opencode-desktop');
879
+ assert.ok(desktopRow, 'OpenCode Desktop should be present in targets');
880
+ assert.equal(desktopRow.installed, false, 'Desktop must not be detected installed without its install markers');
881
+
882
+ const cliRow = parsed.ok.clients.find((client) => client.id === 'opencode');
883
+ assert.ok(cliRow, 'OpenCode CLI should be present in targets');
884
+ assert.equal(cliRow.installed, true, 'OpenCode CLI is detected installed via config file');
870
885
  } finally {
871
886
  fs.rmSync(tempRoot, { recursive: true, force: true });
872
887
  }
@@ -1133,6 +1148,31 @@ test('init auto-registers detected OpenCode in either config layout', () => {
1133
1148
  }
1134
1149
  });
1135
1150
 
1151
+ test('init auto-registers detected OpenCode Desktop when its marker is present', () => {
1152
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-opencode-desktop-init-'));
1153
+ try {
1154
+ const env = sandboxHomeEnv(tempRoot);
1155
+ const kbDir = path.join(tempRoot, 'kb');
1156
+ fs.mkdirSync(kbDir, { recursive: true });
1157
+ fs.mkdirSync(path.join(env.APPDATA, 'ai.opencode.desktop'), { recursive: true });
1158
+
1159
+ const result = runCli(
1160
+ ['init', '--kb', kbDir, '--gx', testGxPath, '--no-smoke', '--format', 'json'],
1161
+ { cwd: kbDir, env: { ...env, ...testGatewayEnv } }
1162
+ );
1163
+ assert.equal(result.status, 0, `init should succeed: ${result.stderr}`);
1164
+
1165
+ const parsed = JSON.parse(result.stdout);
1166
+ assert.ok(parsed.meta.patchedClients.includes('OpenCode Desktop'));
1167
+ const openCodeCfg = path.join(env.XDG_CONFIG_HOME, 'opencode', 'opencode.json');
1168
+ assert.ok(fs.existsSync(openCodeCfg));
1169
+ const written = JSON.parse(fs.readFileSync(openCodeCfg, 'utf8'));
1170
+ assert.ok(written.mcp.genexus18mcp);
1171
+ } finally {
1172
+ fs.rmSync(tempRoot, { recursive: true, force: true });
1173
+ }
1174
+ });
1175
+
1136
1176
  test('clients add replaces a legacy genexus18 entry instead of duplicating it', () => {
1137
1177
  const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-legacy-'));
1138
1178
  const env = sandboxHomeEnv(tempRoot);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genexus-mcp",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "mcpName": "io.github.lennix1337/genexus",
5
5
  "description": "GeneXus 18 MCP server — read, edit, and analyze GeneXus knowledge base objects (transactions, web panels, procedures, SDTs) directly from Claude, Cursor, and other AI agents over the Model Context Protocol.",
6
6
  "keywords": [
@@ -7,7 +7,7 @@
7
7
  "targets": {
8
8
  ".NETCoreApp,Version=v10.0": {},
9
9
  ".NETCoreApp,Version=v10.0/win-x64": {
10
- "GxMcp.Gateway/3.0.0": {
10
+ "GxMcp.Gateway/3.0.2": {
11
11
  "dependencies": {
12
12
  "Newtonsoft.Json": "13.0.3",
13
13
  "System.Management": "10.0.5",
@@ -66,7 +66,7 @@
66
66
  }
67
67
  },
68
68
  "libraries": {
69
- "GxMcp.Gateway/3.0.0": {
69
+ "GxMcp.Gateway/3.0.2": {
70
70
  "type": "project",
71
71
  "serviceable": false,
72
72
  "sha512": ""
Binary file
Binary file
@@ -1,17 +1,17 @@
1
1
  {
2
+ "Server": {
3
+ "HttpPort": 5000,
4
+ "McpStdio": true
5
+ },
2
6
  "Logging": {
3
- "Path": "logs",
4
- "Level": "Debug"
7
+ "Level": "Debug",
8
+ "Path": "logs"
9
+ },
10
+ "GeneXus": {
11
+ "WorkerExecutable": "worker\\\\GxMcp.Worker.exe",
12
+ "InstallationPath": "C:\\\\Program Files (x86)\\\\GeneXus\\\\GeneXus18"
5
13
  },
6
14
  "Environment": {
7
15
  "KBPath": "C:\\\\KBs\\\\YourKB"
8
- },
9
- "Server": {
10
- "McpStdio": true,
11
- "HttpPort": 5000
12
- },
13
- "GeneXus": {
14
- "InstallationPath": "C:\\\\Program Files (x86)\\\\GeneXus\\\\GeneXus18",
15
- "WorkerExecutable": "worker\\\\GxMcp.Worker.exe"
16
16
  }
17
17
  }
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "schemaVersion": "gxmcp-release-manifest/1",
3
- "version": "3.0.0",
4
- "sourceCommit": "6f5c1a27df8447e25b9eca750daef40fa64207bc",
5
- "generatedAtUtc": "2026-09-06T23:59:53.6616612Z",
3
+ "version": "3.0.2",
4
+ "sourceCommit": "e51de09577f3cbf87cfcec935fc718fc8e3ce7d3",
5
+ "sourceCommitPolicy": "exact-tag",
6
+ "generatedAtUtc": "2026-09-08T01:44:24.5489076Z",
6
7
  "runtime": {
7
8
  "gateway": "net10.0-windows",
8
9
  "worker": "net48-x86",
@@ -14,33 +15,33 @@
14
15
  "2026-07-28"
15
16
  ],
16
17
  "schema": "tool_definitions.json",
17
- "schemaSha256": "c43e3943a9b8f6fcb650014a31c1a29059e1e946bf03e1e0ae51893869d8c329",
18
+ "schemaSha256": "df37664020c005ee75c7fa9b43b1546d90cc92f2ea8a42c236b4ccb999c32afd",
18
19
  "provenance": "gxmcp-sbom.json",
19
20
  "artifacts": [
20
21
  {
21
22
  "path": "gxmcp-sbom.json",
22
- "size": 552,
23
- "sha256": "484fc2edbd6146b813a93f64559bc84ca519e1426adb48a01c64e865b91c8239"
23
+ "size": 590,
24
+ "sha256": "c96f9fd41131c981b012996a8fb44d6905bb4b9c5f5b287ca1727f9ff601885e"
24
25
  },
25
26
  {
26
27
  "path": "GxMcp.Gateway.exe",
27
28
  "size": 162304,
28
- "sha256": "947e70d3cc17075957405f9d6442741b44d13f0212daabf87f77e2df68815606"
29
+ "sha256": "4f0fc8014996b711a61fa2b8016f52bf7511dd16d786f7be1beb29ce8f301723"
29
30
  },
30
31
  {
31
32
  "path": "nexus-ide.vsix",
32
- "size": 1318677,
33
- "sha256": "e894e2255c5e2c853d64adf4191ada26e6a74ddb51df752c9c53fed2a281d81c"
33
+ "size": 1318666,
34
+ "sha256": "4f47b9133a4d65668683a24e2fbfde94b05ef6740214684cc555825026749ded"
34
35
  },
35
36
  {
36
37
  "path": "tool_definitions.json",
37
- "size": 103566,
38
- "sha256": "c43e3943a9b8f6fcb650014a31c1a29059e1e946bf03e1e0ae51893869d8c329"
38
+ "size": 105044,
39
+ "sha256": "df37664020c005ee75c7fa9b43b1546d90cc92f2ea8a42c236b4ccb999c32afd"
39
40
  },
40
41
  {
41
42
  "path": "worker/GxMcp.Worker.exe",
42
- "size": 2814464,
43
- "sha256": "f6f966490c52b1e47fb70dfc3523c120d4a80a99292d8a772e3c7f2a8d77ed0b"
43
+ "size": 2859520,
44
+ "sha256": "2565c9663a3ee91019887733ad1b401a60873783c55419a06586794e8424c3e2"
44
45
  }
45
46
  ]
46
47
  }
@@ -1,19 +1,20 @@
1
1
  {
2
2
  "schemaVersion": "gxmcp-provenance/1",
3
- "version": "3.0.0",
4
- "sourceCommit": "6f5c1a27df8447e25b9eca750daef40fa64207bc",
3
+ "version": "3.0.2",
4
+ "sourceCommit": "e51de09577f3cbf87cfcec935fc718fc8e3ce7d3",
5
+ "sourceCommitPolicy": "exact-tag",
5
6
  "components": [
6
7
  {
7
8
  "name": "genexus-mcp",
8
9
  "lockfile": "package-lock.json",
9
- "size": 39915,
10
- "sha256": "52f510e2c266fe270f40bb5884508377a0922edafc035263dbcd8d8d8902fd2e"
10
+ "size": 39914,
11
+ "sha256": "985fedc445aa660d0c24ce8e894b9f9fe10a7cea090a51d2206f4992136309ae"
11
12
  },
12
13
  {
13
14
  "name": "nexus-ide",
14
15
  "lockfile": "src/nexus-ide/package-lock.json",
15
- "size": 274985,
16
- "sha256": "1b4d8ecfb2037951701c50fce38f6db4702a96fd5a3c8a7f4a105b9cce834260"
16
+ "size": 274983,
17
+ "sha256": "670a1a40c59766ee10790a62f115234b7f01a6c1eb0714f8eb125807e14b8593"
17
18
  }
18
19
  ]
19
20
  }
Binary file
@@ -18,7 +18,7 @@
18
18
  {"name":"genexus_run_object","description":"Resolve runtime URL for an object (webRoot + aspx + encoded args). gamSession='auto'|{user,pass,...} captures GAM cookies. Does NOT open a browser. dryRun=true returns the resolved URL without performing GAM login.","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"args":{"type":"array","items":{"type":"string"},"description":"Positional parameter values."},"gamSession":{"description":"'auto' (use GXMCP_GAM_USER/PASS env) or {user, pass, repository?, loginUrl?}."},"dryRun":{"type":"boolean","default":false,"description":"When true, returns the resolved URL without performing the GAM login step."},"kb":{"type":"string","description":"KB alias."}},"required":["name"],"examples":[{"name":"WPMain"},{"name":"WPCustomer","args":["42"]}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":true}},
19
19
  {"name":"genexus_format","description":"Format a GeneXus code snippet using worker rules.","inputSchema":{"type":"object","properties":{"code":{"type":"string"},"kb":{"type":"string","description":"KB alias."}},"required":["code"],"examples":[{"code":"for each Customer where CustomerId = &Id\n &Name = CustomerName\nendfor"}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
20
20
  {"name":"genexus_gam","description":"GAM / integrated-security provisioning via the SDK's IIntegratedSecurityService — distinct from genexus_security (env-scan/regex audit). action=status (default) is read-only: IsEnabledIntegratedSecurity + GAM-DB-reorganize flag. action=define_api / action=deploy are DESTRUCTIVE — they create/alter GAM security tables in the KB's datastore; no default reaches them, action must be set explicitly.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["status","define_api","deploy"],"description":"status (default, read-only) | define_api | deploy."},"force":{"type":"boolean","description":"define_api only: force flag passed to DefineAPI."},"forceTableCreation":{"type":"boolean","description":"deploy only: force GAM table creation."},"rebuild":{"type":"boolean","description":"deploy only: rebuild flag."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"status"},{"action":"deploy","forceTableCreation":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},
21
- {"name":"genexus_properties","description":"Read/update object properties. action=get|set|move. move snapshots every persisted part, checks baseVersion, verifies inside the SDK transaction and after commit, and rolls back divergence. Use destination for a Folder/Module or targetModule for a Module; destKind disambiguates equal names. dryRun does not save or change the token. Move never runs lifecycle, compilation, execution, or tests. Description is the WebPanel/Popup title-bar text. Use genexus_layout set_property for layout controls.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["get","set","move"],"description":"Object-property operation to read or change metadata or move the object."},"name":{"type":"string"},"type":{"type":"string","description":"Optional object type disambiguator."},"control":{"type":"string","description":"Optional. Layout control name (e.g. BtnConfirmar), variable name with & prefix (e.g. &Alu2RegProf), or attribute name."},"propertyName":{"type":"string"},"value":{"type":"string"},"properties":{"type":"object","description":"Batch set: map of propertyName to value applied in 1 transaction."},"destination":{"type":"string","description":"move: target Folder/Module name (auto-detects kind)."},"targetModule":{"type":"string","description":"move: typed alias for a Module destination."},"destKind":{"type":"string","enum":["Folder","Module"],"description":"move: disambiguate when a Folder and Module share a name."},"dryRun":{"type":"boolean","description":"move: preview from/to and preserved parts without persisting."},"baseVersion":{"type":"string","description":"move: opaque optimistic concurrency token returned by a prior read."},"validationMode":{"type":"string","enum":["specify"],"description":"Issue #60: with action=set, run the inline Specify pass (Spec+Gen, no Compile) after the property write, returning structured spc*/gen* diagnostics in the same call. Combines with rollbackOnFailure."},"rollbackOnFailure":{"type":"boolean","description":"move: attempt compensating snapshot restoration if the SDK transaction rollback is insufficient (default true). set+validationMode=specify: request rollback after validation failure."},"kb":{"type":"string","description":"KB alias."}},"required":["action","name"],"examples":[{"action":"get","name":"MyPanel"},{"action":"move","name":"InvoiceHelper","type":"Procedure","targetModule":"operacional","baseVersion":"<versionToken from genexus_read>","dryRun":true,"rollbackOnFailure":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
21
+ {"name":"genexus_properties","description":"Read/update object properties. action=get|set|move. move snapshots every persisted part, checks baseVersion, verifies inside the SDK transaction and after commit, and rolls back divergence. Use destination for a Folder/Module or targetModule for a Module; destKind disambiguates equal names. dryRun does not save or change the token. Move never runs lifecycle, compilation, execution, or tests. Description is the WebPanel/Popup title-bar text. Use genexus_layout set_property for layout controls.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["get","set","move"],"description":"Object-property operation to read or change metadata or move the object."},"name":{"type":"string"},"type":{"type":"string","description":"Optional object type disambiguator."},"control":{"type":"string","description":"Optional. Layout control name (e.g. BtnConfirmar), variable name with & prefix (e.g. &Alu2RegProf), or attribute name."},"propertyName":{"type":"string","description":"Filter for action=get (single property, comma-separated, or * wildcard); property to change for action=set."},"propertyNames":{"type":"array","items":{"type":"string"},"description":"action=get: list of property names to return."},"query":{"type":"string","description":"action=get: filter property names by substring or * wildcard."},"projection":{"type":"string","enum":["minimal","standard","full"],"description":"action=get: compact property subset (minimal, standard, full). Defaults to full."},"value":{"type":"string"},"properties":{"type":"object","description":"Batch set: map of propertyName to value applied in 1 transaction."},"destination":{"type":"string","description":"move: target Folder/Module name (auto-detects kind)."},"targetModule":{"type":"string","description":"move: typed alias for a Module destination."},"destKind":{"type":"string","enum":["Folder","Module"],"description":"move: disambiguate when a Folder and Module share a name."},"dryRun":{"type":"boolean","description":"move: preview from/to and preserved parts without persisting."},"baseVersion":{"type":"string","description":"move: opaque optimistic concurrency token returned by a prior read."},"validationMode":{"type":"string","enum":["specify"],"description":"Issue #60: with action=set, run the inline Specify pass (Spec+Gen, no Compile) after the property write, returning structured spc*/gen* diagnostics in the same call. Combines with rollbackOnFailure."},"rollbackOnFailure":{"type":"boolean","description":"move: attempt compensating snapshot restoration if the SDK transaction rollback is insufficient (default true). set+validationMode=specify: request rollback after validation failure."},"kb":{"type":"string","description":"KB alias."}},"required":["action","name"],"examples":[{"action":"get","name":"MyPanel","propertyName":"Description"},{"action":"get","name":"MyDomain","query":"*Type*"},{"action":"get","name":"MyDomain","projection":"minimal"},{"action":"move","name":"InvoiceHelper","type":"Procedure","targetModule":"operacional","baseVersion":"<versionToken from genexus_read>","dryRun":true,"rollbackOnFailure":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
22
22
  {"name":"genexus_structure","description":"Read or write the structure/data-model of GeneXus objects. update_visual now snapshots every part, checks optimistic concurrency, saves and re-reads the Transaction, and restores the complete snapshot when persistence or authored-part verification fails. Default form projections are allowed to follow Structure; user-authored forms are invariant. No structure action implicitly runs Specify, Generate, Build, Rebuild, compilation, reorganization, execution, or tests. Other actions cover indexes, attributes (set_attribute operates on global attribute definitions; use update_visual/move_attribute/remove_attribute for Transaction structure), levels, Domains (including enumValues), SubType Groups and subtype consistency (check_subtypes). For layout control trees use genexus_layout.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["get_visual","update_visual","get_indexes","create_index","drop_index","set_attribute","set_level","set_domain","get_logic","update_group","move_attribute","remove_attribute","check_subtypes"],"description":"Structure operation to execute."},"name":{"type":"string","description":"Object name. update_visual/move_attribute: Transaction name; create_index/get_indexes: Transaction or Table name."},"module":{"type":"string","description":"update_visual/move_attribute optional: Transaction module."},"attribute":{"type":"string","description":"move_attribute: existing attribute to reorder by native SDK identity."},"before":{"type":"string","description":"move_attribute: place attribute before this attribute in the same level. Mutually exclusive with after/position."},"after":{"type":"string","description":"move_attribute: place attribute after this attribute in the same level. Mutually exclusive with before/position."},"position":{"type":"integer","minimum":0,"description":"move_attribute: zero-based final attribute position in the level. Mutually exclusive with before/after."},"level":{"type":"string","description":"move_attribute: root (default) or an unambiguous subordinate level name."},"levelPath":{"type":"array","items":{"type":"string"},"description":"move_attribute: nested level path, e.g. [\"Item\",\"Operation\"]."},"dryRun":{"type":"boolean","default":false,"description":"update_visual/move_attribute/create_index: validate and return the projected diff without changing any object, Attribute, hash, or version."},"baseVersion":{"type":"string","description":"Optimistic-concurrency token for update_visual/move_attribute/create_index. Stale state returns VersionConflict before mutation."},"expectedVersion":{"type":"string","description":"Alias of baseVersion for update_visual."},"payload":{"type":"object","description":"update_visual (Transaction):{children:[...]}; update_visual (SDT):{isCollection?,collectionItemName?,children:[{name,type?,length?,decimals?,basedOnDomain?,basedOnAttribute?,isCollection?,isLevel?,children?}]}. update_group:{members:[{name,subtypeOf}],remove?:[name]}. create_index:{attributes:[\"Attr\"],unique?:true,name?,order?:\"Ascending\"|\"Descending\"}. Other actions keep their existing typed payloads."},"validationMode":{"type":"string","enum":["specify"],"description":"Explicitly run the inline Specify pass after selected writes. Never runs unless requested."},"rollbackOnFailure":{"type":"boolean","default":true,"description":"update_visual, move_attribute and create_index capture snapshots and verify rollback after any save or re-read divergence."},"kb":{"type":"string","description":"KB alias."},"type":{"type":"string","description":"Optional object type disambiguator (e.g. 'Transaction', 'Table') when multiple objects share the same name."}},"required":["action","name"],"examples":[{"action":"update_visual","name":"OrderRecord","module":"Operations","dryRun":true,"expectedVersion":"<versionToken>","payload":{"children":[{"name":"OrderId"},{"name":"OrderAverageTime"}]}},{"action":"move_attribute","name":"SampleTransaction","attribute":"SampleSubtypeId","after":"SampleReferenceId","level":"root","dryRun":true},{"action":"get_indexes","name":"Customer"},{"action":"create_index","name":"Country","dryRun":true,"baseVersion":"<get_indexes versionToken>","payload":{"name":"UCountryName","attributes":["CountryName"],"unique":true},"rollbackOnFailure":true},{"action":"set_attribute","name":"CustomerBalance","payload":{"formula":"sum(SampleTransactionAmount)"}},{"action":"set_level","name":"Customer","payload":{"descriptionAttribute":"CustomerName"}},{"action":"update_group","name":"SampleSubtypeGroup","payload":{"members":[{"name":"SampleId","subtypeOf":"BaseId"}]}}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
23
23
  {"name":"genexus_authoring","description":"Author members of object types the structure DSL doesn't cover. add_external_method / add_external_property add a method (with parameters) or property to an External Object; add_menu_option adds an option to a Menu (target = a KB object to call); add_condition adds a filter expression to a Data Selector. name = the target object.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["add_external_method","add_external_property","add_menu_option","add_condition"],"description":"Authoring operation to add a typed member or condition to a supported object."},"name":{"type":"string","description":"ExternalObject / Menu / DataSelector name."},"payload":{"type":"object","description":"add_external_method:{name,returnType?,parameters?:[{name,type?,inout?}]}. add_external_property:{name,type?}. add_menu_option:{description,target?,optionCode?}. add_condition:{source}."},"kb":{"type":"string","description":"KB alias."}},"required":["action","name"],"examples":[{"action":"add_external_property","name":"MyExternalObject","payload":{"name":"apiKey","type":"Character"}},{"action":"add_menu_option","name":"MainMenu","payload":{"description":"Customers","target":"CustomerWW"}},{"action":"add_condition","name":"ActiveCustomers","payload":{"source":"CustomerActive = True"}}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
24
24
  {"name":"genexus_layout","description":"Layout/WebForm: get_tree, set_property, find_controls, inspect_surface, scan_mutators. Properties: genexus_properties; structure: genexus_structure get_visual.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["get_tree","set_property","find_controls","set_properties","inspect_surface","get_preview","scan_mutators","rename_printblock","add_printblock","delete_printblock","list_controls","design_system"],"description":"Layout/WebForm operation to perform."},"name":{"type":"string","description":"Target object name (WebPanel, Transaction, Procedure)."},"control":{"type":"string","description":"Control name within the layout or WebForm."},"propertyName":{"type":"string","description":"Property name to modify (e.g. Caption, Visible, Enabled, Class)."},"value":{"type":"string","description":"Value to assign to the specified property."},"query":{"type":"string","description":"find_controls: search query matching control names or captions."},"changes":{"type":"array","description":"set_properties: batch array of {control, propertyName, value} objects.","items":{"type":"object","properties":{"control":{"type":"string","description":"Control name."},"propertyName":{"type":"string","description":"Property name."},"value":{"type":"string","description":"Property value."}},"required":["control","propertyName","value"]}},"limit":{"type":"integer","description":"find_controls/list_controls: maximum results to return."},"currentName":{"type":"string","description":"rename_printblock: existing printblock name."},"newName":{"type":"string","description":"rename_printblock: new printblock name."},"printBlockName":{"type":"string","description":"add_printblock/delete_printblock: name of the printblock."},"height":{"type":"integer","description":"add_printblock: height of the new printblock."},"kb":{"type":"string","description":"KB alias."}},"required":["action"],"examples":[{"action":"get_tree","name":"WPMain"},{"action":"find_controls","name":"WPMain","query":"Button"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
@@ -26,7 +26,7 @@
26
26
  {"name":"genexus_search_source","description":"Regex/semantic search across Procedure/DataProvider/WebPanel/Transaction source. Restrict a scan by object name, persisted GUID, EntityKey, or module/folder-qualified path. Requires the KB index to be Ready — check genexus_lifecycle action=status if results look empty.","inputSchema":{"type":"object","properties":{"callee":{"type":"string","description":"Method/function name (qualified or unqualified)."},"argMatches":{"type":"object","description":"Positional arg index to expected literal text."},"pattern":{"type":"string"},"typeFilter":{"type":"string"},"objectName":{"type":"string","description":"Restrict the scan to these exact object name(s), comma-separated. Makes a search inside one known object O(object) not O(KB), and bypasses the type whitelist."},"guid":{"type":"string","description":"Persisted object GUID from genexus_list_objects."},"entityKey":{"type":"string","description":"Typed GeneXus EntityKey from genexus_list_objects verbose output."},"path":{"type":"string","description":"Module/folder-qualified object path from genexus_list_objects."},"startIndex":{"type":"integer","description":"Legacy object-boundary resume. For a page that ended inside an object, prefer the opaque cursor returned in nextCursor."},"cursor":{"type":"string","description":"Opaque continuation token from nextCursor; preferred when a result page ended inside an object. Do not edit."},"timeoutMs":{"type":"integer","description":"Wall-clock budget (default 30000). Raise it to scan more objects per call."},"scope":{"type":"array","items":{"type":"string","enum":["source","rules","conditions","events","webForm","layout"]},"description":"Parts to scan with line-numbered context. Default [source]. webForm/layout scans the WebPanel/Transaction visual XML (control names, captions, classes, bindings)."},"fields":{"type":"array","items":{"type":"string","enum":["source","caption","description","parmNames","webForm"]},"description":"Whole-field metadata match (returns matchedValue, no line context). Default [source]. Prefer scope=[webForm] for line-context WebForm hits; use fields=[webForm] only for a coarse contains-match."},"maxResults":{"type":"integer"},"caseSensitive":{"type":"boolean"},"includeComments":{"type":"boolean"},"inline_read_top":{"type":"integer","description":"0-3. Inline reads of top N distinct objects in response."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"pattern":"ControlType=\"Radio\""},{"pattern":"for each","typeFilter":"Procedure","maxResults":20}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
27
27
  {"name":"genexus_kb","description":"Manage open KBs, startup config, and GeneXus environments. list/open/close/set_default operate on WorkerPool; set_default selects the implicit target for calls that omit kb (an explicit kb always wins for parallel or cross-KB work); set_startup/get_startup mirror IDE 'Set As Startup Object'; list_environments lists all configured environments; get_environment reads the active environment; set_environment selects an environment.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["list","open","close","set_default","set_startup","get_startup","list_environments","get_environment","set_environment"],"description":"KB pool or startup-selection operation to perform."},"alias":{"type":"string","description":"KB alias. open: auto from path basename if omitted."},"path":{"type":"string","description":"Absolute KB path (required for open if alias not in config)."},"name":{"type":"string","description":"Object name (required for set_startup)."},"environment":{"type":"string","description":"Environment name/folder (required for set_environment), e.g. development."}},"required":["action"],"examples":[{"action":"open","path":"C:\\KBs\\MyKb"},{"action":"list"},{"action":"list_environments"},{"action":"get_environment"},{"action":"set_environment","environment":"development"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
28
28
  {"name":"genexus_navigation","description":"View navigation report (IDE Right-click → View Navigation). latest=true reads the most recent report from .gx/navigation-cache; latest=false runs fresh and refreshes that per-KB cache.","inputSchema":{"type":"object","required":["action","name"],"properties":{"action":{"type":"string","enum":["view"],"description":"Navigation report operation to execute."},"name":{"type":"string"},"latest":{"type":"boolean","default":false,"description":"Read the most recent cached navigation when true; when false, run fresh and refresh the per-KB navigation cache."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"view","name":"Customer"},{"action":"view","name":"Customer","latest":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
29
- {"name":"genexus_api","description":"Inspect HTTP procedures and native API routes. action=list|describe|routes_inspect|routes_clone|routes_update|snapshot|diff_baseline. API route writes use typed ServiceGroupSource, optimistic versioning, full snapshot, rollback and post-save reread; no lifecycle operation is implicit.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["list","describe","routes_inspect","routes_clone","routes_update","snapshot","diff_baseline"],"description":"API introspection, route-editing, or baseline operation to perform."},"api":{"type":"string","description":"API name (routes_inspect|routes_clone|routes_update)."},"sourcePrefix":{"type":"string","description":"Source method/path prefix, e.g. inbound."},"targetPrefix":{"type":"string","description":"Target method/path prefix, e.g. reverse."},"routes":{"type":"array","items":{"type":"object","required":["sourceMethod","method","route"],"additionalProperties":false,"properties":{"sourceMethod":{"type":"string"},"method":{"type":"string"},"route":{"type":"string","pattern":"^/"},"verb":{"type":"string"}}}},"expectedVersion":{"type":"string","description":"versionToken returned by the preceding dry run or inspection."},"dryRun":{"type":"boolean","default":true,"description":"routes_clone/routes_update: preview first; false writes only with expectedVersion."},"rollbackOnFailure":{"type":"boolean","default":true,"description":"Restore the complete API snapshot when post-save verification diverges."},"operation":{"type":"string","description":"Operation value carried by the reused request contract, e.g. REVERSE."},"target":{"type":"string","description":"Procedure or API name (action=describe)."},"name":{"type":"string","description":"Baseline name (action=snapshot)."},"baseline":{"type":"string","description":"Baseline name under .gx/api-baselines/ or absolute path (action=diff_baseline)."},"pathPrefix":{"type":"string","description":"Folder prefix filter (action=list)."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"list"},{"action":"routes_inspect","api":"OrdersApi"},{"action":"routes_clone","api":"OrdersApi","sourcePrefix":"inbound","targetPrefix":"reverse","operation":"REVERSE","dryRun":true,"rollbackOnFailure":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
29
+ {"name":"genexus_api","description":"Inspect HTTP procedures and native API routes. action=list|describe|routes_inspect|routes_clone|routes_update|snapshot|diff_baseline. API route writes use typed ServiceGroupSource, optimistic versioning, full snapshot, rollback and post-save reread; no lifecycle operation is implicit.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["list","describe","routes_inspect","routes_clone","routes_update","snapshot","diff_baseline"],"description":"API introspection, route-editing, or baseline operation to perform."},"api":{"type":"string","description":"API name (routes_inspect|routes_clone|routes_update)."},"sourcePrefix":{"type":"string","description":"Source method/path prefix, e.g. inbound."},"targetPrefix":{"type":"string","description":"Target method/path prefix, e.g. reverse."},"routes":{"type":"array","items":{"type":"object","required":["sourceMethod","method","route"],"additionalProperties":false,"properties":{"sourceMethod":{"type":"string"},"method":{"type":"string"},"route":{"type":"string","pattern":"^/"},"verb":{"type":"string"}}}},"expectedVersion":{"type":"string","description":"versionToken returned by the preceding dry run or inspection."},"versionToken":{"type":"string","description":"Backward-compatible alias for expectedVersion; pass the token returned by the preceding dry run or inspection."},"dryRun":{"type":"boolean","default":true,"description":"routes_clone/routes_update: preview first; false writes only with expectedVersion or versionToken."},"rollbackOnFailure":{"type":"boolean","default":true,"description":"Restore the complete API snapshot when post-save verification diverges."},"operation":{"type":"string","description":"Operation value carried by the reused request contract, e.g. REVERSE."},"target":{"type":"string","description":"Procedure or API name (action=describe)."},"name":{"type":"string","description":"Baseline name (action=snapshot)."},"baseline":{"type":"string","description":"Baseline name under .gx/api-baselines/ or absolute path (action=diff_baseline)."},"pathPrefix":{"type":"string","description":"Folder prefix filter (action=list)."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"list"},{"action":"routes_inspect","api":"OrdersApi"},{"action":"routes_clone","api":"OrdersApi","sourcePrefix":"inbound","targetPrefix":"reverse","operation":"REVERSE","dryRun":true,"rollbackOnFailure":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
30
30
  {"name":"genexus_apply_pattern","description":"Apply a pattern (e.g. WorkWithPlus) to a parent (IDE Right-click → Apply Pattern). Transaction=family-gen; WebPanel/WebComponent/SDPanel=direct-attach (pass settings.template). mode=diagnose (or dryRun=true) returns findings without mutating. Working on Smart Devices? → resources/read uri=genexus://kb/skills/sd-panel-mobile for Main object semantics. mode=actions manages typed grid actions and Action Groups, persists and re-reads PatternInstance, supports dryRun diff, and never adds security permissions automatically.","inputSchema":{"type":"object","required":["name","pattern"],"properties":{"name":{"type":"string","description":"Target KBObject name."},"pattern":{"type":"string","description":"Pattern key ('WorkWithPlus') or GUID."},"mode":{"type":"string","enum":["apply","diagnose","actions"],"description":"apply (default) mutates; diagnose returns reasons without applying. actions exposes typed WWP action-group editing."},"action":{"type":"string","enum":["list_actions","add_grid_action","update_action","move_action","remove_action"],"description":"mode=actions operation."},"group":{"type":"string","description":"Action group name (e.g. TableActions)."},"actionName":{"type":"string","description":"Name of the action to add, update, or remove."},"newGroup":{"type":"string","description":"move_action: destination action group."},"position":{"type":"integer","minimum":0,"description":"zero-based index among actions in group."},"procedure":{"type":"string","description":"Target Procedure to execute on action click."},"selection":{"type":"string","enum":["current","multiple"],"description":"Execution scope: current (single record) or multiple."},"enabledWhen":{"type":"string","description":"Condition expression for action enablement."},"visibleWhen":{"type":"string","description":"Condition expression for action visibility."},"icon":{"type":"string","description":"Action icon name or class."},"description":{"type":"string","description":"Action tooltip / description text."},"confirmation":{"type":"string","description":"Confirmation message prompt."},"confirmTitle":{"type":"string","description":"Confirmation dialog title."},"settings":{"type":"object","description":"Pattern-instance settings tree."},"reapply":{"type":"boolean","default":false,"description":"Re-run on existing instance."},"validate":{"type":"boolean","default":false,"description":"After apply, build the generated host. Adds validation block (60-180s). Catches binding errors."},"dryRun":{"type":"boolean","default":false,"description":"Alias for mode=diagnose. When true, returns pattern findings without mutating. With mode=actions it previews the typed action diff."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"name":"Customer","pattern":"WorkWithPlus"},{"name":"Customer","pattern":"WorkWithPlus","mode":"diagnose"},{"name":"Customer","pattern":"WorkWithPlus","mode":"actions","action":"add_grid_action","group":"Actions","actionName":"Approve","procedure":"ApproveCustomer","dryRun":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
31
31
  {"name":"genexus_edit_and_build","description":"Edit + rebuild callers in one call. Returns edit diff + impact + a build block that may include taskId/pollTarget for lifecycle follow-up. validate=true/validationMode=specify validates the saved object; rollbackOnFailure restores its pre-write snapshot on specification failure.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Target object name."},"part":{"type":"string","description":"Part (Source, Rules, ...)."},"content":{"type":"string","description":"New content. For mode=patch may be {find,replace} object."},"patch":{"description":"Same shape as genexus_edit.patch. Auto-sets mode=patch."},"mode":{"type":"string","enum":["full","patch"],"default":"patch"},"type":{"type":"string","description":"Disambiguates ambiguous names."},"dryRun":{"type":"boolean","default":false},"validate":{"type":"boolean","default":false},"validationMode":{"type":"string","enum":["specify"],"default":"specify"},"rollbackOnFailure":{"type":"boolean","default":true},"buildIncludeCallees":{"type":"string","enum":["none","direct","transitive"],"default":"direct"},"buildPlanCap":{"type":"integer","default":200},"waitForIndex":{"type":"boolean","default":true},"waitTimeoutMs":{"type":"integer","default":30000},"visualVerify":{"type":"boolean","default":false,"description":"Post-edit headless screenshot + pixel-diff vs baseline. See tool-help."}},"required":["name","part"],"examples":[{"name":"Customer","part":"Source","patch":{"find":"oldValue","replace":"newValue"},"validate":true},{"name":"Customer","part":"Rules","mode":"patch","patch":{"find":"error(","replace":"msg("},"dryRun":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
32
32
  {"name":"genexus_security","description":"Audit KB security. action=audit_gam scans GAM/env props; action=scan_secrets greps Source for credential-shaped literals; action=scan_native drives the native GeneXus Security Scanner (ISecurityScannerService). Returns findings with severity.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["audit_gam","scan_secrets","scan_native"],"description":"audit_gam: scans GAM and environment properties; scan_secrets: greps Source for credentials; scan_native: drives native GeneXus Security Scanner."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"audit_gam"},{"action":"scan_secrets"}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
@@ -48,5 +48,5 @@
48
48
  {"name":"genexus_transfer","description":"Real XPZ export/import over the SDK's IKnowledgeManagerService — dependency-aware, IDE Export/Import parity (NOT the filesystem copy genexus_io/kb_import do). action=export (targets[]+outputFile; includeDependencies=true exports transitive closure) | inspect (explore an .xpz, read-only) | import (apply into KB; dryRun defaults true=preview via ExploreExport; dryRun=false requires confirm=true).","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["export","inspect","import"],"description":"XPZ export, inspection, or import operation to perform."},"targets":{"type":"array","items":{"type":"string"},"description":"export: object names to export."},"outputFile":{"type":"string","description":"export: absolute .xpz output path."},"includeDependencies":{"type":"boolean","description":"export: compute transitive dependency closure (Calls, Tables) and export all referenced objects.","default":false},"file":{"type":"string","description":"inspect/import: absolute .xpz path."},"type":{"type":"string","description":"export: disambiguate object type."},"dryRun":{"type":"boolean","description":"import: true (default) previews; false applies (needs confirm)."},"confirm":{"type":"boolean","description":"import with dryRun=false: required."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"export","targets":["Customer"],"outputFile":"C:\\tmp\\cust.xpz"},{"action":"export","targets":["Customer"],"outputFile":"C:\\tmp\\cust_full.xpz","includeDependencies":true},{"action":"inspect","file":"C:\\tmp\\cust.xpz"}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},
49
49
  {"name":"genexus_deploy","description":"Deploy application over the SDK. action=list_targets (read-only, default) enumerates deployment target types (IDeploymentTargetService); action=deploy (destructive, confirm=true) runs IDeploymentService.Deploy(model).","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["list_targets","deploy"],"description":"Deployment-target or deployment execution operation to perform."},"confirm":{"type":"boolean","description":"deploy: required (builds + ships the app)."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"list_targets"},{"action":"deploy","confirm":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},
50
50
  {"name":"genexus_generator_reference","description":"Native typed .NET generator references used by GxExternalReference. list and dry-run actions are read-only. add/remove validate a managed assembly when a path is supplied, require optimistic baseVersion for changes, save only the native GeneratorsPart, reread it, and restore the complete generator-property snapshot on verification failure. No lifecycle action runs implicitly.","inputSchema":{"type":"object","additionalProperties":false,"required":["action","environment","generator"],"properties":{"action":{"type":"string","enum":["list","dry_run_add","add","dry_run_remove","remove"],"description":"Typed .NET generator-reference operation to perform."},"environment":{"type":"string","description":"Active GeneXus Environment name; the tool never switches environments."},"generator":{"type":"string","description":"Generator display name, e.g. Default (.NET)."},"assembly":{"type":"string","description":"Assembly file name for add/remove, e.g. SpreadsheetLibrary.dll."},"assemblyPath":{"type":"string","description":"Absolute path or KB-relative path used to validate a managed assembly. Required for add unless found in a standard model/bin location."},"baseVersion":{"type":"string","description":"Optimistic token returned by list or a dry-run. Required for a real state change."},"dryRun":{"type":"boolean","default":false,"description":"Force add/remove to remain read-only."},"rollbackOnFailure":{"type":"boolean","default":true,"description":"Restore and verify the complete prior generator-property snapshot if save/reread diverges."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"list","environment":".Net Environment","generator":"Default (.NET)"},{"action":"dry_run_add","environment":".Net Environment","generator":"Default (.NET)","assembly":"SpreadsheetLibrary.dll","assemblyPath":"C:\\KBs\\Sample\\CSharpModel\\web\\bin\\SpreadsheetLibrary.dll"},{"action":"add","environment":".Net Environment","generator":"Default (.NET)","assembly":"SpreadsheetLibrary.dll","assemblyPath":"C:\\KBs\\Sample\\CSharpModel\\web\\bin\\SpreadsheetLibrary.dll","baseVersion":"sha256:<token>","rollbackOnFailure":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true,"openWorldHint":false}},
51
- {"name":"genexus_wwp","description":"WorkWithPlus Action Group / grid-action editing (issue #58). action=list (read-only) lists the PatternInstance's action containers and their <userAction>/<standardAction> children; add_action adds a custom userAction to an existing or new group (procedure existence verified, selection single|multiple, enabledWhen condition, icon, description, confirm, position); update_action changes those attributes; move_action relocates an action between groups or reorders it; remove_action deletes an action (confirm=true). dryRun=true returns the XML diff without persisting. Edits target the WorkWithPlus host's PatternInstance XML (survives pattern reapply). NEVER creates Security/GAM permissions. Attributes are passed verbatim to the WWP XML; the SDK's own save normalization is reported honestly via the pattern write verification.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["list","add_action","update_action","move_action","remove_action"],"description":"WorkWithPlus action-group or grid-action operation to perform."},"name":{"type":"string","description":"Transaction, WebPanel, or WorkWithPlus<Object> host."},"group":{"type":"string","description":"Action group/container name (TableActions row). add_action: creates a new group when absent; update/remove: scope filter."},"actionName":{"type":"string","description":"Action name (e.g. 'Reativar')."},"caption":{"type":"string","description":"add/update: button caption (defaults to actionName)."},"procedure":{"type":"string","description":"add/update: associated Procedure; existence is validated against the KB."},"selection":{"type":"string","enum":["single","multiple"],"description":"add/update: execution scope for grid actions."},"enabledWhen":{"type":"string","description":"add/update: availability condition text (e.g. 'MonitorIntegracaoStatus = DSituacaoProcessamento.Suspenso'). Stored verbatim; expression semantics are not validated."},"icon":{"type":"string","description":"add/update: button icon."},"description":{"type":"string","description":"add/update: tooltip/description."},"confirm":{"type":"boolean","description":"add/update: confirmation prompt; remove_action: required to delete (unless dryRun)."},"buttonClass":{"type":"string","description":"add/update: theme button class (e.g. 'btn ButtonCinza')."},"position":{"type":"integer","description":"add/move/update: zero-based index among the group's actions."},"toGroup":{"type":"string","description":"move_action: destination group (created when absent)."},"fromGroup":{"type":"string","description":"move_action: source group (optional; searched across groups when omitted)."},"dryRun":{"type":"boolean","description":"Return the XML diff without persisting (default false)."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"list","name":"MonitorIntegracaoWW"},{"action":"add_action","name":"MonitorIntegracaoWW","group":"Processamento","actionName":"Reativar","procedure":"MonitorIntegracaoReativar","selection":"multiple","enabledWhen":"MonitorIntegracaoStatus = DSituacaoProcessamento.Suspenso","dryRun":true},{"action":"remove_action","name":"MonitorIntegracaoWW","actionName":"Reativar","confirm":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}}
51
+ {"name":"genexus_wwp","description":"Typed WorkWithPlus action, tab, and grid edits with dryRun, optimistic concurrency, exact snapshots, post-save reread, projection verification, and rollback. No lifecycle operation is implicit.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["list","add_action","update_action","move_action","remove_action","add_tab","move_tab","remove_tab","add_grid_attribute"],"description":"WorkWithPlus action-group, tab, or grid-attribute operation to perform."},"name":{"type":"string","description":"Transaction, WebPanel, or WorkWithPlus<Object> host."},"group":{"type":"string","description":"Action group name. add_action creates it when absent; update/remove use it as a filter."},"actionName":{"type":"string","description":"Action name."},"attribute":{"type":"string","description":"add_grid_attribute: GeneXus Attribute name."},"caption":{"type":"string","description":"Action or grid-column caption."},"procedure":{"type":"string","description":"add/update: associated Procedure; existence is validated against the KB."},"selection":{"type":"string","enum":["single","multiple"],"description":"add/update: execution scope for grid actions."},"enabledWhen":{"type":"string","description":"Availability condition stored verbatim; expression semantics are not validated."},"icon":{"type":"string","description":"add/update: button icon."},"description":{"type":"string","description":"add/update: tooltip or description."},"confirm":{"type":"boolean","description":"Confirmation prompt; required to delete unless dryRun."},"buttonClass":{"type":"string","description":"add/update: theme button class."},"position":{"type":"integer","minimum":0,"description":"Zero-based action or tab index."},"toGroup":{"type":"string","description":"move_action: destination group (created when absent)."},"fromGroup":{"type":"string","description":"move_action: source group (optional; searched across groups when omitted)."},"dryRun":{"type":"boolean","description":"Return a typed diff and versionToken without mutation."},"controlName":{"type":"string","description":"Tab ControlName."},"title":{"type":"string","description":"add_tab: tab title."},"children":{"type":"array","description":"add_tab controls; flat children are wrapped in a responsive table.","items":{"$ref":"#/$defs/wwpControl"}},"baseVersion":{"type":"string","description":"Optimistic-concurrency token returned by dryRun/read."},"expectedVersion":{"type":"string","description":"Alias for baseVersion."},"versionToken":{"type":"string","description":"Backward-compatible alias for baseVersion."},"kb":{"type":"string","description":"KB alias."}},"$defs":{"wwpControl":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["variable","userAction","table"]},"name":{"type":"string"},"caption":{"type":"string"},"description":{"type":"string"},"basicType":{"type":"string"},"length":{"type":"integer","minimum":1},"decimals":{"type":"integer","minimum":0},"controlType":{"type":"string"},"controlValues":{"type":"string"},"controlEmptyItem":{"type":"boolean"},"controlEmptyItemText":{"type":"string"},"columns":{"type":"integer","minimum":1},"themeClass":{"type":"string"},"children":{"type":"array","items":{"$ref":"#/$defs/wwpControl"}}},"additionalProperties":false}},"examples":[{"action":"list","name":"SampleOrderWW"},{"action":"add_action","name":"SampleOrderWW","group":"Operations","actionName":"Retry","procedure":"RetrySampleOrder","selection":"multiple","dryRun":true},{"action":"add_tab","name":"SamplePanel","controlName":"Details","title":"Details","children":[{"type":"variable","name":"Status","basicType":"VarChar","length":40},{"type":"userAction","name":"Refresh","caption":"Refresh"}],"dryRun":true},{"action":"add_grid_attribute","name":"SampleOrderWW","attribute":"SampleOrderStatus","caption":"Status","dryRun":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}}
52
52
  ]
Binary file