kaven-cli 0.4.1-alpha.0 → 0.4.2-alpha.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 (68) hide show
  1. package/README.md +181 -207
  2. package/dist/EnvManager-NMS3NMIE.js +15 -0
  3. package/dist/MarketplaceClient-YCFH2VU4.js +1 -0
  4. package/dist/chunk-JHLQ46NG.js +1 -0
  5. package/dist/index.d.ts +4 -0
  6. package/dist/index.js +242 -304
  7. package/dist/tier-table-DQMPQSI2.js +6 -0
  8. package/package.json +26 -11
  9. package/dist/EnvManager-GQMEZ6NV.js +0 -158
  10. package/dist/MarketplaceClient-IJGRQRC4.js +0 -7
  11. package/dist/chunk-3RG5ZIWI.js +0 -10
  12. package/dist/chunk-GHZX5OAA.js +0 -455
  13. package/dist/commands/aiox/index.js +0 -20
  14. package/dist/commands/auth/login.js +0 -122
  15. package/dist/commands/auth/logout.js +0 -23
  16. package/dist/commands/auth/whoami.js +0 -36
  17. package/dist/commands/cache/index.js +0 -43
  18. package/dist/commands/config/features.js +0 -161
  19. package/dist/commands/config/index.js +0 -95
  20. package/dist/commands/index.js +0 -2
  21. package/dist/commands/init/aiox-bootstrap.js +0 -83
  22. package/dist/commands/init/index.js +0 -210
  23. package/dist/commands/init-ci/index.js +0 -153
  24. package/dist/commands/license/index.js +0 -10
  25. package/dist/commands/license/status.js +0 -44
  26. package/dist/commands/license/tier-table.js +0 -46
  27. package/dist/commands/marketplace/browse.js +0 -186
  28. package/dist/commands/marketplace/install.js +0 -263
  29. package/dist/commands/marketplace/list.js +0 -122
  30. package/dist/commands/module/activate.js +0 -245
  31. package/dist/commands/module/add.js +0 -69
  32. package/dist/commands/module/doctor.js +0 -175
  33. package/dist/commands/module/list.js +0 -51
  34. package/dist/commands/module/publish.js +0 -258
  35. package/dist/commands/module/remove.js +0 -58
  36. package/dist/commands/telemetry/view.js +0 -27
  37. package/dist/commands/upgrade/check.js +0 -162
  38. package/dist/commands/upgrade/index.js +0 -185
  39. package/dist/core/AuthService.js +0 -222
  40. package/dist/core/CacheManager.js +0 -154
  41. package/dist/core/ConfigManager.js +0 -166
  42. package/dist/core/EnvManager.js +0 -196
  43. package/dist/core/ErrorRecovery.js +0 -192
  44. package/dist/core/LicenseService.js +0 -83
  45. package/dist/core/ManifestParser.js +0 -52
  46. package/dist/core/MarkerService.js +0 -62
  47. package/dist/core/ModuleDoctor.js +0 -451
  48. package/dist/core/ModuleInstaller.js +0 -169
  49. package/dist/core/ProjectInitializer.js +0 -183
  50. package/dist/core/RegistryResolver.js +0 -95
  51. package/dist/core/SchemaActivator.js +0 -278
  52. package/dist/core/ScriptRunner.js +0 -73
  53. package/dist/core/SignatureVerifier.js +0 -75
  54. package/dist/core/index.js +0 -2
  55. package/dist/infrastructure/Container.js +0 -37
  56. package/dist/infrastructure/MarketplaceClient.js +0 -425
  57. package/dist/infrastructure/TelemetryBuffer.js +0 -73
  58. package/dist/infrastructure/TransactionalFileSystem.js +0 -77
  59. package/dist/infrastructure/errors.js +0 -63
  60. package/dist/infrastructure/index.js +0 -2
  61. package/dist/lib/capabilities-catalog.js +0 -73
  62. package/dist/lib/module-registry.js +0 -47
  63. package/dist/lib/schema-modifier.js +0 -40
  64. package/dist/tier-table-LAL6PAVW.js +0 -52
  65. package/dist/types/auth.js +0 -2
  66. package/dist/types/manifest.js +0 -45
  67. package/dist/types/markers.js +0 -10
  68. package/dist/types/marketplace.js +0 -2
