Confirmed by experiment: how a picker can assign skills per agent, and where the boundary is

This commit is contained in:
Sam
2026-11-11 08:58:23 +11:00
parent 47aacfd6d1
commit e44b0dff51
6 changed files with 527 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
---
type: context
id: context.paperclip-harness.paperclipai
title: paperclipai
status: active
source_of_truth: false
freshness: current
last_reviewed: 2026-11-10
tags:
- pack/paperclip-harness
- agent-memory/context
- autolearn
- rich-discovery
- repo/paperclipai
---
# paperclipai
## Rich discovery update (2026-11-10 21:14:03)
You are right, and my explanation was wrong in a way that matters. Correcting it.
## Per-agent skills already exist — that is the design
`GET /api/agents/{id}/skills` returns a **separate** `desiredSkills` list for every agent. Setting it is one call:
```
POST /api/agents/{id}/skills/sync
{ "mode": "replace",
"desiredSkills": ["company/<id>/nixos-workflow", "paperclipai/paperclip/paperclip"] }
```
`replace` means "this agent gets exactly these". At run time the adapter builds a directory from **that agent's** list and passes it as `--skill`. Builder had its own list; Documenter has another. Different agents, different skills, no picker needed.
What I got wrong: I let a narrow caveat ("links persist in the shared directory, so a skill can linger") stand in for the whole model, which read as "one set for everybody". It is not. The list is per agent and it is stored in Paperclip.
Skills are drawn from `GET /api/skills/available`, the company list, and the catalog — any of which can be assigned to any agent with the call above.
## Per-agent extensions: yes, through the command
The adapter's own configuration document says the command defaults to `pi` and is settable per agent, and so is `env`:
```
adapterConfig.command defaults to "pi"
adapterConfig.env KEY=VALUE pairs
```
So an agent gets its own wrapper:
```sh
#!/bin/sh
exec pi --extension npm:pi-memctx \
--extension git:https://gitea…/pi-config/extensions/tavily-search/index.ts \
"$@"
```
and `PATCH /api/agents/{id}` sets `adapterConfig.command` to that file. The adapter appends its own arguments (`--mode json`, `--session`, `--skill`, `--tools`, `--model`) to whatever the command is, so the wrapper is additive and cannot break the run. `env` is the same lever for environment.
That gives you, today and without touching Paperclip's source:
- one wrapper per role — `builder`, `documenter`, `reviewer` — each with its own extension list;
- a place to pass `--no-skills` if you ever want strict isolation;
- a place to keep the tool list deliberately small.
So the honest summary is: **skills are per agent in Paperclip already; extensions are per agent through the agent's command.** My "one global set" sentence was simply false.
## History — three options, best first
1. **Open the real Pi session in a pane.** Every run is written to `~/.pi/paperclips/<timestamp>-<agentId>.jsonl` and Pi is started with `--session <file>`. A pane running `pi --session <that file>` shows the actual conversation with Pi's own interface, and can be continued. No new code — a tool-pane entry that takes a file path. The only risk is two writers on one session file, so use it on finished runs or as a deliberate hand-over.
2. **A read-only transcript tab** in `Agents>agents`, drawn from the same JSONL. Integrated and safe, less faithful.
3. **`pi --resume`** in a tool pane and pick the session from Pi's own list. Simplest, but you find it by eye.
`GET /api/agents/{id}/task-sessions` maps task → session file and working directory, so options 1 and 2 have a reliable index.
Written into `docs/PLAN-INTERFACE.md` as a correction; committed as `47aacfd`. Nothing in the running layout changed.
If you want, the next build can be small and specific: an `Agents>skills` tab that lists an agent's skills and adds or removes them with those two calls, and a `t` tool-pane entry that opens a chosen Pi session. Say which.
## Source paths observed
- `nix/store/rg248h9sz8dylm8p6a9w9fj4zrv4sgm5-pi-coding-agent-0.82.1/lib/node_modules/pi-monorepo/docs/usage.md`
- `paperclipai/paperclip/paperclip`
- `api/skills/available`
- `pi-config/extensions/tavily-search/index.ts`
## Evidence
- Confidence: 84%
- Reason: Update component/repository context with detailed discovered structure and configuration
## Related
- [[packs/paperclip-harness/00-system/pi-agent/memory-manifest|Memory Manifest]]
## Related learned memories <!-- same-turn-2026-11-10 21:14:03 -->
- session: [[packs/paperclip-harness/80-sessions/paperclip-pi-adapter-per-agent-skills-and-per-agent-extensio|Paperclip + Pi adapter: per-agent skills and per-agent extensions]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-paperclipai-2026-11-10-21-14-03|Rich discovery: paperclipai 2026-11-10 21:14:03]]
- context: [[packs/paperclip-harness/20-context/paperclipai|paperclipai]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|paperclipai deployment operations]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|paperclipai repository structure and configuration patterns]]

