mirror of
https://github.com/Ryder-Sun/Meldwork.git
synced 2026-11-07 06:56:03 -10:00
Refine Meldwork workspace and product strategy
Update the desktop shell, onboarding flow, grouped context selection, and product documentation so the current MVP and outcome-oriented roadmap stay aligned.\n\nChecks: npm --prefix frontend test (117 passed); npm --prefix desktop test (314 passed, 1 timing-sensitive cancellation test failed in the full run and passed when rerun alone); git diff --cached --check.
This commit is contained in:
1 parent
8fa65574fc
commit
b4c706df9f
25 files changed
+1081
-793
No files matched your search
@@ -729,7 +729,11 @@ function createWindow() {
|
||||
minWidth: 980,
|
||||
minHeight: 680,
|
||||
title: 'Meldwork',
|
||||
backgroundColor: '#f3f6f8',
|
||||
backgroundColor: process.platform === 'darwin' ? '#e7edef' : '#f3f6f8',
|
||||
...(process.platform === 'darwin' ? {
|
||||
titleBarStyle: 'hiddenInset',
|
||||
trafficLightPosition: { x: 18, y: 16 },
|
||||
} : {}),
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.cjs'),
|
||||
contextIsolation: true,
|
||||
|
||||
@@ -38,6 +38,7 @@ const isLocalDocument = location.protocol === 'file:'
|
||||
const desktopApi = {
|
||||
isDesktop: true,
|
||||
localOnly: true,
|
||||
platform: process.platform,
|
||||
}
|
||||
|
||||
if (isLocalDocument) Object.assign(desktopApi, {
|
||||
|
||||
@@ -720,6 +720,17 @@ test('ready activates one fixed local workspace and loads the bundled frontend',
|
||||
assert.equal(typeof harness.workspaceInstances[0].input.imageAttachmentLimit, 'function')
|
||||
assert.deepEqual(harness.attachmentInstances[0].cleanupCalls, [[]])
|
||||
assert.equal(harness.windows.length, 1)
|
||||
assert.equal(
|
||||
harness.windows[0].input.backgroundColor,
|
||||
process.platform === 'darwin' ? '#e7edef' : '#f3f6f8',
|
||||
)
|
||||
if (process.platform === 'darwin') {
|
||||
assert.equal(harness.windows[0].input.titleBarStyle, 'hiddenInset')
|
||||
assert.deepEqual(harness.windows[0].input.trafficLightPosition, { x: 18, y: 16 })
|
||||
} else {
|
||||
assert.equal('titleBarStyle' in harness.windows[0].input, false)
|
||||
assert.equal('trafficLightPosition' in harness.windows[0].input, false)
|
||||
}
|
||||
assert.equal(
|
||||
harness.windows[0].loads[0].filename,
|
||||
path.resolve(__dirname, '../../frontend/dist/index.html'),
|
||||
|
||||
@@ -57,6 +57,7 @@ test('local preload exposes the local-only RoundRelay API and narrow Provider me
|
||||
assert.equal(exposedName, 'roundrelayDesktop')
|
||||
assert.equal(Object.isFrozen(api), true)
|
||||
assert.equal(api.localOnly, true)
|
||||
assert.equal(api.platform, process.platform)
|
||||
assert.equal(Object.isFrozen(api.localAgentProvider), true)
|
||||
assert.deepEqual(
|
||||
Object.keys(api.localWorkspace).sort(),
|
||||
|
||||
+9
-9
@@ -1,6 +1,6 @@
|
||||
# Meldwork 文档
|
||||
|
||||
Meldwork 是一个本地优先的 Agent 工作系统。当前仓库是一个 Electron MVP:它把已支持的本地 Agent CLI 放进同一个持久工作空间;长期方向是成为连接本地 Agent、Cloud Agent 与工作渠道的开放 Harness 基座。
|
||||
Meldwork 是一个本地优先的 Agent 工作系统。当前仓库是一个 Electron MVP:它把已支持的本地 Agent CLI、Skill、图片和显式知识来源放进同一个持久工作空间;长期方向是成为连接 Agent、知识上下文、Cloud Agent 与工作渠道的开放工作基座。
|
||||
|
||||
本目录是项目唯一的产品与工程文档入口。`documentation/` 已合并到这里;`archive/` 只保留历史战略版本,不能作为当前产品承诺。
|
||||
|
||||
@@ -8,9 +8,9 @@ Meldwork 是一个本地优先的 Agent 工作系统。当前仓库是一个 Ele
|
||||
|
||||
| 文档 | 用途 | 当前决策 |
|
||||
| --- | --- | --- |
|
||||
| [市场与用户调研](market-user-research.md) | 判断为什么做、为谁做、先验证什么 | 开源优先,当前按非商用协议发布 |
|
||||
| [产品迭代规划](product-iteration-plan.md) | 把愿景拆成一个 OPC 能执行的优先级路线 | 先建立 Harness 基座,再扩展 Cloud/Channel |
|
||||
| [产品 BP](product-bp.md) | 对外解释定位、价值、增长和后续收入 | 先积累开源资产与用户信号,不急于卖席位 |
|
||||
| [市场与用户调研](market-user-research.md) | 判断为什么做、为谁做、先验证什么 | 聚焦 Agent + Knowledge + Outcome,不做聚合聊天器 |
|
||||
| [产品迭代规划](product-iteration-plan.md) | 把愿景拆成一个 OPC 能执行的优先级路线 | 先完成 Context Pack 与 Task Outcome,再扩展 Cloud/Channel |
|
||||
| [产品 BP](product-bp.md) | 对外解释定位、价值、增长和后续收入 | 开源优先,以重复使用和标准化回款决定商业化 |
|
||||
|
||||
## 配套文档
|
||||
|
||||
@@ -27,7 +27,7 @@ Meldwork 是一个本地优先的 Agent 工作系统。当前仓库是一个 Ele
|
||||
|
||||
- **已实现**:当前仓库和测试可以直接支持的能力。
|
||||
- **验证中**:已经有原型或实验,但还没有稳定的用户/可靠性证据。
|
||||
- **路线图**:希望通过 Connector、Task、Artifact、Evidence 等机制交付的未来能力。
|
||||
- **路线图**:希望通过 Context Pack、Connector、Task、Artifact、Evidence 等机制交付的未来能力。
|
||||
- **商业假设**:定价、付费和团队治理相关假设,不能写成当前功能。
|
||||
|
||||
## 协议文件
|
||||
@@ -40,12 +40,12 @@ Meldwork 是一个本地优先的 Agent 工作系统。当前仓库是一个 Ele
|
||||
|
||||
## 当前一句话
|
||||
|
||||
> **Meldwork brings the agents you already use into one local, accountable workspace.**
|
||||
> **Meldwork brings the agents and knowledge sources you already use into one local, accountable workspace.**
|
||||
>
|
||||
> **Meldwork 把你已经在用的 Agent 带进一个本地、可追溯的工作空间。**
|
||||
> **Meldwork 把你已经在用的 Agent 和知识来源带进一个本地、可追溯的工作空间。**
|
||||
|
||||
## 目标一句话
|
||||
|
||||
> **An open harness for work that can move between agents without losing context, control, or proof.**
|
||||
> **An open, local-first work system where context and outcomes can move between agents without losing control or proof.**
|
||||
>
|
||||
> **一套开放的 Agent Harness,让工作可以在不同 Agent 之间流转,同时保留上下文、控制和证据。**
|
||||
> **一套开放、本地优先的 Agent 工作系统,让上下文和结果可以在不同 Agent 之间流转,同时保留控制和证据。**
|
||||
+14
-7
@@ -2,7 +2,7 @@
|
||||
|
||||
## Product Boundary
|
||||
|
||||
Meldwork is a local Electron desktop product for direct and multi-Agent conversations. It has no account system, tenant model, application server, remote conversation service, database, email delivery, scheduled jobs, or public SEO surface.
|
||||
Meldwork is a local Electron desktop product for direct and multi-Agent conversations with explicitly selected Skill, image, and knowledge-source context. It has no account system, tenant model, application server, remote conversation service, database, email delivery, scheduled jobs, or public SEO surface.
|
||||
|
||||
The supported product surface is the packaged Electron application. The frontend is a renderer bundle; without the local preload bridge it shows a desktop-required state and cannot operate the workspace.
|
||||
|
||||
@@ -10,12 +10,14 @@ The supported product surface is the packaged Electron application. The frontend
|
||||
|
||||
| Component | Responsibility | Primary evidence |
|
||||
| --- | --- | --- |
|
||||
| Vue renderer | Agent-first multi-session UI, direct-session rename/delete, per-Agent and per-round run status, background completion markers, first-run carousel, conversation/Skill/image composer UI, bounded attachment-preview cache, dismissible warnings, collapsed execution details, theme/i18n, user confirmation and input collection | `frontend/src/App.vue`, `frontend/src/composables/useAttachmentPreviews.js`, `frontend/src/desktop.js` |
|
||||
| Electron preload | Exposes narrow workspace, installer/Skill, attachment, and Provider methods through `window.roundrelayDesktop` only to a local `file:` document | `desktop/src/preload.cjs` |
|
||||
| Electron main | Trust boundary for IPC authorization and shutdown gating, persistence, attachment import/preview, Skill catalog access, process execution, navigation, sanitized run events, operating-system notifications, Provider storage, and installer control | `desktop/src/main.cjs` |
|
||||
| Vue renderer | Agent-first multi-session UI, direct-session rename/delete, per-Agent and per-round run status, background completion markers, first-run carousel, conversation/Skill/image/knowledge composer UI, bounded attachment-preview cache, dismissible warnings, collapsed execution details, theme/i18n, user confirmation and input collection | `frontend/src/App.vue`, `frontend/src/composables/useAttachmentPreviews.js`, `frontend/src/desktop.js`, `frontend/src/knowledgeBaseCatalog.js` |
|
||||
| Electron preload | Exposes narrow workspace, installer/Skill, attachment, Provider, and knowledge-source methods through `window.roundrelayDesktop` only to a local `file:` document | `desktop/src/preload.cjs` |
|
||||
| Electron main | Trust boundary for IPC authorization and shutdown gating, persistence, attachment import/preview, Skill and knowledge-source validation, process execution, navigation, sanitized run events, operating-system notifications, Provider storage, and installer control | `desktop/src/main.cjs` |
|
||||
| Local workspace | Persists Meldwork conversations, safe message metadata, one main-only native session reference per conversation and Agent, legacy topic-reference migration, Agent-specific transcript deltas, Agent preferences/runtime evidence, and transient active/terminal run state | `desktop/src/local-workspace.cjs` |
|
||||
| Attachment store | Imports validated local images into private app-owned storage, verifies metadata/checksums on read, and removes unreferenced entries | `desktop/src/attachment-store.cjs`, `desktop/src/image-dimensions.cjs` |
|
||||
| Local Skill catalog | Scans bounded known roots per Agent and returns sanitized Skill coordinates without exposing paths or contents | `desktop/src/local-skill-catalog.cjs` |
|
||||
| Local knowledge-source catalog | Detects and probes code-defined Feishu, DingTalk, and Obsidian access modes, returns sanitized readiness, validates task selections, and exposes reference-only future sources | `desktop/src/local-knowledge-base.cjs` |
|
||||
| Knowledge-source store | Persists only the user-selected Obsidian Vault path; Feishu and DingTalk credentials remain owned by their local CLIs | `desktop/src/knowledge-base-store.cjs` |
|
||||
| CLI adapters | Detect and invoke supported local Agent executables with per-Agent arguments and constrained child environments | `desktop/src/cli-adapters.cjs` |
|
||||
| Agent installer | Detects Agents and runs allowlisted npm packages or official installer scripts after user confirmation | `desktop/src/agent-installer.cjs` |
|
||||
| Provider store | Validates Provider metadata and encrypts the API key with Electron `safeStorage` | `desktop/src/provider-store.cjs` |
|
||||
@@ -23,10 +25,10 @@ The supported product surface is the packaged Electron application. The frontend
|
||||
|
||||
## Trust Boundaries
|
||||
|
||||
1. The renderer is not trusted with Node.js, executable paths, native Agent session IDs or storage paths, attachment paths, Skill paths/contents, raw Provider credentials after saving, arbitrary filesystem reads, or arbitrary process execution. User-selected conversation workdirs are the only filesystem paths intentionally shown back to the renderer; pasted image bytes use one exact import payload.
|
||||
1. The renderer is not trusted with Node.js, Agent executable paths, native Agent session IDs or storage paths, attachment paths, Skill paths/contents, raw Provider credentials after saving, arbitrary filesystem reads, or arbitrary process execution. User-selected conversation workdirs and the user-selected Obsidian Vault path are intentional UI-visible paths; pasted image bytes use one exact import payload.
|
||||
2. Preload exposes only named IPC methods. Main validates that every request comes from the current main frame and exact bundled frontend file.
|
||||
3. Main owns local files, OS dialogs, attachment validation/storage, Skill discovery/revalidation, Agent discovery, child processes, installer downloads, and credential encryption.
|
||||
4. Agent CLIs are external processes. They receive a selected working directory, a constrained environment, permission flags, main-resolved image paths, and only their target-scoped Skill context after capability checks.
|
||||
3. Main owns local files, OS dialogs, attachment validation/storage, Skill and knowledge-source discovery/revalidation, Agent discovery, child processes, installer downloads, and credential encryption.
|
||||
4. Agent CLIs are external processes. They receive a selected working directory, a constrained environment, permission flags, main-resolved image paths, target-scoped Skill context, and validated read-only knowledge-source hints after capability checks.
|
||||
5. Provider and installer network destinations are external trust boundaries. Provider URLs are user supplied and validated; installer URLs/packages are code-defined allowlists.
|
||||
|
||||
## Local Data
|
||||
@@ -36,6 +38,7 @@ The supported product surface is the packaged Electron application. The frontend
|
||||
| Meldwork conversations, messages, native session-reference mappings, Agent preferences/runtime evidence | Electron user data: `roundrelay-workspace.json` | Local JSON written through main; native references are keyed by conversation and Agent, remain main-only, and snapshots remove executable paths |
|
||||
| Imported image attachments | Electron user data under `attachments/` | App-owned copy; `0700` directories, `0600` files, magic/MIME/size/dimension validation, metadata checksum, ID-only renderer access |
|
||||
| Provider metadata and encrypted key | Electron user data: `roundrelay-provider.json` | API key encrypted with `safeStorage`; file written atomically with mode `0600` |
|
||||
| Knowledge-source preference | Electron user data: `roundrelay-knowledge-base.json` | Stores the selected absolute Obsidian Vault path only; written atomically as a private file |
|
||||
| Managed OpenClaw state/config | Electron user data under `openclaw-managed/` | Per-scope directories, mode `0700`; config mode `0600`; API key passed by child environment |
|
||||
| Theme, locale, and onboarding completion | Renderer `localStorage` | Non-secret UI preferences |
|
||||
|
||||
@@ -48,6 +51,8 @@ There is no remote data store or application account namespace. Managed OpenClaw
|
||||
- Agent CLIs may call their own configured model providers.
|
||||
- Selected images and Skill-influenced prompts may be sent by an Agent CLI to its configured model provider after local validation.
|
||||
- Compatible Agents may receive the user-configured Provider URL/model/key from main.
|
||||
- Feishu and DingTalk readiness probes may invoke their configured local CLIs; a selected Agent may then use those CLI connections with read-only instructions.
|
||||
- A selected Obsidian Vault may be read by the invoked Agent under the local OS user's permissions.
|
||||
- The installer may download fixed Hermes/Kimi installer URLs or invoke npm for fixed package names.
|
||||
- Credential-free HTTPS links may be opened in the operating-system browser; remote navigation is denied inside the Electron window.
|
||||
- The renderer CSP uses `connect-src 'self'` and does not directly call model or application APIs.
|
||||
@@ -58,6 +63,8 @@ There is no remote data store or application account namespace. Managed OpenClaw
|
||||
- Conversation history is local but not application-encrypted (`desktop/src/local-workspace.cjs`).
|
||||
- Imported attachment copies are private and integrity-checked but not application-encrypted (`desktop/src/attachment-store.cjs`).
|
||||
- Local Skill files are untrusted prompt input. Main prevents renderer-supplied paths and cross-Agent selection, but a selected Skill can still influence Agent behavior (`desktop/src/local-skill-catalog.cjs`, `desktop/src/local-workspace.cjs`).
|
||||
- Knowledge-source access is currently prompt-mediated. Meldwork validates readiness and scope, but it does not yet index content, capture deterministic source snapshots, verify every citation, or enforce read-only behavior inside every upstream Agent tool.
|
||||
- Feishu and DingTalk authentication and document permissions remain owned by their local CLIs. Notion, Confluence, Google Drive, and SharePoint are reference-only planned sources and are not active Connectors.
|
||||
- Native image support is currently limited to Codex, Hermes, and OpenCode, with different per-run limits; mixed groups fail before execution when they cannot receive equal image context (`desktop/src/cli-adapters.cjs`).
|
||||
- Read-only enforcement depends partly on each upstream CLI honoring its permission flags; Meldwork adds per-CLI hardening where available (`desktop/src/cli-adapters.cjs`).
|
||||
- Provider requests and native Agent authentication are external dependencies; Meldwork cannot guarantee their availability or data handling.
|
||||
|
||||
@@ -9,6 +9,7 @@ Meldwork embeds local Agent automation and an Agent installer. There are no webh
|
||||
| Manual Agent reply | Local user sends a message and selects targets | Invokes selected Agents sequentially once | Agent process, Provider/native network use, local message/session writes |
|
||||
| Automatic discussion | Local user sends a group message in automatic mode | Runs every group Agent in complete rounds, 6 rounds by default and up to 10 or 30 minutes, and stops early on unanimous explicit consensus | Same as manual replies, repeated within the bound |
|
||||
| Agent detection/readiness | App startup or explicit refresh | Scans fixed command names and credential evidence | Local process/file reads; Claude may run `auth status --json` |
|
||||
| Knowledge-source readiness | Explicit Knowledge Base settings refresh or source validation | Probes code-defined Feishu/DingTalk CLI status and Obsidian installation/Vault access | Local process/file reads; document-list permission probes may call the configured knowledge service through its CLI |
|
||||
| Agent installation | Local user confirms installation | One installer task at a time | Network download/npm access and global CLI installation |
|
||||
| Managed OpenClaw setup | OpenClaw invocation with configured Provider | Writes isolated runtime configuration if changed | Local config directories/files; Provider call by OpenClaw |
|
||||
| Run completion notification | A manual or automatic run reaches a terminal state while the app window is unfocused | Main emits one sanitized lifecycle event and one local operating-system notification | Local notification only; no network request or conversation message |
|
||||
@@ -22,6 +23,7 @@ Meldwork embeds local Agent automation and an Agent installer. There are no webh
|
||||
- Group name/topic and selected working directory.
|
||||
- Main-resolved paths for selected root images when the target Agent's declared capability accepts the complete set. Automatic discussion keeps offering the root images to each Agent until that Agent first receives them successfully.
|
||||
- Up to four main-revalidated Skill hints scoped to the selected target Agent. Hermes also receives the validated Skill slugs through its native `--skills` arguments.
|
||||
- Up to four main-revalidated knowledge-source hints scoped to selected target Agents. Active sources are currently Feishu, DingTalk, and Obsidian; planned OAuth sources cannot be selected.
|
||||
- Only the selected Agent's native credentials and optional configured Provider values.
|
||||
|
||||
**Executable/tool surface:**
|
||||
@@ -35,6 +37,7 @@ Meldwork embeds local Agent automation and an Agent installer. There are no webh
|
||||
**Steering:**
|
||||
|
||||
- `LocalWorkspace.promptFor` identifies the Agent, repeats bounded stable user constraints, adds only the group transcript delta needed by that Agent's conversation-scoped native session, and asks it not to impersonate other Agents.
|
||||
- Selected knowledge sources add an explicit read-only instruction, source identity, and either a main-resolved local Vault location or detected CLI command name. Meldwork asks the Agent to identify sources used, but does not independently guarantee retrieval completeness or citation correctness.
|
||||
- Automatic discussion preflights root-image limits for every Agent, so each participant can receive the same root image set or the run does not start. This equal-context guarantee applies to root-image availability, not identical prompts: Agents still run sequentially, so later participants can see earlier replies, while native sessions remain conversation-and-Agent-specific and Skill hints remain Agent-specific.
|
||||
|
||||
**Output contract:**
|
||||
@@ -49,6 +52,7 @@ Meldwork embeds local Agent automation and an Agent installer. There are no webh
|
||||
## Workspace Side Effects
|
||||
|
||||
- `allowWrite` defaults to false. Adapters with enforceable permission modes receive read-only/plan arguments until the user explicitly opts into writes.
|
||||
- Knowledge-source selections are task-scoped hints and do not change `allowWrite`. The Agent may read the selected source under local OS and upstream CLI permissions; Meldwork instructs it not to modify source content.
|
||||
- Hermes and OpenClaw do not expose an equivalent Meldwork-enforced read-only switch, so their capability label remains Agent-managed permissions regardless of `allowWrite`.
|
||||
- Main passes write permission per invocation; it does not grant a renderer filesystem API.
|
||||
- Agents run with the local OS user's process identity. Meldwork is not an OS-level sandbox.
|
||||
|
||||
+13
-6
@@ -12,7 +12,7 @@ Meldwork 不是制造 Agent 的公司,也不是把十个 Agent 头像放进一
|
||||
|
||||
它的角色是:
|
||||
|
||||
> **让不同 Agent 接续同一份真实工作,并让用户始终看得见任务、边界、证据和结果。**
|
||||
> **让不同 Agent 基于用户明确授权的知识上下文接续同一份真实工作,并让用户始终看得见任务、边界、证据和结果。**
|
||||
|
||||
### 品牌关键词
|
||||
|
||||
@@ -20,6 +20,7 @@ Meldwork 不是制造 Agent 的公司,也不是把十个 Agent 头像放进一
|
||||
- Local-first:控制面和工作记录默认在本机。
|
||||
- Accountable:工作可追溯、可比较、可验收。
|
||||
- Cross-vendor:全球与中国 Agent 平等接入。
|
||||
- Context-aware:连接用户已有知识来源,但不取代其内容平台。
|
||||
- Quiet confidence:专业、克制、不用“AI 魔法”语言。
|
||||
|
||||
### 品牌应避免
|
||||
@@ -107,21 +108,27 @@ Meldwork 不是制造 Agent 的公司,也不是把十个 Agent 头像放进一
|
||||
>
|
||||
> **面向跨厂商 Agent 的开放、本地优先工作系统。**
|
||||
|
||||
作用:第一次看见产品的人能够立即理解是什么。
|
||||
对需要解释知识来源的页面,可使用扩展品类描述:
|
||||
|
||||
> **An open, local-first work system for agents and knowledge across vendors.**
|
||||
>
|
||||
> **面向跨厂商 Agent 与知识来源的开放、本地优先工作系统。**
|
||||
|
||||
作用:第一次看见产品的人能够立即理解是什么。短版用于 Logo 邻近位置,扩展版用于 README、BP 和产品介绍。
|
||||
|
||||
### 第三层:价值主张
|
||||
|
||||
> **Bring local and cloud agents into one accountable workspace.**
|
||||
> **Bring agents and trusted knowledge into one accountable workspace.**
|
||||
>
|
||||
> **让本地与云端 Agent 在一个可追溯、可验收的工作空间内协作。**
|
||||
> **让 Agent 与可信知识上下文在一个可追溯、可验收的工作空间内协作。**
|
||||
|
||||
作用:解释为什么值得使用。
|
||||
|
||||
### MVP 阶段的事实版文案
|
||||
|
||||
当前还没有 Cloud Agent、Task、Artifact、Evidence 和团队治理,因此 README 应使用:
|
||||
当前还没有 Cloud Agent、Task、Artifact、Evidence 和团队治理;知识来源也只是显式访问提示,不是统一检索引擎。因此 README 应使用:
|
||||
|
||||
> Bring the local Agent CLIs already on your machine into one persistent workspace.
|
||||
> Bring the local Agent CLIs and explicitly selected knowledge sources already available on your machine into one persistent workspace.
|
||||
|
||||
愿景文案与当前能力文案必须分开。
|
||||
|
||||
|
||||
+21
-6
@@ -6,7 +6,7 @@ Meldwork has one human actor: the local desktop user. There are no accounts, rol
|
||||
|
||||
**Precondition:** The local user launches Meldwork.
|
||||
|
||||
1. Electron main creates `ProviderStore`, `AttachmentStore`, and `LocalWorkspace` under `app.getPath('userData')`, plus a `LocalSkillCatalog` rooted at `app.getPath('home')`.
|
||||
1. Electron main creates `ProviderStore`, `KnowledgeBaseStore`, `AttachmentStore`, and `LocalWorkspace` under `app.getPath('userData')`, plus a `LocalSkillCatalog` rooted at `app.getPath('home')`.
|
||||
2. Main registers IPC handlers, creates a sandboxed `BrowserWindow`, and loads the bundled frontend with `loadFile`.
|
||||
3. Before accepting attachment work, main reconciles the private attachment directory against persisted message references. Malformed workspace state disables destructive cleanup.
|
||||
4. Preload exposes workspace, installer, Skill, attachment, and Provider methods only when `location.protocol === 'file:'`.
|
||||
@@ -79,12 +79,27 @@ Meldwork has one human actor: the local desktop user. There are no accounts, rol
|
||||
|
||||
**State/side effects:** Imports private local image copies and reads local Skill manifests. No Skill path, attachment path, preview payload, or raw bytes are persisted in the workspace snapshot.
|
||||
|
||||
## 6. Send A Message To Agents
|
||||
## 6. Connect And Select Knowledge Sources
|
||||
|
||||
**Precondition:** The user opens Knowledge Base settings or opens the composer mention menu.
|
||||
|
||||
1. Main resolves a code-defined source catalog. Feishu and DingTalk are probed through allowlisted local CLI commands; Obsidian is detected as an app or CLI and uses a user-selected Vault directory.
|
||||
2. Main returns sanitized readiness, login, permission, read/write, command-name, and selected-Vault status. Notion, Confluence, Google Drive, and SharePoint remain planned reference entries rather than active Connectors.
|
||||
3. Selecting an Obsidian Vault uses a main-owned directory dialog and persists only the normalized absolute path in `roundrelay-knowledge-base.json`.
|
||||
4. The composer may select up to four ready knowledge sources and scopes each selection to explicit target Agents.
|
||||
5. Before accepting the message, main re-probes missing cache entries and validates that the source is currently readable, its access mode is supported, and every target belongs to the current run.
|
||||
6. `LocalWorkspace` stores sanitized source hints with the user message. At invocation, only the selected Agent receives its validated hints: an allowlisted CLI command name or the selected local Vault location plus a read-only instruction.
|
||||
|
||||
**Deny cases:** Unknown or planned source, missing login, missing permission, unreadable or invalid Vault, unsupported access mode, empty target set, target outside the run, or stale source state.
|
||||
|
||||
**State/side effects:** Probes may invoke local Feishu/DingTalk commands and read local installation state. A later Agent run may read from the selected source and may send derived content to its configured Provider. Meldwork does not currently index, cache, snapshot, or independently verify the source content.
|
||||
|
||||
## 7. Send A Message To Agents
|
||||
|
||||
**Precondition:** The conversation is not already running and at least one selected target belongs to the group.
|
||||
|
||||
1. `LocalWorkspace` persists the user message and creates a cancellable run.
|
||||
2. It builds a bounded prompt from stable group-level user constraints and the recent group transcript. When the same native session is resumed, only messages after that Agent's previous final reply are added, together with Skill hints assigned to that Agent.
|
||||
2. It builds a bounded prompt from stable group-level user constraints and the recent group transcript. When the same native session is resumed, only messages after that Agent's previous final reply are added, together with Skill and knowledge-source hints assigned to that Agent.
|
||||
3. Main resolves the Agent executable and attachment paths internally, selects Provider/native credential environment, and invokes the CLI in the group working directory. Codex, Hermes, and OpenCode receive images through their validated native arguments; Hermes also receives selected Skill slugs through `--skills`.
|
||||
4. CLI adapters apply per-Agent read-only or write-enabled arguments. Child processes receive an allowlisted system environment plus only current-Agent credentials.
|
||||
5. Main emits sanitized active progress. Hermes process details are bounded and kept separate from the final answer; a pre-run message-ID watermark prevents an earlier turn from being selected as the current result.
|
||||
@@ -96,13 +111,13 @@ Meldwork has one human actor: the local desktop user. There are no accounts, rol
|
||||
|
||||
**External side effects:** Agent/provider network calls and possible workspace reads. Workspace writes are intended only when `allowWrite` is true, subject to upstream CLI enforcement.
|
||||
|
||||
## 7. Equal-Context Automatic Discussion And Stop
|
||||
## 8. Equal-Context Automatic Discussion And Stop
|
||||
|
||||
**Precondition:** A group has at least two Agents and a persisted user topic root.
|
||||
|
||||
1. Before creating a run, `LocalWorkspace` checks the root message's entire image set against every group Agent. If any Agent cannot receive the same set, the discussion is rejected before any process starts.
|
||||
2. The user chooses a bounded round count; the default is six and the hard cap is ten.
|
||||
3. `LocalWorkspace` invokes every group Agent once per complete round, preserving one main-only native session reference for each conversation and Agent. The topic root remains a visual and run-lifecycle boundary, not a native-session boundary. Root images are delivered once to each Agent; a failed delivery is retried on that Agent's next attempt instead of silently dropping context. Root Skill selections are revalidated and remain scoped to their target Agent on every attempt.
|
||||
3. `LocalWorkspace` invokes every group Agent once per complete round, preserving one main-only native session reference for each conversation and Agent. The topic root remains a visual and run-lifecycle boundary, not a native-session boundary. Root images are delivered once to each Agent; a failed delivery is retried on that Agent's next attempt instead of silently dropping context. Root Skill and knowledge-source selections are revalidated and remain scoped to their target Agent on every attempt.
|
||||
4. Each Agent must end with one internal consensus marker. The marker is removed before persistence, and the run stops early only when every Agent completes and agrees in the same round.
|
||||
5. A failed Agent is recorded once per stable failure, while later Agents and later bounded rounds continue. Active progress and terminal state are emitted separately from message history.
|
||||
6. The user can stop the group, and a 30-minute total runtime limit also aborts the active process tree.
|
||||
@@ -113,7 +128,7 @@ Meldwork has one human actor: the local desktop user. There are no accounts, rol
|
||||
|
||||
“Equal context” here means every Agent can receive the same root image set before the run is allowed. Discussion remains sequential, so later Agents in a round can see earlier replies; native sessions remain conversation-and-Agent-specific, while selected Skills remain Agent-specific.
|
||||
|
||||
## 8. Shutdown IPC Gate
|
||||
## 9. Shutdown IPC Gate
|
||||
|
||||
**Precondition:** Electron receives `before-quit`.
|
||||
|
||||
|
||||
+12
-12
@@ -10,13 +10,13 @@ This document contains draft public-relations and repository-launch copy for the
|
||||
|
||||
**Chinese:** Agent 可切换,工作不断线。
|
||||
|
||||
**Current one sentence:** Meldwork brings supported local Agent CLIs into one persistent workspace, so conversations, compatible native sessions, and collaboration state can continue when work moves between Agents.
|
||||
**Current one sentence:** Meldwork brings supported local Agent CLIs and explicitly selected knowledge sources into one persistent workspace, so conversations, compatible native sessions, and task context can continue when work moves between Agents.
|
||||
|
||||
**Chinese:** Meldwork 把已支持的本地 Agent CLI 带进一个持续工作空间,让工作在不同 Agent 之间流转时,对话、兼容条件下的原生 Session 和协作状态仍然保留。
|
||||
**Chinese:** Meldwork 把已支持的本地 Agent CLI 和用户明确选择的知识来源带进一个持续工作空间,让工作在不同 Agent 之间流转时,对话、兼容条件下的原生 Session 和任务上下文仍然保留。
|
||||
|
||||
**Target product category:** An open, local-first workspace that any local, cloud, custom, or channel-native Agent can join.
|
||||
**Target product category:** An open, local-first work system for compatible Agents and knowledge sources across vendors.
|
||||
|
||||
**Target architecture line:** If it can act as an Agent, it should be able to join Meldwork.
|
||||
**Target architecture line:** Agents and knowledge sources should join through explicit capabilities, permissions, events, and egress declarations.
|
||||
|
||||
The target category and architecture line describe product direction. The current MVP still uses a fixed set of local CLI adapters.
|
||||
|
||||
@@ -26,23 +26,23 @@ Introducing Meldwork: a persistent workspace for the Agents you already use
|
||||
|
||||
After a license and public connector contract are added, use:
|
||||
|
||||
Introducing Meldwork: an open, local-first workspace for any Agent
|
||||
Introducing Meldwork: an open, local-first workspace for Agents and knowledge
|
||||
|
||||
## Short announcement
|
||||
|
||||
Meldwork is a local-first desktop workspace for general-purpose AI agents. The current MVP discovers supported local Agent CLIs, keeps direct and group conversations persistent, resumes compatible native sessions, and runs bounded discussions without requiring a hosted Meldwork orchestration service. It is not a coding-only Agent aggregator: coding, research, planning, creation, operations, and review are use cases on the same cross-Agent workspace. Provider traffic still follows each selected Agent's configuration.
|
||||
Meldwork is a local-first desktop workspace for general-purpose AI agents. The current MVP discovers supported local Agent CLIs, keeps direct and group conversations persistent, resumes compatible native sessions, runs bounded discussions, and lets users explicitly select ready Feishu, DingTalk, or Obsidian knowledge sources. It is not a coding-only Agent aggregator or a knowledge-base engine: coding, research, planning, creation, operations, and review share one cross-Agent workspace, while source access and Provider traffic still follow the selected local tools and Agent configuration.
|
||||
|
||||
## Chinese announcement
|
||||
|
||||
Meldwork 是面向通用 AI Agent 的本地优先桌面工作空间。当前 MVP 可以发现已支持的本地 Agent CLI、持久保存直接与群组会话、在兼容条件下恢复原生 Session,并在不依赖 Meldwork 托管编排服务的情况下运行有界讨论。它不是 Coding Agent 聚合器:开发、研究、规划、创作、运营和审查,都是同一个跨 Agent 工作空间中的使用场景。所选 Agent 的 Provider 流量仍遵循各自配置。
|
||||
Meldwork 是面向通用 AI Agent 的本地优先桌面工作空间。当前 MVP 可以发现已支持的本地 Agent CLI、持久保存直接与群组会话、在兼容条件下恢复原生 Session、运行有界讨论,并让用户显式选择已就绪的飞书、钉钉或 Obsidian 知识来源。它既不是 Coding Agent 聚合器,也不是知识库引擎:开发、研究、规划、创作、运营和审查共享同一个跨 Agent 工作空间,知识访问和 Provider 流量仍遵循所选本地工具与 Agent 配置。
|
||||
|
||||
## Story structure
|
||||
|
||||
1. People and teams increasingly use several capable Agents for different kinds of work, but their context, sessions, permissions, and outputs remain fragmented.
|
||||
2. Meldwork gives supported local Agents one persistent workspace without asking users to replace their Agent or Provider relationships.
|
||||
1. People and teams increasingly use several capable Agents and many knowledge sources, but their context, sessions, permissions, and outputs remain fragmented.
|
||||
2. Meldwork gives supported local Agents and explicitly selected knowledge sources one persistent workspace without asking users to replace their Agent, Provider, or content platform relationships.
|
||||
3. The current MVP demo should show discovery, persistent conversations, compatible session continuity, Agent-specific capabilities, and bounded collaboration only where verified.
|
||||
4. The next architecture milestone is a public Connector contract and capability manifest so new local, cloud, custom, and channel-native Agents can join without hardcoding.
|
||||
5. The next product milestone is an explicit Task -> Run -> Artifact -> Evidence -> Human acceptance loop.
|
||||
4. The next architecture milestone is a public Agent and Knowledge Connector contract with capability, permission, event, and egress manifests.
|
||||
5. The next product milestone is an explicit Context Pack -> Task -> Run -> Artifact -> Evidence -> Human decision loop.
|
||||
6. The product difference must come from continuity, open connection, evidence, acceptance, and explicit permission boundaries, not from displaying more Agent avatars.
|
||||
7. Local-first does not mean every model is offline; selected Providers may still use the network.
|
||||
|
||||
@@ -51,7 +51,7 @@ Meldwork 是面向通用 AI Agent 的本地优先桌面工作空间。当前 MVP
|
||||
### What changed
|
||||
|
||||
- Repositioned Meldwork from a coding-Agent CLI aggregator to a persistent workspace for general-purpose Agents.
|
||||
- Rewrote the English and Chinese READMEs around user work fragmentation, current MVP facts, and the any-Agent connector direction.
|
||||
- Rewrote the English and Chinese READMEs around user work fragmentation, current MVP facts, and the open Agent/knowledge Connector direction.
|
||||
- Adopted the asymmetric Trace V3 identity across the client, Electron icon, favicon, brand board, and README campaign assets.
|
||||
- Added separate English and Chinese 1600 x 640 README banners using a generated text-free visual plate with exact local logos and typography.
|
||||
- Removed the superseded V2 and coding-specific README banner assets.
|
||||
|
||||
+222
-207
@@ -1,309 +1,325 @@
|
||||
# Meldwork 市场与用户调研说明书
|
||||
|
||||
> 版本:OPC 开源优先版
|
||||
> 版本:General Agent + Knowledge 战略版
|
||||
>
|
||||
> 日期:2026-07-31
|
||||
> 日期:2026-08-02
|
||||
>
|
||||
> 状态:战略工作稿;外部价格、竞品能力和法律结论在公开发布前需要刷新
|
||||
|
||||
## 0. 结论先行
|
||||
|
||||
### 0.1 值不值得做
|
||||
### 0.1 值不值得继续做
|
||||
|
||||
**值得继续做,但当前最合理的目标不是立即做成一个 SaaS,而是做成一个有真实用户价值的开源 Agent Harness 项目。**
|
||||
**值得继续做,但不能继续把 Meldwork 定义为本地 Agent 聚合聊天器,也不应把产品重新锁死在 Coding Agent。**
|
||||
|
||||
Meldwork 已经完成了有价值的 0-1 基础:本地 Electron 工作空间、已支持 Agent CLI 的发现与调用、直接和群组会话、兼容条件下的原生 Session 延续、有限轮次的自动讨论、Skill 与图片上下文、Provider 配置、安全存储和较窄的 Renderer/Main 边界。这些能力足够支持公开 MVP 和真实用户验证,但还不足以证明它是一个独立商业品类。
|
||||
更合理的产品方向是:
|
||||
|
||||
真正值得继续投入的命题不是“把更多 Agent 放在一个窗口”,而是:
|
||||
> **面向 General Agent 与用户已有知识来源的开放、本地优先工作系统。**
|
||||
|
||||
> **当一项工作需要多个 Agent 或需要一个可控的 Agent 执行环境时,Meldwork 能否让任务更容易交接、更容易复核、更容易复用,并且不迫使用户迁移已有 Agent 账户和工作方式?**
|
||||
用户真正需要的不是更多聊天入口,而是让一项工作在不同 Agent、知识来源和人之间接续时,仍然保留:
|
||||
|
||||
这个命题与用户目前的 OPC 资源更匹配:先用开源和内容建立分发,再用真实使用数据决定是否做 Harness 产品、团队治理或商业支持。
|
||||
- 被批准使用的上下文。
|
||||
- 原生 Session 和 Agent 能力。
|
||||
- 清晰的权限与数据出站边界。
|
||||
- 可继续使用的 Artifact。
|
||||
- 支持或反驳结果的 Evidence。
|
||||
- 人类最终采用、拒绝或修改的 Decision。
|
||||
|
||||
### 0.2 为什么不是“多智能体聊天器”
|
||||
因此,Meldwork 的核心闭环应从:
|
||||
|
||||
单纯聚合本地 CLI 的功能很容易被上游 Agent、IDE、终端和云端控制面吸收。多 Agent 的数量、头像、群聊和自动轮次都不是长期壁垒;用户愿意留下来的理由必须是:
|
||||
```text
|
||||
Conversation -> More Agents -> More Messages
|
||||
```
|
||||
|
||||
1. **连接保真**:保留各 Agent 的原生会话、权限和 Provider 关系。
|
||||
2. **工作保真**:任务、运行、交付物和复核记录不会被聊天消息淹没。
|
||||
3. **控制保真**:用户知道哪些数据出站、哪个 Agent 可以写入、什么时候必须人工确认。
|
||||
4. **结果可比**:可以比较独立尝试、审查意见、测试结果和成本,而不是只看谁的文案更流畅。
|
||||
5. **开放扩展**:本地、云端、自定义和渠道型 Agent 都通过统一 Connector 加入,避免被单一厂商锁定。
|
||||
升级为:
|
||||
|
||||
### 0.3 OPC 的决策
|
||||
```text
|
||||
Agent + Knowledge Source
|
||||
-> Context Pack
|
||||
-> Task / Run
|
||||
-> Artifact / Evidence
|
||||
-> Decision / Adoption
|
||||
```
|
||||
|
||||
在一个人、且有日常工作的前提下,项目不能同时追求以下全部目标:广泛适配、企业销售、云端基础设施、完整团队协作、持续内容运营和高频版本迭代。
|
||||
### 0.2 这不是“什么 Agent 都能接”的宽泛平台
|
||||
|
||||
因此采用三层目标:
|
||||
General Agent 表示产品不按 Coding、Research、PM 或 Operations 把 Agent 人为分割成不同品类;它不表示所有 Agent 拥有相同能力,也不表示 Meldwork 可以无条件接入任何 Agent。
|
||||
|
||||
| 层次 | 目标 | 现在是否投入 |
|
||||
每个 Agent 和 Knowledge Connector 都必须声明:
|
||||
|
||||
- 能做什么和不能做什么。
|
||||
- 支持哪些输入、Session 和工具。
|
||||
- 是否可读、可写、可联网和可取消。
|
||||
- 哪些运行事件、Artifact、Evidence 和费用可以观测。
|
||||
- 数据会流向哪里。
|
||||
|
||||
产品卖点应是“开放且可验证的连接”,不是“无限兼容”。
|
||||
|
||||
### 0.3 当前最有价值的新机会
|
||||
|
||||
当前仓库已经开始支持飞书、钉钉和 Obsidian 等知识来源。虽然现阶段只是经过验证的只读访问提示,而不是完整 RAG 或索引引擎,但它使 Meldwork 有机会形成比“多 Agent 控制面”更清晰的差异:
|
||||
|
||||
> **把用户已经拥有的 Agent 和知识上下文带进同一个可追溯工作空间。**
|
||||
|
||||
这条方向覆盖代码、研究、产品、咨询、规划、安全和运营等工作,不依赖某个 Agent 厂商,也不要求 Meldwork 自建模型。
|
||||
|
||||
### 0.4 投入判断
|
||||
|
||||
建议采用双层策略:
|
||||
|
||||
| 层次 | 当前目标 | 决策 |
|
||||
| --- | --- | --- |
|
||||
| 项目目标 | GitHub 上可安装、可理解、可演示的开源 MVP | 立即投入 |
|
||||
| 产品目标 | 验证“跨 Agent 工作连续性 + Harness 控制层”是否产生重复价值 | 立即投入,但只做一个主场景 |
|
||||
| 商业目标 | 为 Connector 兼容、治理、支持和私有部署保留收入选项 | 有付费信号后再投入 |
|
||||
| 开源项目 | 可安装、可理解、可完成真实任务、可贡献 | 立即投入 |
|
||||
| 产品验证 | 证明 Context-grounded Outcome 是否产生重复价值 | 立即投入,但只做一个主协议 |
|
||||
| 平台扩张 | Cloud、Channel、Workflow、Team | 由重复使用和回款触发 |
|
||||
|
||||
### 0.4 直接判断
|
||||
不建议现在同时建设企业平台、云执行、多个 IM Channel、完整知识中台和大量 Connector。
|
||||
|
||||
- **做成高质量开源项目:值得。** 它能带来用户、贡献者、行业声誉和职业资产,即使后续没有商业化也成立。
|
||||
- **直接做通用企业平台:不值得。** OPC 无法承受长期兼容、销售、支持、安全与合规的固定成本。
|
||||
- **探索 Harness 商业化:值得保留。** 但必须先由开源项目验证一个重复、昂贵、可标准化的问题。
|
||||
- **继续堆 Agent 适配器:不值得作为主线。** 适配器数量只有在兼容性、任务结果和社区贡献形成闭环时才有价值。
|
||||
|
||||
## 1. 研究边界与证据口径
|
||||
## 1. 研究边界
|
||||
|
||||
### 1.1 已有证据
|
||||
|
||||
- 当前仓库代码、测试和架构文档对 MVP 能力的审计。
|
||||
- 既有市场研究中的公开调查、竞品官方文档与价格快照。
|
||||
- 对本地 Agent、Cloud Agent、控制面和工作渠道的产品趋势判断。
|
||||
- `/Users/rydersun/Desktop/Meldwork Strategy` 中的市场、路线图和 BP 材料。
|
||||
- 当前仓库对本地 Agent、Session、Provider、Skill、图片和知识来源的实现。
|
||||
- 既有市场研究中关于 Agent 使用、AI 信任、控制面竞争和开源生态的公开资料。
|
||||
|
||||
### 1.2 尚未有的证据
|
||||
### 1.2 尚未成立的事实
|
||||
|
||||
当前没有足够的外部证据证明:用户会为跨厂商中立工作层单独付费;多 Agent 的质量提升能稳定覆盖额外时间和 Token 成本;团队需要一个新的控制面;或者开放 Connector 会自动形成网络效应。
|
||||
当前没有足够证据证明:
|
||||
|
||||
因此本文将结论分为:
|
||||
- 用户会为跨厂商 Agent 工作层单独付费。
|
||||
- 多 Agent 在多数任务上稳定优于一个强 Agent。
|
||||
- 用户需要 Meldwork 自建知识索引,而不是让 Agent 读取已有来源。
|
||||
- 团队愿意把工作状态交给一个新的控制面。
|
||||
- 开放 Connector 会自动形成网络效应。
|
||||
|
||||
- **事实**:仓库或公开来源可以直接支持。
|
||||
- **推断**:由事实推导出的战略判断。
|
||||
- **假设**:需要访谈、真实任务、留存或回款验证。
|
||||
- **决策**:在 OPC 约束下采取的取舍。
|
||||
|
||||
### 1.3 对外使用规则
|
||||
|
||||
外部材料不得把“将来可连接任意 Agent”“Cloud Agent”“审计治理”“企业级安全”写成当前已交付能力。当前 MVP 仍是固定适配的本地 Agent 工作空间;“Harness 基座”是产品方向和设计目标。
|
||||
这些均应作为需要真实任务、留存和回款验证的假设。
|
||||
|
||||
## 2. 市场正在发生什么
|
||||
|
||||
### 2.1 Agent 已从聊天入口变成执行入口
|
||||
### 2.1 Agent 正从工具变成可替换执行单元
|
||||
|
||||
Coding Agent、研究 Agent、终端 Agent 和企业自动化 Agent 都在向文件访问、工具调用、长任务、后台运行和多渠道交接发展。用户不再只面对一个问答框,而是面对多个可执行系统。
|
||||
Codex、Claude Code、Hermes、OpenClaw、Kimi、MiMo、Qwen 等产品正在同时扩展研究、文件、工具、浏览器、代码、自动化和渠道能力。Coding Agent 与 General Agent 的边界正在变模糊。
|
||||
|
||||
这带来两个变化:
|
||||
这意味着:
|
||||
|
||||
1. Agent 本身越来越像基础设施,单个 Agent 的差异会被模型、工具和生态持续重写。
|
||||
2. 用户真正缺少的是工作状态、权限、运行结果、证据和验收的统一管理。
|
||||
1. 用户会长期同时使用多个能力不同的 Agent。
|
||||
2. 单个 Agent 的品牌和能力会频繁变化。
|
||||
3. 独立产品不能把 Agent 数量或聊天 UI 当作壁垒。
|
||||
4. 更稳定的价值位于上下文、工作状态、权限、Evidence 和 Adoption。
|
||||
|
||||
### 2.2 多 Agent 是机会也是陷阱
|
||||
### 2.2 知识上下文仍然碎片化
|
||||
|
||||
多 Agent 只有在以下条件至少满足一个时才有价值:
|
||||
用户的真实上下文散落在本地文件、Obsidian、飞书、钉钉、Notion、Confluence、Google Drive、SharePoint、GitHub 和各种聊天记录中。
|
||||
|
||||
- 任务风险高,第二个独立视角能降低漏检概率。
|
||||
- 任务复杂,单个 Agent 的上下文或工具覆盖不足。
|
||||
- 工作需要不同专业角色,且交付格式可以比较。
|
||||
- 用户本来就拥有多个 Agent,手工切换成本稳定存在。
|
||||
现有 Agent 往往通过各自插件、MCP、CLI、粘贴或索引方案读取这些内容,导致:
|
||||
|
||||
否则,多 Agent 只会增加 Token、等待时间、输出合并和责任归属问题。
|
||||
- 用户反复解释哪些来源可以用。
|
||||
- 不同 Agent 获得的上下文范围不一致。
|
||||
- 输出很难说明依据了哪些内容。
|
||||
- 权限和数据出站由多个工具分别管理。
|
||||
- 换 Agent 后,任务状态和决策链再次丢失。
|
||||
|
||||
### 2.3 用户信任比 Agent 数量更稀缺
|
||||
Meldwork 不需要立即复制所有知识平台,而应先成为“本次任务允许使用哪些上下文”的本地控制层。
|
||||
|
||||
公开调查和行业研究反复显示,开发者采用 AI 的速度很快,但对准确性、隐私和结果可控性的信任并没有同步增加。历史研究还提醒我们:主观“更快”不等于真实交付更快。
|
||||
### 2.3 多 Agent 是按风险升级的能力
|
||||
|
||||
对 Meldwork 的含义是:产品指标不能只统计运行次数、消息数或 Agent 数量;必须记录任务是否完成、结果是否被采用、发现是否被修复、成本是否合理,以及用户是否再次使用。
|
||||
多数普通任务一个 Agent 足够。第二个 Agent 只有在以下情况下更可能产生净价值:
|
||||
|
||||
## 3. 市场分层与竞争格局
|
||||
- 错误成本高,需要独立 Reviewer。
|
||||
- 任务不确定,需要相互独立的方案。
|
||||
- 不同 Agent 具备明显互补的工具或知识访问能力。
|
||||
- 产物需要事实、约束或合规复核。
|
||||
|
||||
### 3.1 价值链
|
||||
因此,产品默认行为应是一个 Agent 完成任务,并在风险、证据不足或用户主动选择时增加第二个 Agent。
|
||||
|
||||
| 层级 | 用户购买的结果 | 代表性方向 | Meldwork 的位置 |
|
||||
| --- | --- | --- | --- |
|
||||
| Agent / 模型 | 生成、推理、执行能力 | Codex、Claude Code、Kimi、Qwen 等 | 连接供给,不与之竞争 |
|
||||
| IDE / Terminal | 在当前开发环境里完成任务 | Cursor、Cline、Warp 等 | 不复制完整 IDE |
|
||||
| Cloud Agent | 离线运行、后台执行、PR 交付 | GitHub、Cursor、Devin、Factory 等 | 未来 Connector |
|
||||
| Agent Control Plane | 并行调度、策略、审计、状态 | Agent HQ、Warp Oz、OpenHands 等 | 未来竞争与合作层 |
|
||||
| Work Channel | 在 GitHub、Slack、Linear、飞书等地派发工作 | Issue、PR、消息渠道 | 未来 Channel |
|
||||
### 2.4 控制面能力会商品化
|
||||
|
||||
### 3.2 直接与相邻竞品
|
||||
GitHub Agent HQ、Cursor、Warp、OpenHands、Cline 和各家原生 Agent 都在增加并行运行、任务列表、团队协作和渠道入口。
|
||||
|
||||
| 竞品/方向 | 强项 | 对 Meldwork 的威胁 | 不应正面复制的部分 |
|
||||
| --- | --- | --- | --- |
|
||||
| GitHub Agent HQ / Copilot | 代码托管、PR、组织治理、渠道分发 | 能把多 Agent 变成平台标配 | GitHub 全栈控制面 |
|
||||
| Cursor / Cline / Warp | 强入口、IDE/终端体验、并行任务 | 用户不需要额外工作台 | 完整 IDE 或终端替代 |
|
||||
| OpenHands | 开放、自托管、Runtime 和第三方 Agent | 与中立 Harness 叙事接近 | 大规模 Runtime 与云基础设施 |
|
||||
| Devin / Factory | 以交付结果、企业合同和云执行为中心 | 在高预算企业中直接卖结果 | 企业销售和云执行舰队 |
|
||||
| 各家 Agent 原生 Teams | 对自家模型、工具和账号优化 | 用户可留在单一生态 | 单厂商闭环 |
|
||||
Meldwork 不能只争夺“控制多个 Agent”这个功能,而应占据更具体的位置:
|
||||
|
||||
### 3.3 竞争空位是假设,不是事实
|
||||
- 跨厂商而非单厂商。
|
||||
- 本地控制而非强制云账户。
|
||||
- 连接用户已有 Agent 与知识来源。
|
||||
- 以 Artifact、Evidence 和 Decision 记录真实工作结果。
|
||||
|
||||
Meldwork 的切入假设是:有一批用户已经同时使用多个 Agent,愿意保留本地控制,却缺少一个跨厂商的工作和证据层。这个假设只有在以下三项同时成立时才有意义:
|
||||
## 3. 市场位置
|
||||
|
||||
1. 手工协调每周重复发生,且耗时足以让用户抱怨。
|
||||
2. 跨 Agent 的独立尝试或审查能改善结果,而不只是增加成本。
|
||||
3. 用户愿意把这层工作状态交给一个开放项目,或愿意为兼容与治理服务付费。
|
||||
| 市场层 | 用户购买的结果 | Meldwork 的关系 |
|
||||
| --- | --- | --- |
|
||||
| Agent / 模型 | 推理、工具调用和执行能力 | 连接供给,不与其竞争 |
|
||||
| IDE / Terminal | 在开发环境完成工作 | 不复制完整 IDE 或终端 |
|
||||
| Knowledge Platform | 存储、搜索和协作文档 | 连接来源,不替代其内容系统 |
|
||||
| Cloud Agent | 后台运行和远程交付 | 条件阶段 Connector |
|
||||
| Agent Control Plane | 并行、状态、策略和审计 | 主要竞争层 |
|
||||
| Work Channel | 在 GitHub、钉钉、飞书、Slack 等地派发工作 | 条件阶段入口 |
|
||||
|
||||
## 4. 目标用户与真实 Jobs to Be Done
|
||||
建议品类:
|
||||
|
||||
### 4.1 第一用户群:多 Agent 重度个人用户
|
||||
> **Open, local-first work system for agents and knowledge across vendors.**
|
||||
|
||||
**特征假设**:已使用两个或以上 Agent;能理解 CLI、工作目录和权限;在复杂编码、研究、规划或审查任务中主动切换工具。
|
||||
不建议定位为:AI IDE、通用聊天应用、知识库 SaaS、模型聚合器、无限自治集群或企业 IM。
|
||||
|
||||
**核心 Job**:
|
||||
## 4. 目标用户与 Jobs to Be Done
|
||||
|
||||
> 当一项工作重要到不能只相信一个 Agent 时,我希望让不同 Agent 在不丢失原生会话和上下文的情况下参与同一个任务,并快速判断哪些结果值得采用。
|
||||
### 4.1 首要用户:高频使用 Agent 的专业知识工作者
|
||||
|
||||
**为什么先服务他们**:访谈成本低、安装决策短、开源传播意愿高、可以直接提供真实任务;他们不需要先购买组织级治理。
|
||||
这类用户可能是产品经理、研究人员、顾问、开发者、安全人员、分析师或创业者。共同特征不是职业名称,而是:
|
||||
|
||||
### 4.2 第二用户群:小型 AI-native 团队
|
||||
- 已使用两个或以上 Agent,或频繁在 Agent 与知识来源之间切换。
|
||||
- 处理有明确产物、来源和判断责任的工作。
|
||||
- 愿意理解工作目录、知识授权和 Provider 边界。
|
||||
- 不希望把全部工作状态迁移到单一厂商平台。
|
||||
|
||||
**核心 Job**:
|
||||
核心 Job:
|
||||
|
||||
> 当团队成员使用不同 Agent 时,我希望有一套共享的任务、权限、验证和交付规则,而不是依赖每个人手工维护 CLI 习惯。
|
||||
> 当一项工作重要到不能只依赖一个 Agent 或一段记忆时,我希望把被批准的知识上下文交给合适的 Agent,让另一个 Agent 独立复核,并保留可以追溯和继续使用的结果。
|
||||
|
||||
**进入条件**:必须先证明个人用户重复使用,再验证团队是否真的需要共享策略、审计和预算;不能因为“企业愿意听演示”就提前做团队平台。
|
||||
### 4.2 第二用户:5-50 人 AI-native 团队
|
||||
|
||||
### 4.3 未来高价值用户:高责任工作团队
|
||||
核心 Job:
|
||||
|
||||
研究、咨询、安全、架构评审和重大迁移等场景对 Evidence 和 Acceptance 的需求更强,但错误成本、合规和支持成本也更高。它们只能作为设计伙伴与未来商业化方向,当前不得宣传为生产级能力。
|
||||
> 当团队成员使用不同 Agent 和知识来源时,我希望复用同一套任务、上下文、权限、Evidence 和交付规则,而不是依赖每个人的私人 Prompt 和工具习惯。
|
||||
|
||||
只有个人闭环形成重复使用后,才验证共享模板、策略、审计和预算。
|
||||
|
||||
### 4.3 未来用户:高责任团队
|
||||
|
||||
研究、咨询、安全、合规、架构和重大决策场景更需要证据与复核,但也要求更强的隔离、审计和支持。当前只适合作为设计伙伴,不应宣传为生产级企业方案。
|
||||
|
||||
### 4.4 暂不优先
|
||||
|
||||
- 只用一个 Agent 做简单任务的用户。
|
||||
- 只追求最低 Token 价格的用户。
|
||||
- 期待无人值守“自动赚钱”的泛自动化用户。
|
||||
- 需要完整 IDE、云执行和企业 SSO 的用户。
|
||||
- 不能接受本地 Agent 仍可能访问外部 Provider 的用户。
|
||||
- 只需要单次聊天或低价模型切换的消费者。
|
||||
- 期待无人值守自动赚钱的泛自动化用户。
|
||||
- 需要完整 IDE、企业知识中台或大规模云 Runtime 的客户。
|
||||
- 要求 Meldwork 自动读取所有个人和企业知识而不做显式授权的用户。
|
||||
|
||||
## 5. 痛点优先级
|
||||
|
||||
| 优先级 | 痛点 | 频率假设 | 用户损失 | 产品机会 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| P0 | 上下文、Session 和结果散落在不同 Agent | 高 | 重复解释、丢失决策 | 持久工作空间与 Session Fidelity |
|
||||
| P0 | 不知道该信任哪个输出 | 中高 | 错误进入交付 | 独立尝试、审查、Evidence 和验收 |
|
||||
| P0 | Agent 权限和 Provider 出站不透明 | 中 | 安全事件、误写入 | 本地控制面、能力与出站声明 |
|
||||
| P1 | 多个结果难以合并成可复用交付物 | 中高 | 手工整理 | Artifact、差异、导出与复验 |
|
||||
| P1 | Agent 版本变化导致适配失效 | 中高 | 维护成本和不稳定 | 兼容矩阵、Contract Test、社区适配 |
|
||||
| P2 | 本地与 Cloud Agent 不能连续交接 | 增长中 | 任务中断 | Local/Cloud Handoff |
|
||||
| P2 | 团队不能统一策略、预算和审计 | 中 | 影子 AI 与采购风险 | Team Policy、成本和审计 |
|
||||
| 优先级 | 痛点 | 用户损失 | 产品机会 |
|
||||
| --- | --- | --- | --- |
|
||||
| P0 | Agent、Session、文件和知识来源割裂 | 重复解释、遗漏约束、无法继续 | Workspace + Context Pack |
|
||||
| P0 | 不知道结果依据了什么 | 错误进入决策和交付 | Source Usage + Evidence |
|
||||
| P0 | 多 Agent 输出难以比较和采用 | 手工整理、责任不清 | Artifact + Decision |
|
||||
| P0 | 权限与数据出站不透明 | 隐私、安全和误写入风险 | Local Control Plane |
|
||||
| P1 | Agent 和知识连接随版本失效 | 激活失败、维护成本高 | Connector Contract + Compatibility |
|
||||
| P1 | 有效工作方式无法复用 | 每次重新写 Prompt | Typed Task / Workflow Template |
|
||||
| P2 | 本地与 Cloud Agent 无法连续交接 | 长任务中断 | Local / Cloud Handoff |
|
||||
| P2 | 工作不能从现有渠道进入 | 额外切换入口 | Channel Connector |
|
||||
|
||||
## 6. 核心竞争力:从聚合工具到 Harness 基座
|
||||
## 6. 核心竞争力
|
||||
|
||||
### 6.1 Connector Contract
|
||||
### 6.1 Context Portability
|
||||
|
||||
每个 Agent 不只提供一个启动命令,还要声明:能力、输入限制、Session 生命周期、权限模式、事件流、Artifact/Evidence 回传、成本时延和数据出站边界。
|
||||
用 Context Pack 明确记录一项任务实际使用的文件、图片、Skill、知识来源、权限和出站范围,使工作换 Agent 后仍能继续。
|
||||
|
||||
### 6.2 Task → Run → Artifact → Evidence → Acceptance
|
||||
### 6.2 Session Fidelity
|
||||
|
||||
这是产品数据模型和用户叙事的共同骨架:
|
||||
尽可能保留不同 Agent 的原生 Session、能力和增量上下文,而不是把所有连接降级为无状态模型 API。
|
||||
|
||||
1. **Task**:要解决什么问题、验收标准是什么。
|
||||
2. **Run**:由哪个 Agent、哪个版本、什么权限和 Provider 执行。
|
||||
3. **Artifact**:代码变更、文档、结论、文件或链接。
|
||||
4. **Evidence**:测试、来源、日志、差异、审查发现。
|
||||
5. **Acceptance**:人类接受、拒绝、修改、Apply、Commit、Export 或 Reopen。
|
||||
### 6.3 Outcome & Evidence Graph
|
||||
|
||||
### 6.3 Compatibility Intelligence
|
||||
|
||||
真正的生态资产不是“支持过多少 Agent”,而是:哪些 Connector 在什么版本、系统和任务类型上可靠;失败发生在哪里;哪些能力可以安全组合。公开兼容矩阵、Contract Test 和失败复现,比一张超长 Agent Logo 墙更有价值。
|
||||
建立 Task、Run、Artifact、Evidence、Source 和 Decision 的关系,使用户可以回答:谁在什么条件下,基于什么上下文,产生了什么结果,最后为何被采用。
|
||||
|
||||
### 6.4 Local Control Plane
|
||||
|
||||
控制面和工作记录默认保留在本机,但不能宣传成“所有数据永不出网”。用户必须看见:Provider、模型、权限、工作目录、图片/Skill 是否出站,以及 Cloud/Channel 连接何时获得授权。
|
||||
工作状态与编排记录默认留在本机;Agent 和 Provider 是否联网、访问哪些知识来源、获得什么写入能力,都应在任务层可见。
|
||||
|
||||
### 6.5 Open Ecosystem
|
||||
### 6.5 Open Connector Ecosystem
|
||||
|
||||
连接器、能力清单、评测任务和文档要尽可能可贡献;核心客户端保持清晰的安全边界。开源项目的网络效应来自:更多真实适配、更多兼容数据、更多任务模板和更低的新用户安装成本,而不是单纯的 Star 数。
|
||||
对 Agent 和 Knowledge Source 使用明确的能力 Manifest、事件 Contract、兼容矩阵和贡献流程。生态价值来自可复现适配和真实失败数据,而不是 Logo 数量。
|
||||
|
||||
## 7. 开源优先的增长判断
|
||||
### 6.6 Routing Intelligence
|
||||
|
||||
### 7.1 为什么开源是 OPC 的最优起点
|
||||
只有在用户单独同意后,才贡献不含 Prompt、原文和 Artifact 的最小派生数据,例如任务类型、Connector 版本、结果评分、时间区间和采用标签。若授权样本不足,路由建议应保持为本地私有能力,不宣传成网络效应。
|
||||
|
||||
- 降低信任门槛:用户可以检查本地数据、权限和执行边界。
|
||||
- 降低获客成本:GitHub、视频和社区内容可以长期累积。
|
||||
- 允许生态共建:适配器和评测任务不必全部由一个人维护。
|
||||
- 即使商业化失败,也保留技术作品、行业影响力和职业资产。
|
||||
- 可以先用真实使用数据判断是否存在独立付费价值。
|
||||
## 7. 首发验证协议
|
||||
|
||||
### 7.2 开源不能自动解决的问题
|
||||
Meldwork 需要保持 General Agent 定位,但首轮不能验证所有场景。建议用一个协议覆盖多个职业:
|
||||
|
||||
- 许可证、依赖和商标边界仍需要明确。
|
||||
- 用户安装、升级、签名、兼容和支持仍然需要维护。
|
||||
- Star 不等于安装,安装不等于重复使用,重复使用不等于付费。
|
||||
- 过早支持太多 Agent 会把 OPC 变成免费的兼容性客服。
|
||||
```text
|
||||
Primary Agent produces an Artifact
|
||||
-> Reviewer Agent checks constraints and Evidence
|
||||
-> Human adopts, rejects or requests revision
|
||||
```
|
||||
|
||||
### 7.3 90 天可观测指标
|
||||
先收集 10-15 个探索任务,再从以下模板中选择痛点最稳定的一类作为主样本:
|
||||
|
||||
**北极星指标:** 每周完成至少一个“跨 Agent 可复核工作闭环”的活跃 Workspace 数量。
|
||||
- 研究与决策核验。
|
||||
- 方案与交付物评审。
|
||||
- 代码与技术审查。
|
||||
|
||||
辅助指标:
|
||||
首轮不把三类任务混合成一个质量结论,只共享产品协议和数据模型。
|
||||
|
||||
- GitHub:Star、Fork、Issue 质量、外部 PR、文档点击。
|
||||
- 产品:安装成功率、首次任务完成率、第二周回访率、跨 Agent 任务占比。
|
||||
- 价值:被用户接受/导出的 Artifact 数、被复验的 Evidence 数、重复任务数。
|
||||
- 社区:有效反馈人数、贡献 Connector 数、内容带来的安装数。
|
||||
- 商业信号:愿意参与设计伙伴、愿意付支持费、愿意试用团队策略的用户数。
|
||||
## 8. 12 周验证计划
|
||||
|
||||
Star、曝光和候补名单不能替代激活、重复使用和真实交付。
|
||||
### 8.1 需求验证
|
||||
|
||||
## 8. 商业化选项,而非当前承诺
|
||||
- 访谈至少 20 名已使用 Agent 的专业用户,覆盖研究/产品与技术工作。
|
||||
- 只讨论过去两周的真实任务,不询问抽象偏好。
|
||||
- 记录上下文搬运、来源确认、手工复核、失败损失和当前工具预算。
|
||||
- 第 6 周前固定最先完成真实 Task 的 15 名用户 cohort。
|
||||
|
||||
### 8.1 可能的收入阶梯
|
||||
### 8.2 产品验证
|
||||
|
||||
| 阶段 | 收入方式 | 触发条件 |
|
||||
- 至少完成 30 个真实 Task,其中前 10 个用于发现流程,后 20 个按冻结模板验证。
|
||||
- 每个任务记录 Context Pack、Primary Artifact、Reviewer Finding、Evidence 和 Decision。
|
||||
- 至少 8/15 固定用户在首次任务后 30 天内再次完成一个真实 Task。
|
||||
- 相对用户当前手工工作方式,上下文搬运和结果整理主动时间中位数下降至少 25%。
|
||||
- Reviewer 新增 Finding 需要记录被采用、修复或拒绝及其原因。
|
||||
|
||||
### 8.3 生态与商业信号
|
||||
|
||||
- 至少 1 个外部 Connector 或 Task Template 贡献。
|
||||
- 至少 3 个团队愿意使用同一标准化试点边界;实际回款与定制服务分开记录。
|
||||
- Star、曝光、候补名单和 LOI 仅作为辅助信号。
|
||||
|
||||
## 9. Go / Pivot / Stop
|
||||
|
||||
### Go
|
||||
|
||||
- 首次任务可以独立完成。
|
||||
- 15 名固定用户中至少 8 名在 30 天内重复。
|
||||
- 至少 20 个 Task 形成 Artifact、Evidence 和 Decision。
|
||||
- 用户主动协调时间明显下降,Reviewer 产生可采用的新价值。
|
||||
- 出现外部贡献或标准化付费信号。
|
||||
|
||||
### Pivot
|
||||
|
||||
- 用户需要单 Agent + Knowledge + Outcome,但多 Agent 价值弱:聚焦本地 Agent 工作台和 Evidence,不强推协作。
|
||||
- 知识访问是主要价值:强化 Context Pack 和 Source Connector,延后 Cloud Agent。
|
||||
- 技术用户重复使用而非技术用户不成立:保留 General Agent 架构,但收窄首发市场。
|
||||
|
||||
### Stop / 收缩
|
||||
|
||||
- 用户只喜欢统一界面,不会再次完成真实任务。
|
||||
- 维护 Connector 的时间长期超过用户价值开发。
|
||||
- 多 Agent 增加的成本和整合负担大于新增价值。
|
||||
- 只有定制开发和咨询收入,没有标准化需求。
|
||||
|
||||
## 10. 开源与商业化
|
||||
|
||||
开源仍是当前最合理的信任和分发方式,但不能把“开源”当作价值验证本身。
|
||||
|
||||
收入选项按证据逐步开放:
|
||||
|
||||
| 阶段 | 可售价值 | 进入条件 |
|
||||
| --- | --- | --- |
|
||||
| 开源期 | 免费核心;可选赞助、咨询和培训 | 先建立信任,不把赞助当产品收入 |
|
||||
| 早期服务 | 兼容性诊断、部署支持、工作流设计 | 有重复问题且可以标准化交付 |
|
||||
| Open Core | 团队策略、审计、兼容 SLA、签名 Registry、离线更新 | 个人用户重复使用且团队问题真实存在 |
|
||||
| Harness 产品 | 私有部署、Channel、Cloud Handoff、预算与策略 | 有 3 个以上相似付费客户和可复用交付 |
|
||||
| Community | 本地核心、基础 Agent/Knowledge 连接、任务协议 | 公开边界和许可证明确 |
|
||||
| Pro | 高级 Context Pack、比较、导出、模板和更新便利 | 个人用户持续重复使用 |
|
||||
| Team | 共享模板、策略、预算、Evidence 和兼容报告 | 多个团队出现同类需求 |
|
||||
| Enterprise | 私有部署、签名 Connector、审计、离线更新和 SLA | 3 个以上标准化付费客户 |
|
||||
|
||||
### 8.2 暂不锁定价格
|
||||
|
||||
当前不直接承诺 `$12-15/月`、按席位或企业年费,因为用户是否愿意在已有 Agent 费用之外购买“中立工作层”尚未被验证。未来可测试:
|
||||
|
||||
- 个人 Pro:按高级工作流、导出、模板和兼容便利收费。
|
||||
- 团队:按策略、审计、共享模板和支持收费,而不是按 Token 加价。
|
||||
- 企业:按私有部署、签名适配、SLA、集成和合规支持收费。
|
||||
|
||||
Meldwork 不应代收或加价模型 Token,除非未来明确提供独立的托管执行服务。
|
||||
|
||||
## 9. OPC 可承受的验证计划
|
||||
|
||||
### 第 1 阶段:公开 MVP(0-6 周)
|
||||
|
||||
- 统一 README、安装路径、截图、演示视频和问题模板。
|
||||
- 只承诺当前已验证的本地 Agent 和 macOS 体验。
|
||||
- 把 Task/Run 的最小结构先落在本地数据中,不建设云服务。
|
||||
- 找到 10-15 名愿意完成真实任务的早期用户。
|
||||
|
||||
### 第 2 阶段:价值实验(7-12 周)
|
||||
|
||||
- 只做一个主场景:实施 Agent + 独立审查 Agent。
|
||||
- 记录用户手工切换耗时、结果质量、误报、成本、等待和最终采用情况。
|
||||
- 观察同一用户是否在 30 天内重复使用,而不是只看首日反馈。
|
||||
- 让用户直接提出第一个 Connector、模板和 Evidence 需求。
|
||||
|
||||
### 第 3 阶段:决定方向(12 周后)
|
||||
|
||||
- 若个人用户重复使用明显:继续开源产品和生态。
|
||||
- 若团队治理需求重复出现:做 1 个标准化付费试点,不做完整企业平台。
|
||||
- 若价值仅来自统一窗口:收缩为稳定的个人开源工具。
|
||||
- 若多 Agent 质量收益不稳定:把重点转到 Harness 基础设施、单 Agent 质量和可验收工作流。
|
||||
|
||||
## 10. 主要质疑与回应
|
||||
|
||||
### “这只是 Wrapper。”
|
||||
|
||||
MVP 阶段这个质疑部分成立。只有 Connector Contract、Session Fidelity、Evidence、Acceptance、兼容矩阵和安全边界形成闭环后,才有资格称为 Harness 层。
|
||||
|
||||
### “上游 Agent 会自己做。”
|
||||
|
||||
这是最高风险,也是坚持跨厂商中立的理由。Meldwork 不争模型、IDE 或云算力,而是服务用户已经购买和配置的不同 Agent。
|
||||
|
||||
### “大部分任务一个 Agent 就够了。”
|
||||
|
||||
成立。产品必须默认单 Agent,只有高风险、低确定性或需要独立审查的任务才建议多 Agent。
|
||||
|
||||
### “开源以后怎么赚钱?”
|
||||
|
||||
先不把赚钱当作成立条件。未来可以通过兼容、治理、支持、私有部署和 Cloud/Channel 集成收费;是否成立由真实回款决定。
|
||||
|
||||
### “本地优先是不是完全离线?”
|
||||
|
||||
不是。Meldwork 的工作记录和控制面可以在本机,但被选中的 Agent 和 Provider 仍可能访问网络。
|
||||
不默认对模型 Token 加价,不提前承诺无限定制 Connector。
|
||||
|
||||
## 11. 最终判断
|
||||
|
||||
Meldwork 的开源机会来自“把 Agent 作为可替换执行单元,把工作作为可持续、可验证的对象”。
|
||||
Meldwork 最值得做的不是“所有 Agent 的客户端”,而是:
|
||||
|
||||
OPC 阶段最重要的不是把路线图写得更大,而是让每一个用户能在几分钟内理解、安装、完成一次真实任务,并愿意回来再做一次。如果这个循环成立,商业化是可选的放大器;如果不成立,及时收缩为高质量开源工具仍然是成功结果。
|
||||
> **一个让 Agent、知识上下文和可验证结果持续接续的本地工作系统。**
|
||||
|
||||
这条路径比 Coding Agent 聚合更宽,但比通用 Agent 平台更具体。它允许代码、研究、产品和运营共享同一工作协议,同时用 Context Pack、Artifact、Evidence 和 Decision 保持产品边界。
|
||||
|
||||
## 12. 参考来源
|
||||
|
||||
@@ -319,4 +335,3 @@ OPC 阶段最重要的不是把路线图写得更大,而是让每一个用户
|
||||
- [Cline](https://github.com/cline/cline)
|
||||
- [Factory](https://www.factory.ai/)
|
||||
- [Devin](https://devin.ai/)
|
||||
|
||||
@@ -21,6 +21,7 @@ Authorization is process-bound:
|
||||
| Create operating-system notifications | Not directly allowed | Denied | N/A | Main creates notifications only from trusted terminal run events; renderer cannot supply notification content |
|
||||
| Select a working directory | Allowed through OS dialog | Denied | Receives selected path only at invocation | Main-owned `dialog.showOpenDialog` |
|
||||
| List/select local Skills | Sanitized coordinates and display names for installed target Agents | Denied | Receives only its validated selections in prompt/native arguments | Installed-Agent gate; main-owned `LocalSkillCatalog`; per-target revalidation; no renderer-supplied path |
|
||||
| Probe/select knowledge sources | Sanitized readiness plus the user-selected Obsidian Vault path | Denied | Receives only target-scoped, validated read-only access hints | Code-defined catalog; main-owned probes/dialog; per-run revalidation; planned OAuth sources cannot be selected |
|
||||
| Import/preview/discard images | Allowed through picker, exact paste payload, attachment ID, and discard list | Denied | Receives a main-resolved path only for an authorized invocation | Main-owned dialog and `AttachmentStore`; type/size/dimension/checksum validation; referenced files cannot be discarded |
|
||||
| Enable workspace writes | Explicit per-conversation opt-in | Denied | Enforced adapters receive write mode only when enabled; Hermes/OpenClaw remain Agent-managed | Stored `allowWrite`; per-CLI permission flags where supported |
|
||||
| Detect Agents | Allowed | Denied | N/A | Code-defined command catalog; executable paths stay in main |
|
||||
@@ -38,6 +39,7 @@ Authorization is process-bound:
|
||||
- `agentInstaller`: catalog/Skill listing/state/start/cancel/sidebar visibility/change events. Skill listing accepts one Agent kind and returns sanitized records only.
|
||||
- `localAttachments`: `pickImages`, exact-payload `importImage`, ID-only `preview`, and ID-list `discard`. It exposes no filesystem read, path resolution, or arbitrary file picker method.
|
||||
- `localAgentProvider`: non-probing status, explicit encryption probe, save, and delete.
|
||||
- `localKnowledgeBase`: source status, code-defined external setup guides, and a main-owned Obsidian Vault directory picker.
|
||||
|
||||
Node integration, webviews, insecure content, and renderer permission requests are disabled. The packaged Electron fuses disable `runAsNode`, Node option injection, CLI inspect arguments, and loading app code outside `app.asar`.
|
||||
|
||||
@@ -49,12 +51,15 @@ Node integration, webviews, insecure content, and renderer permission requests a
|
||||
- Conversation data is local JSON and is not application-encrypted.
|
||||
- Agent executable paths, native session IDs, native session storage paths, attachment paths, Skill paths, preview payloads, and credential material are stripped from renderer snapshots and lifecycle events. User-selected conversation workdirs are intentionally returned for display and editing.
|
||||
- Main scans known per-Agent Skill roots and reads only bounded Skill manifest prefixes for catalog metadata. The renderer cannot request an arbitrary directory or file.
|
||||
- `KnowledgeBaseStore` persists only the normalized user-selected Obsidian Vault path. Feishu and DingTalk authentication remain in their local CLI-owned stores; Meldwork does not receive or persist their tokens.
|
||||
- Knowledge-source selection accepts only code-defined source kinds. Main resolves an allowlisted CLI command name or the selected absolute Vault path and scopes the hint to explicit target Agents.
|
||||
- Agent filesystem access is scoped to the selected working directory by Meldwork arguments/configuration where the upstream CLI supports it.
|
||||
|
||||
## Process And Network Permissions
|
||||
|
||||
- Only supported Agent kinds can be invoked.
|
||||
- Skill selections are limited to four, must still exist in the selected Agent's current catalog, and are routed only to that Agent. Hermes receives validated slugs through its native `--skills` flags; no renderer value becomes an arbitrary CLI argument.
|
||||
- Knowledge-source selections are limited to four, must be currently readable, and are routed only to their selected target Agents. Feishu/DingTalk command names come from main-side detection, not renderer input; Obsidian paths come from the main-owned directory picker.
|
||||
- Image references are limited to four and are resolved inside main. Codex and OpenCode accept up to four; Hermes accepts one; unsupported or unequal multi-Agent context is rejected before any child process starts.
|
||||
- Child environments begin with a system-variable allowlist, then add only the selected Agent's native credentials and optional configured Provider values.
|
||||
- Installer environments remove variables whose names look like keys, tokens, secrets, passwords, credentials, cookies, authorization, or prompts.
|
||||
@@ -67,4 +72,5 @@ Node integration, webviews, insecure content, and renderer permission requests a
|
||||
- There is no per-user permission separation inside the app because there is no account model.
|
||||
- An Agent process runs with the operating-system permissions of the local user. Meldwork permission flags reduce capability but are not an OS sandbox.
|
||||
- Imported images are private local copies but are not application-encrypted; when sent, their contents may reach the selected Agent's configured model Provider.
|
||||
- Knowledge-source content is not copied into Meldwork by the selection flow, but an invoked Agent may read selected documents or Vault files and send relevant content to its configured Provider. Current read-only behavior is an explicit task instruction plus source capability constraints, not an OS sandbox or a universal upstream-tool guarantee.
|
||||
- Installer approval authorizes an external system modification. Package/script integrity is not currently pinned.
|
||||
+176
-141
@@ -1,24 +1,26 @@
|
||||
# Meldwork 产品 BP
|
||||
|
||||
> 版本:OPC / Open-source-first MVP
|
||||
> 版本:General Agent + Knowledge / Open-source-first
|
||||
>
|
||||
> 日期:2026-07-31
|
||||
> 日期:2026-08-02
|
||||
>
|
||||
> 用途:项目介绍、开源发布、设计伙伴沟通和后续商业化讨论
|
||||
|
||||
## 1. 一句话
|
||||
|
||||
**Meldwork 把用户已经在用的本地 Agent 带进一个本地优先、可追溯的工作空间,并逐步演进为连接本地、云端和工作渠道的开放 Agent Harness。**
|
||||
**Meldwork 把用户已经在用的 Agent 和知识来源带进一个本地优先、可追溯的工作空间,让工作可以跨 Agent 接续,并留下可采用的产物与证据。**
|
||||
|
||||
Current MVP is a local-first desktop workspace for supported Agent CLIs. The Harness, Cloud and Channel capabilities are roadmap directions, not current product claims.
|
||||
English:
|
||||
|
||||
## 2. 品牌与定位
|
||||
> **Meldwork brings the agents and knowledge you already use into one local, accountable workspace.**
|
||||
|
||||
### 工作名
|
||||
## 2. 产品定位
|
||||
|
||||
**Meldwork** 继续作为工作名推进。它表达“把分散的工作重新接续起来”,不把产品锁死在 Multi-Agent、Coding 或某一家模型厂商上。
|
||||
### 品类
|
||||
|
||||
正式公开前仍需完成:商标、域名、社交账号、中文理解测试和软件许可证确认。`RoundRelay`、`MAC-Work` 和 `Open-MACWork` 不作为当前主品牌。
|
||||
> **An open, local-first work system for agents and knowledge across vendors.**
|
||||
>
|
||||
> **面向跨厂商 Agent 与知识来源的开放、本地优先工作系统。**
|
||||
|
||||
### 当前 MVP Slogan
|
||||
|
||||
@@ -26,226 +28,259 @@ Current MVP is a local-first desktop workspace for supported Agent CLIs. The Har
|
||||
>
|
||||
> **Agent 可切换,工作不断线。**
|
||||
|
||||
这条文案与当前“持久工作空间、Session 延续”的已实现价值一致,适合现阶段 README 和演示。
|
||||
当前产品已经能够连接已支持的本地 Agent、维持工作空间和兼容条件下的原生 Session,并让用户显式选择部分知识来源。这条 Slogan 仍与现阶段价值一致。
|
||||
|
||||
### 目标产品 Slogan
|
||||
### 目标产品承诺
|
||||
|
||||
> **Different agents. Work you can verify.**
|
||||
> **Different agents. Context stays. Work can be verified.**
|
||||
>
|
||||
> **不同 Agent,工作有据可验。**
|
||||
> **不同 Agent,上下文不断,结果有据可验。**
|
||||
|
||||
当 Task、Artifact、Evidence 与 Acceptance 已经形成真实闭环后,再把这条升级为主 Slogan。它的重点不是“Agent 越多越好”,而是:不同 Agent 可以提供独立视角,但最终工作必须经过证据和人类判断。
|
||||
只有当 Context Pack、Artifact、Evidence 和 Decision 形成真实闭环后,才应把这条表达用于主宣传。
|
||||
|
||||
### 品类描述
|
||||
### 品牌逻辑
|
||||
|
||||
> **An open, local-first work system for agents across vendors.**
|
||||
>
|
||||
> **面向跨厂商 Agent 的开放、本地优先工作系统。**
|
||||
Meld 表示不同 Agent 的工作可以接续,但不要求答案被强行融合或达成共识。Work 表示产品处理的是真实任务、产物和决定,而不是闲聊。
|
||||
|
||||
### 产品主叙事
|
||||
|
||||
Agent 会变,模型会变,入口会变;工作不应该因为换了一个 Agent 就失去上下文、权限边界和复核记录。
|
||||
品牌标志中的连续线代表工作延续,独立的珊瑚色端点代表结果被检查并由人类采用或拒绝。品牌承诺应落在“连续性 + 可验证结果”,而不是 Agent 数量。
|
||||
|
||||
## 3. 用户问题
|
||||
|
||||
当用户同时使用 Codex、Claude Code、OpenCode、Kimi、MiMo、Qwen 或其他 Agent 时,真实工作通常被拆散:
|
||||
Agent 能力越来越强,但用户的工作仍然被拆散:
|
||||
|
||||
- 上下文和原生 Session 在不同终端或应用中断裂。
|
||||
- 用户手工复制任务、文件、限制和前序结果。
|
||||
- 不同 Agent 的输出难以比较,流畅文本被误认为已经完成。
|
||||
- 权限、工作目录、Provider 和数据出站缺少统一可见性。
|
||||
- 结果很难沉淀为可复用的 Artifact、Evidence 和模板。
|
||||
- 不同 Agent 拥有独立 Session、工具、Provider 和权限。
|
||||
- 上下文散落在本地文件、Obsidian、飞书、钉钉、Notion、Confluence、GitHub 和聊天记录中。
|
||||
- 用户不断复制任务、约束和前序结果。
|
||||
- 不同 Agent 的输出难以比较,流畅文本容易被误认为已完成。
|
||||
- 用户不知道结果具体依据了哪些来源,也无法稳定复验。
|
||||
- 切换 Agent 后,Artifact、Evidence 和最终 Decision 很难继续。
|
||||
|
||||
市场已经有越来越多强 Agent,缺少的是用户可以控制的跨 Agent 工作层。
|
||||
市场并不缺更多 Agent,缺少的是用户能够掌控的跨 Agent 工作与上下文层。
|
||||
|
||||
## 4. 解决方案
|
||||
|
||||
### 4.1 当前 MVP
|
||||
|
||||
- 发现和管理已支持的本地 Agent CLI。
|
||||
- 在本地持久保存直接与群组会话。
|
||||
- 在兼容条件下恢复原生 Agent Session。
|
||||
- 用明确轮次和时间边界运行有限的多 Agent 讨论。
|
||||
- 传递 Agent-specific Skill 和受限图片上下文。
|
||||
- 在 Electron 主进程管理执行、工作目录、Provider 和敏感数据。
|
||||
|
||||
### 4.2 目标 Harness
|
||||
|
||||
将产品对象从 Conversation 升级为:
|
||||
Meldwork 的目标闭环:
|
||||
|
||||
```text
|
||||
Task -> Run -> Artifact -> Evidence -> Human Acceptance
|
||||
Agent + Knowledge Source
|
||||
-> Context Pack
|
||||
-> Task / Run
|
||||
-> Artifact / Evidence
|
||||
-> Human Decision / Adoption
|
||||
```
|
||||
|
||||
Connector 负责把本地、云端、自定义和渠道型 Agent 接入同一套能力声明、Session 生命周期、运行事件、权限、出站和结果回传协议。
|
||||
### 4.1 当前 MVP 已实现
|
||||
|
||||
## 5. 目标用户
|
||||
- 本地 Electron 桌面工作空间。
|
||||
- 已支持本地 Agent CLI 的发现、就绪状态和受控运行。
|
||||
- 直接与群组会话,以及兼容条件下的原生 Session 延续。
|
||||
- 有界自动讨论、取消、失败状态和本地通知。
|
||||
- Agent-specific Skill 与受限图片上下文。
|
||||
- Provider 配置和操作系统安全存储。
|
||||
- 飞书、钉钉和 Obsidian 的连接状态与只读知识来源选择。
|
||||
|
||||
### 首要用户:多 Agent 重度个人用户
|
||||
当前知识来源能力是显式访问提示,不是由 Meldwork 执行的统一搜索、索引或 RAG。Notion、Confluence、Google Drive 和 SharePoint 仍是规划入口。
|
||||
|
||||
他们已经在不同 Agent 之间切换,愿意安装本地软件,且在高风险或复杂任务中需要第二个视角。开源项目的价值是降低他们的迁移、试用和信任成本。
|
||||
### 4.2 下一阶段核心
|
||||
|
||||
### 次要用户:5-50 人 AI-native 团队
|
||||
- Knowledge Source 与 Context Pack。
|
||||
- Task、Run、Artifact、Evidence、Decision。
|
||||
- Primary Agent 产出 + Reviewer Agent 独立复核。
|
||||
- Agent / Knowledge Connector Contract。
|
||||
- Evidence Bundle、导出和真实 Adoption 记录。
|
||||
|
||||
他们需要共享的任务模板、权限策略、Evidence 和兼容性信息,但只有在个人工作闭环成立后才进入产品验证。
|
||||
### 4.3 后续条件能力
|
||||
|
||||
### 未来用户:高责任专业团队
|
||||
- Local / Cloud Agent Handoff。
|
||||
- GitHub、钉钉、飞书或其他任务型 Channel。
|
||||
- Typed Workflow、预算和 Human Gate。
|
||||
- Team 策略、审计和可选同步。
|
||||
|
||||
安全、架构、研究、咨询和重大迁移团队对可复核工作更敏感,可能成为 Harness 服务的付费客户;目前不宣传为企业生产级产品。
|
||||
这些属于路线图,不是当前功能承诺。
|
||||
|
||||
## 6. Why now
|
||||
## 5. 首要用户
|
||||
|
||||
1. Agent 正从问答工具进入长任务、工具调用、后台执行和多渠道协作阶段。
|
||||
2. 上游产品会继续增强自己的多 Agent,但用户仍会同时使用多个厂商和本地 CLI。
|
||||
3. AI 使用率增长与信任、准确性、隐私和责任问题同时增长。
|
||||
4. 开源社区需要一个不强迫迁移模型或账号的中立工作层。
|
||||
5. OPC 的资源限制要求先从可验证的小切口建立分发,而不是先建设重型平台。
|
||||
### ICP 1:Agent 重度专业用户
|
||||
|
||||
## 7. 核心竞争力
|
||||
产品经理、研究人员、顾问、开发者、安全人员、分析师和创业者中,已经使用多个 Agent 并需要对产物负责的人。
|
||||
|
||||
### 7.1 跨厂商中立
|
||||
他们购买的不是“更多 Agent”,而是:
|
||||
|
||||
不绑定某个模型、IDE 或 Cloud。用户可以保留已有账号、Provider 和本地工作方式。
|
||||
- 少复制一次上下文。
|
||||
- 少遗漏一个关键来源或约束。
|
||||
- 多一个独立且可追溯的复核视角。
|
||||
- 把结果直接变成可以继续使用的 Artifact。
|
||||
|
||||
### 7.2 Session Fidelity
|
||||
### ICP 2:5-50 人 AI-native 团队
|
||||
|
||||
连接不是简单转发 Prompt,而是尽可能保留原生 Session、Agent-specific 能力和上下文边界。
|
||||
团队成员使用不同 Agent 和知识来源,希望复用相同任务、权限、Evidence 和交付规则。只有个人重复使用成立后,才进入共享模板、策略、预算和审计验证。
|
||||
|
||||
### 7.3 Evidence-first 工作流
|
||||
### ICP 3:未来高责任团队
|
||||
|
||||
把对话输出变成 Artifact、Evidence 和 Acceptance,支持复盘、比较、导出和后续采用。
|
||||
研究、咨询、安全、合规和重大决策团队对 Evidence 和 Decision 链更敏感,但需要更强隔离、审计和支持。当前只作为设计伙伴,不宣传为生产级企业能力。
|
||||
|
||||
### 7.4 Local Control Plane
|
||||
## 6. 首发场景
|
||||
|
||||
工作记录和编排状态默认在本地;Provider、权限、工作目录和数据出站可见。Local-first 不等于所有模型离线。
|
||||
Meldwork 保持 General Agent 定位,但首轮只实现一个通用协议:
|
||||
|
||||
### 7.5 Open Connector Ecosystem
|
||||
```text
|
||||
Primary Agent produces an Artifact
|
||||
-> Reviewer Agent checks constraints and Evidence
|
||||
-> Human adopts, rejects or requests revision
|
||||
```
|
||||
|
||||
公开能力 Contract、兼容矩阵、任务模板和贡献路径,让生态贡献成为增长和维护的杠杆。
|
||||
候选模板:
|
||||
|
||||
## 8. 与竞品的关系
|
||||
- 研究与决策核验。
|
||||
- 方案、PRD、报告或交付物评审。
|
||||
- 代码与技术审查。
|
||||
|
||||
Meldwork 不与 Agent、IDE、终端或云执行平台在同一层争夺全部价值:
|
||||
首轮根据真实任务频率选择一个主模板,不同时为三个领域开发独立产品。
|
||||
|
||||
## 7. Why now
|
||||
|
||||
1. Agent 正从 Coding、Research 或 Chat 工具演化为跨领域执行单元。
|
||||
2. 用户会长期同时使用全球与中国、开源与专有、本地与云端 Agent。
|
||||
3. 知识与工作上下文仍然分散在不同平台,换 Agent 就容易失去连续性。
|
||||
4. 上游平台会快速商品化并行 Agent,但天然优先优化自家生态。
|
||||
5. AI 使用增长与准确性、隐私、成本和责任问题同步增长。
|
||||
6. 本地优先和开源可以降低新控制层的信任门槛。
|
||||
|
||||
## 8. 核心竞争力
|
||||
|
||||
### 8.1 Cross-vendor Neutrality
|
||||
|
||||
不绑定某个模型、IDE、知识平台或 Cloud。用户保留已有 Agent、账号、Provider 和知识来源。
|
||||
|
||||
### 8.2 Context Portability
|
||||
|
||||
Context Pack 记录本次任务实际允许使用的文件、图片、Skill、知识来源、敏感等级和出站范围,使工作换 Agent 后仍可继续。
|
||||
|
||||
### 8.3 Session Fidelity
|
||||
|
||||
连接不是简单转发 Prompt,而是尽可能保留原生 Session、工具、权限和增量上下文。
|
||||
|
||||
### 8.4 Outcome & Evidence Graph
|
||||
|
||||
把 Task、Run、Artifact、Evidence、Source 和 Decision 关联起来,使结果可以比较、复验、导出和继续使用。
|
||||
|
||||
### 8.5 Local Control Plane
|
||||
|
||||
工作状态默认保留在本机,Agent、Provider、知识访问和写入权限在任务层显式可见。Local-first 不等于所有模型离线。
|
||||
|
||||
### 8.6 Open Connector Ecosystem
|
||||
|
||||
公开 Agent 与 Knowledge Connector 的能力 Manifest、兼容矩阵、事件 Contract 和贡献路径。生态价值来自可复现适配与真实失败数据,不是 Logo 数量。
|
||||
|
||||
## 9. 竞争关系
|
||||
|
||||
| 竞品类型 | 他们的优势 | Meldwork 的回答 |
|
||||
| --- | --- | --- |
|
||||
| 单厂商 Agent | 模型、工具和原生体验强 | 连接用户已有的多个 Agent |
|
||||
| AI IDE / Terminal | 入口和编辑体验强 | 不复制 IDE;聚焦跨 Agent 工作连续性 |
|
||||
| 云端控制面 | 并行、后台和企业治理强 | 先做本地控制面,再按证据接 Cloud |
|
||||
| 开放 Agent 平台 | 协议、Runtime 和生态广 | 以易安装、真实任务、兼容验证和 OPC 速度切入 |
|
||||
| 单厂商 Agent | 模型、工具和原生体验强 | 连接用户已有的不同 Agent |
|
||||
| AI IDE / Terminal | 强入口和编辑执行体验 | 不复制 IDE,聚焦跨 Agent 工作状态 |
|
||||
| Knowledge Platform | 内容、搜索和组织协作成熟 | 不替代内容平台,只管理任务上下文和来源关系 |
|
||||
| Cloud Agent Control Plane | 后台执行、并行和企业治理强 | 先做本地控制与可验证 Handoff |
|
||||
| 开放 Agent Platform | Runtime、协议和生态广 | 以易安装、知识接入、Session 和 Outcome 切入 |
|
||||
|
||||
最大风险是上游会吸收多 Agent 控制面能力。因此产品必须持续保持中立、开放和可迁移,而不是围绕某个供应商做深度锁定。
|
||||
最大风险是上游平台覆盖多 Agent 控制面。因此 Meldwork 必须持续保持跨厂商、可迁移和知识平台中立。
|
||||
|
||||
## 9. 开源优先的 Go-to-Market
|
||||
## 10. Go-to-Market
|
||||
|
||||
### 9.1 发布路径
|
||||
### 10.1 开源发布
|
||||
|
||||
1. GitHub 公开仓库:清晰的 README、安装说明、许可证、支持矩阵和安全边界。
|
||||
2. 真实演示:用一个任务展示“实施 Agent + 独立审查 Agent + 人类验收”。
|
||||
3. 兼容性内容:持续发布 Agent 版本、平台和失败复盘,不只发布 Logo。
|
||||
4. 社区入口:Issue 模板、Connector/Task Template 贡献指南和公开路线图。
|
||||
5. 国内外双语传播:GitHub、Bilibili、V2EX、掘金、知乎、X、YouTube、Hacker News、Reddit 等渠道择少而做。
|
||||
1. 提供真实能力矩阵、安装说明、数据边界和故障排查。
|
||||
2. 用一个真实任务演示“知识上下文 -> Primary Artifact -> Reviewer Finding -> Human Decision”。
|
||||
3. 持续发布 Connector 兼容报告和失败复盘。
|
||||
4. 提供 Task Template、Connector 和评测任务的贡献入口。
|
||||
5. 国内外使用同一产品叙事,但只选择少量渠道持续经营。
|
||||
|
||||
### 9.2 内容策略
|
||||
### 10.2 内容策略
|
||||
|
||||
内容必须证明一个用户结果,而不是讲抽象 AI 愿景:
|
||||
内容必须展示真实结果:
|
||||
|
||||
- “两个 Agent 审查同一个真实变更,谁发现了什么?”
|
||||
- “为什么某个 Agent 不能安全地加入这个任务?”
|
||||
- “一次 Connector 失效是如何被定位和修复的?”
|
||||
- “本地优先到底保留了什么,哪些数据仍会出网?”
|
||||
- “一个 OPC 如何在每周 10 小时内维护开源 Agent Harness?”
|
||||
- 同一份知识上下文交给两个 Agent,差异在哪里。
|
||||
- Reviewer 找到了什么,用户最终采用了什么。
|
||||
- 哪些知识来源被允许使用,哪些数据仍会出网。
|
||||
- 一次 Agent 或 Knowledge Connector 失效如何被诊断。
|
||||
- 为什么某项任务只需要一个 Agent。
|
||||
|
||||
### 9.3 90 天目标
|
||||
不展示“十个头像轮流说话”或没有 Artifact 的自动讨论 Demo。
|
||||
|
||||
产品目标优先于曝光目标:
|
||||
### 10.3 90 天目标
|
||||
|
||||
- 15 名外部用户完成真实任务。
|
||||
- 同一批至少 8 名在首次任务后 30 天内重复使用。
|
||||
- 15 名固定外部用户完成真实 Task。
|
||||
- 同一批至少 8 名在首次任务后 30 天内重复。
|
||||
- 至少 20 个 Task 形成 Artifact、Evidence 和 Decision。
|
||||
- 至少 1 个外部 Connector 或 Task Template 贡献。
|
||||
- 形成 20 个有 Acceptance 结果的任务记录。
|
||||
- 以 Star、Fork、视频播放、Issue、安装和重复任务建立完整漏斗,而不是只追求单一数字。
|
||||
- 相对手工跨 Agent,上下文搬运和整理主动时间中位数下降至少 25%。
|
||||
- 至少 3 个团队对同一标准化试点表达真实采购意愿,回款和定制收入分开记录。
|
||||
|
||||
## 10. 商业模式:延后,但保留选项
|
||||
## 11. 商业模式
|
||||
|
||||
### 10.1 开源层
|
||||
### Open Core + BYO Agent / BYO Knowledge
|
||||
|
||||
核心桌面客户端、基础本地工作流、Connector 文档和社区适配器免费开放。具体许可证必须在公开发行前单独完成法律审查与选定。
|
||||
|
||||
### 10.2 可选收入层
|
||||
|
||||
| 收入层 | 可售价值 | 进入条件 |
|
||||
| 层级 | 可售价值 | 进入条件 |
|
||||
| --- | --- | --- |
|
||||
| 支持/培训 | 安装、兼容和工作流辅导 | 问题重复且可形成标准服务包 |
|
||||
| Pro | 个人模板、比较、导出、更新便利 | 个人用户持续重复使用 |
|
||||
| Team | 策略、共享模板、Evidence、预算和审计 | 多个团队出现相同需求 |
|
||||
| Harness / Enterprise | 私有部署、Cloud/Channel、签名 Connector、SLA | 至少 3 个相似付费客户,交付可复用 |
|
||||
| Community | 本地核心、基础 Agent/Knowledge 连接、任务协议 | 公开边界和许可证明确 |
|
||||
| Pro | 高级 Context Pack、比较、导出、模板和更新便利 | 个人用户持续重复使用 |
|
||||
| Team | 共享策略、Evidence、预算、兼容报告和可选同步 | 多个团队出现同类问题 |
|
||||
| Enterprise | 私有部署、签名 Connector、审计、离线更新和 SLA | 至少 3 个标准化付费客户 |
|
||||
|
||||
### 10.3 不做的收入
|
||||
不默认对模型 Token 加价。用户已经为 Agent、模型或知识平台付费,Meldwork 应对工作连续性、验证、兼容和治理收费。
|
||||
|
||||
- 不把 Token 加价作为默认商业模式。
|
||||
- 不在没有标准化边界时承诺定制 Connector 无限支持。
|
||||
- 不把一次咨询、定制开发或未到账意向写成 ARR。
|
||||
- 不因为“企业感兴趣”就提前建设完整企业版。
|
||||
## 12. 投入顺序
|
||||
|
||||
## 11. 投入与资源策略
|
||||
1. 新用户激活、安装和真实能力边界。
|
||||
2. Context Pack 与 Task Outcome 闭环。
|
||||
3. Agent / Knowledge Connector Contract 和兼容测试。
|
||||
4. Evidence、导出和评测。
|
||||
5. 一个 Cloud Handoff 或 Channel。
|
||||
6. Workflow、预算和 Team。
|
||||
|
||||
当前不以融资为项目成立条件。若未来需要外部资金,优先用于:
|
||||
不优先投入:自建模型、重型云平台、完整知识中台、销售团队、全量 Agent 适配和复杂多租户。
|
||||
|
||||
1. Connector 兼容测试与发布基础设施。
|
||||
2. Task/Artifact/Evidence 产品闭环。
|
||||
3. 签名、公证、安装和安全审查。
|
||||
4. 真实用户研究、评测和设计伙伴。
|
||||
5. 开源文档、内容和社区运营。
|
||||
## 13. 关键质疑
|
||||
|
||||
不优先投入:自建模型、重型云平台、销售团队、全量 Agent 适配和复杂多租户。
|
||||
### “只是 Wrapper。”
|
||||
|
||||
## 12. 关键质疑
|
||||
MVP 阶段部分成立。只有 Context Pack、Session Fidelity、Connector Contract、Outcome & Evidence Graph 和兼容数据形成闭环后,才具备独立产品层价值。
|
||||
|
||||
### 只是 Wrapper?
|
||||
### “为什么不直接使用一个强 Agent?”
|
||||
|
||||
MVP 阶段部分成立。产品必须通过 Session Fidelity、Connector Contract、Evidence、Acceptance 和兼容数据把价值从 UI 包装升级为可复用的执行层。
|
||||
多数任务应该只用一个 Agent。Meldwork 的价值首先是工作和上下文连续性;第二个 Agent 只在风险、证据不足或能力互补时加入。
|
||||
|
||||
### 用户为什么不直接用一个强 Agent?
|
||||
### “为什么不直接使用知识平台自己的 AI?”
|
||||
|
||||
多数任务确实应该只用一个。Meldwork 只服务重要到需要独立审查、不同能力或明确权限控制的工作。
|
||||
知识平台优先优化自己的内容和 Agent。Meldwork 服务用户跨多个 Agent、文件和知识平台的工作,并保留本地任务与 Decision 记录。
|
||||
|
||||
### 开源会被复制?
|
||||
### “General Agent 会不会过于宽泛?”
|
||||
|
||||
代码会被复制。难复制的是长期兼容数据、真实任务评测、社区贡献、用户信任和可复用的 Harness 工作方式。如果这些没有建立,项目就不应把自己包装成有护城河的平台。
|
||||
如果产品按职业建立大量模式,会失去焦点。Meldwork 用统一 Task、Context、Artifact、Evidence 和 Decision 协议保持边界,并只验证一个首发模板。
|
||||
|
||||
### 一个 OPC 能做完吗?
|
||||
### “开源会被复制?”
|
||||
|
||||
不能同时做完所有方向。因此路线以一个主场景、少数 Tier-1 Connector、公开文档和内容反馈为约束;Cloud、Channel、Team 只在证据成熟后推进。
|
||||
代码可以复制。长期兼容数据、真实任务评测、Connector 社区、用户信任和可复用工作协议更难复制。如果这些没有形成,项目就不应自称拥有平台护城河。
|
||||
|
||||
## 13. 成功定义
|
||||
## 14. 成功定义
|
||||
|
||||
### 开源成功
|
||||
|
||||
别人能安装、完成任务、复现问题、提交贡献,并且项目能持续产生职业与行业影响力。
|
||||
别人能安装、完成真实任务、理解数据边界、复现问题并提交有效贡献。
|
||||
|
||||
### 产品成功
|
||||
|
||||
同一批用户在 30 天内重复使用跨 Agent 工作闭环,并愿意提供真实 Task、Artifact 和 Evidence 反馈。
|
||||
同一批用户在 30 天内重复完成有 Context Pack、Artifact、Evidence 和 Decision 的 Task。
|
||||
|
||||
### 商业成功
|
||||
|
||||
存在 3 个以上相似的标准化付费需求,且支持、兼容或治理能力的边际交付成本可被一个人或小团队承受。
|
||||
至少 3 个团队为同一标准化能力付费,且支持和兼容成本可以由小团队承受。
|
||||
|
||||
### 应收缩
|
||||
|
||||
如果用户只喜欢统一窗口、不重复使用、不愿贡献或付费,多 Agent 质量收益也不稳定,就把项目定位收缩为高质量个人开源工具,不再继续平台化。
|
||||
若用户只喜欢统一窗口、不重复使用,或多 Agent 价值不成立,则保留单 Agent + Knowledge + Outcome 的个人开源工具,不继续建设平台。
|
||||
|
||||
## 14. 对外最终叙事
|
||||
## 15. 最终叙事
|
||||
|
||||
> **Meldwork is the open, local-first harness for work that moves between agents.**
|
||||
>
|
||||
> **Meldwork 是面向跨 Agent 工作的开放、本地优先 Harness。**
|
||||
> **Agents will change. Knowledge will live in different places. Work still needs continuity and proof.**
|
||||
|
||||
当前宣传补充:
|
||||
|
||||
> **Bring the agents you already use into one accountable workspace.**
|
||||
>
|
||||
> **把你已经在用的 Agent 带进一个可追溯的工作空间。**
|
||||
|
||||
愿景和当前能力必须分开写。不要在公开页面把 Cloud、任意 Connector、Team Governance 或 Enterprise Security 写成已交付。
|
||||
Meldwork 不试图成为另一个万能 Agent,也不取代用户的知识平台。它要成为 Agent 和知识来源之间的本地工作层,让任务能够接续、结果能够复验、决定能够留下。
|
||||
+271
-209
@@ -1,288 +1,350 @@
|
||||
# Meldwork 产品迭代规划说明书
|
||||
|
||||
> 版本:OPC 开源优先版
|
||||
> 版本:General Agent + Knowledge + Outcome
|
||||
>
|
||||
> 日期:2026-07-31
|
||||
> 日期:2026-08-02
|
||||
>
|
||||
> 适用范围:产品、工程、开源、内容和验证工作
|
||||
> 适用范围:产品、工程、开源、内容和用户验证
|
||||
|
||||
## 0. 迭代总原则
|
||||
## 0. 路线结论
|
||||
|
||||
Meldwork 的下一阶段不是把“聊天窗口”做得更复杂,而是把用户正在做的工作变成可持续、可交接、可验证的对象。
|
||||
Meldwork 后续不应继续沿着“增加 Agent 数量”和“强化群聊效果”迭代,也不应重新收窄为 Coding Agent 控制台。
|
||||
|
||||
产品主线:
|
||||
建议主线是:
|
||||
|
||||
```text
|
||||
Agent 连接
|
||||
-> 持久工作空间
|
||||
-> Task / Run
|
||||
-> Artifact / Evidence
|
||||
-> Human Acceptance
|
||||
-> 可复用模板与 Connector 生态
|
||||
Agent / Knowledge Source
|
||||
-> Context Pack
|
||||
-> Task / Run
|
||||
-> Artifact / Evidence
|
||||
-> Decision / Adoption
|
||||
-> Reusable Workflow / Connector
|
||||
```
|
||||
|
||||
OPC 约束下,每一个版本都必须同时回答三个问题:
|
||||
产品要解决的不是“让更多 Agent 同时说话”,而是让一项工作在 Agent、知识来源和人之间流转时,不丢失上下文、权限边界、产物和验证记录。
|
||||
|
||||
1. 用户是否因此更快完成了一项真实工作?
|
||||
2. 这项能力是否可以被演示、复用和写进文档?
|
||||
3. 一个有日常工作的个人是否能在两周内维护它?
|
||||
阶段性取舍:
|
||||
|
||||
如果答案只有“技术上更完整”,不进入近期路线图。
|
||||
1. 保持 General Agent 定位,但只验证一个通用工作协议。
|
||||
2. 默认使用一个 Agent,只有高风险、低确定性或需要独立观点时才增加 Reviewer Agent。
|
||||
3. 先完成本地 Task 和 Outcome 闭环,再决定 Cloud、Channel、Team 是否值得投入。
|
||||
4. 知识源先做显式授权和可追溯上下文,不提前建设重型 RAG、向量数据库或企业知识中台。
|
||||
|
||||
## 1. 当前 MVP 的事实基线
|
||||
## 1. 当前事实基线
|
||||
|
||||
### 1.1 已具备
|
||||
|
||||
- Electron 本地优先桌面应用。
|
||||
- 已支持本地 Agent CLI 的发现、就绪状态和受控调用。
|
||||
- 直接会话与群组会话持久化。
|
||||
- 兼容条件下的原生 Agent Session 续接。
|
||||
- 有界的多轮自动讨论,并有运行状态和失败状态。
|
||||
- Agent-specific Skill 引用和受限图片上下文。
|
||||
- Provider 配置与操作系统安全存储。
|
||||
- Renderer 通过窄 Preload API 访问主进程能力。
|
||||
- 工作目录、写入模式、Installer 和部分 Agent 权限边界。
|
||||
- 直接会话、群组会话和兼容条件下的原生 Agent Session 延续。
|
||||
- 有界自动讨论、运行状态、失败状态和停止能力。
|
||||
- Agent-specific Skill 与受限图片上下文。
|
||||
- Provider 配置、操作系统安全存储和窄 Preload API。
|
||||
- 飞书文档、钉钉文档和 Obsidian 的本地连接状态与只读任务上下文选择。
|
||||
- Notion、Confluence、Google Drive 和 SharePoint 的规划入口,但尚未提供可用 Connector。
|
||||
|
||||
### 1.2 当前不应宣称
|
||||
### 1.2 知识源能力的真实边界
|
||||
|
||||
- 任意 Agent 已经可以通过公开协议接入。
|
||||
- Cloud Agent 已经可以后台执行并回传。
|
||||
- Task、Artifact、Evidence、Acceptance 已经构成完整工作流。
|
||||
- 已具备团队同步、SSO、审计、预算、企业级沙箱或跨设备同步。
|
||||
- 已完成 macOS 公证、Windows 真机发行和所有 Agent 的生产级兼容认证。
|
||||
当前能力是把用户明确选择、经过主进程验证的知识源访问方式作为只读提示交给目标 Agent:
|
||||
|
||||
- 飞书和钉钉通过本机已配置 CLI 连接。
|
||||
- Obsidian 通过用户选择的本地 Vault 目录连接。
|
||||
- Agent 被要求在相关时使用知识源、说明所用来源并避免修改源内容。
|
||||
|
||||
当前尚未实现:
|
||||
|
||||
- Meldwork 自己检索、索引或缓存知识库内容。
|
||||
- 统一的引用片段、内容快照、版本哈希或权限快照。
|
||||
- 确定性 RAG、跨知识库搜索排序或引用完整性校验。
|
||||
- Notion、Confluence、Google Drive 和 SharePoint 的真实连接与授权。
|
||||
|
||||
因此近期对外应使用“Knowledge Sources / 知识来源”和“显式上下文访问”,不应宣传成完整知识库引擎。
|
||||
|
||||
### 1.3 最大结构缺口
|
||||
|
||||
当前持久化中心仍然是 Conversation。下一阶段要把工作对象升级为:
|
||||
当前持久化中心仍然是 Conversation。它能回答 Agent 说了什么,但不能稳定回答:
|
||||
|
||||
| 旧中心 | 新中心 |
|
||||
| --- | --- |
|
||||
| Conversation | Workspace / Task |
|
||||
| Message | Run Event / Decision |
|
||||
| Agent reply | Artifact / Finding |
|
||||
| 自动轮次 | Bounded Workflow |
|
||||
| “接受”按钮 | Acceptance + Apply/Commit/Export |
|
||||
| 适配器数量 | Connector Capability + Compatibility Evidence |
|
||||
- 用户真正要完成的 Task 是什么。
|
||||
- 哪些知识来源和上下文被允许用于这次任务。
|
||||
- 哪次 Run 产生了哪个 Artifact。
|
||||
- 哪些 Evidence 支持或反驳结果。
|
||||
- 用户最终采用、拒绝或修改了什么。
|
||||
|
||||
## 2. 目标产品模型
|
||||
|
||||
### 2.1 Workspace
|
||||
|
||||
用户的本地工作边界,包含工作目录、参与 Agent、权限默认值、Provider 关系、语言/主题和本地数据策略。
|
||||
本地信任与工作边界,包含工作目录、Agent、知识来源、Provider、权限默认值和本地数据策略。
|
||||
|
||||
### 2.2 Task
|
||||
### 2.2 Knowledge Source
|
||||
|
||||
一个有目标、有上下文、有验收标准的工作单元。Task 必须能脱离聊天标题被复述,至少包含:目标、输入、限制、验收标准、风险级别和是否允许多 Agent。
|
||||
可被任务显式授权的输入来源,例如本地 Vault、文档 CLI、未来的 OAuth Connector 或用户选定文件。
|
||||
|
||||
### 2.3 Run
|
||||
每个 Knowledge Source 必须声明:
|
||||
|
||||
一次具体执行。记录 Agent、Connector 版本、Provider/模型标识、权限模式、耗时、成本区间、状态和取消原因;秘密、完整 Token 和原生 Session ID 仍只留在主进程或本地安全存储。
|
||||
- 访问方式与就绪状态。
|
||||
- 可读、可写和网络边界。
|
||||
- 数据所在位置或服务区域的可见说明。
|
||||
- 最后验证时间和已知限制。
|
||||
|
||||
### 2.4 Artifact
|
||||
### 2.3 Context Pack
|
||||
|
||||
用户真正可以采用的产物:代码变更、文档、研究结论、检查清单、结构化数据、链接或导出包。
|
||||
一次 Task 实际使用的上下文集合,而不是整个知识库的永久镜像。至少记录:
|
||||
|
||||
### 2.5 Evidence
|
||||
- 用户输入、选定文件、图片和 Skill。
|
||||
- 被授权的 Knowledge Source。
|
||||
- 目标 Agent 和可见范围。
|
||||
- 创建时间、版本和可复验引用。
|
||||
- 敏感等级与允许出站范围。
|
||||
|
||||
支持 Artifact 的证据:测试、来源、差异、日志摘要、审查发现、截图、用户输入和 Agent 声明。Evidence 需要能指出“由谁、在什么条件下、何时产生”。
|
||||
Knowledge Source 是潜在输入,Context Pack 是本次任务被批准使用的输入。两者都不等于 Evidence。
|
||||
|
||||
### 2.6 Acceptance
|
||||
### 2.4 Task
|
||||
|
||||
用户对 Artifact 的明确动作:接受、拒绝、要求修改、Apply、Commit、Export、Reopen。只有发生采用或明确拒绝,任务才有真实结果。
|
||||
一个有目标、有约束、有验收标准的工作单元。Task 至少包含:目标、背景、Context Pack、预期 Artifact、验收标准、风险级别、预算和是否允许多 Agent。
|
||||
|
||||
## 3. 优先级排序
|
||||
|
||||
### P0:公开 MVP 可用与价值闭环(现在至 6 周)
|
||||
|
||||
| 优先级 | 目标结果 | 最小交付 | 验证方式 |
|
||||
| --- | --- | --- | --- |
|
||||
| P0.1 | 新用户能在 10 分钟内完成首个真实任务 | 安装说明、首次运行引导、Agent readiness、失败修复提示、真实截图 | 5 名非开发者按文档完成安装;记录阻塞点 |
|
||||
| P0.2 | 用户能明确知道当前支持什么 | Connector/Agent 能力表、版本和平台矩阵、已知限制 | README、应用内能力标记与代码一致 |
|
||||
| P0.3 | 用户能把一次协作当作工作而非聊天 | Task 元数据最小模型、任务标题、目标、验收标准、状态 | 10 个真实任务可导出和复盘 |
|
||||
| P0.4 | 多 Agent 的价值可被比较 | 实施 + 独立审查模板、并排结果、手工 Acceptance | 完成至少 10 个配对任务,记录时间、质量和采用 |
|
||||
| P0.5 | 开源项目能被别人使用和反馈 | Issue 模板、故障排查、贡献指南、兼容报告模板 | 第一个外部 Issue 能在一轮内归类和复现 |
|
||||
| P0.6 | 产品不依赖创始人现场解释 | 2 个 3 分钟视频:安装;一次跨 Agent 任务 | 观看者能独立复现核心路径 |
|
||||
|
||||
**P0 明确不做**:Cloud Agent、团队账户、SSO、远程同步、复杂自动化市场、完整 Connector SDK、全面 Windows 发行。
|
||||
|
||||
### P1:Harness 最小基座(6-12 周)
|
||||
|
||||
| 优先级 | 目标结果 | 最小交付 | 验证方式 |
|
||||
| --- | --- | --- | --- |
|
||||
| P1.1 | 新 Agent 不需要修改核心业务逻辑即可加入 | 内部 Connector Contract、Manifest、能力枚举 | 用第二种实现验证 contract 边界 |
|
||||
| P1.2 | 结果可追溯且可复验 | Run 事件、Artifact 引用、Evidence 摘要、Acceptance 记录 | 20 个任务能回答“哪个 Agent 在什么条件下产出” |
|
||||
| P1.3 | 权限和出站更透明 | 每次 Run 的工作目录、写入模式、Provider、图片/Skill 出站提示 | 用户能在发送前做出明确选择 |
|
||||
| P1.4 | 失败不会变成静默丢失 | 取消、超时、恢复、重试、失败原因、可导出诊断包 | 注入失败并检查状态、数据和隐私 |
|
||||
| P1.5 | 社区可以贡献连接器和任务模板 | Connector 文档、示例适配器、兼容测试脚本、模板目录 | 至少 1 个外部适配或模板 PR |
|
||||
|
||||
**P1 退出条件**:至少 15 名用户完成一次真实任务,至少 8 名在 30 天内重复;否则继续做发现和稳定性,不进入 Cloud/Team 线。
|
||||
|
||||
### P2:有证据再做的扩展(3-6 个月)
|
||||
|
||||
| 目标结果 | 候选能力 | 前置证据 |
|
||||
| --- | --- | --- |
|
||||
| 本地任务可以授权给后台 Agent 继续 | Cloud Connector、handoff、回传和本地验收 | 用户明确愿意把哪些输入交给云端,并有 3 个重复场景 |
|
||||
| 工作可以发生在用户已有渠道 | GitHub Issue/PR、Slack、飞书或钉钉 Channel | 至少 5 个用户在相同渠道提出相同需求 |
|
||||
| 团队能复用安全工作方式 | 共享策略、模板、审计和预算摘要 | 3 个团队愿意为标准化试点付费 |
|
||||
| 路由更有依据 | 任务类型到 Agent 组合的推荐 | 至少 50 个有验收结果的匿名任务样本 |
|
||||
|
||||
### P3:暂不排期
|
||||
|
||||
- 自建模型或托管 Token 额度。
|
||||
- 无限制 Agent Swarm、无限轮次和无人值守写入。
|
||||
- 完整企业 IAM、复杂组织层级和跨地域多租户。
|
||||
- 先做一个新的在线社交平台或 Agent 市场。
|
||||
- 为每个热门 Agent 维护深度定制,牺牲核心 Contract。
|
||||
|
||||
## 4. Connector 设计
|
||||
|
||||
### 4.1 最小 Contract
|
||||
建议状态:
|
||||
|
||||
```text
|
||||
discover() -> readiness, version, platform
|
||||
describe() -> capabilities, limits, egress, permission modes
|
||||
start(task) -> run id, native session handle (main-only)
|
||||
resume(session) -> run events and final result
|
||||
cancel(run) -> terminal state
|
||||
collect(run) -> artifacts, evidence, cost/time metadata
|
||||
Draft -> Ready -> Running -> Needs review -> Adopted / Rejected / Blocked
|
||||
-> Reopened / Rolled back
|
||||
```
|
||||
|
||||
核心进程只接收结构化输入,不能让用户文字直接选择任意可执行文件或 Shell 命令。Connector 必须声明不支持的能力,不能用统一假设掩盖差异。
|
||||
### 2.5 Run
|
||||
|
||||
### 4.2 兼容等级
|
||||
一次具体执行,记录 Agent、Connector 版本、Provider/模型标识、原生 Session 引用、权限模式、输入快照、状态、耗时和失败原因。
|
||||
|
||||
| 等级 | 含义 |
|
||||
| --- | --- |
|
||||
| Experimental | 能启动或完成有限 Smoke,版本和平台未经稳定验证 |
|
||||
| Community | 有公开适配和基本 Contract Test,由社区维护 |
|
||||
| Tier-1 | 关键行为在目标平台有重复真实验证,失败可诊断 |
|
||||
| Certified | 有固定版本、签名发行、回归矩阵和明确支持周期 |
|
||||
### 2.6 Artifact
|
||||
|
||||
当前不能把代码中存在的 adapter 自动写成 Tier-1 或 Certified。
|
||||
用户可以继续使用的产物:文档、研究结论、方案、代码变更、清单、结构化数据、图片、链接或导出包。
|
||||
|
||||
### 2.7 Evidence
|
||||
|
||||
支持或反驳 Artifact 的证据:来源引用、文件位置、测试、命令结果、差异、截图、Reviewer Finding 和人类判断。
|
||||
|
||||
Evidence 必须区分:
|
||||
|
||||
- Declared:Agent 自称已经验证。
|
||||
- Observed:Meldwork 捕获到结果或引用。
|
||||
- Reproduced:用户或另一个 Agent 成功复验。
|
||||
- Human accepted:人类确认该证据足以支持决策。
|
||||
|
||||
### 2.8 Decision 与 Adoption
|
||||
|
||||
Acceptance 不能只是点击“接受”。需要记录:
|
||||
|
||||
- 接受、拒绝、要求修改或选择另一个方案。
|
||||
- Artifact 被 Apply、Commit、Export、发送或用于哪项后续决定。
|
||||
- 采用后的测试、复核或结果反馈。
|
||||
|
||||
只有 Artifact 被实际使用,并完成与任务验收标准匹配的复验,才计入产品北极星。
|
||||
|
||||
## 3. 首发工作协议
|
||||
|
||||
首发不按 Coding、Research 或 PM 分裂三套产品,而是实现一个可复用协议:
|
||||
|
||||
```text
|
||||
Create Task
|
||||
-> Select Context Pack
|
||||
-> Primary Agent produces Artifact
|
||||
-> Reviewer Agent checks Artifact and Evidence
|
||||
-> Human adopts, rejects or requests revision
|
||||
```
|
||||
|
||||
可以用三类模板验证,但首轮只能选择一个作为主样本:
|
||||
|
||||
1. 研究与决策核验:基于文档来源形成结论,再由另一个 Agent 检查证据和遗漏。
|
||||
2. 方案与交付物评审:主 Agent 生成 PRD、方案、报告或演示结构,Reviewer 检查约束、冲突和可执行性。
|
||||
3. 代码与技术审查:实施 Agent 产出变更,Reviewer 检查缺陷、测试和风险。
|
||||
|
||||
这三类任务共享相同对象和指标。产品不为每个领域建立独立聊天模式。
|
||||
|
||||
## 4. Outcome Roadmap
|
||||
|
||||
### Phase 0:可信激活,0-4 周
|
||||
|
||||
**目标结果:** 新用户能理解边界,并在 10 分钟内用一个 Agent 完成第一项真实工作。
|
||||
|
||||
最小交付:
|
||||
|
||||
- Agent 与 Knowledge Source readiness 的清晰状态和修复提示。
|
||||
- 当前支持矩阵、访问边界和最后验证日期。
|
||||
- 首次任务引导,不要求用户先创建群组。
|
||||
- 一个 Agent + 可选知识来源的真实任务演示。
|
||||
- 安装、失败诊断和数据出站说明。
|
||||
|
||||
验证:
|
||||
|
||||
- 5 名新用户不依赖现场解释完成安装和首个任务。
|
||||
- 首次任务失败能归因到安装、登录、权限、Connector 或任务输入。
|
||||
- README、应用状态和代码能力一致。
|
||||
|
||||
### Phase 1:Context Pack + Task Outcome,4-10 周
|
||||
|
||||
**目标结果:** 用户能把一次 Agent 工作变成可复盘、可采用的结果,而不是一段聊天记录。
|
||||
|
||||
最小交付:
|
||||
|
||||
- Task、Context Pack、Run、Artifact、Evidence、Decision 的本地最小模型。
|
||||
- 一个 Primary + Reviewer 工作协议。
|
||||
- Reviewer 默认只看到 Artifact、验收标准和声明过的 Evidence,不默认读取 Primary 的完整对话。
|
||||
- Artifact 导出、接受、拒绝、要求修改和 Reopen。
|
||||
- 来源和 Evidence 的人工校正入口。
|
||||
|
||||
验证:
|
||||
|
||||
- 至少 20 个任务能回答“用了什么上下文、谁产生了什么、为什么采用”。
|
||||
- 80% 的测试用户不需要手工整理聊天内容就能导出或采用 Artifact。
|
||||
- 任何 Verified 状态都能追溯到具体 Evidence。
|
||||
|
||||
### Phase 2:Connector Contract + Evidence Graph,10-16 周
|
||||
|
||||
**目标结果:** 新 Agent 和知识来源可以通过稳定能力协议加入,且结果关系能够被搜索和复验。
|
||||
|
||||
最小交付:
|
||||
|
||||
- Agent Connector Manifest:能力、Session、权限、事件、成本和出站声明。
|
||||
- Knowledge Connector Manifest:访问方式、范围、引用、快照能力和限制。
|
||||
- 统一 Run Event:Started、Progress、Permission、SourceUsed、Artifact、Evidence、Usage、Completed/Failed/Cancelled。
|
||||
- Artifact、Evidence、Source 和 Decision 的关系图。
|
||||
- 可导出的 Evidence Bundle 和诊断包。
|
||||
|
||||
验证:
|
||||
|
||||
- 用第二种实现验证 Contract 边界,而不是继续硬编码核心业务。
|
||||
- 至少一个外部 Connector 或 Task Template 贡献。
|
||||
- Connector 失败不会造成静默丢失或错误的“已完成”。
|
||||
|
||||
### Phase 3:Local / Cloud Handoff 与一个 Channel,4-8 个月,条件阶段
|
||||
|
||||
**进入条件:** 15 名固定用户中至少 8 名在 30 天内重复使用,并有 3 个以上重复的后台执行或外部渠道需求。
|
||||
|
||||
候选能力:
|
||||
|
||||
- 本地 Context Pack 的出站预览与用户批准。
|
||||
- 一个 Cloud Agent 的创建、取消、状态和 Artifact 回传。
|
||||
- 优先接一个任务型 Channel。开发者样本优先 GitHub Issue/PR;知识工作样本优先钉钉或飞书。
|
||||
- Channel 只承载 Task、待验收结果和有效上下文,不复制完整 IM。
|
||||
|
||||
### Phase 4:Typed Workflow、预算和停止条件,8-12 个月,条件阶段
|
||||
|
||||
**进入条件:** 同一工作协议被至少 5 名用户重复执行,且手工步骤稳定。
|
||||
|
||||
候选能力:
|
||||
|
||||
- 有类型的输入、输出和 Evidence 要求。
|
||||
- Reviewer、重试、停止条件和 Human Gate。
|
||||
- Task、Workspace 和 Channel 预算。
|
||||
- Observed / Estimated / Unavailable 三态成本。
|
||||
- Workflow 版本、运行历史和失败恢复。
|
||||
|
||||
### Phase 5:Team 与企业治理,12 个月后,条件阶段
|
||||
|
||||
**进入条件:** 至少 3 个团队对同一标准化能力实际付费,且不是定制 Connector 或咨询收入。
|
||||
|
||||
候选能力:
|
||||
|
||||
- 可选加密同步与纯本地模式并存。
|
||||
- 共享模板、策略、RBAC、审计和预算。
|
||||
- SSO/SCIM、签名 Connector Registry、离线更新和兼容 SLA。
|
||||
|
||||
## 5. UI / UX 方向
|
||||
|
||||
### 5.1 从“聊天列表”转为“工作状态”
|
||||
### 5.1 导航从聊天转向工作状态
|
||||
|
||||
左侧导航应优先显示:进行中、待验收、已完成、失败/待重试的 Task;Conversation 作为 Task 内的一个视图,而不是唯一的信息架构。
|
||||
左侧导航优先级:
|
||||
|
||||
1. Inbox:需要授权、补充输入或验收的事项。
|
||||
2. Active Tasks:进行中、待复核、失败和待重试。
|
||||
3. Workspaces / Channels:持续主题和工作边界。
|
||||
4. Conversations:Task 内的交互记录。
|
||||
5. Agents / Knowledge Sources:连接与能力状态。
|
||||
|
||||
### 5.2 Task 工作台
|
||||
|
||||
首屏回答四个问题:
|
||||
首屏必须回答:
|
||||
|
||||
1. 目标是什么?
|
||||
2. 哪些 Agent 已经运行?
|
||||
3. 产出了什么 Artifact 和 Evidence?
|
||||
4. 下一步是接受、修改、导出还是重试?
|
||||
- 目标和验收标准是什么。
|
||||
- 哪些 Context 被允许使用。
|
||||
- 哪些 Run 已完成或失败。
|
||||
- 当前 Artifact 和 Evidence 是什么。
|
||||
- 用户下一步需要采用、修改、授权还是重试。
|
||||
|
||||
### 5.3 多 Agent 的默认行为
|
||||
完整聊天流水作为辅助视图,不应占据默认主界面。
|
||||
|
||||
默认单 Agent;当用户选择“独立审查”或任务风险达到阈值时,再建议第二个 Agent。自动讨论必须有轮次、时间、成本和停止条件,不能用“越多越聪明”作为产品逻辑。
|
||||
### 5.3 多 Agent 对照
|
||||
|
||||
### 5.4 状态与错误
|
||||
- 使用相同 Context Pack 的独立 Attempt。
|
||||
- Artifact 差异、证据覆盖和冲突高亮。
|
||||
- 时间、成本和失败状态明确显示。
|
||||
- 不用 Agent 卡片墙代替可比较的信息结构。
|
||||
|
||||
失败、取消、超时和部分完成必须是一级状态。错误信息要告诉用户:影响了哪个 Agent、哪些数据已经保存、是否可以重试、是否需要重新确认权限。
|
||||
### 5.4 通知
|
||||
|
||||
## 6. 安全、可靠性与发布门槛
|
||||
只通知需要人类行动的事件:权限请求、缺少输入、结果待验收、预算风险、Run 失败和 Connector 退化。
|
||||
|
||||
### P0 发布门槛
|
||||
## 6. 指标体系
|
||||
|
||||
- Renderer 不能获取任意 Shell、可执行路径、密钥或原生 Session ID。
|
||||
- Provider key 仍通过操作系统安全存储,不添加明文回退。
|
||||
- Agent 写入默认受用户选择控制,明确声明不是 OS 级沙箱。
|
||||
- 图片、Skill、Installer 和 Provider 的出站边界在 UI 与文档中一致。
|
||||
- 所有新增状态都有单元测试和失败路径。
|
||||
### 6.1 北极星
|
||||
|
||||
### P1 发布门槛
|
||||
**每周被用户实际采用并完成验证的任务产出数。**
|
||||
|
||||
- 关键 Connector 行为有真实矩阵,而不是只靠 Mock。
|
||||
- Installer 包和脚本实现摘要或签名固定后再扩大分发。
|
||||
- macOS 签名、公证和 clean-machine 安装完成后再承诺公开安装体验。
|
||||
- Windows 只有在真机验证后才进入宣传口径。
|
||||
同时披露:创建 Task 数、Adopted Task 数、失败激活用户数和每个安装 cohort 的人均值。不得只统计多 Agent Task,以免诱导不必要的 Agent 数量增长。
|
||||
|
||||
## 7. 开源与内容不是附属工作
|
||||
### 6.2 当前 OMTM
|
||||
|
||||
对于 OPC,用户获取和技术迭代是同一条产品链:
|
||||
**固定首批用户的 30 天重复 Outcome 率。**
|
||||
|
||||
| 内容动作 | 产品反馈 |
|
||||
| --- | --- |
|
||||
| 发布“两个 Agent 独立审查一个真实任务”视频 | 观察用户最关心的质量、成本或隐私问题 |
|
||||
| 发布兼容性报告 | 找到最值得维护的 Connector |
|
||||
| 发布失败复盘 | 优先修复影响激活的错误 |
|
||||
| 发布 Task 模板 | 发现可标准化的工作流 |
|
||||
| 发布用户案例 | 判断哪些场景值得进入 Harness 产品 |
|
||||
第 6 周前固定最先完成真实 Task 的 15 名用户,要求至少 8 名在各自首次任务后的 30 天内再次完成一个有 Artifact、Evidence 和 Decision 的 Task。
|
||||
|
||||
每周只需要一个可复用主题:一次真实任务、一个失败、一个兼容更新或一个用户问题。不要同时经营十个平台和十种内容格式。
|
||||
### 6.3 价值指标
|
||||
|
||||
## 8. 指标体系
|
||||
- 首次 Task 完成率和完成时间。
|
||||
- Context Pack 被实际使用和校正的比例。
|
||||
- Artifact 被采用、导出或继续使用的比例。
|
||||
- Reviewer 新增有效 Finding 的采用率和误报率。
|
||||
- 相对手工跨 Agent 的上下文搬运与协调时间。
|
||||
- 单 Agent 与多 Agent 的质量、等待和成本差异。
|
||||
|
||||
### 8.1 北极星
|
||||
### 6.4 可靠性指标
|
||||
|
||||
每周完成至少一个“跨 Agent 可复核工作闭环”的活跃 Workspace 数量。
|
||||
- Agent Session resume 成功率。
|
||||
- Knowledge Source readiness 和读取成功率。
|
||||
- Run 取消、失败恢复和 Artifact 捕获完整率。
|
||||
- Connector 版本退化率。
|
||||
- 权限越界、错误写入和数据丢失事件。
|
||||
|
||||
### 8.2 阶段指标
|
||||
## 7. 明确不做
|
||||
|
||||
| 阶段 | OMTM | 辅助指标 |
|
||||
近期不应优先:
|
||||
|
||||
- 用更多 Agent Logo 作为版本卖点。
|
||||
- 通用消费者聊天或社交产品。
|
||||
- 自建模型、Token Marketplace 或默认 Token 加价。
|
||||
- 自动抓取并索引用户所有知识库。
|
||||
- 无限制 Swarm、无限轮次和无人值守写入。
|
||||
- 在 Outcome 闭环成熟前建设 Cron、Webhook 和复杂自动化市场。
|
||||
- 同时开发多个 Cloud Agent、多个 IM Channel 和完整 Team 平台。
|
||||
- 把 General Agent 理解为“没有边界、什么都能做”。
|
||||
|
||||
## 8. 决策门
|
||||
|
||||
| 时间 | 必须回答的问题 | 决策 |
|
||||
| --- | --- | --- |
|
||||
| 公开 MVP | 首次任务完成率 | 安装成功、首个 Agent 就绪、失败自助解决 |
|
||||
| 价值验证 | 30 天重复任务率 | Accepted Artifact、复验 Evidence、协调时间 |
|
||||
| 生态验证 | 外部有效贡献数 | Connector PR、模板 PR、Issue 复现率 |
|
||||
| 商业探索 | 标准化试点回款 | 支持工时、重复需求、试点续费意愿 |
|
||||
| 第 4 周 | 新用户是否能独立完成首个真实任务? | 否则先修激活,不增加平台范围 |
|
||||
| 第 10 周 | Task、Context Pack 和 Outcome 是否减少手工整理并提高采用? | 否则简化对象和首发协议 |
|
||||
| 第 12-16 周 | 15 名固定用户中是否至少 8 名重复,是否出现外部贡献? | 成立才投入 Cloud/Channel |
|
||||
| 第 6-8 个月 | Cloud 或 Channel 是否被真实重复使用并愿意付费? | 只扩展被证明的入口 |
|
||||
| 第 12 个月后 | 是否有 3 个团队为同一标准化能力回款? | 成立才进入 Team/Enterprise |
|
||||
|
||||
不把 Star、曝光、自动讨论轮数和 Agent 数量当作核心产品价值指标。
|
||||
## 9. 最终判断
|
||||
|
||||
## 9. OPC 执行系统
|
||||
Meldwork 的迭代顺序应该是:
|
||||
|
||||
### 9.1 每周时间分配建议
|
||||
1. 从 Agent 会话升级到可采用的 Task Outcome。
|
||||
2. 从临时提示升级到可授权、可复验的 Context Pack。
|
||||
3. 从硬编码适配升级到 Agent 与 Knowledge Connector Contract。
|
||||
4. 从本地工作台扩展到经用户授权的 Cloud 和 Channel。
|
||||
5. 最后才把重复工作方式产品化为 Workflow 与 Team Governance。
|
||||
|
||||
以每周 10-12 小时可投入时间为基准:
|
||||
|
||||
| 工作 | 比例 | 说明 |
|
||||
| --- | ---: | --- |
|
||||
| 用户价值与产品工程 | 45% | 只做当前阶段一个主场景 |
|
||||
| 兼容性与质量 | 20% | 先维护 Tier-1,不追求适配数量 |
|
||||
| 文档、视频和发布 | 20% | 每周一个可复用内容单元 |
|
||||
| 用户反馈与社区 | 10% | 访谈、Issue、PR、复盘 |
|
||||
| 预留 | 5% | 处理上游变化和不可预见问题 |
|
||||
|
||||
如果现实只能投入 5 小时,本周只做 1 个用户价值事项 + 1 个公开文档/视频事项;不新增 Connector。
|
||||
|
||||
### 9.2 单人节奏
|
||||
|
||||
- 周一:从 Issue、反馈和真实任务中选一个结果目标。
|
||||
- 周中:完成最小实现或实验,并记录证据。
|
||||
- 周末:写一篇短更新或录一个短视频,邀请用户复现。
|
||||
- 每四周:删掉没有用户信号的待办,重新冻结下一周期。
|
||||
|
||||
### 9.3 停止条件
|
||||
|
||||
以下情况出现时,立即缩小范围:
|
||||
|
||||
- 连续四周没有用户完成第二次任务。
|
||||
- 维护 Connector 的时间高于用户价值工作的两倍。
|
||||
- 内容有曝光但没有安装、Issue 或复现任务。
|
||||
- 用户只要求定制开发,不愿使用标准化流程。
|
||||
|
||||
## 10. 里程碑与决策门
|
||||
|
||||
### M1:可公开使用
|
||||
|
||||
文档可独立完成安装,核心路径可以演示,能力边界真实,关键安全测试通过。
|
||||
|
||||
### M2:有重复价值
|
||||
|
||||
至少 15 名外部用户完成真实任务,其中同一批至少 8 名在 30 天内重复;至少 20 个任务有明确 Acceptance 结果。
|
||||
|
||||
### M3:有生态迹象
|
||||
|
||||
至少 1 个外部 Connector 或任务模板贡献,Issue 能被复现和合并,用户开始主动提出兼容性与工作流需求。
|
||||
|
||||
### M4:决定是否商业化
|
||||
|
||||
出现 3 个以上相似团队问题,并有实际回款或明确的标准化试点需求,才进入 Harness 商业化实验。
|
||||
|
||||
## 11. 最终路线判断
|
||||
|
||||
先把 Meldwork 做成“别人能安装、能完成任务、能复现、能贡献”的开源项目;再把稳定的重复问题抽象成 Harness 能力;最后才考虑 Cloud、Channel、Team 和 Enterprise。
|
||||
|
||||
顺序不能反过来。否则一个 OPC 会在还没有用户证据时,提前承担平台、云、销售和支持的全部成本。
|
||||
第一和第二步没有完成时,Cloud、Channel、Workflow 和企业功能只会放大当前聊天产品的复杂度。
|
||||
+2
-1
@@ -30,6 +30,7 @@ The packaged smoke exercises the first-run UI, group creation, Skill IPC, and cl
|
||||
| Renderer workbench and onboarding | Shows the configured Agent catalog, gates the first-run carousel on Agent detection, supports focus/scroll/back dismissal, local groups/direct chats, theme, and locale | `frontend/src/__tests__/roundrelay/App.spec.js` | Passed locally |
|
||||
| Conversation run UX and session management | Shows Agent logos and capabilities, multiple direct sessions, rename/delete controls, distinct running animation, per-Agent queued/running/completed state, automatic current/max round progress, active-topic expansion, exact warning dismissal, collapsed process details, background direct completion markers, unavailable-Agent history access, and truthful permission/image limits | `frontend/src/__tests__/roundrelay/App.spec.js`; `desktop/test/main-security.test.cjs` | Passed locally |
|
||||
| Composer Skill routing | Loads Skills only for selected targets, supports `@` selection, and sends structured target-scoped coordinates | `frontend/src/__tests__/roundrelay/App.spec.js`; `desktop/test/local-skill-catalog.test.cjs`; `desktop/test/agent-installer.test.cjs`; `desktop/test/local-workspace.test.cjs` | Passed locally |
|
||||
| Knowledge-source routing | Separates ready/planned sources, probes Feishu/DingTalk/Obsidian state, requires readable access, scopes selections to target Agents, persists only the selected Vault path, and rejects stale or unauthorized hints | `frontend/src/__tests__/roundrelay/App.spec.js`; `desktop/test/local-knowledge-base.test.cjs`; `desktop/test/knowledge-base-store.test.cjs`; `desktop/test/local-workspace.test.cjs`; `desktop/test/main-security.test.cjs` | Passed locally |
|
||||
| Image attachment UI | Imports picker/paste images, permits image-only messages, blocks send and concurrent paste batches during import, keeps accepted all-failed messages out of the composer, discards unsent/overflow/stale imports, and sends metadata without paths or preview data | `frontend/src/__tests__/roundrelay/App.spec.js` | Passed locally |
|
||||
| Attachment preview cache | Loads visible previews only, limits concurrent main-process requests to two, and evicts non-visible least-recent entries from the bounded cache | `frontend/src/__tests__/roundrelay/attachmentPreviews.spec.js` | Passed locally |
|
||||
| Renderer bridge normalization | Uses only `window.roundrelayDesktop` services and normalizes missing data | `frontend/src/__tests__/roundrelay/desktop.spec.js` | Passed locally |
|
||||
@@ -37,7 +38,7 @@ The packaged smoke exercises the first-run UI, group creation, Skill IPC, and cl
|
||||
| Renderer CSP and assets | Entry point keeps self-only/default restrictions, denies unsafe surfaces, and uses relative packaged assets | `frontend/src/__tests__/roundrelay/security.spec.js` | Passed locally |
|
||||
| Main-frame IPC authorization | All registered local channels accept only the exact frontend main frame; other frames/paths are denied before dispatch | `desktop/test/main-security.test.cjs` | Passed locally |
|
||||
| Electron navigation, lifecycle, and shutdown gate | Loads bundled frontend, denies in-window remote navigation, serializes refresh, rejects every trusted IPC call after shutdown starts, then waits for workspace/installer cleanup before quitting | `desktop/test/main-security.test.cjs` | Passed locally |
|
||||
| Narrow preload API | Local document gets only named workspace/installer/Skill/attachment/Provider methods; attachment APIs expose no file read or path resolution; non-local documents get no privileged API | `desktop/test/preload-security.test.cjs` | Passed locally |
|
||||
| Narrow preload API | Local document gets only named workspace/installer/Skill/attachment/Provider/knowledge-source methods; attachment APIs expose no file read or path resolution; non-local documents get no privileged API | `desktop/test/preload-security.test.cjs` | Passed locally |
|
||||
| Packaged Electron hardening | Fuses disable Node/runtime injection and require ASAR integrity | `desktop/test/package-security.test.cjs` | Passed locally |
|
||||
| Provider secret storage | Complete payload required; URL constrained; key encrypted; failures/corruption fail closed; delete works | `desktop/test/provider-store.test.cjs` | Passed locally |
|
||||
| Agent readiness | Detects native credentials without returning values and scopes forwarded credential variables by Agent | `desktop/test/local-agent-readiness.test.cjs` | Passed locally |
|
||||
|
||||
@@ -11,6 +11,8 @@ Meldwork requires no `.env` file, server URL, account token, JWT, database crede
|
||||
| Provider `baseUrl` | Compatible local Agents | User input in renderer, validated by main | Stored locally; replace through UI | HTTPS required, except loopback HTTP; embedded credentials/query/fragment rejected |
|
||||
| Provider `model` | Compatible local Agents | User input in renderer, validated by main | Stored locally; replace through UI | Non-secret model identifier |
|
||||
| Provider `apiKey` | Compatible local Agents | User enters it in renderer; passed once over local IPC | Encrypted with `safeStorage`; rotate by saving a replacement or delete through UI | Secret; status and snapshots never return it |
|
||||
| Obsidian Vault path | Knowledge-source selection | User chooses a directory through the main-owned OS picker | Stored in `roundrelay-knowledge-base.json`; replace or clear through UI | Non-secret local path, but may reveal directory naming; only selected Agents receive it as task context |
|
||||
| Feishu / DingTalk CLI auth | Knowledge-source selection | Owned by the installed `lark-cli`/`opdev` or `dws` CLI | Managed and rotated through the upstream CLI | Meldwork probes status and document access but does not receive or store the upstream token |
|
||||
| Theme / locale | Renderer | User preference | Browser `localStorage` | Non-secret |
|
||||
|
||||
## Native Agent Credential Inputs
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 906 KiB |
@@ -1,31 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 540" role="img">
|
||||
<defs>
|
||||
<linearGradient id="paper" x1="0" x2="1" y1="0" y2="1">
|
||||
<stop offset="0" stop-color="#fffdfa"/>
|
||||
<stop offset="1" stop-color="#f0e9df"/>
|
||||
</linearGradient>
|
||||
<filter id="softShadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="18" stdDeviation="22" flood-color="#483626" flood-opacity=".13"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<rect width="960" height="540" fill="#f6f3ed"/>
|
||||
<circle cx="790" cy="104" r="74" fill="#f4e1d5"/>
|
||||
<circle cx="140" cy="438" r="96" fill="#eee6dc"/>
|
||||
<g filter="url(#softShadow)">
|
||||
<rect x="170" y="92" width="620" height="356" rx="34" fill="url(#paper)" stroke="#d8d1c7"/>
|
||||
</g>
|
||||
<path d="M310 178 C386 118 530 118 628 178" fill="none" stroke="#d8d1c7" stroke-width="10" stroke-linecap="round"/>
|
||||
<path d="M650 206 C714 274 672 364 578 394" fill="none" stroke="#d8d1c7" stroke-width="10" stroke-linecap="round"/>
|
||||
<path d="M382 394 C282 358 248 270 308 204" fill="none" stroke="#d8d1c7" stroke-width="10" stroke-linecap="round"/>
|
||||
<circle cx="480" cy="150" r="42" fill="#5968e8"/>
|
||||
<circle cx="662" cy="300" r="42" fill="#347a66"/>
|
||||
<circle cx="298" cy="300" r="42" fill="#c65d28"/>
|
||||
<path d="M454 151 h52" stroke="#fffaf6" stroke-width="10" stroke-linecap="round"/>
|
||||
<path d="M642 300 h40 M662 280 v40" stroke="#fffaf6" stroke-width="10" stroke-linecap="round"/>
|
||||
<path d="M278 290 l18 18 30 -36" fill="none" stroke="#fffaf6" stroke-width="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<rect x="384" y="246" width="192" height="88" rx="24" fill="#ffffff" stroke="#d8d1c7"/>
|
||||
<rect x="420" y="274" width="118" height="10" rx="5" fill="#282522"/>
|
||||
<rect x="420" y="302" width="72" height="8" rx="4" fill="#a39b91"/>
|
||||
<circle cx="548" cy="306" r="8" fill="#c65d28"/>
|
||||
<circle cx="574" cy="306" r="8" fill="#f0883e"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 907 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
@@ -1,40 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 540" role="img">
|
||||
<defs>
|
||||
<linearGradient id="surface" x1="0" x2="1" y1="0" y2="1">
|
||||
<stop offset="0" stop-color="#fffaf4"/>
|
||||
<stop offset="1" stop-color="#eee6dc"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="accent" x1="0" x2="1" y1="0" y2="1">
|
||||
<stop offset="0" stop-color="#f0883e"/>
|
||||
<stop offset="1" stop-color="#c65d28"/>
|
||||
</linearGradient>
|
||||
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="18" stdDeviation="22" flood-color="#483626" flood-opacity=".14"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<rect width="960" height="540" fill="#f6f3ed"/>
|
||||
<path d="M0 430 C170 372 260 504 424 438 C592 370 714 326 960 390 L960 540 L0 540 Z" fill="#efe6dc"/>
|
||||
<g filter="url(#shadow)">
|
||||
<rect x="118" y="76" width="724" height="388" rx="28" fill="url(#surface)"/>
|
||||
<rect x="118.5" y="76.5" width="723" height="387" rx="27.5" fill="none" stroke="#d8d1c7"/>
|
||||
</g>
|
||||
<rect x="154" y="118" width="186" height="304" rx="22" fill="#ffffff" stroke="#d8d1c7"/>
|
||||
<circle cx="204" cy="174" r="24" fill="#347a66"/>
|
||||
<circle cx="204" cy="246" r="24" fill="#946128"/>
|
||||
<circle cx="204" cy="318" r="24" fill="#25758a"/>
|
||||
<rect x="242" y="160" width="64" height="10" rx="5" fill="#282522"/>
|
||||
<rect x="242" y="180" width="52" height="8" rx="4" fill="#a39b91"/>
|
||||
<rect x="242" y="232" width="82" height="10" rx="5" fill="#282522"/>
|
||||
<rect x="242" y="252" width="48" height="8" rx="4" fill="#a39b91"/>
|
||||
<rect x="242" y="304" width="92" height="10" rx="5" fill="#282522"/>
|
||||
<rect x="242" y="324" width="62" height="8" rx="4" fill="#a39b91"/>
|
||||
<rect x="388" y="118" width="418" height="304" rx="22" fill="#ffffff" stroke="#d8d1c7"/>
|
||||
<rect x="430" y="156" width="160" height="12" rx="6" fill="#282522"/>
|
||||
<rect x="430" y="184" width="292" height="10" rx="5" fill="#a39b91"/>
|
||||
<rect x="430" y="234" width="326" height="48" rx="14" fill="#fbfaf7" stroke="#d8d1c7"/>
|
||||
<rect x="452" y="252" width="102" height="10" rx="5" fill="#77716a"/>
|
||||
<rect x="430" y="302" width="326" height="48" rx="14" fill="#fbfaf7" stroke="#d8d1c7"/>
|
||||
<rect x="452" y="320" width="178" height="10" rx="5" fill="#77716a"/>
|
||||
<rect x="430" y="370" width="142" height="30" rx="15" fill="url(#accent)"/>
|
||||
<path d="M668 146 l26 26 54 -58" fill="none" stroke="#347a66" stroke-width="14" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.4 KiB |
+117
-71
@@ -3,6 +3,7 @@
|
||||
class="app-shell"
|
||||
:class="{ 'sidebar-collapsed': sidebarCollapsed, 'trace-panel-open': tracePanelOpen }"
|
||||
:data-theme="theme"
|
||||
:data-platform="desktopPlatform"
|
||||
>
|
||||
<section v-if="booting" class="boot-state" aria-live="polite">
|
||||
<img class="boot-logo" :src="productAppIcon" alt="Meldwork" />
|
||||
@@ -1456,38 +1457,47 @@
|
||||
:aria-label="t('composer.mentions')"
|
||||
>
|
||||
<template v-if="composerMenuOptions.length">
|
||||
<button
|
||||
v-for="(option, index) in composerMenuOptions"
|
||||
:key="composerMenuOptionKey(option)"
|
||||
:id="`composer-mention-option-${index}`"
|
||||
class="skill-option"
|
||||
:class="{
|
||||
active: skillActiveIndex === index,
|
||||
'agent-mention-option': option.type === 'agent',
|
||||
'knowledge-base-mention-option': option.type === 'knowledge-base',
|
||||
}"
|
||||
type="button"
|
||||
role="option"
|
||||
:aria-selected="skillActiveIndex === index"
|
||||
:disabled="composerMenuOptionDisabled(option)"
|
||||
@mouseenter="skillActiveIndex = index"
|
||||
@click="selectComposerMenuOption(option)"
|
||||
<div
|
||||
v-for="group in composerMenuGroups"
|
||||
:key="group.type"
|
||||
class="mention-menu-section"
|
||||
role="group"
|
||||
:aria-label="group.label"
|
||||
>
|
||||
<img
|
||||
v-if="option.type !== 'skill'"
|
||||
:src="composerMenuOptionLogo(option)"
|
||||
alt=""
|
||||
/>
|
||||
<LibraryOutline v-else class="mention-option-icon" />
|
||||
<span class="skill-option-copy">
|
||||
<strong>{{ composerMenuOptionTitle(option) }}</strong>
|
||||
<small>{{ composerMenuOptionDescription(option) }}</small>
|
||||
</span>
|
||||
<span class="mention-option-action" aria-hidden="true">
|
||||
<small>{{ composerMenuOptionKindLabel(option) }}</small>
|
||||
<AddOutline />
|
||||
</span>
|
||||
</button>
|
||||
<span class="mention-menu-section-label">{{ group.label }}</span>
|
||||
<button
|
||||
v-for="option in group.options"
|
||||
:key="composerMenuOptionKey(option)"
|
||||
:id="`composer-mention-option-${composerMenuOptionIndex(option)}`"
|
||||
class="skill-option"
|
||||
:class="{
|
||||
active: skillActiveIndex === composerMenuOptionIndex(option),
|
||||
'agent-mention-option': option.type === 'agent',
|
||||
'knowledge-base-mention-option': option.type === 'knowledge-base',
|
||||
}"
|
||||
type="button"
|
||||
role="option"
|
||||
:aria-selected="skillActiveIndex === composerMenuOptionIndex(option)"
|
||||
:disabled="composerMenuOptionDisabled(option)"
|
||||
@mouseenter="skillActiveIndex = composerMenuOptionIndex(option)"
|
||||
@click="selectComposerMenuOption(option)"
|
||||
>
|
||||
<img
|
||||
v-if="option.type !== 'skill'"
|
||||
:src="composerMenuOptionLogo(option)"
|
||||
alt=""
|
||||
/>
|
||||
<LibraryOutline v-else class="mention-option-icon" />
|
||||
<span class="skill-option-copy">
|
||||
<strong>{{ composerMenuOptionTitle(option) }}</strong>
|
||||
<small>{{ composerMenuOptionDescription(option) }}</small>
|
||||
</span>
|
||||
<span class="mention-option-action" aria-hidden="true">
|
||||
<small>{{ composerMenuOptionKindLabel(option) }}</small>
|
||||
<AddOutline />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<p v-if="skillsLoading" class="skill-menu-state compact">{{ t('composer.skillsLoading') }}</p>
|
||||
<p v-else-if="!composerMenuOptions.length" class="skill-menu-state">
|
||||
@@ -1652,6 +1662,42 @@
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="selectedSkills.length || selectedKnowledgeBases.length"
|
||||
class="selected-agent-list selected-context-list"
|
||||
:aria-label="t('composer.mentions')"
|
||||
>
|
||||
<span v-for="skill in selectedSkills" :key="skillKey(skill)" class="selected-agent-tag selected-skill">
|
||||
<LibraryOutline class="selected-context-icon" aria-hidden="true" />
|
||||
@{{ skill.name || skill.slug }}
|
||||
<button
|
||||
type="button"
|
||||
:title="t('composer.removeSkill')"
|
||||
:aria-label="t('composer.removeSkill')"
|
||||
:disabled="Boolean(activeRun) || sending"
|
||||
@click="removeSkill(skill)"
|
||||
>
|
||||
<CloseOutline />
|
||||
</button>
|
||||
</span>
|
||||
<span
|
||||
v-for="source in selectedKnowledgeBases"
|
||||
:key="`knowledge:${source.kind}`"
|
||||
class="selected-agent-tag selected-skill selected-knowledge-base"
|
||||
>
|
||||
<img :src="knowledgeBaseLogo(source.kind)" alt="" />
|
||||
@{{ knowledgeBaseName(source.kind) }}
|
||||
<button
|
||||
type="button"
|
||||
:title="t('composer.removeKnowledgeBase')"
|
||||
:aria-label="t('composer.removeKnowledgeBase')"
|
||||
:disabled="Boolean(activeRun) || sending"
|
||||
@click="removeKnowledgeBase(source.kind)"
|
||||
>
|
||||
<CloseOutline />
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<textarea
|
||||
ref="composerInput"
|
||||
v-model="draft"
|
||||
@@ -1691,37 +1737,6 @@
|
||||
>
|
||||
<AtOutline />
|
||||
</button>
|
||||
<div v-if="selectedSkills.length || selectedKnowledgeBases.length" class="selected-skill-list">
|
||||
<span v-for="skill in selectedSkills" :key="skillKey(skill)" class="selected-skill">
|
||||
@{{ skill.name || skill.slug }}
|
||||
<button
|
||||
type="button"
|
||||
:title="t('composer.removeSkill')"
|
||||
:aria-label="t('composer.removeSkill')"
|
||||
:disabled="Boolean(activeRun) || sending"
|
||||
@click="removeSkill(skill)"
|
||||
>
|
||||
<CloseOutline />
|
||||
</button>
|
||||
</span>
|
||||
<span
|
||||
v-for="source in selectedKnowledgeBases"
|
||||
:key="`knowledge:${source.kind}`"
|
||||
class="selected-skill selected-knowledge-base"
|
||||
>
|
||||
<img :src="knowledgeBaseLogo(source.kind)" alt="" />
|
||||
@{{ knowledgeBaseName(source.kind) }}
|
||||
<button
|
||||
type="button"
|
||||
:title="t('composer.removeKnowledgeBase')"
|
||||
:aria-label="t('composer.removeKnowledgeBase')"
|
||||
:disabled="Boolean(activeRun) || sending"
|
||||
@click="removeKnowledgeBase(source.kind)"
|
||||
>
|
||||
<CloseOutline />
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="composer-run-actions">
|
||||
@@ -1791,13 +1806,15 @@
|
||||
</transition>
|
||||
<footer class="onboarding-footer">
|
||||
<div class="onboarding-dots" :aria-label="t('onboarding.progress')">
|
||||
<span
|
||||
<button
|
||||
v-for="(_slide, index) in onboardingSlides"
|
||||
:key="index"
|
||||
type="button"
|
||||
class="onboarding-dot"
|
||||
:class="{ active: onboardingIndex === index }"
|
||||
:aria-label="t('onboarding.goToSlide', { count: index + 1 })"
|
||||
:aria-current="onboardingIndex === index ? 'step' : undefined"
|
||||
@click="selectOnboardingSlide(index)"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
@@ -2153,7 +2170,7 @@ const COMPOSER_INPUT_MIN_HEIGHT = 58
|
||||
const COMPOSER_INPUT_MAX_HEIGHT = 180
|
||||
const DIRECT_SESSION_PREVIEW_LIMIT = 5
|
||||
const GROUP_SESSION_PREVIEW_LIMIT = 8
|
||||
const ONBOARDING_SLIDE_MS = 1450
|
||||
const ONBOARDING_SLIDE_MS = 5000
|
||||
const EMPTY_SHOWCASE_COUNT = 3
|
||||
const EMPTY_SHOWCASE_SLIDE_MS = 2800
|
||||
const DISMISSIBLE_PLAN_WARNING = 'error: Cannot combine --prompt with --plan.'
|
||||
@@ -2293,6 +2310,7 @@ let pendingRequestedGroupId = ''
|
||||
const pendingRunFinishedEvents = new Map()
|
||||
|
||||
const api = computed(() => desktopApi())
|
||||
const desktopPlatform = computed(() => api.value?.platform || installCatalog.value.platform || '')
|
||||
const workspace = computed(() => api.value?.localWorkspace || null)
|
||||
const installer = computed(() => api.value?.agentInstaller || null)
|
||||
const provider = computed(() => api.value?.localAgentProvider || null)
|
||||
@@ -2331,7 +2349,7 @@ const onboardingSlides = computed(() => [
|
||||
body: t('onboarding.discoverBody'),
|
||||
},
|
||||
{
|
||||
image: publicAsset('onboarding/provider-setup.svg'),
|
||||
image: publicAsset('onboarding/provider-setup-v2.png'),
|
||||
title: t('onboarding.providerTitle'),
|
||||
body: t('onboarding.providerBody'),
|
||||
},
|
||||
@@ -2346,7 +2364,7 @@ const onboardingSlides = computed(() => [
|
||||
body: t('onboarding.toolsBody'),
|
||||
},
|
||||
{
|
||||
image: publicAsset('onboarding/auto-discussion.svg'),
|
||||
image: publicAsset('onboarding/auto-discussion-v2.png'),
|
||||
title: t('onboarding.autoTitle'),
|
||||
body: t('onboarding.autoBody'),
|
||||
},
|
||||
@@ -2712,11 +2730,24 @@ const filteredKnowledgeBaseOptions = computed(() => {
|
||||
})
|
||||
.slice(0, MAX_KNOWLEDGE_BASES)
|
||||
})
|
||||
const composerMenuOptions = computed(() => [
|
||||
...filteredSkillOptions.value.map(skill => ({ type: 'skill', value: skill })),
|
||||
...filteredKnowledgeBaseOptions.value.map(source => ({ type: 'knowledge-base', value: source })),
|
||||
...filteredAgentMentionOptions.value.map(kind => ({ type: 'agent', value: kind })),
|
||||
])
|
||||
const composerMenuGroups = computed(() => [
|
||||
{
|
||||
type: 'knowledge-base',
|
||||
label: t('composer.mentionSection.knowledge-base'),
|
||||
options: filteredKnowledgeBaseOptions.value.map(source => ({ type: 'knowledge-base', value: source })),
|
||||
},
|
||||
{
|
||||
type: 'skill',
|
||||
label: t('composer.mentionSection.skill'),
|
||||
options: filteredSkillOptions.value.map(skill => ({ type: 'skill', value: skill })),
|
||||
},
|
||||
{
|
||||
type: 'agent',
|
||||
label: t('composer.mentionSection.agent'),
|
||||
options: filteredAgentMentionOptions.value.map(kind => ({ type: 'agent', value: kind })),
|
||||
},
|
||||
].filter(group => group.options.length))
|
||||
const composerMenuOptions = computed(() => composerMenuGroups.value.flatMap(group => group.options))
|
||||
const activeSkillOptionId = computed(() => (
|
||||
skillMenuOpen.value && composerMenuOptions.value[skillActiveIndex.value]
|
||||
? `composer-mention-option-${skillActiveIndex.value}`
|
||||
@@ -3726,6 +3757,17 @@ function startOnboardingPlayback() {
|
||||
onboardingPlaybackTimer = setTimeout(step, ONBOARDING_SLIDE_MS)
|
||||
}
|
||||
|
||||
function selectOnboardingSlide(index) {
|
||||
const nextIndex = Math.max(0, Math.min(Number(index) || 0, onboardingLastIndex.value))
|
||||
onboardingIndex.value = nextIndex
|
||||
clearOnboardingPlayback()
|
||||
if (onboardingOnLastSlide.value) {
|
||||
onboardingPlaybackComplete.value = true
|
||||
return
|
||||
}
|
||||
startOnboardingPlayback()
|
||||
}
|
||||
|
||||
function beginOnboardingDetection() {
|
||||
onboardingDetecting.value = true
|
||||
void refreshAgents().finally(() => { onboardingDetecting.value = false })
|
||||
@@ -4447,6 +4489,10 @@ function composerMenuOptionKey(option) {
|
||||
return `agent:${option?.value}`
|
||||
}
|
||||
|
||||
function composerMenuOptionIndex(option) {
|
||||
return composerMenuOptions.value.indexOf(option)
|
||||
}
|
||||
|
||||
function composerMenuOptionLogo(option) {
|
||||
if (option?.type === 'knowledge-base') return option.value?.logo || ''
|
||||
if (option?.type === 'agent') return agentLogo(option.value, theme.value)
|
||||
|
||||
@@ -377,9 +377,16 @@ describe('RoundRelay workbench', () => {
|
||||
expect(wrapper.get('.sidebar').attributes()).toHaveProperty('inert')
|
||||
expect(wrapper.get('.workspace-pane').attributes()).toHaveProperty('inert')
|
||||
|
||||
await vi.advanceTimersByTimeAsync(7_500)
|
||||
await wrapper.findAll('.onboarding-dot')[1].trigger('click')
|
||||
expect(wrapper.get('.onboarding-slide img').attributes('src')).toContain('provider-setup-v2.png')
|
||||
expect(wrapper.findAll('.onboarding-dot')[1].attributes('aria-current')).toBe('step')
|
||||
|
||||
await vi.advanceTimersByTimeAsync(5_000)
|
||||
await flushPromises()
|
||||
expect(wrapper.get('.onboarding-slide img').attributes('src')).toContain('auto-discussion.svg')
|
||||
expect(wrapper.get('.onboarding-slide img').attributes('src')).toContain('agent-collaboration.png')
|
||||
|
||||
await wrapper.findAll('.onboarding-dot')[4].trigger('click')
|
||||
expect(wrapper.get('.onboarding-slide img').attributes('src')).toContain('auto-discussion-v2.png')
|
||||
expect(wrapper.get('.onboarding-primary').attributes()).toHaveProperty('disabled')
|
||||
expect(wrapper.get('.onboarding-primary').text()).toContain('Detecting local Agents')
|
||||
|
||||
@@ -1428,6 +1435,25 @@ describe('RoundRelay workbench', () => {
|
||||
expect(source).not.toMatch(/\.sidebar\.collapsed \.new-group-button\s*\{[^}]*margin-inline:\s*auto;/s)
|
||||
})
|
||||
|
||||
it('uses a theme-aware rounded desktop shell instead of hard pane dividers', () => {
|
||||
const source = readFileSync(resolve(process.cwd(), 'src/styles.css'), 'utf8')
|
||||
const appSource = readFileSync(resolve(process.cwd(), 'src/App.vue'), 'utf8')
|
||||
|
||||
expect(appSource).toContain(':data-platform="desktopPlatform"')
|
||||
expect(appSource).toContain("const desktopPlatform = computed(() => api.value?.platform || installCatalog.value.platform || '')")
|
||||
expect(source).toMatch(/--shell-gradient:\s*linear-gradient\(155deg,\s*#f1f7f5 0%,\s*#e5edef 40%,\s*#d4e2e4 72%,\s*#c4d6db 100%\);/)
|
||||
expect(source).toMatch(/:root\[data-theme="dark"\]\s*\{[^}]*--shell-gradient:\s*linear-gradient\(155deg,\s*#293334 0%,\s*#22292b 38%,\s*#192125 70%,\s*#11191e 100%\);/s)
|
||||
expect(source).toMatch(/--onboarding-frame-gradient:\s*linear-gradient\(145deg,\s*#dcefeb 0%,\s*#9fc2ca 48%,\s*#ddb5aa 100%\);/)
|
||||
expect(source).toMatch(/:root\[data-theme="dark"\]\s*\{[^}]*--onboarding-frame-gradient:\s*linear-gradient\(145deg,\s*#4a696b 0%,\s*#2e4751 52%,\s*#775047 100%\);/s)
|
||||
expect(source).toMatch(/\.onboarding-dialog\s*\{[^}]*border:\s*1px solid transparent;[^}]*background:\s*linear-gradient\(var\(--surface\), var\(--surface\)\) padding-box,\s*var\(--onboarding-frame-gradient\) border-box;/s)
|
||||
expect(source).toMatch(/\.app-shell\s*\{[^}]*gap:\s*var\(--shell-gutter\);[^}]*padding:\s*calc\(var\(--desktop-titlebar-height\) \+ var\(--shell-gutter\)\) var\(--shell-gutter\) var\(--shell-gutter\) 0;[^}]*background:\s*var\(--shell-gradient\);/s)
|
||||
expect(source).toMatch(/\.app-shell\[data-platform="darwin"\]::before\s*\{[^}]*-webkit-app-region:\s*drag;/s)
|
||||
expect(source).toMatch(/\.workspace-pane\s*\{[^}]*border-radius:\s*var\(--workspace-radius\);[^}]*background:\s*var\(--workspace-surface\);[^}]*box-shadow:\s*var\(--workspace-shadow\);/s)
|
||||
expect(source).toMatch(/\.sidebar\s*\{[^}]*background:\s*transparent;/s)
|
||||
expect(source).toMatch(/\.conversation-header\s*\{[^}]*border-bottom:\s*0;[^}]*background:\s*transparent;/s)
|
||||
expect(source).toMatch(/\.composer-zone\s*\{[^}]*background:\s*transparent;/s)
|
||||
})
|
||||
|
||||
it('uses one settings entry and a borderless Agent mention menu', () => {
|
||||
const source = readFileSync(resolve(process.cwd(), 'src/styles.css'), 'utf8')
|
||||
|
||||
@@ -2383,7 +2409,10 @@ describe('RoundRelay workbench', () => {
|
||||
expect(wrapper.findAll('.skill-option')).toHaveLength(1)
|
||||
expect(wrapper.get('.skill-option').text()).toContain('Find sources')
|
||||
await textarea.trigger('keydown', { key: 'Enter' })
|
||||
expect(wrapper.get('.selected-skill').text()).toContain('Find sources')
|
||||
const selectedSkill = wrapper.get('.selected-skill')
|
||||
expect(selectedSkill.text()).toContain('Find sources')
|
||||
expect(selectedSkill.classes()).toContain('selected-agent-tag')
|
||||
expect(selectedSkill.element.closest('.composer-input-shell')).not.toBeNull()
|
||||
|
||||
await wrapper.findAll('.selected-agent-tag button')[1].trigger('click')
|
||||
expect(wrapper.findAll('.selected-agent-tag').map(tag => tag.text())).toEqual(['Codex'])
|
||||
@@ -2489,6 +2518,61 @@ describe('RoundRelay workbench', () => {
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('lists knowledge bases before skills in grouped and direct @ menus', async () => {
|
||||
const { wrapper } = await mountApp(({ state, bridge: desktopBridge }) => {
|
||||
state.groups.push({
|
||||
id: 'group-menu-order',
|
||||
conversationType: 'group',
|
||||
name: 'Knowledge review',
|
||||
topic: '',
|
||||
agentKinds: ['codex'],
|
||||
workdir: '/tmp/roundrelay-workspace',
|
||||
allowWrite: false,
|
||||
createdAt: '2026-07-29T08:00:00Z',
|
||||
updatedAt: '2026-07-29T08:00:00Z',
|
||||
})
|
||||
state.groups.push({
|
||||
id: 'direct-menu-order',
|
||||
conversationType: 'direct',
|
||||
directAgentKind: 'codex',
|
||||
name: 'Codex direct',
|
||||
topic: '',
|
||||
agentKinds: ['codex'],
|
||||
workdir: '/tmp/roundrelay-workspace',
|
||||
allowWrite: false,
|
||||
createdAt: '2026-07-29T08:00:00Z',
|
||||
updatedAt: '2026-07-29T08:00:00Z',
|
||||
})
|
||||
desktopBridge.agentInstaller.skills.mockResolvedValue({
|
||||
skills: [{ targetKind: 'codex', namespace: 'research', slug: 'deep-research', name: 'Deep research' }],
|
||||
})
|
||||
})
|
||||
|
||||
await wrapper.get('.conversation-link').trigger('click')
|
||||
const textarea = wrapper.get('.composer-box textarea')
|
||||
await textarea.setValue('@cod')
|
||||
await wrapper.get('.agent-mention-option').trigger('click')
|
||||
await textarea.setValue('@')
|
||||
await flushPromises()
|
||||
|
||||
const sections = wrapper.findAll('.mention-menu-section')
|
||||
expect(sections.map(section => section.get('.mention-menu-section-label').text()))
|
||||
.toEqual(['Knowledge bases', 'Skills'])
|
||||
expect(sections[0].text()).toContain('DingTalk Docs')
|
||||
expect(sections[1].text()).toContain('Deep research')
|
||||
expect(wrapper.findAll('.skill-option').map(option => option.attributes('id')))
|
||||
.toEqual(['composer-mention-option-0', 'composer-mention-option-1'])
|
||||
|
||||
wrapper.vm.selectGroup('direct-menu-order')
|
||||
await flushPromises()
|
||||
await textarea.setValue('@')
|
||||
await flushPromises()
|
||||
expect(wrapper.findAll('.mention-menu-section').map(section => (
|
||||
section.get('.mention-menu-section-label').text()
|
||||
))).toEqual(['Knowledge bases', 'Skills'])
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('restores Agent Tags and Skills when a targeted send fails', async () => {
|
||||
const { wrapper } = await mountApp(({ state, bridge: desktopBridge }) => {
|
||||
state.groups.push({
|
||||
|
||||
@@ -265,6 +265,9 @@ const messages = {
|
||||
'composer.mentionType.agent': 'Agent',
|
||||
'composer.mentionType.skill': 'Skill',
|
||||
'composer.mentionType.knowledge-base': 'Knowledge',
|
||||
'composer.mentionSection.agent': 'Agents',
|
||||
'composer.mentionSection.skill': 'Skills',
|
||||
'composer.mentionSection.knowledge-base': 'Knowledge bases',
|
||||
'composer.knowledgeBaseDescription.feishu': 'Search Feishu documents through the configured local connection',
|
||||
'composer.knowledgeBaseDescription.dingtalk': 'Search DingTalk documents through the configured dws connection',
|
||||
'composer.knowledgeBaseDescription.obsidian': 'Use notes from your selected local vault as task context',
|
||||
@@ -841,6 +844,9 @@ const messages = {
|
||||
'composer.mentionType.agent': 'Agent',
|
||||
'composer.mentionType.skill': '技能',
|
||||
'composer.mentionType.knowledge-base': '知识库',
|
||||
'composer.mentionSection.agent': 'Agent',
|
||||
'composer.mentionSection.skill': '技能',
|
||||
'composer.mentionSection.knowledge-base': '知识库',
|
||||
'composer.knowledgeBaseDescription.feishu': '通过已配置的本地连接查找飞书文档',
|
||||
'composer.knowledgeBaseDescription.dingtalk': '通过已配置的 dws 连接查找钉钉文档',
|
||||
'composer.knowledgeBaseDescription.obsidian': '把已选择的本地仓库作为这次任务的上下文',
|
||||
|
||||
+101
-49
@@ -22,8 +22,15 @@
|
||||
--danger: #b74743;
|
||||
--danger-soft: #fbe8e6;
|
||||
--shadow: 0 12px 32px rgb(41 62 73 / 0.12);
|
||||
--shell-gradient: linear-gradient(155deg, #f1f7f5 0%, #e5edef 40%, #d4e2e4 72%, #c4d6db 100%);
|
||||
--onboarding-frame-gradient: linear-gradient(145deg, #dcefeb 0%, #9fc2ca 48%, #ddb5aa 100%);
|
||||
--workspace-surface: #fbfcfd;
|
||||
--workspace-shadow: 0 1px 2px rgb(41 62 73 / 0.08), 0 10px 28px rgb(41 62 73 / 0.08);
|
||||
--radius-sm: 5px;
|
||||
--radius: 8px;
|
||||
--workspace-radius: 16px;
|
||||
--shell-gutter: 10px;
|
||||
--desktop-titlebar-height: 0px;
|
||||
--sidebar-width: 276px;
|
||||
--sidebar-collapsed-width: 68px;
|
||||
}
|
||||
@@ -49,6 +56,10 @@
|
||||
--danger: #ee817c;
|
||||
--danger-soft: #402326;
|
||||
--shadow: 0 16px 42px rgb(0 0 0 / 0.42);
|
||||
--shell-gradient: linear-gradient(155deg, #293334 0%, #22292b 38%, #192125 70%, #11191e 100%);
|
||||
--onboarding-frame-gradient: linear-gradient(145deg, #4a696b 0%, #2e4751 52%, #775047 100%);
|
||||
--workspace-surface: #181c1e;
|
||||
--workspace-shadow: 0 1px 2px rgb(0 0 0 / 0.42), 0 14px 34px rgb(0 0 0 / 0.24);
|
||||
}
|
||||
|
||||
* {
|
||||
@@ -114,14 +125,33 @@ button svg {
|
||||
}
|
||||
|
||||
.app-shell {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
|
||||
min-height: 100dvh;
|
||||
background: var(--bg);
|
||||
gap: var(--shell-gutter);
|
||||
width: 100%;
|
||||
height: 100dvh;
|
||||
min-height: 0;
|
||||
padding: calc(var(--desktop-titlebar-height) + var(--shell-gutter)) var(--shell-gutter) var(--shell-gutter) 0;
|
||||
overflow: hidden;
|
||||
background: var(--shell-gradient);
|
||||
color: var(--text);
|
||||
transition: grid-template-columns 0.22s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.app-shell[data-platform="darwin"] {
|
||||
--desktop-titlebar-height: 28px;
|
||||
}
|
||||
|
||||
.app-shell[data-platform="darwin"]::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0 0 auto;
|
||||
z-index: 2;
|
||||
height: calc(var(--desktop-titlebar-height) + var(--shell-gutter));
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
.app-shell.sidebar-collapsed {
|
||||
grid-template-columns: var(--sidebar-collapsed-width) minmax(0, 1fr);
|
||||
}
|
||||
@@ -143,12 +173,14 @@ button svg {
|
||||
grid-column: 3;
|
||||
grid-row: 1;
|
||||
min-width: 0;
|
||||
height: 100dvh;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
border-left: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
border: 0;
|
||||
border-radius: var(--workspace-radius);
|
||||
background: var(--workspace-surface);
|
||||
box-shadow: var(--workspace-shadow);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
@@ -226,9 +258,10 @@ button svg {
|
||||
display: grid;
|
||||
grid-template-rows: minmax(0, 1fr) auto;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--border-strong);
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--radius);
|
||||
background: var(--surface);
|
||||
background: linear-gradient(var(--surface), var(--surface)) padding-box,
|
||||
var(--onboarding-frame-gradient) border-box;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
@@ -299,6 +332,10 @@ button svg {
|
||||
position: relative;
|
||||
display: block;
|
||||
flex: 0 0 auto;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.onboarding-dot::after {
|
||||
@@ -319,6 +356,20 @@ button svg {
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
.onboarding-dot:hover::after {
|
||||
background: var(--text-soft);
|
||||
}
|
||||
|
||||
.onboarding-dot.active:hover::after {
|
||||
background: var(--accent-hover);
|
||||
}
|
||||
|
||||
.onboarding-dot:focus-visible {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: -2px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.onboarding-primary {
|
||||
min-width: 170px;
|
||||
}
|
||||
@@ -363,11 +414,11 @@ button svg {
|
||||
|
||||
.sidebar {
|
||||
min-width: 0;
|
||||
height: 100dvh;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
background: var(--sidebar);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.brand-row {
|
||||
@@ -1083,8 +1134,11 @@ button svg {
|
||||
|
||||
.workspace-pane {
|
||||
min-width: 0;
|
||||
height: 100dvh;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
border-radius: var(--workspace-radius);
|
||||
background: var(--workspace-surface);
|
||||
box-shadow: var(--workspace-shadow);
|
||||
}
|
||||
|
||||
.agent-home {
|
||||
@@ -1381,7 +1435,7 @@ button svg {
|
||||
display: grid;
|
||||
grid-template-rows: auto minmax(0, 1fr);
|
||||
overflow: hidden;
|
||||
background: var(--bg);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.system-settings-header {
|
||||
@@ -2726,6 +2780,7 @@ button svg {
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-rows: 68px minmax(0, 1fr) auto;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.conversation-header {
|
||||
@@ -2735,8 +2790,8 @@ button svg {
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
padding: 0 20px 0 24px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
border-bottom: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.conversation-identity {
|
||||
@@ -4697,7 +4752,7 @@ button svg {
|
||||
|
||||
.composer-zone {
|
||||
padding: 10px clamp(18px, 4vw, 44px) 18px;
|
||||
background: var(--bg);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.composer-context-row {
|
||||
@@ -5047,6 +5102,29 @@ button svg {
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.mention-menu-section {
|
||||
display: grid;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.mention-menu-section + .mention-menu-section {
|
||||
margin-top: 6px;
|
||||
padding-top: 6px;
|
||||
border-top: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
|
||||
}
|
||||
|
||||
.mention-menu-section-label {
|
||||
width: fit-content;
|
||||
margin: 2px 8px 3px;
|
||||
padding: 2px 6px;
|
||||
border-radius: 999px;
|
||||
background: var(--surface-hover);
|
||||
color: var(--muted);
|
||||
font-size: 9px;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.skill-option {
|
||||
width: 100%;
|
||||
min-height: 58px;
|
||||
@@ -5258,6 +5336,7 @@ button svg {
|
||||
}
|
||||
|
||||
.selected-agent-tag,
|
||||
.selected-skill,
|
||||
.message-target-list span {
|
||||
height: 28px;
|
||||
display: inline-flex;
|
||||
@@ -5273,6 +5352,8 @@ button svg {
|
||||
}
|
||||
|
||||
.selected-agent-tag > img,
|
||||
.selected-knowledge-base img,
|
||||
.selected-context-icon,
|
||||
.message-target-list img {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
@@ -5280,6 +5361,11 @@ button svg {
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.selected-context-icon {
|
||||
padding: 1px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.selected-agent-tag button {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
@@ -5319,8 +5405,7 @@ button svg {
|
||||
}
|
||||
|
||||
.composer-tools,
|
||||
.composer-run-actions,
|
||||
.selected-skill-list {
|
||||
.composer-run-actions {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -5378,41 +5463,8 @@ button svg {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.selected-skill-list {
|
||||
gap: 4px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.selected-skill {
|
||||
height: 28px;
|
||||
flex: 0 0 auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 0 5px 0 8px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--surface);
|
||||
color: var(--text-soft);
|
||||
font-size: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.selected-knowledge-base img {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
background: transparent;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.selected-skill button {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.selected-skill button svg {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
.message-target-list {
|
||||
|
||||
Reference in new issue
Block a user