Skip to content

chore(packages): publishing metadata for the 73 published packages — per-format types, sideEffects, publishConfig, and 18 missing READMEs - #26198

Merged
objectstack-fleet[bot] merged 8 commits into
mainfrom
claude/project-thread-09e02s
Oct 26, 2026
Merged

objectstack-fleet[bot] merged 8 commits into
mainfrom
claude/project-thread-09e02s

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steve · project thread

Part of #26095

Clause-②: no
Metadata-protocol: none

#26095 asks for two things in order: one reading of publint and @arethetypeswrong over the 73 published packages outside ui/, then the repairs that reading names. This PR carries the reading, the manifest repairs and the 18 missing READMEs. The 14 LICENSE copies the card also asks for are 2,828 lines of byte-identical text on their own, which puts the two halves together over the 3,000-line threshold, so they land as a second PR off this branch once this one merges (that is why this body says Part of, not Fixes).

The reading

publint 0.3.25 and @arethetypeswrong/cli 0.18.5, over all 73 non-private manifests under packages/** (none under ui/), each staged as npm pack would ship it — the manifest, the files whitelist, README/LICENSE/CHANGELOG and each bin target — on a fresh origin/main (d1ea2363f) build of every one of them. No gate is added for either tool; this is the one-time reading the card asks for.

before after
packages with at least one publint message 73 3
publint messages 173 3
packages with at least one attw problem 48 16
attw problems 111 58

Per package, every row that carried an attw problem before or still carries one:

package publint before publint after attw before attw after
@objectstack/spec 2 0 19 19
@objectstack/platform-objects 3 0 21 10
@objectstack/cli 1 0 5 5
@objectstack/metadata 1 0 5 5
@objectstack/core 2 1 3 3
@objectstack/lint 1 0 2 2
@objectstack/metadata-core 1 0 2 2
@objectstack/plugin-auth 4 0 5 2
@objectstack/service-cluster 2 0 2 2
create-objectstack 1 0 2 2
@objectstack/connector-imap 4 0 3 1
@objectstack/driver-memory 3 0 2 1
@objectstack/objectql 3 0 3 1
@objectstack/plugin-webhooks 2 0 1 1
@objectstack/service-datasource 2 0 1 1
@objectstack/types 3 0 3 1
@objectstack/account 3 0 1 0
@objectstack/client 3 0 1 0
@objectstack/client-react 3 0 1 0
@objectstack/connector-mcp 4 0 1 0
@objectstack/connector-openapi 4 0 1 0
@objectstack/connector-rest 4 0 1 0
@objectstack/connector-slack 4 0 1 0
@objectstack/driver-mongodb 3 0 1 0
@objectstack/driver-sql 3 0 1 0
@objectstack/driver-sqlite-wasm 3 0 1 0
@objectstack/driver-turso 3 0 1 0
@objectstack/embedder-openai 4 0 1 0
@objectstack/formula 4 0 1 0
@objectstack/hono 3 0 1 0
@objectstack/knowledge-memory 4 0 1 0
@objectstack/knowledge-ragflow 4 0 1 0
@objectstack/organizations 4 0 1 0
@objectstack/plugin-approvals 4 0 1 0
@objectstack/plugin-audit 3 0 1 0
@objectstack/plugin-dev 3 0 1 0
@objectstack/plugin-email 4 0 1 0
@objectstack/plugin-hono-server 3 0 1 0
@objectstack/plugin-pinyin-search 4 0 1 0
@objectstack/plugin-security 3 0 1 0
@objectstack/plugin-sharing 4 0 1 0
@objectstack/sdui-parser 4 0 1 0
@objectstack/service-sms 4 0 1 0
@objectstack/setup 3 0 1 0
@objectstack/studio 3 0 1 0
@objectstack/trigger-api 4 0 1 0
@objectstack/trigger-record-change 3 0 1 0
@objectstack/trigger-schedule 3 0 1 0

What was repaired

  • Types per module format on 38 manifests. One types entry served both formats, so a TypeScript consumer importing the ESM build was handed the CJS declarations — every one of attw's 38 FalseCJS. Each {types, import, require} entry becomes {import: {types, default}, require: {types, default}}, pointing at the declaration file the same tsup run already emits for that format. No subpath is added or removed and no JavaScript target moves.
  • sideEffects on the 72 manifests that declared none (only @objectstack/spec did), read per package rather than set in bulk, as the card requires. An AST pass over every published package's src listed the top-level statements that run on import — bare imports, expression statements, top-level control flow — and two packages do work on import that a consumer gets by importing alone, so they declare their entry files side-effectful instead of false: @objectstack/service-cluster-redis registers its redis cluster driver at module load ("importing this package is enough"), and create-objectstack's bin reaches its program through a bare import '../dist/index.js'. Everything else is false: the remaining hits register into a registry in the same module that exports its readers (formula's dialect engines, objectql's ajv formats), build a process-wide store inside that module's own initialiser (observability), assert a constant at load (types), or act only when the file is the process entry (cli).
  • publishConfig: { access: 'public' } on the 17 that had none, the value the other 56 declare.
  • type on the 39 that shipped .js without declaring a format. Every .js under their dist/ was read first and is CommonJS, which is what the absent field already meant. @objectstack/console and @objectstack/skills ship no JavaScript at all, so they stay unset and keep publint's suggestion.
  • engines.node >= 22.0.0 on the 22 that had no engines, and repository.url as the full git+https:// git URL on 71 (two already spelled it that way).
  • A README for the 18 published packages that had none — one paragraph of what the package is, the first import a reader writes, and a link to its docs page. These are the pages npm renders, and for these 18 npm rendered nothing.

What is left, and why

  • @objectstack/core keeps its single types entry, so its two FalseESM stay open. Its dist/index.d.ts and dist/index.d.cts are two separate declarations of the same classes, ObjectKernel's private plugins among them, so serving them per condition hands a consumer that reaches core through BOTH resolution modes two incompatible types. @objectstack/plugin-dev is that consumer: its await import('@objectstack/objectql') resolves with resolution-mode: import inside a CommonJS declaration build while its static core import resolves require. Measured with the split in place: pnpm --filter @objectstack/plugin-dev build fails TS2345 at src/dev-plugin.ts:523 with "Types have separate declarations of a private property 'plugins'"; without it, exit 0. The fix is core's dual build, not its export map.
  • NoResolution under node10, on the 15 packages with subpath exports. TypeScript's legacy node resolution predates exports and cannot read a subpath from it at all. Every package here declares engines.node >= 22.0.0, and the alternative — a typesVersions map — is a second declaration of the same surface, drifting from exports the day either is edited. Left declared rather than mirrored.
  • CJSResolvesToESM on four subpaths (cli ././console/./hook-body, create-objectstack/created-summary, metadata-core/testing, service-cluster/testing): these are ESM-only entries, so a require() from CommonJS reaches ESM. Making them dual-format changes the export map's shape, which packages: 73 published root packages carry inconsistent publishing metadata — 18 without README, about 13 without LICENSE, about 33 with main on the ESM file and one types entry for both formats, 19 without publishConfig, sideEffects only in spec #26095 puts outside this card.
  • FalseExportDefault on @objectstack/driver-memory: its src/index.ts ships an export default object whose CJS build lands as a default property. The repair is the package's own export surface, which this card does not touch.

The three classes above are reported to the seat as out-of-scope findings for cards of their own.

Verification

  • turbo run build --force over all 73 published packages at this head: 72 of 72 tasks successful (73 packages, one with no build task). The type additions are the risk this run exists to answer — tsup picks output extensions off type — and the built file set is byte-for-byte the same list of names: 1,103 dist JS and declaration files before and after, diff clean.
  • pnpm --filter @objectstack/plugin-dev build: exit 0 at this head.
  • dispatch-gates --commands derived 95 families for this diff; the run record reconciles with --ran at 95 accounted, 94 run, 0 unrun. Every one of the 94 exits 0. The one NOT MEASURED is check-plugin-teardown-shape.mjs --self-test, which refuses its own prerequisite on a shallow clone (exit 3, its reserved code) because its positive-control fixture is pinned to a commit this checkout cannot reach; its real scan, node scripts/check-plugin-teardown-shape.mjs, exits 0. check-engine-split-ratio.mjs --days 90 refuses the same way for the same reason and was re-run as its --self-test, which passes. CI has the full history.
  • Gates worth naming for this diff, all exit 0: check:published-files, check:published-readme-exports, check-published-readme-links.mjs, check:manifest-repository-directory, check:dts-closure, check:lean-entry-closure, check:dual-build-cjs-loads, check:lockstep-package-count, check-changeset-fixed.mjs, check-empty-changeset.mjs --base origin/main, check:sdui-manifest (the manifest re-records byte-identical).
  • Repo-wide scans (pnpm lint first among them) and the type-check lanes are CI's runs, not this branch's.

Changeset

One patch in .changeset/26095-publishing-metadata.md, naming all 73 packages: every one of them ships a changed manifest, and 18 also ship a new README.


Generated by Claude Code

…ENSE for the 14 without one

Each new README is one paragraph (what the package is), the one import a
reader writes first, and a link to its docs page. The LICENSE files are
byte copies of the root LICENSE, the same file the other 60 published
packages carry: npm packs a package's own LICENSE regardless of `files`,
and no release script copies the root one in.

Claude-Session: https://claude.ai/code/session_01UH1DPuU5rAKoNbDzEyoEw6
Co-authored-by: Claude <noreply@anthropic.com>
…fests without one

56 of the 73 published root packages already declare it; the changesets
config sets access public globally, so this changes no publish outcome and
makes the manifests say the same thing a direct `npm publish` would need.

Claude-Session: https://claude.ai/code/session_01UH1DPuU5rAKoNbDzEyoEw6
Co-authored-by: Claude <noreply@anthropic.com>
…thout it

Read per package, not a blanket value. An AST pass over every published
package's src listed the top-level statements that run on import (bare
imports, expression statements, top-level control flow); two packages do
work on import that a consumer relies on by importing alone:

- service-cluster-redis registers its `redis` cluster driver at module
  load ("importing this package is enough"), so its two entry files are
  declared side-effectful;
- create-objectstack's bin reaches the program through a bare
  `import '../dist/index.js'`, which parses argv at module load.

Everything else is `false`: the remaining hits register into a registry in
the same module that exports its readers (formula's dialect engines,
objectql's ajv formats), build a process-wide store inside that module's
own initialiser (observability), assert a constant at load (types), or
only act when the file is the process entry (cli).

Claude-Session: https://claude.ai/code/session_01UH1DPuU5rAKoNbDzEyoEw6
Co-authored-by: Claude <noreply@anthropic.com>
…sitory fields publint asks for

attw read one `types` entry for both module formats on 39 manifests, so a
TypeScript consumer importing the ESM build was handed the CJS
declarations ("masquerading as CJS" — 38 FalseCJS, plus FalseESM on
@objectstack/core, whose two entries had it the other way round). Each
`{types, import, require}` entry becomes `{import: {types, default},
require: {types, default}}`, pointing at the declaration file the same
tsup run already emits for that format. No subpath is added or removed and
no JavaScript target changes.

Alongside, three things publint reported:

- `"type"` on the 39 manifests that shipped `.js` without declaring a
  format. Every `.js` under their `dist/` was read first and is CommonJS,
  which is what the absent field already meant. `@objectstack/console` and
  `@objectstack/skills` ship no JavaScript at all, so they stay unset.
- `engines.node >= 22.0.0` on the 22 that had no `engines`, the value the
  other 51 already declare.
- `repository.url` as the full `git+https://` git URL on 71 of them; two
  manifests already spelled it that way.

Claude-Session: https://claude.ai/code/session_01UH1DPuU5rAKoNbDzEyoEw6
Co-authored-by: Claude <noreply@anthropic.com>
The LICENSE group is 2,828 of this branch's 4,012 changed lines (each file
is a 202-line byte copy of the root LICENSE), which puts the PR over the
3,000-line human-merge threshold on its own. It lands as a second PR off
this branch once this one is merged; the manifests and the new READMEs are
unaffected by the split.

Claude-Session: https://claude.ai/code/session_01UH1DPuU5rAKoNbDzEyoEw6
Co-authored-by: Claude <noreply@anthropic.com>
…s declaration build

`@objectstack/core` emits `dist/index.d.ts` and `dist/index.d.cts` as two
separate declarations of the same classes, `ObjectKernel`'s private
`plugins` among them. Serving them per condition hands a consumer that
reaches core through BOTH resolution modes two incompatible types, which
is what `@objectstack/plugin-dev` does: its `await
import('@objectstack/objectql')` resolves with `resolution-mode: import`
inside a CommonJS declaration build while its static core import resolves
`require`. Measured: `pnpm --filter @objectstack/plugin-dev build` fails
with TS2345 on dev-plugin.ts:523 ("Types have separate declarations of a
private property 'plugins'") with the split in place, and passes without
it.

So core's two entries keep the single `types` they had, and the two attw
`FalseESM` problems they carry stay open — the fix is core's dual build,
not its export map, which is a card of its own. The other 38 manifests
keep the split: their declaration pairs are tsup's `.d.ts`/`.d.mts`
emission of one source and carry no private-member identity.

Claude-Session: https://claude.ai/code/session_01UH1DPuU5rAKoNbDzEyoEw6
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/xl dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation tooling labels Oct 26, 2026
@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 91 changed file(s) yielded no anchor (packages/adapters/hono/package.json, packages/apps/account/README.md, packages/apps/account/package.json, …), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 73 changed package(s)).

What this run could not see
  • 91 changed file(s) yielded no anchor (packages/adapters/hono/package.json, packages/apps/account/README.md, packages/apps/account/package.json, …) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 175 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 6b9355299d947b1dd7be1a4799489439c0a74353 → packageMentionDocs.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · devx seat 2 · 2026-10-26T15:22Z

Seat domain:devx#2 (#20163) · session_01Q4MDXRbEJCNdPAP4SiXwp9 · reviewed head 23f2dea480 · card #26095, claim 6417373328. This is PR ① of the two serial PRs the seat set for the card. It carries Part of #26095. PR ② (14 LICENSE copies, Fixes #26095) follows on the same branch, reset to main, after this one merges.

  • Scope: 73 package.json, 18 new README.md, one patch changeset in root .changeset/. 92 files, +998/−251, which is under the human-merge threshold. Not governed. Nothing under ui/.
  • Readings:
    • Per-format types. {types, import, require} becomes {import: {types, default}, require: {types, default}} on 38 manifests, each pointing at a declaration file the same tsup run already emits. No subpath is added or removed, and no JS target moves. The dev's full --force rebuild left all 1103 dist file names identical.
    • @objectstack/core held back on purpose: the split breaks plugin-dev's dts build (TS2345, dev-plugin.ts:523). That is a real regression caught by the rebuild and correctly backed out.
    • sideEffects was read per package, not set in bulk. Two packages declare entry arrays: service-cluster-redis registers its driver at load, and create-objectstack's bin uses a bare import. I re-checked the 71 false packages myself. Across their src/** (tests excluded) there are no top-level bare side-effect imports, no globalThis/process.on writes, and no top-level register*(/.use(/.extend( calls.
    • The rest: type: "commonjs" only where every .js under dist/ was read as CommonJS, which is what the absent field already meant. publishConfig.access and engines are filled in, and the git+https repository URL is set. The READMEs follow the card's shape: one paragraph, one import, one docs link.
  • Readings (publint/attw on npm pack staging): packages with publint messages went 73 → 3, and packages with attw problems 48 → 16. Each remaining class is named, as the card asks. The gate ledger has 95 families: 94 exit 0, and 1 is NOT MEASURED because the checkout is shallow (check-plugin-teardown-shape --self-test).
  • CI, not this PR's: Scaffold E2E · Scaffold with repo dist is red in its skills-boundary step. The installed skill set includes objectui, but expected is built from ls -d objectstack-*/ in skills/. skills(ui-merge): move the objectui skill bundle into the root skills/ catalog (decision C) #26097 (merged 2026-10-26) moved the objectui bundle into root skills/ as a curated skill, so that step fails on every PR that triggers the workflow (paths: packages/create-objectstack/**). This PR only touches create-objectstack/package.json metadata. The check is not a required one. The seat files a card for the workflow fix, which is Tier H because it edits .github/workflows/scaffold-e2e.yml. Landing waits for every other check on this head to be green or skipped.
  • Out of scope: the seat files the four findings in the report as cards.

