@salesforce/afv-skills 1.58.0 → 1.60.0

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 (242) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-architecture-analyze/SKILL.md +66 -17
  3. package/skills/agentforce-architecture-analyze/assets/cli/show_access_token.yaml +4 -7
  4. package/skills/agentforce-architecture-analyze/references/contract.json +1 -1
  5. package/skills/agentforce-architecture-analyze/scripts/emit_env.py +2 -2
  6. package/skills/agentforce-architecture-analyze/scripts/main.py +40 -44
  7. package/skills/agentforce-architecture-analyze/scripts/rest_client.py +11 -3
  8. package/skills/agentforce-architecture-analyze/scripts/sf_cli.py +77 -10
  9. package/skills/agentforce-architecture-analyze/scripts/tests/test_end_to_end_fixture.py +1 -0
  10. package/skills/agentforce-architecture-analyze/scripts/tests/test_flow_children_inflation.py +1 -0
  11. package/skills/agentforce-architecture-analyze/scripts/tests/test_main_pipeline.py +53 -2
  12. package/skills/agentforce-architecture-analyze/scripts/tests/test_resolve_creds.py +184 -36
  13. package/skills/agentforce-architecture-analyze/scripts/tests/test_rest_client.py +17 -0
  14. package/skills/agentforce-architecture-analyze/scripts/tests/test_sf_cli.py +165 -11
  15. package/skills/agentforce-architecture-analyze/scripts/tests/test_skill_md_pipeline_block.py +319 -0
  16. package/skills/agentforce-bot-upgrade/SKILL.md +3 -1
  17. package/skills/agentforce-d360-analyze/SKILL.md +28 -10
  18. package/skills/agentforce-d360-analyze/scripts/dc.py +200 -50
  19. package/skills/agentforce-d360-analyze/scripts/discover_sessions.py +10 -6
  20. package/skills/agentforce-d360-analyze/scripts/fetch_dc.py +22 -6
  21. package/skills/agentforce-d360-analyze/scripts/resolve_session.py +21 -13
  22. package/skills/agentforce-d360-analyze/scripts/tests/test_dc_and_resolve_session.py +298 -76
  23. package/skills/agentforce-d360-analyze/scripts/tests/test_default_target_org.py +432 -0
  24. package/skills/agentforce-d360-analyze/scripts/tests/test_discover_sessions.py +1 -1
  25. package/skills/agentforce-d360-analyze/scripts/tests/test_resolve_session_main.py +9 -3
  26. package/skills/agentforce-d360-analyze/scripts/tests/test_skill_md_prefix_block.py +176 -0
  27. package/skills/agentforce-generate/SKILL.md +21 -1
  28. package/skills/agentforce-generate/references/known-issues.md +51 -1
  29. package/skills/agentforce-generate/references/legacy-nga-regression-eval.md +547 -0
  30. package/skills/agentforce-generate/references/upgrade-legacy-agent-to-agentscript.md +577 -0
  31. package/skills/agentforce-generate/scripts/upgrade-legacy-nga-analyze.py +404 -0
  32. package/skills/agentforce-generate/scripts/upgrade-legacy-nga-run-trials.sh +58 -0
  33. package/skills/agentforce-persona-generate/SKILL.md +505 -0
  34. package/skills/agentforce-persona-generate/assets/checklist-template.md +100 -0
  35. package/skills/agentforce-persona-generate/assets/persona-encoding-template.md +252 -0
  36. package/skills/agentforce-persona-generate/assets/persona-template.md +229 -0
  37. package/skills/agentforce-persona-generate/assets/sample-dialog-template.md +50 -0
  38. package/skills/agentforce-persona-generate/assets/workshop-outline-template.md +97 -0
  39. package/skills/agentforce-persona-generate/examples/concierge-persona.md +189 -0
  40. package/skills/agentforce-persona-generate/examples/concierge-sample-dialog.md +70 -0
  41. package/skills/agentforce-persona-generate/examples/drover-persona.md +194 -0
  42. package/skills/agentforce-persona-generate/examples/drover-sample-dialog.md +62 -0
  43. package/skills/agentforce-persona-generate/examples/steady-hand-persona.md +188 -0
  44. package/skills/agentforce-persona-generate/examples/steady-hand-sample-dialog.md +68 -0
  45. package/skills/agentforce-persona-generate/examples/yt-persona.md +195 -0
  46. package/skills/agentforce-persona-generate/examples/yt-sample-dialog.md +66 -0
  47. package/skills/agentforce-persona-generate/references/attributions.md +36 -0
  48. package/skills/agentforce-persona-generate/references/interaction-design-notes.md +30 -0
  49. package/skills/agentforce-persona-generate/references/persona-encoding-guide.md +566 -0
  50. package/skills/agentforce-persona-generate/references/persona-framework.md +796 -0
  51. package/skills/agentforce-persona-generate/references/refinement-mappings.md +31 -0
  52. package/skills/agentforce-persona-generate/references/scoring-rubric.md +58 -0
  53. package/skills/agentforce-persona-generate/references/voice-catalog.json +2327 -0
  54. package/skills/agentforce-persona-generate/references/workshop-question-policy.md +90 -0
  55. package/skills/agentforce-persona-generate/references/workshop-scenario-seeds.md +119 -0
  56. package/skills/agentforce-persona-generate/scripts/parse_agent_yaml.py +223 -0
  57. package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +17 -27
  58. package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +7 -17
  59. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +47 -63
  60. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +10 -13
  61. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -46
  62. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +4 -21
  63. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +58 -82
  64. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +16 -315
  65. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +9 -24
  66. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -44
  67. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +11 -63
  68. package/skills/consumer-goods-rtr-datacloud-export-configure/SKILL.md +2 -1
  69. package/skills/consumer-goods-tpe-dashboard-configure/SKILL.md +2 -1
  70. package/skills/consumer-goods-tpe-dashboard-custom-kpi-configure/SKILL.md +2 -1
  71. package/skills/consumer-goods-tpe-datakit-deploy/SKILL.md +2 -1
  72. package/skills/data360-schema-get/SKILL.md +3 -3
  73. package/skills/design-systems-slds-validate/references/report-format.md +1 -1
  74. package/skills/dx-app-analytics-query/SKILL.md +8 -8
  75. package/skills/dx-org-manage/SKILL.md +1 -0
  76. package/skills/dx-org-shape-manage/SKILL.md +1 -0
  77. package/skills/dx-org-snapshot-manage/SKILL.md +172 -0
  78. package/skills/dx-org-snapshot-manage/examples/create_error_output.json +16 -0
  79. package/skills/dx-org-snapshot-manage/examples/create_success_output.json +19 -0
  80. package/skills/dx-org-snapshot-manage/examples/delete_output.json +9 -0
  81. package/skills/dx-org-snapshot-manage/examples/get_output.json +19 -0
  82. package/skills/dx-org-snapshot-manage/examples/list_output.json +36 -0
  83. package/skills/dx-org-snapshot-manage/references/cli_flags.md +179 -0
  84. package/skills/dx-org-snapshot-manage/references/snapshot_usage.md +55 -0
  85. package/skills/dx-org-trial-expiration-check/SKILL.md +1 -1
  86. package/skills/dx-org-trial-expiration-check/scripts/check_expiration.sh +2 -2
  87. package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +7 -5
  88. package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +11 -11
  89. package/skills/experience-content-media-image-generate/SKILL.md +83 -0
  90. package/skills/experience-content-media-image-generate/scripts/download-image.sh +84 -0
  91. package/skills/experience-ui-bundle-app-coordinate/SKILL.md +12 -12
  92. package/skills/experience-ui-bundle-app-coordinate/references/phase-completion-validation.md +3 -3
  93. package/skills/experience-ui-bundle-app-coordinate/references/phase-execution-pattern.md +9 -7
  94. package/skills/experience-ui-bundle-app-coordinate/scripts/check-dangling-refs.mjs +132 -0
  95. package/skills/experience-ui-bundle-app-coordinate/scripts/check-hosting-target.mjs +62 -0
  96. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-1-complete.mjs +71 -0
  97. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-4-complete.mjs +95 -0
  98. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-6-ready.mjs +78 -0
  99. package/skills/experience-ui-bundle-app-coordinate/scripts/check-prerequisites.mjs +21 -0
  100. package/skills/experience-ui-bundle-app-coordinate/scripts/check-sfdx-project.mjs +28 -0
  101. package/skills/experience-ui-bundle-custom-app-generate/SKILL.md +3 -1
  102. package/skills/experience-ui-bundle-custom-app-generate/scripts/resolve-uibundle-path.mjs +40 -0
  103. package/skills/experience-ui-bundle-frontend-generate/SKILL.md +7 -5
  104. package/skills/experience-ui-bundle-frontend-generate/scripts/check-preconditions.mjs +70 -0
  105. package/skills/experience-ui-bundle-frontend-generate/scripts/resolve-ui-bundle.mjs +76 -0
  106. package/skills/experience-ui-bundle-frontend-generate/scripts/verify-rules.mjs +115 -0
  107. package/skills/experience-ui-bundle-metadata-generate/SKILL.md +7 -3
  108. package/skills/experience-ui-bundle-metadata-generate/references/angular-metadata-generate.md +1 -1
  109. package/skills/experience-ui-bundle-metadata-generate/references/react-metadata-generate.md +1 -1
  110. package/skills/experience-ui-bundle-metadata-generate/scripts/check-api-version.mjs +43 -0
  111. package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.mjs +131 -0
  112. package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.mjs +152 -0
  113. package/skills/experience-ui-bundle-mfa-configure/references/branding.md +10 -6
  114. package/skills/external-diagram-mermaid-generate/SKILL.md +12 -12
  115. package/skills/field-service-data-capture-migrate/references/component-mapping.md +1 -1
  116. package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +1 -2
  117. package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +1 -0
  118. package/skills/field-service-data-capture-migrate/references/transformer-rules.md +1 -1
  119. package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +12 -1
  120. package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +4 -1
  121. package/skills/field-service-setup-orchestrator-get/SKILL.md +0 -1
  122. package/skills/insurance-brokerage-agency-billing-configure/SKILL.md +233 -0
  123. package/skills/insurance-brokerage-agency-billing-configure/references/accounting-setup.md +117 -0
  124. package/skills/insurance-brokerage-agency-billing-configure/references/billing-rules-config.md +237 -0
  125. package/skills/insurance-brokerage-agency-billing-configure/references/billing-settings.md +271 -0
  126. package/skills/insurance-brokerage-agency-billing-configure/references/demo-policy-config.md +138 -0
  127. package/skills/insurance-brokerage-agency-billing-configure/references/org-defaults.md +64 -0
  128. package/skills/insurance-brokerage-agency-billing-configure/references/permissions-config.md +226 -0
  129. package/skills/insurance-brokerage-agency-billing-configure/references/prerequisites.md +142 -0
  130. package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +3 -2
  131. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +3 -3
  132. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +68 -45
  133. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +17 -18
  134. package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +16 -3
  135. package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +16 -13
  136. package/skills/marketing-message-test/SKILL.md +194 -0
  137. package/skills/marketing-message-test/references/api-contract.md +333 -0
  138. package/skills/omnistudio-callable-apex-generate/SKILL.md +3 -3
  139. package/skills/omnistudio-datamapper-generate/SKILL.md +6 -6
  140. package/skills/omnistudio-datapacks-deploy/SKILL.md +11 -11
  141. package/skills/omnistudio-dependencies-analyze/SKILL.md +5 -5
  142. package/skills/omnistudio-epc-catalog-generate/SKILL.md +6 -6
  143. package/skills/omnistudio-flexcard-generate/SKILL.md +6 -6
  144. package/skills/omnistudio-integration-procedure-generate/SKILL.md +6 -6
  145. package/skills/omnistudio-omniscript-generate/SKILL.md +6 -5
  146. package/skills/platform-apex-logs-debug/SKILL.md +1 -0
  147. package/skills/platform-metadata-deploy/SKILL.md +1 -0
  148. package/skills/platform-models-api-configure/SKILL.md +5 -5
  149. package/skills/platform-soql-query/SKILL.md +1 -0
  150. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +17 -6
  151. package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +107 -192
  152. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone-action.json +6 -6
  153. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +49 -20
  154. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +4 -4
  155. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +224 -290
  156. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/workflow.md +295 -0
  157. package/skills/service-itsm-incident-priority-configure/SKILL.md +1 -1
  158. package/skills/service-itsm-slack-itservice-configure/SKILL.md +2 -1
  159. package/skills/service-itsm-slack-itservice-configure/references/manage-slack-connection.md +2 -2
  160. package/skills/service-omni-channel-setup-coordinate/SKILL.md +20 -13
  161. package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +5 -55
  162. package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +0 -38
  163. package/skills/service-omni-command-center-analyze/SKILL.md +2 -3
  164. package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
  165. package/skills/tableau-next-asset-create/README.md +65 -0
  166. package/skills/tableau-next-asset-create/SKILL.md +409 -0
  167. package/skills/tableau-next-asset-create/references/admin-users.md +149 -0
  168. package/skills/tableau-next-asset-create/references/ai-readiness.md +355 -0
  169. package/skills/tableau-next-asset-create/references/alerts.md +111 -0
  170. package/skills/tableau-next-asset-create/references/build-workflow.md +819 -0
  171. package/skills/tableau-next-asset-create/references/dashboard-authoring.md +302 -0
  172. package/skills/tableau-next-asset-create/references/dashboard-design-principles.md +352 -0
  173. package/skills/tableau-next-asset-create/references/data-transform-gotchas.md +210 -0
  174. package/skills/tableau-next-asset-create/references/data-understanding.md +387 -0
  175. package/skills/tableau-next-asset-create/references/deep-reference-index.md +74 -0
  176. package/skills/tableau-next-asset-create/references/destructive-operations.md +62 -0
  177. package/skills/tableau-next-asset-create/references/edit-dashboard.md +273 -0
  178. package/skills/tableau-next-asset-create/references/edit-visualization.md +529 -0
  179. package/skills/tableau-next-asset-create/references/empty-source-handling.md +104 -0
  180. package/skills/tableau-next-asset-create/references/ingest-and-metric-gotchas.md +638 -0
  181. package/skills/tableau-next-asset-create/references/insight-bundle.md +69 -0
  182. package/skills/tableau-next-asset-create/references/large-flat-file-handling.md +331 -0
  183. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_envelope.json +54 -0
  184. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_shared-widget-fields.json +122 -0
  185. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/add_page.json +29 -0
  186. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/delete_page.json +27 -0
  187. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/discard_dashboard.json +11 -0
  188. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget.json +30 -0
  189. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget_to_page.json +30 -0
  190. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/place_widget_on_page.json +30 -0
  191. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_dashboard.json +16 -0
  192. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_page.json +26 -0
  193. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/rename_page.json +28 -0
  194. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/save_dashboard.json +18 -0
  195. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/undo.json +11 -0
  196. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_button_widget.json +69 -0
  197. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_container_widget.json +88 -0
  198. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_filter_widget.json +146 -0
  199. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_metric_widget.json +78 -0
  200. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_navigation_widget.json +80 -0
  201. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_parameter_widget.json +160 -0
  202. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_text_widget.json +103 -0
  203. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_visualization_widget.json +68 -0
  204. package/skills/tableau-next-asset-create/references/sdm-tool-reference.md +721 -0
  205. package/skills/tableau-next-asset-create/references/semantic-query-and-enrichment.md +355 -0
  206. package/skills/tableau-next-asset-create/references/shared-gates.md +322 -0
  207. package/skills/tableau-next-asset-create/references/sharing-and-promotion.md +306 -0
  208. package/skills/tableau-next-asset-create/references/tasks/ai-readiness-audit.md +51 -0
  209. package/skills/tableau-next-asset-create/references/tasks/analyze-data.md +48 -0
  210. package/skills/tableau-next-asset-create/references/tasks/build-dashboard.md +66 -0
  211. package/skills/tableau-next-asset-create/references/tasks/build-end-to-end.md +73 -0
  212. package/skills/tableau-next-asset-create/references/tasks/create-data-transform.md +51 -0
  213. package/skills/tableau-next-asset-create/references/tasks/create-viz.md +58 -0
  214. package/skills/tableau-next-asset-create/references/tasks/edit-dashboard.md +80 -0
  215. package/skills/tableau-next-asset-create/references/tasks/edit-sdm.md +106 -0
  216. package/skills/tableau-next-asset-create/references/tasks/edit-viz.md +40 -0
  217. package/skills/tableau-next-asset-create/references/tasks/enrich-model.md +68 -0
  218. package/skills/tableau-next-asset-create/references/tasks/ingest-flat-file.md +68 -0
  219. package/skills/tableau-next-asset-create/references/tasks/manage-alert.md +35 -0
  220. package/skills/tableau-next-asset-create/references/tasks/profile-dataset.md +47 -0
  221. package/skills/tableau-next-asset-create/references/tasks/promote-or-reuse.md +46 -0
  222. package/skills/tableau-next-asset-create/references/tasks/provision-user.md +39 -0
  223. package/skills/tableau-next-asset-create/references/tasks/query-model.md +92 -0
  224. package/skills/tableau-next-asset-create/references/tasks/review-verified-questions.md +42 -0
  225. package/skills/tableau-next-asset-create/references/tasks/share-asset.md +37 -0
  226. package/skills/tableau-next-asset-create/references/verified-questions.md +125 -0
  227. package/skills/tableau-next-asset-create/references/viz-authoring.md +992 -0
  228. package/skills/experience-ui-bundle-app-coordinate/scripts/check-dangling-refs.sh +0 -42
  229. package/skills/experience-ui-bundle-app-coordinate/scripts/check-hosting-target.sh +0 -26
  230. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-1-complete.sh +0 -35
  231. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-4-complete.sh +0 -47
  232. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-6-ready.sh +0 -33
  233. package/skills/experience-ui-bundle-app-coordinate/scripts/check-prerequisites.sh +0 -20
  234. package/skills/experience-ui-bundle-app-coordinate/scripts/check-sfdx-project.sh +0 -15
  235. package/skills/experience-ui-bundle-custom-app-generate/scripts/resolve-uibundle-path.sh +0 -30
  236. package/skills/experience-ui-bundle-frontend-generate/scripts/check-preconditions.sh +0 -37
  237. package/skills/experience-ui-bundle-frontend-generate/scripts/resolve-ui-bundle.sh +0 -66
  238. package/skills/experience-ui-bundle-frontend-generate/scripts/verify-rules.sh +0 -58
  239. package/skills/experience-ui-bundle-metadata-generate/scripts/check-api-version.sh +0 -30
  240. package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.sh +0 -73
  241. package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.sh +0 -118
  242. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +0 -102
