@sudosandwich/limps 0.2.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 (183) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +190 -0
  3. package/dist/agent-parser.d.ts +146 -0
  4. package/dist/agent-parser.d.ts.map +1 -0
  5. package/dist/agent-parser.js +448 -0
  6. package/dist/agent-parser.js.map +1 -0
  7. package/dist/config.d.ts +54 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +146 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/coordination.d.ts +102 -0
  12. package/dist/coordination.d.ts.map +1 -0
  13. package/dist/coordination.js +157 -0
  14. package/dist/coordination.js.map +1 -0
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +256 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/indexer.d.ts +83 -0
  20. package/dist/indexer.d.ts.map +1 -0
  21. package/dist/indexer.js +467 -0
  22. package/dist/indexer.js.map +1 -0
  23. package/dist/resources/agents-status.d.ts +32 -0
  24. package/dist/resources/agents-status.d.ts.map +1 -0
  25. package/dist/resources/agents-status.js +73 -0
  26. package/dist/resources/agents-status.js.map +1 -0
  27. package/dist/resources/decisions-log.d.ts +21 -0
  28. package/dist/resources/decisions-log.d.ts.map +1 -0
  29. package/dist/resources/decisions-log.js +146 -0
  30. package/dist/resources/decisions-log.js.map +1 -0
  31. package/dist/resources/index.d.ts +10 -0
  32. package/dist/resources/index.d.ts.map +1 -0
  33. package/dist/resources/index.js +74 -0
  34. package/dist/resources/index.js.map +1 -0
  35. package/dist/resources/plans-full.d.ts +11 -0
  36. package/dist/resources/plans-full.d.ts.map +1 -0
  37. package/dist/resources/plans-full.js +71 -0
  38. package/dist/resources/plans-full.js.map +1 -0
  39. package/dist/resources/plans-index.d.ts +30 -0
  40. package/dist/resources/plans-index.d.ts.map +1 -0
  41. package/dist/resources/plans-index.js +177 -0
  42. package/dist/resources/plans-index.js.map +1 -0
  43. package/dist/resources/plans-summary.d.ts +33 -0
  44. package/dist/resources/plans-summary.d.ts.map +1 -0
  45. package/dist/resources/plans-summary.js +238 -0
  46. package/dist/resources/plans-summary.js.map +1 -0
  47. package/dist/rlm/extractors.d.ts +39 -0
  48. package/dist/rlm/extractors.d.ts.map +1 -0
  49. package/dist/rlm/extractors.js +291 -0
  50. package/dist/rlm/extractors.js.map +1 -0
  51. package/dist/rlm/helpers-inject.d.ts +13 -0
  52. package/dist/rlm/helpers-inject.d.ts.map +1 -0
  53. package/dist/rlm/helpers-inject.js +586 -0
  54. package/dist/rlm/helpers-inject.js.map +1 -0
  55. package/dist/rlm/helpers.d.ts +124 -0
  56. package/dist/rlm/helpers.d.ts.map +1 -0
  57. package/dist/rlm/helpers.js +381 -0
  58. package/dist/rlm/helpers.js.map +1 -0
  59. package/dist/rlm/index.d.ts +12 -0
  60. package/dist/rlm/index.d.ts.map +1 -0
  61. package/dist/rlm/index.js +19 -0
  62. package/dist/rlm/index.js.map +1 -0
  63. package/dist/rlm/parallel.d.ts +45 -0
  64. package/dist/rlm/parallel.d.ts.map +1 -0
  65. package/dist/rlm/parallel.js +76 -0
  66. package/dist/rlm/parallel.js.map +1 -0
  67. package/dist/rlm/recursion.d.ts +96 -0
  68. package/dist/rlm/recursion.d.ts.map +1 -0
  69. package/dist/rlm/recursion.js +113 -0
  70. package/dist/rlm/recursion.js.map +1 -0
  71. package/dist/rlm/sampling.d.ts +100 -0
  72. package/dist/rlm/sampling.d.ts.map +1 -0
  73. package/dist/rlm/sampling.js +96 -0
  74. package/dist/rlm/sampling.js.map +1 -0
  75. package/dist/rlm/sandbox.d.ts +73 -0
  76. package/dist/rlm/sandbox.d.ts.map +1 -0
  77. package/dist/rlm/sandbox.js +160 -0
  78. package/dist/rlm/sandbox.js.map +1 -0
  79. package/dist/rlm/security.d.ts +28 -0
  80. package/dist/rlm/security.d.ts.map +1 -0
  81. package/dist/rlm/security.js +154 -0
  82. package/dist/rlm/security.js.map +1 -0
  83. package/dist/server.d.ts +21 -0
  84. package/dist/server.d.ts.map +1 -0
  85. package/dist/server.js +107 -0
  86. package/dist/server.js.map +1 -0
  87. package/dist/task-parser.d.ts +47 -0
  88. package/dist/task-parser.d.ts.map +1 -0
  89. package/dist/task-parser.js +112 -0
  90. package/dist/task-parser.js.map +1 -0
  91. package/dist/test-setup.d.ts +6 -0
  92. package/dist/test-setup.d.ts.map +1 -0
  93. package/dist/test-setup.js +37 -0
  94. package/dist/test-setup.js.map +1 -0
  95. package/dist/tools/claim-task.d.ts +28 -0
  96. package/dist/tools/claim-task.d.ts.map +1 -0
  97. package/dist/tools/claim-task.js +288 -0
  98. package/dist/tools/claim-task.js.map +1 -0
  99. package/dist/tools/create-doc.d.ts +47 -0
  100. package/dist/tools/create-doc.d.ts.map +1 -0
  101. package/dist/tools/create-doc.js +137 -0
  102. package/dist/tools/create-doc.js.map +1 -0
  103. package/dist/tools/create-plan.d.ts +25 -0
  104. package/dist/tools/create-plan.d.ts.map +1 -0
  105. package/dist/tools/create-plan.js +179 -0
  106. package/dist/tools/create-plan.js.map +1 -0
  107. package/dist/tools/delete-doc.d.ts +51 -0
  108. package/dist/tools/delete-doc.d.ts.map +1 -0
  109. package/dist/tools/delete-doc.js +194 -0
  110. package/dist/tools/delete-doc.js.map +1 -0
  111. package/dist/tools/get-next-task.d.ts +49 -0
  112. package/dist/tools/get-next-task.d.ts.map +1 -0
  113. package/dist/tools/get-next-task.js +204 -0
  114. package/dist/tools/get-next-task.js.map +1 -0
  115. package/dist/tools/index.d.ts +10 -0
  116. package/dist/tools/index.d.ts.map +1 -0
  117. package/dist/tools/index.js +122 -0
  118. package/dist/tools/index.js.map +1 -0
  119. package/dist/tools/list-docs.d.ts +53 -0
  120. package/dist/tools/list-docs.d.ts.map +1 -0
  121. package/dist/tools/list-docs.js +236 -0
  122. package/dist/tools/list-docs.js.map +1 -0
  123. package/dist/tools/open-document-in-cursor.d.ts +62 -0
  124. package/dist/tools/open-document-in-cursor.d.ts.map +1 -0
  125. package/dist/tools/open-document-in-cursor.js +211 -0
  126. package/dist/tools/open-document-in-cursor.js.map +1 -0
  127. package/dist/tools/read-doc.d.ts +44 -0
  128. package/dist/tools/read-doc.d.ts.map +1 -0
  129. package/dist/tools/read-doc.js +174 -0
  130. package/dist/tools/read-doc.js.map +1 -0
  131. package/dist/tools/release-task.d.ts +28 -0
  132. package/dist/tools/release-task.d.ts.map +1 -0
  133. package/dist/tools/release-task.js +154 -0
  134. package/dist/tools/release-task.js.map +1 -0
  135. package/dist/tools/rlm-multi-query.d.ts +110 -0
  136. package/dist/tools/rlm-multi-query.d.ts.map +1 -0
  137. package/dist/tools/rlm-multi-query.js +348 -0
  138. package/dist/tools/rlm-multi-query.js.map +1 -0
  139. package/dist/tools/rlm-query.d.ts +56 -0
  140. package/dist/tools/rlm-query.d.ts.map +1 -0
  141. package/dist/tools/rlm-query.js +228 -0
  142. package/dist/tools/rlm-query.js.map +1 -0
  143. package/dist/tools/search-docs.d.ts +34 -0
  144. package/dist/tools/search-docs.d.ts.map +1 -0
  145. package/dist/tools/search-docs.js +292 -0
  146. package/dist/tools/search-docs.js.map +1 -0
  147. package/dist/tools/update-doc.d.ts +149 -0
  148. package/dist/tools/update-doc.d.ts.map +1 -0
  149. package/dist/tools/update-doc.js +195 -0
  150. package/dist/tools/update-doc.js.map +1 -0
  151. package/dist/tools/update-task-status.d.ts +31 -0
  152. package/dist/tools/update-task-status.d.ts.map +1 -0
  153. package/dist/tools/update-task-status.js +303 -0
  154. package/dist/tools/update-task-status.js.map +1 -0
  155. package/dist/types.d.ts +50 -0
  156. package/dist/types.d.ts.map +1 -0
  157. package/dist/types.js +2 -0
  158. package/dist/types.js.map +1 -0
  159. package/dist/utils/backup.d.ts +76 -0
  160. package/dist/utils/backup.d.ts.map +1 -0
  161. package/dist/utils/backup.js +172 -0
  162. package/dist/utils/backup.js.map +1 -0
  163. package/dist/utils/errors.d.ts +93 -0
  164. package/dist/utils/errors.d.ts.map +1 -0
  165. package/dist/utils/errors.js +125 -0
  166. package/dist/utils/errors.js.map +1 -0
  167. package/dist/utils/index.d.ts +8 -0
  168. package/dist/utils/index.d.ts.map +1 -0
  169. package/dist/utils/index.js +9 -0
  170. package/dist/utils/index.js.map +1 -0
  171. package/dist/utils/os-paths.d.ts +45 -0
  172. package/dist/utils/os-paths.d.ts.map +1 -0
  173. package/dist/utils/os-paths.js +81 -0
  174. package/dist/utils/os-paths.js.map +1 -0
  175. package/dist/utils/paths.d.ts +71 -0
  176. package/dist/utils/paths.d.ts.map +1 -0
  177. package/dist/utils/paths.js +165 -0
  178. package/dist/utils/paths.js.map +1 -0
  179. package/dist/watcher.d.ts +19 -0
  180. package/dist/watcher.d.ts.map +1 -0
  181. package/dist/watcher.js +109 -0
  182. package/dist/watcher.js.map +1 -0
  183. package/package.json +85 -0
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Parse YAML frontmatter from markdown content.
3
+ */
4
+ function parseYamlFrontmatter(content) {
5
+ const yamlRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
6
+ const match = content.match(yamlRegex);
7
+ if (!match) {
8
+ return { frontmatter: {}, body: content };
9
+ }
10
+ const frontmatterText = match[1];
11
+ const body = match[2];
12
+ const frontmatter = {};
13
+ const lines = frontmatterText.split('\n');
14
+ for (const line of lines) {
15
+ const trimmed = line.trim();
16
+ if (!trimmed || trimmed.startsWith('#'))
17
+ continue;
18
+ const colonIndex = trimmed.indexOf(':');
19
+ if (colonIndex === -1)
20
+ continue;
21
+ const key = trimmed.slice(0, colonIndex).trim();
22
+ let value = trimmed.slice(colonIndex + 1).trim();
23
+ if (typeof value === 'string') {
24
+ if ((value.startsWith('"') && value.endsWith('"')) ||
25
+ (value.startsWith("'") && value.endsWith("'"))) {
26
+ value = value.slice(1, -1);
27
+ }
28
+ }
29
+ if (key) {
30
+ frontmatter[key] = value;
31
+ }
32
+ }
33
+ return { frontmatter, body };
34
+ }
35
+ /**
36
+ * Extract plan ID from file path.
37
+ */
38
+ function extractPlanId(path, plansPath) {
39
+ const relativePath = path.replace(plansPath, '').replace(/^[/\\]/, '');
40
+ const match = relativePath.match(/^([^/\\]+)/);
41
+ return match ? match[1] : null;
42
+ }
43
+ /**
44
+ * Extract decisions from markdown content.
45
+ * Looks for decision patterns like "Decision:", "We decided", etc.
46
+ */
47
+ function extractDecisions(content, planId, modifiedAt) {
48
+ const decisions = [];
49
+ // Extract title from first H1
50
+ const titleMatch = content.match(/^#\s+(.+)$/m);
51
+ const title = titleMatch ? titleMatch[1].trim() : 'Untitled';
52
+ // Look for decision patterns
53
+ // Pattern 1: "## Decision" or "### Decision" sections
54
+ const decisionSectionRegex = /^#{2,3}\s+Decision[:\s]*(.+?)(?=^#{1,3}\s+|$)/gms;
55
+ const sectionMatches = Array.from(content.matchAll(decisionSectionRegex));
56
+ for (const match of sectionMatches) {
57
+ const decisionText = match[1] || match[0];
58
+ const rationale = decisionText.trim().substring(0, 500); // Limit length
59
+ decisions.push({
60
+ date: new Date(modifiedAt).toISOString(),
61
+ planId,
62
+ title: `${title} - Decision`,
63
+ rationale,
64
+ context: content.substring(0, 200), // First 200 chars as context
65
+ });
66
+ }
67
+ // Pattern 2: "We decided" or "Decision:" in text
68
+ const decisionTextRegex = /(?:We\s+decided|Decision[:\s]+)(.+?)(?=\n\n|$)/gi;
69
+ const textMatches = Array.from(content.matchAll(decisionTextRegex));
70
+ for (const match of textMatches) {
71
+ const rationale = match[1].trim().substring(0, 500);
72
+ // Avoid duplicates
73
+ if (!decisions.some((d) => d.rationale === rationale)) {
74
+ decisions.push({
75
+ date: new Date(modifiedAt).toISOString(),
76
+ planId,
77
+ title: `${title} - Decision`,
78
+ rationale,
79
+ context: content.substring(0, 200),
80
+ });
81
+ }
82
+ }
83
+ // Pattern 3: Look in frontmatter for decision fields
84
+ const { frontmatter } = parseYamlFrontmatter(content);
85
+ if (frontmatter.decision || frontmatter.decisions) {
86
+ const decisionValue = frontmatter.decision || frontmatter.decisions;
87
+ const rationale = typeof decisionValue === 'string' ? decisionValue : JSON.stringify(decisionValue);
88
+ decisions.push({
89
+ date: new Date(modifiedAt).toISOString(),
90
+ planId,
91
+ title: `${title} - Decision`,
92
+ rationale: rationale.substring(0, 500),
93
+ context: content.substring(0, 200),
94
+ });
95
+ }
96
+ return decisions;
97
+ }
98
+ /**
99
+ * Handle decisions://log resource request.
100
+ * Returns chronological decision log with rationale from planning documents.
101
+ *
102
+ * @param uri - Resource URI (should be 'decisions://log')
103
+ * @param context - Resource context
104
+ * @returns Resource result with decisions log
105
+ */
106
+ export async function handleDecisionsLog(uri, context) {
107
+ const { db, config } = context;
108
+ const plansPath = config.plansPath;
109
+ // Query all plan documents from database
110
+ const allDocs = db
111
+ .prepare(`
112
+ SELECT path, content, modified_at
113
+ FROM documents
114
+ WHERE path LIKE ?
115
+ ORDER BY modified_at DESC
116
+ `)
117
+ .all(`${plansPath}%plan.md`);
118
+ const allDecisions = [];
119
+ for (const doc of allDocs) {
120
+ const planId = extractPlanId(doc.path, plansPath);
121
+ if (!planId) {
122
+ continue;
123
+ }
124
+ const decisions = extractDecisions(doc.content, planId, doc.modified_at);
125
+ allDecisions.push(...decisions);
126
+ }
127
+ // Sort chronologically (newest first)
128
+ allDecisions.sort((a, b) => {
129
+ const dateA = new Date(a.date).getTime();
130
+ const dateB = new Date(b.date).getTime();
131
+ return dateB - dateA; // Descending (newest first)
132
+ });
133
+ return {
134
+ contents: [
135
+ {
136
+ uri,
137
+ mimeType: 'application/json',
138
+ text: JSON.stringify({
139
+ decisions: allDecisions,
140
+ total: allDecisions.length,
141
+ }),
142
+ },
143
+ ],
144
+ };
145
+ }
146
+ //# sourceMappingURL=decisions-log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions-log.js","sourceRoot":"","sources":["../../src/resources/decisions-log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ResourceContext } from '../types.js';
3
+ /**
4
+ * Register all MCP resources with the server.
5
+ *
6
+ * @param server - MCP server instance
7
+ * @param context - Resource context
8
+ */
9
+ export declare function registerResources(server: McpServer, context: ResourceContext): void;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAOnD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAkEnF"}
@@ -0,0 +1,74 @@
1
+ import { handlePlansIndex } from './plans-index.js';
2
+ import { handlePlanSummary } from './plans-summary.js';
3
+ import { handlePlanFull } from './plans-full.js';
4
+ import { handleDecisionsLog } from './decisions-log.js';
5
+ import { handleAgentsStatus } from './agents-status.js';
6
+ /**
7
+ * Register all MCP resources with the server.
8
+ *
9
+ * @param server - MCP server instance
10
+ * @param context - Resource context
11
+ */
12
+ export function registerResources(server, context) {
13
+ // Store resource context on server instance for handlers to access
14
+ server.resourceContext = context;
15
+ // Register each resource using the resource() method
16
+ // Signature: resource(name: string, uri: string, readCallback: ReadResourceCallback)
17
+ // The callback receives a URL object, not a string
18
+ server.resource('Plans Index', 'plans://index', async () => {
19
+ const result = await handlePlansIndex('plans://index', context);
20
+ // Ensure text is always defined (not optional)
21
+ return {
22
+ contents: result.contents.map((c) => ({
23
+ uri: c.uri,
24
+ mimeType: c.mimeType,
25
+ text: c.text || '',
26
+ })),
27
+ };
28
+ });
29
+ // For parameterized resources, we need to handle URI parsing
30
+ // Register resources that can match patterns
31
+ server.resource('Plan Summary', 'plans://summary/*', async (uri) => {
32
+ const uriString = uri.toString();
33
+ const result = await handlePlanSummary(uriString, context);
34
+ return {
35
+ contents: result.contents.map((c) => ({
36
+ uri: c.uri,
37
+ mimeType: c.mimeType,
38
+ text: c.text || '',
39
+ })),
40
+ };
41
+ });
42
+ server.resource('Full Plan', 'plans://full/*', async (uri) => {
43
+ const uriString = uri.toString();
44
+ const result = await handlePlanFull(uriString, context);
45
+ return {
46
+ contents: result.contents.map((c) => ({
47
+ uri: c.uri,
48
+ mimeType: c.mimeType,
49
+ text: c.text || '',
50
+ })),
51
+ };
52
+ });
53
+ server.resource('Decisions Log', 'decisions://log', async () => {
54
+ const result = await handleDecisionsLog('decisions://log', context);
55
+ return {
56
+ contents: result.contents.map((c) => ({
57
+ uri: c.uri,
58
+ mimeType: c.mimeType,
59
+ text: c.text || '',
60
+ })),
61
+ };
62
+ });
63
+ server.resource('Agents Status', 'agents://status', async () => {
64
+ const result = await handleAgentsStatus('agents://status', context);
65
+ return {
66
+ contents: result.contents.map((c) => ({
67
+ uri: c.uri,
68
+ mimeType: c.mimeType,
69
+ text: c.text || '',
70
+ })),
71
+ };
72
+ });
73
+ }
74
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ResourceContext, ResourceResult } from '../types.js';
2
+ /**
3
+ * Handle plans://full/{planId} resource request.
4
+ * Returns complete plan content (lazy-loaded, only when explicitly requested).
5
+ *
6
+ * @param uri - Resource URI (should be 'plans://full/{planId}')
7
+ * @param context - Resource context
8
+ * @returns Resource result with full plan content
9
+ */
10
+ export declare function handlePlanFull(uri: string, context: ResourceContext): Promise<ResourceResult>;
11
+ //# sourceMappingURL=plans-full.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans-full.d.ts","sourceRoot":"","sources":["../../src/resources/plans-full.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnE;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAgEzB"}
@@ -0,0 +1,71 @@
1
+ import { existsSync, readFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ /**
4
+ * Handle plans://full/{planId} resource request.
5
+ * Returns complete plan content (lazy-loaded, only when explicitly requested).
6
+ *
7
+ * @param uri - Resource URI (should be 'plans://full/{planId}')
8
+ * @param context - Resource context
9
+ * @returns Resource result with full plan content
10
+ */
11
+ export async function handlePlanFull(uri, context) {
12
+ const { config } = context;
13
+ const plansPath = config.plansPath;
14
+ // Extract planId from URI (plans://full/{planId})
15
+ const match = uri.match(/^plans:\/\/full\/(.+)$/);
16
+ if (!match) {
17
+ return {
18
+ contents: [
19
+ {
20
+ uri,
21
+ mimeType: 'text/plain',
22
+ text: 'Invalid URI format',
23
+ },
24
+ ],
25
+ };
26
+ }
27
+ const planId = match[1];
28
+ const planPath = join(plansPath, planId);
29
+ const planMdPath = join(planPath, 'plan.md');
30
+ // Check if plan exists
31
+ if (!existsSync(planMdPath)) {
32
+ return {
33
+ contents: [
34
+ {
35
+ uri,
36
+ mimeType: 'text/plain',
37
+ text: `Plan not found: ${planId}`,
38
+ },
39
+ ],
40
+ };
41
+ }
42
+ try {
43
+ // Read plan content directly from file (UTF-8)
44
+ const content = readFileSync(planMdPath, 'utf-8');
45
+ // Large files may exceed MCP message size limits
46
+ // For now, we return the content as-is
47
+ // In production, might want to chunk or truncate very large files
48
+ return {
49
+ contents: [
50
+ {
51
+ uri,
52
+ mimeType: 'text/markdown',
53
+ text: content,
54
+ },
55
+ ],
56
+ };
57
+ }
58
+ catch (error) {
59
+ const errorMessage = error instanceof Error ? error.message : String(error);
60
+ return {
61
+ contents: [
62
+ {
63
+ uri,
64
+ mimeType: 'text/plain',
65
+ text: `Error reading plan: ${errorMessage}`,
66
+ },
67
+ ],
68
+ };
69
+ }
70
+ }
71
+ //# sourceMappingURL=plans-full.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans-full.js","sourceRoot":"","sources":["../../src/resources/plans-full.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAW,EACX,OAAwB;IAExB,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC3B,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IAEnC,kDAAkD;IAClD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG;oBACH,QAAQ,EAAE,YAAY;oBACtB,IAAI,EAAE,oBAAoB;iBAC3B;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE7C,uBAAuB;IACvB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG;oBACH,QAAQ,EAAE,YAAY;oBACtB,IAAI,EAAE,mBAAmB,MAAM,EAAE;iBAClC;aACF;SACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,+CAA+C;QAC/C,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAElD,iDAAiD;QACjD,uCAAuC;QACvC,kEAAkE;QAElE,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG;oBACH,QAAQ,EAAE,eAAe;oBACzB,IAAI,EAAE,OAAO;iBACd;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5E,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG;oBACH,QAAQ,EAAE,YAAY;oBACtB,IAAI,EAAE,uBAAuB,YAAY,EAAE;iBAC5C;aACF;SACF,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { ResourceContext, ResourceResult } from '../types.js';
2
+ /**
3
+ * Plan index entry interface.
4
+ */
5
+ export interface PlanIndexEntry {
6
+ id: string;
7
+ title: string;
8
+ status: 'GAP' | 'WIP' | 'PASS' | 'BLOCKED';
9
+ taskCount: number;
10
+ completedCount: number;
11
+ }
12
+ /**
13
+ * Plan index interface.
14
+ */
15
+ export interface PlanIndex {
16
+ plans: PlanIndexEntry[];
17
+ totalPlans: number;
18
+ totalTasks: number;
19
+ completedTasks: number;
20
+ }
21
+ /**
22
+ * Handle plans://index resource request.
23
+ * Returns lightweight index of all plans with status summary.
24
+ *
25
+ * @param uri - Resource URI (should be 'plans://index')
26
+ * @param context - Resource context
27
+ * @returns Resource result with plan index
28
+ */
29
+ export declare function handlePlansIndex(uri: string, context: ResourceContext): Promise<ResourceResult>;
30
+ //# sourceMappingURL=plans-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans-index.d.ts","sourceRoot":"","sources":["../../src/resources/plans-index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AA+GD;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAqGzB"}
@@ -0,0 +1,177 @@
1
+ import { existsSync, readdirSync } from 'fs';
2
+ import { join } from 'path';
3
+ /**
4
+ * Extract plan number from directory name.
5
+ * Handles both padded (0001-plan-name) and unpadded (1-plan-name) formats.
6
+ */
7
+ function extractPlanNumber(dirName) {
8
+ const match = dirName.match(/^0*(\d+)-/);
9
+ if (match) {
10
+ return parseInt(match[1], 10);
11
+ }
12
+ return null;
13
+ }
14
+ /**
15
+ * Parse YAML frontmatter from markdown content.
16
+ * Returns parsed frontmatter and remaining content.
17
+ */
18
+ function parseYamlFrontmatter(content) {
19
+ const yamlRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
20
+ const match = content.match(yamlRegex);
21
+ if (!match) {
22
+ return { frontmatter: {}, body: content };
23
+ }
24
+ const frontmatterText = match[1];
25
+ const body = match[2];
26
+ const frontmatter = {};
27
+ // Simple YAML parser for basic key-value pairs
28
+ const lines = frontmatterText.split('\n');
29
+ for (const line of lines) {
30
+ const trimmed = line.trim();
31
+ if (!trimmed || trimmed.startsWith('#'))
32
+ continue;
33
+ const colonIndex = trimmed.indexOf(':');
34
+ if (colonIndex === -1)
35
+ continue;
36
+ const key = trimmed.slice(0, colonIndex).trim();
37
+ let value = trimmed.slice(colonIndex + 1).trim();
38
+ // Remove quotes if present
39
+ if (typeof value === 'string') {
40
+ if ((value.startsWith('"') && value.endsWith('"')) ||
41
+ (value.startsWith("'") && value.endsWith("'"))) {
42
+ value = value.slice(1, -1);
43
+ }
44
+ }
45
+ if (key) {
46
+ frontmatter[key] = value;
47
+ }
48
+ }
49
+ return { frontmatter, body };
50
+ }
51
+ /**
52
+ * Get plan status from database content or default to GAP.
53
+ */
54
+ function getPlanStatus(db, planPath) {
55
+ const planMdPath = join(planPath, 'plan.md');
56
+ const result = db.prepare('SELECT content FROM documents WHERE path = ?').get(planMdPath);
57
+ if (result?.content) {
58
+ const { frontmatter } = parseYamlFrontmatter(result.content);
59
+ if (frontmatter.status && typeof frontmatter.status === 'string') {
60
+ const status = frontmatter.status;
61
+ if (['GAP', 'WIP', 'PASS', 'BLOCKED'].includes(status)) {
62
+ return status;
63
+ }
64
+ }
65
+ }
66
+ return 'GAP';
67
+ }
68
+ /**
69
+ * Count tasks in a plan by scanning agent files.
70
+ */
71
+ function countTasks(planPath) {
72
+ const agentsDir = join(planPath, 'agents');
73
+ if (!existsSync(agentsDir)) {
74
+ return { total: 0, completed: 0 };
75
+ }
76
+ const files = readdirSync(agentsDir, { withFileTypes: true })
77
+ .filter((dirent) => dirent.isFile() && dirent.name.endsWith('.agent.md'))
78
+ .map((dirent) => dirent.name);
79
+ const total = files.length;
80
+ const completedDir = join(agentsDir, 'completed');
81
+ const completed = existsSync(completedDir)
82
+ ? readdirSync(completedDir, { withFileTypes: true }).filter((dirent) => dirent.isFile() && dirent.name.endsWith('.agent.md')).length
83
+ : 0;
84
+ return { total, completed };
85
+ }
86
+ /**
87
+ * Handle plans://index resource request.
88
+ * Returns lightweight index of all plans with status summary.
89
+ *
90
+ * @param uri - Resource URI (should be 'plans://index')
91
+ * @param context - Resource context
92
+ * @returns Resource result with plan index
93
+ */
94
+ export async function handlePlansIndex(uri, context) {
95
+ const { db, config } = context;
96
+ const plansPath = config.plansPath;
97
+ if (!existsSync(plansPath)) {
98
+ return {
99
+ contents: [
100
+ {
101
+ uri,
102
+ mimeType: 'application/json',
103
+ text: JSON.stringify({
104
+ plans: [],
105
+ totalPlans: 0,
106
+ totalTasks: 0,
107
+ completedTasks: 0,
108
+ }),
109
+ },
110
+ ],
111
+ };
112
+ }
113
+ const dirs = readdirSync(plansPath, { withFileTypes: true })
114
+ .filter((dirent) => dirent.isDirectory())
115
+ .map((dirent) => dirent.name);
116
+ const planEntries = [];
117
+ let totalTasks = 0;
118
+ let completedTasks = 0;
119
+ for (const dir of dirs) {
120
+ const planNumber = extractPlanNumber(dir);
121
+ if (planNumber === null) {
122
+ continue; // Skip directories that don't match plan number pattern
123
+ }
124
+ const planPath = join(plansPath, dir);
125
+ const planMdPath = join(planPath, 'plan.md');
126
+ // Check if plan.md exists
127
+ if (!existsSync(planMdPath)) {
128
+ continue;
129
+ }
130
+ // Get plan title from database
131
+ const docResult = db.prepare('SELECT title FROM documents WHERE path = ?').get(planMdPath);
132
+ const title = docResult?.title || dir;
133
+ const status = getPlanStatus(db, planPath);
134
+ const { total, completed } = countTasks(planPath);
135
+ planEntries.push({
136
+ id: dir,
137
+ title,
138
+ status,
139
+ taskCount: total,
140
+ completedCount: completed,
141
+ });
142
+ totalTasks += total;
143
+ completedTasks += completed;
144
+ }
145
+ // Sort by plan number (numerically)
146
+ planEntries.sort((a, b) => {
147
+ const numA = extractPlanNumber(a.id) ?? 0;
148
+ const numB = extractPlanNumber(b.id) ?? 0;
149
+ return numA - numB;
150
+ });
151
+ const index = {
152
+ plans: planEntries,
153
+ totalPlans: planEntries.length,
154
+ totalTasks,
155
+ completedTasks,
156
+ };
157
+ // Approximate token count (character count / 4)
158
+ const jsonText = JSON.stringify(index);
159
+ const tokenCount = Math.ceil(jsonText.length / 4);
160
+ // If token count exceeds ~100 tokens, truncate plans list
161
+ // This is a lightweight index, so we want to keep it small
162
+ if (tokenCount > 100) {
163
+ // Keep only first N plans to stay under limit
164
+ const maxPlans = Math.floor((100 * 4) / (jsonText.length / planEntries.length));
165
+ index.plans = planEntries.slice(0, Math.max(1, maxPlans));
166
+ }
167
+ return {
168
+ contents: [
169
+ {
170
+ uri,
171
+ mimeType: 'application/json',
172
+ text: JSON.stringify(index),
173
+ },
174
+ ],
175
+ };
176
+ }
177
+ //# sourceMappingURL=plans-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans-index.js","sourceRoot":"","sources":["../../src/resources/plans-index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { ResourceContext, ResourceResult } from '../types.js';
2
+ /**
3
+ * Plan summary interface.
4
+ */
5
+ export interface PlanSummary {
6
+ id: string;
7
+ title: string;
8
+ description: string;
9
+ status: 'GAP' | 'WIP' | 'PASS' | 'BLOCKED';
10
+ tasks: {
11
+ id: string;
12
+ title: string;
13
+ status: 'GAP' | 'WIP' | 'PASS' | 'BLOCKED';
14
+ }[];
15
+ dependencies: string[];
16
+ nextAction: string;
17
+ taskCounts: {
18
+ GAP: number;
19
+ WIP: number;
20
+ PASS: number;
21
+ BLOCKED: number;
22
+ };
23
+ }
24
+ /**
25
+ * Handle plans://summary/{planId} resource request.
26
+ * Returns plan summary with task counts, status rollup, and dependencies.
27
+ *
28
+ * @param uri - Resource URI (should be 'plans://summary/{planId}')
29
+ * @param context - Resource context
30
+ * @returns Resource result with plan summary
31
+ */
32
+ export declare function handlePlanSummary(uri: string, context: ResourceContext): Promise<ResourceResult>;
33
+ //# sourceMappingURL=plans-summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans-summary.d.ts","sourceRoot":"","sources":["../../src/resources/plans-summary.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;IAC3C,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;KAC5C,EAAE,CAAC;IACJ,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE;QACV,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAgMD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAiGzB"}