rudel 0.2.0 → 0.2.1
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/dist/cli.js +87 -54
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
2
|
var __create = Object.create;
|
|
4
3
|
var __getProtoOf = Object.getPrototypeOf;
|
|
5
4
|
var __defProp = Object.defineProperty;
|
|
@@ -26,7 +25,6 @@ var __export = (target, all) => {
|
|
|
26
25
|
set: (newValue) => all[name] = () => newValue
|
|
27
26
|
});
|
|
28
27
|
};
|
|
29
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
30
28
|
|
|
31
29
|
// ../../node_modules/sisteransi/src/index.js
|
|
32
30
|
var require_src = __commonJS((exports, module) => {
|
|
@@ -1889,7 +1887,7 @@ async function run(app, inputs, context) {
|
|
|
1889
1887
|
// package.json
|
|
1890
1888
|
var package_default = {
|
|
1891
1889
|
name: "rudel",
|
|
1892
|
-
version: "0.2.
|
|
1890
|
+
version: "0.2.1",
|
|
1893
1891
|
type: "module",
|
|
1894
1892
|
description: "CLI for the Coding Agent Analytics Platform rudel.ai",
|
|
1895
1893
|
license: "MIT",
|
|
@@ -7795,7 +7793,8 @@ function exec(cmd, args) {
|
|
|
7795
7793
|
|
|
7796
7794
|
// src/lib/git-info.ts
|
|
7797
7795
|
function normalizeRemoteUrl(url) {
|
|
7798
|
-
|
|
7796
|
+
const sanitizedUrl = url.replace(/^([a-z][a-z\d+.-]*:\/\/)[^/]+@/i, "$1");
|
|
7797
|
+
return sanitizedUrl.replace(/^(https?:\/\/|git@|ssh:\/\/)/, "").replace(/:/, "/").replace(/\.git$/, "");
|
|
7799
7798
|
}
|
|
7800
7799
|
async function getGitInfo(cwd) {
|
|
7801
7800
|
const [remoteUrl, branch, sha, packageInfo] = await Promise.all([
|
|
@@ -7919,15 +7918,43 @@ async function getGitSha(cwd) {
|
|
|
7919
7918
|
|
|
7920
7919
|
// src/lib/remote-cache.ts
|
|
7921
7920
|
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
|
|
7922
|
-
import {
|
|
7921
|
+
import { join as join8 } from "node:path";
|
|
7922
|
+
|
|
7923
|
+
// src/lib/local-state.ts
|
|
7924
|
+
import { chmod, mkdir, writeFile } from "node:fs/promises";
|
|
7923
7925
|
import { homedir as homedir5 } from "node:os";
|
|
7924
7926
|
import { dirname as dirname3, join as join7 } from "node:path";
|
|
7925
|
-
var
|
|
7927
|
+
var PRIVATE_DIRECTORY_MODE = 448;
|
|
7928
|
+
var PRIVATE_FILE_MODE = 384;
|
|
7929
|
+
function getRudelConfigDir() {
|
|
7930
|
+
return process.env.RUDEL_CONFIG_DIR ?? join7(homedir5(), ".rudel");
|
|
7931
|
+
}
|
|
7932
|
+
async function ensurePrivateFile(filePath, configDir) {
|
|
7933
|
+
await secureDirectory(configDir);
|
|
7934
|
+
const fileDirectory = dirname3(filePath);
|
|
7935
|
+
if (fileDirectory !== configDir) {
|
|
7936
|
+
await secureDirectory(fileDirectory);
|
|
7937
|
+
}
|
|
7938
|
+
await writeFile(filePath, "", { flag: "a", mode: PRIVATE_FILE_MODE });
|
|
7939
|
+
await chmod(filePath, PRIVATE_FILE_MODE);
|
|
7940
|
+
}
|
|
7941
|
+
async function writePrivateFile(filePath, content, configDir) {
|
|
7942
|
+
await ensurePrivateFile(filePath, configDir);
|
|
7943
|
+
await writeFile(filePath, content, "utf8");
|
|
7944
|
+
}
|
|
7945
|
+
async function secureDirectory(path) {
|
|
7946
|
+
await mkdir(path, { recursive: true, mode: PRIVATE_DIRECTORY_MODE });
|
|
7947
|
+
await chmod(path, PRIVATE_DIRECTORY_MODE);
|
|
7948
|
+
}
|
|
7949
|
+
|
|
7950
|
+
// src/lib/remote-cache.ts
|
|
7926
7951
|
async function getRemoteCache() {
|
|
7927
7952
|
try {
|
|
7928
|
-
|
|
7953
|
+
const path = getRemoteCachePath();
|
|
7954
|
+
if (!existsSync5(path))
|
|
7929
7955
|
return {};
|
|
7930
|
-
|
|
7956
|
+
await ensurePrivateFile(path, getRudelConfigDir());
|
|
7957
|
+
return JSON.parse(readFileSync4(path, "utf-8"));
|
|
7931
7958
|
} catch {
|
|
7932
7959
|
return {};
|
|
7933
7960
|
}
|
|
@@ -7940,10 +7967,12 @@ function cacheRemote(cache, encodedDir, normalizedRemote) {
|
|
|
7940
7967
|
}
|
|
7941
7968
|
async function cacheRemotes(cache) {
|
|
7942
7969
|
try {
|
|
7943
|
-
await
|
|
7944
|
-
await writeFile(CACHE_PATH, JSON.stringify(cache));
|
|
7970
|
+
await writePrivateFile(getRemoteCachePath(), JSON.stringify(cache), getRudelConfigDir());
|
|
7945
7971
|
} catch {}
|
|
7946
7972
|
}
|
|
7973
|
+
function getRemoteCachePath() {
|
|
7974
|
+
return join8(getRudelConfigDir(), "remote-cache.json");
|
|
7975
|
+
}
|
|
7947
7976
|
|
|
7948
7977
|
// src/lib/project-grouping.ts
|
|
7949
7978
|
async function scanAndGroupProjects(cwd = process.cwd()) {
|
|
@@ -11827,12 +11856,12 @@ import {
|
|
|
11827
11856
|
writeFileSync as writeFileSync3
|
|
11828
11857
|
} from "node:fs";
|
|
11829
11858
|
import { homedir as homedir7 } from "node:os";
|
|
11830
|
-
import { join as
|
|
11859
|
+
import { join as join9 } from "node:path";
|
|
11831
11860
|
function getConfigDir() {
|
|
11832
|
-
return process.env.RUDEL_CONFIG_DIR ??
|
|
11861
|
+
return process.env.RUDEL_CONFIG_DIR ?? join9(homedir7(), ".rudel");
|
|
11833
11862
|
}
|
|
11834
11863
|
function getCredentialsPath() {
|
|
11835
|
-
return
|
|
11864
|
+
return join9(getConfigDir(), "credentials.json");
|
|
11836
11865
|
}
|
|
11837
11866
|
function saveCredentials(credentials) {
|
|
11838
11867
|
const dir = getConfigDir();
|
|
@@ -13875,12 +13904,9 @@ var pMapSkip = Symbol("skip");
|
|
|
13875
13904
|
|
|
13876
13905
|
// src/lib/failed-uploads.ts
|
|
13877
13906
|
import { existsSync as existsSync7, readFileSync as readFileSync6 } from "node:fs";
|
|
13878
|
-
import {
|
|
13879
|
-
import { homedir as homedir8 } from "node:os";
|
|
13880
|
-
import { dirname as dirname4, join as join9 } from "node:path";
|
|
13907
|
+
import { join as join10 } from "node:path";
|
|
13881
13908
|
function getFailedUploadsPath() {
|
|
13882
|
-
|
|
13883
|
-
return join9(configDir, "failed-uploads.json");
|
|
13909
|
+
return join10(getRudelConfigDir(), "failed-uploads.json");
|
|
13884
13910
|
}
|
|
13885
13911
|
function normalizeSource(raw) {
|
|
13886
13912
|
if (typeof raw !== "string")
|
|
@@ -13894,6 +13920,7 @@ async function loadFailedUploads() {
|
|
|
13894
13920
|
const path = getFailedUploadsPath();
|
|
13895
13921
|
if (!existsSync7(path))
|
|
13896
13922
|
return [];
|
|
13923
|
+
await ensurePrivateFile(path, getRudelConfigDir());
|
|
13897
13924
|
const data = JSON.parse(readFileSync6(path, "utf-8"));
|
|
13898
13925
|
return data.failures.map((f) => ({
|
|
13899
13926
|
...f,
|
|
@@ -13906,9 +13933,8 @@ async function loadFailedUploads() {
|
|
|
13906
13933
|
async function saveFailedUploads(failures) {
|
|
13907
13934
|
try {
|
|
13908
13935
|
const path = getFailedUploadsPath();
|
|
13909
|
-
await mkdir2(dirname4(path), { recursive: true });
|
|
13910
13936
|
const data = { failures };
|
|
13911
|
-
await
|
|
13937
|
+
await writePrivateFile(path, JSON.stringify(data, null, 2), getRudelConfigDir());
|
|
13912
13938
|
} catch {}
|
|
13913
13939
|
}
|
|
13914
13940
|
async function recordFailedUpload(failure) {
|
|
@@ -14392,11 +14418,11 @@ function renderBatchSummary(summary, options) {
|
|
|
14392
14418
|
// src/lib/product-analytics.ts
|
|
14393
14419
|
import { randomUUID } from "node:crypto";
|
|
14394
14420
|
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "node:fs";
|
|
14395
|
-
import { homedir as
|
|
14396
|
-
import { join as
|
|
14421
|
+
import { homedir as homedir8 } from "node:os";
|
|
14422
|
+
import { join as join11 } from "node:path";
|
|
14397
14423
|
|
|
14398
14424
|
// ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
14399
|
-
import { dirname as
|
|
14425
|
+
import { dirname as dirname4, posix, sep } from "path";
|
|
14400
14426
|
function createModulerModifier() {
|
|
14401
14427
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
14402
14428
|
return async (frames) => {
|
|
@@ -14405,7 +14431,7 @@ function createModulerModifier() {
|
|
|
14405
14431
|
return frames;
|
|
14406
14432
|
};
|
|
14407
14433
|
}
|
|
14408
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ?
|
|
14434
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname4(process.argv[1]) : process.cwd(), isWindows = sep === "\\") {
|
|
14409
14435
|
const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
|
|
14410
14436
|
return (filename) => {
|
|
14411
14437
|
if (!filename)
|
|
@@ -18865,10 +18891,10 @@ function getClient() {
|
|
|
18865
18891
|
return client;
|
|
18866
18892
|
}
|
|
18867
18893
|
function getConfigDir2() {
|
|
18868
|
-
return process.env.RUDEL_CONFIG_DIR ??
|
|
18894
|
+
return process.env.RUDEL_CONFIG_DIR ?? join11(homedir8(), ".rudel");
|
|
18869
18895
|
}
|
|
18870
18896
|
function getAnalyticsStatePath() {
|
|
18871
|
-
return
|
|
18897
|
+
return join11(getConfigDir2(), ANALYTICS_STATE_FILE);
|
|
18872
18898
|
}
|
|
18873
18899
|
function readAnalyticsState() {
|
|
18874
18900
|
const statePath = getAnalyticsStatePath();
|
|
@@ -19021,30 +19047,37 @@ function getBaseCliEventPayload() {
|
|
|
19021
19047
|
var CliProductAnalyticsEvents = PRODUCT_ANALYTICS_EVENTS;
|
|
19022
19048
|
|
|
19023
19049
|
// src/lib/project-config.ts
|
|
19024
|
-
import {
|
|
19025
|
-
|
|
19026
|
-
|
|
19050
|
+
import {
|
|
19051
|
+
chmodSync,
|
|
19052
|
+
existsSync as existsSync9,
|
|
19053
|
+
mkdirSync as mkdirSync4,
|
|
19054
|
+
readFileSync as readFileSync8,
|
|
19055
|
+
writeFileSync as writeFileSync5
|
|
19056
|
+
} from "node:fs";
|
|
19057
|
+
import { homedir as homedir9 } from "node:os";
|
|
19058
|
+
import { join as join12 } from "node:path";
|
|
19027
19059
|
function getConfigDir3() {
|
|
19028
|
-
return process.env.RUDEL_CONFIG_DIR ??
|
|
19060
|
+
return process.env.RUDEL_CONFIG_DIR ?? join12(homedir9(), ".rudel");
|
|
19029
19061
|
}
|
|
19030
19062
|
function getProjectsConfigPath() {
|
|
19031
|
-
return
|
|
19063
|
+
return join12(getConfigDir3(), "projects.json");
|
|
19032
19064
|
}
|
|
19033
19065
|
function loadProjectsConfig() {
|
|
19034
19066
|
const path = getProjectsConfigPath();
|
|
19035
19067
|
if (!existsSync9(path))
|
|
19036
19068
|
return { projects: {} };
|
|
19069
|
+
chmodSync(getConfigDir3(), 448);
|
|
19070
|
+
chmodSync(path, 384);
|
|
19037
19071
|
const content = readFileSync8(path, "utf-8");
|
|
19038
19072
|
return JSON.parse(content);
|
|
19039
19073
|
}
|
|
19040
19074
|
function saveProjectsConfig(config) {
|
|
19041
19075
|
const dir = getConfigDir3();
|
|
19042
|
-
|
|
19043
|
-
|
|
19044
|
-
|
|
19045
|
-
writeFileSync5(
|
|
19046
|
-
|
|
19047
|
-
});
|
|
19076
|
+
mkdirSync4(dir, { recursive: true, mode: 448 });
|
|
19077
|
+
chmodSync(dir, 448);
|
|
19078
|
+
const path = getProjectsConfigPath();
|
|
19079
|
+
writeFileSync5(path, JSON.stringify(config, null, 2), { mode: 384 });
|
|
19080
|
+
chmodSync(path, 384);
|
|
19048
19081
|
}
|
|
19049
19082
|
async function getProjectKey(cwd) {
|
|
19050
19083
|
try {
|
|
@@ -19057,7 +19090,9 @@ async function getProjectKey(cwd) {
|
|
|
19057
19090
|
]);
|
|
19058
19091
|
if (result.exitCode === 0) {
|
|
19059
19092
|
const url = result.stdout.trim();
|
|
19060
|
-
|
|
19093
|
+
if (url.length > 0) {
|
|
19094
|
+
return normalizeRemoteUrl(url);
|
|
19095
|
+
}
|
|
19061
19096
|
}
|
|
19062
19097
|
} catch {}
|
|
19063
19098
|
try {
|
|
@@ -20919,8 +20954,7 @@ async function reportHookUploadFailure(logger2, result, failure) {
|
|
|
20919
20954
|
}
|
|
20920
20955
|
|
|
20921
20956
|
// src/logging.ts
|
|
20922
|
-
import {
|
|
20923
|
-
import { join as join13 } from "node:path";
|
|
20957
|
+
import { join as join14 } from "node:path";
|
|
20924
20958
|
|
|
20925
20959
|
// ../../node_modules/@logtape/file/dist/filesink.base.js
|
|
20926
20960
|
var AdaptiveFlushStrategy = class {
|
|
@@ -21186,7 +21220,7 @@ function getBaseFileSink(path, options) {
|
|
|
21186
21220
|
|
|
21187
21221
|
// ../../node_modules/@logtape/file/dist/filesink.node.js
|
|
21188
21222
|
import fs from "node:fs";
|
|
21189
|
-
import { join as
|
|
21223
|
+
import { join as join13 } from "node:path";
|
|
21190
21224
|
import { promisify } from "node:util";
|
|
21191
21225
|
var nodeDriver = {
|
|
21192
21226
|
openSync(path) {
|
|
@@ -21226,14 +21260,14 @@ var nodeTimeDriver = {
|
|
|
21226
21260
|
readdirSync: fs.readdirSync,
|
|
21227
21261
|
unlinkSync: fs.unlinkSync,
|
|
21228
21262
|
mkdirSync: fs.mkdirSync,
|
|
21229
|
-
joinPath:
|
|
21263
|
+
joinPath: join13
|
|
21230
21264
|
};
|
|
21231
21265
|
var nodeAsyncTimeDriver = {
|
|
21232
21266
|
...nodeAsyncDriver,
|
|
21233
21267
|
readdirSync: fs.readdirSync,
|
|
21234
21268
|
unlinkSync: fs.unlinkSync,
|
|
21235
21269
|
mkdirSync: fs.mkdirSync,
|
|
21236
|
-
joinPath:
|
|
21270
|
+
joinPath: join13
|
|
21237
21271
|
};
|
|
21238
21272
|
function getFileSink(path, options = {}) {
|
|
21239
21273
|
if (options.nonBlocking)
|
|
@@ -21248,14 +21282,13 @@ function getFileSink(path, options = {}) {
|
|
|
21248
21282
|
}
|
|
21249
21283
|
|
|
21250
21284
|
// src/logging.ts
|
|
21251
|
-
var LOG_DIR = join13(homedir11(), ".rudel", "logs");
|
|
21252
|
-
var LOG_FILE = join13(LOG_DIR, "hook-upload.log");
|
|
21253
21285
|
async function setupHookLogging() {
|
|
21254
|
-
const
|
|
21255
|
-
|
|
21286
|
+
const configDir = getRudelConfigDir();
|
|
21287
|
+
const logFile = join14(configDir, "logs", "hook-upload.log");
|
|
21288
|
+
await ensurePrivateFile(logFile, configDir);
|
|
21256
21289
|
await configure({
|
|
21257
21290
|
sinks: {
|
|
21258
|
-
file: getFileSink(
|
|
21291
|
+
file: getFileSink(logFile)
|
|
21259
21292
|
},
|
|
21260
21293
|
loggers: [
|
|
21261
21294
|
{
|
|
@@ -21924,9 +21957,9 @@ function execWithStdin(cmd, args, stdin) {
|
|
|
21924
21957
|
|
|
21925
21958
|
// src/lib/session-resolver.ts
|
|
21926
21959
|
import { access, readdir as readdir3 } from "node:fs/promises";
|
|
21927
|
-
import { homedir as
|
|
21928
|
-
import { basename, dirname as
|
|
21929
|
-
var SESSIONS_BASE_DIR3 =
|
|
21960
|
+
import { homedir as homedir10 } from "node:os";
|
|
21961
|
+
import { basename, dirname as dirname5, join as join15 } from "node:path";
|
|
21962
|
+
var SESSIONS_BASE_DIR3 = join15(homedir10(), ".claude", "projects");
|
|
21930
21963
|
async function resolveSession(input) {
|
|
21931
21964
|
const isPath = input.includes("/") || input.endsWith(".jsonl");
|
|
21932
21965
|
if (isPath) {
|
|
@@ -21943,7 +21976,7 @@ async function resolveFromPath(filePath) {
|
|
|
21943
21976
|
throw new Error(`Session file not found: ${filePath}`);
|
|
21944
21977
|
}
|
|
21945
21978
|
const sessionId = filename.replace(/\.jsonl$/, "");
|
|
21946
|
-
const sessionDir =
|
|
21979
|
+
const sessionDir = dirname5(filePath);
|
|
21947
21980
|
const parentDir = basename(sessionDir);
|
|
21948
21981
|
const projectPath = await decodeProjectPath(parentDir);
|
|
21949
21982
|
return { transcriptPath: filePath, projectPath, sessionDir, sessionId };
|
|
@@ -21958,11 +21991,11 @@ async function resolveFromId(sessionId) {
|
|
|
21958
21991
|
throw new Error(`Session not found: ${sessionId}`);
|
|
21959
21992
|
}
|
|
21960
21993
|
for (const projectDir of projectDirs) {
|
|
21961
|
-
const sessionDir =
|
|
21994
|
+
const sessionDir = join15(SESSIONS_BASE_DIR3, projectDir);
|
|
21962
21995
|
try {
|
|
21963
21996
|
const files = await readdir3(sessionDir);
|
|
21964
21997
|
if (files.includes(sessionFileName)) {
|
|
21965
|
-
const transcriptPath =
|
|
21998
|
+
const transcriptPath = join15(sessionDir, sessionFileName);
|
|
21966
21999
|
const projectPath = await decodeProjectPath(projectDir);
|
|
21967
22000
|
return {
|
|
21968
22001
|
transcriptPath,
|