Files
gyxx-flow/workbench/plugin/client/src/store.js
T
wangyunlong 01218b2907 feat: add deepseek-harness workbench plugin and console diagnosis API
- console: GET /api/workflows/{id}, /runs/{run_id}, /runs/{run_id}/diagnosis
  (journal trace + sanitized bounded log tails, workflow/run pairing enforced)
- workbench/: dsh 宿主插件(7 个工作流工具、中文系统提示词、失败监控器、
  本机回环桥接服务)+ 侧边栏面板客户端包(sidebar.footer.action 与
  shell.overlay 追加插槽)+ 降级独立面板 + 一键启动脚本
- adapters/browser: 收敛 looks_like_login_url 到共享层,修复
  jd_main_image_collector 对 gyxx_flow.accounts 的越层导入
- tests: 新端点覆盖;replay_policy 断言对齐已迁移的 catalog(repeatable)
2026-09-04 11:10:16 +08:00

58 lines
1.3 KiB
JavaScript

/**
* GYXX 工作台面板 —— 极简外部存储(避免向客户端包引入额外依赖)。
* React 18 的 useSyncExternalStore 直接订阅。
*/
const listeners = new Set()
let state = {
open: false,
loading: false,
error: null,
generatedAt: null,
summary: null,
workflows: [],
selectedId: null,
detail: null,
detailLoading: false,
runs: [],
diagnosis: null,
diagnosisLoading: false,
question: '',
businessDate: defaultBusinessDate(),
alerts: [],
seenAlertIds: {},
toasts: [],
}
export function defaultBusinessDate() {
const now = new Date()
now.setDate(now.getDate() - 1)
const pad = (value) => String(value).padStart(2, '0')
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`
}
export function getState() {
return state
}
export function update(patch) {
state = { ...state, ...patch }
for (const listener of listeners) listener()
}
export function subscribe(listener) {
listeners.add(listener)
return () => listeners.delete(listener)
}
export function pushToast(toast) {
const id = `t-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`
update({ toasts: [...state.toasts, { id, ...toast }] })
return id
}
export function dismissToast(id) {
update({ toasts: state.toasts.filter((toast) => toast.id !== id) })
}