Skip to content
Development
Skill

/penguin-plugin

Use for workflows — the tabs and pages beside the chat, with server code behind them, that an Agent keeps in its own `workflows/` folder inside PenguinHarness — building one, changing it, showing it as the whole app, restoring an earlier version, and removing a tab or a whole

BOOST
From plugin
penguin-harness
2.5k34 skills
Install
$ npx -y skills add Prism-Shadow/penguin-harness --skill penguin-plugin --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/penguin-plugin

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use for workflows — the tabs and pages beside the chat, with server code behind them, that an Agent keeps in its own `workflows/` folder inside PenguinHarness — building one, changing it, showing it as the whole app, restoring an earlier version, and removing a tab or a whole

SKILL.md

penguin-plugin.SKILL.md
name: penguin-plugin
description: Use for workflows — the tabs and pages beside the chat, with server code behind them, that an Agent keeps in its own `workflows/` folder inside PenguinHarness — building one, changing it, showing it as the whole app, restoring an earlier version, and removing a tab or a whole workflow when the user wants the custom UI gone.
version: 2026.10.12.2

Penguin plugins: workflows

Inside PenguinHarness an Agent can hold *workflows*: small plugin packages in its own directory, written in TypeScript, that the server boots as module trees, shows as tabs beside the chat, reloads on every file change, and versions so any edit can be undone. This is the same module mechanism the server itself is built from — manifests as data, everything checked before any code runs — so a workflow that does not type-check, that was written against an interface version this server no longer fits, or whose manifests do not hold together fails to load with the problem named, while the previous version keeps serving.

A workflow is a plugin of the server's own kind, which is where this skill's name comes from. It is not a program that reaches an agent from outside, so it takes neither of the penguin-sdk skill's two ways, and that skill's question does not apply to it.

Before you start

If the user's message only invokes this skill (e.g. "use penguin-plugin skill") without saying what the workflow is for, ask the user what they want it to do. Once the request is concrete, do **not** ask follow-up questions: build it end to end and list the assumptions you made in your final reply. A request to undo, revert or remove the UI is the exception: work out which of the four in *Undoing, reverting, removing* is meant first.

Start here — the whole loop is files

You need nothing but your file tools: no HTTP API, no port, no login, no server source. Do not go looking for the running server, its bundle or a checkout of the repository, and do not probe its API — everything you need to know is written into the workflow folder by the server itself.

1. *Where:* your Agent directory is `<App Data Dir>/agents/<Agent ID>/` — both values are in the Environment section of your system prompt. Workflows live in its `workflows/` folder (create it if it is missing); `ls` it to see what already exists before you add or change anything. 2. *Scaffold:* write the three files below — `package.json`, a minimal `index.ts`, one page under `ui/`. The server notices the folder within a second or two. 3. *Read what the server wrote back:* `.build/status.json` is the result of the last load — `{ ok, revision, checkedAt, error, tabs, hints }`. `ok: false` carries the compiler's or the checker's message with file, line and reason; fix that and look again. `ok: true` with an empty `tabs` means NOTHING shows in the user's chat page, however finished the page under `ui/` is: a page is only a file until `package.json` contributes a tab for it (see *Tabs are contributions* below), and `hints` spells out the entry to add. `.harness/README.md` is this same contract in the harness's own words — trust it over this skill if the two ever differ. `.harness/plugin.d.ts` is the exact `WorkflowHost` and `WorkflowMain` THIS harness offers — read it once instead of guessing at an interface. 4. *Iterate:* edit, wait a moment, read `.build/status.json` again. `checkedAt` changing tells you the server saw your edit. When it says `ok: true`, lists your tab under `tabs` and has no `hints`, the tab is already in the user's chat page — and not before. If `status.json` never appears, ask the user to open this Agent's chat page once (that is what starts the server watching the folder) rather than hunting for another way in.

What you do not need to find out by experiment: `host.run` resolves as soon as the turn has STARTED (not when it ends) with `{ sessionId, queued }`; `host.sessionStatus(id)` returns `"idle"`, `"running"` or `"compacting"`, so a run is finished when its Session is back to `"idle"`; `host.getState()` is synchronous and returns whatever was last passed to `setState` (`null` before the first one).

Layout

Layout, under `<root>/<project_id>/agents/<agent_id>/workflows/<workflow_id>/` (beside `agent_state/`):

package.json    "type": "module" and "penguin": { "modules": [ …manifests ] } — no dependency to install
index.ts        default export { modules: { <Name>: { create(ctx) } } } satisfies WorkflowPackage — TypeScript only
ui/             the workflow's pages and their assets; which of them are tabs is what the manifest contributes
state.json      the workflow's own document, kept by the server across reloads and rollbacks
.harness/       the server's: the types this workflow was written against (plugin.d.ts) and their interface table — read plugin.d.ts, never edit it
.build/         the server's: emitted JavaScript per revision, and status.json — the result of the last load; read it, never edit it

The manifest and the handler

The root manifest is named `Workflow`; it requires the host, provides the handler, and contributes its tabs:

{
  "name": "demo",
  "version": "0.1.0",
  "type": "module",
  "penguin": {
    "modules": [
      {
        "name": "Workflow",
        "requires": { "host": { "iface": "@prismshadow/penguin-server#WorkflowHost", "from": "Host" } },
        "provides": { "main": "@prismshadow/penguin-server#WorkflowMain" },
        "contributes": {
          "WebModule.sessionTabs": [
            { "id": "demo.main", "key": "main", "title": "Demo", "titleZh": "演示", "renderer": { "iframe": { "src": "ui/index.html" } } }
          ]
        }
      }
    ]
  }
}
import type { WorkflowPackage } from "@prismshadow/penguin-server/plugin";

export default {
  modules: {
    Workflow: {
      create({ use }) {
        const host = use.host;
        return {
          api: {
            main: {
              async handle(req) {
                // req = { method, path, q
Read more
Ships withpenguin-harness

🐧 Unified and Stable RSI Platform

Get the whole plugin
Stats
2,507
Stars
274
Forks
Active
Maintenance
TypeScript
Language
Apache-2.0
License
51m ago
Last commit
2mo ago
Created

Repo: Prism-Shadow/penguin-harness

Other skills on penguin-harness.