@learnrudi/cli 1.9.8 → 1.9.9
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/README.md +145 -53
- package/dist/index.cjs +1640 -532
- package/dist/packages-manifest.json +1 -1
- package/package.json +20 -21
- package/scripts/postinstall.js +14 -4
package/dist/index.cjs
CHANGED
|
@@ -70,9 +70,9 @@ function ensureDirectories() {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
function parsePackageId(id) {
|
|
73
|
-
const match = id.match(/^(stack|prompt|runtime|binary|agent):(.+)$/);
|
|
73
|
+
const match = id.match(/^(stack|prompt|runtime|binary|agent|npm):(.+)$/);
|
|
74
74
|
if (!match) {
|
|
75
|
-
throw new Error(`Invalid package ID: ${id} (expected format: kind:name, where kind is one of: ${PACKAGE_KINDS.join(", ")})`);
|
|
75
|
+
throw new Error(`Invalid package ID: ${id} (expected format: kind:name, where kind is one of: ${PACKAGE_KINDS.join(", ")}, npm)`);
|
|
76
76
|
}
|
|
77
77
|
return [match[1], match[2]];
|
|
78
78
|
}
|
|
@@ -92,14 +92,21 @@ function getPackagePath(id) {
|
|
|
92
92
|
return import_path.default.join(PATHS.binaries, name);
|
|
93
93
|
case "agent":
|
|
94
94
|
return import_path.default.join(PATHS.agents, name);
|
|
95
|
+
case "npm":
|
|
96
|
+
const sanitized = name.replace(/\//g, "__").replace(/^@/, "");
|
|
97
|
+
return import_path.default.join(PATHS.binaries, "npm", sanitized);
|
|
95
98
|
default:
|
|
96
99
|
throw new Error(`Unknown package kind: ${kind}`);
|
|
97
100
|
}
|
|
98
101
|
}
|
|
99
102
|
function getLockfilePath(id) {
|
|
100
103
|
const [kind, name] = parsePackageId(id);
|
|
101
|
-
|
|
102
|
-
|
|
104
|
+
let lockName = name;
|
|
105
|
+
if (kind === "npm") {
|
|
106
|
+
lockName = name.replace(/\//g, "__").replace(/^@/, "");
|
|
107
|
+
}
|
|
108
|
+
const lockDir = kind === "binary" ? "binaries" : kind === "npm" ? "npms" : kind + "s";
|
|
109
|
+
return import_path.default.join(PATHS.locks, lockDir, `${lockName}.lock.yaml`);
|
|
103
110
|
}
|
|
104
111
|
function isPackageInstalled(id) {
|
|
105
112
|
const packagePath = getPackagePath(id);
|
|
@@ -190,27 +197,6 @@ var init_src = __esm({
|
|
|
190
197
|
});
|
|
191
198
|
|
|
192
199
|
// node_modules/.pnpm/@learnrudi+registry-client@1.0.1/node_modules/@learnrudi/registry-client/src/index.js
|
|
193
|
-
var src_exports = {};
|
|
194
|
-
__export(src_exports, {
|
|
195
|
-
CACHE_TTL: () => CACHE_TTL,
|
|
196
|
-
DEFAULT_REGISTRY_URL: () => DEFAULT_REGISTRY_URL,
|
|
197
|
-
PACKAGE_KINDS: () => PACKAGE_KINDS2,
|
|
198
|
-
RUNTIMES_DOWNLOAD_BASE: () => RUNTIMES_DOWNLOAD_BASE,
|
|
199
|
-
RUNTIMES_RELEASE_VERSION: () => RUNTIMES_RELEASE_VERSION,
|
|
200
|
-
checkCache: () => checkCache,
|
|
201
|
-
clearCache: () => clearCache,
|
|
202
|
-
computeHash: () => computeHash,
|
|
203
|
-
downloadPackage: () => downloadPackage,
|
|
204
|
-
downloadRuntime: () => downloadRuntime,
|
|
205
|
-
downloadTool: () => downloadTool,
|
|
206
|
-
fetchIndex: () => fetchIndex,
|
|
207
|
-
getManifest: () => getManifest,
|
|
208
|
-
getPackage: () => getPackage,
|
|
209
|
-
getPackageKinds: () => getPackageKinds,
|
|
210
|
-
listPackages: () => listPackages,
|
|
211
|
-
searchPackages: () => searchPackages,
|
|
212
|
-
verifyHash: () => verifyHash
|
|
213
|
-
});
|
|
214
200
|
function getLocalRegistryPaths() {
|
|
215
201
|
if (process.env.USE_LOCAL_REGISTRY !== "true") {
|
|
216
202
|
return [];
|
|
@@ -316,19 +302,6 @@ function clearCache() {
|
|
|
316
302
|
import_fs2.default.unlinkSync(PATHS.registryCache);
|
|
317
303
|
}
|
|
318
304
|
}
|
|
319
|
-
function checkCache() {
|
|
320
|
-
const cachePath = PATHS.registryCache;
|
|
321
|
-
if (!import_fs2.default.existsSync(cachePath)) {
|
|
322
|
-
return { fresh: false, age: null };
|
|
323
|
-
}
|
|
324
|
-
try {
|
|
325
|
-
const stat = import_fs2.default.statSync(cachePath);
|
|
326
|
-
const age = Date.now() - stat.mtimeMs;
|
|
327
|
-
return { fresh: age <= CACHE_TTL, age };
|
|
328
|
-
} catch {
|
|
329
|
-
return { fresh: false, age: null };
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
305
|
function getKindSection(kind) {
|
|
333
306
|
return KIND_PLURALS[kind] || `${kind}s`;
|
|
334
307
|
}
|
|
@@ -420,9 +393,6 @@ async function listPackages(kind) {
|
|
|
420
393
|
if (!section) return [];
|
|
421
394
|
return [...section.official || [], ...section.community || []];
|
|
422
395
|
}
|
|
423
|
-
function getPackageKinds() {
|
|
424
|
-
return PACKAGE_KINDS2;
|
|
425
|
-
}
|
|
426
396
|
async function downloadPackage(pkg, destPath, options = {}) {
|
|
427
397
|
const { onProgress } = options;
|
|
428
398
|
const registryPath = pkg.path;
|
|
@@ -833,33 +803,11 @@ function guessArchiveType(filename) {
|
|
|
833
803
|
if (filename.endsWith(".zip")) return "zip";
|
|
834
804
|
return "tar.gz";
|
|
835
805
|
}
|
|
836
|
-
|
|
837
|
-
return new Promise((resolve, reject) => {
|
|
838
|
-
const hash = import_crypto.default.createHash("sha256");
|
|
839
|
-
const stream = import_fs2.default.createReadStream(filePath);
|
|
840
|
-
stream.on("data", (data) => hash.update(data));
|
|
841
|
-
stream.on("end", () => {
|
|
842
|
-
const actualHash = hash.digest("hex");
|
|
843
|
-
resolve(actualHash === expectedHash);
|
|
844
|
-
});
|
|
845
|
-
stream.on("error", reject);
|
|
846
|
-
});
|
|
847
|
-
}
|
|
848
|
-
async function computeHash(filePath) {
|
|
849
|
-
return new Promise((resolve, reject) => {
|
|
850
|
-
const hash = import_crypto.default.createHash("sha256");
|
|
851
|
-
const stream = import_fs2.default.createReadStream(filePath);
|
|
852
|
-
stream.on("data", (data) => hash.update(data));
|
|
853
|
-
stream.on("end", () => resolve(hash.digest("hex")));
|
|
854
|
-
stream.on("error", reject);
|
|
855
|
-
});
|
|
856
|
-
}
|
|
857
|
-
var import_fs2, import_path2, import_crypto, DEFAULT_REGISTRY_URL, RUNTIMES_DOWNLOAD_BASE, CACHE_TTL, PACKAGE_KINDS2, KIND_PLURALS, GITHUB_RAW_BASE, RUNTIMES_RELEASE_VERSION;
|
|
806
|
+
var import_fs2, import_path2, DEFAULT_REGISTRY_URL, RUNTIMES_DOWNLOAD_BASE, CACHE_TTL, PACKAGE_KINDS2, KIND_PLURALS, GITHUB_RAW_BASE, RUNTIMES_RELEASE_VERSION;
|
|
858
807
|
var init_src2 = __esm({
|
|
859
808
|
"node_modules/.pnpm/@learnrudi+registry-client@1.0.1/node_modules/@learnrudi/registry-client/src/index.js"() {
|
|
860
809
|
import_fs2 = __toESM(require("fs"), 1);
|
|
861
810
|
import_path2 = __toESM(require("path"), 1);
|
|
862
|
-
import_crypto = __toESM(require("crypto"), 1);
|
|
863
811
|
init_src();
|
|
864
812
|
DEFAULT_REGISTRY_URL = "https://raw.githubusercontent.com/learn-rudi/registry/main/index.json";
|
|
865
813
|
RUNTIMES_DOWNLOAD_BASE = "https://github.com/learn-rudi/registry/releases/download";
|
|
@@ -873,8 +821,11 @@ var init_src2 = __esm({
|
|
|
873
821
|
}
|
|
874
822
|
});
|
|
875
823
|
|
|
876
|
-
//
|
|
824
|
+
// packages/core/src/resolver.js
|
|
877
825
|
async function resolvePackage(id) {
|
|
826
|
+
if (id.startsWith("npm:")) {
|
|
827
|
+
return resolveDynamicNpm(id);
|
|
828
|
+
}
|
|
878
829
|
const normalizedId = id.includes(":") ? id : `stack:${id}`;
|
|
879
830
|
const pkg = await getPackage(normalizedId);
|
|
880
831
|
if (!pkg) {
|
|
@@ -912,6 +863,51 @@ async function resolvePackage(id) {
|
|
|
912
863
|
installType: mergedPkg.installType
|
|
913
864
|
};
|
|
914
865
|
}
|
|
866
|
+
async function resolveDynamicNpm(id) {
|
|
867
|
+
const spec = id.replace("npm:", "");
|
|
868
|
+
let name, version;
|
|
869
|
+
if (spec.startsWith("@")) {
|
|
870
|
+
const parts = spec.split("@");
|
|
871
|
+
if (parts.length >= 3) {
|
|
872
|
+
name = `@${parts[1]}`;
|
|
873
|
+
version = parts[2];
|
|
874
|
+
} else {
|
|
875
|
+
name = `@${parts[1]}`;
|
|
876
|
+
version = "latest";
|
|
877
|
+
}
|
|
878
|
+
} else {
|
|
879
|
+
const lastAt = spec.lastIndexOf("@");
|
|
880
|
+
if (lastAt > 0) {
|
|
881
|
+
name = spec.substring(0, lastAt);
|
|
882
|
+
version = spec.substring(lastAt + 1);
|
|
883
|
+
} else {
|
|
884
|
+
name = spec;
|
|
885
|
+
version = "latest";
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
const sanitizedName = name.replace(/\//g, "__").replace(/^@/, "");
|
|
889
|
+
const installDir = `npm/${sanitizedName}`;
|
|
890
|
+
const fullId = id;
|
|
891
|
+
const installed = isPackageInstalled(fullId);
|
|
892
|
+
return {
|
|
893
|
+
id: fullId,
|
|
894
|
+
kind: "binary",
|
|
895
|
+
name,
|
|
896
|
+
version,
|
|
897
|
+
description: `Dynamic npm package: ${name}`,
|
|
898
|
+
installType: "npm",
|
|
899
|
+
npmPackage: name,
|
|
900
|
+
installDir,
|
|
901
|
+
installed,
|
|
902
|
+
dependencies: [],
|
|
903
|
+
source: {
|
|
904
|
+
type: "npm",
|
|
905
|
+
spec
|
|
906
|
+
},
|
|
907
|
+
// bins will be discovered after install by installer
|
|
908
|
+
bins: null
|
|
909
|
+
};
|
|
910
|
+
}
|
|
915
911
|
async function resolveDependencies(pkg) {
|
|
916
912
|
const dependencies = [];
|
|
917
913
|
const runtimes = pkg.requires?.runtimes || (pkg.runtime ? [pkg.runtime] : []);
|
|
@@ -1028,7 +1024,7 @@ function compareVersions(a, b) {
|
|
|
1028
1024
|
return 0;
|
|
1029
1025
|
}
|
|
1030
1026
|
var init_resolver = __esm({
|
|
1031
|
-
"
|
|
1027
|
+
"packages/core/src/resolver.js"() {
|
|
1032
1028
|
init_src2();
|
|
1033
1029
|
init_src();
|
|
1034
1030
|
}
|
|
@@ -1111,17 +1107,17 @@ var require_visit = __commonJS({
|
|
|
1111
1107
|
visit.BREAK = BREAK;
|
|
1112
1108
|
visit.SKIP = SKIP;
|
|
1113
1109
|
visit.REMOVE = REMOVE;
|
|
1114
|
-
function visit_(key, node, visitor,
|
|
1115
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
1110
|
+
function visit_(key, node, visitor, path35) {
|
|
1111
|
+
const ctrl = callVisitor(key, node, visitor, path35);
|
|
1116
1112
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
1117
|
-
replaceNode(key,
|
|
1118
|
-
return visit_(key, ctrl, visitor,
|
|
1113
|
+
replaceNode(key, path35, ctrl);
|
|
1114
|
+
return visit_(key, ctrl, visitor, path35);
|
|
1119
1115
|
}
|
|
1120
1116
|
if (typeof ctrl !== "symbol") {
|
|
1121
1117
|
if (identity.isCollection(node)) {
|
|
1122
|
-
|
|
1118
|
+
path35 = Object.freeze(path35.concat(node));
|
|
1123
1119
|
for (let i = 0; i < node.items.length; ++i) {
|
|
1124
|
-
const ci = visit_(i, node.items[i], visitor,
|
|
1120
|
+
const ci = visit_(i, node.items[i], visitor, path35);
|
|
1125
1121
|
if (typeof ci === "number")
|
|
1126
1122
|
i = ci - 1;
|
|
1127
1123
|
else if (ci === BREAK)
|
|
@@ -1132,13 +1128,13 @@ var require_visit = __commonJS({
|
|
|
1132
1128
|
}
|
|
1133
1129
|
}
|
|
1134
1130
|
} else if (identity.isPair(node)) {
|
|
1135
|
-
|
|
1136
|
-
const ck = visit_("key", node.key, visitor,
|
|
1131
|
+
path35 = Object.freeze(path35.concat(node));
|
|
1132
|
+
const ck = visit_("key", node.key, visitor, path35);
|
|
1137
1133
|
if (ck === BREAK)
|
|
1138
1134
|
return BREAK;
|
|
1139
1135
|
else if (ck === REMOVE)
|
|
1140
1136
|
node.key = null;
|
|
1141
|
-
const cv = visit_("value", node.value, visitor,
|
|
1137
|
+
const cv = visit_("value", node.value, visitor, path35);
|
|
1142
1138
|
if (cv === BREAK)
|
|
1143
1139
|
return BREAK;
|
|
1144
1140
|
else if (cv === REMOVE)
|
|
@@ -1159,17 +1155,17 @@ var require_visit = __commonJS({
|
|
|
1159
1155
|
visitAsync.BREAK = BREAK;
|
|
1160
1156
|
visitAsync.SKIP = SKIP;
|
|
1161
1157
|
visitAsync.REMOVE = REMOVE;
|
|
1162
|
-
async function visitAsync_(key, node, visitor,
|
|
1163
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
1158
|
+
async function visitAsync_(key, node, visitor, path35) {
|
|
1159
|
+
const ctrl = await callVisitor(key, node, visitor, path35);
|
|
1164
1160
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
1165
|
-
replaceNode(key,
|
|
1166
|
-
return visitAsync_(key, ctrl, visitor,
|
|
1161
|
+
replaceNode(key, path35, ctrl);
|
|
1162
|
+
return visitAsync_(key, ctrl, visitor, path35);
|
|
1167
1163
|
}
|
|
1168
1164
|
if (typeof ctrl !== "symbol") {
|
|
1169
1165
|
if (identity.isCollection(node)) {
|
|
1170
|
-
|
|
1166
|
+
path35 = Object.freeze(path35.concat(node));
|
|
1171
1167
|
for (let i = 0; i < node.items.length; ++i) {
|
|
1172
|
-
const ci = await visitAsync_(i, node.items[i], visitor,
|
|
1168
|
+
const ci = await visitAsync_(i, node.items[i], visitor, path35);
|
|
1173
1169
|
if (typeof ci === "number")
|
|
1174
1170
|
i = ci - 1;
|
|
1175
1171
|
else if (ci === BREAK)
|
|
@@ -1180,13 +1176,13 @@ var require_visit = __commonJS({
|
|
|
1180
1176
|
}
|
|
1181
1177
|
}
|
|
1182
1178
|
} else if (identity.isPair(node)) {
|
|
1183
|
-
|
|
1184
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
1179
|
+
path35 = Object.freeze(path35.concat(node));
|
|
1180
|
+
const ck = await visitAsync_("key", node.key, visitor, path35);
|
|
1185
1181
|
if (ck === BREAK)
|
|
1186
1182
|
return BREAK;
|
|
1187
1183
|
else if (ck === REMOVE)
|
|
1188
1184
|
node.key = null;
|
|
1189
|
-
const cv = await visitAsync_("value", node.value, visitor,
|
|
1185
|
+
const cv = await visitAsync_("value", node.value, visitor, path35);
|
|
1190
1186
|
if (cv === BREAK)
|
|
1191
1187
|
return BREAK;
|
|
1192
1188
|
else if (cv === REMOVE)
|
|
@@ -1213,23 +1209,23 @@ var require_visit = __commonJS({
|
|
|
1213
1209
|
}
|
|
1214
1210
|
return visitor;
|
|
1215
1211
|
}
|
|
1216
|
-
function callVisitor(key, node, visitor,
|
|
1212
|
+
function callVisitor(key, node, visitor, path35) {
|
|
1217
1213
|
if (typeof visitor === "function")
|
|
1218
|
-
return visitor(key, node,
|
|
1214
|
+
return visitor(key, node, path35);
|
|
1219
1215
|
if (identity.isMap(node))
|
|
1220
|
-
return visitor.Map?.(key, node,
|
|
1216
|
+
return visitor.Map?.(key, node, path35);
|
|
1221
1217
|
if (identity.isSeq(node))
|
|
1222
|
-
return visitor.Seq?.(key, node,
|
|
1218
|
+
return visitor.Seq?.(key, node, path35);
|
|
1223
1219
|
if (identity.isPair(node))
|
|
1224
|
-
return visitor.Pair?.(key, node,
|
|
1220
|
+
return visitor.Pair?.(key, node, path35);
|
|
1225
1221
|
if (identity.isScalar(node))
|
|
1226
|
-
return visitor.Scalar?.(key, node,
|
|
1222
|
+
return visitor.Scalar?.(key, node, path35);
|
|
1227
1223
|
if (identity.isAlias(node))
|
|
1228
|
-
return visitor.Alias?.(key, node,
|
|
1224
|
+
return visitor.Alias?.(key, node, path35);
|
|
1229
1225
|
return void 0;
|
|
1230
1226
|
}
|
|
1231
|
-
function replaceNode(key,
|
|
1232
|
-
const parent =
|
|
1227
|
+
function replaceNode(key, path35, node) {
|
|
1228
|
+
const parent = path35[path35.length - 1];
|
|
1233
1229
|
if (identity.isCollection(parent)) {
|
|
1234
1230
|
parent.items[key] = node;
|
|
1235
1231
|
} else if (identity.isPair(parent)) {
|
|
@@ -1837,10 +1833,10 @@ var require_Collection = __commonJS({
|
|
|
1837
1833
|
var createNode = require_createNode();
|
|
1838
1834
|
var identity = require_identity();
|
|
1839
1835
|
var Node = require_Node();
|
|
1840
|
-
function collectionFromPath(schema,
|
|
1836
|
+
function collectionFromPath(schema, path35, value) {
|
|
1841
1837
|
let v = value;
|
|
1842
|
-
for (let i =
|
|
1843
|
-
const k =
|
|
1838
|
+
for (let i = path35.length - 1; i >= 0; --i) {
|
|
1839
|
+
const k = path35[i];
|
|
1844
1840
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
1845
1841
|
const a = [];
|
|
1846
1842
|
a[k] = v;
|
|
@@ -1859,7 +1855,7 @@ var require_Collection = __commonJS({
|
|
|
1859
1855
|
sourceObjects: /* @__PURE__ */ new Map()
|
|
1860
1856
|
});
|
|
1861
1857
|
}
|
|
1862
|
-
var isEmptyPath = (
|
|
1858
|
+
var isEmptyPath = (path35) => path35 == null || typeof path35 === "object" && !!path35[Symbol.iterator]().next().done;
|
|
1863
1859
|
var Collection = class extends Node.NodeBase {
|
|
1864
1860
|
constructor(type, schema) {
|
|
1865
1861
|
super(type);
|
|
@@ -1889,11 +1885,11 @@ var require_Collection = __commonJS({
|
|
|
1889
1885
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
|
1890
1886
|
* that already exists in the map.
|
|
1891
1887
|
*/
|
|
1892
|
-
addIn(
|
|
1893
|
-
if (isEmptyPath(
|
|
1888
|
+
addIn(path35, value) {
|
|
1889
|
+
if (isEmptyPath(path35))
|
|
1894
1890
|
this.add(value);
|
|
1895
1891
|
else {
|
|
1896
|
-
const [key, ...rest] =
|
|
1892
|
+
const [key, ...rest] = path35;
|
|
1897
1893
|
const node = this.get(key, true);
|
|
1898
1894
|
if (identity.isCollection(node))
|
|
1899
1895
|
node.addIn(rest, value);
|
|
@@ -1907,8 +1903,8 @@ var require_Collection = __commonJS({
|
|
|
1907
1903
|
* Removes a value from the collection.
|
|
1908
1904
|
* @returns `true` if the item was found and removed.
|
|
1909
1905
|
*/
|
|
1910
|
-
deleteIn(
|
|
1911
|
-
const [key, ...rest] =
|
|
1906
|
+
deleteIn(path35) {
|
|
1907
|
+
const [key, ...rest] = path35;
|
|
1912
1908
|
if (rest.length === 0)
|
|
1913
1909
|
return this.delete(key);
|
|
1914
1910
|
const node = this.get(key, true);
|
|
@@ -1922,8 +1918,8 @@ var require_Collection = __commonJS({
|
|
|
1922
1918
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
1923
1919
|
* `true` (collections are always returned intact).
|
|
1924
1920
|
*/
|
|
1925
|
-
getIn(
|
|
1926
|
-
const [key, ...rest] =
|
|
1921
|
+
getIn(path35, keepScalar) {
|
|
1922
|
+
const [key, ...rest] = path35;
|
|
1927
1923
|
const node = this.get(key, true);
|
|
1928
1924
|
if (rest.length === 0)
|
|
1929
1925
|
return !keepScalar && identity.isScalar(node) ? node.value : node;
|
|
@@ -1941,8 +1937,8 @@ var require_Collection = __commonJS({
|
|
|
1941
1937
|
/**
|
|
1942
1938
|
* Checks if the collection includes a value with the key `key`.
|
|
1943
1939
|
*/
|
|
1944
|
-
hasIn(
|
|
1945
|
-
const [key, ...rest] =
|
|
1940
|
+
hasIn(path35) {
|
|
1941
|
+
const [key, ...rest] = path35;
|
|
1946
1942
|
if (rest.length === 0)
|
|
1947
1943
|
return this.has(key);
|
|
1948
1944
|
const node = this.get(key, true);
|
|
@@ -1952,8 +1948,8 @@ var require_Collection = __commonJS({
|
|
|
1952
1948
|
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
|
1953
1949
|
* boolean to add/remove the item from the set.
|
|
1954
1950
|
*/
|
|
1955
|
-
setIn(
|
|
1956
|
-
const [key, ...rest] =
|
|
1951
|
+
setIn(path35, value) {
|
|
1952
|
+
const [key, ...rest] = path35;
|
|
1957
1953
|
if (rest.length === 0) {
|
|
1958
1954
|
this.set(key, value);
|
|
1959
1955
|
} else {
|
|
@@ -4457,9 +4453,9 @@ var require_Document = __commonJS({
|
|
|
4457
4453
|
this.contents.add(value);
|
|
4458
4454
|
}
|
|
4459
4455
|
/** Adds a value to the document. */
|
|
4460
|
-
addIn(
|
|
4456
|
+
addIn(path35, value) {
|
|
4461
4457
|
if (assertCollection(this.contents))
|
|
4462
|
-
this.contents.addIn(
|
|
4458
|
+
this.contents.addIn(path35, value);
|
|
4463
4459
|
}
|
|
4464
4460
|
/**
|
|
4465
4461
|
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
|
@@ -4534,14 +4530,14 @@ var require_Document = __commonJS({
|
|
|
4534
4530
|
* Removes a value from the document.
|
|
4535
4531
|
* @returns `true` if the item was found and removed.
|
|
4536
4532
|
*/
|
|
4537
|
-
deleteIn(
|
|
4538
|
-
if (Collection.isEmptyPath(
|
|
4533
|
+
deleteIn(path35) {
|
|
4534
|
+
if (Collection.isEmptyPath(path35)) {
|
|
4539
4535
|
if (this.contents == null)
|
|
4540
4536
|
return false;
|
|
4541
4537
|
this.contents = null;
|
|
4542
4538
|
return true;
|
|
4543
4539
|
}
|
|
4544
|
-
return assertCollection(this.contents) ? this.contents.deleteIn(
|
|
4540
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path35) : false;
|
|
4545
4541
|
}
|
|
4546
4542
|
/**
|
|
4547
4543
|
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
|
@@ -4556,10 +4552,10 @@ var require_Document = __commonJS({
|
|
|
4556
4552
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
4557
4553
|
* `true` (collections are always returned intact).
|
|
4558
4554
|
*/
|
|
4559
|
-
getIn(
|
|
4560
|
-
if (Collection.isEmptyPath(
|
|
4555
|
+
getIn(path35, keepScalar) {
|
|
4556
|
+
if (Collection.isEmptyPath(path35))
|
|
4561
4557
|
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
4562
|
-
return identity.isCollection(this.contents) ? this.contents.getIn(
|
|
4558
|
+
return identity.isCollection(this.contents) ? this.contents.getIn(path35, keepScalar) : void 0;
|
|
4563
4559
|
}
|
|
4564
4560
|
/**
|
|
4565
4561
|
* Checks if the document includes a value with the key `key`.
|
|
@@ -4570,10 +4566,10 @@ var require_Document = __commonJS({
|
|
|
4570
4566
|
/**
|
|
4571
4567
|
* Checks if the document includes a value at `path`.
|
|
4572
4568
|
*/
|
|
4573
|
-
hasIn(
|
|
4574
|
-
if (Collection.isEmptyPath(
|
|
4569
|
+
hasIn(path35) {
|
|
4570
|
+
if (Collection.isEmptyPath(path35))
|
|
4575
4571
|
return this.contents !== void 0;
|
|
4576
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
4572
|
+
return identity.isCollection(this.contents) ? this.contents.hasIn(path35) : false;
|
|
4577
4573
|
}
|
|
4578
4574
|
/**
|
|
4579
4575
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
@@ -4590,13 +4586,13 @@ var require_Document = __commonJS({
|
|
|
4590
4586
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
4591
4587
|
* boolean to add/remove the item from the set.
|
|
4592
4588
|
*/
|
|
4593
|
-
setIn(
|
|
4594
|
-
if (Collection.isEmptyPath(
|
|
4589
|
+
setIn(path35, value) {
|
|
4590
|
+
if (Collection.isEmptyPath(path35)) {
|
|
4595
4591
|
this.contents = value;
|
|
4596
4592
|
} else if (this.contents == null) {
|
|
4597
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
4593
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path35), value);
|
|
4598
4594
|
} else if (assertCollection(this.contents)) {
|
|
4599
|
-
this.contents.setIn(
|
|
4595
|
+
this.contents.setIn(path35, value);
|
|
4600
4596
|
}
|
|
4601
4597
|
}
|
|
4602
4598
|
/**
|
|
@@ -6548,9 +6544,9 @@ var require_cst_visit = __commonJS({
|
|
|
6548
6544
|
visit.BREAK = BREAK;
|
|
6549
6545
|
visit.SKIP = SKIP;
|
|
6550
6546
|
visit.REMOVE = REMOVE;
|
|
6551
|
-
visit.itemAtPath = (cst,
|
|
6547
|
+
visit.itemAtPath = (cst, path35) => {
|
|
6552
6548
|
let item = cst;
|
|
6553
|
-
for (const [field, index] of
|
|
6549
|
+
for (const [field, index] of path35) {
|
|
6554
6550
|
const tok = item?.[field];
|
|
6555
6551
|
if (tok && "items" in tok) {
|
|
6556
6552
|
item = tok.items[index];
|
|
@@ -6559,23 +6555,23 @@ var require_cst_visit = __commonJS({
|
|
|
6559
6555
|
}
|
|
6560
6556
|
return item;
|
|
6561
6557
|
};
|
|
6562
|
-
visit.parentCollection = (cst,
|
|
6563
|
-
const parent = visit.itemAtPath(cst,
|
|
6564
|
-
const field =
|
|
6558
|
+
visit.parentCollection = (cst, path35) => {
|
|
6559
|
+
const parent = visit.itemAtPath(cst, path35.slice(0, -1));
|
|
6560
|
+
const field = path35[path35.length - 1][0];
|
|
6565
6561
|
const coll = parent?.[field];
|
|
6566
6562
|
if (coll && "items" in coll)
|
|
6567
6563
|
return coll;
|
|
6568
6564
|
throw new Error("Parent collection not found");
|
|
6569
6565
|
};
|
|
6570
|
-
function _visit(
|
|
6571
|
-
let ctrl = visitor(item,
|
|
6566
|
+
function _visit(path35, item, visitor) {
|
|
6567
|
+
let ctrl = visitor(item, path35);
|
|
6572
6568
|
if (typeof ctrl === "symbol")
|
|
6573
6569
|
return ctrl;
|
|
6574
6570
|
for (const field of ["key", "value"]) {
|
|
6575
6571
|
const token = item[field];
|
|
6576
6572
|
if (token && "items" in token) {
|
|
6577
6573
|
for (let i = 0; i < token.items.length; ++i) {
|
|
6578
|
-
const ci = _visit(Object.freeze(
|
|
6574
|
+
const ci = _visit(Object.freeze(path35.concat([[field, i]])), token.items[i], visitor);
|
|
6579
6575
|
if (typeof ci === "number")
|
|
6580
6576
|
i = ci - 1;
|
|
6581
6577
|
else if (ci === BREAK)
|
|
@@ -6586,10 +6582,10 @@ var require_cst_visit = __commonJS({
|
|
|
6586
6582
|
}
|
|
6587
6583
|
}
|
|
6588
6584
|
if (typeof ctrl === "function" && field === "key")
|
|
6589
|
-
ctrl = ctrl(item,
|
|
6585
|
+
ctrl = ctrl(item, path35);
|
|
6590
6586
|
}
|
|
6591
6587
|
}
|
|
6592
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
6588
|
+
return typeof ctrl === "function" ? ctrl(item, path35) : ctrl;
|
|
6593
6589
|
}
|
|
6594
6590
|
exports2.visit = visit;
|
|
6595
6591
|
}
|
|
@@ -7874,14 +7870,14 @@ var require_parser = __commonJS({
|
|
|
7874
7870
|
case "scalar":
|
|
7875
7871
|
case "single-quoted-scalar":
|
|
7876
7872
|
case "double-quoted-scalar": {
|
|
7877
|
-
const
|
|
7873
|
+
const fs35 = this.flowScalar(this.type);
|
|
7878
7874
|
if (atNextItem || it.value) {
|
|
7879
|
-
map.items.push({ start, key:
|
|
7875
|
+
map.items.push({ start, key: fs35, sep: [] });
|
|
7880
7876
|
this.onKeyLine = true;
|
|
7881
7877
|
} else if (it.sep) {
|
|
7882
|
-
this.stack.push(
|
|
7878
|
+
this.stack.push(fs35);
|
|
7883
7879
|
} else {
|
|
7884
|
-
Object.assign(it, { key:
|
|
7880
|
+
Object.assign(it, { key: fs35, sep: [] });
|
|
7885
7881
|
this.onKeyLine = true;
|
|
7886
7882
|
}
|
|
7887
7883
|
return;
|
|
@@ -8009,13 +8005,13 @@ var require_parser = __commonJS({
|
|
|
8009
8005
|
case "scalar":
|
|
8010
8006
|
case "single-quoted-scalar":
|
|
8011
8007
|
case "double-quoted-scalar": {
|
|
8012
|
-
const
|
|
8008
|
+
const fs35 = this.flowScalar(this.type);
|
|
8013
8009
|
if (!it || it.value)
|
|
8014
|
-
fc.items.push({ start: [], key:
|
|
8010
|
+
fc.items.push({ start: [], key: fs35, sep: [] });
|
|
8015
8011
|
else if (it.sep)
|
|
8016
|
-
this.stack.push(
|
|
8012
|
+
this.stack.push(fs35);
|
|
8017
8013
|
else
|
|
8018
|
-
Object.assign(it, { key:
|
|
8014
|
+
Object.assign(it, { key: fs35, sep: [] });
|
|
8019
8015
|
return;
|
|
8020
8016
|
}
|
|
8021
8017
|
case "flow-map-end":
|
|
@@ -8323,15 +8319,13 @@ var require_dist = __commonJS({
|
|
|
8323
8319
|
}
|
|
8324
8320
|
});
|
|
8325
8321
|
|
|
8326
|
-
//
|
|
8322
|
+
// packages/core/src/lockfile.js
|
|
8327
8323
|
async function writeLockfile(resolved) {
|
|
8328
|
-
const
|
|
8329
|
-
const
|
|
8330
|
-
const lockDir = import_path3.default.join(PATHS.locks, lockKind);
|
|
8324
|
+
const lockPath = getLockfilePath(resolved.id);
|
|
8325
|
+
const lockDir = import_path3.default.dirname(lockPath);
|
|
8331
8326
|
if (!import_fs3.default.existsSync(lockDir)) {
|
|
8332
8327
|
import_fs3.default.mkdirSync(lockDir, { recursive: true });
|
|
8333
8328
|
}
|
|
8334
|
-
const lockPath = import_path3.default.join(lockDir, `${name}.lock.yaml`);
|
|
8335
8329
|
const lockfile = {
|
|
8336
8330
|
id: resolved.id,
|
|
8337
8331
|
version: resolved.version,
|
|
@@ -8443,7 +8437,7 @@ async function cleanOrphanedLockfiles() {
|
|
|
8443
8437
|
}
|
|
8444
8438
|
var import_fs3, import_path3, import_yaml;
|
|
8445
8439
|
var init_lockfile = __esm({
|
|
8446
|
-
"
|
|
8440
|
+
"packages/core/src/lockfile.js"() {
|
|
8447
8441
|
import_fs3 = __toESM(require("fs"), 1);
|
|
8448
8442
|
import_path3 = __toESM(require("path"), 1);
|
|
8449
8443
|
import_yaml = __toESM(require_dist(), 1);
|
|
@@ -8451,28 +8445,91 @@ var init_lockfile = __esm({
|
|
|
8451
8445
|
}
|
|
8452
8446
|
});
|
|
8453
8447
|
|
|
8454
|
-
//
|
|
8448
|
+
// packages/core/src/shims.js
|
|
8455
8449
|
var shims_exports = {};
|
|
8456
8450
|
__export(shims_exports, {
|
|
8457
8451
|
createShimsForTool: () => createShimsForTool,
|
|
8452
|
+
getAllShimOwners: () => getAllShimOwners,
|
|
8453
|
+
getShimOwner: () => getShimOwner,
|
|
8458
8454
|
listShims: () => listShims,
|
|
8459
8455
|
removeShims: () => removeShims,
|
|
8460
8456
|
validateShim: () => validateShim
|
|
8461
8457
|
});
|
|
8458
|
+
function getShimRegistryPath() {
|
|
8459
|
+
return import_path4.default.join(PATHS.home, "shim-registry.json");
|
|
8460
|
+
}
|
|
8461
|
+
function loadShimRegistry() {
|
|
8462
|
+
const registryPath = getShimRegistryPath();
|
|
8463
|
+
try {
|
|
8464
|
+
if (import_fs4.default.existsSync(registryPath)) {
|
|
8465
|
+
return JSON.parse(import_fs4.default.readFileSync(registryPath, "utf-8"));
|
|
8466
|
+
}
|
|
8467
|
+
} catch {
|
|
8468
|
+
}
|
|
8469
|
+
return {};
|
|
8470
|
+
}
|
|
8471
|
+
function saveShimRegistry(registry) {
|
|
8472
|
+
const registryPath = getShimRegistryPath();
|
|
8473
|
+
const dir = import_path4.default.dirname(registryPath);
|
|
8474
|
+
if (!import_fs4.default.existsSync(dir)) {
|
|
8475
|
+
import_fs4.default.mkdirSync(dir, { recursive: true });
|
|
8476
|
+
}
|
|
8477
|
+
import_fs4.default.writeFileSync(registryPath, JSON.stringify(registry, null, 2));
|
|
8478
|
+
}
|
|
8479
|
+
function registerShim(bin, owner, type, target) {
|
|
8480
|
+
const registry = loadShimRegistry();
|
|
8481
|
+
const existing = registry[bin];
|
|
8482
|
+
let collision = false;
|
|
8483
|
+
let previousOwner = void 0;
|
|
8484
|
+
if (existing && existing.owner !== owner) {
|
|
8485
|
+
collision = true;
|
|
8486
|
+
previousOwner = existing.owner;
|
|
8487
|
+
}
|
|
8488
|
+
registry[bin] = {
|
|
8489
|
+
owner,
|
|
8490
|
+
type,
|
|
8491
|
+
target,
|
|
8492
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8493
|
+
};
|
|
8494
|
+
saveShimRegistry(registry);
|
|
8495
|
+
return { collision, previousOwner };
|
|
8496
|
+
}
|
|
8497
|
+
function unregisterShim(bin) {
|
|
8498
|
+
const registry = loadShimRegistry();
|
|
8499
|
+
delete registry[bin];
|
|
8500
|
+
saveShimRegistry(registry);
|
|
8501
|
+
}
|
|
8502
|
+
function getShimOwner(bin) {
|
|
8503
|
+
const registry = loadShimRegistry();
|
|
8504
|
+
return registry[bin] || null;
|
|
8505
|
+
}
|
|
8506
|
+
function getAllShimOwners() {
|
|
8507
|
+
return loadShimRegistry();
|
|
8508
|
+
}
|
|
8462
8509
|
async function createShimsForTool(manifest) {
|
|
8463
8510
|
const bins = manifest.bins || [manifest.name || manifest.id.split(":")[1]];
|
|
8511
|
+
const created = [];
|
|
8512
|
+
const collisions = [];
|
|
8464
8513
|
for (const bin of bins) {
|
|
8465
8514
|
const target = resolveBinTarget(manifest, bin);
|
|
8466
8515
|
if (!import_fs4.default.existsSync(target)) {
|
|
8467
8516
|
console.warn(`[Shims] Warning: Binary target does not exist: ${target}`);
|
|
8468
8517
|
continue;
|
|
8469
8518
|
}
|
|
8519
|
+
const shimType = manifest.installType === "binary" ? "symlink" : "wrapper";
|
|
8470
8520
|
if (manifest.installType === "binary") {
|
|
8471
8521
|
createSymlinkShim(bin, target, PATHS.bins);
|
|
8472
8522
|
} else {
|
|
8473
8523
|
createWrapperShim(bin, target, PATHS.bins);
|
|
8474
8524
|
}
|
|
8525
|
+
const { collision, previousOwner } = registerShim(bin, manifest.id, shimType, target);
|
|
8526
|
+
if (collision) {
|
|
8527
|
+
collisions.push({ bin, previousOwner });
|
|
8528
|
+
console.warn(`[Shims] Warning: '${bin}' was owned by ${previousOwner}, now owned by ${manifest.id}`);
|
|
8529
|
+
}
|
|
8530
|
+
created.push(bin);
|
|
8475
8531
|
}
|
|
8532
|
+
return { created, collisions };
|
|
8476
8533
|
}
|
|
8477
8534
|
function resolveBinTarget(manifest, bin) {
|
|
8478
8535
|
switch (manifest.installType) {
|
|
@@ -8513,14 +8570,21 @@ function createSymlinkShim(name, targetAbs, binsDir) {
|
|
|
8513
8570
|
console.log(`[Shims] Created symlink shim: ${name} \u2192 ${targetAbs}`);
|
|
8514
8571
|
}
|
|
8515
8572
|
function removeShims(bins) {
|
|
8573
|
+
const removed = [];
|
|
8574
|
+
const notFound = [];
|
|
8516
8575
|
for (const bin of bins) {
|
|
8517
8576
|
const shimPath = import_path4.default.join(PATHS.bins, bin);
|
|
8518
8577
|
try {
|
|
8519
8578
|
import_fs4.default.unlinkSync(shimPath);
|
|
8579
|
+
unregisterShim(bin);
|
|
8580
|
+
removed.push(bin);
|
|
8520
8581
|
console.log(`[Shims] Removed shim: ${bin}`);
|
|
8521
8582
|
} catch (err) {
|
|
8583
|
+
notFound.push(bin);
|
|
8584
|
+
unregisterShim(bin);
|
|
8522
8585
|
}
|
|
8523
8586
|
}
|
|
8587
|
+
return { removed, notFound };
|
|
8524
8588
|
}
|
|
8525
8589
|
function listShims() {
|
|
8526
8590
|
if (!import_fs4.default.existsSync(PATHS.bins)) {
|
|
@@ -8569,16 +8633,53 @@ function validateShim(bin) {
|
|
|
8569
8633
|
}
|
|
8570
8634
|
var import_fs4, import_path4;
|
|
8571
8635
|
var init_shims = __esm({
|
|
8572
|
-
"
|
|
8636
|
+
"packages/core/src/shims.js"() {
|
|
8573
8637
|
import_fs4 = __toESM(require("fs"), 1);
|
|
8574
8638
|
import_path4 = __toESM(require("path"), 1);
|
|
8575
8639
|
init_src();
|
|
8576
8640
|
}
|
|
8577
8641
|
});
|
|
8578
8642
|
|
|
8579
|
-
//
|
|
8643
|
+
// packages/core/src/installer.js
|
|
8644
|
+
function discoverNpmBins(installPath, packageName) {
|
|
8645
|
+
try {
|
|
8646
|
+
const pkgJsonPath = import_path5.default.join(installPath, "node_modules", packageName, "package.json");
|
|
8647
|
+
if (!import_fs5.default.existsSync(pkgJsonPath)) {
|
|
8648
|
+
console.warn(`[Installer] Warning: Could not find package.json at ${pkgJsonPath}`);
|
|
8649
|
+
return [];
|
|
8650
|
+
}
|
|
8651
|
+
const pkgJson = JSON.parse(import_fs5.default.readFileSync(pkgJsonPath, "utf8"));
|
|
8652
|
+
const bins = [];
|
|
8653
|
+
if (typeof pkgJson.bin === "string") {
|
|
8654
|
+
const binName = packageName.split("/").pop();
|
|
8655
|
+
bins.push(binName);
|
|
8656
|
+
} else if (typeof pkgJson.bin === "object" && pkgJson.bin !== null) {
|
|
8657
|
+
bins.push(...Object.keys(pkgJson.bin));
|
|
8658
|
+
} else {
|
|
8659
|
+
console.warn(`[Installer] Warning: Package '${packageName}' has no 'bin' field`);
|
|
8660
|
+
}
|
|
8661
|
+
return bins;
|
|
8662
|
+
} catch (error) {
|
|
8663
|
+
console.warn(`[Installer] Error discovering bins: ${error.message}`);
|
|
8664
|
+
return [];
|
|
8665
|
+
}
|
|
8666
|
+
}
|
|
8667
|
+
function hasInstallScripts(installPath, packageName) {
|
|
8668
|
+
try {
|
|
8669
|
+
const pkgJsonPath = import_path5.default.join(installPath, "node_modules", packageName, "package.json");
|
|
8670
|
+
if (!import_fs5.default.existsSync(pkgJsonPath)) {
|
|
8671
|
+
return false;
|
|
8672
|
+
}
|
|
8673
|
+
const pkgJson = JSON.parse(import_fs5.default.readFileSync(pkgJsonPath, "utf8"));
|
|
8674
|
+
const scripts = pkgJson.scripts || {};
|
|
8675
|
+
const installScriptKeys = ["preinstall", "install", "postinstall", "prepare"];
|
|
8676
|
+
return installScriptKeys.some((key) => scripts[key]);
|
|
8677
|
+
} catch (error) {
|
|
8678
|
+
return false;
|
|
8679
|
+
}
|
|
8680
|
+
}
|
|
8580
8681
|
async function installPackage(id, options = {}) {
|
|
8581
|
-
const { force = false, onProgress } = options;
|
|
8682
|
+
const { force = false, allowScripts = false, onProgress } = options;
|
|
8582
8683
|
ensureDirectories();
|
|
8583
8684
|
onProgress?.({ phase: "resolving", package: id });
|
|
8584
8685
|
const resolved = await resolvePackage(id);
|
|
@@ -8598,7 +8699,7 @@ async function installPackage(id, options = {}) {
|
|
|
8598
8699
|
for (const pkg of toInstall) {
|
|
8599
8700
|
onProgress?.({ phase: "installing", package: pkg.id, total: toInstall.length, current: results.length + 1 });
|
|
8600
8701
|
try {
|
|
8601
|
-
const result = await installSinglePackage(pkg, { force, onProgress });
|
|
8702
|
+
const result = await installSinglePackage(pkg, { force, allowScripts, onProgress });
|
|
8602
8703
|
results.push(result);
|
|
8603
8704
|
} catch (error) {
|
|
8604
8705
|
return {
|
|
@@ -8618,7 +8719,7 @@ async function installPackage(id, options = {}) {
|
|
|
8618
8719
|
};
|
|
8619
8720
|
}
|
|
8620
8721
|
async function installSinglePackage(pkg, options = {}) {
|
|
8621
|
-
const { force = false, onProgress } = options;
|
|
8722
|
+
const { force = false, allowScripts = false, onProgress } = options;
|
|
8622
8723
|
const installPath = getPackagePath(pkg.id);
|
|
8623
8724
|
if (import_fs5.default.existsSync(installPath) && !force) {
|
|
8624
8725
|
return { success: true, id: pkg.id, path: installPath, skipped: true };
|
|
@@ -8638,7 +8739,23 @@ async function installSinglePackage(pkg, options = {}) {
|
|
|
8638
8739
|
if (!import_fs5.default.existsSync(import_path5.default.join(installPath, "package.json"))) {
|
|
8639
8740
|
execSync10(`"${npmCmd}" init -y`, { cwd: installPath, stdio: "pipe" });
|
|
8640
8741
|
}
|
|
8641
|
-
|
|
8742
|
+
const shouldIgnoreScripts = pkg.source?.type === "npm" && !allowScripts;
|
|
8743
|
+
const installFlags = shouldIgnoreScripts ? "--ignore-scripts --no-audit --no-fund" : "--no-audit --no-fund";
|
|
8744
|
+
execSync10(`"${npmCmd}" install ${pkg.npmPackage} ${installFlags}`, { cwd: installPath, stdio: "pipe" });
|
|
8745
|
+
let bins = pkg.bins;
|
|
8746
|
+
if (!bins || bins.length === 0) {
|
|
8747
|
+
bins = discoverNpmBins(installPath, pkg.npmPackage);
|
|
8748
|
+
console.log(`[Installer] Discovered binaries: ${bins.join(", ") || "(none)"}`);
|
|
8749
|
+
}
|
|
8750
|
+
let installedVersion = pkg.version || "latest";
|
|
8751
|
+
try {
|
|
8752
|
+
const pkgJsonPath = import_path5.default.join(installPath, "node_modules", pkg.npmPackage, "package.json");
|
|
8753
|
+
if (import_fs5.default.existsSync(pkgJsonPath)) {
|
|
8754
|
+
const pkgJson = JSON.parse(import_fs5.default.readFileSync(pkgJsonPath, "utf8"));
|
|
8755
|
+
installedVersion = pkgJson.version;
|
|
8756
|
+
}
|
|
8757
|
+
} catch (err) {
|
|
8758
|
+
}
|
|
8642
8759
|
if (pkg.postInstall) {
|
|
8643
8760
|
onProgress?.({ phase: "postInstall", package: pkg.id, message: pkg.postInstall });
|
|
8644
8761
|
const postInstallCmd = pkg.postInstall.replace(
|
|
@@ -8647,27 +8764,43 @@ async function installSinglePackage(pkg, options = {}) {
|
|
|
8647
8764
|
);
|
|
8648
8765
|
execSync10(postInstallCmd, { cwd: installPath, stdio: "pipe" });
|
|
8649
8766
|
}
|
|
8767
|
+
const scriptsDetected = hasInstallScripts(installPath, pkg.npmPackage);
|
|
8768
|
+
const scriptsPolicy = installFlags.includes("--ignore-scripts") ? "ignore" : "allow";
|
|
8769
|
+
if (scriptsDetected && scriptsPolicy === "ignore") {
|
|
8770
|
+
console.warn(`
|
|
8771
|
+
\u26A0\uFE0F This package defines install scripts that were skipped for security.`);
|
|
8772
|
+
console.warn(` If the CLI fails to run, reinstall with:`);
|
|
8773
|
+
console.warn(` rudi install ${pkg.id} --allow-scripts
|
|
8774
|
+
`);
|
|
8775
|
+
}
|
|
8650
8776
|
const manifest2 = {
|
|
8651
8777
|
id: pkg.id,
|
|
8652
8778
|
kind: pkg.kind,
|
|
8653
8779
|
name: pkgName,
|
|
8654
|
-
version:
|
|
8780
|
+
version: installedVersion,
|
|
8655
8781
|
npmPackage: pkg.npmPackage,
|
|
8782
|
+
bins,
|
|
8783
|
+
hasInstallScripts: scriptsDetected,
|
|
8784
|
+
scriptsPolicy,
|
|
8656
8785
|
postInstall: pkg.postInstall,
|
|
8657
8786
|
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8658
|
-
source: "npm"
|
|
8787
|
+
source: pkg.source || { type: "npm" }
|
|
8659
8788
|
};
|
|
8660
8789
|
import_fs5.default.writeFileSync(
|
|
8661
8790
|
import_path5.default.join(installPath, "manifest.json"),
|
|
8662
8791
|
JSON.stringify(manifest2, null, 2)
|
|
8663
8792
|
);
|
|
8664
|
-
|
|
8665
|
-
|
|
8666
|
-
|
|
8667
|
-
|
|
8668
|
-
|
|
8669
|
-
|
|
8670
|
-
|
|
8793
|
+
if (bins && bins.length > 0) {
|
|
8794
|
+
await createShimsForTool({
|
|
8795
|
+
id: pkg.id,
|
|
8796
|
+
installType: "npm",
|
|
8797
|
+
installDir: installPath,
|
|
8798
|
+
bins,
|
|
8799
|
+
name: pkgName
|
|
8800
|
+
});
|
|
8801
|
+
} else {
|
|
8802
|
+
console.warn(`[Installer] Warning: No binaries found for ${pkg.npmPackage}`);
|
|
8803
|
+
}
|
|
8671
8804
|
return { success: true, id: pkg.id, path: installPath };
|
|
8672
8805
|
} catch (error) {
|
|
8673
8806
|
throw new Error(`Failed to install ${pkg.npmPackage}: ${error.message}`);
|
|
@@ -8815,17 +8948,33 @@ async function uninstallPackage(id) {
|
|
|
8815
8948
|
return { success: false, error: `Package not installed: ${id}` };
|
|
8816
8949
|
}
|
|
8817
8950
|
try {
|
|
8951
|
+
let bins = [];
|
|
8952
|
+
if (kind !== "prompt") {
|
|
8953
|
+
const manifestPath = import_path5.default.join(installPath, "manifest.json");
|
|
8954
|
+
if (import_fs5.default.existsSync(manifestPath)) {
|
|
8955
|
+
try {
|
|
8956
|
+
const manifest = JSON.parse(import_fs5.default.readFileSync(manifestPath, "utf-8"));
|
|
8957
|
+
bins = manifest.bins || manifest.binaries || [];
|
|
8958
|
+
} catch {
|
|
8959
|
+
bins = [name];
|
|
8960
|
+
}
|
|
8961
|
+
}
|
|
8962
|
+
}
|
|
8963
|
+
if (bins.length > 0) {
|
|
8964
|
+
removeShims(bins);
|
|
8965
|
+
}
|
|
8818
8966
|
if (kind === "prompt") {
|
|
8819
8967
|
import_fs5.default.unlinkSync(installPath);
|
|
8820
8968
|
} else {
|
|
8821
8969
|
import_fs5.default.rmSync(installPath, { recursive: true });
|
|
8822
8970
|
}
|
|
8823
|
-
const lockDir = kind === "binary" ? "binaries" : kind + "s";
|
|
8824
|
-
const
|
|
8971
|
+
const lockDir = kind === "binary" ? "binaries" : kind === "npm" ? "npms" : kind + "s";
|
|
8972
|
+
const lockName = name.replace(/\//g, "__").replace(/^@/, "");
|
|
8973
|
+
const lockPath = import_path5.default.join(PATHS.locks, lockDir, `${lockName}.lock.yaml`);
|
|
8825
8974
|
if (import_fs5.default.existsSync(lockPath)) {
|
|
8826
8975
|
import_fs5.default.unlinkSync(lockPath);
|
|
8827
8976
|
}
|
|
8828
|
-
return { success: true };
|
|
8977
|
+
return { success: true, removedShims: bins };
|
|
8829
8978
|
} catch (error) {
|
|
8830
8979
|
return { success: false, error: error.message };
|
|
8831
8980
|
}
|
|
@@ -9109,7 +9258,7 @@ async function installPythonRequirements(pythonPath, onProgress) {
|
|
|
9109
9258
|
}
|
|
9110
9259
|
var import_fs5, import_path5;
|
|
9111
9260
|
var init_installer = __esm({
|
|
9112
|
-
"
|
|
9261
|
+
"packages/core/src/installer.js"() {
|
|
9113
9262
|
import_fs5 = __toESM(require("fs"), 1);
|
|
9114
9263
|
import_path5 = __toESM(require("path"), 1);
|
|
9115
9264
|
init_src();
|
|
@@ -9120,7 +9269,7 @@ var init_installer = __esm({
|
|
|
9120
9269
|
}
|
|
9121
9270
|
});
|
|
9122
9271
|
|
|
9123
|
-
//
|
|
9272
|
+
// packages/core/src/deps.js
|
|
9124
9273
|
function checkRuntime(runtime) {
|
|
9125
9274
|
const name = runtime.replace(/^runtime:/, "");
|
|
9126
9275
|
const rudiPath = import_path6.default.join(PATHS.runtimes, name);
|
|
@@ -9323,7 +9472,7 @@ async function getAllDepsFromRegistry() {
|
|
|
9323
9472
|
}
|
|
9324
9473
|
var import_fs6, import_path6, import_child_process;
|
|
9325
9474
|
var init_deps = __esm({
|
|
9326
|
-
"
|
|
9475
|
+
"packages/core/src/deps.js"() {
|
|
9327
9476
|
import_fs6 = __toESM(require("fs"), 1);
|
|
9328
9477
|
import_path6 = __toESM(require("path"), 1);
|
|
9329
9478
|
import_child_process = require("child_process");
|
|
@@ -9332,7 +9481,7 @@ var init_deps = __esm({
|
|
|
9332
9481
|
}
|
|
9333
9482
|
});
|
|
9334
9483
|
|
|
9335
|
-
//
|
|
9484
|
+
// packages/core/src/rudi-config.js
|
|
9336
9485
|
function createRudiConfig() {
|
|
9337
9486
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9338
9487
|
return {
|
|
@@ -9555,7 +9704,7 @@ function updateSecretStatus(secretName, configured, provider) {
|
|
|
9555
9704
|
}
|
|
9556
9705
|
var fs7, path7, RUDI_JSON_PATH, RUDI_JSON_TMP, RUDI_JSON_LOCK, CONFIG_MODE, LOCK_TIMEOUT_MS;
|
|
9557
9706
|
var init_rudi_config = __esm({
|
|
9558
|
-
"
|
|
9707
|
+
"packages/core/src/rudi-config.js"() {
|
|
9559
9708
|
fs7 = __toESM(require("fs"), 1);
|
|
9560
9709
|
path7 = __toESM(require("path"), 1);
|
|
9561
9710
|
init_src();
|
|
@@ -9567,7 +9716,7 @@ var init_rudi_config = __esm({
|
|
|
9567
9716
|
}
|
|
9568
9717
|
});
|
|
9569
9718
|
|
|
9570
|
-
//
|
|
9719
|
+
// packages/core/src/tool-index.js
|
|
9571
9720
|
function loadSecrets() {
|
|
9572
9721
|
try {
|
|
9573
9722
|
const content = fs8.readFileSync(SECRETS_PATH, "utf-8");
|
|
@@ -9825,7 +9974,7 @@ async function indexAllStacks(options = {}) {
|
|
|
9825
9974
|
}
|
|
9826
9975
|
var import_child_process2, fs8, path8, readline, TOOL_INDEX_PATH, TOOL_INDEX_TMP, SECRETS_PATH, REQUEST_TIMEOUT_MS, PROTOCOL_VERSION;
|
|
9827
9976
|
var init_tool_index = __esm({
|
|
9828
|
-
"
|
|
9977
|
+
"packages/core/src/tool-index.js"() {
|
|
9829
9978
|
import_child_process2 = require("child_process");
|
|
9830
9979
|
fs8 = __toESM(require("fs"), 1);
|
|
9831
9980
|
path8 = __toESM(require("path"), 1);
|
|
@@ -9840,7 +9989,7 @@ var init_tool_index = __esm({
|
|
|
9840
9989
|
}
|
|
9841
9990
|
});
|
|
9842
9991
|
|
|
9843
|
-
//
|
|
9992
|
+
// packages/core/src/system-registry.js
|
|
9844
9993
|
async function registerSystemBinary(name, options = {}) {
|
|
9845
9994
|
const {
|
|
9846
9995
|
searchPaths = getDefaultSearchPaths(),
|
|
@@ -9974,7 +10123,7 @@ function getSystemBinaryInfo(name) {
|
|
|
9974
10123
|
}
|
|
9975
10124
|
var import_fs7, import_path7, import_child_process3;
|
|
9976
10125
|
var init_system_registry = __esm({
|
|
9977
|
-
"
|
|
10126
|
+
"packages/core/src/system-registry.js"() {
|
|
9978
10127
|
import_fs7 = __toESM(require("fs"), 1);
|
|
9979
10128
|
import_path7 = __toESM(require("path"), 1);
|
|
9980
10129
|
import_child_process3 = require("child_process");
|
|
@@ -9983,9 +10132,9 @@ var init_system_registry = __esm({
|
|
|
9983
10132
|
}
|
|
9984
10133
|
});
|
|
9985
10134
|
|
|
9986
|
-
//
|
|
9987
|
-
var
|
|
9988
|
-
__export(
|
|
10135
|
+
// packages/core/src/index.js
|
|
10136
|
+
var src_exports = {};
|
|
10137
|
+
__export(src_exports, {
|
|
9989
10138
|
CONFIG_MODE: () => CONFIG_MODE,
|
|
9990
10139
|
PATHS: () => PATHS,
|
|
9991
10140
|
RUDI_JSON_PATH: () => RUDI_JSON_PATH,
|
|
@@ -10012,6 +10161,7 @@ __export(src_exports2, {
|
|
|
10012
10161
|
formatDependencyResults: () => formatDependencyResults,
|
|
10013
10162
|
getAllDepsFromRegistry: () => getAllDepsFromRegistry,
|
|
10014
10163
|
getAllLockfiles: () => getAllLockfiles,
|
|
10164
|
+
getAllShimOwners: () => getAllShimOwners,
|
|
10015
10165
|
getAvailableDeps: () => getAvailableDeps,
|
|
10016
10166
|
getDefaultNpxBin: () => getDefaultNpxBin,
|
|
10017
10167
|
getDefaultRuntimeBin: () => getDefaultRuntimeBin,
|
|
@@ -10021,6 +10171,7 @@ __export(src_exports2, {
|
|
|
10021
10171
|
getLockfilePath: () => getLockfilePath,
|
|
10022
10172
|
getPackage: () => getPackage,
|
|
10023
10173
|
getPackagePath: () => getPackagePath,
|
|
10174
|
+
getShimOwner: () => getShimOwner,
|
|
10024
10175
|
getSystemBinaryInfo: () => getSystemBinaryInfo,
|
|
10025
10176
|
hasLockfile: () => hasLockfile,
|
|
10026
10177
|
indexAllStacks: () => indexAllStacks,
|
|
@@ -10058,7 +10209,7 @@ __export(src_exports2, {
|
|
|
10058
10209
|
writeToolIndex: () => writeToolIndex
|
|
10059
10210
|
});
|
|
10060
10211
|
var init_src3 = __esm({
|
|
10061
|
-
"
|
|
10212
|
+
"packages/core/src/index.js"() {
|
|
10062
10213
|
init_src();
|
|
10063
10214
|
init_src2();
|
|
10064
10215
|
init_resolver();
|
|
@@ -10072,6 +10223,13 @@ var init_src3 = __esm({
|
|
|
10072
10223
|
}
|
|
10073
10224
|
});
|
|
10074
10225
|
|
|
10226
|
+
// node_modules/.pnpm/@learnrudi+core@1.0.2/node_modules/@learnrudi/core/src/shims.js
|
|
10227
|
+
var init_shims2 = __esm({
|
|
10228
|
+
"node_modules/.pnpm/@learnrudi+core@1.0.2/node_modules/@learnrudi/core/src/shims.js"() {
|
|
10229
|
+
init_src();
|
|
10230
|
+
}
|
|
10231
|
+
});
|
|
10232
|
+
|
|
10075
10233
|
// node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/codegen/code.js
|
|
10076
10234
|
var require_code = __commonJS({
|
|
10077
10235
|
"node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/codegen/code.js"(exports2) {
|
|
@@ -13265,8 +13423,8 @@ var require_utils = __commonJS({
|
|
|
13265
13423
|
}
|
|
13266
13424
|
return ind;
|
|
13267
13425
|
}
|
|
13268
|
-
function removeDotSegments(
|
|
13269
|
-
let input =
|
|
13426
|
+
function removeDotSegments(path35) {
|
|
13427
|
+
let input = path35;
|
|
13270
13428
|
const output = [];
|
|
13271
13429
|
let nextSlash = -1;
|
|
13272
13430
|
let len = 0;
|
|
@@ -13465,8 +13623,8 @@ var require_schemes = __commonJS({
|
|
|
13465
13623
|
wsComponent.secure = void 0;
|
|
13466
13624
|
}
|
|
13467
13625
|
if (wsComponent.resourceName) {
|
|
13468
|
-
const [
|
|
13469
|
-
wsComponent.path =
|
|
13626
|
+
const [path35, query] = wsComponent.resourceName.split("?");
|
|
13627
|
+
wsComponent.path = path35 && path35 !== "/" ? path35 : void 0;
|
|
13470
13628
|
wsComponent.query = query;
|
|
13471
13629
|
wsComponent.resourceName = void 0;
|
|
13472
13630
|
}
|
|
@@ -16819,12 +16977,12 @@ var require_dist2 = __commonJS({
|
|
|
16819
16977
|
throw new Error(`Unknown format "${name}"`);
|
|
16820
16978
|
return f;
|
|
16821
16979
|
};
|
|
16822
|
-
function addFormats2(ajv2, list,
|
|
16980
|
+
function addFormats2(ajv2, list, fs35, exportName) {
|
|
16823
16981
|
var _a;
|
|
16824
16982
|
var _b;
|
|
16825
16983
|
(_a = (_b = ajv2.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
16826
16984
|
for (const f of list)
|
|
16827
|
-
ajv2.addFormat(f,
|
|
16985
|
+
ajv2.addFormat(f, fs35[f]);
|
|
16828
16986
|
}
|
|
16829
16987
|
module2.exports = exports2 = formatsPlugin;
|
|
16830
16988
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -16832,65 +16990,749 @@ var require_dist2 = __commonJS({
|
|
|
16832
16990
|
}
|
|
16833
16991
|
});
|
|
16834
16992
|
|
|
16835
|
-
//
|
|
16836
|
-
|
|
16837
|
-
|
|
16838
|
-
|
|
16839
|
-
|
|
16840
|
-
|
|
16841
|
-
|
|
16842
|
-
|
|
16843
|
-
|
|
16844
|
-
|
|
16845
|
-
|
|
16846
|
-
|
|
16847
|
-
|
|
16848
|
-
|
|
16849
|
-
|
|
16850
|
-
|
|
16851
|
-
|
|
16852
|
-
|
|
16853
|
-
|
|
16854
|
-
|
|
16855
|
-
|
|
16856
|
-
|
|
16857
|
-
|
|
16858
|
-
|
|
16859
|
-
|
|
16860
|
-
|
|
16861
|
-
|
|
16993
|
+
// packages/registry-client/src/index.js
|
|
16994
|
+
var src_exports2 = {};
|
|
16995
|
+
__export(src_exports2, {
|
|
16996
|
+
CACHE_TTL: () => CACHE_TTL2,
|
|
16997
|
+
DEFAULT_REGISTRY_URL: () => DEFAULT_REGISTRY_URL2,
|
|
16998
|
+
PACKAGE_KINDS: () => PACKAGE_KINDS4,
|
|
16999
|
+
RUNTIMES_DOWNLOAD_BASE: () => RUNTIMES_DOWNLOAD_BASE2,
|
|
17000
|
+
RUNTIMES_RELEASE_VERSION: () => RUNTIMES_RELEASE_VERSION2,
|
|
17001
|
+
checkCache: () => checkCache,
|
|
17002
|
+
clearCache: () => clearCache2,
|
|
17003
|
+
computeHash: () => computeHash,
|
|
17004
|
+
downloadPackage: () => downloadPackage2,
|
|
17005
|
+
downloadRuntime: () => downloadRuntime2,
|
|
17006
|
+
downloadTool: () => downloadTool2,
|
|
17007
|
+
fetchIndex: () => fetchIndex2,
|
|
17008
|
+
getManifest: () => getManifest2,
|
|
17009
|
+
getPackage: () => getPackage2,
|
|
17010
|
+
getPackageKinds: () => getPackageKinds,
|
|
17011
|
+
listPackages: () => listPackages2,
|
|
17012
|
+
searchPackages: () => searchPackages2,
|
|
17013
|
+
verifyHash: () => verifyHash
|
|
17014
|
+
});
|
|
17015
|
+
function getLocalRegistryPaths2() {
|
|
17016
|
+
if (process.env.USE_LOCAL_REGISTRY !== "true") {
|
|
17017
|
+
return [];
|
|
17018
|
+
}
|
|
17019
|
+
return [
|
|
17020
|
+
import_path18.default.join(process.cwd(), "registry", "index.json"),
|
|
17021
|
+
import_path18.default.join(process.cwd(), "..", "registry", "index.json"),
|
|
17022
|
+
"/Users/hoff/dev/RUDI/registry/index.json"
|
|
17023
|
+
];
|
|
17024
|
+
}
|
|
17025
|
+
async function fetchIndex2(options = {}) {
|
|
17026
|
+
const { url = DEFAULT_REGISTRY_URL2, force = false } = options;
|
|
17027
|
+
const localResult = getLocalIndex2();
|
|
17028
|
+
if (localResult) {
|
|
17029
|
+
const { index: localIndex, mtime: localMtime } = localResult;
|
|
17030
|
+
const cacheMtime = getCacheMtime2();
|
|
17031
|
+
if (force || !cacheMtime || localMtime > cacheMtime) {
|
|
17032
|
+
cacheIndex2(localIndex);
|
|
17033
|
+
return localIndex;
|
|
17034
|
+
}
|
|
17035
|
+
}
|
|
17036
|
+
if (!force) {
|
|
17037
|
+
const cached = getCachedIndex2();
|
|
17038
|
+
if (cached) {
|
|
17039
|
+
return cached;
|
|
17040
|
+
}
|
|
17041
|
+
}
|
|
17042
|
+
if (localResult) {
|
|
17043
|
+
return localResult.index;
|
|
17044
|
+
}
|
|
17045
|
+
try {
|
|
17046
|
+
const response = await fetch(url, {
|
|
17047
|
+
headers: {
|
|
17048
|
+
"Accept": "application/json",
|
|
17049
|
+
"User-Agent": "rudi-cli/2.0"
|
|
16862
17050
|
}
|
|
16863
|
-
}
|
|
16864
|
-
|
|
16865
|
-
|
|
16866
|
-
|
|
17051
|
+
});
|
|
17052
|
+
if (!response.ok) {
|
|
17053
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
17054
|
+
}
|
|
17055
|
+
const index = await response.json();
|
|
17056
|
+
cacheIndex2(index);
|
|
17057
|
+
return index;
|
|
17058
|
+
} catch (error) {
|
|
17059
|
+
const fallback = getLocalIndex2();
|
|
17060
|
+
if (fallback) {
|
|
17061
|
+
return fallback.index;
|
|
16867
17062
|
}
|
|
17063
|
+
throw new Error(`Failed to fetch registry: ${error.message}`);
|
|
16868
17064
|
}
|
|
16869
|
-
return { command, args, flags };
|
|
16870
17065
|
}
|
|
16871
|
-
function
|
|
16872
|
-
|
|
16873
|
-
|
|
16874
|
-
|
|
16875
|
-
|
|
16876
|
-
|
|
17066
|
+
function getCachedIndex2() {
|
|
17067
|
+
const cachePath = PATHS.registryCache;
|
|
17068
|
+
if (!import_fs19.default.existsSync(cachePath)) {
|
|
17069
|
+
return null;
|
|
17070
|
+
}
|
|
17071
|
+
try {
|
|
17072
|
+
const stat = import_fs19.default.statSync(cachePath);
|
|
17073
|
+
const age = Date.now() - stat.mtimeMs;
|
|
17074
|
+
if (age > CACHE_TTL2) {
|
|
17075
|
+
return null;
|
|
17076
|
+
}
|
|
17077
|
+
return JSON.parse(import_fs19.default.readFileSync(cachePath, "utf-8"));
|
|
17078
|
+
} catch {
|
|
17079
|
+
return null;
|
|
17080
|
+
}
|
|
16877
17081
|
}
|
|
16878
|
-
function
|
|
16879
|
-
|
|
16880
|
-
|
|
16881
|
-
|
|
16882
|
-
|
|
16883
|
-
|
|
17082
|
+
function cacheIndex2(index) {
|
|
17083
|
+
const cachePath = PATHS.registryCache;
|
|
17084
|
+
const cacheDir = import_path18.default.dirname(cachePath);
|
|
17085
|
+
if (!import_fs19.default.existsSync(cacheDir)) {
|
|
17086
|
+
import_fs19.default.mkdirSync(cacheDir, { recursive: true });
|
|
17087
|
+
}
|
|
17088
|
+
import_fs19.default.writeFileSync(cachePath, JSON.stringify(index, null, 2));
|
|
16884
17089
|
}
|
|
16885
|
-
|
|
16886
|
-
|
|
16887
|
-
|
|
16888
|
-
|
|
17090
|
+
function getCacheMtime2() {
|
|
17091
|
+
const cachePath = PATHS.registryCache;
|
|
17092
|
+
if (!import_fs19.default.existsSync(cachePath)) {
|
|
17093
|
+
return null;
|
|
17094
|
+
}
|
|
17095
|
+
try {
|
|
17096
|
+
return import_fs19.default.statSync(cachePath).mtimeMs;
|
|
17097
|
+
} catch {
|
|
17098
|
+
return null;
|
|
17099
|
+
}
|
|
16889
17100
|
}
|
|
16890
|
-
function
|
|
16891
|
-
|
|
16892
|
-
|
|
16893
|
-
|
|
17101
|
+
function getLocalIndex2() {
|
|
17102
|
+
for (const localPath of getLocalRegistryPaths2()) {
|
|
17103
|
+
if (import_fs19.default.existsSync(localPath)) {
|
|
17104
|
+
try {
|
|
17105
|
+
const index = JSON.parse(import_fs19.default.readFileSync(localPath, "utf-8"));
|
|
17106
|
+
const mtime = import_fs19.default.statSync(localPath).mtimeMs;
|
|
17107
|
+
return { index, mtime };
|
|
17108
|
+
} catch {
|
|
17109
|
+
continue;
|
|
17110
|
+
}
|
|
17111
|
+
}
|
|
17112
|
+
}
|
|
17113
|
+
return null;
|
|
17114
|
+
}
|
|
17115
|
+
function clearCache2() {
|
|
17116
|
+
if (import_fs19.default.existsSync(PATHS.registryCache)) {
|
|
17117
|
+
import_fs19.default.unlinkSync(PATHS.registryCache);
|
|
17118
|
+
}
|
|
17119
|
+
}
|
|
17120
|
+
function checkCache() {
|
|
17121
|
+
const cachePath = PATHS.registryCache;
|
|
17122
|
+
if (!import_fs19.default.existsSync(cachePath)) {
|
|
17123
|
+
return { fresh: false, age: null };
|
|
17124
|
+
}
|
|
17125
|
+
try {
|
|
17126
|
+
const stat = import_fs19.default.statSync(cachePath);
|
|
17127
|
+
const age = Date.now() - stat.mtimeMs;
|
|
17128
|
+
return { fresh: age <= CACHE_TTL2, age };
|
|
17129
|
+
} catch {
|
|
17130
|
+
return { fresh: false, age: null };
|
|
17131
|
+
}
|
|
17132
|
+
}
|
|
17133
|
+
function getKindSection2(kind) {
|
|
17134
|
+
return KIND_PLURALS2[kind] || `${kind}s`;
|
|
17135
|
+
}
|
|
17136
|
+
async function searchPackages2(query, options = {}) {
|
|
17137
|
+
const { kind } = options;
|
|
17138
|
+
const index = await fetchIndex2();
|
|
17139
|
+
const results = [];
|
|
17140
|
+
const queryLower = query.toLowerCase();
|
|
17141
|
+
const kinds = kind ? [kind] : PACKAGE_KINDS4;
|
|
17142
|
+
for (const k of kinds) {
|
|
17143
|
+
const section = index.packages?.[getKindSection2(k)];
|
|
17144
|
+
if (!section) continue;
|
|
17145
|
+
const packages = [...section.official || [], ...section.community || []];
|
|
17146
|
+
for (const pkg of packages) {
|
|
17147
|
+
if (matchesQuery2(pkg, queryLower)) {
|
|
17148
|
+
results.push({ ...pkg, kind: k });
|
|
17149
|
+
}
|
|
17150
|
+
}
|
|
17151
|
+
}
|
|
17152
|
+
return results;
|
|
17153
|
+
}
|
|
17154
|
+
function matchesQuery2(pkg, query) {
|
|
17155
|
+
const searchable = [
|
|
17156
|
+
pkg.id || "",
|
|
17157
|
+
pkg.name || "",
|
|
17158
|
+
pkg.description || "",
|
|
17159
|
+
...pkg.tags || []
|
|
17160
|
+
].join(" ").toLowerCase();
|
|
17161
|
+
return searchable.includes(query);
|
|
17162
|
+
}
|
|
17163
|
+
async function getPackage2(id) {
|
|
17164
|
+
const index = await fetchIndex2();
|
|
17165
|
+
const [kind, name] = id.includes(":") ? id.split(":") : [null, id];
|
|
17166
|
+
const kinds = kind ? [kind] : PACKAGE_KINDS4;
|
|
17167
|
+
for (const k of kinds) {
|
|
17168
|
+
const section = index.packages?.[getKindSection2(k)];
|
|
17169
|
+
if (!section) continue;
|
|
17170
|
+
const packages = [...section.official || [], ...section.community || []];
|
|
17171
|
+
for (const pkg of packages) {
|
|
17172
|
+
const kindPrefixPattern = new RegExp(`^(${PACKAGE_KINDS4.join("|")}):`);
|
|
17173
|
+
const pkgShortId = pkg.id?.replace(kindPrefixPattern, "") || "";
|
|
17174
|
+
if (pkgShortId === name || pkg.id === id) {
|
|
17175
|
+
return { ...pkg, kind: k };
|
|
17176
|
+
}
|
|
17177
|
+
}
|
|
17178
|
+
}
|
|
17179
|
+
return null;
|
|
17180
|
+
}
|
|
17181
|
+
async function getManifest2(pkg) {
|
|
17182
|
+
if (!pkg || !pkg.path) {
|
|
17183
|
+
return null;
|
|
17184
|
+
}
|
|
17185
|
+
const manifestPath = pkg.path;
|
|
17186
|
+
if (process.env.USE_LOCAL_REGISTRY === "true") {
|
|
17187
|
+
const localPaths = [
|
|
17188
|
+
import_path18.default.join(process.cwd(), "registry", manifestPath),
|
|
17189
|
+
import_path18.default.join(process.cwd(), "..", "registry", manifestPath),
|
|
17190
|
+
`/Users/hoff/dev/RUDI/registry/${manifestPath}`
|
|
17191
|
+
];
|
|
17192
|
+
for (const localPath of localPaths) {
|
|
17193
|
+
if (import_fs19.default.existsSync(localPath)) {
|
|
17194
|
+
try {
|
|
17195
|
+
const content = import_fs19.default.readFileSync(localPath, "utf-8");
|
|
17196
|
+
return JSON.parse(content);
|
|
17197
|
+
} catch (err) {
|
|
17198
|
+
}
|
|
17199
|
+
}
|
|
17200
|
+
}
|
|
17201
|
+
}
|
|
17202
|
+
try {
|
|
17203
|
+
const url = `${GITHUB_RAW_BASE2}/${manifestPath}`;
|
|
17204
|
+
const response = await fetch(url, {
|
|
17205
|
+
headers: {
|
|
17206
|
+
"Accept": "application/json",
|
|
17207
|
+
"User-Agent": "rudi-cli/2.0"
|
|
17208
|
+
}
|
|
17209
|
+
});
|
|
17210
|
+
if (!response.ok) {
|
|
17211
|
+
return null;
|
|
17212
|
+
}
|
|
17213
|
+
return await response.json();
|
|
17214
|
+
} catch (err) {
|
|
17215
|
+
return null;
|
|
17216
|
+
}
|
|
17217
|
+
}
|
|
17218
|
+
async function listPackages2(kind) {
|
|
17219
|
+
const index = await fetchIndex2();
|
|
17220
|
+
const section = index.packages?.[getKindSection2(kind)];
|
|
17221
|
+
if (!section) return [];
|
|
17222
|
+
return [...section.official || [], ...section.community || []];
|
|
17223
|
+
}
|
|
17224
|
+
function getPackageKinds() {
|
|
17225
|
+
return PACKAGE_KINDS4;
|
|
17226
|
+
}
|
|
17227
|
+
async function downloadPackage2(pkg, destPath, options = {}) {
|
|
17228
|
+
const { onProgress } = options;
|
|
17229
|
+
const registryPath = pkg.path;
|
|
17230
|
+
if (!import_fs19.default.existsSync(destPath)) {
|
|
17231
|
+
import_fs19.default.mkdirSync(destPath, { recursive: true });
|
|
17232
|
+
}
|
|
17233
|
+
onProgress?.({ phase: "downloading", package: pkg.name || pkg.id });
|
|
17234
|
+
if (pkg.kind === "stack" || registryPath.includes("/stacks/")) {
|
|
17235
|
+
await downloadStackFromGitHub2(registryPath, destPath, onProgress);
|
|
17236
|
+
return { success: true, path: destPath };
|
|
17237
|
+
}
|
|
17238
|
+
if (registryPath.endsWith(".md")) {
|
|
17239
|
+
const url = `${GITHUB_RAW_BASE2}/${registryPath}`;
|
|
17240
|
+
const response = await fetch(url, {
|
|
17241
|
+
headers: { "User-Agent": "rudi-cli/2.0" }
|
|
17242
|
+
});
|
|
17243
|
+
if (!response.ok) {
|
|
17244
|
+
throw new Error(`Failed to download ${registryPath}: HTTP ${response.status}`);
|
|
17245
|
+
}
|
|
17246
|
+
const content = await response.text();
|
|
17247
|
+
const destDir = import_path18.default.dirname(destPath);
|
|
17248
|
+
if (!import_fs19.default.existsSync(destDir)) {
|
|
17249
|
+
import_fs19.default.mkdirSync(destDir, { recursive: true });
|
|
17250
|
+
}
|
|
17251
|
+
import_fs19.default.writeFileSync(destPath, content);
|
|
17252
|
+
return { success: true, path: destPath };
|
|
17253
|
+
}
|
|
17254
|
+
throw new Error(`Unsupported package type: ${registryPath}`);
|
|
17255
|
+
}
|
|
17256
|
+
async function downloadStackFromGitHub2(registryPath, destPath, onProgress) {
|
|
17257
|
+
const baseUrl = `${GITHUB_RAW_BASE2}/${registryPath}`;
|
|
17258
|
+
const apiUrl = `https://api.github.com/repos/learn-rudi/registry/contents/${registryPath}`;
|
|
17259
|
+
const listResponse = await fetch(apiUrl, {
|
|
17260
|
+
headers: {
|
|
17261
|
+
"User-Agent": "rudi-cli/2.0",
|
|
17262
|
+
"Accept": "application/vnd.github.v3+json"
|
|
17263
|
+
}
|
|
17264
|
+
});
|
|
17265
|
+
if (!listResponse.ok) {
|
|
17266
|
+
throw new Error(`Stack not found: ${registryPath}`);
|
|
17267
|
+
}
|
|
17268
|
+
const contents = await listResponse.json();
|
|
17269
|
+
if (!Array.isArray(contents)) {
|
|
17270
|
+
throw new Error(`Invalid stack directory: ${registryPath}`);
|
|
17271
|
+
}
|
|
17272
|
+
const existingItems = /* @__PURE__ */ new Map();
|
|
17273
|
+
for (const item of contents) {
|
|
17274
|
+
existingItems.set(item.name, item);
|
|
17275
|
+
}
|
|
17276
|
+
const manifestItem = existingItems.get("manifest.json");
|
|
17277
|
+
if (!manifestItem) {
|
|
17278
|
+
throw new Error(`Stack missing manifest.json: ${registryPath}`);
|
|
17279
|
+
}
|
|
17280
|
+
const manifestResponse = await fetch(manifestItem.download_url, {
|
|
17281
|
+
headers: { "User-Agent": "rudi-cli/2.0" }
|
|
17282
|
+
});
|
|
17283
|
+
const manifest = await manifestResponse.json();
|
|
17284
|
+
import_fs19.default.writeFileSync(import_path18.default.join(destPath, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
17285
|
+
onProgress?.({ phase: "downloading", file: "manifest.json" });
|
|
17286
|
+
const pkgJsonItem = existingItems.get("package.json");
|
|
17287
|
+
if (pkgJsonItem) {
|
|
17288
|
+
const pkgJsonResponse = await fetch(pkgJsonItem.download_url, {
|
|
17289
|
+
headers: { "User-Agent": "rudi-cli/2.0" }
|
|
17290
|
+
});
|
|
17291
|
+
if (pkgJsonResponse.ok) {
|
|
17292
|
+
const pkgJson = await pkgJsonResponse.text();
|
|
17293
|
+
import_fs19.default.writeFileSync(import_path18.default.join(destPath, "package.json"), pkgJson);
|
|
17294
|
+
onProgress?.({ phase: "downloading", file: "package.json" });
|
|
17295
|
+
}
|
|
17296
|
+
}
|
|
17297
|
+
const envExampleItem = existingItems.get(".env.example");
|
|
17298
|
+
if (envExampleItem) {
|
|
17299
|
+
const envResponse = await fetch(envExampleItem.download_url, {
|
|
17300
|
+
headers: { "User-Agent": "rudi-cli/2.0" }
|
|
17301
|
+
});
|
|
17302
|
+
if (envResponse.ok) {
|
|
17303
|
+
const envContent = await envResponse.text();
|
|
17304
|
+
import_fs19.default.writeFileSync(import_path18.default.join(destPath, ".env.example"), envContent);
|
|
17305
|
+
}
|
|
17306
|
+
}
|
|
17307
|
+
const tsconfigItem = existingItems.get("tsconfig.json");
|
|
17308
|
+
if (tsconfigItem) {
|
|
17309
|
+
const tsconfigResponse = await fetch(tsconfigItem.download_url, {
|
|
17310
|
+
headers: { "User-Agent": "rudi-cli/2.0" }
|
|
17311
|
+
});
|
|
17312
|
+
if (tsconfigResponse.ok) {
|
|
17313
|
+
const tsconfig = await tsconfigResponse.text();
|
|
17314
|
+
import_fs19.default.writeFileSync(import_path18.default.join(destPath, "tsconfig.json"), tsconfig);
|
|
17315
|
+
}
|
|
17316
|
+
}
|
|
17317
|
+
const requirementsItem = existingItems.get("requirements.txt");
|
|
17318
|
+
if (requirementsItem) {
|
|
17319
|
+
const reqResponse = await fetch(requirementsItem.download_url, {
|
|
17320
|
+
headers: { "User-Agent": "rudi-cli/2.0" }
|
|
17321
|
+
});
|
|
17322
|
+
if (reqResponse.ok) {
|
|
17323
|
+
const requirements = await reqResponse.text();
|
|
17324
|
+
import_fs19.default.writeFileSync(import_path18.default.join(destPath, "requirements.txt"), requirements);
|
|
17325
|
+
}
|
|
17326
|
+
}
|
|
17327
|
+
const sourceDirs = ["src", "dist", "node", "python", "lib"];
|
|
17328
|
+
for (const dirName of sourceDirs) {
|
|
17329
|
+
const dirItem = existingItems.get(dirName);
|
|
17330
|
+
if (dirItem && dirItem.type === "dir") {
|
|
17331
|
+
onProgress?.({ phase: "downloading", directory: dirName });
|
|
17332
|
+
await downloadDirectoryFromGitHub2(
|
|
17333
|
+
`${baseUrl}/${dirName}`,
|
|
17334
|
+
import_path18.default.join(destPath, dirName),
|
|
17335
|
+
onProgress
|
|
17336
|
+
);
|
|
17337
|
+
}
|
|
17338
|
+
}
|
|
17339
|
+
}
|
|
17340
|
+
async function downloadDirectoryFromGitHub2(dirUrl, destDir, onProgress) {
|
|
17341
|
+
const apiUrl = dirUrl.replace("https://raw.githubusercontent.com/", "https://api.github.com/repos/").replace("/main/", "/contents/");
|
|
17342
|
+
try {
|
|
17343
|
+
const response = await fetch(apiUrl, {
|
|
17344
|
+
headers: {
|
|
17345
|
+
"User-Agent": "rudi-cli/2.0",
|
|
17346
|
+
"Accept": "application/vnd.github.v3+json"
|
|
17347
|
+
}
|
|
17348
|
+
});
|
|
17349
|
+
if (!response.ok) {
|
|
17350
|
+
return;
|
|
17351
|
+
}
|
|
17352
|
+
const contents = await response.json();
|
|
17353
|
+
if (!Array.isArray(contents)) {
|
|
17354
|
+
return;
|
|
17355
|
+
}
|
|
17356
|
+
if (!import_fs19.default.existsSync(destDir)) {
|
|
17357
|
+
import_fs19.default.mkdirSync(destDir, { recursive: true });
|
|
17358
|
+
}
|
|
17359
|
+
for (const item of contents) {
|
|
17360
|
+
if (item.type === "file") {
|
|
17361
|
+
const fileResponse = await fetch(item.download_url, {
|
|
17362
|
+
headers: { "User-Agent": "rudi-cli/2.0" }
|
|
17363
|
+
});
|
|
17364
|
+
if (fileResponse.ok) {
|
|
17365
|
+
const content = await fileResponse.text();
|
|
17366
|
+
import_fs19.default.writeFileSync(import_path18.default.join(destDir, item.name), content);
|
|
17367
|
+
onProgress?.({ phase: "downloading", file: item.name });
|
|
17368
|
+
}
|
|
17369
|
+
} else if (item.type === "dir") {
|
|
17370
|
+
await downloadDirectoryFromGitHub2(
|
|
17371
|
+
item.url.replace("https://api.github.com/repos/", "https://raw.githubusercontent.com/").replace("/contents/", "/main/"),
|
|
17372
|
+
import_path18.default.join(destDir, item.name),
|
|
17373
|
+
onProgress
|
|
17374
|
+
);
|
|
17375
|
+
}
|
|
17376
|
+
}
|
|
17377
|
+
} catch (error) {
|
|
17378
|
+
console.error(`Warning: Could not download ${dirUrl}: ${error.message}`);
|
|
17379
|
+
}
|
|
17380
|
+
}
|
|
17381
|
+
async function downloadRuntime2(runtime, version, destPath, options = {}) {
|
|
17382
|
+
const { onProgress } = options;
|
|
17383
|
+
const platformArch = getPlatformArch();
|
|
17384
|
+
const shortVersion = version.replace(/\.x$/, "").replace(/\.0$/, "");
|
|
17385
|
+
const filename = `${runtime}-${shortVersion}-${platformArch}.tar.gz`;
|
|
17386
|
+
const url = `${RUNTIMES_DOWNLOAD_BASE2}/${RUNTIMES_RELEASE_VERSION2}/${filename}`;
|
|
17387
|
+
onProgress?.({ phase: "downloading", runtime, version, url });
|
|
17388
|
+
const tempDir = import_path18.default.join(PATHS.cache, "downloads");
|
|
17389
|
+
if (!import_fs19.default.existsSync(tempDir)) {
|
|
17390
|
+
import_fs19.default.mkdirSync(tempDir, { recursive: true });
|
|
17391
|
+
}
|
|
17392
|
+
const tempFile = import_path18.default.join(tempDir, filename);
|
|
17393
|
+
try {
|
|
17394
|
+
const response = await fetch(url, {
|
|
17395
|
+
headers: {
|
|
17396
|
+
"User-Agent": "rudi-cli/2.0",
|
|
17397
|
+
"Accept": "application/octet-stream"
|
|
17398
|
+
}
|
|
17399
|
+
});
|
|
17400
|
+
if (!response.ok) {
|
|
17401
|
+
throw new Error(`Failed to download ${runtime}: HTTP ${response.status}`);
|
|
17402
|
+
}
|
|
17403
|
+
const buffer = await response.arrayBuffer();
|
|
17404
|
+
import_fs19.default.writeFileSync(tempFile, Buffer.from(buffer));
|
|
17405
|
+
onProgress?.({ phase: "extracting", runtime, version });
|
|
17406
|
+
if (import_fs19.default.existsSync(destPath)) {
|
|
17407
|
+
import_fs19.default.rmSync(destPath, { recursive: true });
|
|
17408
|
+
}
|
|
17409
|
+
import_fs19.default.mkdirSync(destPath, { recursive: true });
|
|
17410
|
+
const { execSync: execSync10 } = await import("child_process");
|
|
17411
|
+
execSync10(`tar -xzf "${tempFile}" -C "${destPath}" --strip-components=1`, {
|
|
17412
|
+
stdio: "pipe"
|
|
17413
|
+
});
|
|
17414
|
+
import_fs19.default.unlinkSync(tempFile);
|
|
17415
|
+
import_fs19.default.writeFileSync(
|
|
17416
|
+
import_path18.default.join(destPath, "runtime.json"),
|
|
17417
|
+
JSON.stringify({
|
|
17418
|
+
runtime,
|
|
17419
|
+
version,
|
|
17420
|
+
platformArch,
|
|
17421
|
+
downloadedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17422
|
+
source: url
|
|
17423
|
+
}, null, 2)
|
|
17424
|
+
);
|
|
17425
|
+
onProgress?.({ phase: "complete", runtime, version, path: destPath });
|
|
17426
|
+
return { success: true, path: destPath };
|
|
17427
|
+
} catch (error) {
|
|
17428
|
+
if (import_fs19.default.existsSync(tempFile)) {
|
|
17429
|
+
import_fs19.default.unlinkSync(tempFile);
|
|
17430
|
+
}
|
|
17431
|
+
throw new Error(`Failed to install ${runtime} ${version}: ${error.message}`);
|
|
17432
|
+
}
|
|
17433
|
+
}
|
|
17434
|
+
async function downloadTool2(toolName, destPath, options = {}) {
|
|
17435
|
+
const { onProgress } = options;
|
|
17436
|
+
const platformArch = getPlatformArch();
|
|
17437
|
+
const toolManifest = await loadToolManifest2(toolName);
|
|
17438
|
+
if (!toolManifest) {
|
|
17439
|
+
throw new Error(`Binary manifest not found for: ${toolName}`);
|
|
17440
|
+
}
|
|
17441
|
+
const tempDir = import_path18.default.join(PATHS.cache, "downloads");
|
|
17442
|
+
if (!import_fs19.default.existsSync(tempDir)) {
|
|
17443
|
+
import_fs19.default.mkdirSync(tempDir, { recursive: true });
|
|
17444
|
+
}
|
|
17445
|
+
if (import_fs19.default.existsSync(destPath)) {
|
|
17446
|
+
import_fs19.default.rmSync(destPath, { recursive: true });
|
|
17447
|
+
}
|
|
17448
|
+
import_fs19.default.mkdirSync(destPath, { recursive: true });
|
|
17449
|
+
const { execSync: execSync10 } = await import("child_process");
|
|
17450
|
+
const downloads = toolManifest.downloads?.[platformArch];
|
|
17451
|
+
if (downloads && Array.isArray(downloads)) {
|
|
17452
|
+
const downloadedUrls = /* @__PURE__ */ new Set();
|
|
17453
|
+
for (const download of downloads) {
|
|
17454
|
+
const { url, type, binary } = download;
|
|
17455
|
+
if (downloadedUrls.has(url)) {
|
|
17456
|
+
await extractBinaryFromPath2(destPath, binary, destPath);
|
|
17457
|
+
continue;
|
|
17458
|
+
}
|
|
17459
|
+
onProgress?.({ phase: "downloading", tool: toolName, binary: import_path18.default.basename(binary), url });
|
|
17460
|
+
const urlFilename = import_path18.default.basename(new URL(url).pathname);
|
|
17461
|
+
const tempFile = import_path18.default.join(tempDir, urlFilename);
|
|
17462
|
+
try {
|
|
17463
|
+
const response = await fetch(url, {
|
|
17464
|
+
headers: {
|
|
17465
|
+
"User-Agent": "rudi-cli/2.0",
|
|
17466
|
+
"Accept": "application/octet-stream"
|
|
17467
|
+
}
|
|
17468
|
+
});
|
|
17469
|
+
if (!response.ok) {
|
|
17470
|
+
throw new Error(`Failed to download ${binary}: HTTP ${response.status}`);
|
|
17471
|
+
}
|
|
17472
|
+
const buffer = await response.arrayBuffer();
|
|
17473
|
+
import_fs19.default.writeFileSync(tempFile, Buffer.from(buffer));
|
|
17474
|
+
downloadedUrls.add(url);
|
|
17475
|
+
onProgress?.({ phase: "extracting", tool: toolName, binary: import_path18.default.basename(binary) });
|
|
17476
|
+
const archiveType = type || guessArchiveType2(urlFilename);
|
|
17477
|
+
if (archiveType === "zip") {
|
|
17478
|
+
execSync10(`unzip -o "${tempFile}" -d "${destPath}"`, { stdio: "pipe" });
|
|
17479
|
+
} else if (archiveType === "tar.xz") {
|
|
17480
|
+
execSync10(`tar -xJf "${tempFile}" -C "${destPath}"`, { stdio: "pipe" });
|
|
17481
|
+
} else if (archiveType === "tar.gz" || archiveType === "tgz") {
|
|
17482
|
+
execSync10(`tar -xzf "${tempFile}" -C "${destPath}"`, { stdio: "pipe" });
|
|
17483
|
+
} else {
|
|
17484
|
+
throw new Error(`Unsupported archive type: ${archiveType}`);
|
|
17485
|
+
}
|
|
17486
|
+
await extractBinaryFromPath2(destPath, binary, destPath);
|
|
17487
|
+
import_fs19.default.unlinkSync(tempFile);
|
|
17488
|
+
} catch (error) {
|
|
17489
|
+
if (import_fs19.default.existsSync(tempFile)) {
|
|
17490
|
+
import_fs19.default.unlinkSync(tempFile);
|
|
17491
|
+
}
|
|
17492
|
+
throw error;
|
|
17493
|
+
}
|
|
17494
|
+
}
|
|
17495
|
+
const binaries = toolManifest.binaries || [toolName];
|
|
17496
|
+
for (const bin of binaries) {
|
|
17497
|
+
const binPath = import_path18.default.join(destPath, bin);
|
|
17498
|
+
if (import_fs19.default.existsSync(binPath)) {
|
|
17499
|
+
import_fs19.default.chmodSync(binPath, 493);
|
|
17500
|
+
}
|
|
17501
|
+
}
|
|
17502
|
+
} else {
|
|
17503
|
+
const upstreamUrl = toolManifest.upstream?.[platformArch];
|
|
17504
|
+
if (!upstreamUrl) {
|
|
17505
|
+
throw new Error(`No upstream URL for ${toolName} on ${platformArch}`);
|
|
17506
|
+
}
|
|
17507
|
+
const extractConfig = toolManifest.extract?.[platformArch] || toolManifest.extract?.default;
|
|
17508
|
+
if (!extractConfig) {
|
|
17509
|
+
throw new Error(`No extract config for ${toolName} on ${platformArch}`);
|
|
17510
|
+
}
|
|
17511
|
+
onProgress?.({ phase: "downloading", tool: toolName, url: upstreamUrl });
|
|
17512
|
+
const urlFilename = import_path18.default.basename(new URL(upstreamUrl).pathname);
|
|
17513
|
+
const tempFile = import_path18.default.join(tempDir, urlFilename);
|
|
17514
|
+
try {
|
|
17515
|
+
const response = await fetch(upstreamUrl, {
|
|
17516
|
+
headers: {
|
|
17517
|
+
"User-Agent": "rudi-cli/2.0",
|
|
17518
|
+
"Accept": "application/octet-stream"
|
|
17519
|
+
}
|
|
17520
|
+
});
|
|
17521
|
+
if (!response.ok) {
|
|
17522
|
+
throw new Error(`Failed to download ${toolName}: HTTP ${response.status}`);
|
|
17523
|
+
}
|
|
17524
|
+
const buffer = await response.arrayBuffer();
|
|
17525
|
+
import_fs19.default.writeFileSync(tempFile, Buffer.from(buffer));
|
|
17526
|
+
onProgress?.({ phase: "extracting", tool: toolName });
|
|
17527
|
+
const archiveType = extractConfig.type || guessArchiveType2(urlFilename);
|
|
17528
|
+
const stripComponents = extractConfig.strip || 0;
|
|
17529
|
+
const stripFlag = stripComponents > 0 ? ` --strip-components=${stripComponents}` : "";
|
|
17530
|
+
if (archiveType === "zip") {
|
|
17531
|
+
execSync10(`unzip -o "${tempFile}" -d "${destPath}"`, { stdio: "pipe" });
|
|
17532
|
+
} else if (archiveType === "tar.xz") {
|
|
17533
|
+
execSync10(`tar -xJf "${tempFile}" -C "${destPath}"${stripFlag}`, { stdio: "pipe" });
|
|
17534
|
+
} else if (archiveType === "tar.gz" || archiveType === "tgz") {
|
|
17535
|
+
execSync10(`tar -xzf "${tempFile}" -C "${destPath}"${stripFlag}`, { stdio: "pipe" });
|
|
17536
|
+
} else {
|
|
17537
|
+
throw new Error(`Unsupported archive type: ${archiveType}`);
|
|
17538
|
+
}
|
|
17539
|
+
await extractBinaryFromPath2(destPath, extractConfig.binary || toolName, destPath);
|
|
17540
|
+
const binaries = [toolName, ...toolManifest.additionalBinaries || []];
|
|
17541
|
+
for (const bin of binaries) {
|
|
17542
|
+
const binPath = import_path18.default.join(destPath, bin);
|
|
17543
|
+
if (import_fs19.default.existsSync(binPath)) {
|
|
17544
|
+
import_fs19.default.chmodSync(binPath, 493);
|
|
17545
|
+
}
|
|
17546
|
+
}
|
|
17547
|
+
import_fs19.default.unlinkSync(tempFile);
|
|
17548
|
+
} catch (error) {
|
|
17549
|
+
if (import_fs19.default.existsSync(tempFile)) {
|
|
17550
|
+
import_fs19.default.unlinkSync(tempFile);
|
|
17551
|
+
}
|
|
17552
|
+
throw new Error(`Failed to install ${toolName}: ${error.message}`);
|
|
17553
|
+
}
|
|
17554
|
+
}
|
|
17555
|
+
import_fs19.default.writeFileSync(
|
|
17556
|
+
import_path18.default.join(destPath, "manifest.json"),
|
|
17557
|
+
JSON.stringify({
|
|
17558
|
+
id: `binary:${toolName}`,
|
|
17559
|
+
kind: "binary",
|
|
17560
|
+
name: toolManifest.name || toolName,
|
|
17561
|
+
version: toolManifest.version,
|
|
17562
|
+
binaries: toolManifest.bins || toolManifest.binaries || [toolName],
|
|
17563
|
+
platformArch,
|
|
17564
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
17565
|
+
}, null, 2)
|
|
17566
|
+
);
|
|
17567
|
+
onProgress?.({ phase: "complete", tool: toolName, path: destPath });
|
|
17568
|
+
return { success: true, path: destPath };
|
|
17569
|
+
}
|
|
17570
|
+
async function extractBinaryFromPath2(extractedPath, binaryPattern, destPath) {
|
|
17571
|
+
const directPath = import_path18.default.join(destPath, import_path18.default.basename(binaryPattern));
|
|
17572
|
+
if (!binaryPattern.includes("/") && !binaryPattern.includes("*")) {
|
|
17573
|
+
if (import_fs19.default.existsSync(directPath)) {
|
|
17574
|
+
return;
|
|
17575
|
+
}
|
|
17576
|
+
}
|
|
17577
|
+
if (binaryPattern.includes("*") || binaryPattern.includes("/")) {
|
|
17578
|
+
const parts = binaryPattern.split("/");
|
|
17579
|
+
let currentPath = extractedPath;
|
|
17580
|
+
for (let i = 0; i < parts.length; i++) {
|
|
17581
|
+
const part = parts[i];
|
|
17582
|
+
if (part.includes("*")) {
|
|
17583
|
+
if (!import_fs19.default.existsSync(currentPath)) break;
|
|
17584
|
+
const entries = import_fs19.default.readdirSync(currentPath);
|
|
17585
|
+
const pattern = new RegExp("^" + part.replace(/\*/g, ".*") + "$");
|
|
17586
|
+
const match = entries.find((e) => pattern.test(e));
|
|
17587
|
+
if (match) {
|
|
17588
|
+
currentPath = import_path18.default.join(currentPath, match);
|
|
17589
|
+
} else {
|
|
17590
|
+
break;
|
|
17591
|
+
}
|
|
17592
|
+
} else {
|
|
17593
|
+
currentPath = import_path18.default.join(currentPath, part);
|
|
17594
|
+
}
|
|
17595
|
+
}
|
|
17596
|
+
if (import_fs19.default.existsSync(currentPath) && currentPath !== destPath) {
|
|
17597
|
+
const finalPath = import_path18.default.join(destPath, import_path18.default.basename(currentPath));
|
|
17598
|
+
if (currentPath !== finalPath && !import_fs19.default.existsSync(finalPath)) {
|
|
17599
|
+
import_fs19.default.renameSync(currentPath, finalPath);
|
|
17600
|
+
}
|
|
17601
|
+
}
|
|
17602
|
+
}
|
|
17603
|
+
}
|
|
17604
|
+
async function loadToolManifest2(toolName) {
|
|
17605
|
+
for (const basePath of getLocalRegistryPaths2()) {
|
|
17606
|
+
const registryDir = import_path18.default.dirname(basePath);
|
|
17607
|
+
const manifestPath = import_path18.default.join(registryDir, "catalog", "binaries", `${toolName}.json`);
|
|
17608
|
+
if (import_fs19.default.existsSync(manifestPath)) {
|
|
17609
|
+
try {
|
|
17610
|
+
return JSON.parse(import_fs19.default.readFileSync(manifestPath, "utf-8"));
|
|
17611
|
+
} catch {
|
|
17612
|
+
continue;
|
|
17613
|
+
}
|
|
17614
|
+
}
|
|
17615
|
+
}
|
|
17616
|
+
try {
|
|
17617
|
+
const url = `https://raw.githubusercontent.com/learn-rudi/registry/main/catalog/binaries/${toolName}.json`;
|
|
17618
|
+
const response = await fetch(url, {
|
|
17619
|
+
headers: {
|
|
17620
|
+
"User-Agent": "rudi-cli/2.0",
|
|
17621
|
+
"Accept": "application/json"
|
|
17622
|
+
}
|
|
17623
|
+
});
|
|
17624
|
+
if (response.ok) {
|
|
17625
|
+
return await response.json();
|
|
17626
|
+
}
|
|
17627
|
+
} catch {
|
|
17628
|
+
}
|
|
17629
|
+
return null;
|
|
17630
|
+
}
|
|
17631
|
+
function guessArchiveType2(filename) {
|
|
17632
|
+
if (filename.endsWith(".tar.gz") || filename.endsWith(".tgz")) return "tar.gz";
|
|
17633
|
+
if (filename.endsWith(".tar.xz")) return "tar.xz";
|
|
17634
|
+
if (filename.endsWith(".zip")) return "zip";
|
|
17635
|
+
return "tar.gz";
|
|
17636
|
+
}
|
|
17637
|
+
async function verifyHash(filePath, expectedHash) {
|
|
17638
|
+
return new Promise((resolve, reject) => {
|
|
17639
|
+
const hash = import_crypto2.default.createHash("sha256");
|
|
17640
|
+
const stream = import_fs19.default.createReadStream(filePath);
|
|
17641
|
+
stream.on("data", (data) => hash.update(data));
|
|
17642
|
+
stream.on("end", () => {
|
|
17643
|
+
const actualHash = hash.digest("hex");
|
|
17644
|
+
resolve(actualHash === expectedHash);
|
|
17645
|
+
});
|
|
17646
|
+
stream.on("error", reject);
|
|
17647
|
+
});
|
|
17648
|
+
}
|
|
17649
|
+
async function computeHash(filePath) {
|
|
17650
|
+
return new Promise((resolve, reject) => {
|
|
17651
|
+
const hash = import_crypto2.default.createHash("sha256");
|
|
17652
|
+
const stream = import_fs19.default.createReadStream(filePath);
|
|
17653
|
+
stream.on("data", (data) => hash.update(data));
|
|
17654
|
+
stream.on("end", () => resolve(hash.digest("hex")));
|
|
17655
|
+
stream.on("error", reject);
|
|
17656
|
+
});
|
|
17657
|
+
}
|
|
17658
|
+
var import_fs19, import_path18, import_crypto2, DEFAULT_REGISTRY_URL2, RUNTIMES_DOWNLOAD_BASE2, CACHE_TTL2, PACKAGE_KINDS4, KIND_PLURALS2, GITHUB_RAW_BASE2, RUNTIMES_RELEASE_VERSION2;
|
|
17659
|
+
var init_src4 = __esm({
|
|
17660
|
+
"packages/registry-client/src/index.js"() {
|
|
17661
|
+
import_fs19 = __toESM(require("fs"), 1);
|
|
17662
|
+
import_path18 = __toESM(require("path"), 1);
|
|
17663
|
+
import_crypto2 = __toESM(require("crypto"), 1);
|
|
17664
|
+
init_src();
|
|
17665
|
+
DEFAULT_REGISTRY_URL2 = "https://raw.githubusercontent.com/learn-rudi/registry/main/index.json";
|
|
17666
|
+
RUNTIMES_DOWNLOAD_BASE2 = "https://github.com/learn-rudi/registry/releases/download";
|
|
17667
|
+
CACHE_TTL2 = 24 * 60 * 60 * 1e3;
|
|
17668
|
+
PACKAGE_KINDS4 = ["stack", "prompt", "runtime", "binary", "agent"];
|
|
17669
|
+
KIND_PLURALS2 = {
|
|
17670
|
+
binary: "binaries"
|
|
17671
|
+
};
|
|
17672
|
+
GITHUB_RAW_BASE2 = "https://raw.githubusercontent.com/learn-rudi/registry/main";
|
|
17673
|
+
RUNTIMES_RELEASE_VERSION2 = "v1.0.0";
|
|
17674
|
+
}
|
|
17675
|
+
});
|
|
17676
|
+
|
|
17677
|
+
// packages/utils/src/args.js
|
|
17678
|
+
function parseArgs(argv) {
|
|
17679
|
+
const flags = {};
|
|
17680
|
+
const args = [];
|
|
17681
|
+
let command = null;
|
|
17682
|
+
for (let i = 0; i < argv.length; i++) {
|
|
17683
|
+
const arg = argv[i];
|
|
17684
|
+
if (arg.startsWith("--")) {
|
|
17685
|
+
const eqIndex = arg.indexOf("=");
|
|
17686
|
+
if (eqIndex !== -1) {
|
|
17687
|
+
const key = arg.slice(2, eqIndex);
|
|
17688
|
+
const value = arg.slice(eqIndex + 1);
|
|
17689
|
+
flags[key] = value;
|
|
17690
|
+
} else {
|
|
17691
|
+
const key = arg.slice(2);
|
|
17692
|
+
const nextArg = argv[i + 1];
|
|
17693
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
17694
|
+
flags[key] = nextArg;
|
|
17695
|
+
i++;
|
|
17696
|
+
} else {
|
|
17697
|
+
flags[key] = true;
|
|
17698
|
+
}
|
|
17699
|
+
}
|
|
17700
|
+
} else if (arg.startsWith("-") && arg.length > 1) {
|
|
17701
|
+
const chars = arg.slice(1);
|
|
17702
|
+
for (const char of chars) {
|
|
17703
|
+
flags[char] = true;
|
|
17704
|
+
}
|
|
17705
|
+
} else if (!command) {
|
|
17706
|
+
command = arg;
|
|
17707
|
+
} else {
|
|
17708
|
+
args.push(arg);
|
|
17709
|
+
}
|
|
17710
|
+
}
|
|
17711
|
+
return { command, args, flags };
|
|
17712
|
+
}
|
|
17713
|
+
function formatBytes(bytes) {
|
|
17714
|
+
if (bytes === 0) return "0 B";
|
|
17715
|
+
const k = 1024;
|
|
17716
|
+
const sizes = ["B", "KB", "MB", "GB"];
|
|
17717
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
17718
|
+
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`;
|
|
17719
|
+
}
|
|
17720
|
+
function formatDuration(ms) {
|
|
17721
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
17722
|
+
if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
|
|
17723
|
+
const mins = Math.floor(ms / 6e4);
|
|
17724
|
+
const secs = Math.floor(ms % 6e4 / 1e3);
|
|
17725
|
+
return `${mins}m ${secs}s`;
|
|
17726
|
+
}
|
|
17727
|
+
|
|
17728
|
+
// packages/utils/src/help.js
|
|
17729
|
+
function printVersion(version) {
|
|
17730
|
+
console.log(`rudi v${version}`);
|
|
17731
|
+
}
|
|
17732
|
+
function printHelp(topic) {
|
|
17733
|
+
if (topic) {
|
|
17734
|
+
printCommandHelp(topic);
|
|
17735
|
+
return;
|
|
16894
17736
|
}
|
|
16895
17737
|
console.log(`
|
|
16896
17738
|
rudi - RUDI CLI
|
|
@@ -17337,7 +18179,7 @@ var path13 = __toESM(require("path"), 1);
|
|
|
17337
18179
|
var import_child_process4 = require("child_process");
|
|
17338
18180
|
init_src3();
|
|
17339
18181
|
|
|
17340
|
-
//
|
|
18182
|
+
// packages/secrets/src/index.js
|
|
17341
18183
|
var fs10 = __toESM(require("fs"), 1);
|
|
17342
18184
|
var path10 = __toESM(require("path"), 1);
|
|
17343
18185
|
init_src();
|
|
@@ -17418,7 +18260,7 @@ function getStorageInfo() {
|
|
|
17418
18260
|
};
|
|
17419
18261
|
}
|
|
17420
18262
|
|
|
17421
|
-
//
|
|
18263
|
+
// packages/mcp/src/agents.js
|
|
17422
18264
|
var import_fs8 = __toESM(require("fs"), 1);
|
|
17423
18265
|
var import_path8 = __toESM(require("path"), 1);
|
|
17424
18266
|
var import_os2 = __toESM(require("os"), 1);
|
|
@@ -17593,7 +18435,7 @@ function getMcpServerSummary() {
|
|
|
17593
18435
|
return summary;
|
|
17594
18436
|
}
|
|
17595
18437
|
|
|
17596
|
-
//
|
|
18438
|
+
// packages/mcp/src/registry.js
|
|
17597
18439
|
var fs12 = __toESM(require("fs/promises"), 1);
|
|
17598
18440
|
var path12 = __toESM(require("path"), 1);
|
|
17599
18441
|
var os3 = __toESM(require("os"), 1);
|
|
@@ -17982,6 +18824,7 @@ async function cmdInstall(args, flags) {
|
|
|
17982
18824
|
process.exit(1);
|
|
17983
18825
|
}
|
|
17984
18826
|
const force = flags.force || false;
|
|
18827
|
+
const allowScripts = flags["allow-scripts"] || flags.allowScripts || false;
|
|
17985
18828
|
console.log(`Resolving ${pkgId}...`);
|
|
17986
18829
|
try {
|
|
17987
18830
|
const resolved = await resolvePackage(pkgId);
|
|
@@ -18043,6 +18886,7 @@ Or use --force to install anyway.`);
|
|
|
18043
18886
|
Installing...`);
|
|
18044
18887
|
const result = await installPackage(pkgId, {
|
|
18045
18888
|
force,
|
|
18889
|
+
allowScripts,
|
|
18046
18890
|
onProgress: (progress) => {
|
|
18047
18891
|
if (progress.phase === "installing") {
|
|
18048
18892
|
console.log(` Installing ${progress.package}...`);
|
|
@@ -18179,23 +19023,66 @@ Next steps:`);
|
|
|
18179
19023
|
// src/commands/run.js
|
|
18180
19024
|
init_src3();
|
|
18181
19025
|
|
|
18182
|
-
//
|
|
19026
|
+
// packages/runner/src/spawn.js
|
|
18183
19027
|
var import_child_process5 = require("child_process");
|
|
18184
19028
|
var import_path10 = __toESM(require("path"), 1);
|
|
18185
19029
|
var import_fs10 = __toESM(require("fs"), 1);
|
|
18186
|
-
init_src3();
|
|
18187
19030
|
|
|
18188
|
-
// node_modules/.pnpm/@learnrudi+
|
|
19031
|
+
// node_modules/.pnpm/@learnrudi+core@1.0.2/node_modules/@learnrudi/core/src/index.js
|
|
19032
|
+
init_src();
|
|
19033
|
+
init_src2();
|
|
19034
|
+
|
|
19035
|
+
// node_modules/.pnpm/@learnrudi+core@1.0.2/node_modules/@learnrudi/core/src/resolver.js
|
|
19036
|
+
init_src2();
|
|
19037
|
+
init_src();
|
|
19038
|
+
|
|
19039
|
+
// node_modules/.pnpm/@learnrudi+core@1.0.2/node_modules/@learnrudi/core/src/installer.js
|
|
19040
|
+
init_src();
|
|
19041
|
+
init_src2();
|
|
19042
|
+
|
|
19043
|
+
// node_modules/.pnpm/@learnrudi+core@1.0.2/node_modules/@learnrudi/core/src/lockfile.js
|
|
19044
|
+
var import_yaml2 = __toESM(require_dist(), 1);
|
|
19045
|
+
init_src();
|
|
19046
|
+
|
|
19047
|
+
// node_modules/.pnpm/@learnrudi+core@1.0.2/node_modules/@learnrudi/core/src/installer.js
|
|
19048
|
+
init_shims2();
|
|
19049
|
+
|
|
19050
|
+
// node_modules/.pnpm/@learnrudi+core@1.0.2/node_modules/@learnrudi/core/src/deps.js
|
|
19051
|
+
init_src();
|
|
19052
|
+
init_src2();
|
|
19053
|
+
|
|
19054
|
+
// node_modules/.pnpm/@learnrudi+core@1.0.2/node_modules/@learnrudi/core/src/rudi-config.js
|
|
19055
|
+
var path14 = __toESM(require("path"), 1);
|
|
19056
|
+
init_src();
|
|
19057
|
+
var RUDI_JSON_PATH2 = path14.join(RUDI_HOME, "rudi.json");
|
|
19058
|
+
var RUDI_JSON_TMP2 = path14.join(RUDI_HOME, "rudi.json.tmp");
|
|
19059
|
+
var RUDI_JSON_LOCK2 = path14.join(RUDI_HOME, "rudi.json.lock");
|
|
19060
|
+
|
|
19061
|
+
// node_modules/.pnpm/@learnrudi+core@1.0.2/node_modules/@learnrudi/core/src/tool-index.js
|
|
19062
|
+
var path15 = __toESM(require("path"), 1);
|
|
19063
|
+
init_src();
|
|
19064
|
+
var TOOL_INDEX_PATH2 = path15.join(RUDI_HOME, "cache", "tool-index.json");
|
|
19065
|
+
var TOOL_INDEX_TMP2 = path15.join(RUDI_HOME, "cache", "tool-index.json.tmp");
|
|
19066
|
+
var SECRETS_PATH2 = path15.join(RUDI_HOME, "secrets.json");
|
|
19067
|
+
|
|
19068
|
+
// node_modules/.pnpm/@learnrudi+core@1.0.2/node_modules/@learnrudi/core/src/index.js
|
|
19069
|
+
init_shims2();
|
|
19070
|
+
|
|
19071
|
+
// node_modules/.pnpm/@learnrudi+core@1.0.2/node_modules/@learnrudi/core/src/system-registry.js
|
|
19072
|
+
init_src();
|
|
19073
|
+
init_shims2();
|
|
19074
|
+
|
|
19075
|
+
// packages/runner/src/secrets.js
|
|
18189
19076
|
var import_fs9 = __toESM(require("fs"), 1);
|
|
18190
19077
|
var import_path9 = __toESM(require("path"), 1);
|
|
18191
19078
|
var import_os3 = __toESM(require("os"), 1);
|
|
18192
|
-
var
|
|
19079
|
+
var SECRETS_PATH3 = import_path9.default.join(import_os3.default.homedir(), ".rudi", "secrets.json");
|
|
18193
19080
|
function loadSecrets3() {
|
|
18194
|
-
if (!import_fs9.default.existsSync(
|
|
19081
|
+
if (!import_fs9.default.existsSync(SECRETS_PATH3)) {
|
|
18195
19082
|
return {};
|
|
18196
19083
|
}
|
|
18197
19084
|
try {
|
|
18198
|
-
const content = import_fs9.default.readFileSync(
|
|
19085
|
+
const content = import_fs9.default.readFileSync(SECRETS_PATH3, "utf-8");
|
|
18199
19086
|
return JSON.parse(content);
|
|
18200
19087
|
} catch {
|
|
18201
19088
|
return {};
|
|
@@ -18246,17 +19133,17 @@ function redactSecrets(text, secrets) {
|
|
|
18246
19133
|
return result;
|
|
18247
19134
|
}
|
|
18248
19135
|
|
|
18249
|
-
//
|
|
19136
|
+
// packages/runner/src/spawn.js
|
|
18250
19137
|
async function runStack(id, options = {}) {
|
|
18251
19138
|
const { inputs = {}, cwd, env = {}, onStdout, onStderr, onExit, signal } = options;
|
|
18252
19139
|
const startTime = Date.now();
|
|
18253
19140
|
const packagePath = getPackagePath(id);
|
|
18254
19141
|
const manifestPath = import_path10.default.join(packagePath, "manifest.json");
|
|
18255
|
-
const { default:
|
|
18256
|
-
if (!
|
|
19142
|
+
const { default: fs35 } = await import("fs");
|
|
19143
|
+
if (!fs35.existsSync(manifestPath)) {
|
|
18257
19144
|
throw new Error(`Stack manifest not found: ${id}`);
|
|
18258
19145
|
}
|
|
18259
|
-
const manifest = JSON.parse(
|
|
19146
|
+
const manifest = JSON.parse(fs35.readFileSync(manifestPath, "utf-8"));
|
|
18260
19147
|
const { command, args } = resolveCommandFromManifest(manifest, packagePath);
|
|
18261
19148
|
const secrets = await getSecrets(manifest.requires?.secrets || []);
|
|
18262
19149
|
const runEnv = {
|
|
@@ -18362,8 +19249,8 @@ function resolveRelativePath(value, basePath) {
|
|
|
18362
19249
|
return value;
|
|
18363
19250
|
}
|
|
18364
19251
|
|
|
18365
|
-
//
|
|
18366
|
-
var
|
|
19252
|
+
// packages/manifest/src/stack.js
|
|
19253
|
+
var import_yaml3 = __toESM(require_dist(), 1);
|
|
18367
19254
|
var import_fs11 = __toESM(require("fs"), 1);
|
|
18368
19255
|
var import_path11 = __toESM(require("path"), 1);
|
|
18369
19256
|
function parseStackManifest(filePath) {
|
|
@@ -18371,7 +19258,7 @@ function parseStackManifest(filePath) {
|
|
|
18371
19258
|
return parseStackYaml(content, filePath);
|
|
18372
19259
|
}
|
|
18373
19260
|
function parseStackYaml(content, source = "stack.yaml") {
|
|
18374
|
-
const raw = (0,
|
|
19261
|
+
const raw = (0, import_yaml3.parse)(content);
|
|
18375
19262
|
if (!raw || typeof raw !== "object") {
|
|
18376
19263
|
throw new Error(`Invalid stack manifest in ${source}: expected object`);
|
|
18377
19264
|
}
|
|
@@ -18493,13 +19380,13 @@ function findStackManifest(dir) {
|
|
|
18493
19380
|
return null;
|
|
18494
19381
|
}
|
|
18495
19382
|
|
|
18496
|
-
//
|
|
18497
|
-
var import_yaml3 = __toESM(require_dist(), 1);
|
|
18498
|
-
|
|
18499
|
-
// node_modules/.pnpm/@learnrudi+manifest@1.0.0/node_modules/@learnrudi/manifest/src/runtime.js
|
|
19383
|
+
// packages/manifest/src/prompt.js
|
|
18500
19384
|
var import_yaml4 = __toESM(require_dist(), 1);
|
|
18501
19385
|
|
|
18502
|
-
//
|
|
19386
|
+
// packages/manifest/src/runtime.js
|
|
19387
|
+
var import_yaml5 = __toESM(require_dist(), 1);
|
|
19388
|
+
|
|
19389
|
+
// packages/manifest/src/validate.js
|
|
18503
19390
|
var import_ajv = __toESM(require_ajv(), 1);
|
|
18504
19391
|
var import_ajv_formats = __toESM(require_dist2(), 1);
|
|
18505
19392
|
var ajv = new import_ajv.default({ allErrors: true, strict: false });
|
|
@@ -19235,13 +20122,13 @@ function promptSecret(prompt) {
|
|
|
19235
20122
|
var import_fs14 = require("fs");
|
|
19236
20123
|
var import_path14 = require("path");
|
|
19237
20124
|
|
|
19238
|
-
//
|
|
20125
|
+
// packages/db/src/index.js
|
|
19239
20126
|
var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
|
|
19240
20127
|
var import_path13 = __toESM(require("path"), 1);
|
|
19241
20128
|
var import_fs13 = __toESM(require("fs"), 1);
|
|
19242
20129
|
init_src();
|
|
19243
20130
|
|
|
19244
|
-
//
|
|
20131
|
+
// packages/db/src/schema.js
|
|
19245
20132
|
var SCHEMA_VERSION = 5;
|
|
19246
20133
|
var SCHEMA_SQL = `
|
|
19247
20134
|
-- Schema version tracking
|
|
@@ -19801,7 +20688,7 @@ function seedModelPricing(db2) {
|
|
|
19801
20688
|
console.log(` Seeded ${pricingData.length} model pricing entries`);
|
|
19802
20689
|
}
|
|
19803
20690
|
|
|
19804
|
-
//
|
|
20691
|
+
// packages/db/src/search.js
|
|
19805
20692
|
function search(query, options = {}) {
|
|
19806
20693
|
const { limit = 20, provider, sessionId, offset = 0 } = options;
|
|
19807
20694
|
const db2 = getDb();
|
|
@@ -19888,7 +20775,7 @@ function searchFallback(query, options = {}) {
|
|
|
19888
20775
|
return db2.prepare(sql).all(...params);
|
|
19889
20776
|
}
|
|
19890
20777
|
|
|
19891
|
-
//
|
|
20778
|
+
// packages/db/src/stats.js
|
|
19892
20779
|
function getStats() {
|
|
19893
20780
|
const db2 = getDb();
|
|
19894
20781
|
const totals = db2.prepare(`
|
|
@@ -19995,7 +20882,7 @@ function getToolsUsage(db2) {
|
|
|
19995
20882
|
return Object.entries(toolCounts).sort((a, b) => b[1] - a[1]).slice(0, 20).map(([name, count]) => ({ name, count }));
|
|
19996
20883
|
}
|
|
19997
20884
|
|
|
19998
|
-
//
|
|
20885
|
+
// packages/db/src/logs.js
|
|
19999
20886
|
function queryLogs(options = {}) {
|
|
20000
20887
|
const db2 = getDb();
|
|
20001
20888
|
const {
|
|
@@ -20139,11 +21026,11 @@ function getBeforeCrashLogs() {
|
|
|
20139
21026
|
return getRecentLogs(3e4);
|
|
20140
21027
|
}
|
|
20141
21028
|
|
|
20142
|
-
//
|
|
21029
|
+
// packages/db/src/import.js
|
|
20143
21030
|
init_src();
|
|
20144
21031
|
var RUDI_HOME2 = PATHS.home;
|
|
20145
21032
|
|
|
20146
|
-
//
|
|
21033
|
+
// packages/db/src/index.js
|
|
20147
21034
|
var DB_PATH = PATHS.dbFile;
|
|
20148
21035
|
var db = null;
|
|
20149
21036
|
function getDb(options = {}) {
|
|
@@ -20569,7 +21456,7 @@ function dbTables(flags) {
|
|
|
20569
21456
|
var import_fs15 = require("fs");
|
|
20570
21457
|
var import_path15 = require("path");
|
|
20571
21458
|
var import_os4 = require("os");
|
|
20572
|
-
var
|
|
21459
|
+
var import_crypto = require("crypto");
|
|
20573
21460
|
var PROVIDERS = {
|
|
20574
21461
|
claude: {
|
|
20575
21462
|
name: "Claude Code",
|
|
@@ -20728,7 +21615,7 @@ async function importSessions(args, flags) {
|
|
|
20728
21615
|
try {
|
|
20729
21616
|
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
20730
21617
|
insertStmt.run(
|
|
20731
|
-
(0,
|
|
21618
|
+
(0, import_crypto.randomUUID)(),
|
|
20732
21619
|
providerKey,
|
|
20733
21620
|
sessionId,
|
|
20734
21621
|
nowIso,
|
|
@@ -21147,13 +22034,115 @@ async function cmdHome(args, flags) {
|
|
|
21147
22034
|
}
|
|
21148
22035
|
|
|
21149
22036
|
// src/commands/init.js
|
|
21150
|
-
var
|
|
21151
|
-
var
|
|
22037
|
+
var import_fs20 = __toESM(require("fs"), 1);
|
|
22038
|
+
var import_path19 = __toESM(require("path"), 1);
|
|
21152
22039
|
var import_promises = require("stream/promises");
|
|
21153
|
-
var
|
|
22040
|
+
var import_fs21 = require("fs");
|
|
21154
22041
|
var import_child_process6 = require("child_process");
|
|
21155
|
-
|
|
21156
|
-
|
|
22042
|
+
|
|
22043
|
+
// packages/env/src/index.js
|
|
22044
|
+
var import_path17 = __toESM(require("path"), 1);
|
|
22045
|
+
var import_os5 = __toESM(require("os"), 1);
|
|
22046
|
+
var import_fs18 = __toESM(require("fs"), 1);
|
|
22047
|
+
var RUDI_HOME3 = import_path17.default.join(import_os5.default.homedir(), ".rudi");
|
|
22048
|
+
var PATHS2 = {
|
|
22049
|
+
// Root
|
|
22050
|
+
home: RUDI_HOME3,
|
|
22051
|
+
// Installed packages - shared with Studio for unified discovery
|
|
22052
|
+
packages: import_path17.default.join(RUDI_HOME3, "packages"),
|
|
22053
|
+
stacks: import_path17.default.join(RUDI_HOME3, "stacks"),
|
|
22054
|
+
// Shared with Studio
|
|
22055
|
+
prompts: import_path17.default.join(RUDI_HOME3, "prompts"),
|
|
22056
|
+
// Shared with Studio
|
|
22057
|
+
// Runtimes (interpreters: node, python, deno, bun)
|
|
22058
|
+
runtimes: import_path17.default.join(RUDI_HOME3, "runtimes"),
|
|
22059
|
+
// Binaries (utility CLIs: ffmpeg, imagemagick, ripgrep, etc.)
|
|
22060
|
+
binaries: import_path17.default.join(RUDI_HOME3, "binaries"),
|
|
22061
|
+
// Agents (AI CLI tools: claude, codex, gemini, copilot, ollama)
|
|
22062
|
+
agents: import_path17.default.join(RUDI_HOME3, "agents"),
|
|
22063
|
+
// Runtime binaries (content-addressed)
|
|
22064
|
+
store: import_path17.default.join(RUDI_HOME3, "store"),
|
|
22065
|
+
// Shims (symlinks to store/)
|
|
22066
|
+
bins: import_path17.default.join(RUDI_HOME3, "bins"),
|
|
22067
|
+
// Lockfiles
|
|
22068
|
+
locks: import_path17.default.join(RUDI_HOME3, "locks"),
|
|
22069
|
+
// Secrets (OS Keychain preferred, encrypted file fallback)
|
|
22070
|
+
vault: import_path17.default.join(RUDI_HOME3, "vault"),
|
|
22071
|
+
// Database (shared with Studio)
|
|
22072
|
+
db: RUDI_HOME3,
|
|
22073
|
+
dbFile: import_path17.default.join(RUDI_HOME3, "rudi.db"),
|
|
22074
|
+
// Cache
|
|
22075
|
+
cache: import_path17.default.join(RUDI_HOME3, "cache"),
|
|
22076
|
+
registryCache: import_path17.default.join(RUDI_HOME3, "cache", "registry.json"),
|
|
22077
|
+
// Config
|
|
22078
|
+
config: import_path17.default.join(RUDI_HOME3, "config.json"),
|
|
22079
|
+
// Logs
|
|
22080
|
+
logs: import_path17.default.join(RUDI_HOME3, "logs")
|
|
22081
|
+
};
|
|
22082
|
+
function getPlatformArch2() {
|
|
22083
|
+
const platform = import_os5.default.platform();
|
|
22084
|
+
const arch = import_os5.default.arch();
|
|
22085
|
+
const normalizedArch = arch === "x64" ? "x64" : arch === "arm64" ? "arm64" : arch;
|
|
22086
|
+
return `${platform}-${normalizedArch}`;
|
|
22087
|
+
}
|
|
22088
|
+
function ensureDirectories2() {
|
|
22089
|
+
const dirs = [
|
|
22090
|
+
PATHS2.stacks,
|
|
22091
|
+
// MCP servers (google-ai, notion-workspace, etc.)
|
|
22092
|
+
PATHS2.prompts,
|
|
22093
|
+
// Reusable prompts
|
|
22094
|
+
PATHS2.runtimes,
|
|
22095
|
+
// Language runtimes (node, python, bun, deno)
|
|
22096
|
+
PATHS2.binaries,
|
|
22097
|
+
// Utility binaries (ffmpeg, git, jq, etc.)
|
|
22098
|
+
PATHS2.agents,
|
|
22099
|
+
// AI CLI agents (claude, codex, gemini, copilot)
|
|
22100
|
+
PATHS2.bins,
|
|
22101
|
+
// Shims directory (Studio only)
|
|
22102
|
+
PATHS2.locks,
|
|
22103
|
+
// Lock files
|
|
22104
|
+
PATHS2.db,
|
|
22105
|
+
// Database directory
|
|
22106
|
+
PATHS2.cache
|
|
22107
|
+
// Registry cache
|
|
22108
|
+
];
|
|
22109
|
+
for (const dir of dirs) {
|
|
22110
|
+
if (!import_fs18.default.existsSync(dir)) {
|
|
22111
|
+
import_fs18.default.mkdirSync(dir, { recursive: true });
|
|
22112
|
+
}
|
|
22113
|
+
}
|
|
22114
|
+
}
|
|
22115
|
+
var PACKAGE_KINDS3 = ["stack", "prompt", "runtime", "binary", "agent"];
|
|
22116
|
+
function parsePackageId2(id) {
|
|
22117
|
+
const match = id.match(/^(stack|prompt|runtime|binary|agent|npm):(.+)$/);
|
|
22118
|
+
if (!match) {
|
|
22119
|
+
throw new Error(`Invalid package ID: ${id} (expected format: kind:name, where kind is one of: ${PACKAGE_KINDS3.join(", ")}, npm)`);
|
|
22120
|
+
}
|
|
22121
|
+
return [match[1], match[2]];
|
|
22122
|
+
}
|
|
22123
|
+
function getPackagePath2(id) {
|
|
22124
|
+
const [kind, name] = parsePackageId2(id);
|
|
22125
|
+
switch (kind) {
|
|
22126
|
+
case "stack":
|
|
22127
|
+
return import_path17.default.join(PATHS2.stacks, name);
|
|
22128
|
+
case "prompt":
|
|
22129
|
+
return import_path17.default.join(PATHS2.prompts, `${name}.md`);
|
|
22130
|
+
case "runtime":
|
|
22131
|
+
return import_path17.default.join(PATHS2.runtimes, name);
|
|
22132
|
+
case "binary":
|
|
22133
|
+
return import_path17.default.join(PATHS2.binaries, name);
|
|
22134
|
+
case "agent":
|
|
22135
|
+
return import_path17.default.join(PATHS2.agents, name);
|
|
22136
|
+
case "npm":
|
|
22137
|
+
const sanitized = name.replace(/\//g, "__").replace(/^@/, "");
|
|
22138
|
+
return import_path17.default.join(PATHS2.binaries, "npm", sanitized);
|
|
22139
|
+
default:
|
|
22140
|
+
throw new Error(`Unknown package kind: ${kind}`);
|
|
22141
|
+
}
|
|
22142
|
+
}
|
|
22143
|
+
|
|
22144
|
+
// src/commands/init.js
|
|
22145
|
+
init_src4();
|
|
21157
22146
|
var RELEASES_BASE = "https://github.com/learn-rudi/registry/releases/download/v1.0.0";
|
|
21158
22147
|
var BUNDLED_RUNTIMES = ["node", "python"];
|
|
21159
22148
|
var ESSENTIAL_BINARIES = ["sqlite", "ripgrep"];
|
|
@@ -21165,25 +22154,25 @@ async function cmdInit(args, flags) {
|
|
|
21165
22154
|
console.log("\u2550".repeat(60));
|
|
21166
22155
|
console.log("RUDI Initialization");
|
|
21167
22156
|
console.log("\u2550".repeat(60));
|
|
21168
|
-
console.log(`Home: ${
|
|
22157
|
+
console.log(`Home: ${PATHS2.home}`);
|
|
21169
22158
|
console.log();
|
|
21170
22159
|
}
|
|
21171
22160
|
const actions = { created: [], skipped: [], failed: [] };
|
|
21172
22161
|
if (!quiet) console.log("1. Checking directory structure...");
|
|
21173
|
-
|
|
22162
|
+
ensureDirectories2();
|
|
21174
22163
|
const dirs = [
|
|
21175
|
-
|
|
21176
|
-
|
|
21177
|
-
|
|
21178
|
-
|
|
21179
|
-
|
|
21180
|
-
|
|
21181
|
-
|
|
22164
|
+
PATHS2.stacks,
|
|
22165
|
+
PATHS2.prompts,
|
|
22166
|
+
PATHS2.runtimes,
|
|
22167
|
+
PATHS2.binaries,
|
|
22168
|
+
PATHS2.agents,
|
|
22169
|
+
PATHS2.cache,
|
|
22170
|
+
import_path19.default.join(PATHS2.home, "shims")
|
|
21182
22171
|
];
|
|
21183
22172
|
for (const dir of dirs) {
|
|
21184
|
-
const dirName =
|
|
21185
|
-
if (!
|
|
21186
|
-
|
|
22173
|
+
const dirName = import_path19.default.basename(dir);
|
|
22174
|
+
if (!import_fs20.default.existsSync(dir)) {
|
|
22175
|
+
import_fs20.default.mkdirSync(dir, { recursive: true });
|
|
21187
22176
|
actions.created.push(`dir:${dirName}`);
|
|
21188
22177
|
if (!quiet) console.log(` + ${dirName}/ (created)`);
|
|
21189
22178
|
} else {
|
|
@@ -21193,8 +22182,8 @@ async function cmdInit(args, flags) {
|
|
|
21193
22182
|
}
|
|
21194
22183
|
if (!skipDownloads) {
|
|
21195
22184
|
if (!quiet) console.log("\n2. Checking runtimes...");
|
|
21196
|
-
const index = await
|
|
21197
|
-
const platform =
|
|
22185
|
+
const index = await fetchIndex2();
|
|
22186
|
+
const platform = getPlatformArch2();
|
|
21198
22187
|
for (const runtimeName of BUNDLED_RUNTIMES) {
|
|
21199
22188
|
const runtime = index.packages?.runtimes?.official?.find(
|
|
21200
22189
|
(r) => r.id === `runtime:${runtimeName}` || r.id === runtimeName
|
|
@@ -21204,14 +22193,14 @@ async function cmdInit(args, flags) {
|
|
|
21204
22193
|
if (!quiet) console.log(` \u26A0 ${runtimeName}: not found in registry`);
|
|
21205
22194
|
continue;
|
|
21206
22195
|
}
|
|
21207
|
-
const destPath =
|
|
21208
|
-
if (
|
|
22196
|
+
const destPath = import_path19.default.join(PATHS2.runtimes, runtimeName);
|
|
22197
|
+
if (import_fs20.default.existsSync(destPath) && !force) {
|
|
21209
22198
|
actions.skipped.push(`runtime:${runtimeName}`);
|
|
21210
22199
|
if (!quiet) console.log(` \u2713 ${runtimeName}: already installed`);
|
|
21211
22200
|
continue;
|
|
21212
22201
|
}
|
|
21213
22202
|
try {
|
|
21214
|
-
await
|
|
22203
|
+
await downloadRuntime3(runtime, runtimeName, destPath, platform);
|
|
21215
22204
|
actions.created.push(`runtime:${runtimeName}`);
|
|
21216
22205
|
if (!quiet) console.log(` + ${runtimeName}: installed`);
|
|
21217
22206
|
} catch (error) {
|
|
@@ -21229,8 +22218,8 @@ async function cmdInit(args, flags) {
|
|
|
21229
22218
|
if (!quiet) console.log(` \u26A0 ${binaryName}: not found in registry`);
|
|
21230
22219
|
continue;
|
|
21231
22220
|
}
|
|
21232
|
-
const destPath =
|
|
21233
|
-
if (
|
|
22221
|
+
const destPath = import_path19.default.join(PATHS2.binaries, binaryName);
|
|
22222
|
+
if (import_fs20.default.existsSync(destPath) && !force) {
|
|
21234
22223
|
actions.skipped.push(`binary:${binaryName}`);
|
|
21235
22224
|
if (!quiet) console.log(` \u2713 ${binaryName}: already installed`);
|
|
21236
22225
|
continue;
|
|
@@ -21248,14 +22237,14 @@ async function cmdInit(args, flags) {
|
|
|
21248
22237
|
if (!quiet) console.log("\n2-3. Skipping downloads (--skip-downloads)");
|
|
21249
22238
|
}
|
|
21250
22239
|
if (!quiet) console.log("\n4. Updating shims...");
|
|
21251
|
-
const shimsDir =
|
|
22240
|
+
const shimsDir = import_path19.default.join(PATHS2.home, "shims");
|
|
21252
22241
|
const shimCount = await createShims(shimsDir, quiet);
|
|
21253
22242
|
if (shimCount > 0) {
|
|
21254
22243
|
actions.created.push(`shims:${shimCount}`);
|
|
21255
22244
|
}
|
|
21256
22245
|
if (!quiet) console.log("\n5. Checking database...");
|
|
21257
|
-
const dbPath =
|
|
21258
|
-
const dbExists =
|
|
22246
|
+
const dbPath = import_path19.default.join(PATHS2.home, "rudi.db");
|
|
22247
|
+
const dbExists = import_fs20.default.existsSync(dbPath);
|
|
21259
22248
|
try {
|
|
21260
22249
|
const result = initSchema();
|
|
21261
22250
|
if (dbExists) {
|
|
@@ -21270,14 +22259,14 @@ async function cmdInit(args, flags) {
|
|
|
21270
22259
|
if (!quiet) console.log(` \u2717 Database error: ${error.message}`);
|
|
21271
22260
|
}
|
|
21272
22261
|
if (!quiet) console.log("\n6. Checking settings...");
|
|
21273
|
-
const settingsPath =
|
|
21274
|
-
if (!
|
|
22262
|
+
const settingsPath = import_path19.default.join(PATHS2.home, "settings.json");
|
|
22263
|
+
if (!import_fs20.default.existsSync(settingsPath)) {
|
|
21275
22264
|
const settings = {
|
|
21276
22265
|
version: "1.0.0",
|
|
21277
22266
|
initialized: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21278
22267
|
theme: "system"
|
|
21279
22268
|
};
|
|
21280
|
-
|
|
22269
|
+
import_fs20.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
21281
22270
|
actions.created.push("settings");
|
|
21282
22271
|
if (!quiet) console.log(" + settings.json created");
|
|
21283
22272
|
} else {
|
|
@@ -21293,7 +22282,7 @@ async function cmdInit(args, flags) {
|
|
|
21293
22282
|
}
|
|
21294
22283
|
console.log("\u2550".repeat(60));
|
|
21295
22284
|
if (actions.created.includes("settings")) {
|
|
21296
|
-
const shimsPath =
|
|
22285
|
+
const shimsPath = import_path19.default.join(PATHS2.home, "shims");
|
|
21297
22286
|
console.log("\nAdd to your shell profile (~/.zshrc or ~/.bashrc):");
|
|
21298
22287
|
console.log(` export PATH="${shimsPath}:$PATH"`);
|
|
21299
22288
|
console.log("\nThen run:");
|
|
@@ -21303,7 +22292,7 @@ async function cmdInit(args, flags) {
|
|
|
21303
22292
|
}
|
|
21304
22293
|
return actions;
|
|
21305
22294
|
}
|
|
21306
|
-
async function
|
|
22295
|
+
async function downloadRuntime3(runtime, name, destPath, platform) {
|
|
21307
22296
|
let url;
|
|
21308
22297
|
if (runtime.upstream?.[platform]) {
|
|
21309
22298
|
url = runtime.upstream[platform];
|
|
@@ -21326,15 +22315,15 @@ async function downloadBinary(binary, name, destPath, platform) {
|
|
|
21326
22315
|
await downloadAndExtract(url, destPath, name, binary.extract);
|
|
21327
22316
|
}
|
|
21328
22317
|
async function downloadAndExtract(url, destPath, name, extractConfig) {
|
|
21329
|
-
const tempFile =
|
|
22318
|
+
const tempFile = import_path19.default.join(PATHS2.cache, `${name}-download.tar.gz`);
|
|
21330
22319
|
const response = await fetch(url);
|
|
21331
22320
|
if (!response.ok) {
|
|
21332
22321
|
throw new Error(`HTTP ${response.status}`);
|
|
21333
22322
|
}
|
|
21334
|
-
if (!
|
|
21335
|
-
|
|
22323
|
+
if (!import_fs20.default.existsSync(destPath)) {
|
|
22324
|
+
import_fs20.default.mkdirSync(destPath, { recursive: true });
|
|
21336
22325
|
}
|
|
21337
|
-
const fileStream = (0,
|
|
22326
|
+
const fileStream = (0, import_fs21.createWriteStream)(tempFile);
|
|
21338
22327
|
await (0, import_promises.pipeline)(response.body, fileStream);
|
|
21339
22328
|
try {
|
|
21340
22329
|
(0, import_child_process6.execSync)(`tar -xzf "${tempFile}" -C "${destPath}" --strip-components=1`, {
|
|
@@ -21343,7 +22332,7 @@ async function downloadAndExtract(url, destPath, name, extractConfig) {
|
|
|
21343
22332
|
} catch {
|
|
21344
22333
|
(0, import_child_process6.execSync)(`tar -xzf "${tempFile}" -C "${destPath}"`, { stdio: "pipe" });
|
|
21345
22334
|
}
|
|
21346
|
-
|
|
22335
|
+
import_fs20.default.unlinkSync(tempFile);
|
|
21347
22336
|
}
|
|
21348
22337
|
async function createShims(shimsDir, quiet = false) {
|
|
21349
22338
|
const shims = [];
|
|
@@ -21362,17 +22351,17 @@ async function createShims(shimsDir, quiet = false) {
|
|
|
21362
22351
|
ripgrep: "binaries/ripgrep/rg"
|
|
21363
22352
|
};
|
|
21364
22353
|
for (const [shimName, targetPath] of Object.entries(runtimeShims)) {
|
|
21365
|
-
const fullTarget =
|
|
21366
|
-
const shimPath =
|
|
21367
|
-
if (
|
|
22354
|
+
const fullTarget = import_path19.default.join(PATHS2.home, targetPath);
|
|
22355
|
+
const shimPath = import_path19.default.join(shimsDir, shimName);
|
|
22356
|
+
if (import_fs20.default.existsSync(fullTarget)) {
|
|
21368
22357
|
createShim(shimPath, fullTarget);
|
|
21369
22358
|
shims.push(shimName);
|
|
21370
22359
|
}
|
|
21371
22360
|
}
|
|
21372
22361
|
for (const [shimName, targetPath] of Object.entries(binaryShims)) {
|
|
21373
|
-
const fullTarget =
|
|
21374
|
-
const shimPath =
|
|
21375
|
-
if (
|
|
22362
|
+
const fullTarget = import_path19.default.join(PATHS2.home, targetPath);
|
|
22363
|
+
const shimPath = import_path19.default.join(shimsDir, shimName);
|
|
22364
|
+
if (import_fs20.default.existsSync(fullTarget)) {
|
|
21376
22365
|
createShim(shimPath, fullTarget);
|
|
21377
22366
|
shims.push(shimName);
|
|
21378
22367
|
}
|
|
@@ -21387,18 +22376,17 @@ async function createShims(shimsDir, quiet = false) {
|
|
|
21387
22376
|
return shims.length;
|
|
21388
22377
|
}
|
|
21389
22378
|
function createShim(shimPath, targetPath) {
|
|
21390
|
-
if (
|
|
21391
|
-
|
|
22379
|
+
if (import_fs20.default.existsSync(shimPath)) {
|
|
22380
|
+
import_fs20.default.unlinkSync(shimPath);
|
|
21392
22381
|
}
|
|
21393
|
-
|
|
22382
|
+
import_fs20.default.symlinkSync(targetPath, shimPath);
|
|
21394
22383
|
}
|
|
21395
22384
|
|
|
21396
22385
|
// src/commands/update.js
|
|
21397
|
-
var
|
|
21398
|
-
var
|
|
22386
|
+
var import_fs22 = __toESM(require("fs"), 1);
|
|
22387
|
+
var import_path20 = __toESM(require("path"), 1);
|
|
21399
22388
|
var import_child_process7 = require("child_process");
|
|
21400
|
-
|
|
21401
|
-
init_src2();
|
|
22389
|
+
init_src4();
|
|
21402
22390
|
async function cmdUpdate(args, flags) {
|
|
21403
22391
|
const pkgId = args[0];
|
|
21404
22392
|
if (!pkgId) {
|
|
@@ -21419,12 +22407,12 @@ async function cmdUpdate(args, flags) {
|
|
|
21419
22407
|
}
|
|
21420
22408
|
}
|
|
21421
22409
|
async function updatePackage2(pkgId, flags) {
|
|
21422
|
-
const [kind, name] =
|
|
21423
|
-
const installPath =
|
|
21424
|
-
if (!
|
|
22410
|
+
const [kind, name] = parsePackageId2(pkgId);
|
|
22411
|
+
const installPath = getPackagePath2(pkgId);
|
|
22412
|
+
if (!import_fs22.default.existsSync(installPath)) {
|
|
21425
22413
|
return { success: false, error: "Package not installed" };
|
|
21426
22414
|
}
|
|
21427
|
-
const pkg = await
|
|
22415
|
+
const pkg = await getPackage2(pkgId);
|
|
21428
22416
|
if (!pkg) {
|
|
21429
22417
|
return { success: false, error: "Package not found in registry" };
|
|
21430
22418
|
}
|
|
@@ -21444,7 +22432,7 @@ async function updatePackage2(pkgId, flags) {
|
|
|
21444
22432
|
}
|
|
21445
22433
|
if (pkg.pipPackage) {
|
|
21446
22434
|
try {
|
|
21447
|
-
const venvPip =
|
|
22435
|
+
const venvPip = import_path20.default.join(installPath, "venv", "bin", "pip");
|
|
21448
22436
|
(0, import_child_process7.execSync)(`"${venvPip}" install --upgrade ${pkg.pipPackage}`, {
|
|
21449
22437
|
stdio: flags.verbose ? "inherit" : "pipe"
|
|
21450
22438
|
});
|
|
@@ -21460,9 +22448,9 @@ async function updatePackage2(pkgId, flags) {
|
|
|
21460
22448
|
}
|
|
21461
22449
|
if (kind === "runtime" && !pkg.npmPackage && !pkg.pipPackage) {
|
|
21462
22450
|
try {
|
|
21463
|
-
const { downloadRuntime:
|
|
21464
|
-
|
|
21465
|
-
await
|
|
22451
|
+
const { downloadRuntime: downloadRuntime4 } = await Promise.resolve().then(() => (init_src4(), src_exports2));
|
|
22452
|
+
import_fs22.default.rmSync(installPath, { recursive: true, force: true });
|
|
22453
|
+
await downloadRuntime4(name, pkg.version || "latest", installPath, {
|
|
21466
22454
|
onProgress: (p) => {
|
|
21467
22455
|
if (flags.verbose) console.log(` ${p.phase}...`);
|
|
21468
22456
|
}
|
|
@@ -21480,9 +22468,9 @@ async function updateAll2(flags) {
|
|
|
21480
22468
|
let updated = 0;
|
|
21481
22469
|
let failed = 0;
|
|
21482
22470
|
for (const kind of kinds) {
|
|
21483
|
-
const dir = kind === "runtime" ?
|
|
21484
|
-
if (!
|
|
21485
|
-
const entries =
|
|
22471
|
+
const dir = kind === "runtime" ? PATHS2.runtimes : kind === "stack" ? PATHS2.stacks : PATHS2.prompts;
|
|
22472
|
+
if (!import_fs22.default.existsSync(dir)) continue;
|
|
22473
|
+
const entries = import_fs22.default.readdirSync(dir, { withFileTypes: true });
|
|
21486
22474
|
for (const entry of entries) {
|
|
21487
22475
|
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
21488
22476
|
const pkgId = `${kind}:${entry.name}`;
|
|
@@ -21501,14 +22489,14 @@ Updated ${updated} package(s)${failed > 0 ? `, ${failed} failed` : ""}`);
|
|
|
21501
22489
|
}
|
|
21502
22490
|
function getInstalledVersion(installPath, npmPackage) {
|
|
21503
22491
|
try {
|
|
21504
|
-
const pkgJsonPath =
|
|
21505
|
-
if (
|
|
21506
|
-
const pkgJson = JSON.parse(
|
|
22492
|
+
const pkgJsonPath = import_path20.default.join(installPath, "node_modules", npmPackage.replace("@", "").split("/")[0], "package.json");
|
|
22493
|
+
if (import_fs22.default.existsSync(pkgJsonPath)) {
|
|
22494
|
+
const pkgJson = JSON.parse(import_fs22.default.readFileSync(pkgJsonPath, "utf-8"));
|
|
21507
22495
|
return pkgJson.version;
|
|
21508
22496
|
}
|
|
21509
|
-
const rootPkgPath =
|
|
21510
|
-
if (
|
|
21511
|
-
const rootPkg = JSON.parse(
|
|
22497
|
+
const rootPkgPath = import_path20.default.join(installPath, "package.json");
|
|
22498
|
+
if (import_fs22.default.existsSync(rootPkgPath)) {
|
|
22499
|
+
const rootPkg = JSON.parse(import_fs22.default.readFileSync(rootPkgPath, "utf-8"));
|
|
21512
22500
|
const dep = rootPkg.dependencies?.[npmPackage];
|
|
21513
22501
|
if (dep) return dep.replace(/[\^~]/, "");
|
|
21514
22502
|
}
|
|
@@ -21517,20 +22505,20 @@ function getInstalledVersion(installPath, npmPackage) {
|
|
|
21517
22505
|
return null;
|
|
21518
22506
|
}
|
|
21519
22507
|
function updateRuntimeMetadata(installPath, updates) {
|
|
21520
|
-
const metaPath =
|
|
22508
|
+
const metaPath = import_path20.default.join(installPath, "runtime.json");
|
|
21521
22509
|
try {
|
|
21522
22510
|
let meta = {};
|
|
21523
|
-
if (
|
|
21524
|
-
meta = JSON.parse(
|
|
22511
|
+
if (import_fs22.default.existsSync(metaPath)) {
|
|
22512
|
+
meta = JSON.parse(import_fs22.default.readFileSync(metaPath, "utf-8"));
|
|
21525
22513
|
}
|
|
21526
22514
|
meta = { ...meta, ...updates };
|
|
21527
|
-
|
|
22515
|
+
import_fs22.default.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
|
|
21528
22516
|
} catch {
|
|
21529
22517
|
}
|
|
21530
22518
|
}
|
|
21531
22519
|
|
|
21532
22520
|
// src/commands/logs.js
|
|
21533
|
-
var
|
|
22521
|
+
var import_fs23 = __toESM(require("fs"), 1);
|
|
21534
22522
|
function parseTimeAgo(str) {
|
|
21535
22523
|
const match = str.match(/^(\d+)([smhd])$/);
|
|
21536
22524
|
if (!match) return null;
|
|
@@ -21630,7 +22618,7 @@ function exportLogs(logs, filepath, format) {
|
|
|
21630
22618
|
});
|
|
21631
22619
|
content = JSON.stringify(formatted, null, 2);
|
|
21632
22620
|
}
|
|
21633
|
-
|
|
22621
|
+
import_fs23.default.writeFileSync(filepath, content, "utf-8");
|
|
21634
22622
|
return filepath;
|
|
21635
22623
|
}
|
|
21636
22624
|
function printStats(stats) {
|
|
@@ -21756,11 +22744,10 @@ async function handleLogsCommand(args, flags) {
|
|
|
21756
22744
|
}
|
|
21757
22745
|
|
|
21758
22746
|
// src/commands/which.js
|
|
21759
|
-
var
|
|
21760
|
-
var
|
|
22747
|
+
var fs26 = __toESM(require("fs/promises"), 1);
|
|
22748
|
+
var path26 = __toESM(require("path"), 1);
|
|
21761
22749
|
var import_child_process8 = require("child_process");
|
|
21762
22750
|
init_src3();
|
|
21763
|
-
init_src();
|
|
21764
22751
|
async function cmdWhich(args, flags) {
|
|
21765
22752
|
const stackId = args[0];
|
|
21766
22753
|
if (!stackId) {
|
|
@@ -21827,7 +22814,7 @@ Installed stacks:`);
|
|
|
21827
22814
|
if (runtimeInfo.entry) {
|
|
21828
22815
|
console.log("");
|
|
21829
22816
|
console.log("Run MCP server directly:");
|
|
21830
|
-
const entryPath =
|
|
22817
|
+
const entryPath = path26.join(stackPath, runtimeInfo.entry);
|
|
21831
22818
|
if (runtimeInfo.runtime === "node") {
|
|
21832
22819
|
console.log(` echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | node ${entryPath}`);
|
|
21833
22820
|
} else if (runtimeInfo.runtime === "python") {
|
|
@@ -21846,27 +22833,27 @@ Installed stacks:`);
|
|
|
21846
22833
|
async function detectRuntime(stackPath) {
|
|
21847
22834
|
const runtimes = ["node", "python"];
|
|
21848
22835
|
for (const runtime of runtimes) {
|
|
21849
|
-
const runtimePath =
|
|
22836
|
+
const runtimePath = path26.join(stackPath, runtime);
|
|
21850
22837
|
try {
|
|
21851
|
-
await
|
|
22838
|
+
await fs26.access(runtimePath);
|
|
21852
22839
|
if (runtime === "node") {
|
|
21853
|
-
const distEntry =
|
|
21854
|
-
const srcEntry =
|
|
22840
|
+
const distEntry = path26.join(runtimePath, "dist", "index.js");
|
|
22841
|
+
const srcEntry = path26.join(runtimePath, "src", "index.ts");
|
|
21855
22842
|
try {
|
|
21856
|
-
await
|
|
22843
|
+
await fs26.access(distEntry);
|
|
21857
22844
|
return { runtime: "node", entry: `${runtime}/dist/index.js` };
|
|
21858
22845
|
} catch {
|
|
21859
22846
|
try {
|
|
21860
|
-
await
|
|
22847
|
+
await fs26.access(srcEntry);
|
|
21861
22848
|
return { runtime: "node", entry: `${runtime}/src/index.ts` };
|
|
21862
22849
|
} catch {
|
|
21863
22850
|
return { runtime: "node", entry: null };
|
|
21864
22851
|
}
|
|
21865
22852
|
}
|
|
21866
22853
|
} else if (runtime === "python") {
|
|
21867
|
-
const entry =
|
|
22854
|
+
const entry = path26.join(runtimePath, "src", "index.py");
|
|
21868
22855
|
try {
|
|
21869
|
-
await
|
|
22856
|
+
await fs26.access(entry);
|
|
21870
22857
|
return { runtime: "python", entry: `${runtime}/src/index.py` };
|
|
21871
22858
|
} catch {
|
|
21872
22859
|
return { runtime: "python", entry: null };
|
|
@@ -21882,21 +22869,21 @@ async function checkAuth(stackPath, runtime) {
|
|
|
21882
22869
|
const authFiles = [];
|
|
21883
22870
|
let configured = false;
|
|
21884
22871
|
if (runtime === "node" || runtime === "python") {
|
|
21885
|
-
const runtimePath =
|
|
21886
|
-
const tokenPath =
|
|
22872
|
+
const runtimePath = path26.join(stackPath, runtime);
|
|
22873
|
+
const tokenPath = path26.join(runtimePath, "token.json");
|
|
21887
22874
|
try {
|
|
21888
|
-
await
|
|
22875
|
+
await fs26.access(tokenPath);
|
|
21889
22876
|
authFiles.push(`${runtime}/token.json`);
|
|
21890
22877
|
configured = true;
|
|
21891
22878
|
} catch {
|
|
21892
|
-
const accountsPath =
|
|
22879
|
+
const accountsPath = path26.join(runtimePath, "accounts");
|
|
21893
22880
|
try {
|
|
21894
|
-
const accounts = await
|
|
22881
|
+
const accounts = await fs26.readdir(accountsPath);
|
|
21895
22882
|
for (const account of accounts) {
|
|
21896
22883
|
if (account.startsWith(".")) continue;
|
|
21897
|
-
const accountTokenPath =
|
|
22884
|
+
const accountTokenPath = path26.join(accountsPath, account, "token.json");
|
|
21898
22885
|
try {
|
|
21899
|
-
await
|
|
22886
|
+
await fs26.access(accountTokenPath);
|
|
21900
22887
|
authFiles.push(`${runtime}/accounts/${account}/token.json`);
|
|
21901
22888
|
configured = true;
|
|
21902
22889
|
} catch {
|
|
@@ -21906,9 +22893,9 @@ async function checkAuth(stackPath, runtime) {
|
|
|
21906
22893
|
}
|
|
21907
22894
|
}
|
|
21908
22895
|
}
|
|
21909
|
-
const envPath =
|
|
22896
|
+
const envPath = path26.join(stackPath, ".env");
|
|
21910
22897
|
try {
|
|
21911
|
-
const envContent = await
|
|
22898
|
+
const envContent = await fs26.readFile(envPath, "utf-8");
|
|
21912
22899
|
const hasValues = envContent.split("\n").some((line) => {
|
|
21913
22900
|
const trimmed = line.trim();
|
|
21914
22901
|
if (!trimmed || trimmed.startsWith("#")) return false;
|
|
@@ -21952,11 +22939,10 @@ function checkIfRunning(stackName) {
|
|
|
21952
22939
|
}
|
|
21953
22940
|
|
|
21954
22941
|
// src/commands/auth.js
|
|
21955
|
-
var
|
|
21956
|
-
var
|
|
22942
|
+
var fs27 = __toESM(require("fs/promises"), 1);
|
|
22943
|
+
var path27 = __toESM(require("path"), 1);
|
|
21957
22944
|
var import_child_process9 = require("child_process");
|
|
21958
22945
|
init_src3();
|
|
21959
|
-
init_src();
|
|
21960
22946
|
var net = __toESM(require("net"), 1);
|
|
21961
22947
|
async function findAvailablePort(basePort = 3456) {
|
|
21962
22948
|
for (let port = basePort; port < basePort + 10; port++) {
|
|
@@ -21986,26 +22972,26 @@ function isPortAvailable(port) {
|
|
|
21986
22972
|
async function detectRuntime2(stackPath) {
|
|
21987
22973
|
const runtimes = ["node", "python"];
|
|
21988
22974
|
for (const runtime of runtimes) {
|
|
21989
|
-
const runtimePath =
|
|
22975
|
+
const runtimePath = path27.join(stackPath, runtime);
|
|
21990
22976
|
try {
|
|
21991
|
-
await
|
|
22977
|
+
await fs27.access(runtimePath);
|
|
21992
22978
|
if (runtime === "node") {
|
|
21993
|
-
const authTs =
|
|
21994
|
-
const authJs =
|
|
22979
|
+
const authTs = path27.join(runtimePath, "src", "auth.ts");
|
|
22980
|
+
const authJs = path27.join(runtimePath, "dist", "auth.js");
|
|
21995
22981
|
try {
|
|
21996
|
-
await
|
|
22982
|
+
await fs27.access(authTs);
|
|
21997
22983
|
return { runtime: "node", authScript: authTs, useTsx: true };
|
|
21998
22984
|
} catch {
|
|
21999
22985
|
try {
|
|
22000
|
-
await
|
|
22986
|
+
await fs27.access(authJs);
|
|
22001
22987
|
return { runtime: "node", authScript: authJs, useTsx: false };
|
|
22002
22988
|
} catch {
|
|
22003
22989
|
}
|
|
22004
22990
|
}
|
|
22005
22991
|
} else if (runtime === "python") {
|
|
22006
|
-
const authPy =
|
|
22992
|
+
const authPy = path27.join(runtimePath, "src", "auth.py");
|
|
22007
22993
|
try {
|
|
22008
|
-
await
|
|
22994
|
+
await fs27.access(authPy);
|
|
22009
22995
|
return { runtime: "python", authScript: authPy, useTsx: false };
|
|
22010
22996
|
} catch {
|
|
22011
22997
|
}
|
|
@@ -22055,14 +23041,14 @@ Installed stacks:`);
|
|
|
22055
23041
|
console.log(`Using port: ${port}`);
|
|
22056
23042
|
console.log("");
|
|
22057
23043
|
let cmd;
|
|
22058
|
-
const cwd =
|
|
23044
|
+
const cwd = path27.dirname(authInfo.authScript);
|
|
22059
23045
|
if (authInfo.runtime === "node") {
|
|
22060
|
-
const distAuth =
|
|
23046
|
+
const distAuth = path27.join(cwd, "..", "dist", "auth.js");
|
|
22061
23047
|
let useBuiltInPort = false;
|
|
22062
23048
|
let tempAuthScript = null;
|
|
22063
23049
|
try {
|
|
22064
|
-
await
|
|
22065
|
-
const distContent = await
|
|
23050
|
+
await fs27.access(distAuth);
|
|
23051
|
+
const distContent = await fs27.readFile(distAuth, "utf-8");
|
|
22066
23052
|
if (distContent.includes("findAvailablePort")) {
|
|
22067
23053
|
console.log("Using compiled authentication script...");
|
|
22068
23054
|
cmd = `node ${distAuth}${accountEmail ? ` ${accountEmail}` : ""}`;
|
|
@@ -22071,11 +23057,11 @@ Installed stacks:`);
|
|
|
22071
23057
|
} catch {
|
|
22072
23058
|
}
|
|
22073
23059
|
if (!useBuiltInPort) {
|
|
22074
|
-
const authContent = await
|
|
23060
|
+
const authContent = await fs27.readFile(authInfo.authScript, "utf-8");
|
|
22075
23061
|
const tempExt = authInfo.useTsx ? ".ts" : ".mjs";
|
|
22076
|
-
tempAuthScript =
|
|
23062
|
+
tempAuthScript = path27.join(cwd, "..", `auth-temp${tempExt}`);
|
|
22077
23063
|
const modifiedContent = authContent.replace(/localhost:3456/g, `localhost:${port}`).replace(/server\.listen\(3456/g, `server.listen(${port}`);
|
|
22078
|
-
await
|
|
23064
|
+
await fs27.writeFile(tempAuthScript, modifiedContent);
|
|
22079
23065
|
if (authInfo.useTsx) {
|
|
22080
23066
|
cmd = `npx tsx ${tempAuthScript}${accountEmail ? ` ${accountEmail}` : ""}`;
|
|
22081
23067
|
} else {
|
|
@@ -22090,12 +23076,12 @@ Installed stacks:`);
|
|
|
22090
23076
|
stdio: "inherit"
|
|
22091
23077
|
});
|
|
22092
23078
|
if (tempAuthScript) {
|
|
22093
|
-
await
|
|
23079
|
+
await fs27.unlink(tempAuthScript);
|
|
22094
23080
|
}
|
|
22095
23081
|
} catch (error) {
|
|
22096
23082
|
if (tempAuthScript) {
|
|
22097
23083
|
try {
|
|
22098
|
-
await
|
|
23084
|
+
await fs27.unlink(tempAuthScript);
|
|
22099
23085
|
} catch {
|
|
22100
23086
|
}
|
|
22101
23087
|
}
|
|
@@ -22127,21 +23113,20 @@ Installed stacks:`);
|
|
|
22127
23113
|
}
|
|
22128
23114
|
|
|
22129
23115
|
// src/commands/mcp.js
|
|
22130
|
-
var
|
|
22131
|
-
var
|
|
23116
|
+
var fs28 = __toESM(require("fs"), 1);
|
|
23117
|
+
var path28 = __toESM(require("path"), 1);
|
|
22132
23118
|
var import_child_process10 = require("child_process");
|
|
22133
|
-
init_src();
|
|
22134
23119
|
function getBundledRuntime(runtime) {
|
|
22135
23120
|
const platform = process.platform;
|
|
22136
23121
|
if (runtime === "node") {
|
|
22137
|
-
const nodePath = platform === "win32" ?
|
|
22138
|
-
if (
|
|
23122
|
+
const nodePath = platform === "win32" ? path28.join(PATHS2.runtimes, "node", "node.exe") : path28.join(PATHS2.runtimes, "node", "bin", "node");
|
|
23123
|
+
if (fs28.existsSync(nodePath)) {
|
|
22139
23124
|
return nodePath;
|
|
22140
23125
|
}
|
|
22141
23126
|
}
|
|
22142
23127
|
if (runtime === "python") {
|
|
22143
|
-
const pythonPath = platform === "win32" ?
|
|
22144
|
-
if (
|
|
23128
|
+
const pythonPath = platform === "win32" ? path28.join(PATHS2.runtimes, "python", "python.exe") : path28.join(PATHS2.runtimes, "python", "bin", "python3");
|
|
23129
|
+
if (fs28.existsSync(pythonPath)) {
|
|
22145
23130
|
return pythonPath;
|
|
22146
23131
|
}
|
|
22147
23132
|
}
|
|
@@ -22149,18 +23134,18 @@ function getBundledRuntime(runtime) {
|
|
|
22149
23134
|
}
|
|
22150
23135
|
function getBundledNpx() {
|
|
22151
23136
|
const platform = process.platform;
|
|
22152
|
-
const npxPath = platform === "win32" ?
|
|
22153
|
-
if (
|
|
23137
|
+
const npxPath = platform === "win32" ? path28.join(PATHS2.runtimes, "node", "npx.cmd") : path28.join(PATHS2.runtimes, "node", "bin", "npx");
|
|
23138
|
+
if (fs28.existsSync(npxPath)) {
|
|
22154
23139
|
return npxPath;
|
|
22155
23140
|
}
|
|
22156
23141
|
return null;
|
|
22157
23142
|
}
|
|
22158
23143
|
function loadManifest2(stackPath) {
|
|
22159
|
-
const manifestPath =
|
|
22160
|
-
if (!
|
|
23144
|
+
const manifestPath = path28.join(stackPath, "manifest.json");
|
|
23145
|
+
if (!fs28.existsSync(manifestPath)) {
|
|
22161
23146
|
return null;
|
|
22162
23147
|
}
|
|
22163
|
-
return JSON.parse(
|
|
23148
|
+
return JSON.parse(fs28.readFileSync(manifestPath, "utf-8"));
|
|
22164
23149
|
}
|
|
22165
23150
|
function getRequiredSecrets(manifest) {
|
|
22166
23151
|
const secrets = manifest?.requires?.secrets || manifest?.secrets || [];
|
|
@@ -22193,8 +23178,8 @@ async function cmdMcp(args, flags) {
|
|
|
22193
23178
|
console.error("Example: rudi mcp slack");
|
|
22194
23179
|
process.exit(1);
|
|
22195
23180
|
}
|
|
22196
|
-
const stackPath =
|
|
22197
|
-
if (!
|
|
23181
|
+
const stackPath = path28.join(PATHS2.stacks, stackName);
|
|
23182
|
+
if (!fs28.existsSync(stackPath)) {
|
|
22198
23183
|
console.error(`Stack not found: ${stackName}`);
|
|
22199
23184
|
console.error(`Expected at: ${stackPath}`);
|
|
22200
23185
|
console.error("");
|
|
@@ -22243,22 +23228,22 @@ async function cmdMcp(args, flags) {
|
|
|
22243
23228
|
}
|
|
22244
23229
|
return part;
|
|
22245
23230
|
}
|
|
22246
|
-
if (part.startsWith("./") || part.startsWith("../") || !
|
|
22247
|
-
const resolved =
|
|
22248
|
-
if (
|
|
23231
|
+
if (part.startsWith("./") || part.startsWith("../") || !path28.isAbsolute(part)) {
|
|
23232
|
+
const resolved = path28.join(stackPath, part);
|
|
23233
|
+
if (fs28.existsSync(resolved)) {
|
|
22249
23234
|
return resolved;
|
|
22250
23235
|
}
|
|
22251
23236
|
}
|
|
22252
23237
|
return part;
|
|
22253
23238
|
});
|
|
22254
23239
|
const [cmd, ...cmdArgs] = resolvedCommand;
|
|
22255
|
-
const bundledNodeBin =
|
|
22256
|
-
const bundledPythonBin =
|
|
22257
|
-
if (
|
|
23240
|
+
const bundledNodeBin = path28.join(PATHS2.runtimes, "node", "bin");
|
|
23241
|
+
const bundledPythonBin = path28.join(PATHS2.runtimes, "python", "bin");
|
|
23242
|
+
if (fs28.existsSync(bundledNodeBin) || fs28.existsSync(bundledPythonBin)) {
|
|
22258
23243
|
const runtimePaths = [];
|
|
22259
|
-
if (
|
|
22260
|
-
if (
|
|
22261
|
-
env.PATH = runtimePaths.join(
|
|
23244
|
+
if (fs28.existsSync(bundledNodeBin)) runtimePaths.push(bundledNodeBin);
|
|
23245
|
+
if (fs28.existsSync(bundledPythonBin)) runtimePaths.push(bundledPythonBin);
|
|
23246
|
+
env.PATH = runtimePaths.join(path28.delimiter) + path28.delimiter + (env.PATH || "");
|
|
22262
23247
|
}
|
|
22263
23248
|
if (flags.debug) {
|
|
22264
23249
|
console.error(`[rudi mcp] Stack: ${stackName}`);
|
|
@@ -22288,14 +23273,13 @@ async function cmdMcp(args, flags) {
|
|
|
22288
23273
|
}
|
|
22289
23274
|
|
|
22290
23275
|
// src/commands/integrate.js
|
|
22291
|
-
var
|
|
22292
|
-
var
|
|
22293
|
-
var
|
|
22294
|
-
|
|
22295
|
-
var
|
|
22296
|
-
var ROUTER_SHIM_PATH = path25.join(PATHS.home, "shims", "rudi-router");
|
|
23276
|
+
var fs29 = __toESM(require("fs"), 1);
|
|
23277
|
+
var path29 = __toESM(require("path"), 1);
|
|
23278
|
+
var import_os6 = __toESM(require("os"), 1);
|
|
23279
|
+
var HOME2 = import_os6.default.homedir();
|
|
23280
|
+
var ROUTER_SHIM_PATH = path29.join(PATHS2.home, "shims", "rudi-router");
|
|
22297
23281
|
function checkRouterShim() {
|
|
22298
|
-
if (!
|
|
23282
|
+
if (!fs29.existsSync(ROUTER_SHIM_PATH)) {
|
|
22299
23283
|
throw new Error(
|
|
22300
23284
|
`Router shim not found at ${ROUTER_SHIM_PATH}
|
|
22301
23285
|
Run: npm install -g @learnrudi/cli@latest`
|
|
@@ -22304,27 +23288,27 @@ Run: npm install -g @learnrudi/cli@latest`
|
|
|
22304
23288
|
return ROUTER_SHIM_PATH;
|
|
22305
23289
|
}
|
|
22306
23290
|
function backupConfig(configPath) {
|
|
22307
|
-
if (!
|
|
23291
|
+
if (!fs29.existsSync(configPath)) return null;
|
|
22308
23292
|
const backupPath = configPath + ".backup." + Date.now();
|
|
22309
|
-
|
|
23293
|
+
fs29.copyFileSync(configPath, backupPath);
|
|
22310
23294
|
return backupPath;
|
|
22311
23295
|
}
|
|
22312
23296
|
function readJsonConfig(configPath) {
|
|
22313
|
-
if (!
|
|
23297
|
+
if (!fs29.existsSync(configPath)) {
|
|
22314
23298
|
return {};
|
|
22315
23299
|
}
|
|
22316
23300
|
try {
|
|
22317
|
-
return JSON.parse(
|
|
23301
|
+
return JSON.parse(fs29.readFileSync(configPath, "utf-8"));
|
|
22318
23302
|
} catch {
|
|
22319
23303
|
return {};
|
|
22320
23304
|
}
|
|
22321
23305
|
}
|
|
22322
23306
|
function writeJsonConfig(configPath, config) {
|
|
22323
|
-
const dir =
|
|
22324
|
-
if (!
|
|
22325
|
-
|
|
23307
|
+
const dir = path29.dirname(configPath);
|
|
23308
|
+
if (!fs29.existsSync(dir)) {
|
|
23309
|
+
fs29.mkdirSync(dir, { recursive: true });
|
|
22326
23310
|
}
|
|
22327
|
-
|
|
23311
|
+
fs29.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
22328
23312
|
}
|
|
22329
23313
|
function buildRouterEntry(agentId) {
|
|
22330
23314
|
const base = {
|
|
@@ -22343,11 +23327,11 @@ async function integrateAgent(agentId, flags) {
|
|
|
22343
23327
|
return { success: false, error: "Unknown agent" };
|
|
22344
23328
|
}
|
|
22345
23329
|
const configPath = findAgentConfig(agentConfig);
|
|
22346
|
-
const targetPath = configPath ||
|
|
23330
|
+
const targetPath = configPath || path29.join(HOME2, agentConfig.paths[process.platform]?.[0] || agentConfig.paths.darwin[0]);
|
|
22347
23331
|
console.log(`
|
|
22348
23332
|
${agentConfig.name}:`);
|
|
22349
23333
|
console.log(` Config: ${targetPath}`);
|
|
22350
|
-
if (
|
|
23334
|
+
if (fs29.existsSync(targetPath)) {
|
|
22351
23335
|
const backup = backupConfig(targetPath);
|
|
22352
23336
|
if (backup && flags.verbose) {
|
|
22353
23337
|
console.log(` Backup: ${backup}`);
|
|
@@ -22358,7 +23342,7 @@ ${agentConfig.name}:`);
|
|
|
22358
23342
|
if (!config[key]) {
|
|
22359
23343
|
config[key] = {};
|
|
22360
23344
|
}
|
|
22361
|
-
const rudiMcpShimPath =
|
|
23345
|
+
const rudiMcpShimPath = path29.join(PATHS2.home, "shims", "rudi-mcp");
|
|
22362
23346
|
const removedEntries = [];
|
|
22363
23347
|
for (const [serverName, serverConfig] of Object.entries(config[key])) {
|
|
22364
23348
|
if (serverConfig.command === rudiMcpShimPath) {
|
|
@@ -22490,52 +23474,51 @@ Wiring up RUDI router...`);
|
|
|
22490
23474
|
}
|
|
22491
23475
|
|
|
22492
23476
|
// src/commands/migrate.js
|
|
22493
|
-
var
|
|
22494
|
-
var
|
|
22495
|
-
var
|
|
22496
|
-
|
|
22497
|
-
var
|
|
22498
|
-
var
|
|
22499
|
-
var SHIM_PATH = path26.join(PATHS.home, "shims", "rudi-mcp");
|
|
23477
|
+
var fs30 = __toESM(require("fs"), 1);
|
|
23478
|
+
var path30 = __toESM(require("path"), 1);
|
|
23479
|
+
var import_os7 = __toESM(require("os"), 1);
|
|
23480
|
+
var HOME3 = import_os7.default.homedir();
|
|
23481
|
+
var OLD_PROMPT_STACK = path30.join(HOME3, ".prompt-stack");
|
|
23482
|
+
var SHIM_PATH = path30.join(PATHS2.home, "shims", "rudi-mcp");
|
|
22500
23483
|
function getOldStacks() {
|
|
22501
|
-
const stacksDir =
|
|
22502
|
-
if (!
|
|
22503
|
-
return
|
|
22504
|
-
const hasManifest =
|
|
22505
|
-
const hasPackage =
|
|
23484
|
+
const stacksDir = path30.join(OLD_PROMPT_STACK, "stacks");
|
|
23485
|
+
if (!fs30.existsSync(stacksDir)) return [];
|
|
23486
|
+
return fs30.readdirSync(stacksDir, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).filter((d) => {
|
|
23487
|
+
const hasManifest = fs30.existsSync(path30.join(stacksDir, d.name, "manifest.json"));
|
|
23488
|
+
const hasPackage = fs30.existsSync(path30.join(stacksDir, d.name, "package.json"));
|
|
22506
23489
|
return hasManifest || hasPackage;
|
|
22507
23490
|
}).map((d) => d.name);
|
|
22508
23491
|
}
|
|
22509
23492
|
function copyStack(stackName) {
|
|
22510
|
-
const oldPath =
|
|
22511
|
-
const newPath =
|
|
22512
|
-
if (!
|
|
23493
|
+
const oldPath = path30.join(OLD_PROMPT_STACK, "stacks", stackName);
|
|
23494
|
+
const newPath = path30.join(PATHS2.stacks, stackName);
|
|
23495
|
+
if (!fs30.existsSync(oldPath)) {
|
|
22513
23496
|
return { success: false, error: "Source not found" };
|
|
22514
23497
|
}
|
|
22515
|
-
if (
|
|
23498
|
+
if (fs30.existsSync(newPath)) {
|
|
22516
23499
|
return { success: true, skipped: true, reason: "Already exists" };
|
|
22517
23500
|
}
|
|
22518
|
-
if (!
|
|
22519
|
-
|
|
23501
|
+
if (!fs30.existsSync(PATHS2.stacks)) {
|
|
23502
|
+
fs30.mkdirSync(PATHS2.stacks, { recursive: true });
|
|
22520
23503
|
}
|
|
22521
23504
|
copyRecursive(oldPath, newPath);
|
|
22522
23505
|
return { success: true, copied: true };
|
|
22523
23506
|
}
|
|
22524
23507
|
function copyRecursive(src, dest) {
|
|
22525
|
-
const stat =
|
|
23508
|
+
const stat = fs30.statSync(src);
|
|
22526
23509
|
if (stat.isDirectory()) {
|
|
22527
|
-
|
|
22528
|
-
for (const child of
|
|
22529
|
-
copyRecursive(
|
|
23510
|
+
fs30.mkdirSync(dest, { recursive: true });
|
|
23511
|
+
for (const child of fs30.readdirSync(src)) {
|
|
23512
|
+
copyRecursive(path30.join(src, child), path30.join(dest, child));
|
|
22530
23513
|
}
|
|
22531
23514
|
} else {
|
|
22532
|
-
|
|
23515
|
+
fs30.copyFileSync(src, dest);
|
|
22533
23516
|
}
|
|
22534
23517
|
}
|
|
22535
23518
|
function ensureShim() {
|
|
22536
|
-
const shimsDir =
|
|
22537
|
-
if (!
|
|
22538
|
-
|
|
23519
|
+
const shimsDir = path30.dirname(SHIM_PATH);
|
|
23520
|
+
if (!fs30.existsSync(shimsDir)) {
|
|
23521
|
+
fs30.mkdirSync(shimsDir, { recursive: true });
|
|
22539
23522
|
}
|
|
22540
23523
|
const shimContent = `#!/usr/bin/env bash
|
|
22541
23524
|
set -euo pipefail
|
|
@@ -22545,7 +23528,7 @@ else
|
|
|
22545
23528
|
exec npx --yes @learnrudi/cli mcp "$1"
|
|
22546
23529
|
fi
|
|
22547
23530
|
`;
|
|
22548
|
-
|
|
23531
|
+
fs30.writeFileSync(SHIM_PATH, shimContent, { mode: 493 });
|
|
22549
23532
|
}
|
|
22550
23533
|
function buildNewEntry(stackName, agentId) {
|
|
22551
23534
|
const base = {
|
|
@@ -22569,7 +23552,7 @@ function migrateAgentConfig(agentConfig, installedStacks, flags) {
|
|
|
22569
23552
|
if (!configPath) return { skipped: true, reason: "Config not found" };
|
|
22570
23553
|
let config;
|
|
22571
23554
|
try {
|
|
22572
|
-
config = JSON.parse(
|
|
23555
|
+
config = JSON.parse(fs30.readFileSync(configPath, "utf-8"));
|
|
22573
23556
|
} catch {
|
|
22574
23557
|
return { skipped: true, reason: "Could not parse config" };
|
|
22575
23558
|
}
|
|
@@ -22596,9 +23579,9 @@ function migrateAgentConfig(agentConfig, installedStacks, flags) {
|
|
|
22596
23579
|
}
|
|
22597
23580
|
if (updated > 0 || removed > 0) {
|
|
22598
23581
|
const backupPath = configPath + ".backup." + Date.now();
|
|
22599
|
-
|
|
23582
|
+
fs30.copyFileSync(configPath, backupPath);
|
|
22600
23583
|
config[key] = mcpServers;
|
|
22601
|
-
|
|
23584
|
+
fs30.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
22602
23585
|
}
|
|
22603
23586
|
return { updated, removed, changes };
|
|
22604
23587
|
}
|
|
@@ -22647,15 +23630,15 @@ async function migrateStatus() {
|
|
|
22647
23630
|
console.log(`Old .prompt-stack stacks: ${oldStacks.length}`);
|
|
22648
23631
|
if (oldStacks.length > 0) {
|
|
22649
23632
|
for (const name of oldStacks) {
|
|
22650
|
-
const existsInRudi =
|
|
23633
|
+
const existsInRudi = fs30.existsSync(path30.join(PATHS2.stacks, name));
|
|
22651
23634
|
const status = existsInRudi ? "\u2713 (already in .rudi)" : "\u25CB (needs migration)";
|
|
22652
23635
|
console.log(` ${status} ${name}`);
|
|
22653
23636
|
}
|
|
22654
23637
|
}
|
|
22655
|
-
const newStacksDir =
|
|
23638
|
+
const newStacksDir = PATHS2.stacks;
|
|
22656
23639
|
let newStacks = [];
|
|
22657
|
-
if (
|
|
22658
|
-
newStacks =
|
|
23640
|
+
if (fs30.existsSync(newStacksDir)) {
|
|
23641
|
+
newStacks = fs30.readdirSync(newStacksDir, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name);
|
|
22659
23642
|
}
|
|
22660
23643
|
console.log(`
|
|
22661
23644
|
New .rudi stacks: ${newStacks.length}`);
|
|
@@ -22670,7 +23653,7 @@ New .rudi stacks: ${newStacks.length}`);
|
|
|
22670
23653
|
if (!configPath) continue;
|
|
22671
23654
|
let config;
|
|
22672
23655
|
try {
|
|
22673
|
-
config = JSON.parse(
|
|
23656
|
+
config = JSON.parse(fs30.readFileSync(configPath, "utf-8"));
|
|
22674
23657
|
} catch {
|
|
22675
23658
|
continue;
|
|
22676
23659
|
}
|
|
@@ -22706,7 +23689,7 @@ async function migrateStacks(flags) {
|
|
|
22706
23689
|
`);
|
|
22707
23690
|
for (const name of oldStacks) {
|
|
22708
23691
|
if (flags.dryRun) {
|
|
22709
|
-
const exists =
|
|
23692
|
+
const exists = fs30.existsSync(path30.join(PATHS2.stacks, name));
|
|
22710
23693
|
console.log(` [dry-run] ${name}: ${exists ? "would skip (exists)" : "would copy"}`);
|
|
22711
23694
|
} else {
|
|
22712
23695
|
const result = copyStack(name);
|
|
@@ -22721,7 +23704,7 @@ async function migrateStacks(flags) {
|
|
|
22721
23704
|
}
|
|
22722
23705
|
if (!flags.dryRun) {
|
|
22723
23706
|
console.log(`
|
|
22724
|
-
Stacks migrated to: ${
|
|
23707
|
+
Stacks migrated to: ${PATHS2.stacks}`);
|
|
22725
23708
|
}
|
|
22726
23709
|
}
|
|
22727
23710
|
async function migrateConfigs(flags) {
|
|
@@ -22732,8 +23715,8 @@ async function migrateConfigs(flags) {
|
|
|
22732
23715
|
`);
|
|
22733
23716
|
}
|
|
22734
23717
|
let installedStacks = [];
|
|
22735
|
-
if (
|
|
22736
|
-
installedStacks =
|
|
23718
|
+
if (fs30.existsSync(PATHS2.stacks)) {
|
|
23719
|
+
installedStacks = fs30.readdirSync(PATHS2.stacks, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name);
|
|
22737
23720
|
}
|
|
22738
23721
|
for (const agentConfig of AGENT_CONFIGS) {
|
|
22739
23722
|
const configPath = findAgentConfig(agentConfig);
|
|
@@ -22901,9 +23884,9 @@ After configuring secrets, run: rudi index`);
|
|
|
22901
23884
|
// src/commands/status.js
|
|
22902
23885
|
init_src3();
|
|
22903
23886
|
var import_child_process11 = require("child_process");
|
|
22904
|
-
var
|
|
22905
|
-
var
|
|
22906
|
-
var
|
|
23887
|
+
var import_fs24 = __toESM(require("fs"), 1);
|
|
23888
|
+
var import_path21 = __toESM(require("path"), 1);
|
|
23889
|
+
var import_os8 = __toESM(require("os"), 1);
|
|
22907
23890
|
var AGENTS = [
|
|
22908
23891
|
{
|
|
22909
23892
|
id: "claude",
|
|
@@ -22948,8 +23931,8 @@ var BINARIES = [
|
|
|
22948
23931
|
{ id: "jq", name: "jq", command: "jq", versionFlag: "--version" }
|
|
22949
23932
|
];
|
|
22950
23933
|
function fileExists(filePath) {
|
|
22951
|
-
const resolved = filePath.replace("~",
|
|
22952
|
-
return
|
|
23934
|
+
const resolved = filePath.replace("~", import_os8.default.homedir());
|
|
23935
|
+
return import_fs24.default.existsSync(resolved);
|
|
22953
23936
|
}
|
|
22954
23937
|
function checkKeychain(service) {
|
|
22955
23938
|
if (process.platform !== "darwin") return false;
|
|
@@ -22977,13 +23960,13 @@ function getVersion2(command, versionFlag) {
|
|
|
22977
23960
|
}
|
|
22978
23961
|
function findBinary(command, kind = "binary") {
|
|
22979
23962
|
const rudiPaths = [
|
|
22980
|
-
|
|
22981
|
-
|
|
22982
|
-
|
|
22983
|
-
|
|
23963
|
+
import_path21.default.join(PATHS.agents, command, "node_modules", ".bin", command),
|
|
23964
|
+
import_path21.default.join(PATHS.runtimes, command, "bin", command),
|
|
23965
|
+
import_path21.default.join(PATHS.binaries, command, command),
|
|
23966
|
+
import_path21.default.join(PATHS.binaries, command)
|
|
22984
23967
|
];
|
|
22985
23968
|
for (const p of rudiPaths) {
|
|
22986
|
-
if (
|
|
23969
|
+
if (import_fs24.default.existsSync(p)) {
|
|
22987
23970
|
return { found: true, path: p, source: "rudi" };
|
|
22988
23971
|
}
|
|
22989
23972
|
}
|
|
@@ -23001,8 +23984,8 @@ function findBinary(command, kind = "binary") {
|
|
|
23001
23984
|
return { found: false, path: null, source: null };
|
|
23002
23985
|
}
|
|
23003
23986
|
function getAgentStatus(agent) {
|
|
23004
|
-
const rudiPath =
|
|
23005
|
-
const rudiInstalled =
|
|
23987
|
+
const rudiPath = import_path21.default.join(PATHS.agents, agent.id, "node_modules", ".bin", agent.id);
|
|
23988
|
+
const rudiInstalled = import_fs24.default.existsSync(rudiPath);
|
|
23006
23989
|
let globalPath = null;
|
|
23007
23990
|
let globalInstalled = false;
|
|
23008
23991
|
if (!rudiInstalled) {
|
|
@@ -23084,12 +24067,12 @@ async function getFullStatus() {
|
|
|
23084
24067
|
} catch {
|
|
23085
24068
|
}
|
|
23086
24069
|
const directories = {
|
|
23087
|
-
home: { path: PATHS.home, exists:
|
|
23088
|
-
stacks: { path: PATHS.stacks, exists:
|
|
23089
|
-
agents: { path: PATHS.agents, exists:
|
|
23090
|
-
runtimes: { path: PATHS.runtimes, exists:
|
|
23091
|
-
binaries: { path: PATHS.binaries, exists:
|
|
23092
|
-
db: { path: PATHS.db, exists:
|
|
24070
|
+
home: { path: PATHS.home, exists: import_fs24.default.existsSync(PATHS.home) },
|
|
24071
|
+
stacks: { path: PATHS.stacks, exists: import_fs24.default.existsSync(PATHS.stacks) },
|
|
24072
|
+
agents: { path: PATHS.agents, exists: import_fs24.default.existsSync(PATHS.agents) },
|
|
24073
|
+
runtimes: { path: PATHS.runtimes, exists: import_fs24.default.existsSync(PATHS.runtimes) },
|
|
24074
|
+
binaries: { path: PATHS.binaries, exists: import_fs24.default.existsSync(PATHS.binaries) },
|
|
24075
|
+
db: { path: PATHS.db, exists: import_fs24.default.existsSync(PATHS.db) }
|
|
23093
24076
|
};
|
|
23094
24077
|
const summary = {
|
|
23095
24078
|
agentsInstalled: agents.filter((a) => a.installed).length,
|
|
@@ -23197,9 +24180,9 @@ async function cmdStatus(args, flags) {
|
|
|
23197
24180
|
// src/commands/check.js
|
|
23198
24181
|
init_src3();
|
|
23199
24182
|
var import_child_process12 = require("child_process");
|
|
23200
|
-
var
|
|
23201
|
-
var
|
|
23202
|
-
var
|
|
24183
|
+
var import_fs25 = __toESM(require("fs"), 1);
|
|
24184
|
+
var import_path22 = __toESM(require("path"), 1);
|
|
24185
|
+
var import_os9 = __toESM(require("os"), 1);
|
|
23203
24186
|
var AGENT_CREDENTIALS = {
|
|
23204
24187
|
claude: { type: "keychain", service: "Claude Code-credentials" },
|
|
23205
24188
|
codex: { type: "file", path: "~/.codex/auth.json" },
|
|
@@ -23207,8 +24190,8 @@ var AGENT_CREDENTIALS = {
|
|
|
23207
24190
|
copilot: { type: "file", path: "~/.config/github-copilot/hosts.json" }
|
|
23208
24191
|
};
|
|
23209
24192
|
function fileExists2(filePath) {
|
|
23210
|
-
const resolved = filePath.replace("~",
|
|
23211
|
-
return
|
|
24193
|
+
const resolved = filePath.replace("~", import_os9.default.homedir());
|
|
24194
|
+
return import_fs25.default.existsSync(resolved);
|
|
23212
24195
|
}
|
|
23213
24196
|
function checkKeychain2(service) {
|
|
23214
24197
|
if (process.platform !== "darwin") return false;
|
|
@@ -23234,15 +24217,15 @@ function getVersion3(binaryPath, versionFlag = "--version") {
|
|
|
23234
24217
|
}
|
|
23235
24218
|
}
|
|
23236
24219
|
function detectKindFromFilesystem(name) {
|
|
23237
|
-
const agentPath =
|
|
23238
|
-
if (
|
|
23239
|
-
const runtimePath =
|
|
23240
|
-
if (
|
|
23241
|
-
const binaryPath =
|
|
23242
|
-
const binaryPath2 =
|
|
23243
|
-
if (
|
|
23244
|
-
const stackPath =
|
|
23245
|
-
if (
|
|
24220
|
+
const agentPath = import_path22.default.join(PATHS.agents, name, "node_modules", ".bin", name);
|
|
24221
|
+
if (import_fs25.default.existsSync(agentPath)) return "agent";
|
|
24222
|
+
const runtimePath = import_path22.default.join(PATHS.runtimes, name, "bin", name);
|
|
24223
|
+
if (import_fs25.default.existsSync(runtimePath)) return "runtime";
|
|
24224
|
+
const binaryPath = import_path22.default.join(PATHS.binaries, name, name);
|
|
24225
|
+
const binaryPath2 = import_path22.default.join(PATHS.binaries, name);
|
|
24226
|
+
if (import_fs25.default.existsSync(binaryPath) || import_fs25.default.existsSync(binaryPath2)) return "binary";
|
|
24227
|
+
const stackPath = import_path22.default.join(PATHS.stacks, name);
|
|
24228
|
+
if (import_fs25.default.existsSync(stackPath)) return "stack";
|
|
23246
24229
|
try {
|
|
23247
24230
|
const globalPath = (0, import_child_process12.execSync)(`which ${name} 2>/dev/null`, { encoding: "utf-8" }).trim();
|
|
23248
24231
|
if (globalPath) {
|
|
@@ -23288,8 +24271,8 @@ async function cmdCheck(args, flags) {
|
|
|
23288
24271
|
};
|
|
23289
24272
|
switch (kind) {
|
|
23290
24273
|
case "agent": {
|
|
23291
|
-
const rudiPath =
|
|
23292
|
-
const rudiInstalled =
|
|
24274
|
+
const rudiPath = import_path22.default.join(PATHS.agents, name, "node_modules", ".bin", name);
|
|
24275
|
+
const rudiInstalled = import_fs25.default.existsSync(rudiPath);
|
|
23293
24276
|
let globalPath = null;
|
|
23294
24277
|
let globalInstalled = false;
|
|
23295
24278
|
if (!rudiInstalled) {
|
|
@@ -23320,8 +24303,8 @@ async function cmdCheck(args, flags) {
|
|
|
23320
24303
|
break;
|
|
23321
24304
|
}
|
|
23322
24305
|
case "runtime": {
|
|
23323
|
-
const rudiPath =
|
|
23324
|
-
if (
|
|
24306
|
+
const rudiPath = import_path22.default.join(PATHS.runtimes, name, "bin", name);
|
|
24307
|
+
if (import_fs25.default.existsSync(rudiPath)) {
|
|
23325
24308
|
result.installed = true;
|
|
23326
24309
|
result.path = rudiPath;
|
|
23327
24310
|
result.version = getVersion3(rudiPath);
|
|
@@ -23340,8 +24323,8 @@ async function cmdCheck(args, flags) {
|
|
|
23340
24323
|
break;
|
|
23341
24324
|
}
|
|
23342
24325
|
case "binary": {
|
|
23343
|
-
const rudiPath =
|
|
23344
|
-
if (
|
|
24326
|
+
const rudiPath = import_path22.default.join(PATHS.binaries, name, name);
|
|
24327
|
+
if (import_fs25.default.existsSync(rudiPath)) {
|
|
23345
24328
|
result.installed = true;
|
|
23346
24329
|
result.path = rudiPath;
|
|
23347
24330
|
} else {
|
|
@@ -23395,27 +24378,27 @@ async function cmdCheck(args, flags) {
|
|
|
23395
24378
|
|
|
23396
24379
|
// src/commands/shims.js
|
|
23397
24380
|
init_src3();
|
|
23398
|
-
var
|
|
23399
|
-
var
|
|
24381
|
+
var import_fs26 = __toESM(require("fs"), 1);
|
|
24382
|
+
var import_path23 = __toESM(require("path"), 1);
|
|
23400
24383
|
function listShims2() {
|
|
23401
24384
|
const binsDir = PATHS.bins;
|
|
23402
|
-
if (!
|
|
24385
|
+
if (!import_fs26.default.existsSync(binsDir)) {
|
|
23403
24386
|
return [];
|
|
23404
24387
|
}
|
|
23405
|
-
const entries =
|
|
24388
|
+
const entries = import_fs26.default.readdirSync(binsDir);
|
|
23406
24389
|
return entries.filter((entry) => {
|
|
23407
|
-
const fullPath =
|
|
23408
|
-
const stat =
|
|
24390
|
+
const fullPath = import_path23.default.join(binsDir, entry);
|
|
24391
|
+
const stat = import_fs26.default.lstatSync(fullPath);
|
|
23409
24392
|
return stat.isFile() || stat.isSymbolicLink();
|
|
23410
24393
|
});
|
|
23411
24394
|
}
|
|
23412
24395
|
function getShimType(shimPath) {
|
|
23413
|
-
const stat =
|
|
24396
|
+
const stat = import_fs26.default.lstatSync(shimPath);
|
|
23414
24397
|
if (stat.isSymbolicLink()) {
|
|
23415
24398
|
return "symlink";
|
|
23416
24399
|
}
|
|
23417
24400
|
try {
|
|
23418
|
-
const content =
|
|
24401
|
+
const content = import_fs26.default.readFileSync(shimPath, "utf8");
|
|
23419
24402
|
if (content.includes("#!/usr/bin/env bash")) {
|
|
23420
24403
|
return "wrapper";
|
|
23421
24404
|
}
|
|
@@ -23426,14 +24409,14 @@ function getShimType(shimPath) {
|
|
|
23426
24409
|
function getShimTarget(name, shimPath, type) {
|
|
23427
24410
|
if (type === "symlink") {
|
|
23428
24411
|
try {
|
|
23429
|
-
return
|
|
24412
|
+
return import_fs26.default.readlinkSync(shimPath);
|
|
23430
24413
|
} catch (err) {
|
|
23431
24414
|
return null;
|
|
23432
24415
|
}
|
|
23433
24416
|
}
|
|
23434
24417
|
if (type === "wrapper") {
|
|
23435
24418
|
try {
|
|
23436
|
-
const content =
|
|
24419
|
+
const content = import_fs26.default.readFileSync(shimPath, "utf8");
|
|
23437
24420
|
const match = content.match(/exec "([^"]+)"/);
|
|
23438
24421
|
return match ? match[1] : null;
|
|
23439
24422
|
} catch (err) {
|
|
@@ -23455,18 +24438,18 @@ function getPackageFromShim(shimName, target) {
|
|
|
23455
24438
|
return `${kindMap[kind]}:${pkgName}`;
|
|
23456
24439
|
}
|
|
23457
24440
|
const manifestDirs = [
|
|
23458
|
-
|
|
23459
|
-
|
|
23460
|
-
|
|
24441
|
+
import_path23.default.join(PATHS.binaries),
|
|
24442
|
+
import_path23.default.join(PATHS.runtimes),
|
|
24443
|
+
import_path23.default.join(PATHS.agents)
|
|
23461
24444
|
];
|
|
23462
24445
|
for (const dir of manifestDirs) {
|
|
23463
|
-
if (!
|
|
23464
|
-
const packages =
|
|
24446
|
+
if (!import_fs26.default.existsSync(dir)) continue;
|
|
24447
|
+
const packages = import_fs26.default.readdirSync(dir);
|
|
23465
24448
|
for (const pkg of packages) {
|
|
23466
|
-
const manifestPath =
|
|
23467
|
-
if (
|
|
24449
|
+
const manifestPath = import_path23.default.join(dir, pkg, "manifest.json");
|
|
24450
|
+
if (import_fs26.default.existsSync(manifestPath)) {
|
|
23468
24451
|
try {
|
|
23469
|
-
const manifest = JSON.parse(
|
|
24452
|
+
const manifest = JSON.parse(import_fs26.default.readFileSync(manifestPath, "utf8"));
|
|
23470
24453
|
const bins = manifest.bins || manifest.binaries || [manifest.name || pkg];
|
|
23471
24454
|
if (bins.includes(shimName)) {
|
|
23472
24455
|
const kind = dir.includes("binaries") ? "binary" : dir.includes("runtimes") ? "runtime" : "agent";
|
|
@@ -23514,7 +24497,7 @@ async function cmdShims(args, flags) {
|
|
|
23514
24497
|
const results = [];
|
|
23515
24498
|
let hasIssues = false;
|
|
23516
24499
|
for (const name of shimNames) {
|
|
23517
|
-
const shimPath =
|
|
24500
|
+
const shimPath = import_path23.default.join(PATHS.bins, name);
|
|
23518
24501
|
const validation = validateShim(name);
|
|
23519
24502
|
const type = getShimType(shimPath);
|
|
23520
24503
|
const target = getShimTarget(name, shimPath, type);
|
|
@@ -23567,30 +24550,151 @@ ${valid} valid, ${broken} broken`);
|
|
|
23567
24550
|
}
|
|
23568
24551
|
if (subcommand === "fix") {
|
|
23569
24552
|
console.log("\n\x1B[33mAttempting to fix broken shims...\x1B[0m\n");
|
|
23570
|
-
const
|
|
23571
|
-
const
|
|
23572
|
-
|
|
23573
|
-
|
|
23574
|
-
|
|
24553
|
+
const brokenWithPkg = results.filter((r) => !r.valid && r.package);
|
|
24554
|
+
const orphaned = results.filter((r) => !r.valid && !r.package);
|
|
24555
|
+
if (orphaned.length > 0) {
|
|
24556
|
+
console.log(`Removing ${orphaned.length} orphaned shims...`);
|
|
24557
|
+
for (const shim of orphaned) {
|
|
24558
|
+
const shimPath = import_path23.default.join(PATHS.bins, shim.name);
|
|
24559
|
+
try {
|
|
24560
|
+
import_fs26.default.unlinkSync(shimPath);
|
|
24561
|
+
console.log(` \x1B[32m\u2713\x1B[0m Removed ${shim.name}`);
|
|
24562
|
+
} catch (err) {
|
|
24563
|
+
console.log(` \x1B[31m\u2717\x1B[0m Failed to remove ${shim.name}: ${err.message}`);
|
|
24564
|
+
}
|
|
23575
24565
|
}
|
|
23576
|
-
|
|
23577
|
-
|
|
24566
|
+
console.log("");
|
|
24567
|
+
}
|
|
24568
|
+
const brokenPackages = new Set(brokenWithPkg.map((r) => r.package));
|
|
24569
|
+
if (brokenPackages.size === 0 && orphaned.length === 0) {
|
|
23578
24570
|
console.log("No broken shims to fix.");
|
|
23579
24571
|
process.exit(0);
|
|
23580
24572
|
}
|
|
23581
|
-
|
|
23582
|
-
|
|
23583
|
-
|
|
23584
|
-
|
|
23585
|
-
|
|
23586
|
-
|
|
23587
|
-
|
|
24573
|
+
if (brokenPackages.size > 0) {
|
|
24574
|
+
const { installPackage: installPackage2 } = await Promise.resolve().then(() => (init_src3(), src_exports));
|
|
24575
|
+
for (const pkg of brokenPackages) {
|
|
24576
|
+
console.log(`Reinstalling ${pkg}...`);
|
|
24577
|
+
try {
|
|
24578
|
+
await installPackage2(pkg, { force: true });
|
|
24579
|
+
console.log(`\x1B[32m\u2713\x1B[0m Fixed ${pkg}`);
|
|
24580
|
+
} catch (err) {
|
|
24581
|
+
console.log(`\x1B[31m\u2717\x1B[0m Failed to fix ${pkg}: ${err.message}`);
|
|
24582
|
+
}
|
|
23588
24583
|
}
|
|
23589
24584
|
}
|
|
24585
|
+
console.log("\n\x1B[32m\u2713\x1B[0m Fix complete");
|
|
23590
24586
|
}
|
|
23591
24587
|
process.exit(hasIssues ? 1 : 0);
|
|
23592
24588
|
}
|
|
23593
24589
|
|
|
24590
|
+
// src/commands/info.js
|
|
24591
|
+
var import_fs27 = __toESM(require("fs"), 1);
|
|
24592
|
+
var import_path24 = __toESM(require("path"), 1);
|
|
24593
|
+
init_src3();
|
|
24594
|
+
async function cmdInfo(args, flags) {
|
|
24595
|
+
const pkgId = args[0];
|
|
24596
|
+
if (!pkgId) {
|
|
24597
|
+
console.error("Usage: rudi info <package>");
|
|
24598
|
+
console.error("Example: rudi info npm:typescript");
|
|
24599
|
+
console.error(" rudi info binary:supabase");
|
|
24600
|
+
process.exit(1);
|
|
24601
|
+
}
|
|
24602
|
+
try {
|
|
24603
|
+
const [kind, name] = parsePackageId2(pkgId);
|
|
24604
|
+
const installPath = getPackagePath2(pkgId);
|
|
24605
|
+
if (!import_fs27.default.existsSync(installPath)) {
|
|
24606
|
+
console.error(`Package not installed: ${pkgId}`);
|
|
24607
|
+
process.exit(1);
|
|
24608
|
+
}
|
|
24609
|
+
const manifestPath = import_path24.default.join(installPath, "manifest.json");
|
|
24610
|
+
let manifest = null;
|
|
24611
|
+
if (import_fs27.default.existsSync(manifestPath)) {
|
|
24612
|
+
try {
|
|
24613
|
+
manifest = JSON.parse(import_fs27.default.readFileSync(manifestPath, "utf-8"));
|
|
24614
|
+
} catch {
|
|
24615
|
+
console.warn("Warning: Could not parse manifest.json");
|
|
24616
|
+
}
|
|
24617
|
+
}
|
|
24618
|
+
console.log(`
|
|
24619
|
+
Package: ${pkgId}`);
|
|
24620
|
+
console.log("\u2500".repeat(50));
|
|
24621
|
+
console.log(` Name: ${manifest?.name || name}`);
|
|
24622
|
+
console.log(` Kind: ${kind}`);
|
|
24623
|
+
console.log(` Version: ${manifest?.version || "unknown"}`);
|
|
24624
|
+
console.log(` Install Dir: ${installPath}`);
|
|
24625
|
+
const installType = manifest?.installType || (manifest?.npmPackage ? "npm" : manifest?.pipPackage ? "pip" : kind);
|
|
24626
|
+
console.log(` Install Type: ${installType}`);
|
|
24627
|
+
if (manifest?.source) {
|
|
24628
|
+
if (typeof manifest.source === "string") {
|
|
24629
|
+
console.log(` Source: ${manifest.source}`);
|
|
24630
|
+
} else {
|
|
24631
|
+
console.log(` Source: ${manifest.source.type || "unknown"}`);
|
|
24632
|
+
if (manifest.source.spec) {
|
|
24633
|
+
console.log(` Spec: ${manifest.source.spec}`);
|
|
24634
|
+
}
|
|
24635
|
+
}
|
|
24636
|
+
}
|
|
24637
|
+
if (manifest?.npmPackage) {
|
|
24638
|
+
console.log(` npm Package: ${manifest.npmPackage}`);
|
|
24639
|
+
}
|
|
24640
|
+
if (manifest?.pipPackage) {
|
|
24641
|
+
console.log(` pip Package: ${manifest.pipPackage}`);
|
|
24642
|
+
}
|
|
24643
|
+
if (manifest?.hasInstallScripts !== void 0) {
|
|
24644
|
+
console.log(` Has Install Scripts: ${manifest.hasInstallScripts ? "yes" : "no"}`);
|
|
24645
|
+
}
|
|
24646
|
+
if (manifest?.scriptsPolicy) {
|
|
24647
|
+
console.log(` Scripts Policy: ${manifest.scriptsPolicy}`);
|
|
24648
|
+
}
|
|
24649
|
+
if (manifest?.installedAt) {
|
|
24650
|
+
console.log(` Installed: ${new Date(manifest.installedAt).toLocaleString()}`);
|
|
24651
|
+
}
|
|
24652
|
+
const bins = manifest?.bins || manifest?.binaries || [];
|
|
24653
|
+
if (bins.length > 0) {
|
|
24654
|
+
console.log(`
|
|
24655
|
+
Binaries (${bins.length}):`);
|
|
24656
|
+
console.log("\u2500".repeat(50));
|
|
24657
|
+
for (const bin of bins) {
|
|
24658
|
+
const shimPath = import_path24.default.join(PATHS2.bins, bin);
|
|
24659
|
+
const validation = validateShim(bin);
|
|
24660
|
+
const ownership = getShimOwner(bin);
|
|
24661
|
+
let shimStatus = "\u2717 no shim";
|
|
24662
|
+
if (import_fs27.default.existsSync(shimPath)) {
|
|
24663
|
+
if (validation.valid) {
|
|
24664
|
+
shimStatus = `\u2713 ${validation.target}`;
|
|
24665
|
+
} else {
|
|
24666
|
+
shimStatus = `\u26A0 broken: ${validation.error}`;
|
|
24667
|
+
}
|
|
24668
|
+
}
|
|
24669
|
+
console.log(` ${bin}:`);
|
|
24670
|
+
console.log(` Shim: ${shimStatus}`);
|
|
24671
|
+
if (ownership) {
|
|
24672
|
+
const ownerMatch = ownership.owner === pkgId;
|
|
24673
|
+
const ownerStatus = ownerMatch ? "(this package)" : `(owned by ${ownership.owner})`;
|
|
24674
|
+
console.log(` Type: ${ownership.type} ${ownerStatus}`);
|
|
24675
|
+
}
|
|
24676
|
+
}
|
|
24677
|
+
} else {
|
|
24678
|
+
console.log(`
|
|
24679
|
+
Binaries: none`);
|
|
24680
|
+
}
|
|
24681
|
+
const lockName = name.replace(/\//g, "__").replace(/^@/, "");
|
|
24682
|
+
const lockDir = kind === "binary" ? "binaries" : kind === "npm" ? "npms" : kind + "s";
|
|
24683
|
+
const lockPath = import_path24.default.join(PATHS2.locks, lockDir, `${lockName}.lock.yaml`);
|
|
24684
|
+
if (import_fs27.default.existsSync(lockPath)) {
|
|
24685
|
+
console.log(`
|
|
24686
|
+
Lockfile: ${lockPath}`);
|
|
24687
|
+
}
|
|
24688
|
+
console.log("");
|
|
24689
|
+
} catch (error) {
|
|
24690
|
+
console.error(`Error: ${error.message}`);
|
|
24691
|
+
if (flags.verbose) {
|
|
24692
|
+
console.error(error.stack);
|
|
24693
|
+
}
|
|
24694
|
+
process.exit(1);
|
|
24695
|
+
}
|
|
24696
|
+
}
|
|
24697
|
+
|
|
23594
24698
|
// src/index.js
|
|
23595
24699
|
var VERSION = "2.0.0";
|
|
23596
24700
|
async function main() {
|
|
@@ -23686,6 +24790,10 @@ async function main() {
|
|
|
23686
24790
|
case "shims":
|
|
23687
24791
|
await cmdShims(args, flags);
|
|
23688
24792
|
break;
|
|
24793
|
+
case "pkg":
|
|
24794
|
+
case "package":
|
|
24795
|
+
await cmdInfo(args, flags);
|
|
24796
|
+
break;
|
|
23689
24797
|
// Shortcuts for listing specific package types
|
|
23690
24798
|
case "stacks":
|
|
23691
24799
|
await cmdList(["stacks"], flags);
|