@sudosandwich/limps 0.2.1 → 1.0.0

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 (212) hide show
  1. package/README.md +250 -15
  2. package/dist/cli/config-cmd.d.ts +68 -0
  3. package/dist/cli/config-cmd.d.ts.map +1 -0
  4. package/dist/cli/config-cmd.js +206 -0
  5. package/dist/cli/config-cmd.js.map +1 -0
  6. package/dist/cli/index.d.ts +11 -0
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/cli/index.js +12 -0
  9. package/dist/cli/index.js.map +1 -0
  10. package/dist/cli/init-project.d.ts +12 -0
  11. package/dist/cli/init-project.d.ts.map +1 -0
  12. package/dist/cli/init-project.js +104 -0
  13. package/dist/cli/init-project.js.map +1 -0
  14. package/dist/cli/list-agents.d.ts +66 -0
  15. package/dist/cli/list-agents.d.ts.map +1 -0
  16. package/dist/cli/list-agents.js +147 -0
  17. package/dist/cli/list-agents.js.map +1 -0
  18. package/dist/cli/list-plans.d.ts +63 -0
  19. package/dist/cli/list-plans.d.ts.map +1 -0
  20. package/dist/cli/list-plans.js +218 -0
  21. package/dist/cli/list-plans.js.map +1 -0
  22. package/dist/cli/next-task.d.ts +83 -0
  23. package/dist/cli/next-task.d.ts.map +1 -0
  24. package/dist/cli/next-task.js +201 -0
  25. package/dist/cli/next-task.js.map +1 -0
  26. package/dist/cli/registry.d.ts +94 -0
  27. package/dist/cli/registry.d.ts.map +1 -0
  28. package/dist/cli/registry.js +150 -0
  29. package/dist/cli/registry.js.map +1 -0
  30. package/dist/cli/status.d.ts +35 -0
  31. package/dist/cli/status.d.ts.map +1 -0
  32. package/dist/cli/status.js +110 -0
  33. package/dist/cli/status.js.map +1 -0
  34. package/dist/cli.d.ts +3 -0
  35. package/dist/cli.d.ts.map +1 -0
  36. package/dist/cli.js +10 -0
  37. package/dist/cli.js.map +1 -0
  38. package/dist/commands/config/add.d.ts +9 -0
  39. package/dist/commands/config/add.d.ts.map +1 -0
  40. package/dist/commands/config/add.js +20 -0
  41. package/dist/commands/config/add.js.map +1 -0
  42. package/dist/commands/config/discover.d.ts +3 -0
  43. package/dist/commands/config/discover.d.ts.map +1 -0
  44. package/dist/commands/config/discover.js +9 -0
  45. package/dist/commands/config/discover.js.map +1 -0
  46. package/dist/commands/config/index.d.ts +3 -0
  47. package/dist/commands/config/index.d.ts.map +1 -0
  48. package/dist/commands/config/index.js +7 -0
  49. package/dist/commands/config/index.js.map +1 -0
  50. package/dist/commands/config/list.d.ts +3 -0
  51. package/dist/commands/config/list.d.ts.map +1 -0
  52. package/dist/commands/config/list.js +9 -0
  53. package/dist/commands/config/list.js.map +1 -0
  54. package/dist/commands/config/path.d.ts +3 -0
  55. package/dist/commands/config/path.d.ts.map +1 -0
  56. package/dist/commands/config/path.js +10 -0
  57. package/dist/commands/config/path.js.map +1 -0
  58. package/dist/commands/config/remove.d.ts +9 -0
  59. package/dist/commands/config/remove.d.ts.map +1 -0
  60. package/dist/commands/config/remove.js +17 -0
  61. package/dist/commands/config/remove.js.map +1 -0
  62. package/dist/commands/config/set.d.ts +9 -0
  63. package/dist/commands/config/set.d.ts.map +1 -0
  64. package/dist/commands/config/set.js +17 -0
  65. package/dist/commands/config/set.js.map +1 -0
  66. package/dist/commands/config/show.d.ts +3 -0
  67. package/dist/commands/config/show.d.ts.map +1 -0
  68. package/dist/commands/config/show.js +15 -0
  69. package/dist/commands/config/show.js.map +1 -0
  70. package/dist/commands/config/use.d.ts +9 -0
  71. package/dist/commands/config/use.d.ts.map +1 -0
  72. package/dist/commands/config/use.js +17 -0
  73. package/dist/commands/config/use.js.map +1 -0
  74. package/dist/commands/index.d.ts +3 -0
  75. package/dist/commands/index.d.ts.map +1 -0
  76. package/dist/commands/index.js +7 -0
  77. package/dist/commands/index.js.map +1 -0
  78. package/dist/commands/init.d.ts +13 -0
  79. package/dist/commands/init.d.ts.map +1 -0
  80. package/dist/commands/init.js +20 -0
  81. package/dist/commands/init.js.map +1 -0
  82. package/dist/commands/list-agents.d.ts +13 -0
  83. package/dist/commands/list-agents.d.ts.map +1 -0
  84. package/dist/commands/list-agents.js +31 -0
  85. package/dist/commands/list-agents.js.map +1 -0
  86. package/dist/commands/list-plans.d.ts +11 -0
  87. package/dist/commands/list-plans.d.ts.map +1 -0
  88. package/dist/commands/list-plans.js +21 -0
  89. package/dist/commands/list-plans.js.map +1 -0
  90. package/dist/commands/next-task.d.ts +13 -0
  91. package/dist/commands/next-task.d.ts.map +1 -0
  92. package/dist/commands/next-task.js +46 -0
  93. package/dist/commands/next-task.js.map +1 -0
  94. package/dist/commands/serve.d.ts +11 -0
  95. package/dist/commands/serve.d.ts.map +1 -0
  96. package/dist/commands/serve.js +31 -0
  97. package/dist/commands/serve.js.map +1 -0
  98. package/dist/commands/status.d.ts +13 -0
  99. package/dist/commands/status.d.ts.map +1 -0
  100. package/dist/commands/status.js +28 -0
  101. package/dist/commands/status.js.map +1 -0
  102. package/dist/components/AgentsList.d.ts +19 -0
  103. package/dist/components/AgentsList.d.ts.map +1 -0
  104. package/dist/components/AgentsList.js +29 -0
  105. package/dist/components/AgentsList.js.map +1 -0
  106. package/dist/components/Error.d.ts +6 -0
  107. package/dist/components/Error.d.ts.map +1 -0
  108. package/dist/components/Error.js +6 -0
  109. package/dist/components/Error.js.map +1 -0
  110. package/dist/components/NextTask.d.ts +12 -0
  111. package/dist/components/NextTask.d.ts.map +1 -0
  112. package/dist/components/NextTask.js +11 -0
  113. package/dist/components/NextTask.js.map +1 -0
  114. package/dist/components/PlanStatus.d.ts +11 -0
  115. package/dist/components/PlanStatus.d.ts.map +1 -0
  116. package/dist/components/PlanStatus.js +18 -0
  117. package/dist/components/PlanStatus.js.map +1 -0
  118. package/dist/components/PlansList.d.ts +12 -0
  119. package/dist/components/PlansList.d.ts.map +1 -0
  120. package/dist/components/PlansList.js +23 -0
  121. package/dist/components/PlansList.js.map +1 -0
  122. package/dist/components/Success.d.ts +6 -0
  123. package/dist/components/Success.d.ts.map +1 -0
  124. package/dist/components/Success.js +6 -0
  125. package/dist/components/Success.js.map +1 -0
  126. package/dist/index.d.ts +6 -0
  127. package/dist/index.d.ts.map +1 -1
  128. package/dist/index.js +9 -246
  129. package/dist/index.js.map +1 -1
  130. package/dist/server-main.d.ts +11 -0
  131. package/dist/server-main.d.ts.map +1 -0
  132. package/dist/server-main.js +81 -0
  133. package/dist/server-main.js.map +1 -0
  134. package/dist/server.js +1 -1
  135. package/dist/server.js.map +1 -1
  136. package/dist/theme/colors.d.ts +64 -0
  137. package/dist/theme/colors.d.ts.map +1 -0
  138. package/dist/theme/colors.js +85 -0
  139. package/dist/theme/colors.js.map +1 -0
  140. package/dist/theme/index.d.ts +6 -0
  141. package/dist/theme/index.d.ts.map +1 -0
  142. package/dist/theme/index.js +6 -0
  143. package/dist/theme/index.js.map +1 -0
  144. package/dist/tools/claim-task.d.ts +7 -10
  145. package/dist/tools/claim-task.d.ts.map +1 -1
  146. package/dist/tools/create-doc.d.ts +7 -10
  147. package/dist/tools/create-doc.d.ts.map +1 -1
  148. package/dist/tools/create-plan.d.ts +1 -7
  149. package/dist/tools/create-plan.d.ts.map +1 -1
  150. package/dist/tools/delete-doc.d.ts +1 -9
  151. package/dist/tools/delete-doc.d.ts.map +1 -1
  152. package/dist/tools/get-next-task.d.ts +19 -9
  153. package/dist/tools/get-next-task.d.ts.map +1 -1
  154. package/dist/tools/get-next-task.js +64 -1
  155. package/dist/tools/get-next-task.js.map +1 -1
  156. package/dist/tools/get-plan-status.d.ts +24 -0
  157. package/dist/tools/get-plan-status.d.ts.map +1 -0
  158. package/dist/tools/get-plan-status.js +48 -0
  159. package/dist/tools/get-plan-status.js.map +1 -0
  160. package/dist/tools/index.d.ts.map +1 -1
  161. package/dist/tools/index.js +66 -18
  162. package/dist/tools/index.js.map +1 -1
  163. package/dist/tools/list-agents.d.ts +24 -0
  164. package/dist/tools/list-agents.d.ts.map +1 -0
  165. package/dist/tools/list-agents.js +60 -0
  166. package/dist/tools/list-agents.js.map +1 -0
  167. package/dist/tools/list-docs.d.ts +1 -11
  168. package/dist/tools/list-docs.d.ts.map +1 -1
  169. package/dist/tools/list-plans.d.ts +23 -0
  170. package/dist/tools/list-plans.d.ts.map +1 -0
  171. package/dist/tools/list-plans.js +44 -0
  172. package/dist/tools/list-plans.js.map +1 -0
  173. package/dist/tools/open-document-in-cursor.d.ts +1 -9
  174. package/dist/tools/open-document-in-cursor.d.ts.map +1 -1
  175. package/dist/tools/process-doc.d.ts +43 -0
  176. package/dist/tools/process-doc.d.ts.map +1 -0
  177. package/dist/tools/process-doc.js +227 -0
  178. package/dist/tools/process-doc.js.map +1 -0
  179. package/dist/tools/process-docs.d.ts +54 -0
  180. package/dist/tools/process-docs.d.ts.map +1 -0
  181. package/dist/tools/process-docs.js +348 -0
  182. package/dist/tools/process-docs.js.map +1 -0
  183. package/dist/tools/read-doc.d.ts +1 -7
  184. package/dist/tools/read-doc.d.ts.map +1 -1
  185. package/dist/tools/release-task.d.ts +5 -10
  186. package/dist/tools/release-task.d.ts.map +1 -1
  187. package/dist/tools/rlm-multi-query.d.ts +5 -61
  188. package/dist/tools/rlm-multi-query.d.ts.map +1 -1
  189. package/dist/tools/rlm-query.d.ts +1 -13
  190. package/dist/tools/rlm-query.d.ts.map +1 -1
  191. package/dist/tools/search-docs.d.ts +1 -7
  192. package/dist/tools/search-docs.d.ts.map +1 -1
  193. package/dist/tools/update-doc.d.ts +6 -90
  194. package/dist/tools/update-doc.d.ts.map +1 -1
  195. package/dist/tools/update-task-status.d.ts +7 -12
  196. package/dist/tools/update-task-status.d.ts.map +1 -1
  197. package/dist/utils/config-resolver.d.ts +19 -0
  198. package/dist/utils/config-resolver.d.ts.map +1 -0
  199. package/dist/utils/config-resolver.js +65 -0
  200. package/dist/utils/config-resolver.js.map +1 -0
  201. package/dist/utils/index.d.ts +1 -0
  202. package/dist/utils/index.d.ts.map +1 -1
  203. package/dist/utils/index.js +1 -0
  204. package/dist/utils/index.js.map +1 -1
  205. package/dist/utils/markdown.d.ts +15 -0
  206. package/dist/utils/markdown.d.ts.map +1 -0
  207. package/dist/utils/markdown.js +20 -0
  208. package/dist/utils/markdown.js.map +1 -0
  209. package/dist/utils/os-paths.d.ts +4 -4
  210. package/dist/utils/os-paths.js +5 -5
  211. package/dist/utils/os-paths.js.map +1 -1
  212. package/package.json +22 -11
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Project initialization for limps CLI.
3
+ */
4
+ import { resolve } from 'path';
5
+ import { mkdirSync, existsSync, writeFileSync } from 'fs';
6
+ import { homedir } from 'os';
7
+ import which from 'which';
8
+ import { getOSConfigPath, getOSBasePath, getOSDataPath, getOSCoordinationPath, } from '../utils/os-paths.js';
9
+ import { registerProject } from './registry.js';
10
+ /**
11
+ * Expand tilde in path to full home directory path.
12
+ */
13
+ function expandTilde(path) {
14
+ if (path.startsWith('~/')) {
15
+ return resolve(homedir(), path.slice(2));
16
+ }
17
+ return resolve(path);
18
+ }
19
+ /**
20
+ * Get the full path to the limps executable.
21
+ * Falls back to 'limps' if not found in PATH.
22
+ */
23
+ function getLocalPlannerPath() {
24
+ try {
25
+ return which.sync('limps');
26
+ }
27
+ catch {
28
+ return 'limps';
29
+ }
30
+ }
31
+ /**
32
+ * Initialize a new project configuration.
33
+ *
34
+ * @param projectName - Name of the project (e.g., "runi-planning")
35
+ * @param docsPath - Optional path to documentation directory
36
+ * @returns Output message for the CLI
37
+ */
38
+ export function initProject(projectName, docsPath) {
39
+ const basePath = getOSBasePath(projectName);
40
+ const configPath = getOSConfigPath(projectName);
41
+ const dataPath = getOSDataPath(projectName);
42
+ const coordinationPath = getOSCoordinationPath(projectName);
43
+ // Expand tilde in docsPath if provided
44
+ const resolvedDocsPath = docsPath ? expandTilde(docsPath) : null;
45
+ const defaultDocsPath = resolve(homedir(), 'Documents', projectName);
46
+ // Create directory
47
+ mkdirSync(basePath, { recursive: true });
48
+ // Check if config already exists
49
+ if (existsSync(configPath)) {
50
+ throw new Error(`Config already exists at: ${configPath}\nTo reconfigure, delete the existing config file first.`);
51
+ }
52
+ // Create default config with absolute paths
53
+ const config = {
54
+ plansPath: resolvedDocsPath
55
+ ? resolve(resolvedDocsPath, 'plans')
56
+ : resolve(defaultDocsPath, 'plans'),
57
+ docsPaths: [resolvedDocsPath || defaultDocsPath],
58
+ fileExtensions: ['.md'],
59
+ dataPath: dataPath,
60
+ coordinationPath: coordinationPath,
61
+ heartbeatTimeout: 300000,
62
+ debounceDelay: 200,
63
+ maxHandoffIterations: 3,
64
+ };
65
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
66
+ // Auto-register in the project registry
67
+ registerProject(projectName, configPath);
68
+ // Get the full path to limps executable
69
+ const localPlannerPath = getLocalPlannerPath();
70
+ const lines = [];
71
+ lines.push(`\nCreated ${projectName} configuration\n`);
72
+ lines.push(`Project "${projectName}" registered in limps.`);
73
+ lines.push(`Run \`limps config use ${projectName}\` to set as default.\n`);
74
+ lines.push(`Config: ${configPath}`);
75
+ lines.push(`Data: ${dataPath}`);
76
+ lines.push('');
77
+ // Cursor settings snippet
78
+ lines.push('Add this to your Cursor settings (Cmd+Shift+P → "Preferences: Open User Settings (JSON)"):\n');
79
+ lines.push(JSON.stringify({
80
+ 'mcp.servers': {
81
+ [projectName]: {
82
+ command: localPlannerPath,
83
+ args: ['--config', configPath],
84
+ },
85
+ },
86
+ }, null, 2));
87
+ lines.push('');
88
+ // Claude Desktop config snippet
89
+ lines.push('For Claude Desktop, add this to ~/Library/Application Support/Claude/claude_desktop_config.json:\n');
90
+ lines.push(JSON.stringify({
91
+ mcpServers: {
92
+ [projectName]: {
93
+ command: 'npx',
94
+ args: ['-y', '@sudosandwich/limps', '--config', configPath],
95
+ },
96
+ },
97
+ }, null, 2));
98
+ lines.push('');
99
+ // Test command
100
+ lines.push('To test the server:');
101
+ lines.push(` ${localPlannerPath} --config "${configPath}"`);
102
+ return lines.join('\n');
103
+ }
104
+ //# sourceMappingURL=init-project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-project.js","sourceRoot":"","sources":["../../src/cli/init-project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * CLI command: list-agents
3
+ * Lists all agents in a specific plan.
4
+ */
5
+ import type { ServerConfig } from '../config.js';
6
+ import { type ParsedAgentFile, type AgentFrontmatter } from '../agent-parser.js';
7
+ /**
8
+ * Agent entry for CLI output.
9
+ */
10
+ export interface CliAgentEntry {
11
+ number: string;
12
+ title: string;
13
+ status: AgentFrontmatter['status'];
14
+ persona: AgentFrontmatter['persona'];
15
+ dependencyCount: number;
16
+ fileCount: number;
17
+ }
18
+ /**
19
+ * Find plan directory by plan number or name.
20
+ *
21
+ * @param plansPath - Base path to plans
22
+ * @param planId - Plan number (e.g., "4") or full name
23
+ * @returns Full path to plan directory or null
24
+ */
25
+ export declare function findPlanDirectory(plansPath: string, planId: string): string | null;
26
+ /**
27
+ * Get all agent files from a plan directory.
28
+ *
29
+ * @param planDir - Path to plan directory
30
+ * @returns Array of parsed agent files
31
+ */
32
+ export declare function getAgentFiles(planDir: string): ParsedAgentFile[];
33
+ /**
34
+ * Result of listing agents.
35
+ */
36
+ export interface ListAgentsResult {
37
+ planName: string;
38
+ agents: ParsedAgentFile[];
39
+ statusCounts: {
40
+ GAP: number;
41
+ WIP: number;
42
+ PASS: number;
43
+ BLOCKED: number;
44
+ };
45
+ total: number;
46
+ }
47
+ /**
48
+ * Get all agents data from a plan.
49
+ * Returns structured data for rendering.
50
+ *
51
+ * @param config - Server configuration
52
+ * @param planId - Plan number or name
53
+ * @returns Structured agent data or error
54
+ */
55
+ export declare function getAgentsData(config: ServerConfig, planId: string): ListAgentsResult | {
56
+ error: string;
57
+ };
58
+ /**
59
+ * List all agents in a plan.
60
+ *
61
+ * @param config - Server configuration
62
+ * @param planId - Plan number or name
63
+ * @returns Formatted string output for CLI
64
+ */
65
+ export declare function listAgents(config: ServerConfig, planId: string): string;
66
+ //# sourceMappingURL=list-agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-agents.d.ts","sourceRoot":"","sources":["../../src/cli/list-agents.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAkB,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEjG;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnC,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA+BlF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,EAAE,CA2BhE;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,YAAY,EAAE;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,GACb,gBAAgB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAwCtC;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAoCvE"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * CLI command: list-agents
3
+ * Lists all agents in a specific plan.
4
+ */
5
+ import { existsSync, readdirSync, readFileSync } from 'fs';
6
+ import { join } from 'path';
7
+ import { parseAgentFile } from '../agent-parser.js';
8
+ /**
9
+ * Find plan directory by plan number or name.
10
+ *
11
+ * @param plansPath - Base path to plans
12
+ * @param planId - Plan number (e.g., "4") or full name
13
+ * @returns Full path to plan directory or null
14
+ */
15
+ export function findPlanDirectory(plansPath, planId) {
16
+ if (!existsSync(plansPath)) {
17
+ return null;
18
+ }
19
+ const dirs = readdirSync(plansPath, { withFileTypes: true })
20
+ .filter((dirent) => dirent.isDirectory())
21
+ .map((dirent) => dirent.name);
22
+ // Try exact match first
23
+ if (dirs.includes(planId)) {
24
+ return join(plansPath, planId);
25
+ }
26
+ // Try matching by number prefix
27
+ const paddedNumber = planId.padStart(4, '0');
28
+ for (const dir of dirs) {
29
+ if (dir.startsWith(`${paddedNumber}-`) || dir.startsWith(`${planId}-`)) {
30
+ return join(plansPath, dir);
31
+ }
32
+ }
33
+ // Try matching unpadded number
34
+ for (const dir of dirs) {
35
+ const match = dir.match(/^0*(\d+)-/);
36
+ if (match && match[1] === planId) {
37
+ return join(plansPath, dir);
38
+ }
39
+ }
40
+ return null;
41
+ }
42
+ /**
43
+ * Get all agent files from a plan directory.
44
+ *
45
+ * @param planDir - Path to plan directory
46
+ * @returns Array of parsed agent files
47
+ */
48
+ export function getAgentFiles(planDir) {
49
+ const agentsDir = join(planDir, 'agents');
50
+ if (!existsSync(agentsDir)) {
51
+ return [];
52
+ }
53
+ const files = readdirSync(agentsDir, { withFileTypes: true })
54
+ .filter((dirent) => dirent.isFile() && dirent.name.endsWith('.agent.md'))
55
+ .map((dirent) => dirent.name);
56
+ const agents = [];
57
+ for (const file of files) {
58
+ const filePath = join(agentsDir, file);
59
+ try {
60
+ const content = readFileSync(filePath, 'utf-8');
61
+ const parsed = parseAgentFile(filePath, content);
62
+ if (parsed) {
63
+ agents.push(parsed);
64
+ }
65
+ }
66
+ catch {
67
+ // Skip files that can't be read
68
+ }
69
+ }
70
+ return agents;
71
+ }
72
+ /**
73
+ * Get all agents data from a plan.
74
+ * Returns structured data for rendering.
75
+ *
76
+ * @param config - Server configuration
77
+ * @param planId - Plan number or name
78
+ * @returns Structured agent data or error
79
+ */
80
+ export function getAgentsData(config, planId) {
81
+ const planDir = findPlanDirectory(config.plansPath, planId);
82
+ if (!planDir) {
83
+ return { error: `Plan not found: ${planId}` };
84
+ }
85
+ const agents = getAgentFiles(planDir);
86
+ if (agents.length === 0) {
87
+ return { error: 'No agents found' };
88
+ }
89
+ // Sort by agent number
90
+ agents.sort((a, b) => {
91
+ const numA = parseInt(a.agentNumber, 10);
92
+ const numB = parseInt(b.agentNumber, 10);
93
+ return numA - numB;
94
+ });
95
+ // Calculate status counts
96
+ const statusCounts = {
97
+ GAP: 0,
98
+ WIP: 0,
99
+ PASS: 0,
100
+ BLOCKED: 0,
101
+ };
102
+ for (const agent of agents) {
103
+ statusCounts[agent.frontmatter.status]++;
104
+ }
105
+ const planName = planDir.split('/').pop() || planId;
106
+ return {
107
+ planName,
108
+ agents,
109
+ statusCounts,
110
+ total: agents.length,
111
+ };
112
+ }
113
+ /**
114
+ * List all agents in a plan.
115
+ *
116
+ * @param config - Server configuration
117
+ * @param planId - Plan number or name
118
+ * @returns Formatted string output for CLI
119
+ */
120
+ export function listAgents(config, planId) {
121
+ const result = getAgentsData(config, planId);
122
+ if ('error' in result) {
123
+ return result.error;
124
+ }
125
+ const { planName, agents, statusCounts } = result;
126
+ // Format output
127
+ const lines = [];
128
+ lines.push(`Agents in ${planName}:`);
129
+ lines.push('');
130
+ for (const agent of agents) {
131
+ const statusIcon = {
132
+ GAP: ' ',
133
+ WIP: '*',
134
+ PASS: '+',
135
+ BLOCKED: '!',
136
+ }[agent.frontmatter.status];
137
+ const title = agent.title || `Agent ${agent.agentNumber}`;
138
+ lines.push(`[${statusIcon}] ${agent.agentNumber} - ${title}`);
139
+ lines.push(` Persona: ${agent.frontmatter.persona} | Status: ${agent.frontmatter.status}`);
140
+ lines.push(` Dependencies: ${agent.frontmatter.dependencies.length} | Files: ${agent.frontmatter.files.length}`);
141
+ lines.push('');
142
+ }
143
+ lines.push('Summary:');
144
+ lines.push(` Total: ${agents.length} | PASS: ${statusCounts.PASS} | WIP: ${statusCounts.WIP} | GAP: ${statusCounts.GAP} | BLOCKED: ${statusCounts.BLOCKED}`);
145
+ return lines.join('\n');
146
+ }
147
+ //# sourceMappingURL=list-agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-agents.js","sourceRoot":"","sources":["../../src/cli/list-agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * CLI command: list-plans
3
+ * Lists all plans in the configured plansPath.
4
+ */
5
+ import type { ServerConfig } from '../config.js';
6
+ /**
7
+ * Plan entry for CLI output.
8
+ */
9
+ export interface CliPlanEntry {
10
+ number: string;
11
+ name: string;
12
+ workType: 'feature' | 'bug' | 'refactor' | 'docs' | 'unknown';
13
+ overview: string;
14
+ status: 'GAP' | 'WIP' | 'PASS' | 'BLOCKED';
15
+ }
16
+ /**
17
+ * Extract plan number from directory name.
18
+ * Handles both padded (0001-plan-name) and unpadded (1-plan-name) formats.
19
+ */
20
+ export declare function extractPlanNumber(dirName: string): string | null;
21
+ /**
22
+ * Extract plan name from directory name.
23
+ * Removes the number prefix and converts dashes to spaces.
24
+ */
25
+ export declare function extractPlanName(dirName: string): string;
26
+ /**
27
+ * Detect work type from plan content or directory name.
28
+ */
29
+ export declare function detectWorkType(dirName: string, content: string): CliPlanEntry['workType'];
30
+ /**
31
+ * Extract overview from plan content.
32
+ * Looks for content after the title and before the first section.
33
+ */
34
+ export declare function extractOverview(content: string): string;
35
+ /**
36
+ * Get plan status from frontmatter or default.
37
+ */
38
+ export declare function getPlanStatus(content: string): CliPlanEntry['status'];
39
+ /**
40
+ * Result of listing plans.
41
+ */
42
+ export interface ListPlansResult {
43
+ plans: CliPlanEntry[];
44
+ total: number;
45
+ }
46
+ /**
47
+ * Get all plans data from the configured plansPath.
48
+ * Returns structured data for rendering.
49
+ *
50
+ * @param config - Server configuration
51
+ * @returns Structured plan data or error message
52
+ */
53
+ export declare function getPlansData(config: ServerConfig): ListPlansResult | {
54
+ error: string;
55
+ };
56
+ /**
57
+ * List all plans from the configured plansPath.
58
+ *
59
+ * @param config - Server configuration
60
+ * @returns Formatted string output for CLI
61
+ */
62
+ export declare function listPlans(config: ServerConfig): string;
63
+ //# sourceMappingURL=list-plans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-plans.d.ts","sourceRoot":"","sources":["../../src/cli/list-plans.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;CAC5C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMhE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,CAsBzF;AA4CD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAuCvD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CASrE;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,eAAe,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CA+CtF;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAgCtD"}
@@ -0,0 +1,218 @@
1
+ /**
2
+ * CLI command: list-plans
3
+ * Lists all plans in the configured plansPath.
4
+ */
5
+ import { existsSync, readdirSync, readFileSync } from 'fs';
6
+ import { join } from 'path';
7
+ import { stripMarkdown } from '../utils/markdown.js';
8
+ /**
9
+ * Extract plan number from directory name.
10
+ * Handles both padded (0001-plan-name) and unpadded (1-plan-name) formats.
11
+ */
12
+ export function extractPlanNumber(dirName) {
13
+ const match = dirName.match(/^(\d+)-/);
14
+ if (match) {
15
+ return match[1];
16
+ }
17
+ return null;
18
+ }
19
+ /**
20
+ * Extract plan name from directory name.
21
+ * Removes the number prefix and converts dashes to spaces.
22
+ */
23
+ export function extractPlanName(dirName) {
24
+ const match = dirName.match(/^\d+-(.+)$/);
25
+ if (match) {
26
+ return match[1].replace(/-/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
27
+ }
28
+ return dirName;
29
+ }
30
+ /**
31
+ * Detect work type from plan content or directory name.
32
+ */
33
+ export function detectWorkType(dirName, content) {
34
+ const lowerDir = dirName.toLowerCase();
35
+ const lowerContent = content.toLowerCase();
36
+ if (lowerDir.includes('bug') || lowerContent.includes('bug fix')) {
37
+ return 'bug';
38
+ }
39
+ if (lowerDir.includes('refactor') || lowerContent.includes('refactor')) {
40
+ return 'refactor';
41
+ }
42
+ if (lowerDir.includes('doc') || lowerContent.includes('documentation')) {
43
+ return 'docs';
44
+ }
45
+ if (lowerDir.includes('feature') ||
46
+ lowerDir.includes('feat') ||
47
+ lowerContent.includes('feature')) {
48
+ return 'feature';
49
+ }
50
+ return 'unknown';
51
+ }
52
+ /**
53
+ * Parse YAML frontmatter from content.
54
+ */
55
+ function parseYamlFrontmatter(content) {
56
+ const yamlRegex = /^---\s*\n([\s\S]*?)\n---\s*\n/;
57
+ const match = content.match(yamlRegex);
58
+ if (!match) {
59
+ return {};
60
+ }
61
+ const frontmatterText = match[1];
62
+ const frontmatter = {};
63
+ const lines = frontmatterText.split('\n');
64
+ for (const line of lines) {
65
+ const trimmed = line.trim();
66
+ if (!trimmed || trimmed.startsWith('#'))
67
+ continue;
68
+ const colonIndex = trimmed.indexOf(':');
69
+ if (colonIndex === -1)
70
+ continue;
71
+ const key = trimmed.slice(0, colonIndex).trim();
72
+ let value = trimmed.slice(colonIndex + 1).trim();
73
+ if (typeof value === 'string') {
74
+ if ((value.startsWith('"') && value.endsWith('"')) ||
75
+ (value.startsWith("'") && value.endsWith("'"))) {
76
+ value = value.slice(1, -1);
77
+ }
78
+ }
79
+ if (key) {
80
+ frontmatter[key] = value;
81
+ }
82
+ }
83
+ return frontmatter;
84
+ }
85
+ /**
86
+ * Extract overview from plan content.
87
+ * Looks for content after the title and before the first section.
88
+ */
89
+ export function extractOverview(content) {
90
+ // Remove frontmatter
91
+ const withoutFrontmatter = content.replace(/^---\s*\n[\s\S]*?\n---\s*\n/, '');
92
+ // Find content between title and first ## heading
93
+ const lines = withoutFrontmatter.split('\n');
94
+ const overviewLines = [];
95
+ let foundTitle = false;
96
+ for (const line of lines) {
97
+ if (line.startsWith('# ') && !foundTitle) {
98
+ foundTitle = true;
99
+ continue;
100
+ }
101
+ if (foundTitle) {
102
+ if (line.startsWith('## ') || line.startsWith('### ')) {
103
+ break;
104
+ }
105
+ const trimmed = line.trim();
106
+ if (trimmed) {
107
+ // Skip lines that look like raw metadata (e.g., `**Status:** Draft **Date:** 2026-01-15`)
108
+ // These are common when frontmatter leaks into content
109
+ if (/^\*\*[A-Za-z]+\*\*:\s*.*(\*\*[A-Za-z]+\*\*:.*)?$/.test(trimmed)) {
110
+ continue;
111
+ }
112
+ // Skip horizontal rules
113
+ if (/^[-*_]{3,}$/.test(trimmed)) {
114
+ continue;
115
+ }
116
+ overviewLines.push(trimmed);
117
+ }
118
+ }
119
+ }
120
+ const overview = overviewLines.join(' ');
121
+ // Strip markdown for clean CLI display
122
+ const cleaned = stripMarkdown(overview);
123
+ const truncated = cleaned.slice(0, 100);
124
+ return truncated.length === 100 ? truncated + '...' : truncated;
125
+ }
126
+ /**
127
+ * Get plan status from frontmatter or default.
128
+ */
129
+ export function getPlanStatus(content) {
130
+ const frontmatter = parseYamlFrontmatter(content);
131
+ if (frontmatter.status && typeof frontmatter.status === 'string') {
132
+ const status = frontmatter.status.toUpperCase();
133
+ if (['GAP', 'WIP', 'PASS', 'BLOCKED'].includes(status)) {
134
+ return status;
135
+ }
136
+ }
137
+ return 'GAP';
138
+ }
139
+ /**
140
+ * Get all plans data from the configured plansPath.
141
+ * Returns structured data for rendering.
142
+ *
143
+ * @param config - Server configuration
144
+ * @returns Structured plan data or error message
145
+ */
146
+ export function getPlansData(config) {
147
+ const plansPath = config.plansPath;
148
+ if (!existsSync(plansPath)) {
149
+ return { error: 'No plans found (plans directory does not exist)' };
150
+ }
151
+ const dirs = readdirSync(plansPath, { withFileTypes: true })
152
+ .filter((dirent) => dirent.isDirectory())
153
+ .map((dirent) => dirent.name);
154
+ const plans = [];
155
+ for (const dir of dirs) {
156
+ const planNumber = extractPlanNumber(dir);
157
+ if (!planNumber) {
158
+ continue;
159
+ }
160
+ const planMdPath = join(plansPath, dir, 'plan.md');
161
+ let content = '';
162
+ if (existsSync(planMdPath)) {
163
+ try {
164
+ content = readFileSync(planMdPath, 'utf-8');
165
+ }
166
+ catch {
167
+ // Ignore read errors
168
+ }
169
+ }
170
+ plans.push({
171
+ number: planNumber,
172
+ name: extractPlanName(dir),
173
+ workType: detectWorkType(dir, content),
174
+ overview: extractOverview(content),
175
+ status: getPlanStatus(content),
176
+ });
177
+ }
178
+ if (plans.length === 0) {
179
+ return { error: 'No plans found' };
180
+ }
181
+ // Sort by plan number
182
+ plans.sort((a, b) => parseInt(a.number, 10) - parseInt(b.number, 10));
183
+ return { plans, total: plans.length };
184
+ }
185
+ /**
186
+ * List all plans from the configured plansPath.
187
+ *
188
+ * @param config - Server configuration
189
+ * @returns Formatted string output for CLI
190
+ */
191
+ export function listPlans(config) {
192
+ const result = getPlansData(config);
193
+ if ('error' in result) {
194
+ return result.error;
195
+ }
196
+ const { plans } = result;
197
+ // Format output
198
+ const lines = [];
199
+ lines.push('Plans:');
200
+ lines.push('');
201
+ for (const plan of plans) {
202
+ const statusIcon = {
203
+ GAP: ' ',
204
+ WIP: '*',
205
+ PASS: '+',
206
+ BLOCKED: '!',
207
+ }[plan.status];
208
+ lines.push(`[${statusIcon}] ${plan.number.padStart(4, '0')} - ${plan.name}`);
209
+ lines.push(` Type: ${plan.workType} | Status: ${plan.status}`);
210
+ if (plan.overview) {
211
+ lines.push(` ${plan.overview}`);
212
+ }
213
+ lines.push('');
214
+ }
215
+ lines.push(`Total: ${plans.length} plan(s)`);
216
+ return lines.join('\n');
217
+ }
218
+ //# sourceMappingURL=list-plans.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-plans.js","sourceRoot":"","sources":["../../src/cli/list-plans.ts"],"names":[],"mappings":"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"}