@@ -8,17 +8,22 @@ Two responsibilities:
8
8
  column names — those live in the .sql files.
9
9
 
10
10
  2. **Transport.** `resolve_org(alias)` shells out to `sf org display`
11
- for the instance URL + access token. `post(sql, instance_url, token)`
11
+ for the instance URL and `sf org auth show-access-token` for the
12
+ access token. `post(sql, instance_url, token)`
12
13
  POSTs the SQL to the Data Cloud Query API and returns parsed rows.
13
14
  Errors route through `DCQueryError` with the full response body + SQL
14
15
  context so callers can surface a useful message.
16
+ `default_target_org()` reads the sf CLI default target org for entry
17
+ points invoked without `--org`. Both it and `resolve_org` run the
18
+ `show-access-token` capability preflight as their first sf call, so on
19
+ either path a too-old CLI fails with the upgrade message first.
15
20
 
16
21
  Persistence lives in `storage.save`.
17
22
  """
18
23
  from __future__ import annotations
19
24
 
20
25
  import json
21
- import os
26
+ import re
22
27
  import subprocess
23
28
  import sys
24
29
  import urllib.error
@@ -71,51 +76,206 @@ wording has shifted across sf CLI builds while the subcommand has been
71
76
  stable since forcedotcom/cli#3560 landed."""
