feat(client): persist digital governance events

This commit is contained in:
baiyanyun
2026-06-07 18:59:59 +08:00
parent 5e76828afe
commit e37024bdbe
14 changed files with 925 additions and 158 deletions

View File

@@ -34,6 +34,7 @@ declare global {
saveUiState?: (update: { state: AdapterState; action?: string; date?: string; metadata?: Record<string, unknown> }) => Promise<AdapterState>;
getSyncStatus?: () => Promise<QimingclawSyncStatus>;
flushSync?: () => Promise<QimingclawSyncStatus>;
recordGovernanceCommand?: (command: QimingclawGovernanceCommandRecord) => Promise<unknown>;
};
};
}
@@ -124,6 +125,19 @@ interface QimingclawSnapshot {
uiState?: AdapterState | null;
}
interface QimingclawGovernanceCommandRecord {
commandKind: string;
commandId: string;
correlationId?: string;
planId?: string | null;
scheduleId?: string | null;
accepted?: boolean;
message?: string;
error?: string | null;
payload?: Record<string, unknown> | null;
result?: Record<string, unknown> | null;
}
interface QimingclawRuntimeRecords {
generatedAt: string;
plans: QimingclawPlanRecord[];
@@ -519,6 +533,34 @@ async function saveState(
}
}
async function recordGovernanceCommand(
body: GovernanceCommandRequest,
response: GovernanceCommandResponse,
): Promise<void> {
try {
await window.QimingClawBridge?.digital?.recordGovernanceCommand?.({
commandKind: body.command_kind,
commandId: response.command_id,
correlationId: response.correlation_id,
planId: stringFromUnknown(response.result?.plan_id)
|| stringFromUnknown(body.context_refs?.plan_id)
|| stringFromUnknown(body.payload?.plan_id)
|| null,
scheduleId: stringFromUnknown(response.result?.schedule_id)
|| stringFromUnknown(body.context_refs?.schedule_id)
|| stringFromUnknown(body.payload?.schedule_id)
|| null,
accepted: response.accepted,
message: response.message,
error: response.error ?? null,
payload: body.payload ?? null,
result: response.result ?? null,
});
} catch {
// Bridge persistence is best-effort; the adapter response should not block UI flow.
}
}
function parseJsonBody<T>(body: BodyInit | null | undefined): T {
if (typeof body !== 'string' || !body.trim()) return {} as T;
return JSON.parse(body) as T;
@@ -1689,37 +1731,43 @@ async function handleGovernanceCommand(
if (body.command_kind === 'create_plan') {
const createdPlanId = `qimingclaw-local-${slugifyIdPart(stringFromUnknown(body.payload?.title) || planId || 'plan')}-${Date.now()}`;
return governanceAccepted(commandId, correlationId, '已在 qimingclaw 兼容层创建本地计划草稿。', {
const response = governanceAccepted(commandId, correlationId, '已在 qimingclaw 兼容层创建本地计划草稿。', {
plan_id: createdPlanId,
status: 'draft',
source: 'qimingclaw-adapter',
requested_action: body.payload?.requested_action,
original_plan_id: body.payload?.original_plan_id ?? planId,
});
await recordGovernanceCommand(body, response);
return response;
}
if (body.command_kind === 'activate_plan' || body.command_kind === 'run_schedule_now') {
const targetPlanId = planId || runtimeDebugPlans(snapshot)[0]?.plan_id || PLANS[0]?.plan_id || 'qimingclaw-client-readiness';
const dispatch = await dispatchPlan(targetPlanId, snapshot);
return governanceAccepted(commandId, correlationId, '已映射为 qimingclaw 本地任务激活。', {
const response = governanceAccepted(commandId, correlationId, '已映射为 qimingclaw 本地任务激活。', {
plan_id: targetPlanId,
status: 'active',
dispatched_tasks: dispatch.dispatched_tasks,
source: 'qimingclaw-adapter',
});
await recordGovernanceCommand(body, response);
return response;
}
if (body.command_kind === 'create_schedule') {
return governanceAccepted(commandId, correlationId, '已记录 qimingclaw 兼容定时任务请求。', {
const response = governanceAccepted(commandId, correlationId, '已记录 qimingclaw 兼容定时任务请求。', {
schedule_id: scheduleId || `qimingclaw-schedule-${Date.now()}`,
plan_id: planId,
status: 'enabled',
source: 'qimingclaw-adapter',
});
await recordGovernanceCommand(body, response);
return response;
}
if (['submit_plan', 'approve_plan', 'amend_plan', 'resume_plan', 'pause_plan', 'cancel_plan'].includes(body.command_kind)) {
return governanceAccepted(commandId, correlationId, `已接受 ${body.command_kind},当前由 qimingclaw 本地 adapter 记录兼容状态。`, {
const response = governanceAccepted(commandId, correlationId, `已接受 ${body.command_kind},当前由 qimingclaw 本地 adapter 记录兼容状态。`, {
plan_id: planId,
status: body.command_kind === 'approve_plan'
? 'approved'
@@ -1728,15 +1776,19 @@ async function handleGovernanceCommand(
: 'accepted',
source: 'qimingclaw-adapter',
});
await recordGovernanceCommand(body, response);
return response;
}
return {
const response = {
command_id: commandId,
accepted: false,
correlation_id: correlationId,
error: 'missing_capability',
message: `qimingclaw 数字员工兼容层尚未支持 ${body.command_kind}`,
};
await recordGovernanceCommand(body, response);
return response;
}
function governanceAccepted(