@rezti/dsh-rez-suite 0.1.22 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +5 -3
  2. package/lib/client.d.ts +2 -16
  3. package/lib/client.js +9 -145
  4. package/lib/index.d.ts +3 -1
  5. package/lib/index.js +108 -222
  6. package/lib/style.css +0 -81
  7. package/package.json +10 -10
  8. package/src/boss/mount.ts +54 -20
  9. package/src/boss/register.ts +50 -11
  10. package/src/boss/seed.ts +55 -18
  11. package/src/client/api.ts +0 -12
  12. package/src/client/index.ts +3 -16
  13. package/src/client/locales.ts +2 -16
  14. package/src/client/panel/panel.module.css +0 -82
  15. package/src/index.ts +9 -8
  16. package/src/protocol.ts +0 -13
  17. package/src/routes.ts +2 -30
  18. package/templates/staff/finance/.agents/skills/staff-finance/SKILL.md +6 -0
  19. package/templates/staff/finance/AGENTS.md +68 -0
  20. package/templates/staff/finance/BOOTSTRAP.md +23 -0
  21. package/templates/staff/finance/IDENTITY.md +8 -0
  22. package/templates/staff/finance/MEMORY.md +9 -0
  23. package/templates/staff/finance/PRIORITIES.md +3 -0
  24. package/templates/staff/finance/SOUL.md +6 -0
  25. package/templates/staff/finance/USER.md +8 -0
  26. package/templates/staff/finance/memory/.gitkeep +0 -0
  27. package/templates/staff/hr/.agents/skills/staff-hr/SKILL.md +6 -0
  28. package/templates/staff/hr/AGENTS.md +52 -0
  29. package/templates/staff/hr/BOOTSTRAP.md +23 -0
  30. package/templates/staff/hr/IDENTITY.md +8 -0
  31. package/templates/staff/hr/MEMORY.md +9 -0
  32. package/templates/staff/hr/PRIORITIES.md +3 -0
  33. package/templates/staff/hr/SOUL.md +6 -0
  34. package/templates/staff/hr/USER.md +8 -0
  35. package/templates/staff/hr/memory/.gitkeep +0 -0
  36. package/templates/staff/legal/.agents/skills/staff-legal/SKILL.md +6 -0
  37. package/templates/staff/legal/AGENTS.md +48 -0
  38. package/templates/staff/legal/BOOTSTRAP.md +23 -0
  39. package/templates/staff/legal/IDENTITY.md +8 -0
  40. package/templates/staff/legal/MEMORY.md +9 -0
  41. package/templates/staff/legal/PRIORITIES.md +3 -0
  42. package/templates/staff/legal/SOUL.md +6 -0
  43. package/templates/staff/legal/USER.md +8 -0
  44. package/templates/staff/legal/memory/.gitkeep +0 -0
  45. package/src/client/upgrade-button.tsx +0 -115
  46. package/src/self-update.ts +0 -155
package/lib/index.js CHANGED
@@ -5,7 +5,6 @@ import { REZ_CREDENTIAL_REFS, REZ_DEFAULT_CONNECTIONS, REZ_SYSTEMS, lastMcpStart
5
5
  import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, statSync, writeFileSync } from "node:fs";
6
6
  import { DatabaseSync } from "node:sqlite";
7
7
  import { fileURLToPath } from "node:url";
8
- import { spawn } from "node:child_process";
9
8
  //#region ../../node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.2/node_modules/@deepseek-ai/cosmokit/lib/index.js
10
9
  /** Return true when a value is `null` or `undefined`. */
