@proletariat/cli 0.3.23 → 0.3.25

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 (235) hide show
  1. package/dist/commands/action/create.js +4 -4
  2. package/dist/commands/action/update.js +3 -3
  3. package/dist/commands/agent/{temp/cleanup.d.ts → cleanup.d.ts} +1 -1
  4. package/dist/commands/agent/{temp/cleanup.js → cleanup.js} +4 -4
  5. package/dist/commands/agent/index.js +8 -8
  6. package/dist/commands/branch/create.js +2 -2
  7. package/dist/commands/epic/activate.js +9 -17
  8. package/dist/commands/epic/archive.js +13 -24
  9. package/dist/commands/epic/create.d.ts +1 -0
  10. package/dist/commands/epic/create.js +46 -8
  11. package/dist/commands/epic/index.js +2 -2
  12. package/dist/commands/epic/move.js +28 -47
  13. package/dist/commands/epic/progress.js +10 -14
  14. package/dist/commands/epic/project.js +42 -59
  15. package/dist/commands/epic/reorder.js +25 -30
  16. package/dist/commands/epic/spec.d.ts +1 -0
  17. package/dist/commands/epic/spec.js +39 -40
  18. package/dist/commands/epic/ticket.d.ts +2 -0
  19. package/dist/commands/epic/ticket.js +63 -37
  20. package/dist/commands/feedback/index.d.ts +10 -0
  21. package/dist/commands/feedback/index.js +60 -0
  22. package/dist/commands/feedback/list.d.ts +12 -0
  23. package/dist/commands/feedback/list.js +126 -0
  24. package/dist/commands/feedback/submit.d.ts +16 -0
  25. package/dist/commands/feedback/submit.js +220 -0
  26. package/dist/commands/{template/phase/delete.d.ts → feedback/view.d.ts} +7 -5
  27. package/dist/commands/feedback/view.js +109 -0
  28. package/dist/commands/gh/index.js +4 -0
  29. package/dist/commands/{epic/link/remove.d.ts → link/create.d.ts} +6 -7
  30. package/dist/commands/link/create.js +141 -0
  31. package/dist/commands/{epic/link/relates.d.ts → link/index.d.ts} +4 -5
  32. package/dist/commands/link/index.js +87 -0
  33. package/dist/commands/{epic/link/duplicates.d.ts → link/list.d.ts} +7 -4
  34. package/dist/commands/link/list.js +182 -0
  35. package/dist/commands/{spec/link → link}/remove.d.ts +4 -5
  36. package/dist/commands/link/remove.js +120 -0
  37. package/dist/commands/mcp-server.d.ts +22 -0
  38. package/dist/commands/mcp-server.js +98 -0
  39. package/dist/commands/phase/create.js +1 -1
  40. package/dist/commands/project/create.d.ts +1 -0
  41. package/dist/commands/project/create.js +38 -4
  42. package/dist/commands/repo/create.d.ts +38 -0
  43. package/dist/commands/repo/create.js +283 -0
  44. package/dist/commands/repo/index.js +7 -0
  45. package/dist/commands/roadmap/add-project.js +9 -22
  46. package/dist/commands/roadmap/create.d.ts +0 -1
  47. package/dist/commands/roadmap/create.js +46 -40
  48. package/dist/commands/roadmap/delete.js +10 -24
  49. package/dist/commands/roadmap/generate.d.ts +1 -0
  50. package/dist/commands/roadmap/generate.js +21 -22
  51. package/dist/commands/roadmap/remove-project.js +14 -34
  52. package/dist/commands/roadmap/reorder.js +19 -26
  53. package/dist/commands/roadmap/update.js +27 -26
  54. package/dist/commands/roadmap/view.js +5 -12
  55. package/dist/commands/session/attach.d.ts +1 -8
  56. package/dist/commands/session/attach.js +93 -59
  57. package/dist/commands/session/list.d.ts +0 -8
  58. package/dist/commands/session/list.js +130 -81
  59. package/dist/commands/spec/create.d.ts +1 -0
  60. package/dist/commands/spec/create.js +44 -3
  61. package/dist/commands/spec/edit.js +63 -33
  62. package/dist/commands/spec/index.js +2 -2
  63. package/dist/commands/{agent/staff → staff}/add.js +10 -10
  64. package/dist/commands/{agent/staff → staff}/index.d.ts +1 -1
  65. package/dist/commands/{agent/staff → staff}/index.js +7 -7
  66. package/dist/commands/{agent/staff → staff}/list.js +3 -3
  67. package/dist/commands/{agent/staff → staff}/remove.d.ts +1 -1
  68. package/dist/commands/{agent/staff → staff}/remove.js +8 -8
  69. package/dist/commands/{template/phase/index.d.ts → support/book.d.ts} +2 -2
  70. package/dist/commands/support/book.js +54 -0
  71. package/dist/commands/{template/ticket/index.d.ts → support/discord.d.ts} +2 -2
  72. package/dist/commands/support/discord.js +54 -0
  73. package/dist/commands/support/docs.d.ts +10 -0
  74. package/dist/commands/support/docs.js +54 -0
  75. package/dist/commands/support/index.d.ts +19 -0
  76. package/dist/commands/support/index.js +81 -0
  77. package/dist/commands/support/issues.d.ts +11 -0
  78. package/dist/commands/support/issues.js +77 -0
  79. package/dist/commands/support/logs.d.ts +18 -0
  80. package/dist/commands/support/logs.js +247 -0
  81. package/dist/commands/{ticket/template → template}/apply.d.ts +8 -6
  82. package/dist/commands/template/apply.js +262 -0
  83. package/dist/commands/{ticket/template → template}/create.d.ts +5 -6
  84. package/dist/commands/template/create.js +238 -0
  85. package/dist/commands/template/index.js +48 -36
  86. package/dist/commands/{ticket/template → template}/save.d.ts +2 -2
  87. package/dist/commands/template/save.js +104 -0
  88. package/dist/commands/{phase/template → template}/update.d.ts +2 -2
  89. package/dist/commands/template/update.js +99 -0
  90. package/dist/commands/{agent/themes → theme}/add-names.d.ts +1 -1
  91. package/dist/commands/{agent/themes → theme}/add-names.js +6 -6
  92. package/dist/commands/{agent/themes → theme}/create.d.ts +1 -1
  93. package/dist/commands/{agent/themes → theme}/create.js +5 -5
  94. package/dist/commands/{agent/themes → theme}/index.d.ts +1 -1
  95. package/dist/commands/{agent/themes → theme}/index.js +10 -10
  96. package/dist/commands/{agent/themes → theme}/list.d.ts +1 -1
  97. package/dist/commands/{agent/themes → theme}/list.js +5 -5
  98. package/dist/commands/{agent/themes → theme}/set.d.ts +1 -1
  99. package/dist/commands/{agent/themes → theme}/set.js +7 -7
  100. package/dist/commands/ticket/create.d.ts +1 -0
  101. package/dist/commands/ticket/create.js +75 -15
  102. package/dist/commands/ticket/edit.js +44 -13
  103. package/dist/commands/ticket/index.js +6 -6
  104. package/dist/commands/ticket/move.d.ts +7 -0
  105. package/dist/commands/ticket/move.js +132 -0
  106. package/dist/commands/work/spawn.d.ts +1 -0
  107. package/dist/commands/work/spawn.js +72 -8
  108. package/dist/commands/work/start.js +6 -0
  109. package/dist/lib/execution/runners.js +21 -17
  110. package/dist/lib/execution/session-utils.d.ts +60 -0
  111. package/dist/lib/execution/session-utils.js +162 -0
  112. package/dist/lib/execution/spawner.d.ts +2 -0
  113. package/dist/lib/execution/spawner.js +42 -0
  114. package/dist/lib/flags/resolver.d.ts +2 -2
  115. package/dist/lib/flags/resolver.js +15 -0
  116. package/dist/lib/init/index.js +18 -0
  117. package/dist/lib/mcp/helpers.d.ts +43 -0
  118. package/dist/lib/mcp/helpers.js +57 -0
  119. package/dist/lib/mcp/index.d.ts +6 -0
  120. package/dist/lib/mcp/index.js +6 -0
  121. package/dist/lib/mcp/tools/action.d.ts +6 -0
  122. package/dist/lib/mcp/tools/action.js +88 -0
  123. package/dist/lib/mcp/tools/board.d.ts +6 -0
  124. package/dist/lib/mcp/tools/board.js +139 -0
  125. package/dist/lib/mcp/tools/category.d.ts +6 -0
  126. package/dist/lib/mcp/tools/category.js +84 -0
  127. package/dist/lib/mcp/tools/cli-passthrough.d.ts +15 -0
  128. package/dist/lib/mcp/tools/cli-passthrough.js +333 -0
  129. package/dist/lib/mcp/tools/epic.d.ts +6 -0
  130. package/dist/lib/mcp/tools/epic.js +178 -0
  131. package/dist/lib/mcp/tools/index.d.ts +18 -0
  132. package/dist/lib/mcp/tools/index.js +19 -0
  133. package/dist/lib/mcp/tools/phase.d.ts +6 -0
  134. package/dist/lib/mcp/tools/phase.js +131 -0
  135. package/dist/lib/mcp/tools/project.d.ts +6 -0
  136. package/dist/lib/mcp/tools/project.js +196 -0
  137. package/dist/lib/mcp/tools/roadmap.d.ts +6 -0
  138. package/dist/lib/mcp/tools/roadmap.js +123 -0
  139. package/dist/lib/mcp/tools/spec.d.ts +6 -0
  140. package/dist/lib/mcp/tools/spec.js +196 -0
  141. package/dist/lib/mcp/tools/status.d.ts +6 -0
  142. package/dist/lib/mcp/tools/status.js +109 -0
  143. package/dist/lib/mcp/tools/template.d.ts +6 -0
  144. package/dist/lib/mcp/tools/template.js +107 -0
  145. package/dist/lib/mcp/tools/ticket.d.ts +6 -0
  146. package/dist/lib/mcp/tools/ticket.js +393 -0
  147. package/dist/lib/mcp/tools/view.d.ts +6 -0
  148. package/dist/lib/mcp/tools/view.js +76 -0
  149. package/dist/lib/mcp/tools/work.d.ts +6 -0
  150. package/dist/lib/mcp/tools/work.js +132 -0
  151. package/dist/lib/mcp/tools/workflow.d.ts +6 -0
  152. package/dist/lib/mcp/tools/workflow.js +95 -0
  153. package/dist/lib/mcp/types.d.ts +17 -0
  154. package/dist/lib/mcp/types.js +4 -0
  155. package/dist/lib/multiline-input.d.ts +63 -0
  156. package/dist/lib/multiline-input.js +360 -0
  157. package/dist/lib/prompt-json.d.ts +57 -6
  158. package/dist/lib/prompt-json.js +45 -0
  159. package/dist/lib/repos/git.d.ts +7 -0
  160. package/dist/lib/repos/git.js +20 -0
  161. package/oclif.manifest.json +3690 -4995
  162. package/package.json +6 -4
  163. package/dist/commands/agent/temp/index.d.ts +0 -14
  164. package/dist/commands/agent/temp/index.js +0 -85
  165. package/dist/commands/agent/temp/list.d.ts +0 -7
  166. package/dist/commands/agent/temp/list.js +0 -108
  167. package/dist/commands/epic/link/block.d.ts +0 -14
  168. package/dist/commands/epic/link/block.js +0 -81
  169. package/dist/commands/epic/link/duplicates.js +0 -68
  170. package/dist/commands/epic/link/index.d.ts +0 -19
  171. package/dist/commands/epic/link/index.js +0 -272
  172. package/dist/commands/epic/link/relates.js +0 -68
  173. package/dist/commands/epic/link/remove.js +0 -93
  174. package/dist/commands/phase/template/apply.d.ts +0 -17
  175. package/dist/commands/phase/template/apply.js +0 -108
  176. package/dist/commands/phase/template/create.d.ts +0 -17
  177. package/dist/commands/phase/template/create.js +0 -104
  178. package/dist/commands/phase/template/delete.d.ts +0 -17
  179. package/dist/commands/phase/template/delete.js +0 -100
  180. package/dist/commands/phase/template/index.d.ts +0 -15
  181. package/dist/commands/phase/template/index.js +0 -130
  182. package/dist/commands/phase/template/list.d.ts +0 -16
  183. package/dist/commands/phase/template/list.js +0 -97
  184. package/dist/commands/phase/template/update.js +0 -89
  185. package/dist/commands/spec/link/depends.d.ts +0 -14
  186. package/dist/commands/spec/link/depends.js +0 -64
  187. package/dist/commands/spec/link/duplicates.d.ts +0 -14
  188. package/dist/commands/spec/link/duplicates.js +0 -63
  189. package/dist/commands/spec/link/index.d.ts +0 -19
  190. package/dist/commands/spec/link/index.js +0 -207
  191. package/dist/commands/spec/link/relates.d.ts +0 -14
  192. package/dist/commands/spec/link/relates.js +0 -63
  193. package/dist/commands/spec/link/remove.js +0 -96
  194. package/dist/commands/template/phase/apply.d.ts +0 -14
  195. package/dist/commands/template/phase/apply.js +0 -43
  196. package/dist/commands/template/phase/create.d.ts +0 -13
  197. package/dist/commands/template/phase/create.js +0 -38
  198. package/dist/commands/template/phase/delete.js +0 -36
  199. package/dist/commands/template/phase/index.js +0 -63
  200. package/dist/commands/template/phase/list.d.ts +0 -11
  201. package/dist/commands/template/phase/list.js +0 -36
  202. package/dist/commands/template/phase/update.d.ts +0 -14
  203. package/dist/commands/template/phase/update.js +0 -43
  204. package/dist/commands/template/ticket/apply.d.ts +0 -17
  205. package/dist/commands/template/ticket/apply.js +0 -60
  206. package/dist/commands/template/ticket/create.d.ts +0 -20
  207. package/dist/commands/template/ticket/create.js +0 -89
  208. package/dist/commands/template/ticket/delete.d.ts +0 -13
  209. package/dist/commands/template/ticket/delete.js +0 -38
  210. package/dist/commands/template/ticket/index.js +0 -63
  211. package/dist/commands/template/ticket/list.d.ts +0 -11
  212. package/dist/commands/template/ticket/list.js +0 -36
  213. package/dist/commands/template/ticket/save.d.ts +0 -15
  214. package/dist/commands/template/ticket/save.js +0 -46
  215. package/dist/commands/ticket/link/block.d.ts +0 -14
  216. package/dist/commands/ticket/link/block.js +0 -96
  217. package/dist/commands/ticket/link/duplicates.d.ts +0 -14
  218. package/dist/commands/ticket/link/duplicates.js +0 -95
  219. package/dist/commands/ticket/link/index.d.ts +0 -19
  220. package/dist/commands/ticket/link/index.js +0 -256
  221. package/dist/commands/ticket/link/relates.d.ts +0 -14
  222. package/dist/commands/ticket/link/relates.js +0 -95
  223. package/dist/commands/ticket/link/remove.d.ts +0 -16
  224. package/dist/commands/ticket/link/remove.js +0 -132
  225. package/dist/commands/ticket/template/apply.js +0 -252
  226. package/dist/commands/ticket/template/create.js +0 -386
  227. package/dist/commands/ticket/template/delete.d.ts +0 -17
  228. package/dist/commands/ticket/template/delete.js +0 -94
  229. package/dist/commands/ticket/template/index.d.ts +0 -15
  230. package/dist/commands/ticket/template/index.js +0 -120
  231. package/dist/commands/ticket/template/list.d.ts +0 -16
  232. package/dist/commands/ticket/template/list.js +0 -112
  233. package/dist/commands/ticket/template/save.js +0 -163
  234. /package/dist/commands/{agent/staff → staff}/add.d.ts +0 -0
  235. /package/dist/commands/{agent/staff → staff}/list.d.ts +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@proletariat/cli",
