@myagentroam/node 0.9.180 → 0.10.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/NOTICE +7 -0
- package/dist/computer-use-runtime-version.js +1 -1
- package/dist/computer-use-runtime.js +0 -3
- package/dist/config.d.ts +43 -0
- package/dist/config.js +14 -4
- package/dist/main.js +10 -2
- package/dist/runner/codex-runner.js +1 -1
- package/dist/runner/opencode-runner.js +1 -1
- package/dist/service/code-navigation/ecmascript-path-specifier-resolver.js +0 -4
- package/dist/service/direct-transfer-service.js +4 -1
- package/dist/service/hosted-conversation-node-service.js +0 -12
- package/dist/service/workspace-code-navigation-service.js +0 -4
- package/dist/service/workspace-file-service.js +3 -3
- package/dist/service/workspace-queue-workbench-service.js +16 -3
- package/package.json +15 -6
package/NOTICE
CHANGED
|
@@ -2,3 +2,10 @@ MyAgentRoam
|
|
|
2
2
|
Copyright 2026 MyAgentRoam contributors
|
|
3
3
|
|
|
4
4
|
This product includes software developed by the MyAgentRoam project.
|
|
5
|
+
|
|
6
|
+
Enterprise implementation and product composition:
|
|
7
|
+
Copyright 2026 aCHAOS
|
|
8
|
+
Author and licensing contact: aCHAOS (achaosxyz@gmail.com)
|
|
9
|
+
Licensed under MyAgentRoam Enterprise Source-Available License 1.0; see
|
|
10
|
+
ee/LICENSE and LICENSING.md. Independent core and third-party notices remain
|
|
11
|
+
applicable; this attribution does not transfer any contributor's copyright.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const computerUseRuntimeVersion = '0.
|
|
1
|
+
export const computerUseRuntimeVersion = '0.10.1';
|
|
@@ -294,9 +294,6 @@ function safeRuntimePath(root, path) {
|
|
|
294
294
|
throw new ComputerUseRuntimeError('COMPUTER_RUNTIME_MANIFEST_INVALID');
|
|
295
295
|
return target;
|
|
296
296
|
}
|
|
297
|
-
function isMissing(error) {
|
|
298
|
-
return (error instanceof Error && 'code' in error && error.code === 'ENOENT');
|
|
299
|
-
}
|
|
300
297
|
function isAlreadyExists(error) {
|
|
301
298
|
return (error instanceof Error && 'code' in error && error.code === 'EEXIST');
|
|
302
299
|
}
|
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/main.js
CHANGED
|
@@ -17,10 +17,18 @@ 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);
|
|
25
|
+
}
|
|
26
|
+
if (args.includes('--managed-parent')) {
|
|
27
|
+
if (process.send === undefined || !process.connected)
|
|
28
|
+
throw new Error('NODE_MANAGED_PARENT_UNAVAILABLE');
|
|
29
|
+
process.once('disconnect', shutdown);
|
|
23
30
|
}
|
|
31
|
+
await connector.start();
|
|
24
32
|
}
|
|
25
33
|
else if (command === 'supervise') {
|
|
26
34
|
if (process.argv[1] === undefined)
|
|
@@ -49,7 +49,7 @@ export class CodexRunner extends AbstractRunner {
|
|
|
49
49
|
}).find((profile) => profile.runner === this.name);
|
|
50
50
|
return { ...base, models: this.profileCache?.profile.models ?? [] };
|
|
51
51
|
}
|
|
52
|
-
cachedProfile(capabilities,
|
|
52
|
+
cachedProfile(capabilities, _environment = {}) {
|
|
53
53
|
const base = this.profile(capabilities);
|
|
54
54
|
return this.profileCache === undefined ||
|
|
55
55
|
this.profileCacheVersion !== capabilities.codex.version
|
|
@@ -43,7 +43,7 @@ export class OpenCodeRunner extends AbstractRunner {
|
|
|
43
43
|
}).find((profile) => profile.runner === this.name);
|
|
44
44
|
return { ...base, models: [] };
|
|
45
45
|
}
|
|
46
|
-
cachedProfile(capabilities,
|
|
46
|
+
cachedProfile(capabilities, _environment = {}) {
|
|
47
47
|
const cached = this.profileCache;
|
|
48
48
|
return cached === undefined
|
|
49
49
|
? this.profile(capabilities)
|
|
@@ -70,10 +70,6 @@ function candidates(path) {
|
|
|
70
70
|
? [path]
|
|
71
71
|
: [path, ...extensionlessSourceExtensions.map((extension) => `${path}${extension}`)];
|
|
72
72
|
}
|
|
73
|
-
function sourceFileStem(path) {
|
|
74
|
-
const name = path.slice(path.lastIndexOf('/') + 1);
|
|
75
|
-
return name.replace(/(?:\.d)?\.[^.]+$/u, '');
|
|
76
|
-
}
|
|
77
73
|
function unresolvedSpecifierScore(path, specifier) {
|
|
78
74
|
const normalizedSpecifier = specifier.startsWith('@/') ? specifier.slice(2) : specifier;
|
|
79
75
|
return trailingPathCandidateScore(path, unresolvedCandidates(normalizedSpecifier));
|
|
@@ -389,7 +389,10 @@ export class DirectTransferService {
|
|
|
389
389
|
const complete = (error) => {
|
|
390
390
|
channel.removeEventListener('bufferedamountlow', available);
|
|
391
391
|
channel.removeEventListener('close', closed);
|
|
392
|
-
error === undefined
|
|
392
|
+
if (error === undefined)
|
|
393
|
+
resolve();
|
|
394
|
+
else
|
|
395
|
+
reject(error);
|
|
393
396
|
};
|
|
394
397
|
const available = () => complete();
|
|
395
398
|
const closed = () => complete(new Error('DIRECT_CHANNEL_CLOSED'));
|
|
@@ -1798,18 +1798,6 @@ function publishedTemplateEntry(value) {
|
|
|
1798
1798
|
resolvedTarget
|
|
1799
1799
|
};
|
|
1800
1800
|
}
|
|
1801
|
-
function publishedTemplateFiles(value) {
|
|
1802
|
-
if (!Array.isArray(value))
|
|
1803
|
-
throw new Error('CONVERSATION_TEMPLATE_VERSION_CORRUPTED');
|
|
1804
|
-
const paths = new Set();
|
|
1805
|
-
return value.map((candidate) => {
|
|
1806
|
-
const file = publishedTemplateFile(candidate);
|
|
1807
|
-
if (paths.has(file.relativePath))
|
|
1808
|
-
throw new Error('CONVERSATION_TEMPLATE_VERSION_CORRUPTED');
|
|
1809
|
-
paths.add(file.relativePath);
|
|
1810
|
-
return file;
|
|
1811
|
-
});
|
|
1812
|
-
}
|
|
1813
1801
|
function publishedTemplateFile(value, requireKind = false) {
|
|
1814
1802
|
if (!record(value) ||
|
|
1815
1803
|
(requireKind && value.kind !== 'FILE') ||
|
|
@@ -22,10 +22,6 @@ const MAX_TAGS_BYTES = 512 * 1024 * 1024;
|
|
|
22
22
|
const MAX_CANDIDATES = 100;
|
|
23
23
|
const MAX_RESULTS = 20;
|
|
24
24
|
const MAX_REFERENCES = 100;
|
|
25
|
-
const MAX_TAG_LINE_BYTES = 16 * 1024;
|
|
26
|
-
const READ_BLOCK_BYTES = 4096;
|
|
27
|
-
const MAX_TARGET_LINE_SCAN_BYTES = MAX_SOURCE_BYTES;
|
|
28
|
-
const MAX_TARGET_PREVIEW_CHARACTERS = 512;
|
|
29
25
|
/**
|
|
30
26
|
* Builds a demand-driven, standard u-ctags declaration index. It never keeps
|
|
31
27
|
* a complete symbol table, watcher, or idle child process in memory.
|
|
@@ -77,15 +77,15 @@ export class WorkspaceFileService {
|
|
|
77
77
|
: readWorkspaceFileContentRange(workspacePath, path, offset, limit);
|
|
78
78
|
}
|
|
79
79
|
readDirect(workspace, input, workspacePath = workspace.path) {
|
|
80
|
-
const
|
|
80
|
+
const readContent = this.readContent.bind(this);
|
|
81
81
|
return (async function* () {
|
|
82
|
-
const initial = (await
|
|
82
|
+
const initial = (await readContent(workspace, { path: input.path, offset: input.range?.offset ?? 0, limit: 1 }, workspacePath));
|
|
83
83
|
if (initial.size !== input.size || initial.sourceRevision !== input.revision)
|
|
84
84
|
throw new Error('DIRECT_FILE_REVISION_CHANGED');
|
|
85
85
|
let offset = input.range?.offset ?? 0;
|
|
86
86
|
const endOffset = input.range === undefined ? input.size : input.range.offset + input.range.length;
|
|
87
87
|
while (offset < endOffset) {
|
|
88
|
-
const range = (await
|
|
88
|
+
const range = (await readContent(workspace, {
|
|
89
89
|
path: input.path,
|
|
90
90
|
offset,
|
|
91
91
|
limit: Math.min(512 * 1024, endOffset - offset)
|
|
@@ -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.
|
|
3
|
+
"version": "0.10.2",
|
|
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.
|
|
40
|
-
"@myagentroam/
|
|
41
|
-
"@myagentroam/marctl": "0.
|
|
42
|
-
"@myagentroam/
|
|
40
|
+
"@myagentroam/agent": "0.10.2",
|
|
41
|
+
"@myagentroam/code-navigation": "0.10.1",
|
|
42
|
+
"@myagentroam/marctl": "0.10.1",
|
|
43
|
+
"@myagentroam/protocol": "0.10.2"
|
|
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",
|
|
@@ -51,7 +60,7 @@
|
|
|
51
60
|
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.tests.json --noEmit",
|
|
52
61
|
"dev": "tsx watch src/main.ts",
|
|
53
62
|
"start": "node dist/main.js",
|
|
54
|
-
"test:unit": "vitest run --config vitest.config.mts",
|
|
63
|
+
"test:unit": "vitest run --config vitest.config.mts && node --test test/unit/*.test.mjs",
|
|
55
64
|
"test:e2e:real": "vitest run --config vitest.e2e.config.mts"
|
|
56
65
|
}
|
|
57
66
|
}
|