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
4 changes: 2 additions & 2 deletions packages/mtmharness/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@

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. In the default DSH `workspace-write` sandbox, follow the mounted Modern Go cache prompt and set `HOME`, `XDG_CACHE_HOME`, `GOPATH`, `GOMODCACHE`, and `GOCACHE` beneath the current workspace before the first wrapper call.
Modern Go Guidelines is a configured data-only package that exposes the externally installed `use-modern-go` skill. Its trusted manifest pins the JetBrains `v0.1.1` source and SHA-256; the first load downloads it into `$DSH_HOME/mtmharness/skills/modern-go`. Existing files are user-owned and are never overwritten automatically. In the default DSH `workspace-write` sandbox, follow the mounted Modern Go cache prompt and set `HOME`, `XDG_CACHE_HOME`, `GOPATH`, `GOMODCACHE`, and `GOCACHE` beneath the current workspace before the first wrapper call.

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 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.
The coding package configuration is data in `src/features/coding/config.json`: it owns package metadata, immutable GitHub commit pins, expected file digests, and static prompt declarations. The generic loader installs every configured `data-only` package into `$DSH_HOME/mtmharness/skills/<package>` and mounts its skills and prompt. Runtime-backed packages retain their DSH capability handlers while reusing the same manifest installer. 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 skill 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.

## DSH Web Plugin

