Repository navigation
Release 0.14.0 - #63
Merged
Merged
Conversation
Adding a keyword from a repo resource that sits in the SAME directory as
the open file asked the user to pip-install it.
`resourceImportPath` returns a bare basename for a same-directory file
(e.g. `09_database.robot`), and `addLibrary` classified imports with
`endsWith('.resource') || includes('/')`. A `.robot` sibling matched
neither, so it was written as `Library 09_database.robot` (invalid RF)
and `skipInstallCheck` stayed false, which surfaced the pip-install
dialog via `libraries-changed` -> `onLibrariesChanged`.
Extract the classification as `isResourceImport()` in the pure
`resourcePath.ts` module and cover every RF resource-file extension
(.robot/.resource/.txt/.tsv, case-insensitive). Both symptoms derive
from the same flag, so both are fixed at the source.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Clicking a keyword lifts it into the add-bar above the tree; that bar now shows its documentation and source right there, so choosing the right keyword no longer requires opening the doc modal first. Project keywords had no doc to show at all: the repo parser extracted [Arguments] but not [Documentation], and they never go through libdoc, so `explorer.keywords` has no entry for them. Three gaps closed: - backend `parse_robot_keywords_in_repo` now parses [Documentation], joining row cells with a space and `...` continuation rows with a newline (RF semantics), using a real 2+-space/tab cell separator - `getKeywordInfo` consults `projectKeywords` first, mirroring the arg precedence (repo keywords shadow libraries) and reporting the source file as the origin - the palette renders a text preview via the new pure `docPreviewText` helper; libdoc HTML is flattened (block tags -> newlines) rather than rendered, since the column is narrow and the doc modal already exists BuiltIn docs are lazy-fetched on selection and memoized, guarded by a token against out-of-order resolution and by an exact-name check so `fetchKeywordInfo`'s first-hit fallback can't caption a keyword with an unrelated one's docs. Reuses the existing docModal.loading/noDoc strings, so no new i18n keys. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Closes #58. The explorer detected sections with `line.lower().startswith("*** keyword")`, which matches exactly one of the spellings RF accepts. Every other valid form fell through to the generic `startswith("***")` branch — which CLOSED the section instead of opening it. A file that parses and runs perfectly in RF therefore showed an empty keyword palette. The same check backed four surfaces, so they all went blank together: keyword discovery, test-case listing, tag discovery and the file tree's test counts. Now recognised, each verified against RF 7.4.2 rather than assumed: ***Keywords*** **** Keywords **** * Keywords *** Keywords *** Keyword *** (singular) a leading UTF-8 BOM *** 关键字 *** in a file declaring `Language:` The BOM case is the likely trigger behind the report: it only ever lands on a file's first line, which for a `.resource` file is its `*** Keywords ***` header — so a single invisible byte hid every keyword in the file. Still rejected, because RF rejects them too: tab-padded headers, and translated headers with no `Language:` declaration. Being more permissive than RF would be its own bug — the explorer would advertise keywords RF cannot resolve at run time. Header recognition moves into `explorer/rf_sections.py`, shared by all four call sites. Translated names come from `robot.conf.languages` (a hard backend dependency already) rather than a table maintained here, so new RF languages are picked up for free. `*** Tasks ***` now counts towards a file's test count. The editor's own parser had the same blind spot and rendered such files as an empty Flow Editor. Verified before changing it that content always survived the round-trip as preamble, so this was never data loss. Translated headers stay backend-only there — that needs RF's translation table, which the browser lacks. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Minor bump, not a patch: this cycle adds inline keyword documentation to the Flow Editor palette. 0.12.1 is already published. Also documents the palette's inline documentation in the in-app docs (EN/DE/FR/ES). README and the GitHub Pages landing page describe the palette only in general terms and needed no change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- frontend: vite 8, vitest 5, vue-tsc 3, TypeScript 5.9, vue-i18n 11, pinia 4, vue-router 5, js-yaml 5, jsdom 30; drop unused tsconfig presets - backend: uv lock --upgrade (RF 7.5, fastapi 0.141, cryptography 50, reportlab 5, rf-mcp 0.35, fastmcp 3.4); raise security-relevant floors - e2e/extension: Playwright 1.63 (+ matching Docker images), mocha 12, chai 6, eslint 10; npm audit clean - CI + frontend Docker image: Node 20 (EOL) -> Node 24 LTS - fix vue-tsc 3 TS2589/index typing in FlowEditor and StatsView Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
New venv_mode on environment creation: managed (default), system (interpreter RoboScope runs in) and existing (import a venv path). Non-managed modes are ADMIN-only, validated by probing the interpreter, never auto-created and never deleted from disk. Uninstalling packages from RoboScope's own interpreter is refused (409). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
GET /repos/{id}/diff?path= returns {path, status, diff, truncated}: the
unified diff of one working-tree file against HEAD. Untracked files show
as all-added, deleted as all-removed, binaries as diff=null. Output is
capped at 200 KB. A strict path guard rejects absolute paths, '..',
directories and anything that resolves outside the repo root (symlinks
included) with 400. Pathspecs are literal (no globs/magic). Local repos
get 409. Read access is the same as GET /status.
The PublishModal gets a lazy "Show changes" toggle on each file row. The
diff renders as escaped text in a <pre> with +/- lines coloured through
main.css vars. There is no v-html and no new dependency, and toggling
leaves the checkbox selection alone. i18n in EN/DE/FR/ES/ZH, plus
in-app docs in all four doc locales.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
- PATCH/DELETE /environments/{id}/variables/{var_id} (EDITOR). Keys are
validated as env-var names; a case-insensitive deny-list rejects
interpreter-hijack names (PATH, VIRTUAL_ENV, PYTHONPATH, PYTHONHOME,
PYTHONSTARTUP, PYTHONUSERBASE, LD_PRELOAD, DYLD_*, NODE_OPTIONS, ...).
Duplicate keys return 409. Secrets are re-encrypted on update; an empty
value keeps the stored secret.
- Fix: GET /variables masked secrets by mutating the ORM row inside a
committing session, which overwrote stored secrets with "********".
Responses are now built without touching the row, and POST masks too.
- resolve_env_vars() decrypts secrets only at injection time. Subprocess
runner merges them into the child env before PATH/VIRTUAL_ENV (those
still win); docker runner merges them before ROBOT_* run variables
(run variables win). Suites read them as %{NAME}.
- EnvironmentsView: add / inline edit / delete (confirm), secret values
as password input with an "(unchanged)" placeholder. i18n EN/DE/FR/ES,
docs updated in all four locales.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
- Cron validated on schedule create/update (CronTrigger.from_crontab, 422
on invalid); next_run_at maintained as naive UTC (server-local cron).
- Per-minute APScheduler heartbeat run_due_schedules(): fires due active
schedules once (missed slots coalesce), skips when the previous run is
still pending/running, or the creator is inactive/deleted, or the repo
is gone. Runs as the schedule's creator; never copies variables or
advanced config (gate tripwire stays green).
- POST /schedules/{id}/run (RUNNER+ effective role on the repo) starts a
run immediately without moving next_run_at.
- Deleting a schedule detaches its runs instead of violating the FK.
- Schedules table: Last run / Next run columns and a Run now button that
switches to the Runs tab and highlights the new run. i18n EN/DE/FR/ES,
in-app docs subsection on scheduling semantics.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
V14.3: GET /reports/{id}/export?format=csv|json. One row per TestResult
(suite_name, test_name, long_name, status, duration_seconds, tags,
start_time, end_time, error_message) via stdlib csv; cells starting with
= + - @ TAB CR are prefixed with ' (CSV injection). Bad format -> 422,
missing report -> 404. Export CSV / Export JSON buttons on the report
detail view and the run detail panel.
V14.4: DELETE /reports/{id} (204/404), gated by
require_effective_role_for_report(EDITOR); reports without a resolvable
repo (uploads, orphaned runs) fall back to the global role floor.
reports/service.py::delete_report is the single per-report helper and
DELETE /reports/all now loops over it. It only rmtrees the report's own
top-level dir under REPORTS_DIR (run_*/ or archives/<name>/), never the
root, archives/ or anything outside; ai_jobs.report_id is detached.
The linked ExecutionRun is kept (its report link resolves to null).
i18n EN/DE/FR/ES, in-app docs updated, pytest + vitest + one e2e spec.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
Minor bump: Epic V14 closes silent gaps found in a BMAD gap brainstorm (schedules now fire, environment variables reach runs, report CSV/JSON export, single-report delete, publish diff preview), adds environments backed by RoboScope's own Python or an imported venv, and upgrades all dependencies (Vite 8, Vitest 5, vue-i18n 11, Pinia 4, Vue Router 5, RF 7.5, Playwright 1.63, Node 24 in CI). Also fixes a venv-path line in the environment details that showed for API responses without venv_kind (caught by browser-library e2e). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
CI runners have no git identity, so 'git commit' exited 128 in Gate 5. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
…ces it SQLite does not enforce foreign keys, so deleting a repository left its runs, reports, schedules, recordings and KPI rows orphaned (then neither deletable nor cancellable, even for ADMIN); PostgreSQL returned a 500. delete_repository now removes runs via delete_report (report files too) and clears every other repositories.id reference found in the metadata. It is refused with 409 while a run is pending or running. The confirm dialog and docs (EN/DE/FR/ES) now say what gets deleted. Open since the 0.12.1 review. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
sync_repository returns git's error as a string, which sync_repo ignored, so a pull blocked by an uncommitted in-app edit still showed a green 'synced' state. The error now sets sync_status='error' with git's message (no retry: the failure is deterministic). Core of the draft PR #46 without its unrelated reformatting. Fixes #36 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
…rules (#58) The 0.13.0 fix for #58 covered explorer/service.py, but the visual editor's keyword search goes through ai/rf_knowledge._scan_repo_files, a second parser with the old header check and a non-BOM-safe read. A BOM-prefixed resource (typical on Windows) or translated headers (*** 关键字 ***) yielded no keywords there. It now reuses rf_sections and reads utf-8-sig. Also: a single non-ASCII character starts a keyword search (one CJK character is a real query), and keyword file paths are returned in POSIX form so the palette groups them correctly on Windows. Refs #58 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL
raffelino
marked this pull request as ready for review
September 25, 2026 20:29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release 0.14.0, stacked on the still-open 0.13.0 release (#62). Merge #62 first, or merge this one instead since it contains 0.13.0.
What's in it
_bmad-output/planning-artifacts/v014-epics.md):%{NAME}), with a deny-list for names that hijack the interpreter.********.Verification (local, macOS arm64)
browser-libraryfailed and was fixed;flow-editor-template:82failed once in the full run but passes in isolation (flaky)./healthreports 0.14.0. The own-Python environment was exercised against the installed build.🤖 Generated with Claude Code
https://claude.ai/code/session_01GReqJWK77kV77FkNvsLgrL