@hailer/mcp 0.1.17 → 0.2.2

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 (200) hide show
  1. package/dist/app.js +27 -20
  2. package/dist/core.d.ts +33 -9
  3. package/dist/core.js +279 -147
  4. package/dist/mcp/UserContextCache.js +18 -0
  5. package/dist/mcp/hailer-clients.d.ts +9 -1
  6. package/dist/mcp/hailer-clients.js +13 -3
  7. package/dist/mcp/signal-handler.js +1 -1
  8. package/dist/mcp/tool-registry.d.ts +3 -1
  9. package/dist/mcp/tool-registry.js +4 -1
  10. package/dist/mcp/tools/activity.js +43 -34
  11. package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
  12. package/dist/mcp/tools/bot-config/constants.js +94 -0
  13. package/dist/mcp/tools/{bot-config.d.ts → bot-config/core.d.ts} +6 -6
  14. package/dist/mcp/tools/{bot-config.js → bot-config/core.js} +15 -15
  15. package/dist/mcp/tools/bot-config/index.d.ts +10 -0
  16. package/dist/mcp/tools/bot-config/index.js +59 -0
  17. package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
  18. package/dist/mcp/tools/bot-config/tools.js +15 -0
  19. package/dist/mcp/tools/bot-config/types.d.ts +50 -0
  20. package/dist/mcp/tools/bot-config/types.js +6 -0
  21. package/dist/mcp/tools/bug-fixer-tools.d.ts +21 -0
  22. package/dist/mcp/tools/{giuseppe-tools.js → bug-fixer-tools.js} +61 -61
  23. package/dist/mcp/tools/user.js +10 -29
  24. package/dist/mcp/tools/workflow.js +36 -2
  25. package/dist/mcp/utils/data-transformers.d.ts +0 -8
  26. package/dist/mcp/utils/data-transformers.js +0 -28
  27. package/dist/mcp/utils/index.d.ts +4 -1
  28. package/dist/mcp/utils/index.js +17 -3
  29. package/dist/mcp/utils/pagination.d.ts +40 -0
  30. package/dist/mcp/utils/pagination.js +55 -0
  31. package/dist/mcp/utils/response-builder.d.ts +53 -0
  32. package/dist/mcp/utils/response-builder.js +110 -0
  33. package/dist/mcp/utils/tool-helpers.d.ts +0 -8
  34. package/dist/mcp/utils/tool-helpers.js +0 -24
  35. package/dist/mcp/utils/types.d.ts +1 -33
  36. package/dist/mcp-server.d.ts +2 -2
  37. package/dist/mcp-server.js +161 -139
  38. package/package.json +1 -1
  39. package/REFACTOR_STATUS.md +0 -127
  40. package/dist/agents/bot-manager.d.ts +0 -48
  41. package/dist/agents/bot-manager.js +0 -254
  42. package/dist/agents/factory.d.ts +0 -150
  43. package/dist/agents/factory.js +0 -650
  44. package/dist/agents/giuseppe/ai.d.ts +0 -83
  45. package/dist/agents/giuseppe/ai.js +0 -466
  46. package/dist/agents/giuseppe/bot.d.ts +0 -110
  47. package/dist/agents/giuseppe/bot.js +0 -780
  48. package/dist/agents/giuseppe/config.d.ts +0 -25
  49. package/dist/agents/giuseppe/config.js +0 -227
  50. package/dist/agents/giuseppe/files.d.ts +0 -52
  51. package/dist/agents/giuseppe/files.js +0 -338
  52. package/dist/agents/giuseppe/git.d.ts +0 -48
  53. package/dist/agents/giuseppe/git.js +0 -298
  54. package/dist/agents/giuseppe/index.d.ts +0 -97
  55. package/dist/agents/giuseppe/index.js +0 -258
  56. package/dist/agents/giuseppe/lsp.d.ts +0 -113
  57. package/dist/agents/giuseppe/lsp.js +0 -485
  58. package/dist/agents/giuseppe/monitor.d.ts +0 -118
  59. package/dist/agents/giuseppe/monitor.js +0 -621
  60. package/dist/agents/giuseppe/prompt.d.ts +0 -5
  61. package/dist/agents/giuseppe/prompt.js +0 -94
  62. package/dist/agents/giuseppe/registries/pending-classification.d.ts +0 -28
  63. package/dist/agents/giuseppe/registries/pending-classification.js +0 -50
  64. package/dist/agents/giuseppe/registries/pending-fix.d.ts +0 -30
  65. package/dist/agents/giuseppe/registries/pending-fix.js +0 -42
  66. package/dist/agents/giuseppe/registries/pending.d.ts +0 -27
  67. package/dist/agents/giuseppe/registries/pending.js +0 -49
  68. package/dist/agents/giuseppe/specialist.d.ts +0 -47
  69. package/dist/agents/giuseppe/specialist.js +0 -237
  70. package/dist/agents/giuseppe/types.d.ts +0 -123
  71. package/dist/agents/giuseppe/types.js +0 -9
  72. package/dist/agents/hailer-expert/index.d.ts +0 -8
  73. package/dist/agents/hailer-expert/index.js +0 -14
  74. package/dist/agents/hal/daemon.d.ts +0 -142
  75. package/dist/agents/hal/daemon.js +0 -1103
  76. package/dist/agents/hal/definitions.d.ts +0 -55
  77. package/dist/agents/hal/definitions.js +0 -263
  78. package/dist/agents/hal/index.d.ts +0 -3
  79. package/dist/agents/hal/index.js +0 -8
  80. package/dist/agents/index.d.ts +0 -18
  81. package/dist/agents/index.js +0 -48
  82. package/dist/agents/shared/base.d.ts +0 -216
  83. package/dist/agents/shared/base.js +0 -846
  84. package/dist/agents/shared/services/agent-registry.d.ts +0 -107
  85. package/dist/agents/shared/services/agent-registry.js +0 -629
  86. package/dist/agents/shared/services/conversation-manager.d.ts +0 -50
  87. package/dist/agents/shared/services/conversation-manager.js +0 -136
  88. package/dist/agents/shared/services/mcp-client.d.ts +0 -56
  89. package/dist/agents/shared/services/mcp-client.js +0 -124
  90. package/dist/agents/shared/services/message-classifier.d.ts +0 -37
  91. package/dist/agents/shared/services/message-classifier.js +0 -187
  92. package/dist/agents/shared/services/message-formatter.d.ts +0 -89
  93. package/dist/agents/shared/services/message-formatter.js +0 -371
  94. package/dist/agents/shared/services/session-logger.d.ts +0 -106
  95. package/dist/agents/shared/services/session-logger.js +0 -446
  96. package/dist/agents/shared/services/tool-executor.d.ts +0 -41
  97. package/dist/agents/shared/services/tool-executor.js +0 -169
  98. package/dist/agents/shared/services/workspace-schema-cache.d.ts +0 -125
  99. package/dist/agents/shared/services/workspace-schema-cache.js +0 -578
  100. package/dist/agents/shared/specialist.d.ts +0 -91
  101. package/dist/agents/shared/specialist.js +0 -399
  102. package/dist/agents/shared/tool-schema-loader.d.ts +0 -62
  103. package/dist/agents/shared/tool-schema-loader.js +0 -232
  104. package/dist/agents/shared/types.d.ts +0 -327
  105. package/dist/agents/shared/types.js +0 -121
  106. package/dist/client/agents/base.d.ts +0 -207
  107. package/dist/client/agents/base.js +0 -744
  108. package/dist/client/agents/definitions.d.ts +0 -53
  109. package/dist/client/agents/definitions.js +0 -263
  110. package/dist/client/agents/orchestrator.d.ts +0 -141
  111. package/dist/client/agents/orchestrator.js +0 -1062
  112. package/dist/client/agents/specialist.d.ts +0 -86
  113. package/dist/client/agents/specialist.js +0 -340
  114. package/dist/client/bot-entrypoint.d.ts +0 -7
  115. package/dist/client/bot-entrypoint.js +0 -103
  116. package/dist/client/bot-manager.d.ts +0 -44
  117. package/dist/client/bot-manager.js +0 -173
  118. package/dist/client/bot-runner.d.ts +0 -35
  119. package/dist/client/bot-runner.js +0 -188
  120. package/dist/client/chat-agent-daemon.d.ts +0 -464
  121. package/dist/client/chat-agent-daemon.js +0 -1774
  122. package/dist/client/daemon-factory.d.ts +0 -106
  123. package/dist/client/daemon-factory.js +0 -301
  124. package/dist/client/factory.d.ts +0 -111
  125. package/dist/client/factory.js +0 -314
  126. package/dist/client/index.d.ts +0 -17
  127. package/dist/client/index.js +0 -38
  128. package/dist/client/multi-bot-manager.d.ts +0 -42
  129. package/dist/client/multi-bot-manager.js +0 -161
  130. package/dist/client/orchestrator-daemon.d.ts +0 -87
  131. package/dist/client/orchestrator-daemon.js +0 -444
  132. package/dist/client/server.d.ts +0 -8
  133. package/dist/client/server.js +0 -251
  134. package/dist/client/services/agent-registry.d.ts +0 -108
  135. package/dist/client/services/agent-registry.js +0 -630
  136. package/dist/client/services/conversation-manager.d.ts +0 -50
  137. package/dist/client/services/conversation-manager.js +0 -136
  138. package/dist/client/services/mcp-client.d.ts +0 -48
  139. package/dist/client/services/mcp-client.js +0 -105
  140. package/dist/client/services/message-classifier.d.ts +0 -37
  141. package/dist/client/services/message-classifier.js +0 -187
  142. package/dist/client/services/message-formatter.d.ts +0 -84
  143. package/dist/client/services/message-formatter.js +0 -353
  144. package/dist/client/services/session-logger.d.ts +0 -106
  145. package/dist/client/services/session-logger.js +0 -446
  146. package/dist/client/services/tool-executor.d.ts +0 -41
  147. package/dist/client/services/tool-executor.js +0 -169
  148. package/dist/client/services/workspace-schema-cache.d.ts +0 -149
  149. package/dist/client/services/workspace-schema-cache.js +0 -732
  150. package/dist/client/specialist-daemon.d.ts +0 -77
  151. package/dist/client/specialist-daemon.js +0 -197
  152. package/dist/client/specialists.d.ts +0 -53
  153. package/dist/client/specialists.js +0 -178
  154. package/dist/client/tool-schema-loader.d.ts +0 -62
  155. package/dist/client/tool-schema-loader.js +0 -232
  156. package/dist/client/types.d.ts +0 -327
  157. package/dist/client/types.js +0 -121
  158. package/dist/commands/seed-config.d.ts +0 -9
  159. package/dist/commands/seed-config.js +0 -372
  160. package/dist/lib/context-manager.d.ts +0 -111
  161. package/dist/lib/context-manager.js +0 -431
  162. package/dist/lib/prompt-length-manager.d.ts +0 -81
  163. package/dist/lib/prompt-length-manager.js +0 -457
  164. package/dist/mcp/tools/giuseppe-tools.d.ts +0 -21
  165. package/dist/modules/bug-reports/bug-config.d.ts +0 -25
  166. package/dist/modules/bug-reports/bug-config.js +0 -187
  167. package/dist/modules/bug-reports/bug-monitor.d.ts +0 -108
  168. package/dist/modules/bug-reports/bug-monitor.js +0 -510
  169. package/dist/modules/bug-reports/giuseppe-agent.d.ts +0 -58
  170. package/dist/modules/bug-reports/giuseppe-agent.js +0 -467
  171. package/dist/modules/bug-reports/giuseppe-ai.d.ts +0 -83
  172. package/dist/modules/bug-reports/giuseppe-ai.js +0 -466
  173. package/dist/modules/bug-reports/giuseppe-bot.d.ts +0 -110
  174. package/dist/modules/bug-reports/giuseppe-bot.js +0 -804
  175. package/dist/modules/bug-reports/giuseppe-daemon.d.ts +0 -80
  176. package/dist/modules/bug-reports/giuseppe-daemon.js +0 -617
  177. package/dist/modules/bug-reports/giuseppe-files.d.ts +0 -64
  178. package/dist/modules/bug-reports/giuseppe-files.js +0 -375
  179. package/dist/modules/bug-reports/giuseppe-git.d.ts +0 -48
  180. package/dist/modules/bug-reports/giuseppe-git.js +0 -298
  181. package/dist/modules/bug-reports/giuseppe-lsp.d.ts +0 -113
  182. package/dist/modules/bug-reports/giuseppe-lsp.js +0 -485
  183. package/dist/modules/bug-reports/giuseppe-prompt.d.ts +0 -5
  184. package/dist/modules/bug-reports/giuseppe-prompt.js +0 -94
  185. package/dist/modules/bug-reports/index.d.ts +0 -77
  186. package/dist/modules/bug-reports/index.js +0 -215
  187. package/dist/modules/bug-reports/pending-classification-registry.d.ts +0 -28
  188. package/dist/modules/bug-reports/pending-classification-registry.js +0 -50
  189. package/dist/modules/bug-reports/pending-fix-registry.d.ts +0 -30
  190. package/dist/modules/bug-reports/pending-fix-registry.js +0 -42
  191. package/dist/modules/bug-reports/pending-registry.d.ts +0 -27
  192. package/dist/modules/bug-reports/pending-registry.js +0 -49
  193. package/dist/modules/bug-reports/types.d.ts +0 -123
  194. package/dist/modules/bug-reports/types.js +0 -9
  195. package/dist/routes/agents.d.ts +0 -44
  196. package/dist/routes/agents.js +0 -311
  197. package/dist/services/agent-credential-store.d.ts +0 -73
  198. package/dist/services/agent-credential-store.js +0 -212
  199. package/dist/services/bug-monitor.d.ts +0 -23
  200. package/dist/services/bug-monitor.js +0 -275
