@hailer/mcp 0.1.17 → 0.2.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.
- package/dist/app.js +24 -20
- package/dist/core.d.ts +33 -9
- package/dist/core.js +279 -147
- package/dist/mcp/UserContextCache.js +18 -0
- package/dist/mcp/hailer-clients.d.ts +9 -1
- package/dist/mcp/hailer-clients.js +13 -3
- package/dist/mcp/signal-handler.js +1 -1
- package/dist/mcp/tool-registry.d.ts +3 -1
- package/dist/mcp/tool-registry.js +4 -1
- package/dist/mcp/tools/activity.js +43 -34
- package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
- package/dist/mcp/tools/bot-config/constants.js +94 -0
- package/dist/mcp/tools/{bot-config.d.ts → bot-config/core.d.ts} +6 -6
- package/dist/mcp/tools/{bot-config.js → bot-config/core.js} +15 -15
- package/dist/mcp/tools/bot-config/index.d.ts +10 -0
- package/dist/mcp/tools/bot-config/index.js +59 -0
- package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
- package/dist/mcp/tools/bot-config/tools.js +15 -0
- package/dist/mcp/tools/bot-config/types.d.ts +50 -0
- package/dist/mcp/tools/bot-config/types.js +6 -0
- package/dist/mcp/tools/bug-fixer-tools.d.ts +21 -0
- package/dist/mcp/tools/{giuseppe-tools.js → bug-fixer-tools.js} +61 -61
- package/dist/mcp/tools/user.js +10 -29
- package/dist/mcp/tools/workflow.js +36 -2
- package/dist/mcp/utils/data-transformers.d.ts +0 -8
- package/dist/mcp/utils/data-transformers.js +0 -28
- package/dist/mcp/utils/index.d.ts +4 -1
- package/dist/mcp/utils/index.js +17 -3
- package/dist/mcp/utils/pagination.d.ts +40 -0
- package/dist/mcp/utils/pagination.js +55 -0
- package/dist/mcp/utils/response-builder.d.ts +53 -0
- package/dist/mcp/utils/response-builder.js +110 -0
- package/dist/mcp/utils/tool-helpers.d.ts +0 -8
- package/dist/mcp/utils/tool-helpers.js +0 -24
- package/dist/mcp/utils/types.d.ts +1 -33
- package/dist/mcp-server.d.ts +2 -2
- package/dist/mcp-server.js +161 -139
- package/package.json +1 -1
- package/REFACTOR_STATUS.md +0 -127
- package/dist/agents/bot-manager.d.ts +0 -48
- package/dist/agents/bot-manager.js +0 -254
- package/dist/agents/factory.d.ts +0 -150
- package/dist/agents/factory.js +0 -650
- package/dist/agents/giuseppe/ai.d.ts +0 -83
- package/dist/agents/giuseppe/ai.js +0 -466
- package/dist/agents/giuseppe/bot.d.ts +0 -110
- package/dist/agents/giuseppe/bot.js +0 -780
- package/dist/agents/giuseppe/config.d.ts +0 -25
- package/dist/agents/giuseppe/config.js +0 -227
- package/dist/agents/giuseppe/files.d.ts +0 -52
- package/dist/agents/giuseppe/files.js +0 -338
- package/dist/agents/giuseppe/git.d.ts +0 -48
- package/dist/agents/giuseppe/git.js +0 -298
- package/dist/agents/giuseppe/index.d.ts +0 -97
- package/dist/agents/giuseppe/index.js +0 -258
- package/dist/agents/giuseppe/lsp.d.ts +0 -113
- package/dist/agents/giuseppe/lsp.js +0 -485
- package/dist/agents/giuseppe/monitor.d.ts +0 -118
- package/dist/agents/giuseppe/monitor.js +0 -621
- package/dist/agents/giuseppe/prompt.d.ts +0 -5
- package/dist/agents/giuseppe/prompt.js +0 -94
- package/dist/agents/giuseppe/registries/pending-classification.d.ts +0 -28
- package/dist/agents/giuseppe/registries/pending-classification.js +0 -50
- package/dist/agents/giuseppe/registries/pending-fix.d.ts +0 -30
- package/dist/agents/giuseppe/registries/pending-fix.js +0 -42
- package/dist/agents/giuseppe/registries/pending.d.ts +0 -27
- package/dist/agents/giuseppe/registries/pending.js +0 -49
- package/dist/agents/giuseppe/specialist.d.ts +0 -47
- package/dist/agents/giuseppe/specialist.js +0 -237
- package/dist/agents/giuseppe/types.d.ts +0 -123
- package/dist/agents/giuseppe/types.js +0 -9
- package/dist/agents/hailer-expert/index.d.ts +0 -8
- package/dist/agents/hailer-expert/index.js +0 -14
- package/dist/agents/hal/daemon.d.ts +0 -142
- package/dist/agents/hal/daemon.js +0 -1103
- package/dist/agents/hal/definitions.d.ts +0 -55
- package/dist/agents/hal/definitions.js +0 -263
- package/dist/agents/hal/index.d.ts +0 -3
- package/dist/agents/hal/index.js +0 -8
- package/dist/agents/index.d.ts +0 -18
- package/dist/agents/index.js +0 -48
- package/dist/agents/shared/base.d.ts +0 -216
- package/dist/agents/shared/base.js +0 -846
- package/dist/agents/shared/services/agent-registry.d.ts +0 -107
- package/dist/agents/shared/services/agent-registry.js +0 -629
- package/dist/agents/shared/services/conversation-manager.d.ts +0 -50
- package/dist/agents/shared/services/conversation-manager.js +0 -136
- package/dist/agents/shared/services/mcp-client.d.ts +0 -56
- package/dist/agents/shared/services/mcp-client.js +0 -124
- package/dist/agents/shared/services/message-classifier.d.ts +0 -37
- package/dist/agents/shared/services/message-classifier.js +0 -187
- package/dist/agents/shared/services/message-formatter.d.ts +0 -89
- package/dist/agents/shared/services/message-formatter.js +0 -371
- package/dist/agents/shared/services/session-logger.d.ts +0 -106
- package/dist/agents/shared/services/session-logger.js +0 -446
- package/dist/agents/shared/services/tool-executor.d.ts +0 -41
- package/dist/agents/shared/services/tool-executor.js +0 -169
- package/dist/agents/shared/services/workspace-schema-cache.d.ts +0 -125
- package/dist/agents/shared/services/workspace-schema-cache.js +0 -578
- package/dist/agents/shared/specialist.d.ts +0 -91
- package/dist/agents/shared/specialist.js +0 -399
- package/dist/agents/shared/tool-schema-loader.d.ts +0 -62
- package/dist/agents/shared/tool-schema-loader.js +0 -232
- package/dist/agents/shared/types.d.ts +0 -327
- package/dist/agents/shared/types.js +0 -121
- package/dist/client/agents/base.d.ts +0 -207
- package/dist/client/agents/base.js +0 -744
- package/dist/client/agents/definitions.d.ts +0 -53
- package/dist/client/agents/definitions.js +0 -263
- package/dist/client/agents/orchestrator.d.ts +0 -141
- package/dist/client/agents/orchestrator.js +0 -1062
- package/dist/client/agents/specialist.d.ts +0 -86
- package/dist/client/agents/specialist.js +0 -340
- package/dist/client/bot-entrypoint.d.ts +0 -7
- package/dist/client/bot-entrypoint.js +0 -103
- package/dist/client/bot-manager.d.ts +0 -44
- package/dist/client/bot-manager.js +0 -173
- package/dist/client/bot-runner.d.ts +0 -35
- package/dist/client/bot-runner.js +0 -188
- package/dist/client/chat-agent-daemon.d.ts +0 -464
- package/dist/client/chat-agent-daemon.js +0 -1774
- package/dist/client/daemon-factory.d.ts +0 -106
- package/dist/client/daemon-factory.js +0 -301
- package/dist/client/factory.d.ts +0 -111
- package/dist/client/factory.js +0 -314
- package/dist/client/index.d.ts +0 -17
- package/dist/client/index.js +0 -38
- package/dist/client/multi-bot-manager.d.ts +0 -42
- package/dist/client/multi-bot-manager.js +0 -161
- package/dist/client/orchestrator-daemon.d.ts +0 -87
- package/dist/client/orchestrator-daemon.js +0 -444
- package/dist/client/server.d.ts +0 -8
- package/dist/client/server.js +0 -251
- package/dist/client/services/agent-registry.d.ts +0 -108
- package/dist/client/services/agent-registry.js +0 -630
- package/dist/client/services/conversation-manager.d.ts +0 -50
- package/dist/client/services/conversation-manager.js +0 -136
- package/dist/client/services/mcp-client.d.ts +0 -48
- package/dist/client/services/mcp-client.js +0 -105
- package/dist/client/services/message-classifier.d.ts +0 -37
- package/dist/client/services/message-classifier.js +0 -187
- package/dist/client/services/message-formatter.d.ts +0 -84
- package/dist/client/services/message-formatter.js +0 -353
- package/dist/client/services/session-logger.d.ts +0 -106
- package/dist/client/services/session-logger.js +0 -446
- package/dist/client/services/tool-executor.d.ts +0 -41
- package/dist/client/services/tool-executor.js +0 -169
- package/dist/client/services/workspace-schema-cache.d.ts +0 -149
- package/dist/client/services/workspace-schema-cache.js +0 -732
- package/dist/client/specialist-daemon.d.ts +0 -77
- package/dist/client/specialist-daemon.js +0 -197
- package/dist/client/specialists.d.ts +0 -53
- package/dist/client/specialists.js +0 -178
- package/dist/client/tool-schema-loader.d.ts +0 -62
- package/dist/client/tool-schema-loader.js +0 -232
- package/dist/client/types.d.ts +0 -327
- package/dist/client/types.js +0 -121
- package/dist/commands/seed-config.d.ts +0 -9
- package/dist/commands/seed-config.js +0 -372
- package/dist/lib/context-manager.d.ts +0 -111
- package/dist/lib/context-manager.js +0 -431
- package/dist/lib/prompt-length-manager.d.ts +0 -81
- package/dist/lib/prompt-length-manager.js +0 -457
- package/dist/mcp/tools/giuseppe-tools.d.ts +0 -21
- package/dist/modules/bug-reports/bug-config.d.ts +0 -25
- package/dist/modules/bug-reports/bug-config.js +0 -187
- package/dist/modules/bug-reports/bug-monitor.d.ts +0 -108
- package/dist/modules/bug-reports/bug-monitor.js +0 -510
- package/dist/modules/bug-reports/giuseppe-agent.d.ts +0 -58
- package/dist/modules/bug-reports/giuseppe-agent.js +0 -467
- package/dist/modules/bug-reports/giuseppe-ai.d.ts +0 -83
- package/dist/modules/bug-reports/giuseppe-ai.js +0 -466
- package/dist/modules/bug-reports/giuseppe-bot.d.ts +0 -110
- package/dist/modules/bug-reports/giuseppe-bot.js +0 -804
- package/dist/modules/bug-reports/giuseppe-daemon.d.ts +0 -80
- package/dist/modules/bug-reports/giuseppe-daemon.js +0 -617
- package/dist/modules/bug-reports/giuseppe-files.d.ts +0 -64
- package/dist/modules/bug-reports/giuseppe-files.js +0 -375
- package/dist/modules/bug-reports/giuseppe-git.d.ts +0 -48
- package/dist/modules/bug-reports/giuseppe-git.js +0 -298
- package/dist/modules/bug-reports/giuseppe-lsp.d.ts +0 -113
- package/dist/modules/bug-reports/giuseppe-lsp.js +0 -485
- package/dist/modules/bug-reports/giuseppe-prompt.d.ts +0 -5
- package/dist/modules/bug-reports/giuseppe-prompt.js +0 -94
- package/dist/modules/bug-reports/index.d.ts +0 -77
- package/dist/modules/bug-reports/index.js +0 -215
- package/dist/modules/bug-reports/pending-classification-registry.d.ts +0 -28
- package/dist/modules/bug-reports/pending-classification-registry.js +0 -50
- package/dist/modules/bug-reports/pending-fix-registry.d.ts +0 -30
- package/dist/modules/bug-reports/pending-fix-registry.js +0 -42
- package/dist/modules/bug-reports/pending-registry.d.ts +0 -27
- package/dist/modules/bug-reports/pending-registry.js +0 -49
- package/dist/modules/bug-reports/types.d.ts +0 -123
- package/dist/modules/bug-reports/types.js +0 -9
- package/dist/routes/agents.d.ts +0 -44
- package/dist/routes/agents.js +0 -311
- package/dist/services/agent-credential-store.d.ts +0 -73
- package/dist/services/agent-credential-store.js +0 -212
- package/dist/services/bug-monitor.d.ts +0 -23
- package/dist/services/bug-monitor.js +0 -275
|
@@ -1,64 +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 './giuseppe-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
|
-
* Find app project from bug title alone (simplified interface for daemon)
|
|
53
|
-
*/
|
|
54
|
-
findAppFromBugTitle(bugTitle: string): Promise<AppRegistryEntry | null>;
|
|
55
|
-
/**
|
|
56
|
-
* Read a single file
|
|
57
|
-
*/
|
|
58
|
-
readFile(projectPath: string, filePath: string): Promise<string | null>;
|
|
59
|
-
/**
|
|
60
|
-
* Write a file
|
|
61
|
-
*/
|
|
62
|
-
writeFile(projectPath: string, filePath: string, content: string): Promise<boolean>;
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=giuseppe-files.d.ts.map
|
|
@@ -1,375 +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
|
-
* Find app project from bug title alone (simplified interface for daemon)
|
|
338
|
-
*/
|
|
339
|
-
async findAppFromBugTitle(bugTitle) {
|
|
340
|
-
return this.findAppProject({ id: '', name: bugTitle, description: '', workflowId: '', phaseId: '', createdAt: '' }, new Map());
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Read a single file
|
|
344
|
-
*/
|
|
345
|
-
async readFile(projectPath, filePath) {
|
|
346
|
-
try {
|
|
347
|
-
const fullPath = path.join(projectPath, filePath);
|
|
348
|
-
const content = await fs.readFile(fullPath, 'utf-8');
|
|
349
|
-
logger.debug('Read file', { path: filePath, size: content.length });
|
|
350
|
-
return content;
|
|
351
|
-
}
|
|
352
|
-
catch (error) {
|
|
353
|
-
logger.warn('Could not read file', { path: filePath, error });
|
|
354
|
-
return null;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Write a file
|
|
359
|
-
*/
|
|
360
|
-
async writeFile(projectPath, filePath, content) {
|
|
361
|
-
try {
|
|
362
|
-
const fullPath = path.join(projectPath, filePath);
|
|
363
|
-
await fs.mkdir(path.dirname(fullPath), { recursive: true });
|
|
364
|
-
await fs.writeFile(fullPath, content, 'utf-8');
|
|
365
|
-
logger.info('Wrote file', { path: filePath, size: content.length });
|
|
366
|
-
return true;
|
|
367
|
-
}
|
|
368
|
-
catch (error) {
|
|
369
|
-
logger.error('Failed to write file', { path: filePath, error });
|
|
370
|
-
return false;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
exports.GiuseppeFiles = GiuseppeFiles;
|
|
375
|
-
//# sourceMappingURL=giuseppe-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=giuseppe-git.d.ts.map
|