eforge-init

star 67

Initialize eforge in the current project with an interactive setup flow

eforge-build By eforge-build schedule Updated 6/15/2026

name: eforge-init description: Initialize eforge in the current project with an interactive setup flow disable-model-invocation: true

/eforge:init

Initialize eforge in this project. This setup configures an agent runtime profile and post-merge validation commands. You can use an existing local- or user-scope profile from any supported harness, or create a new project profile. When creating a new profile from this flow, the generated profile uses the Pi harness for all tiers, then creates it under eforge/profiles/ and activates it. Also writes eforge/config.yaml for team-wide settings (postMergeCommands, etc.).

Welcome

Before starting Step 1, print this welcome message to the user verbatim:

Welcome to eforge — an agentic build system that turns plans into code. You stay close to the code (planning, decisions) while eforge implements, blind-reviews, and validates in the background.

This setup configures your agent runtime profile and post-merge validation commands.

Then proceed to Step 1.

Workflow

Step 1: Determine postMergeCommands

Inspect the project to figure out the right postMergeCommands:

  1. Read package.json (if it exists) and note which scripts are available (e.g. install, type-check, typecheck, test, build, lint)
  2. Detect the package manager from lockfiles: pnpm-lock.yaml -> pnpm, yarn.lock -> yarn, package-lock.json -> npm, bun.lockb -> bun
  3. Build a suggested command list. Always start with the install command, then add validation scripts in order: type-check, test, build. For example: ["pnpm install", "pnpm type-check", "pnpm test", "pnpm build"]
  4. For non-JS projects: check for Cargo.toml (cargo build, cargo test), go.mod (go build ./..., go test ./...), Makefile (make), etc.
  5. If you can't determine commands, use an empty list

If eforge/config.yaml already exists, also read its current build.postMergeCommands and compare against your analysis. If the existing commands look good, keep them. If your analysis suggests improvements (missing scripts, outdated commands), propose the updated set instead.

Present your suggested commands to the user briefly: "I'd suggest these postMergeCommands based on your project: ..." and ask if they look right. Accept corrections.

Step 1.3: Landing action

Ask the user to choose what happens when a build completes successfully. Present the three options using the native select UI:

Option Shorthand When to use
Open a PR (Recommended) pr Opens a GitHub pull request from the artifact branch targeting the resolved base branch. Requires the gh CLI. Best for team code review workflows.
Merge to base branch merge Auto-merges the artifact branch into the base branch. Fast path with no manual review step.
Leave branch leave Commits to the artifact branch and exits without merging or opening a PR. Use when you want to inspect or handle the branch manually.

Default/recommended selection: pr.

After the user picks pr, run a shell check to verify gh is available:

gh --version

If the command is not found or returns non-zero: warn the user that pr requires the gh CLI and that builds configured with pr will fail until it is installed. Proceed with the selection anyway — the user may install gh later. Do not block or ask them to rechoose.

Store the shorthand value (pr, merge, or leave) for use in the eforge_init calls below (both the existingProfile and fresh-init paths) as landingAction.

Step 1.35: PR auto-merge policy (optional, only when pr is selected)

If the user selected pr as the landing action, briefly inform them about the GitHub PR auto-merge policy option using a native informational note:

"eforge will open a GitHub PR when your build finishes. By default, auto-merge is ask — enabled only when explicitly requested per-build via --landing-auto-merge. You can set a project-level default in eforge/config.yaml under landing.pr.autoMerge (ask | always | never) after init. Run /eforge:config to edit it."

Skip this step if the user selected merge or leave as the landing action.

Step 1.4: Confirm trunk branch and protection policy

  1. Run this shell command to detect the remote default branch:

    git symbolic-ref refs/remotes/origin/HEAD --short
    

    Strip the origin/ prefix from the output (e.g. origin/mainmain). If the command fails or the output is empty, fall back to main.

  2. Ask the user to confirm the detected trunk using showInput with the detected branch as the default value: "Trunk branch detected as <trunk> — confirm or enter a different name." Accept a correction if provided.

  3. Ask using the native select UI:

    Should builds be allowed to merge directly to <trunk> without opening a PR? (solo-dev opt-in)

    • No (recommended) — protect the trunk. eforge will open a PR when landing on trunk. Best for team workflows.
    • Yes — allow landing.action: merge to land directly on trunk. Use for solo developers on unprotected branches.

    Default: No.

  4. Store the confirmed trunkBranch and whether allowLocalMergeToTrunk is true (Yes) or false (No). Pass both when calling eforge_init in the next steps (both the existingProfile and fresh-init paths).

Step 1.45: Stacking (optional)

Ask: "Does this project use stacked PRs with git-spice?"

