systemlink-cli 2.1.0__tar.gz → 2.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/PKG-INFO +2 -1
  2. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/pyproject.toml +2 -1
  3. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/_version.py +1 -1
  4. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/config_click.py +54 -14
  5. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/main.py +3 -3
  6. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/managed_client/transport.py +27 -7
  7. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/policy_click.py +81 -0
  8. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/commands.md +5 -0
  9. systemlink_cli-2.3.0/slcli/ssl_trust.py +633 -0
  10. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_click.py +51 -46
  11. systemlink_cli-2.1.0/slcli/ssl_trust.py +0 -376
  12. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/LICENSE +0 -0
  13. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/dff-editor/editor.js +0 -0
  14. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/dff-editor/index.html +0 -0
  15. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/__init__.py +0 -0
  16. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/__main__.py +0 -0
  17. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/alarm_click.py +0 -0
  18. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/asset_click.py +0 -0
  19. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/cli_formatters.py +0 -0
  20. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/cli_utils.py +0 -0
  21. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/comment_click.py +0 -0
  22. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/completion_click.py +0 -0
  23. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/config.py +0 -0
  24. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/credentials.py +0 -0
  25. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/dataframe_click.py +0 -0
  26. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/dff_click.py +0 -0
  27. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/dff_decorators.py +0 -0
  28. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/example_click.py +0 -0
  29. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/example_loader.py +0 -0
  30. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/example_provisioner.py +0 -0
  31. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/README.md +0 -0
  32. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/_schema/schema-v1.0.json +0 -0
  33. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/demo-data-1/README.md +0 -0
  34. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/demo-data-1/config.yaml +0 -0
  35. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/demo-data-2/README.md +0 -0
  36. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/demo-data-2/config.yaml +0 -0
  37. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/demo-data-3/config.yaml +0 -0
  38. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/demo-data-3/leakage-current-results.json +0 -0
  39. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/demo-data-3/overvoltage-results.json +0 -0
  40. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/demo-data-3/product-xyz-compliance-report.json +0 -0
  41. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/demo-data-3/product-xyz-specification.csv +0 -0
  42. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/demo-data-3/thermal-response-results.json +0 -0
  43. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/exercise-5-1-parametric-insights/README.md +0 -0
  44. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/exercise-5-1-parametric-insights/config.yaml +0 -0
  45. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/exercise-7-1-test-plans/README.md +0 -0
  46. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/exercise-7-1-test-plans/config.yaml +0 -0
  47. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/spec-compliance-notebooks/README.md +0 -0
  48. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/spec-compliance-notebooks/config.yaml +0 -0
  49. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/spec-compliance-notebooks/notebooks/SpecAnalysis_ComplianceCalculation.ipynb +0 -0
  50. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/spec-compliance-notebooks/notebooks/SpecComplianceCalculation.ipynb +0 -0
  51. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/spec-compliance-notebooks/notebooks/SpecfileExtractionAndIngestion.ipynb +0 -0
  52. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/examples/spec-compliance-notebooks/spec_template.xlsx +0 -0
  53. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/feed_click.py +0 -0
  54. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/file_click.py +0 -0
  55. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/function_click.py +0 -0
  56. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/function_templates.py +0 -0
  57. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/managed_client/__init__.py +0 -0
  58. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/managed_client/crypto.py +0 -0
  59. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/managed_client/handlers.py +0 -0
  60. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/managed_client/minion.py +0 -0
  61. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/managed_client/models.py +0 -0
  62. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/managed_client/protocol.py +0 -0
  63. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/managed_client/rest.py +0 -0
  64. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/managed_client/state.py +0 -0
  65. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/managed_client_click.py +0 -0
  66. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/mcp_click.py +0 -0
  67. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/mcp_reachability.py +0 -0
  68. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/mcp_server.py +0 -0
  69. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/mcp_skills.py +0 -0
  70. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/notebook_click.py +0 -0
  71. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/pkce.py +0 -0
  72. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/platform.py +0 -0
  73. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/policy_utils.py +0 -0
  74. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/profile_credentials.py +0 -0
  75. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/profiles.py +0 -0
  76. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/response_handlers.py +0 -0
  77. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/rich_output.py +0 -0
  78. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/routine_click.py +0 -0
  79. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skill_click.py +0 -0
  80. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/SKILL.md +0 -0
  81. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/evals/COPILOT_BATCH_RUN_PROMPT.md +0 -0
  82. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/evals/README.md +0 -0
  83. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/evals/evals.json +0 -0
  84. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/evals/evals.schema.json +0 -0
  85. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/evals/files/spec-import/battery-specs.csv +0 -0
  86. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/evals/files/webapp-package/icon.svg +0 -0
  87. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/evals/files/webapp-package/nipkg.config.json +0 -0
  88. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/evals/files/webapp-package/webapp-content/index.html +0 -0
  89. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/evals/trigger_evals.json +0 -0
  90. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/analysis-recipes.md +0 -0
  91. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/datasheet-workflow.md +0 -0
  92. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/domain-concepts.md +0 -0
  93. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/example-authoring.md +0 -0
  94. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/filtering.md +0 -0
  95. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/import-specs.min.json +0 -0
  96. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/job-debugging/overview.md +0 -0
  97. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/nipkg/overview.md +0 -0
  98. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/notebook/interfaces.md +0 -0
  99. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/notebook/notebook-patterns.md +0 -0
  100. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/notebook/overview.md +0 -0
  101. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/python-test/overview.md +0 -0
  102. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/routine-examples.md +0 -0
  103. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/troubleshooting.md +0 -0
  104. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/webapp/angular-ui-packages.md +0 -0
  105. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/webapp/deployment.md +0 -0
  106. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/webapp/layout-patterns.md +0 -0
  107. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/webapp/nimble-angular.md +0 -0
  108. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/webapp/overview.md +0 -0
  109. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/webapp/systemlink-services.md +0 -0
  110. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/references/webapp/troubleshooting.md +0 -0
  111. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/scripts/benchmark_iteration.py +0 -0
  112. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/scripts/compare_iteration.py +0 -0
  113. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/scripts/eval_manifest.py +0 -0
  114. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/scripts/grade_eval_response.py +0 -0
  115. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/scripts/grade_iteration.py +0 -0
  116. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/scripts/prepare_eval_prompts.py +0 -0
  117. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/scripts/prepare_eval_workspace.py +0 -0
  118. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/scripts/render_eval_review.py +0 -0
  119. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/skills/slcli/scripts/spec_import_helper.py +0 -0
  120. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/spec_click.py +0 -0
  121. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/state_click.py +0 -0
  122. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/system_click.py +0 -0
  123. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/system_query_utils.py +0 -0
  124. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/systemlink-logo.svg +0 -0
  125. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/table_utils.py +0 -0
  126. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/tag_click.py +0 -0
  127. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/templates_click.py +0 -0
  128. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/testmonitor_click.py +0 -0
  129. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/universal_handlers.py +0 -0
  130. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/user_click.py +0 -0
  131. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/utils.py +0 -0
  132. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/version_click.py +0 -0
  133. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/web_editor.py +0 -0
  134. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_bootstrap.py +0 -0
  135. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/.gitignore +0 -0
  136. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/README.md +0 -0
  137. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/angular.json +0 -0
  138. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/package.json +0 -0
  139. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/scripts/filter-sbom.js +0 -0
  140. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/app-routing.module.ts +0 -0
  141. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/app.component.html +0 -0
  142. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/app.component.scss +0 -0
  143. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/app.component.ts +0 -0
  144. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/app.module.ts +0 -0
  145. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/core/layout/app-shell.component.html +0 -0
  146. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/core/layout/app-shell.component.scss +0 -0
  147. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/core/layout/app-shell.component.ts +0 -0
  148. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/core/state/app-view-state.service.ts +0 -0
  149. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/core/systemlink/systemlink-context.service.ts +0 -0
  150. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/core/systemlink/theme-sync.service.ts +0 -0
  151. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/core/systemlink/webapp-home-data.service.ts +0 -0
  152. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.html +0 -0
  153. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.scss +0 -0
  154. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.ts +0 -0
  155. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.html +0 -0
  156. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.scss +0 -0
  157. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.ts +0 -0
  158. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/home/home-page.component.html +0 -0
  159. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/home/home-page.component.scss +0 -0
  160. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/home/home-page.component.ts +0 -0
  161. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/master-detail/master-detail-page.component.html +0 -0
  162. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/master-detail/master-detail-page.component.scss +0 -0
  163. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/master-detail/master-detail-page.component.ts +0 -0
  164. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/operations/operations-page.component.html +0 -0
  165. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/operations/operations-page.component.scss +0 -0
  166. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/operations/operations-page.component.ts +0 -0
  167. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.html +0 -0
  168. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.scss +0 -0
  169. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.ts +0 -0
  170. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/shared/components/empty-state.component.html +0 -0
  171. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/shared/components/empty-state.component.scss +0 -0
  172. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/shared/components/empty-state.component.ts +0 -0
  173. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/shared/components/error-banner.component.html +0 -0
  174. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/shared/components/error-banner.component.scss +0 -0
  175. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/shared/components/error-banner.component.ts +0 -0
  176. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/shared/components/loading-state.component.html +0 -0
  177. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/shared/components/loading-state.component.scss +0 -0
  178. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/shared/components/loading-state.component.ts +0 -0
  179. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/app/shared/states/view-state.model.ts +0 -0
  180. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/assets/README.md +0 -0
  181. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/index.html +0 -0
  182. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/main.ts +0 -0
  183. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/src/styles.scss +0 -0
  184. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/tsconfig.app.json +0 -0
  185. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/webapp_templates/angular/blank/tsconfig.json +0 -0
  186. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/workflow_preview.py +0 -0
  187. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/workflows_click.py +0 -0
  188. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/workitem_click.py +0 -0
  189. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/workspace_click.py +0 -0
  190. {systemlink_cli-2.1.0 → systemlink_cli-2.3.0}/slcli/workspace_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: systemlink-cli
