amazingteam 3.0.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/.ai-team/agents/architect.md +144 -0
- package/.ai-team/agents/ci-analyst.md +188 -0
- package/.ai-team/agents/developer.md +176 -0
- package/.ai-team/agents/planner.md +355 -0
- package/.ai-team/agents/qa.md +189 -0
- package/.ai-team/agents/reviewer.md +211 -0
- package/.ai-team/agents/triage.md +146 -0
- package/.ai-team/commands/ci-analyze.md +116 -0
- package/.ai-team/commands/design.md +100 -0
- package/.ai-team/commands/implement.md +108 -0
- package/.ai-team/commands/release-check.md +142 -0
- package/.ai-team/commands/review.md +142 -0
- package/.ai-team/commands/test.md +115 -0
- package/.ai-team/commands/triage.md +138 -0
- package/.ai-team/memory/architect/architecture_notes.md +67 -0
- package/.ai-team/memory/architect/design_rationale.md +113 -0
- package/.ai-team/memory/architect/module_map.md +84 -0
- package/.ai-team/memory/ci-analyst/failure_patterns.md +102 -0
- package/.ai-team/memory/ci-analyst/runbook_references.md +87 -0
- package/.ai-team/memory/developer/bug_investigation.md +102 -0
- package/.ai-team/memory/developer/build_issues.md +115 -0
- package/.ai-team/memory/developer/implementation_notes.md +83 -0
- package/.ai-team/memory/failures/failure_library.md +103 -0
- package/.ai-team/memory/planner/decomposition_notes.md +82 -0
- package/.ai-team/memory/planner/flow_rules.md +86 -0
- package/.ai-team/memory/planner/github_issue_patterns.md +229 -0
- package/.ai-team/memory/qa/regression_cases.md +101 -0
- package/.ai-team/memory/qa/test_strategy.md +138 -0
- package/.ai-team/memory/qa/validation_notes.md +110 -0
- package/.ai-team/memory/reviewer/quality_rules.md +105 -0
- package/.ai-team/memory/reviewer/recurring_risks.md +109 -0
- package/.ai-team/memory/reviewer/review_notes.md +124 -0
- package/.ai-team/memory/triage/classification_heuristics.md +82 -0
- package/.ai-team/memory/triage/debug_notes.md +87 -0
- package/.ai-team/opencode.template.jsonc +216 -0
- package/.ai-team/skills/bugfix-playbook/skill.md +174 -0
- package/.ai-team/skills/ci-failure-analysis/skill.md +176 -0
- package/.ai-team/skills/issue-triage/skill.md +163 -0
- package/.ai-team/skills/regression-checklist/skill.md +176 -0
- package/.ai-team/skills/release-readiness-check/skill.md +216 -0
- package/.ai-team/skills/repo-architecture-reader/skill.md +139 -0
- package/.ai-team/skills/safe-refactor-checklist/skill.md +215 -0
- package/.ai-team/skills/task-breakdown-and-dispatch/skill.md +151 -0
- package/.ai-team/skills/test-first-feature-dev/skill.md +205 -0
- package/.ai-team/workflows/ci.yml +81 -0
- package/.ai-team/workflows/nightly-ai-maintenance.yml +129 -0
- package/.ai-team/workflows/opencode.yml +33 -0
- package/.ai-team/workflows/pr-check.yml +41 -0
- package/.foundation/foundation.lock +38 -0
- package/.foundation/local-overrides.md +97 -0
- package/.foundation/upgrade-history.md +38 -0
- package/.opencode/agents/architect.md +38 -0
- package/.opencode/agents/ci-analyst.md +38 -0
- package/.opencode/agents/developer.md +43 -0
- package/.opencode/agents/planner.md +47 -0
- package/.opencode/agents/qa.md +34 -0
- package/.opencode/agents/reviewer.md +38 -0
- package/.opencode/agents/triage.md +37 -0
- package/.opencode/commands/auto.md +264 -0
- package/.opencode/commands/breakdown-issue.md +94 -0
- package/.opencode/commands/ci-analyze.md +15 -0
- package/.opencode/commands/close-parent-task.md +122 -0
- package/.opencode/commands/design.md +15 -0
- package/.opencode/commands/dispatch-next.md +102 -0
- package/.opencode/commands/implement.md +16 -0
- package/.opencode/commands/release-check.md +16 -0
- package/.opencode/commands/resume.md +88 -0
- package/.opencode/commands/review.md +15 -0
- package/.opencode/commands/show-blockers.md +97 -0
- package/.opencode/commands/summarize-parent.md +121 -0
- package/.opencode/commands/test.md +15 -0
- package/.opencode/commands/triage.md +109 -0
- package/.opencode/skills/bugfix-playbook/SKILL.md +81 -0
- package/.opencode/skills/ci-failure-analysis/SKILL.md +94 -0
- package/.opencode/skills/issue-triage/SKILL.md +80 -0
- package/.opencode/skills/regression-checklist/SKILL.md +81 -0
- package/.opencode/skills/release-readiness-check/SKILL.md +81 -0
- package/.opencode/skills/repo-architecture-reader/SKILL.md +65 -0
- package/.opencode/skills/safe-refactor-checklist/SKILL.md +76 -0
- package/.opencode/skills/task-breakdown-and-dispatch/SKILL.md +255 -0
- package/.opencode/skills/test-first-feature-dev/SKILL.md +78 -0
- package/AGENTS.md +879 -0
- package/CHANGELOG.md +261 -0
- package/LICENSE +21 -0
- package/README.md +1215 -0
- package/VERSION +1 -0
- package/action/__tests__/downloader.test.js +251 -0
- package/action/__tests__/merger.test.js +156 -0
- package/action/__tests__/path-resolver.test.js +199 -0
- package/action/__tests__/validator.test.js +310 -0
- package/action/action.yml +61 -0
- package/action/index.js +223 -0
- package/action/lib/downloader.js +344 -0
- package/action/lib/merger.js +170 -0
- package/action/lib/path-resolver.js +176 -0
- package/action/lib/setup.js +286 -0
- package/action/lib/validator.js +324 -0
- package/cli/__tests__/cli.test.js +270 -0
- package/cli/amazingteam.cjs +225 -0
- package/cli/commands/check-update.cjs +159 -0
- package/cli/commands/init.cjs +412 -0
- package/cli/commands/local.cjs +264 -0
- package/cli/commands/migrate.cjs +316 -0
- package/cli/commands/status.cjs +241 -0
- package/cli/commands/upgrade.cjs +213 -0
- package/cli/commands/validate.cjs +259 -0
- package/cli/commands/version.cjs +59 -0
- package/cli/sync.cjs +237 -0
- package/dist/index.js +35 -0
- package/docs/architecture/overview.md +138 -0
- package/docs/blocker_resolution_design.md +372 -0
- package/docs/bootstrap-model.md +356 -0
- package/docs/config-reference.md +458 -0
- package/docs/how-to-use.md +178 -0
- package/docs/migration-to-v3.md +355 -0
- package/docs/overlay-guide.md +156 -0
- package/docs/patterns/README.md +67 -0
- package/docs/quick-start-v3.md +330 -0
- package/docs/releases/README.md +64 -0
- package/docs/runbooks/ci/README.md +62 -0
- package/docs/runbooks/ci/build-debug.md +120 -0
- package/docs/runbooks/ci/flaky-tests.md +127 -0
- package/docs/runbooks/getting-started.md +81 -0
- package/docs/upgrade-policy.md +188 -0
- package/docs/versioning.md +199 -0
- package/overlays/README.md +30 -0
- package/overlays/ai-agent-product/.ai-team/skills/llm-integration/skill.md +99 -0
- package/overlays/ai-agent-product/docs/ai-agent-architecture.md +68 -0
- package/overlays/ai-agent-product/overlay.yaml +26 -0
- package/overlays/cpp-qt-desktop/.ai-team/skills/qt-signals-slots/skill.md +60 -0
- package/overlays/cpp-qt-desktop/docs/qt-conventions.md +64 -0
- package/overlays/cpp-qt-desktop/overlay.yaml +22 -0
- package/overlays/python-backend/.ai-team/skills/python-testing/skill.md +90 -0
- package/overlays/python-backend/docs/python-style.md +78 -0
- package/overlays/python-backend/overlay.yaml +22 -0
- package/overlays/web-fullstack/.ai-team/skills/frontend-testing/skill.md +70 -0
- package/overlays/web-fullstack/docs/frontend-conventions.md +68 -0
- package/overlays/web-fullstack/overlay.yaml +26 -0
- package/package.json +84 -0
- package/presets/default.yaml +161 -0
- package/presets/go.yaml +43 -0
- package/presets/python.yaml +43 -0
- package/presets/typescript.yaml +40 -0
- package/schemas/config.schema.json +239 -0
- package/scripts/diff_foundation_vs_project.sh +134 -0
- package/scripts/generate_docs.sh +200 -0
- package/scripts/init_project.sh +455 -0
- package/scripts/plan_upgrade.sh +268 -0
- package/scripts/upgrade_foundation.sh +365 -0
- package/scripts/validate-foundation.cjs +278 -0
- package/scripts/validate_foundation.sh +192 -0
- package/scripts/validate_project_setup.sh +171 -0
- package/tasks/README.md +94 -0
- package/tasks/_template/analysis.md +76 -0
- package/tasks/_template/design.md +121 -0
- package/tasks/_template/implementation.md +121 -0
- package/tasks/_template/release.md +119 -0
- package/tasks/_template/review.md +131 -0
- package/tasks/_template/subtasks/task.yaml +24 -0
- package/tasks/_template/task.yaml +75 -0
- package/tasks/_template/validation.md +128 -0
- package/templates/amazingteam.yml +81 -0
- package/templates/gitignore +14 -0
- package/templates/opencode.jsonc +216 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrade Command
|
|
3
|
+
* Upgrade to a new version
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const https = require('https');
|
|
9
|
+
|
|
10
|
+
const VERSION = require('../../package.json').version;
|
|
11
|
+
const PACKAGE_NAME = 'amazingteam';
|
|
12
|
+
const REGISTRY = 'https://registry.npmjs.org';
|
|
13
|
+
|
|
14
|
+
function getLatestVersion() {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const url = `${REGISTRY}/${PACKAGE_NAME}/latest`;
|
|
17
|
+
|
|
18
|
+
https.get(url, {
|
|
19
|
+
timeout: 10000,
|
|
20
|
+
headers: {
|
|
21
|
+
'User-Agent': `${PACKAGE_NAME}-cli/${VERSION}`
|
|
22
|
+
}
|
|
23
|
+
}, (response) => {
|
|
24
|
+
if (response.statusCode !== 200) {
|
|
25
|
+
reject(new Error(`Registry returned ${response.statusCode}`));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let data = '';
|
|
30
|
+
response.on('data', chunk => { data += chunk; });
|
|
31
|
+
response.on('end', () => {
|
|
32
|
+
try {
|
|
33
|
+
const pkg = JSON.parse(data);
|
|
34
|
+
resolve(pkg.version);
|
|
35
|
+
} catch (err) {
|
|
36
|
+
reject(new Error('Failed to parse registry response'));
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}).on('error', reject).on('timeout', () => {
|
|
40
|
+
reject(new Error('Registry request timeout'));
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function compareVersions(a, b) {
|
|
46
|
+
const [aM, aN, aP] = a.split('.').map(Number);
|
|
47
|
+
const [bM, bN, bP] = b.split('.').map(Number);
|
|
48
|
+
|
|
49
|
+
if (aM !== bM) return aM - bM;
|
|
50
|
+
if (aN !== bN) return aN - bN;
|
|
51
|
+
return aP - bP;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getVersionDiff(from, to) {
|
|
55
|
+
const [fM, fN, fP] = from.split('.').map(Number);
|
|
56
|
+
const [tM, tN, tP] = to.split('.').map(Number);
|
|
57
|
+
|
|
58
|
+
if (tM > fM) return 'major';
|
|
59
|
+
if (tN > fN) return 'minor';
|
|
60
|
+
return 'patch';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function run(options, positional) {
|
|
64
|
+
const projectPath = process.cwd();
|
|
65
|
+
const configPath = path.join(projectPath, 'amazingteam.config.yaml');
|
|
66
|
+
const workflowPath = path.join(projectPath, '.github', 'workflows', 'amazingteam.yml');
|
|
67
|
+
|
|
68
|
+
// Check if initialized
|
|
69
|
+
if (!fs.existsSync(configPath)) {
|
|
70
|
+
console.error('\n❌ AmazingTeam not initialized in this directory.');
|
|
71
|
+
console.error(' Run "amazingteam init" first.\n');
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const targetVersion = options.to;
|
|
76
|
+
const dryRun = options.dryRun;
|
|
77
|
+
|
|
78
|
+
console.log('\n🔄 AmazingTeam Upgrade\n');
|
|
79
|
+
|
|
80
|
+
// Determine target version
|
|
81
|
+
let newVersion;
|
|
82
|
+
try {
|
|
83
|
+
newVersion = targetVersion || await getLatestVersion();
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error('❌ Failed to get latest version:', error.message);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Read current version from config
|
|
90
|
+
let currentVersion = VERSION;
|
|
91
|
+
const configContent = fs.readFileSync(configPath, 'utf-8');
|
|
92
|
+
const versionMatch = configContent.match(/version:\s*["']?(\d+\.\d+\.\d+)/);
|
|
93
|
+
if (versionMatch) {
|
|
94
|
+
currentVersion = versionMatch[1];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
console.log(`Current version: ${currentVersion}`);
|
|
98
|
+
console.log(`Target version: ${newVersion}`);
|
|
99
|
+
|
|
100
|
+
// Check if already up to date
|
|
101
|
+
if (compareVersions(currentVersion, newVersion) >= 0 && !options.force) {
|
|
102
|
+
console.log('\n✅ Already up to date!\n');
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Check for breaking changes
|
|
107
|
+
const diff = getVersionDiff(currentVersion, newVersion);
|
|
108
|
+
if (diff === 'major') {
|
|
109
|
+
console.log('\n⚠️ MAJOR version upgrade detected!');
|
|
110
|
+
console.log(' This may contain breaking changes.');
|
|
111
|
+
console.log(' Please review the changelog before proceeding.\n');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (dryRun) {
|
|
115
|
+
console.log('\n📝 Dry run - showing changes that would be made:\n');
|
|
116
|
+
} else {
|
|
117
|
+
console.log('\n📦 Upgrading...\n');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const changes = [];
|
|
121
|
+
|
|
122
|
+
// Update amazingteam.config.yaml
|
|
123
|
+
if (fs.existsSync(configPath)) {
|
|
124
|
+
let content = fs.readFileSync(configPath, 'utf-8');
|
|
125
|
+
const oldContent = content;
|
|
126
|
+
|
|
127
|
+
content = content.replace(
|
|
128
|
+
/version:\s*["']?\d+\.\d+\.\d+["']?/g,
|
|
129
|
+
`version: "${newVersion}"`
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
if (content !== oldContent) {
|
|
133
|
+
if (dryRun) {
|
|
134
|
+
console.log(' Would update: amazingteam.config.yaml');
|
|
135
|
+
console.log(` version: ${currentVersion} → ${newVersion}`);
|
|
136
|
+
} else {
|
|
137
|
+
fs.writeFileSync(configPath, content);
|
|
138
|
+
console.log(' ✅ Updated: amazingteam.config.yaml');
|
|
139
|
+
}
|
|
140
|
+
changes.push('config');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Update workflow file
|
|
145
|
+
if (fs.existsSync(workflowPath)) {
|
|
146
|
+
let content = fs.readFileSync(workflowPath, 'utf-8');
|
|
147
|
+
const oldContent = content;
|
|
148
|
+
|
|
149
|
+
// Update action version references
|
|
150
|
+
content = content.replace(
|
|
151
|
+
/amazingteam-action@v?\d+\.\d+\.\d+/g,
|
|
152
|
+
`amazingteam-action@v${newVersion}`
|
|
153
|
+
);
|
|
154
|
+
content = content.replace(
|
|
155
|
+
/version:\s*['"]?\d+\.\d+\.\d+['"]?/g,
|
|
156
|
+
`version: '${newVersion}'`
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
if (content !== oldContent) {
|
|
160
|
+
if (dryRun) {
|
|
161
|
+
console.log(' Would update: .github/workflows/amazingteam.yml');
|
|
162
|
+
console.log(` action: @v${currentVersion} → @v${newVersion}`);
|
|
163
|
+
} else {
|
|
164
|
+
fs.writeFileSync(workflowPath, content);
|
|
165
|
+
console.log(' ✅ Updated: .github/workflows/amazingteam.yml');
|
|
166
|
+
}
|
|
167
|
+
changes.push('workflow');
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (changes.length === 0) {
|
|
172
|
+
console.log(' No changes needed.');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (!dryRun && changes.length > 0) {
|
|
176
|
+
console.log('\n✅ Upgrade complete!\n');
|
|
177
|
+
console.log('Next steps:');
|
|
178
|
+
console.log(' 1. Review the changes');
|
|
179
|
+
console.log(' 2. Run `amazingteam local` to download the new version');
|
|
180
|
+
console.log(' 3. Test your project');
|
|
181
|
+
console.log(' 4. Commit the changes\n');
|
|
182
|
+
} else if (dryRun) {
|
|
183
|
+
console.log('\nRun without --dry-run to apply changes.\n');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function help() {
|
|
188
|
+
return `
|
|
189
|
+
amazingteam upgrade - Upgrade to a new version
|
|
190
|
+
|
|
191
|
+
Usage:
|
|
192
|
+
amazingteam upgrade [options]
|
|
193
|
+
|
|
194
|
+
Options:
|
|
195
|
+
--to <version> Upgrade to specific version
|
|
196
|
+
--dry-run Preview changes without applying
|
|
197
|
+
--force Force upgrade even if already up to date
|
|
198
|
+
|
|
199
|
+
Examples:
|
|
200
|
+
amazingteam upgrade Upgrade to latest version
|
|
201
|
+
amazingteam upgrade --to 3.1.0 Upgrade to specific version
|
|
202
|
+
amazingteam upgrade --dry-run Preview upgrade changes
|
|
203
|
+
|
|
204
|
+
What gets updated:
|
|
205
|
+
- amazingteam.config.yaml version
|
|
206
|
+
- .github/workflows/amazingteam.yml action reference
|
|
207
|
+
|
|
208
|
+
Note: After upgrading, run \`amazingteam local\` to download the new version
|
|
209
|
+
for local development.
|
|
210
|
+
`;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
module.exports = { run, help };
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate Command
|
|
3
|
+
* Validate configuration and project structure
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
const VERSION = require('../../package.json').version;
|
|
10
|
+
|
|
11
|
+
function validateConfig(configPath) {
|
|
12
|
+
const issues = [];
|
|
13
|
+
|
|
14
|
+
if (!fs.existsSync(configPath)) {
|
|
15
|
+
return { valid: false, issues: ['amazingteam.config.yaml not found'] };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
19
|
+
|
|
20
|
+
// Check required fields
|
|
21
|
+
if (!content.includes('version:')) {
|
|
22
|
+
issues.push('Missing required field: version');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!content.includes('project:')) {
|
|
26
|
+
issues.push('Missing required field: project');
|
|
27
|
+
} else {
|
|
28
|
+
if (!content.match(/name:\s*["']?\w+/)) {
|
|
29
|
+
issues.push('Missing required field: project.name');
|
|
30
|
+
}
|
|
31
|
+
if (!content.match(/language:\s*["']?\w+/)) {
|
|
32
|
+
issues.push('Missing required field: project.language');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
valid: issues.length === 0,
|
|
38
|
+
issues
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function validateStructure(projectPath) {
|
|
43
|
+
const issues = [];
|
|
44
|
+
|
|
45
|
+
const requiredDirs = [
|
|
46
|
+
'.ai-team',
|
|
47
|
+
'.ai-team/memory',
|
|
48
|
+
'tasks'
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
for (const dir of requiredDirs) {
|
|
52
|
+
if (!fs.existsSync(path.join(projectPath, dir))) {
|
|
53
|
+
issues.push(`Missing directory: ${dir}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const requiredFiles = [
|
|
58
|
+
'amazingteam.config.yaml',
|
|
59
|
+
'.github/workflows/amazingteam.yml'
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
for (const file of requiredFiles) {
|
|
63
|
+
if (!fs.existsSync(path.join(projectPath, file))) {
|
|
64
|
+
issues.push(`Missing file: ${file}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const recommendedFiles = [
|
|
69
|
+
'opencode.jsonc',
|
|
70
|
+
'AGENTS.md',
|
|
71
|
+
'.gitignore'
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
const missingRecommended = recommendedFiles.filter(
|
|
75
|
+
file => !fs.existsSync(path.join(projectPath, file))
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
valid: issues.length === 0,
|
|
80
|
+
issues,
|
|
81
|
+
warnings: missingRecommended.map(f => `Recommended file missing: ${f}`)
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function validateWorkflow(workflowPath) {
|
|
86
|
+
const issues = [];
|
|
87
|
+
|
|
88
|
+
if (!fs.existsSync(workflowPath)) {
|
|
89
|
+
return { valid: false, issues: ['Workflow file not found'] };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const content = fs.readFileSync(workflowPath, 'utf-8');
|
|
93
|
+
|
|
94
|
+
// Check for required permissions
|
|
95
|
+
if (!content.includes('contents: write')) {
|
|
96
|
+
issues.push('Missing permission: contents: write');
|
|
97
|
+
}
|
|
98
|
+
if (!content.includes('pull-requests: write')) {
|
|
99
|
+
issues.push('Missing permission: pull-requests: write');
|
|
100
|
+
}
|
|
101
|
+
if (!content.includes('issues: write')) {
|
|
102
|
+
issues.push('Missing permission: issues: write');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Check for AmazingTeam action
|
|
106
|
+
if (!content.includes('amazingteam-action')) {
|
|
107
|
+
issues.push('AmazingTeam action not referenced in workflow');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Check for secrets
|
|
111
|
+
if (!content.includes('ALIBABA_CODING_PLAN_API_KEY') &&
|
|
112
|
+
!content.includes('OPENCODE_API_KEY')) {
|
|
113
|
+
issues.push('No API key secret referenced');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
valid: issues.length === 0,
|
|
118
|
+
issues
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function validateGitignore(projectPath) {
|
|
123
|
+
const issues = [];
|
|
124
|
+
const warnings = [];
|
|
125
|
+
|
|
126
|
+
const gitignorePath = path.join(projectPath, '.gitignore');
|
|
127
|
+
|
|
128
|
+
if (!fs.existsSync(gitignorePath)) {
|
|
129
|
+
issues.push('.gitignore not found');
|
|
130
|
+
return { valid: false, issues, warnings };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const content = fs.readFileSync(gitignorePath, 'utf-8');
|
|
134
|
+
|
|
135
|
+
if (!content.includes('.ai-team-local/')) {
|
|
136
|
+
warnings.push('.ai-team-local/ not in .gitignore');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!content.includes('.ai-team-cache/')) {
|
|
140
|
+
warnings.push('.ai-team-cache/ not in .gitignore');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
valid: issues.length === 0,
|
|
145
|
+
issues,
|
|
146
|
+
warnings
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async function run(options, positional) {
|
|
151
|
+
const projectPath = process.cwd();
|
|
152
|
+
const configPath = path.join(projectPath, 'amazingteam.config.yaml');
|
|
153
|
+
const workflowPath = path.join(projectPath, '.github', 'workflows', 'amazingteam.yml');
|
|
154
|
+
|
|
155
|
+
console.log('\n🔍 Validating AmazingTeam setup\n');
|
|
156
|
+
|
|
157
|
+
let allValid = true;
|
|
158
|
+
const allIssues = [];
|
|
159
|
+
const allWarnings = [];
|
|
160
|
+
|
|
161
|
+
// Validate config
|
|
162
|
+
console.log('Checking configuration...');
|
|
163
|
+
const configResult = validateConfig(configPath);
|
|
164
|
+
if (configResult.valid) {
|
|
165
|
+
console.log(' ✅ Configuration valid');
|
|
166
|
+
} else {
|
|
167
|
+
console.log(' ❌ Configuration issues:');
|
|
168
|
+
configResult.issues.forEach(issue => {
|
|
169
|
+
console.log(` - ${issue}`);
|
|
170
|
+
});
|
|
171
|
+
allIssues.push(...configResult.issues);
|
|
172
|
+
allValid = false;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Validate structure
|
|
176
|
+
console.log('Checking project structure...');
|
|
177
|
+
const structResult = validateStructure(projectPath);
|
|
178
|
+
if (structResult.valid) {
|
|
179
|
+
console.log(' ✅ Structure valid');
|
|
180
|
+
} else {
|
|
181
|
+
console.log(' ❌ Structure issues:');
|
|
182
|
+
structResult.issues.forEach(issue => {
|
|
183
|
+
console.log(` - ${issue}`);
|
|
184
|
+
});
|
|
185
|
+
allIssues.push(...structResult.issues);
|
|
186
|
+
allValid = false;
|
|
187
|
+
}
|
|
188
|
+
if (structResult.warnings.length > 0) {
|
|
189
|
+
structResult.warnings.forEach(w => console.log(` ⚠️ ${w}`));
|
|
190
|
+
allWarnings.push(...structResult.warnings);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Validate workflow
|
|
194
|
+
console.log('Checking workflow...');
|
|
195
|
+
const workflowResult = validateWorkflow(workflowPath);
|
|
196
|
+
if (workflowResult.valid) {
|
|
197
|
+
console.log(' ✅ Workflow valid');
|
|
198
|
+
} else {
|
|
199
|
+
console.log(' ❌ Workflow issues:');
|
|
200
|
+
workflowResult.issues.forEach(issue => {
|
|
201
|
+
console.log(` - ${issue}`);
|
|
202
|
+
});
|
|
203
|
+
allIssues.push(...workflowResult.issues);
|
|
204
|
+
allValid = false;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Validate gitignore
|
|
208
|
+
console.log('Checking .gitignore...');
|
|
209
|
+
const gitignoreResult = validateGitignore(projectPath);
|
|
210
|
+
if (gitignoreResult.valid) {
|
|
211
|
+
console.log(' ✅ .gitignore valid');
|
|
212
|
+
} else {
|
|
213
|
+
gitignoreResult.issues.forEach(issue => {
|
|
214
|
+
console.log(` - ${issue}`);
|
|
215
|
+
});
|
|
216
|
+
allIssues.push(...gitignoreResult.issues);
|
|
217
|
+
allValid = false;
|
|
218
|
+
}
|
|
219
|
+
if (gitignoreResult.warnings.length > 0) {
|
|
220
|
+
gitignoreResult.warnings.forEach(w => console.log(` ⚠️ ${w}`));
|
|
221
|
+
allWarnings.push(...gitignoreResult.warnings);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Summary
|
|
225
|
+
console.log('\n' + '='.repeat(40));
|
|
226
|
+
|
|
227
|
+
if (allValid && allWarnings.length === 0) {
|
|
228
|
+
console.log('✅ All validations passed!\n');
|
|
229
|
+
} else if (allValid) {
|
|
230
|
+
console.log(`✅ Valid (${allWarnings.length} warnings)\n`);
|
|
231
|
+
} else {
|
|
232
|
+
console.log(`❌ ${allIssues.length} issue(s) found\n`);
|
|
233
|
+
console.log('Fix the issues above and run validate again.\n');
|
|
234
|
+
process.exit(1);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function help() {
|
|
239
|
+
return `
|
|
240
|
+
amazingteam validate - Validate configuration and project structure
|
|
241
|
+
|
|
242
|
+
Usage:
|
|
243
|
+
amazingteam validate
|
|
244
|
+
|
|
245
|
+
Validates:
|
|
246
|
+
- amazingteam.config.yaml configuration
|
|
247
|
+
- Required directories (.ai-team/, tasks/)
|
|
248
|
+
- GitHub workflow configuration
|
|
249
|
+
- .gitignore entries
|
|
250
|
+
|
|
251
|
+
Exit codes:
|
|
252
|
+
0 - All validations passed
|
|
253
|
+
1 - Validation failures found
|
|
254
|
+
|
|
255
|
+
Run this after initialization or upgrades to verify setup.
|
|
256
|
+
`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
module.exports = { run, help };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version Command
|
|
3
|
+
* Show current foundation version
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
const VERSION = require('../../package.json').version;
|
|
10
|
+
|
|
11
|
+
function run(options, positional) {
|
|
12
|
+
const projectPath = process.cwd();
|
|
13
|
+
const configPath = path.join(projectPath, 'amazingteam.config.yaml');
|
|
14
|
+
const workflowPath = path.join(projectPath, '.github', 'workflows', 'amazingteam.yml');
|
|
15
|
+
|
|
16
|
+
console.log(`\namazingteam v${VERSION}\n`);
|
|
17
|
+
|
|
18
|
+
// Check project config
|
|
19
|
+
if (fs.existsSync(configPath)) {
|
|
20
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
21
|
+
const versionMatch = content.match(/version:\s*["']?(\d+\.\d+\.\d+)/);
|
|
22
|
+
if (versionMatch) {
|
|
23
|
+
console.log(`Project config version: ${versionMatch[1]}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Check workflow version
|
|
28
|
+
if (fs.existsSync(workflowPath)) {
|
|
29
|
+
const content = fs.readFileSync(workflowPath, 'utf-8');
|
|
30
|
+
const actionMatch = content.match(/amazingteam-action@v?(\d+\.\d+\.\d+)/);
|
|
31
|
+
if (actionMatch) {
|
|
32
|
+
console.log(`Workflow action version: ${actionMatch[1]}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Check if initialized
|
|
37
|
+
if (!fs.existsSync(configPath)) {
|
|
38
|
+
console.log('\n⚠️ AmazingTeam not initialized in this directory.');
|
|
39
|
+
console.log(' Run "amazingteam init" to get started.\n');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function help() {
|
|
44
|
+
return `
|
|
45
|
+
amazingteam version - Show current foundation version
|
|
46
|
+
|
|
47
|
+
Usage:
|
|
48
|
+
amazingteam version
|
|
49
|
+
ai-team --version
|
|
50
|
+
ai-team -v
|
|
51
|
+
|
|
52
|
+
Displays:
|
|
53
|
+
- CLI version
|
|
54
|
+
- Project config version (if initialized)
|
|
55
|
+
- Workflow action version (if configured)
|
|
56
|
+
`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports = { run, help };
|