3
3
  "description": "Agent orchestration platform for AI labor - Spin up workers on demand for multi-agent development",
4
- "version": "0.3.23",
4
+ "version": "0.3.25",
5
5
  "author": "Chris McDermut",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -12,6 +12,7 @@
12
12
  "bugs": "https://github.com/chrismcdermut/proletariat/issues",
13
13
  "dependencies": {
14
14
  "@inkjs/ui": "^2.0.0",
15
+ "@modelcontextprotocol/sdk": "^1.0.0",
15
16
  "@oclif/core": "^4",
16
17
  "@oclif/plugin-autocomplete": "^3",
17
18
  "@oclif/plugin-commands": "^4",
@@ -19,21 +20,21 @@
19
20
  "@oclif/plugin-plugins": "^5",
20
21
  "@oclif/plugin-warn-if-update-available": "^3",
21
22
  "better-sqlite3": "^12.6.2",
22
- "drizzle-orm": "^0.37.0",
23
23
  "chalk": "^4.1.2",
24
24
  "chokidar": "^5.0.0",
25
+ "drizzle-orm": "^0.37.0",
25
26
  "gray-matter": "^4.0.3",
26
27
  "ink": "^5.0.1",
27
28
  "ink-select-input": "^6.0.0",
28
29
  "inquirer": "^8.2.5",
29
- "react": "^18.0.0"
30
+ "react": "^18.0.0",
31
+ "zod": "^4.3.6"
30
32
  },
