@ai-workbench/remote-agent 0.8.19 → 0.8.23
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 +27 -134
- package/dist/acp.d.ts +23 -16
- package/dist/acp.js +209 -226
- package/dist/agents.d.ts +0 -1
- package/dist/agents.js +2 -2
- package/dist/broker-runtime.d.ts +3 -5
- package/dist/broker-runtime.js +45 -342
- package/dist/broker.d.ts +6 -31
- package/dist/broker.js +42 -113
- package/dist/catalog-ssh.d.ts +2 -31
- package/dist/catalog-ssh.js +9 -39
- package/dist/claude-local.d.ts +1 -1
- package/dist/claude-local.js +41 -105
- package/dist/client.js +34 -126
- package/dist/close-diagnostics.d.ts +6 -20
- package/dist/close-diagnostics.js +13 -57
- package/dist/connect-contract.d.ts +4 -8
- package/dist/conversation-details.d.ts +0 -29
- package/dist/conversation-details.js +8 -99
- package/dist/employee-endpoint.d.ts +1 -1
- package/dist/employee-endpoint.js +21 -19
- package/dist/employee-exec.d.ts +4 -3
- package/dist/employee-exec.js +25 -13
- package/dist/employee-info.d.ts +7 -1
- package/dist/employee-info.js +24 -3
- package/dist/employee-location.js +3 -4
- package/dist/employee-mcp.js +44 -69
- package/dist/employee-native.d.ts +1 -3
- package/dist/employee-native.js +6 -27
- package/dist/employee-presentation.d.ts +0 -5
- package/dist/employee-presentation.js +0 -15
- package/dist/employee-provider.d.ts +3 -11
- package/dist/employee-provider.js +69 -205
- package/dist/employee-reasons.js +1 -5
- package/dist/employee-shell.d.ts +2 -1
- package/dist/employee-shell.js +10 -13
- package/dist/employee-ssh.d.ts +1 -3
- package/dist/employee-ssh.js +13 -16
- package/dist/employee-tools.d.ts +5 -5
- package/dist/failure-evidence.d.ts +2 -10
- package/dist/failure-evidence.js +12 -61
- package/dist/host-workspace.d.ts +4 -2
- package/dist/host-workspace.js +6 -2
- package/dist/index.d.ts +13 -43
- package/dist/index.js +192 -484
- package/dist/input.js +2 -3
- package/dist/local-user-turn.js +5 -6
- package/dist/mapping.d.ts +5 -3
- package/dist/mapping.js +31 -36
- package/dist/model-catalog.d.ts +2 -41
- package/dist/model-catalog.js +24 -282
- package/dist/model-configuration.d.ts +0 -3
- package/dist/model-configuration.js +8 -47
- package/dist/model-presentation.d.ts +1 -0
- package/dist/model-presentation.js +2 -2
- package/dist/permissions.d.ts +15 -0
- package/dist/permissions.js +30 -0
- package/dist/preflight-diagnostic.js +11 -22
- package/dist/preflight-payload.d.ts +1 -1
- package/dist/preflight-payload.js +2 -2
- package/dist/presentation.js +21 -41
- package/dist/provider.d.ts +12 -34
- package/dist/provider.js +17 -92
- package/dist/readiness.js +1 -7
- package/dist/remote-details.d.ts +41 -17
- package/dist/remote-details.js +84 -381
- package/dist/workspace-source.d.ts +1 -25
- package/dist/workspace-source.js +1 -138
- package/package.json +11 -12
- package/dist/catalog-diagnostics.d.ts +0 -16
- package/dist/catalog-diagnostics.js +0 -108
- package/dist/host-layout.d.ts +0 -8
- package/dist/host-layout.js +0 -9
- package/dist/job.d.ts +0 -17
- package/dist/job.js +0 -57
- package/dist/model-defaults.d.ts +0 -29
- package/dist/model-defaults.js +0 -62
- package/dist/oneshot.d.ts +0 -13
- package/dist/oneshot.js +0 -78
- package/dist/protocol-boundary.d.ts +0 -13
- package/dist/protocol-boundary.js +0 -49
- package/dist/provider-locale.d.ts +0 -19
- package/dist/provider-locale.js +0 -73
- package/dist/recovery-checkpoint.d.ts +0 -6
- package/dist/recovery-checkpoint.js +0 -71
- package/dist/recovery.d.ts +0 -51
- package/dist/recovery.js +0 -61
- package/dist/sdk-ssh-wrapper.d.ts +0 -2
- package/dist/sdk-ssh-wrapper.js +0 -34
- package/dist/stage-timing.d.ts +0 -31
- package/dist/stage-timing.js +0 -61
- package/dist/workspace-notice.d.ts +0 -47
- package/dist/workspace-notice.js +0 -273
- package/dist/workspace-source-confirmation.d.ts +0 -4
- package/dist/workspace-source-confirmation.js +0 -12
package/dist/provider.js
CHANGED
|
@@ -4,8 +4,6 @@ import { loginDiagnostic, loginReason } from "./login-diagnostic.js";
|
|
|
4
4
|
import { NeedError } from "./remote.js";
|
|
5
5
|
import { CONNECTION_REQUIRED, TEST_HOST_NOTICE } from "./presentation.js";
|
|
6
6
|
import { CODEX_AGENT } from "./agents.js";
|
|
7
|
-
import { StageTiming } from "./stage-timing.js";
|
|
8
|
-
import { confirmLegacyWorkspaceSource } from "./workspace-source.js";
|
|
9
7
|
export function requireLoginCoordinator(api) {
|
|
10
8
|
if (!['getConnectionState', 'getLoginPromptState', 'requestLoginPrompt', 'refreshLoginPrompts'].every(key => typeof api[key] === 'function'))
|
|
11
9
|
throw new NeedError('CONNECT_API_MISMATCH', '我需要 connect-api 0.6.1 的统一登录询问与连接状态能力', 'L >=0.6.1');
|
|
@@ -138,10 +136,10 @@ export function identity(t) { return `${t.username}@${t.host}:${t.port}`; }
|
|
|
138
136
|
/** Reject draft.3 and legacy runtime rather than inventing workspace bindings. */
|
|
139
137
|
export function requireNativeWorkspace(api) {
|
|
140
138
|
if (typeof api.getContractInfo !== 'function')
|
|
141
|
-
throw new NeedError('DEPENDENCY_REQUIRED', '我需要新版远程主机连接组件提供原生工作区绑定', 'L connect-api 0.7.0 /
|
|
139
|
+
throw new NeedError('DEPENDENCY_REQUIRED', '我需要新版远程主机连接组件提供原生工作区绑定', 'L connect-api 0.7.0 / ensureReady / resolveSessionProject');
|
|
142
140
|
const info = api.getContractInfo();
|
|
143
|
-
if (info?.apiVersion !== '0.7.0' || info.status !== 'implemented' ||
|
|
144
|
-
throw new NeedError('DEPENDENCY_REQUIRED', '我需要新版远程主机连接组件提供原生工作区绑定', 'L connect-api 0.7.0 /
|
|
141
|
+
if (info?.apiVersion !== '0.7.0' || info.status !== 'implemented' || !['ensureReady', 'resolveSessionProject'].every(key => typeof api[key] === 'function'))
|
|
142
|
+
throw new NeedError('DEPENDENCY_REQUIRED', '我需要新版远程主机连接组件提供原生工作区绑定', 'L connect-api 0.7.0 / ensureReady / resolveSessionProject');
|
|
145
143
|
}
|
|
146
144
|
/** Authorization stays in L; ensureReady only checks and records the need. */
|
|
147
145
|
export async function offerLogin(connect, request, currentApi, agent = CODEX_AGENT) {
|
|
@@ -189,32 +187,20 @@ export function connectProvider(get, options = {}) {
|
|
|
189
187
|
let employee;
|
|
190
188
|
const admissions = new WeakMap();
|
|
191
189
|
const preflight = async (request) => {
|
|
192
|
-
request.timing ??= new StageTiming();
|
|
193
190
|
request.signal?.throwIfAborted();
|
|
194
191
|
const api = get();
|
|
195
192
|
if (!api)
|
|
196
193
|
throw new NeedError('DEPENDENCY_REQUIRED', CONNECTION_REQUIRED, 'aiWorkbenchConnect');
|
|
197
194
|
requireNativeWorkspace(api);
|
|
198
195
|
requireLoginCoordinator(api);
|
|
199
|
-
if (request.mode === 'one-shot' && !agent.oneShot)
|
|
200
|
-
throw new NeedError('MODE_UNSUPPORTED', '此远程模型仅支持会话模式', '使用会话模式');
|
|
201
|
-
const confirmedSource = options.workspaceSource ? await confirmLegacyWorkspaceSource(get, api, request, options.workspaceSource) : undefined;
|
|
202
196
|
let sourceStage = 'input-acceptance';
|
|
203
|
-
if (confirmedSource && !request.recordEarlyFailure)
|
|
204
|
-
request.recordEarlyFailure = (error, stage) => confirmedSource.recordFailure(error, stage);
|
|
205
197
|
try {
|
|
206
|
-
confirmedSource?.assertCurrent();
|
|
207
198
|
if (options.employee) {
|
|
208
199
|
const module = await import("./employee-provider.js");
|
|
209
|
-
request.
|
|
210
|
-
}
|
|
211
|
-
confirmedSource?.assertCurrent();
|
|
212
|
-
if (confirmedSource) {
|
|
213
|
-
const previous = request.localAdmissionCheck;
|
|
214
|
-
request.localAdmissionCheck = () => { confirmedSource.assertCurrent(); previous?.(); };
|
|
200
|
+
request.localContext = await module.inspectEmployeeWorkspace(get, options.employee, agent, api, request);
|
|
215
201
|
}
|
|
216
202
|
sourceStage = 'login-readiness';
|
|
217
|
-
const { target, connection } = await
|
|
203
|
+
const { target, connection } = await (async () => {
|
|
218
204
|
request.localAdmissionCheck?.();
|
|
219
205
|
const before = api.getConnectionState();
|
|
220
206
|
const target = await ensureReady(api, agent.loginProvider, request.signal);
|
|
@@ -224,11 +210,9 @@ export function connectProvider(get, options = {}) {
|
|
|
224
210
|
throw new NeedError('CONNECTION_LOST', '远程主机连接组件已更换', '当前员工连接');
|
|
225
211
|
const connection = await waitForLogin(api, agent.loginProvider, before, get, request.signal);
|
|
226
212
|
return { target, connection };
|
|
227
|
-
});
|
|
213
|
+
})();
|
|
228
214
|
if (request.identity && request.identity !== identity(target))
|
|
229
215
|
throw new NeedError('SESSION_CONTEXT_MISMATCH', '员工主机与原会话不一致,请新建会话', '原员工主机');
|
|
230
|
-
if (options.employee && request.localAcceptance)
|
|
231
|
-
await (await import("./employee-provider.js")).validateEmployeeUserTurn(get, options.employee, api, request, connection);
|
|
232
216
|
request.localAdmissionCheck?.();
|
|
233
217
|
admissions.set(request, { api, target, connection });
|
|
234
218
|
sourceStage = 'local-admission';
|
|
@@ -236,7 +220,6 @@ export function connectProvider(get, options = {}) {
|
|
|
236
220
|
if (locations && (locations.phase === 'failed' || locations.phase === 'disposed') && locations.instanceId === connection.instanceId && locations.epoch === connection.epoch && locations.need)
|
|
237
221
|
throw connectNeedError(locations.need);
|
|
238
222
|
await options.local?.admit?.(request, api, connection, target);
|
|
239
|
-
confirmedSource?.assertCurrent();
|
|
240
223
|
}
|
|
241
224
|
catch (error) {
|
|
242
225
|
admissions.delete(request);
|
|
@@ -244,8 +227,6 @@ export function connectProvider(get, options = {}) {
|
|
|
244
227
|
request.recordEarlyFailure = undefined;
|
|
245
228
|
if (record)
|
|
246
229
|
await record(error, sourceStage);
|
|
247
|
-
else
|
|
248
|
-
await confirmedSource?.recordFailure(error, sourceStage);
|
|
249
230
|
throw error;
|
|
250
231
|
}
|
|
251
232
|
};
|
|
@@ -255,16 +236,13 @@ export function connectProvider(get, options = {}) {
|
|
|
255
236
|
const admitted = admissions.get(request);
|
|
256
237
|
admissions.delete(request);
|
|
257
238
|
const { api, target, connection } = admitted;
|
|
258
|
-
const stable = () => request.timing.run('connection-confirm', () => waitForLogin(api, agent.loginProvider, connection, get, request.signal));
|
|
259
|
-
await stable();
|
|
260
|
-
request.localAdmissionCheck?.();
|
|
261
239
|
if (!request.sessionId)
|
|
262
240
|
throw new NeedError('PROJECT_BINDING_REQUIRED', '我需要当前会话和已选择的工作区,请使用原生工作区入口', 'DSH会话与原生工作区');
|
|
263
|
-
const host = await hostWorkspaceGuard(get, api, connection, target, request, options.
|
|
241
|
+
const host = await hostWorkspaceGuard(get, api, connection, target, request, options.workspace, agent.loginProvider);
|
|
264
242
|
try {
|
|
265
243
|
if (!host && options.employee) {
|
|
266
244
|
employee ??= import("./employee-provider.js").then(module => module.createEmployeeProvider(get, options, agent));
|
|
267
|
-
const local = await (await employee)({ api, target, connection, request
|
|
245
|
+
const local = await (await employee)({ api, target, connection, request });
|
|
268
246
|
if (local) {
|
|
269
247
|
local.loginRequired = () => offerLogin(api, request, get, agent);
|
|
270
248
|
return local;
|
|
@@ -272,79 +250,33 @@ export function connectProvider(get, options = {}) {
|
|
|
272
250
|
}
|
|
273
251
|
if (!host && agent.loginProvider === 'claude' && options.local) {
|
|
274
252
|
const runtime = await options.local(request, api, connection, target);
|
|
275
|
-
if (runtime)
|
|
276
|
-
try {
|
|
277
|
-
await stable();
|
|
278
|
-
}
|
|
279
|
-
catch (error) {
|
|
280
|
-
await runtime.dispose?.();
|
|
281
|
-
throw error;
|
|
282
|
-
}
|
|
253
|
+
if (runtime)
|
|
283
254
|
return runtime;
|
|
284
|
-
}
|
|
285
255
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
const resolved = await
|
|
291
|
-
await stable();
|
|
292
|
-
host?.assertCurrent();
|
|
293
|
-
if (!resolved || resolved.instanceId !== connection.instanceId || resolved.epoch !== connection.epoch)
|
|
294
|
-
throw new NeedError('CONNECTION_LOST', '工作区解析回复已失效', '当前连接代次');
|
|
295
|
-
validateTarget(resolved.target);
|
|
256
|
+
// A local source must have been handled by its employee provider above.
|
|
257
|
+
// Host execution requires an explicit host location; no name-based resolver.
|
|
258
|
+
if (!host)
|
|
259
|
+
throw new NeedError('WORKSPACE_LOCATION_REQUIRED', '请选择文件夹来源;改变来源后请新建会话。', '已选择的本机或主机文件夹');
|
|
260
|
+
const resolved = await host.resolve();
|
|
296
261
|
const project = resolved.project;
|
|
297
|
-
const source = resolved.source;
|
|
298
|
-
if (resolved.sessionId !== request.sessionId || !resolved.workspaceId || !resolved.bindingId || !Number.isSafeInteger(resolved.bindingRevision) || resolved.bindingRevision < 1 || !sameTarget(target, resolved.target) || !project || (!host && (source !== undefined && source !== 'legacy-host' || typeof project.name !== 'string' || !project.name || project.name === '.' || project.name === '..' || /[\\/\x00-\x1f\x7f]/.test(project.name) || project.path !== resolved.target.projectRoot + '/' + project.name)))
|
|
299
|
-
throw new NeedError('PROJECT_BINDING_INVALID', '工作区绑定与当前会话或可信主机不一致', 'L核验的原生工作区绑定');
|
|
300
262
|
if (request.cwd && request.cwd !== project.path || request.bindingId && request.bindingId !== resolved.bindingId || request.workspaceId && request.workspaceId !== resolved.workspaceId)
|
|
301
263
|
throw new NeedError(host ? 'PROJECT_BINDING_INVALID' : 'SESSION_CONTEXT_MISMATCH', host ? '文件来源已改,请新建会话继续;原会话历史仍可查看。' : '原会话的工作区绑定已改变,请新建会话', '原工作区绑定');
|
|
302
|
-
const details = await
|
|
264
|
+
const details = await options.details?.(request, api, connection, target);
|
|
303
265
|
try {
|
|
304
|
-
if (details)
|
|
305
|
-
request.timing.bind(detail => details.record(detail));
|
|
306
|
-
await stable();
|
|
307
|
-
host?.assertCurrent();
|
|
308
|
-
let workspaceNotice = undefined;
|
|
309
|
-
const notice = !host && 'notice' in resolved ? resolved.notice : undefined;
|
|
310
|
-
if (notice) {
|
|
311
|
-
if (!options.notice)
|
|
312
|
-
throw new NeedError('DEPENDENCY_REQUIRED', '我需要官方会话持久记录来确认工作区说明', '官方会话与持久化服务');
|
|
313
|
-
workspaceNotice = await request.timing.run('workspace-notice', () => options.notice.deliver(notice, resolved, request, api));
|
|
314
|
-
await stable();
|
|
315
|
-
}
|
|
316
266
|
if (!options.open)
|
|
317
267
|
throw new NeedError('RUNTIME_REQUIRED', '我需要主机运行适配器', '主机broker适配');
|
|
318
|
-
const
|
|
319
|
-
const validateContext = async (ignoreCancellation = false) => {
|
|
320
|
-
const check = () => waitForLogin(api, agent.loginProvider, connection, get, ignoreCancellation ? undefined : request.signal);
|
|
321
|
-
await check();
|
|
322
|
-
if (host && !ignoreCancellation)
|
|
323
|
-
await host.resolve();
|
|
324
|
-
if (observedBinding) {
|
|
325
|
-
const current = api.getWorkspaceBindingState();
|
|
326
|
-
if (current.instanceId !== observedBinding.instanceId || !current.items.some(item => item.bindingId === resolved.bindingId && item.workspaceId === resolved.workspaceId && item.status === 'ready'))
|
|
327
|
-
throw new NeedError('SESSION_CONTEXT_MISMATCH', '当前工作区绑定已改变,原会话操作未执行', '原生会话原绑定');
|
|
328
|
-
}
|
|
329
|
-
await check();
|
|
330
|
-
if (!ignoreCancellation)
|
|
331
|
-
host?.assertCurrent();
|
|
332
|
-
};
|
|
333
|
-
host?.assertCurrent();
|
|
334
|
-
const runtime = await options.open(resolved.target, project, { ...request, ...(host ? { signal: host.signal } : {}), agent, bindingId: resolved.bindingId, workspaceId: resolved.workspaceId, bindingRevision: resolved.bindingRevision, detailChannel: details, validateContext });
|
|
268
|
+
const runtime = await options.open(resolved.target, project, { ...request, ...(host ? { signal: host.signal } : {}), agent, bindingId: resolved.bindingId, workspaceId: resolved.workspaceId, bindingRevision: resolved.bindingRevision, detailChannel: details });
|
|
335
269
|
try {
|
|
336
|
-
await stable();
|
|
337
270
|
host?.observeRuntime(runtime);
|
|
338
271
|
}
|
|
339
272
|
catch (error) {
|
|
340
|
-
|
|
273
|
+
void runtime.dispose?.().catch(() => console.warn('HOST_CLEANUP_FAILED'));
|
|
341
274
|
throw error;
|
|
342
275
|
}
|
|
343
276
|
if (host)
|
|
344
277
|
retainHostScope(runtime, host);
|
|
345
278
|
runtime.hostWorkspace = host && 'directory' in resolved ? Object.freeze({ cwd: resolved.directory.path }) : undefined;
|
|
346
279
|
// The transport can outlive a turn; presentation belongs only to this invocation.
|
|
347
|
-
runtime.workspaceNotice = workspaceNotice || undefined;
|
|
348
280
|
runtime.details = details ?? runtime.details;
|
|
349
281
|
runtime.binding = { bindingId: resolved.bindingId, workspaceId: resolved.workspaceId, revision: resolved.bindingRevision };
|
|
350
282
|
runtime.connection = { ...connection };
|
|
@@ -352,13 +284,6 @@ export function connectProvider(get, options = {}) {
|
|
|
352
284
|
return runtime;
|
|
353
285
|
}
|
|
354
286
|
catch (error) {
|
|
355
|
-
try {
|
|
356
|
-
await details?.flush();
|
|
357
|
-
}
|
|
358
|
-
catch (diagnostic) {
|
|
359
|
-
const code = (value) => value instanceof NeedError && /^[A-Z][A-Z0-9_]*$/.test(value.code) ? value.code : 'UNKNOWN_FAILURE';
|
|
360
|
-
throw new NeedError('CONVERSATION_DETAILS_FAILED', '技术详情未能保存;本轮已停止', `原错误代码 ${code(error)};诊断错误代码 ${code(diagnostic)}`);
|
|
361
|
-
}
|
|
362
287
|
throw error;
|
|
363
288
|
}
|
|
364
289
|
}
|
package/dist/readiness.js
CHANGED
|
@@ -39,12 +39,6 @@ import { unwrap, awaitL, requireLoginCoordinator, requireLoginState } from "./pr
|
|
|
39
39
|
import { NeedError } from "./remote.js";
|
|
40
40
|
import { CONNECTION_REQUIRED, employeeFailure } from "./presentation.js";
|
|
41
41
|
import { CODEX_AGENT } from "./agents.js";
|
|
42
|
-
function details(target) {
|
|
43
|
-
const h = target.hostContext;
|
|
44
|
-
if (!h)
|
|
45
|
-
return [];
|
|
46
|
-
return [{ label: '主机配置', value: h.enforcement }, { label: '检查退出码', value: String(h.checkExitCode) }, ...h.failedChecks.map(item => ({ label: '未通过检查', value: `${item.id}(${item.status})` })), ...h.unverifiedChecks.map(item => ({ label: '未核实检查', value: `${item.id}(${item.status})` }))];
|
|
47
|
-
}
|
|
48
42
|
function blocked(code, technical = [], agent = CODEX_AGENT) {
|
|
49
43
|
return { phase: 'blocked', loginStatus: 'unknown', title: `无法确认 ${agent.name.zh} 登录状态`, message: employeeFailure(code, agent.loginProvider), technical: [...technical, { label: '诊断代码', value: code }] };
|
|
50
44
|
}
|
|
@@ -61,7 +55,7 @@ function snapshot(api, agent = CODEX_AGENT) {
|
|
|
61
55
|
if (!connection.instanceId || state.instanceId !== connection.instanceId)
|
|
62
56
|
return denied('AUTH_STATUS_INVALID', [diagnostic('LOGIN_INSTANCE_MISMATCH')]);
|
|
63
57
|
requireLoginState(state);
|
|
64
|
-
const technical =
|
|
58
|
+
const technical = [];
|
|
65
59
|
if (state.phase === 'blocked' || state.phase === 'disposed')
|
|
66
60
|
return denied(state.technicalDetails?.code ?? 'AUTH_STATUS_INVALID', [...technical, diagnostic(state.phase === 'disposed' ? 'LOGIN_PHASE_DISPOSED' : 'LOGIN_PHASE_BLOCKED')]);
|
|
67
61
|
if (state.queuedProviders?.includes(brand) || state.checkingProviders.includes(brand) || state.phase === 'authorizing' && state.provider === brand)
|
package/dist/remote-details.d.ts
CHANGED
|
@@ -1,9 +1,30 @@
|
|
|
1
|
-
import { type DetailObservation } from './conversation-details.ts';
|
|
1
|
+
import { type DetailObservation, type JsonValue } from './conversation-details.ts';
|
|
2
2
|
import type { LoginDiagnostic } from './login-diagnostic.ts';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
type Connection = {
|
|
4
|
+
instanceId: string;
|
|
5
|
+
epoch: number;
|
|
6
|
+
phase: string;
|
|
7
|
+
};
|
|
8
|
+
export interface RemoteDetail {
|
|
9
|
+
version: 1;
|
|
10
|
+
eventId: string;
|
|
11
|
+
instanceId: string | null;
|
|
12
|
+
epoch: number | null;
|
|
13
|
+
sessionId: string;
|
|
14
|
+
provider: 'claude' | 'codex';
|
|
15
|
+
turn: string | number | null;
|
|
16
|
+
step: string | number | null;
|
|
17
|
+
sequence: number;
|
|
18
|
+
kind: string;
|
|
19
|
+
severity: 'info' | 'warning' | 'action-required';
|
|
20
|
+
code: string;
|
|
21
|
+
summary: string;
|
|
22
|
+
method?: string;
|
|
23
|
+
payload: JsonValue;
|
|
24
|
+
}
|
|
25
|
+
export interface RemoteDetailsApi {
|
|
26
|
+
getConnectionState(): Connection;
|
|
27
|
+
}
|
|
7
28
|
export interface DetailChannel {
|
|
8
29
|
record(observation: DetailObservation): void;
|
|
9
30
|
beginTurn(ids: {
|
|
@@ -11,26 +32,31 @@ export interface DetailChannel {
|
|
|
11
32
|
step: string | number | null;
|
|
12
33
|
}): void;
|
|
13
34
|
endTurn(): void;
|
|
14
|
-
flush(): Promise<void>;
|
|
15
35
|
}
|
|
16
36
|
export interface DetailRequest {
|
|
17
37
|
sessionId: string;
|
|
18
38
|
provider: 'claude' | 'codex';
|
|
19
39
|
identity: string;
|
|
20
|
-
connection
|
|
21
|
-
readonly localAcceptanceId?: string;
|
|
40
|
+
connection?: Connection;
|
|
22
41
|
}
|
|
23
42
|
export declare function privateDirectory(path: string): Promise<void>;
|
|
24
|
-
export declare function durableWrite(path: string, value: unknown): Promise<void>;
|
|
25
|
-
export declare function readJournal(path: string): Promise<unknown>;
|
|
26
43
|
export interface DiagnosticBinding {
|
|
27
44
|
api: RemoteDetailsApi | undefined;
|
|
28
45
|
connection: Connection | undefined;
|
|
29
46
|
}
|
|
47
|
+
/** Diagnostics are best effort. No delivery journal, receipt lookup, replay or turn gate. */
|
|
30
48
|
export declare function createRemoteDetails(options: {
|
|
31
|
-
profileDir
|
|
32
|
-
getApi
|
|
49
|
+
profileDir?: string;
|
|
50
|
+
getApi?: () => unknown;
|
|
51
|
+
warn?: (line: string) => void;
|
|
33
52
|
}): {
|
|
53
|
+
/** Await queued best-effort writes only when releasing the profile, never before dispatch. */
|
|
54
|
+
dispose(): Promise<void>;
|
|
55
|
+
releaseSession(sessionId: string): void;
|
|
56
|
+
read(query: {
|
|
57
|
+
sessionId: string;
|
|
58
|
+
provider: "claude" | "codex";
|
|
59
|
+
}): Promise<RemoteDetail[]>;
|
|
34
60
|
recordLocalFailure(request: {
|
|
35
61
|
sessionId?: string;
|
|
36
62
|
provider: "claude" | "codex";
|
|
@@ -46,8 +72,7 @@ export declare function createRemoteDetails(options: {
|
|
|
46
72
|
step: string | number | null;
|
|
47
73
|
};
|
|
48
74
|
}): Promise<{
|
|
49
|
-
eventId: string
|
|
50
|
-
recorded: true;
|
|
75
|
+
eventId: `${string}-${string}-${string}-${string}-${string}`;
|
|
51
76
|
}>;
|
|
52
77
|
recordPreflightCheck(request: {
|
|
53
78
|
sessionId?: string;
|
|
@@ -58,10 +83,9 @@ export declare function createRemoteDetails(options: {
|
|
|
58
83
|
step: string | number | null;
|
|
59
84
|
};
|
|
60
85
|
binding?: DiagnosticBinding;
|
|
61
|
-
assertScope?: () => void;
|
|
62
86
|
}): Promise<{
|
|
63
|
-
eventId: string
|
|
64
|
-
recorded: true;
|
|
87
|
+
eventId: `${string}-${string}-${string}-${string}-${string}`;
|
|
65
88
|
}>;
|
|
66
89
|
open(request: DetailRequest): Promise<DetailChannel>;
|
|
67
90
|
};
|
|
91
|
+
export {};
|