@geminilight/mindos 1.0.10 → 1.1.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/README_zh.md +3 -3
- package/bin/mindos-shim.cjs +318 -7
- package/dist/agent/prompts.d.ts +1 -1
- package/dist/agent/prompts.d.ts.map +1 -1
- package/dist/agent/prompts.js +14 -0
- package/dist/agent/prompts.js.map +1 -1
- package/dist/agent-runtime/claude-code-cli.d.ts +34 -0
- package/dist/agent-runtime/claude-code-cli.d.ts.map +1 -0
- package/dist/agent-runtime/claude-code-cli.js +259 -0
- package/dist/agent-runtime/claude-code-cli.js.map +1 -0
- package/dist/agent-runtime/claude-code-sdk.d.ts +41 -0
- package/dist/agent-runtime/claude-code-sdk.d.ts.map +1 -0
- package/dist/agent-runtime/claude-code-sdk.js +553 -0
- package/dist/agent-runtime/claude-code-sdk.js.map +1 -0
- package/dist/agent-runtime/codex-app-server.d.ts +154 -0
- package/dist/agent-runtime/codex-app-server.d.ts.map +1 -0
- package/dist/agent-runtime/codex-app-server.js +628 -0
- package/dist/agent-runtime/codex-app-server.js.map +1 -0
- package/dist/agent-runtime/codex-env.d.ts +41 -0
- package/dist/agent-runtime/codex-env.d.ts.map +1 -0
- package/dist/agent-runtime/codex-env.js +278 -0
- package/dist/agent-runtime/codex-env.js.map +1 -0
- package/dist/agent-runtime/index.d.ts +7 -0
- package/dist/agent-runtime/index.d.ts.map +1 -0
- package/dist/agent-runtime/index.js +7 -0
- package/dist/agent-runtime/index.js.map +1 -0
- package/dist/agent-runtime/run.d.ts +111 -0
- package/dist/agent-runtime/run.d.ts.map +1 -0
- package/dist/agent-runtime/run.js +681 -0
- package/dist/agent-runtime/run.js.map +1 -0
- package/dist/agent-runtime/runtime-env.d.ts +28 -0
- package/dist/agent-runtime/runtime-env.d.ts.map +1 -0
- package/dist/agent-runtime/runtime-env.js +66 -0
- package/dist/agent-runtime/runtime-env.js.map +1 -0
- package/dist/agent-runtime.d.ts +2 -0
- package/dist/agent-runtime.d.ts.map +1 -0
- package/dist/agent-runtime.js +2 -0
- package/dist/agent-runtime.js.map +1 -0
- package/dist/client.d.ts +8 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/foundation/config/schema.d.ts +30 -141
- package/dist/foundation/config/schema.d.ts.map +1 -1
- package/dist/foundation/config/schema.js +18 -4
- package/dist/foundation/config/schema.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/knowledge/audit/index.d.ts +4 -0
- package/dist/knowledge/audit/index.d.ts.map +1 -1
- package/dist/knowledge/audit/index.js +92 -8
- package/dist/knowledge/audit/index.js.map +1 -1
- package/dist/knowledge/git/index.d.ts.map +1 -1
- package/dist/knowledge/git/index.js +43 -2
- package/dist/knowledge/git/index.js.map +1 -1
- package/dist/protocols/acp/agent-descriptors.d.ts.map +1 -1
- package/dist/protocols/acp/agent-descriptors.js +7 -4
- package/dist/protocols/acp/agent-descriptors.js.map +1 -1
- package/dist/protocols/acp/index.js +39 -28
- package/dist/protocols/acp/session.d.ts.map +1 -1
- package/dist/protocols/acp/session.js +11 -14
- package/dist/protocols/acp/session.js.map +1 -1
- package/dist/protocols/acp/subprocess.d.ts +4 -1
- package/dist/protocols/acp/subprocess.d.ts.map +1 -1
- package/dist/protocols/acp/subprocess.js +37 -10
- package/dist/protocols/acp/subprocess.js.map +1 -1
- package/dist/protocols/mcp-server/index.cjs +80 -68
- package/dist/server/channel-contract.d.ts +13 -0
- package/dist/server/channel-contract.d.ts.map +1 -0
- package/dist/server/channel-contract.js +115 -0
- package/dist/server/channel-contract.js.map +1 -0
- package/dist/server/contract.d.ts.map +1 -1
- package/dist/server/contract.js +12 -0
- package/dist/server/contract.js.map +1 -1
- package/dist/server/handlers/a2a.d.ts +7 -0
- package/dist/server/handlers/a2a.d.ts.map +1 -1
- package/dist/server/handlers/a2a.js +5 -1
- package/dist/server/handlers/a2a.js.map +1 -1
- package/dist/server/handlers/agent-capabilities.d.ts +60 -0
- package/dist/server/handlers/agent-capabilities.d.ts.map +1 -0
- package/dist/server/handlers/agent-capabilities.js +178 -0
- package/dist/server/handlers/agent-capabilities.js.map +1 -0
- package/dist/server/handlers/agent-runtime-codex.d.ts +29 -0
- package/dist/server/handlers/agent-runtime-codex.d.ts.map +1 -0
- package/dist/server/handlers/agent-runtime-codex.js +198 -0
- package/dist/server/handlers/agent-runtime-codex.js.map +1 -0
- package/dist/server/handlers/agent-runtimes.d.ts +136 -0
- package/dist/server/handlers/agent-runtimes.d.ts.map +1 -0
- package/dist/server/handlers/agent-runtimes.js +712 -0
- package/dist/server/handlers/agent-runtimes.js.map +1 -0
- package/dist/server/handlers/agents.d.ts +6 -0
- package/dist/server/handlers/agents.d.ts.map +1 -1
- package/dist/server/handlers/agents.js +41 -6
- package/dist/server/handlers/agents.js.map +1 -1
- package/dist/server/handlers/ask.d.ts +18 -0
- package/dist/server/handlers/ask.d.ts.map +1 -1
- package/dist/server/handlers/ask.js +70 -0
- package/dist/server/handlers/ask.js.map +1 -1
- package/dist/server/handlers/channels-verify.d.ts +1 -1
- package/dist/server/handlers/channels-verify.d.ts.map +1 -1
- package/dist/server/handlers/channels-verify.js +1 -63
- package/dist/server/handlers/channels-verify.js.map +1 -1
- package/dist/server/handlers/extract-docx.d.ts +42 -0
- package/dist/server/handlers/extract-docx.d.ts.map +1 -0
- package/dist/server/handlers/extract-docx.js +101 -0
- package/dist/server/handlers/extract-docx.js.map +1 -0
- package/dist/server/handlers/extract-pdf.d.ts +32 -0
- package/dist/server/handlers/extract-pdf.d.ts.map +1 -0
- package/dist/server/handlers/extract-pdf.js +116 -0
- package/dist/server/handlers/extract-pdf.js.map +1 -0
- package/dist/server/handlers/im-activity.d.ts.map +1 -1
- package/dist/server/handlers/im-activity.js +26 -1
- package/dist/server/handlers/im-activity.js.map +1 -1
- package/dist/server/handlers/im-config.d.ts +1 -1
- package/dist/server/handlers/im-config.d.ts.map +1 -1
- package/dist/server/handlers/im-config.js +69 -59
- package/dist/server/handlers/im-config.js.map +1 -1
- package/dist/server/handlers/im-feishu-oauth.d.ts +55 -0
- package/dist/server/handlers/im-feishu-oauth.d.ts.map +1 -0
- package/dist/server/handlers/im-feishu-oauth.js +218 -0
- package/dist/server/handlers/im-feishu-oauth.js.map +1 -0
- package/dist/server/handlers/im-status.d.ts +15 -0
- package/dist/server/handlers/im-status.d.ts.map +1 -1
- package/dist/server/handlers/im-status.js +41 -24
- package/dist/server/handlers/im-status.js.map +1 -1
- package/dist/server/handlers/inbox-source.d.ts +18 -0
- package/dist/server/handlers/inbox-source.d.ts.map +1 -0
- package/dist/server/handlers/inbox-source.js +108 -0
- package/dist/server/handlers/inbox-source.js.map +1 -0
- package/dist/server/handlers/inbox.d.ts +2 -0
- package/dist/server/handlers/inbox.d.ts.map +1 -1
- package/dist/server/handlers/inbox.js +34 -2
- package/dist/server/handlers/inbox.js.map +1 -1
- package/dist/server/handlers/mcp-agents.d.ts +16 -1
- package/dist/server/handlers/mcp-agents.d.ts.map +1 -1
- package/dist/server/handlers/mcp-agents.js +174 -44
- package/dist/server/handlers/mcp-agents.js.map +1 -1
- package/dist/server/handlers/mcp-install.d.ts +5 -0
- package/dist/server/handlers/mcp-install.d.ts.map +1 -1
- package/dist/server/handlers/mcp-install.js +68 -20
- package/dist/server/handlers/mcp-install.js.map +1 -1
- package/dist/server/handlers/mcp-restart.js +1 -1
- package/dist/server/handlers/mcp-restart.js.map +1 -1
- package/dist/server/handlers/mcp-status.d.ts +7 -1
- package/dist/server/handlers/mcp-status.d.ts.map +1 -1
- package/dist/server/handlers/mcp-status.js +14 -1
- package/dist/server/handlers/mcp-status.js.map +1 -1
- package/dist/server/handlers/settings-list-models.d.ts +1 -1
- package/dist/server/handlers/settings-list-models.d.ts.map +1 -1
- package/dist/server/handlers/settings-list-models.js +6 -5
- package/dist/server/handlers/settings-list-models.js.map +1 -1
- package/dist/server/handlers/settings-test-key.d.ts.map +1 -1
- package/dist/server/handlers/settings-test-key.js +17 -7
- package/dist/server/handlers/settings-test-key.js.map +1 -1
- package/dist/server/handlers/settings.d.ts +5 -1
- package/dist/server/handlers/settings.d.ts.map +1 -1
- package/dist/server/handlers/settings.js +54 -5
- package/dist/server/handlers/settings.js.map +1 -1
- package/dist/server/handlers/skills.d.ts +1 -0
- package/dist/server/handlers/skills.d.ts.map +1 -1
- package/dist/server/handlers/skills.js +7 -5
- package/dist/server/handlers/skills.js.map +1 -1
- package/dist/server/handlers/sync.d.ts +15 -4
- package/dist/server/handlers/sync.d.ts.map +1 -1
- package/dist/server/handlers/sync.js +552 -81
- package/dist/server/handlers/sync.js.map +1 -1
- package/dist/server/handlers/uninstall.js +1 -0
- package/dist/server/handlers/uninstall.js.map +1 -1
- package/dist/server/handlers/update.js +1 -0
- package/dist/server/handlers/update.js.map +1 -1
- package/dist/server/http.d.ts +20 -0
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +228 -25
- package/dist/server/http.js.map +1 -1
- package/dist/server/index.d.ts +14 -5
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +11 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp-agent-registry.d.ts +184 -0
- package/dist/server/mcp-agent-registry.d.ts.map +1 -1
- package/dist/server/mcp-agent-registry.js +100 -9
- package/dist/server/mcp-agent-registry.js.map +1 -1
- package/dist/server/provider-settings.d.ts +38 -0
- package/dist/server/provider-settings.d.ts.map +1 -0
- package/dist/server/provider-settings.js +286 -0
- package/dist/server/provider-settings.js.map +1 -0
- package/dist/server/route-ownership.d.ts.map +1 -1
- package/dist/server/route-ownership.js +18 -2
- package/dist/server/route-ownership.js.map +1 -1
- package/dist/server/runtime.d.ts +1 -0
- package/dist/server/runtime.d.ts.map +1 -1
- package/dist/server/runtime.js.map +1 -1
- package/dist/session/index.d.ts +96 -15
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/index.js +162 -30
- package/dist/session/index.js.map +1 -1
- package/dist/session/pi-coding-agent-runtime.js +3 -3
- package/dist/session/pi-coding-agent-runtime.js.map +1 -1
- package/dist/session/redaction.d.ts +3 -0
- package/dist/session/redaction.d.ts.map +1 -0
- package/dist/session/redaction.js +47 -0
- package/dist/session/redaction.js.map +1 -0
- package/dist/setup/index.d.ts +1 -0
- package/dist/setup/index.d.ts.map +1 -1
- package/dist/setup/index.js +13 -0
- package/dist/setup/index.js.map +1 -1
- package/package.json +18 -12
- package/src/cli.js +1 -0
|
@@ -0,0 +1,681 @@
|
|
|
1
|
+
import { createClaudeCodeCliClient, createClaudeCodeCliStdioTransport, } from './claude-code-cli.js';
|
|
2
|
+
import { createClaudeCodeSdkClient, isClaudeCodeSdkNativeBinaryError, loadClaudeCodeSdkModule, } from './claude-code-sdk.js';
|
|
3
|
+
import { createCodexAppServerClient, createCodexAppServerStdioTransport, mapCodexAppServerNotificationToSseEvents, } from './codex-app-server.js';
|
|
4
|
+
function sendNativeRuntimeStatus(options, runtime, message) {
|
|
5
|
+
options.send({ type: 'status', visible: true, runtime, message });
|
|
6
|
+
}
|
|
7
|
+
export async function runMindosAgentRuntimeAskSession(options) {
|
|
8
|
+
const scoped = withNativeRuntimeTimeout(options);
|
|
9
|
+
try {
|
|
10
|
+
if (scoped.options.runtime.kind === 'claude') {
|
|
11
|
+
return await runClaudeAskSession(scoped.options);
|
|
12
|
+
}
|
|
13
|
+
return await runCodexAskSession(scoped.options);
|
|
14
|
+
}
|
|
15
|
+
finally {
|
|
16
|
+
scoped.cleanup();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function createNativeRuntimeTimeoutError(timeoutMs) {
|
|
20
|
+
const seconds = Math.max(1, Math.round(timeoutMs / 1000));
|
|
21
|
+
const error = new Error(`Native runtime timed out after ${seconds}s.`);
|
|
22
|
+
error.code = 'TIMEOUT';
|
|
23
|
+
return error;
|
|
24
|
+
}
|
|
25
|
+
function isTimeoutError(value) {
|
|
26
|
+
return value instanceof Error && value.code === 'TIMEOUT';
|
|
27
|
+
}
|
|
28
|
+
function errorFromRuntimeFailure(error, signal) {
|
|
29
|
+
const reason = signal?.reason;
|
|
30
|
+
if (signal?.aborted && isTimeoutError(reason))
|
|
31
|
+
return reason;
|
|
32
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
33
|
+
}
|
|
34
|
+
function throwIfNativeRuntimeTimedOut(signal) {
|
|
35
|
+
if (signal?.aborted && isTimeoutError(signal.reason)) {
|
|
36
|
+
throw signal.reason;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function abortErrorFromSignal(signal) {
|
|
40
|
+
const reason = signal.reason;
|
|
41
|
+
if (reason instanceof Error)
|
|
42
|
+
return reason;
|
|
43
|
+
return new Error(reason ? String(reason) : 'Native runtime aborted.');
|
|
44
|
+
}
|
|
45
|
+
function throwIfNativeRuntimeAborted(signal) {
|
|
46
|
+
if (signal?.aborted) {
|
|
47
|
+
throw abortErrorFromSignal(signal);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function settleIteratorReturn(iterator) {
|
|
51
|
+
const result = iterator.return?.();
|
|
52
|
+
if (result && typeof result.then === 'function') {
|
|
53
|
+
void Promise.resolve(result).catch(() => { });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function nextWithNativeRuntimeAbort(iterator, signal) {
|
|
57
|
+
throwIfNativeRuntimeAborted(signal);
|
|
58
|
+
const nextPromise = Promise.resolve(iterator.next());
|
|
59
|
+
nextPromise.catch(() => { });
|
|
60
|
+
if (!signal)
|
|
61
|
+
return nextPromise;
|
|
62
|
+
let removeAbortListener = () => { };
|
|
63
|
+
const abortPromise = new Promise((_resolve, reject) => {
|
|
64
|
+
const abort = () => reject(abortErrorFromSignal(signal));
|
|
65
|
+
removeAbortListener = () => signal.removeEventListener('abort', abort);
|
|
66
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
67
|
+
});
|
|
68
|
+
try {
|
|
69
|
+
return await Promise.race([nextPromise, abortPromise]);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (signal.aborted) {
|
|
73
|
+
throw abortErrorFromSignal(signal);
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
removeAbortListener();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function* iterateWithNativeRuntimeAbort(iterable, signal) {
|
|
82
|
+
const iterator = iterable[Symbol.asyncIterator]();
|
|
83
|
+
let completed = false;
|
|
84
|
+
try {
|
|
85
|
+
while (true) {
|
|
86
|
+
const next = await nextWithNativeRuntimeAbort(iterator, signal);
|
|
87
|
+
if (next.done) {
|
|
88
|
+
completed = true;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
yield next.value;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
if (!completed) {
|
|
96
|
+
settleIteratorReturn(iterator);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function withNativeRuntimeTimeout(options) {
|
|
101
|
+
const timeoutMs = options.timeoutMs;
|
|
102
|
+
if (!timeoutMs || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
103
|
+
return { options, cleanup: () => { } };
|
|
104
|
+
}
|
|
105
|
+
const controller = new AbortController();
|
|
106
|
+
const abortFromParent = () => {
|
|
107
|
+
if (!controller.signal.aborted) {
|
|
108
|
+
controller.abort(options.signal?.reason ?? new Error('Native runtime aborted.'));
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
if (options.signal?.aborted) {
|
|
112
|
+
abortFromParent();
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
options.signal?.addEventListener('abort', abortFromParent, { once: true });
|
|
116
|
+
}
|
|
117
|
+
const timer = setTimeout(() => {
|
|
118
|
+
if (!controller.signal.aborted) {
|
|
119
|
+
controller.abort(createNativeRuntimeTimeoutError(timeoutMs));
|
|
120
|
+
}
|
|
121
|
+
}, timeoutMs);
|
|
122
|
+
return {
|
|
123
|
+
options: {
|
|
124
|
+
...options,
|
|
125
|
+
signal: controller.signal,
|
|
126
|
+
},
|
|
127
|
+
cleanup: () => {
|
|
128
|
+
clearTimeout(timer);
|
|
129
|
+
options.signal?.removeEventListener('abort', abortFromParent);
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
async function runClaudeAskSession(options) {
|
|
134
|
+
let client;
|
|
135
|
+
let sessionId = options.runtime.externalSessionId;
|
|
136
|
+
const turnState = { sessionId };
|
|
137
|
+
try {
|
|
138
|
+
sendNativeRuntimeStatus(options, 'claude', sessionId
|
|
139
|
+
? 'Resuming Claude Code locally.'
|
|
140
|
+
: 'Starting Claude Code locally.');
|
|
141
|
+
const resolvedClient = await resolveClaudeClient(options);
|
|
142
|
+
client = resolvedClient.client;
|
|
143
|
+
try {
|
|
144
|
+
sessionId = await runClaudeTurnWithClient(options, resolvedClient, turnState);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
sessionId = turnState.sessionId;
|
|
148
|
+
const err = errorFromRuntimeFailure(error, options.signal);
|
|
149
|
+
if (resolvedClient.source !== 'sdk' || !shouldFallbackFromClaudeSdkTurnError(err, options.signal)) {
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
await client.close?.();
|
|
153
|
+
sendNativeRuntimeStatus(options, 'claude', `Claude Agent SDK could not start its native runtime; using Claude Code CLI fallback. ${err.message}`);
|
|
154
|
+
const cliClient = await resolveClaudeCliClient(options);
|
|
155
|
+
client = cliClient;
|
|
156
|
+
turnState.sessionId = sessionId;
|
|
157
|
+
sessionId = await runClaudeTurnWithClient(options, {
|
|
158
|
+
client: cliClient,
|
|
159
|
+
usesCliPermissionPrompt: true,
|
|
160
|
+
source: 'cli',
|
|
161
|
+
}, turnState);
|
|
162
|
+
}
|
|
163
|
+
throwIfNativeRuntimeTimedOut(options.signal);
|
|
164
|
+
return sessionId ? { externalSessionId: sessionId } : {};
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
const err = errorFromRuntimeFailure(error, options.signal);
|
|
168
|
+
if (sessionId) {
|
|
169
|
+
options.send({
|
|
170
|
+
type: 'runtime_binding',
|
|
171
|
+
runtime: 'claude',
|
|
172
|
+
externalSessionId: sessionId,
|
|
173
|
+
cwd: options.cwd,
|
|
174
|
+
status: 'failed',
|
|
175
|
+
reason: err.message,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
options.send({ type: 'error', message: `Claude Code native runtime error: ${err.message}` });
|
|
179
|
+
return { error: err, ...(sessionId ? { externalSessionId: sessionId } : {}) };
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
await client?.close?.();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
async function runClaudeTurnWithClient(options, resolvedClient, state) {
|
|
186
|
+
let sessionId = state.sessionId;
|
|
187
|
+
const permissionPrompt = resolvedClient.usesCliPermissionPrompt
|
|
188
|
+
? await options.services?.createClaudePermissionPrompt?.({
|
|
189
|
+
cwd: options.cwd,
|
|
190
|
+
signal: options.signal,
|
|
191
|
+
})
|
|
192
|
+
: undefined;
|
|
193
|
+
const turnEvents = resolvedClient.client.startTurn({
|
|
194
|
+
prompt: options.prompt,
|
|
195
|
+
cwd: options.cwd,
|
|
196
|
+
...(sessionId ? { sessionId } : {}),
|
|
197
|
+
permissionMode: claudeCliPermissionModeForMindosMode(options.permissionMode),
|
|
198
|
+
...(permissionPrompt ? { permissionPrompt } : {}),
|
|
199
|
+
signal: options.signal,
|
|
200
|
+
});
|
|
201
|
+
for await (const event of iterateWithNativeRuntimeAbort(turnEvents, options.signal)) {
|
|
202
|
+
if (event.type === 'session_id') {
|
|
203
|
+
sessionId = event.sessionId;
|
|
204
|
+
state.sessionId = event.sessionId;
|
|
205
|
+
options.send({
|
|
206
|
+
type: 'runtime_binding',
|
|
207
|
+
runtime: 'claude',
|
|
208
|
+
externalSessionId: event.sessionId,
|
|
209
|
+
cwd: options.cwd,
|
|
210
|
+
});
|
|
211
|
+
sendNativeRuntimeStatus(options, 'claude', 'Claude Code is connected and working in this chat.');
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
options.send(event);
|
|
215
|
+
}
|
|
216
|
+
return sessionId;
|
|
217
|
+
}
|
|
218
|
+
function shouldFallbackFromClaudeSdkTurnError(error, signal) {
|
|
219
|
+
if (signal?.aborted)
|
|
220
|
+
return false;
|
|
221
|
+
return isClaudeCodeSdkNativeBinaryError(error);
|
|
222
|
+
}
|
|
223
|
+
function claudeCliPermissionModeForMindosMode(mode) {
|
|
224
|
+
return mode === 'readonly' ? 'dontAsk' : 'default';
|
|
225
|
+
}
|
|
226
|
+
async function runCodexAskSession(options) {
|
|
227
|
+
let client;
|
|
228
|
+
let threadId = options.runtime.externalSessionId;
|
|
229
|
+
const pendingServerRequests = new Map();
|
|
230
|
+
try {
|
|
231
|
+
sendNativeRuntimeStatus(options, 'codex', threadId
|
|
232
|
+
? 'Resuming Codex locally.'
|
|
233
|
+
: 'Starting Codex locally.');
|
|
234
|
+
client = await resolveCodexClient(options, async (request) => {
|
|
235
|
+
return handleCodexServerRequest(request, options, pendingServerRequests);
|
|
236
|
+
});
|
|
237
|
+
await client.initialize({ signal: options.signal });
|
|
238
|
+
const thread = threadId
|
|
239
|
+
? await client.resumeThread({ threadId }, { signal: options.signal })
|
|
240
|
+
: await client.startThread({ cwd: options.cwd }, { signal: options.signal });
|
|
241
|
+
threadId = thread.threadId;
|
|
242
|
+
options.send({
|
|
243
|
+
type: 'runtime_binding',
|
|
244
|
+
runtime: 'codex',
|
|
245
|
+
externalSessionId: threadId,
|
|
246
|
+
cwd: options.cwd,
|
|
247
|
+
});
|
|
248
|
+
sendNativeRuntimeStatus(options, 'codex', 'Codex is connected and working in this chat.');
|
|
249
|
+
const abortListener = () => {
|
|
250
|
+
if (threadId)
|
|
251
|
+
void client?.interruptTurn?.({ threadId }).catch(() => { });
|
|
252
|
+
};
|
|
253
|
+
options.signal?.addEventListener('abort', abortListener, { once: true });
|
|
254
|
+
try {
|
|
255
|
+
const turnNotifications = client.startTurn({
|
|
256
|
+
threadId,
|
|
257
|
+
cwd: options.cwd,
|
|
258
|
+
input: [{ type: 'text', text: options.prompt }],
|
|
259
|
+
signal: options.signal,
|
|
260
|
+
});
|
|
261
|
+
for await (const notification of iterateWithNativeRuntimeAbort(turnNotifications, options.signal)) {
|
|
262
|
+
if (notification.method === 'serverRequest/resolved') {
|
|
263
|
+
abortCodexPendingServerRequest(notification.params, pendingServerRequests);
|
|
264
|
+
}
|
|
265
|
+
for (const event of mapCodexAppServerNotificationToSseEvents(notification)) {
|
|
266
|
+
options.send(event);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
options.signal?.removeEventListener('abort', abortListener);
|
|
272
|
+
}
|
|
273
|
+
throwIfNativeRuntimeTimedOut(options.signal);
|
|
274
|
+
return { externalSessionId: threadId };
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
const err = errorFromRuntimeFailure(error, options.signal);
|
|
278
|
+
if (threadId) {
|
|
279
|
+
options.send({
|
|
280
|
+
type: 'runtime_binding',
|
|
281
|
+
runtime: 'codex',
|
|
282
|
+
externalSessionId: threadId,
|
|
283
|
+
cwd: options.cwd,
|
|
284
|
+
status: 'failed',
|
|
285
|
+
reason: err.message,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
options.send({ type: 'error', message: `Codex native runtime error: ${err.message}` });
|
|
289
|
+
return { error: err, ...(threadId ? { externalSessionId: threadId } : {}) };
|
|
290
|
+
}
|
|
291
|
+
finally {
|
|
292
|
+
abortAllCodexPendingServerRequests(pendingServerRequests);
|
|
293
|
+
await client?.close?.();
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
async function resolveCodexClient(options, handleServerRequest) {
|
|
297
|
+
if (options.services?.createCodexClient) {
|
|
298
|
+
return options.services.createCodexClient({ cwd: options.cwd, signal: options.signal, handleServerRequest });
|
|
299
|
+
}
|
|
300
|
+
return createCodexAppServerClient(createCodexAppServerStdioTransport({
|
|
301
|
+
cwd: options.cwd,
|
|
302
|
+
...(options.runtime.binaryPath ? { command: options.runtime.binaryPath } : {}),
|
|
303
|
+
...(options.runtimeEnv ? { env: options.runtimeEnv } : {}),
|
|
304
|
+
}), { handleServerRequest });
|
|
305
|
+
}
|
|
306
|
+
async function resolveClaudeClient(options) {
|
|
307
|
+
const command = requireClaudeLocalCliPath(options);
|
|
308
|
+
if (options.services?.createClaudeClient) {
|
|
309
|
+
return {
|
|
310
|
+
client: await options.services.createClaudeClient({ cwd: options.cwd, signal: options.signal }),
|
|
311
|
+
usesCliPermissionPrompt: true,
|
|
312
|
+
source: 'override',
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
try {
|
|
316
|
+
return {
|
|
317
|
+
client: await resolveClaudeSdkClient(options),
|
|
318
|
+
usesCliPermissionPrompt: false,
|
|
319
|
+
source: 'sdk',
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
catch (error) {
|
|
323
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
324
|
+
sendNativeRuntimeStatus(options, 'claude', `Claude Agent SDK is unavailable; using Claude Code CLI fallback. ${err.message}`);
|
|
325
|
+
}
|
|
326
|
+
return {
|
|
327
|
+
client: await resolveClaudeCliClient(options, command),
|
|
328
|
+
usesCliPermissionPrompt: true,
|
|
329
|
+
source: 'cli',
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
async function resolveClaudeSdkClient(options) {
|
|
333
|
+
const command = requireClaudeLocalCliPath(options);
|
|
334
|
+
if (options.services?.createClaudeSdkClient) {
|
|
335
|
+
return options.services.createClaudeSdkClient({
|
|
336
|
+
cwd: options.cwd,
|
|
337
|
+
signal: options.signal,
|
|
338
|
+
command,
|
|
339
|
+
...(options.runtimeEnv ? { env: options.runtimeEnv } : {}),
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
const sdk = options.services?.loadClaudeSdk
|
|
343
|
+
? await options.services.loadClaudeSdk()
|
|
344
|
+
: await loadClaudeCodeSdkModule();
|
|
345
|
+
return createClaudeCodeSdkClient({
|
|
346
|
+
sdk,
|
|
347
|
+
pathToClaudeCodeExecutable: command,
|
|
348
|
+
...(options.runtimeEnv ? { env: options.runtimeEnv } : {}),
|
|
349
|
+
requestRuntimePermission: options.services?.requestRuntimePermission,
|
|
350
|
+
requestUserQuestion: options.services?.requestUserQuestion,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
async function resolveClaudeCliClient(options, command = requireClaudeLocalCliPath(options)) {
|
|
354
|
+
if (options.services?.createClaudeCliClient) {
|
|
355
|
+
return options.services.createClaudeCliClient({
|
|
356
|
+
cwd: options.cwd,
|
|
357
|
+
signal: options.signal,
|
|
358
|
+
command,
|
|
359
|
+
...(options.runtimeEnv ? { env: options.runtimeEnv } : {}),
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
return createClaudeCodeCliClient(createClaudeCodeCliStdioTransport({
|
|
363
|
+
command,
|
|
364
|
+
...(options.runtimeEnv ? { env: options.runtimeEnv } : {}),
|
|
365
|
+
}));
|
|
366
|
+
}
|
|
367
|
+
function isNativeCliBinaryPath(value) {
|
|
368
|
+
return typeof value === 'string' && value.trim().length > 0 && !value.startsWith('sdk:');
|
|
369
|
+
}
|
|
370
|
+
function requireClaudeLocalCliPath(options) {
|
|
371
|
+
if (isNativeCliBinaryPath(options.runtime.binaryPath))
|
|
372
|
+
return options.runtime.binaryPath;
|
|
373
|
+
throw new Error('Claude Code requires a local claude executable detected by MindOS. MindOS does not bundle the Claude Agent SDK native runtime.');
|
|
374
|
+
}
|
|
375
|
+
async function handleCodexServerRequest(request, options, pendingServerRequests) {
|
|
376
|
+
if (isCodexUserInputRequest(request)) {
|
|
377
|
+
return handleCodexUserInputRequest(request, options, pendingServerRequests);
|
|
378
|
+
}
|
|
379
|
+
if (!isCodexApprovalRequest(request)) {
|
|
380
|
+
throw new Error(`Unhandled Codex app-server request: ${request.method}`);
|
|
381
|
+
}
|
|
382
|
+
const permissionRequest = buildCodexPermissionRequest(request);
|
|
383
|
+
const result = await withCodexPendingServerRequest(request, {
|
|
384
|
+
kind: 'permission',
|
|
385
|
+
toolCallId: permissionRequest.toolCallId,
|
|
386
|
+
signal: options.signal,
|
|
387
|
+
pendingServerRequests,
|
|
388
|
+
}, async (signal) => (options.services?.requestRuntimePermission
|
|
389
|
+
? await options.services.requestRuntimePermission(permissionRequest, { signal })
|
|
390
|
+
: { decision: 'cancel', cancelled: true }));
|
|
391
|
+
if (request.method === 'item/permissions/requestApproval') {
|
|
392
|
+
return codexPermissionsApprovalResult(request, result);
|
|
393
|
+
}
|
|
394
|
+
return {
|
|
395
|
+
decision: result.cancelled ? 'cancel' : normalizeCodexApprovalDecision(result.decision),
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
async function handleCodexUserInputRequest(request, options, pendingServerRequests) {
|
|
399
|
+
const questionRequest = buildCodexUserQuestionRequest(request);
|
|
400
|
+
const result = await withCodexPendingServerRequest(request, {
|
|
401
|
+
kind: 'question',
|
|
402
|
+
toolCallId: questionRequest.toolCallId,
|
|
403
|
+
signal: options.signal,
|
|
404
|
+
pendingServerRequests,
|
|
405
|
+
}, async (signal) => (options.services?.requestUserQuestion
|
|
406
|
+
? await options.services.requestUserQuestion(questionRequest, { signal })
|
|
407
|
+
: { answers: [], cancelled: true, error: 'no_bridge' }));
|
|
408
|
+
if (result.cancelled) {
|
|
409
|
+
return { cancelled: true, answers: [], error: result.error ?? 'cancelled' };
|
|
410
|
+
}
|
|
411
|
+
return {
|
|
412
|
+
answers: result.answers.map((answer) => ({
|
|
413
|
+
questionIndex: answer.questionIndex,
|
|
414
|
+
question: answer.question,
|
|
415
|
+
answer: answer.answer,
|
|
416
|
+
...(answer.selected ? { selected: answer.selected } : {}),
|
|
417
|
+
...(answer.kind ? { kind: answer.kind } : {}),
|
|
418
|
+
})),
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
function isCodexUserInputRequest(request) {
|
|
422
|
+
return request.method === 'item/tool/requestUserInput'
|
|
423
|
+
|| request.method === 'tool/requestUserInput';
|
|
424
|
+
}
|
|
425
|
+
function isCodexApprovalRequest(request) {
|
|
426
|
+
return request.method === 'item/commandExecution/requestApproval'
|
|
427
|
+
|| request.method === 'item/fileChange/requestApproval'
|
|
428
|
+
|| request.method === 'item/permissions/requestApproval'
|
|
429
|
+
|| /approval|permission/i.test(request.method);
|
|
430
|
+
}
|
|
431
|
+
async function withCodexPendingServerRequest(request, input, callback) {
|
|
432
|
+
if (!input.pendingServerRequests)
|
|
433
|
+
return callback(input.signal);
|
|
434
|
+
const abortController = new AbortController();
|
|
435
|
+
const abortFromParent = () => abortController.abort();
|
|
436
|
+
if (input.signal?.aborted) {
|
|
437
|
+
abortController.abort();
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
input.signal?.addEventListener('abort', abortFromParent, { once: true });
|
|
441
|
+
}
|
|
442
|
+
const keys = codexServerRequestKeys(request);
|
|
443
|
+
const pending = {
|
|
444
|
+
requestId: request.id,
|
|
445
|
+
toolCallId: input.toolCallId,
|
|
446
|
+
kind: input.kind,
|
|
447
|
+
abortController,
|
|
448
|
+
cleanup: () => {
|
|
449
|
+
input.signal?.removeEventListener('abort', abortFromParent);
|
|
450
|
+
for (const key of keys) {
|
|
451
|
+
if (input.pendingServerRequests?.get(key) === pending) {
|
|
452
|
+
input.pendingServerRequests.delete(key);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
};
|
|
457
|
+
for (const key of keys)
|
|
458
|
+
input.pendingServerRequests.set(key, pending);
|
|
459
|
+
try {
|
|
460
|
+
return await callback(abortController.signal);
|
|
461
|
+
}
|
|
462
|
+
finally {
|
|
463
|
+
pending.cleanup();
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
function abortCodexPendingServerRequest(params, pendingServerRequests) {
|
|
467
|
+
const keys = codexServerRequestResolvedKeys(params);
|
|
468
|
+
for (const key of keys) {
|
|
469
|
+
const pending = pendingServerRequests.get(key);
|
|
470
|
+
if (!pending)
|
|
471
|
+
continue;
|
|
472
|
+
pending.abortController.abort();
|
|
473
|
+
pending.cleanup();
|
|
474
|
+
return true;
|
|
475
|
+
}
|
|
476
|
+
return false;
|
|
477
|
+
}
|
|
478
|
+
function abortAllCodexPendingServerRequests(pendingServerRequests) {
|
|
479
|
+
const pending = new Set(pendingServerRequests.values());
|
|
480
|
+
pendingServerRequests.clear();
|
|
481
|
+
for (const request of pending) {
|
|
482
|
+
request.abortController.abort();
|
|
483
|
+
request.cleanup();
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
function codexServerRequestKeys(request) {
|
|
487
|
+
const params = request.params ?? {};
|
|
488
|
+
return uniqueStrings([
|
|
489
|
+
String(request.id),
|
|
490
|
+
getIdLike(params, 'requestId'),
|
|
491
|
+
getIdLike(params, 'serverRequestId'),
|
|
492
|
+
getIdLike(params, 'jsonrpcId'),
|
|
493
|
+
getIdLike(params, 'itemId'),
|
|
494
|
+
getIdLike(params, 'callId'),
|
|
495
|
+
getIdLike(params, 'id'),
|
|
496
|
+
]);
|
|
497
|
+
}
|
|
498
|
+
function codexServerRequestResolvedKeys(params) {
|
|
499
|
+
return uniqueStrings([
|
|
500
|
+
getIdLike(params, 'requestId'),
|
|
501
|
+
getIdLike(params, 'serverRequestId'),
|
|
502
|
+
getIdLike(params, 'jsonrpcId'),
|
|
503
|
+
getIdLike(params, 'itemId'),
|
|
504
|
+
getIdLike(params, 'callId'),
|
|
505
|
+
getIdLike(params, 'id'),
|
|
506
|
+
]);
|
|
507
|
+
}
|
|
508
|
+
function buildCodexPermissionRequest(request) {
|
|
509
|
+
const params = request.params ?? {};
|
|
510
|
+
const toolCallId = getString(params, 'itemId')
|
|
511
|
+
?? getString(params, 'requestId')
|
|
512
|
+
?? getString(params, 'callId')
|
|
513
|
+
?? getString(params, 'id')
|
|
514
|
+
?? `codex-approval-${request.id}`;
|
|
515
|
+
const command = getString(params, 'command')
|
|
516
|
+
?? getString(params, 'cmd')
|
|
517
|
+
?? getString(params, 'shellCommand');
|
|
518
|
+
const toolName = request.method === 'item/fileChange/requestApproval'
|
|
519
|
+
? 'file_change_approval'
|
|
520
|
+
: command
|
|
521
|
+
? 'Bash'
|
|
522
|
+
: 'approval_request';
|
|
523
|
+
return {
|
|
524
|
+
runtime: 'codex',
|
|
525
|
+
toolCallId,
|
|
526
|
+
toolName,
|
|
527
|
+
input: {
|
|
528
|
+
method: request.method,
|
|
529
|
+
...params,
|
|
530
|
+
},
|
|
531
|
+
options: getCodexPermissionOptions(params, request.method),
|
|
532
|
+
...(getString(params, 'reason') ?? getString(params, 'message') ? {
|
|
533
|
+
reason: getString(params, 'reason') ?? getString(params, 'message'),
|
|
534
|
+
} : {}),
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
function buildCodexUserQuestionRequest(request) {
|
|
538
|
+
const params = request.params ?? {};
|
|
539
|
+
const toolCallId = getString(params, 'itemId')
|
|
540
|
+
?? getString(params, 'requestId')
|
|
541
|
+
?? getString(params, 'callId')
|
|
542
|
+
?? getString(params, 'id')
|
|
543
|
+
?? `codex-question-${request.id}`;
|
|
544
|
+
const questions = normalizeCodexUserQuestions(params);
|
|
545
|
+
return {
|
|
546
|
+
runtime: 'codex',
|
|
547
|
+
toolCallId,
|
|
548
|
+
questions: questions.length > 0 ? questions : [{
|
|
549
|
+
question: getString(params, 'message') ?? getString(params, 'reason') ?? 'Codex needs your input to continue.',
|
|
550
|
+
header: getString(params, 'title') ?? 'Codex input',
|
|
551
|
+
options: [
|
|
552
|
+
{ label: 'Continue', description: 'Allow Codex to continue with this request.' },
|
|
553
|
+
{ label: 'Cancel', description: 'Cancel this request.' },
|
|
554
|
+
],
|
|
555
|
+
}],
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
function normalizeCodexUserQuestions(params) {
|
|
559
|
+
const rawQuestions = Array.isArray(params.questions)
|
|
560
|
+
? params.questions
|
|
561
|
+
: isRecord(params.input) && Array.isArray(params.input.questions)
|
|
562
|
+
? params.input.questions
|
|
563
|
+
: [];
|
|
564
|
+
return rawQuestions
|
|
565
|
+
.filter(isRecord)
|
|
566
|
+
.map((question, index) => ({
|
|
567
|
+
question: getString(question, 'question') ?? getString(question, 'text') ?? getString(question, 'message') ?? `Question ${index + 1}`,
|
|
568
|
+
header: getString(question, 'header') ?? getString(question, 'title') ?? `Question ${index + 1}`,
|
|
569
|
+
multiSelect: question.multiSelect === true || question.multiselect === true,
|
|
570
|
+
options: normalizeCodexUserQuestionOptions(question.options),
|
|
571
|
+
}));
|
|
572
|
+
}
|
|
573
|
+
function normalizeCodexUserQuestionOptions(value) {
|
|
574
|
+
if (!Array.isArray(value))
|
|
575
|
+
return [];
|
|
576
|
+
return value.flatMap((option) => {
|
|
577
|
+
if (typeof option === 'string' && option.trim()) {
|
|
578
|
+
return [{ label: option, description: option }];
|
|
579
|
+
}
|
|
580
|
+
if (!isRecord(option))
|
|
581
|
+
return [];
|
|
582
|
+
const label = getString(option, 'label')
|
|
583
|
+
?? getString(option, 'value')
|
|
584
|
+
?? getString(option, 'title')
|
|
585
|
+
?? (option.isOther === true ? 'Other' : undefined);
|
|
586
|
+
if (!label)
|
|
587
|
+
return [];
|
|
588
|
+
return [{
|
|
589
|
+
label,
|
|
590
|
+
description: getString(option, 'description') ?? getString(option, 'hint') ?? label,
|
|
591
|
+
...(getString(option, 'preview') ? { preview: getString(option, 'preview') } : {}),
|
|
592
|
+
}];
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
function getCodexPermissionOptions(params, method) {
|
|
596
|
+
const fromParams = [
|
|
597
|
+
...stringArray(params.availableDecisions),
|
|
598
|
+
...stringArray(params.decisions),
|
|
599
|
+
...stringArray(params.options),
|
|
600
|
+
].map(decisionOption);
|
|
601
|
+
if (fromParams.length > 0)
|
|
602
|
+
return dedupeOptions(fromParams);
|
|
603
|
+
const defaults = method === 'item/permissions/requestApproval'
|
|
604
|
+
? ['accept', 'acceptForSession', 'decline']
|
|
605
|
+
: ['accept', 'acceptForSession', 'decline'];
|
|
606
|
+
return defaults.map(decisionOption);
|
|
607
|
+
}
|
|
608
|
+
function decisionOption(id) {
|
|
609
|
+
const labels = {
|
|
610
|
+
accept: 'Allow once',
|
|
611
|
+
acceptForSession: 'Allow session',
|
|
612
|
+
decline: 'Deny',
|
|
613
|
+
cancel: 'Cancel',
|
|
614
|
+
deny: 'Deny',
|
|
615
|
+
};
|
|
616
|
+
const descriptions = {
|
|
617
|
+
accept: 'Run this action one time.',
|
|
618
|
+
acceptForSession: 'Run this action and remember the same rule for this Codex session.',
|
|
619
|
+
decline: 'Reject this action.',
|
|
620
|
+
cancel: 'Cancel the pending action.',
|
|
621
|
+
};
|
|
622
|
+
return {
|
|
623
|
+
id,
|
|
624
|
+
label: labels[id] ?? id,
|
|
625
|
+
...(descriptions[id] ? { description: descriptions[id] } : {}),
|
|
626
|
+
intent: id === 'accept' || id === 'acceptForSession' ? 'allow' : id === 'decline' || id === 'deny' ? 'deny' : 'cancel',
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
function dedupeOptions(options) {
|
|
630
|
+
const seen = new Set();
|
|
631
|
+
return options.filter((option) => {
|
|
632
|
+
if (!option.id || seen.has(option.id))
|
|
633
|
+
return false;
|
|
634
|
+
seen.add(option.id);
|
|
635
|
+
return true;
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
function normalizeCodexApprovalDecision(decision) {
|
|
639
|
+
if (decision === 'accept' || decision === 'acceptForSession' || decision === 'decline' || decision === 'cancel') {
|
|
640
|
+
return decision;
|
|
641
|
+
}
|
|
642
|
+
if (decision === 'deny' || decision === 'denied')
|
|
643
|
+
return 'decline';
|
|
644
|
+
return 'cancel';
|
|
645
|
+
}
|
|
646
|
+
function codexPermissionsApprovalResult(request, result) {
|
|
647
|
+
const decision = result.cancelled ? 'cancel' : normalizeCodexApprovalDecision(result.decision);
|
|
648
|
+
if (decision === 'decline' || decision === 'cancel')
|
|
649
|
+
return { permissions: {} };
|
|
650
|
+
const requestedPermissions = request.params?.permissions && typeof request.params.permissions === 'object'
|
|
651
|
+
? request.params.permissions
|
|
652
|
+
: {};
|
|
653
|
+
return {
|
|
654
|
+
permissions: requestedPermissions,
|
|
655
|
+
...(decision === 'acceptForSession' ? { scope: 'session' } : {}),
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
function stringArray(value) {
|
|
659
|
+
if (!Array.isArray(value))
|
|
660
|
+
return [];
|
|
661
|
+
return value.filter((item) => typeof item === 'string' && item.trim().length > 0);
|
|
662
|
+
}
|
|
663
|
+
function uniqueStrings(values) {
|
|
664
|
+
return Array.from(new Set(values.filter((value) => Boolean(value))));
|
|
665
|
+
}
|
|
666
|
+
function isRecord(value) {
|
|
667
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
668
|
+
}
|
|
669
|
+
function getIdLike(record, key) {
|
|
670
|
+
const value = record?.[key];
|
|
671
|
+
if (typeof value === 'string' && value.trim())
|
|
672
|
+
return value;
|
|
673
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
674
|
+
return String(value);
|
|
675
|
+
return undefined;
|
|
676
|
+
}
|
|
677
|
+
function getString(record, key) {
|
|
678
|
+
const value = record[key];
|
|
679
|
+
return typeof value === 'string' && value.trim() ? value : undefined;
|
|
680
|
+
}
|
|
681
|
+
//# sourceMappingURL=run.js.map
|