Releases: suhail-akhtar/aico
Release list
aico 0.8.0
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
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
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:
cwdwas 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
AskUserQuestionboth wrote to stdout and read stdin — which undermcp-serveare the two halves of the JSON-RPC stream. Headless work now gets a decision from policy, never a dialog. maxConcurrentJobslimited 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
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.3andglm-5.3-flashboth matched theglm-5prefix and were billed identically, for models that differ ninefold.z-ai/glm-5.3-flashmatched 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 vendor —
deepseek/…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 EXISTScannot 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
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
dashboardblock 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
vizblock (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, amathblock 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:diagramsrenders 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
xlsxpackage 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 servewas
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 —claimTurnhad 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 auditis clean in this repository.form-data,ws,prismjsand
refractorwere upgraded;xlsxwas replaced.- One advisory reaches consumers and cannot be suppressed from here: ExcelJS
depends onuuid8, which has a bounds-check advisory inv3/v5/v6when a
caller supplies a buffer. ExcelJS callsuuid.v4()with no buffer, so it is
not reachable, butoverridesdo not transit to installers andnpm 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