@myagentroam/node 0.9.4 → 0.9.6
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/claude-agent-sdk.d.ts +1 -0
- package/dist/claude-agent-sdk.js +9 -0
- package/dist/codex-app-server.d.ts +1 -0
- package/dist/codex-app-server.js +4 -2
- package/dist/connector.d.ts +1 -0
- package/dist/connector.js +16 -11
- package/dist/native-jsonl-reader.d.ts +21 -0
- package/dist/native-jsonl-reader.js +89 -0
- package/dist/native-session-history.d.ts +20 -3
- package/dist/native-session-history.js +245 -38
- package/dist/opencode-server.d.ts +1 -0
- package/dist/opencode-server.js +1 -0
- package/dist/runner/abstract-runner.d.ts +11 -2
- package/dist/runner/abstract-runner.js +4 -0
- package/dist/runner/claude/managed-run-controller.js +3 -0
- package/dist/runner/claude-code-runner.d.ts +2 -1
- package/dist/runner/claude-code-runner.js +4 -0
- package/dist/runner/codex/managed-run-controller.js +6 -0
- package/dist/runner/codex-runner.d.ts +2 -1
- package/dist/runner/codex-runner.js +13 -2
- package/dist/runner/opencode/managed-run-controller.js +4 -0
- package/dist/runner/opencode-runner.d.ts +10 -3
- package/dist/runner/opencode-runner.js +87 -14
- package/dist/runner/runner-registry.js +16 -1
- package/dist/runtime-command-detector.js +1 -6
- package/dist/runtime-state.js +1 -0
- package/dist/service/conversation-history-service.d.ts +6 -5
- package/dist/service/conversation-history-service.js +151 -55
- package/dist/service/external-session-resume-service.d.ts +2 -0
- package/dist/service/external-session-resume-service.js +45 -34
- package/dist/service/native-session-projection-service.d.ts +1 -0
- package/dist/service/native-session-projection-service.js +4 -0
- package/dist/service/native-session-watch-service.d.ts +18 -0
- package/dist/service/native-session-watch-service.js +232 -34
- package/dist/service/run-workbench-service.d.ts +2 -4
- package/dist/service/run-workbench-service.js +2 -7
- package/dist/service/session-command-service.js +1 -1
- package/dist/service/session-identity-service.d.ts +1 -1
- package/dist/service/session-identity-service.js +1 -1
- package/dist/service/session-lifecycle-service.js +3 -0
- package/dist/service/session-message-service.d.ts +0 -1
- package/dist/service/session-message-service.js +15 -23
- package/dist/service/skill-directory-service.d.ts +1 -0
- package/dist/service/skill-directory-service.js +40 -6
- package/dist/service/workspace-domain-state.d.ts +3 -0
- package/dist/service/workspace-domain-state.js +1 -0
- package/dist/service/workspace-file-service.d.ts +1 -0
- package/dist/service/workspace-file-service.js +14 -1
- package/dist/service/workspace-queue-workbench-service.d.ts +17 -0
- package/dist/service/workspace-queue-workbench-service.js +66 -6
- package/dist/service/workspace-watch-service.d.ts +7 -2
- package/dist/service/workspace-watch-service.js +32 -6
- package/dist/service/workspace-workbench-service.d.ts +14 -0
- package/dist/service/workspace-workbench-service.js +215 -16
- package/dist/util/personal-instructions.d.ts +2 -0
- package/dist/util/personal-instructions.js +31 -0
- package/dist/util/runner-native-session-parsers.d.ts +1 -0
- package/dist/util/runner-native-session-parsers.js +76 -12
- package/dist/workspace.d.ts +14 -8
- package/dist/workspace.js +65 -42
- package/package.json +2 -2
|
@@ -23,6 +23,7 @@ export interface ClaudeQueryInput {
|
|
|
23
23
|
readonly onChannelReply?: (content: string) => void;
|
|
24
24
|
readonly environment?: Readonly<Record<string, string>>;
|
|
25
25
|
readonly mcpServers?: NonNullable<Options['mcpServers']>;
|
|
26
|
+
readonly personalInstructions?: string;
|
|
26
27
|
}
|
|
27
28
|
/** Image blocks accepted by the Claude Agent SDK message input. */
|
|
28
29
|
export interface ClaudeImageAttachment {
|
package/dist/claude-agent-sdk.js
CHANGED
|
@@ -64,6 +64,15 @@ export class ClaudeAgentSdkAdapter {
|
|
|
64
64
|
// This is the SDK's documented API-side public summary mode. We never
|
|
65
65
|
// enable or forward raw thinking deltas to the Workbench.
|
|
66
66
|
settings: { showThinkingSummaries: true },
|
|
67
|
+
...(input.personalInstructions === undefined
|
|
68
|
+
? {}
|
|
69
|
+
: {
|
|
70
|
+
systemPrompt: {
|
|
71
|
+
type: 'preset',
|
|
72
|
+
preset: 'claude_code',
|
|
73
|
+
append: input.personalInstructions
|
|
74
|
+
}
|
|
75
|
+
}),
|
|
67
76
|
abortController,
|
|
68
77
|
canUseTool: input.onPermission,
|
|
69
78
|
...(input.mcpServers !== undefined || channelEnabled
|
|
@@ -50,6 +50,7 @@ export interface CodexRunConfiguration {
|
|
|
50
50
|
readonly serviceTier?: 'fast';
|
|
51
51
|
readonly collaborationMode?: 'default' | 'plan';
|
|
52
52
|
readonly mcpServers?: unknown;
|
|
53
|
+
readonly developerInstructions?: string;
|
|
53
54
|
}
|
|
54
55
|
interface CodexRpcErrorPayload {
|
|
55
56
|
readonly code?: unknown;
|
package/dist/codex-app-server.js
CHANGED
|
@@ -358,6 +358,9 @@ export class CodexAppServerClient {
|
|
|
358
358
|
function codexThreadConfiguration(cwd, configuration) {
|
|
359
359
|
return {
|
|
360
360
|
...modelOption(configuration.model),
|
|
361
|
+
...(configuration.developerInstructions === undefined
|
|
362
|
+
? {}
|
|
363
|
+
: { developerInstructions: configuration.developerInstructions }),
|
|
361
364
|
...(configuration.mcpServers === undefined
|
|
362
365
|
? {}
|
|
363
366
|
: { config: { mcp_servers: configuration.mcpServers } }),
|
|
@@ -376,8 +379,7 @@ function codexTurnConfiguration(cwd, configuration) {
|
|
|
376
379
|
mode: configuration.collaborationMode,
|
|
377
380
|
settings: {
|
|
378
381
|
model: configuration.model ?? 'gpt-5.6-sol',
|
|
379
|
-
reasoningEffort: configuration.effort ?? null
|
|
380
|
-
developerInstructions: null
|
|
382
|
+
reasoningEffort: configuration.effort ?? null
|
|
381
383
|
}
|
|
382
384
|
}
|
|
383
385
|
}),
|
package/dist/connector.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export type { NodeConnectorOptions } from './connector/node-connector-options.js
|
|
|
3
3
|
export { nodeConnectEndpoint, validatedCapabilities } from './runner/codex/conversation-parser.js';
|
|
4
4
|
export declare function nextReconnectDelay(attempt: number): number;
|
|
5
5
|
export declare class NodeConnector {
|
|
6
|
+
private readonly nodeGeneration;
|
|
6
7
|
private readonly controlChannel;
|
|
7
8
|
private readonly controlMessages;
|
|
8
9
|
private readonly nodeRequests;
|
package/dist/connector.js
CHANGED
|
@@ -86,6 +86,7 @@ function upgradeMetadata(metadata, status) {
|
|
|
86
86
|
return next;
|
|
87
87
|
}
|
|
88
88
|
export class NodeConnector {
|
|
89
|
+
nodeGeneration = crypto.randomUUID().replace(/-/g, '');
|
|
89
90
|
controlChannel;
|
|
90
91
|
controlMessages;
|
|
91
92
|
nodeRequests;
|
|
@@ -153,7 +154,7 @@ export class NodeConnector {
|
|
|
153
154
|
discover: (workspaceId) => this.discoverWorkspaceSessions(workspaceId),
|
|
154
155
|
listPage: (workspaceId) => this.executeNodeOperation('session.list', { workspaceId, limit: 20 }),
|
|
155
156
|
active: (workspaceId) => this.workspaceWatchService.topicActive(workspaceId, 'sessions'),
|
|
156
|
-
emitRevision: (workspaceId
|
|
157
|
+
emitRevision: (workspaceId) => void this.workspaceWorkbenchService?.refreshTopic(workspaceId, 'sessions'),
|
|
157
158
|
onPending: (workspaceId, waitMs) => nodeLog('native.session.discovery.pending', {
|
|
158
159
|
nodeId: this.config?.nodeId,
|
|
159
160
|
workspaceId,
|
|
@@ -192,8 +193,9 @@ export class NodeConnector {
|
|
|
192
193
|
});
|
|
193
194
|
nativeSessionWatchService = new NativeSessionWatchService({
|
|
194
195
|
resolve: async (sessionId) => this.runtime.getAgentSession(sessionId) ??
|
|
195
|
-
this.nativeSessionProjectionService.
|
|
196
|
+
this.nativeSessionProjectionService.resolveCurrent(sessionId),
|
|
196
197
|
managedActive: (session) => hasManagedActiveRun(this.runtime, session),
|
|
198
|
+
suspended: (sessionId) => this.externalSessionResumeService.transitioning(sessionId),
|
|
197
199
|
refreshActivity: (session) => this.conversationHistoryService.refreshExternalActivity(session),
|
|
198
200
|
present: (session) => this.sessionPresentationService.present(session),
|
|
199
201
|
readPage: (session, limit) => this.conversationHistoryService.read(session, { limit }),
|
|
@@ -203,7 +205,10 @@ export class NodeConnector {
|
|
|
203
205
|
emitPage: (session, page) => this.emitWorkbenchEvent('conversation', {
|
|
204
206
|
sessionId: session.id,
|
|
205
207
|
snapshot: this.conversationSegmentService.projectInitial(session, page, 10)
|
|
206
|
-
})
|
|
208
|
+
}),
|
|
209
|
+
nodeId: () => this.config?.nodeId ?? 'runtime-node',
|
|
210
|
+
nodeGeneration: () => this.nodeGeneration,
|
|
211
|
+
emitWatchEvent: (payload) => this.send('watch.event', payload)
|
|
207
212
|
});
|
|
208
213
|
constructor(options = {}) {
|
|
209
214
|
this.config = options.config;
|
|
@@ -396,10 +401,8 @@ export class NodeConnector {
|
|
|
396
401
|
readImage: async (runId, imageIndex) => this.runAttachmentService.read(runId, imageIndex) ??
|
|
397
402
|
(await this.runAttachmentService.readNative(runId, imageIndex)),
|
|
398
403
|
respondUserInput: (runId, requestId, answers) => this.runnerInteractionService.respondUserInput(runId, requestId, answers),
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
cleanupAttachments: (runId) => this.runAttachmentService.cleanup(runId),
|
|
402
|
-
emitQueue: (workspaceId, sessionId) => this.runEventBridge.emitQueue(workspaceId, sessionId),
|
|
404
|
+
cancelQueued: (runId) => this.workspaceQueueWorkbenchService.cancelQueued(runId),
|
|
405
|
+
pauseQueue: (sessionId) => this.workspaceQueueWorkbenchService.pauseForInterrupt(sessionId),
|
|
403
406
|
emitRun: (runId, eventType, payload, status) => this.runEventBridge.emitRun(runId, eventType, payload, status),
|
|
404
407
|
control: (operation, payload) => this.controlMessages.handle(JSON.stringify(createEnvelope(operation, payload))),
|
|
405
408
|
markInterrupted: (runId) => this.runState.interruptRequested.add(runId)
|
|
@@ -447,7 +450,7 @@ export class NodeConnector {
|
|
|
447
450
|
migrateRunnerState: (previousId, nextId) => this.runEventBridge.migrateRunnerSessionIdentity(previousId, nextId),
|
|
448
451
|
emitSession: (session) => this.emitWorkbenchEvent('session', { session }),
|
|
449
452
|
emitRun: (run) => this.emitWorkbenchEvent('run', { run }),
|
|
450
|
-
emitQueue: (
|
|
453
|
+
emitQueue: (sessionId) => this.workspaceQueueWorkbenchService.publish(sessionId),
|
|
451
454
|
emitTurn: (turn) => this.emitConversationTurn(turn)
|
|
452
455
|
});
|
|
453
456
|
this.sessionLifecycleService = new SessionLifecycleService({
|
|
@@ -501,7 +504,6 @@ export class NodeConnector {
|
|
|
501
504
|
emitSession: (session) => this.emitWorkbenchEvent('session', {
|
|
502
505
|
session: this.sessionPresentationService.present(session)
|
|
503
506
|
}),
|
|
504
|
-
emitQueue: (workspaceId, sessionId) => this.runEventBridge.emitQueue(workspaceId, sessionId),
|
|
505
507
|
channelToken: (sessionId) => {
|
|
506
508
|
const session = this.runtime.getAgentSession(sessionId);
|
|
507
509
|
return session === undefined
|
|
@@ -650,7 +652,7 @@ export class NodeConnector {
|
|
|
650
652
|
watches: this.workspaceWatchService,
|
|
651
653
|
sessions: this.workspaceSessionService,
|
|
652
654
|
changes: this.workspaceChangeService,
|
|
653
|
-
emit: (workspaceId, topic
|
|
655
|
+
emit: (workspaceId, topic) => void this.workspaceWorkbenchService?.refreshTopic(workspaceId, topic),
|
|
654
656
|
send: (type, payload, replyTo) => this.send(type, payload, replyTo)
|
|
655
657
|
});
|
|
656
658
|
this.runEventBridge = new NodeRunEventBridge({
|
|
@@ -711,7 +713,10 @@ export class NodeConnector {
|
|
|
711
713
|
uploads: this.workspaceUploadService,
|
|
712
714
|
changes: this.workspaceChangeService,
|
|
713
715
|
listSessions: (workspaceId) => this.executeNodeOperation('session.list', { workspaceId, limit: 20 }),
|
|
714
|
-
invalidate: (workspaceId) => this.workspaceCoordinator.invalidate(workspaceId)
|
|
716
|
+
invalidate: (workspaceId) => this.workspaceCoordinator.invalidate(workspaceId),
|
|
717
|
+
nodeId: () => this.config?.nodeId ?? 'runtime-node',
|
|
718
|
+
nodeGeneration: () => this.nodeGeneration,
|
|
719
|
+
emitWatchEvent: (payload) => this.send('watch.event', payload)
|
|
715
720
|
});
|
|
716
721
|
this.operationRouter.registerAll(this.runnerService.operations());
|
|
717
722
|
this.operationRouter.registerAll(this.terminalService.operations());
|
|
@@ -3,6 +3,27 @@ export interface JsonlWindow {
|
|
|
3
3
|
readonly truncated: boolean;
|
|
4
4
|
readonly size: number;
|
|
5
5
|
}
|
|
6
|
+
export interface JsonlBackwardWindow extends JsonlWindow {
|
|
7
|
+
readonly pageContent: string;
|
|
8
|
+
readonly start: number;
|
|
9
|
+
readonly end: number;
|
|
10
|
+
readonly snapshotEnd: number;
|
|
11
|
+
readonly fileAnchor: string;
|
|
12
|
+
readonly anchorBytes: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function readJsonlFileAnchor(path: string, anchorBytes: number): Promise<string | undefined>;
|
|
15
|
+
/** Reads one newline-aligned window backwards from an opaque byte boundary. */
|
|
16
|
+
export declare function readJsonlBackwardWindow(path: string, options: {
|
|
17
|
+
readonly headBytes: number;
|
|
18
|
+
readonly targetLines: number;
|
|
19
|
+
readonly maxBytes: number;
|
|
20
|
+
readonly page?: {
|
|
21
|
+
readonly snapshotEnd: number;
|
|
22
|
+
readonly nextEnd: number;
|
|
23
|
+
readonly fileAnchor: string;
|
|
24
|
+
readonly anchorBytes: number;
|
|
25
|
+
};
|
|
26
|
+
}): Promise<JsonlBackwardWindow | undefined>;
|
|
6
27
|
/** Reads bounded head/tail windows without ever loading an unbounded transcript. */
|
|
7
28
|
export declare function readJsonlWindow(path: string, options: {
|
|
8
29
|
readonly headBytes?: number;
|
|
@@ -1,5 +1,94 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
import { open, readdir } from 'node:fs/promises';
|
|
2
3
|
import { join } from 'node:path';
|
|
4
|
+
export async function readJsonlFileAnchor(path, anchorBytes) {
|
|
5
|
+
try {
|
|
6
|
+
const handle = await open(path, 'r');
|
|
7
|
+
try {
|
|
8
|
+
const metadata = await handle.stat();
|
|
9
|
+
if (anchorBytes < 0 || anchorBytes > metadata.size)
|
|
10
|
+
return undefined;
|
|
11
|
+
return createHash('sha256')
|
|
12
|
+
.update(await readAt(handle, anchorBytes, 0))
|
|
13
|
+
.digest('base64url');
|
|
14
|
+
}
|
|
15
|
+
finally {
|
|
16
|
+
await handle.close();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Reads one newline-aligned window backwards from an opaque byte boundary. */
|
|
24
|
+
export async function readJsonlBackwardWindow(path, options) {
|
|
25
|
+
try {
|
|
26
|
+
const handle = await open(path, 'r');
|
|
27
|
+
try {
|
|
28
|
+
const metadata = await handle.stat();
|
|
29
|
+
const snapshotEnd = options.page?.snapshotEnd ?? metadata.size;
|
|
30
|
+
if (snapshotEnd > metadata.size)
|
|
31
|
+
return undefined;
|
|
32
|
+
const anchorBytes = options.page?.anchorBytes ?? Math.min(4096, snapshotEnd);
|
|
33
|
+
if (anchorBytes < 0 || anchorBytes > snapshotEnd)
|
|
34
|
+
return undefined;
|
|
35
|
+
const anchor = await readAt(handle, anchorBytes, 0);
|
|
36
|
+
const fileAnchor = createHash('sha256').update(anchor).digest('base64url');
|
|
37
|
+
if (options.page !== undefined && options.page.fileAnchor !== fileAnchor)
|
|
38
|
+
return undefined;
|
|
39
|
+
const headSize = Math.min(options.headBytes, snapshotEnd);
|
|
40
|
+
const end = Math.min(Math.max(options.page?.nextEnd ?? snapshotEnd, headSize), snapshotEnd);
|
|
41
|
+
const rawStart = Math.max(headSize, end - options.maxBytes);
|
|
42
|
+
const head = await readAt(handle, headSize, 0);
|
|
43
|
+
let tail = await readAt(handle, end - rawStart, rawStart);
|
|
44
|
+
let start = rawStart;
|
|
45
|
+
if (rawStart > headSize) {
|
|
46
|
+
const newline = tail.indexOf(0x0a);
|
|
47
|
+
if (newline < 0) {
|
|
48
|
+
tail = Buffer.alloc(0);
|
|
49
|
+
start = end;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
start += newline + 1;
|
|
53
|
+
tail = tail.subarray(newline + 1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (tail.length > 0) {
|
|
57
|
+
let lines = tail.at(-1) === 0x0a ? 0 : 1;
|
|
58
|
+
for (let index = tail.length - 1; index >= 0; index -= 1) {
|
|
59
|
+
if (tail[index] !== 0x0a)
|
|
60
|
+
continue;
|
|
61
|
+
lines += 1;
|
|
62
|
+
if (lines <= options.targetLines)
|
|
63
|
+
continue;
|
|
64
|
+
start += index + 1;
|
|
65
|
+
tail = tail.subarray(index + 1);
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const contiguous = start === headSize;
|
|
70
|
+
return {
|
|
71
|
+
content: contiguous
|
|
72
|
+
? Buffer.concat([head, tail]).toString('utf8')
|
|
73
|
+
: `${head.toString('utf8')}${headSize > 0 && tail.length > 0 ? '\n' : ''}${tail.toString('utf8')}`,
|
|
74
|
+
truncated: start > headSize,
|
|
75
|
+
pageContent: tail.toString('utf8'),
|
|
76
|
+
size: metadata.size,
|
|
77
|
+
start,
|
|
78
|
+
end,
|
|
79
|
+
snapshotEnd,
|
|
80
|
+
fileAnchor,
|
|
81
|
+
anchorBytes
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
await handle.close();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
3
92
|
/** Reads bounded head/tail windows without ever loading an unbounded transcript. */
|
|
4
93
|
export async function readJsonlWindow(path, options) {
|
|
5
94
|
try {
|
|
@@ -59,6 +59,16 @@ export interface NativeSessionHistory {
|
|
|
59
59
|
readonly lastActivityAt: number;
|
|
60
60
|
/** The bounded reader omitted bytes between its header and tail windows. */
|
|
61
61
|
readonly truncated?: boolean;
|
|
62
|
+
/** Opaque paging facts for reading the preceding newline-aligned JSONL window. */
|
|
63
|
+
readonly windowStart?: number;
|
|
64
|
+
readonly windowEnd?: number;
|
|
65
|
+
readonly snapshotEnd?: number;
|
|
66
|
+
readonly fileAnchor?: string;
|
|
67
|
+
readonly anchorBytes?: number;
|
|
68
|
+
/** The supplied page cursor no longer matched this transcript. */
|
|
69
|
+
readonly cursorReset?: boolean;
|
|
70
|
+
/** Page-size input used to derive the stable JSONL line window. */
|
|
71
|
+
readonly windowReadLimit?: number;
|
|
62
72
|
}
|
|
63
73
|
/** Actual context-window facts emitted by the Codex native transcript. */
|
|
64
74
|
export interface NativeCodexContextUsage {
|
|
@@ -78,12 +88,19 @@ export interface NativeClaudeContextUsage {
|
|
|
78
88
|
export declare function discoverNativeSessions(runner: RunnerName, workspacePath: string): Promise<readonly NativeSessionHistory[]>;
|
|
79
89
|
/**
|
|
80
90
|
* Reads every supported transcript header before applying a Workspace filter.
|
|
81
|
-
*
|
|
82
|
-
*
|
|
91
|
+
* A short Runner-level snapshot is shared across Workspaces and refreshes only
|
|
92
|
+
* files whose size or modification time changed. A fixed file-count cutoff
|
|
93
|
+
* would silently hide older sessions from a project with a large global history.
|
|
83
94
|
*/
|
|
84
95
|
export declare function discoverAllNativeSessions(runner: RunnerName): Promise<readonly NativeSessionHistory[]>;
|
|
85
96
|
/** Reads one already-discovered external session again to follow appended JSONL records. */
|
|
86
|
-
export declare function readNativeSession(runner: RunnerName, workspacePath: string, externalSessionId: string
|
|
97
|
+
export declare function readNativeSession(runner: RunnerName, workspacePath: string, externalSessionId: string, page?: {
|
|
98
|
+
readonly snapshotEnd: number;
|
|
99
|
+
readonly nextEnd: number;
|
|
100
|
+
readonly fileAnchor: string;
|
|
101
|
+
readonly anchorBytes: number;
|
|
102
|
+
readonly readLimit?: number;
|
|
103
|
+
}, limit?: number): Promise<NativeSessionHistory | undefined>;
|
|
87
104
|
/**
|
|
88
105
|
* Codex records the most recent prompt token count alongside the model context
|
|
89
106
|
* window in `event_msg/token_count`. Read only the tail of an already
|