@proletariat/cli 0.3.55 → 0.3.57

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 (246) hide show
  1. package/README.md +74 -5
  2. package/bin/validate-better-sqlite3.cjs +44 -5
  3. package/dist/commands/agent/cleanup.d.ts +1 -0
  4. package/dist/commands/agent/cleanup.js +11 -1
  5. package/dist/commands/agent/cleanup.js.map +1 -1
  6. package/dist/commands/agent/rebuild.js +1 -1
  7. package/dist/commands/agent/rebuild.js.map +1 -1
  8. package/dist/commands/asana/import.d.ts +14 -0
  9. package/dist/commands/asana/import.js +240 -0
  10. package/dist/commands/asana/import.js.map +1 -0
  11. package/dist/commands/claude-yolo.d.ts +20 -0
  12. package/dist/commands/claude-yolo.js +86 -0
  13. package/dist/commands/claude-yolo.js.map +1 -0
  14. package/dist/commands/codex/index.d.ts +23 -0
  15. package/dist/commands/codex/index.js +168 -0
  16. package/dist/commands/codex/index.js.map +1 -0
  17. package/dist/commands/codex-yolo.d.ts +20 -0
  18. package/dist/commands/codex-yolo.js +86 -0
  19. package/dist/commands/codex-yolo.js.map +1 -0
  20. package/dist/commands/config/index.js +2 -2
  21. package/dist/commands/config/index.js.map +1 -1
  22. package/dist/commands/dashboard.d.ts +38 -0
  23. package/dist/commands/dashboard.js +352 -0
  24. package/dist/commands/dashboard.js.map +1 -0
  25. package/dist/commands/docker/clean.js +1 -1
  26. package/dist/commands/docker/clean.js.map +1 -1
  27. package/dist/commands/docker/list.js +1 -1
  28. package/dist/commands/docker/list.js.map +1 -1
  29. package/dist/commands/docker/logs.js +1 -1
  30. package/dist/commands/docker/logs.js.map +1 -1
  31. package/dist/commands/docker/restart.js +1 -1
  32. package/dist/commands/docker/restart.js.map +1 -1
  33. package/dist/commands/docker/shell.js +1 -1
  34. package/dist/commands/docker/shell.js.map +1 -1
  35. package/dist/commands/docker/start.js +1 -1
  36. package/dist/commands/docker/start.js.map +1 -1
  37. package/dist/commands/docker/stop.js +1 -1
  38. package/dist/commands/docker/stop.js.map +1 -1
  39. package/dist/commands/docker/sync.js +1 -1
  40. package/dist/commands/docker/sync.js.map +1 -1
  41. package/dist/commands/execution/config.js +2 -2
  42. package/dist/commands/execution/config.js.map +1 -1
  43. package/dist/commands/execution/list.js +1 -1
  44. package/dist/commands/execution/list.js.map +1 -1
  45. package/dist/commands/execution/logs.js +10 -8
  46. package/dist/commands/execution/logs.js.map +1 -1
  47. package/dist/commands/execution/stop.js +1 -1
  48. package/dist/commands/execution/stop.js.map +1 -1
  49. package/dist/commands/execution/view.js +1 -1
  50. package/dist/commands/execution/view.js.map +1 -1
  51. package/dist/commands/init.d.ts +0 -16
  52. package/dist/commands/init.js +50 -160
  53. package/dist/commands/init.js.map +1 -1
  54. package/dist/commands/logs.d.ts +20 -0
  55. package/dist/commands/logs.js +84 -0
  56. package/dist/commands/logs.js.map +1 -0
  57. package/dist/commands/mcp-server.js +1 -1
  58. package/dist/commands/mcp-server.js.map +1 -1
  59. package/dist/commands/new.d.ts +27 -0
  60. package/dist/commands/new.js +184 -0
  61. package/dist/commands/new.js.map +1 -0
  62. package/dist/commands/orchestrator/attach.d.ts +1 -0
  63. package/dist/commands/orchestrator/attach.js +159 -26
  64. package/dist/commands/orchestrator/attach.js.map +1 -1
  65. package/dist/commands/orchestrator/start.d.ts +20 -0
  66. package/dist/commands/orchestrator/start.js +123 -14
  67. package/dist/commands/orchestrator/start.js.map +1 -1
  68. package/dist/commands/orchestrator/status.d.ts +4 -0
  69. package/dist/commands/orchestrator/status.js +70 -29
  70. package/dist/commands/orchestrator/status.js.map +1 -1
  71. package/dist/commands/orchestrator/stop.js +57 -23
  72. package/dist/commands/orchestrator/stop.js.map +1 -1
  73. package/dist/commands/peek.d.ts +20 -0
  74. package/dist/commands/peek.js +84 -0
  75. package/dist/commands/peek.js.map +1 -0
  76. package/dist/commands/poke.d.ts +20 -0
  77. package/dist/commands/poke.js +89 -0
  78. package/dist/commands/poke.js.map +1 -0
  79. package/dist/commands/pr/link.js +1 -1
  80. package/dist/commands/pr/link.js.map +1 -1
  81. package/dist/commands/pr/status.js +1 -1
  82. package/dist/commands/pr/status.js.map +1 -1
  83. package/dist/commands/ps.d.ts +18 -0
  84. package/dist/commands/ps.js +123 -0
  85. package/dist/commands/ps.js.map +1 -0
  86. package/dist/commands/qa/index.js +1 -1
  87. package/dist/commands/qa/index.js.map +1 -1
  88. package/dist/commands/repo/add.js +1 -1
  89. package/dist/commands/repo/add.js.map +1 -1
  90. package/dist/commands/repo/fix-remotes.d.ts +14 -0
  91. package/dist/commands/repo/fix-remotes.js +154 -0
  92. package/dist/commands/repo/fix-remotes.js.map +1 -0
  93. package/dist/commands/repo/list.js +1 -1
  94. package/dist/commands/repo/list.js.map +1 -1
  95. package/dist/commands/repo/remove.js +1 -1
  96. package/dist/commands/repo/remove.js.map +1 -1
  97. package/dist/commands/repo/view.js +1 -1
  98. package/dist/commands/repo/view.js.map +1 -1
  99. package/dist/commands/run/index.d.ts +25 -0
  100. package/dist/commands/run/index.js +212 -0
  101. package/dist/commands/run/index.js.map +1 -0
  102. package/dist/commands/session/index.js +4 -0
  103. package/dist/commands/session/index.js.map +1 -1
  104. package/dist/commands/session/prune.d.ts +18 -0
  105. package/dist/commands/session/prune.js +327 -0
  106. package/dist/commands/session/prune.js.map +1 -0
  107. package/dist/commands/shortcut/connect.d.ts +15 -0
  108. package/dist/commands/shortcut/connect.js +210 -0
  109. package/dist/commands/shortcut/connect.js.map +1 -0
  110. package/dist/commands/stop.d.ts +19 -0
  111. package/dist/commands/stop.js +83 -0
  112. package/dist/commands/stop.js.map +1 -0
  113. package/dist/commands/work/asana.d.ts +23 -0
  114. package/dist/commands/work/asana.js +213 -0
  115. package/dist/commands/work/asana.js.map +1 -0
  116. package/dist/commands/work/complete.js +1 -1
  117. package/dist/commands/work/complete.js.map +1 -1
  118. package/dist/commands/work/ready.js +1 -1
  119. package/dist/commands/work/ready.js.map +1 -1
  120. package/dist/commands/work/review.js +1 -1
  121. package/dist/commands/work/review.js.map +1 -1
  122. package/dist/commands/work/revise.js +1 -1
  123. package/dist/commands/work/revise.js.map +1 -1
  124. package/dist/commands/work/shortcut.d.ts +23 -0
  125. package/dist/commands/work/shortcut.js +212 -0
  126. package/dist/commands/work/shortcut.js.map +1 -0
  127. package/dist/commands/work/spawn.d.ts +3 -0
  128. package/dist/commands/work/spawn.js +175 -2
  129. package/dist/commands/work/spawn.js.map +1 -1
  130. package/dist/commands/work/start.js +54 -45
  131. package/dist/commands/work/start.js.map +1 -1
  132. package/dist/commands/work/watch.js +1 -1
  133. package/dist/commands/work/watch.js.map +1 -1
  134. package/dist/commands/workspace/add.js +1 -1
  135. package/dist/commands/workspace/add.js.map +1 -1
  136. package/dist/commands/workspace/list.js +1 -1
  137. package/dist/commands/workspace/list.js.map +1 -1
  138. package/dist/hooks/init.d.ts +1 -1
  139. package/dist/hooks/init.js +6 -6
  140. package/dist/hooks/init.js.map +1 -1
  141. package/dist/lib/agent-naming.d.ts +15 -0
  142. package/dist/lib/agent-naming.js +32 -0
  143. package/dist/lib/agent-naming.js.map +1 -0
  144. package/dist/lib/agents/commands.d.ts +2 -0
  145. package/dist/lib/agents/commands.js +56 -51
  146. package/dist/lib/agents/commands.js.map +1 -1
  147. package/dist/lib/agents/index.js +11 -7
  148. package/dist/lib/agents/index.js.map +1 -1
  149. package/dist/lib/asana/client.d.ts +8 -0
  150. package/dist/lib/asana/client.js +26 -7
  151. package/dist/lib/asana/client.js.map +1 -1
  152. package/dist/lib/asana/types.d.ts +20 -0
  153. package/dist/lib/branch/index.d.ts +36 -0
  154. package/dist/lib/branch/index.js +129 -0
  155. package/dist/lib/branch/index.js.map +1 -1
  156. package/dist/lib/database/index.js +1 -1
  157. package/dist/lib/database/index.js.map +1 -1
  158. package/dist/lib/database/native-validation.d.ts +2 -0
  159. package/dist/lib/database/native-validation.js +30 -1
  160. package/dist/lib/database/native-validation.js.map +1 -1
  161. package/dist/lib/events/emitting-runner.d.ts +30 -0
  162. package/dist/lib/events/emitting-runner.js +95 -0
  163. package/dist/lib/events/emitting-runner.js.map +1 -0
  164. package/dist/lib/events/event-bus.d.ts +54 -0
  165. package/dist/lib/events/event-bus.js +107 -0
  166. package/dist/lib/events/event-bus.js.map +1 -0
  167. package/dist/lib/events/events.d.ts +67 -0
  168. package/dist/lib/events/events.js +8 -0
  169. package/dist/lib/events/events.js.map +1 -0
  170. package/dist/lib/events/index.d.ts +7 -0
  171. package/dist/lib/events/index.js +6 -0
  172. package/dist/lib/events/index.js.map +1 -0
  173. package/dist/lib/execution/devcontainer.d.ts +27 -0
  174. package/dist/lib/execution/devcontainer.js +80 -0
  175. package/dist/lib/execution/devcontainer.js.map +1 -1
  176. package/dist/lib/execution/runners.d.ts +28 -0
  177. package/dist/lib/execution/runners.js +536 -35
  178. package/dist/lib/execution/runners.js.map +1 -1
  179. package/dist/lib/execution/spawner.js +38 -17
  180. package/dist/lib/execution/spawner.js.map +1 -1
  181. package/dist/lib/execution/types.d.ts +2 -0
  182. package/dist/lib/execution/types.js.map +1 -1
  183. package/dist/lib/external-issues/adapters.d.ts +34 -0
  184. package/dist/lib/external-issues/adapters.js +191 -0
  185. package/dist/lib/external-issues/adapters.js.map +1 -1
  186. package/dist/lib/external-issues/asana.d.ts +75 -0
  187. package/dist/lib/external-issues/asana.js +243 -0
  188. package/dist/lib/external-issues/asana.js.map +1 -0
  189. package/dist/lib/external-issues/index.d.ts +4 -2
  190. package/dist/lib/external-issues/index.js +6 -2
  191. package/dist/lib/external-issues/index.js.map +1 -1
  192. package/dist/lib/external-issues/linear.js.map +1 -1
  193. package/dist/lib/external-issues/mapping-store.js +1 -1
  194. package/dist/lib/external-issues/shortcut.d.ts +86 -0
  195. package/dist/lib/external-issues/shortcut.js +274 -0
  196. package/dist/lib/external-issues/shortcut.js.map +1 -0
  197. package/dist/lib/external-issues/types.d.ts +3 -3
  198. package/dist/lib/external-issues/types.js +1 -1
  199. package/dist/lib/external-issues/types.js.map +1 -1
  200. package/dist/lib/mcp/tools/cli-passthrough.js +1 -1
  201. package/dist/lib/mcp/tools/cli-passthrough.js.map +1 -1
  202. package/dist/lib/mcp/tools/work.js +1 -1
  203. package/dist/lib/mcp/tools/work.js.map +1 -1
  204. package/dist/lib/pmo/index.d.ts +2 -2
  205. package/dist/lib/pmo/index.js +3 -3
  206. package/dist/lib/pmo/index.js.map +1 -1
  207. package/dist/lib/pmo/sync-manager.js +1 -1
  208. package/dist/lib/pmo/sync-manager.js.map +1 -1
  209. package/dist/lib/pmo/watcher.js +1 -1
  210. package/dist/lib/pmo/watcher.js.map +1 -1
  211. package/dist/lib/repos/git.d.ts +44 -0
  212. package/dist/lib/repos/git.js +127 -0
  213. package/dist/lib/repos/git.js.map +1 -1
  214. package/dist/lib/repos/index.js +36 -3
  215. package/dist/lib/repos/index.js.map +1 -1
  216. package/dist/lib/runners/agent-runner.d.ts +92 -0
  217. package/dist/lib/runners/agent-runner.js +9 -0
  218. package/dist/lib/runners/agent-runner.js.map +1 -0
  219. package/dist/lib/runners/claude-code-runner.d.ts +53 -0
  220. package/dist/lib/runners/claude-code-runner.js +132 -0
  221. package/dist/lib/runners/claude-code-runner.js.map +1 -0
  222. package/dist/lib/runners/index.d.ts +34 -0
  223. package/dist/lib/runners/index.js +97 -0
  224. package/dist/lib/runners/index.js.map +1 -0
  225. package/dist/lib/session-store.d.ts +70 -0
  226. package/dist/lib/session-store.js +167 -0
  227. package/dist/lib/session-store.js.map +1 -0
  228. package/dist/lib/shortcut/config.d.ts +44 -0
  229. package/dist/lib/shortcut/config.js +98 -0
  230. package/dist/lib/shortcut/config.js.map +1 -0
  231. package/dist/lib/shortcut/index.d.ts +7 -0
  232. package/dist/lib/shortcut/index.js +7 -0
  233. package/dist/lib/shortcut/index.js.map +1 -0
  234. package/dist/lib/work-source/client.d.ts +10 -0
  235. package/dist/lib/work-source/client.js +74 -0
  236. package/dist/lib/work-source/client.js.map +1 -0
  237. package/dist/lib/work-source/config.d.ts +1 -1
  238. package/dist/lib/work-source/config.js +17 -1
  239. package/dist/lib/work-source/config.js.map +1 -1
  240. package/dist/lib/work-source/index.d.ts +1 -0
  241. package/dist/lib/work-source/index.js +1 -0
  242. package/dist/lib/work-source/index.js.map +1 -1
  243. package/dist/lib/workspace.js +2 -2
  244. package/dist/lib/workspace.js.map +1 -1
  245. package/oclif.manifest.json +8135 -6979
  246. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runner.js","sourceRoot":"","sources":["../../../src/lib/runners/agent-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * ClaudeCodeRunner
3
+ *
4
+ * AgentRunner implementation for Claude Code.
5
+ * Wraps the existing runHost() execution logic from execution/runners.ts
6
+ * to provide a pluggable runner interface while maintaining full backward
7
+ * compatibility with `prlt work start`.
8
+ */
9
+ import type { AgentRunner, AgentSession, SpawnConfig } from './agent-runner.js';
10
+ import type { ExecutionContext, ExecutionConfig } from '../execution/types.js';
11
+ /**
12
+ * Claude Code agent runner.
13
+ *
14
+ * Delegates to the existing runHost() function for spawning, which handles:
15
+ * - tmux session creation for persistence
16
+ * - Terminal tab opening (iTerm, Terminal.app, Ghostty, etc.)
17
+ * - Prompt building and script generation
18
+ * - Permission mode and output mode configuration
19
+ *
20
+ * The peek/poke/stop methods use tmux commands directly since Claude Code
21
+ * sessions always run inside tmux.
22
+ */
23
+ export declare class ClaudeCodeRunner implements AgentRunner {
24
+ readonly name = "claude-code";
25
+ spawn(config: SpawnConfig): Promise<AgentSession>;
26
+ getStatus(session: AgentSession): Promise<'running' | 'done' | 'error'>;
27
+ peek(session: AgentSession, lines?: number): Promise<string>;
28
+ poke(session: AgentSession, message: string): Promise<void>;
29
+ stop(session: AgentSession): Promise<void>;
30
+ /**
31
+ * Build a tmux session name from spawn config.
32
+ * Uses the same naming convention as the existing system:
33
+ * "{ticketId}-{action}-{agentName}" or falls back to a generated name.
34
+ */
35
+ private buildSessionName;
36
+ /**
37
+ * Build an ExecutionContext from SpawnConfig.
38
+ * Maps the simplified SpawnConfig to the richer ExecutionContext used by runHost().
39
+ */
40
+ private buildExecutionContext;
41
+ /**
42
+ * Build ExecutionConfig from SpawnConfig defaults.
43
+ */
44
+ private buildExecutionConfig;
45
+ }
46
+ /**
47
+ * Create a ClaudeCodeRunner that uses a full ExecutionContext and config.
48
+ *
49
+ * This is the integration point for `prlt work start` — it provides a way
50
+ * to spawn Claude Code using the existing rich context while still going
51
+ * through the AgentRunner interface.
52
+ */
53
+ export declare function createClaudeCodeSession(context: ExecutionContext, config?: ExecutionConfig, displayMode?: 'terminal' | 'background' | 'foreground'): Promise<import("../execution/runners.js").RunnerResult>;
@@ -0,0 +1,132 @@
1
+ /**
2
+ * ClaudeCodeRunner
3
+ *
4
+ * AgentRunner implementation for Claude Code.
5
+ * Wraps the existing runHost() execution logic from execution/runners.ts
6
+ * to provide a pluggable runner interface while maintaining full backward
7
+ * compatibility with `prlt work start`.
8
+ */
9
+ import { execSync } from 'node:child_process';
10
+ import { runHost, } from '../execution/runners.js';
11
+ import { DEFAULT_EXECUTION_CONFIG } from '../execution/types.js';
12
+ import { captureTmuxPane } from '../execution/session-utils.js';
13
+ /**
14
+ * Claude Code agent runner.
15
+ *
16
+ * Delegates to the existing runHost() function for spawning, which handles:
17
+ * - tmux session creation for persistence
18
+ * - Terminal tab opening (iTerm, Terminal.app, Ghostty, etc.)
19
+ * - Prompt building and script generation
20
+ * - Permission mode and output mode configuration
21
+ *
22
+ * The peek/poke/stop methods use tmux commands directly since Claude Code
23
+ * sessions always run inside tmux.
24
+ */
25
+ export class ClaudeCodeRunner {
26
+ name = 'claude-code';
27
+ async spawn(config) {
28
+ const sessionName = this.buildSessionName(config);
29
+ const context = this.buildExecutionContext(config, sessionName);
30
+ const executionConfig = this.buildExecutionConfig(config);
31
+ const result = await runHost(context, 'claude-code', executionConfig, config.background ? 'background' : 'terminal');
32
+ if (!result.success) {
33
+ throw new Error(result.error || 'Failed to spawn Claude Code session');
34
+ }
35
+ return {
36
+ id: result.sessionId || sessionName,
37
+ runner: this.name,
38
+ sessionName: result.sessionId || sessionName,
39
+ task: config.task,
40
+ workdir: config.workdir,
41
+ startedAt: new Date(),
42
+ status: 'running',
43
+ };
44
+ }
45
+ async getStatus(session) {
46
+ try {
47
+ const output = execSync(`tmux has-session -t "${session.sessionName}" 2>/dev/null && echo "exists"`, { encoding: 'utf-8', stdio: 'pipe' }).trim();
48
+ if (output === 'exists') {
49
+ return 'running';
50
+ }
51
+ return 'done';
52
+ }
53
+ catch {
54
+ // tmux session doesn't exist — agent has finished or was killed
55
+ return 'done';
56
+ }
57
+ }
58
+ async peek(session, lines = 50) {
59
+ const output = captureTmuxPane(session.sessionName, lines);
60
+ return output ?? '';
61
+ }
62
+ async poke(session, message) {
63
+ try {
64
+ // Send the message as keystrokes followed by Enter
65
+ execSync(`tmux send-keys -t "${session.sessionName}" ${JSON.stringify(message)} Enter`, { stdio: 'pipe' });
66
+ }
67
+ catch (error) {
68
+ throw new Error(`Failed to send message to session "${session.sessionName}": ${error instanceof Error ? error.message : error}`);
69
+ }
70
+ }
71
+ async stop(session) {
72
+ try {
73
+ // Send C-c first to gracefully interrupt the running process
74
+ execSync(`tmux send-keys -t "${session.sessionName}" C-c`, { stdio: 'pipe' });
75
+ // Brief delay to let the process handle the signal
76
+ await new Promise(resolve => setTimeout(resolve, 500));
77
+ // Kill the tmux session
78
+ execSync(`tmux kill-session -t "${session.sessionName}"`, { stdio: 'pipe' });
79
+ }
80
+ catch {
81
+ // Session may already be dead — that's fine
82
+ }
83
+ }
84
+ /**
85
+ * Build a tmux session name from spawn config.
86
+ * Uses the same naming convention as the existing system:
87
+ * "{ticketId}-{action}-{agentName}" or falls back to a generated name.
88
+ */
89
+ buildSessionName(config) {
90
+ // If we have a full ExecutionContext-like task with ticket info, use buildSessionName
91
+ // Otherwise generate a simple name from the runner and timestamp
92
+ return `claude-${Date.now()}`;
93
+ }
94
+ /**
95
+ * Build an ExecutionContext from SpawnConfig.
96
+ * Maps the simplified SpawnConfig to the richer ExecutionContext used by runHost().
97
+ */
98
+ buildExecutionContext(config, sessionName) {
99
+ return {
100
+ ticketId: sessionName,
101
+ ticketTitle: config.task.slice(0, 80),
102
+ ticketDescription: config.task,
103
+ agentName: 'agent',
104
+ agentDir: config.workdir,
105
+ worktreePath: config.workdir,
106
+ branch: 'main',
107
+ createPR: config.createPR,
108
+ actionName: 'work',
109
+ actionPrompt: config.task,
110
+ };
111
+ }
112
+ /**
113
+ * Build ExecutionConfig from SpawnConfig defaults.
114
+ */
115
+ buildExecutionConfig(config) {
116
+ return {
117
+ ...DEFAULT_EXECUTION_CONFIG,
118
+ permissionMode: 'danger',
119
+ };
120
+ }
121
+ }
122
+ /**
123
+ * Create a ClaudeCodeRunner that uses a full ExecutionContext and config.
124
+ *
125
+ * This is the integration point for `prlt work start` — it provides a way
126
+ * to spawn Claude Code using the existing rich context while still going
127
+ * through the AgentRunner interface.
128
+ */
129
+ export function createClaudeCodeSession(context, config = DEFAULT_EXECUTION_CONFIG, displayMode = 'terminal') {
130
+ return runHost(context, 'claude-code', config, displayMode);
131
+ }
132
+ //# sourceMappingURL=claude-code-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-runner.js","sourceRoot":"","sources":["../../../src/lib/runners/claude-code-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Runner Registry
3
+ *
4
+ * Central registry for agent runners. Provides auto-detection of available
5
+ * runtimes and a simple API for retrieving runner instances.
6
+ *
7
+ * Auto-detect order: claude-code → codex → pi
8
+ */
9
+ import type { AgentRunner } from './agent-runner.js';
10
+ export type { AgentRunner, AgentSession, SpawnConfig } from './agent-runner.js';
11
+ export { ClaudeCodeRunner } from './claude-code-runner.js';
12
+ export { createClaudeCodeSession } from './claude-code-runner.js';
13
+ /**
14
+ * Get all runners whose CLI binary is available on PATH.
15
+ *
16
+ * Returns runners in detection order (claude-code, codex, pi).
17
+ * Only runners with an installed CLI are included.
18
+ */
19
+ export declare function getAvailableRunners(): AgentRunner[];
20
+ /**
21
+ * Get a specific runner by name, or the default (first available) runner.
22
+ *
23
+ * @param name - Runner name to look up (e.g. 'claude-code', 'codex').
24
+ * If omitted, returns the first available runner.
25
+ * @returns The runner instance, or null if not found / not available.
26
+ */
27
+ export declare function getRunner(name?: string): AgentRunner | null;
28
+ /**
29
+ * Wrap a runner with event emission.
30
+ *
31
+ * Returns an EventEmittingRunner that delegates to the given runner
32
+ * while emitting runtime events on the global EventBus.
33
+ */
34
+ export declare function withEvents(runner: AgentRunner): AgentRunner;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Runner Registry
3
+ *
4
+ * Central registry for agent runners. Provides auto-detection of available
5
+ * runtimes and a simple API for retrieving runner instances.
6
+ *
7
+ * Auto-detect order: claude-code → codex → pi
8
+ */
9
+ import { execSync } from 'node:child_process';
10
+ import { ClaudeCodeRunner } from './claude-code-runner.js';
11
+ import { EventEmittingRunner } from '../events/emitting-runner.js';
12
+ export { ClaudeCodeRunner } from './claude-code-runner.js';
13
+ export { createClaudeCodeSession } from './claude-code-runner.js';
14
+ // =============================================================================
15
+ // Runner Registry
16
+ // =============================================================================
17
+ /**
18
+ * Known runner definitions.
19
+ * Maps runner name to the CLI binary that must be on PATH and a factory function.
20
+ *
21
+ * Detection order matters — first available runner is the default.
22
+ */
23
+ const RUNNER_DEFINITIONS = [
24
+ {
25
+ name: 'claude-code',
26
+ binary: 'claude',
27
+ create: () => new ClaudeCodeRunner(),
28
+ },
29
+ // Future runners — uncomment when implemented:
30
+ // {
31
+ // name: 'codex',
32
+ // binary: 'codex',
33
+ // create: () => new CodexRunner(),
34
+ // },
35
+ // {
36
+ // name: 'pi',
37
+ // binary: 'pi',
38
+ // create: () => new PiRunner(),
39
+ // },
40
+ ];
41
+ /**
42
+ * Check if a CLI binary is available on PATH.
43
+ */
44
+ function isBinaryAvailable(binary) {
45
+ try {
46
+ execSync(`command -v ${binary}`, { stdio: 'pipe' });
47
+ return true;
48
+ }
49
+ catch {
50
+ return false;
51
+ }
52
+ }
53
+ /**
54
+ * Get all runners whose CLI binary is available on PATH.
55
+ *
56
+ * Returns runners in detection order (claude-code, codex, pi).
57
+ * Only runners with an installed CLI are included.
58
+ */
59
+ export function getAvailableRunners() {
60
+ return RUNNER_DEFINITIONS
61
+ .filter(def => isBinaryAvailable(def.binary))
62
+ .map(def => def.create());
63
+ }
64
+ /**
65
+ * Get a specific runner by name, or the default (first available) runner.
66
+ *
67
+ * @param name - Runner name to look up (e.g. 'claude-code', 'codex').
68
+ * If omitted, returns the first available runner.
69
+ * @returns The runner instance, or null if not found / not available.
70
+ */
71
+ export function getRunner(name) {
72
+ if (name) {
73
+ const def = RUNNER_DEFINITIONS.find(d => d.name === name);
74
+ if (!def)
75
+ return null;
76
+ if (!isBinaryAvailable(def.binary))
77
+ return null;
78
+ return def.create();
79
+ }
80
+ // Auto-detect: return first available
81
+ for (const def of RUNNER_DEFINITIONS) {
82
+ if (isBinaryAvailable(def.binary)) {
83
+ return def.create();
84
+ }
85
+ }
86
+ return null;
87
+ }
88
+ /**
89
+ * Wrap a runner with event emission.
90
+ *
91
+ * Returns an EventEmittingRunner that delegates to the given runner
92
+ * while emitting runtime events on the global EventBus.
93
+ */
94
+ export function withEvents(runner) {
95
+ return new EventEmittingRunner(runner);
96
+ }
97
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/runners/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAIlE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AAEjE,gFAAgF;AAChF,kBAAkB;AAClB,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,kBAAkB,GAInB;IACH;QACE,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,gBAAgB,EAAE;KACrC;IACD,+CAA+C;IAC/C,IAAI;IACJ,mBAAmB;IACnB,qBAAqB;IACrB,qCAAqC;IACrC,KAAK;IACL,IAAI;IACJ,gBAAgB;IAChB,kBAAkB;IAClB,kCAAkC;IAClC,KAAK;CACN,CAAA;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,MAAc;IACvC,IAAI,CAAC;QACH,QAAQ,CAAC,cAAc,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;QACnD,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,kBAAkB;SACtB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;SAC5C,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;AAC7B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,GAAG,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;QACzD,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QACrB,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAA;QAC/C,OAAO,GAAG,CAAC,MAAM,EAAE,CAAA;IACrB,CAAC;IAED,sCAAsC;IACtC,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACrC,IAAI,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,OAAO,GAAG,CAAC,MAAM,EAAE,CAAA;QACrB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,MAAmB;IAC5C,OAAO,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAA;AACxC,CAAC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Global Session Store
3
+ *
4
+ * Tracks agent sessions across all repos on the machine.
5
+ * Works without HQ / PMO — just needs ~/.proletariat/sessions.db.
6
+ *
7
+ * Schema: id, agentName, runner, task, workdir, sessionName,
8
+ * environment, permissionMode, status, startedAt, endedAt
9
+ */
10
+ export interface SessionRecord {
11
+ id: string;
12
+ agentName: string;
13
+ runner: string;
14
+ task: string;
15
+ workdir: string;
16
+ sessionName: string;
17
+ environment: 'host' | 'docker' | 'podman';
18
+ permissionMode: 'danger' | 'safe';
19
+ status: 'running' | 'done' | 'error' | 'stopped';
20
+ startedAt: Date;
21
+ endedAt?: Date;
22
+ }
23
+ export declare class SessionStore {
24
+ private db;
25
+ constructor(dbPath?: string);
26
+ private ensureSchema;
27
+ /**
28
+ * Create a new session record.
29
+ */
30
+ create(params: {
31
+ agentName: string;
32
+ runner: string;
33
+ task: string;
34
+ workdir: string;
35
+ sessionName: string;
36
+ environment: SessionRecord['environment'];
37
+ permissionMode: SessionRecord['permissionMode'];
38
+ }): SessionRecord;
39
+ /**
40
+ * Get a session by ID or agent name.
41
+ */
42
+ get(idOrName: string): SessionRecord | null;
43
+ /**
44
+ * Get a session by tmux session name.
45
+ */
46
+ getBySessionName(sessionName: string): SessionRecord | null;
47
+ /**
48
+ * List sessions, optionally filtered by status.
49
+ */
50
+ list(status?: SessionRecord['status']): SessionRecord[];
51
+ /**
52
+ * Update session status.
53
+ */
54
+ updateStatus(id: string, status: SessionRecord['status']): void;
55
+ /**
56
+ * Reconcile session statuses with actual tmux sessions.
57
+ * Marks sessions as 'done' if their tmux session no longer exists.
58
+ */
59
+ reconcile(): void;
60
+ /**
61
+ * Resolve an identifier to a session.
62
+ * Tries: exact ID match, agent name, partial match on agent name or session name.
63
+ */
64
+ resolve(identifier: string): SessionRecord | null;
65
+ /**
66
+ * Check if a tmux session is alive.
67
+ */
68
+ private isTmuxSessionAlive;
69
+ close(): void;
70
+ }
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Global Session Store
3
+ *
4
+ * Tracks agent sessions across all repos on the machine.
5
+ * Works without HQ / PMO — just needs ~/.proletariat/sessions.db.
6
+ *
7
+ * Schema: id, agentName, runner, task, workdir, sessionName,
8
+ * environment, permissionMode, status, startedAt, endedAt
9
+ */
10
+ import * as fs from 'node:fs';
11
+ import * as path from 'node:path';
12
+ import * as os from 'node:os';
13
+ import Database from 'better-sqlite3';
14
+ import { execSync } from 'node:child_process';
15
+ // =============================================================================
16
+ // Helpers
17
+ // =============================================================================
18
+ function rowToSession(row) {
19
+ return {
20
+ id: row.id,
21
+ agentName: row.agent_name,
22
+ runner: row.runner,
23
+ task: row.task,
24
+ workdir: row.workdir,
25
+ sessionName: row.session_name,
26
+ environment: row.environment,
27
+ permissionMode: row.permission_mode,
28
+ status: row.status,
29
+ startedAt: new Date(row.started_at),
30
+ endedAt: row.ended_at ? new Date(row.ended_at) : undefined,
31
+ };
32
+ }
33
+ function getDbPath() {
34
+ const dir = path.join(os.homedir(), '.proletariat');
35
+ fs.mkdirSync(dir, { recursive: true });
36
+ return path.join(dir, 'sessions.db');
37
+ }
38
+ // =============================================================================
39
+ // Session Store
40
+ // =============================================================================
41
+ export class SessionStore {
42
+ db;
43
+ constructor(dbPath) {
44
+ this.db = new Database(dbPath ?? getDbPath());
45
+ this.ensureSchema();
46
+ }
47
+ ensureSchema() {
48
+ this.db.exec(`
49
+ CREATE TABLE IF NOT EXISTS sessions (
50
+ id TEXT PRIMARY KEY,
51
+ agent_name TEXT NOT NULL,
52
+ runner TEXT NOT NULL,
53
+ task TEXT NOT NULL,
54
+ workdir TEXT NOT NULL,
55
+ session_name TEXT NOT NULL,
56
+ environment TEXT NOT NULL DEFAULT 'host',
57
+ permission_mode TEXT NOT NULL DEFAULT 'safe',
58
+ status TEXT NOT NULL DEFAULT 'running',
59
+ started_at INTEGER NOT NULL,
60
+ ended_at INTEGER
61
+ )
62
+ `);
63
+ }
64
+ /**
65
+ * Create a new session record.
66
+ */
67
+ create(params) {
68
+ const id = `SES-${Date.now().toString(36).toUpperCase()}`;
69
+ const now = Date.now();
70
+ this.db.prepare(`
71
+ INSERT INTO sessions (id, agent_name, runner, task, workdir, session_name, environment, permission_mode, status, started_at)
72
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'running', ?)
73
+ `).run(id, params.agentName, params.runner, params.task, params.workdir, params.sessionName, params.environment, params.permissionMode, now);
74
+ return {
75
+ id,
76
+ agentName: params.agentName,
77
+ runner: params.runner,
78
+ task: params.task,
79
+ workdir: params.workdir,
80
+ sessionName: params.sessionName,
81
+ environment: params.environment,
82
+ permissionMode: params.permissionMode,
83
+ status: 'running',
84
+ startedAt: new Date(now),
85
+ };
86
+ }
87
+ /**
88
+ * Get a session by ID or agent name.
89
+ */
90
+ get(idOrName) {
91
+ const row = this.db.prepare(`SELECT * FROM sessions WHERE id = ? OR agent_name = ? ORDER BY started_at DESC LIMIT 1`).get(idOrName, idOrName);
92
+ return row ? rowToSession(row) : null;
93
+ }
94
+ /**
95
+ * Get a session by tmux session name.
96
+ */
97
+ getBySessionName(sessionName) {
98
+ const row = this.db.prepare(`SELECT * FROM sessions WHERE session_name = ? ORDER BY started_at DESC LIMIT 1`).get(sessionName);
99
+ return row ? rowToSession(row) : null;
100
+ }
101
+ /**
102
+ * List sessions, optionally filtered by status.
103
+ */
104
+ list(status) {
105
+ let rows;
106
+ if (status) {
107
+ rows = this.db.prepare(`SELECT * FROM sessions WHERE status = ? ORDER BY started_at DESC`).all(status);
108
+ }
109
+ else {
110
+ rows = this.db.prepare(`SELECT * FROM sessions ORDER BY started_at DESC`).all();
111
+ }
112
+ return rows.map(rowToSession);
113
+ }
114
+ /**
115
+ * Update session status.
116
+ */
117
+ updateStatus(id, status) {
118
+ const endedAt = (status === 'done' || status === 'error' || status === 'stopped') ? Date.now() : null;
119
+ this.db.prepare(`UPDATE sessions SET status = ?, ended_at = COALESCE(?, ended_at) WHERE id = ?`).run(status, endedAt, id);
120
+ }
121
+ /**
122
+ * Reconcile session statuses with actual tmux sessions.
123
+ * Marks sessions as 'done' if their tmux session no longer exists.
124
+ */
125
+ reconcile() {
126
+ const running = this.list('running');
127
+ for (const session of running) {
128
+ if (!this.isTmuxSessionAlive(session.sessionName)) {
129
+ this.updateStatus(session.id, 'done');
130
+ }
131
+ }
132
+ }
133
+ /**
134
+ * Resolve an identifier to a session.
135
+ * Tries: exact ID match, agent name, partial match on agent name or session name.
136
+ */
137
+ resolve(identifier) {
138
+ // Exact ID match
139
+ const byId = this.get(identifier);
140
+ if (byId)
141
+ return byId;
142
+ // Partial agent name match (prefer running sessions)
143
+ const allSessions = this.list();
144
+ const running = allSessions.filter(s => s.status === 'running');
145
+ const pool = running.length > 0 ? running : allSessions;
146
+ const match = pool.find(s => s.agentName.includes(identifier) ||
147
+ s.sessionName.includes(identifier) ||
148
+ s.id.includes(identifier.toUpperCase()));
149
+ return match ?? null;
150
+ }
151
+ /**
152
+ * Check if a tmux session is alive.
153
+ */
154
+ isTmuxSessionAlive(sessionName) {
155
+ try {
156
+ execSync(`tmux has-session -t "${sessionName}" 2>/dev/null`, { stdio: 'pipe' });
157
+ return true;
158
+ }
159
+ catch {
160
+ return false;
161
+ }
162
+ }
163
+ close() {
164
+ this.db.close();
165
+ }
166
+ }
167
+ //# sourceMappingURL=session-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../../src/lib/session-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Shortcut Configuration Storage
3
+ *
4
+ * Stores Shortcut credentials and preferences in the workspace_settings table.
5
+ * Mirrors the Jira config module pattern.
6
+ */
7
+ import Database from 'better-sqlite3';
8
+ export interface ShortcutConfig {
9
+ apiToken: string;
10
+ workspaceSlug?: string;
11
+ }
12
+ /**
13
+ * Check if Shortcut is configured.
14
+ * Returns true if either:
15
+ * - Database has shortcut.api_token stored, OR
16
+ * - Environment variables PRLT_SHORTCUT_API_TOKEN/SHORTCUT_API_TOKEN are set
17
+ */
18
+ export declare function isShortcutConfigured(db: Database.Database): boolean;
19
+ /**
20
+ * Load Shortcut configuration from the database + environment.
21
+ * Returns null if not configured.
22
+ */
23
+ export declare function loadShortcutConfig(db: Database.Database): ShortcutConfig | null;
24
+ /**
25
+ * Save Shortcut configuration to the database.
26
+ */
27
+ export declare function saveShortcutConfig(db: Database.Database, config: ShortcutConfig): void;
28
+ /**
29
+ * Save the Shortcut API token.
30
+ */
31
+ export declare function saveShortcutApiToken(db: Database.Database, apiToken: string): void;
32
+ /**
33
+ * Save the Shortcut workspace slug.
34
+ */
35
+ export declare function saveShortcutWorkspaceSlug(db: Database.Database, slug: string): void;
36
+ /**
37
+ * Clear all Shortcut configuration from the database.
38
+ */
39
+ export declare function clearShortcutConfig(db: Database.Database): void;
40
+ /**
41
+ * Get the stored Shortcut API token.
42
+ * Also checks PRLT_SHORTCUT_API_TOKEN and SHORTCUT_API_TOKEN environment variables.
43
+ */
44
+ export declare function getShortcutApiToken(db: Database.Database): string | null;