@curatogether/pi
Contribute structured biomedical research to CuraTogether from Pi
Package details
Install @curatogether/pi from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@curatogether/pi- Package
@curatogether/pi- Version
0.20.0- Published
- Aug 16, 2026
- Downloads
- 1,401/mo · 19/wk
- Author
- jonsch1
- License
- UNLICENSED
- Types
- extension, skill
- Size
- 1.3 MB
- Dependencies
- 4 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./dist/index.js"
],
"skills": [
"./skills"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
CuraTogether for Pi
Contribute structured biomedical research to public CuraTogether projects from Pi. The extension connects your CuraTogether account, checks out a project's active research, orchestrates bounded researcher and vocabulary harmonizer agents, validates a local publication draft, and publishes only after your explicit confirmation.
Install
You need Node.js 22.19 or newer and a CuraTogether account.
npm install -g @earendil-works/pi-coding-agent
pi install npm:@curatogether/pi
Pi requires a model provider. Start Pi and use /login if you have not already
connected one.
The package includes a pinned pi-web-access dependency for its isolated
research worker. You do not need to install that extension separately.
Start a project session
Create a dedicated folder and start Pi:
mkdir my-curatogether-research
cd my-curatogether-research
pi
Then run these commands inside Pi:
/login
/cura connect
/cura projects
/cura search <disease, gene, or project name>
/cura join <project-id>
/cura research <objective>
/cura connect opens CuraTogether in your browser. The resulting access token
is stored in your operating system's credential store, not in the research
folder or Pi session. /cura disconnect removes it.
Search does not join a project. /cura join shows the selected project and asks
for confirmation. Starting a research cycle selects a joined project, confirms
the project and objective, permanently binds the complete Pi session, and
downloads the project's active research. If you have joined more than one
project, CuraTogether asks which one to use. Start a new Pi session to work on
another project.
The folder will contain:
.curatogether/
binding.yaml
sessions/
<session-id>/
context/
project.yaml
research.yaml
statements.yaml
syntheses.yaml
index.yaml
manual/
statements/
syntheses/
journal/
runs/
<run-id>/
statements/
syntheses/
reconciliations/
sources/
workers/
manifest.yaml
status.yaml
events.jsonl
result.json
Each Pi session gets an isolated directory. Context is a replaceable, read-only
checkout. Drafts are sharded into one YAML file per statement, synthesis, journal
entry, and harmonizer result. /cura publish compiles these files in memory;
new versions never create a workspace-wide aggregate YAML. Update shards through
the CuraTogether tools instead of generic file-editing tools. Reopening the same
Pi session ID rehydrates its binding and completed research-run references from
this durable directory, so publication does not depend on the original process
remaining open.
Controlled research agents
The installed extension coexists with the rest of a user's Pi setup. In an
ordinary, unbound Pi session it adds /cura and its package skill without
replacing Pi's system prompt.
When /cura research <objective> runs, the researcher and harmonizers do not
inherit that environment. Each is a separate ephemeral Pi process launched
with extension, skill, prompt-template, theme, and context-file discovery
disabled. The extension then explicitly loads only the audited resources needed
for that role and passes an exact tool allowlist:
- Researcher: embedded project context, no filesystem tools,
web_search,fetch_content, andcura_search_indra. - Research web access is bounded in code to four searches and twelve distinct fetched documents. Search breadth is capped and automatic full-content downloads are disabled; repeated fetches are rejected.
- The extractor writes one complete statement template containing
{{subject}},{{predicate}}, and{{object}}. Subject and object slots are entity labels with pending CURIE placeholders. Quote verification and statement QC judge those labels and quotes; QC revises return to the extractor for more turns. The harmonizer maps only QC-accepted statements into schema-v4 claims; only then does the host ground their unique entity labels with the Gilda API in parallel. Leftover unresolved or mismatched CURIEs go to a dedicated conflict worker that can search, using the quote as evidence. The extractor and harmonizer never receive ontology identifiers to “fix”. The harmonizer first maps predicates whose names already exist exactly, then the agent maps only the remainder. Exact matches keep empty context arrays. - Harmonizer: only the CuraTogether vocabulary-category, vocabulary-search, and vocabulary-create tools, and only for predicates that did not exact-match.
The child system prompt replaces Pi's default coding prompt. The children have
no session file and cannot write the publication draft.
While a cycle runs, Pi shows the current action for each active subagent and
opens a local research console. The console streams each worker's full thinking,
tool calls (click for input/output), and model output. Structured status.yaml
records the current stage; events.jsonl is the conversation log.
Equivalent vocabulary proposals are normalized and consolidated by the batch harmonizer
rather than returned to the user as a manual task. Existing exact-name terms remain authoritative.
Malformed structured worker output gets one isolated, tool-free repair pass before the run fails.
Worker or service failures are reported as failures, not as requests for user review.
Fetched source bodies are moved out of the compact child transcript into content-addressed files under sources/.
Research and publication
Useful commands include:
| Command | Purpose |
|---|---|
/cura project |
Show the project bound to this session. |
/cura refresh |
Download the latest active project outputs. |
/cura status |
Show the binding, draft counts, and publication state. |
/cura research <objective> |
Run a discrete research iteration across active topics. |
/cura observe |
Open the local research console in the browser. |
/cura publish |
Validate, confirm, and atomically publish the draft. |
/cura research writes a structured event log for the run and opens a local
console at http://127.0.0.1:<port>/. Workers use the same model you selected
in Pi (/login, including a Codex subscription). The console is a session
workstation: topic backlog, pipeline tree, Trace / Output / Draft panes, and
Publish. Live sessions expose Stop, Run iteration, Reset, New
topic (blank or from published project topics), and Publish. /cura observe
reopens the latest run with the same controls when the session is still bound.
Events are stored at .curatogether/sessions/<session-id>/runs/<run-id>/events.jsonl.
Publication is always explicit. Before uploading, /cura publish shows the
number of outputs and warns that the complete research run and all child
prompts and JSONL streams—including tool calls and results—will become public
provenance and cannot be edited afterward. Cancelling uploads nothing.
Updates and removal
Pi owns the installed package and its dependency tree:
pi update npm:@curatogether/pi # update only CuraTogether
pi update --extensions # update every installed Pi package
pi remove npm:@curatogether/pi # uninstall CuraTogether
Updating the Pi client itself is separate: pi update self. CuraTogether pins
the audited web worker dependency; it changes only when a new CuraTogether
package version is installed.
Published installs use https://curatogether.org for the application API and
https://connectors.curatogether.org for all biomedical source connectors by
default. Either base URL can be overridden explicitly for development.
Local development
From the repository root:
corepack enable
pnpm install
pnpm --filter @curatogether/pi type-check
pnpm --filter @curatogether/pi build
pi install -l ./packages/pi
Run the live Gilda grounding regression benchmark (30 concepts, chemicals, genes, and proteins) with:
pnpm --filter @curatogether/pi benchmark:grounding
The research console is a Vite React app in packages/pi/console. After a
backend is serving (pnpm --filter @curatogether/pi exec tsx scripts/try-console.ts
or /cura observe), iterate on the UI with:
CURA_CONSOLE_PROXY=http://127.0.0.1:<console-port> pnpm --filter @curatogether/pi console:dev
Point the extension at local services before starting Pi:
export CURATOGETHER_URL=http://localhost:3000
export CURATOGETHER_CONNECTORS_URL=http://127.0.0.1:8010
pi
The Next.js app must use the same public origin in BETTER_AUTH_URL and
NEXT_PUBLIC_BETTER_AUTH_URL so the device-authorization return path matches.
See RELEASING.md for the npm release process.