Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,25 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version-file: webview/.nvmrc
cache: npm
cache-dependency-path: webview/package-lock.json
- name: Setup Python Env
uses: ./.github/actions/setup-python-env
with:
uv-extra-groups: ci
- name: Install frontend dependencies
run: npm ci --prefix webview
- name: Check frontend quality
run: |
npm --prefix webview run typecheck
npm --prefix webview run lint
npm --prefix webview run format:check
npm --prefix webview test
npm --prefix webview run build
- name: Check formatting
run: |
source .venv/bin/activate
Expand All @@ -39,10 +54,26 @@ jobs:
steps:
- name: Check out Git repository
uses: actions/checkout@v7
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version-file: webview/.nvmrc
cache: npm
cache-dependency-path: webview/package-lock.json
- name: Setup Python Env
uses: ./.github/actions/setup-python-env
with:
uv-extra-groups: ci
- name: Install frontend dependencies
run: npm ci --prefix webview
- name: Build frontend assets
run: npm --prefix webview run build
- name: Install browser for end-to-end tests
run: npm --prefix webview run playwright:install
- name: Run browser tests
run: npm --prefix webview run test:e2e
- name: Build Python distributions
run: uv build
- name: Run tests
run: |
source .venv/bin/activate
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
exclude: ^proflow/tests/snapshots/|^experiments/
exclude: ^proflow/tests/snapshots/|^experiments/|(^|/)(package\.json|pnpm-lock\.yaml|tsconfig\.json)$


repos:
Expand Down
5 changes: 5 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,8 @@ When responding, explicitly confirm completion of each requirement.
## Testing

- Use `.venv/bin/python -m pytest` for running all tests in the project.

## Webview specific instructions

- Use nvm to manage Node.js versions for the webview project.
- Use pnpm to manage project dependencies for the webview project.
183 changes: 183 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,188 @@
# Changelog

## 2026-11-05

- Date: 2026-11-05
- Summary: Restore graph zoom and pan controls in the relocated webview frontend.
- Added:
- Mouse/touch zoom, canvas panning, bounded zoom controls, and a reset button.
- Changed:
- Graph content shares an SVG transform while controls remain fixed and node
dragging continues to work when zoomed.
- Fixed:
- Restored navigation behavior lost during the frontend directory refactor.
- Docs:
- Documented navigation controls
- Tests:
- Frontend typecheck, unit tests, and zoom/pan browser coverage passed.
- Lint/Format:
- Passed ESLint and Prettier checks.
- Credits: Copilot SDK in VS Code.

## 2026-11-04

- Date: 2026-11-04
- Summary: Isolate the process graph webview in a compiled Node package.
- Added:
- A private TypeScript/Vite ES-module frontend package with a locked npm
dependency tree.
- Vitest unit tests, Playwright browser tests, and Flask route/distribution
tests.
- Changed:
- The Flask host now serves compiled frontend assets while continuing to
provide graph data through `/data`.
- CI runs frontend checks and verifies compiled assets in Python
distributions.
- Fixed:
- Frontend graph requests and invalid graph responses now surface accessible
errors instead of failing silently.
- Docs:
- Documented frontend development, tests, build output, and Python runtime
boundaries.
- Tests:
- 123 Python tests passed and 7 were skipped; 9 Vitest unit tests and 3
Playwright browser tests passed.
- Verified compiled frontend assets are present in both wheel and source
distributions.
- Lint/Format:
- Passed ESLint, Prettier, Ruff lint, and Ruff formatting checks.
- Credits: Copilot SDK in VS Code.

## 2026-11-04

- Date: 2026-11-04
- Summary: Add zooming and panning to the analysis web view.
- Added:
- Mouse/touch zoom, canvas panning, and accessible zoom-in, zoom-out, and
reset buttons.
- Changed:
- Graph elements share a transformed SVG group while controls stay fixed.
- Fixed:
- None.
- Docs:
- Documented graph navigation controls and gestures in the analysis guide.
- Tests:
- Browser-verified button and wheel zoom, zoom bounds, reset, canvas panning,
and stationary controls.
- Lint/Format:
- Not applicable to JavaScript, CSS, and Markdown changes.
- Credits: Copilot SDK in VS Code.

## 2026-11-04

- Date: 2026-11-04
- Summary: Add a control-panel toggle for the graph forces.
- Added:
- An accessible checkbox to pause and resume the force-directed layout.
- Changed:
- The control-panel heading now describes the graph controls.
- Dragging nodes while forces are off moves them without restarting the
simulation.
- Fixed:
- None.
- Docs:
- Documented the force toggle in the process analysis guide.
- Tests:
- Verified force simulation pause/resume and node dragging in the browser.
- Lint/Format:
- Passed the configured pre-commit checks.
- Credits: Copilot SDK in VS Code.

## 2026-11-04

- Date: 2026-11-04
- Summary: Render web-view links as perpendicular Bézier curves.
- Added:
- Cubic Bézier paths for process-network links.
- Changed:
- Box links leave the source's right edge and meet the target's left edge
horizontally.
- Fixed:
- Link paths no longer meet box edges at an angle.
- Docs:
- Documented perpendicular Bézier links in the process analysis guide.
- Tests:
- Verified rendered box-link endpoints and horizontal endpoint tangents in the browser.
- Lint/Format:
- Not applicable to JavaScript and Markdown changes.
- Credits: Copilot SDK in VS Code.

## 2026-11-04

- Date: 2026-11-04
- Summary: Keep node labels visible above their shapes in the web view.
- Added:
- None.
- Changed:
- Node shapes are inserted before labels in SVG rendering order.
- Fixed:
- Rectangle nodes no longer cover their labels.
- Docs:
- Clarified that labels remain visible in both node-shape modes.
- Tests:
- Verified node SVG stacking and visible labels in the browser.
- Lint/Format:
- Not applicable to JavaScript and Markdown changes.
- Credits: Copilot SDK in VS Code.

## 2026-11-03

- Date: 2026-11-03
- Summary: Add a control-panel switch for box and dot graph nodes.
- Added:
- Accessible radio controls for selecting the node shape.
- Changed:
- The graph redraws node shapes, labels, and link endpoints when the selection
changes.
- Fixed:
- None.
- Docs:
- Documented the node-shape switch in the process analysis guide.
- Tests:
- Verified switching between boxes and dots, plus their link endpoints, in
the browser.
- Lint/Format:
- Not applicable to JavaScript, CSS, and Markdown changes.
- Credits: Copilot SDK in VS Code.

## 2026-11-03

- Date: 2026-11-03
- Summary: Render web-view process nodes as boxes with directional edge ports.
- Added:
- Rectangular process nodes with centered labels.
- Changed:
- Incoming links connect to the left side of a node and outgoing links leave
from its right side.
- Fixed:
- None.
- Docs:
- Documented the box and edge direction in the process analysis guide.
- Tests:
- Verified rendered node shapes and directional link endpoints in the browser.
- Lint/Format:
- Not applicable to JavaScript, CSS, and Markdown changes.
- Credits: Copilot SDK in VS Code.

## 2026-11-03

- Date: 2026-11-03
- Summary: Add node search controls to the process network web view.
- Added:
- An accessible node search panel with a live count of visible nodes.
- Changed:
- The web view hides nonmatching nodes and links connected to hidden nodes.
- Fixed:
- None.
- Docs:
- Documented how to run the web view and use its node filter.
- Tests:
- Verified case-insensitive name matching, ID matching, edge filtering, and clearing the search in the browser.
- Project tests passed: 116 passed, 7 skipped.
- Lint/Format:
- Ruff checks and formatting checks passed for the related Python modules.
- Credits: Copilot SDK in VS Code.

## 2026-11-03

- Date: 2026-11-03
Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ inputs and outputs connect to the surrounding data:
`I(value, as_="argument_name")` entries; the `as_` value becomes the
corresponding keyword argument to the function.
- **Outputs** are provided by `state_outputs`. The callable receives the
function result and returns `(value, "target.path")` pairs to write into
state.
function result and returns `(value, "target.path")` pairs to write int state.
- **Other input sources** include `config_inputs`, `parameters_inputs`,
`external_state_inputs`, and `additional_inputs`.
- **Process options** include `gate` to skip a process, `comment` and `group`
Expand Down Expand Up @@ -114,3 +113,11 @@ ruff format . --check
## License

proFlow is distributed under the terms of the [MIT License](./LICENSE).

## Build and Publish

The publish workflow builds the distributions and publishes them to PyPI using trusted publishing.

Use `build_and_deploy.sh patch|minor|major` to bump the version and trigger the publish workflow.

