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.
- package/README.md +24 -3
- package/bin/kodu.js +40 -0
- package/package.json +12 -67
- package/scripts/install.js +68 -0
- package/scripts/postinstall.js +22 -0
- package/AGENTS.md +0 -214
- package/__tests__/core/fs/fs.service.test.ts +0 -72
- package/__tests__/core/registry/registry.service.test.ts +0 -82
- package/__tests__/shared/cleaner/cleaner.service.test.ts +0 -102
- package/__tests__/shared/git/git.service.test.ts +0 -84
- package/__tests__/shared/runbook/runbook.service.test.ts +0 -104
- package/__tests__/shared/tokenizer/tokenizer.service.test.ts +0 -45
- package/biome.json +0 -50
- package/dist/package.json +0 -96
- package/dist/src/app.module.d.ts +0 -2
- package/dist/src/app.module.js +0 -42
- package/dist/src/app.module.js.map +0 -1
- package/dist/src/commands/clean/clean.command.d.ts +0 -37
- package/dist/src/commands/clean/clean.command.js +0 -240
- package/dist/src/commands/clean/clean.command.js.map +0 -1
- package/dist/src/commands/clean/clean.module.d.ts +0 -2
- package/dist/src/commands/clean/clean.module.js +0 -26
- package/dist/src/commands/clean/clean.module.js.map +0 -1
- package/dist/src/commands/init/init.command.d.ts +0 -10
- package/dist/src/commands/init/init.command.js +0 -96
- package/dist/src/commands/init/init.command.js.map +0 -1
- package/dist/src/commands/init/init.module.d.ts +0 -2
- package/dist/src/commands/init/init.module.js +0 -22
- package/dist/src/commands/init/init.module.js.map +0 -1
- package/dist/src/commands/ops/ops-add.command.d.ts +0 -18
- package/dist/src/commands/ops/ops-add.command.js +0 -102
- package/dist/src/commands/ops/ops-add.command.js.map +0 -1
- package/dist/src/commands/ops/ops-init.command.d.ts +0 -22
- package/dist/src/commands/ops/ops-init.command.js +0 -130
- package/dist/src/commands/ops/ops-init.command.js.map +0 -1
- package/dist/src/commands/ops/ops-list.command.d.ts +0 -12
- package/dist/src/commands/ops/ops-list.command.js +0 -73
- package/dist/src/commands/ops/ops-list.command.js.map +0 -1
- package/dist/src/commands/ops/ops-path.command.d.ts +0 -9
- package/dist/src/commands/ops/ops-path.command.js +0 -52
- package/dist/src/commands/ops/ops-path.command.js.map +0 -1
- package/dist/src/commands/ops/ops-runbook.command.d.ts +0 -12
- package/dist/src/commands/ops/ops-runbook.command.js +0 -81
- package/dist/src/commands/ops/ops-runbook.command.js.map +0 -1
- package/dist/src/commands/ops/ops-status.command.d.ts +0 -11
- package/dist/src/commands/ops/ops-status.command.js +0 -62
- package/dist/src/commands/ops/ops-status.command.js.map +0 -1
- package/dist/src/commands/ops/ops-use.command.d.ts +0 -12
- package/dist/src/commands/ops/ops-use.command.js +0 -76
- package/dist/src/commands/ops/ops-use.command.js.map +0 -1
- package/dist/src/commands/ops/ops.command.d.ts +0 -7
- package/dist/src/commands/ops/ops.command.js +0 -56
- package/dist/src/commands/ops/ops.command.js.map +0 -1
- package/dist/src/commands/ops/ops.helpers.d.ts +0 -2
- package/dist/src/commands/ops/ops.helpers.js +0 -11
- package/dist/src/commands/ops/ops.helpers.js.map +0 -1
- package/dist/src/commands/ops/ops.module.d.ts +0 -2
- package/dist/src/commands/ops/ops.module.js +0 -36
- package/dist/src/commands/ops/ops.module.js.map +0 -1
- package/dist/src/commands/pack/pack.command.d.ts +0 -51
- package/dist/src/commands/pack/pack.command.js +0 -355
- package/dist/src/commands/pack/pack.command.js.map +0 -1
- package/dist/src/commands/pack/pack.module.d.ts +0 -2
- package/dist/src/commands/pack/pack.module.js +0 -27
- package/dist/src/commands/pack/pack.module.js.map +0 -1
- package/dist/src/core/config/config.module.d.ts +0 -2
- package/dist/src/core/config/config.module.js +0 -23
- package/dist/src/core/config/config.module.js.map +0 -1
- package/dist/src/core/config/config.schema.d.ts +0 -19
- package/dist/src/core/config/config.schema.js +0 -56
- package/dist/src/core/config/config.schema.js.map +0 -1
- package/dist/src/core/config/config.service.d.ts +0 -7
- package/dist/src/core/config/config.service.js +0 -49
- package/dist/src/core/config/config.service.js.map +0 -1
- package/dist/src/core/config/prompt.service.d.ts +0 -10
- package/dist/src/core/config/prompt.service.js +0 -80
- package/dist/src/core/config/prompt.service.js.map +0 -1
- package/dist/src/core/file-system/fs.module.d.ts +0 -2
- package/dist/src/core/file-system/fs.module.js +0 -21
- package/dist/src/core/file-system/fs.module.js.map +0 -1
- package/dist/src/core/file-system/fs.service.d.ts +0 -27
- package/dist/src/core/file-system/fs.service.js +0 -203
- package/dist/src/core/file-system/fs.service.js.map +0 -1
- package/dist/src/core/registry/registry.module.d.ts +0 -2
- package/dist/src/core/registry/registry.module.js +0 -22
- package/dist/src/core/registry/registry.module.js.map +0 -1
- package/dist/src/core/registry/registry.schema.d.ts +0 -24
- package/dist/src/core/registry/registry.schema.js +0 -21
- package/dist/src/core/registry/registry.schema.js.map +0 -1
- package/dist/src/core/registry/registry.service.d.ts +0 -16
- package/dist/src/core/registry/registry.service.js +0 -91
- package/dist/src/core/registry/registry.service.js.map +0 -1
- package/dist/src/core/ui/ui.module.d.ts +0 -2
- package/dist/src/core/ui/ui.module.js +0 -22
- package/dist/src/core/ui/ui.module.js.map +0 -1
- package/dist/src/core/ui/ui.service.d.ts +0 -22
- package/dist/src/core/ui/ui.service.js +0 -43
- package/dist/src/core/ui/ui.service.js.map +0 -1
- package/dist/src/main.d.ts +0 -2
- package/dist/src/main.js +0 -16
- package/dist/src/main.js.map +0 -1
- package/dist/src/shared/cleaner/cleaner.service.d.ts +0 -23
- package/dist/src/shared/cleaner/cleaner.service.js +0 -223
- package/dist/src/shared/cleaner/cleaner.service.js.map +0 -1
- package/dist/src/shared/cleaner/cleaner.types.d.ts +0 -21
- package/dist/src/shared/cleaner/cleaner.types.js +0 -3
- package/dist/src/shared/cleaner/cleaner.types.js.map +0 -1
- package/dist/src/shared/constants.d.ts +0 -4
- package/dist/src/shared/constants.js +0 -113
- package/dist/src/shared/constants.js.map +0 -1
- package/dist/src/shared/deps/deps.module.d.ts +0 -2
- package/dist/src/shared/deps/deps.module.js +0 -21
- package/dist/src/shared/deps/deps.module.js.map +0 -1
- package/dist/src/shared/deps/deps.service.d.ts +0 -15
- package/dist/src/shared/deps/deps.service.js +0 -114
- package/dist/src/shared/deps/deps.service.js.map +0 -1
- package/dist/src/shared/git/git.module.d.ts +0 -2
- package/dist/src/shared/git/git.module.js +0 -21
- package/dist/src/shared/git/git.module.js.map +0 -1
- package/dist/src/shared/git/git.service.d.ts +0 -5
- package/dist/src/shared/git/git.service.js +0 -56
- package/dist/src/shared/git/git.service.js.map +0 -1
- package/dist/src/shared/runbook/runbook.module.d.ts +0 -2
- package/dist/src/shared/runbook/runbook.module.js +0 -22
- package/dist/src/shared/runbook/runbook.module.js.map +0 -1
- package/dist/src/shared/runbook/runbook.service.d.ts +0 -20
- package/dist/src/shared/runbook/runbook.service.js +0 -118
- package/dist/src/shared/runbook/runbook.service.js.map +0 -1
- package/dist/src/shared/runbook/runbook.templates.d.ts +0 -6
- package/dist/src/shared/runbook/runbook.templates.js +0 -49
- package/dist/src/shared/runbook/runbook.templates.js.map +0 -1
- package/dist/src/shared/tokenizer/tokenizer.module.d.ts +0 -2
- package/dist/src/shared/tokenizer/tokenizer.module.js +0 -21
- package/dist/src/shared/tokenizer/tokenizer.module.js.map +0 -1
- package/dist/src/shared/tokenizer/tokenizer.service.d.ts +0 -10
- package/dist/src/shared/tokenizer/tokenizer.service.js +0 -36
- package/dist/src/shared/tokenizer/tokenizer.service.js.map +0 -1
- package/dist/tsconfig.build.tsbuildinfo +0 -1
- package/docs/todo.md +0 -7
- package/knip.json +0 -10
- package/kodu.json +0 -63
- package/kodu.schema.json +0 -100
- package/lefthook.yml +0 -11
- package/nest-cli.json +0 -8
- package/registry.schema.json +0 -39
- package/scripts/generate-json-schema.ts +0 -27
- package/skills/ac/SKILL.md +0 -239
- package/skills/al/SKILL.md +0 -98
- package/skills/audit/SKILL.md +0 -205
- package/skills/audit/audit-baseline-template.yml +0 -188
- package/skills/audit/runtime-detect.md +0 -64
- package/skills/audit/stacks/_generic.md +0 -41
- package/skills/audit/stacks/_registry.md +0 -47
- package/skills/audit/stacks/go.md +0 -66
- package/skills/audit/stacks/java.md +0 -44
- package/skills/audit/stacks/node.md +0 -57
- package/skills/audit/stacks/python.md +0 -45
- package/skills/audit/stacks/rust.md +0 -44
- package/skills/audit-api-contracts/SKILL.md +0 -201
- package/skills/audit-architecture/SKILL.md +0 -200
- package/skills/audit-bugs/SKILL.md +0 -226
- package/skills/audit-concurrency/SKILL.md +0 -197
- package/skills/audit-deployment/SKILL.md +0 -218
- package/skills/audit-docs/SKILL.md +0 -209
- package/skills/audit-errors/SKILL.md +0 -216
- package/skills/audit-logging/SKILL.md +0 -197
- package/skills/audit-matrix/SKILL.md +0 -245
- package/skills/audit-meta/SKILL.md +0 -120
- package/skills/audit-naming/SKILL.md +0 -200
- package/skills/audit-owasp/SKILL.md +0 -223
- package/skills/audit-performance/SKILL.md +0 -199
- package/skills/audit-reinvention/SKILL.md +0 -214
- package/skills/audit-secrets/SKILL.md +0 -198
- package/skills/audit-tests/SKILL.md +0 -210
- package/skills/audit-validation/SKILL.md +0 -206
- package/skills/audit-verify/SKILL.md +0 -139
- package/skills/audit-yagni/SKILL.md +0 -188
- package/skills/doc-gen/SKILL.md +0 -490
- package/skills/doc-gen/scripts/doc_gen.py +0 -911
- package/skills/generate-project-docs/SKILL.md +0 -380
- package/skills/implement-project/SKILL.md +0 -409
- package/skills/liteend-init/SKILL.md +0 -84
- package/skills/litefront-init/SKILL.md +0 -96
- package/skills/litefront-prototype/SKILL.md +0 -484
- package/skills/ops/SKILL.md +0 -94
- package/skills/post-call-task-builder/SKILL.md +0 -419
- package/skills/project-setup-standardizer/SKILL.md +0 -285
- package/skills/skills-best-practices/SKILL.md +0 -415
- package/skills/start/SKILL.md +0 -319
- package/skills/tech-blueprint/SKILL.md +0 -890
- package/skills/tech-blueprint/scripts/blueprint_validator.py +0 -417
- package/src/app.module.ts +0 -29
- package/src/commands/clean/clean.command.ts +0 -235
- package/src/commands/clean/clean.module.ts +0 -13
- package/src/commands/init/init.command.ts +0 -92
- package/src/commands/init/init.module.ts +0 -9
- package/src/commands/ops/ops-add.command.ts +0 -83
- package/src/commands/ops/ops-init.command.ts +0 -125
- package/src/commands/ops/ops-list.command.ts +0 -57
- package/src/commands/ops/ops-path.command.ts +0 -38
- package/src/commands/ops/ops-runbook.command.ts +0 -74
- package/src/commands/ops/ops-status.command.ts +0 -47
- package/src/commands/ops/ops-use.command.ts +0 -76
- package/src/commands/ops/ops.command.ts +0 -42
- package/src/commands/ops/ops.helpers.ts +0 -20
- package/src/commands/ops/ops.module.ts +0 -23
- package/src/commands/pack/pack.command.ts +0 -347
- package/src/commands/pack/pack.module.ts +0 -14
- package/src/core/config/config.module.ts +0 -10
- package/src/core/config/config.schema.ts +0 -58
- package/src/core/config/config.service.ts +0 -43
- package/src/core/config/prompt.service.ts +0 -80
- package/src/core/file-system/fs.module.ts +0 -8
- package/src/core/file-system/fs.service.ts +0 -248
- package/src/core/registry/registry.module.ts +0 -9
- package/src/core/registry/registry.schema.ts +0 -46
- package/src/core/registry/registry.service.ts +0 -128
- package/src/core/ui/ui.module.ts +0 -9
- package/src/core/ui/ui.service.ts +0 -39
- package/src/main.ts +0 -12
- package/src/shared/cleaner/cleaner.service.ts +0 -289
- package/src/shared/cleaner/cleaner.types.ts +0 -23
- package/src/shared/constants.ts +0 -118
- package/src/shared/deps/deps.module.ts +0 -8
- package/src/shared/deps/deps.service.ts +0 -175
- package/src/shared/git/git.module.ts +0 -8
- package/src/shared/git/git.service.ts +0 -47
- package/src/shared/runbook/runbook.module.ts +0 -9
- package/src/shared/runbook/runbook.service.ts +0 -164
- package/src/shared/runbook/runbook.templates.ts +0 -66
- package/src/shared/tokenizer/tokenizer.module.ts +0 -8
- package/src/shared/tokenizer/tokenizer.service.ts +0 -30
- package/tsconfig.build.json +0 -7
- 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
|
-
}
|
package/dist/src/app.module.d.ts
DELETED
package/dist/src/app.module.js
DELETED
|
@@ -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 {};
|