@torus-engineering/tas-kit 1.9.0 → 1.11.1

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 (68) hide show
  1. package/.claude/commands/ado-create.md +17 -17
  2. package/.claude/commands/ado-delete.md +11 -11
  3. package/.claude/commands/ado-get.md +12 -12
  4. package/.claude/commands/ado-status.md +12 -12
  5. package/.claude/commands/ado-update.md +15 -15
  6. package/.claude/commands/tas-adr.md +33 -33
  7. package/.claude/commands/tas-apitest-plan.md +173 -173
  8. package/.claude/commands/tas-apitest.md +143 -143
  9. package/.claude/commands/tas-brainstorm.md +14 -14
  10. package/.claude/commands/tas-bug.md +113 -113
  11. package/.claude/commands/tas-design.md +37 -37
  12. package/.claude/commands/tas-dev.md +128 -128
  13. package/.claude/commands/tas-e2e-mobile.md +155 -155
  14. package/.claude/commands/tas-e2e-web.md +163 -163
  15. package/.claude/commands/tas-e2e.md +102 -102
  16. package/.claude/commands/tas-epic.md +35 -35
  17. package/.claude/commands/tas-feature.md +47 -47
  18. package/.claude/commands/tas-fix.md +51 -51
  19. package/.claude/commands/tas-functest-mobile.md +144 -144
  20. package/.claude/commands/tas-functest-web.md +192 -192
  21. package/.claude/commands/tas-functest.md +76 -76
  22. package/.claude/commands/tas-init.md +14 -14
  23. package/.claude/commands/tas-plan.md +198 -200
  24. package/.claude/commands/tas-prd.md +37 -37
  25. package/.claude/commands/tas-review.md +111 -111
  26. package/.claude/commands/tas-sad.md +43 -43
  27. package/.claude/commands/tas-security.md +87 -81
  28. package/.claude/commands/tas-spec.md +20 -20
  29. package/.claude/commands/tas-status.md +13 -13
  30. package/.claude/commands/tas-story.md +91 -91
  31. package/.claude/commands/tas-verify.md +51 -51
  32. package/.claude/rules/common/post-review-agent.md +49 -49
  33. package/.claude/rules/common/project-status.md +14 -14
  34. package/.claude/rules/common/stack-detection.md +6 -6
  35. package/.claude/rules/common/token-logging.md +27 -27
  36. package/.claude/rules/csharp/api-testing.md +171 -171
  37. package/.claude/skills/ado-integration/SKILL.md +36 -36
  38. package/.claude/skills/tas-conventions/SKILL.md +32 -32
  39. package/.claude/skills/tas-implementation-complete/SKILL.md +100 -99
  40. package/.claude/skills/tas-tdd/SKILL.md +123 -123
  41. package/.claude/skills/token-logger/SKILL.md +19 -19
  42. package/.tas/README.md +266 -1520
  43. package/.tas/checklists/code-review.md +13 -13
  44. package/.tas/checklists/security.md +3 -3
  45. package/.tas/checklists/story-done.md +11 -11
  46. package/.tas/hooks/README.md +138 -0
  47. package/.tas/hooks/pre-commit +26 -0
  48. package/.tas/hooks/security-scan.js +599 -0
  49. package/.tas/project-status-example.yaml +3 -3
  50. package/.tas/tas-example.yaml +25 -8
  51. package/.tas/templates/ADR.md +16 -16
  52. package/.tas/templates/API-Test-Spec.md +3 -3
  53. package/.tas/templates/Bug.md +12 -12
  54. package/.tas/templates/Design-Spec.md +8 -8
  55. package/.tas/templates/E2E-Execution-Report.md +1 -1
  56. package/.tas/templates/Epic.md +1 -1
  57. package/.tas/templates/Feature.md +10 -10
  58. package/.tas/templates/Func-Test-Spec.md +3 -3
  59. package/.tas/templates/SAD.md +106 -106
  60. package/.tas/templates/Security-Report.md +3 -3
  61. package/.tas/templates/Story.md +9 -9
  62. package/.tas/tools/tas-ado-readme.md +169 -169
  63. package/.tas/tools/tas-ado.py +1 -1
  64. package/CLAUDE-Example.md +37 -58
  65. package/README.md +294 -42
  66. package/bin/cli.js +24 -7
  67. package/lib/install.js +161 -47
  68. package/package.json +1 -1
