@chance722/dsh-inbox 0.2.6 → 0.2.8
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/LICENSE +21 -21
- package/README.md +170 -187
- package/README.zh.md +168 -186
- package/cordis.patch.yml +32 -32
- package/lib/cli.js +1 -0
- package/lib/client.js +4 -1
- package/lib/index.js +93 -12
- package/lib/types/client/messages.d.ts +2 -0
- package/lib/types/host/remote/merge.d.ts +10 -0
- package/lib/types/host/vault/spec.d.ts +38 -0
- package/lib/types/host/vault/vault.d.ts +20 -2
- package/lib/types/shared/panel-wire.d.ts +25 -2
- package/package.json +104 -104
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Chance722
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Chance722
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,187 +1,170 @@
|
|
|
1
|
-
# dsh-inbox
|
|
2
|
-
|
|
3
|
-
** (`dsh`): file whatever you copy into one vault, get it back when you need it — including **by asking your assistant in conversation**.
|
|
6
|
-
|
|
7
|
-
English | [中文](README.zh.md)
|
|
8
|
-
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
The things you copy
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
|
20
|
-
|
|
21
|
-
| **
|
|
22
|
-
| **
|
|
23
|
-
| **
|
|
24
|
-
| **
|
|
25
|
-
| **
|
|
26
|
-
| **
|
|
27
|
-
| **
|
|
28
|
-
| **
|
|
29
|
-
| **
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
```powershell
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
|
129
|
-
|
|
130
|
-
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
pnpm typecheck
|
|
172
|
-
pnpm test # vitest
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
Client-side changes need `pnpm build` and a page reload (dsh's client-hmr reloads it for you); host-side changes need a restart. Details in [docs/help/dev-setup.md](docs/help/dev-setup.md); milestones and acceptance records in the [development bus](docs/feature/dev-bus.md).
|
|
176
|
-
|
|
177
|
-
To switch the profile you actually run between the **published package** and **this checkout** (default profile `web`; set `DSH_PROFILE` for another):
|
|
178
|
-
|
|
179
|
-
```powershell
|
|
180
|
-
pnpm dev:status # which one is in use right now
|
|
181
|
-
pnpm dev:npm # point it at the published version
|
|
182
|
-
pnpm dev:local # point it back here (builds first, then links)
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
## License
|
|
186
|
-
|
|
187
|
-
MIT
|
|
1
|
+
# dsh-inbox
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
A **local inbox plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)** (`dsh`): file whatever you copy into one vault, get it back when you need it — including **by asking your assistant in conversation**.
|
|
6
|
+
|
|
7
|
+
English | [中文](README.zh.md)
|
|
8
|
+
|
|
9
|
+
## What it is
|
|
10
|
+
|
|
11
|
+
The things you copy in a day — a link to read later, a screenshot, a config snippet, an account and password — end up scattered across clipboard history, bookmarks and temp files. dsh-inbox keeps them in one local vault: paste to file, automatic classification, browse and search from the sidebar — and instead of digging through it yourself, ask your assistant "what was that article about caching I saved last month?".
|
|
12
|
+
|
|
13
|
+
Everything lands on your machine, and the model only sees a record when you ask it to look.
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
| Feature | What it does |
|
|
18
|
+
|---|---|
|
|
19
|
+
| **Two ways in** | `/inbox <text or link>` in the composer (attach images to carry them along), or paste / drop / pick a file in the panel |
|
|
20
|
+
| **Automatic classification** | Links by platform and media type (60-odd sites: Bilibili, YouTube, WeChat, 掘金, Zhihu…), text by credential shape, images get a 疑似证件 tag at card proportions; the rest goes to the model, with a daily cap |
|
|
21
|
+
| **Panel** | Filter by watch-later / category / tag, search title, text, link and note, two list densities; the detail pane edits name, category, note and tags, flags watch-later, deletes and restores — and it follows dsh's theme **and language** |
|
|
22
|
+
| **Every record has a name** | A link takes the page's own headline (no model tokens), a photo or file its file name, and the name you type always wins. A page that will not be read — an anti-bot page, a dead link — leaves the address as the name rather than a guess |
|
|
23
|
+
| **Who judged the category** | A coloured badge: 规则判定 (local rules) / 模型判定 (the capped model pass) / 手动判定 (yours — nothing overwrites it later) |
|
|
24
|
+
| **Ask in conversation** | Ask for 收件箱 / 仓库 / inbox and the assistant searches by words, category, tag, watch-later flag or kind (ten at a time plus a count, thumbnails inline) and opens one by id (text up to 1000 characters, link, note, tags, attachments). 「打开 ↗」 under an answer jumps to that record in the 仓库 tab |
|
|
25
|
+
| **Looking at a picture** | Image bytes stay out of the conversation; ask the assistant to look at one and that single image is sent — explicitly, per call |
|
|
26
|
+
| **Credentials are safe** | The body is encrypted at rest, with a key derived from your master password — neither is ever written down. The list shows only the name you gave it, and plain text never reaches a conversation or a model |
|
|
27
|
+
| **Two-way sync** | Point it at a WebDAV folder or an S3 bucket: changes push a few seconds later, 刷新 runs a full push-then-pull merged per record by `id` + timestamp, and emptying the recycle bin deletes the cloud copies too. Two machines see each other when they share one 「目录」 |
|
|
28
|
+
| **Conversation cards** | Tool results render as dsh-inbox cards — links clickable, image markers drawn as thumbnails on your machine |
|
|
29
|
+
| **Gateway quirks** | Some object-storage gateways bind each AccessKey to an "application" and identify clients by a header — so the plugin keeps **one client identity per protocol** |
|
|
30
|
+
|
|
31
|
+
## Screenshots
|
|
32
|
+
|
|
33
|
+

