Skip to content

Releases: suhail-akhtar/aico

aico 0.8.0

Choose a tag to compare

@suhail-akhtar suhail-akhtar released this 01 Sep 20:56

The editor release. aico gets three tools only VS Code can service, the panel
catches up with the browser client, and a Windows bug that broke every
multi-line edit is fixed.

Fixed: every multi-line edit failed on Windows. core.autocrlf defaults to
true there, so a checked-out file holds \r\n — and Read was leaving a
carriage return on the end of every line it showed the model. A model cannot
see one and does not reproduce it, so Edit reported "the string to replace
was not found"
and re-reading changed nothing. Only single-line edits worked.
Read now normalises, Edit matches in the file's own endings, and Write
keeps the endings a file already had.

Tools only the editor can run. VSCodeDiagnostics reads the Problems panel,
so after an edit the agent can ask the language server what it thinks instead of
grepping for the shape of an error. VSCodeTasks runs what is already in your
tasks.json. VSCodeWorkspace creates, adds and opens folders. Offered only
while an editor is attached.

The panel caught up. Delegation is visible, @ addresses a specialist, a
conversation can be renamed, forked or archived, a message can be edited and
sent again with version arrows, plans can be accepted or amended, and there is a
session goal and a provider switcher.

Reasoning effort, per model, from a verified table. Sent in each provider's
own shape. auto means send nothing — which for several vendors is adaptive
per request and for others is a fixed level, and the button now says which.

A shell whose commands exist. Git Bash, then PowerShell, then cmd, with
the prompt naming which one.

Full notes: https://github.com/suhail-akhtar/aico/blob/main/CHANGELOG.md

The attached .vsix is the VS Code extension (0.6.0):
code --install-extension aico-vscode-0.6.0.vsix

0.7.0 — a native VS Code panel

Choose a tag to compare

@suhail-akhtar suhail-akhtar released this 01 Sep 08:33

aico gets its own tab in the Secondary Side Bar beside Chat — the same mechanism Claude Code and Codex use, with no proposed APIs.

It is not the web workspace in a frame, and not a second implementation either: the state layer, the reducer and every transcript component are the browser client's, imported unchanged. The panel is a view over them, styled from your editor theme, so tool cards and diffs match the file next to them.

Edits arrive through the front door. A write applies as a WorkspaceEdit, so Ctrl+Z takes it back and it shows in Source Control. A file changed behind the editor's back can do neither.

It knows what you are looking at. Active file, selection with its line range, and that file's Problems — as removable chips, so it is never a guess what a message will carry. # points at another file or a symbol. The rule: inline what nothing else can recover, merely name files that Read can fetch.

Approvals are real dialogs. Auto (unchanged, still the default), ask-but-not-for-edits, or ask every time. Terminal is deliberately not in the edits pass-through list.

Fixed

  • The extension registered a second project for the folder you had open — VS Code reports Windows paths with a lowercase drive letter while everything else uses uppercase, and the registry compares strings. Sessions started from a terminal stopped appearing in the panel.
  • An untrusted folder disabled the extension in silence. The manifest now declares capabilities.untrustedWorkspaces, so Restricted Mode explains it and offers a Trust button.
  • Opening the panel started a fresh conversation every time, losing the model with it. It now resumes the folder's last conversation.
  • A turn could block forever on stdin when permissions were gated with no callback registered.

Not in this release

VS Code as a tool surface — workspace creation, terminal and diagnostics as tools the agent can call. It needs a per-run source of tool definitions plus execution dispatch, and deserves its own pass.

The extension is not on the Marketplace; build it from vscode-extension/.

0.6.0 — supervision, watchers and an MCP server

Choose a tag to compare

@suhail-akhtar suhail-akhtar released this 31 Aug 15:21

What is running, and what happened while you were away

One work ledger. Sub-agents, background agents, backgrounded shell commands, Mini App servers, cron firings and watchers now share one record shape, one id space and one append-only log. There used to be five separate registries, so nothing could answer "what is running right now?" — there was nowhere to ask.

A restart no longer loses work silently. The log is replayed at startup: a process whose pid is still alive keeps running, everything else is marked lost with a reason. A crash used to leave no trace at all — "it finished" and "it never came back" looked identical afterwards.

Limits the platform enforces. Set deadlineMs, maxCostUsd, maxSteps or idleMs once, with an action of report, stop or kill, and stop checking back. Idle is deliberately separate from a deadline: an agent that has worked hard for an hour and one that has made no call in ten minutes are different failures.

Watchers. Wait for a file, a process, an HTTP endpoint, a command, a log pattern or another job, and be woken when it happens. One turn to register, one to be woken by — instead of a full turn per poll.

