@openviking/dsh-memory-plugin 0.5.12 → 0.5.14

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 CHANGED
@@ -228,7 +228,7 @@ The older size settings apply to fallback recall, not the primary context reques
228
228
  - `tools/pre-execute` denies a DSH filesystem tool (`read`, `glob`, `grep`, `edit`, `write`, `str_replace_editor`) whose path argument is a `viking://` URI, pointing the model at the bridged `mcp__openviking__*` tools instead. A `write` or `edit` under a skill directory (`viking://~/skills/...`, `viking://user/<id>/skills/...`, `viking://agent/skills/...`) points at `mcp__openviking__add_skill` instead, which creates or replaces a whole skill from its `SKILL.md` text. A `grep` whose pattern is `viking://` text still runs.
229
229
  - `tools/post-execute` lets a `bash` command that carries a `viking://` URI run unchanged and attaches a notice for the model: use the bridged tools if it meant OpenViking content, or ignore the notice when the URI is intentional data such as an `ov` argument or an HTTP payload.
230
230
 
231
- Each DSH session maps to `dsh-<session-id>` in OpenViking. Workspace-derived actor peers are resolved per session and sent on every session-specific request: the peer is the git identity of the session's workspace — the normalized `origin` URL (`git@github.com:volcengine/OpenViking.git` becomes `github.com-volcengine-openviking`), else the repository root path, that fallback keeping the older rule where every non-letter-or-digit character becomes `-`. With the default peer settings, no peer is sent outside a git repository, and what is remembered there goes to the user-level space `viking://user/<you>/memories`. One repository therefore keeps one peer across subdirectories, worktrees, clones and machines, while a fork's different origin keeps it separate. Memories written under the older path-derived peer stay reachable: the default `recallPeerScope: all` sweeps every peer under the user.
231
+ Each DSH session maps to `dsh-<session-id>` in OpenViking. IDs that contain Windows-invalid path characters are normalized to a readable underscore form plus a stable hash, so two native IDs cannot collapse onto the same OpenViking session; already-portable IDs keep their existing mapping. Existing sessions whose native IDs require normalization start a new OpenViking session after this upgrade. Workspace-derived actor peers are resolved per session and sent on every session-specific request: the peer is the git identity of the session's workspace — the normalized `origin` URL (`git@github.com:volcengine/OpenViking.git` becomes `github.com-volcengine-openviking`), else the repository root path, that fallback keeping the older rule where every non-letter-or-digit character becomes `-`. With the default peer settings, no peer is sent outside a git repository, and what is remembered there goes to the user-level space `viking://user/<you>/memories`. One repository therefore keeps one peer across subdirectories, worktrees, clones and machines, while a fork's different origin keeps it separate. Memories written under the older path-derived peer stay reachable: the default `recallPeerScope: all` sweeps every peer under the user.
232
232
 
233
233
  Workspace peer settings are loaded from `session.header.cwd` when the session first uses memory. A workspace can set `peer.id` to name its project explicitly, or `peer.source` to choose a preset or template chain. For example, `<root>/.openviking/config.json` can contain:
234
234
 
package/config.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { buildPluginConfig } from "./shared/plugin-config.mjs";
2
2
  import { loadCredentialFiles } from "./shared/credentials.mjs";
3
3
 
4
- export const PLUGIN_VERSION = "0.5.12";
4
+ export const PLUGIN_VERSION = "0.5.14";
5
5
 
