@ifi/pi-spec
v0.4.2
Published
Native spec-kit workflow for pi with a /spec command, TypeScript scaffolding, and spec-driven prompts.
Maintainers
Readme
@ifi/pi-spec
Native spec-driven workflow for pi, inspired by github/spec-kit.
@ifi/pi-spec is a pi extension package, not a shell wrapper and not a general-purpose JavaScript
library. Its job is to bring the core spec-kit workflow into pi as a native TypeScript experience:
- one
/speccommand instead of a pile of separate commands and shell entrypoints - deterministic local scaffolding under
.specify/ - deterministic feature artifacts under
specs/###-feature-name/ - native git/repo detection, branch naming, and feature numbering in TypeScript
- prompt handoff back into pi via
pi.sendUserMessage(...) - project-owned templates that can be customized locally after initialization
The package deliberately keeps the mental model of spec-kit, but replaces its shell orchestration with normal pi tools and normal pi conversations.
Install
pi install npm:@ifi/pi-specOr install the full oh-pi bundle:
npx @ifi/oh-piPurpose
The purpose of this package is to make spec-first development feel native inside pi.
In practice that means:
- Requirements come first
- You write or refine a spec before planning and implementation.
- The workflow is explicit
/spec specify,/spec plan,/spec tasks,/spec implementare separate steps with clear outputs.
- The repository owns the workflow state
- Important artifacts live in normal files in your repo, not in hidden runtime state.
- Pi stays in control of the work
- Instead of calling external shell scripts, pi reads templates, edits files, runs tests, and explains what it did.
- Teams can customize locally
- The package seeds
.specify/templates/, then gets out of the way.
- The package seeds
Goals
The design goals for @ifi/pi-spec are:
- Native pi UX — use pi's existing tools, prompting, and slash-command system
- Spec-kit compatibility of concepts — keep the same major phases and familiar artifact layout
- Type-safe implementation — perform repo detection, path calculation, and branch generation in TypeScript
- Idempotent scaffolding — create missing files without constantly overwriting local customizations
- Low surprise — make state visible through files and
/spec status - Good defaults, flexible templates — ship usable templates while letting projects evolve them
Non-goals
This package intentionally does not try to be:
- a 1:1 shell-script port of upstream spec-kit internals
- a hidden autonomous pipeline that silently runs every step for you
- a generic npm library with a stable programmatic JS API
- a hook runner that auto-executes
.specify/extensions.ymlscripts behind your back
The stable API surface is the slash command and the on-disk workflow structure.
The API I chose
Public API surface
The package has one primary public entrypoint:
/spec [subcommand] [freeform input]Supported subcommands:
Canonical /spec subcommands exposed by the extension. Keep README command lists and exported type
metadata in sync with this source of truth: status, help, init, constitution, specify,
clarify, checklist, plan, tasks, analyze, implement, list, and next.
That is the intentional public API.
There is not a separate public JS/TS library API right now. Internal modules like
workspace.ts, scaffold.ts, or prompts.ts are implementation details for contributors, not a versioned
integration surface for consumers.
Core workflow steps:
Workflow steps that hand work back into pi for feature execution. These ordered steps are
constitution, specify, clarify, checklist, plan, tasks, analyze, and implement.
Keep contributor-facing docs aligned with the same sequence.
Why one /spec command is the right API
I chose one command with subcommands instead of many top-level commands like /specify, /clarify,
/plan, /tasks, etc. for a few reasons:
It matches the workflow mental model
- All of these actions are part of one lifecycle.
- Grouping them under
/specmakes that lifecycle obvious.
It avoids namespace clutter in pi
- A spec workflow can easily consume half a dozen top-level slash commands.
/spec ...keeps the command surface organized.
It is easier to discover
/spec help,/spec status, and/spec nextmake the system self-explanatory.- Users only need to remember one root command.
It preserves upstream familiarity without copying the shell UX
- The step names still map cleanly to spec-kit concepts.
- But the runtime behavior is pi-native instead of script-native.
It centralizes context resolution
- Repo detection, active-feature resolution, scaffold creation, and prompt generation all happen in one place.
- That reduces edge cases and keeps behavior consistent.
Why the API is file-centric
The second part of the API is the filesystem contract:
.specify/for reusable workflow state and templatesspecs/###-feature-name/for per-feature artifacts
I think this is the correct design because it keeps the workflow:
- reviewable in git
- easy to inspect manually
- easy to customize
- resilient across agent restarts
- tool-agnostic at the file layer
In other words, the source of truth is not some in-memory session object; it is the repo itself.
Exact command behavior
Below is the practical contract for each subcommand.
| Command | Purpose | Model handoff | Filesystem side effects |
| --- | --- | --- | --- |
| /spec or /spec status | Show current workflow state | No | None |
| /spec help | Show available commands and guidance | No | None |
| /spec init | Create the base workflow scaffold | No | Creates missing .specify/ files |
| /spec constitution [principles] | Create or revise the project constitution | Yes | Ensures base scaffold exists |
| /spec specify <feature description> | Create the next numbered feature workspace | Yes | Ensures scaffold, creates specs/###-.../, may create/switch git branch |
| /spec clarify [focus] | Ask and resolve high-impact ambiguities in the active spec | Yes | Ensures scaffold exists |
| /spec checklist [domain] | Generate or refine requirement-quality checklists | Yes | Ensures scaffold exists |
| /spec plan [technical context] | Build the implementation plan and design artifacts | Yes | Ensures scaffold, creates plan.md if missing |
| /spec tasks [context] | Generate an executable tasks.md | Yes | Ensures scaffold exists |
| /spec analyze [focus] | Run a read-only consistency review | Yes | Ensures scaffold exists |
| /spec implement [focus] | Execute tasks and update completion state | Yes | Ensures scaffold exists; prompts if checklists are incomplete |
| /spec list | List known feature directories | No | None |
| /spec next | Show the next recommended step | No | None |
Input rules
The command accepts freeform text after the subcommand.
Examples:
/spec constitution Security-first, testable, low-complexity defaults
/spec specify Add usage-based billing alerts for workspace admins
/spec plan Use TypeScript, Vitest, and direct pi tool access
/spec analyze Focus on contradictions between spec.md and tasks.md
/spec implement Start with the MVP story and update tasks as you goNotes:
/spec specifyeffectively requires a real feature description.- Other workflow steps accept freeform guidance and can also run with minimal or no extra guidance.
- When pi has UI input capabilities available, the extension can prompt for missing input instead of failing immediately.
Active feature resolution
For steps that operate on a feature (clarify, checklist, plan, tasks, analyze, implement), the
extension resolves the active feature using this order:
- current branch name if it matches a numbered feature directory
- a single known feature directory, if there is only one
- a UI selection prompt, if multiple features exist and the UI supports selection
- otherwise the latest numbered feature directory
This keeps the common path simple while still working in multi-feature repos.
Files and directories created by the package
Base workflow scaffold
/spec init creates the base workflow scaffold if it is missing.
.specify/
├── README.md
├── extensions.yml
├── memory/
│ ├── constitution.md
│ └── pi-agent.md
└── templates/
├── agent-file-template.md
├── checklist-template.md
├── constitution-template.md
├── plan-template.md
├── spec-template.md
├── tasks-template.md
└── commands/
├── analyze.md
├── checklist.md
├── clarify.md
├── constitution.md
├── implement.md
├── plan.md
├── specify.md
└── tasks.mdWhat these are for:
.specify/README.md— local explanation of the workflow as installed in this repo.specify/extensions.yml— compatibility/config surface; pi inspects it manually when relevant rather than auto-running hooks.specify/memory/constitution.md— canonical governance/principles file.specify/memory/pi-agent.md— pi-native replacement for agent-context update scripts.specify/templates/— local, editable workflow templates copied from the packaged defaults
Per-feature workspace
/spec specify <description> creates a numbered feature workspace:
specs/
└── 001-my-feature/
├── spec.md
├── checklists/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
└── tasks.mdNot every file exists immediately.
Current behavior:
spec.mdis scaffolded during/spec specifyplan.mdis scaffolded during/spec planif it is missing- other files are referenced by the workflow and created as the step needs them
Idempotency rules
Scaffolding is intentionally conservative:
- missing files are created
- existing files are left alone
- bundled templates are copied into the repo once, then become the repo's copies to edit
That is important because the package should seed a workflow, not keep fighting your local customization.
How to use it in practice
1) Initialize the workflow
/spec initUse this when introducing the workflow to a repo for the first time.
What happens:
.specify/is created if missing- default templates are copied in
- constitution and pi-agent memory files are created if missing
- a report is rendered in pi explaining what was created
2) Define the project's constitution
/spec constitution Security-first, testable, backwards-compatible changes by defaultUse this to establish the rules the workflow should follow.
Typical outcomes:
- the constitution file is created or updated in
.specify/memory/constitution.md - related templates may be aligned with those rules
- future workflow steps can refer back to the same governance file
3) Create a feature spec
/spec specify Add SSO login for enterprise tenantsWhat happens:
- the next feature number is computed
- a branch name is generated from the description
specs/###-feature-name/is createdspec.mdis scaffolded- if git is available and you are not already on that feature branch, the extension creates and switches to it
- pi receives a prompt instructing it to follow the local
specifytemplate using the prepared paths
This is the key step that turns a vague idea into a concrete feature workspace.
4) Clarify open questions
/spec clarifyor
/spec clarify Focus on tenant boundaries, auth edge cases, and failure statesThis step is meant to remove the highest-impact ambiguities before planning.
5) Generate a requirement-quality checklist
/spec checklist Authentication quality gatesThis is not supposed to generate implementation TODOs. It is meant to verify that the spec is precise, complete, and testable.
6) Build the implementation plan
/spec plan Use TypeScript, Vitest, and existing auth services; avoid new infrastructureWhat happens:
plan.mdis created if missing- pi is instructed to use the local
planworkflow template pi-agent.mdis treated as the pi-native context artifact instead of shell-generated agent files
7) Generate tasks
/spec tasksor
/spec tasks Prioritize the MVP path and keep tasks grouped by user storyThis step should produce a tasks.md with a strict checkbox-oriented execution plan.
8) Analyze for contradictions
/spec analyzeThis step is intentionally read-only. It is there to catch inconsistencies between the spec, plan, checklists, and tasks before coding begins.
9) Implement
/spec implementor
/spec implement Start with story 1, update tasks.md as each item completesBehavior worth knowing:
- checklist files are summarized before implementation
- if incomplete checklist items exist and the UI supports confirmation, pi asks whether you want to continue
- the implementation prompt reminds pi to mark completed tasks as
[x]
10) Inspect progress any time
/spec status
/spec next
/spec listUse these when you want visibility rather than action:
/spec statusshows artifact presence, checklist summaries, current branch, and known features/spec nextrecommends the next workflow command/spec listlists all numbered feature directories inspecs/
Example end-to-end session
/spec init
/spec constitution Security-first, testable, low-complexity defaults
/spec specify Build a native spec workflow package for pi
/spec clarify
/spec checklist Requirements quality for the initial MVP
/spec plan Use TypeScript, Vitest, and direct pi tool access
/spec tasks Group work by independently testable user stories
/spec analyze
/spec implementThat sequence is the intended happy path.
Native behavior vs upstream spec-kit
This package is inspired by upstream spec-kit, but the runtime model is different on purpose.
What is preserved
- the phase names and overall lifecycle
- the numbered feature directory convention
- the use of templates to guide each phase
- the idea of constitution/spec/plan/tasks/checklist artifacts
What changed
- shell scripts are replaced with TypeScript helpers
- repo/branch/path preparation happens inside the extension
- workflow execution is handed back to pi as a normal prompt-driven task
.specify/memory/pi-agent.mdreplaces agent-update shell behavior.specify/extensions.ymlis preserved as a file, but not auto-executed as hooks
Why this is the correct adaptation for pi
Because pi already has:
- tools for file IO
- tools for running validation commands
- a conversation model for asking clarifying questions
- slash commands for entering workflows
Using shell wrappers would add indirection without adding capability. Native TypeScript makes the workflow:
- easier to test
- easier to reason about
- more portable across environments
- less dependent on shell behavior differences
- more aligned with how pi already works
Internal implementation overview
These modules are useful for contributors, but they are not the promised external API.
extension/index.ts— command registration, dispatch, prompting, and model handoffextension/workspace.ts— repo detection, feature numbering, branch slugging, and path buildingextension/scaffold.ts— idempotent scaffold/template creationextension/prompts.ts— native workflow prompt builder and step-specific notesextension/status.ts— status reporting and checklist summarizationextension/git.ts— minimal git adapter used by the workflowextension/assets/templates/— vendored workflow and file templates adapted from spec-kit
I split the implementation this way because the workflow naturally has four concerns:
- command API and UX
- filesystem/workspace logic
- prompt-generation logic
- status/reporting logic
Keeping those concerns separate made the package easier to test thoroughly.
Customization
After initialization, you can customize the workflow by editing files in your repo:
.specify/memory/constitution.md.specify/memory/pi-agent.md.specify/templates/*.md.specify/templates/commands/*.md
This is another core design choice: the workflow should become your repo's workflow, not remain locked inside the npm package.
Summary
If I had to describe the package in one sentence:
@ifi/pi-specis a native pi implementation of a spec-first workflow whose public API is one/speccommand plus a deterministic.specify/andspecs/###-feature-name/file layout.
I think that is the correct API because it is:
- small enough to remember
- explicit enough to inspect
- compatible enough to feel familiar to spec-kit users
- native enough to feel right inside pi
- testable enough to maintain over time
