@agntk/agent-harness 0.1.1

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/LICENSE +21 -0
  2. package/NOTICE +41 -0
  3. package/README.md +445 -0
  4. package/defaults/agents/summarizer.md +49 -0
  5. package/defaults/instincts/lead-with-answer.md +24 -0
  6. package/defaults/instincts/qualify-before-recommending.md +40 -0
  7. package/defaults/instincts/read-before-edit.md +23 -0
  8. package/defaults/instincts/search-before-create.md +23 -0
  9. package/defaults/playbooks/ship-feature.md +31 -0
  10. package/defaults/rules/ask-before-assuming.md +35 -0
  11. package/defaults/rules/operations.md +35 -0
  12. package/defaults/rules/respect-the-user.md +39 -0
  13. package/defaults/skills/business-analyst.md +181 -0
  14. package/defaults/skills/content-marketer.md +184 -0
  15. package/defaults/skills/research.md +34 -0
  16. package/defaults/tools/example-web-search.md +60 -0
  17. package/defaults/workflows/daily-reflection.md +54 -0
  18. package/dist/agent-framework-K4GUIICH.js +344 -0
  19. package/dist/agent-framework-K4GUIICH.js.map +1 -0
  20. package/dist/analytics-RPT73WNM.js +12 -0
  21. package/dist/analytics-RPT73WNM.js.map +1 -0
  22. package/dist/auto-processor-OLE45UI3.js +13 -0
  23. package/dist/auto-processor-OLE45UI3.js.map +1 -0
  24. package/dist/chunk-274RV3YO.js +162 -0
  25. package/dist/chunk-274RV3YO.js.map +1 -0
  26. package/dist/chunk-4CWAGBNS.js +168 -0
  27. package/dist/chunk-4CWAGBNS.js.map +1 -0
  28. package/dist/chunk-4FDUOGSZ.js +69 -0
  29. package/dist/chunk-4FDUOGSZ.js.map +1 -0
  30. package/dist/chunk-5H34JPMB.js +199 -0
  31. package/dist/chunk-5H34JPMB.js.map +1 -0
  32. package/dist/chunk-6EMOEYGU.js +102 -0
  33. package/dist/chunk-6EMOEYGU.js.map +1 -0
  34. package/dist/chunk-A7BJPQQ6.js +236 -0
  35. package/dist/chunk-A7BJPQQ6.js.map +1 -0
  36. package/dist/chunk-AGAAFJEO.js +76 -0
  37. package/dist/chunk-AGAAFJEO.js.map +1 -0
  38. package/dist/chunk-BSKDOFRT.js +65 -0
  39. package/dist/chunk-BSKDOFRT.js.map +1 -0
  40. package/dist/chunk-CHJ5GNZC.js +100 -0
  41. package/dist/chunk-CHJ5GNZC.js.map +1 -0
  42. package/dist/chunk-CSL3ERUI.js +307 -0
  43. package/dist/chunk-CSL3ERUI.js.map +1 -0
  44. package/dist/chunk-DA7IKHC4.js +229 -0
  45. package/dist/chunk-DA7IKHC4.js.map +1 -0
  46. package/dist/chunk-DGUM43GV.js +11 -0
  47. package/dist/chunk-DGUM43GV.js.map +1 -0
  48. package/dist/chunk-DTTXPHFW.js +211 -0
  49. package/dist/chunk-DTTXPHFW.js.map +1 -0
  50. package/dist/chunk-FD55B3IO.js +204 -0
  51. package/dist/chunk-FD55B3IO.js.map +1 -0
  52. package/dist/chunk-FLZU44SV.js +230 -0
  53. package/dist/chunk-FLZU44SV.js.map +1 -0
  54. package/dist/chunk-GJNNR2RA.js +200 -0
  55. package/dist/chunk-GJNNR2RA.js.map +1 -0
  56. package/dist/chunk-GNUSHD2Y.js +111 -0
  57. package/dist/chunk-GNUSHD2Y.js.map +1 -0
  58. package/dist/chunk-GUJTBGVS.js +2212 -0
  59. package/dist/chunk-GUJTBGVS.js.map +1 -0
  60. package/dist/chunk-IZ6UZ3ZL.js +207 -0
  61. package/dist/chunk-IZ6UZ3ZL.js.map +1 -0
  62. package/dist/chunk-JKMGYWXB.js +197 -0
  63. package/dist/chunk-JKMGYWXB.js.map +1 -0
  64. package/dist/chunk-KFX54TQM.js +165 -0
  65. package/dist/chunk-KFX54TQM.js.map +1 -0
  66. package/dist/chunk-M7NXUK55.js +199 -0
  67. package/dist/chunk-M7NXUK55.js.map +1 -0
  68. package/dist/chunk-MPZ3BPUI.js +374 -0
  69. package/dist/chunk-MPZ3BPUI.js.map +1 -0
  70. package/dist/chunk-OC6YSTDX.js +119 -0
  71. package/dist/chunk-OC6YSTDX.js.map +1 -0
  72. package/dist/chunk-RC6MEZB6.js +469 -0
  73. package/dist/chunk-RC6MEZB6.js.map +1 -0
  74. package/dist/chunk-RY3ZFII7.js +3440 -0
  75. package/dist/chunk-RY3ZFII7.js.map +1 -0
  76. package/dist/chunk-TAT6JU3X.js +167 -0
  77. package/dist/chunk-TAT6JU3X.js.map +1 -0
  78. package/dist/chunk-UDZIS2AQ.js +79 -0
  79. package/dist/chunk-UDZIS2AQ.js.map +1 -0
  80. package/dist/chunk-UPLBF4RZ.js +115 -0
  81. package/dist/chunk-UPLBF4RZ.js.map +1 -0
  82. package/dist/chunk-UWQTZMNI.js +154 -0
  83. package/dist/chunk-UWQTZMNI.js.map +1 -0
  84. package/dist/chunk-W4T7PGI2.js +346 -0
  85. package/dist/chunk-W4T7PGI2.js.map +1 -0
  86. package/dist/chunk-XTBKL5BI.js +111 -0
  87. package/dist/chunk-XTBKL5BI.js.map +1 -0
  88. package/dist/chunk-YIJY5DBV.js +399 -0
  89. package/dist/chunk-YIJY5DBV.js.map +1 -0
  90. package/dist/chunk-YUFNYN2H.js +242 -0
  91. package/dist/chunk-YUFNYN2H.js.map +1 -0
  92. package/dist/chunk-Z2PUCXTZ.js +94 -0
  93. package/dist/chunk-Z2PUCXTZ.js.map +1 -0
  94. package/dist/chunk-ZZJOFKAT.js +13 -0
  95. package/dist/chunk-ZZJOFKAT.js.map +1 -0
  96. package/dist/cli/index.js +3661 -0
  97. package/dist/cli/index.js.map +1 -0
  98. package/dist/config-WVMRUOCA.js +13 -0
  99. package/dist/config-WVMRUOCA.js.map +1 -0
  100. package/dist/context-loader-3ORBPMHJ.js +13 -0
  101. package/dist/context-loader-3ORBPMHJ.js.map +1 -0
  102. package/dist/conversation-QDEIDQPH.js +22 -0
  103. package/dist/conversation-QDEIDQPH.js.map +1 -0
  104. package/dist/cost-tracker-RS3W7SVY.js +24 -0
  105. package/dist/cost-tracker-RS3W7SVY.js.map +1 -0
  106. package/dist/delegate-VJCJLYEK.js +29 -0
  107. package/dist/delegate-VJCJLYEK.js.map +1 -0
  108. package/dist/emotional-state-VQVRA6ED.js +206 -0
  109. package/dist/emotional-state-VQVRA6ED.js.map +1 -0
  110. package/dist/env-discovery-2BLVMAIM.js +251 -0
  111. package/dist/env-discovery-2BLVMAIM.js.map +1 -0
  112. package/dist/export-6GCYHEHQ.js +165 -0
  113. package/dist/export-6GCYHEHQ.js.map +1 -0
  114. package/dist/graph-YUIPOSOO.js +14 -0
  115. package/dist/graph-YUIPOSOO.js.map +1 -0
  116. package/dist/harness-LCHA3DWP.js +10 -0
  117. package/dist/harness-LCHA3DWP.js.map +1 -0
  118. package/dist/harness-WE4SLCML.js +26 -0
  119. package/dist/harness-WE4SLCML.js.map +1 -0
  120. package/dist/health-NZ6WNIMV.js +23 -0
  121. package/dist/health-NZ6WNIMV.js.map +1 -0
  122. package/dist/index.d.ts +3612 -0
  123. package/dist/index.js +13501 -0
  124. package/dist/index.js.map +1 -0
  125. package/dist/indexer-LONANRRM.js +16 -0
  126. package/dist/indexer-LONANRRM.js.map +1 -0
  127. package/dist/instinct-learner-SRM72DHF.js +20 -0
  128. package/dist/instinct-learner-SRM72DHF.js.map +1 -0
  129. package/dist/intake-4M3HNU43.js +21 -0
  130. package/dist/intake-4M3HNU43.js.map +1 -0
  131. package/dist/intelligence-HJOCA4SJ.js +1081 -0
  132. package/dist/intelligence-HJOCA4SJ.js.map +1 -0
  133. package/dist/journal-WANJL3MI.js +24 -0
  134. package/dist/journal-WANJL3MI.js.map +1 -0
  135. package/dist/loader-C3TKIKZR.js +23 -0
  136. package/dist/loader-C3TKIKZR.js.map +1 -0
  137. package/dist/mcp-WTQJJZAO.js +15 -0
  138. package/dist/mcp-WTQJJZAO.js.map +1 -0
  139. package/dist/mcp-discovery-WPAQFL6S.js +377 -0
  140. package/dist/mcp-discovery-WPAQFL6S.js.map +1 -0
  141. package/dist/mcp-installer-6O2XXD3V.js +394 -0
  142. package/dist/mcp-installer-6O2XXD3V.js.map +1 -0
  143. package/dist/metrics-KXGNFAAB.js +20 -0
  144. package/dist/metrics-KXGNFAAB.js.map +1 -0
  145. package/dist/primitive-registry-I6VTIR4W.js +512 -0
  146. package/dist/primitive-registry-I6VTIR4W.js.map +1 -0
  147. package/dist/project-discovery-C4UMD7JI.js +246 -0
  148. package/dist/project-discovery-C4UMD7JI.js.map +1 -0
  149. package/dist/provider-LQHQX7Z7.js +26 -0
  150. package/dist/provider-LQHQX7Z7.js.map +1 -0
  151. package/dist/provider-SXPQZ74H.js +28 -0
  152. package/dist/provider-SXPQZ74H.js.map +1 -0
  153. package/dist/rate-limiter-RLRVM325.js +22 -0
  154. package/dist/rate-limiter-RLRVM325.js.map +1 -0
  155. package/dist/rule-engine-YGQ3RYZM.js +182 -0
  156. package/dist/rule-engine-YGQ3RYZM.js.map +1 -0
  157. package/dist/scaffold-A3VRRCBV.js +347 -0
  158. package/dist/scaffold-A3VRRCBV.js.map +1 -0
  159. package/dist/scheduler-XHHIVHRI.js +397 -0
  160. package/dist/scheduler-XHHIVHRI.js.map +1 -0
  161. package/dist/search-V3W5JMJG.js +75 -0
  162. package/dist/search-V3W5JMJG.js.map +1 -0
  163. package/dist/semantic-search-2DTOO5UX.js +241 -0
  164. package/dist/semantic-search-2DTOO5UX.js.map +1 -0
  165. package/dist/serve-DTQ3HENY.js +291 -0
  166. package/dist/serve-DTQ3HENY.js.map +1 -0
  167. package/dist/sessions-CZGVXKQE.js +21 -0
  168. package/dist/sessions-CZGVXKQE.js.map +1 -0
  169. package/dist/sources-RW5DT56F.js +32 -0
  170. package/dist/sources-RW5DT56F.js.map +1 -0
  171. package/dist/starter-packs-76YUVHEU.js +893 -0
  172. package/dist/starter-packs-76YUVHEU.js.map +1 -0
  173. package/dist/state-GMXILIHW.js +13 -0
  174. package/dist/state-GMXILIHW.js.map +1 -0
  175. package/dist/state-merge-NKO5FRBA.js +174 -0
  176. package/dist/state-merge-NKO5FRBA.js.map +1 -0
  177. package/dist/telemetry-UC6PBXC7.js +22 -0
  178. package/dist/telemetry-UC6PBXC7.js.map +1 -0
  179. package/dist/tool-executor-MJ7IG7PQ.js +28 -0
  180. package/dist/tool-executor-MJ7IG7PQ.js.map +1 -0
  181. package/dist/tools-DZ4KETET.js +20 -0
  182. package/dist/tools-DZ4KETET.js.map +1 -0
  183. package/dist/types-EW7AIB3R.js +18 -0
  184. package/dist/types-EW7AIB3R.js.map +1 -0
  185. package/dist/types-WGDLSPO6.js +16 -0
  186. package/dist/types-WGDLSPO6.js.map +1 -0
  187. package/dist/universal-installer-QGS4SJGX.js +578 -0
  188. package/dist/universal-installer-QGS4SJGX.js.map +1 -0
  189. package/dist/validator-7WXMDIHH.js +22 -0
  190. package/dist/validator-7WXMDIHH.js.map +1 -0
  191. package/dist/verification-gate-FYXUX6LH.js +246 -0
  192. package/dist/verification-gate-FYXUX6LH.js.map +1 -0
  193. package/dist/versioning-Z3XNE2Q2.js +271 -0
  194. package/dist/versioning-Z3XNE2Q2.js.map +1 -0
  195. package/dist/watcher-ISJC7YKL.js +109 -0
  196. package/dist/watcher-ISJC7YKL.js.map +1 -0
  197. package/dist/web-server-DD7ZOP46.js +28 -0
  198. package/dist/web-server-DD7ZOP46.js.map +1 -0
  199. package/package.json +76 -0
  200. package/sources.yaml +121 -0
  201. package/templates/assistant/CORE.md +24 -0
  202. package/templates/assistant/SYSTEM.md +24 -0
  203. package/templates/assistant/config.yaml +51 -0
  204. package/templates/base/CORE.md +17 -0
  205. package/templates/base/SYSTEM.md +24 -0
  206. package/templates/base/config.yaml +51 -0
  207. package/templates/claude-opus/config.yaml +51 -0
  208. package/templates/code-reviewer/CORE.md +25 -0
  209. package/templates/code-reviewer/SYSTEM.md +30 -0
  210. package/templates/code-reviewer/config.yaml +51 -0
  211. package/templates/gpt4/config.yaml +51 -0
  212. package/templates/local/config.yaml +51 -0