|
|
34
|
+
|
|
35
|
+
## Two ways to use it
|
|
36
|
+
|
|
37
|
+
**① File something from the conversation**
|
|
38
|
+
|
|
39
|
+
`/inbox` in the composer, followed by text or a link, with images attached right there — **this never reaches the model**, it only goes into the vault. That is the way to file credentials and throwaway links.
|
|
40
|
+
|
|
41
|
+
**② Ask for it later**
|
|
42
|
+
|
|
43
|
+
No command, just talk:
|
|
44
|
+
|
|
45
|
+
> which of my saved images is the mini-program code?
|
|
46
|
+
>
|
|
47
|
+
> show me that article about caching I saved last week
|
|
48
|
+
>
|
|
49
|
+
> list the links in my inbox I haven't read yet
|
|
50
|
+
|
|
51
|
+
Two questions in the same conversation, on a real machine:
|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
## Install
|
|
58
|
+
|
|
59
|
+
Needs Node ≥ 22 and a working `dsh`; the installer brings pnpm along when your machine does not have it. **Windows only so far** — macOS and Linux are unverified.
|
|
60
|
+
|
|
61
|
+
```powershell
|
|
62
|
+
# install (`dsh web` is `dsh --profile web`, so this is the profile you already start)
|
|
63
|
+
npx @chance722/dsh-inbox init --profile web --install-pnpm
|
|
64
|
+
|
|
65
|
+
# never run dsh on this machine? create the profile in the same command
|
|
66
|
+
npx @chance722/dsh-inbox init --profile web --create-profile --install-pnpm
|
|
67
|
+
|
|
68
|
+
# update (init only installs and wires things up — re-running it never upgrades;
|
|
69
|
+
# minutes after a release, write the exact version instead: @0.2.8)
|
|
70
|
+
dsh plugin --profile web add @chance722/dsh-inbox@latest
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Restart dsh** afterwards, then start it as usual. **Inbox** is in the left rail, and a new session's assistant can look things up ("what links in my inbox haven't I read yet?").
|
|
74
|
+
|
|
75
|
+
`init` also copies dsh's shipped `standard` preset to `~/.dsh/.agent-presets/inbox/` with this plugin added, and points your default preset at it — that is what lets the assistant see the inbox tools. It becomes a snapshot that will not follow later dsh upgrades; both it and the profile are reversible (see Uninstall).
|
|
76
|
+
|
|
77
|
+
To keep your daily dsh untouched, give the plugin its own profile and port: `npx @chance722/dsh-inbox init --create-profile`, then `dsh --profile inbox --no-open --port 3102`.
|
|
78
|
+
|
|
79
|
+
Other flags: `--profile <name>`, `--install-pnpm`, `--no-default`, `--help`.
|
|
80
|
+
|
|
81
|
+
### From a local checkout
|
|
82
|
+
|
|
83
|
+
```powershell
|
|
84
|
+
git clone <this repo> dsh-inbox ; cd dsh-inbox
|
|
85
|
+
pnpm install ; pnpm build
|
|
86
|
+
node lib/cli.js init --package <absolute path to this repo>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Uninstall
|
|
90
|
+
|
|
91
|
+
```powershell
|
|
92
|
+
# 1. remove the package from the profile you installed it into
|
|
93
|
+
# (also drops it from dsh.profile.bundles)
|
|
94
|
+
dsh plugin --profile <that profile> remove @chance722/dsh-inbox
|
|
95
|
+
|
|
96
|
+
# 2. delete what init created
|
|
97
|
+
rm -r ~/.dsh/.agent-presets/inbox # the preset copy
|
|
98
|
+
# default preset: delete agent-presets.default in ~/.dsh/settings.yaml (falls back to the
|
|
99
|
+
# deployment default) or set it to standard; every init left a settings.yaml.bak-* backup
|
|
100
|
+
|
|
101
|
+
# 3. and the profile itself, if you made one just for this
|
|
102
|
+
rm -r ~/.dsh/profiles/<that profile>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Uninstalling does not delete your vault.** To remove the records too: `rm -r ~/.dsh/storages/dsh_inbox`.
|
|
106
|
+
|
|
107
|
+
## Where things live
|
|
108
|
+
|
|
109
|
+
Everything under `%DSH_HOME%` (`C:\Users\<you>\.dsh` on Windows):
|
|
110
|
+
|
|
111
|
+
| What | Where |
|
|
112
|
+
|---|---|
|
|
113
|
+
| Records: text, links, category, note, tags, watch-later… | `storages\dsh_inbox\items\*.json`, one file each |
|
|
114
|
+
| Attachment index (mime / size / original name) | `storages\dsh_inbox\attachments\*.json` |
|
|
115
|
+
| The **bytes** of images, videos and files | `attachments\` — dsh's own content-addressed store, never auto-deleted |
|
|
116
|
+
| Remote password / S3 AccessKey Secret | dsh's credential store, `.credentials.yaml` |
|
|
117
|
+
| Remote settings (URL, bucket, client identity…) | dsh's own settings |
|
|
118
|
+
|
|
119
|
+
### What the remote looks like
|
|
120
|
+
|
|
121
|
+
With a remote configured and `/inbox` as the directory:
|
|
122
|
+
|
|
123
|
+
| Remote path | What it is |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `inbox/<whatever you drop>` | The **drop folder**: any device drops files here and this one ingests them |
|
|
126
|
+
| `inbox/sync/items/<record id>.json` | One record, **machine-readable** — the source of truth for sync |
|
|
127
|
+
| `inbox/sync/items/<record id>.txt` | The same record, **readable** (text, note, which attachments it points at) |
|
|
128
|
+
| `inbox/sync/attachments/<attachment id>.<ext>` | Attachment **bytes** (images, video, PDFs open as themselves) |
|
|
129
|
+
| `inbox/sync/attachments/<attachment id>.meta.json` | The attachment's metadata (original name, dimensions, size, digest) |
|
|
130
|
+
| A 0-byte key ending in `/` | A folder marker the cloud drive made itself, not us |
|
|
131
|
+
|
|
132
|
+
### How syncing works
|
|
133
|
+
|
|
134
|
+
- **Automatic**: a push seconds after a capture or edit (debounced — several quick saves are one push); 「刷新」 is a full sync: push → pull → re-read the list.
|
|
135
|
+
- **Merging**: per `id` + timestamp, the newer write wins, no conflict copies; needed attachment bytes come down with the record.
|
|
136
|
+
- **Two machines**: one shared 「目录」 (blank, `/` and `inbox` are the same). Records a machine left under an older directory come back if you tick **Merge other sync directories too** in the settings.
|
|
137
|
+
- **Deleting**: 「删除」 only moves a record to the bin and the other devices are told it is gone; emptying the bin deletes the cloud copy as well, and it stays deleted — a copy sitting in another sync directory cannot file it back in.
|
|
138
|
+
|
|
139
|
+
## Privacy and security
|
|
140
|
+
|
|
141
|
+
- **Credential bodies are encrypted at rest** (AES-256-GCM, key derived from your master password). Neither the password nor the key is written down: the vault locks on every restart and you unlock it under 设置 → 账密加密, and a forgotten password means unrecoverable ciphertext. With no master password set, a credential is **refused rather than stored in the clear**.
|
|
142
|
+
- **That covers the body only**: notes, categories, tags, timestamps and attachment **bytes** are not encrypted — a key inside a pasted file is still a key inside a file.
|
|
143
|
+
- **Masked where it matters**: a credential is listed by the name you gave it, and its plain text never reaches a conversation or a model.
|
|
144
|
+
- **Pictures**: classification does send an image to the model, and the conversation gets an `[attachment:id]` marker — that one image is sent only when you explicitly ask the assistant to look at it.
|
|
145
|
+
- **The model cannot see your vault** unless you ask it to look, and classification requests are redacted first.
|
|
146
|
+
- **Your remote needs access control**: only credential bodies are ciphertext up there — text, links, notes and attachment bytes are in the clear, and the master password and key never sync.
|
|
147
|
+
- **One thing the install changes outside the panel**: reading a pasted link's headline is the plugin's only outbound request (one GET, only for links captured on this machine, never for links that came through sync). It goes out with a **browser-shaped** identity, an override of `web-fetch-http.userAgent` shipped in this package's `cordis.patch.yml`. That identity is the whole profile's, the model's own web tools included; **your own `cordis.patch.yml` overrides it**. Details: [docs/help/link-title-fetch.md](docs/help/link-title-fetch.md).
|
|
148
|
+
|
|
149
|
+
## Development
|
|
150
|
+
|
|
151
|
+
```powershell
|
|
152
|
+
pnpm install
|
|
153
|
+
pnpm build # lib/index.js (host) + lib/client.js (panel) + lib/cli.js (init) + lib/types
|
|
154
|
+
pnpm typecheck
|
|
155
|
+
pnpm test # vitest
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Client-side changes need `pnpm build` (dsh's client-hmr reloads the page); host-side changes need a restart. Details in [docs/help/dev-setup.md](docs/help/dev-setup.md), milestones in the [development bus](docs/feature/dev-bus.md).
|
|
159
|
+
|
|
160
|
+
To switch the profile you actually run between the **published package** and **this checkout** (default profile `web`; set `DSH_PROFILE` for another):
|
|
161
|
+
|
|
162
|
+
```powershell
|
|
163
|
+
pnpm dev:status # which one is in use right now
|
|
164
|
+
pnpm dev:npm # point it at the published version
|
|
165
|
+
pnpm dev:local # point it back here (builds first, then links)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## License
|
|
169
|
+
|
|
170
|
+
MIT
|