{"version":"2.1.247","anchor":"configurable-spinner-tips-file-loaded-object-shaped-with-a-c","canonical_anchor":"configurable-spinner-tips-file-loaded-object-shaped-with-a-c","heading":"Configurable spinner tips: file-loaded, object-shaped, with a custom label","tier":"use","area":"Settings","scope":null,"heads_up":null,"url":"https:\/\/changelogs.core-directive.com\/v\/2.1.247\/e\/configurable-spinner-tips-file-loaded-object-shaped-with-a-c","release_url":"https:\/\/changelogs.core-directive.com\/v\/2.1.247","markdown":"### Configurable spinner tips: file-loaded, object-shaped, with a custom label\n\nspinnerTipsOverride now takes an object: load tips from a file, relabel them, and drop the built-ins.\n\n**What**\n\nThe `spinnerTipsOverride` setting is now a full object rather than a list of strings, letting you supply tips inline or from a JSON file, replace the \"Tip\" prefix with your own label, and drop the tips that ship with Claude Code. Individual tips can carry an identifier, a per-tip cooldown and a priority weight so a curated set rotates the way you want. Parsing is lenient throughout, so a malformed field or entry is dropped rather than breaking settings loading, and what a scope is allowed to set depends on whether that scope is trusted.\n\n**Details**\n\n- The object takes `tips` (the list itself), `tipsFile` (a path to a JSON file of the same shape), `label` (replaces the default \"Tip\" prefix), and `excludeDefault` (drops the built-in tips).\n- A tip entry is either a plain string or an object of the form `{ id, text, cooldownSessions?, priority? }`; array members that are neither are dropped without rejecting the rest of the list.\n- `id` is a stable identifier of letters, digits, `.`, `_` and `-`, up to 64 characters; `text` is capped at 500 characters and must be a single line.\n- `cooldownSessions` (default 0) is how many sessions to wait before showing a tip again; `priority` (default 0) breaks ties among tips that have never been shown.\n- `spinnerTipsOverride` is now read from project scope too, but project settings are untrusted: only plain strings are accepted there, and object entries are dropped with the warning `spinnerTipsOverride: object tip entries in ${s} are ignored; only plain strings are read from project settings`, where the placeholder names the scope.\n- `tipsFile` and `label` are ignored entirely when they come from an untrusted scope; `tipsFile` is honoured only from user settings, the `--settings` flag, and managed settings installed on disk, and is read once per CLI process.\n- A `tipsFile` arriving through remote managed settings is refused with `spinnerTipsOverride.tipsFile from remote managed settings is ignored; ship inline tips or install the file path via managed-settings.json`.\n- File load failures are logged and counted under the `tips_org_tips_file_load` metric.\n- The built-in tips are suppressed only when a trusted scope supplied tips, so if only a project supplied them the shipped defaults still show.\n- The spinner reads the label from application state as `spinnerTipLabel` and applies it to the narration tip; when the label is still the default \"Tip\" it renders lower-cased.\n\n**Evidence**\n\n`{ id: stable id (letters, digits, \".\", \"_\", \"-\"; max 64), text: the tip (max 500 characters, one line), cooldownSessions?: sessions to wait before showing it again (default 0), priority?: tie-break weight among never-shown tips (default 0) }`, `spinnerTipsOverride: object tip entries in ${s} are ignored; only plain strings are read from project settings`, `spinnerTipsOverride.tipsFile from remote managed settings is ignored; ship inline tips or install the file path via managed-settings.json`, `spinnerTipLabel`\n\n- Area: Settings\n- Names: `spinnerTipsOverride`\n- Tier: Use it now\n- Useful: 4\/5\n- Signal: 2\/5"}