Skip to content

0.16.0

Choose a tag to compare

@suhail-akhtar suhail-akhtar released this 08 Sep 14:40
· 9 commits to main since this release

Found by watching real models build apps from the wizard, end to end, on a
scratch store — and fixing what made them wander. Measured before release:
DeepSeek V4 Pro built the whole API brief (eight stories, four verifier calls
with twelve step checks) in sixteen minutes for fifteen cents, and five of six
dashboard stories with zero console errors and no sideways scroll at 1280px or
390px; it scores the five app skills at 96, 70, 75, 80 and 100 percent. GLM 5.3
Flash reaches the same places more slowly and, reading images, receives the
verifier's screenshots.

Added

  • Checks that follow a requirement. VerifyApp checks take steps — goto,
    click, fill, select, press, wait — and an expect of a selector, { text },
    { url } or { absent }, so "add a customer" is fill, submit, see the row.
    Checks in one call share a page and its cookies, so a sign-in check first
    leaves the rest signed in. screenshot: true saves a PNG after load and
    after each check under .aico/screenshots/ and names the paths;
    viewport is documented for the phone width. A failed check says what was
    done and what was missing ("filled #name, clicked #add, but nothing matched
    .row"). Before this a check could click one selector, and the agent, asked
    to verify a form flow, installed a browser MCP and wrote its own driver.
  • A design skill. app-design says what a screen people pay for looks
    like — one shell, hierarchy and rhythm, tokens not hex, real empty, loading
    and error states, forms and tables, 390px and keyboard — with the six shapes
    as Tailwind sketches in its references, an eval task, and a place in the
    plan and platform skills.
  • The SaaS template has a product shell. Signed in: side navigation from
    one nav.ts list, a page header with the counts and the primary action,
    StatCard, StatusPill and EmptyState components, a menu under md.
    Signed out: a front door without placeholder copy. Success and warning
    tokens, an icon, and a sentence in AICO.md naming the components and the
    design skill.
  • Apps are runnable the moment they exist. Create writes .env.local from
    a template's .env.example with every change-me value replaced by a
    generated secret. The first sign-up used to throw "SESSION_SECRET is
    missing" and the agent spent twenty steps on a form that was fine.
  • A bound conversation starts with the app. The empty state names the
    app, its backlog progress, and offers "Build the next story", "Review what
    is built" and "Plan the next iteration".
  • GUIDE.md has "Building an app" and the learning paragraph.
  • Eyes for the verifier. When the session's model reads images, the
    screenshots a VerifyApp call saved are stored as attachments and shown to
    the model on the next step, with a note to look at them as a person would.
    Text-only models keep the paths for the person. GLM 5.3 Flash and the
    DeepSeek V4 Flash vision build are marked as reading images.
  • Checks are not spent twice on unchanged code. RunChecks remembers the
    last green run per project; with no file written through the tools and no
    shell command since, it answers with that result instead of a minute of
    build. force: true runs them anyway.
  • Two live probes. scripts/apps-build-live.mjs drives the whole loop with
    a real model — create from a template, plan, build story by story, rate a
    reply and keep the proposal it produces, steer a turn, deploy, then open
    every screen in a browser at two widths — and never cuts a busy turn short.
    scripts/skill-eval-live.mjs scores the five app skills against their tasks.
    npm run test:apps:build, npm run test:skills:live.

Fixed

  • The app-state line was computed once per turn. It said "installing"
    through twenty steps of a running app, and the agent reported the state as
    inconsistent and spent steps reconciling it. The caller's volatile sections
    are now re-read before every step.
  • MCP tools added mid-turn were not callable. McpAddServer loaded the
    server and said "24 tools", but the tool list the model saw was built at the
    top of the turn, so it guessed at names. The set is synced before each step.
  • A browser-cancelled request is not a failure. net::ERR_ABORTED on a
    form POST answered by a redirect was reported as "request failed".
  • The side rail floated over the app panel. Plan, checks and task cards
    were fixed to the window's edge; they now anchor to the chat column.
  • A build check knocked the running dev server over. next dev and
    next build wrote to the same .next; the two Next.js templates now give
    development its own directory (.next-dev), which the engine's file lists
    skip, and the health check answers 200 through a build. The dev server's
    generated route types stay out of npm run typecheck, so deleting a page
    no longer fails the check until the server has noticed.
  • OpenRouter's output ceiling was 8,192 tokens. A reasoning model routed
    through the gateway reached it mid-thought, with nothing written and the
    step reported as cut off. The default is 32,768, as for Z.AI first-party;
    providers.openrouter.maxOutputTokens overrides it.
  • A router's model id went to the wrong gateway. With a direct vendor
    active, z-ai/glm-5.3-flash was sent to a compatible endpoint that had
    listed its two models and named neither, and every skill evaluation and a
    whole build failed with "please check the model you provided". A gateway
    that lists the model wins; then OpenRouter; then one that has said nothing.
  • A rating given after a turn ended was never extracted. The person reads
    the reply, then clicks 👎, so the rating lands after turn/end; extraction
    at the end of the next turn only looked at that turn. It now also reads the
    previous turn's ratings. Proposals from a session bound to an app are filed
    with the app, not the workspace every app session shares.
  • The API template answered a browser with not_found. Its front door now
    says what it is and where the OpenAPI document and health route are, and it
    answers the favicon request a browser makes on every visit, which used to be
    the one console error on an otherwise clean run.
  • A finished install read as "Stopped". The work ledger closed a
    completed npm install as a stopped server; it now says "Installed", and an
    app that starts again after an ended record opens a new one.
  • Money is not maths. "$240.00 (subtotal $200.00)" in a reply rendered as
    a formula. A dollar that opens a plain number is escaped before the maths
    pass; $x^2$, display maths, code spans and fences are untouched.
  • Paths read relative to the project or the app. Tool rows and the turn
    summary showed sixty characters of temp directory before the file name; the
    project root is stripped, and inside a bound app everything up to the app's
    directory is.
  • The layout probe's app host takes a port of its own, so an aico already
    serving on the machine no longer makes the workspace screen fail.
  • Ranking tests, workspace-root idempotence test, and the templates probe
    (42 checks) were run before this entry.