Skip to main content

infinite-craft-cli

PyPI Downloads License Python Tests Publish Chrome Web Store

Interactive CLI for Infinite Craft — combine elements from the terminal. Also available as a browser extension and web trainer.

Originally built on infinite-craft by @sqdnoises. As of v1.0, uses curl_cffi directly.

Installation

pip install infinite-craft-cli

Browser extension

Install the Infinite Craft Trainer from the Chrome Web Store — it loads automatically on neal.fun/infinite-craft and fetches the current trainer (trainer.min.js) from GitHub Pages with cache: 'no-store', so feature updates ship without waiting for a Chrome Web Store release. The extension manifest version (extension/manifest.json) is independent of the Python CLI package version (git tags). See PRIVACY.md for the remote-script trust model. Works in Edge, Brave, and other Chromium browsers.

Manual QA (extension): After changes to extension/loader.js, load the unpacked extension on live neal.fun/infinite-craft and confirm the trainer UI appears and IndexedDB-backed commands work (e.g. /list).

For other install methods (console snippet, userscript), see the web trainer page.

Usage

Interactive mode

infinite-craft

This opens a REPL where you can combine elements, search discoveries, and more:

=== Infinite Craft CLI ===

craft> Water + Fire
  💨 Water + 🔥 Fire = 💨 Steam

craft> /search steam
  💨 Steam

craft> /target Steam
  Target set: Steam — you'll be asked whether to continue the batch when this is crafted.

craft> /help

Sticky chrome under the log always shows the pair-API rate bar (next-slot wait + remaining budget). While a job runs it also shows running command + progress, or ◆ confirm with the reason (pair count, target hit). y / n is only on confirm [y/n]>.

Non-interactive mode

Most REPL commands are available as subcommands (shorthand operators like +, ++, and * are REPL-only; script runs a script non-interactively):

infinite-craft combine "Water" "Fire"
infinite-craft search "steam"
infinite-craft list
infinite-craft recipe "Steam"
infinite-craft import "Steam"
infinite-craft export
infinite-craft fill
infinite-craft unfilled
infinite-craft prune
infinite-craft exhaust "Water"
infinite-craft crawl "Water" "Fire"
infinite-craft permute "w*"
infinite-craft with "Water" "fire*"
infinite-craft cross "fire*" "water*"
infinite-craft lucky 25
infinite-craft --version

Commands

Combine & crawl

Shorthand Slash command Description
<element> + <element> /combine <element> <element> Combine two elements
<element> ++ <element> /crawl <element> <element> Crawl: generations over a growing pool until one adds nothing to it

Bulk combine

Shorthand Slash command Description
<query> * <query> /cross <query> <query> Cross-combine matches from both queries
/permute <query> Combine all matching elements with each other
/permutate <query> Permute repeatedly until no new discoveries
/exhaust <query> Each match combined with all discoveries
/lucky [count] Try random untried pairs — entropy mining (default 10). Pairs that produced Nothing aren't persisted, so later sessions may re-draw them

Query syntax

Used by /search, /with, /permute, /permutate, /cross, /exhaust, and script patterns:

Syntax Meaning
substring Case-insensitive substring (default)
* ? [] fnmatch wildcards (e.g. fire*, mu?)
/pattern/ Regex, case-insensitive; real alternation (/steam|mist/), grouping, anchors
!<query> Exclude matches (e.g. !fire* = everything except fire*)
! All elements (exclude nothing)
^<query> First discoveries only (e.g. ^fire* = new fire* matches)
^ All first discoveries

Other commands

