page-agent-sdk 4.8.1 → 4.8.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.
@@ -7702,6 +7702,18 @@ var Vu = class {
7702
7702
  }
7703
7703
  };
7704
7704
  function Hu(e) {
7705
+ let t = e?.pendingReanchors;
7706
+ if (!e || !t || !t.length) return;
7707
+ let n = t.map(([t, n]) => ({
7708
+ o: t,
7709
+ n,
7710
+ spec: e.resourcesByPath.get(t)
7711
+ })).filter((e) => !!e.spec && e.o !== e.n);
7712
+ for (let t of n) e.resourcesByPath.delete(t.o);
7713
+ for (let t of n) e.resourcesByPath.has(t.n) || e.resourcesByPath.set(t.n, t.spec);
7714
+ t.length = 0;
7715
+ }
7716
+ function Uu(e) {
7705
7717
  let { jp: t, resolved: n, resourcesByPath: r, resourceStore: i } = e;
7706
7718
  if (!r.size) return n;
7707
7719
  let a = !1;
@@ -7722,7 +7734,7 @@ function Hu(e) {
7722
7734
  }
7723
7735
  return o;
7724
7736
  }
7725
- function Uu(e, t, n, r) {
7737
+ function Wu(e, t, n, r) {
7726
7738
  if (!r) return {
7727
7739
  code: "RESOURCE_NOT_FOUND",
7728
7740
  message: `句柄 "${e}" 无法展开(资源池未启用)`,
@@ -7743,37 +7755,69 @@ function Uu(e, t, n, r) {
7743
7755
  hint: "重新 read 该字段触发懒注册重建句柄,再写回新句柄 ⟦res:<handle>⟧"
7744
7756
  };
7745
7757
  }
7746
- function Wu(e, t, n) {
7758
+ function Gu(e, t, n) {
7759
+ if (n === void 0) return;
7760
+ let r = t.split(".");
7761
+ for (let i = 0; i < r.length - 1; i++) {
7762
+ if (!/^\d+$/.test(r[i])) continue;
7763
+ let a = r.slice(0, i).join("."), o = r.slice(i + 1).join("."), s = Q(e, a);
7764
+ if (Array.isArray(s)) for (let e = 0; e < s.length; e++) {
7765
+ let a = Q(s[e], o);
7766
+ if (a !== void 0 && zu(a, n)) {
7767
+ let n = [
7768
+ ...r.slice(0, i),
7769
+ String(e),
7770
+ ...r.slice(i + 1)
7771
+ ].join(".");
7772
+ if (n !== t) return n;
7773
+ }
7774
+ }
7775
+ }
7776
+ }
7777
+ function Ku(e, t, n) {
7778
+ let r = n.split("."), i = r.findIndex((e) => /^\d+$/.test(e));
7779
+ if (i < 0) return !1;
7780
+ let a = r.slice(0, i).join("."), o = Number(r[i]), s = Q(e, a), c = Q(t, a);
7781
+ if (!Array.isArray(s) || !Array.isArray(c)) return !1;
7782
+ let l = s[o];
7783
+ if (l === void 0) return !1;
7784
+ for (let e = 0; e < c.length; e++) if (e !== o && zu(l, c[e])) return !0;
7785
+ return !1;
7786
+ }
7787
+ function qu(e, t, n) {
7747
7788
  let r = t.getBind();
7789
+ t.pendingReanchors && (t.pendingReanchors.length = 0);
7748
7790
  for (let [i, a] of t.resourcesByPath) {
7749
- let o = Q(r, i), s = Q(e, i);
7750
- if (s === void 0) {
7791
+ let o = Q(r, i), s = Gu(e, i, o);
7792
+ s && t.pendingReanchors?.push([i, s]);
7793
+ let c = Q(e, s ?? i);
7794
+ if (c === void 0) {
7751
7795
  if (o === void 0) continue;
7752
- let r = i.split(".");
7753
- if (Q(e, r.length > 1 ? r.slice(0, -1).join(".") : "") !== void 0) {
7796
+ let s = i.split(".");
7797
+ if (Q(e, s.length > 1 ? s.slice(0, -1).join(".") : "") !== void 0 && !Ku(e, r, i)) {
7754
7798
  zs(e, i, o);
7755
7799
  continue;
7756
7800
  }
7757
- if (!(e && typeof e == "object" && r[0] in e)) {
7801
+ if (!(e && typeof e == "object" && s[0] in e)) {
7758
7802
  if (n) continue;
7759
7803
  zs(e, i, o);
7760
7804
  continue;
7761
7805
  }
7762
- let s = a.mode === "freeze" && !!t.isFieldRequired?.(i);
7806
+ let c = a.mode === "freeze" && !!t.isFieldRequired?.(i);
7763
7807
  return {
7764
7808
  ok: !1,
7765
7809
  code: a.mode === "freeze" ? "FROZEN_FIELD" : "VERBATIM_PROTECTED",
7766
7810
  path: i,
7767
7811
  message: `整体替换会移除受保护字段 "${i}"(${a.mode}),已拒绝`,
7768
- hint: a.mode === "freeze" ? "含冻结字段的容器不可整体清空/替换:保留包含该字段的元素(补齐其必填字段,如 type),或逐个 remove 其余元素;彻底移除该字段需集成方调整 data.resources" + (s ? `;⚠ 该字段("${i.split(".").pop()}")同时是 schema 必填 —— 新建同类元素会因缺它被 schema 拒,此路死锁:勿反复整体替换重试,改用增量 patch 只写非保护字段,或由集成方将保护字段设为可选/给默认值` : "") : "含 verbatim 字段的容器不可整体清空/替换:保留包含该字段的元素,或先 resource_delete({path}) 释放保护后再整体替换"
7812
+ hint: a.mode === "freeze" ? "含冻结字段的容器不可整体清空/替换:保留包含该字段的元素(补齐其必填字段,如 type),或逐个 remove 其余元素;彻底移除该字段需集成方调整 data.resources" + (c ? `;⚠ 该字段("${i.split(".").pop()}")同时是 schema 必填 —— 新建同类元素会因缺它被 schema 拒,此路死锁:勿反复整体替换重试,改用增量 patch 只写非保护字段,或由集成方将保护字段设为可选/给默认值` : "") : "含 verbatim 字段的容器不可整体清空/替换:保留包含该字段的元素,或先 resource_delete({path}) 释放保护后再整体替换"
7769
7813
  };
7770
7814
  }
7771
7815
  if (a.mode === "freeze") {
7772
- if (s === Pu(i)) {
7816
+ if (c === Pu(i)) {
7773
7817
  zs(e, i, o);
7774
7818
  continue;
7775
7819
  }
7776
- if (!zu(s, o)) return {
7820
+ if (!zu(c, o)) return {
7777
7821
  ok: !1,
7778
7822
  code: "FROZEN_FIELD",
7779
7823
  path: i,
@@ -7781,9 +7825,9 @@ function Wu(e, t, n) {
7781
7825
  hint: "该字段由系统/集成方维护,LLM 不得改动。如需展示其值用 resource_get({path}) 取真值"
7782
7826
  };
7783
7827
  } else {
7784
- let n = Iu(s);
7828
+ let n = Iu(c);
7785
7829
  if (n && n.type === "res") {
7786
- let r = Uu(n.handle, i, o, t.resourceStore);
7830
+ let r = Wu(n.handle, i, o, t.resourceStore);
7787
7831
  if ("value" in r) {
7788
7832
  zs(e, i, r.value);
7789
7833
  continue;
@@ -7796,7 +7840,7 @@ function Wu(e, t, n) {
7796
7840
  hint: r.hint
7797
7841
  };
7798
7842
  }
7799
- if (!zu(s, o)) return {
7843
+ if (!zu(c, o)) return {
7800
7844
  ok: !1,
7801
7845
  code: "VERBATIM_MISMATCH",
7802
7846
  path: i,
@@ -7807,7 +7851,7 @@ function Wu(e, t, n) {
7807
7851
  }
7808
7852
  return { ok: !0 };
7809
7853
  }
7810
- function Gu(e, t, n) {
7854
+ function Ju(e, t, n) {
7811
7855
  let r = t === void 0 ? e.message : `patches[${t}]${n ? ` @ "${n}"` : ""}: ${e.message}`;
7812
7856
  return Z({
7813
7857
  code: e.code,
@@ -7820,22 +7864,22 @@ function Gu(e, t, n) {
7820
7864
  } }
7821
7865
  });
7822
7866
  }
7823
- function Ku(e) {
7867
+ function Yu(e) {
7824
7868
  let { value: t, ctx: n, mergeMode: r } = e;
7825
7869
  if (!n || !n.resourcesByPath.size) return {
7826
7870
  ok: !0,
7827
7871
  value: t
7828
7872
  };
7829
- let i = Vs(t), a = Wu(i, n, r);
7873
+ let i = Vs(t), a = qu(i, n, r);
7830
7874
  return a.ok ? {
7831
7875
  ok: !0,
7832
7876
  value: i
7833
7877
  } : {
7834
7878
  ok: !1,
7835
- error: Gu(a)
7879
+ error: Ju(a)
7836
7880
  };
7837
7881
  }
7838
- function qu(e) {
7882
+ function Xu(e) {
7839
7883
  let { patches: t, clone: n, ctx: r } = e;
7840
7884
  if (!r || !r.resourcesByPath.size) return { ok: !0 };
7841
7885
  for (let e = 0; e < t.length; e++) {
@@ -7860,17 +7904,17 @@ function qu(e) {
7860
7904
  }
7861
7905
  }
7862
7906
  }
7863
- let i = Wu(n, r);
7907
+ let i = qu(n, r);
7864
7908
  if (!i.ok) {
7865
- let e = Ju(i.path, t);
7909
+ let e = Zu(i.path, t);
7866
7910
  return {
7867
7911
  ok: !1,
7868
- error: Gu(i, e >= 0 ? e : void 0, e >= 0 ? t[e].jsonPath : void 0)
7912
+ error: Ju(i, e >= 0 ? e : void 0, e >= 0 ? t[e].jsonPath : void 0)
7869
7913
  };
7870
7914
  }
7871
7915
  return { ok: !0 };
7872
7916
  }
7873
- function Ju(e, t) {
7917
+ function Zu(e, t) {
7874
7918
  let n = Lu(e);
7875
7919
  for (let e = 0; e < t.length; e++) {
7876
7920
  let r = Lu(t[e].jsonPath || "");
@@ -7880,13 +7924,13 @@ function Ju(e, t) {
7880
7924
  }
7881
7925
  //#endregion
7882
7926
  //#region src/core/tools/dataOps.ts
7883
- function Yu(e, t) {
7927
+ function Qu(e, t) {
7884
7928
  if (!e) return null;
7885
7929
  let n = (t ? Uo(e, t) : e)?.shape;
7886
7930
  return n && typeof n == "object" ? Object.keys(n) : null;
7887
7931
  }
7888
- var Xu = (e) => e && e.length ? `(可用字段:${e.slice(0, 12).join(", ")}${e.length > 12 ? " …" : ""})` : "", Zu = (e) => /[.[]/.test(e) ? e.replace(/[.[][^.[]*$/, "") : "";
7889
- function Qu(e) {
7932
+ var $u = (e) => e && e.length ? `(可用字段:${e.slice(0, 12).join(", ")}${e.length > 12 ? " …" : ""})` : "", ed = (e) => /[.[]/.test(e) ? e.replace(/[.[][^.[]*$/, "") : "";
7933
+ function td(e) {
7890
7934
  let { schema: t, allowKeys: n, value: r, bindRef: i } = e, a = [];
7891
7935
  if (n) {
7892
7936
  if (typeof r != "object" || !r || Array.isArray(r)) return {
@@ -7911,7 +7955,7 @@ function Qu(e) {
7911
7955
  error: Z({
7912
7956
  code: "SCHEMA_STRIP",
7913
7957
  message: `字段 ${r} 不在 schema 声明内,写入被拒绝(防静默丢失)`,
7914
- hint: `该数据结构不支持这些字段;请只用 schema 声明的字段,或在 data.schema 中声明后重试${Xu(Yu(t, ""))}`,
7958
+ hint: `该数据结构不支持这些字段;请只用 schema 声明的字段,或在 data.schema 中声明后重试${$u(Qu(t, ""))}`,
7915
7959
  path: r,
7916
7960
  details: { stripped: [r] }
7917
7961
  }),
@@ -7931,7 +7975,7 @@ function Qu(e) {
7931
7975
  error: Z({
7932
7976
  code: "SCHEMA_STRIP",
7933
7977
  message: `字段 ${c.join(", ")} 不在 schema 声明内,写入被拒绝(防静默丢失)`,
7934
- hint: `该数据结构不支持这些字段;请只用 schema 声明的字段,或在 data.schema 中声明后重试${Xu(Yu(t, Zu(String(c[0]))))}`,
7978
+ hint: `该数据结构不支持这些字段;请只用 schema 声明的字段,或在 data.schema 中声明后重试${$u(Qu(t, ed(String(c[0]))))}`,
7935
7979
  path: c[0],
7936
7980
  details: { stripped: c }
7937
7981
  }),
@@ -7970,7 +8014,7 @@ function Qu(e) {
7970
8014
  notices: a
7971
8015
  };
7972
8016
  }
7973
- function $u(e) {
8017
+ function nd(e) {
7974
8018
  let { schema: t, bindRef: n, clone: r, patches: i, schemaErrorMode: a = "zod", appendCaptures: o, moveCaptures: s } = e, c = [], l = (t) => {
7975
8019
  let n = Q(r, t);
7976
8020
  return n === void 0 ? e.valueAt?.(t) : n;
@@ -8279,14 +8323,14 @@ function $u(e) {
8279
8323
  notices: c
8280
8324
  };
8281
8325
  }
8282
- function ed(e) {
8283
- let { bindRef: t, schema: n, allowKeys: r, snapshots: i, maxSnapshots: a, audit: o, dryRun: s, op: c = "set", protectedCtx: l, snapshotLabel: u } = e, d = e.value, f = e.internalAfterWrite ? Vs(t) : null, p = nd(d);
8326
+ function rd(e) {
8327
+ let { bindRef: t, schema: n, allowKeys: r, snapshots: i, maxSnapshots: a, audit: o, dryRun: s, op: c = "set", protectedCtx: l, snapshotLabel: u } = e, d = e.value, f = e.internalAfterWrite ? Vs(t) : null, p = ad(d);
8284
8328
  if (p) return {
8285
8329
  ok: !1,
8286
- error: rd(p)
8330
+ error: od(p)
8287
8331
  };
8288
8332
  if (l) {
8289
- let e = Ku({
8333
+ let e = Yu({
8290
8334
  value: d,
8291
8335
  ctx: l,
8292
8336
  mergeMode: !!r
@@ -8297,7 +8341,7 @@ function ed(e) {
8297
8341
  };
8298
8342
  d = e.value;
8299
8343
  }
8300
- let m = Qu({
8344
+ let m = td({
8301
8345
  schema: n,
8302
8346
  allowKeys: r,
8303
8347
  value: d,
@@ -8334,14 +8378,14 @@ function ed(e) {
8334
8378
  op: c,
8335
8379
  value: h,
8336
8380
  timestamp: Date.now()
8337
- }), e.onWrite?.(), e.internalAfterWrite?.(t, f), {
8381
+ }), e.onWrite?.(), e.internalAfterWrite?.(t, f), Hu(l), {
8338
8382
  ok: !0,
8339
8383
  hash: e.hashFn ? e.hashFn() : qs(t),
8340
8384
  data: h,
8341
8385
  notices: m.notices
8342
8386
  };
8343
8387
  }
8344
- function td(e) {
8388
+ function id(e) {
8345
8389
  let { bindRef: t, patches: n, schema: r, allowKeys: i, snapshots: a, maxSnapshots: o, markDataDirty: s, schemaErrorMode: c = "zod", snapshotLabel: l, dryRun: u, protectedCtx: d } = e, f = e.internalAfterWrite ? Vs(t) : null, p = Vs(t), m = [], h = [], g = [], _ = [], v = (e, t) => {
8346
8390
  (e === "set" || e === "merge") && _.push({
8347
8391
  jp: t,
@@ -8363,7 +8407,7 @@ function td(e) {
8363
8407
  error: Z({
8364
8408
  code: "PATH_DENIED",
8365
8409
  message: `patches[${e}] @ "${a}" 不在 schema 声明字段内`,
8366
- hint: `仅 schema 声明的 key 可写${Xu(Yu(r, Zu(a)))}`
8410
+ hint: `仅 schema 声明的 key 可写${$u(Qu(r, ed(a)))}`
8367
8411
  })
8368
8412
  };
8369
8413
  let o = t.op ?? "set", s;
@@ -8382,10 +8426,10 @@ function td(e) {
8382
8426
  error: oi(`patches[${e}]`, t.value, n.parseError)
8383
8427
  };
8384
8428
  if (s = n.parsed, o !== "move") {
8385
- let t = nd(s);
8429
+ let t = ad(s);
8386
8430
  if (t) return {
8387
8431
  ok: !1,
8388
- error: rd(t, `patches[${e}] @ "${a}"`)
8432
+ error: od(t, `patches[${e}] @ "${a}"`)
8389
8433
  };
8390
8434
  }
8391
8435
  if (o === "move" && typeof s == "string" && !Vo(s, r, i)) return {
@@ -8393,7 +8437,7 @@ function td(e) {
8393
8437
  error: Z({
8394
8438
  code: "PATH_DENIED",
8395
8439
  message: `patches[${e}] move 目标 "${s}" 不在 schema 声明字段内`,
8396
- hint: `move 的 value(目标路径)也须在 schema 声明字段内${Xu(Yu(r, Zu(String(s))))}`
8440
+ hint: `move 的 value(目标路径)也须在 schema 声明字段内${$u(Qu(r, ed(String(s))))}`
8397
8441
  })
8398
8442
  };
8399
8443
  }
@@ -8421,7 +8465,7 @@ function td(e) {
8421
8465
  });
8422
8466
  }
8423
8467
  if (d) {
8424
- let e = qu({
8468
+ let e = Xu({
8425
8469
  patches: n,
8426
8470
  clone: p,
8427
8471
  ctx: d
@@ -8431,7 +8475,7 @@ function td(e) {
8431
8475
  error: e.error
8432
8476
  };
8433
8477
  }
8434
- let y = d ? new Set([...d.resourcesByPath.keys()].map((e) => e.split(".").pop()).filter(Boolean)) : void 0, b = $u({
8478
+ let y = d ? new Set([...d.resourcesByPath.keys()].map((e) => e.split(".").pop()).filter(Boolean)) : void 0, b = nd({
8435
8479
  schema: r,
8436
8480
  bindRef: t,
8437
8481
  clone: p,
@@ -8473,14 +8517,14 @@ function td(e) {
8473
8517
  let n = e.jp ? Q(t, e.jp) : t;
8474
8518
  typeof n == "string" && typeof e.str == "string" && zs(t, e.jp, n + e.str);
8475
8519
  }
8476
- return e.internalAfterWrite?.(t, f), s?.(), {
8520
+ return e.internalAfterWrite?.(t, f), Hu(d), s?.(), {
8477
8521
  ok: !0,
8478
8522
  applied: m,
8479
8523
  clone: p,
8480
8524
  notices: b.notices
8481
8525
  };
8482
8526
  }
8483
- function nd(e) {
8527
+ function ad(e) {
8484
8528
  let t = /^<[A-Za-z_][\w.-]*\s[\d.]+[KMG]?B>$/, n = (e) => {
8485
8529
  if (typeof e == "string") return e.includes("<subtree ") || t.test(e) ? e.slice(0, 60) : null;
8486
8530
  if (Array.isArray(e)) {
@@ -8498,30 +8542,30 @@ function nd(e) {
8498
8542
  };
8499
8543
  return n(e);
8500
8544
  }
8501
- var rd = (e, t) => Z({
8545
+ var od = (e, t) => Z({
8502
8546
  code: "PLACEHOLDER_LEAK",
8503
8547
  path: t || void 0,
8504
8548
  message: `写入值包含摘要占位符 "${e}"(read/query 为省上下文返回的体积占位,非真实数据),已拒绝写入`,
8505
8549
  hint: "占位符子树的真实内容需先窄读获取:read({jsonPath:\"<该子树路径>\"}) 结果根豁免返回全文;聚焦该区域可用 set_focus。基于真实值重新构造写入内容"
8506
8550
  });
8507
- function id(e) {
8551
+ function sd(e) {
8508
8552
  return e < 1024 ? `${e}B` : e < 1024 * 1024 ? `${(e / 1024).toFixed(1)}KB` : `${(e / (1024 * 1024)).toFixed(1)}MB`;
8509
8553
  }
8510
- var ad = 3072;
8511
- function od(e) {
8554
+ var cd = 3072;
8555
+ function ld(e) {
8512
8556
  return typeof e == "string" ? e.length + 2 : typeof e == "number" || typeof e == "boolean" ? 8 : 4;
8513
8557
  }
8514
- function sd(e, t, n, r, i) {
8558
+ function ud(e, t, n, r, i) {
8515
8559
  if (!t || e == null) return e;
8516
- let a = new Set(n.map((e) => e.field)), o = r, s = ad, c = i?.rootExempt ?? !1, l = i?.rootPath ?? "", u = i?.fullTextPrefixes ?? [], d = Vs(e), f = i?.onSummarized, p = (e) => u.some((t) => t && (e === t || e.startsWith(t + ".") || e.startsWith(t + "["))), m = (e, t) => {
8560
+ let a = new Set(n.map((e) => e.field)), o = r, s = cd, c = i?.rootExempt ?? !1, l = i?.rootPath ?? "", u = i?.fullTextPrefixes ?? [], d = Vs(e), f = i?.onSummarized, p = (e) => u.some((t) => t && (e === t || e.startsWith(t + ".") || e.startsWith(t + "["))), m = (e, t) => {
8517
8561
  let n = "#" + String(qs(e)).slice(0, 8);
8518
- if (Array.isArray(e)) return `<subtree ${id(t)} children:${e.length} ${n}>`;
8562
+ if (Array.isArray(e)) return `<subtree ${sd(t)} children:${e.length} ${n}>`;
8519
8563
  let r = Object.keys(e), i = r.slice(0, 6).join(",") + (r.length > 6 ? ",…" : "");
8520
- return `<subtree ${id(t)} keys:[${i}] ${n}>`;
8564
+ return `<subtree ${sd(t)} keys:[${i}] ${n}>`;
8521
8565
  }, h = (e, t, n) => {
8522
8566
  if (typeof e != "object" || !e) return {
8523
8567
  node: e,
8524
- eff: od(e)
8568
+ eff: ld(e)
8525
8569
  };
8526
8570
  if (p(t)) return {
8527
8571
  node: e,
@@ -8544,7 +8588,7 @@ function sd(e, t, n, r, i) {
8544
8588
  let r = 2;
8545
8589
  for (let n of Object.keys(e)) {
8546
8590
  let i = e[n], s = t ? `${t}.${n}` : n;
8547
- if (typeof i == "string" && a.has(n) && i.length >= o && !p(s)) e[n] = `<${n} ${id(i.length)}>`, f?.(s), r += e[n].length + n.length + 2;
8591
+ if (typeof i == "string" && a.has(n) && i.length >= o && !p(s)) e[n] = `<${n} ${sd(i.length)}>`, f?.(s), r += e[n].length + n.length + 2;
8548
8592
  else {
8549
8593
  let t = h(i, s, !1);
8550
8594
  e[n] = t.node, r += t.eff + n.length + 2;
@@ -8560,23 +8604,23 @@ function sd(e, t, n, r, i) {
8560
8604
  };
8561
8605
  return h(d, l, !0).node;
8562
8606
  }
8563
- var cd = 0;
8564
- function ld() {
8565
- return cd++, "c_" + Math.random().toString(36).slice(2, 8) + cd.toString(36);
8607
+ var dd = 0;
8608
+ function fd() {
8609
+ return dd++, "c_" + Math.random().toString(36).slice(2, 8) + dd.toString(36);
8566
8610
  }
8567
- function ud(e, t) {
8611
+ function pd(e, t) {
8568
8612
  if (!(!e || typeof e != "object")) for (let n of t) {
8569
8613
  let t = Q(e, n);
8570
- if (Array.isArray(t)) for (let e of t) e && typeof e == "object" && !("__pgId" in e) && (e.__pgId = ld());
8614
+ if (Array.isArray(t)) for (let e of t) e && typeof e == "object" && !("__pgId" in e) && (e.__pgId = fd());
8571
8615
  }
8572
8616
  }
8573
- function dd(e) {
8617
+ function md(e) {
8574
8618
  (function e(t) {
8575
8619
  if (Array.isArray(t)) t.forEach(e);
8576
8620
  else if (t && typeof t == "object") for (let n of Object.keys(t)) n.startsWith("__pg") ? delete t[n] : e(t[n]);
8577
8621
  })(e);
8578
8622
  }
8579
- function fd(e, n = {}) {
8623
+ function hd(e, n = {}) {
8580
8624
  let i = n.pgIdPaths ?? [], a = n.sandboxRunner ?? _a, o = i.length ? (e, t) => {
8581
8625
  if (t && typeof t == "object") for (let n of i) {
8582
8626
  let r = Q(t, n), i = Q(e, n);
@@ -8603,7 +8647,7 @@ function fd(e, n = {}) {
8603
8647
  t && n && typeof n == "object" && !("__pgId" in n) && (n.__pgId = t, o.add(e));
8604
8648
  }
8605
8649
  }
8606
- ud(e, i);
8650
+ pd(e, i);
8607
8651
  } : void 0, s = i.length ? ms(e.schema, i).schema : e.schema, c = e.bind, l = e.description ?? "主数据对象", u = Bo(s), d = /* @__PURE__ */ new Map(), f = n.vfsStore ? new Vu(n.vfsStore) : void 0;
8608
8652
  function p(e) {
8609
8653
  if (d.clear(), e) for (let t of e) {
@@ -8619,6 +8663,7 @@ function fd(e, n = {}) {
8619
8663
  resourcesByPath: d,
8620
8664
  resourceStore: f,
8621
8665
  getBind: () => c,
8666
+ pendingReanchors: [],
8622
8667
  isFieldRequired: (e) => {
8623
8668
  let t = e.split("."), n = t[t.length - 1], r = (t.length > 1 ? Uo(s, t.slice(0, -1).join(".")) : s)?.shape?.[n];
8624
8669
  return !!r && typeof r.isOptional == "function" && !r.isOptional();
@@ -8888,7 +8933,7 @@ function fd(e, n = {}) {
8888
8933
  details: { expr: e }
8889
8934
  });
8890
8935
  }
8891
- let r = n ?? 50, s = t.slice(0, r), c = s.map((e) => `{"path":${JSON.stringify(e.path)},"index":${e.index === void 0 ? "null" : e.index},"value":${$(sd(e.value, i === "", A, k, {
8936
+ let r = n ?? 50, s = t.slice(0, r), c = s.map((e) => `{"path":${JSON.stringify(e.path)},"index":${e.index === void 0 ? "null" : e.index},"value":${$(ud(e.value, i === "", A, k, {
8892
8937
  rootExempt: !1,
8893
8938
  rootPath: String(e.path ?? ""),
8894
8939
  fullTextPrefixes: o,
@@ -8993,7 +9038,7 @@ function fd(e, n = {}) {
8993
9038
  if (l) {
8994
9039
  let e = await re();
8995
9040
  try {
8996
- let e = td({
9041
+ let e = id({
8997
9042
  bindRef: c,
8998
9043
  patches: [{
8999
9044
  op: "set",
@@ -9027,7 +9072,7 @@ function fd(e, n = {}) {
9027
9072
  });
9028
9073
  let e = await re();
9029
9074
  try {
9030
- let e = td({
9075
+ let e = id({
9031
9076
  bindRef: c,
9032
9077
  patches: t.patches,
9033
9078
  schema: s,
@@ -9049,10 +9094,10 @@ function fd(e, n = {}) {
9049
9094
  e.release();
9050
9095
  }
9051
9096
  }
9052
- let n = t, r = nd(n);
9053
- if (r) return rd(r);
9097
+ let n = t, r = ad(n);
9098
+ if (r) return od(r);
9054
9099
  if (m) {
9055
- let e = Ku({
9100
+ let e = Yu({
9056
9101
  value: n,
9057
9102
  ctx: m
9058
9103
  });
@@ -9066,7 +9111,7 @@ function fd(e, n = {}) {
9066
9111
  });
9067
9112
  let a = o ? Vs(c) : null, d = await re();
9068
9113
  try {
9069
- let e = Qu({
9114
+ let e = td({
9070
9115
  schema: s,
9071
9116
  allowKeys: u,
9072
9117
  value: n,
@@ -9115,12 +9160,12 @@ function fd(e, n = {}) {
9115
9160
  e && (a = ns(a, e));
9116
9161
  }
9117
9162
  let o = a;
9118
- return m && (o = Hu({
9163
+ return m && (o = Uu({
9119
9164
  jp: i,
9120
9165
  resolved: o,
9121
9166
  resourcesByPath: m.resourcesByPath,
9122
9167
  resourceStore: m.resourceStore
9123
- })), n && n.length && (o = Ws(o, n)), r != null && (o = Gs(o, r)), o = sd(o, d === "", A, k, {
9168
+ })), n && n.length && (o = Ws(o, n)), r != null && (o = Gs(o, r)), o = ud(o, d === "", A, k, {
9124
9169
  rootExempt: !0,
9125
9170
  rootPath: i,
9126
9171
  fullTextPrefixes: f,
@@ -9135,7 +9180,7 @@ function fd(e, n = {}) {
9135
9180
  message: `jsonPath "${h}" 含非法段(__proto__/constructor/prototype)`,
9136
9181
  hint: "使用正常属性路径,如 components.0.text(数组索引数字)"
9137
9182
  });
9138
- let g = (e, t) => Yu(s, e) ?? (t && typeof t == "object" && !Array.isArray(t) ? Object.keys(t) : []);
9183
+ let g = (e, t) => Qu(s, e) ?? (t && typeof t == "object" && !Array.isArray(t) ? Object.keys(t) : []);
9139
9184
  if (!Vo(h, s, u)) {
9140
9185
  let e = /[.[]/.test(h) ? h.replace(/[.[][^.[]*$/, "") : "", t = g(e, e ? Q(c, e) : c), n = t.length ? `;父级 "${e || "(root)"}" 的可用字段:${t.slice(0, 12).join(", ")}${t.length > 12 ? " …" : ""}` : "";
9141
9186
  return Z({
@@ -9163,12 +9208,12 @@ function fd(e, n = {}) {
9163
9208
  e && (_ = ns(_, e));
9164
9209
  }
9165
9210
  let v = _;
9166
- m && (v = Hu({
9211
+ m && (v = Uu({
9167
9212
  jp: h,
9168
9213
  resolved: v,
9169
9214
  resourcesByPath: m.resourcesByPath,
9170
9215
  resourceStore: m.resourceStore
9171
- })), w(p, d), n && n.length && (v = Ws(v, n)), r != null && (v = Gs(v, r)), v = sd(v, d === "", A, k, {
9216
+ })), w(p, d), n && n.length && (v = Ws(v, n)), r != null && (v = Gs(v, r)), v = ud(v, d === "", A, k, {
9172
9217
  rootExempt: !0,
9173
9218
  rootPath: h,
9174
9219
  fullTextPrefixes: f,
@@ -9255,7 +9300,7 @@ function fd(e, n = {}) {
9255
9300
  op: t.op ?? "set",
9256
9301
  jsonPath: t.jsonPath || "",
9257
9302
  value: p
9258
- }], l = td({
9303
+ }], l = id({
9259
9304
  bindRef: c,
9260
9305
  patches: i,
9261
9306
  schema: s,
@@ -9277,13 +9322,13 @@ function fd(e, n = {}) {
9277
9322
  timestamp: Date.now()
9278
9323
  });
9279
9324
  let f = ie(d);
9280
- return dd(l.clone), `已 write(edit) 主数据(${l.applied.length} 个 patch)。当前值:${$(l.clone, 600)} (新 hash=${f})`;
9325
+ return md(l.clone), `已 write(edit) 主数据(${l.applied.length} 个 patch)。当前值:${$(l.clone, 600)} (新 hash=${f})`;
9281
9326
  }
9282
9327
  let r = Us(p);
9283
9328
  if (r.parseError) return oi("", p, r.parseError);
9284
9329
  let l = await N("set", e, p, _);
9285
9330
  if (l !== null) return l;
9286
- let v = ed({
9331
+ let v = rd({
9287
9332
  bindRef: c,
9288
9333
  value: r.parsed,
9289
9334
  schema: s,
@@ -9302,7 +9347,7 @@ function fd(e, n = {}) {
9302
9347
  let y = v.hash ?? O();
9303
9348
  w(y, d);
9304
9349
  let b = i.length ? Vs(v.data) : v.data;
9305
- return dd(b), `已 write(set) 主数据 = ${$(b, 600)} (新 hash=${y})${u ? "(白名单模式:仅更新 schema 声明字段,未声明字段保留)" : ""}`;
9350
+ return md(b), `已 write(set) 主数据 = ${$(b, 600)} (新 hash=${y})${u ? "(白名单模式:仅更新 schema 声明字段,未声明字段保留)" : ""}`;
9306
9351
  } finally {
9307
9352
  _.release();
9308
9353
  }
@@ -9426,7 +9471,7 @@ function fd(e, n = {}) {
9426
9471
  try {
9427
9472
  let n = await N("set", D ? C(r) : void 0, d, f);
9428
9473
  if (n !== null) return n;
9429
- let i = ed({
9474
+ let i = rd({
9430
9475
  bindRef: c,
9431
9476
  value: d,
9432
9477
  schema: s,
@@ -9594,7 +9639,7 @@ function fd(e, n = {}) {
9594
9639
  }
9595
9640
  //#endregion
9596
9641
  //#region src/core/tools/htmlValidate.ts
9597
- var pd = /* @__PURE__ */ new Set([
9642
+ var gd = /* @__PURE__ */ new Set([
9598
9643
  "area",
9599
9644
  "base",
9600
9645
  "br",
@@ -9609,8 +9654,8 @@ var pd = /* @__PURE__ */ new Set([
9609
9654
  "source",
9610
9655
  "track",
9611
9656
  "wbr"
9612
- ]), md = /* @__PURE__ */ new Set(["script", "style"]);
9613
- function hd(e) {
9657
+ ]), _d = /* @__PURE__ */ new Set(["script", "style"]);
9658
+ function vd(e) {
9614
9659
  let t = [], n = e.length;
9615
9660
  if (!e.trim()) return t;
9616
9661
  let r = [0];
@@ -9687,8 +9732,8 @@ function hd(e) {
9687
9732
  }
9688
9733
  continue;
9689
9734
  }
9690
- if (!(pd.has(p) || m)) {
9691
- if (md.has(p)) {
9735
+ if (!(gd.has(p) || m)) {
9736
+ if (_d.has(p)) {
9692
9737
  let n = RegExp(`</${p}\\s*>`, "i").exec(e.slice(o));
9693
9738
  if (!n) {
9694
9739
  t.push({
@@ -9717,8 +9762,8 @@ function hd(e) {
9717
9762
  }
9718
9763
  //#endregion
9719
9764
  //#region src/core/sdk/codeAssetMiddleware.ts
9720
- var gd = "__pgTouched", _d = "__pgGenSnapshot", vd = "__pgFinalText", yd = "__pgCodeHashes", bd = "__pgKeepExternal", xd = "__pgNotes", Sd = 200;
9721
- function Cd(e) {
9765
+ var yd = "__pgTouched", bd = "__pgGenSnapshot", xd = "__pgFinalText", Sd = "__pgCodeHashes", Cd = "__pgKeepExternal", wd = "__pgNotes", Td = 200;
9766
+ function Ed(e) {
9722
9767
  let t = [];
9723
9768
  for (let n of e.split("\n")) {
9724
9769
  let e = n.match(/^\s*[-*]?\s*\[note\]\s*(.*)$/i);
@@ -9726,27 +9771,27 @@ function Cd(e) {
9726
9771
  }
9727
9772
  return [...new Set(t)];
9728
9773
  }
9729
- function wd(e, t) {
9730
- let n = Array.isArray(e[xd]) ? e[xd].filter((e) => typeof e == "string") : [];
9731
- e[xd] = [.../* @__PURE__ */ new Set([...n, ...t])].map((e) => e.length > Sd ? e.slice(0, Sd) + "…" : e).slice(-5);
9774
+ function Dd(e, t) {
9775
+ let n = Array.isArray(e[wd]) ? e[wd].filter((e) => typeof e == "string") : [];
9776
+ e[wd] = [.../* @__PURE__ */ new Set([...n, ...t])].map((e) => e.length > Td ? e.slice(0, Td) + "…" : e).slice(-5);
9732
9777
  }
9733
- function Td(e) {
9778
+ function Od(e) {
9734
9779
  let t = 5381;
9735
9780
  for (let n = 0; n < e.length; n++) t = (t << 5) + t + e.charCodeAt(n) | 0;
9736
9781
  return (t >>> 0).toString(16);
9737
9782
  }
9738
- function Ed(e, t) {
9783
+ function kd(e, t) {
9739
9784
  let n = [];
9740
- return Od(e, t, (e) => {
9785
+ return jd(e, t, (e) => {
9741
9786
  typeof e.name == "string" && e.name && n.push(e.name);
9742
9787
  }), n;
9743
9788
  }
9744
- function Dd(e, t) {
9789
+ function Ad(e, t) {
9745
9790
  if (!e.startsWith(t)) return null;
9746
9791
  let n = e.slice(t.length), r = n.lastIndexOf(".");
9747
9792
  return (r > 0 ? n.slice(0, r) : r === 0 ? "" : n) || null;
9748
9793
  }
9749
- function Od(e, t, n) {
9794
+ function jd(e, t, n) {
9750
9795
  if (!(!e || typeof e != "object")) for (let r of t) {
9751
9796
  let t = Q(e, r);
9752
9797
  if (Array.isArray(t)) for (let e = 0; e < t.length; e++) {
@@ -9755,7 +9800,7 @@ function Od(e, t, n) {
9755
9800
  }
9756
9801
  }
9757
9802
  }
9758
- function kd(e, t, n) {
9803
+ function Md(e, t, n) {
9759
9804
  let r = /* @__PURE__ */ new Set();
9760
9805
  if (!e || typeof e != "object") return r;
9761
9806
  for (let i of t) {
@@ -9774,20 +9819,20 @@ function kd(e, t, n) {
9774
9819
  }
9775
9820
  return r;
9776
9821
  }
9777
- function Ad(e) {
9822
+ function Nd(e) {
9778
9823
  let { writablePaths: t, codeVfsPrefix: n, ext: r, codeField: i = "code", onWarning: a, getController: o, vfsStore: s, craftNotes: c = !0 } = e, l = s, u = l.__pgLastCheckout ??= /* @__PURE__ */ new Map(), d = l.__pgPendingRetry ??= /* @__PURE__ */ new Set(), f = l.__pgTouchGen ??= /* @__PURE__ */ new Map();
9779
9824
  return {
9780
9825
  name: "code-asset-checkout-commit",
9781
9826
  beforeAgent: (e) => {
9782
9827
  let c = o()?.get?.().bind;
9783
- c && ud(c, t);
9828
+ c && pd(c, t);
9784
9829
  let l = 0, p = 0, m = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Map();
9785
- if (Od(c, t, (e) => {
9830
+ if (jd(c, t, (e) => {
9786
9831
  l++;
9787
9832
  let t = Q(e, i);
9788
9833
  if (typeof t == "string") {
9789
9834
  p++;
9790
- let i = e.__pgId, a = Td(t);
9835
+ let i = e.__pgId, a = Od(t);
9791
9836
  m.set(i, a);
9792
9837
  let o = `${n}${i}.${r}`, c = s.files[o], l = u.get(i);
9793
9838
  if (c && typeof c.content == "string" && c.content !== t && l === a) {
@@ -9813,24 +9858,24 @@ function Ad(e) {
9813
9858
  }
9814
9859
  return {
9815
9860
  files: s.files,
9816
- [gd]: /* @__PURE__ */ new Set(),
9817
- [vd]: { text: "" },
9818
- [yd]: m,
9819
- [bd]: [],
9820
- [_d]: h
9861
+ [yd]: /* @__PURE__ */ new Set(),
9862
+ [xd]: { text: "" },
9863
+ [Sd]: m,
9864
+ [Cd]: [],
9865
+ [bd]: h
9821
9866
  };
9822
9867
  },
9823
9868
  wrapModelCall: async (e, t) => {
9824
- let n = await t(e), r = e.state[vd];
9869
+ let n = await t(e), r = e.state[xd];
9825
9870
  return r && !(n.toolCalls && n.toolCalls.length) && typeof n.content == "string" && n.content && (r.text = n.content), n;
9826
9871
  },
9827
9872
  augmentPrompt: () => {
9828
9873
  let e = o()?.get?.().bind, i = [], a = 0;
9829
- if (Od(e, t, (e, t, o) => {
9874
+ if (jd(e, t, (e, t, o) => {
9830
9875
  a++;
9831
9876
  let l = typeof e.name == "string" && e.name ? e.name : "", u = l ? `${l} [${o}]` : `(未命名 [${o}])`, d = `${n}${e.__pgId}.${r}`, f = !!s.files[d];
9832
9877
  if (i.push(`- ${u} → ${d}${f ? "" : "(尚未检出,先 vfs_write 创建)"}`), c) {
9833
- let t = Array.isArray(e[xd]) ? e[xd].filter((e) => typeof e == "string") : [];
9878
+ let t = Array.isArray(e[wd]) ? e[wd].filter((e) => typeof e == "string") : [];
9834
9879
  if (t.length) {
9835
9880
  let e = t[t.length - 1];
9836
9881
  i.push(` 📝 笔记×${t.length}(最近):${e.length > 120 ? e.slice(0, 120) + "…" : e}`);
@@ -9852,9 +9897,9 @@ function Ad(e) {
9852
9897
  if (c) {
9853
9898
  let i = e.state.focuses;
9854
9899
  if (i && i.length) {
9855
- let e = kd(o()?.get?.().bind, t, i);
9900
+ let e = Md(o()?.get?.().bind, t, i);
9856
9901
  if (e.size) {
9857
- let t = Dd(s, n);
9902
+ let t = Ad(s, n);
9858
9903
  if (t && !e.has(t)) return {
9859
9904
  content: `PATH_DENIED · vfs 越界:当前聚焦代码文件 [${[...e].map((e) => `${n}${e}.${r}`).join(", ")}],你要改的 "${s}" 不在其中。请只改焦点组件的代码文件;如需改其他组件,请在收口回复中说明需先取消聚焦(焦点由主会话/用户管理,你无 focus 工具)后重试。`,
9860
9905
  status: "error"
@@ -9864,9 +9909,9 @@ function Ad(e) {
9864
9909
  }
9865
9910
  let l = await i(e);
9866
9911
  if (c) {
9867
- let t = e.state[gd];
9912
+ let t = e.state[yd];
9868
9913
  t && t.add(s);
9869
- let r = e.state[_d], i = Dd(s, n);
9914
+ let r = e.state[bd], i = Ad(s, n);
9870
9915
  if (r && i && !r.has(i)) {
9871
9916
  let e = (f.get(i) ?? 0) + 1;
9872
9917
  f.set(i, e), r.set(i, e);
@@ -9877,15 +9922,15 @@ function Ad(e) {
9877
9922
  afterAgent: (e) => {
9878
9923
  let a = o(), l = a?.get?.().bind;
9879
9924
  if (!l) return;
9880
- let u = e[gd] ?? /* @__PURE__ */ new Set();
9925
+ let u = e[yd] ?? /* @__PURE__ */ new Set();
9881
9926
  if (u.size) {
9882
- let o = e[yd] ?? /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
9883
- Od(l, t, (t) => {
9927
+ let o = e[Sd] ?? /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
9928
+ jd(l, t, (t) => {
9884
9929
  let a = t.__pgId;
9885
9930
  c.add(a);
9886
9931
  let l = `${n}${a}.${r}`;
9887
9932
  if (!u.has(l) && !d.has(l)) return;
9888
- let p = e[_d]?.get(a);
9933
+ let p = e[bd]?.get(a);
9889
9934
  if (p !== void 0 && f.get(a) !== p) {
9890
9935
  console.warn(`[page-agent-sdk][code-asset] 组件 ${t.name ?? a}(${l})已有更新的委派接管,跳过本次旧代 commit(不排队不重放;新委派的 commit 为准)`);
9891
9936
  return;
@@ -9896,14 +9941,14 @@ function Ad(e) {
9896
9941
  let r = o.get(a);
9897
9942
  if (r !== void 0) {
9898
9943
  let n = Q(t, i);
9899
- if (typeof n != "string" || Td(n) !== r) {
9944
+ if (typeof n != "string" || Od(n) !== r) {
9900
9945
  console.warn(`[page-agent-sdk][code-asset] 组件 ${t.name ?? a}(${l})在修改期间被外部更新,已保留外部版本(keep_external),本次子 agent 修改未提交`);
9901
- let n = e[bd], r = String(t.name ?? a);
9902
- Array.isArray(n) ? n.push(r) : e[bd] = [r];
9946
+ let n = e[Cd], r = String(t.name ?? a);
9947
+ Array.isArray(n) ? n.push(r) : e[Cd] = [r];
9903
9948
  return;
9904
9949
  }
9905
9950
  }
9906
- let s = hd(n.content);
9951
+ let s = vd(n.content);
9907
9952
  if (s.length) {
9908
9953
  console.warn(`[page-agent-sdk][code-asset] 跳过 commit 未通过校验的半成品(可能 abort/timeout 未跑完 verify):${l} - ${s[0].message}(${s[0].code})`);
9909
9954
  return;
@@ -9915,22 +9960,22 @@ function Ad(e) {
9915
9960
  }
9916
9961
  });
9917
9962
  for (let e of u) {
9918
- let t = Dd(e, n);
9963
+ let t = Ad(e, n);
9919
9964
  t && !c.has(t) && (console.warn(`[page-agent-sdk][code-asset] 组件 ${t}(${e})已被外部删除,放弃 commit 并清理 vfs 工作副本(不复活组件)`), delete s.files[e]);
9920
9965
  }
9921
9966
  a?.markDataDirty?.(), a?.recomputeBaseline?.();
9922
9967
  }
9923
9968
  if (!c) return;
9924
- let p = Cd(e[vd]?.text ?? "");
9969
+ let p = Ed(e[xd]?.text ?? "");
9925
9970
  if (!p.length) return;
9926
9971
  let m = [];
9927
- if (Od(l, t, (e) => {
9928
- (u.size === 0 || u.has(`${n}${e.__pgId}.${r}`)) && m.push(e);
9972
+ if (jd(l, t, (e) => {
9973
+ typeof Q(e, i) == "string" && (u.size === 0 || u.has(`${n}${e.__pgId}.${r}`)) && m.push(e);
9929
9974
  }), !m.length) return;
9930
9975
  let h = !1;
9931
9976
  for (let e of p) {
9932
9977
  let t = m.length === 1 ? m[0] : m.find((t) => typeof t.name == "string" && !!t.name && e.includes(t.name));
9933
- t && (wd(t, [e]), h = !0);
9978
+ t && (Dd(t, [e]), h = !0);
9934
9979
  }
9935
9980
  h && a?.markDataDirty?.();
9936
9981
  }
@@ -9938,7 +9983,7 @@ function Ad(e) {
9938
9983
  }
9939
9984
  //#endregion
9940
9985
  //#region src/core/sdk/componentLock.ts
9941
- function jd() {
9986
+ function Pd() {
9942
9987
  let e = /* @__PURE__ */ new Map();
9943
9988
  return {
9944
9989
  async acquire(t, n) {
@@ -9977,7 +10022,7 @@ function jd() {
9977
10022
  }
9978
10023
  };
9979
10024
  }
9980
- function Md(e, t) {
10025
+ function Fd(e, t) {
9981
10026
  if (Array.isArray(e.components) && e.components.length) {
9982
10027
  let n = new Set(t), r = [...new Set(e.components.filter((e) => typeof e == "string" && e && n.has(e)))];
9983
10028
  if (r.length) return {
@@ -9994,12 +10039,12 @@ function Md(e, t) {
9994
10039
  via: "none"
9995
10040
  };
9996
10041
  }
9997
- function Nd(e, t, n) {
10042
+ function Id(e, t, n) {
9998
10043
  let r = new Set(n);
9999
10044
  if (!r.size || !e || typeof e != "object") return [];
10000
10045
  let i = [];
10001
10046
  for (let n of t) {
10002
- let t = Pd(e, n);
10047
+ let t = Ld(e, n);
10003
10048
  if (Array.isArray(t)) for (let e = 0; e < t.length; e++) {
10004
10049
  let a = t[e];
10005
10050
  a && typeof a == "object" && typeof a.name == "string" && r.has(a.name) && i.push(`${n}.${e}`);
@@ -10007,7 +10052,7 @@ function Nd(e, t, n) {
10007
10052
  }
10008
10053
  return i;
10009
10054
  }
10010
- function Pd(e, t) {
10055
+ function Ld(e, t) {
10011
10056
  let n = e;
10012
10057
  for (let e of t.split(".")) {
10013
10058
  if (!n || typeof n != "object") return;
@@ -10015,26 +10060,26 @@ function Pd(e, t) {
10015
10060
  }
10016
10061
  return n;
10017
10062
  }
10018
- function Fd(e, t) {
10063
+ function Rd(e, t) {
10019
10064
  return t.some((t) => e === t || e.startsWith(t + "."));
10020
10065
  }
10021
- function Id(e, t) {
10066
+ function zd(e, t) {
10022
10067
  let n = [];
10023
10068
  for (let { writablePaths: r, codeField: i } of t) for (let t of r) {
10024
- let r = Pd(e, t);
10069
+ let r = Ld(e, t);
10025
10070
  if (Array.isArray(r)) for (let e = 0; e < r.length; e++) {
10026
10071
  let a = r[e];
10027
- a && typeof a == "object" && typeof Pd(a, i) == "string" && n.push(`${t}.${e}.${i}`);
10072
+ a && typeof a == "object" && typeof Ld(a, i) == "string" && n.push(`${t}.${e}.${i}`);
10028
10073
  }
10029
10074
  }
10030
10075
  return n;
10031
10076
  }
10032
- function Ld(e) {
10077
+ function Bd(e) {
10033
10078
  let t = e ?? {}, n = /* @__PURE__ */ new Set();
10034
10079
  if (typeof t.jsonPath == "string" && t.jsonPath && n.add(t.jsonPath), typeof t.path == "string" && t.path && n.add(t.path), t.patch && typeof t.patch.jsonPath == "string" && t.patch.jsonPath && n.add(t.patch.jsonPath), Array.isArray(t.patches)) for (let e of t.patches) e && typeof e.jsonPath == "string" && e.jsonPath && n.add(e.jsonPath);
10035
10080
  return [...n];
10036
10081
  }
10037
- function Rd(e) {
10082
+ function Vd(e) {
10038
10083
  return {
10039
10084
  name: "component-write-guard",
10040
10085
  wrapToolCall: async (t, n) => {
@@ -10053,9 +10098,9 @@ function Rd(e) {
10053
10098
  status: "error"
10054
10099
  };
10055
10100
  }
10056
- let a = e.getLocked(), o = Object.keys(a), s = e.getCodeFieldPaths?.() ?? [], c = Ld(i);
10101
+ let a = e.getLocked(), o = Object.keys(a), s = e.getCodeFieldPaths?.() ?? [], c = Bd(i);
10057
10102
  if (s.length) {
10058
- let t = c.filter((e) => Fd(e, s));
10103
+ let t = c.filter((e) => Rd(e, s));
10059
10104
  if (t.length) return e.onReject?.({
10060
10105
  paths: t,
10061
10106
  lockedPrefixes: s,
@@ -10066,7 +10111,7 @@ function Rd(e) {
10066
10111
  };
10067
10112
  }
10068
10113
  if (!o.length) return n(t);
10069
- let l = Nd(e.getBind(), e.writablePaths, o);
10114
+ let l = Id(e.getBind(), e.writablePaths, o);
10070
10115
  if (!l.length) return n(t);
10071
10116
  if (!c.length) return e.onReject?.({
10072
10117
  paths: ["(整体 set)"],
@@ -10076,7 +10121,7 @@ function Rd(e) {
10076
10121
  content: `COMPONENT_LOCKED · 组件 [${o.join(", ")}] 正在被子 agent 修改,整体写入会触碰它们。请改用增量 patch(write({patch:{jsonPath,...}}))只写未锁定组件,或等委派结束后再整体操作。`,
10077
10122
  status: "error"
10078
10123
  };
10079
- let u = c.filter((e) => Fd(e, l));
10124
+ let u = c.filter((e) => Rd(e, l));
10080
10125
  return u.length ? (e.onReject?.({
10081
10126
  paths: u,
10082
10127
  lockedPrefixes: l,
@@ -10090,16 +10135,16 @@ function Rd(e) {
10090
10135
  }
10091
10136
  //#endregion
10092
10137
  //#region src/core/sdk/subtreeGuard.ts
10093
- function zd(e) {
10138
+ function Hd(e) {
10094
10139
  let t = e ?? {}, n = [];
10095
10140
  if (t.patch && typeof t.patch.jsonPath == "string" && t.patch.jsonPath && n.push(t.patch.jsonPath), Array.isArray(t.patches)) for (let e of t.patches) e && typeof e.jsonPath == "string" && e.jsonPath && n.push(e.jsonPath);
10096
10141
  return n;
10097
10142
  }
10098
- function Bd(e, t) {
10143
+ function Ud(e, t) {
10099
10144
  return e === t || e.startsWith(t + ".") || e.startsWith(t + "[");
10100
10145
  }
10101
- function Vd(e) {
10102
- let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = (e, t) => t.find((t) => Bd(e, t));
10146
+ function Wd(e) {
10147
+ let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = (e, t) => t.find((t) => Ud(e, t));
10103
10148
  return {
10104
10149
  name: "subtree-write-guard",
10105
10150
  beforeAgent: () => {
@@ -10114,11 +10159,11 @@ function Vd(e) {
10114
10159
  if (a.name !== "write" || (a.args ?? {}).dryRun === !0) return o(a);
10115
10160
  let s = e.getSummarizedPaths();
10116
10161
  if (!s.length) return o(a);
10117
- let c = zd(a.args);
10162
+ let c = Hd(a.args);
10118
10163
  if (!c.length) return o(a);
10119
10164
  for (let e of c) {
10120
10165
  let a = i(e, s);
10121
- if (a && !([...t].some((e) => Bd(e, a)) || n.has(a)) && !r.has(a)) return r.add(a), {
10166
+ if (a && !([...t].some((e) => Ud(e, a)) || n.has(a)) && !r.has(a)) return r.add(a), {
10122
10167
  content: `NEED_NARROW_READ · 写路径 "${e}" 的目标子树 "${a}" 此前只见摘要占位(<subtree …>/<field Nkb>,键名可见但内容未见),直接写入易凭印象猜结构错位。请先 read({jsonPath:"${a}"}) 查看实际内容(结果根豁免返回全文;若它是大数组或内容很大,加 offset/limit 分页或 fields 裁剪、或只读要写的子路径,勿整灌上下文),再基于真实值写入;聚焦该区域也可用 set_focus。若你确认已读过,请检查路径是否写错。`,
10123
10168
  status: "error"
10124
10169
  };
@@ -10134,7 +10179,7 @@ function Vd(e) {
10134
10179
  }
10135
10180
  //#endregion
10136
10181
  //#region src/core/harness/delegateNudge.ts
10137
- function Hd(e, t) {
10182
+ function Gd(e, t) {
10138
10183
  let n = e ?? {}, r = t(), i = (e) => {
10139
10184
  let t = e.split("."), n = [], r = 0;
10140
10185
  for (let e of t) if (n.push(e), /^\d+$/.test(e) && (r++, r >= 1)) break;
@@ -10184,10 +10229,10 @@ function Hd(e, t) {
10184
10229
  kind: o
10185
10230
  };
10186
10231
  }
10187
- function Ud(e) {
10232
+ function Kd(e) {
10188
10233
  return e === "spawn_agent" || e === "spawn_agents" || e.startsWith("use_");
10189
10234
  }
10190
- function Wd(e) {
10235
+ function qd(e) {
10191
10236
  let t = e.threshold ?? 12, n = /* @__PURE__ */ new Set(), r = 0, i = !1, a = !1, o = () => {
10192
10237
  let t = e.getBind();
10193
10238
  if (!t || typeof t != "object") return 0;
@@ -10215,12 +10260,12 @@ function Wd(e) {
10215
10260
  ].join("\n");
10216
10261
  },
10217
10262
  wrapToolCall: async (o, s) => {
10218
- if (Ud(o.name) && (i = !0), o.name !== "write") return s(o);
10263
+ if (Kd(o.name) && (i = !0), o.name !== "write") return s(o);
10219
10264
  let c = await s(o);
10220
10265
  if ((o.args ?? {}).dryRun === !0) return c;
10221
10266
  let l = String(c.content ?? "");
10222
10267
  if (!(c.status !== "error" && !l.startsWith("ERROR:") && !l.includes("未写入") && !l.includes("无需删除")) || i || a) return c;
10223
- let u = Hd(o.args, e.getBind);
10268
+ let u = Gd(o.args, e.getBind);
10224
10269
  for (let e of u.scopes) n.add(e);
10225
10270
  u.kind === "whole-set" && (r += u.count);
10226
10271
  let d = n.size + r;
@@ -10241,7 +10286,7 @@ function Wd(e) {
10241
10286
  }
10242
10287
  //#endregion
10243
10288
  //#region src/core/sdk/baselineGuard.ts
10244
- function Gd(e) {
10289
+ function Jd(e) {
10245
10290
  return {
10246
10291
  name: "baseline-guard",
10247
10292
  wrapToolCall: async (t, n) => {
@@ -10261,21 +10306,21 @@ function Gd(e) {
10261
10306
  }
10262
10307
  //#endregion
10263
10308
  //#region src/core/sdk/diagnostics.ts
10264
- var Kd = 5e4, qd = 6e6;
10265
- function Jd(e) {
10309
+ var Yd = 5e4, Xd = 6e6;
10310
+ function Zd(e) {
10266
10311
  return e.replace(/([?&][^=&?]*(?:key|token|secret|password|signature)[^=&?]*=)[^&]*/gi, "$1***");
10267
10312
  }
10268
- function Yd(e) {
10269
- if (typeof e == "string") return e.length > Kd ? e.slice(0, Kd) + `…<truncated:${e.length - Kd} chars>` : e;
10270
- if (Array.isArray(e)) return e.map(Yd);
10313
+ function Qd(e) {
10314
+ if (typeof e == "string") return e.length > Yd ? e.slice(0, Yd) + `…<truncated:${e.length - Yd} chars>` : e;
10315
+ if (Array.isArray(e)) return e.map(Qd);
10271
10316
  if (e && typeof e == "object") {
10272
10317
  let t = {};
10273
- for (let [n, r] of Object.entries(e)) t[n] = Yd(r);
10318
+ for (let [n, r] of Object.entries(e)) t[n] = Qd(r);
10274
10319
  return t;
10275
10320
  }
10276
10321
  return e;
10277
10322
  }
10278
- function Xd(e) {
10323
+ function $d(e) {
10279
10324
  let t = Array.isArray(e.debugLogs) ? e.debugLogs : [];
10280
10325
  return {
10281
10326
  format: "page-agent-sdk/diagnostics",
@@ -10283,23 +10328,23 @@ function Xd(e) {
10283
10328
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
10284
10329
  environment: {
10285
10330
  userAgent: typeof navigator < "u" ? navigator.userAgent : "node",
10286
- url: typeof location < "u" ? Jd(location.href) : null
10331
+ url: typeof location < "u" ? Zd(location.href) : null
10287
10332
  },
10288
10333
  sessionId: e.sessionId ?? null,
10289
10334
  usage: e.usage ?? null,
10290
10335
  pendingConflict: e.pendingConflict ?? null,
10291
10336
  dataSummary: e.dataSummary ?? null,
10292
- info: e.info ? Yd(e.info) : null,
10293
- messages: (e.messages ?? []).map(Yd),
10294
- debugLogs: t.map(Yd),
10337
+ info: e.info ? Qd(e.info) : null,
10338
+ messages: (e.messages ?? []).map(Qd),
10339
+ debugLogs: t.map(Qd),
10295
10340
  extra: e.extra ?? null
10296
10341
  };
10297
10342
  }
10298
- function Zd(e) {
10343
+ function ef(e) {
10299
10344
  let t = JSON.stringify(e);
10300
- if (t.length <= qd) return t;
10345
+ if (t.length <= Xd) return t;
10301
10346
  let n = Array.isArray(e.debugLogs) ? e.debugLogs : [], r = 0;
10302
- for (; t.length > qd && n.length > 1;) {
10347
+ for (; t.length > Xd && n.length > 1;) {
10303
10348
  let i = Math.max(1, Math.floor(n.length / 2));
10304
10349
  n.splice(0, i), r += i, t = JSON.stringify(e);
10305
10350
  }
@@ -10309,13 +10354,13 @@ function Zd(e) {
10309
10354
  data: {
10310
10355
  stage: "diagnostics_truncated",
10311
10356
  droppedOldestLogs: r,
10312
- reason: `report > ${qd} chars`
10357
+ reason: `report > ${Xd} chars`
10313
10358
  }
10314
10359
  }), t = JSON.stringify(e)), t;
10315
10360
  }
10316
10361
  //#endregion
10317
10362
  //#region src/core/sdk/designSkill/skillDoc.ts
10318
- var Qd = "# Web Design Engineer\n\nThis skill positions the Agent as a top-tier design engineer who crafts elegant, refined Web artifacts using HTML/CSS/JavaScript/React. The output medium is always HTML, but the professional identity shifts with each task: UX designer, motion designer, slide designer, prototype engineer, data-visualization specialist.\n\nCore philosophy: **The bar is \"stunning,\" not \"functional.\" Every pixel is intentional, every interaction is deliberate. Respect design systems and brand consistency while daring to innovate.**\n\n---\n\n## Scope\n\n✅ **Applicable**: Visual front-end deliverables (pages / prototypes / slide decks / visualizations / animations / UI mockups / design systems)\n\n❌ **Not applicable**: Back-end APIs, CLI tools, data-processing scripts, pure logic development with no visual requirements, performance tuning, and other terminal tasks\n\n---\n\n## Host Environment (page-agent-sdk adaptation)\n\n> Read this first: it reinterprets every user-interaction instruction below. This guide was written for an interactive agent; you run as a **delegated sub-agent** inside page-agent-sdk. The adaptations:\n\n- **One-shot delegation**: you receive a spec'd `task`, run to completion, and return a single final report. You **cannot converse with the user mid-run**. Wherever this guide says \"ask the user\", \"wait for confirmation\", or \"checkpoint\" (Step 1 probing, Checkpoints 1–3, ambiguous feedback): pick the **conservative, defensible default**, note the assumption, keep building, and list all assumptions in your **closing report** so the main agent / user can course-correct on the next delegation.\n- **Facts**: no network tools. The delegation `task` is authoritative; see adapted Step 0.\n- **Output form**: each component is **complete, self-contained HTML** — inline `<style>` / `<script>` blocks (centralized, extractable), renderable standalone; external CDN JS/CSS only when the task calls for it. Code lands through your code-asset workflow (vfs working copy / write) and must pass `validate_code` before you finish.\n- **Scale**: usually **one component per delegation**, not a multi-file project. Treat file-management guidance below (descriptive filenames, v2 copies, `assets/` dirs, `brand-spec.md`) as moot; React patterns are kept from upstream for reference — **default to vanilla HTML/CSS/JS**, zero build steps.\n- **v0 / checkpoints**: \"show a v0 early\" translates to: state your design-system declaration (Step 3 block, condensed) in the closing report — not a mid-run pause.\n- **Verification**: you cannot open a browser console — the framework's `validate_code` / render check covers structural verification; run the Step-7 checklist mentally against the code you wrote.\n\n---\n\n## Workflow\n\n### Step 0: Verify Facts Before Anything Else\n\n> **SDK adaptation**: you have no network tools — skip the upstream WebSearch protocol. The delegation `task` is your source of facts. If it names a specific product / brand / version / dated event you cannot verify from the task or context, **do not assert specifics from training data**: implement the stated intent and flag the unverified spec in your closing report (e.g. \"assumed v2 pricing — unverified\"). Never fabricate specs, versions, release status, or stats.\n\n### Step 1: Understand the Requirements (judge the gap, then default deliberately)\n\nYou cannot ask the user — a delegation that stops to ask wastes the whole run. Instead, judge **how large the information gap** is, fill every gap with a **conservative, high-quality default**, and report the assumptions:\n\n- Task already spec'd (visual + content + interaction, like a good delegation task) → **no gap: follow it exactly**; don't re-design around it.\n- Turning an existing component / screenshot into a variant → small gap: only intent may be unclear — default conservatively, match the existing visual vocabulary.\n- \"Make it look great\" with no tone / audience / context → large gap: pick the school + recipe deliberately (Step 2 priority list below), state every assumption.\n- Genuinely vague (\"something nice\", \"I don't know what style\") → run the **Design Direction Advisor** below internally: pick 3 differentiated directions, implement the most conservative one that fits the task, mention the two alternatives in your closing report.\n\nKey areas to default consciously (mirror of upstream probing list):\n- **Product context**: What product? Target users? Existing design system / brand guidelines?\n- **Output type**: Web page / prototype / slide deck / animation / dashboard? Fidelity level?\n- **Variation dimensions**: Which dimensions should variants explore — layout, color, interaction, copy? How many?\n- **Constraints**: Responsive breakpoints? Dark/light mode? Accessibility? Fixed dimensions?\n\n### Step 2: Gather Design Context (by priority)\n\nGood design is rooted in existing context. **Never start from thin air.** Priority order:\n\n1. **Resources the user proactively provides** (screenshots / Figma / codebase / UI Kit / design system) → read them thoroughly and extract tokens\n2. **Existing pages of the user's product** → match their visual vocabulary (see \"When Adding to an Existing UI\" below)\n3. **Industry best practices** → ask which brands or products to use as reference\n4. **User names an anchor** (\"make it Linear-style\" / \"Aesop feeling\" / \"MUJI quietness\") → read the single recipe file at `references/style-recipes/<anchor>.md` (e.g., `references/style-recipes/linear.md`). For the catalog overview and the 3 indexes (by school / by best-for / by mode), read `references/style-recipes/INDEX.md` first.\n5. **Starting from scratch** → establish a temporary system based on industry best practices, or pick a recipe from `references/style-recipes/` (browse via `INDEX.md`) — and state the choice as an assumption in your closing report\n\nWhen analyzing reference materials, focus on: color system, typography scheme, spacing system, border-radius strategy, shadow hierarchy, motion style, component density, copywriting tone.\n\n> **Code ≫ Screenshots**: When the user provides both a codebase and screenshots, invest your effort in reading source code and extracting design tokens rather than guessing from screenshots — rebuilding/editing an interface from code yields far higher quality than from screenshots.\n\n#### When the Task Involves a Specific Brand — Asset Protocol\n\n**Asset > Spec.** A brand's identity is \"being recognized.\" Recognition is driven by assets in this order — **not by hex codes**:\n\n| Asset | Recognition contribution | When required |\n|---|---|---|\n| **Logo** (SVG / PNG, both light & dark variants if available) | Highest — any brand is identified by its logo | **Any brand task** — non-negotiable |\n| **Product imagery** (hero shots, detail, in-context) | Very high — physical products' \"main character\" *is* the product itself | **Physical products** (hardware, packaging, consumer goods) |\n| **UI screenshots** (latest version, real data scrubbed) | Very high — digital products' \"main character\" *is* the interface | **Digital products** (apps, SaaS, websites) |\n| Color tokens | Medium — auxiliary; without the assets above, brands collide | Auxiliary |\n| Typography | Low — needs the above to land | Auxiliary |\n\n**Hard rules**:\n\n- **Don't substitute CSS silhouettes / hand-drawn SVG for real product imagery** — the result is generic \"tech aesthetic\" any brand could wear (zero recognition value, the #1 way branded work fails)\n- **Logo is non-negotiable** — in delegation you cannot fetch one: if the task provides no logo asset, use an honest placeholder (see \"Placeholder Philosophy\") and flag the gap in your closing report — do **not** proceed with a colored rectangle as if it were a logo\n- **Color hex codes alone are not a brand** — they're the cheapest part of the identity\n- All available assets must be referenced via `<img src=\"…\">` as provided in the task / context map, not redrawn\n\n#### When Adding to an Existing UI\n\nThis is more common than designing from scratch. **Understand the visual vocabulary first, then act**:\n\n- **Color & tone**: The actual usage ratio of primary / neutral / accent colors? Does the copy feel engineer-oriented, marketing-oriented, or neutral?\n- **Interaction details**: The feedback style for hover / focus / active states (color shift / shadow / scale / translate)?\n- **Motion language**: Easing function preferences? Duration? Are transitions handled with CSS transition, CSS animation, or JS?\n- **Structural language**: How many elevation levels? Card density — sparse or dense? Border-radius uniform or hierarchical? Common layout patterns (split pane / cards / timeline / table)?\n- **Graphics & iconography**: Icon library in use? Illustration style? Image treatment?\n\nMatching the existing visual vocabulary is the prerequisite for seamless integration; newly added elements should be **indistinguishable from the originals**.\n\n### Step 3a: Position Four Questions Before Picking a System\n\n**Before listing color/typography/spacing tokens**, articulate four positioning questions for each artifact (or each slide / screen / scene):\n\n- **Narrative role**: Hero / transition / data / pull-quote / closing? (Each demands a different visual register.)\n- **Viewing distance**: 10cm phone / 1m laptop / 10m projector? (Drives type scale and information density.)\n- **Visual temperature**: Quiet / energized / authoritative / warm / somber / playful?\n- **Capacity check**: Mentally sketch the rough thumbnail — does the content fit the layout, or will it overflow / look too sparse?\n\nThe system that follows must serve these answers. Picking aesthetics in a vacuum is the root cause of generic output.\n\n### Step 3: Declare the Design System Before Writing Code\n\n**Before writing the first line of code**, articulate the design system in Markdown (in delegation: state it in your closing report — no mid-run pause):\n\n```markdown\nDesign Decisions:\n- Anchor / recipe (if any): [e.g., \"linear\" → `references/style-recipes/linear.md`, or \"custom\"]\n- Color palette: [primary / secondary / neutral / accent]\n- Typography: [heading font / body font / code font]\n- Spacing system: [base unit and multiples]\n- Border-radius strategy: [large / small / sharp]\n- Shadow hierarchy: [elevation 1–5]\n- Motion style: [easing curves / duration / trigger]\n```\n\n> If you picked a recipe from `references/style-recipes/`, paste its concrete palette / typography / spacing / radius / shadow / motion values straight into the block above — that catalog exists so you don't have to invent these on the fly, which is the leading cause of AI-default Inter + #3b82f6 mush. **Load only the one recipe file you're using**, not the whole catalog.\n\n### Step 4: Show a v0 Draft Early\n\n> **SDK adaptation**: in delegation this collapses into the closing report — include the (condensed) design-system declaration and the key structural choices there, so the main agent / user can course-correct on the next round. Build straight to the real thing; don't ship a placeholder skeleton as your final output.\n\nThe v0 mindset still applies *within* the build: lock the tone / layout direction first (design-system declaration), then flesh out content details, states, and motion.\n\n### Step 5: Full Build\n\nWrite full components, add states, and implement motion. Follow the technical specifications and design principles below.\n\n### Step 6: Verification\n\nWalk through the \"Pre-delivery Checklist\" item by item (mentally, against the code — you cannot open a browser console; `validate_code` / render check covers structure).\n\n### Step 7: Critique on Request (or as Self-Check Before Delivery)\n\nWhen the task asks \"review this\", \"is it good?\", \"score this\", \"好不好看\", or as a self-check before declaring done, run a **5-dimension critique**:\n\n| Dimension | What to evaluate |\n|---|---|\n| **Philosophy alignment** | Does every detail trace back to the chosen design direction? Or has it drifted into a generic mishmash? |\n| **Visual hierarchy** | Does the eye flow where intended? Squint test passes? Title/body ratio ≥ 2.5×? |\n| **Craft quality** | Pixel-level alignment, consistent spacing system (e.g., 8pt grid), controlled color count (≤ 4), font families ≤ 2 |\n| **Functionality** | Does each element earn its place? \"If I delete this, does the design get worse?\" If no → delete |\n| **Originality** | Avoids clichés while staying coherent? Any \"unexpected but right\" decisions, or pure template? |\n\nScore each 0–10. Output format:\n\n```markdown\n## Design Critique\n\n**Overall: X.X / 10** [Excellent (8+) / Good (6–7.9) / Needs work (4–5.9) / Failing (<4)]\n\n**By dimension**: Philosophy X / Hierarchy X / Craft X / Functionality X / Originality X\n\n### Keep\n- [Specific things done well, in design language]\n\n### Fix (sorted by severity)\n1. **[Issue name]** — ⚠️ Critical / ⚡ Important / 💡 Polish\n - Current: [what it looks like now]\n - Why: [why it's a problem]\n - Fix: [concrete change with values]\n\n### Quick Wins (top 3 if you only have 5 minutes)\n- [ ] [Highest-impact fix]\n- [ ] [Second]\n- [ ] [Third]\n```\n\n**Critique the design, not the designer.** For per-output-type weighting, common-issue catalog, and detailed scoring rubrics → see `references/critique-guide.md`.\n\n---\n\n## Fallback: Design Direction Advisor\n\n**When to trigger**:\n- The request is genuinely ambiguous (\"make something nice\", \"I don't know what style I want\", \"give me some directions\")\n- No design context exists, and no reference material is available\n- The task explicitly asks for \"a style\" / \"some directions\" / \"a vibe\"\n\n**When to skip**:\n- The task already provided brand / screenshot / style reference → go straight to the main workflow\n- The task stated a specific direction (\"make an Apple-Silicon-style launch animation\") → main workflow\n- Small tweaks → skip\n\n### Mechanism: 3 differentiated directions, not 10 questions\n\nDon't enumerate 10 generic taste questions. Instead, formulate **3 design directions** that come from clearly different schools — so the contrast is visible and the choice is meaningful. Each direction must include:\n\n- **A named designer or studio reference** (e.g., \"Pentagram-style information architecture\", not just \"minimalist\")\n- **2–3 lines of why this direction fits the task's context**\n- **Signature visual cues** (3–4 concrete details: color, typography, layout, motion)\n- **Optional**: one famous touchstone work\n\nIn delegation: implement the most conservative fitting direction, and list all three in the closing report as alternatives for the next round.\n\n### School library — pick 3 from different rows\n\n| School | Vibe | Sample anchors | Best for |\n|---|---|---|---|\n| **Information architecture** | Rational, data-driven, restrained | Pentagram, Edward Tufte, Massimo Vignelli, Bloomberg Terminal | Safe / professional / B2B / data products |\n| **Editorial / minimalist** | Whitespace, refined typography, quiet luxury | Kenya Hara (MUJI), Apple HIG, Dieter Rams, Aesop | Premium / high-end / quiet |\n| **Modern tool / Builder SaaS** | Hairline detail, warm dark, single accent, monospace chips | Linear, Vercel, Raycast, Notion | Developer tools / B2B SaaS / AI tools / infra |\n| **Motion / experimental** | Bold, generative, sensory | Field.io, Active Theory, Resn | Distinctive / launch films / brand moments |\n| **Brutalist / raw** | Anti-design, honest, unpolished | Balenciaga, Are.na, Bloomberg Businessweek covers | Differentiated / confident / counter-culture |\n| **Warm humanist** | Approachable, organic, hand-touched | Mailchimp (early), Stripe Press, Headspace | Lifestyle / education / approachable B2C / wellness |\n\n❌ **Hard rule**: never pick 3 from the same row — the contrast that makes the choice meaningful collapses.\n\n### After a direction is picked\n\nThe chosen direction becomes the design context for Step 2 onward. Surface 2–3 named recipes from that school by reading the matching files in `references/style-recipes/` (e.g., picked *Information Architecture* → read `references/style-recipes/pentagram.md`, `references/style-recipes/bloomberg-terminal.md`). Each recipe file brings concrete palette, typography, spacing, and signature moves you can paste into the Step 3 design-system declaration.\n\n> Extended philosophy library, per-school anchor tables, and AI-prompt templates → `references/design-directions.md`. Anchored recipe catalog → `references/style-recipes/INDEX.md` (catalog index + 3 indexes + cross-cutting anti-patterns) + 25 single-recipe files alongside it.\n\n---\n\n## Technical Specifications\n\n### React + Babel (Inline JSX)\n\nFor React prototypes, use **pinned-version** CDN scripts with `integrity` hashes — see the exact `<script>` tags in `references/advanced-patterns.md`. Do not change versions, do not add `type=\"module\"` (breaks the Babel transpilation pipeline). Import order: React → ReactDOM → Babel → your component files.\n\n> **SDK adaptation**: React remains upstream reference material; in page-agent-sdk components, **default to vanilla HTML/CSS/JS** (self-contained, zero build) unless the task explicitly demands React.\n\n#### Three Non-negotiable Hard Rules\n\n**1. Never use `const styles = { ... }`** — multiple component files with `styles` as a global object will silently overwrite each other. Always namespace: `const terminalStyles = { ... }`, `const headerStyles = { ... }`. Or use inline `style={{...}}` directly. **Never use `styles` as a variable name.**\n\n**2. Separate `<script type=\"text/babel\">` blocks do not share scope** — each Babel script is compiled independently. To share components across files, explicitly attach them to `window` at the end of each file: `Object.assign(window, { Terminal, Line });`\n\n**3. Do not use `scrollIntoView`** — in iframe-embedded preview environments, it disrupts outer-frame scrolling. Use `element.scrollTop = ...` or `window.scrollTo({...})` instead.\n\n### CSS Best Practices\n\n- Prefer CSS Grid + Flexbox for layout\n- Manage design tokens with CSS custom properties\n- **Prefer brand colors for palette**; when more colors are needed, derive harmonious variants using `oklch()` — **never invent new hues from scratch**\n- Use `text-wrap: pretty` for better line breaking\n- Use `clamp()` for fluid typography\n- Use `@container` queries for component-level responsiveness\n- Leverage `@media (prefers-color-scheme)` and `@media (prefers-reduced-motion)`\n\n### File Management\n\n> **SDK adaptation**: you have no filesystem and usually build one self-contained component per delegation — this section is upstream reference. Naming/versioning is handled by the host data model (component name / `__pgId`), not by you.\n\n---\n\n## Design Principles\n\n### Avoid AI-Style Clichés (the WHY matters)\n\nAnti-cliché is **not aesthetic snobbery** — it's protecting the user's brand recognition. The reasoning chain:\n\n1. The user wants their brand to be recognized\n2. AI defaults = average of training data = all brands averaged together = **no brand recognized**\n3. So AI-default output dilutes the user's identity into \"yet another AI-generated page\"\n\nThis is why the only legitimate exception to every anti-cliché rule below is **\"the brand spec uses it\"** — at that point it stops being slop and becomes a brand signature.\n\n| Pattern | Why it's slop | When it's actually fine |\n|---|---|---|\n| Aggressive purple → pink → blue gradient | The \"tech vibe\" formula AI training data converged on; on every SaaS / AI / web3 landing page | The brand itself uses it, or the task is satirizing this aesthetic |\n| Rounded card + colored left-border accent | Material/Tailwind era leftover; now visual noise in every dashboard | The user explicitly asks, or the brand spec preserves it |\n| Emoji as icon substitute | \"Not professional → slap emoji on it\" tic from training data | The brand uses emoji (Notion, Slack, early Linear), or audience is kids / casual |\n| SVG-drawn imagery (faces, scenes, objects) | AI-drawn SVG humans always have misaligned features and feel cheap | **Almost never** — use real images, AI-generated images, or honest placeholder |\n| CSS silhouette substituting for real product imagery | Generic \"tech aesthetic\" — same look across every brand | **Never** for branded work — go fetch the real product image |\n| Inter / Roboto / Arial / Fraunces / system-ui as display | Too common; reads as \"demo page\" rather than \"designed product\" | The brand spec specifies these (and usually with custom adjustments) |\n| Cyber-neon on `#0D1117` dark | GitHub-dark cosplay; baseline noise in dev-tool clones | The brand actually lives in this aesthetic |\n| Fabricated stats, fake logo walls, dummy testimonials | Damages credibility; users notice when numbers don't match reality | **Never** — use placeholders that say \"real data needed\" |\n\n### Emoji Rules\n\n**No emoji by default.** Only use emoji when the target design system/brand itself uses them (e.g., Notion, early Linear, certain consumer brands), and match their density and context precisely.\n\n- ❌ Using emoji as icon substitutes (\"I don't have an icon library, so I'll use 🚀 ⚡ ✨ as fillers\")\n- ❌ Using emoji as decorative filler (\"let's add an emoji before the heading to make it lively\")\n- ✅ No icon available → use a placeholder (see \"Placeholder Philosophy\" below) to signal that a real icon is needed\n- ✅ The brand itself uses emoji → follow the brand\n\n---\n\n### Placeholder Philosophy\n\n**When you lack icons, images, or components, a placeholder is more professional than a poorly drawn fake.**\n\n- Missing icon → square + label (e.g., `[icon]`, `▢`)\n- Missing avatar → initial-letter circle with a color fill\n- Missing image → a placeholder card with aspect-ratio info (e.g., `16:9 image`)\n- Missing data → use explicit \"real data needed\" placeholders; never fabricate\n- Missing logo → honest placeholder + flag in closing report (see Asset Protocol); never substitute \"brand name in a colored box\" for a logo on branded work\n\nA placeholder signals \"real material needed here.\" A fake signals \"I cut corners.\"\n\n### Aim to Stun\n\n- Play with proportion and whitespace to create visual rhythm\n- Bold type-size contrast (a 4–6× ratio between h1 and body text is normal)\n- Use color fills, textures, layering, and blend modes to create depth\n- Experiment with unconventional layouts, novel interaction metaphors, and thoughtful hover states\n- Use CSS animations + transitions for polished micro-interactions (button press, card hover, entry animations)\n- Use SVG filters, `backdrop-filter`, `mix-blend-mode`, `mask`, and other advanced CSS to create memorable moments\n\nCSS, HTML, JS, and SVG are far more capable than most people realize — **use them to astonish the user**.\n\n### Appropriate Scale\n\n| Context | Minimum Size |\n|---|---|\n| 1920×1080 presentations | Text ≥ 24px (ideally larger) |\n| Mobile mockups | Touch targets ≥ 44px |\n| Print documents | ≥ 12pt |\n| Web body text | Start at 16–18px |\n\n### Content Principles\n\n- **No filler content** — every element must earn its place\n- **Don't add sections unilaterally** — implement what the task specifies; if more content seems needed, note it in the closing report instead of padding\n- **Placeholders > fabricated data** — fake data damages credibility more than admitting a gap\n- **Less is more** — \"1,000 no's for every yes\"; whitespace is design\n- If the page looks empty → it's a layout problem, not a content problem. Solve it with composition, whitespace, and type-scale rhythm, not by stuffing content in\n\n---\n\n## Output Type Guidelines\n\n### Interactive Prototypes\n\n- **No title screen / cover page** — prototypes should center in the viewport or fill it (with sensible margins), letting the user see the product immediately\n- Use device frames (iPhone / Android / browser window) to enhance realism (see references file)\n- Implement key interaction paths so the user can click through them\n- Complete state coverage: default / hover / active / focus / disabled / loading / empty / error\n\n### HTML Slide Decks / Presentations\n\n- Fixed canvas at 1920×1080 (16:9), auto-fitted to any viewport via JS `transform: scale()`\n- Centered with letterbox bars; prev/next buttons placed **outside** the scaled container (to remain usable on small screens)\n- Keyboard navigation: ← → to change slides, Space for next\n- **Slide numbering is 1-indexed**: use labels like `01 Title`, `02 Agenda`, matching human speech (\"slide 5\" corresponds to label `05` — never use 0-indexed labels that cause off-by-one confusion)\n- Each slide should have a `data-screen-label` attribute for easy reference\n- Don't cram too much text — visuals lead, text supports; use at most 1–2 background colors per deck\n\n### Data Visualization Dashboards\n\n- Chart.js (simple) or D3.js (complex custom) — loaded via CDN\n- Responsive chart containers (`ResizeObserver`)\n- Provide dark/light mode toggle where it fits\n- Focus on **data-ink ratio**: remove unnecessary gridlines, 3D effects, and shadows; let the data speak\n- Color encoding should carry semantic meaning (up/down / category / time), not serve as decoration\n\n### Animation / Video Demos\n\nChoose animation approach by complexity, from simplest to heaviest — don't reach for a heavy library from the start:\n\n1. **CSS transitions / animations** — sufficient for 80% of micro-interactions (button press, card hover, fade-in entry, state toggle)\n2. **Simple state + setTimeout / requestAnimationFrame** — simple frame-by-frame or event-driven animations\n3. **Custom timeline engine** (full implementation in references) — timeline-driven video/demo scenes: scrubber, play/pause, multi-segment choreography\n4. **Fallback: Popmotion** (`https://unpkg.com/popmotion@11.0.5/dist/popmotion.min.js`) — only if the above three layers genuinely can't cover the use case\n\n> Avoid Framer Motion / GSAP / Lottie unless explicitly requested — bundle overhead and version conflicts. Always provide play/pause + scrubber, and skip \"title screen\" intros — go straight to content.\n\n### Static Visual Comparison vs. Full Flow\n\n- **Pure visual comparison** (button colors, typography, card styles) → use a design canvas to display options side by side\n- **Interactions, flows, multi-option scenarios** → build a full clickable prototype + expose options as Tweaks\n\n---\n\n## Variant Exploration Philosophy\n\nProviding multiple variants is about **exhausting possibilities so the user can mix and match**, not about delivering the perfect option.\n\nExplore \"atomic variants\" across at least these dimensions — mixing conservative, safe options with bold, novel ones:\n\n1. **Layout**: content organization (split pane / card grid / list / timeline)\n2. **Visual**: color palette, typography, texture, layering\n3. **Interaction**: motion, feedback, navigation patterns\n4. **Creative**: convention-breaking metaphors, novel UX, strong visual concepts\n\nStrategy: **Start the first few variants safely within the design system; then progressively push boundaries.** In delegation, prefer the safe-but-excellent end unless the task asks for boldness — radical exploration belongs in the reported alternatives, not in the delivered build.\n\n---\n\n## Tweaks Panel (Live Parameter Adjustment)\n\nLet users adjust design parameters in real time: theme color, font size, dark mode, spacing, component variants, content density, animation toggles, etc.\n\nDesign guidelines:\n- A floating panel in the bottom-right corner (see the reference implementation)\n- Title consistently labeled **\"Tweaks\"**\n- **Completely hidden** when closed, ensuring the design looks final during presentations\n- In multi-variant scenarios, expose variants as dropdowns/toggles within Tweaks instead of creating multiple files\n- Even if the task doesn't ask for tweaks, consider 1–2 creative ones (to expose interesting possibilities) — but skip entirely for small components where a floating panel would pollute the design\n\n---\n\n## Common CDN Resources\n\n**Default to hand-written CSS.** Only load a CDN when the scenario clearly calls for it — never include everything by default.\n\n| When clearly needed | Library |\n|---|---|\n| Charts (line / bar / pie) | Chart.js (`https://cdn.jsdelivr.net/npm/chart.js`) |\n| Complex custom visualizations | D3 v7 (`https://d3js.org/d3.v7.min.js`) |\n| Custom typography | Google Fonts (avoid Inter / Roboto / Arial / Fraunces / system-ui as display) |\n\n| Use only on explicit request or throwaway prototypes | Why |\n|---|---|\n| Tailwind CDN | Conflicts with the \"declare design tokens first\" workflow |\n| Lucide Icons CDN | Prefer placeholders over inserting icons \"to look complete\" when no icon library was specified |\n\n> React + Babel pinned CDN script tags → `references/advanced-patterns.md`. Do not change versions.\n\n---\n\n## Pre-delivery Checklist\n\nComplete the following before considering the work delivered (all items must pass):\n\n- [ ] **Facts**: any product/brand/version spec that couldn't be verified is flagged in the closing report — not asserted, not fabricated\n- [ ] **If the task is branded**: logo/product imagery come from task-provided assets via `<img src>` (or honest placeholder + flag), never CSS silhouettes or redrawn SVG for real imagery\n- [ ] Code passes `validate_code` (structure) — the framework's render check is the console-error proxy\n- [ ] Renders correctly on **target devices/viewports** (responsive web → mobile / tablet / desktop; slide decks/video with fixed dimensions → scaling container adapts without distortion)\n- [ ] **Interactive components** (buttons, links, inputs, cards, etc.) include states as appropriate: hover / focus / active / disabled / loading; empty/error states added where the scenario warrants them\n- [ ] No text overflow or truncation; `text-wrap: pretty` applied\n- [ ] All colors come from the design system declared in Step 3 — **no rogue hues introduced**\n- [ ] No use of `scrollIntoView`\n- [ ] No AI clichés (purple-pink gradients, emoji abuse, left-border accent cards, Inter/Roboto) — unless the brand spec explicitly uses them\n- [ ] No filler content, no fabricated data\n- [ ] Semantic naming, clean structure, easy to modify later\n- [ ] Visual quality at Dribbble / Behance showcase level\n- [ ] **Closing report**: condensed design-system declaration + assumptions/flags + (optionally) critique score and alternatives\n\n---\n\n## Collaborating with the User\n\n- **Report work-in-progress thinking**: your closing report carries the v0 role — design-system declaration, key decisions, assumptions\n- Explain decisions using **design language** (\"I tightened the spacing to create a tool-like feel\"), not technical language\n- When the task is ambiguous, state how you read it and what you'd do differently under another reading — the next delegation can pivot\n- Offer alternatives and creative options in the report so the user sees the boundaries of what's possible\n- When summarizing, **only mention important caveats and next steps** — don't recap what you did; the code speaks for itself\n\n---\n\n## References Routing\n\nRead on demand based on task type — don't preload everything (load via `load_skill('web-design-engineer', ref='<name>')`):\n\n| Task | Read |\n|---|---|\n| Slide engine, device frames, Tweaks panel, animation timeline, design canvas, dark mode, data viz, oklch color system, font recommendations | `references/advanced-patterns.md` |\n| Vague request → recommend 3 design directions; extended philosophy library + per-direction visual recipes + AI-prompt templates | `references/design-directions.md` |\n| Task names an anchor (\"Linear-style\" / \"Aesop feeling\") → load **only that one file** | `references/style-recipes/<anchor>.md` (e.g., `linear.md`, `aesop.md`) |\n| Browse the recipe catalog / compare options after Direction Advisor picks a school | `references/style-recipes/INDEX.md` (3 indexes + cross-cutting anti-patterns; then read 1–3 specific recipe files) |\n| Critique mode — detailed scoring rubrics, per-output-type weighting, common-issue catalog (top 10) | `references/critique-guide.md` |\n", $d = [
10363
+ var tf = "# Web Design Engineer\n\nThis skill positions the Agent as a top-tier design engineer who crafts elegant, refined Web artifacts using HTML/CSS/JavaScript/React. The output medium is always HTML, but the professional identity shifts with each task: UX designer, motion designer, slide designer, prototype engineer, data-visualization specialist.\n\nCore philosophy: **The bar is \"stunning,\" not \"functional.\" Every pixel is intentional, every interaction is deliberate. Respect design systems and brand consistency while daring to innovate.**\n\n---\n\n## Scope\n\n✅ **Applicable**: Visual front-end deliverables (pages / prototypes / slide decks / visualizations / animations / UI mockups / design systems)\n\n❌ **Not applicable**: Back-end APIs, CLI tools, data-processing scripts, pure logic development with no visual requirements, performance tuning, and other terminal tasks\n\n---\n\n## Host Environment (page-agent-sdk adaptation)\n\n> Read this first: it reinterprets every user-interaction instruction below. This guide was written for an interactive agent; you run as a **delegated sub-agent** inside page-agent-sdk. The adaptations:\n\n- **One-shot delegation**: you receive a spec'd `task`, run to completion, and return a single final report. You **cannot converse with the user mid-run**. Wherever this guide says \"ask the user\", \"wait for confirmation\", or \"checkpoint\" (Step 1 probing, Checkpoints 1–3, ambiguous feedback): pick the **conservative, defensible default**, note the assumption, keep building, and list all assumptions in your **closing report** so the main agent / user can course-correct on the next delegation.\n- **Facts**: no network tools. The delegation `task` is authoritative; see adapted Step 0.\n- **Output form**: each component is **complete, self-contained HTML** — inline `<style>` / `<script>` blocks (centralized, extractable), renderable standalone; external CDN JS/CSS only when the task calls for it. Code lands through your code-asset workflow (vfs working copy / write) and must pass `validate_code` before you finish.\n- **Scale**: usually **one component per delegation**, not a multi-file project. Treat file-management guidance below (descriptive filenames, v2 copies, `assets/` dirs, `brand-spec.md`) as moot; React patterns are kept from upstream for reference — **default to vanilla HTML/CSS/JS**, zero build steps.\n- **v0 / checkpoints**: \"show a v0 early\" translates to: state your design-system declaration (Step 3 block, condensed) in the closing report — not a mid-run pause.\n- **Verification**: you cannot open a browser console — the framework's `validate_code` / render check covers structural verification; run the Step-7 checklist mentally against the code you wrote.\n\n---\n\n## Workflow\n\n### Step 0: Verify Facts Before Anything Else\n\n> **SDK adaptation**: you have no network tools — skip the upstream WebSearch protocol. The delegation `task` is your source of facts. If it names a specific product / brand / version / dated event you cannot verify from the task or context, **do not assert specifics from training data**: implement the stated intent and flag the unverified spec in your closing report (e.g. \"assumed v2 pricing — unverified\"). Never fabricate specs, versions, release status, or stats.\n\n### Step 1: Understand the Requirements (judge the gap, then default deliberately)\n\nYou cannot ask the user — a delegation that stops to ask wastes the whole run. Instead, judge **how large the information gap** is, fill every gap with a **conservative, high-quality default**, and report the assumptions:\n\n- Task already spec'd (visual + content + interaction, like a good delegation task) → **no gap: follow it exactly**; don't re-design around it.\n- Turning an existing component / screenshot into a variant → small gap: only intent may be unclear — default conservatively, match the existing visual vocabulary.\n- \"Make it look great\" with no tone / audience / context → large gap: pick the school + recipe deliberately (Step 2 priority list below), state every assumption.\n- Genuinely vague (\"something nice\", \"I don't know what style\") → run the **Design Direction Advisor** below internally: pick 3 differentiated directions, implement the most conservative one that fits the task, mention the two alternatives in your closing report.\n\nKey areas to default consciously (mirror of upstream probing list):\n- **Product context**: What product? Target users? Existing design system / brand guidelines?\n- **Output type**: Web page / prototype / slide deck / animation / dashboard? Fidelity level?\n- **Variation dimensions**: Which dimensions should variants explore — layout, color, interaction, copy? How many?\n- **Constraints**: Responsive breakpoints? Dark/light mode? Accessibility? Fixed dimensions?\n\n### Step 2: Gather Design Context (by priority)\n\nGood design is rooted in existing context. **Never start from thin air.** Priority order:\n\n1. **Resources the user proactively provides** (screenshots / Figma / codebase / UI Kit / design system) → read them thoroughly and extract tokens\n2. **Existing pages of the user's product** → match their visual vocabulary (see \"When Adding to an Existing UI\" below)\n3. **Industry best practices** → ask which brands or products to use as reference\n4. **User names an anchor** (\"make it Linear-style\" / \"Aesop feeling\" / \"MUJI quietness\") → read the single recipe file at `references/style-recipes/<anchor>.md` (e.g., `references/style-recipes/linear.md`). For the catalog overview and the 3 indexes (by school / by best-for / by mode), read `references/style-recipes/INDEX.md` first.\n5. **Starting from scratch** → establish a temporary system based on industry best practices, or pick a recipe from `references/style-recipes/` (browse via `INDEX.md`) — and state the choice as an assumption in your closing report\n\nWhen analyzing reference materials, focus on: color system, typography scheme, spacing system, border-radius strategy, shadow hierarchy, motion style, component density, copywriting tone.\n\n> **Code ≫ Screenshots**: When the user provides both a codebase and screenshots, invest your effort in reading source code and extracting design tokens rather than guessing from screenshots — rebuilding/editing an interface from code yields far higher quality than from screenshots.\n\n#### When the Task Involves a Specific Brand — Asset Protocol\n\n**Asset > Spec.** A brand's identity is \"being recognized.\" Recognition is driven by assets in this order — **not by hex codes**:\n\n| Asset | Recognition contribution | When required |\n|---|---|---|\n| **Logo** (SVG / PNG, both light & dark variants if available) | Highest — any brand is identified by its logo | **Any brand task** — non-negotiable |\n| **Product imagery** (hero shots, detail, in-context) | Very high — physical products' \"main character\" *is* the product itself | **Physical products** (hardware, packaging, consumer goods) |\n| **UI screenshots** (latest version, real data scrubbed) | Very high — digital products' \"main character\" *is* the interface | **Digital products** (apps, SaaS, websites) |\n| Color tokens | Medium — auxiliary; without the assets above, brands collide | Auxiliary |\n| Typography | Low — needs the above to land | Auxiliary |\n\n**Hard rules**:\n\n- **Don't substitute CSS silhouettes / hand-drawn SVG for real product imagery** — the result is generic \"tech aesthetic\" any brand could wear (zero recognition value, the #1 way branded work fails)\n- **Logo is non-negotiable** — in delegation you cannot fetch one: if the task provides no logo asset, use an honest placeholder (see \"Placeholder Philosophy\") and flag the gap in your closing report — do **not** proceed with a colored rectangle as if it were a logo\n- **Color hex codes alone are not a brand** — they're the cheapest part of the identity\n- All available assets must be referenced via `<img src=\"…\">` as provided in the task / context map, not redrawn\n\n#### When Adding to an Existing UI\n\nThis is more common than designing from scratch. **Understand the visual vocabulary first, then act**:\n\n- **Color & tone**: The actual usage ratio of primary / neutral / accent colors? Does the copy feel engineer-oriented, marketing-oriented, or neutral?\n- **Interaction details**: The feedback style for hover / focus / active states (color shift / shadow / scale / translate)?\n- **Motion language**: Easing function preferences? Duration? Are transitions handled with CSS transition, CSS animation, or JS?\n- **Structural language**: How many elevation levels? Card density — sparse or dense? Border-radius uniform or hierarchical? Common layout patterns (split pane / cards / timeline / table)?\n- **Graphics & iconography**: Icon library in use? Illustration style? Image treatment?\n\nMatching the existing visual vocabulary is the prerequisite for seamless integration; newly added elements should be **indistinguishable from the originals**.\n\n### Step 3a: Position Four Questions Before Picking a System\n\n**Before listing color/typography/spacing tokens**, articulate four positioning questions for each artifact (or each slide / screen / scene):\n\n- **Narrative role**: Hero / transition / data / pull-quote / closing? (Each demands a different visual register.)\n- **Viewing distance**: 10cm phone / 1m laptop / 10m projector? (Drives type scale and information density.)\n- **Visual temperature**: Quiet / energized / authoritative / warm / somber / playful?\n- **Capacity check**: Mentally sketch the rough thumbnail — does the content fit the layout, or will it overflow / look too sparse?\n\nThe system that follows must serve these answers. Picking aesthetics in a vacuum is the root cause of generic output.\n\n### Step 3: Declare the Design System Before Writing Code\n\n**Before writing the first line of code**, articulate the design system in Markdown (in delegation: state it in your closing report — no mid-run pause):\n\n```markdown\nDesign Decisions:\n- Anchor / recipe (if any): [e.g., \"linear\" → `references/style-recipes/linear.md`, or \"custom\"]\n- Color palette: [primary / secondary / neutral / accent]\n- Typography: [heading font / body font / code font]\n- Spacing system: [base unit and multiples]\n- Border-radius strategy: [large / small / sharp]\n- Shadow hierarchy: [elevation 1–5]\n- Motion style: [easing curves / duration / trigger]\n```\n\n> If you picked a recipe from `references/style-recipes/`, paste its concrete palette / typography / spacing / radius / shadow / motion values straight into the block above — that catalog exists so you don't have to invent these on the fly, which is the leading cause of AI-default Inter + #3b82f6 mush. **Load only the one recipe file you're using**, not the whole catalog.\n\n### Step 4: Show a v0 Draft Early\n\n> **SDK adaptation**: in delegation this collapses into the closing report — include the (condensed) design-system declaration and the key structural choices there, so the main agent / user can course-correct on the next round. Build straight to the real thing; don't ship a placeholder skeleton as your final output.\n\nThe v0 mindset still applies *within* the build: lock the tone / layout direction first (design-system declaration), then flesh out content details, states, and motion.\n\n### Step 5: Full Build\n\nWrite full components, add states, and implement motion. Follow the technical specifications and design principles below.\n\n### Step 6: Verification\n\nWalk through the \"Pre-delivery Checklist\" item by item (mentally, against the code — you cannot open a browser console; `validate_code` / render check covers structure).\n\n### Step 7: Critique on Request (or as Self-Check Before Delivery)\n\nWhen the task asks \"review this\", \"is it good?\", \"score this\", \"好不好看\", or as a self-check before declaring done, run a **5-dimension critique**:\n\n| Dimension | What to evaluate |\n|---|---|\n| **Philosophy alignment** | Does every detail trace back to the chosen design direction? Or has it drifted into a generic mishmash? |\n| **Visual hierarchy** | Does the eye flow where intended? Squint test passes? Title/body ratio ≥ 2.5×? |\n| **Craft quality** | Pixel-level alignment, consistent spacing system (e.g., 8pt grid), controlled color count (≤ 4), font families ≤ 2 |\n| **Functionality** | Does each element earn its place? \"If I delete this, does the design get worse?\" If no → delete |\n| **Originality** | Avoids clichés while staying coherent? Any \"unexpected but right\" decisions, or pure template? |\n\nScore each 0–10. Output format:\n\n```markdown\n## Design Critique\n\n**Overall: X.X / 10** [Excellent (8+) / Good (6–7.9) / Needs work (4–5.9) / Failing (<4)]\n\n**By dimension**: Philosophy X / Hierarchy X / Craft X / Functionality X / Originality X\n\n### Keep\n- [Specific things done well, in design language]\n\n### Fix (sorted by severity)\n1. **[Issue name]** — ⚠️ Critical / ⚡ Important / 💡 Polish\n - Current: [what it looks like now]\n - Why: [why it's a problem]\n - Fix: [concrete change with values]\n\n### Quick Wins (top 3 if you only have 5 minutes)\n- [ ] [Highest-impact fix]\n- [ ] [Second]\n- [ ] [Third]\n```\n\n**Critique the design, not the designer.** For per-output-type weighting, common-issue catalog, and detailed scoring rubrics → see `references/critique-guide.md`.\n\n---\n\n## Fallback: Design Direction Advisor\n\n**When to trigger**:\n- The request is genuinely ambiguous (\"make something nice\", \"I don't know what style I want\", \"give me some directions\")\n- No design context exists, and no reference material is available\n- The task explicitly asks for \"a style\" / \"some directions\" / \"a vibe\"\n\n**When to skip**:\n- The task already provided brand / screenshot / style reference → go straight to the main workflow\n- The task stated a specific direction (\"make an Apple-Silicon-style launch animation\") → main workflow\n- Small tweaks → skip\n\n### Mechanism: 3 differentiated directions, not 10 questions\n\nDon't enumerate 10 generic taste questions. Instead, formulate **3 design directions** that come from clearly different schools — so the contrast is visible and the choice is meaningful. Each direction must include:\n\n- **A named designer or studio reference** (e.g., \"Pentagram-style information architecture\", not just \"minimalist\")\n- **2–3 lines of why this direction fits the task's context**\n- **Signature visual cues** (3–4 concrete details: color, typography, layout, motion)\n- **Optional**: one famous touchstone work\n\nIn delegation: implement the most conservative fitting direction, and list all three in the closing report as alternatives for the next round.\n\n### School library — pick 3 from different rows\n\n| School | Vibe | Sample anchors | Best for |\n|---|---|---|---|\n| **Information architecture** | Rational, data-driven, restrained | Pentagram, Edward Tufte, Massimo Vignelli, Bloomberg Terminal | Safe / professional / B2B / data products |\n| **Editorial / minimalist** | Whitespace, refined typography, quiet luxury | Kenya Hara (MUJI), Apple HIG, Dieter Rams, Aesop | Premium / high-end / quiet |\n| **Modern tool / Builder SaaS** | Hairline detail, warm dark, single accent, monospace chips | Linear, Vercel, Raycast, Notion | Developer tools / B2B SaaS / AI tools / infra |\n| **Motion / experimental** | Bold, generative, sensory | Field.io, Active Theory, Resn | Distinctive / launch films / brand moments |\n| **Brutalist / raw** | Anti-design, honest, unpolished | Balenciaga, Are.na, Bloomberg Businessweek covers | Differentiated / confident / counter-culture |\n| **Warm humanist** | Approachable, organic, hand-touched | Mailchimp (early), Stripe Press, Headspace | Lifestyle / education / approachable B2C / wellness |\n\n❌ **Hard rule**: never pick 3 from the same row — the contrast that makes the choice meaningful collapses.\n\n### After a direction is picked\n\nThe chosen direction becomes the design context for Step 2 onward. Surface 2–3 named recipes from that school by reading the matching files in `references/style-recipes/` (e.g., picked *Information Architecture* → read `references/style-recipes/pentagram.md`, `references/style-recipes/bloomberg-terminal.md`). Each recipe file brings concrete palette, typography, spacing, and signature moves you can paste into the Step 3 design-system declaration.\n\n> Extended philosophy library, per-school anchor tables, and AI-prompt templates → `references/design-directions.md`. Anchored recipe catalog → `references/style-recipes/INDEX.md` (catalog index + 3 indexes + cross-cutting anti-patterns) + 25 single-recipe files alongside it.\n\n---\n\n## Technical Specifications\n\n### React + Babel (Inline JSX)\n\nFor React prototypes, use **pinned-version** CDN scripts with `integrity` hashes — see the exact `<script>` tags in `references/advanced-patterns.md`. Do not change versions, do not add `type=\"module\"` (breaks the Babel transpilation pipeline). Import order: React → ReactDOM → Babel → your component files.\n\n> **SDK adaptation**: React remains upstream reference material; in page-agent-sdk components, **default to vanilla HTML/CSS/JS** (self-contained, zero build) unless the task explicitly demands React.\n\n#### Three Non-negotiable Hard Rules\n\n**1. Never use `const styles = { ... }`** — multiple component files with `styles` as a global object will silently overwrite each other. Always namespace: `const terminalStyles = { ... }`, `const headerStyles = { ... }`. Or use inline `style={{...}}` directly. **Never use `styles` as a variable name.**\n\n**2. Separate `<script type=\"text/babel\">` blocks do not share scope** — each Babel script is compiled independently. To share components across files, explicitly attach them to `window` at the end of each file: `Object.assign(window, { Terminal, Line });`\n\n**3. Do not use `scrollIntoView`** — in iframe-embedded preview environments, it disrupts outer-frame scrolling. Use `element.scrollTop = ...` or `window.scrollTo({...})` instead.\n\n### CSS Best Practices\n\n- Prefer CSS Grid + Flexbox for layout\n- Manage design tokens with CSS custom properties\n- **Prefer brand colors for palette**; when more colors are needed, derive harmonious variants using `oklch()` — **never invent new hues from scratch**\n- Use `text-wrap: pretty` for better line breaking\n- Use `clamp()` for fluid typography\n- Use `@container` queries for component-level responsiveness\n- Leverage `@media (prefers-color-scheme)` and `@media (prefers-reduced-motion)`\n\n### File Management\n\n> **SDK adaptation**: you have no filesystem and usually build one self-contained component per delegation — this section is upstream reference. Naming/versioning is handled by the host data model (component name / `__pgId`), not by you.\n\n---\n\n## Design Principles\n\n### Avoid AI-Style Clichés (the WHY matters)\n\nAnti-cliché is **not aesthetic snobbery** — it's protecting the user's brand recognition. The reasoning chain:\n\n1. The user wants their brand to be recognized\n2. AI defaults = average of training data = all brands averaged together = **no brand recognized**\n3. So AI-default output dilutes the user's identity into \"yet another AI-generated page\"\n\nThis is why the only legitimate exception to every anti-cliché rule below is **\"the brand spec uses it\"** — at that point it stops being slop and becomes a brand signature.\n\n| Pattern | Why it's slop | When it's actually fine |\n|---|---|---|\n| Aggressive purple → pink → blue gradient | The \"tech vibe\" formula AI training data converged on; on every SaaS / AI / web3 landing page | The brand itself uses it, or the task is satirizing this aesthetic |\n| Rounded card + colored left-border accent | Material/Tailwind era leftover; now visual noise in every dashboard | The user explicitly asks, or the brand spec preserves it |\n| Emoji as icon substitute | \"Not professional → slap emoji on it\" tic from training data | The brand uses emoji (Notion, Slack, early Linear), or audience is kids / casual |\n| SVG-drawn imagery (faces, scenes, objects) | AI-drawn SVG humans always have misaligned features and feel cheap | **Almost never** — use real images, AI-generated images, or honest placeholder |\n| CSS silhouette substituting for real product imagery | Generic \"tech aesthetic\" — same look across every brand | **Never** for branded work — go fetch the real product image |\n| Inter / Roboto / Arial / Fraunces / system-ui as display | Too common; reads as \"demo page\" rather than \"designed product\" | The brand spec specifies these (and usually with custom adjustments) |\n| Cyber-neon on `#0D1117` dark | GitHub-dark cosplay; baseline noise in dev-tool clones | The brand actually lives in this aesthetic |\n| Fabricated stats, fake logo walls, dummy testimonials | Damages credibility; users notice when numbers don't match reality | **Never** — use placeholders that say \"real data needed\" |\n\n### Emoji Rules\n\n**No emoji by default.** Only use emoji when the target design system/brand itself uses them (e.g., Notion, early Linear, certain consumer brands), and match their density and context precisely.\n\n- ❌ Using emoji as icon substitutes (\"I don't have an icon library, so I'll use 🚀 ⚡ ✨ as fillers\")\n- ❌ Using emoji as decorative filler (\"let's add an emoji before the heading to make it lively\")\n- ✅ No icon available → use a placeholder (see \"Placeholder Philosophy\" below) to signal that a real icon is needed\n- ✅ The brand itself uses emoji → follow the brand\n\n---\n\n### Placeholder Philosophy\n\n**When you lack icons, images, or components, a placeholder is more professional than a poorly drawn fake.**\n\n- Missing icon → square + label (e.g., `[icon]`, `▢`)\n- Missing avatar → initial-letter circle with a color fill\n- Missing image → a placeholder card with aspect-ratio info (e.g., `16:9 image`)\n- Missing data → use explicit \"real data needed\" placeholders; never fabricate\n- Missing logo → honest placeholder + flag in closing report (see Asset Protocol); never substitute \"brand name in a colored box\" for a logo on branded work\n\nA placeholder signals \"real material needed here.\" A fake signals \"I cut corners.\"\n\n### Aim to Stun\n\n- Play with proportion and whitespace to create visual rhythm\n- Bold type-size contrast (a 4–6× ratio between h1 and body text is normal)\n- Use color fills, textures, layering, and blend modes to create depth\n- Experiment with unconventional layouts, novel interaction metaphors, and thoughtful hover states\n- Use CSS animations + transitions for polished micro-interactions (button press, card hover, entry animations)\n- Use SVG filters, `backdrop-filter`, `mix-blend-mode`, `mask`, and other advanced CSS to create memorable moments\n\nCSS, HTML, JS, and SVG are far more capable than most people realize — **use them to astonish the user**.\n\n### Appropriate Scale\n\n| Context | Minimum Size |\n|---|---|\n| 1920×1080 presentations | Text ≥ 24px (ideally larger) |\n| Mobile mockups | Touch targets ≥ 44px |\n| Print documents | ≥ 12pt |\n| Web body text | Start at 16–18px |\n\n### Content Principles\n\n- **No filler content** — every element must earn its place\n- **Don't add sections unilaterally** — implement what the task specifies; if more content seems needed, note it in the closing report instead of padding\n- **Placeholders > fabricated data** — fake data damages credibility more than admitting a gap\n- **Less is more** — \"1,000 no's for every yes\"; whitespace is design\n- If the page looks empty → it's a layout problem, not a content problem. Solve it with composition, whitespace, and type-scale rhythm, not by stuffing content in\n\n---\n\n## Output Type Guidelines\n\n### Interactive Prototypes\n\n- **No title screen / cover page** — prototypes should center in the viewport or fill it (with sensible margins), letting the user see the product immediately\n- Use device frames (iPhone / Android / browser window) to enhance realism (see references file)\n- Implement key interaction paths so the user can click through them\n- Complete state coverage: default / hover / active / focus / disabled / loading / empty / error\n\n### HTML Slide Decks / Presentations\n\n- Fixed canvas at 1920×1080 (16:9), auto-fitted to any viewport via JS `transform: scale()`\n- Centered with letterbox bars; prev/next buttons placed **outside** the scaled container (to remain usable on small screens)\n- Keyboard navigation: ← → to change slides, Space for next\n- **Slide numbering is 1-indexed**: use labels like `01 Title`, `02 Agenda`, matching human speech (\"slide 5\" corresponds to label `05` — never use 0-indexed labels that cause off-by-one confusion)\n- Each slide should have a `data-screen-label` attribute for easy reference\n- Don't cram too much text — visuals lead, text supports; use at most 1–2 background colors per deck\n\n### Data Visualization Dashboards\n\n- Chart.js (simple) or D3.js (complex custom) — loaded via CDN\n- Responsive chart containers (`ResizeObserver`)\n- Provide dark/light mode toggle where it fits\n- Focus on **data-ink ratio**: remove unnecessary gridlines, 3D effects, and shadows; let the data speak\n- Color encoding should carry semantic meaning (up/down / category / time), not serve as decoration\n\n### Animation / Video Demos\n\nChoose animation approach by complexity, from simplest to heaviest — don't reach for a heavy library from the start:\n\n1. **CSS transitions / animations** — sufficient for 80% of micro-interactions (button press, card hover, fade-in entry, state toggle)\n2. **Simple state + setTimeout / requestAnimationFrame** — simple frame-by-frame or event-driven animations\n3. **Custom timeline engine** (full implementation in references) — timeline-driven video/demo scenes: scrubber, play/pause, multi-segment choreography\n4. **Fallback: Popmotion** (`https://unpkg.com/popmotion@11.0.5/dist/popmotion.min.js`) — only if the above three layers genuinely can't cover the use case\n\n> Avoid Framer Motion / GSAP / Lottie unless explicitly requested — bundle overhead and version conflicts. Always provide play/pause + scrubber, and skip \"title screen\" intros — go straight to content.\n\n### Static Visual Comparison vs. Full Flow\n\n- **Pure visual comparison** (button colors, typography, card styles) → use a design canvas to display options side by side\n- **Interactions, flows, multi-option scenarios** → build a full clickable prototype + expose options as Tweaks\n\n---\n\n## Variant Exploration Philosophy\n\nProviding multiple variants is about **exhausting possibilities so the user can mix and match**, not about delivering the perfect option.\n\nExplore \"atomic variants\" across at least these dimensions — mixing conservative, safe options with bold, novel ones:\n\n1. **Layout**: content organization (split pane / card grid / list / timeline)\n2. **Visual**: color palette, typography, texture, layering\n3. **Interaction**: motion, feedback, navigation patterns\n4. **Creative**: convention-breaking metaphors, novel UX, strong visual concepts\n\nStrategy: **Start the first few variants safely within the design system; then progressively push boundaries.** In delegation, prefer the safe-but-excellent end unless the task asks for boldness — radical exploration belongs in the reported alternatives, not in the delivered build.\n\n---\n\n## Tweaks Panel (Live Parameter Adjustment)\n\nLet users adjust design parameters in real time: theme color, font size, dark mode, spacing, component variants, content density, animation toggles, etc.\n\nDesign guidelines:\n- A floating panel in the bottom-right corner (see the reference implementation)\n- Title consistently labeled **\"Tweaks\"**\n- **Completely hidden** when closed, ensuring the design looks final during presentations\n- In multi-variant scenarios, expose variants as dropdowns/toggles within Tweaks instead of creating multiple files\n- Even if the task doesn't ask for tweaks, consider 1–2 creative ones (to expose interesting possibilities) — but skip entirely for small components where a floating panel would pollute the design\n\n---\n\n## Common CDN Resources\n\n**Default to hand-written CSS.** Only load a CDN when the scenario clearly calls for it — never include everything by default.\n\n| When clearly needed | Library |\n|---|---|\n| Charts (line / bar / pie) | Chart.js (`https://cdn.jsdelivr.net/npm/chart.js`) |\n| Complex custom visualizations | D3 v7 (`https://d3js.org/d3.v7.min.js`) |\n| Custom typography | Google Fonts (avoid Inter / Roboto / Arial / Fraunces / system-ui as display) |\n\n| Use only on explicit request or throwaway prototypes | Why |\n|---|---|\n| Tailwind CDN | Conflicts with the \"declare design tokens first\" workflow |\n| Lucide Icons CDN | Prefer placeholders over inserting icons \"to look complete\" when no icon library was specified |\n\n> React + Babel pinned CDN script tags → `references/advanced-patterns.md`. Do not change versions.\n\n---\n\n## Pre-delivery Checklist\n\nComplete the following before considering the work delivered (all items must pass):\n\n- [ ] **Facts**: any product/brand/version spec that couldn't be verified is flagged in the closing report — not asserted, not fabricated\n- [ ] **If the task is branded**: logo/product imagery come from task-provided assets via `<img src>` (or honest placeholder + flag), never CSS silhouettes or redrawn SVG for real imagery\n- [ ] Code passes `validate_code` (structure) — the framework's render check is the console-error proxy\n- [ ] Renders correctly on **target devices/viewports** (responsive web → mobile / tablet / desktop; slide decks/video with fixed dimensions → scaling container adapts without distortion)\n- [ ] **Interactive components** (buttons, links, inputs, cards, etc.) include states as appropriate: hover / focus / active / disabled / loading; empty/error states added where the scenario warrants them\n- [ ] No text overflow or truncation; `text-wrap: pretty` applied\n- [ ] All colors come from the design system declared in Step 3 — **no rogue hues introduced**\n- [ ] No use of `scrollIntoView`\n- [ ] No AI clichés (purple-pink gradients, emoji abuse, left-border accent cards, Inter/Roboto) — unless the brand spec explicitly uses them\n- [ ] No filler content, no fabricated data\n- [ ] Semantic naming, clean structure, easy to modify later\n- [ ] Visual quality at Dribbble / Behance showcase level\n- [ ] **Closing report**: condensed design-system declaration + assumptions/flags + (optionally) critique score and alternatives\n\n---\n\n## Collaborating with the User\n\n- **Report work-in-progress thinking**: your closing report carries the v0 role — design-system declaration, key decisions, assumptions\n- Explain decisions using **design language** (\"I tightened the spacing to create a tool-like feel\"), not technical language\n- When the task is ambiguous, state how you read it and what you'd do differently under another reading — the next delegation can pivot\n- Offer alternatives and creative options in the report so the user sees the boundaries of what's possible\n- When summarizing, **only mention important caveats and next steps** — don't recap what you did; the code speaks for itself\n\n---\n\n## References Routing\n\nRead on demand based on task type — don't preload everything (load via `load_skill('web-design-engineer', ref='<name>')`):\n\n| Task | Read |\n|---|---|\n| Slide engine, device frames, Tweaks panel, animation timeline, design canvas, dark mode, data viz, oklch color system, font recommendations | `references/advanced-patterns.md` |\n| Vague request → recommend 3 design directions; extended philosophy library + per-direction visual recipes + AI-prompt templates | `references/design-directions.md` |\n| Task names an anchor (\"Linear-style\" / \"Aesop feeling\") → load **only that one file** | `references/style-recipes/<anchor>.md` (e.g., `linear.md`, `aesop.md`) |\n| Browse the recipe catalog / compare options after Direction Advisor picks a school | `references/style-recipes/INDEX.md` (3 indexes + cross-cutting anti-patterns; then read 1–3 specific recipe files) |\n| Critique mode — detailed scoring rubrics, per-output-type weighting, common-issue catalog (top 10) | `references/critique-guide.md` |\n", nf = [
10319
10364
  {
10320
10365
  name: "references/advanced-patterns.md",
10321
10366
  description: "Code templates: device frames, slide engine, animation timeline, Tweaks panel, design canvas, dark mode, data viz, oklch color system, font picks, pinned React+CDN tags",
@@ -10461,19 +10506,19 @@ var Qd = "# Web Design Engineer\n\nThis skill positions the Agent as a top-tier
10461
10506
  description: "Y2K / Frutiger Aero Retrofuturism · Late-90s / early-2000s techno-optimism: chrome, glassy bubbles, jelly translucency, lens flare",
10462
10507
  getContent: () => "\n# y2k-retrofuturism — Y2K / Frutiger Aero Retrofuturism\n\n- **School**: Specialty / Genre\n- **Vibe**: Late-90s / early-2000s techno-optimism: chrome, glassy bubbles, jelly translucency, lens flare\n- **Best for**: Fashion / music / nostalgia-coded products, creative campaigns, anything referencing 1999–2005 internet\n- **Touchstone**: late-90s Apple iMac G3 ads, Windows Vista Aero, the original iPod aqua buttons, MySpace pages\n\n**Palette**\n- Ground: electric ice blue `#A3D5FF` or chrome silver `#E0E4EA`\n- Glass accents: cyan `#5FC9F8` → magenta `#FF66C4` (the iridescent / oil-slick gradient)\n- Chrome: brushed-steel highlights at `#C4C9D2` to `#F2F4F8`\n- Acid green pops: `#A8FF00` (used sparingly)\n- Ink: `#000000` or `#FFFFFF` depending on ground\n\n**Typography**\n- Display: a chunky rounded sans with personality — Frutiger, Eurostile, or Sharp Grotesk in heavy weight; sometimes a chrome-effect treatment\n- Body: friendly humanist sans like Frutiger or Avenir at 14–16px\n- Numerals love an LCD / digital-readout treatment for hero counters\n- Underline + sparkle treatments common on link hover\n\n**Spacing**: 4 / 8 / 16 / 24 — packed but bubbly\n\n**Radius**: gummy — 16 / 24 / 32 / 9999 (full circle). Buttons are pill-shaped jelly bubbles.\n\n**Shadow**: heavy and colored — glossy reflections, drop shadows like `0 16px 32px rgba(95, 201, 248, 0.4)`. Inner highlights to simulate glass.\n\n**Motion**: bouncy springs, glow pulses, lens flare sweeps. Anything that recalls early-Flash interactions.\n\n**Signature moves**\n- Glassy translucent buttons with an inner top highlight (faking aqua / lozenge)\n- Iridescent oil-slick gradients on hero / character imagery\n- Chrome-effect type with sparkle overlays\n- Lens flare or specular highlight on any glass surface\n- 3D / dimensional UI elements (the OS-X-Aqua dock effect)\n- Floating circular orbs / bubbles drifting in the background\n\n**Avoid**\n- Sharp corners\n- Muted / earthy palettes — Y2K is bright and synthetic\n- Restrained typography — Y2K is exuberant\n- Anything that reads as \"tasteful 2020s minimalism\"\n\n**AI prompt seed**\n> Y2K retrofuturism scene, chrome silver and ice-blue iridescent gradient background, floating glass orbs with cyan and magenta oil-slick reflections, lens flare in upper right, single bright translucent pill-shaped button, late-1990s techno-optimism vibe, 16:9.\n\n**Don't use when**\n- The brand has no nostalgic / retro / playful claim\n- The audience is enterprise / professional — this recipe is consumer-fashion-music coded\n- Long-form readability matters (Y2K is for moments, not for reading)\n\n---\n\n> **Same school — Specialty / Genre**: [`mid-century-modern`](./mid-century-modern.md) \n> **Browse all 25 recipes**: [INDEX.md](./INDEX.md)\n\n"
10463
10508
  }
10464
- ], ef = "web-design-engineer";
10465
- function tf() {
10509
+ ], rf = "web-design-engineer";
10510
+ function af() {
10466
10511
  return {
10467
- name: ef,
10512
+ name: rf,
10468
10513
  description: "Design taste & anti-cliché system: declare the design system (palette/type/spacing/motion) before coding, avoid AI-default aesthetics (purple gradients/emoji icons/Inter), 25 named style recipes (linear/apple-hig/muji/pentagram/bloomberg-terminal…), 5-dimension critique. Load BEFORE starting any design-heavy visual work.",
10469
- getContent: () => Qd,
10470
- references: $d
10514
+ getContent: () => tf,
10515
+ references: nf
10471
10516
  };
10472
10517
  }
10473
10518
  //#endregion
10474
10519
  //#region src/core/sdk/htmlRenderCheck.ts
10475
- var nf = /SecurityError|localStorage|sessionStorage|document\.cookie|Access is denied for this document/i;
10476
- function rf(e) {
10520
+ var of = /SecurityError|localStorage|sessionStorage|document\.cookie|Access is denied for this document/i;
10521
+ function sf(e) {
10477
10522
  if (e.noDom) return {
10478
10523
  verdict: "pass",
10479
10524
  problems: [],
@@ -10496,10 +10541,10 @@ function rf(e) {
10496
10541
  let e = r.lineno === void 0 ? "" : `(第 ${r.lineno} 行)`;
10497
10542
  switch (r.type) {
10498
10543
  case "js-error":
10499
- nf.test(r.message) ? n.push(`storage 类错误降级为观察(沙箱 opaque origin 访问 localStorage/cookie 抛 SecurityError,非代码缺陷):${r.message}${e}`) : t.push(`JS 运行时错误:${r.message}${e}${r.source ? ` [${r.source}]` : ""}`);
10544
+ of.test(r.message) ? n.push(`storage 类错误降级为观察(沙箱 opaque origin 访问 localStorage/cookie 抛 SecurityError,非代码缺陷):${r.message}${e}`) : t.push(`JS 运行时错误:${r.message}${e}${r.source ? ` [${r.source}]` : ""}`);
10500
10545
  break;
10501
10546
  case "console-error":
10502
- nf.test(r.message) ? n.push(`console.error(storage 类,沙箱假阳性降观察):${r.message}`) : t.push(`console.error:${r.message}`);
10547
+ of.test(r.message) ? n.push(`console.error(storage 类,沙箱假阳性降观察):${r.message}`) : t.push(`console.error:${r.message}`);
10503
10548
  break;
10504
10549
  case "unhandledrejection":
10505
10550
  t.push(`未捕获的异步 Promise 拒绝(unhandledrejection):${r.message}`);
@@ -10522,7 +10567,7 @@ function rf(e) {
10522
10567
  metrics: e.metrics
10523
10568
  };
10524
10569
  }
10525
- function af(e) {
10570
+ function cf(e) {
10526
10571
  return [
10527
10572
  "(function(){",
10528
10573
  `var N=${JSON.stringify(e)};`,
@@ -10549,23 +10594,23 @@ function af(e) {
10549
10594
  "})();"
10550
10595
  ].join("\n");
10551
10596
  }
10552
- function of(e, t) {
10553
- let n = `<script>${af(t)}<\/script>`;
10597
+ function lf(e, t) {
10598
+ let n = `<script>${cf(t)}<\/script>`;
10554
10599
  return /<head[^>]*>/i.test(e) ? e.replace(/<head[^>]*>/i, (e) => e + n) : /<html[^>]*>/i.test(e) ? e.replace(/<html[^>]*>/i, (e) => e + n) : n + e;
10555
10600
  }
10556
- function sf() {
10601
+ function uf() {
10557
10602
  return typeof document < "u" && typeof document.createElement == "function" && document.body !== void 0 && document.body !== null;
10558
10603
  }
10559
- var cf = {
10604
+ var df = {
10560
10605
  created: 0,
10561
10606
  destroyed: 0
10562
10607
  };
10563
- function lf() {
10564
- return { ...cf };
10608
+ function ff() {
10609
+ return { ...df };
10565
10610
  }
10566
- function uf(e, t = {}) {
10611
+ function pf(e, t = {}) {
10567
10612
  let n = t.silenceMs ?? 900, r = t.hardCapMs ?? 4e3, i = t.metricsGraceMs ?? 500;
10568
- if (!sf()) return Promise.resolve({
10613
+ if (!uf()) return Promise.resolve({
10569
10614
  handshake: !1,
10570
10615
  signals: [],
10571
10616
  noDom: !0
@@ -10573,9 +10618,9 @@ function uf(e, t = {}) {
10573
10618
  let a = `pg_rc_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
10574
10619
  return new Promise((t) => {
10575
10620
  let o = [], s = !1, c, l, u, d, f, p, m = !1;
10576
- cf.created++;
10621
+ df.created++;
10577
10622
  let h = () => {
10578
- m || (m = !0, u && window.removeEventListener("message", u), d && clearTimeout(d), f && clearTimeout(f), p && clearTimeout(p), l && (l.remove(), cf.destroyed++));
10623
+ m || (m = !0, u && window.removeEventListener("message", u), d && clearTimeout(d), f && clearTimeout(f), p && clearTimeout(p), l && (l.remove(), df.destroyed++));
10579
10624
  }, g = (e = !1) => {
10580
10625
  h(), t({
10581
10626
  handshake: s,
@@ -10622,14 +10667,14 @@ function uf(e, t = {}) {
10622
10667
  ...r.source === void 0 ? {} : { source: String(r.source) },
10623
10668
  ...typeof r.lineno == "number" ? { lineno: r.lineno } : {}
10624
10669
  }), s && _();
10625
- }, window.addEventListener("message", u), f = setTimeout(() => g(!0), r), l = document.createElement("iframe"), l.setAttribute("sandbox", "allow-scripts"), l.setAttribute("aria-hidden", "true"), l.setAttribute("tabindex", "-1"), l.style.cssText = "position:fixed;left:-9999px;top:0;width:1024px;height:600px;visibility:hidden;border:0;opacity:0;pointer-events:none;", l.srcdoc = of(e, a), document.body.appendChild(l);
10670
+ }, window.addEventListener("message", u), f = setTimeout(() => g(!0), r), l = document.createElement("iframe"), l.setAttribute("sandbox", "allow-scripts"), l.setAttribute("aria-hidden", "true"), l.setAttribute("tabindex", "-1"), l.style.cssText = "position:fixed;left:-9999px;top:0;width:1024px;height:600px;visibility:hidden;border:0;opacity:0;pointer-events:none;", l.srcdoc = lf(e, a), document.body.appendChild(l);
10626
10671
  });
10627
10672
  }
10628
- function df(e = {}) {
10629
- let t = e.vfsPrefix ?? "html/", n = e.codeField ?? "code", r = e.maxTargets ?? 4, i = typeof e.runner == "function", a = e.runner ?? ((e) => uf(e)), o, s = e.writablePaths ?? [];
10673
+ function mf(e = {}) {
10674
+ let t = e.vfsPrefix ?? "html/", n = e.codeField ?? "code", r = e.maxTargets ?? 4, i = typeof e.runner == "function", a = e.runner ?? ((e) => pf(e)), o, s = e.writablePaths ?? [];
10630
10675
  return {
10631
10676
  check: async ({ state: e, log: c }) => {
10632
- if (!i && !sf()) return c?.("middleware", {
10677
+ if (!i && !uf()) return c?.("middleware", {
10633
10678
  stage: "render_check_skip",
10634
10679
  reason: "no-dom"
10635
10680
  }), { ok: !0 };
@@ -10664,7 +10709,7 @@ function df(e = {}) {
10664
10709
  });
10665
10710
  let g = [], _ = [], v = [];
10666
10711
  for (let e of h) {
10667
- let t = rf(await a(e.html));
10712
+ let t = sf(await a(e.html));
10668
10713
  for (let n of t.problems) g.push(`${e.label}:${n}`);
10669
10714
  for (let n of t.warnings) _.push(`${e.label}:${n}`);
10670
10715
  t.verdict === "unavailable" && v.push(e.label), c?.("middleware", {
@@ -10704,7 +10749,7 @@ function df(e = {}) {
10704
10749
  }
10705
10750
  };
10706
10751
  }
10707
- function ff(e, t) {
10752
+ function hf(e, t) {
10708
10753
  return async (n) => {
10709
10754
  let r = await e(n);
10710
10755
  return r.ok ? t(n) : r;
@@ -10712,7 +10757,7 @@ function ff(e, t) {
10712
10757
  }
10713
10758
  //#endregion
10714
10759
  //#region src/core/sdk/htmlSubagent.ts
10715
- function pf(e, t, n) {
10760
+ function gf(e, t, n) {
10716
10761
  let r = "html";
10717
10762
  return `你是纯代码组件生成专家。可用工具:vfs_write / vfs_edit / vfs_rm(写/改/删代码工作副本 vfs ${e}) / vfs_read + vfs_grep(读 vfs) / validate_code(代码格式自检) / write(写 data,writablePaths 限定;set/patch 增量或整体) / read / write_todos + update_todo(规划)。
10718
10763
 
@@ -10767,7 +10812,7 @@ ${`- 输出形态:完整、自包含的 HTML 页面(.${r},可独立成页)`}
10767
10812
  - 一次想清楚 → 动手 → 验证 → 收口。**思考是手段不是目的,产出代码才是**。
10768
10813
  8. **收口格式(必守,最后一行)**:收口回复 = 简短结果总结 + **末行交接笔记** \`[note] <一句话实现要点>\` —— 关键设计决策 / 用户偏好 / 踩坑(如「[note] 液面用 height keyframes 4.2s 循环;装饰仅灯串+光斑 2 类」)。框架只识别末尾 [note] 行存进组件、自动转交下次维护该组件的子 agent;**漏写 = 下任失去交接**(真 LLM 实测漏写率 3/4,务必末行带上)。一行内,只写可复用结论。`;
10769
10814
  }
10770
- function mf(e, t) {
10815
+ function _f(e, t) {
10771
10816
  return `# HTML 完整页面生成规范
10772
10817
 
10773
10818
  ## 代码资产模型(重要)
@@ -10805,14 +10850,14 @@ function mf(e, t) {
10805
10850
  - 语义化标签(button / nav / section);图片 alt;交互可键盘聚焦
10806
10851
  - 颜色对比达标;不只用颜色传达信息`;
10807
10852
  }
10808
- function hf(e = "components", t = "code") {
10853
+ function vf(e = "components", t = "code") {
10809
10854
  return {
10810
10855
  name: "html-fragment",
10811
10856
  description: "完整 HTML 页面生成规范:代码作为 data 资产 / vfs 工作副本 / 完整自包含可独立成页 / script+CSS 集中放置 / 可引外部 JS/CSS / validate_code 自检 / 安全底线 / 可访问性",
10812
- getContent: () => mf(e, t)
10857
+ getContent: () => _f(e, t)
10813
10858
  };
10814
10859
  }
10815
- function gf(e = {}) {
10860
+ function yf(e = {}) {
10816
10861
  let t = e.vfsPrefix ?? "html/";
10817
10862
  return ({ state: e }) => {
10818
10863
  let n = e.files;
@@ -10820,7 +10865,7 @@ function gf(e = {}) {
10820
10865
  let r = [];
10821
10866
  for (let [e, i] of Object.entries(n)) {
10822
10867
  if (!e.startsWith(t)) continue;
10823
- let n = hd(i.content);
10868
+ let n = vd(i.content);
10824
10869
  for (let t of n) r.push(`${e} 第 ${t.line} 行:${t.message}(${t.code})`);
10825
10870
  }
10826
10871
  return r.length ? {
@@ -10829,7 +10874,7 @@ function gf(e = {}) {
10829
10874
  } : { ok: !0 };
10830
10875
  };
10831
10876
  }
10832
- function _f(e) {
10877
+ function bf(e) {
10833
10878
  let n, i, a = {
10834
10879
  name: "html-validate-tools",
10835
10880
  beforeAgent: (e) => {
@@ -10864,7 +10909,7 @@ function _f(e) {
10864
10909
  }
10865
10910
  let s = [];
10866
10911
  for (let e of o) {
10867
- let t = hd(e.content);
10912
+ let t = vd(e.content);
10868
10913
  t.length && s.push(`${e.path}:\n${t.map((e) => ` 第 ${e.line} 行 ${e.message}(${e.code})`).join("\n")}`);
10869
10914
  }
10870
10915
  return s.length ? `❌ 格式校验未通过:\n${s.join("\n")}\n请用 vfs_edit 修正后重新调用 validate_code 复查。` : `✅ 格式校验通过(${o.map((e) => e.path).join(", ")}:标签闭合等结构合法)。`;
@@ -10882,35 +10927,35 @@ function _f(e) {
10882
10927
  i = e;
10883
10928
  }, a;
10884
10929
  }
10885
- function vf() {
10930
+ function xf() {
10886
10931
  return ({ state: e }) => {
10887
10932
  let t = e.__pgFinalText?.text ?? "";
10888
- return !t || Cd(t).length ? { ok: !0 } : {
10933
+ return !t || Ed(t).length ? { ok: !0 } : {
10889
10934
  ok: !1,
10890
10935
  feedback: "收口回复缺末行交接笔记:请在回复末行补一条 `[note] <一句话实现要点>`(关键设计决策/用户偏好/踩坑,框架会存进组件转交下次维护该组件的 agent;只追加这一行,不要重写其它内容)。"
10891
10936
  };
10892
10937
  };
10893
10938
  }
10894
- var yf = 2;
10895
- function bf(e = {}) {
10939
+ var Sf = 2;
10940
+ function Cf(e = {}) {
10896
10941
  let { writablePaths: t, codeVfsPrefix: n = "html/", id: r = "html", description: i, planning: a = !0, summarization: o = !0, maxToolRounds: s = 12, temperature: c = .4, skills: l, extraTools: u, formatCheck: d = !0, codeField: f = "code", orchestratorPrompt: p = !0, craftNotes: m = !0, llm: h, thinkingMode: g, allowedTools: _, design: v } = e;
10897
10942
  if (t !== void 0 && !Array.isArray(t)) throw Error("[page-agent-sdk][createHtmlSubagent] writablePaths 须为字符串数组(代码组件 data 区,如 [\"components\"])/ 省略以从 schema 自动推断");
10898
10943
  let y = [];
10899
10944
  a && y.push(so());
10900
- let b = d ? df({
10945
+ let b = d ? mf({
10901
10946
  vfsPrefix: n,
10902
10947
  codeField: f,
10903
10948
  writablePaths: t ?? []
10904
10949
  }) : void 0;
10905
10950
  if (d) {
10906
- y.push(_f(n));
10907
- let e = gf({ vfsPrefix: n }), t = b ? ff(e, b.check) : e, r = m ? vf() : void 0, i = Hl({ check: r ? Vl(t, r) : t });
10951
+ y.push(bf(n));
10952
+ let e = yf({ vfsPrefix: n }), t = b ? hf(e, b.check) : e, r = m ? xf() : void 0, i = Hl({ check: r ? Vl(t, r) : t });
10908
10953
  b && (i._setGetController = b.setGetController), y.push(i);
10909
10954
  }
10910
- let x = u ?? [], S = t?.[0] ?? "components", C = l === void 0, w = v === !1 ? null : v === void 0 || v === !0 ? tf() : v, T = (e) => [...C ? [hf(e, f)] : l, ...w ? [w] : []], E = {
10955
+ let x = u ?? [], S = t?.[0] ?? "components", C = l === void 0, w = v === !1 ? null : v === void 0 || v === !0 ? af() : v, T = (e) => [...C ? [vf(e, f)] : l, ...w ? [w] : []], E = {
10911
10956
  id: r,
10912
10957
  description: i ?? `生成/修改纯代码组件(代码作为 data 资产,代码字段 ${f} 随 data 持久化;vfs 作工作副本;能规划(write_todos)+ 执行)。需写代码组件或灵活定制时委派`,
10913
- systemPrompt: pf(n, f, S),
10958
+ systemPrompt: gf(n, f, S),
10914
10959
  ...h ? { llm: h } : {},
10915
10960
  ...g ? { thinkingMode: g } : {},
10916
10961
  writablePaths: t ?? [],
@@ -10924,7 +10969,7 @@ function bf(e = {}) {
10924
10969
  ],
10925
10970
  middleware: y.length ? y : void 0,
10926
10971
  summarization: o === !1 ? void 0 : o,
10927
- maxVerifyAttempts: d ? yf : void 0,
10972
+ maxVerifyAttempts: d ? Sf : void 0,
10928
10973
  temperature: c,
10929
10974
  skills: T(S),
10930
10975
  maxToolRounds: s,
@@ -10939,12 +10984,12 @@ function bf(e = {}) {
10939
10984
  }
10940
10985
  };
10941
10986
  return E._rebuildCodeAssetPaths = (e) => {
10942
- E.systemPrompt = pf(n, f, e), E.skills = T(e), b?.setWritablePaths([e]);
10987
+ E.systemPrompt = gf(n, f, e), E.skills = T(e), b?.setWritablePaths([e]);
10943
10988
  }, E;
10944
10989
  }
10945
10990
  //#endregion
10946
10991
  //#region src/core/sdk/defineTool.ts
10947
- function xf(e) {
10992
+ function wf(e) {
10948
10993
  let t = r(async (t) => {
10949
10994
  let n = await e.handler(t);
10950
10995
  return typeof n == "string" ? n : JSON.stringify(n);
@@ -10957,7 +11002,7 @@ function xf(e) {
10957
11002
  }
10958
11003
  //#endregion
10959
11004
  //#region src/core/sdk/inspectContextTool.ts
10960
- var Sf = t.object({
11005
+ var Tf = t.object({
10961
11006
  path: t.string().optional().describe("分类 key 过滤(如 toolResults/history/systemPrompt/dataHint);不传=全部分类"),
10962
11007
  role: t.enum([
10963
11008
  "user",
@@ -10967,11 +11012,11 @@ var Sf = t.object({
10967
11012
  ]).optional().describe("聚焦每轮首句的角色(assistant→回复摘要,user→问题摘要);不影响工具列表"),
10968
11013
  limit: t.number().int().min(1).max(50).optional().describe("返回最近 N 轮(默认全部;超 50 自动截最近 50 防返回过大)")
10969
11014
  });
10970
- function Cf(e) {
10971
- return xf({
11015
+ function Ef(e) {
11016
+ return wf({
10972
11017
  name: "inspect_context",
10973
11018
  description: "查看当前对话上下文的构成(供压缩决策)。返回:totalTokens(历史轮次 token 总和,与触发判断同口径)、occupancy(窗口占用比)、contextWindow、categories(分类占用)、rounds(每轮 token/工具/首句)。先调用本工具查看构成,再决定压缩策略。",
10974
- schema: Sf,
11019
+ schema: Tf,
10975
11020
  handler: (t) => {
10976
11021
  let n = Cc(e.getMessages()), r = n.length > 50 ? n.slice(n.length - 50) : n, i = (t.limit && r.length > t.limit ? r.slice(r.length - t.limit) : r).map((e) => {
10977
11022
  let n = Fc(e), r = Tc(e), i = t.role === "assistant" ? e.assistantMsgs[0] ?? e.userMsg : e.userMsg, a = wc(typeof i.content == "string" ? i.content : "", 60);
@@ -10994,7 +11039,7 @@ function Cf(e) {
10994
11039
  }
10995
11040
  //#endregion
10996
11041
  //#region src/core/sdk/compressDecision.ts
10997
- var wf = t.object({
11042
+ var Df = t.object({
10998
11043
  keepRounds: t.number().int().min(0).max(50).optional(),
10999
11044
  windowRatio: t.number().min(0).max(1).optional(),
11000
11045
  summarize: t.object({ mode: t.enum(["index", "llm"]) }),
@@ -11004,23 +11049,23 @@ var wf = t.object({
11004
11049
  }).refine((e) => e.keepRounds !== void 0 || e.windowRatio !== void 0, { message: "keepRounds 与 windowRatio 至少填一个(按当前触发模式)" });
11005
11050
  //#endregion
11006
11051
  //#region src/core/sdk/llmResolver.ts
11007
- function Tf(e) {
11052
+ function Of(e) {
11008
11053
  let t = e.find((e) => e.role === "user");
11009
11054
  if (!t) return;
11010
11055
  let n = t.content, r = (typeof n == "string" ? n : Array.isArray(n) ? n.map((e) => typeof e == "string" ? e : e?.text ?? "").join("") : String(n ?? "")).trim().replace(/[\n\r]+/g, " ");
11011
11056
  if (r) return r.length > 30 ? r.slice(0, 30) + "…" : r;
11012
11057
  }
11013
- function Ef(e) {
11058
+ function kf(e) {
11014
11059
  return !!e && typeof e == "object" && typeof e.invoke == "function" && typeof e.stream == "function";
11015
11060
  }
11016
- function Df(e) {
11061
+ function Af(e) {
11017
11062
  let t = e.content;
11018
11063
  return typeof t == "string" ? t : Array.isArray(t) ? t.map((e) => typeof e == "string" ? e : e?.text ?? "").join("") : String(t ?? "");
11019
11064
  }
11020
- function Of(e) {
11065
+ function jf(e) {
11021
11066
  let t = e.summaryLlm ?? e.llm;
11022
11067
  if (!t) return;
11023
- let n = e.summaryTemperature ?? .3, r = e.summaryMaxTokens ?? 2048, i = e.summaryTimeoutMs ?? 15e3, s = Ef(t) ? t : null, c = Ef(t) ? null : t;
11068
+ let n = e.summaryTemperature ?? .3, r = e.summaryMaxTokens ?? 2048, i = e.summaryTimeoutMs ?? 15e3, s = kf(t) ? t : null, c = kf(t) ? null : t;
11024
11069
  if (c && !c.apiKey) {
11025
11070
  e.summaryLlm && console.warn("[page-agent-sdk][summarization] summaryLlm 已配置但缺 apiKey,摘要回退主 agent 模型或零成本索引摘要");
11026
11071
  return;
@@ -11033,16 +11078,16 @@ function Of(e) {
11033
11078
  temperature: n,
11034
11079
  maxTokens: r,
11035
11080
  thinkingFallback: "simple"
11036
- })), Df(await l.invoke([new o("你是对话历史压缩助手。把下面按轮次索引的对话要点,改写成一段连贯、紧凑的中文摘要,保留关键事实、用户意图与已用工具,不要编造。直接输出摘要正文。"), new a(e)], { signal: t.signal })).trim();
11081
+ })), Af(await l.invoke([new o("你是对话历史压缩助手。把下面按轮次索引的对话要点,改写成一段连贯、紧凑的中文摘要,保留关键事实、用户意图与已用工具,不要编造。直接输出摘要正文。"), new a(e)], { signal: t.signal })).trim();
11037
11082
  } finally {
11038
11083
  clearTimeout(s);
11039
11084
  }
11040
11085
  };
11041
11086
  }
11042
- function kf(e) {
11087
+ function Mf(e) {
11043
11088
  let t = e.titleLlm ?? e.summaryLlm ?? e.llm;
11044
11089
  if (!t) return;
11045
- let n = Ef(t) ? t : null, r = Ef(t) ? null : t;
11090
+ let n = kf(t) ? t : null, r = kf(t) ? null : t;
11046
11091
  if (r && !r.apiKey) return;
11047
11092
  let i = n;
11048
11093
  return async (t) => {
@@ -11054,7 +11099,7 @@ function kf(e) {
11054
11099
  thinkingFallback: "simple"
11055
11100
  }));
11056
11101
  let t = await i.invoke([new o(e.i18n?.locale === "en-US" ? "Generate a short English title (max 10 words) summarizing the conversation below. Output the title text only, no quotes or punctuation." : "根据以下对话的主旨,生成一个简短的中文标题(不超过15个字,不要标点和引号,直接输出标题文字)。"), new a(n)], { signal: s.signal }), c = e.i18n?.locale === "en-US" ? 60 : 20;
11057
- return Df(t).trim().replace(/^["'""「『]|["'""」』]$/g, "").split("\n")[0].slice(0, c);
11102
+ return Af(t).trim().replace(/^["'""「『]|["'""」』]$/g, "").split("\n")[0].slice(0, c);
11058
11103
  } catch {
11059
11104
  return "";
11060
11105
  } finally {
@@ -11062,10 +11107,10 @@ function kf(e) {
11062
11107
  }
11063
11108
  };
11064
11109
  }
11065
- function Af() {
11110
+ function Nf() {
11066
11111
  return `call_dec_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
11067
11112
  }
11068
- function jf(e) {
11113
+ function Pf(e) {
11069
11114
  let t = e.match(/```(?:json)?\s*([\s\S]*?)```/), n = t ? t[1] : e, r = n.indexOf("{"), i = n.lastIndexOf("}");
11070
11115
  if (r < 0 || i < 0 || i <= r) return null;
11071
11116
  try {
@@ -11074,21 +11119,21 @@ function jf(e) {
11074
11119
  return null;
11075
11120
  }
11076
11121
  }
11077
- function Mf(e) {
11122
+ function Ff(e) {
11078
11123
  if (!e) return null;
11079
- let t = jf(e);
11124
+ let t = Pf(e);
11080
11125
  if (t == null) return null;
11081
- let n = wf.safeParse(t);
11126
+ let n = Df.safeParse(t);
11082
11127
  return n.success ? n.data : null;
11083
11128
  }
11084
- async function Nf(e, t, n, r) {
11129
+ async function If(e, t, n, r) {
11085
11130
  let i = [...n];
11086
11131
  for (let n = 0; n < 3; n++) {
11087
11132
  let n = await e.invoke(i, { signal: r }), a = n?.tool_calls ?? [];
11088
- if (!a.length) return Df(n).trim();
11133
+ if (!a.length) return Af(n).trim();
11089
11134
  i = [...i, n];
11090
11135
  for (let e of a) {
11091
- let n = e.id ?? Af();
11136
+ let n = e.id ?? Nf();
11092
11137
  try {
11093
11138
  let r = await t.invoke(e.args ?? {}), a = typeof r == "string" ? r : r?.content ?? JSON.stringify(r);
11094
11139
  i = [...i, new s({
@@ -11105,10 +11150,10 @@ async function Nf(e, t, n, r) {
11105
11150
  }
11106
11151
  return "";
11107
11152
  }
11108
- function Pf(e) {
11153
+ function Lf(e) {
11109
11154
  let t = e.summaryLlm ?? e.llm;
11110
11155
  if (!t) return;
11111
- let n = Ef(t) ? t : null, r = Ef(t) ? null : t;
11156
+ let n = kf(t) ? t : null, r = kf(t) ? null : t;
11112
11157
  if (r && !r.apiKey) return;
11113
11158
  let i = e.decisionTimeoutMs ?? 6e3, s = e.decisionMaxTokens ?? 2048, c = n;
11114
11159
  return async (e) => {
@@ -11121,12 +11166,12 @@ function Pf(e) {
11121
11166
  }));
11122
11167
  let n = c;
11123
11168
  if (typeof n.bindTools != "function") return null;
11124
- let i = Cf({
11169
+ let i = Ef({
11125
11170
  getMessages: e.getMessages,
11126
11171
  getSnapshot: e.getSnapshot,
11127
11172
  contextWindow: e.contextWindow
11128
11173
  }), l = n.bindTools([i]), u = e.triggerMode === "token" ? "token 模式:必填 windowRatio(0~1 保留窗口预算比例,如 0.4);keepRounds 可选" : "轮数模式:必填 keepRounds(保留最近几轮,如 6);windowRatio 可选", d = [new o(`你是对话历史压缩决策助手。当前触发模式 = ${e.triggerMode}(${e.triggerReason})。先调用 inspect_context 查看上下文构成,再输出压缩决策 JSON。${u}。仅输出 JSON,不要多余文字/markdown。schema:{keepRounds?(int 0-50), windowRatio?(0-1), summarize:{mode:"index"|"llm"}, recallTopK?(int 0-10), preserveTools?(string[]≤10), reason?(≤200字)}。keepRounds/windowRatio 至少填一个。`), new a(`触发原因:${e.triggerReason}\n上下文窗口:${e.contextWindow ?? "未知"} tokens\n阈值比例:${e.thresholdRatio ?? "未知"}\n\n请决策压缩策略(先 inspect_context 查看,再输出 JSON)。`)];
11129
- return Mf(await Nf(l, i, d, t.signal)) || Mf(await Nf(l, i, [...d, new a("上一次输出无效(JSON 解析失败或 schema 校验不通过)。请只输出符合 schema 的压缩决策 JSON,不要多余文字/markdown 代码块。")], t.signal));
11174
+ return Ff(await If(l, i, d, t.signal)) || Ff(await If(l, i, [...d, new a("上一次输出无效(JSON 解析失败或 schema 校验不通过)。请只输出符合 schema 的压缩决策 JSON,不要多余文字/markdown 代码块。")], t.signal));
11130
11175
  } catch {
11131
11176
  return null;
11132
11177
  } finally {
@@ -11134,8 +11179,8 @@ function Pf(e) {
11134
11179
  }
11135
11180
  };
11136
11181
  }
11137
- function Ff(e) {
11138
- let t = e.llm, n = Ef(e.llm) ? void 0 : e.llm;
11182
+ function Rf(e) {
11183
+ let t = e.llm, n = kf(e.llm) ? void 0 : e.llm;
11139
11184
  return {
11140
11185
  modelCaps: v({
11141
11186
  model: n?.model ?? t?.model ?? t?.modelName,
@@ -11143,14 +11188,14 @@ function Ff(e) {
11143
11188
  maxOutputTokens: e.maxOutputTokens ?? n?.maxOutputTokens ?? t?.maxOutputTokens,
11144
11189
  vision: n?.vision ?? t?.vision
11145
11190
  }),
11146
- summaryLlmInvoke: Of(e),
11147
- titleLlmInvoke: kf(e),
11148
- compressDecisionInvoke: Pf(e)
11191
+ summaryLlmInvoke: jf(e),
11192
+ titleLlmInvoke: Mf(e),
11193
+ compressDecisionInvoke: Lf(e)
11149
11194
  };
11150
11195
  }
11151
11196
  //#endregion
11152
11197
  //#region src/core/sdk/conflictManager.ts
11153
- function If(e, t) {
11198
+ function zf(e, t) {
11154
11199
  let n = /* @__PURE__ */ Vt(null), r = 0;
11155
11200
  function i(i, a) {
11156
11201
  let o = t?.() ?? "ask";
@@ -11196,7 +11241,7 @@ function If(e, t) {
11196
11241
  }
11197
11242
  //#endregion
11198
11243
  //#region src/core/utils/id.ts
11199
- function Lf() {
11244
+ function Bf() {
11200
11245
  try {
11201
11246
  if (typeof crypto < "u" && typeof crypto.randomUUID == "function") return crypto.randomUUID();
11202
11247
  } catch {}
@@ -11204,7 +11249,7 @@ function Lf() {
11204
11249
  }
11205
11250
  //#endregion
11206
11251
  //#region src/core/backends/storage.ts
11207
- var Rf = "chat-sdk", zf = 50 * 1024 * 1024, Bf = 4 * 1024 * 1024, Vf = 10 * 1024 * 1024, Hf = .9, Uf = 500, Wf = 5e3, Gf = 300, Kf = "__meta__", qf = "v:1", Jf = [
11252
+ var Vf = "chat-sdk", Hf = 50 * 1024 * 1024, Uf = 4 * 1024 * 1024, Wf = 10 * 1024 * 1024, Gf = .9, Kf = 500, qf = 5e3, Jf = 300, Yf = "__meta__", Xf = "v:1", Zf = [
11208
11253
  "messages",
11209
11254
  "vfs",
11210
11255
  "todos",
@@ -11216,51 +11261,51 @@ var Rf = "chat-sdk", zf = 50 * 1024 * 1024, Bf = 4 * 1024 * 1024, Vf = 10 * 1024
11216
11261
  "focus",
11217
11262
  "planConfirmation"
11218
11263
  ];
11219
- function Yf(e) {
11220
- return e === "local" || e === "session" ? Bf : zf;
11264
+ function Qf(e) {
11265
+ return e === "local" || e === "session" ? Uf : Hf;
11221
11266
  }
11222
- function Xf(e) {
11267
+ function $f(e) {
11223
11268
  if (typeof e != "object" || !e) return !1;
11224
11269
  let t = e;
11225
11270
  return t.name === "QuotaExceededError" || t.name === "NS_ERROR_DOM_QUOTA_REACHED" || t.code === 22 || t.code === 1014;
11226
11271
  }
11227
- function Zf(e, t, n, r) {
11272
+ function ep(e, t, n, r) {
11228
11273
  return [
11229
- qf,
11274
+ Xf,
11230
11275
  e,
11231
11276
  t,
11232
11277
  n,
11233
11278
  r
11234
11279
  ].join("::");
11235
11280
  }
11236
- function Qf(e, t, n) {
11281
+ function tp(e, t, n) {
11237
11282
  return [
11238
- qf,
11283
+ Xf,
11239
11284
  e,
11240
11285
  t,
11241
11286
  n
11242
11287
  ].join("::") + "::";
11243
11288
  }
11244
- function $f(e, t) {
11289
+ function np(e, t) {
11245
11290
  return [
11246
- qf,
11291
+ Xf,
11247
11292
  e,
11248
11293
  t
11249
11294
  ].join("::") + "::";
11250
11295
  }
11251
- function ep(e) {
11252
- return [qf, e].join("::") + "::";
11296
+ function rp(e) {
11297
+ return [Xf, e].join("::") + "::";
11253
11298
  }
11254
- var tp = null;
11255
- function np(e) {
11256
- tp ||= new TextEncoder();
11299
+ var ip = null;
11300
+ function ap(e) {
11301
+ ip ||= new TextEncoder();
11257
11302
  try {
11258
- return tp.encode(JSON.stringify(e)).length;
11303
+ return ip.encode(JSON.stringify(e)).length;
11259
11304
  } catch {
11260
11305
  return 0;
11261
11306
  }
11262
11307
  }
11263
- function rp(e, t, n) {
11308
+ function op(e, t, n) {
11264
11309
  let r = e.reduce((e, t) => e + t.bytes, 0);
11265
11310
  if (r <= t) return [];
11266
11311
  let i = t * n, a = [...e].sort((e, t) => e.lastAccessed - t.lastAccessed), o = [];
@@ -11270,7 +11315,7 @@ function rp(e, t, n) {
11270
11315
  }
11271
11316
  return o;
11272
11317
  }
11273
- function ip() {
11318
+ function sp() {
11274
11319
  let e = /* @__PURE__ */ new Map();
11275
11320
  return {
11276
11321
  async get(t) {
@@ -11290,7 +11335,7 @@ function ip() {
11290
11335
  }
11291
11336
  };
11292
11337
  }
11293
- function ap(e) {
11338
+ function cp(e) {
11294
11339
  return new Promise((t, n) => {
11295
11340
  if (typeof indexedDB > "u") {
11296
11341
  n(/* @__PURE__ */ Error("indexedDB 不可用"));
@@ -11351,7 +11396,7 @@ function ap(e) {
11351
11396
  }, r.onerror = () => n(r.error);
11352
11397
  });
11353
11398
  }
11354
- function op(e) {
11399
+ function lp(e) {
11355
11400
  return {
11356
11401
  async get(t) {
11357
11402
  let n = e.getItem(t);
@@ -11396,24 +11441,24 @@ function op(e) {
11396
11441
  }
11397
11442
  };
11398
11443
  }
11399
- function sp(e, t, n) {
11444
+ function up(e, t, n) {
11400
11445
  let r = (e.get(t) ?? Promise.resolve()).then(n, n);
11401
11446
  return e.set(t, r.then(() => void 0, () => void 0)), r;
11402
11447
  }
11403
- function cp(e = {}) {
11404
- return up(e, typeof e.backend == "object" && e.backend ? e.backend : void 0);
11448
+ function dp(e = {}) {
11449
+ return pp(e, typeof e.backend == "object" && e.backend ? e.backend : void 0);
11405
11450
  }
11406
- function lp(e, t) {
11407
- return up(e, t);
11451
+ function fp(e, t) {
11452
+ return pp(e, t);
11408
11453
  }
11409
- function up(e = {}, t) {
11410
- let n = e.dbName ?? Rf, r = typeof e.backend == "string" ? e.backend ?? "indexed" : "indexed", i = e.maxBytes ?? Yf(r), a = e.maxBytesPerSession ?? (i === Infinity ? Infinity : Vf), o = e.evictionWatermark ?? Hf, s = e.debounceMs ?? Uf, c = /* @__PURE__ */ new Set();
11454
+ function pp(e = {}, t) {
11455
+ let n = e.dbName ?? Vf, r = typeof e.backend == "string" ? e.backend ?? "indexed" : "indexed", i = e.maxBytes ?? Qf(r), a = e.maxBytesPerSession ?? (i === Infinity ? Infinity : Wf), o = e.evictionWatermark ?? Gf, s = e.debounceMs ?? Kf, c = /* @__PURE__ */ new Set();
11411
11456
  function l(e) {
11412
11457
  for (let t of c) try {
11413
11458
  t(e);
11414
11459
  } catch {}
11415
11460
  }
11416
- let u = ip(), d = !1, f, p = new Promise((e) => {
11461
+ let u = sp(), d = !1, f, p = new Promise((e) => {
11417
11462
  f = e;
11418
11463
  });
11419
11464
  (async () => {
@@ -11424,16 +11469,16 @@ function up(e = {}, t) {
11424
11469
  }
11425
11470
  if (r === "indexed") {
11426
11471
  if (typeof indexedDB > "u") throw Error("indexedDB 不可用");
11427
- u = await ap(n), f(!0);
11472
+ u = await cp(n), f(!0);
11428
11473
  } else if (r === "session") {
11429
11474
  if (typeof sessionStorage > "u") throw Error("sessionStorage 不可用");
11430
- u = op(sessionStorage), f(!0);
11475
+ u = lp(sessionStorage), f(!0);
11431
11476
  } else if (r === "local") {
11432
11477
  if (typeof localStorage > "u") throw Error("localStorage 不可用");
11433
- u = op(localStorage), f(!0);
11434
- } else u = ip(), f(!1);
11478
+ u = lp(localStorage), f(!0);
11479
+ } else u = sp(), f(!1);
11435
11480
  } catch (e) {
11436
- u = ip();
11481
+ u = sp();
11437
11482
  let t = e instanceof Error ? e.message : String(e);
11438
11483
  f(!1), Promise.resolve().then(() => l({
11439
11484
  type: "degraded",
@@ -11443,10 +11488,10 @@ function up(e = {}, t) {
11443
11488
  })();
11444
11489
  let m = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Map(), g = /* @__PURE__ */ new Map();
11445
11490
  function _(e, t, r, i) {
11446
- let o = Zf(n, r, i, Kf);
11447
- return sp(g, o, async () => {
11491
+ let o = ep(n, r, i, Yf);
11492
+ return up(g, o, async () => {
11448
11493
  let n = async () => {
11449
- let n = await u.get(o), s = await u.get(e), c = s == null ? 0 : np(s), d = np(t), f = (n?.bytes ?? 0) + (d - c);
11494
+ let n = await u.get(o), s = await u.get(e), c = s == null ? 0 : ap(s), d = ap(t), f = (n?.bytes ?? 0) + (d - c);
11450
11495
  if (f > a) {
11451
11496
  l({
11452
11497
  type: "quota",
@@ -11468,12 +11513,12 @@ function up(e = {}, t) {
11468
11513
  try {
11469
11514
  await n();
11470
11515
  } catch (e) {
11471
- if (Xf(e) && !d) {
11516
+ if ($f(e) && !d) {
11472
11517
  d = !0;
11473
11518
  try {
11474
11519
  await x();
11475
11520
  } catch {}
11476
- u = ip(), Promise.resolve().then(() => l({
11521
+ u = sp(), Promise.resolve().then(() => l({
11477
11522
  type: "degraded",
11478
11523
  reason: "存储配额超限(QuotaExceededError),已淘汰最旧会话并降级内存"
11479
11524
  }));
@@ -11485,7 +11530,7 @@ function up(e = {}, t) {
11485
11530
  });
11486
11531
  }
11487
11532
  function v(e, t, r, i) {
11488
- let a = Zf(n, e, t, r), o = m.get(a);
11533
+ let a = ep(n, e, t, r), o = m.get(a);
11489
11534
  o && o.resolve();
11490
11535
  let c = h.get(a);
11491
11536
  return c && clearTimeout(c), new Promise((n) => {
@@ -11512,16 +11557,16 @@ function up(e = {}, t) {
11512
11557
  function b() {
11513
11558
  y ||= setTimeout(() => {
11514
11559
  y = null, x();
11515
- }, Gf);
11560
+ }, Jf);
11516
11561
  }
11517
11562
  async function x() {
11518
11563
  if (i !== Infinity) try {
11519
11564
  let e = [];
11520
- await u.scan(ep(n), (t, n) => {
11565
+ await u.scan(rp(n), (t, n) => {
11521
11566
  t.endsWith("::__meta__") && e.push(n);
11522
11567
  });
11523
- let t = rp(e, i, o);
11524
- for (let e of t) await u.clearPrefix(Qf(n, e.agentId, e.sessionId)), l({
11568
+ let t = op(e, i, o);
11569
+ for (let e of t) await u.clearPrefix(tp(n, e.agentId, e.sessionId)), l({
11525
11570
  type: "evicted",
11526
11571
  agentId: e.agentId,
11527
11572
  sessionId: e.sessionId,
@@ -11538,13 +11583,13 @@ function up(e = {}, t) {
11538
11583
  ready: p,
11539
11584
  async listSessions(e) {
11540
11585
  let t = [];
11541
- return await u.scan($f(n, e), (e, n) => {
11586
+ return await u.scan(np(n, e), (e, n) => {
11542
11587
  e.endsWith("::__meta__") && t.push(n);
11543
11588
  }), t.sort((e, t) => t.lastAccessed - e.lastAccessed);
11544
11589
  },
11545
11590
  async load(e, t) {
11546
- let r = Zf(n, e, t, Kf);
11547
- return await sp(g, r, async () => {
11591
+ let r = ep(n, e, t, Yf);
11592
+ return await up(g, r, async () => {
11548
11593
  let i = await u.get(r);
11549
11594
  if (!i) return;
11550
11595
  let a = {
@@ -11553,8 +11598,8 @@ function up(e = {}, t) {
11553
11598
  todos: [],
11554
11599
  memory: ""
11555
11600
  };
11556
- for (let r of Jf) {
11557
- let i = await u.get(Zf(n, e, t, r));
11601
+ for (let r of Zf) {
11602
+ let i = await u.get(ep(n, e, t, r));
11558
11603
  i != null && (a[r] = i);
11559
11604
  }
11560
11605
  i.lastAccessed = Date.now();
@@ -11566,12 +11611,12 @@ function up(e = {}, t) {
11566
11611
  },
11567
11612
  async save(e, t, n) {
11568
11613
  let r = [];
11569
- for (let i of Jf) n[i] !== void 0 && r.push(v(e, t, i, n[i]));
11614
+ for (let i of Zf) n[i] !== void 0 && r.push(v(e, t, i, n[i]));
11570
11615
  await Promise.all(r);
11571
11616
  },
11572
11617
  async updateTitle(e, t, r) {
11573
- let i = Zf(n, e, t, Kf);
11574
- return sp(g, i, async () => {
11618
+ let i = ep(n, e, t, Yf);
11619
+ return up(g, i, async () => {
11575
11620
  let e = await u.get(i);
11576
11621
  e && (e.title = r, e.lastAccessed = Date.now(), await u.set(i, e));
11577
11622
  });
@@ -11581,7 +11626,7 @@ function up(e = {}, t) {
11581
11626
  let t = h.get(e);
11582
11627
  t && (clearTimeout(t), h.delete(e));
11583
11628
  }
11584
- let t = e.flushTimeoutMs ?? Wf, n = Array.from(m.entries());
11629
+ let t = e.flushTimeoutMs ?? qf, n = Array.from(m.entries());
11585
11630
  await Promise.all(n.map(([e, n]) => new Promise((r) => {
11586
11631
  let i;
11587
11632
  _(e, n.value, n.agentId, n.sessionId).then(() => {
@@ -11597,13 +11642,13 @@ function up(e = {}, t) {
11597
11642
  }))), l({ type: "flush" }), x();
11598
11643
  },
11599
11644
  async deleteSession(e, t) {
11600
- let r = Qf(n, e, t);
11645
+ let r = tp(n, e, t);
11601
11646
  for (let [e, t] of m.entries()) e.startsWith(r) && (t.resolve(), m.delete(e));
11602
11647
  for (let [e, t] of h.entries()) e.startsWith(r) && (clearTimeout(t), h.delete(e));
11603
11648
  await u.clearPrefix(r);
11604
11649
  },
11605
11650
  async createSession(e, t, r) {
11606
- let i = r ?? Lf(), a = Date.now(), o = {
11651
+ let i = r ?? Bf(), a = Date.now(), o = {
11607
11652
  agentId: e,
11608
11653
  sessionId: i,
11609
11654
  createdAt: a,
@@ -11612,7 +11657,7 @@ function up(e = {}, t) {
11612
11657
  title: t
11613
11658
  };
11614
11659
  try {
11615
- await u.set(Zf(n, e, i, Kf), o);
11660
+ await u.set(ep(n, e, i, Yf), o);
11616
11661
  } catch {}
11617
11662
  return i;
11618
11663
  },
@@ -11629,15 +11674,15 @@ function up(e = {}, t) {
11629
11674
  }
11630
11675
  //#endregion
11631
11676
  //#region src/core/sdk/optionsResolver.ts
11632
- function dp(e) {
11633
- return e === void 0 ? cp({ backend: "memory" }) : e === !1 ? null : typeof e == "string" ? cp({ backend: e }) : e.enabled === !1 ? null : cp(e);
11677
+ function mp(e) {
11678
+ return e === void 0 ? dp({ backend: "memory" }) : e === !1 ? null : typeof e == "string" ? dp({ backend: e }) : e.enabled === !1 ? null : dp(e);
11634
11679
  }
11635
- function fp(e) {
11680
+ function hp(e) {
11636
11681
  return e.dialog ?? {};
11637
11682
  }
11638
11683
  //#endregion
11639
11684
  //#region src/core/capabilities.ts
11640
- var pp = [
11685
+ var gp = [
11641
11686
  {
11642
11687
  name: "dataOps",
11643
11688
  defaultOn: !0
@@ -11713,13 +11758,13 @@ var pp = [
11713
11758
  requires: ["summarization"]
11714
11759
  }
11715
11760
  ];
11716
- function mp(e) {
11761
+ function _p(e) {
11717
11762
  let t = {};
11718
- for (let n of pp) {
11763
+ for (let n of gp) {
11719
11764
  let r = e?.[n.name];
11720
11765
  t[n.name] = n.defaultOn ? r !== !1 : r === !0;
11721
11766
  }
11722
- for (let e of pp) if (e.requires && t[e.name]) {
11767
+ for (let e of gp) if (e.requires && t[e.name]) {
11723
11768
  for (let n of e.requires) if (!t[n]) {
11724
11769
  t[e.name] = !1;
11725
11770
  break;
@@ -11729,7 +11774,7 @@ function mp(e) {
11729
11774
  }
11730
11775
  //#endregion
11731
11776
  //#region src/core/sdk/events.ts
11732
- function hp(e) {
11777
+ function vp(e) {
11733
11778
  let t = /* @__PURE__ */ new Set(), n = (n) => {
11734
11779
  if (n.type !== "approval_request") {
11735
11780
  if (e) try {
@@ -11755,7 +11800,7 @@ function hp(e) {
11755
11800
  }
11756
11801
  //#endregion
11757
11802
  //#region src/core/sdk/contextPreset.ts
11758
- var gp = {
11803
+ var yp = {
11759
11804
  auto: {
11760
11805
  summaryThresholdRatio: .5,
11761
11806
  windowRatio: .4,
@@ -11783,7 +11828,7 @@ var gp = {
11783
11828
  enableRecall: !0,
11784
11829
  enableLLMSummary: !0
11785
11830
  }
11786
- }, _p = {
11831
+ }, bp = {
11787
11832
  auto: ["describe_data", "read"],
11788
11833
  conservative: ["describe_data"],
11789
11834
  aggressive: ["describe_data", "read"],
@@ -11794,8 +11839,8 @@ var gp = {
11794
11839
  "search_data"
11795
11840
  ]
11796
11841
  };
11797
- function vp(e, t) {
11798
- let n = gp[e.contextPreset ?? "auto"] ?? {}, r = e.contextOptions === !1 ? {} : e.contextOptions ?? {};
11842
+ function xp(e, t) {
11843
+ let n = yp[e.contextPreset ?? "auto"] ?? {}, r = e.contextOptions === !1 ? {} : e.contextOptions ?? {};
11799
11844
  return {
11800
11845
  ...n,
11801
11846
  ...r,
@@ -11805,7 +11850,7 @@ function vp(e, t) {
11805
11850
  }
11806
11851
  //#endregion
11807
11852
  //#region src/core/sdk/middlewareStack.ts
11808
- var yp = {
11853
+ var Sp = {
11809
11854
  dataHint: 10,
11810
11855
  usageHints: 20,
11811
11856
  todos: 30,
@@ -11822,17 +11867,17 @@ var yp = {
11822
11867
  subagents: 140,
11823
11868
  augmentSystem: 150
11824
11869
  };
11825
- function bp(e) {
11870
+ function Cp(e) {
11826
11871
  return e.map((e, t) => ({
11827
11872
  m: e,
11828
11873
  i: t,
11829
- p: yp[e.name] ?? Infinity
11874
+ p: Sp[e.name] ?? Infinity
11830
11875
  })).sort((e, t) => e.p - t.p || e.i - t.i).map((e) => e.m);
11831
11876
  }
11832
11877
  //#endregion
11833
11878
  //#region src/core/tools/fetchDoc.ts
11834
- var xp = 3e4, Sp = [r(async ({ url: e, as: t }) => {
11835
- let n = new AbortController(), r = setTimeout(() => n.abort(), xp);
11879
+ var wp = 3e4, Tp = [r(async ({ url: e, as: t }) => {
11880
+ let n = new AbortController(), r = setTimeout(() => n.abort(), wp);
11836
11881
  try {
11837
11882
  let r = await fetch(e, {
11838
11883
  method: "GET",
@@ -11849,7 +11894,7 @@ var xp = 3e4, Sp = [r(async ({ url: e, as: t }) => {
11849
11894
  ].join("\n");
11850
11895
  } catch (t) {
11851
11896
  let r = t?.message || String(t);
11852
- return n.signal.aborted ? `获取失败:请求超时(${xp}ms,${e})。` : /Failed to fetch|NetworkError|CORS|blocked/i.test(r) ? `获取失败:可能是 CORS 跨域拦截或网络错误(${r})。浏览器仅能 GET 同源或服务端已配置 CORS 的资源;跨域抓取需后端代理。` : `获取失败:${r}`;
11897
+ return n.signal.aborted ? `获取失败:请求超时(${wp}ms,${e})。` : /Failed to fetch|NetworkError|CORS|blocked/i.test(r) ? `获取失败:可能是 CORS 跨域拦截或网络错误(${r})。浏览器仅能 GET 同源或服务端已配置 CORS 的资源;跨域抓取需后端代理。` : `获取失败:${r}`;
11853
11898
  } finally {
11854
11899
  clearTimeout(r);
11855
11900
  }
@@ -11860,7 +11905,7 @@ var xp = 3e4, Sp = [r(async ({ url: e, as: t }) => {
11860
11905
  url: t.string().describe("要抓取的 URL(同源或已配 CORS)"),
11861
11906
  as: t.enum(["text", "markdown"]).optional().describe("返回格式标签,默认 text")
11862
11907
  })
11863
- })], Cp = [
11908
+ })], Ep = [
11864
11909
  "id",
11865
11910
  "class",
11866
11911
  "href",
@@ -11872,12 +11917,12 @@ var xp = 3e4, Sp = [r(async ({ url: e, as: t }) => {
11872
11917
  "aria-label",
11873
11918
  "name",
11874
11919
  "type"
11875
- ], wp = /^(value|srcdoc|formaction|on\w+)$/i, Tp = /token|secret|password|passwd|api[-_]?key|auth|cred|csrf|session/i;
11876
- function Ep(e, t) {
11920
+ ], Dp = /^(value|srcdoc|formaction|on\w+)$/i, Op = /token|secret|password|passwd|api[-_]?key|auth|cred|csrf|session/i;
11921
+ function kp(e, t) {
11877
11922
  if (!e) return null;
11878
- let { depth: n, attrs: r, includeText: i = !0 } = t, a = r !== void 0, o = r ?? Cp, s = (e) => {
11923
+ let { depth: n, attrs: r, includeText: i = !0 } = t, a = r !== void 0, o = r ?? Ep, s = (e) => {
11879
11924
  let t = {};
11880
- for (let n of Array.from(e.attributes)) (a ? o.includes(n.name) : o.includes(n.name) || n.name.startsWith("data-")) && (wp.test(n.name) || Tp.test(n.name) || (t[n.name] = n.value));
11925
+ for (let n of Array.from(e.attributes)) (a ? o.includes(n.name) : o.includes(n.name) || n.name.startsWith("data-")) && (Dp.test(n.name) || Op.test(n.name) || (t[n.name] = n.value));
11881
11926
  return t;
11882
11927
  }, c = (e, t) => {
11883
11928
  let n = {
@@ -11893,10 +11938,10 @@ function Ep(e, t) {
11893
11938
  };
11894
11939
  return c(e, n);
11895
11940
  }
11896
- var Dp = r(({ selector: e, depth: t, attrs: n, includeText: r }) => {
11941
+ var Ap = r(({ selector: e, depth: t, attrs: n, includeText: r }) => {
11897
11942
  let i = e ? document.querySelector(e) : document.body;
11898
11943
  if (!i) return `未找到匹配元素:selector="${e}"`;
11899
- let a = Ep(i, {
11944
+ let a = kp(i, {
11900
11945
  depth: t ?? 3,
11901
11946
  attrs: n,
11902
11947
  includeText: r ?? !0
@@ -11911,22 +11956,22 @@ var Dp = r(({ selector: e, depth: t, attrs: n, includeText: r }) => {
11911
11956
  attrs: t.array(t.string()).optional().describe("属性白名单(传了 = 严格白名单;不传 = 默认常用 + data-*)"),
11912
11957
  includeText: t.boolean().optional().describe("是否包含直接文本(默认 true)")
11913
11958
  })
11914
- }), Op = [Dp], kp = /* @__PURE__ */ "display.position.visibility.opacity.color.background-color.background-image.font-size.font-weight.line-height.text-align.z-index.overflow.width.height.margin.padding.border.border-radius.box-shadow.transform.transition.animation.cursor.pointer-events.flex-direction.gap.max-width.min-height".split("."), Ap = /* @__PURE__ */ new WeakMap(), jp = !1;
11915
- function Mp() {
11916
- if (jp) return;
11959
+ }), jp = [Ap], Mp = /* @__PURE__ */ "display.position.visibility.opacity.color.background-color.background-image.font-size.font-weight.line-height.text-align.z-index.overflow.width.height.margin.padding.border.border-radius.box-shadow.transform.transition.animation.cursor.pointer-events.flex-direction.gap.max-width.min-height".split("."), Np = /* @__PURE__ */ new WeakMap(), Pp = !1;
11960
+ function Fp() {
11961
+ if (Pp) return;
11917
11962
  let e = globalThis.EventTarget;
11918
11963
  if (!e?.prototype?.addEventListener) return;
11919
- jp = !0;
11964
+ Pp = !0;
11920
11965
  let t = e.prototype.addEventListener, n = e.prototype.removeEventListener;
11921
11966
  e.prototype.addEventListener = function(e, ...n) {
11922
11967
  try {
11923
- let t = Ap.get(this);
11924
- t || (t = /* @__PURE__ */ new Map(), Ap.set(this, t)), t.set(String(e), (t.get(String(e)) ?? 0) + 1);
11968
+ let t = Np.get(this);
11969
+ t || (t = /* @__PURE__ */ new Map(), Np.set(this, t)), t.set(String(e), (t.get(String(e)) ?? 0) + 1);
11925
11970
  } catch {}
11926
11971
  return t.call(this, e, ...n);
11927
11972
  }, e.prototype.removeEventListener = function(e, ...t) {
11928
11973
  try {
11929
- let t = Ap.get(this);
11974
+ let t = Np.get(this);
11930
11975
  if (t) {
11931
11976
  let n = (t.get(String(e)) ?? 1) - 1;
11932
11977
  n <= 0 ? t.delete(String(e)) : t.set(String(e), n);
@@ -11935,10 +11980,10 @@ function Mp() {
11935
11980
  return n.call(this, e, ...t);
11936
11981
  };
11937
11982
  }
11938
- function Np(e) {
11939
- return [...Ap.get(e)?.entries() ?? []].filter(([, e]) => e > 0).map(([e]) => e);
11983
+ function Ip(e) {
11984
+ return [...Np.get(e)?.entries() ?? []].filter(([, e]) => e > 0).map(([e]) => e);
11940
11985
  }
11941
- function Pp(e, t = 12) {
11986
+ function Lp(e, t = 12) {
11942
11987
  let n = [], r = e, i = 0;
11943
11988
  for (; r && r.tagName && i < t;) {
11944
11989
  let e = r.tagName.toLowerCase(), t = r.id;
@@ -11959,7 +12004,7 @@ function Pp(e, t = 12) {
11959
12004
  }
11960
12005
  return n.join(" > ");
11961
12006
  }
11962
- function Fp(e, t, n = {}) {
12007
+ function Rp(e, t, n = {}) {
11963
12008
  if (!e) return {
11964
12009
  hits: [],
11965
12010
  total: 0,
@@ -11997,7 +12042,7 @@ function Fp(e, t, n = {}) {
11997
12042
  n = r.slice(Math.max(0, i - 20), i + t.length + 40);
11998
12043
  }
11999
12044
  return {
12000
- selector: Pp(e),
12045
+ selector: Lp(e),
12001
12046
  tag: e.tagName.toLowerCase(),
12002
12047
  text: n.slice(0, 120)
12003
12048
  };
@@ -12006,7 +12051,7 @@ function Fp(e, t, n = {}) {
12006
12051
  truncated: a.length > o
12007
12052
  };
12008
12053
  }
12009
- var Ip = [
12054
+ var zp = [
12010
12055
  "content",
12011
12056
  "display",
12012
12057
  "width",
@@ -12014,14 +12059,14 @@ var Ip = [
12014
12059
  "background-color",
12015
12060
  "position"
12016
12061
  ];
12017
- function Lp(e, t = {}) {
12062
+ function Bp(e, t = {}) {
12018
12063
  if (!e) return null;
12019
12064
  let n = {
12020
- selector: Pp(e),
12065
+ selector: Lp(e),
12021
12066
  tag: e.tagName.toLowerCase(),
12022
12067
  attrs: {}
12023
12068
  };
12024
- for (let t of Array.from(e.attributes)) !(Cp.includes(t.name) || t.name.startsWith("data-")) || wp.test(t.name) || Tp.test(t.name) || (n.attrs[t.name] = t.value);
12069
+ for (let t of Array.from(e.attributes)) !(Ep.includes(t.name) || t.name.startsWith("data-")) || Dp.test(t.name) || Op.test(t.name) || (n.attrs[t.name] = t.value);
12025
12070
  let r = Array.from(e.childNodes).filter((e) => e.nodeType === 3).map((e) => e.textContent || "").join("").trim();
12026
12071
  r && (n.text = r.slice(0, 400));
12027
12072
  let i = String(e.innerText ?? e.textContent ?? "").trim();
@@ -12043,7 +12088,7 @@ function Lp(e, t = {}) {
12043
12088
  if (typeof a != "function") return r;
12044
12089
  try {
12045
12090
  let i = a(e, n ?? null);
12046
- for (let e of n ? Ip : t.styles ?? kp) {
12091
+ for (let e of n ? zp : t.styles ?? Mp) {
12047
12092
  let t = typeof i.getPropertyValue == "function" ? i.getPropertyValue(e) : i[e];
12048
12093
  t && (r[e] = String(t).slice(0, 200));
12049
12094
  }
@@ -12061,16 +12106,16 @@ function Lp(e, t = {}) {
12061
12106
  n.events = {
12062
12107
  inline: t,
12063
12108
  vue: r ? Object.keys(r).filter((e) => /^on[A-Z]/.test(e)).map((e) => e.slice(2).toLowerCase()) : [],
12064
- captured: Np(e)
12109
+ captured: Ip(e)
12065
12110
  };
12066
12111
  }
12067
12112
  return n;
12068
12113
  }
12069
- var Rp = r(({ query: e, mode: t, limit: n, root: r }) => {
12070
- Mp();
12114
+ var Vp = r(({ query: e, mode: t, limit: n, root: r }) => {
12115
+ Fp();
12071
12116
  let i = r ? document.querySelector(r) : document;
12072
12117
  if (r && !i) return `未找到 root 元素:selector="${r}"`;
12073
- let a = Fp(i, e, {
12118
+ let a = Rp(i, e, {
12074
12119
  mode: t,
12075
12120
  limit: n
12076
12121
  });
@@ -12087,11 +12132,11 @@ var Rp = r(({ query: e, mode: t, limit: n, root: r }) => {
12087
12132
  limit: t.number().int().min(1).max(20).optional().describe("返回上限(默认 10)"),
12088
12133
  root: t.string().optional().describe("限定搜索范围的容器选择器(默认整页)")
12089
12134
  })
12090
- }), zp = r(({ selector: e, styles: t, includeHtml: n, htmlLimit: r, includeEvents: i, includeRect: a, pseudo: o }) => {
12091
- Mp();
12135
+ }), Hp = r(({ selector: e, styles: t, includeHtml: n, htmlLimit: r, includeEvents: i, includeRect: a, pseudo: o }) => {
12136
+ Fp();
12092
12137
  let s = document.querySelector(e);
12093
12138
  if (!s) return `未找到匹配元素:selector="${e}"(可先用 dom_search 定位)`;
12094
- let c = Lp(s, {
12139
+ let c = Bp(s, {
12095
12140
  styles: t,
12096
12141
  includeHtml: n,
12097
12142
  htmlLimit: r,
@@ -12112,7 +12157,7 @@ var Rp = r(({ query: e, mode: t, limit: n, root: r }) => {
12112
12157
  includeRect: t.boolean().optional().describe("是否含几何位置(默认 true)"),
12113
12158
  pseudo: t.boolean().optional().describe("是否含 ::before/::after 伪元素摘要(默认 false)")
12114
12159
  })
12115
- }), Bp = {
12160
+ }), Up = {
12116
12161
  name: "dom-inspect",
12117
12162
  description: "页面 DOM 深度检视工具(dom_search 搜索元素 / dom_info 读内容·计算样式·事件绑定·几何)。定位元素、验证样式落地、排查交互绑定时加载",
12118
12163
  getContent: () => [
@@ -12129,15 +12174,15 @@ var Rp = r(({ query: e, mode: t, limit: n, root: r }) => {
12129
12174
  "## 排障套路",
12130
12175
  "1. dom_search(mode:\"text\", query:按钮文案) 定位 → 2. dom_info(styles:[\"display\",\"background-color\",\"pointer-events\"]) 验证样式/点击性 → 3. 不符则改数据(get_dom 看结构对照)"
12131
12176
  ].join("\n"),
12132
- tools: [() => [Rp, zp]]
12177
+ tools: [() => [Vp, Hp]]
12133
12178
  };
12134
12179
  //#endregion
12135
12180
  //#region src/core/tools/envTool.ts
12136
- function Vp(e) {
12181
+ function Wp(e) {
12137
12182
  let t = e;
12138
12183
  return typeof t.tagName == "string" || typeof t.nodeType == "number" && typeof t.nodeName == "string";
12139
12184
  }
12140
- function Hp(e, t = 3, n = 2e3, r, i) {
12185
+ function Gp(e, t = 3, n = 2e3, r, i) {
12141
12186
  if (e == null) return e;
12142
12187
  if (typeof e == "string") return e.length > n ? e.slice(0, n) + "…(已截断)" : e;
12143
12188
  if (typeof e == "number" || typeof e == "boolean") return e;
@@ -12146,14 +12191,14 @@ function Hp(e, t = 3, n = 2e3, r, i) {
12146
12191
  if (typeof e == "bigint") return `${e.toString()}n`;
12147
12192
  if (typeof e != "object") return String(e);
12148
12193
  let a = e;
12149
- if (Vp(a)) {
12194
+ if (Wp(a)) {
12150
12195
  let e = a;
12151
12196
  return e.tagName ? `[Element: <${e.tagName.toLowerCase()}>]` : `[Node: ${e.nodeName}]`;
12152
12197
  }
12153
12198
  if (r?.has(a)) return "[Circular]";
12154
12199
  let o = r ?? /* @__PURE__ */ new WeakSet();
12155
12200
  if (o.add(a), Array.isArray(e)) {
12156
- let r = e.slice(0, 100).map((e) => Hp(e, t - 1, n, o, i));
12201
+ let r = e.slice(0, 100).map((e) => Gp(e, t - 1, n, o, i));
12157
12202
  return e.length > 100 && r.push(`…(共 ${e.length} 项,已截断)`), r;
12158
12203
  }
12159
12204
  if (t < 0) return "(对象,已截断)";
@@ -12166,14 +12211,14 @@ function Hp(e, t = 3, n = 2e3, r, i) {
12166
12211
  }
12167
12212
  try {
12168
12213
  let e = a[r];
12169
- i?.test(r) ? s[r] = "[REDACTED]" : s[r] = Hp(e, t - 1, n, o, i);
12214
+ i?.test(r) ? s[r] = "[REDACTED]" : s[r] = Gp(e, t - 1, n, o, i);
12170
12215
  } catch {
12171
12216
  s[r] = "(getter 抛错)";
12172
12217
  }
12173
12218
  }
12174
12219
  return s;
12175
12220
  }
12176
- function Up(e) {
12221
+ function Kp(e) {
12177
12222
  let t = e ?? (typeof window < "u" ? window : {}), n = t.navigator, r = t.location, i = t.document;
12178
12223
  return {
12179
12224
  location: {
@@ -12206,9 +12251,9 @@ function Up(e) {
12206
12251
  } : "(无 document)"
12207
12252
  };
12208
12253
  }
12209
- var Wp = /^(localStorage|sessionStorage|cookie|document|frames|frameElement|opener|parent|top|self|window|globalThis|closed|history|navigation|trustedTypes|origin|crossOriginIsolated)$/, Gp = /token|secret|password|passwd|api[-_]?key|auth|cred|csrf|session|ticket/i, Kp = r(({ key: e }) => {
12254
+ var qp = /^(localStorage|sessionStorage|cookie|document|frames|frameElement|opener|parent|top|self|window|globalThis|closed|history|navigation|trustedTypes|origin|crossOriginIsolated)$/, Jp = /token|secret|password|passwd|api[-_]?key|auth|cred|csrf|session|ticket/i, Yp = r(({ key: e }) => {
12210
12255
  if (e) {
12211
- if (Wp.test(e) || Gp.test(e)) return JSON.stringify({
12256
+ if (qp.test(e) || Jp.test(e)) return JSON.stringify({
12212
12257
  key: e,
12213
12258
  denied: !0,
12214
12259
  reason: "安全:该 key 在 denylist(localStorage/sessionStorage/cookie/document 或敏感命名 token/secret/key/auth),不读取防泄漏"
@@ -12218,18 +12263,18 @@ var Wp = /^(localStorage|sessionStorage|cookie|document|frames|frameElement|open
12218
12263
  key: e,
12219
12264
  exists: t !== void 0,
12220
12265
  type: typeof t,
12221
- value: Hp(t, 3, 2e3, void 0, Gp)
12266
+ value: Gp(t, 3, 2e3, void 0, Jp)
12222
12267
  }, null, 2);
12223
12268
  }
12224
- return JSON.stringify(Up(), null, 2);
12269
+ return JSON.stringify(Kp(), null, 2);
12225
12270
  }, {
12226
12271
  name: "inspect_env",
12227
12272
  description: "读宿主页面环境信息(排查调试)。不传参返回摘要(URL/origin、浏览器/语言、viewport、title/readyState);传 key 读指定 window 属性值(如 key:\"appConfig\")。只读,大结果自动外存 vfs。",
12228
12273
  schema: t.object({ key: t.string().optional().describe("要读取的 window 属性名(如 \"appConfig\"/\"__DEBUG__\");不传 = 返回环境摘要") })
12229
- }), qp = [Kp];
12274
+ }), Xp = [Yp];
12230
12275
  //#endregion
12231
12276
  //#region src/core/harness/budget.ts
12232
- function Jp(e, t, n) {
12277
+ function Zp(e, t, n) {
12233
12278
  let r = 0;
12234
12279
  return {
12235
12280
  name: "budget",
@@ -12254,12 +12299,12 @@ function Jp(e, t, n) {
12254
12299
  }
12255
12300
  //#endregion
12256
12301
  //#region src/core/sdk/actions.ts
12257
- var Yp = /^[a-zA-Z][a-zA-Z0-9_]*$/;
12258
- function Xp(e) {
12302
+ var Qp = /^[a-zA-Z][a-zA-Z0-9_]*$/;
12303
+ function $p(e) {
12259
12304
  let n = [];
12260
12305
  for (let [i, a] of Object.entries(e)) {
12261
- if (!Yp.test(i)) {
12262
- console.warn(`[page-agent-sdk][actions] 动作名 "${i}" 非法(须匹配 ${Yp}),已跳过`);
12306
+ if (!Qp.test(i)) {
12307
+ console.warn(`[page-agent-sdk][actions] 动作名 "${i}" 非法(须匹配 ${Qp}),已跳过`);
12263
12308
  continue;
12264
12309
  }
12265
12310
  let e = a.description || `宿主动作 ${i}`;
@@ -12279,9 +12324,9 @@ function Xp(e) {
12279
12324
  }
12280
12325
  return n;
12281
12326
  }
12282
- function Zp(e) {
12327
+ function em(e) {
12283
12328
  let t = {};
12284
- for (let [n, r] of Object.entries(e)) Yp.test(n) && (t[n] = {
12329
+ for (let [n, r] of Object.entries(e)) Qp.test(n) && (t[n] = {
12285
12330
  description: r.description,
12286
12331
  hasParams: !!r.params
12287
12332
  });
@@ -12289,12 +12334,12 @@ function Zp(e) {
12289
12334
  }
12290
12335
  //#endregion
12291
12336
  //#region src/core/toolsets.ts
12292
- var Qp = Sp, $p = Op;
12293
- function em(e, t) {
12294
- return fd(e, t);
12337
+ var tm = Tp, nm = jp;
12338
+ function rm(e, t) {
12339
+ return hd(e, t);
12295
12340
  }
12296
- function tm(e, t, n, r, i) {
12297
- let a = mp(e);
12341
+ function im(e, t, n, r, i) {
12342
+ let a = _p(e);
12298
12343
  return [
12299
12344
  ...a.dataOps ? t : [],
12300
12345
  ...a.fetch ? n : [],
@@ -12304,7 +12349,7 @@ function tm(e, t, n, r, i) {
12304
12349
  }
12305
12350
  //#endregion
12306
12351
  //#region src/core/sdk/toolRegistry.ts
12307
- function nm(e) {
12352
+ function am(e) {
12308
12353
  let t = /* @__PURE__ */ new Map(), n = [];
12309
12354
  for (let r of e) for (let e of r.tools) {
12310
12355
  let i = t.get(e.name);
@@ -12324,15 +12369,15 @@ function nm(e) {
12324
12369
  }
12325
12370
  //#endregion
12326
12371
  //#region src/core/harness/usageHints.ts
12327
- var rm = .7;
12328
- function im(e, t, n) {
12329
- let r = mp(e);
12372
+ var om = .7;
12373
+ function sm(e, t, n) {
12374
+ let r = _p(e);
12330
12375
  return {
12331
12376
  name: "usageHints",
12332
12377
  augmentPrompt: (i) => {
12333
12378
  let a = [];
12334
12379
  if (r.planning && (a.push("【自适应规划】按任务复杂度决定是否先规划,不要对简单任务过度编排:"), a.push(" · 简单/明确任务(改单字段、调样式、查值)→ 直接 read/write 执行,不必 write_todos。"), a.push(" · 复杂任务(多步、大改、有歧义、不可逆)→ 先 write_todos 拆解,首个任务标 in_progress,逐项推进。"), a.push(" · 执行中发现步骤要改/补/细分 → 用 update_todo({id, content?, status?}) 按 id 增量改单项,不必重传整个清单。"), a.push(" · update_todo 标 completed 时附 evidence: 本次实际写入的 jsonPath(如 \"components.2\"),供收口对账;工作经委派子 agent 完成等无主写路径时,如实写明完成方式(勿编造路径)。"), e?.humanConfirm ? a.push(" · 规划出多步方案若需用户拍板 → 先 request_human_confirmation 给方案选项,确认后再执行。") : a.push(" · 规划出多步方案若需用户拍板 → 以文字列出方案选项等用户回复,勿自行拍板。"), a.push(" · 计划修订有次数上限(maxPlanRevisions,默认 5,只计 write_todos 调用、调研轮不计):勿反复改计划而不执行,规划充分后即开始 write 落地。")), t && (a.push("改主数据前先 read({jsonPath}) 读其当前真实值(返回末尾 hash=xxx 为乐观锁标识),基于真实值改,不要凭记忆。写入是否被自动校验由集成方 conflictWatchFields 声明决定:若已声明且主数据在你 read 之后被外部改过,会触发冲突——集成方若开启人工介入,工具会挂起等用户决定(保留外部/强制覆盖/回退),你应等待工具返回后按结果继续(保留外部→重新 read 再改;强制覆盖→已写入,继续;回退→已回退到历史快照,基于回退值重写);未开启人工介入时返回 VERSION_CONFLICT 不写入,重新 read 拿最新值再改。"), a.push("读类分流:取值/结构 → read(多路径用 jsonPaths);字段约束 → schema_data;条件筛选定位 → query_data(多条一次用 queries);名字模糊找 → search_data;整体说明 → read 不传路径(= describe_data)。"), a.push("修改大对象/数组优先用 write 增量改({patch:{op,jsonPath,value}} 只发改动部分),避免 write({value}) 整体重传被 max_tokens 截断导致 JSON 不完整、校验失败。"), a.push("修改主数据出错时可用 restore_data 回退最近一次。"), a.push("在大数组里按条件筛选元素用 query_data(JSONPath,如 $.components[?(@.type==\"card\" && @.price<100)]),返回匹配元素的 path/index;定位后再 write({patch}) 改。"), a.push("找名字记不清的元素用 search_data(支持 substring/regex/fuzzy 模糊搜索)。"), a.push("需要过滤/映射/聚合/批量重写大数组时用 eval_script(沙箱脚本,入参 data);只读探查用 mode=query,批量重写用 mode=transform(返回值经校验后落地)。"), a.push("读大数组用 read({jsonPath,offset,limit}) 分页(返回 hasMore=true 时 offset+=limit 续读);一次读多个不相关子路径用 read({jsonPaths});复杂改动先 write({...,dryRun:true}) 预检不落盘。"), a.push("【省轮次·批量】≥2 个路径一律 read({jsonPaths:[...]}) 一次取回(路径互不相关也合批,禁止连续单路径 read);多条件筛选用 query_data({queries:[expr1,expr2,…]}) 一次取回(2-10 条);改多处用 write({patches:[{op:\"set\",jsonPath,value},...]}) 一次提交多改动(原子任一失败回滚),勿逐个 write 烧轮次预算。"), a.push("读到 <subtree Nkb keys:[…] #指纹> 或 <code Nkb> 占位 = 该子树键名/体积可见但内容未见:写入前先窄读全文(read({jsonPath:\"该子树路径\"}),结果根豁免返全文)或 set_focus 聚焦该区域;勿凭键名印象猜路径/猜值直写(直接写占位子树会被拦下要求先窄读)。"), a.push("对比当前与历史快照(或一段 JSON against)的差异用 diff_data({snapshotId?,against?})(返回结构化 path→from/to,verify 自纠/操作审计/\"刚才改了啥\");只读查历史快照值用 history_data({id?,jsonPath?})。")), r.subagent && a.push("独立子任务可 spawn_agent 委派(过程隔离,不占主上下文):默认只读,需要子 agent 写数据时传 writablePaths(路径前缀白名单,越界 PATH_OUT_OF_SCOPE)。多个独立子任务可 spawn_agents 并行委派(各子互不通信,结论由你汇总;并行委派不可授写权限,写操作由你收尾执行)。"), r.inspectEnv && a.push("排查页面环境(当前 URL/浏览器/视口/集成方调试变量)用 inspect_env——不传参返回环境摘要(location/navigator/viewport/document),传 key 读特定 window 属性(如 inspect_env({key:\"appConfig\"}) 读 window.appConfig)。改完数据看渲染、定位\"为何没生效\"时用它(只读,不改数据)。"), r.domInspect && a.push("改完数据想确认渲染是否生效(或定位元素/辅助 UI 设计问答)用 get_dom({selector?,depth?}) 读渲染后 DOM(结构化返回 tag/attrs/text/children,depth 控制深度防爆炸,只读)。配合宿主 actions(save_draft/publish 等)形成\"改数据→get_dom 看渲染→触发动作\"闭环。"), r.draftWrite && (a.push("生成超大 JSON(如 50+ 组件页面,单次 write 受 max_tokens 限制装不下)用 draft_write 分块构建 → draft_commit 原子提交:draft_write({draftId, chunk, mode}) mode:\"start\" 新建/\"append\" 追加(拼 JSON 片段到 drafts 池);累积完 draft_commit({draftId}) 合并 + schema 校验 + 写主数据(失败草稿保留可修后重试,成功自动清草稿)。小改仍用 write patch,只在大 JSON 从零生成时用 draft。"), a.push("⚠️ 大 JSON 分块构建是典型多轮工具调用(draft_write×N + draft_commit + read 确认 + 调研 read/query),默认 maxToolRounds=30(3.43 起;轮次预算吃紧时 system 会注入预算提示段,按提示优先收口);目标组件数很大时集成方仍可在 createChatSdk 显式上调 maxToolRounds(按 N+10 估算)。draft_commit 提交同样走乐观锁(改前 read 拿 hash,bind 被改过会触发冲突介入,不静默覆盖)。")), r.focus && (a.push("【上下文聚焦】判断任务范围,用 set_focus/add_focus/remove_focus/clear_focus 自动收敛工作范围:"), a.push(" · 局部任务(只改某一组件/区域,如「调导航栏」「改 components.3 样式」)→ 先 read 定位 jsonPath,再 set_focus({path:\"该子树路径\"}) 聚焦;聚焦后每轮只看该子树结构,写其他位置会被 PATH_DENIED 拒绝。"), a.push(" · 多个相关组件(如「同时改导航栏和页脚」)→ set_focus 聚焦首个后用 add_focus({path}) 追加其余;聚焦后可写任一焦点子树,越界仍被拒;移除单个用 remove_focus({path})。"), a.push(" · 全局任务(多处/整体结构,如「重排所有组件」「换主题」)→ 不要聚焦,保持全量视野直接写。"), a.push(" · 完成局部精修、要转向其他区域或做整体改动 → 调 clear_focus 退出聚焦(清空全部焦点),恢复全部读写权限。"), a.push(" · set_focus/add_focus 的 path 必须在 schema 内(类型校验);不确定路径先 read/describe_data 查。")), e?.subagents?.length) {
12335
- let t = e.subagents.filter((e) => (e.temperature ?? 0) >= rm || /规划|创意|设计|方案|brainstorm|plan/i.test(e.description)), n = e.subagents.filter((e) => (e.temperature ?? 0) < rm && /反思|审查|挑刺|校验|review|critique|reflect/i.test(e.description));
12380
+ let t = e.subagents.filter((e) => (e.temperature ?? 0) >= om || /规划|创意|设计|方案|brainstorm|plan/i.test(e.description)), n = e.subagents.filter((e) => (e.temperature ?? 0) < om && /反思|审查|挑刺|校验|review|critique|reflect/i.test(e.description));
12336
12381
  a.push("【规划-反思-执行·路由】按任务性质选模式,不要对简单任务过度编排:"), t.length && (a.push(` · 创作/设计/开放性需求(如"设计主题风格""换个感觉")→ 先调 ${t.map((e) => "use_" + e.id).join("/")} 出 2-3 套方案(高温创意),`), a.push(e?.humanConfirm ? " 不要自己拍板;拿到方案后,若需用户拍板用 request_human_confirmation 弹选项。" : " 不要自己拍板;拿到方案后以文字列出选项等用户回复(humanConfirm 未开,勿调不存在工具)。")), n.length && a.push(` · 严谨/易错/校验类 → 可先调 ${n.map((e) => "use_" + e.id).join("/")} 反思挑刺(低温审查),据反馈修订。`), a.push(" · 方案定稿后,由你(主 agent)用 write 落地成 JSON(低温度执行 + schema 校验 + 写前确认)。"), a.push(" · 简单/明确任务(如\"标题改红色\")直接执行,不必走规划-反思。");
12337
12382
  }
12338
12383
  e?.humanConfirm && (a.push("【人工确认·必读】以下情形必须先调 request_human_confirmation 征询用户、拿到答复后再继续,不要自行拍板:"), a.push(" 1) 用户让你「给方案/列选项/我来选/挑一个」时:把每个方案作为一个 option,调 request_human_confirmation(question=简述, options=[方案A,方案B,...], recommendation=你推荐的)。不要只回文字罗列方案让用户自己回复——要用工具把选项做成可点选按钮。"), a.push(" 2) 需求有歧义/不确定时:调工具问清楚(options 不传则用户答同意或拒绝)。"), a.push(" 3) 即将执行高风险不可逆操作(删除/覆盖/批量改动)前:调工具确认。"), a.push(" 4) 规划出多步方案需用户确认时:把整个方案(或关键分步)作为 option 调 request_human_confirmation,确认后再执行。"), a.push("用户在选项里选了哪个,就按那个方案继续;选「拒绝」则停止并询问如何调整。"));
@@ -12352,7 +12397,7 @@ function im(e, t, n) {
12352
12397
  }
12353
12398
  //#endregion
12354
12399
  //#region src/core/harness/resourcesPin.ts
12355
- function am(e) {
12400
+ function cm(e) {
12356
12401
  return {
12357
12402
  name: "resourcesPin",
12358
12403
  augmentPrompt: () => {
@@ -12366,66 +12411,66 @@ function am(e) {
12366
12411
  }
12367
12412
  //#endregion
12368
12413
  //#region src/core/backends/skillStore.ts
12369
- var om = "v:1::skill-store", sm = "chat-sdk";
12370
- function cm(e, t, n) {
12371
- return `${om}::${e}::${t}::${n}`;
12414
+ var lm = "v:1::skill-store", um = "chat-sdk";
12415
+ function dm(e, t, n) {
12416
+ return `${lm}::${e}::${t}::${n}`;
12372
12417
  }
12373
- function lm(e, t) {
12374
- return `${om}::${e}::${t}::`;
12418
+ function fm(e, t) {
12419
+ return `${lm}::${e}::${t}::`;
12375
12420
  }
12376
- function um(e = {}) {
12377
- let t = e.dbName ?? sm, n = e.backend ?? "indexed", r = e.id ?? "", i, a, o = new Promise((e) => {
12421
+ function pm(e = {}) {
12422
+ let t = e.dbName ?? um, n = e.backend ?? "indexed", r = e.id ?? "", i, a, o = new Promise((e) => {
12378
12423
  a = e;
12379
12424
  });
12380
12425
  return (async () => {
12381
12426
  try {
12382
12427
  if (n === "indexed") {
12383
12428
  if (typeof indexedDB > "u") throw Error("indexedDB 不可用");
12384
- i = await ap(t), a(!0);
12429
+ i = await cp(t), a(!0);
12385
12430
  } else if (n === "session") {
12386
12431
  if (typeof sessionStorage > "u") throw Error("sessionStorage 不可用");
12387
- i = op(sessionStorage), a(!0);
12432
+ i = lp(sessionStorage), a(!0);
12388
12433
  } else if (n === "local") {
12389
12434
  if (typeof localStorage > "u") throw Error("localStorage 不可用");
12390
- i = op(localStorage), a(!0);
12391
- } else i = ip(), a(!1);
12435
+ i = lp(localStorage), a(!0);
12436
+ } else i = sp(), a(!1);
12392
12437
  } catch {
12393
- i = ip(), a(!1);
12438
+ i = sp(), a(!1);
12394
12439
  }
12395
12440
  })(), {
12396
12441
  ready: o,
12397
12442
  async list() {
12398
12443
  let e = [];
12399
- return await i.scan(lm(t, r), (t, n) => {
12444
+ return await i.scan(fm(t, r), (t, n) => {
12400
12445
  e.push(n);
12401
12446
  }), e;
12402
12447
  },
12403
12448
  async get(e) {
12404
- return await i.get(cm(t, r, e));
12449
+ return await i.get(dm(t, r, e));
12405
12450
  },
12406
12451
  async put(e) {
12407
12452
  try {
12408
- await i.set(cm(t, r, e.name), e);
12453
+ await i.set(dm(t, r, e.name), e);
12409
12454
  } catch (e) {
12410
- Xf(e) && (i = ip());
12455
+ $f(e) && (i = sp());
12411
12456
  }
12412
12457
  },
12413
12458
  async remove(e) {
12414
- let n = cm(t, r, e);
12459
+ let n = dm(t, r, e);
12415
12460
  return await i.get(n) == null ? !1 : (await i.del(n), !0);
12416
12461
  },
12417
12462
  async clear() {
12418
- await i.clearPrefix(lm(t, r));
12463
+ await i.clearPrefix(fm(t, r));
12419
12464
  },
12420
12465
  dispose() {}
12421
12466
  };
12422
12467
  }
12423
- var dm = /large_results\/[^\s"'`),]+\.txt/g;
12424
- function fm(e) {
12468
+ var mm = /large_results\/[^\s"'`),]+\.txt/g;
12469
+ function hm(e) {
12425
12470
  let t = /* @__PURE__ */ new Set(), n = (e) => {
12426
12471
  if (typeof e != "string" || !e) return;
12427
12472
  let n;
12428
- for (dm.lastIndex = 0; (n = dm.exec(e)) !== null;) t.add(n[0]);
12473
+ for (mm.lastIndex = 0; (n = mm.exec(e)) !== null;) t.add(n[0]);
12429
12474
  };
12430
12475
  for (let r of e) {
12431
12476
  if (n(r.content), r.steps) for (let e of r.steps) n(e.result);
@@ -12433,14 +12478,14 @@ function fm(e) {
12433
12478
  }
12434
12479
  return t;
12435
12480
  }
12436
- function pm(e, t) {
12481
+ function gm(e, t) {
12437
12482
  let n = [];
12438
12483
  for (let r of Object.keys(e)) r.startsWith("large_results/") && !t.has(r) && n.push(r);
12439
12484
  return n;
12440
12485
  }
12441
12486
  //#endregion
12442
12487
  //#region src/core/utils/serialRunner.ts
12443
- function mm() {
12488
+ function _m() {
12444
12489
  let e = Promise.resolve();
12445
12490
  return function(t) {
12446
12491
  let n = e.then(t, t);
@@ -12449,24 +12494,24 @@ function mm() {
12449
12494
  }
12450
12495
  //#endregion
12451
12496
  //#region src/core/sdk/createChatSdk.ts
12452
- var hm = 30, gm = /* @__PURE__ */ new Map();
12453
- function _m(e, t) {
12497
+ var vm = 30, ym = /* @__PURE__ */ new Map();
12498
+ function bm(e, t) {
12454
12499
  return e === "restore_data" ? "restore" : e === "write" ? t?.dryRun ? null : t?.del ? "delete" : t?.patch || t?.patches ? "edit" : "set" : e === "eval_script" ? t?.mode === "transform" ? "edit" : null : e === "draft_commit" || e === "resource_update" ? "edit" : null;
12455
12500
  }
12456
- function vm(e) {
12501
+ function xm(e) {
12457
12502
  return e === "spawn_agent" || e === "spawn_agents" || e.startsWith("use_");
12458
12503
  }
12459
- function ym(e, t, n, r) {
12504
+ function Sm(e, t, n, r) {
12460
12505
  let i = 0;
12461
12506
  return {
12462
12507
  name: "sdk-events",
12463
12508
  wrapToolCall: async (t, r) => {
12464
- let i = await r(t), a = _m(t.name, t.args), o = typeof i.content == "string" && i.content.startsWith("ERROR:");
12509
+ let i = await r(t), a = bm(t.name, t.args), o = typeof i.content == "string" && i.content.startsWith("ERROR:");
12465
12510
  return a && !o ? e({
12466
12511
  type: "data_change",
12467
12512
  operation: a,
12468
12513
  value: n()?.bind
12469
- }) : i.status === "done" && !o && vm(t.name) && e({
12514
+ }) : i.status === "done" && !o && xm(t.name) && e({
12470
12515
  type: "data_change",
12471
12516
  operation: "edit",
12472
12517
  value: n()?.bind
@@ -12494,7 +12539,7 @@ function ym(e, t, n, r) {
12494
12539
  }
12495
12540
  };
12496
12541
  }
12497
- function bm(e, t, n, r, i) {
12542
+ function Cm(e, t, n, r, i) {
12498
12543
  if (!n) return i && console.warn(`[page-agent-sdk][focus] capabilities.focus 关闭,${t} 忽略`), {
12499
12544
  ok: !1,
12500
12545
  error: "capabilities.focus 关闭"
@@ -12512,12 +12557,12 @@ function bm(e, t, n, r, i) {
12512
12557
  error: "当前无主数据 schema,无法聚焦"
12513
12558
  });
12514
12559
  }
12515
- function xm(e, n) {
12560
+ function wm(e, n) {
12516
12561
  let i = {
12517
12562
  prompt_tokens: 0,
12518
12563
  completion_tokens: 0,
12519
12564
  total_tokens: 0
12520
- }, a = If(() => Y, () => e.conflictPolicy ?? "ask"), o = /* @__PURE__ */ Vt(0), s = dp(e.storage);
12565
+ }, a = zf(() => Y, () => e.conflictPolicy ?? "ask"), o = /* @__PURE__ */ Vt(0), s = mp(e.storage);
12521
12566
  s && (e.debug && s.onEvent((e) => console.log("[page-agent-sdk][storage]", e)), s.onEvent((e) => {
12522
12567
  e.type === "quota" && X.agent?.debugLogs?.value?.push({
12523
12568
  timestamp: Date.now(),
@@ -12529,13 +12574,13 @@ function xm(e, n) {
12529
12574
  }
12530
12575
  });
12531
12576
  }));
12532
- let { modelCaps: c, summaryLlmInvoke: l, titleLlmInvoke: u, compressDecisionInvoke: d } = Ff(e), f = c;
12577
+ let { modelCaps: c, summaryLlmInvoke: l, titleLlmInvoke: u, compressDecisionInvoke: d } = Rf(e), f = c;
12533
12578
  if (e.debug && console.log("[page-agent-sdk][modelCaps]", f), f.contextWindow < 2e5) throw Error(`[page-agent-sdk] 模型上下文窗口 ${f.contextWindow} 小于最小支持 ${p}(需 ≥200K 窗口模型,如 GLM-5.2/Claude/Kimi/Qwen-1M/DeepSeek-v4)`);
12534
12579
  {
12535
- let t = e.llm, n = Ef(t) ? t.model ?? t.modelName ?? "" : t.model ?? "", r = Ef(t) ? t.maxTokens ?? f.maxOutputTokens : t.maxTokens ?? h(t.model) ?? f.maxOutputTokens, i = _(n || void 0, f, r);
12580
+ let t = e.llm, n = kf(t) ? t.model ?? t.modelName ?? "" : t.model ?? "", r = kf(t) ? t.maxTokens ?? f.maxOutputTokens : t.maxTokens ?? h(t.model) ?? f.maxOutputTokens, i = _(n || void 0, f, r);
12536
12581
  i && console.warn(i);
12537
12582
  }
12538
- let m = vp(e, f.contextWindow), g = m.enableLLMSummary !== !1, y = (e.contextOptions && e.contextOptions.preserveLastToolResults) ?? _p[e.contextPreset ?? "auto"], b = new Set(y), x = e.llm;
12583
+ let m = xp(e, f.contextWindow), g = m.enableLLMSummary !== !1, y = (e.contextOptions && e.contextOptions.preserveLastToolResults) ?? bp[e.contextPreset ?? "auto"], b = new Set(y), x = e.llm;
12539
12584
  e.debug && !l && console.warn("[page-agent-sdk][summarization] 未构造 llmInvoke(apiKey 缺失?),摘要回退零成本索引摘要");
12540
12585
  let S = /* @__PURE__ */ kt([]), C = xu(e.vfs?.initialFiles, {
12541
12586
  persist: s ? { save: (e) => {
@@ -12591,8 +12636,8 @@ function xm(e, n) {
12591
12636
  let oe = { current: null }, M = e.data ? {
12592
12637
  ...e.data,
12593
12638
  description: e.data.description ?? "主数据对象"
12594
- } : void 0, se = !(e.subagents ?? []).some((e) => e._codeAsset) && mp(e.capabilities).subagent, N = e.subagents;
12595
- se && M?.schema && ts(M.schema).length && (N = [...e.subagents ?? [], bf()], console.info("[page-agent-sdk] 检测到 schema 含代码组件数组(如 components[].code),已自动装配 HTML 代码子 agent(委派编排 + vfs 工作副本 + 格式校验 + 增量 commit)。需定制(codeField/formatCheck/craftNotes 等)请显式传 createHtmlSubagent(...)"));
12639
+ } : void 0, se = !(e.subagents ?? []).some((e) => e._codeAsset) && _p(e.capabilities).subagent, N = e.subagents;
12640
+ se && M?.schema && ts(M.schema).length && (N = [...e.subagents ?? [], Cf()], console.info("[page-agent-sdk] 检测到 schema 含代码组件数组(如 components[].code),已自动装配 HTML 代码子 agent(委派编排 + vfs 工作副本 + 格式校验 + 增量 commit)。需定制(codeField/formatCheck/craftNotes 等)请显式传 createHtmlSubagent(...)"));
12596
12641
  let P = (N ?? []).filter((e) => !!e._codeAsset), F = /* @__PURE__ */ new Set();
12597
12642
  for (let e of P) {
12598
12643
  if (e._codeAsset.writablePaths.length) continue;
@@ -12608,7 +12653,7 @@ function xm(e, n) {
12608
12653
  getTodos: () => oe.current?.getState?.()?.todos ?? [],
12609
12654
  messages: S,
12610
12655
  maxCheckpoints: z && typeof z == "object" ? z.maxCheckpoints : void 0
12611
- }) : null, de = !z || typeof z != "object" || z.auto !== !1, V = mp(e.capabilities), fe = V.dataOps, pe = V.draftWrite, H = V.automation, me = _u({
12656
+ }) : null, de = !z || typeof z != "object" || z.auto !== !1, V = _p(e.capabilities), fe = V.dataOps, pe = V.draftWrite, H = V.automation, me = _u({
12612
12657
  ...e,
12613
12658
  locale: e.i18n?.locale
12614
12659
  });
@@ -12616,7 +12661,7 @@ function xm(e, n) {
12616
12661
  let e = ce.map((e) => e._codeAsset.orchestratorPrompt).filter(Boolean).join("\n\n");
12617
12662
  e && (me += "\n\n" + e);
12618
12663
  } else M?.schema && es(M.schema) && (me += "\n\n" + vs.htmlDirectWriteFallback, console.warn("[page-agent-sdk] 检测到 schema 含 code 字段但未注册 html 子 agent:已自动注入「主 agent 自己写 HTML」编排(code 作普通字段直接 write,无 vfs 工作副本 / 无格式校验门禁)。如需代码资产机制(vfs + 格式校验 + 增量 commit + 主上下文 code 摘要),注册 createHtmlSubagent;若确为降级意图可忽略。"));
12619
- let he = fe && M ? fd(M, {
12664
+ let he = fe && M ? hd(M, {
12620
12665
  onAudit: e.onAudit ?? (e.debug ? (e) => console.log("[page-agent-sdk][data audit]", e) : void 0),
12621
12666
  maxSnapshots: e.maxSnapshots,
12622
12667
  onConflict: a.set,
@@ -12625,7 +12670,7 @@ function xm(e, n) {
12625
12670
  vfsStore: pe || M?.resources?.length ? C : void 0,
12626
12671
  ...le.length ? { pgIdPaths: le } : {},
12627
12672
  ...R.length ? { largeTextPaths: R } : {}
12628
- }) : [], ge = fe ? he : [], U = fe && M ? he.controller ?? null : null, _e = fe && M?.resources?.length && U?.getResourcesSnapshot ? am({ getResourcesSnapshot: () => U?.getResourcesSnapshot?.() ?? [] }) : void 0, W = () => U?.get() ?? M, ve = new Set(he.map((e) => e.name)), ye = e.conflictWatchFields ?? [], be = !ye.includes("*") && ye.length ? new Set(ye) : void 0, xe = U ? Gd({
12673
+ }) : [], ge = fe ? he : [], U = fe && M ? he.controller ?? null : null, _e = fe && M?.resources?.length && U?.getResourcesSnapshot ? cm({ getResourcesSnapshot: () => U?.getResourcesSnapshot?.() ?? [] }) : void 0, W = () => U?.get() ?? M, ve = new Set(he.map((e) => e.name)), ye = e.conflictWatchFields ?? [], be = !ye.includes("*") && ye.length ? new Set(ye) : void 0, xe = U ? Jd({
12629
12674
  getBind: () => W()?.bind,
12630
12675
  recomputeAll: () => U.recomputeAllBaselines?.(),
12631
12676
  hasBaselines: () => U.hasBaselines?.() ?? !1,
@@ -12642,15 +12687,15 @@ function xm(e, n) {
12642
12687
  }
12643
12688
  }), Gt(n));
12644
12689
  }
12645
- }) : void 0, G = /* @__PURE__ */ new Map(), Se = tm(V, ge, Sp, V.domInspect && !V.skills ? [
12646
- ...Op,
12647
- Rp,
12648
- zp
12649
- ] : Op, qp);
12690
+ }) : void 0, G = /* @__PURE__ */ new Map(), Se = im(V, ge, Tp, V.domInspect && !V.skills ? [
12691
+ ...jp,
12692
+ Vp,
12693
+ Hp
12694
+ ] : jp, Xp);
12650
12695
  Se.forEach((e) => G.set(e.name, "builtin"));
12651
12696
  let K = [...e.tools || []];
12652
12697
  K.forEach((e) => G.set(e.name, "user"));
12653
- let Ce = Xp(e.actions ?? {});
12698
+ let Ce = $p(e.actions ?? {});
12654
12699
  Ce.forEach((e) => G.set(e.name, "action"));
12655
12700
  let we = [], Te = !1, Ee = e.humanConfirm !== !1 && (!e.approval || e.approval.humanConfirmTool !== !1), De = Ee ? jl() : null;
12656
12701
  De && G.set(kl, "builtin");
@@ -12723,7 +12768,7 @@ function xm(e, n) {
12723
12768
  let Fe = [], Ie = /* @__PURE__ */ new Map(), q = Le();
12724
12769
  function Le() {
12725
12770
  Ni(K), Ni(Ce), Ni(Fe);
12726
- let { tools: e, collisions: t } = nm([
12771
+ let { tools: e, collisions: t } = am([
12727
12772
  {
12728
12773
  label: "builtin",
12729
12774
  tools: Se
@@ -12800,7 +12845,7 @@ function xm(e, n) {
12800
12845
  timeoutMs: J?.timeoutMs
12801
12846
  }), it = I?.map((e) => {
12802
12847
  if (!e._codeAsset) return e;
12803
- let t = e._codeAsset, n = Ad({
12848
+ let t = e._codeAsset, n = Nd({
12804
12849
  writablePaths: t.writablePaths,
12805
12850
  codeVfsPrefix: t.codeVfsPrefix,
12806
12851
  ext: t.ext,
@@ -12815,16 +12860,16 @@ function xm(e, n) {
12815
12860
  ...e,
12816
12861
  middleware: r
12817
12862
  };
12818
- }), at = L && Ke ? jd() : void 0, ot = at ? Rd({
12863
+ }), at = L && Ke ? Pd() : void 0, ot = at ? Vd({
12819
12864
  getBind: () => W()?.bind,
12820
12865
  writablePaths: le,
12821
12866
  getLocked: () => at.locked(),
12822
12867
  tools: q,
12823
- getCodeFieldPaths: () => Id(W()?.bind, ce.map((e) => ({
12868
+ getCodeFieldPaths: () => zd(W()?.bind, ce.map((e) => ({
12824
12869
  writablePaths: e._codeAsset.writablePaths,
12825
12870
  codeField: e._codeAsset.codeField
12826
12871
  })))
12827
- }) : void 0, st = U?.getSummarizedPaths && U.clearSummarizedPaths ? Vd({
12872
+ }) : void 0, st = U?.getSummarizedPaths && U.clearSummarizedPaths ? Wd({
12828
12873
  getSummarizedPaths: () => U.getSummarizedPaths(),
12829
12874
  clearSummarizedPaths: () => U.clearSummarizedPaths()
12830
12875
  }) : void 0, ct = Ke && it !== void 0 ? hl(it, {
@@ -12847,10 +12892,10 @@ function xm(e, n) {
12847
12892
  timeoutMs: e.subagent?.timeoutMs,
12848
12893
  ...at ? {
12849
12894
  componentLock: at,
12850
- resolveComponents: (e) => Md(e, Ed(W()?.bind, le))
12895
+ resolveComponents: (e) => Fd(e, kd(W()?.bind, le))
12851
12896
  } : {}
12852
12897
  }) : void 0, lt = ct ? ct.controller : null, ut = (t) => {
12853
- let n = t.thinkingMode ?? e.subagent?.thinkingMode, r = n ? Ef(t.llm ?? e.llm) ? "instance-noop" : "applied" : "inherited";
12898
+ let n = t.thinkingMode ?? e.subagent?.thinkingMode, r = n ? kf(t.llm ?? e.llm) ? "instance-noop" : "applied" : "inherited";
12854
12899
  return {
12855
12900
  ...t,
12856
12901
  ...n ? { thinkingMode: n } : {},
@@ -12871,8 +12916,8 @@ function xm(e, n) {
12871
12916
  } : void 0
12872
12917
  }) : void 0, mt = Qe ? cu({
12873
12918
  contextWindow: f.contextWindow,
12874
- thresholdRatio: vp(e, f.contextWindow).summaryThresholdRatio
12875
- }) : void 0, ht = im({
12919
+ thresholdRatio: xp(e, f.contextWindow).summaryThresholdRatio
12920
+ }) : void 0, ht = sm({
12876
12921
  ...V,
12877
12922
  humanConfirm: Ee,
12878
12923
  subagents: I?.map(ut)
@@ -12892,7 +12937,7 @@ function xm(e, n) {
12892
12937
  return;
12893
12938
  }
12894
12939
  }
12895
- } : null, vt = hp(e.onEvent), Y = vt.emit, yt, bt = [], xt = (e) => ({
12940
+ } : null, vt = vp(e.onEvent), Y = vt.emit, yt, bt = [], xt = (e) => ({
12896
12941
  name: e.name,
12897
12942
  description: e.description,
12898
12943
  content: typeof e.getContent == "function" ? e.getContent() : ""
@@ -12900,7 +12945,7 @@ function xm(e, n) {
12900
12945
  name: e.name,
12901
12946
  description: e.description,
12902
12947
  getContent: () => e.content
12903
- }), Ct = e.skillStorage === !1 ? null : um({
12948
+ }), Ct = e.skillStorage === !1 ? null : pm({
12904
12949
  ...typeof e.skillStorage == "object" ? e.skillStorage : {},
12905
12950
  id: e.skillStorage && typeof e.skillStorage == "object" && e.skillStorage.id ? e.skillStorage.id : `agent::${n}`
12906
12951
  }), wt = () => {
@@ -12932,14 +12977,14 @@ function xm(e, n) {
12932
12977
  decideInvoke: d,
12933
12978
  getSnapshot: () => mt?.getSnapshot()
12934
12979
  } : {}
12935
- }) : void 0, Dt = bp([
12980
+ }) : void 0, Dt = Cp([
12936
12981
  ...gt ? [gt] : [],
12937
12982
  ht,
12938
12983
  ...ze ? [T] : [],
12939
12984
  O,
12940
12985
  ee,
12941
12986
  ...Re ? [w] : [],
12942
- ...Ve ? [yt = Sc([...V.domInspect && !(e.skills || []).some((e) => e.name === Bp.name) ? [Bp] : [], ...e.skills || []], {
12987
+ ...Ve ? [yt = Sc([...V.domInspect && !(e.skills || []).some((e) => e.name === Up.name) ? [Up] : [], ...e.skills || []], {
12943
12988
  readVfs: He ? (e) => C.files[e]?.content : void 0,
12944
12989
  onToolsReady: (e, t) => {
12945
12990
  for (let n of t) {
@@ -12965,16 +13010,16 @@ function xm(e, n) {
12965
13010
  ...ct ? [ct] : [],
12966
13011
  ...ot ? [ot] : [],
12967
13012
  ...st ? [st] : [],
12968
- ...U && Ke ? [Wd({ getBind: () => W()?.bind })] : [],
13013
+ ...U && Ke ? [qd({ getBind: () => W()?.bind })] : [],
12969
13014
  ..._t ? [_t] : [],
12970
13015
  ...mt ? [mt] : [],
12971
13016
  ...e.middleware || [],
12972
- ...H ? [Jp(i, {
13017
+ ...H ? [Zp(i, {
12973
13018
  tokenBudget: e.tokenBudget,
12974
13019
  timeBudgetMs: e.timeBudgetMs
12975
13020
  }, Y)] : [],
12976
- ym(Y, S, W, i)
12977
- ]), Ot = e.maxMemoryRounds ?? hm;
13021
+ Sm(Y, S, W, i)
13022
+ ]), Ot = e.maxMemoryRounds ?? vm;
12978
13023
  function At(e) {
12979
13024
  return (e) => {
12980
13025
  e.type !== "approval_request" && Y(e);
@@ -12988,7 +13033,7 @@ function xm(e, n) {
12988
13033
  e.debug && console.warn("[page-agent-sdk][persist] refreshSessions 失败(已吞):", t);
12989
13034
  }
12990
13035
  }
12991
- let Nt = mm(), Pt = /* @__PURE__ */ new Set();
13036
+ let Nt = _m(), Pt = /* @__PURE__ */ new Set();
12992
13037
  function Ft(e) {
12993
13038
  let t = new AbortController(), n = () => t.abort();
12994
13039
  return e && (e.aborted ? t.abort() : e.addEventListener("abort", n, { once: !0 })), Pt.add(t), {
@@ -13097,7 +13142,7 @@ function xm(e, n) {
13097
13142
  code: "IMAGE_UNSUPPORTED_MODEL"
13098
13143
  }), Error(`[page-agent-sdk] ${e}`);
13099
13144
  }
13100
- C?.setProtectedRefs?.(fm(S));
13145
+ C?.setProtectedRefs?.(hm(S));
13101
13146
  let i = H ? t.maxAutoRetries ?? 1 : 0, o = 0, c = !1, l = At(t.signal);
13102
13147
  if (t.signal) {
13103
13148
  let e = () => a.resolve("keep_external");
@@ -13172,7 +13217,7 @@ function xm(e, n) {
13172
13217
  if (await X.initDone, !e.length) return [];
13173
13218
  if (X.refCount <= 0) throw Error("page-agent-sdk: agent 已释放(unmount),拒绝排队中的 batch");
13174
13219
  let r = [], i = At(n);
13175
- if (C?.setProtectedRefs?.(fm(S)), n) {
13220
+ if (C?.setProtectedRefs?.(hm(S)), n) {
13176
13221
  let e = () => a.resolve("keep_external");
13177
13222
  n.aborted ? e() : n.addEventListener("abort", e, { once: !0 });
13178
13223
  }
@@ -13299,7 +13344,7 @@ function xm(e, n) {
13299
13344
  })), e.memory && qt({ memory: j.get() || (typeof e.memory == "string" ? e.memory : "") }), Mt(), Ut = void 0, Wt = !1, X.infoTick.value++, r;
13300
13345
  },
13301
13346
  resetSession: () => {
13302
- It(), a.resolve("keep_external"), X.sessionId = Lf(), S.splice(0, S.length), C.clear?.(), w.reset([]), e.memory || j.reset(""), T.reset(), ae.reset(), A.reset(), Et?.reset(), ee.reset(), te = void 0, B && B.importStack([]), X.agent && (X.agent.debugLogs.value = [], X.agent.resetStaleReadsInvalidated?.()), s && s.createSession(X.agentId, e.session?.title, X.sessionId).catch((t) => {
13347
+ It(), a.resolve("keep_external"), X.sessionId = Bf(), S.splice(0, S.length), C.clear?.(), w.reset([]), e.memory || j.reset(""), T.reset(), ae.reset(), A.reset(), Et?.reset(), ee.reset(), te = void 0, B && B.importStack([]), X.agent && (X.agent.debugLogs.value = [], X.agent.resetStaleReadsInvalidated?.()), s && s.createSession(X.agentId, e.session?.title, X.sessionId).catch((t) => {
13303
13348
  e.debug && console.warn("[page-agent-sdk][persist] createSession 失败(已吞):", t);
13304
13349
  }), Y({
13305
13350
  type: "session_restored",
@@ -13319,7 +13364,7 @@ function xm(e, n) {
13319
13364
  code: "IMAGE_UNSUPPORTED_MODEL"
13320
13365
  }), Error(`[page-agent-sdk] ${e}`);
13321
13366
  }
13322
- C?.setProtectedRefs?.(fm(e));
13367
+ C?.setProtectedRefs?.(hm(e));
13323
13368
  let i = (e) => {
13324
13369
  t?.(e), Y(e), e.type === "subagent" && (e.kind === "tool_call" || e.kind === "tool_result") && X.infoTick.value++;
13325
13370
  };
@@ -13334,7 +13379,7 @@ function xm(e, n) {
13334
13379
  if (X.refCount--, X.refCount <= 0) {
13335
13380
  It(), Te = !0, s && (C.flush?.(), s.flush(), s.dispose()), Ct && Ct.dispose();
13336
13381
  let e = X.mcpClosers.splice(0);
13337
- e.length && Promise.allSettled(e.map((e) => e())), gm.delete(n);
13382
+ e.length && Promise.allSettled(e.map((e) => e())), ym.delete(n);
13338
13383
  }
13339
13384
  },
13340
13385
  resolveConflict: a.resolve,
@@ -13354,14 +13399,14 @@ function xm(e, n) {
13354
13399
  },
13355
13400
  setLlm(t) {
13356
13401
  let n;
13357
- if (Ef(t)) n = t;
13402
+ if (kf(t)) n = t;
13358
13403
  else {
13359
13404
  let e = t;
13360
13405
  if ((e.provider ?? "openai") === "anthropic") throw Error("[page-agent-sdk][setLlm] 切换到 Anthropic 需传 BaseChatModel 实例(动态 import 无法同步);请先 const { ChatAnthropic } = await import(\"@langchain/anthropic\") 构造实例后传入");
13361
13406
  n = E(e);
13362
13407
  }
13363
13408
  typeof n.bindTools != "function" && e.debug && console.warn("[page-agent-sdk][setLlm] 新模型不支持 bindTools(tool calling 会失效)"), x = t;
13364
- let r = Ef(t) ? void 0 : t;
13409
+ let r = kf(t) ? void 0 : t;
13365
13410
  if (f = v({
13366
13411
  model: r?.model ?? t.model ?? t.modelName,
13367
13412
  contextWindow: e.contextWindow ?? r?.contextWindow,
@@ -13405,7 +13450,7 @@ function xm(e, n) {
13405
13450
  return {
13406
13451
  id: n,
13407
13452
  sessionId: X.sessionId,
13408
- model: Ef(x) ? x.model ?? x.modelName : x.model,
13453
+ model: kf(x) ? x.model ?? x.modelName : x.model,
13409
13454
  systemPrompt: X.agent?.getEffectiveSystemPrompt?.() ?? me + gu(W(), e.schemaHint),
13410
13455
  tools: (X.agent?.allTools ?? q).map((e) => ({
13411
13456
  name: e.name,
@@ -13445,7 +13490,7 @@ function xm(e, n) {
13445
13490
  workingMemory: Be ? ae.getWorkingMemory() : void 0,
13446
13491
  focus: ke ? A.getFocus() : void 0,
13447
13492
  focuses: ke ? A.getFocuses() : [],
13448
- actions: Zp(e.actions ?? {}),
13493
+ actions: em(e.actions ?? {}),
13449
13494
  subagent: {
13450
13495
  enabled: !!rt,
13451
13496
  maxDepth: e.subagent?.maxDepth ?? 1,
@@ -13505,7 +13550,7 @@ function xm(e, n) {
13505
13550
  approxBytes: e
13506
13551
  };
13507
13552
  }
13508
- return Zd(Xd({
13553
+ return ef($d({
13509
13554
  debugLogs: X.agent?.debugLogs?.value ?? [],
13510
13555
  messages: X.messages,
13511
13556
  info: t,
@@ -13532,11 +13577,11 @@ function xm(e, n) {
13532
13577
  return ke ? A.getFocuses() : [];
13533
13578
  },
13534
13579
  setFocus(t) {
13535
- let n = bm(t, "setFocus", ke, () => W()?.schema, e.debug);
13580
+ let n = Cm(t, "setFocus", ke, () => W()?.schema, e.debug);
13536
13581
  return n.ok ? (A.setFocus(t), e.debug && A.isInvokeActive() && console.info("[page-agent-sdk][focus] 在途流程进行中,聚焦将在下一次输入生效(当前流程不受影响)"), X.infoTick.value++, { ok: !0 }) : n;
13537
13582
  },
13538
13583
  addFocus(t) {
13539
- let n = bm(t, "addFocus", ke, () => W()?.schema, e.debug);
13584
+ let n = Cm(t, "addFocus", ke, () => W()?.schema, e.debug);
13540
13585
  return n.ok ? A.getFocuses().length >= 8 ? (e.debug && console.warn("[page-agent-sdk][focus] addFocus 拒绝:焦点数已达上限 8(augmentPrompt 注入每焦点子树 schema,过多致 system prompt 超预算)"), {
13541
13586
  ok: !1,
13542
13587
  error: "焦点数上限 8(避免 system prompt 撑爆)"
@@ -13610,14 +13655,14 @@ function xm(e, n) {
13610
13655
  }
13611
13656
  function zt(e) {
13612
13657
  let t = {};
13613
- for (let n of fm(e)) {
13658
+ for (let n of hm(e)) {
13614
13659
  let e = C.files[n];
13615
13660
  e && (t[n] = e.content);
13616
13661
  }
13617
13662
  return t;
13618
13663
  }
13619
13664
  function Bt() {
13620
- let e = pm(C.files, fm(S));
13665
+ let e = gm(C.files, hm(S));
13621
13666
  for (let t of e) delete C.files[t];
13622
13667
  }
13623
13668
  function Ht() {
@@ -13721,7 +13766,7 @@ function xm(e, n) {
13721
13766
  qt({ focus: e.length ? e : null });
13722
13767
  }
13723
13768
  H && B && (qt({ checkpoints: B.exportStack() }), qt({ usage: i }));
13724
- let t = Tf(S);
13769
+ let t = Of(S);
13725
13770
  if (t && t !== Ut && (Ut = t, Jt(X.sessionId, t)), e.autoTitle !== !1 && u && !Wt && S.some((e) => e.role === "user") && S.some((e) => e.role === "assistant")) {
13726
13771
  Wt = !0;
13727
13772
  let e = X.sessionId;
@@ -13799,7 +13844,7 @@ function xm(e, n) {
13799
13844
  }
13800
13845
  }));
13801
13846
  })();
13802
- let t = Ef(e.llm) ? e.llm : await D(e.llm);
13847
+ let t = kf(e.llm) ? e.llm : await D(e.llm);
13803
13848
  X.agent = zo({
13804
13849
  llm: t,
13805
13850
  systemPrompt: me,
@@ -13815,7 +13860,7 @@ function xm(e, n) {
13815
13860
  contextWindow: f.contextWindow,
13816
13861
  maxOutputTokens: f.maxOutputTokens,
13817
13862
  vision: f.vision,
13818
- imageContentFormat: !Ef(e.llm) && (e.llm.provider ?? "openai") === "anthropic" ? "anthropic" : "openai",
13863
+ imageContentFormat: !kf(e.llm) && (e.llm.provider ?? "openai") === "anthropic" ? "anthropic" : "openai",
13819
13864
  maxVerifyAttempts: Ze ? Je : 0,
13820
13865
  roundTokenBudget: e.roundTokenBudget ?? 0,
13821
13866
  staleReadInvalidation: e.staleReadInvalidation,
@@ -13828,12 +13873,12 @@ function xm(e, n) {
13828
13873
  });
13829
13874
  })(), X;
13830
13875
  }
13831
- function Sm(e, t) {
13832
- let n = e.id ?? Lf();
13876
+ function Tm(e, t) {
13877
+ let n = e.id ?? Bf();
13833
13878
  e.id || console.warn(`[page-agent-sdk] 未传 options.id,已生成随机 id "${n}"。刷新后持久化数据无法恢复,请传稳定 id。`);
13834
- let r = e.streaming ?? !0, i = e.ui ?? "default", a, o = e.shareContext ? gm.get(n) : void 0;
13835
- o ? a = o : (a = xm(e, n), e.shareContext && gm.set(n, a)), a.refCount++;
13836
- let s = null, c = fp(e), l = null, u = null;
13879
+ let r = e.streaming ?? !0, i = e.ui ?? "default", a, o = e.shareContext ? ym.get(n) : void 0;
13880
+ o ? a = o : (a = wm(e, n), e.shareContext && ym.set(n, a)), a.refCount++;
13881
+ let s = null, c = hp(e), l = null, u = null;
13837
13882
  async function d(n) {
13838
13883
  if (await a.initDone, s) {
13839
13884
  s.show();
@@ -14056,7 +14101,7 @@ function Sm(e, t) {
14056
14101
  }
14057
14102
  //#endregion
14058
14103
  //#region src/core/sdk/ragSubagent.ts
14059
- function Cm(e, t, n, r, i) {
14104
+ function Em(e, t, n, r, i) {
14060
14105
  let a = [];
14061
14106
  e && a.push("vfs_grep + vfs_read(搜预注入文档)"), t && a.push(`${r}(语义检索)`), n && a.push(`${i}(按 source 加载)`), a.push("fetch_document(公网 URL)");
14062
14107
  let o = [];
@@ -14071,7 +14116,7 @@ function Cm(e, t, n, r, i) {
14071
14116
 
14072
14117
  你是只读检索角色,不要尝试修改任何数据。不要尝试上面未列出的工具。`;
14073
14118
  }
14074
- function wm(e, t, n, r, i) {
14119
+ function Dm(e, t, n, r, i) {
14075
14120
  let a = [], o = [];
14076
14121
  return e && (a.push("- vfs_grep / vfs_read:搜集成方预注入 vfs 的文档(组件文档 / UI 规范)—— 快、静态,先查"), o.push("- 静态文档(组件库文档 / UI 规范):vfs_grep")), t && (a.push(`- ${r}:语义检索(retriever 向量库)—— 模糊匹配,关键词不确定 / 语义相似时用`), o.push(`- 语义相似(「瀑布流组件」「倒计时」「拼团」):${r}`)), n && (a.push(`- ${i}:按 source 精确加载(已知文档 id / URL / key)—— 精确取特定文档`), o.push(`- 已知文档 id / URL:${i}`)), a.push("- fetch_document:公网 URL —— 查公开资料"), o.push("- 公开 URL(设计规范网站 / 第三方文档):fetch_document"), `# 知识检索策略(RAG)
14077
14122
 
@@ -14088,12 +14133,12 @@ ${a.join("\n")}
14088
14133
  ## 何时用何源
14089
14134
  ${o.join("\n")}`;
14090
14135
  }
14091
- var Tm = {
14136
+ var Om = {
14092
14137
  name: "rag-search",
14093
14138
  description: "多源知识检索策略:vfs 预注入文档 → 语义检索 → 指定文档加载 → 公网;综合结构化结论 + 溯源",
14094
- getContent: () => wm(!0, !0, !0, "search_docs", "load_doc")
14139
+ getContent: () => Dm(!0, !0, !0, "search_docs", "load_doc")
14095
14140
  };
14096
- function Em(e, n, i) {
14141
+ function km(e, n, i) {
14097
14142
  let a = r(async ({ query: e, topK: t }) => {
14098
14143
  try {
14099
14144
  let r = await n(e, { topK: t ?? i });
@@ -14111,7 +14156,7 @@ function Em(e, n, i) {
14111
14156
  });
14112
14157
  return Ni([a]), a;
14113
14158
  }
14114
- function Dm(e, n) {
14159
+ function Am(e, n) {
14115
14160
  let i = r(async ({ source: e }) => {
14116
14161
  try {
14117
14162
  let t = await n(e), r = Array.isArray(t) ? t : [t];
@@ -14126,19 +14171,19 @@ function Dm(e, n) {
14126
14171
  });
14127
14172
  return Ni([i]), i;
14128
14173
  }
14129
- function Om(e) {
14174
+ function jm(e) {
14130
14175
  let { retriever: t, loader: n, useVfs: r = !0, id: i = "rag", description: a, topK: o = 5, searchToolName: s = "search_docs", loadToolName: c = "load_doc", maxToolRounds: l = 8, summarization: u, skills: d, extraTools: f } = e;
14131
14176
  if (!t && !n && r === !1) throw Error("[page-agent-sdk][createRagSubagent] 至少配一种知识源:retriever / loader / useVfs(true)");
14132
14177
  let p = [];
14133
- t && p.push(Em(s, t, o)), n && p.push(Dm(c, n)), f && p.push(...f);
14178
+ t && p.push(km(s, t, o)), n && p.push(Am(c, n)), f && p.push(...f);
14134
14179
  let m = r ? [
14135
14180
  "vfs_grep",
14136
14181
  "vfs_read",
14137
14182
  "vfs_json_read"
14138
- ] : void 0, h = Cm(r, !!t, !!n, s, c), g = {
14183
+ ] : void 0, h = Em(r, !!t, !!n, s, c), g = {
14139
14184
  name: "rag-search",
14140
- description: Tm.description,
14141
- getContent: () => wm(r, !!t, !!n, s, c)
14185
+ description: Om.description,
14186
+ getContent: () => Dm(r, !!t, !!n, s, c)
14142
14187
  };
14143
14188
  return {
14144
14189
  id: i,
@@ -14153,7 +14198,7 @@ function Om(e) {
14153
14198
  }
14154
14199
  //#endregion
14155
14200
  //#region src/core/utils/clipboard.ts
14156
- async function km(e) {
14201
+ async function Mm(e) {
14157
14202
  try {
14158
14203
  let t = globalThis.navigator?.clipboard;
14159
14204
  if (t && typeof t.writeText == "function") return await t.writeText(e), !0;
@@ -14171,8 +14216,8 @@ async function km(e) {
14171
14216
  }
14172
14217
  //#endregion
14173
14218
  //#region src/core/composables/useChat.ts
14174
- var Am = 4e3;
14175
- function jm(e = {}) {
14219
+ var Nm = 4e3;
14220
+ function Pm(e = {}) {
14176
14221
  let { fetchResponse: t, fetchStream: n, onPersist: r, onClear: i, onQueuedCleared: a, onBeforeRegenerate: o } = e, s = /* @__PURE__ */ kt({
14177
14222
  messages: e.messages ?? [],
14178
14223
  loading: !1,
@@ -14252,7 +14297,7 @@ function jm(e = {}) {
14252
14297
  let t = e.delta || "";
14253
14298
  n.subReasonFull = (n.subReasonFull || "") + t;
14254
14299
  let r = (n.subReason || "") + t;
14255
- n.subReason = r.length > Am ? r.slice(-4e3) : r;
14300
+ n.subReason = r.length > Nm ? r.slice(-4e3) : r;
14256
14301
  break;
14257
14302
  }
14258
14303
  n.children ||= [];
@@ -14382,7 +14427,7 @@ function jm(e = {}) {
14382
14427
  }
14383
14428
  //#endregion
14384
14429
  //#region src/core/components/icons.ts
14385
- var Mm = {
14430
+ var Fm = {
14386
14431
  header: "🤖",
14387
14432
  subagent: "🤖",
14388
14433
  subagentProgress: "🧬",
@@ -14393,10 +14438,10 @@ var Mm = {
14393
14438
  recommend: "💡",
14394
14439
  conflict: "⚠️"
14395
14440
  };
14396
- function Nm(e) {
14397
- let t = { ...Mm };
14441
+ function Im(e) {
14442
+ let t = { ...Fm };
14398
14443
  if (!e) return t;
14399
- let n = Object.keys(Mm);
14444
+ let n = Object.keys(Fm);
14400
14445
  for (let r of n) {
14401
14446
  let n = e[r];
14402
14447
  typeof n == "string" && (t[r] = n);
@@ -14405,7 +14450,7 @@ function Nm(e) {
14405
14450
  }
14406
14451
  //#endregion
14407
14452
  //#region src/core/components/messages.ts
14408
- var Pm = {
14453
+ var Lm = {
14409
14454
  defaultTitle: "AI 助手",
14410
14455
  inputPlaceholder: "输入消息,Enter 发送...",
14411
14456
  newSession: "新建会话",
@@ -14629,8 +14674,8 @@ var Pm = {
14629
14674
  codeDemoText: "这是一段示例文字,用于展示 CSS 效果。",
14630
14675
  codeDemoButton: "按钮",
14631
14676
  codeDemoInput: "输入框"
14632
- }, Fm = {
14633
- "zh-CN": Pm,
14677
+ }, Rm = {
14678
+ "zh-CN": Lm,
14634
14679
  "en-US": {
14635
14680
  defaultTitle: "AI Assistant",
14636
14681
  inputPlaceholder: "Type a message, Enter to send...",
@@ -14857,10 +14902,10 @@ var Pm = {
14857
14902
  codeDemoInput: "Input"
14858
14903
  }
14859
14904
  };
14860
- function Im(e = "zh-CN", t) {
14905
+ function zm(e = "zh-CN", t) {
14861
14906
  let n = {
14862
- ...Pm,
14863
- ...Fm[e]
14907
+ ...Lm,
14908
+ ...Rm[e]
14864
14909
  };
14865
14910
  if (!t) return n;
14866
14911
  let r = { ...n };
@@ -14872,9 +14917,9 @@ function Im(e = "zh-CN", t) {
14872
14917
  }
14873
14918
  //#endregion
14874
14919
  //#region src/core/composables/chatContext.ts
14875
- var Lm = Symbol("chatContext");
14876
- function Rm(e = {}) {
14877
- let t = jm({
14920
+ var Bm = Symbol("chatContext");
14921
+ function Vm(e = {}) {
14922
+ let t = Pm({
14878
14923
  fetchResponse: e.fetchResponse,
14879
14924
  fetchStream: e.fetchStream,
14880
14925
  messages: e.messages,
@@ -14896,7 +14941,7 @@ function Rm(e = {}) {
14896
14941
  }, h = /* @__PURE__ */ Vt({}), g = (e) => h.value[e] === !0, _ = (e) => {
14897
14942
  h.value[e] = !g(e);
14898
14943
  }, v = /* @__PURE__ */ Vt(!1), y = (e) => {
14899
- km(e).then((e) => {
14944
+ Mm(e).then((e) => {
14900
14945
  e && (v.value = !0, setTimeout(() => {
14901
14946
  v.value = !1;
14902
14947
  }, 1500));
@@ -14958,7 +15003,7 @@ function Rm(e = {}) {
14958
15003
  e.onClearFocus?.();
14959
15004
  }, se = (t) => {
14960
15005
  e.onFocusChipClick?.(t);
14961
- }, N = Nm(e.icons), P = e.locale ?? "zh-CN", F = Im(P, e.dialogMessages);
15006
+ }, N = Im(e.icons), P = e.locale ?? "zh-CN", F = zm(P, e.dialogMessages);
14962
15007
  return {
14963
15008
  chat: t,
14964
15009
  inputText: o,
@@ -15000,15 +15045,15 @@ function Rm(e = {}) {
15000
15045
  toolStepView: e.toolStepView
15001
15046
  };
15002
15047
  }
15003
- function zm() {
15004
- let e = Yn(Lm);
15048
+ function Hm() {
15049
+ let e = Yn(Bm);
15005
15050
  if (!e) throw Error("useChatContext 必须在 provide(chatContextKey) 的组件子树内调用");
15006
15051
  return e;
15007
15052
  }
15008
15053
  //#endregion
15009
15054
  //#region src/core/index.headless.ts
15010
- function Bm(e) {
15011
- return Sm(e);
15055
+ function Um(e) {
15056
+ return Tm(e);
15012
15057
  }
15013
15058
  //#endregion
15014
- export { pp as CAPABILITIES, gp as CONTEXT_PRESETS, wf as CompressDecisionSchema, kp as DEFAULT_COMPUTED_STYLES, zc as DEFAULT_PROMPT_SOFT_CAP, mu as DEFAULT_SYSTEM_PROMPT, pd as HTML_VOID_TAGS, kl as HUMAN_CONFIRM_TOOL_NAME, pi as ImageInputError, g as LOW_CAPS_HINT_BASELINE, p as MIN_CONTEXT_WINDOW, Xi as MODEL_UNAVAILABLE_GUIDANCE, Rc as SOFT_CAP_MIN_WINDOW, Mc as STOP_WORDS, Is as UNSAFE_KEYS, Zp as actionsToInspectInfo, Xp as actionsToTools, li as agentError, su as analyzeContext, Ys as applyPatchToClone, Qs as applyPatchToLive, td as applyPatchesToBind, Yo as arrayMinLength, ci as asAgentError, af as buildCollectorJs, Pp as buildCssPath, gu as buildDataPrompt, Xd as buildDiagnosticsReport, of as buildSandboxSrcdoc, _u as buildSystemPrompt, Lm as chatContextKey, ed as commitSetToBind, ff as composeStructureThenRender, wi as compressImage, pu as connectMcp, D as constructLlmFromConfig, E as constructOpenLlmSync, km as copyText, zo as createAgent, Ol as createApprovalMiddleware, Rm as createChatContext, Bm as createChatSdk, zl as createCheckpointManager, Bl as createCheckpointMiddleware, If as createConflictManager, cu as createContextInspectorMiddleware, vf as createCraftNoteCheck, fd as createDataOps, gf as createHtmlFormatCheck, df as createHtmlRenderCheck, bf as createHtmlSubagent, Ml as createHumanConfirmMiddleware, jl as createHumanConfirmTool, ip as createMemoryBackend, xl as createMemoryMiddleware, u as createProxyLlm, Om as createRagSubagent, ra as createSandboxRunner, hp as createSdkEvents, mm as createSerialRunner, cp as createSessionStore, lp as createSessionStoreWithBackend, um as createSkillStore, fl as createSubagentMiddleware, Kc as createSubagentTracker, hl as createSubagentsMiddleware, im as createUsageHintsMiddleware, Hl as createVerifyMiddleware, xu as createVfs, op as createWebStorageBackend, Jl as createWriteBackCheck, Zi as decorateModelUnavailable, Vs as deepClone, em as defineDataToolset, cc as defineSkill, xf as defineTool, Bs as deleteByPath, Tf as deriveTitle, ls as describeSchemaNode, To as detectGarbledToolCall, nc as diffObjects, zp as domInfoTool, Bp as domInspectSkill, Rp as domSearchTool, Ep as domToStructure, Op as domTools, $p as domToolsStatic, Xo as elementSchemaCandidates, Mp as ensureDomListenerRecorder, Pc as estimateMessageTokens, Fc as estimateRoundTokens, y as estimateTokens, ee as extractReasoningDelta, Ss as extractSchemaHint, lu as extractText, O as extractTextDelta, te as extractUsage, Sp as fetchDocTools, Qp as fetchTools, tc as findStrippedKeys, us as formatConstraints, ii as formatZodIssues, Q as getByPath, Dp as getDomTool, Lp as getElementInfo, Up as getEnvSummary, Np as getRecordedListeners, lf as getSandboxLifecycle, Uo as getSchemaAtPath, Bo as getSchemaTopKeys, qs as hashValue, _s as htmlOrchestratorPrompt, Ic as indexSummarize, Kp as inspectEnvTool, qp as inspectTools, Ef as isChatModel, Ji as isContextLengthError, Yi as isModelUnavailableError, Vo as isPathAllowed, Xf as isQuotaError, Ls as isUnsafePath, pa as jpEval, oi as jsonParseError, Gs as limitDepth, _ as lowCapsHint, Jd as maskUrlCredentials, Us as maybeParseValue, Hd as measureWriteScale, rf as normalizeRenderResult, re as normalizeUsage, x as offloadPassThroughChars, b as offloadThresholdChars, gs as presets, rs as projectBySchema, ns as projectBySchemaDeep, Ws as projectFields, Lc as recallRounds, uf as renderInSandbox, ds as renderSchemaHint, fs as renderSchemaOverview, hs as renderSchemaShallow, mp as resolveCapabilities, vp as resolveContextOptions, fp as resolveDialogConfig, Ff as resolveLlm, v as resolveModelCaps, Vc as resolvePromptSoftCap, Ko as resolveSchemaPath, dp as resolveStorage, ec as restoreInPlace, $s as restoreLive, si as routeError, _a as runSandboxedScript, Rs as safeMerge, Hp as safeSerialize, $ as safeStringify, Jo as schemaHasRefinement, Fp as searchDom, ha as searchJson, tm as selectBuiltinTools, zs as setByPath, Hc as shouldTriggerCompression, Zd as stringifyDiagnosticsReport, vs as systemPromptHelpers, h as tableMaxOutputTokens, Nc as tokenize, Z as toolError, Ho as unwrapSchema, jm as useChat, zm as useChatContext, qo as validateAtPath, hd as validateHtmlFormat, Qu as validateRootValueLocally, $u as validateWriteLocally, Js as watchFieldsHash, e as z, ai as zodError };
15059
+ export { gp as CAPABILITIES, yp as CONTEXT_PRESETS, Df as CompressDecisionSchema, Mp as DEFAULT_COMPUTED_STYLES, zc as DEFAULT_PROMPT_SOFT_CAP, mu as DEFAULT_SYSTEM_PROMPT, gd as HTML_VOID_TAGS, kl as HUMAN_CONFIRM_TOOL_NAME, pi as ImageInputError, g as LOW_CAPS_HINT_BASELINE, p as MIN_CONTEXT_WINDOW, Xi as MODEL_UNAVAILABLE_GUIDANCE, Rc as SOFT_CAP_MIN_WINDOW, Mc as STOP_WORDS, Is as UNSAFE_KEYS, em as actionsToInspectInfo, $p as actionsToTools, li as agentError, su as analyzeContext, Ys as applyPatchToClone, Qs as applyPatchToLive, id as applyPatchesToBind, Yo as arrayMinLength, ci as asAgentError, cf as buildCollectorJs, Lp as buildCssPath, gu as buildDataPrompt, $d as buildDiagnosticsReport, lf as buildSandboxSrcdoc, _u as buildSystemPrompt, Bm as chatContextKey, rd as commitSetToBind, hf as composeStructureThenRender, wi as compressImage, pu as connectMcp, D as constructLlmFromConfig, E as constructOpenLlmSync, Mm as copyText, zo as createAgent, Ol as createApprovalMiddleware, Vm as createChatContext, Um as createChatSdk, zl as createCheckpointManager, Bl as createCheckpointMiddleware, zf as createConflictManager, cu as createContextInspectorMiddleware, xf as createCraftNoteCheck, hd as createDataOps, yf as createHtmlFormatCheck, mf as createHtmlRenderCheck, Cf as createHtmlSubagent, Ml as createHumanConfirmMiddleware, jl as createHumanConfirmTool, sp as createMemoryBackend, xl as createMemoryMiddleware, u as createProxyLlm, jm as createRagSubagent, ra as createSandboxRunner, vp as createSdkEvents, _m as createSerialRunner, dp as createSessionStore, fp as createSessionStoreWithBackend, pm as createSkillStore, fl as createSubagentMiddleware, Kc as createSubagentTracker, hl as createSubagentsMiddleware, sm as createUsageHintsMiddleware, Hl as createVerifyMiddleware, xu as createVfs, lp as createWebStorageBackend, Jl as createWriteBackCheck, Zi as decorateModelUnavailable, Vs as deepClone, rm as defineDataToolset, cc as defineSkill, wf as defineTool, Bs as deleteByPath, Of as deriveTitle, ls as describeSchemaNode, To as detectGarbledToolCall, nc as diffObjects, Hp as domInfoTool, Up as domInspectSkill, Vp as domSearchTool, kp as domToStructure, jp as domTools, nm as domToolsStatic, Xo as elementSchemaCandidates, Fp as ensureDomListenerRecorder, Pc as estimateMessageTokens, Fc as estimateRoundTokens, y as estimateTokens, ee as extractReasoningDelta, Ss as extractSchemaHint, lu as extractText, O as extractTextDelta, te as extractUsage, Tp as fetchDocTools, tm as fetchTools, tc as findStrippedKeys, us as formatConstraints, ii as formatZodIssues, Q as getByPath, Ap as getDomTool, Bp as getElementInfo, Kp as getEnvSummary, Ip as getRecordedListeners, ff as getSandboxLifecycle, Uo as getSchemaAtPath, Bo as getSchemaTopKeys, qs as hashValue, _s as htmlOrchestratorPrompt, Ic as indexSummarize, Yp as inspectEnvTool, Xp as inspectTools, kf as isChatModel, Ji as isContextLengthError, Yi as isModelUnavailableError, Vo as isPathAllowed, $f as isQuotaError, Ls as isUnsafePath, pa as jpEval, oi as jsonParseError, Gs as limitDepth, _ as lowCapsHint, Zd as maskUrlCredentials, Us as maybeParseValue, Gd as measureWriteScale, sf as normalizeRenderResult, re as normalizeUsage, x as offloadPassThroughChars, b as offloadThresholdChars, gs as presets, rs as projectBySchema, ns as projectBySchemaDeep, Ws as projectFields, Lc as recallRounds, pf as renderInSandbox, ds as renderSchemaHint, fs as renderSchemaOverview, hs as renderSchemaShallow, _p as resolveCapabilities, xp as resolveContextOptions, hp as resolveDialogConfig, Rf as resolveLlm, v as resolveModelCaps, Vc as resolvePromptSoftCap, Ko as resolveSchemaPath, mp as resolveStorage, ec as restoreInPlace, $s as restoreLive, si as routeError, _a as runSandboxedScript, Rs as safeMerge, Gp as safeSerialize, $ as safeStringify, Jo as schemaHasRefinement, Rp as searchDom, ha as searchJson, im as selectBuiltinTools, zs as setByPath, Hc as shouldTriggerCompression, ef as stringifyDiagnosticsReport, vs as systemPromptHelpers, h as tableMaxOutputTokens, Nc as tokenize, Z as toolError, Ho as unwrapSchema, Pm as useChat, Hm as useChatContext, qo as validateAtPath, vd as validateHtmlFormat, td as validateRootValueLocally, nd as validateWriteLocally, Js as watchFieldsHash, e as z, ai as zodError };