@linkup-ai/abap-ai 2.2.1 → 2.2.4
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/cli/activate.js +2 -1
- package/dist/cli/init.js +88 -14
- package/dist/cli/remove.js +3 -2
- package/dist/cli/status.js +5 -3
- package/dist/cli/systems.js +3 -2
- package/dist/cli.js +2 -1
- package/dist/postinstall.js +88 -0
- package/package.json +3 -2
package/dist/cli/activate.js
CHANGED
|
@@ -37,8 +37,9 @@ exports.readLicense = readLicense;
|
|
|
37
37
|
exports.activate = activate;
|
|
38
38
|
const crypto = __importStar(require("crypto"));
|
|
39
39
|
const fs = __importStar(require("fs"));
|
|
40
|
+
const os = __importStar(require("os"));
|
|
40
41
|
const path = __importStar(require("path"));
|
|
41
|
-
const LICENSE_DIR = path.join(
|
|
42
|
+
const LICENSE_DIR = path.join(os.homedir(), ".abap-ai");
|
|
42
43
|
const LICENSE_PATH = path.join(LICENSE_DIR, "license.json");
|
|
43
44
|
// ── Beta key validation (offline, HMAC-based) ───────────────────────
|
|
44
45
|
// Em produção será substituído por fetch ao license server (api.lkpabap.ai)
|
package/dist/cli/init.js
CHANGED
|
@@ -39,11 +39,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.init = init;
|
|
40
40
|
const prompts_1 = __importDefault(require("prompts"));
|
|
41
41
|
const fs = __importStar(require("fs"));
|
|
42
|
+
const os = __importStar(require("os"));
|
|
42
43
|
const path = __importStar(require("path"));
|
|
43
44
|
const https = __importStar(require("https"));
|
|
44
45
|
const http = __importStar(require("http"));
|
|
45
|
-
const GLOBAL_MCP_PATH = path.join(
|
|
46
|
-
const LOCAL_MCP_PATH = path.join(process.cwd(), ".
|
|
46
|
+
const GLOBAL_MCP_PATH = path.join(os.homedir(), ".claude", "mcp.json");
|
|
47
|
+
const LOCAL_MCP_PATH = path.join(process.cwd(), ".mcp.json"); // VS Code lê .mcp.json na raiz do workspace
|
|
47
48
|
function getMcpPath(local) {
|
|
48
49
|
return local ? LOCAL_MCP_PATH : GLOBAL_MCP_PATH;
|
|
49
50
|
}
|
|
@@ -136,13 +137,8 @@ function writeMcpConfig(config, mcpPath) {
|
|
|
136
137
|
fs.writeFileSync(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
137
138
|
}
|
|
138
139
|
function detectServerPath() {
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
if (fs.existsSync(fromCli))
|
|
142
|
-
return fromCli;
|
|
143
|
-
// Fallback: path global do pacote
|
|
144
|
-
const globalPath = path.resolve(__dirname, "..", "index.js");
|
|
145
|
-
return globalPath;
|
|
140
|
+
// cli.js e index.js ficam ambos em dist/ após o build
|
|
141
|
+
return path.resolve(__dirname, "index.js");
|
|
146
142
|
}
|
|
147
143
|
function addSystemToConfig(config, system) {
|
|
148
144
|
const serverName = `abap-${system.name}`;
|
|
@@ -159,12 +155,72 @@ function addSystemToConfig(config, system) {
|
|
|
159
155
|
env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
160
156
|
}
|
|
161
157
|
config.mcpServers[serverName] = {
|
|
162
|
-
command:
|
|
158
|
+
command: process.execPath,
|
|
163
159
|
args: [serverPath],
|
|
164
160
|
env,
|
|
165
161
|
};
|
|
166
162
|
}
|
|
167
163
|
// ---------------------------------------------------------------------------
|
|
164
|
+
// CLAUDE.md — contexto para o Claude Code
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
function buildClaudeMdSection(config) {
|
|
167
|
+
const sapServers = Object.entries(config.mcpServers).filter(([k]) => k.startsWith("abap-"));
|
|
168
|
+
if (sapServers.length === 0)
|
|
169
|
+
return "";
|
|
170
|
+
const lines = [
|
|
171
|
+
"## LKPABAP.ai — Sistemas SAP configurados",
|
|
172
|
+
"",
|
|
173
|
+
"Este projeto tem o MCP `@linkup-ai/abap-ai` ativo. Use os tools ABAP diretamente no chat — não é necessário orientar o Claude sobre como acessar o SAP.",
|
|
174
|
+
"",
|
|
175
|
+
"### Sistemas disponíveis",
|
|
176
|
+
"",
|
|
177
|
+
];
|
|
178
|
+
for (const [name, server] of sapServers) {
|
|
179
|
+
const env = server.env || {};
|
|
180
|
+
const url = env.SAP_URL || "?";
|
|
181
|
+
const client = env.SAP_CLIENT || "?";
|
|
182
|
+
const role = env.ABAP_AI_ENV_ROLE || "DEVELOPMENT";
|
|
183
|
+
const roleLabel = role === "PRODUCTION" ? "PRD — somente leitura"
|
|
184
|
+
: role === "QUALITY" ? "QAS — somente leitura"
|
|
185
|
+
: "DEV — leitura, escrita e criação permitidas";
|
|
186
|
+
lines.push(`- **${name}** — \`${url}\` (client ${client}) — ${roleLabel}`);
|
|
187
|
+
}
|
|
188
|
+
lines.push("", "### Exemplos de uso", "");
|
|
189
|
+
lines.push('- "Leia a classe ZCL_PEDIDO no sistema abap-dev"');
|
|
190
|
+
lines.push('- "Crie um report YTESTE sem request de transporte"');
|
|
191
|
+
lines.push('- "Busque onde a FM BAPI_SALESORDER_CREATEFROMDAT2 é usada"');
|
|
192
|
+
lines.push('- "Rode o ATC no pacote ZVENDAS e corrija os erros"');
|
|
193
|
+
lines.push("");
|
|
194
|
+
return lines.join("\n");
|
|
195
|
+
}
|
|
196
|
+
const CLAUDE_MD_MARKER_START = "<!-- lkpabap:start -->";
|
|
197
|
+
const CLAUDE_MD_MARKER_END = "<!-- lkpabap:end -->";
|
|
198
|
+
function updateClaudeMd(claudeMdPath, config) {
|
|
199
|
+
const section = buildClaudeMdSection(config);
|
|
200
|
+
if (!section)
|
|
201
|
+
return;
|
|
202
|
+
const block = `${CLAUDE_MD_MARKER_START}\n${section}${CLAUDE_MD_MARKER_END}\n`;
|
|
203
|
+
let existing = "";
|
|
204
|
+
try {
|
|
205
|
+
existing = fs.readFileSync(claudeMdPath, "utf-8");
|
|
206
|
+
}
|
|
207
|
+
catch { /* novo arquivo */ }
|
|
208
|
+
let updated;
|
|
209
|
+
if (existing.includes(CLAUDE_MD_MARKER_START)) {
|
|
210
|
+
// Atualiza bloco existente
|
|
211
|
+
const re = new RegExp(`${CLAUDE_MD_MARKER_START}[\\s\\S]*?${CLAUDE_MD_MARKER_END}\\n?`, "g");
|
|
212
|
+
updated = existing.replace(re, block);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
// Acrescenta ao final
|
|
216
|
+
updated = existing ? `${existing.trimEnd()}\n\n${block}` : block;
|
|
217
|
+
}
|
|
218
|
+
const dir = path.dirname(claudeMdPath);
|
|
219
|
+
if (!fs.existsSync(dir))
|
|
220
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
221
|
+
fs.writeFileSync(claudeMdPath, updated, "utf-8");
|
|
222
|
+
}
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
168
224
|
// Wizard
|
|
169
225
|
// ---------------------------------------------------------------------------
|
|
170
226
|
async function promptSystem() {
|
|
@@ -256,14 +312,16 @@ async function promptSystem() {
|
|
|
256
312
|
async function init(options = {}) {
|
|
257
313
|
const local = options.local ?? false;
|
|
258
314
|
const mcpPath = getMcpPath(local);
|
|
259
|
-
const
|
|
315
|
+
const scopeLabel = local
|
|
316
|
+
? `projeto → ${mcpPath}`
|
|
317
|
+
: `global → ${mcpPath}`;
|
|
260
318
|
console.log(`
|
|
261
319
|
╭─────────────────────────────────────╮
|
|
262
320
|
│ LKPABAP.ai — Setup │
|
|
263
321
|
│ Conecte o Claude ao seu SAP │
|
|
264
322
|
╰─────────────────────────────────────╯
|
|
265
323
|
|
|
266
|
-
Escopo: ${
|
|
324
|
+
Escopo: ${scopeLabel}
|
|
267
325
|
`);
|
|
268
326
|
const config = readMcpConfig(mcpPath);
|
|
269
327
|
const existingCount = Object.keys(config.mcpServers).filter((k) => k.startsWith("abap-")).length;
|
|
@@ -330,6 +388,11 @@ async function init(options = {}) {
|
|
|
330
388
|
}
|
|
331
389
|
if (addedSystems.length > 0) {
|
|
332
390
|
writeMcpConfig(config, mcpPath);
|
|
391
|
+
// Gera/atualiza CLAUDE.md com contexto sobre os sistemas SAP
|
|
392
|
+
const claudeMdPath = local
|
|
393
|
+
? path.join(process.cwd(), "CLAUDE.md")
|
|
394
|
+
: path.join(os.homedir(), ".claude", "CLAUDE.md");
|
|
395
|
+
updateClaudeMd(claudeMdPath, config);
|
|
333
396
|
const total = Object.keys(config.mcpServers).filter((k) => k.startsWith("abap-")).length;
|
|
334
397
|
console.log(`
|
|
335
398
|
✓ Configuração salva em ${mcpPath}
|
|
@@ -345,11 +408,22 @@ async function init(options = {}) {
|
|
|
345
408
|
const line = ` │ • ${name} (client ${client}, ${roleTag})`;
|
|
346
409
|
console.log(`${line}${" ".repeat(Math.max(1, 48 - line.length))}│`);
|
|
347
410
|
}
|
|
348
|
-
|
|
411
|
+
if (local) {
|
|
412
|
+
console.log(` │${" ".repeat(46)}│
|
|
413
|
+
│ Próximo passo no VS Code:${" ".repeat(19)}│
|
|
414
|
+
│ 1. Ctrl+Shift+P → "Reload Window"${" ".repeat(8)}│
|
|
415
|
+
│ 2. Clique "Allow" no aviso do MCP${" ".repeat(8)}│
|
|
416
|
+
│ 3. Converse com o Claude Code!${" ".repeat(11)}│
|
|
417
|
+
╰──────────────────────────────────────────────╯
|
|
418
|
+
`);
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
console.log(` │${" ".repeat(46)}│
|
|
349
422
|
│ Próximo passo:${" ".repeat(29)}│
|
|
350
|
-
│ Abra o
|
|
423
|
+
│ Abra o Claude Code e use!${" ".repeat(16)}│
|
|
351
424
|
╰──────────────────────────────────────────────╯
|
|
352
425
|
`);
|
|
426
|
+
}
|
|
353
427
|
}
|
|
354
428
|
else {
|
|
355
429
|
console.log("\n Nenhum sistema adicionado.\n");
|
package/dist/cli/remove.js
CHANGED
|
@@ -39,9 +39,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.remove = remove;
|
|
40
40
|
const prompts_1 = __importDefault(require("prompts"));
|
|
41
41
|
const fs = __importStar(require("fs"));
|
|
42
|
+
const os = __importStar(require("os"));
|
|
42
43
|
const path = __importStar(require("path"));
|
|
43
|
-
const GLOBAL_MCP_PATH = path.join(
|
|
44
|
-
const LOCAL_MCP_PATH = path.join(process.cwd(), ".
|
|
44
|
+
const GLOBAL_MCP_PATH = path.join(os.homedir(), ".claude", "mcp.json");
|
|
45
|
+
const LOCAL_MCP_PATH = path.join(process.cwd(), ".mcp.json");
|
|
45
46
|
async function remove(name, options = {}) {
|
|
46
47
|
const serverName = name.startsWith("abap-") ? name : `abap-${name}`;
|
|
47
48
|
const mcpPath = options.local ? LOCAL_MCP_PATH : GLOBAL_MCP_PATH;
|
package/dist/cli/status.js
CHANGED
|
@@ -35,13 +35,15 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.status = status;
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
|
+
const os = __importStar(require("os"));
|
|
38
39
|
const path = __importStar(require("path"));
|
|
39
40
|
const https = __importStar(require("https"));
|
|
40
41
|
const http = __importStar(require("http"));
|
|
41
42
|
const activate_js_1 = require("./activate.js");
|
|
42
|
-
const MCP_JSON_PATH = path.join(
|
|
43
|
-
const LOG_DIR = path.join(
|
|
44
|
-
|
|
43
|
+
const MCP_JSON_PATH = path.join(os.homedir(), ".claude", "mcp.json");
|
|
44
|
+
const LOG_DIR = path.join(os.homedir(), ".abap-ai", "logs");
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
46
|
+
const VERSION = require("../../package.json").version;
|
|
45
47
|
// ---------------------------------------------------------------------------
|
|
46
48
|
// Teste rápido de conexão (timeout 5s)
|
|
47
49
|
// ---------------------------------------------------------------------------
|
package/dist/cli/systems.js
CHANGED
|
@@ -35,9 +35,10 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.systems = systems;
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
|
+
const os = __importStar(require("os"));
|
|
38
39
|
const path = __importStar(require("path"));
|
|
39
|
-
const GLOBAL_MCP_PATH = path.join(
|
|
40
|
-
const LOCAL_MCP_PATH = path.join(process.cwd(), ".
|
|
40
|
+
const GLOBAL_MCP_PATH = path.join(os.homedir(), ".claude", "mcp.json");
|
|
41
|
+
const LOCAL_MCP_PATH = path.join(process.cwd(), ".mcp.json");
|
|
41
42
|
async function systems(options = {}) {
|
|
42
43
|
const mcpPath = options.local ? LOCAL_MCP_PATH : GLOBAL_MCP_PATH;
|
|
43
44
|
let config;
|
package/dist/cli.js
CHANGED
|
@@ -6,7 +6,8 @@ const activate_js_1 = require("./cli/activate.js");
|
|
|
6
6
|
const status_js_1 = require("./cli/status.js");
|
|
7
7
|
const remove_js_1 = require("./cli/remove.js");
|
|
8
8
|
const systems_js_1 = require("./cli/systems.js");
|
|
9
|
-
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
10
|
+
const VERSION = require("../package.json").version;
|
|
10
11
|
const HELP = `
|
|
11
12
|
LKPABAP.ai — AI-powered ABAP development for SAP
|
|
12
13
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const os = __importStar(require("os"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const child_process_1 = require("child_process");
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
42
|
+
const VERSION = require("../package.json").version;
|
|
43
|
+
function checkNode() {
|
|
44
|
+
const version = process.version; // e.g. "v20.11.0"
|
|
45
|
+
const major = parseInt(version.slice(1).split(".")[0], 10);
|
|
46
|
+
return { ok: major >= 18, version };
|
|
47
|
+
}
|
|
48
|
+
function checkClaudeCode() {
|
|
49
|
+
// Verifica se o Claude Code CLI está instalado
|
|
50
|
+
try {
|
|
51
|
+
(0, child_process_1.execSync)("claude --version", { stdio: "pipe" });
|
|
52
|
+
return { ok: true, detail: "encontrado" };
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Verifica se a pasta ~/.claude existe (extensão VS Code cria ela)
|
|
56
|
+
const claudeDir = path.join(os.homedir(), ".claude");
|
|
57
|
+
if (fs.existsSync(claudeDir)) {
|
|
58
|
+
return { ok: true, detail: "pasta ~/.claude encontrada (VS Code extension)" };
|
|
59
|
+
}
|
|
60
|
+
return { ok: false, detail: "não encontrado" };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function main() {
|
|
64
|
+
const node = checkNode();
|
|
65
|
+
const claude = checkClaudeCode();
|
|
66
|
+
const nodeIcon = node.ok ? "✓" : "✗";
|
|
67
|
+
const claudeIcon = claude.ok ? "✓" : "⚠";
|
|
68
|
+
const title = ` LKPABAP.ai v${VERSION} instalado!`;
|
|
69
|
+
console.log(`
|
|
70
|
+
╭──────────────────────────────────────────────╮
|
|
71
|
+
│${title}${" ".repeat(Math.max(1, 47 - title.length))}│
|
|
72
|
+
╰──────────────────────────────────────────────╯
|
|
73
|
+
|
|
74
|
+
Pré-requisitos:
|
|
75
|
+
${nodeIcon} Node.js ${node.version}${node.ok ? "" : " ← precisa de v18+"}
|
|
76
|
+
${claudeIcon} Claude Code: ${claude.detail}${claude.ok ? "" : "\n → Instale em: https://claude.ai/download"}
|
|
77
|
+
|
|
78
|
+
Próximos passos:
|
|
79
|
+
1. abap-ai activate LK-XXXX-XXXX-XXXX ← ative sua licença
|
|
80
|
+
2. cd <pasta-do-projeto>
|
|
81
|
+
abap-ai init --local ← configure o sistema SAP
|
|
82
|
+
3. Abra o VS Code nesta pasta e use!
|
|
83
|
+
`);
|
|
84
|
+
if (!node.ok) {
|
|
85
|
+
console.error(" AVISO: Node.js 18+ é obrigatório. Versão atual: " + node.version + "\n");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linkup-ai/abap-ai",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.4",
|
|
4
4
|
"description": "LKPABAP.ai — AI-powered ABAP development tools for SAP S/4HANA via ADT REST API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"build": "tsc && rm -rf dist/knowledge && cp -r src/knowledge dist/knowledge",
|
|
32
32
|
"start": "node dist/index.js",
|
|
33
33
|
"dev": "tsc --watch",
|
|
34
|
-
"prepublishOnly": "npm run build"
|
|
34
|
+
"prepublishOnly": "npm run build",
|
|
35
|
+
"postinstall": "node dist/postinstall.js || true"
|
|
35
36
|
},
|
|
36
37
|
"dependencies": {
|
|
37
38
|
"@modelcontextprotocol/sdk": "^1.0.0",
|