72
77
 
73
78
 
74
- def _run_sf_json(argv: list[str], env: dict | None = None) -> dict:
79
+ # Token-redaction patterns, vendored from agentforce-architecture-analyze's
80
+ # rest_client (this skill is self-contained and must not import across
81
+ # skills). sf CLI failure output can echo the access token — e.g. a
82
+ # `show-access-token --json` run that exits non-zero with the payload on
83
+ # stdout — so every stderr/stdout string is scrubbed before it reaches a
84
+ # SystemExit message. Deliberately permissive: over-redact, never leak.
85
+ _AUTH_HEADER_RE = re.compile(r"(Authorization\s*:\s*Bearer\s+)\S+", re.IGNORECASE) # @rule-suppress starter-sec-002 — re.compile, not exec/eval
86
+ _BEARER_RE = re.compile(r"(\bBearer\s+)[^\s\"']+", re.IGNORECASE) # @rule-suppress starter-sec-002 — re.compile, not exec/eval
87
+ _ACCESS_TOKEN_QS_RE = re.compile(r"(access[_]?token\s*=\s*)[^&\s\"']+", re.IGNORECASE) # @rule-suppress starter-sec-002 — re.compile, not exec/eval
88
+ _ACCESS_TOKEN_JSON_RE = re.compile(r"(\"access[_]?token\"\s*:\s*\")[^\"]*", re.IGNORECASE) # @rule-suppress starter-sec-002 — re.compile, not exec/eval
89
+
90
+
91
+ def _redact_text(text: str | None) -> str:
92
+ """Scrub bearer tokens and accessToken values from sf CLI output."""
93
+ if not text:
94
+ return ""
95
+ text = _AUTH_HEADER_RE.sub(r"\1<redacted>", text)
96
+ text = _BEARER_RE.sub(r"\1<redacted>", text)
97
+ text = _ACCESS_TOKEN_QS_RE.sub(r"\1<redacted>", text)
98
+ text = _ACCESS_TOKEN_JSON_RE.sub(r"\1<redacted>", text)
99
+ return text
100
+
101
+
102
+ def _run_sf_json(argv: list[str]) -> dict:
75
103
  """Shell out + parse JSON. SystemExits on FileNotFoundError /
76
- CalledProcessError so callers get a clean message instead of a stack."""
104
+ CalledProcessError so callers get a clean message instead of a stack.
105
+ Failure output is redacted before it is surfaced."""
77
106
  try:
78
- r = subprocess.run(
79
- argv, capture_output=True, text=True, check=True, env=env,
80
- )
107
+ r = subprocess.run(argv, capture_output=True, text=True, check=True)
81
108
  except FileNotFoundError:
82
109
  raise SystemExit("sf CLI not found on PATH — install Salesforce CLI first")
83
110
  except subprocess.CalledProcessError as e:
111
+ detail = _redact_text((e.stderr or "").strip() or (e.stdout or "").strip())
112
+ raise SystemExit(f"{' '.join(argv[:4])}... failed:\n{detail}") from None
113
+ return json.loads(r.stdout)
114
+
115
+
116
+ _show_access_token_capability_ok = False
117
+ """Set once the preflight succeeds; the check then never reruns in this
118
+ process. Failures are NOT cached, so a fixed PATH/upgrade is picked up on
119
+ the next call."""
120
+
121
+ _SHOW_ACCESS_TOKEN_HELP_SIGNATURE_RE = re.compile(
122
+ r"\$\s*sf\s+org\s+auth\s+show-access-token\b"
123
+ )
124
+ """USAGE-line form that real `--help` output always contains
125
+ (`$ sf org auth show-access-token -o <value> ...`). The bare command name is
126
+ not enough: unknown-command notices echo it too
127
+ (`Command org:auth:show-access-token not found`,
128
+ `show-access-token is not a sf command`). A zero-exit probe whose output
129
+ lacks the USAGE form is treated as a failed check."""
130
+
131
+ _ANSI_ESCAPE_RE = re.compile(r"\x1b\[[0-9;?]*[ -/]*[@-~]")
132
+
133
+
134
+ def _assert_show_access_token_capability() -> None:
135
+ """Fail fast if the installed sf CLI lacks `sf org auth show-access-token`.
136
+
137
+ That command is the only supported token-retrieval path
138
+ (forcedotcom/cli#3560). Probing `--help` needs no org auth and turns a
139
+ confusing downstream failure into an actionable upgrade message.
140
+ `default_target_org` and `resolve_org` each call this first, ahead of
141
+ every other sf call they make. A successful probe is cached for the
142
+ process lifetime, so the second call costs nothing.
143
+
144
+ Exit status alone is not trusted: a CLI build that answers an unknown
145
+ command with exit 0 (e.g. printing top-level help or a "not found"
146
+ notice) would otherwise pass. The probe therefore also requires the
147
+ command's USAGE line (`$ sf org auth show-access-token`) in the
148
+ ANSI-stripped stdout+stderr; if it is absent the check fails and is not
149
+ cached.
150
+ """
151
+ global _show_access_token_capability_ok
152
+ if _show_access_token_capability_ok:
153
+ return
154
+ try:
155
+ proc = subprocess.run(
156
+ ["sf", "org", "auth", "show-access-token", "--help"],
157
+ capture_output=True,
158
+ text=True,
159
+ timeout=30,
160
+ check=True,
161
+ )
162
+ except FileNotFoundError as exc:
84
163
  raise SystemExit(
85
- f"{' '.join(argv[:4])}... failed:\n{e.stderr.strip() or e.stdout.strip()}"
164
+ "sf CLI not found on PATH — install Salesforce CLI first"
165
+ ) from exc
166
+ except subprocess.CalledProcessError as exc:
167
+ detail = (
168
+ _redact_text((exc.stderr or "").strip() or (exc.stdout or "").strip())
169
+ or "unknown error"
86
170
  )
87
- return json.loads(r.stdout)
171
+ raise SystemExit(
172
+ "sf CLI is missing required command "
173
+ "'sf org auth show-access-token'. Upgrade/reinstall Salesforce CLI "
174
+ "to a build that provides this command, then retry.\n"
175
+ f"Preflight detail: {detail}"
176
+ ) from exc
177
+ except subprocess.TimeoutExpired as exc:
178
+ raise SystemExit(
179
+ "sf CLI capability preflight for 'sf org auth show-access-token' "
180
+ "timed out after 30s"
181
+ ) from exc
182
+ help_text = _ANSI_ESCAPE_RE.sub(
183
+ "", f"{proc.stdout or ''}\n{proc.stderr or ''}",
184
+ )
185
+ if not _SHOW_ACCESS_TOKEN_HELP_SIGNATURE_RE.search(help_text):
186
+ # Zero exit without the command's help signature — the CLI did not
187
+ # recognise the command. Fail (uncached) like a non-zero exit.
188
+ # Redact before truncating so a token can never be split past the regex.
189
+ detail = (
190
+ _redact_text(help_text.strip())[:500]
191
+ or "help output lacked the command signature"
192
+ )
193
+ raise SystemExit(
194
+ "sf CLI is missing required command "
195
+ "'sf org auth show-access-token'. Upgrade/reinstall Salesforce CLI "
196
+ "to a build that provides this command, then retry.\n"
197
+ f"Preflight detail: {detail}"
198
+ )
199
+ _show_access_token_capability_ok = True
88
200
 
89
201
 
90
- def resolve_org(alias: str) -> tuple[str, str]:
91
- """Resolve instanceUrl + accessToken for the sf org alias.
202
+ NO_DEFAULT_ORG_MSG = (
203
+ "no --org given and no default target org set — run "
204
+ "`sf config set target-org <alias>` or pass --org <alias>"
205
+ )
206
+
207
+
208
+ def default_target_org() -> str:
209
+ """Return the sf CLI default target org alias/username.
92
210
 
93
- Two-path strategy per forcedotcom/cli#3560 (effective 2026-05-27):
211
+ Used by entry points when ``--org`` is omitted ("my org" means the CLI
212
+ default). Reads ``.result[0].value`` from
213
+ ``sf config get target-org --json``. Raises SystemExit with a clear,
214
+ redacted message when the CLI is missing, fails, times out, returns
215
+ non-JSON, or has no default set.
94
216
 
95
- 1. **Primary** — `sf org display --json --verbose` for instanceUrl,
96
- then `sf org auth show-access-token --json --no-prompt` for the
97
- access token. This is the upstream long-term path; the
98
- `SF_TEMP_SHOW_SECRETS=true` workaround is decommissioned in
99
- summer 2026.
100
- 2. **Fallback** — if `sf org auth show-access-token` is unknown
101
- (older sf CLI) OR returns an empty/redacted value, fall back
102
- to the accessToken from the org_display call which uses
103
- `SF_TEMP_SHOW_SECRETS=true` env var to bypass the redaction.
217
+ The show-access-token capability preflight runs first, before
218
+ ``sf config get``. A CLI too old to fetch a token then fails with the
219
+ upgrade/reinstall message, not a misleading "no default org" message.
220
+ The preflight is cached per process, so the later ``resolve_org`` call
221
+ does not probe again.
222
+ """
223
+ _assert_show_access_token_capability()
224
+ argv = ["sf", "config", "get", "target-org", "--json"]
225
+ try:
226
+ proc = subprocess.run(
227
+ argv, capture_output=True, text=True, timeout=30, check=True,
228
+ )
229
+ except FileNotFoundError:
230
+ raise SystemExit(
231
+ "sf CLI not found on PATH — install Salesforce CLI first"
232
+ ) from None
233
+ except subprocess.CalledProcessError as exc:
234
+ detail = (
235
+ _redact_text((exc.stderr or "").strip() or (exc.stdout or "").strip())
236
+ or "unknown error"
237
+ )
238
+ raise SystemExit(
239
+ f"{NO_DEFAULT_ORG_MSG}\n`sf config get target-org` failed: {detail}"
240
+ ) from None
241
+ except subprocess.TimeoutExpired:
242
+ raise SystemExit(
243
+ f"{NO_DEFAULT_ORG_MSG}\n`sf config get target-org` timed out after 30s"
244
+ ) from None
245
+ try:
246
+ payload = json.loads(proc.stdout or "")
247
+ except json.JSONDecodeError:
248
+ raise SystemExit(
249
+ f"{NO_DEFAULT_ORG_MSG}\n`sf config get target-org --json` returned "
250
+ f"non-JSON output: {_redact_text(proc.stdout.strip())[:200]}"
251
+ ) from None
252
+ result = payload.get("result") if isinstance(payload, dict) else None
253
+ first = result[0] if isinstance(result, list) and result else {}
254
+ value = first.get("value") if isinstance(first, dict) else None
255
+ if not isinstance(value, str) or not value.strip():
256
+ raise SystemExit(NO_DEFAULT_ORG_MSG)
257
+ return value.strip()
104
258
 
105
- `--verbose` is required on the org_display call: without it, sf CLI
106
- v2 omits `accessToken` from the JSON entirely (so the fallback
107
- path needs both `--verbose` and the env var to work).
259
+
260
+ def resolve_org(alias: str) -> tuple[str, str]:
261
+ """Resolve instanceUrl + accessToken for the sf org alias.
262
+
263
+ Token retrieval is fail-fast (forcedotcom/cli#3560): the access token
264
+ comes ONLY from `sf org auth show-access-token --json --no-prompt`.
265
+ `sf org display --json --verbose` is used for non-secret metadata
266
+ (instanceUrl); any `accessToken` it carries is ignored.
108
267
 
109
268
  Raises SystemExit on CLI failure — this is the one thing every
110
269
  downstream operation depends on, so a clean early exit is friendlier
111
270
  than a stack trace.
112
271
  """
113
- # Step 1: org_display gives us instanceUrl always; accessToken is
114
- # the legacy fallback path (redacted unless SF_TEMP_SHOW_SECRETS=true).
115
- env = {**os.environ, "SF_TEMP_SHOW_SECRETS": "true"}
272
+ # Step 1: capability preflight first, so a missing sf binary or missing
273
+ # command yields the actionable preflight error (cached once it passes).
274
+ _assert_show_access_token_capability()
275
+
276
+ # Step 2: org_display for instanceUrl (non-secret metadata only).
116
277
  display = _run_sf_json(
117
278
  ["sf", "org", "display", "--target-org", alias, "--json", "--verbose"],
118
- env=env,
119
279
  )["result"]
120
280
  instance_url = display.get("instanceUrl") or ""
121
281
  if not instance_url:
@@ -123,37 +283,27 @@ def resolve_org(alias: str) -> tuple[str, str]:
123
283
  f"sf org display returned no instanceUrl for alias {alias!r}"
124
284
  )
