Skip to content

feat(spec): add ActionSchema.openIn for declarative url new-tab (objectui #2043)#2413

Merged
os-zhuang merged 1 commit into
mainfrom
claude/unruffled-nightingale-a230fe
Jun 28, 2026
Merged

feat(spec): add ActionSchema.openIn for declarative url new-tab (objectui #2043)#2413
os-zhuang merged 1 commit into
mainfrom
claude/unruffled-nightingale-a230fe

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Why

Counterpart to objectui issue #2043. objectui added a first-class declarative field for url actions — openIn?: 'self' | 'new-tab' — in its public ActionSchema, honored by ActionRunner.executeUrl (read with priority over the legacy params.newTab / external-URL heuristic) and forwarded by all renderers (action-button/icon/menu/group, basic/elements).

But @objectstack/spec's ActionSchema was a plain z.object(...) that strips unknown keys, so openIn written via defineAction({...}) was silently dropped at build and never reached objectui's runtime. Downstream authors (e.g. plan-management) therefore still couldn't use it.

What

  1. packages/spec/src/ui/action.zod.ts — add openIn: z.enum(['self', 'new-tab']).optional() next to target. Kept distinct from the existing opensInNewTab / newTabUrl (those pre-open an about:blank tab synchronously for async SSO-redirect handlers — not merged). openIn is the simple, static case.
  2. action.test.ts — 5 cases, including a regression guard that openIn survives parse() (the whole point: it used to be stripped).
  3. liveness/action.json — classify openIn as live (objectui is the consumer). The liveness gate passes (exit 0).
  4. skills/objectstack-ui/SKILL.md — document the openIn vs opensInNewTab/newTabUrl split, plus a warning that new-tab behavior must not be expressed via params (object form fails the zod build; array form mis-renders as a user-facing checkbox).
  5. changeset@objectstack/spec minor.

openIn semantics

  • 'new-tab' — open a static target URL in a new tab. No handler, no pre-open.
  • 'self' — navigate in place.
  • omitted — external/absolute URLs open in a new tab; relative URLs navigate in place.
defineAction({
  name: 'print_a3',
  label: '打印总表(A3)',
  type: 'url',
  target: '/print/a3?id=${record.id}',
  openIn: 'new-tab',
});

Publish coordination

The objectui side is already merged (issue #2043). Consuming projects need a @objectstack/spec version that includes this field for the declarative path to work end-to-end — hence the minor changeset.

Verification

  • vitest run src/ui/action.test.ts77 passed
  • tsx scripts/liveness/check-liveness.mtsexit 0 (✓ all governed-type properties are classified)
  • tsc --noEmit → clean

@vercel

vercel Bot commented Jun 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 28, 2026 5:24am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests protocol:ui tooling size/m labels Jun 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec.

90 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/cloud-artifact-api.mdx (via packages/spec)
  • content/docs/concepts/cluster-semantics.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/implementation-status.mdx (via @objectstack/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/spec)
  • content/docs/concepts/packages.mdx (via @objectstack/spec)
  • content/docs/concepts/setup-app.mdx (via @objectstack/spec)
  • content/docs/concepts/skills.mdx (via @objectstack/spec)
  • content/docs/concepts/webhook-delivery.mdx (via @objectstack/spec)
  • content/docs/getting-started/architecture.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.mdx (via @objectstack/spec)
  • content/docs/getting-started/core-concepts.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/guides/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/guides/ai-capabilities.mdx (via @objectstack/spec)
  • content/docs/guides/airtable-dashboard-analysis.mdx (via @objectstack/spec)
  • content/docs/guides/analytics-datasets.mdx (via @objectstack/spec)
  • content/docs/guides/api-reference.mdx (via @objectstack/spec)
  • content/docs/guides/business-logic.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/error-catalog.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/field-type-gallery.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/field-validation-rules.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/protocol-diagram.mdx (via packages/spec)
  • content/docs/guides/cheatsheets/query-cheat-sheet.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/quick-reference.mdx (via @objectstack/spec)
  • content/docs/guides/client-sdk.mdx (via @objectstack/spec)
  • content/docs/guides/common-patterns.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/auth-service.mdx (via packages/spec)
  • content/docs/guides/contracts/cache-service.mdx (via packages/spec)
  • content/docs/guides/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/index.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/guides/contracts/storage-service.mdx (via packages/spec)
  • content/docs/guides/data-modeling.mdx (via @objectstack/spec)
  • content/docs/guides/driver-configuration.mdx (via @objectstack/spec)
  • content/docs/guides/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/guides/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/guides/external-datasources.mdx (via @objectstack/spec)
  • content/docs/guides/formula.mdx (via @objectstack/spec)
  • content/docs/guides/hook-bodies.mdx (via packages/spec)
  • content/docs/guides/kernel-services.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/dashboard.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/field.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/flow.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/index.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/object.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/validation.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/workflow.mdx (via @objectstack/spec)
  • content/docs/guides/packages.mdx (via @objectstack/spec)
  • content/docs/guides/plugin-development.mdx (via @objectstack/spec)
  • content/docs/guides/plugins.mdx (via @objectstack/spec)
  • content/docs/guides/project-scoping.mdx (via @objectstack/spec)
  • content/docs/guides/public-forms.mdx (via @objectstack/spec)
  • content/docs/guides/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/index.mdx (via packages/spec)
  • content/docs/guides/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/guides/security.mdx (via @objectstack/spec)
  • content/docs/guides/seed-data.mdx (via @objectstack/spec)
  • content/docs/guides/skills.mdx (via @objectstack/spec)
  • content/docs/guides/standards.mdx (via @objectstack/spec)
  • content/docs/guides/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/guides/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via packages/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via packages/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang merged commit ecf193f into main Jun 28, 2026
17 checks passed
@os-zhuang
os-zhuang deleted the claude/unruffled-nightingale-a230fe branch June 28, 2026 07:24
…ctui #2043)

@objectstack/spec's ActionSchema was a plain z.object() that stripped
unknown keys, so the openIn field authored via defineAction({...}) was
silently dropped at build and never reached objectui's ActionRunner.

Add openIn?: 'self' | 'new-tab' next to target. objectui (issue #2043)
already honors it in ActionRunner.executeUrl with priority over the
legacy params.newTab/external-URL heuristic; renderers forward it.

Kept distinct from opensInNewTab/newTabUrl (async SSO pre-open). It is a
static execution option and must stay out of params.

- packages/spec/src/ui/action.zod.ts: add openIn enum field
- action.test.ts: 5 cases incl. not-stripped-at-build regression guard
- liveness/action.json: classify openIn live (objectui consumer)
- skills/objectstack-ui/SKILL.md: document openIn vs opensInNewTab split
  + warn against expressing new-tab via params
- changeset: @objectstack/spec minor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation protocol:ui size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants