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.
Files changed (164) hide show
  1. package/.ai-team/agents/architect.md +144 -0
  2. package/.ai-team/agents/ci-analyst.md +188 -0
  3. package/.ai-team/agents/developer.md +176 -0
  4. package/.ai-team/agents/planner.md +355 -0
  5. package/.ai-team/agents/qa.md +189 -0
  6. package/.ai-team/agents/reviewer.md +211 -0
  7. package/.ai-team/agents/triage.md +146 -0
  8. package/.ai-team/commands/ci-analyze.md +116 -0
  9. package/.ai-team/commands/design.md +100 -0
  10. package/.ai-team/commands/implement.md +108 -0
  11. package/.ai-team/commands/release-check.md +142 -0
  12. package/.ai-team/commands/review.md +142 -0
  13. package/.ai-team/commands/test.md +115 -0
  14. package/.ai-team/commands/triage.md +138 -0
  15. package/.ai-team/memory/architect/architecture_notes.md +67 -0
  16. package/.ai-team/memory/architect/design_rationale.md +113 -0
  17. package/.ai-team/memory/architect/module_map.md +84 -0
  18. package/.ai-team/memory/ci-analyst/failure_patterns.md +102 -0
  19. package/.ai-team/memory/ci-analyst/runbook_references.md +87 -0
  20. package/.ai-team/memory/developer/bug_investigation.md +102 -0
  21. package/.ai-team/memory/developer/build_issues.md +115 -0
  22. package/.ai-team/memory/developer/implementation_notes.md +83 -0
  23. package/.ai-team/memory/failures/failure_library.md +103 -0
  24. package/.ai-team/memory/planner/decomposition_notes.md +82 -0
  25. package/.ai-team/memory/planner/flow_rules.md +86 -0
  26. package/.ai-team/memory/planner/github_issue_patterns.md +229 -0
  27. package/.ai-team/memory/qa/regression_cases.md +101 -0
  28. package/.ai-team/memory/qa/test_strategy.md +138 -0
  29. package/.ai-team/memory/qa/validation_notes.md +110 -0
  30. package/.ai-team/memory/reviewer/quality_rules.md +105 -0
  31. package/.ai-team/memory/reviewer/recurring_risks.md +109 -0
  32. package/.ai-team/memory/reviewer/review_notes.md +124 -0
  33. package/.ai-team/memory/triage/classification_heuristics.md +82 -0
  34. package/.ai-team/memory/triage/debug_notes.md +87 -0
  35. package/.ai-team/opencode.template.jsonc +216 -0
  36. package/.ai-team/skills/bugfix-playbook/skill.md +174 -0
  37. package/.ai-team/skills/ci-failure-analysis/skill.md +176 -0
  38. package/.ai-team/skills/issue-triage/skill.md +163 -0
  39. package/.ai-team/skills/regression-checklist/skill.md +176 -0
  40. package/.ai-team/skills/release-readiness-check/skill.md +216 -0
  41. package/.ai-team/skills/repo-architecture-reader/skill.md +139 -0
  42. package/.ai-team/skills/safe-refactor-checklist/skill.md +215 -0
  43. package/.ai-team/skills/task-breakdown-and-dispatch/skill.md +151 -0
  44. package/.ai-team/skills/test-first-feature-dev/skill.md +205 -0
  45. package/.ai-team/workflows/ci.yml +81 -0
  46. package/.ai-team/workflows/nightly-ai-maintenance.yml +129 -0
  47. package/.ai-team/workflows/opencode.yml +33 -0
  48. package/.ai-team/workflows/pr-check.yml +41 -0
  49. package/.foundation/foundation.lock +38 -0
  50. package/.foundation/local-overrides.md +97 -0
  51. package/.foundation/upgrade-history.md +38 -0
  52. package/.opencode/agents/architect.md +38 -0
  53. package/.opencode/agents/ci-analyst.md +38 -0
  54. package/.opencode/agents/developer.md +43 -0
  55. package/.opencode/agents/planner.md +47 -0
  56. package/.opencode/agents/qa.md +34 -0
  57. package/.opencode/agents/reviewer.md +38 -0
  58. package/.opencode/agents/triage.md +37 -0
  59. package/.opencode/commands/auto.md +264 -0
  60. package/.opencode/commands/breakdown-issue.md +94 -0
  61. package/.opencode/commands/ci-analyze.md +15 -0
  62. package/.opencode/commands/close-parent-task.md +122 -0
  63. package/.opencode/commands/design.md +15 -0
  64. package/.opencode/commands/dispatch-next.md +102 -0
  65. package/.opencode/commands/implement.md +16 -0
  66. package/.opencode/commands/release-check.md +16 -0
  67. package/.opencode/commands/resume.md +88 -0
  68. package/.opencode/commands/review.md +15 -0
  69. package/.opencode/commands/show-blockers.md +97 -0
  70. package/.opencode/commands/summarize-parent.md +121 -0
  71. package/.opencode/commands/test.md +15 -0
  72. package/.opencode/commands/triage.md +109 -0
  73. package/.opencode/skills/bugfix-playbook/SKILL.md +81 -0
  74. package/.opencode/skills/ci-failure-analysis/SKILL.md +94 -0
  75. package/.opencode/skills/issue-triage/SKILL.md +80 -0
  76. package/.opencode/skills/regression-checklist/SKILL.md +81 -0
  77. package/.opencode/skills/release-readiness-check/SKILL.md +81 -0
  78. package/.opencode/skills/repo-architecture-reader/SKILL.md +65 -0
  79. package/.opencode/skills/safe-refactor-checklist/SKILL.md +76 -0
  80. package/.opencode/skills/task-breakdown-and-dispatch/SKILL.md +255 -0
  81. package/.opencode/skills/test-first-feature-dev/SKILL.md +78 -0
  82. package/AGENTS.md +879 -0
  83. package/CHANGELOG.md +261 -0
  84. package/LICENSE +21 -0
  85. package/README.md +1215 -0
  86. package/VERSION +1 -0
  87. package/action/__tests__/downloader.test.js +251 -0
  88. package/action/__tests__/merger.test.js +156 -0
  89. package/action/__tests__/path-resolver.test.js +199 -0
  90. package/action/__tests__/validator.test.js +310 -0
  91. package/action/action.yml +61 -0
  92. package/action/index.js +223 -0
  93. package/action/lib/downloader.js +344 -0
  94. package/action/lib/merger.js +170 -0
  95. package/action/lib/path-resolver.js +176 -0
  96. package/action/lib/setup.js +286 -0
  97. package/action/lib/validator.js +324 -0
  98. package/cli/__tests__/cli.test.js +270 -0
  99. package/cli/amazingteam.cjs +225 -0
  100. package/cli/commands/check-update.cjs +159 -0
  101. package/cli/commands/init.cjs +412 -0
  102. package/cli/commands/local.cjs +264 -0
  103. package/cli/commands/migrate.cjs +316 -0
  104. package/cli/commands/status.cjs +241 -0
  105. package/cli/commands/upgrade.cjs +213 -0
  106. package/cli/commands/validate.cjs +259 -0
  107. package/cli/commands/version.cjs +59 -0
  108. package/cli/sync.cjs +237 -0
  109. package/dist/index.js +35 -0
  110. package/docs/architecture/overview.md +138 -0
  111. package/docs/blocker_resolution_design.md +372 -0
  112. package/docs/bootstrap-model.md +356 -0
  113. package/docs/config-reference.md +458 -0
  114. package/docs/how-to-use.md +178 -0
  115. package/docs/migration-to-v3.md +355 -0
  116. package/docs/overlay-guide.md +156 -0
  117. package/docs/patterns/README.md +67 -0
  118. package/docs/quick-start-v3.md +330 -0
  119. package/docs/releases/README.md +64 -0
  120. package/docs/runbooks/ci/README.md +62 -0
  121. package/docs/runbooks/ci/build-debug.md +120 -0
  122. package/docs/runbooks/ci/flaky-tests.md +127 -0
  123. package/docs/runbooks/getting-started.md +81 -0
  124. package/docs/upgrade-policy.md +188 -0
  125. package/docs/versioning.md +199 -0
  126. package/overlays/README.md +30 -0
  127. package/overlays/ai-agent-product/.ai-team/skills/llm-integration/skill.md +99 -0
  128. package/overlays/ai-agent-product/docs/ai-agent-architecture.md +68 -0
  129. package/overlays/ai-agent-product/overlay.yaml +26 -0
  130. package/overlays/cpp-qt-desktop/.ai-team/skills/qt-signals-slots/skill.md +60 -0
  131. package/overlays/cpp-qt-desktop/docs/qt-conventions.md +64 -0
  132. package/overlays/cpp-qt-desktop/overlay.yaml +22 -0
  133. package/overlays/python-backend/.ai-team/skills/python-testing/skill.md +90 -0
  134. package/overlays/python-backend/docs/python-style.md +78 -0
  135. package/overlays/python-backend/overlay.yaml +22 -0
  136. package/overlays/web-fullstack/.ai-team/skills/frontend-testing/skill.md +70 -0
  137. package/overlays/web-fullstack/docs/frontend-conventions.md +68 -0
  138. package/overlays/web-fullstack/overlay.yaml +26 -0
  139. package/package.json +84 -0
  140. package/presets/default.yaml +161 -0
  141. package/presets/go.yaml +43 -0
  142. package/presets/python.yaml +43 -0
  143. package/presets/typescript.yaml +40 -0
  144. package/schemas/config.schema.json +239 -0
  145. package/scripts/diff_foundation_vs_project.sh +134 -0
  146. package/scripts/generate_docs.sh +200 -0
  147. package/scripts/init_project.sh +455 -0
  148. package/scripts/plan_upgrade.sh +268 -0
  149. package/scripts/upgrade_foundation.sh +365 -0
  150. package/scripts/validate-foundation.cjs +278 -0
  151. package/scripts/validate_foundation.sh +192 -0
  152. package/scripts/validate_project_setup.sh +171 -0
  153. package/tasks/README.md +94 -0
  154. package/tasks/_template/analysis.md +76 -0
  155. package/tasks/_template/design.md +121 -0
  156. package/tasks/_template/implementation.md +121 -0
  157. package/tasks/_template/release.md +119 -0
  158. package/tasks/_template/review.md +131 -0
  159. package/tasks/_template/subtasks/task.yaml +24 -0
  160. package/tasks/_template/task.yaml +75 -0
  161. package/tasks/_template/validation.md +128 -0
  162. package/templates/amazingteam.yml +81 -0
  163. package/templates/gitignore +14 -0
  164. package/templates/opencode.jsonc +216 -0
@@ -0,0 +1,310 @@
1
+ /**
2
+ * Validator Module Tests
3
+ */
4
+
5
+ const {
6
+ validateAgainstSchema,
7
+ validateConfig,
8
+ validateRequiredFiles,
9
+ validateProjectStructure
10
+ } = require('../lib/validator');
11
+
12
+ function testValidateAgainstSchema_TypeValidation() {
13
+ console.log('Testing validateAgainstSchema type validation...');
14
+
15
+ const schema = {
16
+ type: 'object',
17
+ properties: {
18
+ name: { type: 'string' },
19
+ count: { type: 'integer' },
20
+ active: { type: 'boolean' }
21
+ }
22
+ };
23
+
24
+ const validValue = {
25
+ name: 'test',
26
+ count: 42,
27
+ active: true
28
+ };
29
+
30
+ const result = validateAgainstSchema(validValue, schema);
31
+ console.assert(result.valid === true, 'Valid object should pass');
32
+ console.assert(result.errors.length === 0, 'Should have no errors');
33
+
34
+ const invalidValue = {
35
+ name: 123,
36
+ count: 'not a number',
37
+ active: 'yes'
38
+ };
39
+
40
+ const invalidResult = validateAgainstSchema(invalidValue, schema);
41
+ console.assert(invalidResult.valid === false, 'Invalid object should fail');
42
+ console.assert(invalidResult.errors.length > 0, 'Should have errors');
43
+
44
+ console.log(' ✓ type validation tests passed');
45
+ }
46
+
47
+ function testValidateAgainstSchema_EnumValidation() {
48
+ console.log('Testing validateAgainstSchema enum validation...');
49
+
50
+ const schema = {
51
+ type: 'object',
52
+ properties: {
53
+ role: { enum: ['admin', 'user', 'guest'] },
54
+ status: { enum: ['active', 'inactive'] }
55
+ }
56
+ };
57
+
58
+ const valid = { role: 'admin', status: 'active' };
59
+ const validResult = validateAgainstSchema(valid, schema);
60
+ console.assert(validResult.valid === true, 'Valid enum values should pass');
61
+
62
+ const invalid = { role: 'superuser', status: 'active' };
63
+ const invalidResult = validateAgainstSchema(invalid, schema);
64
+ console.assert(invalidResult.valid === false, 'Invalid enum should fail');
65
+ console.assert(invalidResult.errors[0].includes('must be one of'), 'Error should mention enum values');
66
+
67
+ console.log(' ✓ enum validation tests passed');
68
+ }
69
+
70
+ function testValidateAgainstSchema_StringValidation() {
71
+ console.log('Testing validateAgainstSchema string validation...');
72
+
73
+ const schema = {
74
+ type: 'object',
75
+ properties: {
76
+ name: { type: 'string', minLength: 3, maxLength: 10 },
77
+ email: { type: 'string', pattern: '^[a-z]+@[a-z]+\\.[a-z]+$' }
78
+ }
79
+ };
80
+
81
+ const validName = { name: 'test' };
82
+ const validNameResult = validateAgainstSchema(validName, schema);
83
+ console.assert(validNameResult.valid === true, 'Valid string length should pass');
84
+
85
+ const shortName = { name: 'ab' };
86
+ const shortResult = validateAgainstSchema(shortName, schema);
87
+ console.assert(shortResult.valid === false, 'Too short string should fail');
88
+ console.assert(shortResult.errors[0].includes('minLength'), 'Error should mention minLength');
89
+
90
+ const longName = { name: 'verylongname' };
91
+ const longResult = validateAgainstSchema(longName, schema);
92
+ console.assert(longResult.valid === false, 'Too long string should fail');
93
+
94
+ const validEmail = { email: 'test@example.com' };
95
+ const validEmailResult = validateAgainstSchema(validEmail, schema);
96
+ console.assert(validEmailResult.valid === true, 'Valid email pattern should pass');
97
+
98
+ const invalidEmail = { email: 'invalid-email' };
99
+ const invalidEmailResult = validateAgainstSchema(invalidEmail, schema);
100
+ console.assert(invalidEmailResult.valid === false, 'Invalid email pattern should fail');
101
+
102
+ console.log(' ✓ string validation tests passed');
103
+ }
104
+
105
+ function testValidateAgainstSchema_NumberValidation() {
106
+ console.log('Testing validateAgainstSchema number validation...');
107
+
108
+ const schema = {
109
+ type: 'object',
110
+ properties: {
111
+ age: { type: 'integer', minimum: 0, maximum: 150 },
112
+ score: { type: 'number', minimum: 0, maximum: 100 }
113
+ }
114
+ };
115
+
116
+ const valid = { age: 25, score: 85.5 };
117
+ const validResult = validateAgainstSchema(valid, schema);
118
+ console.assert(validResult.valid === true, 'Valid numbers should pass');
119
+
120
+ const negativeAge = { age: -5 };
121
+ const negativeResult = validateAgainstSchema(negativeAge, schema);
122
+ console.assert(negativeResult.valid === false, 'Negative age should fail');
123
+ console.assert(negativeResult.errors[0].includes('minimum'), 'Error should mention minimum');
124
+
125
+ const overMax = { score: 150 };
126
+ const overMaxResult = validateAgainstSchema(overMax, schema);
127
+ console.assert(overMaxResult.valid === false, 'Over maximum should fail');
128
+
129
+ const nonInteger = { age: 25.5 };
130
+ const nonIntResult = validateAgainstSchema(nonInteger, schema);
131
+ console.assert(nonIntResult.valid === false, 'Non-integer age should fail');
132
+
133
+ console.log(' ✓ number validation tests passed');
134
+ }
135
+
136
+ function testValidateAgainstSchema_ArrayValidation() {
137
+ console.log('Testing validateAgainstSchema array validation...');
138
+
139
+ const schema = {
140
+ type: 'object',
141
+ properties: {
142
+ tags: {
143
+ type: 'array',
144
+ items: { type: 'string' },
145
+ minItems: 1,
146
+ maxItems: 5
147
+ }
148
+ }
149
+ };
150
+
151
+ const valid = { tags: ['a', 'b', 'c'] };
152
+ const validResult = validateAgainstSchema(valid, schema);
153
+ console.assert(validResult.valid === true, 'Valid array should pass');
154
+
155
+ const empty = { tags: [] };
156
+ const emptyResult = validateAgainstSchema(empty, schema);
157
+ console.assert(emptyResult.valid === false, 'Empty array should fail (minItems)');
158
+
159
+ const tooMany = { tags: ['1', '2', '3', '4', '5', '6'] };
160
+ const tooManyResult = validateAgainstSchema(tooMany, schema);
161
+ console.assert(tooManyResult.valid === false, 'Array with too many items should fail');
162
+
163
+ const invalidItems = { tags: ['a', 123, 'b'] };
164
+ const invalidItemsResult = validateAgainstSchema(invalidItems, schema);
165
+ console.assert(invalidItemsResult.valid === false, 'Array with invalid items should fail');
166
+
167
+ console.log(' ✓ array validation tests passed');
168
+ }
169
+
170
+ function testValidateAgainstSchema_RequiredProperties() {
171
+ console.log('Testing validateAgainstSchema required properties...');
172
+
173
+ const schema = {
174
+ type: 'object',
175
+ required: ['name', 'version'],
176
+ properties: {
177
+ name: { type: 'string' },
178
+ version: { type: 'string' },
179
+ optional: { type: 'string' }
180
+ }
181
+ };
182
+
183
+ const valid = { name: 'test', version: '1.0' };
184
+ const validResult = validateAgainstSchema(valid, schema);
185
+ console.assert(validResult.valid === true, 'Object with required properties should pass');
186
+
187
+ const missingVersion = { name: 'test' };
188
+ const missingResult = validateAgainstSchema(missingVersion, schema);
189
+ console.assert(missingResult.valid === false, 'Missing required property should fail');
190
+ console.assert(missingResult.errors[0].includes('required'), 'Error should mention required');
191
+
192
+ console.log(' ✓ required properties tests passed');
193
+ }
194
+
195
+ function testValidateAgainstSchema_NestedObjects() {
196
+ console.log('Testing validateAgainstSchema nested objects...');
197
+
198
+ const schema = {
199
+ type: 'object',
200
+ properties: {
201
+ project: {
202
+ type: 'object',
203
+ properties: {
204
+ name: { type: 'string' },
205
+ language: { type: 'string' }
206
+ },
207
+ required: ['name']
208
+ }
209
+ }
210
+ };
211
+
212
+ const valid = { project: { name: 'my-project', language: 'typescript' } };
213
+ const validResult = validateAgainstSchema(valid, schema);
214
+ console.assert(validResult.valid === true, 'Valid nested object should pass');
215
+
216
+ const missingNested = { project: { language: 'typescript' } };
217
+ const missingResult = validateAgainstSchema(missingNested, schema);
218
+ console.assert(missingResult.valid === false, 'Missing nested required property should fail');
219
+
220
+ console.log(' ✓ nested objects tests passed');
221
+ }
222
+
223
+ function testValidateConfig() {
224
+ console.log('Testing validateConfig...');
225
+
226
+ const schema = {
227
+ type: 'object',
228
+ required: ['version', 'project'],
229
+ properties: {
230
+ version: { type: 'string' },
231
+ project: {
232
+ type: 'object',
233
+ required: ['name'],
234
+ properties: {
235
+ name: { type: 'string' },
236
+ language: { type: 'string' }
237
+ }
238
+ }
239
+ }
240
+ };
241
+
242
+ const validConfig = {
243
+ version: '1.0',
244
+ project: {
245
+ name: 'test-project',
246
+ language: 'typescript'
247
+ }
248
+ };
249
+
250
+ const result = validateConfig(validConfig, schema);
251
+ console.assert(result.valid === true, 'Valid config should pass');
252
+
253
+ const invalidConfig = {
254
+ version: '1.0'
255
+ };
256
+
257
+ const invalidResult = validateConfig(invalidConfig, schema);
258
+ console.assert(invalidResult.valid === false, 'Invalid config should fail');
259
+
260
+ console.log(' ✓ validateConfig tests passed');
261
+ }
262
+
263
+ function testValidateRequiredFiles() {
264
+ console.log('Testing validateRequiredFiles...');
265
+
266
+ const result = validateRequiredFiles(process.cwd(), ['package.json']);
267
+ console.assert(result.valid === true, 'package.json should exist');
268
+ console.assert(result.missing.length === 0, 'Should have no missing files');
269
+
270
+ const missingResult = validateRequiredFiles(process.cwd(), ['nonexistent-file.xyz']);
271
+ console.assert(missingResult.valid === false, 'Non-existent file should fail');
272
+ console.assert(missingResult.missing.length === 1, 'Should have one missing file');
273
+
274
+ console.log(' ✓ validateRequiredFiles tests passed');
275
+ }
276
+
277
+ function testValidateProjectStructure() {
278
+ console.log('Testing validateProjectStructure...');
279
+
280
+ const result = validateProjectStructure(process.cwd());
281
+
282
+ console.assert(Array.isArray(result.issues), 'Should return issues array');
283
+
284
+ if (result.valid) {
285
+ console.log(' Project structure is valid');
286
+ } else {
287
+ console.log(` Project has issues: ${result.issues.join(', ')}`);
288
+ }
289
+
290
+ console.log(' ✓ validateProjectStructure tests passed');
291
+ }
292
+
293
+ function runAll() {
294
+ console.log('\n=== Validator Module Tests ===\n');
295
+
296
+ testValidateAgainstSchema_TypeValidation();
297
+ testValidateAgainstSchema_EnumValidation();
298
+ testValidateAgainstSchema_StringValidation();
299
+ testValidateAgainstSchema_NumberValidation();
300
+ testValidateAgainstSchema_ArrayValidation();
301
+ testValidateAgainstSchema_RequiredProperties();
302
+ testValidateAgainstSchema_NestedObjects();
303
+ testValidateConfig();
304
+ testValidateRequiredFiles();
305
+ testValidateProjectStructure();
306
+
307
+ console.log('\n✅ All validator tests passed!\n');
308
+ }
309
+
310
+ runAll();
@@ -0,0 +1,61 @@
1
+ # AmazingTeam Foundation GitHub Action
2
+ # Downloads and sets up AmazingTeam Foundation for use in workflows
3
+
4
+ name: 'AmazingTeam Setup'
5
+ description: 'Set up AmazingTeam Foundation for AI-powered development'
6
+ author: 'AmazingTeam'
7
+ branding:
8
+ icon: 'cpu'
9
+ color: 'blue'
10
+
11
+ inputs:
12
+ version:
13
+ description: 'AmazingTeam Foundation version to use'
14
+ required: false
15
+ default: '3.0.0'
16
+
17
+ config:
18
+ description: 'Path to amazingteam.config.yaml'
19
+ required: false
20
+ default: 'amazingteam.config.yaml'
21
+
22
+ overlay:
23
+ description: 'Technology overlay to apply (e.g., python-backend, web-fullstack)'
24
+ required: false
25
+ default: ''
26
+
27
+ cache:
28
+ description: 'Enable caching of foundation downloads'
29
+ required: false
30
+ default: 'true'
31
+
32
+ cache-dir:
33
+ description: 'Directory to cache foundation downloads'
34
+ required: false
35
+ default: '~/.amazingteam-cache'
36
+
37
+ outputs:
38
+ foundation-path:
39
+ description: 'Path to the downloaded foundation'
40
+ value: ${{ steps.setup.outputs.foundation-path }}
41
+
42
+ setup-complete:
43
+ description: 'Whether setup completed successfully'
44
+ value: ${{ steps.setup.outputs.success }}
45
+
46
+ version:
47
+ description: 'Foundation version that was set up'
48
+ value: ${{ steps.setup.outputs.version }}
49
+
50
+ runs:
51
+ using: 'node20'
52
+ main: 'index.js'
53
+
54
+ # Future: Support composite action for more complex setup
55
+ # runs:
56
+ # using: 'composite'
57
+ # steps:
58
+ # - name: Setup AmazingTeam
59
+ # shell: bash
60
+ # run: |
61
+ # node ${{ github.action_path }}/index.js
@@ -0,0 +1,223 @@
1
+ /**
2
+ * AmazingTeam Foundation GitHub Action
3
+ * Main entry point for the action
4
+ */
5
+
6
+ const core = require('@actions/core');
7
+ const github = require('@actions/github');
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ const downloader = require('./lib/downloader');
12
+ const merger = require('./lib/merger');
13
+ const setup = require('./lib/setup');
14
+ const validator = require('./lib/validator');
15
+ const PathResolver = require('./lib/path-resolver');
16
+
17
+ /**
18
+ * Parse YAML config (minimal implementation)
19
+ * For production, use js-yaml package
20
+ */
21
+ function parseYamlConfig(content) {
22
+ const lines = content.split('\n');
23
+ const result = {};
24
+ let currentPath = [];
25
+ let currentIndent = 0;
26
+
27
+ function setValue(obj, keys, value) {
28
+ let current = obj;
29
+ for (let i = 0; i < keys.length - 1; i++) {
30
+ if (!current[keys[i]]) {
31
+ current[keys[i]] = {};
32
+ }
33
+ current = current[keys[i]];
34
+ }
35
+ current[keys[keys.length - 1]] = value;
36
+ }
37
+
38
+ for (const line of lines) {
39
+ if (line.trim().startsWith('#') || line.trim() === '') continue;
40
+
41
+ const indent = line.search(/\S/);
42
+ const trimmed = line.trim();
43
+ const colonIndex = trimmed.indexOf(':');
44
+
45
+ if (colonIndex > 0) {
46
+ const key = trimmed.substring(0, colonIndex).trim();
47
+ let value = trimmed.substring(colonIndex + 1).trim();
48
+
49
+ // Adjust path based on indent
50
+ const level = Math.floor(indent / 2);
51
+ currentPath = currentPath.slice(0, level);
52
+ currentPath.push(key);
53
+
54
+ if (value !== '') {
55
+ // Parse value
56
+ let parsedValue;
57
+ if (value.startsWith('[') && value.endsWith(']')) {
58
+ parsedValue = value.slice(1, -1).split(',').map(s => s.trim().replace(/^["']|["']$/g, ''));
59
+ } else if (value === 'true') {
60
+ parsedValue = true;
61
+ } else if (value === 'false') {
62
+ parsedValue = false;
63
+ } else if (value === 'null') {
64
+ parsedValue = null;
65
+ } else if (!isNaN(Number(value))) {
66
+ parsedValue = Number(value);
67
+ } else {
68
+ parsedValue = value.replace(/^["']|["']$/g, '');
69
+ }
70
+
71
+ setValue(result, currentPath, parsedValue);
72
+ currentPath.pop();
73
+ }
74
+ }
75
+ }
76
+
77
+ return result;
78
+ }
79
+
80
+ /**
81
+ * Load user configuration
82
+ */
83
+ async function loadUserConfig(configPath, projectDir) {
84
+ const fullPath = path.join(projectDir, configPath);
85
+
86
+ if (!fs.existsSync(fullPath)) {
87
+ core.warning(`Config file not found: ${configPath}, using defaults`);
88
+ return {};
89
+ }
90
+
91
+ const content = fs.readFileSync(fullPath, 'utf-8');
92
+ return parseYamlConfig(content);
93
+ }
94
+
95
+ /**
96
+ * Load preset configuration
97
+ */
98
+ async function loadPreset(presetName, foundationDir) {
99
+ if (!presetName) {
100
+ return null;
101
+ }
102
+
103
+ const presetPath = path.join(foundationDir, 'presets', `${presetName}.yaml`);
104
+
105
+ if (!fs.existsSync(presetPath)) {
106
+ core.warning(`Preset not found: ${presetName}`);
107
+ return null;
108
+ }
109
+
110
+ const content = fs.readFileSync(presetPath, 'utf-8');
111
+ return parseYamlConfig(content);
112
+ }
113
+
114
+ /**
115
+ * Load default configuration
116
+ */
117
+ async function loadDefaultConfig(foundationDir) {
118
+ const defaultPath = path.join(foundationDir, 'presets', 'default.yaml');
119
+
120
+ if (!fs.existsSync(defaultPath)) {
121
+ core.warning('Default preset not found, using minimal config');
122
+ return {
123
+ version: '1.0',
124
+ project: {
125
+ name: 'unknown',
126
+ language: 'typescript'
127
+ }
128
+ };
129
+ }
130
+
131
+ const content = fs.readFileSync(defaultPath, 'utf-8');
132
+ return parseYamlConfig(content);
133
+ }
134
+
135
+ /**
136
+ * Main action function
137
+ */
138
+ async function run() {
139
+ try {
140
+ // Get inputs
141
+ const version = core.getInput('version') || '3.0.0';
142
+ const configPath = core.getInput('config') || 'amazingteam.config.yaml';
143
+ const overlay = core.getInput('overlay') || '';
144
+ const useCache = core.getInput('cache') !== 'false';
145
+ const cacheDir = core.getInput('cache-dir') || path.join(process.env.HOME || '', '.amazingteam-cache');
146
+
147
+ const projectDir = process.env.GITHUB_WORKSPACE || process.cwd();
148
+
149
+ core.info(`Setting up AmazingTeam Foundation v${version}`);
150
+ core.info(`Project directory: ${projectDir}`);
151
+
152
+ // Step 1: Download foundation
153
+ core.info('Downloading foundation...');
154
+ const foundationDir = await downloader.downloadFoundation({
155
+ version,
156
+ cacheDir: useCache ? cacheDir : null
157
+ });
158
+ core.info(`Foundation downloaded to: ${foundationDir}`);
159
+
160
+ // Step 2: Load configurations
161
+ core.info('Loading configurations...');
162
+ const defaultConfig = await loadDefaultConfig(foundationDir);
163
+ const presetConfig = overlay ? await loadPreset(overlay, foundationDir) : null;
164
+ const userConfig = await loadUserConfig(configPath, projectDir);
165
+
166
+ // Step 3: Merge configurations
167
+ core.info('Merging configurations...');
168
+ const mergedConfig = merger.mergeWithPreset(presetConfig, defaultConfig, userConfig);
169
+
170
+ // Validate merged config
171
+ const validation = merger.validateMergedConfig(mergedConfig);
172
+ if (!validation.valid) {
173
+ core.warning(`Configuration validation warnings: ${validation.errors.join(', ')}`);
174
+ }
175
+
176
+ // Step 4: Setup runtime
177
+ core.info('Setting up runtime...');
178
+ const setupResult = setup.setup(foundationDir, projectDir, mergedConfig);
179
+
180
+ // Step 5: Verify setup
181
+ const verification = setup.verifySetup(projectDir);
182
+ if (!verification.valid) {
183
+ core.warning(`Setup verification issues: ${verification.issues.join(', ')}`);
184
+ }
185
+
186
+ // Set outputs
187
+ core.setOutput('foundation-path', foundationDir);
188
+ core.setOutput('setup-complete', 'true');
189
+ core.setOutput('version', version);
190
+
191
+ // Export environment variables for subsequent steps
192
+ core.exportVariable('AI_TEAM_FOUNDATION_PATH', foundationDir);
193
+ core.exportVariable('AI_TEAM_VERSION', version);
194
+
195
+ core.info('AmazingTeam Foundation setup complete!');
196
+
197
+ // Summary
198
+ core.summary.addRaw(`
199
+ ## AmazingTeam Foundation Setup Complete
200
+
201
+ | Property | Value |
202
+ |----------|-------|
203
+ | Version | ${version} |
204
+ | Foundation Path | ${foundationDir} |
205
+ | Config | ${configPath} |
206
+ | Overlay | ${overlay || 'none'} |
207
+
208
+ ### Created Directories
209
+ ${setupResult.createdDirectories.map(d => `- ${d}`).join('\n')}
210
+
211
+ ### Generated Files
212
+ - ${setupResult.opencodePath}
213
+ `).write();
214
+
215
+ } catch (error) {
216
+ core.setFailed(`AmazingTeam setup failed: ${error.message}`);
217
+ core.error(error.stack);
218
+ process.exit(1);
219
+ }
220
+ }
221
+
222
+ // Run the action
223
+ run();