@linkup-ai/abap-ai 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +389 -0
  2. package/dist/adt-client.js +383 -0
  3. package/dist/cli/activate.js +127 -0
  4. package/dist/cli/init.js +559 -0
  5. package/dist/cli/link.js +148 -0
  6. package/dist/cli/remove.js +83 -0
  7. package/dist/cli/status.js +231 -0
  8. package/dist/cli/systems.js +72 -0
  9. package/dist/cli.js +92 -0
  10. package/dist/index.js +1442 -0
  11. package/dist/knowledge/abap/abap-dictionary.md +199 -0
  12. package/dist/knowledge/abap/abap-sql.md +296 -0
  13. package/dist/knowledge/abap/amdp.md +273 -0
  14. package/dist/knowledge/abap/clean-code.md +293 -0
  15. package/dist/knowledge/abap/cloud-background-processing.md +250 -0
  16. package/dist/knowledge/abap/cloud-communication.md +265 -0
  17. package/dist/knowledge/abap/cloud-development.md +176 -0
  18. package/dist/knowledge/abap/cloud-extensibility.md +252 -0
  19. package/dist/knowledge/abap/cloud-released-apis.md +261 -0
  20. package/dist/knowledge/abap/constructor-expressions.md +289 -0
  21. package/dist/knowledge/abap/enhancements.md +232 -0
  22. package/dist/knowledge/abap/exceptions.md +271 -0
  23. package/dist/knowledge/abap/internal-tables.md +205 -0
  24. package/dist/knowledge/abap/object-orientation.md +298 -0
  25. package/dist/knowledge/abap/performance.md +216 -0
  26. package/dist/knowledge/abap/rap-abstract-entities.md +206 -0
  27. package/dist/knowledge/abap/rap-business-events.md +216 -0
  28. package/dist/knowledge/abap/rap-draft.md +191 -0
  29. package/dist/knowledge/abap/rap-eml.md +453 -0
  30. package/dist/knowledge/abap/rap-end-to-end.md +486 -0
  31. package/dist/knowledge/abap/rap-feature-control.md +185 -0
  32. package/dist/knowledge/abap/rap-numbering.md +280 -0
  33. package/dist/knowledge/abap/rap-service-exposure.md +163 -0
  34. package/dist/knowledge/abap/rap-unmanaged.md +468 -0
  35. package/dist/knowledge/abap/string-processing.md +180 -0
  36. package/dist/knowledge/abap/unit-testing.md +303 -0
  37. package/dist/knowledge/abap-cds/access-control.md +241 -0
  38. package/dist/knowledge/abap-cds/annotations.md +331 -0
  39. package/dist/knowledge/abap-cds/associations.md +254 -0
  40. package/dist/knowledge/abap-cds/expressions.md +230 -0
  41. package/dist/knowledge/abap-cds/functions.md +245 -0
  42. package/dist/knowledge/abap-cds/metadata-extensions.md +294 -0
  43. package/dist/knowledge/cap/authentication.md +278 -0
  44. package/dist/knowledge/cap/cdl-syntax.md +247 -0
  45. package/dist/knowledge/cap/cql-queries.md +266 -0
  46. package/dist/knowledge/cap/deployment.md +343 -0
  47. package/dist/knowledge/cap/event-handlers.md +287 -0
  48. package/dist/knowledge/cap/fiori-integration.md +303 -0
  49. package/dist/knowledge/cap/service-definitions.md +287 -0
  50. package/dist/knowledge/fiori/annotations.md +347 -0
  51. package/dist/knowledge/fiori/deployment.md +340 -0
  52. package/dist/knowledge/fiori/fiori-elements.md +332 -0
  53. package/dist/knowledge/fiori/fiori-side-effects.md +107 -0
  54. package/dist/knowledge/fiori/fiori-valuelist.md +144 -0
  55. package/dist/knowledge/fiori/ui5-controllers.md +358 -0
  56. package/dist/knowledge/fiori/ui5-data-binding.md +311 -0
  57. package/dist/knowledge/fiori/ui5-fragments-dialogs.md +330 -0
  58. package/dist/knowledge/fiori/ui5-manifest.md +411 -0
  59. package/dist/knowledge/fiori/ui5-routing.md +303 -0
  60. package/dist/knowledge/fiori/ui5-xml-views.md +294 -0
  61. package/dist/license-guard.js +81 -0
  62. package/dist/logger.js +114 -0
  63. package/dist/postinstall.js +165 -0
  64. package/dist/security-audit.js +136 -0
  65. package/dist/security-policy.js +322 -0
  66. package/dist/system-profile.js +207 -0
  67. package/dist/tools/abap-doc.js +72 -0
  68. package/dist/tools/abapgit.js +161 -0
  69. package/dist/tools/activate.js +71 -0
  70. package/dist/tools/atc-check.js +117 -0
  71. package/dist/tools/auth-object.js +56 -0
  72. package/dist/tools/breakpoints.js +76 -0
  73. package/dist/tools/call-hierarchy.js +84 -0
  74. package/dist/tools/cds-annotations.js +98 -0
  75. package/dist/tools/cds-dependencies.js +65 -0
  76. package/dist/tools/check.js +47 -0
  77. package/dist/tools/code-completion.js +70 -0
  78. package/dist/tools/code-coverage.js +111 -0
  79. package/dist/tools/create-amdp.js +111 -0
  80. package/dist/tools/create-dcl.js +81 -0
  81. package/dist/tools/create-transport.js +38 -0
  82. package/dist/tools/create.js +285 -0
  83. package/dist/tools/data-preview.js +37 -0
  84. package/dist/tools/delete.js +45 -0
  85. package/dist/tools/deploy-bsp.js +298 -0
  86. package/dist/tools/discovery.js +59 -0
  87. package/dist/tools/element-info.js +93 -0
  88. package/dist/tools/enhancements.js +186 -0
  89. package/dist/tools/extract-method.js +44 -0
  90. package/dist/tools/function-group.js +59 -0
  91. package/dist/tools/knowledge.js +275 -0
  92. package/dist/tools/lock-object.js +75 -0
  93. package/dist/tools/message-class.js +67 -0
  94. package/dist/tools/navigate.js +80 -0
  95. package/dist/tools/number-range.js +57 -0
  96. package/dist/tools/object-documentation.js +43 -0
  97. package/dist/tools/object-structure.js +78 -0
  98. package/dist/tools/object-versions.js +57 -0
  99. package/dist/tools/package-contents.js +60 -0
  100. package/dist/tools/pretty-printer.js +35 -0
  101. package/dist/tools/publish-binding.js +49 -0
  102. package/dist/tools/quick-fix.js +69 -0
  103. package/dist/tools/read.js +172 -0
  104. package/dist/tools/refactor-rename.js +60 -0
  105. package/dist/tools/release-transport.js +24 -0
  106. package/dist/tools/released-apis.js +51 -0
  107. package/dist/tools/repository-tree.js +90 -0
  108. package/dist/tools/scaffold-rap.js +642 -0
  109. package/dist/tools/search.js +73 -0
  110. package/dist/tools/shared/data-format.js +101 -0
  111. package/dist/tools/sql-console.js +17 -0
  112. package/dist/tools/system-info.js +271 -0
  113. package/dist/tools/traces.js +66 -0
  114. package/dist/tools/transport-contents.js +83 -0
  115. package/dist/tools/transports.js +68 -0
  116. package/dist/tools/unit-test.js +135 -0
  117. package/dist/tools/where-used.js +59 -0
  118. package/dist/tools/write.js +120 -0
  119. package/package.json +50 -0
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.link = link;
40
+ const prompts_1 = __importDefault(require("prompts"));
41
+ const path = __importStar(require("path"));
42
+ const init_js_1 = require("./init.js");
43
+ const LOCAL_MCP_PATH = path.join(process.cwd(), ".mcp.json");
44
+ async function link() {
45
+ console.log(`
46
+ ╭─────────────────────────────────────╮
47
+ │ LKPABAP.ai — Link Workspace │
48
+ │ Conecta este projeto ao SAP │
49
+ ╰─────────────────────────────────────╯
50
+
51
+ Workspace: ${process.cwd()}
52
+ `);
53
+ // Lê config global
54
+ const globalConfig = (0, init_js_1.readMcpConfig)(init_js_1.GLOBAL_MCP_PATH);
55
+ const sapEntries = Object.entries(globalConfig.mcpServers).filter(([k]) => k.startsWith("abap-"));
56
+ if (sapEntries.length === 0) {
57
+ console.log(" ✗ Nenhum sistema SAP encontrado na configuração global.\n" +
58
+ " Execute primeiro: abap-ai init\n");
59
+ return;
60
+ }
61
+ // Monta opções para seleção
62
+ const choices = sapEntries.map(([name, server]) => {
63
+ const env = server.env || {};
64
+ const url = env.SAP_URL || "?";
65
+ const client = env.SAP_CLIENT || "?";
66
+ const role = env.ABAP_AI_ENV_ROLE || "DEVELOPMENT";
67
+ const tag = role === "PRODUCTION" ? "PRD" : role === "QUALITY" ? "QAS" : "DEV";
68
+ return {
69
+ title: `${name} (${url}, client ${client}, ${tag})`,
70
+ value: name,
71
+ selected: true,
72
+ };
73
+ });
74
+ const { selected } = await (0, prompts_1.default)({
75
+ type: "multiselect",
76
+ name: "selected",
77
+ message: "Selecione os sistemas SAP para este workspace",
78
+ choices,
79
+ hint: "Espaço para marcar/desmarcar, Enter para confirmar",
80
+ min: 1,
81
+ }, {
82
+ onCancel: () => {
83
+ console.log("\n Cancelado.\n");
84
+ process.exit(0);
85
+ },
86
+ });
87
+ if (!selected || selected.length === 0) {
88
+ console.log("\n Nenhum sistema selecionado.\n");
89
+ return;
90
+ }
91
+ // Monta config local apenas com os sistemas escolhidos
92
+ const localConfig = { mcpServers: {} };
93
+ for (const name of selected) {
94
+ localConfig.mcpServers[name] = globalConfig.mcpServers[name];
95
+ }
96
+ // Verifica se já existe .mcp.json local e avisa sobre merge
97
+ const existingLocal = (0, init_js_1.readMcpConfig)(LOCAL_MCP_PATH);
98
+ const existingAbap = Object.keys(existingLocal.mcpServers).filter((k) => k.startsWith("abap-"));
99
+ if (existingAbap.length > 0) {
100
+ const { overwrite } = await (0, prompts_1.default)({
101
+ type: "confirm",
102
+ name: "overwrite",
103
+ message: `Este workspace já tem ${existingAbap.length} sistema(s) configurado(s). Substituir?`,
104
+ initial: false,
105
+ });
106
+ if (!overwrite) {
107
+ console.log("\n Operação cancelada. Configuração local mantida.\n");
108
+ return;
109
+ }
110
+ // Preserva servidores não-abap que existam no .mcp.json local
111
+ for (const [k, v] of Object.entries(existingLocal.mcpServers)) {
112
+ if (!k.startsWith("abap-")) {
113
+ localConfig.mcpServers[k] = v;
114
+ }
115
+ }
116
+ }
117
+ // Grava os 3 arquivos locais
118
+ (0, init_js_1.writeMcpConfig)(localConfig, LOCAL_MCP_PATH);
119
+ const claudeMdPath = path.join(process.cwd(), "CLAUDE.md");
120
+ (0, init_js_1.updateClaudeMd)(claudeMdPath, localConfig);
121
+ (0, init_js_1.writeClaudeSettings)(process.cwd());
122
+ // Relatório final
123
+ console.log(`
124
+ ✓ Workspace configurado!
125
+
126
+ ╭──────────────────────────────────────────────╮
127
+ │ Arquivos criados/atualizados: │`);
128
+ console.log(` │ • .mcp.json (servidores MCP) │`);
129
+ console.log(` │ • CLAUDE.md (contexto + políticas)│`);
130
+ console.log(` │ • .claude/settings.json (hooks segurança) │`);
131
+ console.log(` │ │`);
132
+ console.log(` │ ${selected.length} sistema(s) vinculado(s):${" ".repeat(Math.max(0, 24 - selected.length.toString().length))}│`);
133
+ for (const name of selected) {
134
+ const env = localConfig.mcpServers[name]?.env || {};
135
+ const client = env.SAP_CLIENT || "?";
136
+ const role = env.ABAP_AI_ENV_ROLE || "DEVELOPMENT";
137
+ const tag = role === "PRODUCTION" ? "PRD" : role === "QUALITY" ? "QAS" : "DEV";
138
+ const line = ` │ • ${name} (client ${client}, ${tag})`;
139
+ console.log(`${line}${" ".repeat(Math.max(1, 48 - line.length))}│`);
140
+ }
141
+ console.log(` │ │
142
+ │ Próximo passo no VS Code: │
143
+ │ 1. Ctrl+Shift+P → "Reload Window" │
144
+ │ 2. Clique "Allow" no aviso do MCP │
145
+ │ 3. Converse com o Claude Code! │
146
+ ╰──────────────────────────────────────────────╯
147
+ `);
148
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.remove = remove;
40
+ const prompts_1 = __importDefault(require("prompts"));
41
+ const fs = __importStar(require("fs"));
42
+ const os = __importStar(require("os"));
43
+ const path = __importStar(require("path"));
44
+ const GLOBAL_MCP_PATH = path.join(os.homedir(), ".claude", "mcp.json");
45
+ const LOCAL_MCP_PATH = path.join(process.cwd(), ".mcp.json");
46
+ async function remove(name, options = {}) {
47
+ const serverName = name.startsWith("abap-") ? name : `abap-${name}`;
48
+ const mcpPath = options.local ? LOCAL_MCP_PATH : GLOBAL_MCP_PATH;
49
+ let config;
50
+ try {
51
+ const raw = fs.readFileSync(mcpPath, "utf-8");
52
+ config = JSON.parse(raw);
53
+ }
54
+ catch {
55
+ console.error(` ✗ Arquivo ${mcpPath} não encontrado.`);
56
+ process.exit(1);
57
+ return;
58
+ }
59
+ if (!config.mcpServers[serverName]) {
60
+ console.error(` ✗ Sistema "${serverName}" não encontrado no mcp.json.`);
61
+ const available = Object.keys(config.mcpServers).filter((k) => k.startsWith("abap-"));
62
+ if (available.length > 0) {
63
+ console.log(` Sistemas disponíveis: ${available.join(", ")}`);
64
+ }
65
+ process.exit(1);
66
+ return;
67
+ }
68
+ const { confirm } = await (0, prompts_1.default)({
69
+ type: "confirm",
70
+ name: "confirm",
71
+ message: `Confirma remoção do sistema "${serverName}"?`,
72
+ initial: false,
73
+ });
74
+ if (!confirm) {
75
+ console.log(" Cancelado.\n");
76
+ return;
77
+ }
78
+ delete config.mcpServers[serverName];
79
+ fs.writeFileSync(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
80
+ const remaining = Object.keys(config.mcpServers).filter((k) => k.startsWith("abap-")).length;
81
+ console.log(`\n ✓ Sistema "${serverName}" removido de ${mcpPath}`);
82
+ console.log(` ${remaining} sistema(s) restante(s).\n`);
83
+ }
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.status = status;
37
+ const fs = __importStar(require("fs"));
38
+ const os = __importStar(require("os"));
39
+ const path = __importStar(require("path"));
40
+ const https = __importStar(require("https"));
41
+ const http = __importStar(require("http"));
42
+ const activate_js_1 = require("./activate.js");
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;
47
+ // ---------------------------------------------------------------------------
48
+ // Teste rápido de conexão (timeout 5s)
49
+ // ---------------------------------------------------------------------------
50
+ async function quickTest(url, user, pass, client, selfSigned) {
51
+ const parsed = new URL(`${url}/sap/bc/adt/discovery`);
52
+ return new Promise((resolve) => {
53
+ const transport = parsed.protocol === "https:" ? https : http;
54
+ const req = transport.request({
55
+ hostname: parsed.hostname,
56
+ port: parsed.port || (parsed.protocol === "https:" ? 443 : 80),
57
+ path: parsed.pathname,
58
+ method: "GET",
59
+ headers: {
60
+ Authorization: "Basic " + Buffer.from(`${user}:${pass}`).toString("base64"),
61
+ "sap-client": client,
62
+ Accept: "application/atomsvc+xml",
63
+ },
64
+ rejectUnauthorized: !selfSigned,
65
+ timeout: 5000,
66
+ }, (res) => {
67
+ let body = "";
68
+ res.on("data", (chunk) => (body += chunk));
69
+ res.on("end", () => {
70
+ if (res.statusCode === 200) {
71
+ // Extrair info básica
72
+ const versionMatch = body.match(/release="(\d+)"/i);
73
+ const version = versionMatch ? `BASIS ${versionMatch[1]}` : "";
74
+ resolve({ ok: true, info: version || "OK" });
75
+ }
76
+ else {
77
+ resolve({ ok: false, info: `HTTP ${res.statusCode}` });
78
+ }
79
+ });
80
+ });
81
+ req.on("error", () => resolve({ ok: false, info: "Sem conexão" }));
82
+ req.on("timeout", () => { req.destroy(); resolve({ ok: false, info: "Timeout" }); });
83
+ req.end();
84
+ });
85
+ }
86
+ // ---------------------------------------------------------------------------
87
+ // Métricas do dia (do logger)
88
+ // ---------------------------------------------------------------------------
89
+ function getTodayMetrics() {
90
+ const today = new Date().toISOString().split("T")[0];
91
+ const logFile = path.join(LOG_DIR, `adt-${today}.jsonl`);
92
+ if (!fs.existsSync(logFile)) {
93
+ return { calls: 0, success: 0, errors: 0, avgMs: 0 };
94
+ }
95
+ const lines = fs.readFileSync(logFile, "utf-8").trim().split("\n").filter(Boolean);
96
+ let success = 0;
97
+ let errors = 0;
98
+ let totalMs = 0;
99
+ for (const line of lines) {
100
+ try {
101
+ const entry = JSON.parse(line);
102
+ if (entry.status && entry.status < 400) {
103
+ success++;
104
+ }
105
+ else {
106
+ errors++;
107
+ }
108
+ if (entry.duration)
109
+ totalMs += entry.duration;
110
+ }
111
+ catch {
112
+ // skip malformed lines
113
+ }
114
+ }
115
+ const calls = success + errors;
116
+ return { calls, success, errors, avgMs: calls > 0 ? Math.round(totalMs / calls) : 0 };
117
+ }
118
+ // ---------------------------------------------------------------------------
119
+ // Contar knowledge files
120
+ // ---------------------------------------------------------------------------
121
+ function countKnowledge() {
122
+ // Tentar dist/knowledge primeiro, depois src/knowledge
123
+ const candidates = [
124
+ path.resolve(__dirname, "..", "knowledge"),
125
+ path.resolve(process.cwd(), "src", "knowledge"),
126
+ path.resolve(process.cwd(), "dist", "knowledge"),
127
+ ];
128
+ for (const dir of candidates) {
129
+ if (fs.existsSync(dir)) {
130
+ let files = 0;
131
+ let domains = 0;
132
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
133
+ for (const entry of entries) {
134
+ if (entry.isDirectory()) {
135
+ domains++;
136
+ const domainFiles = fs.readdirSync(path.join(dir, entry.name)).filter((f) => f.endsWith(".md"));
137
+ files += domainFiles.length;
138
+ }
139
+ }
140
+ return { files, domains };
141
+ }
142
+ }
143
+ return { files: 0, domains: 0 };
144
+ }
145
+ // ---------------------------------------------------------------------------
146
+ // Main
147
+ // ---------------------------------------------------------------------------
148
+ async function status() {
149
+ console.log(`
150
+ ╭──────────────────────────────────────────────╮
151
+ │ LKPABAP.ai v${VERSION}${" ".repeat(30 - VERSION.length)}│
152
+ ╰──────────────────────────────────────────────╯`);
153
+ // Licença
154
+ console.log(`
155
+ Licença
156
+ ───────`);
157
+ const license = (0, activate_js_1.readLicense)();
158
+ if (license) {
159
+ const now = new Date();
160
+ const expires = new Date(license.expires);
161
+ const daysLeft = Math.ceil((expires.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
162
+ const expired = daysLeft <= 0;
163
+ const planLabel = `${license.plan.charAt(0).toUpperCase() + license.plan.slice(1)} (BYOK)`;
164
+ console.log(` Plano: ${planLabel}`);
165
+ console.log(` Válido até: ${license.expires} (${expired ? "EXPIRADA" : `${daysLeft} dias restantes`})`);
166
+ console.log(` Status: ${expired ? "✗ Expirada — renove em https://lkpabap.ai" : "✓ Ativa"}`);
167
+ }
168
+ else {
169
+ console.log(` Status: ✗ Nenhuma licença configurada`);
170
+ console.log(` → Execute: abap-ai activate <LICENSE_KEY>`);
171
+ }
172
+ // Sistemas SAP
173
+ console.log(`
174
+ Sistemas SAP configurados
175
+ ─────────────────────────`);
176
+ let mcpConfig = { mcpServers: {} };
177
+ try {
178
+ const raw = fs.readFileSync(MCP_JSON_PATH, "utf-8");
179
+ mcpConfig = JSON.parse(raw);
180
+ }
181
+ catch {
182
+ // no mcp.json
183
+ }
184
+ const sapServers = Object.entries(mcpConfig.mcpServers || {}).filter(([k]) => k.startsWith("abap-"));
185
+ if (sapServers.length === 0) {
186
+ console.log(` Nenhum configurado`);
187
+ console.log(` → Execute: abap-ai init`);
188
+ }
189
+ else {
190
+ for (const [name, server] of sapServers) {
191
+ const env = server.env || {};
192
+ const url = env.SAP_URL || "?";
193
+ const client = env.SAP_CLIENT || "?";
194
+ const selfSigned = env.NODE_TLS_REJECT_UNAUTHORIZED === "0";
195
+ const shortUrl = url.replace(/^https?:\/\//, "").replace(/\.local$/, "");
196
+ if (env.SAP_URL && env.SAP_USER && env.SAP_PASS) {
197
+ const result = await quickTest(env.SAP_URL, env.SAP_USER, env.SAP_PASS, client, selfSigned);
198
+ if (result.ok) {
199
+ console.log(` ✓ ${name} ${shortUrl} (client ${client}) ${result.info}`);
200
+ }
201
+ else {
202
+ console.log(` ✗ ${name} ${shortUrl} (client ${client}) ${result.info}`);
203
+ }
204
+ }
205
+ else {
206
+ console.log(` ⚠ ${name} ${shortUrl} (client ${client}) Credenciais incompletas`);
207
+ }
208
+ }
209
+ }
210
+ // Uso hoje
211
+ const metrics = getTodayMetrics();
212
+ if (metrics.calls > 0) {
213
+ const successRate = metrics.calls > 0 ? Math.round((metrics.success / metrics.calls) * 100) : 0;
214
+ console.log(`
215
+ Uso hoje
216
+ ────────
217
+ Chamadas ADT: ${metrics.calls}
218
+ Sucesso: ${metrics.success} (${successRate}%)
219
+ Erros: ${metrics.errors}
220
+ Tempo médio: ${metrics.avgMs}ms`);
221
+ }
222
+ // Knowledge
223
+ const knowledge = countKnowledge();
224
+ if (knowledge.files > 0) {
225
+ console.log(`
226
+ Knowledge Base
227
+ ──────────────
228
+ ${knowledge.files} guias | ${knowledge.domains} domínios`);
229
+ }
230
+ console.log("");
231
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.systems = systems;
37
+ const fs = __importStar(require("fs"));
38
+ const os = __importStar(require("os"));
39
+ const path = __importStar(require("path"));
40
+ const GLOBAL_MCP_PATH = path.join(os.homedir(), ".claude", "mcp.json");
41
+ const LOCAL_MCP_PATH = path.join(process.cwd(), ".mcp.json");
42
+ async function systems(options = {}) {
43
+ const mcpPath = options.local ? LOCAL_MCP_PATH : GLOBAL_MCP_PATH;
44
+ let config;
45
+ try {
46
+ const raw = fs.readFileSync(mcpPath, "utf-8");
47
+ config = JSON.parse(raw);
48
+ }
49
+ catch {
50
+ console.log("\n Nenhum sistema configurado.");
51
+ console.log(` → Execute: abap-ai init${options.local ? " --local" : ""}\n`);
52
+ return;
53
+ }
54
+ const sapServers = Object.entries(config.mcpServers || {}).filter(([k]) => k.startsWith("abap-"));
55
+ if (sapServers.length === 0) {
56
+ console.log("\n Nenhum sistema SAP configurado.");
57
+ console.log(` → Execute: abap-ai init${options.local ? " --local" : ""}\n`);
58
+ return;
59
+ }
60
+ const scope = options.local ? `projeto (${process.cwd()})` : "global";
61
+ console.log(`\n Sistemas SAP (${sapServers.length}) — ${scope}:`);
62
+ console.log(" " + "─".repeat(60));
63
+ for (const [name, server] of sapServers) {
64
+ const env = server.env || {};
65
+ const url = (env.SAP_URL || "?").replace(/^https?:\/\//, "");
66
+ const client = env.SAP_CLIENT || "?";
67
+ const user = env.SAP_USER || "?";
68
+ const ssl = env.NODE_TLS_REJECT_UNAUTHORIZED === "0" ? " [SSL:off]" : "";
69
+ console.log(` ${name} ${url} client=${client} user=${user}${ssl}`);
70
+ }
71
+ console.log("");
72
+ }
package/dist/cli.js ADDED
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const init_js_1 = require("./cli/init.js");
5
+ const activate_js_1 = require("./cli/activate.js");
6
+ const status_js_1 = require("./cli/status.js");
7
+ const remove_js_1 = require("./cli/remove.js");
8
+ const systems_js_1 = require("./cli/systems.js");
9
+ const link_js_1 = require("./cli/link.js");
10
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
11
+ const VERSION = require("../package.json").version;
12
+ const HELP = `
13
+ LKPABAP.ai — AI-powered ABAP development for SAP
14
+
15
+ Uso:
16
+ abap-ai <comando> [opções]
17
+
18
+ Comandos:
19
+ init [--local] Configura conexão com sistema SAP (wizard interativo)
20
+ link Vincula sistemas globais a este workspace (VS Code)
21
+ activate <LICENSE_KEY> Ativa licença do produto
22
+ status Mostra licença, sistemas e métricas de uso
23
+ systems [--local] Lista sistemas SAP configurados
24
+ remove <nome> [--local] Remove um sistema SAP do mcp.json
25
+
26
+ Opções:
27
+ --local Usa config do projeto atual (.claude/mcp.json) em vez do global
28
+ --version, -v Mostra versão
29
+ --help, -h Mostra esta ajuda
30
+
31
+ Exemplos:
32
+ abap-ai init Wizard global (todos os workspaces)
33
+ abap-ai init --local Wizard para este workspace/projeto apenas
34
+ abap-ai link Vincula sistemas SAP a este workspace (necessário no VS Code)
35
+ abap-ai activate LK-XXXX Ativa licença
36
+ abap-ai status Verifica estado do ambiente
37
+ abap-ai remove novaforma-qas Remove sistema (config global)
38
+ abap-ai remove rdg --local Remove sistema da config do projeto
39
+ `;
40
+ async function main() {
41
+ const args = process.argv.slice(2);
42
+ const command = args[0];
43
+ if (!command || command === "--help" || command === "-h") {
44
+ console.log(HELP);
45
+ return;
46
+ }
47
+ if (command === "--version" || command === "-v") {
48
+ console.log(`LKPABAP.ai v${VERSION}`);
49
+ return;
50
+ }
51
+ const local = args.includes("--local");
52
+ switch (command) {
53
+ case "init":
54
+ await (0, init_js_1.init)({ local });
55
+ break;
56
+ case "activate": {
57
+ const key = args[1];
58
+ if (!key) {
59
+ console.error(" ✗ Informe a license key: abap-ai activate LK-XXXX-XXXX-XXXX");
60
+ process.exit(1);
61
+ }
62
+ await (0, activate_js_1.activate)(key);
63
+ break;
64
+ }
65
+ case "status":
66
+ await (0, status_js_1.status)();
67
+ break;
68
+ case "link":
69
+ await (0, link_js_1.link)();
70
+ break;
71
+ case "systems":
72
+ await (0, systems_js_1.systems)({ local });
73
+ break;
74
+ case "remove": {
75
+ const name = args.filter((a) => !a.startsWith("--"))[1];
76
+ if (!name) {
77
+ console.error(" ✗ Informe o nome do sistema: abap-ai remove <nome>");
78
+ process.exit(1);
79
+ }
80
+ await (0, remove_js_1.remove)(name, { local });
81
+ break;
82
+ }
83
+ default:
84
+ console.error(` ✗ Comando desconhecido: "${command}"`);
85
+ console.log(HELP);
86
+ process.exit(1);
87
+ }
88
+ }
89
+ main().catch((err) => {
90
+ console.error(` ✗ Erro: ${err.message || err}`);
91
+ process.exit(1);
92
+ });