Skip to content

Releases: FishInSalt/ink

ink-agent 0.4.0

Choose a tag to compare

@FishInSalt FishInSalt released this 11 Oct 05:35

[0.4.0] - 2026-10-11

Added

  • run_error extension event. A top-level run that dies to a provider
    throw (or a failed overflow-recovery/compaction) now fires run_error
    — exactly once per crashed run, mutually exclusive with run_end,
    never on aborts, never from subagent crashes (a child crash stays a tool
    result). The payload is the crash message (first line, capped). The
    shipped task-timer extension stops its footer timer and paints
    failed after M:SS instead of ticking forever — previously a crashed
    run left running … on screen until the next run started (the
    documented run_end asymmetry; that contract is unchanged).

Changed

  • Clipboard pastes real file paths. Pasting a Finder/Explorer file
    copy (Ctrl+V) now inserts the real file paths — read per-platform
    (macOS public.file-url + NSFilenamesPboardType, Linux
    text/uri-list via wl-paste/xclip, Windows FileDropList) and
    joined with newlines; a bang draft shell-quotes and space-joins them.
    Paste order becomes file paths → image → text, and a path containing
    control characters drops the whole paste. A pasted absolute path at
    line start now submits to the model instead of being mistaken for a
    command (a candidate name containing / is never a command, except
    the skill: prefix scheme).

Fixed

  • Finder file copies no longer paste their icon. The defect behind
    the change above: a Finder file copy used to insert a tmp path
    whose bytes were the file's icon image — the path reader now runs
    before the image leg, and a garbage-reading platform reader aborts the
    paste instead of falling through to the icon image.

ink-agent v0.3.0

Choose a tag to compare

@FishInSalt FishInSalt released this 09 Oct 17:06

[0.3.0] - 2026-10-10

