rudel 0.1.6 → 0.1.8
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 +15 -0
- package/dist/cli.js +81 -58
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
CLI for uploading [Claude Code](https://docs.anthropic.com/en/docs/claude-code) session transcripts to [Rudel](https://app.rudel.ai) for analytics.
|
|
4
4
|
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- [Bun](https://bun.sh) runtime installed
|
|
8
|
+
|
|
5
9
|
## Installation
|
|
6
10
|
|
|
7
11
|
```bash
|
|
@@ -65,6 +69,17 @@ Show the currently authenticated user.
|
|
|
65
69
|
|
|
66
70
|
Clear stored credentials.
|
|
67
71
|
|
|
72
|
+
## What Data Is Collected
|
|
73
|
+
|
|
74
|
+
Each uploaded session includes:
|
|
75
|
+
|
|
76
|
+
- Session ID & timestamps (start, last interaction)
|
|
77
|
+
- User ID & organization ID
|
|
78
|
+
- Project path & package name
|
|
79
|
+
- Git context (repository, branch, SHA, remote)
|
|
80
|
+
- Session transcript (full prompt & response content)
|
|
81
|
+
- Sub-agent usage
|
|
82
|
+
|
|
68
83
|
## Links
|
|
69
84
|
|
|
70
85
|
- **Web App**: [app.rudel.ai](https://app.rudel.ai)
|
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.8",
|
|
1963
1963
|
type: "module",
|
|
1964
1964
|
description: "CLI for the Coding Agent Analytics Platform rudel.ai",
|
|
1965
1965
|
license: "MIT",
|
|
@@ -2000,11 +2000,11 @@ var package_default = {
|
|
|
2000
2000
|
"@logtape/logtape": "^2.0.4",
|
|
2001
2001
|
"@orpc/client": "^1.13.5",
|
|
2002
2002
|
"@orpc/contract": "^1.13.5",
|
|
2003
|
-
"@rudel/agent-adapters": "workspace:*",
|
|
2004
2003
|
"@stricli/core": "^1.2.5",
|
|
2005
2004
|
"p-map": "^7.0.4"
|
|
2006
2005
|
},
|
|
2007
2006
|
devDependencies: {
|
|
2007
|
+
"@rudel/agent-adapters": "workspace:*",
|
|
2008
2008
|
"@rudel/api-routes": "workspace:*",
|
|
2009
2009
|
"@rudel/typescript-config": "workspace:*",
|
|
2010
2010
|
"bun-types": "latest",
|
|
@@ -5997,9 +5997,9 @@ var RudelClaudeSessionsRowSchema = exports_external.object({
|
|
|
5997
5997
|
session_id: exports_external.string(),
|
|
5998
5998
|
organization_id: exports_external.string(),
|
|
5999
5999
|
project_path: exports_external.string(),
|
|
6000
|
-
repository: exports_external.string().nullable(),
|
|
6001
6000
|
git_remote: exports_external.string(),
|
|
6002
6001
|
package_name: exports_external.string(),
|
|
6002
|
+
package_type: exports_external.string(),
|
|
6003
6003
|
content: exports_external.string(),
|
|
6004
6004
|
ingested_at: exports_external.string(),
|
|
6005
6005
|
user_id: exports_external.string(),
|
|
@@ -6014,7 +6014,9 @@ var RudelCodexSessionsRowSchema = exports_external.object({
|
|
|
6014
6014
|
session_id: exports_external.string(),
|
|
6015
6015
|
organization_id: exports_external.string(),
|
|
6016
6016
|
project_path: exports_external.string(),
|
|
6017
|
-
|
|
6017
|
+
git_remote: exports_external.string(),
|
|
6018
|
+
package_name: exports_external.string(),
|
|
6019
|
+
package_type: exports_external.string(),
|
|
6018
6020
|
content: exports_external.string(),
|
|
6019
6021
|
ingested_at: exports_external.string(),
|
|
6020
6022
|
user_id: exports_external.string(),
|
|
@@ -6028,9 +6030,9 @@ var RudelSessionAnalyticsRowSchema = exports_external.object({
|
|
|
6028
6030
|
session_id: exports_external.string(),
|
|
6029
6031
|
organization_id: exports_external.string(),
|
|
6030
6032
|
project_path: exports_external.string(),
|
|
6031
|
-
repository: exports_external.string().nullable(),
|
|
6032
6033
|
git_remote: exports_external.string(),
|
|
6033
6034
|
package_name: exports_external.string(),
|
|
6035
|
+
package_type: exports_external.string(),
|
|
6034
6036
|
content: exports_external.string(),
|
|
6035
6037
|
subagents: exports_external.record(exports_external.string(), exports_external.string()),
|
|
6036
6038
|
skills: exports_external.array(exports_external.string()),
|
|
@@ -6363,9 +6365,9 @@ class ClaudeCodeAdapter {
|
|
|
6363
6365
|
source: this.source,
|
|
6364
6366
|
sessionId: session.sessionId,
|
|
6365
6367
|
projectPath: session.projectPath,
|
|
6366
|
-
repository: context.gitInfo.repository,
|
|
6367
6368
|
gitRemote: context.gitInfo.gitRemote,
|
|
6368
6369
|
packageName: context.gitInfo.packageName,
|
|
6370
|
+
packageType: context.gitInfo.packageType,
|
|
6369
6371
|
gitBranch: context.gitInfo.branch,
|
|
6370
6372
|
gitSha: context.gitInfo.sha,
|
|
6371
6373
|
tag: context.tag,
|
|
@@ -6418,9 +6420,9 @@ class ClaudeCodeAdapter {
|
|
|
6418
6420
|
session_id: input.sessionId,
|
|
6419
6421
|
organization_id: context.organizationId,
|
|
6420
6422
|
project_path: input.projectPath,
|
|
6421
|
-
repository: input.repository ?? null,
|
|
6422
6423
|
git_remote: input.gitRemote ?? "",
|
|
6423
6424
|
package_name: input.packageName ?? "",
|
|
6425
|
+
package_type: input.packageType ?? "",
|
|
6424
6426
|
content: input.content,
|
|
6425
6427
|
subagents,
|
|
6426
6428
|
ingested_at: now,
|
|
@@ -7695,7 +7697,6 @@ class CodexAdapter {
|
|
|
7695
7697
|
source: this.source,
|
|
7696
7698
|
sessionId: session.sessionId,
|
|
7697
7699
|
projectPath: session.projectPath,
|
|
7698
|
-
repository: context.gitInfo.repository,
|
|
7699
7700
|
gitBranch: session.gitBranch ?? context.gitInfo.branch,
|
|
7700
7701
|
gitSha: session.gitSha ?? context.gitInfo.sha,
|
|
7701
7702
|
tag: context.tag,
|
|
@@ -7741,7 +7742,9 @@ class CodexAdapter {
|
|
|
7741
7742
|
session_id: input.sessionId,
|
|
7742
7743
|
organization_id: context.organizationId,
|
|
7743
7744
|
project_path: input.projectPath,
|
|
7744
|
-
|
|
7745
|
+
git_remote: input.gitRemote ?? "",
|
|
7746
|
+
package_name: input.packageName ?? "",
|
|
7747
|
+
package_type: input.packageType ?? "",
|
|
7745
7748
|
content: input.content,
|
|
7746
7749
|
ingested_at: now,
|
|
7747
7750
|
user_id: context.userId,
|
|
@@ -10867,7 +10870,8 @@ var OverviewKPIsSchema = exports_external.object({
|
|
|
10867
10870
|
distinct_projects: exports_external.number(),
|
|
10868
10871
|
distinct_subagents: exports_external.number(),
|
|
10869
10872
|
distinct_skills: exports_external.number(),
|
|
10870
|
-
distinct_slash_commands: exports_external.number()
|
|
10873
|
+
distinct_slash_commands: exports_external.number(),
|
|
10874
|
+
total_sessions: exports_external.number()
|
|
10871
10875
|
});
|
|
10872
10876
|
var UsageTrendDataSchema = exports_external.object({
|
|
10873
10877
|
date: exports_external.string(),
|
|
@@ -10946,6 +10950,8 @@ var DeveloperSessionSchema = exports_external.object({
|
|
|
10946
10950
|
session_id: exports_external.string(),
|
|
10947
10951
|
session_date: exports_external.string(),
|
|
10948
10952
|
project_path: exports_external.string(),
|
|
10953
|
+
git_remote: exports_external.string().optional(),
|
|
10954
|
+
package_name: exports_external.string().optional(),
|
|
10949
10955
|
duration_min: exports_external.number(),
|
|
10950
10956
|
total_tokens: exports_external.number(),
|
|
10951
10957
|
has_subagents: exports_external.boolean(),
|
|
@@ -10956,6 +10962,8 @@ var DeveloperSessionSchema = exports_external.object({
|
|
|
10956
10962
|
});
|
|
10957
10963
|
var DeveloperProjectSchema = exports_external.object({
|
|
10958
10964
|
project_path: exports_external.string(),
|
|
10965
|
+
git_remote: exports_external.string().optional(),
|
|
10966
|
+
package_name: exports_external.string().optional(),
|
|
10959
10967
|
sessions: exports_external.number(),
|
|
10960
10968
|
total_duration_min: exports_external.number(),
|
|
10961
10969
|
total_tokens: exports_external.number(),
|
|
@@ -11274,10 +11282,6 @@ var LearningsTrendDataPointSchema = exports_external.record(exports_external.str
|
|
|
11274
11282
|
var LearningsTrendInputSchema = DaysInputSchema.extend({
|
|
11275
11283
|
splitBy: exports_external.enum(["user_id", "repository"])
|
|
11276
11284
|
});
|
|
11277
|
-
var UserMappingSchema = exports_external.object({
|
|
11278
|
-
user_id: exports_external.string(),
|
|
11279
|
-
username: exports_external.string()
|
|
11280
|
-
});
|
|
11281
11285
|
// ../../packages/api-routes/src/index.ts
|
|
11282
11286
|
var HealthSchema = exports_external.object({
|
|
11283
11287
|
status: exports_external.literal("ok"),
|
|
@@ -11313,9 +11317,9 @@ var IngestSessionInputSchema = exports_external.object({
|
|
|
11313
11317
|
source: SourceSchema.default("claude_code"),
|
|
11314
11318
|
sessionId: exports_external.string(),
|
|
11315
11319
|
projectPath: exports_external.string(),
|
|
11316
|
-
repository: exports_external.string().optional(),
|
|
11317
11320
|
gitRemote: exports_external.string().optional(),
|
|
11318
11321
|
packageName: exports_external.string().optional(),
|
|
11322
|
+
packageType: exports_external.string().optional(),
|
|
11319
11323
|
gitBranch: exports_external.string().optional(),
|
|
11320
11324
|
gitSha: exports_external.string().optional(),
|
|
11321
11325
|
tag: SessionTagSchema.optional(),
|
|
@@ -11333,18 +11337,15 @@ var contract = {
|
|
|
11333
11337
|
listMyOrganizations: oc.output(exports_external.array(OrganizationSchema)),
|
|
11334
11338
|
ingestSession: oc.input(IngestSessionInputSchema).output(IngestSessionOutputSchema),
|
|
11335
11339
|
getOrganizationSessionCount: oc.input(exports_external.object({ organizationId: exports_external.string() })).output(exports_external.object({ count: exports_external.number() })),
|
|
11336
|
-
deleteOrganization: oc.input(exports_external.object({
|
|
11337
|
-
organizationId: exports_external.string(),
|
|
11338
|
-
migrateSessionsTo: exports_external.string().optional()
|
|
11339
|
-
})).output(exports_external.object({ success: exports_external.literal(true) })),
|
|
11340
|
+
deleteOrganization: oc.input(exports_external.object({ organizationId: exports_external.string() })).output(exports_external.object({ success: exports_external.literal(true) })),
|
|
11340
11341
|
analytics: {
|
|
11341
11342
|
overview: {
|
|
11342
|
-
kpis: oc.input(
|
|
11343
|
-
usageTrend: oc.input(
|
|
11344
|
-
modelTokensTrend: oc.input(
|
|
11345
|
-
insights: oc.input(
|
|
11346
|
-
teamSummaryComparison: oc.input(
|
|
11347
|
-
successRate: oc.input(
|
|
11343
|
+
kpis: oc.input(DateRangeInputSchema).output(OverviewKPIsSchema),
|
|
11344
|
+
usageTrend: oc.input(DateRangeInputSchema).output(exports_external.array(UsageTrendDataSchema)),
|
|
11345
|
+
modelTokensTrend: oc.input(DateRangeInputSchema).output(exports_external.array(ModelTokensTrendDataSchema)),
|
|
11346
|
+
insights: oc.input(DateRangeInputSchema).output(exports_external.array(InsightSchema)),
|
|
11347
|
+
teamSummaryComparison: oc.input(DateRangeInputSchema).output(TeamSummaryComparisonSchema),
|
|
11348
|
+
successRate: oc.input(DateRangeInputSchema).output(SuccessRateSchema)
|
|
11348
11349
|
},
|
|
11349
11350
|
developers: {
|
|
11350
11351
|
list: oc.input(DaysInputSchema).output(exports_external.array(DeveloperSummarySchema)),
|
|
@@ -11387,9 +11388,6 @@ var contract = {
|
|
|
11387
11388
|
users: oc.output(exports_external.array(exports_external.string())),
|
|
11388
11389
|
projects: oc.output(exports_external.array(exports_external.string())),
|
|
11389
11390
|
trend: oc.input(LearningsTrendInputSchema).output(exports_external.array(LearningsTrendDataPointSchema))
|
|
11390
|
-
},
|
|
11391
|
-
users: {
|
|
11392
|
-
mappings: oc.input(DaysInputSchema).output(exports_external.array(UserMappingSchema))
|
|
11393
11391
|
}
|
|
11394
11392
|
}
|
|
11395
11393
|
};
|
|
@@ -11550,49 +11548,73 @@ function normalizeRemoteUrl(url) {
|
|
|
11550
11548
|
return url.replace(/^(https?:\/\/|git@|ssh:\/\/)/, "").replace(/:/, "/").replace(/\.git$/, "");
|
|
11551
11549
|
}
|
|
11552
11550
|
async function getGitInfo(cwd) {
|
|
11553
|
-
const [remoteUrl, branch, sha,
|
|
11551
|
+
const [remoteUrl, branch, sha, packageInfo] = await Promise.all([
|
|
11554
11552
|
getGitRemoteUrl(cwd),
|
|
11555
11553
|
getGitBranch(cwd),
|
|
11556
11554
|
getGitSha(cwd),
|
|
11557
|
-
|
|
11555
|
+
getPackageInfo(cwd)
|
|
11558
11556
|
]);
|
|
11559
11557
|
const gitRemote = remoteUrl ? normalizeRemoteUrl(remoteUrl) : undefined;
|
|
11560
|
-
const repository = getRepositoryName(gitRemote, packageName, cwd);
|
|
11561
11558
|
return {
|
|
11562
|
-
repository,
|
|
11563
11559
|
gitRemote,
|
|
11564
|
-
packageName:
|
|
11560
|
+
packageName: packageInfo?.name,
|
|
11561
|
+
packageType: packageInfo?.type,
|
|
11565
11562
|
branch: branch ?? undefined,
|
|
11566
11563
|
sha: sha ?? undefined
|
|
11567
11564
|
};
|
|
11568
11565
|
}
|
|
11569
|
-
function
|
|
11570
|
-
|
|
11571
|
-
const
|
|
11572
|
-
|
|
11573
|
-
|
|
11574
|
-
|
|
11575
|
-
return
|
|
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;
|
|
11576
11573
|
}
|
|
11577
|
-
if (packageName)
|
|
11578
|
-
return packageName;
|
|
11579
|
-
const dirName = cwd.split("/").pop();
|
|
11580
|
-
return dirName ?? undefined;
|
|
11581
11574
|
}
|
|
11582
|
-
async function
|
|
11575
|
+
async function getNodePackage(root) {
|
|
11583
11576
|
try {
|
|
11584
|
-
const
|
|
11585
|
-
|
|
11586
|
-
|
|
11587
|
-
const
|
|
11588
|
-
|
|
11589
|
-
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
|
|
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
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;
|
|
11596
11618
|
} catch {
|
|
11597
11619
|
return null;
|
|
11598
11620
|
}
|
|
@@ -14470,8 +14492,9 @@ async function runSingleUpload(flags, session) {
|
|
|
14470
14492
|
}
|
|
14471
14493
|
write(`Found session at: ${sessionInfo.transcriptPath}`);
|
|
14472
14494
|
const gitInfo = await getGitInfo(sessionInfo.projectPath);
|
|
14473
|
-
|
|
14474
|
-
|
|
14495
|
+
const displayName = gitInfo.gitRemote || gitInfo.packageName || sessionInfo.projectPath.split("/").pop();
|
|
14496
|
+
if (displayName)
|
|
14497
|
+
write(`Repository: ${displayName}`);
|
|
14475
14498
|
if (gitInfo.branch)
|
|
14476
14499
|
write(`Branch: ${gitInfo.branch}`);
|
|
14477
14500
|
const organizationId = flags.org ?? await getProjectOrgId(sessionInfo.projectPath);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rudel",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI for the Coding Agent Analytics Platform rudel.ai",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,13 +41,13 @@
|
|
|
41
41
|
"@logtape/logtape": "^2.0.4",
|
|
42
42
|
"@orpc/client": "^1.13.5",
|
|
43
43
|
"@orpc/contract": "^1.13.5",
|
|
44
|
-
"@rudel/agent-adapters": "workspace:*",
|
|
45
44
|
"@stricli/core": "^1.2.5",
|
|
46
45
|
"p-map": "^7.0.4"
|
|
47
46
|
},
|
|
48
47
|
"devDependencies": {
|
|
49
|
-
"@rudel/
|
|
50
|
-
"@rudel/
|
|
48
|
+
"@rudel/agent-adapters": "0.0.0",
|
|
49
|
+
"@rudel/api-routes": "0.0.0",
|
|
50
|
+
"@rudel/typescript-config": "0.0.0",
|
|
51
51
|
"bun-types": "latest",
|
|
52
52
|
"typescript": "5.9.2"
|
|
53
53
|
}
|