)]}'
{
  "commit": "f2595883805ef6156b22899894e62e3673f456ce",
  "tree": "270c0fb26eb6ba996bf0ee6678d45735c0d9ae84",
  "parents": [
    "b223efd0c09f874ce85437f0329f40f4c46bf090"
  ],
  "author": {
    "name": "mloeppky-zoox",
    "email": "mloeppky@zoox.com",
    "time": "Thu Jul 16 13:46:02 2026 -0700"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Thu Jul 16 13:46:02 2026 -0700"
  },
  "message": "fix(npm_package_store): link first-party (JsInfo) deps into the store node_modules (#2917)\n\nFixes #2915\n\n## Problem\n\nIn `_npm_package_store_impl`, the `NpmPackageInfo` (3rd-party) branch\niterates `ctx.attr.deps` and links each dep into the store\u0027s nested\n`node_modules/{store_root}/{store_name}/node_modules/{dep}`. The `elif\nctx.attr.src and JsInfo in ctx.attr.src:` (first-party / `js_library`)\nbranch does **not** — it only creates the top-level package symlink and\nnever links its deps.\n\nConsequently, for a first-party package `@scope/web` that depends on\nfirst-party `@scope/base`, the store copy\n\n```\nnode_modules/.aspect_rules_js/@scope+web@0.0.0/node_modules/@scope/\n```\n\nis missing `@scope/base`. The package itself is linked (both at the app\nlevel and as a package-store directory); what\u0027s absent is the package\u0027s\n**direct deps** inside its *own* package-store `node_modules/`.\nApp-level `require()`s still resolve through the fully-populated\napp-level `node_modules`, so they work — but any tool that resolves a\nfirst-party package\u0027s deps **through its package-store copy** (rather\nthan the app-level link) then fails with `Cannot find module` /\n`ENOENT`. That\u0027s the `readlink`/`realpath` resolution path in #2915 /\n#2914 (and the same symptom as the closed #1092).\n\n## Fix\n\nMirror the `NpmPackageInfo` branch\u0027s direct-deps loop into the JsInfo\nbranch: same same-root-package guard, `dep_package_store_directory`\ntruthiness check, and ref-dep fallthrough to `direct_ref_deps`.\n\n## Testing\n\n- New assertion in `examples/linked_consumer/test_pkg_deps_linked.js`:\nit locates the first-party `@lib/test2` package-store link and asserts\ntest2\u0027s own deps (`@aspect-test/e`, `alias-e`) are linked into test2\u0027s\npackage-store `node_modules/` — which were absent before this change.\n- The `*_package_store_1p.listing` image-test fixtures now include\nfirst-party packages\u0027 dep links (e.g. `uuid` under `@image-test/a` and\n`@image-test/d`), giving a concrete before/after diff of the files that\nnewly become available in the sandbox.\n- Existing first-party linking targets still pass\n(`//linked_consumer:{direct,pkg,sources_test,types_test}`,\n`//js_lib_pkg/b:{test_each_target,test_parent_target}`) — existing\nlinking is unaffected.\n\n## Notes / caveats\n\n- This adds nested symlink outputs to **every** first-party package\nstore, so expect broader cache invalidation. As with the 3rd-party\nbranch, watch for an output-path collision if a dep is aliased to the\npackage\u0027s own name.\n- Related: closed #1092 (same \"Cannot find module\" symptom) and open\n#2226 (first-party peer-dep propagation, a different mechanism in\n`npm_link_package_store.bzl`).\n\nCo-Authored-By: Claude Code\n\n---------\n\nSigned-off-by: mloeppky-zoox \u003cmloeppky@zoox.com\u003e\nCo-authored-by: Cursor \u003ccursoragent@cursor.com\u003e\nCo-authored-by: Jason Bedard \u003cjason+github@jbedard.ca\u003e\nCo-authored-by: Claude Fable 5 \u003cnoreply@anthropic.com\u003e",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "01e681166b3a8f43ba937e89a1b854fa3cbd4928",
      "old_mode": 33261,
      "old_path": "examples/.aspect/rules/external_repository_action_cache/npm_translate_lock_LTE4Nzc1MDcwNjU\u003d",
      "new_id": "9a75355500477b0c7dde5d239da0b160a38c24e9",
      "new_mode": 33261,
      "new_path": "examples/.aspect/rules/external_repository_action_cache/npm_translate_lock_LTE4Nzc1MDcwNjU\u003d"
    },
    {
      "type": "modify",
      "old_id": "4dfdc95033aea508193d22751bca2c6c8b41f715",
      "old_mode": 33188,
      "old_path": "examples/linked_consumer/BUILD.bazel",
      "new_id": "26c8e9d7e1feff3099306326675ecaf4d68165da",
      "new_mode": 33188,
      "new_path": "examples/linked_consumer/BUILD.bazel"
    },
    {
      "type": "modify",
      "old_id": "e33a5181df7b4eab4f7face20802857b25864c0a",
      "old_mode": 33188,
      "old_path": "examples/linked_consumer/test_pkg_deps_linked.js",
      "new_id": "9f8779331fbe5a3dec98fb26164bba32280db381",
      "new_mode": 33188,
      "new_path": "examples/linked_consumer/test_pkg_deps_linked.js"
    },
    {
      "type": "modify",
      "old_id": "d59e8b7467ec30a07a0a9253b723f0b1646974d7",
      "old_mode": 33188,
      "old_path": "examples/linked_lib/package.json",
      "new_id": "4fc5370f32e4f82f3d8f56f608a0e7ecbb51dc9f",
      "new_mode": 33188,
      "new_path": "examples/linked_lib/package.json"
    },
    {
      "type": "modify",
      "old_id": "74b402d4a079425a3afc8c03ad7bed682eca45f4",
      "old_mode": 33188,
      "old_path": "examples/pnpm-lock.yaml",
      "new_id": "a83e82033dd8fe909e42b09d3008be8524e1680b",
      "new_mode": 33188,
      "new_path": "examples/pnpm-lock.yaml"
    },
    {
      "type": "modify",
      "old_id": "a4d911792d7b62aa37cc75cc163f14105060565e",
      "old_mode": 33188,
      "old_path": "js/private/test/image/checksum_test.expected",
      "new_id": "aff8c116f25f20ae6d460589ebc019ee549239ce",
      "new_mode": 33188,
      "new_path": "js/private/test/image/checksum_test.expected"
    },
    {
      "type": "modify",
      "old_id": "b8532b1221e9879c421966305b875007a94d2ac4",
      "old_mode": 33188,
      "old_path": "js/private/test/image/custom_layers_nomatch_test_package_store_1p.listing",
      "new_id": "79e1b3398115180a516358b7ef4c3f9edbf5a154",
      "new_mode": 33188,
      "new_path": "js/private/test/image/custom_layers_nomatch_test_package_store_1p.listing"
    },
    {
      "type": "modify",
      "old_id": "3b48ff991ef4b82539aabd3beb785fd9d53b95f6",
      "old_mode": 33188,
      "old_path": "js/private/test/image/custom_owner_test_package_store_1p.listing",
      "new_id": "acbbb01cfdac52de954fc4df8e143006cc7fed97",
      "new_mode": 33188,
      "new_path": "js/private/test/image/custom_owner_test_package_store_1p.listing"
    },
    {
      "type": "modify",
      "old_id": "40957b4c16549e1239c5209afd7188b0822eeb85",
      "old_mode": 33188,
      "old_path": "js/private/test/image/default_test_package_store_1p.listing",
      "new_id": "7d336b7a14a48aed6b295f1f175a035c841bbde9",
      "new_mode": 33188,
      "new_path": "js/private/test/image/default_test_package_store_1p.listing"
    },
    {
      "type": "modify",
      "old_id": "b8532b1221e9879c421966305b875007a94d2ac4",
      "old_mode": 33188,
      "old_path": "js/private/test/image/regex_edge_cases_test_package_store_1p.listing",
      "new_id": "79e1b3398115180a516358b7ef4c3f9edbf5a154",
      "new_mode": 33188,
      "new_path": "js/private/test/image/regex_edge_cases_test_package_store_1p.listing"
    },
    {
      "type": "modify",
      "old_id": "e155281a03fc347b911058f0e08f2993c9854188",
      "old_mode": 33188,
      "old_path": "npm/private/npm_package_store.bzl",
      "new_id": "c33ac08944c8fb251b7ade8ef2463c3544a036a3",
      "new_mode": 33188,
      "new_path": "npm/private/npm_package_store.bzl"
    }
  ]
}
