@waterplus-ai/waterbuddy 0.1.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 +60 -0
- package/lib/client/index.js +68 -0
- package/lib/host/index.js +67 -0
- package/lib/shared/persona.js +11 -0
- package/package.json +38 -0
- package/patches/cordis.patch.yml +15 -0
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# WaterPlus AI WaterBuddy Bundle
|
|
2
|
+
|
|
3
|
+
This package turns an official DeepSeek Harness Web profile into the WaterPlus AI internal deployment used by company staff.
|
|
4
|
+
|
|
5
|
+
It provides:
|
|
6
|
+
|
|
7
|
+
- The approved WaterPlus AI sidebar mark and wordmark with `Powered by DSH` attribution.
|
|
8
|
+
- The WaterPlus AI internal assistant persona “小加”, focused on water-industry work.
|
|
9
|
+
- The public Xiaojia MCP service at `https://ai.shuiwujia.com/mcp`, exposed as model tools.
|
|
10
|
+
- `WaterBuddy` browser title, favicon, and PWA manifest through the Web server extension points.
|
|
11
|
+
- A single installable `dsh.bundle` layer; the official base and Web bundles remain untouched.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
From a clean DSH installation, run:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
dsh plugin --profile web add /absolute/path/to/waterbuddy-0.1.0.tgz
|
|
19
|
+
dsh --profile web
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
For a published private registry package, replace the path with `@waterplus-ai/waterbuddy@0.1.0` and configure the registry credentials in the profile.
|
|
23
|
+
|
|
24
|
+
The package is a profile layer, not a desktop application replacement. It changes the Web profile after installation; a Tauri or other desktop shell still needs its own native branding resources.
|
|
25
|
+
|
|
26
|
+
## Extension points
|
|
27
|
+
|
|
28
|
+
The bundle disables only `ui-brand-official`, inserts its own browser row into the same sidebar slots, and adds one `@deepseek-ai/dsh-mcp-client` row for Xiaojia. It does not modify `dsh-base`, `dsh-web-app`, the agent loop, or the official package source. The Host half uses `WebServer.register` for the brand icon and PWA manifest, `WebServer.tapIndex` for the initial document title, and `ctx.systemPrompt.section()` for the WaterPlus role description. The browser half retains the WaterBuddy suffix when session titles change.
|
|
29
|
+
|
|
30
|
+
The MCP endpoint is currently public, so the bundle sends no credentials. When company SSO is ready, add an access-token header through the profile's MCP configuration rather than baking a token into this package; the SSO client can refresh the token and restart or update the MCP connection as required.
|
|
31
|
+
|
|
32
|
+
## Directory layout
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
waterplus-dsh-enterprise/
|
|
36
|
+
├── lib/
|
|
37
|
+
│ ├── host/ # Host entrypoint: Web server and system prompt
|
|
38
|
+
│ ├── client/ # Browser ModuleLoader bundle and UI slots
|
|
39
|
+
│ └── shared/ # Shared role text and future cross-half contracts
|
|
40
|
+
├── patches/ # Cordis bundle patch declarations
|
|
41
|
+
├── tests/ # Host/client regression tests
|
|
42
|
+
├── releases/ # Generated .tgz files; one file per published version
|
|
43
|
+
├── docs/ # Design notes and WaterBuddy feature specifications
|
|
44
|
+
├── package.json # Package metadata and build commands
|
|
45
|
+
├── pnpm-lock.yaml # Reproducible package-manager metadata
|
|
46
|
+
└── README.md
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Build and test from this directory:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
pnpm test
|
|
53
|
+
pnpm run pack:check
|
|
54
|
+
pnpm run pack:release
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
New WaterBuddy capabilities should be added under the matching `lib/host/`, `lib/client/`, or
|
|
58
|
+
`lib/shared/` area, with corresponding tests under `tests/` and design decisions recorded under
|
|
59
|
+
`docs/`. Keep generated archives in `releases/` and do not install an old archive after a newer
|
|
60
|
+
version is created.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: '@waterplus-ai/waterbuddy',
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
const { Fragment, jsx, jsxs } = require('react/jsx-runtime')
|
|
5
|
+
const module = { exports: {} }
|
|
6
|
+
const exports = module.exports
|
|
7
|
+
const mark = 'data:image/png;base64,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'
|
|
8
|
+
const wordmark = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVoAAABUCAYAAADDLP+yAAAACXBIWXMAAAAAAAAAAQCEeRdzAAAAAXNSR0IB2cksfwAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABGdBTUEAALGPC/xhBQAADwNJREFUeJztne11IykWhhWCM1iF4AzWGUxnMM6gN4CxJO+Z/94MvBk4BIXgEBSCElh1rYAqAVXA/QDKcp/3OYfT3TOqKoqCF7jcC5sNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYF12v4ZZOm92w8mnX5+bl+EYpf3lXfSMg7nmeu8oXe99S9dn7M1vgrS7HAT3fx7vew7uG9/vMLyP6W3zOuyvfz4KSwp8Bw7D0+ZwrTuH4WOsW2O9uNaxw7Xevg5/fnUWQQPs951rCit9VDzzmfmM8/Li/a9jQmzp9PfwD0EG31SFchgemPeXFzqE9vfCCmyqQ0+mk6gjB/fH6/BTKbR8XVk+c89+xoLd9WKN0O6uL8qF3xPMC+SJdX/TcGT3PrHzDtbnMGydaA6nfDIj1LGzPFz+o2x0J/ss8P0wYqkV2tfhD9Uzq4TWVFaN0L4IhuDqQrmOhOl7b+X3vchMH2BdTAfL64jfrOBqG5xLZ8xuvhGH4cft7+pvz9CVFFVCa3C2WKnYJuwQBXSFciTvawp+rR4NrANXaNsliO13wc1C3NRfa5LUzmirhdYovGZUS1XO0BbSy05rFrjk99xKyxisyPpCO0QNGNwnRm9c+30a/62vJ5I1polqoTUZ7mGnNQZr3/voCoWy08pHyp/iAgbr8jVCa5J+RRr0Z1oAex11p85Oy19j8s+vFFqDdesSCi1lp91fR5u70Z3GFcpZXigFe4qqoJX2GbAeXye0/AVYsD5+UOV15/DruFqn2kRorSgKhZay0zofXC9sukLJ22k19tl/D/8UFzBYl3qhPdu65uqbtHOn1wXA+sSL3l539G5esjUm96wGQvsyPKvMB38VRgDuN97wrCuUc9Z2Jrf7ygsXrI9eaI/JjtTa9gS2fI39DvRl7iI6faM17bRNhNaIWUs7beg25gvlUVUguemc3D4LG9x3QNN4OH7dh8u/WPfS2O9AX+bBKGGEn8okqfjOTYTWZfiosNOmp1pmWp8SY02hpApEY59F+OX3QCq0JuiGfW+W2KJDvieSbT00SSo8j+wA7iLzp28mtEbQWtlpQ5exUIx1hbIUc82op7evpKkQLhQ0nwCN7NvKfSLptQJEDt4T6bWYWpOk/Ds3E1pjcG5lp7UbwwRi7N28NOG4SzGXvHRN4zGN3rmpvds9FVx6s6PjuT8unadlHtz994sURsC0wHUCj4Ho13U6NR1KnJdt8t7c7/oqGM1OcBpmnJ/H5Dfy32r5Drn3Lt1Hc8/WuHf9aet4vBHTzy8bKOQGZ15TFNGhs3twaCa0ht1wUthpl5V94S42RmNpfd/mwsDfQGRMF/40wQnA24Zn5jjdRFcntLn3qF/9toJ2OQS7WCXS9fmpToO6Ly2ASzON3/glLtd5ZZcIrcaLhHP/cKGEmoVxxb71e7kOa8tIVNDPWE+Y9d1MudfsCHL5CoW/WMeF9TRHU6HVRInN7bSphbXQzUsTjju300ptvZyw29tmJooP5vJDfex1hNY1HOlGKyf2jlacEcS8AruGTIuau79kRCsPp/59hJZXV0v5cwvUVL1NpzUEt1hmkZ1WGXl64Q/AmgqtLkosdsFK3+Mc/H9NocQLFOICJSqEWyTRrV7yU3+hdRVT13CmPJJlJRTaksiaVCe0cg8Bjv91/Pt3Ig/thZZj2qkV2sP/nhvU+b47oJXLPlz70e0QKHH5bCq0Bk2UWGinzW29OP1G5/sWF4isgpTDbikhuCVjt1JHorhKuXh2Q6F1Daem0fiyLjV0idByflsjtKpyIhdkz6Lf9xBajo9njdC679JmYNHTHa48aAgHb/pwXO56RXOhVUWJBR9zP3wUf6MNxw0LRLTZdymMlymy4Qhtd/mv8qP2E1pNlFw55cVWJrT07KVOaAfRwiFv4WRuCnsn3vVrhHY/nJh1d5m/ulkPr23VwvG7j+y0ym0TuR1Fc6HVRImFdloTDUb9RjMyDAtEYn7I2bu4042UwVwnthKhPdn8LdNyYUM2OhmPdbHlT1XM9LRQJrT0d64VWu42hy7fJ3HDaye0D+wItZ5CS5fv2Qqo+Yam7Zg/Xb7nz+u74xlH2LSaECfeoKa50OqixM63VdDS76YPI3fPigtEMoJLvyO30eVXJffiDysRWn4D5N0jF566HTucXFmkfJj5QssRg3qhdWlnzwrLhWvz7ZHzzqWV0EblZ++Zz09foS3V27LNNawrvRfCeCPUUBO04bj5MP+Q5kLrXvIoFtu/rPvOj/LvbiOdOjst3yaTi1wrN55QLIrlJBLb9kJLj8rPrPewgpuZZcz9J+9VaH2jcb7Oky+ozEyV6ljKdUUyog3LstTJsYSW+U5LoS28D/NUE8lRVhr4vrFzTdDZnTk+wl2EVhMlZly4KPvu/vJeVShS37l0+C79ESUViW9GSAmt7GDJeQOken1pYEJabOc2y3sW2rqUHvW/E+8qMB2MboBz32Xz3HB6/mVCeye7l0m8CKLOS7tYzehgugit5iyxFzsK/iRNDDWFEi66cUalKaGhPqIkdl72Limhpd8hTLF/Z3mxQPUemQ4wdt8TCC1j+nc3QntJ+1S2NB3sh1NcrpelL2rOFr+4F/O9ZKaDYZwJbNMPXQnJTC8cTOnDcekDAboIrWE3pBe1atMkfrV2WrpQ02G3pY+oESd3T47Nd5kfaRnEQlu2tWlJ5SledOALrQ3dvLyXU0VkWLuUt032FNopuXJ4En0n7rsthZYzWjyr8tQCuatWaKftF47bTWi1Z4lxhVZrp/UxzoT7x2U5Qil/xLppE/0+qRHtgxVPboqvPeafVeF2ky6jYFd7RWSY7PnrC20pEmsNoQ3rCM+mzhejpdBKzXancZS7zgGWclfFGh97fp3tJrTqs8SKqd7JOPadyxdqLt4+f9/txofh8j9WOP0rmxD0o8wU5Tx+2n0M1KmQ9/sRWpl9W5vXdYWWmyf+yC2VP91s0tWr3tuN6g5cfay6fmrHJToK7cNGEyVG2XGjZ2iM18zjcVJTwby54SPxkUyjKOXvuPE2yON4fWlaxvc6oBuaPhJGm/yz70NonY8nv/Iv05m5p0C54X5HobV5UTr4T3W5l1lBE0wRfsde4bjdhNa99LHtiFZomE+nI+P6tHE7V1jTib3hf5tsVKWP65//Oean1AAkQltuvDW2KG3yJ2Xcj9D6/Egb55G94PO7Cq2r7zViO7A3IuKiNRvFQlsTjvuUzVtXodVtBl4Y0c5GEPpjyCc7bcaek7FR5grLieZMaK0/Zr53NDtHeaH0Nsx8vr+30Hrb+n0Jrb/umZghuYgn6daK9ym0ko13iLpkN1Ti5av1t56jm6EsR6Lccp6n0mJ4V6HVbgaeS8v719lpc9fnGlPOdDD9Xh7tNeXHx9vnf9dSaNc3HcQjyH6NTyu0Ic6s8IfNh/mz5sDF311o/T1LEYKlxIus4uUh3R7KaXn0UI9w3K5Ca9hdK0cP++ytUCrttKnKWw7FTFVGv6+pNSOMx1XT6WM2bSl5QrQTWvvexcWwjw13N3/prv/fQWhb8jVCWw6YkdghpSHCpi1QIcLzpHWLjN9JN3hIByXpN1nKaUd3oW3l5vUinM6XU2innTeEfK+UE4lWW721WwyjK26pg2pR8bPPhdCqhYwrtJSrocyhX+sb/iAY5dZHlGnFMR2UpJ/x5TaT7y60zdy8Mi9Qa6edmwMo0UxX9jahh+UG0FZoywEb7aZzyzxDaPsLbb4Mucema/KXQ3NMkxSdW1beU0C90NdgQKgsgDZuXvnpfN2+B/PpOuVYnSuwWncVWoAaj2iJXrvXqBZCu47Q2m9odyTbjvl44G9Sr8xfsRwIE18tOvtw/mh4vZ023Wl0F1pbCLnNvNmJOOWg1k57E2q6Z80Le21kGL2/6/IavdDa64ly6xHNA6FdT2hbpLx7lxmgfLLrSHkDpLoRLWeT7/S75WevNRGGqcXTVYS21s3r5UJFXWg2gwjttGMlIJ5DFZrWL5A30lhWxtz0hr9STIneedP+6HII7fy7Oj/s50SKRWw/nKqFUy5Gy7rkBhs+L9RBi7Svcn5kyUG7GUz5yKUaO+1SwFcRWt1m4LR91t+/jZ2W28DnFS2+J3+fANmJsymhTZtMJKMkTgWYgi+8//HD+O8t+zn+nSG0WpHbDyWx6pOSQpups66e/LAC5kPS6QWxWl9anVsXfbCi/oy/ZcexitAa6C0QS/bZLXl/jZ12WiGcph4S4XDX5J5Z3tzDCJUTd0nDSQltvhLZRhmlwtlnogp1jvIkFdt7Edoa31hZfrS2vsSGLsKFrBZpmQe5nVdar2Xlqx150qY+/bdbivhqQqt38+J9COkm2DZFdlq5jZVzQsG0Y7/zJX3f6MMWE0I7nNjXlza9qAunlIst3bh7Cy3/mOha9LHzmdFk1UnKy3KQ5KH9IZ71MwttnjgumTV22vni+GpCq3XzemHab3R2Gi9eWltkTUPS5tW/M//jUbsLWXOAekerT5E72H44EY2gs9ASZdGSmiNS8kd9l8uPk3a3jp+fB3dApH6EnspDffnS75BsD6wDOfXfbv5uqwmtQeXmxQwG0K48tphCusZdX/nLKeV1kLcVLyrWRbLQp6lc/AUNagrcV2jlI/BatJ1xfsW/TmwnEZAK7YSN/qqq7+0WWXX54Jsr9DOIeIa8qtBqdvOSuBjV2Glr8aeTyiudG11QI8p05eA2Oq7Qxu/CKU+32YrYfFAYGfUT2lMXlzUOmgjG0qKmrr6dZiHf9AymnAfTgUhMTr6ut0A/tecPCmq20gzfc1WhdSdg7gVJFtqqsdO2csgO39GJCFUBj5tpe0V/7UOh8ZR7Ybf71MfYA59uadpXQRsm7GLX3xZ7NEw7WdU0Gr9jVizoNXa79Mzms2kD1+dtEsdTs7rpD2aUC5zJj7m+lDhlZsp82uMjfjd3mKTp5Od1vQVuUZmxz8ZlPPbIto8P4aL3k2DvklkKnsM3bdZHyQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK/B93U+fOpCfi/AAAAABJRU5ErkJggg=='
|
|
9
|
+
|
|
10
|
+
function WaterPlusMark({ size, className }) {
|
|
11
|
+
return jsx('img', {
|
|
12
|
+
src: mark,
|
|
13
|
+
width: size,
|
|
14
|
+
height: size,
|
|
15
|
+
className,
|
|
16
|
+
alt: 'WaterPlus AI',
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function WaterPlusName() {
|
|
21
|
+
return jsxs(Fragment, {
|
|
22
|
+
children: [
|
|
23
|
+
jsx('img', { src: wordmark, width: 99, height: 24, alt: 'WaterPlus AI' }),
|
|
24
|
+
jsx('small', {
|
|
25
|
+
style: {
|
|
26
|
+
color: 'var(--dsw-text-tertiary, #7b8494)',
|
|
27
|
+
fontSize: 10,
|
|
28
|
+
fontWeight: 500,
|
|
29
|
+
opacity: 0.7,
|
|
30
|
+
whiteSpace: 'nowrap',
|
|
31
|
+
},
|
|
32
|
+
children: 'Powered by DSH',
|
|
33
|
+
}),
|
|
34
|
+
],
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const inject = ['slots']
|
|
39
|
+
function apply(ctx) {
|
|
40
|
+
ctx.effect(() => {
|
|
41
|
+
const normalizeTitle = () => {
|
|
42
|
+
if (document.title === 'DeepSeek Harness' || document.title === 'DSH Local Build') {
|
|
43
|
+
document.title = 'WaterBuddy'
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
const title = document.title.replace(
|
|
47
|
+
/ — (?:DeepSeek Harness|DSH Local Build)$/,
|
|
48
|
+
' — WaterBuddy',
|
|
49
|
+
)
|
|
50
|
+
if (title !== document.title) document.title = title
|
|
51
|
+
}
|
|
52
|
+
normalizeTitle()
|
|
53
|
+
const observer = new MutationObserver(normalizeTitle)
|
|
54
|
+
observer.observe(document.head, { childList: true, subtree: true, characterData: true })
|
|
55
|
+
return () => { observer.disconnect() }
|
|
56
|
+
}, 'waterbuddy: document title')
|
|
57
|
+
ctx.slots.inject('sidebar.brand.mark', () =>
|
|
58
|
+
ctx.slots.inject('sidebar.brand.name', function* () {
|
|
59
|
+
yield ctx.slots.register({ name: 'sidebar.brand.mark' }, WaterPlusMark)
|
|
60
|
+
yield ctx.slots.register({ name: 'sidebar.brand.name' }, WaterPlusName)
|
|
61
|
+
}))
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
exports.inject = inject
|
|
65
|
+
exports.apply = apply
|
|
66
|
+
return module.exports
|
|
67
|
+
},
|
|
68
|
+
})
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const WATERPLUS_ICON = Buffer.from('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', 'base64')
|
|
2
|
+
|
|
3
|
+
import { WATERPLUS_PERSONA } from '../shared/persona.js'
|
|
4
|
+
|
|
5
|
+
const MANIFEST = JSON.stringify({
|
|
6
|
+
id: '/',
|
|
7
|
+
name: 'WaterBuddy',
|
|
8
|
+
short_name: 'WaterBuddy',
|
|
9
|
+
start_url: '/',
|
|
10
|
+
scope: '/',
|
|
11
|
+
display: 'fullscreen',
|
|
12
|
+
icons: [{ src: '/waterplus-mark.png', sizes: '84x84', type: 'image/png', purpose: 'any' }],
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
/** Required host service: the HTTP server that serves the Web profile. */
|
|
16
|
+
export const inject = ['webServer', 'systemPrompt']
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Install the WaterBuddy Web identity without replacing dsh-web-app. The
|
|
20
|
+
* named routes own only the brand icon and manifest; all other assets
|
|
21
|
+
* continue through the official static frontend fallback.
|
|
22
|
+
* @param ctx - Host context carrying the Web server service.
|
|
23
|
+
*/
|
|
24
|
+
export function apply(ctx) {
|
|
25
|
+
ctx.effect(() => {
|
|
26
|
+
const disposeFavicon = ctx.webServer.register({
|
|
27
|
+
kind: 'exact',
|
|
28
|
+
path: '/waterplus-mark.png',
|
|
29
|
+
handler: (_req, res) => {
|
|
30
|
+
res.writeHead(200, {
|
|
31
|
+
'content-type': 'image/png',
|
|
32
|
+
'cache-control': 'public, max-age=3600',
|
|
33
|
+
})
|
|
34
|
+
res.end(WATERPLUS_ICON)
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
const disposeManifest = ctx.webServer.register({
|
|
38
|
+
kind: 'exact',
|
|
39
|
+
path: '/manifest.webmanifest',
|
|
40
|
+
handler: (_req, res) => {
|
|
41
|
+
res.writeHead(200, {
|
|
42
|
+
'content-type': 'application/manifest+json; charset=utf-8',
|
|
43
|
+
'cache-control': 'public, max-age=3600',
|
|
44
|
+
})
|
|
45
|
+
res.end(MANIFEST)
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
const disposeTitle = ctx.webServer.tapIndex((html) => {
|
|
49
|
+
const titled = html.replace(/<title>[^<]*<\/title>/i, '<title>WaterBuddy</title>')
|
|
50
|
+
return titled.replace(
|
|
51
|
+
/<link[^>]+rel=["']icon["'][^>]*>/i,
|
|
52
|
+
'<link rel="icon" type="image/png" href="/waterplus-mark.png" />',
|
|
53
|
+
)
|
|
54
|
+
})
|
|
55
|
+
const disposePersona = ctx.systemPrompt.section({
|
|
56
|
+
name: 'waterplus:persona',
|
|
57
|
+
order: 100,
|
|
58
|
+
text: WATERPLUS_PERSONA,
|
|
59
|
+
})
|
|
60
|
+
return () => {
|
|
61
|
+
disposePersona()
|
|
62
|
+
disposeTitle()
|
|
63
|
+
disposeManifest()
|
|
64
|
+
disposeFavicon()
|
|
65
|
+
}
|
|
66
|
+
}, 'waterbuddy: Web identity')
|
|
67
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deployment persona for the WaterPlus internal assistant.
|
|
3
|
+
* Keep this focused on role and domain scope; operational policies belong in
|
|
4
|
+
* separate prompt sections so they can evolve independently.
|
|
5
|
+
*/
|
|
6
|
+
export const WATERPLUS_PERSONA = [
|
|
7
|
+
'你叫“小加”,隶属“水务加”(珠海卓邦科技有限公司简称),是一名水务行业的专属 AI 助手。',
|
|
8
|
+
'你主要服务公司内部人员,重点协助处理水务政策、行业标准、规范文件、招投标信息、行业会议、企业信息和典型案例等问题。',
|
|
9
|
+
'回答问题时,优先依据当前会话提供的资料、工作区文件和可用工具;资料不足时明确说明,不要编造事实。',
|
|
10
|
+
'除非用户另有要求,使用用户提问的语言回答,表达专业、清晰、易读。',
|
|
11
|
+
].join('\n')
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@waterplus-ai/waterbuddy",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "WaterPlus AI WaterBuddy branding and Web profile bundle for DeepSeek Harness",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "lib/host/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./lib/host/index.js",
|
|
10
|
+
"./client": "./lib/client/index.js",
|
|
11
|
+
"./cordis.patch.yml": "./patches/cordis.patch.yml",
|
|
12
|
+
"./package.json": "./package.json"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"lib/host/index.js",
|
|
16
|
+
"lib/client/index.js",
|
|
17
|
+
"lib/shared/persona.js",
|
|
18
|
+
"patches/cordis.patch.yml",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"dsh": {
|
|
22
|
+
"bundle": {
|
|
23
|
+
"patch": "./patches/cordis.patch.yml"
|
|
24
|
+
},
|
|
25
|
+
"client": {
|
|
26
|
+
"platform": "web",
|
|
27
|
+
"inject": [
|
|
28
|
+
"@deepseek-ai/dsh-client-ui-renderer",
|
|
29
|
+
"@deepseek-ai/dsh-client-ui-sidebar"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"test": "node --test tests/*.test.mjs",
|
|
35
|
+
"pack:check": "pnpm pack --dry-run",
|
|
36
|
+
"pack:release": "pnpm pack --pack-destination releases"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# WaterPlus AI WaterBuddy layer. This file is applied after dsh-web-app.
|
|
2
|
+
# The official brand occupant is disabled so the WaterPlus client occupant can
|
|
3
|
+
# claim the same generic sidebar slots without changing the official package.
|
|
4
|
+
- id: ui-brand-official
|
|
5
|
+
disabled: true
|
|
6
|
+
|
|
7
|
+
- insert:
|
|
8
|
+
- id: ui-brand-waterplus
|
|
9
|
+
name: '@waterplus-ai/waterbuddy'
|
|
10
|
+
- id: mcp-xiaojia
|
|
11
|
+
name: '@deepseek-ai/dsh-mcp-client'
|
|
12
|
+
config:
|
|
13
|
+
serverName: Xiaojia
|
|
14
|
+
transport: streamable-http
|
|
15
|
+
url: https://ai.shuiwujia.com/mcp
|