@dcyfr/ai 1.0.1 → 1.0.3
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/CHANGELOG.md +21 -0
- package/README.md +19 -22
- package/bin/cli.js +12 -0
- package/bin/tui/config-wizard.js +107 -0
- package/bin/tui/validation-dashboard.js +123 -0
- package/bin/tui.js +259 -0
- package/dist/ai/agents/agent-loader.d.ts +131 -0
- package/dist/ai/agents/agent-loader.d.ts.map +1 -0
- package/dist/ai/agents/agent-loader.js +399 -0
- package/dist/ai/agents/agent-loader.js.map +1 -0
- package/dist/ai/agents/agent-registry.d.ts +120 -0
- package/dist/ai/agents/agent-registry.d.ts.map +1 -0
- package/dist/ai/agents/agent-registry.js +345 -0
- package/dist/ai/agents/agent-registry.js.map +1 -0
- package/dist/ai/agents/agent-router.d.ts +97 -0
- package/dist/ai/agents/agent-router.d.ts.map +1 -0
- package/dist/ai/agents/agent-router.js +375 -0
- package/dist/ai/agents/agent-router.js.map +1 -0
- package/dist/ai/agents/index.d.ts +10 -0
- package/dist/ai/agents/index.d.ts.map +1 -0
- package/dist/ai/agents/index.js +12 -0
- package/dist/ai/agents/index.js.map +1 -0
- package/dist/ai/agents/types.d.ts +264 -0
- package/dist/ai/agents/types.d.ts.map +1 -0
- package/dist/ai/agents/types.js +10 -0
- package/dist/ai/agents/types.js.map +1 -0
- package/dist/ai/agents-builtin/architecture/architecture-reviewer.d.ts +12 -0
- package/dist/ai/agents-builtin/architecture/architecture-reviewer.d.ts.map +1 -0
- package/dist/ai/agents-builtin/architecture/architecture-reviewer.js +92 -0
- package/dist/ai/agents-builtin/architecture/architecture-reviewer.js.map +1 -0
- package/dist/ai/agents-builtin/architecture/cloud-architect.d.ts +12 -0
- package/dist/ai/agents-builtin/architecture/cloud-architect.d.ts.map +1 -0
- package/dist/ai/agents-builtin/architecture/cloud-architect.js +103 -0
- package/dist/ai/agents-builtin/architecture/cloud-architect.js.map +1 -0
- package/dist/ai/agents-builtin/architecture/database-architect.d.ts +12 -0
- package/dist/ai/agents-builtin/architecture/database-architect.d.ts.map +1 -0
- package/dist/ai/agents-builtin/architecture/database-architect.js +95 -0
- package/dist/ai/agents-builtin/architecture/database-architect.js.map +1 -0
- package/dist/ai/agents-builtin/architecture/index.d.ts +11 -0
- package/dist/ai/agents-builtin/architecture/index.d.ts.map +1 -0
- package/dist/ai/agents-builtin/architecture/index.js +11 -0
- package/dist/ai/agents-builtin/architecture/index.js.map +1 -0
- package/dist/ai/agents-builtin/content/index.d.ts +9 -0
- package/dist/ai/agents-builtin/content/index.d.ts.map +1 -0
- package/dist/ai/agents-builtin/content/index.js +9 -0
- package/dist/ai/agents-builtin/content/index.js.map +1 -0
- package/dist/ai/agents-builtin/content/technical-writer.d.ts +12 -0
- package/dist/ai/agents-builtin/content/technical-writer.d.ts.map +1 -0
- package/dist/ai/agents-builtin/content/technical-writer.js +93 -0
- package/dist/ai/agents-builtin/content/technical-writer.js.map +1 -0
- package/dist/ai/agents-builtin/data/data-scientist.d.ts +12 -0
- package/dist/ai/agents-builtin/data/data-scientist.d.ts.map +1 -0
- package/dist/ai/agents-builtin/data/data-scientist.js +92 -0
- package/dist/ai/agents-builtin/data/data-scientist.js.map +1 -0
- package/dist/ai/agents-builtin/data/index.d.ts +9 -0
- package/dist/ai/agents-builtin/data/index.d.ts.map +1 -0
- package/dist/ai/agents-builtin/data/index.js +9 -0
- package/dist/ai/agents-builtin/data/index.js.map +1 -0
- package/dist/ai/agents-builtin/development/backend-architect.d.ts +12 -0
- package/dist/ai/agents-builtin/development/backend-architect.d.ts.map +1 -0
- package/dist/ai/agents-builtin/development/backend-architect.js +99 -0
- package/dist/ai/agents-builtin/development/backend-architect.js.map +1 -0
- package/dist/ai/agents-builtin/development/frontend-developer.d.ts +12 -0
- package/dist/ai/agents-builtin/development/frontend-developer.d.ts.map +1 -0
- package/dist/ai/agents-builtin/development/frontend-developer.js +106 -0
- package/dist/ai/agents-builtin/development/frontend-developer.js.map +1 -0
- package/dist/ai/agents-builtin/development/fullstack-developer.d.ts +12 -0
- package/dist/ai/agents-builtin/development/fullstack-developer.d.ts.map +1 -0
- package/dist/ai/agents-builtin/development/fullstack-developer.js +86 -0
- package/dist/ai/agents-builtin/development/fullstack-developer.js.map +1 -0
- package/dist/ai/agents-builtin/development/index.d.ts +12 -0
- package/dist/ai/agents-builtin/development/index.d.ts.map +1 -0
- package/dist/ai/agents-builtin/development/index.js +12 -0
- package/dist/ai/agents-builtin/development/index.js.map +1 -0
- package/dist/ai/agents-builtin/development/typescript-pro.d.ts +12 -0
- package/dist/ai/agents-builtin/development/typescript-pro.d.ts.map +1 -0
- package/dist/ai/agents-builtin/development/typescript-pro.js +98 -0
- package/dist/ai/agents-builtin/development/typescript-pro.js.map +1 -0
- package/dist/ai/agents-builtin/devops/devops-engineer.d.ts +12 -0
- package/dist/ai/agents-builtin/devops/devops-engineer.d.ts.map +1 -0
- package/dist/ai/agents-builtin/devops/devops-engineer.js +98 -0
- package/dist/ai/agents-builtin/devops/devops-engineer.js.map +1 -0
- package/dist/ai/agents-builtin/devops/index.d.ts +9 -0
- package/dist/ai/agents-builtin/devops/index.d.ts.map +1 -0
- package/dist/ai/agents-builtin/devops/index.js +9 -0
- package/dist/ai/agents-builtin/devops/index.js.map +1 -0
- package/dist/ai/agents-builtin/index.d.ts +36 -0
- package/dist/ai/agents-builtin/index.d.ts.map +1 -0
- package/dist/ai/agents-builtin/index.js +107 -0
- package/dist/ai/agents-builtin/index.js.map +1 -0
- package/dist/ai/agents-builtin/performance/index.d.ts +9 -0
- package/dist/ai/agents-builtin/performance/index.d.ts.map +1 -0
- package/dist/ai/agents-builtin/performance/index.js +9 -0
- package/dist/ai/agents-builtin/performance/index.js.map +1 -0
- package/dist/ai/agents-builtin/performance/performance-profiler.d.ts +12 -0
- package/dist/ai/agents-builtin/performance/performance-profiler.d.ts.map +1 -0
- package/dist/ai/agents-builtin/performance/performance-profiler.js +89 -0
- package/dist/ai/agents-builtin/performance/performance-profiler.js.map +1 -0
- package/dist/ai/agents-builtin/research/index.d.ts +9 -0
- package/dist/ai/agents-builtin/research/index.d.ts.map +1 -0
- package/dist/ai/agents-builtin/research/index.js +9 -0
- package/dist/ai/agents-builtin/research/index.js.map +1 -0
- package/dist/ai/agents-builtin/research/research-orchestrator.d.ts +12 -0
- package/dist/ai/agents-builtin/research/research-orchestrator.d.ts.map +1 -0
- package/dist/ai/agents-builtin/research/research-orchestrator.js +83 -0
- package/dist/ai/agents-builtin/research/research-orchestrator.js.map +1 -0
- package/dist/ai/agents-builtin/security/index.d.ts +9 -0
- package/dist/ai/agents-builtin/security/index.d.ts.map +1 -0
- package/dist/ai/agents-builtin/security/index.js +9 -0
- package/dist/ai/agents-builtin/security/index.js.map +1 -0
- package/dist/ai/agents-builtin/security/security-engineer.d.ts +12 -0
- package/dist/ai/agents-builtin/security/security-engineer.d.ts.map +1 -0
- package/dist/ai/agents-builtin/security/security-engineer.js +90 -0
- package/dist/ai/agents-builtin/security/security-engineer.js.map +1 -0
- package/dist/ai/agents-builtin/testing/debugger.d.ts +13 -0
- package/dist/ai/agents-builtin/testing/debugger.d.ts.map +1 -0
- package/dist/ai/agents-builtin/testing/debugger.js +89 -0
- package/dist/ai/agents-builtin/testing/debugger.js.map +1 -0
- package/dist/ai/agents-builtin/testing/index.d.ts +10 -0
- package/dist/ai/agents-builtin/testing/index.d.ts.map +1 -0
- package/dist/ai/agents-builtin/testing/index.js +10 -0
- package/dist/ai/agents-builtin/testing/index.js.map +1 -0
- package/dist/ai/agents-builtin/testing/test-engineer.d.ts +12 -0
- package/dist/ai/agents-builtin/testing/test-engineer.d.ts.map +1 -0
- package/dist/ai/agents-builtin/testing/test-engineer.js +93 -0
- package/dist/ai/agents-builtin/testing/test-engineer.js.map +1 -0
- package/dist/ai/config/loader.d.ts +19 -5
- package/dist/ai/config/loader.d.ts.map +1 -1
- package/dist/ai/config/loader.js +53 -18
- package/dist/ai/config/loader.js.map +1 -1
- package/dist/ai/config/schema.d.ts +600 -8
- package/dist/ai/config/schema.d.ts.map +1 -1
- package/dist/ai/config/schema.js +156 -0
- package/dist/ai/config/schema.js.map +1 -1
- package/dist/ai/index.d.ts +4 -1
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +35 -1
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/mcp/index.d.ts +8 -0
- package/dist/ai/mcp/index.d.ts.map +1 -0
- package/dist/ai/mcp/index.js +8 -0
- package/dist/ai/mcp/index.js.map +1 -0
- package/dist/ai/mcp/mcp-registry.d.ts +127 -0
- package/dist/ai/mcp/mcp-registry.d.ts.map +1 -0
- package/dist/ai/mcp/mcp-registry.js +355 -0
- package/dist/ai/mcp/mcp-registry.js.map +1 -0
- package/dist/ai/mcp/types.d.ts +126 -0
- package/dist/ai/mcp/types.d.ts.map +1 -0
- package/dist/ai/mcp/types.js +9 -0
- package/dist/ai/mcp/types.js.map +1 -0
- package/dist/ai/utils/storage.d.ts +6 -1
- package/dist/ai/utils/storage.d.ts.map +1 -1
- package/dist/ai/utils/storage.js +57 -22
- package/dist/ai/utils/storage.js.map +1 -1
- package/package.json +24 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`1d6f12e`](https://github.com/dcyfr/dcyfr-ai/commit/1d6f12ed981054fcb0b26beac4be452926ba793f) Thanks [@dcyfr](https://github.com/dcyfr)! - Automated release management and CI improvements
|
|
8
|
+
|
|
9
|
+
- Added automated release workflows with changesets
|
|
10
|
+
- Fixed glob TypeScript compatibility issues
|
|
11
|
+
- Improved integration test handling for CI environments
|
|
12
|
+
- Added canary release workflow for pre-release testing
|
|
13
|
+
- Comprehensive CI pipeline with type checking, linting, and tests
|
|
14
|
+
|
|
3
15
|
All notable changes to @dcyfr/ai will be documented in this file.
|
|
4
16
|
|
|
5
17
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
@@ -10,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
10
22
|
### Added
|
|
11
23
|
|
|
12
24
|
#### Core Framework
|
|
25
|
+
|
|
13
26
|
- Configuration system with three-layer merge (defaults → project → env)
|
|
14
27
|
- Support for YAML, JSON, and package.json configuration formats
|
|
15
28
|
- Environment variable overrides for all configuration options
|
|
@@ -20,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
20
33
|
- Validation framework with parallel/serial execution modes
|
|
21
34
|
|
|
22
35
|
#### Plugin System
|
|
36
|
+
|
|
23
37
|
- Plugin manifest validation
|
|
24
38
|
- Lifecycle hooks (onLoad, onValidate, onComplete, onUnload)
|
|
25
39
|
- Error isolation and recovery
|
|
@@ -27,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
27
41
|
- Plugin timeout support
|
|
28
42
|
|
|
29
43
|
#### Telemetry
|
|
44
|
+
|
|
30
45
|
- Session management with context tracking
|
|
31
46
|
- Metric recording (compliance, test pass rate, costs)
|
|
32
47
|
- Agent statistics aggregation
|
|
@@ -35,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
35
50
|
- Memory storage adapter for testing
|
|
36
51
|
|
|
37
52
|
#### Provider Support
|
|
53
|
+
|
|
38
54
|
- Claude (Anthropic)
|
|
39
55
|
- Groq
|
|
40
56
|
- Ollama
|
|
@@ -43,6 +59,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
43
59
|
- Generic provider interface
|
|
44
60
|
|
|
45
61
|
#### CLI Tools
|
|
62
|
+
|
|
46
63
|
- `init` - Initialize new project
|
|
47
64
|
- `config:init` - Create configuration file
|
|
48
65
|
- `config:validate` - Validate configuration
|
|
@@ -50,6 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
50
67
|
- `plugin:create` - Generate plugin template
|
|
51
68
|
|
|
52
69
|
#### Documentation
|
|
70
|
+
|
|
53
71
|
- Comprehensive getting started guide
|
|
54
72
|
- Complete API reference
|
|
55
73
|
- Plugin development guide
|
|
@@ -57,6 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
57
75
|
- Migration documentation
|
|
58
76
|
|
|
59
77
|
#### Configuration Templates
|
|
78
|
+
|
|
60
79
|
- Default YAML configuration
|
|
61
80
|
- Default JSON configuration
|
|
62
81
|
- Minimal configuration templates
|
|
@@ -70,6 +89,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
70
89
|
- Zero breaking changes in API surface
|
|
71
90
|
|
|
72
91
|
### Developer Experience
|
|
92
|
+
|
|
73
93
|
- Type-safe configuration with Zod
|
|
74
94
|
- ESM modules with .d.ts declarations
|
|
75
95
|
- Comprehensive error messages
|
|
@@ -79,6 +99,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
79
99
|
## [Unreleased]
|
|
80
100
|
|
|
81
101
|
### Planned
|
|
102
|
+
|
|
82
103
|
- Redis storage adapter for telemetry
|
|
83
104
|
- Database storage adapter
|
|
84
105
|
- Additional validation gates
|
package/README.md
CHANGED
|
@@ -187,31 +187,28 @@ See [examples/](./examples/) directory:
|
|
|
187
187
|
- [Configuration Guide](./docs/configuration.md)
|
|
188
188
|
- [Plugin Development](./docs/plugins.md)
|
|
189
189
|
- [API Reference](./docs/api.md)
|
|
190
|
+
- [Release Management](./docs/RELEASE_MANAGEMENT.md) - Publishing and versioning
|
|
191
|
+
- [Quick Release Guide](./docs/RELEASE_QUICK_START.md) - TL;DR for releases
|
|
190
192
|
|
|
191
|
-
##
|
|
193
|
+
## Contributing
|
|
192
194
|
|
|
193
|
-
|
|
194
|
-
@dcyfr/ai (Public Framework)
|
|
195
|
-
├── Core
|
|
196
|
-
│ ├── TelemetryEngine - Usage tracking
|
|
197
|
-
│ └── ProviderRegistry - Multi-provider AI
|
|
198
|
-
├── Plugins
|
|
199
|
-
│ ├── PluginLoader - Dynamic loading
|
|
200
|
-
│ └── ValidationFramework - Quality gates
|
|
201
|
-
├── Config
|
|
202
|
-
│ ├── Schema (Zod) - Validation
|
|
203
|
-
│ └── Loader - Three-layer merge
|
|
204
|
-
└── CLI
|
|
205
|
-
└── Config tools
|
|
206
|
-
|
|
207
|
-
@dcyfr/agents (Private Agents)
|
|
208
|
-
└── Specialized validators for DCYFR projects
|
|
209
|
-
```
|
|
195
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for contribution guidelines.
|
|
210
196
|
|
|
211
|
-
|
|
197
|
+
### Release Process
|
|
212
198
|
|
|
213
|
-
|
|
199
|
+
We use [Changesets](https://github.com/changesets/changesets) for automated versioning and publishing.
|
|
214
200
|
|
|
215
|
-
|
|
201
|
+
**For contributors:**
|
|
202
|
+
```bash
|
|
203
|
+
# Add a changeset describing your changes
|
|
204
|
+
npm run changeset
|
|
216
205
|
|
|
217
|
-
|
|
206
|
+
# Commit the changeset with your PR
|
|
207
|
+
git add .changeset/*.md
|
|
208
|
+
git commit -m "feat: your feature"
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**For maintainers:**
|
|
212
|
+
- Changesets automatically creates Release PRs
|
|
213
|
+
- Merging a Release PR publishes to npm
|
|
214
|
+
- See [Release Management](./docs/RELEASE_MANAGEMENT.md) for full details
|
package/bin/cli.js
CHANGED
|
@@ -176,6 +176,8 @@ Commands:
|
|
|
176
176
|
config:validate Validate configuration file
|
|
177
177
|
config:init Initialize new configuration file
|
|
178
178
|
config:schema Show configuration schema
|
|
179
|
+
tui:dashboard Interactive validation dashboard (OpenTUI)
|
|
180
|
+
tui:wizard Interactive configuration wizard (OpenTUI)
|
|
179
181
|
help Show this help message
|
|
180
182
|
|
|
181
183
|
Options:
|
|
@@ -230,6 +232,16 @@ async function main() {
|
|
|
230
232
|
await showSchema();
|
|
231
233
|
break;
|
|
232
234
|
|
|
235
|
+
case 'tui:dashboard':
|
|
236
|
+
case 'tui:wizard':
|
|
237
|
+
case 'tui':
|
|
238
|
+
// Delegate to TUI CLI
|
|
239
|
+
console.log('🎨 Launching interactive TUI...\n');
|
|
240
|
+
console.log('Use: npx @dcyfr/ai-tui ' + options.command.replace('tui:', ''));
|
|
241
|
+
console.log('Or run: node bin/tui.js ' + options.command.replace('tui:', ''));
|
|
242
|
+
process.exit(0);
|
|
243
|
+
break;
|
|
244
|
+
|
|
233
245
|
case 'help':
|
|
234
246
|
case '--help':
|
|
235
247
|
case '-h':
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive Configuration Wizard
|
|
3
|
+
* Uses inquirer for interactive prompts
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import inquirer from 'inquirer';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Run configuration wizard
|
|
11
|
+
*/
|
|
12
|
+
export async function runConfigWizard() {
|
|
13
|
+
console.log(chalk.cyan.bold('\n⚙️ DCYFR Configuration Wizard\n'));
|
|
14
|
+
console.log(chalk.gray('Configure your AI agent framework\n'));
|
|
15
|
+
|
|
16
|
+
const answers = await inquirer.prompt([
|
|
17
|
+
{
|
|
18
|
+
type: 'input',
|
|
19
|
+
name: 'projectName',
|
|
20
|
+
message: 'Project name:',
|
|
21
|
+
default: 'my-project',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
type: 'list',
|
|
25
|
+
name: 'format',
|
|
26
|
+
message: 'Config format:',
|
|
27
|
+
choices: [
|
|
28
|
+
{ name: 'YAML (Recommended)', value: 'yaml' },
|
|
29
|
+
{ name: 'JSON', value: 'json' },
|
|
30
|
+
],
|
|
31
|
+
default: 'yaml',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: 'confirm',
|
|
35
|
+
name: 'telemetryEnabled',
|
|
36
|
+
message: 'Enable telemetry?',
|
|
37
|
+
default: true,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
type: 'confirm',
|
|
41
|
+
name: 'validationEnabled',
|
|
42
|
+
message: 'Enable validation?',
|
|
43
|
+
default: true,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: 'confirm',
|
|
47
|
+
name: 'parallelExecution',
|
|
48
|
+
message: 'Enable parallel execution?',
|
|
49
|
+
default: true,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
type: 'number',
|
|
53
|
+
name: 'designTokenCompliance',
|
|
54
|
+
message: 'Design token compliance threshold (%):',
|
|
55
|
+
default: 90,
|
|
56
|
+
when: (answers) => answers.validationEnabled,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
type: 'number',
|
|
60
|
+
name: 'pageLayoutUsage',
|
|
61
|
+
message: 'PageLayout usage threshold (%):',
|
|
62
|
+
default: 90,
|
|
63
|
+
when: (answers) => answers.validationEnabled,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: 'checkbox',
|
|
67
|
+
name: 'agents',
|
|
68
|
+
message: 'Select agents to enable:',
|
|
69
|
+
choices: [
|
|
70
|
+
{ name: 'Design Tokens', value: 'designTokens', checked: true },
|
|
71
|
+
{ name: 'Barrel Exports', value: 'barrelExports', checked: true },
|
|
72
|
+
{ name: 'Page Layout', value: 'pageLayout', checked: true },
|
|
73
|
+
{ name: 'Test Data', value: 'testData', checked: true },
|
|
74
|
+
{ name: 'API Pattern', value: 'apiPattern', checked: false },
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
projectName: answers.projectName,
|
|
81
|
+
format: answers.format,
|
|
82
|
+
telemetryEnabled: answers.telemetryEnabled,
|
|
83
|
+
validationEnabled: answers.validationEnabled,
|
|
84
|
+
parallelExecution: answers.parallelExecution,
|
|
85
|
+
designTokenCompliance: answers.designTokenCompliance || 90,
|
|
86
|
+
pageLayoutUsage: answers.pageLayoutUsage || 90,
|
|
87
|
+
agents: {
|
|
88
|
+
designTokens: {
|
|
89
|
+
enabled: answers.agents.includes('designTokens'),
|
|
90
|
+
compliance: (answers.designTokenCompliance || 90) / 100,
|
|
91
|
+
},
|
|
92
|
+
barrelExports: {
|
|
93
|
+
enabled: answers.agents.includes('barrelExports'),
|
|
94
|
+
},
|
|
95
|
+
pageLayout: {
|
|
96
|
+
enabled: answers.agents.includes('pageLayout'),
|
|
97
|
+
targetUsage: (answers.pageLayoutUsage || 90) / 100,
|
|
98
|
+
},
|
|
99
|
+
testData: {
|
|
100
|
+
enabled: answers.agents.includes('testData'),
|
|
101
|
+
},
|
|
102
|
+
apiPattern: {
|
|
103
|
+
enabled: answers.agents.includes('apiPattern'),
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Validation Dashboard
|
|
3
|
+
* Interactive terminal UI for displaying validation results using chalk and cli-table3
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import Table from 'cli-table3';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Status icon helper
|
|
11
|
+
*/
|
|
12
|
+
export function getStatusIcon(status) {
|
|
13
|
+
const icons = {
|
|
14
|
+
pass: chalk.green.bold('✓'),
|
|
15
|
+
fail: chalk.red.bold('✗'),
|
|
16
|
+
warn: chalk.yellow.bold('⚠'),
|
|
17
|
+
pending: chalk.gray.bold('○'),
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return icons[status] || icons.pending;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Progress bar helper
|
|
25
|
+
*/
|
|
26
|
+
export function renderProgressBar(value, max = 100, width = 30) {
|
|
27
|
+
const percentage = Math.min(100, (value / max) * 100);
|
|
28
|
+
const filledWidth = Math.floor((percentage / 100) * width);
|
|
29
|
+
const emptyWidth = width - filledWidth;
|
|
30
|
+
|
|
31
|
+
const filled = '█'.repeat(filledWidth);
|
|
32
|
+
const empty = '░'.repeat(emptyWidth);
|
|
33
|
+
|
|
34
|
+
let colorFn = chalk.green;
|
|
35
|
+
if (percentage < 50) colorFn = chalk.red;
|
|
36
|
+
else if (percentage < 90) colorFn = chalk.yellow;
|
|
37
|
+
|
|
38
|
+
return `${colorFn(filled)}${chalk.gray(empty)} ${chalk.cyan(percentage.toFixed(1) + '%')}`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Render gate status row
|
|
43
|
+
*/
|
|
44
|
+
export function renderGateRow(gate) {
|
|
45
|
+
const status = gate.passed ? 'pass' : 'fail';
|
|
46
|
+
const compliance = gate.compliance || 0;
|
|
47
|
+
const icon = getStatusIcon(status);
|
|
48
|
+
const progressBar = renderProgressBar(compliance, 100, 20);
|
|
49
|
+
const issues = gate.violations > 0 ? chalk.red(`${gate.violations} issues`) : chalk.gray('0 issues');
|
|
50
|
+
|
|
51
|
+
const name = gate.name.padEnd(20);
|
|
52
|
+
|
|
53
|
+
return `${icon} ${name} ${progressBar} ${issues}`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Render agent summary
|
|
58
|
+
*/
|
|
59
|
+
export function renderAgentSummary(agents) {
|
|
60
|
+
const lines = [chalk.cyan.bold('🤖 Agents'), ''];
|
|
61
|
+
|
|
62
|
+
Object.entries(agents).forEach(([name, config]) => {
|
|
63
|
+
const enabled = 'enabled' in config ? config.enabled : true;
|
|
64
|
+
const icon = enabled ? chalk.green('✓') : chalk.gray('✗');
|
|
65
|
+
const agentName = enabled ? chalk.white(name) : chalk.gray(name);
|
|
66
|
+
lines.push(` ${icon} ${agentName}`);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return lines.join('\n');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Main validation dashboard
|
|
74
|
+
*/
|
|
75
|
+
export function renderValidationDashboard(config, report) {
|
|
76
|
+
const hasReport = report && report.gates;
|
|
77
|
+
const passed = report?.valid || false;
|
|
78
|
+
|
|
79
|
+
const lines = [];
|
|
80
|
+
|
|
81
|
+
// Header
|
|
82
|
+
const status = passed ? chalk.green.bold('PASS') : chalk.red.bold('FAIL');
|
|
83
|
+
lines.push('');
|
|
84
|
+
lines.push(chalk.cyan.bold('🔍 DCYFR Validation Dashboard') + ' ' + status);
|
|
85
|
+
lines.push('─'.repeat(80));
|
|
86
|
+
lines.push('');
|
|
87
|
+
|
|
88
|
+
// Project info
|
|
89
|
+
lines.push(`${chalk.gray('📂 Project:')} ${chalk.white(config.projectName || '(unnamed)')}`);
|
|
90
|
+
lines.push(`${chalk.gray('📊 Version:')} ${chalk.white(config.version)}`);
|
|
91
|
+
lines.push('');
|
|
92
|
+
|
|
93
|
+
// Validation gates
|
|
94
|
+
if (hasReport) {
|
|
95
|
+
lines.push(chalk.cyan.bold('🎯 Validation Gates'));
|
|
96
|
+
lines.push('');
|
|
97
|
+
report.gates.forEach((gate) => {
|
|
98
|
+
lines.push(renderGateRow(gate));
|
|
99
|
+
});
|
|
100
|
+
lines.push('');
|
|
101
|
+
|
|
102
|
+
// Overall metrics
|
|
103
|
+
lines.push('─'.repeat(80));
|
|
104
|
+
const gatesPassed = report.gates.filter((g) => g.passed).length;
|
|
105
|
+
const totalViolations = report.gates.reduce((sum, g) => sum + (g.violations || 0), 0);
|
|
106
|
+
const avgCompliance = (report.gates.reduce((sum, g) => sum + (g.compliance || 0), 0) / report.gates.length).toFixed(1);
|
|
107
|
+
|
|
108
|
+
lines.push('');
|
|
109
|
+
lines.push(`${chalk.gray('Gates Passed:')} ${chalk.green.bold(gatesPassed)}/${report.gates.length} ${chalk.gray('Total Violations:')} ${chalk.red.bold(totalViolations)} ${chalk.gray('Avg Compliance:')} ${chalk.cyan.bold(avgCompliance + '%')}`);
|
|
110
|
+
lines.push('');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Agent summary
|
|
114
|
+
lines.push(renderAgentSummary(config.agents));
|
|
115
|
+
lines.push('');
|
|
116
|
+
|
|
117
|
+
// Footer
|
|
118
|
+
lines.push('─'.repeat(80));
|
|
119
|
+
lines.push(chalk.gray.italic('Press Q to quit, R to refresh, V for verbose mode'));
|
|
120
|
+
lines.push('');
|
|
121
|
+
|
|
122
|
+
return lines.join('\n');
|
|
123
|
+
}
|
package/bin/tui.js
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* DCYFR AI Framework TUI (Terminal UI)
|
|
5
|
+
* Interactive dashboard using chalk and inquirer
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import ora from 'ora';
|
|
10
|
+
import readline from 'readline';
|
|
11
|
+
import { ConfigLoader } from '../dist/ai/config/loader.js';
|
|
12
|
+
import { ValidationFramework } from '../dist/ai/validation/framework.js';
|
|
13
|
+
import { renderValidationDashboard } from './tui/validation-dashboard.js';
|
|
14
|
+
import { runConfigWizard } from './tui/config-wizard.js';
|
|
15
|
+
import { existsSync } from 'fs';
|
|
16
|
+
import { writeFile } from 'fs/promises';
|
|
17
|
+
import { join } from 'path';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Run interactive validation dashboard
|
|
21
|
+
*/
|
|
22
|
+
async function runDashboard(options) {
|
|
23
|
+
const projectRoot = options.root || process.cwd();
|
|
24
|
+
const configFile = options.config;
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
// Load configuration
|
|
28
|
+
const spinner = ora('Loading configuration...').start();
|
|
29
|
+
|
|
30
|
+
const loader = new ConfigLoader({
|
|
31
|
+
projectRoot,
|
|
32
|
+
configFile,
|
|
33
|
+
validate: true,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const config = await loader.load();
|
|
37
|
+
spinner.succeed('Configuration loaded');
|
|
38
|
+
|
|
39
|
+
// Run validation
|
|
40
|
+
spinner.start('Running validation...');
|
|
41
|
+
|
|
42
|
+
const framework = new ValidationFramework({
|
|
43
|
+
gates: config.validation.gates,
|
|
44
|
+
parallel: config.validation.parallel,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const report = await framework.validate({
|
|
48
|
+
projectRoot: config.project.root,
|
|
49
|
+
files: config.project.include,
|
|
50
|
+
config: config.agents,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
spinner.succeed('Validation complete');
|
|
54
|
+
|
|
55
|
+
// Display dashboard
|
|
56
|
+
console.clear();
|
|
57
|
+
console.log(renderValidationDashboard(config, report));
|
|
58
|
+
|
|
59
|
+
// Setup keyboard input for interactive mode
|
|
60
|
+
readline.emitKeypressEvents(process.stdin);
|
|
61
|
+
if (process.stdin.isTTY) {
|
|
62
|
+
process.stdin.setRawMode(true);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.log(chalk.gray('\nPress Q to quit, R to refresh...\n'));
|
|
66
|
+
|
|
67
|
+
process.stdin.on('keypress', async (str, key) => {
|
|
68
|
+
if (key.name === 'q' || (key.ctrl && key.name === 'c')) {
|
|
69
|
+
console.log(chalk.yellow('\n👋 Exiting dashboard...\n'));
|
|
70
|
+
process.exit(0);
|
|
71
|
+
} else if (key.name === 'r') {
|
|
72
|
+
// Refresh
|
|
73
|
+
console.clear();
|
|
74
|
+
const spinner = ora('Refreshing validation...').start();
|
|
75
|
+
const newReport = await framework.validate({
|
|
76
|
+
projectRoot: config.project.root,
|
|
77
|
+
files: config.project.include,
|
|
78
|
+
config: config.agents,
|
|
79
|
+
});
|
|
80
|
+
spinner.succeed('Validation refreshed');
|
|
81
|
+
console.log(renderValidationDashboard(config, newReport));
|
|
82
|
+
console.log(chalk.gray('\nPress Q to quit, R to refresh...\n'));
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error(chalk.red('❌ Failed to run dashboard:'), error.message);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Run interactive configuration wizard
|
|
93
|
+
*/
|
|
94
|
+
async function runWizard(options) {
|
|
95
|
+
const projectRoot = options.root || process.cwd();
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
const config = await runConfigWizard();
|
|
99
|
+
|
|
100
|
+
// Create config file
|
|
101
|
+
await createConfigFile(config, projectRoot);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
if (error.isTTYError) {
|
|
104
|
+
console.error(chalk.red('❌ Prompt couldn\'t be rendered in the current environment'));
|
|
105
|
+
} else {
|
|
106
|
+
console.error(chalk.red('❌ Failed to run wizard:'), error.message);
|
|
107
|
+
}
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Create configuration file from wizard state
|
|
114
|
+
*/
|
|
115
|
+
async function createConfigFile(state, projectRoot) {
|
|
116
|
+
const configFile = state.format === 'json' ? '.dcyfr.json' : '.dcyfr.yaml';
|
|
117
|
+
const configPath = join(projectRoot, configFile);
|
|
118
|
+
|
|
119
|
+
if (existsSync(configPath)) {
|
|
120
|
+
console.error(chalk.red(`\n❌ Config file already exists: ${configPath}`));
|
|
121
|
+
console.error(chalk.yellow('Delete it first or use --force flag'));
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Build config object
|
|
126
|
+
const config = {
|
|
127
|
+
version: '1.0.0',
|
|
128
|
+
projectName: state.projectName || 'my-project',
|
|
129
|
+
telemetry: {
|
|
130
|
+
enabled: state.telemetryEnabled,
|
|
131
|
+
},
|
|
132
|
+
validation: {
|
|
133
|
+
enabled: state.validationEnabled,
|
|
134
|
+
parallel: state.parallelExecution,
|
|
135
|
+
gates: Object.entries(state.agents)
|
|
136
|
+
.filter(([_, cfg]) => cfg.enabled)
|
|
137
|
+
.map(([name]) => name),
|
|
138
|
+
},
|
|
139
|
+
agents: state.agents,
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// Write file
|
|
143
|
+
const content =
|
|
144
|
+
state.format === 'json'
|
|
145
|
+
? JSON.stringify(config, null, 2)
|
|
146
|
+
: Object.entries(config)
|
|
147
|
+
.map(([key, val]) => `${key}: ${JSON.stringify(val)}`)
|
|
148
|
+
.join('\n');
|
|
149
|
+
|
|
150
|
+
await writeFile(configPath, content, 'utf-8');
|
|
151
|
+
|
|
152
|
+
console.log(chalk.green(`\n✅ Created ${configPath}`));
|
|
153
|
+
console.log(chalk.cyan('\nNext steps:'));
|
|
154
|
+
console.log(' 1. Review and customize the configuration');
|
|
155
|
+
console.log(' 2. Run ' + chalk.bold('npx @dcyfr/ai tui:dashboard') + ' to test');
|
|
156
|
+
console.log(' 3. Integrate into your CI/CD pipeline\n');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Show TUI help
|
|
161
|
+
*/
|
|
162
|
+
function showHelp() {
|
|
163
|
+
console.log(`
|
|
164
|
+
DCYFR AI Framework - Interactive TUI
|
|
165
|
+
|
|
166
|
+
Usage:
|
|
167
|
+
npx @dcyfr/ai tui:<command> [options]
|
|
168
|
+
|
|
169
|
+
Commands:
|
|
170
|
+
tui:dashboard Interactive validation dashboard
|
|
171
|
+
tui:wizard Interactive configuration wizard
|
|
172
|
+
tui:help Show this help message
|
|
173
|
+
|
|
174
|
+
Options:
|
|
175
|
+
--root <path> Project root directory (default: current directory)
|
|
176
|
+
--config <file> Custom config file path (dashboard only)
|
|
177
|
+
--format <json|yaml> Config format for wizard (default: yaml)
|
|
178
|
+
|
|
179
|
+
Examples:
|
|
180
|
+
# Run interactive validation dashboard
|
|
181
|
+
npx @dcyfr/ai tui:dashboard
|
|
182
|
+
|
|
183
|
+
# Run configuration wizard
|
|
184
|
+
npx @dcyfr/ai tui:wizard
|
|
185
|
+
|
|
186
|
+
# Dashboard with custom config
|
|
187
|
+
npx @dcyfr/ai tui:dashboard --config custom.yaml
|
|
188
|
+
|
|
189
|
+
Keyboard Shortcuts:
|
|
190
|
+
Q Quit
|
|
191
|
+
R Refresh (dashboard)
|
|
192
|
+
V Verbose mode
|
|
193
|
+
Ctrl+C Exit
|
|
194
|
+
|
|
195
|
+
Documentation:
|
|
196
|
+
https://github.com/dcyfr/dcyfr-ai/blob/main/docs/TUI.md
|
|
197
|
+
`);
|
|
198
|
+
process.exit(0);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Parse command line arguments
|
|
203
|
+
*/
|
|
204
|
+
function parseArgs() {
|
|
205
|
+
const args = process.argv.slice(2);
|
|
206
|
+
const command = args[0] || 'help';
|
|
207
|
+
const flags = {};
|
|
208
|
+
|
|
209
|
+
for (let i = 1; i < args.length; i++) {
|
|
210
|
+
const arg = args[i];
|
|
211
|
+
|
|
212
|
+
if (arg.startsWith('--')) {
|
|
213
|
+
const [key, value] = arg.substring(2).split('=');
|
|
214
|
+
if (value !== undefined) {
|
|
215
|
+
flags[key] = value;
|
|
216
|
+
} else {
|
|
217
|
+
flags[key] = args[i + 1]?.startsWith('--') ? true : args[++i] || true;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return { command, flags };
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Main CLI entry point
|
|
227
|
+
*/
|
|
228
|
+
async function main() {
|
|
229
|
+
const { command, flags } = parseArgs();
|
|
230
|
+
|
|
231
|
+
switch (command) {
|
|
232
|
+
case 'tui:dashboard':
|
|
233
|
+
case 'dashboard':
|
|
234
|
+
await runDashboard(flags);
|
|
235
|
+
break;
|
|
236
|
+
|
|
237
|
+
case 'tui:wizard':
|
|
238
|
+
case 'wizard':
|
|
239
|
+
await runWizard(flags);
|
|
240
|
+
break;
|
|
241
|
+
|
|
242
|
+
case 'tui:help':
|
|
243
|
+
case 'help':
|
|
244
|
+
case '--help':
|
|
245
|
+
case '-h':
|
|
246
|
+
showHelp();
|
|
247
|
+
break;
|
|
248
|
+
|
|
249
|
+
default:
|
|
250
|
+
console.error(`❌ Unknown command: ${command}\n`);
|
|
251
|
+
showHelp();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Run CLI
|
|
256
|
+
main().catch((error) => {
|
|
257
|
+
console.error('❌ Unexpected error:', error);
|
|
258
|
+
process.exit(1);
|
|
259
|
+
});
|