aico mcp-serve. aico speaks MCP on stdin and stdout, so Claude Code or any MCP client can hand it work. Nothing listens: no socket, no port. Six tools, deliberately not Read/Bash/Edit — the surface is delegation, not remote control. Read-only unless started with --allow-writes, because consent does not transfer: ticking auto-approve for your own session is not the same decision as letting an unattended process edit your repository.

Supervise replaces AgentSupervise, which could see sub-agents and nothing else. Outcomes stay listed until acknowledged — losing a failure to whichever turn glanced at it is how a background job becomes a mystery an hour later.

Fixed — scheduled jobs that quietly did nothing

Four separate causes, all found by running it rather than reading it:

  • cwd was never forwarded to the agent. Every background agent and every cron job ran in the server's directory, so a nightly job pointed at a repository wrote its files somewhere else and looked, from that repository, exactly like a job that had done nothing.
  • Two prompts could hang a headless run forever. The permission gate and AskUserQuestion both wrote to stdout and read stdin — which under mcp-serve are the two halves of the JSON-RPC stream. Headless work now gets a decision from policy, never a dialog.
  • maxConcurrentJobs limited nothing — it counted dispatches, which are fire-and-forget.
  • A slow job stacked copies of itself. One scheduled every minute that takes an hour started sixty.

Also: background agents reported no token usage, so a spend ceiling compared against zero and could never fire; stop reasons were being overwritten by generic ones; and MCP servers with a space in their command failed on Windows with only "MCP process exited unexpectedly" to go on — which is the default Node install path.

Verified

2,273 offline assertions · 190 web UI · 31 web reducer · 35 Mini Apps over real HTTP · plus live suites that drive a real daemon, real child processes, real sockets and real models: 25 watcher · 37 mcp-serve · 13 MCP client · 15 daemon · 18 cron · 28 MCP end-to-end · 11 permission.

Install

npx github:suhail-akhtar/aico#v0.6.0 serve

Requires Node 22.5 or newer. Full notes in CHANGELOG.md.

aico 0.5.0

Choose a tag to compare

@suhail-akhtar suhail-akhtar released this 30 Aug 20:16

Mini Apps, sub-agent supervision, and a run of corrections that only surfaced by using the thing.

Requires Node 22.5 or newer (was 20). node:sqlite ships from 22.5 and Mini Apps are built on it, so an older install stops rather than degrades. That is the only breaking change.

npx github:suhail-akhtar/aico#v0.5.0 serve

Mini Apps

Ask for an invoice ledger or a habit tracker and get a real application with a database behind it, at its own local URL, still there tomorrow. Two kinds:

  • A page — one HTML file with Alpine over a shared server that runs no code the model wrote. Nothing to install; serving the moment it is saved. Apps never send SQL: the page names a table and passes values, and the server builds the statement.
  • A Next.js app — its own server, routing, dependencies and process, for when the job needs server-side logic or a database that is not SQLite. Its own port makes it its own origin, and its environment is stripped of every key, token and password by pattern. What is not contained is written down too: it runs Node as you.

Each app gets its own conversation. Open it and ask for a change; its identity, schema and file list sit in the cached prefix rather than being re-sent each turn. Off by default — Settings → Mini Apps, effective immediately, no restart.

Sub-agents you can see and steer

A delegated turn used to go blank: the parent made one Task call and everything interesting happened where the page could not see it. There is now a panel showing each child, the tool it is inside, its elapsed time and cost — and you can correct one mid-run without losing what it has learned, or stop one without taking down its siblings.

Fixed

  • GLM priced from its published list rather than its name. glm-5.3 and glm-5.3-flash both matched the glm-5 prefix and were billed identically, for models that differ ninefold. z-ai/glm-5.3-flash matched nothing at all and fell through to an invented rate.
  • GLM no longer capped at 8K output. A ceiling below what a model can write truncates the tool call, and a half-emitted call does nothing at all.
  • A routed model id no longer goes to a direct vendordeepseek/… was being sent to api.openai.com, which answers "invalid model ID".
  • Memory and goals are followed. Memory sat above the safety rules and was never restated; a standing goal appeared once at the top of the prompt and, on a twenty-step turn, thousands of tokens behind every decision after the first.
  • Sessions nobody used are no longer saved. Opening the workspace against a folder used to leave a placeholder conversation behind permanently.
  • A Mini App schema can change. CREATE TABLE IF NOT EXISTS cannot add a column, and the open handle never re-read the file — so an agent asked to add one saw its change vanish, decided the app was broken, and deleted it.
  • Sub-agents ran in the wrong directory on a multi-workspace server.

Verified

