@myagentroam/node 0.10.1 → 0.10.3
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/config.d.ts +43 -0
- package/dist/config.js +14 -4
- package/dist/connector.js +1 -1
- package/dist/main.js +5 -2
- package/dist/service/direct-transfer-service.js +1 -1
- package/dist/service/terminal-direct-service.js +3 -0
- package/dist/service/workspace-queue-workbench-service.js +16 -3
- package/package.json +13 -4
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface ConversationHostingConfig {
|
|
2
|
+
readonly enabled: boolean;
|
|
3
|
+
/** Relative directory inside dataDirectory. */
|
|
4
|
+
readonly storeDirectory?: string;
|
|
5
|
+
readonly inactiveRetentionDays?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface DirectTransferConfig {
|
|
8
|
+
readonly udpPortRangeBegin: number;
|
|
9
|
+
readonly udpPortRangeEnd: number;
|
|
10
|
+
}
|
|
11
|
+
export interface DirectTransferUdpPortRange {
|
|
12
|
+
readonly begin: number;
|
|
13
|
+
readonly end: number;
|
|
14
|
+
}
|
|
15
|
+
export interface ComputerUseConfig {
|
|
16
|
+
readonly enabled: boolean;
|
|
17
|
+
/** Development/validation override; production distributions use the managed runtime path. */
|
|
18
|
+
readonly runtimeExecutable?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface NodeConfig {
|
|
21
|
+
readonly serverUrl: string;
|
|
22
|
+
/** Explicit roots or the platform default resolved while loading the config. */
|
|
23
|
+
readonly allowedRoots: readonly string[];
|
|
24
|
+
/** Absolute or config-relative root for SQLite, upgrades and other private Node data. */
|
|
25
|
+
readonly dataDirectory?: string;
|
|
26
|
+
readonly conversationHosting?: ConversationHostingConfig;
|
|
27
|
+
readonly directTransfer?: DirectTransferConfig;
|
|
28
|
+
readonly computerUse?: ComputerUseConfig;
|
|
29
|
+
readonly nodeId?: string;
|
|
30
|
+
readonly credential?: string;
|
|
31
|
+
readonly registrationToken?: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function nodeConfigPath(): string;
|
|
34
|
+
export declare function loadNodeConfig(path?: string): Promise<NodeConfig>;
|
|
35
|
+
export declare function directTransferUdpPortRange(config: Pick<NodeConfig, 'directTransfer'> | undefined): DirectTransferUdpPortRange;
|
|
36
|
+
/** Uses the Node service account's scope when no Workspace roots are configured. */
|
|
37
|
+
export declare function defaultAllowedRoots(platform?: NodeJS.Platform, homePath?: string, currentDirectory?: string): readonly string[];
|
|
38
|
+
export declare function nodeDatabasePath(config: NodeConfig, configPath?: string): string;
|
|
39
|
+
export declare function nodeDataDirectory(config: NodeConfig, configPath?: string): string;
|
|
40
|
+
export declare function computerUseRuntimeExecutable(config: NodeConfig, configPath?: string, platform?: NodeJS.Platform, architecture?: string): string | undefined;
|
|
41
|
+
export declare function hostedConversationStorePath(config: NodeConfig, configPath?: string): string | undefined;
|
|
42
|
+
/** Credentials are always written with owner-only POSIX permissions where supported. */
|
|
43
|
+
export declare function saveNodeConfig(config: NodeConfig, path?: string): Promise<void>;
|
package/dist/config.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
1
|
+
import { chmod, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
2
3
|
import { homedir } from 'node:os';
|
|
3
4
|
import { dirname, isAbsolute, relative, resolve, sep, win32 } from 'node:path';
|
|
4
5
|
import { computerUseRuntimeVersion } from './computer-use-runtime-version.js';
|
|
@@ -87,9 +88,18 @@ export function hostedConversationStorePath(config, configPath = nodeConfigPath(
|
|
|
87
88
|
/** Credentials are always written with owner-only POSIX permissions where supported. */
|
|
88
89
|
export async function saveNodeConfig(config, path = nodeConfigPath()) {
|
|
89
90
|
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
await
|
|
91
|
+
const temporary = `${path}.${randomUUID()}.tmp`;
|
|
92
|
+
try {
|
|
93
|
+
await writeFile(temporary, `${JSON.stringify(config, undefined, 2)}\n`, {
|
|
94
|
+
mode: 0o600,
|
|
95
|
+
flag: 'wx'
|
|
96
|
+
});
|
|
97
|
+
if (process.platform !== 'win32')
|
|
98
|
+
await chmod(temporary, 0o600);
|
|
99
|
+
await rename(temporary, path);
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
await rm(temporary, { force: true });
|
|
93
103
|
}
|
|
94
104
|
}
|
|
95
105
|
function parseConversationHosting(value) {
|
package/dist/connector.js
CHANGED
|
@@ -1684,7 +1684,7 @@ export class NodeConnector {
|
|
|
1684
1684
|
nodeGeneration: () => this.nodeGeneration,
|
|
1685
1685
|
send: (type, payload) => this.send(type, payload),
|
|
1686
1686
|
terminalManager: this.terminalManager,
|
|
1687
|
-
sendTerminalReady: (directSessionId) => this.send('terminal.direct.ready', { directSessionId }),
|
|
1687
|
+
sendTerminalReady: (directSessionId, phase) => this.send('terminal.direct.ready', { directSessionId, ...(phase ? { phase } : {}) }),
|
|
1688
1688
|
udpPortRange: () => directTransferUdpPortRange(this.config),
|
|
1689
1689
|
openUpload: async (descriptor) => {
|
|
1690
1690
|
if (descriptor.direction !== 'UPLOAD' || descriptor.resource.kind !== 'WORKSPACE_FILE')
|
package/dist/main.js
CHANGED
|
@@ -17,10 +17,13 @@ if (command === 'run') {
|
|
|
17
17
|
const { NodeConnector } = await import('./connector.js');
|
|
18
18
|
configureNodeLog(nodeDataDirectory(await loadNodeConfig(config), config));
|
|
19
19
|
const connector = new NodeConnector({ configPath: config });
|
|
20
|
-
|
|
20
|
+
const shutdown = () => {
|
|
21
|
+
void connector.stop().finally(() => process.exit(0));
|
|
22
|
+
};
|
|
21
23
|
for (const signal of ['SIGINT', 'SIGTERM']) {
|
|
22
|
-
process.once(signal,
|
|
24
|
+
process.once(signal, shutdown);
|
|
23
25
|
}
|
|
26
|
+
await connector.start();
|
|
24
27
|
}
|
|
25
28
|
else if (command === 'supervise') {
|
|
26
29
|
if (process.argv[1] === undefined)
|
|
@@ -47,7 +47,7 @@ export class DirectTransferService {
|
|
|
47
47
|
this.leaseGraceMs = options.leaseGraceMs ?? LEASE_GRACE_MS;
|
|
48
48
|
this.leaseCheckMs = options.leaseCheckMs ?? LEASE_CHECK_MS;
|
|
49
49
|
if (options.terminalManager !== undefined)
|
|
50
|
-
this.terminalDirect = new TerminalDirectService(options.terminalManager, (id) => options.sendTerminalReady?.(id), (command, peer) => {
|
|
50
|
+
this.terminalDirect = new TerminalDirectService(options.terminalManager, (id, phase) => options.sendTerminalReady?.(id, phase), (command, peer) => {
|
|
51
51
|
const transport = this.transports.get(command.transportSessionId);
|
|
52
52
|
return (transport?.peer === peer &&
|
|
53
53
|
transport.command.workbenchConnectionId === command.workbenchConnectionId &&
|
|
@@ -114,6 +114,9 @@ export class TerminalDirectService {
|
|
|
114
114
|
this.sendFrame(session, frame);
|
|
115
115
|
channel.onmessage = (event) => this.accept(session, event.data);
|
|
116
116
|
this.manager.startCommand(session.command.terminalId);
|
|
117
|
+
void Promise.resolve()
|
|
118
|
+
.then(() => this.sendReady(session.command.directSessionId, 'ATTACHED'))
|
|
119
|
+
.catch(() => console.warn('AUDIT_RECEIPT_UNAVAILABLE'));
|
|
117
120
|
}
|
|
118
121
|
catch (error) {
|
|
119
122
|
this.remove(session, error instanceof Error && error.message === 'TERMINAL_ATTACH_CONFLICT'
|
|
@@ -44,8 +44,8 @@ export class WorkspaceQueueWorkbenchService {
|
|
|
44
44
|
version: queue.version,
|
|
45
45
|
paused: queue.paused,
|
|
46
46
|
items: queue.itemIds.flatMap((itemId) => {
|
|
47
|
-
const item = this.
|
|
48
|
-
if (item === undefined
|
|
47
|
+
const item = this.publicQueueItem(itemId);
|
|
48
|
+
if (item === undefined)
|
|
49
49
|
return [];
|
|
50
50
|
const session = this.options.runtime.getAgentSession(item.sessionId);
|
|
51
51
|
return [
|
|
@@ -89,7 +89,16 @@ export class WorkspaceQueueWorkbenchService {
|
|
|
89
89
|
throw new Error('QUEUE_INVALID');
|
|
90
90
|
const session = this.requireSession(input);
|
|
91
91
|
assertSessionControlOwner(this.options.runtime, session.id, input.__requestUserId);
|
|
92
|
-
this.options.runtime.
|
|
92
|
+
const current = this.options.runtime.sessionQueue(session.id);
|
|
93
|
+
const publicItemIds = new Set(current.itemIds.filter((itemId) => this.publicQueueItem(itemId) !== undefined));
|
|
94
|
+
const reorderedIds = input.queueItemIds;
|
|
95
|
+
if (reorderedIds.length !== publicItemIds.size ||
|
|
96
|
+
new Set(reorderedIds).size !== reorderedIds.length ||
|
|
97
|
+
reorderedIds.some((itemId) => !publicItemIds.has(itemId)))
|
|
98
|
+
throw new Error('QUEUE_VERSION_CONFLICT');
|
|
99
|
+
let index = 0;
|
|
100
|
+
// Reorder only public slots, leaving internal continuations in place.
|
|
101
|
+
this.options.runtime.reorderSessionQueue(session.id, input.expectedVersion, current.itemIds.map((itemId) => (publicItemIds.has(itemId) ? reorderedIds[index++] : itemId)));
|
|
93
102
|
this.options.emit(session.workspaceId, session.id);
|
|
94
103
|
return {
|
|
95
104
|
queue: this.present(session.workspaceId, session.id),
|
|
@@ -151,6 +160,10 @@ export class WorkspaceQueueWorkbenchService {
|
|
|
151
160
|
throw new Error('SESSION_NOT_FOUND');
|
|
152
161
|
return session;
|
|
153
162
|
}
|
|
163
|
+
publicQueueItem(itemId) {
|
|
164
|
+
const item = this.options.runtime.getQueueItem(itemId);
|
|
165
|
+
return item?.clientMessageId.startsWith('goal:') ? undefined : item;
|
|
166
|
+
}
|
|
154
167
|
requireItem(itemId, workspaceId) {
|
|
155
168
|
const item = this.options.runtime.getQueueItem(itemId);
|
|
156
169
|
if (item === undefined)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myagentroam/node",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.3",
|
|
4
4
|
"description": "MyAgentRoam Node runtime CLI.",
|
|
5
5
|
"license": "Apache-2.0 AND GPL-2.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"scripts/install-web-browser.mjs",
|
|
10
10
|
"vendor/ripgrep/**/*",
|
|
11
11
|
"vendor/ctags/**/*",
|
|
12
|
+
"dist/config.d.ts",
|
|
12
13
|
"LICENSE",
|
|
13
14
|
"NOTICE"
|
|
14
15
|
],
|
|
@@ -36,14 +37,22 @@
|
|
|
36
37
|
"playwright": "1.62.1",
|
|
37
38
|
"ws": "^8.21.3",
|
|
38
39
|
"zod": "4.4.3",
|
|
39
|
-
"@myagentroam/agent": "0.10.
|
|
40
|
-
"@myagentroam/
|
|
40
|
+
"@myagentroam/agent": "0.10.3",
|
|
41
|
+
"@myagentroam/code-navigation": "0.10.1",
|
|
41
42
|
"@myagentroam/marctl": "0.10.1",
|
|
42
|
-
"@myagentroam/
|
|
43
|
+
"@myagentroam/protocol": "0.10.3"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"@types/ws": "^8.18.1"
|
|
46
47
|
},
|
|
48
|
+
"exports": {
|
|
49
|
+
"./config": {
|
|
50
|
+
"types": "./dist/config.d.ts",
|
|
51
|
+
"import": "./dist/config.js"
|
|
52
|
+
},
|
|
53
|
+
"./cli": "./dist/main.js",
|
|
54
|
+
"./package.json": "./package.json"
|
|
55
|
+
},
|
|
47
56
|
"scripts": {
|
|
48
57
|
"postinstall": "node scripts/install-web-browser.mjs",
|
|
49
58
|
"build": "node ../scripts/clean-build-output.mjs dist && tsc -p tsconfig.json",
|