dsh-cindy-host 0.1.28 → 0.1.30
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/CHANGELOG.md +14 -0
- package/README.md +6 -2
- package/package.json +1 -1
- package/src/host-media-fetch.js +6 -12
- package/src/host-version.js +1 -1
- package/src/host.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.30 — 2026-10-29
|
|
4
|
+
|
|
5
|
+
- Match Cindy native local media fetching: baseDir/workdir constraints are optional; absolute file references no longer fail with no-root. Explicit constraints, sensitive-path checks, regular-file checks and byte limits remain enforced.
|
|
6
|
+
- Fix the shared parser/resolver for all file types and original, thumbnail, prepareOnly and file-peer reads; no PNG-specific workaround or controller changes.
|
|
7
|
+
- Add contract regressions for 15 extensions, POSIX/Windows paths, both file/audio schemes, real filesystem preparation and rootless peer bytes/EOF.
|
|
8
|
+
- Minimal patch on published 0.1.29; preserves its runtime and queue/input-delivery behavior. Requires the same DSH 0.2.1-rc.3 carrier and Node >=22.16. Linux handset end-to-end acceptance requires deployment and is not implied by publication.
|
|
9
|
+
|
|
10
|
+
## 0.1.29 — 2026-10-29
|
|
11
|
+
|
|
12
|
+
- Publish from a clean, committed Git source tree; preserve the accepted 0.1.28 runtime behavior.
|
|
13
|
+
- Make native Android queue/ACK and durable-outbox regression tests offline and repository-contained.
|
|
14
|
+
- Pin upstream Cindy test sources with Apache-2.0 LICENSE and NOTICE; exclude all fixtures from the npm package.
|
|
15
|
+
- Synchronize the dependency lock and version-aware isolated smoke helper; retain current DSH SDK peers without forced upgrades.
|
|
16
|
+
|
|
3
17
|
## 0.1.28 — 2026-10-28
|
|
4
18
|
|
|
5
19
|
- Fix busy input confirmation on both controllers: DSH admission no longer removes an actual pending inbox row from later projections.
|
package/README.md
CHANGED
|
@@ -4,14 +4,18 @@ A Host-side adapter connecting current Cindy clients to DeepSeek Harness.
|
|
|
4
4
|
|
|
5
5
|
## Requirements and installation
|
|
6
6
|
|
|
7
|
-
Version 0.1.
|
|
7
|
+
Version 0.1.29 targets the verified **DSH 0.2.1-rc.3** service contracts, with **Node.js >=22.16**. Its DSH peer versions are pinned to this carrier to prevent an installer from mixing a newer prerelease SDK into the running host. The verified Desktop runtime includes Node.js 24.21. Install through the Desktop DSH plugin manager. CLI-managed profiles can use:
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
dsh plugin --profile <profile> add dsh-cindy-host@0.1.
|
|
10
|
+
dsh plugin --profile <profile> add dsh-cindy-host@0.1.29
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Reload the Host plugin after installation. A full DSH restart is separate. Keep existing Cindy sign-in, device identity and settings; do not run two Host processes with the same identity.
|
|
14
14
|
|
|
15
|
+
## 0.1.29: reproducible repository release
|
|
16
|
+
|
|
17
|
+
Runtime behavior is unchanged from the phone- and desktop-accepted 0.1.28. This release synchronizes the verified source, dependency lock and offline native-client contract fixtures into Git. The pinned third-party fixtures are test-only and excluded from the npm package.
|
|
18
|
+
|
|
15
19
|
## 0.1.28: busy enqueue confirmation
|
|
16
20
|
|
|
17
21
|
A real DSH pending inbox occurrence remains in pendingQueue (or steeringQueueClientIds) in enqueue replies, pushes and polling until it is actually claimed or committed. Handing input to DSH is not delivery to the user turn. This fixes 0.1.27 empty follow-up projections overwriting the busy-queue acknowledgment on Android and desktop. Regression tests execute the current Android parser and stale-ACK authority handling, not just the durable outbox state machine.
|
package/package.json
CHANGED
package/src/host-media-fetch.js
CHANGED
|
@@ -8,19 +8,14 @@
|
|
|
8
8
|
* (`apps/desktop/src/main/device-link/mediaFetch.ts`: 解析本机媒体 → 上传 OSS → 返回引用):
|
|
9
9
|
*
|
|
10
10
|
* ```
|
|
11
|
-
* request { url: 'xdt-file://open?path=<abs
|
|
11
|
+
* request { url: 'xdt-file://open?path=<abs>', thumbnail?, skipCache?, prepareOnly? }
|
|
12
12
|
* response { ossKey, mimeType, size } // the controller presign-gets the key
|
|
13
13
|
* ```
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* constraint" for old controllers; here a request that names no root (neither `baseDir`
|
|
20
|
-
* nor the `workdir` a chat image carries) is refused. Without that, any absolute path
|
|
21
|
-
* on this machine would be servable by anyone who can reach the Host.
|
|
22
|
-
* 2. **Realpath on both sides.** A symlink inside the workspace must not become a way out
|
|
23
|
-
* of it, and `/tmp` vs `/private/tmp` must not make a legitimate file look outside.
|
|
15
|
+
* Directory constraints are optional, matching Cindy's native media-fetch contract.
|
|
16
|
+
* A plain absolute `path` is accepted; when `baseDir` or `workdir` is supplied, both
|
|
17
|
+
* the file and the root are realpath'd before containment checks. This prevents a
|
|
18
|
+
* symlink from escaping a supplied root and handles `/tmp` vs `/private/tmp` aliases.
|
|
24
19
|
*
|
|
25
20
|
* Malformed constraint parameters are refused rather than ignored: silently degrading to
|
|
26
21
|
* "unconstrained" is how a constraint gets removed by a typo.
|
|
@@ -266,7 +261,6 @@ export function parseMediaFetchRequest(url) {
|
|
|
266
261
|
if (value.trim() === '' || !isAbsoluteMediaPath(value)) return { ok: false, reason: `invalid-${key}` };
|
|
267
262
|
roots.push(value);
|
|
268
263
|
}
|
|
269
|
-
if (roots.length === 0) return { ok: false, reason: 'no-root' };
|
|
270
264
|
|
|
271
265
|
let maxBytes = null;
|
|
272
266
|
const rawMaxBytes = parsed.searchParams.get('maxBytes');
|
|
@@ -316,7 +310,7 @@ export function createLocalFileResolver({
|
|
|
316
310
|
// A root that does not resolve cannot authorise anything; the others still can.
|
|
317
311
|
}
|
|
318
312
|
}
|
|
319
|
-
if (
|
|
313
|
+
if (request.roots.length > 0 && !allowedRoots.some((root) => isInsideDirectory(real, root))) {
|
|
320
314
|
return { ok: false, code: 'FORBIDDEN', message: 'the requested file is outside the directory the controller named' };
|
|
321
315
|
}
|
|
322
316
|
if (isBlockedMediaPath(real, blocked)) {
|
package/src/host-version.js
CHANGED
package/src/host.js
CHANGED
|
@@ -227,8 +227,8 @@ export async function startHost(initialSource, settings = DEFAULT_HOST_SETTINGS,
|
|
|
227
227
|
*
|
|
228
228
|
* The chat-image path: a picture the agent produced is referenced by path in the
|
|
229
229
|
* transcript, and the controller resolves it through `device-link:media:fetch`. Same
|
|
230
|
-
* uploader as the file browser's export ops
|
|
231
|
-
*
|
|
230
|
+
* uploader as the file browser's export ops. Directory constraints are optional, as
|
|
231
|
+
* in Cindy; when supplied, both the file and the root are realpath'd before checking.
|
|
232
232
|
*/
|
|
233
233
|
const fetchLocalMedia = createLocalMediaFetcher({ uploader: uploadMedia });
|
|
234
234
|
const resolvePeerFile = createLocalFileResolver({ maxBytes: FILE_PEER_MAX_BYTES });
|