Skip to content

LevelCode editor: activity timeline, approval redesign, error handling + reliability - #2

Merged
ndemianc merged 7 commits into
developfrom
chore/levelcode-completeness-sweep
Jul 10, 2026
Merged

LevelCode editor: activity timeline, approval redesign, error handling + reliability#2
ndemianc merged 7 commits into
developfrom
chore/levelcode-completeness-sweep

Conversation

@ndemianc

@ndemianc ndemianc commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

The full LevelCode editor pass from this cycle. Builds on the atom-*levelcode-* rename.

Agent activity (chat webview)

  • Activity timeline — tool/command actions thread a single rail (GitHub-commit style). Executed commands render as collapsible Copilot-style cards: RunningRan header with command chips + live state, the command with lightweight shell syntax highlighting, streamed output visible by default, an exit/duration status foot, and the agent's intent in italics.
  • Falling-dots progress — a Copilot-style cascading-dots indicator replaces the spinner while a command runs.
  • Command approval redesign — quiet Cursor/Claude-style ask card (no macOS-terminal chrome) with Enter/Esc keyboard shortcuts; collapses to a one-line verdict.
  • Collapsible question + plan panels, plan redesign with professional status icons + progress bar, and a compelling plan-aware cap/upgrade card.

Error handling (pairs with thin.ly #341)

  • Providers forward the structured error code; a neutral "service temporarily unavailable" card renders for our-side outages instead of a red error — distinct from the accent upgrade card (reserved for a real user-wallet cap). No raw provider text reaches the UI.

Reliability / build

  • Refresh-on-401 retry in the agent loop (long agent runs no longer die on a mid-run token expiry).
  • apply-branding.mjs prunes stale renamed-away extensions (fixes duplicate-command registration); run-dev.sh skips the broken Copilot compile.
  • Branding: correct GitHub org in product links (levelcodelevelcodeai).

All webview changes were verified in a static harness in both light and dark themes (rail continuity, highlighting, dots animation, collapse/expand, approval Enter/Esc, service card), no console errors.

🤖 Generated with Claude Code

ndemianc and others added 7 commits July 8, 2026 13:15
Long/looping agent runs 401'd (Signature has expired) — only the chat path refreshed the access token on 401; the agent loop was called raw. Add isAgentAuthError + wrap the turn call: on a 401 before any content has streamed, refresh once (via a ctx.refreshAuth hook wired in extension.js), update ctx.apiKey, and retry the turn once. Mid-stream/second failures propagate; BYOK / refresh-failed rethrow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rade card

ask_user and update_plan panels get a collapse/expand header (plan collapse state persists across re-renders). Plan redesign: professional .ci status icons (check / spinning sync / circle), a progress bar + count pill, refined rows. Free-tier cap (402 cap_reached) now renders a compelling upgrade card (plan-aware: paid users get a Manage-plan button) instead of raw error JSON.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…le in dev

apply-branding.mjs prunes orphaned LevelCode extensions from vscode/extensions (renamed-away atom-* copies double-registered commands). run-dev.sh compiles the client only (compile-client), skipping the proprietary Copilot build (stripped/disabled anyway, and broken under Node 24 by a glob CJS/ESM error).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ots, approval redesign

Rework the agent's command/tool activity into a connected timeline (rail + nodes). Executed commands render as collapsible GitHub/Copilot-style cards: a Running→Ran header with command chips + live state, the command with lightweight shell syntax highlighting, streamed output visible by default, an exit/duration status foot, and the agent's intent in italics. A Copilot-style falling-dots indicator replaces the spinner while running. run_command approval is redesigned as a quiet Cursor/Claude-style ask card (no macOS-terminal chrome) with Enter/Esc keyboard shortcuts that collapses to a one-line verdict. agent.js posts the command explanation so the card can show the why.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… upgrade card)

Pairs with thin.ly's upstream-error sanitizer (PR #341): the gateway now returns a safe, classified error, so the editor picks a calmer presentation. Providers forward the structured error 'code'; agent.js and extension.js pass it along on agentError/assistantError; chat.html adds isServiceIssue + addServiceCard — a neutral notice (amber warning icon, no accent, no CTA) — and routes service_unavailable / service_busy / gateway_error to it, keeping the accent upgrade card reserved for a genuine user-wallet cap. Even if the code fails to propagate, the gateway message is already sanitized, so no raw provider text can reach any branch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
licenseUrl / reportIssueUrl / releaseNotesUrl in product.overlay.json pointed at github.com/levelcode/levelcode; the canonical repo is github.com/levelcodeai/levelcode.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ndemianc ndemianc changed the title rename extensions from atom-ai to levelcode-ai LevelCode editor: activity timeline, approval redesign, error handling + reliability Jul 10, 2026
@ndemianc
ndemianc merged commit 6a55986 into develop Jul 10, 2026
1 check passed
@ndemianc
ndemianc deleted the chore/levelcode-completeness-sweep branch July 10, 2026 03:16
ndemianc added a commit that referenced this pull request Jul 24, 2026
All five points were real. Two of them made the tool quietly report LESS than
the truth, which is the failure mode that matters most for something whose whole
job is producing accurate facts.

1. prevTag was interpolated into a shell string. A tag name is repo-controlled
   but still runtime-discovered input, so this is now defended twice: all git
   calls go through spawnSync with an argv array (a shell cannot be quoted out
   of one), and the base tag must match ^vX.Y.Z$ before use. Shape matters
   independently of injection — a stray v0.9.2-rc1 sorts into the 'v*' glob and
   would silently produce the wrong range, wrong commit list and wrong compare
   link. Verified: v0.9.2-rc1, v-wip and "v0.9.2; rm -rf /" are all rejected.

2. PRs were only detected from merge commits, so on a squash-merging repo the
   list would read "(none detected)" while every subject carried "(#123)". Both
   shapes are now collected.

3. Suites were keyed by basename, so two extensions with the same test filename
   would produce an ambiguous "biggest suites" list. Keyed by relative path now.

4. The coverage line printed "N cases in total" while suites whose summary could
   not be parsed silently contributed 0 — authoritative-sounding and UNDER-
   reporting. This one bit immediately: 5 of 24 suites do not print a count, so
   "273 cases in total" was wrong. It now says how many suites were counted and
   names the ones that were not.

5. The fix/perf heading also carried reverts; renamed to say so.

Also fixes a bug I introduced while making #2: prNumbers became a Set, but the
renderer still read .length, which is undefined on a Set — so the PR list emptied
itself silently. Caught by re-running against the real range (expected #33-36,
got "(none detected)"). Materialised to a sorted array.

Verified end to end against v0.9.1..HEAD: PRs #33-36 detected, coverage line now
honest about the 5 unparsed suites, and all guardrails still fire.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant