@salesforce/afv-skills 1.66.0 → 1.68.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.
- package/README.md +55 -5
- package/package.json +2 -4
- package/skills/agentforce-offline-experimentation-run/SKILL.md +26 -49
- package/skills/agentforce-offline-experimentation-run/scripts/bt_compare.py +81 -0
- package/skills/agentforce-offline-experimentation-run/scripts/bt_fetch.py +358 -0
- package/skills/agentforce-offline-experimentation-run/scripts/bt_patch_agent.py +110 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/__init__.py +34 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/agentpatch.py +483 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/agentsrc.py +565 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/cache.py +95 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/compare.py +617 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/fetch.py +1012 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/judge.py +148 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/messages.py +92 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/patch.py +327 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/redact.py +40 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/results.py +288 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/scoring.py +340 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/sfap.py +238 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/splits.py +136 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/stdm.py +98 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/tokens.py +173 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/units.py +199 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/versions.py +194 -0
- package/skills/agentforce-offline-experimentation-run/scripts/build_report.py +366 -378
- package/skills/agentforce-offline-experimentation-run/scripts/resolve-token.sh +14 -4
- package/skills/agentforce-offline-experimentation-run/scripts/sfap_replay.py +472 -796
- package/skills/commerce-react-storefront-create/SKILL.md +350 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/SKILL.md +2 -2
- package/skills/consumer-goods-promotion-bo-api-deploy/references/generate-and-wire.md +28 -16
- package/skills/consumer-goods-promotion-bo-api-deploy/references/smoke-and-verify.md +18 -1
- package/skills/dx-lifecycle-center/SKILL.md +5 -2
- package/skills/dx-lifecycle-center/assets/widgets/connect-connected/connect-connected.json +65 -0
- package/skills/dx-lifecycle-center/assets/widgets/connect-connected/schema.json +32 -0
- package/skills/dx-lifecycle-center/assets/widgets/connect-sign-in/connect-sign-in.json +57 -0
- package/skills/dx-lifecycle-center/assets/widgets/connect-sign-in/schema.json +21 -0
- package/skills/dx-lifecycle-center/examples/workflows.md +20 -6
- package/skills/dx-lifecycle-center/references/connect-org.md +21 -2
- package/skills/dx-lifecycle-center/references/deploy.md +2 -2
- package/skills/dx-lifecycle-center/references/list-orgs.md +1 -1
- package/skills/dx-lifecycle-center/scripts/card-policy.jq +71 -0
- package/skills/dx-lifecycle-center/scripts/fill-widget.jq +29 -0
- package/skills/dx-lifecycle-center/scripts/widget.sh +28 -0
- package/skills/dx-org-devhub-configure/SKILL.md +85 -84
- package/skills/dx-org-devhub-configure/examples/status-output.md +25 -2
- package/skills/dx-org-devhub-configure/scripts/devhub.sh +265 -140
- package/skills/dx-org-devhub-configure/scripts/test-devhub.sh +100 -15
- package/skills/dx-packaging-move-to-2gp-migrate/SKILL.md +89 -0
- package/skills/dx-packaging-move-to-2gp-migrate/references/api-operations.md +164 -0
- package/skills/dx-scratch-def-configure/SKILL.md +163 -0
- package/skills/dx-scratch-def-configure/examples/confirm-card.md +53 -0
- package/skills/dx-scratch-def-configure/examples/report-recipes.md +100 -0
- package/skills/dx-scratch-def-configure/references/features.json +3270 -0
- package/skills/dx-scratch-def-configure/references/project-scratch-def.schema.json +1841 -0
- package/skills/dx-scratch-def-configure/references/settings-map.json +682 -0
- package/skills/dx-scratch-def-configure/scripts/lib_scratch_def.py +1306 -0
- package/skills/dx-scratch-def-configure/scripts/requirements.txt +3 -0
- package/skills/dx-scratch-def-configure/scripts/scrape_config_values.py +848 -0
- package/skills/education-cloud-domain-configure/SKILL.md +22 -24
- package/skills/education-cloud-domain-configure/references/dependent-features.md +9 -0
- package/skills/education-cloud-domain-configure/references/domain-features.md +15 -0
- package/skills/education-cloud-domain-configure/references/gotchas-extended.md +8 -0
- package/skills/education-cloud-domain-configure/references/setup-widgets.md +123 -0
- package/skills/education-cloud-multi-campus-configure/SKILL.md +1 -1
- package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +1 -1
- package/skills/experience-design-validate/SKILL.md +1 -1
- package/skills/experience-search-coordinate/SKILL.md +19 -13
- package/skills/experience-search-coordinate/references/content-route.md +79 -1
- package/skills/experience-search-coordinate/references/media-route.md +30 -4
- package/skills/experience-ui-bundle-features-generate/SKILL.md +1 -1
- package/skills/experience-ui-bundle-mfa-configure/SKILL.md +1 -1
- package/skills/field-service-data-capture-migrate/SKILL.md +1 -1
- package/skills/platform-apex-generate/SKILL.md +14 -11
- package/skills/platform-apex-test-generate/SKILL.md +2 -1
- package/skills/platform-datamask-run/SKILL.md +52 -71
- package/skills/platform-datamask-run/references/api-surface.md +10 -4
- package/skills/platform-datamask-run/references/policy-authoring.md +56 -7
- package/skills/platform-datamask-run/references/run-and-abort.md +17 -10
- package/skills/platform-datamask-run/scripts/poll-job.sh +15 -25
- package/skills/platform-dataspace-access-configure/SKILL.md +19 -1
- package/skills/platform-metadata-deploy/README.md +1 -1
- package/skills/platform-metadata-deploy/SKILL.md +114 -15
- package/skills/platform-metadata-deploy/references/agent-deployment-guide.md +3 -4
- package/skills/platform-metadata-deploy/references/orchestration.md +2 -3
- package/skills/platform-metadata-discovery-get/SKILL.md +185 -0
- package/skills/platform-metadata-discovery-get/references/api-map.md +25 -0
- package/skills/platform-metadata-discovery-get/references/h360-routes.md +30 -0
- package/skills/platform-metadata-discovery-get/references/scoped-soql.md +52 -0
- package/skills/platform-metadata-grounding-get/SKILL.md +170 -0
- package/skills/platform-policy-rule-generate/SKILL.md +84 -232
- package/skills/platform-policy-rule-generate/references/condition-model.md +47 -0
- package/skills/platform-policy-rule-generate/references/condition-templates.md +89 -0
- package/skills/platform-policy-rule-generate/references/conjunction-compiler.md +25 -0
- package/skills/platform-policy-rule-generate/references/conjunction-expression.md +22 -0
- package/skills/platform-policy-rule-generate/references/consumer-all.md +9 -0
- package/skills/platform-policy-rule-generate/references/consumer-datacloud-ui.md +91 -0
- package/skills/platform-policy-rule-generate/references/deploy-errors.md +24 -36
- package/skills/platform-policy-rule-generate/references/examples/ExistsJoinRLS/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/ExistsJoinRLS/policyRuleDefinitionSets/ExistsJoinRLS.policyRuleDefinitionSet +6 -0
- package/skills/platform-policy-rule-generate/references/examples/ExistsJoinRLS/policyRuleDefinitions/ExistsJoinRLS_Rule_1.policyRuleDefinition +91 -0
- package/skills/platform-policy-rule-generate/references/examples/FieldReadDeny/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/FieldReadDeny/policyRuleDefinitionSets/FieldReadDeny.policyRuleDefinitionSet +6 -0
- package/skills/platform-policy-rule-generate/references/examples/FieldReadDeny/policyRuleDefinitions/FieldReadDeny_Rule_1.policyRuleDefinition +72 -0
- package/skills/platform-policy-rule-generate/references/examples/LastCharactersFieldMasking/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/LastCharactersFieldMasking/policyRuleDefinitionSets/LastCharactersFieldMasking.policyRuleDefinitionSet +6 -0
- package/skills/platform-policy-rule-generate/references/examples/LastCharactersFieldMasking/policyRuleDefinitions/LastCharactersFieldMasking_Rule_1.policyRuleDefinition +77 -0
- package/skills/platform-policy-rule-generate/references/examples/PrincipalFieldMatchRLS/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/PrincipalFieldMatchRLS/policyRuleDefinitionSets/PrincipalFieldMatchRLS.policyRuleDefinitionSet +6 -0
- package/skills/platform-policy-rule-generate/references/examples/PrincipalFieldMatchRLS/policyRuleDefinitions/PrincipalFieldMatchRLS_Rule_1.policyRuleDefinition +77 -0
- package/skills/platform-policy-rule-generate/references/examples/TaggedObjectAccess/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/TaggedObjectAccess/policyRuleDefinitionSets/TaggedObjectAccess.policyRuleDefinitionSet +4 -0
- package/skills/platform-policy-rule-generate/references/examples/TaggedObjectAccess/policyRuleDefinitions/TaggedObjectAccess_Rule_1.policyRuleDefinition +65 -0
- package/skills/platform-policy-rule-generate/references/headless-transport.md +87 -0
- package/skills/platform-policy-rule-generate/references/policy-schema-full.md +17 -10
- package/skills/platform-policy-rule-generate/references/policy-shapes.md +74 -0
- package/skills/platform-policy-rule-generate/references/principal-expression.md +31 -0
- package/skills/platform-policy-rule-generate/references/reference-resolution.md +51 -0
- package/skills/platform-policy-rule-generate/references/resource-expression.md +48 -0
- package/skills/platform-policy-rule-generate/references/runtime-context.md +9 -0
- package/skills/platform-policy-rule-generate/references/templates-access.md +11 -9
- package/skills/platform-policy-rule-generate/references/templates-advanced.md +4 -2
- package/skills/platform-policy-rule-generate/references/templates-record.md +37 -22
- package/skills/platform-policy-rule-generate/references/templates-transform.md +10 -8
- package/skills/platform-policy-rule-generate/references/templates.md +2 -2
- package/skills/platform-policy-rule-generate/references/ui-compatibility.md +35 -17
- package/skills/platform-report-generate/SKILL.md +9 -4
- package/skills/platform-report-generate/references/chart-types.md +26 -2
- package/skills/platform-report-generate/references/column-names.md +43 -0
- package/skills/platform-report-generate/references/errors-and-troubleshooting.md +1 -1
- package/skills/platform-report-generate/references/verification-checklist.md +10 -2
- package/skills/platform-value-set-generate/SKILL.md +19 -19
- package/skills/platform-widget-generate/SKILL.md +25 -51
- package/skills/platform-widget-generate/examples/formulas.json +19 -2
- package/skills/platform-widget-generate/examples/localized-labels.json +57 -0
- package/skills/platform-widget-generate/references/widget-actions.md +29 -0
- package/skills/platform-widget-generate/references/widget-bundle-validation.md +1 -0
- package/skills/platform-widget-generate/references/widget-formulas.md +24 -7
- package/skills/platform-widget-generate/references/widget-gotchas.md +10 -0
- package/skills/platform-widget-generate/references/widget-labels.md +78 -0
- package/skills/platform-widget-generate/references/widget-styling.md +12 -0
- package/skills/sales-call-scoring-configure/SKILL.md +17 -10
- package/skills/sales-call-scoring-configure/scripts/enable-call-scoring.sh +55 -33
- package/skills/service-digital-engagement-channel-configure/SKILL.md +11 -7
- package/skills/service-digital-engagement-channel-configure/assets/messaging_channel_template.xml +33 -0
- package/skills/service-digital-engagement-channel-configure/references/channel_settings.md +123 -16
- package/skills/service-digital-engagement-deployment-configure/SKILL.md +37 -100
- package/skills/service-digital-engagement-deployment-configure/assets/esd_web_update_template.xml +83 -8
- package/skills/service-digital-engagement-deployment-configure/examples/esd_web_prechat_fields.xml +74 -0
- package/skills/service-digital-engagement-deployment-configure/references/connect_api_creation.md +13 -3
- package/skills/service-digital-engagement-deployment-configure/references/deployment_settings.md +13 -78
- package/skills/service-digital-engagement-deployment-configure/references/onboarding_contract.md +5 -6
- package/skills/service-digital-engagement-deployment-configure/references/prechat_forms.md +245 -0
- package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +164 -120
- package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +61 -37
- package/skills/service-itsm-agentic-setup-incident-management/references/audit-tracking.md +42 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/broadcast-communications.md +23 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/email-to-incident.md +23 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-dashboards.md +25 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-persona-psg.md +30 -146
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-preferences.md +32 -136
- package/skills/service-itsm-agentic-setup-incident-management/references/major-incident-management.md +32 -155
- package/skills/service-itsm-agentic-setup-incident-management/references/manage-incidents-with-ai.md +45 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/priority-matrix.md +32 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/service-mgmt-privilege.md +30 -140
- package/skills/service-itsm-agentic-setup-incident-management/references/sla-milestones.md +110 -0
|
@@ -5,9 +5,13 @@
|
|
|
5
5
|
#
|
|
6
6
|
# Dev Hub is the org feature that lets you create and manage scratch orgs and
|
|
7
7
|
# second-generation (2GP)/unlocked packages. This script reports whether Dev Hub
|
|
8
|
-
# is enabled,
|
|
9
|
-
#
|
|
10
|
-
#
|
|
8
|
+
# is enabled, shows the org's scratch org ALLOCATION (Active/Daily limits and how
|
|
9
|
+
# many remain, with pre-flight warnings), reports the org EDITION, reads the
|
|
10
|
+
# current DevHubSettings PREFERENCES, ENABLES Dev Hub (or configures its
|
|
11
|
+
# sub-preferences) via a Metadata API deploy, and lists the active scratch orgs
|
|
12
|
+
# created from the Dev Hub. It can also list the authenticated orgs on this
|
|
13
|
+
# machine. It does NOT authenticate new orgs — that is a precondition; the script
|
|
14
|
+
# only prints the login command as guidance.
|
|
11
15
|
#
|
|
12
16
|
# How enablement works: the Dev Hub master switch is the deployable metadata
|
|
13
17
|
# field DevHubSettings.enableScratchOrgManagementPref (there is NO "enableDevHub"
|
|
@@ -25,29 +29,30 @@
|
|
|
25
29
|
# reliable enablement test.)
|
|
26
30
|
#
|
|
27
31
|
# Usage:
|
|
28
|
-
# devhub.sh [org] # status: is Dev Hub on? + allocation
|
|
29
|
-
# devhub.sh [org] --allocation # scratch org allocation only
|
|
32
|
+
# devhub.sh [org] # status: is Dev Hub on? + edition + allocation
|
|
33
|
+
# devhub.sh [org] --allocation # scratch org allocation only (with warnings)
|
|
34
|
+
# devhub.sh [org] --show-settings # read current DevHubSettings preferences
|
|
30
35
|
# devhub.sh [org] --list-scratch # list this Dev Hub's active scratch orgs
|
|
36
|
+
# devhub.sh --list-orgs # list authenticated orgs on this machine
|
|
31
37
|
# devhub.sh [org] --enable # validate enabling Dev Hub (dry run)
|
|
32
38
|
# devhub.sh [org] --enable --apply # actually enable Dev Hub (irreversible)
|
|
33
39
|
# devhub.sh [org] --enable --packaging --apply # enable + turn on 2GP
|
|
34
40
|
# devhub.sh [org] --configure --snapshots --apply # set a sub-pref (Dev Hub already on)
|
|
35
41
|
# devhub.sh [org] --json # machine-readable status
|
|
36
42
|
# devhub.sh --fail-if-disabled # exit 3 if Dev Hub is not enabled (CI gate)
|
|
37
|
-
# devhub.sh [alias] --instance-url https://my-domain.my.salesforce.com --enable --apply
|
|
38
|
-
# # log in to that instance, then enable Dev Hub
|
|
39
|
-
# devhub.sh https://my-domain.my.salesforce.com # bare URL: log in to that instance
|
|
40
|
-
# devhub.sh myalias --login # just authenticate an org via the browser
|
|
41
43
|
#
|
|
42
|
-
# "org" is an alias or username. If omitted, the default target-org is used,
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
# A bare positional that looks like a URL (contains "://") is treated as an
|
|
46
|
-
# --instance-url to log in to, not as an org alias.
|
|
44
|
+
# "org" is an alias or username. If omitted, the default target-org is used, and
|
|
45
|
+
# if that is unset, the default target-dev-hub. If neither is set, the script
|
|
46
|
+
# lists the authenticated orgs and asks you to pass one or set a default.
|
|
47
47
|
#
|
|
48
48
|
# Options:
|
|
49
|
-
# --allocation, -A Show only the scratch org allocation (Active/Daily)
|
|
49
|
+
# --allocation, -A Show only the scratch org allocation (Active/Daily),
|
|
50
|
+
# with a WARN when <2 remain and a NOTE above 80% usage.
|
|
51
|
+
# --show-settings, -s Read and show which DevHubSettings preferences are
|
|
52
|
+
# currently enabled/disabled (Tooling API). Dev Hub must
|
|
53
|
+
# be on.
|
|
50
54
|
# --list-scratch, -l List active scratch orgs created from this Dev Hub.
|
|
55
|
+
# --list-orgs List the orgs authenticated with the Salesforce CLI.
|
|
51
56
|
# --enable, -e Enable Dev Hub (deploys enableScratchOrgManagementPref
|
|
52
57
|
# =true). Defaults to a validate-only dry run; add
|
|
53
58
|
# --apply to actually enable. May be combined with the
|
|
@@ -63,15 +68,14 @@
|
|
|
63
68
|
# "enable"; VALUE is true|false). Repeatable.
|
|
64
69
|
# --apply Actually deploy (default for --enable/--configure is a
|
|
65
70
|
# validate-only dry run).
|
|
66
|
-
# --login Authenticate an org first via `sf org login web`
|
|
67
|
-
# (opens a browser). Runs before the requested action.
|
|
68
|
-
# --instance-url URL Log in to a Salesforce instance (My Domain, sandbox,
|
|
69
|
-
# or pre-release/scratch instance) with
|
|
70
|
-
# `sf org login web --instance-url URL`. Implies --login.
|
|
71
71
|
# --json Emit machine-readable JSON.
|
|
72
72
|
# --fail-if-disabled Exit 3 if Dev Hub is not enabled on the target org.
|
|
73
73
|
# --help, -h Show this help.
|
|
74
74
|
#
|
|
75
|
+
# Authentication is a precondition. If an org is not authenticated, the script
|
|
76
|
+
# prints the exact `sf org login web` command to run — it never opens a browser
|
|
77
|
+
# or logs in for you.
|
|
78
|
+
#
|
|
75
79
|
# Exit codes:
|
|
76
80
|
# 0 success
|
|
77
81
|
# 1 the org could not be queried, or a deploy failed (auth/connection/deploy)
|
|
@@ -98,21 +102,21 @@ command -v jq >/dev/null 2>&1 || die "'jq' not found on PATH."
|
|
|
98
102
|
export SF_AUTOUPDATE_DISABLE=true
|
|
99
103
|
|
|
100
104
|
# --- constants -----------------------------------------------------------
|
|
101
|
-
SETTINGS_API_VERSION="
|
|
105
|
+
SETTINGS_API_VERSION="62.0" # DevHubSettings: base fields >=47.0, but
|
|
106
|
+
# enableShapeExportPref needs >=55.0 and
|
|
107
|
+
# enableScratchOrgSnapshotPref needs >=61.0,
|
|
108
|
+
# so read/deploy at a version that has them all.
|
|
102
109
|
DEVHUB_SWITCH="enableScratchOrgManagementPref"
|
|
103
110
|
|
|
104
111
|
# --- option state --------------------------------------------------------
|
|
105
112
|
TARGET="" # org alias/username (positional or resolved default)
|
|
106
113
|
TARGET_EXPLICIT=0 # 1 when the caller supplied an org alias/username
|
|
107
|
-
MODE="status" # status | allocation | list | deploy
|
|
108
|
-
MODE_EXPLICIT=0 # 1 when the caller selected an operation
|
|
114
|
+
MODE="status" # status | allocation | settings | list | listorgs | deploy
|
|
109
115
|
ENABLING=0 # 1 when --enable was passed (seeds the master switch)
|
|
110
116
|
OUTPUT="human" # human | json
|
|
111
117
|
APPLY=0 # deploy: 0 = dry run (validate only), 1 = real deploy
|
|
112
118
|
FAIL_IF_DISABLED=0
|
|
113
119
|
PREFS=() # requested DevHubSettings prefs (KEY=VALUE)
|
|
114
|
-
DO_LOGIN=0 # 1 when --login or --instance-url requests a browser login
|
|
115
|
-
LOGIN_INSTANCE_URL="" # instance URL for `sf org login web --instance-url`
|
|
116
120
|
|
|
117
121
|
# --- run state -----------------------------------------------------------
|
|
118
122
|
DEVHUB_STATE="" # enabled | disabled | auth_error
|
|
@@ -120,6 +124,9 @@ DEVHUB_ERRNAME="" # error .name when auth_error
|
|
|
120
124
|
DEVHUB_ERRMSG=""
|
|
121
125
|
SCRATCH_COUNT="" # ScratchOrgInfo count when enabled
|
|
122
126
|
INSTANCE_URL="" # resolved org instance URL (for the Setup deep link)
|
|
127
|
+
ORG_EDITION="" # Organization.OrganizationType (best effort)
|
|
128
|
+
ORG_IS_SANDBOX="" # true|false (best effort)
|
|
129
|
+
ORG_FACTS_DONE=0 # 1 once org_facts has run
|
|
123
130
|
|
|
124
131
|
usage() {
|
|
125
132
|
sed -n '2,/^set -uo/p' "$0" | sed '/^set -uo/d; s/^# \{0,1\}//; s/^#//'
|
|
@@ -128,7 +135,7 @@ usage() {
|
|
|
128
135
|
# Set MODE, rejecting a second conflicting mode selection.
|
|
129
136
|
set_mode() {
|
|
130
137
|
if [ "$MODE" != "status" ] && [ "$MODE" != "$1" ]; then
|
|
131
|
-
die "Choose only one of --allocation, --list-scratch, --enable/--configure."
|
|
138
|
+
die "Choose only one of --allocation, --show-settings, --list-scratch, --list-orgs, --enable/--configure."
|
|
132
139
|
fi
|
|
133
140
|
MODE="$1"
|
|
134
141
|
}
|
|
@@ -174,44 +181,31 @@ add_pref() {
|
|
|
174
181
|
# --- argument parsing ----------------------------------------------------
|
|
175
182
|
while [ $# -gt 0 ]; do
|
|
176
183
|
case "$1" in
|
|
177
|
-
--allocation|-A)
|
|
178
|
-
--
|
|
179
|
-
--
|
|
180
|
-
--
|
|
181
|
-
--
|
|
182
|
-
--
|
|
183
|
-
--
|
|
184
|
-
--
|
|
184
|
+
--allocation|-A) set_mode allocation; shift ;;
|
|
185
|
+
--show-settings|-s) set_mode settings; shift ;;
|
|
186
|
+
--list-scratch|-l) set_mode list; shift ;;
|
|
187
|
+
--list-orgs) set_mode listorgs; shift ;;
|
|
188
|
+
--enable|-e) ENABLING=1; set_mode deploy; shift ;;
|
|
189
|
+
--configure|-c) set_mode deploy; shift ;;
|
|
190
|
+
--packaging) add_pref "enablePackaging2=true"; set_mode deploy; shift ;;
|
|
191
|
+
--snapshots) add_pref "enableScratchOrgSnapshotPref=true"; set_mode deploy; shift ;;
|
|
192
|
+
--shape) add_pref "enableShapeExportPref=true"; set_mode deploy; shift ;;
|
|
193
|
+
--scratch-management) add_pref "$DEVHUB_SWITCH=true"; set_mode deploy; shift ;;
|
|
185
194
|
--pref)
|
|
186
195
|
shift
|
|
187
196
|
[ $# -gt 0 ] || die "--pref requires a KEY=VALUE argument (e.g. --pref enablePackaging2=true)."
|
|
188
197
|
case "$1" in *=*) : ;; *) die "--pref expects KEY=VALUE (got: '$1')." ;; esac
|
|
189
|
-
|
|
198
|
+
add_pref "$1"; set_mode deploy; shift ;;
|
|
190
199
|
--pref=*)
|
|
191
200
|
kv="${1#*=}"
|
|
192
201
|
case "$kv" in *=*) : ;; *) die "--pref expects KEY=VALUE (got: '$kv')." ;; esac
|
|
193
|
-
|
|
202
|
+
add_pref "$kv"; set_mode deploy; shift ;;
|
|
194
203
|
--apply) APPLY=1; shift ;;
|
|
195
|
-
--login) DO_LOGIN=1; shift ;;
|
|
196
|
-
--instance-url)
|
|
197
|
-
shift
|
|
198
|
-
[ $# -gt 0 ] || die "--instance-url requires a URL (e.g. --instance-url https://my-domain.my.salesforce.com)."
|
|
199
|
-
[ -n "$LOGIN_INSTANCE_URL" ] && die "Specify only one instance URL. Got extra: $1"
|
|
200
|
-
LOGIN_INSTANCE_URL="$1"; DO_LOGIN=1; shift ;;
|
|
201
|
-
--instance-url=*)
|
|
202
|
-
[ -n "$LOGIN_INSTANCE_URL" ] && die "Specify only one instance URL. Got extra: ${1#*=}"
|
|
203
|
-
LOGIN_INSTANCE_URL="${1#*=}"; DO_LOGIN=1; shift ;;
|
|
204
204
|
--json) OUTPUT="json"; shift ;;
|
|
205
205
|
--fail-if-disabled) FAIL_IF_DISABLED=1; shift ;;
|
|
206
206
|
--help|-h) usage; exit 0 ;;
|
|
207
207
|
--) shift; break ;;
|
|
208
208
|
-*) die "Unknown option: $1 (try --help)" ;;
|
|
209
|
-
*://*)
|
|
210
|
-
# A bare URL positional is an instance URL to log in to (My Domain,
|
|
211
|
-
# sandbox, or pre-release/scratch instance), not an org alias — an alias or
|
|
212
|
-
# username never contains "://". Route it to the login path.
|
|
213
|
-
[ -n "$LOGIN_INSTANCE_URL" ] && die "Specify only one instance URL. Got extra: $1"
|
|
214
|
-
LOGIN_INSTANCE_URL="$1"; DO_LOGIN=1; shift ;;
|
|
215
209
|
*)
|
|
216
210
|
[ -n "$TARGET" ] && die "Specify only one org. Got extra: $1"
|
|
217
211
|
TARGET="$1"; TARGET_EXPLICIT=1; shift ;;
|
|
@@ -235,13 +229,63 @@ if [ "$APPLY" -eq 1 ] && [ "$TARGET_EXPLICIT" -ne 1 ]; then
|
|
|
235
229
|
die "--apply requires an explicit org alias or username; refusing to mutate an implicit default org."
|
|
236
230
|
fi
|
|
237
231
|
|
|
238
|
-
#
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
232
|
+
# Bound one Salesforce CLI call. `sf org list` can wait on a keychain or
|
|
233
|
+
# network prompt longer than the eval harness tool timeout, and the agent
|
|
234
|
+
# then stops before it writes report.md. A parent-side wait is used because
|
|
235
|
+
# an alarm set before exec is not reliable on every platform.
|
|
236
|
+
sf_bounded() {
|
|
237
|
+
local out_file pid i
|
|
238
|
+
out_file="$(mktemp)"
|
|
239
|
+
sf "$@" >"$out_file" 2>/dev/null &
|
|
240
|
+
pid=$!
|
|
241
|
+
i=0
|
|
242
|
+
while [ "$i" -lt 20 ]; do
|
|
243
|
+
if ! kill -0 "$pid" 2>/dev/null; then
|
|
244
|
+
wait "$pid"
|
|
245
|
+
local rc=$?
|
|
246
|
+
cat "$out_file"
|
|
247
|
+
rm -f "$out_file"
|
|
248
|
+
return "$rc"
|
|
249
|
+
fi
|
|
250
|
+
sleep 1
|
|
251
|
+
i=$((i + 1))
|
|
252
|
+
done
|
|
253
|
+
kill "$pid" 2>/dev/null || true
|
|
254
|
+
pkill -P "$pid" 2>/dev/null || true
|
|
255
|
+
wait "$pid" 2>/dev/null || true
|
|
256
|
+
rm -f "$out_file"
|
|
257
|
+
return 142
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
# --- org discovery -------------------------------------------------------
|
|
261
|
+
# List the orgs authenticated with the Salesforce CLI. Handles both the newer
|
|
262
|
+
# {result:{nonScratchOrgs,scratchOrgs}} shape and the older {result:[...]}.
|
|
263
|
+
list_orgs() {
|
|
264
|
+
local out
|
|
265
|
+
out="$(sf_bounded org list --json 2>/dev/null)" || { echo "Could not list authenticated orgs (is the Salesforce CLI installed and working?)." >&2; return 1; }
|
|
266
|
+
local norm
|
|
267
|
+
norm="$(printf '%s' "$out" | jq -c '
|
|
268
|
+
[ ((.result.nonScratchOrgs // []) + (.result.scratchOrgs // []) + (.result.other // []) +
|
|
269
|
+
(if (.result|type)=="array" then .result else [] end))[]
|
|
270
|
+
| {alias:(.alias // null), username:(.username // null),
|
|
271
|
+
connectedStatus:(.connectedStatus // .status // null),
|
|
272
|
+
isDefault:((.isDefaultUsername // .isDefault) // false)} ]' 2>/dev/null)"
|
|
273
|
+
if [ "$OUTPUT" = "json" ]; then
|
|
274
|
+
printf '%s\n' "${norm:-[]}"
|
|
275
|
+
return 0
|
|
276
|
+
fi
|
|
277
|
+
local n
|
|
278
|
+
n="$(printf '%s' "${norm:-[]}" | jq 'length' 2>/dev/null)"
|
|
279
|
+
if [ -z "$n" ] || [ "$n" = "0" ]; then
|
|
280
|
+
echo "No orgs are authenticated with the Salesforce CLI."
|
|
281
|
+
echo " Log in with: sf org login web --alias <my-alias>"
|
|
282
|
+
return 0
|
|
283
|
+
fi
|
|
284
|
+
echo "Authenticated orgs:"
|
|
285
|
+
printf '%s' "$norm" | jq -r '.[]
|
|
286
|
+
| " \(.alias // .username // "?")\t\(.username // "?")\t\(.connectedStatus // "?")\(if .isDefault then " (default)" else "" end)"' \
|
|
287
|
+
| while IFS=$'\t' read -r a u s; do printf " %-24s %-32s %s\n" "$a" "$u" "$s"; done
|
|
288
|
+
}
|
|
245
289
|
|
|
246
290
|
# --- org resolution ------------------------------------------------------
|
|
247
291
|
resolve_target() {
|
|
@@ -252,56 +296,16 @@ resolve_target() {
|
|
|
252
296
|
[ -n "$TARGET" ] && return 0
|
|
253
297
|
echo "No org specified and no default target-org / target-dev-hub is set." >&2
|
|
254
298
|
echo >&2
|
|
299
|
+
if [ "$OUTPUT" != "json" ]; then
|
|
300
|
+
list_orgs >&2 || true
|
|
301
|
+
echo >&2
|
|
302
|
+
fi
|
|
255
303
|
echo "Pass an org alias/username, or set a default:" >&2
|
|
256
304
|
echo " sf org login web --alias <my-alias> # authenticate an org" >&2
|
|
257
305
|
echo " sf config set target-org <my-alias> # make it the default" >&2
|
|
258
306
|
exit 2
|
|
259
307
|
}
|
|
260
308
|
|
|
261
|
-
# --- interactive login ---------------------------------------------------
|
|
262
|
-
# Authenticate an org with `sf org login web`, honoring an optional
|
|
263
|
-
# --instance-url (My Domain, sandbox, or pre-release/scratch instance) and, when
|
|
264
|
-
# an org identifier was supplied, using it as the CLI alias. Opens a browser for
|
|
265
|
-
# the OAuth flow; returns non-zero if the login fails or times out.
|
|
266
|
-
do_login() {
|
|
267
|
-
local args=(org login web)
|
|
268
|
-
[ -n "$LOGIN_INSTANCE_URL" ] && args+=(--instance-url "$LOGIN_INSTANCE_URL")
|
|
269
|
-
[ -n "$TARGET" ] && args+=(--alias "$TARGET")
|
|
270
|
-
|
|
271
|
-
if [ "$OUTPUT" != "json" ]; then
|
|
272
|
-
echo "Authenticating with the Salesforce CLI (a browser window will open)..."
|
|
273
|
-
[ -n "$LOGIN_INSTANCE_URL" ] && echo " instance URL: $LOGIN_INSTANCE_URL"
|
|
274
|
-
[ -n "$TARGET" ] && echo " alias: $TARGET"
|
|
275
|
-
echo " Complete the login in the browser promptly (the session times out)."
|
|
276
|
-
echo
|
|
277
|
-
fi
|
|
278
|
-
|
|
279
|
-
local out ok
|
|
280
|
-
out="$(sf "${args[@]}" --json 2>/dev/null)"
|
|
281
|
-
ok="$(printf '%s' "$out" | jq -r 'if .status==0 then "true" else "false" end' 2>/dev/null)"
|
|
282
|
-
|
|
283
|
-
if [ "$ok" != "true" ]; then
|
|
284
|
-
local msg
|
|
285
|
-
msg="$(printf '%s' "$out" | jq -r '.message // empty' 2>/dev/null)"
|
|
286
|
-
if [ "$OUTPUT" = "json" ]; then
|
|
287
|
-
jq -n --arg msg "${msg:-login failed}" '{status:"login_failed", error:$msg}'
|
|
288
|
-
else
|
|
289
|
-
echo "Login failed: ${msg:-unknown error}." >&2
|
|
290
|
-
echo " Retry in your own terminal, or use the device flow if the browser flow keeps timing out:" >&2
|
|
291
|
-
echo " sf org login device${LOGIN_INSTANCE_URL:+ --instance-url $(shell_quote "$LOGIN_INSTANCE_URL")}${TARGET:+ --alias $(shell_quote "$TARGET")}" >&2
|
|
292
|
-
fi
|
|
293
|
-
return 1
|
|
294
|
-
fi
|
|
295
|
-
|
|
296
|
-
# Adopt the authenticated username as the target when none was supplied, so the
|
|
297
|
-
# rest of the run operates on the org the user just logged in to.
|
|
298
|
-
if [ -z "$TARGET" ]; then
|
|
299
|
-
TARGET="$(printf '%s' "$out" | jq -r '.result.username // empty' 2>/dev/null)"
|
|
300
|
-
fi
|
|
301
|
-
[ "$OUTPUT" != "json" ] && echo "Authenticated: ${TARGET:-(org)}" && echo
|
|
302
|
-
return 0
|
|
303
|
-
}
|
|
304
|
-
|
|
305
309
|
# Render one dynamic value as a safe, copy-pasteable shell argument.
|
|
306
310
|
shell_quote() {
|
|
307
311
|
printf "'%s'" "$(printf '%s' "$1" | sed "s/'/'\\\\''/g")"
|
|
@@ -332,6 +336,61 @@ detect_devhub() {
|
|
|
332
336
|
esac
|
|
333
337
|
}
|
|
334
338
|
|
|
339
|
+
# --- org facts (edition / sandbox) ---------------------------------------
|
|
340
|
+
# Best effort: populate ORG_EDITION, ORG_IS_SANDBOX. Never aborts.
|
|
341
|
+
org_facts() {
|
|
342
|
+
[ "$ORG_FACTS_DONE" -eq 1 ] && return 0
|
|
343
|
+
ORG_FACTS_DONE=1
|
|
344
|
+
local out
|
|
345
|
+
out="$(sf data query --query "SELECT OrganizationType, IsSandbox FROM Organization" \
|
|
346
|
+
--target-org "$TARGET" --json 2>/dev/null)" || return 0
|
|
347
|
+
ORG_EDITION="$(printf '%s' "$out" | jq -r '.result.records[0].OrganizationType // empty' 2>/dev/null)"
|
|
348
|
+
# Use an explicit null-check rather than `// empty`: IsSandbox is a boolean, and
|
|
349
|
+
# `false // empty` would drop a legitimate `false`, reporting a non-sandbox org
|
|
350
|
+
# as "unknown" (isSandbox:null) instead of false.
|
|
351
|
+
ORG_IS_SANDBOX="$(printf '%s' "$out" | jq -r '(.result.records[0].IsSandbox) as $s | if $s==null then empty else ($s|tostring) end' 2>/dev/null)"
|
|
352
|
+
return 0
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
# --- DevHubSettings preferences read -------------------------------------
|
|
356
|
+
# Reads the current DevHubSettings via the Tooling API and echoes TSV rows
|
|
357
|
+
# "key<TAB>true|false" for each enable* preference. Returns non-zero on failure.
|
|
358
|
+
read_devhub_settings() {
|
|
359
|
+
local out
|
|
360
|
+
out="$(sf api request rest "/services/data/v${SETTINGS_API_VERSION}/tooling/sobjects/DevHubSettings/DevHub" \
|
|
361
|
+
--target-org "$TARGET" --json 2>/dev/null)" || return 1
|
|
362
|
+
# `sf api request rest --json` returns the raw REST body; be robust to a
|
|
363
|
+
# possible {result:{...}} wrapper too.
|
|
364
|
+
printf '%s' "$out" | jq -r '
|
|
365
|
+
(.Metadata // .result.Metadata // {})
|
|
366
|
+
| to_entries[]? | select(.key|startswith("enable"))
|
|
367
|
+
| [.key, (.value|tostring)] | @tsv' 2>/dev/null
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
render_settings() {
|
|
371
|
+
local rows
|
|
372
|
+
rows="$(read_devhub_settings)"
|
|
373
|
+
if [ -z "$rows" ]; then
|
|
374
|
+
if [ "$OUTPUT" = "json" ]; then
|
|
375
|
+
jq -n --arg org "$TARGET" '{org:$org, settings:{}, note:"Could not read DevHubSettings (Dev Hub may be off, or you lack access)."}'
|
|
376
|
+
else
|
|
377
|
+
echo "Could not read DevHubSettings for '$TARGET' — Dev Hub may be off, or you may lack access." >&2
|
|
378
|
+
fi
|
|
379
|
+
return 1
|
|
380
|
+
fi
|
|
381
|
+
if [ "$OUTPUT" = "json" ]; then
|
|
382
|
+
printf '%s\n' "$rows" | jq -R -s --arg org "$TARGET" '
|
|
383
|
+
{org:$org,
|
|
384
|
+
settings:( [ split("\n")[] | select(length>0) | split("\t") | {(.[0]): (.[1]=="true")} ] | add // {} )}'
|
|
385
|
+
return 0
|
|
386
|
+
fi
|
|
387
|
+
echo "DevHub preferences for '$TARGET':"
|
|
388
|
+
printf '%s\n' "$rows" | while IFS=$'\t' read -r k v; do
|
|
389
|
+
[ -n "$k" ] || continue
|
|
390
|
+
if [ "$v" = "true" ]; then printf " %-34s ON\n" "$k"; else printf " %-34s OFF\n" "$k"; fi
|
|
391
|
+
done
|
|
392
|
+
}
|
|
393
|
+
|
|
335
394
|
# Echoes TSV rows "name<TAB>remaining<TAB>max" for the two scratch org limits,
|
|
336
395
|
# or nothing if the org could not be queried.
|
|
337
396
|
allocation_rows() {
|
|
@@ -343,6 +402,13 @@ allocation_rows() {
|
|
|
343
402
|
| [.name, (.remaining|tostring), (.max|tostring)] | @tsv'
|
|
344
403
|
}
|
|
345
404
|
|
|
405
|
+
# Integer percentage used = (max-rem)*100/max, or empty when max is empty/0.
|
|
406
|
+
pct_used() {
|
|
407
|
+
local max="$1" rem="$2"
|
|
408
|
+
{ [ -n "$max" ] && [ "$max" -gt 0 ] 2>/dev/null; } || { echo ""; return; }
|
|
409
|
+
echo $(( (max - rem) * 100 / max ))
|
|
410
|
+
}
|
|
411
|
+
|
|
346
412
|
# Resolve the org instance URL for the Setup deep link (best effort).
|
|
347
413
|
resolve_instance_url() {
|
|
348
414
|
[ -n "$INSTANCE_URL" ] && return 0
|
|
@@ -351,6 +417,7 @@ resolve_instance_url() {
|
|
|
351
417
|
}
|
|
352
418
|
|
|
353
419
|
# --- auth error reporting ------------------------------------------------
|
|
420
|
+
# Guidance only: print the exact login command to run. Never logs in.
|
|
354
421
|
print_auth_error() {
|
|
355
422
|
if [ "$OUTPUT" = "json" ]; then
|
|
356
423
|
jq -n --arg org "$TARGET" --arg name "$DEVHUB_ERRNAME" --arg msg "$DEVHUB_ERRMSG" \
|
|
@@ -360,22 +427,11 @@ print_auth_error() {
|
|
|
360
427
|
printf " %-30s could not query org (%s)\n" "$TARGET" "${DEVHUB_ERRNAME:-error}"
|
|
361
428
|
[ -n "$DEVHUB_ERRMSG" ] && printf " %-30s (%s)\n" "" "$DEVHUB_ERRMSG"
|
|
362
429
|
echo
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
echo " Or let this script log you in and continue in one step:"
|
|
369
|
-
echo " devhub.sh ${TARGET:+$(shell_quote "$TARGET") }--instance-url $(shell_quote "$LOGIN_INSTANCE_URL") --login"
|
|
370
|
-
else
|
|
371
|
-
echo " To authenticate, run one of:"
|
|
372
|
-
echo " sf org login web --alias $(shell_quote "$TARGET") # interactive browser login"
|
|
373
|
-
echo " sf org login web --alias <my-alias> --instance-url https://MYDOMAIN.my.salesforce.com # sandbox/My Domain"
|
|
374
|
-
echo " Or let this script log you in and continue in one step:"
|
|
375
|
-
echo " devhub.sh $(shell_quote "$TARGET") --login # prod/DE/trial"
|
|
376
|
-
echo " devhub.sh <my-alias> --instance-url https://MYDOMAIN.my.salesforce.com --login # sandbox/My Domain"
|
|
377
|
-
fi
|
|
378
|
-
echo " Then re-run. List existing logins with: sf org list"
|
|
430
|
+
echo " This org is not authenticated (or the session expired). Authentication is"
|
|
431
|
+
echo " a precondition for this skill — run one of these yourself, then re-run:"
|
|
432
|
+
echo " sf org login web --alias $(shell_quote "$TARGET") # prod / DE / trial"
|
|
433
|
+
echo " sf org login web --alias <my-alias> --instance-url https://MYDOMAIN.my.salesforce.com # sandbox / My Domain"
|
|
434
|
+
echo " List existing logins with: sf org list"
|
|
379
435
|
}
|
|
380
436
|
|
|
381
437
|
# --- Setup UI fallback text ----------------------------------------------
|
|
@@ -391,22 +447,36 @@ print_ui_fallback() {
|
|
|
391
447
|
|
|
392
448
|
# --- allocation rendering ------------------------------------------------
|
|
393
449
|
render_allocation() {
|
|
394
|
-
local rows a_max a_rem d_max d_rem
|
|
450
|
+
local rows a_max a_rem d_max d_rem a_pct d_pct
|
|
395
451
|
rows="$(allocation_rows)" || { echo "Could not read org limits for '$TARGET'." >&2; return 1; }
|
|
396
452
|
a_rem="$(printf '%s\n' "$rows" | awk -F'\t' '$1=="ActiveScratchOrgs"{print $2}')"
|
|
397
453
|
a_max="$(printf '%s\n' "$rows" | awk -F'\t' '$1=="ActiveScratchOrgs"{print $3}')"
|
|
398
454
|
d_rem="$(printf '%s\n' "$rows" | awk -F'\t' '$1=="DailyScratchOrgs"{print $2}')"
|
|
399
455
|
d_max="$(printf '%s\n' "$rows" | awk -F'\t' '$1=="DailyScratchOrgs"{print $3}')"
|
|
456
|
+
a_pct="$(pct_used "$a_max" "$a_rem")"
|
|
457
|
+
d_pct="$(pct_used "$d_max" "$d_rem")"
|
|
400
458
|
|
|
401
459
|
if [ "$OUTPUT" = "json" ]; then
|
|
460
|
+
local warns=()
|
|
461
|
+
if [ -n "$a_max" ] && [ "$a_max" -gt 0 ] 2>/dev/null && [ "$a_rem" -lt 2 ] 2>/dev/null; then
|
|
462
|
+
warns+=("only $a_rem active scratch org(s) remaining")
|
|
463
|
+
fi
|
|
464
|
+
{ [ -n "$a_pct" ] && [ "$a_pct" -gt 80 ] 2>/dev/null; } && warns+=("Active scratch org usage at ${a_pct}%")
|
|
465
|
+
{ [ -n "$d_pct" ] && [ "$d_pct" -gt 80 ] 2>/dev/null; } && warns+=("Daily scratch org usage at ${d_pct}%")
|
|
466
|
+
local warn_json="[]"
|
|
467
|
+
if [ "${#warns[@]}" -gt 0 ]; then
|
|
468
|
+
warn_json="$(printf '%s\n' "${warns[@]}" | jq -R . | jq -s .)"
|
|
469
|
+
fi
|
|
402
470
|
jq -n --arg org "$TARGET" \
|
|
403
|
-
--argjson am "${a_max:-null}" --argjson ar "${a_rem:-null}" \
|
|
404
|
-
--argjson dm "${d_max:-null}" --argjson dr "${d_rem:-null}"
|
|
471
|
+
--argjson am "${a_max:-null}" --argjson ar "${a_rem:-null}" --argjson ap "${a_pct:-null}" \
|
|
472
|
+
--argjson dm "${d_max:-null}" --argjson dr "${d_rem:-null}" --argjson dp "${d_pct:-null}" \
|
|
473
|
+
--argjson warnings "$warn_json" '
|
|
405
474
|
{org:$org,
|
|
406
475
|
allocation:{
|
|
407
|
-
activeScratchOrgs:{max:$am, remaining:$ar, used:(if $am!=null and $ar!=null then ($am-$ar) else null end)},
|
|
408
|
-
dailyScratchOrgs:{max:$dm, remaining:$dr, used:(if $dm!=null and $dr!=null then ($dm-$dr) else null end)}
|
|
409
|
-
}
|
|
476
|
+
activeScratchOrgs:{max:$am, remaining:$ar, used:(if $am!=null and $ar!=null then ($am-$ar) else null end), usedPct:$ap},
|
|
477
|
+
dailyScratchOrgs:{max:$dm, remaining:$dr, used:(if $dm!=null and $dr!=null then ($dm-$dr) else null end), usedPct:$dp}
|
|
478
|
+
},
|
|
479
|
+
warnings:$warnings}'
|
|
410
480
|
return 0
|
|
411
481
|
fi
|
|
412
482
|
|
|
@@ -418,6 +488,12 @@ render_allocation() {
|
|
|
418
488
|
printf " %-22s %10s %10s %10s\n" "Limit" "Used" "Remaining" "Max"
|
|
419
489
|
[ -n "$a_max" ] && printf " %-22s %10s %10s %10s\n" "Active scratch orgs" "$(( a_max - a_rem ))" "$a_rem" "$a_max"
|
|
420
490
|
[ -n "$d_max" ] && printf " %-22s %10s %10s %10s\n" "Daily scratch orgs" "$(( d_max - d_rem ))" "$d_rem" "$d_max"
|
|
491
|
+
# Pre-flight warnings.
|
|
492
|
+
if [ -n "$a_max" ] && [ "$a_max" -gt 0 ] 2>/dev/null && [ "$a_rem" -lt 2 ] 2>/dev/null; then
|
|
493
|
+
echo " WARN: only $a_rem active scratch org(s) remaining."
|
|
494
|
+
fi
|
|
495
|
+
{ [ -n "$a_pct" ] && [ "$a_pct" -gt 80 ] 2>/dev/null; } && echo " NOTE: Active scratch org usage at ${a_pct}% ($(( a_max - a_rem ))/$a_max)."
|
|
496
|
+
{ [ -n "$d_pct" ] && [ "$d_pct" -gt 80 ] 2>/dev/null; } && echo " NOTE: Daily scratch org usage at ${d_pct}% ($(( d_max - d_rem ))/$d_max)."
|
|
421
497
|
echo
|
|
422
498
|
echo " Active = orgs alive right now; Daily = successful creations in a rolling 24h window."
|
|
423
499
|
echo " Allocation is set by the Dev Hub's edition (e.g. Developer/trial 3 & 6;"
|
|
@@ -459,6 +535,23 @@ cleanup_deploy_temp() {
|
|
|
459
535
|
}
|
|
460
536
|
|
|
461
537
|
render_deploy() {
|
|
538
|
+
# Enabling Dev Hub cannot happen on a sandbox. When actually applying an
|
|
539
|
+
# enablement, verify eligibility first and refuse before touching the org.
|
|
540
|
+
if [ "$ENABLING" -eq 1 ] && [ "$APPLY" -eq 1 ]; then
|
|
541
|
+
org_facts
|
|
542
|
+
if [ "$ORG_IS_SANDBOX" = "true" ]; then
|
|
543
|
+
if [ "$OUTPUT" = "json" ]; then
|
|
544
|
+
jq -n --arg org "$TARGET" '{applied:false, enabling:true, success:false, message:"Refused: Dev Hub cannot be enabled on a sandbox. Use a production, Developer Edition, or trial org."}'
|
|
545
|
+
else
|
|
546
|
+
echo "Refused — '$TARGET' is a sandbox, and Dev Hub cannot be enabled on a sandbox."
|
|
547
|
+
echo " Dev Hub must be a production/business org (or a Developer Edition / trial org)."
|
|
548
|
+
echo
|
|
549
|
+
print_ui_fallback
|
|
550
|
+
fi
|
|
551
|
+
return 1
|
|
552
|
+
fi
|
|
553
|
+
fi
|
|
554
|
+
|
|
462
555
|
# Sub-prefs (packaging, snapshots, shape) require Dev Hub to be on. If the
|
|
463
556
|
# user is configuring one without also enabling, and Dev Hub is off, warn.
|
|
464
557
|
if [ "$ENABLING" -eq 0 ] && [ "$DEVHUB_STATE" = "disabled" ] && [ "$OUTPUT" != "json" ]; then
|
|
@@ -572,13 +665,17 @@ render_status() {
|
|
|
572
665
|
a_max="$(printf '%s\n' "$rows" | awk -F'\t' '$1=="ActiveScratchOrgs"{print $3}')"
|
|
573
666
|
d_rem="$(printf '%s\n' "$rows" | awk -F'\t' '$1=="DailyScratchOrgs"{print $2}')"
|
|
574
667
|
d_max="$(printf '%s\n' "$rows" | awk -F'\t' '$1=="DailyScratchOrgs"{print $3}')"
|
|
668
|
+
org_facts
|
|
575
669
|
jq -n --arg org "$TARGET" --arg state "$DEVHUB_STATE" \
|
|
576
670
|
--argjson count "${SCRATCH_COUNT:-null}" \
|
|
671
|
+
--arg edition "${ORG_EDITION}" --arg sandbox "${ORG_IS_SANDBOX}" \
|
|
577
672
|
--argjson am "${a_max:-null}" --argjson ar "${a_rem:-null}" \
|
|
578
673
|
--argjson dm "${d_max:-null}" --argjson dr "${d_rem:-null}" '
|
|
579
674
|
{org:$org,
|
|
580
675
|
devHubEnabled:($state=="enabled"),
|
|
581
676
|
status:$state,
|
|
677
|
+
edition:(if $edition=="" then null else $edition end),
|
|
678
|
+
isSandbox:(if $sandbox=="" then null else ($sandbox=="true") end),
|
|
582
679
|
activeScratchOrgSignups:$count,
|
|
583
680
|
allocation:{
|
|
584
681
|
activeScratchOrgs:{max:$am, remaining:$ar},
|
|
@@ -587,42 +684,56 @@ render_status() {
|
|
|
587
684
|
return 0
|
|
588
685
|
fi
|
|
589
686
|
|
|
687
|
+
org_facts
|
|
590
688
|
echo "Dev Hub status for '$TARGET':"
|
|
591
689
|
if [ "$DEVHUB_STATE" = "enabled" ]; then
|
|
592
690
|
echo " Dev Hub: ENABLED (ScratchOrgInfo is queryable)"
|
|
691
|
+
echo " Detection: ScratchOrgInfo is queryable only when Dev Hub is on. A successful count means ENABLED. An INVALID_TYPE error means NOT ENABLED. Scratch org limits are not used as the enablement check."
|
|
692
|
+
[ -n "$ORG_EDITION" ] && echo " Edition: $ORG_EDITION"
|
|
693
|
+
[ "$ORG_IS_SANDBOX" = "true" ] && echo " (Sandbox org)"
|
|
593
694
|
[ -n "$SCRATCH_COUNT" ] && echo " Scratch org signup records: $SCRATCH_COUNT"
|
|
695
|
+
# Best-effort current-preference summary; never let it break status.
|
|
696
|
+
local prefs
|
|
697
|
+
prefs="$(read_devhub_settings 2>/dev/null | awk -F'\t' '$2=="true"{printf "%s ", $1}')"
|
|
698
|
+
[ -n "$prefs" ] && echo " Enabled preferences: $prefs"
|
|
594
699
|
echo
|
|
595
700
|
render_allocation
|
|
596
701
|
else
|
|
597
702
|
echo " Dev Hub: NOT ENABLED"
|
|
703
|
+
echo " Detection: ScratchOrgInfo is queryable only when Dev Hub is on. A successful count means ENABLED. An INVALID_TYPE error means NOT ENABLED. Scratch org limits are not used, because they are reported even when Dev Hub is off."
|
|
704
|
+
[ -n "$ORG_EDITION" ] && echo " Edition: $ORG_EDITION"
|
|
705
|
+
[ "$ORG_IS_SANDBOX" = "true" ] && echo " (Sandbox org — cannot host Dev Hub)"
|
|
598
706
|
echo
|
|
599
|
-
echo "
|
|
600
|
-
echo " devhub.sh \"$TARGET\" --enable # validate first (dry run)"
|
|
601
|
-
echo " devhub.sh \"$TARGET\" --enable --apply # actually enable"
|
|
602
|
-
echo " Requires ModifyAllData or ModifyMetadata (System Administrator);"
|
|
603
|
-
echo " not allowed in a sandbox or an org with a registered namespace."
|
|
707
|
+
echo " Scratch org allocation, Dev Hub preferences, and the scratch org list are not available until Dev Hub is enabled. An empty allocation or a failed exit from those modes means Dev Hub is off, not that the org is unauthenticated."
|
|
604
708
|
echo
|
|
709
|
+
if [ "$ORG_IS_SANDBOX" = "true" ]; then
|
|
710
|
+
echo " This is a sandbox — Dev Hub cannot be enabled here. Use a production,"
|
|
711
|
+
echo " Developer Edition, or trial org instead."
|
|
712
|
+
echo
|
|
713
|
+
else
|
|
714
|
+
echo " Enable it (deploys $DEVHUB_SWITCH=true; irreversible):"
|
|
715
|
+
echo " devhub.sh \"$TARGET\" --enable # validate first (dry run)"
|
|
716
|
+
echo " devhub.sh \"$TARGET\" --enable --apply # actually enable"
|
|
717
|
+
echo " Requires ModifyAllData or ModifyMetadata (System Administrator);"
|
|
718
|
+
echo " not allowed in a sandbox or an org with a registered namespace."
|
|
719
|
+
echo
|
|
720
|
+
fi
|
|
605
721
|
print_ui_fallback
|
|
606
722
|
fi
|
|
607
723
|
}
|
|
608
724
|
|
|
609
725
|
# --- dispatch ------------------------------------------------------------
|
|
610
|
-
#
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
if [ "$DO_LOGIN" -eq 1 ]; then
|
|
614
|
-
do_login || exit 1
|
|
615
|
-
if [ "$MODE_EXPLICIT" -eq 0 ] && [ "$FAIL_IF_DISABLED" -eq 0 ]; then
|
|
616
|
-
exit 0
|
|
617
|
-
fi
|
|
726
|
+
# --list-orgs needs no target and no auth check — handle it first.
|
|
727
|
+
if [ "$MODE" = "listorgs" ]; then
|
|
728
|
+
list_orgs; exit $?
|
|
618
729
|
fi
|
|
619
730
|
|
|
620
731
|
resolve_target
|
|
621
732
|
|
|
622
|
-
# status/deploy need the enablement state; allocation and list query
|
|
623
|
-
# directly and surface their own errors.
|
|
733
|
+
# status/deploy/settings need the enablement state; allocation and list query
|
|
734
|
+
# the org directly and surface their own errors.
|
|
624
735
|
case "$MODE" in
|
|
625
|
-
status|deploy)
|
|
736
|
+
status|deploy|settings)
|
|
626
737
|
if ! detect_devhub && [ "$DEVHUB_STATE" = "auth_error" ]; then
|
|
627
738
|
print_auth_error
|
|
628
739
|
exit 1
|
|
@@ -630,10 +741,24 @@ case "$MODE" in
|
|
|
630
741
|
;;
|
|
631
742
|
esac
|
|
632
743
|
|
|
744
|
+
# --show-settings requires Dev Hub to be on.
|
|
745
|
+
if [ "$MODE" = "settings" ] && [ "$DEVHUB_STATE" != "enabled" ]; then
|
|
746
|
+
if [ "$OUTPUT" = "json" ]; then
|
|
747
|
+
jq -n --arg org "$TARGET" '{org:$org, settings:{}, note:"Dev Hub is not enabled; there are no DevHubSettings to read."}'
|
|
748
|
+
else
|
|
749
|
+
echo "Dev Hub is not enabled on '$TARGET' — there are no DevHubSettings to read." >&2
|
|
750
|
+
echo " Packaging (enablePackaging2), org shape export (enableShapeExportPref), and scratch org snapshots (enableScratchOrgSnapshotPref) cannot be read until Dev Hub is enabled. Do not guess ON or OFF." >&2
|
|
751
|
+
echo " Validate with a dry run first. Enabling is irreversible and needs a System Administrator (ModifyAllData or ModifyMetadata)." >&2
|
|
752
|
+
echo " Enable it first with: devhub.sh \"$TARGET\" --enable --apply" >&2
|
|
753
|
+
fi
|
|
754
|
+
exit 1
|
|
755
|
+
fi
|
|
756
|
+
|
|
633
757
|
rc=0
|
|
634
758
|
case "$MODE" in
|
|
635
759
|
status) render_status || rc=1 ;;
|
|
636
760
|
allocation) render_allocation || rc=1 ;;
|
|
761
|
+
settings) render_settings || rc=1 ;;
|
|
637
762
|
list) render_list || rc=1 ;;
|
|
638
763
|
deploy) render_deploy || rc=1 ;;
|
|
639
764
|
esac
|