@myagentroam/node 0.11.0 → 0.11.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.
- package/dist/connector.js +20 -25
- package/dist/database.js +53 -31
- package/dist/migrations/v021.js +64 -0
- package/dist/service/node-run-event-bridge.js +0 -113
- package/dist/service/node-workspace-coordinator.js +21 -3
- package/dist/service/scheduled-session-coordinator.js +10 -12
- package/dist/service/skill-directory-service.js +2 -2
- package/dist/service/skill-install-service.js +15 -7
- package/dist/service/skill-node-operation-service.js +5 -4
- package/dist/service/workbench-event-projection.js +112 -0
- package/dist/service/workbench-event-service.js +24 -7
- package/dist/service/workspace-change-service.js +29 -13
- package/dist/service/workspace-file-service.js +3 -1
- package/dist/service/workspace-git-exclude-service.js +59 -32
- package/dist/service/workspace-service.js +34 -9
- package/dist/service/workspace-watch-snapshot-service.js +35 -5
- package/dist/service/workspace-workbench-service.js +23 -11
- package/dist/terminal.js +13 -12
- package/dist/workspace.js +27 -3
- package/package.json +4 -4
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
|
-
import {
|
|
2
|
+
import { isAbsolute, win32 } from 'node:path';
|
|
3
|
+
import { listGitHistoryRefs, normalizeFilePreviewPath, openGitHistoryFileContent, readGitHistory, readGitHistoryFileDiff, readGitHistoryFileContentRange, readGitHistoryFiles, readCurrentChangeDiff, readRestrictedDiff, resolveGitRepository, resolveGitRepositoryTarget, resolveWorkspaceGitRoot, restoreCurrentChange } from '../workspace.js';
|
|
3
4
|
import { WorkspaceCodeNavigationService } from './workspace-code-navigation-service.js';
|
|
4
5
|
import { WorkspaceContentSearchService } from './workspace-content-search-service.js';
|
|
5
6
|
import { WorkspaceWatchController } from './workspace-watch-controller.js';
|
|
@@ -98,7 +99,7 @@ export class WorkspaceWorkbenchService {
|
|
|
98
99
|
}
|
|
99
100
|
async readPredictionFile(workspaceId, path, worktreePath) {
|
|
100
101
|
const workspace = this.options.requireWorkspace(workspaceId);
|
|
101
|
-
const repository = await this.fileRepository(workspace, worktreePath ? { worktreePath } : {});
|
|
102
|
+
const repository = await this.fileRepository(workspace, worktreePath ? { worktreePath, path } : {});
|
|
102
103
|
const { readWorkspaceTextFile } = await import('../workspace.js');
|
|
103
104
|
return readWorkspaceTextFile(repository, path, 0, 64 * 1024);
|
|
104
105
|
}
|
|
@@ -180,7 +181,7 @@ export class WorkspaceWorkbenchService {
|
|
|
180
181
|
(input.worktreePath !== undefined && typeof input.worktreePath !== 'string'))
|
|
181
182
|
throw new Error('GIT_DIFF_INVALID');
|
|
182
183
|
const workspace = this.gitWorkspace(input.workspaceId);
|
|
183
|
-
const repository = await resolveGitRepositoryTarget(workspace.path, input.repositoryPath ?? '', input.worktreePath);
|
|
184
|
+
const repository = await resolveGitRepositoryTarget(await resolveWorkspaceGitRoot(workspace.path, workspace.includeParentRepository ?? true), input.repositoryPath ?? '', input.worktreePath);
|
|
184
185
|
return { diff: await readCurrentChangeDiff(repository, input.path) };
|
|
185
186
|
}
|
|
186
187
|
async restoreChange(input) {
|
|
@@ -191,7 +192,7 @@ export class WorkspaceWorkbenchService {
|
|
|
191
192
|
(input.state !== 'STAGED' && input.state !== 'UNSTAGED' && input.state !== 'UNTRACKED'))
|
|
192
193
|
throw new Error('GIT_CHANGE_RESTORE_UNAVAILABLE');
|
|
193
194
|
const workspace = this.gitWorkspace(input.workspaceId);
|
|
194
|
-
const repository = await resolveGitRepositoryTarget(workspace.path, input.repositoryPath ?? '', input.worktreePath);
|
|
195
|
+
const repository = await resolveGitRepositoryTarget(await resolveWorkspaceGitRoot(workspace.path, workspace.includeParentRepository ?? true), input.repositoryPath ?? '', input.worktreePath);
|
|
195
196
|
await restoreCurrentChange(repository, input.path, input.state);
|
|
196
197
|
this.options.invalidate(workspace.id);
|
|
197
198
|
return { restored: true };
|
|
@@ -201,14 +202,22 @@ export class WorkspaceWorkbenchService {
|
|
|
201
202
|
(input.repositoryPath !== undefined && typeof input.repositoryPath !== 'string'))
|
|
202
203
|
throw new Error('GIT_REPOSITORY_INVALID');
|
|
203
204
|
const workspace = this.gitWorkspace(input.workspaceId);
|
|
204
|
-
return resolveGitRepository(workspace.path, input.repositoryPath ?? '');
|
|
205
|
+
return resolveGitRepository(await resolveWorkspaceGitRoot(workspace.path, workspace.includeParentRepository ?? true), input.repositoryPath ?? '');
|
|
205
206
|
}
|
|
206
207
|
async fileRepository(workspace, input) {
|
|
207
|
-
if (input.worktreePath === undefined)
|
|
208
|
+
if (input.worktreePath === undefined && input.repositoryPath === undefined)
|
|
208
209
|
return workspace.path;
|
|
209
|
-
if (typeof input.worktreePath !== 'string')
|
|
210
|
+
if ((input.worktreePath !== undefined && typeof input.worktreePath !== 'string') ||
|
|
211
|
+
(input.repositoryPath !== undefined && typeof input.repositoryPath !== 'string'))
|
|
210
212
|
throw new Error('GIT_REPOSITORY_INVALID');
|
|
211
|
-
|
|
213
|
+
if (typeof input.path !== 'string' ||
|
|
214
|
+
input.path.startsWith('mar-attachment:') ||
|
|
215
|
+
input.previewDirectory !== undefined)
|
|
216
|
+
throw new Error('FILE_PATH_ESCAPE');
|
|
217
|
+
const path = normalizeFilePreviewPath(input.path);
|
|
218
|
+
if (isAbsolute(path) || win32.isAbsolute(path))
|
|
219
|
+
throw new Error('FILE_PATH_ESCAPE');
|
|
220
|
+
return resolveGitRepositoryTarget(await resolveWorkspaceGitRoot(workspace.path, workspace.includeParentRepository ?? true), input.repositoryPath ?? '', input.worktreePath);
|
|
212
221
|
}
|
|
213
222
|
refs(input) {
|
|
214
223
|
if (input.refs === undefined)
|
|
@@ -280,6 +289,9 @@ export class WorkspaceWorkbenchService {
|
|
|
280
289
|
const input = {
|
|
281
290
|
workspaceId: workspace.id,
|
|
282
291
|
path: descriptor.resource.path,
|
|
292
|
+
...(descriptor.resource.repositoryPath === undefined
|
|
293
|
+
? {}
|
|
294
|
+
: { repositoryPath: descriptor.resource.repositoryPath }),
|
|
283
295
|
...(descriptor.resource.worktreePath === undefined
|
|
284
296
|
? {}
|
|
285
297
|
: { worktreePath: descriptor.resource.worktreePath })
|
|
@@ -372,12 +384,12 @@ export class WorkspaceWorkbenchService {
|
|
|
372
384
|
typeof input.toRef !== 'string')
|
|
373
385
|
throw new Error('GIT_DIFF_INVALID');
|
|
374
386
|
const workspace = this.gitWorkspace(input.workspaceId);
|
|
375
|
-
return {
|
|
387
|
+
return {
|
|
388
|
+
diff: await readRestrictedDiff(await resolveWorkspaceGitRoot(workspace.path, workspace.includeParentRepository ?? true), input.fromRef, input.toRef)
|
|
389
|
+
};
|
|
376
390
|
}
|
|
377
391
|
gitWorkspace(workspaceId) {
|
|
378
392
|
const workspace = this.options.requireWorkspace(workspaceId);
|
|
379
|
-
if (workspace.kind !== 'GIT_WORKSPACE')
|
|
380
|
-
throw new Error('WORKSPACE_NOT_GIT');
|
|
381
393
|
return workspace;
|
|
382
394
|
}
|
|
383
395
|
}
|
package/dist/terminal.js
CHANGED
|
@@ -318,17 +318,14 @@ export class TerminalManager {
|
|
|
318
318
|
const summary = this.notifySummary(terminal);
|
|
319
319
|
try {
|
|
320
320
|
if (terminal.pty !== undefined) {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
}
|
|
326
|
-
catch {
|
|
327
|
-
await this.terminate(terminal.pty, this.platform);
|
|
328
|
-
}
|
|
321
|
+
// Native PTY hangup reaches POSIX foreground jobs in a separate process group
|
|
322
|
+
// and releases the native console on Windows; shell-group TERM cannot do this.
|
|
323
|
+
try {
|
|
324
|
+
terminal.pty.kill();
|
|
329
325
|
}
|
|
330
|
-
|
|
326
|
+
catch {
|
|
331
327
|
await this.terminate(terminal.pty, this.platform);
|
|
328
|
+
}
|
|
332
329
|
}
|
|
333
330
|
if (terminal.pipe !== undefined)
|
|
334
331
|
await this.terminate(terminal.pipe, this.platform);
|
|
@@ -338,13 +335,17 @@ export class TerminalManager {
|
|
|
338
335
|
}
|
|
339
336
|
return summary;
|
|
340
337
|
}
|
|
338
|
+
/** Ends current terminals without disposing the manager's idle collection. */
|
|
339
|
+
async closeAll() {
|
|
340
|
+
await Promise.all([...this.terminals.values()]
|
|
341
|
+
.filter((terminal) => terminal.state === 'RUNNING')
|
|
342
|
+
.map((terminal) => this.close(terminal.id)));
|
|
343
|
+
}
|
|
341
344
|
async shutdown() {
|
|
342
345
|
if (this.idleTimer !== undefined)
|
|
343
346
|
clearInterval(this.idleTimer);
|
|
344
347
|
this.idleTimer = undefined;
|
|
345
|
-
await
|
|
346
|
-
.filter((terminal) => terminal.state === 'RUNNING')
|
|
347
|
-
.map((terminal) => this.close(terminal.id)));
|
|
348
|
+
await this.closeAll();
|
|
348
349
|
}
|
|
349
350
|
onFrame(listener) {
|
|
350
351
|
this.frameListeners.add(listener);
|
package/dist/workspace.js
CHANGED
|
@@ -1187,7 +1187,7 @@ export function isWithinAllowedRoot(target, roots, platform = hostPlatform()) {
|
|
|
1187
1187
|
});
|
|
1188
1188
|
}
|
|
1189
1189
|
/** Resolving both candidate and roots rejects Linux symlinks which point outside a root. */
|
|
1190
|
-
export async function inspectWorkspace(requestedPath, allowedRoots) {
|
|
1190
|
+
export async function inspectWorkspace(requestedPath, allowedRoots, includeParentRepository = true) {
|
|
1191
1191
|
const resolvedPath = await realpath(requestedPath);
|
|
1192
1192
|
const resolvedRoots = await Promise.all(allowedRoots.map((root) => realpath(root)));
|
|
1193
1193
|
const directory = await stat(resolvedPath);
|
|
@@ -1195,16 +1195,40 @@ export async function inspectWorkspace(requestedPath, allowedRoots) {
|
|
|
1195
1195
|
throw new Error('WORKSPACE_NOT_ALLOWED');
|
|
1196
1196
|
}
|
|
1197
1197
|
try {
|
|
1198
|
-
const
|
|
1198
|
+
const repositoryRoot = await resolveWorkspaceGitRoot(resolvedPath, includeParentRepository);
|
|
1199
|
+
const summary = { ...(await readGitSummary(repositoryRoot)), repositoryRoot };
|
|
1199
1200
|
return { path: resolvedPath, kind: 'GIT_WORKSPACE', gitSummary: summary };
|
|
1200
1201
|
}
|
|
1201
1202
|
catch (error) {
|
|
1202
|
-
if ((error instanceof GitCommandError && error.code === 128) ||
|
|
1203
|
+
if ((error instanceof GitCommandError && error.code === 128) ||
|
|
1204
|
+
isGitUnavailable(error) ||
|
|
1205
|
+
(error instanceof Error && error.message === 'WORKSPACE_NOT_GIT')) {
|
|
1203
1206
|
return { path: resolvedPath, kind: 'DIRECTORY' };
|
|
1204
1207
|
}
|
|
1205
1208
|
throw error;
|
|
1206
1209
|
}
|
|
1207
1210
|
}
|
|
1211
|
+
/** Resolves the working tree without changing the registered Workspace identity. */
|
|
1212
|
+
export async function resolveWorkspaceGitRoot(workspacePath, includeParentRepository = true) {
|
|
1213
|
+
const workspace = await resolveRegisteredWorkspaceRoot(workspacePath);
|
|
1214
|
+
if (!includeParentRepository) {
|
|
1215
|
+
const marker = await lstat(resolve(workspace, '.git')).catch((error) => {
|
|
1216
|
+
if (error.code === 'ENOENT')
|
|
1217
|
+
return undefined;
|
|
1218
|
+
throw error;
|
|
1219
|
+
});
|
|
1220
|
+
if (marker === undefined ||
|
|
1221
|
+
marker.isSymbolicLink() ||
|
|
1222
|
+
(!marker.isFile() && !marker.isDirectory()))
|
|
1223
|
+
throw new Error('WORKSPACE_NOT_GIT');
|
|
1224
|
+
}
|
|
1225
|
+
const result = await runReadOnlyGit(workspace, ['rev-parse', '--show-toplevel']);
|
|
1226
|
+
const root = await realpath(result.text.replace(/\n$/u, ''));
|
|
1227
|
+
if (!includeParentRepository &&
|
|
1228
|
+
normalizeWorkspacePath(root) !== normalizeWorkspacePath(workspace))
|
|
1229
|
+
throw new Error('WORKSPACE_NOT_GIT');
|
|
1230
|
+
return root;
|
|
1231
|
+
}
|
|
1208
1232
|
export async function readGitSummary(workspacePath) {
|
|
1209
1233
|
const commonDir = (await runReadOnlyGit(workspacePath, ['rev-parse', '--git-common-dir'])).text.trim();
|
|
1210
1234
|
const headResult = await runReadOnlyGitAllowFailure(workspacePath, [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myagentroam/node",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"description": "MyAgentRoam Node runtime CLI.",
|
|
5
5
|
"license": "Apache-2.0 AND GPL-2.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"playwright": "1.62.1",
|
|
38
38
|
"ws": "^8.21.3",
|
|
39
39
|
"zod": "4.4.3",
|
|
40
|
-
"@myagentroam/agent": "0.11.
|
|
40
|
+
"@myagentroam/agent": "0.11.2",
|
|
41
|
+
"@myagentroam/protocol": "0.11.2",
|
|
41
42
|
"@myagentroam/marctl": "0.11.0",
|
|
42
|
-
"@myagentroam/code-navigation": "0.11.0"
|
|
43
|
-
"@myagentroam/protocol": "0.11.0"
|
|
43
|
+
"@myagentroam/code-navigation": "0.11.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/ws": "^8.18.1"
|