11
10
  function isNullable(value) {
@@ -2958,8 +2957,7 @@ const REZ_API = {
2958
2957
  audit: "/api/dsh-rez-suite/audit",
2959
2958
  auditReset: "/api/dsh-rez-suite/audit/reset",
2960
2959
  weixin: "/api/dsh-rez-suite/weixin",
2961
- weixinVerify: "/api/dsh-rez-suite/weixin/verify",
2962
- update: "/api/dsh-rez-suite/update"
2960
+ weixinVerify: "/api/dsh-rez-suite/weixin/verify"
2963
2961
  };
2964
2962
  //#endregion
2965
2963
  //#region src/store.ts
@@ -3222,7 +3220,7 @@ function applyPublicPatch(current, patch) {
3222
3220
  }
3223
3221
  /** Build every /api/dsh-rez-suite route (exact paths). */
3224
3222
  function makeRoutes(deps) {
3225
- const { getConfig, updateConfig, host, tokens, onCredentialWritten, selfUpdate } = deps;
3223
+ const { getConfig, updateConfig, host, tokens, onCredentialWritten } = deps;
3226
3224
  const guard = (req, res, method) => {
3227
3225
  if (!isLoopbackRequest(req)) {
3228
3226
  writeJson(res, 403, { error: "forbidden: loopback-only" });
@@ -3294,31 +3292,6 @@ function makeRoutes(deps) {
3294
3292
  tokens.reset();
3295
3293
  writeJson(res, 200, { ok: true });
3296
3294
  }
3297
- },
3298
- {
3299
- kind: "exact",
3300
- path: REZ_API.update,
3301
- handler: async (req, res) => {
3302
- const method = req.method === "POST" ? "POST" : "GET";
3303
- if (!guard(req, res, method)) return;
3304
- if (selfUpdate === void 0) {
3305
- writeJson(res, 501, { error: "self-update is not available" });
3306
- return;
3307
- }
3308
- try {
3309
- if (method === "GET") {
3310
- writeJson(res, 200, await selfUpdate.status());
3311
- return;
3312
- }
3313
- const result = await selfUpdate.apply();
3314
- writeJson(res, 200, result);
3315
- if (result.restarting) setTimeout(() => {
3316
- selfUpdate.relaunch();
3317
- }, 400);
3318
- } catch (error) {
3319
- writeJson(res, 502, { error: error instanceof Error ? error.message : String(error) });
3320
- }
3321
- }
3322
3295
  }
3323
3296
  ];
3324
3297
  }
@@ -7710,11 +7683,12 @@ function rezConfigTool(config) {
7710
7683
  //#endregion
7711
7684
  //#region src/boss/register.ts
7712
7685
  /**
7713
- * Register or drop the three boss rooms in the official workspace sidebar.
7686
+ * Register or drop workspace rows in the official sidebar.
7714
7687
  * `workspaceRegistry.create` is idempotent: same canonical path returns the
7715
- * existing record. New records are prepended, so we register in reverse to
7716
- * keep 搞钱 → 产品 → 运营 at the top of the sidebar.
7717
- * `delete` only drops the registry row — directories and session logs stay.
7688
+ * existing record. New records are prepended, so we register in reverse then
7689
+ * `insertBefore` to pin 搞钱 → 产品 → 运营 人事助理 财务助理 法务助理
7690
+ * (微信 stays after that block). `delete` only drops the registry row —
7691
+ * directories and session logs stay.
7718
7692
  */
7719
7693
  function canon(path) {
7720
7694
  try {
@@ -7723,18 +7697,41 @@ function canon(path) {
7723
7697
  return path;
7724
7698
  }
7725
7699
  }
7726
- function isRegisteredBossRoom(workspace, rooms) {
7700
+ function isRegisteredRoom(workspace, rooms) {
7727
7701
  return new Set(rooms.map((room) => canon(room.path))).has(canon(workspace.path));
7728
7702
  }
7729
- async function registerBossWorkspaces(registry, rooms) {
7703
+ async function registerWorkspaces(registry, rooms) {
7730
7704
  for (const room of [...rooms].reverse()) await registry.create(room.path, room.folder);
7731
7705
  }
7732
- async function unregisterBossWorkspaces(registry, rooms) {
7706
+ async function unregisterWorkspaces(registry, rooms) {
7733
7707
  for (const workspace of registry.list()) {
7734
- if (!isRegisteredBossRoom(workspace, rooms)) continue;
7708
+ if (!isRegisteredRoom(workspace, rooms)) continue;
7735
7709
  await registry.delete(workspace.id);
7736
7710
  }
7737
7711
  }
7712
+ function findWechatWorkspace(listed) {
7713
+ return listed.find((workspace) => workspace.title === "微信" || /(?:^|\/)微信$/.test(canon(workspace.path).replace(/\\/g, "/")));
7714
+ }
7715
+ /**
7716
+ * Place `rooms` in the given order, immediately before 微信 when that folder
7717
+ * exists. No-op when insertBefore is missing (create-prepend fallback).
7718
+ */
7719
+ async function orderWorkspaces(registry, rooms) {
7720
+ if (typeof registry.insertBefore !== "function" || rooms.length === 0) return;
7721
+ const listed = registry.list();
7722
+ const wechat = findWechatWorkspace(listed);
7723
+ const ids = [];
7724
+ for (const room of rooms) {
7725
+ const rec = listed.find((workspace) => canon(workspace.path) === canon(room.path));
7726
+ if (rec !== void 0) ids.push(rec.id);
7727
+ }
7728
+ if (ids.length === 0) return;
7729
+ const beforeLast = wechat !== void 0 && !ids.includes(wechat.id) ? wechat.id : void 0;
7730
+ for (let index = ids.length - 1; index >= 0; index -= 1) {
7731
+ const before = index === ids.length - 1 ? beforeLast : ids[index + 1];
7732
+ await registry.insertBefore(ids[index], before);
7733
+ }
7734
+ }
7738
7735
  //#endregion
7739
7736
  //#region src/boss/seed.ts
7740
7737
  const BOSS_ROOMS = [
@@ -7751,6 +7748,20 @@ const BOSS_ROOMS = [
7751
7748
  folder: "运营"
7752
7749
  }
7753
7750
  ];
7751
+ const STAFF_ROOMS = [
7752
+ {
7753
+ id: "hr",
7754
+ folder: "人事助理"
7755
+ },
7756
+ {
7757
+ id: "finance",
7758
+ folder: "财务助理"
7759
+ },
7760
+ {
7761
+ id: "legal",
7762
+ folder: "法务助理"
7763
+ }
7764
+ ];
7754
7765
  /** User-owned files. Re-seeding never overwrites these. */
7755
7766
  const LIVING_BASENAMES = /* @__PURE__ */ new Set([
7756
7767
  "USER.md",
@@ -7758,28 +7769,39 @@ const LIVING_BASENAMES = /* @__PURE__ */ new Set([
7758
7769
  "PRIORITIES.md",
7759
7770
  "IDENTITY.md"
7760
7771
  ]);
7761
- function defaultTemplatesRoot() {
7772
+ function findTemplates(kind, marker) {
7762
7773
  const here = fileURLToPath(new URL(".", import.meta.url));
7763
7774
  const candidates = [
7764
- join(here, "../templates/boss"),
7765
- join(here, "../../templates/boss"),
7766
- join(here, "templates/boss")
7775
+ join(here, "../templates", kind),
7776
+ join(here, "../../templates", kind),
7777
+ join(here, "templates", kind)
7767
7778
  ];
7768
- for (const dir of candidates) if (existsSync(join(dir, "money"))) return dir;
7769
- throw new Error("missing boss workspace templates (expected templates/boss/money)");
7779
+ for (const dir of candidates) if (existsSync(join(dir, marker))) return dir;
7780
+ throw new Error(`missing ${kind} workspace templates (expected templates/${kind}/${marker})`);
7770
7781
  }
7771
- function seedBossWorkspaces(options) {
7772
- const templatesRoot = options.templatesRoot ?? defaultTemplatesRoot();
7773
- mkdirSync(options.destRoot, { recursive: true });
7782
+ function defaultBossTemplatesRoot() {
7783
+ return findTemplates("boss", "money");
7784
+ }
7785
+ function defaultStaffTemplatesRoot() {
7786
+ return findTemplates("staff", "hr");
7787
+ }
7788
+ function seedRooms(destRoot, rooms, templatesRoot) {
7789
+ mkdirSync(destRoot, { recursive: true });
7774
7790
  return {
7775
- destRoot: options.destRoot,
7776
- rooms: BOSS_ROOMS.map((room) => seedRoom(templatesRoot, options.destRoot, room))
7791
+ destRoot,
7792
+ rooms: rooms.map((room) => seedRoom(templatesRoot, destRoot, room))
7777
7793
  };
7778
7794
  }
7795
+ function seedBossWorkspaces(options) {
7796
+ return seedRooms(options.destRoot, BOSS_ROOMS, options.templatesRoot ?? defaultBossTemplatesRoot());
7797
+ }
7798
+ function seedStaffWorkspaces(options) {
7799
+ return seedRooms(options.destRoot, STAFF_ROOMS, options.templatesRoot ?? defaultStaffTemplatesRoot());
7800
+ }
7779
7801
  function seedRoom(templatesRoot, destRoot, room) {
7780
7802
  const src = join(templatesRoot, room.id);
7781
7803
  const dest = join(destRoot, room.folder);
7782
- if (!existsSync(src) || !statSync(src).isDirectory()) throw new Error("missing boss workspace template: " + src);
7804
+ if (!existsSync(src) || !statSync(src).isDirectory()) throw new Error("missing workspace template: " + src);
7783
7805
  const created = !existsSync(join(dest, "AGENTS.md"));
7784
7806
  const bootstrapGone = existsSync(join(dest, "AGENTS.md")) && !existsSync(join(dest, "BOOTSTRAP.md"));
7785
7807
  mkdirSync(dest, { recursive: true });
@@ -7831,42 +7853,52 @@ function listFiles(root) {
7831
7853
  }
7832
7854
  //#endregion
7833
7855
  //#region src/boss/mount.ts
7834
- const BOSS_ROLE_HINT = "设置 → 插件 → ReZ-TI → 角色选「老板」后,左侧会出现搞钱 / 产品 / 运营三室。不必手动「添加工作区」。";
7856
+ const STAFF_GUIDANCE = [
7857
+ "侧栏已登记人事助理 / 财务助理 / 法务助理。装完、选身份后自动出现,不必手动「添加工作区」、也不必拖排序。",
7858
+ "三个助理给所有人用。能做什么看当前 Odoo 帐号的可视范围;Harness 只列选项,不自审、不自过账。",
7859
+ "报销走财务助理。搞钱室是战略数字,不要在助理房间里做。"
7860
+ ].join("");
7835
7861
  const BOSS_GUIDANCE = [
7836
- "当前角色是老板。侧栏已登记三室:~/.dsh/workspaces/搞钱、产品、运营。不必手动「添加工作区」。",
7862
+ "当前角色是老板。侧栏已登记搞钱 / 产品 / 运营,后面是人事助理 / 财务助理 / 法务助理。不必手动「添加工作区」。",
7837
7863
  "每个文件夹是独立作战室,官方 dsh 会注入该目录 AGENTS.md。",
7838
7864
  "若该室仍有 BOOTSTRAP.md:本会话先做短问三拍,沉淀到 PRIORITIES.md / MEMORY.md,然后删除 BOOTSTRAP.md。",
7839
- "已初始化后:读 PRIORITIES.md + MEMORY.md + 今日/昨日 memory/;回答固定四行:结论 → 数字(哪家公司、哪段时间)→ 拍板 1~3 件事 → 未执行任何过账/付款/对外发送。",
7840
- "微信文件夹仍是收件箱,不要在那边查账或砍 SKU。"
7865
+ "已初始化后:读 PRIORITIES.md + MEMORY.md + 今日/昨日 memory/;老板三室回答固定四行:结论 → 数字(哪家公司、哪段时间)→ 拍板 1~3 件事 → 未执行任何过账/付款/对外发送。",
7866
+ "微信文件夹仍是收件箱,不要在那边查账、报销或砍 SKU。"
7841
7867
  ].join("");
7842
- function bossGuidanceFor(role) {
7843
- return role === "boss" ? BOSS_GUIDANCE : BOSS_ROLE_HINT;
7868
+ const BOSS_ROLE_HINT = "搞钱 / 产品 / 运营仅角色选「老板」时出现。人事 / 财务 / 法务助理所有角色都会登记。";
7869
+ function workspaceGuidanceFor(role) {
7870
+ return role === "boss" ? BOSS_GUIDANCE : STAFF_GUIDANCE + BOSS_ROLE_HINT;
7844
7871
  }
7845
7872
  function destRoot(env = process.env) {
7846
7873
  if (env.REZ_BOSS_WORKSPACES !== void 0 && env.REZ_BOSS_WORKSPACES !== "") return env.REZ_BOSS_WORKSPACES;
7847
7874
  return join(env.DSH_HOME !== void 0 && env.DSH_HOME !== "" ? env.DSH_HOME : join(homedir(), ".dsh"), "workspaces");
7848
7875
  }
7849
- function expectedBossRooms(env = process.env) {
7876
+ function refsFor(rooms, env) {
7850
7877
  const root = destRoot(env);
7851
- return BOSS_ROOMS.map((room) => ({
7878
+ return rooms.map((room) => ({
7852
7879
  path: join(root, room.folder),
7853
7880
  folder: room.folder
7854
7881
  }));
7855
7882
  }
7856
- async function syncBossWorkspaces(registry, role, env = process.env) {
7857
- if (role === "boss") {
7858
- await registerBossWorkspaces(registry, seedBossWorkspaces({ destRoot: destRoot(env) }).rooms);
7859
- return;
7860
- }
7861
- await unregisterBossWorkspaces(registry, expectedBossRooms(env));
7883
+ function expectedBossRooms(env = process.env) {
7884
+ return refsFor(BOSS_ROOMS, env);
7885
+ }
7886
+ function expectedStaffRooms(env = process.env) {
7887
+ return refsFor(STAFF_ROOMS, env);
7862
7888
  }
7863
- /** Seed/register 三室 only for role=boss; drop sidebar rows otherwise. Returns a re-sync function. */
7864
- function mountBossDesk(ctx, getRole) {
7889
+ async function syncRezWorkspaces(registry, role, env = process.env) {
7890
+ await registerWorkspaces(registry, seedStaffWorkspaces({ destRoot: destRoot(env) }).rooms);
7891
+ if (role === "boss") await registerWorkspaces(registry, seedBossWorkspaces({ destRoot: destRoot(env) }).rooms);
7892
+ else await unregisterWorkspaces(registry, expectedBossRooms(env));
7893
+ await orderWorkspaces(registry, role === "boss" ? [...expectedBossRooms(env), ...expectedStaffRooms(env)] : expectedStaffRooms(env));
7894
+ }
7895
+ /** Seed/register staff for every role; boss rooms only when role=boss. */
7896
+ function mountRezWorkspaces(ctx, getRole) {
7865
7897
  const run = () => {
7866
7898
  ctx.inject(["workspaceRegistry"], (inner) => {
7867
- syncBossWorkspaces(inner.get("workspaceRegistry"), getRole()).catch((error) => {
7899
+ syncRezWorkspaces(inner.get("workspaceRegistry"), getRole()).catch((error) => {
7868
7900
  const why = error instanceof Error ? error.message : String(error);
7869
- console.error("[dsh-rez-suite] boss workspace sync failed:", why);
7901
+ console.error("[dsh-rez-suite] workspace sync failed:", why);
7870
7902
  });
7871
7903
  });
7872
7904
  };
@@ -7874,153 +7906,6 @@ function mountBossDesk(ctx, getRole) {
7874
7906
  return run;
7875
7907
  }
7876
7908
  //#endregion
7877
- //#region src/self-update.ts
7878
- /**
7879
- * In-place upgrade of @rezti/dsh-rez-suite inside the running dsh profile.
7880
- * pnpm add writes the new bits; Node cannot replace an already-imported host
7881
- * module, so we respawn the same argv after the HTTP response flushes.
7882
- */
7883
- const SUITE_PACKAGE = "@rezti/dsh-rez-suite";
7884
- const NPM_LATEST = "https://registry.npmjs.org/@rezti/dsh-rez-suite/latest";
7885
- const PNPM_TIMEOUT_MS = 18e4;
7886
- function compareVersions(left, right) {
7887
- const a = left.split(".").map((part) => Number.parseInt(part, 10) || 0);
7888
- const b = right.split(".").map((part) => Number.parseInt(part, 10) || 0);
7889
- const n = Math.max(a.length, b.length);
7890
- for (let i = 0; i < n; i += 1) {
7891
- const av = a[i] ?? 0;
7892
- const bv = b[i] ?? 0;
7893
- if (av > bv) return 1;
7894
- if (av < bv) return -1;
7895
- }
7896
- return 0;
7897
- }
7898
- function readInstalledVersion(packageDir) {
7899
- const raw = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
7900
- if (typeof raw.version !== "string" || raw.version === "") throw new Error("suite package.json missing version");
7901
- return raw.version;
7902
- }
7903
- function findProfileDir(startDir) {
7904
- let dir = startDir;
7905
- for (let i = 0; i < 12; i += 1) {
7906
- const manifest = join(dir, "package.json");
7907
- if (existsSync(manifest)) try {
7908
- const raw = JSON.parse(readFileSync(manifest, "utf8"));
7909
- if (Array.isArray(raw.dsh?.profile?.bundles)) return dir;
7910
- } catch {}
7911
- const parent = dirname(dir);
7912
- if (parent === dir) break;
7913
- dir = parent;
7914
- }
7915
- throw new Error("cannot find dsh profile directory (no package.json with dsh.profile.bundles)");
7916
- }
7917
- function shellQuote(value) {
7918
- return `'${value.replaceAll("'", `'\\''`)}'`;
7919
- }
7920
- function relaunchScript(argv, parentPid) {
7921
- return `while kill -0 ${parentPid} 2>/dev/null; do sleep 0.15; done; sleep 0.25; exec ${argv.map(shellQuote).join(" ")}`;
7922
- }
7923
- async function fetchLatestVersion(fetchImpl = fetch) {
7924
- const response = await fetchImpl(NPM_LATEST, { headers: { accept: "application/json" } });
7925
- if (!response.ok) throw new Error(`npm registry HTTP ${response.status}`);
7926
- const body = await response.json();
7927
- if (typeof body.version !== "string" || body.version === "") throw new Error("npm registry missing version");
7928
- return body.version;
7929
- }
7930
- function runPnpmAdd(cwd, spec, env = process.env) {
7931
- return new Promise((resolve, reject) => {
7932
- const child = spawn("pnpm", ["add", spec], {
7933
- cwd,
7934
- env,
7935
- stdio: [
7936
- "ignore",
7937
- "pipe",
7938
- "pipe"
7939
- ]
7940
- });
7941
- let stderr = "";
7942
- child.stderr.on("data", (chunk) => {
7943
- stderr += chunk.toString();
7944
- });
7945
- const timer = setTimeout(() => {
7946
- child.kill("SIGTERM");
7947
- reject(/* @__PURE__ */ new Error("pnpm add timed out after 3 minutes"));
7948
- }, PNPM_TIMEOUT_MS);
7949
- child.on("error", (error) => {
7950
- clearTimeout(timer);
7951
- reject(error);
7952
- });
7953
- child.on("close", (code) => {
7954
- clearTimeout(timer);
7955
- if (code === 0) resolve();
7956
- else reject(new Error(stderr.trim() || `pnpm add exited ${String(code)}`));
7957
- });
7958
- });
7959
- }
7960
- function spawnRelaunch(argv, parentPid, cwd, env = process.env) {
7961
- spawn("/bin/bash", ["-c", relaunchScript(argv, parentPid)], {
7962
- cwd,
7963
- env,
7964
- detached: true,
7965
- stdio: "ignore"
7966
- }).unref();
7967
- }
7968
- let inflight;
7969
- function createSelfUpdate(io) {
7970
- const status = async () => {
7971
- const installed = readInstalledVersion(io.packageDir);
7972
- const latest = await io.fetchLatest();
7973
- return {
7974
- package: SUITE_PACKAGE,
7975
- installed,
7976
- latest,
7977
- outdated: compareVersions(latest, installed) > 0
7978
- };
7979
- };
7980
- const apply = async () => {
7981
- if (inflight !== void 0) throw new Error("upgrade already running");
7982
- const work = (async () => {
7983
- const snapshot = await status();
7984
- if (!snapshot.outdated) return {
7985
- ...snapshot,
7986
- restarting: false
7987
- };
7988
- const profileDir = findProfileDir(io.packageDir);
7989
- await io.install(profileDir, `${SUITE_PACKAGE}@${snapshot.latest}`);
7990
- return {
7991
- ...snapshot,
7992
- installed: snapshot.latest,
7993
- outdated: false,
7994
- restarting: true
7995
- };
7996
- })();
7997
- inflight = work;
7998
- try {
7999
- return await work;
8000
- } finally {
8001
- inflight = void 0;
8002
- }
8003
- };
8004
- return {
8005
- status,
8006
- apply,
8007
- relaunch: io.relaunch
8008
- };
8009
- }
8010
- function liveSelfUpdate() {
8011
- return createSelfUpdate({
8012
- packageDir: dirname(fileURLToPath(new URL(".", import.meta.url))),
8013
- fetchLatest: () => fetchLatestVersion(),
8014
- install: (profileDir, spec) => runPnpmAdd(profileDir, spec),
8015
- relaunch: () => {
8016
- spawnRelaunch(process.argv, process.pid, process.cwd());
8017
- setTimeout(() => {
8018
- process.exit(0);
8019
- }, 50);
8020
- }
8021
- });
8022
- }
8023
- //#endregion
8024
7909
  //#region src/index.ts
8025
7910
  const name = "rez-suite";
8026
7911
  const inject = [
@@ -8096,8 +7981,10 @@ const REZ_GUIDANCE_CORE = [
8096
7981
  "涉及资金、对外发送、设备控制、生产写入时先征得用户批准。"
8097
7982
  ].join("");
8098
7983
  function rezGuidanceFor(role) {
8099
- return REZ_GUIDANCE_CORE + bossGuidanceFor(role);
7984
+ return REZ_GUIDANCE_CORE + workspaceGuidanceFor(role);
8100
7985
  }
7986
+ /** @deprecated use rezGuidanceFor */
7987
+ const REZ_GUIDANCE = REZ_GUIDANCE_CORE;
8101
7988
  function normalize(input) {
8102
7989
  return mergeConfig(defaultConfig(), input ?? {});
8103
7990
  }
@@ -8118,7 +8005,7 @@ function delegatedHost(ctx, getConfig) {
8118
8005
  }
8119
8006
  function apply(ctx, config) {
8120
8007
  let current = () => normalize(config);
8121
- const syncBossDesk = mountBossDesk(ctx, () => current().role);
8008
+ const syncWorkspaces = mountRezWorkspaces(ctx, () => current().role);
8122
8009
  const tokens = new TokenManager(joinTokenDb());
8123
8010
  const host = delegatedHost(ctx, () => current());
8124
8011
  ctx.effect(() => () => {
@@ -8131,7 +8018,7 @@ function apply(ctx, config) {
8131
8018
  const value = normalize(next);
8132
8019
  saveConfig(value);
8133
8020
  current = () => value;
8134
- syncBossDesk();
8021
+ syncWorkspaces();
8135
8022
  try {
8136
8023
  const settings = ctx.get("settings");
8137
8024
  if (settings?.update !== void 0) await settings.update(REZ_SETTINGS_NAMESPACE, value);
@@ -8145,8 +8032,7 @@ function apply(ctx, config) {
8145
8032
  onCredentialWritten: (ref) => {
8146
8033
  const emit = ctx.emit;
8147
8034
  emit("credentials/updated", ref);
8148
- },
8149
- selfUpdate: liveSelfUpdate()
8035
+ }
8150
8036
  });
8151
8037
  let disposeRoutes;
8152
8038
  let disposeTools;
@@ -8188,11 +8074,11 @@ function apply(ctx, config) {
8188
8074
  setSource: (source) => {
8189
8075
  current = source;
8190
8076
  sync();
8191
- syncBossDesk();
8077
+ syncWorkspaces();
8192
8078
  },
8193
8079
  onChange: () => {
8194
8080
  sync();
8195
- syncBossDesk();
8081
+ syncWorkspaces();
8196
8082
  }
8197
8083
  });
8198
8084
  sync();
@@ -8201,4 +8087,4 @@ function joinTokenDb() {
8201
8087
  return join(homedir(), ".dsh", "dsh-rez-token-manager.sqlite");
8202
8088
  }
8203
8089
  //#endregion
8204
- export { Config, REZ_GUIDANCE_CORE, REZ_SETTINGS_NAMESPACE, apply, inject, name, rezGuidanceFor };
8090
+ export { Config, REZ_GUIDANCE, REZ_GUIDANCE_CORE, REZ_SETTINGS_NAMESPACE, apply, inject, name, rezGuidanceFor };
package/lib/style.css CHANGED
@@ -287,84 +287,3 @@
287
287
  font-size: 15px;
288
288
  font-weight: 600;
289
289
  }
290
-
291
- .LOjPTW_upgradeLayer {
292
- flex: none;
293
- align-items: center;
294
- width: 100%;
295
- height: 42px;
296
- margin: 8px 0 0;
297
- display: flex;
298
- position: relative;
299
- }
300
-
301
- .LOjPTW_upgradeLayerRail {
302
- width: 36px;
303
- height: 36px;
304
- margin: 0;
305
- }
306
-
307
- .LOjPTW_upgradeButton {
308
- width: calc(100% + 4px);
309
- height: 42px;
310
- color: var(--dsw-alias-label-primary);
311
- cursor: pointer;
312
- background: none;
313
- border: none;
314
- border-radius: 12px;
315
- align-items: center;
316
- gap: 8px;
317
- margin: 0 -2px;
318
- padding: 0 10px 0 8px;
319
- font-family: inherit;
320
- font-size: 14px;
321
- display: inline-flex;
322
- overflow: hidden;
323
- }
324
-
325
- .LOjPTW_upgradeButton:hover, .LOjPTW_upgradeButton[data-outdated] {
326
- background: var(--dsw-alias-interactive-bg-hover);
327
- }
328
-
329
- .LOjPTW_upgradeButton:disabled {
330
- cursor: progress;
331
- opacity: .72;
332
- }
333
-
334
- .LOjPTW_upgradeButton:focus-visible {
335
- outline: 2px solid var(--dsw-alias-brand-primary);
336
- outline-offset: -2px;
337
- }
338
-
339
- .LOjPTW_upgradeLayerRail .LOjPTW_upgradeButton {
340
- border-radius: 50%;
341
- justify-content: center;
342
- gap: 0;
343
- width: 36px;
344
- height: 36px;
345
- padding: 0;
346
- }
347
-
348
- .LOjPTW_upgradeLabel {
349
- text-overflow: ellipsis;
350
- white-space: nowrap;
351
- min-width: 0;
352
- overflow: hidden;
353
- }
354
-
355
- .LOjPTW_upgradeMeta {
356
- color: var(--dsw-alias-label-tertiary);
357
- font-variant-numeric: tabular-nums;
358
- flex: none;
359
- margin-left: auto;
360
- font-size: 12px;
361
- line-height: 16px;
362
- }
363
-
364
- .LOjPTW_upgradeDot {
365
- background: var(--dsw-alias-brand-primary);
366
- border-radius: 50%;
367
- flex: none;
368
- width: 7px;
369
- height: 7px;
370
- }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rezti/dsh-rez-suite",
3
3
  "description": "ReZ-TI one-package install for DeepSeek Harness. Update with: dsh plugin --profile web update @rezti/dsh-rez-suite",
4
- "version": "0.1.22",
4
+ "version": "0.1.24",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": "^22.19.0 || >=24.0.0"
@@ -30,8 +30,7 @@
30
30
  "@deepseek-ai/dsh-client-connection",
31
31
  "@deepseek-ai/dsh-client-locale",
32
32
  "@deepseek-ai/dsh-client-ui-settings",
33
- "@deepseek-ai/dsh-client-ui-settings-plugins",
34
- "@deepseek-ai/dsh-client-ui-sidebar"
33
+ "@deepseek-ai/dsh-client-ui-settings-plugins"
35
34
  ],
36
35
  "platform": "web"
37
36
  }
@@ -39,15 +38,15 @@
39
38
  "dependencies": {
40
39
  "@modelcontextprotocol/sdk": "^1.30.0",
41
40
  "zod": "^4.4.3",
42
- "@rezti/dsh-rez-nextcloud": "0.1.7",
43
- "@rezti/dsh-rez-ha-bridge": "0.1.7",
44
- "@rezti/dsh-rez-tapd": "0.1.0",
45
- "@rezti/dsh-rez-token-manager": "0.1.4",
41
+ "@rezti/dsh-rez-ha-bridge": "0.1.9",
46
42
  "@rezti/dsh-rez-gsc": "0.1.0",
47
- "@rezti/dsh-rez-odoo": "0.1.7",
43
+ "@rezti/dsh-rez-odoo": "0.1.9",
48
44
  "@rezti/dsh-rez-intent": "0.1.5",
49
- "@rezti/dsh-rez-wechat": "0.1.12",
50
- "@rezti/dsh-rez-sso": "0.1.8"
45
+ "@rezti/dsh-rez-sso": "0.1.9",
46
+ "@rezti/dsh-rez-tapd": "0.1.0",
47
+ "@rezti/dsh-rez-token-manager": "0.1.4",
48
+ "@rezti/dsh-rez-nextcloud": "0.1.9",
49
+ "@rezti/dsh-rez-wechat": "0.1.14"
51
50
  },
52
51
  "peerDependencies": {
53
52
  "react": "^18.2.0",
@@ -86,6 +85,7 @@
86
85
  "src",
87
86
  "servers",
88
87
  "templates/boss/**/*",
88
+ "templates/staff/**/*",
89
89
  "cordis.patch.yml",
90
90
  "README.md",
91
91
  "README.zh.md"