3
- Version: 2.1.0
3
+ Version: 2.3.0
4
4
  Summary: SystemLink Integrator CLI - cross-platform CLI for SystemLink workflows and templates.
5
5
  License-File: LICENSE
6
6
  Author: Fred Visser
@@ -18,6 +18,7 @@ Requires-Dist: cryptography (>=49.0.0)
18
18
  Requires-Dist: filelock (>=3.20,<4)
19
19
  Requires-Dist: httpcore2 (>=2.10.0,<3) ; extra == "mcp"
20
20
  Requires-Dist: httpx2 (>=2.12.0,<3) ; extra == "mcp"
21
+ Requires-Dist: idna (>=3.10,<4)
21
22
  Requires-Dist: keyring (>=25.6.0,<26.0.0)
22
23
  Requires-Dist: mcp (>=2,<3) ; extra == "mcp"
23
24
  Requires-Dist: msgpack (>=1.1,<2) ; extra == "managed-client"
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "systemlink-cli"
3
- version = "2.1.0"
3
+ version = "2.3.0"
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" }]
@@ -29,6 +29,7 @@ click = ">=7.1.2"
29
29
  filelock = ">=3.20,<4"
30
30
  keyring = "^25.6.0"
31
31
  requests = "^2.32.4"
32
+ idna = ">=3.10,<4"
32
33
  tabulate = "^0.10.0"
33
34
  truststore = ">=0.9,<0.11"
34
35
  watchdog = "^6.0.0"
@@ -1,4 +1,4 @@
1
1
  """Version information for slcli."""
2
2
 
3
3
  # This file is auto-generated. Do not edit manually.
4
- __version__ = "2.1.0"
4
+ __version__ = "2.3.0"
@@ -6,6 +6,7 @@ import os
6
6
  import re
7
7
  import ssl
8
8
  import sys
9
+ from pathlib import Path
9
10
  from typing import Any, NoReturn, Optional
10
11
  from urllib.parse import urlparse
11
12
 
@@ -26,14 +27,16 @@ from .platform import (
26
27
  from .profiles import Profile, ProfileConfig, check_config_file_permissions
27
28
  from .rich_output import render_table
28
29
  from .ssl_trust import (
30
+ get_managed_trust_path,
29
31
  get_managed_trust_records,
30
32
  get_ssl_server_origin,
31
33
  inspect_server_certificate,
34
+ load_ca_certificate,
32
35
  remove_managed_trust,
33
36
  save_managed_certificate,
34
37
  )
35
38
  from .table_utils import output_formatted_list
36
- from .utils import ExitCodes, get_base_url, get_base_url_resolution
39
+ from .utils import ExitCodes, get_base_url_resolution
37
40
 
38
41
  API_KEY_LENGTH = 42
39
42
  API_KEY_PATTERN = re.compile(rf"^[A-Za-z0-9_-]{{{API_KEY_LENGTH}}}$")
@@ -765,12 +768,31 @@ def register_config_commands(cli: Any) -> None:
765
768
  )
766
769
 
767
770
  certificate_details = certificate.to_dict()
771
+ trusted_certificate = None
772
+ try:
773
+ trusted_path = get_managed_trust_path(certificate.origin)
774
+ if trusted_path is not None:
775
+ trusted_certificate = json.loads(
776
+ trusted_path.with_suffix(".json").read_text(encoding="utf-8")
777
+ )
778
+ trusted_certificate["origin"] = certificate.origin
779
+ trusted_certificate.setdefault("trust-type", "leaf")
780
+ except (OSError, ValueError) as exc:
781
+ click.echo(f"Could not read managed certificate metadata: {exc}.", err=True)
782
+ trusted_certificate = None
768
783
  if output_format == "json":
784
+ certificate_details["trusted-certificate"] = trusted_certificate
769
785
  click.echo(json.dumps(certificate_details, indent=2))
770
786
  return
771
787
 
772
788
  click.echo(f"Server certificate for {certificate_details.get('origin', 'unknown')}")
773
789
  _show_certificate_details(certificate_details)
790
+ if trusted_certificate:
791
+ kind = "CA" if trusted_certificate.get("trust-type") == "ca" else "leaf"
792
+ click.echo(f"\nTrusted {kind} certificate for this origin")
793
+ _show_certificate_details(trusted_certificate)
794
+ else:
795
+ click.echo("\nNo managed trust certificate for this origin.")
774
796
 
775
797
  @trust.command(name="list")
776
798
  @click.option(
@@ -794,13 +816,14 @@ def register_config_commands(cli: Any) -> None:
794
816
  [
795
817
  str(record.get("origin", "")),
796
818
  str(record.get("fingerprint", "")),
819
+ "CA" if record.get("trust-type") == "ca" else "leaf",
797
820
  "yes" if record.get("self-signed") else "no",
798
821
  ]
799
822
  for record in records
800
823
  ]
