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
34 changes: 32 additions & 2 deletions .mendcode/marketplace/index.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"version": 0,
"marketplace": {
"name": "MendCode Official Packages",
"source": "https://github.com/MendCode/mendcode-packages"
"name": "MendCode Official Marketplace",
"source": "https://github.com/MendCode/mendcode-marketplace"
},
"packs": [
{
Expand Down Expand Up @@ -76,6 +76,36 @@
"runtime": {
"extensions": 1
}
},
{
"id": "mendcode-marketplace-lab",
"version": "1.0.0",
"title": "MendCode Marketplace Lab",
"description": "Example package with a shell-backed widget, custom tool, page artifact, prompt mode, skill, and compact TUI profile.",
"tags": ["marketplace", "widgets", "tools", "pages", "example"],
"channel": "official",
"digest": {
"algorithm": "sha256",
"value": "3978003a5e38454b9669b18734b5b64b5eb330bc9993df316298f0ad0f68524a"
},
"compatibility": {
"mendcode": ">=0.1.14 <1.0.0",
"runtimePack": "^0"
},
"source": {
"type": "github",
"url": "packages/mendcode-marketplace-lab"
},
"runtime": {
"commands": 1,
"modes": 1,
"skills": 1,
"plugins": 1,
"tools": 1,
"pages": 1,
"prompts": 1,
"extensions": 1
}
}
]
}
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
# MendCode Official Packages
# MendCode Official Marketplace

This repository is the public package registry used by MendCode's default `official` source.
This repository is the public marketplace registry used by MendCode's default `official` source.

Packages are shareable `.mendcode` overlays. They can add commands, modes, skills, prompts, MCP config, widgets, and TUI profiles without replacing a user's local sessions, auth state, cache, runs, or personal customization files.
Marketplace packages are shareable `.mendcode` overlays. They can add commands, modes, skills, prompts, MCP config, custom tool calls, custom pages, shell-backed widgets, and TUI profiles without replacing a user's local sessions, auth state, cache, runs, or personal customization files.

## Install

```bash
mendcode packages search ""
mendcode packages show mendcode-starter
mendcode packages install mendcode-starter
mendcode marketplace search ""
mendcode marketplace show mendcode-starter
mendcode marketplace install mendcode-starter
```

For a non-default source:

```bash
mendcode packages add-source company --type github --url https://github.com/YourOrg/company-mendcode-packages.git --channel team
mendcode packages install company-standard company
mendcode marketplace add-source company --type github --url https://github.com/YourOrg/company-mendcode-marketplace.git --channel team
mendcode marketplace install company-standard company
```

## Packages
## Marketplace Packages

- `mendcode-starter`: onboarding command and skill for safe MendCode package usage.
- `mendcode-review`: review command, mode, and skill for evidence-backed code review.
- `mendcode-tui-compact`: compact TUI profile for dense terminal use.
- `mendcode-marketplace-lab`: example package with a shell-backed widget, custom tool, page artifact, prompt mode, skill, and compact TUI profile.

## Safety Contract

Official packages must not include secrets, auth state, local run history, cache output, generated runtime files, dependency folders, or binary payloads. Package install is an overlay under `.mendcode/packages/installed/<id>` and can be disabled or removed without deleting local project customization.
Official marketplace packages must not include secrets, auth state, local run history, cache output, generated runtime files, dependency folders, or binary payloads. Package install is an overlay under `.mendcode/packages/installed/<id>` and can be disabled or removed without deleting local project customization.

Every PR must pass package validation before review.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Marketplace Lab

