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
8 changes: 4 additions & 4 deletions packages/mtmharness/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
- **DSH Web plugin**: the package root and `./client` export use the official `dsh.client` lazy-CJS contract. One installation provides the settings-controlled MTM Connect secondary extension and the Codebase Memory/Modern Go/Ponytail/RTK coding features.
- **Independent web client**: the package also publishes a BrowserHistory static app and a MemoryHistory script/embed entry. These artifacts own their React root, router, styles, and teardown and never load the local coding runtime.

The DSH plugin is assembled from coding and secondary frontend domains under one Host/Client lifecycle. Codebase Memory keeps its `codebase_memory` server namespace and `mcp__codebase_memory__*` tool names; Ponytail exposes six externally installed skills through DSH's native skill surface. The `/ponytail` command controls per-agent intensity; the five companion names remain available as native skills and are not duplicated as host commands. The `mtm-coding` settings namespace contains the runtime extension toggles.
The DSH plugin is assembled from coding and secondary frontend domains under one Host/Client lifecycle. Codebase Memory keeps its `codebase_memory` server namespace and `mcp__codebase_memory__*` tool names; Ponytail exposes six externally installed skills through DSH's native skill surface. The `/ponytail` command controls per-agent automatic prompt intensity; `off` suppresses that section while explicit native skill invocation remains available. The five companion names are not duplicated as host commands. The `mtm-coding` settings namespace contains the runtime extension toggles.

Modern Go Guidelines is enabled by default as the externally installed `use-modern-go` skill. Its trusted manifest pins the JetBrains `v0.1.1` source and SHA-256; the first enable downloads it into `$DSH_HOME/mtmharness/skills/modern-go`, and `modernGoEnabled` removes the skill from the DSH catalog. Existing files are user-owned and are never overwritten automatically.

RTK is an optional coding feature in the same `mtm-coding` settings namespace. `rtkMode` defaults to `auto`: it transparently rewrites Bash calls when the DSH `tools/pre-record-input` capability is available and falls back to guidance when it is not. Explicit `rewrite` is strict and reports `unavailable` on older DSH runtimes instead of changing frozen tool inputs. The pinned RTK `v0.45.0` binary is resolved and installed lazily from the matching command hook under the DSH home with checksum verification; there is no separate RTK skill document. RTK telemetry, tracking, and tee output are disabled for plugin-managed runs.
RTK is an optional coding feature in the same `mtm-coding` settings namespace. `rtkMode` defaults to `auto` and provides guidance for explicitly invoking an RTK command when the executable is available. The current DSH ToolRuntime has no supported pre-dispatch input-rewrite seam, so the plugin does not register a speculative hook; `rewrite` reports `unavailable` and leaves frozen tool arguments unchanged. The pinned RTK `v0.45.0` runtime helpers remain checksum-verified for explicit integrations; there is no separate RTK skill document. RTK telemetry, tracking, and tee output are disabled for plugin-managed runs.

## Coding Skill Files

The trusted package catalog is data in `src/features/coding/packages.json`: it owns labels, icon keys, immutable GitHub commit pins, expected file digests, and static prompt declarations. On first enable, Ponytail and Modern Go documents are downloaded into `$DSH_HOME/mtmharness/skills/<package>` only when that directory is absent. Downloads are size-limited, SHA-256 checked, written to a temporary sibling, and atomically renamed; an existing directory is treated as an editable user copy. Each enabled package mounts one uniquely named official `@deepseek-ai/dsh-skill-filesystem` provider against its managed custom root, so agents can read and edit the files. Static manifest prompts are mounted only while their package is enabled.
The trusted package catalog is data in `src/features/coding/packages.json`: it owns labels, icon keys, immutable GitHub commit pins, expected file digests, and static prompt declarations. On first enable, Ponytail and Modern Go documents plus their pinned resources are downloaded into `$DSH_HOME/mtmharness/skills/<package>` only when that directory is absent; an existing older directory is completed only with missing bundle files. Downloads are size-limited, SHA-256 checked, written to a temporary sibling, and atomically renamed; existing files remain user-owned and are never overwritten. Each enabled package mounts one uniquely named official `@deepseek-ai/dsh-skill-filesystem` provider against its managed custom root, so agents can read the files while writes remain subject to the active DSH filesystem policy. Static manifest prompts are mounted only while their package is enabled.

