Skip to content

feat: add dev-mode hot reload, dev-stack orchestrator, and contributo…#739

Open
ObservedObserver wants to merge 1 commit into
mainfrom
improve-dev-experience
Open

feat: add dev-mode hot reload, dev-stack orchestrator, and contributo…#739
ObservedObserver wants to merge 1 commit into
mainfrom
improve-dev-experience

Conversation

@ObservedObserver

Copy link
Copy Markdown
Member

…r/agent docs

Improve the local developer experience for both humans and coding agents.

Dev mode (opt-in, production unchanged):

  • anywidget widget loads pygwalker-app.es.js from disk as a pathlib.Path when PYGWALKER_DEV=1 or ANYWIDGET_HMR=1, so anywidget hot-reloads it live in the notebook. With the flags unset, the bundled ESM string is embedded exactly as before.
  • app: add yarn dev:build (vite build --watch) to rebuild the bundle on change.

Tooling:

  • scripts/dev.py: one command starts the frontend watch build + JupyterLab with the dev env flags and tees all output to logs/ (frontend.log, jupyter.log, pygwalker.log). Waits for the first build, fails fast if it crashes, and tears down the process tree cleanly on Ctrl+C.
  • utils/log.py: honor PYGWALKER_LOG_LEVEL and PYGWALKER_LOG_FILE (idempotent handlers); default console logging unchanged.

Docs:

  • AGENTS.md (repo map, build model, dev stack, logs, commands, gotchas) with CLAUDE.md importing it; docs/ARCHITECTURE.md (how the Python and frontend halves are built and communicate); docs/DEVELOPMENT.md rewritten around the anywidget HMR workflow with the legacy Vite dev-server/component_url path kept as an appendix; cross-links from README and CONTRIBUTING.

…r/agent docs

Improve the local developer experience for both humans and coding agents.

Dev mode (opt-in, production unchanged):
- anywidget widget loads pygwalker-app.es.js from disk as a pathlib.Path when
  PYGWALKER_DEV=1 or ANYWIDGET_HMR=1, so anywidget hot-reloads it live in the
  notebook. With the flags unset, the bundled ESM string is embedded exactly as
  before.
- app: add `yarn dev:build` (vite build --watch) to rebuild the bundle on change.

Tooling:
- scripts/dev.py: one command starts the frontend watch build + JupyterLab with
  the dev env flags and tees all output to logs/ (frontend.log, jupyter.log,
  pygwalker.log). Waits for the first build, fails fast if it crashes, and tears
  down the process tree cleanly on Ctrl+C.
- utils/log.py: honor PYGWALKER_LOG_LEVEL and PYGWALKER_LOG_FILE (idempotent
  handlers); default console logging unchanged.

Docs:
- AGENTS.md (repo map, build model, dev stack, logs, commands, gotchas) with
  CLAUDE.md importing it; docs/ARCHITECTURE.md (how the Python and frontend halves
  are built and communicate); docs/DEVELOPMENT.md rewritten around the anywidget
  HMR workflow with the legacy Vite dev-server/component_url path kept as an
  appendix; cross-links from README and CONTRIBUTING.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8005c8bf72

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/dev.py
svc.stop()
print("[dev] done.")

return 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Propagate child service failures

When either managed process exits because of a real startup/runtime failure, such as yarn dev:build failing from missing frontend dependencies or Jupyter failing on a busy port, the loop records the non-zero child code but main() still falls through to return 0. That makes python scripts/dev.py report success to shells/automation even though the dev stack never came up; preserve the failing service's exit status unless shutdown was requested by a signal.

Useful? React with 👍 / 👎.

Comment thread scripts/dev.py
env = os.environ.copy()
# Force the frontend dev path on: the widget loads the built ESM from disk and hot-reloads.
env["PYGWALKER_DEV"] = "1"
env["ANYWIDGET_HMR"] = "1"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include anywidget's watcher dependency for HMR

In a fresh environment following the new pip install -e ".[dev]" setup, PyGWalker installs plain anywidget but not anywidget's dev extra/watchfiles. Since this script unconditionally enables ANYWIDGET_HMR and the widget now passes a Path as _esm, anywidget's file watcher cannot start without that extra dependency, so edits rebuild but do not hot-reload as promised. Add watchfiles or anywidget[dev] to the dev setup/dependencies before forcing HMR.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant