feat: update agents, tools, permissions and web UI - #36
Conversation
- lex.toml: switch to git deps - src/agents/*: build, explore, plan, refactor, review, spec, test agents updated - src/permissions/rules.lex, manifests.lex: permission rules and manifests - src/tools/index.lex, os_check.lex: tool index and OS check tool - src/server/web.lex: web server - src/web/index.html: updated UI Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| let mode := util.field_str_or(args, "mode", "build") | ||
| match proc.spawn("lex", ["--output", "json", "check", path]) { | ||
| Err(msg) => Err(e.single("", "proc_error", msg)), | ||
| Ok(out) => if out.exit_code != 0 { | ||
| Err(e.single("", "lex_check_failed", str.concat(out.stdout, out.stderr))) | ||
| } else { | ||
| match jv.parse(out.stdout) { | ||
| Err(_) => Err(e.single("", "parse_error", "could not parse lex check output")), | ||
| Ok(parsed) => { | ||
| let required := extract_effects(parsed) | ||
| let forbidden := forbidden_for_mode(mode) |
There was a problem hiding this comment.
Medium: mode is supplied by the tool caller and defaults to build, so forbidden_for_mode returns no forbidden effects for build or any typo/unknown value. A prompt-injected refactor agent can call os_check with mode: "build" and receive grant check passed for code that uses net, bypassing the trust-grant check this tool is meant to enforce. Bind the mode from the active session or validate an enum and fail closed.
| lex-llm = { git = "https://github.com/alpibrusl/lex-llm" } | ||
| lex-agent = { git = "https://github.com/alpibrusl/lex-agent" } | ||
| lex-trail = { git = "https://github.com/alpibrusl/lex-trail" } | ||
| lex-spec = { git = "https://github.com/alpibrusl/lex-spec" } | ||
| lex-schema = { git = "https://github.com/alpibrusl/lex-schema" } | ||
| lex-os-manifest = { git = "https://github.com/alpibrusl/lex-os-manifest" } | ||
| lex-web = { git = "https://github.com/alpibrusl/lex-web" } |
There was a problem hiding this comment.
Medium: these new Git dependencies are unpinned and there is no lockfile in this repo. Future installs/builds will resolve mutable default branches from these remote repos, so a compromised repo or force-pushed branch can inject code into lex-code builds. Pin each dependency to an immutable commit/tag, and commit a lockfile if Lex supports one.
There was a problem hiding this comment.
Found and fixed two high-severity regressions from this PR in follow-up PR #37: #37
Bug and impact:
os_checkwas bypassable in refactor mode. A refactor agent could callos_checkwithoutmodeor withmode: "build", causing files with forbiddenneteffects to be reported as passing the grant check.- The web UI defaulted to Ollama while every Ollama agent variant in this PR has
tools: []andmax_steps: Some(3), making the default browser experience unable to read/write/grep/check code.
Root cause:
os_checktrusted a model-suppliedmodeargument and defaulted to the full build grant.index.htmlselected Ollama by default despite the Ollama agents being intentionally chat-only in this PR.
Fix and validation:
- PR #37 removes the caller-controlled
modeparameter fromos_checkand fixes it to the currently permitted refactor grant. - PR #37 restores Anthropic as the web UI default provider.
- Validation performed: source regression checks, local static web serving check, and browser walkthrough confirming the provider dropdown defaults to Anthropic.
lex check .could not run because thelexCLI is not installed in this environment.
Sent by Cursor Automation: Quality of PR Lex
|
|
||
| fn execute(args :: jv.Json) -> [net, io, proc] Result[jv.Json, e.Errors] { | ||
| let path := util.field_str_or(args, "path", ".") | ||
| let mode := util.field_str_or(args, "mode", "build") |
There was a problem hiding this comment.
This defaults omitted mode to build, and the model can also explicitly pass mode: "build". In refactor mode that bypasses the new trust-grant check: a Lex file requiring net effects is checked against the full build grant, so forbidden_for_mode returns no violations and the tool reports a pass instead of the expected refactor grant violation. I fixed this in PR #37 by removing the caller-controlled mode from the schema and binding this tool to the refactor grant.
| </label> | ||
| <label>Provider | ||
| <select id="provider-select"> | ||
| <option value="ollama" selected>Ollama</option> |
There was a problem hiding this comment.
This makes the default browser path select Ollama, but this same PR changed every ollama_agent() to tools: [] and max_steps: Some(3). A user opening the web UI and sending a normal build/explore/refactor task gets a chat-only agent that cannot read, write, grep, or run checks. PR #37 restores Anthropic as the default so the initial web experience uses a fully-tooled provider.
- build.lex: add vertex_agent() using vtx.gemini_35_flash() + providers.vertex();
fix ollama_agent() to use all_tools() and max_steps=20 (was empty tools + 3 steps)
- session.lex: route "vertex" provider tag to vertex_agent() for Build mode
- main.lex: add --vertex flag, run_headless() function for headless/CI use,
and collect_final_text() that prefers StepDone over TextChunk accumulation
run_headless emits [AGENTCMP_RESULT]\t{"ok":…,"final":…} sentinel so the
agentcmp lex_code adapter can parse results without screen-scraping.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>


Summary
lex.toml: path → git depsTest plan
lex check src/**/*.lexlex test tests/🤖 Generated with Claude Code