@myagentroam/node 0.1.0
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/README.md +17 -0
- package/dist/capabilities.d.ts +5 -0
- package/dist/capabilities.js +23 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/claude-agent-sdk.d.ts +101 -0
- package/dist/claude-agent-sdk.js +341 -0
- package/dist/claude-agent-sdk.js.map +1 -0
- package/dist/claude-channel.d.ts +28 -0
- package/dist/claude-channel.js +45 -0
- package/dist/claude-channel.js.map +1 -0
- package/dist/codex-app-server.d.ts +96 -0
- package/dist/codex-app-server.js +361 -0
- package/dist/codex-app-server.js.map +1 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.js +51 -0
- package/dist/config.js.map +1 -0
- package/dist/connector.d.ts +343 -0
- package/dist/connector.js +5525 -0
- package/dist/connector.js.map +1 -0
- package/dist/database.d.ts +282 -0
- package/dist/database.js +1347 -0
- package/dist/database.js.map +1 -0
- package/dist/event-buffer.d.ts +12 -0
- package/dist/event-buffer.js +29 -0
- package/dist/event-buffer.js.map +1 -0
- package/dist/fake-runner.d.ts +42 -0
- package/dist/fake-runner.js +130 -0
- package/dist/fake-runner.js.map +1 -0
- package/dist/health.d.ts +4 -0
- package/dist/health.js +4 -0
- package/dist/health.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +47 -0
- package/dist/main.js.map +1 -0
- package/dist/native-session-history.d.ts +72 -0
- package/dist/native-session-history.js +647 -0
- package/dist/native-session-history.js.map +1 -0
- package/dist/operational.d.ts +30 -0
- package/dist/operational.js +82 -0
- package/dist/operational.js.map +1 -0
- package/dist/process-tree.d.ts +9 -0
- package/dist/process-tree.js +19 -0
- package/dist/process-tree.js.map +1 -0
- package/dist/runner-command-engine.d.ts +19 -0
- package/dist/runner-command-engine.js +47 -0
- package/dist/runner-command-engine.js.map +1 -0
- package/dist/runner-profiles.d.ts +11 -0
- package/dist/runner-profiles.js +138 -0
- package/dist/runner-profiles.js.map +1 -0
- package/dist/runner-usage.d.ts +33 -0
- package/dist/runner-usage.js +193 -0
- package/dist/runner-usage.js.map +1 -0
- package/dist/runtime-state.d.ts +174 -0
- package/dist/runtime-state.js +957 -0
- package/dist/runtime-state.js.map +1 -0
- package/dist/service.d.ts +4 -0
- package/dist/service.js +39 -0
- package/dist/service.js.map +1 -0
- package/dist/storage.d.ts +2 -0
- package/dist/storage.js +33 -0
- package/dist/storage.js.map +1 -0
- package/dist/terminal.d.ts +132 -0
- package/dist/terminal.js +417 -0
- package/dist/terminal.js.map +1 -0
- package/dist/workspace.d.ts +116 -0
- package/dist/workspace.js +732 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @myagentroam/node
|
|
2
|
+
|
|
3
|
+
MyAgentRoam Node runtime CLI for Linux and Windows.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Node.js `>=22.13 <25`
|
|
8
|
+
- A private Node configuration file containing the Server URL, Node credential, local data path, and allowed workspace roots
|
|
9
|
+
|
|
10
|
+
## Install and run
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install --global @myagentroam/node
|
|
14
|
+
mar-node run --config /path/to/mar-node.json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The package contains only the executable and its runtime dependencies. It never includes Node configuration, credentials, SQLite data, workspaces, or Runner credentials.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { probeClaudeCode } from './claude-agent-sdk.js';
|
|
2
|
+
import { probeCodex } from './codex-app-server.js';
|
|
3
|
+
export function detectCapabilities(commands = {}) {
|
|
4
|
+
if (process.platform !== 'win32' && process.platform !== 'linux') {
|
|
5
|
+
throw new Error('NODE_PLATFORM_UNSUPPORTED');
|
|
6
|
+
}
|
|
7
|
+
const codex = probeCodex(commands.codex);
|
|
8
|
+
const claudeCode = probeClaudeCode(commands.claudeCode);
|
|
9
|
+
return {
|
|
10
|
+
platform: process.platform,
|
|
11
|
+
architecture: process.arch,
|
|
12
|
+
nodeVersion: process.version,
|
|
13
|
+
codex: {
|
|
14
|
+
available: codex.available && codex.compatible,
|
|
15
|
+
...(codex.version === undefined ? {} : { version: codex.version })
|
|
16
|
+
},
|
|
17
|
+
claudeCode: {
|
|
18
|
+
available: claudeCode.available && claudeCode.compatible,
|
|
19
|
+
...(claudeCode.version === undefined ? {} : { version: claudeCode.version })
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,MAAM,UAAU,kBAAkB,CAChC,WAAsE,EAAE;IAExE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACxD,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,IAAI;QAC1B,WAAW,EAAE,OAAO,CAAC,OAAO;QAC5B,KAAK,EAAE;YACL,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,UAAU;YAC9C,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;SACnE;QACD,UAAU,EAAE;YACV,SAAS,EAAE,UAAU,CAAC,SAAS,IAAI,UAAU,CAAC,UAAU;YACxD,GAAG,CAAC,UAAU,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC;SAC7E;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { type CanUseTool, type Options, type PermissionResult, type Query, type SDKMessage, type SDKSessionInfo, type SDKUserMessage, type SessionMessage } from '@anthropic-ai/claude-agent-sdk';
|
|
2
|
+
export interface ClaudeCodeProbe {
|
|
3
|
+
readonly available: boolean;
|
|
4
|
+
readonly compatible: boolean;
|
|
5
|
+
readonly version?: string;
|
|
6
|
+
readonly authenticated: boolean;
|
|
7
|
+
readonly channel: {
|
|
8
|
+
readonly researchPreview: true;
|
|
9
|
+
readonly requiresExplicitOptIn: true;
|
|
10
|
+
readonly organizationPolicy: 'UNKNOWN';
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export interface ClaudeQueryInput {
|
|
14
|
+
readonly prompt: string;
|
|
15
|
+
readonly cwd: string;
|
|
16
|
+
readonly resumeSessionId?: string;
|
|
17
|
+
readonly model?: string | null;
|
|
18
|
+
readonly effort?: string | null;
|
|
19
|
+
readonly access?: string | null;
|
|
20
|
+
readonly attachments?: readonly ClaudeImageAttachment[];
|
|
21
|
+
readonly onPermission: CanUseTool;
|
|
22
|
+
readonly onMessage: (message: SDKMessage) => void;
|
|
23
|
+
readonly onChannelReply?: (content: string) => void;
|
|
24
|
+
}
|
|
25
|
+
/** Image blocks accepted by the Claude Agent SDK message input. */
|
|
26
|
+
export interface ClaudeImageAttachment {
|
|
27
|
+
readonly mime: 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp';
|
|
28
|
+
readonly dataBase64: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ClaudeRunHandle {
|
|
31
|
+
readonly completed: Promise<void>;
|
|
32
|
+
interrupt(): Promise<void>;
|
|
33
|
+
cancel(): void;
|
|
34
|
+
getContextUsage(): Promise<ClaudeContextUsage>;
|
|
35
|
+
}
|
|
36
|
+
/** A live, SDK-owned session accepts input only after the SDK consumes it. */
|
|
37
|
+
export interface ClaudeChannelRunHandle extends ClaudeRunHandle {
|
|
38
|
+
deliver(content: string): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
/** Normalized public portion of the official SDK context usage response. */
|
|
41
|
+
export interface ClaudeContextUsage {
|
|
42
|
+
readonly model: string;
|
|
43
|
+
readonly usedTokens: number;
|
|
44
|
+
readonly maxTokens: number;
|
|
45
|
+
readonly rawMaxTokens: number;
|
|
46
|
+
readonly percentage: number;
|
|
47
|
+
}
|
|
48
|
+
/** The small injectable surface prevents tests from depending on authentication. */
|
|
49
|
+
export interface ClaudeSdkBindings {
|
|
50
|
+
readonly query: (input: {
|
|
51
|
+
readonly prompt: string | AsyncIterable<SDKUserMessage>;
|
|
52
|
+
readonly options: Options;
|
|
53
|
+
}) => Query;
|
|
54
|
+
readonly listSessions: (options: {
|
|
55
|
+
readonly dir?: string;
|
|
56
|
+
readonly includeWorktrees?: boolean;
|
|
57
|
+
}) => Promise<SDKSessionInfo[]>;
|
|
58
|
+
readonly getSessionInfo: (sessionId: string, options: {
|
|
59
|
+
readonly dir?: string;
|
|
60
|
+
}) => Promise<SDKSessionInfo | undefined>;
|
|
61
|
+
readonly getSessionMessages: (sessionId: string, options: {
|
|
62
|
+
readonly dir?: string;
|
|
63
|
+
}) => Promise<SessionMessage[]>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Adapter for the supported Agent SDK APIs only. It neither parses nor writes
|
|
67
|
+
* Claude JSONL transcripts. A caller must serialize resume operations itself.
|
|
68
|
+
*/
|
|
69
|
+
export declare class ClaudeAgentSdkAdapter {
|
|
70
|
+
private readonly sdk;
|
|
71
|
+
constructor(sdk?: ClaudeSdkBindings);
|
|
72
|
+
start(input: ClaudeQueryInput): ClaudeRunHandle;
|
|
73
|
+
/**
|
|
74
|
+
* Opens one managed SDK stream and leaves it alive for verified Channel
|
|
75
|
+
* input. This is never used for foreign CLI/VS Code sessions.
|
|
76
|
+
*/
|
|
77
|
+
startChannel(input: ClaudeQueryInput): ClaudeChannelRunHandle;
|
|
78
|
+
private startWithPrompt;
|
|
79
|
+
listSessions(cwd: string): Promise<SDKSessionInfo[]>;
|
|
80
|
+
readSession(sessionId: string, cwd: string): Promise<SessionMessage[]>;
|
|
81
|
+
sessionInfo(sessionId: string, cwd: string): Promise<SDKSessionInfo | undefined>;
|
|
82
|
+
/**
|
|
83
|
+
* Reads context occupancy through the SDK's control channel. The input
|
|
84
|
+
* iterable deliberately never yields a user message, so this does not add
|
|
85
|
+
* `/context` or any synthetic text to the native conversation.
|
|
86
|
+
*/
|
|
87
|
+
readContextUsage(sessionId: string, cwd: string): Promise<ClaudeContextUsage>;
|
|
88
|
+
/**
|
|
89
|
+
* The SDK publishes the authoritative, session-specific command list in its
|
|
90
|
+
* first system/init record. Keep the input stream empty and stop as soon as
|
|
91
|
+
* that record arrives so discovery never submits a user prompt.
|
|
92
|
+
*/
|
|
93
|
+
discoverSlashCommands(cwd: string): Promise<readonly string[]>;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Channel availability deliberately remains conservative. The CLI does not
|
|
97
|
+
* expose an API to read organization allowlists, so a successful executable
|
|
98
|
+
* probe must never be interpreted as permission to activate a channel.
|
|
99
|
+
*/
|
|
100
|
+
export declare function probeClaudeCode(command?: string): ClaudeCodeProbe;
|
|
101
|
+
export declare function denyPermission(message?: string): PermissionResult;
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { createSdkMcpServer, getSessionInfo, getSessionMessages, listSessions, query } from '@anthropic-ai/claude-agent-sdk';
|
|
3
|
+
import { tool } from '@anthropic-ai/claude-agent-sdk';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { minimalRunnerEnvironment, platformCliInvocation } from './operational.js';
|
|
6
|
+
const nativeBindings = {
|
|
7
|
+
query,
|
|
8
|
+
listSessions,
|
|
9
|
+
getSessionInfo,
|
|
10
|
+
getSessionMessages
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Adapter for the supported Agent SDK APIs only. It neither parses nor writes
|
|
14
|
+
* Claude JSONL transcripts. A caller must serialize resume operations itself.
|
|
15
|
+
*/
|
|
16
|
+
export class ClaudeAgentSdkAdapter {
|
|
17
|
+
sdk;
|
|
18
|
+
constructor(sdk = nativeBindings) {
|
|
19
|
+
this.sdk = sdk;
|
|
20
|
+
}
|
|
21
|
+
start(input) {
|
|
22
|
+
return this.startWithPrompt(input, input.prompt);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Opens one managed SDK stream and leaves it alive for verified Channel
|
|
26
|
+
* input. This is never used for foreign CLI/VS Code sessions.
|
|
27
|
+
*/
|
|
28
|
+
startChannel(input) {
|
|
29
|
+
const channel = new ClaudeInputStream();
|
|
30
|
+
const run = this.startWithPrompt(input, channel, true);
|
|
31
|
+
const initial = channel.deliver(input.prompt, input.attachments);
|
|
32
|
+
return {
|
|
33
|
+
...run,
|
|
34
|
+
async deliver(content) {
|
|
35
|
+
if (content.length === 0)
|
|
36
|
+
throw new Error('CLAUDE_CHANNEL_MESSAGE_INVALID');
|
|
37
|
+
await channel.deliver(content);
|
|
38
|
+
},
|
|
39
|
+
cancel() {
|
|
40
|
+
channel.close();
|
|
41
|
+
run.cancel();
|
|
42
|
+
},
|
|
43
|
+
completed: initial.then(() => run.completed)
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
startWithPrompt(input, prompt, channelEnabled = false) {
|
|
47
|
+
const abortController = new AbortController();
|
|
48
|
+
const stream = this.sdk.query({
|
|
49
|
+
prompt,
|
|
50
|
+
options: {
|
|
51
|
+
cwd: input.cwd,
|
|
52
|
+
env: minimalRunnerEnvironment(),
|
|
53
|
+
...(input.resumeSessionId === undefined ? {} : { resume: input.resumeSessionId }),
|
|
54
|
+
...(input.model === undefined || input.model === null ? {} : { model: input.model }),
|
|
55
|
+
...(isClaudeEffort(input.effort) ? { effort: input.effort } : {}),
|
|
56
|
+
permissionMode: claudePermissionMode(input.access),
|
|
57
|
+
// This is the SDK's documented API-side public summary mode. We never
|
|
58
|
+
// enable or forward raw thinking deltas to the Workbench.
|
|
59
|
+
settings: { showThinkingSummaries: true },
|
|
60
|
+
abortController,
|
|
61
|
+
canUseTool: input.onPermission,
|
|
62
|
+
...(channelEnabled ? { mcpServers: { myagentroam: channelMcpServer(input) } } : {})
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
const completed = consume(stream, input.onMessage);
|
|
66
|
+
return {
|
|
67
|
+
completed,
|
|
68
|
+
async interrupt() {
|
|
69
|
+
await stream.interrupt();
|
|
70
|
+
},
|
|
71
|
+
async getContextUsage() {
|
|
72
|
+
return normalizeContextUsage(await stream.getContextUsage());
|
|
73
|
+
},
|
|
74
|
+
cancel() {
|
|
75
|
+
abortController.abort();
|
|
76
|
+
stream.close();
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
listSessions(cwd) {
|
|
81
|
+
// The SDK otherwise includes all sibling git worktrees by default. A
|
|
82
|
+
// MAR Workspace must only project sessions whose native cwd belongs to
|
|
83
|
+
// that registered Workspace.
|
|
84
|
+
return this.sdk.listSessions({ dir: cwd, includeWorktrees: false });
|
|
85
|
+
}
|
|
86
|
+
readSession(sessionId, cwd) {
|
|
87
|
+
return this.sdk.getSessionMessages(sessionId, { dir: cwd });
|
|
88
|
+
}
|
|
89
|
+
sessionInfo(sessionId, cwd) {
|
|
90
|
+
return this.sdk.getSessionInfo(sessionId, { dir: cwd });
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Reads context occupancy through the SDK's control channel. The input
|
|
94
|
+
* iterable deliberately never yields a user message, so this does not add
|
|
95
|
+
* `/context` or any synthetic text to the native conversation.
|
|
96
|
+
*/
|
|
97
|
+
async readContextUsage(sessionId, cwd) {
|
|
98
|
+
const abortController = new AbortController();
|
|
99
|
+
// 冷启动 Claude CLI 可能需要数秒加载本地 skills;3 秒会在控制响应
|
|
100
|
+
// 到达前主动中止,导致历史会话看似没有上下文。
|
|
101
|
+
const timeout = setTimeout(() => abortController.abort(), 15_000);
|
|
102
|
+
const emptyInput = {
|
|
103
|
+
async *[Symbol.asyncIterator]() {
|
|
104
|
+
await new Promise(() => undefined);
|
|
105
|
+
yield* [];
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const stream = this.sdk.query({
|
|
109
|
+
prompt: emptyInput,
|
|
110
|
+
options: {
|
|
111
|
+
cwd,
|
|
112
|
+
env: minimalRunnerEnvironment(),
|
|
113
|
+
resume: sessionId,
|
|
114
|
+
abortController
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
// Claude 的控制请求由 Query 的事件循环驱动。即使不发送用户输入,
|
|
118
|
+
// 也必须消费该流,initialize/get_context_usage 才能收到 CLI 响应。
|
|
119
|
+
// 这个 drain 只读取 SDK 事件,emptyInput 永远不会产生一个 Turn。
|
|
120
|
+
const drain = (async () => {
|
|
121
|
+
try {
|
|
122
|
+
for await (const message of stream) {
|
|
123
|
+
void message;
|
|
124
|
+
// Context probe has no presentation events to project.
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Closing this short-lived control query aborts its read loop normally.
|
|
129
|
+
}
|
|
130
|
+
})();
|
|
131
|
+
try {
|
|
132
|
+
await stream.initializationResult();
|
|
133
|
+
return normalizeContextUsage(await stream.getContextUsage());
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
clearTimeout(timeout);
|
|
137
|
+
abortController.abort();
|
|
138
|
+
stream.close();
|
|
139
|
+
await drain;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The SDK publishes the authoritative, session-specific command list in its
|
|
144
|
+
* first system/init record. Keep the input stream empty and stop as soon as
|
|
145
|
+
* that record arrives so discovery never submits a user prompt.
|
|
146
|
+
*/
|
|
147
|
+
async discoverSlashCommands(cwd) {
|
|
148
|
+
const abortController = new AbortController();
|
|
149
|
+
const timeout = setTimeout(() => abortController.abort(), 3_000);
|
|
150
|
+
const emptyInput = {
|
|
151
|
+
async *[Symbol.asyncIterator]() {
|
|
152
|
+
await new Promise(() => undefined);
|
|
153
|
+
yield* [];
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
const stream = this.sdk.query({
|
|
157
|
+
prompt: emptyInput,
|
|
158
|
+
options: { cwd, env: minimalRunnerEnvironment(), abortController }
|
|
159
|
+
});
|
|
160
|
+
try {
|
|
161
|
+
for await (const message of stream) {
|
|
162
|
+
const candidate = message;
|
|
163
|
+
if (candidate.type === 'system' &&
|
|
164
|
+
candidate.subtype === 'init' &&
|
|
165
|
+
Array.isArray(candidate.slash_commands)) {
|
|
166
|
+
return candidate.slash_commands.filter((value) => typeof value === 'string' && /^[A-Za-z0-9_./-]{1,128}$/.test(value));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return [];
|
|
170
|
+
}
|
|
171
|
+
finally {
|
|
172
|
+
clearTimeout(timeout);
|
|
173
|
+
abortController.abort();
|
|
174
|
+
stream.close();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function normalizeContextUsage(value) {
|
|
179
|
+
if (!Number.isFinite(value.totalTokens) ||
|
|
180
|
+
!Number.isInteger(value.totalTokens) ||
|
|
181
|
+
!Number.isFinite(value.maxTokens) ||
|
|
182
|
+
!Number.isInteger(value.maxTokens) ||
|
|
183
|
+
!Number.isFinite(value.rawMaxTokens) ||
|
|
184
|
+
!Number.isInteger(value.rawMaxTokens) ||
|
|
185
|
+
!Number.isFinite(value.percentage) ||
|
|
186
|
+
value.totalTokens < 0 ||
|
|
187
|
+
value.maxTokens <= 0 ||
|
|
188
|
+
value.rawMaxTokens <= 0 ||
|
|
189
|
+
typeof value.model !== 'string' ||
|
|
190
|
+
value.model.length === 0)
|
|
191
|
+
throw new Error('CLAUDE_CONTEXT_USAGE_INVALID');
|
|
192
|
+
return {
|
|
193
|
+
model: value.model,
|
|
194
|
+
usedTokens: value.totalTokens,
|
|
195
|
+
maxTokens: value.maxTokens,
|
|
196
|
+
rawMaxTokens: value.rawMaxTokens,
|
|
197
|
+
percentage: value.percentage
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
function isClaudeEffort(value) {
|
|
201
|
+
return (value === 'low' ||
|
|
202
|
+
value === 'medium' ||
|
|
203
|
+
value === 'high' ||
|
|
204
|
+
value === 'xhigh' ||
|
|
205
|
+
value === 'max');
|
|
206
|
+
}
|
|
207
|
+
function claudePermissionMode(access) {
|
|
208
|
+
if (access === 'accept-edits')
|
|
209
|
+
return 'acceptEdits';
|
|
210
|
+
if (access === 'bypass')
|
|
211
|
+
return 'bypassPermissions';
|
|
212
|
+
if (access === 'plan')
|
|
213
|
+
return 'plan';
|
|
214
|
+
return 'default';
|
|
215
|
+
}
|
|
216
|
+
function channelMcpServer(input) {
|
|
217
|
+
return createSdkMcpServer({
|
|
218
|
+
name: 'myagentroam',
|
|
219
|
+
version: '0.1.0',
|
|
220
|
+
instructions: 'Use the myagentroam_channel_reply tool only to send a concise reply to the Admin Channel.',
|
|
221
|
+
alwaysLoad: true,
|
|
222
|
+
tools: [
|
|
223
|
+
tool('channel_reply', 'Send one text reply to the authorized MyAgentRoam Admin Channel.', { content: z.string().min(1).max(20_000) }, async ({ content }) => {
|
|
224
|
+
input.onChannelReply?.(content);
|
|
225
|
+
return { content: [{ type: 'text', text: 'Channel reply delivered.' }] };
|
|
226
|
+
}, { alwaysLoad: true })
|
|
227
|
+
]
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
class ClaudeInputStream {
|
|
231
|
+
queued = [];
|
|
232
|
+
waiting;
|
|
233
|
+
closed = false;
|
|
234
|
+
deliver(content, attachments = []) {
|
|
235
|
+
if (this.closed)
|
|
236
|
+
return Promise.reject(new Error('CLAUDE_CHANNEL_CLOSED'));
|
|
237
|
+
return new Promise((received) => {
|
|
238
|
+
const entry = { message: toUserMessage(content, attachments), received };
|
|
239
|
+
const waiting = this.waiting;
|
|
240
|
+
this.waiting = undefined;
|
|
241
|
+
if (waiting !== undefined) {
|
|
242
|
+
received();
|
|
243
|
+
waiting({ value: entry.message, done: false });
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
this.queued.push(entry);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
async next() {
|
|
251
|
+
const entry = this.queued.shift();
|
|
252
|
+
if (entry !== undefined) {
|
|
253
|
+
entry.received();
|
|
254
|
+
return { value: entry.message, done: false };
|
|
255
|
+
}
|
|
256
|
+
if (this.closed)
|
|
257
|
+
return { value: undefined, done: true };
|
|
258
|
+
return new Promise((resolve) => {
|
|
259
|
+
this.waiting = resolve;
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
[Symbol.asyncIterator]() {
|
|
263
|
+
return this;
|
|
264
|
+
}
|
|
265
|
+
close() {
|
|
266
|
+
this.closed = true;
|
|
267
|
+
const waiting = this.waiting;
|
|
268
|
+
this.waiting = undefined;
|
|
269
|
+
waiting?.({ value: undefined, done: true });
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
function toUserMessage(content, attachments = []) {
|
|
273
|
+
return {
|
|
274
|
+
type: 'user',
|
|
275
|
+
message: {
|
|
276
|
+
role: 'user',
|
|
277
|
+
content: attachments.length === 0
|
|
278
|
+
? content
|
|
279
|
+
: [
|
|
280
|
+
{ type: 'text', text: content },
|
|
281
|
+
...attachments.map((attachment) => ({
|
|
282
|
+
type: 'image',
|
|
283
|
+
source: {
|
|
284
|
+
type: 'base64',
|
|
285
|
+
media_type: attachment.mime,
|
|
286
|
+
data: attachment.dataBase64
|
|
287
|
+
}
|
|
288
|
+
}))
|
|
289
|
+
]
|
|
290
|
+
},
|
|
291
|
+
parent_tool_use_id: null,
|
|
292
|
+
shouldQuery: true
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
async function consume(stream, onMessage) {
|
|
296
|
+
for await (const message of stream)
|
|
297
|
+
onMessage(message);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Channel availability deliberately remains conservative. The CLI does not
|
|
301
|
+
* expose an API to read organization allowlists, so a successful executable
|
|
302
|
+
* probe must never be interpreted as permission to activate a channel.
|
|
303
|
+
*/
|
|
304
|
+
export function probeClaudeCode(command = 'claude') {
|
|
305
|
+
const versionInvocation = platformCliInvocation(command, ['--version']);
|
|
306
|
+
const versionResult = spawnSync(versionInvocation.command, versionInvocation.args, {
|
|
307
|
+
encoding: 'utf8',
|
|
308
|
+
timeout: 3_000
|
|
309
|
+
});
|
|
310
|
+
const version = versionResult.status === 0 ? versionResult.stdout.trim() : undefined;
|
|
311
|
+
const authInvocation = platformCliInvocation(command, ['auth', 'status', '--json']);
|
|
312
|
+
const authResult = spawnSync(authInvocation.command, authInvocation.args, {
|
|
313
|
+
encoding: 'utf8',
|
|
314
|
+
timeout: 3_000
|
|
315
|
+
});
|
|
316
|
+
let authenticated = false;
|
|
317
|
+
if (authResult.status === 0) {
|
|
318
|
+
try {
|
|
319
|
+
const parsed = JSON.parse(authResult.stdout);
|
|
320
|
+
authenticated = parsed.loggedIn === true;
|
|
321
|
+
}
|
|
322
|
+
catch {
|
|
323
|
+
authenticated = false;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return {
|
|
327
|
+
available: version !== undefined,
|
|
328
|
+
compatible: version !== undefined && /^2\.1\./.test(version),
|
|
329
|
+
...(version === undefined ? {} : { version }),
|
|
330
|
+
authenticated,
|
|
331
|
+
channel: {
|
|
332
|
+
researchPreview: true,
|
|
333
|
+
requiresExplicitOptIn: true,
|
|
334
|
+
organizationPolicy: 'UNKNOWN'
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
export function denyPermission(message = 'USER_DECISION_REJECTED') {
|
|
339
|
+
return { behavior: 'deny', message };
|
|
340
|
+
}
|
|
341
|
+
//# sourceMappingURL=claude-agent-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-agent-sdk.js","sourceRoot":"","sources":["../src/claude-agent-sdk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type ChannelDelivery = 'PENDING_RECEIPT' | 'STEERED' | 'QUEUED_NEXT_TURN' | 'REJECTED';
|
|
2
|
+
export interface ClaudeChannelMessage {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
readonly senderId: string;
|
|
5
|
+
readonly token: string;
|
|
6
|
+
readonly content: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ClaudeChannelReceipt {
|
|
9
|
+
readonly messageId: string;
|
|
10
|
+
readonly result: Exclude<ChannelDelivery, 'PENDING_RECEIPT'>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Per-session authorization and receipt bookkeeping for a Channel MCP plugin.
|
|
14
|
+
* A transport may acknowledge only that it wrote an event; callers must wait
|
|
15
|
+
* for acknowledge() before displaying a steering success.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ClaudeChannelGate {
|
|
18
|
+
readonly sessionId: string;
|
|
19
|
+
readonly token: string;
|
|
20
|
+
private readonly expiresAt;
|
|
21
|
+
private readonly now;
|
|
22
|
+
private readonly allowedSenders;
|
|
23
|
+
private readonly deliveries;
|
|
24
|
+
constructor(sessionId: string, token?: string, senders?: readonly string[], expiresAt?: number, now?: () => number);
|
|
25
|
+
accept(message: ClaudeChannelMessage): ChannelDelivery;
|
|
26
|
+
acknowledge(receipt: ClaudeChannelReceipt): ChannelDelivery;
|
|
27
|
+
delivery(messageId: string): ChannelDelivery | undefined;
|
|
28
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Per-session authorization and receipt bookkeeping for a Channel MCP plugin.
|
|
4
|
+
* A transport may acknowledge only that it wrote an event; callers must wait
|
|
5
|
+
* for acknowledge() before displaying a steering success.
|
|
6
|
+
*/
|
|
7
|
+
export class ClaudeChannelGate {
|
|
8
|
+
sessionId;
|
|
9
|
+
token;
|
|
10
|
+
expiresAt;
|
|
11
|
+
now;
|
|
12
|
+
allowedSenders;
|
|
13
|
+
deliveries = new Map();
|
|
14
|
+
constructor(sessionId, token = randomUUID(), senders = ['admin'], expiresAt = Date.now() + 10 * 60_000, now = Date.now) {
|
|
15
|
+
this.sessionId = sessionId;
|
|
16
|
+
this.token = token;
|
|
17
|
+
this.expiresAt = expiresAt;
|
|
18
|
+
this.now = now;
|
|
19
|
+
this.allowedSenders = new Set(senders);
|
|
20
|
+
}
|
|
21
|
+
accept(message) {
|
|
22
|
+
if (message.token !== this.token ||
|
|
23
|
+
!this.allowedSenders.has(message.senderId) ||
|
|
24
|
+
this.now() >= this.expiresAt ||
|
|
25
|
+
message.content.length === 0) {
|
|
26
|
+
return 'REJECTED';
|
|
27
|
+
}
|
|
28
|
+
const previous = this.deliveries.get(message.id);
|
|
29
|
+
if (previous !== undefined)
|
|
30
|
+
return previous;
|
|
31
|
+
this.deliveries.set(message.id, 'PENDING_RECEIPT');
|
|
32
|
+
return 'PENDING_RECEIPT';
|
|
33
|
+
}
|
|
34
|
+
acknowledge(receipt) {
|
|
35
|
+
const previous = this.deliveries.get(receipt.messageId);
|
|
36
|
+
if (previous !== 'PENDING_RECEIPT')
|
|
37
|
+
return 'REJECTED';
|
|
38
|
+
this.deliveries.set(receipt.messageId, receipt.result);
|
|
39
|
+
return receipt.result;
|
|
40
|
+
}
|
|
41
|
+
delivery(messageId) {
|
|
42
|
+
return this.deliveries.get(messageId);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=claude-channel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-channel.js","sourceRoot":"","sources":["../src/claude-channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAgBzC;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IAKjB;IACA;IAEQ;IACA;IARF,cAAc,CAAsB;IACpC,UAAU,GAAG,IAAI,GAAG,EAA2B,CAAC;IAEjE,YACW,SAAiB,EACjB,QAAgB,UAAU,EAAE,EACrC,UAA6B,CAAC,OAAO,CAAC,EACrB,YAAY,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,EACpC,MAAoB,IAAI,CAAC,GAAG;QAJpC,cAAS,GAAT,SAAS,CAAQ;QACjB,UAAK,GAAL,KAAK,CAAuB;QAEpB,cAAS,GAAT,SAAS,CAA2B;QACpC,QAAG,GAAH,GAAG,CAAyB;QAE7C,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,OAA6B;QAClC,IACE,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK;YAC5B,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC1C,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,SAAS;YAC5B,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAC5B,CAAC;YACD,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACjD,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;QAC5C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC;QACnD,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,WAAW,CAAC,OAA6B;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACxD,IAAI,QAAQ,KAAK,iBAAiB;YAAE,OAAO,UAAU,CAAC;QACtD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACvD,OAAO,OAAO,CAAC,MAAM,CAAC;IACxB,CAAC;IAED,QAAQ,CAAC,SAAiB;QACxB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;CACF"}
|