browserrig 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- browserrig-0.2.0/.agents/skills/smelt/references/CHANGELOG.md +646 -0
- browserrig-0.2.0/.agents/skills/smelt/references/README.md +186 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/adoption.md +103 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/architecture.md +171 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/cli.md +152 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/configuration.md +299 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/integrations.md +103 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rule-selection.md +102 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/README.md +71 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT101.md +40 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT102.md +38 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT103.md +39 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT104.md +39 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT105.md +38 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT106.md +39 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT107.md +36 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT108.md +38 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT109.md +41 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT301.md +40 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT302.md +33 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT305.md +39 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT306.md +47 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT307.md +41 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT308.md +38 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT309.md +37 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT310.md +35 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT311.md +37 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT312.md +39 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT313.md +43 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT314.md +39 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT315.md +45 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT316.md +47 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT317.md +45 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT318.md +43 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT319.md +38 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT320.md +47 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT321.md +36 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT322.md +41 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT323.md +42 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT324.md +53 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT325.md +34 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT326.md +42 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT327.md +43 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT328.md +44 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT329.md +42 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT330.md +43 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT331.md +37 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT332.md +37 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT333.md +44 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT334.md +43 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT335.md +47 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT336.md +34 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT401.md +37 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT420.md +38 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT421.md +38 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT422.md +39 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT423.md +38 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT424.md +38 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT425.md +38 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT426.md +38 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT427.md +39 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT428.md +40 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT429.md +48 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT430.md +58 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT431.md +42 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT901.md +33 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT902.md +33 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT903.md +33 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/structure.md +624 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/testing.md +252 -0
- browserrig-0.2.0/.agents/skills/smelt/references/docs/upgrading.md +344 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/.github/workflows/checks.yml +2 -2
- {browserrig-0.1.0 → browserrig-0.2.0}/.pre-commit-config.yml +0 -7
- {browserrig-0.1.0 → browserrig-0.2.0}/.smelt/debt.json +18 -18
- {browserrig-0.1.0 → browserrig-0.2.0}/.smelt.schema.json +375 -1
- browserrig-0.2.0/CHANGELOG.md +237 -0
- browserrig-0.2.0/PKG-INFO +270 -0
- browserrig-0.1.0/PKG-INFO → browserrig-0.2.0/README.md +95 -62
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/__init__.py +45 -13
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/activity/plugin.py +23 -18
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/agent.py +12 -10
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/__init__.py +6 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/base.py +7 -13
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/chrome.py +42 -27
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/config.py +20 -11
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/downloads.py +48 -24
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/favicon.py +1 -2
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/frame.py +21 -5
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/frames.py +19 -14
- browserrig-0.2.0/browserrig/browser/guard.py +203 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/images.py +9 -1
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/input.py +2 -0
- browserrig-0.2.0/browserrig/browser/network.py +77 -0
- browserrig-0.2.0/browserrig/browser/overlays.py +193 -0
- browserrig-0.2.0/browserrig/browser/plugin.py +131 -0
- browserrig-0.2.0/browserrig/browser/policy.py +19 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/process.py +1 -1
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/tab.py +39 -9
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/tabs.py +101 -13
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/worlds.py +1 -2
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/choreography/__init__.py +8 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/choreography/events.py +69 -2
- browserrig-0.2.0/browserrig/choreography/images.py +21 -0
- browserrig-0.2.0/browserrig/choreography/plugin.py +398 -0
- browserrig-0.2.0/browserrig/choreography/projection.py +214 -0
- browserrig-0.2.0/browserrig/choreography/receipts.py +109 -0
- browserrig-0.2.0/browserrig/choreography/renderer.py +101 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/choreography/stage.py +14 -10
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/choreography/tabstrip.py +7 -9
- browserrig-0.2.0/browserrig/choreography/view.css +841 -0
- browserrig-0.2.0/browserrig/choreography/view.html +68 -0
- browserrig-0.2.0/browserrig/choreography/work.py +264 -0
- browserrig-0.2.0/browserrig/completion/__init__.py +3 -0
- browserrig-0.2.0/browserrig/completion/models.py +43 -0
- browserrig-0.2.0/browserrig/completion/output.py +73 -0
- browserrig-0.1.0/browserrig/completion.py → browserrig-0.2.0/browserrig/completion/plugin.py +73 -81
- browserrig-0.2.0/browserrig/completion/state.py +8 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/composition.py +29 -18
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/core/__init__.py +7 -2
- browserrig-0.2.0/browserrig/core/coordination.py +30 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/core/kinds.py +12 -0
- browserrig-0.2.0/browserrig/core/tools.py +93 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/events.py +70 -5
- browserrig-0.2.0/browserrig/files/__init__.py +43 -0
- browserrig-0.2.0/browserrig/files/bridge.py +137 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/config.py +4 -4
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/content.py +2 -2
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/data.py +0 -22
- browserrig-0.2.0/browserrig/files/extras.py +10 -0
- browserrig-0.2.0/browserrig/files/formats.py +90 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/imaging.py +17 -4
- browserrig-0.2.0/browserrig/files/media.py +23 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/models.py +5 -3
- browserrig-0.2.0/browserrig/files/plugin.py +50 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/reading.py +55 -5
- browserrig-0.2.0/browserrig/files/system.py +206 -0
- browserrig-0.2.0/browserrig/files/transfer.py +89 -0
- browserrig-0.2.0/browserrig/files/workspace.py +146 -0
- browserrig-0.2.0/browserrig/guardrails/__init__.py +3 -0
- browserrig-0.2.0/browserrig/guardrails/domains.py +127 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/handoff/models.py +4 -4
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/handoff/plugin.py +81 -50
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/handoff/state.py +3 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/controller.py +5 -1
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/keyboard.py +54 -101
- browserrig-0.2.0/browserrig/input/keys.py +158 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/mouse.py +49 -7
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/presenter.py +23 -5
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/target.py +1 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/kinds.py +2 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/nudges/plugin.py +20 -12
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/__init__.py +8 -2
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/capture.py +138 -38
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/changes.py +4 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/content.py +49 -10
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/delta.py +6 -2
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/dom.py +3 -1
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/__init__.py +51 -13
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/accessibility.py +4 -0
- browserrig-0.2.0/browserrig/observation/extraction/cookies.py +202 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/document.py +38 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/elements.py +123 -19
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/semantics.py +12 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/find.py +1 -1
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/handle.py +6 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/images.py +28 -9
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/marks.py +3 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/models.py +38 -6
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/plugin.py +97 -32
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/render.py +69 -4
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/renderer.py +14 -4
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/state.py +7 -3
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/pacing/plugin.py +5 -5
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/__init__.py +3 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/downloads.py +2 -2
- browserrig-0.2.0/browserrig/readiness/network.py +99 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/plugin.py +24 -14
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/policies.py +2 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/state.py +2 -2
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/wait.py +35 -3
- browserrig-0.2.0/browserrig/recording/__init__.py +4 -0
- browserrig-0.2.0/browserrig/recording/capture.py +64 -0
- browserrig-0.2.0/browserrig/recording/editing.py +120 -0
- browserrig-0.2.0/browserrig/recording/models.py +27 -0
- browserrig-0.2.0/browserrig/recording/plugin.py +195 -0
- browserrig-0.2.0/browserrig/recording/timeline.py +67 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/README.md +9 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/__init__.py +40 -4
- browserrig-0.2.0/browserrig/scripts/choreography.js +36 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/content.js +12 -1
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/element.js +13 -0
- browserrig-0.2.0/browserrig/scripts/file_input.js +12 -0
- browserrig-0.2.0/browserrig/scripts/lib/choreography/caption.js +148 -0
- browserrig-0.2.0/browserrig/scripts/lib/choreography/cursor.js +302 -0
- browserrig-0.2.0/browserrig/scripts/lib/choreography/keyboard.js +136 -0
- browserrig-0.2.0/browserrig/scripts/lib/choreography/panels.js +131 -0
- browserrig-0.2.0/browserrig/scripts/lib/choreography/surface.js +90 -0
- browserrig-0.2.0/browserrig/scripts/lib/choreography/transfers.js +140 -0
- browserrig-0.2.0/browserrig/scripts/lib/choreography/work.js +225 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/models.py +21 -0
- browserrig-0.2.0/browserrig/scripts/overlay.js +56 -0
- browserrig-0.2.0/browserrig/scripts/overlay_message.js +5 -0
- browserrig-0.2.0/browserrig/scripts/overlay_styles.js +14 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/stability.js +26 -2
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/plugin.py +10 -13
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/terminal.py +5 -2
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/__init__.py +2 -1
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/chains.py +10 -5
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/dialogs.py +7 -6
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/effects.py +2 -0
- browserrig-0.2.0/browserrig/tools/execution/__init__.py +3 -0
- browserrig-0.2.0/browserrig/tools/execution/completion.py +124 -0
- browserrig-0.2.0/browserrig/tools/execution/context.py +56 -0
- browserrig-0.2.0/browserrig/tools/execution/invocation.py +66 -0
- browserrig-0.2.0/browserrig/tools/execution/plugin.py +179 -0
- browserrig-0.2.0/browserrig/tools/execution/policy.py +65 -0
- browserrig-0.2.0/browserrig/tools/execution/transaction.py +250 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/files.py +147 -102
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/find.py +20 -22
- browserrig-0.2.0/browserrig/tools/forms.py +79 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/intents.py +2 -2
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/javascript.py +8 -11
- browserrig-0.2.0/browserrig/tools/keyboard.py +136 -0
- browserrig-0.2.0/browserrig/tools/mouse.py +279 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/navigation.py +60 -85
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/scrolling.py +3 -0
- browserrig-0.2.0/browserrig/tools/tabs.py +60 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/targeting.py +11 -4
- {browserrig-0.1.0 → browserrig-0.2.0}/docs/agent-guide.md +162 -71
- browserrig-0.2.0/docs/browser-choreography.md +148 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/docs/browser-composition.md +276 -24
- {browserrig-0.1.0 → browserrig-0.2.0}/docs/browser-interaction.md +94 -28
- {browserrig-0.1.0 → browserrig-0.2.0}/docs/development.md +42 -15
- {browserrig-0.1.0 → browserrig-0.2.0}/docs/files-and-events.md +196 -46
- {browserrig-0.1.0 → browserrig-0.2.0}/docs/harnessed-telemetry-feedback.md +9 -1
- {browserrig-0.1.0 → browserrig-0.2.0}/docs/human-handoff.md +36 -13
- browserrig-0.2.0/docs/media/choreography/compact.png +0 -0
- browserrig-0.2.0/docs/media/choreography/demo.mp4 +0 -0
- browserrig-0.2.0/docs/media/choreography/files.png +0 -0
- browserrig-0.2.0/docs/media/choreography/find.png +0 -0
- browserrig-0.2.0/docs/media/choreography/keyboard.png +0 -0
- browserrig-0.2.0/docs/media/choreography/navigation.png +0 -0
- browserrig-0.2.0/docs/media/choreography/observation.png +0 -0
- browserrig-0.2.0/docs/media/choreography/overview.png +0 -0
- browserrig-0.2.0/docs/media/choreography/pointer.png +0 -0
- browserrig-0.2.0/docs/media/choreography/scroll.png +0 -0
- browserrig-0.2.0/docs/media/choreography/tabs.png +0 -0
- browserrig-0.2.0/docs/media/choreography/thinking.png +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/docs/telemetry.md +130 -36
- browserrig-0.2.0/evals/README.md +71 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/examples/connect_browser.py +2 -1
- {browserrig-0.1.0 → browserrig-0.2.0}/examples/controls.py +5 -4
- {browserrig-0.1.0 → browserrig-0.2.0}/examples/direct_browser.py +2 -1
- {browserrig-0.1.0 → browserrig-0.2.0}/examples/openai_agent.py +19 -5
- {browserrig-0.1.0 → browserrig-0.2.0}/examples/session_store.py +5 -9
- {browserrig-0.1.0 → browserrig-0.2.0}/examples/telemetry.py +12 -2
- {browserrig-0.1.0 → browserrig-0.2.0}/examples/tracing_smoke.py +3 -2
- browserrig-0.2.0/examples/visualization.html +54 -0
- browserrig-0.2.0/examples/visualization.py +89 -0
- browserrig-0.2.0/examples/visualization_gallery.py +57 -0
- browserrig-0.2.0/examples/visualization_run.py +257 -0
- browserrig-0.2.0/examples/visualization_server.py +68 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/pyproject.toml +19 -12
- {browserrig-0.1.0 → browserrig-0.2.0}/smelt.yml +30 -2
- browserrig-0.2.0/tests/activity/__init__.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/activity}/test_activity.py +10 -6
- browserrig-0.2.0/tests/browser/__init__.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/browser}/test_chrome.py +38 -3
- browserrig-0.2.0/tests/browser/test_plugin.py +158 -0
- browserrig-0.1.0/tests/test_javascript.py → browserrig-0.2.0/tests/browser/test_tab.py +2 -1
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/browser}/test_tab_state.py +2 -2
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/browser}/test_worlds.py +1 -1
- {browserrig-0.1.0 → browserrig-0.2.0}/tests/check_distribution.py +31 -4
- {browserrig-0.1.0 → browserrig-0.2.0}/tests/check_file_corpus.py +7 -6
- browserrig-0.2.0/tests/choreography/__init__.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/choreography}/test_choreography.py +46 -34
- browserrig-0.2.0/tests/choreography/test_plugin_work.py +86 -0
- browserrig-0.2.0/tests/choreography/test_projection.py +41 -0
- browserrig-0.2.0/tests/choreography/test_receipts.py +84 -0
- browserrig-0.2.0/tests/choreography/test_work.py +104 -0
- browserrig-0.2.0/tests/completion/__init__.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/completion}/test_completion.py +108 -28
- {browserrig-0.1.0 → browserrig-0.2.0}/tests/conftest.py +13 -0
- browserrig-0.2.0/tests/core/__init__.py +0 -0
- browserrig-0.2.0/tests/core/test_coordination.py +47 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/tests/fakes.py +61 -21
- browserrig-0.2.0/tests/files/__init__.py +0 -0
- browserrig-0.1.0/tests/test_file_readers.py → browserrig-0.2.0/tests/files/test_reading.py +85 -53
- browserrig-0.1.0/tests/test_archive_input_limit.py → browserrig-0.2.0/tests/files/test_reading_archive_input_limit.py +9 -4
- browserrig-0.1.0/tests/test_extraction_budget.py → browserrig-0.2.0/tests/files/test_reading_extraction_budget.py +7 -3
- browserrig-0.2.0/tests/guardrails/test_domains.py +83 -0
- browserrig-0.2.0/tests/guardrails/test_domains_tools.py +60 -0
- browserrig-0.2.0/tests/handoff/__init__.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/handoff}/test_handoff.py +165 -62
- browserrig-0.2.0/tests/input/__init__.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/input}/test_input.py +103 -31
- browserrig-0.2.0/tests/integration/__init__.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_agent_facade_integration.py +67 -19
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_agent_integration.py +18 -15
- browserrig-0.2.0/tests/integration/test_allowed_domains_integration.py +215 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_attached_context_integration.py +2 -1
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_browser_integration.py +24 -5
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_chains_integration.py +65 -11
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_content_integration.py +5 -2
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_controls_integration.py +34 -15
- browserrig-0.2.0/tests/integration/test_cookies_integration.py +213 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_download_integration.py +233 -40
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_elements_integration.py +2 -1
- browserrig-0.2.0/tests/integration/test_extraction_context_integration.py +244 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_find_integration.py +4 -4
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_frames_integration.py +58 -11
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_gestures_integration.py +15 -12
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_input_integration.py +142 -16
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_javascript_integration.py +6 -6
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_navigation_integration.py +3 -4
- browserrig-0.2.0/tests/integration/test_new_tab_integration.py +89 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_observation_integration.py +39 -22
- browserrig-0.2.0/tests/integration/test_overlays_integration.py +294 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_readiness_integration.py +15 -17
- browserrig-0.2.0/tests/integration/test_recording_integration.py +249 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_references_integration.py +8 -8
- browserrig-0.2.0/tests/integration/test_reveal_actions_integration.py +292 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_scripts_integration.py +2 -1
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_secret_javascript_guard_integration.py +7 -1
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_secret_screenshots_integration.py +2 -1
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_secrets_integration.py +13 -11
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_tab_state_integration.py +5 -6
- browserrig-0.2.0/tests/integration/test_tracing_integration.py +94 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_viewport_integration.py +41 -17
- browserrig-0.2.0/tests/integration/test_visualization_integration.py +390 -0
- browserrig-0.2.0/tests/nudges/__init__.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/nudges}/test_nudges.py +18 -17
- browserrig-0.2.0/tests/observation/__init__.py +0 -0
- browserrig-0.2.0/tests/observation/test_capture.py +255 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/observation}/test_delta.py +21 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/observation}/test_models.py +50 -4
- browserrig-0.2.0/tests/observation/test_plugin.py +64 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/observation}/test_references.py +18 -23
- browserrig-0.2.0/tests/project/__init__.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/project}/test_architecture.py +1 -1
- browserrig-0.2.0/tests/project/test_documentation.py +39 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/project}/test_optional_defaults.py +4 -4
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/project}/test_telemetry.py +124 -2
- browserrig-0.2.0/tests/readiness/__init__.py +0 -0
- browserrig-0.2.0/tests/readiness/test_network.py +199 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/readiness}/test_readiness.py +32 -15
- browserrig-0.2.0/tests/recording/__init__.py +0 -0
- browserrig-0.2.0/tests/recording/test_recording.py +407 -0
- browserrig-0.2.0/tests/scripts/__init__.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/scripts}/test_scripts.py +10 -2
- browserrig-0.2.0/tests/secrets/__init__.py +0 -0
- browserrig-0.1.0/tests/test_secret_javascript_guard.py → browserrig-0.2.0/tests/secrets/test_plugin_javascript_guard.py +1 -1
- browserrig-0.1.0/tests/test_secret_screenshots.py → browserrig-0.2.0/tests/secrets/test_redaction_screenshots.py +6 -2
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/secrets}/test_secrets.py +19 -11
- browserrig-0.1.0/tests/test_session_store.py → browserrig-0.2.0/tests/test_agent_session_store.py +85 -12
- {browserrig-0.1.0 → browserrig-0.2.0}/tests/test_composition.py +30 -16
- browserrig-0.1.0/tests/test_browser_composition.py → browserrig-0.2.0/tests/test_composition_browser.py +131 -48
- browserrig-0.1.0/tests/test_dependencies.py → browserrig-0.2.0/tests/test_composition_dependencies.py +198 -72
- browserrig-0.1.0/tests/test_kit.py → browserrig-0.2.0/tests/test_composition_pack.py +69 -53
- {browserrig-0.1.0 → browserrig-0.2.0}/tests/test_events.py +28 -1
- {browserrig-0.1.0 → browserrig-0.2.0}/tests/test_terminal.py +25 -1
- browserrig-0.2.0/tests/tools/__init__.py +0 -0
- browserrig-0.2.0/tests/tools/execution/__init__.py +0 -0
- browserrig-0.2.0/tests/tools/execution/test_invocation.py +146 -0
- browserrig-0.1.0/tests/test_actions.py → browserrig-0.2.0/tests/tools/execution/test_transaction.py +66 -15
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/tools}/test_chains.py +24 -50
- browserrig-0.2.0/tests/tools/test_files.py +770 -0
- browserrig-0.2.0/tests/tools/test_mouse.py +210 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/tools}/test_navigation.py +17 -14
- {browserrig-0.1.0 → browserrig-0.2.0}/uv.lock +310 -95
- browserrig-0.1.0/CHANGELOG.md +0 -27
- browserrig-0.1.0/README.md +0 -124
- browserrig-0.1.0/browserrig/browser/plugin.py +0 -44
- browserrig-0.1.0/browserrig/choreography/plugin.py +0 -75
- browserrig-0.1.0/browserrig/core/tools.py +0 -32
- browserrig-0.1.0/browserrig/files/__init__.py +0 -25
- browserrig-0.1.0/browserrig/files/formats.py +0 -84
- browserrig-0.1.0/browserrig/files/system.py +0 -204
- browserrig-0.1.0/browserrig/tools/execution.py +0 -333
- browserrig-0.1.0/browserrig/tools/forms.py +0 -76
- browserrig-0.1.0/browserrig/tools/keyboard.py +0 -126
- browserrig-0.1.0/browserrig/tools/mouse.py +0 -224
- browserrig-0.1.0/browserrig/tools/tabs.py +0 -81
- browserrig-0.1.0/tests/test_capture.py +0 -82
- browserrig-0.1.0/tests/test_files.py +0 -460
- {browserrig-0.1.0 → browserrig-0.2.0}/.env.example +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/.gitattributes +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/.github/workflows/release.yml +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/.gitignore +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/.prettierignore +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/.prettierrc.json +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/LICENSE +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/activity/__init__.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/activity/models.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/activity/state.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/models.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/setup.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/choreography/scenes.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/core/errors.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/core/geometry.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/core/ids.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/core/options.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/containers.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/documents.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/kinds.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/spreadsheets.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/text.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/xlsx.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/handoff/__init__.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/handoff/changes.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/__init__.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/motor.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/pointer.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/wheel.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/nudges/__init__.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/nudges/state.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/config.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/styles.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/visibility.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/redirects.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/references.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/pacing/__init__.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/py.typed +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/config.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/dom.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/hooks.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/models.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/strategy.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/cursor.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/find.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/focused.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/composed.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/elements.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/geometry.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/hit.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/markdown.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/scroll.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/secret.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/visibility.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/owner_hits.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/owner_scroll.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/owner_size.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/page_facts.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/reset.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/scroll.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/secret_field.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/secret_focus.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/seed.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/tab_strip.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/viewport.js +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/__init__.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/models.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/origin.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/redaction.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/state.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/totp.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/compose.yml +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/eslint.config.mjs +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/examples/__init__.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/package.json +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/pnpm-lock.yaml +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/tests/__init__.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/browser}/test_process.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/tests/check_release.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/tests/file_corpus.json +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/tests/javascript.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/observation}/test_marks.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/observation}/test_redirects.py +0 -0
- {browserrig-0.1.0 → browserrig-0.2.0}/tests/observations.py +0 -0
- {browserrig-0.1.0/tests → browserrig-0.2.0/tests/project}/test_release.py +0 -0
- /browserrig-0.1.0/tests/test_secret_unicode.py → /browserrig-0.2.0/tests/secrets/test_redaction_unicode.py +0 -0
|
@@ -0,0 +1,646 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
User-visible changes, newest first. Agents should read the latest release's
|
|
4
|
+
migration notes before interpreting fewer findings as an improvement. For the
|
|
5
|
+
current configuration and complete rule contracts, see the [README](README.md),
|
|
6
|
+
[rule catalog](docs/rules/README.md) and [activation guide](docs/rule-selection.md).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.6.0] - 2026-11-08
|
|
11
|
+
|
|
12
|
+
Report schema 2, YAML version 1, grouped debt baseline version 2 and the default
|
|
13
|
+
rule set remain unchanged. The six new rules SMT331–SMT336 are opt-in; canonical
|
|
14
|
+
filename checks activate through explicit file-naming policy. Existing individual
|
|
15
|
+
rule selections remain valid. New `init --maintainability` configurations select
|
|
16
|
+
`information-hiding`, adding SMT320 and SMT335 to the previous starter policy.
|
|
17
|
+
Update installation, hook and CI pins together to `0.6.0` (`v0.6.0`), refresh the
|
|
18
|
+
editor schema and review findings before changing debt. No baseline rewrite is
|
|
19
|
+
required for this upgrade. See the [upgrade checklist](docs/upgrading.md#050-to-060).
|
|
20
|
+
|
|
21
|
+
- Optional [SMT336](docs/rules/SMT336.md) reviews module filenames that repeat an
|
|
22
|
+
ancestor package, such as `cars/application/car_exporter.py`. Enable
|
|
23
|
+
`rules: {redundant-module-name: hint}`. Whole-name prefixes/suffixes and simple
|
|
24
|
+
trailing-s plurals are recognized; occupied shorter names are not suggested.
|
|
25
|
+
Renames and import updates remain manual. Implements
|
|
26
|
+
[#94](https://github.com/mathisarends/smelt/issues/94).
|
|
27
|
+
|
|
28
|
+
- Enable the five public-API reviews together with
|
|
29
|
+
`rules: {information-hiding: warning}` (SMT316/SMT320/SMT335/SMT429/SMT430).
|
|
30
|
+
Tests alone do not justify public visibility. Individual entries override the
|
|
31
|
+
group in the same map regardless of order; closer package settings still win.
|
|
32
|
+
The group works with CLI selection/ignores and scoped ignores, and is exposed
|
|
33
|
+
in `explain`, catalog JSON and the editor schema. Existing names, codes,
|
|
34
|
+
suppressions and debt identities remain valid. `init --maintainability` now
|
|
35
|
+
writes this group, adding the module-symbol and attribute reviews to its
|
|
36
|
+
generated selection. See [scope and migration](docs/rule-selection.md#information-hiding).
|
|
37
|
+
|
|
38
|
+
- Optional [SMT335](docs/rules/SMT335.md) reviews public instance and class data
|
|
39
|
+
attributes with no observed access outside their class. Enable
|
|
40
|
+
`rules: {internal-public-attribute: warning}`. Test access preserves visibility
|
|
41
|
+
without duplicating SMT430; exports and uncertain inheritance/framework
|
|
42
|
+
contracts remain protected. Renames stay manual. Implements
|
|
43
|
+
[#96](https://github.com/mathisarends/smelt/issues/96).
|
|
44
|
+
|
|
45
|
+
- Ship the official `smelt` agent skill with every wheel and source distribution,
|
|
46
|
+
including the complete offline rule, configuration and CLI reference. Install
|
|
47
|
+
with `smelt skill install`; refresh after upgrading with `--force`, which
|
|
48
|
+
replaces local edits and obsolete references. Use `--destination` to choose
|
|
49
|
+
another skill directory. See [agent skill installation](docs/cli.md#agent-skill).
|
|
50
|
+
Generated references are checked for drift in CI and release validation with
|
|
51
|
+
`python scripts/generate.py --check`. The bundle contains consumer guides and
|
|
52
|
+
rule pages; benchmark/evaluation data and maintainer documents stay in the repo.
|
|
53
|
+
|
|
54
|
+
- Optional [SMT334](docs/rules/SMT334.md) reviews private literal constants such
|
|
55
|
+
as `DownloadController._DOWNLOADABLE_EXTENSIONS` for placement at module scope.
|
|
56
|
+
Enable `rules: {private-class-constant: error}` to block them. Inherited and
|
|
57
|
+
decorated classes retain their attribute contracts; moves and reference updates
|
|
58
|
+
remain manual. Implements [#82](https://github.com/mathisarends/smelt/issues/82).
|
|
59
|
+
|
|
60
|
+
- Optional [SMT333](docs/rules/SMT333.md), enabled with
|
|
61
|
+
`rules: {prefer-callable-instance: hint}`, reviews classes with one public
|
|
62
|
+
instance method for `__call__` and an operation-based class name. Findings keep
|
|
63
|
+
constructor and call-time signatures separate. Existing callable APIs,
|
|
64
|
+
inheritance and decorated/protocol classes remain valid; no automatic rename.
|
|
65
|
+
|
|
66
|
+
- Declare canonical YAML extensions and Compose basenames once with
|
|
67
|
+
`structure.file_naming: {yaml_extension: yaml, compose_basename: compose}`.
|
|
68
|
+
[SMT331](docs/rules/SMT331.md) and [SMT332](docs/rules/SMT332.md) flag other
|
|
69
|
+
spellings throughout the project, including hidden configuration directories
|
|
70
|
+
and dotted Compose variants. Policies are optional, respect exclusions and
|
|
71
|
+
support staged checks; renames and reference updates remain manual.
|
|
72
|
+
Staged checks reuse YAML candidates from native Git-index capture, with an
|
|
73
|
+
independent flat-inventory fallback, instead of walking virtual directories.
|
|
74
|
+
|
|
75
|
+
## [0.5.0] - 2026-11-02
|
|
76
|
+
|
|
77
|
+
Report schema 2, YAML version 1 and the default rule set remain unchanged.
|
|
78
|
+
Debt writes now use grouped baseline version 2, which older Smelt versions cannot
|
|
79
|
+
read. Existing version-1 baselines remain readable; unscoped SMT321 debt needs
|
|
80
|
+
review and explicit re-recording. Update installation, hook and CI pins together
|
|
81
|
+
to `0.5.0` (`v0.5.0`) before rewriting baselines, and refresh the editor schema.
|
|
82
|
+
See the [upgrade checklist](docs/upgrading.md#040-to-050).
|
|
83
|
+
|
|
84
|
+
- Contributor checks now require an issue/ticket reference for TODO comments
|
|
85
|
+
through Ruff TD003. Tracked TODOs remain allowed; Smelt's rule catalog is unchanged.
|
|
86
|
+
|
|
87
|
+
- Document SMT317's activation and developer-facing extraction evidence with
|
|
88
|
+
concrete query-helper regressions. Inherited-class exclusions and the existing
|
|
89
|
+
advisory behavior are preserved; no duplicate static-method rule is added.
|
|
90
|
+
|
|
91
|
+
- Optional SMT329 (`rules: {caller-before-callee: hint}`) reviews step-down reading
|
|
92
|
+
order for direct same-visibility functions and ordinary methods. Recursive,
|
|
93
|
+
shadowed and definition-time-dependent pairs are retained; SMT313's public-first
|
|
94
|
+
categories take precedence. No definitions are moved automatically.
|
|
95
|
+
|
|
96
|
+
- Optional SMT328 (`rules: {redundant-dishka-provider: hint}`) reviews Dishka
|
|
97
|
+
provider methods that only forward dependencies to a constructor. Findings
|
|
98
|
+
include a direct registration candidate with recognized decorator options.
|
|
99
|
+
Resource factories and additional logic remain valid; no automatic rewrite.
|
|
100
|
+
|
|
101
|
+
- Optional SMT327 (`rules: {secret-settings-field: warning}`) reviews secret-named
|
|
102
|
+
Pydantic settings fields accepting plain `str`/`bytes`, including optional and
|
|
103
|
+
annotated types. Correct secret types and nonsecret names remain valid.
|
|
104
|
+
Findings omit default values; no annotations or consumers are rewritten.
|
|
105
|
+
|
|
106
|
+
- Optional SMT326 (`rules: {no-base-class-suffix: error}`) reviews class definitions
|
|
107
|
+
such as `_MessageBase`. SMT323 retains its existing prefix semantics. Imports,
|
|
108
|
+
aliases and test classes remain outside scope; no automatic rename.
|
|
109
|
+
|
|
110
|
+
- Optional SMT330 (`rules: {package-only-dunder-all: error}`) restricts module
|
|
111
|
+
`__all__` declarations to package `__init__.py` files. Package overrides and
|
|
112
|
+
reasoned suppressions retain deliberate compatibility exports; no automatic move.
|
|
113
|
+
|
|
114
|
+
- Optional SMT431 (`rules: {nondeterministic-test-data: warning}`) reviews known
|
|
115
|
+
random/UUID data generators in tests and fixtures. Prefer fixed test inputs or
|
|
116
|
+
seeded local generators; intentional randomness tests can retain reasoned
|
|
117
|
+
suppressions. Production generators are unaffected; no automatic rewrite.
|
|
118
|
+
|
|
119
|
+
- SMT108 now reviews mixed package-facade and implementation imports with
|
|
120
|
+
`bundle_imports_at: 2`, includes missing export proposals and blocks bundling
|
|
121
|
+
advice when proposed caller/facade edges close a known runtime import cycle.
|
|
122
|
+
|
|
123
|
+
- Debt baselines now write grouped JSON version 2: repeated rule/path/message
|
|
124
|
+
metadata appears once, while every accepted fingerprint and duplicate occurrence
|
|
125
|
+
remains available for matching. Version-1 files remain readable; `smelt debt
|
|
126
|
+
--prune` upgrades assessed entries without accepting new debt. Use `smelt debt
|
|
127
|
+
--show [PATHS]` for a compact, read-only baseline summary, or add `--format json`
|
|
128
|
+
for the grouped data. [SMT321](docs/rules/SMT321.md) now distinguishes enclosing
|
|
129
|
+
functions in debt and changed checks, so fixing one function cannot silently
|
|
130
|
+
accept an identical new violation in another. Old unscoped SMT321 debt requires
|
|
131
|
+
review and explicit re-recording. See [adoption](docs/adoption.md).
|
|
132
|
+
|
|
133
|
+
- Package contracts now support `module_docstrings: require`, activating
|
|
134
|
+
[SMT325](docs/rules/SMT325.md) `missing-module-docstring` for every analyzed
|
|
135
|
+
production module, including empty package initializers. Empty/blank docstrings
|
|
136
|
+
do not satisfy the requirement. Choose `forbid` for the existing
|
|
137
|
+
[SMT309](docs/rules/SMT309.md) convention; use a reasoned file suppression or an
|
|
138
|
+
explicit nested `allow` policy for exceptions. Defaults remain unchanged.
|
|
139
|
+
|
|
140
|
+
- Optional [SMT324](docs/rules/SMT324.md), enabled with
|
|
141
|
+
`rules: {prefer-str-enum-discriminator: hint}`, reviews single-string `Literal`
|
|
142
|
+
fields named `type`, `kind` or `tag` for shared `StrEnum` members. Keep narrow
|
|
143
|
+
`Literal[EventType.MEMBER]` annotations and matching enum defaults. This syntax
|
|
144
|
+
review does not prove union membership or rewrite code; Python targets before
|
|
145
|
+
3.11 and general multi-value Literals remain unchanged.
|
|
146
|
+
|
|
147
|
+
## [0.4.0] - 2026-11-01
|
|
148
|
+
|
|
149
|
+
Report schema 2, YAML version 1 and the default rule set remain unchanged.
|
|
150
|
+
Custom rules must update `BaseRule` imports to `Rule` and annotations for the
|
|
151
|
+
former `Rule` protocol to `RuleContract`. Update installation, hook and CI pins
|
|
152
|
+
together to `0.4.0` (`v0.4.0`) and refresh the editor schema. See the
|
|
153
|
+
[upgrade checklist](docs/upgrading.md#030-to-040).
|
|
154
|
+
|
|
155
|
+
- Use `.yml` consistently in configuration examples, fixtures and maintainer
|
|
156
|
+
scripts. `smelt init` now creates `smelt.yml`, which takes precedence when both
|
|
157
|
+
supported filenames exist. Existing `smelt.yaml` files still work. The published
|
|
158
|
+
`.pre-commit-hooks.yaml` manifest retains its required filename. Integration
|
|
159
|
+
instructions consistently use prek.
|
|
160
|
+
|
|
161
|
+
- Optional [SMT323](docs/rules/SMT323.md), enabled with
|
|
162
|
+
`rules: {no-base-class-prefix: error}`, rejects class definitions such as
|
|
163
|
+
`BaseRepository` and `_BaseRepository` in favor of responsibility-based names.
|
|
164
|
+
Imports, third-party inheritance, `Baseline` and `Base64` remain valid. Package
|
|
165
|
+
rule overrides can disable the convention; checks never rename symbols.
|
|
166
|
+
Smelt enables the convention for its own sources; the default set is unchanged.
|
|
167
|
+
- Smelt also enables the opt-in `deep-object-navigation` Law of Demeter review
|
|
168
|
+
for its own sources. Facade analysis receives its file inventory directly,
|
|
169
|
+
and filesystem/Python-target analysis receives its source store explicitly.
|
|
170
|
+
SMT322 recognizes statically evidenced module/data namespaces and known value
|
|
171
|
+
APIs, preserving unknown collaborator findings. Changes to imported record
|
|
172
|
+
definitions are considered on every check; no code is executed or rewritten.
|
|
173
|
+
Unproven namespaces remain advisory review candidates, with known receiver
|
|
174
|
+
types and the unresolved step included for agent API-contract review. A finding
|
|
175
|
+
alone does not require an architecture change.
|
|
176
|
+
- Rule implementations now inherit `smelt.rules.base.Rule` instead of `BaseRule`.
|
|
177
|
+
The former structural `Rule` protocol is named `RuleContract`; lazy rule
|
|
178
|
+
implementations retain the same interface. Update custom rule imports and
|
|
179
|
+
type annotations accordingly.
|
|
180
|
+
- Independent workspaces can share a local policy fragment with `extends` and
|
|
181
|
+
explicit child overrides. Mappings merge; lists replace, including `[]`.
|
|
182
|
+
Project paths remain relative to the selected workspace. `config show --sources`
|
|
183
|
+
explains effective inputs and origins; staged checks and cache dependencies
|
|
184
|
+
include all bases. Both published hooks now run on every commit, including
|
|
185
|
+
policy-only edits. See [shared configuration](docs/configuration.md#shared-local-policy).
|
|
186
|
+
|
|
187
|
+
- New opt-in [SMT322](docs/rules/SMT322.md) `deep-object-navigation` reviews
|
|
188
|
+
method calls reached through multiple stored instance attributes, such as
|
|
189
|
+
`self.browser.input.motor().aim()`. Enable with
|
|
190
|
+
`rules: {deep-object-navigation: hint}` or `--select SMT322`; package rule
|
|
191
|
+
overrides and inline suppressions preserve intentional navigation. Direct
|
|
192
|
+
collaborator calls, pure data reads and direct-collaborator fluent chains
|
|
193
|
+
remain quiet. This bounded syntax review has no automatic rewrite.
|
|
194
|
+
- [SMT901](docs/rules/SMT901.md) diagnoses unknown inline suppression identifiers,
|
|
195
|
+
including readable rule names where stable SMT codes are required. Known
|
|
196
|
+
inactive rules retain their narrowed-check behavior.
|
|
197
|
+
- [SMT426](docs/rules/SMT426.md) groups shared-helper operations by one repair in
|
|
198
|
+
text and adds deterministic `shared_helper` JSON groups. Individual findings,
|
|
199
|
+
identities, counts, suppressions and debt remain unchanged. [SMT424](docs/rules/SMT424.md)
|
|
200
|
+
explains known helper inference limits at the affected call sites.
|
|
201
|
+
- [SMT104](docs/rules/SMT104.md) adds the opt-in `cycles: [modules]` scope and
|
|
202
|
+
independent `type_checking_cycles: ignore`. Existing scopes are explicitly
|
|
203
|
+
labeled as aggregated; witnesses include edge phases. Default scopes stay unchanged.
|
|
204
|
+
- [SMT109](docs/rules/SMT109.md) accepts optional, statically verified
|
|
205
|
+
`structure.canonical_exports` ownership and distinguishes same-root/other-root
|
|
206
|
+
importers. Existing exports inform the review; frequency alone never expands API.
|
|
207
|
+
- Literal lazy-export tables with a matching guarded `import_module`/`getattr`
|
|
208
|
+
forwarder now contribute export identity and visibility evidence. Unsupported
|
|
209
|
+
dynamic handlers, escaped/mutated tables and type stubs alone remain unverified.
|
|
210
|
+
- [SMT313](docs/rules/SMT313.md) permits bounded ordering fixes around unrelated
|
|
211
|
+
nested-function dictionaries and `nonlocal` closure writes. Reflection on
|
|
212
|
+
unknown receivers or ordered namespaces retains its manual-review barrier.
|
|
213
|
+
|
|
214
|
+
- New opt-in [SMT321](docs/rules/SMT321.md) `implicit-optional-default`
|
|
215
|
+
reviews `parameter or fallback` for explicitly optional parameters with a
|
|
216
|
+
`None` default. Enable with `rules: {implicit-optional-default: warning}` or
|
|
217
|
+
`--select SMT321`. Use `--fix --unsafe-fixes` to replace it with an explicit
|
|
218
|
+
`is not None` conditional after reviewing intentional falsy defaults. Plain
|
|
219
|
+
`--fix` preserves existing truthiness behavior.
|
|
220
|
+
|
|
221
|
+
## [0.3.0] - 2026-11-01
|
|
222
|
+
|
|
223
|
+
### Upgrade first
|
|
224
|
+
|
|
225
|
+
**JSON consumers need an update.** Check and error documents now use schema 2.
|
|
226
|
+
Request `--show-coverage` for full coverage details and resolve
|
|
227
|
+
`expected.usage_scope_index` through the report's `usage_scopes` array. This is
|
|
228
|
+
a report-format change; YAML stays `version: 1`, and default rules, exit codes,
|
|
229
|
+
SMT codes and debt identities stay unchanged. See the
|
|
230
|
+
[upgrade checklist and compatible parser example](docs/upgrading.md).
|
|
231
|
+
|
|
232
|
+
Update tool, dependency, hook and CI pins together to `0.3.0` (Git tag `v0.3.0`),
|
|
233
|
+
then refresh `.smelt.schema.json`. Upgrading from 0.1.x also requires the
|
|
234
|
+
[configuration migration](docs/configuration.md#breaking-change-migration).
|
|
235
|
+
|
|
236
|
+
### New capabilities
|
|
237
|
+
|
|
238
|
+
| Capability | Enable / use | Details |
|
|
239
|
+
| --- | --- | --- |
|
|
240
|
+
| Review widely imported names missing from a package facade | Set a contract's `export_at` threshold; opt-in, hint severity | [SMT109](docs/rules/SMT109.md) |
|
|
241
|
+
| Review internal public constants and PEP 695 aliases | `rules: {internal-public-module-symbol: warning}`; opt-in | [SMT320](docs/rules/SMT320.md) |
|
|
242
|
+
| Get one-line findings with repair advice | `smelt check --format concise` | [CLI and reports](docs/cli.md) |
|
|
243
|
+
| Migrate existing installations and report consumers | Follow the release-specific checklist | [Upgrading](docs/upgrading.md) |
|
|
244
|
+
|
|
245
|
+
### Ordering and module visibility
|
|
246
|
+
|
|
247
|
+
- SMT313 now recognizes unions of unshadowed builtin types and `None` in eager
|
|
248
|
+
function annotations for declared Python 3.10+ targets, so a helper annotated
|
|
249
|
+
`str | bytes` no longer silently blocks public-first ordering on Python 3.12/3.13.
|
|
250
|
+
Imported/user-defined operands, shadowed names, explicit namespace mutations and unions in defaults remain
|
|
251
|
+
execution barriers. Inspect barriers with `check --format json --show-coverage`.
|
|
252
|
+
- New opt-in [SMT320](docs/rules/SMT320.md) `internal-public-module-symbol`
|
|
253
|
+
reviews single, unconditional uppercase module assignments and PEP 695 type
|
|
254
|
+
aliases with no observed external use or public-signature evidence. Enable it
|
|
255
|
+
with `rules: {internal-public-module-symbol: warning}` or `--select SMT320`.
|
|
256
|
+
Exports, imports/re-exports, test accesses, escaped modules and public annotation
|
|
257
|
+
dependencies preserve names. Dynamic namespaces and uncertain bindings are
|
|
258
|
+
skipped; external consumers remain unassessed. No automatic renaming.
|
|
259
|
+
- SMT311/SMT313 explanations clarify that Python 3.12/3.13 projects can retain
|
|
260
|
+
an annotations future import for forward references in their chosen public-first
|
|
261
|
+
order. Eager dependencies still take priority when the import is absent. `Self`
|
|
262
|
+
requires a subclass-preserving return contract; no automatic replacement of a
|
|
263
|
+
matching class-name annotation is suggested. See [definition ordering](docs/structure.md#definition-order-with-execution-dependencies).
|
|
264
|
+
|
|
265
|
+
### Test evidence and package contracts
|
|
266
|
+
|
|
267
|
+
- Opt-in SMT424/SMT425/SMT426 outcome and deadline reviews follow one direct call
|
|
268
|
+
to an unambiguous, undecorated, non-generator helper in the same file, including local async
|
|
269
|
+
helpers executed with `await` or `asyncio.run`. Assertions retain empty-loop
|
|
270
|
+
review, and hidden unbounded operations report their helper and call site.
|
|
271
|
+
Caller async deadlines guard async waits, never synchronous subprocesses.
|
|
272
|
+
Uncalled definitions, unexecuted coroutines, callbacks, imported helper bodies
|
|
273
|
+
and further helper calls remain outside inference; configured assertion helpers
|
|
274
|
+
continue to work. No analyzed code is executed.
|
|
275
|
+
- Overlapping test roots consistently assign a test to the most specific declared
|
|
276
|
+
root, independent of configuration order. Mirror checks retain separate
|
|
277
|
+
workspace-member roots.
|
|
278
|
+
- Package contracts can set `export_at` for SMT109 `facade-export-gap`: one
|
|
279
|
+
advisory finding per widely imported implementation name missing from its
|
|
280
|
+
facade, with definition location, importer lists, other re-exports and a bounded
|
|
281
|
+
cycle check. Tests count only with `count_tests: true`; type-checking-only
|
|
282
|
+
imports and uncertain exports are skipped. No automatic API or import changes.
|
|
283
|
+
See [facade reviews](docs/structure.md#suggestions-to-bundle-implementation-imports).
|
|
284
|
+
- Overlapping SMT108/SMT109 thresholds now choose the most specific pattern per
|
|
285
|
+
concrete package, removing duplicate hints and allowing exact overrides of
|
|
286
|
+
wildcard contracts. Equally specific conflicting settings are config errors.
|
|
287
|
+
|
|
288
|
+
### Reports, suppressions and fixes
|
|
289
|
+
|
|
290
|
+
- **JSON report schema 2:** `check --format json` emits a small coverage summary
|
|
291
|
+
by default; `--show-coverage` restores full policy details and the per-file
|
|
292
|
+
inventory. Repeated visibility boundaries move to report-level `usage_scopes`,
|
|
293
|
+
referenced by each finding's `expected.usage_scope_index`. Scope, comparison,
|
|
294
|
+
warnings and exit thresholds remain available. See [report compatibility](docs/cli.md).
|
|
295
|
+
- `check --format concise` prints one line per finding with repair advice.
|
|
296
|
+
Text omits empty details, prints visibility limits once, and groups related
|
|
297
|
+
late-import SMT313 findings with their affected lines. JSON keeps individual
|
|
298
|
+
findings plus an `ordering` group; debt fingerprints are retained.
|
|
299
|
+
- Inline suppressions follow logical continuation lines, including interior
|
|
300
|
+
comments in multiline assertions, formatted calls and signatures. Interior
|
|
301
|
+
import-name exceptions stay local and never cover neighboring names, the next
|
|
302
|
+
statement or a function body. Unused-suppression checks remain active. See
|
|
303
|
+
[suppression scope](docs/adoption.md).
|
|
304
|
+
- Visibility rules preserve public members of classes exported through static
|
|
305
|
+
package facades or `__all__`, including aliases and re-export chains; cache
|
|
306
|
+
invalidation tracks export changes. SMT429 distinguishes functions referenced
|
|
307
|
+
only by tests from helpers also used inside their module, without claiming
|
|
308
|
+
unassessed external consumers do not exist.
|
|
309
|
+
- Cache directories ignore their own contents. Init reports the number of tests
|
|
310
|
+
matching a mirror pattern, and ordinary text checks omit the policy coverage
|
|
311
|
+
banner without architecture (strict coverage still applies). Hook documentation
|
|
312
|
+
uses a pinned wheel installation and explains source-build requirements.
|
|
313
|
+
SMT311/SMT318 explanations clarify decorated annotations and Literal-typed
|
|
314
|
+
boundaries; SMT426's subprocess example explicitly sets `check=False`.
|
|
315
|
+
- Release checks enforce matching Python/native/lockfile versions, dated release
|
|
316
|
+
notes and current installation pins. Publication also waits for installation
|
|
317
|
+
smoke tests of the exact Linux x86_64, Windows x86_64 and macOS aarch64 wheels.
|
|
318
|
+
|
|
319
|
+
## [0.2.0] - 2026-10-31
|
|
320
|
+
|
|
321
|
+
- Visibility reviews (SMT316/SMT317/SMT429/SMT430) explicitly limit their claims to
|
|
322
|
+
analyzed callers and expose `usage_scope`, including exclusions and unassessed
|
|
323
|
+
maintainer scripts, unselected packages and external consumers. They do not
|
|
324
|
+
scan excluded code or infer that unobserved callers cannot exist.
|
|
325
|
+
- SMT313 fix refusals identify the triggering expression and source location in
|
|
326
|
+
`fix_blocker` and the human-readable reason, including inherited/decorated
|
|
327
|
+
classes, namespace inspection and nonliteral type variables. Existing safety
|
|
328
|
+
refusals are retained; skipped-fix output carries the same location.
|
|
329
|
+
- SMT425 recognizes locally assigned nonempty list/set/dict literals, including
|
|
330
|
+
annotations and aliases, and discards that evidence after possible mutations,
|
|
331
|
+
calls or branch merges. SMT424/SMT425 also recognize direct assertions in
|
|
332
|
+
statically known, checked `sys.executable -c` subprocesses. Unchecked exits,
|
|
333
|
+
optimized Python, dynamic scripts, files and potentially swallowed failures
|
|
334
|
+
remain outside recognition; subprocess review hints explain that boundary.
|
|
335
|
+
- Smelt now checks its own sources with public-first ordering, internal-member
|
|
336
|
+
visibility, test-only public API reviews, when-needed future annotations and
|
|
337
|
+
test-quality reviews. CI and release validation fail on warnings too. Internal
|
|
338
|
+
helpers are private, obsolete snapshot helpers are removed, and deliberate
|
|
339
|
+
primitive/cache tests carry local, reasoned exceptions. Consumer defaults stay
|
|
340
|
+
unchanged.
|
|
341
|
+
- SMT420 locates private imports on the imported name, including aliases in
|
|
342
|
+
multiline imports. A reasoned exception on that name now survives Ruff
|
|
343
|
+
formatting and does not suppress neighboring import lines; put multiline
|
|
344
|
+
import exceptions next to the affected name.
|
|
345
|
+
- Optional [SMT319](docs/rules/SMT319.md), enabled with
|
|
346
|
+
`rules: {prefer-package-import: hint}` or `--select SMT319`, suggests existing
|
|
347
|
+
package re-exports so callers can combine imports through a common `__init__.py`.
|
|
348
|
+
All names must have direct, unconditional public re-exports in analyzed code;
|
|
349
|
+
internal package imports and unscanned third-party packages are excluded.
|
|
350
|
+
Findings preserve aliases in their suggestions; checks never rewrite imports.
|
|
351
|
+
- Worker transport now acknowledges requests within 250 ms and bounds accepted
|
|
352
|
+
responses to five seconds, including partial output. Failures fall back to
|
|
353
|
+
foreground checking without repeating accepted requests. A watchdog and four
|
|
354
|
+
OS-owned worker slots bound background sessions; terminated workers release
|
|
355
|
+
capacity. Whole-process memory observations include helpers and Windows
|
|
356
|
+
launchers; the retained-state budget is not a total-process memory quota.
|
|
357
|
+
- Default cached staged checks read HEAD, the index and Git objects through a
|
|
358
|
+
persistent native reader, avoiding Git child-process starts. The reader supports
|
|
359
|
+
SHA-1/SHA-256, packed objects, linked worktrees, split indexes and alternate
|
|
360
|
+
commit indexes. Unsupported repositories, other Git overrides and reader
|
|
361
|
+
failures fall back to Git; `--no-cache` keeps independent reads. Workers also
|
|
362
|
+
retain bounded member dependency state, validating current inputs before reuse
|
|
363
|
+
and discarding borrowed state on failed updates. Worker requests are sent as
|
|
364
|
+
complete TCP frames. See the [paired CLI and complete-hook measurements](https://github.com/mathisarends/smelt/blob/main/docs/agent-workflow.md).
|
|
365
|
+
- Staged checks reuse verified policy blobs before parsing configuration, avoiding
|
|
366
|
+
a redundant Git blob subprocess after source edits. Policy changes still use
|
|
367
|
+
their captured object ID; `--no-cache` keeps independent reads. Paired Windows
|
|
368
|
+
CLI edit medians improve about 11%; complete-hook gains remain inconclusive.
|
|
369
|
+
- The installed CLI now uses a native Rust client and bounded local workers for
|
|
370
|
+
read-only checks. Fresh clients reuse imports, while every check captures current
|
|
371
|
+
Git/config inputs. CI, fixes and other commands stay in the foreground; worker
|
|
372
|
+
startup/transport failures fall back to checking. Workers restart when analyzer
|
|
373
|
+
identity changes and expire after 120 idle seconds. Source installs, including
|
|
374
|
+
pre-commit environments from Git, now require Rust; release wheels include the
|
|
375
|
+
compiled client. `python -m smelt` retains the direct Python entry point.
|
|
376
|
+
- Member-local checks maintain a persistent reverse dependency index and replace
|
|
377
|
+
only changed usage contributions. Unchanged decisions can be reused without
|
|
378
|
+
loading all definition objects. Removed callers, re-exports, missing namespaces,
|
|
379
|
+
inheritance and inventory changes remain part of invalidation.
|
|
380
|
+
|
|
381
|
+
- Checks select built-in rules using a generated lightweight catalog, loading only
|
|
382
|
+
the needed implementations. Staged results can survive edits to unobserved
|
|
383
|
+
content while preserving the current index hash in JSON/SARIF; additions,
|
|
384
|
+
deletions, observed source, config, metadata and debt still invalidate them.
|
|
385
|
+
Normal cached staged retries capture repository/HEAD and index in two Git
|
|
386
|
+
invocations. A separate benchmark measures a retained Python worker including
|
|
387
|
+
fresh client startup and IPC; it preceded the native client above.
|
|
388
|
+
See [the performance measurements](https://github.com/mathisarends/smelt/blob/main/docs/agent-workflow.md).
|
|
389
|
+
- Staged checks read captured Git blobs directly instead of writing temporary
|
|
390
|
+
source trees. An unchanged retry can reuse its exact result before loading the
|
|
391
|
+
analysis engine. Per-file import, member and test facts and selected findings
|
|
392
|
+
are reused across edits, with dependency-aware invalidation for callers,
|
|
393
|
+
re-exports and fixtures. `--no-cache` remains an independent check. See the
|
|
394
|
+
[paired CLI benchmarks and cache limits](https://github.com/mathisarends/smelt/blob/main/docs/agent-workflow.md).
|
|
395
|
+
- `architecture.imports.transitive: true` now checks arbitrary import chains for
|
|
396
|
+
layer, cross-feature, shared, composition-root and third-party policies, e.g.
|
|
397
|
+
`domain → shared.utils → sqlalchemy`. Findings include a deterministic shortest
|
|
398
|
+
chain with each hop's source line; `TYPE_CHECKING` policy applies at every hop.
|
|
399
|
+
The opt-in now follows all reachable module imports, including allowed layers
|
|
400
|
+
and unused facade exports, rather than just selected re-exports. External
|
|
401
|
+
packages remain leaves and the default is still direct imports only. Smelt's
|
|
402
|
+
own repository policy enables these checks. See
|
|
403
|
+
[SMT101](docs/rules/SMT101.md) and [SMT103](docs/rules/SMT103.md).
|
|
404
|
+
- **Breaking configuration API:** fixed source/test checks are enabled directly by
|
|
405
|
+
problem name in `rules`, with one value for activation and severity. Removed
|
|
406
|
+
`review_*`, assertion/private-import boolean flags, binary helper conventions,
|
|
407
|
+
`ordering.enabled` and the experimental preset. Public-first ordering needs an
|
|
408
|
+
explicit rule entry; options alone do not enable it. Package `rules` use the
|
|
409
|
+
same names and closest-package precedence. Stable SMT codes, debt identities
|
|
410
|
+
and architecture-policy activation are retained. See the complete
|
|
411
|
+
[migration table and developer-facing YAML API](docs/configuration.md).
|
|
412
|
+
- `--select` and `--ignore` accept the same canonical names as YAML and `explain`.
|
|
413
|
+
`context` reports effective rule severities for existing and planned modules.
|
|
414
|
+
Scoped-off debt is retained as unassessed when recording/pruning.
|
|
415
|
+
- `smelt init --maintainability` writes explicit individual checks, plus a local
|
|
416
|
+
`.smelt.schema.json` and YAML modeline. Editor completions, validation and hover
|
|
417
|
+
examples come from the real catalog and work offline. Plain `init` keeps its
|
|
418
|
+
conservative check selection. Existing configs can export `smelt config schema`
|
|
419
|
+
and add the modeline; see [editor setup](docs/configuration.md#editor-completion-hover-and-validation).
|
|
420
|
+
- Optional [SMT430](docs/rules/SMT430.md), enabled by
|
|
421
|
+
`rules: {test-only-public-attribute: warning}` or `--select SMT430`,
|
|
422
|
+
reviews public instance/class data attributes read only by tests outside their
|
|
423
|
+
class. Findings include test locations and a collision-free private name.
|
|
424
|
+
Possible production accesses and uncertain class contracts preserve visibility;
|
|
425
|
+
checks never rename code. Public-use rules now share the same member index,
|
|
426
|
+
export/import evidence and private-name suggestions. The new rule is off by
|
|
427
|
+
default and never renames code automatically.
|
|
428
|
+
- Optional [SMT318](docs/rules/SMT318.md), enabled with `rules: {SMT318: hint}`
|
|
429
|
+
or `--select SMT318`, reviews direct `StrEnum.MEMBER.value` reads for using the
|
|
430
|
+
string enum member directly. Known import aliases and analyzed re-exports are
|
|
431
|
+
supported; ordinary enums, uncertain bindings and instance inference are
|
|
432
|
+
excluded. Exact-string boundaries can still need a conversion, so findings
|
|
433
|
+
remain advisory and checks stay read-only. The default rule set is unchanged.
|
|
434
|
+
- `smelt check --staged` reviews the actual Git index against HEAD, using staged
|
|
435
|
+
source, configuration, Python metadata and debt. The new `smelt-staged` hook
|
|
436
|
+
blocks new warnings as well as errors, including findings in unchanged methods
|
|
437
|
+
whose last caller was removed. Partial staging and untracked files cannot hide
|
|
438
|
+
commit findings. JSON/SARIF distinguish staged scope from working-tree changes.
|
|
439
|
+
- Content-addressed JSON caches reuse complete analyses, per-file member facts
|
|
440
|
+
and the historical baseline. `--no-cache` recomputes independently. Member-use
|
|
441
|
+
analysis avoids repeated per-function tree walks; cache invalidation includes
|
|
442
|
+
contents, inventory, policy, Python targets and analyzer implementation. See
|
|
443
|
+
[the commit workflow and benchmark](https://github.com/mathisarends/smelt/blob/main/docs/agent-workflow.md). Changed/staged
|
|
444
|
+
snapshots reject symbolic links; staged fixes require editing and re-staging
|
|
445
|
+
working files explicitly.
|
|
446
|
+
- SMT316 feedback explains how to retain a deliberate public API with a reasoned
|
|
447
|
+
`# smelt: ignore[SMT316] -- ...` comment on its definition. Existing suppression
|
|
448
|
+
reason and unused-suppression checks continue to apply with caching.
|
|
449
|
+
|
|
450
|
+
- Optional [SMT316](docs/rules/SMT316.md), enabled with
|
|
451
|
+
`rules: {internal-public-member: warning}`, reviews public module functions and
|
|
452
|
+
ordinary instance methods with no observed external use, including unused
|
|
453
|
+
definitions. Findings suggest a private name and list internal uses/callbacks
|
|
454
|
+
so agents can review renames. Existing private names are avoided. Explicit
|
|
455
|
+
exports, decorators, inheritance and possible external method accesses preserve
|
|
456
|
+
public APIs; test-only public module functions remain covered by SMT429.
|
|
457
|
+
- Optional [SMT317](docs/rules/SMT317.md), enabled with
|
|
458
|
+
`rules: {internal-static-helper: hint}`, suggests extracting internal static helpers
|
|
459
|
+
to private module functions. Class dependencies, inheritance, extra decorators
|
|
460
|
+
and possible external callers preserve deliberate static APIs. Both new
|
|
461
|
+
rules support closest package `off` overrides and appear in `smelt context`.
|
|
462
|
+
Checks remain read-only and the default rule set is unchanged.
|
|
463
|
+
- Optional [SMT429](docs/rules/SMT429.md), enabled by
|
|
464
|
+
`rules: {test-only-public-function: warning}`, reviews public module functions
|
|
465
|
+
accessed from tests but not from other analyzed production modules. Findings
|
|
466
|
+
suggest a leading underscore and include test locations so agents can review
|
|
467
|
+
the rename and test the public caller. Explicit exports and decorated functions
|
|
468
|
+
stay public; external/dynamic consumers remain a review limitation. The default
|
|
469
|
+
rule set is unchanged.
|
|
470
|
+
|
|
471
|
+
## [0.1.6] - 2026-10-29
|
|
472
|
+
|
|
473
|
+
### Compatibility and activation
|
|
474
|
+
|
|
475
|
+
- SMT428 remains opt-in through `tests.review_async_mock_assertions`; the default
|
|
476
|
+
rule set is unchanged. Its findings ask for review of an individual test, not a
|
|
477
|
+
claim that the suite misses the regression.
|
|
478
|
+
- Existing `tests.review_test_deadlines` policies can now report additional known
|
|
479
|
+
asyncio subprocess waits. Review each operation's local deadline, including
|
|
480
|
+
cleanup paths, rather than adding a blanket timeout or await restriction.
|
|
481
|
+
|
|
482
|
+
### Added and fixed
|
|
483
|
+
|
|
484
|
+
- SMT426 now reviews `wait()` and `communicate()` on known asyncio subprocesses
|
|
485
|
+
created through awaited standard factories or explicit Process annotations.
|
|
486
|
+
Each operation needs its own local guard, including exit waits after bounded
|
|
487
|
+
reads or `kill()`. Unknown process-like objects remain outside scope.
|
|
488
|
+
- Optional SMT428 (`tests.review_async_mock_assertions`) reviews call-only checks
|
|
489
|
+
on known async mocks and async class-spec methods. Await assertions, deliberate
|
|
490
|
+
scheduling checks and synchronous methods remain valid. Known fixture specs and
|
|
491
|
+
simple local history values are traced without executing analyzed code; unknown
|
|
492
|
+
methods and general data flow remain outside scope. Executed missing-await
|
|
493
|
+
counterexamples demonstrate the distinction between call and await assertions.
|
|
494
|
+
- `context` text now shows all adopted test-quality review flags, including when
|
|
495
|
+
only the newer policies are enabled.
|
|
496
|
+
- SMT424 recognizes awaited, typed Event observations inside local timeout
|
|
497
|
+
contexts that raise on expiry, consistently with SMT426 deadline recognition.
|
|
498
|
+
Unused contexts, unawaited waits and `move_on_after` scopes are not outcome
|
|
499
|
+
evidence; configured timeout helpers alone still do not count as assertions.
|
|
500
|
+
|
|
501
|
+
## [0.1.5] - 2026-10-29
|
|
502
|
+
|
|
503
|
+
### Compatibility and activation
|
|
504
|
+
|
|
505
|
+
- Existing opted-in test policies can report additional MonkeyPatch operations
|
|
506
|
+
and known instance accesses. New SMT425-SMT427 review policies remain opt-in;
|
|
507
|
+
the small default rule set is unchanged. Review legitimate boundary tests
|
|
508
|
+
rather than exposing internals or imposing a global mock ban.
|
|
509
|
+
- `--fail-on warning` now includes configuration warnings, and unused
|
|
510
|
+
`pytest.raises`/`warns` context objects no longer count as outcome evidence.
|
|
511
|
+
A passing static report is not proof of test effectiveness.
|
|
512
|
+
|
|
513
|
+
### Added and fixed
|
|
514
|
+
|
|
515
|
+
- `scripts/evaluate.py` supports repeatable agent review loops: compare two import
|
|
516
|
+
roots on identical config bytes, retain
|
|
517
|
+
structured recognition changes and independently bounded logs, then optionally
|
|
518
|
+
execute explicitly selected pytest targets. Invalid analysis, timeouts and
|
|
519
|
+
incomplete collection remain distinct from test failures; normal checks never
|
|
520
|
+
execute analyzed tests. See the [evaluation workflow](docs/testing.md#evaluate-a-test-quality-change).
|
|
521
|
+
- Test outcome review now recognizes known mock interaction assertions, annotated
|
|
522
|
+
fixture receivers and awaited, bounded asyncio Event observations. Unused
|
|
523
|
+
`pytest.raises`/`warns` context objects no longer count as checks. Unknown
|
|
524
|
+
`assert_*` methods and fixture execution alone remain insufficient evidence.
|
|
525
|
+
- [SMT420](docs/rules/SMT420.md) tracks direct known production constructors and
|
|
526
|
+
explicitly typed instance reads, including analyzed facade re-exports and
|
|
527
|
+
consistent known fixture return/yield tuple components. Unknown/conflicting
|
|
528
|
+
outputs, private writes and local fakes are excluded; fixture inference has
|
|
529
|
+
separate provenance and respects class/conftest scope. A private class import
|
|
530
|
+
is not reported again for each public instance operation.
|
|
531
|
+
[SMT421–SMT423](docs/rules/SMT422.md) now include MonkeyPatch attribute
|
|
532
|
+
replacement, aliases and context scopes, with operation/provenance metadata.
|
|
533
|
+
MonkeyPatch environment/mapping setup is excluded from the mock count.
|
|
534
|
+
- Optional [SMT425](docs/rules/SMT425.md), [SMT426](docs/rules/SMT426.md) and
|
|
535
|
+
[SMT427](docs/rules/SMT427.md) review potentially vacuous outcomes, known waits
|
|
536
|
+
without deadlines/scheduler-clock replacements, and small independent-case loop
|
|
537
|
+
candidates. They remain advisory and require explicit test policies; no fixer,
|
|
538
|
+
blanket mock/sleep ban or assertion quota is introduced.
|
|
539
|
+
- Configuration warnings now appear in JSON `configuration_diagnostics`, SARIF
|
|
540
|
+
configuration notifications, GitHub annotations and text summaries. They count
|
|
541
|
+
toward `summary.warnings` and `--fail-on warning`, including scoped/changed
|
|
542
|
+
checks; rule selection, suppressions and debt cannot hide configuration warnings.
|
|
543
|
+
|
|
544
|
+
## [0.1.4] - 2026-10-29
|
|
545
|
+
|
|
546
|
+
### Migration: rule activation changed
|
|
547
|
+
|
|
548
|
+
- Only **SMT301, SMT901, SMT902 and SMT903** run by default. Declaring an
|
|
549
|
+
architecture, package or test policy activates the corresponding checks without
|
|
550
|
+
a second enable switch. The catalog now distinguishes 4 default, 24 policy-driven
|
|
551
|
+
and 2 explicitly selected rules; activation and severity are separate.
|
|
552
|
+
- **SMT104 import cycles and SMT305 unclassified-module hints require explicit
|
|
553
|
+
selection.** To retain these checks from earlier versions, add:
|
|
554
|
+
|
|
555
|
+
```yaml
|
|
556
|
+
rules:
|
|
557
|
+
SMT104: error
|
|
558
|
+
SMT305: warning
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
- `--select SMT3` and `--select ALL` activate matching opt-in checks and replace
|
|
562
|
+
normal selection. Explicit `off` settings and ignores still win; selection does
|
|
563
|
+
not invent missing policies. Strict coverage remains mandatory when configured
|
|
564
|
+
or requested, even outside the selected rule prefix.
|
|
565
|
+
- `smelt init` still proposes architecture but leaves naming conventions and test
|
|
566
|
+
mirroring disabled for review. A detected mirror pattern remains available as a
|
|
567
|
+
setting, with an activation comment.
|
|
568
|
+
- Debt for inactive or hint-only rules is retained when recording/pruning, rather
|
|
569
|
+
than silently considered resolved. Older cycle and indirect-import debt can
|
|
570
|
+
resurface because corrected fingerprints track the actual dependency. Review
|
|
571
|
+
these findings before recording new debt.
|
|
572
|
+
|
|
573
|
+
### Added
|
|
574
|
+
|
|
575
|
+
| Capability | Rules / interface | What agents can now check |
|
|
576
|
+
| --- | --- | --- |
|
|
577
|
+
| Strict architecture coverage | [SMT306](docs/rules/SMT306.md), `project.coverage: strict`, `--strict-coverage` | Production files outside package selection, missing architecture roles and exclusions without reasons. These gaps cannot be hidden by changed/path filters, suppressions or debt. |
|
|
578
|
+
| Package structure and public APIs | [SMT107](docs/rules/SMT107.md), [SMT307](docs/rules/SMT307.md) | Required modules and explicit public entry points through `structure.contracts`; outside callers cannot import private implementation modules. |
|
|
579
|
+
| Import fanout | [SMT108](docs/rules/SMT108.md) | Optional hints when one outside caller imports too many distinct modules from the same contracted package. |
|
|
580
|
+
| Source conventions | [SMT308](docs/rules/SMT308.md)–[SMT312](docs/rules/SMT312.md) | Scoped absolute/relative import styles, module-docstring policy, future-annotation policy and private module/package names. Python targets come from declared metadata or configuration. |
|
|
581
|
+
| Definition order | [SMT313](docs/rules/SMT313.md) | Dependency-aware module/class ordering, including execution barriers and bounded, explicitly requested fixes. |
|
|
582
|
+
| Instance field assignments | [SMT314](docs/rules/SMT314.md) | Bundled or chained writes to multiple direct instance attributes when `instance_assignments: separate` is declared. |
|
|
583
|
+
| Type dispatch | [SMT315](docs/rules/SMT315.md) | Review hints for same-subject `isinstance`/`elif` chains under a declared `type_dispatch` policy. |
|
|
584
|
+
| Test quality | [SMT420](docs/rules/SMT420.md)–[SMT424](docs/rules/SMT424.md) | Configured private production access, forbidden mocks, string patch targets, per-test patch limits and missing recognized outcome assertions. |
|
|
585
|
+
|
|
586
|
+
- `smelt context <path> --format json` explains ownership, coverage status,
|
|
587
|
+
applicable contracts, effective conventions and Python targets for existing or
|
|
588
|
+
planned files. Planned placement is distinguished from analyzed source.
|
|
589
|
+
- `check --show-coverage` exposes the per-file policy inventory. JSON reports add
|
|
590
|
+
discovery roots, classification counts, policy references, exclusions and a
|
|
591
|
+
policy hash. Rule metadata exposes activation, analysis requirements and
|
|
592
|
+
configuration paths through `rules`, `explain` and reports.
|
|
593
|
+
- Contributor documentation and catalog checks verify explicit registration,
|
|
594
|
+
unique rule codes/names, complete metadata and generated documentation.
|
|
595
|
+
- Tag-triggered PyPI Trusted Publishing validates the tag/version and main
|
|
596
|
+
ancestry, runs checks, builds and smoke-tests both distributions, then publishes
|
|
597
|
+
the validated artifacts without a stored PyPI API token.
|
|
598
|
+
|
|
599
|
+
### Fixed
|
|
600
|
+
|
|
601
|
+
- Resolve named re-exports across layer, feature, shared and composition-root
|
|
602
|
+
boundaries. Indirect findings retain the final forbidden target; declared
|
|
603
|
+
feature wiring no longer produces false unknown-layer findings.
|
|
604
|
+
- Track every cyclic architecture edge and semantic identities/multiplicity in
|
|
605
|
+
changed/debt comparisons. New edges, patches or ordering inversions cannot hide
|
|
606
|
+
behind an accepted aggregate finding. Existing violations do not become new
|
|
607
|
+
merely because an import's formatting, comment or alias changed.
|
|
608
|
+
- Merge namespace package portions, reject duplicate module definitions and infer
|
|
609
|
+
usable workspace source roots. Grouped imports check every alias, and source
|
|
610
|
+
discovery avoids symlink cycles.
|
|
611
|
+
- Reject duplicate YAML keys and invalid source encoding. With `--format json`,
|
|
612
|
+
usage/configuration/analysis errors return structured error documents; reports
|
|
613
|
+
identify their origin and comparison scope. SARIF and GitHub paths are rebased
|
|
614
|
+
correctly for nested configurations.
|
|
615
|
+
|
|
616
|
+
### Agent workflow and limits
|
|
617
|
+
|
|
618
|
+
```bash
|
|
619
|
+
smelt rules --format json
|
|
620
|
+
smelt context path/to/module.py --format json
|
|
621
|
+
smelt check --changed --base origin/main --format json
|
|
622
|
+
smelt check --strict-coverage --show-coverage --format json
|
|
623
|
+
smelt explain SMT313 --format json
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
- Normal checks are read-only. After configuring ordering with `fix: safe-only`,
|
|
627
|
+
`smelt check --select SMT313 --fix` can apply bounded definition moves. It
|
|
628
|
+
preserves source trivia, validates the permitted AST moves and refuses unsafe
|
|
629
|
+
or concurrently changed files. Run the project formatter afterwards.
|
|
630
|
+
- SMT314 and SMT315 have no automatic rewrite. Splitting assignments or converting
|
|
631
|
+
type dispatch can change evaluation, guards and fallthrough.
|
|
632
|
+
- Coverage means policy assignment within declared discovery roots, not a proof
|
|
633
|
+
of behavior. Package APIs and test-quality checks are static and do not infer
|
|
634
|
+
dynamic imports, arbitrary runtime access or fixture dependency effects.
|
|
635
|
+
- Import fanout, match suggestions and missing-assertion checks are review aids;
|
|
636
|
+
their default severities differ. Configure policy and severity deliberately.
|
|
637
|
+
|
|
638
|
+
[Unreleased]: https://github.com/mathisarends/smelt/compare/v0.6.0...HEAD
|
|
639
|
+
[0.6.0]: https://github.com/mathisarends/smelt/compare/v0.5.0...v0.6.0
|
|
640
|
+
[0.5.0]: https://github.com/mathisarends/smelt/compare/v0.4.0...v0.5.0
|
|
641
|
+
[0.4.0]: https://github.com/mathisarends/smelt/compare/v0.3.0...v0.4.0
|
|
642
|
+
[0.3.0]: https://github.com/mathisarends/smelt/compare/v0.2.0...v0.3.0
|
|
643
|
+
[0.2.0]: https://github.com/mathisarends/smelt/compare/v0.1.6...v0.2.0
|
|
644
|
+
[0.1.6]: https://github.com/mathisarends/smelt/compare/v0.1.5...v0.1.6
|
|
645
|
+
[0.1.5]: https://github.com/mathisarends/smelt/compare/v0.1.4...v0.1.5
|
|
646
|
+
[0.1.4]: https://github.com/mathisarends/smelt/compare/v0.1.3...v0.1.4
|