@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,238 @@
1
+ import { existsSync, readFileSync, readdirSync } from 'fs';
2
+ import { join } from 'path';
3
+ /**
4
+ * Parse YAML frontmatter from markdown content.
5
+ */
6
+ function parseYamlFrontmatter(content) {
7
+ const yamlRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
8
+ const match = content.match(yamlRegex);
9
+ if (!match) {
10
+ return { frontmatter: {}, body: content };
11
+ }
12
+ const frontmatterText = match[1];
13
+ const body = match[2];
14
+ const frontmatter = {};
15
+ const lines = frontmatterText.split('\n');
16
+ for (const line of lines) {
17
+ const trimmed = line.trim();
18
+ if (!trimmed || trimmed.startsWith('#'))
19
+ continue;
20
+ const colonIndex = trimmed.indexOf(':');
21
+ if (colonIndex === -1)
22
+ continue;
23
+ const key = trimmed.slice(0, colonIndex).trim();
24
+ let value = trimmed.slice(colonIndex + 1).trim();
25
+ if (typeof value === 'string') {
26
+ if ((value.startsWith('"') && value.endsWith('"')) ||
27
+ (value.startsWith("'") && value.endsWith("'"))) {
28
+ value = value.slice(1, -1);
29
+ }
30
+ }
31
+ if (key) {
32
+ frontmatter[key] = value;
33
+ }
34
+ }
35
+ return { frontmatter, body };
36
+ }
37
+ /**
38
+ * Extract description from markdown content (first paragraph after title).
39
+ */
40
+ function extractDescription(content) {
41
+ // Remove frontmatter if present
42
+ const { body } = parseYamlFrontmatter(content);
43
+ // Remove title (first H1)
44
+ const withoutTitle = body.replace(/^#\s+.+$/m, '').trim();
45
+ // Get first paragraph (non-empty line)
46
+ const lines = withoutTitle.split('\n');
47
+ for (const line of lines) {
48
+ const trimmed = line.trim();
49
+ if (trimmed &&
50
+ !trimmed.startsWith('#') &&
51
+ !trimmed.startsWith('*') &&
52
+ !trimmed.startsWith('-')) {
53
+ return trimmed.substring(0, 200); // Limit to ~200 chars
54
+ }
55
+ }
56
+ return '';
57
+ }
58
+ /**
59
+ * Extract task information from agent files.
60
+ */
61
+ function extractTasks(planPath) {
62
+ const agentsDir = join(planPath, 'agents');
63
+ if (!existsSync(agentsDir)) {
64
+ return [];
65
+ }
66
+ const tasks = [];
67
+ // Check completed directory
68
+ const completedDir = join(agentsDir, 'completed');
69
+ const completedFiles = existsSync(completedDir)
70
+ ? readdirSync(completedDir, { withFileTypes: true })
71
+ .filter((dirent) => dirent.isFile() && dirent.name.endsWith('.agent.md'))
72
+ .map((dirent) => dirent.name)
73
+ : [];
74
+ // Check main agents directory
75
+ const agentFiles = readdirSync(agentsDir, { withFileTypes: true })
76
+ .filter((dirent) => dirent.isFile() && dirent.name.endsWith('.agent.md'))
77
+ .map((dirent) => dirent.name);
78
+ for (const file of agentFiles) {
79
+ const filePath = join(agentsDir, file);
80
+ const content = readFileSync(filePath, 'utf-8');
81
+ // Extract title from first H1 or filename
82
+ const h1Match = content.match(/^#\s+(.+)$/m);
83
+ const title = h1Match ? h1Match[1].trim() : file.replace('.agent.md', '');
84
+ // Extract status from content (look for "Status: GAP/WIP/PASS/BLOCKED")
85
+ const statusMatch = content.match(/Status:\s*(GAP|WIP|PASS|BLOCKED)/i);
86
+ const status = (statusMatch ? statusMatch[1].toUpperCase() : 'GAP');
87
+ tasks.push({
88
+ id: file.replace('.agent.md', ''),
89
+ title,
90
+ status: completedFiles.includes(file) ? 'PASS' : status,
91
+ });
92
+ }
93
+ // Add completed tasks
94
+ for (const file of completedFiles) {
95
+ if (!agentFiles.includes(file)) {
96
+ const filePath = join(completedDir, file);
97
+ const content = readFileSync(filePath, 'utf-8');
98
+ const h1Match = content.match(/^#\s+(.+)$/m);
99
+ const title = h1Match ? h1Match[1].trim() : file.replace('.agent.md', '');
100
+ tasks.push({
101
+ id: file.replace('.agent.md', ''),
102
+ title,
103
+ status: 'PASS',
104
+ });
105
+ }
106
+ }
107
+ return tasks;
108
+ }
109
+ /**
110
+ * Extract dependencies from markdown content.
111
+ */
112
+ function extractDependencies(content, frontmatter) {
113
+ const deps = [];
114
+ // Check frontmatter
115
+ if (frontmatter.dependencies) {
116
+ if (Array.isArray(frontmatter.dependencies)) {
117
+ deps.push(...frontmatter.dependencies.map((d) => String(d)));
118
+ }
119
+ else if (typeof frontmatter.dependencies === 'string') {
120
+ deps.push(frontmatter.dependencies);
121
+ }
122
+ }
123
+ // Extract from content: #1, #2, feature-1, etc.
124
+ const featureRefRegex = /#(\d+)|feature[_-]?(\d+)/gi;
125
+ const matches = content.matchAll(featureRefRegex);
126
+ for (const match of matches) {
127
+ if (match[1]) {
128
+ deps.push(`#${match[1]}`);
129
+ }
130
+ else if (match[2]) {
131
+ deps.push(`feature-${match[2]}`);
132
+ }
133
+ }
134
+ return Array.from(new Set(deps));
135
+ }
136
+ /**
137
+ * Get next action from first GAP task.
138
+ */
139
+ function getNextAction(tasks) {
140
+ const gapTask = tasks.find((t) => t.status === 'GAP');
141
+ if (gapTask) {
142
+ return `Work on ${gapTask.title} (${gapTask.id})`;
143
+ }
144
+ const wipTask = tasks.find((t) => t.status === 'WIP');
145
+ if (wipTask) {
146
+ return `Continue ${wipTask.title} (${wipTask.id})`;
147
+ }
148
+ return 'All tasks complete';
149
+ }
150
+ /**
151
+ * Handle plans://summary/{planId} resource request.
152
+ * Returns plan summary with task counts, status rollup, and dependencies.
153
+ *
154
+ * @param uri - Resource URI (should be 'plans://summary/{planId}')
155
+ * @param context - Resource context
156
+ * @returns Resource result with plan summary
157
+ */
158
+ export async function handlePlanSummary(uri, context) {
159
+ const { db, config } = context;
160
+ const plansPath = config.plansPath;
161
+ // Extract planId from URI (plans://summary/{planId})
162
+ const match = uri.match(/^plans:\/\/summary\/(.+)$/);
163
+ if (!match) {
164
+ return {
165
+ contents: [
166
+ {
167
+ uri,
168
+ mimeType: 'application/json',
169
+ text: JSON.stringify({ error: 'Invalid URI format' }),
170
+ },
171
+ ],
172
+ };
173
+ }
174
+ const planId = match[1];
175
+ const planPath = join(plansPath, planId);
176
+ const planMdPath = join(planPath, 'plan.md');
177
+ // Check if plan exists
178
+ if (!existsSync(planMdPath)) {
179
+ return {
180
+ contents: [
181
+ {
182
+ uri,
183
+ mimeType: 'application/json',
184
+ text: JSON.stringify({ error: 'Plan not found', planId }),
185
+ },
186
+ ],
187
+ };
188
+ }
189
+ // Get plan content from database
190
+ const docResult = db
191
+ .prepare('SELECT title, content FROM documents WHERE path = ?')
192
+ .get(planMdPath);
193
+ if (!docResult) {
194
+ return {
195
+ contents: [
196
+ {
197
+ uri,
198
+ mimeType: 'application/json',
199
+ text: JSON.stringify({ error: 'Plan not indexed', planId }),
200
+ },
201
+ ],
202
+ };
203
+ }
204
+ const { frontmatter } = parseYamlFrontmatter(docResult.content);
205
+ const status = (frontmatter.status && typeof frontmatter.status === 'string' ? frontmatter.status : 'GAP');
206
+ const title = docResult.title;
207
+ const description = extractDescription(docResult.content);
208
+ const dependencies = extractDependencies(docResult.content, frontmatter);
209
+ const tasks = extractTasks(planPath);
210
+ // Count tasks by status
211
+ const taskCounts = {
212
+ GAP: tasks.filter((t) => t.status === 'GAP').length,
213
+ WIP: tasks.filter((t) => t.status === 'WIP').length,
214
+ PASS: tasks.filter((t) => t.status === 'PASS').length,
215
+ BLOCKED: tasks.filter((t) => t.status === 'BLOCKED').length,
216
+ };
217
+ const nextAction = getNextAction(tasks);
218
+ const summary = {
219
+ id: planId,
220
+ title,
221
+ description,
222
+ status,
223
+ tasks,
224
+ dependencies,
225
+ nextAction,
226
+ taskCounts,
227
+ };
228
+ return {
229
+ contents: [
230
+ {
231
+ uri,
232
+ mimeType: 'application/json',
233
+ text: JSON.stringify(summary),
234
+ },
235
+ ],
236
+ };
237
+ }
238
+ //# sourceMappingURL=plans-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans-summary.js","sourceRoot":"","sources":["../../src/resources/plans-summary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Lower-level parsing utilities for document extraction.
3
+ * Feature #3: Built-in Helper Functions (extractors layer)
4
+ *
5
+ * These are pure functions used by helpers.ts for parsing markdown, YAML, and Gherkin.
6
+ */
7
+ /**
8
+ * Parse markdown headers from content.
9
+ * Returns array of headers with level (1-6), text, and line number (1-indexed).
10
+ *
11
+ * @param content - Markdown content
12
+ * @returns Array of header objects
13
+ */
14
+ export declare function parseMarkdownHeaders(content: string): {
15
+ level: number;
16
+ text: string;
17
+ line: number;
18
+ }[];
19
+ /**
20
+ * Parse YAML frontmatter from content.
21
+ * Frontmatter must be at the very start of the file (no leading whitespace).
22
+ * Returns parsed YAML object or null if no valid frontmatter found.
23
+ *
24
+ * @param content - Content with optional YAML frontmatter
25
+ * @returns Parsed YAML object or null
26
+ */
27
+ export declare function parseYamlFrontmatter(content: string): Record<string, unknown> | null;
28
+ /**
29
+ * Parse Gherkin scenarios from content.
30
+ * Returns array of scenarios with name and steps array.
31
+ *
32
+ * @param content - Content containing Gherkin scenarios
33
+ * @returns Array of scenario objects
34
+ */
35
+ export declare function parseGherkinScenarios(content: string): {
36
+ name: string;
37
+ steps: string[];
38
+ }[];
39
+ //# sourceMappingURL=extractors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractors.d.ts","sourceRoot":"","sources":["../../src/rlm/extractors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,GACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAoBjD;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAsCpF;AAoMD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,CA6C1F"}
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Lower-level parsing utilities for document extraction.
3
+ * Feature #3: Built-in Helper Functions (extractors layer)
4
+ *
5
+ * These are pure functions used by helpers.ts for parsing markdown, YAML, and Gherkin.
6
+ */
7
+ /**
8
+ * Parse markdown headers from content.
9
+ * Returns array of headers with level (1-6), text, and line number (1-indexed).
10
+ *
11
+ * @param content - Markdown content
12
+ * @returns Array of header objects
13
+ */
14
+ export function parseMarkdownHeaders(content) {
15
+ const headers = [];
16
+ const lines = content.split('\n');
17
+ for (let i = 0; i < lines.length; i++) {
18
+ const line = lines[i];
19
+ const match = line.match(/^(#{1,6})\s+(.+)$/);
20
+ if (match) {
21
+ const level = match[1].length;
22
+ const text = match[2].trim();
23
+ headers.push({
24
+ level,
25
+ text,
26
+ line: i + 1, // 1-indexed
27
+ });
28
+ }
29
+ }
30
+ return headers;
31
+ }
32
+ /**
33
+ * Parse YAML frontmatter from content.
34
+ * Frontmatter must be at the very start of the file (no leading whitespace).
35
+ * Returns parsed YAML object or null if no valid frontmatter found.
36
+ *
37
+ * @param content - Content with optional YAML frontmatter
38
+ * @returns Parsed YAML object or null
39
+ */
40
+ export function parseYamlFrontmatter(content) {
41
+ // Frontmatter must be at very start (no leading whitespace)
42
+ if (!content.startsWith('---\n')) {
43
+ return null;
44
+ }
45
+ // Find the closing ---
46
+ // Look for \n---\n (most common case) or ---\n at start (empty frontmatter)
47
+ let endIndex = content.indexOf('\n---\n', 4); // Start search after first ---\n
48
+ // If not found, check if the next thing is ---\n (empty frontmatter case)
49
+ if (endIndex === -1) {
50
+ if (content.slice(4, 8) === '---\n') {
51
+ // Empty frontmatter: ---\n---\n
52
+ endIndex = 4; // The second --- starts at index 4
53
+ }
54
+ else {
55
+ return null; // No closing delimiter
56
+ }
57
+ }
58
+ else {
59
+ // Found \n---\n, so the actual --- starts at endIndex + 1
60
+ endIndex = endIndex + 1; // Adjust to point to the start of ---
61
+ }
62
+ // Extract YAML content (between first ---\n and second ---\n)
63
+ const yamlContent = content.slice(4, endIndex); // Skip "---\n"
64
+ // Handle empty frontmatter
65
+ if (yamlContent.trim() === '') {
66
+ return {};
67
+ }
68
+ // Simple YAML parser for common cases
69
+ // For production, consider using a YAML library, but for now we'll do basic parsing
70
+ try {
71
+ return parseSimpleYaml(yamlContent);
72
+ }
73
+ catch {
74
+ return null;
75
+ }
76
+ }
77
+ /**
78
+ * Simple YAML parser for frontmatter.
79
+ * Handles key-value pairs, nested objects, arrays, and multiline strings.
80
+ * This is a simplified parser - for complex YAML, consider using a library.
81
+ */
82
+ function parseSimpleYaml(yaml) {
83
+ const trimmedYaml = yaml.trim();
84
+ // Handle empty frontmatter
85
+ if (trimmedYaml === '') {
86
+ return {};
87
+ }
88
+ const result = {};
89
+ const lines = yaml.split('\n');
90
+ const stack = [
91
+ { obj: result, indent: -1 },
92
+ ];
93
+ let i = 0;
94
+ while (i < lines.length) {
95
+ const line = lines[i];
96
+ const trimmed = line.trim();
97
+ // Skip empty lines
98
+ if (trimmed === '') {
99
+ i++;
100
+ continue;
101
+ }
102
+ // Calculate indentation
103
+ const indent = line.length - line.trimStart().length;
104
+ // Pop stack until we find the right parent
105
+ while (stack.length > 1 && indent <= stack[stack.length - 1].indent) {
106
+ stack.pop();
107
+ }
108
+ const current = stack[stack.length - 1];
109
+ // Check for multiline string (| or >)
110
+ if (trimmed.endsWith('|') || trimmed.endsWith('>')) {
111
+ const keyMatch = trimmed.match(/^([^:]+):\s*([|>])$/);
112
+ if (keyMatch) {
113
+ const key = keyMatch[1].trim();
114
+ const multilineType = keyMatch[2];
115
+ const multilineContent = [];
116
+ i++;
117
+ // Collect multiline content
118
+ while (i < lines.length) {
119
+ const nextLine = lines[i];
120
+ const nextIndent = nextLine.length - nextLine.trimStart().length;
121
+ const nextTrimmed = nextLine.trim();
122
+ // Stop if we hit a line with same or less indentation (not part of multiline)
123
+ if (nextIndent <= indent && nextTrimmed !== '') {
124
+ break;
125
+ }
126
+ // For | (literal), preserve newlines; for > (folded), fold newlines
127
+ if (multilineType === '|') {
128
+ // Preserve the line content, removing the indentation
129
+ if (nextIndent > indent) {
130
+ // Remove the base indentation (key's indent level)
131
+ const baseIndent = indent + 2; // Key is at indent, content is at indent+2
132
+ const contentLine = nextLine.slice(baseIndent);
133
+ multilineContent.push(contentLine);
134
+ }
135
+ else if (nextTrimmed === '') {
136
+ // Empty line in literal block
137
+ multilineContent.push('');
138
+ }
139
+ }
140
+ else {
141
+ // Folded: replace newlines with spaces, but preserve paragraph breaks
142
+ if (nextTrimmed === '') {
143
+ multilineContent.push('\n');
144
+ }
145
+ else {
146
+ multilineContent.push(nextTrimmed + ' ');
147
+ }
148
+ }
149
+ i++;
150
+ }
151
+ // For literal (|), join with newlines
152
+ // YAML spec: literal blocks preserve newlines and add a final newline
153
+ let finalContent = multilineType === '|' ? multilineContent.join('\n') : multilineContent.join('').trim();
154
+ // For literal blocks, ensure there's a trailing newline (YAML spec)
155
+ if (multilineType === '|' && !finalContent.endsWith('\n')) {
156
+ finalContent += '\n';
157
+ }
158
+ current.obj[key] = finalContent;
159
+ continue;
160
+ }
161
+ }
162
+ // Check for array item
163
+ if (trimmed.startsWith('- ')) {
164
+ const value = trimmed.slice(2).trim();
165
+ // Find the array - look for the most recent key in stack that has an array
166
+ let arrayFound = false;
167
+ for (let j = stack.length - 1; j >= 0; j--) {
168
+ const stackItem = stack[j];
169
+ if (stackItem.key && Array.isArray(stackItem.obj[stackItem.key])) {
170
+ stackItem.obj[stackItem.key].push(parseValue(value));
171
+ arrayFound = true;
172
+ break;
173
+ }
174
+ }
175
+ // If no array found, this shouldn't happen in valid YAML, but handle gracefully
176
+ if (!arrayFound) {
177
+ // This is a malformed YAML - skip it
178
+ }
179
+ i++;
180
+ continue;
181
+ }
182
+ // Regular key-value pair
183
+ const colonIndex = trimmed.indexOf(':');
184
+ if (colonIndex === -1) {
185
+ i++;
186
+ continue;
187
+ }
188
+ const key = trimmed.slice(0, colonIndex).trim();
189
+ const valueStr = trimmed.slice(colonIndex + 1).trim();
190
+ // Check if this starts a nested object
191
+ if (valueStr === '' && i + 1 < lines.length) {
192
+ const nextLine = lines[i + 1];
193
+ const nextIndent = nextLine.length - nextLine.trimStart().length;
194
+ const nextTrimmed = nextLine.trim();
195
+ if (nextIndent > indent) {
196
+ // Check if next line is an array item
197
+ if (nextTrimmed.startsWith('- ')) {
198
+ // This is an array
199
+ const array = [];
200
+ current.obj[key] = array;
201
+ // Push a stack entry that tracks this array
202
+ stack.push({ obj: current.obj, indent: indent, key: key });
203
+ i++;
204
+ continue;
205
+ }
206
+ else {
207
+ // This is a nested object
208
+ const nestedObj = {};
209
+ current.obj[key] = nestedObj;
210
+ stack.push({ obj: nestedObj, indent: indent });
211
+ i++;
212
+ continue;
213
+ }
214
+ }
215
+ }
216
+ current.obj[key] = parseValue(valueStr);
217
+ i++;
218
+ }
219
+ return result;
220
+ }
221
+ /**
222
+ * Parse a YAML value string into appropriate JavaScript type.
223
+ */
224
+ function parseValue(value) {
225
+ const trimmed = value.trim();
226
+ // Boolean
227
+ if (trimmed === 'true')
228
+ return true;
229
+ if (trimmed === 'false')
230
+ return false;
231
+ // Null
232
+ if (trimmed === 'null' || trimmed === '~')
233
+ return null;
234
+ // Number
235
+ if (/^-?\d+$/.test(trimmed))
236
+ return parseInt(trimmed, 10);
237
+ if (/^-?\d+\.\d+$/.test(trimmed))
238
+ return parseFloat(trimmed);
239
+ // String (remove quotes if present)
240
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
241
+ (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
242
+ return trimmed.slice(1, -1);
243
+ }
244
+ return trimmed;
245
+ }
246
+ /**
247
+ * Parse Gherkin scenarios from content.
248
+ * Returns array of scenarios with name and steps array.
249
+ *
250
+ * @param content - Content containing Gherkin scenarios
251
+ * @returns Array of scenario objects
252
+ */
253
+ export function parseGherkinScenarios(content) {
254
+ const scenarios = [];
255
+ const lines = content.split('\n');
256
+ let currentScenario = null;
257
+ for (const line of lines) {
258
+ const trimmed = line.trim();
259
+ // Check for Scenario: line
260
+ const scenarioMatch = trimmed.match(/^Scenario:\s*(.+)$/i);
261
+ if (scenarioMatch) {
262
+ // Save previous scenario if exists
263
+ if (currentScenario) {
264
+ scenarios.push(currentScenario);
265
+ }
266
+ // Start new scenario
267
+ currentScenario = {
268
+ name: scenarioMatch[1].trim(),
269
+ steps: [],
270
+ };
271
+ continue;
272
+ }
273
+ // Check for step keywords (Given, When, Then, And, But)
274
+ const stepMatch = trimmed.match(/^(Given|When|Then|And|But)\s+(.+)$/i);
275
+ if (stepMatch) {
276
+ if (currentScenario) {
277
+ currentScenario.steps.push(trimmed);
278
+ }
279
+ continue;
280
+ }
281
+ // If we have a scenario and this line is not empty and not a step,
282
+ // it might be part of a step continuation (for now, we ignore it)
283
+ // In a full Gherkin parser, we'd handle step continuations
284
+ }
285
+ // Don't forget the last scenario
286
+ if (currentScenario) {
287
+ scenarios.push(currentScenario);
288
+ }
289
+ return scenarios;
290
+ }
291
+ //# sourceMappingURL=extractors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractors.js","sourceRoot":"","sources":["../../src/rlm/extractors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Serialized JavaScript code for helper and extractor functions.
3
+ * This code is injected into the QuickJS sandbox environment.
4
+ *
5
+ * These are pure JavaScript versions of the helpers and extractors,
6
+ * without TypeScript types or imports.
7
+ */
8
+ /**
9
+ * Get the JavaScript code to inject into the sandbox.
10
+ * This includes all helper and extractor functions.
11
+ */
12
+ export declare function getHelpersCode(): string;
13
+ //# sourceMappingURL=helpers-inject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers-inject.d.ts","sourceRoot":"","sources":["../../src/rlm/helpers-inject.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CA6jBvC"}