@vfarcic/dot-ai 0.40.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  </div>
8
8
 
9
- DevOps AI Toolkit provides three powerful AI-driven capabilities: **Kubernetes deployment recommendations** that discover your cluster's capabilities and suggest optimal deployment approaches, **automated documentation testing** that validates documentation accuracy by executing commands and testing examples, and **shared prompts library** that enables centralized prompt sharing via native slash commands across development teams.
9
+ DevOps AI Toolkit is an AI-powered development productivity platform that enhances software development workflows through intelligent automation and AI-driven assistance.
10
10
 
11
11
  ## Who is this for?
12
12
 
@@ -86,7 +86,7 @@ DevOps AI Toolkit is designed to be used through AI development tools via MCP (M
86
86
  Perfect for conversational AI-driven workflows:
87
87
 
88
88
  1. **Create `.mcp.json` in your project:**
89
- <!-- dotai-ignore: MCP server binary (dot-ai-mcp) not testable as CLI - only works through MCP client connections -->
89
+ <!-- dotai-ignore: MCP server binary (dot-ai-mcp) only works through MCP client connections -->
90
90
  ```json
91
91
  {
92
92
  "mcpServers": {
@@ -203,35 +203,17 @@ Agent: I'm executing the PRD creation workflow. Please describe the feature you
203
203
  - **[MCP Documentation Testing Guide](docs/mcp-documentation-testing-guide.md)** - Automated documentation validation
204
204
  - **[MCP Prompts Guide](docs/mcp-prompts-guide.md)** - Shared prompt library and slash commands
205
205
 
206
- ### 👩‍💻 Development
207
- - **[API Reference](docs/API.md)** - TypeScript interfaces and programmatic usage
208
- - **[Development Guide](docs/DEVELOPMENT.md)** - Contributing, setup, and testing
209
-
210
- ### 🏗️ Architecture
211
- - **[Design Overview](docs/design.md)** - Technical design and principles
212
- - **[Discovery Engine](docs/discovery-engine.md)** - Cluster resource discovery
213
-
214
- ### 🤖 AI & Integration
215
- - **[Error Handling](docs/error-handling.md)** - Error management and debugging
216
- - **[Function Registration](docs/function-registration.md)** - Tool and function management
217
-
218
- **Quick Navigation:**
219
- - **New to DevOps AI Toolkit?** → Start with [MCP Setup Guide](docs/mcp-setup.md)
220
- - **Building integrations?** → See [API Reference](docs/API.md)
221
- - **Contributing code?** → Read [Development Guide](docs/DEVELOPMENT.md)
222
- - **Understanding architecture?** → Check [Design Overview](docs/design.md)
223
-
224
206
  ## Support
225
207
 
226
208
  - **Issues**: [GitHub Issues](https://github.com/vfarcic/dot-ai/issues)
227
209
 
228
210
  ## Contributing
229
211
 
230
- We welcome contributions! See the [Development Guide](docs/DEVELOPMENT.md) for details on:
231
- - Setting up the development environment
232
- - Running tests
233
- - Code style and conventions
234
- - Submitting pull requests
212
+ We welcome contributions! Please:
213
+ - Fork the repository and create a feature branch
214
+ - Run tests with `npm test` to ensure changes work correctly
215
+ - Follow existing code style and conventions
216
+ - Submit a pull request with a clear description of changes
235
217
 
236
218
  ## License
237
219
 
@@ -239,4 +221,4 @@ MIT License - see [LICENSE](LICENSE) file for details.
239
221
 
240
222
  ---
241
223
 
242
- **DevOps AI Toolkit** - Making Kubernetes deployment intelligent and accessible for everyone.
224
+ **DevOps AI Toolkit** - AI-powered development productivity platform for enhanced software development workflows.
package/dist/index.d.ts CHANGED
@@ -1,10 +1,9 @@
1
1
  /**
2
2
  * DevOps AI Toolkit Main Entry Point
3
3
  *
4
- * Universal Kubernetes application deployment agent with dual CLI/MCP interfaces
4
+ * Universal Kubernetes application deployment agent with MCP interface
5
5
  */
6
6
  export * from './core';
7
- export * from './interfaces/cli';
8
7
  export declare const version = "0.1.0";
9
8
  export declare const name = "dot-ai";
10
9
  declare const _default: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,QAAQ,CAAC;AACvB,cAAc,kBAAkB,CAAC;AAGjC,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,IAAI,WAAW,CAAC;;;;;AAG7B,wBAGE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,QAAQ,CAAC;AAGvB,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,IAAI,WAAW,CAAC;;;;;AAG7B,wBAGE"}
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * DevOps AI Toolkit Main Entry Point
4
4
  *
5
- * Universal Kubernetes application deployment agent with dual CLI/MCP interfaces
5
+ * Universal Kubernetes application deployment agent with MCP interface
6
6
  */
7
7
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
8
  if (k2 === undefined) k2 = k;
@@ -21,7 +21,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
22
  exports.name = exports.version = void 0;
23
23
  __exportStar(require("./core"), exports);
24
- __exportStar(require("./interfaces/cli"), exports);
25
24
  // Version information
26
25
  exports.version = '0.1.0';
27
26
  exports.name = 'dot-ai';
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "@vfarcic/dot-ai",
3
- "version": "0.40.0",
3
+ "version": "0.41.0",
4
4
  "description": "Universal Kubernetes application deployment agent with CLI and MCP interfaces",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "bin": {
8
- "dot-ai": "./dist/cli.js",
9
8
  "dot-ai-mcp": "./dist/mcp/server.js"
10
9
  },
11
10
  "exports": {
@@ -21,14 +20,12 @@
21
20
  "clean": "rm -rf dist",
22
21
  "prebuild": "npm run clean && npm run lint",
23
22
  "build": "tsc --sourceMap false",
24
- "postbuild": "chmod +x dist/cli.js dist/mcp/server.js",
23
+ "postbuild": "chmod +x dist/mcp/server.js",
25
24
  "build:prod": "npm run clean && tsc --sourceMap false --removeComments true",
26
25
  "build:dev": "tsc --sourceMap true",
27
26
  "build:watch": "tsc --watch",
28
- "build:cli": "npm run build && chmod +x dist/cli.js",
29
27
  "build:mcp": "npm run build && echo 'MCP server built successfully'",
30
28
  "dev": "ts-node src/index.ts",
31
- "start:cli": "node dist/cli.js",
32
29
  "start:mcp": "node dist/mcp/server.js",
33
30
  "lint": "eslint src/ --ext .ts",
34
31
  "format": "prettier --write src/",
@@ -42,7 +39,6 @@
42
39
  "keywords": [
43
40
  "kubernetes",
44
41
  "deployment",
45
- "cli",
46
42
  "mcp",
47
43
  "devops",
48
44
  "containers",
@@ -12,49 +12,28 @@ You are helping initiate active implementation work on a specific Product Requir
12
12
 
13
13
  ## Process Overview
14
14
 
15
- 1. **Auto-Detect Target PRD** - Intelligently determine which PRD to start implementing
16
- 2. **Validate PRD Readiness** - Ensure the PRD is ready for implementation
15
+ 1. **Select Target PRD** - Ask user which PRD they want to implement
16
+ 2. **Validate PRD Readiness** - Ensure the selected PRD is ready for implementation
17
17
  3. **Set Up Implementation Context** - Prepare the development environment
18
18
  4. **Identify Starting Point** - Determine the best first implementation task
19
19
  5. **Begin Implementation** - Launch into actual development work
20
20
 
21
- ## Step 1: Smart PRD Detection
21
+ ## Step 1: PRD Selection
22
22
 
23
- **Auto-detect the target PRD using these context clues (in priority order):**
23
+ **Ask the user which PRD they want to start implementing:**
24
24
 
25
- 1. **Git Branch Analysis** - Check current branch name for PRD patterns:
26
- - `feature/prd-12-*` PRD 12
27
- - `prd-13-*` → PRD 13
28
- - `feature/prd-*` → Extract PRD number
29
-
30
- 2. **Recent Git Commits** - Look at recent commit messages for PRD references:
31
- - "feat: PRD 12 setup" → PRD 12
32
- - "docs: update prd-13 requirements" → PRD 13
33
-
34
- 3. **Git Status Analysis** - Check modified/staged files for PRD clues:
35
- - Modified `prds/12-*.md` → PRD 12
36
- - Changes in PRD-specific directories
25
+ ```markdown
26
+ ## Which PRD would you like to start implementing?
37
27
 
38
- 4. **Available PRDs Discovery** - List all PRDs in `prds/` directory and identify those ready for implementation
28
+ Please provide the PRD number (e.g., "12", "PRD 12", or "36").
39
29
 
40
- 5. **Fallback to User Choice** - Only if context detection fails, ask user to specify
30
+ **Not sure which PRD to work on?**
31
+ Execute `dot-ai:prds-get` prompt to see all available PRDs organized by priority and readiness.
41
32
 
42
- **PRD Detection Implementation:**
43
- ```bash
44
- # Use these tools to gather context:
45
- # 1. Check git branch: gitStatus shows current branch
46
- # 2. Check git status: Look for modified PRD files
47
- # 3. List PRDs: Use LS or Glob to find prds/*.md files
48
- # 4. Recent commits: Use Bash 'git log --oneline -n 5' for recent context
33
+ **Your choice**: [Wait for user input]
49
34
  ```
50
35
 
51
- **Detection Output:**
52
- ```markdown
53
- 🚀 **Starting work on PRD [X]** ([Feature Name])
54
- - Branch: `feature/prd-[X]-[feature-name]` ✅
55
- - PRD file: `prds/[X]-[feature-name].md` ✅
56
- - Current status: Ready for implementation ✅
57
- ```
36
+ Once the user provides the PRD number, proceed to load and validate that specific PRD.
58
37
 
59
38
  ## Step 2: PRD Readiness Validation
60
39
 
@@ -104,6 +83,8 @@ git push -u origin feature/prd-[issue-id]-[feature-name]
104
83
  - **Mark PRD as "In Progress"**: Update PRD status section
105
84
  - **Create implementation log**: Add initial work log entry with start date
106
85
  - **Set up progress tracking**: Identify key milestones for progress updates
86
+ - **✅ CRITICAL: Update milestone checkboxes**: As you complete each implementation milestone in the PRD, immediately mark the corresponding checkbox as [x] completed
87
+ - **Commit milestone updates**: Include PRD milestone updates in your commits to maintain accurate progress tracking
107
88
 
108
89
  ## Step 4: Identify Implementation Starting Point
109
90
 
@@ -167,6 +148,12 @@ If confirmed, provide:
167
148
  - **Commit initial setup**: Make initial commit with branch and any setup changes
168
149
  - **Documentation updates**: Add PRD traceability comments to any docs being implemented
169
150
 
151
+ ### Ongoing PRD Maintenance During Implementation
152
+ Throughout the implementation process:
153
+ - **After completing any milestone**: Immediately update the corresponding checkbox in the PRD file from `[ ]` to `[x]`
154
+ - **Update work log**: Add entries documenting what was accomplished
155
+ - **Keep status current**: Update the PRD status section to reflect current implementation state
156
+
170
157
  ## Success Criteria
171
158
 
172
159
  This command should:
@@ -22,14 +22,25 @@ Fetch all open GitHub issues from this project that have the 'PRD' label.
22
22
  - Direct link to the issue
23
23
  - PRD file link (if available in issue description)
24
24
 
25
- 3. **Priority Analysis**: If multiple PRDs exist, help identify:
26
- - Which PRDs are most recently updated
27
- - Which PRDs have active work in progress
28
- - Which PRDs might be blocked or stalled
29
-
30
- 4. **Next Steps Suggestion**: Based on the PRD list, suggest logical next actions:
31
- - Which PRD to work on next
32
- - PRDs that need attention or updates
33
- - Opportunities for parallel work
25
+ 3. **Meaningful Categorization**: Group PRDs by their actual purpose and impact, not generic labels:
26
+ - **Architecture & Infrastructure**: Core system changes, API designs, major refactors
27
+ - **User Experience**: Features that directly impact how users interact with the system
28
+ - **Developer Experience**: Tools, workflows, testing, documentation that help developers
29
+ - **AI & Intelligence**: Machine learning, AI-powered features, recommendation engines
30
+ - **Operations & Monitoring**: Deployment, scaling, observability, performance
31
+ - **Integration & Extensibility**: Third-party integrations, plugin systems, APIs
32
+
33
+ Each category should briefly explain what the PRDs in that group will accomplish for users or the system.
34
+
35
+ 4. **Priority Analysis**: If multiple PRDs exist, help identify:
36
+ - Which PRDs are most recently updated or have active discussion
37
+ - Which PRDs have dependencies on other PRDs
38
+ - Which PRDs are foundational vs. incremental improvements
39
+ - Which PRDs might be blocked or need clarification
40
+
41
+ 5. **Next Steps Suggestion**: Based on the PRD list, suggest logical next actions:
42
+ - Which PRD to work on next based on dependencies and impact
43
+ - PRDs that need attention, updates, or clarification
44
+ - Opportunities for parallel work on independent PRDs
34
45
 
35
46
  This provides a complete view of all active product requirements and helps with project planning and prioritization.
package/dist/cli.d.ts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js DELETED
@@ -1,51 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- const index_js_1 = require("./core/index.js");
5
- const cli_js_1 = require("./interfaces/cli.js");
6
- function isHelpCommand(argv) {
7
- return argv.includes('--help') || argv.includes('-h') ||
8
- argv.includes('help') || argv.includes('--version') ||
9
- argv.includes('-v') || argv.length <= 2;
10
- }
11
- async function main() {
12
- try {
13
- // Create CLI interface first (without cluster connection)
14
- const cli = new cli_js_1.CliInterface();
15
- // If it's a help or version command, run immediately without cluster
16
- if (isHelpCommand(process.argv)) {
17
- await cli.run(process.argv);
18
- return;
19
- }
20
- // For other commands, initialize cluster connection
21
- const kubeconfigIndex = process.argv.findIndex(arg => arg === '--kubeconfig');
22
- const kubeconfigPath = kubeconfigIndex !== -1 && kubeconfigIndex + 1 < process.argv.length
23
- ? process.argv[kubeconfigIndex + 1]
24
- : undefined;
25
- const dotAI = new index_js_1.DotAI({
26
- kubernetesConfig: kubeconfigPath
27
- });
28
- await dotAI.initialize();
29
- // Set the initialized agent and run the command
30
- cli.setDotAI(dotAI);
31
- await cli.run(process.argv);
32
- }
33
- catch (error) {
34
- process.stderr.write(`Failed to start DevOps AI Toolkit CLI: ${error.message}\n`);
35
- // Provide troubleshooting guidance for cluster connection issues
36
- if (error.message.includes('No active cluster') ||
37
- error.message.includes('connection refused') ||
38
- error.message.includes('kubeconfig')) {
39
- process.stderr.write(`\nTroubleshooting steps:\n`);
40
- process.stderr.write(`- Run 'kubectl cluster-info' to verify cluster connectivity\n`);
41
- process.stderr.write(`- Check your kubeconfig with 'kubectl config view'\n`);
42
- process.stderr.write(`- Verify cluster endpoint accessibility\n`);
43
- }
44
- process.exit(1);
45
- }
46
- }
47
- main().catch(error => {
48
- // Use process.stderr.write instead of console.error to avoid ESLint warnings
49
- process.stderr.write(`Unexpected error: ${error}\n`);
50
- process.exit(1);
51
- });
@@ -1,75 +0,0 @@
1
- /**
2
- * CLI Interface Module
3
- *
4
- * Command-line interface for dot-ai
5
- */
6
- import { DotAI } from '../core';
7
- export interface CliResult {
8
- success: boolean;
9
- data?: any;
10
- error?: string;
11
- warnings?: string[];
12
- _rawFormat?: boolean;
13
- }
14
- export interface ParsedArguments {
15
- command: string;
16
- options: Record<string, any>;
17
- }
18
- export interface CliConfig {
19
- defaultOutput?: string;
20
- verboseMode?: boolean;
21
- outputFile?: string;
22
- quietMode?: boolean;
23
- }
24
- export declare class CliInterface {
25
- private dotAI?;
26
- private program;
27
- private config;
28
- private logger;
29
- constructor(dotAI?: DotAI, config?: CliConfig);
30
- setDotAI(dotAI: DotAI): void;
31
- private ensureDotAI;
32
- private getPackageInfo;
33
- private setupCommands;
34
- getCommands(): string[];
35
- getSubcommands(): string[];
36
- getHelp(): Promise<string>;
37
- getCommandHelp(commandName: string): Promise<string>;
38
- parseArguments(args: string[]): Promise<ParsedArguments>;
39
- private getValidOptionsForCommand;
40
- executeCommand(command: string, options?: Record<string, any>): Promise<CliResult>;
41
- private handleStatusCommand;
42
- private handleLearnCommand;
43
- private handleRecommendCommand;
44
- private handleChooseSolutionCommand;
45
- private handleAnswerQuestionCommand;
46
- private handleGenerateManifestsCommand;
47
- private handleDeployManifestsCommand;
48
- private handleTestDocsCommand;
49
- continueWorkflow(workflowId: string, input: {
50
- responses: Record<string, any>;
51
- }): Promise<CliResult>;
52
- formatOutput(result: CliResult, format: string): string;
53
- private formatAsTable;
54
- private outputResult;
55
- /**
56
- * Process global options and update config
57
- */
58
- private processGlobalOptions;
59
- private handleError;
60
- /**
61
- * Show progress message to user during long-running operations
62
- */
63
- private showProgress;
64
- /**
65
- * Clear progress indicators
66
- */
67
- private clearProgress;
68
- /**
69
- * Find best solutions with detailed progress feedback
70
- */
71
- private findBestSolutionsWithProgress;
72
- run(args?: string[]): Promise<void>;
73
- }
74
- export default CliInterface;
75
- //# sourceMappingURL=cli.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/interfaces/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAahC,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAC,CAAQ;IACtB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAS;gBAEX,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,GAAE,SAAc;IAiBjD,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAI5B,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,aAAa;IA4NrB,WAAW,IAAI,MAAM,EAAE;IAIvB,cAAc,IAAI,MAAM,EAAE;IAIpB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAoB1B,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQpD,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IAgD9D,OAAO,CAAC,yBAAyB;IA4B3B,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,OAAO,CAAC,SAAS,CAAC;YAsC9E,mBAAmB;YAoBnB,kBAAkB;YAsBlB,sBAAsB;YAsCtB,2BAA2B;YAoC3B,2BAA2B;YAuC3B,8BAA8B;YAoC9B,4BAA4B;YAiC5B,qBAAqB;IAmD7B,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAoBzG,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAgCvD,OAAO,CAAC,aAAa;IAmDrB,OAAO,CAAC,YAAY;IAyBpB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,WAAW;IAkBnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAOpB;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;YACW,6BAA6B;IA+BrC,GAAG,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;CASxD;AAGD,eAAe,YAAY,CAAC"}
@@ -1,844 +0,0 @@
1
- "use strict";
2
- /**
3
- * CLI Interface Module
4
- *
5
- * Command-line interface for dot-ai
6
- */
7
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
- if (k2 === undefined) k2 = k;
9
- var desc = Object.getOwnPropertyDescriptor(m, k);
10
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
- desc = { enumerable: true, get: function() { return m[k]; } };
12
- }
13
- Object.defineProperty(o, k2, desc);
14
- }) : (function(o, m, k, k2) {
15
- if (k2 === undefined) k2 = k;
16
- o[k2] = m[k];
17
- }));
18
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
- Object.defineProperty(o, "default", { enumerable: true, value: v });
20
- }) : function(o, v) {
21
- o["default"] = v;
22
- });
23
- var __importStar = (this && this.__importStar) || (function () {
24
- var ownKeys = function(o) {
25
- ownKeys = Object.getOwnPropertyNames || function (o) {
26
- var ar = [];
27
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
- return ar;
29
- };
30
- return ownKeys(o);
31
- };
32
- return function (mod) {
33
- if (mod && mod.__esModule) return mod;
34
- var result = {};
35
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
- __setModuleDefault(result, mod);
37
- return result;
38
- };
39
- })();
40
- var __importDefault = (this && this.__importDefault) || function (mod) {
41
- return (mod && mod.__esModule) ? mod : { "default": mod };
42
- };
43
- Object.defineProperty(exports, "__esModule", { value: true });
44
- exports.CliInterface = void 0;
45
- const commander_1 = require("commander");
46
- const yaml = __importStar(require("js-yaml"));
47
- const cli_table3_1 = __importDefault(require("cli-table3"));
48
- const recommend_1 = require("../tools/recommend");
49
- const choose_solution_1 = require("../tools/choose-solution");
50
- const answer_question_1 = require("../tools/answer-question");
51
- const generate_manifests_1 = require("../tools/generate-manifests");
52
- const deploy_manifests_1 = require("../tools/deploy-manifests");
53
- const error_handling_1 = require("../core/error-handling");
54
- const fs_1 = require("fs");
55
- const path_1 = require("path");
56
- class CliInterface {
57
- dotAI;
58
- program;
59
- config;
60
- logger;
61
- constructor(dotAI, config = {}) {
62
- this.dotAI = dotAI;
63
- this.config = config;
64
- this.program = new commander_1.Command();
65
- this.logger = new error_handling_1.ConsoleLogger('CLI');
66
- this.program.name('dot-ai').description('AI-powered Kubernetes deployment agent');
67
- // Add global options that apply to all commands
68
- this.program
69
- .option('--kubeconfig <path>', 'Path to kubeconfig file (overrides KUBECONFIG env var and default location)')
70
- .option('--verbose', 'Enable verbose output globally')
71
- .option('--output-file <path>', 'Write clean formatted output to file (respects --output format)')
72
- .option('--quiet', 'Suppress tool registration and info logs');
73
- this.setupCommands();
74
- }
75
- setDotAI(dotAI) {
76
- this.dotAI = dotAI;
77
- }
78
- ensureDotAI() {
79
- if (!this.dotAI) {
80
- throw new Error('Cluster connection required. Please ensure your kubeconfig is valid and cluster is accessible.');
81
- }
82
- return this.dotAI;
83
- }
84
- getPackageInfo() {
85
- try {
86
- const packagePath = (0, path_1.join)(__dirname, '../../package.json');
87
- const packageJson = JSON.parse((0, fs_1.readFileSync)(packagePath, 'utf8'));
88
- return { name: packageJson.name, version: packageJson.version };
89
- }
90
- catch (error) {
91
- return { name: '@vfarcic/dot-ai', version: '0.1.0' }; // fallback
92
- }
93
- }
94
- setupCommands() {
95
- const { name, version } = this.getPackageInfo();
96
- this.program
97
- .name('dot-ai')
98
- .description('Kubernetes application deployment agent with AI-powered orchestration')
99
- .version(version, '-v, --version', 'output the version number');
100
- // Add custom help with installation and usage examples
101
- this.program.addHelpText('after', `
102
-
103
- Installation:
104
- npm install -g ${name} Install globally
105
- npx ${name} <command> Run without installing
106
-
107
- Examples:
108
- npx ${name} recommend --intent "deploy my Node.js app"
109
- npx ${name} status --deployment my-app
110
- npx ${name} learn --pattern microservice
111
-
112
- For more help on specific commands, use:
113
- npx ${name} help <command>
114
- `);
115
- // Status command
116
- this.program
117
- .command('status')
118
- .description('Check deployment status')
119
- .option('--deployment <id>', 'Deployment/workflow ID to check')
120
- .option('--output <format>', 'Output format (json|yaml|table)', 'json')
121
- .action(async (options, command) => {
122
- // Get global options from parent command
123
- const globalOptions = command.parent?.opts() || {};
124
- this.processGlobalOptions(globalOptions);
125
- // Validate output format
126
- if (options.output && !['json', 'yaml', 'table'].includes(options.output)) {
127
- console.error('Error: Invalid output format. Supported: json, yaml, table');
128
- process.exit(1);
129
- }
130
- const result = await this.executeCommand('status', options);
131
- this.outputResult(result, options.output || this.config.defaultOutput || 'json', this.config.outputFile);
132
- });
133
- // Learn command
134
- this.program
135
- .command('learn')
136
- .description('Show learned deployment patterns and recommendations')
137
- .option('--pattern <type>', 'Filter by pattern type')
138
- .option('--output <format>', 'Output format (json|yaml|table)', 'json')
139
- .action(async (options, command) => {
140
- // Get global options from parent command
141
- const globalOptions = command.parent?.opts() || {};
142
- this.processGlobalOptions(globalOptions);
143
- // Validate output format
144
- if (options.output && !['json', 'yaml', 'table'].includes(options.output)) {
145
- console.error('Error: Invalid output format. Supported: json, yaml, table');
146
- process.exit(1);
147
- }
148
- const result = await this.executeCommand('learn', options);
149
- this.outputResult(result, options.output || this.config.defaultOutput || 'json', this.config.outputFile);
150
- });
151
- // Recommend command
152
- this.program
153
- .command('recommend')
154
- .description('Get AI-powered Kubernetes resource recommendations based on your intent')
155
- .requiredOption('--intent <description>', 'Describe what you want to deploy or accomplish')
156
- .option('--session-dir <path>', 'Directory to store solution files (defaults to DOT_AI_SESSION_DIR env var)')
157
- .option('--output <format>', 'Output format (json|yaml|table)', 'json')
158
- .action(async (options, command) => {
159
- // Get global options from parent command
160
- const globalOptions = command.parent?.opts() || {};
161
- this.processGlobalOptions(globalOptions);
162
- // Validate output format
163
- if (options.output && !['json', 'yaml', 'table'].includes(options.output)) {
164
- console.error('Error: Invalid output format. Supported: json, yaml, table');
165
- process.exit(1);
166
- }
167
- const result = await this.executeCommand('recommend', options);
168
- this.outputResult(result, options.output || this.config.defaultOutput || 'json', this.config.outputFile);
169
- });
170
- // Choose Solution command
171
- this.program
172
- .command('choose-solution')
173
- .description('Select a solution by ID and return its questions for configuration')
174
- .requiredOption('--solution-id <id>', 'Solution ID to choose (e.g., sol_2025-07-01T154349_1e1e242592ff)')
175
- .requiredOption('--session-dir <path>', 'Directory containing solution files')
176
- .option('--output <format>', 'Output format (json|yaml|table)', 'json')
177
- .action(async (options, command) => {
178
- // Get global options from parent command
179
- const globalOptions = command.parent?.opts() || {};
180
- this.processGlobalOptions(globalOptions);
181
- // Validate output format
182
- if (options.output && !['json', 'yaml', 'table'].includes(options.output)) {
183
- console.error('Error: Invalid output format. Supported: json, yaml, table');
184
- process.exit(1);
185
- }
186
- const result = await this.executeCommand('chooseSolution', options);
187
- this.outputResult(result, options.output || this.config.defaultOutput || 'json', this.config.outputFile);
188
- });
189
- // Answer Question command
190
- this.program
191
- .command('answer-question')
192
- .description('Process user answers and return remaining questions or completion status')
193
- .requiredOption('--solution-id <id>', 'Solution ID to update (e.g., sol_2025-07-01T154349_1e1e242592ff)')
194
- .requiredOption('--session-dir <path>', 'Directory containing solution files')
195
- .requiredOption('--answers <json>', 'User answers as JSON object')
196
- .requiredOption('--stage <stage>', 'Configuration stage (required, basic, advanced, open)')
197
- .option('--done', 'Set when providing final open question answer', false)
198
- .option('--output <format>', 'Output format (json|yaml|table)', 'json')
199
- .action(async (options, command) => {
200
- // Get global options from parent command
201
- const globalOptions = command.parent?.opts() || {};
202
- this.processGlobalOptions(globalOptions);
203
- // Parse answers JSON
204
- try {
205
- options.answers = JSON.parse(options.answers);
206
- }
207
- catch (error) {
208
- console.error('Error: Invalid JSON in --answers parameter');
209
- process.exit(1);
210
- }
211
- // Validate output format
212
- if (options.output && !['json', 'yaml', 'table'].includes(options.output)) {
213
- console.error('Error: Invalid output format. Supported: json, yaml, table');
214
- process.exit(1);
215
- }
216
- const result = await this.executeCommand('answerQuestion', options);
217
- this.outputResult(result, options.output || this.config.defaultOutput || 'json', this.config.outputFile);
218
- });
219
- // Generate Manifests command
220
- this.program
221
- .command('generate-manifests')
222
- .description('Generate Kubernetes manifests from solution configuration using AI')
223
- .requiredOption('--solution-id <id>', 'Solution ID to generate manifests for (e.g., sol_2025-07-01T154349_1e1e242592ff)')
224
- .requiredOption('--session-dir <path>', 'Directory containing solution files')
225
- .option('--output <format>', 'Output format (json|yaml|table)', 'json')
226
- .action(async (options, command) => {
227
- // Get global options from parent command
228
- const globalOptions = command.parent?.opts() || {};
229
- this.processGlobalOptions(globalOptions);
230
- // Validate output format
231
- if (options.output && !['json', 'yaml', 'table'].includes(options.output)) {
232
- console.error('Error: Invalid output format. Supported: json, yaml, table');
233
- process.exit(1);
234
- }
235
- const result = await this.executeCommand('generateManifests', options);
236
- this.outputResult(result, options.output || this.config.defaultOutput || 'json', this.config.outputFile);
237
- });
238
- // Deploy Manifests command
239
- this.program
240
- .command('deploy-manifests')
241
- .description('Deploy Kubernetes manifests from generated solution')
242
- .requiredOption('--solution-id <id>', 'Solution ID to deploy')
243
- .requiredOption('--session-dir <path>', 'Session directory path')
244
- .option('--timeout <seconds>', 'Deployment timeout in seconds', '30')
245
- .option('--output <format>', 'Output format (json|yaml|table)', 'json')
246
- .action(async (options, command) => {
247
- // Get global options from parent command
248
- const globalOptions = command.parent?.opts() || {};
249
- this.processGlobalOptions(globalOptions);
250
- // Validate output format
251
- if (options.output && !['json', 'yaml', 'table'].includes(options.output)) {
252
- console.error('Error: Invalid output format. Supported: json, yaml, table');
253
- process.exit(1);
254
- }
255
- const result = await this.executeCommand('deployManifests', options);
256
- this.outputResult(result, options.output || this.config.defaultOutput || 'json', this.config.outputFile);
257
- });
258
- // Test Docs command
259
- this.program
260
- .command('test-docs')
261
- .description('Test documentation for accuracy and functionality')
262
- .option('--file <path>', 'Path to documentation file to test (optional - if not provided, will discover available files)')
263
- .option('--file-pattern <pattern>', 'File pattern for discovery (e.g., "**/*.md", "*.rst") - defaults to DOT_AI_DOC_PATTERN env var or "**/*.md"')
264
- .option('--session-id <id>', 'Existing session ID to continue')
265
- .option('--session-dir <path>', 'Directory to store session files (defaults to DOT_AI_SESSION_DIR env var)')
266
- .option('--phase <phase>', 'Specific phase to run (scan, test, analyze, fix, done)', 'scan')
267
- .option('--section-id <id>', 'Section ID when submitting test results')
268
- .option('--results <text>', 'Test results to store (for client agent reporting back)')
269
- .option('--output <format>', 'Output format (json|yaml|table)', 'json')
270
- .action(async (options, command) => {
271
- // Get global options from parent command
272
- const globalOptions = command.parent?.opts() || {};
273
- this.processGlobalOptions(globalOptions);
274
- // Validate output format
275
- if (options.output && !['json', 'yaml', 'table'].includes(options.output)) {
276
- console.error('Error: Invalid output format. Supported: json, yaml, table');
277
- process.exit(1);
278
- }
279
- // Validate phase
280
- if (options.phase && !['scan', 'test', 'analyze', 'fix', 'done'].includes(options.phase)) {
281
- console.error('Error: Invalid phase. Supported: scan, test, analyze, fix, done');
282
- process.exit(1);
283
- }
284
- const result = await this.executeCommand('testDocs', options);
285
- this.outputResult(result, options.output || this.config.defaultOutput || 'json', this.config.outputFile);
286
- });
287
- // REMOVED: enhance command - moved to legacy reference
288
- // See src/legacy/tools/enhance-solution.ts for reference implementation
289
- }
290
- getCommands() {
291
- return ['dot-ai'];
292
- }
293
- getSubcommands() {
294
- return this.program.commands.map(cmd => cmd.name());
295
- }
296
- async getHelp() {
297
- const { name } = this.getPackageInfo();
298
- const basicHelp = this.program.helpInformation();
299
- const customHelp = `
300
-
301
- Installation:
302
- npm install -g ${name} Install globally
303
- npx ${name} <command> Run without installing
304
-
305
- Examples:
306
- npx ${name} recommend --intent "deploy my Node.js app"
307
- npx ${name} status --deployment my-app
308
- npx ${name} learn --pattern microservice
309
-
310
- For more help on specific commands, use:
311
- npx ${name} help <command>
312
- `;
313
- return basicHelp + customHelp;
314
- }
315
- async getCommandHelp(commandName) {
316
- const command = this.program.commands.find(cmd => cmd.name() === commandName);
317
- if (!command) {
318
- throw new Error(`Unknown command: ${commandName}`);
319
- }
320
- return command.helpInformation();
321
- }
322
- async parseArguments(args) {
323
- if (args.length === 0) {
324
- throw new Error('No command provided');
325
- }
326
- const commandName = args[0];
327
- const validCommands = this.getSubcommands();
328
- if (!validCommands.includes(commandName)) {
329
- throw new Error(`Unknown command: ${commandName}`);
330
- }
331
- // Validate options based on command
332
- const options = {};
333
- for (let i = 1; i < args.length; i += 2) {
334
- const option = args[i];
335
- const value = args[i + 1];
336
- if (!option.startsWith('--')) {
337
- throw new Error(`Invalid option format: ${option}`);
338
- }
339
- const optionName = option.substring(2);
340
- // Validate known options for each command
341
- const validOptions = this.getValidOptionsForCommand(commandName);
342
- if (!validOptions.includes(optionName)) {
343
- throw new Error(`Unknown option: ${option}`);
344
- }
345
- // Validate specific option values
346
- if (optionName === 'output' && value && !['json', 'yaml', 'table'].includes(value)) {
347
- throw new Error('Invalid output format. Supported: json, yaml, table');
348
- }
349
- options[optionName] = value || true;
350
- }
351
- // Check required options
352
- // (no required option checks needed for current commands)
353
- return {
354
- command: commandName,
355
- options
356
- };
357
- }
358
- getValidOptionsForCommand(command) {
359
- const commonOptions = ['output', 'verbose'];
360
- switch (command) {
361
- case 'discover':
362
- return [...commonOptions, 'cluster', 'remember'];
363
- case 'status':
364
- return [...commonOptions, 'deployment'];
365
- case 'learn':
366
- return [...commonOptions, 'pattern'];
367
- case 'recommend':
368
- return [...commonOptions, 'intent', 'session-dir'];
369
- case 'chooseSolution':
370
- return [...commonOptions, 'solution-id', 'session-dir'];
371
- case 'answerQuestion':
372
- return [...commonOptions, 'solution-id', 'session-dir', 'stage', 'answers', 'done'];
373
- case 'generateManifests':
374
- return [...commonOptions, 'solution-id', 'session-dir'];
375
- case 'deployManifests':
376
- return [...commonOptions, 'solution-id', 'session-dir', 'timeout'];
377
- case 'testDocs':
378
- return [...commonOptions, 'file', 'file-pattern', 'session-id', 'session-dir', 'phase', 'section-id', 'results'];
379
- // REMOVED: enhance command, deploy command
380
- default:
381
- return commonOptions;
382
- }
383
- }
384
- async executeCommand(command, options = {}) {
385
- try {
386
- // Only initialize DotAI for commands that need cluster access
387
- if (command !== 'chooseSolution' && command !== 'answerQuestion' && command !== 'generateManifests' && command !== 'testDocs') {
388
- await this.ensureDotAI().initialize();
389
- }
390
- switch (command) {
391
- case 'status':
392
- return await this.handleStatusCommand(options);
393
- case 'learn':
394
- return await this.handleLearnCommand(options);
395
- case 'recommend':
396
- return await this.handleRecommendCommand(options);
397
- case 'chooseSolution':
398
- return await this.handleChooseSolutionCommand(options);
399
- case 'answerQuestion':
400
- return await this.handleAnswerQuestionCommand(options);
401
- case 'generateManifests':
402
- return await this.handleGenerateManifestsCommand(options);
403
- case 'deployManifests':
404
- return await this.handleDeployManifestsCommand(options);
405
- case 'testDocs':
406
- return await this.handleTestDocsCommand(options);
407
- // REMOVED: enhance command, deploy command
408
- default:
409
- return {
410
- success: false,
411
- error: `Unknown command: ${command}`
412
- };
413
- }
414
- }
415
- catch (error) {
416
- return this.handleError(error, command);
417
- }
418
- }
419
- async handleStatusCommand(options) {
420
- try {
421
- const phase = this.ensureDotAI().workflow.getCurrentPhase();
422
- return {
423
- success: true,
424
- data: {
425
- workflowId: options.deployment,
426
- phase,
427
- status: 'active'
428
- }
429
- };
430
- }
431
- catch (error) {
432
- return {
433
- success: false,
434
- error: `Status check failed: ${error.message}`
435
- };
436
- }
437
- }
438
- async handleLearnCommand(options) {
439
- try {
440
- const recommendations = await this.ensureDotAI().memory.getRecommendations(options.pattern || 'deployment', {});
441
- return {
442
- success: true,
443
- data: {
444
- recommendations,
445
- patternType: options.pattern || 'deployment'
446
- }
447
- };
448
- }
449
- catch (error) {
450
- return {
451
- success: false,
452
- error: `Learning retrieval failed: ${error.message}`
453
- };
454
- }
455
- }
456
- async handleRecommendCommand(options) {
457
- try {
458
- // Show progress for long-running AI operations
459
- this.showProgress('🔍 Analyzing your intent and discovering cluster resources...');
460
- // Prepare arguments for the recommend tool including session directory
461
- const toolArgs = {
462
- intent: options.intent,
463
- sessionDir: options.sessionDir // This will be passed to our tool's getSessionDirectory function
464
- };
465
- this.showProgress('🤖 AI is analyzing resources and generating solutions...');
466
- // Execute the recommend tool directly
467
- const requestId = `cli_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
468
- const result = await (0, recommend_1.handleRecommendTool)(toolArgs, this.ensureDotAI(), this.logger, requestId);
469
- this.clearProgress();
470
- // Parse the tool result
471
- const responseData = JSON.parse(result.content[0].text);
472
- return {
473
- success: true,
474
- data: responseData
475
- };
476
- }
477
- catch (error) {
478
- // Give a moment for user to see progress before clearing
479
- await new Promise(resolve => setTimeout(resolve, 1000));
480
- this.clearProgress(); // Clear progress indicators on error
481
- return {
482
- success: false,
483
- error: `AI-powered recommendations failed: ${error.message}`
484
- };
485
- }
486
- }
487
- async handleChooseSolutionCommand(options) {
488
- try {
489
- // Show progress for file operations
490
- this.showProgress('📋 Loading solution and extracting questions...');
491
- // Prepare arguments for the chooseSolution tool
492
- const toolArgs = {
493
- solutionId: options.solutionId,
494
- sessionDir: options.sessionDir
495
- };
496
- // Execute the chooseSolution tool directly
497
- const requestId = `cli_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
498
- const result = await (0, choose_solution_1.handleChooseSolutionTool)(toolArgs, null, this.logger, requestId);
499
- this.clearProgress();
500
- // Parse the tool result
501
- const responseData = JSON.parse(result.content[0].text);
502
- return {
503
- success: true,
504
- data: responseData
505
- };
506
- }
507
- catch (error) {
508
- // Give a moment for user to see progress before clearing
509
- await new Promise(resolve => setTimeout(resolve, 1000));
510
- this.clearProgress(); // Clear progress indicators on error
511
- return {
512
- success: false,
513
- error: `Choose solution failed: ${error.message}`
514
- };
515
- }
516
- }
517
- async handleAnswerQuestionCommand(options) {
518
- try {
519
- // Show progress for file operations
520
- this.showProgress('📝 Processing answers and updating solution...');
521
- // Prepare arguments for the answerQuestion tool
522
- const toolArgs = {
523
- solutionId: options.solutionId,
524
- sessionDir: options.sessionDir,
525
- stage: options.stage,
526
- answers: options.answers,
527
- done: options.done || false
528
- };
529
- // Execute the answerQuestion tool directly
530
- const requestId = `cli_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
531
- const result = await (0, answer_question_1.handleAnswerQuestionTool)(toolArgs, null, this.logger, requestId);
532
- this.clearProgress();
533
- // Parse the tool result
534
- const responseData = JSON.parse(result.content[0].text);
535
- return {
536
- success: true,
537
- data: responseData
538
- };
539
- }
540
- catch (error) {
541
- // Give a moment for user to see progress before clearing
542
- await new Promise(resolve => setTimeout(resolve, 1000));
543
- this.clearProgress(); // Clear progress indicators on error
544
- return {
545
- success: false,
546
- error: `Answer question failed: ${error.message}`
547
- };
548
- }
549
- }
550
- async handleGenerateManifestsCommand(options) {
551
- try {
552
- // Show progress for manifest generation
553
- this.showProgress('🤖 Generating Kubernetes manifests with AI...');
554
- // Prepare arguments for the generateManifests tool
555
- const toolArgs = {
556
- solutionId: options.solutionId,
557
- sessionDir: options.sessionDir
558
- };
559
- // Execute the generateManifests tool directly
560
- const requestId = `cli_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
561
- const result = await (0, generate_manifests_1.handleGenerateManifestsTool)(toolArgs, this.dotAI, this.logger, requestId);
562
- this.clearProgress();
563
- // Parse the tool result
564
- const responseData = JSON.parse(result.content[0].text);
565
- return {
566
- success: true,
567
- data: responseData
568
- };
569
- }
570
- catch (error) {
571
- // Give a moment for user to see progress before clearing
572
- await new Promise(resolve => setTimeout(resolve, 1000));
573
- this.clearProgress(); // Clear progress indicators on error
574
- return {
575
- success: false,
576
- error: `Manifest generation failed: ${error.message}`
577
- };
578
- }
579
- }
580
- async handleDeployManifestsCommand(options) {
581
- try {
582
- // Show progress for deployment
583
- this.showProgress('🚀 Deploying Kubernetes manifests...');
584
- // Prepare arguments for the deployManifests tool
585
- const toolArgs = {
586
- solutionId: options.solutionId,
587
- timeout: parseInt(options.timeout) || 30
588
- };
589
- // Execute the deployManifests tool directly
590
- const requestId = `cli_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
591
- const result = await (0, deploy_manifests_1.handleDeployManifestsTool)(toolArgs, this.ensureDotAI(), this.logger, requestId);
592
- this.clearProgress();
593
- // Parse the tool result
594
- const responseData = JSON.parse(result.content[0].text);
595
- return {
596
- success: true,
597
- data: responseData
598
- };
599
- }
600
- catch (error) {
601
- this.clearProgress(); // Clear progress indicators on error
602
- return {
603
- success: false,
604
- error: `Manifest deployment failed: ${error.message}`
605
- };
606
- }
607
- }
608
- async handleTestDocsCommand(options) {
609
- try {
610
- // Show progress for documentation testing
611
- this.showProgress('📄 Analyzing documentation for testable items...');
612
- // Validate file exists if provided
613
- const fs = require('fs');
614
- if (options.file && !fs.existsSync(options.file)) {
615
- return {
616
- success: false,
617
- error: `Documentation file not found: ${options.file}`
618
- };
619
- }
620
- // Prepare arguments for the testDocs tool
621
- const toolArgs = {
622
- filePath: options.file,
623
- sessionId: options.sessionId,
624
- phase: options.phase,
625
- filePattern: options.filePattern,
626
- sessionDir: options.sessionDir,
627
- sectionId: options.sectionId,
628
- results: options.results
629
- };
630
- // Execute the testDocs tool directly
631
- const { handleTestDocsTool } = await Promise.resolve().then(() => __importStar(require('../tools/test-docs')));
632
- const requestId = `cli_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
633
- const result = await handleTestDocsTool(toolArgs, this.dotAI || null, this.logger, requestId);
634
- this.clearProgress();
635
- // Parse the tool result
636
- const responseData = JSON.parse(result.content[0].text);
637
- return {
638
- success: true,
639
- data: responseData
640
- };
641
- }
642
- catch (error) {
643
- this.clearProgress();
644
- return {
645
- success: false,
646
- error: `Documentation testing failed: ${error.message}`
647
- };
648
- }
649
- }
650
- // REMOVED: handleEnhanceCommand method - moved to legacy reference
651
- // See src/legacy/tools/enhance-solution.ts for reference implementation
652
- async continueWorkflow(workflowId, input) {
653
- try {
654
- await this.ensureDotAI().workflow.transitionTo('Validation');
655
- const claudeResponse = await this.ensureDotAI().claude.processUserInput(`Continue workflow ${workflowId} with responses: ${JSON.stringify(input.responses)}`);
656
- return {
657
- success: true,
658
- data: claudeResponse
659
- };
660
- }
661
- catch (error) {
662
- return {
663
- success: false,
664
- error: `Workflow continuation failed: ${error.message}`
665
- };
666
- }
667
- }
668
- formatOutput(result, format) {
669
- // Handle raw format for commands that need it
670
- const isRawFormat = result._rawFormat;
671
- if (isRawFormat) {
672
- switch (format) {
673
- case 'json':
674
- return JSON.stringify(result.data, null, 2);
675
- case 'yaml':
676
- return yaml.dump(result.data);
677
- case 'table':
678
- return this.formatAsTable({ success: true, data: result.data });
679
- default:
680
- return JSON.stringify(result.data, null, 2);
681
- }
682
- }
683
- // Standard CLI format for other commands
684
- switch (format) {
685
- case 'json':
686
- return JSON.stringify(result, null, 2);
687
- case 'yaml':
688
- return yaml.dump(result);
689
- case 'table':
690
- return this.formatAsTable(result);
691
- default:
692
- return JSON.stringify(result, null, 2);
693
- }
694
- }
695
- formatAsTable(result) {
696
- if (!result.success) {
697
- const table = new cli_table3_1.default({
698
- head: ['Status', 'Error'],
699
- colWidths: [20, 60]
700
- });
701
- table.push(['Failed', result.error || 'Unknown error']);
702
- return table.toString();
703
- }
704
- // Format data as table based on content
705
- if (result.data && (result.data.resources || result.data.crds)) {
706
- const table = new cli_table3_1.default({
707
- head: ['Resource Type', 'Category'],
708
- colWidths: [40, 20]
709
- });
710
- // Add discovered resources
711
- if (result.data.resources && result.data.resources.resources) {
712
- result.data.resources.resources.forEach((resource) => {
713
- const category = resource.group === '' ? 'Core' : resource.group;
714
- table.push([resource.kind, category]);
715
- });
716
- }
717
- // Add custom resources (CRDs) - handle both string and object formats
718
- if (result.data.crds && Array.isArray(result.data.crds)) {
719
- result.data.crds.forEach((crd) => {
720
- const crdName = typeof crd === 'string' ? crd : crd.name;
721
- table.push([crdName, 'Custom']);
722
- });
723
- }
724
- return table.toString();
725
- }
726
- // Generic table format
727
- const table = new cli_table3_1.default({
728
- head: ['Property', 'Value'],
729
- colWidths: [30, 50]
730
- });
731
- if (result.data) {
732
- Object.entries(result.data).forEach(([key, value]) => {
733
- table.push([key, JSON.stringify(value)]);
734
- });
735
- }
736
- return table.toString();
737
- }
738
- outputResult(result, format, outputFile) {
739
- const output = this.formatOutput(result, format);
740
- if (outputFile) {
741
- // Write clean output to file
742
- const fs = require('fs');
743
- const path = require('path');
744
- // Ensure directory exists
745
- const dir = path.dirname(outputFile);
746
- if (!fs.existsSync(dir)) {
747
- fs.mkdirSync(dir, { recursive: true });
748
- }
749
- fs.writeFileSync(outputFile, output);
750
- }
751
- else {
752
- // Write to stdout
753
- process.stdout.write(`${output}\n`);
754
- }
755
- if (!result.success) {
756
- process.exit(1);
757
- }
758
- }
759
- /**
760
- * Process global options and update config
761
- */
762
- processGlobalOptions(options) {
763
- if (options.verbose !== undefined) {
764
- this.config.verboseMode = options.verbose;
765
- }
766
- if (options.outputFile !== undefined) {
767
- this.config.outputFile = options.outputFile;
768
- }
769
- if (options.quiet !== undefined) {
770
- this.config.quietMode = options.quiet;
771
- }
772
- }
773
- handleError(error, _command) {
774
- this.clearProgress(); // Clear any progress indicators on error
775
- let errorMessage = error.message;
776
- // Provide helpful error messages for common issues
777
- if (errorMessage.includes('ENOTFOUND') || errorMessage.includes('connection')) {
778
- errorMessage = 'Cannot connect to Kubernetes cluster. Check your kubeconfig and cluster status.';
779
- }
780
- else if (errorMessage.includes('Connection failed')) {
781
- errorMessage = `Failed to initialize DevOps AI Toolkit: ${errorMessage}`;
782
- }
783
- return {
784
- success: false,
785
- error: errorMessage
786
- };
787
- }
788
- /**
789
- * Show progress message to user during long-running operations
790
- */
791
- showProgress(message) {
792
- // Only show progress if output is going to console (not when piped or in JSON mode)
793
- if (process.stdout.isTTY) {
794
- process.stderr.write(`\r\x1b[K${message}`);
795
- }
796
- }
797
- /**
798
- * Clear progress indicators
799
- */
800
- clearProgress() {
801
- if (process.stdout.isTTY) {
802
- process.stderr.write('\r\x1b[K');
803
- }
804
- }
805
- /**
806
- * Find best solutions with detailed progress feedback
807
- */
808
- async findBestSolutionsWithProgress(recommender, intent, discoverResourcesFn, explainResourceFn) {
809
- this.showProgress('🤖 AI is analyzing your intent...');
810
- // Start a timer to show elapsed time
811
- const startTime = Date.now();
812
- const progressInterval = setInterval(() => {
813
- const elapsed = Math.floor((Date.now() - startTime) / 1000);
814
- this.showProgress(`🤖 AI analysis in progress... (${elapsed}s)`);
815
- }, 3000);
816
- try {
817
- // The ResourceRecommender handles the three phases internally:
818
- // 1. Resource discovery and selection
819
- // 2. Schema fetching and ranking
820
- // 3. Question generation
821
- const solutions = await recommender.findBestSolutions(intent, discoverResourcesFn, explainResourceFn);
822
- clearInterval(progressInterval);
823
- return solutions;
824
- }
825
- catch (error) {
826
- clearInterval(progressInterval);
827
- throw error;
828
- }
829
- }
830
- // CLI entry point
831
- async run(args = process.argv) {
832
- try {
833
- await this.program.parseAsync(args);
834
- }
835
- catch (error) {
836
- const result = this.handleError(error, 'general');
837
- this.outputResult(result, 'json');
838
- process.exit(1);
839
- }
840
- }
841
- }
842
- exports.CliInterface = CliInterface;
843
- // Export for CLI entry point
844
- exports.default = CliInterface;