View File

@@ -1805,3 +1805,88 @@ Committed as `77014d0` — documentation only, nothing in the running layout cha
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-pi-2026-11-10-21-03-21|Rich discovery: .pi 2026-11-10 21:03:21]]
- context: [[packs/paperclip-harness/20-context/home|.pi]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|.pi deployment operations]]
---
## Update (2026-11-10 21:14:03)
## Structural/configuration observations (2026-11-10 21:14:03)
You are right, and my explanation was wrong in a way that matters. Correcting it.
## Per-agent skills already exist — that is the design
`GET /api/agents/{id}/skills` returns a **separate** `desiredSkills` list for every agent. Setting it is one call:
```
POST /api/agents/{id}/skills/sync
{ "mode": "replace",
"desiredSkills": ["company/<id>/nixos-workflow", "paperclipai/paperclip/paperclip"] }
```
`replace` means "this agent gets exactly these". At run time the adapter builds a directory from **that agent's** list and passes it as `--skill`. Builder had its own list; Documenter has another. Different agents, different skills, no picker needed.
What I got wrong: I let a narrow caveat ("links persist in the shared directory, so a skill can linger") stand in for the whole model, which read as "one set for everybody". It is not. The list is per agent and it is stored in Paperclip.
Skills are drawn from `GET /api/skills/available`, the company list, and the catalog — any of which can be assigned to any agent with the call above.
## Per-agent extensions: yes, through the command
The adapter's own configuration document says the command defaults to `pi` and is settable per agent, and so is `env`:
```
adapterConfig.command defaults to "pi"
adapterConfig.env KEY=VALUE pairs
```
So an agent gets its own wrapper:
```sh
#!/bin/sh
exec pi --extension npm:pi-memctx \
--extension git:https://gitea…/pi-config/extensions/tavily-search/index.ts \
"$@"
```
and `PATCH /api/agents/{id}` sets `adapterConfig.command` to that file. The adapter appends its own arguments (`--mode json`, `--session`, `--skill`, `--tools`, `--model`) to whatever the command is, so the wrapper is additive and cannot break the run. `env` is the same lever for environment.
That gives you, today and without touching Paperclip's source:
- one wrapper per role — `builder`, `documenter`, `reviewer` — each with its own extension list;
- a place to pass `--no-skills` if you ever want strict isolation;
- a place to keep the tool list deliberately small.
So the honest summary is: **skills are per agent in Paperclip already; extensions are per agent through the agent's command.** My "one global set" sentence was simply false.
## History — three options, best first
1. **Open the real Pi session in a pane.** Every run is written to `~/.pi/paperclips/<timestamp>-<agentId>.jsonl` and Pi is started with `--session <file>`. A pane running `pi --session <that file>` shows the actual conversation with Pi's own interface, and can be continued. No new code — a tool-pane entry that takes a file path. The only risk is two writers on one session file, so use it on finished runs or as a deliberate hand-over.
2. **A read-only transcript tab** in `Agents>agents`, drawn from the same JSONL. Integrated and safe, less faithful.
3. **`pi --resume`** in a tool pane and pick the session from Pi's own list. Simplest, but you find it by eye.
`GET /api/agents/{id}/task-sessions` maps task → session file and working directory, so options 1 and 2 have a reliable index.
Written into `docs/PLAN-INTERFACE.md` as a correction; committed as `47aacfd`. Nothing in the running layout changed.
If you want, the next build can be small and specific: an `Agents>skills` tab that lists an agent's skills and adds or removes them with those two calls, and a `t` tool-pane entry that opens a chosen Pi session. Say which.
## Source paths observed
- `nix/store/rg248h9sz8dylm8p6a9w9fj4zrv4sgm5-pi-coding-agent-0.82.1/lib/node_modules/pi-monorepo/docs/usage.md`
- `paperclipai/paperclip/paperclip`
- `api/skills/available`
- `pi-config/extensions/tavily-search/index.ts`
## Evidence
- Confidence: 82%
- Reason: Captured factual repo structure/configuration patterns from rich discovery
## Related learned memories <!-- same-turn-2026-11-10 21:14:03 -->
- session: [[packs/paperclip-harness/80-sessions/paperclip-pi-adapter-per-agent-skills-and-per-agent-extensio|Paperclip + Pi adapter: per-agent skills and per-agent extensions]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-paperclipai-2026-11-10-21-14-03|Rich discovery: paperclipai 2026-11-10 21:14:03]]
- context: [[packs/paperclip-harness/20-context/paperclipai|paperclipai]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|paperclipai deployment operations]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|paperclipai repository structure and configuration patterns]]

