@curatogether/pi

Contribute structured biomedical research to CuraTogether from Pi

Packages

Package details

extensionskill

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, and cura_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.