125
285
 
126
- # Step 2: prefer the dedicated command. Older sf CLI versions emit
127
- # "is not a sf command" with returncode 0 (warning, not error), so
128
- # we detect by parsing JSON shape. If the command is unknown the
129
- # output isn't JSON; we let the json parse error trigger the fallback.
130
- access_token = ""
286
+ # Step 3: dedicated command is the only token source.
131
287
  try:
132
288
  token_payload = _run_sf_json(
133
289
  ["sf", "org", "auth", "show-access-token",
134
290
  "--target-org", alias, "--json", "--no-prompt"],
135
291
  )
136
- except (SystemExit, json.JSONDecodeError):
137
- # Unknown command on older sf CLI → JSON parse fails OR
138
- # CalledProcessError → SystemExit; either way, fall through.
139
- pass
140
- else:
141
- token_result = token_payload.get("result") or {}
142
- access_token = token_result.get("accessToken") or ""
143
-
144
- # Fallback: if the dedicated command didn't yield a usable token,
145
- # try the legacy SF_TEMP_SHOW_SECRETS path via the org_display
146
- # payload we already have.
147
- if not access_token or _REDACTION_MARKER_FRAGMENT in access_token:
148
- legacy = display.get("accessToken") or ""
149
- if legacy and _REDACTION_MARKER_FRAGMENT not in legacy:
150
- access_token = legacy
292
+ except (SystemExit, json.JSONDecodeError) as exc:
293
+ raise SystemExit(
294
+ f"could not retrieve access token for alias {alias!r} via "
295
+ "sf org auth show-access-token; ensure the org is authenticated "
296
+ f"(sf org login web --alias {alias}).\nDetail: {exc}"
297
+ ) from exc
298
+
299
+ token_result = token_payload.get("result") or {}
300
+ access_token = token_result.get("accessToken") or ""
151
301
 