If yes:

  • Confirm the git-spice binary location. Ask: "Is git-spice on your $PATH, or is there a custom path? (Set command: gs only if you explicitly use that alias.)" Default: on $PATH as git-spice (no override needed).
  • Store stackingEnabled: true. If the user supplied a non-default path (anything other than git-spice on $PATH), also store gitSpiceCommand: "<path>".
  • Pass stackingEnabled: true (and gitSpiceCommand when the user provided a custom path) when calling eforge_init in Steps 1.5 and 5. The tool persists these as stacking.enabled and stacking.gitSpice.command in eforge/config.yaml.

Example eforge_init call fields when stacking is selected with the default git-spice command:

{
  "stackingEnabled": true
}

Example when stacking is selected with a custom path:

{
  "stackingEnabled": true,
  "gitSpiceCommand": "/usr/local/bin/git-spice"
}
  • Remind the user to run git-spice repo init in the repository if they haven't already.

If no: proceed to Step 1.5.

Step 1.5: Existing local- and user-scope profiles

Call eforge_profile { action: "list", scope: "local" } and eforge_profile { action: "list", scope: "user" } to check for existing profiles outside the project tier.

If both responses contain no profiles (both lists empty), skip this step entirely and proceed to Step 2.

If any profiles exist, present them in a combined table:

Name Scope Harness Planning model
<name> local <agents.tiers.planning.harness> <agents.tiers.planning.model>
<name> user <agents.tiers.planning.harness> <agents.tiers.planning.model>

Ask: "Would you like to use one of these existing profiles, or create a new project profile?" If the chosen profile uses claude-sdk, mention that it is supported but optional and Anthropic-specific. Starting June 15, 2026, Anthropic says Claude Agent SDK and claude -p usage no longer count toward Claude plan limits; eligible plans may receive a separate monthly Agent SDK credit, usage beyond that credit is billed at standard API rates when extra usage is enabled, otherwise requests stop, and API-key users remain pay-as-you-go.

On pick (existing profile):

Call eforge_init with:

{
  "existingProfile": { "name": "<chosen>", "scope": "<local|user>" },
  "postMergeCommands": [...],
  "landingAction": "<pr|merge|leave>",
  "trunkBranch": "<confirmedTrunk>",
  "allowLocalMergeToTrunk": <true|false>,
  "stackingEnabled": true,           // only when stacking was selected
  "gitSpiceCommand": "<custom path>" // only when the user provided a non-default path
}

Include force: true if $ARGUMENTS contains --force or force. Omit stackingEnabled when the user did not opt into stacking. Omit gitSpiceCommand when using the default git-spice on $PATH.

Skip Steps 2–6. Proceed directly to the result message.

  • For a local-scope pick:

    eforge initialized with local-scope profile <name> activated. The profile lives at .eforge/profiles/<name>.yaml. eforge/config.yaml was written with the agreed postMergeCommands and landing.action setting.

  • For a user-scope pick:

    eforge initialized with user-scope profile <name> activated. The profile lives at ~/.config/eforge/profiles/<name>.yaml. eforge/config.yaml was written with the agreed postMergeCommands and landing.action setting.

On "create new project profile": Fall through to Step 2.

Step 2: Setup mode

When creating a new project profile in this flow, the harness is always pi. Ask the user: "Quick setup (one provider and suggested tier models, including an optional separate implementation model) or mix-and-match (pick a different provider/model/effort per tier)?"

Pi is the recommended execution harness for new eforge setup. Existing local- or user-scope claude-sdk profiles remain supported; if the user selects one, mention that it is Anthropic-specific and follows the Agent SDK credit/API-pricing caveat above.

Step 3a: Quick path

When the user chooses Quick setup:

  1. Provider: Call eforge_models with { action: "providers", harness: "pi" } to get available providers. Present the list and ask the user to pick one.
  2. Planning/review/evaluation model: Call eforge_models with { action: "list", harness: "pi", provider: "<chosen>" } to get available models (sorted newest-first). Show the top 10 and ask the user to pick.
  3. Implementation model: Prompt:

    Pick a separate implementation-tier model? (Recommended — most build steps run at the implementation tier, so a cheaper/smaller model here saves a lot. Press enter to reuse <planning-id>.) Show the same top-10 list with the user's planning pick highlighted as the default. If the user accepts the default, set implementation.model = planning.model.

  4. Assemble the single-provider profile (same provider for all tiers):
profile:
  agents:
    tiers:
      planning:
        harness: pi
        model: <picked>
        effort: high
        pi:
          provider: <chosen>
      implementation:
        harness: pi
        model: <picked-or-planning>
        effort: medium
        pi:
          provider: <chosen>
      review:
        harness: pi
        model: <picked>
        effort: high
        pi:
          provider: <chosen>
      evaluation:
        harness: pi
        model: <picked>
        effort: high
        pi:
          provider: <chosen>