@@ -1,171 +1,171 @@
1
- ---
2
- paths:
3
- - "**/*.cs"
4
- - "**/ApiTests/**"
5
- - "**/Api.Tests/**"
6
- ---
7
-
8
- # C# API Automation Testing
9
-
10
- > Dùng bởi `/tas-api-test`. Extends [csharp/testing.md](./testing.md).
11
-
12
- ## Tech Stack
13
-
14
- | Thành phần | Lựa chọn |
15
- |---|---|
16
- | Framework | xUnit (default) — match project nếu đã dùng MSTest/NUnit |
17
- | Assertions | FluentAssertions |
18
- | HTTP | System.Net.Http.HttpClient |
19
- | Config | Microsoft.Extensions.Configuration + JSON/EnvVars |
20
-
21
- ```xml
22
- <!-- ApiTests.csproj packages -->
23
- <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.*" />
24
- <PackageReference Include="xunit" Version="2.*" />
25
- <PackageReference Include="xunit.runner.visualstudio" Version="2.*" />
26
- <PackageReference Include="FluentAssertions" Version="6.*" />
27
- <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.*" />
28
- <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.*" />
29
- <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.*" />
30
- ```
31
-
32
- ## Project Structure
33
-
34
- ```
35
- tests/ApiTests/
36
- appsettings.json # base (không secrets thật)
37
- appsettings.Test.json # Test env override
38
- appsettings.Staging.json # Staging env override
39
- .gitignore # appsettings.*.local.json
40
- Shared/
41
- ApiTestSettings.cs
42
- TestBase.cs
43
- v1/
44
- UsersApiTests.cs
45
- v2/ # APPEND-ONLY: không sửa v1
46
- UsersApiTests.cs
47
- ```
48
-
49
- ## Config
50
-
51
- ```json
52
- // appsettings.json
53
- {
54
- "ApiTest": {
55
- "BaseUrl": "https://localhost:5001",
56
- "TimeoutSeconds": 30,
57
- "Auth": { "Type": "Bearer", "TokenEndpoint": "/api/auth/token", "Username": "", "Password": "" }
58
- }
59
- }
60
- ```
61
-
62
- ```csharp
63
- // ApiTestSettings.cs
64
- public sealed class ApiTestSettings
65
- {
66
- public required string BaseUrl { get; init; }
67
- public int TimeoutSeconds { get; init; } = 30;
68
- public required AuthSettings Auth { get; init; }
69
- }
70
- public sealed class AuthSettings
71
- {
72
- public string Type { get; init; } = "Bearer";
73
- public string TokenEndpoint { get; init; } = "/api/auth/token";
74
- public string Username { get; init; } = "";
75
- public string Password { get; init; } = "";
76
- }
77
- ```
78
-
79
- ```csharp
80
- // TestBase.cs
81
- public abstract class TestBase : IAsyncLifetime
82
- {
83
- protected HttpClient Client { get; private set; } = null!;
84
- protected ApiTestSettings Settings { get; private set; } = null!;
85
-
86
- public async Task InitializeAsync()
87
- {
88
- var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Test";
89
- Settings = new ConfigurationBuilder()
90
- .AddJsonFile("appsettings.json")
91
- .AddJsonFile($"appsettings.{env}.json", optional: true)
92
- .AddEnvironmentVariables("APITEST_")
93
- .Build()
94
- .GetRequiredSection("ApiTest").Get<ApiTestSettings>()!;
95
-
96
- Client = new HttpClient { BaseAddress = new Uri(Settings.BaseUrl),
97
- Timeout = TimeSpan.FromSeconds(Settings.TimeoutSeconds) };
98
-
99
- if (!string.IsNullOrEmpty(Settings.Auth.Username))
100
- await AuthenticateAsync();
101
- }
102
-
103
- public Task DisposeAsync() { Client.Dispose(); return Task.CompletedTask; }
104
-
105
- protected async Task AuthenticateAsync(string? username = null, string? password = null)
106
- {
107
- var res = await Client.PostAsJsonAsync(Settings.Auth.TokenEndpoint,
108
- new { username = username ?? Settings.Auth.Username, password = password ?? Settings.Auth.Password });
109
- res.EnsureSuccessStatusCode();
110
- var token = (await res.Content.ReadFromJsonAsync<TokenResponse>())!.AccessToken;
111
- Client.DefaultRequestHeaders.Authorization =
112
- new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
113
- }
114
-
115
- private sealed record TokenResponse(string AccessToken);
116
- }
117
- ```
118
-
119
- ## Test Class Header (bắt buộc)
120
-
121
- ```csharp
122
- // ============================================================
123
- // {Resource} API Tests — v{N}
124
- // Spec: {spec-file} | Generated: {YYYY-MM-DD} | Story: {ID}
125
- // APPEND-ONLY: không sửa methods đã tồn tại.
126
- // ============================================================
127
- namespace ApiTests.V{N};
128
- public sealed class {Resource}ApiTests : TestBase
129
- {
130
- // Inline DTOs — không import từ production code
131
- private sealed record {Resource}Dto(Guid Id, string Name);
132
- private sealed record ListResponse<T>(IReadOnlyList<T> Data, int Total);
133
- }
134
- ```
135
-
136
- ## Test Naming
137
-
138
- ```
139
- {HttpMethod}_{Resource}_Returns{Status}_When{Condition}
140
- ```
141
-
142
- dụ: `GetById_User_Returns200_WhenExists`, `Create_Order_Returns422_WhenEmailInvalid`
143
-
144
- AC test: comment `// AC: {text}` ngay dưới XML doc.
145
-
146
- ## XML Doc (bắt buộc trên mỗi test)
147
-
148
- ```csharp
149
- /// <summary>Verify {METHOD} {path} → {status} khi {condition}. Spec: {ref}</summary>
150
- [Fact]
151
- public async Task ...
152
- ```
153
-
154
- ## Coverage Matrix
155
-
156
- | Điều kiện | Status | Khi nào |
157
- |---|---|---|
158
- | Valid, authenticated | 2xx | Luôn |
159
- | Không token | 401 | Endpoint yêu cầu auth |
160
- | Không đủ quyền | 403 | RBAC / ownership |
161
- | `{id}` không tồn tại | 404 | path param |
162
- | Required field thiếu/sai | 400/422 | request body |
163
- | Business rule (từ AC) | 4xx | Story AC tương ứng |
164
-
165
- ## CI/CD Env Vars
166
-
167
- ```
168
- ASPNETCORE_ENVIRONMENT=Test
169
- APITEST__AUTH__USERNAME=... # double __ cho nested key
170
- APITEST__AUTH__PASSWORD=...
171
- ```
1
+ ---
2
+ paths:
3
+ - "**/*.cs"
4
+ - "**/ApiTests/**"
5
+ - "**/Api.Tests/**"
6
+ ---
7
+
8
+ # C# API Automation Testing
9
+
10
+ > Used by `/tas-api-test`. Extends [csharp/testing.md](./testing.md).
11
+
12
+ ## Tech Stack
13
+
14
+ | Component | Choice |
15
+ |---|---|
16
+ | Framework | xUnit (default) — match project if already using MSTest/NUnit |
17
+ | Assertions | FluentAssertions |
18
+ | HTTP | System.Net.Http.HttpClient |
19
+ | Config | Microsoft.Extensions.Configuration + JSON/EnvVars |
20
+
21
+ ```xml
22
+ <!-- ApiTests.csproj packages -->
23
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.*" />
24
+ <PackageReference Include="xunit" Version="2.*" />
25
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.*" />
26
+ <PackageReference Include="FluentAssertions" Version="6.*" />
27
+ <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.*" />
28
+ <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.*" />
29
+ <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.*" />
30
+ ```
31
+
32
+ ## Project Structure
33
+
34
+ ```
35
+ tests/ApiTests/
36
+ appsettings.json # base (no real secrets)
37
+ appsettings.Test.json # Test env override
38
+ appsettings.Staging.json # Staging env override
39
+ .gitignore # appsettings.*.local.json
40
+ Shared/
41
+ ApiTestSettings.cs
42
+ TestBase.cs
43
+ v1/
44
+ UsersApiTests.cs
45
+ v2/ # APPEND-ONLY: don't modify v1
46
+ UsersApiTests.cs
47
+ ```
48
+
49
+ ## Config
50
+
51
+ ```json
52
+ // appsettings.json
53
+ {
54
+ "ApiTest": {
55
+ "BaseUrl": "https://localhost:5001",
56
+ "TimeoutSeconds": 30,
57
+ "Auth": { "Type": "Bearer", "TokenEndpoint": "/api/auth/token", "Username": "", "Password": "" }
58
+ }
59
+ }
60
+ ```
61
+
62
+ ```csharp
63
+ // ApiTestSettings.cs
64
+ public sealed class ApiTestSettings
65
+ {
66
+ public required string BaseUrl { get; init; }
67
+ public int TimeoutSeconds { get; init; } = 30;
68
+ public required AuthSettings Auth { get; init; }
69
+ }
70
+ public sealed class AuthSettings
71
+ {
72
+ public string Type { get; init; } = "Bearer";
73
+ public string TokenEndpoint { get; init; } = "/api/auth/token";
74
+ public string Username { get; init; } = "";
75
+ public string Password { get; init; } = "";
76
+ }
77
+ ```
78
+
79
+ ```csharp
80
+ // TestBase.cs
81
+ public abstract class TestBase : IAsyncLifetime
82
+ {
83
+ protected HttpClient Client { get; private set; } = null!;
84
+ protected ApiTestSettings Settings { get; private set; } = null!;
85
+
86
+ public async Task InitializeAsync()
87
+ {
88
+ var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Test";
89
+ Settings = new ConfigurationBuilder()
90
+ .AddJsonFile("appsettings.json")
91
+ .AddJsonFile($"appsettings.{env}.json", optional: true)
92
+ .AddEnvironmentVariables("APITEST_")
93
+ .Build()
94
+ .GetRequiredSection("ApiTest").Get<ApiTestSettings>()!;
95
+
96
+ Client = new HttpClient { BaseAddress = new Uri(Settings.BaseUrl),
97
+ Timeout = TimeSpan.FromSeconds(Settings.TimeoutSeconds) };
98
+
99
+ if (!string.IsNullOrEmpty(Settings.Auth.Username))
100
+ await AuthenticateAsync();
101
+ }
102
+
103
+ public Task DisposeAsync() { Client.Dispose(); return Task.CompletedTask; }
104
+
105
+ protected async Task AuthenticateAsync(string? username = null, string? password = null)
106
+ {
107
+ var res = await Client.PostAsJsonAsync(Settings.Auth.TokenEndpoint,
108
+ new { username = username ?? Settings.Auth.Username, password = password ?? Settings.Auth.Password });
109
+ res.EnsureSuccessStatusCode();
110
+ var token = (await res.Content.ReadFromJsonAsync<TokenResponse>())!.AccessToken;
111
+ Client.DefaultRequestHeaders.Authorization =
112
+ new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
113
+ }
114
+
115
+ private sealed record TokenResponse(string AccessToken);
116
+ }
117
+ ```
118
+
119
+ ## Test Class Header (required)
120
+
121
+ ```csharp
122
+ // ============================================================
123
+ // {Resource} API Tests — v{N}
124
+ // Spec: {spec-file} | Generated: {YYYY-MM-DD} | Story: {ID}
125
+ // APPEND-ONLY: don't modify existing methods.
126
+ // ============================================================
127
+ namespace ApiTests.V{N};
128
+ public sealed class {Resource}ApiTests : TestBase
129
+ {
130
+ // Inline DTOs — don't import from production code
131
+ private sealed record {Resource}Dto(Guid Id, string Name);
132
+ private sealed record ListResponse<T>(IReadOnlyList<T> Data, int Total);
133
+ }
134
+ ```
135
+
136
+ ## Test Naming
137
+
138
+ ```
139
+ {HttpMethod}_{Resource}_Returns{Status}_When{Condition}
140
+ ```
141
+
142
+ Example: `GetById_User_Returns200_WhenExists`, `Create_Order_Returns422_WhenEmailInvalid`
143
+
144
+ AC test: comment `// AC: {text}` right below XML doc.
145
+
146
+ ## XML Doc (required on each test)
147
+
148
+ ```csharp
149
+ /// <summary>Verify {METHOD} {path} → {status} when {condition}. Spec: {ref}</summary>
150
+ [Fact]
151
+ public async Task ...
152
+ ```
153
+
154
+ ## Coverage Matrix
155
+
156
+ | Condition | Status | When |
157
+ |---|---|---|
158
+ | Valid, authenticated | 2xx | Always |
159
+ | No token | 401 | Endpoint requires auth |
160
+ | Insufficient permission | 403 | RBAC / ownership |
161
+ | `{id}` doesn't exist | 404 | Has path param |
162
+ | Required field missing/invalid | 400/422 | Has request body |
163
+ | Business rule (from AC) | 4xx | Story has corresponding AC |
164
+
165
+ ## CI/CD Env Vars
166
+
167
+ ```
168
+ ASPNETCORE_ENVIRONMENT=Test
169
+ APITEST__AUTH__USERNAME=... # double __ for nested key
170
+ APITEST__AUTH__PASSWORD=...
171
+ ```
@@ -1,54 +1,54 @@
1
1
  ---
