aios-core 2.3.1 → 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.
|
@@ -267,6 +267,60 @@ github:
|
|
|
267
267
|
pr_creation: true
|
|
268
268
|
issue_management: true
|
|
269
269
|
|
|
270
|
+
# Pull Request Configuration
|
|
271
|
+
# Controls how @devops *create-pr generates PR titles and descriptions
|
|
272
|
+
pr:
|
|
273
|
+
# Title format options:
|
|
274
|
+
# - "conventional": Uses Conventional Commits format for semantic-release
|
|
275
|
+
# Example: "feat(auth): implement OAuth login [Story 6.17]"
|
|
276
|
+
# - "story-first": Story ID first (legacy/simple projects)
|
|
277
|
+
# Example: "[Story 6.17] Implement OAuth Login"
|
|
278
|
+
# - "branch-based": Converts branch name to title
|
|
279
|
+
# Example: "Feature User Auth"
|
|
280
|
+
title_format: conventional # Options: conventional | story-first | branch-based
|
|
281
|
+
|
|
282
|
+
# Include story ID in PR title when available
|
|
283
|
+
include_story_id: true
|
|
284
|
+
|
|
285
|
+
# Conventional commits mapping (only used when title_format: conventional)
|
|
286
|
+
# Maps branch prefixes to commit types
|
|
287
|
+
conventional_commits:
|
|
288
|
+
enabled: true
|
|
289
|
+
branch_type_map:
|
|
290
|
+
feature/: feat
|
|
291
|
+
feat/: feat
|
|
292
|
+
fix/: fix
|
|
293
|
+
bugfix/: fix
|
|
294
|
+
hotfix/: fix
|
|
295
|
+
docs/: docs
|
|
296
|
+
chore/: chore
|
|
297
|
+
refactor/: refactor
|
|
298
|
+
test/: test
|
|
299
|
+
perf/: perf
|
|
300
|
+
ci/: ci
|
|
301
|
+
style/: style
|
|
302
|
+
build/: build
|
|
303
|
+
default_type: feat
|
|
304
|
+
|
|
305
|
+
# Base branch for PRs (auto-detected if not set)
|
|
306
|
+
# base_branch: main
|
|
307
|
+
|
|
308
|
+
# Auto-assign reviewers based on story type
|
|
309
|
+
auto_assign_reviewers: false
|
|
310
|
+
|
|
311
|
+
# Draft PRs by default
|
|
312
|
+
draft_by_default: false
|
|
313
|
+
|
|
314
|
+
# Semantic Release Integration (Story 6.17)
|
|
315
|
+
# When enabled, PR titles follow Conventional Commits for automatic releases
|
|
316
|
+
semantic_release:
|
|
317
|
+
enabled: true # Set to false if project doesn't use semantic-release
|
|
318
|
+
# Release types triggered by commit prefixes:
|
|
319
|
+
# - feat: → Minor release (2.3.0 → 2.4.0)
|
|
320
|
+
# - fix: → Patch release (2.3.0 → 2.3.1)
|
|
321
|
+
# - feat!: or BREAKING CHANGE: → Major release (2.3.0 → 3.0.0)
|
|
322
|
+
# - docs:, chore:, test:, etc. → No release
|
|
323
|
+
|
|
270
324
|
# ============================================
|
|
271
325
|
# SECTION 9: CodeRabbit Integration (Story 6.3.3)
|
|
272
326
|
# MASTER TOGGLE: When enabled=false, ALL CodeRabbit behavior is disabled
|
|
@@ -262,22 +262,209 @@ function extractStoryInfo(storyPath) {
|
|
|
262
262
|
}
|
|
263
263
|
```
|
|
264
264
|
|
|
265
|
-
### Step 4: Generate PR Title
|
|
265
|
+
### Step 4: Generate PR Title (Configurable Format)
|
|
266
|
+
|
|
267
|
+
> **Configuration-Driven:** PR title format is controlled by `core-config.yaml` → `github.pr.title_format`
|
|
268
|
+
> This allows each project to choose the format that matches their workflow.
|
|
266
269
|
|
|
267
270
|
```javascript
|
|
271
|
+
const yaml = require('js-yaml');
|
|
272
|
+
const fs = require('fs');
|
|
273
|
+
const path = require('path');
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Load PR configuration from core-config.yaml
|
|
277
|
+
* @returns {Object} PR configuration with defaults
|
|
278
|
+
*/
|
|
279
|
+
function loadPRConfig() {
|
|
280
|
+
const configPath = path.join(process.cwd(), '.aios-core', 'core-config.yaml');
|
|
281
|
+
|
|
282
|
+
// Default configuration (for projects without core-config)
|
|
283
|
+
const defaults = {
|
|
284
|
+
title_format: 'story-first', // Safe default for most projects
|
|
285
|
+
include_story_id: true,
|
|
286
|
+
conventional_commits: {
|
|
287
|
+
enabled: false,
|
|
288
|
+
branch_type_map: {
|
|
289
|
+
'feature/': 'feat',
|
|
290
|
+
'feat/': 'feat',
|
|
291
|
+
'fix/': 'fix',
|
|
292
|
+
'bugfix/': 'fix',
|
|
293
|
+
'hotfix/': 'fix',
|
|
294
|
+
'docs/': 'docs',
|
|
295
|
+
'chore/': 'chore',
|
|
296
|
+
'refactor/': 'refactor',
|
|
297
|
+
'test/': 'test',
|
|
298
|
+
'perf/': 'perf',
|
|
299
|
+
'ci/': 'ci',
|
|
300
|
+
'style/': 'style',
|
|
301
|
+
'build/': 'build'
|
|
302
|
+
},
|
|
303
|
+
default_type: 'feat'
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
try {
|
|
308
|
+
if (fs.existsSync(configPath)) {
|
|
309
|
+
const config = yaml.load(fs.readFileSync(configPath, 'utf8'));
|
|
310
|
+
return { ...defaults, ...config?.github?.pr };
|
|
311
|
+
}
|
|
312
|
+
} catch (error) {
|
|
313
|
+
console.warn('Could not load core-config.yaml, using defaults');
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return defaults;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Generate PR title based on project configuration.
|
|
321
|
+
*
|
|
322
|
+
* Supported formats (configured in core-config.yaml → github.pr.title_format):
|
|
323
|
+
*
|
|
324
|
+
* 1. "conventional" - Conventional Commits format (for semantic-release)
|
|
325
|
+
* Example: "feat(auth): implement OAuth login [Story 6.17]"
|
|
326
|
+
*
|
|
327
|
+
* 2. "story-first" - Story ID first (legacy/simple projects)
|
|
328
|
+
* Example: "[Story 6.17] Implement OAuth Login"
|
|
329
|
+
*
|
|
330
|
+
* 3. "branch-based" - Branch name converted to title
|
|
331
|
+
* Example: "Feature User Auth"
|
|
332
|
+
*
|
|
333
|
+
* @param {string} branchName - Current git branch name
|
|
334
|
+
* @param {Object} storyInfo - Story information (id, title)
|
|
335
|
+
* @returns {string} Formatted PR title
|
|
336
|
+
*/
|
|
268
337
|
function generatePRTitle(branchName, storyInfo) {
|
|
338
|
+
const config = loadPRConfig();
|
|
339
|
+
const format = config.title_format || 'story-first';
|
|
340
|
+
|
|
341
|
+
switch (format) {
|
|
342
|
+
case 'conventional':
|
|
343
|
+
return generateConventionalTitle(branchName, storyInfo, config);
|
|
344
|
+
case 'story-first':
|
|
345
|
+
return generateStoryFirstTitle(branchName, storyInfo, config);
|
|
346
|
+
case 'branch-based':
|
|
347
|
+
return generateBranchBasedTitle(branchName, storyInfo, config);
|
|
348
|
+
default:
|
|
349
|
+
return generateStoryFirstTitle(branchName, storyInfo, config);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Format: {type}({scope}): {description} [Story {id}]
|
|
355
|
+
* Used for: Projects with semantic-release automation
|
|
356
|
+
*/
|
|
357
|
+
function generateConventionalTitle(branchName, storyInfo, config) {
|
|
358
|
+
const typeMap = config.conventional_commits?.branch_type_map || {};
|
|
359
|
+
const defaultType = config.conventional_commits?.default_type || 'feat';
|
|
360
|
+
|
|
361
|
+
// Detect commit type from branch prefix
|
|
362
|
+
let type = defaultType;
|
|
363
|
+
for (const [prefix, commitType] of Object.entries(typeMap)) {
|
|
364
|
+
if (branchName.startsWith(prefix)) {
|
|
365
|
+
type = commitType;
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Extract scope from branch name (e.g., feat/auth/login -> scope=auth)
|
|
371
|
+
const scopeMatch = branchName.match(/^[a-z-]+\/([a-z-]+)\//);
|
|
372
|
+
const scope = scopeMatch ? scopeMatch[1] : null;
|
|
373
|
+
const scopeStr = scope ? `(${scope})` : '';
|
|
374
|
+
|
|
375
|
+
// Generate description
|
|
376
|
+
if (storyInfo && storyInfo.id && storyInfo.title) {
|
|
377
|
+
let cleanTitle = storyInfo.title
|
|
378
|
+
.replace(/^Story\s*\d+\.\d+[:\s-]*/i, '')
|
|
379
|
+
.trim();
|
|
380
|
+
cleanTitle = cleanTitle.charAt(0).toLowerCase() + cleanTitle.slice(1);
|
|
381
|
+
|
|
382
|
+
const storyRef = config.include_story_id ? ` [Story ${storyInfo.id}]` : '';
|
|
383
|
+
return `${type}${scopeStr}: ${cleanTitle}${storyRef}`;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Fallback: convert branch name to description
|
|
387
|
+
const description = branchName
|
|
388
|
+
.replace(/^(feature|feat|fix|bugfix|hotfix|docs|chore|refactor|test|perf|ci|style|build)\//, '')
|
|
389
|
+
.replace(/^[a-z-]+\//, '')
|
|
390
|
+
.replace(/-/g, ' ')
|
|
391
|
+
.toLowerCase()
|
|
392
|
+
.trim();
|
|
393
|
+
|
|
394
|
+
return `${type}${scopeStr}: ${description}`;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Format: [Story {id}] {Title}
|
|
399
|
+
* Used for: Simple projects, legacy workflows, non-NPM projects
|
|
400
|
+
*/
|
|
401
|
+
function generateStoryFirstTitle(branchName, storyInfo, config) {
|
|
269
402
|
if (storyInfo && storyInfo.id && storyInfo.title) {
|
|
270
403
|
return `[Story ${storyInfo.id}] ${storyInfo.title}`;
|
|
271
404
|
}
|
|
272
405
|
|
|
273
406
|
// Fallback: convert branch name to title
|
|
274
407
|
return branchName
|
|
275
|
-
.replace(/^feature\//, '')
|
|
408
|
+
.replace(/^(feature|feat|fix|bugfix|hotfix|docs|chore|refactor|test|perf|ci|style|build)\//, '')
|
|
276
409
|
.replace(/-/g, ' ')
|
|
277
410
|
.replace(/\b\w/g, c => c.toUpperCase());
|
|
278
411
|
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Format: {Branch Name As Title}
|
|
415
|
+
* Used for: Minimal projects, quick iterations
|
|
416
|
+
*/
|
|
417
|
+
function generateBranchBasedTitle(branchName, storyInfo, config) {
|
|
418
|
+
const title = branchName
|
|
419
|
+
.replace(/^(feature|feat|fix|bugfix|hotfix|docs|chore|refactor|test|perf|ci|style|build)\//, '')
|
|
420
|
+
.replace(/-/g, ' ')
|
|
421
|
+
.replace(/\b\w/g, c => c.toUpperCase());
|
|
422
|
+
|
|
423
|
+
if (config.include_story_id && storyInfo?.id) {
|
|
424
|
+
return `${title} [Story ${storyInfo.id}]`;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return title;
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
## Configuration Reference
|
|
432
|
+
|
|
433
|
+
Add to your project's `core-config.yaml`:
|
|
434
|
+
|
|
435
|
+
```yaml
|
|
436
|
+
github:
|
|
437
|
+
pr:
|
|
438
|
+
# Options: conventional | story-first | branch-based
|
|
439
|
+
title_format: conventional # For semantic-release projects
|
|
440
|
+
# title_format: story-first # For simple projects (default)
|
|
441
|
+
|
|
442
|
+
include_story_id: true
|
|
443
|
+
|
|
444
|
+
conventional_commits:
|
|
445
|
+
enabled: true
|
|
446
|
+
branch_type_map:
|
|
447
|
+
feature/: feat
|
|
448
|
+
fix/: fix
|
|
449
|
+
docs/: docs
|
|
450
|
+
# Add custom mappings as needed
|
|
451
|
+
default_type: feat
|
|
452
|
+
|
|
453
|
+
semantic_release:
|
|
454
|
+
enabled: true # Set false if not using semantic-release
|
|
279
455
|
```
|
|
280
456
|
|
|
457
|
+
## Title Format Examples
|
|
458
|
+
|
|
459
|
+
| Format | Branch | Story | Generated Title |
|
|
460
|
+
|--------|--------|-------|-----------------|
|
|
461
|
+
| `conventional` | `feature/user-auth` | 6.17: User Auth | `feat: user auth [Story 6.17]` |
|
|
462
|
+
| `conventional` | `fix/cli/parsing` | 6.18: CLI Fix | `fix(cli): cLI fix [Story 6.18]` |
|
|
463
|
+
| `story-first` | `feature/user-auth` | 6.17: User Auth | `[Story 6.17] User Auth` |
|
|
464
|
+
| `story-first` | `fix/cli-bug` | - | `Cli Bug` |
|
|
465
|
+
| `branch-based` | `feature/user-auth` | 6.17 | `User Auth [Story 6.17]` |
|
|
466
|
+
| `branch-based` | `docs/readme` | - | `Readme` |
|
|
467
|
+
|
|
281
468
|
### Step 5: Generate PR Description
|
|
282
469
|
|
|
283
470
|
```javascript
|
|
@@ -415,10 +602,60 @@ Called by `@github-devops` via `*create-pr` command.
|
|
|
415
602
|
## Validation
|
|
416
603
|
|
|
417
604
|
- PR created in correct repository (detected URL)
|
|
418
|
-
- PR title
|
|
605
|
+
- PR title follows Conventional Commits format (required for semantic-release)
|
|
606
|
+
- PR title includes story ID if available (e.g., `[Story 6.17]`)
|
|
419
607
|
- PR description includes repository context
|
|
420
608
|
- Base branch is correct (usually main/master)
|
|
421
609
|
|
|
610
|
+
## Semantic-Release Integration (Optional)
|
|
611
|
+
|
|
612
|
+
> **Note:** This section only applies when `core-config.yaml` has:
|
|
613
|
+
> - `github.pr.title_format: conventional`
|
|
614
|
+
> - `github.semantic_release.enabled: true`
|
|
615
|
+
>
|
|
616
|
+
> Projects without semantic-release should use `title_format: story-first` (default).
|
|
617
|
+
|
|
618
|
+
**When enabled:** PRs merged via "Squash and merge" use the PR title as commit message, triggering semantic-release:
|
|
619
|
+
|
|
620
|
+
| Branch Pattern | Generated Title | Release |
|
|
621
|
+
|---------------|-----------------|---------|
|
|
622
|
+
| `feature/user-auth` | `feat: user auth` | ✅ Minor |
|
|
623
|
+
| `feat/auth/sso-login` | `feat(auth): sso login` | ✅ Minor |
|
|
624
|
+
| `fix/cli-parsing` | `fix: cli parsing` | ✅ Patch |
|
|
625
|
+
| `docs/readme-update` | `docs: readme update` | ❌ None |
|
|
626
|
+
| `chore/deps-update` | `chore: deps update` | ❌ None |
|
|
627
|
+
|
|
628
|
+
For breaking changes, manually edit the PR title to include `!`:
|
|
629
|
+
- `feat!: redesign authentication API [Story 7.1]`
|
|
630
|
+
|
|
631
|
+
## Configuration for Different Project Types
|
|
632
|
+
|
|
633
|
+
### NPM Package with Semantic-Release (aios-core)
|
|
634
|
+
```yaml
|
|
635
|
+
github:
|
|
636
|
+
pr:
|
|
637
|
+
title_format: conventional
|
|
638
|
+
semantic_release:
|
|
639
|
+
enabled: true
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### Simple Web App (no releases)
|
|
643
|
+
```yaml
|
|
644
|
+
github:
|
|
645
|
+
pr:
|
|
646
|
+
title_format: story-first # [Story 6.17] Title
|
|
647
|
+
semantic_release:
|
|
648
|
+
enabled: false
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
### Quick Prototypes
|
|
652
|
+
```yaml
|
|
653
|
+
github:
|
|
654
|
+
pr:
|
|
655
|
+
title_format: branch-based # Just branch name as title
|
|
656
|
+
include_story_id: false
|
|
657
|
+
```
|
|
658
|
+
|
|
422
659
|
## Notes
|
|
423
660
|
|
|
424
661
|
- Works with ANY repository
|
|
@@ -88,6 +88,47 @@ deployment:
|
|
|
88
88
|
staging: ["staging", "needs-review"]
|
|
89
89
|
production: ["production", "promotion"]
|
|
90
90
|
|
|
91
|
+
# =============================================================================
|
|
92
|
+
# GITHUB INTEGRATION
|
|
93
|
+
# Pull Request and semantic-release configuration
|
|
94
|
+
# =============================================================================
|
|
95
|
+
github:
|
|
96
|
+
enabled: true
|
|
97
|
+
cli_required: false
|
|
98
|
+
|
|
99
|
+
# Pull Request Configuration
|
|
100
|
+
# Controls how @devops *create-pr generates PR titles
|
|
101
|
+
pr:
|
|
102
|
+
# Title format options:
|
|
103
|
+
# - "conventional": For semantic-release (feat: description [Story X.Y])
|
|
104
|
+
# - "story-first": Simple format ([Story X.Y] Description) - DEFAULT
|
|
105
|
+
# - "branch-based": Just branch name as title
|
|
106
|
+
title_format: {{PR_TITLE_FORMAT}}
|
|
107
|
+
|
|
108
|
+
include_story_id: true
|
|
109
|
+
|
|
110
|
+
# Only used when title_format: conventional
|
|
111
|
+
conventional_commits:
|
|
112
|
+
enabled: {{CONVENTIONAL_COMMITS_ENABLED}}
|
|
113
|
+
branch_type_map:
|
|
114
|
+
feature/: feat
|
|
115
|
+
feat/: feat
|
|
116
|
+
fix/: fix
|
|
117
|
+
bugfix/: fix
|
|
118
|
+
hotfix/: fix
|
|
119
|
+
docs/: docs
|
|
120
|
+
chore/: chore
|
|
121
|
+
refactor/: refactor
|
|
122
|
+
test/: test
|
|
123
|
+
default_type: feat
|
|
124
|
+
|
|
125
|
+
auto_assign_reviewers: false
|
|
126
|
+
draft_by_default: false
|
|
127
|
+
|
|
128
|
+
# Semantic Release (only for NPM packages)
|
|
129
|
+
semantic_release:
|
|
130
|
+
enabled: {{SEMANTIC_RELEASE_ENABLED}}
|
|
131
|
+
|
|
91
132
|
# =============================================================================
|
|
92
133
|
# AGENT CONFIGURATION
|
|
93
134
|
# Agent-specific settings
|