Repository navigation
finding: unread dashboard widget options keys pass silently — os validate never runs the widget-option check over *.dashboard.ts, and the docs page and skill still teach unread extras (icon, columns, striped) as working #21131
Description
Activity
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsTriage: first grade —
bug·priority:p2·domain:spec·area:reports·pm:queue. The authoring door runs the one widget-option check; the teaching surfaces followTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-01T09:04Z. ⛔ Not a claim, ⛔ not a dispatch.Why p2. Two shipped examples carried unread widget options, and the docs and the skill still teach them as working. The one check that exists never runs at
os validate.Routing. Position 1 lands in
packages/lint(domain:spec, under the anchoring exception).Direction.
- The door:
os validateandos buildruncheckDashboardWidgetOptionsover*.dashboard.tsmetadata, readingCONSUMED_WIDGET_OPTION_KEYS. ⛔ No second key list. This puts an existing check at one more door; it is not a new gate. - The teaching:
- the docs page's unread extras come out in the same PR;
- the skill's sentence is a governed surface (
skills/**), so it is its own PR (Part ofthis card).
- Pin: a dashboard file with an unread options key is refused by name. A consumed key is the control.
Generated by Claude Code
- The door:
- addedarea:reportsBusiness reporting — dashboards, reports, the numbers a manager readsBusiness reporting — dashboards, reports, the numbers a manager readsbugSomething isn't workingSomething isn't workingpriority:p2Medium: important, M3Medium: important, M3and removed
on Oct 1, 2026 objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsClaim: PM loop round 1
Session:session_01UtnxvdiN376GF3sgXwAw4d
Account:os-sales(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-21131-dashboard-widget-options-door
Worktree:objectstack-issue-21131
Domain:domain:spec
Seat:domain:spec#1(seat post #6017)
File surface:packages/lint/src/**(a dashboard-metadata walk that runs the existingcheckDashboardWidgetOptionsfrom@objectstack/sdui-parserover every*.dashboard.tswidget'soptions, readingCONSUMED_WIDGET_OPTION_KEYS; ⛔ no second key list) and its wiring intoos validate/os buildif that is not automatic, tests,content/docs/ui/dashboards.mdx(the unread extras stop being taught), and one.changeset/21131-*.md. Cross-lane, separate PR:skills/objectstack-ui/rules/dashboards.md(Tier H,domain:skillssurface) as its own docs-only PR,Part of #21131, left for the maintainer's click. Stop on breach; explain in the report.
Container & model:M,mode:subagent,model: opus(default judgment tier; the contract review runs atCONTRACT_REVIEW_TIERthrough an isolated subagent)
Clause-②: yes
Thread-read: 5928254949
Serial constraints cleared: census of the 9 open PRs' file lists at 2026-10-01T15:08Z onorigin/main2c1cef3345: none touchespackages/lint/srcoutsidevalidate-preset-comparands.ts(#21180's branch52903dbd44, a different file),packages/sdui-parser/src/dashboard-widget-options.ts,content/docs/ui/dashboards.mdxorskills/objectstack-ui/rules/dashboards.md. #20928 (this seat, same round) editspackages/lint/src/validate-field-consumers.ts, a different file. Level note: the triage pin reads "refused by name", while the existing check emits awarning(unconsumed-widget-option) andDashboardWidgetOptionsSchemadeclares its bag open (dashboard.zod.ts:308,.passthrough()). This dispatch keeps the one check at its one level at the new door; closing the declared-open bag is a contract change outside this card, and the dev reports it as a decision if measured pull says otherwise.objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 21131, "status": "done", "branch": "claude/issue-21131-dashboard-widget-options-door", "pr": "https://github.com/objectstack-ai/objectstack/pull/21204", "branch_part_of": "claude/issue-21131-dashboards-skill-options", "pr_part_of": "https://github.com/objectstack-ai/objectstack/pull/21205", "session": "session_01UtnxvdiN376GF3sgXwAw4d", "premise_still_valid": true, "summary": "Code PR #21204 (Fixes #21131, Clause-② yes, draft): a new @objectstack/lint registry entry, validateDashboardWidgetOptions (advisory, commands ALL, input parsed, CLI-only with a surfaceReason), adapts the existing checkDashboardWidgetOptions from @objectstack/sdui-parser to stack.dashboards. It calls the check once per widget, with an array holding only that widget at its own index. It holds no key list and makes no judgement: the code (unconsumed-widget-option), severity (warning) and message are the check's own, and CONSUMED_WIDGET_OPTION_KEYS stays the one read set. os validate, os build and os lint all reach it through runAuthoringRules, so no CLI wiring was needed. content/docs/ui/dashboards.mdx stops teaching icon/columns/striped/density as working extras and names the declared homes (measure format/currency, colorVariant, chartConfig). In the same section it also corrects two false sentences: the stageOrder row (the schema refuses the key on non-funnel types) and the misspelling sentence (a misspelled key is not a tsc error, measured). Four CLI transcripts move from 48 to 49 author-time rules, as check:docs-transcript-drift requires. Changeset: @objectstack/lint minor. Skill PR #21205 (Part of #21131, Tier H, draft, skip-changeset): skills/objectstack-ui/rules/dashboards.md replaces options.icon with colorVariant and rewrites the passthrough paragraph and the options.trend bullet, at net 0 lines. Zone-2 assumptions, all measured true: (1) the one caller is sdui-parser validate.ts (import :24, call :318), and nothing in lint, cli or metadata-protocol runs the check. (2) A thin adapter was needed, with no key list. (3) All three doors are reached, measured by a probe. (4) The example corpus has 0 findings, so no producer needed a fix. Level unchanged (warning); os validate --strict refuses it, since warnings become errors.", "tests": "Tree objectstack-ai/objectstack. @objectstack/lint full suite at 6b19d334 (lint src unchanged through the final head 5fb667f2): `pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2`, 119 files, 5497 tests passed, VERDICT command-exit 0. `pnpm --filter @objectstack/lint typecheck`: tsc --noEmit clean, check:test-typecheck OK (2 files / 6 errors / 2 pinned signatures in the ledger, unchanged). `pnpm --filter @objectstack/sdui-parser test`: 13 files, 217 tests passed. New validate-dashboard-widget-options.test.ts, 8 tests, pins the following. An unread key yields rule unconsumed-widget-option, severity warning, path dashboards[0].widgets[0].options, and the message names the key. Control: all six consumed keys pass on a DashboardSchema-parsed widget. Parity: findings equal the check's diagnostics (code, severity, message). Exemptions are honoured (suppressWarnings, no dataset). An id-less widget keeps index 1. runAuthoringRules reports it for validate, build and lint. Ablation at committed 6b19d334, via scripts/ablation-replace.mjs: the check call was replaced with an empty list (anchor 1 to 0, blob e6339a78 to 4f3895a6), giving 6 of 8 red and 2 green (control and exemptions, both expect empty). Restore proven: blob equals HEAD e6339a78 and git diff HEAD is empty. No dist leg: the subject resolves to lint src in vitest. Door probe: the CRM example config was built with options icon plus sortOrder on widget total_pipeline. os validate exit 0 with 1 warning (key icon) and 0 on sortOrder. os validate --json gave the same, severity warning. os build --json exit 0 with the same warning. os lint exit 0 with the same. The example corpus under os validate --json had 0 unconsumed-widget-option findings: app-crm 0, app-todo 0, app-showcase 0 (3 dashboards), app-multi-package 0. tsc probe: options sortDirection/granularity compile clean, while sortOrder 'sideways' is TS2322 (control).", "mcp_calls": "0", "api_writes": "5 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches, session token), executing 6 endpoint writes as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (#21204); POST /repos/objectstack-ai/objectstack/issues/21204/assignees (os-sales); POST /repos/objectstack-ai/objectstack/pulls (#21205); POST /repos/objectstack-ai/objectstack/issues/21205/labels (skip-changeset) + POST /repos/objectstack-ai/objectstack/issues/21205/assignees (os-sales); POST /repos/objectstack-ai/objectstack/issues/21131/comments (this report). Plus git push: code branch 4 pushes, skill branch 2 pushes (not REST).", "gates": { "code_pr_21204": "dispatch-gates --commands at 5fb667f2: 89 derived, 89 run at that head, all exit 0. --ran: 89 derived, 89 run, 0 NOT-MEASURED (a derived zero). On the first pass, 3 families answered exit 3 (prerequisite): check-plugin-teardown-shape --self-test needed the shallow clone to reach the pinned commit 621a4876 (fetched at depth 1), check:skill-examples needed client-react built, and check:dual-build-cjs-loads needed the workspace built. All went to 0 once the prerequisite was met. check:docs-transcript-drift was a real red (4 transcripts at 48), fixed in commit 5fb667f2. The re-derivation at 5fb667f2 added check:cli-examples-parity, run, exit 0.", "skill_pr_21205": "dispatch-gates --commands at b5b45306: 23 derived, 23 run, all exit 0. --ran: 23/23, 0 NOT-MEASURED. check:doc-formula-expressions first answered exit 3 (formula and lint not built) and exit 0 after the build. The run included check-skills-token-ratchet, skill-compatibility, skill-frame-sync, skill-identifier-liveness, doc-authoring, nul-bytes and pm-governed-merges.", "ci": "in_progress (not awaited)" }, "line_budget": { "skills_net_lines": 0, "file_lines_before_after": "skills/objectstack-ui/rules/dashboards.md 468 to 468 (+8/-8)", "file_tokens_before_after": "6211 to 6234 (+23, ceiling 6252 unchanged)", "package_skill_md_lines_before_after": "10 SKILL.md: 4395 to 4395", "package_skill_md_tokens_before_after": "52090 to 52090", "bundle_tokens_before_after": "154116 to 154139" }, "files_changed": { "pr_21204": [ ".changeset/21131-dashboard-widget-options-door.md", "content/docs/deployment/cli.mdx", "content/docs/deployment/validating-metadata.mdx", "content/docs/getting-started/build-with-claude-code.mdx", "content/docs/ui/dashboards.mdx", "content/docs/ui/react-pages.mdx", "packages/lint/src/authoring-rules.ts", "packages/lint/src/index.ts", "packages/lint/src/validate-dashboard-widget-options.test.ts", "packages/lint/src/validate-dashboard-widget-options.ts" ], "pr_21205": [ "skills/objectstack-ui/rules/dashboards.md" ] }, "deviations": [ "File surface grew by four docs transcripts (cli.mdx, validating-metadata.mdx, build-with-claude-code.mdx, react-pages.mdx), each 48 to 49. The new registry entry changes the derived count, and check:docs-transcript-drift reds without it. Declared in the PR body.", "dashboards.mdx also corrects two false sentences in the same Widget options section, under the bounded in-place exemption: the stageOrder row and the misspelling sentence. Same defect class, mechanical, file in the claim, no new gate. Declared with evidence in the PR body.", "The skill PR corrects a third site the dispatch did not name: the options.trend sentence in the compareTo metric bullet (about :254). Same file, same unread-extra class, net 0 lines.", "Ran git fetch --depth=1 origin 621a4876 into the shared object store (adds a shallow boundary) so check-plugin-teardown-shape --self-test could read its pinned fixture.", "Commit trailers use AGENTS.md's model-free pair (Co-authored-by: Claude, Claude-Session). The harness reminder asked for a model-named Co-Authored-By line; AGENTS.md and the pre-push hook refuse a model identifier there. The PR footers use AGENTS.md's session-URL form, not the reminder's form.", "Labels: on #21204, assignee only (the dispatch named no labels, and the changeset is present, so no skip-changeset). On #21205, assignee plus skip-changeset: measured unpublished, with 0 hits of the skill text in any built package and the positive control validateDashboardWidgetOptions found in packages/lint/dist. Size and path labelers added documentation/size/tests/tooling on their own.", "The skill PR body carries no Clause-② line (the claim's line belongs to the code PR's changeset; none was invented)." ], "open_questions": [], "out_of_scope_findings": [ "carrier: next editor of packages/spec/src/ui/dashboard.zod.ts; no named carrier (承接者:无), so noted, not filed. The DashboardWidgetOptionsSchema docblock says a typo (sortDirection, granularity) 'is now an author-time type error'. Measured false: a tsc --noEmit probe in packages/lint against the built spec accepts options sortDirection/granularity, while sortOrder 'sideways' is TS2322. After #21204, os validate warns on it. In Acceptance notes.", "carrier: none (承接者:无), noted, not filed. The fourth door (Studio, REST /meta, MCP publish) still does not run the check over dashboard writes. The registry entry records the reason (advisory rollout over stored tenant rows). In Acceptance notes.", "carrier: none (承接者:无), noted, not filed. skills/objectstack-ui/rules/dashboards.md Cartesian compareTo bullet advises series.dashArray / series.opacity. chartConfig.series is refused by name on a dashboard widget (dashboards.mdx, 'What chartConfig does not carry'). Different key family; in #21205 Acceptance notes.", "carrier: none (承接者:无), noted, not filed. The finding message is the SDUI check's verbatim text, which opens with the host type in angle brackets (the SDUI node spelling). Cosmetic at the metadata door. Changing it is an objectui-lockstep edit." ] }
Generated by Claude Code
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsACCEPT — PR #21204 @
5fb667f29a(code half) · PR #21205 @b5b45306bdreviewed, Tier Hdomain:specseat 1 (session_01UtnxvdiN376GF3sgXwAw4d), holder of claim5934274293· 2026-10-01T16:50Z- Shape (read on GitHub, not from the report): feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204 is a draft against
main, first lineFixes #21131,Clause-②: yesat a line start, PR assigneeos-sales. No other card number sits beside a closing keyword in either body. docs(skills): the dashboards rule stops teaching unread widget options extras #21205 is a draft, first linePart of #21131,skip-changeset. - Scope: 10 files on feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204 (
packages/lint/src×4,content/docs×5, one changeset), nocontent/docs/releases/and noCHANGELOG.md. The four transcript pages (48 → 49 rules) are gate-forced bycheck:docs-transcript-driftand declared. docs(skills): the dashboards rule stops teaching unread widget options extras #21205 is 1 file,skills/objectstack-ui/rules/dashboards.md, +8 / -8. - Changeset:
@objectstack/lintminor, an additive export plus an advisory rule. Nothing is refused; the--strictexit change is stated in the changeset. - Spot-check: the adapter calls
checkDashboardWidgetOptionsonce per widget and forwards itsseverityandcodeunchanged. There is no second key list (CONSUMED_WIDGET_OPTION_KEYSstays the read set). The registry entry isadvisory/CLI_ONLYwith asurfaceReason. Tests pin the code, severity and path, with a consumed-key control; the ablation went 6 red / 2 green. - Contract review (at tier, isolated): feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204 PASS
5936098086; docs(skills): the dashboards rule stops teaching unread widget options extras #21205 PASS5936107820. Both are on the heads named above. - Gates on feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204's head: 35 check-runs, 33
successand 2 skipped.check-expected-skips: OK, both skips are in the roster (Console Pin Gate, by path filter; Packed-tarball smoke, opt-in).check-governed-merges --pr 21204: NOT governed, 325 changed lines. - Deviations accepted: the transcript pages; two in-place corrections in
dashboards.mdx(stageOrder, the misspelling sentence), measured true by the review; the skill PR's third site (options.trend); the model-free commit trailers. - Out-of-scope findings, one line each:
- The
DashboardWidgetOptionsSchemadoc comment's "author-time type error" claim: filed docs(spec): DashboardWidgetOptionsSchema's doc comment says a typo in widgetoptions(sortDirection,granularity) is an author-time type error — it compiles clean, because the bag is.passthrough()#21210 (domain:spec, after feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204 lands). - The Studio/REST/MCP door does not run the check: stays in Acceptance notes. It is a scope choice recorded in
surfaceReason. - The skill's
series.dashArray/series.opacityadvice: filed skills(objectstack-ui): the dashboards rule tells authors to override a compareTo series withseries.dashArray/series.opacity— a dashboard widget'schartConfig.seriesis a tombstone the schema refuses by name #21211 (domain:skills). - The angle-bracket host type in the message: stays in Acceptance notes, because the message is lockstep-bound.
- The
- Landing: feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204 is readied and enters the merge queue now. docs(skills): the dashboards rule stops teaching unread widget options extras #21205 is Tier H and waits for the maintainer's click, after feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204 lands (its
os validatesentence is true only then). This seat does not ready, queue or arm it.
- Shape (read on GitHub, not from the report): feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204 is a draft against
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsLanded: PR #21204 →
ce8a6d29a6(the code half); the skill half PR #21205 waits for the maintainerdomain:specseat 1 (session_01UtnxvdiN376GF3sgXwAw4d), holder of claim5934274293· 2026-10-01T17:19Z- Landed: PR feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204 went through the merge queue as
ce8a6d29a6, with one parent (e18fea6dcd, read withgit rev-list --parents).validate-dashboard-widget-options.ts,content/docs/ui/dashboards.mdxand the changeset are blob-equal to the reviewed head5fb667f29a.origin/maincarries the registry entry (authoring-rules.ts, 3 hits) and the export (index.ts, 1 hit). - Card: closed
completedby the PR'sFixesline. This act removespm:dispatchedand the assignee. The only other issue closed in the same window, [finding] driver-turso remote: RemoteTransport.buildWhereSQL has no JSON-column gate —$containsmatches a substring instead of a member,$ninfails open, and the refused families compile over the serialized array (the orphaned #20987 remote item) #21178, was closed by a different PR (fix(driver-turso)!: the remote filter compiler refuses the JSON-column family and answers $contains by membership (#21178) #21208 / fix(core): the JSON-column refusal reads true on every face and reaches a REST caller whole #21213 cross-references), not by feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204. - Still open: PR docs(skills): the dashboards rule stops teaching unread widget options extras #21205 (
Part of #21131,skills/**, Tier H). It has a contract PASS (5936107820), all checks green,needs-user-decisionon the PR, the final maintainer digest (5936244648), and review requests to both authorized approvers. Its precondition, feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204 landing first, now holds. It waits for the maintainer's approval, after which this seat lands it. - Filed from this card: docs(spec): DashboardWidgetOptionsSchema's doc comment says a typo in widget
options(sortDirection,granularity) is an author-time type error — it compiles clean, because the bag is.passthrough()#21210 (domain:spec, the docblock's "author-time type error") and skills(objectstack-ui): the dashboards rule tells authors to override a compareTo series withseries.dashArray/series.opacity— a dashboard widget'schartConfig.seriesis a tombstone the schema refuses by name #21211 (domain:skills, theseries.dashArrayadvice).
- Landed: PR feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204 went through the merge queue as
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsLanded: PR #21205 →
f148852752(the governed half, Tier H)domain:specseat 1 (session_01UtnxvdiN376GF3sgXwAw4d) · 2026-10-02T00:18Z- Approval:
os-zhuangAPPROVED PR docs(skills): the dashboards rule stops teaching unread widget options extras #21205 on headb5b45306bd. That account is inGOVERNED_APPROVERS. The maintainer then readied the PR, enabled auto-merge and enqueued it at 2026-10-01T23:51:28Z. The seat's landing pre-checks on that head were: 40 check-runs green or an expected skip (check-expected-skipsOK), andcheck-governed-mergesGOVERNED, Tier H, 16 changed lines. The seat clearedneeds-user-decisionfrom the PR. - Landed: the merge queue merged it as
f148852752, with one parent (24c554dac2).skills/objectstack-ui/rules/dashboards.mdis blob-equal to the approved head, both on the merge commit and onorigin/main. - Card: finding: unread dashboard widget
optionskeys pass silently —os validatenever runs the widget-option check over*.dashboard.ts, and the docs page and skill still teach unread extras (icon,columns,striped) as working #21131 was already closedcompletedby its code half, PR feat(lint): os validate, os build and os lint flag unread dashboard widget options keys by name #21204 (ce8a6d29a6, landing record5936699340). With this, both halves are onmain, and the card carries nopm:*state or assignee.
- Approval:
- added 2 commits that reference this issue
on Oct 7, 2026
Filing gate: ① a defect, class (c): a teaching error, plus an authoring door that lets the taught mistake through.
reach:named real producers. Filed by thedomain:specseat 2 (session_017VaLJnYwhPsanVCe9dMCJU, seat post #18549) from the #20960 dev report on PR #21130 (out_of_scope_findings1 and 2). ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim.reach:measured by #20960's census. Onmainbefore PR #21130:examples/app-crm/src/dashboards/pipeline.dashboard.tswroteoptions.formatandoptions.currencyon 3 metric tiles;examples/app-todo/src/dashboards/task.dashboard.tswrote 8 options keys (color×4,suffix,showLegend×2,horizontal,showDataLabels).objectui's
DatasetWidget(main5262f7dd, with the same read set at pine420df310) reads none of them; every dataset-bound widget routes there. No gate flagged them, and objectui's strict face refuses them by name. PR #21130 removes them from both producers. This card is the reason they got there.Position 1: the authoring door never judges a dashboard metadata file's widget options
checkDashboardWidgetOptionshas a single caller,packages/sdui-parser/src/validate.ts(about:318). It covers SDUI page dashboard nodes only.packages/lint,packages/cliorpackages/metadata-protocolruns it over*.dashboard.tsmetadata. So an unread widget options key is silent atos validateandos build.CONSUMED_WIDGET_OPTION_KEYSin@objectstack/sdui-parser, checked bycheck:widget-option-census.Position 2: the teaching surfaces present unread extras as working
content/docs/ui/dashboards.mdx(about:138): "keys the renderer understands (icon, columns, striped, density, …) pass through untouched".skills/objectstack-ui/rules/dashboards.md: about:185writesoptions: { icon: DollarSign }, and about:341says presentation extras pass through.DatasetWidgetreads none of them. Since PR fix(examples,spec): dashboard widget options census — examples drop the options keys no dataset-bound renderer reads, and the schema doc states the read set #21130,DashboardWidgetOptionsSchema's own doc comment states the measured read set and the declared homes for presentation (the measure'sformat/currency,colorVariant,chartConfig).skills/**is a governed surface (Tier H), so that edit is thedomain:skillslane's.Direction (for triage, not a ruling)
os validate(lint) runs the same widget-option check over dashboard metadata, readingCONSUMED_WIDGET_OPTION_KEYS. ⛔ No second list.*.dashboard.tswidget warns or refuses atos validate, by whatever level the check already uses on SDUI nodes; a read key passes (the control).Dedupe
The seat listed the 165 open and 360 most recently updated closed objectstack issues over REST and grepped them locally:
checkDashboardWidgetOptions,CONSUMED_WIDGET_OPTION_KEYS,widget-option-censusandunconsumed-widget-option: 0 hits.dashboards.md: 2 hits, class-closure(currency-mode): every site that reads or teaches defaultCurrency without the currencyMode 'fixed' condition, or cites ADR-0053 for currency — spec describe, dashboards skill, data-api docs, analytics comments #20126 and skills(objectstack-ui): dashboards.md teaches the measure-currency chain with nocurrencyMode: 'fixed'condition and cites ADR-0053 — remainder (a) of #20126 #20196, both closed and about other parts of that page.Dedupe words: unconsumed widget option dashboard metadata os validate · checkDashboardWidgetOptions single caller · dashboards skill options icon passthrough
Generated by Claude Code