opencode-conductor-cdd-plugin 1.0.0-beta.13

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 (91) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +163 -0
  3. package/README.test.md +51 -0
  4. package/dist/commands/implement.d.ts +1 -0
  5. package/dist/commands/implement.js +30 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +108 -0
  8. package/dist/index.test.d.ts +1 -0
  9. package/dist/index.test.js +122 -0
  10. package/dist/prompts/agent/cdd.md +41 -0
  11. package/dist/prompts/agent/implementer.md +22 -0
  12. package/dist/prompts/agent.md +23 -0
  13. package/dist/prompts/cdd/implement.json +4 -0
  14. package/dist/prompts/cdd/newTrack.json +4 -0
  15. package/dist/prompts/cdd/revert.json +4 -0
  16. package/dist/prompts/cdd/setup.json +4 -0
  17. package/dist/prompts/cdd/setup.test.d.ts +1 -0
  18. package/dist/prompts/cdd/setup.test.js +132 -0
  19. package/dist/prompts/cdd/setup.test.ts +168 -0
  20. package/dist/prompts/cdd/status.json +4 -0
  21. package/dist/prompts/strategies/delegate.md +11 -0
  22. package/dist/prompts/strategies/manual.md +9 -0
  23. package/dist/templates/code_styleguides/c.md +28 -0
  24. package/dist/templates/code_styleguides/cpp.md +46 -0
  25. package/dist/templates/code_styleguides/csharp.md +115 -0
  26. package/dist/templates/code_styleguides/dart.md +238 -0
  27. package/dist/templates/code_styleguides/general.md +23 -0
  28. package/dist/templates/code_styleguides/go.md +48 -0
  29. package/dist/templates/code_styleguides/html-css.md +49 -0
  30. package/dist/templates/code_styleguides/java.md +39 -0
  31. package/dist/templates/code_styleguides/javascript.md +51 -0
  32. package/dist/templates/code_styleguides/julia.md +27 -0
  33. package/dist/templates/code_styleguides/kotlin.md +41 -0
  34. package/dist/templates/code_styleguides/php.md +37 -0
  35. package/dist/templates/code_styleguides/python.md +37 -0
  36. package/dist/templates/code_styleguides/react.md +37 -0
  37. package/dist/templates/code_styleguides/ruby.md +39 -0
  38. package/dist/templates/code_styleguides/rust.md +44 -0
  39. package/dist/templates/code_styleguides/shell.md +35 -0
  40. package/dist/templates/code_styleguides/solidity.md +60 -0
  41. package/dist/templates/code_styleguides/sql.md +39 -0
  42. package/dist/templates/code_styleguides/swift.md +36 -0
  43. package/dist/templates/code_styleguides/typescript.md +43 -0
  44. package/dist/templates/code_styleguides/vue.md +38 -0
  45. package/dist/templates/code_styleguides/zig.md +27 -0
  46. package/dist/templates/workflow.md +336 -0
  47. package/dist/tools/background.d.ts +54 -0
  48. package/dist/tools/background.js +198 -0
  49. package/dist/tools/commands.d.ts +11 -0
  50. package/dist/tools/commands.js +80 -0
  51. package/dist/tools/commands.test.d.ts +1 -0
  52. package/dist/tools/commands.test.js +142 -0
  53. package/dist/tools/delegate.d.ts +3 -0
  54. package/dist/tools/delegate.js +45 -0
  55. package/dist/utils/autogenerateFlow.d.ts +65 -0
  56. package/dist/utils/autogenerateFlow.js +391 -0
  57. package/dist/utils/autogenerateFlow.test.d.ts +1 -0
  58. package/dist/utils/autogenerateFlow.test.js +610 -0
  59. package/dist/utils/bootstrap.d.ts +1 -0
  60. package/dist/utils/bootstrap.js +46 -0
  61. package/dist/utils/commandFactory.d.ts +11 -0
  62. package/dist/utils/commandFactory.js +69 -0
  63. package/dist/utils/commitMessages.d.ts +35 -0
  64. package/dist/utils/commitMessages.js +33 -0
  65. package/dist/utils/commitMessages.test.d.ts +1 -0
  66. package/dist/utils/commitMessages.test.js +79 -0
  67. package/dist/utils/configDetection.d.ts +7 -0
  68. package/dist/utils/configDetection.js +49 -0
  69. package/dist/utils/configDetection.test.d.ts +1 -0
  70. package/dist/utils/configDetection.test.js +119 -0
  71. package/dist/utils/contentGeneration.d.ts +10 -0
  72. package/dist/utils/contentGeneration.js +141 -0
  73. package/dist/utils/contentGeneration.test.d.ts +1 -0
  74. package/dist/utils/contentGeneration.test.js +147 -0
  75. package/dist/utils/contextAnalysis.d.ts +100 -0
  76. package/dist/utils/contextAnalysis.js +308 -0
  77. package/dist/utils/contextAnalysis.test.d.ts +1 -0
  78. package/dist/utils/contextAnalysis.test.js +307 -0
  79. package/dist/utils/gitNotes.d.ts +23 -0
  80. package/dist/utils/gitNotes.js +53 -0
  81. package/dist/utils/gitNotes.test.d.ts +1 -0
  82. package/dist/utils/gitNotes.test.js +105 -0
  83. package/dist/utils/ignoreMatcher.d.ts +9 -0
  84. package/dist/utils/ignoreMatcher.js +77 -0
  85. package/dist/utils/ignoreMatcher.test.d.ts +1 -0
  86. package/dist/utils/ignoreMatcher.test.js +126 -0
  87. package/dist/utils/stateManager.d.ts +10 -0
  88. package/dist/utils/stateManager.js +30 -0
  89. package/package.json +90 -0
  90. package/scripts/convert-legacy.cjs +17 -0
  91. package/scripts/postinstall.cjs +38 -0
@@ -0,0 +1,168 @@
1
+ import { describe, it, expect, beforeAll } from 'vitest';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+
5
+ describe('setup.json prompt structure', () => {
6
+ let setupPrompt: string;
7
+
8
+ beforeAll(() => {
9
+ const setupJsonPath = path.join(__dirname, 'setup.json');
10
+ const setupJson = JSON.parse(fs.readFileSync(setupJsonPath, 'utf-8'));
11
+ setupPrompt = setupJson.prompt;
12
+ });
13
+
14
+ describe('Autogenerate option mandate', () => {
15
+ const requiredText = 'E) Autogenerate and review';
16
+ const mandatoryInstructionPattern = /\*\*Mandatory:\*\*.*autogenerate and review/is;
17
+
18
+ it('should contain Section 2.1 (Product Guide) with autogenerate mandate', () => {
19
+ expect(setupPrompt).toContain('### 2.1 Generate Product Guide');
20
+
21
+ const section21Start = setupPrompt.indexOf('### 2.1 Generate Product Guide');
22
+ const section22Start = setupPrompt.indexOf('### 2.2 Generate Product Guidelines');
23
+ const section21 = setupPrompt.substring(section21Start, section22Start);
24
+
25
+ expect(section21).toMatch(mandatoryInstructionPattern);
26
+ expect(section21).toContain(requiredText);
27
+ });
28
+
29
+ it('should contain Section 2.2 (Product Guidelines) with autogenerate mandate', () => {
30
+ expect(setupPrompt).toContain('### 2.2 Generate Product Guidelines');
31
+
32
+ const section22Start = setupPrompt.indexOf('### 2.2 Generate Product Guidelines');
33
+ const section23Start = setupPrompt.indexOf('### 2.3 Define Technology Stack');
34
+ const section22 = setupPrompt.substring(section22Start, section23Start);
35
+
36
+ expect(section22).toMatch(mandatoryInstructionPattern);
37
+ expect(section22).toContain(requiredText);
38
+ });
39
+
40
+ it('should contain Section 2.3 (Tech Stack) with autogenerate mandate', () => {
41
+ expect(setupPrompt).toContain('### 2.3 Define Technology Stack');
42
+
43
+ const section23Start = setupPrompt.indexOf('### 2.3 Define Technology Stack');
44
+ const section24Start = setupPrompt.indexOf('### 2.4 Select Code Styleguides');
45
+ const section23 = setupPrompt.substring(section23Start, section24Start);
46
+
47
+ expect(section23).toMatch(mandatoryInstructionPattern);
48
+ expect(section23).toContain(requiredText);
49
+ });
50
+
51
+ it('should contain Section 2.4 (Code Styleguides) with autogenerate mandate', () => {
52
+ expect(setupPrompt).toContain('### 2.4 Select Code Styleguides');
53
+
54
+ const section24Start = setupPrompt.indexOf('### 2.4 Select Code Styleguides');
55
+ const section25Start = setupPrompt.indexOf('### 2.5 Define Workflow');
56
+ const section24 = setupPrompt.substring(section24Start, section25Start);
57
+
58
+ expect(section24).toMatch(mandatoryInstructionPattern);
59
+ expect(section24).toContain(requiredText);
60
+ });
61
+
62
+ it('should contain Section 2.5 (Workflow) with autogenerate mandate', () => {
63
+ expect(setupPrompt).toContain('### 2.5 Define Workflow');
64
+
65
+ const section25Start = setupPrompt.indexOf('### 2.5 Define Workflow');
66
+ const section30Start = setupPrompt.indexOf('## 3.0 INITIAL TRACK');
67
+ const section25 = setupPrompt.substring(section25Start, section30Start);
68
+
69
+ expect(section25).toMatch(mandatoryInstructionPattern);
70
+ expect(section25).toContain(requiredText);
71
+ });
72
+ });
73
+
74
+ describe('Sequential questioning instructions', () => {
75
+ const sequentialPattern = /ask questions sequentially.*one by one/is;
76
+
77
+ it('should enforce sequential questioning in Section 2.1', () => {
78
+ const section21Start = setupPrompt.indexOf('### 2.1 Generate Product Guide');
79
+ const section22Start = setupPrompt.indexOf('### 2.2 Generate Product Guidelines');
80
+ const section21 = setupPrompt.substring(section21Start, section22Start);
81
+
82
+ expect(section21).toMatch(sequentialPattern);
83
+ });
84
+
85
+ it('should enforce sequential questioning in Section 2.2', () => {
86
+ const section22Start = setupPrompt.indexOf('### 2.2 Generate Product Guidelines');
87
+ const section23Start = setupPrompt.indexOf('### 2.3 Define Technology Stack');
88
+ const section22 = setupPrompt.substring(section22Start, section23Start);
89
+
90
+ expect(section22).toMatch(sequentialPattern);
91
+ });
92
+
93
+ it('should enforce sequential questioning in Section 2.4', () => {
94
+ const section24Start = setupPrompt.indexOf('### 2.4 Select Code Styleguides');
95
+ const section25Start = setupPrompt.indexOf('### 2.5 Define Workflow');
96
+ const section24 = setupPrompt.substring(section24Start, section25Start);
97
+
98
+ expect(section24).toMatch(sequentialPattern);
99
+ });
100
+
101
+ it('should enforce sequential questioning in Section 2.5', () => {
102
+ const section25Start = setupPrompt.indexOf('### 2.5 Define Workflow');
103
+ const section30Start = setupPrompt.indexOf('## 3.0 INITIAL TRACK');
104
+ const section25 = setupPrompt.substring(section25Start, section30Start);
105
+
106
+ expect(section25).toMatch(sequentialPattern);
107
+ });
108
+ });
109
+
110
+ describe('Basic prompt structure validation', () => {
111
+ it('should have description field', () => {
112
+ const setupJsonPath = path.join(__dirname, 'setup.json');
113
+ const setupJson = JSON.parse(fs.readFileSync(setupJsonPath, 'utf-8'));
114
+
115
+ expect(setupJson).toHaveProperty('description');
116
+ expect(setupJson.description).toBeTruthy();
117
+ });
118
+
119
+ it('should have prompt field', () => {
120
+ const setupJsonPath = path.join(__dirname, 'setup.json');
121
+ const setupJson = JSON.parse(fs.readFileSync(setupJsonPath, 'utf-8'));
122
+
123
+ expect(setupJson).toHaveProperty('prompt');
124
+ expect(setupJson.prompt).toBeTruthy();
125
+ expect(typeof setupJson.prompt).toBe('string');
126
+ });
127
+
128
+ it('should contain all major setup phases', () => {
129
+ expect(setupPrompt).toContain('## 1.0 SYSTEM DIRECTIVE');
130
+ expect(setupPrompt).toContain('## 1.1 BEGIN `RESUME` CHECK');
131
+ expect(setupPrompt).toContain('## 1.3 PROJECT MATURITY DETECTION');
132
+ expect(setupPrompt).toContain('## 2.0 INITIALIZATION PHASE');
133
+ expect(setupPrompt).toContain('## 3.0 INITIAL TRACK');
134
+ expect(setupPrompt).toContain('## 4.0 COMPLETION');
135
+ });
136
+
137
+ it('should contain all 5 interactive sections', () => {
138
+ expect(setupPrompt).toContain('### 2.1 Generate Product Guide');
139
+ expect(setupPrompt).toContain('### 2.2 Generate Product Guidelines');
140
+ expect(setupPrompt).toContain('### 2.3 Define Technology Stack');
141
+ expect(setupPrompt).toContain('### 2.4 Select Code Styleguides');
142
+ expect(setupPrompt).toContain('### 2.5 Define Workflow');
143
+ });
144
+ });
145
+
146
+ describe('Backward compatibility', () => {
147
+ it('should maintain existing resume logic', () => {
148
+ expect(setupPrompt).toContain('last_successful_step');
149
+ expect(setupPrompt).toContain('setup_state.json');
150
+ expect(setupPrompt).toContain('2.1_product_guide');
151
+ expect(setupPrompt).toContain('2.2_product_guidelines');
152
+ expect(setupPrompt).toContain('2.3_tech_stack');
153
+ expect(setupPrompt).toContain('2.4_code_styleguides');
154
+ expect(setupPrompt).toContain('2.5_workflow');
155
+ });
156
+
157
+ it('should maintain brownfield detection logic', () => {
158
+ expect(setupPrompt).toContain('BROWNFIELD');
159
+ expect(setupPrompt).toContain('GREENFIELD');
160
+ expect(setupPrompt).toContain('PROJECT MATURITY DETECTION');
161
+ });
162
+
163
+ it('should allow manual Q&A flow (no hard requirement for autogenerate)', () => {
164
+ expect(setupPrompt).not.toContain('MUST autogenerate');
165
+ expect(setupPrompt).not.toContain('MUST use autogenerate');
166
+ });
167
+ });
168
+ });
@@ -0,0 +1,4 @@
1
+ {
2
+ "description": "Displays the current progress of the project",
3
+ "prompt": "## 1.0 SYSTEM DIRECTIVE\nYou are an AI agent. Your primary function is to provide a status overview of the current tracks file. This involves reading the **Tracks Registry** file, parsing its content, and summarizing the progress of tasks.\n\nCRITICAL: You must validate the success of every tool call. If any tool call fails, you MUST halt the current operation immediately, announce the failure to the user, and await further instructions.\n\n---\n\n\n## 1.1 SETUP CHECK\n**PROTOCOL: Verify that the Orchestrator environment is properly set up.**\n\n1. **Verify Core Context:** Using the **Universal File Resolution Protocol**, resolve and verify the existence of:\n - **Tracks Registry**\n - **Product Definition**\n - **Tech Stack**\n - **Workflow**\n\n2. **Handle Failure:**\n - If ANY of these files are missing, you MUST halt the operation immediately.\n - Announce: \"Orchestrator is not set up. Please run `/orchestrator:setup` to set up the environment.\"\n - Do NOT proceed to Status Overview Protocol.\n\n---\n\n## 2.0 STATUS OVERVIEW PROTOCOL\n**PROTOCOL: Follow this sequence to provide a status overview.**\n\n**TOKEN BUDGET RULES:**\n- Default to a concise summary (counts of tracks and task statuses).\n- Only read full plan files if the user explicitly asks for details.\n- For any file larger than 1MB, read only the first and last 20 lines.\n\n### 2.1 Read Project Plan\n1. **Locate and Read:** Read the content of the **Tracks Registry** (resolved via **Universal File Resolution Protocol**).\n2. **Locate and Read Tracks:**\n - Parse the **Tracks Registry** to identify all registered tracks and their paths.\n * **Parsing Logic:** When reading the **Tracks Registry** to identify tracks, look for lines matching either the new standard format `- [ ] **Track:` or the legacy format `## [ ] Track:`.\n - For each track, resolve and read its **Implementation Plan** (using **Universal File Resolution Protocol** via the track's index file).\n\n### 2.2 Parse and Summarize Plan\n1. **Parse Content:**\n - Identify major project phases/sections (e.g., top-level markdown headings).\n - Identify individual tasks and their current status (e.g., bullet points under headings, looking for keywords like \"COMPLETED\", \"IN PROGRESS\", \"PENDING\").\n2. **Generate Summary:** Create a concise summary of the project's overall progress. This should include:\n - The total number of major phases.\n - The total number of tasks.\n - The number of tasks completed, in progress, and pending.\n\n### 2.3 Present Status Overview\n1. **Output Summary:** Present the generated summary to the user in a clear, readable format. The status report must include:\n - **Current Date/Time:** The current timestamp.\n - **Project Status:** A high-level summary of progress (e.g., \"On Track\", \"Behind Schedule\", \"Blocked\").\n - **Current Phase and Task:** The specific phase and task currently marked as \"IN PROGRESS\".\n - **Next Action Needed:** The next task listed as \"PENDING\".\n - **Blockers:** Any items explicitly marked as blockers in the plan.\n - **Phases (total):** The total number of major phases.\n - **Tasks (total):** The total number of tasks.\n - **Progress:** The overall progress of the plan, presented as tasks_completed/tasks_total (percentage_completed%).\n\n"
4
+ }
@@ -0,0 +1,11 @@
1
+ **MODE: SYNERGY (Architectural Delegation)**
2
+ You are acting as the **Architect**. Your responsibility is to oversee the track while delegating execution to **Sisyphus**.
3
+
4
+ **DIRECTIVE:**
5
+ 1. **Do NOT implement code yourself.**
6
+ 2. **Delegate:** For each task in `plan.md`, call `@sisyphus`.
7
+ * *Note:* The system will automatically inject the full project context for you.
8
+ * *Instruction:* Tell Sisyphus: "Execute this task. You have authority to update `plan.md` if needed. Report 'PLAN_UPDATED' if you do."
9
+ 3. **Verify:**
10
+ * If Sisyphus reports 'PLAN_UPDATED', you MUST **reload** `plan.md` before the next task.
11
+ * If success, verify against the plan and proceed to the next task.
@@ -0,0 +1,9 @@
1
+ **MODE: STANDARD (Manual Implementation)**
2
+ You are acting as the **Developer**. Your responsibility is to implement the code, tests, and documentation yourself.
3
+
4
+ **DIRECTIVE:**
5
+ 1. **Implement Manually:** Loop through each task in `plan.md` one by one.
6
+ 2. **Workflow:** Follow the `workflow.md` TDD protocol precisely (Red -> Green -> Refactor).
7
+ 3. **Commits:**
8
+ * **AUTHORITY OVERRIDE:** You have explicit authority to create Git commits as defined in the workflow.
9
+ * Do not ask for further permission for the granular task commits defined in `workflow.md`.
@@ -0,0 +1,28 @@
1
+ # C Style Guide Summary
2
+
3
+ This document summarizes key rules and best practices for C development, based on the GNU Coding Standards and common industrial practices.
4
+
5
+ ## 1. Naming Conventions
6
+ - **Files**: `snake_case.c` and `snake_case.h`.
7
+ - **Functions**: `snake_case()` (e.g., `calculate_total`).
8
+ - **Variables**: `snake_case` (e.g., `user_id`).
9
+ - **Constants**: `UPPER_CASE_WITH_UNDERSCORES` (e.g., `BUFFER_SIZE`).
10
+ - **Types (typedefs)**: `snake_case_t` (e.g., `config_t`).
11
+
12
+ ## 2. Formatting
13
+ - **Indentation**: 2 or 4 spaces (be consistent).
14
+ - **Braces**: Use the standard K&R style or Allman style, as long as it is consistent throughout the project.
15
+ - **Line Length**: Limit lines to 80 characters.
16
+
17
+ ## 3. Programming Practices
18
+ - **Header Guards**: Always use `#ifndef HEADER_NAME_H` guards.
19
+ - **Memory Management**: Always check the return value of `malloc`, `calloc`, and `realloc`. Always `free` dynamically allocated memory.
20
+ - **Pointers**: Initialize pointers to `NULL` if they are not immediately assigned a valid address.
21
+ - **Error Handling**: Use return codes (e.g., `int` with `0` for success) for error propagation.
22
+
23
+ ## 4. Documentation
24
+ - Use `/* ... */` for block comments.
25
+ - Use `//` for short, single-line comments (C99 and later).
26
+ - Document function parameters and return values in the header file.
27
+
28
+ *Source: [GNU Coding Standards](https://www.gnu.org/prep/standards/)*
@@ -0,0 +1,46 @@
1
+ # C++ Style Guide Summary
2
+
3
+ This document summarizes key rules and best practices for modern C++ development, based on the Google C++ Style Guide and the C++ Core Guidelines.
4
+
5
+ ## 1. Naming Conventions
6
+ - **Files**: `snake_case.cc` and `snake_case.h`.
7
+ - **Types (Classes, Structs, Type Aliases, Enums)**: `UpperCamelCase` (e.g., `HttpRequest`).
8
+ - **Variables (Local and Class Members)**: `lowerCamelCase` (e.g., `localVariable`).
9
+ - *Note: Some styles use `snake_case` or `trailing_underscore_` for private members.*
10
+ - **Functions & Methods**: `UpperCamelCase` (e.g., `OpenFile`).
11
+ - **Constants**: `kUpperCamelCase` (e.g., `kDaysInAWeek`).
12
+ - **Namespaces**: `lower_snake_case`.
13
+
14
+ ## 2. Header Files
15
+ - **Self-contained Headers**: Headers should be self-contained and have `#define` guards (e.g., `PROJECT_PATH_FILE_H_`).
16
+ - **Include Order**:
17
+ 1. Related header
18
+ 2. C system headers
19
+ 3. C++ library headers
20
+ 4. Other library headers
21
+ 5. Project headers
22
+
23
+ ## 3. Scoping and Classes
24
+ - **Namespaces**: Wrap code in namespaces to avoid name collisions. Do not use `using namespace std;` in header files.
25
+ - **Classes**:
26
+ - Keep constructors small. Use `explicit` for single-argument constructors.
27
+ - Avoid complex initialization in constructors; use an `Init()` method if necessary.
28
+ - Mark overriding methods with `override`.
29
+ - **Structs vs. Classes**: Use `struct` only for passive data carriers (POD). Everything else should be a `class`.
30
+
31
+ ## 4. Modern C++ Features (C++11 and later)
32
+ - **`auto`**: Use `auto` to avoid repeating type names, but only when it improves readability.
33
+ - **Smart Pointers**: Prefer `std::unique_ptr` for ownership. Use `std::shared_ptr` only when ownership must be shared. Never use `std::auto_ptr`.
34
+ - **`nullptr`**: Always use `nullptr` instead of `NULL` or `0`.
35
+ - **Brace Initialization**: Use `{}` for initialization where appropriate.
36
+
37
+ ## 5. Memory Management
38
+ - **Avoid Raw Pointers**: Use smart pointers or references.
39
+ - **RAII**: Resource Acquisition Is Initialization is a fundamental pattern. Manage resources (memory, file handles, locks) via object lifetimes.
40
+
41
+ ## 6. Formatting
42
+ - **Indentation**: 2 spaces (Google style).
43
+ - **Line Length**: 80 characters limit is preferred.
44
+ - **Braces**: Opening brace on the same line as the statement.
45
+
46
+ *Source: [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)*
@@ -0,0 +1,115 @@
1
+ # Google C# Style Guide Summary
2
+
3
+ This document summarizes key rules and best practices from the Google C# Style Guide.
4
+
5
+ ## 1. Naming Conventions
6
+ - **PascalCase:** For class names, method names, constants, properties, namespaces, and public fields.
7
+ - Example: `MyClass`, `GetValue()`, `MaxValue`
8
+ - **_camelCase:** For private, internal, and protected fields (with leading underscore).
9
+ - Example: `_myField`, `_internalState`
10
+ - **camelCase:** For local variables and parameters.
11
+ - Example: `localVariable`, `methodParameter`
12
+ - **Interfaces:** Prefix with `I` (e.g., `IMyInterface`).
13
+ - **Type Parameters:** Use descriptive names prefixed with `T` (e.g., `TValue`, `TKey`), or just `T` for simple cases.
14
+
15
+ ## 2. Formatting Rules
16
+ - **Indentation:** Use 2 spaces (never tabs).
17
+ - **Braces:** K&R style—no line break before the opening brace; keep `} else` on one line; braces required even when optional.
18
+ ```csharp
19
+ if (condition) {
20
+ DoSomething();
21
+ } else {
22
+ DoSomethingElse();
23
+ }
24
+ ```
25
+ - **Line Length:** Column limit 100.
26
+ - **One Statement Per Line:** Each statement on its own line.
27
+
28
+ ## 3. Declaration Order
29
+ Class member ordering:
30
+ - Group members in this order:
31
+ 1. Nested classes, enums, delegates, and events
32
+ 2. Static, const, and readonly fields
33
+ 3. Fields and properties
34
+ 4. Constructors and finalizers
35
+ 5. Methods
36
+ - Within each group, order by accessibility:
37
+ 1. Public
38
+ 2. Internal
39
+ 3. Protected internal
40
+ 4. Protected
41
+ 5. Private
42
+ - Where possible, group interface implementations together.
43
+
44
+ ## 4. Language Features
45
+ - **var:** Use of `var` is encouraged if it aids readability by avoiding type names that are noisy, obvious, or unimportant. Prefer explicit types when it improves clarity.
46
+ ```csharp
47
+ var apple = new Apple(); // Good - type is obvious
48
+ bool success = true; // Preferred over var for basic types
49
+ ```
50
+ - **Expression-bodied Members:** Use sparingly for simple properties and lambdas; don't use on method definitions.
51
+ ```csharp
52
+ public int Age => _age;
53
+ // Methods: prefer block bodies.
54
+ ```
55
+ - **String Interpolation:** In general, use whatever is easiest to read, particularly for logging and assert messages.
56
+ - Be aware that chained `operator+` concatenations can be slower and cause memory churn.
57
+ - If performance is a concern, `StringBuilder` can be faster for multiple concatenations.
58
+ ```csharp
59
+ var message = $"Hello, {name}!";
60
+ ```
61
+ - **Collection Initializers:** Use collection and object initializers when appropriate.
62
+ ```csharp
63
+ var list = new List<int> { 1, 2, 3 };
64
+ ```
65
+ - **Null-conditional Operators:** Use `?.` and `??` to simplify null checks.
66
+ ```csharp
67
+ var length = text?.Length ?? 0;
68
+ ```
69
+ - **Pattern Matching:** Use pattern matching for type checks and casts.
70
+ ```csharp
71
+ if (obj is string str) { /* use str */ }
72
+ ```
73
+
74
+ ## 5. Best Practices
75
+ - **Structs vs Classes**:
76
+ - Almost always use a class.
77
+ - Consider structs only for small, value-like types that are short-lived or frequently embedded.
78
+ - Performance considerations may justify deviations from this guidance.
79
+ - **Access Modifiers:** Always explicitly declare access modifiers (don't rely on defaults).
80
+ - **Ordering Modifiers:** Use standard order: `public protected internal private new abstract virtual override sealed static readonly extern unsafe volatile async`.
81
+ - **Namespace Imports:** Place `using` directives at the top of the file (outside namespaces); `System` first, then alphabetical.
82
+ - **Constants:** Always make variables `const` when possible; if not, use `readonly`. Prefer named constants over magic numbers.
83
+ - **IEnumerable vs IList vs IReadOnlyList:** When method inputs are intended to be immutable, prefer the most restrictive collection type possible (e.g., IEnumerable, IReadOnlyList); for return values, prefer IList when transferring ownership of a mutable collection, and otherwise prefer the most restrictive option.
84
+ - **Array vs List:** Prefer `List<>` for public variables, properties, and return types. Use arrays when size is fixed and known at construction time, or for multidimensional arrays.
85
+ - **Extension Methods:** Only use when the source is unavailable or changing it is infeasible. Only for core, general features. Be aware they obfuscate code.
86
+ - **LINQ:** Use LINQ for readability, but be mindful of performance in hot paths.
87
+
88
+ ## 6. File Organization
89
+ - **One Class Per File:** Typically one class, interface, enum, or struct per file.
90
+ - **File Name:** Prefer the file name to match the name of the primary type it contains.
91
+ - **Folders and File Locations:**
92
+ - Be consistent within the project.
93
+ - Prefer a flat folder structure where possible.
94
+ - Don’t force file/folder layout to match namespaces.
95
+ - **Namespaces:**
96
+ - In general, namespaces should be no more than 2 levels deep.
97
+ - For shared library/module code, use namespaces.
98
+ - For leaf application code, namespaces are not necessary.
99
+ - New top-level namespace names must be globally unique and recognizable.
100
+
101
+ ## 7. Parameters and Returns
102
+ - **out Parameters:** Permitted for output-only values; place `out` parameters after all other parameters. Prefer tuples or return types when they improve clarity.
103
+ - **Argument Clarity:** When argument meaning is nonobvious, use named constants, replace `bool` with `enum`, use named arguments, or create a configuration class/struct.
104
+ ```csharp
105
+ // Bad
106
+ DecimalNumber product = CalculateProduct(values, 7, false, null);
107
+
108
+ // Good
109
+ var options = new ProductOptions { PrecisionDecimals = 7, UseCache = CacheUsage.DontUseCache };
110
+ DecimalNumber product = CalculateProduct(values, options, completionDelegate: null);
111
+ ```
112
+
113
+ **BE CONSISTENT.** When editing code, follow the existing style in the codebase.
114
+
115
+ *Source: [Google C# Style Guide](https://google.github.io/styleguide/csharp-style.html)*
@@ -0,0 +1,238 @@
1
+ # Dart Code Style Guide
2
+
3
+ This guide summarizes key recommendations from the official Effective Dart documentation, covering style, documentation, language usage, and API design principles. Adhering to these guidelines promotes consistent, readable, and maintainable Dart code.
4
+
5
+ ## 1. Style
6
+
7
+ ### 1.1. Identifiers
8
+
9
+ - **DO** name types, extensions, and enum types using `UpperCamelCase`.
10
+ - **DO** name packages, directories, and source files using `lowercase_with_underscores`.
11
+ - **DO** name import prefixes using `lowercase_with_underscores`.
12
+ - **DO** name other identifiers (class members, top-level definitions, variables, parameters) using `lowerCamelCase`.
13
+ - **PREFER** using `lowerCamelCase` for constant names.
14
+ - **DO** capitalize acronyms and abbreviations longer than two letters like words (e.g., `Http`, `Nasa`, `Uri`). Two-letter acronyms (e.g., `ID`, `TV`, `UI`) should remain capitalized.
15
+ - **PREFER** using wildcards (`_`) for unused callback parameters in anonymous and local functions.
16
+ - **DON'T** use a leading underscore for identifiers that aren't private.
17
+ - **DON'T** use prefix letters (e.g., `kDefaultTimeout`).
18
+ - **DON'T** explicitly name libraries using the `library` directive.
19
+
20
+ ### 1.2. Ordering
21
+
22
+ - **DO** place `dart:` imports before other imports.
23
+ - **DO** place `package:` imports before relative imports.
24
+ - **DO** specify exports in a separate section after all imports.
25
+ - **DO** sort sections alphabetically.
26
+
27
+ ### 1.3. Formatting
28
+
29
+ - **DO** format your code using `dart format`.
30
+ - **CONSIDER** changing your code to make it more formatter-friendly (e.g., shortening long identifiers, simplifying nested expressions).
31
+ - **PREFER** lines 80 characters or fewer.
32
+ - **DO** use curly braces for all flow control statements (`if`, `for`, `while`, `do`, `try`, `catch`, `finally`).
33
+
34
+ ## 2. Documentation
35
+
36
+ ### 2.1. Comments
37
+
38
+ - **DO** format comments like sentences (capitalize the first word, end with a period).
39
+ - **DON'T** use block comments (`/* ... */`) for documentation; use `//` for regular comments.
40
+
41
+ ### 2.2. Doc Comments
42
+
43
+ - **DO** use `///` doc comments to document members and types.
44
+ - **PREFER** writing doc comments for public APIs.
45
+ - **CONSIDER** writing a library-level doc comment.
46
+ - **CONSIDER** writing doc comments for private APIs.
47
+ - **DO** start doc comments with a single-sentence summary.
48
+ - **DO** separate the first sentence of a doc comment into its own paragraph.
49
+ - **AVOID** redundancy with the surrounding context (e.g., don't repeat the class name in its doc comment).
50
+ - **PREFER** starting comments of a function or method with third-person verbs if its main purpose is a side effect (e.g., "Connects to...").
51
+ - **PREFER** starting a non-boolean variable or property comment with a noun phrase (e.g., "The current day...").
52
+ - **PREFER** starting a boolean variable or property comment with "Whether" followed by a noun or gerund phrase (e.g., "Whether the modal is...").
53
+ - **PREFER** a noun phrase or non-imperative verb phrase for a function or method if returning a value is its primary purpose.
54
+ - **DON'T** write documentation for both the getter and setter of a property.
55
+ - **PREFER** starting library or type comments with noun phrases.
56
+ - **CONSIDER** including code samples in doc comments using triple backticks.
57
+ - **DO** use square brackets (`[]`) in doc comments to refer to in-scope identifiers (e.g., `[StateError]`, `[anotherMethod()]`, `[Duration.inDays]`, `[Point.new]`).
58
+ - **DO** use prose to explain parameters, return values, and exceptions.
59
+ - **DO** put doc comments before metadata annotations.
60
+
61
+ ### 2.3. Markdown
62
+
63
+ - **AVOID** using markdown excessively.
64
+ - **AVOID** using HTML for formatting.
65
+ - **PREFER** backtick fences (```) for code blocks.
66
+
67
+ ### 2.4. Writing
68
+
69
+ - **PREFER** brevity.
70
+ - **AVOID** abbreviations and acronyms unless they are obvious.
71
+ - **PREFER** using "this" instead of "the" to refer to a member's instance.
72
+
73
+ ## 3. Usage
74
+
75
+ ### 3.1. Libraries
76
+
77
+ - **DO** use strings in `part of` directives.
78
+ - **DON'T** import libraries that are inside the `src` directory of another package.
79
+ - **DON'T** allow an import path to reach into or out of `lib`.
80
+ - **PREFER** relative import paths when not crossing the `lib` boundary.
81
+
82
+ ### 3.2. Null Safety
83
+
84
+ - **DON'T** explicitly initialize variables to `null`.
85
+ - **DON'T** use an explicit default value of `null`.
86
+ - **DON'T** use `true` or `false` in equality operations (e.g., `if (nonNullableBool == true)`).
87
+ - **AVOID** `late` variables if you need to check whether they are initialized; prefer nullable types.
88
+ - **CONSIDER** type promotion or null-check patterns for using nullable types.
89
+
90
+ ### 3.3. Strings
91
+
92
+ - **DO** use adjacent strings to concatenate string literals.
93
+ - **PREFER** using interpolation (`$variable`, `${expression}`) to compose strings and values.
94
+ - **AVOID** using curly braces in interpolation when not needed (e.g., `'$name'` instead of `'${name}'`).
95
+
96
+ ### 3.4. Collections
97
+
98
+ - **DO** use collection literals (`[]`, `{}`, `<type>{}`) when possible.
99
+ - **DON'T** use `.length` to check if a collection is empty; use `.isEmpty` or `.isNotEmpty`.
100
+ - **AVOID** using `Iterable.forEach()` with a function literal; prefer `for-in` loops.
101
+ - **DON'T** use `List.from()` unless you intend to change the type of the result; prefer `.toList()`.
102
+ - **DO** use `whereType()` to filter a collection by type.
103
+ - **AVOID** using `cast()` when a nearby operation (like `List<T>.from()` or `map<T>()`) will do.
104
+
105
+ ### 3.5. Functions
106
+
107
+ - **DO** use a function declaration to bind a function to a name.
108
+ - **DON'T** create a lambda when a tear-off will do (e.g., `list.forEach(print)` instead of `list.forEach((e) => print(e))`).
109
+
110
+ ### 3.6. Variables
111
+
112
+ - **DO** follow a consistent rule for `var` and `final` on local variables (either `final` for non-reassigned and `var` for reassigned, or `var` for all locals).
113
+ - **AVOID** storing what you can calculate (e.g., don't store `area` if you have `radius`).
114
+
115
+ ### 3.7. Members
116
+
117
+ - **DON'T** wrap a field in a getter and setter unnecessarily.
118
+ - **PREFER** using a `final` field to make a read-only property.
119
+ - **CONSIDER** using `=>` for simple members (getters, setters, single-expression methods).
120
+ - **DON'T** use `this.` except to redirect to a named constructor or to avoid shadowing.
121
+ - **DO** initialize fields at their declaration when possible.
122
+
123
+ ### 3.8. Constructors
124
+
125
+ - **DO** use initializing formals (`this.field`) when possible.
126
+ - **DON'T** use `late` when a constructor initializer list will do.
127
+ - **DO** use `;` instead of `{}` for empty constructor bodies.
128
+ - **DON'T** use `new`.
129
+ - **DON'T** use `const` redundantly in constant contexts.
130
+
131
+ ### 3.9. Error Handling
132
+
133
+ - **AVOID** `catch` clauses without `on` clauses.
134
+ - **DON'T** discard errors from `catch` clauses without `on` clauses.
135
+ - **DO** throw objects that implement `Error` only for programmatic errors.
136
+ - **DON'T** explicitly catch `Error` or types that implement it.
137
+ - **DO** use `rethrow` to rethrow a caught exception to preserve the original stack trace.
138
+
139
+ ### 3.10. Asynchrony
140
+
141
+ - **PREFER** `async`/`await` over using raw `Future`s.
142
+ - **DON'T** use `async` when it has no useful effect.
143
+ - **CONSIDER** using higher-order methods to transform a stream.
144
+ - **AVOID** using `Completer` directly.
145
+
146
+ ## 4. API Design
147
+
148
+ ### 4.1. Names
149
+
150
+ - **DO** use terms consistently.
151
+ - **AVOID** abbreviations unless more common than the unabbreviated term.
152
+ - **PREFER** putting the most descriptive noun last (e.g., `pageCount`).
153
+ - **CONSIDER** making the code read like a sentence when using the API.
154
+ - **PREFER** a noun phrase for a non-boolean property or variable.
155
+ - **PREFER** a non-imperative verb phrase for a boolean property or variable (e.g., `isEnabled`, `canClose`).
156
+ - **CONSIDER** omitting the verb for a named boolean parameter (e.g., `growable: true`).
157
+ - **PREFER** the "positive" name for a boolean property or variable (e.g., `isConnected` over `isDisconnected`).
158
+ - **PREFER** an imperative verb phrase for a function or method whose main purpose is a side effect (e.g., `list.add()`, `window.refresh()`).
159
+ - **PREFER** a noun phrase or non-imperative verb phrase for a function or method if returning a value is its primary purpose (e.g., `list.elementAt(3)`).
160
+ - **CONSIDER** an imperative verb phrase for a function or method if you want to draw attention to the work it performs (e.g., `database.downloadData()`).
161
+ - **AVOID** starting a method name with `get`.
162
+ - **PREFER** naming a method `to___()` if it copies the object's state to a new object (e.g., `toList()`).
163
+ - **PREFER** naming a method `as___()` if it returns a different representation backed by the original object (e.g., `asMap()`).
164
+ - **AVOID** describing the parameters in the function's or method's name.
165
+ - **DO** follow existing mnemonic conventions when naming type parameters (e.g., `E` for elements, `K`, `V` for map keys/values, `T`, `S`, `U` for general types).
166
+
167
+ ### 4.2. Libraries
168
+
169
+ - **PREFER** making declarations private (`_`).
170
+ - **CONSIDER** declaring multiple classes in the same library if they logically belong together.
171
+
172
+ ### 4.3. Classes and Mixins
173
+
174
+ - **AVOID** defining a one-member abstract class when a simple function (`typedef`) will do.
175
+ - **AVOID** defining a class that contains only static members; prefer top-level functions/variables or a library.
176
+ - **AVOID** extending a class that isn't intended to be subclassed.
177
+ - **DO** use class modifiers (e.g., `final`, `interface`, `sealed`) to control if your class can be extended.
178
+ - **AVOID** implementing a class that isn't intended to be an interface.
179
+ - **DO** use class modifiers to control if your class can be an interface.
180
+ - **PREFER** defining a pure mixin or pure class to a `mixin class`.
181
+
182
+ ### 4.4. Constructors
183
+
184
+ - **CONSIDER** making your constructor `const` if the class supports it (all fields are `final` and initialized in the constructor).
185
+
186
+ ### 4.5. Members
187
+
188
+ - **PREFER** making fields and top-level variables `final`.
189
+ - **DO** use getters for operations that conceptually access properties (no arguments, returns a result, no user-visible side effects, idempotent).
190
+ - **DO** use setters for operations that conceptually change properties (single argument, no result, changes state, idempotent).
191
+ - **DON'T** define a setter without a corresponding getter.
192
+ - **AVOID** using runtime type tests to fake overloading.
193
+ - **AVOID** public `late final` fields without initializers.
194
+ - **AVOID** returning nullable `Future`, `Stream`, and collection types; prefer empty containers or non-nullable futures of nullable types.
195
+ - **AVOID** returning `this` from methods just to enable a fluent interface; prefer method cascades.
196
+
197
+ ### 4.6. Types
198
+
199
+ - **DO** type annotate variables without initializers.
200
+ - **DO** type annotate fields and top-level variables if the type isn't obvious.
201
+ - **DON'T** redundantly type annotate initialized local variables.
202
+ - **DO** annotate return types on function declarations.
203
+ - **DO** annotate parameter types on function declarations.
204
+ - **DON'T** annotate inferred parameter types on function expressions.
205
+ - **DON'T** type annotate initializing formals.
206
+ - **DO** write type arguments on generic invocations that aren't inferred.
207
+ - **DON'T** write type arguments on generic invocations that are inferred.
208
+ - **AVOID** writing incomplete generic types.
209
+ - **DO** annotate with `dynamic` instead of letting inference fail silently.
210
+ - **PREFER** signatures in function type annotations.
211
+ - **DON'T** specify a return type for a setter.
212
+ - **DON'T** use the legacy `typedef` syntax.
213
+ - **PREFER** inline function types over `typedef`s.
214
+ - **PREFER** using function type syntax for parameters.
215
+ - **AVOID** using `dynamic` unless you want to disable static checking.
216
+ - **DO** use `Future<void>` as the return type of asynchronous members that do not produce values.
217
+ - **AVOID** using `FutureOr<T>` as a return type.
218
+
219
+ ### 4.7. Parameters
220
+
221
+ - **AVOID** positional boolean parameters.
222
+ - **AVOID** optional positional parameters if the user may want to omit earlier parameters.
223
+ - **AVOID** mandatory parameters that accept a special "no argument" value.
224
+ - **DO** use inclusive start and exclusive end parameters to accept a range.
225
+
226
+ ### 4.8. Equality
227
+
228
+ - **DO** override `hashCode` if you override `==`.
229
+ - **DO** make your `==` operator obey the mathematical rules of equality (reflexive, symmetric, transitive, consistent).
230
+ - **AVOID** defining custom equality for mutable classes.
231
+ - **DON'T** make the parameter to `==` nullable.
232
+
233
+ _Sources:_
234
+
235
+ - [Effective Dart: Style](https://dart.dev/effective-dart/style)
236
+ - [Effective Dart: Documentation](https://dart.dev/effective-dart/documentation)
237
+ - [Effective Dart: Usage](https://dart.dev/effective-dart/usage)
238
+ - [Effective Dart: Design](https://dart.dev/effective-dart/design)
@@ -0,0 +1,23 @@
1
+ # General Code Style Principles
2
+
3
+ This document outlines general coding principles that apply across all languages and frameworks used in this project.
4
+
5
+ ## Readability
6
+ - Code should be easy to read and understand by humans.
7
+ - Avoid overly clever or obscure constructs.
8
+
9
+ ## Consistency
10
+ - Follow existing patterns in the codebase.
11
+ - Maintain consistent formatting, naming, and structure.
12
+
13
+ ## Simplicity
14
+ - Prefer simple solutions over complex ones.
15
+ - Break down complex problems into smaller, manageable parts.
16
+
17
+ ## Maintainability
18
+ - Write code that is easy to modify and extend.
19
+ - Minimize dependencies and coupling.
20
+
21
+ ## Documentation
22
+ - Document *why* something is done, not just *what*.
23
+ - Keep documentation up-to-date with code changes.