152
302
  if not access_token or _REDACTION_MARKER_FRAGMENT in access_token:
153
303
  raise SystemExit(
154
304
  f"could not retrieve a usable access token for alias {alias!r} "
155
- f"via sf org auth show-access-token (primary) or sf org display "
156
- f"(fallback). Ensure sf CLI is logged in for this org."
305
+ "via sf org auth show-access-token. Ensure sf CLI is logged in "
306
+ "for this org and the command returned a real token."
157
307
  )
158
308
 
159
309
  return instance_url, access_token
@@ -9,9 +9,11 @@ DC-only by design (no OTel path).
9
9
 
10
10
  ## CLI
11
11
 
12
- python3 scripts/discover_sessions.py --org <alias> [options]
12
+ python3 scripts/discover_sessions.py [--org <alias>] [options]
13
13
 
14
- Options (all optional except --org):
14
+ Options (all optional):
15
+ --org <alias> sf CLI org alias. Default: the sf CLI default target org
16
+ (`sf config get target-org`).
15
17
  --since <expr> "last 2 hours" | "last 10" | "today" | "yesterday"
16
18
  | "YYYY-MM-DD" | "YYYY-MM-DD to YYYY-MM-DD"
17
19
  | explicit UTC/TZ datetime (RFC 3339). Default: last 24 hours.