## DSH Web Plugin

Expand All @@ -24,7 +24,7 @@ Install the package into a web profile:

Restart the DSH Web host after changing profile composition. Open Settings > Plugins > Plugin configuration to control MTM Connect. The host owns the React root, session connection, and lifecycle.

The plugin registers the `mtm-connect` settings namespace and its externally managed coding skills. No local device backend, token, or loopback RPC is activated by this frontend experiment. The independent static/embed client remains a separate application surface and is not part of the DSH plugin.
The plugin registers the `mtm-connect` settings namespace and its externally managed coding skills. MTM Connect itself activates no local device backend or token flow; package updates use the host's official DSH connection RPC. The independent static/embed client remains a separate application surface and is not part of the DSH plugin.

## Secondary Extensions

Expand Down
140 changes: 70 additions & 70 deletions packages/mtmharness/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mtmharness",
"version": "0.9.2",
"version": "0.9.3",
"description": "Unified DeepSeek Harness Web plugin with Connect, Codebase Memory, Modern Go, Ponytail, and independent static/embed clients.",
"type": "module",
"engines": { "node": ">=22.19.0", "pnpm": ">=11.7.0" },
Expand Down Expand Up @@ -60,83 +60,83 @@
"repository": { "type": "git", "url": "git+https://github.com/codeh007/mtmdsh.git", "directory": "packages/mtmharness" },
"dependencies": {
"@deepseek-ai/schemastery": "3.18.2",
"npm": "11.7.0"
"npm": "11.7.0",
"yaml": "^2.4.2"
},
"peerDependencies": {
"@deepseek-ai/cordis": "^4.0.2",
"@deepseek-ai/dsh-agent": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-attachment": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-brand": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-code-runtime": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-commands": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-llm": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-mcp-client": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-sandbox": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-scope": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-session": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-session-turn-outline": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-settings": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-fs": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-home-paths": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-invariants": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-skill": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-skill-filesystem": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-subprocess": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-system-prompt": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-timeout": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-tools": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-typert-protocol": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-user-approval": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-client-connection": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-client-locale": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-client-store": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-settings": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-settings-plugins": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-sidebar": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-layout": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-slots": "^0.1.2-alpha.4",
"@deepseek-ai/dsh-agent": "0.1.2-alpha.5",
"@deepseek-ai/dsh-attachment": "0.1.2-alpha.5",
"@deepseek-ai/dsh-brand": "0.1.2-alpha.5",
"@deepseek-ai/dsh-code-runtime": "0.1.2-alpha.5",
"@deepseek-ai/dsh-commands": "0.1.2-alpha.5",
"@deepseek-ai/dsh-llm": "0.1.2-alpha.5",
"@deepseek-ai/dsh-mcp-client": "0.1.2-alpha.5",
"@deepseek-ai/dsh-sandbox": "0.1.2-alpha.5",
"@deepseek-ai/dsh-scope": "0.1.2-alpha.5",
"@deepseek-ai/dsh-session-projection": "0.1.2-alpha.5",
"@deepseek-ai/dsh-session": "0.1.2-alpha.5",
"@deepseek-ai/dsh-session-turn-outline": "0.1.2-alpha.5",
"@deepseek-ai/dsh-settings": "0.1.2-alpha.5",
"@deepseek-ai/dsh-fs": "0.1.2-alpha.5",
"@deepseek-ai/dsh-home-paths": "0.1.2-alpha.5",
"@deepseek-ai/dsh-skill": "0.1.2-alpha.5",
"@deepseek-ai/dsh-skill-filesystem": "0.1.2-alpha.5",
"@deepseek-ai/dsh-subprocess": "0.1.2-alpha.5",
"@deepseek-ai/dsh-system-prompt": "0.1.2-alpha.5",
"@deepseek-ai/dsh-timeout": "0.1.2-alpha.5",
"@deepseek-ai/dsh-tools": "0.1.2-alpha.5",
"@deepseek-ai/dsh-typert-protocol": "0.1.2-alpha.5",
"@deepseek-ai/dsh-user-approval": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-connection": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-locale": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-store": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-renderer": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-primitives": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-settings": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-sidebar": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-layout": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-slots": "0.1.2-alpha.5",
"react": ">=18.2.0 <20"
},
"devDependencies": {
"@base-ui/react": "1.7.0",
"@deepseek-ai/cordis": "4.0.2",
"@deepseek-ai/dsh-agent": "0.1.2-alpha.4",
"@deepseek-ai/dsh-attachment": "0.1.2-alpha.4",
"@deepseek-ai/dsh-brand": "0.1.2-alpha.4",
"@deepseek-ai/dsh-code-runtime": "0.1.2-alpha.4",
"@deepseek-ai/dsh-commands": "0.1.2-alpha.4",
"@deepseek-ai/dsh-llm": "0.1.2-alpha.4",
"@deepseek-ai/dsh-mcp-client": "0.1.2-alpha.4",
"@deepseek-ai/dsh-sandbox": "0.1.2-alpha.4",
"@deepseek-ai/dsh-scope": "0.1.2-alpha.4",
"@deepseek-ai/dsh-session-projection": "0.1.2-alpha.4",
"@deepseek-ai/dsh-session": "0.1.2-alpha.4",
"@deepseek-ai/dsh-session-turn-outline": "0.1.2-alpha.4",
"@deepseek-ai/dsh-settings": "0.1.2-alpha.4",
"@deepseek-ai/dsh-fs": "0.1.2-alpha.4",
"@deepseek-ai/dsh-home-paths": "0.1.2-alpha.4",
"@deepseek-ai/dsh-invariants": "0.1.2-alpha.4",
"@deepseek-ai/dsh-skill": "0.1.2-alpha.4",
"@deepseek-ai/dsh-skill-filesystem": "0.1.2-alpha.4",
"@deepseek-ai/dsh-subprocess": "0.1.2-alpha.4",
"@deepseek-ai/dsh-system-prompt": "0.1.2-alpha.4",
"@deepseek-ai/dsh-timeout": "0.1.2-alpha.4",
"@deepseek-ai/dsh-tools": "0.1.2-alpha.4",
"@deepseek-ai/dsh-typert-protocol": "0.1.2-alpha.4",
"@deepseek-ai/dsh-user-approval": "0.1.2-alpha.4",
"@deepseek-ai/dsh-client-connection": "0.1.2-alpha.4",
"@deepseek-ai/dsh-client-locale": "0.1.2-alpha.4",
"@deepseek-ai/dsh-client-store": "0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-renderer": "0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-primitives": "0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-settings": "0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-sidebar": "0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-layout": "0.1.2-alpha.4",
"@deepseek-ai/dsh-client-ui-slots": "0.1.2-alpha.4",
"@deepseek-ai/dsh-agent": "0.1.2-alpha.5",
"@deepseek-ai/dsh-attachment": "0.1.2-alpha.5",
"@deepseek-ai/dsh-brand": "0.1.2-alpha.5",
"@deepseek-ai/dsh-code-runtime": "0.1.2-alpha.5",
"@deepseek-ai/dsh-commands": "0.1.2-alpha.5",
"@deepseek-ai/dsh-llm": "0.1.2-alpha.5",
"@deepseek-ai/dsh-mcp-client": "0.1.2-alpha.5",
"@deepseek-ai/dsh-sandbox": "0.1.2-alpha.5",
"@deepseek-ai/dsh-scope": "0.1.2-alpha.5",
"@deepseek-ai/dsh-session-projection": "0.1.2-alpha.5",
"@deepseek-ai/dsh-session": "0.1.2-alpha.5",
"@deepseek-ai/dsh-session-turn-outline": "0.1.2-alpha.5",
"@deepseek-ai/dsh-settings": "0.1.2-alpha.5",
"@deepseek-ai/dsh-fs": "0.1.2-alpha.5",
"@deepseek-ai/dsh-home-paths": "0.1.2-alpha.5",
"@deepseek-ai/dsh-invariants": "0.1.2-alpha.5",
"@deepseek-ai/dsh-skill": "0.1.2-alpha.5",
"@deepseek-ai/dsh-skill-filesystem": "0.1.2-alpha.5",
"@deepseek-ai/dsh-subprocess": "0.1.2-alpha.5",
"@deepseek-ai/dsh-system-prompt": "0.1.2-alpha.5",
"@deepseek-ai/dsh-timeout": "0.1.2-alpha.5",
"@deepseek-ai/dsh-tools": "0.1.2-alpha.5",
"@deepseek-ai/dsh-typert-protocol": "0.1.2-alpha.5",
"@deepseek-ai/dsh-user-approval": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-connection": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-locale": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-store": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-renderer": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-primitives": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-settings": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-sidebar": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-layout": "0.1.2-alpha.5",
"@deepseek-ai/dsh-client-ui-slots": "0.1.2-alpha.5",
"@tailwindcss/vite": "4.3.3",
"@tanstack/react-router": "1.169.2",
"@types/node": "22.20.1",
Expand Down
19 changes: 18 additions & 1 deletion packages/mtmharness/src/client/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Context } from "@deepseek-ai/cordis";
import { describe, expect, it } from "vitest";
import { apply as applyHost } from "../index.ts";
import { apply, inject } from "./index.ts";
Expand Down Expand Up @@ -144,7 +145,23 @@ describe("mtmharness Host half", () => {

describe("mtmharness browser half", () => {
it("declares the combined service dependencies", () => {
expect(inject).toEqual(["slots", "locale", "settingsScope"]);
expect(inject).toEqual(["slots", "locale", "settingsScope", "connection"]);
});

it("waits for connection before the direct client entry runs", async () => {
const root = new Context();
for (const service of ["slots", "locale", "settingsScope"]) root.provide(service, {});
let seen: unknown;
const consumer = {
inject,
apply(ctx: { get(name: string): unknown }) { seen = ctx.get("connection"); },
};
const provider = {
apply(ctx: { provide(name: string, value: unknown): void }) { ctx.provide("connection", {}); },
};
const [consumerFiber, providerFiber] = await Promise.all([root.plugin(consumer), root.plugin(provider)]);
expect(seen).toBeDefined();
await Promise.all([consumerFiber.dispose(), providerFiber.dispose()]);
});

it("only exposes update actions for loopback connections", () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/mtmharness/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { apply as applyMtmConnect } from "../features/mtm-connect/client/index.t
import { apply as applySecondary } from "../features/secondary/client.ts";

export { applyCoding };
export const inject = ["slots", "locale", "settingsScope"];
export const inject = ["slots", "locale", "settingsScope", "connection"];

/** Register coding and secondary features under one plugin-owned lifecycle. */
export function apply(ctx: ClientContext): void {
Expand Down
12 changes: 6 additions & 6 deletions packages/mtmharness/src/features/coding/client/locales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ export const en: Record<MtmCodingLocaleKey, string> = {
ponytailSubagents: "Apply Ponytail to subagents",
ponytailSubagentsHint: "Carry the coding rules into child agents.",
rtkMode: "RTK mode",
rtkModeHint: "Rewrite transparently when supported; otherwise use inline guidance.",
rtkModeHint: "Use guidance for explicit RTK commands; transparent rewrite is unavailable with the current DSH tool contract.",
rtkModeOff: "Off",
rtkModeGuidance: "Guidance",
rtkModeAuto: "Automatic fallback",
rtkModeRewrite: "Transparent rewrite",
rtkModeAuto: "Guidance (default)",
rtkModeRewrite: "Unavailable rewrite",
modeOff: "Off",
modeLite: "Lite",
modeFull: "Full",
Expand Down Expand Up @@ -120,11 +120,11 @@ export const zh: Record<MtmCodingLocaleKey, string> = {
ponytailSubagents: "对子 agent 启用 Ponytail",
ponytailSubagentsHint: "将编程规则传递给子 agent。",
rtkMode: "RTK 模式",
rtkModeHint: "在支持时透明重写;否则使用内联指导。",
rtkModeHint: "使用指导显式调用 RTK;当前 DSH 工具契约不支持透明重写。",
rtkModeOff: "关闭",
rtkModeGuidance: "指导",
rtkModeAuto: "自动降级",
rtkModeRewrite: "透明重写",
rtkModeAuto: "指导(默认)",
rtkModeRewrite: "透明重写(不可用)",
modeOff: "关闭",
modeLite: "精简",
modeFull: "完整",
Expand Down
Loading
Loading