Expand Down
2 changes: 1 addition & 1 deletion packages/mtmharness/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mtmharness",
"version": "0.9.5",
"version": "0.9.6",
"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
2 changes: 0 additions & 2 deletions packages/mtmharness/src/client/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ function clientBench(loopback = true): { registered: Registered[]; cleanups: Arr
codebaseMemoryEnabled: false,
dynamicCanvasEnabled: false,
codebaseMemoryAugmentHooks: true,
modernGoEnabled: true,
ponytailEnabled: true,
ponytailMode: "full",
ponytailSubagents: true,
Expand Down Expand Up @@ -99,7 +98,6 @@ async function hostBench(): Promise<{ registeredNamespaces: string[]; cleanups:
codebaseMemoryEnabled: false,
dynamicCanvasEnabled: false,
codebaseMemoryAugmentHooks: true,
modernGoEnabled: false,
ponytailEnabled: false,
ponytailMode: "full",
ponytailSubagents: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ export function MtmCodingCard(props: MtmCodingCardProps) {
<BooleanField t={t} label="codebaseMemoryEnabled" hint="codebaseMemoryEnabledHint" field={state.fields.codebaseMemoryEnabled} disabled={disabled} onChange={(value) => { props.edit("codebaseMemoryEnabled", String(value)); }} onReset={() => { props.resetField("codebaseMemoryEnabled"); }} />
<BooleanField t={t} label="dynamicCanvasEnabled" hint="dynamicCanvasEnabledHint" field={state.fields.dynamicCanvasEnabled} disabled={disabled} onChange={(value) => { props.edit("dynamicCanvasEnabled", String(value)); }} onReset={() => { props.resetField("dynamicCanvasEnabled"); }} />
<BooleanField t={t} label="codebaseMemoryAugmentHooks" hint="codebaseMemoryAugmentHooksHint" field={state.fields.codebaseMemoryAugmentHooks} disabled={disabled} onChange={(value) => { props.edit("codebaseMemoryAugmentHooks", String(value)); }} onReset={() => { props.resetField("codebaseMemoryAugmentHooks"); }} />
<BooleanField t={t} label="modernGoEnabled" hint="modernGoEnabledHint" field={state.fields.modernGoEnabled} disabled={disabled} onChange={(value) => { props.edit("modernGoEnabled", String(value)); }} onReset={() => { props.resetField("modernGoEnabled"); }} />
<BooleanField t={t} label="ponytailEnabled" hint="ponytailEnabledHint" field={state.fields.ponytailEnabled} disabled={disabled} onChange={(value) => { props.edit("ponytailEnabled", String(value)); }} onReset={() => { props.resetField("ponytailEnabled"); }} />
<div style={fieldStyle}>
{fieldLabel(t, "ponytailMode", mode, () => { props.resetField("ponytailMode"); }, disabled)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { MtmCodingCardController } from "./controller.ts";
function settingsScope() {
let snapshot = {
status: "ready",
value: { codebaseMemoryEnabled: true, dynamicCanvasEnabled: false, codebaseMemoryAugmentHooks: true, modernGoEnabled: true, ponytailEnabled: true, ponytailMode: "full", ponytailSubagents: true, rtkMode: "auto" },
value: { codebaseMemoryEnabled: true, dynamicCanvasEnabled: false, codebaseMemoryAugmentHooks: true, ponytailEnabled: true, ponytailMode: "full", ponytailSubagents: true, rtkMode: "auto" },
base: {},
user: {},
revision: 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const FIELD_NAMES = [
"codebaseMemoryEnabled",
"dynamicCanvasEnabled",
"codebaseMemoryAugmentHooks",
"modernGoEnabled",
"ponytailEnabled",
"ponytailMode",
"ponytailSubagents",
Expand Down
6 changes: 0 additions & 6 deletions packages/mtmharness/src/features/coding/client/locales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ export type MtmCodingLocaleKey =
| "dynamicCanvasEnabledHint"
| "codebaseMemoryAugmentHooks"
| "codebaseMemoryAugmentHooksHint"
| "modernGoEnabled"
| "modernGoEnabledHint"
| "ponytailEnabled"
| "ponytailEnabledHint"
| "ponytailMode"
Expand Down Expand Up @@ -59,8 +57,6 @@ export const en: Record<MtmCodingLocaleKey, string> = {
dynamicCanvasEnabledHint: "Load the pinned Canvas extension at runtime from its published artifact.",
codebaseMemoryAugmentHooks: "Codebase Memory context augmentation",
codebaseMemoryAugmentHooksHint: "Add bounded repository context around session and read/search events.",
modernGoEnabled: "Modern Go Guidelines",
modernGoEnabledHint: "Use JetBrains Modern Go guidance when working on Go code.",
ponytailEnabled: "Ponytail",
ponytailEnabledHint: "Apply the lazy-senior-dev rules and managed editable skills.",
ponytailMode: "Ponytail intensity",
Expand Down Expand Up @@ -111,8 +107,6 @@ export const zh: Record<MtmCodingLocaleKey, string> = {
dynamicCanvasEnabledHint: "从已发布的固定版本载荷中运行时加载 Canvas 扩展。",
codebaseMemoryAugmentHooks: "Codebase Memory 上下文增强",
codebaseMemoryAugmentHooksHint: "在会话和读/搜索事件周围加入有边界的仓库上下文。",
modernGoEnabled: "Modern Go Guidelines",
modernGoEnabledHint: "编写 Go 代码时使用 JetBrains Modern Go 指导。",
ponytailEnabled: "Ponytail",
ponytailEnabledHint: "启用 lazy senior dev 规则和可编辑的托管 skills。",
ponytailMode: "Ponytail 强度",
Expand Down
102 changes: 102 additions & 0 deletions packages/mtmharness/src/features/coding/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{
"packages": [
{
"id": "codebase-memory",
"label": "Codebase Memory",
"description": "Graph-first code discovery and repository context.",
"icon": "search",
"kind": "runtime-backed"
},
{
"id": "modern-go",
"label": "Modern Go Guidelines",
"description": "Version-specific guidance for modern Go code.",
"icon": "code",
"kind": "data-only",
"prompt": {
"order": 89,
"text": "Modern Go cache policy for DSH workspace-write shells: /home/code may be read-only. Before invoking the pinned wrapper, keep every write inside the current workspace. Linux/macOS: `cache=\"$PWD/.mtmharness-cache\"; mkdir -p \"$cache\"; env HOME=\"$cache/home\" XDG_CACHE_HOME=\"$cache/cache\" GOPATH=\"$cache/gopath\" GOMODCACHE=\"$cache/gopath/pkg/mod\" GOCACHE=\"$cache/go-build\" GOTOOLCHAIN=local sh \"<skill-dir>/scripts/run-tool.sh\" ...`. PowerShell: `$cache = Join-Path (Get-Location) \".mtmharness-cache\"; New-Item -ItemType Directory -Force $cache | Out-Null; $env:HOME = Join-Path $cache \"home\"; $env:XDG_CACHE_HOME = Join-Path $cache \"cache\"; $env:GOPATH = Join-Path $cache \"gopath\"; $env:GOMODCACHE = Join-Path $env:GOPATH \"pkg/mod\"; $env:GOCACHE = Join-Path $cache \"go-build\"; $env:LOCALAPPDATA = Join-Path $cache \"localappdata\"; $env:GOTOOLCHAIN = \"local\"; & \"<skill-dir>\\scripts\\run-tool.ps1\" ...`. Do not use the default HOME or request elevated sandbox access just for Go caches."
},
"skills": {
"repository": "https://github.com/JetBrains/go-modern-guidelines",
"revision": "937827b86eeff98f45150ce00236bc34a30ed20f",
"files": [
{
"name": "use-modern-go",
"path": "plugin/skills/use-modern-go/SKILL.md",
"sha256": "333346bebb212d7acded062cdeb1f5a01e421ebdab976c4c4fcb02cca31508f7"
},
{
"name": "use-modern-go",
"path": "plugin/skills/use-modern-go/scripts/VERSION",
"sha256": "d0b4f9120ba026c00fa23cb84b4e1620a2e6436592e58155a5151653179572c0"
},
{
"name": "use-modern-go",
"path": "plugin/skills/use-modern-go/scripts/run-tool.ps1",
"sha256": "7bd7bd8c8394e9cdbd290251b143e54639e527d52a1099135f1ba91edb5a677b"
},
{
"name": "use-modern-go",
"path": "plugin/skills/use-modern-go/scripts/run-tool.sh",
"sha256": "a593b2484834fc7d068e7cbe1a09f92b149ed61b9a07556ea50790d95f50a25b"
}
]
}
},
{
"id": "ponytail",
"label": "Ponytail",
"description": "Minimal coding rules and over-engineering reviews.",
"icon": "code",
"kind": "runtime-backed",
"skills": {
"repository": "https://github.com/dietrichgebert/ponytail",
"revision": "0a4dd63ad4541f4f655c4108a295916f3c1d8fda",
"files": [
{
"name": "ponytail",
"path": "skills/ponytail/SKILL.md",
"sha256": "1316a2f3f95741d2300b116fe0c2d81ce4a9568656ed0a62643f54aaf09957f2"
},
{
"name": "ponytail-audit",
"path": "skills/ponytail-audit/SKILL.md",
"sha256": "5560b8e383dbe2ddfddc873a1e2bf2e586e23e0cd7d995537482b2315331f6d1"
},
{
"name": "ponytail-debt",
"path": "skills/ponytail-debt/SKILL.md",
"sha256": "c84fba75f0ca12bfe83f9a78ea02fd125c5dd3f1fbb18124105a489937f284e6"
},
{
"name": "ponytail-gain",
"path": "skills/ponytail-gain/SKILL.md",
"sha256": "24e01d1c9715cb136ba1c4f1e52a95940c0193558b876828e537736480d6408b"
},
{
"name": "ponytail-help",
"path": "skills/ponytail-help/SKILL.md",
"sha256": "2264d1615117b02b0fd5a69ec84cd2757006471a78e4d6c22eed6d581c1d37a4"
},
{
"name": "ponytail-review",
"path": "skills/ponytail-review/SKILL.md",
"sha256": "40df33b58fc6ef889b93585733feb9566b76e9586efa7f376785c1e995197ac0"
}
]
}
},
{
"id": "rtk",
"label": "RTK",
"description": "Reduced shell output with transparent Bash rewriting.",
"icon": "terminal",
"kind": "runtime-backed",
"prompt": {
"order": 109,
"text": "RTK only concerns Bash shell commands. DSH read, grep, glob, PowerShell, and persistent terminal calls are not covered by this integration.\nRTK failures and unsupported commands pass through; RTK_DISABLED=1 disables one command."
}
}
]
}
40 changes: 7 additions & 33 deletions packages/mtmharness/src/features/coding/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Context, Fiber } from "@deepseek-ai/cordis";
import type {} from "@deepseek-ai/dsh-settings";
import { apply as applyCodebaseMemory, type Config as CodebaseMemoryConfig } from "./codebase-memory.js";
import { apply as applyPonytail } from "./ponytail.js";
import { applyManifestPackage, MTM_CODING_PACKAGES } from "./manifest.js";
import { applyDataOnlyPackages } from "./manifest.js";
import { apply as applyRtk } from "./rtk.js";
import {
MtmCodingSettingsSchema,
Expand All @@ -13,7 +13,7 @@ import {

export { buildMcpConfig, resolveConfig } from "./codebase-memory.js";
export { MtmCodingSettingsSchema, codebaseMemoryConfig } from "./types.js";
export { MTM_CODING_PACKAGES } from "./manifest.js";
export { MTM_CODING_PACKAGES, codingPackage } from "./manifest.js";
export type { MtmCodingPackageCatalog, MtmCodingPackageKind, MtmCodingPackageManifest, MtmCodingSkillSource } from "./manifest.js";
export {
extractHookContext,
Expand All @@ -36,12 +36,10 @@ const CodebaseMemoryFeature = {
apply: applyCodebaseMemory,
};

const ModernGoFeature = {
name: "mtm-coding-modern-go",
inject: ["skills"],
apply: async (ctx: Context): Promise<void> => {
await applyManifestPackage(ctx, MTM_CODING_PACKAGES.modernGo);
},
const DataOnlyFeature = {
name: "mtm-coding-data-only",
inject: ["skills", "systemPrompt"],
apply: applyDataOnlyPackages,
};

const PonytailFeature = {
Expand Down Expand Up @@ -81,12 +79,6 @@ function ponytailKey(settings: MtmCodingSettings): string {
});
}

function modernGoKey(settings: MtmCodingSettings): string {
return jsonKey({
enabled: settings.modernGoEnabled,
});
}

function rtkKey(settings: MtmCodingSettings): string {
return jsonKey({
mode: settings.rtkMode,
Expand All @@ -101,19 +93,16 @@ export async function apply(ctx: Context, rawConfig: MtmCodingConfig = {}): Prom
{ base: rawConfig },
);
let codebaseMemoryFiber: MountedFiber | undefined;
let modernGoFiber: MountedFiber | undefined;
let ponytailFiber: MountedFiber | undefined;
let rtkFiber: MountedFiber | undefined;
let activeCodebaseKey = "";
let activeModernGoKey = "";
let activePonytailKey = "";
let activeRtkKey = "";
let reconciling = Promise.resolve();
let stopped = false;

const reconcile = async (next: MtmCodingSettings): Promise<void> => {
const nextCodebaseKey = codebaseKey(next);
const nextModernGoKey = modernGoKey(next);
const nextPonytailKey = ponytailKey(next);
const nextRtkKey = rtkKey(next);

Expand All @@ -136,22 +125,6 @@ export async function apply(ctx: Context, rawConfig: MtmCodingConfig = {}): Prom
}
}

if (nextModernGoKey !== activeModernGoKey || (next.modernGoEnabled && modernGoFiber === undefined)) {
await dispose(modernGoFiber);
modernGoFiber = undefined;
activeModernGoKey = "";
if (next.modernGoEnabled) {
try {
modernGoFiber = await ctx.plugin(ModernGoFeature);
activeModernGoKey = nextModernGoKey;
} catch (error) {
ctx.logger.warn("mtm-coding: Modern Go is unavailable: " + String(error));
}
} else {
activeModernGoKey = nextModernGoKey;
}
}

if (nextPonytailKey !== activePonytailKey || (next.ponytailEnabled && ponytailFiber === undefined)) {
await dispose(ponytailFiber);
ponytailFiber = undefined;
Expand Down Expand Up @@ -207,5 +180,6 @@ export async function apply(ctx: Context, rawConfig: MtmCodingConfig = {}): Prom
await reconciling;
}, "mtm-coding.lifecycle");

if (typeof ctx.plugin === "function") await ctx.plugin(DataOnlyFeature);
await queueReconcile();
}
Loading
Loading