View File

@@ -515,3 +515,88 @@ Committed as `77014d0` — documentation only, nothing in the running layout cha
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-pi-2026-11-10-21-03-21|Rich discovery: .pi 2026-11-10 21:03:21]]
- context: [[packs/paperclip-harness/20-context/home|.pi]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|.pi deployment operations]]
---
## Update (2026-11-10 21:14:03)
## Deployment/runbook details discovered (2026-11-10 21:14:03)
You are right, and my explanation was wrong in a way that matters. Correcting it.
## Per-agent skills already exist — that is the design
`GET /api/agents/{id}/skills` returns a **separate** `desiredSkills` list for every agent. Setting it is one call:
```
POST /api/agents/{id}/skills/sync
{ "mode": "replace",
"desiredSkills": ["company/<id>/nixos-workflow", "paperclipai/paperclip/paperclip"] }
```
`replace` means "this agent gets exactly these". At run time the adapter builds a directory from **that agent's** list and passes it as `--skill`. Builder had its own list; Documenter has another. Different agents, different skills, no picker needed.
What I got wrong: I let a narrow caveat ("links persist in the shared directory, so a skill can linger") stand in for the whole model, which read as "one set for everybody". It is not. The list is per agent and it is stored in Paperclip.
Skills are drawn from `GET /api/skills/available`, the company list, and the catalog — any of which can be assigned to any agent with the call above.
## Per-agent extensions: yes, through the command
The adapter's own configuration document says the command defaults to `pi` and is settable per agent, and so is `env`:
```
adapterConfig.command defaults to "pi"
adapterConfig.env KEY=VALUE pairs
```
So an agent gets its own wrapper:
```sh
#!/bin/sh
exec pi --extension npm:pi-memctx \
--extension git:https://gitea…/pi-config/extensions/tavily-search/index.ts \
"$@"
```
and `PATCH /api/agents/{id}` sets `adapterConfig.command` to that file. The adapter appends its own arguments (`--mode json`, `--session`, `--skill`, `--tools`, `--model`) to whatever the command is, so the wrapper is additive and cannot break the run. `env` is the same lever for environment.
That gives you, today and without touching Paperclip's source:
- one wrapper per role — `builder`, `documenter`, `reviewer` — each with its own extension list;
- a place to pass `--no-skills` if you ever want strict isolation;
- a place to keep the tool list deliberately small.
So the honest summary is: **skills are per agent in Paperclip already; extensions are per agent through the agent's command.** My "one global set" sentence was simply false.
## History — three options, best first
1. **Open the real Pi session in a pane.** Every run is written to `~/.pi/paperclips/<timestamp>-<agentId>.jsonl` and Pi is started with `--session <file>`. A pane running `pi --session <that file>` shows the actual conversation with Pi's own interface, and can be continued. No new code — a tool-pane entry that takes a file path. The only risk is two writers on one session file, so use it on finished runs or as a deliberate hand-over.
2. **A read-only transcript tab** in `Agents>agents`, drawn from the same JSONL. Integrated and safe, less faithful.
3. **`pi --resume`** in a tool pane and pick the session from Pi's own list. Simplest, but you find it by eye.
`GET /api/agents/{id}/task-sessions` maps task → session file and working directory, so options 1 and 2 have a reliable index.
Written into `docs/PLAN-INTERFACE.md` as a correction; committed as `47aacfd`. Nothing in the running layout changed.
If you want, the next build can be small and specific: an `Agents>skills` tab that lists an agent's skills and adds or removes them with those two calls, and a `t` tool-pane entry that opens a chosen Pi session. Say which.
## Source paths observed
- `nix/store/rg248h9sz8dylm8p6a9w9fj4zrv4sgm5-pi-coding-agent-0.82.1/lib/node_modules/pi-monorepo/docs/usage.md`
- `paperclipai/paperclip/paperclip`
- `api/skills/available`
- `pi-config/extensions/tavily-search/index.ts`
## Evidence
- Confidence: 83%
- Reason: Extracted repeatable deploy/configuration procedure from rich discovery
## Related learned memories <!-- same-turn-2026-11-10 21:14:03 -->
- session: [[packs/paperclip-harness/80-sessions/paperclip-pi-adapter-per-agent-skills-and-per-agent-extensio|Paperclip + Pi adapter: per-agent skills and per-agent extensions]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-paperclipai-2026-11-10-21-14-03|Rich discovery: paperclipai 2026-11-10 21:14:03]]
- context: [[packs/paperclip-harness/20-context/paperclipai|paperclipai]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|paperclipai deployment operations]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|paperclipai repository structure and configuration patterns]]