@@ -1,183 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ProjectInitializer = void 0;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
- const path_1 = __importDefault(require("path"));
9
- const child_process_1 = require("child_process");
10
- const TEMPLATE_REPO = "https://github.com/kaven-co/kaven-template.git";
11
- const KAVEN_SQUAD_REPO = "https://github.com/bychrisr/kaven-squad";
12
- /** Run a shell command via spawn, returning exit code. */
13
- function runCommand(cmd, args, cwd, onData) {
14
- return new Promise((resolve, reject) => {
15
- const proc = (0, child_process_1.spawn)(cmd, args, { cwd, stdio: onData ? "pipe" : "inherit" });
16
- if (onData && proc.stdout) {
17
- proc.stdout.on("data", (d) => onData(d.toString()));
18
- }
19
- if (onData && proc.stderr) {
20
- proc.stderr.on("data", (d) => onData(d.toString()));
21
- }
22
- proc.on("error", reject);
23
- proc.on("close", (code) => resolve(code ?? 0));
24
- });
25
- }
26
- class ProjectInitializer {
27
- /** Validate that the project name only contains alphanumerics and hyphens. */
28
- validateName(name) {
29
- if (!name || name.trim().length === 0) {
30
- return { valid: false, reason: "Project name cannot be empty" };
31
- }
32
- if (/\s/.test(name)) {
33
- return { valid: false, reason: "Project name cannot contain spaces" };
34
- }
35
- if (!/^[a-z0-9-]+$/.test(name)) {
36
- return {
37
- valid: false,
38
- reason: "Project name must only contain lowercase letters, numbers, and hyphens",
39
- };
40
- }
41
- return { valid: true };
42
- }
43
- /** Clone the template (from Git or local path) into targetDir. */
44
- async cloneTemplate(targetDir, templateSource) {
45
- const source = templateSource || TEMPLATE_REPO;
46
- console.log(`[INIT] Clone Source: ${source}`);
47
- console.log(`[INIT] Target Dir: ${targetDir}`);
48
- // If it's a local path that exists, copy it instead of cloning
49
- if (await fs_extra_1.default.pathExists(source) && (source.startsWith("/") || source.startsWith("./") || source.startsWith("../"))) {
50
- console.log(`[INIT] Local Path Detected. Copying...`);
51
- await fs_extra_1.default.copy(source, targetDir, {
52
- filter: (src) => !src.includes("node_modules") && !src.includes(".git") && !src.includes(".turbo")
53
- });
54
- console.log(`[INIT] Local Copy Done.`);
55
- return;
56
- }
57
- const exitCode = await runCommand("git", ["clone", "--depth", "1", source, targetDir], process.cwd());
58
- if (exitCode !== 0) {
59
- throw new Error(`git clone failed with exit code ${exitCode}`);
60
- }
61
- }
62
- /** Remove the .git directory from the cloned project. */
63
- async removeGitDir(targetDir) {
64
- const gitDir = path_1.default.join(targetDir, ".git");
65
- if (await fs_extra_1.default.pathExists(gitDir)) {
66
- await fs_extra_1.default.remove(gitDir);
67
- }
68
- }
69
- /** Replace placeholders in key project files. */
70
- async replacePlaceholders(targetDir, values) {
71
- const replacements = {
72
- "{{PROJECT_NAME}}": values.projectName,
73
- "{{DATABASE_URL}}": values.dbUrl,
74
- "{{DEFAULT_LOCALE}}": values.locale,
75
- "{{DEFAULT_CURRENCY}}": values.currency,
76
- };
77
- const filesToProcess = [
78
- "package.json",
79
- ".env.example",
80
- "packages/database/prisma/schema.prisma",
81
- "apps/api/package.json",
82
- "apps/admin/package.json",
83
- "apps/tenant/package.json",
84
- "docs/architecture/tech-stack.md",
85
- "docs/architecture/source-tree.md",
86
- "docs/architecture/coding-standards.md",
87
- ];
88
- for (const relFile of filesToProcess) {
89
- const filePath = path_1.default.join(targetDir, relFile);
90
- if (!(await fs_extra_1.default.pathExists(filePath)))
91
- continue;
92
- let content = await fs_extra_1.default.readFile(filePath, "utf-8");
93
- for (const [placeholder, value] of Object.entries(replacements)) {
94
- content = content.split(placeholder).join(value);
95
- }
96
- await fs_extra_1.default.writeFile(filePath, content, "utf-8");
97
- }
98
- // Safety net: directly update root package.json name field regardless of placeholder
99
- const pkgPath = path_1.default.join(targetDir, "package.json");
100
- if (await fs_extra_1.default.pathExists(pkgPath)) {
101
- const pkg = await fs_extra_1.default.readJson(pkgPath);
102
- if (pkg.name !== values.projectName) {
103
- pkg.name = values.projectName;
104
- await fs_extra_1.default.writeJson(pkgPath, pkg, { spaces: 2 });
105
- }
106
- }
107
- }
108
- /** Run pnpm install in the target directory. */
109
- async runInstall(targetDir) {
110
- const exitCode = await runCommand("pnpm", ["install"], targetDir);
111
- if (exitCode !== 0) {
112
- throw new Error(`pnpm install failed with exit code ${exitCode}`);
113
- }
114
- }
115
- /** Initialize git and create an initial commit. */
116
- async initGit(targetDir) {
117
- await runCommand("git", ["init"], targetDir);
118
- await runCommand("git", ["add", "."], targetDir);
119
- await runCommand("git", ["commit", "-m", "chore: initial kaven setup"], targetDir);
120
- }
121
- /**
122
- * Clone kaven-squad into squads/kaven-squad/ inside the project.
123
- * Returns { installed: true } on success, { installed: false, reason } on failure.
124
- * Never throws — squad installation is non-fatal.
125
- */
126
- async installSquad(targetDir) {
127
- const squadsDir = path_1.default.join(targetDir, "squads");
128
- const squadDir = path_1.default.join(squadsDir, "kaven-squad");
129
- // Squad already present — skip
130
- if (await fs_extra_1.default.pathExists(squadDir)) {
131
- return { installed: false, reason: "already-exists" };
132
- }
133
- await fs_extra_1.default.ensureDir(squadsDir);
134
- const exitCode = await runCommand("git", ["clone", "--depth", "1", KAVEN_SQUAD_REPO, squadDir], process.cwd());
135
- if (exitCode !== 0) {
136
- return {
137
- installed: false,
138
- reason: `git clone exited with code ${exitCode}`,
139
- };
140
- }
141
- // Remove .git — squad history not needed in user project
142
- const squadGitDir = path_1.default.join(squadDir, ".git");
143
- if (await fs_extra_1.default.pathExists(squadGitDir)) {
144
- await fs_extra_1.default.remove(squadGitDir);
145
- }
146
- return { installed: true };
147
- }
148
- /**
149
- * Install AIOX Core runtime into the project via npx.
150
- * Non-fatal — if it fails, user gets instructions to run manually.
151
- */
152
- async installAIOXCore(targetDir) {
153
- const exitCode = await runCommand('npx', ['aiox-core@5.0.3', 'install', '--quiet'], targetDir);
154
- if (exitCode !== 0) {
155
- return {
156
- installed: false,
157
- reason: `npx aiox-core exited with code ${exitCode}`,
158
- };
159
- }
160
- return { installed: true };
161
- }
162
- /** Health check after project initialization. */
163
- async healthCheck(targetDir) {
164
- const issues = [];
165
- // Check key files exist
166
- const requiredFiles = ["package.json", ".env.example", "packages/database/prisma/schema.prisma"];
167
- for (const file of requiredFiles) {
168
- if (!(await fs_extra_1.default.pathExists(path_1.default.join(targetDir, file)))) {
169
- issues.push(`Missing required file: ${file}`);
170
- }
171
- }
172
- // Check node_modules exists (if install was run)
173
- const hasNodeModules = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, "node_modules"));
174
- if (!hasNodeModules) {
175
- issues.push("Dependencies not installed. Run: pnpm install");
176
- }
177
- return {
178
- healthy: issues.length === 0,
179
- issues,
180
- };
181
- }
182
- }
183
- exports.ProjectInitializer = ProjectInitializer;
@@ -1,95 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RegistryResolver = void 0;
4
- const ConfigManager_1 = require("./ConfigManager");
5
- const MarketplaceClient_1 = require("../infrastructure/MarketplaceClient");
6
- const AuthService_1 = require("./AuthService");
7
- /**
8
- * C2.5: Registry resolver — handles both official and custom registries
9
- */
10
- class RegistryResolver {
11
- authService;
12
- constructor(authService) {
13
- this.authService = authService || new AuthService_1.AuthService();
14
- }
15
- /**
16
- * Get the active registry URL (custom or default)
17
- */
18
- async getActiveRegistry() {
19
- await ConfigManager_1.configManager.initialize();
20
- return ConfigManager_1.configManager.getRegistry();
21
- }
22
- /**
23
- * Get marketplace client for active registry
24
- */
25
- async getMarketplaceClient() {
26
- const registry = await this.getActiveRegistry();
27
- const client = new MarketplaceClient_1.MarketplaceClient(this.authService);
28
- // Set custom registry if configured
29
- if (registry !== "https://marketplace.kaven.site") {
30
- client.baseUrl = registry;
31
- }
32
- return client;
33
- }
34
- /**
35
- * Validate registry URL is accessible
36
- */
37
- async validateRegistry(url) {
38
- try {
39
- const response = await fetch(`${url}/health`);
40
- if (!response.ok) {
41
- return {
42
- valid: false,
43
- error: `Registry returned ${response.status} ${response.statusText}`,
44
- };
45
- }
46
- return { valid: true };
47
- }
48
- catch (error) {
49
- return {
50
- valid: false,
51
- error: `Failed to connect: ${error instanceof Error ? error.message : String(error)}`,
52
- };
53
- }
54
- }
55
- /**
56
- * Set custom registry
57
- */
58
- async setCustomRegistry(url) {
59
- // Validate URL format
60
- try {
61
- new URL(url);
62
- }
63
- catch {
64
- throw new Error(`Invalid URL format: ${url}`);
65
- }
66
- // Validate registry is accessible
67
- const validation = await this.validateRegistry(url);
68
- if (!validation.valid) {
69
- throw new Error(`Registry validation failed: ${validation.error}`);
70
- }
71
- // Save to config
72
- await ConfigManager_1.configManager.initialize();
73
- await ConfigManager_1.configManager.set("customRegistry", url);
74
- }
75
- /**
76
- * Reset to default registry
77
- */
78
- async resetToDefaultRegistry() {
79
- await ConfigManager_1.configManager.initialize();
80
- await ConfigManager_1.configManager.set("customRegistry", undefined);
81
- }
82
- /**
83
- * List all available registries (default + custom)
84
- */
85
- async listRegistries() {
86
- await ConfigManager_1.configManager.initialize();
87
- const config = ConfigManager_1.configManager.getAll();
88
- return {
89
- default: config.registry || "https://marketplace.kaven.site",
90
- custom: config.customRegistry,
91
- active: await this.getActiveRegistry(),
92
- };
93
- }
94
- }
95
- exports.RegistryResolver = RegistryResolver;
@@ -1,278 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SchemaActivator = exports.KAVEN_MODULES = void 0;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
- const path_1 = __importDefault(require("path"));
9
- exports.KAVEN_MODULES = [
10
- {
11
- id: "auth",
12
- label: "Auth & Identity",
13
- description: "Gestão de usuários, permissões e sessões",
14
- models: ["User", "Role", "Capability", "AuthSession", "AuditLog"],
15
- enums: ["UserRole"],
16
- dependsOn: [],
17
- },
18
- {
19
- id: "billing",
20
- label: "Billing",
21
- description: "Faturamento, assinaturas e pagamentos",
22
- models: ["Invoice", "Order", "Subscription", "Plan", "Payment", "Product"],
23
- enums: [],
24
- dependsOn: [],
25
- },
26
- {
27
- id: "projects",
28
- label: "Projects",
29
- description: "Gestão de projetos e tasks",
30
- models: ["Project", "Task"],
31
- enums: ["ProjectStatus", "TaskStatus", "TaskPriority"],
32
- dependsOn: [],
33
- },
34
- {
35
- id: "notifications",
36
- label: "Notifications",
37
- description: "Notificações e preferências de usuário",
38
- models: ["Notification", "UserPreference"],
39
- enums: [],
40
- dependsOn: [],
41
- },
42
- {
43
- id: "marketing-tracking",
44
- label: "Marketing Tracking",
45
- description: "Observabilidade de anúncios, GTM, GA4 e Meta CAPI",
46
- models: ["TrackingEvent"],
47
- enums: ["TrackingSource"],
48
- dependsOn: [],
49
- },
50
- {
51
- id: "service-tokens",
52
- label: "Service Tokens",
53
- description: "Agent authentication tokens for AIOX integration",
54
- models: ["ServiceToken"],
55
- enums: [],
56
- dependsOn: [],
57
- },
58
- ];
59
- // ============================================================
60
- // Marcadores de seção no schema
61
- // ============================================================
62
- const BEGIN_MARKER = (moduleId) => `// [KAVEN_MODULE:${moduleId.toUpperCase()} BEGIN]`;
63
- const END_MARKER = (moduleId) => `// [KAVEN_MODULE:${moduleId.toUpperCase()} END]`;
64
- // ============================================================
65
- // SchemaActivator — lê/escreve schema.extended.prisma
66
- // ============================================================
67
- class SchemaActivator {
68
- schemaPath;
69
- constructor(projectRoot) {
70
- this.schemaPath = path_1.default.join(projectRoot, "packages", "database", "prisma", "schema.extended.prisma");
71
- }
72
- /** Verifica se o schema existe no projeto */
73
- async exists() {
74
- return fs_extra_1.default.pathExists(this.schemaPath);
75
- }
76
- /** Caminho absoluto do schema */
77
- get path() {
78
- return this.schemaPath;
79
- }
80
- /** Lê o conteúdo atual do schema */
81
- async readSchema() {
82
- return fs_extra_1.default.readFile(this.schemaPath, "utf-8");
83
- }
84
- /** Persiste o conteúdo no schema */
85
- async writeSchema(content) {
86
- await fs_extra_1.default.writeFile(this.schemaPath, content, "utf-8");
87
- }
88
- /**
89
- * Detecta se um módulo está ativo no schema.
90
- *
91
- * Estratégia:
92
- * 1. Se existirem marcadores BEGIN/END: verifica se o conteúdo dentro
93
- * dos marcadores NÃO está completamente comentado.
94
- * 2. Se não houver marcadores: verifica se algum dos models principais
95
- * do módulo está presente e não comentado no arquivo.
96
- */
97
- async getModuleStatus(def) {
98
- const content = await this.readSchema();
99
- const begin = BEGIN_MARKER(def.id);
100
- const end = END_MARKER(def.id);
101
- const hasMarkers = content.includes(begin) && content.includes(end);
102
- let active = false;
103
- if (hasMarkers) {
104
- const block = this.extractBlock(content, def.id);
105
- active = block !== null && this.isBlockActive(block);
106
- }
107
- else {
108
- // Sem marcadores: verifica presença de pelo menos um model descomentado
109
- active = def.models.some((modelName) => this.isModelActive(content, modelName));
110
- }
111
- return {
112
- id: def.id,
113
- label: def.label,
114
- description: def.description,
115
- models: def.models,
116
- dependsOn: def.dependsOn,
117
- active,
118
- hasMarkers,
119
- };
120
- }
121
- /** Ativa um módulo: se tem marcadores, descomenta o bloco; senão, injeta o bloco */
122
- async activateModule(def) {
123
- const content = await this.readSchema();
124
- const begin = BEGIN_MARKER(def.id);
125
- const end = END_MARKER(def.id);
126
- if (content.includes(begin) && content.includes(end)) {
127
- const updated = this.uncommentBlock(content, def.id);
128
- await this.writeSchema(updated);
129
- return;
130
- }
131
- // Módulo não tem seção marcada — sem template para injetar
132
- throw new Error(`O módulo "${def.id}" não possui uma seção marcada (BEGIN/END) no schema.\n` +
133
- `Adicione o bloco do módulo manualmente com os marcadores:\n` +
134
- ` ${begin}\n` +
135
- ` ... models do módulo ...\n` +
136
- ` ${end}`);
137
- }
138
- /** Desativa um módulo: comenta todos os models do bloco */
139
- async deactivateModule(def) {
140
- const content = await this.readSchema();
141
- const begin = BEGIN_MARKER(def.id);
142
- const end = END_MARKER(def.id);
143
- if (!content.includes(begin) || !content.includes(end)) {
144
- throw new Error(`O módulo "${def.id}" não possui marcadores BEGIN/END no schema. ` +
145
- `Não é possível desativar automaticamente.`);
146
- }
147
- const updated = this.commentBlock(content, def.id);
148
- await this.writeSchema(updated);
149
- }
150
- // ──────────────────────────────────────────────
151
- // Helpers de manipulação de blocos
152
- // ──────────────────────────────────────────────
153
- /**
154
- * Extrai o conteúdo entre os marcadores BEGIN e END (exclusive).
155
- * Retorna null se os marcadores não forem encontrados.
156
- */
157
- extractBlock(content, moduleId) {
158
- const begin = BEGIN_MARKER(moduleId);
159
- const end = END_MARKER(moduleId);
160
- const lines = content.split("\n");
161
- let beginIdx = -1;
162
- let endIdx = -1;
163
- for (let i = 0; i < lines.length; i++) {
164
- if (lines[i].includes(begin))
165
- beginIdx = i;
166
- if (lines[i].includes(end) && beginIdx !== -1) {
167
- endIdx = i;
168
- break;
169
- }
170
- }
171
- if (beginIdx === -1 || endIdx === -1)
172
- return null;
173
- return lines.slice(beginIdx + 1, endIdx).join("\n");
174
- }
175
- /**
176
- * Verifica se um bloco tem ao menos uma linha não-comentada relevante
177
- * (ignora linhas vazias e comentários simples).
178
- */
179
- isBlockActive(block) {
180
- return block.split("\n").some((line) => {
181
- const trimmed = line.trim();
182
- return (trimmed.length > 0 &&
183
- !trimmed.startsWith("//") &&
184
- !trimmed.startsWith("/*") &&
185
- !trimmed.startsWith("*"));
186
- });
187
- }
188
- /**
189
- * Verifica se um model específico está ativo (não comentado) no schema.
190
- * Procura pela linha `model ModelName {` sem `//` antes.
191
- */
192
- isModelActive(content, modelName) {
193
- const lines = content.split("\n");
194
- for (const line of lines) {
195
- const trimmed = line.trim();
196
- if (trimmed.startsWith(`model ${modelName}`) &&
197
- !line.trimStart().startsWith("//")) {
198
- return true;
199
- }
200
- }
201
- return false;
202
- }
203
- /**
204
- * Comenta todas as linhas não-comentadas dentro do bloco BEGIN/END.
205
- */
206
- commentBlock(content, moduleId) {
207
- const begin = BEGIN_MARKER(moduleId);
208
- const end = END_MARKER(moduleId);
209
- const lines = content.split("\n");
210
- let inBlock = false;
211
- const result = [];
212
- for (const line of lines) {
213
- if (line.includes(begin)) {
214
- inBlock = true;
215
- result.push(line);
216
- continue;
217
- }
218
- if (line.includes(end)) {
219
- inBlock = false;
220
- result.push(line);
221
- continue;
222
- }
223
- if (inBlock) {
224
- const trimmed = line.trim();
225
- if (trimmed.length === 0) {
226
- result.push(line);
227
- }
228
- else if (trimmed.startsWith("//")) {
229
- result.push(line); // já comentado
230
- }
231
- else {
232
- result.push(`// ${line}`);
233
- }
234
- }
235
- else {
236
- result.push(line);
237
- }
238
- }
239
- return result.join("\n");
240
- }
241
- /**
242
- * Remove `// ` do início das linhas dentro do bloco BEGIN/END.
243
- */
244
- uncommentBlock(content, moduleId) {
245
- const begin = BEGIN_MARKER(moduleId);
246
- const end = END_MARKER(moduleId);
247
- const lines = content.split("\n");
248
- let inBlock = false;
249
- const result = [];
250
- for (const line of lines) {
251
- if (line.includes(begin)) {
252
- inBlock = true;
253
- result.push(line);
254
- continue;
255
- }
256
- if (line.includes(end)) {
257
- inBlock = false;
258
- result.push(line);
259
- continue;
260
- }
261
- if (inBlock) {
262
- // Remove exatamente um nível de comentário preservando identação
263
- const match = line.match(/^(\s*)\/\/\s?(.*)$/);
264
- if (match) {
265
- result.push(match[1] + match[2]);
266
- }
267
- else {
268
- result.push(line);
269
- }
270
- }
271
- else {
272
- result.push(line);
273
- }
274
- }
275
- return result.join("\n");
276
- }
277
- }
278
- exports.SchemaActivator = SchemaActivator;
@@ -1,73 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ScriptRunner = void 0;
7
- const child_process_1 = require("child_process");
8
- const readline_1 = __importDefault(require("readline"));
9
- const chalk_1 = __importDefault(require("chalk"));
10
- class ScriptRunner {
11
- timeoutMs;
12
- constructor(timeoutMs = 60_000) {
13
- this.timeoutMs = timeoutMs;
14
- }
15
- async runScript(script, label, skipConfirmation = false) {
16
- if (!skipConfirmation) {
17
- const confirmed = await this.confirm(`Run ${label} script: ${script.command} ${(script.args ?? []).join(' ')}?`);
18
- if (!confirmed) {
19
- console.log(chalk_1.default.dim(` Skipping ${label} script.`));
20
- return;
21
- }
22
- }
23
- return new Promise((resolve, reject) => {
24
- const child = (0, child_process_1.spawn)(script.command, script.args ?? [], {
25
- cwd: script.cwd,
26
- stdio: ['ignore', 'pipe', 'pipe'],
27
- shell: true,
28
- });
29
- const prefix = chalk_1.default.dim(`[${label}] `);
30
- child.stdout?.on('data', (data) => {
31
- process.stdout.write(prefix + data.toString());
32
- });
33
- child.stderr?.on('data', (data) => {
34
- process.stderr.write(prefix + chalk_1.default.yellow(data.toString()));
35
- });
36
- const timer = setTimeout(() => {
37
- console.warn(chalk_1.default.yellow(`\n ⚠ ${label} script timed out after ${this.timeoutMs / 1000}s, sending SIGTERM...`));
38
- child.kill('SIGTERM');
39
- setTimeout(() => {
40
- child.kill('SIGKILL');
41
- }, 5_000);
42
- }, this.timeoutMs);
43
- child.on('close', (code) => {
44
- clearTimeout(timer);
45
- if (code === 0 || code === null) {
46
- resolve();
47
- }
48
- else {
49
- reject(new Error(`${label} script exited with code ${code}`));
50
- }
51
- });
52
- child.on('error', (err) => {
53
- clearTimeout(timer);
54
- reject(err);
55
- });
56
- });
57
- }
58
- async runScripts(scripts, label, skipConfirmation = false) {
59
- for (const script of scripts) {
60
- await this.runScript(script, label, skipConfirmation);
61
- }
62
- }
63
- confirm(message) {
64
- return new Promise((resolve) => {
65
- const rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout });
66
- rl.question(`\n ${message} [y/N] `, (answer) => {
67
- rl.close();
68
- resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
69
- });
70
- });
71
- }
72
- }
73
- exports.ScriptRunner = ScriptRunner;