feat(identity): derive package identity from package.json (#94 Wave 1 stages 1-2) - #115
feat(identity): derive package identity from package.json (#94 Wave 1 stages 1-2)#115ScriptedAlchemy wants to merge 4 commits into
Conversation
Package.json remains authoritative for packaged projects. Unversioned and unpackaged projects now carry a labeled development fallback through the normalized model, ProjectContext, manifests, inspect, and source status. plugin.version mismatches warn only against a real package.json version; plugin.name is unchanged.
🦋 Changeset detectedLatest commit: 826b2ab The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 642e14353b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (alreadyDeclared) return inputs; | ||
| return [...inputs, { path: packageJsonPath, sha256: packageSnapshot.sha256 }]; |
There was a problem hiding this comment.
Keep package.json in every freshness snapshot
When .gitignore excludes package.json (for example via *.json), snapshotProjectSource() omits it, but this branch adds it to ProjectContext.sourceInputs anyway. ArtifactService.build() later compares that context with a fresh snapshot using exact array equality, so every Workbench build is rejected with AB7101 even when no source changed. Force package.json into snapshotProjectSource() as well so preparation and freshness checks use the same input set.
Useful? React with 👍 / 👎.
| const packageVersionPattern = | ||
| /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/u; |
There was a problem hiding this comment.
Reject invalid prerelease identifiers
For package versions containing an invalid SemVer prerelease, such as 1.0.0-01, 1.0.0-., or 1.0.0-alpha..1, this pattern returns true because it treats the entire prerelease as an unrestricted character run; parseSemanticVersion() applies the same loose rule. These values are therefore recorded as authoritative semantic package versions and accepted by artifact-manifest validation instead of receiving the development fallback or being rejected. Validate dot-separated identifiers, including the no-empty-identifiers and no-leading-zero numeric rules.
Useful? React with 👍 / 👎.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
The labeled 0.0.0-dev fallback is covered by skills-starter, hooks-and-scripts, and mcp-app.
Adopted from PR #115 (parallel session): the labeled 0.0.0-dev development-fallback naming, package identity on the dev source status DTO (SourceStatus + agent API wire DTOs + coordinator passthrough), a minor changeset (new public manifest/context fields are a feature), and ProjectService-level source-status test coverage. Codex fixes: reject npm-reserved package names (node_modules, favicon.ico) and ignore a package.json symlinked outside the project root (AB4011) so identity cannot drift without a revision change. Also pins rejection of invalid semver prerelease identifiers, which #115's looser pattern accepted.
|
Closing in favor of #117, which lands the same #94 stages 1-2 scope — thanks for this parallel take; several of its choices were folded into #117 (commit 4179a20) with credit: Adopted from this PR
Where #117 diverges deliberately
Branch left intact. |
Adopted from PR #115 (parallel session): the labeled 0.0.0-dev development-fallback naming, package identity on the dev source status DTO (SourceStatus + agent API wire DTOs + coordinator passthrough), a minor changeset (new public manifest/context fields are a feature), and ProjectService-level source-status test coverage. Codex fixes: reject npm-reserved package names (node_modules, favicon.ico) and ignore a package.json symlinked outside the project root (AB4011) so identity cannot drift without a revision change. Also pins rejection of invalid semver prerelease identifiers, which #115's looser pattern accepted.
…ages 1-2) (#121) * feat(identity): derive package name/version into project identity (stages 1-2) Part of #94. Derives validated packageName/packageVersion from the project's package.json into NormalizedMetadata and ProjectContext, and exposes both axes distinctly in artifact manifests, inspect output, and dev status DTOs (ArtifactEpoch). Projects without a package version keep a clearly labeled development fallback in displays; nothing new is required. New warning diagnostics: AB4008 (plugin.version differs from the package version), AB4009 (invalid npm package name), AB4010 (invalid package semver), AB4011 (unparsable package.json). Per G9, plugin.name stays the host-native slug and is never derived. * feat(identity): adopt #115 conventions and fix Codex findings Adopted from PR #115 (parallel session): the labeled 0.0.0-dev development-fallback naming, package identity on the dev source status DTO (SourceStatus + agent API wire DTOs + coordinator passthrough), a minor changeset (new public manifest/context fields are a feature), and ProjectService-level source-status test coverage. Codex fixes: reject npm-reserved package names (node_modules, favicon.ico) and ignore a package.json symlinked outside the project root (AB4011) so identity cannot drift without a revision change. Also pins rejection of invalid semver prerelease identifiers, which #115's looser pattern accepted. * fix(workbench): accept the derived package identity fields in strict status and artifact decoders The workbench client decodes /api/project/status and the artifact inspection route with exact-key validation, so the new optional packageName/packageVersion axes made every decode fail and the dashboard never settled (all browser e2e suites timed out on visibility). Allow both optional fields in sourceStatusSchema, artifactEpochSchema, and the artifact-client isProject check, and flip the overview.e2e source-status pin to include the derived packageName.
Summary
Wave 1 Lane A, stages 1–2 of #94: derive validated package identity from
package.jsonand expose it without replacing host plugin identity.package.jsonname/version becomepackageName/packageVersiononProjectContext, the normalized model, artifact manifests, inspect results, and development source status.plugin.versionstill authors the native plugin version. A mismatch warns (AB4008) and never silently wins;package.jsonis authoritative.plugin.nameis unchanged (G9). Scoped package names are not host slugs.0.0.0-devdevelopment fallback. Release fail-closed without package identity stays a later stage.Proof
audiobook-curatorkeeps one version source:package.json1.0.0. Config comments document the derivation.skills-starter,hooks-and-scripts,mcp-app) have no package version and are labeled0.0.0-dev.Fixes #94 (Wave 1 stages 1–2 only;
plugin.versionremains required).Test plan
core.test.ts,project-identity.test.ts,config.test.ts,manifest.test.ts,dev-services.test.ts(76 passed)examples-contract.test.tsinspect pins for skills-starter and mcp-app identityplugin.versionmismatch warns AB4008 and does not overridepackage.jsonplugin.namestays the host slug when package name differs