mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-04 01:44:13 +02:00
Script buttons, live mode and macro recorder pages (PRs #1219-#1225, #1227, #1228, pending); report-arrow submenu fix (#1218, pending)
New pages script_buttons, assistant_live_mode, macro_recorder, linked from the sidebar, scripting, mcp_server and ai_assistants. ai_assistants: the 29 Sep section no longer says 'Not merged yet'.
+6
@@ -157,6 +157,12 @@
|
||||
|
||||
**[Connecting an AI assistant](ai_assistants)** — setup for Claude, Copilot, Gemini, Codex, Cursor, LM Studio
|
||||
|
||||
**[Script buttons](script_buttons)** — stored scripts with an icon, by hand or by an assistant _(pending)_
|
||||
|
||||
**[Live mode](assistant_live_mode)** — an assistant working in the open project while you watch _(pending)_
|
||||
|
||||
**[Macro recorder](macro_recorder)** — record a task by hand, for an assistant to script _(pending)_
|
||||
|
||||
**[Development Roadmap](development_roadmap)**
|
||||
|
||||
**[Vision](vision)** — _proposal, under discussion_
|
||||
|
||||
+20
-1
@@ -230,7 +230,7 @@ The server speaks MCP over standard input and output.
|
||||
|
||||
---
|
||||
|
||||
## Not merged yet
|
||||
## Added on 29 September 2026
|
||||
|
||||
Four changes make this simpler. All four merged on 29 September 2026, so
|
||||
they are in builds made after that (on Windows, nightlies newer than
|
||||
@@ -278,6 +278,24 @@ It also tells you, in bold, when something is missing:
|
||||
| *Python est introuvable sur cet ordinateur* | the Python the setup names is not there. On Windows, run the QElectroTech installer again and tick *Python pour l'assistant IA*, or install Python; elsewhere, install Python 3 from your system's packages |
|
||||
| *Python n'est peut-être pas installé* (Windows) | only the Microsoft Store shortcut answers to `python`, which opens the Store instead of running the server |
|
||||
|
||||
## Coming next: buttons, live mode, recordings
|
||||
|
||||
> **Status: pending.** Described on their own pages, each in open pull
|
||||
> requests ([#1219](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1219)–[#1225](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1225),
|
||||
> [#1227](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1227),
|
||||
> [#1228](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1228)).
|
||||
> None works until they are merged.
|
||||
|
||||
- **[Script buttons](script_buttons)**: ask the assistant for a button; it
|
||||
writes the script, tests it on a copy of a project, and stores it with an
|
||||
icon. You press it.
|
||||
- **[Live mode](assistant_live_mode)**: with a setting turned on and a warning
|
||||
accepted at each start, the assistant works in the project you have open,
|
||||
one Ctrl+Z per action.
|
||||
- **[Macro recorder](macro_recorder)**: do the task once by hand while
|
||||
recording, paste the request, and the assistant writes a script it has
|
||||
checked does the same.
|
||||
|
||||
## ChatGPT, and Claude or Copilot in a web browser
|
||||
|
||||
These reach a server only through the internet, from their own computers.
|
||||
@@ -290,3 +308,4 @@ still use the server's reading tools on a project you upload to it. See
|
||||
|
||||
- **[MCP server](mcp_server)**: every tool and setting
|
||||
- **[JavaScript Scripting](scripting)**: what edits run underneath
|
||||
- **[Script buttons](script_buttons)**, **[Live mode](assistant_live_mode)**, **[Macro recorder](macro_recorder)**: pending
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
# Live mode: an AI assistant working in the open project
|
||||
|
||||
Normally an AI assistant connected through the **[MCP server](mcp_server)**
|
||||
works on files: it reads a `.qet`, tests changes on copies, and never touches
|
||||
the drawing you have open. **Live mode** adds a second way of working: the
|
||||
assistant on one screen, QElectroTech on the other, and each thing it does
|
||||
happens in front of you, in the project you have open — where you can watch
|
||||
it, refuse it, undo it, or carry on by hand.
|
||||
|
||||
> **Status: pending.** Nothing on this page is merged yet:
|
||||
>
|
||||
> | PR | What it adds | Builds on |
|
||||
> |---|---|---|
|
||||
> | [#1222](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1222) | the setting, the startup warning, the status-bar indicator, running scripts live | [#1221](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1221) ([script buttons](script_buttons)) |
|
||||
> | [#1223](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1223) | the *Assistant* panel, ask-first, the allowed commands, the screenshot | #1222 |
|
||||
> | [#1225](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1225) | the `qet_live_*` MCP tools | [#1224](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1224) |
|
||||
>
|
||||
> Check those PRs before trying any of this against your own build. The
|
||||
> proposal is
|
||||
> [discussion #1226](https://github.com/qelectrotech/qelectrotech-source-mirror/discussions/1226).
|
||||
|
||||
Menu and option names are given in French, as QElectroTech shows them until
|
||||
the translations are updated, with an English gloss in italics.
|
||||
|
||||
---
|
||||
|
||||
## The two ways an assistant works
|
||||
|
||||
| | Headless (the usual way) | Live |
|
||||
|---|---|---|
|
||||
| works on | `.qet` files and copies of them | the project open in your QElectroTech |
|
||||
| QElectroTech running? | no — started in the background for each call | yes, your own window |
|
||||
| MCP tools | `qet_*`, `qet_script_*` | `qet_live_*` only |
|
||||
| what you must switch on | `QET_ENABLE_SCRIPTING=1` | that, **and** the live setting, **and** the warning at this start |
|
||||
| undo | nothing of yours changed | one Ctrl+Z per assistant action |
|
||||
|
||||
A script tested headless runs the same way live; only where it runs changes.
|
||||
The tools are kept apart so one can never be taken for the other.
|
||||
|
||||
---
|
||||
|
||||
## Switching it on: three switches
|
||||
|
||||
1. **The MCP server** is started with `QET_ENABLE_SCRIPTING=1`, as for the
|
||||
editing tools (see [Scripting gate](mcp_server#scripting-gate)).
|
||||
2. **The setting.** In **Configurer QElectroTech > Général** (*Settings >
|
||||
General*): *Autoriser un assistant IA à agir sur le projet ouvert (mode
|
||||
direct)* (*Allow an AI assistant to act on the open project (live mode)*).
|
||||
Off by default. It takes effect at the next start; unticking it cuts the
|
||||
connection at once.
|
||||
3. **The warning, at every start.** While the setting is on, each time
|
||||
QElectroTech starts it shows, before anything can connect:
|
||||
|
||||
> *Le mode direct est activé : un assistant IA connecté pourra exécuter des
|
||||
> scripts sur le projet ouvert. Chaque action s'annule d'un Ctrl+Z, et le
|
||||
> bouton « Arrêter » de la barre d'état coupe la connexion.*
|
||||
>
|
||||
> (*Live mode is on: a connected AI assistant will be able to run scripts on
|
||||
> the open project. Each action is undone with Ctrl+Z, and the "Stop" button
|
||||
> on the status bar cuts the connection.*)
|
||||
|
||||
| Button | Does |
|
||||
|---|---|
|
||||
| *Continuer* (*Continue*) | opens the connection for this session |
|
||||
| *Pas pour cette session* (*Not this session*) | stays closed until the next start |
|
||||
| *Désactiver* (*Turn off*) | stays closed and turns the setting off |
|
||||
|
||||
So a setting you forgot about can never leave the door open silently.
|
||||
|
||||
With the setting off, QElectroTech opens nothing at all and behaves exactly as
|
||||
it does without this feature; the `qet_live_*` tools answer that live mode is
|
||||
off and do nothing. When they cannot connect, they say which of the three
|
||||
switches is missing.
|
||||
|
||||
---
|
||||
|
||||
## While the assistant is connected
|
||||
|
||||
### The status bar
|
||||
|
||||
Shows *Mode direct : en attente d'un assistant* (*Live mode: waiting for an
|
||||
assistant*) or *Mode direct : assistant connecté* (*assistant connected*), then
|
||||
the last thing it did, with ✓ or ✗ and the time. Hover it for the error, if
|
||||
there was one.
|
||||
|
||||
**Arrêter** (*Stop*) beside it cuts the connection for the rest of the session.
|
||||
|
||||
### The Assistant panel
|
||||
|
||||
> **Status: pending** — [PR #1223](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1223).
|
||||
|
||||
A panel called **Assistant** opens on the right while live mode is open. It
|
||||
lists every action, newest first: the time, ✓ or ✗, and its undo step's name.
|
||||
Hover an entry, or double-click it, for the details: the error, what the
|
||||
script logged, and the script itself.
|
||||
|
||||
At the top: *Demander avant d'exécuter un script écrit par l'assistant* (*Ask
|
||||
before running a script the assistant wrote*), **ticked at every start**. While
|
||||
it is ticked, a script the assistant wrote on the spot is shown to you first,
|
||||
in a box titled *L'assistant veut exécuter un script* (*The assistant wants to
|
||||
run a script*):
|
||||
|
||||
| Button | Does |
|
||||
|---|---|
|
||||
| *Exécuter* (*Run*) | runs it |
|
||||
| *Refuser* (*Refuse*) | nothing happens; the assistant is told you refused |
|
||||
| *Toujours pour cette session* (*Always this session*) | runs it and stops asking until the next start |
|
||||
|
||||
Stored scripts — the **[script buttons](script_buttons)** you already have —
|
||||
run without asking: you put them there.
|
||||
|
||||
### Undo
|
||||
|
||||
Each assistant action is **one undo step**, named *Assistant : <what it
|
||||
did>*, in the same undo history as your own work. Ctrl+Z takes it back.
|
||||
|
||||
The assistant can undo too (`qet_live_undo_last`), but **only its own last
|
||||
step**. If the newest step is something you did, it is refused: what you do by
|
||||
hand stays yours to undo.
|
||||
|
||||
---
|
||||
|
||||
## What the assistant can do
|
||||
|
||||
> **Status: pending** — [PR #1225](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1225)
|
||||
> (and #1223 for the commands and the screenshot).
|
||||
|
||||
| Tool | Does | Needs `QET_ENABLE_SCRIPTING=1` |
|
||||
|---|---|---|
|
||||
| `qet_live_status` | is QElectroTech there and live mode open; the project and sheet on screen, how many sheets, what is selected, the last undo step; the stored scripts; whether a [macro recording](macro_recorder) is under way | no |
|
||||
| `qet_live_run_script` | runs script text on the open project (asks you first, see above); returns what it logged, its error, and the undo step's name | yes |
|
||||
| `qet_live_run_stored` | presses one of your stored script buttons, by its id | yes |
|
||||
| `qet_live_command` | runs one editor command from a fixed list (below) | no |
|
||||
| `qet_live_show_folio` | shows another sheet of the open project | no |
|
||||
| `qet_live_undo_last` | undoes the newest step, only if it was the assistant's | no |
|
||||
| `qet_live_screenshot` | an image of the sheet on screen, so the assistant sees what you see | no |
|
||||
|
||||
### The commands it may use
|
||||
|
||||
Only commands that open no window, so nothing can end up waiting for an
|
||||
answer nobody gives. Everything else — saving, deleting, exporting, printing —
|
||||
is refused; for edits it runs a script, which you can undo.
|
||||
|
||||
| Command id (`diagrameditor.…`) | |
|
||||
|---|---|
|
||||
| `select_all`, `select_nothing`, `select_invert`, `select_all_conductors`, `select_all_text_fields` | selection |
|
||||
| `zoom_in`, `zoom_out`, `zoom_content`, `zoom_fit`, `zoom_reset` | view |
|
||||
| `rotate_selection`, `rotate_texts`, `snap_selection_to_grid` | arrange |
|
||||
| `group_selection`, `ungroup_selection` | [groups](grouping_items) |
|
||||
| `conductor_reset` | redraw the selected wires' path |
|
||||
|
||||
### What it cannot do
|
||||
|
||||
- **Click on the screen.** Clicking at coordinates breaks at every layout
|
||||
change and can be steered by anything drawn on a sheet. The assistant acts
|
||||
only through the same calls a script button uses.
|
||||
- **Open a dialog.** `qet.showMessage()` in a live script goes to the log
|
||||
instead of opening a box.
|
||||
- **Run two things at once.** One request at a time; a second one meanwhile is
|
||||
answered "busy". A script still stops after 30 seconds.
|
||||
- **Reach you over the network.** The connection is a local socket (a named
|
||||
pipe on Windows), on your own machine only.
|
||||
|
||||
---
|
||||
|
||||
## How the assistant finds QElectroTech
|
||||
|
||||
When you press *Continuer*, QElectroTech adds the connection's name and a
|
||||
random token to `qet-assistant.json` (see
|
||||
[script buttons](script_buttons#qet-assistantjson)), readable only by you, and
|
||||
removes them on *Arrêter* or when it closes. The MCP server reads them from
|
||||
there; a connection without the token is closed.
|
||||
|
||||
The token keeps out other users of the computer and stale connections. A
|
||||
program already running as you could read your projects anyway, which is why
|
||||
what you can see — the indicator, the panel, ask-first, undo — matters more
|
||||
than the token.
|
||||
|
||||
---
|
||||
|
||||
## The risk, stated plainly
|
||||
|
||||
Live mode is the one place an assistant changes the project you have open. The
|
||||
risk it adds: **text inside a project you received** (a label, a note, a
|
||||
title-block field) could try to steer the assistant into editing your drawing.
|
||||
The answers are ask-first for anything the assistant writes itself, the log,
|
||||
and one Ctrl+Z per action. If you do not need it, leave the setting off.
|
||||
|
||||
---
|
||||
|
||||
## A session, start to finish
|
||||
|
||||
1. Tick the live setting, restart QElectroTech, press *Continuer*. The status
|
||||
bar says *en attente d'un assistant*; the Assistant panel opens.
|
||||
2. Open your project. In the assistant's chat: *"number the wires on the sheet
|
||||
I'm looking at, starting at 100"*.
|
||||
3. The assistant calls `qet_live_status`, sees the project and sheet, and may
|
||||
take a `qet_live_screenshot`.
|
||||
4. It writes a script and sends it with `qet_live_run_script`. The ask-first
|
||||
box shows it; you press *Exécuter*.
|
||||
5. The wires are numbered; the panel shows *Assistant : …* with ✓.
|
||||
Not what you wanted? Ctrl+Z.
|
||||
6. **Arrêter** when you are done.
|
||||
|
||||
---
|
||||
|
||||
## Limitations
|
||||
|
||||
- **macOS has not been tested.** Linux, and a Windows build under Wine with a
|
||||
Windows-side client, have.
|
||||
- **No questions back.** A live script cannot ask you for a value; the
|
||||
assistant asks in its chat instead.
|
||||
|
||||
---
|
||||
|
||||
## See also
|
||||
|
||||
- **[Script buttons](script_buttons)** — the stored scripts live mode can press
|
||||
- **[Macro recorder](macro_recorder)** — show the assistant a task instead of describing it
|
||||
- **[MCP server](mcp_server)** and **[Connecting an AI assistant](ai_assistants)**
|
||||
- **[JavaScript Scripting](scripting)** — what a script can do
|
||||
- [Discussion #1226](https://github.com/qelectrotech/qelectrotech-source-mirror/discussions/1226) — the proposal
|
||||
@@ -93,6 +93,18 @@ A project that has none yet gets the common collection's **Coming arrow** and
|
||||
**Going arrow**. If the common collection isn't available either, the
|
||||
submenu is hidden. It is also hidden on a read-only sheet.
|
||||
|
||||
> **Status: pending.** The paragraph below describes
|
||||
> [PR #1218](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1218),
|
||||
> not yet merged. Until it lands, current builds show the bug it fixes
|
||||
> ([#1210](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/1210)):
|
||||
> once you place a Coming arrow, the Going arrow drops out of the submenu
|
||||
> (and the other way round), and comes back only after closing the project
|
||||
> without saving.
|
||||
|
||||
With #1218 the submenu always lists the standard **Coming arrow** and
|
||||
**Going arrow**, after the report symbols the project already uses, and each
|
||||
name appears once. Placing one arrow no longer hides the other.
|
||||
|
||||
For what a sheet report does once placed, see
|
||||
**[Linking wires across pages](folio_links)**.
|
||||
|
||||
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
# Macro recorder
|
||||
|
||||
Do a task once by hand in QElectroTech, with recording on. Then hand the
|
||||
recording to an AI assistant, which turns it into a general, tested
|
||||
**[script button](script_buttons)** — "rotate the selected coils half a
|
||||
turn" rather than "rotate KA1 and KA2".
|
||||
|
||||
> **Status: pending.** Nothing on this page is merged yet:
|
||||
>
|
||||
> | PR | What it adds | Builds on |
|
||||
> |---|---|---|
|
||||
> | [#1227](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1227) | recording in QElectroTech: start, stop, the files, the status bar, the request to paste | [#1223](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1223) |
|
||||
> | [#1228](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1228) | the `qet_recording_*` MCP tools | [#1225](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1225) |
|
||||
>
|
||||
> Both sit at the end of the [script buttons](script_buttons) series. Check
|
||||
> the PRs before trying any of this against your own build.
|
||||
|
||||
> **Not the same "macros" as templates.** QElectroTech's
|
||||
> **[templates](templates)** — reusable blocks of symbols — live in a folder
|
||||
> called `macros`. The macro recorder has nothing to do with them: it records
|
||||
> *what you do*, and its result is a script.
|
||||
|
||||
Menu and option names are given in French, as QElectroTech shows them until
|
||||
the translations are updated, with an English gloss in italics.
|
||||
|
||||
---
|
||||
|
||||
## Why a recording, and not a replay
|
||||
|
||||
Describing a drawing task in words to an assistant is slow and easy to get
|
||||
wrong. Showing it is quicker. But replaying your mouse clicks would break as
|
||||
soon as anything on the sheet moved, so the recorder does not keep clicks. It
|
||||
keeps **what changed**, step by step, and the whole project before and after.
|
||||
The assistant writes a script from that, and checks the script reproduces
|
||||
exactly the change you made.
|
||||
|
||||
QElectroTech cannot send anything to an assistant itself: the assistant asks,
|
||||
QElectroTech answers. So the recording is saved where the assistant's
|
||||
**[MCP server](mcp_server)** can read it, and you hand it over with one paste.
|
||||
|
||||
---
|
||||
|
||||
## Recording
|
||||
|
||||
> **Status: pending** — [PR #1227](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1227).
|
||||
|
||||
1. Open the project and select what the task starts from (the selection is
|
||||
recorded too).
|
||||
2. **Projet > Scripts > Enregistrer une macro** (*Project > Scripts > Record a
|
||||
macro*). It is also a command in command search (**Ctrl+Shift+M**) and on
|
||||
the **S** shortcut bar if you add it.
|
||||
3. Do the task. The status bar shows *● Enregistrement : N étape(s)*
|
||||
(*Recording: N steps*) with an **Arrêter** (*Stop*) button.
|
||||
4. Stop: **Arrêter**, or the same menu entry, which is ticked while recording.
|
||||
|
||||
A box, *Macro enregistrée* (*Macro recorded*), gives the recording's name
|
||||
(*Macro du 02/10/2026 14:30*), its number of steps and its folder:
|
||||
|
||||
| Button | Does |
|
||||
|---|---|
|
||||
| *Copier la demande pour l'assistant* (*Copy the request for the assistant*) | copies a ready-made request to paste into the assistant's chat |
|
||||
| *Ouvrir le dossier* (*Open the folder*) | opens the recording's folder |
|
||||
| *Fermer* (*Close*) | closes the box; the recording stays saved |
|
||||
|
||||
Recording needs no setting: it only writes files. Turning it into a script
|
||||
does — see below.
|
||||
|
||||
### What counts as a step
|
||||
|
||||
Every entry the task adds to the undo history (*Annulations*, *Undo* panel) is
|
||||
one step: its name as the Undo panel shows it, which sheet, what
|
||||
was selected after it, and the sheet as it was after it. Because steps come
|
||||
from the undo history, any command QElectroTech has is recorded with nothing
|
||||
to teach the recorder.
|
||||
|
||||
- **An undo during the recording** is recorded as a step too.
|
||||
- **Several moves of the same item in a row** merge into one step, as they do
|
||||
in the undo history. The before-and-after result is still exact.
|
||||
- **Closing the project while recording** stops it and keeps the steps so far,
|
||||
but there is then no "after" project, and the recording says so.
|
||||
|
||||
### Where it is saved
|
||||
|
||||
In the `recordings` folder of your QElectroTech data folder, one folder per
|
||||
recording:
|
||||
|
||||
| System | Folder |
|
||||
|---|---|
|
||||
| Linux | `~/.local/share/QElectroTech/QElectroTech/recordings/` |
|
||||
| Windows | `%APPDATA%\QElectroTech\QElectroTech\recordings\` |
|
||||
| macOS | `~/Library/Application Support/QElectroTech/QElectroTech/recordings/` |
|
||||
|
||||
```
|
||||
recordings/<id>/
|
||||
recording.json name, project, start and stop time, the steps
|
||||
before.qet the whole project when you started recording
|
||||
after.qet the whole project when you stopped
|
||||
steps/003.xml the sheet the step happened on, as it was after step 3
|
||||
```
|
||||
|
||||
`qet-assistant.json` (see
|
||||
[script buttons](script_buttons#qet-assistantjson)) lists the recordings and
|
||||
whether one is under way; in **[live mode](assistant_live_mode)**,
|
||||
`qet_live_status` says so too.
|
||||
|
||||
On a very large project, saving `before.qet` and `after.qet` can take a few
|
||||
seconds, as saving the project does — at start and stop only, not at each
|
||||
step.
|
||||
|
||||
---
|
||||
|
||||
## Turning it into a script
|
||||
|
||||
> **Status: pending** — [PR #1228](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1228).
|
||||
|
||||
Paste the copied request into the assistant's chat. It names the recording and
|
||||
asks the assistant to read it with `qet_recording_read`, write a script that
|
||||
does the same **in general** (on the selected items rather than on those
|
||||
particular ones), check it with `qet_recording_check` until it matches, then
|
||||
offer it as a button with `qet_script_install`. You can add to it: *"…and make
|
||||
it work on every sheet"*.
|
||||
|
||||
| Tool | Does | Needs `QET_ENABLE_SCRIPTING=1` |
|
||||
|---|---|---|
|
||||
| `qet_recording_list` | the recordings, newest first: id, name, steps, project | no |
|
||||
| `qet_recording_read` | one recording as structured changes — each step's name, sheet, selection and what changed on the sheet ("element KA1 moved by (20, 0)", "wire added between …") — and the overall change from before to after | no |
|
||||
| `qet_recording_check` | runs a script on a copy of `before.qet`, starting from the same sheet and selection you had, and compares the result with `after.qet`: **matches**, or what differs | yes |
|
||||
| `qet_recording_remove` | deletes one recording | yes |
|
||||
|
||||
`qet_recording_check` is what makes "the script does what I did" a measured
|
||||
fact rather than the assistant's guess. A rotation by the wrong angle, a
|
||||
script that does nothing, or one that fails — each is reported, the last with
|
||||
the line that failed.
|
||||
|
||||
---
|
||||
|
||||
## Worked example
|
||||
|
||||
1. Select the two coils on a sheet.
|
||||
2. **Projet > Scripts > Enregistrer une macro**.
|
||||
3. Rotate the selection twice (Space, Space).
|
||||
4. **Arrêter** → *Copier la demande pour l'assistant* → paste into the chat.
|
||||
5. The assistant reads 2 steps, writes "rotate every selected symbol by 180°",
|
||||
and `qet_recording_check` reports a match. A first try at 90° would be
|
||||
reported a quarter turn off.
|
||||
6. It installs the script; a **Scripts** toolbar button appears. Next time,
|
||||
select any symbols and click it.
|
||||
|
||||
---
|
||||
|
||||
## Limitations
|
||||
|
||||
- **One project per recording.**
|
||||
- **No clicks or positions replayed** — on purpose, see above.
|
||||
- **QElectroTech does not call an assistant itself.** That would mean API
|
||||
keys, network access and a choice of provider inside QElectroTech: a
|
||||
different project.
|
||||
- **macOS has not been tested.**
|
||||
|
||||
---
|
||||
|
||||
## See also
|
||||
|
||||
- **[Script buttons](script_buttons)** — where the resulting script ends up
|
||||
- **[Live mode](assistant_live_mode)** — the assistant acting in the open project
|
||||
- **[MCP server](mcp_server)** and **[Connecting an AI assistant](ai_assistants)**
|
||||
- **[JavaScript Scripting](scripting)**
|
||||
+13
@@ -244,6 +244,17 @@ from before the setting existed need nothing.
|
||||
|
||||
\* Needs `QET_ENABLE_SCRIPTING=1`.
|
||||
|
||||
> **Status: pending.** Three more groups of tools are in open pull requests,
|
||||
> each described on its own page:
|
||||
>
|
||||
> | Tools | Page | PR |
|
||||
> |---|---|---|
|
||||
> | `qet_script_api`, `qet_script_test`, `qet_script_install`, `qet_script_list`, `qet_script_read`, `qet_script_remove`, `qet_about` | [Script buttons](script_buttons#letting-an-ai-assistant-write-the-script) | [#1224](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1224) |
|
||||
> | `qet_live_status`, `qet_live_run_script`, `qet_live_run_stored`, `qet_live_command`, `qet_live_show_folio`, `qet_live_undo_last`, `qet_live_screenshot` | [Live mode](assistant_live_mode#what-the-assistant-can-do) | [#1225](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1225) |
|
||||
> | `qet_recording_list`, `qet_recording_read`, `qet_recording_check`, `qet_recording_remove` | [Macro recorder](macro_recorder#turning-it-into-a-script) | [#1228](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1228) |
|
||||
>
|
||||
> None of them works until its PR is merged.
|
||||
|
||||
---
|
||||
|
||||
## Worked examples
|
||||
@@ -460,6 +471,8 @@ regression in the thing under test, not a missing switch.
|
||||
- **[Connecting an AI assistant](ai_assistants)** — setup for each assistant
|
||||
- **[JavaScript Scripting](scripting)** — the `qet.*` engine `qet_edit` and
|
||||
`qet_query` drive underneath
|
||||
- **[Script buttons](script_buttons)**, **[Live mode](assistant_live_mode)**,
|
||||
**[Macro recorder](macro_recorder)** — the pending script, live and recording tools
|
||||
- **[The project database](project_database)** — what `qet_query` reads
|
||||
- **[CLI Reference](cli_reference)** — the export flags `qet_export` wraps
|
||||
- **[Automating QElectroTech](api_reference)** — the file-format and
|
||||
|
||||
+303
@@ -0,0 +1,303 @@
|
||||
# Script buttons
|
||||
|
||||
Keep a JavaScript script in QElectroTech, give it an icon and a shortcut, and
|
||||
run it from a button, a menu, the shortcut bar or command search — instead of
|
||||
picking the file again every time. You can write the script yourself, or let
|
||||
an AI assistant write, test and store it through the
|
||||
**[MCP server](mcp_server)**. Both end in the same place: a file in your
|
||||
scripts folder, which QElectroTech turns into a button.
|
||||
|
||||
> **Status: pending.** Nothing on this page is merged yet; the series starts
|
||||
> with [PR #1219](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1219). Each section names
|
||||
> its own pull request; check it before trying any of this against your own
|
||||
> build. The whole series:
|
||||
>
|
||||
> | PR | What it adds | Builds on |
|
||||
> |---|---|---|
|
||||
> | [#1219](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1219) | `qet.currentFolio()`, `qet.apiSignatures()`, one undo step per run | — |
|
||||
> | [#1220](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1220) | stored scripts, the *Scripts* menu and toolbar | #1219 |
|
||||
> | [#1221](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1221) | the script manager window | #1220 |
|
||||
> | [#1224](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1224) | MCP tools to write, test and store scripts | — |
|
||||
>
|
||||
> The proposal and its open questions are in
|
||||
> [discussion #1226](https://github.com/qelectrotech/qelectrotech-source-mirror/discussions/1226).
|
||||
> The same series continues with **[live mode](assistant_live_mode)** and the
|
||||
> **[macro recorder](macro_recorder)**.
|
||||
|
||||
Menu and option names are given in French, as QElectroTech shows them until
|
||||
the translations are updated, with an English gloss in italics.
|
||||
|
||||
---
|
||||
|
||||
## Why this exists
|
||||
|
||||
**[JavaScript Scripting](scripting)** already lets a script read a project,
|
||||
edit it with real undo, and export it. But from the editor, *Exécuter un
|
||||
script…* (*Run script*) asks for a file every time, and a script cannot tell
|
||||
which sheet you are looking at. So a repeated task — put a revision note on
|
||||
this sheet, renumber the selected wires, rotate the selected coils — stays a
|
||||
chore. Script buttons make a script a command like any other.
|
||||
|
||||
## Before you start: scripting must be on
|
||||
|
||||
Scripts are **off by default**
|
||||
([PR #984](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/984)).
|
||||
A script runs with your rights: it can read and change the open project and
|
||||
write files. The setting is in **Configurer QElectroTech > Général** (*Settings
|
||||
> General*): *Autoriser l'exécution de scripts JavaScript* (*Allow running
|
||||
JavaScript scripts*). If it is off, the first time you press a script button
|
||||
QElectroTech asks whether to turn it on. Nothing on this page gets around that
|
||||
switch.
|
||||
|
||||
---
|
||||
|
||||
## The scripts folder
|
||||
|
||||
> **Status: pending** — [PR #1220](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1220).
|
||||
|
||||
Each script is one `.js` file in the `scripts` folder of your QElectroTech
|
||||
data folder:
|
||||
|
||||
| System | Folder |
|
||||
|---|---|
|
||||
| Linux | `~/.local/share/QElectroTech/QElectroTech/scripts/` |
|
||||
| Windows | `%APPDATA%\QElectroTech\QElectroTech\scripts\` |
|
||||
| macOS | `~/Library/Application Support/QElectroTech/QElectroTech/scripts/` |
|
||||
|
||||
If you start QElectroTech with `--data-dir`, the folder moves with it.
|
||||
**Projet > Scripts > Ouvrir le dossier des scripts** (*Project > Scripts >
|
||||
Open the scripts folder*) opens it, creating it if needed.
|
||||
|
||||
QElectroTech watches the folder. Drop a script in and its button appears
|
||||
straight away; delete it and the button, its menu entry and its shortcut go.
|
||||
No restart, and nothing to register.
|
||||
|
||||
Scripts are yours, not the project's: nothing is added to the `.qet` file, and
|
||||
a project you receive cannot bring a script with it.
|
||||
|
||||
### The header
|
||||
|
||||
The top of the file says how the button looks. One file holds both, so there
|
||||
is nothing to keep in step and one file to share:
|
||||
|
||||
```js
|
||||
// ==QETScript==
|
||||
// @name Add revision note
|
||||
// @icon note.svg
|
||||
// @tooltip Puts a "Rev A" note on the sheet you are looking at
|
||||
// @shortcut Ctrl+Alt+R
|
||||
// @context canvas
|
||||
// @api 1
|
||||
// ==/QETScript==
|
||||
var f = qet.currentFolio();
|
||||
qet.addText(f, "Rev A", 40, 40);
|
||||
```
|
||||
|
||||
| Key | Required | Meaning |
|
||||
|---|---|---|
|
||||
| `@name` | **yes** | the button's text, and the name shown in menus, command search and the undo history |
|
||||
| `@icon` | no | a picture file next to the script (`note.svg`, `note.png`), or `builtin:<name>` for an icon from QElectroTech's theme. Left out: a tile with the name's initials |
|
||||
| `@tooltip` | no | the text shown when you hover the button |
|
||||
| `@shortcut` | no | a keyboard shortcut, written as Qt writes them (`Ctrl+Alt+R`). A shortcut you set in the shortcut settings wins over it |
|
||||
| `@context` | no | when the button is usable — see the next table. Default `canvas` |
|
||||
| `@api` | no | the header version; only `1` exists |
|
||||
|
||||
| `@context` | The button works when… |
|
||||
|---|---|
|
||||
| `canvas` | a project is open (always) |
|
||||
| `selection` | something is selected on the sheet |
|
||||
| `conductor` | at least one wire is selected |
|
||||
|
||||
Without an open project every script button is greyed out.
|
||||
|
||||
**A wrong header is refused, not ignored.** An unknown key (`@shortcutt`), a
|
||||
missing `@name`, an unknown `@context` or an `@api` other than `1` means no
|
||||
button. The file is listed greyed in **Projet > Scripts** as *Ignoré :
|
||||
broken.js: unknown header key @shortcutt* (*Ignored*), so you can see which
|
||||
line is wrong. A misspelt shortcut that silently did nothing would be harder
|
||||
to find.
|
||||
|
||||
A file name becomes the script's id: `add-revision-note.js` is
|
||||
`diagrameditor.script.add-revision-note` in the shortcut settings.
|
||||
|
||||
---
|
||||
|
||||
## Running a script
|
||||
|
||||
> **Status: pending** — [PR #1220](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1220).
|
||||
|
||||
Every stored script is an ordinary command, so you can reach it any of these
|
||||
ways:
|
||||
|
||||
| Where | How |
|
||||
|---|---|
|
||||
| **Projet > Scripts** (*Project > Scripts*) | one entry per script, with its icon |
|
||||
| the **Scripts** toolbar | one button per script. Hidden while the folder has no script, shown once the first one arrives |
|
||||
| its keyboard shortcut | `@shortcut`, or one you set in the shortcut settings |
|
||||
| the **S** shortcut bar | add it with "…" → Customise, like any command (see [Drawing faster](drawing_faster)) |
|
||||
| command search, **Ctrl+Shift+M** | type the script's name |
|
||||
|
||||
Below the scripts, the **Projet > Scripts** menu holds:
|
||||
|
||||
| Entry | Does |
|
||||
|---|---|
|
||||
| *Enregistrer une macro* (*Record a macro*) | see **[Macro recorder](macro_recorder)** (PR #1227) |
|
||||
| *Gérer les scripts…* (*Manage scripts*) | the script manager, below |
|
||||
| *Exécuter un script...* (*Run script*) | run any `.js` file once, as before — it moves here from the *Projet* menu |
|
||||
| *Ouvrir le dossier des scripts* | open the scripts folder |
|
||||
|
||||
### One click, one Ctrl+Z
|
||||
|
||||
> **Status: pending** — [PR #1219](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1219).
|
||||
|
||||
A script run from the editor is **one undo step**, named *Script : <name>*.
|
||||
A button that adds twenty items is undone with one Ctrl+Z, not twenty. This
|
||||
also applies to *Exécuter un script…*. A script that changes nothing leaves no
|
||||
empty step behind. Headless `--run` keeps one step per call, as before.
|
||||
|
||||
### Which sheet the script works on
|
||||
|
||||
> **Status: pending** — [PR #1219](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1219).
|
||||
|
||||
`qet.currentFolio()` returns the index of the sheet on screen, so a button
|
||||
acts where you are looking. Headless (`--run`, or an assistant testing a copy)
|
||||
it returns `0`, the first sheet, so the same script can be tried without a
|
||||
window. It returns `-1` if the project has no sheet.
|
||||
|
||||
---
|
||||
|
||||
## The script manager
|
||||
|
||||
> **Status: pending** — [PR #1221](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1221).
|
||||
|
||||
**Projet > Scripts > Gérer les scripts…** (*Manage scripts*) lists your
|
||||
scripts with their icons on the left, and edits the selected one on the right.
|
||||
|
||||
| Field | Header line it writes |
|
||||
|---|---|
|
||||
| *Nom :* (*Name*) | `@name` |
|
||||
| *Icône :* (*Icon*) | `@icon`. Leave it empty for the initials tile, type `builtin:<name>` for a theme icon, or click the preview to choose an SVG or PNG — the file is copied into the scripts folder |
|
||||
| *Info-bulle :* (*Tooltip*) | `@tooltip` |
|
||||
| *Raccourci :* (*Shortcut*) | `@shortcut` |
|
||||
| *Actif :* (*Active*) | `@context`: *Toujours* (*Always*), *Avec une sélection* (*With a selection*), *Avec un conducteur sélectionné* (*With a wire selected*) |
|
||||
|
||||
Below the fields is the script's text, a plain text editor.
|
||||
|
||||
| Button | Does |
|
||||
|---|---|
|
||||
| *Nouveau* (*New*) | starts a script called *Nouveau script* from a template |
|
||||
| *Enregistrer* (*Save*) | writes the file; the button appears or updates |
|
||||
| *Tester* (*Test*) | saves, then runs it on the current project. Ctrl+Z takes it back |
|
||||
| *Supprimer* (*Delete*) | asks, then deletes the file, and its icon if no other script uses it |
|
||||
| *Ouvrir le dossier* | opens the scripts folder |
|
||||
| *Fermer* (*Close*) | asks whether to save first if the script was changed |
|
||||
|
||||
A script whose header is wrong is listed with the reason (*Pas de bouton :
|
||||
…*, *No button*), and *Enregistrer* refuses to save a header that would give
|
||||
no button, with the reason under the editor.
|
||||
|
||||
The manager only writes files. The folder does the rest, so the manager, a
|
||||
text editor and an AI assistant can never disagree about what a script is.
|
||||
|
||||
---
|
||||
|
||||
## Letting an AI assistant write the script
|
||||
|
||||
> **Status: pending** — [PR #1224](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1224).
|
||||
|
||||
With the **[MCP server](mcp_server)** set up
|
||||
(**[Connecting an AI assistant](ai_assistants)**), you can ask: *"make me a
|
||||
button that puts a Rev A note on the sheet I'm looking at"*. The assistant:
|
||||
|
||||
1. reads the call list with `qet_script_api`,
|
||||
2. writes the script and tries it with `qet_script_test` — on a **copy** of
|
||||
one of your projects, which it then compares with the original, so you see
|
||||
what it would change,
|
||||
3. stores it with `qet_script_install`, optionally with an SVG icon it drew.
|
||||
|
||||
The button appears in your open QElectroTech. **The assistant never presses
|
||||
it**: you do. (To let it act on the open project, see
|
||||
**[live mode](assistant_live_mode)**.)
|
||||
|
||||
| Tool | Does | Needs `QET_ENABLE_SCRIPTING=1` |
|
||||
|---|---|---|
|
||||
| `qet_script_api` | every call a script can make, with its arguments, taken from the QElectroTech it targets | yes |
|
||||
| `qet_script_test` | runs script text on a copy of a project and returns what changed (a `qet_diff`); the project is never modified | yes |
|
||||
| `qet_script_install` | stores a script as a button: checks the header, writes `<id>.js` and optionally `<id>.svg`. Given `test_project`, it tests first and refuses a script that fails | yes |
|
||||
| `qet_script_list` | the stored scripts, with their header fields, and the files that give no button and why | no |
|
||||
| `qet_script_read` | the text and icon of one stored script | no |
|
||||
| `qet_script_remove` | deletes a stored script, and its icon if no other script uses it | yes |
|
||||
| `qet_about` | what QElectroTech last wrote about itself: its folders, whether scripting is on, its stored scripts | no |
|
||||
|
||||
`QET_ENABLE_SCRIPTING=1` goes in the environment the MCP server is started in,
|
||||
as for the editing tools (see [Scripting gate](mcp_server#scripting-gate)).
|
||||
|
||||
**Where the server puts scripts.** The server chooses the folder; a tool call
|
||||
cannot. In order: `QET_MCP_SCRIPTS_DIR` if set; else the folder QElectroTech
|
||||
named in `qet-assistant.json`; else the platform folder in the table above.
|
||||
Set `QET_MCP_SCRIPTS_DIR` if you start QElectroTech with `--data-dir` and it
|
||||
has not run since.
|
||||
|
||||
### qet-assistant.json
|
||||
|
||||
Whenever an editor window opens, and whenever the stored scripts or the
|
||||
settings change, QElectroTech writes `qet-assistant.json` in the platform data
|
||||
folder (`~/.local/share/QElectroTech/QElectroTech/` on Linux,
|
||||
`%APPDATA%\QElectroTech\QElectroTech\` on Windows) — there even when
|
||||
`--data-dir` moves everything else, so the server can always find it. It
|
||||
lists QElectroTech's version, every folder in use (data, settings, scripts,
|
||||
element and title block collections), whether scripting and live mode are on,
|
||||
every script call, the stored scripts and the ones refused, and — only while
|
||||
live mode is open — how to reach it. Only you can read it. `qet_about` shows
|
||||
it to the assistant, without the live-mode token.
|
||||
|
||||
---
|
||||
|
||||
## Worked example: a button by hand
|
||||
|
||||
1. **Projet > Scripts > Ouvrir le dossier des scripts**.
|
||||
2. Save this as `rotate-selected.js` there:
|
||||
|
||||
```js
|
||||
// ==QETScript==
|
||||
// @name Rotate selected half a turn
|
||||
// @tooltip Rotates every selected symbol on this sheet by 180°
|
||||
// @context selection
|
||||
// ==/QETScript==
|
||||
var f = qet.currentFolio();
|
||||
var uuids = qet.selectedElements(f);
|
||||
for (var i = 0; i < uuids.length; i++)
|
||||
qet.rotateElement(f, uuids[i], 180);
|
||||
qet.log("rotated " + uuids.length + " symbol(s)");
|
||||
```
|
||||
|
||||
With no `@icon`, the button shows a tile with the name's initials. Other calls are
|
||||
listed on **[JavaScript Scripting](scripting)**, and `qet.apiSignatures()`
|
||||
returns every call your QElectroTech knows.
|
||||
3. The **Scripts** toolbar appears with the new button, greyed until you
|
||||
select something.
|
||||
4. Select some symbols, click. One Ctrl+Z undoes all the rotations.
|
||||
|
||||
---
|
||||
|
||||
## Limitations
|
||||
|
||||
- **Your folder only.** No scripts per project or shared across a company yet
|
||||
(open question 3 in discussion #1226).
|
||||
- **No questions to the user.** A script cannot yet ask for a value when you
|
||||
press its button; one button does one thing.
|
||||
- **macOS has not been tested.** Linux and Windows have, including a Windows
|
||||
build run under Wine.
|
||||
- **No arbitrary menu commands from a script**, as before — see
|
||||
[JavaScript Scripting](scripting#limitations-on-purpose).
|
||||
|
||||
---
|
||||
|
||||
## See also
|
||||
|
||||
- **[JavaScript Scripting](scripting)** — every call a script can make
|
||||
- **[Live mode](assistant_live_mode)** — an assistant running scripts in the open project while you watch
|
||||
- **[Macro recorder](macro_recorder)** — do a task by hand once, and let an assistant turn it into a button
|
||||
- **[MCP server](mcp_server)** and **[Connecting an AI assistant](ai_assistants)**
|
||||
- **[Drawing faster](drawing_faster)** — the shortcut bar and command search scripts appear in
|
||||
- [Discussion #1226](https://github.com/qelectrotech/qelectrotech-source-mirror/discussions/1226) — the proposal
|
||||
+26
@@ -52,6 +52,15 @@ qelectrotech --run export_after_revision.js "$1"
|
||||
and runs the chosen script against the *currently open* project. Useful for
|
||||
one-off macros you don't want to wire into CI.
|
||||
|
||||
> **Status: pending.** [PR #1220](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1220)
|
||||
> moves this entry to **Projet → Scripts → Exécuter un script...**, and adds
|
||||
> stored scripts with their own button, icon and shortcut — see
|
||||
> **[Script buttons](script_buttons)**.
|
||||
> [PR #1219](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1219)
|
||||
> makes a run from the editor **one undo step**, named *Script : <name>*,
|
||||
> so one Ctrl+Z undoes the whole script; headless `--run` keeps one step per
|
||||
> call. Neither is merged yet.
|
||||
|
||||
---
|
||||
|
||||
## What a script can do
|
||||
@@ -245,6 +254,20 @@ Every method above is either non-blocking by construction, or — for
|
||||
`showMessage` — safe under QET's existing non-interactive mode, which is
|
||||
already on for the whole process before any headless script runs.
|
||||
|
||||
### Which sheet is on screen, and what calls exist
|
||||
|
||||
> **Status: pending** — [PR #1219](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1219), not yet merged.
|
||||
|
||||
```js
|
||||
var f = qet.currentFolio() // index of the sheet on screen; 0 headless; -1 if the project has none
|
||||
qet.apiSignatures() // every call this build offers, with its arguments
|
||||
```
|
||||
|
||||
`currentFolio()` lets a script act where the user is looking, which a
|
||||
[script button](script_buttons) needs. `apiSignatures()` comes from the
|
||||
running build itself, so a list made from it (as the MCP server's
|
||||
`qet_script_api` does) cannot drift from what the build really has.
|
||||
|
||||
### Logging
|
||||
|
||||
```js
|
||||
@@ -353,5 +376,8 @@ change of mind shows up in one obvious place:
|
||||
- **[Automating QElectroTech](api_reference)** — the file-format and headless
|
||||
export ground this builds on
|
||||
- **[MCP server](mcp_server)** — an AI assistant driving this engine through `qet_edit`/`qet_query`
|
||||
- **[Script buttons](script_buttons)** — store a script and run it from a button _(pending, [PR #1220](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1220))_
|
||||
- **[Live mode](assistant_live_mode)** — an assistant running scripts in the open project _(pending, [PR #1222](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1222))_
|
||||
- **[Macro recorder](macro_recorder)** — record a task by hand for an assistant to script _(pending, [PR #1227](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1227))_
|
||||
- [PR #891](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/891) — implementation, with the exact tests run against it
|
||||
- [Issue #162](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/162) — the original request and design discussion
|
||||
|
||||
Reference in New Issue
Block a user