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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,31 @@ jobs:
- name: Verify API inventory and reports
run: npm run api:check

web-visual:
name: Web visual and accessibility
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 22.16.0
cache: npm

- name: Install
run: npm ci

- name: Install Chromium
run: npx playwright install --with-deps chromium

- name: Build Web workspace
run: npm run build -w @rdk-moss/agent

- name: Run Playwright visual and accessibility gate
run: npm run test:filter -w @rdk-moss/agent -- --filter web-ui-browser

verify:
name: Verify (${{ matrix.os }})
runs-on: ${{ matrix.os }}
Expand Down
25 changes: 22 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,30 @@ Categories: **Added** · **Changed** · **Fixed** · **Removed** · **Internal**

## [Unreleased]

### Fixed

- **Cross-platform plugin process lifecycle**: active Worker RPC calls now keep their worker alive
until every pending promise settles, and exact-version plugin installation runs npm's JavaScript
CLI directly on Windows instead of failing through the `npm.cmd` shim.

### Added

- **Zero-friction Web workspace**: `moss web` starts a local browser experience with streaming chat,
visible tool evidence, cancellation, and live redacted runtime capabilities without sending model
credentials to the browser.
- **Complete local Web workbench**: `moss web` now provides the responsive three-column Moss design
system, durable searchable sessions, resume/rename/export/delete/fork/rewind, cursor-based SSE,
rich conversation and tool evidence, bounded text/image attachments, generated-file downloads,
approval and question takeover, modes/Goal/Todo/queue/steering, jobs/workflows, trajectory and
verdict details, seven consistent settings sections, keyboard/reduced-motion support, and
fixed-viewport Playwright visual/accessibility gates. Provider credentials never enter the
browser, and every mutation requires same-Host, same-Origin, per-server CSRF authorization.
- **Hot-reloadable plugin platform and audited DeepSeek compatibility**: plugins can contribute
tools, Skills, experts, prompts, commands, providers, MCP presets, schema configuration, secrets,
and typed Web slots. Exact-version npm candidates use immutable roots; import/setup/calls run
behind terminable Worker RPC and active-call leases; enable/disable/config changes drain and
atomically retain the last-good composition. The Web settings page and CLI share add/remove/
enable/disable/list/doctor behavior. Real DeepSeek Harness `package.json + cordis.patch.yml`
packages are inspected without executing Cordis: only an audited `SKILL.md` or explicit Moss
adapter data is mapped, native client/runtime ABI fails closed, and the attributed
`official:deepseek-harness` Skill/command/exact MCP preset remains opt-in.
- **Durable Web task history**: Web tasks now receive ordered run identities, persisted tool
evidence, honest completion/verification states, restart interruption recovery, and inspectable
run-history endpoints. `npm run demo:capabilities` exercises a plugin, inline Skill, read-only
Expand Down
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ the runtime implements that intent.
- [`env-vars.md`](./env-vars.md): environment variables and ownership.
- [`deepseek-harness-review.md`](./deepseek-harness-review.md): evidence-based plugin lifecycle
lessons, staged Moss adoption, and explicit non-goals.
- [`deepseek-harness-plugin-audit.md`](./deepseek-harness-plugin-audit.md): revision-pinned ecosystem
audit, reusable declarative subset, license evidence, and fail-closed Cordis compatibility rules.

## Evaluation and evolution

Expand Down
56 changes: 56 additions & 0 deletions docs/deepseek-harness-plugin-audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# DeepSeek Harness plugin compatibility audit

Audit date: 2026-08-18. Sources were read directly from GitHub. The official product reference is
[`deepseek-ai/deepseek-harness`](https://github.com/deepseek-ai/deepseek-harness); the ecosystem
inventory is
[`awesome-dsh-plugin/awesome-dsh-plugin`](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin).
At the audited revision the inventory contained 1,247 YAML entries. Its own warning is controlling:
listing means installability and maintenance checks, not a security review.

## Compatibility rule

An official DSH bundle targets Cordis, `cordis.patch.yml`, the `@deepseek-ai/dsh-*` host services,
and DSH client slots. Moss uses different runtime and Web contracts. It must therefore never execute
a DSH bundle as if the ABIs were interchangeable.

Moss imports only declarative contributions that can be mapped without changing their meaning:

- `SKILL.md` content becomes a Moss Skill with its contained source path recorded; license metadata
remains an audit input and is not synthesized when the package does not declare it.
- MCP server declarations become an explicit Moss MCP preset.
- data-only command templates and JSON Schema configuration become their Moss equivalents.
- native DSH runtime, Cordis service, and client-slot modules are rejected with a precise
compatibility diagnostic. They may be ported deliberately to Moss APIs after source review.

Installation stays explicit. Imported third-party JavaScript remains trusted code, not sandboxed
code. Moss runs it behind a termination-bounded Worker/RPC lifecycle so import/setup hangs cannot
block the core host, but that boundary is deliberately not described as a permission sandbox. A
catalog entry never grants automatic execution.

## Reviewed candidates

| Candidate | License | Decision | Reason |
| ---------------------------------------------- | ------------ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `HenryZ838978/deepseek-harness` 0.2.0 | MIT | Bundled, disabled by default | Its protocol Skill is host-neutral. Moss also exposes its exact-version `@deepseek-harness/mcp@0.2.0` server as an MCP preset and a `deepseek-protocol` command. |
| `awesome-dsh-plugin/dsh-find-plugin` 0.3.6 | MIT | Do not execute; reuse catalog ideas | It requires `@deepseek-ai/cordis` and `@deepseek-ai/dsh-tools`. Moss plugin discovery must use Moss manifests and explicit installs. |
| `liuyuelintop/dsh-conversation-exporter` 0.2.0 | MIT | Native Moss implementation retained | The DSH client module depends on DSH runtime/conversation slots. Moss now provides server-owned Markdown export, avoiding a parallel exporter. |
| `Anionex/dsh-turn-rewind` 0.1.1 | BSD-3-Clause | Native Moss implementation retained | Its persistent ledger is strong prior art, but its Cordis and DSH client ABI is incompatible. Moss uses its existing conversation/file checkpoints and exposes non-destructive rewind. |
| `AcidGr/dsh-web-mobile-fix` 1.0.2 | MIT | Behavior ported into the Moss design system | The package is a DSH CSS overlay. Moss implements first-class session/details drawers, settings layout, focus containment, and 44 px controls instead of loading a parallel theme. |
| `GooodWei/context-vista` 0.1.0 | MIT | Behavior ported into Moss conversation/details UI | The package requires DSH commands, settings, locale, and conversation services. Moss renders its own durable usage/context projection and `/context` control. |
| `HongMing-Huang/dsh-file-upload` 0.4.2 | MIT | Capability ported behind Moss attachment contracts | Its document conversion is useful prior art, but the plugin depends on DSH Cordis credentials, filesystem, tools, runtime, and React 18. Moss keeps upload security and message persistence in its own host. |

## Rejected loading patterns

- A plugin declaring `dsh.bundle.patch` is not sufficient evidence of Moss compatibility.
- The compatibility reader audits the real `package.json + cordis.patch.yml` package shape. Optional
`moss.dsh-adapter.json` is a Moss-owned data adapter, not a native DSH manifest or ABI claim.
- A package with `dsh.client.inject` cannot be mounted into a Moss ShadowRoot by renaming imports.
- Theme or layout plugins cannot inject global CSS; Moss tokens and controlled components remain the
single design system.
- Marketplace or GitHub topic results are never auto-installed.
- Plugins without a verified license, exact source revision, manifest containment, side-effect
metadata, or successful candidate activation remain disabled.

This audit is repeated before adding a bundled compatibility source. The completion gate verifies
that unsupported DSH bundles fail closed and that accepted Skill/MCP mappings are reversible and
owned by one plugin generation.
66 changes: 60 additions & 6 deletions docs/user-guide/23-runtime-plugins.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Runtime plugins for embedding hosts

`createMossRuntime()` accepts host-trusted `MossPlugin` objects. A plugin can
contribute tools, inline skills, read-only sub-agent experts, prompt layers, and
contribute tools, inline skills, read-only sub-agent experts, prompt layers, Web UI slots, and
owned cleanup effects without mutating process-global registries.

```ts
Expand Down Expand Up @@ -42,6 +42,53 @@ await runtime.plugins.unload('example/review');
await runtime.close();
```

## Explicit CLI installation

Trusted plugins can also ship a `moss.plugin.json` v1 at their package root:

```json
{
"schemaVersion": 1,
"id": "example/review",
"version": "1.0.0",
"runtime": { "module": "./dist/plugin.js", "export": "plugin" },
"web": {
"contributions": [
{ "id": "review-settings", "slot": "settings.plugin", "module": "./dist/settings.js" }
]
},
"configSchema": "./config.schema.json"
}
```

Install and inspect it explicitly:

```bash
moss plugins add ./my-plugin
moss plugins add @example/moss-review@1.0.0
moss plugins add official:deepseek-harness
moss plugins list
moss plugins doctor
moss plugins enable deepseek/harness
moss plugins disable example/review
```

New plugins are installed **disabled** so installation cannot silently activate executable code.
Local paths remain linked to their resolved root. npm sources require an exact semantic version,
install under the Moss config directory, and run with lifecycle scripts disabled. `doctor` performs
containment, manifest, schema, module-resolution, and compatibility checks without executing a
disabled plugin. `enable` performs candidate activation inside the bounded Worker/RPC lifecycle
before publishing the state change. Registry mutations use a cross-process lock so simultaneous
CLI/Web updates do not lose records. Manifest/runtime failures are reported and isolated so the core
workbench can still start. Web enable, disable, and remove drain active calls and publish a new
composition generation without restarting the server; a failed candidate or drain timeout keeps the
last-good generation active.

`official:deepseek-harness` is an MIT-licensed compatibility Skill adapted from the independently
maintained `HenryZ838978/deepseek-harness` project. It adds protocol guidance for DeepSeek reasoning,
streamed parallel tools, token limits, cache stability, and endpoint selection; it does not install
credentials or claim that third-party JavaScript is sandboxed.

## Fastest path: generate a validated tool

Use the scaffold when starting a new host project:
Expand Down Expand Up @@ -70,12 +117,19 @@ generated host and must not be committed.
does not return prompt content, expert instructions, model routing, budgets,
credentials, or arbitrary plugin configuration.
- Executable plugins are trusted host code. Moss does not discover or execute
JavaScript from the workspace, and the plugin host is not a sandbox.
JavaScript automatically from the workspace, and the plugin host is not a sandbox.
- Web contributions use stable Moss slots and package-relative modules. Plugin UI must consume the
public `--moss-*` tokens. Advanced modules export `mount(root, context)` and receive an isolated
`ShadowRoot`; JSON Schema configuration remains the preferred default surface.
- A Web contribution must currently be one browser-ready ESM file. Bundle relative and bare imports
into that file before publishing; the v1 loopback host does not serve multi-file module graphs.

Dynamic unload while a plugin tool call is still active is not yet an HMR
contract. Hosts should close or drain agent work before unloading a plugin. A
future quiescence layer will gate new calls, abort/drain active leases, and then
release resources.
Dynamic unload gates new calls and waits for active Tool/provider/command leases. A timeout keeps the
old generation active; successful Web enable/disable publishes a composition event and browser asset
URLs carry that generation for cache busting. Installed JavaScript import/setup and later calls run
through a termination-bounded Worker/RPC boundary. This prevents sync/async startup hangs from
blocking the core host, but it is not a permission sandbox and installed code remains user-authorized
trusted code.

## Cordis direction

Expand Down
38 changes: 33 additions & 5 deletions docs/user-guide/24-web-ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ moss web

Open `http://127.0.0.1:3080`. To select another port, run `moss web 4080`.

The React workbench uses one responsive three-column layout: sessions on the left, conversation in
the center, and runtime/tool details on the right. Narrow desktop and tablet widths collapse the
detail rail and then the session rail instead of switching to a separately styled interface. Light
and dark themes share the same `--moss-*` design tokens, focus treatment, state colors, and reduced
motion behavior.

## What the screen proves

- **Timeline** streams the assistant response instead of waiting for the whole turn.
Expand All @@ -23,9 +29,25 @@ Open `http://127.0.0.1:3080`. To select another port, run `moss web 4080`.
count, and verification instead of treating a fluent model answer as proof.
- Selecting a recent run opens its durable event timeline. The list is keyboard accessible, and the
detail endpoint supports sequence cursors for incremental recovery.

The server binds to loopback by default, rejects non-local mutation origins, sets a restrictive
Content Security Policy, and never sends provider configuration or credentials to the browser.
- **Settings** exposes Runtime, Models, Permissions, and Plugins using the same controls and density
as the conversation surface. Credential values are process-owned and are never returned.
- **Sessions** can be searched, resumed, renamed, exported, explicitly deleted, forked, or rewound
into a new non-destructive branch. Draft, scroll, details, and panel state are retained per task.
- **Interaction controls** present approval and user questions in the composer, and expose the same
plan/default/accept-edits policy, Goal, Todo, queue, steering, workflow, job, model, Skill, and
sub-agent inventories owned by the configured runtime.
- **Attachments** upload bounded UTF-8 text or signature-checked images into an instance-local
store. Generated workspace files are copied through a realpath-contained artifact endpoint before
download; a browser-supplied path is never opened as an arbitrary host path.
- **Plugins** can be installed, diagnosed, configured, enabled, disabled, and removed without
restarting the Web server. UI modules receive typed slot ownership and the Moss controlled
component entry instead of defining a parallel theme.

The server binds to loopback by default. Every mutation requires the exact Host, same Origin, and a
random per-server CSRF token obtained by the bootstrapped same-origin client. It sets a restrictive
Content Security Policy and never sends provider configuration or credential values to the browser.
API keys and plugin secrets are write/delete-only; status responses reveal only whether a value is
configured.

## Long tasks

Expand Down Expand Up @@ -59,6 +81,12 @@ non-zero if any contribution was not used or if the final answer was not grounde

## Current limits

- Durable session browsing and fork/rewind controls are planned rather than silently approximated.
- Plugin hot reload is not exposed until active tool-call leases and quiescent unload are complete.
- Remote binding and multi-user authentication are intentionally absent from this local-first slice.
- Third-party JavaScript plugins are explicitly trusted code. Worker containment makes a stuck
import/setup/call terminable, but it is not a permissions sandbox; a plugin can still use its Node
process authority and an advanced browser module runs in the same page origin.
- Native DeepSeek Harness Cordis runtime/client modules are not ABI-compatible with Moss. Moss can
import only an audited package's declarative `SKILL.md` or explicit Moss adapter data; unsupported
client slots fail closed.
- The previous compact Web surface remains available at `/?legacy=1` for one release cycle as a
rollback path. It uses the current CSRF/session APIs and will be removed after that window.
Loading