2,122 offline assertions, 190 web-client checks, 35 Mini Apps checks over real HTTP, plus live runs against a real model: a sub-agent corrected mid-flight, a bound section changing an app in place, and one app of each kind built from scratch and then opened and used.

Full detail in CHANGELOG.md.

v0.4.0 — dashboards, statistical graphics, 26 diagram types, mathematics

Choose a tag to compare

@suhail-akhtar suhail-akhtar released this 28 Aug 15:13

A release about the chat surface: what the agent can draw, and what happens
when a drawing goes wrong.

Added

  • Branch a conversation from any point in it. Every message offers it, and
    the two sides mean different things: from a reply the branch ends with that
    reply, and from your own message it ends just before it with the text handed
    back to the composer. The cut is a turn rather than a message, because a tool
    call and the result answering it can be several events apart and every
    provider rejects a request holding one without the other.
  • Dashboards in the chat. A dashboard block takes KPI tiles with
    sparklines and a responsive grid of chart, viz and table panels — one fence,
    one board, one frame. Asked for "a single dashboard view" the agent used to
    write a standalone HTML file, correctly, because chat blocks are one per fence
    and nothing else was possible.
  • Statistical graphics through a viz block (Vega-Lite). Binning,
    aggregation, regression, loess, density, quantiles, window functions, box
    plots, error bars and faceting are computed by the library from raw rows,
    rather than pre-computed by the model and emitted twice.
  • Mathematics, which was always rendering and was never advertised. $x^2$
    inline, $$…$$ on its own line, a math block with the frame's controls,
    and chemistry via \ce{2H2 + O2 -> 2H2O}.
  • Twenty-six diagram types instead of six. C4 at every level including
    deployment and dynamic, cloud architecture, block, packet, requirements,
    gantt, timeline, kanban, mindmap, quadrant, gitGraph, journey, sankey,
    treemap, radar and the rest — all from the mermaid already in the tree, none
    of which had been mentioned. npm run test:diagrams renders every one in a
    real browser so the list describes this build rather than mermaid's docs.
  • Zoom and pan on diagrams, with the controls over the drawing. Plain wheel
    still scrolls the page; zoom is on the buttons and ctrl/⌘+wheel.
  • WidgetSpec, which hands back the exact shape of any drawable block, or
    of a single diagram type. The catalogue carries a one-line summary per kind in
    the prompt and the full contract behind this tool, so adding kinds does not
    grow the text billed on every request.

Changed

  • Widget controls are icons with tooltips, each carrying its label as an
    accessible name.
  • Diagrams live in the same frame as everything else — same copy, download,
    expand and hide, and for the first time the same repair path when one fails
    to parse. Expanding fills the window and Escape leaves it.
  • Repairing a widget no longer holds a conversation about it. The corrected
    version replaces the broken one in place and the exchange stays out of the
    transcript, though the log keeps every word. A repair that produced nothing
    stays visible, because a widget marked "being fixed" with no explanation is
    worse than the noise.
  • Spreadsheet attachments are read through ExcelJS. The xlsx package is
    abandoned on npm at 0.18.5 with a prototype-pollution and a ReDoS advisory,
    both in the parser, and this code parses files a user uploaded.

Fixed

  • Sessions started from the web ran in whatever directory aico serve was
    launched in — usually AICO's own checkout — rather than the configured
    workspace. The server was already right; the client named a project on every
    request, so the correct default was unreachable.
  • The model a session is held with is remembered. It used to live in browser
    state, so it reverted to the global default on reload with nothing to say it
    had. Choosing in Settings sets the default without silently pinning whichever
    chat was open, and a pinned session says so and can follow the default again.
  • Queue did nothing at all. Messages went into a queue that was never
    drained — claimTurn had no callers anywhere. Steer worked and looked broken
    for the opposite reason: it lands at the next step boundary and said nothing
    in the meantime. Both now show what was accepted and when it will run.
  • Charts stopped flickering and hidden widgets stopped reappearing when a new
    message streamed. react-markdown reconciles by component identity, so a
    rebuilt component map remounted every fenced block — the charts were not
    redrawing, they were being destroyed and rebuilt.

Security

  • npm audit is clean in this repository. form-data, ws, prismjs and
    refractor were upgraded; xlsx was replaced.
  • One advisory reaches consumers and cannot be suppressed from here: ExcelJS
    depends on uuid 8, which has a bounds-check advisory in v3/v5/v6 when a
    caller supplies a buffer. ExcelJS calls uuid.v4() with no buffer, so it is
    not reachable, but overrides do not transit to installers and npm audit
    will report it. It replaced two advisories that were reachable.

Install

npx @suhail-akhtar/aico@0.4.0

Full diff: v0.3.0...v0.4.0