@vfarcic/dot-ai 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/.claude/commands/context-load.md +11 -0
  2. package/.claude/commands/context-save.md +16 -0
  3. package/.claude/commands/prd-done.md +115 -0
  4. package/.claude/commands/prd-get.md +25 -0
  5. package/.claude/commands/prd-start.md +87 -0
  6. package/.claude/commands/task-done.md +77 -0
  7. package/.claude/commands/tests-reminder.md +32 -0
  8. package/.claude/settings.local.json +20 -0
  9. package/.eslintrc.json +25 -0
  10. package/.github/workflows/ci.yml +170 -0
  11. package/.prettierrc.json +10 -0
  12. package/.teller.yml +8 -0
  13. package/CLAUDE.md +162 -0
  14. package/assets/images/logo.png +0 -0
  15. package/bin/dot-ai.ts +47 -0
  16. package/destroy.sh +45 -0
  17. package/devbox.json +13 -0
  18. package/devbox.lock +225 -0
  19. package/docs/API.md +449 -0
  20. package/docs/CONTEXT.md +49 -0
  21. package/docs/DEVELOPMENT.md +203 -0
  22. package/docs/NEXT_STEPS.md +97 -0
  23. package/docs/STAGE_BASED_API.md +97 -0
  24. package/docs/cli-guide.md +798 -0
  25. package/docs/design.md +750 -0
  26. package/docs/discovery-engine.md +515 -0
  27. package/docs/error-handling.md +429 -0
  28. package/docs/function-registration.md +157 -0
  29. package/docs/mcp-guide.md +416 -0
  30. package/package.json +2 -121
  31. package/renovate.json +51 -0
  32. package/setup.sh +111 -0
  33. package/{dist/cli.js → src/cli.ts} +26 -19
  34. package/src/core/claude.ts +280 -0
  35. package/src/core/deploy-operation.ts +127 -0
  36. package/src/core/discovery.ts +900 -0
  37. package/src/core/error-handling.ts +562 -0
  38. package/src/core/index.ts +143 -0
  39. package/src/core/kubernetes-utils.ts +218 -0
  40. package/src/core/memory.ts +148 -0
  41. package/src/core/schema.ts +830 -0
  42. package/src/core/session-utils.ts +97 -0
  43. package/src/core/workflow.ts +234 -0
  44. package/src/index.ts +18 -0
  45. package/src/interfaces/cli.ts +872 -0
  46. package/src/interfaces/mcp.ts +183 -0
  47. package/src/mcp/server.ts +131 -0
  48. package/src/tools/answer-question.ts +807 -0
  49. package/src/tools/choose-solution.ts +169 -0
  50. package/src/tools/deploy-manifests.ts +94 -0
  51. package/src/tools/generate-manifests.ts +502 -0
  52. package/src/tools/index.ts +41 -0
  53. package/src/tools/recommend.ts +370 -0
  54. package/tests/__mocks__/@kubernetes/client-node.ts +106 -0
  55. package/tests/build-system.test.ts +345 -0
  56. package/tests/configuration.test.ts +226 -0
  57. package/tests/core/deploy-operation.test.ts +38 -0
  58. package/tests/core/discovery.test.ts +1648 -0
  59. package/tests/core/error-handling.test.ts +632 -0
  60. package/tests/core/schema.test.ts +1658 -0
  61. package/tests/core/session-utils.test.ts +245 -0
  62. package/tests/core.test.ts +439 -0
  63. package/tests/fixtures/configmap-no-labels.yaml +8 -0
  64. package/tests/fixtures/crossplane-app-configuration.yaml +6 -0
  65. package/tests/fixtures/crossplane-providers.yaml +45 -0
  66. package/tests/fixtures/crossplane-rbac.yaml +48 -0
  67. package/tests/fixtures/invalid-configmap.yaml +8 -0
  68. package/tests/fixtures/invalid-deployment.yaml +17 -0
  69. package/tests/fixtures/test-deployment.yaml +28 -0
  70. package/tests/fixtures/valid-configmap.yaml +15 -0
  71. package/tests/infrastructure.test.ts +426 -0
  72. package/tests/interfaces/cli.test.ts +1036 -0
  73. package/tests/interfaces/mcp.test.ts +139 -0
  74. package/tests/kubernetes-utils.test.ts +200 -0
  75. package/tests/mcp/server.test.ts +126 -0
  76. package/tests/setup.ts +31 -0
  77. package/tests/tools/answer-question.test.ts +367 -0
  78. package/tests/tools/choose-solution.test.ts +481 -0
  79. package/tests/tools/deploy-manifests.test.ts +185 -0
  80. package/tests/tools/generate-manifests.test.ts +441 -0
  81. package/tests/tools/index.test.ts +111 -0
  82. package/tests/tools/recommend.test.ts +180 -0
  83. package/tsconfig.json +34 -0
  84. package/dist/cli.d.ts +0 -3
  85. package/dist/cli.d.ts.map +0 -1
  86. package/dist/core/claude.d.ts +0 -42
  87. package/dist/core/claude.d.ts.map +0 -1
  88. package/dist/core/claude.js +0 -229
  89. package/dist/core/deploy-operation.d.ts +0 -38
  90. package/dist/core/deploy-operation.d.ts.map +0 -1
  91. package/dist/core/deploy-operation.js +0 -101
  92. package/dist/core/discovery.d.ts +0 -162
  93. package/dist/core/discovery.d.ts.map +0 -1
  94. package/dist/core/discovery.js +0 -758
  95. package/dist/core/error-handling.d.ts +0 -167
  96. package/dist/core/error-handling.d.ts.map +0 -1
  97. package/dist/core/error-handling.js +0 -399
  98. package/dist/core/index.d.ts +0 -42
  99. package/dist/core/index.d.ts.map +0 -1
  100. package/dist/core/index.js +0 -123
  101. package/dist/core/kubernetes-utils.d.ts +0 -38
  102. package/dist/core/kubernetes-utils.d.ts.map +0 -1
  103. package/dist/core/kubernetes-utils.js +0 -177
  104. package/dist/core/memory.d.ts +0 -45
  105. package/dist/core/memory.d.ts.map +0 -1
  106. package/dist/core/memory.js +0 -113
  107. package/dist/core/schema.d.ts +0 -187
  108. package/dist/core/schema.d.ts.map +0 -1
  109. package/dist/core/schema.js +0 -655
  110. package/dist/core/session-utils.d.ts +0 -29
  111. package/dist/core/session-utils.d.ts.map +0 -1
  112. package/dist/core/session-utils.js +0 -121
  113. package/dist/core/workflow.d.ts +0 -70
  114. package/dist/core/workflow.d.ts.map +0 -1
  115. package/dist/core/workflow.js +0 -161
  116. package/dist/index.d.ts +0 -15
  117. package/dist/index.d.ts.map +0 -1
  118. package/dist/index.js +0 -32
  119. package/dist/interfaces/cli.d.ts +0 -74
  120. package/dist/interfaces/cli.d.ts.map +0 -1
  121. package/dist/interfaces/cli.js +0 -769
  122. package/dist/interfaces/mcp.d.ts +0 -30
  123. package/dist/interfaces/mcp.d.ts.map +0 -1
  124. package/dist/interfaces/mcp.js +0 -105
  125. package/dist/mcp/server.d.ts +0 -9
  126. package/dist/mcp/server.d.ts.map +0 -1
  127. package/dist/mcp/server.js +0 -151
  128. package/dist/tools/answer-question.d.ts +0 -27
  129. package/dist/tools/answer-question.d.ts.map +0 -1
  130. package/dist/tools/answer-question.js +0 -696
  131. package/dist/tools/choose-solution.d.ts +0 -23
  132. package/dist/tools/choose-solution.d.ts.map +0 -1
  133. package/dist/tools/choose-solution.js +0 -171
  134. package/dist/tools/deploy-manifests.d.ts +0 -25
  135. package/dist/tools/deploy-manifests.d.ts.map +0 -1
  136. package/dist/tools/deploy-manifests.js +0 -74
  137. package/dist/tools/generate-manifests.d.ts +0 -23
  138. package/dist/tools/generate-manifests.d.ts.map +0 -1
  139. package/dist/tools/generate-manifests.js +0 -424
  140. package/dist/tools/index.d.ts +0 -11
  141. package/dist/tools/index.d.ts.map +0 -1
  142. package/dist/tools/index.js +0 -34
  143. package/dist/tools/recommend.d.ts +0 -23
  144. package/dist/tools/recommend.d.ts.map +0 -1
  145. package/dist/tools/recommend.js +0 -332
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Choose Solution Tool - Select a solution and return its questions
3
+ */
4
+
5
+ import { z } from 'zod';
6
+ import { ErrorHandler, ErrorCategory, ErrorSeverity } from '../core/error-handling';
7
+ import { DotAI } from '../core/index';
8
+ import { Logger } from '../core/error-handling';
9
+ import * as fs from 'fs';
10
+ import * as path from 'path';
11
+ import { getAndValidateSessionDirectory } from '../core/session-utils';
12
+
13
+ // Tool metadata for direct MCP registration
14
+ export const CHOOSESOLUTION_TOOL_NAME = 'chooseSolution';
15
+ export const CHOOSESOLUTION_TOOL_DESCRIPTION = 'Select a solution by ID and return its questions for configuration';
16
+
17
+ // Zod schema for MCP registration
18
+ export const CHOOSESOLUTION_TOOL_INPUT_SCHEMA = {
19
+ solutionId: z.string().regex(/^sol_[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}_[a-f0-9]+$/).describe('The solution ID to choose (e.g., sol_2025-07-01T154349_1e1e242592ff)')
20
+ };
21
+
22
+
23
+
24
+ /**
25
+ * Load solution file by ID
26
+ */
27
+ function loadSolutionFile(solutionId: string, sessionDir: string): any {
28
+ const solutionPath = path.join(sessionDir, `${solutionId}.json`);
29
+
30
+ if (!fs.existsSync(solutionPath)) {
31
+ throw new Error(`Solution file not found: ${solutionPath}. Available files: ${fs.readdirSync(sessionDir).filter(f => f.endsWith('.json')).join(', ')}`);
32
+ }
33
+
34
+ try {
35
+ const content = fs.readFileSync(solutionPath, 'utf8');
36
+ const solution = JSON.parse(content);
37
+
38
+ // Validate solution structure
39
+ if (!solution.solutionId || !solution.questions) {
40
+ throw new Error(`Invalid solution file structure: ${solutionId}. Missing required fields: solutionId or questions`);
41
+ }
42
+
43
+ return solution;
44
+ } catch (error) {
45
+ if (error instanceof SyntaxError) {
46
+ throw new Error(`Invalid JSON in solution file: ${solutionId}. ${error.message}`);
47
+ }
48
+ throw error;
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Direct MCP tool handler for chooseSolution functionality
54
+ */
55
+ export async function handleChooseSolutionTool(
56
+ args: { solutionId: string },
57
+ dotAI: DotAI,
58
+ logger: Logger,
59
+ requestId: string
60
+ ): Promise<{ content: { type: 'text'; text: string }[] }> {
61
+ return await ErrorHandler.withErrorHandling(
62
+ async () => {
63
+ logger.debug('Handling chooseSolution request', { requestId, solutionId: args?.solutionId });
64
+
65
+ // Input validation is handled automatically by MCP SDK with Zod schema
66
+ // args are already validated and typed when we reach this point
67
+
68
+ // Get session directory from environment
69
+ let sessionDir: string;
70
+ try {
71
+ sessionDir = getAndValidateSessionDirectory(args, false); // requireWrite=false
72
+ logger.debug('Session directory resolved and validated', { sessionDir });
73
+ } catch (error) {
74
+ throw ErrorHandler.createError(
75
+ ErrorCategory.VALIDATION,
76
+ ErrorSeverity.HIGH,
77
+ error instanceof Error ? error.message : 'Session directory validation failed',
78
+ {
79
+ operation: 'session_directory_validation',
80
+ component: 'ChooseSolutionTool',
81
+ requestId,
82
+ suggestedActions: [
83
+ 'Ensure session directory exists and is readable',
84
+ 'Check directory permissions',
85
+ 'Verify the directory path is correct',
86
+ 'Verify DOT_AI_SESSION_DIR environment variable is correctly set'
87
+ ]
88
+ }
89
+ );
90
+ }
91
+
92
+ // Load solution file
93
+ let solution: any;
94
+ try {
95
+ solution = loadSolutionFile(args.solutionId, sessionDir);
96
+ logger.debug('Solution file loaded successfully', {
97
+ solutionId: args.solutionId,
98
+ hasQuestions: !!solution.questions,
99
+ questionCategories: {
100
+ required: solution.questions?.required?.length || 0,
101
+ basic: solution.questions?.basic?.length || 0,
102
+ advanced: solution.questions?.advanced?.length || 0,
103
+ hasOpen: !!solution.questions?.open
104
+ }
105
+ });
106
+ } catch (error) {
107
+ throw ErrorHandler.createError(
108
+ ErrorCategory.STORAGE,
109
+ ErrorSeverity.HIGH,
110
+ error instanceof Error ? error.message : 'Failed to load solution file',
111
+ {
112
+ operation: 'solution_file_load',
113
+ component: 'ChooseSolutionTool',
114
+ requestId,
115
+ input: { solutionId: args.solutionId, sessionDir },
116
+ suggestedActions: [
117
+ 'Check that the solution ID is correct',
118
+ 'Verify the solution file exists in the session directory',
119
+ 'Ensure the solution was created by a recent recommend tool call',
120
+ 'List available solution files in the session directory'
121
+ ]
122
+ }
123
+ );
124
+ }
125
+
126
+ // Prepare response with solution details and questions
127
+ const response = {
128
+ status: 'stage_questions',
129
+ solutionId: solution.solutionId,
130
+ currentStage: 'required',
131
+ questions: solution.questions.required || [],
132
+ nextStage: 'basic',
133
+ message: 'Please provide the required configuration for your application.',
134
+ nextAction: 'answerQuestion',
135
+ guidance: 'Answer questions in this stage or skip to proceed to the next stage. Do NOT try to generate manifests yet.',
136
+ timestamp: new Date().toISOString()
137
+ };
138
+
139
+ logger.info('Choose solution completed successfully', {
140
+ solutionId: args.solutionId,
141
+ sessionDir,
142
+ questionCategories: {
143
+ required: solution.questions.required?.length || 0,
144
+ basic: solution.questions.basic?.length || 0,
145
+ advanced: solution.questions.advanced?.length || 0,
146
+ hasOpen: !!solution.questions.open
147
+ },
148
+ totalQuestions: (solution.questions.required?.length || 0) +
149
+ (solution.questions.basic?.length || 0) +
150
+ (solution.questions.advanced?.length || 0) +
151
+ (solution.questions.open ? 1 : 0)
152
+ });
153
+
154
+ return {
155
+ content: [{
156
+ type: 'text' as const,
157
+ text: JSON.stringify(response, null, 2)
158
+ }]
159
+ };
160
+ },
161
+ {
162
+ operation: 'choose_solution',
163
+ component: 'ChooseSolutionTool',
164
+ requestId,
165
+ input: args
166
+ }
167
+ );
168
+ }
169
+
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Deploy Manifests Tool - Apply Kubernetes manifests with readiness checking
3
+ */
4
+
5
+ import { z } from 'zod';
6
+ import { ErrorHandler } from '../core/error-handling';
7
+ import { DeployOperation } from '../core/deploy-operation';
8
+ import { DotAI } from '../core/index';
9
+ import { Logger } from '../core/error-handling';
10
+
11
+ // Tool metadata for direct MCP registration
12
+ export const DEPLOYMANIFESTS_TOOL_NAME = 'deployManifests';
13
+ export const DEPLOYMANIFESTS_TOOL_DESCRIPTION = 'Deploy Kubernetes manifests from generated solution with kubectl apply --wait';
14
+
15
+ // Zod schema for MCP registration
16
+ export const DEPLOYMANIFESTS_TOOL_INPUT_SCHEMA = {
17
+ solutionId: z.string().regex(/^sol_[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}_[a-f0-9]+$/).describe('Solution ID to deploy (e.g., sol_2025-07-01T154349_1e1e242592ff)'),
18
+ timeout: z.number().min(1).max(600).optional().describe('Deployment timeout in seconds (default: 30)')
19
+ };
20
+
21
+
22
+ /**
23
+ * Direct MCP tool handler for deployManifests functionality
24
+ */
25
+ export async function handleDeployManifestsTool(
26
+ args: { solutionId: string; timeout?: number },
27
+ dotAI: DotAI,
28
+ logger: Logger,
29
+ requestId: string
30
+ ): Promise<{ content: { type: 'text'; text: string }[] }> {
31
+ return await ErrorHandler.withErrorHandling(
32
+ async () => {
33
+ logger.debug('Handling deployManifests request', {
34
+ requestId,
35
+ solutionId: args?.solutionId,
36
+ timeout: args?.timeout
37
+ });
38
+
39
+ // Input validation is handled automatically by MCP SDK with Zod schema
40
+ // args are already validated and typed when we reach this point
41
+
42
+ const deployOp = new DeployOperation();
43
+
44
+ const deployOptions = {
45
+ solutionId: args.solutionId,
46
+ timeout: args.timeout || 30
47
+ };
48
+
49
+ logger.info('Starting deployment operation', {
50
+ solutionId: args.solutionId,
51
+ timeout: deployOptions.timeout,
52
+ requestId
53
+ });
54
+
55
+ const result = await deployOp.deploy(deployOptions);
56
+
57
+ logger.info('Deployment operation completed', {
58
+ success: result.success,
59
+ solutionId: result.solutionId,
60
+ manifestPath: result.manifestPath,
61
+ readinessTimeout: result.readinessTimeout,
62
+ requestId
63
+ });
64
+
65
+ // Prepare response with deployment status
66
+ const response = {
67
+ success: result.success,
68
+ solutionId: result.solutionId,
69
+ manifestPath: result.manifestPath,
70
+ readinessTimeout: result.readinessTimeout,
71
+ message: result.message,
72
+ kubectlOutput: result.kubectlOutput,
73
+ // Additional deployment status info
74
+ deploymentComplete: result.success && !result.readinessTimeout,
75
+ requiresStatusCheck: result.success && result.readinessTimeout,
76
+ timestamp: new Date().toISOString()
77
+ };
78
+
79
+ return {
80
+ content: [{
81
+ type: 'text' as const,
82
+ text: JSON.stringify(response, null, 2)
83
+ }]
84
+ };
85
+ },
86
+ {
87
+ operation: 'deploy_manifests',
88
+ component: 'DeployManifestsTool',
89
+ requestId,
90
+ input: args
91
+ }
92
+ );
93
+ }
94
+