@salesforce/afv-skills 1.59.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.
- package/package.json +1 -1
- package/skills/agentforce-architecture-analyze/SKILL.md +66 -17
- package/skills/agentforce-architecture-analyze/assets/cli/show_access_token.yaml +4 -7
- package/skills/agentforce-architecture-analyze/references/contract.json +1 -1
- package/skills/agentforce-architecture-analyze/scripts/emit_env.py +2 -2
- package/skills/agentforce-architecture-analyze/scripts/main.py +40 -44
- package/skills/agentforce-architecture-analyze/scripts/rest_client.py +11 -3
- package/skills/agentforce-architecture-analyze/scripts/sf_cli.py +77 -10
- package/skills/agentforce-architecture-analyze/scripts/tests/test_end_to_end_fixture.py +1 -0
- package/skills/agentforce-architecture-analyze/scripts/tests/test_flow_children_inflation.py +1 -0
- package/skills/agentforce-architecture-analyze/scripts/tests/test_main_pipeline.py +53 -2
- package/skills/agentforce-architecture-analyze/scripts/tests/test_resolve_creds.py +184 -36
- package/skills/agentforce-architecture-analyze/scripts/tests/test_rest_client.py +17 -0
- package/skills/agentforce-architecture-analyze/scripts/tests/test_sf_cli.py +165 -11
- package/skills/agentforce-architecture-analyze/scripts/tests/test_skill_md_pipeline_block.py +319 -0
- package/skills/agentforce-d360-analyze/SKILL.md +28 -10
- package/skills/agentforce-d360-analyze/scripts/dc.py +200 -50
- package/skills/agentforce-d360-analyze/scripts/discover_sessions.py +10 -6
- package/skills/agentforce-d360-analyze/scripts/fetch_dc.py +22 -6
- package/skills/agentforce-d360-analyze/scripts/resolve_session.py +21 -13
- package/skills/agentforce-d360-analyze/scripts/tests/test_dc_and_resolve_session.py +298 -76
- package/skills/agentforce-d360-analyze/scripts/tests/test_default_target_org.py +432 -0
- package/skills/agentforce-d360-analyze/scripts/tests/test_discover_sessions.py +1 -1
- package/skills/agentforce-d360-analyze/scripts/tests/test_resolve_session_main.py +9 -3
- package/skills/agentforce-d360-analyze/scripts/tests/test_skill_md_prefix_block.py +176 -0
- package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +17 -27
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +7 -17
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +47 -63
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +10 -13
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -46
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +4 -21
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +58 -82
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +16 -315
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +9 -24
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -44
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +11 -63
- package/skills/consumer-goods-rtr-datacloud-export-configure/SKILL.md +2 -1
- package/skills/consumer-goods-tpe-dashboard-configure/SKILL.md +2 -1
- package/skills/consumer-goods-tpe-dashboard-custom-kpi-configure/SKILL.md +2 -1
- package/skills/consumer-goods-tpe-datakit-deploy/SKILL.md +2 -1
- package/skills/data360-schema-get/SKILL.md +3 -3
- package/skills/design-systems-slds-validate/references/report-format.md +1 -1
- package/skills/dx-org-manage/SKILL.md +1 -0
- package/skills/dx-org-shape-manage/SKILL.md +1 -0
- package/skills/dx-org-snapshot-manage/SKILL.md +172 -0
- package/skills/dx-org-snapshot-manage/examples/create_error_output.json +16 -0
- package/skills/dx-org-snapshot-manage/examples/create_success_output.json +19 -0
- package/skills/dx-org-snapshot-manage/examples/delete_output.json +9 -0
- package/skills/dx-org-snapshot-manage/examples/get_output.json +19 -0
- package/skills/dx-org-snapshot-manage/examples/list_output.json +36 -0
- package/skills/dx-org-snapshot-manage/references/cli_flags.md +179 -0
- package/skills/dx-org-snapshot-manage/references/snapshot_usage.md +55 -0
- package/skills/dx-org-trial-expiration-check/SKILL.md +1 -1
- package/skills/dx-org-trial-expiration-check/scripts/check_expiration.sh +2 -2
- package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +7 -5
- package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +11 -11
- package/skills/experience-content-media-image-generate/SKILL.md +83 -0
- package/skills/experience-content-media-image-generate/scripts/download-image.sh +84 -0
- package/skills/external-diagram-mermaid-generate/SKILL.md +12 -12
- package/skills/field-service-data-capture-migrate/references/component-mapping.md +1 -1
- package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +1 -2
- package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +1 -0
- package/skills/field-service-data-capture-migrate/references/transformer-rules.md +1 -1
- package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +12 -1
- package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +4 -1
- package/skills/field-service-setup-orchestrator-get/SKILL.md +0 -1
- package/skills/insurance-brokerage-agency-billing-configure/SKILL.md +233 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/accounting-setup.md +117 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/billing-rules-config.md +237 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/billing-settings.md +271 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/demo-policy-config.md +138 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/org-defaults.md +64 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/permissions-config.md +226 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/prerequisites.md +142 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +3 -2
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +3 -3
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +68 -45
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +17 -18
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +16 -3
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +16 -13
- package/skills/marketing-message-test/SKILL.md +194 -0
- package/skills/marketing-message-test/references/api-contract.md +333 -0
- package/skills/omnistudio-callable-apex-generate/SKILL.md +3 -3
- package/skills/omnistudio-datamapper-generate/SKILL.md +6 -6
- package/skills/omnistudio-datapacks-deploy/SKILL.md +11 -11
- package/skills/omnistudio-dependencies-analyze/SKILL.md +5 -5
- package/skills/omnistudio-epc-catalog-generate/SKILL.md +6 -6
- package/skills/omnistudio-flexcard-generate/SKILL.md +6 -6
- package/skills/omnistudio-integration-procedure-generate/SKILL.md +6 -6
- package/skills/omnistudio-omniscript-generate/SKILL.md +6 -5
- package/skills/platform-apex-logs-debug/SKILL.md +1 -0
- package/skills/platform-metadata-deploy/SKILL.md +1 -0
- package/skills/platform-models-api-configure/SKILL.md +5 -5
- package/skills/platform-soql-query/SKILL.md +1 -0
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +17 -6
- package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +107 -192
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone-action.json +6 -6
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +49 -20
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +4 -4
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +224 -290
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/workflow.md +295 -0
- package/skills/service-itsm-incident-priority-configure/SKILL.md +1 -1
- package/skills/service-itsm-slack-itservice-configure/SKILL.md +2 -1
- package/skills/service-itsm-slack-itservice-configure/references/manage-slack-connection.md +2 -2
- package/skills/service-omni-channel-setup-coordinate/SKILL.md +20 -13
- package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +5 -55
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +0 -38
- package/skills/service-omni-command-center-analyze/SKILL.md +2 -3
- package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
- package/skills/tableau-next-asset-create/README.md +65 -0
- package/skills/tableau-next-asset-create/SKILL.md +409 -0
- package/skills/tableau-next-asset-create/references/admin-users.md +149 -0
- package/skills/tableau-next-asset-create/references/ai-readiness.md +355 -0
- package/skills/tableau-next-asset-create/references/alerts.md +111 -0
- package/skills/tableau-next-asset-create/references/build-workflow.md +819 -0
- package/skills/tableau-next-asset-create/references/dashboard-authoring.md +302 -0
- package/skills/tableau-next-asset-create/references/dashboard-design-principles.md +352 -0
- package/skills/tableau-next-asset-create/references/data-transform-gotchas.md +210 -0
- package/skills/tableau-next-asset-create/references/data-understanding.md +387 -0
- package/skills/tableau-next-asset-create/references/deep-reference-index.md +74 -0
- package/skills/tableau-next-asset-create/references/destructive-operations.md +62 -0
- package/skills/tableau-next-asset-create/references/edit-dashboard.md +273 -0
- package/skills/tableau-next-asset-create/references/edit-visualization.md +529 -0
- package/skills/tableau-next-asset-create/references/empty-source-handling.md +104 -0
- package/skills/tableau-next-asset-create/references/ingest-and-metric-gotchas.md +638 -0
- package/skills/tableau-next-asset-create/references/insight-bundle.md +69 -0
- package/skills/tableau-next-asset-create/references/large-flat-file-handling.md +331 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_envelope.json +54 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_shared-widget-fields.json +122 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/add_page.json +29 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/delete_page.json +27 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/discard_dashboard.json +11 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget.json +30 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget_to_page.json +30 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/place_widget_on_page.json +30 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_dashboard.json +16 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_page.json +26 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/rename_page.json +28 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/save_dashboard.json +18 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/undo.json +11 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_button_widget.json +69 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_container_widget.json +88 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_filter_widget.json +146 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_metric_widget.json +78 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_navigation_widget.json +80 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_parameter_widget.json +160 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_text_widget.json +103 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_visualization_widget.json +68 -0
- package/skills/tableau-next-asset-create/references/sdm-tool-reference.md +721 -0
- package/skills/tableau-next-asset-create/references/semantic-query-and-enrichment.md +355 -0
- package/skills/tableau-next-asset-create/references/shared-gates.md +322 -0
- package/skills/tableau-next-asset-create/references/sharing-and-promotion.md +306 -0
- package/skills/tableau-next-asset-create/references/tasks/ai-readiness-audit.md +51 -0
- package/skills/tableau-next-asset-create/references/tasks/analyze-data.md +48 -0
- package/skills/tableau-next-asset-create/references/tasks/build-dashboard.md +66 -0
- package/skills/tableau-next-asset-create/references/tasks/build-end-to-end.md +73 -0
- package/skills/tableau-next-asset-create/references/tasks/create-data-transform.md +51 -0
- package/skills/tableau-next-asset-create/references/tasks/create-viz.md +58 -0
- package/skills/tableau-next-asset-create/references/tasks/edit-dashboard.md +80 -0
- package/skills/tableau-next-asset-create/references/tasks/edit-sdm.md +106 -0
- package/skills/tableau-next-asset-create/references/tasks/edit-viz.md +40 -0
- package/skills/tableau-next-asset-create/references/tasks/enrich-model.md +68 -0
- package/skills/tableau-next-asset-create/references/tasks/ingest-flat-file.md +68 -0
- package/skills/tableau-next-asset-create/references/tasks/manage-alert.md +35 -0
- package/skills/tableau-next-asset-create/references/tasks/profile-dataset.md +47 -0
- package/skills/tableau-next-asset-create/references/tasks/promote-or-reuse.md +46 -0
- package/skills/tableau-next-asset-create/references/tasks/provision-user.md +39 -0
- package/skills/tableau-next-asset-create/references/tasks/query-model.md +92 -0
- package/skills/tableau-next-asset-create/references/tasks/review-verified-questions.md +42 -0
- package/skills/tableau-next-asset-create/references/tasks/share-asset.md +37 -0
- package/skills/tableau-next-asset-create/references/verified-questions.md +125 -0
- package/skills/tableau-next-asset-create/references/viz-authoring.md +992 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +0 -102
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# Sharing and promotion/reuse — payloads and gotchas
|
|
2
|
+
|
|
3
|
+
Load this from `tasks/share-asset.md` or `tasks/promote-or-reuse.md`. Not a
|
|
4
|
+
first hop.
|
|
5
|
+
|
|
6
|
+
Principal lookup, access-level rules, safe share mutation, and the Reuse /
|
|
7
|
+
Promotion request lifecycle live here once. Task guides stay thin.
|
|
8
|
+
|
|
9
|
+
The MCP tools are namespaced per server — names here are bare; use whichever
|
|
10
|
+
server prefix is connected.
|
|
11
|
+
|
|
12
|
+
## Contents
|
|
13
|
+
|
|
14
|
+
Intent → heading:
|
|
15
|
+
|
|
16
|
+
- Resolve a recipient / `recordId` / share row → Share: principal lookup
|
|
17
|
+
- `accessType` / `owner` / `viewer` / group vs user → Share: permission matrix
|
|
18
|
+
- Personal Org share vs production → Share: Personal Org
|
|
19
|
+
- Duplicate / partial batch / silent 204 / last owner → Share: safe mutation
|
|
20
|
+
- `defaultExc` vs empty 204 / error array → Share: response wrap
|
|
21
|
+
- Reuse vs Promotion, poll fields, list filters → Promote: request lifecycle
|
|
22
|
+
- Package URL, `sf` CLI, git/`gh` PR → Promote: pull-request recovery
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Share: principal lookup
|
|
27
|
+
|
|
28
|
+
**Resolve the recipient before `add_asset_share`.** Call
|
|
29
|
+
`search_users_and_groups` first. Pass the query as `usersAndGroupsQueryInput`
|
|
30
|
+
(not a bare top-level `searchTerm`). Each result item's `id` is the
|
|
31
|
+
`userOrGroupId` to pass.
|
|
32
|
+
|
|
33
|
+
- `searchTerm`: **Minimum 2 characters**. A single character is rejected (not
|
|
34
|
+
"few results"). Matching is **case-insensitive**.
|
|
35
|
+
- Results interleave users and groups in `items`. Paginate with independent
|
|
36
|
+
`nextUserOffset` and `nextGroupOffset` — do not add `items.length` to a
|
|
37
|
+
single offset.
|
|
38
|
+
- `useAutoSuggest` defaults to `false`; typeahead is opt-in.
|
|
39
|
+
- `recipientSearchTerm` on `list_asset_shares` is a case-insensitive
|
|
40
|
+
**substring** on display name / username. **No minimum length**; blank
|
|
41
|
+
values are ignored. Do not treat it as the same rule as `searchTerm`.
|
|
42
|
+
|
|
43
|
+
**`recordId` is the asset's Salesforce record ID**, not its `apiName` or label.
|
|
44
|
+
Obtain it from `get_dashboard`, `get_visualization`, `list_workspaces`, or
|
|
45
|
+
`get_semantic_model`. An id that is not a known asset type (dashboard,
|
|
46
|
+
workspace, visualization, semantic model) returns `INVALID_INPUT`. Missing
|
|
47
|
+
entity-level view permission → `ACCESS_DENIED`.
|
|
48
|
+
|
|
49
|
+
**`list_asset_shares`:** do not pass `setupObjectType` — the asset type is
|
|
50
|
+
inferred from the `recordId` prefix.
|
|
51
|
+
|
|
52
|
+
- `limit` Defaults to **10**. No enforced maximum. Paginate; a first page is
|
|
53
|
+
not the full recipient list.
|
|
54
|
+
- `orderBy` is only `CreatedDate` (default) or `UserDisplayName`. Anything
|
|
55
|
+
else errors.
|
|
56
|
+
- `sortOrder` is case-sensitive: only the exact string `"ASC"` is ascending.
|
|
57
|
+
`"asc"` (or anything else) silently falls back to descending.
|
|
58
|
+
- `filterByRecipientType` `Group` maps internally to both Group and Queue.
|
|
59
|
+
- Callers who are not an owner or manager of the asset get a **filtered view**
|
|
60
|
+
(owner-level shares plus their own entry) with no indication that other
|
|
61
|
+
rows were hidden.
|
|
62
|
+
- `ownerCount` is always the unfiltered total, even when `filterByAccessType`
|
|
63
|
+
or `limit` narrows `recordAccessMappings`.
|
|
64
|
+
- Shares for deleted users/groups are silently omitted (no tombstone).
|
|
65
|
+
|
|
66
|
+
**Existing shares (update / remove):** `list_asset_shares` first, then use the
|
|
67
|
+
`userOrGroupId` on each entry. `update_asset_share` **Does not remap** ids —
|
|
68
|
+
pass the listed (shadow) value. A prod-sourced add-time id **will not match**
|
|
69
|
+
and the update **fails** — that is not the remove path's HTTP 204 silent
|
|
70
|
+
no-op.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Share: permission matrix
|
|
75
|
+
|
|
76
|
+
`accessType` allowed values **vary by** `setupObjectType`. An unsupported
|
|
77
|
+
combination returns `INVALID_INPUT`. `commenter` and `manager` are **never**
|
|
78
|
+
valid for any asset type.
|
|
79
|
+
|
|
80
|
+
| `setupObjectType` | Production | Notes |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| `analyticsvisualization` | `viewer` only | Personal Org writes: `ACCESS_DENIED` (workspace only) |
|
|
83
|
+
| `analyticsdashboard` | `viewer` only | Personal Org writes: `ACCESS_DENIED` (workspace only) |
|
|
84
|
+
| `analyticsworkspace` | `viewer`, `editor`, `owner` | Personal Org: `viewer`, `editor` (not `owner`) |
|
|
85
|
+
| `semanticmodel` | `viewer`, `editor`, `owner` | Personal Org writes: `ACCESS_DENIED` (workspace only) |
|
|
86
|
+
|
|
87
|
+
**Groups cannot be `owner`** on any asset type → `INVALID_INPUT`.
|
|
88
|
+
|
|
89
|
+
`applicationDomain` is required on each `accessRequestItems` entry and must
|
|
90
|
+
literally be `"Tableau"`.
|
|
91
|
+
|
|
92
|
+
`add_asset_share` and `update_asset_share` take **top-level** parameters
|
|
93
|
+
alongside `recordId` — do not nest them in a `body` wrapper.
|
|
94
|
+
|
|
95
|
+
Reference shape (substitute ids from `list_*` / `search_users_and_groups`):
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"recordId": "<18-char asset id>",
|
|
100
|
+
"accessRequestItems": [
|
|
101
|
+
{
|
|
102
|
+
"userOrGroupId": "<id from search_users_and_groups>",
|
|
103
|
+
"setupObjectType": "analyticsdashboard",
|
|
104
|
+
"accessType": "viewer",
|
|
105
|
+
"applicationDomain": "Tableau"
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Share: Personal Org
|
|
114
|
+
|
|
115
|
+
**Writes** (`add_asset_share`, `update_asset_share`, `remove_asset_share`): only
|
|
116
|
+
`analyticsworkspace`. Any other `setupObjectType` returns `ACCESS_DENIED`
|
|
117
|
+
(`You can only modify sharing for workspaces in a Personal Org.`). The call
|
|
118
|
+
is rejected on asset type before `accessType` is checked — a personal-org
|
|
119
|
+
dashboard or visualization is not a `viewer` share.
|
|
120
|
+
|
|
121
|
+
**Group sharing is not supported** in Personal Orgs. Recipients must be
|
|
122
|
+
individual users. `ALL_USERS` as the group id returns `ACCESS_DENIED`.
|
|
123
|
+
|
|
124
|
+
**Reads:** listing shares is not restricted to workspaces — you can list shares
|
|
125
|
+
on dashboards, visualizations, and models there even though you cannot add /
|
|
126
|
+
update / remove them.
|
|
127
|
+
|
|
128
|
+
**Search:** `search_users_and_groups` **does not fail** in a Personal Org; it
|
|
129
|
+
returns the same results as production, and you may call either server's tool.
|
|
130
|
+
Only **user** results are usable as share recipients there (see group rule).
|
|
131
|
+
Do not skip to a "production-only" search on the belief that personal-org
|
|
132
|
+
search always fails.
|
|
133
|
+
|
|
134
|
+
**IDs:** `add_asset_share` stores a local **shadow ID**. `list_asset_shares`
|
|
135
|
+
returns that shadow on `userOrGroupId` and `userOrGroup.id`. Use the shadow
|
|
136
|
+
with `update_asset_share` and `remove_asset_share`. For a user who is **not
|
|
137
|
+
yet** in the personal org, pass the prod-sourced id from
|
|
138
|
+
`search_users_and_groups` into **add** — no shadow ID exists yet for that user.
|
|
139
|
+
Do **not** keep the prod id for remove: that call returns HTTP 204 and the
|
|
140
|
+
share stays. The same prod id on `update_asset_share` **fails** (no remap,
|
|
141
|
+
not a silent 204). List after every remove.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Share: safe mutation
|
|
146
|
+
|
|
147
|
+
Confirm recipient + asset + `accessType` before add or update. Confirm before
|
|
148
|
+
remove — the user **loses access immediately**.
|
|
149
|
+
|
|
150
|
+
- **`sendNotificationToRecipients`:** optional; emails the recipient. The grant
|
|
151
|
+
still takes effect without it.
|
|
152
|
+
- **Duplicate add:** that item fails with `DUPLICATE_VALUE` in
|
|
153
|
+
`failedRecordShares`; other items in the same request can still succeed.
|
|
154
|
+
Always inspect `failedRecordShares` on an otherwise successful response.
|
|
155
|
+
- **Partial update:** same `failedRecordShares` rule.
|
|
156
|
+
- **No existing share on update:** a **multi-item** batch reports
|
|
157
|
+
`RESOURCE_NOT_FOUND` per item in `failedRecordShares`. A **single-item**
|
|
158
|
+
request instead fails the call with top-level
|
|
159
|
+
`RESOURCE_UPDATE_FAILURE_UNPROCESSABLE`. Verify the row via `list_asset_shares`
|
|
160
|
+
before a one-item update.
|
|
161
|
+
- **Invalid id format on update:** `fails the entire batch` with
|
|
162
|
+
`INVALID_INPUT` and `failedRecordShares` empty — not a per-item failure.
|
|
163
|
+
- **Minimum owner:** the API keeps **at least one owner**. Downgrading or
|
|
164
|
+
removing the last owner → `INVALID_INPUT`.
|
|
165
|
+
- **Cannot remove your own share** → `INVALID_INPUT`. The API checks own share before
|
|
166
|
+
the minimum-owner rule, so the last owner who is also the caller sees the
|
|
167
|
+
own-share error.
|
|
168
|
+
- **Remove id mismatch / missing row:** HTTP 204 silently (looks like
|
|
169
|
+
success) with **no error**. In a Personal Org, a prod-sourced add-time id
|
|
170
|
+
is this silent no-op — the share remains. Verify with `list_asset_shares`
|
|
171
|
+
before and after; 204 is not proof the row is gone.
|
|
172
|
+
- **Conversation visualizations** (`creationSource = CONVERSATION`): add and
|
|
173
|
+
list GET return `INVALID_INPUT` when the ephemeral viz sharing gate is on.
|
|
174
|
+
|
|
175
|
+
To **revoke access entirely**, use `remove_asset_share` — `update_asset_share`
|
|
176
|
+
only changes `accessType`.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Share: response wrap
|
|
181
|
+
|
|
182
|
+
`add_asset_share`, `update_asset_share`, and `search_users_and_groups`
|
|
183
|
+
double-wrap as `{"defaultExc": "<stringified JSON>", "responseCode": <number>}`.
|
|
184
|
+
Parse `JSON.parse(response.defaultExc)` (same pattern as
|
|
185
|
+
`sdm-tool-reference.md` Response double-wrap).
|
|
186
|
+
|
|
187
|
+
`remove_asset_share` does **not**. Success is an empty body (HTTP 204). Failure
|
|
188
|
+
is a raw **JSON array** (`[{"errorCode": "...", "message": "..."}]`).
|
|
189
|
+
|
|
190
|
+
`list_asset_shares` is unwrapped.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Promote: request lifecycle
|
|
195
|
+
|
|
196
|
+
`create_reuse_promotion_request` is one tool for two directions — meaning flips.
|
|
197
|
+
Pass the create fields as **flat top-level params** (`requestType`, `assetId`,
|
|
198
|
+
`label`, `workspaceIdOrApiName`, `requesterComment`) — there is **no**
|
|
199
|
+
`dataAssetRequestInput` (or any other) body wrapper; the schema is
|
|
200
|
+
`additionalProperties: false` and rejects one. Create `requestType` is
|
|
201
|
+
`Reuse`/`Promotion` (capitalized). `list_promotion_reuse_requests` uses
|
|
202
|
+
lowercase `reuse` (case-insensitive); the create response also shows
|
|
203
|
+
`reuse` | `promotion`.
|
|
204
|
+
|
|
205
|
+
| `requestType` | `assetId` | `workspaceIdOrApiName` |
|
|
206
|
+
|---|---|---|
|
|
207
|
+
| Reuse | prod asset to copy | Personal Org **destination** workspace |
|
|
208
|
+
| Promotion | Personal Org asset to package | Personal Org workspace **containing** the asset |
|
|
209
|
+
|
|
210
|
+
`workspaceIdOrApiName` is an id or true apiName, **NOT the workspace label**
|
|
211
|
+
with spaces.
|
|
212
|
+
|
|
213
|
+
**Reuse `assetId` types:** Dashboard, Visualization, DMO, SDM, or CIO only.
|
|
214
|
+
Do **not** pass a Data Lake Object (`0gO`) or a Data Connection id — those
|
|
215
|
+
requests are rejected.
|
|
216
|
+
|
|
217
|
+
`requesterComment` is required (max **254** chars). Do not omit or pass null
|
|
218
|
+
— the downstream UI will break.
|
|
219
|
+
|
|
220
|
+
**Org:** caller must be in a Personal Org. Otherwise
|
|
221
|
+
`INVALID_INPUT: "Request is not supported in this type of org"`.
|
|
222
|
+
|
|
223
|
+
**After create — poll `get_promotion_reuse_request` by the returned `id`**
|
|
224
|
+
(listing a known request is not the poll path — `get_promotion_reuse_request`
|
|
225
|
+
is cheaper and returns more detail).
|
|
226
|
+
|
|
227
|
+
`status` is lowercase on the wire. Documented values: `requested`,
|
|
228
|
+
`reviewContent`, `markAcceptedOrRejected`, `accepted`, `rejected`,
|
|
229
|
+
`extracting`, `extractionComplete`, `migrating`, `migrationSucceeded`,
|
|
230
|
+
`failed`, `cancelled`, `manageCsv`, `manageAccess`, `manageDataPolicy`,
|
|
231
|
+
`markComplete`, `completed`.
|
|
232
|
+
|
|
233
|
+
- **Reuse:** poll `status` until the terminal `completed`
|
|
234
|
+
(`taskProgressStatus: terminal`). Happy path: `requested` → `accepted` →
|
|
235
|
+
`extracting` → `extractionComplete` → `migrating` → `migrationSucceeded` →
|
|
236
|
+
`completed`. Do **not** wait for `migrationSucceeded` as the end state — it
|
|
237
|
+
is a brief intermediate a late poll skips right past on the way to
|
|
238
|
+
`completed`. **STOP** on `failed`, `cancelled`, or `rejected` — do not keep
|
|
239
|
+
polling for success. When `status = rejected`, read `rejectionComment` (that
|
|
240
|
+
is when it is populated) and surface it; do not invent a reason.
|
|
241
|
+
- **Promotion:** poll `packageExportStatus` every **10 seconds** for up to
|
|
242
|
+
30 seconds until it is `ready`. **The wire value is lowercase** (`ready`,
|
|
243
|
+
`packaging`, …) even though the `create_reuse_promotion_request` schema enum
|
|
244
|
+
and older docs show it capitalized (`"Ready"`) — match case-insensitively; a
|
|
245
|
+
strict `=== "Ready"` check never fires. Note `status` itself stays
|
|
246
|
+
`requested` throughout a Promotion (it does not advance like Reuse) — gate
|
|
247
|
+
only on `packageExportStatus`. If it is ready, **ask** the user before
|
|
248
|
+
`create_promotion_pull_request`. If it is not ready, tell them to try
|
|
249
|
+
`create_promotion_pull_request` later — do not poll indefinitely.
|
|
250
|
+
`packageExportStatus` must be `ready` before `create_promotion_pull_request`.
|
|
251
|
+
Same stop on Reuse-style `failed` / `cancelled` / `rejected` if `status`
|
|
252
|
+
lands there before export is ready.
|
|
253
|
+
|
|
254
|
+
**`list_promotion_reuse_requests`:** optional query fields are **top-level**
|
|
255
|
+
(combinable) — `workspaceIdOrApiName`, `assetId`, `assetType`, `createdBy`,
|
|
256
|
+
`searchQueryTerm`, `status`, `taskProgressStatus`, `sortBy`, `orderBy`,
|
|
257
|
+
`limit`, `offset`. Do **not** nest them in a `requestParams` wrapper (that
|
|
258
|
+
name is the Connect Java map, not an MCP key). Always pass
|
|
259
|
+
`requestType=reuse` (case-insensitive). Omitting it mixes Promotion rows
|
|
260
|
+
into the list with no error.
|
|
261
|
+
|
|
262
|
+
- `assetId` — filter to one source prod asset.
|
|
263
|
+
- `createdBy` — user id of the requester.
|
|
264
|
+
- `searchQueryTerm` — free-text match against label / comment.
|
|
265
|
+
- `assetType` — `dashboard` / `visualization` / `semanticModel` / etc.
|
|
266
|
+
Do not invent further values.
|
|
267
|
+
- `status` — **comma-separated**, e.g. `requested,extracting,migrating` for
|
|
268
|
+
in-flight or `rejected,failed` for terminal. Values are **silently
|
|
269
|
+
accepted** even when spelled wrong — a typo returns an empty list, not a
|
|
270
|
+
validation error. Spell statuses like the get-by-id lifecycle above.
|
|
271
|
+
- `taskProgressStatus` — also comma-separated; **finer-grained than
|
|
272
|
+
`status`**. Do not send one field's values on the other.
|
|
273
|
+
- `sortBy` and `orderBy` — sort key plus asc / desc. Do not invent allowed
|
|
274
|
+
keys; omit unless the user named a sort.
|
|
275
|
+
- `limit` / `offset` — paginate. A default page size applies if `limit` is
|
|
276
|
+
omitted (do not assume the first page is complete).
|
|
277
|
+
- For one known id, prefer `get_promotion_reuse_request` — cheaper, more
|
|
278
|
+
detail.
|
|
279
|
+
|
|
280
|
+
Create/list may double-wrap: if the body looks like `defaultExc`, parse it
|
|
281
|
+
the same way as Share wrap. Get-by-id is unwrapped (do not assume
|
|
282
|
+
`defaultExc` on a failed poll).
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Promote: pull-request recovery
|
|
287
|
+
|
|
288
|
+
`create_promotion_pull_request` does **not** open the GitHub PR. It returns a
|
|
289
|
+
GET-only `presignedUrl` (expires in **5 minutes**) plus `requestId`. Download
|
|
290
|
+
immediately. Git / `gh pr create` is **client-side**.
|
|
291
|
+
|
|
292
|
+
1. `PROMO_DIR=/tmp/promotion_<requestId>` (and `mdapi` / `source` under it) so
|
|
293
|
+
concurrent promotions do not collide.
|
|
294
|
+
2. `curl` the zip. Decode `&` in the URL to `&` first.
|
|
295
|
+
3. Unzip into `$PROMO_DIR/mdapi/`.
|
|
296
|
+
4. If the Salesforce sf CLI is missing, **STOP**. Tell the user it is required to
|
|
297
|
+
convert the package, and give them the remaining commands — do not continue.
|
|
298
|
+
5. Write `$PROMO_DIR/source/sfdx-project.json` as
|
|
299
|
+
`{"packageDirectories":[{"path":"force-app","default":true}],"sourceApiVersion":"67.0"}`.
|
|
300
|
+
Convert: `sf project convert mdapi --root-dir $PROMO_DIR/mdapi/unpackaged
|
|
301
|
+
--output-dir $PROMO_DIR/source/force-app`. Output files carry a `-meta.xml`
|
|
302
|
+
suffix.
|
|
303
|
+
6. **Ask** which directory in the target repo should receive the files. Copy
|
|
304
|
+
the contents **inside** `force-app/main/default/` (not the parent folders).
|
|
305
|
+
7. **Ask** for the branch name. Commit, push, `gh pr create`. Title the
|
|
306
|
+
promotion; body lists the datakit files and the **promotion request id**.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Task: AI-readiness audit + backfill / validate a model
|
|
2
|
+
|
|
3
|
+
Backfill missing AI-readiness metadata on an existing model, or validate a model
|
|
4
|
+
(no-island + query-returns-data audit). Entry points 14 and 16.
|
|
5
|
+
|
|
6
|
+
## Gates (assert before any tool call) → `../shared-gates.md`
|
|
7
|
+
|
|
8
|
+
**Backfill (entry 14):** Required **G1, G3, G5** · Conditional **G6** (◐)
|
|
9
|
+
**Validate (entry 16):** Required **G1, G2, G4, G7**
|
|
10
|
+
|
|
11
|
+
- **G1** (router-asserted): a `mcp__tableau-next-*__` tool must be connected.
|
|
12
|
+
- **Tool names are written bare** — invoke each under your client's name for that `tableau-next-*` server tool (`shared-gates.md`).
|
|
13
|
+
- **G3 (backfill):** read back the exact apiNames via `list_*` BEFORE any sparse
|
|
14
|
+
`update_*` call — sparse updates that target an assumed/suffixed name silently
|
|
15
|
+
miss. Echo `isVisible` and `dataObjectFieldName` on every dimension/measure
|
|
16
|
+
update (`shared-gates.md` G5 / `sdm-tool-reference.md`).
|
|
17
|
+
- **G5 (backfill):** distinct `description` per component (never copy-paste),
|
|
18
|
+
`sentiment` on directional measures/metrics, `agentEnabled:true` via
|
|
19
|
+
`update_semantic_model`, `businessPreferences` via
|
|
20
|
+
`get_semantic_model_business_preferences` /
|
|
21
|
+
`update_semantic_model_business_preferences` (`update_semantic_model`
|
|
22
|
+
fallback), correct date/type and dimension-vs-measure roles. Full
|
|
23
|
+
checklist: `../ai-readiness.md`.
|
|
24
|
+
- **G2 + G4 + G7 (validate):** every object joined (no islands) and
|
|
25
|
+
`run_semantic_query` returns real rows. Here G5 is a similarity *scan*, not
|
|
26
|
+
metadata creation — do not over-assert it.
|
|
27
|
+
- **G6** (◐, backfill): profile only if a field's role/meaning isn't understood;
|
|
28
|
+
do NOT re-ingest or re-model.
|
|
29
|
+
|
|
30
|
+
## Steps
|
|
31
|
+
|
|
32
|
+
The complete AI-readiness checklist, description/label quality guides, ambiguity
|
|
33
|
+
management, and `businessPreferences` examples are in **`../ai-readiness.md`**.
|
|
34
|
+
|
|
35
|
+
- **Backfill** — read back apiNames (`list_semantic_model_dimensions` / `_measures`
|
|
36
|
+
/ `_data_objects` / `_metrics`), then sparse `update_semantic_model_dimension` /
|
|
37
|
+
`_measure` (include `description` **and** echo `isVisible` + `dataObjectFieldName`
|
|
38
|
+
— description-only resets hidden fields to visible),
|
|
39
|
+
`get_semantic_model_business_preferences` then
|
|
40
|
+
`update_semantic_model_business_preferences` for prefs (GET first; full
|
|
41
|
+
replacement of `# `-prefixed lines, send only `businessPreferences`;
|
|
42
|
+
`update_semantic_model` is the fallback), `update_semantic_model` for
|
|
43
|
+
`agentEnabled`, and `sentiment` on directional measures/metrics.
|
|
44
|
+
- **Validate** — audit that every object participates in ≥1 relationship (G4) and
|
|
45
|
+
that `run_semantic_query` returns real rows (G7); a ~0-row join is broken.
|
|
46
|
+
- **Never declare AI-ready on metadata completeness alone** — recommend the
|
|
47
|
+
Semantic Model AI Optimization similarity scan (Semantic Model Builder UI)
|
|
48
|
+
before handoff; `modelHealth: Low` flags ambiguous components. Mention this
|
|
49
|
+
whenever the user asks whether a model is ready, finished, or handoff-able.
|
|
50
|
+
- **Scoring golden Q&A / listing verified questions** is
|
|
51
|
+
`review-verified-questions.md`, not this checklist.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Task: Analyze data (natural-language question)
|
|
2
|
+
|
|
3
|
+
Answer an interpretive analytical question through `analyze_data`: breakdowns,
|
|
4
|
+
rankings, trends, and comparisons. The Analytics Agent picks the SDM — you do
|
|
5
|
+
not need to pin one. Do **not** use this for a plain count, total, or scalar
|
|
6
|
+
("how many orders", "what is total revenue") — that is `query-model.md` /
|
|
7
|
+
`run_semantic_query`, even when no model was named.
|
|
8
|
+
|
|
9
|
+
## Gates (assert before any tool call) → `../shared-gates.md`
|
|
10
|
+
|
|
11
|
+
Required: **G1** · Conditional: **G6** (◐, if the returned numbers' grain is unclear)
|
|
12
|
+
|
|
13
|
+
- **G1** (router-asserted): a `mcp__tableau-next-*__` tool must be connected.
|
|
14
|
+
- **Tool names are written bare** — invoke each under your client's name for that
|
|
15
|
+
`tableau-next-*` server tool (`shared-gates.md`).
|
|
16
|
+
- **G6** (◐): if additivity/grain of the answer isn't understood, profile first
|
|
17
|
+
(`../data-understanding.md`) — do not re-ingest.
|
|
18
|
+
|
|
19
|
+
## When **not** to use this tool
|
|
20
|
+
|
|
21
|
+
- **Figures** (count, total, scalar, "give / run me the numbers") →
|
|
22
|
+
`query-model.md`. Discover the SDM with `list_semantic_models` if unnamed.
|
|
23
|
+
- **Named model + structured table** ("query Sales_Model for revenue by region",
|
|
24
|
+
explicit `run_semantic_query`) → `query-model.md`.
|
|
25
|
+
- **Greenfield** — nothing modeled yet / CSV / "build a dashboard" →
|
|
26
|
+
`build-end-to-end.md`.
|
|
27
|
+
- **Metadata discovery** (list SDMs, dashboards, fields, relationships) →
|
|
28
|
+
`list_*` / `get_*`, not `analyze_data`.
|
|
29
|
+
- **Ongoing monitor** ("alert me when…", change/list/delete my alerts) →
|
|
30
|
+
`manage-alert.md`. This tool answers once; it does not persist a watch.
|
|
31
|
+
|
|
32
|
+
## Steps
|
|
33
|
+
|
|
34
|
+
1. Call `analyze_data` with the user's question as the utterance.
|
|
35
|
+
2. **Do not pin `targetEntityNameOrId` or `targetEntityType`** unless the
|
|
36
|
+
user explicitly named a specific SDM / data source. `targetEntityType` is
|
|
37
|
+
`sdm` **only** when pinning.
|
|
38
|
+
3. If a complex question fails, break it into simpler questions and reason
|
|
39
|
+
client-side.
|
|
40
|
+
4. **This tool does NOT automatically render visualizations.** If `vizMetadata`
|
|
41
|
+
is returned and the user wants to see the chart, explicitly call
|
|
42
|
+
`render_visualization` with that object. (Opposite of `edit_visualization`,
|
|
43
|
+
which renders inline and must **not** be chased with `render_visualization`.)
|
|
44
|
+
5. Long-running / async: a slow answer polls in the background (up to several
|
|
45
|
+
minutes) rather than timing out — wait; do not treat silence as failure.
|
|
46
|
+
|
|
47
|
+
This is a read/analysis entry point — it does not model, enrich, or persist a
|
|
48
|
+
chart. If the answer needs a saved visualization, continue to `create-viz.md`.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Task: Design / create a dashboard
|
|
2
|
+
|
|
3
|
+
Design a dashboard narrative, create a **new** dashboard, or add a global
|
|
4
|
+
filter. Entry points 18, 19, 21. (Entry point 20, "add/edit a widget on an
|
|
5
|
+
existing dashboard," now lives in `edit-dashboard.md`.)
|
|
6
|
+
|
|
7
|
+
## Gates (assert before any tool call) → `../shared-gates.md`
|
|
8
|
+
|
|
9
|
+
Required: **G1, G8-full** · plus per-action:
|
|
10
|
+
- **Design narrative (18):** G1, G8-full · Conditional **G6** (◐, if you don't
|
|
11
|
+
yet understand what the underlying data means).
|
|
12
|
+
- **Create dashboard (19):** G1, **G2/G7** (transitive), G3, G8-full.
|
|
13
|
+
- **Add global filter (21):** G1, G3 only — do NOT over-gate with G2/G7/G8.
|
|
14
|
+
|
|
15
|
+
- **G1** (router-asserted): a `mcp__tableau-next-*__` tool must be connected.
|
|
16
|
+
- **Tool names are written bare** — invoke each under your client's name for that `tableau-next-*` server tool (`shared-gates.md`).
|
|
17
|
+
- **G8-full (decision #1):** design the narrative FIRST — KPIs → trends →
|
|
18
|
+
breakdowns → correlations, KPIs top/left on the F/Z path, chart-type diversity
|
|
19
|
+
(`../dashboard-design-principles.md`, MANDATORY for a dashboard).
|
|
20
|
+
- **G2/G7 (transitive):** a dashboard is only as valid as its widgets — each
|
|
21
|
+
viz/metric widget's underlying query must have returned real rows first.
|
|
22
|
+
- **G3:** read back the exact metric apiName / viz `id`+`name` before referencing
|
|
23
|
+
them in a widget.
|
|
24
|
+
- **G6** (◐, narrative design): if you don't yet understand grain/additivity of
|
|
25
|
+
the data the narrative is built around, profile first (`../data-understanding.md`).
|
|
26
|
+
|
|
27
|
+
## Hard constraint — viz-type widgets (decision #2)
|
|
28
|
+
|
|
29
|
+
A **viz-type widget requires the `id` + generated `name` returned by a prior
|
|
30
|
+
`create_visualization` call** (`upsert_visualization_widget`'s `source: {id,
|
|
31
|
+
name}` — `../edit-dashboard.md` §2). This dashboard shell can self-serve
|
|
32
|
+
**metric + text** widgets once built, but **not** a viz widget from nothing. So:
|
|
33
|
+
|
|
34
|
+
- **Metric / text widgets:** self-serve via `tasks/edit-dashboard.md` once the
|
|
35
|
+
shell exists.
|
|
36
|
+
- **Viz widget:** either (a) **compose** the `create-viz.md` flow first to get the
|
|
37
|
+
`id`+`name`, or (b) **accept** a pre-existing viz `id`+`name` the user supplies.
|
|
38
|
+
If the user asks for a chart on the dashboard and no viz exists yet, route
|
|
39
|
+
through **`create-viz.md`** first, then place its `id`+`name` as a viz widget
|
|
40
|
+
via `tasks/edit-dashboard.md`.
|
|
41
|
+
|
|
42
|
+
## Steps
|
|
43
|
+
|
|
44
|
+
Dashboard creation and the 48-column grid spec are in
|
|
45
|
+
**`../dashboard-authoring.md`**; `../build-workflow.md` Step 11 is the spine.
|
|
46
|
+
Once the shell exists, all widget/page editing — metric, viz, text, or any
|
|
47
|
+
other widget kind — routes through **`edit-dashboard.md`** via
|
|
48
|
+
**`tasks/edit-dashboard.md`**; this guide covers create + design + global
|
|
49
|
+
filter only.
|
|
50
|
+
|
|
51
|
+
- **Create empty shell** — `create_dashboard` (`widgets:{}`; seed one layout
|
|
52
|
+
with an empty `page_1` since widgets get placed next — `layouts:[]` only if
|
|
53
|
+
they won't — and always pass `minorVersion: -1` explicitly —
|
|
54
|
+
`../dashboard-authoring.md` §1).
|
|
55
|
+
- **Metric / viz / text / any other widget** — hand off to
|
|
56
|
+
**`tasks/edit-dashboard.md`** (`edit_dashboard`'s `upsert_*_widget` +
|
|
57
|
+
`place_widget_on_page`, staged as a draft, saved only on confirmation) — the
|
|
58
|
+
only supported path for widget/page editing.
|
|
59
|
+
- **Global filter** — `add_global_filter_to_dashboard`; self-contained (no
|
|
60
|
+
separate read/replace round trip), value-matching rule of thumb, and the
|
|
61
|
+
contrast with a per-viz filter — `../dashboard-authoring.md` §5.
|
|
62
|
+
- **Metric-card insight payload (app renderer only)** — `../insight-bundle.md`.
|
|
63
|
+
Do **not** call `generate_insight_bundle` on a user chat turn.
|
|
64
|
+
- **Show / open an existing dashboard** — `render_dashboard`, not
|
|
65
|
+
`get_dashboard`. Flags and metadata-vs-render split:
|
|
66
|
+
`../dashboard-authoring.md` §8.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Task: Build a semantic model + dashboard end-to-end (greenfield)
|
|
2
|
+
|
|
3
|
+
The greenfield "nothing is modeled yet" path — analyze flat files, a table
|
|
4
|
+
on an existing connection, or other unmodeled data all the way through to a
|
|
5
|
+
dashboard.
|
|
6
|
+
|
|
7
|
+
This guide is the **gate map** for the greenfield flow, not a second copy of the
|
|
8
|
+
spine: it declares which gates fire across the whole build (below), maps each step
|
|
9
|
+
to the gate it enforces and the slice-guide that can be entered standalone, then
|
|
10
|
+
hands the actual procedure to `../build-workflow.md`. The router points here rather
|
|
11
|
+
than straight to `build-workflow.md` so the full-flow gate coverage is asserted
|
|
12
|
+
before Step 0 and the mid-flow entry points stay discoverable.
|
|
13
|
+
|
|
14
|
+
## Gates (assert before any tool call) → `../shared-gates.md`
|
|
15
|
+
|
|
16
|
+
Required across the flow: **G1, G2, G3, G4, G5, G6, G7, G8**. Each step below
|
|
17
|
+
inherits the gates its action needs (per the coverage matrix). At minimum:
|
|
18
|
+
|
|
19
|
+
- **G1** (router-asserted): a `mcp__tableau-next-*__` tool must be connected.
|
|
20
|
+
- **Tool names are written bare** — invoke each under your client's name for that `tableau-next-*` server tool (`shared-gates.md`).
|
|
21
|
+
- **G6** *first*: profile before you model — grain, field roles, cardinality,
|
|
22
|
+
additivity, date roles. For a large/wide/cryptic file, infer its schema before
|
|
23
|
+
creating the data stream, then do value-level checks with `run_query`.
|
|
24
|
+
- **G2** before adding any *discovered* object. For a DMO you just created and
|
|
25
|
+
mapped in this flow, poll `run_query` until `<dmo>__dlm` exists (`COUNT = 0`
|
|
26
|
+
is READY; `42P01` keep polling) — `shared-gates.md` G2. Keep the discovered
|
|
27
|
+
row-count gate as-is.
|
|
28
|
+
- **G3** before writing any apiName you did not just read back.
|
|
29
|
+
- **G4 + G7** once ≥2 objects exist: every object joined, every join row-verified.
|
|
30
|
+
- **G5** on every component you create (metrics first).
|
|
31
|
+
- **G7 + G8** before any `create_visualization`.
|
|
32
|
+
|
|
33
|
+
## Steps
|
|
34
|
+
|
|
35
|
+
The full procedural spine with verified per-tool payloads and inline gotchas lives
|
|
36
|
+
in **`../build-workflow.md`** — load it and follow Step 0 → Step 11:
|
|
37
|
+
|
|
38
|
+
- **Step 0 — Ingest** (CSV/Excel upload **or** existing database connection) →
|
|
39
|
+
see `../ingest-and-metric-gotchas.md` §A (file) / §C (connection) and
|
|
40
|
+
`ingest-flat-file.md` standalone. File chain: `get_upload_connection` →
|
|
41
|
+
`infer_object_schema` → `create_data_stream` → `run_data_stream` → wait DLO
|
|
42
|
+
Active → SCHEMA REALITY CHECK + real Primary Key read-back →
|
|
43
|
+
`create_data_model_object` (unsuffixed name; platform adds `__dlm`) → wait
|
|
44
|
+
DMO Ready → `create_dlo_to_dmo_mapping` → poll `run_query` until
|
|
45
|
+
`<dmo>__dlm` exists (`get_dlo_to_dmo_mapping_status` `ACTIVE` is metadata
|
|
46
|
+
only). Connection chain: `list_connections` →
|
|
47
|
+
`list_data_connection_objects` → `infer_object_schema` →
|
|
48
|
+
`create_data_stream` (`dataAccessMode: "Direct_Access"`, connection
|
|
49
|
+
developer name) → `run_data_stream` `interactive: false` → then the same
|
|
50
|
+
DMO / mapping tail.
|
|
51
|
+
- **Step 0.5 / 1 — Profile + discover** (G6) → `../data-understanding.md`,
|
|
52
|
+
`../large-flat-file-handling.md`; or `profile-dataset.md`.
|
|
53
|
+
- **Step 2 — Verify data presence** (G2) → `../empty-source-handling.md`. For
|
|
54
|
+
DMOs you just created and mapped in Step 0, wait until `run_query` succeeds
|
|
55
|
+
on `__dlm` (`COUNT = 0` is READY); keep the discovered-source row-count
|
|
56
|
+
gate as-is.
|
|
57
|
+
- **Step 3 — Confirm join keys** (G7) with a real JOIN row-count.
|
|
58
|
+
- **Steps 4–6 — Create model with nested fields, add remaining objects, add
|
|
59
|
+
relationships** (G2, G3, G4, G5) → `../sdm-tool-reference.md`; or
|
|
60
|
+
`edit-sdm.md`. Bind via one `create_semantic_model` with explicit
|
|
61
|
+
`semanticDimensions[]` / `semanticMeasurements[]` (`shouldIncludeAllFields:
|
|
62
|
+
false`); do not N-call `add_semantic_model_dimension` / `_measure`.
|
|
63
|
+
- **Step 7 — Validate (BLOCKING)** (G4, G7): every object joined +
|
|
64
|
+
`run_semantic_query` returns real rows; empty → STOP.
|
|
65
|
+
- **Step 8 — Enrich** (G5, G6, G7): calc dimensions/measures + metrics →
|
|
66
|
+
`../semantic-query-and-enrichment.md`; metric gotchas `../ingest-and-metric-gotchas.md`
|
|
67
|
+
§B; or `enrich-model.md`.
|
|
68
|
+
- **Step 9 — Query the model** (G7) → `../semantic-query-and-enrichment.md`; or
|
|
69
|
+
`query-model.md`.
|
|
70
|
+
- **Step 10 — Create visualizations** (G7, G8) → `../dashboard-design-principles.md`
|
|
71
|
+
(narrative first), `../viz-authoring.md`; or `create-viz.md`.
|
|
72
|
+
- **Step 11 — Build the dashboard** (G7 transitive, G8) → `../dashboard-authoring.md`;
|
|
73
|
+
or `build-dashboard.md`.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Task: Create or update a Data Cloud SQL transform
|
|
2
|
+
|
|
3
|
+
Materialize a **derived** DLO/DMO from one or more source objects via a Data
|
|
4
|
+
Cloud SQL (DCSQL) transform. Use this when the user wants a new derived table
|
|
5
|
+
or to change how an existing transform-backed table is produced — not for
|
|
6
|
+
CSV ingest (`ingest-flat-file.md`) and not for semantic-model calculated
|
|
7
|
+
fields (`enrich-model.md`).
|
|
8
|
+
|
|
9
|
+
## Gates (assert before any tool call) → `../shared-gates.md`
|
|
10
|
+
|
|
11
|
+
Required: **G1** · Conditional: **G2** (◐, source object must exist)
|
|
12
|
+
|
|
13
|
+
- **G1** (router-asserted): a `mcp__tableau-next-*__` tool must be connected.
|
|
14
|
+
- **Tool names are written bare** — invoke each under your client's name for that `tableau-next-*` server tool (`shared-gates.md`).
|
|
15
|
+
- **Confirmation (this guide):** never call `create_data_transform`,
|
|
16
|
+
`update_data_transform`, or `run_data_transform` without an explicit "yes"
|
|
17
|
+
after showing SQL + preview. Run is a **separate** yes from create/update.
|
|
18
|
+
- **G2** (◐): the **source** relation must be a real `__dll` / `__dlm` from
|
|
19
|
+
`browse_data_assets`. Do not invent the apiName.
|
|
20
|
+
|
|
21
|
+
## Steps
|
|
22
|
+
|
|
23
|
+
Payloads, immutable-vs-editable fields, timeout recovery, SparkInternal
|
|
24
|
+
substitutions, and error strings are in
|
|
25
|
+
**`../data-transform-gotchas.md`**.
|
|
26
|
+
|
|
27
|
+
1. Disambiguate: **create** if the output object does not exist; **update**
|
|
28
|
+
if it is already transform-backed (never a second transform on that table).
|
|
29
|
+
2. Resolve the source `assetApiName` (with suffix). Multiple matches → STOP
|
|
30
|
+
and ask.
|
|
31
|
+
3. Generate DCSQL; validate (`validate_data_transform` and/or `run_query`
|
|
32
|
+
with `rowLimit: 10`). **Every output SELECT alias / `fields[].name` must
|
|
33
|
+
be `__c`-suffixed** — validate does not error on a bare alias, it
|
|
34
|
+
silently renames the derived field, and the mismatch only fails later
|
|
35
|
+
on `run_data_transform` (see the deep ref).
|
|
36
|
+
4. Confirm with the user (SQL + preview + output name).
|
|
37
|
+
5. Create (full nested `definitions`/`manifest`) or update (GET first; full
|
|
38
|
+
replace; copy 🔒 fields). Create, update, and validate send the **same
|
|
39
|
+
flat body** (`name` / `type` / `definitions` at the top level — no
|
|
40
|
+
`dataTransformObject` / `dataTransform` envelope). On update timeout, GET
|
|
41
|
+
and compare `compiled_code` — do not blindly retry.
|
|
42
|
+
6. Create-only: add the new output object to the workspace the user named
|
|
43
|
+
(else list and ask).
|
|
44
|
+
7. Confirm, then `run_data_transform` only after the transform is `ACTIVE`
|
|
45
|
+
(not `PROCESSING`). Runs may be sync or async; poll
|
|
46
|
+
`get_data_transform_run_history` until the run succeeds or fails
|
|
47
|
+
(typically 10–15 minutes). If status looks stuck, call
|
|
48
|
+
`refresh_data_transform_status` then poll history again. Do **not** treat
|
|
49
|
+
`get_data_transform` `ACTIVE` as “rows are ready.” BATCH definitions use
|
|
50
|
+
`DCSQL`; STREAMING uses `SQL`. DMO outputs need `KQ_<pk>` (see the deep
|
|
51
|
+
ref).
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Task: Create a visualization (single chart)
|
|
2
|
+
|
|
3
|
+
Create one visualization with `create_visualization` on a built, populated model.
|
|
4
|
+
Entry point 17. (For a dashboard, use `build-dashboard.md`.) This is also the
|
|
5
|
+
**first hop** for a chart-type / `create_visualization` payload lookup — do not
|
|
6
|
+
start at `viz-authoring.md`.
|
|
7
|
+
|
|
8
|
+
## Gates (assert before any tool call) → `../shared-gates.md`
|
|
9
|
+
|
|
10
|
+
Required: **G1, G2, G3, G7, G8-light** · Conditional: **G4** (◐, if the chart
|
|
11
|
+
queries across >1 object), **G5/G6** (◐, consume-not-create)
|
|
12
|
+
|
|
13
|
+
- **G1** (router-asserted): a `mcp__tableau-next-*__` tool must be connected.
|
|
14
|
+
- **Tool names are written bare** — invoke each under your client's name for that `tableau-next-*` server tool (`shared-gates.md`).
|
|
15
|
+
- **G7:** run `run_semantic_query` and confirm real rows come back BEFORE
|
|
16
|
+
`create_visualization` — never chart a model that returned empty.
|
|
17
|
+
- **G2:** don't chart an empty/unverified source — field-richness ≠ data-presence.
|
|
18
|
+
- **G3:** read field apiNames back via `list_*`; `create_visualization` uses a
|
|
19
|
+
`fields` map keyed by fieldKey (`{objectName, fieldName, function}`; `objectName`
|
|
20
|
+
omitted for calc measures) — NOT the retired `fieldRef`/`measureFunction` shape,
|
|
21
|
+
and distinct from `run_semantic_query`'s snake_case `table_field`.
|
|
22
|
+
- **G8-light (decision #1):** state the chart's **analytical intent** — the one
|
|
23
|
+
question this chart answers and why the chart type fits the field roles
|
|
24
|
+
(trend/comparison/part-to-whole/correlation/forecast). A single standalone viz
|
|
25
|
+
does NOT require the full dashboard narrative, and you must **not invent a
|
|
26
|
+
dashboard** around it.
|
|
27
|
+
- **G5/G6** (◐): viz *consumes* metadata rather than creating it — business-
|
|
28
|
+
friendly labels depend on upstream descriptions already existing.
|
|
29
|
+
- **G4** (◐): only chart across objects that are actually joined — do not set
|
|
30
|
+
`queryUnrelatedDataObjects:"Exception"` and chart across unjoined objects.
|
|
31
|
+
|
|
32
|
+
## Steps
|
|
33
|
+
|
|
34
|
+
The visualization tool-selection guide, chart-type decision matrix (mapped to MCP
|
|
35
|
+
tools), field-selection priorities, color/breakdown encoding, UserAgg handling,
|
|
36
|
+
and verified payloads are in **`../viz-authoring.md`**; narrative/labeling
|
|
37
|
+
guidance is `../dashboard-design-principles.md`.
|
|
38
|
+
|
|
39
|
+
**First, identify the user's analysis intent — it picks the analysis type, which
|
|
40
|
+
picks the chart.** Don't jump straight to a bar chart:
|
|
41
|
+
|
|
42
|
+
| User intent (example) | Analysis type | Tool guidance | §reference |
|
|
43
|
+
|---|---|---|---|
|
|
44
|
+
| "revenue over time" | trend | Line (date on columns) | `viz-authoring.md` §11 Time Series |
|
|
45
|
+
| "top categories by sales" | comparison | Bar (dim on columns, sorted) | `viz-authoring.md` §11 Bar |
|
|
46
|
+
| "market-share breakdown" | part-to-whole | Donut (< 5 vals) or Bar (≥ 5) | `viz-authoring.md` §11 Donut |
|
|
47
|
+
| "discount vs profit relationship" | correlation | Scatter (2 measures, 1 color dim) | `viz-authoring.md` §11 Scatter |
|
|
48
|
+
| "predict next quarter revenue" | forecast | Line + `visualSpecification.forecasts` | `viz-authoring.md` §3 / §11 Time Series (forecast) |
|
|
49
|
+
|
|
50
|
+
- Pick the chart type matched to intent + field roles — do not default every
|
|
51
|
+
chart to a bar chart.
|
|
52
|
+
- Build with `create_visualization` (`fields` map + `visualSpecification`), only
|
|
53
|
+
after Step 9 / G7 returns real data. FieldKeys in `fields` are pointers —
|
|
54
|
+
they must exactly match `rows` / `columns` / encoding `fieldKey` strings.
|
|
55
|
+
- For forecast asks: timeseries Line only, continuous `DateTrunc*` date +
|
|
56
|
+
measure, then a `forecasts` entry (`HoltWinters` or `RidgeRegression`).
|
|
57
|
+
- Keep the returned viz `id` + generated `name` — a dashboard viz-widget needs
|
|
58
|
+
both (see `build-dashboard.md`).
|