View File

@@ -0,0 +1,67 @@
---
type: session
id: session.paperclip-harness.paperclip-pi-adapter-per-agent-skills-and-per-agent-extensio
title: Paperclip + Pi adapter: per-agent skills and per-agent extensions
status: active
source_of_truth: false
freshness: current
last_reviewed: 2026-11-10
tags:
- pack/paperclip-harness
- agent-memory/session
- paperclip
- pi-coding-agent
- per-agent-skills
- per-agent-extensions
- pi_local-adapter
- task-sessions
- session-history
---
# Paperclip + Pi adapter: per-agent skills and per-agent extensions
Discovery turn correcting an earlier wrong claim that Paperclip supports only one skill set for all agents.
Per-agent skills (already implemented in Paperclip):
- `GET /api/agents/{id}/skills` returns a separate `desiredSkills` list for each agent.
- `POST /api/agents/{id}/skills/sync` with body `{ "mode": "add" | "remove" | "replace", "desiredSkills": [string | { key, versionId(uuid|null) }] }` syncs an agent's skills. `replace` means exactly that list.
- At run time the pi_local adapter builds a skill directory from that agent's list and passes it to Pi as `--skill`.
- Skill sources: `GET /api/skills/available`, the company list, and the skill catalog. Key format examples seen: `company/<id>/nixos-workflow`, `paperclipai/paperclip/paperclip`.
- Caveat: skill links persist in a shared directory, so a skill can linger if not replaced.
Per-agent extensions (no Paperclip source change needed):
- pi_local adapter config document (`agentConfigurationDoc` in adapter index.js) states `command` defaults to `pi` and `env` is KEY=VALUE; both are per agent.
- `PATCH /api/agents/{id}` with `adapterConfig.command` set to a wrapper script gives each agent its own extension list. Example wrapper: `#!/bin/sh\nexec pi --extension npm:pi-memctx --extension git:https://.../extensions/tavily-search/index.ts "$@"`.
- The adapter appends its own args (`--mode json`, `--session`, `--skill`, `--tools`, `--model`) to the command, so a wrapper is additive/safe.
- `adapterConfig.env` is the same lever for env per agent.
- Suggested role wrappers: `builder`, `documenter`, `reviewer`.
Pi runtime facts (pi-coding-agent):
- Paperclip runs Pi with `--session <file>`; sessions live at `~/.pi/paperclips/<timestamp>-<agentId>.jsonl`.
- `GET /api/agents/{id}/task-sessions` maps task -> session file and cwd.
- Pi bash-tool env vars: `PI_CODING_AGENT`, `PI_SESSION_ID`, `PI_SESSION_FILE`, `PI_PROVIDER`, `PI_MODEL`, `PI_REASONING_LEVEL`. `PI_OFFLINE` configures Pi. Inspect `$PI_PROVIDER/$PI_MODEL` instead of inferring from prompt.
- `pi -c/--continue` continues most recent session; `pi -r/--resume` browses sessions.
History-viewing options, best first:
1. Tool pane running `pi --session <jsonl>` on a finished run (risk: two writers on one session file).
2. Read-only transcript tab in `Agents>agents` from the same JSONL.
3. `pi --resume` in a tool pane and pick by eye.
Repo/files touched: correction written to `docs/PLAN-INTERFACE.md`; commit `47aacfd`. Nothing in the running layout changed. Sandbox install pin: `npm install -g @earendil-works/pi-coding-agent@0.74.0` (adapter) while Nix has pi-coding-agent 0.82.1. Follow-ups the user could pick: an `Agents>skills` tab (list/add/remove via the two API calls) and a `t` tool-pane entry to open a chosen Pi session.
## Evidence
- Confidence: 90%
- Reason: Rich discovery snapshot with concrete API endpoints, adapter config levers, session paths, and commit reference that a future agent can reuse.
## Related
- [[packs/paperclip-harness/00-system/pi-agent/memory-manifest|Memory Manifest]]
## Related learned memories <!-- same-turn-2026-11-10 21:14:03 -->
- session: [[packs/paperclip-harness/80-sessions/paperclip-pi-adapter-per-agent-skills-and-per-agent-extensio|Paperclip + Pi adapter: per-agent skills and per-agent extensions]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-paperclipai-2026-11-10-21-14-03|Rich discovery: paperclipai 2026-11-10 21:14:03]]
- context: [[packs/paperclip-harness/20-context/paperclipai|paperclipai]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|paperclipai deployment operations]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|paperclipai repository structure and configuration patterns]]

View File

@@ -0,0 +1,104 @@
---
type: session
id: session.paperclip-harness.rich-discovery-paperclipai-2026-11-10-21-14-03
title: Rich discovery: paperclipai 2026-11-10 21:14:03
status: active
source_of_truth: false
freshness: current
last_reviewed: 2026-11-10
tags:
- pack/paperclip-harness
- agent-memory/session
- autolearn
- rich-discovery
- repo/paperclipai
---
# Rich discovery: paperclipai 2026-11-10 21:14:03
Sanitized rich discovery snapshot captured automatically from the completed turn.
## Source paths observed
- `nix/store/rg248h9sz8dylm8p6a9w9fj4zrv4sgm5-pi-coding-agent-0.82.1/lib/node_modules/pi-monorepo/docs/usage.md`
- `paperclipai/paperclip/paperclip`
- `api/skills/available`
- `pi-config/extensions/tavily-search/index.ts`
## Final answer snapshot
You are right, and my explanation was wrong in a way that matters. Correcting it.
## Per-agent skills already exist — that is the design
`GET /api/agents/{id}/skills` returns a **separate** `desiredSkills` list for every agent. Setting it is one call:
```
POST /api/agents/{id}/skills/sync
{ "mode": "replace",
"desiredSkills": ["company/<id>/nixos-workflow", "paperclipai/paperclip/paperclip"] }
```
`replace` means "this agent gets exactly these". At run time the adapter builds a directory from **that agent's** list and passes it as `--skill`. Builder had its own list; Documenter has another. Different agents, different skills, no picker needed.
What I got wrong: I let a narrow caveat ("links persist in the shared directory, so a skill can linger") stand in for the whole model, which read as "one set for everybody". It is not. The list is per agent and it is stored in Paperclip.
Skills are drawn from `GET /api/skills/available`, the company list, and the catalog — any of which can be assigned to any agent with the call above.
## Per-agent extensions: yes, through the command
The adapter's own configuration document says the command defaults to `pi` and is settable per agent, and so is `env`:
```
adapterConfig.command defaults to "pi"
adapterConfig.env KEY=VALUE pairs
```
So an agent gets its own wrapper:
```sh
#!/bin/sh
exec pi --extension npm:pi-memctx \
--extension git:https://gitea…/pi-config/extensions/tavily-search/index.ts \
"$@"
```
and `PATCH /api/agents/{id}` sets `adapterConfig.command` to that file. The adapter appends its own arguments (`--mode json`, `--session`, `--skill`, `--tools`, `--model`) to whatever the command is, so the wrapper is additive and cannot break the run. `env` is the same lever for environment.
That gives you, today and without touching Paperclip's source:
- one wrapper per role — `builder`, `documenter`, `reviewer` — each with its own extension list;
- a place to pass `--no-skills` if you ever want strict isolation;
- a place to keep the tool list deliberately small.
So the honest summary is: **skills are per agent in Paperclip already; extensions are per agent through the agent's command.** My "one global set" sentence was simply false.
## History — three options, best first
1. **Open the real Pi session in a pane.** Every run is written to `~/.pi/paperclips/<timestamp>-<agentId>.jsonl` and Pi is started with `--session <file>`. A pane running `pi --session <that file>` shows the actual conversation with Pi's own interface, and can be continued. No new code — a tool-pane entry that takes a file path. The only risk is two writers on one session file, so use it on finished runs or as a deliberate hand-over.
2. **A read-only transcript tab** in `Agents>agents`, drawn from the same JSONL. Integrated and safe, less faithful.
3. **`pi --resume`** in a tool pane and pick the session from Pi's own list. Simplest, but you find it by eye.
`GET /api/agents/{id}/task-sessions` maps task → session file and working directory, so options 1 and 2 have a reliable index.
Written into `docs/PLAN-INTERFACE.md` as a correction; committed as `47aacfd`. Nothing in the running layout changed.
If you want, the next build can be small and specific: an `Agents>skills` tab that lists an agent's skills and adds or removes them with those two calls, and a `t` tool-pane entry that opens a chosen Pi session. Say which.
## Evidence
- Confidence: 86%
- Reason: Preserve full sanitized discovery detail from a rich investigation turn
## Related
- [[packs/paperclip-harness/00-system/pi-agent/memory-manifest|Memory Manifest]]
## Related learned memories <!-- same-turn-2026-11-10 21:14:03 -->
- session: [[packs/paperclip-harness/80-sessions/paperclip-pi-adapter-per-agent-skills-and-per-agent-extensio|Paperclip + Pi adapter: per-agent skills and per-agent extensions]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-paperclipai-2026-11-10-21-14-03|Rich discovery: paperclipai 2026-11-10 21:14:03]]
- context: [[packs/paperclip-harness/20-context/paperclipai|paperclipai]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|paperclipai deployment operations]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|paperclipai repository structure and configuration patterns]]

