@ai-workbench/remote-agent 0.8.21 → 0.8.24
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 +28 -155
- package/dist/acp.d.ts +20 -15
- package/dist/acp.js +197 -224
- 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 +40 -105
- package/dist/client.js +34 -127
- 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 -3
- package/dist/employee-endpoint.js +8 -39
- package/dist/employee-exec.d.ts +4 -3
- package/dist/employee-exec.js +25 -13
- package/dist/employee-info.d.ts +5 -1
- package/dist/employee-info.js +16 -5
- 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 +1 -1
- package/dist/index.d.ts +12 -42
- package/dist/index.js +203 -471
- package/dist/input.js +2 -3
- package/dist/local-user-turn.js +5 -6
- package/dist/mapping.d.ts +0 -3
- package/dist/mapping.js +0 -34
- 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.d.ts +0 -1
- package/dist/presentation.js +21 -42
- package/dist/provider.d.ts +12 -48
- package/dist/provider.js +18 -106
- 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
|
@@ -2,10 +2,8 @@ import { hostWorkspaceGuard } from "./host-workspace.js";
|
|
|
2
2
|
import { connectNeedError } from "./connect-need.js";
|
|
3
3
|
import { loginDiagnostic, loginReason } from "./login-diagnostic.js";
|
|
4
4
|
import { NeedError } from "./remote.js";
|
|
5
|
-
import { CONNECTION_REQUIRED
|
|
5
|
+
import { CONNECTION_REQUIRED } 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');
|
|
@@ -120,28 +118,15 @@ export function validateTarget(t) {
|
|
|
120
118
|
|| ![t.projectRoot, t.session.command, t.session.root, t.session.settingsPath].every(p => typeof p === 'string' && p.startsWith('/'))) {
|
|
121
119
|
throw new NeedError('CONNECT_API_MISMATCH', '我需要 connect-api 0.3.0 的可信主机、项目和 session 能力;旧目标不能继续使用', 'L 提供的完整 0.3.0 目标');
|
|
122
120
|
}
|
|
123
|
-
hostContextNotice(t);
|
|
124
|
-
}
|
|
125
|
-
/** Only the declared public check identifiers/statuses, never provider evidence. */
|
|
126
|
-
export function hostContextNotice(t) {
|
|
127
|
-
const h = t.hostContext;
|
|
128
|
-
if (h === undefined)
|
|
129
|
-
return;
|
|
130
|
-
const checks = (items) => Array.isArray(items) && items.every(item => item && typeof item.id === 'string' && typeof item.status === 'string');
|
|
131
|
-
if (!h || (h.enforcement !== 'test' && h.enforcement !== 'production') || (h.checkExitCode !== 0 && h.checkExitCode !== 1) || !checks(h.failedChecks) || !checks(h.unverifiedChecks))
|
|
132
|
-
throw new NeedError('CONNECT_API_MISMATCH', '主机检查背景无效,不能假定已通过生产检查', 'L 提供的有效 hostContext');
|
|
133
|
-
if (h.enforcement !== 'test')
|
|
134
|
-
return;
|
|
135
|
-
return TEST_HOST_NOTICE;
|
|
136
121
|
}
|
|
137
122
|
export function identity(t) { return `${t.username}@${t.host}:${t.port}`; }
|
|
138
123
|
/** Reject draft.3 and legacy runtime rather than inventing workspace bindings. */
|
|
139
124
|
export function requireNativeWorkspace(api) {
|
|
140
125
|
if (typeof api.getContractInfo !== 'function')
|
|
141
|
-
throw new NeedError('DEPENDENCY_REQUIRED', '我需要新版远程主机连接组件提供原生工作区绑定', 'L connect-api 0.7.0 /
|
|
126
|
+
throw new NeedError('DEPENDENCY_REQUIRED', '我需要新版远程主机连接组件提供原生工作区绑定', 'L connect-api 0.7.0 / ensureReady / resolveSessionProject');
|
|
142
127
|
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 /
|
|
128
|
+
if (info?.apiVersion !== '0.7.0' || info.status !== 'implemented' || !['ensureReady', 'resolveSessionProject'].every(key => typeof api[key] === 'function'))
|
|
129
|
+
throw new NeedError('DEPENDENCY_REQUIRED', '我需要新版远程主机连接组件提供原生工作区绑定', 'L connect-api 0.7.0 / ensureReady / resolveSessionProject');
|
|
145
130
|
}
|
|
146
131
|
/** Authorization stays in L; ensureReady only checks and records the need. */
|
|
147
132
|
export async function offerLogin(connect, request, currentApi, agent = CODEX_AGENT) {
|
|
@@ -189,32 +174,20 @@ export function connectProvider(get, options = {}) {
|
|
|
189
174
|
let employee;
|
|
190
175
|
const admissions = new WeakMap();
|
|
191
176
|
const preflight = async (request) => {
|
|
192
|
-
request.timing ??= new StageTiming();
|
|
193
177
|
request.signal?.throwIfAborted();
|
|
194
178
|
const api = get();
|
|
195
179
|
if (!api)
|
|
196
180
|
throw new NeedError('DEPENDENCY_REQUIRED', CONNECTION_REQUIRED, 'aiWorkbenchConnect');
|
|
197
181
|
requireNativeWorkspace(api);
|
|
198
182
|
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
183
|
let sourceStage = 'input-acceptance';
|
|
203
|
-
if (confirmedSource && !request.recordEarlyFailure)
|
|
204
|
-
request.recordEarlyFailure = (error, stage) => confirmedSource.recordFailure(error, stage);
|
|
205
184
|
try {
|
|
206
|
-
confirmedSource?.assertCurrent();
|
|
207
185
|
if (options.employee) {
|
|
208
186
|
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?.(); };
|
|
187
|
+
request.localContext = await module.inspectEmployeeWorkspace(get, options.employee, agent, api, request);
|
|
215
188
|
}
|
|
216
189
|
sourceStage = 'login-readiness';
|
|
217
|
-
const { target, connection } = await
|
|
190
|
+
const { target, connection } = await (async () => {
|
|
218
191
|
request.localAdmissionCheck?.();
|
|
219
192
|
const before = api.getConnectionState();
|
|
220
193
|
const target = await ensureReady(api, agent.loginProvider, request.signal);
|
|
@@ -224,11 +197,9 @@ export function connectProvider(get, options = {}) {
|
|
|
224
197
|
throw new NeedError('CONNECTION_LOST', '远程主机连接组件已更换', '当前员工连接');
|
|
225
198
|
const connection = await waitForLogin(api, agent.loginProvider, before, get, request.signal);
|
|
226
199
|
return { target, connection };
|
|
227
|
-
});
|
|
200
|
+
})();
|
|
228
201
|
if (request.identity && request.identity !== identity(target))
|
|
229
202
|
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
203
|
request.localAdmissionCheck?.();
|
|
233
204
|
admissions.set(request, { api, target, connection });
|
|
234
205
|
sourceStage = 'local-admission';
|
|
@@ -236,7 +207,6 @@ export function connectProvider(get, options = {}) {
|
|
|
236
207
|
if (locations && (locations.phase === 'failed' || locations.phase === 'disposed') && locations.instanceId === connection.instanceId && locations.epoch === connection.epoch && locations.need)
|
|
237
208
|
throw connectNeedError(locations.need);
|
|
238
209
|
await options.local?.admit?.(request, api, connection, target);
|
|
239
|
-
confirmedSource?.assertCurrent();
|
|
240
210
|
}
|
|
241
211
|
catch (error) {
|
|
242
212
|
admissions.delete(request);
|
|
@@ -244,8 +214,6 @@ export function connectProvider(get, options = {}) {
|
|
|
244
214
|
request.recordEarlyFailure = undefined;
|
|
245
215
|
if (record)
|
|
246
216
|
await record(error, sourceStage);
|
|
247
|
-
else
|
|
248
|
-
await confirmedSource?.recordFailure(error, sourceStage);
|
|
249
217
|
throw error;
|
|
250
218
|
}
|
|
251
219
|
};
|
|
@@ -255,16 +223,13 @@ export function connectProvider(get, options = {}) {
|
|
|
255
223
|
const admitted = admissions.get(request);
|
|
256
224
|
admissions.delete(request);
|
|
257
225
|
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
226
|
if (!request.sessionId)
|
|
262
227
|
throw new NeedError('PROJECT_BINDING_REQUIRED', '我需要当前会话和已选择的工作区,请使用原生工作区入口', 'DSH会话与原生工作区');
|
|
263
|
-
const host = await hostWorkspaceGuard(get, api, connection, target, request, options.
|
|
228
|
+
const host = await hostWorkspaceGuard(get, api, connection, target, request, options.workspace, agent.loginProvider);
|
|
264
229
|
try {
|
|
265
230
|
if (!host && options.employee) {
|
|
266
231
|
employee ??= import("./employee-provider.js").then(module => module.createEmployeeProvider(get, options, agent));
|
|
267
|
-
const local = await (await employee)({ api, target, connection, request
|
|
232
|
+
const local = await (await employee)({ api, target, connection, request });
|
|
268
233
|
if (local) {
|
|
269
234
|
local.loginRequired = () => offerLogin(api, request, get, agent);
|
|
270
235
|
return local;
|
|
@@ -272,79 +237,33 @@ export function connectProvider(get, options = {}) {
|
|
|
272
237
|
}
|
|
273
238
|
if (!host && agent.loginProvider === 'claude' && options.local) {
|
|
274
239
|
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
|
-
}
|
|
240
|
+
if (runtime)
|
|
283
241
|
return runtime;
|
|
284
|
-
}
|
|
285
242
|
}
|
|
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);
|
|
243
|
+
// A local source must have been handled by its employee provider above.
|
|
244
|
+
// Host execution requires an explicit host location; no name-based resolver.
|
|
245
|
+
if (!host)
|
|
246
|
+
throw new NeedError('WORKSPACE_LOCATION_REQUIRED', '请选择文件夹来源;改变来源后请新建会话。', '已选择的本机或主机文件夹');
|
|
247
|
+
const resolved = await host.resolve();
|
|
296
248
|
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
249
|
if (request.cwd && request.cwd !== project.path || request.bindingId && request.bindingId !== resolved.bindingId || request.workspaceId && request.workspaceId !== resolved.workspaceId)
|
|
301
250
|
throw new NeedError(host ? 'PROJECT_BINDING_INVALID' : 'SESSION_CONTEXT_MISMATCH', host ? '文件来源已改,请新建会话继续;原会话历史仍可查看。' : '原会话的工作区绑定已改变,请新建会话', '原工作区绑定');
|
|
302
|
-
const details = await
|
|
251
|
+
const details = await options.details?.(request, api, connection, target);
|
|
303
252
|
try {
|
|
304
|
-
if (details)
|
|
305
|
-
request.timing.bind(detail => details.record(detail));
|
|
306
|
-
await stable();
|
|
307
|
-
host?.assertCurrent();
|
|
308
|
-
if (host)
|
|
309
|
-
details?.record({ kind: 'session', severity: 'info', code: 'HOST_EXECUTION_VALIDATION_POLICY', summary: '主机目录核验不可关闭:每轮接纳时由L核验主机身份、登录与物理目录;之后消息、审批回复与检查点只核对内存中的连接、登录与位置,靠已订阅的L连接和位置事件撤销,不重复SSH。' });
|
|
310
|
-
let workspaceNotice = undefined;
|
|
311
|
-
const notice = !host && 'notice' in resolved ? resolved.notice : undefined;
|
|
312
|
-
if (notice) {
|
|
313
|
-
if (!options.notice)
|
|
314
|
-
throw new NeedError('DEPENDENCY_REQUIRED', '我需要官方会话持久记录来确认工作区说明', '官方会话与持久化服务');
|
|
315
|
-
workspaceNotice = await request.timing.run('workspace-notice', () => options.notice.deliver(notice, resolved, request, api));
|
|
316
|
-
await stable();
|
|
317
|
-
}
|
|
318
253
|
if (!options.open)
|
|
319
254
|
throw new NeedError('RUNTIME_REQUIRED', '我需要主机运行适配器', '主机broker适配');
|
|
320
|
-
const
|
|
321
|
-
const validateContext = async (ignoreCancellation = false) => {
|
|
322
|
-
const check = () => waitForLogin(api, agent.loginProvider, connection, get, ignoreCancellation ? undefined : request.signal);
|
|
323
|
-
await check();
|
|
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 });
|
|
255
|
+
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
256
|
try {
|
|
336
|
-
await stable();
|
|
337
257
|
host?.observeRuntime(runtime);
|
|
338
258
|
}
|
|
339
259
|
catch (error) {
|
|
340
|
-
|
|
260
|
+
void runtime.dispose?.().catch(() => console.warn('HOST_CLEANUP_FAILED'));
|
|
341
261
|
throw error;
|
|
342
262
|
}
|
|
343
263
|
if (host)
|
|
344
264
|
retainHostScope(runtime, host);
|
|
345
265
|
runtime.hostWorkspace = host && 'directory' in resolved ? Object.freeze({ cwd: resolved.directory.path }) : undefined;
|
|
346
266
|
// The transport can outlive a turn; presentation belongs only to this invocation.
|
|
347
|
-
runtime.workspaceNotice = workspaceNotice || undefined;
|
|
348
267
|
runtime.details = details ?? runtime.details;
|
|
349
268
|
runtime.binding = { bindingId: resolved.bindingId, workspaceId: resolved.workspaceId, revision: resolved.bindingRevision };
|
|
350
269
|
runtime.connection = { ...connection };
|
|
@@ -352,13 +271,6 @@ export function connectProvider(get, options = {}) {
|
|
|
352
271
|
return runtime;
|
|
353
272
|
}
|
|
354
273
|
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
274
|
throw error;
|
|
363
275
|
}
|
|
364
276
|
}
|
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 {};
|