31
33
  "devDependencies": {
32
34
  "@eslint/compat": "^2.0.0",
33
35
  "@oclif/prettier-config": "^0.2.1",
34
36
  "@oclif/test": "^4",
35
37
  "@types/better-sqlite3": "^7.6.13",
36
- "drizzle-kit": "^0.30.0",
37
38
  "@types/chai": "^4",
38
39
  "@types/ink-spinner": "^3.0.5",
39
40
  "@types/inquirer": "^8.2.6",
@@ -42,6 +43,7 @@
42
43
  "@types/node": "^20",
43
44
  "@types/react": "^18",
44
45
  "chai": "^4",
46
+ "drizzle-kit": "^0.30.0",
45
47
  "eslint": "^9",
46
48
  "eslint-config-oclif": "^6.0.129",
47
49
  "eslint-config-prettier": "^10",
@@ -1,14 +0,0 @@
1
- import { PMOCommand } from '../../../lib/pmo/index.js';
2
- export default class Temp extends PMOCommand {
3
- static description: string;
4
- static examples: string[];
5
- static flags: {
6
- json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
- 'no-interactive': import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
- project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
- };
10
- protected getPMOOptions(): {
11
- promptIfMultiple: boolean;
12
- };
13
- execute(): Promise<void>;
14
- }
@@ -1,85 +0,0 @@
1
- import { Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
- import { colors } from '../../../lib/colors.js';
4
- import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
5
- import { shouldOutputJson, outputPromptAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
6
- export default class Temp extends PMOCommand {
7
- static description = 'Manage temporary (ephemeral) agents';
8
- static examples = [
9
- '<%= config.bin %> <%= command.id %> list',
10
- '<%= config.bin %> <%= command.id %> cleanup --temp',
11
- '<%= config.bin %> <%= command.id %> cleanup bold-bezos-1',
12
- ];
13
- static flags = {
14
- ...pmoBaseFlags,
15
- json: Flags.boolean({
16
- char: 'm',
17
- aliases: ['machine'],
18
- description: 'Output prompt configuration as JSON (for AI agents/scripts)',
19
- default: false,
20
- }),
21
- 'no-interactive': Flags.boolean({
22
- description: 'Alias for --json flag',
23
- default: false,
24
- }),
25
- };
26
- getPMOOptions() {
27
- return { promptIfMultiple: false };
28
- }
29
- async execute() {
30
- const { flags } = await this.parse(Temp);
31
- // Check if JSON output mode is active
32
- const jsonMode = shouldOutputJson(flags);
33
- // Define choices once, use for both JSON and interactive modes
34
- // Include command field for AI agent navigation
35
- const menuChoices = [
36
- { name: 'List temp agents', value: 'list', command: 'prlt agent temp list --machine' },
37
- { name: 'Clean up temp agents', value: 'cleanup', command: 'prlt agent temp cleanup --machine' },
38
- { name: 'Cancel', value: 'cancel', command: '' },
39
- ];
40
- const message = 'What would you like to do?';
41
- // In JSON mode, output menu prompt
42
- if (jsonMode) {
43
- outputPromptAsJson(buildPromptConfig('list', 'action', message, menuChoices), createMetadata('agent temp', flags));
44
- return;
45
- }
46
- this.log(colors.primary('Temporary Agents'));
47
- this.log(colors.textMuted('Ephemeral agents created by "prlt work spawn".\n'));
48
- const { action } = await inquirer.prompt([{
49
- type: 'list',
50
- name: 'action',
51
- message,
52
- choices: [
53
- { name: '📋 ' + menuChoices[0].name, value: menuChoices[0].value },
54
- { name: '🧹 ' + menuChoices[1].name, value: menuChoices[1].value },
55
- new inquirer.Separator(),
56
- { name: '❌ ' + menuChoices[2].name, value: menuChoices[2].value },
57
- ]
58
- }]);
59
- if (action === 'cancel') {
60
- this.log(colors.textMuted('Operation cancelled.'));
61
- return;
62
- }
63
- try {
64
- switch (action) {
65
- case 'list': {
66
- const { default: ListCommand } = await import('./list.js');
67
- const cmd = new ListCommand([], this.config);
68
- await cmd.run();
69
- break;
70
- }
71
- case 'cleanup': {
72
- const { default: CleanupCommand } = await import('./cleanup.js');
73
- const cmd = new CleanupCommand([], this.config);
74
- await cmd.run();
75
- break;
76
- }
77
- default:
78
- this.error(`Unknown action: ${action}`);
79
- }
80
- }
81
- catch (error) {
82
- this.error(`Failed to execute temp ${action}: ${error instanceof Error ? error.message : String(error)}`);
83
- }
84
- }
85
- }
@@ -1,7 +0,0 @@
1
- import { Command } from '@oclif/core';
2
- export default class List extends Command {
3
- static description: string;
4
- static examples: string[];
5
- static flags: {};
6
- run(): Promise<void>;
7
- }
@@ -1,108 +0,0 @@
1
- import { Command } from '@oclif/core';
2
- import chalk from 'chalk';
3
- import * as path from 'node:path';
4
- import * as fs from 'node:fs';
5
- import { getWorkspaceInfo, getAllAgentsStatus, getAgentTmuxSessions } from '../../../lib/agents/commands.js';
6
- export default class List extends Command {
7
- static description = 'List all temporary (ephemeral) agents and their status';
8
- static examples = [
9
- '<%= config.bin %> <%= command.id %>',
10
- ];
11
- static flags = {};
12
- async run() {
13
- try {
14
- // Get workspace information
15
- const workspaceInfo = getWorkspaceInfo();
16
- // Filter to ephemeral agents only
17
- const ephemeralAgents = workspaceInfo.agents.filter(a => a.type === 'ephemeral');
18
- if (ephemeralAgents.length === 0) {
19
- this.log(chalk.yellow('No temporary agents found. Create them with "prlt work spawn"'));
20
- return;
21
- }
22
- // Separate active and cleaned agents
23
- const activeAgents = ephemeralAgents.filter(a => a.status === 'active');
24
- const cleanedAgents = ephemeralAgents.filter(a => a.status === 'cleaned');
25
- // Get status for all agents
26
- const agentsStatus = getAllAgentsStatus(workspaceInfo);
27
- // Active agents
28
- if (activeAgents.length > 0) {
29
- this.log(chalk.bold.cyan('\n Active Temporary Agents:\n'));
30
- const activeStatus = agentsStatus.filter(a => activeAgents.some(s => s.name === a.name));
31
- for (const agentStatus of activeStatus) {
32
- // Check for running tmux sessions
33
- const sessions = getAgentTmuxSessions(agentStatus.name);
34
- const hasRunningWork = sessions.length > 0;
35
- // Agent info line
36
- const statusIcon = hasRunningWork ? '🟡' : (agentStatus.exists ? '🟢' : '🔴');
37
- const runningLabel = hasRunningWork ? chalk.yellow(' (running)') : '';
38
- const status = agentStatus.exists ? chalk.green('Active') : chalk.red('Missing');
39
- this.log(`${statusIcon} ${chalk.bold(agentStatus.name)} - ${status}${runningLabel}`);
40
- if (agentStatus.exists) {
41
- // Show branch info
42
- if (agentStatus.branch) {
43
- this.log(chalk.cyan(` Branch: ${agentStatus.branch}`));
44
- }
45
- // Show repository status
46
- if (agentStatus.repositories.length > 0) {
47
- const dirtyRepos = agentStatus.repositories.filter(r => r.status === 'dirty').length;
48
- const reposWithCommits = agentStatus.repositories.filter(r => r.commitsAhead > 0);
49
- let repoStatusText = `${agentStatus.repositories.length} repo(s)`;
50
- if (dirtyRepos > 0) {
51
- repoStatusText += `, ${dirtyRepos} dirty`;
52
- }
53
- if (reposWithCommits.length > 0) {
54
- const commitDetails = reposWithCommits.map(r => `${r.name}(+${r.commitsAhead})`).join(', ');
55
- repoStatusText += `, commits ahead: ${commitDetails}`;
56
- }
57
- this.log(chalk.white(` Repositories: ${repoStatusText}`));
58
- }
59
- // Show ticket info
60
- if (agentStatus.assignedTickets.length > 0) {
61
- this.log(chalk.blue(` Current tickets: ${agentStatus.assignedTickets.join(', ')}`));
62
- }
63
- }
64
- else {
65
- const agentDir = path.join(workspaceInfo.agentsPath, agentStatus.name);
66
- const dirExists = fs.existsSync(agentDir);
67
- if (dirExists) {
68
- this.log(chalk.red(` Invalid or broken worktrees`));
69
- }
70
- else {
71
- this.log(chalk.red(` Agent directory not found`));
72
- }
73
- }
74
- this.log(''); // Empty line between agents
75
- }
76
- }
77
- // Cleaned agents (if any)
78
- if (cleanedAgents.length > 0) {
79
- this.log(chalk.bold.dim('\n Cleaned Temporary Agents:\n'));
80
- for (const agent of cleanedAgents) {
81
- const cleanedAt = agent.cleaned_at
82
- ? new Date(agent.cleaned_at).toLocaleString()
83
- : 'unknown';
84
- this.log(chalk.dim(` ${agent.name} - cleaned at ${cleanedAt}`));
85
- }
86
- this.log('');
87
- }
88
- // Summary
89
- const runningCount = activeAgents.filter(a => {
90
- const sessions = getAgentTmuxSessions(a.name);
91
- return sessions.length > 0;
92
- }).length;
93
- this.log(chalk.bold(`Summary:`));
94
- this.log(` Total temporary agents: ${ephemeralAgents.length}`);
95
- this.log(` Active: ${activeAgents.length}`);
96
- if (runningCount > 0) {
97
- this.log(chalk.yellow(` Running work: ${runningCount}`));
98
- }
99
- this.log(chalk.dim(` Cleaned: ${cleanedAgents.length}`));
100
- if (activeAgents.length > 0 && runningCount === 0) {
101
- this.log(chalk.dim('\nTip: Use "prlt agent temp cleanup --temp" to clean up idle agents.'));
102
- }
103
- }
104
- catch (error) {
105
- this.error(error instanceof Error ? error.message : String(error));
106
- }
107
- }
108
- }
@@ -1,14 +0,0 @@
1
- import { PMOCommand } from '../../../lib/pmo/index.js';
2
- export default class EpicLinkBlock extends PMOCommand {
3
- static description: string;
4
- static examples: string[];
5
- static args: {
6
- id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
- blocker: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
8
- };
9
- static flags: {
10
- project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
- json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
- };
13
- execute(): Promise<void>;
14
- }
@@ -1,81 +0,0 @@
1
- import { Args, Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
- import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../../lib/pmo/index.js';
4
- import { styles } from '../../../lib/styles.js';
5
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
6
- export default class EpicLinkBlock extends PMOCommand {
7
- static description = 'Add a blocking dependency (epic is blocked by another)';
8
- static examples = [
9
- '<%= config.bin %> <%= command.id %> EPIC-001 EPIC-002 # EPIC-001 is blocked by EPIC-002',
10
- ];
11
- static args = {
12
- id: Args.string({ description: 'Epic ID that will be blocked', required: true }),
13
- blocker: Args.string({ description: 'Epic ID that blocks this epic', required: false }),
14
- };
15
- static flags = {
16
- ...pmoBaseFlags,
17
- project: Flags.string({ char: 'P', description: 'Project ID' }),
18
- json: Flags.boolean({
19
- char: 'm',
20
- aliases: ['machine'],
21
- description: 'Output prompt configuration as JSON (for AI agents/scripts)',
22
- default: false,
23
- }),
24
- };
25
- async execute() {
26
- const { args, flags } = await this.parse(EpicLinkBlock);
27
- // Check if JSON output mode is active
28
- const jsonMode = shouldOutputJson(flags);
29
- // Helper to handle errors in JSON mode
30
- const handleError = (code, message) => {
31
- if (jsonMode) {
32
- outputErrorAsJson(code, message, createMetadata('epic link block', flags));
33
- this.exit(1);
34
- }
35
- this.error(message);
36
- };
37
- const epic = await this.storage.getEpic(args.id);
38
- if (!epic)
39
- return handleError('EPIC_NOT_FOUND', `Epic not found: ${args.id}`);
40
- const projectId = epic.projectId;
41
- let blockerId = args.blocker;
42
- if (!blockerId) {
43
- const allEpics = await this.storage.listEpics(projectId);
44
- const otherEpics = allEpics.filter(e => e.id !== args.id);
45
- if (otherEpics.length === 0) {
46
- if (jsonMode) {
47
- outputErrorAsJson('NO_OTHER_EPICS', 'No other epics.', createMetadata('epic link block', flags));
48
- return;
49
- }
50
- this.log(styles.muted('\nNo other epics.'));
51
- return;
52
- }
53
- // In JSON mode, output blocker selection prompt
54
- if (jsonMode) {
55
- const epicChoices = otherEpics.map(e => ({ name: `${e.id} - ${e.title} (${e.status})`, value: e.id }));
56
- outputPromptAsJson(buildPromptConfig('list', 'blocker', `Select epic that blocks ${args.id}:`, epicChoices), createMetadata('epic link block', flags));
57
- return;
58
- }
59
- const { selected } = await inquirer.prompt([{
60
- type: 'list', name: 'selected', message: `Select epic that blocks ${args.id}:`,
61
- choices: otherEpics.map(e => ({ name: `${e.id} - ${e.title} (${e.status})`, value: e.id })),
62
- }]);
63
- blockerId = selected;
64
- }
65
- const blockerEpic = await this.storage.getEpic(blockerId);
66
- if (!blockerEpic)
67
- return handleError('BLOCKER_EPIC_NOT_FOUND', `Epic not found: ${blockerId}`);
68
- try {
69
- await this.storage.createEpicDependency(args.id, blockerId, 'blocks');
70
- await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
71
- this.log(styles.success(`\n✅ ${styles.emphasis(args.id)} is blocked by ${styles.emphasis(blockerId)}`));
72
- this.log(styles.muted(` ${epic.title} blocked by: ${blockerEpic.title}`));
73
- }
74
- catch (error) {
75
- if (error instanceof Error && (error.message.includes('already exists') || error.message.includes('self-dependency'))) {
76
- this.error(error.message.includes('already exists') ? 'Dependency already exists' : 'Cannot create self-dependency');
77
- }
78
- throw error;
79
- }
80
- }
81
- }
@@ -1,68 +0,0 @@
1
- import { Args, Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
- import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../../lib/pmo/index.js';
4
- import { styles } from '../../../lib/styles.js';
5
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
6
- export default class EpicLinkDuplicates extends PMOCommand {
7
- static description = 'Mark an epic as duplicate of another';
8
- static examples = ['<%= config.bin %> <%= command.id %> EPIC-001 EPIC-002'];
9
- static args = {
10
- id: Args.string({ description: 'Duplicate epic ID', required: true }),
11
- original: Args.string({ description: 'Original epic ID', required: false }),
12
- };
13
- static flags = {
14
- ...pmoBaseFlags,
15
- project: Flags.string({ char: 'P', description: 'Project ID' }),
16
- json: Flags.boolean({
17
- char: 'm',
18
- aliases: ['machine'],
19
- description: 'Output prompt configuration as JSON (for AI agents/scripts)',
20
- default: false,
21
- }),
22
- };
23
- async execute() {
24
- const { args, flags } = await this.parse(EpicLinkDuplicates);
25
- // Check if JSON output mode is active
26
- const jsonMode = shouldOutputJson(flags);
27
- // Helper to handle errors in JSON mode
28
- const handleError = (code, message) => {
29
- if (jsonMode) {
30
- outputErrorAsJson(code, message, createMetadata('epic link duplicates', flags));
31
- this.exit(1);
32
- }
33
- this.error(message);
34
- };
35
- const epic = await this.storage.getEpic(args.id);
36
- if (!epic)
37
- return handleError('EPIC_NOT_FOUND', `Epic not found: ${args.id}`);
38
- const projectId = epic.projectId;
39
- let originalId = args.original;
40
- if (!originalId) {
41
- const allEpics = await this.storage.listEpics(projectId);
42
- const otherEpics = allEpics.filter(e => e.id !== args.id);
43
- if (otherEpics.length === 0) {
44
- if (jsonMode) {
45
- outputErrorAsJson('NO_OTHER_EPICS', 'No other epics.', createMetadata('epic link duplicates', flags));
46
- return;
47
- }
48
- this.log(styles.muted('\nNo other epics.'));
49
- return;
50
- }
51
- // In JSON mode, output original epic selection prompt
52
- if (jsonMode) {
53
- const epicChoices = otherEpics.map(e => ({ name: `${e.id} - ${e.title}`, value: e.id }));
54
- outputPromptAsJson(buildPromptConfig('list', 'original', `Select the original epic (${args.id} is a duplicate of):`, epicChoices), createMetadata('epic link duplicates', flags));
55
- return;
56
- }
57
- const { selected } = await inquirer.prompt([{ type: 'list', name: 'selected', message: `Select the original epic (${args.id} is a duplicate of):`,
58
- choices: otherEpics.map(e => ({ name: `${e.id} - ${e.title}`, value: e.id })) }]);
59
- originalId = selected;
60
- }
61
- const originalEpic = await this.storage.getEpic(originalId);
62
- if (!originalEpic)
63
- return handleError('ORIGINAL_EPIC_NOT_FOUND', `Epic not found: ${originalId}`);
64
- await this.storage.createEpicDependency(args.id, originalId, 'duplicates');
65
- await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
66
- this.log(styles.success(`\n✅ ${styles.emphasis(args.id)} duplicates ${styles.emphasis(originalId)}`));
67
- }
68
- }
@@ -1,19 +0,0 @@
1
- import { PMOCommand } from '../../../lib/pmo/index.js';
2
- export default class EpicLink extends PMOCommand {
3
- static description: string;
4
- static examples: string[];
5
- static args: {
6
- id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
7
- };
8
- static flags: {
9
- project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
- blocks: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
- relates: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
- duplicates: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
- all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
- json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
- };
16
- execute(): Promise<void>;
17
- private addDependency;
18
- private viewDependencies;
19
- }