@proletariat/cli 0.3.44 → 0.3.45

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.
@@ -1,8 +1,7 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import chalk from 'chalk';
3
- import * as path from 'node:path';
4
3
  import * as fs from 'node:fs';
5
- import { getWorkspaceInfo, getAllAgentsStatus, getAgentTmuxSessions } from '../../lib/agents/commands.js';
4
+ import { getWorkspaceInfo, getAllAgentsStatus, getAgentTmuxSessions, resolveAgentDir } from '../../lib/agents/commands.js';
6
5
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
7
6
  import { shouldOutputJson } from '../../lib/prompt-json.js';
8
7
  export default class List extends PMOCommand {
@@ -139,7 +138,7 @@ export default class List extends PMOCommand {
139
138
  }
140
139
  }
141
140
  else {
142
- const agentDir = path.join(workspaceInfo.agentsPath, agentStatus.name);
141
+ const agentDir = resolveAgentDir(workspaceInfo, agentStatus.name);
143
142
  const dirExists = fs.existsSync(agentDir);
144
143
  if (dirExists) {
145
144
  this.log(chalk.red(` Invalid or broken worktrees`));
@@ -3,7 +3,7 @@ import * as path from 'node:path';
3
3
  import * as fs from 'node:fs';
4
4
  import { execSync } from 'node:child_process';
5
5
  import { colors } from '../../lib/colors.js';
6
- import { getWorkspaceInfo, formatAgentList } from '../../lib/agents/commands.js';
6
+ import { getWorkspaceInfo, formatAgentList, resolveAgentDir } from '../../lib/agents/commands.js';
7
7
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
8
8
  import { isDockerRunning, getAgentContainerName, isContainerRunning, getContainerId, } from '../../lib/execution/runners.js';
9
9
  import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
@@ -74,7 +74,7 @@ export default class Login extends PMOCommand {
74
74
  if (!agent) {
75
75
  this.error(`Agent "${agentName}" not found. Available: ${formatAgentList(workspaceInfo.agents)}`);
76
76
  }
77
- const agentDir = path.join(workspaceInfo.agentsPath, agentName);
77
+ const agentDir = resolveAgentDir(workspaceInfo, agentName);
78
78
  // Check if Docker config exists
79
79
  const dockerfilePath = path.join(agentDir, '.devcontainer', 'Dockerfile');
80
80
  if (!fs.existsSync(dockerfilePath)) {
@@ -4,7 +4,7 @@ import { promisify } from 'node:util';
4
4
  import * as path from 'node:path';
5
5
  import * as fs from 'node:fs';
6
6
  import { colors } from '../../lib/colors.js';
7
- import { getWorkspaceInfo } from '../../lib/agents/commands.js';
7
+ import { getWorkspaceInfo, resolveAgentDir } from '../../lib/agents/commands.js';
8
8
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
9
9
  import { isDockerRunning } from '../../lib/execution/runners.js';
10
10
  import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
@@ -76,8 +76,7 @@ export default class AgentRebuild extends PMOCommand {
76
76
  this.error('Not in a proletariat workspace. Run `prlt init` first.');
77
77
  }
78
78
  this.log(colors.primary(`🔨 Rebuilding agent: ${agentName}\n`));
79
- const agentsPath = path.join(workspaceInfo.path, 'agents', 'staff');
80
- const agentDir = path.join(agentsPath, agentName);
79
+ const agentDir = resolveAgentDir(workspaceInfo, agentName);
81
80
  try {
82
81
  this.log(colors.textSecondary(' Building devcontainer...'));
83
82
  const buildCommand = [
@@ -4,7 +4,7 @@ import * as fs from 'node:fs';
4
4
  import { execSync, spawn } from 'node:child_process';
5
5
  import Database from 'better-sqlite3';
6
6
  import { colors } from '../../lib/colors.js';
7
- import { getWorkspaceInfo, getAgentTmuxSessions, formatAgentList } from '../../lib/agents/commands.js';
7
+ import { getWorkspaceInfo, getAgentTmuxSessions, formatAgentList, resolveAgentDir } from '../../lib/agents/commands.js';
8
8
  import { hasDevcontainerConfig } from '../../lib/execution/devcontainer.js';
9
9
  import { getTerminalApp } from '../../lib/execution/config.js';
10
10
  import { isDockerRunning, getAgentContainerName, isContainerRunning, getContainerId, } from '../../lib/execution/runners.js';
@@ -110,7 +110,7 @@ export default class Shell extends PMOCommand {
110
110
  // If 'continue', proceed with opening a new shell
111
111
  this.log(colors.warning('\nProceeding with new shell - be careful of conflicts!\n'));
112
112
  }
113
- const agentDir = path.join(workspaceInfo.agentsPath, agentName);
113
+ const agentDir = resolveAgentDir(workspaceInfo, agentName);
114
114
  // Check if agent has devcontainer
115
115
  const hasDevcontainer = hasDevcontainerConfig(agentDir);
116
116
  // In JSON mode with agent name provided, output combined config prompt
@@ -1,6 +1,6 @@
1
1
  import { Args } from '@oclif/core';
2
2
  import { colors, format } from '../../lib/colors.js';
3
- import { getWorkspaceInfo, getAgentStatus, getAllAgentsStatus, formatAgentList } from '../../lib/agents/commands.js';
3
+ import { getWorkspaceInfo, getAgentStatus, getAllAgentsStatus, formatAgentList, resolveAgentDir } from '../../lib/agents/commands.js';
4
4
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
5
5
  import { shouldOutputJson, outputErrorAsJson, outputSuccessAsJson, createMetadata, } from '../../lib/prompt-json.js';
6
6
  export default class Status extends PMOCommand {
@@ -83,7 +83,7 @@ export default class Status extends PMOCommand {
83
83
  name: agentName,
84
84
  type: agent.type,
85
85
  exists: agentStatus.exists,
86
- path: `${workspaceInfo.agentsPath}/${agentName}`,
86
+ path: resolveAgentDir(workspaceInfo, agentName),
87
87
  branch: agentStatus.branch,
88
88
  repositories: agentStatus.repositories.map(r => ({
89
89
  name: r.name,
@@ -107,7 +107,7 @@ export default class Status extends PMOCommand {
107
107
  return;
108
108
  }
109
109
  // Location
110
- this.log(`📍 Location: ${colors.path(`${workspaceInfo.agentsPath}/${agentName}`)}`);
110
+ this.log(`📍 Location: ${colors.path(resolveAgentDir(workspaceInfo, agentName))}`);
111
111
  // Branch info
112
112
  if (agentStatus.branch) {
113
113
  this.log(`🌿 Branch: ${colors.warning(agentStatus.branch)}`);
@@ -1,7 +1,7 @@
1
1
  import { Args } from '@oclif/core';
2
2
  import * as path from 'node:path';
3
3
  import { colors } from '../../lib/colors.js';
4
- import { getWorkspaceInfo, formatAgentList } from '../../lib/agents/commands.js';
4
+ import { getWorkspaceInfo, formatAgentList, resolveAgentDir } from '../../lib/agents/commands.js';
5
5
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
6
6
  import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
7
7
  export default class Visit extends PMOCommand {
@@ -74,7 +74,7 @@ export default class Visit extends PMOCommand {
74
74
  return handleError('AGENT_NOT_FOUND', `Agent "${agentName}" not found. Available: ${formatAgentList(workspaceInfo.agents)}`);
75
75
  }
76
76
  // Calculate path to agent directory
77
- const agentDir = path.join(workspaceInfo.agentsPath, agentName);
77
+ const agentDir = resolveAgentDir(workspaceInfo, agentName);
78
78
  const relativePath = path.relative(process.cwd(), agentDir);
79
79
  // Display navigation command
80
80
  this.log(colors.primary(`🤖 Visiting agent: ${agentName}`));
@@ -1,8 +1,7 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import chalk from 'chalk';
3
- import * as path from 'node:path';
4
3
  import * as fs from 'node:fs';
5
- import { getWorkspaceInfo, getAllAgentsStatus } from '../../lib/agents/commands.js';
4
+ import { getWorkspaceInfo, getAllAgentsStatus, resolveAgentDir } from '../../lib/agents/commands.js';
6
5
  import { shouldOutputJson } from '../../lib/prompt-json.js';
7
6
  import { machineOutputFlags } from '../../lib/pmo/index.js';
8
7
  export default class List extends Command {
@@ -73,7 +72,7 @@ export default class List extends Command {
73
72
  }
74
73
  }
75
74
  else {
76
- const agentDir = path.join(workspaceInfo.agentsPath, agentStatus.name);
75
+ const agentDir = resolveAgentDir(workspaceInfo, agentStatus.name);
77
76
  const dirExists = fs.existsSync(agentDir);
78
77
  if (dirExists) {
79
78
  this.log(chalk.red(` Invalid or broken worktrees`));
@@ -6,7 +6,7 @@ import Database from 'better-sqlite3';
6
6
  import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../lib/pmo/index.js';
7
7
  import { getWorkColumnSetting, findColumnByName } from '../../lib/pmo/utils.js';
8
8
  import { styles } from '../../lib/styles.js';
9
- import { getWorkspaceInfo } from '../../lib/agents/commands.js';
9
+ import { getWorkspaceInfo, resolveAgentDir } from '../../lib/agents/commands.js';
10
10
  import { DEFAULT_EXECUTION_CONFIG, } from '../../lib/execution/types.js';
11
11
  import { runExecution, isDockerRunning, isDevcontainerCliInstalled } from '../../lib/execution/runners.js';
12
12
  import { ExecutionStorage } from '../../lib/execution/storage.js';
@@ -179,8 +179,8 @@ export default class WorkRevise extends PMOCommand {
179
179
  this.error(`Ticket "${ticketId}" already has work in progress: ${runningExecution.id}\n` +
180
180
  `Stop it first with "prlt work stop ${runningExecution.id}"`);
181
181
  }
182
- // Find worktree path
183
- const agentDir = path.join(workspaceInfo.agentsPath, agentName);
182
+ // Find worktree path (handles staff and temp agents)
183
+ const agentDir = resolveAgentDir(workspaceInfo, agentName);
184
184
  if (!fs.existsSync(agentDir)) {
185
185
  db.close();
186
186
  this.error(`Agent directory not found at ${agentDir}.`);
@@ -9,7 +9,7 @@ import { shouldOutputJson, outputErrorAsJson, createMetadata, outputConfirmation
9
9
  import { FlagResolver } from '../../lib/flags/index.js';
10
10
  import { getWorkColumnSetting, findColumnByName } from '../../lib/pmo/utils.js';
11
11
  import { styles } from '../../lib/styles.js';
12
- import { getWorkspaceInfo, createEphemeralAgent, getTicketTmuxSession, killTmuxSession, findWorktreeForBranch, } from '../../lib/agents/commands.js';
12
+ import { getWorkspaceInfo, createEphemeralAgent, getTicketTmuxSession, killTmuxSession, findWorktreeForBranch, resolveAgentDir, } from '../../lib/agents/commands.js';
13
13
  import { generateBranchName, DEFAULT_EXECUTION_CONFIG, } from '../../lib/execution/types.js';
14
14
  import { runExecution, isDockerRunning, isGitHubTokenAvailable, isDevcontainerCliInstalled, dockerCredentialsExist, getDockerCredentialInfo } from '../../lib/execution/runners.js';
15
15
  import { ExecutionStorage, ContainerStorage } from '../../lib/execution/storage.js';
@@ -1712,7 +1712,7 @@ export default class WorkStart extends PMOCommand {
1712
1712
  }
1713
1713
  // Check Docker credentials if any agents use devcontainers
1714
1714
  const anyUseDevcontainer = availableAgents.some(agent => {
1715
- const agentDir = path.join(workspaceInfo.agentsPath, agent.name);
1715
+ const agentDir = resolveAgentDir(workspaceInfo, agent.name);
1716
1716
  return hasDevcontainerConfig(agentDir) && !flags['run-on-host'];
1717
1717
  });
1718
1718
  // Track whether user explicitly chose to use API key instead of OAuth
@@ -1858,8 +1858,8 @@ export default class WorkStart extends PMOCommand {
1858
1858
  async spawnSingleTicket(ticket, agent, workspaceInfo, executionStorage, db, flags) {
1859
1859
  const agentName = agent.name;
1860
1860
  // Note: Ticket assignee update moved to after successful spawn
1861
- // Find agent directory and worktree
1862
- const agentDir = path.join(workspaceInfo.agentsPath, agentName);
1861
+ // Find agent directory and worktree (handles staff and temp agents)
1862
+ const agentDir = resolveAgentDir(workspaceInfo, agentName);
1863
1863
  if (!fs.existsSync(agentDir)) {
1864
1864
  throw new Error(`Agent directory not found: ${agentDir}`);
1865
1865
  }
@@ -3,7 +3,7 @@ import * as path from 'node:path';
3
3
  import Database from 'better-sqlite3';
4
4
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
5
5
  import { styles } from '../../lib/styles.js';
6
- import { getWorkspaceInfo } from '../../lib/agents/commands.js';
6
+ import { getWorkspaceInfo, resolveAgentDir } from '../../lib/agents/commands.js';
7
7
  import { ExecutionStorage } from '../../lib/execution/storage.js';
8
8
  import { hasDevcontainerConfig } from '../../lib/execution/devcontainer.js';
9
9
  import { spawnForColumn, getAvailableAgents, isDockerRunning, isDevcontainerCliInstalled, } from '../../lib/execution/spawner.js';
@@ -152,7 +152,7 @@ export default class WorkWatch extends PMOCommand {
152
152
  }
153
153
  // Check if any agent has devcontainer
154
154
  const hasDevcontainer = workspaceInfo.agents.some(agent => {
155
- const agentDir = path.join(workspaceInfo.agentsPath, agent.name);
155
+ const agentDir = resolveAgentDir(workspaceInfo, agent.name);
156
156
  return hasDevcontainerConfig(agentDir);
157
157
  });
158
158
  // Prompt for environment and display mode if not provided
@@ -1,4 +1,15 @@
1
1
  import { Agent, Repository, MountMode as DBMountMode } from '../database/index.js';
2
+ /**
3
+ * Resolve the directory for an agent, cascading through resolution strategies.
4
+ * Handles both staff (persistent) and temp (ephemeral) agents.
5
+ *
6
+ * Resolution order:
7
+ * 1. Check agent's worktree_path from DB (most reliable)
8
+ * 2. Check ephemeral directory if agent type is ephemeral
9
+ * 3. Check both directories on disk as fallback
10
+ * 4. Fall back to staff path (caller handles missing dir error)
11
+ */
12
+ export declare function resolveAgentDir(workspaceInfo: WorkspaceInfo, agentName: string): string;
2
13
  /**
3
14
  * Format a list of agents for display in error messages.
4
15
  * Truncates long lists to avoid overwhelming output.
@@ -10,6 +10,43 @@ import { isValidAgentName, getSuggestedAgentNames, generateEphemeralAgentName, g
10
10
  import { createDevcontainerConfig } from '../execution/devcontainer.js';
11
11
  import { getGitIdentity } from '../pr/index.js';
12
12
  import { getPMOContext } from '../pmo/index.js';
13
+ /**
14
+ * Resolve the directory for an agent, cascading through resolution strategies.
15
+ * Handles both staff (persistent) and temp (ephemeral) agents.
16
+ *
17
+ * Resolution order:
18
+ * 1. Check agent's worktree_path from DB (most reliable)
19
+ * 2. Check ephemeral directory if agent type is ephemeral
20
+ * 3. Check both directories on disk as fallback
21
+ * 4. Fall back to staff path (caller handles missing dir error)
22
+ */
23
+ export function resolveAgentDir(workspaceInfo, agentName) {
24
+ const agent = workspaceInfo.agents.find(a => a.name === agentName);
25
+ // 1. Check DB worktree_path (most reliable - set during agent creation)
26
+ if (agent?.worktree_path) {
27
+ const fullWorktreePath = path.join(workspaceInfo.path, agent.worktree_path);
28
+ // worktree_path may point to repo subdir (e.g. agents/staff/altman/proletariat)
29
+ // Go up to the agent dir level
30
+ const agentDir = path.dirname(fullWorktreePath);
31
+ if (fs.existsSync(agentDir))
32
+ return agentDir;
33
+ }
34
+ // 2. Check ephemeral directory if agent type is ephemeral
35
+ if (agent?.type === 'ephemeral') {
36
+ const ephemeralDir = path.join(workspaceInfo.path, 'agents', workspaceInfo.ephemeralAgentsDir, agentName);
37
+ if (fs.existsSync(ephemeralDir))
38
+ return ephemeralDir;
39
+ }
40
+ // 3. Check both directories on disk (handles DB inconsistencies)
41
+ const tempDir = path.join(workspaceInfo.path, 'agents', workspaceInfo.ephemeralAgentsDir, agentName);
42
+ if (fs.existsSync(tempDir))
43
+ return tempDir;
44
+ const staffDir = path.join(workspaceInfo.agentsPath, agentName);
45
+ if (fs.existsSync(staffDir))
46
+ return staffDir;
47
+ // 4. Fall back to staff path - caller will handle the missing dir error
48
+ return staffDir;
49
+ }
13
50
  /**
14
51
  * Format a list of agents for display in error messages.
15
52
  * Truncates long lists to avoid overwhelming output.
@@ -169,15 +206,8 @@ export function getAgentStatus(workspaceInfo, agentName) {
169
206
  const exists = !!agentRecord;
170
207
  // Get worktrees from database to find actual agent location
171
208
  const worktrees = getAgentWorktrees(workspaceInfo.path, agentName);
172
- // Derive agent directory from worktree path, or fall back to default
173
- let agentDir = path.join(workspaceInfo.agentsPath, agentName);
174
- if (worktrees.length > 0) {
175
- // worktree_path is like "agents/staff/altman/proletariat-altman"
176
- // Agent dir is the parent: "agents/staff/altman"
177
- const worktreePath = worktrees[0].worktree_path;
178
- const agentDirRelative = path.dirname(worktreePath);
179
- agentDir = path.join(workspaceInfo.path, agentDirRelative);
180
- }
209
+ // Resolve agent directory (handles both staff and temp agents)
210
+ const agentDir = resolveAgentDir(workspaceInfo, agentName);
181
211
  const dirExists = fs.existsSync(agentDir);
182
212
  const status = {
183
213
  name: agentName,
@@ -314,7 +344,7 @@ export async function removeAgentsFromWorkspace(workspaceInfo, agentNames) {
314
344
  const failed = [];
315
345
  for (const agentName of agentNames) {
316
346
  try {
317
- const agentDir = path.join(workspaceInfo.agentsPath, agentName);
347
+ const agentDir = resolveAgentDir(workspaceInfo, agentName);
318
348
  // Stop and remove Docker container if it exists
319
349
  try {
320
350
  const containerId = execSync(`docker ps -aq --filter "label=devcontainer.local_folder=${agentDir}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
@@ -100,6 +100,7 @@ export function buildTmuxScript(sessionName, claudeCmd, displayMode) {
100
100
  export TERM=xterm-256color
101
101
  export COLORTERM=truecolor
102
102
  unset CI
103
+ unset CLAUDECODE
103
104
  echo "🚀 Starting: ${sessionName}"
104
105
  echo ""
105
106
  ${claudeCmd}
@@ -112,6 +113,7 @@ kill 1
112
113
  export TERM=xterm-256color
113
114
  export COLORTERM=truecolor
114
115
  unset CI
116
+ unset CLAUDECODE
115
117
  echo "🚀 Starting: ${sessionName}"
116
118
  echo ""
117
119
  ${claudeCmd}
@@ -470,6 +472,8 @@ export async function runHost(context, executor, config, displayMode = 'terminal
470
472
  const setTitleCmds = getSetTitleCommands(windowTitle);
471
473
  const scriptContent = `#!/bin/bash
472
474
  # Auto-generated script for ticket ${context.ticketId}
475
+ unset CI
476
+ unset CLAUDECODE
473
477
  SCRIPT_PATH="${scriptPath}"
474
478
  PROMPT_PATH="${promptPath}"
475
479
  ${setTitleCmds}
@@ -9,6 +9,7 @@ import * as path from 'node:path';
9
9
  import { execSync } from 'node:child_process';
10
10
  import { autoExportToBoard } from '../pmo/index.js';
11
11
  import { getWorkColumnSetting, findColumnByName } from '../pmo/utils.js';
12
+ import { resolveAgentDir } from '../agents/commands.js';
12
13
  import { findHQRoot } from '../repos/index.js';
13
14
  import { hasGitHubRemote } from '../repos/git.js';
14
15
  import { hasDevcontainerConfig } from './devcontainer.js';
@@ -182,8 +183,8 @@ export function selectAgent(strategy, availableAgents, executionStorage, roundRo
182
183
  export async function spawnAgentForTicket(ticket, agentName, storage, executionStorage, workspaceInfo, db, pmoPath, options = {}) {
183
184
  const log = options.log || (() => { });
184
185
  const executor = options.executor || DEFAULT_EXECUTION_CONFIG.defaultExecutor;
185
- // Determine agent directory and worktree path
186
- const agentDir = path.join(workspaceInfo.agentsPath, agentName);
186
+ // Determine agent directory and worktree path (handles staff and temp agents)
187
+ const agentDir = resolveAgentDir(workspaceInfo, agentName);
187
188
  if (!fs.existsSync(agentDir)) {
188
189
  return {
189
190
  success: false,
@@ -80,26 +80,42 @@ export const BUILTIN_THEMES = [
80
80
  {
81
81
  id: 'billionaires',
82
82
  name: 'billionaires',
83
- displayName: 'Billionaires & Tech Elite',
83
+ displayName: 'Billionaires',
84
84
  description: 'The ultra-wealthy work for you',
85
85
  persistentDir: 'staff',
86
86
  ephemeralDir: 'temp',
87
87
  names: [
88
- // Tech founders & executives
89
- 'altman', 'andreesen', 'bezos', 'branson', 'brin', 'buffett',
90
- 'cook', 'dalio', 'dario', 'dorsey', 'ellison', 'gates', 'huang',
91
- 'iger', 'jobs', 'kalanick', 'karpathy', 'lecun', 'ma', 'musk',
92
- 'nadella', 'page', 'pichai', 'sandberg', 'schultz', 'sutskever',
93
- 'thiel', 'wojcicki', 'zuck',
94
- // More tech leaders
95
- 'ballmer', 'benioff', 'chesky', 'collison', 'dell', 'durov',
96
- 'fink', 'fridman', 'grove', 'hastings', 'hoffman', 'horowitz',
97
- 'hurd', 'ive', 'khosla', 'knight', 'kutcher', 'levie', 'levinson',
98
- 'lynch', 'marcus', 'mayer', 'mcnealy', 'morin', 'neumann',
99
- 'omidyar', 'packard', 'parker', 'powell', 'rabois', 'rometty',
100
- 'ross', 'schmidt', 'sequoia', 'siebel', 'silbermann', 'sinofsky',
101
- 'spiegel', 'spolsky', 'sweeney', 'systrom', 'torvalds', 'wales',
102
- 'wozniak', 'yang', 'yegge', 'zhang', 'zhong'
88
+ 'altman', 'andreesen', 'ballmer', 'benioff', 'bezos', 'branson',
89
+ 'brin', 'buffett', 'chesky', 'collison', 'cook', 'dalio',
90
+ 'dario', 'dell', 'dorsey', 'durov', 'ellison', 'fink',
91
+ 'gates', 'hastings', 'hoffman', 'horowitz', 'huang', 'jobs',
92
+ 'kalanick', 'khosla', 'knight', 'levinson', 'ma', 'mcnealy',
93
+ 'musk', 'nadella', 'neumann', 'omidyar', 'page', 'parker',
94
+ 'pichai', 'sandberg', 'schmidt', 'schultz', 'siebel',
95
+ 'silbermann', 'spiegel', 'sweeney', 'systrom', 'thiel',
96
+ 'wozniak', 'yang', 'zuck'
97
+ ]
98
+ },
99
+ {
100
+ id: 'cracked-engineers',
101
+ name: 'cracked-engineers',
102
+ displayName: 'Cracked Engineers',
103
+ description: 'AI researchers, engineers, and tech legends',
104
+ persistentDir: 'staff',
105
+ ephemeralDir: 'temp',
106
+ names: [
107
+ // AI researchers
108
+ 'karpathy', 'lecun', 'sutskever',
109
+ // Engineers & creators
110
+ 'sinofsky', 'spolsky', 'torvalds', 'yegge',
111
+ // Investors & operators (non-billionaire)
112
+ 'grove', 'kutcher', 'rabois', 'ross',
113
+ // Podcasters & educators
114
+ 'fridman',
115
+ // Other tech figures
116
+ 'hurd', 'iger', 'ive', 'levie', 'lynch', 'marcus', 'mayer',
117
+ 'morin', 'powell', 'rometty', 'wales', 'wojcicki', 'zhang',
118
+ 'zhong'
103
119
  ]
104
120
  },
105
121
  {