Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/centralized-workspace-storage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"dsh-mnemon": patch
---

Add a built-in centralized workspace storage mode with live root settings, per-workspace routing and read-only inventory. Runtime, Documents, Memory Spaces and state share an isolated workspace subtree; global USER.md remains optional and scope switches preserve existing data.

新增内置的集中工作区存储模式,提供实时根目录设置、工作区路由和只读清单。Runtime、Documents、Memory Spaces 与 state 使用独立工作区子目录,仍可共享全局 USER.md,切换范围保留旧数据。
8 changes: 8 additions & 0 deletions .changeset/workspace-storage-layout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"dsh-mnemon": patch
"dsh-mnemon-source-memory-spaces": patch
---

Keep the workspace picker and alignment action visible when storage labels wrap, and constrain long Memory Space directory paths to their available column.

存储标签换行时保持工作区选择器和对齐操作可见,并将较长的记忆空间目录路径限制在当前列宽内。
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Runtime context, searchable documents and long-term evidence share a familiar Si

A **memory space** is one named, Provider-backed scope for long-term evidence. It contains individual memories and can be activated independently. The Chinese product term is **记忆空间**.

Use the same data from Sidebar, conversation tools or Headless. Global, workspace and custom storage scopes are explicit. Direct retrieval does not spawn a Mnemon task Agent; Agent Query, semantic writes and maintenance may use the configured model. [Workflows and costs](https://github.com/omdsh-dev/dsh-mnemon/blob/main/docs/en/reference/workflows.md).
Use the same data from Sidebar, conversation tools or Headless. Global, workspace, centralized workspace and custom storage scopes are explicit. Direct retrieval does not spawn a Mnemon task Agent; Agent Query, semantic writes and maintenance may use the configured model. [Workflows and costs](https://github.com/omdsh-dev/dsh-mnemon/blob/main/docs/en/reference/workflows.md).

## Start with the default installation

Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

**记忆空间(memory space)** 是由 Provider 承载、可以独立命名和激活的长期证据范围,其中包含多条具体记忆。

Sidebar、对话工具与 Headless 使用同一套数据。全局、工作区与自定义范围明确可选。直接检索不创建 Mnemon 任务 Agent;Agent 查询、语义写入和整理可能使用已配置的模型。[流程与调用开销](https://github.com/omdsh-dev/dsh-mnemon/blob/main/docs/zh-CN/reference/workflows.md)。
Sidebar、对话工具与 Headless 使用同一套数据。全局、工作区、集中工作区与自定义范围明确可选。直接检索不创建 Mnemon 任务 Agent;Agent 查询、语义写入和整理可能使用已配置的模型。[流程与调用开销](https://github.com/omdsh-dev/dsh-mnemon/blob/main/docs/zh-CN/reference/workflows.md)。

## 从默认组合开始

Expand Down
2 changes: 1 addition & 1 deletion docs/en/development/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Check Sidebar without a session, all primary/secondary tabs, Runtime add/edit/re

For an embedded Electron Host, pass `pnpm e2e:serve --electron=/absolute/path/to/electron` (on macOS, use `Electron.app/Contents/MacOS/Electron`). Supply a separately installed test Electron executable and an isolated npm prefix through `MNEMON_CLI_PATH` and `npm_config_prefix`. The fixture runs the published DSH Web stack in Electron's main process with no `ELECTRON_RUN_AS_NODE` on the Host. It exposes Node internals for the published Cordis loader, without rebuilding or modifying DSH packages. Stop with Ctrl-C as usual.

Also switch `displayMode` live: Sidebar and Builtin must never mount together. Both use the same Source pages; Builtin follows its owning session for global/workspace/custom reads, writes and tasks, hides scope controls, and clears stale data and editors when the session changes. Check legacy `buildin` normalization and the collapsed icon under the native Sidebar skin as well as supported layout plugins.
Also switch `displayMode` live: Sidebar and Builtin must never mount together. Both use the same Source pages; Builtin follows its owning session for global/workspace/workspaces/custom reads, writes and tasks, hides scope controls, and clears stale data and editors when the session changes. Check legacy `buildin` normalization and the collapsed icon under the native Sidebar skin as well as supported layout plugins.

The [2026-09-04 main-rebase verification](../../pr-assets/main-rebase-20260904/README.md) records the exact v0.4.7/DSH rc.1 revisions, full registry and source-overlay suites, independent artifacts, plugin composition persistence and real shared-placement checks, including their limits.

Expand Down
6 changes: 6 additions & 0 deletions docs/en/development/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ Like a Spring Boot starter, the default distribution chooses dependencies and ex

`ctx.mnemonMemory` is a real restricted service object, not the engine cast to a narrower type. It exposes one registration primitive, used through `installMemory`; Host execution stays internal. Provider modules follow the same principle inside their own Source, with only a bound `host.install` capability. Public test fixtures exercise these protocols without handing out their private owners.

## Built-in storage scope

Storage layout is part of the root package's Host infrastructure. The same resolver handles `global`, `workspace`, `custom` and `workspaces`; Core carries the selected operation scope and enforces View authority. Filesystem canonicalization, environment/home defaults and workspace directory hashes stay in Host code, without a storage contribution API or a separate package.

The Host passes the resolved directory to each default Source. Sources continue to own their formats, transactions and Provider state; a layout change does not move their data. The opt-in global USER.md uses a separate global root while project data stays under the chosen workspace root. Settings and read-only inventory use the same layout resolver.

## Default plugin combination

| Plugin | Memory authority | Default View contribution |
Expand Down
3 changes: 2 additions & 1 deletion docs/en/guides/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ Tasks follow the DSH new-session model route by default. **Settings → Memory S

Bounded workers may still perform structured judgment internally, but that is an implementation detail. The UI and product documentation consistently call the user-visible unit an **independent task Agent**.

## Global, workspace, and custom scope
## Storage scope

- **Global** uses `~/.mnemon`, suitable for a control plane shared by local workspaces and Agents.
- **Workspace** uses `<workspace>/.mnemon`; local data planes such as Mnemon, Holographic, and ByteRover can follow it automatically.
- **Custom** is effectively a global scope at an explicit path, useful for team conventions and isolated demo roots.
- **Centralized workspaces** (`workspaces`) is built into the Host: one fixed root, independent workspace subdirectories, and optional global USER.md. Scope switches preserve every old root.

Remote Provider workspaces, users, banks, projects, containers, and URIs are their own namespaces. Switching the DSH workspace never silently rewrites them. The workbench may inspect a chosen directory; an independent task Agent always writes according to its effective workspace and saved scope rules.

Expand Down
3 changes: 3 additions & 0 deletions docs/en/guides/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ By default, open the dedicated workbench from Memory System in the DSH sidebar.
| **Global** (default) | `MNEMON_DATA_DIR` or `~/.mnemon` | Sharing one memory set across workspaces |
| **Workspace** | `<workspace>/.mnemon` | Project isolation with cross-workspace inspection in the workbench |
| **Custom** | `dataDir` | A dedicated disk, mounted volume, or explicit directory |
| **Centralized workspaces** | `<central-root>/workspaces/<workspace-path-hash>/` | Central management with project isolation |

For centralized project isolation, select `storageScope: workspaces` and optionally set `dataDir`; data is stored in `<central-root>/workspaces/<workspace-path-hash>/`. The directory setting appears alongside the scope selector. Existing roots are retained when switching modes.

Save initializes a candidate runtime graph before atomically switching the Host. The page clears stale state and reloads automatically—no browser refresh is needed. Changing scope never migrates, merges, or deletes old data.

Expand Down
5 changes: 4 additions & 1 deletion docs/en/guides/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Generate an inventory or checksums and rehearse recovery in isolation. A normal

## Changing storage scope

Saving `global` / `workspace` / `custom` initializes a new runtime graph before switching atomically. The page reloads automatically, but **data is not migrated**:
Saving `global` / `workspace` / `custom` / `workspaces` initializes a new runtime graph before switching atomically. The page reloads automatically, but **data is not migrated**:

```text
old scope -- save --> new empty or existing root
Expand All @@ -110,6 +110,9 @@ no automatic delete

Recommended migration: export from the old scope → switch and confirm the new root → import → verify. In Workspace mode, confirm both inspection and execution targets.

With `workspaces`, back up the complete central directory for every workspace, or export a Pack for the selected workspace only. A renamed/moved workspace receives a new path hash; restoring its old data is an explicit operator action.


Existing turns and delegated child activations may still use the old runtime. Wait for them to finish or cancel them before moving or retiring its data. Parent completion alone does not release an asynchronous child's delegation; a newly created or cold-resumed activation captures its own authorized generation.

<a id="cloud-hosted-webui"></a>
Expand Down
4 changes: 3 additions & 1 deletion docs/en/guides/ui-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Older media remain available with their original version labels in [historical e

The Memory System sidebar entry always opens its workspace, including after visiting Task Board or SSH. Clicking it again keeps the current page open; use Back to conversation to close it.

With `displayMode: builtin`, open Memory System from the conversation's tabs instead; the Sidebar entry is absent. The header omits storage-mode and workspace-selection controls because the Host uses the owning session's global, workspace or custom scope. All Source pages and dialogs below are shared, and conversation shortcuts open the matching tab. See [scope mapping](../reference/configuration.md#entry-placement-displaymode-and-tabenabled).
With `displayMode: builtin`, open Memory System from the conversation's tabs instead; the Sidebar entry is absent. The header omits storage-mode and workspace-selection controls because the Host uses the owning session's global, workspace, centralized workspaces or custom scope. All Source pages and dialogs below are shared, and conversation shortcuts open the matching tab. See [scope mapping](../reference/configuration.md#entry-placement-displaymode-and-tabenabled).

Primary pages remain **Status, Runtime, Documents, Memory Spaces**. Memory Spaces adds **Overview, Recall, Content, Entities**, with **Remember** and **Distillation strategy** at the top right. A generated View is an internal per-turn runtime artifact, not a navigation page; Status does not own plugin discovery or installation.

Expand Down Expand Up @@ -172,6 +172,8 @@ Settings centralizes stable user choices and reusable **service configuration**:
- API Keys use a conventional password field whose eye button toggles visible/hidden; there is no clear-credential checkbox, dedicated Remove row, or saved-secret caption;
- the three enhancement switches apply immediately; the footer Save action persists all other changes without waiting for discovery or recall. Health belongs on Status and instances belong on Overview;
- global / workspace / custom tags show effective scope; Providers with the same scope semantics reuse Mnemon's configuration framework.
- Choose **Settings → Memory System → Memory scope → Centralized · isolated by workspace** to collect project-isolated memory in one directory. Its optional **Central root directory** field is in the same section; leave it empty for `MNEMON_DATA_DIR` or `~/.mnemon`. The independent **Global user profile** option remains available.

- User profile scope is independent: **Global user profile** combines global USER.md with workspace/custom MEMORY.md without moving either source.

Each default layer has one master switch. “On” permits on-demand use; it does not force Recall on every turn.
Expand Down
24 changes: 20 additions & 4 deletions docs/en/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ $DSH_HOME/settings.yaml

The default is commonly `~/.dsh/settings.yaml`. All current settings are marked `live`; after Save, the Host initializes a candidate runtime graph and then switches to it atomically.

The Web settings page edits `storageScope`, the independent `runtimeUserScope`, `dataDir`, Mnemon Native's Ollama embedding override, one master switch for each of the three memory Sources, the background task Agent model route, and the Turn memory and Save-to-memory switches under `mnemon-ui`. Global and Workspace define the scope of the complete memory system; the USER.md profile may explicitly remain global while project memory follows that scope. Mnemon Native owns its Custom data location, embedding runtime, and ZIP backup/migration controls. Each external provider has a collapsible service configuration for reusable endpoints, credentials, or executables. Enabling or saving it discovers the provider's existing namespaces and maps them into Memory Spaces → Overview; disabling it removes those local mappings without deleting provider data. Other advanced settings must be changed directly in YAML.
The Web settings page edits `storageScope`, the independent `runtimeUserScope`, `dataDir`, Mnemon Native's Ollama embedding override, one master switch for each of the three memory Sources, the background task Agent model route, and the Turn memory and Save-to-memory switches under `mnemon-ui`. The scope selector applies to the complete memory system. Centralized workspaces exposes its optional root beside that selector; the USER.md profile may explicitly remain global while project memory follows the selected scope. Mnemon Native owns its Custom data location, embedding runtime, and ZIP backup/migration controls. Each external provider has a collapsible service configuration for reusable endpoints, credentials, or executables. Enabling or saving it discovers the provider's existing namespaces and maps them into Memory Spaces → Overview; disabling it removes those local mappings without deleting provider data. Other advanced settings must be changed directly in YAML.

## Complete Example

```yaml
mnemon:
storageScope: global # global | workspace | custom
storageScope: global # global | workspace | custom | workspaces
runtimeUserScope: storage # storage | global
# dataDir: ~/mnemon-data # required for custom
# cliPath: /opt/homebrew/bin/mnemon
Expand Down Expand Up @@ -63,9 +63,9 @@ mnemon:

| Setting | Default | Range | Implementation Semantics |
|---|---:|---|---|
| `storageScope` | `global` | `global` / `workspace` / `custom` | Controls the root for Runtime, Documents, Memory Spaces, and reserved state as one unit |
| `storageScope` | `global` | `global` / `workspace` / `custom` / `workspaces` | Controls the root for Runtime, Documents, Memory Spaces, and reserved state as one unit |
| `runtimeUserScope` | `storage` | `storage` / `global` | Keeps USER.md in the selected storage root, or overlays the global USER.md while project MEMORY.md and the other layers stay selected-scope |
| `dataDir` | unset | absolute path, `~`, or `~/...` | Required for `custom`; legacy configurations that set only this option automatically resolve to `custom` |
| `dataDir` | unset | absolute path, `~`, or `~/...` | Required for `custom`; optional central root for `workspaces`; legacy configurations that set only this option automatically resolve to `custom` |
| `cliPath` | auto-discovered | executable path | Explicitly selects the Mnemon CLI |
| `store` | unset | `[A-Za-z0-9][A-Za-z0-9_-]*` | Compatibility discovery/preference hint for legacy Stores; semantic operations are routed through Memory Spaces |
| `timeoutMs` | `10000` | 100–120000 ms | Hard timeout for a single CLI call |
Expand Down Expand Up @@ -208,6 +208,21 @@ Each turn then projects `USER.md` from the global root (`MNEMON_DATA_DIR` when s

Changing this setting never copies, merges, or deletes entries. Switching back to `runtimeUserScope: storage` reveals the selected root's original USER.md again. A Mnemon Pack still represents one selected storage root, so a workspace Pack does not silently include the separate global USER.md; back up the global root separately when that profile is important.

### `workspaces`

This built-in mode is available with the Starter; no additional plugin is required. Select **Centralized · isolated by workspace** in Memory scope; configure its optional **Central root directory** in the same section.

```yaml
mnemon:
storageScope: workspaces
dataDir: ~/central-memory # optional; otherwise MNEMON_DATA_DIR or ~/.mnemon
runtimeUserScope: global # optional; share only USER.md
```

All four areas (`runtime`, `data`, `documents`, `state`) live under `<central-root>/workspaces/<sha256(canonical-workspace-path)>/`. Existing symlink aliases resolve to the same ID; different workspace paths remain isolated. A move or rename selects a new ID, with no automatic migration. Sidebar inspection follows the selected registered workspace; Builtin and Headless follow the owning session cwd. Global USER.md still uses `MNEMON_DATA_DIR` or `~/.mnemon`, even when the central root is customized.

Changing scopes never migrates, merges or deletes an old root. A ZIP Pack still contains only the selected workspace root; back up the whole central directory to preserve all workspaces. Remote Provider namespaces retain their own sharing semantics.

### `custom`

```yaml
Expand Down Expand Up @@ -345,6 +360,7 @@ Builtin omits the header's storage-mode badge, workspace picker, and alignment c
| `global` | Shared `MNEMON_DATA_DIR` or `~/.mnemon`, regardless of the session workspace |
| `workspace` | The current session's `<cwd>/.mnemon`; switching conversations follows their respective workspaces |
| `custom` | Configured `dataDir`, regardless of the session workspace |
| `workspaces` | The current session’s subtree under `<central-root>/workspaces/<workspace-path-hash>/` |

The existing `runtimeUserScope: global` exception still keeps USER.md global. Changing placement does not change scope, migrate memory data, or revive the old builtin navigation. Settings RPC applies entry changes live.

Expand Down
5 changes: 4 additions & 1 deletion docs/en/reference/storage-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ Use `global` for a common local root, `custom` for an explicitly agreed root, or

`storageScope` determines the entire root, not just the Mnemon databases. The `workspace` scope resolves an independent `<workspace>/.mnemon` for every registered DSH workspace. The opt-in `runtimeUserScope=global` is the sole split-root exception: Runtime reads USER.md from the global root while MEMORY.md and every other component remain under the selected root. Workbench tasks use the inspected workspace; conversation tools and lifecycle hooks use their owning session's cwd and pinned View. `state/memory-providers.json` stores third-party endpoints, target URIs, identities, and optional credentials. Its mode is `0600`; the Host returns configured field names, never saved credential values.

The `workspaces` layout keeps all four areas under `<central-root>/workspaces/<workspace-path-hash>/`; Host path resolution never creates files or changes old roots. Only explicit `runtimeUserScope: global` places USER.md outside that workspace subtree.


## Runtime Memory

### Semantics
Expand Down Expand Up @@ -133,7 +136,7 @@ User profiles, ordinary conversation, temporary progress, raw large logs, and se

The physical sharing scope of Documents is determined by `storageScope`:

- `workspace`: normally isolated with the project;
- `workspace` / `workspaces`: normally isolated with the project;
- `global` / `custom`: multiple workspaces may share the same `documents/index.json`.

Therefore, “Project Documents” describes the content type and does not guarantee physical isolation by workspace. The current session workspace constrains only `sourcePaths` on new writes.
Expand Down
Loading