@@ -1,25 +0,0 @@
1
- /**
2
- * Bug Reports Module - Configuration Discovery
3
- *
4
- * Discovers Bug Reports workflow by name pattern.
5
- * No hardcoded IDs - works in any workspace.
6
- */
7
- import type { UserContext } from '../../mcp/UserContextCache';
8
- import type { BugReportsConfig, WorkflowDiscoveryResult } from './types';
9
- /**
10
- * Discover Bug Reports workflow in a workspace
11
- */
12
- export declare function discoverWorkflow(userContext: UserContext, config: BugReportsConfig): Promise<WorkflowDiscoveryResult | null>;
13
- /**
14
- * Load config from MCP Config workflow or environment
15
- */
16
- export declare function loadConfig(userContext: UserContext): Promise<BugReportsConfig>;
17
- /**
18
- * Get default configuration
19
- */
20
- export declare function getDefaultConfig(): BugReportsConfig;
21
- /**
22
- * Save config back to Hailer (creates/updates config activity)
23
- */
24
- export declare function saveConfig(_userContext: UserContext, _config: BugReportsConfig): Promise<boolean>;
25
- //# sourceMappingURL=config.d.ts.map
@@ -1,227 +0,0 @@
1
- "use strict";
2
- /**
3
- * Bug Reports Module - Configuration Discovery
4
- *
5
- * Discovers Bug Reports workflow by name pattern.
6
- * No hardcoded IDs - works in any workspace.
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.discoverWorkflow = discoverWorkflow;
10
- exports.loadConfig = loadConfig;
11
- exports.getDefaultConfig = getDefaultConfig;
12
- exports.saveConfig = saveConfig;
13
- const logger_1 = require("../../lib/logger");
14
- const logger = (0, logger_1.createLogger)({ component: 'bug-reports-config' });
15
- /**
16
- * Discover Bug Reports workflow in a workspace
17
- */
18
- async function discoverWorkflow(userContext, config) {
19
- const { workspaceCache } = userContext;
20
- // Find workflow by name pattern
21
- const workflows = Object.values(workspaceCache.rawInit.processes || {});
22
- const bugWorkflow = workflows.find((w) => w.name?.toLowerCase().includes(config.workflowNamePattern.toLowerCase()));
23
- if (!bugWorkflow) {
24
- logger.warn(`Workflow matching "${config.workflowNamePattern}" not found`);
25
- return null;
26
- }
27
- logger.info('Found Bug Reports workflow', {
28
- id: bugWorkflow._id,
29
- name: bugWorkflow.name
30
- });
31
- // Discover phases by name
32
- const phases = Object.values(bugWorkflow.phases || {});
33
- const phaseMap = {
34
- new: phases.find((p) => p.name?.toLowerCase() === config.phaseNames.new.toLowerCase())?._id,
35
- inProgress: phases.find((p) => p.name?.toLowerCase() === config.phaseNames.inProgress.toLowerCase())?._id,
36
- fixed: phases.find((p) => p.name?.toLowerCase() === config.phaseNames.fixed.toLowerCase())?._id,
37
- closed: phases.find((p) => p.name?.toLowerCase() === config.phaseNames.closed.toLowerCase())?._id,
38
- declined: phases.find((p) => p.name?.toLowerCase() === config.phaseNames.declined.toLowerCase())?._id
39
- };
40
- // Discover fields by label pattern
41
- const fieldMap = await discoverFields(bugWorkflow);
42
- const result = {
43
- workflowId: bugWorkflow._id,
44
- workflowName: bugWorkflow.name,
45
- phases: phaseMap,
46
- fields: fieldMap
47
- };
48
- logger.info('Workflow discovery complete', {
49
- workflowId: result.workflowId,
50
- phases: Object.entries(result.phases).filter(([, v]) => v).map(([k]) => k),
51
- fields: Object.entries(result.fields).filter(([, v]) => v).map(([k]) => k)
52
- });
53
- return result;
54
- }
55
- /**
56
- * Discover field IDs by label patterns
57
- */
58
- async function discoverFields(workflow) {
59
- const fields = {};
60
- // Get all fields from all phases
61
- const allFields = [];
62
- for (const phase of Object.values(workflow.phases || {})) {
63
- for (const field of Object.values(phase.fields || {})) {
64
- allFields.push(field);
65
- }
66
- }
67
- // Also check workflow-level fields (some workflows store fields here)
68
- for (const field of Object.values(workflow.fields || {})) {
69
- allFields.push(field);
70
- }
71
- logger.info('Field discovery', {
72
- workflowName: workflow.name,
73
- phaseCount: Object.keys(workflow.phases || {}).length,
74
- fieldCount: allFields.length,
75
- fieldSample: allFields.slice(0, 5).map(f => ({
76
- id: f._id,
77
- key: f.key,
78
- label: f.label,
79
- type: f.type
80
- }))
81
- });
82
- // Known field keys for Bug Reports template (marketplace standard)
83
- const knownKeys = {
84
- 'appId': 'appId',
85
- 'appName': 'appName',
86
- 'description': 'description',
87
- 'reportedBy': 'reportedBy',
88
- 'stepsToReproduce': 'stepsToReproduce',
89
- 'expectedBehavior': 'expectedBehavior',
90
- 'actualBehavior': 'actualBehavior',
91
- 'priority': 'priority'
92
- };
93
- // First pass: match by field key (most reliable for templates)
94
- for (const field of allFields) {
95
- const fieldKey = field.key;
96
- if (fieldKey && knownKeys[fieldKey]) {
97
- const mappedKey = knownKeys[fieldKey];
98
- if (!fields[mappedKey]) {
99
- fields[mappedKey] = field._id;
100
- logger.debug(`Mapped field by key "${fieldKey}" -> ${mappedKey}`, { fieldId: field._id });
101
- }
102
- }
103
- }
104
- // Second pass: match by label patterns (fallback)
105
- const patterns = {
106
- appId: /app\s*(id|identifier)/i,
107
- appName: /app\s*name/i,
108
- description: /description|details|bug\s*description/i,
109
- stepsToReproduce: /steps|reproduce|how\s*to|repro/i,
110
- expectedBehavior: /expected|should/i,
111
- actualBehavior: /actual|instead|result/i,
112
- reportedBy: /reported\s*by|reporter|submitter|author/i,
113
- priority: /priority|severity|urgency/i
114
- };
115
- for (const field of allFields) {
116
- const label = field.label || field.key || '';
117
- for (const [key, pattern] of Object.entries(patterns)) {
118
- if (!fields[key] && pattern.test(label)) {
119
- fields[key] = field._id;
120
- logger.debug(`Mapped field by label "${label}" -> ${key}`, { fieldId: field._id });
121
- }
122
- }
123
- }
124
- logger.info('Field discovery complete', {
125
- mappedFields: Object.keys(fields).filter(k => fields[k])
126
- });
127
- return fields;
128
- }
129
- /**
130
- * Load config from MCP Config workflow or environment
131
- */
132
- async function loadConfig(userContext) {
133
- const { workspaceCache, hailer } = userContext;
134
- // Try to load from MCP Config workflow
135
- try {
136
- const workflows = Object.values(workspaceCache.rawInit.processes || {});
137
- const mcpConfigWorkflow = workflows.find((w) => w.name?.toLowerCase().includes('mcp config'));
138
- if (mcpConfigWorkflow) {
139
- const phases = Object.values(mcpConfigWorkflow.phases || {});
140
- if (phases.length > 0) {
141
- const result = await hailer.fetchActivityList(mcpConfigWorkflow._id, phases[0]._id, 100);
142
- const activities = result?.activities || result || [];
143
- const configActivity = activities.find((a) => a.name === 'Bug Monitor Service' || a.name === 'Bug Reports Config');
144
- if (configActivity) {
145
- const fullActivity = await hailer.fetchActivityById(configActivity._id);
146
- const configJson = extractJsonFromFields(fullActivity.fields);
147
- if (configJson) {
148
- logger.info('Loaded Bug Reports config from Hailer');
149
- return {
150
- ...getDefaultConfig(),
151
- ...configJson
152
- };
153
- }
154
- }
155
- }
156
- }
157
- }
158
- catch (error) {
159
- logger.warn('Failed to load config from Hailer, using defaults', { error });
160
- }
161
- // Fall back to environment variables
162
- return loadConfigFromEnv();
163
- }
164
- /**
165
- * Extract JSON config from activity fields
166
- */
167
- function extractJsonFromFields(fields) {
168
- for (const fieldData of Object.values(fields || {})) {
169
- if (fieldData.type === 'textarea' && fieldData.value) {
170
- try {
171
- return JSON.parse(fieldData.value);
172
- }
173
- catch {
174
- // Not JSON, continue
175
- }
176
- }
177
- }
178
- return null;
179
- }
180
- /**
181
- * Load config from environment variables
182
- */
183
- function loadConfigFromEnv() {
184
- return {
185
- enabled: process.env.BUG_MONITOR_ENABLED === 'true',
186
- workflowNamePattern: process.env.BUG_MONITOR_WORKFLOW_PATTERN || 'Bug Reports',
187
- phaseNames: {
188
- new: process.env.BUG_MONITOR_PHASE_NEW || 'New',
189
- inProgress: process.env.BUG_MONITOR_PHASE_IN_PROGRESS || 'In Progress',
190
- fixed: process.env.BUG_MONITOR_PHASE_FIXED || 'Fixed',
191
- closed: process.env.BUG_MONITOR_PHASE_CLOSED || 'Closed',
192
- declined: process.env.BUG_MONITOR_PHASE_DECLINED || 'Declined'
193
- },
194
- intervalMs: parseInt(process.env.BUG_MONITOR_INTERVAL_MS || '300000', 10),
195
- autoFix: process.env.BUG_MONITOR_AUTO_FIX === 'true',
196
- notifyOnNew: process.env.BUG_MONITOR_NOTIFY !== 'false',
197
- anthropicApiKey: process.env.ANTHROPIC_API_KEY
198
- };
199
- }
200
- /**
201
- * Get default configuration
202
- */
203
- function getDefaultConfig() {
204
- return {
205
- enabled: false,
206
- workflowNamePattern: 'Bug Reports',
207
- phaseNames: {
208
- new: 'New',
209
- inProgress: 'In Progress',
210
- fixed: 'Fixed',
211
- closed: 'Closed',
212
- declined: 'Declined'
213
- },
214
- intervalMs: 300000,
215
- autoFix: false,
216
- notifyOnNew: true
217
- };
218
- }
219
- /**
220
- * Save config back to Hailer (creates/updates config activity)
221
- */
222
- async function saveConfig(_userContext, _config) {
223
- // TODO: Implement save config to MCP Config workflow
224
- logger.warn('saveConfig not yet implemented');
225
- return false;
226
- }
227
- //# sourceMappingURL=config.js.map
@@ -1,52 +0,0 @@
1
- /**
2
- * Giuseppe Files Module - File scanning, reading, and modification
3
- */
4
- import type { BugReport, AppRegistryEntry } from './types';
5
- import type { FixPlan } from './ai';
6
- export interface FileContent {
7
- path: string;
8
- content: string;
9
- }
10
- export interface ApplyResult {
11
- success: boolean;
12
- files: string[];
13
- error?: string;
14
- }
15
- export interface ScannedApp {
16
- path: string;
17
- name: string;
18
- appId?: string;
19
- }
20
- export declare class GiuseppeFiles {
21
- private appsBasePath?;
22
- constructor(appsBasePath?: string);
23
- /**
24
- * Check if file exists
25
- */
26
- fileExists(filePath: string): Promise<boolean>;
27
- /**
28
- * Scan for source file NAMES only (no content)
29
- */
30
- scanSourceFiles(projectPath: string): Promise<string[]>;
31
- /**
32
- * Read specific files by path
33
- */
34
- readSelectedFiles(projectPath: string, filePaths: string[]): Promise<FileContent[]>;
35
- /**
36
- * Find relevant files by searching for keywords from feedback/bug
37
- */
38
- findRelevantFiles(projectPath: string, feedback: string, bug: BugReport): Promise<string[]>;
39
- /**
40
- * Apply fixes to files
41
- */
42
- applyFixes(app: AppRegistryEntry, fixes: FixPlan['fix']['files']): Promise<ApplyResult>;
43
- /**
44
- * Scan apps directory for projects
45
- */
46
- scanAppsDirectory(): Promise<ScannedApp[]>;
47
- /**
48
- * Find app project by appId, appName, or bug title
49
- */
50
- findAppProject(bug: BugReport, appsRegistry: Map<string, AppRegistryEntry>): Promise<AppRegistryEntry | null>;
51
- }
52
- //# sourceMappingURL=files.d.ts.map
@@ -1,338 +0,0 @@
1
- "use strict";
2
- /**
3
- * Giuseppe Files Module - File scanning, reading, and modification
4
- */
5
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- var desc = Object.getOwnPropertyDescriptor(m, k);
8
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
- desc = { enumerable: true, get: function() { return m[k]; } };
10
- }
11
- Object.defineProperty(o, k2, desc);
12
- }) : (function(o, m, k, k2) {
13
- if (k2 === undefined) k2 = k;
14
- o[k2] = m[k];
15
- }));
16
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
- Object.defineProperty(o, "default", { enumerable: true, value: v });
18
- }) : function(o, v) {
19
- o["default"] = v;
20
- });
21
- var __importStar = (this && this.__importStar) || (function () {
22
- var ownKeys = function(o) {
23
- ownKeys = Object.getOwnPropertyNames || function (o) {
24
- var ar = [];
25
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
- return ar;
27
- };
28
- return ownKeys(o);
29
- };
30
- return function (mod) {
31
- if (mod && mod.__esModule) return mod;
32
- var result = {};
33
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
- __setModuleDefault(result, mod);
35
- return result;
36
- };
37
- })();
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.GiuseppeFiles = void 0;
40
- const child_process_1 = require("child_process");
41
- const fs = __importStar(require("fs/promises"));
42
- const path = __importStar(require("path"));
43
- const logger_1 = require("../../lib/logger");
44
- const logger = (0, logger_1.createLogger)({ component: 'giuseppe-files' });
45
- /**
46
- * Escape shell metacharacters to prevent command injection
47
- */
48
- function escapeShellArg(arg) {
49
- return arg.replace(/["\$`\\!]/g, '\\$&');
50
- }
51
- class GiuseppeFiles {
52
- appsBasePath;
53
- constructor(appsBasePath) {
54
- this.appsBasePath = appsBasePath;
55
- }
56
- /**
57
- * Check if file exists
58
- */
59
- async fileExists(filePath) {
60
- try {
61
- await fs.access(filePath);
62
- return true;
63
- }
64
- catch {
65
- return false;
66
- }
67
- }
68
- /**
69
- * Scan for source file NAMES only (no content)
70
- */
71
- async scanSourceFiles(projectPath) {
72
- const files = [];
73
- const extensions = ['.tsx', '.ts', '.jsx', '.js', '.css', '.scss'];
74
- const ignoreDirs = ['node_modules', 'dist', 'build', '.git', 'coverage', '.next', 'public'];
75
- const scanDir = async (dir, depth = 0) => {
76
- if (depth > 5)
77
- return;
78
- try {
79
- const entries = await fs.readdir(dir, { withFileTypes: true });
80
- for (const entry of entries) {
81
- const fullPath = path.join(dir, entry.name);
82
- const relativePath = path.relative(projectPath, fullPath);
83
- if (entry.isDirectory()) {
84
- if (!ignoreDirs.includes(entry.name) && !entry.name.startsWith('.')) {
85
- await scanDir(fullPath, depth + 1);
86
- }
87
- }
88
- else if (extensions.some(ext => entry.name.endsWith(ext))) {
89
- // Skip test files
90
- if (!entry.name.includes('.test.') && !entry.name.includes('.spec.')) {
91
- files.push(relativePath);
92
- }
93
- }
94
- }
95
- }
96
- catch {
97
- // Skip unreadable directories
98
- }
99
- };
100
- await scanDir(projectPath);
101
- return files;
102
- }
103
- /**
104
- * Read specific files by path
105
- */
106
- async readSelectedFiles(projectPath, filePaths) {
107
- const files = [];
108
- for (const filePath of filePaths) {
109
- try {
110
- const fullPath = path.join(projectPath, filePath);
111
- const content = await fs.readFile(fullPath, 'utf-8');
112
- files.push({ path: filePath, content });
113
- logger.debug('Read file', { path: filePath, size: content.length });
114
- }
115
- catch (error) {
116
- logger.warn('Could not read file', { path: filePath, error });
117
- }
118
- }
119
- return files;
120
- }
121
- /**
122
- * Find relevant files by searching for keywords from feedback/bug
123
- */
124
- async findRelevantFiles(projectPath, feedback, bug) {
125
- const relevantFiles = new Set();
126
- // Extract keywords from feedback and bug description
127
- const text = `${feedback} ${bug.name} ${bug.description || ''} ${bug.stepsToReproduce || ''}`;
128
- // Find component names (PascalCase words)
129
- const componentMatches = text.match(/[A-Z][a-zA-Z]+(?:Tool|Button|Modal|Panel|Canvas|Toolbar|Card|Slot)?/g) || [];
130
- // Find function/variable names (camelCase or specific keywords)
131
- const functionMatches = text.match(/(?:handle|on|set|get|use)[A-Z][a-zA-Z]+|delete|remove|add|select|click|drag|drop|cursor/gi) || [];
132
- const keywords = [...new Set([...componentMatches, ...functionMatches])];
133
- // Search for each keyword using grep
134
- for (const keyword of keywords.slice(0, 10)) { // Limit searches
135
- try {
136
- const escapedKeyword = escapeShellArg(keyword);
137
- const result = (0, child_process_1.execSync)(`git grep -l "${escapedKeyword}" -- "*.tsx" "*.ts" 2>/dev/null || true`, { cwd: projectPath, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
138
- result.trim().split('\n').filter(f => f).forEach(f => relevantFiles.add(f));
139
- }
140
- catch {
141
- // Ignore grep errors
142
- }
143
- }
144
- return Array.from(relevantFiles);
145
- }
146
- /**
147
- * Apply fixes to files
148
- */
149
- async applyFixes(app, fixes) {
150
- const modifiedFiles = [];
151
- try {
152
- for (const fix of fixes) {
153
- const filePath = path.join(app.projectPath, fix.path);
154
- if (fix.action === 'edit' && fix.search && fix.replace !== undefined) {
155
- // Check file exists before reading
156
- if (!await this.fileExists(filePath)) {
157
- return {
158
- success: false,
159
- files: modifiedFiles,
160
- error: `File not found: ${fix.path} - check the path is correct`
161
- };
162
- }
163
- const content = await fs.readFile(filePath, 'utf-8');
164
- // Try exact match first
165
- if (content.includes(fix.search)) {
166
- const newContent = content.replace(fix.search, fix.replace);
167
- await fs.writeFile(filePath, newContent, 'utf-8');
168
- modifiedFiles.push(fix.path);
169
- }
170
- else {
171
- // Try normalized whitespace match
172
- const normalizeWs = (s) => s.replace(/\s+/g, ' ').trim();
173
- const normalizedContent = normalizeWs(content);
174
- const normalizedSearch = normalizeWs(fix.search);
175
- if (normalizedContent.includes(normalizedSearch)) {
176
- // Find the actual line(s) to replace using line-by-line search
177
- const searchLines = fix.search.split('\n').map(l => l.trim()).filter(l => l);
178
- const contentLines = content.split('\n');
179
- let found = false;
180
- for (let i = 0; i <= contentLines.length - searchLines.length; i++) {
181
- const candidateLines = contentLines.slice(i, i + searchLines.length);
182
- if (candidateLines.every((line, j) => line.trim() === searchLines[j])) {
183
- // Found match - replace these lines
184
- const before = contentLines.slice(0, i);
185
- const after = contentLines.slice(i + searchLines.length);
186
- const replaceLines = fix.replace.split('\n');
187
- const newContent = [...before, ...replaceLines, ...after].join('\n');
188
- await fs.writeFile(filePath, newContent, 'utf-8');
189
- modifiedFiles.push(fix.path);
190
- found = true;
191
- break;
192
- }
193
- }
194
- if (!found) {
195
- return {
196
- success: false,
197
- files: modifiedFiles,
198
- error: `Search string not found in ${fix.path} (whitespace mismatch)`
199
- };
200
- }
201
- }
202
- else {
203
- return {
204
- success: false,
205
- files: modifiedFiles,
206
- error: `Search string not found in ${fix.path}`
207
- };
208
- }
209
- }
210
- }
211
- else if (fix.action === 'create' && fix.content) {
212
- await fs.mkdir(path.dirname(filePath), { recursive: true });
213
- await fs.writeFile(filePath, fix.content, 'utf-8');
214
- modifiedFiles.push(fix.path);
215
- }
216
- else if (fix.action === 'delete') {
217
- await fs.unlink(filePath);
218
- modifiedFiles.push(fix.path);
219
- }
220
- }
221
- return { success: true, files: modifiedFiles };
222
- }
223
- catch (error) {
224
- return {
225
- success: false,
226
- files: modifiedFiles,
227
- error: error instanceof Error ? error.message : String(error)
228
- };
229
- }
230
- }
231
- /**
232
- * Scan apps directory for projects
233
- */
234
- async scanAppsDirectory() {
235
- if (!this.appsBasePath) {
236
- logger.warn('DEV_APPS_PATH not set - cannot scan for apps');
237
- return [];
238
- }
239
- logger.debug('Scanning apps directory', { path: this.appsBasePath });
240
- const results = [];
241
- try {
242
- const entries = await fs.readdir(this.appsBasePath, { withFileTypes: true });
243
- for (const entry of entries) {
244
- if (entry.isDirectory()) {
245
- const projectPath = path.join(this.appsBasePath, entry.name);
246
- const manifestPath = path.join(projectPath, 'manifest.json');
247
- try {
248
- const manifestContent = await fs.readFile(manifestPath, 'utf-8');
249
- const manifest = JSON.parse(manifestContent);
250
- results.push({
251
- path: projectPath,
252
- name: manifest.name || entry.name,
253
- appId: manifest.appId
254
- });
255
- }
256
- catch {
257
- // No manifest, just use directory name
258
- results.push({
259
- path: projectPath,
260
- name: entry.name
261
- });
262
- }
263
- }
264
- }
265
- }
266
- catch (error) {
267
- logger.warn('Failed to scan apps directory', { error });
268
- }
269
- logger.debug('Found apps', { count: results.length, apps: results.map(a => a.name) });
270
- return results;
271
- }
272
- /**
273
- * Find app project by appId, appName, or bug title
274
- */
275
- async findAppProject(bug, appsRegistry) {
276
- // 1. Check registry first
277
- if (bug.appId && appsRegistry.has(bug.appId)) {
278
- return appsRegistry.get(bug.appId);
279
- }
280
- // 2. Try to find by appId in apps directory
281
- if (this.appsBasePath && bug.appId) {
282
- const apps = await this.scanAppsDirectory();
283
- for (const app of apps) {
284
- if (app.appId === bug.appId) {
285
- return {
286
- projectPath: app.path,
287
- name: app.name
288
- };
289
- }
290
- }
291
- }
292
- // 3. Try to find by app name
293
- if (this.appsBasePath && bug.appName) {
294
- const apps = await this.scanAppsDirectory();
295
- for (const app of apps) {
296
- if (app.name.toLowerCase().includes(bug.appName.toLowerCase())) {
297
- return {
298
- projectPath: app.path,
299
- name: app.name
300
- };
301
- }
302
- }
303
- }
304
- // 4. Try to extract app name from bug title (e.g., "Bug Report - Lineup Manager")
305
- if (this.appsBasePath) {
306
- const apps = await this.scanAppsDirectory();
307
- const bugTitle = bug.name.toLowerCase();
308
- for (const app of apps) {
309
- const appNameLower = app.name.toLowerCase();
310
- // Check if app name appears in bug title
311
- if (bugTitle.includes(appNameLower) ||
312
- bugTitle.includes(appNameLower.replace(/-/g, ' ')) ||
313
- bugTitle.includes(appNameLower.replace(/_/g, ' '))) {
314
- logger.info('Found app from bug title', { bugTitle: bug.name, appName: app.name });
315
- return {
316
- projectPath: app.path,
317
- name: app.name
318
- };
319
- }
320
- }
321
- // Also try matching directory name directly
322
- for (const app of apps) {
323
- const dirName = app.path.split('/').pop()?.toLowerCase() || '';
324
- if (bugTitle.includes(dirName) ||
325
- bugTitle.includes(dirName.replace(/-/g, ' '))) {
326
- logger.info('Found app from directory name', { bugTitle: bug.name, dirName });
327
- return {
328
- projectPath: app.path,
329
- name: app.name
330
- };
331
- }
332
- }
333
- }
334
- return null;
335
- }
336
- }
337
- exports.GiuseppeFiles = GiuseppeFiles;
338
- //# sourceMappingURL=files.js.map
@@ -1,48 +0,0 @@
1
- /**
2
- * Giuseppe Git Module - Git operations for committing, reverting, tagging
3
- */
4
- import type { BugReport, AppRegistryEntry } from './types';
5
- export declare class GiuseppeGit {
6
- /**
7
- * Get source files using git ls-files (fast and accurate)
8
- */
9
- getSourceFilesFromGit(projectPath: string): Promise<string[]>;
10
- /**
11
- * Commit changes to git
12
- */
13
- commitChanges(app: AppRegistryEntry, bug: BugReport): Promise<{
14
- success: boolean;
15
- hash?: string;
16
- }>;
17
- /**
18
- * Revert changes using git checkout
19
- */
20
- revertChanges(app: AppRegistryEntry, files: string[]): Promise<void>;
21
- /**
22
- * Get latest version from git tags (e.g., v1.0.1 -> 1.0.1)
23
- * Returns null if no version tags found
24
- */
25
- getLatestVersionFromTags(projectPath: string): string | null;
26
- /**
27
- * Create and push a version tag after successful publish
28
- */
29
- createVersionTag(projectPath: string, version: string): boolean;
30
- /**
31
- * Bump patch version in manifest.json (bug fixes always bump patch)
32
- * Uses git tags to determine latest version, falls back to manifest
33
- * 1.0.0 -> 1.0.1 -> 1.0.2 etc.
34
- */
35
- bumpPatchVersion(projectPath: string): Promise<{
36
- oldVersion: string;
37
- newVersion: string;
38
- } | null>;
39
- /**
40
- * Push to git remote
41
- */
42
- push(projectPath: string): Promise<boolean>;
43
- /**
44
- * Stage and commit version bump
45
- */
46
- commitVersionBump(projectPath: string, version: string): Promise<boolean>;
47
- }
48
- //# sourceMappingURL=git.d.ts.map