prime-agent-feature-factory

Prime Agent integration for feature-factory: the feature skill and its install-context script.

Packages

Package details

skill

Install prime-agent-feature-factory from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:prime-agent-feature-factory
Package
prime-agent-feature-factory
Version
0.13.0
Published
Oct 26, 2026
Downloads
2,125/mo · 370/wk
Author
jcarreira
License
MIT
Types
skill
Size
235.3 KB
Dependencies
1 dependency · 0 peers
Pi manifest JSON
{
  "skills": [
    "./skills"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

prime-agent-feature-factory

Prime Agent integration for feature-factory. It ships a Prime-specific feature skill, a context script and an unattended launcher, while preserving the factory package's canonical workflow and CLI-owned durable state.

Requires Prime Agent 0.10 or newer (the Rust host) and Node.js 22 or newer. 0.12.0 is the first version for that host: Prime 0.10 loads no JavaScript extensions, so the /feature command and the feature_factory_context tool that earlier versions registered no longer exist.

Install

prime-agent package install npm:prime-agent-feature-factory

The package manifest exposes the skill through pi.skills. Prime Agent runs a real npm install of the package, so the runtime feature-factory dependency is installed beside it.

Use

Interactively, in any Prime session:

/skill:feature [--autonomous | --headless] <ticket key | feature idea>

Unattended, use the launcher, not prime-agent -p:

node "$(npm root -g)/prime-agent-feature-factory/bin/launch.js" --cwd <repo> -- --autonomous <issue-number> < /dev/null

-p cannot drive a run on Prime 0.10. It runs the session in-process. On 0.10.0 rlm.spawn has no child runtime there and agent messaging does not exist. 0.10.1 runs subagents inline and has agent messaging, but agent_observe, which the skill needs, exists only in a daemon worker. The skill refuses either way. The launcher instead starts a Prime daemon on its own socket, creates a resident session there (one that outlives the launcher), sets the autonomous budget (600 turns, 200 continuations, 6,000,000 tokens and six hours by default; --max-turns, --max-continuations, --max-tokens and --timeout-ms override them), prompts it with /skill:feature <arguments>, prints one JSON line and exits:

{"socket":"/tmp/prime-agent-501/feature-….sock","activeSessionId":"e44fd57b15c3","stop":"PRIME_AGENT_DAEMON_SOCKET=… prime-agent stop e44fd57b15c3"}

If the launch exits 1 after creating the session, it still prints that line, with "prompt" added: "refused" means the daemon declined the prompt and the session is idle, so stop it; "unconfirmed" means the acknowledgement was lost and the run may be working. Check it with prime-agent list --json on that socket before stopping it or launching again. The launcher never re-sends an unconfirmed prompt, because a second one could start a second driver.

The GH_TOKEN and FACTORY_PUBLISHING_IDENTITY a run needs must be in the launcher's environment. The launcher sends that environment with the create as launchEnv, and Prime 0.10.1 applies it to the session. Prime 0.10.0 ignores it and gives a session the daemon's boot environment, which is why the daemon is the launcher's own, started with that environment. --socket reuses a daemon you started yourself; on 0.10.0 it must have booted with the run's environment. Prefer Prime 0.10.1, since 0.10.0's TUI blanks in iTerm2's fullscreen view. --skill <path> adds a skill file to the session; it does not turn discovery off, so where the adapter is also installed the session sees two feature skills. Which one a self-hosted run then follows is not yet verified on Prime 0.10.

Stop a run with the printed stop command. Do not use prime-agent shutdown: on 0.10.0 it stops every daemon under the same socket directory, interactive sessions included, and its narrower 0.10.1 scope was not tested here. The run's daemon stays up, idle, after the run terminalizes.

The integration drives foreground runs only, and rejects --background before creating or changing a run. The skill reads its install context by running bin/context.js, which prints the installed agent directory, the factory CLI and each specialist's spawn profile. It binds SESSION_ID from the session's own durable sessionId in agent_observe.list_agents(), uses Prime RLM children for specialist work, and requires their reports through agent messaging.

skills/feature/WORKFLOW.md is a package-local copy of the factory's canonical workflow. pretest and prepack refresh it with the repository sync script so the adapter never relies on a skill loader to inline another package's resource. The CLI remains the only writer of run.json.

Specialist model and thinking level

Every agent file in feature-factory declares model, role, and effort in its frontmatter. This adapter uses role and effort, and ignores the declared model for the same reason the OpenCode adapter does: sonnet and opus are tiers, while Prime requires an exact provider/id selector and fails a spawn given anything else.

effort becomes the child's thinking level directly — every declared value (low, medium, high, xhigh) is one of Prime's THINKING_LEVELS, so nothing is mapped or approximated. A value outside that set is dropped rather than passed, because an unknown level fails the spawn instead of being ignored, and inheriting the parent's level is the safer miss.

A model resolves through the same four levels as the OpenCode plugin, most specific first, so an operator configuring both hosts learns one vocabulary:

profiles[<agent>]  →  profiles[<role>]  →  profiles.default  →  profile

Configure them in .prime/agent/feature-factory.json, project-local first and then ~/.prime/agent/feature-factory.json for every project:

{ "profiles": {
    "planning": { "model": "openai/gpt-5.6-sol", "thinking": "xhigh" },
    "builder":  { "model": "openai/gpt-5.6-sol" },
    "story-reader": { "model": "openai/gpt-5.6-luna", "thinking": "minimal" }
} }

The project file wins outright over the home file; they are not merged, so a project that sets only builder does not inherit the home file's other roles. A malformed or non-object file is skipped rather than raised, because a typo in an optional profile must not stop every run before it starts.

That file is the configuration surface because the skill runs bin/context.js with no options, so anything reachable only by calling its exports directly is not configuration.

Roles come from each agent's own frontmatter — planning, story, research, design, builder, test, reviewer — so a new agent inherits its role without needing an entry.

model has no default here, deliberately. Prime's own subagentDefaultModel setting already means "one model for every child", and it applies exactly when a spawn omits model=. Pinning a selector is fail-closed at both layers: an unavailable, unauthenticated or expired selection fails the spawn rather than falling back to another model. That is the behaviour you want — a run should not quietly proceed on a model nobody chose — but it means a wrong selector stops the chain rather than degrading it. Configure one only after rlm.find_models() confirms it from the credentials the run will use.

What this adapter cannot enforce

On OpenCode, each agent's declared tools becomes a permission map, and that is what keeps a reviewer from editing the code it judges. Prime children inherit the parent's tools and skills, and rlm.spawn takes no tool or skill argument, so that separation is instruction here rather than enforcement: the composed prompt states the allowed files and tools, and nothing stops a child ignoring it. Recursion depth is enforced by the host — the default permits children but not grandchildren.

Development

From this package directory:

npm test
npm pack --dry-run

License

MIT