2
2
  name: ado-integration
3
3
  description: |
4
- Azure DevOps integration. Auto-invoke khi user nhắc đến:
4
+ Azure DevOps integration. Auto-invoke when user mentions:
5
5
  sync ADO, push to board, pull work item, update status on ADO,
6
- create work item on ADO, hoặc bất kỳ thao tác liên quan Azure DevOps.
6
+ create work item on ADO, or any Azure DevOps related operation.
7
7
  allowed-tools: Read, Write, Edit, Bash, Grep
8
8
  ---
9
9
 
10
10
  # ADO Integration Skill
11
11
 
12
- Cho phép đồng bộ hai chiều giữa file .md trong repo work items trên Azure DevOps.
13
- ADO sync **thao tác có chủ đích** — không tự động sau mỗi lần edit file.
12
+ Enables bidirectional sync between .md files in repo and work items on Azure DevOps.
13
+ ADO sync is **intentional operation** — not automatic after each file edit.
14
14
 
15
15
  ## When to Use
16
16
 
17
- - User yêu cầu sync, push, pull work item lên/từ ADO
18
- - User chạy `/ado-create`, `/ado-update`, `/ado-status`, `/ado-get`, `/ado-delete`
19
- - KHÔNG invoke khi: user chỉ edit file .md thông thường không nhắc đến ADO
17
+ - User requests sync, push, pull work item to/from ADO
18
+ - User runs `/ado-create`, `/ado-update`, `/ado-status`, `/ado-get`, `/ado-delete`
19
+ - DO NOT invoke when: user only edits .md file normally without mentioning ADO
20
20
 
