@dxtmisha/scripts 0.9.1 → 0.10.3

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 (49) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/package.json +2 -1
  3. package/src/classes/Ai/AiClaudeAgent.ts +16 -0
  4. package/src/classes/Ai/AiClaudeAgentLite.ts +86 -0
  5. package/src/classes/Ai/AiClaudeCliLite.ts +29 -65
  6. package/src/classes/Ai/AiClaudeLite.ts +19 -7
  7. package/src/classes/Ai/AiGoogleCliLite.ts +27 -64
  8. package/src/classes/Ai/AiOpenAi.ts +26 -0
  9. package/src/classes/Ai/AiOpenAiLite.ts +107 -0
  10. package/src/classes/Ai/AiZAi.ts +17 -0
  11. package/src/classes/Ai/AiZAiLite.ts +26 -0
  12. package/src/classes/Ai/ApiTmp.ts +43 -0
  13. package/src/classes/Build/BuildPackages.ts +33 -7
  14. package/src/classes/Design/DesignComponent.ts +1 -1
  15. package/src/classes/Design/DesignTypes.ts +7 -6
  16. package/src/classes/Design/DesignWikiStorm.ts +7 -7
  17. package/src/classes/Design/DesignWikiStormItem.ts +64 -34
  18. package/src/classes/Library/LibraryAiPrompt.ts +2 -2
  19. package/src/classes/Library/LibraryAiPromptItem.ts +37 -3
  20. package/src/composables/useAi.ts +15 -0
  21. package/src/config.ts +9 -7
  22. package/src/demo/ai.ts +10 -0
  23. package/src/library-ai.ts +4 -4
  24. package/src/library.ts +67 -54
  25. package/src/media/templates/componentDoc/materials/{prompt.txt → prompt.md} +4 -4
  26. package/src/media/templates/componentDoc/wiki/prompt.md +21 -0
  27. package/src/media/templates/componentDoc/wiki/run.ts +1 -1
  28. package/src/media/templates/packages/library/package.json +7 -5
  29. package/src/media/templates/prompts/aiCodeGlobalPrompt.en.md +77 -0
  30. package/src/media/templates/prompts/aiCodeGlobalPrompt.ru.md +78 -0
  31. package/src/types/configTypes.ts +9 -2
  32. package/src/types/webTypes.ts +33 -4
  33. package/src/classes/Component/__tests__/ComponentCreator.test.ts +0 -71
  34. package/src/classes/Component/__tests__/ComponentItem.test.ts +0 -71
  35. package/src/classes/Git/__tests__/GitRead.test.ts +0 -70
  36. package/src/composables/__tests__/useAi.test.ts +0 -75
  37. package/src/functions/__tests__/getComponentPaths.test.ts +0 -19
  38. package/src/functions/__tests__/getConfigAi.test.ts +0 -26
  39. package/src/functions/__tests__/getConstructorProperties.test.ts +0 -51
  40. package/src/functions/__tests__/getDirname.test.ts +0 -31
  41. package/src/functions/__tests__/getNameDirByPaths.test.ts +0 -40
  42. package/src/functions/__tests__/getPackageJson.test.ts +0 -34
  43. package/src/functions/__tests__/hasNativeDirname.test.ts +0 -18
  44. package/src/functions/__tests__/toPathStandardSep.test.ts +0 -31
  45. package/src/media/templates/componentDoc/wiki/prompt.txt +0 -16
  46. package/src/media/templates/prompts/aiCodeGlobalPrompt.en.txt +0 -40
  47. package/src/media/templates/prompts/aiCodeGlobalPrompt.ru.txt +0 -40
  48. /package/src/media/templates/prompts/{aiCodeVuePrompt.en.txt → aiCodeVuePrompt.en.md} +0 -0
  49. /package/src/media/templates/prompts/{aiCodeVuePrompt.ru.txt → aiCodeVuePrompt.ru.md} +0 -0