Command Description
/search <query> Search discoveries
/recipe <element> Show shortest recipe from base elements
/list List all discovered elements
/import <element|file.ic> Import from Infinibrowser or .ic save file
/fill Fetch missing recipes from Infinibrowser
/unfilled List elements without recipes
/prune Remove orphan elements Infinibrowser can't fill
/export [path] Export discoveries as .ic save file
/history Show combinations tried this session
/target <element> Watch for a result; ask y/n to continue the batch on hit
/target Show current target
/target clear Clear target
`/auto [on off]`
`/relay [on off
/queue Show running and pending commands (status also appears in chrome)
/help Show help
/quit Exit

Scripting

Every non-slash line in the REPL is a script (the old shorthands are one-statement scripts). Statements are separated by ;; whitespace-delimited operators are structure and everything attached is pattern material, so mountain range + ship still combines exactly what it says. Bare words are element references (error if unknown); patterns with metacharacters (* ? [] /regex/ ! ^) are queries; quoted strings are exact element references.

targets := ^(fire* / water*) ;          # bind first-discoveries having a fire*+water* recipe
(targets)* -> |[]| < 2 ;                # permute passes until a pass yields < 2 new
[] * (earth* / fire*)                   # cross what that made against filtered earth*

Pure, loop-free scripts (bare queries, unions, filters, walrus bindings) run immediately and interleave with a running bulk command, like /search; mutating scripts and loops queue on the pair lane.

Highlights: , union, - difference, & intersect, //% known-recipe filters, (expr)*/(expr)**/(expr)! permute/permutate/exhaust, (expr)100 first-100 ((expr)(|x*|) dynamic counts), (expr)100? random-100, (expr)? shuffle, A * B cross, A ++ B crawl, [ expr ]/[] new-element sets, set @x body for-each, body -> cond do-until, body ~ cond while, cond ? a : b ternary. Conditions are statically pure — mutations inside a condition are parse errors. Every mutating operation's value is the set it produced, so pipelines chain. Save scripts as .ice files and run them with /script <path> (file picker in the trainer) or infinite-craft script -f path. Non-interactive runs have no y/n prompt: bulk operations over the warn threshold announce their pair count and proceed; script failures exit non-zero. Full spec: docs/superpowers/specs/2026-08-20-script-language-v0.6.md.

Breaking changes in 2.0: +| is removed (use *; /with remains), bare words in old *//+| positions were substring queries and are now element references (write *fire* for substring), bare pattern lines print matches instead of erroring, A + B + C chains combines, and /permutate no longer stops at 50 rounds.

Queues and confirm (Python REPL + trainer)

Pair-API work (combine, crawl, permute, exhaust, …) and Infinibrowser work (/fill, /prune, /import) use independent queues so one lane can run while the other is busy. Local commands (/help, /search, /list, /recipe, /history, /clear, /unfilled, /queue, /target) run immediately — their output may interleave with a running job.

Large batches and /target hits pause on confirm [y/n]>: y continues, n / Esc / Stop cancels remaining work. The job row states the reason (331 pairs, target hit); keybindings are not repeated in the log.

Key Action
Esc Skip current command, continue to next in that lane (TTY / Stop in the trainer)
Ctrl+C While running: stop and discard remaining queue; at confirm: decline only

Deferred commands print Queued: when that lane is already running.

Hive mind (shared pair cache)

Neal's server caches every pair anyone has ever combined — only genuinely novel discoveries cost real inference — so there is no reason for two players to spend rate-limit slots asking the same question twice. The CLI and trainer share a small relay (relay/, a free Render web service) holding the union of every connected user's results. Cache order everywhere is local → hive → neal.fun: a rate-limit slot is committed only after both cache tiers miss, and fresh results are contributed back automatically. Bulk runs sweep the whole batch against the hive in one request before spending their first slot.

One timer. Every client — idle or running — sends the relay a ~1s beat: liveness, neal reachability, and the active run id out; a status and a "there's work you could do" bit back. That beat is the only clock in the protocol — everything else is an event — and one threshold derives from it: anything a session owns (its runs' bounties, its work assignments, its place in the household budget split) lapses ~15s after its last beat.

Bounty board. When a bulk run needs more than the rate slots it has free right now, it offers the entire uncovered remainder to the board (up to 500 pairs), bound to its run id — so neal.fun's rate limit is pooled across willing users instead of stranding your backlog. The board entry lives exactly as long as the run keeps appearing in your beats: cancel (or crash) and it lapses by silence alone, no revoke call anywhere. Idle clients whose beat says there's work pull it and get it assigned — never handed to two workers while the assignee stays live and neal-capable, and forfeited the moment it lapses or reports it can't reach neal. You keep grinding your own list regardless (bounties are parallelization offers, not delegation), your run absorbs the fleet's fills right before each spend, and if you and the fleet ever derive the same pair twice, that duplicate independent sighting counts as peer-review confirmation — overlap is review, not waste. Serving is on by default and symmetric: while you're idle at the prompt, your client serves the hive too.

Peer review. A cache entry is trusted only after a second, independent client re-asks neal.fun and gets the same answer (review work never accepts a cached answer, and is never handed to the session that authored the sighting). A conflicting claim against an unreviewed entry drops it, so the network self-heals around a bad result rather than trusting last-writer.

Same-IP fairness. The relay sees each client's public IP and tells everyone how many sessions on that IP are actively spending neal budget; each client divides its per-IP window by that count. Two laptops on one home Wi-Fi each settle to half the limit before hitting a 429, not after. Bounty work is offered only to IPs where nobody is running, so serving the hive never contests your own household's runs.

429 = stand down. neal.fun's 429 is an hours-long IP ban, not a backoff signal, so a client that trips one stops making neal requests entirely (hive lookups still work) and broadcasts the cooldown to every session on its IP.

The tier is on by default and fails open — if the relay is down or cold, the CLI just talks to neal.fun as before. /relay toggles it and /relay status shows connection, hits/contributions/bounties, the current budget split, and any cooldown. IC_RELAY=off disables it at startup; IC_RELAY_URL points at a different relay. The relay keeps its cache in RAM and is re-seeded by clients from their own recipe stores on connect (plus an optional Upstash Redis snapshot across restarts), so a cold instance refills within minutes.

The rate bar shows all of this: a pulsing 🐝 counter beside the bar for pairs served to you by the hive (they cost no slots), honey-gold cells inside the bar for slots you've lent to bounty work, and a cooldown note when you're banned.

Data storage

Discoveries and recipes are stored in ~/.infinite-craft-cli/:

  • discoveries.json -- all discovered elements
  • recipes.json -- known element combinations
  • export.ic -- default export location

Browser extension / bookmarklet

The browser trainers share the same command syntax, query matching, and script language as the Python CLI (wildcards, /regex/, ! exclude, ^ first discoveries, /combine, /with, /cross, /target, and scripts). Browser-only additions: /clear to clear the output panel, and IndexedDB storage instead of ~/.infinite-craft-cli/. Rate, job, and queue status live in the sticky panel above the input (visual-only; no /queue command). Local commands such as /search may interleave output with a running queued command.

Long runs in a background tab: the trainer holds a Web Lock while a run is active, which keeps Chrome's Memory Saver / Energy Saver from freezing the tab under current heuristics. If a backgrounded run still pauses (the exemption is a heuristic, not a guarantee), add neal.fun to chrome://settings/performance → "Always keep these sites active", or keep the tab in a partially visible window. Truly long unattended jobs are what the Python CLI is for.

Development

After editing bookmarklet/trainer.src.mjs, rebuild the bundles:

bazel build //bookmarklet:site

Build the Python wheel:

bazel build //release:wheel.dist

Run all tests:

bazel test //...

This includes //sudo:craft_lockstep_test, which runs the kernel's own test suite against both the generated Python and JavaScript and diffs the two. //tests/... alone skips it.

Run integration tests (hits the real API):

bazel test //tests:test_integration --test_env=INTEGRATION_TESTS=1

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

infinite_craft_cli-3.0.0-py3-none-any.whl (106.2 kB view details)

Uploaded Python 3

File details

Details for the file infinite_craft_cli-3.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for infinite_craft_cli-3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ea86310cc20a93ebad5f59a77ec624b50b3ee238d84e362b3ecd909bc33931d3
MD5 7c92930b9780aedeb5881d1a556d1f62
BLAKE2b-256 57a34675ad43c08f5bbb3e4418158b390a95c8d8369e43e6e924bf024da9e13e

See more details on using hashes here.

Provenance

The following attestation bundles were made for infinite_craft_cli-3.0.0-py3-none-any.whl:

Publisher: publish.yml on hacker6284/infinite-craft-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

3.0.2

1 file

3.0.1

1 file

This release

3.0.0 This release

1 file

2.5.0

1 file

2.4.1

1 file

2.4.0

1 file

2.3.0

1 file

2.2.0

1 file

2.1.1

1 file

2.1.0

1 file

2.0.1

1 file

2.0.0

1 file

1.11.0

1 file

1.10.2

1 file

1.10.1

1 file

1.10.0

1 file

1.9.2

1 file

1.9.1

1 file

1.9.0

1 file

1.8.4

1 file

1.8.3

1 file

1.8.2

1 file

1.8.1

1 file

1.8.0

1 file

1.7.0

1 file

1.6.0

1 file

1.5.0

2 files

1.4.2

2 files

1.4.1

2 files

1.4.0

2 files

1.3.0

2 files

1.2.9

2 files

1.2.8

2 files

1.2.7

2 files

1.2.6

2 files

1.2.2

2 files

1.2.1

2 files

1.2.0

2 files

1.1.0

2 files

1.0.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page