Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
230d962
fix(transpiler): sync WS1 pin-typing surface from web
dcoutinho1328 Jun 17, 2026
6aa335b
feat(transpiler): run both engines and log output comparison
dcoutinho1328 Jun 17, 2026
7581d2b
feat(transpiler): library-agnostic block resolution from project vari…
dcoutinho1328 Jun 17, 2026
a9e5234
refactor(transpiler): retire xml2st, make in-process TS transpiler so…
dcoutinho1328 Jun 23, 2026
c82dbda
fix(transpiler): drop redundant body-value casts in pou-graphical (lint)
dcoutinho1328 Jun 23, 2026
6d2db22
style: prettier-format editor-compiler-platform-port (format check)
dcoutinho1328 Jun 23, 2026
0eca061
Merge remote-tracking branch 'origin/development' into fix/parity/ws1…
dcoutinho1328 Jun 24, 2026
bcf0f2a
fix(transpiler): LD coil grouping (#836) + chained-block output order…
dcoutinho1328 Jun 25, 2026
78862ac
fix(compiler): close debug port on ST write failure; drop needless async
dcoutinho1328 Jun 25, 2026
9d420a0
Merge remote-tracking branch 'origin/development' into fix/parity/ws1…
dcoutinho1328 Jun 25, 2026
ed0fe8c
feat(softmotion): CiA 402 SoftMotion axis support (mirror of openplc-…
thiagoralves Jul 6, 2026
f4a9349
fix: keep sidebar size on context switch and hide stray activity-bar …
JoaoGSP Jul 6, 2026
4dab805
Merge pull request #929 from Autonomy-Logic/fix/switch-context-visual…
JoaoGSP Jul 6, 2026
ec9ef06
fix: eliminate phantom source-control diffs in graphical editors
JoaoGSP Jul 7, 2026
13465ba
style: apply prettier formatting
JoaoGSP Jul 7, 2026
365e099
fix: address CodeRabbit review findings
JoaoGSP Jul 7, 2026
92fd6cd
Merge pull request #930 from Autonomy-Logic/fix/graphical-languages-s…
JoaoGSP Jul 7, 2026
7752bd2
fix: prevent located interface-class variables from corrupting POU va…
JoaoGSP Jul 8, 2026
97540fe
fix: load picked project after unsaved-changes prompt in File -> Open
JoaoGSP Jul 8, 2026
0646fb0
fix: deliver preserved variable text to the auto-opened POU's code view
JoaoGSP Jul 8, 2026
63fb449
Merge pull request #931 from Autonomy-Logic/fix/DOPE-447
JoaoGSP Jul 8, 2026
c3522bc
fix: clear stale fallback variablesText when code view is committed
JoaoGSP Jul 8, 2026
6b9dc6a
Merge branch 'development' into fix/DOPE-445-issue-904
JoaoGSP Jul 8, 2026
c749388
Merge pull request #932 from Autonomy-Logic/fix/DOPE-445-issue-904
JoaoGSP Jul 8, 2026
6a28927
feat(softmotion): device-tree icon + CiA 402 axis config screen (mirr…
thiagoralves Jul 10, 2026
2eca634
fix(softmotion): axis rename, valid names, simplified axis tab, hide …
thiagoralves Jul 10, 2026
c2aa65e
feat(softmotion): ST LSP recognizes generated axis globals (mirror of…
thiagoralves Jul 10, 2026
5a6c023
refactor(softmotion): axis as ambient global for the LSP; no VAR_EXTE…
thiagoralves Jul 14, 2026
26d4894
fix(lsp): sync resource globals so user VAR_EXTERNAL declarations res…
thiagoralves Jul 14, 2026
cfb045a
perf(graphical-editor): migrate to narrow zustand selectors (DOPE-487)
JoaoGSP Jul 14, 2026
fda6964
Merge pull request #935 from Autonomy-Logic/fix/dope-487-narrow-store…
JoaoGSP Jul 15, 2026
cc34abe
fix(debugger): resolve VAR_EXTERNAL globals to one canonical watch
thiagoralves Jul 16, 2026
538e087
Merge remote-tracking branch 'origin/development' into feat/plcopen-s…
thiagoralves Jul 16, 2026
431c7bf
chore(release): bump strucpp to v0.6.0
thiagoralves Jul 16, 2026
8fdb4f6
Merge pull request #928 from Autonomy-Logic/feat/plcopen-softmotion
thiagoralves Jul 16, 2026
678c414
perf(graphical-editor): memoize node components and stabilize ReactFl…
JoaoGSP Jul 16, 2026
4719f80
Merge remote-tracking branch 'origin/development' into fix/dope-488-m…
JoaoGSP Jul 16, 2026
acf9fd5
fix(architecture): document backend-shared exception for SoftMotion a…
dcoutinho1328 Jul 16, 2026
4c1f750
Merge remote-tracking branch 'origin/development' into fix/dope-488-m…
JoaoGSP Jul 16, 2026
68f2c04
Merge pull request #938 from Autonomy-Logic/fix/dope-488-memoize-grap…
JoaoGSP Jul 17, 2026
04fcf18
fix(naming): validate element names as IEC identifiers + robust basen…
thiagoralves Jul 17, 2026
ae1e53c
fix(project): persist structural changes only on save (unify web + de…
thiagoralves Jul 17, 2026
cab951e
Merge pull request #939 from Autonomy-Logic/fix/element-name-validation
thiagoralves Jul 17, 2026
a8a14e7
Merge remote-tracking branch 'origin/development' into fix/unify-pers…
thiagoralves Jul 17, 2026
2081469
Merge pull request #940 from Autonomy-Logic/fix/unify-persist-on-save
thiagoralves Jul 17, 2026
c812081
feat: web unsaved-changes beforeunload guard (shared accelerator-hand…
thiagoralves Jul 17, 2026
3aa662b
perf(graphical-editor): scope ladder selection to the affected rung (…
JoaoGSP Jul 17, 2026
8b7dfbf
Merge remote-tracking branch 'origin/development' into fix/dope-489-s…
JoaoGSP Jul 17, 2026
db08561
Merge pull request #942 from Autonomy-Logic/fix/dope-489-scope-ladder…
JoaoGSP Jul 17, 2026
d945aa9
Merge pull request #941 from Autonomy-Logic/fix/web-exit-guard
thiagoralves Jul 20, 2026
5f9b636
fix(hardware): informative serial-port names + macOS cu. canonicaliza…
thiagoralves Jul 20, 2026
72adc40
chore: repo setup for Claude workflows and doc cleanup (#913)
dcoutinho1328 Jul 20, 2026
c577fa7
feat(plcopen): PLCopen XML import parser + import/export UI (NODE-111…
dcoutinho1328 Jul 21, 2026
3d71e58
Merge remote-tracking branch 'origin/development' into fix/parity/ws1…
dcoutinho1328 Jul 21, 2026
b3b7d7c
perf(graphical-editor): remove edit hot-path deep clones + debounce f…
JoaoGSP Jul 21, 2026
5580cb9
Merge remote-tracking branch 'origin/development' into fix/dope-490-e…
JoaoGSP Jul 21, 2026
a4fd376
fix(review): mirror web PR #528 review fixes (shared surface sync)
dcoutinho1328 Jul 21, 2026
5ebab22
style: prettier line-wrap in flow-writeback.ts
JoaoGSP Jul 21, 2026
f778c3a
Merge pull request #885 from Autonomy-Logic/fix/parity/ws1-corpus-div…
dcoutinho1328 Jul 21, 2026
3a71699
Merge remote-tracking branch 'origin/development' into fix/dope-490-e…
JoaoGSP Jul 21, 2026
417158d
Merge pull request #948 from Autonomy-Logic/fix/dope-490-edit-hot-pat…
JoaoGSP Jul 21, 2026
4eda412
perf(graphical-editor): scope per-edit scans + batch hot-path store w…
JoaoGSP Jul 21, 2026
01b84a3
test: strengthen FBD updateNodes dirty-state assertions + cover use-c…
JoaoGSP Jul 21, 2026
634ae95
Merge pull request #949 from Autonomy-Logic/fix/dope-491-hot-path-scans
JoaoGSP Jul 21, 2026
e48914d
fix(graphical): dotted refs as constants + resolve globals/struct-mem…
thiagoralves Jul 22, 2026
a41c8d8
chore: remove xml2st references + fix autocomplete box sizing (#951)
thiagoralves Jul 22, 2026
9e6e025
fix(resources): cascade-delete global variable used as VAR_EXTERNAL (…
thiagoralves Jul 22, 2026
53e01f2
feat: runtime User Management screen with RBAC
thiagoralves Jul 22, 2026
a271795
fix(lsp): resolve connection and message types from one vscode-jsonrp…
JoaoGSP Jul 23, 2026
66f91db
Merge remote-tracking branch 'origin/development' into HEAD
JoaoGSP Jul 23, 2026
237e496
Merge pull request #956 from Autonomy-Logic/bugfix/dope-505-lsp-jsonr…
JoaoGSP Jul 23, 2026
d891c29
chore(deps): upgrade @xyflow/react 12.0.1 -> 12.11.2 (DOPE-492)
JoaoGSP Jul 23, 2026
7e193ad
style(fbd): wrap onNodeDragStop callback per prettier
JoaoGSP Jul 23, 2026
7ace8eb
Merge pull request #957 from Autonomy-Logic/chore/dope-492-reactflow-…
JoaoGSP Jul 23, 2026
68b3021
fix(user-management): connect after first user, version gate, UX fixes
thiagoralves Jul 23, 2026
66db0d8
fix(user-management): keep connection after first-user creation
thiagoralves Jul 23, 2026
8cc96f6
fix(user-management): center New User button + no crash when logged out
thiagoralves Jul 23, 2026
f482aad
fix(user-management): use the Users icon on the tab (not the IL default)
thiagoralves Jul 23, 2026
a284c9e
Merge remote-tracking branch 'origin/development' into feature/user-m…
thiagoralves Jul 23, 2026
526e470
style: prettier formatting for user-management screen + ipc main
thiagoralves Jul 23, 2026
2e134a8
Merge pull request #953 from Autonomy-Logic/feature/user-management
thiagoralves Jul 24, 2026
217cf12
chore(release): bump version to 4.2.9
thiagoralves Jul 24, 2026
54c914c
Merge pull request #959 from Autonomy-Logic/chore/app-version-4.2.9
thiagoralves Jul 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .claude/review-guidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Review Guidelines

Order of concern: correctness, architecture, tests, style.

- Layer dependencies respect ports and adapters: frontend, backend, and middleware only communicate through the ports in `src/middleware/shared/ports/`. `npm run validate:arch` must pass.
- DTOs cross layer boundaries, never domain entities.
- 100%-coverage directories stay at 100%; new behavior comes with tests (Jest for logic, Playwright for user flows).
- TypeScript Best Practices in CLAUDE.md apply to every diff (no `any`, no `as`, no `!`, no floating promises, boundary validation over casting).
- Named exports over default exports.
- No emojis in code, comments, or docs.
- Docs updated when documented behavior changes (README, CLAUDE.md, docs/).
19 changes: 19 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"permissions": {
"allow": [
"Bash(npm run:*)",
"Bash(npm test:*)",
"Bash(npx tsx:*)",
"Bash(npx playwright test:*)",
"Bash(git status:*)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(git show:*)",
"Bash(git branch:*)",
"Bash(gh pr view:*)",
"Bash(gh pr list:*)",
"Bash(gh issue view:*)",
"Bash(gh issue list:*)"
]
}
}
6 changes: 0 additions & 6 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,6 @@ else
echo " WARNING: matiec binary not found at $BIN_DIR/iec2c"
fi

if [ -f "$BIN_DIR/xml2st" ]; then
echo " xml2st binary ($NODE_ARCH): OK"
else
echo " WARNING: xml2st binary not found at $BIN_DIR/xml2st"
fi

# Fix Electron sandbox for container (chrome-sandbox needs SUID root + mode 4755)
CHROME_SANDBOX="node_modules/electron/dist/chrome-sandbox"
if [ -f "$CHROME_SANDBOX" ]; then
Expand Down
1 change: 0 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@
# Identification for binary files used as compilers/transpilers
##########################
iec2c binary
xml2st binary
resources/bin/**/* binary
2 changes: 1 addition & 1 deletion .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Install dependencies
run: npm ci --ignore-scripts

- name: Download strucpp + xml2st binaries
- name: Download strucpp binaries
# tsc needs the strucpp package to resolve the types imported
# from `backend/shared/library/strucpp-runtime.ts` and friends.
# Run the binary downloader directly (skipping the rest of
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
# --ignore-scripts skips the postinstall, so strucpp (a GitHub-release
# package, not an npm dep) is never fetched — yet the TS sources import
# `strucpp/libs/iec-types.json` and its runtime headers. Install just
# strucpp (no xml2st platform binary, no native rebuild) so the suites
# strucpp (no native rebuild) so the suites
# can load and the coverage gate actually runs.
- name: Install strucpp
run: npm run setup:strucpp
Expand Down
44 changes: 35 additions & 9 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ src/
├── main/ # Electron main process (Node.js)
├── frontend/ # React UI layer (renderer process)
│ ├── components/ # Atomic Design: _atoms, _molecules, _organisms, _features, _templates
│ ├── store/ # Zustand store (19 slices)
│ ├── store/ # Zustand store (18 slices)
│ ├── hooks/ # Custom React hooks
│ ├── services/ # Business logic and side effects
│ ├── utils/ # Domain utilities (PLC, graphical, debug, formatters)
│ ├── data/ # Static data (function libraries, block definitions)
│ ├── locales/ # i18next translations
│ └── assets/ # Images, icons
├── backend/
│ ├── editor/ # Main process modules (compiler, hardware, modbus, websocket, services)
│ ├── editor/ # Main process modules (compiler, hardware, modbus, ethercat, library-manager, services)
│ └── shared/ # Platform-agnostic utilities (XML generation, project parsing, simulator)
├── middleware/ # Ports & Adapters layer
│ ├── shared/
Expand Down Expand Up @@ -131,7 +131,7 @@ Main and renderer processes communicate through typed IPC bridges:

### State Management (Zustand)

Single store composed of 19 slices (`src/frontend/store/`), accessed via auto-generated selector hooks:
Single store composed of 18 slices (`src/frontend/store/`), accessed via auto-generated selector hooks:

```typescript
import { useOpenPLCStore } from '@root/frontend/store'
Expand Down Expand Up @@ -160,7 +160,7 @@ const createPou = useOpenPLCStore((s) => s.projectActions.createPou)
| `console` | Log output |
| `library` | System + user function block libraries |
| `file` | File save states (dirty tracking) |
| `ai`, `clipboard`, `history`, `modal`, `search`, `shared`, `version-control`, `webrtc` | Supporting features |
| `ai`, `history`, `modal`, `readme`, `search`, `shared`, `version-control`, `webrtc` | Supporting features |

**Conventions:**
- Actions are grouped under a `*Actions` namespace (e.g., `projectActions`, `deviceActions`)
Expand Down Expand Up @@ -205,14 +205,19 @@ Flow state is stored per-POU in dedicated slices (`ladder`, `fbd`). Flows must b
Orchestrated by `CompilerModule` (`src/backend/editor/compiler/compiler-module.ts`):

```
PLCProjectData -> Preprocess POUs -> XML Generation -> xml2st -> iec2c -> C code
PLCProjectData -> Preprocess POUs -> ST transpiler (in-process) -> strucpp -> C++ code
|
defines.h (pins, Modbus, MD5)
|
Arduino CLI / openplc-compiler -> firmware
```

Platform-specific binaries in `/resources/bin/[platform]/[arch]/`. Board configs in `/resources/sources/boards/hals.json`.
Structured Text is generated in-process by the TS transpiler
(`src/backend/shared/transpilers/st-transpiler/`) on both editor and web — the
legacy `xml2st` binary path has been retired. `XmlGenerator` is kept only for
the "Export Project as XML" feature.

Platform-specific binaries in `/resources/bin/[platform]/[arch]/`. Board configs in `src/backend/shared/firmware/hals.json`.

### Debugging

Expand Down Expand Up @@ -241,9 +246,22 @@ When adding new code to covered directories, you must add corresponding tests to
- ESLint flat config (`eslint.config.mjs`) with TypeScript strict type checking
- Prettier: 120 char width, no semicolons, single quotes, trailing commas
- Import sorting enforced via `simple-import-sort` plugin
- Pre-commit hooks via Husky run lint-staged on `./src/**/*`
- Pre-commit hooks via Husky run lint-staged on `./src/**/*.{ts,tsx}`
- Path alias: `@root/*` -> `./src/*`

### TypeScript Best Practices

- No type assertions: `as` hides real type errors — fix the type at the source or narrow with type guards. `as const` is fine; `as unknown as T` is forbidden.
- No non-null assertions (`!`): handle the undefined case or narrow explicitly.
- For truly unknown data use `unknown` and narrow before use — never `any`.
- No `@ts-ignore`/`@ts-expect-error` without a one-line justification.
- Validate external data at the boundary (IPC payloads, project files, downloaded binaries metadata) with schemas (zod) or type guards instead of casting.
- No floating promises: `await` or handle rejection explicitly — async errors must not disappear.
- Prefer `??` over `||` for defaults when `0`, `''`, or `false` are valid values.
- Model variant states as discriminated unions; make `switch` exhaustive with a `never` check.
- Named exports over default exports.
- Zustand state changes only through slice actions — never mutate store values from components.

## Key Technologies

- **Electron 35** / **React 18** / **TypeScript** (target ES2022)
Expand Down Expand Up @@ -311,7 +329,7 @@ on its `main` push. (Ideally `package.json.version` should be derived from

### IEC address allocation + alias registry

Located in `src/backend/shared/utils/iec-address/` (byte-identical on
Located in `src/middleware/shared/utils/iec-address/` (byte-identical on
openplc-web). Pure functions, no IPC, no electron coupling.

- **Address pool** (`address-pool.ts`): producer-only, target-scoped
Expand Down Expand Up @@ -353,7 +371,15 @@ new alias.

## Environment

- **Node.js:** >= 20.x < 24
- **Node.js:** >= 22.x < 24
- **Dev server port:** 1313
- **Supported platforms:** macOS, Windows, Linux (x64 & ARM64)
- **Binaries:** Auto-downloaded via `scripts/download-binaries.ts` during `npm install`

## Git Workflow

Follow the Workflow section in CONTRIBUTING.md (base branch, branch naming, Conventional Commits). `<type>` maps from the Jira issue type: Story → `feature`, Bug → `bugfix`, Task → `task`, Improvement → `improvement`.

## Issue Tracker

Jira, project key `DOPE`. Fetch and update tickets via the Atlassian MCP tools. Reference the ticket key (`DOPE-<n>`) in branch names and PR descriptions. GitHub Issues (`.github/ISSUE_TEMPLATE/`) receives external bug reports; planned work lives in Jira.
35 changes: 35 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Contributing

## Setup

Requires Node.js >= 22 < 24. See README.md for the full step by step.

```bash
npm install
npm run dev # dev server on port 1313
```

## Workflow

1. Internal work is tracked in Jira, project DOPE (internal tracker). External contributors: open a GitHub issue using the provided templates.
2. Branch from `development`, named `<type>/DOPE-<n>-<kebab-slug>` (`<type>`: feature, bugfix, task, improvement). Maintenance without a ticket uses `chore/`, `ci/`, `docs/`. External contributors without Jira access: use the GitHub issue number instead (`<type>/gh-<n>-<kebab-slug>`); a maintainer files the DOPE ticket when needed.
3. Commit style: Conventional Commits, concise, focused on why.
4. Open a PR targeting `development` and fill in the PR template.

## Before pushing

```bash
npm run test # unit tests (Jest, with coverage)
npm run test:e2e # end-to-end (Playwright, requires a build)
npm run validate:arch # architecture layer dependencies
```

Lint and format run on commit via Husky.

## Docs

If your change alters documented behavior (commands, endpoints, env vars, architecture, setup steps), update the affected docs (README, CLAUDE.md, docs/) in the same PR.

## Review

PRs are reviewed against `.claude/review-guidelines.md`.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ In order to run the development version, clone the repository, and install depen
You'll need the following tools:

- [Git](https://git-scm.com/)
- [NodeJS](https://nodejs.org/en/download/), version `>=20 <24`
- [NodeJS](https://nodejs.org/en/download/), version `>=22 <24`

### Step by step

Expand All @@ -38,6 +38,14 @@ npm install
npm run dev
```

### Running tests

```bash
npm run test # Unit tests (Jest, with coverage)
npm run test:watch # Unit tests in watch mode (no coverage)
npm run test:e2e # End-to-end tests (Playwright, builds the app first)
```

## Releasing a New Version

The project uses GitHub Actions to automatically build and release new versions for all supported platforms (macOS, Windows, and Linux) in both x64 and ARM64 architectures.
Expand Down
6 changes: 1 addition & 5 deletions binary-versions.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
{
"xml2st": {
"version": "v4.0.7",
"repository": "Autonomy-Logic/xml2st"
},
"strucpp": {
"version": "v0.5.13",
"version": "v0.6.0",
"repository": "Autonomy-Logic/STruCpp"
}
}
12 changes: 6 additions & 6 deletions docs/debugger-scalability-analysis.md
Original file line number Diff line number Diff line change
Expand Up @@ -1193,9 +1193,9 @@ Implement **Strategy F** (lazy registration) only if needed for extreme-scale pr
### openplc-editor
| File | Changes |
|------|---------|
| `src/main/modules/compiler/compiler-module.ts` | Pass target platform to xml2st |
| `src/utils/debug-parser.ts` | Support JSON manifest parsing |
| `src/renderer/utils/debugger-session.ts` | Array index handling, protocol v2 |
| `src/main/modules/modbus/modbus-client.ts` | Array element request method |
| `src/main/modules/websocket/websocket-debug-client.ts` | Array element request method |
| `src/renderer/screens/workspace-screen.tsx` | Array polling in debug loop |
| `src/backend/editor/compiler/compiler-module.ts` | Pass target platform to xml2st |
| `src/frontend/utils/debug-parser.ts` | Support JSON manifest parsing |
| `src/frontend/utils/debugger-session.ts` | Array index handling, protocol v2 |
| `src/backend/editor/modbus/modbus-client.ts` | Array element request method |
| `src/backend/shared/debug/websocket-debug-transport.ts` | Array element request method |
| `src/frontend/screens/workspace-screen.tsx` | Array polling in debug loop |
Loading
Loading