Review this checkout as a MendCode marketplace package author. Verify package artifacts, public API usage, shell-widget memory bounds, and absence of secrets or local state.
6 changes: 6 additions & 0 deletions packages/mendcode-marketplace-lab/.mendcode/mendcode.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"plugin": ["./plugins/marketplace-lab.ts"],
"plugin_enabled": {
"mendcode.marketplace-lab": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Marketplace Lab Mode

Prioritize package authoring correctness:

- Use marketplace commands, not legacy package wording.
- Prefer public MendCode APIs over runtime internals.
- Treat widgets, pages, tools, prompts, modes, commands, and skills as separately reviewable artifacts.
- Keep shell integrations opt-in, bounded, and easy to stop.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default function marketplaceLabPage() {
return [
"Marketplace Lab Page",
"",
"Package pages are distributed under .mendcode/pages.",
"Use the public plugin API for live routes and widgets.",
].join("\n")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { createSignal } from "solid-js"
import type { TuiPluginApi } from "@mendcode/plugin/tui"

function lastLines(value: string, count: number) {
return value.split(/\r?\n/).filter(Boolean).slice(-count).join(" ")
}

export default {
id: "mendcode.marketplace-lab",
async tui(api: TuiPluginApi) {
const [output, setOutput] = createSignal("idle")
let stopShell: (() => void) | undefined

const startShell = () => {
stopShell?.()
const command =
process.env.MENDCODE_LAB_WIDGET_COMMAND ||
"printf 'marketplace lab\\n'; printf 'cwd: '; pwd; printf 'sessions: '; find .mendcode -maxdepth 2 -type f 2>/dev/null | wc -l"
const proc = api.shell.spawn(command, { maxBuffer: 8_000 })
const offOutput = proc.onOutput((event) => setOutput(lastLines(event.output, 3) || "running"))
const offExit = proc.onExit((event) => setOutput(`${lastLines(event.output, 3) || "done"} exit=${event.code}`))
stopShell = () => {
offOutput()
offExit()
void proc.stop()
}
}

api.ui.runtime.setWidget(
"mendcode.marketplace-lab.shell",
() => `Lab shell · ${output()}`,
{
placement: "sessionBottomDock",
order: 80,
title: "Lab shell",
width: 38,
minWidth: 24,
maxWidth: 60,
height: "auto",
interactive: true,
},
)

api.route.register([
{
name: "marketplace-lab",
render() {
return [
"Marketplace Lab",
"",
"This page is provided by a marketplace package.",
`Workspace: ${api.state.path.directory}`,
`Sessions: ${api.state.session.count()}`,
`Widget output: ${output()}`,
"",
"Use the command palette to start or stop the shell widget.",
].join("\n")
},
},
])

api.command.register(() => [
{
title: "Marketplace Lab: Open Page",
value: "marketplace-lab.open",
category: "Marketplace Lab",
onSelect() {
api.route.navigate("marketplace-lab")
},
},
{
title: "Marketplace Lab: Start Shell Widget",
value: "marketplace-lab.shell.start",
category: "Marketplace Lab",
onSelect: startShell,
},
{
title: "Marketplace Lab: Stop Shell Widget",
value: "marketplace-lab.shell.stop",
category: "Marketplace Lab",
onSelect() {
stopShell?.()
stopShell = undefined
setOutput("stopped")
},
},
])

api.ui.runtime.setStatus("mendcode.marketplace-lab", "Marketplace Lab", { order: 80 })

api.lifecycle.onDispose(() => {
stopShell?.()
api.ui.runtime.clearWidget("mendcode.marketplace-lab.shell")
api.ui.runtime.clearStatus("mendcode.marketplace-lab")
})
},
}
5 changes: 5 additions & 0 deletions packages/mendcode-marketplace-lab/.mendcode/prompt-mode.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"version": 0,
"mode": "full",
"live": "runtime-run-chat"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Marketplace Lab Full Prompt Notes

When this package is active, use custom memory tools only when memory must change. Do not run extractors or background memory workflows just because a message was answered.

When authoring widgets, prefer stable block updates and bounded shell output. For full-screen terminal apps, require a PTY-backed helper instead of pretending stdout pipes are a full terminal.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
printf "Marketplace Lab"
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Marketplace Lab

Use this skill when building or reviewing MendCode marketplace packages.

Checklist:

- Keep package artifacts under `.mendcode/`.
- Use public APIs from `@mendcode/plugin/tui`.
- Put assistant-facing custom tools in `.mendcode/tools`.
- Put package-owned page artifacts in `.mendcode/pages`.
- Keep shell-backed widgets bounded with `maxBuffer`.
- Do not include secrets, local sessions, caches, auth state, or binary payloads.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default {
description: "Inspect the installed Marketplace Lab package state.",
args: {},
execute: async () => {
return [
"Marketplace Lab is installed.",
"Available examples: shell-backed TUI widget, package route, custom tool, prompt mode, skill, and compact TUI profile.",
"Set MENDCODE_LAB_WIDGET_COMMAND to change the shell widget command.",
].join("\n")
},
}
91 changes: 91 additions & 0 deletions packages/mendcode-marketplace-lab/.mendcode/tui/profile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
{
"version": 0,
"profile": "marketplace-lab",
"promptChrome": {
"preset": "top-bottom",
"borderStyle": "single"
},
"promptStatus": {
"enabled": true,
"commandsHint": {
"visible": false
},
"placementByPreset": {
"box": "outside",
"top-bottom": "outside",
"minimal": "outside",
"ascii-box": "inside"
},
"left": [
{ "type": "builtin", "value": "mode" },
{ "type": "builtin", "value": "model" },
{ "type": "builtin", "value": "provider" }
],
"right": [],
"separator": " · ",
"scripts": {
"left": {
"enabled": true,
"command": "sh ./.mendcode/scripts/lab-status.sh",
"timeoutMs": 150,
"refreshMs": 5000,
"prepend": false
},
"right": {
"enabled": false,
"command": "",
"timeoutMs": 150,
"refreshMs": 1000,
"prepend": false
}
},
"script": {
"enabled": false,
"command": "",
"timeoutMs": 150,
"refreshMs": 1000,
"prepend": false
}
},
"presentation": {
"profile": "mendcode",
"reasoning": {
"defaultVisibility": "collapsed"
},
"activity": {
"style": "raw",
"placement": "current",
"maxLines": 1,
"collapseOnComplete": false,
"showModel": false,
"showTokens": true,
"showElapsed": true,
"showInterruptHint": true
}
},
"identity": {
"productName": "MendCode",
"tagline": "marketplace lab",
"logoMode": "title",
"logoFont": "mendcode"
},
"layout": {
"density": "compact",
"spacing": "tight",
"borders": "single",
"zones": {
"sidebar": { "enabled": false, "compact": false, "width": 0 },
"header": { "enabled": true },
"footer": { "enabled": true },
"session": { "transcript": "main", "metadata": "footer", "stickyUserHeader": true },
"prompt": { "position": "bottom", "rightSurface": false }
}
},
"widgets": {
"enabled": ["marketplace-lab-shell", "todo", "notes"],
"order": ["todo", "notes", "marketplace-lab-shell"],
"config": {
"marketplace-lab-shell": { "surface": "sessionBottomDock", "width": 38 }
}
}
}
33 changes: 33 additions & 0 deletions packages/mendcode-marketplace-lab/mend-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"version": 0,
"id": "mendcode-marketplace-lab",
"packageVersion": "1.0.0",
"title": "MendCode Marketplace Lab",
"description": "Example marketplace package with a shell-backed widget, custom tool, page artifact, prompt mode, skill, and TUI profile.",
"kind": "example",
"channel": "official",
"compatibility": {
"mendcode": ">=0.1.14 <1.0.0",
"runtimePack": "^0"
},
"artifacts": {
"commands": [".mendcode/commands/marketplace-lab.md"],
"modes": [".mendcode/modes/marketplace-lab.md"],
"skills": [".mendcode/skills/marketplace-lab/SKILL.md"],
"plugins": [".mendcode/plugins/marketplace-lab.ts"],
"tools": [".mendcode/tools/marketplace_lab.ts"],
"pages": [".mendcode/pages/marketplace-lab.ts"],
"prompts": [".mendcode/prompts/marketplace-lab-full.md"],
"extensions": [".mendcode/scripts/lab-status.sh"],
"tuiProfile": ".mendcode/tui/profile.json"
},
"distribution": {
"source": {
"type": "github",
"url": "packages/mendcode-marketplace-lab"
},
"trust": {
"signatureRequired": false
}
}
}
2 changes: 2 additions & 0 deletions scripts/validate-packages.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ function isApplyAllowed(rel) {
if (/^\.mendcode\/modes\/.+\.md$/.test(normalized)) return true
if (/^\.mendcode\/skills\/.+\/SKILL\.md$/.test(normalized)) return true
if (/^\.mendcode\/plugins\/.+\.(ts|js)$/.test(normalized)) return true
if (/^\.mendcode\/tools\/.+\.(ts|js)$/.test(normalized)) return true
if (/^\.mendcode\/pages\/.+$/.test(normalized)) return true
if (/^\.mendcode\/prompts\/.+\.md$/.test(normalized)) return true
if (/^\.mendcode\/mcp\/.+\.jsonc?$/.test(normalized)) return true
if (/^\.mendcode\/(widgets|components|scripts)\/.+$/.test(normalized)) return true
Expand Down
Loading