weifuwu 0.82.0 → 0.82.2

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.
@@ -3049,9 +3049,20 @@ body.wf-dragging {
3049
3049
  }
3050
3050
 
3051
3051
  .wf-chart-tooltip-label {
3052
+ display: inline-flex;
3053
+ align-items: center;
3054
+ gap: var(--wf-gap-xs);
3052
3055
  font-weight: var(--wf-font-weight-semibold);
3053
3056
  }
3054
3057
 
3058
+ .wf-chart-tooltip-dot {
3059
+ width: 8px;
3060
+ height: 8px;
3061
+ border-radius: 50%;
3062
+ display: inline-block;
3063
+ flex-shrink: 0;
3064
+ }
3065
+
3055
3066
  .wf-chart-tooltip-value {
3056
3067
  opacity: 0.8;
3057
3068
  }
@@ -8542,50 +8553,82 @@ body.wf-dragging {
8542
8553
  display: flex;
8543
8554
  align-items: center;
8544
8555
  gap: var(--wf-gap-md);
8556
+ /* thumb 尺寸(可覆盖定制;marks/tooltip 偏移常量按默认 18px 同步——覆盖需知悉) */
8557
+ --wf-slider-thumb-size: 18px;
8545
8558
  }
8546
8559
 
8547
- .wf-slider-input {
8560
+ /* 轨道容器(input + marks 同宽对齐——value 显示不参与) */
8561
+ .wf-slider-track {
8548
8562
  flex: 1;
8563
+ min-width: 0;
8564
+ }
8565
+
8566
+ .wf-slider-input {
8567
+ width: 100%;
8549
8568
  height: 6px;
8550
8569
  appearance: none;
8570
+ /* 清零 UA 默认 padding/border(Chrome range 默认 padding 9px + border 1px)——
8571
+ 否则 content 区被压缩,thumb 活动范围 ≠ 盒宽,marks/渐变偏移公式错位 */
8572
+ padding: 0;
8573
+ border: none;
8551
8574
  background: var(--wf-color-border);
8552
8575
  border-radius: var(--wf-radius-xs);
8553
8576
  outline: none;
8554
8577
  cursor: pointer;
8578
+ margin: 8px 0; /* thumb 18px 超出轨道——留出 hover/拖拽空间 */
8555
8579
  }
8556
8580
 
8557
- .wf-slider-input:hover::-webkit-slider-thumb {
8581
+ /* hover / 拖拽中(active):thumb 放大 + 加深(跨浏览器一致) */
8582
+ .wf-slider-input:hover::-webkit-slider-thumb,
8583
+ .wf-slider-input:active::-webkit-slider-thumb {
8558
8584
  transform: scale(1.15);
8585
+ background: var(--wf-color-primary-hover);
8559
8586
  }
8587
+ .wf-slider-input:hover::-moz-range-thumb,
8588
+ .wf-slider-input:active::-moz-range-thumb {
8589
+ transform: scale(1.15);
8590
+ background: var(--wf-color-primary-hover);
8591
+ }
8592
+
8560
8593
  .wf-slider-input:focus-visible::-webkit-slider-thumb {
8561
8594
  box-shadow: 0 0 0 3px var(--wf-color-primary-bg);
8562
8595
  }
8596
+ .wf-slider-input:focus-visible::-moz-range-thumb {
8597
+ box-shadow: 0 0 0 3px var(--wf-color-primary-bg);
8598
+ }
8599
+
8563
8600
  .wf-slider-input::-webkit-slider-thumb {
8564
8601
  appearance: none;
8565
- width: 18px;
8566
- height: 18px;
8602
+ width: var(--wf-slider-thumb-size);
8603
+ height: var(--wf-slider-thumb-size);
8567
8604
  border-radius: 50%;
8568
8605
  background: var(--wf-color-primary);
8569
8606
  cursor: pointer;
8570
8607
  border: 2px solid var(--wf-color-on-brand);
8571
8608
  box-shadow: var(--wf-slider-thumb-shadow, var(--wf-shadow-sm));
8572
- transition: transform 0.15s ease, box-shadow 0.15s ease;
8609
+ transition: transform var(--wf-dur-fast) var(--wf-ease-out),
8610
+ background-color var(--wf-dur-fast) var(--wf-ease-out),
8611
+ box-shadow var(--wf-dur-fast) var(--wf-ease-out);
8573
8612
  }
8574
8613
 
8575
8614
  /* Firefox 同款 thumb(跨浏览器一致) */
8576
8615
  .wf-slider-input::-moz-range-thumb {
8577
- width: 14px; /* 去除 border 后的同视觉尺寸 */
8578
- height: 14px;
8616
+ width: calc(var(--wf-slider-thumb-size) - 4px); /* 去除 border 后的同视觉尺寸 */
8617
+ height: calc(var(--wf-slider-thumb-size) - 4px);
8579
8618
  border-radius: 50%;
8580
8619
  background: var(--wf-color-primary);
8581
8620
  cursor: pointer;
8582
8621
  border: 2px solid var(--wf-color-on-brand);
8583
8622
  box-shadow: var(--wf-slider-thumb-shadow, var(--wf-shadow-sm));
8584
- transition: transform 0.15s ease, box-shadow 0.15s ease;
8623
+ transition: transform var(--wf-dur-fast) var(--wf-ease-out),
8624
+ background-color var(--wf-dur-fast) var(--wf-ease-out),
8625
+ box-shadow var(--wf-dur-fast) var(--wf-ease-out);
8585
8626
  }
8586
8627
 
8587
8628
  .wf-slider-input::-moz-range-track {
8588
8629
  height: 6px;
8630
+ padding: 0; /* Firefox track 默认 padding——清零保 content = 盒宽 */
8631
+ border: none;
8589
8632
  border-radius: var(--wf-radius-xs);
8590
8633
  background: transparent; /* 进度填充由组件 inline 渐变提供 */
8591
8634
  }
@@ -8602,9 +8645,58 @@ body.wf-dragging {
8602
8645
  text-align: center;
8603
8646
  }
8604
8647
 
8648
+ /* ── 当前值气泡(拖拽/hover/focus 显示——portal 渲染) ── */
8649
+ .wf-slider-tip {
8650
+ z-index: var(--wf-z-tooltip);
8651
+ background: var(--wf-color-text);
8652
+ color: var(--wf-color-bg);
8653
+ padding: 2px var(--wf-space-sm);
8654
+ border-radius: var(--wf-radius-sm);
8655
+ font-size: var(--wf-font-size-xs);
8656
+ font-weight: var(--wf-font-weight-semibold);
8657
+ transform: translate(-50%, -100%);
8658
+ pointer-events: none;
8659
+ white-space: nowrap;
8660
+ }
8661
+
8662
+ /* ── 刻度标记(marks) ── */
8663
+ .wf-slider-marks {
8664
+ position: relative;
8665
+ height: 18px;
8666
+ margin-top: 2px;
8667
+ pointer-events: none;
8668
+ }
8669
+
8670
+ .wf-slider-mark {
8671
+ position: absolute;
8672
+ top: 0;
8673
+ transform: translateX(-50%);
8674
+ display: flex;
8675
+ flex-direction: column;
8676
+ align-items: center;
8677
+ gap: 2px;
8678
+ }
8679
+
8680
+ .wf-slider-mark-dot {
8681
+ width: 8px;
8682
+ height: 8px;
8683
+ border-radius: 50%;
8684
+ background: var(--wf-color-border-dark);
8685
+ border: 2px solid var(--wf-color-bg);
8686
+ box-sizing: border-box;
8687
+ }
8688
+
8689
+ .wf-slider-mark-label {
8690
+ font-size: var(--wf-font-size-xs);
8691
+ color: var(--wf-color-text-tertiary);
8692
+ white-space: nowrap;
8693
+ }
8694
+
8605
8695
  /* disabled(F2 状态矩阵) */
8606
8696
  .wf-slider-input--dis { opacity: 0.5; cursor: not-allowed; }
8607
8697
  .wf-slider-input:disabled { cursor: not-allowed; }
8698
+ .wf-slider-input:disabled::-webkit-slider-thumb,
8699
+ .wf-slider-input:disabled::-moz-range-thumb { cursor: not-allowed; }
8608
8700
 
8609
8701
  /* weifuwu/components — Space 间距容器 */
8610
8702
 
package/dist/index.js CHANGED
@@ -1696,6 +1696,28 @@ function userSystem(options) {
1696
1696
  currentUser = user;
1697
1697
  return { ...session, user };
1698
1698
  },
1699
+ async ssoLogin(email2, opts) {
1700
+ const normalized = normalizeEmail(email2);
1701
+ let user;
1702
+ const existing = await sql.query.from(USERS_TABLE).select("id", "email", "name", "role", "tenant").where({ email: normalized }).run();
1703
+ if (existing.length) {
1704
+ user = existing[0];
1705
+ } else {
1706
+ const rows = await sql.query.insert(USERS_TABLE).values({ email: normalized, password_hash: null, name: opts?.name ?? null, role: null, tenant: null }).returning("id", "email", "name", "role", "tenant").run();
1707
+ user = rows[0];
1708
+ }
1709
+ let appId;
1710
+ if (opts?.appId) {
1711
+ const member = await findMemberRole(opts.appId, user.id);
1712
+ if (!member) {
1713
+ await sql.query.insert(MEMBER_TABLE).values({ app_id: opts.appId, user_id: user.id, role: "member", invited_by: null }).run();
1714
+ }
1715
+ appId = opts.appId;
1716
+ }
1717
+ const session = await issueSession(user, appId ? { appId, role: "member" } : void 0);
1718
+ currentUser = user;
1719
+ return { ...session, user };
1720
+ },
1699
1721
  async createInvite(appId, opts) {
1700
1722
  if (!currentUser) throw new HttpError("Unauthorized", 401);
1701
1723
  const role = await findMemberRole(appId, currentUser.id);
@@ -1736,7 +1758,7 @@ function userSystem(options) {
1736
1758
  CREATE TABLE IF NOT EXISTS ${USERS_TABLE} (
1737
1759
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
1738
1760
  email TEXT NOT NULL UNIQUE,
1739
- password_hash TEXT NOT NULL,
1761
+ password_hash TEXT,
1740
1762
  name TEXT,
1741
1763
  role TEXT,
1742
1764
  tenant TEXT,
@@ -1744,6 +1766,7 @@ function userSystem(options) {
1744
1766
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
1745
1767
  )
1746
1768
  `);
1769
+ await sql.unsafe(`ALTER TABLE ${USERS_TABLE} ALTER COLUMN password_hash DROP NOT NULL`);
1747
1770
  await sql.unsafe(`
1748
1771
  CREATE TABLE IF NOT EXISTS ${SESSIONS_TABLE} (
1749
1772
  token_hash TEXT PRIMARY KEY,
@@ -2941,9 +2964,14 @@ function createEmbeddingClient(ebd) {
2941
2964
  };
2942
2965
  }
2943
2966
  function createAiClient(opts) {
2944
- const endpoint = `${opts.baseUrl.replace(/\/$/, "")}/chat/completions`;
2945
- const headers = { "Content-Type": "application/json", Authorization: `Bearer ${opts.apiKey}` };
2946
2967
  const embedding = createEmbeddingClient(opts.embedding);
2968
+ function endpointFor(params) {
2969
+ const base2 = params.baseUrl ?? opts.baseUrl;
2970
+ return `${base2.replace(/\/$/, "")}/chat/completions`;
2971
+ }
2972
+ function headersFor(params) {
2973
+ return { "Content-Type": "application/json", Authorization: `Bearer ${params.apiKey ?? opts.apiKey}` };
2974
+ }
2947
2975
  const approvals = /* @__PURE__ */ new Map();
2948
2976
  function approve(response) {
2949
2977
  const resolve3 = approvals.get(response.id);
@@ -2985,9 +3013,9 @@ function createAiClient(opts) {
2985
3013
  return calls;
2986
3014
  }
2987
3015
  async function chat(params, options) {
2988
- const res = await fetch(endpoint, {
3016
+ const res = await fetch(endpointFor(params), {
2989
3017
  method: "POST",
2990
- headers,
3018
+ headers: headersFor(params),
2991
3019
  body: JSON.stringify({ ...params, model: params.model ?? opts.defaultModel, stream: false }),
2992
3020
  signal: options?.signal
2993
3021
  });
@@ -3020,9 +3048,9 @@ function createAiClient(opts) {
3020
3048
  const { emit, signal } = stepOpts;
3021
3049
  let res;
3022
3050
  try {
3023
- res = await fetch(endpoint, {
3051
+ res = await fetch(endpointFor(params), {
3024
3052
  method: "POST",
3025
- headers,
3053
+ headers: headersFor(params),
3026
3054
  body: JSON.stringify({ ...params, model: params.model ?? opts.defaultModel, stream: true }),
3027
3055
  signal
3028
3056
  });
@@ -3169,7 +3197,7 @@ function createAgent(client, config) {
3169
3197
  emit("wf:step", { type: "llm" });
3170
3198
  let finish = { content: "", toolCalls: [] };
3171
3199
  await client.streamStep(
3172
- { model: config.model, messages: all, tools: toolDefs },
3200
+ { model: config.model, apiKey: config.apiKey, baseUrl: config.baseUrl, messages: all, tools: toolDefs },
3173
3201
  {
3174
3202
  emit,
3175
3203
  signal,