@@ -1,70 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { GitRead } from '../GitRead'
3
- import { execSync } from 'node:child_process'
4
- import { PropertiesFile } from '../../Properties/PropertiesFile'
5
-
6
- vi.mock('node:child_process', () => ({
7
- execSync: vi.fn()
8
- }))
9
-
10
- vi.mock('../../Properties/PropertiesFile', () => ({
11
- PropertiesFile: {
12
- getTime: vi.fn()
13
- }
14
- }))
15
-
16
- describe('GitRead', () => {
17
- beforeEach(() => {
18
- vi.clearAllMocks()
19
- })
20
-
21
- it('getDirPrefix should return the result of git rev-parse', () => {
22
- vi.mocked(execSync).mockReturnValue('packages/scripts/' as any)
23
- const result = GitRead.getDirPrefix()
24
- expect(execSync).toHaveBeenCalledWith('git rev-parse --show-prefix', expect.anything())
25
- expect(result).toBe('packages/scripts/')
26
- })
27
-
28
- it('getFilesPath should return list of HEAD files', () => {
29
- vi.mocked(execSync).mockReturnValue('file1.ts\nfile2.ts\n' as any)
30
- const result = GitRead.getFilesPath()
31
- expect(result).toEqual(['file1.ts', 'file2.ts'])
32
- })
33
-
34
- it('getList should return files with metadata', () => {
35
- vi.mocked(execSync).mockImplementation((cmd: string) => {
36
- if (cmd.startsWith('git rev-parse')) return 'prefix/' as any
37
- if (cmd.startsWith('git ls-tree')) return 'file.ts\n' as any
38
- if (cmd.startsWith('git log')) return '2023-10-27 12:00:00 +0300' as any
39
- return '' as any
40
- })
41
-
42
- const result = GitRead.getList()
43
- expect(result[0]).toMatchObject({
44
- path: 'file.ts',
45
- pathFull: 'prefix/file.ts',
46
- date: expect.stringContaining('2023-10-27')
47
- })
48
- })
49
-
50
- it('getListPorcelain should parse git status and metadata', () => {
51
- vi.mocked(execSync).mockImplementation((cmd: string) => {
52
- if (cmd.startsWith('git rev-parse')) return 'prefix/' as any
53
- if (cmd.startsWith('git status')) return 'M file.ts\nA new.ts\n' as any
54
- return '' as any
55
- })
56
- vi.mocked(PropertiesFile.getTime).mockReturnValue('2023-10-27 12:00:00' as any)
57
-
58
- const result = GitRead.getListPorcelain()
59
- expect(result).toHaveLength(2)
60
- expect(result[0]).toMatchObject({
61
- path: 'file.ts',
62
- status: 'M'
63
- })
64
- })
65
-
66
- it('splitPath should correctly split string', () => {
67
- expect(GitRead.splitPath('a/b/c')).toEqual(['a', 'b', 'c'])
68
- expect(GitRead.splitPath('/a/b/')).toEqual(['a', 'b'])
69
- })
70
- })
@@ -1,75 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { useAi } from '../useAi'
3
- import { PropertiesConfig } from '../../classes/Properties/PropertiesConfig'
4
- import { AiGoogle } from '../../classes/Ai/AiGoogle'
5
- import { AiGoogleCli } from '../../classes/Ai/AiGoogleCli'
6
-
7
- vi.mock('../../classes/Properties/PropertiesConfig', () => ({
8
- PropertiesConfig: {
9
- getAiType: vi.fn()
10
- }
11
- }))
12
-
13
- vi.mock('../../classes/Ai/AiGoogle', () => {
14
- return {
15
- AiGoogle: vi.fn().mockImplementation(function () {
16
- return { name: 'AiGoogleInstance' }
17
- })
18
- }
19
- })
20
-
21
- vi.mock('../../classes/Ai/AiGoogleCli', () => {
22
- return {
23
- AiGoogleCli: vi.fn().mockImplementation(function () {
24
- return { name: 'AiGoogleCliInstance' }
25
- })
26
- }
27
- })
28
-
29
- describe('useAi', () => {
30
- beforeEach(() => {
31
- vi.clearAllMocks()
32
- })
33
-
34
- it('should return an instance of AiGoogle when the type is gemini', () => {
35
- vi.mocked(PropertiesConfig.getAiType).mockReturnValue('gemini')
36
- const mockInstance = { name: 'AiGoogleInstance' }
37
- vi.mocked(AiGoogle).mockImplementation(function () {
38
- return mockInstance as any
39
- })
40
-
41
- const result = useAi()
42
-
43
- expect(result).toEqual(mockInstance)
44
- expect(AiGoogle).toHaveBeenCalled()
45
- })
46
-
47
- it('should return an instance of AiGoogleCli when the type is gemini-cli', () => {
48
- vi.mocked(PropertiesConfig.getAiType).mockReturnValue('gemini-cli')
49
- const mockInstance = { name: 'AiGoogleCliInstance' }
50
- vi.mocked(AiGoogleCli).mockImplementation(function () {
51
- return mockInstance as any
52
- })
53
-
54
- const result = useAi()
55
-
56
- expect(result).toEqual(mockInstance)
57
- expect(AiGoogleCli).toHaveBeenCalled()
58
- })
59
-
60
- it('should return undefined for an unknown type', () => {
61
- vi.mocked(PropertiesConfig.getAiType).mockReturnValue('unknown' as any)
62
-
63
- const result = useAi()
64
-
65
- expect(result).toBeUndefined()
66
- })
67
-
68
- it('should return undefined if no type is configured', () => {
69
- vi.mocked(PropertiesConfig.getAiType).mockReturnValue(undefined as any)
70
-
71
- const result = useAi()
72
-
73
- expect(result).toBeUndefined()
74
- })
75
- })
@@ -1,19 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { getComponentPaths } from '../getComponentPaths'
3
- import { UI_DIRS_COMPONENTS } from '../../config'
4
-
5
- describe('getComponentPaths', () => {
6
- it('should return an array containing UI_DIRS_COMPONENTS and the given path', () => {
7
- const path = 'test-component'
8
- const result = getComponentPaths(path)
9
-
10
- expect(result).toEqual([...UI_DIRS_COMPONENTS, path])
11
- })
12
-
13
- it('it should work with nested paths', () => {
14
- const path = 'nested/test-component'
15
- const result = getComponentPaths(path)
16
-
17
- expect(result).toEqual([...UI_DIRS_COMPONENTS, path])
18
- })
19
- })
@@ -1,26 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest'
2
- import { getConfigAi } from '../getConfigAi'
3
- import { PropertiesConfig } from '../../classes/Properties/PropertiesConfig'
4
-
5
- vi.mock('../../classes/Properties/PropertiesConfig', () => ({
6
- PropertiesConfig: {
7
- getAiKey: vi.fn(),
8
- getAiModel: vi.fn()
9
- }
10
- }))
11
-
12
- describe('getConfigAi', () => {
13
- it('should return AI key and model from PropertiesConfig', () => {
14
- const mockKey = 'test-key'
15
- const mockModel = 'test-model'
16
-
17
- vi.mocked(PropertiesConfig.getAiKey).mockReturnValue(mockKey)
18
- vi.mocked(PropertiesConfig.getAiModel).mockReturnValue(mockModel)
19
-
20
- const result = getConfigAi()
21
-
22
- expect(result).toEqual([mockKey, mockModel])
23
- expect(PropertiesConfig.getAiKey).toHaveBeenCalled()
24
- expect(PropertiesConfig.getAiModel).toHaveBeenCalled()
25
- })
26
- })
@@ -1,51 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { getConstructorProperties } from '../getConstructorProperties'
3
- import { PropertiesFile } from '../../classes/Properties/PropertiesFile'
4
- import { hasNativeDirname } from '../hasNativeDirname'
5
-
6
- vi.mock('../../classes/Properties/PropertiesFile', () => ({
7
- PropertiesFile: {
8
- readFile: vi.fn()
9
- }
10
- }))
11
-
12
- vi.mock('../hasNativeDirname', () => ({
13
- hasNativeDirname: vi.fn()
14
- }))
15
-
16
- describe('getConstructorProperties', () => {
17
- beforeEach(() => {
18
- vi.clearAllMocks()
19
- })
20
-
21
- it('should return properties for given constructor names', () => {
22
- const mockItem = { some: 'property' }
23
- vi.mocked(hasNativeDirname).mockReturnValue(true)
24
- vi.mocked(PropertiesFile.readFile).mockReturnValue(mockItem)
25
-
26
- const result = getConstructorProperties(['Button', 'Input'])
27
-
28
- expect(result).toEqual({
29
- Button: mockItem,
30
- Input: mockItem
31
- })
32
- expect(PropertiesFile.readFile).toHaveBeenCalledTimes(2)
33
- })
34
-
35
- it('should return an empty object if no constructors found or error occurs', () => {
36
- vi.mocked(hasNativeDirname).mockReturnValue(true)
37
- vi.mocked(PropertiesFile.readFile).mockReturnValue(undefined)
38
-
39
- const result = getConstructorProperties(['NonExistent'])
40
-
41
- expect(result).toEqual({})
42
- })
43
-
44
- it('should handles non-native dirname environment', () => {
45
- vi.mocked(hasNativeDirname).mockReturnValue(false)
46
- vi.mocked(PropertiesFile.readFile).mockReturnValue({ status: 'ok' })
47
-
48
- const result = getConstructorProperties(['Button'])
49
- expect(result).toEqual({ Button: { status: 'ok' } })
50
- })
51
- })
@@ -1,31 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { getDirname } from '../getDirname'
3
- import { hasNativeDirname } from '../hasNativeDirname'
4
-
5
- vi.mock('../hasNativeDirname', () => ({
6
- hasNativeDirname: vi.fn()
7
- }))
8
-
9
- // We can't easily mock import.meta.url or __dirname globally in a way that affects the module internally without ESM tricks,
10
- // but we can at least test that it calls the right path based on hasNativeDirname
11
- describe('getDirname', () => {
12
- beforeEach(() => {
13
- vi.clearAllMocks()
14
- })
15
-
16
- it('should return __dirname when hasNativeDirname is true', () => {
17
- vi.mocked(hasNativeDirname).mockReturnValue(true)
18
-
19
- // In a vitest environment with native support, __dirname should be defined
20
- // We expect it to not throw and return a string
21
- const result = getDirname()
22
- expect(typeof result).toBe('string')
23
- })
24
-
25
- it('should return a path via fileURLToPath when hasNativeDirname is false', () => {
26
- vi.mocked(hasNativeDirname).mockReturnValue(false)
27
-
28
- const result = getDirname()
29
- expect(typeof result).toBe('string')
30
- })
31
- })
@@ -1,40 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { getNameDirByPaths } from '../getNameDirByPaths'
3
- import { PropertiesFile } from '../../classes/Properties/PropertiesFile'
4
-
5
- vi.mock('../../classes/Properties/PropertiesFile', () => ({
6
- PropertiesFile: {
7
- splitForDir: vi.fn(),
8
- joinPath: vi.fn()
9
- }
10
- }))
11
-
12
- describe('getNameDirByPaths', () => {
13
- beforeEach(() => {
14
- vi.clearAllMocks()
15
- })
16
-
17
- it('should return the last directory name from provided paths', () => {
18
- const mockPaths = ['src', 'components', 'button']
19
- const mockJoinedPath = 'src/components/button'
20
- const mockSplitDirs = ['src', 'components', 'button']
21
-
22
- vi.mocked(PropertiesFile.joinPath).mockReturnValue(mockJoinedPath)
23
- vi.mocked(PropertiesFile.splitForDir).mockReturnValue(mockSplitDirs)
24
-
25
- const result = getNameDirByPaths(mockPaths)
26
-
27
- expect(result).toBe('button')
28
- expect(PropertiesFile.joinPath).toHaveBeenCalledWith(mockPaths)
29
- expect(PropertiesFile.splitForDir).toHaveBeenCalledWith(mockJoinedPath)
30
- })
31
-
32
- it('should work with a single path segment', () => {
33
- const mockPaths = ['root']
34
- vi.mocked(PropertiesFile.joinPath).mockReturnValue('root')
35
- vi.mocked(PropertiesFile.splitForDir).mockReturnValue(['root'])
36
-
37
- const result = getNameDirByPaths(mockPaths)
38
- expect(result).toBe('root')
39
- })
40
- })
@@ -1,34 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { getPackageJson } from '../getPackageJson'
3
- import { PropertiesFile } from '../../classes/Properties/PropertiesFile'
4
- import { UI_FILE_PACKAGE } from '../../config'
5
-
6
- vi.mock('../../classes/Properties/PropertiesFile', () => ({
7
- PropertiesFile: {
8
- readFile: vi.fn()
9
- }
10
- }))
11
-
12
- describe('getPackageJson', () => {
13
- beforeEach(() => {
14
- vi.clearAllMocks()
15
- })
16
-
17
- it('should return package.json content via PropertiesFile.readFile', () => {
18
- const mockContent = { name: 'test-package', version: '1.0.0' }
19
- vi.mocked(PropertiesFile.readFile).mockReturnValue(mockContent)
20
-
21
- const result = getPackageJson()
22
-
23
- expect(result).toEqual(mockContent)
24
- expect(PropertiesFile.readFile).toHaveBeenCalledWith(UI_FILE_PACKAGE)
25
- })
26
-
27
- it('should return undefined if file reading fails', () => {
28
- vi.mocked(PropertiesFile.readFile).mockReturnValue(undefined)
29
-
30
- const result = getPackageJson()
31
-
32
- expect(result).toBeUndefined()
33
- })
34
- })
@@ -1,18 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { hasNativeDirname } from '../hasNativeDirname'
3
-
4
- describe('hasNativeDirname', () => {
5
- it('should return a boolean', () => {
6
- const result = hasNativeDirname()
7
- expect(typeof result).toBe('boolean')
8
- })
9
-
10
- it('it should return true if __dirname is defined', () => {
11
- // In vitest/node environment, __dirname is usually defined
12
- // We can't easily "un-define" it for a negative test without complex environment manipulation,
13
- // but we can verify it returns true if it's there
14
- if (typeof __dirname !== 'undefined') {
15
- expect(hasNativeDirname()).toBe(true)
16
- }
17
- })
18
- })
@@ -1,31 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { toPathStandardSep } from '../toPathStandardSep'
3
- import requirePath from 'path'
4
-
5
- vi.mock('path', async (importOriginal) => {
6
- const actual = await importOriginal<typeof import('path')>()
7
- return {
8
- ...actual,
9
- default: {
10
- ...actual,
11
- sep: '/'
12
- }
13
- }
14
- })
15
-
16
- describe('toPathStandardSep', () => {
17
- beforeEach(() => {
18
- vi.clearAllMocks()
19
- vi.mocked(requirePath).sep = '/'
20
- })
21
-
22
- it('should replace all forward slashes with the platform-specific separator', () => {
23
- vi.mocked(requirePath).sep = '\\'
24
- expect(toPathStandardSep('src/components/button')).toBe('src\\components\\button')
25
- })
26
-
27
- it('should not change the path if it already uses the correct separator (unix)', () => {
28
- vi.mocked(requirePath).sep = '/'
29
- expect(toPathStandardSep('src/components/button')).toBe('src/components/button')
30
- })
31
- })
@@ -1,16 +0,0 @@
1
- Task Goal:
2
- The primary goal is to write comprehensive, high-quality documentation for the Vue 3 component.
3
-
4
- Component Resolution & Analysis:
5
- If the source files of the component were not directly attached or provided in the prompt, they are located in the parent directory (one folder above the current "wiki" folder). In this case, you must thoroughly locate and study the component's main Vue file, its properties/types files, styling sheets, and all reachable dependencies to fully understand its features, internal logic, and behavior in its entirety.
6
-
7
- Mandatory Instruction:
8
- You must read and strictly follow the basic rules, coding standards, and templates specified in:
9
- node_modules/@dxtmisha/scripts/src/media/templates/prompts/componentPrompt.en.txt
10
-
11
- All constraints, formatting standards, and styling helper classes described in that file must be adhered to without exception.
12
- (Warning: If this file is not accessible, missing, or cannot be read, you do not need to study or follow the instructions from it; instead, proceed with standard high-quality documentation practices.)
13
-
14
- ---
15
- CRITICAL PRIORITY RULE:
16
- Everything below this line has a higher priority than the text above it.
@@ -1,40 +0,0 @@
1
- ### Global Development Principles (AI Code Promise)
2
-
3
- Your primary goal is to generate flawless, industrial-grade code that adheres to dxt-ui standards. You promise to follow these rules strictly:
4
-
5
- 1. **"Copy-Paste Ready" Principle**:
6
- - Generate code that can be copied and run without a single manual edit.
7
- - All imports must be absolute or correct relative paths.
8
- - No `// ... rest of the code`, no `// imports here`. Only the complete, working file.
9
-
10
- 2. **Zero Tolerance for Hallucinations**:
11
- - Use only the libraries and versions specified in the project's `package.json`.
12
- - Do not invent API methods that do not exist in the current versions of dependencies.
13
- - If information is insufficient, it is better to ask or point out the limitation than to hallucinate.
14
-
15
- 3. **Clean Code Standards**:
16
- - **DRY & KISS**: Avoid duplication, write as simply and clearly as possible.
17
- - **SOLID**: Every module, class, or function must have one clear responsibility.
18
- - **Declarative Approach**: Prefer a declarative programming style (array functional methods, composition).
19
-
20
- 4. **Uncompromising TypeScript**:
21
- - No `any`. Use `unknown` if the type is truly unknown, or create generic types.
22
- - Always define interfaces for input and output data.
23
- - Use `as const`, `readonly`, and enums/union types to increase reliability.
24
-
25
- 5. **Professional Documentation (TSDoc)**:
26
- - Accompany all exported entities with TSDoc comments in the [wikiLanguage] language.
27
- - Describe the purpose, parameters, return values, and potential exceptions.
28
- - Usage examples in comments are encouraged for complex functions.
29
-
30
- 6. **Architectural Consistency**:
31
- - Respect the project structure. If it is standard in the project to move logic into `composables` or `utils`, follow that pattern.
32
- - Do not modify global styles or styles of base UI components unless explicitly requested.
33
-
34
- 7. **Security and Performance**:
35
- - Write error-proof code (guard clauses, optional chaining `?.`, nullish coalescing `??`).
36
- - Avoid redundant calculations in loops and heavy operations in reactive dependencies.
37
-
38
- 8. **Aesthetics and Conciseness**:
39
- - The code must be beautiful. Use logical indentation and group code by meaning.
40
- - Save tokens by avoiding redundant comments where the code speaks for itself.
@@ -1,40 +0,0 @@
1
- ### Глобальные принципы разработки (AI Code Promise)
2
-
3
- Твоя главная цель — генерировать безупречный, промышленный код, который соответствует стандартам dxt-ui. Ты обещаешь следовать этим правилам неукоснительно:
4
-
5
- 1. **Принцип «Copy-Paste Ready» (Готовность к использованию)**:
6
- - Генерируй код, который можно скопировать и запустить без единой правки.
7
- - Все импорты должны быть абсолютными или корректными относительными.
8
- - Никаких `// ... остальной код`, никаких `// импорты здесь`. Только полный, рабочий файл.
9
-
10
- 2. **Нулевая толерантность к галлюцинациям**:
11
- - Используй только те библиотеки и версии, которые указаны в `package.json` проекта.
12
- - Не выдумывай методы API, которых не существует в текущих версиях зависимостей.
13
- - Если информации недостаточно — лучше спроси или укажи на ограничение, чем галлюцинируй.
14
-
15
- 3. **Стандарты чистого кода (Clean Code)**:
16
- - **DRY & KISS**: Избегай дублирования, пиши максимально просто и понятно.
17
- - **SOLID**: Каждый модуль, класс или функция должны иметь одну четкую ответственность.
18
- - **Декларативность**: Отдавай предпочтение декларативному стилю программирования (функциональные методы массивов, композиция).
19
-
20
- 4. **Бескомпромиссный TypeScript**:
21
- - Никаких `any`. Используй `unknown`, если тип действительно неизвестен, или создавай generic-типы.
22
- - Всегда определяй интерфейсы для входных и выходных данных.
23
- - Используй `as const`, `readonly` и перечисления (enums/union types) для повышения надежности.
24
-
25
- 5. **Профессиональное документирование (TSDoc)**:
26
- - Сопровождай все экспортируемые сущности комментариями TSDoc на [wikiLanguage] языке.
27
- - Описывай назначение, параметры, возвращаемые значения и возможные исключения.
28
- - Примеры использования в комментариях приветствуются для сложных функций.
29
-
30
- 6. **Архитектурная консистентность**:
31
- - Соблюдай структуру проекта. Если в проекте принято выносить логику в `composables` или `utils` — следуй этому паттерну.
32
- - Не изменяй глобальные стили или стили базовых UI-компонентов, если это не было явно запрошено.
33
-
34
- 7. **Безопасность и Производительность**:
35
- - Пиши код, защищенный от ошибок (guard clauses, опциональная цепочка `?.`, nullish coalescing `??`).
36
- - Избегай лишних вычислений в циклах и тяжелых операций в реактивных зависимостях.
37
-
38
- 8. **Эстетика и Лаконичность**:
39
- - Код должен быть красивым. Используй логические отступы и группировку кода по смыслу.
40
- - Экономь токены, избегая избыточных комментариев там, где код говорит сам за себя.