Added

  • Parallel read-only tools. read, grep, find and ls are
    concurrency-safe now: a run of consecutive independent calls issued in
    one message runs in parallel behind the same five-slot window as task
    calls. The system
    prompt's tool catalog gains a derived line telling the model this roster
    can run concurrently (roster names in parentheses while the roster has
    at most six entries).

  • Queued-call visibility. A concurrency-safe call's row shows as soon
    as the call is issued — └─ queued for read-only tools, └─ queued #N
    for task calls — with no timer until a slot admits it (the task row then
    continues as └─ pending #N). Queue time never counts toward the call's
    duration.

  • /sessions prune: sweep orphaned child sessions (subagent transcripts
    whose parent session file no longer exists) after an interactive
    confirm — header.id matching (never filename), live-lease exemption
    via child-lease semantics.

  • Chinese README (README.zh-CN.md): full translation of the root README
    with a language switch on both; npm packs it automatically (README* rule),
    so it ships with the package and the smoke allowlist admits it.

  • GitHub Pages documentation site: scripts/build-docs-site.mjs builds
    _site/ from the README and the ten docs pages (link rewrites, heading
    anchors, sitemap); .github/workflows/pages.yml deploys it to
    https://fishinsalt.github.io/ink/, and the npm homepage now points there.

  • Full Simplified-Chinese mirror of the docs site: docs/zh-CN/ (ten
    pages) builds to /zh/ with a per-page language switcher, hreflang
    alternates, a translated sitemap, and a translations-may-lag footer
    note; the npm package ships the mirror. scripts/check-docs.mjs now
    enforces mirror completeness, en↔zh structural parity (heading level
    sequences, byte-identical code fences, link-target multisets), and
    anchor mappability; test/docs-site.test.ts exercises the built site.

  • Promotion assets: assets/demo.tape + assets/demo-setup.sh record the
    README demo GIF, and assets/social-preview.html →
    assets/social-preview.png is the repository social preview card.

Changed

  • Concurrent tool scheduling: sliding window. Consecutive
    concurrency-safe calls now run behind a sliding window of five slots — a
    freed slot immediately admits the next call in issue order — instead of
    fixed chunks in which every call waited for the slowest member of its
    chunk. Results still settle in call order.

  • Abort grace. After an interrupt, tool calls that ignore the abort
    signal get a bounded ten-second wait; when it lapses the host synthesizes
    the call's result (did not respond to the interrupt within 10s — result abandoned) and the run concludes — Ctrl+C no longer hangs on a
    signal-ignoring tool. Only the post-abort wait is bounded, not tool
    runtime in general.

  • Login docs. README (both languages) leads with /login — environment
    variables second, the npx caveat block retired to docs/cli.md — and the
    /login listing now states where keys are stored (six API-key rows →
    ~/.ink/auth.json, stored key beats the environment variable) with OAuth
    scoped to the ChatGPT-plan row.

  • Legacy impVersion arm retired. Child-launch records must carry
    inkVersion; a record still carrying the legacy impVersion key is
    rejected outright (cross-version resume was already refused; no
    migration is performed).

  • Docs site: the wordmark cursor now blinks like a terminal cursor; the
    animation is turned off under prefers-reduced-motion: reduce.

  • README.zh-CN.md: the site link now points at the Chinese home
    (.../ink/zh/), and its two shell blocks carry the English comments
    byte-identical to README.md (the code-fence parity rule).

ink-agent v0.2.3

Choose a tag to compare

@FishInSalt FishInSalt released this 06 Oct 11:52

[0.2.3] - 2026-10-06

Added

  • Self-documentation. The npm package now ships docs/ (ten
    user-facing pages), examples/, and CHANGELOG.md; the default system
    prompt carries a docs routing section (absolute install paths plus a
    topic table) so the model can look up Ink's own documentation on demand.
    ink --version / ink --help verify an install non-interactively, and
    this page is the published changelog.
  • examples/README.md: an index of everything the examples directory
    ships (six extensions, the scout subagent, the ledger skill).

Changed

  • README restructured: getting-started first, the rename-from-imp section
    retired (its facts live in docs/cli.md, this changelog, and the design
    archive), npm/license/release badges, the full provider family list, and
    an agent-friendly install path (verify, one-shot -p, uninstall,
    no-lifecycle-scripts declaration, EACCES and trust-gate guidance).
  • package.json files now publish docs (with !docs/design),
    examples, CHANGELOG.md; the package smoke allowlist admits them.
  • Design archive moved to docs/design/ — historical design documents
    and review records no longer ship in the package.
  • web-search example README: reference sections compressed to summaries;
    full contracts remain in the design document.

ink-agent v0.2.2

Choose a tag to compare

@FishInSalt FishInSalt released this 06 Oct 09:20

[0.2.2] - 2026-10-06

Changed

  • Identifier follow-through (rename design Amendment A1, D1/D2). New
    child launch records write inkVersion (legacy impVersion records stay
    readable through a normalization arm; cross-version resume refusals are
    unchanged), and the child lease machine-id file is .ink-machine-id
    (orphaned .imp-machine-id files are never read, rewritten or deleted).
    No migration is needed or performed.
  • Codex originator (Amendment A1, D3). Codex (ChatGPT plan) requests now
    carry originator: "ink" instead of "imp".

ink-agent v0.2.1

Choose a tag to compare

@FishInSalt FishInSalt released this 06 Oct 03:55

[0.2.1] - 2026-10-06

Changed

  • Repository renamed to FishInSalt/ink. The GitHub repository moved from
    FishInSalt/imp (old URLs redirect). Package metadata (repository,
    homepage, bugs), the README and RELEASING.md now point at the new name,
    and the README install commands use ink-agent@latest. No runtime, CLI, or
    extension behaviour changed other than the version string; this is a
    metadata-only release, to be published from the reviewed tagged commit.

ink-agent v0.2.0

Choose a tag to compare

@FishInSalt FishInSalt released this 06 Oct 03:14

[0.2.0] - 2026-10-06

Added

  • guardian — the config-driven permission gate (#guardian). The
    shipped gate example is examples/extensions/guardian.mjs now: rules are
    plain text with * wildcards that span anything including newlines (or
    regex for full regular expressions), split into ordered deny / ask
    lists (deny wins), with an optional reason shown to the human and
    optional tool scoping — write / edit rules match the resolved file
    path, bash rules match the command. Anything unmatched runs; there is no
    allow action. A broken config keeps the last good rules (footer hint,
    /guardian reload); every deny/ask outcome is audited to
    ~/.ink/guardian.log. The ask picker red-highlights the span the rule
    matched (preview.warnSpans). An ask question left unanswered can now
    time out (askTimeoutMs, a new optional host-side deadline on
    api.confirm; the shipped template uses 10 minutes): the timeout counts
    as declined, is audited as timeout, grants no session memory, and
    reaches the model with its own wording, distinct from a manual decline.
    While a deadline is set, the picker's question line carries the dim
    countdown in parentheses right next to it (e.g. allow this bash command? (9:59), ticking down).
    The template was rebuilt around portable, catastrophe-only rules
    (whole-home and filesystem-root wipes, disk tools, the .ssh folder,
    remote-destroying git / gh operations). Start from
    examples/extensions/guardian.template.json; design and review log:
    docs/guardian-design.md.

  • Tool-name colors via extensions (#tool-name-colors). Tool names in the
    TUI call header can carry a color now, through a new load-gated extension
    registration api.registerToolColor(names, color) — one name, several, or
    "*", with any of the 16 standard-16 tokens, "none" (bold-only), or an
    absolute token: #rrggbb (truecolor) or ansi256:N (0–255). Named
    tokens follow the terminal theme; absolute tokens do not, by design.
    api.suggestToolColor(names, color) is the author tier: a tool's own
    extension suggests its default look, and any user registration outranks
    any suggestion (resolution: user exact > user "*" > suggested exact >
    suggested "*"). Nothing is colored by default; opt-in themes ship as
    extensions (the owner's palette lives in
    examples/extensions/tool-colors.mjs, which also doubles as the API
    example). Exact names beat the wildcard, the first registration of a key
    wins within its tier, hex is stored lowercased, and print/replay/legacy
    surfaces are untouched. Colors never affect layout — spans are applied
    after the row plan, so visible widths are unchanged; a colors-only theme
    counts in the startup banner (— 8 colors), suggestions as their own
    count (— 2 tools, 2 suggested colors). Design + three adversarial
    review rounds + three amendments: docs/tool-name-colors-design.md.

Changed

  • Node support and CI coverage. The minimum Node version is now 22.19.0,
    matching the pinned TUI dependency. CI checks that exact minimum and Node 24;
    CI and release gates require rg/fd instead of silently skipping search tests.

  • Ink rename (ink-agent@0.2.0). The product is now Ink, an
    open-source AI assistant and agent harness for the terminal. The sole
    executable is ink; there is no imp alias. Active configuration uses
    ~/.ink, project .ink, and INK_*, without automatic migration or
    old-name fallback. ImpSettings becomes InkSettings for source consumers.
    Ordinary session history can be preserved by a separately approved cutover;
    historical child sessions remain inspectable but are not resumable. Saved
    impVersion fields, .imp-machine-id leases, historical release records,
    and actual FishInSalt/imp URLs are retained. Publication uses new
    INK_NPM_PUBLISH_ENABLED / INK_NPM_PACKAGE gates; dispatch is always
    dry-run. Historical publishing capability needs separately approved
    retirement, and the first Ink publication needs its own reviewed design.

  • Task live view in its own header (#task-inline-live-rows). A running
    task call's live overview (the └─ pending #N … line with the agent and
    the elapsed time, plus its N tool starts · last: … row) moved out of the
    bottom activity region and into the transcript, directly under that call's
    own ● task header. Concurrent subagents therefore read top to bottom in launch order —
    header, its own live line, its own result — instead of all headers stacked
    above all overview rows.

  • Confirm prompt surface, Phase 1 (#confirm-prompt). The guardian-style
    approval ask is legible now: the transcript keeps one ▪ confirm: record line
    (the dim detail note is written only where no picker exists — readline,
    no-host and print paths are byte-identical), the picker numbers its rows
    (→ 1. Yes) on non-filterable pickers, digits 1–9 answer directly, and a
    dim affordance line sits under the items
    ((↑/↓ move · enter select · esc cancel · 1-3 quick pick)). Filterable
    pickers are untouched: digits stay query characters and no hint row is added.
    Design + five adversarial review rounds: docs/confirm-prompt-design.md.

  • Confirm prompt surface, Phase 2 (#confirm-prompt). Extensions can now say
    it in two structured fields instead of prose: preview renders the request in
    the transcript's own call-header idiom (● bash rm -rf …, the risky fragment
    alert-highlighted, never a completion suffix — the call has not run), and
    rememberLabel names what "don't ask again this session" will cover
    (Yes, don't ask again this session (this command pattern)). The host
    sanitizes both, so an extension can never inject terminal control sequences,
    and shows the command exactly once on every surface — in the picker where one
    exists, as one plain note line otherwise. Guardian passes both at its bash
    gate and a memory label at its write gate, dropping the command: prefix
    from its detail. Malformed values render nothing; hosts without a picker
    ignore the styling and stay byte-stable.

  • Confirm prompt surface, Phase 3 (#confirm-prompt). The approval moment now
    says who is asking and reads as one piece. The host names the caller —
    ▪ confirm: guardian — allow this bash command? in the transcript, a faint
    · guardian after the picker title, and blocked by extension guardian: in
    the block result — so extensions stop naming themselves (guardian drops its
    [guardian] prefixes) without any new API surface: the label is host-derived
    and cannot be spoofed. While a picker is open the activity region paints no
    tool rows: tool_start precedes the gate, so those rows used to claim
    running Ns although nothing was executing, and repeated the gated command a
    third time. Every picker now opens one blank row below the transcript, and the
    line you decide on (the extension's reason) renders at normal weight instead of
    faint — the (↑/↓ move …) affordance and the ▪ record lines stay faint.
    Design + three adversarial review rounds + a mutation-verified implementation
    check: docs/confirm-prompt-design.md §15.

  • Confirm prompt surface, Phase 4 (#confirm-prompt). The picker title no
    longer repeats the caller's name (allow this bash command? — the transcript's
    ▪ confirm: guardian — … record line already says who asks), and every picker
    box now opens with a horizontal rule carrying that name in the middle:
    ──────────────── guardian ────────────────. The rule is host-drawn from the
    same host-held name, so an extension cannot write a different one; the dashes
    are faint and the label sits at normal weight. Unattributed pickers get plain
    dashes, and the login dialog keeps its own frame. Design + two adversarial
    review rounds + a mutation-verified implementation check:
    docs/confirm-prompt-design.md §16.

  • TUI tool-call duration (#tui-tool-elapsed). Completed tool calls in the
    TUI transcript carry a marker — green ✓ for successes, red ✗ for
    failures — with a dim wall-time suffix when the call took ≥1s
    (● bash npm test ✓ 2.3s; 1m03s minute form); sub-second calls show
    the bare marker (amendments 2-3). Interruptions and replayed history carry
    none; legacy and print rendering are unchanged. Design + adversarial
    review: docs/tui-tool-elapsed-design.md.

  • Loop health monitoring + uncapped children (#loop-health). Subagents no
    longer stop at a 60-turn wall (CHILD_MAX_TURNS removed; owner decisions
    2026-09-29: no numeric valve, no prompt injection). A shared,
    observation-only loop-health monitor now runs in both the subagent engine
    and the main loop and detects three conditions from the existing event
    stream: repeated identical tool-call turns, repeated failed edit/write
    attempts, and the child's
    compaction-failure backstop. Child facts surface honestly (task-result
    lines + a health field on the TaskRecord); first fires render one dim
    REPL note (▪ health: …; INK_HEALTH=0 disables; thresholds overridable
    via INK_HEALTH_* env). Nothing is injected into any model context; print
    mode gains no health output of its own (a fired signal's task-result text
    change shows there only in the tool row's line count). Design + two-track
    adversarial review (plus two folded post-merge review rounds):
    docs/loop-health-design.md.

  • Startup model resolution (#startup-model-resolution). A machine whose
    only credential belongs to a non-anthropic family no longer demands a
    manual /model in every new session:

    • when the builtin startup default is unusable and exactly ONE credential
      source exists (the shared-MOONSHOT_API_KEY pair counts once), Ink
      resolves that family's curated switchHint (zai/glm-5.3, …) — one
      ▪ note, never written to settings, seeded as a non-explicit session
      model, print mode resolves silently;
    • /login auto-selects the fam...
Read more

imp-agent v0.1.0

Choose a tag to compare

@FishInSalt FishInSalt released this 26 Sep 16:41

Initial public release of imp-agent.

  • Interactive TUI (streaming, one-line tool status, queued steering and
    follow-up runs) plus print mode (imp -p "...") and piped stdin
  • Agent loop with tool execution: abort, validation, error feedback,
    steering hooks, and a compaction hook
  • Sessions: append-only JSONL message trees (~/.imp/sessions/),
    --continue / --resume <id> / imp sessions, the /tree navigator,
    /fork
  • Auto-compaction: older turns are summarized into a checkpoint near the
    context limit; the full history on disk is preserved
  • Tools: bash, read (offset/limit, images), edit, write, grep,
    find, ls, task (subagents); the search tools respect .gitignore
  • Providers: Anthropic, Z.AI (GLM), DeepSeek, Moonshot/Kimi, and OpenAI
    (API key or ChatGPT-plan OAuth); credentials from environment variables
    or /login
  • Extensions, skills, named subagents, MCP servers, markdown quick commands,
    and custom system prompts (SYSTEM.md)

See the README's Status section for the full current capability list.