systemlink-cli 1.27.1__tar.gz → 1.27.3__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.27.1 → systemlink_cli-1.27.3}/PKG-INFO +1 -1
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/pyproject.toml +1 -1
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/_version.py +1 -1
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/main.py +12 -2
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/platform.py +21 -5
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skill_click.py +107 -4
- systemlink_cli-1.27.3/slcli/skills/slcli/SKILL.md +221 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/analysis-recipes.md +87 -2
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/commands.md +76 -7
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/troubleshooting.md +41 -0
- systemlink_cli-1.27.3/slcli/skills/slcli/references/webapp/deployment.md +332 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/webapp/overview.md +5 -1
- systemlink_cli-1.27.3/slcli/version_click.py +199 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_click.py +9 -2
- systemlink_cli-1.27.1/slcli/skills/slcli/SKILL.md +0 -91
- systemlink_cli-1.27.1/slcli/skills/slcli/references/webapp/deployment.md +0 -147
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/LICENSE +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/dff-editor/editor.js +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/dff-editor/index.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/__init__.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/__main__.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/alarm_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/asset_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/cli_formatters.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/cli_utils.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/comment_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/completion_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/config.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/config_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/dataframe_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/dff_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/dff_decorators.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/example_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/example_loader.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/example_provisioner.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/README.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/_schema/schema-v1.0.json +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/demo-data-1/README.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/demo-data-1/config.yaml +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/demo-data-2/README.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/demo-data-2/config.yaml +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/demo-data-3/config.yaml +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/demo-data-3/leakage-current-results.json +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/demo-data-3/overvoltage-results.json +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/demo-data-3/product-xyz-compliance-report.json +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/demo-data-3/product-xyz-specification.csv +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/demo-data-3/thermal-response-results.json +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/exercise-5-1-parametric-insights/README.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/exercise-5-1-parametric-insights/config.yaml +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/exercise-7-1-test-plans/README.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/exercise-7-1-test-plans/config.yaml +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/spec-compliance-notebooks/README.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/spec-compliance-notebooks/config.yaml +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/spec-compliance-notebooks/notebooks/SpecAnalysis_ComplianceCalculation.ipynb +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/spec-compliance-notebooks/notebooks/SpecComplianceCalculation.ipynb +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/spec-compliance-notebooks/notebooks/SpecfileExtractionAndIngestion.ipynb +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/examples/spec-compliance-notebooks/spec_template.xlsx +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/feed_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/file_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/function_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/function_templates.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/mcp_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/mcp_reachability.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/mcp_server.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/notebook_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/pkce.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/policy_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/policy_utils.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/profiles.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/response_handlers.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/rich_output.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/routine_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/datasheet-workflow.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/example-authoring.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/filtering.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/import-specs.min.json +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/job-debugging/overview.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/nipkg/overview.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/notebook/interfaces.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/notebook/notebook-patterns.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/notebook/overview.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/python-test/overview.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/routine-examples.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/webapp/angular-ui-packages.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/webapp/layout-patterns.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/webapp/nimble-angular.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/webapp/systemlink-services.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/webapp/troubleshooting.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/scripts/spec_import_helper.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/spec_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/ssl_trust.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/state_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/system_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/system_query_utils.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/systemlink-logo.svg +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/table_utils.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/tag_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/templates_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/testmonitor_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/universal_handlers.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/user_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/utils.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/web_editor.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_bootstrap.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/.gitignore +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/README.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/angular.json +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/package.json +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/scripts/filter-sbom.js +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/app-routing.module.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/app.component.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/app.component.scss +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/app.component.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/app.module.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/core/layout/app-shell.component.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/core/layout/app-shell.component.scss +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/core/layout/app-shell.component.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/core/state/app-view-state.service.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/core/systemlink/systemlink-context.service.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/core/systemlink/theme-sync.service.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/core/systemlink/webapp-home-data.service.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.scss +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.scss +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/home/home-page.component.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/home/home-page.component.scss +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/home/home-page.component.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/master-detail/master-detail-page.component.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/master-detail/master-detail-page.component.scss +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/master-detail/master-detail-page.component.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/operations/operations-page.component.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/operations/operations-page.component.scss +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/operations/operations-page.component.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.scss +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/shared/components/empty-state.component.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/shared/components/empty-state.component.scss +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/shared/components/empty-state.component.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/shared/components/error-banner.component.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/shared/components/error-banner.component.scss +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/shared/components/error-banner.component.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/shared/components/loading-state.component.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/shared/components/loading-state.component.scss +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/shared/components/loading-state.component.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/app/shared/states/view-state.model.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/assets/README.md +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/index.html +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/main.ts +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/src/styles.scss +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/tsconfig.app.json +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/webapp_templates/angular/blank/tsconfig.json +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/workflow_preview.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/workflows_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/workitem_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/workspace_click.py +0 -0
- {systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/workspace_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "systemlink-cli"
|
|
3
|
-
version = "1.27.
|
|
3
|
+
version = "1.27.3"
|
|
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" }]
|
|
@@ -43,6 +43,7 @@ from .templates_click import register_templates_commands
|
|
|
43
43
|
from .testmonitor_click import register_testmonitor_commands
|
|
44
44
|
from .user_click import register_user_commands
|
|
45
45
|
from .utils import describe_config_source
|
|
46
|
+
from .version_click import register_version_commands
|
|
46
47
|
from .webapp_click import register_webapp_commands
|
|
47
48
|
from .workitem_click import register_workitem_commands
|
|
48
49
|
from .workspace_click import register_workspace_commands
|
|
@@ -71,7 +72,15 @@ def _configure_rich_click_command_groups() -> None:
|
|
|
71
72
|
"slcli": [
|
|
72
73
|
{
|
|
73
74
|
"name": "Configure",
|
|
74
|
-
"commands": [
|
|
75
|
+
"commands": [
|
|
76
|
+
"config",
|
|
77
|
+
"login",
|
|
78
|
+
"logout",
|
|
79
|
+
"info",
|
|
80
|
+
"version",
|
|
81
|
+
"completion",
|
|
82
|
+
"example",
|
|
83
|
+
],
|
|
75
84
|
},
|
|
76
85
|
{
|
|
77
86
|
"name": "Administer",
|
|
@@ -363,7 +372,7 @@ def cli(ctx: base_click.Context, version: bool, profile: Optional[str]) -> None:
|
|
|
363
372
|
|
|
364
373
|
# Check for mandatory migration BEFORE any command runs
|
|
365
374
|
# Skip migration check only for version flag and config migrate command
|
|
366
|
-
if ctx.invoked_subcommand not in (None, "config"):
|
|
375
|
+
if ctx.invoked_subcommand not in (None, "config", "version"):
|
|
367
376
|
from .profiles import ProfileConfig, has_keyring_credentials, migrate_from_keyring
|
|
368
377
|
|
|
369
378
|
config_path = ProfileConfig.get_config_path()
|
|
@@ -769,5 +778,6 @@ register_testmonitor_commands(cli)
|
|
|
769
778
|
register_webapp_commands(cli)
|
|
770
779
|
register_skill_commands(cli)
|
|
771
780
|
register_user_commands(cli)
|
|
781
|
+
register_version_commands(cli)
|
|
772
782
|
register_workitem_commands(cli)
|
|
773
783
|
register_workspace_commands(cli)
|
|
@@ -168,8 +168,9 @@ def get_platform() -> str:
|
|
|
168
168
|
|
|
169
169
|
Detection priority:
|
|
170
170
|
1. SYSTEMLINK_PLATFORM environment variable (explicit, most reliable)
|
|
171
|
-
2.
|
|
172
|
-
3.
|
|
171
|
+
2. Platform stored on the active profile (set during login via endpoint probing)
|
|
172
|
+
3. Stored platform from keyring config (legacy fallback)
|
|
173
|
+
4. Return PLATFORM_UNKNOWN if no explicit or stored platform is available
|
|
173
174
|
|
|
174
175
|
Note: Results are cached for performance. Use clear_platform_cache() to reset.
|
|
175
176
|
|
|
@@ -182,11 +183,26 @@ def get_platform() -> str:
|
|
|
182
183
|
if env_platform in (PLATFORM_SLE, PLATFORM_SLS):
|
|
183
184
|
return env_platform
|
|
184
185
|
|
|
185
|
-
|
|
186
|
-
|
|
186
|
+
if not any(os.environ.get(name) for name in ("SLCLI_API_URL", "SYSTEMLINK_API_URL")):
|
|
187
|
+
try:
|
|
188
|
+
from .profiles import get_active_profile
|
|
189
|
+
|
|
190
|
+
profile = get_active_profile()
|
|
191
|
+
profile_platform = str(profile.platform or "").upper() if profile else ""
|
|
192
|
+
if profile_platform in (PLATFORM_SLE, PLATFORM_SLS):
|
|
193
|
+
return profile_platform
|
|
194
|
+
except (
|
|
195
|
+
FileNotFoundError,
|
|
196
|
+
json.JSONDecodeError,
|
|
197
|
+
KeyError,
|
|
198
|
+
AttributeError,
|
|
199
|
+
click.ClickException,
|
|
200
|
+
):
|
|
201
|
+
pass
|
|
202
|
+
|
|
187
203
|
cfg = _get_keyring_config()
|
|
188
204
|
if cfg:
|
|
189
|
-
platform = cfg.get("platform", "")
|
|
205
|
+
platform = str(cfg.get("platform", "")).upper()
|
|
190
206
|
if platform in (PLATFORM_SLE, PLATFORM_SLS):
|
|
191
207
|
return platform
|
|
192
208
|
|
|
@@ -6,11 +6,14 @@ from pathlib import Path
|
|
|
6
6
|
from typing import Any, Dict, List, Optional, Tuple
|
|
7
7
|
|
|
8
8
|
import click
|
|
9
|
+
from packaging.version import InvalidVersion, Version
|
|
9
10
|
|
|
11
|
+
from ._version import __version__
|
|
10
12
|
from .utils import ExitCodes, format_success
|
|
11
13
|
|
|
12
14
|
SKILL_NAME = "slcli"
|
|
13
15
|
_FALLBACK_SKILL_CHOICES = [SKILL_NAME]
|
|
16
|
+
_VERSION_FILENAME = ".slcli-version"
|
|
14
17
|
|
|
15
18
|
# Mapping of client name -> (personal skills dir, project subdir relative to repo root)
|
|
16
19
|
# personal dir uses Path.home() so it's always resolved at call time via _personal_dir().
|
|
@@ -119,6 +122,23 @@ def _expand_skill_selection(skill_names: Optional[List[str]] = None) -> List[str
|
|
|
119
122
|
return requested
|
|
120
123
|
|
|
121
124
|
|
|
125
|
+
def _skill_installation_status(destination_root: Path, skill_name: str) -> str:
|
|
126
|
+
"""Return the version status of an installed skill."""
|
|
127
|
+
destination_dir = destination_root / skill_name
|
|
128
|
+
if not destination_dir.exists():
|
|
129
|
+
return "missing"
|
|
130
|
+
|
|
131
|
+
version_file = destination_dir / _VERSION_FILENAME
|
|
132
|
+
if not version_file.exists():
|
|
133
|
+
return "unversioned"
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
installed_version = version_file.read_text(encoding="utf-8").strip()
|
|
137
|
+
return "current" if Version(installed_version) >= Version(__version__) else "outdated"
|
|
138
|
+
except (InvalidVersion, OSError):
|
|
139
|
+
return "unversioned"
|
|
140
|
+
|
|
141
|
+
|
|
122
142
|
def install_skills_to_directory(
|
|
123
143
|
directory: Path,
|
|
124
144
|
skill_names: Optional[List[str]] = None,
|
|
@@ -150,6 +170,7 @@ def install_skills_to_directory(
|
|
|
150
170
|
destination_dir.unlink()
|
|
151
171
|
|
|
152
172
|
shutil.copytree(source_dir, destination_dir)
|
|
173
|
+
(destination_dir / _VERSION_FILENAME).write_text(f"{__version__}\n", encoding="utf-8")
|
|
153
174
|
|
|
154
175
|
return len(selected_skills)
|
|
155
176
|
|
|
@@ -184,6 +205,19 @@ def _resolve_destinations(clients: List[str], scope: str) -> List[Path]:
|
|
|
184
205
|
return seen
|
|
185
206
|
|
|
186
207
|
|
|
208
|
+
def _requested_destinations(
|
|
209
|
+
directory: Optional[Path], client: Optional[str], scope: Optional[str]
|
|
210
|
+
) -> List[Path]:
|
|
211
|
+
"""Resolve either a custom skills directory or client-specific destinations."""
|
|
212
|
+
if directory is not None:
|
|
213
|
+
if client is not None or scope is not None:
|
|
214
|
+
raise ValueError("--directory cannot be combined with --client or --scope")
|
|
215
|
+
return [directory.expanduser()]
|
|
216
|
+
|
|
217
|
+
selected_clients = CLIENT_CHOICES if client == "all" else [client or "agents"]
|
|
218
|
+
return _resolve_destinations(selected_clients, scope or "project")
|
|
219
|
+
|
|
220
|
+
|
|
187
221
|
def register_skill_commands(cli: Any) -> None:
|
|
188
222
|
"""Register the skill command group with the CLI.
|
|
189
223
|
|
|
@@ -217,6 +251,13 @@ def register_skill_commands(cli: Any) -> None:
|
|
|
217
251
|
default=None,
|
|
218
252
|
help="personal (~/ home dirs), project (current repo), or both.",
|
|
219
253
|
)
|
|
254
|
+
@click.option(
|
|
255
|
+
"--directory",
|
|
256
|
+
"-d",
|
|
257
|
+
type=click.Path(file_okay=False, path_type=Path),
|
|
258
|
+
default=None,
|
|
259
|
+
help="Install directly into this skills directory.",
|
|
260
|
+
)
|
|
220
261
|
@click.option(
|
|
221
262
|
"--force",
|
|
222
263
|
"-F",
|
|
@@ -225,7 +266,11 @@ def register_skill_commands(cli: Any) -> None:
|
|
|
225
266
|
help="Overwrite existing skill installation without prompting.",
|
|
226
267
|
)
|
|
227
268
|
def install_skill(
|
|
228
|
-
skill: Optional[str],
|
|
269
|
+
skill: Optional[str],
|
|
270
|
+
client: Optional[str],
|
|
271
|
+
scope: Optional[str],
|
|
272
|
+
directory: Optional[Path],
|
|
273
|
+
force: bool,
|
|
229
274
|
) -> None:
|
|
230
275
|
"""Install bundled skills for supported AI clients."""
|
|
231
276
|
requested_skills: Optional[List[str]]
|
|
@@ -235,11 +280,9 @@ def register_skill_commands(cli: Any) -> None:
|
|
|
235
280
|
assert skill is not None
|
|
236
281
|
requested_skills = [skill.lower()]
|
|
237
282
|
selected_skill_names = _expand_skill_selection(requested_skills)
|
|
238
|
-
selected_clients = CLIENT_CHOICES if client == "all" else [client or "agents"]
|
|
239
|
-
selected_scope = scope or "project"
|
|
240
|
-
destinations = _resolve_destinations(selected_clients, selected_scope)
|
|
241
283
|
|
|
242
284
|
try:
|
|
285
|
+
destinations = _requested_destinations(directory, client, scope)
|
|
243
286
|
installed_count = 0
|
|
244
287
|
for destination in destinations:
|
|
245
288
|
installed_count += install_skills_to_directory(
|
|
@@ -257,6 +300,9 @@ def register_skill_commands(cli: Any) -> None:
|
|
|
257
300
|
except FileNotFoundError as exc:
|
|
258
301
|
click.echo(f"✗ {exc}", err=True)
|
|
259
302
|
sys.exit(ExitCodes.GENERAL_ERROR)
|
|
303
|
+
except OSError as exc:
|
|
304
|
+
click.echo(f"✗ Unable to install skills: {exc}", err=True)
|
|
305
|
+
sys.exit(ExitCodes.GENERAL_ERROR)
|
|
260
306
|
|
|
261
307
|
format_success(
|
|
262
308
|
"Installed bundled AI skills",
|
|
@@ -266,3 +312,60 @@ def register_skill_commands(cli: Any) -> None:
|
|
|
266
312
|
"Installed": str(installed_count),
|
|
267
313
|
},
|
|
268
314
|
)
|
|
315
|
+
|
|
316
|
+
@skill.command(name="check")
|
|
317
|
+
@click.option(
|
|
318
|
+
"--skill",
|
|
319
|
+
"-k",
|
|
320
|
+
type=click.Choice(SKILL_CHOICES + ["all"], case_sensitive=False),
|
|
321
|
+
default=None,
|
|
322
|
+
help=f"Skill to check ({', '.join(SKILL_CHOICES)}, or all).",
|
|
323
|
+
)
|
|
324
|
+
@click.option(
|
|
325
|
+
"--client",
|
|
326
|
+
"-c",
|
|
327
|
+
type=click.Choice(CLIENT_CHOICES + ["all"], case_sensitive=False),
|
|
328
|
+
default=None,
|
|
329
|
+
help="AI client installation to check (agents, claude, or all).",
|
|
330
|
+
)
|
|
331
|
+
@click.option(
|
|
332
|
+
"--scope",
|
|
333
|
+
"-s",
|
|
334
|
+
type=click.Choice(["personal", "project", "both"], case_sensitive=False),
|
|
335
|
+
default=None,
|
|
336
|
+
help="personal (~/ home dirs), project (current repo), or both.",
|
|
337
|
+
)
|
|
338
|
+
@click.option(
|
|
339
|
+
"--directory",
|
|
340
|
+
"-d",
|
|
341
|
+
type=click.Path(file_okay=False, path_type=Path),
|
|
342
|
+
default=None,
|
|
343
|
+
help="Check skills directly in this directory.",
|
|
344
|
+
)
|
|
345
|
+
def check_skills(
|
|
346
|
+
skill: Optional[str],
|
|
347
|
+
client: Optional[str],
|
|
348
|
+
scope: Optional[str],
|
|
349
|
+
directory: Optional[Path],
|
|
350
|
+
) -> None:
|
|
351
|
+
"""Check whether installed skills match the bundled version."""
|
|
352
|
+
requested_skills = None if skill in (None, "all") else [skill.lower()]
|
|
353
|
+
|
|
354
|
+
try:
|
|
355
|
+
selected_skill_names = _expand_skill_selection(requested_skills)
|
|
356
|
+
destinations = _requested_destinations(directory, client, scope)
|
|
357
|
+
except ValueError as exc:
|
|
358
|
+
click.echo(f"✗ {exc}", err=True)
|
|
359
|
+
sys.exit(ExitCodes.INVALID_INPUT)
|
|
360
|
+
|
|
361
|
+
needs_update = False
|
|
362
|
+
click.echo(f"Bundled skill version: {__version__}")
|
|
363
|
+
for destination in destinations:
|
|
364
|
+
for skill_name in selected_skill_names:
|
|
365
|
+
status = _skill_installation_status(destination, skill_name)
|
|
366
|
+
indicator = "✓" if status == "current" else "✗"
|
|
367
|
+
click.echo(f"{indicator} {destination / skill_name}: {status}")
|
|
368
|
+
needs_update = needs_update or status != "current"
|
|
369
|
+
|
|
370
|
+
if needs_update:
|
|
371
|
+
sys.exit(ExitCodes.GENERAL_ERROR)
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: slcli
|
|
3
|
+
description: >-
|
|
4
|
+
Query and manage NI SystemLink resources using the slcli command-line interface.
|
|
5
|
+
Use when the user asks about test results, assets, systems, work items,
|
|
6
|
+
specifications, webapps, notebooks, dataframes, files, feeds, tags,
|
|
7
|
+
authorization, users, example fixture authoring, example config.yaml files,
|
|
8
|
+
or other SystemLink resource workflows. Use it when the user asks to create,
|
|
9
|
+
validate, review, install, or troubleshoot a SystemLink example fixture.
|
|
10
|
+
argument-hint: >-
|
|
11
|
+
Describe the SystemLink workflow you want to inspect, automate, scaffold, or
|
|
12
|
+
troubleshoot.
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# SystemLink CLI
|
|
16
|
+
|
|
17
|
+
Use this skill when the task is primarily about `slcli` commands or a
|
|
18
|
+
SystemLink resource workflow that should be driven from the CLI.
|
|
19
|
+
|
|
20
|
+
## When to use it
|
|
21
|
+
|
|
22
|
+
- Querying or managing SystemLink resources through `slcli`
|
|
23
|
+
- Looking up exact command syntax, flags, or JSON output patterns
|
|
24
|
+
- Building command sequences for analysis, provisioning, packaging, or cleanup
|
|
25
|
+
- Creating, validating, or reviewing `slcli example` fixture YAML
|
|
26
|
+
- Troubleshooting CLI behavior, platform gating, or command selection
|
|
27
|
+
|
|
28
|
+
## Reference docs
|
|
29
|
+
|
|
30
|
+
Load only what the current task needs.
|
|
31
|
+
|
|
32
|
+
| Topic | File | When to load |
|
|
33
|
+
| --- | --- | --- |
|
|
34
|
+
| CLI command reference | [commands.md](./references/commands.md) | Looking up command syntax, options, or examples |
|
|
35
|
+
| Example fixture authoring | [example-authoring.md](./references/example-authoring.md) | Creating or reviewing `config.yaml`, resource references, file-backed fixtures, or validation behavior |
|
|
36
|
+
| Datasheet-to-spec workflow | [datasheet-workflow.md](./references/datasheet-workflow.md) | Importing specifications from PDF, CSV, or structured text |
|
|
37
|
+
| Minimal spec import payload | [import-specs.min.json](./references/import-specs.min.json) | Need a bundled create-compatible starter payload or conditions |
|
|
38
|
+
| Spec import helper | [spec_import_helper.py](./scripts/spec_import_helper.py) | Scaffold or validate a datasheet spec import payload |
|
|
39
|
+
| Filtering guide | [filtering.md](./references/filtering.md) | Advanced filters, LINQ syntax, and query composition |
|
|
40
|
+
| Analysis recipes | [analysis-recipes.md](./references/analysis-recipes.md) | Multi-step analysis workflows and reporting patterns |
|
|
41
|
+
| Troubleshooting | [troubleshooting.md](./references/troubleshooting.md) | SSL, workspace IDs, encoding, or scripting pitfalls |
|
|
42
|
+
| Notebook workflow | [notebook/overview.md](./references/notebook/overview.md) | Creating notebooks for SystemLink |
|
|
43
|
+
| Webapp workflow | [webapp/overview.md](./references/webapp/overview.md) | Hosted Angular webapp scaffolding and deployment |
|
|
44
|
+
| Python test workflow | [python-test/overview.md](./references/python-test/overview.md) | Python test app structure and deployment |
|
|
45
|
+
| Job debugging | [job-debugging/overview.md](./references/job-debugging/overview.md) | Salt job triage and recovery |
|
|
46
|
+
| NI package files | [nipkg/overview.md](./references/nipkg/overview.md) | File-package assembly and `nipkg pack` guidance |
|
|
47
|
+
|
|
48
|
+
## Default approach
|
|
49
|
+
|
|
50
|
+
1. At the start of troubleshooting or a substantial `slcli` workflow, run the
|
|
51
|
+
update preflight once per session:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
slcli version check
|
|
55
|
+
slcli skill check --client CLIENT --scope SCOPE
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Set `CLIENT` and `SCOPE` to the active skill installation, or use
|
|
59
|
+
`--directory PATH` for a custom skills directory. If the CLI is outdated,
|
|
60
|
+
recommend the update command printed by `version check`. If the skill is
|
|
61
|
+
missing, unversioned, or outdated, recommend `slcli skill install` with the
|
|
62
|
+
same target and `--force`. Ask before running either update because they
|
|
63
|
+
modify the user's environment. A failed or unavailable check is advisory:
|
|
64
|
+
report it briefly and continue the requested workflow unless version skew
|
|
65
|
+
is the likely cause.
|
|
66
|
+
2. Prefer long-form flags in generated commands.
|
|
67
|
+
3. Use `--format json` when the result will be filtered, transformed, or piped
|
|
68
|
+
into other tools.
|
|
69
|
+
4. Use `--summary --group-by` for aggregation before fetching large raw result sets.
|
|
70
|
+
5. Use convenience filters first, then fall back to `--filter` with `--substitution` for complex queries.
|
|
71
|
+
6. Stay scoped to the user’s requested resource or workflow.
|
|
72
|
+
7. Load deeper references only when the command surface alone is not enough.
|
|
73
|
+
8. For example authoring or review, load `example-authoring.md` before proposing YAML.
|
|
74
|
+
9. Prefer workspace IDs over names in scripted workflows when an endpoint is strict about identity.
|
|
75
|
+
10. Use `make_api_request` from `slcli.utils` for helper scripts so auth, SSL, and error handling stay consistent.
|
|
76
|
+
11. For datasheet imports, default to autonomy when the product or workspace can be resolved unambiguously.
|
|
77
|
+
|
|
78
|
+
## Common command groups
|
|
79
|
+
|
|
80
|
+
| Group | Purpose | Key subcommands |
|
|
81
|
+
| --- | --- | --- |
|
|
82
|
+
| `testmonitor` | Test results and products | `result list/get`, `product list/create/update` |
|
|
83
|
+
| `alarm` | Alarm monitoring and lifecycle actions | `list`, `get`, `acknowledge`, `force-clear`, `delete`, `transition`, `monitor` |
|
|
84
|
+
| `spec` | Specifications | `list`, `query`, `get`, `create`, `import`, `export` |
|
|
85
|
+
| `asset` | Assets and calibration | `list`, `get`, `summary`, `calibration` |
|
|
86
|
+
| `system` | System fleet | `list`, `get`, `compare`, `summary`, `job` |
|
|
87
|
+
| `tag` | Tag read/write | `list`, `get-value`, `set-value`, `create` |
|
|
88
|
+
| `routine` | Event-action routines | `list`, `create`, `enable/disable` |
|
|
89
|
+
| `comment` | Resource comments | `list`, `add`, `update`, `delete` |
|
|
90
|
+
| `workitem` | Work items and workflows | `list`, `create`, `schedule`, `template`, `workflow` |
|
|
91
|
+
| `file` | File management | `list`, `upload`, `download`, `query`, `watch` |
|
|
92
|
+
| `notebook` | Jupyter notebooks | `manage list/create`, `execute start/sync` |
|
|
93
|
+
| `feed` | Package feeds | `list`, `create`, `package upload` |
|
|
94
|
+
| `customfield` | Dynamic form fields | `list`, `create`, `export`, `edit` |
|
|
95
|
+
| `template` | Test plan templates | `list`, `import`, `export` |
|
|
96
|
+
| `webapp` | Web applications | `new`, `pack`, `publish`, `list` |
|
|
97
|
+
| `config` | Connection profiles | `list`, `use`, `add`, `delete` |
|
|
98
|
+
| `user` | User management | `list`, `get`, `create`, `update` |
|
|
99
|
+
| `auth` | Authorization policies | `policy list/create`, `template list` |
|
|
100
|
+
| `workspace` | Workspaces | `list`, `get` |
|
|
101
|
+
| `version` | CLI update hygiene | `check` |
|
|
102
|
+
| `skill` | AI skill installation | `install`, `check` |
|
|
103
|
+
| `example` | Demo provisioning | `list`, `install`, `delete` |
|
|
104
|
+
|
|
105
|
+
Example package fixtures are declared as `package` resources after a `feed`
|
|
106
|
+
resource. Use `source.type: dummy` for deterministic packages, `file` for a
|
|
107
|
+
fixture-relative `.nipkg`, or `repository` for an explicit HTTPS package URL.
|
|
108
|
+
The repository catalog can identify packages and feeds, but package bytes must
|
|
109
|
+
come from a direct package URL or an existing feed download path.
|
|
110
|
+
|
|
111
|
+
## Mandatory scope resolution
|
|
112
|
+
|
|
113
|
+
Before the first resource query, resolve the profile and workspace separately.
|
|
114
|
+
Treat a workspace supplied by the user as a workspace identifier, never as a
|
|
115
|
+
profile name. Match it exactly against either the workspace name or UUID.
|
|
116
|
+
|
|
117
|
+
1. Run `slcli config list --format json` and select profiles whose `workspace`
|
|
118
|
+
field matches the requested workspace name. If the user supplied a UUID,
|
|
119
|
+
probe configured profiles sequentially instead. Do not infer a profile from
|
|
120
|
+
a similar name such as `demo-fred` or `fred-roaster`.
|
|
121
|
+
2. Use the global `--profile NAME` override on every command. The option goes
|
|
122
|
+
before the command group, for example:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
slcli --profile PROFILE_NAME workspace list --format json
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
This preserves the user's global active profile.
|
|
129
|
+
3. If several profiles match, probe them sequentially with
|
|
130
|
+
`slcli --profile NAME info --skip-health --format json`. Continue past a
|
|
131
|
+
missing credential, unavailable endpoint, or permission error. Confirm the
|
|
132
|
+
selected candidate with one read-only workspace query before issuing the
|
|
133
|
+
actual resource query. Do not fan out the same query across candidates.
|
|
134
|
+
4. Use the first authorized candidate. Ask the user only when several
|
|
135
|
+
candidates are authorized and the choice could change the answer.
|
|
136
|
+
5. With the selected profile, run `workspace list --format json` and resolve
|
|
137
|
+
the requested workspace by exact name or UUID. Carry both the display name
|
|
138
|
+
and UUID, but use the UUID for subsequent queries when the command accepts
|
|
139
|
+
it.
|
|
140
|
+
|
|
141
|
+
When reading `slcli info --format json`, use `active_profile_name` as the
|
|
142
|
+
effective profile after CLI or environment overrides. `current_profile` is the
|
|
143
|
+
persisted config pointer and may differ. Use `api_url_source` to confirm where
|
|
144
|
+
the effective endpoint came from; never use `current_profile` alone to decide
|
|
145
|
+
which profile served a query.
|
|
146
|
+
|
|
147
|
+
## Mandatory non-interactive webapp deployment protocol
|
|
148
|
+
|
|
149
|
+
For every webapp creation, publish, redeploy, or update task, load
|
|
150
|
+
[deployment.md](./references/webapp/deployment.md) and follow its ordered
|
|
151
|
+
protocol. Do not build or upload an artifact until the deployment target has
|
|
152
|
+
been resolved. The protocol is non-interactive: use JSON output and bounded
|
|
153
|
+
inventory commands, and do not rely on table pagination or terminal prompts.
|
|
154
|
+
|
|
155
|
+
1. Discover the installed command surface before composing commands:
|
|
156
|
+
```bash
|
|
157
|
+
slcli config list --format json
|
|
158
|
+
slcli webapp publish -h
|
|
159
|
+
slcli webapp list -h
|
|
160
|
+
```
|
|
161
|
+
Installed `--help` wins over this skill and its references. Confirm every
|
|
162
|
+
option on the installed CLI; `webapp publish` currently has `--id`, `--name`,
|
|
163
|
+
and `--workspace`, while `webapp list` has bounded JSON output and `-f`.
|
|
164
|
+
Prefer long options in generated commands after confirming they exist.
|
|
165
|
+
2. Resolve the effective profile and target workspace separately. Probe a
|
|
166
|
+
candidate with `info --skip-health --format json`, resolve the workspace
|
|
167
|
+
display name to its UUID with `workspace list --format json`, and carry the
|
|
168
|
+
UUID into every later command. Never use a similar profile name as a
|
|
169
|
+
substitute for workspace identity.
|
|
170
|
+
3. Resolve the exact webapp target before building or uploading. Use a
|
|
171
|
+
bounded, filtered, non-interactive inventory, for example:
|
|
172
|
+
```bash
|
|
173
|
+
slcli --profile PROFILE webapp list \
|
|
174
|
+
--workspace WORKSPACE_ID --filter "Coffee Tasting" \
|
|
175
|
+
--take 10 --format json
|
|
176
|
+
```
|
|
177
|
+
The server-side `--filter` is a substring filter, so compare returned names
|
|
178
|
+
locally. One exact name match means update that webapp with its returned ID
|
|
179
|
+
by default. Multiple exact matches are ambiguous and require a selected ID.
|
|
180
|
+
No exact match means report that a new resource would be created and obtain
|
|
181
|
+
explicit confirmation or an explicit create instruction before using
|
|
182
|
+
`--name`; never create a duplicate as an implicit fallback.
|
|
183
|
+
4. Inspect the project contract before running its dev server or production
|
|
184
|
+
build. Read `package.json` and `angular.json`; do not append `--host` when
|
|
185
|
+
the package script already supplies it. Remove or correct legacy Angular
|
|
186
|
+
options such as `buildOptimizer` and `vendorChunk` when they make `ng serve`
|
|
187
|
+
reject the configuration. Run the production build, detect its actual
|
|
188
|
+
output directory, and verify the hosted routing, CSP, authentication, and
|
|
189
|
+
service/workspace contract. The Test Monitor results service prefix is
|
|
190
|
+
`/nitest/v2/query-results`, not `/nitestmonitor/v2/query-results`; do not
|
|
191
|
+
hardcode `workspace=Default` when the target workspace was resolved.
|
|
192
|
+
5. Publish only after steps 1-4 pass. Pass the resolved workspace for a new
|
|
193
|
+
webapp, or the exact existing webapp ID for an update. Capture the returned
|
|
194
|
+
webapp ID, published URL, and publish timestamp in the task record.
|
|
195
|
+
6. Validate at three levels: deployment metadata with `webapp get`, an
|
|
196
|
+
authenticated CLI query for the target workspace and required resources,
|
|
197
|
+
and an authenticated browser check of the hosted URL. A reachable URL is
|
|
198
|
+
not proof of an authenticated app. If the browser redirects to login or
|
|
199
|
+
returns 401, report exactly: `deployment reachable, interactive hosted
|
|
200
|
+
validation pending.`
|
|
201
|
+
|
|
202
|
+
## Product lookup and overview defaults
|
|
203
|
+
|
|
204
|
+
For product discovery, use this order:
|
|
205
|
+
|
|
206
|
+
1. Try an exact or likely part number with `testmonitor product list
|
|
207
|
+
--part-number`.
|
|
208
|
+
2. Try the name and family convenience filters.
|
|
209
|
+
3. If a convenience filter returns `[]`, treat that as inconclusive. Scan the
|
|
210
|
+
resolved workspace catalog with a bounded JSON query and match name or part
|
|
211
|
+
number locally with `jq`.
|
|
212
|
+
4. Fetch the selected product with `testmonitor product get <PRODUCT_ID>`.
|
|
213
|
+
|
|
214
|
+
For a product overview, fetch the product record and directly linked metadata
|
|
215
|
+
only. Use `--summary` for counts and statuses, and grouped summaries for
|
|
216
|
+
profiles, programs, or other supported dimensions. For result data, use only
|
|
217
|
+
dimensions exposed by the command, such as `status` and `programName`. Fetch
|
|
218
|
+
only the latest 5 to 10 results, projecting relevant fields with `jq`. Fetch
|
|
219
|
+
full result details only for a specific run or failure. Record an explicit UTC
|
|
220
|
+
`as of` time and treat counts from separate live queries as separate
|
|
221
|
+
observations.
|
{systemlink_cli-1.27.1 → systemlink_cli-1.27.3}/slcli/skills/slcli/references/analysis-recipes.md
RENAMED
|
@@ -17,10 +17,94 @@ Each recipe maps to a real-world scenario and shows the exact commands needed.
|
|
|
17
17
|
- [Recipe 9: Product family workload distribution](#recipe-9-product-family-workload-distribution)
|
|
18
18
|
- [Recipe 10: Environmental condition failure patterns](#recipe-10-environmental-condition-failure-patterns)
|
|
19
19
|
- [Recipe 11: Create and schedule a work item on a specific fixture/slot and system](#recipe-11-create-and-schedule-a-work-item-on-a-specific-fixtureslot-and-system)
|
|
20
|
+
- [Product discovery and overview](#product-discovery-and-overview)
|
|
20
21
|
- [General tips](#general-tips)
|
|
21
22
|
|
|
22
23
|
---
|
|
23
24
|
|
|
25
|
+
## Product discovery and overview
|
|
26
|
+
|
|
27
|
+
**Question:** Tell me about a product in a specific workspace without
|
|
28
|
+
producing an oversized, inconsistent report.
|
|
29
|
+
|
|
30
|
+
**Prerequisite:** Complete the mandatory profile and workspace resolution in
|
|
31
|
+
the main `slcli` skill. Set `PROFILE` to the selected profile and
|
|
32
|
+
`WORKSPACE_ID` to the resolved workspace UUID. Capture the observation time
|
|
33
|
+
before querying live data:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
PROFILE="<PROFILE_NAME>"
|
|
37
|
+
WORKSPACE_ID="<WORKSPACE_UUID>"
|
|
38
|
+
AS_OF="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
39
|
+
printf 'As of %s\n' "$AS_OF"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Lookup order:**
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# 1. Exact or likely part number
|
|
46
|
+
slcli --profile "$PROFILE" testmonitor product list \
|
|
47
|
+
--workspace "$WORKSPACE_ID" --part-number "<PART_NUMBER>" \
|
|
48
|
+
--format json --take 25
|
|
49
|
+
|
|
50
|
+
# 2. Name or family convenience filters, when the part-number lookup is empty
|
|
51
|
+
slcli --profile "$PROFILE" testmonitor product list \
|
|
52
|
+
--workspace "$WORKSPACE_ID" --name "<PRODUCT_NAME>" \
|
|
53
|
+
--format json --take 25
|
|
54
|
+
slcli --profile "$PROFILE" testmonitor product list \
|
|
55
|
+
--workspace "$WORKSPACE_ID" --family "<FAMILY>" \
|
|
56
|
+
--format json --take 25
|
|
57
|
+
|
|
58
|
+
# 3. Bounded workspace catalog fallback when convenience filters are empty
|
|
59
|
+
slcli --profile "$PROFILE" testmonitor product list \
|
|
60
|
+
--workspace "$WORKSPACE_ID" --format json --take 100 |
|
|
61
|
+
jq --arg name "<PRODUCT_NAME>" --arg part "<PART_NUMBER>" '
|
|
62
|
+
[ .[] | select(
|
|
63
|
+
(($name != "") and ((.name // "" | ascii_downcase) | contains($name | ascii_downcase)))
|
|
64
|
+
or (($part != "") and ((.partNumber // "" | ascii_downcase) | contains($part | ascii_downcase)))
|
|
65
|
+
) | {id, name, partNumber, family, workspace} ]'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
An empty result from a name or family filter does not prove that the product is
|
|
69
|
+
absent. Increase the bounded catalog limit only deliberately, and project the
|
|
70
|
+
candidate fields in `jq` before displaying them. Fetch the selected record only
|
|
71
|
+
after identifying its ID:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
slcli --profile "$PROFILE" testmonitor product get <PRODUCT_ID> --format json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Overview budget:**
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Directly linked metadata, only when relevant to the question
|
|
81
|
+
slcli --profile "$PROFILE" spec list --product <PRODUCT_ID> --format json
|
|
82
|
+
|
|
83
|
+
# Compact counts and status breakdown
|
|
84
|
+
slcli --profile "$PROFILE" testmonitor result list \
|
|
85
|
+
--part-number "<PART_NUMBER>" --summary --group-by status \
|
|
86
|
+
--format json
|
|
87
|
+
|
|
88
|
+
# Grouped program summary
|
|
89
|
+
slcli --profile "$PROFILE" testmonitor result list \
|
|
90
|
+
--part-number "<PART_NUMBER>" --summary --group-by programName \
|
|
91
|
+
--format json
|
|
92
|
+
|
|
93
|
+
# Latest 5 to 10 results, projected to relevant fields
|
|
94
|
+
slcli --profile "$PROFILE" testmonitor result list \
|
|
95
|
+
--part-number "<PART_NUMBER>" --order-by STARTED_AT --descending \
|
|
96
|
+
--take 10 --format json |
|
|
97
|
+
jq '[.[] | {id, status: .status.statusType, startedAt, programName,
|
|
98
|
+
partNumber, serialNumber}]'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Use `testmonitor result get <RESULT_ID> --include-steps --format json` only
|
|
102
|
+
when the user asks about a particular run or failure. Counts from separate
|
|
103
|
+
commands are not one atomic snapshot; report the `as of` time and call out
|
|
104
|
+
live-data changes when totals do not agree.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
24
108
|
## Recipe 1: Operator failure rate analysis
|
|
25
109
|
|
|
26
110
|
**Question:** Which operators have the highest failure rates and what should they
|
|
@@ -482,8 +566,9 @@ slcli workitem schedule wi-12345 \
|
|
|
482
566
|
- **Start with `--summary`** to understand data shape before fetching raw records.
|
|
483
567
|
- **Use `--group-by`** with `--summary` for aggregation: `status`, `programName`,
|
|
484
568
|
`serialNumber`, `operator`, `hostName`, `systemId`.
|
|
485
|
-
- **Chain with `jq`** for complex transformations — always use
|
|
486
|
-
- **Use `--take` wisely** — start
|
|
569
|
+
- **Chain with `jq`** for complex transformations — always use `--format json`.
|
|
570
|
+
- **Use `--take` wisely** — start with 5-10 for recent detail and a bounded
|
|
571
|
+
catalog query for discovery; increase only when the question requires it.
|
|
487
572
|
- **For rate calculations**, query total count and filtered count separately, then divide.
|
|
488
573
|
- **Use `--order-by TOTAL_TIME_IN_SECONDS --descending`** to find slowest tests quickly.
|
|
489
574
|
- **Asset `--connected` flag** limits to assets in currently connected systems.
|