6
6
  /**
7
7
  * Namespace for the bridged OpenViking MCP tools. DSH publishes every MCP tool
package/icon.svg CHANGED
@@ -1,17 +1,4 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-label="OpenViking" focusable="false">
2
- <title>OpenViking</title>
3
- <style>
4
- /* Monochrome mark. The plugin card renders this file as an image document,
5
- which cannot read the page palette, so the two inks are declared here and
6
- the scheme flip comes from the only signal an image document gets:
7
- prefers-color-scheme. The base fill attribute keeps the black ink in
8
- renderers that lack that query, and the class is named after the product
9
- to stay unique if this file is ever inlined. */
10
- @media (prefers-color-scheme: dark) {
11
- .openviking-mark { fill: #ffffff; }
12
- }
13
- </style>
14
- <path class="openviking-mark" fill="#000000" d="M21.9136 11.2875C21.8311 15.6708 18.953 19.691 14.5292 21.0217C10.1055 22.3524 5.48691 20.587 3 16.9758L6.35328 15.9668C8.52232 18.6563 12.1802 19.9123 15.6932 18.8558C19.2062 17.7993 21.5646 14.7335 21.8903 11.2938L21.9136 11.2867V11.2875Z"/>
15
- <path class="openviking-mark" fill="#000000" d="M11.9754 2.26476C14.2745 3.4155 19.0247 7.27598 19.1416 14.5217L9.68011 17.3709C10.3938 16.4998 11.0303 15.5158 11.5546 14.4446L15.4019 13.2751C16.6438 8.11275 14.2504 4.18838 11.9941 2.3115C11.9878 2.29592 11.9816 2.28034 11.9754 2.26398V2.26476ZM11.9941 2.31228C13.7548 6.71269 13.2274 11.0251 11.5546 14.4446L8.98047 15.2268C12.4085 10.0457 12.4865 5.64375 11.9699 2.29125C11.9785 2.29826 11.9863 2.30527 11.9941 2.3115V2.31228Z"/>
16
- <path class="openviking-mark" fill="#000000" d="M11.9909 2.31144C13.7517 6.71185 13.2243 11.0242 11.5515 14.4437L8.97656 15.2259C12.4046 10.0449 12.4826 5.64291 11.966 2.29041C11.9746 2.29742 11.9824 2.30443 11.9902 2.31066L11.9909 2.31144Z"/>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#07090D">
2
+ <style>@media (prefers-color-scheme: dark) { .openviking-mark { fill: #F4F5F3; } }</style>
3
+ <g class="openviking-mark"><polygon points="2,21 6,21 18,3"/><polygon points="9,21 21,3 21,21"/></g>
17
4
  </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openviking/dsh-memory-plugin",
3
- "version": "0.5.12",
3
+ "version": "0.5.14",
4
4
  "description": "OpenViking memory and context bundle for DeepSeek Harness",
5
5
  "icon": "./icon.svg",
6
6
  "type": "module",
@@ -20,6 +20,7 @@
20
20
  "mcp.mjs",
21
21
  "mcp-env.mjs",
22
22
  "runtime.mjs",
23
+ "session-id.mjs",
23
24
  "skills.mjs",
24
25
  "uri-guard.mjs",
25
26
  "servers/",
package/runtime.mjs CHANGED
@@ -1,7 +1,6 @@
1
1
  import { isCaptureEnabled } from "./shared/capture-utils.mjs";
2
2
  import { buildProfileBlock } from "./shared/profile-inject.mjs";
3
3
  import { buildRecallBlock, isRecallEnabled } from "./shared/recall-core.mjs";
4
- import { deriveHarnessSessionId } from "./shared/session-model.mjs";
5
4
  import {
6
5
  dequeue,
7
6
  enqueue,
@@ -16,6 +15,7 @@ import {
16
15
  pluginMessage,
17
16
  promptText,
18
17
  } from "./capture.mjs";
18
+ import { deriveDshSessionId } from "./session-id.mjs";
19
19
 
20
20
  export class OpenVikingRuntime {
21
21
  constructor(client, config, logger = console, resolveSessionPeer = null) {
@@ -45,7 +45,7 @@ export class OpenVikingRuntime {
45
45
  });
46
46
  state = {
47
47
  dshSessionId: String(session.id),
48
- ovSessionId: deriveHarnessSessionId("dsh-", String(session.id)),
48
+ ovSessionId: deriveDshSessionId(session.id),
49
49
  config: { ...this.config, peerId: peer.peerId, legacyPeerId: peer.legacyPeerId },
50
50
  ready: false,
51
51
  profileBlock: "",
package/session-id.mjs ADDED
@@ -0,0 +1,21 @@
1
+ import { createHash } from "node:crypto";
2
+ import { deriveHarnessSessionId } from "./shared/session-model.mjs";
3
+
4
+ // Keep identifiers valid as a single path component on Windows. The `dsh-`
5
+ // prefix also prevents reserved device names such as CON and NUL from matching
6
+ // the whole component.
7
+ const WINDOWS_UNSAFE = /[<>:"/\\|?*\u0000-\u001F]/g;
8
+ const WINDOWS_UNSAFE_TRAILING = /[. ]+$/g;
9
+
10
+ export function deriveDshSessionId(sessionId) {
11
+ const original = deriveHarnessSessionId("dsh-", String(sessionId));
12
+ const portable = original
13
+ .replace(WINDOWS_UNSAFE, "_")
14
+ .replace(WINDOWS_UNSAFE_TRAILING, match => "_".repeat(match.length));
15
+ if (portable === original) return original;
16
+
17
+ // Replacement alone is lossy (`im:a` and `im?a` both become `im_a`). Keep a
18
+ // readable stem and add a stable digest whenever normalization was needed.
19
+ const digest = createHash("sha256").update(original).digest("hex").slice(0, 12);
20
+ return `${portable}__${digest}`;
21
+ }