agentleFS
koaningkoaning/wigglystuff/AGENTS.md

wigglystuff

AGENTS.md455 starsChanged 4 months agoMITView on GitHub

This repo uses a conductor.json setup script (make install) that runs automatically when a Conductor workspace is created. It installs all dependencies so the environment is ready to use immediately. wigglystuff ships a small roster of AnyWidget "agents" that surface different input modalities (sliders, speech, paint, etc.) across notebook runtimes. This page is a quick lookup so you can see what exists and which traitlets each agent syncs back to Python.

  • Installs packages

We split this AGENTS.md into the rules it gives an agent

7 rules. About 0 are common, 4 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    After visual approval, run the smallest focused checks once.

    line 93
  2. Distinctive:

    Keep widget unit tests compact: cover each public behavior once, group repetitive validation cases in one test, and avoid parameter …

    line 96
  3. Very specific:

    All agents inherit from anywidget.AnyWidget, so widget.observe(handler) remains the standard way to react to state changes.

    line 100
  4. Very specific:

    Check wigglystuff/__init__.py for the names that are re-exported at the package root so you can keep imports consistent.

    line 107
  5. Distinctive:

    When styling widgets, support both light and dark themes by defining component-specific CSS variables (see Matrix/SortableList).

    line 120
  6. Very specific:

    When adding a new widget, remember to update the docs gallery (docs/index.md), the README gallery (readme.md), the LLM context file …

    line 125
  7. Distinctive:

    When planning a new widget, always present the proposed Python API (constructor, traitlets, helper methods) during plan review so the user …

    line 168

≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

Setup

This repo uses a conductor.json setup script (make install) that runs automatically when a Conductor workspace is created. It installs all dependencies so the environment is ready to use immediately.

Agents

wigglystuff ships a small roster of AnyWidget "agents" that surface different input modalities (sliders, speech, paint, etc.) across notebook runtimes. This page is a quick lookup so you can see what exists and which traitlets each agent syncs back to Python.

Quick reference

