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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ the remote fixture and temporary credentials were removed afterward.
- `skills/` contains the canonical, harness-neutral skill files.
- `adapters/` contains per-harness frontmatter changes.
- `profiles/harnesses.json` defines supported harnesses and default paths.
- `docs/harness-adapters.md` records the official skill and session rules used
by each Harness adapter.
- `profiles/artifacts.json` defines optional artifacts and documents unsupported
harness-owned surfaces.
- `profiles/skills.json` defines the canonical skill inventory.
Expand Down
11 changes: 1 addition & 10 deletions adapters/opencode.json
Original file line number Diff line number Diff line change
@@ -1,10 +1 @@
{
"removeFrontmatter": {
"show-me-your-work": ["metadata"]
},
"frontmatter": {
"show-me-your-work": {
"compatibility": "Node.js 18 or newer is required for scripts/log.mjs."
}
}
}
{}
11 changes: 1 addition & 10 deletions adapters/pi.json
Original file line number Diff line number Diff line change
@@ -1,10 +1 @@
{
"removeFrontmatter": {
"show-me-your-work": ["metadata"]
},
"frontmatter": {
"show-me-your-work": {
"compatibility": "Node.js 18 or newer is required for scripts/log.mjs."
}
}
}
{}
47 changes: 47 additions & 0 deletions docs/harness-adapters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Harness adapter reference

This page records the vendor rules that shape mstack's adapters. The links point
to the official documentation used for each entry.

## Skill locations and frontmatter

| Harness | User skill root | Project skill root | Supported optional fields |
| --- | --- | --- | --- |
| Codex | `~/.agents/skills/` | `.agents/skills/` | Agent Skills fields; Codex-specific `agents/openai.yaml` lives beside each skill |
| Claude Code | `~/.claude/skills/` | `.claude/skills/` | `name`, `description`, `license`, `compatibility`, `metadata`, and Claude invocation fields |
| OpenCode | `~/.config/opencode/skills/` | `.opencode/skills/` | `license`, `compatibility`, and `metadata` |
| pi | `~/.pi/agent/skills/` | `.pi/skills/` | `license`, `compatibility`, `metadata`, `allowed-tools`, and `disable-model-invocation` |

Sources:

- [Codex skills](https://learn.chatgpt.com/docs/build-skills) and [Codex subagents](https://learn.chatgpt.com/docs/agent-configuration/subagents)
- [Claude Code skills](https://code.claude.com/docs/en/skills)
- [OpenCode skills](https://opencode.ai/docs/skills)
- [pi skills](https://pi.dev/docs/latest/skills)

The canonical tree keeps the Agent Skills fields that all supported Harnesses
can read. Claude Code accepts `metadata` but does not act on its contents, so
`adapters/claude.json` removes that map and surfaces the logger requirement in
the `compatibility` field instead. OpenCode and pi retain `metadata` because
their official references support it.

## Delegation and session records

Codex stores agent configuration in `.codex/agents/*.toml` and
`~/.codex/agents/*.toml`. Claude Code stores subagent definitions in
`.claude/agents/`. OpenCode stores agent definitions in `.opencode/agents/` or
`~/.config/opencode/agents/`. pi does not require a separate agent file for
skill use; it loads skills through discovery, the `--skill` flag, or the
`/skill:name` command.

Pi sessions are JSONL files under `~/.pi/agent/sessions/` by default. The
`PI_CODING_AGENT_SESSION_DIR` variable and `--session-dir` flag select another
root. Session records can form a tree through `id` and `parentId`, so a history
reader follows the active leaf instead of assuming that file order is one
linear transcript. Use `pi --export <session-file>` or `/export` when an HTML
record is needed. `--no-session` creates no persistent record.

The [pi session format](https://pi.dev/docs/latest/session-format), [pi
sessions](https://pi.dev/docs/latest/sessions), and [pi environment variables](https://pi.dev/docs/latest/environment-variables)
pages define these rules. The repository-specific history procedure is in
[`skills/recall/references/history-sources.md`](../skills/recall/references/history-sources.md).
31 changes: 31 additions & 0 deletions docs/pi-e2e-evidence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# pi end-to-end evidence

The three requested skills ran through pi `0.85.1` in a disposable Git
workspace on 2026-09-11. The installer copied all 50 skills into the workspace
project root at `.pi/skills/` with `HARNESS_SKILLS_PI_DIR=<workspace>/.pi/skills`.

Each command used pi's documented non-interactive mode, approved the project so
project-local skills were discoverable, emitted JSONL events, kept a session
directory for inspection, and allowed only read tools:

```text
pi -p --approve --mode json --session-dir .pi/e2e-sessions --tools read,grep,find,ls -- "/skill:meta-mode Read the installed skill before answering. Reply exactly mstack-meta-mode-ok."
pi -p --approve --mode json --session-dir .pi/e2e-sessions --tools read,grep,find,ls -- "/skill:architect Read the installed skill before answering. Reply exactly mstack-architect-ok."
pi -p --approve --mode json --session-dir .pi/e2e-sessions --tools read,grep,find,ls -- "/skill:create-verification-skill Read the installed skill before answering. Do not create files or run an app. Reply exactly mstack-create-verification-skill-ok."
```

Observed output:

```text
mstack-meta-mode-ok
mstack-architect-ok
mstack-create-verification-skill-ok
```

Each JSONL session contains a user `message_start` event whose text includes the
resolved `<skill name="..." location=".../.pi/skills/.../SKILL.md">` block,
followed by the marker in the assistant `message_end` event. The run proves
project skill discovery and invocation through pi. The marker prompts exercise
loading only. They do not claim that the skills completed their full workflows.
In particular, `create-verification-skill` did not drive an application because
this smoke workspace has no application to launch.
10 changes: 6 additions & 4 deletions scripts/install.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,12 @@ test("installs harness-specific frontmatter and preserves conflicts", () => {
const pi = readFileSync(piPath, "utf8");
assert.match(codex, /^metadata:/m);
assert.doesNotMatch(codex, /^compatibility:/m);
for (const adapted of [claude, opencode, pi]) {
assert.match(adapted, /^compatibility:/m);
assert.doesNotMatch(adapted, /^metadata:/m);
assert.doesNotMatch(adapted, /The included logger requires/i);
assert.match(claude, /^compatibility:/m);
assert.doesNotMatch(claude, /^metadata:/m);
for (const adapted of [opencode, pi]) {
assert.match(adapted, /^metadata:/m);
assert.match(adapted, /^ requirements: Node\.js 18 or newer for scripts\/log\.mjs$/m);
assert.doesNotMatch(adapted, /^compatibility:/m);
}

const marker = join(env.HARNESS_SKILLS_CODEX_DIR, "blast-radius", "marker.txt");
Expand Down
26 changes: 26 additions & 0 deletions skills/recall/references/history-sources.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,32 @@ Use `--sanitize` whenever exported data will leave the local machine. Do not
depend on OpenCode's internal database layout unless the CLI cannot provide the
required authorized record.

## Pi

Pi stores persistent sessions as JSONL trees. The default root is
`~/.pi/agent/sessions/`; project sessions are nested under a slugged directory
(`--<path>--`, with `/`, `\\`, and `:` replaced by `-`), and files are named
`<timestamp>_<session-id>.jsonl`. Set `PI_CODING_AGENT_SESSION_DIR` or pass
`--session-dir <path>` when using a custom root; the CLI flag takes precedence.

Prefer `pi -r`/`/resume` for interactive discovery and `pi --export <file>` (or
`/export`) when a readable HTML transcript is needed. For programmatic recall,
parse JSONL entries by `type` and follow the `id`/`parentId` tree from the active
leaf; do not treat the file as a linear transcript. Session versions 1 and 2
are migrated to version 3 when loaded. `--no-session` and RPC clients started
with `--no-session` do not create a persistent session.

Limit scans to the active workspace's slug and use the newest matching session
metadata before opening message contents. Session records can contain tool
outputs and extension data, so keep raw reads local unless the user explicitly
authorizes sharing.

Official references: [skills](https://pi.dev/docs/latest/skills),
[sessions](https://pi.dev/docs/latest/sessions),
[session format](https://pi.dev/docs/latest/session-format),
[environment variables](https://pi.dev/docs/latest/environment-variables),
and [RPC mode](https://pi.dev/docs/latest/rpc).

## Shared project records

Repository history, pull requests, issues, documentation, project chat, and
Expand Down