21
21
  ## Always / Ask / Never
22
22
 
23
- | | Hành động |
23
+ | | Action |
24
24
  |---|---|
25
- | **Always** | Đọc `tas.yaml` kiểm tra `ado.enabled` trước bất kỳ thao tác nào |
26
- | **Always** | Hiển thị ADO ID URL sau mỗi create/update thành công |
27
- | **Always** | Cập nhật frontmatter `ado_id`, `ado_state`, `last_ado_sync` trong file .md sau sync |
28
- | **Ask** | Khi sync bulk nhiều items cùng lúc — confirm list trước khi chạy |
29
- | **Ask** | Khi phát hiện conflict giữa file .md ADO item (ai source of truth?) |
30
- | **Ask** | Khi delete work item — đây thao tác không thể undo |
31
- | **Never** | Auto-sync mỗi khi file .md được edit (quá aggressive, dễ gây noise) |
32
- | **Never** | Xóa ADO item không xác nhận rõ ràng từ user |
33
- | **Never** | Tạo duplicate work item nếu đã có `ado_id` trong frontmatter |
34
-
35
- ## Bước đầu tiên Kiểm tra ADO enabled
36
-
37
- Trước khi thực hiện bất kỳ thao tác nào, đọc `tas.yaml` tại root kiểm tra `ado.enabled`:
38
- - Nếu `ado.enabled: false` hoặc field không tồn tại: thông báo "ADO integration bị tắt trong tas.yaml (`ado.enabled: false`). Bật lên nếu project dùng ADO." rồi dừng lại.
39
- - Nếu `ado.enabled: true`: tiếp tục bình thường.
25
+ | **Always** | Read `tas.yaml` and check `ado.enabled` before any operation |
26
+ | **Always** | Display ADO ID and URL after each successful create/update |
27
+ | **Always** | Update frontmatter `ado_id`, `ado_state`, `last_ado_sync` in .md file after sync |
28
+ | **Ask** | When syncing multiple items at once — confirm list before running |
29
+ | **Ask** | When detecting conflict between .md file and ADO item (which is source of truth?) |
30
+ | **Ask** | When deleting work item — this is irreversible operation |
31
+ | **Never** | Auto-sync whenever .md file is edited (too aggressive, creates noise) |
32
+ | **Never** | Delete ADO item without clear user confirmation |
33
+ | **Never** | Create duplicate work item if `ado_id` already exists in frontmatter |
34
+
35
+ ## First StepCheck ADO Enabled
36
+
37
+ Before performing any operation, read `tas.yaml` at root and check `ado.enabled`:
38
+ - If `ado.enabled: false` or field doesn't exist: notify "ADO integration is disabled in tas.yaml (`ado.enabled: false`). Enable if project uses ADO." then stop.
39
+ - If `ado.enabled: true`: continue normally.
40
40
 
