johankit 0.1.3 → 1.0.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 (62) hide show
  1. package/README.md +45 -62
  2. package/dist/cli/commands/sync.js +38 -59
  3. package/dist/core/validation.js +7 -20
  4. package/dist/core/write.js +10 -9
  5. package/dist/src/cli/commands/copy.js +11 -0
  6. package/dist/src/cli/commands/paste.js +128 -0
  7. package/dist/src/cli/commands/prompt.js +54 -0
  8. package/dist/src/cli/commands/sync.js +166 -0
  9. package/dist/src/core/clipboard.js +64 -0
  10. package/dist/src/core/config.js +41 -0
  11. package/dist/{core → src/core}/diff.js +10 -14
  12. package/dist/{core → src/core}/git.js +1 -2
  13. package/dist/src/core/scan.js +75 -0
  14. package/dist/src/core/schema.js +18 -0
  15. package/dist/src/core/validation.js +11 -0
  16. package/dist/src/core/write.js +24 -0
  17. package/dist/src/index.js +39 -0
  18. package/dist/src/tests/cleanCodeBlock.test.js +23 -0
  19. package/dist/src/tests/scan.test.js +35 -0
  20. package/dist/src/tests/schema.test.js +22 -0
  21. package/dist/src/utils/cleanCodeBlock.js +13 -0
  22. package/dist/types.js +1 -0
  23. package/johankit.yml +6 -0
  24. package/package.json +20 -10
  25. package/src/cli/commands/copy.ts +6 -19
  26. package/src/cli/commands/paste.ts +79 -31
  27. package/src/cli/commands/prompt.ts +24 -64
  28. package/src/cli/commands/sync.ts +112 -71
  29. package/src/core/clipboard.ts +46 -80
  30. package/src/core/config.ts +22 -32
  31. package/src/core/diff.ts +10 -21
  32. package/src/core/scan.ts +52 -43
  33. package/src/core/schema.ts +17 -34
  34. package/src/core/validation.ts +8 -27
  35. package/src/core/write.ts +11 -17
  36. package/src/index.ts +43 -77
  37. package/src/tests/cleanCodeBlock.test.ts +21 -0
  38. package/src/tests/scan.test.ts +33 -0
  39. package/src/tests/schema.test.ts +24 -0
  40. package/src/types.ts +4 -50
  41. package/src/utils/cleanCodeBlock.ts +12 -12
  42. package/tsconfig.json +14 -5
  43. package/Readme.md +0 -56
  44. package/dist/cli/commands/copy.js +0 -29
  45. package/dist/cli/commands/paste.js +0 -49
  46. package/dist/cli/commands/prompt.js +0 -89
  47. package/dist/cli/commands/three.js +0 -106
  48. package/dist/cli/commands/tree.js +0 -107
  49. package/dist/core/clipboard.js +0 -89
  50. package/dist/core/config.js +0 -52
  51. package/dist/core/scan.js +0 -67
  52. package/dist/core/schema.js +0 -41
  53. package/dist/index.js +0 -72
  54. package/dist/services/JohankitService.js +0 -59
  55. package/dist/utils/cleanCodeBlock.js +0 -12
  56. package/dist/utils/createAsciiTree.js +0 -46
  57. package/johankit.yaml +0 -2
  58. package/src/cli/commands/tree.ts +0 -119
  59. package/src/services/JohankitService.ts +0 -70
  60. package/src/utils/createAsciiTree.ts +0 -53
  61. package/types.ts +0 -11
  62. /package/{types.js → dist/src/types.js} +0 -0
package/tsconfig.json CHANGED
@@ -3,14 +3,23 @@
3
3
  "target": "ES2020",
4
4
  "module": "NodeNext",
5
5
  "moduleResolution": "NodeNext",
6
- "baseUrl": "./src",
6
+ "baseUrl": ".",
7
7
  "paths": {
8
- "*": ["*", "core/*"]
8
+ "*": ["src/*", "src/core/core/*", "cli/*"]
9
9
  },
10
10
  "outDir": "dist",
11
- "rootDir": "src",
11
+ "rootDir": ".",
12
12
  "esModuleInterop": true,
13
13
  "strict": true,
14
14
  "skipLibCheck": true
15
- }
16
- }
15
+ },
16
+ "include": [
17
+ "src/**/*",
18
+ "src/core/core/**/*",
19
+ "cli/**/*"
20
+ ],
21
+ "exclude": [
22
+ "node_modules",
23
+ "dist"
24
+ ]
25
+ }
package/Readme.md DELETED
@@ -1,56 +0,0 @@
1
- # JohanKit CLI
2
-
3
- JohanKit é uma ferramenta para copiar, colar e sincronizar snapshots de código de forma inteligente usando AI.
4
-
5
- ## Comandos
6
-
7
- ### Copy
8
- Copia um diretório ou arquivos específicos para o clipboard em formato JSON.
9
-
10
- ```bash
11
- johankit copy <dir> [exts]
12
- ```
13
-
14
- - `<dir>`: Diretório a copiar (padrão `.`)
15
- - `[exts]`: Extensões separadas por vírgula (ex: `ts,js`)
16
-
17
- ### Paste
18
- Aplica o conteúdo do clipboard em um diretório.
19
-
20
- ```bash
21
- johankit paste <dir>
22
- ```
23
-
24
- - `<dir>`: Diretório de destino (padrão `.`)
25
-
26
- ### Prompt
27
- Gera um prompt com o snapshot atual do diretório para AI, copiando para o clipboard.
28
-
29
- ```bash
30
- johankit prompt <dir> "<user request>"
31
- ```
32
-
33
- ### Sync
34
- Aplica patches gerados pela AI em um diretório e atualiza o clipboard com o novo snapshot.
35
-
36
- ```bash
37
- johankit sync <dir>
38
- ```
39
-
40
- ## Exemplo de Uso
41
-
42
- ```bash
43
- johankit prompt src "refatorar para async/await"
44
- johankit sync src
45
- ```
46
-
47
- ## Configuração
48
- Crie um arquivo `johankit.yaml` na raiz do projeto para customizar os diretórios e arquivos a ignorar.
49
-
50
- ```yaml
51
- ignore:
52
- - dist
53
- - node_modules
54
- ```
55
-
56
- Por padrão, os seguintes diretórios já são ignorados: `.git`, `node_modules`, `dist`, `build`, `coverage`, `tmp`, `temp`.
@@ -1,29 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.copy = void 0;
4
- const scan_1 = require("../../core/scan");
5
- const clipboard_1 = require("../../core/clipboard");
6
- async function copy(input) {
7
- let snapshot;
8
- if (Array.isArray(input)) {
9
- snapshot = input.map(path => {
10
- const fileSnapshot = (0, scan_1.scanDir)(path);
11
- if (fileSnapshot.length !== 1) {
12
- throw new Error(`Expected single file for path: ${path}`);
13
- }
14
- return fileSnapshot[0];
15
- });
16
- }
17
- else {
18
- snapshot = (0, scan_1.scanDir)(input);
19
- }
20
- const clipboardJSON = JSON.stringify(snapshot, null, 2);
21
- try {
22
- await (0, clipboard_1.copyToClipboard)(clipboardJSON);
23
- }
24
- catch (err) {
25
- console.warn("Clipboard unavailable:", err);
26
- }
27
- return clipboardJSON;
28
- }
29
- exports.copy = copy;
@@ -1,49 +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.paste = void 0;
7
- // src/cli/commands/paste.ts
8
- const write_1 = require("../../core/write");
9
- const clipboard_1 = require("../../core/clipboard");
10
- const cleanCodeBlock_1 = __importDefault(require("../../utils/cleanCodeBlock"));
11
- const diff_1 = require("../../core/diff");
12
- const validation_1 = require("../../core/validation");
13
- async function paste(dir) {
14
- try {
15
- const content = await (0, clipboard_1.readClipboard)();
16
- if (!content) {
17
- throw new Error("Clipboard empty or inaccessible");
18
- }
19
- let parsed;
20
- try {
21
- const { cleaned } = (0, cleanCodeBlock_1.default)(content);
22
- parsed = JSON.parse(cleaned);
23
- }
24
- catch (e) {
25
- throw new Error("Clipboard content is not valid JSON");
26
- }
27
- if (Array.isArray(parsed) && parsed.every(f => f.path && f.content)) {
28
- // Caso seja snapshot
29
- (0, write_1.writeFiles)(dir, parsed, true);
30
- }
31
- else if (Array.isArray(parsed) && parsed.every(f => f.type && f.path)) {
32
- // Caso seja DiffPatch
33
- const validated = (0, validation_1.validatePatches)(parsed);
34
- (0, diff_1.applyDiff)(dir, validated);
35
- }
36
- else {
37
- throw new Error("JSON is neither FileSnapshot array nor DiffPatch array");
38
- }
39
- process.stdout.write("✔ Pasted from clipboard\n");
40
- }
41
- catch (error) {
42
- process.stderr.write("✖ Paste failed\n");
43
- if (error instanceof Error) {
44
- process.stderr.write(`${error.message}\n`);
45
- }
46
- process.exit(1);
47
- }
48
- }
49
- exports.paste = paste;
@@ -1,89 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.prompt = void 0;
4
- // src/cli/commands/prompt.ts
5
- const scan_1 = require("../../core/scan");
6
- const clipboard_1 = require("../../core/clipboard");
7
- async function prompt(dir, userPrompt, diff = false) {
8
- const snapshot = (0, scan_1.scanDir)(dir);
9
- const llmExamples = [
10
- {
11
- type: 'FileSnapshot',
12
- example: [
13
- {
14
- path: 'src/example.ts',
15
- content: 'export const x = 42;'
16
- }
17
- ]
18
- },
19
- {
20
- type: 'DiffPatch',
21
- example: [
22
- {
23
- type: 'modify',
24
- path: 'src/example.ts',
25
- content: 'export const x = 43;'
26
- },
27
- {
28
- type: 'create',
29
- path: 'src/newFile.ts',
30
- content: 'export const newFile = true;'
31
- },
32
- {
33
- type: 'delete',
34
- path: 'src/oldFile.ts'
35
- }
36
- ]
37
- }
38
- ];
39
- const template = `
40
- You are an AI software engineer.
41
-
42
- You will receive a JSON array representing a snapshot of a codebase.
43
- Each item has the following structure:
44
- {
45
- "path": "relative/path/to/file.ext",
46
- "content": "full file content"
47
- }
48
-
49
- ---
50
-
51
- SNAPSHOT
52
- ${JSON.stringify(snapshot, null, 2)}
53
-
54
- ---
55
-
56
- YOUR TASK
57
- Propose changes according to the user request.
58
-
59
- Return ONLY a JSON array of ${diff ? 'DiffPatch' : 'FileSnapshot'}.
60
-
61
- PATCH FORMAT (STRICT)
62
- {
63
- \"path\": \"relative/path/to/file.ext\",
64
- \"content\": \"FULL updated file content (omit for delete)\"
65
- }
66
-
67
- EXAMPLE RESPONSE FROM LLM:
68
- ${JSON.stringify(diff ? llmExamples.find(e => e.type === 'DiffPatch')?.example : llmExamples.find(e => e.type === 'FileSnapshot')?.example, null, 2)}
69
-
70
- IMPORTANT RULES
71
- - Do NOT return explanations
72
- - Do NOT return markdown
73
- - Return ONLY valid JSON inside the \"\`\`\`\"
74
- - Always return within a Markdown Code Block.
75
-
76
- USER REQUEST
77
- ${userPrompt}
78
- `;
79
- try {
80
- await (0, clipboard_1.copyToClipboard)(template.trim());
81
- process.stdout.write(template.trim());
82
- process.stdout.write("\n\n✔ Prompt + Snapshot + Example copied to clipboard\n");
83
- }
84
- catch (e) {
85
- process.stdout.write(template.trim());
86
- process.stderr.write("\n✖ Failed to copy to clipboard (output only)\n");
87
- }
88
- }
89
- exports.prompt = prompt;
@@ -1,106 +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.tree = void 0;
7
- const path_1 = __importDefault(require("path"));
8
- const ts_morph_1 = require("ts-morph");
9
- /**
10
- * Heurística simples para classificar arquivos
11
- */
12
- function detectFileKind(filePath, exportsCount) {
13
- if (filePath.includes("/cli/"))
14
- return "cli";
15
- if (filePath.endsWith("index.ts") || filePath.endsWith("main.ts"))
16
- return "entry";
17
- if (exportsCount === 0)
18
- return "util";
19
- if (exportsCount > 3)
20
- return "domain";
21
- return "unknown";
22
- }
23
- async function tree(dir) {
24
- const project = new ts_morph_1.Project({});
25
- project.addSourceFilesAtPaths([
26
- `${dir}/**/*.{ts,tsx,js,jsx}`,
27
- `!${dir}/**/node_modules/**/*`,
28
- `!${dir}/**/dist/**/*`,
29
- ]);
30
- const tree = [];
31
- for (const file of project.getSourceFiles()) {
32
- const absolutePath = file.getFilePath();
33
- const filePath = path_1.default.relative(dir, absolutePath);
34
- if (filePath.includes("node_modules") || filePath.includes("/dist/")) {
35
- continue;
36
- }
37
- /* ---------------- IMPORTS ---------------- */
38
- const imports = file
39
- .getImportDeclarations()
40
- .map(i => i.getModuleSpecifierValue());
41
- /* ---------------- CLASSES ---------------- */
42
- const classes = file.getClasses().map(cls => ({
43
- name: cls.getName() || "<anonymous>",
44
- methods: cls.getMethods().map(m => ({
45
- name: m.getName(),
46
- params: m.getParameters().map(p => p.getName()),
47
- returnType: safeType(() => m.getReturnType().getText()),
48
- scope: "class",
49
- }))
50
- }));
51
- /* ---------------- FUNCTIONS ---------------- */
52
- const functions = file.getFunctions().map(fn => ({
53
- name: fn.getName() || "<anonymous>",
54
- params: fn.getParameters().map(p => p.getName()),
55
- returnType: safeType(() => fn.getReturnType().getText()),
56
- scope: "global",
57
- }));
58
- /* ---------------- VARIABLES ---------------- */
59
- const variables = file.getVariableDeclarations().map(v => ({
60
- name: v.getName(),
61
- type: safeType(() => v.getType().getText()),
62
- scope: v.getParent() instanceof ts_morph_1.SourceFile ? "global" : "local",
63
- }));
64
- /* ---------------- EXPORTS ---------------- */
65
- const exports = [];
66
- let mainExport;
67
- file.getExportedDeclarations().forEach((decls, name) => {
68
- decls.forEach(d => {
69
- let kind = "unknown";
70
- if (d.getKind() === ts_morph_1.SyntaxKind.ClassDeclaration)
71
- kind = "class";
72
- if (d.getKind() === ts_morph_1.SyntaxKind.FunctionDeclaration)
73
- kind = "function";
74
- if (d.getKind() === ts_morph_1.SyntaxKind.VariableDeclaration)
75
- kind = "variable";
76
- if (d.getKind() === ts_morph_1.SyntaxKind.TypeAliasDeclaration)
77
- kind = "type";
78
- exports.push({ name, kind });
79
- });
80
- });
81
- if (exports.length === 1) {
82
- mainExport = exports[0].name;
83
- }
84
- const kind = detectFileKind(filePath, exports.length);
85
- tree.push({
86
- path: filePath,
87
- kind,
88
- imports,
89
- classes,
90
- functions,
91
- variables,
92
- exports,
93
- mainExport,
94
- });
95
- }
96
- return tree;
97
- }
98
- exports.tree = tree;
99
- function safeType(fn) {
100
- try {
101
- return fn();
102
- }
103
- catch {
104
- return "unknown";
105
- }
106
- }
@@ -1,107 +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.tree = void 0;
7
- const path_1 = __importDefault(require("path"));
8
- const ts_morph_1 = require("ts-morph");
9
- /**
10
- * Heurística simples para classificar arquivos
11
- */
12
- function detectFileKind(filePath, exportsCount) {
13
- if (filePath.includes("/cli/"))
14
- return "cli";
15
- if (filePath.endsWith("index.ts") || filePath.endsWith("main.ts"))
16
- return "entry";
17
- if (exportsCount === 0)
18
- return "util";
19
- if (exportsCount > 3)
20
- return "domain";
21
- return "unknown";
22
- }
23
- async function tree(dir) {
24
- const project = new ts_morph_1.Project({});
25
- project.addSourceFilesAtPaths([
26
- `${dir}/**/*.{ts,tsx,js,jsx}`,
27
- `!${dir}/**/node_modules/**/*`,
28
- `!${dir}/**/dist/**/*`,
29
- ]);
30
- const tree = [];
31
- for (const file of project.getSourceFiles()) {
32
- const absolutePath = file.getFilePath();
33
- const filePath = path_1.default.relative(dir, absolutePath);
34
- console.log(filePath);
35
- if (filePath.includes("node_modules") || filePath.includes("/dist/")) {
36
- continue;
37
- }
38
- /* ---------------- IMPORTS ---------------- */
39
- const imports = file
40
- .getImportDeclarations()
41
- .map(i => i.getModuleSpecifierValue());
42
- /* ---------------- CLASSES ---------------- */
43
- const classes = file.getClasses().map(cls => ({
44
- name: cls.getName() || "<anonymous>",
45
- methods: cls.getMethods().map(m => ({
46
- name: m.getName(),
47
- params: m.getParameters().map(p => p.getName()),
48
- returnType: safeType(() => m.getReturnType().getText()),
49
- scope: "class",
50
- }))
51
- }));
52
- /* ---------------- FUNCTIONS ---------------- */
53
- const functions = file.getFunctions().map(fn => ({
54
- name: fn.getName() || "<anonymous>",
55
- params: fn.getParameters().map(p => p.getName()),
56
- returnType: safeType(() => fn.getReturnType().getText()),
57
- scope: "global",
58
- }));
59
- /* ---------------- VARIABLES ---------------- */
60
- const variables = file.getVariableDeclarations().map(v => ({
61
- name: v.getName(),
62
- type: safeType(() => v.getType().getText()),
63
- scope: v.getParent() instanceof ts_morph_1.SourceFile ? "global" : "local",
64
- }));
65
- /* ---------------- EXPORTS ---------------- */
66
- const exports = [];
67
- let mainExport;
68
- file.getExportedDeclarations().forEach((decls, name) => {
69
- decls.forEach(d => {
70
- let kind = "unknown";
71
- if (d.getKind() === ts_morph_1.SyntaxKind.ClassDeclaration)
72
- kind = "class";
73
- if (d.getKind() === ts_morph_1.SyntaxKind.FunctionDeclaration)
74
- kind = "function";
75
- if (d.getKind() === ts_morph_1.SyntaxKind.VariableDeclaration)
76
- kind = "variable";
77
- if (d.getKind() === ts_morph_1.SyntaxKind.TypeAliasDeclaration)
78
- kind = "type";
79
- exports.push({ name, kind });
80
- });
81
- });
82
- if (exports.length === 1) {
83
- mainExport = exports[0].name;
84
- }
85
- const kind = detectFileKind(filePath, exports.length);
86
- tree.push({
87
- path: filePath,
88
- kind,
89
- imports,
90
- classes,
91
- functions,
92
- variables,
93
- exports,
94
- mainExport,
95
- });
96
- }
97
- return tree;
98
- }
99
- exports.tree = tree;
100
- function safeType(fn) {
101
- try {
102
- return fn();
103
- }
104
- catch {
105
- return "unknown";
106
- }
107
- }
@@ -1,89 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readClipboard = exports.copyToClipboard = void 0;
4
- // src/core/clipboard.ts
5
- const child_process_1 = require("child_process");
6
- let memoryClipboard = "";
7
- function copyToClipboard(text) {
8
- return new Promise((resolve, reject) => {
9
- let command = "xclip";
10
- let args = ["-selection", "clipboard"];
11
- if (process.platform === "darwin") {
12
- command = "pbcopy";
13
- args = [];
14
- }
15
- else if (process.platform === "win32") {
16
- command = "clip";
17
- args = [];
18
- }
19
- const child = (0, child_process_1.spawn)(command, args, {
20
- stdio: ["pipe", "ignore", "ignore"]
21
- });
22
- let resolved = false;
23
- child.on("error", (err) => {
24
- memoryClipboard = text;
25
- resolved = true;
26
- resolve();
27
- });
28
- child.stdin.on("error", (err) => {
29
- if (err.code === "EPIPE") {
30
- resolved = true;
31
- resolve();
32
- }
33
- else {
34
- memoryClipboard = text;
35
- if (!resolved)
36
- resolve();
37
- }
38
- });
39
- child.stdin.write(text);
40
- child.stdin.end();
41
- child.on("close", () => {
42
- if (!resolved)
43
- resolve();
44
- });
45
- });
46
- }
47
- exports.copyToClipboard = copyToClipboard;
48
- function readClipboard() {
49
- return new Promise((resolve, reject) => {
50
- let command;
51
- let args = [];
52
- if (process.platform === "darwin") {
53
- command = "pbpaste";
54
- }
55
- else if (process.platform === "win32") {
56
- command = "powershell";
57
- args = ["-Command", "Get-Clipboard"];
58
- }
59
- else {
60
- command = "xclip";
61
- args = ["-selection", "clipboard", "-o"];
62
- }
63
- const child = (0, child_process_1.spawn)(command, args, {
64
- stdio: ["ignore", "pipe", "pipe"]
65
- });
66
- let data = "";
67
- let error = "";
68
- let fallback = false;
69
- child.stdout.on("data", chunk => {
70
- data += chunk.toString();
71
- });
72
- child.stderr.on("data", chunk => {
73
- error += chunk.toString();
74
- });
75
- child.on("error", () => {
76
- fallback = true;
77
- resolve(memoryClipboard);
78
- });
79
- child.on("close", code => {
80
- if (code !== 0 || fallback) {
81
- resolve(memoryClipboard);
82
- }
83
- else {
84
- resolve(data);
85
- }
86
- });
87
- });
88
- }
89
- exports.readClipboard = readClipboard;
@@ -1,52 +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.loadConfig = void 0;
7
- // src/core/config.ts
8
- const path_1 = __importDefault(require("path"));
9
- const fs_1 = require("fs");
10
- const js_yaml_1 = require("js-yaml");
11
- const CONFIG_FILENAME = "johankit.yaml";
12
- const DEFAULT_IGNORE = [
13
- ".git",
14
- "node_modules",
15
- "dist",
16
- "build",
17
- "coverage",
18
- "tmp",
19
- "temp",
20
- ];
21
- /**
22
- * Tenta carregar as configurações do arquivo johankit.yaml na basePath.
23
- * Retorna um objeto Config com defaults se o arquivo não for encontrado.
24
- * @param basePath O diretório base para procurar o arquivo de configuração.
25
- * @returns O objeto de configuração.
26
- */
27
- function loadConfig(basePath) {
28
- const configPath = path_1.default.join(basePath, CONFIG_FILENAME);
29
- try {
30
- const content = (0, fs_1.readFileSync)(configPath, "utf8");
31
- const loadedConfig = (0, js_yaml_1.load)(content);
32
- return {
33
- ignore: [
34
- ...DEFAULT_IGNORE,
35
- ...(loadedConfig.ignore || []),
36
- ],
37
- };
38
- }
39
- catch (error) {
40
- if (error instanceof Error && error.code === "ENOENT") {
41
- // Arquivo não encontrado, retorna configuração padrão
42
- return {
43
- ignore: DEFAULT_IGNORE,
44
- };
45
- }
46
- console.warn(`[johankit] Aviso: Falha ao carregar ${CONFIG_FILENAME}. Usando defaults.`, error);
47
- return {
48
- ignore: DEFAULT_IGNORE,
49
- };
50
- }
51
- }
52
- exports.loadConfig = loadConfig;
package/dist/core/scan.js DELETED
@@ -1,67 +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.scanDir = void 0;
7
- // src/core/scan.ts
8
- const fs_1 = __importDefault(require("fs"));
9
- const path_1 = __importDefault(require("path"));
10
- function scanDir(basePath, options = {}) {
11
- const result = [];
12
- const base = path_1.default.resolve(basePath);
13
- const exts = options.extensions?.map(e => e.startsWith(".") ? e : `.${e}`);
14
- // Default ignores
15
- const ignoreSet = new Set([
16
- "node_modules", ".git", "dist", "build", ".DS_Store", "coverage", ".env", "yarn.lock",
17
- ]);
18
- // Read .gitignore if exists
19
- const gitignorePath = path_1.default.join(base, ".gitignore");
20
- if (fs_1.default.existsSync(gitignorePath)) {
21
- try {
22
- const lines = fs_1.default.readFileSync(gitignorePath, "utf8").split("\n");
23
- for (const line of lines) {
24
- const trimmed = line.trim();
25
- if (trimmed && !trimmed.startsWith("#")) {
26
- ignoreSet.add(trimmed.replace(/^\//, "").replace(/\/$/, ""));
27
- }
28
- }
29
- }
30
- catch (e) {
31
- // ignore read errors
32
- }
33
- }
34
- function shouldIgnore(name) {
35
- if (ignoreSet.has(name))
36
- return true;
37
- for (const pattern of ignoreSet) {
38
- if (pattern.startsWith("*") && name.endsWith(pattern.slice(1)))
39
- return true;
40
- if (name.startsWith(pattern + "/"))
41
- return true;
42
- }
43
- return false;
44
- }
45
- function loop(currentPath) {
46
- const entries = fs_1.default.readdirSync(currentPath, { withFileTypes: true });
47
- for (const entry of entries) {
48
- if (shouldIgnore(entry.name))
49
- continue;
50
- const fullPath = path_1.default.join(currentPath, entry.name);
51
- if (entry.isDirectory()) {
52
- loop(fullPath);
53
- }
54
- else {
55
- if (exts && !exts.includes(path_1.default.extname(entry.name)))
56
- continue;
57
- result.push({
58
- path: path_1.default.relative(base, fullPath).replace(/\\/g, "/"),
59
- content: fs_1.default.readFileSync(fullPath, "utf8"),
60
- });
61
- }
62
- }
63
- }
64
- loop(base);
65
- return result;
66
- }
67
- exports.scanDir = scanDir;