@@ -55,7 +57,7 @@ from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
55
57
 
56
58
  sys.path.insert(0, str(Path(__file__).parent))
57
59
 
58
- from dc import DCQueryError, load_sql, post, resolve_org
60
+ from dc import DCQueryError, default_target_org, load_sql, post, resolve_org
59
61
  from _shared.sql import _escape_sql_literal
60
62
 
61
63
 
@@ -477,7 +479,8 @@ def main() -> int:
477
479
  description="Find candidate Agentforce sessions via Data Cloud. "
478
480
  "Prints a numbered picker; no artifacts written.",
479
481
  )
480
- ap.add_argument("--org", required=True, help="sf CLI org alias (the one you configured via `sf org login`)")
482
+ ap.add_argument("--org", help="sf CLI org alias (the one you configured via `sf org login`). "
483
+ "Default: the sf CLI default target org")
481
484
  ap.add_argument("--since", help='time range: "last 2 hours" | "today" | "yesterday" | '
482
485
  '"YYYY-MM-DD" | "YYYY-MM-DD to YYYY-MM-DD" | ISO datetime. '
483
486
  'Default: last 24 hours.')
@@ -519,7 +522,8 @@ def main() -> int:
519
522
  limit=args.limit,
520
523
  )
521
524
 
522
- instance_url, token = resolve_org(args.org)
525
+ org = args.org or default_target_org()
526
+ instance_url, token = resolve_org(org)
523
527
  try:
