Skip to content

Commit 79c43ad

Browse files
committed
chore(chat-plugin): sync robotcode skill from agent-plugins
1 parent 37d7079 commit 79c43ad

3 files changed

Lines changed: 164 additions & 36 deletions

File tree

chat-plugins/.upstream.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"source": "github.com/robotcodedev/robotframework-agent-plugins",
3-
"sha": "78ca270f5cfa755c3ce545dc6fbfb6d1eb614fa3",
4-
"syncedAt": "2026-06-07T22:45:13+00:00"
3+
"sha": "4e348b3ae7ca7939e1fc4b331de1748fb68a1b27",
4+
"syncedAt": "2026-06-08T00:20:18+00:00"
55
}

chat-plugins/robotcode/skills/robotcode/SKILL.md

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ description: >-
66
or runs a suite (or a single test or task), or narrows a run to a subset by tag,
77
suite, or name; asks why a suite or test failed or won't run, or wants to fix,
88
debug, or step through a failing one; asks what a keyword or library does or
9-
which arguments it takes; configures the project via `robot.toml` and profiles;
9+
which arguments it takes; configures, reviews, troubleshoots, or explains the project's `robot.toml` /
10+
profile configuration or a single setting;
1011
statically analyzes the project — errors, undefined keywords, wrong arguments,
1112
and unused keywords/variables — before running; inspects a finished run (its
1213
`output.xml`) or compares two runs to see what changed before and after; or
@@ -37,7 +38,7 @@ Decide what the user actually wants *before* reaching for a command — these in
3738
- **Debug a live run***"fix this test", "why does this test fail / won't it run?", "step through it", "break at line X", "what is `${response}` there?", "try this in the actual test/suite".* Pause the real run; inspect the live stack/variables **and run keywords at the `(rdb)` prompt in the real context**. This — not the REPL — is how you experiment *inside* a real test or suite. See [references/debugging.md](references/debugging.md).
3839
- **Analyze / lint the code***"find issues", "check my robot code", "any undefined keywords / wrong arguments?", "are there unused keywords or variables?".* Static analysis (errors, undefined keywords, wrong args, unresolved/unused variables), no run. See [references/analyze.md](references/analyze.md).
3940
- **Inventory / understand the project***"what tests/tags/suites exist?", "which tests have tag X?", "how big is this?".* See [Discovery](#discovery--whats-in-the-project).
40-
- **Configure the project***"set up robot.toml", "add a CI profile", "configure variables/paths", "what's my effective config?".* See [Configuration & profiles](#configuration--profiles).
41+
- **Configure the project***"set up robot.toml", "add a CI profile", "configure variables/paths", "what's my effective config?".* See [references/config.md](references/config.md).
4142
- **Look up a keyword or library***"what does X do?", "what args does it take?".* See [Documentation lookup priority](#documentation-lookup-priority).
4243

4344
For **standalone exploration** ("watch me", "try …", "do it for me") prefer the REPL over writing a throwaway `.robot` file — a working session promotes into a test cheaply (`.save`), whereas a prematurely written test wastes effort, can't be watched, and tears its browser/connection down at the run's end. But the moment a **real test or suite** is in play — fixing it, stepping it, or asking *why it fails* — use the **debugger** (or read the recorded failure with [`results`](references/results.md) first), **not the REPL**, because only the debugger runs the test in its real context. In short: **the REPL is for trying things out; the debugger is for debugging a test.**
@@ -70,6 +71,7 @@ For non-obvious RobotCode CLI details that are not library/resource keyword docu
7071
- **REPL** — Interactive exploration and step-by-step development of tests and keywords in [references/repl.md](references/repl.md).
7172
- **Debugging** — Pausing a live run at a breakpoint and inspecting the stack/variables (`robotcode robot-debug`, `repl --break`) in [references/debugging.md](references/debugging.md).
7273
- **Authoring** — Writing/extending tests and reusable keywords (reuse → prototype → analyze → run) in [references/authoring.md](references/authoring.md).
74+
- **Configuration**`robot.toml` and profiles (loading order, inheritance, `extend-`, computed `{ expr }` / `{ if }` values, previewing a profile with `discover`) in [references/config.md](references/config.md).
7375
- **Reference** — Gotchas that prevent common agent mistakes.
7476

7577
## If robotcode isn't installed (or a command is missing)
@@ -221,40 +223,16 @@ Target one test by its **longname** (`-bl`), never a bare `.robot` file — a fi
221223
| Goal | Command |
222224
| --- | --- |
223225
| List setting keys | `robotcode config info list` |
224-
| Describe one setting | `robotcode config info desc <key>` |
225-
| Config files used | `robotcode config files` |
226-
| Effective configuration | `robotcode config show` |
227-
| Effective configuration for a profile | `robotcode --profile <name> config show` |
228-
| Detected root | `robotcode config root` |
229-
| List profiles | `robotcode profiles list` |
230-
| Show a profile | `robotcode --profile <name> profiles show` |
226+
| Explain a setting — read its docs (type, description, TOML example) | `robotcode config info desc <key>` |
227+
| Config files used / detected root | `robotcode config files` / `robotcode config root` |
228+
| Effective config — all files merged, incl. user-global defaults | `robotcode config show` (`-s` shows each setting's source; `--format json`) |
229+
| Effective config for a profile | `robotcode --profile <name> config show` |
230+
| List / show profiles | `robotcode profiles list` / `robotcode --profile <name> profiles show` |
231+
| Preview a profile's effect on a run | `robotcode --profile <name> discover tests` |
231232

232-
Use `config show` for resolution questions ("what's my effective config?"). **When writing or editing `robot.toml` or a profile, look up the exact key, its type, and a TOML example with `config info desc <key>` (wildcards work: `*tag*`, `rebot.*`) or `config info list` — don't guess settings — then confirm the merged result with `config show`.** Select profiles with the global `--profile <name>` option before the subcommand.
233+
**To explain, write, or edit a setting, read its documentation from `config info desc <key>`** (type, description, and a TOML example; wildcards `*tag*`, `rebot.*`) instead of guessing, then confirm the result with `config show`. **A setting's effective value can come from a profile** — when explaining what is actually in effect, account for the active profile(s): `robotcode --profile <name> config show` shows the value under that profile, and `config show -s` attributes each setting to the file or profile it came from. Profiles (`[profiles.<name>]`) layer onto the top-level settings; `--profile` is repeatable and globbed, and multiple profiles merge by `precedence`.
233234

234-
For example, to add a library search path — look the key up, write it, then verify:
235-
236-
```bash
237-
robotcode config info desc python-path # exact key, its type, and a TOML example
238-
```
239-
240-
```toml
241-
# robot.toml
242-
python-path = ["libs/", "resources/"]
243-
```
244-
245-
```bash
246-
robotcode config show # confirm it resolved as expected
247-
```
248-
249-
**Multiple profiles merge.** `--profile` is repeatable and each value is a glob against the defined profile names, so `-p ci -p "docker*"` selects and combines several profiles into one effective configuration:
250-
251-
- **Order / conflicts** — profiles are applied in ascending `precedence` (default `0`); on a conflicting scalar key, the higher-precedence profile wins.
252-
- **Override vs. append** — within the merge, a plain key (e.g. `args`, `paths`) **replaces** the accumulated value, while its `extend-`-prefixed twin (`extend-args`, `extend-paths`, `extend-variables`, …) **appends** to it. This is how a profile adds to the base config instead of clobbering it.
253-
- **`inherits`** — a profile can pull in other profiles by name (string or list); parents are selected and merged too.
254-
- **`enabled` / `hidden`** — a profile can switch itself off (`enabled = false`, or an `if` condition) or hide from listings; disabled profiles are skipped during merge.
255-
- **`default-profiles`** — config key choosing what runs when no `--profile` is given.
256-
257-
To see the merged result of a selection, run `robotcode -p <a> -p <b> config show` (or `profiles show` for a single profile's own definition).
235+
**Full reference — loading order, profile inheritance / `precedence` / `enabled` / `extend-`, recipes, and previewing a profile with `discover` — see [references/config.md](references/config.md).**
258236

259237
## Interpreting results
260238

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# Configuration: `robot.toml` and profiles
2+
3+
`robot.toml` centralizes a Robot Framework project's settings — paths, variables, output options, and environment-specific **profiles** — so they live in version control instead of scattered argument files or CLI flags. `robotcode` honors it for every command (`robot`, `discover`, `robot-debug`, …).
4+
5+
## What goes in it
6+
7+
Every `robot` / `rebot` command-line option is a key (multi-word options use hyphens: `--outputdir``output-dir`), plus RobotCode-specific settings:
8+
9+
```toml
10+
output-dir = "results"
11+
log-level = "INFO"
12+
languages = ["en", "fi"]
13+
paths = ["tests"] # so `robotcode robot` needs no path argument
14+
15+
[variables]
16+
BROWSER = "Chrome"
17+
LOGIN_URL = "https://example.com/login"
18+
```
19+
20+
Don't memorize or guess keys — the catalog is the tool:
21+
22+
- `robotcode config info list` — every settable key (including `[profile].*` and the `extend-*` twins).
23+
- `robotcode config info desc <key>` — type, description, and a TOML example. Wildcards work: `config info desc "*tag*"`, `config info desc "rebot.*"`.
24+
- `robot --help` — the underlying Robot Framework options these keys mirror.
25+
26+
`config info desc <key>` is the authoritative source whether you're **explaining** a setting (its meaning and accepted type) or **editing** one. When editing, the reliable loop is **look up (`config info desc`) → write the TOML → verify (`config show`)** — don't hand-write keys from memory. When explaining a setting's *value*, note that `config show` reports what is actually in effect and a profile can override the top-level value, so use `robotcode --profile <name> config show` (or `config show -s` to attribute each setting to its file/profile) to report the value under the active profile rather than just the default.
27+
28+
## Computed values: `expr` and `if`
29+
30+
A value doesn't have to be a literal. Wherever a setting is a string (its type from `config info desc` contains `StringExpression`), a list item, a dict value, or a `[variables]` entry, you can supply an **expression** instead — an inline table `{ expr = "<python expression>" }` that RobotCode evaluates once when it resolves the config:
31+
32+
```toml
33+
output-dir = { expr = "f'results/{date.today()}'" }
34+
35+
[variables]
36+
BUILD = { expr = "environ.get('BUILD_ID', 'local')" }
37+
```
38+
39+
Profiles add a **condition**: `enabled` and `hidden` take `{ if = "<python expression>" }` (or the dotted form `enabled.if = "..."`), evaluated as a boolean — this is how a profile switches itself on only on CI, on a given OS, and so on:
40+
41+
```toml
42+
[profiles.ci]
43+
enabled.if = "environ.get('CI') == 'true'"
44+
```
45+
46+
These are **not** arbitrary Python. The string must be a single *expression* (no statements, assignments, imports, or semicolons), and only two groups of names are in scope:
47+
48+
- the config globals — `environ`, `re`, `platform`, `datetime`, `date`, `time`, `timedelta`, `timezone`, `Path` (so the typical uses are environment- and platform-driven config); and
49+
- standard safe built-ins — type constructors (`str`, `int`, `float`, `bool`, `list`, `dict`, `tuple`, `set`, `bytes`) and common functions (`len`, `min`, `max`, `sum`, `sorted`, `reversed`, `range`, `enumerate`, `zip`, `map`, `filter`, `abs`, `round`, `format`, `ord`, `chr`, …).
50+
51+
Attribute and method calls on those objects are fine (`environ.get('CI')`, `platform.system()`, `Path.cwd() / 'app'`). Any other name — `os`, `open`, `__import__`, a module you weren't given a global for — is rejected when the value is evaluated, with `Name access to '<name>' is not allowed`; that error almost always means the expression reached for something outside this safe set.
52+
53+
When explaining such a setting, `config info desc` tells you whether it accepts an expression (the `StringExpression` in its type), and `config show` reports the **evaluated** result that is actually in effect — not the `{ expr = … }` source.
54+
55+
## Where config lives, and the loading order
56+
57+
RobotCode merges several files; a later one overrides settings from the earlier ones. Each layer has a deliberate purpose:
58+
59+
1. **Global user config** — a user-level `robot.toml` *outside* the repo (run `robotcode config files` for the exact path). Your machine-wide defaults across every Robot project; never committed anywhere.
60+
2. **`pyproject.toml`** — project root, under `[tool.robot]`. Robot settings here only if you deliberately keep a single config file (see split-by-concern below).
61+
3. **`robot.toml`** — project root; the **shared, committed** project configuration — the team's single source of truth and what makes runs reproducible. Everything the team needs to run the suite the same way belongs here, in version control.
62+
4. **`.robot.toml`** — project root; **personal, per-developer overrides**, deliberately **git-ignored**. For local-only tweaks that must not affect teammates — a local library/browser path, an extra `python-path`, a personal `default-profiles`, a temporary `log-level`. Nothing the team relies on goes here.
63+
64+
**Why it is split this way.** The three layers divide responsibility on purpose. The committed `robot.toml` is the team's shared baseline — it is what makes runs reproducible, so anything the whole team needs to run the suite identically lives there, in version control. `.robot.toml` (git-ignored) and the global user config are the *personal* layers: they stay out of the repo and **can** differ from machine to machine, so a developer **can** adjust things locally — a local library/browser path, an extra `python-path`, a personal `default-profiles` — without changing what everyone else runs. They are optional; their point is to *allow* per-developer overrides, not to require them. The committed `robot.toml` stays the common baseline, and any per-machine difference comes only from these optional layers. The same split tells you where a new setting belongs: if a correct, identical run depends on it, it goes in the committed `robot.toml`; if it is a machine- or person-specific convenience, it goes in `.robot.toml` or the user-global file.
65+
66+
**`robot.toml` vs. `pyproject.toml` — split by concern.** Keep *Python*-project configuration (build, dependencies, and Python tools like ruff/mypy/pytest) in `pyproject.toml`, and *Robot Framework* configuration (paths, variables, profiles, RF/rebot options, RobotCode settings) in **`robot.toml`** — even when the project already has a `pyproject.toml`. RobotCode *can* read Robot settings from a `[tool.robot]` section in `pyproject.toml` (it loads before `robot.toml`, so `robot.toml` wins on conflict), but the clean practice is to keep the two apart. `robot.toml` also keeps its keys at the top level (`output-dir = "results"`, `[profiles.dev]`), so it stays flat and readable instead of nesting everything under `[tool.robot]` / `[tool.robot.profiles.<name>]`.
67+
68+
Inspect what is actually in play instead of guessing:
69+
70+
- `robotcode config files` — which config files were found and their roles/precedence.
71+
- `robotcode config root` — the detected project root, and how it was discovered.
72+
- `robotcode config show` — the merged, effective configuration. `--format json` for machine output; `-s` / `--single` to see each file's own contribution.
73+
74+
## Profiles
75+
76+
A profile is a named settings block (`[profiles.<name>]`) layered on top of the top-level (default) settings:
77+
78+
```toml
79+
output-dir = "results" # default — applies unless a profile overrides it
80+
81+
[profiles.dev]
82+
output-dir = "results/dev"
83+
variables = { ENVIRONMENT = "development", API_URL = "http://dev-api.example.com" }
84+
85+
[profiles.prod]
86+
output-dir = "results/prod"
87+
variables = { ENVIRONMENT = "production", API_URL = "https://api.example.com" }
88+
```
89+
90+
- **`inherits`** — pull in other profiles by name: `inherits = ["base"]` (string or list).
91+
- **`hidden` / `enabled`**`hidden = true` keeps a profile out of listings; `enabled.if = "<python expression>"` (e.g. `enabled.if = "platform.system() == 'Windows'"`) switches it on conditionally.
92+
- **`precedence`** — a number (default `0`); when several profiles merge, the higher-precedence one wins a conflicting scalar key.
93+
- **`extend-` prefix** — within a merge a plain key **replaces** the accumulated value, while its `extend-` twin **appends** to it. Supported on `variables`, `include` / `exclude`, `python-path`, `metadata`, and more (check `config info`).
94+
- **`default-profiles`** — which profile(s) apply when no `--profile` is given.
95+
96+
### Selecting and inspecting profiles
97+
98+
```bash
99+
robotcode --profile dev robot tests/ # one profile
100+
robotcode -p base -p "win*" robot tests/ # repeatable; each value is a glob; all matches merge
101+
robotcode profiles list # defined profiles
102+
robotcode --profile dev profiles show # a single profile's own definition
103+
robotcode -p base -p win config show # the merged, effective config for a selection
104+
```
105+
106+
Merge order: default (top-level) settings first → profiles by ascending `precedence` → for equal precedence, the order given on the command line.
107+
108+
### See a profile's effect on a run — without running
109+
110+
`discover` applies the resolved configuration too, so it previews exactly what a profile changes: which tests/suites are selected, and how their longnames and tags come out after the profile's `paths`, `include` / `exclude`, and name transforms.
111+
112+
```bash
113+
robotcode --profile ci discover tests # the tests this profile would run
114+
robotcode --profile ci discover suites # the resulting suite tree
115+
robotcode --profile ci discover tags # the resolved tags
116+
robotcode discover tests # …compare against no profile (or `-p a` vs `-p b`)
117+
```
118+
119+
The longnames it prints are exactly what you pass to `robotcode robot -bl "<longname>"` / `robotcode robot-debug -bl "<longname>"` to run or debug one test in that same resolved context.
120+
121+
## Common patterns
122+
123+
```toml
124+
# A base profile others inherit, plus environment profiles
125+
[profiles.base]
126+
log-level = "INFO"
127+
variables = { TIMEOUT = "20s" }
128+
129+
[profiles.dev]
130+
inherits = ["base"]
131+
extend-variables = { ENVIRONMENT = "development" } # adds to base, doesn't replace
132+
133+
[profiles.ci]
134+
inherits = ["base"]
135+
extend-variables = { ENVIRONMENT = "ci" }
136+
extend-include = ["smoke"] # adds to any inherited includes
137+
138+
# Platform-conditional profile
139+
[profiles.windows]
140+
enabled.if = "platform.system() == 'Windows'"
141+
variables = { DRIVER_PATH = "C:\\drivers" }
142+
```
143+
144+
## Gotchas
145+
146+
- **`extend-` vs. plain replaces silently.** A profile's plain `variables = { … }` *replaces* the inherited/default variables (the others are dropped); use `extend-variables` to add. Same for `include`, `python-path`, `metadata`, etc.
147+
- **Config changes longnames.** `paths` and name-transform settings change suite/test *names* from what the files literally say — so select a single test by its `discover` / `results` **longname** (`-bl`), never by its file path. See [debugging.md](debugging.md).
148+
- **CLI overrides config.** Flags on the command line win over `robot.toml`; use them to narrow a one-off run, not as a substitute for the config.
149+
- **`config show` is the merged result, so it includes the user-global defaults.** A setting that isn't in the project's `robot.toml` / `pyproject.toml` is usually one of those user-level defaults (source #1 above) rather than something the project sets. `config show -s` (each file's own contribution) and `config files` show which file each setting comes from, which attributes any setting to its layer.
150+
- **Verify, don't guess.** Confirm keys/types with `config info desc` and the merged result with `config show` — and preview a profile's selection with `discover` — before trusting an edit.

0 commit comments

Comments
 (0)