opencode already reads skills from ~/.claude/skills and ~/.agents/skills, so those needed nothing. The rest did. The manifest now links agents/AGENTS.md to ~/.config/opencode/AGENTS.md as well, beside the Claude Code and Codex names. opencode keeps its MCP servers in its own JSON config, with no file to point a symlink at, so link-mcp now writes them there too. It builds one entry per row of user/agents/mcp/servers with the same tokens it gives Claude Code, and adds ~/.claude/rules/*.md under instructions, since opencode does not read that directory by itself. Only those two keys change. The file is written private and swapped in whole because it now holds tokens, and a config with JSONC comments is left alone with a warning rather than rewritten without them.
76 lines
3.7 KiB
Markdown
76 lines
3.7 KiB
Markdown
# Personal content
|
|
|
|
Everything else in Panama is the desktop. This directory is the person using it.
|
|
|
|
The problem it solves is small and annoying: an agent skill, an SSH host alias
|
|
or a set of expansion triggers is worth having on every machine you own, but
|
|
none of it belongs in the shared configuration, and keeping it in a second
|
|
repository means remembering to update two things. So it lives here, tracked,
|
|
and one file says where each piece goes.
|
|
|
|
## What is in here
|
|
|
|
| Path | Goes to | Why |
|
|
| --- | --- | --- |
|
|
| `agents/AGENTS.md` | `~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md`, `~/.config/opencode/AGENTS.md` | Three tools, one file. These were byte-identical copies before this, waiting to disagree. |
|
|
| `agents/skills/` | `~/.agents/skills`, `~/.claude/skills` | Personal skills live once in the checkout. Both destinations use `linkdir` so Panama's shipped skills can live beside them. opencode reads both directories itself. |
|
|
| `agents/rules/` | `~/.claude/rules` | opencode loads these through `instructions` in its config, which `setup/scripts/link-mcp` writes. |
|
|
| `ssh/config` | `~/.ssh/config` | Host aliases only. Keys are per-machine and are never tracked. |
|
|
| `espanso/identity.yml` | `~/.config/espanso/match/identity.yml` | Copied, not linked, because a machine may add its own triggers. |
|
|
|
|
`manifest` is the authority; this table is a summary of it.
|
|
|
|
## The three kinds
|
|
|
|
`link` and `copy` mean what they say: one symlink, or one copy made only if the
|
|
destination is empty. `linkdir` is the third, and it exists because one
|
|
destination is no longer only ours.
|
|
|
|
Panama ships its own agent skills now (`skills/`, linked by
|
|
`setup/scripts/link-skills`), and they go to both skill homes. A directory
|
|
cannot be a symlink to two places, so both personal entries use `linkdir`: each
|
|
destination is a real directory, and each child of `user/agents/skills/` is
|
|
linked into it individually.
|
|
|
|
Two consequences, recorded rather than fixed:
|
|
|
|
- **A personal skill named like a shipped one shadows it.** `link-user` runs
|
|
after `link-skills` and displaces what it finds, so the personal one wins in
|
|
both skill homes.
|
|
- **A new personal skill needs a re-link to appear.** The whole-directory link
|
|
showed a newly created skill instantly; per-child links do not know about a
|
|
child that did not exist when they were made. Put new shared skills in
|
|
`user/agents/skills/`, then run `panama update` or `setup/scripts/link-user`.
|
|
A tool that installs directly into a home skill directory creates a
|
|
machine-local skill until it is moved into the checkout.
|
|
|
|
## It is off unless you say yes
|
|
|
|
The installer asks, naming the destinations, and the default is no. Nothing here
|
|
is linked on a machine that did not answer yes, and the answer is remembered in
|
|
`$XDG_STATE_HOME/panama/user-content` so upgrades do not re-ask.
|
|
|
|
That gating is the whole reason this can be tracked in a repository other people
|
|
clone. If you are that other person: delete what is in here, put your own in its
|
|
place, and answer yes. The mechanism is yours, the contents are not.
|
|
|
|
## Adding something
|
|
|
|
Put the file under `user/`, add a line to `manifest`, run:
|
|
|
|
```bash
|
|
./setup/scripts/link-user
|
|
```
|
|
|
|
Anything already at the destination is moved to `config/old/` rather than
|
|
deleted, under a name that says where it came from.
|
|
|
|
## What does not go in here
|
|
|
|
Anything secret. This repository is readable by anyone who finds it, and the
|
|
contract test refuses private keys, tokens and credentials outright. That means
|
|
no `~/.ssh/id_*`, no `.credentials.json`, no API keys, and no `settings.json`
|
|
carrying the names of hosts or people you would rather not publish. Machine
|
|
state that a tool rewrites on its own does not belong here either; it will churn
|
|
the git history for no benefit.
|