library-skills 0.0.9 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "library-skills",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "Library Skills, AI Agents using libraries, as intended, always up to date.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -100,6 +100,9 @@ function iterNodePackageRoots(nodeModules) {
100
100
  if (!isDirectory(fullPath)) {
101
101
  continue;
102
102
  }
103
+ if (entry.startsWith(".")) {
104
+ continue;
105
+ }
103
106
  if (entry.startsWith("@")) {
104
107
  for (const scopedEntry of readdirSync(fullPath).sort()) {
105
108
  const scopedPath = join(fullPath, scopedEntry);
package/ts/dist/cli.d.ts CHANGED
@@ -20,6 +20,11 @@ interface UvWorkspace {
20
20
  members: string[];
21
21
  currentMember: string | null;
22
22
  }
23
+ interface NodeWorkspace {
24
+ root: string;
25
+ members: string[];
26
+ currentMember: string | null;
27
+ }
23
28
 
24
29
  interface ProjectContext {
25
30
  cwd: string;
@@ -28,6 +33,9 @@ interface ProjectContext {
28
33
  sitePackagesDir: string | null;
29
34
  nodeModulesDir: string | null;
30
35
  workspace: UvWorkspace | null;
36
+ nodeWorkspace: NodeWorkspace | null;
37
+ workspaceDependencyFiles: string[];
38
+ nodeWorkspaceDependencyFiles: string[];
31
39
  dependencyFiles: string[];
32
40
  }
33
41
  interface InstalledStatus {
package/ts/dist/cli.js CHANGED
@@ -114,6 +114,9 @@ function iterNodePackageRoots(nodeModules) {
114
114
  if (!isDirectory(fullPath)) {
115
115
  continue;
116
116
  }
117
+ if (entry.startsWith(".")) {
118
+ continue;
119
+ }
117
120
  if (entry.startsWith("@")) {
118
121
  for (const scopedEntry of readdirSync(fullPath).sort()) {
119
122
  const scopedPath = join(fullPath, scopedEntry);
@@ -519,6 +522,28 @@ function getNodeTopLevelDeps(projectRoot) {
519
522
  if (!existsSync2(packageJson)) {
520
523
  return null;
521
524
  }
525
+ return getNodeTopLevelDepsFromFiles([packageJson]);
526
+ }
527
+ function getNodeTopLevelDepsFromFiles(packageJsonFiles) {
528
+ if (packageJsonFiles.length === 0) {
529
+ return null;
530
+ }
531
+ const deps = /* @__PURE__ */ new Set();
532
+ let found = false;
533
+ for (const packageJson of packageJsonFiles) {
534
+ if (!existsSync2(packageJson)) {
535
+ continue;
536
+ }
537
+ const data = readPackageJson(packageJson);
538
+ if (data === null) {
539
+ return null;
540
+ }
541
+ found = true;
542
+ extractNodeTopLevelDeps(data, deps);
543
+ }
544
+ return found ? deps : null;
545
+ }
546
+ function readPackageJson(packageJson) {
522
547
  let data;
523
548
  try {
524
549
  data = JSON.parse(readFileSync2(packageJson, "utf8"));
@@ -526,9 +551,11 @@ function getNodeTopLevelDeps(projectRoot) {
526
551
  return null;
527
552
  }
528
553
  if (!isRecord2(data)) {
529
- return /* @__PURE__ */ new Set();
554
+ return {};
530
555
  }
531
- const deps = /* @__PURE__ */ new Set();
556
+ return data;
557
+ }
558
+ function extractNodeTopLevelDeps(data, deps) {
532
559
  for (const field of [
533
560
  "dependencies",
534
561
  "devDependencies",
@@ -543,7 +570,6 @@ function getNodeTopLevelDeps(projectRoot) {
543
570
  deps.add(normalizePackageName(packageName));
544
571
  }
545
572
  }
546
- return deps;
547
573
  }
548
574
  function getTopLevelDeps(projectRoot) {
549
575
  const dependencySets = [
@@ -558,6 +584,9 @@ function getTopLevelDeps(projectRoot) {
558
584
  function getWorkspaceTopLevelDeps(pyprojects) {
559
585
  return getPythonTopLevelDepsFromFiles(pyprojects);
560
586
  }
587
+ function getNodeWorkspaceTopLevelDeps(packageJsonFiles) {
588
+ return getNodeTopLevelDepsFromFiles(packageJsonFiles);
589
+ }
561
590
  function extractDepsFromSpecs(depSpecs, deps) {
562
591
  for (const depSpec of depSpecs) {
563
592
  if (typeof depSpec !== "string") {
@@ -733,6 +762,26 @@ function findUvWorkspace(cwd) {
733
762
  }
734
763
  return null;
735
764
  }
765
+ function findNodeWorkspace(cwd) {
766
+ for (const directory of ancestors(cwd)) {
767
+ const packageJson = `${directory}/package.json`;
768
+ if (!existsSync4(packageJson)) {
769
+ continue;
770
+ }
771
+ const data = readPackageJson2(packageJson);
772
+ const memberGlobs = getNodeWorkspaceGlobs(data);
773
+ if (memberGlobs === null) {
774
+ continue;
775
+ }
776
+ const members = findNodeWorkspaceMembers(directory, memberGlobs);
777
+ return {
778
+ root: directory,
779
+ members,
780
+ currentMember: findCurrentMember(cwd, members)
781
+ };
782
+ }
783
+ return null;
784
+ }
736
785
  function workspaceDependencyFiles(workspace) {
737
786
  if (workspace.currentMember !== null) {
738
787
  return [`${workspace.currentMember}/pyproject.toml`];
@@ -742,6 +791,15 @@ function workspaceDependencyFiles(workspace) {
742
791
  ...workspace.members.map((member) => `${member}/pyproject.toml`)
743
792
  ].filter((path) => existsSync4(path));
744
793
  }
794
+ function nodeWorkspaceDependencyFiles(workspace) {
795
+ if (workspace.currentMember !== null) {
796
+ return [`${workspace.currentMember}/package.json`];
797
+ }
798
+ return [
799
+ `${workspace.root}/package.json`,
800
+ ...workspace.members.map((member) => `${member}/package.json`)
801
+ ].filter((path) => existsSync4(path));
802
+ }
745
803
  function readPyproject(path) {
746
804
  try {
747
805
  const data = parse3(readFileSync3(path, "utf8"));
@@ -750,6 +808,14 @@ function readPyproject(path) {
750
808
  return {};
751
809
  }
752
810
  }
811
+ function readPackageJson2(path) {
812
+ try {
813
+ const data = JSON.parse(readFileSync3(path, "utf8"));
814
+ return isRecord3(data) ? data : {};
815
+ } catch {
816
+ return {};
817
+ }
818
+ }
753
819
  function hasUvWorkspace(data) {
754
820
  const tool = data["tool"];
755
821
  if (!isRecord3(tool)) {
@@ -786,6 +852,36 @@ function findWorkspaceMembers(root, data) {
786
852
  }
787
853
  return [...members].sort();
788
854
  }
855
+ function getNodeWorkspaceGlobs(data) {
856
+ const workspaces = data["workspaces"];
857
+ if (Array.isArray(workspaces)) {
858
+ return workspaces.filter((value) => typeof value === "string");
859
+ }
860
+ if (isRecord3(workspaces)) {
861
+ const packages = workspaces["packages"];
862
+ if (Array.isArray(packages)) {
863
+ return packages.filter((value) => typeof value === "string");
864
+ }
865
+ }
866
+ return null;
867
+ }
868
+ function findNodeWorkspaceMembers(root, memberGlobs) {
869
+ const includes = memberGlobs.filter((pattern) => !pattern.startsWith("!"));
870
+ const excludes = memberGlobs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
871
+ const members = /* @__PURE__ */ new Set();
872
+ for (const memberGlob of includes) {
873
+ for (const member of expandMemberGlob(root, memberGlob)) {
874
+ const relativePath = relative3(root, member).split(sep).join("/");
875
+ if (isExcluded(relativePath, excludes)) {
876
+ continue;
877
+ }
878
+ if (isFile(`${member}/package.json`)) {
879
+ members.add(resolve3(member));
880
+ }
881
+ }
882
+ }
883
+ return [...members].sort();
884
+ }
789
885
  function getWorkspaceTable(data) {
790
886
  const tool = data["tool"];
791
887
  if (!isRecord3(tool)) {
@@ -893,6 +989,10 @@ function findProjectRoot(cwd) {
893
989
  if (workspace !== null) {
894
990
  return workspace.root;
895
991
  }
992
+ const nodeWorkspace = findNodeWorkspace(cwd);
993
+ if (nodeWorkspace !== null) {
994
+ return nodeWorkspace.root;
995
+ }
896
996
  for (const directory of ancestors2(cwd)) {
897
997
  if (isFile2(join4(directory, "pyproject.toml")) || isFile2(join4(directory, "uv.lock")) || venvFromDotVenv(directory) !== null || isFile2(join4(directory, "package.json")) || isDirectory4(join4(directory, "node_modules"))) {
898
998
  return directory;
@@ -1020,7 +1120,10 @@ function isDirectory4(path) {
1020
1120
  // ts/src/cli.ts
1021
1121
  function getProjectContext(cwd = process.cwd()) {
1022
1122
  const workspace = findUvWorkspace(cwd);
1023
- const projectRoot = workspace?.root ?? findProjectRoot(cwd) ?? cwd;
1123
+ const nodeWorkspace = findNodeWorkspace(cwd);
1124
+ const projectRoot = workspace?.root ?? nodeWorkspace?.root ?? findProjectRoot(cwd) ?? cwd;
1125
+ const workspaceFiles = workspace === null ? [] : workspaceDependencyFiles(workspace);
1126
+ const nodeWorkspaceFiles = nodeWorkspace === null ? [] : nodeWorkspaceDependencyFiles(nodeWorkspace);
1024
1127
  const targetEnvironment = findVenv(cwd);
1025
1128
  const sitePackagesDir = targetEnvironment === null ? null : getSitePackagesDir(targetEnvironment);
1026
1129
  const nodeModulesDir = findNodeModules(cwd);
@@ -1031,7 +1134,10 @@ function getProjectContext(cwd = process.cwd()) {
1031
1134
  sitePackagesDir,
1032
1135
  nodeModulesDir,
1033
1136
  workspace,
1034
- dependencyFiles: workspace ? workspaceDependencyFiles(workspace) : []
1137
+ nodeWorkspace,
1138
+ workspaceDependencyFiles: workspaceFiles,
1139
+ nodeWorkspaceDependencyFiles: nodeWorkspaceFiles,
1140
+ dependencyFiles: [...workspaceFiles, ...nodeWorkspaceFiles]
1035
1141
  };
1036
1142
  }
1037
1143
  function scanContext(context) {
@@ -1074,8 +1180,8 @@ function topLevelSkills({
1074
1180
  return skills;
1075
1181
  }
1076
1182
  const topLevelDeps = getTopLevelDeps(context.projectRoot);
1077
- const workspaceTopLevelDeps = context.workspace === null ? null : getWorkspaceTopLevelDeps(context.dependencyFiles);
1078
- const selectedTopLevelDeps = context.workspace === null ? topLevelDeps : workspaceTopLevelDeps;
1183
+ const workspaceTopLevelDeps = getWorkspaceTopLevelDepsForContext(context);
1184
+ const selectedTopLevelDeps = context.workspace === null && context.nodeWorkspace === null ? topLevelDeps : workspaceTopLevelDeps;
1079
1185
  if (selectedTopLevelDeps === null) {
1080
1186
  return skills;
1081
1187
  }
@@ -1083,6 +1189,16 @@ function topLevelSkills({
1083
1189
  (skill) => selectedTopLevelDeps.has(normalizePackageName(skill.packageName))
1084
1190
  );
1085
1191
  }
1192
+ function getWorkspaceTopLevelDepsForContext(context) {
1193
+ const dependencySets = [
1194
+ context.workspace === null ? null : getWorkspaceTopLevelDeps(context.workspaceDependencyFiles),
1195
+ context.nodeWorkspace === null ? null : getNodeWorkspaceTopLevelDeps(context.nodeWorkspaceDependencyFiles)
1196
+ ].filter((deps) => deps !== null);
1197
+ if (dependencySets.length === 0) {
1198
+ return null;
1199
+ }
1200
+ return new Set(dependencySets.flatMap((deps) => [...deps]));
1201
+ }
1086
1202
  function printWarnings(warnings) {
1087
1203
  for (const warning of warnings) {
1088
1204
  console.log(`Warning: ${warning}`);
@@ -1108,6 +1224,11 @@ function printContext(context) {
1108
1224
  if (context.workspace.currentMember !== null) {
1109
1225
  console.log(`Workspace member: ${context.workspace.currentMember}`);
1110
1226
  }
1227
+ } else if (context.nodeWorkspace !== null) {
1228
+ console.log(`Workspace root: ${context.nodeWorkspace.root}`);
1229
+ if (context.nodeWorkspace.currentMember !== null) {
1230
+ console.log(`Workspace member: ${context.nodeWorkspace.currentMember}`);
1231
+ }
1111
1232
  }
1112
1233
  console.log(
1113
1234
  `Target Python environment: ${context.targetEnvironment ? displayPath(context.targetEnvironment, context.projectRoot) : "not found"}`
@@ -1148,8 +1269,8 @@ function scanJsonPayload({
1148
1269
  }) {
1149
1270
  return {
1150
1271
  project_root: context.projectRoot,
1151
- workspace_root: context.workspace?.root ?? "",
1152
- workspace_member: context.workspace?.currentMember ?? "",
1272
+ workspace_root: context.workspace?.root ?? context.nodeWorkspace?.root ?? "",
1273
+ workspace_member: context.workspace?.currentMember ?? context.nodeWorkspace?.currentMember ?? "",
1153
1274
  dependency_files: context.dependencyFiles,
1154
1275
  target_environment: context.targetEnvironment ?? "",
1155
1276
  node_modules: context.nodeModulesDir ?? "",
package/ts/dist/deps.cjs CHANGED
@@ -21,6 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var deps_exports = {};
22
22
  __export(deps_exports, {
23
23
  getNodeTopLevelDeps: () => getNodeTopLevelDeps,
24
+ getNodeTopLevelDepsFromFiles: () => getNodeTopLevelDepsFromFiles,
25
+ getNodeWorkspaceTopLevelDeps: () => getNodeWorkspaceTopLevelDeps,
24
26
  getPythonTopLevelDeps: () => getPythonTopLevelDeps,
25
27
  getPythonTopLevelDepsFromFiles: () => getPythonTopLevelDepsFromFiles,
26
28
  getTopLevelDeps: () => getTopLevelDeps,
@@ -98,6 +100,28 @@ function getNodeTopLevelDeps(projectRoot) {
98
100
  if (!(0, import_node_fs2.existsSync)(packageJson)) {
99
101
  return null;
100
102
  }
103
+ return getNodeTopLevelDepsFromFiles([packageJson]);
104
+ }
105
+ function getNodeTopLevelDepsFromFiles(packageJsonFiles) {
106
+ if (packageJsonFiles.length === 0) {
107
+ return null;
108
+ }
109
+ const deps = /* @__PURE__ */ new Set();
110
+ let found = false;
111
+ for (const packageJson of packageJsonFiles) {
112
+ if (!(0, import_node_fs2.existsSync)(packageJson)) {
113
+ continue;
114
+ }
115
+ const data = readPackageJson(packageJson);
116
+ if (data === null) {
117
+ return null;
118
+ }
119
+ found = true;
120
+ extractNodeTopLevelDeps(data, deps);
121
+ }
122
+ return found ? deps : null;
123
+ }
124
+ function readPackageJson(packageJson) {
101
125
  let data;
102
126
  try {
103
127
  data = JSON.parse((0, import_node_fs2.readFileSync)(packageJson, "utf8"));
@@ -105,9 +129,11 @@ function getNodeTopLevelDeps(projectRoot) {
105
129
  return null;
106
130
  }
107
131
  if (!isRecord(data)) {
108
- return /* @__PURE__ */ new Set();
132
+ return {};
109
133
  }
110
- const deps = /* @__PURE__ */ new Set();
134
+ return data;
135
+ }
136
+ function extractNodeTopLevelDeps(data, deps) {
111
137
  for (const field of [
112
138
  "dependencies",
113
139
  "devDependencies",
@@ -122,7 +148,6 @@ function getNodeTopLevelDeps(projectRoot) {
122
148
  deps.add(normalizePackageName(packageName));
123
149
  }
124
150
  }
125
- return deps;
126
151
  }
127
152
  function getTopLevelDeps(projectRoot) {
128
153
  const dependencySets = [
@@ -137,6 +162,9 @@ function getTopLevelDeps(projectRoot) {
137
162
  function getWorkspaceTopLevelDeps(pyprojects) {
138
163
  return getPythonTopLevelDepsFromFiles(pyprojects);
139
164
  }
165
+ function getNodeWorkspaceTopLevelDeps(packageJsonFiles) {
166
+ return getNodeTopLevelDepsFromFiles(packageJsonFiles);
167
+ }
140
168
  function extractDepsFromSpecs(depSpecs, deps) {
141
169
  for (const depSpec of depSpecs) {
142
170
  if (typeof depSpec !== "string") {
@@ -184,6 +212,8 @@ var testing = {
184
212
  // Annotate the CommonJS export names for ESM import in node:
185
213
  0 && (module.exports = {
186
214
  getNodeTopLevelDeps,
215
+ getNodeTopLevelDepsFromFiles,
216
+ getNodeWorkspaceTopLevelDeps,
187
217
  getPythonTopLevelDeps,
188
218
  getPythonTopLevelDepsFromFiles,
189
219
  getTopLevelDeps,
@@ -1,8 +1,10 @@
1
1
  declare function getPythonTopLevelDeps(projectRoot: string): Set<string> | null;
2
2
  declare function getPythonTopLevelDepsFromFiles(pyprojects: string[]): Set<string> | null;
3
3
  declare function getNodeTopLevelDeps(projectRoot: string): Set<string> | null;
4
+ declare function getNodeTopLevelDepsFromFiles(packageJsonFiles: string[]): Set<string> | null;
4
5
  declare function getTopLevelDeps(projectRoot: string): Set<string> | null;
5
6
  declare function getWorkspaceTopLevelDeps(pyprojects: string[]): Set<string> | null;
7
+ declare function getNodeWorkspaceTopLevelDeps(packageJsonFiles: string[]): Set<string> | null;
6
8
  declare function extractDepsFromSpecs(depSpecs: unknown[], deps: Set<string>): void;
7
9
  declare function extractDepsFromDependencyGroup(groupName: unknown, dependencyGroups: Record<string, unknown>, deps: Set<string>, visited: Set<unknown>): void;
8
10
  declare function isRecord(value: unknown): value is Record<string, unknown>;
@@ -12,4 +14,4 @@ declare const testing: {
12
14
  isRecord: typeof isRecord;
13
15
  };
14
16
 
15
- export { getNodeTopLevelDeps, getPythonTopLevelDeps, getPythonTopLevelDepsFromFiles, getTopLevelDeps, getWorkspaceTopLevelDeps, testing };
17
+ export { getNodeTopLevelDeps, getNodeTopLevelDepsFromFiles, getNodeWorkspaceTopLevelDeps, getPythonTopLevelDeps, getPythonTopLevelDepsFromFiles, getTopLevelDeps, getWorkspaceTopLevelDeps, testing };
package/ts/dist/deps.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  declare function getPythonTopLevelDeps(projectRoot: string): Set<string> | null;
2
2
  declare function getPythonTopLevelDepsFromFiles(pyprojects: string[]): Set<string> | null;
3
3
  declare function getNodeTopLevelDeps(projectRoot: string): Set<string> | null;
4
+ declare function getNodeTopLevelDepsFromFiles(packageJsonFiles: string[]): Set<string> | null;
4
5
  declare function getTopLevelDeps(projectRoot: string): Set<string> | null;
5
6
  declare function getWorkspaceTopLevelDeps(pyprojects: string[]): Set<string> | null;
7
+ declare function getNodeWorkspaceTopLevelDeps(packageJsonFiles: string[]): Set<string> | null;
6
8
  declare function extractDepsFromSpecs(depSpecs: unknown[], deps: Set<string>): void;
7
9
  declare function extractDepsFromDependencyGroup(groupName: unknown, dependencyGroups: Record<string, unknown>, deps: Set<string>, visited: Set<unknown>): void;
8
10
  declare function isRecord(value: unknown): value is Record<string, unknown>;
@@ -12,4 +14,4 @@ declare const testing: {
12
14
  isRecord: typeof isRecord;
13
15
  };
14
16
 
15
- export { getNodeTopLevelDeps, getPythonTopLevelDeps, getPythonTopLevelDepsFromFiles, getTopLevelDeps, getWorkspaceTopLevelDeps, testing };
17
+ export { getNodeTopLevelDeps, getNodeTopLevelDepsFromFiles, getNodeWorkspaceTopLevelDeps, getPythonTopLevelDeps, getPythonTopLevelDepsFromFiles, getTopLevelDeps, getWorkspaceTopLevelDeps, testing };
package/ts/dist/deps.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  normalizePackageName
3
- } from "./chunk-DKDHRFD4.js";
3
+ } from "./chunk-JRJ32CKR.js";
4
4
 
5
5
  // ts/src/deps.ts
6
6
  import { existsSync, readFileSync } from "fs";
@@ -62,6 +62,28 @@ function getNodeTopLevelDeps(projectRoot) {
62
62
  if (!existsSync(packageJson)) {
63
63
  return null;
64
64
  }
65
+ return getNodeTopLevelDepsFromFiles([packageJson]);
66
+ }
67
+ function getNodeTopLevelDepsFromFiles(packageJsonFiles) {
68
+ if (packageJsonFiles.length === 0) {
69
+ return null;
70
+ }
71
+ const deps = /* @__PURE__ */ new Set();
72
+ let found = false;
73
+ for (const packageJson of packageJsonFiles) {
74
+ if (!existsSync(packageJson)) {
75
+ continue;
76
+ }
77
+ const data = readPackageJson(packageJson);
78
+ if (data === null) {
79
+ return null;
80
+ }
81
+ found = true;
82
+ extractNodeTopLevelDeps(data, deps);
83
+ }
84
+ return found ? deps : null;
85
+ }
86
+ function readPackageJson(packageJson) {
65
87
  let data;
66
88
  try {
67
89
  data = JSON.parse(readFileSync(packageJson, "utf8"));
@@ -69,9 +91,11 @@ function getNodeTopLevelDeps(projectRoot) {
69
91
  return null;
70
92
  }
71
93
  if (!isRecord(data)) {
72
- return /* @__PURE__ */ new Set();
94
+ return {};
73
95
  }
74
- const deps = /* @__PURE__ */ new Set();
96
+ return data;
97
+ }
98
+ function extractNodeTopLevelDeps(data, deps) {
75
99
  for (const field of [
76
100
  "dependencies",
77
101
  "devDependencies",
@@ -86,7 +110,6 @@ function getNodeTopLevelDeps(projectRoot) {
86
110
  deps.add(normalizePackageName(packageName));
87
111
  }
88
112
  }
89
- return deps;
90
113
  }
91
114
  function getTopLevelDeps(projectRoot) {
92
115
  const dependencySets = [
@@ -101,6 +124,9 @@ function getTopLevelDeps(projectRoot) {
101
124
  function getWorkspaceTopLevelDeps(pyprojects) {
102
125
  return getPythonTopLevelDepsFromFiles(pyprojects);
103
126
  }
127
+ function getNodeWorkspaceTopLevelDeps(packageJsonFiles) {
128
+ return getNodeTopLevelDepsFromFiles(packageJsonFiles);
129
+ }
104
130
  function extractDepsFromSpecs(depSpecs, deps) {
105
131
  for (const depSpec of depSpecs) {
106
132
  if (typeof depSpec !== "string") {
@@ -147,6 +173,8 @@ var testing = {
147
173
  };
148
174
  export {
149
175
  getNodeTopLevelDeps,
176
+ getNodeTopLevelDepsFromFiles,
177
+ getNodeWorkspaceTopLevelDeps,
150
178
  getPythonTopLevelDeps,
151
179
  getPythonTopLevelDepsFromFiles,
152
180
  getTopLevelDeps,
@@ -53,6 +53,26 @@ function findUvWorkspace(cwd) {
53
53
  }
54
54
  return null;
55
55
  }
56
+ function findNodeWorkspace(cwd) {
57
+ for (const directory of ancestors(cwd)) {
58
+ const packageJson = `${directory}/package.json`;
59
+ if (!(0, import_node_fs.existsSync)(packageJson)) {
60
+ continue;
61
+ }
62
+ const data = readPackageJson(packageJson);
63
+ const memberGlobs = getNodeWorkspaceGlobs(data);
64
+ if (memberGlobs === null) {
65
+ continue;
66
+ }
67
+ const members = findNodeWorkspaceMembers(directory, memberGlobs);
68
+ return {
69
+ root: directory,
70
+ members,
71
+ currentMember: findCurrentMember(cwd, members)
72
+ };
73
+ }
74
+ return null;
75
+ }
56
76
  function readPyproject(path) {
57
77
  try {
58
78
  const data = (0, import_smol_toml.parse)((0, import_node_fs.readFileSync)(path, "utf8"));
@@ -61,6 +81,14 @@ function readPyproject(path) {
61
81
  return {};
62
82
  }
63
83
  }
84
+ function readPackageJson(path) {
85
+ try {
86
+ const data = JSON.parse((0, import_node_fs.readFileSync)(path, "utf8"));
87
+ return isRecord(data) ? data : {};
88
+ } catch {
89
+ return {};
90
+ }
91
+ }
64
92
  function hasUvWorkspace(data) {
65
93
  const tool = data["tool"];
66
94
  if (!isRecord(tool)) {
@@ -97,6 +125,36 @@ function findWorkspaceMembers(root, data) {
97
125
  }
98
126
  return [...members].sort();
99
127
  }
128
+ function getNodeWorkspaceGlobs(data) {
129
+ const workspaces = data["workspaces"];
130
+ if (Array.isArray(workspaces)) {
131
+ return workspaces.filter((value) => typeof value === "string");
132
+ }
133
+ if (isRecord(workspaces)) {
134
+ const packages = workspaces["packages"];
135
+ if (Array.isArray(packages)) {
136
+ return packages.filter((value) => typeof value === "string");
137
+ }
138
+ }
139
+ return null;
140
+ }
141
+ function findNodeWorkspaceMembers(root, memberGlobs) {
142
+ const includes = memberGlobs.filter((pattern) => !pattern.startsWith("!"));
143
+ const excludes = memberGlobs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
144
+ const members = /* @__PURE__ */ new Set();
145
+ for (const memberGlob of includes) {
146
+ for (const member of expandMemberGlob(root, memberGlob)) {
147
+ const relativePath = (0, import_node_path.relative)(root, member).split(import_node_path.sep).join("/");
148
+ if (isExcluded(relativePath, excludes)) {
149
+ continue;
150
+ }
151
+ if (isFile(`${member}/package.json`)) {
152
+ members.add((0, import_node_path.resolve)(member));
153
+ }
154
+ }
155
+ }
156
+ return [...members].sort();
157
+ }
100
158
  function getWorkspaceTable(data) {
101
159
  const tool = data["tool"];
102
160
  if (!isRecord(tool)) {
@@ -204,6 +262,10 @@ function findProjectRoot(cwd) {
204
262
  if (workspace !== null) {
205
263
  return workspace.root;
206
264
  }
265
+ const nodeWorkspace = findNodeWorkspace(cwd);
266
+ if (nodeWorkspace !== null) {
267
+ return nodeWorkspace.root;
268
+ }
207
269
  for (const directory of ancestors2(cwd)) {
208
270
  if (isFile2((0, import_node_path2.join)(directory, "pyproject.toml")) || isFile2((0, import_node_path2.join)(directory, "uv.lock")) || venvFromDotVenv(directory) !== null || isFile2((0, import_node_path2.join)(directory, "package.json")) || isDirectory2((0, import_node_path2.join)(directory, "node_modules"))) {
209
271
  return directory;
@@ -25,6 +25,26 @@ function findUvWorkspace(cwd) {
25
25
  }
26
26
  return null;
27
27
  }
28
+ function findNodeWorkspace(cwd) {
29
+ for (const directory of ancestors(cwd)) {
30
+ const packageJson = `${directory}/package.json`;
31
+ if (!existsSync(packageJson)) {
32
+ continue;
33
+ }
34
+ const data = readPackageJson(packageJson);
35
+ const memberGlobs = getNodeWorkspaceGlobs(data);
36
+ if (memberGlobs === null) {
37
+ continue;
38
+ }
39
+ const members = findNodeWorkspaceMembers(directory, memberGlobs);
40
+ return {
41
+ root: directory,
42
+ members,
43
+ currentMember: findCurrentMember(cwd, members)
44
+ };
45
+ }
46
+ return null;
47
+ }
28
48
  function readPyproject(path) {
29
49
  try {
30
50
  const data = parse(readFileSync(path, "utf8"));
@@ -33,6 +53,14 @@ function readPyproject(path) {
33
53
  return {};
34
54
  }
35
55
  }
56
+ function readPackageJson(path) {
57
+ try {
58
+ const data = JSON.parse(readFileSync(path, "utf8"));
59
+ return isRecord(data) ? data : {};
60
+ } catch {
61
+ return {};
62
+ }
63
+ }
36
64
  function hasUvWorkspace(data) {
37
65
  const tool = data["tool"];
38
66
  if (!isRecord(tool)) {
@@ -69,6 +97,36 @@ function findWorkspaceMembers(root, data) {
69
97
  }
70
98
  return [...members].sort();
71
99
  }
100
+ function getNodeWorkspaceGlobs(data) {
101
+ const workspaces = data["workspaces"];
102
+ if (Array.isArray(workspaces)) {
103
+ return workspaces.filter((value) => typeof value === "string");
104
+ }
105
+ if (isRecord(workspaces)) {
106
+ const packages = workspaces["packages"];
107
+ if (Array.isArray(packages)) {
108
+ return packages.filter((value) => typeof value === "string");
109
+ }
110
+ }
111
+ return null;
112
+ }
113
+ function findNodeWorkspaceMembers(root, memberGlobs) {
114
+ const includes = memberGlobs.filter((pattern) => !pattern.startsWith("!"));
115
+ const excludes = memberGlobs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
116
+ const members = /* @__PURE__ */ new Set();
117
+ for (const memberGlob of includes) {
118
+ for (const member of expandMemberGlob(root, memberGlob)) {
119
+ const relativePath = relative(root, member).split(sep).join("/");
120
+ if (isExcluded(relativePath, excludes)) {
121
+ continue;
122
+ }
123
+ if (isFile(`${member}/package.json`)) {
124
+ members.add(resolve(member));
125
+ }
126
+ }
127
+ }
128
+ return [...members].sort();
129
+ }
72
130
  function getWorkspaceTable(data) {
73
131
  const tool = data["tool"];
74
132
  if (!isRecord(tool)) {
@@ -176,6 +234,10 @@ function findProjectRoot(cwd) {
176
234
  if (workspace !== null) {
177
235
  return workspace.root;
178
236
  }
237
+ const nodeWorkspace = findNodeWorkspace(cwd);
238
+ if (nodeWorkspace !== null) {
239
+ return nodeWorkspace.root;
240
+ }
179
241
  for (const directory of ancestors2(cwd)) {
180
242
  if (isFile2(join(directory, "pyproject.toml")) || isFile2(join(directory, "uv.lock")) || venvFromDotVenv(directory) !== null || isFile2(join(directory, "package.json")) || isDirectory2(join(directory, "node_modules"))) {
181
243
  return directory;
@@ -113,6 +113,9 @@ function iterNodePackageRoots(nodeModules) {
113
113
  if (!isDirectory(fullPath)) {
114
114
  continue;
115
115
  }
116
+ if (entry.startsWith(".")) {
117
+ continue;
118
+ }
116
119
  if (entry.startsWith("@")) {
117
120
  for (const scopedEntry of (0, import_node_fs.readdirSync)(fullPath).sort()) {
118
121
  const scopedPath = (0, import_node_path.join)(fullPath, scopedEntry);
@@ -3,7 +3,7 @@ import {
3
3
  scanNodePackages,
4
4
  scanPythonDistributions,
5
5
  testing
6
- } from "./chunk-DKDHRFD4.js";
6
+ } from "./chunk-JRJ32CKR.js";
7
7
  export {
8
8
  normalizePackageName,
9
9
  scanNodePackages,