View File

@@ -490,3 +490,88 @@ deliberately small.
`GET /api/agents/{id}/task-sessions` maps task → session file and working directory, so option
1 and 2 both have a reliable index and neither needs guessing.
---
# Confirmed: what the picker emulation needs, and what it can actually do
Researched by doing it, on this machine, with the board key. Everything below returned 200 or
201 unless it says otherwise.
## The gap, measured
| Set | Where | Count |
|---|---|---|
| what the pi-config picker lists | `~/.agents/skills` | **21** (archify, caveman, nixos-workflow, tuios, …) |
| what Paperclip can assign | `GET /api/companies/{id}/skills` | **9** (agentmail, obsidian-cli, paperclip, project-docs, system-architect, …) |
So eleven skills a person can see in the picker cannot be given to a Paperclip agent today,
because Paperclip has never heard of them. That is the whole problem, and it is smaller than
it looked.
## What works, in order
1. **Copy the skill into the company's managed directory.** A local import is refused from
anywhere else — `POST …/skills/import` with a path under `~/.agents` returned **403
`skill_workspace_boundary_denied`**, "Import from a configured Paperclip workspace or the
company managed-skill directory". Copying to
`~/.paperclip/instances/default/skills/<companyId>/<name>` and importing that path returned
**201**:
```
{"key": "local/9a9eba3826/nixos-workflow", "slug": "nixos-workflow", …}
```
2. **Assign it to one agent, and only that agent**:
```
POST /api/agents/{agentId}/skills/sync
{"mode": "add", "desiredSkills": ["local/9a9eba3826/nixos-workflow"]} → 200
```
Verified on `Documenter`: its list went from three skills to four and back to three after a
`remove`. Different agents, different lists — as expected.
3. **Extensions have no Paperclip equivalent.** `~/.agents/extensions` holds them; Paperclip's
skill model does not. The per-agent lever is `adapterConfig.command`, which defaults to `pi`
and is appended to by the adapter. A wrapper per agent that passes `--extension …` and then
`exec pi "$@"` is the equivalent of `pi-config` for a Paperclip run.
## So the emulation is this, and nothing more
A picker that does what `pi-config`'s does, for Paperclip agents:
- **reads** `~/.agents/skills` and `~/.agents/extensions` (the same source the picker uses),
the company skill list, and the chosen agent's `desiredSkills`;
- **marks** each entry: available but not in Paperclip · in Paperclip · on this agent;
- **on choosing** an unavailable skill: copy it into the managed directory, import it, then
`skills/sync` it onto that agent;
- **on removing**: `skills/sync` with `remove`;
- **for an extension**: add it to that agent's wrapper file and point
`adapterConfig.command` at the wrapper.
That is a small command or one panel, not a new subsystem, and every step above is already
verified.
## A change made while checking this
`nixos-workflow` was copied into the company's managed directory and imported, so it is now in
Paperclip's list and can be assigned to any agent. It is assigned to nobody. Nothing else was
changed; `Documenter`'s skills were put back exactly as they were.
## Pi history — the cheap answer is probably enough
The instinct is right. Every run is already a file:
```
~/.pi/paperclips/<timestamp>-<agentId>.jsonl 178 of them here
```
`GET /api/agents/{id}/task-sessions` maps a task to its session file and folder. So the
cheapest useful thing is a tool-pane entry that opens `~/.pi/paperclips` in Yazi, or a pane
running `pi --resume` that lists sessions and opens one with Pi's own interface. Both are
minutes of work and neither invents anything.
A transcript tab inside `Agents>agents` is the integration option: read the JSONL, draw the
messages, no second process. Worth doing only if the file browser feels like a detour after a
week of use. Recommendation: do the cheap one now, decide later.