AgentModule/ClassCore traitletsOne-liner
AltairWidgetwigglystuff.altair_widget.AltairWidgetspec, width, heightFlicker-free Altair chart with smooth data updates
ScatterLogwigglystuff.scatter_log.ScatterLogspec, width, heightAccumulate reactive values into a live, optionally multi-series scatter plot
AnnotationWidgetwigglystuff.annotation.AnnotationWidgetaction, action_timestamp, note, listening, actions, keyboard_mapping, gamepad_mapping, debounce_ms, widthAnnotation input surface with buttons, keyboard, gamepad, and speech-to-text
ApiDocwigglystuff.api_doc.ApiDocdoc, width, show_privateRenders API docs for Python classes/functions
Slider2Dwigglystuff.slider2d.Slider2Dx, y, x_bounds, y_bounds, width, height2D pointer for coupled parameters
Knobwigglystuff.knob.Knobvalue, min_value, max_value, step, start_angle, end_angle, ticks, steps, size, label, show_value, color, midi, midi_cc, midi_channel, midi_device, midi_key, midi_scopeAudio-panel rotary knob with configurable sweep, detents, and Web MIDI learn
Faderwigglystuff.fader.Fadervalue, min_value, max_value, step, ticks, steps, orientation, length, label, show_value, color, midi, midi_cc, midi_channel, midi_device, midi_key, midi_scopeMixing-console fader with a configurable tick scale, detents, and Web MIDI learn
MidiButtonwigglystuff.midi_button.MidiButtonvalue, press_timestamp, velocity, label, icon, mode, size, color, midi, midi_note, midi_channel, midi_device, midi_key, midi_scopeMomentary/toggle pad with icon or text faces and Web MIDI note learn
Pipwigglystuff.pip.Pipchild, width, height, floatingWraps a widget and floats it in a picture-in-picture window above other windows
FloatingPanelwigglystuff.floating_panel.FloatingPanelchild, corner, width, collapsed, title (not an AnyWidget — a marimo display helper)Pins any marimo content in a draggable in-page panel that stays visible while the notebook scrolls and minimizes to its header; portals to document.body to beat cell hover z-index; works in iframes/molab unlike Pip
BezierCurvewigglystuff.bezier_curve.BezierCurvepoints, samples, x, y, t, closed, playing, loop, interval_ms, duration_ms, sync_throttle_ms, show_axes, n_samples, x_bounds, y_bounds, width, heightArbitrary-degree Bezier curve editor with draggable control points, playback, and optional axis ticks
CurveEditorwigglystuff.curve_editor.CurveEditorpoints, samples, x, y, t, curve, closed, playing, loop, tension, alpha, selected_index, show_axes, n_samples, x_bounds, y_bounds, width, heightChart-space curve editor with D3 line interpolators, path progress, and optional axis ticks
ChartPuckwigglystuff.chart_puck.ChartPuckx, y, x_bounds, y_bounds, axes_pixel_bounds, width, height, chart_base64, puck_radius, puck_color, throttleDraggable puck overlay for matplotlib charts
ChartMultiSelectwigglystuff.chart_multi_select.ChartMultiSelectselections, active_class, n_classes, selected_index, mode, modes, x_bounds, y_bounds, axes_pixel_bounds, width, height, chart_base64, selection_opacityMulti-region class-labeled selection on matplotlib charts
ChartSelectwigglystuff.chart_select.ChartSelectmode, selection, has_selection, x_bounds, y_bounds, axes_pixel_bounds, width, height, chart_base64, selection_color, selection_opacityBox/lasso selection on matplotlib charts
Matrixwigglystuff.matrix.Matrixmatrix, rows, cols, min_value, max_value, step, mirrorSpreadsheet-like numeric editor
TangleSliderwigglystuff.tangle.TangleSlideramount, min_value, max_value, step, steps, pixels_per_stepInline slider ala Bret Victor
TangleChoicewigglystuff.tangle.TangleChoicechoice, choicesInline toggle among labels
TangleSelectwigglystuff.tangle.TangleSelectchoice, choicesDropdown version of the above
TangleLatexwigglystuff.tangle_latex.TangleLatexlatex, parameters, values, display_mode, editor, reveal_all_on_drag, theme, errorLaTeX formula with draggable \tangle{name} numbers/symbols
TangleDistributionwigglystuff.tangle.TangleDistributiondistribution, params, live_params, dragging, bounds, steps, pixels_per_step, template, digits, sync_throttle_msInline tangle number holding a whole distribution: drag ↔/↕ for its two scipy-named parameters with a floating shape preview; 14 families (norm, lognorm, gamma, expon, weibull_min, uniform, laplace, logistic, beta, poisson, binom, nbinom, geom, randint); built-in cdf/ppf/pdf/pmf/sample (maths in wigglystuff/_distributions.py, no scipy)
TangleFunctionwigglystuff.tangle_function.TangleFunctionfn_name, parameters, param_order, values, theme, width, errorIntrospects a typed function into an editable call expression: drag numbers, click-cycle Literal/Enum/bool, edit strings; reads annotated_types/pydantic Field bounds; unbounded scrubbers by default; syncs values to splat into the function
FormulaAnimationwigglystuff.formula_animation.FormulaAnimationsteps, title, spotlight, step, height, theme, errorStep through a LaTeX derivation one line at a time (prev/next buttons, opt-in arrow keys, reactive step); KaTeX-rendered with an optional final spotlight frame
SortableListwigglystuff.sortable_list.SortableListvalue, addable, removable, editable, labelDrag-and-drop ordering with optional CRUD
CopyToClipboardwigglystuff.copy_to_clipboard.CopyToClipboardtext_to_copyCopies the payload into the OS clipboard
ColorPickerwigglystuff.color_picker.ColorPickercolorNative color input with rgb helper
EdgeDrawwigglystuff.edge_draw.EdgeDrawnames, links, directed, width, heightSketch node/link diagrams and query adjacency
GridDrawwigglystuff.grid_draw.GridDrawdots, lines, rows, cols, line_width, dot_radius, theme, width, heightDraw dots on grid intersections and orthogonal line segments between them
HeatmapSelectwigglystuff.heatmap_select.HeatmapSelectpinned_cell, pinned_row, pinned_col, hover_cell, hover_row, hover_col, image_base64, n_rows, n_cols, x_range, y_range, cell_width, cell_height, row_color, col_color, throttleBret Victor style parameter-space grid; pin a cell plus a whole row/column off either axis
GraphWidgetwigglystuff.graph_widget.GraphWidgetnodes, edges, directed, width, height, selected_nodes, selected_edgesProgrammatic force-directed graph visualization
Paintwigglystuff.paint.Paintbase64, width, height, store_background, rainbow_brush, brush, marker, eraser, color_picker, colorMS-Paint-style canvas with PIL helpers and a configurable toolbar
Excalidrawwigglystuff.excalidraw.Excalidrawscene, image_base64, theme, height, sync_throttle_msEmbedded Excalidraw whiteboard (loads from CDN); get_pil/save/from_file helpers (save() remembers the path)
ParallelCoordinateswigglystuff.parallel_coords.ParallelCoordinatesdata, color_by, height, filtered_indices, selected_indices, brush_extents, selectionsHiPlot-powered parallel coordinates with brush filtering and axis reordering
ThreeWidgetwigglystuff.three_widget.ThreeWidgetdata, width, height, show_grid, show_axes, dark_mode, axis_labels, animate_updates, animation_duration_ms3D scatter plot for point clouds
WebcamCapturewigglystuff.webcam_capture.WebcamCaptureimage_base64, capturing, interval_ms, facing_modeWebcam preview with snapshot capture
GamepadWidgetwigglystuff.gamepad.GamepadWidgetaxes, current_button_press, dpad_*, current_timestampStreams browser Gamepad API events
HoverZoomwigglystuff.hover_zoom.HoverZoomimage, zoom_factor, width, height, _cropImage hover zoom with magnified side panel
KeystrokeWidgetwigglystuff.keystroke.KeystrokeWidgetlast_keyCaptures the latest keypress w/ modifiers
LiveEditwigglystuff.live_edit.LiveEditcode, trace, annotations, error, editable, theme, width, height, float_precision, visible_columnsSource-linked loop trace for inspecting one Python function run; click numeric column headers to chart them
StateViewerwigglystuff.state_viewer.StateViewercode, lines, steps, views, variables, step, playing, interval_ms, loop, timeline_label, sync_throttle_ms, returned, error, truncated, heightAnimates one run of a function (e.g. a backtracking or BFS search): an optional view_func draws the state at each executed line (its parameter names pick the locals), next to the source, a fixed variables table, and a scrubbable timeline of call depth or a timeline_func value (e.g. frontier size); state exposes real local values so other widgets can draw it; max_steps caps the recording
ManimWebwigglystuff.manim_web.ManimWebcode, width, height, version, errorRuns a manim-web (browser Manim) scene from a JS string, local file, or URL
ObservablePlotwigglystuff.observable_plot.ObservablePlotcode, variables, width, height, version, errorRuns Observable Plot JS from a string, local file, or URL, injecting Python variables by name
EsmWidgetwigglystuff.esm_widget.EsmWidgetcode, css, data, width, height, errorRenders an inline ES module (any CDN library, e.g. motion.dev or Observable Plot) with a two-way data bridge; change:data fires without re-running render
AsyncFlowwigglystuff.async_flow.AsyncFlowevents, now_ms, running, widthLive swimlane timeline of one async run (await AsyncFlow.trace(main())); one lane per task, running vs suspended-at-await, nested by parent; needs Python 3.12+
TraceViewwigglystuff.trace_view.TraceViewspans, trace_id, show_latest, selected_span_id, cursor_ms, collapsed, title, height, now_msOpenTelemetry trace waterfall: indented span tree with state/timeline/duration, replay scrubber, details panel; live via span_processor() (needs opentelemetry-sdk, the otel extra) or from_otlp/from_spans; W&B Weave via with view.capture_weave(): (the weave extra) or from_weave
WebkitSpeechToTextWidgetwigglystuff.talk.WebkitSpeechToTextWidgettranscript, listening, trigger_listenWebKit speech recognition bridge
DriverTourwigglystuff.driver_tour.DriverToursteps, auto_start, show_progress, active, current_stepGuided product tours via Driver.js
CellTourwigglystuff.cell_tour.CellToursteps, auto_start, show_progress, active, current_stepSimplified cell-based tours for marimo
TextComparewigglystuff.text_compare.TextComparetext_a, text_b, matches, selected_match, min_match_wordsSide-by-side text diff with match highlighting
EnvConfigwigglystuff.env_config.EnvConfigvariables, all_validEnvironment variable config with validation
ModuleTreeWidgetwigglystuff.module_tree.ModuleTreeWidgettree, initial_expand_depthInteractive tree viewer for PyTorch nn.Module
Neo4jWidgetwigglystuff.neo4j_widget.Neo4jWidgetnodes, relationships, schema, error, query_running, selected_nodes, selected_relationships, width, heightInteractive Neo4j graph explorer with Cypher query input
SplineDrawwigglystuff.spline_draw.SplineDrawdata, curve, curve_error, brushsize, n_classes, width, heightDraw scatter points with Python-computed spline curve fitting
ScatterWidgetre-exported from drawdatadata, brushsize, width, height, n_classesPaint multi-class 2D scatter data with brush
PlaySliderwigglystuff.play_slider.PlaySlidervalue, min_value, max_value, step, interval_ms, playing, loop, widthSlider with play/pause button for auto-advancing values
FramePlayerwigglystuff.frame_player.FramePlayerframes, value, interval_ms, playing, loop, width, show_indexPlay a sequence of images (PIL/paths/URLs/figures) as an inline looping "video"
CircularSliderwigglystuff.circular_slider.CircularSlidervalue, start, stop, step, size, thickness, show_value, color, labelCircular dial slider for picking a single value
CircularRangeSliderwigglystuff.circular_slider.CircularRangeSlidervalue ((low, high)), start, stop, step, size, thickness, show_value, color, labelCircular dial slider for picking a span of values (wraps the seam)
HoverSliderwigglystuff.hover_slider.HoverSlidervalue, hover_value, hovering, start, stop, step, steps, sync_throttle_ms, show_value, label, color, widthSlider that emits both the committed value and the live value under the pointer
RidgelineChartwigglystuff.ridgeline_chart.RidgelineChartdata, x_values, width, height, overlap, stroke_width, fill_opacity, peak_scale, x_label, y_label, selected_index, selected_rowStacked waveform "Joy Division" visualization with clickable rows
Treemapwigglystuff.treemap.Treemapdata, width, height, max_depth, value_col, selected_path, clicked_path, hovered_pathZoomable hierarchical treemap with breadcrumbs
WidgetDAGwigglystuff.widget_dag.WidgetDAGnodes, edges, layout (not an AnyWidget — a marimo display helper)Arrange live widgets/images as a DAG (columns by edge-depth) and draw the connecting arrows; WidgetDAG.from_widgets([...]) derives the edges from marimo's dataflow graph (one node per cell)
Hintwigglystuff.hint.Hinttarget, note, side, color, gap (not an AnyWidget — a marimo display helper)Wrap a widget and curve an arrow from an explanatory note to its edge; the note is any marimo content, and hints compose into stacks, WidgetDAG nodes, and each other

