一键导入
ts-variable-timezone
Manage the ts_user_timezone variable in ThoughtSpot — search current values, or set/remove timezone values at org or user level.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Manage the ts_user_timezone variable in ThoughtSpot — search current values, or set/remove timezone values at org or user level.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Convert or import a Snowflake Semantic View into ThoughtSpot as a Model. Use when Snowflake is the source and the goal is a ThoughtSpot Model — whether migrating Snowflake metrics and semantic definitions into ThoughtSpot or making a Semantic View available for Spotter and search-based analytics. Direction is always Snowflake → ThoughtSpot. Not for ThoughtSpot → Snowflake, standalone DDL generation, or adding AI context to existing ThoughtSpot models.
Convert or export a ThoughtSpot Worksheet or Model into a Snowflake Semantic View. Use when ThoughtSpot is the source and the goal is a Snowflake Semantic View — whether converting metrics and formulas for Cortex Analyst access, generating CREATE SEMANTIC VIEW DDL, writing a .sql file for later execution, or updating an existing Snowflake SV from a changed model. Direction is always ThoughtSpot → Snowflake. Not for Snowflake → ThoughtSpot, standalone TML exports, or adding synonyms/AI context to ThoughtSpot models.
Convert a Looker semantic model (LookML project) into ThoughtSpot — parses model + view .lkml files, generates Table TML and Model TML per explore, validates invariants, and imports. Optionally converts LookML dashboards to ThoughtSpot Liveboards. Direction is always Looker → ThoughtSpot.
Prepare a ThoughtSpot Model to work well with Spotter. Use when you want to improve how a Model responds to natural language queries — reviewing and writing AI context, synonyms, reference questions, business terms, and data model instructions. Mines real language from existing Liveboards, Answers, and optionally Snowflake query history to ground the coaching in how users actually talk about the data.
Convert or import a Databricks Metric View into ThoughtSpot as a Model. Use when Databricks is the source and the goal is a ThoughtSpot Model — whether migrating Databricks metrics and semantic definitions into ThoughtSpot or making a Metric View available for Spotter and search-based analytics. Direction is always Databricks → ThoughtSpot. Not for ThoughtSpot → Databricks, standalone DDL generation, or adding AI context to existing ThoughtSpot models.
Convert or export a ThoughtSpot Worksheet or Model into a Databricks Metric View. Use when ThoughtSpot is the source and the goal is a Databricks Metric View — whether converting metrics and formulas for Databricks AI/BI access, generating CREATE VIEW WITH METRICS DDL, writing a .sql file for later execution, or publishing ThoughtSpot semantics to Unity Catalog. Direction is always ThoughtSpot → Databricks. Not for Databricks → ThoughtSpot, standalone TML exports, or adding synonyms/AI context to ThoughtSpot models.
| name | ts-variable-timezone |
| description | Manage the ts_user_timezone variable in ThoughtSpot — search current values, or set/remove timezone values at org or user level. |
Manage values for the ts_user_timezone template variable, which controls the timezone
applied to date/time calculations per org or per user.
Ask one question at a time. Wait for each answer before proceeding.
| File | Purpose |
|---|---|
| ../ts-profile-thoughtspot/SKILL.md | ThoughtSpot auth, profile config, token persistence |
/ts-profile-thoughtspot if notts CLI installed: pip install -e tools/ts-clits_user_timezone variable must already exist on the clusterRead ~/.claude/thoughtspot-profiles.json. If the file is missing or empty, prompt the
user to run /ts-profile-thoughtspot first.
If multiple profiles exist, ask:
Which ThoughtSpot profile would you like to use?
1. {name} — {base_url}
2. {name} — {base_url}
Enter number:
If exactly one profile exists, show it and ask the user to confirm.
Authenticate:
source ~/.zshenv && ts auth whoami --profile "{profile_name}"
If the command fails, refer to ts-profile-thoughtspot/SKILL.md for the token refresh procedure.
Save {base_url} (strip trailing slash) and {profile_name} for display in confirmation
and result summaries. The ts CLI handles auth and SSL internally — no need to track
{verify_ssl} or manage bearer tokens.
Ask:
What would you like to do with ts_user_timezone?
1 Search — view current timezone values set for ts_user_timezone
2 Set — set (or overwrite) a timezone value for an org or user
3 Remove — remove the timezone value for an org or user
Enter 1, 2, or 3:
Map selections:
{operation} = "search" → go to Search Flow{operation} = "set" (API operation: REPLACE){operation} = "remove" (API operation: REMOVE — skill will look up current value)Save {operation}. If {operation} is "search", skip to Search Flow.
Otherwise continue with Step 3.
source ~/.zshenv && ts variables search ts_user_timezone --profile "{profile_name}"
Parse the JSON response. The response is an array; the first element's values array
holds the assignments. Display in a readable table:
ts_user_timezone — current assignments on {base_url}
Org Level Principal Timezone
──────────────── ────── ───────────────── ──────────────────
Primary org — Asia/Kolkata
Primary user guest1 America/New_York
...
Total: {n} assignment(s)
Level is "user" when principal_type == "USER", otherwise "org".
Principal shows principal_identifier for user-level rows, — for org-level.
If the response's values array is empty, show:
No values are currently set for ts_user_timezone on {base_url}.
On API error, show the raw error message from the response.
After displaying results, stop — do not continue to Step 3.
If {operation} is "remove", skip this step — the current value will be looked up
automatically in Step 7 before the API call.
Ask:
Timezone value (IANA format, e.g. Asia/Kolkata, America/New_York, Europe/London):
Validate the format: must contain exactly one / and match the pattern
Continent/City or Region/City (e.g. Asia/Kolkata, America/New_York,
Pacific/Auckland). Common valid prefixes: Africa, America, Antarctica,
Arctic, Asia, Atlantic, Australia, Europe, Indian, Pacific, UTC, Etc.
If the format looks invalid, warn the user:
"{value}" does not look like a valid IANA timezone (expected format: Region/City).
Common examples: Asia/Kolkata, America/New_York, Europe/London, Australia/Sydney.
Continue anyway? (Y / N):
Save {timezone_value}.
Fetch all active orgs:
source ~/.zshenv && ts orgs search --status ACTIVE --profile "{profile_name}"
Parse the JSON array. Each element has an orgName field. Save all names as
{available_orgs}.
If 20 or fewer orgs — show a numbered checklist:
Which org(s) should this apply to? Enter numbers separated by commas (e.g. 1, 3):
1 Primary
2 Sales
3 Engineering
...
Parse input as comma-separated numbers. Save selected names as {org_identifiers}.
If more than 20 orgs — ask by name instead:
{n} orgs found. Enter org name(s), comma-separated (exact match required):
e.g. Primary, Sales, Engineering
Validate each name against {available_orgs}. For any name not found, show:
Org "{name}" not found. Available orgs containing "{name}":
- {close match 1}
- {close match 2}
Re-ask until all names are valid. Save as {org_identifiers}.
Ask:
Apply to:
1 Org level — applies to all users in the org(s)
2 Specific user(s) — search by name or email
3 Users in a group — find users via group membership
Enter 1, 2, or 3:
If 1: set {level} to "org", leave {principal_identifiers} empty.
Ask: Search for user (name or email pattern): Save as {user_search_term}.
source ~/.zshenv && ts users search \
--name "{user_search_term}" \
$(printf -- '--org "%s" ' {org_identifiers}) \
--account-status ACTIVE \
--profile "{profile_name}"
Display results as a numbered list: # | Display Name | Username (email).
name values as
{principal_identifiers}. Set {level} = "user".Ask: Search for group (name pattern): Save as {group_search_term}.
source ~/.zshenv && ts users groups \
--name "{group_search_term}" \
$(printf -- '--org "%s" ' {org_identifiers}) \
--include-users \
--profile "{profile_name}"
Show matching groups as a numbered list: # | Group Name | User count. User picks one group.
Then show the users in that group (from the users array in the response):
Users in "{group_name}":
1 user@example.com
2 another@example.com
...
Apply to all {n} users? (Y) or enter numbers to pick specific ones:
Save selected name values as {principal_identifiers}. Set {level} = "user".
Show a summary before making any changes:
Ready to update ts_user_timezone:
Operation: {operation}
Timezone: {timezone_value} ← omitted if operation is remove
Orgs: {org_identifiers joined with ", "}
Level: {level} level{" — users: " + ", ".join(principal_identifiers) if level == "user" else ""}
Cluster: {base_url}
Proceed? (Y / N):
If N, ask what to change and return to the relevant step.
Build the ts variables set command with one --org flag per org, and one --user flag
per user (if user-level). The CLI builds the cross-product internally:
source ~/.zshenv && ts variables set ts_user_timezone "{timezone_value}" \
--org "{org1}" [--org "{org2}" ...] \
[--user "{user1}" [--user "{user2}" ...]] \
--profile "{profile_name}"
import subprocess, json
result = subprocess.run(
["bash", "-c",
f"source ~/.zshenv && ts variables search ts_user_timezone --profile '{profile_name}'"],
capture_output=True, text=True,
)
data = json.loads(result.stdout)
all_values = data[0].get("values", []) if data else []
current_value = None
for v in all_values:
if "{level}" == "user":
if v.get("principal_type") == "USER" and v.get("org_identifier") in {org_identifiers}:
current_value = v["value"]
break
else:
if v.get("principal_type") is None and v.get("org_identifier") in {org_identifiers}:
current_value = v["value"]
break
If current_value is None, report that no assignment exists for any selected org and stop.
Then remove:
source ~/.zshenv && ts variables remove ts_user_timezone "{current_value}" \
--org "{org1}" [--org "{org2}" ...] \
[--user "{user1}" [--user "{user2}" ...]] \
--profile "{profile_name}"
error key → extract and display the error messageOn success (no output):
ts_user_timezone updated.
Operation: {operation}
Timezone: {timezone_value} ← omitted if operation is remove
Orgs: {org_identifiers joined with ", "}
Applied at: {level} level{" — users: " + ", ".join(principal_identifiers) if level == "user" else ""}
Cluster: {base_url}
On error:
API call failed.
Error: {error_message}
Common causes:
- Timezone value is not recognised by ThoughtSpot (check IANA spelling)
- Username does not exist in the specified org
- Org name is incorrect (check exact capitalisation)
- ts_user_timezone variable does not exist on this cluster
| Symptom | Action |
|---|---|
ts auth whoami returns 401 | Token expired — follow refresh steps in /ts-profile-thoughtspot |
SSLCertVerificationError | Set "verify_ssl": false in ~/.claude/thoughtspot-profiles.json for this profile |
| API returns 404 on the variable endpoint | ts_user_timezone variable may not exist on this cluster — ask admin to create it |
API returns 400 with variable_assignment error | Request body is malformed — check that operation (REPLACE/REMOVE) and variable_values are set correctly |
| Timezone not applied after update | Token may be stale in the ThoughtSpot session — ask the user to log out and back in |
| Version | Date | Summary |
|---|---|---|
| 2.0.0 | 2026-05-11 | Refactor to use ts CLI commands: ts variables search/set/remove, ts orgs search, ts users search, ts users groups — removes all curl boilerplate |
| 1.5.0 | 2026-05-11 | Step 5: user search (by name/email) and group-based user selection; multi-user scope support |
| 1.4.0 | 2026-05-11 | Step 4: adaptive UX — numbered checklist for ≤20 orgs, name entry with validation for >20 |
| 1.3.0 | 2026-05-11 | Step 4: fetch org list from API and present numbered checklist; support multiple orgs in one call |
| 1.2.0 | 2026-05-11 | Step 5: replace "press Enter for org level" with explicit 1/2 menu (Enter doesn't work in Claude Code chat) |
| 1.1.0 | 2026-05-11 | Fix API endpoint and schema: use global /update-values with variable_values/operation fields; fix Remove to look up current value before calling REMOVE |
| 1.0.0 | 2026-04-27 | Initial release — search, set, and remove timezone values for ts_user_timezone |