aiwg 2026.2.8 → 2026.2.9
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/agentic/code/frameworks/research-complete/manifest.json +24 -0
- package/docs/_manifest.json +97 -1
- package/docs/releases/_manifest.json +12 -0
- package/docs/releases/v2026.2.9-announcement.md +60 -0
- package/package.json +4 -3
- package/tools/agents/deploy-agents.mjs +5 -4
- package/tools/agents/providers/base.mjs +237 -26
- package/tools/agents/providers/claude.mjs +18 -113
- package/tools/agents/providers/codex.mjs +20 -49
- package/tools/agents/providers/copilot.mjs +17 -108
- package/tools/agents/providers/cursor.mjs +17 -113
- package/tools/agents/providers/factory.mjs +17 -111
- package/tools/agents/providers/opencode.mjs +17 -110
- package/tools/agents/providers/warp.mjs +18 -113
- package/tools/agents/providers/windsurf.mjs +38 -117
- package/tools/commands/deploy-prompts-codex.mjs +12 -14
- package/tools/skills/deploy-skills-codex.mjs +8 -14
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "research-complete",
|
|
3
|
+
"type": "framework",
|
|
4
|
+
"name": "Research Complete",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"description": "Research workflow framework for discovery, acquisition, synthesis, citation, quality, and archival operations.",
|
|
7
|
+
"modeAliases": [
|
|
8
|
+
"research"
|
|
9
|
+
],
|
|
10
|
+
"entry": {
|
|
11
|
+
"agents": "agents",
|
|
12
|
+
"commands": "commands",
|
|
13
|
+
"skills": "skills",
|
|
14
|
+
"templates": "templates"
|
|
15
|
+
},
|
|
16
|
+
"workspace": {
|
|
17
|
+
"subdirs": [
|
|
18
|
+
"repo",
|
|
19
|
+
"corpus",
|
|
20
|
+
"working",
|
|
21
|
+
"archive"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
}
|
package/docs/_manifest.json
CHANGED
|
@@ -57,6 +57,18 @@
|
|
|
57
57
|
"references/REF-002-llm-failure-modes-agentic",
|
|
58
58
|
"references/REF-003-mcp-specification-2025",
|
|
59
59
|
"releases",
|
|
60
|
+
"releases/v2026.2.9-announcement",
|
|
61
|
+
"releases/v2026.2.8-announcement",
|
|
62
|
+
"releases/v2026.2.7-announcement",
|
|
63
|
+
"releases/v2026.2.5-announcement",
|
|
64
|
+
"releases/v2026.2.4-announcement",
|
|
65
|
+
"releases/v2026.2.3-announcement",
|
|
66
|
+
"releases/v2026.2.0-announcement",
|
|
67
|
+
"releases/v2026.1.7-announcement",
|
|
68
|
+
"releases/v2026.1.6-announcement",
|
|
69
|
+
"releases/v2026.1.5-announcement",
|
|
70
|
+
"releases/v2026.1.4-announcement",
|
|
71
|
+
"releases/v2026.1.3-announcement",
|
|
60
72
|
"releases/v2024.12.5-announcement",
|
|
61
73
|
"releases/v2024.12.4-announcement",
|
|
62
74
|
"releases/v2024.12.3-announcement",
|
|
@@ -441,10 +453,94 @@
|
|
|
441
453
|
"summary": "Release notes",
|
|
442
454
|
"collapsed": true
|
|
443
455
|
},
|
|
456
|
+
{
|
|
457
|
+
"id": "releases/v2026.2.9-announcement",
|
|
458
|
+
"title": "v2026.2.9",
|
|
459
|
+
"summary": "Latest release",
|
|
460
|
+
"file": "releases/v2026.2.9-announcement.md",
|
|
461
|
+
"parent": "releases"
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
"id": "releases/v2026.2.8-announcement",
|
|
465
|
+
"title": "v2026.2.8",
|
|
466
|
+
"summary": "Previous release",
|
|
467
|
+
"file": "releases/v2026.2.8-announcement.md",
|
|
468
|
+
"parent": "releases"
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
"id": "releases/v2026.2.7-announcement",
|
|
472
|
+
"title": "v2026.2.7",
|
|
473
|
+
"summary": "Previous release",
|
|
474
|
+
"file": "releases/v2026.2.7-announcement.md",
|
|
475
|
+
"parent": "releases"
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
"id": "releases/v2026.2.5-announcement",
|
|
479
|
+
"title": "v2026.2.5",
|
|
480
|
+
"summary": "Previous release",
|
|
481
|
+
"file": "releases/v2026.2.5-announcement.md",
|
|
482
|
+
"parent": "releases"
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
"id": "releases/v2026.2.4-announcement",
|
|
486
|
+
"title": "v2026.2.4",
|
|
487
|
+
"summary": "Previous release",
|
|
488
|
+
"file": "releases/v2026.2.4-announcement.md",
|
|
489
|
+
"parent": "releases"
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
"id": "releases/v2026.2.3-announcement",
|
|
493
|
+
"title": "v2026.2.3",
|
|
494
|
+
"summary": "Previous release",
|
|
495
|
+
"file": "releases/v2026.2.3-announcement.md",
|
|
496
|
+
"parent": "releases"
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
"id": "releases/v2026.2.0-announcement",
|
|
500
|
+
"title": "v2026.2.0",
|
|
501
|
+
"summary": "Previous release",
|
|
502
|
+
"file": "releases/v2026.2.0-announcement.md",
|
|
503
|
+
"parent": "releases"
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
"id": "releases/v2026.1.7-announcement",
|
|
507
|
+
"title": "v2026.1.7",
|
|
508
|
+
"summary": "Previous release",
|
|
509
|
+
"file": "releases/v2026.1.7-announcement.md",
|
|
510
|
+
"parent": "releases"
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
"id": "releases/v2026.1.6-announcement",
|
|
514
|
+
"title": "v2026.1.6",
|
|
515
|
+
"summary": "Previous release",
|
|
516
|
+
"file": "releases/v2026.1.6-announcement.md",
|
|
517
|
+
"parent": "releases"
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
"id": "releases/v2026.1.5-announcement",
|
|
521
|
+
"title": "v2026.1.5",
|
|
522
|
+
"summary": "Previous release",
|
|
523
|
+
"file": "releases/v2026.1.5-announcement.md",
|
|
524
|
+
"parent": "releases"
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
"id": "releases/v2026.1.4-announcement",
|
|
528
|
+
"title": "v2026.1.4",
|
|
529
|
+
"summary": "Previous release",
|
|
530
|
+
"file": "releases/v2026.1.4-announcement.md",
|
|
531
|
+
"parent": "releases"
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
"id": "releases/v2026.1.3-announcement",
|
|
535
|
+
"title": "v2026.1.3",
|
|
536
|
+
"summary": "Previous release",
|
|
537
|
+
"file": "releases/v2026.1.3-announcement.md",
|
|
538
|
+
"parent": "releases"
|
|
539
|
+
},
|
|
444
540
|
{
|
|
445
541
|
"id": "releases/v2024.12.5-announcement",
|
|
446
542
|
"title": "v2024.12.5",
|
|
447
|
-
"summary": "
|
|
543
|
+
"summary": "Previous release",
|
|
448
544
|
"file": "releases/v2024.12.5-announcement.md",
|
|
449
545
|
"parent": "releases"
|
|
450
546
|
},
|
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
"summary": "Release notes",
|
|
4
4
|
"collapsed": true,
|
|
5
5
|
"order": [
|
|
6
|
+
"v2026.2.9-announcement",
|
|
7
|
+
"v2026.2.8-announcement",
|
|
8
|
+
"v2026.2.7-announcement",
|
|
9
|
+
"v2026.2.5-announcement",
|
|
10
|
+
"v2026.2.4-announcement",
|
|
11
|
+
"v2026.2.3-announcement",
|
|
12
|
+
"v2026.2.0-announcement",
|
|
13
|
+
"v2026.1.7-announcement",
|
|
14
|
+
"v2026.1.6-announcement",
|
|
15
|
+
"v2026.1.5-announcement",
|
|
16
|
+
"v2026.1.4-announcement",
|
|
17
|
+
"v2026.1.3-announcement",
|
|
6
18
|
"v2024.12.5-announcement",
|
|
7
19
|
"v2024.12.4-announcement",
|
|
8
20
|
"v2024.12.3-announcement",
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# AIWG v2026.2.9 — "Manifest Native" Release
|
|
2
|
+
|
|
3
|
+
**Released**: 2026-02-15
|
|
4
|
+
|
|
5
|
+
This release completes provider normalization around manifest-driven discovery so framework/addon deployment no longer depends on scattered provider-specific curation. Codex now receives the same research and media-curator deployment coverage as the other providers.
|
|
6
|
+
|
|
7
|
+
## Highlights
|
|
8
|
+
|
|
9
|
+
| What changed | Why you care |
|
|
10
|
+
|--------------|--------------|
|
|
11
|
+
| Manifest-native provider deployment | Framework artifacts are discovered from manifests/shared utilities instead of hardcoded per-provider lists |
|
|
12
|
+
| Codex framework parity | Research and Media Curator components are now included through the same mode-aware discovery path |
|
|
13
|
+
| Lower maintenance overhead | Adding new frameworks/components is significantly more automatic once manifests are present |
|
|
14
|
+
| Test coverage updates | Integration and smoke tests now assert normalized provider behavior for framework deployment |
|
|
15
|
+
|
|
16
|
+
## Provider Normalization
|
|
17
|
+
|
|
18
|
+
All 8 providers now align on shared discovery behavior:
|
|
19
|
+
|
|
20
|
+
- Claude
|
|
21
|
+
- Codex (OpenAI)
|
|
22
|
+
- Copilot
|
|
23
|
+
- Cursor
|
|
24
|
+
- Factory
|
|
25
|
+
- OpenCode
|
|
26
|
+
- Warp
|
|
27
|
+
- Windsurf
|
|
28
|
+
|
|
29
|
+
Instead of each provider manually curating framework directories, deployment now uses centralized manifest-aware helpers to resolve frameworks and artifacts by mode.
|
|
30
|
+
|
|
31
|
+
## Codex: Research + Media Curator Coverage
|
|
32
|
+
|
|
33
|
+
Codex deployment scripts now use framework discovery for command and skill selection, which closes gaps where newly added frameworks could be missed in Codex-specific install paths.
|
|
34
|
+
|
|
35
|
+
### What this enables
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# These now deploy consistently for Codex via the normalized discovery path
|
|
39
|
+
aiwg use research --provider codex
|
|
40
|
+
aiwg use media-curator --provider codex
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Manifest-Driven Extensibility
|
|
44
|
+
|
|
45
|
+
A framework with a valid `manifest.json` and standard component layout is now discoverable by provider deployment without requiring one-off changes in each provider module.
|
|
46
|
+
|
|
47
|
+
This release also adds explicit manifest metadata for `research-complete` to support that flow.
|
|
48
|
+
|
|
49
|
+
## Install / Update
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install -g aiwg@2026.2.9
|
|
53
|
+
|
|
54
|
+
# Or update existing installation
|
|
55
|
+
aiwg update
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Full Changelog
|
|
59
|
+
|
|
60
|
+
See [CHANGELOG.md](../../CHANGELOG.md) for complete details.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aiwg",
|
|
3
|
-
"version": "2026.2.
|
|
3
|
+
"version": "2026.2.9",
|
|
4
4
|
"description": "Cognitive architecture for AI-augmented software development with structured memory, ensemble validation, and closed-loop correction. FAIR-aligned artifacts, 84% cost reduction via human-in-the-loop, standards adopted by 100+ organizations.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
"package-plugins": "node tools/plugin/package-plugins.mjs --all",
|
|
18
18
|
"package-plugins:clean": "node tools/plugin/package-plugins.mjs --all --clean",
|
|
19
19
|
"build": "tsc",
|
|
20
|
-
"test": "vitest",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"test:ci": "vitest run --exclude \"test/integration/**\" --exclude \"test/characterization/**\" --exclude \"test/smoke/**\" --exclude \"test/unit/intake/git-history-analyzer.test.ts\" --exclude \"test/unit/ralph-external/snapshot-manager.test.ts\" --exclude \"test/unit/smiths/toolsmith/runtime-discovery.test.ts\"",
|
|
21
22
|
"test:coverage": "vitest --coverage",
|
|
22
23
|
"test:ui": "vitest --ui",
|
|
23
|
-
"test:watch": "vitest
|
|
24
|
+
"test:watch": "vitest",
|
|
24
25
|
"typecheck": "tsc --noEmit",
|
|
25
26
|
"clean": "rm -rf dist coverage"
|
|
26
27
|
},
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* Options:
|
|
12
12
|
* --source <path> Source directory (defaults to repo root)
|
|
13
13
|
* --target <path> Target directory (defaults to cwd)
|
|
14
|
-
* --mode <type> Deployment mode: general, sdlc, marketing, media-curator, research, both, or all (default)
|
|
14
|
+
* --mode <type> Deployment mode: general, sdlc, marketing (alias: mmk), media-curator, research, both, or all (default)
|
|
15
15
|
* --deploy-commands Deploy commands in addition to agents
|
|
16
16
|
* --deploy-skills Deploy skills in addition to agents
|
|
17
17
|
* --deploy-rules Deploy rules in addition to agents
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* general - Deploy only writing-quality addon agents and commands (alias: writing)
|
|
32
32
|
* writing - Deploy only writing-quality addon agents (alias for general)
|
|
33
33
|
* sdlc - Deploy only SDLC Complete framework agents and commands
|
|
34
|
-
* marketing - Deploy only Media/Marketing Kit framework agents and commands
|
|
34
|
+
* marketing - Deploy only Media/Marketing Kit framework agents and commands (alias: mmk)
|
|
35
35
|
* media-curator - Deploy only Media Curator framework agents and commands
|
|
36
36
|
* research - Deploy only Research Complete framework agents and commands
|
|
37
37
|
* both - Deploy writing + SDLC (legacy compatibility)
|
|
@@ -140,7 +140,7 @@ Usage:
|
|
|
140
140
|
Options:
|
|
141
141
|
--source <path> Source directory (defaults to repo root)
|
|
142
142
|
--target <path> Target directory (defaults to cwd)
|
|
143
|
-
--mode <type> Deployment mode: general, sdlc, marketing, media-curator, research, both, or all (default)
|
|
143
|
+
--mode <type> Deployment mode: general, sdlc, marketing (alias: mmk), media-curator, research, both, or all (default)
|
|
144
144
|
--deploy-commands Deploy commands in addition to agents
|
|
145
145
|
--deploy-skills Deploy skills in addition to agents
|
|
146
146
|
--deploy-rules Deploy rules in addition to agents
|
|
@@ -181,7 +181,7 @@ Providers (all deploy agents, commands, skills, and rules):
|
|
|
181
181
|
Modes:
|
|
182
182
|
general - Writing-quality addon agents and commands (alias: writing)
|
|
183
183
|
sdlc - SDLC Complete framework agents and commands
|
|
184
|
-
marketing - Media/Marketing Kit framework agents and commands
|
|
184
|
+
marketing - Media/Marketing Kit framework agents and commands (alias: mmk)
|
|
185
185
|
media-curator - Media Curator framework agents and commands
|
|
186
186
|
research - Research Complete framework agents and commands
|
|
187
187
|
both - writing + SDLC (legacy compatibility)
|
|
@@ -342,6 +342,7 @@ function deepMerge(target, source) {
|
|
|
342
342
|
|
|
343
343
|
// Normalize mode aliases
|
|
344
344
|
if (cfg.mode === 'writing') cfg.mode = 'general';
|
|
345
|
+
if (cfg.mode === 'mmk') cfg.mode = 'marketing';
|
|
345
346
|
|
|
346
347
|
console.log(`\n=== AIWG Agent Deployment ===`);
|
|
347
348
|
console.log(`Provider: ${cfg.provider}`);
|
|
@@ -371,39 +371,47 @@ export function deploySkillDir(skillDir, destDir, opts) {
|
|
|
371
371
|
* Initialize framework-scoped workspace structure
|
|
372
372
|
* Creates .aiwg/frameworks/{framework-id}/ directories
|
|
373
373
|
*/
|
|
374
|
-
export function initializeFrameworkWorkspace(target, mode, dryRun) {
|
|
374
|
+
export function initializeFrameworkWorkspace(target, mode, dryRun, srcRoot = null) {
|
|
375
375
|
const aiwgBase = path.join(target, '.aiwg');
|
|
376
376
|
const frameworksDir = path.join(aiwgBase, 'frameworks');
|
|
377
377
|
const sharedDir = path.join(aiwgBase, 'shared');
|
|
378
378
|
|
|
379
|
-
const frameworkDirs =
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
379
|
+
const frameworkDirs = srcRoot
|
|
380
|
+
? getFrameworksForMode(srcRoot, mode).map(fw => ({
|
|
381
|
+
id: fw.id,
|
|
382
|
+
subdirs: fw.workspaceSubdirs
|
|
383
|
+
}))
|
|
384
|
+
: [];
|
|
385
|
+
|
|
386
|
+
// Backward-compatible fallback when source root isn't provided.
|
|
387
|
+
if (frameworkDirs.length === 0) {
|
|
388
|
+
if (mode === 'sdlc' || mode === 'both' || mode === 'all') {
|
|
389
|
+
frameworkDirs.push({
|
|
390
|
+
id: 'sdlc-complete',
|
|
391
|
+
subdirs: ['repo', 'projects', 'working', 'archive']
|
|
392
|
+
});
|
|
393
|
+
}
|
|
387
394
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
395
|
+
if (mode === 'marketing' || mode === 'all') {
|
|
396
|
+
frameworkDirs.push({
|
|
397
|
+
id: 'media-marketing-kit',
|
|
398
|
+
subdirs: ['repo', 'campaigns', 'working', 'archive']
|
|
399
|
+
});
|
|
400
|
+
}
|
|
394
401
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
402
|
+
if (mode === 'media-curator' || mode === 'all') {
|
|
403
|
+
frameworkDirs.push({
|
|
404
|
+
id: 'media-curator',
|
|
405
|
+
subdirs: ['repo', 'library', 'working', 'archive']
|
|
406
|
+
});
|
|
407
|
+
}
|
|
401
408
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
409
|
+
if (mode === 'research' || mode === 'all') {
|
|
410
|
+
frameworkDirs.push({
|
|
411
|
+
id: 'research-complete',
|
|
412
|
+
subdirs: ['repo', 'corpus', 'working', 'archive']
|
|
413
|
+
});
|
|
414
|
+
}
|
|
407
415
|
}
|
|
408
416
|
|
|
409
417
|
if (frameworkDirs.length === 0) return;
|
|
@@ -582,6 +590,209 @@ export function filterAgentFiles(files, opts) {
|
|
|
582
590
|
});
|
|
583
591
|
}
|
|
584
592
|
|
|
593
|
+
// ============================================================================
|
|
594
|
+
// Framework Discovery
|
|
595
|
+
// ============================================================================
|
|
596
|
+
|
|
597
|
+
const MODE_ALIASES = {
|
|
598
|
+
writing: 'general',
|
|
599
|
+
mmk: 'marketing'
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
const LEGACY_FRAMEWORK_MODE_ALIASES = {
|
|
603
|
+
'sdlc-complete': ['sdlc'],
|
|
604
|
+
'media-marketing-kit': ['marketing', 'mmk'],
|
|
605
|
+
'media-curator': ['media-curator'],
|
|
606
|
+
'research-complete': ['research']
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
const DEFAULT_FRAMEWORK_SUBDIRS = {
|
|
610
|
+
'sdlc-complete': ['repo', 'projects', 'working', 'archive'],
|
|
611
|
+
'media-marketing-kit': ['repo', 'campaigns', 'working', 'archive'],
|
|
612
|
+
'media-curator': ['repo', 'library', 'working', 'archive'],
|
|
613
|
+
'research-complete': ['repo', 'corpus', 'working', 'archive']
|
|
614
|
+
};
|
|
615
|
+
|
|
616
|
+
function normalizePathSegment(segment) {
|
|
617
|
+
return String(segment || '')
|
|
618
|
+
.replace(/^\/+/, '')
|
|
619
|
+
.replace(/\/+$/, '');
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
function ensureStringArray(value) {
|
|
623
|
+
if (!value) return [];
|
|
624
|
+
return Array.isArray(value) ? value.map(v => String(v)) : [String(value)];
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
function uniqueLower(values) {
|
|
628
|
+
const seen = new Set();
|
|
629
|
+
const out = [];
|
|
630
|
+
for (const raw of values) {
|
|
631
|
+
const v = String(raw || '').trim().toLowerCase();
|
|
632
|
+
if (!v || seen.has(v)) continue;
|
|
633
|
+
seen.add(v);
|
|
634
|
+
out.push(v);
|
|
635
|
+
}
|
|
636
|
+
return out;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
export function normalizeDeploymentMode(mode = 'all') {
|
|
640
|
+
const normalized = String(mode || 'all').toLowerCase();
|
|
641
|
+
return MODE_ALIASES[normalized] || normalized;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
function resolveFrameworkComponentDir(frameworkPath, manifest, component) {
|
|
645
|
+
const entry = manifest?.entry?.[component];
|
|
646
|
+
const relPath = normalizePathSegment(entry || component);
|
|
647
|
+
return path.join(frameworkPath, relPath);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Discover framework roots under agentic/code/frameworks.
|
|
652
|
+
* Framework metadata is loaded from root manifest.json when present.
|
|
653
|
+
*/
|
|
654
|
+
export function discoverFrameworks(srcRoot) {
|
|
655
|
+
const frameworksRoot = path.join(srcRoot, 'agentic', 'code', 'frameworks');
|
|
656
|
+
if (!fs.existsSync(frameworksRoot)) return [];
|
|
657
|
+
|
|
658
|
+
const frameworks = [];
|
|
659
|
+
const entries = fs.readdirSync(frameworksRoot, { withFileTypes: true })
|
|
660
|
+
.filter(e => e.isDirectory())
|
|
661
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
662
|
+
|
|
663
|
+
for (const entry of entries) {
|
|
664
|
+
const frameworkPath = path.join(frameworksRoot, entry.name);
|
|
665
|
+
const manifestPath = path.join(frameworkPath, 'manifest.json');
|
|
666
|
+
let manifest = {};
|
|
667
|
+
|
|
668
|
+
if (fs.existsSync(manifestPath)) {
|
|
669
|
+
try {
|
|
670
|
+
manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
671
|
+
} catch (e) {
|
|
672
|
+
console.warn(`Warning: Could not parse framework manifest for ${entry.name}: ${e.message}`);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
const id = String(manifest.id || manifest.framework || entry.name);
|
|
677
|
+
const aliases = uniqueLower([
|
|
678
|
+
id,
|
|
679
|
+
entry.name,
|
|
680
|
+
...ensureStringArray(manifest.modeAliases),
|
|
681
|
+
...ensureStringArray(manifest.aliases),
|
|
682
|
+
...(LEGACY_FRAMEWORK_MODE_ALIASES[id] || [])
|
|
683
|
+
]);
|
|
684
|
+
|
|
685
|
+
const workspaceSubdirs = ensureStringArray(
|
|
686
|
+
manifest.workspace?.subdirs || manifest.workspace?.directories
|
|
687
|
+
);
|
|
688
|
+
|
|
689
|
+
const agentsDir = resolveFrameworkComponentDir(frameworkPath, manifest, 'agents');
|
|
690
|
+
const commandsDir = resolveFrameworkComponentDir(frameworkPath, manifest, 'commands');
|
|
691
|
+
const skillsDir = resolveFrameworkComponentDir(frameworkPath, manifest, 'skills');
|
|
692
|
+
const rulesDir = resolveFrameworkComponentDir(frameworkPath, manifest, 'rules');
|
|
693
|
+
|
|
694
|
+
frameworks.push({
|
|
695
|
+
id,
|
|
696
|
+
name: manifest.name || entry.name,
|
|
697
|
+
path: frameworkPath,
|
|
698
|
+
manifest,
|
|
699
|
+
aliases,
|
|
700
|
+
workspaceSubdirs: workspaceSubdirs.length > 0
|
|
701
|
+
? workspaceSubdirs
|
|
702
|
+
: (DEFAULT_FRAMEWORK_SUBDIRS[id] || ['repo', 'working', 'archive']),
|
|
703
|
+
components: {
|
|
704
|
+
agents: { path: agentsDir, exists: fs.existsSync(agentsDir) },
|
|
705
|
+
commands: { path: commandsDir, exists: fs.existsSync(commandsDir) },
|
|
706
|
+
skills: { path: skillsDir, exists: fs.existsSync(skillsDir) },
|
|
707
|
+
rules: { path: rulesDir, exists: fs.existsSync(rulesDir) }
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
return frameworks;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Select frameworks for a deployment mode.
|
|
717
|
+
*/
|
|
718
|
+
export function getFrameworksForMode(srcRoot, mode) {
|
|
719
|
+
const normalizedMode = normalizeDeploymentMode(mode);
|
|
720
|
+
const frameworks = discoverFrameworks(srcRoot);
|
|
721
|
+
|
|
722
|
+
if (normalizedMode === 'all') return frameworks;
|
|
723
|
+
if (normalizedMode === 'general') return [];
|
|
724
|
+
if (normalizedMode === 'both') {
|
|
725
|
+
return frameworks.filter(fw => fw.aliases.includes('sdlc'));
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
return frameworks.filter(fw =>
|
|
729
|
+
fw.id.toLowerCase() === normalizedMode || fw.aliases.includes(normalizedMode)
|
|
730
|
+
);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Collect framework artifacts for a deployment mode.
|
|
735
|
+
* @param {string} srcRoot - Source root directory
|
|
736
|
+
* @param {string} mode - Deployment mode
|
|
737
|
+
* @param {object} options - Collection options
|
|
738
|
+
* @param {boolean} options.includeAgents - Include agents
|
|
739
|
+
* @param {boolean} options.includeCommands - Include commands
|
|
740
|
+
* @param {boolean} options.includeSkills - Include skills
|
|
741
|
+
* @param {boolean} options.includeRules - Include rules
|
|
742
|
+
* @param {boolean} options.recursiveCommands - Use recursive command listing
|
|
743
|
+
* @param {boolean} options.consolidatedSdlcRules - Use RULES-INDEX for SDLC when available
|
|
744
|
+
* @returns {{frameworks: Array, agents: string[], commands: string[], skills: string[], rules: string[]}}
|
|
745
|
+
*/
|
|
746
|
+
export function collectFrameworkArtifacts(srcRoot, mode, options = {}) {
|
|
747
|
+
const {
|
|
748
|
+
includeAgents = true,
|
|
749
|
+
includeCommands = true,
|
|
750
|
+
includeSkills = true,
|
|
751
|
+
includeRules = true,
|
|
752
|
+
recursiveCommands = true,
|
|
753
|
+
consolidatedSdlcRules = true
|
|
754
|
+
} = options;
|
|
755
|
+
|
|
756
|
+
const frameworks = getFrameworksForMode(srcRoot, mode);
|
|
757
|
+
const artifacts = {
|
|
758
|
+
frameworks,
|
|
759
|
+
agents: [],
|
|
760
|
+
commands: [],
|
|
761
|
+
skills: [],
|
|
762
|
+
rules: []
|
|
763
|
+
};
|
|
764
|
+
|
|
765
|
+
for (const framework of frameworks) {
|
|
766
|
+
if (includeAgents && framework.components.agents.exists) {
|
|
767
|
+
artifacts.agents.push(...listMdFiles(framework.components.agents.path));
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
if (includeCommands && framework.components.commands.exists) {
|
|
771
|
+
const commandFiles = recursiveCommands
|
|
772
|
+
? listMdFilesRecursive(framework.components.commands.path)
|
|
773
|
+
: listMdFiles(framework.components.commands.path);
|
|
774
|
+
artifacts.commands.push(...commandFiles);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
if (includeSkills && framework.components.skills.exists) {
|
|
778
|
+
artifacts.skills.push(...listSkillDirs(framework.components.skills.path));
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
if (includeRules && framework.components.rules.exists) {
|
|
782
|
+
if (consolidatedSdlcRules && framework.id === 'sdlc-complete') {
|
|
783
|
+
const indexPath = getRulesIndexPath(srcRoot);
|
|
784
|
+
if (indexPath) {
|
|
785
|
+
artifacts.rules.push(indexPath);
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
artifacts.rules.push(...listMdFiles(framework.components.rules.path));
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
return artifacts;
|
|
794
|
+
}
|
|
795
|
+
|
|
585
796
|
// ============================================================================
|
|
586
797
|
// Addon Discovery
|
|
587
798
|
// ============================================================================
|