tuner-testkit 4.3.0__tar.gz → 5.0.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.
- {tuner_testkit-4.3.0/tuner_testkit.egg-info → tuner_testkit-5.0.0}/PKG-INFO +10 -2
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/README.md +9 -1
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/pyproject.toml +6 -2
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/__init__.py +1 -1
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_mock/store.py +2 -3
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/build.py +12 -1
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/cli.py +48 -42
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/agents/bdd-asset-pipeline.md +3 -1
- tuner_testkit-5.0.0/tuner_testkit/apps/dna/dna_payload/.cursor/agents/sut-self-learning.md +72 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/agents/sut-source-to-design.md +3 -1
- tuner_testkit-5.0.0/tuner_testkit/apps/dna/dna_payload/.cursor/rules/agent-task-log.mdc +22 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/apps-authoring.mdc +15 -13
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/bdd-asset-layering.mdc +3 -3
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/commit-convention.mdc +3 -2
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/index-hygiene.mdc +6 -3
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/explore-sut/SKILL.md +5 -1
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/maintain-index/SKILL.md +14 -1
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/maintain-page-objects/SKILL.md +2 -2
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/AGENTS.md +12 -5
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/MANIFEST.txt +1 -1
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/action-words-syntax.md +13 -13
- tuner_testkit-5.0.0/tuner_testkit/apps/dna/dna_payload/docs/spec/agent-task-log.md +70 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/api-objects-syntax.md +3 -3
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/apps-authoring-syntax.md +9 -7
- tuner_testkit-5.0.0/tuner_testkit/apps/dna/dna_payload/docs/spec/artifacts-layout.md +94 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/commit-convention.md +3 -1
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/page-objects-syntax.md +2 -1
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/sut-self-learning.md +6 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/dna/dna_payload/tools/git-hooks/README.md +32 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/dna/dna_payload/tools/git-hooks/pre-commit +19 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/dna/dna_payload/tools/git-hooks/secret_scan.py +145 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/tools/git-hooks/validate_commit_msg.py +12 -1
- tuner_testkit-5.0.0/tuner_testkit/apps/dna/targets.py +182 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/tests/test_cli.py +3 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/dna/tests/test_targets.py +62 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/evidence/persist.py +25 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/index_ai/registry.py +30 -10
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/scaffold.py +45 -9
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/INDEX.project.md +82 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/behave.ini +23 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/config/env.py +1 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/data/sut-accounts.example.yaml +18 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/gitignore +36 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/packages/api_objects/registry.py +3 -4
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/tests/features/api_environment.py +49 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/tests/features/api_steps/given.py +1 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/tests/features/api_steps/then.py +1 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/tests/features/api_steps/when.py +1 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/tests/features/ui_environment.py +70 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/tests/features/ui_steps/given.py +1 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/tests/features/ui_steps/then.py +1 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/tests/features/ui_steps/when.py +1 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/stubs/tests/pytest/conftest.py +53 -0
- tuner_testkit-5.0.0/tuner_testkit/apps/init_repo/tests/test_git_hooks.py +70 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/tests/test_scaffold.py +16 -0
- tuner_testkit-4.3.0/tuner_testkit/apps/mock_server/plane.py → tuner_testkit-5.0.0/tuner_testkit/apps/mock_server/tool.py +13 -20
- tuner_testkit-5.0.0/tuner_testkit/artifacts.py +274 -0
- tuner_testkit-5.0.0/tuner_testkit/catalog/__init__.py +20 -0
- tuner_testkit-5.0.0/tuner_testkit/catalog/build.py +109 -0
- tuner_testkit-5.0.0/tuner_testkit/catalog/front_matter.py +259 -0
- tuner_testkit-5.0.0/tuner_testkit/catalog/scan.py +499 -0
- tuner_testkit-5.0.0/tuner_testkit/catalog/tests/test_build.py +95 -0
- tuner_testkit-5.0.0/tuner_testkit/catalog/tests/test_front_matter.py +60 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/registry.py +2 -2
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/project.py +17 -1
- tuner_testkit-5.0.0/tuner_testkit/tools/__init__.py +44 -0
- tuner_testkit-5.0.0/tuner_testkit/tools/manifest.py +482 -0
- tuner_testkit-5.0.0/tuner_testkit/tools/tests/test_manifest.py +102 -0
- tuner_testkit-5.0.0/tuner_testkit/workspace/__init__.py +1 -0
- tuner_testkit-5.0.0/tuner_testkit/workspace/__main__.py +3 -0
- tuner_testkit-5.0.0/tuner_testkit/workspace/cli.py +145 -0
- tuner_testkit-5.0.0/tuner_testkit/workspace/index_render.py +175 -0
- tuner_testkit-5.0.0/tuner_testkit/workspace/tests/test_index_render.py +63 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0/tuner_testkit.egg-info}/PKG-INFO +10 -2
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit.egg-info/SOURCES.txt +36 -16
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit.egg-info/entry_points.txt +1 -1
- tuner_testkit-4.3.0/tuner_testkit/action_words/plane.py +0 -83
- tuner_testkit-4.3.0/tuner_testkit/apps/_shared/plane.py +0 -25
- tuner_testkit-4.3.0/tuner_testkit/apps/_shared/plane_app.py +0 -296
- tuner_testkit-4.3.0/tuner_testkit/apps/_shared/plane_asset.py +0 -147
- tuner_testkit-4.3.0/tuner_testkit/apps/_shared/tests/test_plane_asset.py +0 -124
- tuner_testkit-4.3.0/tuner_testkit/apps/_shared/tests/test_plane_collect.py +0 -45
- tuner_testkit-4.3.0/tuner_testkit/apps/dna/dna_payload/tools/git-hooks/README.md +0 -28
- tuner_testkit-4.3.0/tuner_testkit/apps/index_platform/__init__.py +0 -9
- tuner_testkit-4.3.0/tuner_testkit/apps/index_platform/__main__.py +0 -29
- tuner_testkit-4.3.0/tuner_testkit/apps/index_platform/build.py +0 -63
- tuner_testkit-4.3.0/tuner_testkit/apps/index_platform/catalog.py +0 -228
- tuner_testkit-4.3.0/tuner_testkit/apps/index_platform/plane.py +0 -29
- tuner_testkit-4.3.0/tuner_testkit/apps/index_platform/tests/test_catalog.py +0 -29
- tuner_testkit-4.3.0/tuner_testkit/apps/init_repo/stubs/behave.ini +0 -18
- tuner_testkit-4.3.0/tuner_testkit/apps/init_repo/stubs/packages/api_objects/plane.py +0 -14
- tuner_testkit-4.3.0/tuner_testkit/apps/init_repo/stubs/packages/page_objects/plane.py +0 -14
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/LICENSE +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/setup.cfg +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/action_words/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/action_words/__main__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/action_words/_internal/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/action_words/_internal/api.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/action_words/_internal/db.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/action_words/_internal/generators.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/action_words/_internal/ids.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/action_words/_internal/wait.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/action_words/base.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/action_words/context.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/action_words/registry.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_mock/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_mock/app.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_mock/errors.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_mock/router.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_mock/spec.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_objects/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_objects/auth.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_objects/recording/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_objects/recording/capture.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_objects/recording/codegen.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_objects/recording/freeze.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_objects/recording/mocks.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_objects/recording/normalize.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_objects/recording/pipeline.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_objects/recording/sanitize.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_test/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_test/client.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_test/errors.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_test/jsonpath.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/api_test/model.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/_shared/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/_shared/changelog.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/api_recorder/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/api_recorder/__main__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/api_recorder/addon.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/api_recorder/cli.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/api_recorder/playwright_tap.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/api_recorder/tests/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/api_recorder/tests/test_addon.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/__main__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/hooks/sync_registry.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/hooks.json +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/apps-handover.mdc +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/assets-knowledge.mdc +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/bdd-pipeline-gates.mdc +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/bdd-stage-layout.mdc +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/explore-safety.mdc +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/packages-db.mdc +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/packages-fake.mdc +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/packages-logging.mdc +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/packages-page-test.mdc +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/analyze-mcp-network/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/create-action-word/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/create-app/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/derive-design-knowledge/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/derive-feature-sets/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/dump-ddl/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/feature-authoring/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/feature-review-lint/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/freeze-api-objects/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/maintain-behave-steps/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/release-template/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/reuse-analysis/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/run-feature-playwright-mcp/SKILL.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/assets-knowledge-syntax.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/bdd-run-gherkin-in-playwrightMCP.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/behave-gerkin-syntax.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/behave-step-definitions.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/design-knowledge-syntax.md +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/tools/git-hooks/commit-msg +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/dna_payload/tools/git-hooks/pre-push +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/paths.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dna/source.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/dump_ddl.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/evidence/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/evidence/__main__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/evidence/cli.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/evidence/tests/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/evidence/tests/test_cli.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/evidence/tests/test_persist.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/index_ai/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/index_ai/__main__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/__main__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/manifest.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/apps/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/packages/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/packages/action_words/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/packages/action_words/_internal/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/packages/action_words/_internal/params.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/packages/action_words/models.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/packages/api_objects/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/packages/api_objects/auth.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/packages/api_objects/recording/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/packages/page_objects/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/init_repo/stubs/packages/page_objects/session.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/mock_server/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/mock_server/__main__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/mock_server/cli.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/mock_server/seed.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/page_recorder/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/page_recorder/__main__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/page_recorder/capture.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/page_recorder/cli.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/page_recorder/codegen.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/page_recorder/freeze.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/page_recorder/inject.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/page_recorder/session.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/page_recorder/tests/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/page_recorder/tests/test_capture.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/page_recorder/tests/test_cli.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/page_recorder/tests/test_freeze.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/recorder/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/recorder/__main__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/recorder/cli.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/recorder/tests/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/apps/recorder/tests/test_cli.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/config.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/db/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/db/client.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/db/connection.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/excel/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/excel/workbook.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/fake/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/fake/__main__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/fake/catalog.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/fake/china.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/fake/cli.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/fake/core.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/fake/medical.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/fake/wrappers.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/logging/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/logging/context.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/logging/core.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/logging/helpers.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/logging/hooks.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/logging/scenario_file.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/__init__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/__main__.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/base.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/driver.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/errors.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/harvest.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/health.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/locator.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/model.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/session.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/steps.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit/page_test/testing.py +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit.egg-info/dependency_links.txt +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit.egg-info/requires.txt +0 -0
- {tuner_testkit-4.3.0 → tuner_testkit-5.0.0}/tuner_testkit.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tuner-testkit
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0.0
|
|
4
4
|
Summary: Shared test runtime, recorders, and DNA overlay for SUT test repos
|
|
5
5
|
Author: tuner-testkit contributors
|
|
6
6
|
License-Expression: MIT
|
|
@@ -167,6 +167,10 @@ git add -A && git commit
|
|
|
167
167
|
|
|
168
168
|
`tuner-dna check` 核对项目树 DNA 是否与**当前 PATH 上那份** kit 一致。建议先 `uv tool upgrade`,再 `sync`,避免 CLI 还是旧包、`.venv` 已是新包。
|
|
169
169
|
|
|
170
|
+
**其他 AI IDE**:DNA 以 Cursor 布局为源,`tuner-dna sync --ide claude,agents`(或 `all`)把 skills 渲染到
|
|
171
|
+
`.claude/skills/` / `.agents/skills/`、subagents 到 `.claude/agents/`,并生成 `CLAUDE.md`(`@AGENTS.md` + always-on 规则内联 + 路径规则清单)。
|
|
172
|
+
`tuner-dna targets` 列出各目标落点;hooks.json 不跨工具翻译。目录约定随各工具文档变动,用前核对。
|
|
173
|
+
|
|
170
174
|
新仓第一次仍用第 2 节的 `tuner-init scaffold`(会写依赖并做一次 `tuner-dna sync`),不是每次发版都重新 scaffold。
|
|
171
175
|
|
|
172
176
|
`[phone-ui]` 为预留空 extra,4.0 未实现。
|
|
@@ -210,4 +214,8 @@ uv sync --extra all
|
|
|
210
214
|
|
|
211
215
|
`uv sync --extra dev` 与 `--extra all` 等价(`dev` 只是引用 `[all]`)。
|
|
212
216
|
|
|
213
|
-
|
|
217
|
+
本仓是**平台仓**,不是 workspace。`dogfood/` 是用 `tuner-init scaffold dogfood --no-ai` 生成的 workspace 示范
|
|
218
|
+
(被测系统 = 平台本身,uv workspace 成员,共用 `.venv`):路线图在 `dogfood/assets/domain-notes/platform/roadmap.md`,
|
|
219
|
+
验收活文档在 `dogfood/tests/features/`。见 [`dogfood/README.md`](dogfood/README.md)。
|
|
220
|
+
|
|
221
|
+
5.0.0 发行说明(Plane Job 协议退场、`tuner-workspace`)见 [`docs/changelog/TEMPLATE-5.0.0.md`](docs/changelog/TEMPLATE-5.0.0.md);4.3.0 见 [`TEMPLATE-4.3.0.md`](docs/changelog/TEMPLATE-4.3.0.md);3.x → 4.x 迁移见 [`TEMPLATE-4.0.0.md`](docs/changelog/TEMPLATE-4.0.0.md)。平台能力地图见 [`INDEX.md`](INDEX.md)。
|
|
@@ -122,6 +122,10 @@ git add -A && git commit
|
|
|
122
122
|
|
|
123
123
|
`tuner-dna check` 核对项目树 DNA 是否与**当前 PATH 上那份** kit 一致。建议先 `uv tool upgrade`,再 `sync`,避免 CLI 还是旧包、`.venv` 已是新包。
|
|
124
124
|
|
|
125
|
+
**其他 AI IDE**:DNA 以 Cursor 布局为源,`tuner-dna sync --ide claude,agents`(或 `all`)把 skills 渲染到
|
|
126
|
+
`.claude/skills/` / `.agents/skills/`、subagents 到 `.claude/agents/`,并生成 `CLAUDE.md`(`@AGENTS.md` + always-on 规则内联 + 路径规则清单)。
|
|
127
|
+
`tuner-dna targets` 列出各目标落点;hooks.json 不跨工具翻译。目录约定随各工具文档变动,用前核对。
|
|
128
|
+
|
|
125
129
|
新仓第一次仍用第 2 节的 `tuner-init scaffold`(会写依赖并做一次 `tuner-dna sync`),不是每次发版都重新 scaffold。
|
|
126
130
|
|
|
127
131
|
`[phone-ui]` 为预留空 extra,4.0 未实现。
|
|
@@ -165,4 +169,8 @@ uv sync --extra all
|
|
|
165
169
|
|
|
166
170
|
`uv sync --extra dev` 与 `--extra all` 等价(`dev` 只是引用 `[all]`)。
|
|
167
171
|
|
|
168
|
-
|
|
172
|
+
本仓是**平台仓**,不是 workspace。`dogfood/` 是用 `tuner-init scaffold dogfood --no-ai` 生成的 workspace 示范
|
|
173
|
+
(被测系统 = 平台本身,uv workspace 成员,共用 `.venv`):路线图在 `dogfood/assets/domain-notes/platform/roadmap.md`,
|
|
174
|
+
验收活文档在 `dogfood/tests/features/`。见 [`dogfood/README.md`](dogfood/README.md)。
|
|
175
|
+
|
|
176
|
+
5.0.0 发行说明(Plane Job 协议退场、`tuner-workspace`)见 [`docs/changelog/TEMPLATE-5.0.0.md`](docs/changelog/TEMPLATE-5.0.0.md);4.3.0 见 [`TEMPLATE-4.3.0.md`](docs/changelog/TEMPLATE-4.3.0.md);3.x → 4.x 迁移见 [`TEMPLATE-4.0.0.md`](docs/changelog/TEMPLATE-4.0.0.md)。平台能力地图见 [`INDEX.md`](INDEX.md)。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tuner-testkit"
|
|
3
|
-
version = "
|
|
3
|
+
version = "5.0.0"
|
|
4
4
|
description = "Shared test runtime, recorders, and DNA overlay for SUT test repos"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -69,7 +69,7 @@ tuner-mock-server = "tuner_testkit.apps.mock_server.cli:main"
|
|
|
69
69
|
tuner-dna = "tuner_testkit.apps.dna.cli:main"
|
|
70
70
|
tuner-init = "tuner_testkit.apps.init_repo.__main__:main"
|
|
71
71
|
tuner-index-ai = "tuner_testkit.apps.index_ai.__main__:main"
|
|
72
|
-
tuner-
|
|
72
|
+
tuner-workspace = "tuner_testkit.workspace.cli:main"
|
|
73
73
|
tuner-fake = "tuner_testkit.fake.cli:main"
|
|
74
74
|
tuner-page-test = "tuner_testkit.page_test.__main__:main"
|
|
75
75
|
tuner-action-words = "tuner_testkit.action_words.__main__:main"
|
|
@@ -90,6 +90,10 @@ include = ["tuner_testkit*"]
|
|
|
90
90
|
build_py = "tuner_testkit.apps.dna.build.BuildPyWithDna"
|
|
91
91
|
sdist = "tuner_testkit.apps.dna.build.SdistWithDna"
|
|
92
92
|
|
|
93
|
+
[tool.uv.workspace]
|
|
94
|
+
# dogfood/ is a workspace scaffolded by `tuner-init` from this repo (SUT = the platform itself).
|
|
95
|
+
members = ["dogfood"]
|
|
96
|
+
|
|
93
97
|
[tool.tuner-testkit]
|
|
94
98
|
page_objects = "packages/page_objects"
|
|
95
99
|
api_objects = "packages/api_objects"
|
|
@@ -6,9 +6,8 @@ Two layers:
|
|
|
6
6
|
* **overrides** — whatever the admin API changed since startup.
|
|
7
7
|
|
|
8
8
|
Overrides win on read and stay in memory until :meth:`MockStore.persist` writes
|
|
9
|
-
them out. That split is deliberate: the
|
|
10
|
-
response without the server writing into the checked-out repo
|
|
11
|
-
``tuner_testkit/apps/index_platform/README.md`` — catalog jobs do not write git).
|
|
9
|
+
them out. That split is deliberate: a test platform or the workbench must be able
|
|
10
|
+
to redefine a response without the server writing into the checked-out repo.
|
|
12
11
|
"""
|
|
13
12
|
from __future__ import annotations
|
|
14
13
|
|
|
@@ -31,8 +31,19 @@ def _payload_ready(root: Path | None = None) -> bool:
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
def _bundle() -> None:
|
|
34
|
+
"""Refresh ``dna_payload`` from the template tree when building a wheel.
|
|
35
|
+
|
|
36
|
+
A leftover ``dna_payload/`` from an older build must not short-circuit:
|
|
37
|
+
that shipped stale DNA (4.3.0 payload inside a 4.4.0 wheel).
|
|
38
|
+
"""
|
|
34
39
|
_ensure_src_on_path()
|
|
35
|
-
|
|
40
|
+
from tuner_testkit.project import template_source_root
|
|
41
|
+
|
|
42
|
+
if template_source_root() is None:
|
|
43
|
+
if not _payload_ready():
|
|
44
|
+
raise RuntimeError(
|
|
45
|
+
"no DNA payload in this install and no template checkout to bundle from"
|
|
46
|
+
)
|
|
36
47
|
return
|
|
37
48
|
|
|
38
49
|
from tuner_testkit.apps.dna.cli import cmd_bundle
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import argparse
|
|
6
|
-
import hashlib
|
|
7
6
|
import json
|
|
8
7
|
import shutil
|
|
9
8
|
import sys
|
|
@@ -16,43 +15,39 @@ from tuner_testkit.apps.dna.source import (
|
|
|
16
15
|
iter_dna_files,
|
|
17
16
|
payload_package_dir,
|
|
18
17
|
)
|
|
18
|
+
from tuner_testkit.apps.dna.targets import (
|
|
19
|
+
TARGET_LAYOUTS,
|
|
20
|
+
diff_file_map,
|
|
21
|
+
parse_targets,
|
|
22
|
+
render_target,
|
|
23
|
+
write_file_map,
|
|
24
|
+
)
|
|
19
25
|
from tuner_testkit.project import ProjectRootError, project_root
|
|
20
26
|
|
|
21
27
|
|
|
22
|
-
def _hash_bytes(data: bytes) -> str:
|
|
23
|
-
return hashlib.sha256(data).hexdigest()
|
|
24
|
-
|
|
25
|
-
|
|
26
28
|
def _target_root(explicit: str | None) -> Path:
|
|
27
29
|
if explicit:
|
|
28
30
|
return Path(explicit).expanduser().resolve()
|
|
29
31
|
return project_root()
|
|
30
32
|
|
|
31
33
|
|
|
34
|
+
def _targets(args: argparse.Namespace) -> list[str]:
|
|
35
|
+
return parse_targets(getattr(args, "ide", None))
|
|
36
|
+
|
|
37
|
+
|
|
32
38
|
def cmd_sync(args: argparse.Namespace) -> int:
|
|
33
39
|
try:
|
|
34
40
|
source = dna_source_root()
|
|
35
41
|
dest = _target_root(args.target)
|
|
36
|
-
|
|
42
|
+
targets = _targets(args)
|
|
43
|
+
except (DnaSourceError, ProjectRootError, ValueError) as exc:
|
|
37
44
|
print(str(exc), file=sys.stderr)
|
|
38
45
|
return 2
|
|
39
46
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if dst.exists() and not args.overwrite:
|
|
45
|
-
if dst.is_file() and src.read_bytes() == dst.read_bytes():
|
|
46
|
-
skipped += 1
|
|
47
|
-
continue
|
|
48
|
-
if dst.is_file() and not args.overwrite:
|
|
49
|
-
skipped += 1
|
|
50
|
-
continue
|
|
51
|
-
dst.parent.mkdir(parents=True, exist_ok=True)
|
|
52
|
-
shutil.copy2(src, dst)
|
|
53
|
-
copied += 1
|
|
54
|
-
print(f"copy {rel}")
|
|
55
|
-
print(f"dna sync: copied={copied} skipped={skipped} dest={dest}")
|
|
47
|
+
for target in targets:
|
|
48
|
+
files = render_target(source, target)
|
|
49
|
+
copied, skipped = write_file_map(dest, files, overwrite=args.overwrite)
|
|
50
|
+
print(f"dna sync[{target}]: copied={copied} skipped={skipped} dest={dest}")
|
|
56
51
|
marker = dest / ".tuner-dna-version"
|
|
57
52
|
marker.write_text(_kit_version() + "\n", encoding="utf-8")
|
|
58
53
|
return 0
|
|
@@ -62,28 +57,33 @@ def cmd_check(args: argparse.Namespace) -> int:
|
|
|
62
57
|
try:
|
|
63
58
|
source = dna_source_root()
|
|
64
59
|
dest = _target_root(args.target)
|
|
65
|
-
|
|
60
|
+
targets = _targets(args)
|
|
61
|
+
except (DnaSourceError, ProjectRootError, ValueError) as exc:
|
|
66
62
|
print(str(exc), file=sys.stderr)
|
|
67
63
|
return 2
|
|
68
64
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
missing.append(rel)
|
|
65
|
+
drifted = False
|
|
66
|
+
for target in targets:
|
|
67
|
+
missing, changed = diff_file_map(dest, render_target(source, target))
|
|
68
|
+
if not missing and not changed:
|
|
69
|
+
print(f"DNA[{target}] matches installed kit payload.")
|
|
75
70
|
continue
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
print(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
71
|
+
drifted = True
|
|
72
|
+
for rel in missing:
|
|
73
|
+
print(f" [{target}] missing: {rel}", file=sys.stderr)
|
|
74
|
+
for rel in changed:
|
|
75
|
+
print(f" [{target}] changed: {rel}", file=sys.stderr)
|
|
76
|
+
if drifted:
|
|
77
|
+
print("Run `tuner-dna sync --overwrite [--ide <targets>]` to refresh platform DNA.", file=sys.stderr)
|
|
78
|
+
return 1
|
|
79
|
+
return 0
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def cmd_targets(_args: argparse.Namespace) -> int:
|
|
83
|
+
for name, layout in TARGET_LAYOUTS.items():
|
|
84
|
+
print(f"{name:8s} skills={layout.skills_dir or '-':16s} agents={layout.agents_dir or '-':16s} "
|
|
85
|
+
f"instructions={layout.instructions_file or '-':10s} {layout.note}")
|
|
86
|
+
return 0
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
def cmd_bundle(_args: argparse.Namespace) -> int:
|
|
@@ -123,19 +123,25 @@ def _kit_version() -> str:
|
|
|
123
123
|
def main(argv: list[str] | None = None) -> int:
|
|
124
124
|
parser = argparse.ArgumentParser(
|
|
125
125
|
prog="tuner-dna",
|
|
126
|
-
description="Sync
|
|
126
|
+
description="Sync AI-IDE / git DNA from tuner-testkit into a project repo (Cursor by default; --ide for others).",
|
|
127
127
|
)
|
|
128
128
|
sub = parser.add_subparsers(dest="cmd", required=True)
|
|
129
|
+
ide_help = "comma-separated IDE targets: cursor (default), claude, agents, codex, all"
|
|
129
130
|
|
|
130
|
-
p_sync = sub.add_parser("sync", help="copy DNA files into the project")
|
|
131
|
+
p_sync = sub.add_parser("sync", help="copy / render DNA files into the project")
|
|
131
132
|
p_sync.add_argument("--target", default=None, help="project root (default: cwd project)")
|
|
132
133
|
p_sync.add_argument("--overwrite", action="store_true", help="overwrite differing files")
|
|
134
|
+
p_sync.add_argument("--ide", default=None, help=ide_help)
|
|
133
135
|
p_sync.set_defaults(func=cmd_sync)
|
|
134
136
|
|
|
135
137
|
p_check = sub.add_parser("check", help="report DNA drift vs the kit payload")
|
|
136
138
|
p_check.add_argument("--target", default=None)
|
|
139
|
+
p_check.add_argument("--ide", default=None, help=ide_help)
|
|
137
140
|
p_check.set_defaults(func=cmd_check)
|
|
138
141
|
|
|
142
|
+
p_targets = sub.add_parser("targets", help="list IDE targets and where each renders")
|
|
143
|
+
p_targets.set_defaults(func=cmd_targets)
|
|
144
|
+
|
|
139
145
|
p_bundle = sub.add_parser("bundle", help="copy DNA into the wheel payload directory")
|
|
140
146
|
p_bundle.set_defaults(func=cmd_bundle)
|
|
141
147
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bdd-asset-pipeline
|
|
3
|
-
version: 2.0.
|
|
3
|
+
version: 2.0.1
|
|
4
4
|
description: Lower-half of SUT self-learning — Feature Sets + design knowledge → Reuse Analysis → Freeze API Objects → Maintain Page Objects → Maintain Steps → behave regression. Use only for behave/BDD automation assets. Do NOT use when the user explicitly requests pytest. Do NOT use this agent as the explore-first entry; start from docs/spec/sut-self-learning.md instead.
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -104,3 +104,5 @@ Before writing Then-assertions, **read `assets/design/**`**:
|
|
|
104
104
|
- `behave --stage ui` succeeds for UI features that exist.
|
|
105
105
|
- `behave --stage api` succeeds for API features that exist (or `--dry-run`
|
|
106
106
|
with documented TODO).
|
|
107
|
+
- Task log written to `artifacts/inbox/` per `docs/spec/agent-task-log.md`
|
|
108
|
+
(no secrets).
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sut-self-learning
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: Orchestrate explore-first SUT self-learning — accounts → Playwright MCP explore → evidence → freeze API/page objects → design knowledge → index, with an artifacts/inbox task log. Hand off to bdd-asset-pipeline only when Feature Sets are in scope. Do NOT use when the user explicitly requests pytest-only work.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# SUT self-learning orchestrator (upper half + optional handoff)
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
串起「学习被测 Web 系统并生长测试资产」的**上半程**。规格
|
|
12
|
+
`docs/spec/sut-self-learning.md`。本文件是可执行编排;规格不是本 agent 的替代。
|
|
13
|
+
|
|
14
|
+
**下半程**(已有 feature set → steps / behave)交给
|
|
15
|
+
`.cursor/agents/bdd-asset-pipeline.md`,不要在本 agent 里硬造 Gherkin,除非用户明确要验收自动化。
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
- 工程师说「探索 SUT / 学习某某模块 / 生成测试资产 / 再跑一轮自学习」。
|
|
20
|
+
- 下游仓已有 `tuner-init` 骨架,SUT 可访问。
|
|
21
|
+
|
|
22
|
+
## Inputs
|
|
23
|
+
|
|
24
|
+
1. `INDEX.md` + 若存在 `INDEX.project.md`(已有切片、勿重复冻登录接口)。
|
|
25
|
+
2. **账号**(只读,禁止拷进仓库/evidence/inbox):
|
|
26
|
+
1. `data/sut-accounts.local.yaml`(gitignore,首选)
|
|
27
|
+
2. 否则 `config/env_local.py` 的 `TEST_ACCOUNT`
|
|
28
|
+
3. 都没有则停,让工程师按 `data/sut-accounts.example.yaml` 补本机文件
|
|
29
|
+
3. 垂直切片(一个模块,不是全站爬)。
|
|
30
|
+
4. 可选:SUT 源码根(如 Plane `apps/api`)——有则跑 `sut-source-to-design`。
|
|
31
|
+
|
|
32
|
+
## Skills / agents(顺序)
|
|
33
|
+
|
|
34
|
+
| 步 | 组件 | 产出 |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| 0 | 读账号 + `explore-safety` | 登录参数(内存) |
|
|
37
|
+
| 1 | `dump-ddl`(缺表才跑,禁 `--all`) | `assets/ddl/<ds>/` |
|
|
38
|
+
| 2 | `explore-sut` | `artifacts/evidence/<run_id>/` + `assets/explore/` |
|
|
39
|
+
| 3 | `analyze-mcp-network`(`tuner-evidence routes`) | 路由表 JSON |
|
|
40
|
+
| 4 | `reuse-analysis` | 复用 vs 新建 |
|
|
41
|
+
| 5 | `freeze-api-objects` | `packages/api_objects/`(跳过 sign-in) |
|
|
42
|
+
| 6 | `maintain-page-objects` | `packages/page_objects/` |
|
|
43
|
+
| 7 | `derive-design-knowledge`;有源码则 **`sut-source-to-design`** | `assets/design/` |
|
|
44
|
+
| 8 | `maintain-index` | `INDEX.project.md` 或 `INDEX.md` |
|
|
45
|
+
| 9 | **本 agent** 写 inbox | `artifacts/inbox/<utc>-sut-self-learning-<slice>.md` |
|
|
46
|
+
| 10 | 仅当用户要 `.feature` | `derive-feature-sets` → **`bdd-asset-pipeline`** |
|
|
47
|
+
|
|
48
|
+
每步先 **Read** 对应 `SKILL.md` / agent 正文再执行。不要跳过 evidence 落盘。
|
|
49
|
+
|
|
50
|
+
## Inbox(强制)
|
|
51
|
+
|
|
52
|
+
遵循 `docs/spec/agent-task-log.md`。SUT 自学习日志 **必须**含:
|
|
53
|
+
|
|
54
|
+
- `## Pages explored`(url pattern / title / 按钮)
|
|
55
|
+
- `## Assets added this run`(本任务新增或更新的 api/page/explore/design/ddl)
|
|
56
|
+
- `run_id`;`account_id`(无密码)
|
|
57
|
+
- 若这是第 N 轮 dogfood:`## Loop delta` 对比上一轮 inbox / 平台能力
|
|
58
|
+
|
|
59
|
+
## Hard rules
|
|
60
|
+
|
|
61
|
+
- 活体 SUT:`explore-safety`(throwaway 数据;不问不准删)。
|
|
62
|
+
- 密钥不入库、不进 evidence、不进 inbox。
|
|
63
|
+
- Web cookie session 的 path 占位用 `{workspace_slug}` 等,调用走 `set_path`。
|
|
64
|
+
- 页面资产 app 名对齐现有 `packages/page_objects/<app>/`,勿与装饰器模块重名。
|
|
65
|
+
- 未走 Gate 1 证据不得写 api/page/design。
|
|
66
|
+
|
|
67
|
+
## Done
|
|
68
|
+
|
|
69
|
+
- evidence 在磁盘且已脱敏。
|
|
70
|
+
- 切片的 explore +(若有写操作)design 已引用 `run_id`。
|
|
71
|
+
- 新路由已冻或书面说明跳过原因。
|
|
72
|
+
- inbox 已落盘,页面清单与资产增量齐全。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sut-source-to-design
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.1
|
|
4
4
|
description: Walk SUT backend source (Django models/views/serializers, or equivalent) plus assets/ddl to draft assets/design/<app>/<route-slug>.md. Use when the engineer points at a source tree. Do not invent tables. Complements derive-design-knowledge; this agent is the source-channel playbook.
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -31,3 +31,5 @@ Highest-quality `writes` / `noise` / `reads` often come from **models.save / vie
|
|
|
31
31
|
- `confidence: inferred` for source-only; `observed` only with DB/log evidence.
|
|
32
32
|
- No secrets.
|
|
33
33
|
- Do not generate action words here.
|
|
34
|
+
- Write `artifacts/inbox/<utc>-sut-source-to-design-<slice>.md` per
|
|
35
|
+
`docs/spec/agent-task-log.md` (outputs = design files; no secrets).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Every agent run must leave a task log under artifacts/inbox/ (no secrets).
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Agent task log — `artifacts/inbox/`
|
|
8
|
+
|
|
9
|
+
每次按 `.cursor/agents/*.md` 编排执行(含 SUT 自学习),结束前必须写一份任务记录。
|
|
10
|
+
细则见 `docs/spec/agent-task-log.md`。
|
|
11
|
+
|
|
12
|
+
## Must
|
|
13
|
+
|
|
14
|
+
- 路径:`artifacts/inbox/<UTC>-<agent>-<slice>.md`(例 `20260914T031200Z-sut-self-learning-cycles.md`)。
|
|
15
|
+
- 必填:`agent`、意图、输入、产出文件列表、下一步。
|
|
16
|
+
- **SUT 自学习**额外必填:本次探索的页面(url pattern + 标题)、本次新增/更新的测试资产路径。
|
|
17
|
+
- 只写 `account_id` / workspace slug,**禁止**密码、token、Cookie。
|
|
18
|
+
|
|
19
|
+
## Must not
|
|
20
|
+
|
|
21
|
+
- 用聊天摘要代替 inbox 落盘。
|
|
22
|
+
- 把 inbox 当 evidence(网络 dump 仍走 `artifacts/evidence/<run_id>/`)。
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
description: SUT apps/ and kit tuner_testkit.apps tools must be standalone-runnable and reuse tuner_testkit plus this repo's packages business assets; no reinventing wheels, no secrets, not imported by tests
|
|
3
3
|
globs: apps/**,tuner_testkit/apps/**
|
|
4
4
|
alwaysApply: false
|
|
5
|
-
version:
|
|
5
|
+
version: 2.0.0
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# apps — 创建期约束
|
|
@@ -30,18 +30,20 @@ version: 1.4.0
|
|
|
30
30
|
- 不得被 `tests/` import(复用逻辑下沉到 `packages/` 业务资产或 `tuner_testkit`)。
|
|
31
31
|
- 不得写入 token / cookie / 密码 / Authorization / session 等敏感值。
|
|
32
32
|
- 破坏性操作无开关、默认非 dry-run/只读 → 禁止。
|
|
33
|
-
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
`
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
33
|
+
- 造数 / API / UI 动作不得做成伪 app:写成 action word(`@register` 后自动进目录与工作台)。
|
|
34
|
+
|
|
35
|
+
## 工作台可见 vs 本地维护
|
|
36
|
+
|
|
37
|
+
- **工作台可见**(团队成员要在 `tuner-workbench` 里填参运行):提供 import-safe 的
|
|
38
|
+
`apps/<name>/tool.py`,用 `tuner_testkit.tools.tool(tool_id=..., name=..., module="apps.<name>", group=...,
|
|
39
|
+
destructive=..., timeout=...)` 装饰 `build_parser`;`tuner-workspace catalog` 据此导出
|
|
40
|
+
`params_schema` / `argv_plan`。每个参数必须有 `help`(即表单 label);破坏性工具声明 `destructive=True`
|
|
41
|
+
且 CLI 默认 dry-run。
|
|
42
|
+
- **本地维护**(工程师跑完再 commit,产物进 git;如 dump_ddl / recorder / init_repo / index_ai):
|
|
43
|
+
不写 `tool.py`,或写了但 `visibility="local"`。
|
|
44
|
+
- 发现器只 import `apps/*/tool.py` 与 kit 的 `tuner_testkit/apps/*/tool.py`;`cli.py` 可以较重,
|
|
45
|
+
但 `tool.py` 及其 import 的模块禁止顶层 import DB 驱动 / Playwright / mitmproxy。
|
|
46
|
+
- 需要机器可读输出时用 `--json` envelope(`status / outputs[] / artifacts[] / log_path`),见规范 §7。
|
|
45
47
|
|
|
46
48
|
## 相关
|
|
47
49
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
description: Enforce layered boundaries between feature/steps/action_words/page_objects/api_objects and tuner_testkit runtime; no selector or request leakage across layers
|
|
3
3
|
globs: **/*.py
|
|
4
4
|
alwaysApply: false
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.4.0
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Asset Layering — boundary rules per layer
|
|
@@ -43,8 +43,8 @@ Each layer owns one responsibility. Leakage across layers (e.g. selectors in ste
|
|
|
43
43
|
- **No secrets in repo**, ever: `Authorization`, `Cookie`, `Set-Cookie`, `*token*`, `*secret*`, `*password*`, `*session*`. Also applies to captures under `artifacts/evidence/`.
|
|
44
44
|
- **Evidence-driven edits**: Page/API object changes must be backed by Playwright MCP snapshots, `tuner-recorder` / `tuner-api-recorder` captures (`python -m tuner_testkit.apps.recorder` / `api_recorder`), or run_summary findings; avoid locator/path guesses.
|
|
45
45
|
- **`tests/**` must not import `apps.*`**. Action words for BDD/pytest stay in
|
|
46
|
-
`tuner_testkit.action_words
|
|
47
|
-
`
|
|
46
|
+
`tuner_testkit.action_words`; every `@register`ed word is already listed by
|
|
47
|
+
`tuner-workspace catalog` and runnable from the workbench — do not wrap them as `apps.*`.
|
|
48
48
|
|
|
49
49
|
## Examples
|
|
50
50
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Commits must follow Conventional Commits with a layer-aligned scope; the declared scope must cover the layers actually changed. Single source of truth is docs/spec/commit-convention.md.
|
|
3
3
|
alwaysApply: true
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# 提交规范(Conventional Commits + 六层 scope)
|
|
@@ -12,7 +12,8 @@ version: 1.0.0
|
|
|
12
12
|
- `type` ∈ `feat|fix|refactor|docs|test|perf|chore|build|ci|style|revert`。
|
|
13
13
|
- `scope` 用**对齐六层/资产类别**的值:`assets / apps / packages / api_objects /
|
|
14
14
|
page_objects / action_words / tests / docs / rules / skills / agents / hooks /
|
|
15
|
-
init_repo / index`(多层用逗号分隔,如 `feat(apps,packages):
|
|
15
|
+
init_repo / index / dogfood`(多层用逗号分隔,如 `feat(apps,packages): ...`;
|
|
16
|
+
`dogfood/**` 一律用 `dogfood`)。
|
|
16
17
|
- **scope 必须覆盖本次真实改动涉及的层**(`packages` 是三个子资产层的上位 scope)。
|
|
17
18
|
|
|
18
19
|
一眼可读优先:让人从提交信息就看出"更新了 assets、新增了 apps、录制了新的 api_objects"等。
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Keep the repo-level INDEX.md current and require managed assets to leave a changelog trail; index is the discovery entry for humans and the LLM
|
|
3
|
-
globs: assets/**,packages/api_objects/**,packages/page_objects/**,apps/**,tuner_testkit/apps
|
|
3
|
+
globs: assets/**,packages/api_objects/**,packages/page_objects/**,apps/**,tuner_testkit/apps/**,dogfood/assets/**,dogfood/packages/**,dogfood/apps/**,dogfood/INDEX.project.md
|
|
4
4
|
alwaysApply: false
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.3.0
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# index-hygiene — 索引与留痕纪律
|
|
9
9
|
|
|
10
10
|
根 `INDEX.md` 是**平台**能力地图(发现入口)。若存在 `INDEX.project.md`,那是试验田 / 下游项目仓的**业务资产**地图;两份索引都必须与各自职责范围内的仓库状态一致。
|
|
11
|
+
平台仓内的 `dogfood/` 是用 scaffold 生成的 workspace,它的业务地图是 `dogfood/INDEX.project.md`。
|
|
11
12
|
|
|
12
13
|
## 留痕(changelog trail)
|
|
13
14
|
|
|
@@ -21,7 +22,9 @@ version: 1.1.3
|
|
|
21
22
|
|
|
22
23
|
## 增量维护(省 token)
|
|
23
24
|
|
|
24
|
-
-
|
|
25
|
+
- 索引里 `<!-- auto:begin:<zone> -->` 围栏内的区块由 `tuner-workspace index render` 从
|
|
26
|
+
`artifacts/catalogs/workspace.json` 确定性渲染,**禁止手写**;CI 跑 `tuner-workspace index check`。
|
|
27
|
+
- 围栏外的人工区更新 `INDEX.md` 时**优先读各区 `CHANGELOG` 的 delta**,据此补条目;
|
|
25
28
|
**不要为维护索引而全量读取 `assets/ddl/*.sql` 正文**。
|
|
26
29
|
- AI 组件区(`.cursor/**`)不手写进 `INDEX.md`:由 `python -m tuner_testkit.apps.index_ai`
|
|
27
30
|
确定性生成 `.cursor/REGISTRY.md`,`INDEX.md` 只链接过去。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: explore-sut
|
|
3
|
-
version: 1.
|
|
3
|
+
version: 1.2.0
|
|
4
4
|
description: Explore-first Playwright MCP session against a live SUT. Produces sanitized artifacts/evidence/<run_id>/ plus assets/explore capability notes. Use when learning a web SUT, mapping pages/buttons, or gathering evidence before any .feature exists. Do NOT use when the user already has a feature to implement — use run-feature-playwright-mcp instead.
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -23,6 +23,10 @@ description: Explore-first Playwright MCP session against a live SUT. Produces s
|
|
|
23
23
|
## Steps
|
|
24
24
|
|
|
25
25
|
1. Read `INDEX.md` and `INDEX.project.md` if present. Note base URLs from `config`.
|
|
26
|
+
Load login from **`data/sut-accounts.local.yaml`** if it exists; else
|
|
27
|
+
`config/env_local.py` `TEST_ACCOUNT`. Copy `data/sut-accounts.example.yaml`
|
|
28
|
+
when neither exists and **stop**. Never write the password into evidence,
|
|
29
|
+
explore notes, inbox, or git.
|
|
26
30
|
2. Pick a **vertical slice** (e.g. workspace → project → issue), not a full-site crawl.
|
|
27
31
|
3. Navigate with Playwright MCP. After each meaningful action, dump network + snapshot.
|
|
28
32
|
4. Persist with **`tuner-evidence persist`** (do not leave captures only in chat):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: maintain-index
|
|
3
3
|
description: Updates the repo-level INDEX.md (knowledge/capability map) incrementally by reading changelog deltas, not full asset bodies. Use after new assets/tools/objects are added, or when INDEX.md drifts from reality.
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Maintain INDEX.md(增量、省 token)
|
|
@@ -13,6 +13,19 @@ version: 1.1.2
|
|
|
13
13
|
- **写范围**:`INDEX.md`;若 `INDEX.project.md` 存在则也可改它。AI 组件区不手写(见下)。
|
|
14
14
|
- **分流**:平台工具 / 公共 `packages` / AI 组件链接 → `INDEX.md`。业务 DDL / SQL / 用例 / explore / design / api_objects / page_objects / features → 有 `INDEX.project.md` 就写那里,不要把 SUT 明细填进 `INDEX.md`。
|
|
15
15
|
|
|
16
|
+
## 先跑确定性渲染,再做人工区
|
|
17
|
+
|
|
18
|
+
索引文件里被 `<!-- auto:begin:<zone> -->` … `<!-- auto:end:<zone> -->` 围起来的区块**不要手写**:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv run tuner-workspace catalog # 刷新 artifacts/catalogs/workspace.json
|
|
22
|
+
uv run tuner-workspace index render # 渲染 INDEX.project.md(无则 INDEX.md)的 auto 围栏
|
|
23
|
+
uv run tuner-workspace index check # CI:自动区过期则 exit 1
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
zone:`ddl` / `sql` / `assets` / `api_objects` / `page_objects` / `action_words` / `apps` / `features`。
|
|
27
|
+
本 skill 只负责围栏**之外**的人工区(用途一句话、confidence 采信说明、平台工具的交接文档链接等)。
|
|
28
|
+
|
|
16
29
|
## 核心原则:读 delta,不全量读
|
|
17
30
|
|
|
18
31
|
- **自动区**(`assets/ddl/`、`packages/api_objects/`、`packages/page_objects/` 等):**只读各区 `CHANGELOG` 的尾部增量**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: maintain-page-objects
|
|
3
|
-
version: 2.0
|
|
3
|
+
version: 2.1.0
|
|
4
4
|
description: Creates or updates page assets under packages/page_objects/ on the tuner_testkit.page_test runtime (PageModel element table + declarative flows, or BasePage escape hatch) following page-objects-syntax.md. Use when UI steps fail due to locators, new UI flows are needed, selector leakage must be removed from steps, or doctor reports locator rot.
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -50,7 +50,7 @@ description: Creates or updates page assets under packages/page_objects/ on the
|
|
|
50
50
|
- 每个 flow 带 `description` 与 `example_params`(让 `run --example` 可一键跑)。
|
|
51
51
|
- 页面级 `asserts` / `extracts` 只放**页面自身的稳定契约**(`open()` 时执行);
|
|
52
52
|
flow 级断言写在该 flow 的 steps 里。
|
|
53
|
-
-
|
|
53
|
+
- 不需要任何装饰器就会出现在 `tuner-workspace catalog` 与工作台的只读页面清单里(静态扫描 `page_id`)。
|
|
54
54
|
|
|
55
55
|
## Quick validation(必须跑)
|
|
56
56
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- version: 1.
|
|
1
|
+
<!-- version: 1.5.0 -->
|
|
2
2
|
# AGENTS — 平台总入口(轻量 DM)
|
|
3
3
|
|
|
4
4
|
> 本文件是"repo as a platform"的**稳定世界观**:只写不常变的分层结构与角色。
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
| 测试层 | `tests/` | 自动化测试代码(behave `features/` + `pytest/`)。 | behave / pytest |
|
|
22
22
|
| 文档层 | `docs/` | 仓库使用说明与规范(`docs/spec/**`)。 | 只读 |
|
|
23
23
|
|
|
24
|
-
配套:`config/`(环境/数据源)、`.cursor/`(AI 组件,见下)、`artifacts/`·`logs
|
|
24
|
+
配套:`config/`(环境/数据源)、`.cursor/`(AI 组件,见下)、`artifacts/`·`logs/`(运行产出,规范 `docs/spec/artifacts-layout.md`:MCP evidence 落 `artifacts/evidence/<run_id>/`;agent 任务记录落 `artifacts/inbox/`;工具运行落 `artifacts/runs/<run_id>/`;回归报告落 `artifacts/reports/<run_id>/`,每个 run 目录带 `manifest.json`)。SUT 登录本机文件:`data/sut-accounts.local.yaml`(gitignore)。
|
|
25
25
|
|
|
26
26
|
## 2. 三角色
|
|
27
27
|
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
```mermaid
|
|
44
44
|
flowchart TD
|
|
45
45
|
Start[任务到达] --> Q{任务类型?}
|
|
46
|
-
Q -->|"学习被测系统 / 探索式测试"| Learn["SUT
|
|
46
|
+
Q -->|"学习被测系统 / 探索式测试"| Learn["SUT 自学习编排\n.cursor/agents/sut-self-learning.md"]
|
|
47
47
|
Q -->|"业务 UI/API 流自动化"| BDD["BDD 资产流水线(下半程)\n.cursor/agents/bdd-asset-pipeline.md"]
|
|
48
48
|
Q -->|"明确要求 pytest / 性能 / DB 核对"| Pytest["pytest 路径\n复用 tuner_testkit + packages,不产出 .feature"]
|
|
49
49
|
Q -->|"需要一个新的独立工具"| App["create-app skill\napps-authoring / apps-handover 规则"]
|
|
@@ -52,7 +52,7 @@ flowchart TD
|
|
|
52
52
|
Q -->|"读/策展/索引知识"| Idx["查 INDEX.md + maintain-index skill"]
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
- **学习被测系统** → `docs/spec/sut-self-learning.md
|
|
55
|
+
- **学习被测系统** → `.cursor/agents/sut-self-learning.md`(编排 explore → freeze → design;规格 `docs/spec/sut-self-learning.md`;任务 log 见 `docs/spec/agent-task-log.md`)。
|
|
56
56
|
- **业务 UI/API 流** → `.cursor/agents/bdd-asset-pipeline.md`(自学习的**下半程**;内部含三门禁,仅在此分支生效)。
|
|
57
57
|
- **明确 pytest** → 直接写 pytest,复用 `tuner_testkit` 与本仓 `packages/**` 业务资产,不要为满足分层而硬造 Gherkin。
|
|
58
58
|
- **造工具** → `create-app` skill;工具做好按 `apps-handover.mdc` 补交接文档。证据通道(日志/DB 日志取数)也落 `apps/`,遵守 CLI + JSON 输出约定。
|
|
@@ -65,11 +65,14 @@ flowchart TD
|
|
|
65
65
|
- 不得将 token / cookie / Authorization / 密码 / session 等敏感信息写入仓库(含 capture 与 api_objects)。
|
|
66
66
|
- 提交遵循 Conventional Commits + 六层 scope,见 `docs/spec/commit-convention.md`(`commit-msg` hook 会校验)。
|
|
67
67
|
- DB 只走 `tuner_testkit.db`,日志只走 `tuner_testkit.logging`(见对应 rule)。
|
|
68
|
-
- 密钥只放本机 `config/env_local.py` 或环境变量,**任何分支都不得提交**。多套 prd/uat/dev 写在 `env_local.ENVIRONMENTS` 里,用 `python -m tuner_testkit.config use <name>` 切换(或 `TUNER_ENV`)。
|
|
68
|
+
- 密钥只放本机 `config/env_local.py`、`data/**/*.local.yaml` 或环境变量,**任何分支都不得提交**。多套 prd/uat/dev 写在 `env_local.ENVIRONMENTS` 里,用 `python -m tuner_testkit.config use <name>` 切换(或 `TUNER_ENV`)。探索账号优先 `data/sut-accounts.local.yaml`(模板 `data/sut-accounts.example.yaml`)。
|
|
69
69
|
|
|
70
70
|
## 6. 分支与下游仓
|
|
71
71
|
|
|
72
72
|
本公开仓只维护**平台**:`tuner_testkit/`、`.cursor/**`、`docs/spec/**`、`INDEX.md`。
|
|
73
|
+
**本仓不是 workspace**:真正的个人 workspace 是 `tuner-init scaffold` 生成的下游仓。仓内 `dogfood/`
|
|
74
|
+
是用同一 scaffold 生成的 workspace 示范(被测系统 = 平台本身),存放路线图、验收剧本与活文档;
|
|
75
|
+
它是 uv workspace 成员,不带自己的 `.cursor/`(根 DNA 覆盖全树),提交 scope 用 `dogfood`。
|
|
73
76
|
|
|
74
77
|
| 分支 | 职责 | 谁改 |
|
|
75
78
|
| --- | --- | --- |
|
|
@@ -78,3 +81,7 @@ flowchart TD
|
|
|
78
81
|
- **下游 SUT 测试仓**用 `tuner-init scaffold` 从空白目录新建,用 `uv add tuner-testkit==x.y.z` + `tuner-dna sync` 取平台能力。业务资产(`assets/`、objects、features、`INDEX.project.md`)只活在下游仓。
|
|
79
82
|
- 试用中发现框架要改:在 `public-main` 改并提交(内循环可用 `uv tool install --from <this-repo>`);阶段收口打 tag 发 PyPI,下游再升级。
|
|
80
83
|
- 历史分支 `plane-dogfood` **退役**:分支式 dogfood 验不了 `tuner-init` + PyPI 全链。Plane 的业务测试仓是外部仓(如 `tuner-test-platform-testrepo`)。
|
|
84
|
+
- **「Plane」在本仓只指 dogfood 的被测系统**(plane.so 类项目管理产品)。曾经的 Plane Job / Sync 协议
|
|
85
|
+
(`@plane_app`、`@plane_*`、`index_platform`)已在 5.0.0 退场,对应能力中立化为 `tuner_testkit.tools`
|
|
86
|
+
(tool manifest)与 `tuner_testkit.catalog`(`tuner-workspace catalog`);云端拉取 workspace 属于 D 阶段,
|
|
87
|
+
见 `dogfood/assets/domain-notes/platform/roadmap.md`。
|