801
824
  render_table(
802
- headers=["SERVER", "SHA-256", "SELF-SIGNED"],
803
- column_widths=[40, 64, 12],
825
+ headers=["SERVER", "SHA-256", "TRUST TYPE", "SELF-SIGNED"],
826
+ column_widths=[40, 64, 10, 12],
804
827
  rows=rows,
805
828
  show_total=True,
806
829
  total_label="certificate(s)",
@@ -808,30 +831,47 @@ def register_config_commands(cli: Any) -> None:
808
831
 
809
832
  @trust.command(name="add")
810
833
  @click.option("--url", help="HTTPS server URL (defaults to the active API URL)")
834
+ @click.option(
835
+ "--certificate",
836
+ type=click.Path(exists=True, dir_okay=False, path_type=Path),
837
+ help="Import one public CA certificate (PEM or DER), scoped to this server origin",
838
+ )
811
839
  @click.option(
812
840
  "--fingerprint",
813
841
  required=True,
814
842
  help="Expected SHA-256 fingerprint of the certificate to trust",
815
843
  )
816
- def add_trusted_certificate(url: Optional[str], fingerprint: str) -> None:
817
- """Trust a server certificate after verifying its fingerprint."""
818
- server_url = url or get_base_url()
844
+ def add_trusted_certificate(
845
+ url: Optional[str], certificate: Optional[Path], fingerprint: str
846
+ ) -> None:
847
+ """Trust a live server certificate or imported CA after fingerprint verification."""
848
+ server_url = url or get_base_url_resolution().value
819
849
  try:
820
850
  expected_fingerprint = _normalize_fingerprint(fingerprint)
821
- certificate = inspect_server_certificate(server_url)
851
+ trusted_certificate = (
852
+ load_ca_certificate(server_url, certificate)
853
+ if certificate is not None
854
+ else inspect_server_certificate(server_url)
855
+ )
822
856
  except (OSError, ValueError, ssl.SSLError) as exc:
823
- _exit_with_validation_error(f"Could not inspect the server certificate: {exc}.")
857
+ _exit_with_validation_error(f"Could not load the certificate: {exc}.")
824
858
 
825
- _show_certificate_warning(certificate.to_dict())
826
- if certificate.fingerprint != expected_fingerprint:
859
+ _show_certificate_details(trusted_certificate.to_dict(), err=True)
860
+ if trusted_certificate.fingerprint != expected_fingerprint:
827
861
  _exit_with_validation_error(
828
- "The server certificate fingerprint does not match the supplied fingerprint."
862
+ "The certificate fingerprint does not match the supplied fingerprint."
863
+ )
864
+ if trusted_certificate.trust_type == "ca":
865
+ click.echo(
866
+ "Trusting certificates issued by this CA for this origin only; "
867
+ "hostname and validity verification remain enabled.",
868
+ err=True,
829
869
  )
830
870
  try:
831
- path = save_managed_certificate(certificate)
871
+ path = save_managed_certificate(trusted_certificate)
832
872
  except OSError as exc:
833
873
  _exit_with_validation_error(f"Could not save the trusted certificate: {exc}.")
834
- click.echo(f"✓ Trusted certificate for {certificate.origin}")
874
+ click.echo(f"✓ Trusted certificate for {trusted_certificate.origin}")
835
875
  click.echo(f" Certificate file: {path}")
836
876
 
837
877
  @trust.command(name="remove")
@@ -839,7 +879,7 @@ def register_config_commands(cli: Any) -> None:
839
879
  @click.option("--force", is_flag=True, help="Skip confirmation prompt")
840
880
  def remove_trusted_certificate(url: Optional[str], force: bool) -> None:
841
881
  """Remove a server certificate from the managed trust store."""
842
- server_url = url or get_base_url()
882
+ server_url = url or get_base_url_resolution().value
843
883
  try:
844
884
  origin = get_ssl_server_origin(server_url)
845
885
  except ValueError as exc:
@@ -35,7 +35,7 @@ from .rich_output import install_rich_output, render_table
35
35
  from .routine_click import register_routine_commands
36
36
  from .skill_click import register_skill_commands
37
37
  from .spec_click import register_spec_commands
38
- from .ssl_trust import OS_TRUST_INJECTED, OS_TRUST_REASON
38
+ from .ssl_trust import OS_TRUST_INJECTED, OS_TRUST_REASON, create_explicit_tls_context
39
39
  from .state_click import register_state_commands
40
40
  from .system_click import register_system_commands
41
41
  from .tag_click import register_tag_commands
@@ -143,11 +143,11 @@ def _build_tls_debug_context(ssl_verify: Union[bool, str]) -> ssl.SSLContext:
143
143
  return ctx
144
144
 
145
145
  if isinstance(ssl_verify, str):
146
- return ssl.create_default_context(cafile=ssl_verify)
146
+ return create_explicit_tls_context(ssl_verify)
147
147
 
148
148
  verify_env = os.environ.get("REQUESTS_CA_BUNDLE") or os.environ.get("SSL_CERT_FILE")
149
149
  if verify_env:
150
- return ssl.create_default_context(cafile=verify_env)
150
+ return create_explicit_tls_context(verify_env)
151
151
 
152
152
  if OS_TRUST_INJECTED:
153
153
  try:
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import socket
6
+ import threading
6
7
  from collections import deque
7
8
  from dataclasses import dataclass
8
9
  from urllib.parse import urlsplit
@@ -12,6 +13,7 @@ from .protocol import MAX_FRAME_SIZE, MessagePackStream, SaltMessage
12
13
 
13
14
  DEFAULT_REQUEST_PORT = 4506
14
15
  DEFAULT_PUBLISH_PORT = 4505
16
+ IDLE_RECEIVE_POLL_INTERVAL = 0.1
15
17
 
16
18
 
17
19
  @dataclass(frozen=True)
@@ -53,6 +55,7 @@ class SaltChannel:
53
55
  self._decoder = MessagePackStream(max_frame_size=max_frame_size)
54
56
  self._pending: deque[SaltMessage] = deque()
55
57
  self._closed = False
58
+ self._receive_lock = threading.RLock()
56
59
 
57
60
  @classmethod
58
61
  def connect(
@@ -80,7 +83,7 @@ class SaltChannel:
80
83
  raise TransportError("Unable to send a Salt message.") from error
81
84
 
82
85
  def receive(self, *, ignore_timeout: bool = False) -> SaltMessage:
83
- """Read until one complete Salt MessagePack message is available."""
86
+ """Read a complete Salt message, polling for closure when ignoring timeouts."""
84
87
  if self._closed:
85
88
  raise TransportError("The Salt channel is closed.")
86
89
  if self._pending:
@@ -89,7 +92,23 @@ class SaltChannel:
89
92
  if self._closed:
90
93
  raise TransportError("The Salt channel is closed.")
91
94
  try:
92
- data = self._connection.recv(65536)
95
+ with self._receive_lock:
96
+ if self._closed:
97
+ raise TransportError("The Salt channel is closed.")
98
+ if ignore_timeout:
99
+ timeout = self._connection.gettimeout()
100
+ self._connection.settimeout(
101
+ IDLE_RECEIVE_POLL_INTERVAL
102
+ if timeout is None
103
+ else min(timeout, IDLE_RECEIVE_POLL_INTERVAL)
104
+ )
105
+ try:
106
+ data = self._connection.recv(65536)
107
+ finally:
108
+ if not self._closed:
109
+ self._connection.settimeout(timeout)
110
+ else:
111
+ data = self._connection.recv(65536)
93
112
  except socket.timeout as error:
94
113
  if ignore_timeout:
95
114
  continue
@@ -105,7 +124,7 @@ class SaltChannel:
105
124
  return self._pending.popleft()
106
125
 
107
126
  def close(self) -> None:
108
- """Close the socket and release its file descriptor."""
127
+ """Interrupt active reads before releasing the socket descriptor."""
109
128
  if self._closed:
110
129
  return
111
130
  self._closed = True
@@ -113,7 +132,8 @@ class SaltChannel:
113
132
  self._connection.shutdown(socket.SHUT_RDWR)
114
133
  except OSError:
115
134
  pass
116
- try:
117
- self._connection.close()
118
- except OSError:
119
- pass
135
+ with self._receive_lock:
136
+ try:
137
+ self._connection.close()
138
+ except OSError:
139
+ pass
@@ -18,6 +18,7 @@ from .policy_utils import (
18
18
  _format_template_list_row,
19
19
  _load_statements_from_file,
20
20
  _parse_properties_from_cli,
21
+ _validate_statements,
21
22
  )
22
23
  from .universal_handlers import FilteredResponse, UniversalResponseHandler
23
24
  from .utils import (
@@ -534,6 +535,86 @@ def register_policy_commands(cli: Any) -> None:
534
535
  except Exception as exc:
535
536
  handle_api_error(exc)
536
537
 
538
+ @template_group.command(name="update")
539
+ @click.argument("template_id")
540
+ @click.option("--name", type=str, default=None, help="New policy template name")
541
+ @click.option(
542
+ "--type",
543
+ "template_type",
544
+ type=click.Choice(["user", "service"], case_sensitive=False),
545
+ default=None,
546
+ help="New policy template type",
547
+ )
548
+ @click.option(
549
+ "--statements-file",
550
+ type=click.Path(exists=True, dir_okay=False),
551
+ default=None,
552
+ help='JSON file containing a statements list or an object with a "statements" list',
553
+ )
554
+ @click.option(
555
+ "--properties",
556
+ "-p",
557
+ multiple=True,
558
+ help="Updated custom properties as key=value (repeatable)",
559
+ )
560
+ @click.option(
561
+ "--format",
562
+ "-f",
563
+ type=click.Choice(["table", "json"]),
564
+ default="table",
565
+ show_default=True,
566
+ help="Output format",
567
+ )
568
+ def update_template(
569
+ template_id: str,
570
+ name: Optional[str],
571
+ template_type: Optional[str],
572
+ statements_file: Optional[str],
573
+ properties: Tuple[str, ...],
574
+ format: str,
575
+ ) -> None:
576
+ """Update selected fields on a reusable policy template."""
577
+ from .utils import check_readonly_mode
578
+
579
+ check_readonly_mode("update a policy template")
580
+
581
+ try:
582
+ payload: Dict[str, Any] = {}
583
+ if name is not None:
584
+ payload["name"] = name
585
+ if template_type is not None:
586
+ payload["type"] = template_type.lower()
587
+ if statements_file is not None:
588
+ statements = _load_statements_from_file(statements_file)
589
+ is_valid, error_message = _validate_statements(
590
+ statements,
591
+ require_workspace=False,
592
+ )
593
+ if not is_valid:
594
+ raise ValueError(error_message or "Invalid statements")
595
+ payload["statements"] = statements
596
+ if properties:
597
+ payload["properties"] = _parse_properties_from_cli(properties)
598
+ if not payload:
599
+ raise ValueError("At least one update option is required")
600
+ except ValueError as exc:
601
+ click.echo(f"✗ Error: {exc}", err=True)
602
+ sys.exit(ExitCodes.INVALID_INPUT)
603
+
604
+ try:
605
+ url = f"{get_base_url()}/niauth/v1/policy-templates/{template_id}"
606
+ current_template = make_api_request("GET", url, payload=None).json()
607
+ merged_payload = {
608
+ field: current_template[field]
609
+ for field in ("name", "type", "statements", "properties")
610
+ if field in current_template
611
+ }
612
+ merged_payload.update(payload)
613
+ resp = make_api_request("PUT", url, payload=merged_payload)
614
+ _display_template_details(resp.json(), format)
615
+ except Exception as exc:
616
+ handle_api_error(exc)
617
+
537
618
  @template_group.command(name="list")
538
619
  @click.option(
539
620
  "--type",
@@ -746,6 +746,7 @@ slcli auth policy diff <POLICY_ID_1> <POLICY_ID_2> # Compare two policies
746
746
  # Policy templates
747
747
  slcli auth template list [-t INT] [-f json]
748
748
  slcli auth template create --name TEXT --statements-file PATH [--type user|service] [-p KEY=VALUE] [-f json]
749
+ slcli auth template update TEMPLATE_ID [--name TEXT] [--type user|service] [--statements-file PATH] [-p KEY=VALUE] [-f json]
749
750
  slcli auth template get <TEMPLATE_ID> [-f json]
750
751
  slcli auth template delete <TEMPLATE_ID>
751
752
  ```
@@ -759,6 +760,10 @@ or an object with a `statements` array, for example:
759
760
  [{"actions": ["testresult:Read"], "resource": ["*"]}]
760
761
  ```
761
762
 
763
+ `auth template update` fetches the current template and preserves unspecified
764
+ fields before sending `PUT /niauth/v1/policy-templates/{template-id}`.
765
+ Supplied statements and properties replace their existing values.
766
+
762
767
  Workspace fields are not required. Properties are repeatable string-valued
763
768
  `key=value` pairs. JSON output returns the full created template, including
764
769
  its ID. Apply that ID to a workspace using `auth policy create TEMPLATE_ID