Skip to content

Commit be92d46

Browse files
os-trumpclaude
andauthored
feat(scripts): make repository.directory mandatory for a publishable manifest, and backfill the 14 (#16705)
* fix(manifests): declare `repository.directory` on the 14 publishable packages that declared none npm renders `repository.directory` as the package page's "source" deep link, concatenated onto the repository URL. These fourteen manifests carried no `repository` block at all, so every one of those npm pages has no source link rather than a broken one -- the half of the population that `check:manifest-repository-directory` counted and deliberately did not judge. Ruled mandatory for a publishable (non-private) workspace manifest, so this is the backfill the ruling asks for. The block is the canonical one 57 of the 58 declaring manifests already carry (`type` + `url` + `directory`); `directory` alone does not resolve on npm without the URL it is concatenated onto, which is why this is a block rather than a line. Each file keeps its own indentation -- `connector-openapi` is four-space and stays four-space -- and the key sits where the tree already puts it, immediately before `files`. Private manifests are untouched: they publish nothing, so they have no npm page for the link to be missing from. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zTkyNHJ7TkuN2oXtP5x37 * feat(scripts): make `repository.directory` mandatory for a publishable manifest `check:manifest-repository-directory` shipped judging only the manifests that DECLARED the field and counting the rest, because whether declaring is mandatory was a policy question. It has been ruled: a publishable (non-private) workspace manifest declares `repository.directory` naming its own directory. A publishable manifest that declares nothing is now a finding rather than a skip, and every prose passage that put the question to the reader -- in the script's header, in its refusal text, in its verdict line and in the CI step's comment -- is replaced by what was ruled. Silence stays exempt for a PRIVATE manifest, which publishes nothing and so has no npm page for a link to be missing from; a private manifest that declares a WRONG directory is still judged, because privacy exempts silence, not error. The anti-vacuity design grows with the population it now reads. This gate had one predicate and now has two, and the second empties in the direction that makes no noise: a `isPublishable` stuck on false owes the new invariant to nobody and passes every silent manifest. So `isPublishable` gets its own two-direction control pair (a named non-private subject must read PUBLISHABLE, a `private: true` one must read PRIVATE) alongside the tracked-directory pair, all four must fire before any verdict prints, and `MIN_PUBLISHABLE` floors the population itself -- the probes cannot catch a field renamed upstream and the floor cannot catch a predicate stuck in place, so both instruments are kept and neither is described as covering the other. The census pins move rather than going stale: 82 manifests, 72 declaring, 70 publishable, 0 publishable declaring nothing, 530 tracked directories, all re-measured on the post-backfill tree, with every floor re-derived from those numbers rather than carried over. The self-test's battery roster gains the new battery and its floors are re-derived too -- two of them had drifted below their batteries (5 against 6 cases, 9 against 12), and slack in a floor is exactly that many cases allowed to stop running unnoticed. Changeset: the fourteen backfilled manifests are published files of released packages, and the field is only read once it is published, so this takes a `patch` per package rather than `skip-changeset`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zTkyNHJ7TkuN2oXtP5x37 * fix(scripts): name both predicates in the control-probe floor refusal The control floor now covers four probes across two predicates, and its refusal text still named only the tracked-directory one. Surfaced by the ablation that sticks `isPublishable` on true: the run refused for the right reason and explained it as the wrong one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zTkyNHJ7TkuN2oXtP5x37 --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 4c31f02 commit be92d46

17 files changed

Lines changed: 461 additions & 111 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
"@objectstack/connector-mcp": patch
3+
"@objectstack/connector-openapi": patch
4+
"@objectstack/connector-rest": patch
5+
"@objectstack/connector-slack": patch
6+
"@objectstack/embedder-openai": patch
7+
"@objectstack/knowledge-memory": patch
8+
"@objectstack/knowledge-ragflow": patch
9+
"@objectstack/plugin-approvals": patch
10+
"@objectstack/plugin-email": patch
11+
"@objectstack/plugin-pinyin-search": patch
12+
"@objectstack/plugin-reports": patch
13+
"@objectstack/plugin-sharing": patch
14+
"@objectstack/service-sms": patch
15+
"@objectstack/trigger-api": patch
16+
---
17+
18+
These fourteen packages now declare `repository.directory`, so their npm pages carry a working "source" deep link to their own directory in the monorepo.
19+
20+
npm renders that field by concatenating it onto `repository.url`. None of these fourteen manifests carried a `repository` block at all, so every one of their npm pages offered no route from the package back to its code — not a broken link, no link. That is what this publishes: the block those pages read, naming each package's own directory.
21+
22+
Nothing else about these packages changes. No export, no runtime behaviour, no dependency and no file in the tarball other than the manifest's own `repository` key. The version bump exists because the fix is only real once it is published: the field lives in the manifest npm serves, so a corrected manifest sitting in the repository leaves the package page exactly as wrong as it was.
23+
24+
The rule behind it is now mechanical rather than remembered — `check:manifest-repository-directory` makes a publishable (non-private) workspace manifest declare the field naming its own directory, so a package added or moved after this cannot quietly go back to having no source link.

.github/workflows/lint.yml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3673,13 +3673,16 @@ jobs:
36733673
# whole population rather than a rule about moves: one of the three commits
36743674
# involved moved nothing at all — it edited `repository.url` in the same
36753675
# JSON object with the stale `directory` line as visible hunk context, and
3676-
# it shipped. Humans looked and missed it twice. ⛔ It judges only manifests
3677-
# that DECLARE the field; whether declaring is mandatory for a publishable
3678-
# package is an open policy question and a maintainer's to answer, so
3679-
# silence is counted and never a finding. Runs its own --self-test first:
3680-
# this population is `git ls-files` plus a field predicate, so a changed
3681-
# glob or a renamed field empties it silently and the production run would
3682-
# print exactly what a clean tree prints. Static read of tracked manifests;
3676+
# it shipped. Humans looked and missed it twice. Declaration is MANDATORY
3677+
# for a publishable (non-private) manifest — ruled, and the 14 that
3678+
# declared nothing were backfilled in the same change; a private manifest
3679+
# publishes nothing, so its silence is exempt while a wrong value in it is
3680+
# still judged. Runs its own --self-test first: this population is
3681+
# `git ls-files` plus TWO field predicates, so a changed glob, a renamed
3682+
# `repository.directory` or a `name`/`private` that stops reading as
3683+
# publishable each empty it silently and the production run would print
3684+
# exactly what a clean tree prints — hence pinned floors on all four counts
3685+
# and a control pair on each predicate. Static read of tracked manifests;
36833686
# no build, no network, sub-second.
36843687
- name: Manifest repository.directory guard
36853688
run: pnpm check:manifest-repository-directory

packages/connectors/connector-mcp/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@
3939
"ai",
4040
"tools"
4141
],
42+
"repository": {
43+
"type": "git",
44+
"url": "https://github.com/objectstack-ai/objectstack.git",
45+
"directory": "packages/connectors/connector-mcp"
46+
},
4247
"files": [
4348
"dist",
4449
"README.md",

packages/connectors/connector-openapi/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
"integration",
3838
"api"
3939
],
40+
"repository": {
41+
"type": "git",
42+
"url": "https://github.com/objectstack-ai/objectstack.git",
43+
"directory": "packages/connectors/connector-openapi"
44+
},
4045
"files": [
4146
"dist",
4247
"README.md",

packages/connectors/connector-rest/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
"integration",
3737
"http"
3838
],
39+
"repository": {
40+
"type": "git",
41+
"url": "https://github.com/objectstack-ai/objectstack.git",
42+
"directory": "packages/connectors/connector-rest"
43+
},
3944
"files": [
4045
"dist",
4146
"README.md",

packages/connectors/connector-slack/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
"integration",
3535
"messaging"
3636
],
37+
"repository": {
38+
"type": "git",
39+
"url": "https://github.com/objectstack-ai/objectstack.git",
40+
"directory": "packages/connectors/connector-slack"
41+
},
3742
"files": [
3843
"dist",
3944
"README.md",

packages/plugins/embedder-openai/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
"siliconflow",
4141
"ollama"
4242
],
43+
"repository": {
44+
"type": "git",
45+
"url": "https://github.com/objectstack-ai/objectstack.git",
46+
"directory": "packages/plugins/embedder-openai"
47+
},
4348
"files": [
4449
"dist",
4550
"README.md",

packages/plugins/knowledge-memory/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
"memory",
3838
"in-memory"
3939
],
40+
"repository": {
41+
"type": "git",
42+
"url": "https://github.com/objectstack-ai/objectstack.git",
43+
"directory": "packages/plugins/knowledge-memory"
44+
},
4045
"files": [
4146
"dist",
4247
"README.md",

packages/plugins/knowledge-ragflow/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
"rag",
3838
"ragflow"
3939
],
40+
"repository": {
41+
"type": "git",
42+
"url": "https://github.com/objectstack-ai/objectstack.git",
43+
"directory": "packages/plugins/knowledge-ragflow"
44+
},
4045
"files": [
4146
"dist",
4247
"README.md",

packages/plugins/plugin-approvals/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@
4545
"workflow",
4646
"process"
4747
],
48+
"repository": {
49+
"type": "git",
50+
"url": "https://github.com/objectstack-ai/objectstack.git",
51+
"directory": "packages/plugins/plugin-approvals"
52+
},
4853
"files": [
4954
"dist",
5055
"README.md",

0 commit comments

Comments
 (0)