docs(skills): document the action and component nav item types - #14138

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows
Sep 1, 2026
Merged

docs(skills): document the action and component nav item types#14138
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13890

The published skills/objectstack-ui "Navigation Item Types" table listed 7 of the 9 live
NavItemVariant members: action and component had no row, in a section whose heading
names the catalog and whose other seven rows are present — so an AI author reading it
could not reach either variant.

Part of #13658. The objectstack twin of the fix the objectui sweep landed in that repo's
skills/objectui/guides/app-composition.md; the rows here are written in this table's own
Type | Properties | Purpose idiom rather than copied.

Member set, verified against the schema

The live set is read out of the schema at runtime — hand the discriminated union a bogus
type and print the options it names, rather than trusting the card's "9" or the
NavItemVariant type alias:

DISCRIMINATOR OPTIONS (from the schema): ["object","dashboard","page","url","report","action","component","separator","group"]
COUNT: 9
ISSUE: invalid_union | Invalid discriminator value. Expected 'object' | 'dashboard' | 'page' | 'url' | 'report' | 'action' | 'component' | 'separator' | 'group'

Nine members; the two absent from the table are exactly action and component.
packages/spec/src/ui/app.zod.ts backs each row: ActionNavItemSchema requires
actionDef, itself a strict object of actionName plus an optional open params;
ComponentNavItemSchema requires componentRef (a ComponentRegistry key such as
metadata:resource) with an optional open params passed to the component as props.
Neither variant accepts childrenNAV_VARIANTS_ACCEPTING_CHILDREN is object and
group only — so neither row lists it.

pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/ui/app.test.ts
102 passed (1 file), including the pin that parses all nine variants with their full
declared payloads.

Rows added

| `action` | `actionDef` (`{ actionName, params? }`), `label`, `icon` | Run an action instead of navigating |
| `component` | `componentRef`, `params?`, `label`, `icon` | Built-in platform component; `componentRef` is a colon-joined registry key (`metadata:resource`), `params` become props |

Token budget — funded by deletion in the same file, no ceiling raise

The file sat at its ceiling with headroom 0, so the two rows are paid for by removing text,
not by moving a ceiling. Verdict lines from node scripts/check-skills-token-ratchet.mjs:

before: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25445 tokens (ceiling 25445; headroom 0).
after: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25441 tokens (ceiling 25445; headroom 4).

Funding source — two Common Pitfalls entries deleted, neither of which carries a fact the
file does not state better elsewhere (a real deletion, not a re-wrap; the ceiling constant
is untouched):

  • "Using provider: 'api' when provider: 'object' is available" — a strict subset of
    the Data Source best-practice block a thousand lines above, which is the richer of the two
    (it also names automatic CRUD).
  • "Not setting quick filters … always add a 'My Records' filter" — superseded by the
    ADR-0047 userFilters section in the same file, which prescribes the opposite default:
    "Omit userFilters when unsure … most views need no filter elements at all." Keeping
    both left the skill teaching two contradictory defaults.

Required skills/** readings, lines and tokens (token unit is the ratchet's own
ceil(utf8 bytes / 4)):

ReadingBeforeAfterDelta
skills/objectstack-ui/SKILL.md, whole file — lines21112105-6
skills/objectstack-ui/SKILL.md, whole file — tokens2544525441-4
Whole published package, all 11 SKILL.md — lines1053310527-6
Whole published package, all 11 SKILL.md — tokens118696118692-4

Both readings are net negative: the catalog gets two missing rows and gets shorter.

Ledger

scripts/check-skill-identifier-liveness.mjs records this gap in
scripts/skill-identifier-liveness-ledger.json under leg2Gaps.navigation-item-types, and
refuses an improvement that does not ratchet it down. Second commit does exactly that; the
gate now reports Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s).

Gates

Full derived union at HEAD c587bd7ff, from
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands run
against that same commit (21 commands over the 2 changed paths), plus check:nul-bytes.
Exit codes captured before any pipe. 21 green; one NOT MEASURED:

  • node scripts/check-test-completeness.mjs exits 3 with no argument by design — it parses
    a saved turbo run test log, which a local family run has none of. Its own text says this
    is not a red and there is nothing here to fix.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3
    (PREREQUISITE NOT MET) because @objectstack/formula and @objectstack/lint were not
    built in this fresh worktree; after building both it exits 0 at the same HEAD.

No changeset: the diff publishes nothing from any package, so the PR carries
skip-changeset.

Landing

skills/** is a governed surface — this PR stays a draft and is merged by the
maintainer, by hand. No auto-merge, no queue.

Session: session_01Msg17tAHJ3jVTYFgHydCm2.

Generated by Claude Code


Generated by Claude Code

The objectstack-ui Navigation Item Types table listed 7 of the 9 live
discriminated-union members; `action` and `component` had no row, so an
author reading the published skill could not discover either target.
Funded within the file's token ceiling (headroom was 0) by deleting two
Common Pitfalls entries that carry no fact the file does not state better
elsewhere:
- pitfall 1 restated the Data Source best-practice block verbatim (and that
block is the richer of the two -- it also names automatic CRUD);
- pitfall 4 ("always add a quick filter") is superseded by the ADR-0047
userFilters section, which prescribes the opposite default: omit
`userFilters` when unsure, most views need no filter elements at all.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
The recorded NavItemVariant gap of 2 (action, component) is closed by the
table rows in the previous commit; the gate refuses an improvement that
leaves budget behind for a later edit to spend silently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
@os-zhuang
os-zhuang marked this pull request as ready for review September 1, 2026 07:19
@os-zhuang
os-zhuang added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0ff3d96Sep 1, 2026
34 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-13890-nav-item-types-rows branch September 1, 2026 07:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skills/objectstack-ui "Navigation Item Types" documents 7 of the 9 live NavItemVariant members — action and component have no row

2 participants

@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

docs(skills): document the action and component nav item types - #14138

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows
Sep 1, 2026
Merged

docs(skills): document the action and component nav item types#14138
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13890

The published skills/objectstack-ui "Navigation Item Types" table listed 7 of the 9 live
NavItemVariant members: action and component had no row, in a section whose heading
names the catalog and whose other seven rows are present — so an AI author reading it
could not reach either variant.

Part of #13658. The objectstack twin of the fix the objectui sweep landed in that repo's
skills/objectui/guides/app-composition.md; the rows here are written in this table's own
Type | Properties | Purpose idiom rather than copied.

Member set, verified against the schema

The live set is read out of the schema at runtime — hand the discriminated union a bogus
type and print the options it names, rather than trusting the card's "9" or the
NavItemVariant type alias:

DISCRIMINATOR OPTIONS (from the schema): ["object","dashboard","page","url","report","action","component","separator","group"]
COUNT: 9
ISSUE: invalid_union | Invalid discriminator value. Expected 'object' | 'dashboard' | 'page' | 'url' | 'report' | 'action' | 'component' | 'separator' | 'group'

Nine members; the two absent from the table are exactly action and component.
packages/spec/src/ui/app.zod.ts backs each row: ActionNavItemSchema requires
actionDef, itself a strict object of actionName plus an optional open params;
ComponentNavItemSchema requires componentRef (a ComponentRegistry key such as
metadata:resource) with an optional open params passed to the component as props.
Neither variant accepts childrenNAV_VARIANTS_ACCEPTING_CHILDREN is object and
group only — so neither row lists it.

pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/ui/app.test.ts
102 passed (1 file), including the pin that parses all nine variants with their full
declared payloads.

Rows added

| `action` | `actionDef` (`{ actionName, params? }`), `label`, `icon` | Run an action instead of navigating |
| `component` | `componentRef`, `params?`, `label`, `icon` | Built-in platform component; `componentRef` is a colon-joined registry key (`metadata:resource`), `params` become props |

Token budget — funded by deletion in the same file, no ceiling raise

The file sat at its ceiling with headroom 0, so the two rows are paid for by removing text,
not by moving a ceiling. Verdict lines from node scripts/check-skills-token-ratchet.mjs:

before: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25445 tokens (ceiling 25445; headroom 0).
after: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25441 tokens (ceiling 25445; headroom 4).

Funding source — two Common Pitfalls entries deleted, neither of which carries a fact the
file does not state better elsewhere (a real deletion, not a re-wrap; the ceiling constant
is untouched):

  • "Using provider: 'api' when provider: 'object' is available" — a strict subset of
    the Data Source best-practice block a thousand lines above, which is the richer of the two
    (it also names automatic CRUD).
  • "Not setting quick filters … always add a 'My Records' filter" — superseded by the
    ADR-0047 userFilters section in the same file, which prescribes the opposite default:
    "Omit userFilters when unsure … most views need no filter elements at all." Keeping
    both left the skill teaching two contradictory defaults.

Required skills/** readings, lines and tokens (token unit is the ratchet's own
ceil(utf8 bytes / 4)):

ReadingBeforeAfterDelta
skills/objectstack-ui/SKILL.md, whole file — lines21112105-6
skills/objectstack-ui/SKILL.md, whole file — tokens2544525441-4
Whole published package, all 11 SKILL.md — lines1053310527-6
Whole published package, all 11 SKILL.md — tokens118696118692-4

Both readings are net negative: the catalog gets two missing rows and gets shorter.

Ledger

scripts/check-skill-identifier-liveness.mjs records this gap in
scripts/skill-identifier-liveness-ledger.json under leg2Gaps.navigation-item-types, and
refuses an improvement that does not ratchet it down. Second commit does exactly that; the
gate now reports Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s).

Gates

Full derived union at HEAD c587bd7ff, from
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands run
against that same commit (21 commands over the 2 changed paths), plus check:nul-bytes.
Exit codes captured before any pipe. 21 green; one NOT MEASURED:

  • node scripts/check-test-completeness.mjs exits 3 with no argument by design — it parses
    a saved turbo run test log, which a local family run has none of. Its own text says this
    is not a red and there is nothing here to fix.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3
    (PREREQUISITE NOT MET) because @objectstack/formula and @objectstack/lint were not
    built in this fresh worktree; after building both it exits 0 at the same HEAD.

No changeset: the diff publishes nothing from any package, so the PR carries
skip-changeset.

Landing

skills/** is a governed surface — this PR stays a draft and is merged by the
maintainer, by hand. No auto-merge, no queue.

Session: session_01Msg17tAHJ3jVTYFgHydCm2.

Generated by Claude Code


Generated by Claude Code

The objectstack-ui Navigation Item Types table listed 7 of the 9 live
discriminated-union members; `action` and `component` had no row, so an
author reading the published skill could not discover either target.
Funded within the file's token ceiling (headroom was 0) by deleting two
Common Pitfalls entries that carry no fact the file does not state better
elsewhere:
- pitfall 1 restated the Data Source best-practice block verbatim (and that
block is the richer of the two -- it also names automatic CRUD);
- pitfall 4 ("always add a quick filter") is superseded by the ADR-0047
userFilters section, which prescribes the opposite default: omit
`userFilters` when unsure, most views need no filter elements at all.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
The recorded NavItemVariant gap of 2 (action, component) is closed by the
table rows in the previous commit; the gate refuses an improvement that
leaves budget behind for a later edit to spend silently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
@os-zhuang
os-zhuang marked this pull request as ready for review September 1, 2026 07:19
@os-zhuang
os-zhuang added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0ff3d96Sep 1, 2026
34 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-13890-nav-item-types-rows branch September 1, 2026 07:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skills/objectstack-ui "Navigation Item Types" documents 7 of the 9 live NavItemVariant members — action and component have no row

2 participants

@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(skills): document the action and component nav item types - #14138

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows
Sep 1, 2026
Merged

docs(skills): document the action and component nav item types#14138
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13890

The published skills/objectstack-ui "Navigation Item Types" table listed 7 of the 9 live
NavItemVariant members: action and component had no row, in a section whose heading
names the catalog and whose other seven rows are present — so an AI author reading it
could not reach either variant.

Part of #13658. The objectstack twin of the fix the objectui sweep landed in that repo's
skills/objectui/guides/app-composition.md; the rows here are written in this table's own
Type | Properties | Purpose idiom rather than copied.

Member set, verified against the schema

The live set is read out of the schema at runtime — hand the discriminated union a bogus
type and print the options it names, rather than trusting the card's "9" or the
NavItemVariant type alias:

DISCRIMINATOR OPTIONS (from the schema): ["object","dashboard","page","url","report","action","component","separator","group"]
COUNT: 9
ISSUE: invalid_union | Invalid discriminator value. Expected 'object' | 'dashboard' | 'page' | 'url' | 'report' | 'action' | 'component' | 'separator' | 'group'

Nine members; the two absent from the table are exactly action and component.
packages/spec/src/ui/app.zod.ts backs each row: ActionNavItemSchema requires
actionDef, itself a strict object of actionName plus an optional open params;
ComponentNavItemSchema requires componentRef (a ComponentRegistry key such as
metadata:resource) with an optional open params passed to the component as props.
Neither variant accepts childrenNAV_VARIANTS_ACCEPTING_CHILDREN is object and
group only — so neither row lists it.

pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/ui/app.test.ts
102 passed (1 file), including the pin that parses all nine variants with their full
declared payloads.

Rows added

| `action` | `actionDef` (`{ actionName, params? }`), `label`, `icon` | Run an action instead of navigating |
| `component` | `componentRef`, `params?`, `label`, `icon` | Built-in platform component; `componentRef` is a colon-joined registry key (`metadata:resource`), `params` become props |

Token budget — funded by deletion in the same file, no ceiling raise

The file sat at its ceiling with headroom 0, so the two rows are paid for by removing text,
not by moving a ceiling. Verdict lines from node scripts/check-skills-token-ratchet.mjs:

before: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25445 tokens (ceiling 25445; headroom 0).
after: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25441 tokens (ceiling 25445; headroom 4).

Funding source — two Common Pitfalls entries deleted, neither of which carries a fact the
file does not state better elsewhere (a real deletion, not a re-wrap; the ceiling constant
is untouched):

  • "Using provider: 'api' when provider: 'object' is available" — a strict subset of
    the Data Source best-practice block a thousand lines above, which is the richer of the two
    (it also names automatic CRUD).
  • "Not setting quick filters … always add a 'My Records' filter" — superseded by the
    ADR-0047 userFilters section in the same file, which prescribes the opposite default:
    "Omit userFilters when unsure … most views need no filter elements at all." Keeping
    both left the skill teaching two contradictory defaults.

Required skills/** readings, lines and tokens (token unit is the ratchet's own
ceil(utf8 bytes / 4)):

ReadingBeforeAfterDelta
skills/objectstack-ui/SKILL.md, whole file — lines21112105-6
skills/objectstack-ui/SKILL.md, whole file — tokens2544525441-4
Whole published package, all 11 SKILL.md — lines1053310527-6
Whole published package, all 11 SKILL.md — tokens118696118692-4

Both readings are net negative: the catalog gets two missing rows and gets shorter.

Ledger

scripts/check-skill-identifier-liveness.mjs records this gap in
scripts/skill-identifier-liveness-ledger.json under leg2Gaps.navigation-item-types, and
refuses an improvement that does not ratchet it down. Second commit does exactly that; the
gate now reports Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s).

Gates

Full derived union at HEAD c587bd7ff, from
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands run
against that same commit (21 commands over the 2 changed paths), plus check:nul-bytes.
Exit codes captured before any pipe. 21 green; one NOT MEASURED:

  • node scripts/check-test-completeness.mjs exits 3 with no argument by design — it parses
    a saved turbo run test log, which a local family run has none of. Its own text says this
    is not a red and there is nothing here to fix.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3
    (PREREQUISITE NOT MET) because @objectstack/formula and @objectstack/lint were not
    built in this fresh worktree; after building both it exits 0 at the same HEAD.

No changeset: the diff publishes nothing from any package, so the PR carries
skip-changeset.

Landing

skills/** is a governed surface — this PR stays a draft and is merged by the
maintainer, by hand. No auto-merge, no queue.

Session: session_01Msg17tAHJ3jVTYFgHydCm2.

Generated by Claude Code


Generated by Claude Code

The objectstack-ui Navigation Item Types table listed 7 of the 9 live
discriminated-union members; `action` and `component` had no row, so an
author reading the published skill could not discover either target.
Funded within the file's token ceiling (headroom was 0) by deleting two
Common Pitfalls entries that carry no fact the file does not state better
elsewhere:
- pitfall 1 restated the Data Source best-practice block verbatim (and that
block is the richer of the two -- it also names automatic CRUD);
- pitfall 4 ("always add a quick filter") is superseded by the ADR-0047
userFilters section, which prescribes the opposite default: omit
`userFilters` when unsure, most views need no filter elements at all.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
The recorded NavItemVariant gap of 2 (action, component) is closed by the
table rows in the previous commit; the gate refuses an improvement that
leaves budget behind for a later edit to spend silently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
@os-zhuang
os-zhuang marked this pull request as ready for review September 1, 2026 07:19
@os-zhuang
os-zhuang added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0ff3d96Sep 1, 2026
34 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-13890-nav-item-types-rows branch September 1, 2026 07:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skills/objectstack-ui "Navigation Item Types" documents 7 of the 9 live NavItemVariant members — action and component have no row

2 participants

@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(skills): document the action and component nav item types - #14138

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows
Sep 1, 2026
Merged

docs(skills): document the action and component nav item types#14138
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13890

The published skills/objectstack-ui "Navigation Item Types" table listed 7 of the 9 live
NavItemVariant members: action and component had no row, in a section whose heading
names the catalog and whose other seven rows are present — so an AI author reading it
could not reach either variant.

Part of #13658. The objectstack twin of the fix the objectui sweep landed in that repo's
skills/objectui/guides/app-composition.md; the rows here are written in this table's own
Type | Properties | Purpose idiom rather than copied.

Member set, verified against the schema

The live set is read out of the schema at runtime — hand the discriminated union a bogus
type and print the options it names, rather than trusting the card's "9" or the
NavItemVariant type alias:

DISCRIMINATOR OPTIONS (from the schema): ["object","dashboard","page","url","report","action","component","separator","group"]
COUNT: 9
ISSUE: invalid_union | Invalid discriminator value. Expected 'object' | 'dashboard' | 'page' | 'url' | 'report' | 'action' | 'component' | 'separator' | 'group'

Nine members; the two absent from the table are exactly action and component.
packages/spec/src/ui/app.zod.ts backs each row: ActionNavItemSchema requires
actionDef, itself a strict object of actionName plus an optional open params;
ComponentNavItemSchema requires componentRef (a ComponentRegistry key such as
metadata:resource) with an optional open params passed to the component as props.
Neither variant accepts childrenNAV_VARIANTS_ACCEPTING_CHILDREN is object and
group only — so neither row lists it.

pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/ui/app.test.ts
102 passed (1 file), including the pin that parses all nine variants with their full
declared payloads.

Rows added

| `action` | `actionDef` (`{ actionName, params? }`), `label`, `icon` | Run an action instead of navigating |
| `component` | `componentRef`, `params?`, `label`, `icon` | Built-in platform component; `componentRef` is a colon-joined registry key (`metadata:resource`), `params` become props |

Token budget — funded by deletion in the same file, no ceiling raise

The file sat at its ceiling with headroom 0, so the two rows are paid for by removing text,
not by moving a ceiling. Verdict lines from node scripts/check-skills-token-ratchet.mjs:

before: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25445 tokens (ceiling 25445; headroom 0).
after: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25441 tokens (ceiling 25445; headroom 4).

Funding source — two Common Pitfalls entries deleted, neither of which carries a fact the
file does not state better elsewhere (a real deletion, not a re-wrap; the ceiling constant
is untouched):

  • "Using provider: 'api' when provider: 'object' is available" — a strict subset of
    the Data Source best-practice block a thousand lines above, which is the richer of the two
    (it also names automatic CRUD).
  • "Not setting quick filters … always add a 'My Records' filter" — superseded by the
    ADR-0047 userFilters section in the same file, which prescribes the opposite default:
    "Omit userFilters when unsure … most views need no filter elements at all." Keeping
    both left the skill teaching two contradictory defaults.

Required skills/** readings, lines and tokens (token unit is the ratchet's own
ceil(utf8 bytes / 4)):

ReadingBeforeAfterDelta
skills/objectstack-ui/SKILL.md, whole file — lines21112105-6
skills/objectstack-ui/SKILL.md, whole file — tokens2544525441-4
Whole published package, all 11 SKILL.md — lines1053310527-6
Whole published package, all 11 SKILL.md — tokens118696118692-4

Both readings are net negative: the catalog gets two missing rows and gets shorter.

Ledger

scripts/check-skill-identifier-liveness.mjs records this gap in
scripts/skill-identifier-liveness-ledger.json under leg2Gaps.navigation-item-types, and
refuses an improvement that does not ratchet it down. Second commit does exactly that; the
gate now reports Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s).

Gates

Full derived union at HEAD c587bd7ff, from
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands run
against that same commit (21 commands over the 2 changed paths), plus check:nul-bytes.
Exit codes captured before any pipe. 21 green; one NOT MEASURED:

  • node scripts/check-test-completeness.mjs exits 3 with no argument by design — it parses
    a saved turbo run test log, which a local family run has none of. Its own text says this
    is not a red and there is nothing here to fix.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3
    (PREREQUISITE NOT MET) because @objectstack/formula and @objectstack/lint were not
    built in this fresh worktree; after building both it exits 0 at the same HEAD.

No changeset: the diff publishes nothing from any package, so the PR carries
skip-changeset.

Landing

skills/** is a governed surface — this PR stays a draft and is merged by the
maintainer, by hand. No auto-merge, no queue.

Session: session_01Msg17tAHJ3jVTYFgHydCm2.

Generated by Claude Code


Generated by Claude Code

The objectstack-ui Navigation Item Types table listed 7 of the 9 live
discriminated-union members; `action` and `component` had no row, so an
author reading the published skill could not discover either target.
Funded within the file's token ceiling (headroom was 0) by deleting two
Common Pitfalls entries that carry no fact the file does not state better
elsewhere:
- pitfall 1 restated the Data Source best-practice block verbatim (and that
block is the richer of the two -- it also names automatic CRUD);
- pitfall 4 ("always add a quick filter") is superseded by the ADR-0047
userFilters section, which prescribes the opposite default: omit
`userFilters` when unsure, most views need no filter elements at all.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
The recorded NavItemVariant gap of 2 (action, component) is closed by the
table rows in the previous commit; the gate refuses an improvement that
leaves budget behind for a later edit to spend silently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
@os-zhuang
os-zhuang marked this pull request as ready for review September 1, 2026 07:19
@os-zhuang
os-zhuang added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0ff3d96Sep 1, 2026
34 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-13890-nav-item-types-rows branch September 1, 2026 07:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skills/objectstack-ui "Navigation Item Types" documents 7 of the 9 live NavItemVariant members — action and component have no row

2 participants

@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

docs(skills): document the action and component nav item types - #14138

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows
Sep 1, 2026
Merged

docs(skills): document the action and component nav item types#14138
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13890

The published skills/objectstack-ui "Navigation Item Types" table listed 7 of the 9 live
NavItemVariant members: action and component had no row, in a section whose heading
names the catalog and whose other seven rows are present — so an AI author reading it
could not reach either variant.

Part of #13658. The objectstack twin of the fix the objectui sweep landed in that repo's
skills/objectui/guides/app-composition.md; the rows here are written in this table's own
Type | Properties | Purpose idiom rather than copied.

Member set, verified against the schema

The live set is read out of the schema at runtime — hand the discriminated union a bogus
type and print the options it names, rather than trusting the card's "9" or the
NavItemVariant type alias:

DISCRIMINATOR OPTIONS (from the schema): ["object","dashboard","page","url","report","action","component","separator","group"]
COUNT: 9
ISSUE: invalid_union | Invalid discriminator value. Expected 'object' | 'dashboard' | 'page' | 'url' | 'report' | 'action' | 'component' | 'separator' | 'group'

Nine members; the two absent from the table are exactly action and component.
packages/spec/src/ui/app.zod.ts backs each row: ActionNavItemSchema requires
actionDef, itself a strict object of actionName plus an optional open params;
ComponentNavItemSchema requires componentRef (a ComponentRegistry key such as
metadata:resource) with an optional open params passed to the component as props.
Neither variant accepts childrenNAV_VARIANTS_ACCEPTING_CHILDREN is object and
group only — so neither row lists it.

pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/ui/app.test.ts
102 passed (1 file), including the pin that parses all nine variants with their full
declared payloads.

Rows added

| `action` | `actionDef` (`{ actionName, params? }`), `label`, `icon` | Run an action instead of navigating |
| `component` | `componentRef`, `params?`, `label`, `icon` | Built-in platform component; `componentRef` is a colon-joined registry key (`metadata:resource`), `params` become props |

Token budget — funded by deletion in the same file, no ceiling raise

The file sat at its ceiling with headroom 0, so the two rows are paid for by removing text,
not by moving a ceiling. Verdict lines from node scripts/check-skills-token-ratchet.mjs:

before: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25445 tokens (ceiling 25445; headroom 0).
after: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25441 tokens (ceiling 25445; headroom 4).

Funding source — two Common Pitfalls entries deleted, neither of which carries a fact the
file does not state better elsewhere (a real deletion, not a re-wrap; the ceiling constant
is untouched):

  • "Using provider: 'api' when provider: 'object' is available" — a strict subset of
    the Data Source best-practice block a thousand lines above, which is the richer of the two
    (it also names automatic CRUD).
  • "Not setting quick filters … always add a 'My Records' filter" — superseded by the
    ADR-0047 userFilters section in the same file, which prescribes the opposite default:
    "Omit userFilters when unsure … most views need no filter elements at all." Keeping
    both left the skill teaching two contradictory defaults.

Required skills/** readings, lines and tokens (token unit is the ratchet's own
ceil(utf8 bytes / 4)):

ReadingBeforeAfterDelta
skills/objectstack-ui/SKILL.md, whole file — lines21112105-6
skills/objectstack-ui/SKILL.md, whole file — tokens2544525441-4
Whole published package, all 11 SKILL.md — lines1053310527-6
Whole published package, all 11 SKILL.md — tokens118696118692-4

Both readings are net negative: the catalog gets two missing rows and gets shorter.

Ledger

scripts/check-skill-identifier-liveness.mjs records this gap in
scripts/skill-identifier-liveness-ledger.json under leg2Gaps.navigation-item-types, and
refuses an improvement that does not ratchet it down. Second commit does exactly that; the
gate now reports Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s).

Gates

Full derived union at HEAD c587bd7ff, from
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands run
against that same commit (21 commands over the 2 changed paths), plus check:nul-bytes.
Exit codes captured before any pipe. 21 green; one NOT MEASURED:

  • node scripts/check-test-completeness.mjs exits 3 with no argument by design — it parses
    a saved turbo run test log, which a local family run has none of. Its own text says this
    is not a red and there is nothing here to fix.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3
    (PREREQUISITE NOT MET) because @objectstack/formula and @objectstack/lint were not
    built in this fresh worktree; after building both it exits 0 at the same HEAD.

No changeset: the diff publishes nothing from any package, so the PR carries
skip-changeset.

Landing

skills/** is a governed surface — this PR stays a draft and is merged by the
maintainer, by hand. No auto-merge, no queue.

Session: session_01Msg17tAHJ3jVTYFgHydCm2.

Generated by Claude Code


Generated by Claude Code

The objectstack-ui Navigation Item Types table listed 7 of the 9 live
discriminated-union members; `action` and `component` had no row, so an
author reading the published skill could not discover either target.
Funded within the file's token ceiling (headroom was 0) by deleting two
Common Pitfalls entries that carry no fact the file does not state better
elsewhere:
- pitfall 1 restated the Data Source best-practice block verbatim (and that
block is the richer of the two -- it also names automatic CRUD);
- pitfall 4 ("always add a quick filter") is superseded by the ADR-0047
userFilters section, which prescribes the opposite default: omit
`userFilters` when unsure, most views need no filter elements at all.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
The recorded NavItemVariant gap of 2 (action, component) is closed by the
table rows in the previous commit; the gate refuses an improvement that
leaves budget behind for a later edit to spend silently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
@os-zhuang
os-zhuang marked this pull request as ready for review September 1, 2026 07:19
@os-zhuang
os-zhuang added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0ff3d96Sep 1, 2026
34 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-13890-nav-item-types-rows branch September 1, 2026 07:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skills/objectstack-ui "Navigation Item Types" documents 7 of the 9 live NavItemVariant members — action and component have no row

2 participants

@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(skills): document the action and component nav item types - #14138

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows
Sep 1, 2026
Merged

docs(skills): document the action and component nav item types#14138
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13890

The published skills/objectstack-ui "Navigation Item Types" table listed 7 of the 9 live
NavItemVariant members: action and component had no row, in a section whose heading
names the catalog and whose other seven rows are present — so an AI author reading it
could not reach either variant.

Part of #13658. The objectstack twin of the fix the objectui sweep landed in that repo's
skills/objectui/guides/app-composition.md; the rows here are written in this table's own
Type | Properties | Purpose idiom rather than copied.

Member set, verified against the schema

The live set is read out of the schema at runtime — hand the discriminated union a bogus
type and print the options it names, rather than trusting the card's "9" or the
NavItemVariant type alias:

DISCRIMINATOR OPTIONS (from the schema): ["object","dashboard","page","url","report","action","component","separator","group"]
COUNT: 9
ISSUE: invalid_union | Invalid discriminator value. Expected 'object' | 'dashboard' | 'page' | 'url' | 'report' | 'action' | 'component' | 'separator' | 'group'

Nine members; the two absent from the table are exactly action and component.
packages/spec/src/ui/app.zod.ts backs each row: ActionNavItemSchema requires
actionDef, itself a strict object of actionName plus an optional open params;
ComponentNavItemSchema requires componentRef (a ComponentRegistry key such as
metadata:resource) with an optional open params passed to the component as props.
Neither variant accepts childrenNAV_VARIANTS_ACCEPTING_CHILDREN is object and
group only — so neither row lists it.

pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/ui/app.test.ts
102 passed (1 file), including the pin that parses all nine variants with their full
declared payloads.

Rows added

| `action` | `actionDef` (`{ actionName, params? }`), `label`, `icon` | Run an action instead of navigating |
| `component` | `componentRef`, `params?`, `label`, `icon` | Built-in platform component; `componentRef` is a colon-joined registry key (`metadata:resource`), `params` become props |

Token budget — funded by deletion in the same file, no ceiling raise

The file sat at its ceiling with headroom 0, so the two rows are paid for by removing text,
not by moving a ceiling. Verdict lines from node scripts/check-skills-token-ratchet.mjs:

before: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25445 tokens (ceiling 25445; headroom 0).
after: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25441 tokens (ceiling 25445; headroom 4).

Funding source — two Common Pitfalls entries deleted, neither of which carries a fact the
file does not state better elsewhere (a real deletion, not a re-wrap; the ceiling constant
is untouched):

  • "Using provider: 'api' when provider: 'object' is available" — a strict subset of
    the Data Source best-practice block a thousand lines above, which is the richer of the two
    (it also names automatic CRUD).
  • "Not setting quick filters … always add a 'My Records' filter" — superseded by the
    ADR-0047 userFilters section in the same file, which prescribes the opposite default:
    "Omit userFilters when unsure … most views need no filter elements at all." Keeping
    both left the skill teaching two contradictory defaults.

Required skills/** readings, lines and tokens (token unit is the ratchet's own
ceil(utf8 bytes / 4)):

ReadingBeforeAfterDelta
skills/objectstack-ui/SKILL.md, whole file — lines21112105-6
skills/objectstack-ui/SKILL.md, whole file — tokens2544525441-4
Whole published package, all 11 SKILL.md — lines1053310527-6
Whole published package, all 11 SKILL.md — tokens118696118692-4

Both readings are net negative: the catalog gets two missing rows and gets shorter.

Ledger

scripts/check-skill-identifier-liveness.mjs records this gap in
scripts/skill-identifier-liveness-ledger.json under leg2Gaps.navigation-item-types, and
refuses an improvement that does not ratchet it down. Second commit does exactly that; the
gate now reports Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s).

Gates

Full derived union at HEAD c587bd7ff, from
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands run
against that same commit (21 commands over the 2 changed paths), plus check:nul-bytes.
Exit codes captured before any pipe. 21 green; one NOT MEASURED:

  • node scripts/check-test-completeness.mjs exits 3 with no argument by design — it parses
    a saved turbo run test log, which a local family run has none of. Its own text says this
    is not a red and there is nothing here to fix.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3
    (PREREQUISITE NOT MET) because @objectstack/formula and @objectstack/lint were not
    built in this fresh worktree; after building both it exits 0 at the same HEAD.

No changeset: the diff publishes nothing from any package, so the PR carries
skip-changeset.

Landing

skills/** is a governed surface — this PR stays a draft and is merged by the
maintainer, by hand. No auto-merge, no queue.

Session: session_01Msg17tAHJ3jVTYFgHydCm2.

Generated by Claude Code


Generated by Claude Code

The objectstack-ui Navigation Item Types table listed 7 of the 9 live
discriminated-union members; `action` and `component` had no row, so an
author reading the published skill could not discover either target.
Funded within the file's token ceiling (headroom was 0) by deleting two
Common Pitfalls entries that carry no fact the file does not state better
elsewhere:
- pitfall 1 restated the Data Source best-practice block verbatim (and that
block is the richer of the two -- it also names automatic CRUD);
- pitfall 4 ("always add a quick filter") is superseded by the ADR-0047
userFilters section, which prescribes the opposite default: omit
`userFilters` when unsure, most views need no filter elements at all.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
The recorded NavItemVariant gap of 2 (action, component) is closed by the
table rows in the previous commit; the gate refuses an improvement that
leaves budget behind for a later edit to spend silently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
@os-zhuang
os-zhuang marked this pull request as ready for review September 1, 2026 07:19
@os-zhuang
os-zhuang added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0ff3d96Sep 1, 2026
34 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-13890-nav-item-types-rows branch September 1, 2026 07:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skills/objectstack-ui "Navigation Item Types" documents 7 of the 9 live NavItemVariant members — action and component have no row

2 participants

@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(skills): document the action and component nav item types - #14138

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows
Sep 1, 2026
Merged

docs(skills): document the action and component nav item types#14138
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13890

The published skills/objectstack-ui "Navigation Item Types" table listed 7 of the 9 live
NavItemVariant members: action and component had no row, in a section whose heading
names the catalog and whose other seven rows are present — so an AI author reading it
could not reach either variant.

Part of #13658. The objectstack twin of the fix the objectui sweep landed in that repo's
skills/objectui/guides/app-composition.md; the rows here are written in this table's own
Type | Properties | Purpose idiom rather than copied.

Member set, verified against the schema

The live set is read out of the schema at runtime — hand the discriminated union a bogus
type and print the options it names, rather than trusting the card's "9" or the
NavItemVariant type alias:

DISCRIMINATOR OPTIONS (from the schema): ["object","dashboard","page","url","report","action","component","separator","group"]
COUNT: 9
ISSUE: invalid_union | Invalid discriminator value. Expected 'object' | 'dashboard' | 'page' | 'url' | 'report' | 'action' | 'component' | 'separator' | 'group'

Nine members; the two absent from the table are exactly action and component.
packages/spec/src/ui/app.zod.ts backs each row: ActionNavItemSchema requires
actionDef, itself a strict object of actionName plus an optional open params;
ComponentNavItemSchema requires componentRef (a ComponentRegistry key such as
metadata:resource) with an optional open params passed to the component as props.
Neither variant accepts childrenNAV_VARIANTS_ACCEPTING_CHILDREN is object and
group only — so neither row lists it.

pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/ui/app.test.ts
102 passed (1 file), including the pin that parses all nine variants with their full
declared payloads.

Rows added

| `action` | `actionDef` (`{ actionName, params? }`), `label`, `icon` | Run an action instead of navigating |
| `component` | `componentRef`, `params?`, `label`, `icon` | Built-in platform component; `componentRef` is a colon-joined registry key (`metadata:resource`), `params` become props |

Token budget — funded by deletion in the same file, no ceiling raise

The file sat at its ceiling with headroom 0, so the two rows are paid for by removing text,
not by moving a ceiling. Verdict lines from node scripts/check-skills-token-ratchet.mjs:

before: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25445 tokens (ceiling 25445; headroom 0).
after: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25441 tokens (ceiling 25445; headroom 4).

Funding source — two Common Pitfalls entries deleted, neither of which carries a fact the
file does not state better elsewhere (a real deletion, not a re-wrap; the ceiling constant
is untouched):

  • "Using provider: 'api' when provider: 'object' is available" — a strict subset of
    the Data Source best-practice block a thousand lines above, which is the richer of the two
    (it also names automatic CRUD).
  • "Not setting quick filters … always add a 'My Records' filter" — superseded by the
    ADR-0047 userFilters section in the same file, which prescribes the opposite default:
    "Omit userFilters when unsure … most views need no filter elements at all." Keeping
    both left the skill teaching two contradictory defaults.

Required skills/** readings, lines and tokens (token unit is the ratchet's own
ceil(utf8 bytes / 4)):

ReadingBeforeAfterDelta
skills/objectstack-ui/SKILL.md, whole file — lines21112105-6
skills/objectstack-ui/SKILL.md, whole file — tokens2544525441-4
Whole published package, all 11 SKILL.md — lines1053310527-6
Whole published package, all 11 SKILL.md — tokens118696118692-4

Both readings are net negative: the catalog gets two missing rows and gets shorter.

Ledger

scripts/check-skill-identifier-liveness.mjs records this gap in
scripts/skill-identifier-liveness-ledger.json under leg2Gaps.navigation-item-types, and
refuses an improvement that does not ratchet it down. Second commit does exactly that; the
gate now reports Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s).

Gates

Full derived union at HEAD c587bd7ff, from
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands run
against that same commit (21 commands over the 2 changed paths), plus check:nul-bytes.
Exit codes captured before any pipe. 21 green; one NOT MEASURED:

  • node scripts/check-test-completeness.mjs exits 3 with no argument by design — it parses
    a saved turbo run test log, which a local family run has none of. Its own text says this
    is not a red and there is nothing here to fix.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3
    (PREREQUISITE NOT MET) because @objectstack/formula and @objectstack/lint were not
    built in this fresh worktree; after building both it exits 0 at the same HEAD.

No changeset: the diff publishes nothing from any package, so the PR carries
skip-changeset.

Landing

skills/** is a governed surface — this PR stays a draft and is merged by the
maintainer, by hand. No auto-merge, no queue.

Session: session_01Msg17tAHJ3jVTYFgHydCm2.

Generated by Claude Code


Generated by Claude Code

The objectstack-ui Navigation Item Types table listed 7 of the 9 live
discriminated-union members; `action` and `component` had no row, so an
author reading the published skill could not discover either target.
Funded within the file's token ceiling (headroom was 0) by deleting two
Common Pitfalls entries that carry no fact the file does not state better
elsewhere:
- pitfall 1 restated the Data Source best-practice block verbatim (and that
block is the richer of the two -- it also names automatic CRUD);
- pitfall 4 ("always add a quick filter") is superseded by the ADR-0047
userFilters section, which prescribes the opposite default: omit
`userFilters` when unsure, most views need no filter elements at all.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
The recorded NavItemVariant gap of 2 (action, component) is closed by the
table rows in the previous commit; the gate refuses an improvement that
leaves budget behind for a later edit to spend silently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
@os-zhuang
os-zhuang marked this pull request as ready for review September 1, 2026 07:19
@os-zhuang
os-zhuang added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0ff3d96Sep 1, 2026
34 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-13890-nav-item-types-rows branch September 1, 2026 07:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skills/objectstack-ui "Navigation Item Types" documents 7 of the 9 live NavItemVariant members — action and component have no row

2 participants

@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

docs(skills): document the action and component nav item types - #14138

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows
Sep 1, 2026
Merged

docs(skills): document the action and component nav item types#14138
os-zhuang merged 3 commits into
mainfrom
claude/issue-13890-nav-item-types-rows

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13890

The published skills/objectstack-ui "Navigation Item Types" table listed 7 of the 9 live
NavItemVariant members: action and component had no row, in a section whose heading
names the catalog and whose other seven rows are present — so an AI author reading it
could not reach either variant.

Part of #13658. The objectstack twin of the fix the objectui sweep landed in that repo's
skills/objectui/guides/app-composition.md; the rows here are written in this table's own
Type | Properties | Purpose idiom rather than copied.

Member set, verified against the schema

The live set is read out of the schema at runtime — hand the discriminated union a bogus
type and print the options it names, rather than trusting the card's "9" or the
NavItemVariant type alias:

DISCRIMINATOR OPTIONS (from the schema): ["object","dashboard","page","url","report","action","component","separator","group"]
COUNT: 9
ISSUE: invalid_union | Invalid discriminator value. Expected 'object' | 'dashboard' | 'page' | 'url' | 'report' | 'action' | 'component' | 'separator' | 'group'

Nine members; the two absent from the table are exactly action and component.
packages/spec/src/ui/app.zod.ts backs each row: ActionNavItemSchema requires
actionDef, itself a strict object of actionName plus an optional open params;
ComponentNavItemSchema requires componentRef (a ComponentRegistry key such as
metadata:resource) with an optional open params passed to the component as props.
Neither variant accepts childrenNAV_VARIANTS_ACCEPTING_CHILDREN is object and
group only — so neither row lists it.

pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/ui/app.test.ts
102 passed (1 file), including the pin that parses all nine variants with their full
declared payloads.

Rows added

| `action` | `actionDef` (`{ actionName, params? }`), `label`, `icon` | Run an action instead of navigating |
| `component` | `componentRef`, `params?`, `label`, `icon` | Built-in platform component; `componentRef` is a colon-joined registry key (`metadata:resource`), `params` become props |

Token budget — funded by deletion in the same file, no ceiling raise

The file sat at its ceiling with headroom 0, so the two rows are paid for by removing text,
not by moving a ceiling. Verdict lines from node scripts/check-skills-token-ratchet.mjs:

before: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25445 tokens (ceiling 25445; headroom 0).
after: ✓ check-skills-token-ratchet: skills/objectstack-ui/SKILL.md is 25441 tokens (ceiling 25445; headroom 4).

Funding source — two Common Pitfalls entries deleted, neither of which carries a fact the
file does not state better elsewhere (a real deletion, not a re-wrap; the ceiling constant
is untouched):

  • "Using provider: 'api' when provider: 'object' is available" — a strict subset of
    the Data Source best-practice block a thousand lines above, which is the richer of the two
    (it also names automatic CRUD).
  • "Not setting quick filters … always add a 'My Records' filter" — superseded by the
    ADR-0047 userFilters section in the same file, which prescribes the opposite default:
    "Omit userFilters when unsure … most views need no filter elements at all." Keeping
    both left the skill teaching two contradictory defaults.

Required skills/** readings, lines and tokens (token unit is the ratchet's own
ceil(utf8 bytes / 4)):

ReadingBeforeAfterDelta
skills/objectstack-ui/SKILL.md, whole file — lines21112105-6
skills/objectstack-ui/SKILL.md, whole file — tokens2544525441-4
Whole published package, all 11 SKILL.md — lines1053310527-6
Whole published package, all 11 SKILL.md — tokens118696118692-4

Both readings are net negative: the catalog gets two missing rows and gets shorter.

Ledger

scripts/check-skill-identifier-liveness.mjs records this gap in
scripts/skill-identifier-liveness-ledger.json under leg2Gaps.navigation-item-types, and
refuses an improvement that does not ratchet it down. Second commit does exactly that; the
gate now reports Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s).

Gates

Full derived union at HEAD c587bd7ff, from
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands run
against that same commit (21 commands over the 2 changed paths), plus check:nul-bytes.
Exit codes captured before any pipe. 21 green; one NOT MEASURED:

  • node scripts/check-test-completeness.mjs exits 3 with no argument by design — it parses
    a saved turbo run test log, which a local family run has none of. Its own text says this
    is not a red and there is nothing here to fix.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3
    (PREREQUISITE NOT MET) because @objectstack/formula and @objectstack/lint were not
    built in this fresh worktree; after building both it exits 0 at the same HEAD.

No changeset: the diff publishes nothing from any package, so the PR carries
skip-changeset.

Landing

skills/** is a governed surface — this PR stays a draft and is merged by the
maintainer, by hand. No auto-merge, no queue.

Session: session_01Msg17tAHJ3jVTYFgHydCm2.

Generated by Claude Code


Generated by Claude Code

The objectstack-ui Navigation Item Types table listed 7 of the 9 live
discriminated-union members; `action` and `component` had no row, so an
author reading the published skill could not discover either target.
Funded within the file's token ceiling (headroom was 0) by deleting two
Common Pitfalls entries that carry no fact the file does not state better
elsewhere:
- pitfall 1 restated the Data Source best-practice block verbatim (and that
block is the richer of the two -- it also names automatic CRUD);
- pitfall 4 ("always add a quick filter") is superseded by the ADR-0047
userFilters section, which prescribes the opposite default: omit
`userFilters` when unsure, most views need no filter elements at all.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
The recorded NavItemVariant gap of 2 (action, component) is closed by the
table rows in the previous commit; the gate refuses an improvement that
leaves budget behind for a later edit to spend silently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Msg17tAHJ3jVTYFgHydCm2
@os-zhuang
os-zhuang marked this pull request as ready for review September 1, 2026 07:19
@os-zhuang
os-zhuang added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0ff3d96Sep 1, 2026
34 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-13890-nav-item-types-rows branch September 1, 2026 07:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skills/objectstack-ui "Navigation Item Types" documents 7 of the 9 live NavItemVariant members — action and component have no row

2 participants

@os-zhuang@claude