@memo-code/memo 0.8.5 → 0.8.7
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/web/server/main.cjs +145359 -0
- package/package.json +2 -1
- package/dist/web/server/app.controller.d.ts +0 -6
- package/dist/web/server/app.controller.js +0 -33
- package/dist/web/server/app.module.d.ts +0 -4
- package/dist/web/server/app.module.js +0 -61
- package/dist/web/server/auth/access-token.guard.d.ts +0 -9
- package/dist/web/server/auth/access-token.guard.js +0 -53
- package/dist/web/server/auth/auth.controller.d.ts +0 -18
- package/dist/web/server/auth/auth.controller.js +0 -75
- package/dist/web/server/auth/auth.module.d.ts +0 -2
- package/dist/web/server/auth/auth.module.js +0 -24
- package/dist/web/server/auth/auth.service.d.ts +0 -15
- package/dist/web/server/auth/auth.service.js +0 -146
- package/dist/web/server/auth/auth.types.d.ts +0 -26
- package/dist/web/server/auth/auth.types.js +0 -2
- package/dist/web/server/auth/public.decorator.d.ts +0 -2
- package/dist/web/server/auth/public.decorator.js +0 -7
- package/dist/web/server/chat/chat.controller.d.ts +0 -30
- package/dist/web/server/chat/chat.controller.js +0 -150
- package/dist/web/server/chat/chat.module.d.ts +0 -2
- package/dist/web/server/chat/chat.module.js +0 -26
- package/dist/web/server/chat/chat.service.d.ts +0 -61
- package/dist/web/server/chat/chat.service.js +0 -847
- package/dist/web/server/chat/chat.types.d.ts +0 -38
- package/dist/web/server/chat/chat.types.js +0 -2
- package/dist/web/server/common/constants.d.ts +0 -1
- package/dist/web/server/common/constants.js +0 -4
- package/dist/web/server/common/filters/api-error.filter.d.ts +0 -7
- package/dist/web/server/common/filters/api-error.filter.js +0 -95
- package/dist/web/server/common/interceptors/api-response.interceptor.d.ts +0 -15
- package/dist/web/server/common/interceptors/api-response.interceptor.js +0 -51
- package/dist/web/server/common/middleware/request-logging.middleware.d.ts +0 -7
- package/dist/web/server/common/middleware/request-logging.middleware.js +0 -42
- package/dist/web/server/config/memo-config.service.d.ts +0 -7
- package/dist/web/server/config/memo-config.service.js +0 -106
- package/dist/web/server/config/memo-config.types.d.ts +0 -6
- package/dist/web/server/config/memo-config.types.js +0 -2
- package/dist/web/server/config/server-config.module.d.ts +0 -2
- package/dist/web/server/config/server-config.module.js +0 -22
- package/dist/web/server/config/server-config.service.d.ts +0 -14
- package/dist/web/server/config/server-config.service.js +0 -326
- package/dist/web/server/config/server-config.service.test.d.ts +0 -1
- package/dist/web/server/config/server-config.service.test.js +0 -193
- package/dist/web/server/config/server-config.types.d.ts +0 -27
- package/dist/web/server/config/server-config.types.js +0 -2
- package/dist/web/server/main.d.ts +0 -1
- package/dist/web/server/main.js +0 -19
- package/dist/web/server/mcp/mcp.controller.d.ts +0 -38
- package/dist/web/server/mcp/mcp.controller.js +0 -126
- package/dist/web/server/mcp/mcp.module.d.ts +0 -2
- package/dist/web/server/mcp/mcp.module.js +0 -22
- package/dist/web/server/mcp/mcp.service.d.ts +0 -25
- package/dist/web/server/mcp/mcp.service.js +0 -56
- package/dist/web/server/server.d.ts +0 -18
- package/dist/web/server/server.js +0 -142
- package/dist/web/server/sessions/sessions.controller.d.ts +0 -8
- package/dist/web/server/sessions/sessions.controller.js +0 -59
- package/dist/web/server/sessions/sessions.module.d.ts +0 -2
- package/dist/web/server/sessions/sessions.module.js +0 -24
- package/dist/web/server/sessions/sessions.service.d.ts +0 -22
- package/dist/web/server/sessions/sessions.service.js +0 -217
- package/dist/web/server/sessions/sessions.types.d.ts +0 -18
- package/dist/web/server/sessions/sessions.types.js +0 -2
- package/dist/web/server/skills/skills.controller.d.ts +0 -31
- package/dist/web/server/skills/skills.controller.js +0 -86
- package/dist/web/server/skills/skills.module.d.ts +0 -2
- package/dist/web/server/skills/skills.module.js +0 -24
- package/dist/web/server/skills/skills.service.d.ts +0 -38
- package/dist/web/server/skills/skills.service.js +0 -97
- package/dist/web/server/stream/stream.module.d.ts +0 -2
- package/dist/web/server/stream/stream.module.js +0 -20
- package/dist/web/server/stream/stream.service.d.ts +0 -26
- package/dist/web/server/stream/stream.service.js +0 -166
- package/dist/web/server/tsconfig.build.tsbuildinfo +0 -1
- package/dist/web/server/workspaces/workspaces.module.d.ts +0 -2
- package/dist/web/server/workspaces/workspaces.module.js +0 -20
- package/dist/web/server/workspaces/workspaces.service.d.ts +0 -38
- package/dist/web/server/workspaces/workspaces.service.js +0 -378
- package/dist/web/server/workspaces/workspaces.types.d.ts +0 -1
- package/dist/web/server/workspaces/workspaces.types.js +0 -2
- package/dist/web/server/workspaces/workspaces.utils.d.ts +0 -1
- package/dist/web/server/workspaces/workspaces.utils.js +0 -9
- package/dist/web/server/ws/rpc-router.service.d.ts +0 -20
- package/dist/web/server/ws/rpc-router.service.js +0 -275
- package/dist/web/server/ws/session-runtime-registry.service.d.ts +0 -37
- package/dist/web/server/ws/session-runtime-registry.service.js +0 -118
- package/dist/web/server/ws/ws-event-bus.service.d.ts +0 -5
- package/dist/web/server/ws/ws-event-bus.service.js +0 -27
- package/dist/web/server/ws/ws-gateway.module.d.ts +0 -2
- package/dist/web/server/ws/ws-gateway.module.js +0 -42
- package/dist/web/server/ws/ws-gateway.service.d.ts +0 -42
- package/dist/web/server/ws/ws-gateway.service.js +0 -473
- package/dist/web/server/ws/ws.errors.d.ts +0 -8
- package/dist/web/server/ws/ws.errors.js +0 -16
- package/dist/web/server/ws/ws.types.d.ts +0 -34
- package/dist/web/server/ws/ws.types.js +0 -2
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.WorkspacesModule = void 0;
|
|
10
|
-
const common_1 = require("@nestjs/common");
|
|
11
|
-
const workspaces_service_1 = require("./workspaces.service");
|
|
12
|
-
let WorkspacesModule = class WorkspacesModule {
|
|
13
|
-
};
|
|
14
|
-
exports.WorkspacesModule = WorkspacesModule;
|
|
15
|
-
exports.WorkspacesModule = WorkspacesModule = __decorate([
|
|
16
|
-
(0, common_1.Module)({
|
|
17
|
-
providers: [workspaces_service_1.WorkspacesService],
|
|
18
|
-
exports: [workspaces_service_1.WorkspacesService],
|
|
19
|
-
})
|
|
20
|
-
], WorkspacesModule);
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { ServerConfigService } from '../config/server-config.service';
|
|
2
|
-
import type { WorkspaceFsListResult, WorkspaceRecord } from './workspaces.types';
|
|
3
|
-
export declare class WorkspacesService {
|
|
4
|
-
private readonly serverConfigService;
|
|
5
|
-
private historyHydrated;
|
|
6
|
-
constructor(serverConfigService: ServerConfigService);
|
|
7
|
-
list(): Promise<{
|
|
8
|
-
items: WorkspaceRecord[];
|
|
9
|
-
}>;
|
|
10
|
-
getById(id: string): Promise<WorkspaceRecord | null>;
|
|
11
|
-
resolveWorkspace(input: {
|
|
12
|
-
workspaceId?: string;
|
|
13
|
-
cwd?: string;
|
|
14
|
-
}): Promise<WorkspaceRecord>;
|
|
15
|
-
ensureByCwd(cwd: string, name?: string, options?: {
|
|
16
|
-
validateReadable?: boolean;
|
|
17
|
-
}): Promise<WorkspaceRecord>;
|
|
18
|
-
add(input: {
|
|
19
|
-
cwd?: unknown;
|
|
20
|
-
name?: unknown;
|
|
21
|
-
}): Promise<{
|
|
22
|
-
created: boolean;
|
|
23
|
-
item: WorkspaceRecord;
|
|
24
|
-
}>;
|
|
25
|
-
update(workspaceId: string, input: {
|
|
26
|
-
name?: unknown;
|
|
27
|
-
}): Promise<{
|
|
28
|
-
updated: boolean;
|
|
29
|
-
item: WorkspaceRecord;
|
|
30
|
-
}>;
|
|
31
|
-
remove(workspaceId: string): Promise<{
|
|
32
|
-
deleted: boolean;
|
|
33
|
-
}>;
|
|
34
|
-
touchLastUsed(workspaceId: string): Promise<void>;
|
|
35
|
-
listDirectories(pathInput: string | undefined): Promise<WorkspaceFsListResult>;
|
|
36
|
-
private hydrateFromHistoryIfNeeded;
|
|
37
|
-
private resolveReadableDirectory;
|
|
38
|
-
}
|
|
@@ -1,378 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.WorkspacesService = void 0;
|
|
13
|
-
const node_fs_1 = require("node:fs");
|
|
14
|
-
const promises_1 = require("node:fs/promises");
|
|
15
|
-
const node_os_1 = require("node:os");
|
|
16
|
-
const node_path_1 = require("node:path");
|
|
17
|
-
const common_1 = require("@nestjs/common");
|
|
18
|
-
const server_config_service_1 = require("../config/server-config.service");
|
|
19
|
-
const workspaces_utils_1 = require("./workspaces.utils");
|
|
20
|
-
const MAX_DIRECTORY_ITEMS = 200;
|
|
21
|
-
function resolveMemoHome() {
|
|
22
|
-
const memoHome = process.env.MEMO_HOME;
|
|
23
|
-
if (!memoHome || !memoHome.trim())
|
|
24
|
-
return (0, node_path_1.join)((0, node_os_1.homedir)(), '.memo');
|
|
25
|
-
if (!memoHome.startsWith('~'))
|
|
26
|
-
return memoHome;
|
|
27
|
-
return (0, node_path_1.join)((0, node_os_1.homedir)(), memoHome.slice(1));
|
|
28
|
-
}
|
|
29
|
-
function toWorkspaceRecord(input) {
|
|
30
|
-
return {
|
|
31
|
-
id: input.id,
|
|
32
|
-
name: input.name,
|
|
33
|
-
cwd: input.cwd,
|
|
34
|
-
createdAt: input.createdAt,
|
|
35
|
-
lastUsedAt: input.lastUsedAt,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
function byNameThenPath(a, b) {
|
|
39
|
-
const nameResult = a.name.localeCompare(b.name, undefined, {
|
|
40
|
-
sensitivity: 'base',
|
|
41
|
-
});
|
|
42
|
-
if (nameResult !== 0)
|
|
43
|
-
return nameResult;
|
|
44
|
-
return a.cwd.localeCompare(b.cwd);
|
|
45
|
-
}
|
|
46
|
-
function extractCwdFromHistoryLog(raw) {
|
|
47
|
-
const lines = raw.split('\n');
|
|
48
|
-
for (const line of lines) {
|
|
49
|
-
if (!line.trim())
|
|
50
|
-
continue;
|
|
51
|
-
let parsed;
|
|
52
|
-
try {
|
|
53
|
-
parsed = JSON.parse(line);
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
59
|
-
continue;
|
|
60
|
-
const event = parsed;
|
|
61
|
-
if (event.type !== 'session_start')
|
|
62
|
-
continue;
|
|
63
|
-
const meta = event.meta;
|
|
64
|
-
if (!meta || typeof meta !== 'object' || Array.isArray(meta))
|
|
65
|
-
continue;
|
|
66
|
-
const cwd = meta.cwd;
|
|
67
|
-
if (typeof cwd !== 'string' || !cwd.trim())
|
|
68
|
-
continue;
|
|
69
|
-
return (0, workspaces_utils_1.normalizeWorkspacePath)(cwd);
|
|
70
|
-
}
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
async function collectHistoryCwds() {
|
|
74
|
-
const sessionsDir = (0, node_path_1.join)(resolveMemoHome(), 'sessions');
|
|
75
|
-
const results = new Set();
|
|
76
|
-
const walk = async (dirPath) => {
|
|
77
|
-
let entries;
|
|
78
|
-
try {
|
|
79
|
-
entries = await (0, promises_1.readdir)(dirPath, { withFileTypes: true });
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
for (const entry of entries) {
|
|
85
|
-
if (entry.isSymbolicLink())
|
|
86
|
-
continue;
|
|
87
|
-
const fullPath = (0, node_path_1.join)(dirPath, entry.name);
|
|
88
|
-
if (entry.isDirectory()) {
|
|
89
|
-
await walk(fullPath);
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
if (!entry.isFile() || !entry.name.endsWith('.jsonl'))
|
|
93
|
-
continue;
|
|
94
|
-
try {
|
|
95
|
-
const raw = await (0, promises_1.readFile)(fullPath, 'utf8');
|
|
96
|
-
const cwd = extractCwdFromHistoryLog(raw);
|
|
97
|
-
if (cwd) {
|
|
98
|
-
results.add(cwd);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
await walk((0, node_path_1.resolve)(sessionsDir));
|
|
106
|
-
return Array.from(results.values()).sort((a, b) => a.localeCompare(b));
|
|
107
|
-
}
|
|
108
|
-
function isWithinRoot(path, rootPath) {
|
|
109
|
-
const normalizedPath = (0, workspaces_utils_1.normalizeWorkspacePath)(path);
|
|
110
|
-
const normalizedRoot = (0, workspaces_utils_1.normalizeWorkspacePath)(rootPath);
|
|
111
|
-
if (normalizedRoot === '/')
|
|
112
|
-
return true;
|
|
113
|
-
if (normalizedPath === normalizedRoot)
|
|
114
|
-
return true;
|
|
115
|
-
return normalizedPath.startsWith(`${normalizedRoot}/`);
|
|
116
|
-
}
|
|
117
|
-
let WorkspacesService = class WorkspacesService {
|
|
118
|
-
serverConfigService;
|
|
119
|
-
historyHydrated = false;
|
|
120
|
-
constructor(serverConfigService) {
|
|
121
|
-
this.serverConfigService = serverConfigService;
|
|
122
|
-
}
|
|
123
|
-
async list() {
|
|
124
|
-
await this.hydrateFromHistoryIfNeeded();
|
|
125
|
-
const config = await this.serverConfigService.load();
|
|
126
|
-
return {
|
|
127
|
-
items: config.workspaces.map(toWorkspaceRecord).sort(byNameThenPath),
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
async getById(id) {
|
|
131
|
-
const target = id.trim();
|
|
132
|
-
if (!target)
|
|
133
|
-
return null;
|
|
134
|
-
const config = await this.serverConfigService.load();
|
|
135
|
-
const found = config.workspaces.find((item) => item.id === target);
|
|
136
|
-
return found ? toWorkspaceRecord(found) : null;
|
|
137
|
-
}
|
|
138
|
-
async resolveWorkspace(input) {
|
|
139
|
-
const workspaceId = input.workspaceId?.trim();
|
|
140
|
-
if (workspaceId) {
|
|
141
|
-
const found = await this.getById(workspaceId);
|
|
142
|
-
if (!found) {
|
|
143
|
-
throw new common_1.NotFoundException(`workspace not found: ${workspaceId}`);
|
|
144
|
-
}
|
|
145
|
-
return found;
|
|
146
|
-
}
|
|
147
|
-
const cwd = input.cwd?.trim();
|
|
148
|
-
if (cwd) {
|
|
149
|
-
return this.ensureByCwd(cwd);
|
|
150
|
-
}
|
|
151
|
-
throw new common_1.BadRequestException('workspaceId is required');
|
|
152
|
-
}
|
|
153
|
-
async ensureByCwd(cwd, name, options) {
|
|
154
|
-
const normalizedCwd = options?.validateReadable === false
|
|
155
|
-
? (0, workspaces_utils_1.normalizeWorkspacePath)(cwd)
|
|
156
|
-
: await this.resolveReadableDirectory(cwd);
|
|
157
|
-
const id = (0, workspaces_utils_1.workspaceIdFromCwd)(normalizedCwd);
|
|
158
|
-
const existing = await this.getById(id);
|
|
159
|
-
if (existing) {
|
|
160
|
-
if (name && name.trim() && existing.name !== name.trim()) {
|
|
161
|
-
const renamed = await this.update(existing.id, { name });
|
|
162
|
-
return renamed.item;
|
|
163
|
-
}
|
|
164
|
-
return existing;
|
|
165
|
-
}
|
|
166
|
-
const now = new Date().toISOString();
|
|
167
|
-
const next = {
|
|
168
|
-
id,
|
|
169
|
-
cwd: normalizedCwd,
|
|
170
|
-
name: (0, workspaces_utils_1.normalizeWorkspaceName)(name ?? (0, workspaces_utils_1.defaultWorkspaceName)(normalizedCwd), normalizedCwd),
|
|
171
|
-
createdAt: now,
|
|
172
|
-
lastUsedAt: now,
|
|
173
|
-
};
|
|
174
|
-
await this.serverConfigService.updateConfig((config) => {
|
|
175
|
-
return {
|
|
176
|
-
...config,
|
|
177
|
-
workspaces: [...config.workspaces, next].sort((a, b) => a.cwd.localeCompare(b.cwd)),
|
|
178
|
-
};
|
|
179
|
-
});
|
|
180
|
-
return next;
|
|
181
|
-
}
|
|
182
|
-
async add(input) {
|
|
183
|
-
const cwd = typeof input.cwd === 'string' ? input.cwd.trim() : '';
|
|
184
|
-
if (!cwd) {
|
|
185
|
-
throw new common_1.BadRequestException('cwd is required');
|
|
186
|
-
}
|
|
187
|
-
const name = typeof input.name === 'string' ? input.name.trim() : undefined;
|
|
188
|
-
const item = await this.ensureByCwd(cwd, name);
|
|
189
|
-
return { created: true, item };
|
|
190
|
-
}
|
|
191
|
-
async update(workspaceId, input) {
|
|
192
|
-
const id = workspaceId.trim();
|
|
193
|
-
if (!id) {
|
|
194
|
-
throw new common_1.BadRequestException('workspaceId is required');
|
|
195
|
-
}
|
|
196
|
-
const found = await this.getById(id);
|
|
197
|
-
if (!found) {
|
|
198
|
-
throw new common_1.NotFoundException('workspace not found');
|
|
199
|
-
}
|
|
200
|
-
const name = typeof input.name === 'string' ? input.name.trim() : '';
|
|
201
|
-
if (!name) {
|
|
202
|
-
throw new common_1.BadRequestException('name is required');
|
|
203
|
-
}
|
|
204
|
-
const next = {
|
|
205
|
-
...found,
|
|
206
|
-
name,
|
|
207
|
-
lastUsedAt: new Date().toISOString(),
|
|
208
|
-
};
|
|
209
|
-
await this.serverConfigService.updateConfig((config) => ({
|
|
210
|
-
...config,
|
|
211
|
-
workspaces: config.workspaces.map((item) => item.id === id ? next : item),
|
|
212
|
-
}));
|
|
213
|
-
return { updated: true, item: next };
|
|
214
|
-
}
|
|
215
|
-
async remove(workspaceId) {
|
|
216
|
-
const id = workspaceId.trim();
|
|
217
|
-
if (!id) {
|
|
218
|
-
throw new common_1.BadRequestException('workspaceId is required');
|
|
219
|
-
}
|
|
220
|
-
const found = await this.getById(id);
|
|
221
|
-
if (!found) {
|
|
222
|
-
throw new common_1.NotFoundException('workspace not found');
|
|
223
|
-
}
|
|
224
|
-
await this.serverConfigService.updateConfig((config) => ({
|
|
225
|
-
...config,
|
|
226
|
-
workspaces: config.workspaces.filter((item) => item.id !== id),
|
|
227
|
-
}));
|
|
228
|
-
return { deleted: true };
|
|
229
|
-
}
|
|
230
|
-
async touchLastUsed(workspaceId) {
|
|
231
|
-
const id = workspaceId.trim();
|
|
232
|
-
if (!id)
|
|
233
|
-
return;
|
|
234
|
-
await this.serverConfigService.updateConfig((config) => ({
|
|
235
|
-
...config,
|
|
236
|
-
workspaces: config.workspaces.map((item) => item.id === id
|
|
237
|
-
? {
|
|
238
|
-
...item,
|
|
239
|
-
lastUsedAt: new Date().toISOString(),
|
|
240
|
-
}
|
|
241
|
-
: item),
|
|
242
|
-
}));
|
|
243
|
-
}
|
|
244
|
-
async listDirectories(pathInput) {
|
|
245
|
-
const config = await this.serverConfigService.load();
|
|
246
|
-
const rootPath = config.workspaceBrowser.rootPath || '/';
|
|
247
|
-
const rootRealPath = await this.resolveReadableDirectory(rootPath);
|
|
248
|
-
let requestedPath = pathInput?.trim() ? pathInput.trim() : rootRealPath;
|
|
249
|
-
if (!pathInput?.trim() && rootRealPath === '/') {
|
|
250
|
-
try {
|
|
251
|
-
requestedPath = await this.resolveReadableDirectory((0, node_os_1.homedir)());
|
|
252
|
-
}
|
|
253
|
-
catch {
|
|
254
|
-
requestedPath = rootRealPath;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
const targetPath = await this.resolveReadableDirectory(requestedPath);
|
|
258
|
-
if (!isWithinRoot(targetPath, rootRealPath)) {
|
|
259
|
-
throw new common_1.BadRequestException('path is outside workspace browser root');
|
|
260
|
-
}
|
|
261
|
-
let entries;
|
|
262
|
-
try {
|
|
263
|
-
entries = await (0, promises_1.readdir)(targetPath, { withFileTypes: true });
|
|
264
|
-
}
|
|
265
|
-
catch {
|
|
266
|
-
throw new common_1.BadRequestException('failed to read directory');
|
|
267
|
-
}
|
|
268
|
-
const sortedEntries = entries
|
|
269
|
-
.filter((entry) => !entry.name.startsWith('.'))
|
|
270
|
-
.sort((a, b) => a.name.localeCompare(b.name, undefined, { sensitivity: 'base' }));
|
|
271
|
-
const items = [];
|
|
272
|
-
for (const entry of sortedEntries) {
|
|
273
|
-
if (items.length >= MAX_DIRECTORY_ITEMS)
|
|
274
|
-
break;
|
|
275
|
-
const candidate = (0, node_path_1.resolve)(targetPath, entry.name);
|
|
276
|
-
let directoryPath = null;
|
|
277
|
-
if (entry.isDirectory()) {
|
|
278
|
-
directoryPath = (0, workspaces_utils_1.normalizeWorkspacePath)(candidate);
|
|
279
|
-
}
|
|
280
|
-
else if (entry.isSymbolicLink()) {
|
|
281
|
-
try {
|
|
282
|
-
const linked = (0, workspaces_utils_1.normalizeWorkspacePath)(await (0, promises_1.realpath)(candidate));
|
|
283
|
-
const linkedStat = await (0, promises_1.stat)(linked);
|
|
284
|
-
if (!linkedStat.isDirectory())
|
|
285
|
-
continue;
|
|
286
|
-
if (!isWithinRoot(linked, rootRealPath))
|
|
287
|
-
continue;
|
|
288
|
-
directoryPath = linked;
|
|
289
|
-
}
|
|
290
|
-
catch {
|
|
291
|
-
continue;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
continue;
|
|
296
|
-
}
|
|
297
|
-
if (!directoryPath)
|
|
298
|
-
continue;
|
|
299
|
-
let readable = true;
|
|
300
|
-
try {
|
|
301
|
-
await (0, promises_1.access)(directoryPath, node_fs_1.constants.R_OK | node_fs_1.constants.X_OK);
|
|
302
|
-
}
|
|
303
|
-
catch {
|
|
304
|
-
readable = false;
|
|
305
|
-
}
|
|
306
|
-
items.push({
|
|
307
|
-
name: entry.name,
|
|
308
|
-
path: directoryPath,
|
|
309
|
-
kind: 'dir',
|
|
310
|
-
readable,
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
const parent = (0, node_path_1.dirname)(targetPath);
|
|
314
|
-
const parentPath = targetPath === rootRealPath || !isWithinRoot(parent, rootRealPath)
|
|
315
|
-
? null
|
|
316
|
-
: (0, workspaces_utils_1.normalizeWorkspacePath)(parent);
|
|
317
|
-
return {
|
|
318
|
-
path: (0, workspaces_utils_1.normalizeWorkspacePath)(targetPath),
|
|
319
|
-
parentPath,
|
|
320
|
-
items,
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
async hydrateFromHistoryIfNeeded() {
|
|
324
|
-
if (this.historyHydrated)
|
|
325
|
-
return;
|
|
326
|
-
this.historyHydrated = true;
|
|
327
|
-
const config = await this.serverConfigService.load();
|
|
328
|
-
if (config.workspaces.length > 0)
|
|
329
|
-
return;
|
|
330
|
-
const cwds = await collectHistoryCwds();
|
|
331
|
-
if (cwds.length === 0)
|
|
332
|
-
return;
|
|
333
|
-
const now = new Date().toISOString();
|
|
334
|
-
const hydrated = cwds.map((cwd) => ({
|
|
335
|
-
id: (0, workspaces_utils_1.workspaceIdFromCwd)(cwd),
|
|
336
|
-
cwd,
|
|
337
|
-
name: (0, workspaces_utils_1.defaultWorkspaceName)(cwd),
|
|
338
|
-
createdAt: now,
|
|
339
|
-
lastUsedAt: now,
|
|
340
|
-
}));
|
|
341
|
-
await this.serverConfigService.updateConfig((current) => ({
|
|
342
|
-
...current,
|
|
343
|
-
workspaces: hydrated,
|
|
344
|
-
}));
|
|
345
|
-
}
|
|
346
|
-
async resolveReadableDirectory(path) {
|
|
347
|
-
const normalizedPath = (0, workspaces_utils_1.normalizeWorkspacePath)(path);
|
|
348
|
-
let realPath;
|
|
349
|
-
try {
|
|
350
|
-
realPath = (0, workspaces_utils_1.normalizeWorkspacePath)(await (0, promises_1.realpath)(normalizedPath));
|
|
351
|
-
}
|
|
352
|
-
catch {
|
|
353
|
-
throw new common_1.BadRequestException(`directory does not exist: ${path}`);
|
|
354
|
-
}
|
|
355
|
-
let directoryStat;
|
|
356
|
-
try {
|
|
357
|
-
directoryStat = await (0, promises_1.stat)(realPath);
|
|
358
|
-
}
|
|
359
|
-
catch {
|
|
360
|
-
throw new common_1.BadRequestException(`directory is not accessible: ${path}`);
|
|
361
|
-
}
|
|
362
|
-
if (!directoryStat.isDirectory()) {
|
|
363
|
-
throw new common_1.BadRequestException(`path is not a directory: ${path}`);
|
|
364
|
-
}
|
|
365
|
-
try {
|
|
366
|
-
await (0, promises_1.access)(realPath, node_fs_1.constants.R_OK | node_fs_1.constants.X_OK);
|
|
367
|
-
}
|
|
368
|
-
catch {
|
|
369
|
-
throw new common_1.BadRequestException(`directory is not readable: ${path}`);
|
|
370
|
-
}
|
|
371
|
-
return realPath;
|
|
372
|
-
}
|
|
373
|
-
};
|
|
374
|
-
exports.WorkspacesService = WorkspacesService;
|
|
375
|
-
exports.WorkspacesService = WorkspacesService = __decorate([
|
|
376
|
-
(0, common_1.Injectable)(),
|
|
377
|
-
__metadata("design:paramtypes", [server_config_service_1.ServerConfigService])
|
|
378
|
-
], WorkspacesService);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type { WorkspaceDirEntry, WorkspaceFsListResult, WorkspaceRecord, SessionRuntimeBadge, } from '@memo-code/core';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { cwdBelongsToWorkspace, defaultWorkspaceName, normalizeWorkspaceName, normalizeWorkspacePath, workspaceIdFromCwd, } from '@memo-code/core';
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.workspaceIdFromCwd = exports.normalizeWorkspacePath = exports.normalizeWorkspaceName = exports.defaultWorkspaceName = exports.cwdBelongsToWorkspace = void 0;
|
|
4
|
-
var core_1 = require("@memo-code/core");
|
|
5
|
-
Object.defineProperty(exports, "cwdBelongsToWorkspace", { enumerable: true, get: function () { return core_1.cwdBelongsToWorkspace; } });
|
|
6
|
-
Object.defineProperty(exports, "defaultWorkspaceName", { enumerable: true, get: function () { return core_1.defaultWorkspaceName; } });
|
|
7
|
-
Object.defineProperty(exports, "normalizeWorkspaceName", { enumerable: true, get: function () { return core_1.normalizeWorkspaceName; } });
|
|
8
|
-
Object.defineProperty(exports, "normalizeWorkspacePath", { enumerable: true, get: function () { return core_1.normalizeWorkspacePath; } });
|
|
9
|
-
Object.defineProperty(exports, "workspaceIdFromCwd", { enumerable: true, get: function () { return core_1.workspaceIdFromCwd; } });
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { ChatService } from '../chat/chat.service';
|
|
2
|
-
import { McpService } from '../mcp/mcp.service';
|
|
3
|
-
import { SessionsService } from '../sessions/sessions.service';
|
|
4
|
-
import { SkillsService } from '../skills/skills.service';
|
|
5
|
-
import { WorkspacesService } from '../workspaces/workspaces.service';
|
|
6
|
-
import { SessionRuntimeRegistry } from './session-runtime-registry.service';
|
|
7
|
-
export type RpcCallContext = {
|
|
8
|
-
connectionId: string;
|
|
9
|
-
username: string;
|
|
10
|
-
};
|
|
11
|
-
export declare class RpcRouterService {
|
|
12
|
-
private readonly sessionsService;
|
|
13
|
-
private readonly chatService;
|
|
14
|
-
private readonly mcpService;
|
|
15
|
-
private readonly skillsService;
|
|
16
|
-
private readonly workspacesService;
|
|
17
|
-
private readonly sessionRegistry;
|
|
18
|
-
constructor(sessionsService: SessionsService, chatService: ChatService, mcpService: McpService, skillsService: SkillsService, workspacesService: WorkspacesService, sessionRegistry: SessionRuntimeRegistry);
|
|
19
|
-
dispatch(context: RpcCallContext, method: string, params: unknown): Promise<unknown>;
|
|
20
|
-
}
|