524
528
  rows = post(sql, instance_url, token, "discover_sessions")
525
529
  except DCQueryError as e:
@@ -544,7 +548,7 @@ def main() -> int:
544
548
  print(render_picker(
545
549
  rows=rows,
546
550
  agent_by_sid=agent_by_sid,
547
- org=args.org,
551
+ org=org,
548
552
  tr=tr,
549
553
  filters=filters,
550
554
  composed_sql=sql,
@@ -23,7 +23,9 @@ Design contract:
23
23
  - Rerunning the same session overwrites prior artifacts.
24
24
 
25
25
  Invocation:
26
- python3 scripts/fetch_dc.py --session <uuid> --org <alias> [--verbose]
26
+ python3 scripts/fetch_dc.py --session <uuid> [--org <alias>] [--verbose]
27
+
28
+ `--org` defaults to the sf CLI default target org (`sf config get target-org`).
27
29
 
28
30
  After the waterfall finishes, the fetcher chains two downstream steps:
29
31
  1. assemble_dc.main_for_session → dc._session_tree.json
@@ -66,7 +68,7 @@ from pathlib import Path
66
68
  sys.path.insert(0, str(Path(__file__).parent))
67
69
 
68
70
  from config import DATA_ROOT, paths, sql as _sql_mod
69
- from dc import SQL_DIR, DCQueryError, load_sql, post, resolve_org
71
+ from dc import SQL_DIR, DCQueryError, default_target_org, load_sql, post, resolve_org
70
72
  from storage import save
71
73
 
72
74
 
@@ -357,7 +359,7 @@ def main() -> int:
357
359
  help="AI-agent session UUID, OR a Salesforce MessagingSession id "
358
360
  "(0Mw... prefix). Messaging ids are resolved to the UUID "
359
361
  "via a one-row DC lookup before the waterfall starts.")
360
- ap.add_argument("--org", required=True, help="sf org alias")
362
+ ap.add_argument("--org", help="sf org alias (default: the sf CLI default target org)")
361
363
  ap.add_argument("--verbose", action="store_true", help="dump each SQL before POST")
362
364
  ap.add_argument("--no-assemble", action="store_true",
363
365
  help="skip tree assembly after fetch")
@@ -371,6 +373,20 @@ def main() -> int:
371
373
 
372
374
  _preflight_templates()
373
375
 
376
+ # No --org means the sf CLI default target org. If none is set, surface
377
+ # it through the DC-access-denied contract (reason "no_org", exit 10
378
+ # headless) — the same path an unresolvable alias takes.
379
+ org = args.org
380
+ if not org:
381
+ try:
382
+ org = default_target_org()
383
+ except SystemExit as e:
384
+ return _handle_dc_access_denied(
385
+ DcAccessDenied("no_org", str(e)),
386
+ session_id=args.session,
387
+ is_tty=sys.stdin.isatty(),
388
+ )
389
+
374
390
  # Accept either a UUID or a MessagingSession id (0Mw...). The resolver
375
391
  # passes UUIDs through unchanged; on messaging ids it tries disk first
376
392
  # (any prior fetch left dc.sessions.json behind under DATA_ROOT), and
@@ -380,7 +396,7 @@ def main() -> int:
380
396
  # On multi-match or zero-match the resolver exits with a diagnostic.
381
397
  from resolve_session import is_messaging_id, resolve_disk_or_live
382
398
  input_id = args.session
383
- session_id = resolve_disk_or_live(input_id, org=args.org)
399
+ session_id = resolve_disk_or_live(input_id, org=org)
384
400
  if is_messaging_id(input_id):
385
401
  _log(f"resolved messaging id {input_id} → AiAgentSession {session_id}")
386
402
 
@@ -390,7 +406,7 @@ def main() -> int:
390
406
  # emits either an interactive prompt or a JSON preamble depending on
391
407
  # tty presence, then exits with EXIT_DC_ACCESS_DENIED (10).
392
408
  try:
393
- instance_url, token = preflight_dc_access(session_id, args.org)
409
+ instance_url, token = preflight_dc_access(session_id, org)
394
410
  except DcAccessDenied as exc:
395
411
  return _handle_dc_access_denied(
396
412
  exc,
@@ -402,7 +418,7 @@ def main() -> int:
402
418
 
403
419
  ctx = {
404
420
  "session_id": session_id,
405
- "org_alias": args.org,
421
+ "org_alias": org,
406
422
  "instance_url": instance_url,
407
423
  "token": token,
408
424
  "verbose": args.verbose,
@@ -21,7 +21,8 @@ specific UUID.
21
21
 
22
22
  ## Two resolution modes
23
23
 
24
- 1. **Live** — query DC. Requires `--org`. Used by `fetch_dc.py` at the
24
+ 1. **Live** — query DC against `--org` (CLI: defaults to the sf CLI default
25
+ target org). Used by `fetch_dc.py` at the
25
26
  top of the pipeline (before any artifacts exist on disk).
26
27
  2. **Disk-first** — scan `DATA_ROOT/*/dc.sessions.json` for a row whose
27
28
  `ssot__RelatedMessagingSessionId__c` matches. No DC call, no `--org`
@@ -31,7 +32,7 @@ specific UUID.
31
32
 
32
33
  ## CLI
33
34
 
34
- python3 scripts/resolve_session.py --id <uuid|msg_id> --org <alias>
35
+ python3 scripts/resolve_session.py --id <uuid|msg_id> [--org <alias>]
35
36
 
36
37
  Prints the resolved UUID to stdout on single-match (or pass-through).
37
38
  Non-zero exit with diagnostics on zero-match and multi-match.
@@ -47,7 +48,7 @@ from typing import List, Optional
47
48
  sys.path.insert(0, str(Path(__file__).parent))
48
49
 
49
50
  from config import DATA_ROOT
50
- from dc import load_sql, post, resolve_org
51
+ from dc import default_target_org, load_sql, post, resolve_org
51
52
 
52
53
 
53
54
  # NOT_SET sentinel set. Matches fetch_dc.py:41; keep in sync.
@@ -224,7 +225,8 @@ def main() -> int:
224
225
  )
225
226
  ap.add_argument("--id", required=True,
226
227
  help="Either the AI-agent session UUID or the MessagingSession id (0Mw...)")
227
- ap.add_argument("--org", help="sf org alias (required for live DC lookup when input is 0Mw...)")
228
+ ap.add_argument("--org", help="sf org alias for the live DC lookup when input is 0Mw... "
229
+ "(default: the sf CLI default target org)")
228
230
  ap.add_argument("--disk-only", action="store_true",
229
231
  help="Only scan DATA_ROOT/*/dc.sessions.json; no DC query")
230
232
  # Runtime-agnostic path overrides; default to ~/.vibe/...
@@ -243,19 +245,25 @@ def main() -> int:
243
245
  return 1
244
246
  print(found)
245
247
  return 0
246
- if not args.org:
247
- # Try disk first as a convenience; only error if that also misses.
248
+ org = args.org
249
+ if not org:
250
+ # Try disk first as a convenience; on a miss, fall back to the sf CLI
251
+ # default target org for the live lookup, and only error if that
252
+ # is unset too.
248
253
  disk = resolve_from_disk(args.id)
249
254
  if disk is not None:
250
255
  print(disk)
251
256
  return 0
252
- print(
253
- f"resolve_session: {args.id!r} not found on disk; --org <alias> required "
254
- f"for a live DC lookup",
255
- file=sys.stderr,
256
- )
257
- return 2
258
- uuid = resolve(args.id, org=args.org)
257
+ try:
258
+ org = default_target_org()
259
+ except SystemExit as e:
260
+ print(
261
+ f"resolve_session: {args.id!r} not found on disk; --org <alias> required "
262
+ f"for a live DC lookup ({e})",
263
+ file=sys.stderr,
264
+ )
265
+ return 2
266
+ uuid = resolve(args.id, org=org)
259
267
  print(uuid)
260
268
  return 0
261
269