@@ -0,0 +1,346 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ writeIndexFile
5
+ } from "./chunk-4FDUOGSZ.js";
6
+ import {
7
+ loadDirectory,
8
+ parseHarnessDocument
9
+ } from "./chunk-UPLBF4RZ.js";
10
+ import {
11
+ getPrimitiveDirs
12
+ } from "./chunk-4CWAGBNS.js";
13
+
14
+ // src/runtime/intake.ts
15
+ import { readFileSync, writeFileSync, unlinkSync, existsSync, mkdirSync, readdirSync, copyFileSync } from "fs";
16
+ import { join, basename } from "path";
17
+ import { tmpdir } from "os";
18
+ import matter from "gray-matter";
19
+ var VALID_TYPES = ["rule", "instinct", "skill", "playbook", "workflow", "tool", "agent"];
20
+ var TYPE_DIRS = {
21
+ rule: "rules",
22
+ instinct: "instincts",
23
+ skill: "skills",
24
+ playbook: "playbooks",
25
+ workflow: "workflows",
26
+ tool: "tools",
27
+ agent: "agents"
28
+ };
29
+ function fixCapability(filePath) {
30
+ const result = {
31
+ valid: true,
32
+ type: null,
33
+ errors: [],
34
+ warnings: [],
35
+ fixes_applied: []
36
+ };
37
+ if (!existsSync(filePath)) {
38
+ result.valid = false;
39
+ result.errors.push("File does not exist");
40
+ return result;
41
+ }
42
+ if (!filePath.endsWith(".md")) {
43
+ result.valid = false;
44
+ result.errors.push("File must be a .md file");
45
+ return result;
46
+ }
47
+ const raw = readFileSync(filePath, "utf-8");
48
+ let parsed;
49
+ try {
50
+ parsed = matter(raw);
51
+ } catch (err) {
52
+ result.valid = false;
53
+ result.errors.push(`Failed to parse frontmatter: ${err}`);
54
+ return result;
55
+ }
56
+ const data = { ...parsed.data };
57
+ let content = parsed.content;
58
+ let modified = false;
59
+ if (!data.id) {
60
+ const name = basename(filePath, ".md");
61
+ data.id = name.replace(/[^a-z0-9-]/gi, "-").toLowerCase();
62
+ result.fixes_applied.push(`Added id: "${data.id}" (from filename)`);
63
+ modified = true;
64
+ }
65
+ if (!data.status) {
66
+ data.status = "active";
67
+ result.fixes_applied.push('Added status: "active"');
68
+ modified = true;
69
+ }
70
+ const existingTags = Array.isArray(data.tags) ? data.tags.map((t) => t.toLowerCase()) : [];
71
+ let detectedType = null;
72
+ for (const type of VALID_TYPES) {
73
+ if (existingTags.includes(type)) {
74
+ detectedType = type;
75
+ break;
76
+ }
77
+ }
78
+ if (!detectedType) {
79
+ const bodyLower = content.toLowerCase();
80
+ if (bodyLower.includes("# rule:")) detectedType = "rule";
81
+ else if (bodyLower.includes("# instinct:")) detectedType = "instinct";
82
+ else if (bodyLower.includes("# skill:")) detectedType = "skill";
83
+ else if (bodyLower.includes("# playbook:")) detectedType = "playbook";
84
+ else if (bodyLower.includes("# workflow:")) detectedType = "workflow";
85
+ else if (bodyLower.includes("# tool:")) detectedType = "tool";
86
+ else if (bodyLower.includes("# agent:")) detectedType = "agent";
87
+ }
88
+ if (detectedType && !existingTags.includes(detectedType)) {
89
+ if (!Array.isArray(data.tags)) data.tags = [];
90
+ data.tags.push(detectedType);
91
+ result.fixes_applied.push(`Added tag: "${detectedType}"`);
92
+ modified = true;
93
+ }
94
+ result.type = detectedType;
95
+ const l0Regex = /<!--\s*L0:\s*(.*?)\s*-->/;
96
+ if (!l0Regex.test(content)) {
97
+ const headingMatch = content.match(/^#\s+(.+)$/m);
98
+ const firstLine = content.split("\n").find((line) => line.trim().length > 0);
99
+ const summary = headingMatch ? headingMatch[1].trim() : firstLine?.trim() ?? "";
100
+ if (summary.length > 0) {
101
+ const l0Text = summary.length > 120 ? summary.slice(0, 117) + "..." : summary;
102
+ content = `<!-- L0: ${l0Text} -->
103
+ ${content}`;
104
+ result.fixes_applied.push("Generated L0 summary from content");
105
+ modified = true;
106
+ }
107
+ }
108
+ const l1Regex = /<!--\s*L1:\s*(.*?)\s*-->/s;
109
+ if (!l1Regex.test(content)) {
110
+ const paragraphs = content.split(/\n{2,}/).filter((p) => {
111
+ const trimmed = p.trim();
112
+ return trimmed.length > 0 && !trimmed.startsWith("<!--") && !trimmed.startsWith("#");
113
+ });
114
+ if (paragraphs.length > 0) {
115
+ const para = paragraphs[0].replace(/\n/g, " ").trim();
116
+ const l1Text = para.length > 300 ? para.slice(0, 297) + "..." : para;
117
+ const l0Pos = content.indexOf("-->");
118
+ if (l0Pos !== -1) {
119
+ const insertPos = l0Pos + 3;
120
+ content = content.slice(0, insertPos) + `
121
+ <!-- L1: ${l1Text} -->` + content.slice(insertPos);
122
+ } else {
123
+ content = `<!-- L1: ${l1Text} -->
124
+ ${content}`;
125
+ }
126
+ result.fixes_applied.push("Generated L1 summary from first paragraph");
127
+ modified = true;
128
+ }
129
+ }
130
+ if (modified) {
131
+ const newRaw = matter.stringify(content, data);
132
+ writeFileSync(filePath, newRaw, "utf-8");
133
+ }
134
+ if (!result.type) {
135
+ result.errors.push(
136
+ 'Cannot determine primitive type. Add a type tag or use a heading like "# Skill: Name"'
137
+ );
138
+ }
139
+ const bodyContent = content.replace(l0Regex, "").replace(l1Regex, "").trim();
140
+ if (!bodyContent || bodyContent.length < 20) {
141
+ result.valid = false;
142
+ result.errors.push("Body content is too short or empty");
143
+ }
144
+ if (result.errors.length > 0) {
145
+ result.valid = false;
146
+ }
147
+ return result;
148
+ }
149
+ function evaluateCapability(filePath, harnessDir) {
150
+ const result = {
151
+ valid: true,
152
+ type: null,
153
+ errors: [],
154
+ warnings: [],
155
+ fixes_applied: []
156
+ };
157
+ if (!existsSync(filePath)) {
158
+ result.valid = false;
159
+ result.errors.push("File does not exist");
160
+ return result;
161
+ }
162
+ if (!filePath.endsWith(".md")) {
163
+ result.valid = false;
164
+ result.errors.push("File must be a .md file");
165
+ return result;
166
+ }
167
+ let doc;
168
+ try {
169
+ doc = parseHarnessDocument(filePath);
170
+ } catch (err) {
171
+ result.valid = false;
172
+ result.errors.push(`Failed to parse: ${err}`);
173
+ return result;
174
+ }
175
+ if (!doc.frontmatter.id) {
176
+ result.valid = false;
177
+ result.errors.push("Missing frontmatter field: id");
178
+ }
179
+ if (!doc.frontmatter.status) {
180
+ result.warnings.push('Missing status field, defaulting to "active"');
181
+ }
182
+ const tags = doc.frontmatter.tags.map((t) => t.toLowerCase());
183
+ for (const type of VALID_TYPES) {
184
+ if (tags.includes(type)) {
185
+ result.type = type;
186
+ break;
187
+ }
188
+ }
189
+ if (!result.type) {
190
+ const bodyLower = doc.body.toLowerCase();
191
+ if (bodyLower.includes("# rule:")) result.type = "rule";
192
+ else if (bodyLower.includes("# instinct:")) result.type = "instinct";
193
+ else if (bodyLower.includes("# skill:")) result.type = "skill";
194
+ else if (bodyLower.includes("# playbook:")) result.type = "playbook";
195
+ else if (bodyLower.includes("# workflow:")) result.type = "workflow";
196
+ else if (bodyLower.includes("# tool:")) result.type = "tool";
197
+ else if (bodyLower.includes("# agent:")) result.type = "agent";
198
+ }
199
+ if (!result.type) {
200
+ result.valid = false;
201
+ result.errors.push(
202
+ 'Cannot determine primitive type. Add a type tag (rule, instinct, skill, playbook, workflow, tool, agent) or use a heading like "# Skill: Name"'
203
+ );
204
+ }
205
+ if (!doc.l0) {
206
+ result.warnings.push("Missing L0 summary (<!-- L0: ... -->). Recommended for context loading.");
207
+ }
208
+ if (!doc.l1) {
209
+ result.warnings.push("Missing L1 summary (<!-- L1: ... -->). Recommended for context loading.");
210
+ }
211
+ if (!doc.body || doc.body.length < 20) {
212
+ result.valid = false;
213
+ result.errors.push("Body content is too short or empty");
214
+ }
215
+ if (harnessDir) {
216
+ resolveDependencies(doc, harnessDir, result);
217
+ }
218
+ return result;
219
+ }
220
+ function resolveDependencies(doc, harnessDir, result) {
221
+ const primitiveDirs = getPrimitiveDirs();
222
+ const knownIds = /* @__PURE__ */ new Set();
223
+ for (const dir of primitiveDirs) {
224
+ const fullPath = join(harnessDir, dir);
225
+ if (!existsSync(fullPath)) continue;
226
+ const docs = loadDirectory(fullPath);
227
+ for (const d of docs) {
228
+ knownIds.add(d.frontmatter.id);
229
+ }
230
+ }
231
+ const related = doc.frontmatter.related;
232
+ if (related && related.length > 0) {
233
+ for (const ref of related) {
234
+ if (knownIds.has(ref)) continue;
235
+ const refPath = join(harnessDir, ref);
236
+ if (existsSync(refPath) || existsSync(refPath + ".md")) continue;
237
+ result.warnings.push(`Unresolved reference: "${ref}" (related: field) \u2014 not found in harness`);
238
+ }
239
+ }
240
+ const withAgent = doc.frontmatter.with;
241
+ if (withAgent) {
242
+ const agentsDir = join(harnessDir, "agents");
243
+ let agentFound = false;
244
+ if (existsSync(agentsDir)) {
245
+ const agentDocs = loadDirectory(agentsDir);
246
+ agentFound = agentDocs.some(
247
+ (d) => d.frontmatter.id === withAgent || basename(d.path, ".md") === withAgent
248
+ );
249
+ }
250
+ if (!agentFound) {
251
+ result.warnings.push(`Unresolved agent: "${withAgent}" (with: field) \u2014 no matching agent found`);
252
+ }
253
+ }
254
+ const schedule = doc.frontmatter.schedule;
255
+ if (schedule) {
256
+ const fields = schedule.trim().split(/\s+/);
257
+ if (fields.length < 5 || fields.length > 6) {
258
+ result.warnings.push(`Possibly invalid cron expression: "${schedule}" (expected 5-6 fields)`);
259
+ }
260
+ }
261
+ }
262
+ function installCapability(harnessDir, filePath) {
263
+ const evalResult = evaluateCapability(filePath, harnessDir);
264
+ if (!evalResult.valid || !evalResult.type) {
265
+ return { installed: false, destination: "", evalResult };
266
+ }
267
+ const targetDir = join(harnessDir, TYPE_DIRS[evalResult.type]);
268
+ if (!existsSync(targetDir)) {
269
+ mkdirSync(targetDir, { recursive: true });
270
+ }
271
+ const destination = join(targetDir, basename(filePath));
272
+ copyFileSync(filePath, destination);
273
+ const processedDir = join(harnessDir, "intake", ".processed");
274
+ if (!existsSync(processedDir)) {
275
+ mkdirSync(processedDir, { recursive: true });
276
+ }
277
+ copyFileSync(filePath, join(processedDir, basename(filePath)));
278
+ writeIndexFile(harnessDir, TYPE_DIRS[evalResult.type]);
279
+ return { installed: true, destination, evalResult };
280
+ }
281
+ function processIntake(harnessDir) {
282
+ const intakeDir = join(harnessDir, "intake");
283
+ if (!existsSync(intakeDir)) return [];
284
+ const files = readdirSync(intakeDir).filter(
285
+ (f) => f.endsWith(".md") && !f.startsWith(".")
286
+ );
287
+ const results = [];
288
+ for (const file of files) {
289
+ const filePath = join(intakeDir, file);
290
+ const result = installCapability(harnessDir, filePath);
291
+ results.push({ file, result });
292
+ if (result.installed) {
293
+ try {
294
+ unlinkSync(filePath);
295
+ } catch (_unlinkErr) {
296
+ }
297
+ }
298
+ }
299
+ return results;
300
+ }
301
+ async function downloadCapability(url) {
302
+ let parsed;
303
+ try {
304
+ parsed = new URL(url);
305
+ } catch {
306
+ return { downloaded: false, localPath: "", error: `Invalid URL: ${url}` };
307
+ }
308
+ if (parsed.protocol !== "https:") {
309
+ return { downloaded: false, localPath: "", error: "Only HTTPS URLs are supported" };
310
+ }
311
+ const urlPath = parsed.pathname;
312
+ let filename = basename(urlPath);
313
+ if (!filename.endsWith(".md")) {
314
+ filename = filename + ".md";
315
+ }
316
+ try {
317
+ const response = await fetch(url);
318
+ if (!response.ok) {
319
+ return { downloaded: false, localPath: "", error: `HTTP ${response.status}: ${response.statusText}` };
320
+ }
321
+ const body = await response.text();
322
+ if (body.length === 0) {
323
+ return { downloaded: false, localPath: "", error: "Downloaded file is empty" };
324
+ }
325
+ if (body.length > 1048576) {
326
+ return { downloaded: false, localPath: "", error: "File exceeds 1MB size limit" };
327
+ }
328
+ const tempDir = join(tmpdir(), "harness-download");
329
+ mkdirSync(tempDir, { recursive: true });
330
+ const localPath = join(tempDir, filename);
331
+ writeFileSync(localPath, body, "utf-8");
332
+ return { downloaded: true, localPath };
333
+ } catch (err) {
334
+ const msg = err instanceof Error ? err.message : String(err);
335
+ return { downloaded: false, localPath: "", error: `Download failed: ${msg}` };
336
+ }
337
+ }
338
+
339
+ export {
340
+ fixCapability,
341
+ evaluateCapability,
342
+ installCapability,
343
+ processIntake,
344
+ downloadCapability
345
+ };
346
+ //# sourceMappingURL=chunk-W4T7PGI2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/intake.ts"],"sourcesContent":["import { readFileSync, writeFileSync, unlinkSync, existsSync, mkdirSync, readdirSync, copyFileSync } from 'fs';\nimport { join, basename } from 'path';\nimport { tmpdir } from 'os';\nimport matter from 'gray-matter';\nimport { parseHarnessDocument, loadDirectory } from '../primitives/loader.js';\nimport { writeIndexFile } from './indexer.js';\nimport { getPrimitiveDirs } from '../core/types.js';\nimport type { HarnessDocument } from '../core/types.js';\n\nexport interface EvalResult {\n valid: boolean;\n type: string | null;\n errors: string[];\n warnings: string[];\n fixes_applied: string[];\n}\n\nconst VALID_TYPES = ['rule', 'instinct', 'skill', 'playbook', 'workflow', 'tool', 'agent'];\nconst TYPE_DIRS: Record<string, string> = {\n rule: 'rules',\n instinct: 'instincts',\n skill: 'skills',\n playbook: 'playbooks',\n workflow: 'workflows',\n tool: 'tools',\n agent: 'agents',\n};\n\n/**\n * Auto-fix common issues in a capability file.\n * Reads the file, applies fixes, writes back, returns what was fixed.\n * Does NOT fix unfixable issues (e.g., empty body, unparseable YAML).\n */\nexport function fixCapability(filePath: string): EvalResult {\n const result: EvalResult = {\n valid: true,\n type: null,\n errors: [],\n warnings: [],\n fixes_applied: [],\n };\n\n if (!existsSync(filePath)) {\n result.valid = false;\n result.errors.push('File does not exist');\n return result;\n }\n\n if (!filePath.endsWith('.md')) {\n result.valid = false;\n result.errors.push('File must be a .md file');\n return result;\n }\n\n const raw = readFileSync(filePath, 'utf-8');\n let parsed: ReturnType<typeof matter>;\n try {\n parsed = matter(raw);\n } catch (err) {\n result.valid = false;\n result.errors.push(`Failed to parse frontmatter: ${err}`);\n return result;\n }\n\n const data = { ...parsed.data } as Record<string, unknown>;\n let content = parsed.content;\n let modified = false;\n\n // Fix 1: Missing id — derive from filename\n if (!data.id) {\n const name = basename(filePath, '.md');\n data.id = name.replace(/[^a-z0-9-]/gi, '-').toLowerCase();\n result.fixes_applied.push(`Added id: \"${data.id}\" (from filename)`);\n modified = true;\n }\n\n // Fix 2: Missing status — set to active\n if (!data.status) {\n data.status = 'active';\n result.fixes_applied.push('Added status: \"active\"');\n modified = true;\n }\n\n // Fix 3: Missing type tag — infer from content and add tag\n const existingTags = Array.isArray(data.tags) ? (data.tags as string[]).map((t) => t.toLowerCase()) : [];\n let detectedType: string | null = null;\n for (const type of VALID_TYPES) {\n if (existingTags.includes(type)) {\n detectedType = type;\n break;\n }\n }\n if (!detectedType) {\n const bodyLower = content.toLowerCase();\n if (bodyLower.includes('# rule:')) detectedType = 'rule';\n else if (bodyLower.includes('# instinct:')) detectedType = 'instinct';\n else if (bodyLower.includes('# skill:')) detectedType = 'skill';\n else if (bodyLower.includes('# playbook:')) detectedType = 'playbook';\n else if (bodyLower.includes('# workflow:')) detectedType = 'workflow';\n else if (bodyLower.includes('# tool:')) detectedType = 'tool';\n else if (bodyLower.includes('# agent:')) detectedType = 'agent';\n }\n if (detectedType && !existingTags.includes(detectedType)) {\n if (!Array.isArray(data.tags)) data.tags = [];\n (data.tags as string[]).push(detectedType);\n result.fixes_applied.push(`Added tag: \"${detectedType}\"`);\n modified = true;\n }\n result.type = detectedType;\n\n // Fix 4: Missing L0 — generate from first heading or first non-empty line\n const l0Regex = /<!--\\s*L0:\\s*(.*?)\\s*-->/;\n if (!l0Regex.test(content)) {\n const headingMatch = content.match(/^#\\s+(.+)$/m);\n const firstLine = content.split('\\n').find((line) => line.trim().length > 0);\n const summary = headingMatch ? headingMatch[1].trim() : (firstLine?.trim() ?? '');\n if (summary.length > 0) {\n const l0Text = summary.length > 120 ? summary.slice(0, 117) + '...' : summary;\n content = `<!-- L0: ${l0Text} -->\\n${content}`;\n result.fixes_applied.push('Generated L0 summary from content');\n modified = true;\n }\n }\n\n // Fix 5: Missing L1 — generate from first paragraph\n const l1Regex = /<!--\\s*L1:\\s*(.*?)\\s*-->/s;\n if (!l1Regex.test(content)) {\n const paragraphs = content.split(/\\n{2,}/).filter((p) => {\n const trimmed = p.trim();\n return trimmed.length > 0 && !trimmed.startsWith('<!--') && !trimmed.startsWith('#');\n });\n if (paragraphs.length > 0) {\n const para = paragraphs[0].replace(/\\n/g, ' ').trim();\n const l1Text = para.length > 300 ? para.slice(0, 297) + '...' : para;\n // Insert L1 after L0 if present, otherwise at the top\n const l0Pos = content.indexOf('-->');\n if (l0Pos !== -1) {\n const insertPos = l0Pos + 3;\n content = content.slice(0, insertPos) + `\\n<!-- L1: ${l1Text} -->` + content.slice(insertPos);\n } else {\n content = `<!-- L1: ${l1Text} -->\\n${content}`;\n }\n result.fixes_applied.push('Generated L1 summary from first paragraph');\n modified = true;\n }\n }\n\n // Write back if modified\n if (modified) {\n const newRaw = matter.stringify(content, data);\n writeFileSync(filePath, newRaw, 'utf-8');\n }\n\n // Re-evaluate after fixes\n if (!result.type) {\n result.errors.push(\n 'Cannot determine primitive type. Add a type tag or use a heading like \"# Skill: Name\"',\n );\n }\n\n // Check body has content\n const bodyContent = content.replace(l0Regex, '').replace(l1Regex, '').trim();\n if (!bodyContent || bodyContent.length < 20) {\n result.valid = false;\n result.errors.push('Body content is too short or empty');\n }\n\n if (result.errors.length > 0) {\n result.valid = false;\n }\n\n return result;\n}\n\n/**\n * Evaluate a capability file. If harnessDir is provided, also checks\n * dependency resolution (related: references, with: agent references).\n */\nexport function evaluateCapability(filePath: string, harnessDir?: string): EvalResult {\n const result: EvalResult = {\n valid: true,\n type: null,\n errors: [],\n warnings: [],\n fixes_applied: [],\n };\n\n // Step 1: Check file exists and is markdown\n if (!existsSync(filePath)) {\n result.valid = false;\n result.errors.push('File does not exist');\n return result;\n }\n\n if (!filePath.endsWith('.md')) {\n result.valid = false;\n result.errors.push('File must be a .md file');\n return result;\n }\n\n // Step 2: Try to parse\n let doc: HarnessDocument;\n try {\n doc = parseHarnessDocument(filePath);\n } catch (err) {\n result.valid = false;\n result.errors.push(`Failed to parse: ${err}`);\n return result;\n }\n\n // Step 3: Check frontmatter\n if (!doc.frontmatter.id) {\n result.valid = false;\n result.errors.push('Missing frontmatter field: id');\n }\n\n if (!doc.frontmatter.status) {\n result.warnings.push('Missing status field, defaulting to \"active\"');\n }\n\n // Step 4: Detect type from tags or directory hint\n const tags = doc.frontmatter.tags.map((t) => t.toLowerCase());\n for (const type of VALID_TYPES) {\n if (tags.includes(type)) {\n result.type = type;\n break;\n }\n }\n\n if (!result.type) {\n // Try to infer from content\n const bodyLower = doc.body.toLowerCase();\n if (bodyLower.includes('# rule:')) result.type = 'rule';\n else if (bodyLower.includes('# instinct:')) result.type = 'instinct';\n else if (bodyLower.includes('# skill:')) result.type = 'skill';\n else if (bodyLower.includes('# playbook:')) result.type = 'playbook';\n else if (bodyLower.includes('# workflow:')) result.type = 'workflow';\n else if (bodyLower.includes('# tool:')) result.type = 'tool';\n else if (bodyLower.includes('# agent:')) result.type = 'agent';\n }\n\n if (!result.type) {\n result.valid = false;\n result.errors.push(\n 'Cannot determine primitive type. Add a type tag (rule, instinct, skill, playbook, workflow, tool, agent) or use a heading like \"# Skill: Name\"',\n );\n }\n\n // Step 5: Check L0/L1\n if (!doc.l0) {\n result.warnings.push('Missing L0 summary (<!-- L0: ... -->). Recommended for context loading.');\n }\n if (!doc.l1) {\n result.warnings.push('Missing L1 summary (<!-- L1: ... -->). Recommended for context loading.');\n }\n\n // Step 6: Check body has content\n if (!doc.body || doc.body.length < 20) {\n result.valid = false;\n result.errors.push('Body content is too short or empty');\n }\n\n // Step 7: Dependency resolution (when harness dir is available)\n if (harnessDir) {\n resolveDependencies(doc, harnessDir, result);\n }\n\n return result;\n}\n\n/**\n * Check that referenced primitives (related: and with: fields) exist in the harness.\n */\nfunction resolveDependencies(doc: HarnessDocument, harnessDir: string, result: EvalResult): void {\n // Load all known primitive IDs for reference checking\n const primitiveDirs = getPrimitiveDirs();\n const knownIds = new Set<string>();\n for (const dir of primitiveDirs) {\n const fullPath = join(harnessDir, dir);\n if (!existsSync(fullPath)) continue;\n const docs = loadDirectory(fullPath);\n for (const d of docs) {\n knownIds.add(d.frontmatter.id);\n }\n }\n\n // Check related: references\n const related = doc.frontmatter.related;\n if (related && related.length > 0) {\n for (const ref of related) {\n if (knownIds.has(ref)) continue;\n // Check if it's a file path\n const refPath = join(harnessDir, ref);\n if (existsSync(refPath) || existsSync(refPath + '.md')) continue;\n result.warnings.push(`Unresolved reference: \"${ref}\" (related: field) — not found in harness`);\n }\n }\n\n // Check with: agent reference (used for delegation)\n const withAgent = doc.frontmatter.with;\n if (withAgent) {\n // Check if agent exists in agents/ directory\n const agentsDir = join(harnessDir, 'agents');\n let agentFound = false;\n if (existsSync(agentsDir)) {\n const agentDocs = loadDirectory(agentsDir);\n agentFound = agentDocs.some(\n (d) => d.frontmatter.id === withAgent || basename(d.path, '.md') === withAgent,\n );\n }\n if (!agentFound) {\n result.warnings.push(`Unresolved agent: \"${withAgent}\" (with: field) — no matching agent found`);\n }\n }\n\n // Check schedule: cron expression validity (for workflows)\n const schedule = doc.frontmatter.schedule;\n if (schedule) {\n // Basic cron validation: should have 5-6 space-separated fields\n const fields = schedule.trim().split(/\\s+/);\n if (fields.length < 5 || fields.length > 6) {\n result.warnings.push(`Possibly invalid cron expression: \"${schedule}\" (expected 5-6 fields)`);\n }\n }\n}\n\nexport function installCapability(harnessDir: string, filePath: string): { installed: boolean; destination: string; evalResult: EvalResult } {\n const evalResult = evaluateCapability(filePath, harnessDir);\n\n if (!evalResult.valid || !evalResult.type) {\n return { installed: false, destination: '', evalResult };\n }\n\n const targetDir = join(harnessDir, TYPE_DIRS[evalResult.type]);\n if (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n }\n\n const destination = join(targetDir, basename(filePath));\n\n // Copy file to target directory\n copyFileSync(filePath, destination);\n\n // Move original to .processed\n const processedDir = join(harnessDir, 'intake', '.processed');\n if (!existsSync(processedDir)) {\n mkdirSync(processedDir, { recursive: true });\n }\n copyFileSync(filePath, join(processedDir, basename(filePath)));\n\n // Rebuild index for target directory\n writeIndexFile(harnessDir, TYPE_DIRS[evalResult.type]);\n\n return { installed: true, destination, evalResult };\n}\n\nexport function processIntake(harnessDir: string): Array<{ file: string; result: ReturnType<typeof installCapability> }> {\n const intakeDir = join(harnessDir, 'intake');\n if (!existsSync(intakeDir)) return [];\n\n const files = readdirSync(intakeDir).filter(\n (f) => f.endsWith('.md') && !f.startsWith('.'),\n );\n\n const results: Array<{ file: string; result: ReturnType<typeof installCapability> }> = [];\n\n for (const file of files) {\n const filePath = join(intakeDir, file);\n const result = installCapability(harnessDir, filePath);\n results.push({ file, result });\n\n // Remove from intake if installed\n if (result.installed) {\n try {\n unlinkSync(filePath);\n } catch (_unlinkErr) {\n // Best-effort cleanup — file persists if removal fails\n }\n }\n }\n\n return results;\n}\n\nexport interface DownloadResult {\n downloaded: boolean;\n localPath: string;\n error?: string;\n}\n\n/**\n * Download a capability file from a URL to a temporary file.\n * Validates the URL (must be HTTPS) and content type (must look like markdown).\n * Returns a local temp path suitable for passing to installCapability().\n */\nexport async function downloadCapability(url: string): Promise<DownloadResult> {\n // Validate URL\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return { downloaded: false, localPath: '', error: `Invalid URL: ${url}` };\n }\n\n if (parsed.protocol !== 'https:') {\n return { downloaded: false, localPath: '', error: 'Only HTTPS URLs are supported' };\n }\n\n // Derive filename from URL path\n const urlPath = parsed.pathname;\n let filename = basename(urlPath);\n if (!filename.endsWith('.md')) {\n filename = filename + '.md';\n }\n\n try {\n const response = await fetch(url);\n\n if (!response.ok) {\n return { downloaded: false, localPath: '', error: `HTTP ${response.status}: ${response.statusText}` };\n }\n\n const body = await response.text();\n\n // Basic validation: must contain frontmatter delimiters or be valid markdown\n if (body.length === 0) {\n return { downloaded: false, localPath: '', error: 'Downloaded file is empty' };\n }\n\n // Max size: 1MB\n if (body.length > 1_048_576) {\n return { downloaded: false, localPath: '', error: 'File exceeds 1MB size limit' };\n }\n\n // Write to temp directory\n const tempDir = join(tmpdir(), 'harness-download');\n mkdirSync(tempDir, { recursive: true });\n const localPath = join(tempDir, filename);\n writeFileSync(localPath, body, 'utf-8');\n\n return { downloaded: true, localPath };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { downloaded: false, localPath: '', error: `Download failed: ${msg}` };\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ loadDirectory
5
+ } from "./chunk-UPLBF4RZ.js";
6
+
7
+ // src/runtime/tools.ts
8
+ import { existsSync } from "fs";
9
+ import { join } from "path";
10
+ function extractAuth(body) {
11
+ const authSection = body.match(/## Authentication\s*\n([\s\S]*?)(?=\n## |\n$|$)/i);
12
+ if (!authSection) return [];
13
+ const envVarPattern = /`([A-Z][A-Z0-9_]+)`/g;
14
+ const vars = [];
15
+ const seen = /* @__PURE__ */ new Set();
16
+ let match;
17
+ while ((match = envVarPattern.exec(authSection[1])) !== null) {
18
+ const envVar = match[1];
19
+ if (!seen.has(envVar)) {
20
+ seen.add(envVar);
21
+ vars.push({
22
+ envVar,
23
+ present: process.env[envVar] !== void 0 && process.env[envVar] !== ""
24
+ });
25
+ }
26
+ }
27
+ return vars;
28
+ }
29
+ function extractOperations(body) {
30
+ const opsSection = body.match(/## (?:Common )?Operations\s*\n([\s\S]*?)(?=\n## |\n$|$)/i);
31
+ if (!opsSection) return [];
32
+ const ops = [];
33
+ const lines = opsSection[1].split("\n");
34
+ let currentSection = "";
35
+ for (const line of lines) {
36
+ const headingMatch = line.match(/^### (.+)/);
37
+ if (headingMatch) {
38
+ currentSection = headingMatch[1].trim();
39
+ continue;
40
+ }
41
+ const opMatch = line.match(/`?(GET|POST|PUT|DELETE|PATCH)\s+(\S+?)`?(?:\s|$)/);
42
+ if (opMatch) {
43
+ const name = currentSection ? `${currentSection}: ${opMatch[2].split("/").pop() || opMatch[2]}` : opMatch[2].split("/").pop() || opMatch[2];
44
+ ops.push({
45
+ name,
46
+ method: opMatch[1],
47
+ endpoint: opMatch[2]
48
+ });
49
+ }
50
+ }
51
+ return ops;
52
+ }
53
+ function extractRateLimits(body) {
54
+ const section = body.match(/## Rate Limits\s*\n([\s\S]*?)(?=\n## |\n$|$)/i);
55
+ if (!section) return [];
56
+ return section[1].split("\n").filter((l) => l.startsWith("- ")).map((l) => l.replace(/^- /, "").trim());
57
+ }
58
+ function extractGotchas(body) {
59
+ const section = body.match(/## Gotchas\s*\n([\s\S]*?)(?=\n## |\n$|$)/i);
60
+ if (!section) return [];
61
+ return section[1].split("\n").filter((l) => l.startsWith("- ")).map((l) => l.replace(/^- /, "").trim());
62
+ }
63
+ function parseToolDefinition(doc) {
64
+ return {
65
+ id: doc.frontmatter.id,
66
+ doc,
67
+ tags: doc.frontmatter.tags,
68
+ status: doc.frontmatter.status,
69
+ auth: extractAuth(doc.body),
70
+ operations: extractOperations(doc.body),
71
+ rateLimits: extractRateLimits(doc.body),
72
+ gotchas: extractGotchas(doc.body)
73
+ };
74
+ }
75
+ function loadTools(harnessDir) {
76
+ const toolsDir = join(harnessDir, "tools");
77
+ if (!existsSync(toolsDir)) return [];
78
+ const docs = loadDirectory(toolsDir);
79
+ return docs.map(parseToolDefinition);
80
+ }
81
+ function getToolById(harnessDir, toolId) {
82
+ const tools = loadTools(harnessDir);
83
+ return tools.find((t) => t.id === toolId) ?? null;
84
+ }
85
+ function listToolSummaries(harnessDir) {
86
+ const tools = loadTools(harnessDir);
87
+ return tools.map((t) => ({
88
+ id: t.id,
89
+ l0: t.doc.l0,
90
+ tags: t.tags,
91
+ status: t.status,
92
+ authReady: t.auth.length === 0 || t.auth.every((a) => a.present),
93
+ operationCount: t.operations.length
94
+ }));
95
+ }
96
+ function checkToolAuth(harnessDir, toolId) {
97
+ const tools = toolId ? [getToolById(harnessDir, toolId)].filter((t) => t !== null) : loadTools(harnessDir);
98
+ return tools.map((t) => ({
99
+ tool: t.id,
100
+ auth: t.auth
101
+ }));
102
+ }
103
+
104
+ export {
105
+ parseToolDefinition,
106
+ loadTools,
107
+ getToolById,
108
+ listToolSummaries,
109
+ checkToolAuth
110
+ };
111
+ //# sourceMappingURL=chunk-XTBKL5BI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/tools.ts"],"sourcesContent":["import { existsSync, readdirSync } from 'fs';\nimport { join, basename } from 'path';\nimport { loadDirectory } from '../primitives/loader.js';\nimport type { HarnessDocument } from '../core/types.js';\n\nexport interface ToolAuth {\n envVar: string;\n present: boolean;\n}\n\nexport interface ToolOperation {\n name: string;\n method: string;\n endpoint: string;\n}\n\nexport interface ToolDefinition {\n id: string;\n doc: HarnessDocument;\n tags: string[];\n status: string;\n auth: ToolAuth[];\n operations: ToolOperation[];\n rateLimits: string[];\n gotchas: string[];\n}\n\nexport interface ToolSummary {\n id: string;\n l0: string;\n tags: string[];\n status: string;\n authReady: boolean;\n operationCount: number;\n}\n\n/**\n * Extract environment variable names from authentication section.\n * Looks for `ENV_VAR_NAME` patterns (all-caps with underscores) in the auth section.\n */\nfunction extractAuth(body: string): ToolAuth[] {\n const authSection = body.match(/## Authentication\\s*\\n([\\s\\S]*?)(?=\\n## |\\n$|$)/i);\n if (!authSection) return [];\n\n const envVarPattern = /`([A-Z][A-Z0-9_]+)`/g;\n const vars: ToolAuth[] = [];\n const seen = new Set<string>();\n let match: RegExpExecArray | null;\n\n while ((match = envVarPattern.exec(authSection[1])) !== null) {\n const envVar = match[1];\n if (!seen.has(envVar)) {\n seen.add(envVar);\n vars.push({\n envVar,\n present: process.env[envVar] !== undefined && process.env[envVar] !== '',\n });\n }\n }\n\n return vars;\n}\n\n/**\n * Extract operations from Common Operations / Operations sections.\n * Looks for lines with HTTP method + endpoint patterns.\n */\nfunction extractOperations(body: string): ToolOperation[] {\n const opsSection = body.match(/## (?:Common )?Operations\\s*\\n([\\s\\S]*?)(?=\\n## |\\n$|$)/i);\n if (!opsSection) return [];\n\n const ops: ToolOperation[] = [];\n const lines = opsSection[1].split('\\n');\n let currentSection = '';\n\n for (const line of lines) {\n const headingMatch = line.match(/^### (.+)/);\n if (headingMatch) {\n currentSection = headingMatch[1].trim();\n continue;\n }\n\n // Match patterns like: `GET /repos/{owner}/{repo}/pulls`\n // or: POST /sendMessage\n const opMatch = line.match(/`?(GET|POST|PUT|DELETE|PATCH)\\s+(\\S+?)`?(?:\\s|$)/);\n if (opMatch) {\n const name = currentSection\n ? `${currentSection}: ${opMatch[2].split('/').pop() || opMatch[2]}`\n : opMatch[2].split('/').pop() || opMatch[2];\n ops.push({\n name,\n method: opMatch[1],\n endpoint: opMatch[2],\n });\n }\n }\n\n return ops;\n}\n\n/**\n * Extract rate limit lines from Rate Limits section.\n */\nfunction extractRateLimits(body: string): string[] {\n const section = body.match(/## Rate Limits\\s*\\n([\\s\\S]*?)(?=\\n## |\\n$|$)/i);\n if (!section) return [];\n\n return section[1]\n .split('\\n')\n .filter((l) => l.startsWith('- '))\n .map((l) => l.replace(/^- /, '').trim());\n}\n\n/**\n * Extract gotchas/caveats from Gotchas section.\n */\nfunction extractGotchas(body: string): string[] {\n const section = body.match(/## Gotchas\\s*\\n([\\s\\S]*?)(?=\\n## |\\n$|$)/i);\n if (!section) return [];\n\n return section[1]\n .split('\\n')\n .filter((l) => l.startsWith('- '))\n .map((l) => l.replace(/^- /, '').trim());\n}\n\n/**\n * Parse a tool document into a structured ToolDefinition.\n */\nexport function parseToolDefinition(doc: HarnessDocument): ToolDefinition {\n return {\n id: doc.frontmatter.id,\n doc,\n tags: doc.frontmatter.tags,\n status: doc.frontmatter.status,\n auth: extractAuth(doc.body),\n operations: extractOperations(doc.body),\n rateLimits: extractRateLimits(doc.body),\n gotchas: extractGotchas(doc.body),\n };\n}\n\n/**\n * Load all tool definitions from the tools/ directory.\n */\nexport function loadTools(harnessDir: string): ToolDefinition[] {\n const toolsDir = join(harnessDir, 'tools');\n if (!existsSync(toolsDir)) return [];\n\n const docs = loadDirectory(toolsDir);\n return docs.map(parseToolDefinition);\n}\n\n/**\n * Get a specific tool definition by ID.\n */\nexport function getToolById(harnessDir: string, toolId: string): ToolDefinition | null {\n const tools = loadTools(harnessDir);\n return tools.find((t) => t.id === toolId) ?? null;\n}\n\n/**\n * List tools with summary info (without full document content).\n */\nexport function listToolSummaries(harnessDir: string): ToolSummary[] {\n const tools = loadTools(harnessDir);\n return tools.map((t) => ({\n id: t.id,\n l0: t.doc.l0,\n tags: t.tags,\n status: t.status,\n authReady: t.auth.length === 0 || t.auth.every((a) => a.present),\n operationCount: t.operations.length,\n }));\n}\n\n/**\n * Check auth status for a specific tool or all tools.\n */\nexport function checkToolAuth(harnessDir: string, toolId?: string): Array<{ tool: string; auth: ToolAuth[] }> {\n const tools = toolId\n ? [getToolById(harnessDir, toolId)].filter((t): t is ToolDefinition => t !== null)\n : loadTools(harnessDir);\n\n return tools.map((t) => ({\n tool: t.id,\n auth: t.auth,\n }));\n}\n"],"mappings":"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","names":[]}