rudel 0.1.8 → 0.1.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/dist/cli.js +385 -242
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1959,7 +1959,7 @@ async function run(app, inputs, context) {
|
|
|
1959
1959
|
// package.json
|
|
1960
1960
|
var package_default = {
|
|
1961
1961
|
name: "rudel",
|
|
1962
|
-
version: "0.1.
|
|
1962
|
+
version: "0.1.9",
|
|
1963
1963
|
type: "module",
|
|
1964
1964
|
description: "CLI for the Coding Agent Analytics Platform rudel.ai",
|
|
1965
1965
|
license: "MIT",
|
|
@@ -6132,16 +6132,6 @@ function toDisplayPath(absolutePath) {
|
|
|
6132
6132
|
const home = homedir();
|
|
6133
6133
|
return absolutePath.startsWith(home) ? `~${absolutePath.slice(home.length)}` : absolutePath;
|
|
6134
6134
|
}
|
|
6135
|
-
function groupProjectsForCwd(projects, cwd) {
|
|
6136
|
-
const current = projects.filter((p) => p.projectPath === cwd);
|
|
6137
|
-
const currentSet = new Set(current);
|
|
6138
|
-
const subfolders = projects.filter((p) => !currentSet.has(p) && p.projectPath.startsWith(`${cwd}/`));
|
|
6139
|
-
const subfoldersSet = new Set(subfolders);
|
|
6140
|
-
const others = projects.filter((p) => !currentSet.has(p) && !subfoldersSet.has(p));
|
|
6141
|
-
subfolders.sort((a, b) => a.projectPath.localeCompare(b.projectPath));
|
|
6142
|
-
others.sort((a, b) => a.displayPath.localeCompare(b.displayPath));
|
|
6143
|
-
return { current, subfolders, others };
|
|
6144
|
-
}
|
|
6145
6135
|
|
|
6146
6136
|
// ../../packages/agent-adapters/src/adapters/claude-code/settings.ts
|
|
6147
6137
|
import { execSync } from "child_process";
|
|
@@ -7778,33 +7768,314 @@ function getAvailableAdapters() {
|
|
|
7778
7768
|
registerAdapter(claudeCodeAdapter);
|
|
7779
7769
|
registerAdapter(codexAdapter);
|
|
7780
7770
|
|
|
7781
|
-
// src/
|
|
7782
|
-
|
|
7771
|
+
// src/lib/project-grouping.ts
|
|
7772
|
+
import { homedir as homedir6 } from "os";
|
|
7773
|
+
|
|
7774
|
+
// src/lib/git-info.ts
|
|
7775
|
+
import { join as join6 } from "path";
|
|
7776
|
+
var {$ } = globalThis.Bun;
|
|
7777
|
+
function normalizeRemoteUrl(url) {
|
|
7778
|
+
return url.replace(/^(https?:\/\/|git@|ssh:\/\/)/, "").replace(/:/, "/").replace(/\.git$/, "");
|
|
7779
|
+
}
|
|
7780
|
+
async function getGitInfo(cwd) {
|
|
7781
|
+
const [remoteUrl, branch, sha, packageInfo] = await Promise.all([
|
|
7782
|
+
getGitRemoteUrl(cwd),
|
|
7783
|
+
getGitBranch(cwd),
|
|
7784
|
+
getGitSha(cwd),
|
|
7785
|
+
getPackageInfo(cwd)
|
|
7786
|
+
]);
|
|
7787
|
+
const gitRemote = remoteUrl ? normalizeRemoteUrl(remoteUrl) : undefined;
|
|
7788
|
+
return {
|
|
7789
|
+
gitRemote,
|
|
7790
|
+
packageName: packageInfo?.name,
|
|
7791
|
+
packageType: packageInfo?.type,
|
|
7792
|
+
branch: branch ?? undefined,
|
|
7793
|
+
sha: sha ?? undefined
|
|
7794
|
+
};
|
|
7795
|
+
}
|
|
7796
|
+
async function getPackageInfo(cwd) {
|
|
7797
|
+
try {
|
|
7798
|
+
const gitRootResult = await $`git -C ${cwd} rev-parse --show-toplevel`.quiet();
|
|
7799
|
+
const root = gitRootResult.exitCode === 0 ? gitRootResult.text().trim() : cwd;
|
|
7800
|
+
return await getNodePackage(root) ?? await getPythonPackage(root) ?? await getRustPackage(root) ?? await getGoModule(root);
|
|
7801
|
+
} catch {
|
|
7802
|
+
return null;
|
|
7803
|
+
}
|
|
7804
|
+
}
|
|
7805
|
+
async function getNodePackage(root) {
|
|
7806
|
+
try {
|
|
7807
|
+
const file = Bun.file(join6(root, "package.json"));
|
|
7808
|
+
if (!await file.exists())
|
|
7809
|
+
return null;
|
|
7810
|
+
const pkg = await file.json();
|
|
7811
|
+
return pkg.name ? { name: pkg.name, type: "package.json" } : null;
|
|
7812
|
+
} catch {
|
|
7813
|
+
return null;
|
|
7814
|
+
}
|
|
7815
|
+
}
|
|
7816
|
+
async function getPythonPackage(root) {
|
|
7817
|
+
try {
|
|
7818
|
+
const file = Bun.file(join6(root, "pyproject.toml"));
|
|
7819
|
+
if (!await file.exists())
|
|
7820
|
+
return null;
|
|
7821
|
+
const content = await file.text();
|
|
7822
|
+
const name = content.match(/^\s*name\s*=\s*"([^"]+)"/m)?.[1];
|
|
7823
|
+
return name ? { name, type: "pyproject.toml" } : null;
|
|
7824
|
+
} catch {
|
|
7825
|
+
return null;
|
|
7826
|
+
}
|
|
7827
|
+
}
|
|
7828
|
+
async function getRustPackage(root) {
|
|
7829
|
+
try {
|
|
7830
|
+
const file = Bun.file(join6(root, "Cargo.toml"));
|
|
7831
|
+
if (!await file.exists())
|
|
7832
|
+
return null;
|
|
7833
|
+
const content = await file.text();
|
|
7834
|
+
const name = content.match(/^\s*name\s*=\s*"([^"]+)"/m)?.[1];
|
|
7835
|
+
return name ? { name, type: "Cargo.toml" } : null;
|
|
7836
|
+
} catch {
|
|
7837
|
+
return null;
|
|
7838
|
+
}
|
|
7839
|
+
}
|
|
7840
|
+
async function getGoModule(root) {
|
|
7841
|
+
try {
|
|
7842
|
+
const file = Bun.file(join6(root, "go.mod"));
|
|
7843
|
+
if (!await file.exists())
|
|
7844
|
+
return null;
|
|
7845
|
+
const content = await file.text();
|
|
7846
|
+
const name = content.match(/^module\s+(\S+)/m)?.[1];
|
|
7847
|
+
return name ? { name, type: "go.mod" } : null;
|
|
7848
|
+
} catch {
|
|
7849
|
+
return null;
|
|
7850
|
+
}
|
|
7851
|
+
}
|
|
7852
|
+
async function getGitRemoteUrl(cwd) {
|
|
7853
|
+
try {
|
|
7854
|
+
const result = await $`git -C ${cwd} remote get-url origin`.quiet();
|
|
7855
|
+
if (result.exitCode !== 0)
|
|
7856
|
+
return null;
|
|
7857
|
+
return result.text().trim() || null;
|
|
7858
|
+
} catch {
|
|
7859
|
+
return null;
|
|
7860
|
+
}
|
|
7861
|
+
}
|
|
7862
|
+
async function getGitBranch(cwd) {
|
|
7863
|
+
try {
|
|
7864
|
+
const result = await $`git -C ${cwd} rev-parse --abbrev-ref HEAD`.quiet();
|
|
7865
|
+
if (result.exitCode !== 0)
|
|
7866
|
+
return null;
|
|
7867
|
+
return result.text().trim();
|
|
7868
|
+
} catch {
|
|
7869
|
+
return null;
|
|
7870
|
+
}
|
|
7871
|
+
}
|
|
7872
|
+
async function getGitSha(cwd) {
|
|
7873
|
+
try {
|
|
7874
|
+
const result = await $`git -C ${cwd} rev-parse HEAD`.quiet();
|
|
7875
|
+
if (result.exitCode !== 0)
|
|
7876
|
+
return null;
|
|
7877
|
+
return result.text().trim();
|
|
7878
|
+
} catch {
|
|
7879
|
+
return null;
|
|
7880
|
+
}
|
|
7881
|
+
}
|
|
7882
|
+
|
|
7883
|
+
// src/lib/remote-cache.ts
|
|
7884
|
+
import { homedir as homedir5 } from "os";
|
|
7885
|
+
import { join as join7 } from "path";
|
|
7886
|
+
var CACHE_PATH = join7(homedir5(), ".rudel", "remote-cache.json");
|
|
7887
|
+
async function getRemoteCache() {
|
|
7888
|
+
try {
|
|
7889
|
+
const file = Bun.file(CACHE_PATH);
|
|
7890
|
+
if (!await file.exists())
|
|
7891
|
+
return {};
|
|
7892
|
+
return await file.json();
|
|
7893
|
+
} catch {
|
|
7894
|
+
return {};
|
|
7895
|
+
}
|
|
7896
|
+
}
|
|
7897
|
+
function getCachedRemote(cache, encodedDir) {
|
|
7898
|
+
return cache[encodedDir] ?? null;
|
|
7899
|
+
}
|
|
7900
|
+
function cacheRemote(cache, encodedDir, normalizedRemote) {
|
|
7901
|
+
cache[encodedDir] = normalizedRemote;
|
|
7902
|
+
}
|
|
7903
|
+
async function cacheRemotes(cache) {
|
|
7904
|
+
try {
|
|
7905
|
+
const { mkdir } = await import("fs/promises");
|
|
7906
|
+
const { dirname: dirname3 } = await import("path");
|
|
7907
|
+
await mkdir(dirname3(CACHE_PATH), { recursive: true });
|
|
7908
|
+
await Bun.write(CACHE_PATH, JSON.stringify(cache));
|
|
7909
|
+
} catch {}
|
|
7910
|
+
}
|
|
7911
|
+
|
|
7912
|
+
// src/lib/project-grouping.ts
|
|
7913
|
+
async function scanAndGroupProjects(cwd = process.cwd()) {
|
|
7783
7914
|
const adapters2 = getAvailableAdapters();
|
|
7784
|
-
const
|
|
7915
|
+
const projects = [];
|
|
7785
7916
|
for (const adapter of adapters2) {
|
|
7786
|
-
const
|
|
7787
|
-
|
|
7917
|
+
const scanned = await adapter.scanAllSessions();
|
|
7918
|
+
projects.push(...scanned);
|
|
7919
|
+
}
|
|
7920
|
+
const groups = await groupProjectsByRemote(projects, cwd);
|
|
7921
|
+
return { projects, groups };
|
|
7922
|
+
}
|
|
7923
|
+
function extractDisplayName(normalized) {
|
|
7924
|
+
const parts = normalized.split("/");
|
|
7925
|
+
if (parts.length >= 3) {
|
|
7926
|
+
return parts.slice(1).join("/");
|
|
7927
|
+
}
|
|
7928
|
+
return normalized;
|
|
7929
|
+
}
|
|
7930
|
+
function encodeProjectPath2(projectPath) {
|
|
7931
|
+
return projectPath.replace(/\//g, "-");
|
|
7932
|
+
}
|
|
7933
|
+
async function groupProjectsByRemote(projects, cwd) {
|
|
7934
|
+
const cache = await getRemoteCache();
|
|
7935
|
+
let cacheUpdated = false;
|
|
7936
|
+
const remotes = await Promise.all(projects.map((p) => getGitRemoteUrl(p.projectPath)));
|
|
7937
|
+
const grouped = new Map;
|
|
7938
|
+
const ungrouped = [];
|
|
7939
|
+
for (let i = 0;i < projects.length; i++) {
|
|
7940
|
+
const project = projects[i];
|
|
7941
|
+
const remote = remotes[i];
|
|
7942
|
+
if (remote) {
|
|
7943
|
+
const normalized = normalizeRemoteUrl(remote);
|
|
7944
|
+
const encodedDir = encodeProjectPath2(project.projectPath);
|
|
7945
|
+
if (getCachedRemote(cache, encodedDir) !== normalized) {
|
|
7946
|
+
cacheRemote(cache, encodedDir, normalized);
|
|
7947
|
+
cacheUpdated = true;
|
|
7948
|
+
}
|
|
7949
|
+
const existing = grouped.get(normalized);
|
|
7950
|
+
if (existing) {
|
|
7951
|
+
existing.projects.push(project);
|
|
7952
|
+
} else {
|
|
7953
|
+
grouped.set(normalized, { remote: normalized, projects: [project] });
|
|
7954
|
+
}
|
|
7955
|
+
} else {
|
|
7956
|
+
const encodedDir = encodeProjectPath2(project.projectPath);
|
|
7957
|
+
const cached = getCachedRemote(cache, encodedDir);
|
|
7958
|
+
if (cached) {
|
|
7959
|
+
const existing = grouped.get(cached);
|
|
7960
|
+
if (existing) {
|
|
7961
|
+
existing.projects.push(project);
|
|
7962
|
+
} else {
|
|
7963
|
+
grouped.set(cached, { remote: cached, projects: [project] });
|
|
7964
|
+
}
|
|
7965
|
+
} else {
|
|
7966
|
+
ungrouped.push(project);
|
|
7967
|
+
}
|
|
7968
|
+
}
|
|
7788
7969
|
}
|
|
7970
|
+
const groups = [];
|
|
7971
|
+
for (const [, entry] of grouped) {
|
|
7972
|
+
const containsCwd = entry.projects.some((p) => cwd === p.projectPath || cwd.startsWith(`${p.projectPath}/`));
|
|
7973
|
+
groups.push({
|
|
7974
|
+
displayName: extractDisplayName(entry.remote),
|
|
7975
|
+
gitRemote: entry.remote,
|
|
7976
|
+
projects: entry.projects,
|
|
7977
|
+
totalSessions: entry.projects.reduce((s, p) => s + p.sessionCount, 0),
|
|
7978
|
+
containsCwd
|
|
7979
|
+
});
|
|
7980
|
+
}
|
|
7981
|
+
const homeSegments = homedir6().split("/").length;
|
|
7982
|
+
const remainingUngrouped = [];
|
|
7983
|
+
for (const project of ungrouped) {
|
|
7984
|
+
const match = findBestGroupByPath(project, groups, homeSegments);
|
|
7985
|
+
if (match) {
|
|
7986
|
+
match.projects.push(project);
|
|
7987
|
+
match.totalSessions += project.sessionCount;
|
|
7988
|
+
if (cwd === project.projectPath || cwd.startsWith(`${project.projectPath}/`)) {
|
|
7989
|
+
match.containsCwd = true;
|
|
7990
|
+
}
|
|
7991
|
+
} else {
|
|
7992
|
+
remainingUngrouped.push(project);
|
|
7993
|
+
}
|
|
7994
|
+
}
|
|
7995
|
+
for (const project of remainingUngrouped) {
|
|
7996
|
+
const containsCwd = cwd === project.projectPath || cwd.startsWith(`${project.projectPath}/`);
|
|
7997
|
+
groups.push({
|
|
7998
|
+
displayName: project.displayPath,
|
|
7999
|
+
gitRemote: null,
|
|
8000
|
+
projects: [project],
|
|
8001
|
+
totalSessions: project.sessionCount,
|
|
8002
|
+
containsCwd
|
|
8003
|
+
});
|
|
8004
|
+
}
|
|
8005
|
+
groups.sort((a, b) => {
|
|
8006
|
+
if (a.containsCwd !== b.containsCwd)
|
|
8007
|
+
return a.containsCwd ? -1 : 1;
|
|
8008
|
+
const aHasRemote = a.gitRemote !== null;
|
|
8009
|
+
const bHasRemote = b.gitRemote !== null;
|
|
8010
|
+
if (aHasRemote !== bHasRemote)
|
|
8011
|
+
return aHasRemote ? -1 : 1;
|
|
8012
|
+
return a.displayName.localeCompare(b.displayName);
|
|
8013
|
+
});
|
|
8014
|
+
if (cacheUpdated) {
|
|
8015
|
+
cacheRemotes(cache);
|
|
8016
|
+
}
|
|
8017
|
+
return groups;
|
|
8018
|
+
}
|
|
8019
|
+
function commonPrefixLength(a, b) {
|
|
8020
|
+
const partsA = a.split("/");
|
|
8021
|
+
const partsB = b.split("/");
|
|
8022
|
+
let count = 0;
|
|
8023
|
+
for (let i = 0;i < Math.min(partsA.length, partsB.length); i++) {
|
|
8024
|
+
if (partsA[i] === partsB[i])
|
|
8025
|
+
count++;
|
|
8026
|
+
else
|
|
8027
|
+
break;
|
|
8028
|
+
}
|
|
8029
|
+
return count;
|
|
8030
|
+
}
|
|
8031
|
+
function findBestGroupByPath(project, groups, homeSegments) {
|
|
8032
|
+
let bestGroup = null;
|
|
8033
|
+
let bestLen = 0;
|
|
8034
|
+
let secondBestLen = 0;
|
|
8035
|
+
for (const group2 of groups) {
|
|
8036
|
+
if (!group2.gitRemote)
|
|
8037
|
+
continue;
|
|
8038
|
+
let groupBest = 0;
|
|
8039
|
+
for (const p of group2.projects) {
|
|
8040
|
+
groupBest = Math.max(groupBest, commonPrefixLength(project.projectPath, p.projectPath));
|
|
8041
|
+
}
|
|
8042
|
+
if (groupBest > bestLen) {
|
|
8043
|
+
secondBestLen = bestLen;
|
|
8044
|
+
bestLen = groupBest;
|
|
8045
|
+
bestGroup = group2;
|
|
8046
|
+
} else if (groupBest > secondBestLen) {
|
|
8047
|
+
secondBestLen = groupBest;
|
|
8048
|
+
}
|
|
8049
|
+
}
|
|
8050
|
+
if (bestGroup && bestLen > homeSegments && bestLen > secondBestLen) {
|
|
8051
|
+
return bestGroup;
|
|
8052
|
+
}
|
|
8053
|
+
return null;
|
|
8054
|
+
}
|
|
8055
|
+
|
|
8056
|
+
// src/commands/dev/list-sessions.ts
|
|
8057
|
+
async function runListSessions() {
|
|
8058
|
+
const { projects: allProjects, groups } = await scanAndGroupProjects();
|
|
7789
8059
|
if (allProjects.length === 0) {
|
|
7790
8060
|
console.log("No projects with sessions found.");
|
|
7791
8061
|
return;
|
|
7792
8062
|
}
|
|
7793
|
-
const cwd = process.cwd();
|
|
7794
|
-
const grouped = groupProjectsForCwd(allProjects, cwd);
|
|
7795
8063
|
const lines = [];
|
|
7796
|
-
for (const
|
|
7797
|
-
const
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
const
|
|
7807
|
-
|
|
8064
|
+
for (const group2 of groups) {
|
|
8065
|
+
const isCurrent = group2.containsCwd ? " [current]" : "";
|
|
8066
|
+
if (group2.projects.length === 1) {
|
|
8067
|
+
const proj = group2.projects[0];
|
|
8068
|
+
const name = getAdapter(proj.source).name;
|
|
8069
|
+
lines.push(`[${name}] ${proj.displayPath} (${proj.sessionCount} sessions)${isCurrent}`);
|
|
8070
|
+
continue;
|
|
8071
|
+
}
|
|
8072
|
+
const totalSessions2 = group2.projects.reduce((s, p) => s + p.sessionCount, 0);
|
|
8073
|
+
lines.push(`${group2.displayName} (${group2.projects.length} projects, ${totalSessions2} sessions)${isCurrent}`);
|
|
8074
|
+
for (const proj of group2.projects) {
|
|
8075
|
+
const name = getAdapter(proj.source).name;
|
|
8076
|
+
const cwdMarker = proj.projectPath === process.cwd() ? " [cwd]" : "";
|
|
8077
|
+
lines.push(` [${name}] ${proj.displayPath} (${proj.sessionCount} sessions)${cwdMarker}`);
|
|
8078
|
+
}
|
|
7808
8079
|
}
|
|
7809
8080
|
const totalSessions = allProjects.reduce((s, p) => s + p.sessionCount, 0);
|
|
7810
8081
|
console.log(`${allProjects.length} projects, ${totalSessions} sessions
|
|
@@ -7863,8 +8134,8 @@ var X = (t, e = {}, s = {}) => {
|
|
|
7863
8134
|
const ut = t.slice(C, w) || t.slice(h, o);
|
|
7864
8135
|
v = 0;
|
|
7865
8136
|
for (const Y of ut.replaceAll(ct, "")) {
|
|
7866
|
-
const $ = Y.codePointAt(0) || 0;
|
|
7867
|
-
if (lt($) ? f = m : ht($) ? f = V : E !== A && at($) ? f = E : f = A, c + f > b && (d = Math.min(d, Math.max(C, h) + v)), c + f > i) {
|
|
8137
|
+
const $2 = Y.codePointAt(0) || 0;
|
|
8138
|
+
if (lt($2) ? f = m : ht($2) ? f = V : E !== A && at($2) ? f = E : f = A, c + f > b && (d = Math.min(d, Math.max(C, h) + v)), c + f > i) {
|
|
7868
8139
|
F = true;
|
|
7869
8140
|
break t;
|
|
7870
8141
|
}
|
|
@@ -8501,15 +8772,15 @@ var Fe = /\p{M}+/gu;
|
|
|
8501
8772
|
var ye = { limit: 1 / 0, ellipsis: "" };
|
|
8502
8773
|
var jt = (t, r = {}, s = {}) => {
|
|
8503
8774
|
const i = r.limit ?? 1 / 0, a = r.ellipsis ?? "", o = r?.ellipsisWidth ?? (a ? jt(a, ye, s).width : 0), u = s.ansiWidth ?? 0, l = s.controlWidth ?? 0, n = s.tabWidth ?? 8, c = s.ambiguousWidth ?? 1, g = s.emojiWidth ?? 2, F = s.fullWidthWidth ?? 2, p = s.regularWidth ?? 1, E = s.wideWidth ?? 2;
|
|
8504
|
-
let $ = 0, m = 0, h = t.length, y2 = 0, f = false, v = h, S2 = Math.max(0, i - o), I2 = 0, B2 = 0, A = 0, w = 0;
|
|
8775
|
+
let $2 = 0, m = 0, h = t.length, y2 = 0, f = false, v = h, S2 = Math.max(0, i - o), I2 = 0, B2 = 0, A = 0, w = 0;
|
|
8505
8776
|
t:
|
|
8506
8777
|
for (;; ) {
|
|
8507
|
-
if (B2 > I2 || m >= h && m > $) {
|
|
8508
|
-
const _2 = t.slice(I2, B2) || t.slice(
|
|
8778
|
+
if (B2 > I2 || m >= h && m > $2) {
|
|
8779
|
+
const _2 = t.slice(I2, B2) || t.slice($2, m);
|
|
8509
8780
|
y2 = 0;
|
|
8510
8781
|
for (const D2 of _2.replaceAll(Fe, "")) {
|
|
8511
8782
|
const T2 = D2.codePointAt(0) || 0;
|
|
8512
|
-
if (ge(T2) ? w = F : fe(T2) ? w = E : c !== p && pe(T2) ? w = c : w = p, A + w > S2 && (v = Math.min(v, Math.max(I2, $) + y2)), A + w > i) {
|
|
8783
|
+
if (ge(T2) ? w = F : fe(T2) ? w = E : c !== p && pe(T2) ? w = c : w = p, A + w > S2 && (v = Math.min(v, Math.max(I2, $2) + y2)), A + w > i) {
|
|
8513
8784
|
f = true;
|
|
8514
8785
|
break t;
|
|
8515
8786
|
}
|
|
@@ -8524,7 +8795,7 @@ var jt = (t, r = {}, s = {}) => {
|
|
|
8524
8795
|
f = true;
|
|
8525
8796
|
break;
|
|
8526
8797
|
}
|
|
8527
|
-
A += w, I2 =
|
|
8798
|
+
A += w, I2 = $2, B2 = m, m = $2 = at2.lastIndex;
|
|
8528
8799
|
continue;
|
|
8529
8800
|
}
|
|
8530
8801
|
if (At2.lastIndex = m, At2.test(t)) {
|
|
@@ -8532,7 +8803,7 @@ var jt = (t, r = {}, s = {}) => {
|
|
|
8532
8803
|
f = true;
|
|
8533
8804
|
break;
|
|
8534
8805
|
}
|
|
8535
|
-
A += u, I2 =
|
|
8806
|
+
A += u, I2 = $2, B2 = m, m = $2 = At2.lastIndex;
|
|
8536
8807
|
continue;
|
|
8537
8808
|
}
|
|
8538
8809
|
if (it2.lastIndex = m, it2.test(t)) {
|
|
@@ -8540,7 +8811,7 @@ var jt = (t, r = {}, s = {}) => {
|
|
|
8540
8811
|
f = true;
|
|
8541
8812
|
break;
|
|
8542
8813
|
}
|
|
8543
|
-
A += w, I2 =
|
|
8814
|
+
A += w, I2 = $2, B2 = m, m = $2 = it2.lastIndex;
|
|
8544
8815
|
continue;
|
|
8545
8816
|
}
|
|
8546
8817
|
if (nt2.lastIndex = m, nt2.test(t)) {
|
|
@@ -8548,7 +8819,7 @@ var jt = (t, r = {}, s = {}) => {
|
|
|
8548
8819
|
f = true;
|
|
8549
8820
|
break;
|
|
8550
8821
|
}
|
|
8551
|
-
A += w, I2 =
|
|
8822
|
+
A += w, I2 = $2, B2 = m, m = $2 = nt2.lastIndex;
|
|
8552
8823
|
continue;
|
|
8553
8824
|
}
|
|
8554
8825
|
if (wt2.lastIndex = m, wt2.test(t)) {
|
|
@@ -8556,7 +8827,7 @@ var jt = (t, r = {}, s = {}) => {
|
|
|
8556
8827
|
f = true;
|
|
8557
8828
|
break;
|
|
8558
8829
|
}
|
|
8559
|
-
A += g, I2 =
|
|
8830
|
+
A += g, I2 = $2, B2 = m, m = $2 = wt2.lastIndex;
|
|
8560
8831
|
continue;
|
|
8561
8832
|
}
|
|
8562
8833
|
m += 1;
|
|
@@ -8619,34 +8890,34 @@ var Ie = (t, r, s = {}) => {
|
|
|
8619
8890
|
let i = "", a, o;
|
|
8620
8891
|
const u = t.split(" "), l = Ce(u);
|
|
8621
8892
|
let n = [""];
|
|
8622
|
-
for (const [
|
|
8893
|
+
for (const [$2, m] of u.entries()) {
|
|
8623
8894
|
s.trim !== false && (n[n.length - 1] = (n.at(-1) ?? "").trimStart());
|
|
8624
8895
|
let h = M2(n.at(-1) ?? "");
|
|
8625
|
-
if ($ !== 0 && (h >= r && (s.wordWrap === false || s.trim === false) && (n.push(""), h = 0), (h > 0 || s.trim === false) && (n[n.length - 1] += " ", h++)), s.hard && l[$] > r) {
|
|
8626
|
-
const y2 = r - h, f = 1 + Math.floor((l[$] - y2 - 1) / r);
|
|
8627
|
-
Math.floor((l[$] - 1) / r) < f && n.push(""), It2(n, m, r);
|
|
8896
|
+
if ($2 !== 0 && (h >= r && (s.wordWrap === false || s.trim === false) && (n.push(""), h = 0), (h > 0 || s.trim === false) && (n[n.length - 1] += " ", h++)), s.hard && l[$2] > r) {
|
|
8897
|
+
const y2 = r - h, f = 1 + Math.floor((l[$2] - y2 - 1) / r);
|
|
8898
|
+
Math.floor((l[$2] - 1) / r) < f && n.push(""), It2(n, m, r);
|
|
8628
8899
|
continue;
|
|
8629
8900
|
}
|
|
8630
|
-
if (h + l[$] > r && h > 0 && l[$] > 0) {
|
|
8901
|
+
if (h + l[$2] > r && h > 0 && l[$2] > 0) {
|
|
8631
8902
|
if (s.wordWrap === false && h < r) {
|
|
8632
8903
|
It2(n, m, r);
|
|
8633
8904
|
continue;
|
|
8634
8905
|
}
|
|
8635
8906
|
n.push("");
|
|
8636
8907
|
}
|
|
8637
|
-
if (h + l[$] > r && s.wordWrap === false) {
|
|
8908
|
+
if (h + l[$2] > r && s.wordWrap === false) {
|
|
8638
8909
|
It2(n, m, r);
|
|
8639
8910
|
continue;
|
|
8640
8911
|
}
|
|
8641
8912
|
n[n.length - 1] += m;
|
|
8642
8913
|
}
|
|
8643
|
-
s.trim !== false && (n = n.map(($) => Se($)));
|
|
8914
|
+
s.trim !== false && (n = n.map(($2) => Se($2)));
|
|
8644
8915
|
const c = n.join(`
|
|
8645
8916
|
`), g = c[Symbol.iterator]();
|
|
8646
8917
|
let F = g.next(), p = g.next(), E = 0;
|
|
8647
8918
|
for (;!F.done; ) {
|
|
8648
|
-
const $ = F.value, m = p.value;
|
|
8649
|
-
if (i +=
|
|
8919
|
+
const $2 = F.value, m = p.value;
|
|
8920
|
+
if (i += $2, $2 === ot2 || $2 === Gt) {
|
|
8650
8921
|
Ht.lastIndex = E + 1;
|
|
8651
8922
|
const f = Ht.exec(c)?.groups;
|
|
8652
8923
|
if (f?.code !== undefined) {
|
|
@@ -8657,8 +8928,8 @@ var Ie = (t, r, s = {}) => {
|
|
|
8657
8928
|
}
|
|
8658
8929
|
const h = a ? we(a) : undefined;
|
|
8659
8930
|
m === `
|
|
8660
|
-
` ? (o && (i += Kt("")), a && h && (i += Ut(h))) : $ === `
|
|
8661
|
-
` && (a && h && (i += Ut(a)), o && (i += Kt(o))), E +=
|
|
8931
|
+
` ? (o && (i += Kt("")), a && h && (i += Ut(h))) : $2 === `
|
|
8932
|
+
` && (a && h && (i += Ut(a)), o && (i += Kt(o))), E += $2.length, F = p, p = g.next();
|
|
8662
8933
|
}
|
|
8663
8934
|
return i;
|
|
8664
8935
|
};
|
|
@@ -8680,13 +8951,13 @@ var be = (t, r, s, i, a) => {
|
|
|
8680
8951
|
};
|
|
8681
8952
|
var X2 = (t) => {
|
|
8682
8953
|
const { cursor: r, options: s, style: i } = t, a = t.output ?? process.stdout, o = rt(a), u = t.columnPadding ?? 0, l = t.rowPadding ?? 4, n = o - u, c = nt(a), g = import_picocolors2.default.dim("..."), F = t.maxItems ?? Number.POSITIVE_INFINITY, p = Math.max(c - l, 0), E = Math.max(Math.min(F, p), 5);
|
|
8683
|
-
let $ = 0;
|
|
8684
|
-
r >= E - 3 && ($ = Math.max(Math.min(r - E + 3, s.length - E), 0));
|
|
8685
|
-
let m = E < s.length && $ > 0, h = E < s.length && $ + E < s.length;
|
|
8686
|
-
const y2 = Math.min($ + E, s.length), f = [];
|
|
8954
|
+
let $2 = 0;
|
|
8955
|
+
r >= E - 3 && ($2 = Math.max(Math.min(r - E + 3, s.length - E), 0));
|
|
8956
|
+
let m = E < s.length && $2 > 0, h = E < s.length && $2 + E < s.length;
|
|
8957
|
+
const y2 = Math.min($2 + E, s.length), f = [];
|
|
8687
8958
|
let v = 0;
|
|
8688
8959
|
m && v++, h && v++;
|
|
8689
|
-
const S2 = $ + (m ? 1 : 0), I2 = y2 - (h ? 1 : 0);
|
|
8960
|
+
const S2 = $2 + (m ? 1 : 0), I2 = y2 - (h ? 1 : 0);
|
|
8690
8961
|
for (let A = S2;A < I2; A++) {
|
|
8691
8962
|
const w = J2(i(s[A], A === r), n, { hard: true, trim: false }).split(`
|
|
8692
8963
|
`);
|
|
@@ -8712,8 +8983,8 @@ function Yt(t, r, s, i) {
|
|
|
8712
8983
|
}
|
|
8713
8984
|
var Te = (t) => t;
|
|
8714
8985
|
var Me = (t = "", r = "", s) => {
|
|
8715
|
-
const i = s?.output ?? process.stdout, a = rt(i), o = 2, u = s?.titlePadding ?? 1, l = s?.contentPadding ?? 2, n = s?.width === undefined || s.width === "auto" ? 1 : Math.min(1, s.width), c = s?.withGuide ?? _.withGuide ? `${d} ` : "", g = s?.formatBorder ?? Te, F = ((s?.rounded) ? _e : De).map(g), p = g(rt2), E = g(d), $ = M2(c), m = M2(r), h = a -
|
|
8716
|
-
let y2 = Math.floor(a * n) -
|
|
8986
|
+
const i = s?.output ?? process.stdout, a = rt(i), o = 2, u = s?.titlePadding ?? 1, l = s?.contentPadding ?? 2, n = s?.width === undefined || s.width === "auto" ? 1 : Math.min(1, s.width), c = s?.withGuide ?? _.withGuide ? `${d} ` : "", g = s?.formatBorder ?? Te, F = ((s?.rounded) ? _e : De).map(g), p = g(rt2), E = g(d), $2 = M2(c), m = M2(r), h = a - $2;
|
|
8987
|
+
let y2 = Math.floor(a * n) - $2;
|
|
8717
8988
|
if (s?.width === "auto") {
|
|
8718
8989
|
const _2 = t.split(`
|
|
8719
8990
|
`);
|
|
@@ -8775,8 +9046,8 @@ var R2 = { message: (t = [], { symbol: r = import_picocolors2.default.gray(d), s
|
|
|
8775
9046
|
if (F.length > 0) {
|
|
8776
9047
|
const [p, ...E] = F;
|
|
8777
9048
|
p.length > 0 ? u.push(`${c}${p}`) : u.push(l ? r : "");
|
|
8778
|
-
for (const $ of E)
|
|
8779
|
-
|
|
9049
|
+
for (const $2 of E)
|
|
9050
|
+
$2.length > 0 ? u.push(`${g}${$2}`) : u.push(l ? s : "");
|
|
8780
9051
|
}
|
|
8781
9052
|
i.write(`${u.join(`
|
|
8782
9053
|
`)}
|
|
@@ -8868,7 +9139,7 @@ ${import_picocolors2.default.cyan(x2)}
|
|
|
8868
9139
|
var Ke = import_picocolors2.default.magenta;
|
|
8869
9140
|
var bt2 = ({ indicator: t = "dots", onCancel: r, output: s = process.stdout, cancelMessage: i, errorMessage: a, frames: o = et2 ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], delay: u = et2 ? 80 : 120, signal: l, ...n } = {}) => {
|
|
8870
9141
|
const c = ct2();
|
|
8871
|
-
let g, F, p = false, E = false, $ = "", m, h = performance.now();
|
|
9142
|
+
let g, F, p = false, E = false, $2 = "", m, h = performance.now();
|
|
8872
9143
|
const y2 = rt(s), f = n?.styleFrame ?? Ke, v = (b) => {
|
|
8873
9144
|
const O2 = b > 1 ? a ?? _.messages.error : i ?? _.messages.cancel;
|
|
8874
9145
|
E = b === 1, p && (L2(O2, b), E && typeof r == "function" && r());
|
|
@@ -8888,22 +9159,22 @@ var bt2 = ({ indicator: t = "dots", onCancel: r, output: s = process.stdout, can
|
|
|
8888
9159
|
const O2 = (performance.now() - b) / 1000, j2 = Math.floor(O2 / 60), G2 = Math.floor(O2 % 60);
|
|
8889
9160
|
return j2 > 0 ? `[${j2}m ${G2}s]` : `[${G2}s]`;
|
|
8890
9161
|
}, T2 = n.withGuide ?? _.withGuide, Y = (b = "") => {
|
|
8891
|
-
p = true, g = Bt({ output: s }), $ = _2(b), h = performance.now(), T2 && s.write(`${import_picocolors2.default.gray(d)}
|
|
9162
|
+
p = true, g = Bt({ output: s }), $2 = _2(b), h = performance.now(), T2 && s.write(`${import_picocolors2.default.gray(d)}
|
|
8892
9163
|
`);
|
|
8893
9164
|
let O2 = 0, j2 = 0;
|
|
8894
9165
|
B2(), F = setInterval(() => {
|
|
8895
|
-
if (c && $ === m)
|
|
9166
|
+
if (c && $2 === m)
|
|
8896
9167
|
return;
|
|
8897
|
-
w(), m =
|
|
9168
|
+
w(), m = $2;
|
|
8898
9169
|
const G2 = f(o[O2]);
|
|
8899
9170
|
let tt2;
|
|
8900
9171
|
if (c)
|
|
8901
|
-
tt2 = `${G2} ${$}...`;
|
|
9172
|
+
tt2 = `${G2} ${$2}...`;
|
|
8902
9173
|
else if (t === "timer")
|
|
8903
|
-
tt2 = `${G2} ${$} ${D2(h)}`;
|
|
9174
|
+
tt2 = `${G2} ${$2} ${D2(h)}`;
|
|
8904
9175
|
else {
|
|
8905
9176
|
const te = ".".repeat(Math.floor(j2)).slice(0, 3);
|
|
8906
|
-
tt2 = `${G2} ${$}${te}`;
|
|
9177
|
+
tt2 = `${G2} ${$2}${te}`;
|
|
8907
9178
|
}
|
|
8908
9179
|
const Zt = J2(tt2, y2, { hard: true, trim: false });
|
|
8909
9180
|
s.write(Zt), O2 = O2 + 1 < o.length ? O2 + 1 : 0, j2 = j2 < 4 ? j2 + 0.125 : 0;
|
|
@@ -8913,12 +9184,12 @@ var bt2 = ({ indicator: t = "dots", onCancel: r, output: s = process.stdout, can
|
|
|
8913
9184
|
return;
|
|
8914
9185
|
p = false, clearInterval(F), w();
|
|
8915
9186
|
const G2 = O2 === 0 ? import_picocolors2.default.green(V) : O2 === 1 ? import_picocolors2.default.red(dt2) : import_picocolors2.default.red($t2);
|
|
8916
|
-
$ = b ??
|
|
8917
|
-
`) : s.write(`${G2} ${$}
|
|
9187
|
+
$2 = b ?? $2, j2 || (t === "timer" ? s.write(`${G2} ${$2} ${D2(h)}
|
|
9188
|
+
`) : s.write(`${G2} ${$2}
|
|
8918
9189
|
`)), A(), g();
|
|
8919
9190
|
};
|
|
8920
9191
|
return { start: Y, stop: (b = "") => L2(b, 0), message: (b = "") => {
|
|
8921
|
-
$ = _2(b ?? $);
|
|
9192
|
+
$2 = _2(b ?? $2);
|
|
8922
9193
|
}, cancel: (b = "") => L2(b, 1), error: (b = "") => L2(b, 2), clear: () => L2("", 0, true), get isCancelled() {
|
|
8923
9194
|
return E;
|
|
8924
9195
|
} };
|
|
@@ -8940,13 +9211,13 @@ function qe({ style: t = "heavy", max: r = 100, size: s = 40, ...i } = {}) {
|
|
|
8940
9211
|
default:
|
|
8941
9212
|
return import_picocolors2.default.magenta;
|
|
8942
9213
|
}
|
|
8943
|
-
}, g = (E, $) => {
|
|
9214
|
+
}, g = (E, $2) => {
|
|
8944
9215
|
const m = Math.floor(o / l * n);
|
|
8945
|
-
return `${c(E)(zt[t].repeat(m))}${import_picocolors2.default.dim(zt[t].repeat(n - m))} ${$}`;
|
|
9216
|
+
return `${c(E)(zt[t].repeat(m))}${import_picocolors2.default.dim(zt[t].repeat(n - m))} ${$2}`;
|
|
8946
9217
|
}, F = (E = "") => {
|
|
8947
9218
|
u = E, a.start(g("initial", E));
|
|
8948
|
-
}, p = (E = 1, $) => {
|
|
8949
|
-
o = Math.min(l, E + o), a.message(g("active", $ ?? u)), u = $ ?? u;
|
|
9219
|
+
}, p = (E = 1, $2) => {
|
|
9220
|
+
o = Math.min(l, E + o), a.message(g("active", $2 ?? u)), u = $2 ?? u;
|
|
8950
9221
|
};
|
|
8951
9222
|
return { start: F, stop: a.stop, cancel: a.cancel, error: a.error, clear: a.clear, advance: p, isCancelled: a.isCancelled, message: (E) => p(0, E) };
|
|
8952
9223
|
}
|
|
@@ -10505,13 +10776,13 @@ import {
|
|
|
10505
10776
|
rmSync,
|
|
10506
10777
|
writeFileSync as writeFileSync3
|
|
10507
10778
|
} from "fs";
|
|
10508
|
-
import { homedir as
|
|
10509
|
-
import { join as
|
|
10779
|
+
import { homedir as homedir7 } from "os";
|
|
10780
|
+
import { join as join8 } from "path";
|
|
10510
10781
|
function getConfigDir() {
|
|
10511
|
-
return process.env.RUDEL_CONFIG_DIR ??
|
|
10782
|
+
return process.env.RUDEL_CONFIG_DIR ?? join8(homedir7(), ".rudel");
|
|
10512
10783
|
}
|
|
10513
10784
|
function getCredentialsPath() {
|
|
10514
|
-
return
|
|
10785
|
+
return join8(getConfigDir(), "credentials.json");
|
|
10515
10786
|
}
|
|
10516
10787
|
function saveCredentials(token, apiBaseUrl) {
|
|
10517
10788
|
const dir = getConfigDir();
|
|
@@ -10694,8 +10965,8 @@ async function pMap(iterable, mapper, {
|
|
|
10694
10965
|
var pMapSkip = Symbol("skip");
|
|
10695
10966
|
|
|
10696
10967
|
// src/lib/failed-uploads.ts
|
|
10697
|
-
import { homedir as
|
|
10698
|
-
import { join as
|
|
10968
|
+
import { homedir as homedir8 } from "os";
|
|
10969
|
+
import { join as join9 } from "path";
|
|
10699
10970
|
|
|
10700
10971
|
// ../../node_modules/.bun/@orpc+contract@1.13.6/node_modules/@orpc/contract/dist/shared/contract.D_dZrO__.mjs
|
|
10701
10972
|
function mergeErrorMap(errorMap1, errorMap2) {
|
|
@@ -11393,7 +11664,7 @@ var contract = {
|
|
|
11393
11664
|
};
|
|
11394
11665
|
|
|
11395
11666
|
// src/lib/failed-uploads.ts
|
|
11396
|
-
var FAILED_UPLOADS_PATH =
|
|
11667
|
+
var FAILED_UPLOADS_PATH = join9(homedir8(), ".rudel", "failed-uploads.json");
|
|
11397
11668
|
function normalizeSource(raw) {
|
|
11398
11669
|
if (typeof raw !== "string")
|
|
11399
11670
|
return;
|
|
@@ -11541,125 +11812,16 @@ function renderBatchSummary(summary, options) {
|
|
|
11541
11812
|
}
|
|
11542
11813
|
}
|
|
11543
11814
|
|
|
11544
|
-
// src/lib/git-info.ts
|
|
11545
|
-
import { join as join8 } from "path";
|
|
11546
|
-
var {$ } = globalThis.Bun;
|
|
11547
|
-
function normalizeRemoteUrl(url) {
|
|
11548
|
-
return url.replace(/^(https?:\/\/|git@|ssh:\/\/)/, "").replace(/:/, "/").replace(/\.git$/, "");
|
|
11549
|
-
}
|
|
11550
|
-
async function getGitInfo(cwd) {
|
|
11551
|
-
const [remoteUrl, branch, sha, packageInfo] = await Promise.all([
|
|
11552
|
-
getGitRemoteUrl(cwd),
|
|
11553
|
-
getGitBranch(cwd),
|
|
11554
|
-
getGitSha(cwd),
|
|
11555
|
-
getPackageInfo(cwd)
|
|
11556
|
-
]);
|
|
11557
|
-
const gitRemote = remoteUrl ? normalizeRemoteUrl(remoteUrl) : undefined;
|
|
11558
|
-
return {
|
|
11559
|
-
gitRemote,
|
|
11560
|
-
packageName: packageInfo?.name,
|
|
11561
|
-
packageType: packageInfo?.type,
|
|
11562
|
-
branch: branch ?? undefined,
|
|
11563
|
-
sha: sha ?? undefined
|
|
11564
|
-
};
|
|
11565
|
-
}
|
|
11566
|
-
async function getPackageInfo(cwd) {
|
|
11567
|
-
try {
|
|
11568
|
-
const gitRootResult = await $`git -C ${cwd} rev-parse --show-toplevel`.quiet();
|
|
11569
|
-
const root = gitRootResult.exitCode === 0 ? gitRootResult.text().trim() : cwd;
|
|
11570
|
-
return await getNodePackage(root) ?? await getPythonPackage(root) ?? await getRustPackage(root) ?? await getGoModule(root);
|
|
11571
|
-
} catch {
|
|
11572
|
-
return null;
|
|
11573
|
-
}
|
|
11574
|
-
}
|
|
11575
|
-
async function getNodePackage(root) {
|
|
11576
|
-
try {
|
|
11577
|
-
const file = Bun.file(join8(root, "package.json"));
|
|
11578
|
-
if (!await file.exists())
|
|
11579
|
-
return null;
|
|
11580
|
-
const pkg = await file.json();
|
|
11581
|
-
return pkg.name ? { name: pkg.name, type: "package.json" } : null;
|
|
11582
|
-
} catch {
|
|
11583
|
-
return null;
|
|
11584
|
-
}
|
|
11585
|
-
}
|
|
11586
|
-
async function getPythonPackage(root) {
|
|
11587
|
-
try {
|
|
11588
|
-
const file = Bun.file(join8(root, "pyproject.toml"));
|
|
11589
|
-
if (!await file.exists())
|
|
11590
|
-
return null;
|
|
11591
|
-
const content = await file.text();
|
|
11592
|
-
const name = content.match(/^\s*name\s*=\s*"([^"]+)"/m)?.[1];
|
|
11593
|
-
return name ? { name, type: "pyproject.toml" } : null;
|
|
11594
|
-
} catch {
|
|
11595
|
-
return null;
|
|
11596
|
-
}
|
|
11597
|
-
}
|
|
11598
|
-
async function getRustPackage(root) {
|
|
11599
|
-
try {
|
|
11600
|
-
const file = Bun.file(join8(root, "Cargo.toml"));
|
|
11601
|
-
if (!await file.exists())
|
|
11602
|
-
return null;
|
|
11603
|
-
const content = await file.text();
|
|
11604
|
-
const name = content.match(/^\s*name\s*=\s*"([^"]+)"/m)?.[1];
|
|
11605
|
-
return name ? { name, type: "Cargo.toml" } : null;
|
|
11606
|
-
} catch {
|
|
11607
|
-
return null;
|
|
11608
|
-
}
|
|
11609
|
-
}
|
|
11610
|
-
async function getGoModule(root) {
|
|
11611
|
-
try {
|
|
11612
|
-
const file = Bun.file(join8(root, "go.mod"));
|
|
11613
|
-
if (!await file.exists())
|
|
11614
|
-
return null;
|
|
11615
|
-
const content = await file.text();
|
|
11616
|
-
const name = content.match(/^module\s+(\S+)/m)?.[1];
|
|
11617
|
-
return name ? { name, type: "go.mod" } : null;
|
|
11618
|
-
} catch {
|
|
11619
|
-
return null;
|
|
11620
|
-
}
|
|
11621
|
-
}
|
|
11622
|
-
async function getGitRemoteUrl(cwd) {
|
|
11623
|
-
try {
|
|
11624
|
-
const result = await $`git -C ${cwd} remote get-url origin`.quiet();
|
|
11625
|
-
if (result.exitCode !== 0)
|
|
11626
|
-
return null;
|
|
11627
|
-
return result.text().trim() || null;
|
|
11628
|
-
} catch {
|
|
11629
|
-
return null;
|
|
11630
|
-
}
|
|
11631
|
-
}
|
|
11632
|
-
async function getGitBranch(cwd) {
|
|
11633
|
-
try {
|
|
11634
|
-
const result = await $`git -C ${cwd} rev-parse --abbrev-ref HEAD`.quiet();
|
|
11635
|
-
if (result.exitCode !== 0)
|
|
11636
|
-
return null;
|
|
11637
|
-
return result.text().trim();
|
|
11638
|
-
} catch {
|
|
11639
|
-
return null;
|
|
11640
|
-
}
|
|
11641
|
-
}
|
|
11642
|
-
async function getGitSha(cwd) {
|
|
11643
|
-
try {
|
|
11644
|
-
const result = await $`git -C ${cwd} rev-parse HEAD`.quiet();
|
|
11645
|
-
if (result.exitCode !== 0)
|
|
11646
|
-
return null;
|
|
11647
|
-
return result.text().trim();
|
|
11648
|
-
} catch {
|
|
11649
|
-
return null;
|
|
11650
|
-
}
|
|
11651
|
-
}
|
|
11652
|
-
|
|
11653
11815
|
// src/lib/project-config.ts
|
|
11654
11816
|
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
11655
|
-
import { homedir as
|
|
11656
|
-
import { join as
|
|
11817
|
+
import { homedir as homedir9 } from "os";
|
|
11818
|
+
import { join as join10 } from "path";
|
|
11657
11819
|
var {$: $2 } = globalThis.Bun;
|
|
11658
11820
|
function getConfigDir2() {
|
|
11659
|
-
return process.env.RUDEL_CONFIG_DIR ??
|
|
11821
|
+
return process.env.RUDEL_CONFIG_DIR ?? join10(homedir9(), ".rudel");
|
|
11660
11822
|
}
|
|
11661
11823
|
function getProjectsConfigPath() {
|
|
11662
|
-
return
|
|
11824
|
+
return join10(getConfigDir2(), "projects.json");
|
|
11663
11825
|
}
|
|
11664
11826
|
function loadProjectsConfig() {
|
|
11665
11827
|
const path = getProjectsConfigPath();
|
|
@@ -13503,8 +13665,8 @@ var ConfigError = class extends Error {
|
|
|
13503
13665
|
};
|
|
13504
13666
|
|
|
13505
13667
|
// src/logging.ts
|
|
13506
|
-
import { homedir as
|
|
13507
|
-
import { join as
|
|
13668
|
+
import { homedir as homedir10 } from "os";
|
|
13669
|
+
import { join as join12 } from "path";
|
|
13508
13670
|
|
|
13509
13671
|
// ../../node_modules/.bun/@logtape+file@2.0.4+2d5de51540e256d2/node_modules/@logtape/file/dist/filesink.base.js
|
|
13510
13672
|
var AdaptiveFlushStrategy = class {
|
|
@@ -13770,7 +13932,7 @@ function getBaseFileSink(path, options) {
|
|
|
13770
13932
|
|
|
13771
13933
|
// ../../node_modules/.bun/@logtape+file@2.0.4+2d5de51540e256d2/node_modules/@logtape/file/dist/filesink.node.js
|
|
13772
13934
|
import fs from "fs";
|
|
13773
|
-
import { join as
|
|
13935
|
+
import { join as join11 } from "path";
|
|
13774
13936
|
import { promisify } from "util";
|
|
13775
13937
|
var nodeDriver = {
|
|
13776
13938
|
openSync(path) {
|
|
@@ -13810,14 +13972,14 @@ var nodeTimeDriver = {
|
|
|
13810
13972
|
readdirSync: fs.readdirSync,
|
|
13811
13973
|
unlinkSync: fs.unlinkSync,
|
|
13812
13974
|
mkdirSync: fs.mkdirSync,
|
|
13813
|
-
joinPath:
|
|
13975
|
+
joinPath: join11
|
|
13814
13976
|
};
|
|
13815
13977
|
var nodeAsyncTimeDriver = {
|
|
13816
13978
|
...nodeAsyncDriver,
|
|
13817
13979
|
readdirSync: fs.readdirSync,
|
|
13818
13980
|
unlinkSync: fs.unlinkSync,
|
|
13819
13981
|
mkdirSync: fs.mkdirSync,
|
|
13820
|
-
joinPath:
|
|
13982
|
+
joinPath: join11
|
|
13821
13983
|
};
|
|
13822
13984
|
function getFileSink(path, options = {}) {
|
|
13823
13985
|
if (options.nonBlocking)
|
|
@@ -13832,8 +13994,8 @@ function getFileSink(path, options = {}) {
|
|
|
13832
13994
|
}
|
|
13833
13995
|
|
|
13834
13996
|
// src/logging.ts
|
|
13835
|
-
var LOG_DIR =
|
|
13836
|
-
var LOG_FILE =
|
|
13997
|
+
var LOG_DIR = join12(homedir10(), ".rudel", "logs");
|
|
13998
|
+
var LOG_FILE = join12(LOG_DIR, "hook-upload.log");
|
|
13837
13999
|
async function setupHookLogging() {
|
|
13838
14000
|
const { mkdir } = await import("fs/promises");
|
|
13839
14001
|
await mkdir(LOG_DIR, { recursive: true }).catch(() => {});
|
|
@@ -14215,8 +14377,8 @@ var setOrgCommand = buildCommand({
|
|
|
14215
14377
|
|
|
14216
14378
|
// src/lib/classifier.ts
|
|
14217
14379
|
import { mkdir, unlink } from "fs/promises";
|
|
14218
|
-
import { homedir as
|
|
14219
|
-
import { join as
|
|
14380
|
+
import { homedir as homedir11 } from "os";
|
|
14381
|
+
import { join as join13 } from "path";
|
|
14220
14382
|
|
|
14221
14383
|
// src/lib/types.ts
|
|
14222
14384
|
var SESSION_TAGS = [
|
|
@@ -14243,8 +14405,8 @@ var SYSTEM_PROMPT = `You are a session classifier. Analyze the Claude Code sessi
|
|
|
14243
14405
|
CRITICAL: Respond with ONLY the tag name. Nothing else. No explanation, no punctuation, no formatting. Just ONE of: research, new_feature, bug_fix, refactoring, documentation, tests`;
|
|
14244
14406
|
async function classifySession(content) {
|
|
14245
14407
|
const truncatedContent = content.slice(0, 50000);
|
|
14246
|
-
const tempDir =
|
|
14247
|
-
const tempFile =
|
|
14408
|
+
const tempDir = join13(homedir11(), ".claude", "temp");
|
|
14409
|
+
const tempFile = join13(tempDir, `classify-${Date.now()}.txt`);
|
|
14248
14410
|
try {
|
|
14249
14411
|
await mkdir(tempDir, { recursive: true });
|
|
14250
14412
|
await Bun.write(tempFile, `Classify this session transcript:
|
|
@@ -14284,9 +14446,9 @@ ${truncatedContent}`);
|
|
|
14284
14446
|
|
|
14285
14447
|
// src/lib/session-resolver.ts
|
|
14286
14448
|
import { access, readdir as readdir3 } from "fs/promises";
|
|
14287
|
-
import { homedir as
|
|
14288
|
-
import { basename, dirname as dirname3, join as
|
|
14289
|
-
var SESSIONS_BASE_DIR3 =
|
|
14449
|
+
import { homedir as homedir12 } from "os";
|
|
14450
|
+
import { basename, dirname as dirname3, join as join14 } from "path";
|
|
14451
|
+
var SESSIONS_BASE_DIR3 = join14(homedir12(), ".claude", "projects");
|
|
14290
14452
|
async function resolveSession(input) {
|
|
14291
14453
|
const isPath = input.includes("/") || input.endsWith(".jsonl");
|
|
14292
14454
|
if (isPath) {
|
|
@@ -14318,11 +14480,11 @@ async function resolveFromId(sessionId) {
|
|
|
14318
14480
|
throw new Error(`Session not found: ${sessionId}`);
|
|
14319
14481
|
}
|
|
14320
14482
|
for (const projectDir of projectDirs) {
|
|
14321
|
-
const sessionDir =
|
|
14483
|
+
const sessionDir = join14(SESSIONS_BASE_DIR3, projectDir);
|
|
14322
14484
|
try {
|
|
14323
14485
|
const files = await readdir3(sessionDir);
|
|
14324
14486
|
if (files.includes(sessionFileName)) {
|
|
14325
|
-
const transcriptPath =
|
|
14487
|
+
const transcriptPath = join14(sessionDir, sessionFileName);
|
|
14326
14488
|
const projectPath = await decodeProjectPath(projectDir);
|
|
14327
14489
|
return {
|
|
14328
14490
|
transcriptPath,
|
|
@@ -14352,45 +14514,26 @@ async function runInteractiveUpload(flags) {
|
|
|
14352
14514
|
We("rudel upload");
|
|
14353
14515
|
const spin = bt2();
|
|
14354
14516
|
spin.start("Scanning projects...");
|
|
14355
|
-
const
|
|
14356
|
-
const allProjects = [];
|
|
14357
|
-
for (const adapter of adapters2) {
|
|
14358
|
-
const projects = await adapter.scanAllSessions();
|
|
14359
|
-
allProjects.push(...projects);
|
|
14360
|
-
}
|
|
14517
|
+
const { projects: allProjects, groups } = await scanAndGroupProjects();
|
|
14361
14518
|
spin.stop(`Found ${allProjects.length} project(s)`);
|
|
14362
14519
|
if (allProjects.length === 0) {
|
|
14363
14520
|
R2.warn("No projects with sessions found.");
|
|
14364
14521
|
Le("Nothing to upload.");
|
|
14365
14522
|
return;
|
|
14366
14523
|
}
|
|
14367
|
-
const cwd = process.cwd();
|
|
14368
|
-
const grouped = groupProjectsForCwd(allProjects, cwd);
|
|
14369
14524
|
const options = [];
|
|
14370
14525
|
const preSelected = [];
|
|
14371
|
-
for (const
|
|
14372
|
-
|
|
14373
|
-
|
|
14374
|
-
|
|
14375
|
-
|
|
14376
|
-
|
|
14377
|
-
|
|
14378
|
-
|
|
14379
|
-
|
|
14380
|
-
|
|
14381
|
-
|
|
14382
|
-
value: sub,
|
|
14383
|
-
label: ` [${getAdapterName(sub.source)}] ${relative}`,
|
|
14384
|
-
hint: sessionCountHint(sub.sessionCount)
|
|
14385
|
-
});
|
|
14386
|
-
preSelected.push(sub);
|
|
14387
|
-
}
|
|
14388
|
-
for (const other of grouped.others) {
|
|
14389
|
-
options.push({
|
|
14390
|
-
value: other,
|
|
14391
|
-
label: `[${getAdapterName(other.source)}] ${other.displayPath}`,
|
|
14392
|
-
hint: sessionCountHint(other.sessionCount)
|
|
14393
|
-
});
|
|
14526
|
+
for (const group2 of groups) {
|
|
14527
|
+
for (const proj of group2.projects) {
|
|
14528
|
+
options.push({
|
|
14529
|
+
value: proj,
|
|
14530
|
+
label: `[${getAdapterName(proj.source)}] ${proj.displayPath}`,
|
|
14531
|
+
hint: sessionCountHint(proj.sessionCount)
|
|
14532
|
+
});
|
|
14533
|
+
if (group2.containsCwd) {
|
|
14534
|
+
preSelected.push(proj);
|
|
14535
|
+
}
|
|
14536
|
+
}
|
|
14394
14537
|
}
|
|
14395
14538
|
const selected = await je({
|
|
14396
14539
|
message: "Select projects to upload",
|