kodu 2.2.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/README.md +24 -3
  2. package/bin/kodu.js +40 -0
  3. package/package.json +12 -67
  4. package/scripts/install.js +68 -0
  5. package/scripts/postinstall.js +22 -0
  6. package/AGENTS.md +0 -214
  7. package/__tests__/core/fs/fs.service.test.ts +0 -72
  8. package/__tests__/core/registry/registry.service.test.ts +0 -82
  9. package/__tests__/shared/cleaner/cleaner.service.test.ts +0 -102
  10. package/__tests__/shared/git/git.service.test.ts +0 -84
  11. package/__tests__/shared/runbook/runbook.service.test.ts +0 -104
  12. package/__tests__/shared/tokenizer/tokenizer.service.test.ts +0 -45
  13. package/biome.json +0 -50
  14. package/dist/package.json +0 -96
  15. package/dist/src/app.module.d.ts +0 -2
  16. package/dist/src/app.module.js +0 -42
  17. package/dist/src/app.module.js.map +0 -1
  18. package/dist/src/commands/clean/clean.command.d.ts +0 -37
  19. package/dist/src/commands/clean/clean.command.js +0 -240
  20. package/dist/src/commands/clean/clean.command.js.map +0 -1
  21. package/dist/src/commands/clean/clean.module.d.ts +0 -2
  22. package/dist/src/commands/clean/clean.module.js +0 -26
  23. package/dist/src/commands/clean/clean.module.js.map +0 -1
  24. package/dist/src/commands/init/init.command.d.ts +0 -10
  25. package/dist/src/commands/init/init.command.js +0 -96
  26. package/dist/src/commands/init/init.command.js.map +0 -1
  27. package/dist/src/commands/init/init.module.d.ts +0 -2
  28. package/dist/src/commands/init/init.module.js +0 -22
  29. package/dist/src/commands/init/init.module.js.map +0 -1
  30. package/dist/src/commands/ops/ops-add.command.d.ts +0 -18
  31. package/dist/src/commands/ops/ops-add.command.js +0 -102
  32. package/dist/src/commands/ops/ops-add.command.js.map +0 -1
  33. package/dist/src/commands/ops/ops-init.command.d.ts +0 -22
  34. package/dist/src/commands/ops/ops-init.command.js +0 -130
  35. package/dist/src/commands/ops/ops-init.command.js.map +0 -1
  36. package/dist/src/commands/ops/ops-list.command.d.ts +0 -12
  37. package/dist/src/commands/ops/ops-list.command.js +0 -73
  38. package/dist/src/commands/ops/ops-list.command.js.map +0 -1
  39. package/dist/src/commands/ops/ops-path.command.d.ts +0 -9
  40. package/dist/src/commands/ops/ops-path.command.js +0 -52
  41. package/dist/src/commands/ops/ops-path.command.js.map +0 -1
  42. package/dist/src/commands/ops/ops-runbook.command.d.ts +0 -12
  43. package/dist/src/commands/ops/ops-runbook.command.js +0 -81
  44. package/dist/src/commands/ops/ops-runbook.command.js.map +0 -1
  45. package/dist/src/commands/ops/ops-status.command.d.ts +0 -11
  46. package/dist/src/commands/ops/ops-status.command.js +0 -62
  47. package/dist/src/commands/ops/ops-status.command.js.map +0 -1
  48. package/dist/src/commands/ops/ops-use.command.d.ts +0 -12
  49. package/dist/src/commands/ops/ops-use.command.js +0 -76
  50. package/dist/src/commands/ops/ops-use.command.js.map +0 -1
  51. package/dist/src/commands/ops/ops.command.d.ts +0 -7
  52. package/dist/src/commands/ops/ops.command.js +0 -56
  53. package/dist/src/commands/ops/ops.command.js.map +0 -1
  54. package/dist/src/commands/ops/ops.helpers.d.ts +0 -2
  55. package/dist/src/commands/ops/ops.helpers.js +0 -11
  56. package/dist/src/commands/ops/ops.helpers.js.map +0 -1
  57. package/dist/src/commands/ops/ops.module.d.ts +0 -2
  58. package/dist/src/commands/ops/ops.module.js +0 -36
  59. package/dist/src/commands/ops/ops.module.js.map +0 -1
  60. package/dist/src/commands/pack/pack.command.d.ts +0 -51
  61. package/dist/src/commands/pack/pack.command.js +0 -355
  62. package/dist/src/commands/pack/pack.command.js.map +0 -1
  63. package/dist/src/commands/pack/pack.module.d.ts +0 -2
  64. package/dist/src/commands/pack/pack.module.js +0 -27
  65. package/dist/src/commands/pack/pack.module.js.map +0 -1
  66. package/dist/src/core/config/config.module.d.ts +0 -2
  67. package/dist/src/core/config/config.module.js +0 -23
  68. package/dist/src/core/config/config.module.js.map +0 -1
  69. package/dist/src/core/config/config.schema.d.ts +0 -19
  70. package/dist/src/core/config/config.schema.js +0 -56
  71. package/dist/src/core/config/config.schema.js.map +0 -1
  72. package/dist/src/core/config/config.service.d.ts +0 -7
  73. package/dist/src/core/config/config.service.js +0 -49
  74. package/dist/src/core/config/config.service.js.map +0 -1
  75. package/dist/src/core/config/prompt.service.d.ts +0 -10
  76. package/dist/src/core/config/prompt.service.js +0 -80
  77. package/dist/src/core/config/prompt.service.js.map +0 -1
  78. package/dist/src/core/file-system/fs.module.d.ts +0 -2
  79. package/dist/src/core/file-system/fs.module.js +0 -21
  80. package/dist/src/core/file-system/fs.module.js.map +0 -1
  81. package/dist/src/core/file-system/fs.service.d.ts +0 -27
  82. package/dist/src/core/file-system/fs.service.js +0 -203
  83. package/dist/src/core/file-system/fs.service.js.map +0 -1
  84. package/dist/src/core/registry/registry.module.d.ts +0 -2
  85. package/dist/src/core/registry/registry.module.js +0 -22
  86. package/dist/src/core/registry/registry.module.js.map +0 -1
  87. package/dist/src/core/registry/registry.schema.d.ts +0 -24
  88. package/dist/src/core/registry/registry.schema.js +0 -21
  89. package/dist/src/core/registry/registry.schema.js.map +0 -1
  90. package/dist/src/core/registry/registry.service.d.ts +0 -16
  91. package/dist/src/core/registry/registry.service.js +0 -91
  92. package/dist/src/core/registry/registry.service.js.map +0 -1
  93. package/dist/src/core/ui/ui.module.d.ts +0 -2
  94. package/dist/src/core/ui/ui.module.js +0 -22
  95. package/dist/src/core/ui/ui.module.js.map +0 -1
  96. package/dist/src/core/ui/ui.service.d.ts +0 -22
  97. package/dist/src/core/ui/ui.service.js +0 -43
  98. package/dist/src/core/ui/ui.service.js.map +0 -1
  99. package/dist/src/main.d.ts +0 -2
  100. package/dist/src/main.js +0 -16
  101. package/dist/src/main.js.map +0 -1
  102. package/dist/src/shared/cleaner/cleaner.service.d.ts +0 -23
  103. package/dist/src/shared/cleaner/cleaner.service.js +0 -223
  104. package/dist/src/shared/cleaner/cleaner.service.js.map +0 -1
  105. package/dist/src/shared/cleaner/cleaner.types.d.ts +0 -21
  106. package/dist/src/shared/cleaner/cleaner.types.js +0 -3
  107. package/dist/src/shared/cleaner/cleaner.types.js.map +0 -1
  108. package/dist/src/shared/constants.d.ts +0 -4
  109. package/dist/src/shared/constants.js +0 -113
  110. package/dist/src/shared/constants.js.map +0 -1
  111. package/dist/src/shared/deps/deps.module.d.ts +0 -2
  112. package/dist/src/shared/deps/deps.module.js +0 -21
  113. package/dist/src/shared/deps/deps.module.js.map +0 -1
  114. package/dist/src/shared/deps/deps.service.d.ts +0 -15
  115. package/dist/src/shared/deps/deps.service.js +0 -114
  116. package/dist/src/shared/deps/deps.service.js.map +0 -1
  117. package/dist/src/shared/git/git.module.d.ts +0 -2
  118. package/dist/src/shared/git/git.module.js +0 -21
  119. package/dist/src/shared/git/git.module.js.map +0 -1
  120. package/dist/src/shared/git/git.service.d.ts +0 -5
  121. package/dist/src/shared/git/git.service.js +0 -56
  122. package/dist/src/shared/git/git.service.js.map +0 -1
  123. package/dist/src/shared/runbook/runbook.module.d.ts +0 -2
  124. package/dist/src/shared/runbook/runbook.module.js +0 -22
  125. package/dist/src/shared/runbook/runbook.module.js.map +0 -1
  126. package/dist/src/shared/runbook/runbook.service.d.ts +0 -20
  127. package/dist/src/shared/runbook/runbook.service.js +0 -118
  128. package/dist/src/shared/runbook/runbook.service.js.map +0 -1
  129. package/dist/src/shared/runbook/runbook.templates.d.ts +0 -6
  130. package/dist/src/shared/runbook/runbook.templates.js +0 -49
  131. package/dist/src/shared/runbook/runbook.templates.js.map +0 -1
  132. package/dist/src/shared/tokenizer/tokenizer.module.d.ts +0 -2
  133. package/dist/src/shared/tokenizer/tokenizer.module.js +0 -21
  134. package/dist/src/shared/tokenizer/tokenizer.module.js.map +0 -1
  135. package/dist/src/shared/tokenizer/tokenizer.service.d.ts +0 -10
  136. package/dist/src/shared/tokenizer/tokenizer.service.js +0 -36
  137. package/dist/src/shared/tokenizer/tokenizer.service.js.map +0 -1
  138. package/dist/tsconfig.build.tsbuildinfo +0 -1
  139. package/docs/todo.md +0 -7
  140. package/knip.json +0 -10
  141. package/kodu.json +0 -63
  142. package/kodu.schema.json +0 -100
  143. package/lefthook.yml +0 -11
  144. package/nest-cli.json +0 -8
  145. package/registry.schema.json +0 -39
  146. package/scripts/generate-json-schema.ts +0 -27
  147. package/skills/ac/SKILL.md +0 -239
  148. package/skills/al/SKILL.md +0 -98
  149. package/skills/audit/SKILL.md +0 -205
  150. package/skills/audit/audit-baseline-template.yml +0 -188
  151. package/skills/audit/runtime-detect.md +0 -64
  152. package/skills/audit/stacks/_generic.md +0 -41
  153. package/skills/audit/stacks/_registry.md +0 -47
  154. package/skills/audit/stacks/go.md +0 -66
  155. package/skills/audit/stacks/java.md +0 -44
  156. package/skills/audit/stacks/node.md +0 -57
  157. package/skills/audit/stacks/python.md +0 -45
  158. package/skills/audit/stacks/rust.md +0 -44
  159. package/skills/audit-api-contracts/SKILL.md +0 -201
  160. package/skills/audit-architecture/SKILL.md +0 -200
  161. package/skills/audit-bugs/SKILL.md +0 -226
  162. package/skills/audit-concurrency/SKILL.md +0 -197
  163. package/skills/audit-deployment/SKILL.md +0 -218
  164. package/skills/audit-docs/SKILL.md +0 -209
  165. package/skills/audit-errors/SKILL.md +0 -216
  166. package/skills/audit-logging/SKILL.md +0 -197
  167. package/skills/audit-matrix/SKILL.md +0 -245
  168. package/skills/audit-meta/SKILL.md +0 -120
  169. package/skills/audit-naming/SKILL.md +0 -200
  170. package/skills/audit-owasp/SKILL.md +0 -223
  171. package/skills/audit-performance/SKILL.md +0 -199
  172. package/skills/audit-reinvention/SKILL.md +0 -214
  173. package/skills/audit-secrets/SKILL.md +0 -198
  174. package/skills/audit-tests/SKILL.md +0 -210
  175. package/skills/audit-validation/SKILL.md +0 -206
  176. package/skills/audit-verify/SKILL.md +0 -139
  177. package/skills/audit-yagni/SKILL.md +0 -188
  178. package/skills/doc-gen/SKILL.md +0 -490
  179. package/skills/doc-gen/scripts/doc_gen.py +0 -911
  180. package/skills/generate-project-docs/SKILL.md +0 -380
  181. package/skills/implement-project/SKILL.md +0 -409
  182. package/skills/liteend-init/SKILL.md +0 -84
  183. package/skills/litefront-init/SKILL.md +0 -96
  184. package/skills/litefront-prototype/SKILL.md +0 -484
  185. package/skills/ops/SKILL.md +0 -94
  186. package/skills/post-call-task-builder/SKILL.md +0 -419
  187. package/skills/project-setup-standardizer/SKILL.md +0 -285
  188. package/skills/skills-best-practices/SKILL.md +0 -415
  189. package/skills/start/SKILL.md +0 -319
  190. package/skills/tech-blueprint/SKILL.md +0 -890
  191. package/skills/tech-blueprint/scripts/blueprint_validator.py +0 -417
  192. package/src/app.module.ts +0 -29
  193. package/src/commands/clean/clean.command.ts +0 -235
  194. package/src/commands/clean/clean.module.ts +0 -13
  195. package/src/commands/init/init.command.ts +0 -92
  196. package/src/commands/init/init.module.ts +0 -9
  197. package/src/commands/ops/ops-add.command.ts +0 -83
  198. package/src/commands/ops/ops-init.command.ts +0 -125
  199. package/src/commands/ops/ops-list.command.ts +0 -57
  200. package/src/commands/ops/ops-path.command.ts +0 -38
  201. package/src/commands/ops/ops-runbook.command.ts +0 -74
  202. package/src/commands/ops/ops-status.command.ts +0 -47
  203. package/src/commands/ops/ops-use.command.ts +0 -76
  204. package/src/commands/ops/ops.command.ts +0 -42
  205. package/src/commands/ops/ops.helpers.ts +0 -20
  206. package/src/commands/ops/ops.module.ts +0 -23
  207. package/src/commands/pack/pack.command.ts +0 -347
  208. package/src/commands/pack/pack.module.ts +0 -14
  209. package/src/core/config/config.module.ts +0 -10
  210. package/src/core/config/config.schema.ts +0 -58
  211. package/src/core/config/config.service.ts +0 -43
  212. package/src/core/config/prompt.service.ts +0 -80
  213. package/src/core/file-system/fs.module.ts +0 -8
  214. package/src/core/file-system/fs.service.ts +0 -248
  215. package/src/core/registry/registry.module.ts +0 -9
  216. package/src/core/registry/registry.schema.ts +0 -46
  217. package/src/core/registry/registry.service.ts +0 -128
  218. package/src/core/ui/ui.module.ts +0 -9
  219. package/src/core/ui/ui.service.ts +0 -39
  220. package/src/main.ts +0 -12
  221. package/src/shared/cleaner/cleaner.service.ts +0 -289
  222. package/src/shared/cleaner/cleaner.types.ts +0 -23
  223. package/src/shared/constants.ts +0 -118
  224. package/src/shared/deps/deps.module.ts +0 -8
  225. package/src/shared/deps/deps.service.ts +0 -175
  226. package/src/shared/git/git.module.ts +0 -8
  227. package/src/shared/git/git.service.ts +0 -47
  228. package/src/shared/runbook/runbook.module.ts +0 -9
  229. package/src/shared/runbook/runbook.service.ts +0 -164
  230. package/src/shared/runbook/runbook.templates.ts +0 -66
  231. package/src/shared/tokenizer/tokenizer.module.ts +0 -8
  232. package/src/shared/tokenizer/tokenizer.service.ts +0 -30
  233. package/tsconfig.build.json +0 -7
  234. package/tsconfig.json +0 -28