Patterns to remember

Visual approval comes before verification

  • For new widgets and visual or interaction changes, stop once the implementation and demo are ready for inspection. Give the user a concrete way to open the widget, then wait for explicit visual approval before running test suites, requesting code review, updating galleries/docs, committing, pushing, or starting branch-finishing workflows. The user may want another design pass.
  • During visual iteration, do not repeatedly run automated checks after CSS, SVG, layout, or styling tweaks. Make the change and return it for inspection.
  • After visual approval, run the smallest focused checks once. Run the full repository suite only when preparing to ship/merge or when shared infrastructure changed.
  • Keep widget unit tests compact: cover each public behavior once, group repetitive validation cases in one test, and avoid parameter matrices that multiply test count without adding distinct behavioral coverage.
  • All agents inherit from anywidget.AnyWidget, so widget.observe(handler) remains the standard way to react to state changes.
  • Constructors tend to validate bounds, lengths, or choice counts; let the raised ValueError/TraitError guide you instead of duplicating the logic.
  • Several widgets expose helper methods (e.g., Paint.get_pil(), EdgeDraw.get_adjacency_matrix())—lean on those rather than re-implementing conversions.
  • Check wigglystuff/__init__.py for the names that are re-exported at the package root so you can keep imports consistent.
  • numpy and pillow are optional dependencies. They are listed under [project.optional-dependencies] in pyproject.toml, not in the core dependencies. Widgets that need numpy or pillow must import them inside the method or function that uses them (never at module top-level). This keeps import wigglystuff and widgets that don't need these libraries working without them installed. Install with pip install wigglystuff[all] to get both, or wigglystuff[numpy] / wigglystuff[pillow] individually.
  • The repo standardizes on uv for Python workflows (uv pip install -e . etc.) and the standard library's pathlib for filesystem paths—mirror those choices in new agents to keep the codebase consistent.
  • When styling widgets, support both light and dark themes by defining component-specific CSS variables (see Matrix/SortableList). Scope your defaults to the widget root, mark color-scheme: light dark, and provide overrides that respond to .dark, .dark-theme, or [data-theme="dark"] ancestors so notebook-level theme toggles work instantly.
  • When adding a new widget, remember to update the docs gallery (docs/index.md), the README gallery (readme.md), the LLM context file (docs/llms.txt), and the changelog (CHANGELOG.md). Add a screenshot to docs/assets/gallery/ and reference it from the gallery locations to keep them in sync. Screenshots are stored as .webp — if you only have a PNG, drop it in and run uv run python scripts/png_to_webp.py to convert and clean up.
  • Every link to MoLab (molab.marimo.io) must carry ?utm_source=wigglystuff so outbound traffic is attributable in analytics. This applies to the gallery links in README.md and docs/index.md and any MoLab reference in docs/llms.txt. When adding a new widget, append the param to its molab demo links (e.g. .../demos/<name>.py/wasm?utm_source=wigglystuff).
  • New or changed features that haven't been released yet go under the ## [Unreleased] section at the top of CHANGELOG.md. That section gets renamed to a versioned heading (e.g., ## [0.2.37]) only at release time.
  • At release time, also bump the wigglystuff==X.Y.Z pin in the script header of every demo notebook that exercises an unreleased feature. The demos/*.py files use PEP 723 # /// script blocks that pin a published version — if a demo uses APIs only present in the new release, leaving the old pin means uv run demos/<name>.py (and anyone who downloads the demo) will get the old wigglystuff and the feature will be missing. After bumping pyproject.toml, grep demos/ for the previous version and update the pins on any demo touched in the release.
  • Each widget has a demo marimo notebook in the demos/ folder (e.g., demos/colorpicker.py). When adding a new widget, create a corresponding demo notebook. Run demos with marimo edit demos/<widget>.py.
  • After visual approval, smoke-test new or modified widget code with uv run python -c "..." to instantiate the widget, exercise traitlet changes, and check edge cases (built-ins, empty inputs, toggles).
  • After visual approval, run uv run marimo check demos/<notebook>.py after editing a demo notebook to verify it parses correctly and has no cell dependency issues. which only validates structure.
  • Dumber is better. Prefer obvious, direct code over clever abstractions—someone new to the project should be able to read the code top-to-bottom and grok it without needing to look up framework magic or trace through indirection.
  • Do not modify package-lock.json unless intentionally updating JS dependencies. If it shows up in git diff, revert it with git checkout package-lock.json.
  • Docs are built with zensical, not mkdocs. The config lives in zensical.toml; build with make docs and preview with make docs-serve (which builds, then serves site/ via python -m http.server). Packages like mkdocstrings are zensical plugins — their presence is not evidence that this is an mkdocs project.
  • When planning a new widget, always present the proposed Python API (constructor, traitlets, helper methods) during plan review so the user can sign off on the interface before implementation.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.