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.
Files changed (3) hide show
  1. package/README.md +15 -0
  2. package/dist/cli.js +81 -58
  3. 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.6",
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
- repository: exports_external.string().nullable(),
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
- repository: input.repository ?? null,
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(DaysInputSchema).output(OverviewKPIsSchema),
11343
- usageTrend: oc.input(DaysInputSchema).output(exports_external.array(UsageTrendDataSchema)),
11344
- modelTokensTrend: oc.input(DaysInputSchema).output(exports_external.array(ModelTokensTrendDataSchema)),
11345
- insights: oc.input(DaysInputSchema).output(exports_external.array(InsightSchema)),
11346
- teamSummaryComparison: oc.input(DaysInputSchema).output(TeamSummaryComparisonSchema),
11347
- successRate: oc.input(DaysInputSchema).output(SuccessRateSchema)
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, packageName] = await Promise.all([
11551
+ const [remoteUrl, branch, sha, packageInfo] = await Promise.all([
11554
11552
  getGitRemoteUrl(cwd),
11555
11553
  getGitBranch(cwd),
11556
11554
  getGitSha(cwd),
11557
- getPackageName(cwd)
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: packageName ?? undefined,
11560
+ packageName: packageInfo?.name,
11561
+ packageType: packageInfo?.type,
11565
11562
  branch: branch ?? undefined,
11566
11563
  sha: sha ?? undefined
11567
11564
  };
11568
11565
  }
11569
- function getRepositoryName(gitRemote, packageName, cwd) {
11570
- if (gitRemote) {
11571
- const parts = gitRemote.split("/");
11572
- if (parts.length >= 3) {
11573
- return parts.slice(1).join("/");
11574
- }
11575
- return gitRemote;
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 getPackageName(cwd) {
11575
+ async function getNodePackage(root) {
11583
11576
  try {
11584
- const gitRootResult = await $`git -C ${cwd} rev-parse --show-toplevel`.quiet();
11585
- const gitRoot = gitRootResult.exitCode === 0 ? gitRootResult.text().trim() : cwd;
11586
- const packageJsonPath = join8(gitRoot, "package.json");
11587
- const packageFile = Bun.file(packageJsonPath);
11588
- if (await packageFile.exists()) {
11589
- try {
11590
- const packageJson = await packageFile.json();
11591
- if (packageJson.name)
11592
- return packageJson.name;
11593
- } catch {}
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
- if (gitInfo.repository)
14474
- write(`Repository: ${gitInfo.repository}`);
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.6",
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/api-routes": "workspace:*",
50
- "@rudel/typescript-config": "workspace:*",
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
  }