Configure a PyPI trusted publisher for this GitHub repository with workflow filename `publish.yml` and environment `pypi` before pushing the tag. No PyPI API token is needed.
67 changes: 67 additions & 0 deletions proflow/analysis/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,73 @@ though an `Edge` record's `source` field identifies the consumer and its
(`target == -1`) are omitted from the exported graph. The function returns
the same node-link data it writes.

## Explore a network in the web view

The optional Flask web view displays the process network as an interactive
force-directed graph. Install Flask if needed, then run it from the project root:

```bash
python -m pip install flask
python -m proflow.analysis.webview.run_app
```

Open the printed local URL and use the **Search nodes** field to match node IDs,
function names, or process descriptions without regard to case. The graph hides
nonmatching nodes and links that connect to hidden nodes; clearing the search
restores the full network. Use **Enable forces** to pause or resume the
force-directed layout, and **Node shape** to switch between labeled boxes (the
default) and dots. Dragging nodes remains available while forces are paused.
Use the mouse wheel or a touch gesture to zoom, and drag empty canvas to pan.
The **Zoom in**, **Zoom out**, and **Reset** buttons provide equivalent controls;
reset returns to the original view. Zoom is bounded so the graph cannot become
arbitrarily small or large. Panning and zooming do not interfere with dragging
nodes.
In box mode, incoming links connect to the left edge and outgoing links leave
the right edge, with cubic Bézier curves that leave and meet the boxes
perpendicularly. Node labels remain visible in both modes.

### Develop the webview frontend

The frontend is a private Node ES-module package in
[`proflow_webview`](../../proflow_webview).
It uses TypeScript for strict type checking, Vite to build, Vitest for unit
tests, and Playwright for browser tests. The Python package serves the compiled
assets and provides graph data at `/data`; Node is needed only to develop and
build the frontend, not to run an installed Python package.

Use Node 22 or newer and install frontend dependencies from the repository root:

```bash
pnpm --dir proflow_webview install --frozen-lockfile
```

For frontend development, start the Flask server in one terminal and Vite in
another. Vite proxies `/data` to the Flask server on port 8000:

```bash
uv sync --locked --group web
uv run --locked python -m proflow.analysis.webview.run_app
pnpm --dir proflow_webview dev
```

Run the frontend checks and build compiled assets for the Flask server:

```bash
pnpm --dir proflow_webview typecheck
pnpm --dir proflow_webview lint
pnpm --dir proflow_webview format:check
pnpm --dir proflow_webview test
pnpm --dir proflow_webview build
```

The build output is stored in
`proflow/analysis/webview/static/force/frontend-dist` and included in Python
source and binary distributions. The Playwright suite starts the Flask server
automatically; install Chromium first with
`pnpm --dir proflow_webview playwright:install`, then run
`pnpm --dir proflow_webview test:e2e`. Python route tests are included in the
project pytest suite.

## Dependencies

The canvas workflow requires `ipycanvas`. JSON export requires `networkx`.
Expand Down
37 changes: 37 additions & 0 deletions proflow/analysis/export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""Export process analysis results to the force webview JSON format."""

from dataclasses import asdict

from proflow.analysis.network.extract_nodes_and_edges import Edge, Node


def processes_to_json(
nodes_and_edges: tuple[list[Node], list[Edge]],
) -> dict[str, object]:
"""Write process nodes and edges as force webview node-link JSON.

The returned graph data is also written to ``output_file``. Unresolved
edges, whose ``target`` is ``-1``, are omitted from the links.
"""
nodes, edges = nodes_and_edges
graph_data: dict[str, object] = {
"directed": True,
"multigraph": True,
"graph": {},
"nodes": [{**asdict(node), "id": node.index} for node in nodes],
"links": [
{
"source": edge.target,
"target": edge.source,
"name": edge.name,
"key": 0,
"id": link_id,
}
for link_id, edge in enumerate(
(edge for edge in edges if edge.target != -1),
start=1,
)
],
}

return graph_data
2 changes: 1 addition & 1 deletion proflow/analysis/network/extract_nodes_and_edges_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from proflow.tests.demodata import DEMO_PROCESSES
from proflow.tests.mock_data import DEMO_PROCESSES

from .extract_nodes_and_edges import (
Edge,
Expand Down
Loading
Loading