41
41
  ## Prerequisites
42
42
 
43
- - Azure CLI + extension azure-devops: `az extension add --name azure-devops --upgrade`
44
- - Python 3.8+ với pyyaml: `pip install pyyaml`
45
- - PAT trong file .env: `AzureDevops_Personal_AccessToken=your-pat-here`
43
+ - Azure CLI + azure-devops extension: `az extension add --name azure-devops --upgrade`
44
+ - Python 3.8+ with pyyaml: `pip install pyyaml`
45
+ - PAT in .env file: `AzureDevops_Personal_AccessToken=your-pat-here`
46
46
 
47
47
  ## Commands
48
48
 
49
- Tất cả ADO commands chạy qua: `python .tas/tools/tas-ado.py <command> [args]`
49
+ All ADO commands run via: `python .tas/tools/tas-ado.py <command> [args]`
50
50
 
51
- Hoặc dùng slash commands:
51
+ Or use slash commands:
52
52
  - `/ado-create <type> <temp-id> [--parent-id <id>]`
53
53
  - `/ado-get <ado-id>`
54
54
  - `/ado-update <type> <ado-id> [--assign <name>] [--status <state>]`
@@ -57,19 +57,19 @@ Hoặc dùng slash commands:
57
57
 
58
58
  ## File Convention
59
59
 
60
- - Tên file: `{type}-{ado_id}-{slug-title}.md`
61
- - Mỗi file frontmatter YAML: `ado_id`, `ado_type`, `ado_state`, `last_ado_sync`
62
- - File .md single source of truth, sync lên ADO khi cần
60
+ - Filename: `{type}-{ado_id}-{slug-title}.md`
61
+ - Each file has YAML frontmatter: `ado_id`, `ado_type`, `ado_state`, `last_ado_sync`
62
+ - .md file is single source of truth, sync to ADO when needed
63
63
 
64
64
  ## Red Flags
65
65
 
66
- - File `ado_id` nhưng state trong file khác ADO → confirm với user trước khi ghi đè
67
- - PAT hết hạn hướng dẫn rotate, không log token ra stdout
68
- - `ado.enabled: true` nhưng project chưa setup Azure CLI → check prerequisites trước
66
+ - File has `ado_id` but state in file differs from ADO → confirm with user before overwriting
67
+ - PAT expiredguide to rotate, don't log token to stdout
68
+ - `ado.enabled: true` but project hasn't set up Azure CLI → check prerequisites first
69
69
 
70
70
  ## Anti-Rationalization
71
71
 
72
72
  | Rationalization | Counter |
73
73
  |---|---|
74
- | "Auto-sync tiện hơn, không cần nhớ" | Hook auto-sync gây unintended pushes khi edit draft — sync phải chủ đích |
75
- | "Delete chắc OK, mình biết mình đang làm gì" | ADO delete không undo — luôn confirm, user trông vẻ chắc chắn |
74
+ | "Auto-sync is more convenient, no need to remember" | Hook auto-sync causes unintended pushes when editing draft — sync must be intentional |
75
+ | "Delete is OK, I know what I'm doing" | ADO delete has no undo — always confirm, even if user seems confident |
@@ -1,65 +1,65 @@
1
1
  ---
2
2
  name: tas-conventions
3
3
  description: |
4
- Coding conventions naming rules của dự án Torus.
5
- Auto-invoke khi viết code mới, review code, refactor,
6
- hoặc khi user hỏi về coding standards.
4
+ Coding conventions and naming rules for Torus projects.
5
+ Auto-invoke when writing new code, reviewing code, refactoring,
6
+ or when user asks about coding standards.
7
7
  allowed-tools: Read, Grep, Glob
8
8
  ---
9
9
 
10
10
  # TAS Conventions
11
11
 
12
- Khi generate hoặc review code, PHẢI tuân thủ conventions được định nghĩa trong `CLAUDE.md` của project.
12
+ When generating or reviewing code, MUST follow conventions defined in project's `CLAUDE.md`.
13
13
 
14
14
  ## When to Use
15
15
 
16
- - Trước khi generate code mới (check conventions)
17
- - Khi review code của user (verify compliance)
18
- - Khi user hỏi "đặt tên thế nào?", "format như thế nào?"
19
- - KHÔNG invoke khi: đọc file thuần, không liên quan đến code output
16
+ - Before generating new code (check conventions)
17
+ - When reviewing user's code (verify compliance)
18
+ - When user asks "what to name?", "what format?"
19
+ - DO NOT invoke when: reading files only, not related to code output
20
20
 
21
21
  ## Always / Ask / Never
22
22
 
23
- | | Hành động |
23
+ | | Action |
24
24
  |---|---|
