systemlink-cli 1.29.1__tar.gz → 1.29.4__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.
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/PKG-INFO +1 -1
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/pyproject.toml +1 -1
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/_version.py +1 -1
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/config_click.py +20 -4
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/platform.py +77 -22
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/SKILL.md +1 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/evals/evals.json +275 -1
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/evals/evals.schema.json +3 -2
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/analysis-recipes.md +75 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/commands.md +12 -0
- systemlink_cli-1.29.4/slcli/skills/slcli/references/domain-concepts.md +106 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/filtering.md +37 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/scripts/eval_manifest.py +6 -2
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/scripts/grade_eval_response.py +24 -1
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/tsconfig.json +2 -3
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/LICENSE +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/dff-editor/editor.js +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/dff-editor/index.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/__init__.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/__main__.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/alarm_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/asset_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/cli_formatters.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/cli_utils.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/comment_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/completion_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/config.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/dataframe_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/dff_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/dff_decorators.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/example_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/example_loader.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/example_provisioner.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/README.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/_schema/schema-v1.0.json +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/demo-data-1/README.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/demo-data-1/config.yaml +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/demo-data-2/README.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/demo-data-2/config.yaml +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/demo-data-3/config.yaml +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/demo-data-3/leakage-current-results.json +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/demo-data-3/overvoltage-results.json +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/demo-data-3/product-xyz-compliance-report.json +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/demo-data-3/product-xyz-specification.csv +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/demo-data-3/thermal-response-results.json +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/exercise-5-1-parametric-insights/README.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/exercise-5-1-parametric-insights/config.yaml +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/exercise-7-1-test-plans/README.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/exercise-7-1-test-plans/config.yaml +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/spec-compliance-notebooks/README.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/spec-compliance-notebooks/config.yaml +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/spec-compliance-notebooks/notebooks/SpecAnalysis_ComplianceCalculation.ipynb +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/spec-compliance-notebooks/notebooks/SpecComplianceCalculation.ipynb +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/spec-compliance-notebooks/notebooks/SpecfileExtractionAndIngestion.ipynb +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/examples/spec-compliance-notebooks/spec_template.xlsx +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/feed_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/file_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/function_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/function_templates.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/main.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/mcp_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/mcp_reachability.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/mcp_server.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/mcp_skills.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/notebook_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/pkce.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/policy_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/policy_utils.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/profiles.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/response_handlers.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/rich_output.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/routine_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skill_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/evals/COPILOT_BATCH_RUN_PROMPT.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/evals/README.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/evals/files/spec-import/battery-specs.csv +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/evals/files/webapp-package/icon.svg +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/evals/files/webapp-package/nipkg.config.json +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/evals/files/webapp-package/webapp-content/index.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/evals/trigger_evals.json +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/datasheet-workflow.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/example-authoring.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/import-specs.min.json +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/job-debugging/overview.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/nipkg/overview.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/notebook/interfaces.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/notebook/notebook-patterns.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/notebook/overview.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/python-test/overview.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/routine-examples.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/troubleshooting.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/webapp/angular-ui-packages.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/webapp/deployment.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/webapp/layout-patterns.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/webapp/nimble-angular.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/webapp/overview.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/webapp/systemlink-services.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/references/webapp/troubleshooting.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/scripts/benchmark_iteration.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/scripts/compare_iteration.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/scripts/grade_iteration.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/scripts/prepare_eval_prompts.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/scripts/prepare_eval_workspace.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/scripts/render_eval_review.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/skills/slcli/scripts/spec_import_helper.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/spec_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/ssl_trust.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/state_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/system_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/system_query_utils.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/systemlink-logo.svg +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/table_utils.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/tag_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/templates_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/testmonitor_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/universal_handlers.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/user_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/utils.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/version_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/web_editor.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_bootstrap.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/.gitignore +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/README.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/angular.json +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/package.json +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/scripts/filter-sbom.js +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/app-routing.module.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/app.component.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/app.component.scss +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/app.component.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/app.module.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/core/layout/app-shell.component.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/core/layout/app-shell.component.scss +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/core/layout/app-shell.component.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/core/state/app-view-state.service.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/core/systemlink/systemlink-context.service.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/core/systemlink/theme-sync.service.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/core/systemlink/webapp-home-data.service.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.scss +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.scss +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/home/home-page.component.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/home/home-page.component.scss +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/home/home-page.component.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/master-detail/master-detail-page.component.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/master-detail/master-detail-page.component.scss +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/master-detail/master-detail-page.component.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/operations/operations-page.component.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/operations/operations-page.component.scss +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/operations/operations-page.component.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.scss +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/shared/components/empty-state.component.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/shared/components/empty-state.component.scss +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/shared/components/empty-state.component.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/shared/components/error-banner.component.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/shared/components/error-banner.component.scss +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/shared/components/error-banner.component.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/shared/components/loading-state.component.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/shared/components/loading-state.component.scss +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/shared/components/loading-state.component.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/app/shared/states/view-state.model.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/assets/README.md +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/index.html +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/main.ts +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/src/styles.scss +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/webapp_templates/angular/blank/tsconfig.app.json +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/workflow_preview.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/workflows_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/workitem_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/workspace_click.py +0 -0
- {systemlink_cli-1.29.1 → systemlink_cli-1.29.4}/slcli/workspace_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "systemlink-cli"
|
|
3
|
-
version = "1.29.
|
|
3
|
+
version = "1.29.4"
|
|
4
4
|
description = "SystemLink Integrator CLI - cross-platform CLI for SystemLink workflows and templates."
|
|
5
5
|
authors = ["Fred Visser <fred.visser@emerson.com>"]
|
|
6
6
|
packages = [{ include = "slcli" }]
|
|
@@ -109,6 +109,11 @@ def _all_service_probes_unauthorized(services: dict[str, str]) -> bool:
|
|
|
109
109
|
return bool(services) and all(status == "unauthorized" for status in services.values())
|
|
110
110
|
|
|
111
111
|
|
|
112
|
+
def _any_service_probes_unauthorized(services: dict[str, str]) -> bool:
|
|
113
|
+
"""Return True if any recorded service probe failed with authorization."""
|
|
114
|
+
return bool(services) and any(status == "unauthorized" for status in services.values())
|
|
115
|
+
|
|
116
|
+
|
|
112
117
|
def _normalize_fingerprint(fingerprint: str) -> str:
|
|
113
118
|
"""Normalize a SHA-256 certificate fingerprint supplied by a user."""
|
|
114
119
|
normalized = fingerprint.replace(":", "").replace(" ", "").strip().upper()
|
|
@@ -179,7 +184,10 @@ def _trust_certificate_if_requested(
|
|
|
179
184
|
|
|
180
185
|
try:
|
|
181
186
|
save_managed_certificate(certificate)
|
|
182
|
-
|
|
187
|
+
if auth_scheme == "bearer":
|
|
188
|
+
retry_status = check_web_server_auth(url, credential, auth_scheme=auth_scheme)
|
|
189
|
+
else:
|
|
190
|
+
retry_status = check_service_status(url, credential, auth_scheme=auth_scheme)
|
|
183
191
|
except (OSError, ValueError) as exc:
|
|
184
192
|
_exit_with_validation_error(
|
|
185
193
|
f"Could not save the trusted certificate: {exc}. Profile was not saved.",
|
|
@@ -303,10 +311,10 @@ def _add_profile_impl(
|
|
|
303
311
|
|
|
304
312
|
assert isinstance(api_key, str)
|
|
305
313
|
|
|
306
|
-
# PKCE
|
|
314
|
+
# Validate PKCE against the Web Server identity route; API-key login retains API probes.
|
|
307
315
|
click.echo("Checking server connectivity and services...")
|
|
308
316
|
if auth_mode == "pkce":
|
|
309
|
-
status =
|
|
317
|
+
status = check_web_server_auth(web_url, api_key, auth_scheme="bearer")
|
|
310
318
|
else:
|
|
311
319
|
status = check_service_status(url, api_key)
|
|
312
320
|
|
|
@@ -321,6 +329,11 @@ def _add_profile_impl(
|
|
|
321
329
|
)
|
|
322
330
|
|
|
323
331
|
platform = status["platform"]
|
|
332
|
+
if auth_mode == "pkce":
|
|
333
|
+
platform_status = check_service_status(web_url, api_key, auth_scheme="bearer")
|
|
334
|
+
detected_platform = platform_status.get("platform")
|
|
335
|
+
if detected_platform in (PLATFORM_SLE, PLATFORM_SLS):
|
|
336
|
+
platform = detected_platform
|
|
324
337
|
services = status.get("services", {})
|
|
325
338
|
|
|
326
339
|
if not status["server_reachable"]:
|
|
@@ -330,7 +343,10 @@ def _add_profile_impl(
|
|
|
330
343
|
ExitCodes.NETWORK_ERROR,
|
|
331
344
|
)
|
|
332
345
|
|
|
333
|
-
if status["auth_valid"] is False and
|
|
346
|
+
if status["auth_valid"] is False and (
|
|
347
|
+
_all_service_probes_unauthorized(services)
|
|
348
|
+
or (_any_service_probes_unauthorized(services) and platform == PLATFORM_SLS)
|
|
349
|
+
):
|
|
334
350
|
auth_failure_message = (
|
|
335
351
|
"PKCE bearer token validation failed. The server responded, but the token was not authorized. "
|
|
336
352
|
if auth_mode == "pkce"
|
|
@@ -88,6 +88,7 @@ FILE_QUERY_LINQ_PATH = "/nifile/v1/service-groups/Default/query-files-linq"
|
|
|
88
88
|
SYSTEM_SEARCH_PATH = "/nisysmgmt/v1/materialized/search-systems"
|
|
89
89
|
SYSTEM_QUERY_PATH = "/nisysmgmt/v1/query-systems"
|
|
90
90
|
WEB_SERVER_AUTH_PATH = "/niauth/v1/auth"
|
|
91
|
+
SLS_PLATFORM_PROBE_PATH = "/nitagrule/"
|
|
91
92
|
|
|
92
93
|
SLE_ONLY_SERVICE_NAMES = (
|
|
93
94
|
"Dynamic Form Fields",
|
|
@@ -97,17 +98,22 @@ SLE_ONLY_SERVICE_NAMES = (
|
|
|
97
98
|
)
|
|
98
99
|
|
|
99
100
|
|
|
100
|
-
def _detect_platform_from_services(
|
|
101
|
-
|
|
101
|
+
def _detect_platform_from_services(
|
|
102
|
+
services: Dict[str, str], sls_platform_status: Optional[str] = None
|
|
103
|
+
) -> str:
|
|
104
|
+
"""Infer the platform from positive platform capability probes.
|
|
102
105
|
|
|
103
106
|
Args:
|
|
104
107
|
services: Mapping of service display name to probe status.
|
|
105
108
|
|
|
106
109
|
Returns:
|
|
107
110
|
PLATFORM_SLE when any SLE-only service is reachable or explicitly
|
|
108
|
-
unauthorized, PLATFORM_SLS when
|
|
111
|
+
unauthorized, PLATFORM_SLS when the SLS-only platform probe succeeds,
|
|
109
112
|
otherwise PLATFORM_UNKNOWN.
|
|
110
113
|
"""
|
|
114
|
+
if sls_platform_status == "ok":
|
|
115
|
+
return PLATFORM_SLS
|
|
116
|
+
|
|
111
117
|
sle_statuses = [services.get(name) for name in SLE_ONLY_SERVICE_NAMES if name in services]
|
|
112
118
|
if not sle_statuses:
|
|
113
119
|
return PLATFORM_UNKNOWN
|
|
@@ -115,12 +121,47 @@ def _detect_platform_from_services(services: Dict[str, str]) -> str:
|
|
|
115
121
|
if any(status in ("ok", "unauthorized") for status in sle_statuses):
|
|
116
122
|
return PLATFORM_SLE
|
|
117
123
|
|
|
118
|
-
if all(status == "not_found" for status in sle_statuses):
|
|
119
|
-
return PLATFORM_SLS
|
|
120
|
-
|
|
121
124
|
return PLATFORM_UNKNOWN
|
|
122
125
|
|
|
123
126
|
|
|
127
|
+
def _is_valid_sls_platform_probe(response: requests.Response) -> bool:
|
|
128
|
+
"""Return whether a Tag Rule Engine response identifies an SLS instance."""
|
|
129
|
+
try:
|
|
130
|
+
payload = response.json()
|
|
131
|
+
except ValueError:
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
return isinstance(payload, dict) and (
|
|
135
|
+
isinstance(payload.get("v1"), dict) and "version" in payload
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _probe_sls_platform(api_url: str, credential: str, auth_scheme: str = "api-key") -> str:
|
|
140
|
+
"""Probe the unauthenticated Tag Rule Engine versioning endpoint."""
|
|
141
|
+
headers = get_auth_headers(credential, auth_scheme, "application/json")
|
|
142
|
+
ssl_verify = get_ssl_verify(api_url)
|
|
143
|
+
|
|
144
|
+
try:
|
|
145
|
+
response = requests.get(
|
|
146
|
+
f"{api_url}{SLS_PLATFORM_PROBE_PATH}",
|
|
147
|
+
headers=headers,
|
|
148
|
+
verify=ssl_verify,
|
|
149
|
+
timeout=10,
|
|
150
|
+
)
|
|
151
|
+
except requests.exceptions.SSLError:
|
|
152
|
+
return "certificate_error"
|
|
153
|
+
except requests.RequestException:
|
|
154
|
+
return "unreachable"
|
|
155
|
+
|
|
156
|
+
if response.status_code == 200:
|
|
157
|
+
return "ok" if _is_valid_sls_platform_probe(response) else "error"
|
|
158
|
+
if response.status_code in (401, 403):
|
|
159
|
+
return "unauthorized"
|
|
160
|
+
if response.status_code in (404, 501):
|
|
161
|
+
return "not_found"
|
|
162
|
+
return "error"
|
|
163
|
+
|
|
164
|
+
|
|
124
165
|
def _get_keyring_config() -> Dict[str, Any]:
|
|
125
166
|
"""Attempt to read a single JSON config entry from keyring.
|
|
126
167
|
|
|
@@ -200,6 +241,7 @@ def get_platform() -> str:
|
|
|
200
241
|
):
|
|
201
242
|
pass
|
|
202
243
|
|
|
244
|
+
# Priority 3: Stored platform from keyring config (legacy fallback)
|
|
203
245
|
cfg = _get_keyring_config()
|
|
204
246
|
if cfg:
|
|
205
247
|
platform = str(cfg.get("platform", "")).upper()
|
|
@@ -438,7 +480,7 @@ def _get_service_status_snapshot(force_refresh: bool = False) -> Optional[Dict[s
|
|
|
438
480
|
|
|
439
481
|
_, api_url, credential, auth_scheme = api_context
|
|
440
482
|
if auth_scheme == "bearer":
|
|
441
|
-
status =
|
|
483
|
+
status = check_web_server_auth(api_url, credential, auth_scheme)
|
|
442
484
|
else:
|
|
443
485
|
status = check_service_status(api_url, credential)
|
|
444
486
|
_save_service_status_snapshot(api_context, status)
|
|
@@ -783,8 +825,6 @@ def _check_service_status(
|
|
|
783
825
|
|
|
784
826
|
services: Dict[str, str] = {}
|
|
785
827
|
any_responded = False
|
|
786
|
-
any_authorized = False
|
|
787
|
-
all_unauthorized = True
|
|
788
828
|
certificate_error = False
|
|
789
829
|
|
|
790
830
|
for display_name, method, url_path in SERVICE_CHECKS:
|
|
@@ -809,26 +849,39 @@ def _check_service_status(
|
|
|
809
849
|
|
|
810
850
|
if resp.status_code in (200, 400):
|
|
811
851
|
services[display_name] = "ok"
|
|
812
|
-
any_authorized = True
|
|
813
|
-
all_unauthorized = False
|
|
814
852
|
elif resp.status_code == 401:
|
|
815
853
|
services[display_name] = "unauthorized"
|
|
816
854
|
elif resp.status_code == 403:
|
|
817
855
|
services[display_name] = "unauthorized"
|
|
818
856
|
elif resp.status_code == 404:
|
|
819
857
|
services[display_name] = "not_found"
|
|
820
|
-
all_unauthorized = False
|
|
821
858
|
else:
|
|
822
859
|
services[display_name] = "error"
|
|
823
|
-
all_unauthorized = False
|
|
824
860
|
except requests.exceptions.SSLError:
|
|
825
861
|
services[display_name] = "certificate_error"
|
|
826
862
|
certificate_error = True
|
|
827
863
|
except requests.RequestException:
|
|
828
864
|
services[display_name] = "unreachable"
|
|
829
865
|
|
|
866
|
+
sls_platform_status = _probe_sls_platform(api_url, credential, auth_scheme)
|
|
867
|
+
certificate_error = certificate_error or sls_platform_status == "certificate_error"
|
|
868
|
+
|
|
830
869
|
# Determine overall status
|
|
831
870
|
if not any_responded:
|
|
871
|
+
if sls_platform_status not in ("unreachable", "certificate_error"):
|
|
872
|
+
return {
|
|
873
|
+
"server_reachable": True,
|
|
874
|
+
"auth_valid": None,
|
|
875
|
+
"services": services,
|
|
876
|
+
"certificate_error": certificate_error,
|
|
877
|
+
"certificate": None,
|
|
878
|
+
"file_query_endpoint": None,
|
|
879
|
+
"elasticsearch_available": None,
|
|
880
|
+
"system_query_endpoint": None,
|
|
881
|
+
"materialized_search_available": None,
|
|
882
|
+
"platform": _detect_platform_from_services(services, sls_platform_status),
|
|
883
|
+
}
|
|
884
|
+
|
|
832
885
|
certificate_details: Optional[Dict[str, Any]] = None
|
|
833
886
|
if certificate_error:
|
|
834
887
|
try:
|
|
@@ -850,20 +903,20 @@ def _check_service_status(
|
|
|
850
903
|
"platform": PLATFORM_UNREACHABLE,
|
|
851
904
|
}
|
|
852
905
|
|
|
853
|
-
# Determine
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
if all_unauthorized and any_responded:
|
|
857
|
-
auth_valid = False
|
|
858
|
-
|
|
859
|
-
# Determine platform from multiple SLE-only service responses.
|
|
860
|
-
platform = _detect_platform_from_services(services)
|
|
906
|
+
# Determine platform from positive capability probes.
|
|
907
|
+
platform = _detect_platform_from_services(services, sls_platform_status)
|
|
908
|
+
initial_auth_valid = any(status == "ok" for status in services.values())
|
|
861
909
|
|
|
862
910
|
file_capability = get_file_query_capability(api_url, credential, auth_scheme)
|
|
863
911
|
services["File"] = file_capability["status"]
|
|
864
912
|
system_capability = get_system_query_capability(api_url, credential, auth_scheme)
|
|
865
913
|
services["Systems"] = system_capability["status"]
|
|
866
914
|
|
|
915
|
+
# Recompute auth after capability probes add their final service statuses.
|
|
916
|
+
auth_valid = initial_auth_valid or any(
|
|
917
|
+
status in ("ok", "fallback") for status in services.values()
|
|
918
|
+
)
|
|
919
|
+
|
|
867
920
|
return {
|
|
868
921
|
"server_reachable": True,
|
|
869
922
|
"auth_valid": auth_valid,
|
|
@@ -945,7 +998,9 @@ def get_platform_info(skip_health: bool = False) -> Dict[str, Any]:
|
|
|
945
998
|
server_reachable = status["server_reachable"]
|
|
946
999
|
auth_valid = status["auth_valid"]
|
|
947
1000
|
services = status["services"]
|
|
948
|
-
|
|
1001
|
+
detected_platform = status.get("platform", PLATFORM_UNKNOWN)
|
|
1002
|
+
if detected_platform != PLATFORM_UNKNOWN:
|
|
1003
|
+
platform = detected_platform
|
|
949
1004
|
file_query_endpoint = status.get("file_query_endpoint")
|
|
950
1005
|
elasticsearch_available = status.get("elasticsearch_available")
|
|
951
1006
|
system_query_endpoint = status.get("system_query_endpoint")
|
|
@@ -36,6 +36,7 @@ Load only what the current task needs.
|
|
|
36
36
|
| Datasheet-to-spec workflow | [datasheet-workflow.md](./references/datasheet-workflow.md) | Importing specifications from PDF, CSV, or structured text |
|
|
37
37
|
| Minimal spec import payload | [import-specs.min.json](./references/import-specs.min.json) | Need a bundled create-compatible starter payload or conditions |
|
|
38
38
|
| Spec import helper | [spec_import_helper.py](./scripts/spec_import_helper.py) | Scaffold or validate a datasheet spec import payload |
|
|
39
|
+
| Domain concepts | [domain-concepts.md](./references/domain-concepts.md) | Interpreting resource terminology, relationships, identifiers, status intent, or availability |
|
|
39
40
|
| Filtering guide | [filtering.md](./references/filtering.md) | Advanced filters, LINQ syntax, and query composition |
|
|
40
41
|
| Analysis recipes | [analysis-recipes.md](./references/analysis-recipes.md) | Multi-step analysis workflows and reporting patterns |
|
|
41
42
|
| Troubleshooting | [troubleshooting.md](./references/troubleshooting.md) | SSL, workspace IDs, encoding, or scripting pitfalls |
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"skill_name": "slcli",
|
|
4
4
|
"recommended_suites": {
|
|
5
5
|
"gating": [1, 4, 5, 7, 10],
|
|
6
|
-
"regression": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
|
|
6
|
+
"regression": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
|
|
7
7
|
},
|
|
8
8
|
"evals": [
|
|
9
9
|
{
|
|
@@ -637,6 +637,280 @@
|
|
|
637
637
|
]
|
|
638
638
|
}
|
|
639
639
|
]
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
"id": 12,
|
|
643
|
+
"tags": ["regression", "testmonitor", "status-intent"],
|
|
644
|
+
"prompt": "Show me failed SystemLink tests from the last seven days. Treat every terminal failure outcome as a failure.",
|
|
645
|
+
"expected_output": "Uses one parameterized testmonitor query covering FAILED, ERRORED, and TERMINATED, constrained to results started during the last seven days without matching unrelated statuses.",
|
|
646
|
+
"files": [],
|
|
647
|
+
"expectations": [
|
|
648
|
+
"Uses the testmonitor result list command",
|
|
649
|
+
"Expands broad failure intent to FAILED, ERRORED, and TERMINATED",
|
|
650
|
+
"Uses substitutions rather than interpolating status values",
|
|
651
|
+
"Adds a parameterized startedAt lower bound for the last seven days",
|
|
652
|
+
"Does not implement failure as everything other than PASSED"
|
|
653
|
+
],
|
|
654
|
+
"grading_rules": [
|
|
655
|
+
{
|
|
656
|
+
"text": "Queries test results",
|
|
657
|
+
"critical": true,
|
|
658
|
+
"positive_control": "slcli testmonitor result list --format json",
|
|
659
|
+
"negative_control": "slcli testmonitor product list --format json",
|
|
660
|
+
"scope": "command",
|
|
661
|
+
"mode": "any_of",
|
|
662
|
+
"patterns": [
|
|
663
|
+
"slcli\\s+testmonitor\\s+result\\s+list"
|
|
664
|
+
]
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
"text": "Includes all terminal failure statuses",
|
|
668
|
+
"critical": true,
|
|
669
|
+
"positive_control": "slcli testmonitor result list --filter 'status.statusType == @0 or status.statusType == @1 or status.statusType == @2' --substitution FAILED --substitution ERRORED --substitution TERMINATED",
|
|
670
|
+
"negative_control": "slcli testmonitor result list --status FAILED",
|
|
671
|
+
"scope": "command",
|
|
672
|
+
"mode": "all_of",
|
|
673
|
+
"patterns": [
|
|
674
|
+
"--substitution\\s+FAILED",
|
|
675
|
+
"--substitution\\s+ERRORED",
|
|
676
|
+
"--substitution\\s+TERMINATED",
|
|
677
|
+
"--filter\\s+[^\\n]*status\\.statusType\\s*==\\s*@0",
|
|
678
|
+
"--filter\\s+[^\\n]*status\\.statusType\\s*==\\s*@1",
|
|
679
|
+
"--filter\\s+[^\\n]*status\\.statusType\\s*==\\s*@2"
|
|
680
|
+
]
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
"text": "Avoids not-passed filtering",
|
|
684
|
+
"critical": true,
|
|
685
|
+
"positive_control": "slcli testmonitor result list --filter 'status.statusType == @0' --substitution FAILED",
|
|
686
|
+
"negative_control": "slcli testmonitor result list --filter 'status.statusType != @0' --substitution PASSED",
|
|
687
|
+
"scope": "command",
|
|
688
|
+
"mode": "none_of",
|
|
689
|
+
"patterns": [
|
|
690
|
+
"status\\.statusType\\s*!=",
|
|
691
|
+
"NOT\\s+PASSED"
|
|
692
|
+
]
|
|
693
|
+
},
|
|
694
|
+
{
|
|
695
|
+
"text": "Constrains results to the last seven days",
|
|
696
|
+
"critical": true,
|
|
697
|
+
"positive_control": "slcli testmonitor result list --filter '(status.statusType == @0 or status.statusType == @1 or status.statusType == @2) and startedAt >= @3' --substitution FAILED --substitution ERRORED --substitution TERMINATED --substitution 2026-09-10T00:00:00Z",
|
|
698
|
+
"negative_control": "slcli testmonitor result list --filter 'status.statusType == @0 or status.statusType == @1 or status.statusType == @2' --substitution FAILED --substitution ERRORED --substitution TERMINATED",
|
|
699
|
+
"scope": "command",
|
|
700
|
+
"mode": "all_of",
|
|
701
|
+
"validator": "last_n_days",
|
|
702
|
+
"days": 7,
|
|
703
|
+
"control_reference_date": "2026-09-17",
|
|
704
|
+
"patterns": [
|
|
705
|
+
"startedAt\\s*>=\\s*@\\d+",
|
|
706
|
+
"--substitution\\s+\\d{4}-\\d{2}-\\d{2}T00:00:00Z"
|
|
707
|
+
]
|
|
708
|
+
}
|
|
709
|
+
]
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
"id": 13,
|
|
713
|
+
"tags": ["regression", "packages", "routing"],
|
|
714
|
+
"prompt": "Show the commands to check packages available in feed FEED-1, packages installed on system SYS-1, and packages declared by desired state STATE-1.",
|
|
715
|
+
"expected_output": "Routes repository availability, observed installation, and desired-state membership to three distinct slcli command surfaces.",
|
|
716
|
+
"files": [],
|
|
717
|
+
"expectations": [
|
|
718
|
+
"Uses feed package list for available packages",
|
|
719
|
+
"Uses system details with installed packages for observed installation",
|
|
720
|
+
"Uses state details for desired packages",
|
|
721
|
+
"Does not imply that any one package view proves another"
|
|
722
|
+
],
|
|
723
|
+
"grading_rules": [
|
|
724
|
+
{
|
|
725
|
+
"text": "Queries available feed packages",
|
|
726
|
+
"critical": true,
|
|
727
|
+
"positive_control": "slcli feed package list --feed-id FEED-1 --format json",
|
|
728
|
+
"negative_control": "slcli feed list --format json",
|
|
729
|
+
"scope": "command",
|
|
730
|
+
"mode": "all_of",
|
|
731
|
+
"patterns": [
|
|
732
|
+
"slcli\\s+feed\\s+package\\s+list",
|
|
733
|
+
"--feed-id\\s+FEED-1"
|
|
734
|
+
]
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
"text": "Queries installed system packages",
|
|
738
|
+
"critical": true,
|
|
739
|
+
"positive_control": "slcli system get SYS-1 --include-packages --format json",
|
|
740
|
+
"negative_control": "slcli system get SYS-1 --format json",
|
|
741
|
+
"scope": "command",
|
|
742
|
+
"mode": "all_of",
|
|
743
|
+
"patterns": [
|
|
744
|
+
"slcli\\s+system\\s+get\\s+SYS-1",
|
|
745
|
+
"--include-packages"
|
|
746
|
+
]
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
"text": "Queries desired-state packages",
|
|
750
|
+
"critical": true,
|
|
751
|
+
"positive_control": "slcli state get STATE-1 --format json",
|
|
752
|
+
"negative_control": "slcli state list --format json",
|
|
753
|
+
"scope": "command",
|
|
754
|
+
"mode": "any_of",
|
|
755
|
+
"patterns": [
|
|
756
|
+
"slcli\\s+state\\s+get\\s+STATE-1"
|
|
757
|
+
]
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
"text": "Keeps package views independent",
|
|
761
|
+
"critical": true,
|
|
762
|
+
"positive_control": "slcli feed package list --feed-id FEED-1 --format json\nslcli system get SYS-1 --include-packages --format json\nslcli state get STATE-1 --format json\nThese are independent facts; do not infer one from another.",
|
|
763
|
+
"negative_control": "slcli feed package list --feed-id FEED-1 --format json\nslcli system get SYS-1 --include-packages --format json\nslcli state get STATE-1 --format json",
|
|
764
|
+
"scope": "response",
|
|
765
|
+
"mode": "all_of",
|
|
766
|
+
"patterns": [
|
|
767
|
+
"independent facts",
|
|
768
|
+
"do not infer"
|
|
769
|
+
]
|
|
770
|
+
}
|
|
771
|
+
]
|
|
772
|
+
},
|
|
773
|
+
{
|
|
774
|
+
"id": 14,
|
|
775
|
+
"tags": ["regression", "systems", "health"],
|
|
776
|
+
"prompt": "Check the current health of SystemLink system SYS-1, including current health signals and active alarm instances.",
|
|
777
|
+
"expected_output": "Combines system state, active alarm instances, and current CPU, memory, and disk health-tag values without inventing thresholds or claiming that an empty instance query means no alarm rule is configured.",
|
|
778
|
+
"files": [],
|
|
779
|
+
"expectations": [
|
|
780
|
+
"Retrieves system details and active alarm instances",
|
|
781
|
+
"Reads the three standard current health tags",
|
|
782
|
+
"Treats missing or stale evidence as an incomplete health conclusion",
|
|
783
|
+
"Does not invent utilization thresholds"
|
|
784
|
+
],
|
|
785
|
+
"grading_rules": [
|
|
786
|
+
{
|
|
787
|
+
"text": "Includes system and alarm state",
|
|
788
|
+
"critical": true,
|
|
789
|
+
"positive_control": "slcli system get SYS-1 --include-alarms --format json",
|
|
790
|
+
"negative_control": "slcli system get SYS-1 --format json",
|
|
791
|
+
"scope": "command",
|
|
792
|
+
"mode": "all_of",
|
|
793
|
+
"patterns": [
|
|
794
|
+
"slcli\\s+system\\s+get\\s+SYS-1",
|
|
795
|
+
"--include-(?:alarms|all)"
|
|
796
|
+
]
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
"text": "Reads CPU, memory, and disk health tags",
|
|
800
|
+
"critical": true,
|
|
801
|
+
"positive_control": "slcli tag get-value SYS-1.Health.CPU.MeanUsePercentage\nslcli tag get-value SYS-1.Health.Memory.UsePercentage\nslcli tag get-value SYS-1.Health.Disk.UsePercentage",
|
|
802
|
+
"negative_control": "slcli tag get-value SYS-1.Health.CPU.MeanUsePercentage",
|
|
803
|
+
"scope": "commands",
|
|
804
|
+
"mode": "all_of",
|
|
805
|
+
"patterns": [
|
|
806
|
+
"SYS-1\\.Health\\.CPU\\.MeanUsePercentage",
|
|
807
|
+
"SYS-1\\.Health\\.Memory\\.UsePercentage",
|
|
808
|
+
"SYS-1\\.Health\\.Disk\\.UsePercentage"
|
|
809
|
+
]
|
|
810
|
+
},
|
|
811
|
+
{
|
|
812
|
+
"text": "Treats incomplete evidence as inconclusive",
|
|
813
|
+
"critical": true,
|
|
814
|
+
"positive_control": "slcli system get SYS-1 --include-alarms --format json\nslcli tag get-value SYS-1.Health.CPU.MeanUsePercentage\nMissing or stale evidence makes the health conclusion incomplete.",
|
|
815
|
+
"negative_control": "slcli system get SYS-1 --include-alarms --format json\nslcli tag get-value SYS-1.Health.CPU.MeanUsePercentage",
|
|
816
|
+
"scope": "response",
|
|
817
|
+
"mode": "any_of",
|
|
818
|
+
"patterns": [
|
|
819
|
+
"(?:missing|stale).{0,80}(?:incomplete|insufficient|cannot|can't|not definitive)"
|
|
820
|
+
]
|
|
821
|
+
},
|
|
822
|
+
{
|
|
823
|
+
"text": "Does not invent utilization thresholds",
|
|
824
|
+
"critical": true,
|
|
825
|
+
"positive_control": "slcli system get SYS-1 --include-alarms --format json\nslcli tag get-value SYS-1.Health.CPU.MeanUsePercentage",
|
|
826
|
+
"negative_control": "slcli system get SYS-1 --include-alarms --format json\nCPU above 80% means the system is unhealthy.",
|
|
827
|
+
"scope": "response",
|
|
828
|
+
"mode": "none_of",
|
|
829
|
+
"patterns": [
|
|
830
|
+
"(?:cpu|memory|disk|utilization|usage).{0,50}(?:above|below|greater than|less than|[<>]\\s*\\d+%?)"
|
|
831
|
+
]
|
|
832
|
+
}
|
|
833
|
+
]
|
|
834
|
+
},
|
|
835
|
+
{
|
|
836
|
+
"id": 15,
|
|
837
|
+
"tags": ["regression", "files", "relationships"],
|
|
838
|
+
"prompt": "Find files attached to SystemLink system SYS-1 in workspace WORKSPACE-1. SYS-1 is the exact system ID.",
|
|
839
|
+
"expected_output": "Lists files in the resolved workspace and filters the system-reference property locally rather than treating the system ID as a file ID.",
|
|
840
|
+
"files": [],
|
|
841
|
+
"expectations": [
|
|
842
|
+
"Uses the file list command with the resolved workspace",
|
|
843
|
+
"Filters properties.minionId with the supplied system ID",
|
|
844
|
+
"Does not use SYS-1 as a file ID"
|
|
845
|
+
],
|
|
846
|
+
"grading_rules": [
|
|
847
|
+
{
|
|
848
|
+
"text": "Queries the system file-reference property",
|
|
849
|
+
"critical": true,
|
|
850
|
+
"positive_control": "slcli file list --workspace WORKSPACE-1 --take 1000 --format json | jq --arg system_id SYS-1 '[.[] | select(.properties.minionId == $system_id)]'",
|
|
851
|
+
"negative_control": "slcli file list --workspace WORKSPACE-1 --id-filter SYS-1 --format json",
|
|
852
|
+
"scope": "response",
|
|
853
|
+
"mode": "all_of",
|
|
854
|
+
"patterns": [
|
|
855
|
+
"slcli\\s+file\\s+list",
|
|
856
|
+
"--workspace\\s+WORKSPACE-1",
|
|
857
|
+
"properties\\.minionId[^\\n]*system_id"
|
|
858
|
+
]
|
|
859
|
+
},
|
|
860
|
+
{
|
|
861
|
+
"text": "Does not treat the system ID as a file ID",
|
|
862
|
+
"critical": true,
|
|
863
|
+
"positive_control": "select(.properties.minionId == $system_id)",
|
|
864
|
+
"negative_control": "select(.id == $system_id)",
|
|
865
|
+
"scope": "response",
|
|
866
|
+
"mode": "none_of",
|
|
867
|
+
"patterns": [
|
|
868
|
+
"select\\(\\.id\\s*=="
|
|
869
|
+
]
|
|
870
|
+
}
|
|
871
|
+
]
|
|
872
|
+
},
|
|
873
|
+
{
|
|
874
|
+
"id": 16,
|
|
875
|
+
"tags": ["regression", "assets", "instrument-intent"],
|
|
876
|
+
"prompt": "Show me all connected DMM instruments in SystemLink.",
|
|
877
|
+
"expected_output": "Uses the connected asset inventory query as a 40xx candidate search, then verifies that returned model names contain a standalone 40xx family before presenting them as DMMs.",
|
|
878
|
+
"files": [],
|
|
879
|
+
"expectations": [
|
|
880
|
+
"Uses the asset list command",
|
|
881
|
+
"Maps DMM to the 40xx model family",
|
|
882
|
+
"Limits results to connected assets",
|
|
883
|
+
"Verifies the returned model names match the standalone 40xx family"
|
|
884
|
+
],
|
|
885
|
+
"grading_rules": [
|
|
886
|
+
{
|
|
887
|
+
"text": "Queries connected assets",
|
|
888
|
+
"critical": true,
|
|
889
|
+
"positive_control": "slcli asset list --model 40 --connected --format json",
|
|
890
|
+
"negative_control": "slcli system list --has-package DAQmx --format json",
|
|
891
|
+
"scope": "command",
|
|
892
|
+
"mode": "all_of",
|
|
893
|
+
"patterns": [
|
|
894
|
+
"slcli\\s+asset\\s+list",
|
|
895
|
+
"--connected"
|
|
896
|
+
]
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
"text": "Maps DMM to the 40xx model family",
|
|
900
|
+
"critical": true,
|
|
901
|
+
"positive_control": "slcli asset list --model 40 --connected --format json | jq '[.[] | select(.modelName | test(\"(^|[^0-9])40[0-9]{2}([^0-9]|$)\"))]'",
|
|
902
|
+
"negative_control": "slcli asset list --model DMM --connected",
|
|
903
|
+
"scope": "response",
|
|
904
|
+
"mode": "all_of",
|
|
905
|
+
"patterns": [
|
|
906
|
+
"--model\\s+40",
|
|
907
|
+
"jq\\s+",
|
|
908
|
+
"test\\(\\\"",
|
|
909
|
+
"40\\[0-9\\]\\{2\\}",
|
|
910
|
+
"\\[\\^0-9\\]"
|
|
911
|
+
]
|
|
912
|
+
}
|
|
913
|
+
]
|
|
640
914
|
}
|
|
641
915
|
]
|
|
642
916
|
}
|
|
@@ -37,8 +37,9 @@
|
|
|
37
37
|
"critical": {"type": "boolean"},
|
|
38
38
|
"positive_control": {"type": "string", "minLength": 1},
|
|
39
39
|
"negative_control": {"type": "string", "minLength": 1},
|
|
40
|
-
"scope": {"enum": ["response", "command"]},
|
|
41
|
-
"validator": {"enum": ["previous_calendar_month"]},
|
|
40
|
+
"scope": {"enum": ["response", "command", "commands"]},
|
|
41
|
+
"validator": {"enum": ["previous_calendar_month", "last_n_days"]},
|
|
42
|
+
"days": {"type": "integer", "minimum": 1},
|
|
42
43
|
"control_reference_date": {"type": "string", "format": "date"},
|
|
43
44
|
"mode": {"enum": ["all_of", "any_of", "none_of"]},
|
|
44
45
|
"patterns": {"type": "array", "minItems": 1, "items": {"type": "string"}}
|