@torus-engineering/tas-kit 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/tas-adr.md +33 -29
- package/.claude/commands/tas-api-test.md +95 -0
- package/.claude/commands/tas-bug.md +113 -109
- package/.claude/commands/tas-design.md +37 -33
- package/.claude/commands/tas-dev.md +128 -115
- package/.claude/commands/tas-e2e-mobile.md +155 -0
- package/.claude/commands/tas-e2e-web.md +163 -0
- package/.claude/commands/tas-e2e.md +102 -0
- package/.claude/commands/tas-epic.md +35 -31
- package/.claude/commands/tas-feature.md +47 -43
- package/.claude/commands/tas-fix.md +51 -47
- package/.claude/commands/tas-functest-mobile.md +144 -0
- package/.claude/commands/tas-functest-web.md +192 -0
- package/.claude/commands/tas-functest.md +76 -0
- package/.claude/commands/tas-plan.md +200 -184
- package/.claude/commands/tas-prd.md +37 -33
- package/.claude/commands/tas-review.md +111 -104
- package/.claude/commands/tas-sad.md +43 -39
- package/.claude/commands/tas-security.md +81 -80
- package/.claude/commands/tas-story.md +91 -87
- package/.claude/commands/tas-verify.md +51 -41
- package/.claude/rules/common/post-review-agent.md +49 -39
- package/.claude/rules/common/testing.md +24 -0
- package/.claude/rules/common/token-logging.md +27 -0
- package/.claude/rules/csharp/api-testing.md +171 -0
- package/.claude/rules/csharp/patterns.md +10 -0
- package/.claude/rules/python/patterns.md +10 -0
- package/.claude/rules/typescript/patterns.md +10 -0
- package/.claude/rules/web/performance.md +9 -0
- package/.claude/skills/api-design/SKILL.md +3 -1
- package/.claude/skills/{backend-patterns → js-backend-patterns}/SKILL.md +2 -1
- package/.claude/skills/tas-implementation-complete/SKILL.md +99 -97
- package/.claude/skills/tas-tdd/SKILL.md +123 -82
- package/.claude/skills/token-logger/SKILL.md +19 -0
- package/.tas/templates/E2E-Execution-Report.md +198 -0
- package/.tas/templates/E2E-Mobile-Spec.md +130 -0
- package/.tas/templates/E2E-Report.md +174 -0
- package/.tas/templates/E2E-Scenario.md +180 -0
- package/.tas/templates/E2E-Web-Spec.md +164 -0
- package/.tas/templates/Feature.md +55 -55
- package/.tas/templates/Func-Test-Script.md +254 -0
- package/.tas/templates/Func-Test-Spec.md +187 -0
- package/.tas/templates/SAD.md +274 -274
- package/.tas/templates/Story.md +90 -88
- package/bin/cli.js +56 -56
- package/lib/deleted-files.json +33 -0
- package/lib/install.js +213 -176
- package/package.json +34 -34
- package/.claude/agents/README.md +0 -83
- package/.claude/agents/ado-agent.md +0 -39
- package/.claude/agents/code-architect.md +0 -62
- package/.claude/agents/code-simplifier.md +0 -53
- package/.claude/agents/comment-analyzer.md +0 -59
- package/.claude/agents/conversation-analyzer.md +0 -57
- package/.claude/agents/docs-lookup.md +0 -55
- package/.claude/agents/harness-optimizer.md +0 -62
- package/.claude/agents/loop-operator.md +0 -56
- package/.claude/agents/performance-optimizer.md +0 -78
- package/.claude/agents/pr-test-analyzer.md +0 -68
- package/.claude/agents/pytorch-build-resolver.md +0 -76
- package/.claude/agents/refactor-cleaner.md +0 -70
- package/.claude/agents/seo-specialist.md +0 -75
- package/.claude/agents/silent-failure-hunter.md +0 -69
- package/.claude/agents/type-design-analyzer.md +0 -75
- package/.claude/rules/common/agents.md +0 -65
- package/.claude/rules/common/coding-style.md +0 -90
- package/.claude/rules/common/development-workflow.md +0 -44
- package/.claude/rules/common/git-workflow.md +0 -24
- package/.claude/rules/common/performance.md +0 -55
- package/.claude/skills/agent-harness-construction/SKILL.md +0 -77
- package/.claude/skills/agent-introspection-debugging/SKILL.md +0 -157
package/lib/install.js
CHANGED
|
@@ -1,176 +1,213 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import readline from 'node:readline';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
console.log(
|
|
90
|
-
|
|
91
|
-
//
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
console.log(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
await
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import readline from 'node:readline';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { createRequire } from 'node:module';
|
|
6
|
+
|
|
7
|
+
const PACKAGE_DIR = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
|
|
10
|
+
async function getDeletedFiles() {
|
|
11
|
+
try {
|
|
12
|
+
const manifest = require('./deleted-files.json');
|
|
13
|
+
return Object.values(manifest).flat();
|
|
14
|
+
} catch {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function removeDeletedFiles(target, deletedFiles) {
|
|
20
|
+
const removed = [];
|
|
21
|
+
const skipped = [];
|
|
22
|
+
for (const relPath of deletedFiles) {
|
|
23
|
+
const fullPath = path.join(target, relPath);
|
|
24
|
+
try {
|
|
25
|
+
await fs.rm(fullPath, { force: false });
|
|
26
|
+
removed.push(relPath);
|
|
27
|
+
} catch {
|
|
28
|
+
skipped.push(relPath);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { removed, skipped };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function confirm(question) {
|
|
35
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
36
|
+
return new Promise((resolve) => {
|
|
37
|
+
rl.question(`${question} [y/N] `, (answer) => {
|
|
38
|
+
rl.close();
|
|
39
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function exists(p) {
|
|
45
|
+
return fs.access(p).then(() => true).catch(() => false);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function copyDir(src, dest) {
|
|
49
|
+
await fs.cp(src, dest, { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export async function update({ directory, yes }) {
|
|
53
|
+
const target = path.resolve(directory);
|
|
54
|
+
|
|
55
|
+
// Must already have .claude/ or .tas/ — otherwise suggest install
|
|
56
|
+
const claudeExists = await exists(path.join(target, '.claude'));
|
|
57
|
+
const tasExists = await exists(path.join(target, '.tas'));
|
|
58
|
+
if (!claudeExists && !tasExists) {
|
|
59
|
+
console.error(` ERROR: No TAS Kit found in: ${target}`);
|
|
60
|
+
console.error(` Run "install" first to set up TAS Kit.`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log(`\nUpdating TAS Kit in: ${target}\n`);
|
|
65
|
+
|
|
66
|
+
if (!yes) {
|
|
67
|
+
console.warn(` This will overwrite .claude/ and .tas/ with the latest kit files.`);
|
|
68
|
+
console.warn(` Your CLAUDE.md, tas.yaml, and .env.example will NOT be touched.\n`);
|
|
69
|
+
const ok = await confirm('Continue?');
|
|
70
|
+
if (!ok) {
|
|
71
|
+
console.log('Update cancelled.');
|
|
72
|
+
process.exit(0);
|
|
73
|
+
}
|
|
74
|
+
console.log();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Overwrite .claude/
|
|
78
|
+
await copyDir(
|
|
79
|
+
path.join(PACKAGE_DIR, '.claude'),
|
|
80
|
+
path.join(target, '.claude')
|
|
81
|
+
);
|
|
82
|
+
console.log(' [ok] .claude/ (updated)');
|
|
83
|
+
|
|
84
|
+
// Overwrite .tas/
|
|
85
|
+
await copyDir(
|
|
86
|
+
path.join(PACKAGE_DIR, '.tas'),
|
|
87
|
+
path.join(target, '.tas')
|
|
88
|
+
);
|
|
89
|
+
console.log(' [ok] .tas/ (updated)');
|
|
90
|
+
|
|
91
|
+
// Remove files deleted from the kit in previous versions
|
|
92
|
+
const deletedFiles = await getDeletedFiles();
|
|
93
|
+
if (deletedFiles.length > 0) {
|
|
94
|
+
const { removed } = await removeDeletedFiles(target, deletedFiles);
|
|
95
|
+
if (removed.length > 0) {
|
|
96
|
+
for (const f of removed) {
|
|
97
|
+
console.log(` [rm] ${f} (removed in this version)`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Set executable bit on tas-ado.py (Unix/macOS)
|
|
103
|
+
if (process.platform !== 'win32') {
|
|
104
|
+
const adoPy = path.join(target, '.tas', 'tools', 'tas-ado.py');
|
|
105
|
+
if (await exists(adoPy)) {
|
|
106
|
+
await fs.chmod(adoPy, 0o755);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
console.log(` [--] CLAUDE.md, tas.yaml, .env.example — not touched`);
|
|
111
|
+
|
|
112
|
+
console.log(`
|
|
113
|
+
TAS Kit updated successfully!
|
|
114
|
+
|
|
115
|
+
If this version added new settings or templates, check the changelog
|
|
116
|
+
and manually merge changes into your CLAUDE.md and tas.yaml if needed.
|
|
117
|
+
`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export async function install({ directory, yes }) {
|
|
121
|
+
const target = path.resolve(directory);
|
|
122
|
+
|
|
123
|
+
// Ensure target directory exists
|
|
124
|
+
await fs.mkdir(target, { recursive: true });
|
|
125
|
+
|
|
126
|
+
console.log(`\nInstalling TAS Kit into: ${target}\n`);
|
|
127
|
+
|
|
128
|
+
// Warn if .claude/ or .tas/ already exist
|
|
129
|
+
const claudeExists = await exists(path.join(target, '.claude'));
|
|
130
|
+
const tasExists = await exists(path.join(target, '.tas'));
|
|
131
|
+
|
|
132
|
+
if ((claudeExists || tasExists) && !yes) {
|
|
133
|
+
const existing = [claudeExists && '.claude/', tasExists && '.tas/'].filter(Boolean).join(', ');
|
|
134
|
+
console.warn(` WARNING: ${existing} already exist in target directory.`);
|
|
135
|
+
console.warn(` Existing files with the same names will be overwritten.\n`);
|
|
136
|
+
const ok = await confirm('Continue?');
|
|
137
|
+
if (!ok) {
|
|
138
|
+
console.log('Installation cancelled.');
|
|
139
|
+
process.exit(0);
|
|
140
|
+
}
|
|
141
|
+
console.log();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Copy .claude/
|
|
145
|
+
await copyDir(
|
|
146
|
+
path.join(PACKAGE_DIR, '.claude'),
|
|
147
|
+
path.join(target, '.claude')
|
|
148
|
+
);
|
|
149
|
+
console.log(' [ok] .claude/');
|
|
150
|
+
|
|
151
|
+
// Copy .tas/
|
|
152
|
+
await copyDir(
|
|
153
|
+
path.join(PACKAGE_DIR, '.tas'),
|
|
154
|
+
path.join(target, '.tas')
|
|
155
|
+
);
|
|
156
|
+
console.log(' [ok] .tas/');
|
|
157
|
+
|
|
158
|
+
// Copy CLAUDE-Example.md as CLAUDE.md (only if absent)
|
|
159
|
+
const claudeMdTarget = path.join(target, 'CLAUDE.md');
|
|
160
|
+
if (!(await exists(claudeMdTarget))) {
|
|
161
|
+
await fs.copyFile(
|
|
162
|
+
path.join(PACKAGE_DIR, 'CLAUDE-Example.md'),
|
|
163
|
+
claudeMdTarget
|
|
164
|
+
);
|
|
165
|
+
console.log(' [ok] CLAUDE.md (from CLAUDE-Example.md)');
|
|
166
|
+
} else {
|
|
167
|
+
console.log(' [--] CLAUDE.md already exists, skipped');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Copy .env.example (only if absent)
|
|
171
|
+
const envExampleTarget = path.join(target, '.env.example');
|
|
172
|
+
if (!(await exists(envExampleTarget))) {
|
|
173
|
+
await fs.copyFile(
|
|
174
|
+
path.join(PACKAGE_DIR, '.env.example'),
|
|
175
|
+
envExampleTarget
|
|
176
|
+
);
|
|
177
|
+
console.log(' [ok] .env.example');
|
|
178
|
+
} else {
|
|
179
|
+
console.log(' [--] .env.example already exists, skipped');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Copy tas-example.yaml as tas.yaml (only if absent)
|
|
183
|
+
const tasYamlTarget = path.join(target, 'tas.yaml');
|
|
184
|
+
if (!(await exists(tasYamlTarget))) {
|
|
185
|
+
await fs.copyFile(
|
|
186
|
+
path.join(PACKAGE_DIR, '.tas', 'tas-example.yaml'),
|
|
187
|
+
tasYamlTarget
|
|
188
|
+
);
|
|
189
|
+
console.log(' [ok] tas.yaml (from .tas/tas-example.yaml)');
|
|
190
|
+
} else {
|
|
191
|
+
console.log(' [--] tas.yaml already exists, skipped');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Set executable bit on tas-ado.py (Unix/macOS)
|
|
195
|
+
if (process.platform !== 'win32') {
|
|
196
|
+
const adoPy = path.join(target, '.tas', 'tools', 'tas-ado.py');
|
|
197
|
+
if (await exists(adoPy)) {
|
|
198
|
+
await fs.chmod(adoPy, 0o755);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
console.log(`
|
|
203
|
+
TAS Kit installed successfully!
|
|
204
|
+
|
|
205
|
+
Next steps:
|
|
206
|
+
1. Edit CLAUDE.md — add your project's tech stack and conventions
|
|
207
|
+
2. Edit tas.yaml — set project name, team and ADO config
|
|
208
|
+
3. Create .env — add AZURE_DEVOPS_PAT (see .env.example)
|
|
209
|
+
4. Open Claude Code — run /tas-init to initialize your project
|
|
210
|
+
|
|
211
|
+
Docs: .tas/README.md
|
|
212
|
+
`);
|
|
213
|
+
}
|
package/package.json
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@torus-engineering/tas-kit",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Torus Agentic SDLC Kit — Collection of commands, skills, rules, hooks, agents and workflows for modern AI-First SDLC",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"tas-kit": "bin/cli.js"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"bin/",
|
|
11
|
-
"lib/",
|
|
12
|
-
".claude/",
|
|
13
|
-
".tas/",
|
|
14
|
-
"CLAUDE-Example.md",
|
|
15
|
-
".env.example"
|
|
16
|
-
],
|
|
17
|
-
"engines": {
|
|
18
|
-
"node": ">=18.0.0"
|
|
19
|
-
},
|
|
20
|
-
"keywords": [
|
|
21
|
-
"claude-code",
|
|
22
|
-
"sdlc",
|
|
23
|
-
"ai",
|
|
24
|
-
"torus",
|
|
25
|
-
"tas",
|
|
26
|
-
"agentic"
|
|
27
|
-
],
|
|
28
|
-
"author": "Torus BelleSoft",
|
|
29
|
-
"license": "MIT",
|
|
30
|
-
"repository": {
|
|
31
|
-
"type": "git",
|
|
32
|
-
"url": "git+https://github.com/torus-bellesoft/agentic-sdlc-kit.git"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@torus-engineering/tas-kit",
|
|
3
|
+
"version": "1.8.0",
|
|
4
|
+
"description": "Torus Agentic SDLC Kit — Collection of commands, skills, rules, hooks, agents and workflows for modern AI-First SDLC",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"tas-kit": "bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"lib/",
|
|
12
|
+
".claude/",
|
|
13
|
+
".tas/",
|
|
14
|
+
"CLAUDE-Example.md",
|
|
15
|
+
".env.example"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=18.0.0"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"claude-code",
|
|
22
|
+
"sdlc",
|
|
23
|
+
"ai",
|
|
24
|
+
"torus",
|
|
25
|
+
"tas",
|
|
26
|
+
"agentic"
|
|
27
|
+
],
|
|
28
|
+
"author": "Torus BelleSoft",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/torus-bellesoft/agentic-sdlc-kit.git"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/.claude/agents/README.md
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# Agent Catalog
|
|
2
|
-
|
|
3
|
-
Tất cả 29 agents trong `.claude/agents/`. Mỗi agent chạy **isolated context** — không share session với main conversation.
|
|
4
|
-
|
|
5
|
-
## Flow Agents
|
|
6
|
-
|
|
7
|
-
Được trigger tự động bởi TAS commands tại các bước cụ thể trong workflow.
|
|
8
|
-
|
|
9
|
-
| Agent | Trigger tại | Điều kiện |
|
|
10
|
-
|-------|------------|-----------|
|
|
11
|
-
| `code-reviewer` | `/tas-dev` Bước 4, `/tas-review` Bước 3, `tas-implementation-complete` | Luôn chạy sau implement |
|
|
12
|
-
| `security-reviewer` | `/tas-dev` Bước 4, `/tas-review` Bước 3, `/tas-security` | Luôn chạy sau implement |
|
|
13
|
-
| `csharp-reviewer` | `/tas-dev` Bước 4, `/tas-review` Bước 3 | Khi stack là .NET/C# |
|
|
14
|
-
| `typescript-reviewer` | `/tas-dev` Bước 4, `/tas-review` Bước 3 | Khi stack là Node.js/React/TypeScript |
|
|
15
|
-
| `python-reviewer` | `/tas-dev` Bước 4, `/tas-review` Bước 3 | Khi stack là Python |
|
|
16
|
-
| `database-reviewer` | `/tas-security` | Khi stack có SQL database |
|
|
17
|
-
| `aws-reviewer` | `/tas-review` Bước 3, `/tas-security` | Khi stack có AWS infrastructure |
|
|
18
|
-
| `code-explorer` | `/tas-plan` Bước 2 | Luôn chạy khi planning |
|
|
19
|
-
| `architect` | `/tas-plan` Bước 2 | Khi Story có architectural impact |
|
|
20
|
-
| `build-resolver` | `/tas-dev` Bước 3, `/tas-bug` fix step | Khi tests vẫn fail sau 1 lần tự fix |
|
|
21
|
-
| `e2e-runner` | `/tas-verify` Bước 4.5 | Khi Feature có E2E test cases |
|
|
22
|
-
| `doc-updater` | `/tas-dev` Bước 5 | Optional — khi Story thay đổi API/schema/setup |
|
|
23
|
-
|
|
24
|
-
## Utility Agents
|
|
25
|
-
|
|
26
|
-
Dùng on-demand — không trigger tự động. Gọi khi cần theo từng tình huống cụ thể.
|
|
27
|
-
|
|
28
|
-
### Planning & Architecture
|
|
29
|
-
|
|
30
|
-
| Agent | Mục đích | Khi nào dùng |
|
|
31
|
-
|-------|---------|-------------|
|
|
32
|
-
| `planner` | Lập kế hoạch implement | Feature phức tạp, refactor lớn chưa có Story |
|
|
33
|
-
| `architect` | Thiết kế system-level | Quyết định architectural ảnh hưởng nhiều services |
|
|
34
|
-
| `code-architect` | Thiết kế code structure | Design layers, interfaces, dependency direction |
|
|
35
|
-
| `docs-lookup` | Tìm thông tin trong docs | Khi cần tra cứu PRD/SAD/ADR/Story mà không đọc hết |
|
|
36
|
-
|
|
37
|
-
### Code Quality
|
|
38
|
-
|
|
39
|
-
| Agent | Mục đích | Khi nào dùng |
|
|
40
|
-
|-------|---------|-------------|
|
|
41
|
-
| `tdd-guide` | Test-driven development | Feature mới, bug fix — enforce Red-Green-Refactor |
|
|
42
|
-
| `refactor-cleaner` | Dọn dead code, simplify | Code maintenance, sau khi feature ổn định |
|
|
43
|
-
| `code-simplifier` | Giảm complexity | Code quá phức tạp, over-engineered |
|
|
44
|
-
| `comment-analyzer` | Kiểm tra/cập nhật comments | Docs/comments lỗi thời hoặc thiếu |
|
|
45
|
-
| `pr-test-analyzer` | Phân tích test coverage của PR | Trước/sau khi tạo PR — check coverage gaps |
|
|
46
|
-
| `silent-failure-hunter` | Tìm hidden bugs | Nghi ngờ có lỗi ẩn, swallowed exceptions |
|
|
47
|
-
| `type-design-analyzer` | TypeScript type design | Type phức tạp, overuse of `any`, weak generics |
|
|
48
|
-
|
|
49
|
-
### Performance & Optimization
|
|
50
|
-
|
|
51
|
-
| Agent | Mục đích | Khi nào dùng |
|
|
52
|
-
|-------|---------|-------------|
|
|
53
|
-
| `performance-optimizer` | Diagnose perf issues | API chậm, memory cao, re-render bottleneck |
|
|
54
|
-
| `seo-specialist` | SEO cho React/Next.js | Optimize meta tags, SSR/SSG, Core Web Vitals |
|
|
55
|
-
|
|
56
|
-
### Infrastructure & Build
|
|
57
|
-
|
|
58
|
-
| Agent | Mục đích | Khi nào dùng |
|
|
59
|
-
|-------|---------|-------------|
|
|
60
|
-
| `pytorch-build-resolver` | Fix ML/Python dependency issues | CUDA mismatch, torch/tf install fail |
|
|
61
|
-
| `harness-optimizer` | Optimize Claude Code setup | Khi setup cảm thấy chậm hoặc token-wasteful |
|
|
62
|
-
|
|
63
|
-
### Operations
|
|
64
|
-
|
|
65
|
-
| Agent | Mục đích | Khi nào dùng |
|
|
66
|
-
|-------|---------|-------------|
|
|
67
|
-
| `ado-agent` | Azure DevOps operations | Sync work items, batch ADO updates |
|
|
68
|
-
| `loop-operator` | Repetitive operations | Apply cùng operation cho nhiều files/entities |
|
|
69
|
-
| `conversation-analyzer` | Phân tích user feedback | Trước khi viết PRD/Feature spec |
|
|
70
|
-
| `code-explorer` | Codebase mapping | Trước khi plan — "how does X work?" |
|
|
71
|
-
|
|
72
|
-
## Cách gọi Utility Agent
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
Agent({
|
|
76
|
-
subagent_type: "<agent-name>",
|
|
77
|
-
prompt: "..."
|
|
78
|
-
})
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Prompt cần đủ: scope (cái gì), context (tại sao), focus (ưu tiên gì), format (output dạng nào).
|
|
82
|
-
|
|
83
|
-
> Orchestration patterns và parallel execution: xem `.claude/rules/common/agents.md`
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ado-agent
|
|
3
|
-
description: Specialized agent for Azure DevOps operations. Use when syncing work items, pushing/pulling ADO data, or performing batch ADO updates that require isolated execution.
|
|
4
|
-
allowed-tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# ADO Agent
|
|
8
|
-
|
|
9
|
-
You are a specialized Azure DevOps integration agent. Your job is to execute ADO operations cleanly and return only the result — success, failure, or data — to the calling session.
|
|
10
|
-
|
|
11
|
-
## Responsibilities
|
|
12
|
-
- Read artifact .md files (Epic, Feature, Story, Bug) and extract frontmatter (ado_id, ado_type, ado_state)
|
|
13
|
-
- Run `python .tas/tools/tas-ado.py` commands to sync with Azure DevOps
|
|
14
|
-
- Report what changed, what failed, and why — nothing else
|
|
15
|
-
|
|
16
|
-
## How to operate
|
|
17
|
-
1. Read `tas.yaml` at project root for ADO project config (org, project, team)
|
|
18
|
-
2. Read the target artifact file(s) to get current state
|
|
19
|
-
3. Execute the appropriate `tas-ado.py` command
|
|
20
|
-
4. Report back: operation performed, ADO ID(s) affected, new state
|
|
21
|
-
|
|
22
|
-
## Commands available
|
|
23
|
-
```
|
|
24
|
-
python .tas/tools/tas-ado.py create <type> <temp-id> [--parent-id <id>]
|
|
25
|
-
python .tas/tools/tas-ado.py get <ado-id>
|
|
26
|
-
python .tas/tools/tas-ado.py update <type> <ado-id> [--assign <name>] [--status <state>]
|
|
27
|
-
python .tas/tools/tas-ado.py delete <type> <ado-id>
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Output format
|
|
31
|
-
Return a concise summary:
|
|
32
|
-
- Operation: what was done
|
|
33
|
-
- Result: success/failure
|
|
34
|
-
- ADO IDs: affected work items
|
|
35
|
-
- Changes: what was updated (state, fields)
|
|
36
|
-
- Errors: if any, exact error message
|
|
37
|
-
|
|
38
|
-
Do NOT make assumptions about ADO project config — always read `tas.yaml` first.
|
|
39
|
-
Do NOT update .md files unless explicitly instructed.
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: code-architect
|
|
3
|
-
description: Use when designing code structure within a service or module — layers, abstractions, interfaces, dependency direction. Bridges the gap between system architecture (architect agent) and implementation (code). Produces design specs, not code.
|
|
4
|
-
allowed-tools: Read, Grep, Glob
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Code Architect Agent
|
|
8
|
-
|
|
9
|
-
You are a code architecture agent. You design how code should be structured — layers, abstractions, interfaces, data models — without writing the actual implementation. You produce design decisions for developers to implement.
|
|
10
|
-
|
|
11
|
-
## Responsibilities
|
|
12
|
-
- Define layer boundaries (API / Application / Domain / Infrastructure)
|
|
13
|
-
- Design interfaces and contracts before implementation
|
|
14
|
-
- Identify where patterns apply: Repository, Service, Factory, Strategy, etc.
|
|
15
|
-
- Ensure design aligns with ADRs and SAD
|
|
16
|
-
- Flag over-engineering and under-engineering equally
|
|
17
|
-
|
|
18
|
-
## How to operate
|
|
19
|
-
|
|
20
|
-
1. Read relevant ADRs (`docs/adr/`) and SAD sections that constrain the design
|
|
21
|
-
2. Understand the feature or module being designed
|
|
22
|
-
3. Explore existing patterns in the codebase (Grep for similar implementations) — follow what exists unless it's clearly wrong
|
|
23
|
-
4. Produce a design that is:
|
|
24
|
-
- **Minimal**: only as complex as the problem requires
|
|
25
|
-
- **Consistent**: matches existing patterns in the codebase
|
|
26
|
-
- **Testable**: dependencies are injectable, side effects are explicit
|
|
27
|
-
|
|
28
|
-
## Stack patterns
|
|
29
|
-
- **.NET**: Clean Architecture layers, CQRS with MediatR, Repository over DbContext
|
|
30
|
-
- **Node.js**: Service / Repository split, dependency injection via constructor
|
|
31
|
-
- **Python**: Service layer, dataclasses/Pydantic for models, avoid global state
|
|
32
|
-
- **React**: Container/Presentational split, custom hooks for logic, avoid prop drilling
|
|
33
|
-
|
|
34
|
-
## Output format
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
**Design: [Feature/Module name]**
|
|
38
|
-
|
|
39
|
-
**Layer structure**:
|
|
40
|
-
```
|
|
41
|
-
API Layer → [what lives here]
|
|
42
|
-
Application → [what lives here]
|
|
43
|
-
Domain → [what lives here]
|
|
44
|
-
Infrastructure → [what lives here]
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
**Key interfaces/contracts**:
|
|
48
|
-
```
|
|
49
|
-
IXxxRepository: [methods]
|
|
50
|
-
IXxxService: [methods]
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
**Data models**:
|
|
54
|
-
- `XxxDto`: [fields and purpose]
|
|
55
|
-
- `XxxEntity`: [fields and purpose]
|
|
56
|
-
|
|
57
|
-
**Patterns applied**: [Repository / CQRS / Strategy / etc. + why]
|
|
58
|
-
|
|
59
|
-
**What NOT to do**: [common pitfalls for this design]
|
|
60
|
-
|
|
61
|
-
**ADR reference**: [existing ADR that applies, or flag if new ADR needed]
|
|
62
|
-
---
|