library-skills 0.0.10 → 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 +1 -1
- package/ts/dist/cli.d.ts +110 -0
- package/ts/dist/cli.js +127 -9
- package/ts/dist/deps.cjs +33 -3
- package/ts/dist/deps.d.cts +3 -1
- package/ts/dist/deps.d.ts +3 -1
- package/ts/dist/deps.js +31 -3
- package/ts/dist/python-env.cjs +62 -0
- package/ts/dist/python-env.js +62 -0
package/package.json
CHANGED
package/ts/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
|
|
4
|
+
interface Skill {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
path: string;
|
|
8
|
+
packageName: string;
|
|
9
|
+
skillDir: string;
|
|
10
|
+
packageVersion: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface InstallTarget {
|
|
14
|
+
name: string;
|
|
15
|
+
path: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface UvWorkspace {
|
|
19
|
+
root: string;
|
|
20
|
+
members: string[];
|
|
21
|
+
currentMember: string | null;
|
|
22
|
+
}
|
|
23
|
+
interface NodeWorkspace {
|
|
24
|
+
root: string;
|
|
25
|
+
members: string[];
|
|
26
|
+
currentMember: string | null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface ProjectContext {
|
|
30
|
+
cwd: string;
|
|
31
|
+
projectRoot: string;
|
|
32
|
+
targetEnvironment: string | null;
|
|
33
|
+
sitePackagesDir: string | null;
|
|
34
|
+
nodeModulesDir: string | null;
|
|
35
|
+
workspace: UvWorkspace | null;
|
|
36
|
+
nodeWorkspace: NodeWorkspace | null;
|
|
37
|
+
workspaceDependencyFiles: string[];
|
|
38
|
+
nodeWorkspaceDependencyFiles: string[];
|
|
39
|
+
dependencyFiles: string[];
|
|
40
|
+
}
|
|
41
|
+
interface InstalledStatus {
|
|
42
|
+
target: InstallTarget;
|
|
43
|
+
name: string;
|
|
44
|
+
type: "symlink" | "directory" | "missing";
|
|
45
|
+
path: string;
|
|
46
|
+
targetPath: string | null;
|
|
47
|
+
status: "up to date" | "broken" | "outdated" | "orphaned" | "name mismatch" | "hand-authored" | "new";
|
|
48
|
+
skill: Skill | null;
|
|
49
|
+
}
|
|
50
|
+
interface GlobalOptions {
|
|
51
|
+
claude?: boolean;
|
|
52
|
+
yes?: boolean;
|
|
53
|
+
check?: boolean;
|
|
54
|
+
all?: boolean;
|
|
55
|
+
skill?: string[];
|
|
56
|
+
}
|
|
57
|
+
interface ListOptions {
|
|
58
|
+
installed?: boolean;
|
|
59
|
+
json?: boolean;
|
|
60
|
+
claude?: boolean;
|
|
61
|
+
all?: boolean;
|
|
62
|
+
}
|
|
63
|
+
interface ScanOptions {
|
|
64
|
+
all?: boolean;
|
|
65
|
+
json?: boolean;
|
|
66
|
+
}
|
|
67
|
+
declare function getProjectContext(cwd?: string): ProjectContext;
|
|
68
|
+
declare function topLevelSkills({ context, skills, includeAll, }: {
|
|
69
|
+
context: ProjectContext;
|
|
70
|
+
skills: Skill[];
|
|
71
|
+
includeAll: boolean;
|
|
72
|
+
}): Skill[];
|
|
73
|
+
declare function displayPath(path: string | null | undefined, projectRoot: string): string;
|
|
74
|
+
declare function printTable(columns: string[], rows: Array<Record<string, string>>): void;
|
|
75
|
+
declare function findCollisions(skills: Skill[]): Set<string>;
|
|
76
|
+
declare function filterInstallableSkills({ skills, selectedNames, includeAll, }: {
|
|
77
|
+
skills: Skill[];
|
|
78
|
+
selectedNames: string[];
|
|
79
|
+
includeAll: boolean;
|
|
80
|
+
}): Skill[];
|
|
81
|
+
declare function installedStatuses({ targets, skills, }: {
|
|
82
|
+
targets: InstallTarget[];
|
|
83
|
+
skills: Skill[];
|
|
84
|
+
}): InstalledStatus[];
|
|
85
|
+
declare function installSelected({ skills, targets, projectRoot, copy, }: {
|
|
86
|
+
skills: Skill[];
|
|
87
|
+
targets: InstallTarget[];
|
|
88
|
+
projectRoot: string;
|
|
89
|
+
copy?: boolean;
|
|
90
|
+
}): number;
|
|
91
|
+
declare function sync(options: GlobalOptions): Promise<void>;
|
|
92
|
+
declare function scanCommand(options: ScanOptions): void;
|
|
93
|
+
declare function listCommand(options: ListOptions): void;
|
|
94
|
+
declare function createProgram(): Command;
|
|
95
|
+
declare function main(argv?: string[]): Promise<void>;
|
|
96
|
+
declare const testing: {
|
|
97
|
+
filterInstallableSkills: typeof filterInstallableSkills;
|
|
98
|
+
findCollisions: typeof findCollisions;
|
|
99
|
+
getProjectContext: typeof getProjectContext;
|
|
100
|
+
installSelected: typeof installSelected;
|
|
101
|
+
installedStatuses: typeof installedStatuses;
|
|
102
|
+
listCommand: typeof listCommand;
|
|
103
|
+
scanCommand: typeof scanCommand;
|
|
104
|
+
sync: typeof sync;
|
|
105
|
+
topLevelSkills: typeof topLevelSkills;
|
|
106
|
+
displayPath: typeof displayPath;
|
|
107
|
+
printTable: typeof printTable;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export { createProgram, main, testing };
|
package/ts/dist/cli.js
CHANGED
|
@@ -522,6 +522,28 @@ function getNodeTopLevelDeps(projectRoot) {
|
|
|
522
522
|
if (!existsSync2(packageJson)) {
|
|
523
523
|
return null;
|
|
524
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) {
|
|
525
547
|
let data;
|
|
526
548
|
try {
|
|
527
549
|
data = JSON.parse(readFileSync2(packageJson, "utf8"));
|
|
@@ -529,9 +551,11 @@ function getNodeTopLevelDeps(projectRoot) {
|
|
|
529
551
|
return null;
|
|
530
552
|
}
|
|
531
553
|
if (!isRecord2(data)) {
|
|
532
|
-
return
|
|
554
|
+
return {};
|
|
533
555
|
}
|
|
534
|
-
|
|
556
|
+
return data;
|
|
557
|
+
}
|
|
558
|
+
function extractNodeTopLevelDeps(data, deps) {
|
|
535
559
|
for (const field of [
|
|
536
560
|
"dependencies",
|
|
537
561
|
"devDependencies",
|
|
@@ -546,7 +570,6 @@ function getNodeTopLevelDeps(projectRoot) {
|
|
|
546
570
|
deps.add(normalizePackageName(packageName));
|
|
547
571
|
}
|
|
548
572
|
}
|
|
549
|
-
return deps;
|
|
550
573
|
}
|
|
551
574
|
function getTopLevelDeps(projectRoot) {
|
|
552
575
|
const dependencySets = [
|
|
@@ -561,6 +584,9 @@ function getTopLevelDeps(projectRoot) {
|
|
|
561
584
|
function getWorkspaceTopLevelDeps(pyprojects) {
|
|
562
585
|
return getPythonTopLevelDepsFromFiles(pyprojects);
|
|
563
586
|
}
|
|
587
|
+
function getNodeWorkspaceTopLevelDeps(packageJsonFiles) {
|
|
588
|
+
return getNodeTopLevelDepsFromFiles(packageJsonFiles);
|
|
589
|
+
}
|
|
564
590
|
function extractDepsFromSpecs(depSpecs, deps) {
|
|
565
591
|
for (const depSpec of depSpecs) {
|
|
566
592
|
if (typeof depSpec !== "string") {
|
|
@@ -736,6 +762,26 @@ function findUvWorkspace(cwd) {
|
|
|
736
762
|
}
|
|
737
763
|
return null;
|
|
738
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
|
+
}
|
|
739
785
|
function workspaceDependencyFiles(workspace) {
|
|
740
786
|
if (workspace.currentMember !== null) {
|
|
741
787
|
return [`${workspace.currentMember}/pyproject.toml`];
|
|
@@ -745,6 +791,15 @@ function workspaceDependencyFiles(workspace) {
|
|
|
745
791
|
...workspace.members.map((member) => `${member}/pyproject.toml`)
|
|
746
792
|
].filter((path) => existsSync4(path));
|
|
747
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
|
+
}
|
|
748
803
|
function readPyproject(path) {
|
|
749
804
|
try {
|
|
750
805
|
const data = parse3(readFileSync3(path, "utf8"));
|
|
@@ -753,6 +808,14 @@ function readPyproject(path) {
|
|
|
753
808
|
return {};
|
|
754
809
|
}
|
|
755
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
|
+
}
|
|
756
819
|
function hasUvWorkspace(data) {
|
|
757
820
|
const tool = data["tool"];
|
|
758
821
|
if (!isRecord3(tool)) {
|
|
@@ -789,6 +852,36 @@ function findWorkspaceMembers(root, data) {
|
|
|
789
852
|
}
|
|
790
853
|
return [...members].sort();
|
|
791
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
|
+
}
|
|
792
885
|
function getWorkspaceTable(data) {
|
|
793
886
|
const tool = data["tool"];
|
|
794
887
|
if (!isRecord3(tool)) {
|
|
@@ -896,6 +989,10 @@ function findProjectRoot(cwd) {
|
|
|
896
989
|
if (workspace !== null) {
|
|
897
990
|
return workspace.root;
|
|
898
991
|
}
|
|
992
|
+
const nodeWorkspace = findNodeWorkspace(cwd);
|
|
993
|
+
if (nodeWorkspace !== null) {
|
|
994
|
+
return nodeWorkspace.root;
|
|
995
|
+
}
|
|
899
996
|
for (const directory of ancestors2(cwd)) {
|
|
900
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"))) {
|
|
901
998
|
return directory;
|
|
@@ -1023,7 +1120,10 @@ function isDirectory4(path) {
|
|
|
1023
1120
|
// ts/src/cli.ts
|
|
1024
1121
|
function getProjectContext(cwd = process.cwd()) {
|
|
1025
1122
|
const workspace = findUvWorkspace(cwd);
|
|
1026
|
-
const
|
|
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);
|
|
1027
1127
|
const targetEnvironment = findVenv(cwd);
|
|
1028
1128
|
const sitePackagesDir = targetEnvironment === null ? null : getSitePackagesDir(targetEnvironment);
|
|
1029
1129
|
const nodeModulesDir = findNodeModules(cwd);
|
|
@@ -1034,7 +1134,10 @@ function getProjectContext(cwd = process.cwd()) {
|
|
|
1034
1134
|
sitePackagesDir,
|
|
1035
1135
|
nodeModulesDir,
|
|
1036
1136
|
workspace,
|
|
1037
|
-
|
|
1137
|
+
nodeWorkspace,
|
|
1138
|
+
workspaceDependencyFiles: workspaceFiles,
|
|
1139
|
+
nodeWorkspaceDependencyFiles: nodeWorkspaceFiles,
|
|
1140
|
+
dependencyFiles: [...workspaceFiles, ...nodeWorkspaceFiles]
|
|
1038
1141
|
};
|
|
1039
1142
|
}
|
|
1040
1143
|
function scanContext(context) {
|
|
@@ -1077,8 +1180,8 @@ function topLevelSkills({
|
|
|
1077
1180
|
return skills;
|
|
1078
1181
|
}
|
|
1079
1182
|
const topLevelDeps = getTopLevelDeps(context.projectRoot);
|
|
1080
|
-
const workspaceTopLevelDeps =
|
|
1081
|
-
const selectedTopLevelDeps = context.workspace === null ? topLevelDeps : workspaceTopLevelDeps;
|
|
1183
|
+
const workspaceTopLevelDeps = getWorkspaceTopLevelDepsForContext(context);
|
|
1184
|
+
const selectedTopLevelDeps = context.workspace === null && context.nodeWorkspace === null ? topLevelDeps : workspaceTopLevelDeps;
|
|
1082
1185
|
if (selectedTopLevelDeps === null) {
|
|
1083
1186
|
return skills;
|
|
1084
1187
|
}
|
|
@@ -1086,6 +1189,16 @@ function topLevelSkills({
|
|
|
1086
1189
|
(skill) => selectedTopLevelDeps.has(normalizePackageName(skill.packageName))
|
|
1087
1190
|
);
|
|
1088
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
|
+
}
|
|
1089
1202
|
function printWarnings(warnings) {
|
|
1090
1203
|
for (const warning of warnings) {
|
|
1091
1204
|
console.log(`Warning: ${warning}`);
|
|
@@ -1111,6 +1224,11 @@ function printContext(context) {
|
|
|
1111
1224
|
if (context.workspace.currentMember !== null) {
|
|
1112
1225
|
console.log(`Workspace member: ${context.workspace.currentMember}`);
|
|
1113
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
|
+
}
|
|
1114
1232
|
}
|
|
1115
1233
|
console.log(
|
|
1116
1234
|
`Target Python environment: ${context.targetEnvironment ? displayPath(context.targetEnvironment, context.projectRoot) : "not found"}`
|
|
@@ -1151,8 +1269,8 @@ function scanJsonPayload({
|
|
|
1151
1269
|
}) {
|
|
1152
1270
|
return {
|
|
1153
1271
|
project_root: context.projectRoot,
|
|
1154
|
-
workspace_root: context.workspace?.root ?? "",
|
|
1155
|
-
workspace_member: context.workspace?.currentMember ?? "",
|
|
1272
|
+
workspace_root: context.workspace?.root ?? context.nodeWorkspace?.root ?? "",
|
|
1273
|
+
workspace_member: context.workspace?.currentMember ?? context.nodeWorkspace?.currentMember ?? "",
|
|
1156
1274
|
dependency_files: context.dependencyFiles,
|
|
1157
1275
|
target_environment: context.targetEnvironment ?? "",
|
|
1158
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
|
|
132
|
+
return {};
|
|
109
133
|
}
|
|
110
|
-
|
|
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,
|
package/ts/dist/deps.d.cts
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.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
|
@@ -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
|
|
94
|
+
return {};
|
|
73
95
|
}
|
|
74
|
-
|
|
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,
|
package/ts/dist/python-env.cjs
CHANGED
|
@@ -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;
|
package/ts/dist/python-env.js
CHANGED
|
@@ -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;
|