mcp-perplexity-pro 1.1.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 +638 -0
- package/bin/mcp-perplexity-pro +8 -0
- package/bin/mcp-perplexity-pro-stdio +9 -0
- package/dist/claude-code-bridge.d.ts +3 -0
- package/dist/claude-code-bridge.d.ts.map +1 -0
- package/dist/claude-code-bridge.js +111 -0
- package/dist/claude-code-bridge.js.map +1 -0
- package/dist/http-index.d.ts +3 -0
- package/dist/http-index.d.ts.map +1 -0
- package/dist/http-index.js +38 -0
- package/dist/http-index.js.map +1 -0
- package/dist/http-server.d.ts +33 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +362 -0
- package/dist/http-server.js.map +1 -0
- package/dist/http-streaming-server.d.ts +4 -0
- package/dist/http-streaming-server.d.ts.map +1 -0
- package/dist/http-streaming-server.js +514 -0
- package/dist/http-streaming-server.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/launcher.d.ts +3 -0
- package/dist/launcher.d.ts.map +1 -0
- package/dist/launcher.js +209 -0
- package/dist/launcher.js.map +1 -0
- package/dist/mcp-server.d.ts +5 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +329 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/models.d.ts +45 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +284 -0
- package/dist/models.js.map +1 -0
- package/dist/perplexity-api.d.ts +59 -0
- package/dist/perplexity-api.d.ts.map +1 -0
- package/dist/perplexity-api.js +455 -0
- package/dist/perplexity-api.js.map +1 -0
- package/dist/port-utils.d.ts +31 -0
- package/dist/port-utils.d.ts.map +1 -0
- package/dist/port-utils.js +114 -0
- package/dist/port-utils.js.map +1 -0
- package/dist/project-manager.d.ts +91 -0
- package/dist/project-manager.d.ts.map +1 -0
- package/dist/project-manager.js +422 -0
- package/dist/project-manager.js.map +1 -0
- package/dist/simple-streaming.d.ts +26 -0
- package/dist/simple-streaming.d.ts.map +1 -0
- package/dist/simple-streaming.js +75 -0
- package/dist/simple-streaming.js.map +1 -0
- package/dist/sse-index.d.ts +3 -0
- package/dist/sse-index.d.ts.map +1 -0
- package/dist/sse-index.js +38 -0
- package/dist/sse-index.js.map +1 -0
- package/dist/sse-server.d.ts +4 -0
- package/dist/sse-server.d.ts.map +1 -0
- package/dist/sse-server.js +208 -0
- package/dist/sse-server.js.map +1 -0
- package/dist/stdio-bridge.d.ts +21 -0
- package/dist/stdio-bridge.d.ts.map +1 -0
- package/dist/stdio-bridge.js +157 -0
- package/dist/stdio-bridge.js.map +1 -0
- package/dist/stdio-server.d.ts +7 -0
- package/dist/stdio-server.d.ts.map +1 -0
- package/dist/stdio-server.js +396 -0
- package/dist/stdio-server.js.map +1 -0
- package/dist/storage.d.ts +65 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +328 -0
- package/dist/storage.js.map +1 -0
- package/dist/streaming-wrapper.d.ts +63 -0
- package/dist/streaming-wrapper.d.ts.map +1 -0
- package/dist/streaming-wrapper.js +452 -0
- package/dist/streaming-wrapper.js.map +1 -0
- package/dist/tools/async.d.ts +28 -0
- package/dist/tools/async.d.ts.map +1 -0
- package/dist/tools/async.js +167 -0
- package/dist/tools/async.js.map +1 -0
- package/dist/tools/chat.d.ts +29 -0
- package/dist/tools/chat.d.ts.map +1 -0
- package/dist/tools/chat.js +233 -0
- package/dist/tools/chat.js.map +1 -0
- package/dist/tools/projects.d.ts +19 -0
- package/dist/tools/projects.d.ts.map +1 -0
- package/dist/tools/projects.js +219 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/tools/query.d.ts +13 -0
- package/dist/tools/query.d.ts.map +1 -0
- package/dist/tools/query.js +178 -0
- package/dist/tools/query.js.map +1 -0
- package/dist/types.d.ts +330 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +90 -0
- package/dist/types.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export interface ProjectInfo {
|
|
2
|
+
name: string;
|
|
3
|
+
path: string;
|
|
4
|
+
chatCount: number;
|
|
5
|
+
reportCount: number;
|
|
6
|
+
jobCount: number;
|
|
7
|
+
lastUsed?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface SessionData {
|
|
10
|
+
currentProject?: string;
|
|
11
|
+
projects: Set<string>;
|
|
12
|
+
lastUsed: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class ProjectManager {
|
|
15
|
+
private storageRoot;
|
|
16
|
+
private sessions;
|
|
17
|
+
private sessionFile;
|
|
18
|
+
constructor(storageRoot: string);
|
|
19
|
+
/**
|
|
20
|
+
* Lists all existing projects by scanning the projects directory
|
|
21
|
+
*/
|
|
22
|
+
listExistingProjects(): Promise<string[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Gets detailed information about existing projects
|
|
25
|
+
*/
|
|
26
|
+
getProjectsInfo(): Promise<ProjectInfo[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Smart project detection with multiple fallback strategies
|
|
29
|
+
*/
|
|
30
|
+
detectProject(explicitProject?: string, sessionId?: string): Promise<string>;
|
|
31
|
+
/**
|
|
32
|
+
* Extracts project name from file path using common patterns
|
|
33
|
+
*/
|
|
34
|
+
private extractProjectFromPath;
|
|
35
|
+
/**
|
|
36
|
+
* Detects project name from git repository
|
|
37
|
+
*/
|
|
38
|
+
private detectGitProject;
|
|
39
|
+
/**
|
|
40
|
+
* Validates if a name is suitable as a project name
|
|
41
|
+
*/
|
|
42
|
+
private isValidProjectName;
|
|
43
|
+
/**
|
|
44
|
+
* Normalizes project name for consistent storage
|
|
45
|
+
*/
|
|
46
|
+
private normalizeProjectName;
|
|
47
|
+
/**
|
|
48
|
+
* Remembers a project for a session
|
|
49
|
+
*/
|
|
50
|
+
rememberProject(sessionId: string | undefined, projectName: string): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Gets the current project for a session
|
|
53
|
+
*/
|
|
54
|
+
getSessionProject(sessionId: string): string | null;
|
|
55
|
+
/**
|
|
56
|
+
* Gets recent projects for a session
|
|
57
|
+
*/
|
|
58
|
+
getRecentProjects(sessionId: string): string[];
|
|
59
|
+
/**
|
|
60
|
+
* Loads session data from disk
|
|
61
|
+
*/
|
|
62
|
+
private loadSessions;
|
|
63
|
+
/**
|
|
64
|
+
* Persists session data to disk
|
|
65
|
+
*/
|
|
66
|
+
private persistSessions;
|
|
67
|
+
/**
|
|
68
|
+
* Creates helpful error message with project suggestions
|
|
69
|
+
*/
|
|
70
|
+
createProjectSuggestionMessage(sessionId?: string): Promise<string>;
|
|
71
|
+
/**
|
|
72
|
+
* Gets the storage path for a specific project
|
|
73
|
+
*/
|
|
74
|
+
getProjectStoragePath(projectName: string): string;
|
|
75
|
+
/**
|
|
76
|
+
* Deletes a project and all its data permanently
|
|
77
|
+
*/
|
|
78
|
+
deleteProject(projectName: string): Promise<{
|
|
79
|
+
deleted: boolean;
|
|
80
|
+
message: string;
|
|
81
|
+
stats?: any;
|
|
82
|
+
}>;
|
|
83
|
+
/**
|
|
84
|
+
* Gets statistics for a specific project
|
|
85
|
+
*/
|
|
86
|
+
private getProjectStats;
|
|
87
|
+
}
|
|
88
|
+
export declare class ProjectDetectionError extends Error {
|
|
89
|
+
constructor(message: string);
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=project-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-manager.d.ts","sourceRoot":"","sources":["../src/project-manager.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,WAAW,CAAS;gBAEhB,WAAW,EAAE,MAAM;IAM/B;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAgB/C;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IA6D/C;;OAEG;IACG,aAAa,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmClF;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA+B9B;;OAEG;YACW,gBAAgB;IAuB9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;OAEG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBxF;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAInD;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAK9C;;OAEG;YACW,YAAY;IAmB1B;;OAEG;YACW,eAAe;IAmB7B;;OAEG;IACG,8BAA8B,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA4CzE;;OAEG;IACH,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAIlD;;OAEG;IACG,aAAa,CACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IA4C9D;;OAEG;YACW,eAAe;CA4C9B;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B"}
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { basename } from 'path';
|
|
4
|
+
export class ProjectManager {
|
|
5
|
+
storageRoot;
|
|
6
|
+
sessions = new Map();
|
|
7
|
+
sessionFile;
|
|
8
|
+
constructor(storageRoot) {
|
|
9
|
+
this.storageRoot = storageRoot;
|
|
10
|
+
this.sessionFile = path.join(storageRoot, 'sessions', 'session-data.json');
|
|
11
|
+
this.loadSessions();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Lists all existing projects by scanning the projects directory
|
|
15
|
+
*/
|
|
16
|
+
async listExistingProjects() {
|
|
17
|
+
const projectsDir = path.join(this.storageRoot, 'projects');
|
|
18
|
+
try {
|
|
19
|
+
await fs.access(projectsDir);
|
|
20
|
+
const entries = await fs.readdir(projectsDir, { withFileTypes: true });
|
|
21
|
+
return entries
|
|
22
|
+
.filter(entry => entry.isDirectory())
|
|
23
|
+
.map(entry => entry.name)
|
|
24
|
+
.sort();
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
// Projects directory doesn't exist yet
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Gets detailed information about existing projects
|
|
33
|
+
*/
|
|
34
|
+
async getProjectsInfo() {
|
|
35
|
+
const projectNames = await this.listExistingProjects();
|
|
36
|
+
const projectsInfo = [];
|
|
37
|
+
for (const name of projectNames) {
|
|
38
|
+
const projectPath = path.join(this.storageRoot, 'projects', name);
|
|
39
|
+
const info = {
|
|
40
|
+
name,
|
|
41
|
+
path: projectPath,
|
|
42
|
+
chatCount: 0,
|
|
43
|
+
reportCount: 0,
|
|
44
|
+
jobCount: 0,
|
|
45
|
+
};
|
|
46
|
+
try {
|
|
47
|
+
// Count chats
|
|
48
|
+
const chatsDir = path.join(projectPath, 'chats');
|
|
49
|
+
try {
|
|
50
|
+
const chatFiles = await fs.readdir(chatsDir);
|
|
51
|
+
info.chatCount = chatFiles.filter(f => f.endsWith('.json')).length;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Chats directory doesn't exist
|
|
55
|
+
}
|
|
56
|
+
// Count reports
|
|
57
|
+
const reportsDir = path.join(projectPath, 'reports');
|
|
58
|
+
try {
|
|
59
|
+
const reportFiles = await fs.readdir(reportsDir);
|
|
60
|
+
info.reportCount = reportFiles.filter(f => f.endsWith('.json')).length;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Reports directory doesn't exist
|
|
64
|
+
}
|
|
65
|
+
// Count async jobs
|
|
66
|
+
const jobsDir = path.join(projectPath, 'async-jobs');
|
|
67
|
+
try {
|
|
68
|
+
const jobFiles = await fs.readdir(jobsDir);
|
|
69
|
+
info.jobCount = jobFiles.filter(f => f.endsWith('.json')).length;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Jobs directory doesn't exist
|
|
73
|
+
}
|
|
74
|
+
// Get last used date from directory modification time
|
|
75
|
+
const stats = await fs.stat(projectPath);
|
|
76
|
+
info.lastUsed = stats.mtime.toISOString();
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
// Error reading project info, but include the project anyway
|
|
80
|
+
}
|
|
81
|
+
projectsInfo.push(info);
|
|
82
|
+
}
|
|
83
|
+
// Sort by last used date (most recent first)
|
|
84
|
+
return projectsInfo.sort((a, b) => {
|
|
85
|
+
if (!a.lastUsed && !b.lastUsed)
|
|
86
|
+
return 0;
|
|
87
|
+
if (!a.lastUsed)
|
|
88
|
+
return 1;
|
|
89
|
+
if (!b.lastUsed)
|
|
90
|
+
return -1;
|
|
91
|
+
return new Date(b.lastUsed).getTime() - new Date(a.lastUsed).getTime();
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Smart project detection with multiple fallback strategies
|
|
96
|
+
*/
|
|
97
|
+
async detectProject(explicitProject, sessionId) {
|
|
98
|
+
// 1. Explicit project name takes precedence
|
|
99
|
+
if (explicitProject?.trim()) {
|
|
100
|
+
const normalizedProject = this.normalizeProjectName(explicitProject.trim());
|
|
101
|
+
await this.rememberProject(sessionId, normalizedProject);
|
|
102
|
+
return normalizedProject;
|
|
103
|
+
}
|
|
104
|
+
// 2. Try to detect from current working directory
|
|
105
|
+
const cwd = process.cwd();
|
|
106
|
+
const projectFromPath = this.extractProjectFromPath(cwd);
|
|
107
|
+
if (projectFromPath) {
|
|
108
|
+
await this.rememberProject(sessionId, projectFromPath);
|
|
109
|
+
return projectFromPath;
|
|
110
|
+
}
|
|
111
|
+
// 3. Check if we're in a git repository
|
|
112
|
+
const gitProject = await this.detectGitProject(cwd);
|
|
113
|
+
if (gitProject) {
|
|
114
|
+
await this.rememberProject(sessionId, gitProject);
|
|
115
|
+
return gitProject;
|
|
116
|
+
}
|
|
117
|
+
// 4. Use session-based memory
|
|
118
|
+
if (sessionId) {
|
|
119
|
+
const sessionProject = this.getSessionProject(sessionId);
|
|
120
|
+
if (sessionProject) {
|
|
121
|
+
return sessionProject;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// 5. Cannot detect - need user input
|
|
125
|
+
throw new ProjectDetectionError('Project name required for organization');
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Extracts project name from file path using common patterns
|
|
129
|
+
*/
|
|
130
|
+
extractProjectFromPath(filePath) {
|
|
131
|
+
const segments = filePath.split(path.sep).filter(Boolean);
|
|
132
|
+
const commonProjectPaths = [
|
|
133
|
+
'Projects',
|
|
134
|
+
'workspace',
|
|
135
|
+
'code',
|
|
136
|
+
'repos',
|
|
137
|
+
'src',
|
|
138
|
+
'development',
|
|
139
|
+
'dev',
|
|
140
|
+
];
|
|
141
|
+
// Look for common project directory patterns
|
|
142
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
143
|
+
if (commonProjectPaths.some(p => segments[i].toLowerCase().includes(p.toLowerCase()))) {
|
|
144
|
+
const potentialProject = segments[i + 1];
|
|
145
|
+
if (potentialProject && this.isValidProjectName(potentialProject)) {
|
|
146
|
+
return this.normalizeProjectName(potentialProject);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Fallback to last directory name if it looks like a project
|
|
151
|
+
const lastDir = segments[segments.length - 1];
|
|
152
|
+
if (lastDir && this.isValidProjectName(lastDir)) {
|
|
153
|
+
return this.normalizeProjectName(lastDir);
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Detects project name from git repository
|
|
159
|
+
*/
|
|
160
|
+
async detectGitProject(cwd) {
|
|
161
|
+
try {
|
|
162
|
+
// Look for .git directory by walking up the directory tree
|
|
163
|
+
let currentDir = cwd;
|
|
164
|
+
while (currentDir !== path.dirname(currentDir)) {
|
|
165
|
+
const gitPath = path.join(currentDir, '.git');
|
|
166
|
+
try {
|
|
167
|
+
await fs.access(gitPath);
|
|
168
|
+
const repoName = basename(currentDir);
|
|
169
|
+
if (this.isValidProjectName(repoName)) {
|
|
170
|
+
return this.normalizeProjectName(repoName);
|
|
171
|
+
}
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
currentDir = path.dirname(currentDir);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
// Git detection failed
|
|
181
|
+
}
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Validates if a name is suitable as a project name
|
|
186
|
+
*/
|
|
187
|
+
isValidProjectName(name) {
|
|
188
|
+
// Avoid common non-project directory names
|
|
189
|
+
const invalidNames = [
|
|
190
|
+
'src',
|
|
191
|
+
'app',
|
|
192
|
+
'lib',
|
|
193
|
+
'dist',
|
|
194
|
+
'build',
|
|
195
|
+
'node_modules',
|
|
196
|
+
'.git',
|
|
197
|
+
'temp',
|
|
198
|
+
'tmp',
|
|
199
|
+
];
|
|
200
|
+
return (!invalidNames.includes(name.toLowerCase()) &&
|
|
201
|
+
name.length > 0 &&
|
|
202
|
+
name.length < 100 &&
|
|
203
|
+
/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(name)); // Valid filesystem name
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Normalizes project name for consistent storage
|
|
207
|
+
*/
|
|
208
|
+
normalizeProjectName(name) {
|
|
209
|
+
return name.toLowerCase().replace(/[^a-z0-9._-]/g, '-');
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Remembers a project for a session
|
|
213
|
+
*/
|
|
214
|
+
async rememberProject(sessionId, projectName) {
|
|
215
|
+
if (!sessionId)
|
|
216
|
+
return;
|
|
217
|
+
const session = this.sessions.get(sessionId) || {
|
|
218
|
+
projects: new Set(),
|
|
219
|
+
lastUsed: new Date().toISOString(),
|
|
220
|
+
};
|
|
221
|
+
session.currentProject = projectName;
|
|
222
|
+
session.projects.add(projectName);
|
|
223
|
+
session.lastUsed = new Date().toISOString();
|
|
224
|
+
this.sessions.set(sessionId, session);
|
|
225
|
+
await this.persistSessions();
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Gets the current project for a session
|
|
229
|
+
*/
|
|
230
|
+
getSessionProject(sessionId) {
|
|
231
|
+
return this.sessions.get(sessionId)?.currentProject || null;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Gets recent projects for a session
|
|
235
|
+
*/
|
|
236
|
+
getRecentProjects(sessionId) {
|
|
237
|
+
const session = this.sessions.get(sessionId);
|
|
238
|
+
return session ? Array.from(session.projects).reverse() : []; // Most recent first
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Loads session data from disk
|
|
242
|
+
*/
|
|
243
|
+
async loadSessions() {
|
|
244
|
+
try {
|
|
245
|
+
await fs.mkdir(path.dirname(this.sessionFile), { recursive: true });
|
|
246
|
+
const data = await fs.readFile(this.sessionFile, 'utf-8');
|
|
247
|
+
const parsed = JSON.parse(data);
|
|
248
|
+
// Convert plain objects back to Map with Set
|
|
249
|
+
for (const [sessionId, sessionData] of Object.entries(parsed)) {
|
|
250
|
+
this.sessions.set(sessionId, {
|
|
251
|
+
...sessionData,
|
|
252
|
+
projects: new Set(sessionData.projects || []),
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
// File doesn't exist or is invalid, start fresh
|
|
258
|
+
this.sessions.clear();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Persists session data to disk
|
|
263
|
+
*/
|
|
264
|
+
async persistSessions() {
|
|
265
|
+
try {
|
|
266
|
+
await fs.mkdir(path.dirname(this.sessionFile), { recursive: true });
|
|
267
|
+
// Convert Map with Set to plain object for JSON serialization
|
|
268
|
+
const toSerialize = {};
|
|
269
|
+
for (const [sessionId, sessionData] of this.sessions.entries()) {
|
|
270
|
+
toSerialize[sessionId] = {
|
|
271
|
+
...sessionData,
|
|
272
|
+
projects: Array.from(sessionData.projects),
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
await fs.writeFile(this.sessionFile, JSON.stringify(toSerialize, null, 2));
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
console.error('Failed to persist session data:', error);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Creates helpful error message with project suggestions
|
|
283
|
+
*/
|
|
284
|
+
async createProjectSuggestionMessage(sessionId) {
|
|
285
|
+
const existingProjects = await this.listExistingProjects();
|
|
286
|
+
const recentProjects = sessionId ? this.getRecentProjects(sessionId) : [];
|
|
287
|
+
let message = `🎯 **Project Name Required**
|
|
288
|
+
|
|
289
|
+
To keep your conversations and research organized, please specify a project name.
|
|
290
|
+
|
|
291
|
+
**Option 1 - Add to your query:**
|
|
292
|
+
\`\`\`
|
|
293
|
+
Ask Perplexity: "Your question here" (project_name: "my-project")
|
|
294
|
+
\`\`\`
|
|
295
|
+
`;
|
|
296
|
+
if (recentProjects.length > 0) {
|
|
297
|
+
message += `\n**Option 2 - Recent projects from your session:**\n`;
|
|
298
|
+
recentProjects.slice(0, 5).forEach(project => {
|
|
299
|
+
message += `- \`${project}\`\n`;
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
if (existingProjects.length > 0) {
|
|
303
|
+
message += `\n**Option 3 - Existing projects:**\n`;
|
|
304
|
+
existingProjects.slice(0, 10).forEach(project => {
|
|
305
|
+
message += `- \`${project}\`\n`;
|
|
306
|
+
});
|
|
307
|
+
if (existingProjects.length > 10) {
|
|
308
|
+
message += `... and ${existingProjects.length - 10} more (use list_projects_perplexity to see all)\n`;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
message += `
|
|
312
|
+
**Option 4 - Run from project directory:**
|
|
313
|
+
Make sure you're in your project folder when using this tool for auto-detection.
|
|
314
|
+
|
|
315
|
+
**Tips:**
|
|
316
|
+
- Use consistent naming (e.g., "my-website", "ai-research")
|
|
317
|
+
- Project names are normalized to lowercase with dashes
|
|
318
|
+
- All conversations, reports, and jobs are organized by project`;
|
|
319
|
+
return message;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Gets the storage path for a specific project
|
|
323
|
+
*/
|
|
324
|
+
getProjectStoragePath(projectName) {
|
|
325
|
+
return path.join(this.storageRoot, 'projects', this.normalizeProjectName(projectName));
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Deletes a project and all its data permanently
|
|
329
|
+
*/
|
|
330
|
+
async deleteProject(projectName) {
|
|
331
|
+
const normalizedName = this.normalizeProjectName(projectName);
|
|
332
|
+
const projectPath = this.getProjectStoragePath(normalizedName);
|
|
333
|
+
try {
|
|
334
|
+
// First, check if project exists
|
|
335
|
+
await fs.access(projectPath);
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
return {
|
|
339
|
+
deleted: false,
|
|
340
|
+
message: `Project "${normalizedName}" does not exist.`,
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
try {
|
|
344
|
+
// Get stats before deletion
|
|
345
|
+
const stats = await this.getProjectStats(normalizedName);
|
|
346
|
+
// Remove the entire project directory
|
|
347
|
+
await fs.rm(projectPath, { recursive: true, force: true });
|
|
348
|
+
// Clean up from all sessions
|
|
349
|
+
for (const sessionData of this.sessions.values()) {
|
|
350
|
+
if (sessionData.currentProject === normalizedName) {
|
|
351
|
+
delete sessionData.currentProject;
|
|
352
|
+
}
|
|
353
|
+
sessionData.projects.delete(normalizedName);
|
|
354
|
+
}
|
|
355
|
+
await this.persistSessions();
|
|
356
|
+
return {
|
|
357
|
+
deleted: true,
|
|
358
|
+
message: `Project "${normalizedName}" and all its data have been permanently deleted.`,
|
|
359
|
+
stats,
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
return {
|
|
364
|
+
deleted: false,
|
|
365
|
+
message: `Failed to delete project "${normalizedName}": ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Gets statistics for a specific project
|
|
371
|
+
*/
|
|
372
|
+
async getProjectStats(projectName) {
|
|
373
|
+
const projectPath = this.getProjectStoragePath(projectName);
|
|
374
|
+
const stats = {
|
|
375
|
+
chatCount: 0,
|
|
376
|
+
reportCount: 0,
|
|
377
|
+
jobCount: 0,
|
|
378
|
+
totalFiles: 0,
|
|
379
|
+
};
|
|
380
|
+
try {
|
|
381
|
+
// Count chats
|
|
382
|
+
const chatsDir = path.join(projectPath, 'chats');
|
|
383
|
+
try {
|
|
384
|
+
const chatFiles = await fs.readdir(chatsDir);
|
|
385
|
+
stats.chatCount = chatFiles.filter(f => f.endsWith('.json')).length;
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
// Directory doesn't exist
|
|
389
|
+
}
|
|
390
|
+
// Count reports
|
|
391
|
+
const reportsDir = path.join(projectPath, 'reports');
|
|
392
|
+
try {
|
|
393
|
+
const reportFiles = await fs.readdir(reportsDir);
|
|
394
|
+
stats.reportCount = reportFiles.filter(f => f.endsWith('.json')).length;
|
|
395
|
+
}
|
|
396
|
+
catch {
|
|
397
|
+
// Directory doesn't exist
|
|
398
|
+
}
|
|
399
|
+
// Count async jobs
|
|
400
|
+
const jobsDir = path.join(projectPath, 'async-jobs');
|
|
401
|
+
try {
|
|
402
|
+
const jobFiles = await fs.readdir(jobsDir);
|
|
403
|
+
stats.jobCount = jobFiles.filter(f => f.endsWith('.json')).length;
|
|
404
|
+
}
|
|
405
|
+
catch {
|
|
406
|
+
// Directory doesn't exist
|
|
407
|
+
}
|
|
408
|
+
stats.totalFiles = stats.chatCount + stats.reportCount + stats.jobCount;
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
// Error reading project stats
|
|
412
|
+
}
|
|
413
|
+
return stats;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
export class ProjectDetectionError extends Error {
|
|
417
|
+
constructor(message) {
|
|
418
|
+
super(message);
|
|
419
|
+
this.name = 'ProjectDetectionError';
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=project-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-manager.js","sourceRoot":"","sources":["../src/project-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Simple streaming helper that sends LoggingMessageNotifications via STDIO
|
|
4
|
+
* This should work with Claude Code without requiring HTTP/SSE or OAuth
|
|
5
|
+
*/
|
|
6
|
+
export declare class SimpleStreaming {
|
|
7
|
+
private server;
|
|
8
|
+
constructor(server: Server);
|
|
9
|
+
/**
|
|
10
|
+
* Send a streaming message to Claude Code
|
|
11
|
+
*/
|
|
12
|
+
sendMessage(message: string): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Stream content in chunks with delays for a typewriter effect
|
|
15
|
+
*/
|
|
16
|
+
streamContent(content: string, chunkSize?: number, delayMs?: number): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Wrap a tool handler with streaming capabilities
|
|
19
|
+
*/
|
|
20
|
+
wrapWithStreaming<T>(toolName: string, handler: () => Promise<T>, startMessage?: string): Promise<T>;
|
|
21
|
+
/**
|
|
22
|
+
* Split text into chunks
|
|
23
|
+
*/
|
|
24
|
+
private chunkText;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=simple-streaming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-streaming.d.ts","sourceRoot":"","sources":["../src/simple-streaming.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAMxE;;;GAGG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAElC;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBjD;;OAEG;IACG,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAY,EACvB,OAAO,GAAE,MAAW,GACnB,OAAO,CAAC,IAAI,CAAC;IAWhB;;OAEG;IACG,iBAAiB,CAAC,CAAC,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,CAAC,CAAC;IAmBb;;OAEG;IACH,OAAO,CAAC,SAAS;CAOlB"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple streaming helper that sends LoggingMessageNotifications via STDIO
|
|
3
|
+
* This should work with Claude Code without requiring HTTP/SSE or OAuth
|
|
4
|
+
*/
|
|
5
|
+
export class SimpleStreaming {
|
|
6
|
+
server;
|
|
7
|
+
constructor(server) {
|
|
8
|
+
this.server = server;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Send a streaming message to Claude Code
|
|
12
|
+
*/
|
|
13
|
+
async sendMessage(message) {
|
|
14
|
+
try {
|
|
15
|
+
const notification = {
|
|
16
|
+
method: 'notifications/message',
|
|
17
|
+
params: {
|
|
18
|
+
level: 'info',
|
|
19
|
+
data: message,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
const rpcNotification = {
|
|
23
|
+
...notification,
|
|
24
|
+
jsonrpc: '2.0',
|
|
25
|
+
};
|
|
26
|
+
// Send the notification via the server's transport
|
|
27
|
+
await this.server.notification(rpcNotification);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error('Error sending streaming message:', error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Stream content in chunks with delays for a typewriter effect
|
|
35
|
+
*/
|
|
36
|
+
async streamContent(content, chunkSize = 100, delayMs = 50) {
|
|
37
|
+
const chunks = this.chunkText(content, chunkSize);
|
|
38
|
+
for (const chunk of chunks) {
|
|
39
|
+
await this.sendMessage(chunk);
|
|
40
|
+
if (delayMs > 0) {
|
|
41
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Wrap a tool handler with streaming capabilities
|
|
47
|
+
*/
|
|
48
|
+
async wrapWithStreaming(toolName, handler, startMessage) {
|
|
49
|
+
try {
|
|
50
|
+
// Send start message
|
|
51
|
+
await this.sendMessage(startMessage || `🚀 Starting ${toolName}...`);
|
|
52
|
+
// Execute the handler
|
|
53
|
+
const result = await handler();
|
|
54
|
+
// Send completion message
|
|
55
|
+
await this.sendMessage('✅ Complete!');
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
// Send error message
|
|
60
|
+
await this.sendMessage(`❌ Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Split text into chunks
|
|
66
|
+
*/
|
|
67
|
+
chunkText(text, chunkSize) {
|
|
68
|
+
const chunks = [];
|
|
69
|
+
for (let i = 0; i < text.length; i += chunkSize) {
|
|
70
|
+
chunks.push(text.slice(i, i + chunkSize));
|
|
71
|
+
}
|
|
72
|
+
return chunks;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=simple-streaming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-streaming.js","sourceRoot":"","sources":["../src/simple-streaming.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,OAAO,eAAe;IACN;IAApB,YAAoB,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;IAEtC;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,OAAe;QAC/B,IAAI,CAAC;YACH,MAAM,YAAY,GAA+B;gBAC/C,MAAM,EAAE,uBAAuB;gBAC/B,MAAM,EAAE;oBACN,KAAK,EAAE,MAAM;oBACb,IAAI,EAAE,OAAO;iBACd;aACF,CAAC;YAEF,MAAM,eAAe,GAAwB;gBAC3C,GAAG,YAAY;gBACf,OAAO,EAAE,KAAK;aACf,CAAC;YAEF,mDAAmD;YACnD,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CACjB,OAAe,EACf,YAAoB,GAAG,EACvB,UAAkB,EAAE;QAEpB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAElD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;gBAChB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CACrB,QAAgB,EAChB,OAAyB,EACzB,YAAqB;QAErB,IAAI,CAAC;YACH,qBAAqB;YACrB,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,IAAI,eAAe,QAAQ,KAAK,CAAC,CAAC;YAErE,sBAAsB;YACtB,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;YAE/B,0BAA0B;YAC1B,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;YAEtC,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qBAAqB;YACrB,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC7F,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,SAAS,CAAC,IAAY,EAAE,SAAiB;QAC/C,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse-index.d.ts","sourceRoot":"","sources":["../src/sse-index.ts"],"names":[],"mappings":""}
|