Step 3b: Mix-and-match path

When the user chooses Mix-and-match, walk tiers planning -> implementation -> review -> evaluation:

For each tier:

  • Provider: Ask which provider to use. Default = previous tier's provider. Call eforge_models with { action: "providers", harness: "pi" } for the list.
  • Model: Ask which model. Default = previous tier's model when provider is unchanged. Call eforge_models with { action: "list", harness: "pi", provider: "<chosen>" } and show the top 10 newest-first.
  • Effort: Ask from low | medium | high | xhigh | max. Default: high for planning/review/evaluation, medium for implementation.

Assembled profile shape:

profile:
  agents:
    tiers:
      planning:
        harness: pi
        model: anthropic/claude-opus-4-6
        effort: high
        pi:
          provider: openrouter
      implementation:
        harness: pi
        model: qwen3-coder
        effort: medium
        pi:
          provider: local
      review:
        harness: pi
        model: anthropic/claude-opus-4-6
        effort: high
        pi:
          provider: openrouter
      evaluation:
        harness: pi
        model: gemini-flash
        effort: high
        pi:
          provider: google

Step 4: Profile name

Derive a candidate profile name from the assembled profile using these rules (mirrors the server-side deriveProfileName helper):

  • Same provider+model across all four tiers: use the sanitized model ID. Sanitize by lowercasing, replacing . with -, stripping a leading claude- prefix, and collapsing repeated dashes. Example: claude-opus-4-7opus-4-7.
  • Same provider, model varies across tiers: use pi-<provider> (e.g. pi-openrouter).
  • Multiple providers: use mixed-<planning-tier-provider> (e.g. mixed-openrouter).

Show the candidate name to the user: "I'd name this profile <candidate>. Does that work, or would you like a different name?" Accept a one-word override (alphanumeric + dashes). If the user accepts, proceed with the candidate. Set profile.name to the final name before calling the tool.

Step 5: Persist

Call eforge_init with:

{
  "profile": {
    "name": "<finalName>",
    "agents": {
      "tiers": {
        "planning":       { "harness": "...", "model": "...", "effort": "...", "pi": { "provider": "..." } },
        "implementation": { "harness": "...", "model": "...", "effort": "...", "pi": { "provider": "..." } },
        "review":         { "harness": "...", "model": "...", "effort": "...", "pi": { "provider": "..." } },
        "evaluation":     { "harness": "...", "model": "...", "effort": "...", "pi": { "provider": "..." } }
      }
    }
  },
  "postMergeCommands": [...],
  "landingAction": "<pr|merge|leave>",
  "trunkBranch": "<confirmedTrunk>",
  "allowLocalMergeToTrunk": <true|false>,
  "stackingEnabled": true,           // only when stacking was selected
  "gitSpiceCommand": "<custom path>",// only when the user provided a non-default path
  "force": true
}

Include force: true if $ARGUMENTS contains --force or force. Include pi: { "provider": "..." } on every tier entry. Omit stackingEnabled when the user did not opt into stacking. Omit gitSpiceCommand when using the default git-spice on $PATH.

Step 6: Migrate (--migrate)

If $ARGUMENTS contains --migrate, skip Steps 2-5 above. Instead call eforge_init with { migrate: true }. This extracts the legacy backend:/pi:/agents.* fields from the existing config.yaml into a named profile, activates it, and strips those fields from config.yaml.

For a newly created project profile, the tool will create the profile under eforge/profiles/, activate it via eforge/.active-profile, and write eforge/config.yaml alongside other team-wide settings.

Step 7: Report

Once the tool completes successfully, inform the user:

eforge initialized with profile <profileName>. The profile lives at eforge/profiles/<profileName>.yaml and is now active. You can customize further with /eforge:config --edit, switch profiles with /eforge:profile, or create additional profiles with /eforge:profile-new. Use /eforge:profile-new --scope user to create a user-scope profile under ~/.config/eforge/profiles/ that applies across all your projects.

Related Skills

Skill Command When to suggest
Build eforge_build User wants to enqueue work for the daemon to build
Config eforge_config User wants to view, edit, or validate the eforge config
Profile eforge_profile User wants to inspect or switch agent runtime profiles
Profile (new) /eforge:profile-new User wants to create a personal agent runtime profile
Planning entry eforge-plan workstation / contribution User wants to plan changes before building
Status eforge_status User wants to check build progress or queue state
Restart eforge_restart User wants to restart the eforge daemon
Update eforge_update User wants to check for or install eforge updates
Install via CLI
npx skills add https://github.com/eforge-build/eforge --skill eforge-init
Repository Details
star Stars 67
call_split Forks 4
navigation Branch main
article Path SKILL.md
More from Creator
eforge-build
eforge-build Explore all skills →