@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.
- package/README.md +5 -3
- package/lib/client.d.ts +2 -16
- package/lib/client.js +9 -145
- package/lib/index.d.ts +3 -1
- package/lib/index.js +108 -222
- package/lib/style.css +0 -81
- package/package.json +10 -10
- package/src/boss/mount.ts +54 -20
- package/src/boss/register.ts +50 -11
- package/src/boss/seed.ts +55 -18
- package/src/client/api.ts +0 -12
- package/src/client/index.ts +3 -16
- package/src/client/locales.ts +2 -16
- package/src/client/panel/panel.module.css +0 -82
- package/src/index.ts +9 -8
- package/src/protocol.ts +0 -13
- package/src/routes.ts +2 -30
- package/templates/staff/finance/.agents/skills/staff-finance/SKILL.md +6 -0
- package/templates/staff/finance/AGENTS.md +68 -0
- package/templates/staff/finance/BOOTSTRAP.md +23 -0
- package/templates/staff/finance/IDENTITY.md +8 -0
- package/templates/staff/finance/MEMORY.md +9 -0
- package/templates/staff/finance/PRIORITIES.md +3 -0
- package/templates/staff/finance/SOUL.md +6 -0
- package/templates/staff/finance/USER.md +8 -0
- package/templates/staff/finance/memory/.gitkeep +0 -0
- package/templates/staff/hr/.agents/skills/staff-hr/SKILL.md +6 -0
- package/templates/staff/hr/AGENTS.md +52 -0
- package/templates/staff/hr/BOOTSTRAP.md +23 -0
- package/templates/staff/hr/IDENTITY.md +8 -0
- package/templates/staff/hr/MEMORY.md +9 -0
- package/templates/staff/hr/PRIORITIES.md +3 -0
- package/templates/staff/hr/SOUL.md +6 -0
- package/templates/staff/hr/USER.md +8 -0
- package/templates/staff/hr/memory/.gitkeep +0 -0
- package/templates/staff/legal/.agents/skills/staff-legal/SKILL.md +6 -0
- package/templates/staff/legal/AGENTS.md +48 -0
- package/templates/staff/legal/BOOTSTRAP.md +23 -0
- package/templates/staff/legal/IDENTITY.md +8 -0
- package/templates/staff/legal/MEMORY.md +9 -0
- package/templates/staff/legal/PRIORITIES.md +3 -0
- package/templates/staff/legal/SOUL.md +6 -0
- package/templates/staff/legal/USER.md +8 -0
- package/templates/staff/legal/memory/.gitkeep +0 -0
- package/src/client/upgrade-button.tsx +0 -115
- 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
|
|
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
|
|
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
|
|
7716
|
-
*
|
|
7717
|
-
* `delete` only drops the registry row —
|
|
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
|
|
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
|
|
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
|
|
7706
|
+
async function unregisterWorkspaces(registry, rooms) {
|
|
7733
7707
|
for (const workspace of registry.list()) {
|
|
7734
|
-
if (!
|
|
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
|
|
7772
|
+
function findTemplates(kind, marker) {
|
|
7762
7773
|
const here = fileURLToPath(new URL(".", import.meta.url));
|
|
7763
7774
|
const candidates = [
|
|
7764
|
-
join(here, "../templates
|
|
7765
|
-
join(here, "../../templates
|
|
7766
|
-
join(here, "templates
|
|
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,
|
|
7769
|
-
throw new Error(
|
|
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
|
|
7772
|
-
|
|
7773
|
-
|
|
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
|
|
7776
|
-
rooms:
|
|
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
|
|
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
|
|
7856
|
+
const STAFF_GUIDANCE = [
|
|
7857
|
+
"侧栏已登记人事助理 / 财务助理 / 法务助理。装完、选身份后自动出现,不必手动「添加工作区」、也不必拖排序。",
|
|
7858
|
+
"三个助理给所有人用。能做什么看当前 Odoo 帐号的可视范围;Harness 只列选项,不自审、不自过账。",
|
|
7859
|
+
"报销走财务助理。搞钱室是战略数字,不要在助理房间里做。"
|
|
7860
|
+
].join("");
|
|
7835
7861
|
const BOSS_GUIDANCE = [
|
|
7836
|
-
"
|
|
7862
|
+
"当前角色是老板。侧栏已登记搞钱 / 产品 / 运营,后面是人事助理 / 财务助理 / 法务助理。不必手动「添加工作区」。",
|
|
7837
7863
|
"每个文件夹是独立作战室,官方 dsh 会注入该目录 AGENTS.md。",
|
|
7838
7864
|
"若该室仍有 BOOTSTRAP.md:本会话先做短问三拍,沉淀到 PRIORITIES.md / MEMORY.md,然后删除 BOOTSTRAP.md。",
|
|
7839
|
-
"已初始化后:读 PRIORITIES.md + MEMORY.md + 今日/昨日 memory
|
|
7840
|
-
"
|
|
7865
|
+
"已初始化后:读 PRIORITIES.md + MEMORY.md + 今日/昨日 memory/;老板三室回答固定四行:结论 → 数字(哪家公司、哪段时间)→ 拍板 1~3 件事 → 未执行任何过账/付款/对外发送。",
|
|
7866
|
+
"微信文件夹仍是收件箱,不要在那边查账、报销或砍 SKU。"
|
|
7841
7867
|
].join("");
|
|
7842
|
-
|
|
7843
|
-
|
|
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
|
|
7876
|
+
function refsFor(rooms, env) {
|
|
7850
7877
|
const root = destRoot(env);
|
|
7851
|
-
return
|
|
7878
|
+
return rooms.map((room) => ({
|
|
7852
7879
|
path: join(root, room.folder),
|
|
7853
7880
|
folder: room.folder
|
|
7854
7881
|
}));
|
|
7855
7882
|
}
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
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
|
-
|
|
7864
|
-
|
|
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
|
-
|
|
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]
|
|
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 +
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
8077
|
+
syncWorkspaces();
|
|
8192
8078
|
},
|
|
8193
8079
|
onChange: () => {
|
|
8194
8080
|
sync();
|
|
8195
|
-
|
|
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.
|
|
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-
|
|
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.
|
|
43
|
+
"@rezti/dsh-rez-odoo": "0.1.9",
|
|
48
44
|
"@rezti/dsh-rez-intent": "0.1.5",
|
|
49
|
-
"@rezti/dsh-rez-
|
|
50
|
-
"@rezti/dsh-rez-
|
|
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"
|