@whyshu/argent-erp 0.2.3 → 0.3.0
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 +32 -21
- package/dist/client.js +54 -12
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
# @whyshu/argent-erp(v0.
|
|
1
|
+
# @whyshu/argent-erp(v0.3.0)
|
|
2
2
|
|
|
3
3
|
**两件东西,一个货**:
|
|
4
4
|
|
|
5
|
-
1.
|
|
6
|
-
办公室现场 / 待办 / 时间线 / 货件 /
|
|
5
|
+
1. **左侧栏 ERP 入口 + 主视图面板**:侧栏多一个「ERP」图标,点一下主视图(会话区)整页切到 ERP——
|
|
6
|
+
办公室现场 / 待办 / 时间线 / 货件 / 聊一聊;点会话行或面板里的「← 会话」即可回到对话;
|
|
7
7
|
2. **「六禾园办公室助理」preset**:让「和办公室聊一聊」变成一个**真正的 dsh 会话**
|
|
8
8
|
(原生 Chat,含轨迹/统计/中断),但**边界写死在 preset 里**——只聊办公室、只读 ERP、无本机能力。
|
|
9
9
|
|
|
@@ -18,31 +18,40 @@ src/data.mjs 数据层:whoami / overview / timeline / flow / ship
|
|
|
18
18
|
src/office-guard.js 办公室会话的**工具边界**(preset 内挂载:只放行 mcp__argent__erp_*)
|
|
19
19
|
src/vendor/ account-token.mjs + redact.mjs 的**副本**(插件可发布,不能相对 import core/lib)
|
|
20
20
|
presets/argent-office.patch.yml 「六禾园办公室助理」preset 声明行(dsh 0.2.x 行式 preset)
|
|
21
|
-
dist/client.js 客户端 bundle(手写维护):注册
|
|
21
|
+
dist/client.js 客户端 bundle(手写维护):注册 sidebar.panellist(id=erp,图标)+ main(key=erp,面板)
|
|
22
22
|
test/ 客户端 bundle + preset 边界冒烟测试(纯夹具,不启 dsh、不联网)
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
`package.json#dsh.bundle.patch` 是**数组**:`[cordis.patch.yml, presets/argent-office.patch.yml]`
|
|
26
26
|
⇒ 一次 `install_bundle` 同时落「ERP 视图」与「办公室助理 preset」。
|
|
27
27
|
|
|
28
|
-
## 2.
|
|
28
|
+
## 2. 它是「左侧栏入口 + 主视图面板」,不是会话 tab、也不是右侧栏
|
|
29
29
|
|
|
30
|
-
dsh 0.2.x
|
|
31
|
-
|
|
30
|
+
dsh 0.2.x 的两项原生扩展点(`dsh-client-ui-sidebar` / `dsh-client-ui-layout`):
|
|
31
|
+
|
|
32
|
+
- `sidebar.panellist`:左侧栏那排**全局面板图标**(插件、定时任务…);列表条目的 `id` 就是"对应哪个主视图";
|
|
33
|
+
- `main`(keyed):主视图区,`activePanelId` 命中哪个 key 就渲染哪个;`null` = 显示对话。
|
|
34
|
+
|
|
35
|
+
本插件注册两项,**id 与 key 必须相同**:
|
|
32
36
|
|
|
33
37
|
```js
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
id: "erp",
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
// ① 左侧栏图标(owner props: { size, active })
|
|
39
|
+
ctx.slots.inject("sidebar.panellist", () => ctx.slots.register({
|
|
40
|
+
name: "sidebar.panellist", id: "erp", order: 15, label: () => "ERP",
|
|
41
|
+
}, ErpIcon))
|
|
42
|
+
|
|
43
|
+
// ② 主视图面板(root 作用域:没有 Session 绑定)
|
|
44
|
+
ctx.slots.inject("main", () => ctx.slots.register({
|
|
45
|
+
name: "main", key: "erp",
|
|
46
|
+
inject: () => ({ sessions, workspaceNav, remote, closePanel }), // 给「聊一聊」建会话 / 返回按钮用
|
|
40
47
|
}, ErpView))
|
|
41
48
|
```
|
|
42
49
|
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
-
|
|
50
|
+
- 点击侧栏图标由 sidebar 调 `ctx.layout.selectPanel("erp")`;点任意会话行由 workspace 调
|
|
51
|
+
`selectPanel(null)` 回到对话;面板内再给一个「← 会话」按钮(同样走 `selectPanel(null)`)。
|
|
52
|
+
- 主视图面板是 **root 作用域**(没有 `sessionId`):"在哪个 workspace 建办公室会话"取
|
|
53
|
+
`useWorkspaces` 的第 1 个 workspace(有当前会话时优先当前会话所属 workspace)。
|
|
54
|
+
- 面板只在被选中时挂载 ⇒ 轮询/请求随关闭自动停。
|
|
46
55
|
|
|
47
56
|
## 3. 视图内容
|
|
48
57
|
|
|
@@ -117,7 +126,7 @@ ERP 网页里那个「办公室聊一聊」**保持原样**(服务端 SSE +
|
|
|
117
126
|
|
|
118
127
|
| 路径 | 作用 |
|
|
119
128
|
|---|---|
|
|
120
|
-
| `/api/argent-erp/health` | 存活 + 版本 + `erpTools`(ERP 工具数;0=缺 @whyshu/argent)+ `officePreset` + `clientPingAt`(bundle 加载)/ `viewPingAt
|
|
129
|
+
| `/api/argent-erp/health` | 存活 + 版本 + `erpTools`(ERP 工具数;0=缺 @whyshu/argent)+ `officePreset` + `clientPingAt`(bundle 加载)/ `viewPingAt`(面板打开/渲染)|
|
|
121
130
|
| `/api/argent-erp/whoami` | 账号 + 租户列表 + 默认租户 |
|
|
122
131
|
| `/api/argent-erp/overview?tenant=` | 办公室现场(KPI/在岗/执行机/待办 20/动态 10,脱敏) |
|
|
123
132
|
| `/api/argent-erp/timeline?tenant=&days=` | 时间线(`/sku-flows`,按天分组) |
|
|
@@ -142,7 +151,7 @@ dsh 设置 → 插件(Plugins)→ 安装 bundle → @whyshu/argent-erp
|
|
|
142
151
|
```
|
|
143
152
|
|
|
144
153
|
- 装完**重启 dsh**(bundle patch 的宿主行与 preset 行在启动时装配);
|
|
145
|
-
-
|
|
154
|
+
- 之后**左侧栏出现「ERP」图标**(点击切主视图),新建会话的 **preset 选择器**里出现「六禾园办公室助理」;
|
|
146
155
|
- ⚠️ **同机需要 `@whyshu/argent`**(≥0.2.0):它提供 `mcp__argent__erp_*` 工具与 `whyshu` provider。
|
|
147
156
|
缺它时插件仍能装、视图仍能看(端点会报 no_token),但办公室角色会被 `office-guard` **安全降级为无工具**;
|
|
148
157
|
宿主 `/api/argent-erp/health` 的 `erpTools` 会返回 `0`(= 没有 ERP 工具),`-1` = 读不到 tools 服务。
|
|
@@ -159,9 +168,11 @@ curl -s http://127.0.0.1:3080/api/argent-erp/health # {"ok":true,"version":
|
|
|
159
168
|
# 3) preset 行是否落了(应含 include:preset-argent-office)
|
|
160
169
|
# cordis_inspect_query host/Config/listConfigs name='@deepseek-ai/dsh-agent-preset'
|
|
161
170
|
|
|
162
|
-
# 4)
|
|
163
|
-
# cordis_inspect_query client/Slots/listSubTree root='
|
|
164
|
-
# ⇒ occupants 含 { registrant: "argent-erp-client", id: "erp", order:
|
|
171
|
+
# 4) 客户端两处注册
|
|
172
|
+
# cordis_inspect_query client/Slots/listSubTree root='sidebar.panellist'
|
|
173
|
+
# ⇒ occupants 含 { registrant: "argent-erp-client", id: "erp", order: 15, active: true }
|
|
174
|
+
# cordis_inspect_query client/Slots/listSubTree root='main'
|
|
175
|
+
# ⇒ occupants 含 { registrant: "argent-erp-client", key: "erp", active: true }
|
|
165
176
|
|
|
166
177
|
# 5) 单测(15 项,含 preset 边界断言)
|
|
167
178
|
node plugins/argent-erp/test/client-bundle.test.mjs
|
package/dist/client.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* argent-erp · 客户端(dsh browser bundle 格式,**手写维护**)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* 形态:**左侧栏一个「ERP」图标**(`sidebar.panellist`,id=erp)+ **主视图面板**(`main`,key=erp)——
|
|
5
|
+
* 点侧栏图标,主视图(会话区)切到 ERP;点会话行或面板里的「← 会话」回到对话。
|
|
5
6
|
* 渲染 ERP 的只读视图:办公室现场 / 待办 / 时间线 / 货件 / 聊一聊。
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
+
* 为什么不是右侧栏:ERP 是"一整页工作台"(KPI/待办/时间线/货件/聊天入口),塞进窄侧栏只能看数字;
|
|
9
|
+
* 主视图面板能给它完整宽度,同时左侧栏一点就回来,不打断会话。
|
|
8
10
|
*
|
|
9
11
|
* 数据全部来自宿主端点 `/api/argent-erp/*`(token 在宿主侧,浏览器拿不到)。
|
|
10
12
|
* ⛔ 不做写操作;重编辑一律跳 ERP web。
|
|
@@ -521,7 +523,7 @@ window.__ModuleLoader__.load({
|
|
|
521
523
|
const [tenant, setTenant] = React.useState("")
|
|
522
524
|
const [detail, setDetail] = React.useState(null) // { kind:'flow'|'shipment', id }
|
|
523
525
|
const [nonce, setNonce] = React.useState(0) // 刷新时让各自取数的面板重挂
|
|
524
|
-
//
|
|
526
|
+
// 渲染信标:只有打开 ERP 面板才会打 ⇒ /health 的 viewPingAt 能证明"真的渲染了"
|
|
525
527
|
React.useEffect(() => { try { fetch(API + "/ping?from=view") } catch { /* noop */ } }, [])
|
|
526
528
|
const who = useApi("/whoami")
|
|
527
529
|
const health = useApi("/health")
|
|
@@ -556,6 +558,12 @@ window.__ModuleLoader__.load({
|
|
|
556
558
|
|
|
557
559
|
return h("div", { className: "aerp-root" },
|
|
558
560
|
h("div", { className: "aerp-head" },
|
|
561
|
+
props && typeof props.closePanel === "function"
|
|
562
|
+
? h("button", {
|
|
563
|
+
type: "button", className: "aerp-btn", title: "回到会话",
|
|
564
|
+
onClick: () => { try { props.closePanel() } catch { /* noop */ } },
|
|
565
|
+
}, "← 会话")
|
|
566
|
+
: null,
|
|
559
567
|
h("span", { className: "aerp-title" }, "Argent ERP"),
|
|
560
568
|
tenants.length > 1
|
|
561
569
|
? h("select", {
|
|
@@ -581,26 +589,60 @@ window.__ModuleLoader__.load({
|
|
|
581
589
|
const name = "argent-erp-client"
|
|
582
590
|
const inject = ["slots"]
|
|
583
591
|
|
|
592
|
+
/** 侧栏入口 id 与主视图面板 key 必须一致(sidebar 用 id 去 main 槽取面板) */
|
|
593
|
+
const PANEL_ID = "erp"
|
|
594
|
+
|
|
595
|
+
/** 左侧栏「ERP」图标(owner props: { size, active };用 currentColor,跟随主题) */
|
|
596
|
+
function ErpIcon(props) {
|
|
597
|
+
const size = (props && props.size) || 16
|
|
598
|
+
const active = Boolean(props && props.active)
|
|
599
|
+
const color = active ? "var(--dsw-alias-brand-primary)" : "currentColor"
|
|
600
|
+
return h("svg", {
|
|
601
|
+
width: size, height: size, viewBox: "0 0 24 24", fill: "none",
|
|
602
|
+
stroke: color, strokeWidth: 1.6, strokeLinecap: "round", strokeLinejoin: "round",
|
|
603
|
+
style: { display: "block" }, "aria-hidden": "true", focusable: "false",
|
|
604
|
+
},
|
|
605
|
+
h("path", { d: "M3.6 9.6 5.3 4.3h13.4l1.7 5.3" }),
|
|
606
|
+
h("path", { d: "M4.3 9.6h15.4v9.1a1.3 1.3 0 0 1-1.3 1.3H5.6a1.3 1.3 0 0 1-1.3-1.3V9.6Z" }),
|
|
607
|
+
h("path", { d: "M9.4 20v-4.7h5.2V20" }))
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/** 取服务;没有/未注入时返回 undefined(动态插件 ctx 的白名单可能不含某个服务) */
|
|
611
|
+
const getService = (ctx, name) => { try { return ctx.get(name) } catch { return undefined } }
|
|
612
|
+
|
|
584
613
|
function apply(ctx) {
|
|
585
614
|
injectCss()
|
|
586
615
|
// 自检信标:宿主 /health 会回报 clientPingAt ⇒ 能区分"bundle 没加载"与"加载了但没显示"
|
|
587
616
|
try { fetch(API + "/ping?from=client").catch(() => {}) } catch { /* noop */ }
|
|
588
617
|
|
|
589
|
-
// ⛔
|
|
618
|
+
// ⛔ 永不抛出:注册失败只影响 ERP 入口,不能让 web boot 报 "entry did not activate"
|
|
619
|
+
|
|
620
|
+
// ① 左侧栏入口(图标按钮):点击后 sidebar 调 ctx.layout.selectPanel('erp') 切主视图
|
|
590
621
|
try {
|
|
591
|
-
ctx.slots.inject("
|
|
592
|
-
name: "
|
|
593
|
-
id:
|
|
594
|
-
order:
|
|
622
|
+
ctx.slots.inject("sidebar.panellist", () => ctx.slots.register({
|
|
623
|
+
name: "sidebar.panellist",
|
|
624
|
+
id: PANEL_ID,
|
|
625
|
+
order: 15,
|
|
595
626
|
label: () => "ERP",
|
|
627
|
+
}, ErpIcon))
|
|
628
|
+
} catch (e) {
|
|
629
|
+
console.warn("[argent-erp] 侧栏入口注册失败(不影响 dsh):", (e && e.message) || e)
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
// ② 主视图面板:key 与侧栏 id 相同;root 作用域(没有 Session 绑定)
|
|
633
|
+
try {
|
|
634
|
+
ctx.slots.inject("main", () => ctx.slots.register({
|
|
635
|
+
name: "main",
|
|
636
|
+
key: PANEL_ID,
|
|
596
637
|
inject: () => ({
|
|
597
|
-
sessions: (
|
|
598
|
-
workspaceNav: (
|
|
599
|
-
remote: (
|
|
638
|
+
sessions: getService(ctx, "sessions"),
|
|
639
|
+
workspaceNav: getService(ctx, "uiWorkspace"),
|
|
640
|
+
remote: getService(ctx, "remote"),
|
|
641
|
+
closePanel: () => { try { getService(ctx, "layout")?.selectPanel?.(null) } catch { /* noop */ } },
|
|
600
642
|
}),
|
|
601
643
|
}, ErpView))
|
|
602
644
|
} catch (e) {
|
|
603
|
-
console.warn("[argent-erp]
|
|
645
|
+
console.warn("[argent-erp] 主视图面板注册失败(不影响 dsh):", (e && e.message) || e)
|
|
604
646
|
}
|
|
605
647
|
}
|
|
606
648
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whyshu/argent-erp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Argent ERP
|
|
5
|
+
"description": "Argent ERP 左侧栏入口 + 主视图面板(dsh sidebar.panellist/main)+ 六禾园办公室助理 preset + 办公室聊一聊",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"dsh",
|
|
8
8
|
"deepseek-harness",
|