docs: describe Deals as the user-facing unit

This commit is contained in:
mirivlad 2026-07-14 23:57:50 +08:00
parent f9b20d51ff
commit 41aeefc182
4 changed files with 74 additions and 72 deletions

View File

@ -7,7 +7,7 @@
### Keep the context of your work together — locally. ### Keep the context of your work together — locally.
Files, notes, links, browser captures, activity and work history Files, notes, links, browser captures, activity and work history
in one extensible local-first workspace. in one extensible local-first workbench.
**English** · [Русский](README.ru.md) **English** · [Русский](README.ru.md)
@ -29,7 +29,7 @@ in one extensible local-first workspace.
Verstak is a local-first workbench that keeps the context around your work in one place. Verstak is a local-first workbench that keeps the context around your work in one place.
A **workspace** can represent almost anything: A **Deal** can represent almost anything:
* a software project; * a software project;
* a client or customer; * a client or customer;
@ -47,11 +47,11 @@ No account, cloud service or sync server is required for local use.
## Verstak in use ## Verstak in use
| Overview: return to a workspace and see its recent work, captures and items that need attention. | Files: manage ordinary folders and documents inside a workspace. | | Overview: return to a Deal and see its recent work, captures and items that need attention. | Files: manage ordinary folders and documents inside a Deal. |
| --- | --- | | --- | --- |
| ![Verstak Overview in a test vault](docs/screenshots/overview.png) | ![Verstak workspace files in a test vault](docs/screenshots/workspace-files.png) | | ![Verstak Overview in a test vault](docs/screenshots/overview.png) | ![Verstak Deal files in a test vault](docs/screenshots/workspace-files.png) |
| Notes: keep Markdown notes next to the workspace they describe. | Journal: record a completed session and retain its context. | | Notes: keep Markdown notes next to the Deal they describe. | Journal: record a completed session and retain its context. |
| --- | --- | | --- | --- |
| ![Verstak notes in a test vault](docs/screenshots/notes.png) | ![Verstak journal in a test vault](docs/screenshots/journal.png) | | ![Verstak notes in a test vault](docs/screenshots/notes.png) | ![Verstak journal in a test vault](docs/screenshots/journal.png) |
@ -59,17 +59,17 @@ No account, cloud service or sync server is required for local use.
| Feature | Description | | Feature | Description |
| ------------------------ | -------------------------------------------------------------------------------------------- | | ------------------------ | -------------------------------------------------------------------------------------------- |
| **Workspaces** | Organize files, notes and activity around durable projects, clients and other areas of work. | | **Deals** | Organize files, notes and activity around durable projects, clients and other areas of work. |
| **Files** | Browse and manage ordinary files stored inside your vault. | | **Files** | Browse and manage ordinary files stored inside your vault. |
| **Notes** | Create Markdown notes, overview pages and links between related information. | | **Notes** | Create Markdown notes, overview pages and links between related information. |
| **Overview** | Quickly return to recent work and see what may need attention. | | **Overview** | Quickly return to recent work and see what may need attention. |
| **Browser Inbox** | Send pages, links, selections and files from a browser into Verstak. | | **Browser Inbox** | Send pages, links, selections and files from a browser into Verstak. |
| **Activity and Journal** | Reconstruct work sessions and turn selected activity into journal entries. | | **Activity and Journal** | Reconstruct work sessions and turn selected activity into journal entries. |
| **Todo** | Keep optional task lists inside individual workspaces and across the whole vault. | | **Todo** | Keep optional task lists inside individual Deals and across the whole vault. |
| **Search** | Search across notes, files and supported plugin data. | | **Search** | Search across notes, files and supported plugin data. |
| **Trash** | Restore deleted items or remove them permanently from one central location. | | **Trash** | Restore deleted items or remove them permanently from one central location. |
| **Secrets** | Keep credentials and access information connected to the relevant workspace. | | **Secrets** | Keep credentials and access information connected to the relevant Deal. |
| **Templates** | Create repeatable workspace structures for common types of work. | | **Templates** | Create repeatable Deal structures for common types of work. |
| **Plugins** | Add, replace or disable tools without turning Verstak into one rigid monolithic application. | | **Plugins** | Add, replace or disable tools without turning Verstak into one rigid monolithic application. |
| **Optional sync** | Synchronize vaults between devices using a self-hosted Verstak Sync Server. | | **Optional sync** | Synchronize vaults between devices using a self-hosted Verstak Sync Server. |
@ -151,9 +151,9 @@ Documents/
Your files and notes remain ordinary files that can be accessed without Verstak. Your files and notes remain ordinary files that can be accessed without Verstak.
### 2. Create your first workspace ### 2. Create your first Deal
Inside the vault, create a workspace for a project, client, server, device or another area of work. Inside the vault, create a Deal for a project, client, server, device or another area of work.
For example: For example:
@ -167,7 +167,7 @@ Training course
### 3. Add context ### 3. Add context
Open the workspace and add the information needed to return to it later: Open the Deal and add the information needed to return to it later:
* notes and decisions; * notes and decisions;
* documents and source files; * documents and source files;
@ -245,15 +245,15 @@ for distribution-specific dependencies.
The desktop, SDK and official plugin repositories must be cloned as sibling directories: The desktop, SDK and official plugin repositories must be cloned as sibling directories:
```text ```text
verstak-workspace/ verstak-source/
├── verstak/ ├── verstak/
├── verstak-sdk/ ├── verstak-sdk/
└── verstak-official-plugins/ └── verstak-official-plugins/
``` ```
```bash ```bash
mkdir verstak-workspace mkdir verstak-source
cd verstak-workspace cd verstak-source
git clone https://github.com/mirivlad/verstak.git git clone https://github.com/mirivlad/verstak.git
git clone https://github.com/mirivlad/verstak-sdk.git git clone https://github.com/mirivlad/verstak-sdk.git

View File

@ -244,15 +244,15 @@ sha256sum -c SHA256SUMS --ignore-missing
Desktop, SDK и официальные плагины должны находиться в соседних каталогах: Desktop, SDK и официальные плагины должны находиться в соседних каталогах:
```text ```text
verstak-workspace/ verstak-source/
├── verstak/ ├── verstak/
├── verstak-sdk/ ├── verstak-sdk/
└── verstak-official-plugins/ └── verstak-official-plugins/
``` ```
```bash ```bash
mkdir verstak-workspace mkdir verstak-source
cd verstak-workspace cd verstak-source
git clone https://github.com/mirivlad/verstak.git git clone https://github.com/mirivlad/verstak.git
git clone https://github.com/mirivlad/verstak-sdk.git git clone https://github.com/mirivlad/verstak-sdk.git

View File

@ -464,7 +464,7 @@ contributions summary.
Conflicts are rejected unless `options.overwrite` is true. Conflicts are rejected unless `options.overwrite` is true.
- `files.deleteTrash(trashId)` — permanently removes a file/folder already in - `files.deleteTrash(trashId)` — permanently removes a file/folder already in
internal trash. This operation cannot be undone. internal trash. This operation cannot be undone.
- UI policy: the workspace `Files` plugin displays only live files and folders. - UI policy: the Deal `Files` plugin displays only live files and folders.
The global official `verstak.trash` plugin owns listing, restoring, filtering, The global official `verstak.trash` plugin owns listing, restoring, filtering,
and permanently deleting deleted items across the vault. and permanently deleting deleted items across the vault.
- `files.openExternal(relativePath)` — opens a vault-relative file/folder in - `files.openExternal(relativePath)` — opens a vault-relative file/folder in
@ -635,7 +635,7 @@ bundled runtime. Это реальный runtime contract для cooperative bun
1. Unregister contributions всех plugins предыдущего discovery. 1. Unregister contributions всех plugins предыдущего discovery.
2. Unregister all non-core capabilities. 2. Unregister all non-core capabilities.
3. Re-register core capabilities + vault + workspace (если открыт). 3. Re-register core capabilities + vault + Deal manager (если открыт).
4. Re-scan discovery directories и повторить capability resolution. 4. Re-scan discovery directories и повторить capability resolution.
5. Register contributions для loaded/degraded plugins (disabled/failed — не регистрируются). 5. Register contributions для loaded/degraded plugins (disabled/failed — не регистрируются).
6. Update plugins list. 6. Update plugins list.
@ -838,51 +838,52 @@ Vault plugin state хранится **внутри vault** в `.verstak/plugins.
- `./scripts/smoke-platform.sh` — ✅ (enable/disable/plugins.json) - `./scripts/smoke-platform.sh` — ✅ (enable/disable/plugins.json)
- `./scripts/build.sh` — ✅ - `./scripts/build.sh` — ✅
## Workspace Core Capability ## Дело: core capability
Workspace — это физическая папка верхнего уровня внутри vault root. Filesystem Дело — это физическая папка верхнего уровня внутри vault root. Filesystem
является source of truth для списка workspaces. является source of truth для списка Дел.
Пример: Пример:
``` ```
<vault>/ <vault>/
Workspace/ Deal/
Notes/ Notes/
Project/ Project/
ClientA/ ClientA/
.verstak/ .verstak/
``` ```
Нет единого `<vault>/Workspace/` контейнера для всех workspaces. Папка Нет единого `<vault>/Deal/` контейнера для всех Дел. Папка `Deal/` может быть
`Workspace/` может быть обычным workspace, но `Project/` и `ClientA/` являются обычным Делом, но `Project/` и `ClientA/` являются такими же Делами на том же
такими же workspace на том же уровне. уровне.
### Хранение ### Хранение
Workspace existence/list хранится только в filesystem: Существование и список Дел хранятся только в filesystem:
- `ListWorkspaces()` читает top-level directories из vault root. - `ListWorkspaces()` читает top-level directories из vault root.
- `.verstak`, reserved/internal directories, top-level files и symlinks не - `.verstak`, reserved/internal directories, top-level files и symlinks не
считаются workspaces. считаются Делами.
- `.verstak/workspace*.json` не является source of truth для списка workspaces. - `.verstak/workspace*.json` не является source of truth для списка Дел.
- Нет persisted workspace path mapping и нет virtual workspace tree, которое - Нет virtual workspace tree, которое
мапится на произвольные папки. мапится на произвольные папки.
`.verstak` может хранить только metadata, которая не заменяет filesystem: `.verstak` может хранить только metadata, которая не заменяет filesystem:
- UI state: selected workspace, expanded folders, sort/pin state, preferences. - UI state: выбранное Дело, expanded folders, sort/pin state, preferences.
- Semantic snapshot: applied template snapshot, enabled feature areas, exact - Semantic snapshot: applied template snapshot, enabled feature areas, exact
`workspaceTools`, and folder conventions. `workspaceTools`, and folder conventions.
Template snapshot копируется в metadata при создании workspace. Workspace При создании Дела runtime генерирует UUID и сохраняет его в
identity при этом остаётся именем top-level folder; `metadata.workspaceName` `.verstak/workspace.json`. `workspaceId` — постоянная личность Дела;
является presentation/snapshot field, not canonical identity. Если сохранённое `workspaceRootPath` и `workspaceName` — изменяемый адрес и presentation fields.
значение расходится с именем папки, runtime возвращает canonical `workspaceName` Переименование обновляет путь, но не ID. Новая папка с прежним именем получает
равным имени папки без filesystem side effects. другой ID и не может перехватить старые привязки.
```json ```json
{ {
"workspaceId": "1eb7cc69-52e8-4a18-ae2a-50d5229c5b60",
"workspaceName": "Project", "workspaceName": "Project",
"createdFromTemplate": { "createdFromTemplate": {
"templateId": "project", "templateId": "project",
@ -921,25 +922,25 @@ identity при этом остаётся именем top-level folder; `metada
} }
``` ```
Если original template удалён или изменён позже, существующий workspace Если original template удалён или изменён позже, существующее Дело
открывается по сохранённому snapshot и не мутирует автоматически. Template открывается по сохранённому snapshot и не мутирует автоматически. Template
update/migration может быть только явной future feature. Если metadata update/migration может быть только явной future feature. Если metadata
отсутствует, workspace открывается как generic workspace минимум с `files: true`. отсутствует, Дело открывается как generic Deal минимум с `files: true`.
### API ### API
- `ListWorkspaces()` — список top-level physical folders. - `ListWorkspaces()` — список top-level папок Дел с их `workspaceId`.
- `ListWorkspaceTemplates()` — selectable built-in templates с presentation - `ListWorkspaceTemplates()` — selectable built-in templates с presentation
metadata и `workspaceTools`. metadata и `workspaceTools`.
- `CreateWorkspace(name, templateId?)` — создать `<vault>/<name>/`, применить - `CreateWorkspace(name, templateId?)` — создать `<vault>/<name>/`, применить
template один раз, сохранить snapshot metadata. template один раз, сохранить snapshot metadata.
- `RenameWorkspace(oldName, newName)` — физически переименовать top-level folder - `RenameWorkspace(oldName, newName)` — физически переименовать top-level папку
и обновить metadata key/name. Дела и обновить metadata name, не меняя `workspaceId`.
- `TrashWorkspace(name)` — перенести весь top-level workspace folder в internal - `TrashWorkspace(name)` — перенести весь top-level folder Дела в internal
trash policy. trash policy.
- `GetWorkspaceMetadata(name)` — прочитать metadata или вернуть generic fallback. - `GetWorkspaceMetadata(name)` — прочитать metadata или вернуть generic fallback.
- `UpdateWorkspaceMetadata(name, patch)` — обновить metadata без влияния на - `UpdateWorkspaceMetadata(name, patch)` — обновить metadata без влияния на
существование workspace. существование Дела.
Deprecated compatibility APIs: Deprecated compatibility APIs:
@ -949,7 +950,7 @@ Deprecated compatibility APIs:
- `ArchiveWorkspaceNode(...)` — wrapper over `TrashWorkspace`. - `ArchiveWorkspaceNode(...)` — wrapper over `TrashWorkspace`.
- `MoveWorkspaceNode(...)` — unsupported; old nested/mapped moves are rejected. - `MoveWorkspaceNode(...)` — unsupported; old nested/mapped moves are rejected.
- `GetCurrentWorkspaceNode()` / `SetCurrentWorkspaceNode(...)` — wrappers over - `GetCurrentWorkspaceNode()` / `SetCurrentWorkspaceNode(...)` — wrappers over
selected top-level workspace UI state. selected top-level Deal UI state.
Эти методы существуют только для постепенного frontend/Wails cleanup. Они не Эти методы существуют только для постепенного frontend/Wails cleanup. Они не
должны создавать или сохранять nested workspace tree и не должны восстанавливать должны создавать или сохранять nested workspace tree и не должны восстанавливать
@ -957,32 +958,33 @@ Deprecated compatibility APIs:
### Capability ### Capability
`verstak/core/workspace/v1` — регистрируется только когда vault открыт и workspace инициализирован. `verstak/core/workspace/v1` — техническое имя capability; оно регистрируется
только когда vault открыт и Deal manager инициализирован.
### Правила ### Правила
- Workspace name — один safe folder name, не path. - Имя Дела — один safe folder name, не path.
- Reject: empty, slash, backslash, absolute-looking paths, `..`, null byte, - Reject: empty, slash, backslash, absolute-looking paths, `..`, null byte,
`.verstak`, reserved/internal names, symlink workspaces, conflicts. `.verstak`, reserved/internal names, symlink Дел, conflicts.
- WorkspaceItems получают `workspaceRootPath`, равный имени top-level папки - WorkspaceItems получают техническое поле `workspaceRootPath`, равное имени top-level папки
(`Project`, `ClientA`, etc). Files plugin показывает именно эту папку. (`Project`, `ClientA`, etc). Files plugin показывает именно эту папку.
- Files API остаётся raw vault-relative API: `Project/Notes/example.md`, - Files API остаётся raw vault-relative API: `Project/Notes/example.md`,
`Project/docs/file.md`, `Test/readme.md`. `Project/docs/file.md`, `Test/readme.md`.
- Notes are ordinary Markdown files under `<workspace>/Notes/`; нет - Notes are ordinary Markdown files under `<Deal>/Notes/`; нет
`.verstak/notes`, UUID note storage или второго source of truth для note `.verstak/notes`, UUID note storage или второго source of truth для note
content. content.
### Lifecycle Events ### Lifecycle Events
Runtime publishes workspace lifecycle events after successful operations: Runtime publishes lifecycle events Дел после успешных операций:
- `workspace.created` — payload includes `operation: "create"`, - `workspace.created` — payload includes `operation: "create"`, `workspaceId`,
`workspaceRootPath`, `workspaceName`, and optional `templateId`. `workspaceRootPath`, `workspaceName`, and optional `templateId`.
- `workspace.renamed` — payload includes `operation: "rename"`, new - `workspace.renamed` — payload includes `operation: "rename"`, `workspaceId`,
`workspaceRootPath` / `workspaceName`, and previous workspace fields. new `workspaceRootPath` / `workspaceName`, and previous path fields.
- `workspace.trashed` — payload includes `operation: "trash"`, - `workspace.trashed` — payload includes `operation: "trash"`, `workspaceId`,
`workspaceRootPath`, `workspaceName`, `trashId`, `trashPath`, and `deletedAt`. `workspaceRootPath`, `workspaceName`, `trashId`, `trashPath`, and `deletedAt`.
- `workspace.selected` — payload includes `operation: "select"`, - `workspace.selected` — payload includes `operation: "select"`, `workspaceId`,
`workspaceRootPath`, and `workspaceName`. `workspaceRootPath`, and `workspaceName`.
Official Activity subscribes to these events and stores them through the normal Official Activity subscribes to these events and stores them through the normal
@ -990,11 +992,11 @@ activity provider path.
### UI ### UI
Workspace list в sidebar: Список Дел в sidebar:
- Flat list of top-level workspace folders. - Flat list of top-level папок Дел.
- Create workspace, rename workspace, trash workspace. - Создать Дело, переименовать Дело, переместить Дело в корзину.
- Selection is stored as selected workspace name. - Selection is stored as selected Deal name.
- No expand/collapse workspace tree and no case/folder node creation in core. - No expand/collapse tree and no case/folder node creation in core.
--- ---

View File

@ -1,12 +1,12 @@
# Workspace Templates # Deal Templates
Workspace templates choose which dynamic plugin workspace tabs are visible when a Deal templates choose which dynamic plugin Deal tabs are visible when a new
new top-level workspace is created. They do not enable or disable plugins for the top-level Deal is created. They do not enable or disable plugins for the
whole vault and do not affect global sidebar tools. whole vault and do not affect global sidebar tools.
## Built-in templates ## Built-in templates
| Template | Workspace tabs | | Template | Deal tabs |
| --- | --- | | --- | --- |
| General | Notes, Files, Journal, Activity, Browser Inbox | | General | Notes, Files, Journal, Activity, Browser Inbox |
| Project | Notes, Files, Todos, Journal, Activity, Browser Inbox | | Project | Notes, Files, Todos, Journal, Activity, Browser Inbox |
@ -14,27 +14,27 @@ whole vault and do not affect global sidebar tools.
| Admin | Notes, Files, Secrets, Todos, Journal | | Admin | Notes, Files, Secrets, Todos, Journal |
| Minimal | Notes, Files | | Minimal | Notes, Files |
The create-workspace modal displays the selected template description and its The create-Deal modal displays the selected template description and its
included plugin tabs before the folder is created. included plugin tabs before the folder is created.
## Metadata and compatibility ## Metadata and compatibility
Creation stores a template snapshot in `.verstak/workspaces/` metadata. The Creation stores a template snapshot in `.verstak/workspaces/` metadata. The
snapshot contains the template id, name, version, applied time, and an ordered snapshot contains the template id, name, version, applied time, and an ordered
`workspaceTools` list of plugin IDs. Existing workspace metadata without `workspaceTools` list of plugin IDs. Existing Deal metadata without
`workspaceTools` remains compatible: its workspace continues to show all globally `workspaceTools` remains compatible: its Deal continues to show all globally
enabled workspace plugins rather than unexpectedly hiding tabs. enabled Deal plugins rather than unexpectedly hiding tabs.
Templates are applied once. Editing the built-in catalog or creating another Templates are applied once. Editing the built-in catalog or creating another
workspace with a different template never changes an existing workspace snapshot. Deal with a different template never changes an existing Deal snapshot.
There is no template editor or post-creation template switcher yet. There is no template editor or post-creation template switcher yet.
## Global tools and unavailable plugins ## Global tools and unavailable plugins
Template visibility applies only to `workspaceItems` in the selected workspace. Template visibility applies only to `workspaceItems` in the selected Deal.
Global views and sidebar items, such as global Todos, Browser Inbox, and Trash, Global views and sidebar items, such as global Todos, Browser Inbox, and Trash,
remain available according to the normal plugin enablement state. remain available according to the normal plugin enablement state.
The workspace host intersects the snapshot with dynamically discovered, globally The Deal host intersects the snapshot with dynamically discovered, globally
enabled plugin contributions. If a template references a plugin that is missing or enabled plugin contributions. If a template references a plugin that is missing or
disabled, that tab is simply absent; the other template tabs remain usable. disabled, that tab is simply absent; the other template tabs remain usable.