or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cache-utilities.mdclient-management.mddata-models-types.mdindex.mdissue-operations.mdproject-management.mdteam-administration.mduser-management.md

user-management.mddocs/

0

# User Management

1

2

User operations including profile access, team memberships, issue assignments, and organizational data management.

3

4

## Capabilities

5

6

### Core User Operations

7

8

Basic user management operations for accessing user profiles and information.

9

10

```python { .api }

11

def get(self, user_id: str) -> LinearUser:

12

"""

13

Fetch a Linear user by ID with comprehensive user details and organization information.

14

15

Args:

16

user_id: The ID of the user to fetch

17

18

Returns:

19

LinearUser with complete details

20

21

Raises:

22

ValueError: If user not found

23

"""

24

25

def get_all(self) -> Dict[str, LinearUser]:

26

"""

27

Get all users in the organization.

28

29

Returns:

30

Dictionary mapping user IDs to LinearUser objects

31

"""

32

33

def get_me(self) -> LinearUser:

34

"""

35

Get the current user based on the API key.

36

37

Returns:

38

LinearUser object for the authenticated user

39

40

Raises:

41

ValueError: If authentication fails

42

"""

43

```

44

45

Usage examples:

46

47

```python

48

from linear_api import LinearClient

49

50

client = LinearClient()

51

52

# Get current user

53

me = client.users.get_me()

54

print(f"Current user: {me.name} ({me.email})")

55

print(f"Admin: {me.admin}, Active: {me.active}")

56

57

# Get specific user

58

user = client.users.get("user-id")

59

print(f"User: {user.displayName} - {user.email}")

60

61

# Get all organization users

62

all_users = client.users.get_all()

63

print(f"Organization has {len(all_users)} users")

64

```

65

66

### User Discovery

67

68

Find users by various identifiers and attributes.

69

70

```python { .api }

71

def get_email_map(self) -> Dict[str, str]:

72

"""

73

Get a mapping of user IDs to their email addresses.

74

75

Returns:

76

Dictionary mapping user IDs to email addresses

77

"""

78

79

def get_id_by_email(self, email: str) -> str:

80

"""

81

Get a user ID by their email address.

82

83

Args:

84

email: The email address to search for

85

86

Returns:

87

User ID string

88

89

Raises:

90

ValueError: If user not found

91

"""

92

93

def get_id_by_name(self, name: str) -> str:

94

"""

95

Get a user ID by their name (fuzzy match with exact, case-insensitive,

96

and partial matching).

97

98

Args:

99

name: The name to search for

100

101

Returns:

102

User ID string

103

104

Raises:

105

ValueError: If user not found

106

"""

107

```

108

109

Usage examples:

110

111

```python

112

# Get email mapping for all users

113

email_map = client.users.get_email_map()

114

print(f"Found {len(email_map)} users with emails")

115

116

# Find user by email

117

user_id = client.users.get_id_by_email("john.doe@company.com")

118

user = client.users.get(user_id)

119

120

# Find user by name (fuzzy matching)

121

user_id = client.users.get_id_by_name("John Doe")

122

# Also works with partial matches:

123

# user_id = client.users.get_id_by_name("john")

124

# user_id = client.users.get_id_by_name("John")

125

```

126

127

### Issue Management

128

129

Access issues assigned to or created by users.

130

131

```python { .api }

132

def get_assigned_issues(self, user_id: str) -> Dict[str, LinearIssue]:

133

"""

134

Get issues assigned to a user.

135

136

Args:

137

user_id: The ID of the user

138

139

Returns:

140

Dictionary mapping issue IDs to LinearIssue objects

141

"""

142

143

def get_created_issues(self, user_id: str) -> List[Dict[str, Any]]:

144

"""

145

Get issues created by a user with basic issue information.

146

147

Args:

148

user_id: The ID of the user

149

150

Returns:

151

List of issue dictionaries

152

"""

153

```

154

155

Usage examples:

156

157

```python

158

# Get user's assigned issues

159

assigned_issues = client.users.get_assigned_issues("user-id")

160

print(f"User has {len(assigned_issues)} assigned issues")

161

162

# Group by status

163

from collections import defaultdict

164

by_status = defaultdict(list)

165

for issue in assigned_issues.values():

166

by_status[issue.state.name].append(issue)

167

168

print("Issues by status:")

169

for status, issues in by_status.items():

170

print(f" {status}: {len(issues)} issues")

171

172

# Get issues created by user

173

created_issues = client.users.get_created_issues("user-id")

174

print(f"User has created {len(created_issues)} issues")

175

```

176

177

### Team Membership

178

179

Access user team memberships and organizational relationships.

180

181

```python { .api }

182

def get_team_memberships(self, user_id: str) -> List[Dict[str, Any]]:

183

"""

184

Get team memberships for a user with team information included.

185

186

Args:

187

user_id: The ID of the user

188

189

Returns:

190

List of team membership dictionaries

191

"""

192

193

def get_teams(self, user_id: str) -> List[LinearTeam]:

194

"""

195

Get teams that a user is a member of.

196

197

Args:

198

user_id: The ID of the user

199

200

Returns:

201

List of LinearTeam objects

202

"""

203

```

204

205

Usage examples:

206

207

```python

208

# Get user's team memberships

209

memberships = client.users.get_team_memberships("user-id")

210

print(f"User is a member of {len(memberships)} teams")

211

212

for membership in memberships:

213

team_info = membership.get('team', {})

214

is_owner = membership.get('owner', False)

215

print(f" - {team_info.get('name')} {'(Owner)' if is_owner else ''}")

216

217

# Get teams directly

218

teams = client.users.get_teams("user-id")

219

for team in teams:

220

print(f"Team: {team.name} ({team.key})")

221

```

222

223

### Draft Management

224

225

Access document and issue drafts created by users.

226

227

```python { .api }

228

def get_drafts(self, user_id: str) -> List[Draft]:

229

"""

230

Get document drafts created by a user.

231

232

Args:

233

user_id: The ID of the user

234

235

Returns:

236

List of Draft objects

237

"""

238

239

def get_issue_drafts(self, user_id: str) -> List[IssueDraft]:

240

"""

241

Get issue drafts created by a user.

242

243

Args:

244

user_id: The ID of the user

245

246

Returns:

247

List of IssueDraft objects

248

"""

249

```

250

251

Usage examples:

252

253

```python

254

# Get user's document drafts

255

drafts = client.users.get_drafts("user-id")

256

print(f"User has {len(drafts)} document drafts")

257

258

# Get user's issue drafts

259

issue_drafts = client.users.get_issue_drafts("user-id")

260

print(f"User has {len(issue_drafts)} issue drafts")

261

```

262

263

### Cache Management

264

265

Control caching for user-related data.

266

267

```python { .api }

268

def invalidate_cache(self) -> None:

269

"""

270

Invalidate all user-related caches.

271

"""

272

```

273

274

Usage examples:

275

276

```python

277

# Clear user caches

278

client.users.invalidate_cache()

279

```

280

281

## User Properties and Attributes

282

283

The LinearUser model includes comprehensive user information:

284

285

### Core User Fields

286

287

```python

288

user = client.users.get_me()

289

290

# Required fields

291

print(f"ID: {user.id}")

292

print(f"Name: {user.name}")

293

print(f"Display Name: {user.displayName}")

294

print(f"Email: {user.email}")

295

print(f"Created: {user.createdAt}")

296

print(f"Updated: {user.updatedAt}")

297

298

# Boolean status fields

299

print(f"Active: {user.active}")

300

print(f"Admin: {user.admin}")

301

print(f"App User: {user.app}")

302

print(f"Guest: {user.guest}")

303

print(f"Is Me: {user.isMe}")

304

```

305

306

### Optional User Fields

307

308

```python

309

# Optional profile information

310

if user.avatarUrl:

311

print(f"Avatar: {user.avatarUrl}")

312

313

if user.description:

314

print(f"Description: {user.description}")

315

316

if user.timezone:

317

print(f"Timezone: {user.timezone}")

318

319

if user.statusEmoji:

320

print(f"Status: {user.statusEmoji} {user.statusLabel}")

321

322

# Usage statistics

323

if hasattr(user, 'createdIssueCount'):

324

print(f"Created issues: {user.createdIssueCount}")

325

326

# Calendar integration

327

if user.calendarHash:

328

print(f"Calendar hash: {user.calendarHash}")

329

```

330

331

## Advanced User Workflows

332

333

### User Activity Analysis

334

335

```python

336

def analyze_user_activity(user_id: str):

337

user = client.users.get(user_id)

338

assigned_issues = client.users.get_assigned_issues(user_id)

339

created_issues = client.users.get_created_issues(user_id)

340

teams = client.users.get_teams(user_id)

341

342

print(f"User Activity Report: {user.displayName}")

343

print(f"Email: {user.email}")

344

print(f"Status: {'Active' if user.active else 'Inactive'}")

345

print(f"Admin: {'Yes' if user.admin else 'No'}")

346

print(f"Teams: {len(teams)}")

347

print(f"Assigned Issues: {len(assigned_issues)}")

348

print(f"Created Issues: {len(created_issues)}")

349

350

# Analyze assigned issue states

351

if assigned_issues:

352

state_counts = {}

353

for issue in assigned_issues.values():

354

state = issue.state.name

355

state_counts[state] = state_counts.get(state, 0) + 1

356

357

print("\nAssigned Issues by State:")

358

for state, count in state_counts.items():

359

print(f" {state}: {count}")

360

361

# List teams

362

if teams:

363

print("\nTeam Memberships:")

364

for team in teams:

365

print(f" - {team.name} ({team.key})")

366

367

return {

368

"user": user,

369

"team_count": len(teams),

370

"assigned_issues": len(assigned_issues),

371

"created_issues": len(created_issues)

372

}

373

374

# Analyze user activity

375

activity = analyze_user_activity("user-id")

376

```

377

378

### Team Member Directory

379

380

```python

381

def create_team_directory():

382

all_users = client.users.get_all()

383

384

# Filter active users

385

active_users = {uid: user for uid, user in all_users.items() if user.active}

386

387

# Group by team membership

388

team_members = {}

389

390

for user_id, user in active_users.items():

391

teams = client.users.get_teams(user_id)

392

for team in teams:

393

if team.id not in team_members:

394

team_members[team.id] = {

395

'team': team,

396

'members': []

397

}

398

team_members[team.id]['members'].append(user)

399

400

print("Team Directory:")

401

print("=" * 50)

402

403

for team_id, team_data in team_members.items():

404

team = team_data['team']

405

members = team_data['members']

406

407

print(f"\n{team.name} ({team.key})")

408

print("-" * 30)

409

410

# Sort members by name

411

members.sort(key=lambda u: u.displayName.lower())

412

413

for member in members:

414

admin_badge = " [ADMIN]" if member.admin else ""

415

print(f" • {member.displayName} ({member.email}){admin_badge}")

416

417

print(f" Total: {len(members)} members")

418

419

# Create directory

420

create_team_directory()

421

```

422

423

### User Workload Analysis

424

425

```python

426

def analyze_workloads():

427

all_users = client.users.get_all()

428

workloads = []

429

430

for user_id, user in all_users.items():

431

if not user.active:

432

continue

433

434

assigned_issues = client.users.get_assigned_issues(user_id)

435

436

# Calculate workload metrics

437

total_issues = len(assigned_issues)

438

in_progress = sum(1 for issue in assigned_issues.values()

439

if issue.state.type == 'started')

440

441

workloads.append({

442

'user': user,

443

'total_issues': total_issues,

444

'in_progress': in_progress,

445

'workload_score': in_progress + (total_issues * 0.3)

446

})

447

448

# Sort by workload

449

workloads.sort(key=lambda w: w['workload_score'], reverse=True)

450

451

print("User Workload Analysis:")

452

print("=" * 60)

453

print(f"{'Name':<25} {'Total':<8} {'Active':<8} {'Workload':<10}")

454

print("-" * 60)

455

456

for workload in workloads[:20]: # Top 20

457

user = workload['user']

458

print(f"{user.displayName:<25} {workload['total_issues']:<8} "

459

f"{workload['in_progress']:<8} {workload['workload_score']:<10.1f}")

460

461

# Analyze workloads

462

analyze_workloads()

463

```

464

465

### User Search and Filtering

466

467

```python

468

def search_users(query: str, filters: dict = None):

469

"""

470

Search for users with flexible criteria.

471

472

Args:

473

query: Search term for name or email

474

filters: Additional filters (active, admin, teams, etc.)

475

"""

476

all_users = client.users.get_all()

477

results = []

478

479

query_lower = query.lower()

480

481

for user_id, user in all_users.items():

482

# Text search

483

matches_query = (

484

query_lower in user.name.lower() or

485

query_lower in user.displayName.lower() or

486

query_lower in user.email.lower()

487

)

488

489

if not matches_query:

490

continue

491

492

# Apply filters

493

if filters:

494

if 'active' in filters and user.active != filters['active']:

495

continue

496

if 'admin' in filters and user.admin != filters['admin']:

497

continue

498

499

results.append(user)

500

501

# Sort by relevance (exact matches first, then by name)

502

def sort_key(user):

503

exact_name = user.name.lower() == query_lower

504

exact_display = user.displayName.lower() == query_lower

505

exact_email = user.email.lower() == query_lower

506

507

return (not (exact_name or exact_display or exact_email), user.displayName.lower())

508

509

results.sort(key=sort_key)

510

511

print(f"Search results for '{query}':")

512

for user in results[:10]: # Top 10 results

513

status = "Active" if user.active else "Inactive"

514

admin = " [ADMIN]" if user.admin else ""

515

print(f" • {user.displayName} ({user.email}) - {status}{admin}")

516

517

return results

518

519

# Search examples

520

search_users("john") # Find users named John

521

search_users("@company.com") # Find users by email domain

522

search_users("", {'active': True, 'admin': True}) # Find active admins

523

```

524

525

### Organization Metrics

526

527

```python

528

def get_organization_metrics():

529

all_users = client.users.get_all()

530

531

# Calculate metrics

532

total_users = len(all_users)

533

active_users = sum(1 for user in all_users.values() if user.active)

534

admin_users = sum(1 for user in all_users.values() if user.admin)

535

guest_users = sum(1 for user in all_users.values() if user.guest)

536

537

print("Organization User Metrics:")

538

print("=" * 40)

539

print(f"Total Users: {total_users}")

540

print(f"Active Users: {active_users} ({active_users/total_users:.1%})")

541

print(f"Admin Users: {admin_users} ({admin_users/total_users:.1%})")

542

print(f"Guest Users: {guest_users} ({guest_users/total_users:.1%})")

543

print(f"Inactive Users: {total_users - active_users}")

544

545

# Get all teams for team membership analysis

546

all_teams = client.teams.get_all()

547

team_memberships = 0

548

549

for user in all_users.values():

550

if user.active:

551

teams = client.users.get_teams(user.id)

552

team_memberships += len(teams)

553

554

avg_teams = team_memberships / active_users if active_users > 0 else 0

555

print(f"Average teams per active user: {avg_teams:.1f}")

556

557

return {

558

'total': total_users,

559

'active': active_users,

560

'admin': admin_users,

561

'guest': guest_users,

562

'avg_teams_per_user': avg_teams

563

}

564

565

# Get organization metrics

566

metrics = get_organization_metrics()

567

```