@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 @@
1
+ {"version":3,"sources":["../src/runtime/intelligence.ts"],"sourcesContent":["import { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join, relative } from 'path';\nimport { loadDirectoryWithErrors, loadDirectory } from '../primitives/loader.js';\nimport { buildDependencyGraph } from './graph.js';\nimport { getPrimitiveDirs } from '../core/types.js';\nimport type { HarnessConfig, HarnessDocument } from '../core/types.js';\nimport { loadConfig } from '../core/config.js';\nimport type { InstinctCandidate } from './instinct-learner.js';\nimport { installInstinct } from './instinct-learner.js';\nimport { log } from '../core/logger.js';\nimport { checkRateLimit } from './rate-limiter.js';\nimport { buildRateLimits } from './guardrails.js';\nimport { checkBudget } from './cost-tracker.js';\nimport { validateHarness } from './validator.js';\n\n// --- Auto-Promote Instincts ---\n\nexport interface PatternOccurrence {\n behavior: string;\n journalDates: string[];\n count: number;\n}\n\nexport interface AutoPromoteResult {\n patterns: PatternOccurrence[];\n promoted: string[];\n skipped: string[];\n journalsScanned: number;\n}\n\n/**\n * Scan all journals for instinct candidates that appear 3+ times.\n * These repeated patterns suggest strong behavioral signals worth auto-promoting.\n *\n * The function:\n * 1. Reads all journal files\n * 2. Extracts \"## Instinct Candidates\" sections\n * 3. Normalizes behavior text for fuzzy matching\n * 4. Groups by similar behavior (normalized string comparison)\n * 5. Returns patterns with 3+ occurrences across different journal dates\n * 6. Optionally auto-installs promoted instincts\n */\nexport function autoPromoteInstincts(\n harnessDir: string,\n options?: { threshold?: number; install?: boolean },\n): AutoPromoteResult {\n const threshold = options?.threshold ?? 3;\n const journalDir = join(harnessDir, 'memory', 'journal');\n\n if (!existsSync(journalDir)) {\n return { patterns: [], promoted: [], skipped: [], journalsScanned: 0 };\n }\n\n const files = readdirSync(journalDir)\n .filter((f) => f.endsWith('.md') && /^\\d{4}-\\d{2}-\\d{2}/.test(f))\n .sort();\n\n // Collect all instinct candidate behaviors with their journal dates\n const behaviorMap = new Map<string, { original: string; dates: Set<string> }>();\n\n for (const file of files) {\n const content = readFileSync(join(journalDir, file), 'utf-8');\n const dateMatch = file.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (!dateMatch) continue;\n const journalDate = dateMatch[1];\n\n // Extract instinct candidates section\n const sectionMatch = content.match(/## Instinct Candidates\\n([\\s\\S]*?)(?=\\n## |\\n*$)/);\n if (!sectionMatch) continue;\n\n const lines = sectionMatch[1]\n .split('\\n')\n .filter((l) => l.startsWith('- '))\n .map((l) => l.slice(2).trim().replace(/^INSTINCT:\\s*/i, ''));\n\n for (const line of lines) {\n if (!line) continue;\n const normalized = normalizeBehavior(line);\n if (!normalized) continue;\n\n const existing = behaviorMap.get(normalized);\n if (existing) {\n existing.dates.add(journalDate);\n } else {\n behaviorMap.set(normalized, { original: line, dates: new Set([journalDate]) });\n }\n }\n }\n\n // Filter to patterns with threshold+ occurrences across different dates\n const patterns: PatternOccurrence[] = [];\n for (const [, value] of behaviorMap) {\n if (value.dates.size >= threshold) {\n patterns.push({\n behavior: value.original,\n journalDates: [...value.dates].sort(),\n count: value.dates.size,\n });\n }\n }\n\n // Sort by count descending\n patterns.sort((a, b) => b.count - a.count);\n\n // Deduplicate against existing instincts\n const existingIds = new Set<string>();\n const existingBehaviors = new Set<string>();\n const instinctsDir = join(harnessDir, 'instincts');\n if (existsSync(instinctsDir)) {\n const docs = loadDirectory(instinctsDir);\n for (const doc of docs) {\n existingIds.add(doc.frontmatter.id);\n if (doc.l0) existingBehaviors.add(normalizeBehavior(doc.l0));\n }\n }\n\n const promoted: string[] = [];\n const skipped: string[] = [];\n\n for (const pattern of patterns) {\n const normalized = normalizeBehavior(pattern.behavior);\n const id = behaviorToId(pattern.behavior);\n\n if (existingIds.has(id) || existingBehaviors.has(normalized)) {\n skipped.push(id);\n continue;\n }\n\n if (options?.install) {\n const candidate: InstinctCandidate = {\n id,\n behavior: pattern.behavior,\n provenance: `auto-promote:${pattern.journalDates.length}x across ${pattern.journalDates[0]} to ${pattern.journalDates[pattern.journalDates.length - 1]}`,\n confidence: Math.min(0.9, 0.5 + pattern.count * 0.1),\n };\n\n const path = installInstinct(harnessDir, candidate);\n if (path) {\n promoted.push(id);\n } else {\n skipped.push(id);\n }\n }\n }\n\n return { patterns, promoted, skipped, journalsScanned: files.length };\n}\n\n/**\n * Normalize behavior text for fuzzy matching.\n * Lowercases, strips punctuation, collapses whitespace.\n */\nfunction normalizeBehavior(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * Convert a behavior string to a kebab-case ID.\n */\nfunction behaviorToId(behavior: string): string {\n return behavior\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .slice(0, 50)\n .replace(/-+$/, '');\n}\n\n// --- Dead Primitive Detection ---\n\nexport interface DeadPrimitive {\n id: string;\n path: string;\n directory: string;\n lastModified: string;\n daysSinceModified: number;\n reason: string;\n}\n\nexport interface DeadPrimitiveResult {\n dead: DeadPrimitive[];\n totalScanned: number;\n thresholdDays: number;\n}\n\n/**\n * Detect \"dead\" primitives — files that are:\n * 1. Orphaned (no incoming or outgoing references via related:/with:)\n * 2. Not modified in the last N days (default 30)\n *\n * Excludes session and journal directories (memory files).\n * Does NOT flag recently created primitives even if orphaned.\n */\nexport function detectDeadPrimitives(\n harnessDir: string,\n config?: HarnessConfig,\n options?: { thresholdDays?: number },\n): DeadPrimitiveResult {\n const thresholdDays = options?.thresholdDays ?? 30;\n const now = Date.now();\n const thresholdMs = thresholdDays * 24 * 60 * 60 * 1000;\n\n // Build dependency graph to find orphans\n const graph = buildDependencyGraph(harnessDir, config);\n const orphanIds = new Set(graph.orphans);\n\n // Also find nodes with only broken refs (effectively orphaned)\n const connectedIds = new Set<string>();\n for (const edge of graph.edges) {\n connectedIds.add(edge.from);\n connectedIds.add(edge.to);\n }\n\n const dead: DeadPrimitive[] = [];\n let totalScanned = 0;\n\n for (const node of graph.nodes) {\n totalScanned++;\n\n // Skip non-orphans\n if (!orphanIds.has(node.id)) continue;\n\n // Check file modification time\n const absPath = join(harnessDir, node.path);\n if (!existsSync(absPath)) continue;\n\n try {\n const stat = statSync(absPath);\n const mtime = stat.mtime.getTime();\n const daysSince = Math.floor((now - mtime) / (24 * 60 * 60 * 1000));\n\n if (daysSince >= thresholdDays) {\n dead.push({\n id: node.id,\n path: node.path,\n directory: node.directory,\n lastModified: stat.mtime.toISOString().split('T')[0],\n daysSinceModified: daysSince,\n reason: `Orphaned (no references) and not modified in ${daysSince} days`,\n });\n }\n } catch (err) {\n log.warn(`Failed to stat ${absPath}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n // Sort by days since modified (most stale first)\n dead.sort((a, b) => b.daysSinceModified - a.daysSinceModified);\n\n return { dead, totalScanned, thresholdDays };\n}\n\n// --- Contradiction Detection ---\n\nexport interface Contradiction {\n primitiveA: { id: string; path: string; type: string; text: string };\n primitiveB: { id: string; path: string; type: string; text: string };\n reason: string;\n severity: 'low' | 'medium' | 'high';\n}\n\nexport interface ContradictionResult {\n contradictions: Contradiction[];\n rulesChecked: number;\n instinctsChecked: number;\n}\n\n/**\n * Detect contradictions between rules and instincts.\n *\n * Checks for:\n * 1. Direct negation patterns (\"always X\" vs \"never X\", \"do X\" vs \"don't X\")\n * 2. Conflicting tag overlap with opposing behavioral signals\n * 3. Same topic with contradictory directives\n *\n * This is a heuristic-based detector (no LLM needed).\n * Returns candidate contradictions for human review.\n */\nexport function detectContradictions(\n harnessDir: string,\n): ContradictionResult {\n const rulesDir = join(harnessDir, 'rules');\n const instinctsDir = join(harnessDir, 'instincts');\n\n const rules: HarnessDocument[] = existsSync(rulesDir) ? loadDirectory(rulesDir) : [];\n const instincts: HarnessDocument[] = existsSync(instinctsDir) ? loadDirectory(instinctsDir) : [];\n\n const contradictions: Contradiction[] = [];\n\n // Build a lookup of behavioral directives from each document\n const ruleDirectives = rules.map((doc) => ({\n doc,\n directives: extractDirectives(doc),\n topics: extractTopics(doc),\n }));\n\n const instinctDirectives = instincts.map((doc) => ({\n doc,\n directives: extractDirectives(doc),\n topics: extractTopics(doc),\n }));\n\n // Cross-check rules vs instincts\n for (const rule of ruleDirectives) {\n for (const instinct of instinctDirectives) {\n // Check directive negation patterns\n for (const rd of rule.directives) {\n for (const id of instinct.directives) {\n const negation = checkNegation(rd, id);\n if (negation) {\n contradictions.push({\n primitiveA: {\n id: rule.doc.frontmatter.id,\n path: relative(harnessDir, rule.doc.path),\n type: 'rule',\n text: rd.raw,\n },\n primitiveB: {\n id: instinct.doc.frontmatter.id,\n path: relative(harnessDir, instinct.doc.path),\n type: 'instinct',\n text: id.raw,\n },\n reason: negation,\n severity: 'high',\n });\n }\n }\n }\n\n // Check topic conflicts (same topic, opposing signals)\n const sharedTopics = rule.topics.filter((t) => instinct.topics.includes(t));\n if (sharedTopics.length > 0) {\n // Check if one says \"always\" and other says \"never\" about shared topic\n const ruleText = (rule.doc.l0 + ' ' + rule.doc.body).toLowerCase();\n const instinctText = (instinct.doc.l0 + ' ' + instinct.doc.body).toLowerCase();\n\n for (const topic of sharedTopics) {\n const ruleHasAlways = hasPositiveDirective(ruleText, topic);\n const instinctHasNever = hasNegativeDirective(instinctText, topic);\n const ruleHasNever = hasNegativeDirective(ruleText, topic);\n const instinctHasAlways = hasPositiveDirective(instinctText, topic);\n\n if ((ruleHasAlways && instinctHasNever) || (ruleHasNever && instinctHasAlways)) {\n // Avoid duplicate if already caught by directive check\n const alreadyCaught = contradictions.some(\n (c) =>\n c.primitiveA.id === rule.doc.frontmatter.id &&\n c.primitiveB.id === instinct.doc.frontmatter.id,\n );\n if (!alreadyCaught) {\n contradictions.push({\n primitiveA: {\n id: rule.doc.frontmatter.id,\n path: relative(harnessDir, rule.doc.path),\n type: 'rule',\n text: rule.doc.l0 || rule.doc.frontmatter.id,\n },\n primitiveB: {\n id: instinct.doc.frontmatter.id,\n path: relative(harnessDir, instinct.doc.path),\n type: 'instinct',\n text: instinct.doc.l0 || instinct.doc.frontmatter.id,\n },\n reason: `Conflicting directives about \"${topic}\"`,\n severity: 'medium',\n });\n }\n }\n }\n }\n }\n }\n\n // Also check rules vs rules and instincts vs instincts\n checkIntraGroupContradictions(ruleDirectives, 'rule', harnessDir, contradictions);\n checkIntraGroupContradictions(instinctDirectives, 'instinct', harnessDir, contradictions);\n\n return {\n contradictions,\n rulesChecked: rules.length,\n instinctsChecked: instincts.length,\n };\n}\n\ninterface Directive {\n action: 'positive' | 'negative';\n verb: string;\n subject: string;\n raw: string;\n}\n\n/**\n * Extract behavioral directives from a document.\n * Looks for patterns like \"always X\", \"never Y\", \"do X\", \"don't Y\", \"avoid X\", \"prefer Y\".\n */\nfunction extractDirectives(doc: HarnessDocument): Directive[] {\n const directives: Directive[] = [];\n const text = (doc.l0 + '\\n' + doc.body).trim();\n\n // Process line by line\n for (const line of text.split('\\n')) {\n const trimmed = line.trim().toLowerCase();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n // Strip list markers\n const cleaned = trimmed.replace(/^[-*]\\s+/, '').replace(/^\\d+\\.\\s+/, '');\n\n // Positive patterns\n const positiveMatch = cleaned.match(\n /^(always|must|should|prefer|ensure|require|use)\\s+(.+)/,\n );\n if (positiveMatch) {\n directives.push({\n action: 'positive',\n verb: positiveMatch[1],\n subject: positiveMatch[2].replace(/[.!]$/, ''),\n raw: cleaned,\n });\n continue;\n }\n\n // Negative patterns\n const negativeMatch = cleaned.match(\n /^(never|don'?t|avoid|do not|must not|should not|shouldn'?t)\\s+(.+)/,\n );\n if (negativeMatch) {\n directives.push({\n action: 'negative',\n verb: negativeMatch[1],\n subject: negativeMatch[2].replace(/[.!]$/, ''),\n raw: cleaned,\n });\n }\n }\n\n return directives;\n}\n\n/**\n * Extract topic keywords from a document (from tags, ID, and L0).\n */\nfunction extractTopics(doc: HarnessDocument): string[] {\n const topics: string[] = [];\n\n // Tags as topics\n for (const tag of doc.frontmatter.tags) {\n topics.push(tag.toLowerCase());\n }\n\n // ID words as topics\n const idParts = doc.frontmatter.id.split('-').filter((p) => p.length > 2);\n topics.push(...idParts.map((p) => p.toLowerCase()));\n\n return [...new Set(topics)];\n}\n\n/**\n * Check if two directives are negations of each other.\n */\nfunction checkNegation(a: Directive, b: Directive): string | null {\n // One positive, one negative\n if (a.action === b.action) return null;\n\n // Normalize subjects for comparison\n const subA = a.subject.toLowerCase().replace(/\\s+/g, ' ').trim();\n const subB = b.subject.toLowerCase().replace(/\\s+/g, ' ').trim();\n\n // Direct subject match\n if (subA === subB) {\n return `Direct contradiction: \"${a.raw}\" vs \"${b.raw}\"`;\n }\n\n // Fuzzy match: check if one subject is a substring of the other (with word boundaries)\n const wordsA = subA.split(' ').filter((w) => w.length > 3);\n const wordsB = subB.split(' ').filter((w) => w.length > 3);\n const overlap = wordsA.filter((w) => wordsB.includes(w));\n\n if (overlap.length >= 2 && overlap.length >= Math.min(wordsA.length, wordsB.length) * 0.6) {\n return `Likely contradiction (shared terms: ${overlap.join(', ')}): \"${a.raw}\" vs \"${b.raw}\"`;\n }\n\n return null;\n}\n\nfunction hasPositiveDirective(text: string, topic: string): boolean {\n const patterns = [\n new RegExp(`always\\\\s+\\\\w*${topic}`, 'i'),\n new RegExp(`must\\\\s+\\\\w*${topic}`, 'i'),\n new RegExp(`should\\\\s+\\\\w*${topic}`, 'i'),\n new RegExp(`prefer\\\\s+\\\\w*${topic}`, 'i'),\n new RegExp(`use\\\\s+\\\\w*${topic}`, 'i'),\n ];\n return patterns.some((p) => p.test(text));\n}\n\nfunction hasNegativeDirective(text: string, topic: string): boolean {\n const patterns = [\n new RegExp(`never\\\\s+\\\\w*${topic}`, 'i'),\n new RegExp(`avoid\\\\s+\\\\w*${topic}`, 'i'),\n new RegExp(`don'?t\\\\s+\\\\w*${topic}`, 'i'),\n new RegExp(`do not\\\\s+\\\\w*${topic}`, 'i'),\n ];\n return patterns.some((p) => p.test(text));\n}\n\nfunction checkIntraGroupContradictions(\n group: Array<{ doc: HarnessDocument; directives: Directive[]; topics: string[] }>,\n type: string,\n harnessDir: string,\n contradictions: Contradiction[],\n): void {\n for (let i = 0; i < group.length; i++) {\n for (let j = i + 1; j < group.length; j++) {\n const a = group[i];\n const b = group[j];\n\n for (const da of a.directives) {\n for (const db of b.directives) {\n const negation = checkNegation(da, db);\n if (negation) {\n contradictions.push({\n primitiveA: {\n id: a.doc.frontmatter.id,\n path: relative(harnessDir, a.doc.path),\n type,\n text: da.raw,\n },\n primitiveB: {\n id: b.doc.frontmatter.id,\n path: relative(harnessDir, b.doc.path),\n type,\n text: db.raw,\n },\n reason: negation,\n severity: 'medium',\n });\n }\n }\n }\n }\n }\n}\n\n// --- Session Enrichment ---\n\nexport interface SessionEnrichment {\n sessionId: string;\n topics: string[];\n tokenCount: number;\n stepCount: number;\n model: string;\n toolsUsed: string[];\n primitivesReferenced: string[];\n duration: string;\n}\n\nexport interface EnrichmentResult {\n enriched: SessionEnrichment[];\n sessionsScanned: number;\n}\n\n/**\n * Enrich sessions with extracted metadata.\n *\n * Scans session files and extracts:\n * - Topics (from prompt text, frequent nouns, matched primitive IDs)\n * - Token/step counts (from frontmatter or markdown body)\n * - Model used\n * - Tools used (from tool call sections)\n * - Referenced primitives (IDs mentioned in session text)\n * - Duration\n */\nexport function enrichSessions(\n harnessDir: string,\n config?: HarnessConfig,\n options?: { from?: string; to?: string },\n): EnrichmentResult {\n const sessionsDir = join(harnessDir, 'memory', 'sessions');\n if (!existsSync(sessionsDir)) {\n return { enriched: [], sessionsScanned: 0 };\n }\n\n // Load all primitive IDs for cross-reference\n const primitiveIds = new Set<string>();\n const dirs = getPrimitiveDirs(config);\n for (const dir of dirs) {\n const fullPath = join(harnessDir, dir);\n if (!existsSync(fullPath)) continue;\n const { docs } = loadDirectoryWithErrors(fullPath);\n for (const doc of docs) {\n primitiveIds.add(doc.frontmatter.id);\n }\n }\n\n const files = readdirSync(sessionsDir)\n .filter((f) => f.endsWith('.md') && !f.startsWith('.') && !f.startsWith('_'))\n .sort();\n\n // Filter by date range\n const filtered = files.filter((f) => {\n if (!options?.from && !options?.to) return true;\n const dateMatch = f.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (!dateMatch) return false;\n const d = dateMatch[1];\n if (options?.from && d < options.from) return false;\n if (options?.to && d > options.to) return false;\n return true;\n });\n\n const enriched: SessionEnrichment[] = [];\n\n for (const file of filtered) {\n const content = readFileSync(join(sessionsDir, file), 'utf-8');\n const sessionId = file.replace(/\\.md$/, '');\n\n const enrichment = enrichSession(content, sessionId, primitiveIds);\n enriched.push(enrichment);\n }\n\n return { enriched, sessionsScanned: filtered.length };\n}\n\nfunction enrichSession(\n content: string,\n sessionId: string,\n primitiveIds: Set<string>,\n): SessionEnrichment {\n // Extract metadata from frontmatter/body\n const tokensMatch = content.match(/[Tt]okens?[:\\s]+(\\d[\\d,]*)/);\n const tokenCount = tokensMatch ? parseInt(tokensMatch[1].replace(/,/g, ''), 10) : 0;\n\n const stepsMatch = content.match(/[Ss]teps?[:\\s]+(\\d+)/);\n const stepCount = stepsMatch ? parseInt(stepsMatch[1], 10) : 0;\n\n const modelMatch = content.match(/[Mm]odel[:\\s]+([^\\n]+)/);\n const model = modelMatch ? modelMatch[1].trim() : 'unknown';\n\n const durationMatch = content.match(/[Dd]uration[:\\s]+([^\\n]+)/);\n const duration = durationMatch ? durationMatch[1].trim() : '';\n\n // Extract tools used from tool call sections\n const toolsUsed: string[] = [];\n const toolMatches = content.matchAll(/### Tool(?:\\s+Call)?:\\s*(\\S+)/g);\n for (const match of toolMatches) {\n const toolName = match[1];\n if (!toolsUsed.includes(toolName)) {\n toolsUsed.push(toolName);\n }\n }\n\n // Also check for tool_calls in frontmatter-style sections\n const toolCallMatches = content.matchAll(/toolName[:\\s]+[\"']?(\\S+)[\"']?/g);\n for (const match of toolCallMatches) {\n const toolName = match[1];\n if (!toolsUsed.includes(toolName)) {\n toolsUsed.push(toolName);\n }\n }\n\n // Find referenced primitives (any primitive ID that appears in text)\n const primitivesReferenced: string[] = [];\n for (const id of primitiveIds) {\n if (id.length < 3) continue; // Skip very short IDs to avoid false positives\n if (content.includes(id)) {\n primitivesReferenced.push(id);\n }\n }\n\n // Extract topics from prompt section\n const topics = extractSessionTopics(content);\n\n return {\n sessionId,\n topics,\n tokenCount,\n stepCount,\n model,\n toolsUsed,\n primitivesReferenced,\n duration,\n };\n}\n\n/**\n * Extract topic keywords from session content.\n * Uses a simple frequency-based approach on meaningful words.\n */\nfunction extractSessionTopics(content: string): string[] {\n // Extract prompt section specifically\n const promptMatch = content.match(/## Prompt\\n([\\s\\S]*?)(?=\\n## |$)/);\n const promptText = promptMatch ? promptMatch[1] : '';\n\n // Also include summary\n const summaryMatch = content.match(/## Summary\\n([\\s\\S]*?)(?=\\n## |$)/);\n const summaryText = summaryMatch ? summaryMatch[1] : '';\n\n const text = (promptText + ' ' + summaryText).toLowerCase();\n\n // Common stop words to filter out\n const stopWords = new Set([\n 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',\n 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',\n 'should', 'may', 'might', 'shall', 'can', 'need', 'must', 'to', 'of',\n 'in', 'for', 'on', 'with', 'at', 'by', 'from', 'as', 'into', 'about',\n 'like', 'through', 'after', 'before', 'between', 'under', 'during',\n 'and', 'or', 'but', 'not', 'no', 'nor', 'so', 'yet', 'both', 'either',\n 'neither', 'each', 'every', 'all', 'any', 'few', 'more', 'most', 'other',\n 'some', 'such', 'than', 'too', 'very', 'just', 'also', 'this', 'that',\n 'these', 'those', 'it', 'its', 'i', 'me', 'my', 'we', 'our', 'you',\n 'your', 'he', 'she', 'they', 'them', 'their', 'what', 'which', 'who',\n 'when', 'where', 'how', 'why', 'if', 'then', 'else', 'while', 'up',\n 'out', 'off', 'over', 'only', 'own', 'same', 'get', 'got', 'make',\n 'made', 'use', 'used', 'using', 'one', 'two', 'new',\n ]);\n\n // Count word frequencies\n const words = text\n .replace(/[^a-z0-9\\s-]/g, '')\n .split(/\\s+/)\n .filter((w) => w.length > 3 && !stopWords.has(w));\n\n const freq = new Map<string, number>();\n for (const word of words) {\n freq.set(word, (freq.get(word) ?? 0) + 1);\n }\n\n // Return top 5 most frequent meaningful words\n return Array.from(freq.entries())\n .filter(([, count]) => count >= 1)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([word]) => word);\n}\n\n// --- Capability Suggestions ---\n\nexport interface CapabilitySuggestion {\n topic: string;\n frequency: number;\n sessionDates: string[];\n suggestion: string;\n suggestedType: 'skill' | 'playbook';\n}\n\nexport interface CapabilitySuggestionResult {\n suggestions: CapabilitySuggestion[];\n topicsAnalyzed: number;\n sessionsScanned: number;\n}\n\n/**\n * Suggest capabilities (skills/playbooks) for frequent session topics\n * that don't have existing coverage.\n *\n * Scans sessions for recurring topics, cross-references against existing\n * skills/playbooks, and suggests new ones for uncovered topics.\n */\nexport function suggestCapabilities(\n harnessDir: string,\n config?: HarnessConfig,\n options?: { minFrequency?: number },\n): CapabilitySuggestionResult {\n const minFrequency = options?.minFrequency ?? 3;\n\n // Enrich sessions to get topics\n const { enriched, sessionsScanned } = enrichSessions(harnessDir, config);\n\n // Collect topic frequency across sessions\n const topicOccurrences = new Map<string, Set<string>>();\n for (const session of enriched) {\n const dateMatch = session.sessionId.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n const date = dateMatch ? dateMatch[1] : session.sessionId;\n\n for (const topic of session.topics) {\n if (!topicOccurrences.has(topic)) {\n topicOccurrences.set(topic, new Set());\n }\n topicOccurrences.get(topic)!.add(date);\n }\n }\n\n // Load existing skills and playbooks\n const coveredTopics = new Set<string>();\n const skillsDir = join(harnessDir, 'skills');\n const playbooksDir = join(harnessDir, 'playbooks');\n\n for (const dir of [skillsDir, playbooksDir]) {\n if (!existsSync(dir)) continue;\n const docs = loadDirectory(dir);\n for (const doc of docs) {\n // Add ID parts as covered topics\n for (const part of doc.frontmatter.id.split('-')) {\n if (part.length > 2) coveredTopics.add(part.toLowerCase());\n }\n // Add tags as covered topics\n for (const tag of doc.frontmatter.tags) {\n coveredTopics.add(tag.toLowerCase());\n }\n }\n }\n\n // Find frequent uncovered topics\n const suggestions: CapabilitySuggestion[] = [];\n\n for (const [topic, dates] of topicOccurrences) {\n if (dates.size < minFrequency) continue;\n if (coveredTopics.has(topic)) continue;\n\n const suggestedType = dates.size >= 5 ? 'playbook' : 'skill';\n suggestions.push({\n topic,\n frequency: dates.size,\n sessionDates: [...dates].sort(),\n suggestion: `Create a ${suggestedType} for \"${topic}\" — appeared in ${dates.size} session(s)`,\n suggestedType,\n });\n }\n\n // Sort by frequency\n suggestions.sort((a, b) => b.frequency - a.frequency);\n\n return {\n suggestions,\n topicsAnalyzed: topicOccurrences.size,\n sessionsScanned,\n };\n}\n\n// --- Failure Taxonomy ---\n\n/**\n * Named failure modes with recovery strategies.\n * Based on common agent failure patterns (context overflow, tool errors,\n * budget exhaustion, hallucination, stale primitives, circular delegation).\n */\nexport type FailureMode =\n | 'context_overflow'\n | 'tool_execution_error'\n | 'budget_exhausted'\n | 'rate_limited'\n | 'llm_timeout'\n | 'llm_error'\n | 'hallucination_detected'\n | 'stale_primitive'\n | 'circular_delegation'\n | 'missing_dependency'\n | 'parse_error'\n | 'config_invalid'\n | 'mcp_connection_failed'\n | 'state_corruption'\n | 'unknown';\n\nexport interface FailureRecord {\n mode: FailureMode;\n timestamp: string;\n sessionId?: string;\n message: string;\n context?: Record<string, unknown>;\n recoveryAttempted?: string;\n recovered: boolean;\n}\n\nexport interface FailureTaxonomy {\n modes: Record<FailureMode, {\n description: string;\n severity: 'low' | 'medium' | 'high' | 'critical';\n recoveryStrategies: string[];\n autoRecoverable: boolean;\n }>;\n}\n\n/**\n * The canonical failure taxonomy for agent-harness.\n * Each mode has a description, severity level, recovery strategies,\n * and whether automatic recovery is possible.\n */\nexport const FAILURE_TAXONOMY: FailureTaxonomy = {\n modes: {\n context_overflow: {\n description: 'System prompt + conversation exceeds model context window',\n severity: 'high',\n recoveryStrategies: [\n 'Trim oldest messages from conversation history',\n 'Reduce primitive loading level (L2 → L1 → L0)',\n 'Archive old sessions to free memory budget',\n 'Split into sub-conversations with summarized context',\n ],\n autoRecoverable: true,\n },\n tool_execution_error: {\n description: 'An MCP or HTTP tool call failed during execution',\n severity: 'medium',\n recoveryStrategies: [\n 'Retry with exponential backoff',\n 'Fall back to alternative tool if available',\n 'Report error to LLM and ask for alternative approach',\n 'Skip tool and proceed with available context',\n ],\n autoRecoverable: true,\n },\n budget_exhausted: {\n description: 'Daily or monthly spending limit has been reached',\n severity: 'critical',\n recoveryStrategies: [\n 'Wait until next budget period',\n 'Switch to cheaper model (fast_model or summary_model)',\n 'Queue non-urgent tasks for later execution',\n 'Alert operator to increase budget',\n ],\n autoRecoverable: false,\n },\n rate_limited: {\n description: 'LLM API rate limit hit (per-minute/hour/day)',\n severity: 'medium',\n recoveryStrategies: [\n 'Wait for retryAfterMs from rate limiter',\n 'Reduce request frequency',\n 'Queue and batch requests',\n ],\n autoRecoverable: true,\n },\n llm_timeout: {\n description: 'LLM API call timed out without response',\n severity: 'medium',\n recoveryStrategies: [\n 'Retry with same prompt',\n 'Retry with shorter prompt (reduce context)',\n 'Switch to faster model',\n 'Increase timeout_ms in config',\n ],\n autoRecoverable: true,\n },\n llm_error: {\n description: 'LLM API returned an error response (4xx/5xx)',\n severity: 'high',\n recoveryStrategies: [\n 'Retry with exponential backoff (max_retries in config)',\n 'Switch to fallback model',\n 'Check API key validity',\n 'Log error details for debugging',\n ],\n autoRecoverable: true,\n },\n hallucination_detected: {\n description: 'LLM output contains fabricated facts or references to non-existent primitives',\n severity: 'medium',\n recoveryStrategies: [\n 'Re-prompt with explicit grounding: \"Only reference primitives that exist\"',\n 'Validate output against known primitive IDs',\n 'Add validation step before acting on LLM output',\n 'Record in journal for future training',\n ],\n autoRecoverable: false,\n },\n stale_primitive: {\n description: 'A referenced primitive is outdated, deprecated, or orphaned',\n severity: 'low',\n recoveryStrategies: [\n 'Run detectDeadPrimitives() to identify stale files',\n 'Archive deprecated primitives',\n 'Update references to point to current versions',\n 'Auto-flag via validator',\n ],\n autoRecoverable: true,\n },\n circular_delegation: {\n description: 'Agent delegation loop detected (A delegates to B delegates to A)',\n severity: 'high',\n recoveryStrategies: [\n 'Track delegation chain and break on cycle detection',\n 'Set max delegation depth (default: 3)',\n 'Return partial result from last agent in chain',\n 'Log delegation graph for debugging',\n ],\n autoRecoverable: true,\n },\n missing_dependency: {\n description: 'A required dependency (primitive, MCP server, API key) is missing',\n severity: 'high',\n recoveryStrategies: [\n 'Run doctorHarness() to auto-fix missing files',\n 'Check .env for required API keys',\n 'Install missing MCP servers',\n 'Prompt user to install missing bundle',\n ],\n autoRecoverable: false,\n },\n parse_error: {\n description: 'A primitive file has invalid YAML frontmatter or malformed content',\n severity: 'medium',\n recoveryStrategies: [\n 'Run fixCapability() to auto-repair frontmatter',\n 'Skip the malformed file and log a warning',\n 'Use default frontmatter values',\n 'Report to user for manual fix',\n ],\n autoRecoverable: true,\n },\n config_invalid: {\n description: 'config.yaml fails schema validation',\n severity: 'critical',\n recoveryStrategies: [\n 'Fall back to CONFIG_DEFAULTS',\n 'Report specific validation errors to user',\n 'Run harness doctor to attempt repair',\n ],\n autoRecoverable: false,\n },\n mcp_connection_failed: {\n description: 'Failed to connect to an MCP server (process spawn or HTTP)',\n severity: 'medium',\n recoveryStrategies: [\n 'Retry connection with backoff',\n 'Disable the server and continue without its tools',\n 'Check command/URL/env configuration',\n 'Fall back to built-in tools only',\n ],\n autoRecoverable: true,\n },\n state_corruption: {\n description: 'state.md is unreadable or contains invalid data',\n severity: 'high',\n recoveryStrategies: [\n 'Fall back to DEFAULT_STATE',\n 'Rebuild state from session history',\n 'Reset state.md and log the event',\n ],\n autoRecoverable: true,\n },\n unknown: {\n description: 'An unclassified error occurred',\n severity: 'high',\n recoveryStrategies: [\n 'Log full error with stack trace',\n 'Record in health.json failure counter',\n 'Alert operator',\n 'Graceful shutdown if critical path',\n ],\n autoRecoverable: false,\n },\n },\n};\n\nexport interface FailureAnalysis {\n recentFailures: FailureRecord[];\n modeFrequency: Record<string, number>;\n mostCommonMode: FailureMode | null;\n suggestedRecovery: string[];\n healthImplication: 'healthy' | 'degraded' | 'unhealthy';\n}\n\n/**\n * Classify an error into a failure mode.\n */\nexport function classifyFailure(error: Error | string, context?: Record<string, unknown>): FailureMode {\n const msg = typeof error === 'string' ? error.toLowerCase() : error.message.toLowerCase();\n\n if (msg.includes('context') && (msg.includes('overflow') || msg.includes('too long') || msg.includes('exceed'))) {\n return 'context_overflow';\n }\n if (msg.includes('tool') && (msg.includes('fail') || msg.includes('error') || msg.includes('timeout'))) {\n return 'tool_execution_error';\n }\n if (msg.includes('budget') || msg.includes('spending') || msg.includes('limit exceeded')) {\n return 'budget_exhausted';\n }\n if (msg.includes('rate limit') || msg.includes('429') || msg.includes('too many requests')) {\n return 'rate_limited';\n }\n if (msg.includes('timeout') || msg.includes('timed out') || msg.includes('ETIMEDOUT')) {\n return 'llm_timeout';\n }\n if (msg.includes('mcp') && (msg.includes('connect') || msg.includes('spawn') || msg.includes('failed'))) {\n return 'mcp_connection_failed';\n }\n if (msg.includes('parse') || msg.includes('yaml') || msg.includes('frontmatter') || msg.includes('malformed')) {\n return 'parse_error';\n }\n if (msg.includes('config') && (msg.includes('invalid') || msg.includes('validation'))) {\n return 'config_invalid';\n }\n if (msg.includes('state') && (msg.includes('corrupt') || msg.includes('invalid') || msg.includes('unreadable'))) {\n return 'state_corruption';\n }\n if (msg.includes('circular') || msg.includes('delegation loop') || msg.includes('cycle')) {\n return 'circular_delegation';\n }\n if (msg.includes('missing') || msg.includes('not found') || msg.includes('dependency')) {\n return 'missing_dependency';\n }\n if (msg.includes('401') || msg.includes('403') || msg.includes('500') || msg.includes('502') || msg.includes('503')) {\n return 'llm_error';\n }\n\n return 'unknown';\n}\n\n/**\n * Get recovery strategies for a failure mode.\n */\nexport function getRecoveryStrategies(mode: FailureMode): string[] {\n return FAILURE_TAXONOMY.modes[mode]?.recoveryStrategies ?? ['Log error and alert operator'];\n}\n\n/**\n * Analyze failure patterns from session history and health data.\n * Returns frequency analysis and recovery suggestions.\n */\nexport function analyzeFailures(\n harnessDir: string,\n options?: { days?: number },\n): FailureAnalysis {\n const days = options?.days ?? 7;\n const now = Date.now();\n const cutoffMs = days * 24 * 60 * 60 * 1000;\n\n const recentFailures: FailureRecord[] = [];\n\n // Scan health.json for failures\n const healthPath = join(harnessDir, 'memory', 'health.json');\n if (existsSync(healthPath)) {\n try {\n const health = JSON.parse(readFileSync(healthPath, 'utf-8'));\n if (health.lastError) {\n const mode = classifyFailure(health.lastError);\n recentFailures.push({\n mode,\n timestamp: health.lastFailure || new Date().toISOString(),\n message: health.lastError,\n recovered: health.consecutiveFailures === 0,\n });\n }\n } catch {\n // Malformed health.json\n }\n }\n\n // Scan sessions for error indicators\n const sessionsDir = join(harnessDir, 'memory', 'sessions');\n if (existsSync(sessionsDir)) {\n const files = readdirSync(sessionsDir)\n .filter((f) => f.endsWith('.md') && !f.startsWith('.'))\n .sort()\n .reverse();\n\n for (const file of files) {\n const dateMatch = file.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (dateMatch) {\n const fileDate = new Date(dateMatch[1]).getTime();\n if (now - fileDate > cutoffMs) break;\n }\n\n try {\n const content = readFileSync(join(sessionsDir, file), 'utf-8');\n // Look for error patterns in session content\n const errorLines = content.split('\\n').filter((l) =>\n l.toLowerCase().includes('error') ||\n l.toLowerCase().includes('failed') ||\n l.toLowerCase().includes('timeout'),\n );\n\n for (const line of errorLines.slice(0, 3)) {\n const mode = classifyFailure(line);\n if (mode !== 'unknown') {\n recentFailures.push({\n mode,\n timestamp: dateMatch?.[1] ?? 'unknown',\n sessionId: file.replace('.md', ''),\n message: line.trim().slice(0, 200),\n recovered: true,\n });\n }\n }\n } catch {\n // Skip unreadable sessions\n }\n }\n }\n\n // Calculate frequency\n const modeFrequency: Record<string, number> = {};\n for (const f of recentFailures) {\n modeFrequency[f.mode] = (modeFrequency[f.mode] ?? 0) + 1;\n }\n\n // Find most common mode\n let mostCommonMode: FailureMode | null = null;\n let maxFreq = 0;\n for (const [mode, count] of Object.entries(modeFrequency)) {\n if (count > maxFreq) {\n maxFreq = count;\n mostCommonMode = mode as FailureMode;\n }\n }\n\n // Suggest recovery\n const suggestedRecovery = mostCommonMode\n ? getRecoveryStrategies(mostCommonMode)\n : [];\n\n // Determine health implication\n let healthImplication: 'healthy' | 'degraded' | 'unhealthy' = 'healthy';\n if (recentFailures.length > 5) {\n healthImplication = 'unhealthy';\n } else if (recentFailures.length > 0) {\n healthImplication = 'degraded';\n }\n\n return {\n recentFailures: recentFailures.slice(0, 20),\n modeFrequency,\n mostCommonMode,\n suggestedRecovery,\n healthImplication,\n };\n}\n\n// --- Verification Gates ---\n\nexport type GateStatus = 'pass' | 'fail' | 'warn' | 'skip';\n\nexport interface GateCheck {\n name: string;\n description: string;\n status: GateStatus;\n message: string;\n details?: Record<string, unknown>;\n}\n\nexport interface VerificationGateResult {\n gateName: string;\n passed: boolean;\n checks: GateCheck[];\n summary: string;\n}\n\nexport type GateDefinition = {\n name: string;\n description: string;\n check: (harnessDir: string, config?: HarnessConfig) => GateCheck[];\n};\n\n/**\n * Built-in verification gates for the harness.\n * Each gate is a set of checks that must pass at a specific stage.\n */\nexport const BUILTIN_GATES: GateDefinition[] = [\n {\n name: 'pre-boot',\n description: 'Checks before agent boot: config valid, CORE.md exists, API key available',\n check: (harnessDir: string) => {\n const checks: GateCheck[] = [];\n\n // CORE.md exists\n checks.push(existsSync(join(harnessDir, 'CORE.md'))\n ? { name: 'core-md', description: 'CORE.md exists', status: 'pass', message: 'CORE.md present' }\n : { name: 'core-md', description: 'CORE.md exists', status: 'fail', message: 'Missing CORE.md — required for agent identity' });\n\n // Config valid\n try {\n loadConfig(harnessDir);\n checks.push({ name: 'config-valid', description: 'config.yaml valid', status: 'pass', message: 'Config parsed successfully' });\n } catch (err) {\n checks.push({ name: 'config-valid', description: 'config.yaml valid', status: 'fail', message: `Config error: ${err instanceof Error ? err.message : String(err)}` });\n }\n\n // API key available\n const hasKey = !!(process.env.OPENROUTER_API_KEY || process.env.OPENAI_API_KEY || process.env.ANTHROPIC_API_KEY);\n checks.push(hasKey\n ? { name: 'api-key', description: 'API key available', status: 'pass', message: 'API key found in environment' }\n : { name: 'api-key', description: 'API key available', status: 'warn', message: 'No API key in environment — will need --api-key flag' });\n\n // Memory directory\n const memDir = join(harnessDir, 'memory');\n checks.push(existsSync(memDir)\n ? { name: 'memory-dir', description: 'Memory directory exists', status: 'pass', message: 'memory/ directory present' }\n : { name: 'memory-dir', description: 'Memory directory exists', status: 'warn', message: 'memory/ directory missing — will be created on first run' });\n\n return checks;\n },\n },\n {\n name: 'pre-run',\n description: 'Checks before each LLM call: budget, rate limits, context budget',\n check: (harnessDir: string) => {\n const checks: GateCheck[] = [];\n\n let config: HarnessConfig;\n try {\n config = loadConfig(harnessDir);\n } catch {\n checks.push({ name: 'config-load', description: 'Config loadable', status: 'fail', message: 'Cannot load config' });\n return checks;\n }\n\n // Budget check\n try {\n const budgetStatus = checkBudget(harnessDir, config.budget);\n const exceeded = (budgetStatus.daily_remaining_usd !== null && budgetStatus.daily_remaining_usd <= 0) ||\n (budgetStatus.monthly_remaining_usd !== null && budgetStatus.monthly_remaining_usd <= 0);\n if (exceeded) {\n checks.push({ name: 'budget', description: 'Budget not exceeded', status: 'fail', message: 'Budget limit exceeded', details: { ...budgetStatus } });\n } else {\n checks.push({ name: 'budget', description: 'Budget not exceeded', status: 'pass', message: 'Within budget' });\n }\n } catch (err) {\n checks.push({ name: 'budget', description: 'Budget not exceeded', status: 'skip', message: `Budget check unavailable: ${err instanceof Error ? err.message : String(err)}` });\n }\n\n // Rate limit check\n try {\n const limits = buildRateLimits(config);\n if (limits.length === 0) {\n checks.push({ name: 'rate-limit', description: 'Rate limit not hit', status: 'pass', message: 'No rate limits configured' });\n } else {\n let blocked = false;\n for (const limit of limits) {\n const rateCheck = checkRateLimit(harnessDir, limit);\n if (!rateCheck.allowed) {\n const windowLabel = limit.window_ms <= 60_000 ? 'minute' : limit.window_ms <= 3_600_000 ? 'hour' : 'day';\n checks.push({ name: 'rate-limit', description: 'Rate limit not hit', status: 'fail', message: `Rate limited (${windowLabel}): ${rateCheck.current}/${rateCheck.max}. Retry after ${Math.ceil(rateCheck.retry_after_ms / 1000)}s` });\n blocked = true;\n break;\n }\n }\n if (!blocked) {\n checks.push({ name: 'rate-limit', description: 'Rate limit not hit', status: 'pass', message: 'Within rate limits' });\n }\n }\n } catch (err) {\n checks.push({ name: 'rate-limit', description: 'Rate limit not hit', status: 'skip', message: `Rate limit check unavailable: ${err instanceof Error ? err.message : String(err)}` });\n }\n\n // Health check\n const healthPath = join(harnessDir, 'memory', 'health.json');\n if (existsSync(healthPath)) {\n try {\n const health = JSON.parse(readFileSync(healthPath, 'utf-8'));\n if (health.consecutiveFailures >= 3) {\n checks.push({ name: 'health', description: 'Agent healthy', status: 'warn', message: `${health.consecutiveFailures} consecutive failures detected` });\n } else {\n checks.push({ name: 'health', description: 'Agent healthy', status: 'pass', message: 'No recent failure pattern' });\n }\n } catch {\n checks.push({ name: 'health', description: 'Agent healthy', status: 'skip', message: 'Health data unavailable' });\n }\n }\n\n return checks;\n },\n },\n {\n name: 'post-session',\n description: 'Checks after a session: session recorded, no parse errors, primitives intact',\n check: (harnessDir: string) => {\n const checks: GateCheck[] = [];\n\n // Sessions directory exists and has files\n const sessionsDir = join(harnessDir, 'memory', 'sessions');\n if (existsSync(sessionsDir)) {\n const files = readdirSync(sessionsDir).filter((f) => f.endsWith('.md') && !f.startsWith('.'));\n checks.push({\n name: 'sessions-recorded',\n description: 'Sessions being recorded',\n status: files.length > 0 ? 'pass' : 'warn',\n message: `${files.length} session file(s) in memory`,\n });\n } else {\n checks.push({ name: 'sessions-recorded', description: 'Sessions being recorded', status: 'warn', message: 'No sessions directory' });\n }\n\n // Check for parse errors in primitives\n const dirs = getPrimitiveDirs();\n let totalParseErrors = 0;\n for (const dir of dirs) {\n const fullPath = join(harnessDir, dir);\n if (!existsSync(fullPath)) continue;\n const { errors } = loadDirectoryWithErrors(fullPath);\n totalParseErrors += errors.length;\n }\n\n checks.push(totalParseErrors === 0\n ? { name: 'parse-errors', description: 'No primitive parse errors', status: 'pass', message: 'All primitives parse cleanly' }\n : { name: 'parse-errors', description: 'No primitive parse errors', status: 'warn', message: `${totalParseErrors} parse error(s) in primitives` });\n\n return checks;\n },\n },\n {\n name: 'pre-deploy',\n description: 'Checks before deployment: validator passes, no dead primitives, no contradictions',\n check: (harnessDir: string, config?: HarnessConfig) => {\n const checks: GateCheck[] = [];\n\n // Run validator\n try {\n const validation = validateHarness(harnessDir);\n if (validation.errors.length > 0) {\n checks.push({ name: 'validator', description: 'Validator passes', status: 'fail', message: `${validation.errors.length} error(s)`, details: { errors: validation.errors } });\n } else if (validation.warnings.length > 0) {\n checks.push({ name: 'validator', description: 'Validator passes', status: 'warn', message: `${validation.warnings.length} warning(s)` });\n } else {\n checks.push({ name: 'validator', description: 'Validator passes', status: 'pass', message: 'Validation clean' });\n }\n } catch (err) {\n checks.push({ name: 'validator', description: 'Validator passes', status: 'fail', message: `Validator error: ${err instanceof Error ? err.message : String(err)}` });\n }\n\n // Check for dead primitives\n const deadResult = detectDeadPrimitives(harnessDir, config);\n checks.push(deadResult.dead.length === 0\n ? { name: 'dead-primitives', description: 'No dead primitives', status: 'pass', message: 'All primitives referenced or recently modified' }\n : { name: 'dead-primitives', description: 'No dead primitives', status: 'warn', message: `${deadResult.dead.length} dead primitive(s) found`, details: { dead: deadResult.dead.map((d) => d.id) } });\n\n // Check for contradictions\n const contradictionResult = detectContradictions(harnessDir);\n checks.push(contradictionResult.contradictions.length === 0\n ? { name: 'contradictions', description: 'No contradictions', status: 'pass', message: 'No conflicting rules/instincts' }\n : { name: 'contradictions', description: 'No contradictions', status: 'warn', message: `${contradictionResult.contradictions.length} potential contradiction(s)` });\n\n return checks;\n },\n },\n];\n\n/**\n * Run a verification gate by name.\n * Returns all check results and an overall pass/fail status.\n */\nexport function runGate(\n gateName: string,\n harnessDir: string,\n config?: HarnessConfig,\n): VerificationGateResult {\n const gate = BUILTIN_GATES.find((g) => g.name === gateName);\n if (!gate) {\n return {\n gateName,\n passed: false,\n checks: [{ name: 'gate-not-found', description: 'Gate exists', status: 'fail', message: `Unknown gate: ${gateName}` }],\n summary: `Gate \"${gateName}\" not found. Available: ${BUILTIN_GATES.map((g) => g.name).join(', ')}`,\n };\n }\n\n const checks = gate.check(harnessDir, config);\n const hasFails = checks.some((c) => c.status === 'fail');\n const hasWarns = checks.some((c) => c.status === 'warn');\n\n const passed = !hasFails;\n const passCount = checks.filter((c) => c.status === 'pass').length;\n const failCount = checks.filter((c) => c.status === 'fail').length;\n const warnCount = checks.filter((c) => c.status === 'warn').length;\n\n let summary = `${gate.name}: ${passCount} passed`;\n if (failCount > 0) summary += `, ${failCount} failed`;\n if (warnCount > 0) summary += `, ${warnCount} warnings`;\n\n return { gateName, passed, checks, summary };\n}\n\n/**\n * Run all built-in verification gates.\n */\nexport function runAllGates(\n harnessDir: string,\n config?: HarnessConfig,\n): VerificationGateResult[] {\n return BUILTIN_GATES.map((gate) => runGate(gate.name, harnessDir, config));\n}\n\n/**\n * List available gate names and descriptions.\n */\nexport function listGates(): Array<{ name: string; description: string }> {\n return BUILTIN_GATES.map((g) => ({ name: g.name, description: g.description }));\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ compressJournals,
5
+ listJournals,
6
+ listUnjournaled,
7
+ parseJournalSynthesis,
8
+ synthesizeJournal,
9
+ synthesizeJournalRange
10
+ } from "./chunk-CSL3ERUI.js";
11
+ import "./chunk-UPLBF4RZ.js";
12
+ import "./chunk-IZ6UZ3ZL.js";
13
+ import "./chunk-CHJ5GNZC.js";
14
+ import "./chunk-4CWAGBNS.js";
15
+ import "./chunk-ZZJOFKAT.js";
16
+ export {
17
+ compressJournals,
18
+ listJournals,
19
+ listUnjournaled,
20
+ parseJournalSynthesis,
21
+ synthesizeJournal,
22
+ synthesizeJournalRange
23
+ };
24
+ //# sourceMappingURL=journal-WANJL3MI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ estimateTokens,
5
+ getAtLevel,
6
+ loadAllPrimitives,
7
+ loadAllPrimitivesWithErrors,
8
+ loadDirectory,
9
+ loadDirectoryWithErrors,
10
+ parseHarnessDocument
11
+ } from "./chunk-UPLBF4RZ.js";
12
+ import "./chunk-4CWAGBNS.js";
13
+ import "./chunk-ZZJOFKAT.js";
14
+ export {
15
+ estimateTokens,
16
+ getAtLevel,
17
+ loadAllPrimitives,
18
+ loadAllPrimitivesWithErrors,
19
+ loadDirectory,
20
+ loadDirectoryWithErrors,
21
+ parseHarnessDocument
22
+ };
23
+ //# sourceMappingURL=loader-C3TKIKZR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ createMcpManager,
5
+ loadMcpTools,
6
+ validateMcpConfig
7
+ } from "./chunk-5H34JPMB.js";
8
+ import "./chunk-BSKDOFRT.js";
9
+ import "./chunk-ZZJOFKAT.js";
10
+ export {
11
+ createMcpManager,
12
+ loadMcpTools,
13
+ validateMcpConfig
14
+ };
15
+ //# sourceMappingURL=mcp-WTQJJZAO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,377 @@
1
+ #!/usr/bin/env node
2
+
3
+ import "./chunk-ZZJOFKAT.js";
4
+
5
+ // src/runtime/mcp-discovery.ts
6
+ import { existsSync, readFileSync } from "fs";
7
+ import { join } from "path";
8
+ import { homedir, platform } from "os";
9
+ function vscodeGlobalStoragePath(h, mac, extensionId) {
10
+ if (mac) {
11
+ return join(h, "Library", "Application Support", "Code", "User", "globalStorage", extensionId);
12
+ }
13
+ return join(h, ".config", "Code", "User", "globalStorage", extensionId);
14
+ }
15
+ function extractClaudeCodeServers(root) {
16
+ const merged = {};
17
+ const topLevel = root.mcpServers;
18
+ if (topLevel && typeof topLevel === "object" && !Array.isArray(topLevel)) {
19
+ Object.assign(merged, topLevel);
20
+ }
21
+ const projects = root.projects;
22
+ if (projects && typeof projects === "object" && !Array.isArray(projects)) {
23
+ for (const projectData of Object.values(projects)) {
24
+ if (!projectData || typeof projectData !== "object" || Array.isArray(projectData)) continue;
25
+ const proj = projectData;
26
+ const projServers = proj.mcpServers;
27
+ if (projServers && typeof projServers === "object" && !Array.isArray(projServers)) {
28
+ for (const [name, config] of Object.entries(projServers)) {
29
+ if (!(name in merged)) {
30
+ merged[name] = config;
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ return merged;
37
+ }
38
+ function buildToolConfigs(h, mac) {
39
+ return [
40
+ {
41
+ tool: "Claude Desktop",
42
+ path: () => mac ? join(h, "Library", "Application Support", "Claude", "claude_desktop_config.json") : join(h, ".config", "Claude", "claude_desktop_config.json"),
43
+ rootKey: "mcpServers"
44
+ },
45
+ {
46
+ tool: "Claude Code",
47
+ path: () => join(h, ".claude.json"),
48
+ rootKey: "mcpServers",
49
+ usesTypeField: true,
50
+ extractServers: extractClaudeCodeServers
51
+ },
52
+ {
53
+ tool: "Cursor",
54
+ path: () => join(h, ".cursor", "mcp.json"),
55
+ rootKey: "mcpServers"
56
+ },
57
+ {
58
+ tool: "Windsurf",
59
+ path: () => join(h, ".codeium", "windsurf", "mcp_config.json"),
60
+ rootKey: "mcpServers"
61
+ },
62
+ {
63
+ tool: "Copilot CLI",
64
+ path: () => join(h, ".copilot", "mcp-config.json"),
65
+ rootKey: "mcpServers"
66
+ },
67
+ {
68
+ tool: "Cline",
69
+ path: () => join(vscodeGlobalStoragePath(h, mac, "saoudrizwan.claude-dev"), "settings", "cline_mcp_settings.json"),
70
+ rootKey: "mcpServers"
71
+ },
72
+ {
73
+ tool: "Roo Code",
74
+ path: () => join(vscodeGlobalStoragePath(h, mac, "rooveterinaryinc.roo-cline"), "settings", "mcp_settings.json"),
75
+ rootKey: "mcpServers"
76
+ },
77
+ {
78
+ tool: "VS Code",
79
+ path: () => mac ? join(h, "Library", "Application Support", "Code", "User", "mcp.json") : join(h, ".config", "Code", "User", "mcp.json"),
80
+ rootKey: "servers",
81
+ usesTypeField: true
82
+ },
83
+ {
84
+ tool: "Zed",
85
+ path: () => join(h, ".config", "zed", "settings.json"),
86
+ rootKey: "context_servers"
87
+ }
88
+ ];
89
+ }
90
+ function inferTransport(serverObj, usesTypeField) {
91
+ if (usesTypeField && typeof serverObj.type === "string") {
92
+ const t = serverObj.type.toLowerCase();
93
+ if (t === "sse") return "sse";
94
+ if (t === "http") return "http";
95
+ if (t === "stdio") return "stdio";
96
+ }
97
+ if (typeof serverObj.command === "string") return "stdio";
98
+ if (typeof serverObj.url === "string" || typeof serverObj.serverUrl === "string") {
99
+ const url = serverObj.url ?? serverObj.serverUrl;
100
+ if (url.includes("/sse") || serverObj.type === "sse") return "sse";
101
+ return "http";
102
+ }
103
+ return "stdio";
104
+ }
105
+ function parseServer(name, serverObj, usesTypeField) {
106
+ const transport = inferTransport(serverObj, usesTypeField);
107
+ const server = { name, transport };
108
+ if (transport === "stdio") {
109
+ if (typeof serverObj.command === "string") server.command = serverObj.command;
110
+ if (Array.isArray(serverObj.args)) {
111
+ server.args = serverObj.args.filter((a) => typeof a === "string").map((a) => redactArgValue(a));
112
+ }
113
+ if (serverObj.env && typeof serverObj.env === "object" && !Array.isArray(serverObj.env)) {
114
+ server.env = redactEnv(filterStringRecord(serverObj.env));
115
+ }
116
+ if (typeof serverObj.cwd === "string") server.cwd = serverObj.cwd;
117
+ } else {
118
+ const url = serverObj.url ?? serverObj.serverUrl;
119
+ if (typeof url === "string") server.url = url;
120
+ if (serverObj.headers && typeof serverObj.headers === "object" && !Array.isArray(serverObj.headers)) {
121
+ const headers = filterStringRecord(serverObj.headers);
122
+ for (const [k, v] of Object.entries(headers)) {
123
+ if (SECRET_PATTERNS.test(k) || SECRET_PATTERNS.test(v)) {
124
+ headers[k] = `\${${k.toUpperCase().replace(/[^A-Z0-9]/g, "_")}}`;
125
+ }
126
+ }
127
+ server.headers = headers;
128
+ }
129
+ }
130
+ return server;
131
+ }
132
+ function filterStringRecord(obj) {
133
+ const result = {};
134
+ for (const [k, v] of Object.entries(obj)) {
135
+ if (typeof v === "string") result[k] = v;
136
+ }
137
+ return result;
138
+ }
139
+ var SECRET_PATTERNS = /(?:api[_-]?key|secret|token|password|bearer|auth)/i;
140
+ var SAFE_ENV_KEYS = /^(?:PATH|HOME|NODE_ENV|NODE_OPTIONS|SHELL|LANG|LC_\w+|TZ|TERM|EDITOR)$/;
141
+ var BEARER_PATTERN = /^(Authorization:\s*Bearer\s+)\S+$/i;
142
+ var TOKEN_ARG_PATTERN = /^(--(?:token|api-key|secret|password)[=:])\S+$/i;
143
+ function redactArgValue(arg) {
144
+ const bearerMatch = BEARER_PATTERN.exec(arg);
145
+ if (bearerMatch) return `${bearerMatch[1]}\${BEARER_TOKEN}`;
146
+ const tokenMatch = TOKEN_ARG_PATTERN.exec(arg);
147
+ if (tokenMatch) return `${tokenMatch[1]}\${TOKEN}`;
148
+ return arg;
149
+ }
150
+ function redactEnv(env) {
151
+ const result = {};
152
+ for (const [k, v] of Object.entries(env)) {
153
+ if (SAFE_ENV_KEYS.test(k)) {
154
+ result[k] = v;
155
+ } else if (SECRET_PATTERNS.test(k)) {
156
+ result[k] = `\${${k}}`;
157
+ } else {
158
+ result[k] = v;
159
+ }
160
+ }
161
+ return result;
162
+ }
163
+ function readJsonSafe(filePath) {
164
+ let raw = readFileSync(filePath, "utf-8");
165
+ raw = raw.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "");
166
+ let result = "";
167
+ let inString = false;
168
+ let escape = false;
169
+ let i = 0;
170
+ while (i < raw.length) {
171
+ const ch = raw[i];
172
+ if (escape) {
173
+ result += ch;
174
+ escape = false;
175
+ i++;
176
+ continue;
177
+ }
178
+ if (inString) {
179
+ if (ch === "\\") {
180
+ escape = true;
181
+ result += ch;
182
+ } else if (ch === '"') {
183
+ inString = false;
184
+ result += ch;
185
+ } else {
186
+ result += ch;
187
+ }
188
+ i++;
189
+ continue;
190
+ }
191
+ if (ch === '"') {
192
+ inString = true;
193
+ result += ch;
194
+ i++;
195
+ } else if (ch === "/" && i + 1 < raw.length && raw[i + 1] === "/") {
196
+ while (i < raw.length && raw[i] !== "\n") i++;
197
+ } else if (ch === "/" && i + 1 < raw.length && raw[i + 1] === "*") {
198
+ i += 2;
199
+ while (i + 1 < raw.length && !(raw[i] === "*" && raw[i + 1] === "/")) i++;
200
+ i += 2;
201
+ } else {
202
+ result += ch;
203
+ i++;
204
+ }
205
+ }
206
+ return JSON.parse(result);
207
+ }
208
+ function scanTool(toolConfig) {
209
+ const configPath = toolConfig.path();
210
+ const source = {
211
+ tool: toolConfig.tool,
212
+ configPath,
213
+ found: false,
214
+ servers: []
215
+ };
216
+ if (!existsSync(configPath)) {
217
+ return source;
218
+ }
219
+ source.found = true;
220
+ try {
221
+ const parsed = readJsonSafe(configPath);
222
+ if (!parsed || typeof parsed !== "object") {
223
+ source.error = "Config file is not a JSON object";
224
+ return source;
225
+ }
226
+ const root = parsed;
227
+ const serversObj = toolConfig.extractServers ? toolConfig.extractServers(root) : root[toolConfig.rootKey];
228
+ if (!serversObj || typeof serversObj !== "object" || Array.isArray(serversObj)) {
229
+ return source;
230
+ }
231
+ const entries = Object.entries(serversObj);
232
+ for (const [name, value] of entries) {
233
+ if (!value || typeof value !== "object" || Array.isArray(value)) continue;
234
+ const serverObj = value;
235
+ if (serverObj.disabled === true || serverObj.enabled === false) continue;
236
+ try {
237
+ const server = parseServer(name, serverObj, toolConfig.usesTypeField);
238
+ if (server.command || server.url) {
239
+ source.servers.push(server);
240
+ }
241
+ } catch {
242
+ }
243
+ }
244
+ } catch (err) {
245
+ source.error = err instanceof Error ? err.message : String(err);
246
+ }
247
+ return source;
248
+ }
249
+ function discoverMcpServers(options) {
250
+ const h = options?.homeDir ?? homedir();
251
+ const mac = options?.isMac ?? platform() === "darwin";
252
+ const toolConfigs = buildToolConfigs(h, mac);
253
+ const sources = [];
254
+ const seenNames = /* @__PURE__ */ new Set();
255
+ const uniqueServers = [];
256
+ for (const toolConfig of toolConfigs) {
257
+ const source = scanTool(toolConfig);
258
+ sources.push(source);
259
+ for (const server of source.servers) {
260
+ if (!seenNames.has(server.name)) {
261
+ seenNames.add(server.name);
262
+ uniqueServers.push(server);
263
+ }
264
+ }
265
+ }
266
+ return {
267
+ sources,
268
+ servers: uniqueServers,
269
+ sourcesFound: sources.filter((s) => s.found).length,
270
+ totalServers: uniqueServers.length
271
+ };
272
+ }
273
+ var NORMALIZABLE_BINARIES = /* @__PURE__ */ new Set(["npx", "node", "python", "python3"]);
274
+ function normalizeCommand(command) {
275
+ if (!command.startsWith("/")) return command;
276
+ const base = command.substring(command.lastIndexOf("/") + 1);
277
+ if (NORMALIZABLE_BINARIES.has(base)) return base;
278
+ return command;
279
+ }
280
+ function hasAuthConfigured(server) {
281
+ if (server.headers) {
282
+ for (const k of Object.keys(server.headers)) {
283
+ if (k.toLowerCase() === "authorization") return true;
284
+ }
285
+ }
286
+ return false;
287
+ }
288
+ function findEnvPlaceholders(value) {
289
+ const matches = value.matchAll(/\$\{([A-Z_][A-Z0-9_]*)\}/gi);
290
+ return Array.from(matches, (m) => m[1]);
291
+ }
292
+ function filterUnsafeServers(servers) {
293
+ const result = [];
294
+ for (const server of servers) {
295
+ if (server.transport === "http" || server.transport === "sse") {
296
+ if (!hasAuthConfigured(server)) {
297
+ console.warn(`[mcp-discovery] skipping ${server.name}: ${server.transport} transport with no Authorization header`);
298
+ continue;
299
+ }
300
+ }
301
+ let missingVar;
302
+ if (server.env) {
303
+ for (const v of Object.values(server.env)) {
304
+ for (const varName of findEnvPlaceholders(v)) {
305
+ if (!(varName in process.env) || !process.env[varName]) {
306
+ missingVar = varName;
307
+ break;
308
+ }
309
+ }
310
+ if (missingVar) break;
311
+ }
312
+ }
313
+ if (!missingVar && server.headers) {
314
+ for (const v of Object.values(server.headers)) {
315
+ for (const varName of findEnvPlaceholders(v)) {
316
+ if (!(varName in process.env) || !process.env[varName]) {
317
+ missingVar = varName;
318
+ break;
319
+ }
320
+ }
321
+ if (missingVar) break;
322
+ }
323
+ }
324
+ if (missingVar) {
325
+ console.warn(`[mcp-discovery] skipping ${server.name}: required env var ${missingVar} not set`);
326
+ continue;
327
+ }
328
+ result.push(server);
329
+ }
330
+ return result;
331
+ }
332
+ function discoveredServersToYaml(servers) {
333
+ if (servers.length === 0) return "";
334
+ const lines = ["mcp:", " servers:"];
335
+ for (const server of servers) {
336
+ lines.push(` ${server.name}:`);
337
+ lines.push(` transport: ${server.transport}`);
338
+ if (server.transport === "stdio") {
339
+ let normalizedCommand;
340
+ if (server.command) {
341
+ normalizedCommand = normalizeCommand(server.command);
342
+ lines.push(` command: ${normalizedCommand}`);
343
+ }
344
+ const wasNormalized = !!server.command && normalizedCommand !== server.command;
345
+ if (server.args && server.args.length > 0) {
346
+ lines.push(` args: [${server.args.map((a) => `"${a}"`).join(", ")}]`);
347
+ }
348
+ const filteredEnv = server.env ? Object.fromEntries(Object.entries(server.env).filter(([k]) => !(wasNormalized && k === "PATH"))) : void 0;
349
+ if (filteredEnv && Object.keys(filteredEnv).length > 0) {
350
+ lines.push(" env:");
351
+ for (const [k, v] of Object.entries(filteredEnv)) {
352
+ lines.push(` ${k}: "${v}"`);
353
+ }
354
+ }
355
+ if (server.cwd) lines.push(` cwd: "${server.cwd}"`);
356
+ } else {
357
+ if (server.url) lines.push(` url: "${server.url}"`);
358
+ if (server.headers && Object.keys(server.headers).length > 0) {
359
+ lines.push(" headers:");
360
+ for (const [k, v] of Object.entries(server.headers)) {
361
+ lines.push(` ${k}: "${v}"`);
362
+ }
363
+ }
364
+ }
365
+ }
366
+ return lines.join("\n");
367
+ }
368
+ function getScannedTools() {
369
+ return buildToolConfigs("", true).map((t) => t.tool);
370
+ }
371
+ export {
372
+ discoverMcpServers,
373
+ discoveredServersToYaml,
374
+ filterUnsafeServers,
375
+ getScannedTools
376
+ };
377
+ //# sourceMappingURL=mcp-discovery-WPAQFL6S.js.map