Generated by Claude Code

… shape

Both pins asserted the old `{types, import, require}` entry verbatim, so
the per-format split this branch makes reds them on purpose (Test Core
6/8). They now pin the new shape: `import` typed by tsup's `.d.mts`,
`require` by its `.d.ts`, `types` first inside each condition. What each
pin exists for — the subpath is published and `dist` is whitelisted — is
unchanged.

Claude-Session: https://claude.ai/code/session_01UH1DPuU5rAKoNbDzEyoEw6
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · devx seat 2 · 2026-10-26T15:56Z

Seat domain:devx#2 (#20163) · reviewed head 1ec660e247. This round follows ACCEPT 6419816152, which reviewed 23f2dea480.


Generated by Claude Code

@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 40358686385 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

分类:failure —— 按下面的日志分诊。

失败的 job(日志抽取,best effort):

  • Test Core (5/8) — 失败步骤: Run this shard's tests

    @objectstack/plugin-security:test:  FAIL  src/controlled-by-parent-owner-may-edit.test.ts > [#25760] what the opt-in does NOT widen — each shape keeps the master-edit rule > a DELEGATED update by the 
      ↳ 失败原因: @objectstack/plugin-security:test: AssertionError: expected '[Security] Access denied: on-behalf-o…' to contain '[Security] Access denied: update on \…'
    

↳ 失败原因 是判读的关键:超时(Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言(AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️ 断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError。 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 25 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Merged via the queue into main with commit 8061f33 Oct 26, 2026
51 of 52 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-09e02s branch October 26, 2026 16:58
os-tesla pushed a commit that referenced this pull request Oct 26, 2026
Resolves packages/sdui-parser/package.json: main's publishing metadata
(#26198, engines) and this branch's LICENSE-MIT `files` entry both kept.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A6SEitNngAMugGbuJHWsDS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/xl tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants