Skip to content

Fix TypeScript build error for blog frontmatter fields - #37

Merged
huangyiirene merged 2 commits into
copilot/fix-homepage-font-colorfrom
copilot/fix-error-in-workflow-step
Jan 20, 2026
Merged

huangyiirene merged 2 commits into
copilot/fix-homepage-font-colorfrom
copilot/fix-error-in-workflow-step

Conversation

Copilot AI commented Jan 20, 2026

Copy link
Copy Markdown
Contributor

The CI build was failing because blog posts used custom frontmatter fields (date, author, tags) that weren't typed in the fumadocs-mdx schema. Type casts (as any) masked this until TypeScript compilation.

Changes

source.config.ts

  • Configure blog schema via docs.schema property with extended frontmatter
  • Use z.coerce.string() for date field to handle YAML's auto-parsing to Date objects

source.ts

  • Remove as any casts to enable type inference

page.tsx

  • Add BlogPostData interface and type assertions for custom fields
  • Preserve original page.data.body access for MDX component
// Before: unsafe cast hid the missing schema
export const blog = defineDocs({
  dir: '../../content/blog',
}) as any;

// After: explicit schema configuration
const blogSchema = frontmatterSchema.extend({
  date: z.coerce.string().optional(),
  author: z.string().optional(),
  tags: z.array(z.string()).optional(),
});

export const blog = defineDocs({
  dir: '../../content/blog',
  docs: { schema: blogSchema },
});
Original prompt

引用: https://github.com/objectstack-ai/spec/actions/runs/21161689880/job/60857524435#step:8:1


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@vercel

vercel Bot commented Jan 20, 2026

Copy link
Copy Markdown

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

Project Deployment Review Updated (UTC)
spec Ready Ready Preview, Comment Jan 20, 2026 7:28am

Request Review

- Remove `as any` type casts from source.config.ts and source.ts
- Properly configure fumadocs-mdx blog schema with extended frontmatter fields
- Use z.coerce.string() for date field to handle YAML Date objects
- Add BlogPostData interface and type assertions in blog page component
- Build now passes successfully

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix error in workflow step execution Fix TypeScript build error for blog frontmatter fields Jan 20, 2026
Copilot AI requested a review from hotlong January 20, 2026 07:31
@github-actions github-actions Bot added documentation Improvements or additions to documentation size/m labels Jan 20, 2026
@huangyiirene
huangyiirene marked this pull request as ready for review January 20, 2026 07:54
@huangyiirene
huangyiirene merged commit 526ccb0 into copilot/fix-homepage-font-color Jan 20, 2026
5 checks passed
xuyushun441-sys pushed a commit that referenced this pull request May 25, 2026
Adds entries 26-40 covering the gaps that make the helpdesk template
'pretty but not daily-usable' from an end-user perspective:

P0 additions:
- #26 No inline message composer on detail pages
- #27 No external-user portal mechanism
- #28 Attachment/file-list field UI not E2E

P1 additions:
- #29 No 'changed since last visit' indicator
- #30 Bulk operations UI unverified (escalates #17)
- #31 Rich-text editor scoped to comments only
- #32 No first-class canned response / macro
- #33 No collaboration presence indicators
- #34 No keyboard-shortcut API
- #35 No conditional SLA timer (pause on waiting_customer)
- #36 Formula fields can't reference foreign object fields

P2 additions:
- #37 No chart drill-down
- #38 No period-over-period analytics primitive
- #39 No inbound-channel abstraction (email-to-ticket etc.)
- #40 i18n translation namespace validation weak

Includes 'user-pain → platform-gap' mapping table tracing each end-user
complaint to a specific issue number.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
os-warren added a commit that referenced this pull request Sep 4, 2026
…cision/runId/repairable beside its 500

Maintainer ruling 2026-09-04, decision batch #37, option B. One
`POST /api/v1/approvals/requests/{id}/reject` produced three coexisting
outcomes: the caller read HTTP 500, the request row WAS terminal and had
left the pending inbox, and the run was stranded. 500 alone reads as "the
rejection did not happen", so callers retried against a durable decision.

The status code does not move — the effect landing while the run strands
is still a failure — and the door does not become atomic: the #13937
shape-4 ruling binds this door's own writes too, so no decision is ever
rolled back. What changed is that the door stops discarding what the
engine said.

- `serviceResume` carries `AutomationResult.status` through. It read only
  success/code/error, and the stranded exit reports a status and NO code,
  so the repairability signal died one line before the envelope was built
  — a member with a producer and, until now, zero consumers.
- `resumeRecordedOutcome` throws a carrier with `finalized` (the decision
  stands), `decision`, `runId`, and `repairable` derived from the engine's
  `'stranded'` discriminator. Absence of that stamp is `false`, never a
  default: a repair verb that would refuse is worse than no promise.
- The REST approvals door forwards those four fields on `RESUME_FAILED`
  only, presence-gated — an error with no carrier answers exactly the body
  it always did.
- `@objectstack/types` hosts the constructor and its recogniser in one
  module (the producer is a plugin; rest cannot import one), the same Home
  rule as the validation-failure pair beside it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpTx2tbq3pZRYAdoGt6E6Y
zhuangjianguo pushed a commit that referenced this pull request Sep 8, 2026
… throw carries

The contract already declared the posture: a decision that finalises a
flow-bound request and cannot resume its own run throws rather than
answering `resumed: false`, because a recorded decision whose flow never
advances is #4420's zombie half-state. What it never said is that the
throw is now readable.

The maintainer ruling #13807 (2026-09-04, decision batch #37) owes both
halves — "throws with the decision and run identified; the fields are the
published way to read it" — and only the first half was written down. The
`resumed` docblock now names the second: the 500-class `RESUME_FAILED`
carries `finalized`, `decision`, `runId` and `repairable` on its ERROR
body as `StrandedDecisionDetails` (`@objectstack/types`, attached by
`strandedDecisionFailure`, read back by `strandedDecisionDetails`, merged
into the response by the REST approvals door), and the status code does
not move because a durable decision over a run that will not advance is
still a failure.

Prose only. No member is added: the four facts ride the ERROR, so putting
them on this success shape would declare a shape that never carries them,
and the docblock says so explicitly. It also keeps them distinct from
`resumeFailure`, which reports the #16472 family's different event — a
resume failure told behind an answer that still succeeded.

The changeset is owed on the second half of the two-part test, not the
first: `src/contracts/approval-service.ts` is outside `packages/spec`'s
`files[]`, but the changed docblock text is emitted into
`dist/contracts/index.d.ts` and `index.d.mts`, which `files[]` publishes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Sep 9, 2026
…decision / runId / repairable beside its 500 (objectstack-ai#15436)

* fix(approvals,rest,types): a stranded decision publishes finalized/decision/runId/repairable beside its 500

Maintainer ruling 2026-09-04, decision batch objectstack-ai#37, option B. One
`POST /api/v1/approvals/requests/{id}/reject` produced three coexisting
outcomes: the caller read HTTP 500, the request row WAS terminal and had
left the pending inbox, and the run was stranded. 500 alone reads as "the
rejection did not happen", so callers retried against a durable decision.

The status code does not move — the effect landing while the run strands
is still a failure — and the door does not become atomic: the objectstack-ai#13937
shape-4 ruling binds this door's own writes too, so no decision is ever
rolled back. What changed is that the door stops discarding what the
engine said.

- `serviceResume` carries `AutomationResult.status` through. It read only
  success/code/error, and the stranded exit reports a status and NO code,
  so the repairability signal died one line before the envelope was built
  — a member with a producer and, until now, zero consumers.
- `resumeRecordedOutcome` throws a carrier with `finalized` (the decision
  stands), `decision`, `runId`, and `repairable` derived from the engine's
  `'stranded'` discriminator. Absence of that stamp is `false`, never a
  default: a repair verb that would refuse is worse than no promise.
- The REST approvals door forwards those four fields on `RESUME_FAILED`
  only, presence-gated — an error with no carrier answers exactly the body
  it always did.
- `@objectstack/types` hosts the constructor and its recogniser in one
  module (the producer is a plugin; rest cannot import one), the same Home
  rule as the validation-failure pair beside it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpTx2tbq3pZRYAdoGt6E6Y

* test(approvals): route the new pin's engine double through ObjectQL's dispatch predicates

`check:engine-double-contract` and `check:objectql-double-limit` both caught
the new fake in `decision-strand-envelope.test.ts`: its `update()`/`delete()`
hand-rolled the dispatch and its `find()` read the caller's bound by
truthiness, so `limit: 0` would have returned the whole table. Both verbs now
open with `assertEngineUpdateDispatch` / `assertEngineDeleteDispatch` and the
bound is honoured by presence; the two new rows are recorded in the pinned
ledger (`--write`, 2 added, 0 lost).

`check:system-context-census` anchors are re-anchored by its own `--fix`: pure
line rot from this branch's edits, uniform +5 on `rest-server.ts` (the import
block) and +52 on `approval-service.ts` (the docblocks), which is what makes it
rot rather than a finding.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpTx2tbq3pZRYAdoGt6E6Y

* chore(docs): regenerate the system-context census page from the merged tree

The os-regen merge driver hands this page back rather than text-merging it —
it is generated. Regenerated with `pnpm gen:system-context-census` after
merging origin/main; the three re-anchors are all line rot in
`packages/runtime/src/domains/actions.ts` (+10 from upstream commits), none
of them this branch's own files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpTx2tbq3pZRYAdoGt6E6Y

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Sep 9, 2026
… throw carries (objectstack-ai#16983)

The contract already declared the posture: a decision that finalises a
flow-bound request and cannot resume its own run throws rather than
answering `resumed: false`, because a recorded decision whose flow never
advances is objectstack-ai#4420's zombie half-state. What it never said is that the
throw is now readable.

The maintainer ruling objectstack-ai#13807 (2026-09-04, decision batch objectstack-ai#37) owes both
halves — "throws with the decision and run identified; the fields are the
published way to read it" — and only the first half was written down. The
`resumed` docblock now names the second: the 500-class `RESUME_FAILED`
carries `finalized`, `decision`, `runId` and `repairable` on its ERROR
body as `StrandedDecisionDetails` (`@objectstack/types`, attached by
`strandedDecisionFailure`, read back by `strandedDecisionDetails`, merged
into the response by the REST approvals door), and the status code does
not move because a durable decision over a run that will not advance is
still a failure.

Prose only. No member is added: the four facts ride the ERROR, so putting
them on this success shape would declare a shape that never carries them,
and the docblock says so explicitly. It also keeps them distinct from
`resumeFailure`, which reports the objectstack-ai#16472 family's different event — a
resume failure told behind an answer that still succeeded.

The changeset is owed on the second half of the two-part test, not the
first: `src/contracts/approval-service.ts` is outside `packages/spec`'s
`files[]`, but the changed docblock text is emitted into
`dist/contracts/index.d.ts` and `index.d.mts`, which `files[]` publishes.


Claude-Session: https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x

Co-authored-by: Claude <noreply@anthropic.com>
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 size/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants