testerkit 0.4.0__py3-none-any.whl
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.
- testerkit/__init__.py +68 -0
- testerkit/_docs/_assets/operator-ui/channels/table.png +0 -0
- testerkit/_docs/_assets/operator-ui/dashboard/runs.png +0 -0
- testerkit/_docs/_assets/operator-ui/dashboard/stations.png +0 -0
- testerkit/_docs/_assets/operator-ui/events/filters.png +0 -0
- testerkit/_docs/_assets/operator-ui/events/table.png +0 -0
- testerkit/_docs/_assets/operator-ui/explore/chart.png +0 -0
- testerkit/_docs/_assets/operator-ui/explore/filters.png +0 -0
- testerkit/_docs/_assets/operator-ui/explore/plot-controls.png +0 -0
- testerkit/_docs/_assets/operator-ui/files/table.png +0 -0
- testerkit/_docs/_assets/operator-ui/launch/form.png +0 -0
- testerkit/_docs/_assets/operator-ui/metrics/filters.png +0 -0
- testerkit/_docs/_assets/operator-ui/metrics/pareto.png +0 -0
- testerkit/_docs/_assets/operator-ui/metrics/ppk.png +0 -0
- testerkit/_docs/_assets/operator-ui/metrics/yield.png +0 -0
- testerkit/_docs/_assets/operator-ui/results/detail-header.png +0 -0
- testerkit/_docs/_assets/operator-ui/results/detail-measurements.png +0 -0
- testerkit/_docs/_assets/operator-ui/results/detail-overview.png +0 -0
- testerkit/_docs/_assets/operator-ui/results/detail-steps.png +0 -0
- testerkit/_docs/_assets/operator-ui/results/stats.png +0 -0
- testerkit/_docs/_assets/operator-ui/results/table.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/designer.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/docs.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/fixtures.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/instruments.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/parts.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/profiles.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/stations.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/tests.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/uuts.png +0 -0
- testerkit/_docs/concepts/configuration/capabilities.md +447 -0
- testerkit/_docs/concepts/configuration/fixtures.md +335 -0
- testerkit/_docs/concepts/configuration/index.md +14 -0
- testerkit/_docs/concepts/configuration/parts.md +276 -0
- testerkit/_docs/concepts/configuration/stations.md +214 -0
- testerkit/_docs/concepts/data/data-stores.md +199 -0
- testerkit/_docs/concepts/data/event-log.md +185 -0
- testerkit/_docs/concepts/data/event-sourcing.md +76 -0
- testerkit/_docs/concepts/data/flight-streaming.md +58 -0
- testerkit/_docs/concepts/data/index.md +17 -0
- testerkit/_docs/concepts/data/sessions.md +78 -0
- testerkit/_docs/concepts/data/three-verbs.md +260 -0
- testerkit/_docs/concepts/execution/index.md +13 -0
- testerkit/_docs/concepts/execution/outcomes.md +199 -0
- testerkit/_docs/concepts/execution/step-hierarchy.md +170 -0
- testerkit/_docs/concepts/execution/step-manifest.md +115 -0
- testerkit/_docs/concepts/index.md +40 -0
- testerkit/_docs/concepts/overview/ai-integration.md +57 -0
- testerkit/_docs/concepts/overview/architecture.md +357 -0
- testerkit/_docs/concepts/overview/index.md +14 -0
- testerkit/_docs/concepts/overview/platform-vs-framework.md +147 -0
- testerkit/_docs/concepts/overview/pytest.md +53 -0
- testerkit/_docs/concepts/overview/tiers.md +46 -0
- testerkit/_docs/how-to/catalog/datasheet-to-test.md +169 -0
- testerkit/_docs/how-to/catalog/index.md +11 -0
- testerkit/_docs/how-to/configuration/configuring-stations.md +364 -0
- testerkit/_docs/how-to/configuration/custom-drivers.md +484 -0
- testerkit/_docs/how-to/configuration/index.md +13 -0
- testerkit/_docs/how-to/configuration/mock-mode.md +342 -0
- testerkit/_docs/how-to/data/benchmarking.md +120 -0
- testerkit/_docs/how-to/data/capture-an-artifact.md +84 -0
- testerkit/_docs/how-to/data/capture-waveform.md +110 -0
- testerkit/_docs/how-to/data/choosing-a-channel-verb.md +108 -0
- testerkit/_docs/how-to/data/compare-runs.md +120 -0
- testerkit/_docs/how-to/data/export-results.md +104 -0
- testerkit/_docs/how-to/data/find-flaky-tests.md +108 -0
- testerkit/_docs/how-to/data/grafana-dashboards.md +148 -0
- testerkit/_docs/how-to/data/index.md +23 -0
- testerkit/_docs/how-to/data/mcp-debug-failures.md +125 -0
- testerkit/_docs/how-to/data/mcp-query-runs.md +120 -0
- testerkit/_docs/how-to/data/querying-channels.md +117 -0
- testerkit/_docs/how-to/data/querying-events.md +85 -0
- testerkit/_docs/how-to/data/stream-live-channel.md +134 -0
- testerkit/_docs/how-to/execution/custom-operator-ui.md +136 -0
- testerkit/_docs/how-to/execution/index.md +21 -0
- testerkit/_docs/how-to/execution/limits.md +193 -0
- testerkit/_docs/how-to/execution/managing-sessions.md +100 -0
- testerkit/_docs/how-to/execution/multi-uut-testing.md +211 -0
- testerkit/_docs/how-to/execution/operator-prompts.md +151 -0
- testerkit/_docs/how-to/execution/profiles.md +304 -0
- testerkit/_docs/how-to/execution/spec-driven-testing.md +169 -0
- testerkit/_docs/how-to/execution/test-context.md +212 -0
- testerkit/_docs/how-to/execution/traceability.md +252 -0
- testerkit/_docs/how-to/execution/vector-expansion.md +394 -0
- testerkit/_docs/how-to/execution/writing-tests.md +363 -0
- testerkit/_docs/how-to/index.md +59 -0
- testerkit/_docs/how-to/overview/index.md +11 -0
- testerkit/_docs/how-to/overview/mcp-integration.md +168 -0
- testerkit/_docs/how-to/overview/operator-ui-tour.md +234 -0
- testerkit/_docs/integration/data/grafana.md +162 -0
- testerkit/_docs/integration/data/index.md +15 -0
- testerkit/_docs/integration/data/lakehouse-import.md +226 -0
- testerkit/_docs/integration/data/logging.md +131 -0
- testerkit/_docs/integration/data/results-api.md +51 -0
- testerkit/_docs/integration/index.md +20 -0
- testerkit/_docs/integration/runtime/harness.md +281 -0
- testerkit/_docs/integration/runtime/index.md +13 -0
- testerkit/_docs/integration/runtime/instruments.md +284 -0
- testerkit/_docs/integration/runtime/pytest-existing.md +315 -0
- testerkit/_docs/reference/catalog/cookbook.md +389 -0
- testerkit/_docs/reference/catalog/index.md +11 -0
- testerkit/_docs/reference/catalog/schema.md +375 -0
- testerkit/_docs/reference/cli.md +660 -0
- testerkit/_docs/reference/configuration.md +406 -0
- testerkit/_docs/reference/data/channels-schema.md +145 -0
- testerkit/_docs/reference/data/event-types.md +554 -0
- testerkit/_docs/reference/data/events-schema.md +120 -0
- testerkit/_docs/reference/data/files-schema.md +141 -0
- testerkit/_docs/reference/data/index.md +18 -0
- testerkit/_docs/reference/data/models.md +2229 -0
- testerkit/_docs/reference/data/outputs.md +82 -0
- testerkit/_docs/reference/data/parquet-schema.md +529 -0
- testerkit/_docs/reference/data/performance-limits.md +224 -0
- testerkit/_docs/reference/data/query-api.md +247 -0
- testerkit/_docs/reference/index.md +69 -0
- testerkit/_docs/reference/operator-ui/channels/detail.md +82 -0
- testerkit/_docs/reference/operator-ui/channels/list.md +70 -0
- testerkit/_docs/reference/operator-ui/dashboard.md +87 -0
- testerkit/_docs/reference/operator-ui/designer.md +167 -0
- testerkit/_docs/reference/operator-ui/events.md +89 -0
- testerkit/_docs/reference/operator-ui/files.md +74 -0
- testerkit/_docs/reference/operator-ui/fixtures.md +100 -0
- testerkit/_docs/reference/operator-ui/instruments.md +126 -0
- testerkit/_docs/reference/operator-ui/launch.md +79 -0
- testerkit/_docs/reference/operator-ui/live.md +102 -0
- testerkit/_docs/reference/operator-ui/measurements.md +159 -0
- testerkit/_docs/reference/operator-ui/metrics.md +217 -0
- testerkit/_docs/reference/operator-ui/parts.md +98 -0
- testerkit/_docs/reference/operator-ui/profiles.md +103 -0
- testerkit/_docs/reference/operator-ui/results/detail.md +214 -0
- testerkit/_docs/reference/operator-ui/results/list.md +106 -0
- testerkit/_docs/reference/operator-ui/stations.md +98 -0
- testerkit/_docs/reference/operator-ui/tests.md +173 -0
- testerkit/_docs/reference/operator-ui/uuts.md +67 -0
- testerkit/_docs/reference/overview/index.md +11 -0
- testerkit/_docs/reference/overview/pytest-native.md +142 -0
- testerkit/_docs/reference/overview/skills.md +177 -0
- testerkit/_docs/reference/pytest/fixtures.md +342 -0
- testerkit/_docs/reference/pytest/index.md +12 -0
- testerkit/_docs/reference/pytest/markers.md +257 -0
- testerkit/_docs/reference/runtime/api.md +246 -0
- testerkit/_docs/reference/runtime/client.md +280 -0
- testerkit/_docs/reference/runtime/connect.md +140 -0
- testerkit/_docs/reference/runtime/index.md +13 -0
- testerkit/_docs/tutorial/01-first-test.md +113 -0
- testerkit/_docs/tutorial/02-mock-instruments.md +88 -0
- testerkit/_docs/tutorial/03-fixtures.md +169 -0
- testerkit/_docs/tutorial/04-limits.md +139 -0
- testerkit/_docs/tutorial/05-configuration.md +194 -0
- testerkit/_docs/tutorial/06-specifications.md +273 -0
- testerkit/_docs/tutorial/07-real-instruments.md +245 -0
- testerkit/_docs/tutorial/08-capabilities.md +223 -0
- testerkit/_docs/tutorial/09-production.md +374 -0
- testerkit/_docs/tutorial/10-live-monitoring.md +156 -0
- testerkit/_docs/tutorial/11-waveforms-and-evidence.md +169 -0
- testerkit/_docs/tutorial/12-continuous-monitoring.md +145 -0
- testerkit/_docs/tutorial/13-parallel-testing.md +233 -0
- testerkit/_docs/tutorial/index.md +61 -0
- testerkit/_docs/tutorial/quickstart.md +282 -0
- testerkit/analysis/__init__.py +9 -0
- testerkit/analysis/_common.py +24 -0
- testerkit/analysis/measurement_facets.py +524 -0
- testerkit/analysis/measurements_query.py +1458 -0
- testerkit/analysis/metrics.py +389 -0
- testerkit/analysis/runs_query.py +434 -0
- testerkit/analysis/steps_query.py +413 -0
- testerkit/api/__init__.py +6 -0
- testerkit/api/_mime.py +71 -0
- testerkit/api/app.py +1171 -0
- testerkit/api/dialogs/__init__.py +36 -0
- testerkit/api/dialogs/manager.py +617 -0
- testerkit/api/dialogs/models.py +79 -0
- testerkit/api/models.py +80 -0
- testerkit/api/responses.py +205 -0
- testerkit/api/runner.py +222 -0
- testerkit/api/schemas.py +311 -0
- testerkit/benchmark/__init__.py +34 -0
- testerkit/benchmark/concurrency.py +248 -0
- testerkit/benchmark/core.py +232 -0
- testerkit/benchmark/runner.py +628 -0
- testerkit/benchmark/scenario.py +313 -0
- testerkit/benchmark/system.py +191 -0
- testerkit/benchmark/workloads.py +507 -0
- testerkit/catalog/__init__.py +6 -0
- testerkit/catalog/generic/generic_dmm.yaml +61 -0
- testerkit/catalog/generic/generic_eload.yaml +31 -0
- testerkit/catalog/generic/generic_fgen.yaml +56 -0
- testerkit/catalog/generic/generic_oscilloscope.yaml +45 -0
- testerkit/catalog/generic/generic_psu.yaml +77 -0
- testerkit/catalog/generic/generic_smu.yaml +73 -0
- testerkit/channels.py +538 -0
- testerkit/cli/__init__.py +32 -0
- testerkit/cli/_common.py +113 -0
- testerkit/cli/_time.py +179 -0
- testerkit/cli/benchmark_cmd.py +56 -0
- testerkit/cli/catalog_cmd.py +39 -0
- testerkit/cli/daemon.py +157 -0
- testerkit/cli/data_cmd.py +1040 -0
- testerkit/cli/discover_cmd.py +94 -0
- testerkit/cli/docs_cmd.py +100 -0
- testerkit/cli/instrument.py +172 -0
- testerkit/cli/mcp_cmd.py +37 -0
- testerkit/cli/metrics.py +366 -0
- testerkit/cli/project.py +312 -0
- testerkit/cli/root.py +14 -0
- testerkit/cli/runs.py +412 -0
- testerkit/cli/schema_cmd.py +87 -0
- testerkit/cli/serve_cmd.py +50 -0
- testerkit/cli/setup_cmd.py +604 -0
- testerkit/cli/station.py +294 -0
- testerkit/cli/validate.py +112 -0
- testerkit/client.py +463 -0
- testerkit/connect.py +635 -0
- testerkit/data/__init__.py +8 -0
- testerkit/data/_accumulator_pool.py +455 -0
- testerkit/data/_atomic.py +59 -0
- testerkit/data/_collection_indices.py +67 -0
- testerkit/data/_daemon_lifecycle.py +535 -0
- testerkit/data/_duckdb_daemon.py +695 -0
- testerkit/data/_duckdb_flight_server.py +813 -0
- testerkit/data/_event_filters.py +15 -0
- testerkit/data/_event_reader.py +101 -0
- testerkit/data/_flight_errors.py +199 -0
- testerkit/data/_flight_query.py +202 -0
- testerkit/data/_flight_retry.py +148 -0
- testerkit/data/_flight_subscribe.py +67 -0
- testerkit/data/_index_epoch.py +342 -0
- testerkit/data/_ipc_writer.py +185 -0
- testerkit/data/_json_safe.py +63 -0
- testerkit/data/_process.py +18 -0
- testerkit/data/_push_relay.py +124 -0
- testerkit/data/_runs_duckdb_daemon.py +2704 -0
- testerkit/data/_session_reaper.py +110 -0
- testerkit/data/_sql_helpers.py +30 -0
- testerkit/data/_store.py +24 -0
- testerkit/data/backends/__init__.py +7 -0
- testerkit/data/backends/_event_accumulator.py +957 -0
- testerkit/data/backends/_row_helpers.py +1172 -0
- testerkit/data/backends/parquet.py +1143 -0
- testerkit/data/backends/protocol.py +35 -0
- testerkit/data/channels/__init__.py +8 -0
- testerkit/data/channels/_flight_daemon.py +75 -0
- testerkit/data/channels/client.py +242 -0
- testerkit/data/channels/flight_manager.py +88 -0
- testerkit/data/channels/index.py +664 -0
- testerkit/data/channels/models.py +418 -0
- testerkit/data/channels/server.py +162 -0
- testerkit/data/channels/store.py +1481 -0
- testerkit/data/data_dir.py +61 -0
- testerkit/data/duckdb_manager.py +79 -0
- testerkit/data/event_log.py +384 -0
- testerkit/data/event_store.py +768 -0
- testerkit/data/events.py +1025 -0
- testerkit/data/exporters/__init__.py +6 -0
- testerkit/data/exporters/_helpers.py +40 -0
- testerkit/data/exporters/csv_exporter.py +168 -0
- testerkit/data/exporters/hdf5.py +234 -0
- testerkit/data/exporters/json_exporter.py +229 -0
- testerkit/data/exporters/mdf4.py +201 -0
- testerkit/data/exporters/stdf.py +255 -0
- testerkit/data/exporters/tdms.py +292 -0
- testerkit/data/files/__init__.py +71 -0
- testerkit/data/files/_backend.py +207 -0
- testerkit/data/files/_catalog_daemon.py +84 -0
- testerkit/data/files/catalog.py +218 -0
- testerkit/data/files/catalog_manager.py +325 -0
- testerkit/data/files/models.py +60 -0
- testerkit/data/files/serializers.py +414 -0
- testerkit/data/files/store.py +463 -0
- testerkit/data/files/streaming.py +783 -0
- testerkit/data/models.py +604 -0
- testerkit/data/ref.py +152 -0
- testerkit/data/retention.py +297 -0
- testerkit/data/run_store.py +367 -0
- testerkit/data/runs_duckdb_manager.py +103 -0
- testerkit/data/schema_dispatch.py +191 -0
- testerkit/data/schema_migrate.py +76 -0
- testerkit/data/schema_versions.py +85 -0
- testerkit/data/schemas.py +288 -0
- testerkit/data/subscribers/__init__.py +48 -0
- testerkit/data/subscribers/_base.py +20 -0
- testerkit/data/subscribers/_output_file.py +25 -0
- testerkit/data/subscribers/replay.py +55 -0
- testerkit/environment.py +84 -0
- testerkit/execution/__init__.py +11 -0
- testerkit/execution/_git.py +190 -0
- testerkit/execution/_state.py +740 -0
- testerkit/execution/accessors.py +54 -0
- testerkit/execution/audit.py +51 -0
- testerkit/execution/cascade.py +85 -0
- testerkit/execution/connections.py +491 -0
- testerkit/execution/harness.py +1931 -0
- testerkit/execution/instrument_events.py +42 -0
- testerkit/execution/limits.py +154 -0
- testerkit/execution/metadata.py +102 -0
- testerkit/execution/mocks.py +63 -0
- testerkit/execution/profiles.py +616 -0
- testerkit/execution/run_scope.py +1331 -0
- testerkit/execution/session_scope.py +196 -0
- testerkit/execution/sidecar.py +280 -0
- testerkit/execution/site_runner.py +705 -0
- testerkit/execution/sites.py +183 -0
- testerkit/execution/sync.py +294 -0
- testerkit/execution/uut_provider.py +231 -0
- testerkit/execution/vectors.py +205 -0
- testerkit/execution/verify.py +396 -0
- testerkit/expand.py +75 -0
- testerkit/files.py +235 -0
- testerkit/fixtures/__init__.py +6 -0
- testerkit/fixtures/manager.py +357 -0
- testerkit/grafana/__init__.py +1 -0
- testerkit/grafana/bootstrap.py +61 -0
- testerkit/grafana/cli.py +314 -0
- testerkit/grafana/dashboards/asset_utilization.json +92 -0
- testerkit/grafana/dashboards/channel_explorer.json +77 -0
- testerkit/grafana/dashboards/event_log.json +92 -0
- testerkit/grafana/dashboards/failure_pareto.json +104 -0
- testerkit/grafana/dashboards/measurement_distribution.json +97 -0
- testerkit/grafana/dashboards/measurement_trend.json +161 -0
- testerkit/grafana/dashboards/station_comparison.json +95 -0
- testerkit/grafana/dashboards/test_duration.json +104 -0
- testerkit/grafana/dashboards/unit_traceability.json +73 -0
- testerkit/grafana/dashboards/yield_overview.json +189 -0
- testerkit/grafana/provisioning/dashboards.yaml.j2 +12 -0
- testerkit/grafana/provisioning/datasources.yaml.j2 +17 -0
- testerkit/grafana/server.py +282 -0
- testerkit/init.py +724 -0
- testerkit/instruments/__init__.py +10 -0
- testerkit/instruments/base.py +82 -0
- testerkit/instruments/discovery/__init__.py +62 -0
- testerkit/instruments/discovery/_base.py +174 -0
- testerkit/instruments/discovery/lxi.py +152 -0
- testerkit/instruments/discovery/ni.py +95 -0
- testerkit/instruments/discovery/serial.py +73 -0
- testerkit/instruments/discovery/visa.py +98 -0
- testerkit/instruments/lifecycle.py +213 -0
- testerkit/instruments/loader.py +79 -0
- testerkit/instruments/locks.py +178 -0
- testerkit/instruments/mocks.py +230 -0
- testerkit/instruments/observer.py +270 -0
- testerkit/instruments/observers/__init__.py +36 -0
- testerkit/instruments/observers/_base.py +68 -0
- testerkit/instruments/observers/daqmx.py +70 -0
- testerkit/instruments/observers/descriptor.py +69 -0
- testerkit/instruments/observers/generic.py +92 -0
- testerkit/instruments/observers/lantz.py +31 -0
- testerkit/instruments/observers/modbus.py +96 -0
- testerkit/instruments/observers/motion.py +68 -0
- testerkit/instruments/observers/ni_modular.py +73 -0
- testerkit/instruments/observers/ophyd.py +80 -0
- testerkit/instruments/observers/pymeasure.py +120 -0
- testerkit/instruments/observers/qcodes.py +66 -0
- testerkit/instruments/observers/scpi.py +88 -0
- testerkit/instruments/observers/tektronix.py +57 -0
- testerkit/instruments/observers/visa.py +103 -0
- testerkit/instruments/pool.py +459 -0
- testerkit/instruments/proxy.py +59 -0
- testerkit/instruments/route_manager.py +329 -0
- testerkit/instruments/routed_proxy.py +88 -0
- testerkit/instruments/server.py +508 -0
- testerkit/instruments/switch.py +43 -0
- testerkit/instruments/visa.py +294 -0
- testerkit/matching/__init__.py +6 -0
- testerkit/matching/service.py +969 -0
- testerkit/mcp/__init__.py +6 -0
- testerkit/mcp/server.py +681 -0
- testerkit/mcp/tools.py +1868 -0
- testerkit/models/__init__.py +18 -0
- testerkit/models/capability.py +598 -0
- testerkit/models/catalog.py +76 -0
- testerkit/models/data_options.py +153 -0
- testerkit/models/enums.py +334 -0
- testerkit/models/instrument.py +152 -0
- testerkit/models/instrument_asset.py +25 -0
- testerkit/models/part.py +271 -0
- testerkit/models/part_manifest.py +96 -0
- testerkit/models/project.py +114 -0
- testerkit/models/station.py +140 -0
- testerkit/models/test_config.py +748 -0
- testerkit/ontology/__init__.py +39 -0
- testerkit/ontology/schema.py +188 -0
- testerkit/ontology/testerkit.yaml +1420 -0
- testerkit/parts/__init__.py +8 -0
- testerkit/parts/context.py +181 -0
- testerkit/parts/folder.py +251 -0
- testerkit/parts/loader.py +27 -0
- testerkit/prompts/__init__.py +17 -0
- testerkit/prompts/core.py +133 -0
- testerkit/pytest_plugin/__init__.py +1287 -0
- testerkit/pytest_plugin/autouse.py +369 -0
- testerkit/pytest_plugin/helpers.py +354 -0
- testerkit/pytest_plugin/hooks.py +1982 -0
- testerkit/pytest_plugin/markers.py +203 -0
- testerkit/pytest_plugin/retry.py +37 -0
- testerkit/pytest_plugin/sweeps.py +117 -0
- testerkit/queries.py +78 -0
- testerkit/reports/__init__.py +6 -0
- testerkit/reports/core.py +492 -0
- testerkit/reports/datasheet.py +831 -0
- testerkit/reports/templates/datasheet.html +383 -0
- testerkit/reports/templates/default.html +153 -0
- testerkit/sbom.py +142 -0
- testerkit/schema_export.py +101 -0
- testerkit/signals.py +63 -0
- testerkit/skills/README.md +58 -0
- testerkit/skills/templates/project-instructions.md +125 -0
- testerkit/skills/testerkit-analysis/SKILL.md +87 -0
- testerkit/skills/testerkit-capture/SKILL.md +114 -0
- testerkit/skills/testerkit-data/SKILL.md +138 -0
- testerkit/skills/testerkit-datasheets/SKILL.md +100 -0
- testerkit/skills/testerkit-datasheets/agents/scaffold-writer.md +115 -0
- testerkit/skills/testerkit-datasheets/agents/section-extractor.md +98 -0
- testerkit/skills/testerkit-datasheets/agents/section-reviewer.md +153 -0
- testerkit/skills/testerkit-datasheets/agents/section-splitter.md +89 -0
- testerkit/skills/testerkit-datasheets/agents/section-writer.md +226 -0
- testerkit/skills/testerkit-datasheets/references/catalog-pipeline.md +271 -0
- testerkit/skills/testerkit-datasheets/references/process-queue.md +42 -0
- testerkit/skills/testerkit-datasheets/references/scaffold.md +156 -0
- testerkit/skills/testerkit-datasheets/references/test-pipeline.md +312 -0
- testerkit/skills/testerkit-debug/SKILL.md +127 -0
- testerkit/skills/testerkit-interactive/SKILL.md +188 -0
- testerkit/skills/testerkit-interactive/references/live-ui-patterns.md +102 -0
- testerkit/skills/testerkit-mocks/SKILL.md +128 -0
- testerkit/skills/testerkit-parts/SKILL.md +126 -0
- testerkit/skills/testerkit-profiles/SKILL.md +139 -0
- testerkit/skills/testerkit-sites/SKILL.md +140 -0
- testerkit/skills/testerkit-stations/SKILL.md +146 -0
- testerkit/skills/testerkit-tests/SKILL.md +136 -0
- testerkit/store.py +1639 -0
- testerkit/ui/__init__.py +71 -0
- testerkit/ui/_asgi.py +162 -0
- testerkit/ui/app.py +32 -0
- testerkit/ui/components/__init__.py +13 -0
- testerkit/ui/components/artifact_viewer.py +250 -0
- testerkit/ui/components/channel_values.py +159 -0
- testerkit/ui/components/event_timeline.py +222 -0
- testerkit/ui/components/execution_gantt.py +210 -0
- testerkit/ui/components/file_streams.py +147 -0
- testerkit/ui/components/instrument_activity.py +146 -0
- testerkit/ui/components/session_table.py +118 -0
- testerkit/ui/pages/__init__.py +25 -0
- testerkit/ui/pages/channels/__init__.py +4 -0
- testerkit/ui/pages/channels/detail.py +932 -0
- testerkit/ui/pages/channels/list.py +515 -0
- testerkit/ui/pages/dashboard.py +236 -0
- testerkit/ui/pages/designer/__init__.py +5 -0
- testerkit/ui/pages/designer/graph.py +635 -0
- testerkit/ui/pages/designer/matching.py +663 -0
- testerkit/ui/pages/designer/page.py +593 -0
- testerkit/ui/pages/designer/properties.py +591 -0
- testerkit/ui/pages/designer/state.py +468 -0
- testerkit/ui/pages/docs/__init__.py +6 -0
- testerkit/ui/pages/docs/index.py +95 -0
- testerkit/ui/pages/docs/page.py +698 -0
- testerkit/ui/pages/events/__init__.py +3 -0
- testerkit/ui/pages/events/list.py +263 -0
- testerkit/ui/pages/explore.py +1108 -0
- testerkit/ui/pages/files/__init__.py +4 -0
- testerkit/ui/pages/files/detail.py +426 -0
- testerkit/ui/pages/files/list.py +447 -0
- testerkit/ui/pages/fixtures/__init__.py +8 -0
- testerkit/ui/pages/fixtures/detail.py +280 -0
- testerkit/ui/pages/fixtures/edit.py +370 -0
- testerkit/ui/pages/fixtures/list.py +180 -0
- testerkit/ui/pages/fixtures/new.py +195 -0
- testerkit/ui/pages/instruments/__init__.py +4 -0
- testerkit/ui/pages/instruments/detail.py +320 -0
- testerkit/ui/pages/instruments/edit.py +482 -0
- testerkit/ui/pages/instruments/list.py +249 -0
- testerkit/ui/pages/instruments/new.py +200 -0
- testerkit/ui/pages/launch.py +261 -0
- testerkit/ui/pages/live.py +124 -0
- testerkit/ui/pages/metrics_page.py +1229 -0
- testerkit/ui/pages/parts/__init__.py +11 -0
- testerkit/ui/pages/parts/detail.py +202 -0
- testerkit/ui/pages/parts/edit.py +310 -0
- testerkit/ui/pages/parts/list.py +160 -0
- testerkit/ui/pages/parts/new.py +170 -0
- testerkit/ui/pages/parts/requirements.py +153 -0
- testerkit/ui/pages/parts/stations.py +199 -0
- testerkit/ui/pages/profiles/__init__.py +4 -0
- testerkit/ui/pages/profiles/detail.py +113 -0
- testerkit/ui/pages/profiles/list.py +86 -0
- testerkit/ui/pages/results/__init__.py +4 -0
- testerkit/ui/pages/results/detail.py +631 -0
- testerkit/ui/pages/results/list.py +230 -0
- testerkit/ui/pages/stations/__init__.py +4 -0
- testerkit/ui/pages/stations/detail.py +256 -0
- testerkit/ui/pages/stations/edit.py +273 -0
- testerkit/ui/pages/stations/list.py +180 -0
- testerkit/ui/pages/stations/new.py +311 -0
- testerkit/ui/pages/tests/__init__.py +4 -0
- testerkit/ui/pages/tests/detail.py +152 -0
- testerkit/ui/pages/tests/list.py +194 -0
- testerkit/ui/pages/uuts/__init__.py +4 -0
- testerkit/ui/pages/uuts/list.py +97 -0
- testerkit/ui/shared/__init__.py +8 -0
- testerkit/ui/shared/components.py +1826 -0
- testerkit/ui/shared/dialogs.py +105 -0
- testerkit/ui/shared/event_binding.py +194 -0
- testerkit/ui/shared/layout.py +314 -0
- testerkit/ui/shared/services.py +1719 -0
- testerkit/ui/shared/timestamps.py +21 -0
- testerkit/ui/static/branding/favicon-16.png +0 -0
- testerkit/ui/static/branding/favicon-32.png +0 -0
- testerkit/ui/static/branding/favicon-48.png +0 -0
- testerkit/ui/static/branding/testerkit-icon-256.png +0 -0
- testerkit/ui/static/branding/testerkit-mark.svg +1 -0
- testerkit/ui/static/branding/testerkit-wordmark.svg +1 -0
- testerkit/ui/static/global.css +465 -0
- testerkit/utils/__init__.py +17 -0
- testerkit/utils/enum_meta.py +800 -0
- testerkit/utils/paths.py +75 -0
- testerkit/utils/ranges.py +257 -0
- testerkit/validation.py +82 -0
- testerkit/verbs.py +142 -0
- testerkit-0.4.0.dist-info/METADATA +250 -0
- testerkit-0.4.0.dist-info/RECORD +521 -0
- testerkit-0.4.0.dist-info/WHEEL +4 -0
- testerkit-0.4.0.dist-info/entry_points.txt +5 -0
- testerkit-0.4.0.dist-info/licenses/LICENSE +191 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testerkit-data
|
|
3
|
+
description: Use when a user wants to read, query, or export existing TesterKit test data — runs, steps, measurements, channels, files, or events — or understand the data stores and how to access them (models, CLI, Query API, MCP). Not computing a statistic across runs (that's testerkit-analysis) and not diagnosing why one run failed (that's testerkit-debug).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Reading TesterKit data
|
|
7
|
+
|
|
8
|
+
The data already exists on disk. This skill covers the **stores, the model,
|
|
9
|
+
and every read surface** — models, CLI, Query API, MCP, UI — so a question
|
|
10
|
+
turns into the right access call.
|
|
11
|
+
|
|
12
|
+
## The one rule
|
|
13
|
+
|
|
14
|
+
**Never read `data/**/*.parquet` or `data/*/_index.*.duckdb` directly.** That
|
|
15
|
+
layout is internal and content-addressed — the fingerprint in an index
|
|
16
|
+
filename is a hash of the current schema, so it renames on any version bump and
|
|
17
|
+
a hand-rolled reader breaks silently on upgrade. Every question below has a
|
|
18
|
+
stable, purpose-built surface. If none exposes the shape you need, extend the
|
|
19
|
+
Query API — don't reach into the files.
|
|
20
|
+
|
|
21
|
+
## 1. The stores
|
|
22
|
+
|
|
23
|
+
TesterKit keeps four data stores under the project `data/` dir. All are derived
|
|
24
|
+
from the event log:
|
|
25
|
+
|
|
26
|
+
| Store | Holds | Read via |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| runs / measurements | tabular run → step → measurement records | CLI (`testerkit runs`/`show`), Query API, `testerkit_runs`/`testerkit_steps` |
|
|
29
|
+
| channels | streaming / waveform samples | `testerkit.channels` module, `testerkit_channels`, UI |
|
|
30
|
+
| files | blobs & growing artifacts (photos, logs, vendor captures) | `testerkit.files` module, `testerkit_files`, UI |
|
|
31
|
+
| events | the append-only log every store is derived from | `testerkit_events` / `testerkit_sessions`, UI |
|
|
32
|
+
|
|
33
|
+
Tabular runs data has a first-class **CLI**; channels, files, and events read
|
|
34
|
+
through the UI, MCP, HTTP, or the Python modules — there is no `testerkit
|
|
35
|
+
channels`/`files`/`events` subcommand.
|
|
36
|
+
|
|
37
|
+
## 2. The model
|
|
38
|
+
|
|
39
|
+
A run carries its step tree; each step carries three role-tagged
|
|
40
|
+
`list<struct>` lanes — `inputs`, `outputs`, `measurements`. Reference a value
|
|
41
|
+
by **role + name**:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from testerkit.queries import FieldRef
|
|
45
|
+
FieldRef.measurement("v_rail") # a judged measurement (has a limit)
|
|
46
|
+
FieldRef.output("capture_length") # a recorded output reading
|
|
47
|
+
FieldRef.input("vin") # a stimulus input
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Only `measurements` carry limits; `inputs`/`outputs` are record-only. Full
|
|
51
|
+
shape: `reference/data/models` and `reference/data/parquet-schema`.
|
|
52
|
+
|
|
53
|
+
## 3. CLI (tabular data)
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
testerkit runs --station bench_01 --since 7d --json # list / filter runs
|
|
57
|
+
testerkit show <run_id> # one run: outcome, steps, measurements
|
|
58
|
+
testerkit show <run_id> -f json # machine-readable (also html|pdf|csv)
|
|
59
|
+
testerkit show <run_id> --env # captured environment snapshot
|
|
60
|
+
testerkit export <run_id> -f stdf -o exports/ # STDF and other event-shaped formats
|
|
61
|
+
testerkit sbom <run_id> -o sbom.json # CycloneDX 1.6
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`show`/`export`'s id is a run_id or session_id prefix, auto-detected. Prefer
|
|
65
|
+
`--json` for tool use — stable across schema changes and token-efficient.
|
|
66
|
+
`testerkit show` prints measurements only; it doesn't list outputs or artifact URIs.
|
|
67
|
+
|
|
68
|
+
## 4. Query API (scripted)
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from testerkit.queries import RunsQuery, StepsQuery, MeasurementsQuery, FieldRef
|
|
72
|
+
|
|
73
|
+
with RunsQuery() as q:
|
|
74
|
+
for r in q.list_recent(limit=20, outcome="failed"):
|
|
75
|
+
print(r.uut_serial_number, r.station_hostname, r.outcome)
|
|
76
|
+
q.get(run_id) # one run
|
|
77
|
+
q.list_for_session(session_id)
|
|
78
|
+
|
|
79
|
+
with StepsQuery() as s:
|
|
80
|
+
s.list_for_run(run_id) # flat step list
|
|
81
|
+
s.tree_for_run(run_id) # nested step tree
|
|
82
|
+
|
|
83
|
+
with MeasurementsQuery() as m:
|
|
84
|
+
m.parametric(y=FieldRef.measurement("v_rail"), x=FieldRef.input("vin"))
|
|
85
|
+
m.histogram(field=FieldRef.output("capture_length"))
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Opening a query class with no args reads the active project's data dir; always
|
|
89
|
+
close it (or use `with`). These are the same classes `testerkit serve` renders, so
|
|
90
|
+
anything scriptable here is clickable there. Computing yield/Ppk/Pareto/trend
|
|
91
|
+
over these rows is `testerkit-analysis`.
|
|
92
|
+
|
|
93
|
+
## 5. Channels & files readback
|
|
94
|
+
|
|
95
|
+
| Data | Surface |
|
|
96
|
+
|---|---|
|
|
97
|
+
| Channel, one-shot pull | `testerkit.channels.query(name, last_n=..., max_points=...)` |
|
|
98
|
+
| Channel, live gauge/chart | `testerkit.channels.latest(name, cb)` / `.live(name, cb, max_hz=...)` |
|
|
99
|
+
| Channel, agent/remote | MCP `testerkit_channels(channel_id, session_id=, last_n=, max_points=)` |
|
|
100
|
+
| Channel, human | `testerkit serve` → `/channels/<channel_id>` |
|
|
101
|
+
| Artifact catalog (metadata, not bytes) | MCP `testerkit_files(uri=, session_id=, run_id=)` |
|
|
102
|
+
| Artifact, human | `testerkit serve` → `/files` |
|
|
103
|
+
|
|
104
|
+
Filter artifact readback by `session_id`, not `run_id`, to catch every artifact
|
|
105
|
+
from a run — `observe`-routed blobs carry no `run_id`. Writing channels/files in
|
|
106
|
+
the first place is `testerkit-capture`.
|
|
107
|
+
|
|
108
|
+
## 6. Events
|
|
109
|
+
|
|
110
|
+
The event log is the source every other store derives from — read it for the
|
|
111
|
+
raw ordered stream, or when a projection looks wrong:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
MCP testerkit_events(session_id=, event_type=, role=, since=, limit=)
|
|
115
|
+
MCP testerkit_sessions(project=) # session index
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 7. MCP read tools
|
|
119
|
+
|
|
120
|
+
| MCP tool | Mirrors |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `testerkit_runs(action="list"\|"get", run_id=...)` | `testerkit runs` / `RunsQuery` |
|
|
123
|
+
| `testerkit_steps(run_id=..., action="list"\|"tree")` | `StepsQuery.list_for_run` / `.tree_for_run` |
|
|
124
|
+
| `testerkit_channels` / `testerkit_files` / `testerkit_events` / `testerkit_sessions` | channel / file / event / session reads |
|
|
125
|
+
|
|
126
|
+
## Deeper
|
|
127
|
+
Read the docs:
|
|
128
|
+
```bash
|
|
129
|
+
testerkit docs show concepts/data/data-stores
|
|
130
|
+
testerkit docs show reference/data/models
|
|
131
|
+
testerkit docs show reference/data/query-api
|
|
132
|
+
testerkit docs show reference/data/parquet-schema
|
|
133
|
+
testerkit docs show how-to/data/mcp-query-runs
|
|
134
|
+
testerkit docs show how-to/data/export-results
|
|
135
|
+
```
|
|
136
|
+
Sibling skills: `testerkit-analysis` (compute a statistic over these records),
|
|
137
|
+
`testerkit-capture` (write channels/files in the first place), `testerkit-debug`
|
|
138
|
+
(why one run failed).
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testerkit-datasheets
|
|
3
|
+
description: Use ONLY when the user has an instrument or part datasheet PDF to import into TesterKit config (an instrument → catalog entry, or a part → part spec). For writing tests without a datasheet, use testerkit-tests instead.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Datasheet import
|
|
7
|
+
|
|
8
|
+
Turn a datasheet PDF into TesterKit config: an **instrument** datasheet becomes a
|
|
9
|
+
catalog entry, a **part/DUT** datasheet becomes a part spec plus a test. This is
|
|
10
|
+
a deliberate, gated, multi-phase procedure — run it because the user asked to
|
|
11
|
+
import a datasheet, never as a reflex to "write me a test." If there's no PDF in
|
|
12
|
+
hand, you're in the wrong skill (see `testerkit-tests`).
|
|
13
|
+
|
|
14
|
+
## 1. Route: what did they hand you?
|
|
15
|
+
|
|
16
|
+
| The user has… | Pipeline | Reference |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| An **instrument** datasheet PDF (DMM, PSU, scope, load…) — need exact specs, channels, accuracy | catalog pipeline | `references/catalog-pipeline.md` |
|
|
19
|
+
| A **part/DUT** datasheet PDF — need characteristics, pins, and a test that exercises them | test pipeline | `references/test-pipeline.md` |
|
|
20
|
+
| A **well-known instrument, no PDF** (Keysight, Tektronix, Rigol, Fluke…) — fast approximate entry | scaffold | `references/scaffold.md` |
|
|
21
|
+
| A **batch** of pending PDFs already queued in `catalog/QUEUE.md` | queue processor | `references/process-queue.md` |
|
|
22
|
+
|
|
23
|
+
If the user's ask doesn't fit any row — e.g. they want a test but have no
|
|
24
|
+
datasheet at all — hand off to `testerkit-tests` instead of forcing a pipeline here.
|
|
25
|
+
|
|
26
|
+
## 2. Instrument datasheet → catalog entry
|
|
27
|
+
|
|
28
|
+
Read `references/catalog-pipeline.md` and follow it exactly, phase by phase. Do
|
|
29
|
+
not summarize or shortcut the phases here — that file is the orchestration
|
|
30
|
+
contract, not this one.
|
|
31
|
+
|
|
32
|
+
In outline: the orchestrator never reads the PDF itself. It spawns five
|
|
33
|
+
sub-agents from `agents/` in sequence — `section-splitter` maps the PDF into
|
|
34
|
+
sections, `scaffold-writer` writes the device-level YAML (channels, connectors,
|
|
35
|
+
board attributes), then per section `section-extractor` → `section-writer` →
|
|
36
|
+
`section-reviewer` cycle until a mechanical audit script and the reviewer both
|
|
37
|
+
report clean. Every phase ends in a checkpoint or gate tag; do not proceed past
|
|
38
|
+
one that hasn't fired.
|
|
39
|
+
|
|
40
|
+
The output is a catalog YAML entry — the same shape a station's
|
|
41
|
+
`catalog_ref:` resolves against (see `testerkit-stations`).
|
|
42
|
+
|
|
43
|
+
## 3. Part/DUT datasheet → part spec + test
|
|
44
|
+
|
|
45
|
+
Read `references/test-pipeline.md` and follow it exactly, phase by phase. This
|
|
46
|
+
pipeline is collaborative — it gates on user approval at every phase (part spec,
|
|
47
|
+
instrument recommendation, station config, generated test) via
|
|
48
|
+
`ask_user_input_v0` / `AskUserQuestion`. Never assume approval and skip a gate.
|
|
49
|
+
|
|
50
|
+
In outline: parse the datasheet into characteristics + pins → save a part spec
|
|
51
|
+
via `testerkit_project(action="save", type="part", ...)` → recommend catalog
|
|
52
|
+
instruments via `testerkit_match` (falling back to generic instruments or the
|
|
53
|
+
scaffold path below if the catalog has no match) → build a station → generate
|
|
54
|
+
the test file plus its sidecar YAML. Characteristic and limit shapes match what
|
|
55
|
+
`testerkit-parts` and `testerkit-tests` describe — this pipeline is how those artifacts
|
|
56
|
+
get their first draft from a datasheet instead of from scratch.
|
|
57
|
+
|
|
58
|
+
## 4. No PDF, well-known instrument → scaffold
|
|
59
|
+
|
|
60
|
+
If the user names a common instrument by model number and doesn't have (or need)
|
|
61
|
+
the datasheet, read `references/scaffold.md` and follow it. It writes a catalog
|
|
62
|
+
entry from model knowledge, marks it `scaffold: true`, and uses conservative
|
|
63
|
+
ranges — never claim accuracy you can't back with a source. This is the fast
|
|
64
|
+
path; the catalog pipeline in step 2 is the thorough path when exact
|
|
65
|
+
specifications matter. If confidence in the instrument is low, say so and
|
|
66
|
+
recommend the catalog pipeline instead of guessing.
|
|
67
|
+
|
|
68
|
+
## 5. Batch of queued datasheets
|
|
69
|
+
|
|
70
|
+
If the user asks to work through a backlog — "process the queue," "do all the
|
|
71
|
+
pending datasheets" — read `references/process-queue.md` and follow it. It loops
|
|
72
|
+
the catalog pipeline (step 2) over every `pending` / `pending:redo` row in
|
|
73
|
+
`catalog/QUEUE.md`, updating each row's status as it completes, and does not stop
|
|
74
|
+
to ask the user between instruments.
|
|
75
|
+
|
|
76
|
+
## 6. Validate before declaring done
|
|
77
|
+
|
|
78
|
+
Every pipeline above ends with the artifact still unverified until you run:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
testerkit validate --type catalog <path>.yaml # instrument pipeline
|
|
82
|
+
testerkit validate --type part <path>.yaml # test pipeline part spec
|
|
83
|
+
testerkit validate --type station <path>.yaml # test pipeline station config
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
or, for the test pipeline, the equivalent MCP save calls
|
|
87
|
+
(`testerkit_project(action="save", type=..., ...)`), which validate server-side
|
|
88
|
+
against the same Pydantic models. A pipeline is not complete until its YAML
|
|
89
|
+
validates clean — do not report success on an artifact you haven't checked.
|
|
90
|
+
|
|
91
|
+
## Deeper
|
|
92
|
+
|
|
93
|
+
`references/`: `catalog-pipeline.md` (instrument → catalog, full phase spec),
|
|
94
|
+
`test-pipeline.md` (part → spec/station/test, full phase spec), `scaffold.md`
|
|
95
|
+
(no-PDF fast path), `process-queue.md` (batch driver). `agents/`: the five
|
|
96
|
+
sub-agent prompts the catalog pipeline spawns
|
|
97
|
+
(`section-splitter`, `scaffold-writer`, `section-extractor`, `section-writer`,
|
|
98
|
+
`section-reviewer`). Sibling skills: `testerkit-tests` (writing tests without a
|
|
99
|
+
datasheet), `testerkit-stations` (what a catalog entry feeds into), `testerkit-parts`
|
|
100
|
+
(part characteristics and limits once the spec exists).
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scaffold-writer
|
|
3
|
+
description: Reads targeted pages of a datasheet PDF and writes the device-level catalog YAML (catalog_entry with channels, interfaces, board attributes). Does NOT extract capabilities.
|
|
4
|
+
variables: PDF_PATH, YAML_PATH, INSTRUMENT_ID, OVERVIEW_PAGES, CONNECTOR_PAGES, GENERAL_PAGES, ENUM_CONNECTORS, ENUM_TERMINALS, ENUM_GROUNDS
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**Recommended model tier:** high-capability reasoning (Anthropic Opus, Google Gemini 2.5 Pro, OpenAI GPT-5 / o-series, or equivalent). Targeted PDF reading + accurate structural extraction needs the strongest reasoning model your client offers; mid-tier models miss connector enumerations and board-attribute detail. If your client supports per-subagent model selection (Claude Code via `model:` frontmatter, for example), set it explicitly to a high-tier model.
|
|
8
|
+
|
|
9
|
+
# Scaffold Writer Agent
|
|
10
|
+
|
|
11
|
+
You read targeted pages of an instrument datasheet and write the device-level catalog YAML. That is your ONLY job. You do NOT extract capabilities or spec tables. You write the catalog_entry shell that capability agents will populate later.
|
|
12
|
+
|
|
13
|
+
**Do NOT read other catalog YAML files as examples.** Your only inputs are the PDF pages and the schema/enum references below. Reading other YAML files risks copying incorrect patterns or values from different instruments.
|
|
14
|
+
|
|
15
|
+
**Tool rules:**
|
|
16
|
+
- Use Read tool to read files, Write/Edit tools to create/modify files. NEVER use Bash cat, heredocs, or echo for file I/O.
|
|
17
|
+
- Write YAML directly via Write/Edit. NEVER create Python scripts to generate YAML.
|
|
18
|
+
|
|
19
|
+
## Your Assignment
|
|
20
|
+
|
|
21
|
+
- **PDF:** `{{PDF_PATH}}`
|
|
22
|
+
- **Output YAML:** `{{YAML_PATH}}`
|
|
23
|
+
- **Instrument ID:** `{{INSTRUMENT_ID}}`
|
|
24
|
+
- **Overview pages:** {{OVERVIEW_PAGES}}
|
|
25
|
+
- **Connector pages:** {{CONNECTOR_PAGES}}
|
|
26
|
+
- **General spec pages:** {{GENERAL_PAGES}}
|
|
27
|
+
|
|
28
|
+
## Instructions
|
|
29
|
+
|
|
30
|
+
### Step 1: Read the targeted pages
|
|
31
|
+
|
|
32
|
+
Read ONLY the pages listed above (overview, connector, general spec pages). Read them carefully — you have few pages to cover, so be thorough.
|
|
33
|
+
|
|
34
|
+
From the overview pages, extract:
|
|
35
|
+
- Manufacturer name
|
|
36
|
+
- Model number and variants
|
|
37
|
+
- Part description (1-2 sentences)
|
|
38
|
+
|
|
39
|
+
From the connector/I/O pages, extract:
|
|
40
|
+
- Every physical connector: name, type, terminal configuration, ground topology
|
|
41
|
+
- Front panel vs rear panel layout
|
|
42
|
+
- Optional connectors (e.g., "Option 1EM adds rear RF output")
|
|
43
|
+
|
|
44
|
+
From the general spec pages, extract:
|
|
45
|
+
- Operating temperature range
|
|
46
|
+
- Storage temperature range
|
|
47
|
+
- Weight
|
|
48
|
+
- Power requirements (voltage, frequency, power consumption)
|
|
49
|
+
- Warmup time
|
|
50
|
+
- Calibration interval
|
|
51
|
+
- Max working voltage
|
|
52
|
+
- Pollution degree, max altitude, humidity
|
|
53
|
+
- Any other board-level specs
|
|
54
|
+
|
|
55
|
+
### Step 2: Read schema references
|
|
56
|
+
|
|
57
|
+
Use these enum values — they are the ONLY valid values for channel fields:
|
|
58
|
+
|
|
59
|
+
**ConnectorType:** {{ENUM_CONNECTORS}}
|
|
60
|
+
|
|
61
|
+
**TerminalRole:** {{ENUM_TERMINALS}}
|
|
62
|
+
|
|
63
|
+
**GroundTopology:** {{ENUM_GROUNDS}}
|
|
64
|
+
|
|
65
|
+
Read `docs/reference/catalog/schema.md` for attribute format (scalar `value` or min/max `range`).
|
|
66
|
+
|
|
67
|
+
### Step 3: Write the scaffold YAML
|
|
68
|
+
|
|
69
|
+
Write the initial YAML to `{{YAML_PATH}}`:
|
|
70
|
+
|
|
71
|
+
1. **3-line header comment:** instrument name, PDF source, key summary
|
|
72
|
+
2. **catalog_entry:**
|
|
73
|
+
- manufacturer, model, description
|
|
74
|
+
- interfaces (e.g., pxi, usb, lan, gpib)
|
|
75
|
+
- channels — every physical connector with documented electrical specs
|
|
76
|
+
- attributes — board-level facts (operating temp, weight, power, warmup, cal interval, etc.)
|
|
77
|
+
- capabilities: [] (empty — section agents will populate this)
|
|
78
|
+
|
|
79
|
+
**Channel rules:**
|
|
80
|
+
- Include ALL channels from the PDF — every physical connector with documented electrical specs
|
|
81
|
+
- Include optional channels with a note about which option adds them
|
|
82
|
+
- Use compact range syntax: `"ai[0:7]"` not arrays of individual names
|
|
83
|
+
- Set correct `terminals`, `connector`, and `ground` from the PDF
|
|
84
|
+
- Use MeasurementFunction enum values for naming guidance
|
|
85
|
+
|
|
86
|
+
**Board-level attribute format:**
|
|
87
|
+
- Scalar: `warmup_time: {value: 30, unit: min}`
|
|
88
|
+
- Range: `operating_temperature: {range: {min: 0, max: 55, unit: degC}}`
|
|
89
|
+
|
|
90
|
+
### Step 4: Validate the scaffold loads
|
|
91
|
+
|
|
92
|
+
Run:
|
|
93
|
+
```
|
|
94
|
+
uv run testerkit validate --type catalog {{YAML_PATH}}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Fix any errors until it loads clean.
|
|
98
|
+
|
|
99
|
+
### Step 5: Return your results
|
|
100
|
+
|
|
101
|
+
Return this exact format:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
SCAFFOLD RESULT
|
|
105
|
+
===============
|
|
106
|
+
Written to: {{YAML_PATH}}
|
|
107
|
+
Channels: <list with connectors>
|
|
108
|
+
Interfaces: <list>
|
|
109
|
+
Board attributes: <count>
|
|
110
|
+
Status: validated clean / errors
|
|
111
|
+
|
|
112
|
+
CHANNELS YAML
|
|
113
|
+
=============
|
|
114
|
+
<just the channels: dict from the scaffold, for injection into downstream prompts>
|
|
115
|
+
```
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: section-extractor
|
|
3
|
+
description: Reads PDF pages and produces a complete structured inventory file. ONE job — extraction only, no YAML, no schema knowledge.
|
|
4
|
+
variables: PDF_PATH, PAGES, SECTION_NAME, INVENTORY_PATH
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**Recommended model tier:** high-capability reasoning (Anthropic Opus, Google Gemini 2.5 Pro, OpenAI GPT-5 / o-series, or equivalent). Complete-and-mechanical PDF extraction is the most demanding step in the workflow; a weaker model drops rows, misreads accuracy tables, and produces inventories that downstream agents can't recover from. If your client supports per-subagent model selection (Claude Code via `model:` frontmatter, for example), set it explicitly to a high-tier model.
|
|
8
|
+
|
|
9
|
+
# Section Extractor Agent
|
|
10
|
+
|
|
11
|
+
You read specific pages of an instrument datasheet PDF and produce a complete structured inventory file. That is your ONLY job. You do NOT write YAML. You do NOT know the catalog schema. You extract what the PDF says, completely and mechanically.
|
|
12
|
+
|
|
13
|
+
**Tool rules:**
|
|
14
|
+
- Use Read tool to read files, Write tool to create files. NEVER use Bash cat, heredocs, or echo for file I/O.
|
|
15
|
+
|
|
16
|
+
## Your Assignment
|
|
17
|
+
|
|
18
|
+
- **PDF:** `{{PDF_PATH}}`
|
|
19
|
+
- **Pages to read:** {{PAGES}}
|
|
20
|
+
- **Section:** {{SECTION_NAME}}
|
|
21
|
+
- **Output:** `{{INVENTORY_PATH}}`
|
|
22
|
+
|
|
23
|
+
## Instructions
|
|
24
|
+
|
|
25
|
+
<step id="1" name="Read PDF pages">
|
|
26
|
+
Read your assigned PDF pages (2-4 pages at a time). For EVERY table on every page:
|
|
27
|
+
- List ALL column headers. Capture EVERY column, not just Standard/default. Option columns (e.g., EP3, EP4, Option 001) are just as important as the base column.
|
|
28
|
+
- Count rows and columns.
|
|
29
|
+
- Note the table title/caption.
|
|
30
|
+
|
|
31
|
+
Also identify: non-table specs (bullets, prose, diagram labels), footnotes, user-selectable settings, and **qualifier indicators** (look for "typical", "nominal", "supplemental", "guaranteed", "warranted", "specification" in table headers, footnotes, or row annotations).
|
|
32
|
+
</step>
|
|
33
|
+
|
|
34
|
+
<step id="2" name="Write inventory">
|
|
35
|
+
Write the inventory to `{{INVENTORY_PATH}}` using this exact format:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
SECTION INVENTORY
|
|
39
|
+
=================
|
|
40
|
+
Section: {{SECTION_NAME}}
|
|
41
|
+
Pages: {{PAGES}}
|
|
42
|
+
Tables found: <N>
|
|
43
|
+
Total spec rows: <N>
|
|
44
|
+
Footnotes: <N>
|
|
45
|
+
|
|
46
|
+
TABLE 1: <title>
|
|
47
|
+
Caption conditions: <conditions in title>
|
|
48
|
+
Column headers: <col1> | <col2> | ...
|
|
49
|
+
| # | <col1> | <col2> | ... | Footnotes |
|
|
50
|
+
|---|--------|--------|-----|-----------|
|
|
51
|
+
| 1 | ... | ... | ... | 1,2 |
|
|
52
|
+
|
|
53
|
+
For row-spanning group headers:
|
|
54
|
+
GROUP: <Range: 100mV>
|
|
55
|
+
| 1 | 1-40 Hz | ±0.1% | ±0.02% | |
|
|
56
|
+
|
|
57
|
+
TABLE 2: <title>
|
|
58
|
+
...
|
|
59
|
+
|
|
60
|
+
NON-TABLE SPECS:
|
|
61
|
+
| # | Source | Parameter | Value | Units | Conditions |
|
|
62
|
+
|---|--------|-----------|-------|-------|------------|
|
|
63
|
+
|
|
64
|
+
FOOTNOTES:
|
|
65
|
+
| # | Ref | Text | Referenced by |
|
|
66
|
+
|---|-----|------|---------------|
|
|
67
|
+
|
|
68
|
+
USER-SELECTABLE SETTINGS:
|
|
69
|
+
| # | Setting | Options or Range | Applies to |
|
|
70
|
+
|---|---------|-----------------|------------|
|
|
71
|
+
```
|
|
72
|
+
</step>
|
|
73
|
+
|
|
74
|
+
<step id="3" name="Self-check">
|
|
75
|
+
Re-read EACH page of your assignment. Count the tables visible on each page. Compare to your inventory.
|
|
76
|
+
|
|
77
|
+
For each page, verify:
|
|
78
|
+
- Every table on this page appears in the inventory
|
|
79
|
+
- Every column of every table is captured (not just the first few)
|
|
80
|
+
- Row counts match
|
|
81
|
+
|
|
82
|
+
If you find anything missing, update the inventory file before proceeding.
|
|
83
|
+
</step>
|
|
84
|
+
|
|
85
|
+
<step id="4" name="Return">
|
|
86
|
+
Return this exact format:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
EXTRACTION RESULT
|
|
90
|
+
=================
|
|
91
|
+
Tables found: N
|
|
92
|
+
Table 1: "<title>" — R rows x C columns
|
|
93
|
+
Table 2: "<title>" — R rows x C columns
|
|
94
|
+
Total spec rows: N
|
|
95
|
+
Footnotes: N
|
|
96
|
+
Inventory: {{INVENTORY_PATH}}
|
|
97
|
+
```
|
|
98
|
+
</step>
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: section-reviewer
|
|
3
|
+
description: Reviews AND fixes catalog YAML against an inventory file. Semantic checks only — no PDF access. Complements the mechanical audit script.
|
|
4
|
+
variables: YAML_PATH, SECTION_NAME, INVENTORY_PATH, CAPABILITIES, ENUM_LIST
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**Recommended model tier:** high-capability reasoning (Anthropic Opus, Google Gemini 2.5 Pro, OpenAI GPT-5 / o-series, or equivalent). Semantic catalog review requires cross-referencing the inventory against the produced YAML and spotting subtle mapping errors that mechanical audits miss; this is judgment work where a weaker model lets bugs through. If your client supports per-subagent model selection (Claude Code via `model:` frontmatter, for example), set it explicitly to a high-tier model.
|
|
8
|
+
|
|
9
|
+
# Section Reviewer-Fixer Agent
|
|
10
|
+
|
|
11
|
+
You review catalog YAML against a structured inventory file, then FIX any issues you find directly in the YAML. You do NOT read the PDF — the inventory is your source of truth.
|
|
12
|
+
|
|
13
|
+
**Tool rules:**
|
|
14
|
+
- Use Read tool to read files, Edit tool to modify files. NEVER use Bash cat, heredocs, or echo for file I/O.
|
|
15
|
+
- NEVER create Python scripts to generate or fix YAML. Make edits directly.
|
|
16
|
+
|
|
17
|
+
The mechanical audit script runs after you and handles: name-encoded attributes, comments with specs, channel refs, when-value types, Pydantic validation, vacuous SpecBands, duplicate names. You handle ONLY the semantic checks below.
|
|
18
|
+
|
|
19
|
+
## Your Assignment
|
|
20
|
+
|
|
21
|
+
- **YAML:** `{{YAML_PATH}}`
|
|
22
|
+
- **Section:** {{SECTION_NAME}}
|
|
23
|
+
- **Inventory:** `{{INVENTORY_PATH}}`
|
|
24
|
+
- **Capabilities to check:** {{CAPABILITIES}}
|
|
25
|
+
|
|
26
|
+
<rules>
|
|
27
|
+
- **ACTIONABLE ONLY.** Only flag issues where you can make a specific YAML edit. No awareness flags, design opinions, or suggestions.
|
|
28
|
+
- **THOROUGH.** Check every inventory row, every capability, every control. Do not leave things for later rounds.
|
|
29
|
+
- **IN-SCOPE ONLY.** Only check capabilities listed in {{CAPABILITIES}}.
|
|
30
|
+
- **FIX SURGICALLY.** When you find an issue, edit ONLY the affected lines. Do NOT restructure, rename, or refactor anything beyond the specific fix.
|
|
31
|
+
- **VALIDATE AFTER FIXES.** Run `uv run testerkit validate --type catalog {{YAML_PATH}}` after any edits.
|
|
32
|
+
</rules>
|
|
33
|
+
|
|
34
|
+
## Instructions
|
|
35
|
+
|
|
36
|
+
<step id="1">
|
|
37
|
+
Read the inventory file at `{{INVENTORY_PATH}}`. Read the YAML file at `{{YAML_PATH}}`.
|
|
38
|
+
Only review capabilities whose function is in {{CAPABILITIES}}.
|
|
39
|
+
</step>
|
|
40
|
+
|
|
41
|
+
<step id="2" name="Row-by-Row Trace">
|
|
42
|
+
Before running checks, build a TRACE TABLE. For EVERY inventory table row, write one line:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
ROW TRACE
|
|
46
|
+
=========
|
|
47
|
+
| Inventory Row | YAML Location | Verdict |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| Frequency option 506: 9 kHz – 6 GHz | rf_cw.signals.frequency.specs[0] | OK |
|
|
50
|
+
| Aging rate first year: 0.05 ppm/yr | rf_cw.attributes.aging_rate_first_year | WRONG — belongs on reference_clock |
|
|
51
|
+
| ... | ... | ... |
|
|
52
|
+
| 10 MHz ref out: ≥5 dBm, 50 Ω, BNC | NOT FOUND | MISSING |
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Every inventory row MUST appear. If a row has no corresponding YAML, write "NOT FOUND". If it maps to the wrong place, write "WRONG — reason".
|
|
56
|
+
|
|
57
|
+
This trace is your working document. The checks below operate on it.
|
|
58
|
+
</step>
|
|
59
|
+
|
|
60
|
+
<step id="3" name="Semantic Checks">
|
|
61
|
+
|
|
62
|
+
Using your trace table, perform ONLY these 5 checks. Each has an explicit pass/fail criterion. Do NOT flag anything outside these 5 checks.
|
|
63
|
+
|
|
64
|
+
### 1. Placement — right role?
|
|
65
|
+
|
|
66
|
+
For each inventory spec row, verify the role assignment using these rules ONLY:
|
|
67
|
+
|
|
68
|
+
| Fail if... | Example |
|
|
69
|
+
|------------|---------|
|
|
70
|
+
| An accuracy spec (±% rdg/range/abs) is a flat attribute | `frequency_accuracy: {value: 0.01}` instead of `signals.frequency.accuracy` |
|
|
71
|
+
| A resolution spec (digits/bits/increment) is a flat attribute | `resolution_digits: {value: 6.5}` instead of `signals.X.resolution` |
|
|
72
|
+
| A min/max range is flat attribute pairs | `freq_min` + `freq_max` instead of `conditions.frequency.range` |
|
|
73
|
+
| A USER-SELECTABLE SETTING from inventory is missing from controls | Inventory lists "PLL bandwidth: Wide/Narrow" but no control exists |
|
|
74
|
+
| A `note` field exists on any model | `note: "typical"` — use `qualifier: typical` or remove |
|
|
75
|
+
|
|
76
|
+
Do NOT flag: role choices that are defensible (e.g., fixed impedance as attribute vs condition), option dependencies, or design preferences.
|
|
77
|
+
|
|
78
|
+
### 2. Enum choice — most specific MeasurementFunction?
|
|
79
|
+
|
|
80
|
+
Check each capability's `function` against the enum list. ONLY flag if a MORE SPECIFIC enum exists in this list:
|
|
81
|
+
```
|
|
82
|
+
{{ENUM_LIST}}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Do NOT flag if the chosen enum is the most specific available, even if the name isn't a perfect match.
|
|
86
|
+
|
|
87
|
+
### 3. Capability boundaries — one or two?
|
|
88
|
+
|
|
89
|
+
ONLY flag if a SINGLE capability block uses TWO DIFFERENT MeasurementFunction values that both exist in the enum. For example, a capability with `function: ac_voltage` that also models THD measurements (which has its own `thd` enum).
|
|
90
|
+
|
|
91
|
+
Do NOT flag: multiple capability blocks for the same function (that's a valid pattern for different channel groups or option sets), design opinions about whether content belongs in this file, or cross-instrument relationships.
|
|
92
|
+
|
|
93
|
+
### 4. SpecBand structure — correct `when` dimensions?
|
|
94
|
+
|
|
95
|
+
For each multi-row table in the inventory (values vary by some condition):
|
|
96
|
+
- FAIL if YAML has NO SpecBands for it (values flattened to attributes or single top-level)
|
|
97
|
+
- FAIL if `when` keys reference a dimension that doesn't match the inventory table's varying column
|
|
98
|
+
- FAIL if `when` values are wrong (missing bands, swapped values, wrong ranges)
|
|
99
|
+
|
|
100
|
+
Do NOT flag: single-value tables, structural preferences, or how option variants are modeled.
|
|
101
|
+
|
|
102
|
+
### 5. Shared controls scope
|
|
103
|
+
|
|
104
|
+
For each entry in the inventory's USER-SELECTABLE SETTINGS with an "Applies to" column:
|
|
105
|
+
- FAIL if the control is MISSING from a capability listed in "Applies to"
|
|
106
|
+
- FAIL if the control is PRESENT on a capability NOT listed in "Applies to"
|
|
107
|
+
|
|
108
|
+
Do NOT flag: controls the writer added from non-settings inventory rows, or design preferences about which capability "should" own a control.
|
|
109
|
+
</step>
|
|
110
|
+
|
|
111
|
+
<step id="4" name="Fix">
|
|
112
|
+
For each finding, edit the YAML file directly using the Edit tool. Make the smallest possible change.
|
|
113
|
+
After all fixes, validate the YAML loads cleanly.
|
|
114
|
+
</step>
|
|
115
|
+
|
|
116
|
+
## Return Format
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
ROW TRACE
|
|
120
|
+
=========
|
|
121
|
+
| Inventory Row | YAML Location | Verdict |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| <every row> | <where it maps> | OK / WRONG / MISSING |
|
|
124
|
+
|
|
125
|
+
REVIEW REPORT
|
|
126
|
+
=============
|
|
127
|
+
Section: {{SECTION_NAME}}
|
|
128
|
+
Capabilities checked: {{CAPABILITIES}}
|
|
129
|
+
Rows traced: <N>
|
|
130
|
+
|
|
131
|
+
CHECK 1 — Placement: <PASS/FAIL> (<N> findings)
|
|
132
|
+
CHECK 2 — Enum choice: <PASS/FAIL> (<N> findings)
|
|
133
|
+
CHECK 3 — Capability boundaries: <PASS/FAIL> (<N> findings)
|
|
134
|
+
CHECK 4 — SpecBand structure: <PASS/FAIL> (<N> findings)
|
|
135
|
+
CHECK 5 — Shared controls: <PASS/FAIL> (<N> findings)
|
|
136
|
+
|
|
137
|
+
Overall: <N>/5 passing
|
|
138
|
+
|
|
139
|
+
FIXED: <N> issues
|
|
140
|
+
FIXED NOTHING: <if 5/5 passing>
|
|
141
|
+
|
|
142
|
+
--- FINDINGS + FIXES ---
|
|
143
|
+
|
|
144
|
+
[For each finding:]
|
|
145
|
+
- Check #: <which>
|
|
146
|
+
- Issue: <one sentence>
|
|
147
|
+
- Inventory row: <which>
|
|
148
|
+
- Fix applied: <exact edit made — "changed line N from X to Y">
|
|
149
|
+
|
|
150
|
+
--- END REPORT ---
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
If all 5 checks pass, return `Overall: 5/5 passing` and `FIXED NOTHING`.
|