You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(levelcode-ai): correct the group card's live state, aggregate order and labels
Four defects found by re-reading the reference transcript against what the
grouping actually did:
1. The aggregate read its clauses backwards ("Ran 2 commands, read and edited
PLAN.md"). Files lead, commands trail; a lone command is "a command", not
"1 command".
2. Groups were created collapsed, which hid the output of the step the header
claims to be running — the opposite of the fixed-footprint behavior it was
meant to give. The group body now stays open and each member collapses to a
one-line row as it finishes (collapseMember), so only finished work folds.
A failing step re-opens its own row and the group; the single-member unwrap
hands the card back expanded.
3. read_file and search derived their labels from arguments ("Read src/x.js")
where the reference shows the model's own sentence. Both now take a required
explanation, same as run_command; it titles the row and the raw tool text
drops to the tooltip.
4. None of the DOM behavior was executed by a test — only the pure grammar
functions and a syntax compile, which is why 2 shipped. test/groupReducer.js
extracts the real reducer functions and drives them through a fake DOM:
live header, member collapse, failure re-open, user-stop-is-not-failure,
unwrap, late background exit, idempotent close, grouping-off, label/tooltip.
Full extension gate green (20 suites).
Copy file name to clipboardExpand all lines: extensions/levelcode-ai/agent.js
+7-5Lines changed: 7 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -31,7 +31,7 @@ const SYSTEM_BASE = [
31
31
'- Use delete_file to remove an existing file (e.g. during a refactor). To RENAME/move a file, write_file the new path then delete_file the old one. Deletions are reviewable (Keep/Undo) and restorable from the per-turn checkpoint.',
32
32
'- Your file edits are APPLIED IMMEDIATELY and the user reviews them afterward in the editor with Keep/Undo — do NOT wait for approval, and do NOT re-edit a file you just edited. Only run_command still needs approval; if the user skips a command, adapt or stop.',
33
33
'- Commands that do NOT exit on their own (dev servers, file watchers, tail -f) MUST be run with run_command background:true — it returns immediately so you keep working instead of hanging. After starting one, call read_command_output with the returned id to watch for a readiness/port line (e.g. "listening on :3000") before you test against it. Use a normal foreground run_command for things that finish (builds, installs, tests, git, curl). This pairs with verification: bring the app up in the background, confirm it serves, fix, repeat.',
34
-
'- EVERY run_commandMUST include "explanation": 5-10 words, active voice, imperative, saying what the command does ("Run the extension unit tests", "Find the insertion point in section 10"). It becomes this action\'s label in the user\'s activity view — never omit it.',
34
+
'- EVERY run_command, read_file and search MUST include "explanation": 3-10 words, active voice, imperative, saying what you are doing and why ("Run the extension unit tests", "Find the insertion point in section 10", "Read the runAgent call site"). It becomes that action\'s label in the user\'s activity view — never omit it.',
35
35
'- Paths are relative to the workspace root. In a MULTI-ROOT workspace (several top-level folders), paths from list_files/search are prefixed with the folder name (e.g. "thin.ly/app/models/link.rb") — use them exactly as shown; an unprefixed path resolves against the first folder. To create a file in a specific folder, prefix its name. run_command accepts an optional "folder" to pick which folder it runs in.',
36
36
'- For a multi-step goal, call update_plan FIRST with a short checklist (3-8 short items, all "pending"), then call it again to set an item "in_progress" when you start it and "done" when finished. Skip the plan for trivial single-step goals.',
37
37
'- If the goal truly depends on a decision only the user can make (tech stack, scope, where to create files, must-have features), call ask_user ONCE with concise multiple-choice questions (a short header + 2-4 concrete options each) INSTEAD of writing the questions as prose. Put your RECOMMENDED option FIRST and use its description to say why — and, when it matters, what would change your mind. Then act on their answers and do not ask again. Do NOT ask about things you can reasonably decide yourself — prefer a sensible default and proceed.',
{name: 'read_file',description: 'Read a workspace file (path relative to the workspace root; in a multi-root workspace use the folder-name prefix exactly as list_files shows it).',input_schema: {type: 'object',properties: {path: {type: 'string'}},required: ['path']}},
46
-
{name: 'search',description: 'Search file contents for a literal string. Returns file:line snippets.',input_schema: {type: 'object',properties: {query: {type: 'string'}},required: ['query']}},
45
+
{name: 'read_file',description: 'Read a workspace file (path relative to the workspace root; in a multi-root workspace use the folder-name prefix exactly as list_files shows it).',input_schema: {type: 'object',properties: {path: {type: 'string'},explanation: {type: 'string',description: 'ALWAYS provide: 3-8 words, active voice, imperative — WHY you are reading this ("Read the runAgent call site", "Read agent.js tool definitions"). Shown to the user as this action\'s label.'}},required: ['path']}},
46
+
{name: 'search',description: 'Search file contents for a literal string. Returns file:line snippets.',input_schema: {type: 'object',properties: {query: {type: 'string'},explanation: {type: 'string',description: 'ALWAYS provide: 3-8 words, active voice, imperative — what you are looking for ("Find every postMessage call site"). Shown to the user as this action\'s label.'}},required: ['query']}},
47
47
{name: 'update_plan',description: 'Declare or update your task checklist for a multi-step goal. Pass the FULL list each time, each item with a status. Call it once up front (all pending), then again to mark an item in_progress when you start it and done when finished. Skip for trivial single-step goals.',input_schema: {type: 'object',properties: {todos: {type: 'array',items: {type: 'object',properties: {title: {type: 'string'},status: {type: 'string',enum: ['pending','in_progress','done']}},required: ['title','status']}}},required: ['todos']}},
48
48
{name: 'edit_file',description: 'Make a targeted edit to an EXISTING file: replace an exact, unique snippet (old_str) with new_str. Applied immediately; the user reviews it with Keep/Undo. old_str must appear exactly once — include enough surrounding context to be unique.',input_schema: {type: 'object',properties: {path: {type: 'string'},old_str: {type: 'string'},new_str: {type: 'string'}},required: ['path','old_str','new_str']}},
49
49
{name: 'write_file',description: 'Create a new file (or fully overwrite a short one) with the COMPLETE content. For edits to existing files, prefer edit_file. Applied immediately; the user reviews it with Keep/Undo.',input_schema: {type: 'object',properties: {path: {type: 'string'},content: {type: 'string'}},required: ['path','content']}},
@@ -276,7 +276,9 @@ async function runTool(tu, ctx) {
0 commit comments