robotcode 2.8.0.dev677__tar.gz → 2.9.0.dev51__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,125 @@ All notable changes to this project will be documented in this file. See [conven
6
6
 
7
7
  ### <!-- 0 -->Features
8
8
 
9
+ #### PyCharm
10
+
11
+ - Show a keyword's usages on Ctrl+click on its definition ([6b29872](https://github.com/robotcodedev/robotcode/commit/6b298725de829e1843ef24ca507799b1e02f0f3d))
12
+
13
+ In PyCharm, Ctrl+click and Navigate | Declaration or Usages on the name
14
+ of a keyword definition now list the keyword's usages, as Show Usages
15
+ does, instead of "Cannot find declaration to go to". Ctrl+hover on the
16
+ name shows the keyword's documentation, as on a call (#677).
17
+
18
+
19
+ #### RobotCode
20
+
21
+ - Write errors that stop a command as [ ERROR ] ([c2add74](https://github.com/robotcodedev/robotcode/commit/c2add74cdf9ca82b90f37e28e5c3d819b27d2eb0))
22
+
23
+ An error that stops a command, such as a mistyped profile or option, now looks like the errors robotcode reports and
24
+ goes on after: `[ ERROR ] No profile matches 'typo'.`, with ERROR in red on a terminal, instead of `Error: …`. Debug
25
+ sessions show it the same way, and the exit codes stay.
26
+
27
+
28
+
29
+ ### <!-- 1 -->Bug Fixes
30
+
31
+ #### PyCharm
32
+
33
+ - End a debug session with the Terminal tab in front ([0d6b972](https://github.com/robotcodedev/robotcode/commit/0d6b972ec1bbd4d171b94a96791b56e1e8343df1))
34
+
35
+ A debug session in PyCharm now ends with the Terminal tab in front, as a
36
+ run does, instead of the Debug Console. An error that stops the session
37
+ before Robot Framework runs, such as a selected profile that robot.toml
38
+ does not define, is then in view.
39
+
40
+
41
+ #### REPL
42
+
43
+ - Start robotcode when only the replserver extra is installed ([c9255a3](https://github.com/robotcodedev/robotcode/commit/c9255a36131ae4e4ea058a55948f9e8043f9119a))
44
+
45
+ With `robotcode[replserver]` or `robotcode-repl-server` installed
46
+ without `robotcode-repl`, every robotcode command failed, even
47
+ `robotcode --version`, with "No module named 'robotcode.repl'". The
48
+ REPL server package now installs `robotcode-repl` with it.
49
+
50
+
51
+ #### Robot
52
+
53
+ - Find a library class whose name differs from its module ([598239d](https://github.com/robotcodedev/robotcode/commit/598239d4a35cd7faf605b0e34271a4a45609abe2))
54
+
55
+ Since Robot Framework 7.2 a library module may hold its library class
56
+ under another name when it is the only class marked with @library or
57
+ ROBOT_AUTO_KEYWORDS. RobotCode now loads that class as robot does, so its
58
+ keywords are no longer reported as missing (#678). A failed library
59
+ import now reads "Importing library 'X' failed", as in robot's message.
60
+
61
+ - Render documentation links and images whose target contains a space ([e5c66d7](https://github.com/robotcodedev/robotcode/commit/e5c66d7b8ddecfc826fe1aa599aa52fefad67d69))
62
+
63
+ A link or an image in Robot Framework documentation whose target contains a
64
+ space, such as `[images/doc/my image.png|Title]`, showed up as raw Markdown
65
+ text in hovers and in the Documentation Viewer instead of a link or an image.
66
+
67
+
68
+ #### VS Code
69
+
70
+ - Stay quiet in folders without Robot Framework ([9691d40](https://github.com/robotcodedev/robotcode/commit/9691d40e180a7a68a85f94ab94a15667877123d4))
71
+
72
+ In a workspace folder without Robot Framework, such as a TypeScript project in which a Markdown file or a debug
73
+ session activated RobotCode, RobotCode no longer shows its environment message, starts no Python processes and shows
74
+ nothing in the Testing view. A folder that becomes a Robot Framework project during the session, through a robot.toml,
75
+ a dependency in pyproject.toml or requirements.txt, or a first .robot file, gets its language server and tests without
76
+ a reload, and the update notification waits for such a folder.
77
+
78
+ - Keep errors that end the REPL in its terminal ([21f1a9f](https://github.com/robotcodedev/robotcode/commit/21f1a9f4c29acaca08ceeaa417397ec1c96ebee9))
79
+
80
+ An error that ends the REPL, such as a selected configuration profile that the folder does not define, now stays in
81
+ the REPL's terminal until you press a key. Before, a notification came instead of the REPL, or VS Code closed the
82
+ terminal and only reported its exit code.
83
+
84
+
85
+
86
+ ### <!-- 2 -->Documentation
87
+
88
+ #### VS Code
89
+
90
+ - Say that errors that end the REPL stay in its terminal ([2013cdc](https://github.com/robotcodedev/robotcode/commit/2013cdc7f5ecf5dc7fcbee8cb49aecdcd4f76460))
91
+
92
+ #### Website
93
+
94
+ - Move Finding Robot Files into Project Configuration ([80949f7](https://github.com/robotcodedev/robotcode/commit/80949f7f5763879f66407343881d801e998f04c5))
95
+
96
+ The guide on which files RobotCode finds is now a page of the Project
97
+ Configuration group, after Files and Project Root, and its Quick start
98
+ describes the project root as that page does. The group Robot Framework
99
+ Tips is now called Tips & Tricks.
100
+
101
+ - Group the guides by tool and topic ([81b22b8](https://github.com/robotcodedev/robotcode/commit/81b22b8aa0cb3c98710bf17bb234383fac9fb52e))
102
+
103
+ The Guides area now has a group per tool and topic: the command guides
104
+ and the wrapper guide moved to /guides/cli/ under an overview, the
105
+ Robot Framework tips to /guides/tips/ and the highlighting tip into the
106
+ VS Code group, and the robot.toml group and the .robotignore guide are
107
+ named by their subject. Getting Started has a page for the command
108
+ line. The old paths are not redirected.
109
+
110
+ - Add a security.txt ([8f11e99](https://github.com/robotcodedev/robotcode/commit/8f11e9946cdf8c23d65de272a4e2ae594985b1d1))
111
+
112
+ robotcode.io/.well-known/security.txt names the contacts for security
113
+ reports from SECURITY.md. The Pages upload now includes hidden
114
+ directories, which it leaves out by default.
115
+
116
+ - Add a robots.txt and keep the old sitemap.xml address ([4056212](https://github.com/robotcodedev/robotcode/commit/40562125c751ca89aea7ad47d0fdbd436622aad1))
117
+
118
+ The robots.txt tells search engines where the sitemap is. /sitemap.xml,
119
+ the sitemap address of the VitePress site, answers again and points to
120
+ the pages of the new sitemap.
121
+
122
+
123
+
124
+ ## [2.8.0](https://github.com/robotcodedev/robotcode/compare/v2.7.0..v2.8.0) - 2026-10-25
125
+
126
+ ### <!-- 0 -->Features
127
+
9
128
  #### Analyze
10
129
 
11
130
  - Add hidden dump-model command to inspect the semantic model ([23ad07c](https://github.com/robotcodedev/robotcode/commit/23ad07c8ffbddf3b6429d94f958537cdd39bf0c6))
@@ -48,6 +167,10 @@ All notable changes to this project will be documented in this file. See [conven
48
167
 
49
168
  #### Language Server
50
169
 
170
+ - Show the errors of the configuration in the editor ([3bbd793](https://github.com/robotcodedev/robotcode/commit/3bbd79367cabf8b2a2104c7aa04b27c893839405))
171
+
172
+ The language server now starts also when robot.toml cannot be loaded or a profile name selects nothing, and shows such errors of the configuration as error messages in the editor instead of only in its log. Names of the editor's own profile selection are left to the editor, which reports them with a way to fix them.
173
+
51
174
  - Highlight uses of keyword arguments as parameters ([e4ae168](https://github.com/robotcodedev/robotcode/commit/e4ae168c607daa0398e78e4c69a443b06a38e830))
52
175
 
53
176
  Uses of an argument declared in [Arguments] now get the semantic token
@@ -148,6 +271,17 @@ All notable changes to this project will be documented in this file. See [conven
148
271
 
149
272
  #### PyCharm
150
273
 
274
+ - Report selected profiles that robot.toml does not define ([3489863](https://github.com/robotcodedev/robotcode/commit/3489863203ae585da40268ca094e6ade6ea814dc))
275
+
276
+ When the selection names a profile that robot.toml does not define, a notification says so and offers Remove from Selection and Select Configuration Profiles..., also in place of the notification about a failed discovery. The profile list keeps patterns and hidden profiles in the selection, and messages of the language server show characters such as * and < as they are.
277
+
278
+ - Complete robot.toml and highlight robot code blocks in Markdown ([aa1af47](https://github.com/robotcodedev/robotcode/commit/aa1af472c9bd27aa10f8ee4475c206fdaf128f20))
279
+
280
+ PyCharm now completes the settings of robot.toml and .robot.toml from
281
+ RobotCode's JSON schema without a schema mapping by hand, as VS Code does.
282
+ Markdown code blocks marked robot, like those marked robotframework, are
283
+ highlighted as Robot Framework code in the editor and the preview.
284
+
151
285
  - Use the interpreter of the Robot Framework module ([1c77903](https://github.com/robotcodedev/robotcode/commit/1c77903e1757b875d142e3c34baf0827e95d42f8))
152
286
 
153
287
  In a project with several modules, RobotCode now takes the interpreter
@@ -274,6 +408,10 @@ All notable changes to this project will be documented in this file. See [conven
274
408
 
275
409
  #### REPL
276
410
 
411
+ - Name the file and line of each keyword in the JSON of robotcode doc ([7124234](https://github.com/robotcodedev/robotcode/commit/7124234d715b8922d2cd66fe66b65247ebc05c2c))
412
+
413
+ The keyword entries in the JSON of `robotcode doc` now carry `source` and `lineno`, the file that defines the keyword and its line there, empty and `-1` when they are unknown. A tool that reads the JSON can open the definition of a keyword from them.
414
+
277
415
  - Handle Ctrl-C like Python's REPL and pdb ([27124be](https://github.com/robotcodedev/robotcode/commit/27124be4aef8453a03df8891611dd545fa59baf0))
278
416
 
279
417
  Ctrl-C at the `>>>`, `(rdb)` and `(com)` prompts used to end the session, resume the run or store the typed commands; it now drops what was typed and shows the prompt again. While a run executes with the debugger attached, Ctrl-C pauses at the next keyword instead of failing the keyword that runs.
@@ -373,6 +511,34 @@ All notable changes to this project will be documented in this file. See [conven
373
511
 
374
512
  #### VS Code
375
513
 
514
+ - Show or open a Documentation Viewer from the Documentation Bookmarks view ([bc9855f](https://github.com/robotcodedev/robotcode/commit/bc9855f7569a0272444c7fa1b1e549eaec79a278))
515
+
516
+ The title of the Documentation Bookmarks view has two buttons: Show Documentation Viewer brings the viewer that the actions use to the front with the focus, also from another window, or opens one when there is none, and New Documentation Viewer opens a new one. Show Documentation Viewer is a command of the palette too.
517
+
518
+ - Add a context menu to the outline of the Documentation Viewer ([8a1b212](https://github.com/robotcodedev/robotcode/commit/8a1b212773b1b29e9f7242729b4c910a9b4dda6d))
519
+
520
+ A right-click on an entry of the outline, the context menu key or Shift+F10 opens a menu that shows the entry in the same or in a new viewer, bookmarks it without going there, and for a keyword opens the file that defines it at its line, also a library of the Python environment such as `Collections.py`.
521
+
522
+ - Report selected profiles that a folder does not define ([10ef5c8](https://github.com/robotcodedev/robotcode/commit/10ef5c813dcbc6624272a9fa49af724d3d8b54a7))
523
+
524
+ When robotcode.profiles names a profile that a folder's configuration does not define, a notification says so and offers Remove from Selection and Select Configuration Profiles, the Testing view shows a hint instead of an error item, and the REPL shows the notification instead of a terminal that closes with the error. Select Configuration Profiles keeps patterns and hidden profiles in the selection and stores long profile names in full.
525
+
526
+ - Bookmark places in the Documentation Viewer ([9f56212](https://github.com/robotcodedev/robotcode/commit/9f56212038429dcffce77ebb9a2a8db898186367))
527
+
528
+ A star after the target field bookmarks the place a viewer shows, in its
529
+ workspace folder. The Explorer view Documentation Bookmarks lists, opens
530
+ and removes the bookmarks and moves them to All Workspaces, which
531
+ Settings Sync takes to other machines; the first start bookmarks the
532
+ standard libraries. The target field shows the place after a #, as a
533
+ browser's address bar does, and offers the bookmarks before its
534
+ completions.
535
+
536
+ - Complete the target in the Documentation Viewer ([16e6fbb](https://github.com/robotcodedev/robotcode/commit/16e6fbba7d76c00982e09c291e4fecb2e53a4614))
537
+
538
+ While you type in the target field of the Documentation Viewer, a list under
539
+ it completes the names of libraries, resources and suite files, as the editor
540
+ does for imports. Enter or Tab takes the selected suggestion.
541
+
376
542
  - Copy the versions in use for a report ([1e0d8f8](https://github.com/robotcodedev/robotcode/commit/1e0d8f8b32589035e61f652c428cdcea9e40268e))
377
543
  - Open a new Documentation Viewer from a viewer's toolbar ([e4c6fe7](https://github.com/robotcodedev/robotcode/commit/e4c6fe78d11d654676ee0857ad8d77ec0ed84569))
378
544
 
@@ -503,6 +669,10 @@ All notable changes to this project will be documented in this file. See [conven
503
669
 
504
670
  #### Config
505
671
 
672
+ - Stop at a profile name that selects no profile ([dd3fb9c](https://github.com/robotcodedev/robotcode/commit/dd3fb9c45646da1760903c6226f7789d7fe8f706))
673
+
674
+ A profile name or pattern from -p, ROBOTCODE_PROFILES, an editor's selection or inherits that selects no profile now stops robotcode before it runs anything, as an invalid robot.toml does: run exits with 252 and reports "No profile matches 'typo'.". Until now the command went on without the profile, so a mistyped profile on a CI server ran with another configuration. A name in default-profiles is only reported, an exact name also selects a profile with *, ? or [ in its name, and profiles that inherit each other stop with an error instead of a crash.
675
+
506
676
  - Apply none of the profiles a disabled profile inherits from ([edaa183](https://github.com/robotcodedev/robotcode/commit/edaa183792ecbb1f9de72d6f68731e8fafc61545))
507
677
 
508
678
  Selecting a disabled profile still applied the profiles two or more levels up
@@ -517,6 +687,10 @@ All notable changes to this project will be documented in this file. See [conven
517
687
 
518
688
  #### Debugger
519
689
 
690
+ - Show an error before the run in the Debug Console ([e7f9a61](https://github.com/robotcodedev/robotcode/commit/e7f9a61bb460c9cf1bd0ba959f11e29112ed01f0))
691
+
692
+ With the internal console, a run that robotcode stops before Robot Framework runs, for example because of an error in robot.toml, now shows the error in the Debug Console. Until now the debug session ended first and the error was lost.
693
+
520
694
  - Let a run's variable replace an inherited one of any case on Windows ([82ea39e](https://github.com/robotcodedev/robotcode/commit/82ea39e6265b79dd44252f8ddc46e8bd72fbd4f9))
521
695
 
522
696
  On Windows, a variable that a run's environment sets, such as `path` in
@@ -622,6 +796,13 @@ All notable changes to this project will be documented in this file. See [conven
622
796
 
623
797
  #### PyCharm
624
798
 
799
+ - Show the report and the log in the preview in PyCharm's theme ([c0f92e4](https://github.com/robotcodedev/robotcode/commit/c0f92e42351b9558c8bc7fc0fbda4a2766951eb1))
800
+
801
+ With Robot Framework 7.0 or later, the built-in preview shows the report
802
+ and the log in PyCharm's light or dark theme and follows a change of the
803
+ theme, also in an open tab. A theme chosen with the switch of the report
804
+ or the log stays until PyCharm's theme changes.
805
+
625
806
  - Name the run configuration in the texts about its interpreter ([9e905c4](https://github.com/robotcodedev/robotcode/commit/9e905c4110bdc5b99e05d35be99f28705b0c639f))
626
807
 
627
808
  When a Robot Framework run configuration has an interpreter other than the
@@ -984,6 +1165,36 @@ All notable changes to this project will be documented in this file. See [conven
984
1165
 
985
1166
  #### Runner
986
1167
 
1168
+ - Don't double the backslashes in results log links with spaces ([15cdb24](https://github.com/robotcodedev/robotcode/commit/15cdb248b2e2d4418748ce32bd04f6115b4428ec))
1169
+
1170
+ On Windows, with html-to-markdown installed, `robotcode results log` showed
1171
+ links to files outside the output directory with doubled backslashes when the
1172
+ path contains a space.
1173
+
1174
+ - Take the wrapper from the configuration of the command ([aee1e50](https://github.com/robotcodedev/robotcode/commit/aee1e505428ef82a3a549e10914971a1fcf71d7a))
1175
+
1176
+ Commands that run Robot Framework take the wrapper from the configuration
1177
+ they use, found from their paths, and load that configuration once. A run
1178
+ of a project's tests from the root of a monorepo now runs under that
1179
+ project's wrapper, and -v shows the loading once. A configuration that
1180
+ cannot be loaded starts no wrapper, also not one given with --wrapper.
1181
+
1182
+ - Resolve encoded and file: links and videos in results log ([85ddc4c](https://github.com/robotcodedev/robotcode/commit/85ddc4c6a8372c4daf5af4635aa9dea5ed460a50))
1183
+
1184
+ robotcode results log now finds files whose names are URL-encoded, such as
1185
+ screenshots named after a test, follows the file: links OperatingSystem logs
1186
+ for files in the output directory, and extracts the videos Browser records.
1187
+ Linked screenshots no longer get an extra skipped entry, embedded files keep
1188
+ the name of their download attribute, and every message that links an
1189
+ extracted file points to the copy.
1190
+
1191
+ - Keep screenshot messages when an old html-to-markdown is installed ([1d719bc](https://github.com/robotcodedev/robotcode/commit/1d719bcf1c0745136f5147d5a9e0bc01277d8202))
1192
+
1193
+ With html-to-markdown older than 3.18 installed, robotcode results log showed
1194
+ the screenshot messages of SeleniumLibrary and Browser as empty lines, and
1195
+ --extract left its directory empty. Such versions are now ignored in favour of
1196
+ the built-in converter, and the html extra requires html-to-markdown 3.18.
1197
+
987
1198
  - Discover tests without a line number ([9f3077d](https://github.com/robotcodedev/robotcode/commit/9f3077d8adb868db8bbcb1dc34a08b6a0cfad275))
988
1199
 
989
1200
  `robotcode discover` no longer fails as a whole when a custom parser or
@@ -1046,6 +1257,10 @@ All notable changes to this project will be documented in this file. See [conven
1046
1257
 
1047
1258
  #### VS Code
1048
1259
 
1260
+ - Shorten the description of the Documentation Viewer's openLocation setting ([db4a080](https://github.com/robotcodedev/robotcode/commit/db4a080e7b975c468b2daa94f61a83225ae47c19))
1261
+
1262
+ It now only says where a new viewer opens: beside the active editor or in the active editor group.
1263
+
1049
1264
  - Fill the Keywords view once the language server has started ([599ad73](https://github.com/robotcodedev/robotcode/commit/599ad73808c54bc7ddf77703acd7d831316004fc))
1050
1265
 
1051
1266
  When VS Code restores an open Robot Framework file at startup, the Keywords
@@ -1253,6 +1468,10 @@ All notable changes to this project will be documented in this file. See [conven
1253
1468
 
1254
1469
  #### REPL
1255
1470
 
1471
+ - Design the native REPL and notebooks ([6929f4c](https://github.com/robotcodedev/robotcode/commit/6929f4c81d454abdfc33cd3dd83c60052ea88920))
1472
+
1473
+ dev-docs/repl-and-notebooks.md collects the decisions for a Robot Framework REPL in VS Code's Interactive Window and for notebooks, the execution layer they share with robotcode repl, the facts they rest on and the open questions. It gets cut into OpenSpec changes later.
1474
+
1256
1475
  - Correct the REPL and robot-debug guides ([e794706](https://github.com/robotcodedev/robotcode/commit/e794706e5b7c07155cfa33bcb83d8ed5c4f186a5))
1257
1476
 
1258
1477
  Corrects the dot-command prefixes, the flags only `robotcode repl` has, several prompt features of both backends, the example outputs, that `-l` needs `-o`, and where `--stop-on-entry` stops.
@@ -1307,6 +1526,14 @@ All notable changes to this project will be documented in this file. See [conven
1307
1526
 
1308
1527
  #### VS Code
1309
1528
 
1529
+ - Show the Documentation Bookmarks view in the guide ([e6fc968](https://github.com/robotcodedev/robotcode/commit/e6fc968841a1587c83164baa2cb169dfd75cee8a))
1530
+
1531
+ The page Documentation Viewer shows the view in the Explorer, with its groups and buttons, beside a viewer at the selected bookmark.
1532
+
1533
+ - List the new commands of the Documentation Viewer and retake its media ([fe31be3](https://github.com/robotcodedev/robotcode/commit/fe31be3bc6e65856d6476006d66fe704352f2f4e))
1534
+
1535
+ The command table of the overview lists Show Documentation Viewer and Reset Documentation Bookmarks. The screenshot and the recording of the Documentation Viewer show the star of the bookmarks, the place in the target field and the new icon of New Documentation Viewer.
1536
+
1310
1537
  - Describe the button for a new Documentation Viewer ([35a20c0](https://github.com/robotcodedev/robotcode/commit/35a20c0ecf37c56934c63ae51d2eaac2d22eca84))
1311
1538
 
1312
1539
  The guide and the command table use the renamed commands, the guide describes
@@ -1361,6 +1588,56 @@ All notable changes to this project will be documented in this file. See [conven
1361
1588
 
1362
1589
  #### Website
1363
1590
 
1591
+ - Show the documentation bookmarks in the v2.8.0 release notes ([018fb51](https://github.com/robotcodedev/robotcode/commit/018fb511faeb37854801d59d69f96ff28db7e7ff))
1592
+
1593
+ The post now presents the Documentation Bookmarks view with a screenshot,
1594
+ gives PyCharm a longer entry higher up in the highlights and shortens the
1595
+ breaking change for profile names that select no profile.
1596
+
1597
+ - Let the spiders ask for a poke during the Halloween season ([a548ae1](https://github.com/robotcodedev/robotcode/commit/a548ae17fa6723861a9129f2de0f8711ff5658d2))
1598
+
1599
+ During the Halloween season a spider of the home page or a news page now
1600
+ and then says "Trick or treat? Poke me!" in a speech bubble, so that
1601
+ visitors find the RobotCode tips that clicked creatures leave as treats.
1602
+ The spiders take turns and stop asking once the visitor has got a treat.
1603
+
1604
+ - Add the v2.8.0 release notes ([2717523](https://github.com/robotcodedev/robotcode/commit/27175235ef39fd707beb39606dad42e609f9b4e8))
1605
+
1606
+ Announce the Robot Framework 7.5 support, the Documentation Viewer, the
1607
+ Python environments in VS Code, the biggest update of the PyCharm plugin
1608
+ and the new website, with screenshots of the new features.
1609
+
1610
+ - Link the contribution guide and the dev builds on Support & Contribute ([5cb2af5](https://github.com/robotcodedev/robotcode/commit/5cb2af59e975c94601f4c8199d778ec20338d5e3))
1611
+
1612
+ The page now points contributors to CONTRIBUTING.md and testers to the page about the dev builds.
1613
+
1614
+ - Add nine posters to the Halloween gallery of the home page ([6cd6d52](https://github.com/robotcodedev/robotcode/commit/6cd6d52d8a73efacfa3b32dfe795e08bc485e4a2))
1615
+
1616
+ During the Halloween season the gallery of the home page shows nine new posters, from The Suite to A Nightmare on CI Street; the poster after Nosferatu (2024) is gone.
1617
+
1618
+ - Describe what happens when a profile name selects no profile ([aaa65fb](https://github.com/robotcodedev/robotcode/commit/aaa65fb61fa08d43cfcec6fecc93b9b74690a10e))
1619
+
1620
+ The robot.toml troubleshooting page and the VS Code and PyCharm guides say when such a name stops a command, what the language server shows, and how the editors report a name of their selection.
1621
+
1622
+ - Describe how results log --extract resolves links and names files ([39eafe7](https://github.com/robotcodedev/robotcode/commit/39eafe7f5698b54965a0313893d84ab4cb3b2bd8))
1623
+
1624
+ The --extract section now says how encoded names, file: links, folders,
1625
+ videos and repeated references are handled, and that an embedded file keeps
1626
+ the name from its download attribute.
1627
+
1628
+ - Say that the PyCharm preview shows report and log in the IDE's theme ([10b6537](https://github.com/robotcodedev/robotcode/commit/10b6537875cbc61cb3e88b585d36f7560122b756))
1629
+
1630
+ The page on running tests says that the preview shows the report and the
1631
+ log in PyCharm's theme, follows a change of it, and keeps the theme chosen
1632
+ with the page's own switch until PyCharm's theme changes.
1633
+
1634
+ - Say that PyCharm completes robot.toml and highlights robot code blocks ([5b11695](https://github.com/robotcodedev/robotcode/commit/5b116950b7994d1e8ab54778606499fec9e8689d))
1635
+
1636
+ The configuration pages say that PyCharm completes robot.toml and
1637
+ .robot.toml without further setup, and the comparison with VS Code gets
1638
+ rows for the completion in robot.toml and for Robot Framework code blocks
1639
+ in Markdown.
1640
+
1364
1641
  - Say which module's interpreter RobotCode uses in PyCharm ([978fd75](https://github.com/robotcodedev/robotcode/commit/978fd75e5bec2bb9967d1694565e2b314843cdd1))
1365
1642
 
1366
1643
  The PyCharm guide now says that RobotCode takes the interpreter of the module
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: robotcode
3
- Version: 2.8.0-dev.677
3
+ Version: 2.9.0-dev.51
4
4
  Summary: Command line interface for RobotCode
5
5
  Project-URL: Homepage, https://robotcode.io
6
6
  Project-URL: Donate, https://opencollective.com/robotcode
@@ -34,35 +34,35 @@ Classifier: Topic :: Text Editors :: Integrated Development Environments (IDE)
34
34
  Classifier: Topic :: Utilities
35
35
  Classifier: Typing :: Typed
36
36
  Requires-Python: >=3.10
37
- Requires-Dist: robotcode-core==2.8.0-dev.677
38
- Requires-Dist: robotcode-plugin==2.8.0-dev.677
39
- Requires-Dist: robotcode-robot==2.8.0-dev.677
37
+ Requires-Dist: robotcode-core==2.9.0-dev.51
38
+ Requires-Dist: robotcode-plugin==2.9.0-dev.51
39
+ Requires-Dist: robotcode-robot==2.9.0-dev.51
40
40
  Provides-Extra: all
41
41
  Requires-Dist: docutils; extra == 'all'
42
42
  Requires-Dist: pyyaml>=5.4; extra == 'all'
43
- Requires-Dist: robotcode-analyze==2.8.0-dev.677; extra == 'all'
44
- Requires-Dist: robotcode-debugger==2.8.0-dev.677; extra == 'all'
45
- Requires-Dist: robotcode-language-server==2.8.0-dev.677; extra == 'all'
46
- Requires-Dist: robotcode-repl-server==2.8.0-dev.677; extra == 'all'
47
- Requires-Dist: robotcode-repl==2.8.0-dev.677; extra == 'all'
48
- Requires-Dist: robotcode-runner==2.8.0-dev.677; extra == 'all'
43
+ Requires-Dist: robotcode-analyze==2.9.0-dev.51; extra == 'all'
44
+ Requires-Dist: robotcode-debugger==2.9.0-dev.51; extra == 'all'
45
+ Requires-Dist: robotcode-language-server==2.9.0-dev.51; extra == 'all'
46
+ Requires-Dist: robotcode-repl-server==2.9.0-dev.51; extra == 'all'
47
+ Requires-Dist: robotcode-repl==2.9.0-dev.51; extra == 'all'
48
+ Requires-Dist: robotcode-runner==2.9.0-dev.51; extra == 'all'
49
49
  Requires-Dist: robotframework-robocop>=6.0.0; extra == 'all'
50
50
  Provides-Extra: analyze
51
- Requires-Dist: robotcode-analyze==2.8.0-dev.677; extra == 'analyze'
51
+ Requires-Dist: robotcode-analyze==2.9.0-dev.51; extra == 'analyze'
52
52
  Provides-Extra: debugger
53
- Requires-Dist: robotcode-debugger==2.8.0-dev.677; extra == 'debugger'
53
+ Requires-Dist: robotcode-debugger==2.9.0-dev.51; extra == 'debugger'
54
54
  Provides-Extra: languageserver
55
- Requires-Dist: robotcode-language-server==2.8.0-dev.677; extra == 'languageserver'
55
+ Requires-Dist: robotcode-language-server==2.9.0-dev.51; extra == 'languageserver'
56
56
  Provides-Extra: lint
57
57
  Requires-Dist: robotframework-robocop>=2.0.0; extra == 'lint'
58
58
  Provides-Extra: repl
59
- Requires-Dist: robotcode-repl==2.8.0-dev.677; extra == 'repl'
59
+ Requires-Dist: robotcode-repl==2.9.0-dev.51; extra == 'repl'
60
60
  Provides-Extra: replserver
61
- Requires-Dist: robotcode-repl-server==2.8.0-dev.677; extra == 'replserver'
61
+ Requires-Dist: robotcode-repl-server==2.9.0-dev.51; extra == 'replserver'
62
62
  Provides-Extra: rest
63
63
  Requires-Dist: docutils; extra == 'rest'
64
64
  Provides-Extra: runner
65
- Requires-Dist: robotcode-runner==2.8.0-dev.677; extra == 'runner'
65
+ Requires-Dist: robotcode-runner==2.9.0-dev.51; extra == 'runner'
66
66
  Provides-Extra: yaml
67
67
  Requires-Dist: pyyaml>=5.4; extra == 'yaml'
68
68
  Description-Content-Type: text/markdown
@@ -185,7 +185,7 @@ For CI pipelines, the command line, or LSP-compatible editors like Neovim, Subli
185
185
  pip install "robotcode[runner,analyze]"
186
186
  ```
187
187
 
188
- Pick the extras that match your use case — see the [CLI reference](https://robotcode.io/reference/cli/) for the available packages and how to install them.
188
+ Pick the extras that match your use case — see [Get Started on the Command Line](https://robotcode.io/getting-started/command-line/) for the commands each extra brings, installing with pip or uv and a first run, and the [CLI reference](https://robotcode.io/reference/cli/) for every command and option.
189
189
 
190
190
 
191
191
  ## Documentation
@@ -193,7 +193,7 @@ Pick the extras that match your use case — see the [CLI reference](https://rob
193
193
  For detailed instructions, visit our **[official documentation](https://robotcode.io)**. Additional resources:
194
194
 
195
195
  - **[Q&A](https://github.com/robotcodedev/robotcode/discussions/categories/q-a):** Answers to common questions about RobotCode.
196
- - **[Guides](https://robotcode.io/guides/):** How to use RobotCode's commands and set up projects, plus common pitfalls and editor customization.
196
+ - **[Guides](https://robotcode.io/guides/):** How to work with RobotCode in VS Code, in PyCharm and on the command line, how to set up projects with `robot.toml`, and tips for Robot Framework code.
197
197
  - **[Command Line Tools Reference](https://robotcode.io/reference/cli/):** Comprehensive documentation on using RobotCode's CLI tools.
198
198
  - **[Changelog](https://github.com/robotcodedev/robotcode/blob/main/CHANGELOG.md):** Track changes, updates, and new features in each release.
199
199
  - **[Support & Contribute](https://robotcode.io/contributing/):** Ways to back the project — financial, code, feedback.
@@ -116,7 +116,7 @@ For CI pipelines, the command line, or LSP-compatible editors like Neovim, Subli
116
116
  pip install "robotcode[runner,analyze]"
117
117
  ```
118
118
 
119
- Pick the extras that match your use case — see the [CLI reference](https://robotcode.io/reference/cli/) for the available packages and how to install them.
119
+ Pick the extras that match your use case — see [Get Started on the Command Line](https://robotcode.io/getting-started/command-line/) for the commands each extra brings, installing with pip or uv and a first run, and the [CLI reference](https://robotcode.io/reference/cli/) for every command and option.
120
120
 
121
121
 
122
122
  ## Documentation
@@ -124,7 +124,7 @@ Pick the extras that match your use case — see the [CLI reference](https://rob
124
124
  For detailed instructions, visit our **[official documentation](https://robotcode.io)**. Additional resources:
125
125
 
126
126
  - **[Q&A](https://github.com/robotcodedev/robotcode/discussions/categories/q-a):** Answers to common questions about RobotCode.
127
- - **[Guides](https://robotcode.io/guides/):** How to use RobotCode's commands and set up projects, plus common pitfalls and editor customization.
127
+ - **[Guides](https://robotcode.io/guides/):** How to work with RobotCode in VS Code, in PyCharm and on the command line, how to set up projects with `robot.toml`, and tips for Robot Framework code.
128
128
  - **[Command Line Tools Reference](https://robotcode.io/reference/cli/):** Comprehensive documentation on using RobotCode's CLI tools.
129
129
  - **[Changelog](https://github.com/robotcodedev/robotcode/blob/main/CHANGELOG.md):** Track changes, updates, and new features in each release.
130
130
  - **[Support & Contribute](https://robotcode.io/contributing/):** Ways to back the project — financial, code, feedback.
@@ -203,6 +203,9 @@ get-release-version = ["python scripts/get_release_version.py"]
203
203
  bump = ["cz bump {args}"]
204
204
  install-bundled-editable = "python ./scripts/install_bundled_editable.py"
205
205
  sync-chat-plugin = ["python scripts/sync_chat_plugin.py {args}"]
206
+ check-chat-plugin-release = ["python scripts/chat_plugin_release.py check {args}"]
207
+ prepare-chat-plugin-release = ["python scripts/chat_plugin_release.py prepare {args}"]
208
+ verify-chat-plugin-release = ["python scripts/chat_plugin_release.py verify-published {args}"]
206
209
 
207
210
 
208
211
  [envs.hatch-static-analysis]
@@ -49,26 +49,26 @@ classifiers = [
49
49
  "Framework :: Robot Framework :: Tool",
50
50
  ]
51
51
  requires-python = ">=3.10"
52
- dependencies = ["robotcode-core==2.8.0-dev.677", "robotcode-plugin==2.8.0-dev.677", "robotcode-robot==2.8.0-dev.677"]
52
+ dependencies = ["robotcode-core==2.9.0-dev.51", "robotcode-plugin==2.9.0-dev.51", "robotcode-robot==2.9.0-dev.51"]
53
53
  dynamic = ["version"]
54
54
 
55
55
  [project.optional-dependencies]
56
- debugger = ["robotcode-debugger==2.8.0-dev.677"]
57
- languageserver = ["robotcode-language-server==2.8.0-dev.677"]
58
- runner = ["robotcode-runner==2.8.0-dev.677"]
59
- analyze = ["robotcode-analyze==2.8.0-dev.677"]
56
+ debugger = ["robotcode-debugger==2.9.0-dev.51"]
57
+ languageserver = ["robotcode-language-server==2.9.0-dev.51"]
58
+ runner = ["robotcode-runner==2.9.0-dev.51"]
59
+ analyze = ["robotcode-analyze==2.9.0-dev.51"]
60
60
  yaml = ["PyYAML>=5.4"]
61
61
  lint = ["robotframework-robocop>=2.0.0"]
62
62
  rest = ["docutils"]
63
- repl = ["robotcode-repl==2.8.0-dev.677"]
64
- replserver = ["robotcode-repl-server==2.8.0-dev.677"]
63
+ repl = ["robotcode-repl==2.9.0-dev.51"]
64
+ replserver = ["robotcode-repl-server==2.9.0-dev.51"]
65
65
  all = [
66
- "robotcode-debugger==2.8.0-dev.677",
67
- "robotcode-language-server==2.8.0-dev.677",
68
- "robotcode-runner==2.8.0-dev.677",
69
- "robotcode-analyze==2.8.0-dev.677",
70
- "robotcode-repl==2.8.0-dev.677",
71
- "robotcode-repl-server==2.8.0-dev.677",
66
+ "robotcode-debugger==2.9.0-dev.51",
67
+ "robotcode-language-server==2.9.0-dev.51",
68
+ "robotcode-runner==2.9.0-dev.51",
69
+ "robotcode-analyze==2.9.0-dev.51",
70
+ "robotcode-repl==2.9.0-dev.51",
71
+ "robotcode-repl-server==2.9.0-dev.51",
72
72
  "PyYAML>=5.4",
73
73
  "robotframework-robocop>=6.0.0",
74
74
  "docutils"
@@ -84,7 +84,7 @@ repl = ["robotcode-repl"]
84
84
  yaml = ["PyYAML>=5.4"]
85
85
  lint = ["robotframework-robocop>=6.0.0"]
86
86
  rest = ["docutils"]
87
- html = ["html-to-markdown>=2.0"]
87
+ html = ["html-to-markdown>=3.18"]
88
88
  all = [
89
89
  { "include-group" = "debugger" },
90
90
  { "include-group" = "languageserver" },
@@ -358,11 +358,13 @@ changelog_merge_prerelease = true
358
358
  gpg_sign = true
359
359
  annotated_tag = true
360
360
  pre_bump_hooks = [
361
+ "hatch run build:check-chat-plugin-release",
361
362
  "hatch env remove lint",
362
363
  "hatch run build:update-git-versions",
363
364
  "hatch run build:update-changelog",
364
365
  "git add .",
365
366
  ]
367
+ post_bump_hooks = ["hatch run build:prepare-chat-plugin-release"]
366
368
 
367
369
 
368
370
  [tool.robotcode-analyze.extend-modifiers]
@@ -2,11 +2,8 @@ import json
2
2
  import logging
3
3
  import logging.config
4
4
  import os
5
- import shlex
6
- import subprocess
7
- import sys
8
5
  from pathlib import Path
9
- from typing import IO, Any, List, Literal, Optional
6
+ from typing import IO, Any, List, Literal, Mapping, Optional
10
7
 
11
8
  import click
12
9
 
@@ -17,12 +14,13 @@ from robotcode.plugin import (
17
14
  ColoredOutput,
18
15
  OutputFormat,
19
16
  pass_application,
17
+ show_error,
20
18
  )
21
19
  from robotcode.plugin._agent_detection import is_running_in_ai_agent
22
20
  from robotcode.plugin.click_helper.aliases import AliasedGroup
23
21
  from robotcode.plugin.click_helper.exit_codes import has_robot_exit_codes
24
22
  from robotcode.plugin.click_helper.types import EnumChoice
25
- from robotcode.plugin.click_helper.wrappable import WRAPPER_APPLIED_ENV, is_wrappable
23
+ from robotcode.plugin.click_helper.wrappable import WRAPPER_APPLIED_ENV, invoked_command_is_wrappable, is_wrappable
26
24
  from robotcode.plugin.manager import PluginManager
27
25
 
28
26
  from .__version__ import __version__
@@ -51,125 +49,77 @@ class RobotCodeFormatter(logging.Formatter):
51
49
  super().__init__(*args, defaults=defaults, **kwargs)
52
50
 
53
51
 
54
- def _maybe_reexec_under_wrapper(
55
- ctx: click.Context, app: Application, cli_wrapper: Optional[str] = None, no_wrapper: bool = False
56
- ) -> None:
57
- """Re-execute this process through a configured ``wrapper`` command.
58
-
59
- When a ``wrapper`` is configured - either via ``--wrapper`` on the command
60
- line (``cli_wrapper``) or the selected profile's ``wrapper`` (e.g. to run
61
- the tests inside a specific X11/Wayland session) - and the invoked command
62
- is ``@wrappable`` (i.e. it executes Robot Framework), the process
63
- re-executes itself **once** through that command before Robot Framework
64
- starts. ``--wrapper`` overrides the profile; ``--no-wrapper`` disables
65
- wrapping for this run. The guard env var prevents infinite recursion and
66
- lets an outer layer suppress the re-exec by setting it itself.
52
+ def _warn_about_ignored_wrapper(ctx: click.Context, app: Application) -> None:
53
+ """Warn about a ``--wrapper`` that does not apply.
54
+
55
+ The command itself starts robotcode under the ``wrapper``, once it has loaded its
56
+ configuration (see `robotcode.plugin.click_helper.wrappable.run_under_wrapper`).
67
57
  """
68
- if no_wrapper:
69
- if cli_wrapper:
58
+ if app.config.no_wrapper:
59
+ if app.config.wrapper:
70
60
  app.warning("Ignoring --wrapper because --no-wrapper was given.")
71
61
  return
72
- if os.environ.get(WRAPPER_APPLIED_ENV):
62
+ if not app.config.wrapper or os.environ.get(WRAPPER_APPLIED_ENV) or not ctx.invoked_subcommand:
73
63
  return
64
+ if not invoked_command_is_wrappable(ctx):
65
+ app.warning(f"Ignoring --wrapper: '{ctx.invoked_subcommand}' does not execute Robot Framework.")
74
66
 
75
- sub_name = ctx.invoked_subcommand
76
- if not sub_name:
77
- return
78
- # The command itself opts in via @wrappable; aliases resolve to the same
79
- # command object, so this is alias-safe and needs no central name list.
80
- sub_cmd = ctx.command.get_command(ctx, sub_name) if isinstance(ctx.command, click.Group) else None
81
- if sub_cmd is None or not is_wrappable(sub_cmd):
82
- if cli_wrapper:
83
- app.warning(f"Ignoring --wrapper: '{sub_name}' does not execute Robot Framework.")
84
- return
85
67
 
86
- from robotcode.robot.config.loader import load_robot_config_from_path
87
- from robotcode.robot.config.utils import get_config_files
88
-
89
- profile_wrapper = None
90
- try:
91
- config_files, _, _ = get_config_files(
92
- config_files=app.config.config_files,
93
- root_folder=app.config.root,
94
- no_vcs=app.config.no_vcs,
95
- verbose_callback=app.verbose,
96
- )
97
- # `evaluated_with_env` also applies the profile's `env` to `os.environ`,
98
- # so the wrapper command can rely on it. Profile errors are swallowed
99
- # here: the command loads the config again and reports them, so they
100
- # show up once. (Without a callback they would raise, and an unknown
101
- # profile would make us skip the wrapper of a valid one.)
102
- profile = (
103
- load_robot_config_from_path(*config_files, verbose_callback=app.verbose)
104
- .combine_profiles(*(app.config.profiles or []), verbose_callback=app.verbose, error_callback=lambda _: None)
105
- .evaluated_with_env(verbose_callback=app.verbose, error_callback=lambda _: None)
106
- )
107
- profile_wrapper = profile.wrapper
108
- except Exception as e:
109
- # Don't fail early on config problems here; the actual command loads the
110
- # config again and reports errors properly. An explicit --wrapper is
111
- # still honored below.
112
- message = str(e)
113
- app.verbose(lambda: f"Skipping profile wrapper detection: {message}")
114
-
115
- # `--wrapper` overrides the profile's `wrapper`. The evaluated profile turns
116
- # StringExpression entries into plain strings.
117
- if cli_wrapper:
118
- wrapper = shlex.split(cli_wrapper)
119
- elif profile_wrapper:
120
- wrapper = [str(w) for w in profile_wrapper]
68
+ def _set_output_options(app: Application, color: Optional[bool], pager: Optional[bool]) -> None:
69
+ """Set the colour and pager choice of `app` from `--color/--no-color` and `--pager/--no-pager`."""
70
+ if color is None:
71
+ app.config.colored_output = ColoredOutput.AUTO
72
+ elif color:
73
+ app.config.colored_output = ColoredOutput.YES
121
74
  else:
122
- return
75
+ app.config.colored_output = ColoredOutput.NO
76
+ app.config.pager = pager
123
77
 
124
- # A dry run must not start the wrapper: it would set up and tear down the
125
- # real environment. Show it instead; the command itself then prints its own
126
- # dry-run output.
127
- if app.config.dry:
128
- app.echo(f"Dry run, not executing the wrapper. Would run robotcode under: {' '.join(wrapper)}")
129
- return
78
+ # AI-agent auto-detect: when running inside a known agent session
79
+ # (Claude Code, Copilot, OpenCode, …) demote colour and pager
80
+ # defaults so the agent's stdout capture stays clean. Explicit CLI
81
+ # flags and `NO_COLOR` / `FORCE_COLOR` keep their precedence.
82
+ if is_running_in_ai_agent():
83
+ if color is None and not os.environ.get("NO_COLOR") and not os.environ.get("FORCE_COLOR"):
84
+ app.config.colored_output = ColoredOutput.NO
85
+ if pager is None:
86
+ app.config.pager = False
130
87
 
131
- # Rebuild the invocation the way this process was actually started, so the
132
- # re-exec finds robotcode even when it runs from a bundled path (VS Code) and
133
- # is not installed in the interpreter. `launcher_script` is set only when we
134
- # were started through a bundled entry (its `__main__` sets it) or an explicit
135
- # `--launcher-script`; otherwise robotcode is importable directly and
136
- # `-m robotcode.cli` is correct. We deliberately do NOT consult the
137
- # ROBOTCODE_BUNDLED_ROBOTCODE_MAIN env var: VS Code sets it in every terminal,
138
- # so a directly started robotcode would be diverted to the bundled copy.
139
- # Mirrors the debug launcher's `debugger_script` handling.
140
- entry = [str(app.config.launcher_script)] if app.config.launcher_script else ["-m", "robotcode.cli"]
141
- command = [*wrapper, sys.executable, *entry, *sys.argv[1:]]
142
- app.verbose(lambda: "Running under wrapper: " + " ".join(command))
143
-
144
- # Run robotcode again under the wrapper; the guard env stops the spawned
145
- # robotcode from wrapping a second time. On POSIX we replace this process with
146
- # execvp (no extra process); Windows has no such exec, so there we spawn the
147
- # command, wait, and forward its exit code.
148
- os.environ[WRAPPER_APPLIED_ENV] = "1"
149
- try:
150
- if sys.platform == "win32":
151
- sys.exit(subprocess.run(command).returncode)
152
- os.execvp(command[0], command)
153
- except OSError as e:
154
- raise click.ClickException(f"Failed to execute wrapper command {wrapper!r}: {e}") from e
155
-
156
-
157
- class RobotDataError(click.ClickException):
158
- """An error robotcode reports itself for a command that passes on Robot Framework's
159
- exit codes.
160
88
 
161
- Shows the original error unchanged, but exits with Robot Framework's code for invalid
162
- data or command line options instead of Click's 1 or 2.
163
- """
89
+ def _application_for(params: Mapping[str, Any]) -> Application:
90
+ """An `Application` for an error that comes before the root command has set one up,
91
+ set up from robotcode's own options `params` as far as they are known."""
92
+ app = Application()
93
+ _set_output_options(app, params.get("color"), params.get("pager"))
94
+ return app
95
+
164
96
 
165
- exit_code = 252
97
+ class RobotCodeError(click.ClickException):
98
+ """An error that stops a robotcode command, written as robotcode writes the errors it
99
+ reports (`robotcode.plugin.show_error`). Keeps the exit code of the error."""
166
100
 
167
- def __init__(self, error: click.ClickException) -> None:
101
+ def __init__(self, error: click.ClickException, app: Application) -> None:
168
102
  super().__init__(error.message)
169
103
  self.error = error
104
+ self.app = app
105
+ # click declares the exit code on the class; this one is the code of the error
106
+ self.exit_code = error.exit_code # type: ignore[misc]
170
107
 
171
108
  def show(self, file: Optional[IO[Any]] = None) -> None:
172
- self.error.show(file)
109
+ show_error(self.app, self.error, file)
110
+
111
+
112
+ class RobotDataError(RobotCodeError):
113
+ """An error robotcode reports itself for a command that passes on Robot Framework's
114
+ exit codes.
115
+
116
+ Exits with Robot Framework's code for invalid data or command line options instead of
117
+ Click's 1 or 2.
118
+ """
119
+
120
+ def __init__(self, error: click.ClickException, app: Application) -> None:
121
+ super().__init__(error, app)
122
+ self.exit_code = 252 # type: ignore[misc]
173
123
 
174
124
 
175
125
  class RobotCodeGroup(AliasedGroup):
@@ -182,15 +132,40 @@ class RobotCodeGroup(AliasedGroup):
182
132
  invalid option - exits with Robot Framework's 252 instead. Robot Framework's own exit
183
133
  codes never arrive as Click errors, so they pass through unchanged, and so does any
184
134
  other code.
135
+
136
+ Every Click error of a command or of the group's own options is written as
137
+ `[ ERROR ] <message>`, with the `Application` of the command. An error that comes
138
+ before the root command has set it up - a command name that does not exist or is
139
+ missing, an invalid option of robotcode itself - gets one set up from robotcode's own
140
+ options, so that `--no-color` and AI-agent sessions apply to it too.
185
141
  """
186
142
 
143
+ def make_context(
144
+ self, info_name: Optional[str], args: List[str], parent: Optional[click.Context] = None, **extra: Any
145
+ ) -> click.Context:
146
+ # Click's parser takes the arguments out of the list it gets
147
+ command_line = list(args)
148
+ try:
149
+ return super().make_context(info_name, args, parent, **extra)
150
+ except click.ClickException as e:
151
+ # Click stops at an invalid option before it takes any value; read robotcode's
152
+ # own options again as Click's shell completion does, without errors or
153
+ # callbacks, passing over unknown options
154
+ lenient = {**extra, "resilient_parsing": True, "ignore_unknown_options": True}
155
+ try:
156
+ params = super().make_context(info_name, command_line, parent, **lenient).params
157
+ except click.ClickException:
158
+ params = {}
159
+ raise RobotCodeError(e, _application_for(params)) from e
160
+
187
161
  def invoke(self, ctx: click.Context) -> Any:
188
162
  try:
189
163
  return super().invoke(ctx)
190
164
  except click.ClickException as e:
165
+ app = ctx.find_object(Application) or _application_for(ctx.params)
191
166
  if e.exit_code in (1, 2) and self._passes_on_robot_exit_codes(ctx):
192
- raise RobotDataError(e) from e
193
- raise
167
+ raise RobotDataError(e, app) from e
168
+ raise RobotCodeError(e, app) from e
194
169
 
195
170
  def _passes_on_robot_exit_codes(self, ctx: click.Context) -> bool:
196
171
  name = ctx.invoked_subcommand
@@ -443,31 +418,17 @@ def robotcode(
443
418
  app.config.root = root
444
419
  app.config.no_vcs = no_vcs
445
420
 
446
- if color is None:
447
- app.config.colored_output = ColoredOutput.AUTO
448
- elif color:
449
- app.config.colored_output = ColoredOutput.YES
450
- else:
451
- app.config.colored_output = ColoredOutput.NO
452
- app.config.pager = pager
453
-
454
- # AI-agent auto-detect: when running inside a known agent session
455
- # (Claude Code, Copilot, OpenCode, …) demote colour and pager
456
- # defaults so the agent's stdout capture stays clean. Explicit CLI
457
- # flags and `NO_COLOR` / `FORCE_COLOR` keep their precedence.
458
- if is_running_in_ai_agent():
459
- if color is None and not os.environ.get("NO_COLOR") and not os.environ.get("FORCE_COLOR"):
460
- app.config.colored_output = ColoredOutput.NO
461
- if pager is None:
462
- app.config.pager = False
421
+ _set_output_options(app, color, pager)
463
422
  app.config.output_format = format
464
423
  app.config.launcher_script = launcher_script
465
424
  app.config.default_paths = default_path
466
425
  app.config.log_enabled = log
467
426
  app.config.log_level = log_level
468
427
  app.config.log_calls = log_calls
428
+ app.config.wrapper = wrapper
429
+ app.config.no_wrapper = no_wrapper
469
430
 
470
- _maybe_reexec_under_wrapper(ctx, app, wrapper, no_wrapper)
431
+ _warn_about_ignored_wrapper(ctx, app)
471
432
 
472
433
  if log_config:
473
434
  if log_calls:
@@ -0,0 +1 @@
1
+ __version__ = "2.9.0-dev.51"
@@ -13,6 +13,7 @@ from robotcode.robot.config.loader import (
13
13
  DiscoverdBy,
14
14
  load_robot_config_from_path,
15
15
  )
16
+ from robotcode.robot.config.model import UnknownProfile
16
17
  from robotcode.robot.config.utils import get_config_files
17
18
 
18
19
 
@@ -85,8 +86,20 @@ def list(app: Application, paths: List[Path], show_hidden: bool = False, sort_by
85
86
 
86
87
  config = load_robot_config_from_path(*config_files, verbose_callback=app.verbose)
87
88
 
89
+ # the editors fill their profile lists with this command, also when their selection names a profile that is
90
+ # gone, so a name that selects no profile is only reported, and those of the selection are listed for them
91
+ unknown_selected: List[str] = []
92
+
93
+ def report_unknown(unknown: UnknownProfile) -> None:
94
+ app.error(unknown.message)
95
+ if unknown.selected:
96
+ unknown_selected.append(unknown.name)
97
+
88
98
  _, selected_profiles, enabled_names = config.combine_profiles_ex(
89
- *(app.config.profiles or []), verbose_callback=app.verbose, error_callback=app.error
99
+ *(app.config.profiles or []),
100
+ verbose_callback=app.verbose,
101
+ error_callback=app.error,
102
+ unknown_profile_callback=report_unknown,
90
103
  )
91
104
 
92
105
  selected_names = [k for k in selected_profiles.keys()]
@@ -121,6 +134,8 @@ def list(app: Application, paths: List[Path], show_hidden: bool = False, sort_by
121
134
  messages += ["No profiles defined."]
122
135
  if messages:
123
136
  result["messages"] = messages
137
+ if unknown_selected:
138
+ result["unknownSelected"] = unknown_selected
124
139
 
125
140
  if app.config.output_format is None or app.config.output_format == OutputFormat.TEXT:
126
141
  for v in result["profiles"]:
@@ -1 +0,0 @@
1
- __version__ = "2.8.0-dev.677"