@@ -1,102 +0,0 @@
1
- import { beforeEach, describe, expect, it, vi } from 'vitest';
2
- import { ConfigService } from '../../../src/core/config/config.service';
3
-
4
- vi.mock('../../../src/core/config/config.service', () => ({
5
- ConfigService: vi.fn().mockImplementation(() => ({
6
- getConfig: () => ({
7
- cleaner: {
8
- whitelist: [],
9
- keepJSDoc: false,
10
- useGitignore: false,
11
- },
12
- packer: {
13
- ignore: [],
14
- useGitignore: false,
15
- },
16
- }),
17
- })),
18
- }));
19
-
20
- vi.mock('../../../src/core/file-system/fs.service', () => ({
21
- FsService: vi.fn().mockImplementation(() => ({})),
22
- }));
23
-
24
- describe('CleanerService', () => {
25
- beforeEach(() => {
26
- vi.clearAllMocks();
27
- });
28
-
29
- it('should remove single-line comments', async () => {
30
- const { CleanerService } = await import(
31
- '../../../src/shared/cleaner/cleaner.service'
32
- );
33
- const configService = new ConfigService() as never;
34
- const fsService = {} as never;
35
- const cleaner = new CleanerService(configService, fsService);
36
-
37
- const input = `const x = 1; // comment
38
- const y = 2;`;
39
- const result = cleaner.cleanContent('test.ts', input);
40
-
41
- expect(result).toBe('const x = 1; \nconst y = 2;');
42
- });
43
-
44
- it('should remove multi-line comments', async () => {
45
- const { CleanerService } = await import(
46
- '../../../src/shared/cleaner/cleaner.service'
47
- );
48
- const configService = new ConfigService() as never;
49
- const fsService = {} as never;
50
- const cleaner = new CleanerService(configService, fsService);
51
-
52
- const input = `/* comment */
53
- const x = 1;`;
54
- const result = cleaner.cleanContent('test.ts', input);
55
-
56
- expect(result).toBe('\nconst x = 1;');
57
- });
58
-
59
- it('should preserve comments in whitelist', async () => {
60
- const { CleanerService } = await import(
61
- '../../../src/shared/cleaner/cleaner.service'
62
- );
63
- const configService = new ConfigService() as never;
64
- const fsService = {} as never;
65
- const cleaner = new CleanerService(configService, fsService);
66
-
67
- const input = `const x = 1; // eslint-disable-line
68
- const y = 2;`;
69
- const result = cleaner.cleanContent('test.ts', input);
70
-
71
- expect(result).toBe('const x = 1; // eslint-disable-line\nconst y = 2;');
72
- });
73
-
74
- it('should keep JSDoc when option is set', async () => {
75
- const { CleanerService } = await import(
76
- '../../../src/shared/cleaner/cleaner.service'
77
- );
78
- const configService = new ConfigService() as never;
79
- const fsService = {} as never;
80
- const cleaner = new CleanerService(configService, fsService);
81
-
82
- const input = `/** JSDoc */
83
- const x = 1;`;
84
- const result = cleaner.cleanContent('test.ts', input, true);
85
-
86
- expect(result).toBe('/** JSDoc */\nconst x = 1;');
87
- });
88
-
89
- it('should remove JSX expression without content', async () => {
90
- const { CleanerService } = await import(
91
- '../../../src/shared/cleaner/cleaner.service'
92
- );
93
- const configService = new ConfigService() as never;
94
- const fsService = {} as never;
95
- const cleaner = new CleanerService(configService, fsService);
96
-
97
- const input = `const x = <>{/* comment */}</>;`;
98
- const result = cleaner.cleanContent('test.tsx', input);
99
-
100
- expect(result).toBe('const x = <></>;');
101
- });
102
- });
@@ -1,84 +0,0 @@
1
- import { execa } from 'execa';
2
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
- import { GitService } from '../../../src/shared/git/git.service';
4
-
5
- vi.mock('execa');
6
-
7
- const mockExeca = vi.mocked(execa);
8
-
9
- describe('GitService', () => {
10
- let gitService: GitService;
11
-
12
- beforeEach(() => {
13
- vi.clearAllMocks();
14
- gitService = new GitService();
15
- });
16
-
17
- afterEach(() => {
18
- vi.resetAllMocks();
19
- });
20
-
21
- describe('ensureRepo', () => {
22
- it('should resolve when inside git repo', async () => {
23
- mockExeca.mockResolvedValue({ stdout: '' } as never);
24
-
25
- await expect(gitService.ensureRepo()).resolves.not.toThrow();
26
- });
27
-
28
- it('should reject when not in git repo', async () => {
29
- mockExeca.mockRejectedValue(new Error('fatal: not a git repository'));
30
-
31
- await expect(gitService.ensureRepo()).rejects.toThrow();
32
- });
33
- });
34
-
35
- describe('getChangedFiles', () => {
36
- it('should return empty array when no changes', async () => {
37
- mockExeca.mockResolvedValue({ stdout: '' } as never);
38
-
39
- const files = await gitService.getChangedFiles();
40
-
41
- expect(files).toEqual([]);
42
- });
43
-
44
- it('should return changed files from all sources', async () => {
45
- const mockCalls = [
46
- { stdout: '' }, // ensureRepo
47
- { stdout: 'src/a.ts\nsrc/b.ts' }, // diff
48
- { stdout: '' }, // diff --staged
49
- { stdout: '' }, // ls-files
50
- ];
51
- mockExeca
52
- .mockResolvedValueOnce(mockCalls[0] as never)
53
- .mockResolvedValueOnce(mockCalls[1] as never)
54
- .mockResolvedValueOnce(mockCalls[2] as never)
55
- .mockResolvedValueOnce(mockCalls[3] as never);
56
-
57
- const files = await gitService.getChangedFiles();
58
-
59
- expect(files).toEqual(['src/a.ts', 'src/b.ts']);
60
- });
61
- });
62
-
63
- describe('getStagedFiles', () => {
64
- it('should return empty array when no staged files', async () => {
65
- mockExeca
66
- .mockResolvedValueOnce({ stdout: '' } as never)
67
- .mockResolvedValueOnce({ stdout: '' } as never);
68
-
69
- const files = await gitService.getStagedFiles();
70
-
71
- expect(files).toEqual([]);
72
- });
73
-
74
- it('should return staged files', async () => {
75
- mockExeca
76
- .mockResolvedValueOnce({ stdout: '' } as never)
77
- .mockResolvedValueOnce({ stdout: 'src/new.ts' } as never);
78
-
79
- const files = await gitService.getStagedFiles();
80
-
81
- expect(files).toEqual(['src/new.ts']);
82
- });
83
- });
84
- });
@@ -1,104 +0,0 @@
1
- import { promises as fs } from 'node:fs';
2
- import os from 'node:os';
3
- import path from 'node:path';
4
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
- import { RunbookService } from '../../../src/shared/runbook/runbook.service';
6
-
7
- describe('RunbookService', () => {
8
- let root: string;
9
- const service = new RunbookService();
10
-
11
- beforeEach(async () => {
12
- root = await fs.mkdtemp(path.join(os.tmpdir(), 'kodu-runbook-'));
13
- });
14
-
15
- afterEach(async () => {
16
- await fs.rm(root, { recursive: true, force: true });
17
- });
18
-
19
- async function readGitignore(): Promise<string> {
20
- return fs.readFile(path.join(root, '.gitignore'), 'utf8');
21
- }
22
-
23
- describe('scaffold', () => {
24
- it('creates config.json and runbook.md', async () => {
25
- await service.scaffold(
26
- { project: 'demo', stands: ['local', 'dev'], activeStand: 'local' },
27
- root,
28
- );
29
-
30
- const config = await service.readConfig(root);
31
- expect(config.project).toBe('demo');
32
- expect(config.activeStand).toBe('local');
33
-
34
- const runbook = await service.readRunbook(root);
35
- expect(runbook).toContain('## Стенд: dev');
36
- });
37
-
38
- it('does not overwrite an existing runbook.md', async () => {
39
- await service.scaffold(
40
- { project: 'demo', stands: ['local'], activeStand: 'local' },
41
- root,
42
- );
43
- await fs.writeFile(service.runbookPath(root), 'ручные правки', 'utf8');
44
-
45
- await service.scaffold(
46
- { project: 'demo', stands: ['local'], activeStand: 'dev' },
47
- root,
48
- );
49
-
50
- expect(await service.readRunbook(root)).toBe('ручные правки');
51
- });
52
- });
53
-
54
- describe('ensureGitignore', () => {
55
- it('returns no-git outside a git repository', async () => {
56
- expect(await service.ensureGitignore(root)).toBe('no-git');
57
- await expect(
58
- fs.access(path.join(root, '.gitignore')),
59
- ).rejects.toBeTruthy();
60
- });
61
-
62
- it('creates .gitignore when missing in a git repo', async () => {
63
- await fs.mkdir(path.join(root, '.git'));
64
-
65
- expect(await service.ensureGitignore(root)).toBe('created');
66
- expect(await readGitignore()).toContain('/.runbook/');
67
- });
68
-
69
- it('appends to an existing .gitignore', async () => {
70
- await fs.mkdir(path.join(root, '.git'));
71
- await fs.writeFile(
72
- path.join(root, '.gitignore'),
73
- 'node_modules\n',
74
- 'utf8',
75
- );
76
-
77
- expect(await service.ensureGitignore(root)).toBe('added');
78
- const content = await readGitignore();
79
- expect(content).toContain('node_modules');
80
- expect(content).toContain('/.runbook/');
81
- });
82
-
83
- it('is idempotent — does not duplicate the entry', async () => {
84
- await fs.mkdir(path.join(root, '.git'));
85
- await fs.writeFile(path.join(root, '.gitignore'), '.runbook/\n', 'utf8');
86
-
87
- expect(await service.ensureGitignore(root)).toBe('present');
88
- const occurrences = (await readGitignore()).split('runbook').length - 1;
89
- expect(occurrences).toBe(1);
90
- });
91
- });
92
-
93
- describe('detectStack', () => {
94
- it('detects docker-compose and .env.example', async () => {
95
- await fs.writeFile(path.join(root, 'docker-compose.yml'), '', 'utf8');
96
- await fs.writeFile(path.join(root, '.env.example'), '', 'utf8');
97
-
98
- const detected = await service.detectStack(root);
99
- expect(detected.compose).toBe(true);
100
- expect(detected.envExample).toBe(true);
101
- expect(detected.dockerfile).toBe(false);
102
- });
103
- });
104
- });
@@ -1,45 +0,0 @@
1
- import { beforeEach, describe, expect, it } from 'vitest';
2
-
3
- describe('TokenizerService', () => {
4
- let tokenizer: {
5
- count: (text: string) => { tokens: number; usdEstimate: number };
6
- };
7
-
8
- beforeEach(async () => {
9
- const { TokenizerService } = await import(
10
- '../../../src/shared/tokenizer/tokenizer.service'
11
- );
12
- tokenizer = new TokenizerService();
13
- });
14
-
15
- it('should count tokens for empty string', () => {
16
- const result = tokenizer.count('');
17
-
18
- expect(result.tokens).toBe(0);
19
- expect(result.usdEstimate).toBe(0);
20
- });
21
-
22
- it('should count tokens for simple text', () => {
23
- const result = tokenizer.count('hello world');
24
-
25
- expect(result.tokens).toBeGreaterThan(0);
26
- expect(result.usdEstimate).toBeGreaterThan(0);
27
- });
28
-
29
- it('should estimate cost correctly based on DEFAULT_PRICE_PER_MILLION', () => {
30
- const result = tokenizer.count('a'.repeat(1000));
31
-
32
- expect(result.tokens).toBeGreaterThan(0);
33
- // DEFAULT_PRICE_PER_MILLION = 5 means $5 per 1M tokens
34
- const expectedCost = (result.tokens / 1_000_000) * 5;
35
- expect(result.usdEstimate).toBe(expectedCost);
36
- });
37
-
38
- it('should handle large text', () => {
39
- const longText = 'test '.repeat(10000);
40
- const result = tokenizer.count(longText);
41
-
42
- expect(result.tokens).toBeGreaterThan(10000);
43
- expect(result.usdEstimate).toBeGreaterThan(0);
44
- });
45
- });
package/biome.json DELETED
@@ -1,50 +0,0 @@
1
- {
2
- "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
3
- "assist": {
4
- "actions": {
5
- "source": {
6
- "organizeImports": "on"
7
- }
8
- }
9
- },
10
- "files": {
11
- "ignoreUnknown": false,
12
- "includes": ["**", "!**/node_modules", "!**/dist"]
13
- },
14
- "formatter": {
15
- "enabled": true,
16
- "indentStyle": "space",
17
- "lineEnding": "lf"
18
- },
19
- "javascript": {
20
- "formatter": {
21
- "quoteStyle": "single"
22
- },
23
- "parser": {
24
- "unsafeParameterDecoratorsEnabled": true
25
- }
26
- },
27
- "linter": {
28
- "enabled": true,
29
- "rules": {
30
- "correctness": {
31
- "noUnusedFunctionParameters": "error",
32
- "noUnusedImports": "error",
33
- "noUnusedVariables": "error"
34
- },
35
- "recommended": true,
36
- "style": {
37
- "noNonNullAssertion": "off",
38
- "useImportType": "off"
39
- },
40
- "suspicious": {
41
- "noPrototypeBuiltins": "off"
42
- }
43
- }
44
- },
45
- "vcs": {
46
- "clientKind": "git",
47
- "enabled": true,
48
- "useIgnoreFile": true
49
- }
50
- }
package/dist/package.json DELETED
@@ -1,96 +0,0 @@
1
- {
2
- "name": "kodu",
3
- "version": "2.2.0",
4
- "description": "High-performance CLI to prepare codebase for LLMs, automate reviews, and draft commits.",
5
- "repository": {
6
- "type": "git",
7
- "url": "git+https://github.com/uxname/kodu.git"
8
- },
9
- "bugs": {
10
- "url": "https://github.com/uxname/kodu/issues"
11
- },
12
- "homepage": "https://github.com/uxname/kodu#readme",
13
- "keywords": [
14
- "cli",
15
- "ai",
16
- "llm",
17
- "developer-tools",
18
- "productivity",
19
- "typescript",
20
- "openai",
21
- "automation",
22
- "code-review",
23
- "context-window",
24
- "git-tools"
25
- ],
26
- "private": false,
27
- "license": "MIT",
28
- "bin": {
29
- "kodu": "dist/src/main.js"
30
- },
31
- "scripts": {
32
- "________________ BUILD AND RUN ________________": "",
33
- "build": "nest build && chmod +x dist/src/main.js",
34
- "generate:schema": "ts-node scripts/generate-json-schema.ts",
35
- "postbuild": "npm run generate:schema",
36
- "start:prod": "node dist/main.js",
37
- "start:dev": "nest start --watch",
38
- "new:command": "nest g -c nest-commander-schematics command",
39
- "new:question": "nest g -c nest-commander-schematics question",
40
- "________________ FORMAT AND LINT ________________": "",
41
- "lint": "biome check",
42
- "lint:fix": "biome check --write",
43
- "lint:fix:unsafe": "biome check --write --unsafe",
44
- "ts:check": "tsc --noEmit",
45
- "knip": "knip --production",
46
- "check": "run-p ts:check lint:fix knip",
47
- "________________ TEST ________________": "",
48
- "test": "vitest run",
49
- "test:watch": "vitest",
50
- "test:cov": "vitest run --coverage",
51
- "________________ OTHER ________________": "",
52
- "prepare": "is-ci || lefthook install",
53
- "update": "npx npm-check-updates -u && rimraf node_modules package-lock.json && npm i",
54
- "postupdate": "npm run lint:fix && npm run check"
55
- },
56
- "dependencies": {
57
- "@inquirer/confirm": "^6.0.4",
58
- "@inquirer/input": "^5.0.4",
59
- "@inquirer/select": "^5.0.4",
60
- "@nestjs/common": "^11.0.1",
61
- "@nestjs/core": "^11.0.1",
62
- "clipboardy": "^5.0.2",
63
- "execa": "^9.6.1",
64
- "ignore": "^7.0.5",
65
- "js-tiktoken": "^1.0.21",
66
- "lilconfig": "^3.1.3",
67
- "nest-commander": "^3.20.1",
68
- "picocolors": "^1.1.1",
69
- "reflect-metadata": "^0.2.2",
70
- "rxjs": "^7.8.1",
71
- "source-map-support": "^0.5.21",
72
- "tinyglobby": "^0.2.15",
73
- "ts-morph": "^24.0.0",
74
- "yocto-spinner": "^1.0.0",
75
- "zod": "^4.3.6"
76
- },
77
- "devDependencies": {
78
- "@biomejs/biome": "^2.3.12",
79
- "@nestjs/cli": "^11.0.0",
80
- "@nestjs/schematics": "^11.0.0",
81
- "@nestjs/testing": "^11.0.1",
82
- "@types/node": "^22.10.7",
83
- "is-ci": "^4.1.0",
84
- "knip": "^5.82.1",
85
- "lefthook": "^2.0.15",
86
- "nest-commander-schematics": "^3.2.0",
87
- "npm-check-updates": "^18.3.1",
88
- "npm-run-all": "^4.1.5",
89
- "rimraf": "^6.1.3",
90
- "ts-loader": "^9.5.2",
91
- "ts-node": "^10.9.2",
92
- "tsconfig-paths": "^4.2.0",
93
- "typescript": "^5.7.3",
94
- "vitest": "^3.2.4"
95
- }
96
- }
@@ -1,2 +0,0 @@
1
- export declare class AppModule {
2
- }
@@ -1,42 +0,0 @@
1
- "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.AppModule = void 0;
10
- const common_1 = require("@nestjs/common");
11
- const clean_module_1 = require("./commands/clean/clean.module");
12
- const init_module_1 = require("./commands/init/init.module");
13
- const ops_module_1 = require("./commands/ops/ops.module");
14
- const pack_module_1 = require("./commands/pack/pack.module");
15
- const config_module_1 = require("./core/config/config.module");
16
- const fs_module_1 = require("./core/file-system/fs.module");
17
- const registry_module_1 = require("./core/registry/registry.module");
18
- const ui_module_1 = require("./core/ui/ui.module");
19
- const git_module_1 = require("./shared/git/git.module");
20
- const runbook_module_1 = require("./shared/runbook/runbook.module");
21
- const tokenizer_module_1 = require("./shared/tokenizer/tokenizer.module");
22
- let AppModule = class AppModule {
23
- };
24
- exports.AppModule = AppModule;
25
- exports.AppModule = AppModule = __decorate([
26
- (0, common_1.Module)({
27
- imports: [
28
- config_module_1.ConfigModule,
29
- ui_module_1.UiModule,
30
- fs_module_1.FsModule,
31
- git_module_1.GitModule,
32
- tokenizer_module_1.TokenizerModule,
33
- registry_module_1.RegistryModule,
34
- runbook_module_1.RunbookModule,
35
- init_module_1.InitModule,
36
- pack_module_1.PackModule,
37
- clean_module_1.CleanModule,
38
- ops_module_1.OpsModule,
39
- ],
40
- })
41
- ], AppModule);
42
- //# sourceMappingURL=app.module.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,gEAA4D;AAC5D,6DAAyD;AACzD,0DAAsD;AACtD,6DAAyD;AACzD,+DAA2D;AAC3D,4DAAwD;AACxD,qEAAiE;AACjE,mDAA+C;AAC/C,wDAAoD;AACpD,oEAAgE;AAChE,0EAAsE;AAiB/D,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,8BAAS;oBAAT,SAAS;IAfrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,4BAAY;YACZ,oBAAQ;YACR,oBAAQ;YACR,sBAAS;YACT,kCAAe;YACf,gCAAc;YACd,8BAAa;YACb,wBAAU;YACV,wBAAU;YACV,0BAAW;YACX,sBAAS;SACV;KACF,CAAC;GACW,SAAS,CAAG"}
@@ -1,37 +0,0 @@
1
- import { CommandRunner } from 'nest-commander';
2
- import { ConfigService } from '../../core/config/config.service';
3
- import { FsService } from '../../core/file-system/fs.service';
4
- import { UiService } from '../../core/ui/ui.service';
5
- import { CleanerService } from '../../shared/cleaner/cleaner.service';
6
- import { GitService } from '../../shared/git/git.service';
7
- type CleanOptions = {
8
- dryRun?: boolean;
9
- changed?: boolean;
10
- staged?: boolean;
11
- backup?: boolean;
12
- noJsdoc?: boolean;
13
- verbose?: boolean;
14
- stdin?: boolean;
15
- };
16
- export declare class CleanCommand extends CommandRunner {
17
- private readonly ui;
18
- private readonly fsService;
19
- private readonly cleaner;
20
- private readonly config;
21
- private readonly git;
22
- constructor(ui: UiService, fsService: FsService, cleaner: CleanerService, config: ConfigService, git: GitService);
23
- parseDryRun(): boolean;
24
- parseChanged(): boolean;
25
- parseStaged(): boolean;
26
- parseBackup(): boolean;
27
- parseNoJsdoc(): boolean;
28
- parseVerbose(): boolean;
29
- parseStdin(): boolean;
30
- run(inputs: string[], options?: CleanOptions): Promise<void>;
31
- private runStdin;
32
- private readStdin;
33
- private buildSpinnerText;
34
- private noFilesMessage;
35
- private collectTargets;
36
- }
37
- export {};