25
- | **Always** | Đọc `CLAUDE.md` trước khi áp dụng convention |
26
- | **Always** | Chỉ ra file:line cụ thể khi phát hiện vi phạm |
27
- | **Ask** | Khi convention trong CLAUDE.md hồ hoặc conflict |
28
- | **Never** | Hardcode convention (naming, format) không đọc CLAUDE.md trước |
29
- | **Never** | Áp dụng convention từ project khác vào project hiện tại |
25
+ | **Always** | Read `CLAUDE.md` before applying convention |
26
+ | **Always** | Point to specific file:line when detecting violation |
27
+ | **Ask** | When convention in CLAUDE.md is vague or has conflict |
28
+ | **Never** | Hardcode convention (naming, format) without reading CLAUDE.md first |
29
+ | **Never** | Apply convention from other project to current project |
30
30
 
31
31
  ## Checklist
32
32
 
33
- - Đọc `CLAUDE.md` để lấy naming conventions, branching, commit format, stack rules
34
- - Enforce các conventions đó trong code output
35
- - Nếu code vi phạm conventions, chỉ ra cụ thể: file:line + convention bị vi phạm + cách sửa
33
+ - Read `CLAUDE.md` to get naming conventions, branching, commit format, stack rules
34
+ - Enforce those conventions in code output
35
+ - If code violates conventions, point specifically: file:line + violated convention + how to fix
36
36
 
37
- ## Common Conventions (Default — override bằng CLAUDE.md)
37
+ ## Common Conventions (Default — override by CLAUDE.md)
38
38
 
39
- Các conventions mặc định này chỉ áp dụng khi `CLAUDE.md` không định nghĩa khác:
39
+ These default conventions only apply when `CLAUDE.md` doesn't define otherwise:
40
40
 
41
41
  - Variables/functions: `camelCase`
42
42
  - Types/Interfaces/Components: `PascalCase`
43
43
  - Constants: `UPPER_SNAKE_CASE`
44
44
  - Boolean vars: prefix `is`, `has`, `should`, `can`
45
- - File naming: kebab-case cho files, PascalCase cho components
45
+ - File naming: kebab-case for files, PascalCase for components
46
46
  - Commit format: `<type>: <description>` (feat, fix, refactor, docs, test, chore)
47
47
 
48
48
  ## Red Flags
49
49
 
50
- - Magic numbers trong code (e.g. `if (count > 50)`) → phải dùng named constant
51
- - Deep nesting >4 levels → dùng early return hoặc extract method
52
- - Function >50 lines → extract thành functions nhỏ hơn
53
- - File >800 lines → extract thành modules
54
- - Variable tên 1-2 tự (`x`, `t`, `d`) trong production code → đặt tên mô tả
55
- - `any` type trong TypeScript → dùng type cụ thể hoặc generic
56
- - Commented-out code block lớn xóa nếu không cần, dùng git history thay thế
50
+ - Magic numbers in code (e.g., `if (count > 50)`) → must use named constant
51
+ - Deep nesting >4 levels → use early return or extract method
52
+ - Function >50 lines → extract to smaller functions
53
+ - File >800 lines → extract to modules
54
+ - Variable with 1-2 char name (`x`, `t`, `d`) in production code → use descriptive name
55
+ - `any` type in TypeScript → use specific type or generic
56
+ - Large commented-out code block → delete if not needed, use git history instead
57
57
 
58
58
  ## Verification
59
59
 
60
- - [ ] CLAUDE.md đã được đọc trước khi review/generate code
61
- - [ ] Naming tuân thủ conventions trong CLAUDE.md
62
- - [ ] Không magic numbers
63
- - [ ] Không deep nesting (>4 levels)
60
+ - [ ] CLAUDE.md has been read before reviewing/generating code
61
+ - [ ] Naming follows conventions in CLAUDE.md
62
+ - [ ] No magic numbers
63
+ - [ ] No deep nesting (>4 levels)
64
64
  - [ ] Functions < 50 lines, files < 800 lines
65
- - [ ] Commit message theo format đã định nghĩa
65
+ - [ ] Commit message follows defined format