@agntk/agent-harness 0.1.3 → 0.1.5

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 (123) hide show
  1. package/dist/{agent-framework-K4GUIICH.js → agent-framework-CMFC3VJM.js} +8 -8
  2. package/dist/{auto-processor-OLE45UI3.js → auto-processor-SDAJF67T.js} +3 -3
  3. package/dist/{chunk-XTBKL5BI.js → chunk-2ENYRENZ.js} +2 -2
  4. package/dist/{chunk-UPLBF4RZ.js → chunk-2UVWCTAY.js} +2 -2
  5. package/dist/{chunk-4CWAGBNS.js → chunk-4TQQZILG.js} +73 -3
  6. package/dist/chunk-4TQQZILG.js.map +1 -0
  7. package/dist/{chunk-A7BJPQQ6.js → chunk-5O5OGOOQ.js} +2 -2
  8. package/dist/{chunk-UWQTZMNI.js → chunk-7GZ4D6V6.js} +2 -2
  9. package/dist/{chunk-FLZU44SV.js → chunk-AN6Y4MDD.js} +6 -6
  10. package/dist/{chunk-4FDUOGSZ.js → chunk-D7AWV24Z.js} +3 -3
  11. package/dist/{chunk-CHJ5GNZC.js → chunk-EC42HQQH.js} +2 -2
  12. package/dist/{chunk-274RV3YO.js → chunk-GX2RCSFJ.js} +3 -3
  13. package/dist/{chunk-GJNNR2RA.js → chunk-M6PDMK2O.js} +3 -3
  14. package/dist/{chunk-GUJTBGVS.js → chunk-MSO7DKBK.js} +99 -188
  15. package/dist/chunk-MSO7DKBK.js.map +1 -0
  16. package/dist/{chunk-CSL3ERUI.js → chunk-NBEAK63K.js} +3 -3
  17. package/dist/{chunk-DA7IKHC4.js → chunk-NOJW5KG2.js} +2 -2
  18. package/dist/{chunk-M7NXUK55.js → chunk-NVC2WY4K.js} +2 -2
  19. package/dist/{chunk-YIJY5DBV.js → chunk-P74KXHA4.js} +4 -4
  20. package/dist/{chunk-YUFNYN2H.js → chunk-PTQ37NRI.js} +4 -4
  21. package/dist/{chunk-KFX54TQM.js → chunk-RPBC2QOA.js} +73 -3
  22. package/dist/chunk-RPBC2QOA.js.map +1 -0
  23. package/dist/{chunk-RY3ZFII7.js → chunk-SEHAQTBO.js} +6 -6
  24. package/dist/{chunk-MPZ3BPUI.js → chunk-UMXPOYZR.js} +4 -4
  25. package/dist/{chunk-W4T7PGI2.js → chunk-UXCHAS3Z.js} +4 -4
  26. package/dist/chunk-XVFVTDE6.js +98 -0
  27. package/dist/chunk-XVFVTDE6.js.map +1 -0
  28. package/dist/cli/index.js +105 -104
  29. package/dist/cli/index.js.map +1 -1
  30. package/dist/{config-WVMRUOCA.js → config-2O6S2YJO.js} +3 -3
  31. package/dist/config-LLQZYN2Q.js +11 -0
  32. package/dist/{context-loader-3ORBPMHJ.js → context-loader-XCZ5EXNG.js} +4 -4
  33. package/dist/{conversation-QDEIDQPH.js → conversation-OPLE23IM.js} +6 -6
  34. package/dist/{delegate-VJCJLYEK.js → delegate-ZJCIADNN.js} +7 -7
  35. package/dist/{export-6GCYHEHQ.js → export-2HEAAOUF.js} +3 -3
  36. package/dist/{graph-YUIPOSOO.js → graph-5MKRTC3J.js} +4 -4
  37. package/dist/harness-ABKZWP47.js +11 -0
  38. package/dist/{harness-WE4SLCML.js → harness-XSBQBY7T.js} +8 -8
  39. package/dist/index.d.ts +22 -0
  40. package/dist/index.js +226 -6
  41. package/dist/index.js.map +1 -1
  42. package/dist/{indexer-LONANRRM.js → indexer-YKSGUVYT.js} +4 -4
  43. package/dist/{instinct-learner-SRM72DHF.js → instinct-learner-CWVMLUWX.js} +5 -5
  44. package/dist/{intake-4M3HNU43.js → intake-M5NRR6QR.js} +5 -5
  45. package/dist/{intelligence-HJOCA4SJ.js → intelligence-UW4TCOC7.js} +10 -10
  46. package/dist/{journal-WANJL3MI.js → journal-KN265YLU.js} +5 -5
  47. package/dist/{loader-C3TKIKZR.js → loader-BOCVXVCH.js} +3 -3
  48. package/dist/{mcp-installer-6O2XXD3V.js → mcp-installer-KV3XZRRF.js} +3 -3
  49. package/dist/{primitive-registry-I6VTIR4W.js → primitive-registry-HOJMUFBT.js} +3 -3
  50. package/dist/{rule-engine-YGQ3RYZM.js → rule-engine-I4AFQSSR.js} +3 -3
  51. package/dist/{scaffold-A3VRRCBV.js → scaffold-ZY4XWINP.js} +4 -4
  52. package/dist/{scheduler-XHHIVHRI.js → scheduler-TYOQKO4C.js} +11 -11
  53. package/dist/{search-V3W5JMJG.js → search-4IYM525O.js} +3 -3
  54. package/dist/{semantic-search-2DTOO5UX.js → semantic-search-G624D6CI.js} +3 -3
  55. package/dist/{serve-DTQ3HENY.js → serve-QFUZWOU3.js} +9 -9
  56. package/dist/{telemetry-UC6PBXC7.js → telemetry-MVDNGJEC.js} +4 -4
  57. package/dist/{tool-executor-MJ7IG7PQ.js → tool-executor-KEYQLO4M.js} +5 -5
  58. package/dist/{tools-DZ4KETET.js → tools-EB3BHRRF.js} +4 -4
  59. package/dist/{types-EW7AIB3R.js → types-NYKB2DN3.js} +2 -2
  60. package/dist/{types-WGDLSPO6.js → types-VRSXU4AM.js} +2 -2
  61. package/dist/{universal-installer-EVBDGOWM.js → universal-installer-7MFCJUW7.js} +228 -6
  62. package/dist/universal-installer-7MFCJUW7.js.map +1 -0
  63. package/dist/{validator-7WXMDIHH.js → validator-LZXBFEPV.js} +8 -8
  64. package/dist/{verification-gate-FYXUX6LH.js → verification-gate-ALSJVKSW.js} +3 -3
  65. package/dist/{watcher-ISJC7YKL.js → watcher-CSHVDOCM.js} +5 -5
  66. package/dist/{web-server-DD7ZOP46.js → web-server-7NGOTK7J.js} +8 -8
  67. package/dist/web-server-7NGOTK7J.js.map +1 -0
  68. package/package.json +1 -1
  69. package/dist/chunk-4CWAGBNS.js.map +0 -1
  70. package/dist/chunk-GUJTBGVS.js.map +0 -1
  71. package/dist/chunk-KFX54TQM.js.map +0 -1
  72. package/dist/harness-LCHA3DWP.js +0 -10
  73. package/dist/universal-installer-EVBDGOWM.js.map +0 -1
  74. /package/dist/{agent-framework-K4GUIICH.js.map → agent-framework-CMFC3VJM.js.map} +0 -0
  75. /package/dist/{auto-processor-OLE45UI3.js.map → auto-processor-SDAJF67T.js.map} +0 -0
  76. /package/dist/{chunk-XTBKL5BI.js.map → chunk-2ENYRENZ.js.map} +0 -0
  77. /package/dist/{chunk-UPLBF4RZ.js.map → chunk-2UVWCTAY.js.map} +0 -0
  78. /package/dist/{chunk-A7BJPQQ6.js.map → chunk-5O5OGOOQ.js.map} +0 -0
  79. /package/dist/{chunk-UWQTZMNI.js.map → chunk-7GZ4D6V6.js.map} +0 -0
  80. /package/dist/{chunk-FLZU44SV.js.map → chunk-AN6Y4MDD.js.map} +0 -0
  81. /package/dist/{chunk-4FDUOGSZ.js.map → chunk-D7AWV24Z.js.map} +0 -0
  82. /package/dist/{chunk-CHJ5GNZC.js.map → chunk-EC42HQQH.js.map} +0 -0
  83. /package/dist/{chunk-274RV3YO.js.map → chunk-GX2RCSFJ.js.map} +0 -0
  84. /package/dist/{chunk-GJNNR2RA.js.map → chunk-M6PDMK2O.js.map} +0 -0
  85. /package/dist/{chunk-CSL3ERUI.js.map → chunk-NBEAK63K.js.map} +0 -0
  86. /package/dist/{chunk-DA7IKHC4.js.map → chunk-NOJW5KG2.js.map} +0 -0
  87. /package/dist/{chunk-M7NXUK55.js.map → chunk-NVC2WY4K.js.map} +0 -0
  88. /package/dist/{chunk-YIJY5DBV.js.map → chunk-P74KXHA4.js.map} +0 -0
  89. /package/dist/{chunk-YUFNYN2H.js.map → chunk-PTQ37NRI.js.map} +0 -0
  90. /package/dist/{chunk-RY3ZFII7.js.map → chunk-SEHAQTBO.js.map} +0 -0
  91. /package/dist/{chunk-MPZ3BPUI.js.map → chunk-UMXPOYZR.js.map} +0 -0
  92. /package/dist/{chunk-W4T7PGI2.js.map → chunk-UXCHAS3Z.js.map} +0 -0
  93. /package/dist/{config-WVMRUOCA.js.map → config-2O6S2YJO.js.map} +0 -0
  94. /package/dist/{context-loader-3ORBPMHJ.js.map → config-LLQZYN2Q.js.map} +0 -0
  95. /package/dist/{conversation-QDEIDQPH.js.map → context-loader-XCZ5EXNG.js.map} +0 -0
  96. /package/dist/{delegate-VJCJLYEK.js.map → conversation-OPLE23IM.js.map} +0 -0
  97. /package/dist/{graph-YUIPOSOO.js.map → delegate-ZJCIADNN.js.map} +0 -0
  98. /package/dist/{export-6GCYHEHQ.js.map → export-2HEAAOUF.js.map} +0 -0
  99. /package/dist/{harness-LCHA3DWP.js.map → graph-5MKRTC3J.js.map} +0 -0
  100. /package/dist/{harness-WE4SLCML.js.map → harness-ABKZWP47.js.map} +0 -0
  101. /package/dist/{indexer-LONANRRM.js.map → harness-XSBQBY7T.js.map} +0 -0
  102. /package/dist/{instinct-learner-SRM72DHF.js.map → indexer-YKSGUVYT.js.map} +0 -0
  103. /package/dist/{intake-4M3HNU43.js.map → instinct-learner-CWVMLUWX.js.map} +0 -0
  104. /package/dist/{journal-WANJL3MI.js.map → intake-M5NRR6QR.js.map} +0 -0
  105. /package/dist/{intelligence-HJOCA4SJ.js.map → intelligence-UW4TCOC7.js.map} +0 -0
  106. /package/dist/{loader-C3TKIKZR.js.map → journal-KN265YLU.js.map} +0 -0
  107. /package/dist/{telemetry-UC6PBXC7.js.map → loader-BOCVXVCH.js.map} +0 -0
  108. /package/dist/{mcp-installer-6O2XXD3V.js.map → mcp-installer-KV3XZRRF.js.map} +0 -0
  109. /package/dist/{primitive-registry-I6VTIR4W.js.map → primitive-registry-HOJMUFBT.js.map} +0 -0
  110. /package/dist/{rule-engine-YGQ3RYZM.js.map → rule-engine-I4AFQSSR.js.map} +0 -0
  111. /package/dist/{scaffold-A3VRRCBV.js.map → scaffold-ZY4XWINP.js.map} +0 -0
  112. /package/dist/{scheduler-XHHIVHRI.js.map → scheduler-TYOQKO4C.js.map} +0 -0
  113. /package/dist/{search-V3W5JMJG.js.map → search-4IYM525O.js.map} +0 -0
  114. /package/dist/{semantic-search-2DTOO5UX.js.map → semantic-search-G624D6CI.js.map} +0 -0
  115. /package/dist/{serve-DTQ3HENY.js.map → serve-QFUZWOU3.js.map} +0 -0
  116. /package/dist/{tool-executor-MJ7IG7PQ.js.map → telemetry-MVDNGJEC.js.map} +0 -0
  117. /package/dist/{tools-DZ4KETET.js.map → tool-executor-KEYQLO4M.js.map} +0 -0
  118. /package/dist/{types-EW7AIB3R.js.map → tools-EB3BHRRF.js.map} +0 -0
  119. /package/dist/{types-WGDLSPO6.js.map → types-NYKB2DN3.js.map} +0 -0
  120. /package/dist/{validator-7WXMDIHH.js.map → types-VRSXU4AM.js.map} +0 -0
  121. /package/dist/{web-server-DD7ZOP46.js.map → validator-LZXBFEPV.js.map} +0 -0
  122. /package/dist/{verification-gate-FYXUX6LH.js.map → verification-gate-ALSJVKSW.js.map} +0 -0
  123. /package/dist/{watcher-ISJC7YKL.js.map → watcher-CSHVDOCM.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/harness.ts","../src/core/config.ts","../src/core/logger.ts","../src/runtime/context-loader.ts","../src/primitives/loader.ts","../src/runtime/state.ts","../src/runtime/file-lock.ts","../src/runtime/sessions.ts","../src/runtime/cost-tracker.ts","../src/runtime/health.ts","../src/runtime/rate-limiter.ts","../src/runtime/guardrails.ts","../src/runtime/tool-executor.ts","../src/runtime/tools.ts","../src/runtime/mcp.ts"],"sourcesContent":["import { existsSync } from 'fs';\nimport { resolve } from 'path';\nimport { loadConfig } from './config.js';\nimport { log } from './logger.js';\nimport type {\n CreateHarnessOptions,\n HarnessConfig,\n HarnessAgent,\n HarnessHooks,\n AgentRunResult,\n AgentStreamResult,\n AgentState,\n} from './types.js';\nimport { getModel, generate, streamGenerateWithDetails } from '../llm/provider.js';\nimport { buildSystemPrompt } from '../runtime/context-loader.js';\nimport { loadState, saveState } from '../runtime/state.js';\nimport { createSessionId, writeSession, type SessionRecord } from '../runtime/sessions.js';\nimport { recordCost } from '../runtime/cost-tracker.js';\nimport { recordSuccess, recordFailure, recordBoot } from '../runtime/health.js';\nimport { checkGuardrails } from '../runtime/guardrails.js';\nimport { buildToolSet, type AIToolSet } from '../runtime/tool-executor.js';\nimport { createMcpManager, type McpManager } from '../runtime/mcp.js';\n\nexport function createHarness(options: CreateHarnessOptions): HarnessAgent {\n const dir = resolve(options.dir);\n\n if (!existsSync(dir)) {\n throw new Error(`Harness directory not found: ${dir}`);\n }\n\n const config = loadConfig(dir, options.config);\n\n // Apply model and provider overrides from options\n if (options.model) {\n config.model = { ...config.model, id: options.model };\n }\n if (options.provider) {\n config.model = { ...config.model, provider: options.provider };\n }\n\n const model = getModel(config, options.apiKey);\n const hooks: HarnessHooks = options.hooks ?? {};\n\n let state: AgentState;\n let systemPrompt: string;\n let booted = false;\n let toolSet: AIToolSet = {};\n let mcpManager: McpManager | undefined;\n\n const agent: HarnessAgent = {\n name: config.agent.name,\n config,\n\n async boot() {\n // Load state\n state = loadState(dir);\n const previousMode = state.mode;\n state.mode = 'active';\n state.last_interaction = new Date().toISOString();\n\n // Build system prompt from harness files\n const ctx = buildSystemPrompt(dir, config);\n systemPrompt = ctx.systemPrompt;\n\n // Connect to MCP servers and load their tools\n let mcpTools: AIToolSet = {};\n mcpManager = createMcpManager(config);\n if (mcpManager.hasServers()) {\n try {\n await mcpManager.connect();\n mcpTools = mcpManager.getTools();\n } catch (err) {\n log.warn(`MCP connection failed during boot: ${err instanceof Error ? err.message : String(err)}. Continuing without MCP tools.`);\n }\n }\n\n // Load tools and convert to AI SDK format (includes markdown + programmatic + MCP)\n toolSet = buildToolSet(dir, options.toolExecutor, mcpTools);\n const toolCount = Object.keys(toolSet).length;\n\n booted = true;\n\n log.info(\n `Booted \"${config.agent.name}\" | ` +\n `${ctx.budget.loaded_files.length} files loaded | ` +\n `~${ctx.budget.used_tokens} tokens used | ` +\n `${ctx.budget.remaining} remaining` +\n (toolCount > 0 ? ` | ${toolCount} tools` : ''),\n );\n\n for (const warning of ctx.warnings) {\n log.warn(warning);\n }\n\n // Lifecycle: onStateChange\n if (previousMode !== 'active' && hooks.onStateChange) {\n await hooks.onStateChange({ agent, previous: previousMode, current: 'active' });\n }\n\n // Record boot in health metrics\n try { recordBoot(dir); } catch { /* best-effort */ }\n\n // Lifecycle: onBoot\n if (hooks.onBoot) {\n await hooks.onBoot({ agent, config, state });\n }\n },\n\n async run(prompt: string): Promise<AgentRunResult> {\n if (!booted) await agent.boot();\n\n // Check guardrails (rate limits + budget) before LLM call\n const guard = checkGuardrails(dir, config);\n if (!guard.allowed) {\n const error = new Error(`Guardrail blocked: ${guard.reason}`);\n try { recordFailure(dir, error.message); } catch { /* best-effort */ }\n if (hooks.onError) {\n try { await hooks.onError({ agent, error, prompt }); } catch { /* best-effort */ }\n }\n throw error;\n }\n\n const sessionId = createSessionId();\n const started = new Date().toISOString();\n\n const hasTools = Object.keys(toolSet).length > 0;\n let result;\n try {\n result = await generate({\n model,\n system: systemPrompt,\n prompt,\n maxRetries: config.model.max_retries,\n timeoutMs: config.model.timeout_ms,\n ...(hasTools ? { tools: toolSet, maxToolSteps: options.toolExecutor?.maxToolCalls ?? 5 } : {}),\n });\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n try { recordFailure(dir, error.message); } catch { /* best-effort */ }\n if (hooks.onError) {\n try { await hooks.onError({ agent, error, prompt }); } catch { /* best-effort */ }\n }\n throw error;\n }\n\n const ended = new Date().toISOString();\n\n // Write session record\n const session: SessionRecord = {\n id: sessionId,\n started,\n ended,\n prompt,\n summary: result.text.slice(0, 200),\n tokens_used: result.usage.totalTokens,\n steps: result.steps,\n model_id: config.model.id,\n tool_calls: result.toolCalls.length > 0 ? result.toolCalls : undefined,\n };\n\n // Post-LLM recording — wrapped in try-catch so telemetry failures\n // never mask a successful LLM result\n try {\n writeSession(dir, session);\n } catch (err) {\n log.warn(`Failed to write session ${sessionId}: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n try {\n recordCost(dir, {\n model_id: config.model.id,\n provider: config.model.provider ?? 'openrouter',\n input_tokens: result.usage.inputTokens,\n output_tokens: result.usage.outputTokens,\n source: `run:${sessionId}`,\n });\n } catch (err) {\n log.warn(`Failed to record cost: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n try {\n recordSuccess(dir);\n } catch (err) {\n log.warn(`Failed to record health: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n try {\n state.last_interaction = ended;\n saveState(dir, state);\n } catch (err) {\n log.warn(`Failed to save state: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n const runResult: AgentRunResult = {\n text: result.text,\n usage: result.usage,\n session_id: sessionId,\n steps: result.steps,\n toolCalls: result.toolCalls,\n };\n\n // Lifecycle: onSessionEnd — wrapped so hook errors don't lose the result\n if (hooks.onSessionEnd) {\n try {\n await hooks.onSessionEnd({ agent, sessionId, prompt, result: runResult });\n } catch (err) {\n log.warn(`onSessionEnd hook error: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n return runResult;\n },\n\n stream(prompt: string): AgentStreamResult {\n const sessionId = createSessionId();\n\n // Deferred result — resolves after stream is fully consumed and recording completes\n let resolveResult: (r: AgentRunResult) => void;\n let rejectResult: (e: Error) => void;\n const resultPromise = new Promise<AgentRunResult>((res, rej) => {\n resolveResult = res;\n rejectResult = rej;\n });\n // Prevent unhandled rejection when error propagates via the generator throw path\n // and consumer doesn't explicitly await .result\n resultPromise.catch(() => {});\n\n async function* generateStream(): AsyncIterable<string> {\n if (!booted) await agent.boot();\n\n // Check guardrails (rate limits + budget) before LLM call\n const guard = checkGuardrails(dir, config);\n if (!guard.allowed) {\n const error = new Error(`Guardrail blocked: ${guard.reason}`);\n try { recordFailure(dir, error.message); } catch { /* best-effort */ }\n if (hooks.onError) {\n try { await hooks.onError({ agent, error, prompt }); } catch { /* best-effort */ }\n }\n rejectResult(error);\n throw error;\n }\n\n const started = new Date().toISOString();\n let fullText = '';\n\n const hasTools = Object.keys(toolSet).length > 0;\n\n let streamResult;\n try {\n streamResult = streamGenerateWithDetails({\n model,\n system: systemPrompt,\n prompt,\n maxRetries: config.model.max_retries,\n timeoutMs: config.model.timeout_ms,\n ...(hasTools ? { tools: toolSet, maxToolSteps: options.toolExecutor?.maxToolCalls ?? 5 } : {}),\n });\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n try { recordFailure(dir, error.message); } catch { /* best-effort */ }\n if (hooks.onError) {\n try { await hooks.onError({ agent, error, prompt }); } catch { /* best-effort */ }\n }\n rejectResult(error);\n throw error;\n }\n\n try {\n for await (const chunk of streamResult.textStream) {\n fullText += chunk;\n yield chunk;\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n try { recordFailure(dir, error.message); } catch { /* best-effort */ }\n if (hooks.onError) {\n try { await hooks.onError({ agent, error, prompt }); } catch { /* best-effort */ }\n }\n rejectResult(error);\n throw error;\n }\n\n // Await post-stream metadata — wrapped so failures don't crash the generator\n let usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n let steps = 1;\n let toolCalls: Array<{ toolName: string; args: Record<string, unknown>; result: unknown }> = [];\n try {\n [usage, steps, toolCalls] = await Promise.all([\n streamResult.usage,\n streamResult.steps,\n streamResult.toolCalls,\n ]);\n } catch (err) {\n log.warn(`Failed to resolve post-stream metadata: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n const ended = new Date().toISOString();\n\n const session: SessionRecord = {\n id: sessionId,\n started,\n ended,\n prompt,\n summary: fullText.slice(0, 200),\n tokens_used: usage.totalTokens,\n steps,\n model_id: config.model.id,\n tool_calls: toolCalls.length > 0 ? toolCalls : undefined,\n };\n\n // Post-stream recording — wrapped so telemetry failures don't break the caller\n try {\n writeSession(dir, session);\n } catch (err) {\n log.warn(`Failed to write session ${sessionId}: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n try {\n recordCost(dir, {\n model_id: config.model.id,\n provider: config.model.provider ?? 'openrouter',\n input_tokens: usage.inputTokens,\n output_tokens: usage.outputTokens,\n source: `stream:${sessionId}`,\n });\n } catch (err) {\n log.warn(`Failed to record cost: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n try {\n recordSuccess(dir);\n } catch (err) {\n log.warn(`Failed to record health: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n try {\n state.last_interaction = ended;\n saveState(dir, state);\n } catch (err) {\n log.warn(`Failed to save state: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n const runResult: AgentRunResult = {\n text: fullText,\n usage,\n session_id: sessionId,\n steps,\n toolCalls,\n };\n\n // Lifecycle: onSessionEnd\n if (hooks.onSessionEnd) {\n try {\n await hooks.onSessionEnd({ agent, sessionId, prompt, result: runResult });\n } catch (err) {\n log.warn(`onSessionEnd hook error: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n resolveResult(runResult);\n }\n\n return {\n textStream: generateStream(),\n result: resultPromise,\n };\n },\n\n async shutdown() {\n if (!booted) return;\n\n // Lifecycle: onShutdown — wrapped so hook errors don't prevent cleanup\n if (hooks.onShutdown) {\n try {\n await hooks.onShutdown({ agent, state });\n } catch (err) {\n log.warn(`onShutdown hook error: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n // Close MCP server connections\n if (mcpManager) {\n try {\n await mcpManager.close();\n } catch (err) {\n log.warn(`MCP shutdown error: ${err instanceof Error ? err.message : String(err)}`);\n }\n mcpManager = undefined;\n }\n\n const previousMode = state.mode;\n state.mode = 'idle';\n try {\n saveState(dir, state);\n } catch (err) {\n log.warn(`Failed to save state during shutdown: ${err instanceof Error ? err.message : String(err)}`);\n }\n booted = false;\n\n // Lifecycle: onStateChange\n if (previousMode !== 'idle' && hooks.onStateChange) {\n try {\n await hooks.onStateChange({ agent, previous: previousMode, current: 'idle' });\n } catch (err) {\n log.warn(`onStateChange hook error: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n log.info(`Shutdown \"${config.agent.name}\"`);\n },\n\n getSystemPrompt() {\n return systemPrompt || '';\n },\n\n getState() {\n return state || loadState(dir);\n },\n };\n\n return agent;\n}\n","import { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport YAML from 'yaml';\nimport { CONFIG_DEFAULTS, HarnessConfigSchema, type HarnessConfig, type DeepPartial } from './types.js';\n\nconst CONFIG_FILENAMES = ['config.yaml', 'config.yml', 'harness.yaml', 'harness.yml'];\n\nexport function loadConfig(dir: string, overrides?: DeepPartial<HarnessConfig>): HarnessConfig {\n let raw: Record<string, unknown> = {};\n\n for (const filename of CONFIG_FILENAMES) {\n const configPath = join(dir, filename);\n if (existsSync(configPath)) {\n const content = readFileSync(configPath, 'utf-8');\n raw = YAML.parse(content) || {};\n break;\n }\n }\n\n // Deep merge: defaults <- file <- overrides\n let merged = deepMerge(\n CONFIG_DEFAULTS as unknown as Record<string, unknown>,\n raw,\n ) as unknown as Record<string, unknown>;\n\n if (overrides) {\n merged = deepMerge(\n merged,\n overrides as unknown as Record<string, unknown>,\n );\n }\n\n // Validate with Zod — parse applies defaults and coerces types\n const result = HarnessConfigSchema.safeParse(merged);\n if (!result.success) {\n const issues = result.error.issues\n .map((i) => ` ${i.path.join('.')}: ${i.message}`)\n .join('\\n');\n throw new Error(`Invalid config:\\n${issues}`);\n }\n\n return result.data;\n}\n\nexport function writeDefaultConfig(_dir: string, agentName: string = 'my-agent'): string {\n return `# Agent Harness Configuration\nagent:\n name: ${agentName}\n version: \"0.1.0\"\n\nmodel:\n provider: openrouter\n id: anthropic/claude-sonnet-4\n max_tokens: 200000\n max_retries: 2\n # timeout_ms: 60000\n\nruntime:\n scratchpad_budget: 10000\n timezone: America/New_York\n # heartbeat: \"0 6-23 * * *\" # reserved, not yet implemented\n # daily_summary: \"0 22 * * *\" # reserved, not yet implemented\n\nmemory:\n session_retention_days: 7\n journal_retention_days: 365\n\nchannels:\n primary: cli\n\nextensions:\n directories: []\n\n# rate_limits:\n# per_minute: 10\n# per_hour: 100\n# per_day: 500\n\n# budget:\n# daily_limit_usd: 5.00\n# monthly_limit_usd: 100.00\n# enforce: true\n`;\n}\n\nfunction deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n const result = { ...target };\n for (const key of Object.keys(source)) {\n if (\n source[key] &&\n typeof source[key] === 'object' &&\n !Array.isArray(source[key]) &&\n target[key] &&\n typeof target[key] === 'object' &&\n !Array.isArray(target[key])\n ) {\n result[key] = deepMerge(\n target[key] as Record<string, unknown>,\n source[key] as Record<string, unknown>,\n );\n } else {\n result[key] = source[key];\n }\n }\n return result;\n}\n","export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n silent: 4,\n};\n\nexport interface Logger {\n debug(msg: string, ...args: unknown[]): void;\n info(msg: string, ...args: unknown[]): void;\n warn(msg: string, ...args: unknown[]): void;\n error(msg: string, ...args: unknown[]): void;\n setLevel(level: LogLevel): void;\n getLevel(): LogLevel;\n child(prefix: string): Logger;\n}\n\nlet globalLevel: LogLevel = 'info';\n\nfunction shouldLog(level: LogLevel): boolean {\n return LEVEL_ORDER[level] >= LEVEL_ORDER[globalLevel];\n}\n\nfunction formatMessage(prefix: string, level: LogLevel, msg: string): string {\n const tag = prefix ? `[${prefix}]` : '';\n if (level === 'debug') return `${tag} ${msg}`.trimStart();\n if (level === 'warn') return `${tag} WARN: ${msg}`.trimStart();\n if (level === 'error') return `${tag} ERROR: ${msg}`.trimStart();\n return `${tag} ${msg}`.trimStart();\n}\n\nfunction createLoggerWithPrefix(prefix: string): Logger {\n return {\n debug(msg: string, ...args: unknown[]) {\n if (shouldLog('debug')) console.error(formatMessage(prefix, 'debug', msg), ...args);\n },\n info(msg: string, ...args: unknown[]) {\n if (shouldLog('info')) console.error(formatMessage(prefix, 'info', msg), ...args);\n },\n warn(msg: string, ...args: unknown[]) {\n if (shouldLog('warn')) console.error(formatMessage(prefix, 'warn', msg), ...args);\n },\n error(msg: string, ...args: unknown[]) {\n if (shouldLog('error')) console.error(formatMessage(prefix, 'error', msg), ...args);\n },\n setLevel(level: LogLevel) {\n globalLevel = level;\n },\n getLevel() {\n return globalLevel;\n },\n child(childPrefix: string) {\n const combined = prefix ? `${prefix}:${childPrefix}` : childPrefix;\n return createLoggerWithPrefix(combined);\n },\n };\n}\n\nexport function createLogger(prefix: string = ''): Logger {\n return createLoggerWithPrefix(prefix);\n}\n\nexport function setGlobalLogLevel(level: LogLevel): void {\n globalLevel = level;\n}\n\nexport function getGlobalLogLevel(): LogLevel {\n return globalLevel;\n}\n\nexport const log = createLogger('harness');\n","import { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { loadAllPrimitivesWithErrors, estimateTokens, getAtLevel } from '../primitives/loader.js';\nimport type { ParseError } from '../primitives/loader.js';\nimport type { HarnessConfig, HarnessDocument, ContextBudget } from '../core/types.js';\nimport { log } from '../core/logger.js';\n\nexport interface LoadedContext {\n systemPrompt: string;\n budget: ContextBudget;\n parseErrors: ParseError[];\n warnings: string[];\n}\n\nexport function buildSystemPrompt(harnessDir: string, config: HarnessConfig): LoadedContext {\n const maxTokens = config.model.max_tokens;\n const budget: ContextBudget = {\n max_tokens: maxTokens,\n used_tokens: 0,\n remaining: maxTokens,\n loaded_files: [],\n };\n\n const warnings: string[] = [];\n const sections: string[] = [];\n\n // --- Step 1: Load CORE.md (always, full content) ---\n const corePath = join(harnessDir, 'CORE.md');\n if (existsSync(corePath)) {\n const core = readFileSync(corePath, 'utf-8');\n sections.push(`# CORE IDENTITY\\n\\n${core}`);\n budget.used_tokens += estimateTokens(core);\n budget.loaded_files.push('CORE.md');\n }\n\n // --- Step 2: Load state.md ---\n const statePath = join(harnessDir, 'state.md');\n if (existsSync(statePath)) {\n const state = readFileSync(statePath, 'utf-8');\n sections.push(`# CURRENT STATE\\n\\n${state}`);\n budget.used_tokens += estimateTokens(state);\n budget.loaded_files.push('state.md');\n }\n\n // --- Step 3: Load SYSTEM.md (boot instructions) ---\n const systemPath = join(harnessDir, 'SYSTEM.md');\n if (existsSync(systemPath)) {\n const system = readFileSync(systemPath, 'utf-8');\n sections.push(`# SYSTEM\\n\\n${system}`);\n budget.used_tokens += estimateTokens(system);\n budget.loaded_files.push('SYSTEM.md');\n }\n\n // --- Step 4: Load all primitives at appropriate level ---\n const extDirs = config.extensions?.directories ?? [];\n const { primitives, errors: parseErrors } = loadAllPrimitivesWithErrors(harnessDir, extDirs);\n\n // Report parse errors\n if (parseErrors.length > 0) {\n for (const pe of parseErrors) {\n log.warn(`Failed to parse primitive: ${pe.path} — ${pe.error}`);\n }\n warnings.push(`${parseErrors.length} primitive file(s) failed to parse`);\n }\n\n const targetBudget = maxTokens * 0.15; // Use 15% of context for harness\n\n // Priority order for loading primitives (core dirs first, extensions appended)\n const priorityOrder = ['rules', 'instincts', 'skills', 'playbooks', 'tools', 'workflows', 'agents'];\n for (const dir of extDirs) {\n if (!priorityOrder.includes(dir)) {\n priorityOrder.push(dir);\n }\n }\n\n // Collect all docs to estimate total demand before deciding levels\n const allDocs: { category: string; doc: HarnessDocument }[] = [];\n for (const category of priorityOrder) {\n const docs = primitives.get(category);\n if (!docs || docs.length === 0) continue;\n for (const doc of docs) {\n allDocs.push({ category, doc });\n }\n }\n\n if (allDocs.length === 0) {\n warnings.push('No primitives found — add rules, instincts, or skills to improve agent behavior');\n }\n\n // Estimate total L2 demand vs available budget for primitives\n const primitiveBudget = targetBudget - budget.used_tokens;\n let totalL2Demand = 0;\n for (const { doc } of allDocs) {\n totalL2Demand += estimateTokens(getAtLevel(doc, 2));\n }\n\n // Choose a global disclosure level based on how much fits\n let globalLevel: 0 | 1 | 2;\n if (totalL2Demand <= primitiveBudget) {\n globalLevel = 2; // Everything fits at full\n } else {\n // Estimate L1 demand\n let totalL1Demand = 0;\n for (const { doc } of allDocs) {\n totalL1Demand += estimateTokens(getAtLevel(doc, 1));\n }\n globalLevel = totalL1Demand <= primitiveBudget ? 1 : 0;\n }\n\n for (const category of priorityOrder) {\n const docs = primitives.get(category);\n if (!docs || docs.length === 0) continue;\n\n const categoryLabel = category.toUpperCase();\n const categoryDocs: string[] = [];\n\n for (const doc of docs) {\n // Start from global level, fall back if this doc would exceed budget\n let level = globalLevel;\n let content = getAtLevel(doc, level);\n let tokens = estimateTokens(content);\n\n while (budget.used_tokens + tokens > targetBudget && level > 0) {\n level = (level - 1) as 0 | 1;\n content = getAtLevel(doc, level);\n tokens = estimateTokens(content);\n }\n\n categoryDocs.push(`### ${doc.frontmatter.id}\\n${content}`);\n budget.used_tokens += tokens;\n budget.loaded_files.push(doc.path);\n }\n\n if (categoryDocs.length > 0) {\n sections.push(`# ${categoryLabel}\\n\\n${categoryDocs.join('\\n\\n')}`);\n }\n }\n\n // --- Step 5: Load scratch.md if exists ---\n const scratchPath = join(harnessDir, 'memory', 'scratch.md');\n if (existsSync(scratchPath)) {\n const scratch = readFileSync(scratchPath, 'utf-8');\n if (scratch.trim()) {\n sections.push(`# SCRATCH (Current Working Memory)\\n\\n${scratch}`);\n budget.used_tokens += estimateTokens(scratch);\n budget.loaded_files.push('memory/scratch.md');\n }\n }\n\n budget.remaining = maxTokens - budget.used_tokens;\n\n // --- Step 6: Budget warnings ---\n const usagePercent = (budget.used_tokens / maxTokens) * 100;\n if (usagePercent > 12) {\n // System prompt using more than 80% of its 15% allocation\n warnings.push(\n `System prompt using ${usagePercent.toFixed(1)}% of total context ` +\n `(${budget.used_tokens}/${maxTokens} tokens) — some primitives may be truncated`,\n );\n log.warn(\n `Context budget high: ${budget.used_tokens}/${maxTokens} tokens ` +\n `(${usagePercent.toFixed(1)}%), ${budget.loaded_files.length} files loaded`,\n );\n }\n\n if (globalLevel < 2) {\n const levelName = globalLevel === 0 ? 'L0 (summary only)' : 'L1 (paragraph summary)';\n warnings.push(`Primitives loaded at ${levelName} due to budget constraints`);\n }\n\n return {\n systemPrompt: sections.join('\\n\\n---\\n\\n'),\n budget,\n parseErrors,\n warnings,\n };\n}\n","import { readFileSync, readdirSync, existsSync } from 'fs';\nimport { join, extname } from 'path';\nimport matter from 'gray-matter';\nimport { FrontmatterSchema, CORE_PRIMITIVE_DIRS, type HarnessDocument, type Frontmatter } from '../core/types.js';\n\nexport interface ParseError {\n path: string;\n error: string;\n}\n\nexport interface LoadResult {\n docs: HarnessDocument[];\n errors: ParseError[];\n}\n\n// Extract L0 and L1 from HTML comments at the top of the markdown body\n// Format: <!-- L0: one-line summary -->\n// <!-- L1: paragraph summary -->\nconst L0_REGEX = /<!--\\s*L0:\\s*([\\s\\S]*?)\\s*-->/;\nconst L1_REGEX = /<!--\\s*L1:\\s*([\\s\\S]*?)\\s*-->/;\n\nexport function parseHarnessDocument(filePath: string): HarnessDocument {\n const raw = readFileSync(filePath, 'utf-8');\n const { data, content } = matter(raw);\n\n // Parse frontmatter with defaults\n // Normalize dates: gray-matter converts date strings to Date objects\n const normalized = { ...data };\n for (const key of ['created', 'updated']) {\n if (normalized[key] instanceof Date) {\n normalized[key] = (normalized[key] as Date).toISOString().split('T')[0];\n }\n }\n\n let frontmatter: Frontmatter;\n try {\n frontmatter = FrontmatterSchema.parse(normalized);\n } catch {\n // Fallback: create minimal frontmatter from filename\n const id = filePath.split('/').pop()?.replace('.md', '') || 'unknown';\n frontmatter = FrontmatterSchema.parse({ id });\n }\n\n // Extract L0 and L1 from content\n const l0Match = content.match(L0_REGEX);\n const l1Match = content.match(L1_REGEX);\n\n const l0 = l0Match ? l0Match[1].trim() : '';\n const l1 = l1Match ? l1Match[1].trim() : '';\n\n // Body is the content without L0/L1 comments\n const body = content\n .replace(L0_REGEX, '')\n .replace(L1_REGEX, '')\n .trim();\n\n return {\n path: filePath,\n frontmatter,\n l0,\n l1,\n body,\n raw,\n };\n}\n\nexport function loadDirectory(dirPath: string): HarnessDocument[] {\n return loadDirectoryWithErrors(dirPath).docs;\n}\n\nexport function loadDirectoryWithErrors(dirPath: string): LoadResult {\n if (!existsSync(dirPath)) return { docs: [], errors: [] };\n\n const files = readdirSync(dirPath);\n const docs: HarnessDocument[] = [];\n const errors: ParseError[] = [];\n\n for (const file of files) {\n if (extname(file) !== '.md') continue;\n if (file.startsWith('_')) continue; // Skip index files\n if (file.startsWith('.')) continue; // Skip hidden files\n\n const filePath = join(dirPath, file);\n try {\n const doc = parseHarnessDocument(filePath);\n if (doc.frontmatter.status !== 'archived' && doc.frontmatter.status !== 'deprecated') {\n docs.push(doc);\n }\n } catch (err) {\n errors.push({\n path: filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return { docs, errors };\n}\n\nexport interface LoadAllResult {\n primitives: Map<string, HarnessDocument[]>;\n errors: ParseError[];\n}\n\nexport function loadAllPrimitives(harnessDir: string, extraDirs?: string[]): Map<string, HarnessDocument[]> {\n return loadAllPrimitivesWithErrors(harnessDir, extraDirs).primitives;\n}\n\nexport function loadAllPrimitivesWithErrors(harnessDir: string, extraDirs?: string[]): LoadAllResult {\n const primitives = new Map<string, HarnessDocument[]>();\n const allErrors: ParseError[] = [];\n\n const directories: string[] = [...CORE_PRIMITIVE_DIRS];\n if (extraDirs) {\n for (const dir of extraDirs) {\n if (!directories.includes(dir)) {\n directories.push(dir);\n }\n }\n }\n\n for (const dir of directories) {\n const { docs, errors } = loadDirectoryWithErrors(join(harnessDir, dir));\n primitives.set(dir, docs);\n allErrors.push(...errors);\n }\n\n return { primitives, errors: allErrors };\n}\n\n// Estimate token count (rough: 1 token ≈ 4 chars)\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n// Load a file at a specific disclosure level\nexport function getAtLevel(doc: HarnessDocument, level: 0 | 1 | 2): string {\n switch (level) {\n case 0:\n return doc.l0 || doc.frontmatter.id;\n case 1:\n return doc.l1 || doc.l0 || doc.body.slice(0, 400);\n case 2:\n return doc.body;\n }\n}\n","import { readFileSync, writeFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport type { AgentState } from '../core/types.js';\nimport { withFileLockSync } from './file-lock.js';\n\nconst DEFAULT_STATE: AgentState = {\n mode: 'idle',\n goals: [],\n active_workflows: [],\n last_interaction: new Date().toISOString(),\n unfinished_business: [],\n};\n\nexport function loadState(harnessDir: string): AgentState {\n const statePath = join(harnessDir, 'state.md');\n\n if (!existsSync(statePath)) {\n return { ...DEFAULT_STATE };\n }\n\n const content = readFileSync(statePath, 'utf-8');\n return parseStateMd(content);\n}\n\nexport function saveState(harnessDir: string, state: AgentState): void {\n const statePath = join(harnessDir, 'state.md');\n const content = renderStateMd(state);\n withFileLockSync(harnessDir, statePath, () => {\n writeFileSync(statePath, content, 'utf-8');\n });\n}\n\nfunction parseStateMd(content: string): AgentState {\n const state = { ...DEFAULT_STATE };\n\n const modeMatch = content.match(/## Mode\\s*\\n(.+)/);\n if (modeMatch) state.mode = modeMatch[1].trim();\n\n const goalsMatch = content.match(/## Goals\\s*\\n([\\s\\S]*?)(?=\\n## |\\n$|$)/);\n if (goalsMatch) {\n state.goals = goalsMatch[1]\n .split('\\n')\n .filter(l => l.startsWith('- '))\n .map(l => l.replace(/^- /, '').trim());\n }\n\n const workflowsMatch = content.match(/## Active Workflows\\s*\\n([\\s\\S]*?)(?=\\n## |\\n$|$)/);\n if (workflowsMatch) {\n state.active_workflows = workflowsMatch[1]\n .split('\\n')\n .filter(l => l.startsWith('- '))\n .map(l => l.replace(/^- /, '').trim());\n }\n\n const lastMatch = content.match(/## Last Interaction\\s*\\n(.+)/);\n if (lastMatch) state.last_interaction = lastMatch[1].trim();\n\n const unfinishedMatch = content.match(/## Unfinished Business\\s*\\n([\\s\\S]*?)(?=\\n## |\\n$|$)/);\n if (unfinishedMatch) {\n state.unfinished_business = unfinishedMatch[1]\n .split('\\n')\n .filter(l => l.startsWith('- '))\n .map(l => l.replace(/^- /, '').trim());\n }\n\n return state;\n}\n\nfunction renderStateMd(state: AgentState): string {\n const lines: string[] = [\n '# Agent State',\n '',\n '## Mode',\n state.mode,\n '',\n '## Goals',\n ...state.goals.map(g => `- ${g}`),\n '',\n '## Active Workflows',\n ...state.active_workflows.map(w => `- ${w}`),\n '',\n '## Last Interaction',\n state.last_interaction,\n '',\n '## Unfinished Business',\n ...state.unfinished_business.map(u => `- ${u}`),\n '',\n ];\n\n return lines.join('\\n');\n}\n","import { writeFileSync, unlinkSync, readFileSync, existsSync, mkdirSync } from 'fs';\nimport { join, basename } from 'path';\n\nexport interface LockInfo {\n pid: number;\n acquired: string;\n file: string;\n}\n\nexport interface LockOptions {\n /** Stale lock timeout in ms (default: 30000 = 30s) */\n staleMs?: number;\n /** How often to retry in ms (default: 50) */\n retryIntervalMs?: number;\n /** Max time to wait for lock in ms (default: 5000 = 5s) */\n waitMs?: number;\n}\n\nconst DEFAULT_STALE_MS = 30000;\nconst DEFAULT_RETRY_MS = 50;\nconst DEFAULT_WAIT_MS = 5000;\n\nfunction getLockDir(harnessDir: string): string {\n return join(harnessDir, 'memory');\n}\n\nfunction getLockPath(harnessDir: string, filePath: string): string {\n const lockDir = getLockDir(harnessDir);\n const lockName = basename(filePath).replace(/\\.[^.]+$/, '') + '.lock';\n return join(lockDir, lockName);\n}\n\n/**\n * Read lock info from a lock file. Returns null if missing or corrupt.\n */\nfunction readLockInfo(lockPath: string): LockInfo | null {\n if (!existsSync(lockPath)) return null;\n try {\n const content = readFileSync(lockPath, 'utf-8');\n const parsed: unknown = JSON.parse(content);\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n 'pid' in parsed &&\n 'acquired' in parsed\n ) {\n return parsed as LockInfo;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if a lock is stale (older than staleMs or held by dead process).\n */\nfunction isStale(info: LockInfo, staleMs: number): boolean {\n const age = Date.now() - new Date(info.acquired).getTime();\n if (age > staleMs) return true;\n\n // Check if the process that holds the lock is still alive\n try {\n process.kill(info.pid, 0);\n return false; // Process exists\n } catch {\n return true; // Process is dead\n }\n}\n\n/**\n * Try to acquire a file lock. Non-blocking — returns immediately.\n * Returns true if lock was acquired, false if already held.\n */\nexport function tryLock(harnessDir: string, filePath: string, options?: LockOptions): boolean {\n const staleMs = options?.staleMs ?? DEFAULT_STALE_MS;\n const lockPath = getLockPath(harnessDir, filePath);\n\n // Ensure lock directory exists\n const lockDir = getLockDir(harnessDir);\n if (!existsSync(lockDir)) {\n mkdirSync(lockDir, { recursive: true });\n }\n\n // Check existing lock\n const existing = readLockInfo(lockPath);\n if (existing) {\n if (isStale(existing, staleMs)) {\n // Stale lock — remove it\n try {\n unlinkSync(lockPath);\n } catch {\n // Another process may have already cleaned it up\n }\n } else {\n // Lock is valid and held by another process\n return false;\n }\n }\n\n // Write our lock file\n const info: LockInfo = {\n pid: process.pid,\n acquired: new Date().toISOString(),\n file: filePath,\n };\n\n try {\n // Use wx flag — fails if file already exists (atomic-ish on most systems)\n writeFileSync(lockPath, JSON.stringify(info), { flag: 'wx' });\n return true;\n } catch {\n // Another process got the lock between our check and write\n return false;\n }\n}\n\n/**\n * Release a file lock. Safe to call even if we don't hold it.\n */\nexport function releaseLock(harnessDir: string, filePath: string): void {\n const lockPath = getLockPath(harnessDir, filePath);\n\n if (!existsSync(lockPath)) return;\n\n // Only release if we own it\n const info = readLockInfo(lockPath);\n if (info && info.pid === process.pid) {\n try {\n unlinkSync(lockPath);\n } catch {\n // Already cleaned up\n }\n }\n}\n\n/**\n * Wait to acquire a file lock with timeout.\n * Polls at retryIntervalMs until lock is acquired or waitMs expires.\n */\nexport async function acquireLock(\n harnessDir: string,\n filePath: string,\n options?: LockOptions,\n): Promise<boolean> {\n const retryMs = options?.retryIntervalMs ?? DEFAULT_RETRY_MS;\n const waitMs = options?.waitMs ?? DEFAULT_WAIT_MS;\n const deadline = Date.now() + waitMs;\n\n while (Date.now() < deadline) {\n if (tryLock(harnessDir, filePath, options)) {\n return true;\n }\n await new Promise((resolve) => setTimeout(resolve, retryMs));\n }\n\n return false;\n}\n\n/**\n * Execute a function while holding a file lock.\n * Acquires lock, runs fn, releases lock (even on error).\n * If lock cannot be acquired within waitMs, runs fn anyway (fail-open).\n */\nexport async function withFileLock<T>(\n harnessDir: string,\n filePath: string,\n fn: () => T | Promise<T>,\n options?: LockOptions,\n): Promise<T> {\n const acquired = await acquireLock(harnessDir, filePath, options);\n\n try {\n return await fn();\n } finally {\n if (acquired) {\n releaseLock(harnessDir, filePath);\n }\n }\n}\n\n/**\n * Synchronous version of withFileLock for use in sync code paths.\n * Tries lock once — if fails, proceeds anyway (fail-open).\n */\nexport function withFileLockSync<T>(\n harnessDir: string,\n filePath: string,\n fn: () => T,\n options?: LockOptions,\n): T {\n const acquired = tryLock(harnessDir, filePath, options);\n\n try {\n return fn();\n } finally {\n if (acquired) {\n releaseLock(harnessDir, filePath);\n }\n }\n}\n\n/**\n * Check if a file is currently locked (by any process).\n */\nexport function isLocked(harnessDir: string, filePath: string, options?: LockOptions): boolean {\n const staleMs = options?.staleMs ?? DEFAULT_STALE_MS;\n const lockPath = getLockPath(harnessDir, filePath);\n const info = readLockInfo(lockPath);\n if (!info) return false;\n return !isStale(info, staleMs);\n}\n\n/**\n * Force-remove a lock regardless of who owns it.\n * Use only for manual cleanup via CLI.\n */\nexport function breakLock(harnessDir: string, filePath: string): boolean {\n const lockPath = getLockPath(harnessDir, filePath);\n if (!existsSync(lockPath)) return false;\n try {\n unlinkSync(lockPath);\n return true;\n } catch {\n return false;\n }\n}\n","import { writeFileSync, mkdirSync, existsSync, readdirSync, unlinkSync, copyFileSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport { withFileLockSync } from './file-lock.js';\nimport type { ToolCallInfo } from '../core/types.js';\n\nexport interface SessionRecord {\n id: string;\n started: string;\n ended: string;\n prompt: string;\n summary: string;\n tokens_used: number;\n steps: number;\n model_id?: string;\n delegated_to?: string;\n /** Tool calls executed during this session */\n tool_calls?: ToolCallInfo[];\n}\n\nexport function createSessionId(): string {\n const now = new Date();\n const date = now.toISOString().split('T')[0];\n const short = randomUUID().slice(0, 8);\n return `${date}-${short}`;\n}\n\n/** Format tool calls as markdown for session files */\nfunction formatToolCalls(toolCalls?: ToolCallInfo[]): string {\n if (!toolCalls || toolCalls.length === 0) return '';\n\n const lines = ['\\n## Tools Used\\n'];\n for (const tc of toolCalls) {\n lines.push(`### ${tc.toolName}`);\n const argsStr = JSON.stringify(tc.args, null, 2);\n lines.push(`**Args:** \\`${argsStr.length > 200 ? argsStr.slice(0, 200) + '...' : argsStr}\\``);\n if (tc.result !== null && tc.result !== undefined) {\n const resultStr = typeof tc.result === 'string' ? tc.result : JSON.stringify(tc.result);\n lines.push(`**Result:** ${resultStr.length > 300 ? resultStr.slice(0, 300) + '...' : resultStr}`);\n }\n lines.push('');\n }\n return lines.join('\\n');\n}\n\nexport function writeSession(harnessDir: string, session: SessionRecord): string {\n const sessionsDir = join(harnessDir, 'memory', 'sessions');\n if (!existsSync(sessionsDir)) {\n mkdirSync(sessionsDir, { recursive: true });\n }\n\n const filePath = join(sessionsDir, `${session.id}.md`);\n const tags = session.delegated_to\n ? `[session, delegation, ${session.delegated_to}]`\n : '[session]';\n const modelLine = session.model_id ? `\\n**Model:** ${session.model_id}` : '';\n const delegateLine = session.delegated_to ? `\\n**Delegated to:** ${session.delegated_to}` : '';\n const toolSection = formatToolCalls(session.tool_calls);\n\n const content = `---\nid: ${session.id}\ntags: ${tags}\ncreated: ${session.started}\nupdated: ${session.ended}\nauthor: agent\nstatus: active\nduration_minutes: ${Math.round((new Date(session.ended).getTime() - new Date(session.started).getTime()) / 60000)}\n---\n\n<!-- L0: Session ${session.id} — ${session.summary.slice(0, 60)} -->\n<!-- L1: ${session.summary} -->\n\n# Session: ${session.id}\n\n**Started:** ${session.started}\n**Ended:** ${session.ended}\n**Tokens:** ${session.tokens_used}\n**Steps:** ${session.steps}${modelLine}${delegateLine}\n\n## Prompt\n${session.prompt}\n\n## Summary\n${session.summary}\n${toolSection}`;\n\n withFileLockSync(harnessDir, filePath, () => {\n writeFileSync(filePath, content, 'utf-8');\n });\n return filePath;\n}\n\nexport interface CleanupResult {\n sessionsRemoved: number;\n journalsRemoved: number;\n sessionFiles: string[];\n journalFiles: string[];\n}\n\nexport interface ArchiveResult {\n sessionsArchived: number;\n journalsArchived: number;\n sessionFiles: string[];\n journalFiles: string[];\n}\n\n/**\n * Archive sessions and journals older than their configured retention periods.\n * Moves files to archive/YYYY-MM/ subdirectories instead of deleting them.\n * Archived files remain on disk for audit/query but aren't loaded by default.\n */\nexport function archiveOldFiles(\n harnessDir: string,\n sessionRetentionDays: number,\n journalRetentionDays: number,\n): ArchiveResult {\n const result: ArchiveResult = {\n sessionsArchived: 0,\n journalsArchived: 0,\n sessionFiles: [],\n journalFiles: [],\n };\n\n const now = Date.now();\n\n // Archive sessions\n const sessionsDir = join(harnessDir, 'memory', 'sessions');\n if (existsSync(sessionsDir)) {\n const cutoff = now - sessionRetentionDays * 24 * 60 * 60 * 1000;\n const files = readdirSync(sessionsDir).filter(\n (f) => f.endsWith('.md') && !f.startsWith('.') && !f.startsWith('_'),\n );\n\n for (const file of files) {\n const dateStr = extractDateFromFilename(file);\n if (dateStr && new Date(dateStr).getTime() < cutoff) {\n const yearMonth = dateStr.slice(0, 7); // YYYY-MM\n const archiveDir = join(sessionsDir, 'archive', yearMonth);\n mkdirSync(archiveDir, { recursive: true });\n copyFileSync(join(sessionsDir, file), join(archiveDir, file));\n unlinkSync(join(sessionsDir, file));\n result.sessionsArchived++;\n result.sessionFiles.push(file);\n }\n }\n }\n\n // Archive journals\n const journalDir = join(harnessDir, 'memory', 'journal');\n if (existsSync(journalDir)) {\n const cutoff = now - journalRetentionDays * 24 * 60 * 60 * 1000;\n const files = readdirSync(journalDir).filter(\n (f) => f.endsWith('.md') && !f.startsWith('.') && !f.startsWith('_'),\n );\n\n for (const file of files) {\n const dateStr = extractDateFromFilename(file);\n if (dateStr && new Date(dateStr).getTime() < cutoff) {\n const yearMonth = dateStr.slice(0, 7);\n const archiveDir = join(journalDir, 'archive', yearMonth);\n mkdirSync(archiveDir, { recursive: true });\n copyFileSync(join(journalDir, file), join(archiveDir, file));\n unlinkSync(join(journalDir, file));\n result.journalsArchived++;\n result.journalFiles.push(file);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Remove sessions and journals older than their configured retention periods.\n * @deprecated Use archiveOldFiles() instead — it preserves files in archive/.\n * This function deletes files permanently.\n */\nexport function cleanupOldFiles(\n harnessDir: string,\n sessionRetentionDays: number,\n journalRetentionDays: number,\n): CleanupResult {\n const result: CleanupResult = {\n sessionsRemoved: 0,\n journalsRemoved: 0,\n sessionFiles: [],\n journalFiles: [],\n };\n\n const now = Date.now();\n\n // Clean sessions\n const sessionsDir = join(harnessDir, 'memory', 'sessions');\n if (existsSync(sessionsDir)) {\n const cutoff = now - sessionRetentionDays * 24 * 60 * 60 * 1000;\n const files = readdirSync(sessionsDir).filter((f) => f.endsWith('.md') && !f.startsWith('.'));\n\n for (const file of files) {\n const dateStr = extractDateFromFilename(file);\n if (dateStr && new Date(dateStr).getTime() < cutoff) {\n unlinkSync(join(sessionsDir, file));\n result.sessionsRemoved++;\n result.sessionFiles.push(file);\n }\n }\n }\n\n // Clean journals\n const journalDir = join(harnessDir, 'memory', 'journal');\n if (existsSync(journalDir)) {\n const cutoff = now - journalRetentionDays * 24 * 60 * 60 * 1000;\n const files = readdirSync(journalDir).filter((f) => f.endsWith('.md') && !f.startsWith('.'));\n\n for (const file of files) {\n const dateStr = extractDateFromFilename(file);\n if (dateStr && new Date(dateStr).getTime() < cutoff) {\n unlinkSync(join(journalDir, file));\n result.journalsRemoved++;\n result.journalFiles.push(file);\n }\n }\n }\n\n return result;\n}\n\n/** Extract YYYY-MM-DD from filename like \"2026-04-06-abcdef12.md\" or \"2026-04-06.md\" */\nfunction extractDateFromFilename(filename: string): string | null {\n const match = filename.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (!match) return null;\n const date = new Date(match[1]);\n return isNaN(date.getTime()) ? null : match[1];\n}\n\n/** List all session files with their dates */\nexport function listSessions(harnessDir: string): Array<{ id: string; date: string; path: string }> {\n const sessionsDir = join(harnessDir, 'memory', 'sessions');\n if (!existsSync(sessionsDir)) return [];\n\n return readdirSync(sessionsDir)\n .filter((f) => f.endsWith('.md') && !f.startsWith('.'))\n .sort()\n .reverse()\n .map((f) => ({\n id: f.replace('.md', ''),\n date: extractDateFromFilename(f) || 'unknown',\n path: join(sessionsDir, f),\n }));\n}\n\n/** List files that would be removed by cleanup (dry run — doesn't delete) */\nexport function listExpiredFiles(\n harnessDir: string,\n sessionRetentionDays: number,\n journalRetentionDays: number,\n): { sessionFiles: string[]; journalFiles: string[] } {\n const now = Date.now();\n const sessionFiles: string[] = [];\n const journalFiles: string[] = [];\n\n const sessionsDir = join(harnessDir, 'memory', 'sessions');\n if (existsSync(sessionsDir)) {\n const cutoff = now - sessionRetentionDays * 24 * 60 * 60 * 1000;\n const files = readdirSync(sessionsDir).filter((f) => f.endsWith('.md') && !f.startsWith('.'));\n for (const file of files) {\n const dateStr = extractDateFromFilename(file);\n if (dateStr && new Date(dateStr).getTime() < cutoff) {\n sessionFiles.push(file);\n }\n }\n }\n\n const journalDir = join(harnessDir, 'memory', 'journal');\n if (existsSync(journalDir)) {\n const cutoff = now - journalRetentionDays * 24 * 60 * 60 * 1000;\n const files = readdirSync(journalDir).filter((f) => f.endsWith('.md') && !f.startsWith('.'));\n for (const file of files) {\n const dateStr = extractDateFromFilename(file);\n if (dateStr && new Date(dateStr).getTime() < cutoff) {\n journalFiles.push(file);\n }\n }\n }\n\n return { sessionFiles, journalFiles };\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';\nimport { join } from 'path';\n\n/** Cost per 1M tokens for a model (input and output separately) */\nexport interface ModelPricing {\n model_pattern: string;\n input_per_million: number;\n output_per_million: number;\n}\n\n/** A recorded cost event */\nexport interface CostEntry {\n timestamp: string;\n model_id: string;\n provider: string;\n input_tokens: number;\n output_tokens: number;\n cost_usd: number;\n source: string;\n}\n\n/** Budget configuration */\nexport interface BudgetConfig {\n daily_limit_usd?: number;\n monthly_limit_usd?: number;\n alert_threshold_pct?: number;\n}\n\n/** Budget status check result */\nexport interface BudgetStatus {\n daily_spent_usd: number;\n daily_limit_usd: number | null;\n daily_remaining_usd: number | null;\n daily_pct: number | null;\n monthly_spent_usd: number;\n monthly_limit_usd: number | null;\n monthly_remaining_usd: number | null;\n monthly_pct: number | null;\n alerts: string[];\n}\n\n/** Spending summary for a time period */\nexport interface SpendingSummary {\n total_cost_usd: number;\n total_input_tokens: number;\n total_output_tokens: number;\n entries: number;\n by_model: Record<string, { cost_usd: number; input_tokens: number; output_tokens: number; count: number }>;\n by_provider: Record<string, { cost_usd: number; count: number }>;\n}\n\n/** Persisted cost store */\nexport interface CostStore {\n entries: CostEntry[];\n updated: string;\n}\n\nconst COST_FILE = 'costs.json';\nconst MAX_ENTRIES = 5000;\n\n/** Default pricing for common models (per 1M tokens) */\nconst DEFAULT_PRICING: ModelPricing[] = [\n // Anthropic via OpenRouter\n { model_pattern: 'anthropic/claude-sonnet-4', input_per_million: 3.0, output_per_million: 15.0 },\n { model_pattern: 'anthropic/claude-opus-4', input_per_million: 15.0, output_per_million: 75.0 },\n { model_pattern: 'anthropic/claude-haiku-3.5', input_per_million: 0.8, output_per_million: 4.0 },\n // Direct Anthropic\n { model_pattern: 'claude-sonnet-4', input_per_million: 3.0, output_per_million: 15.0 },\n { model_pattern: 'claude-opus-4', input_per_million: 15.0, output_per_million: 75.0 },\n { model_pattern: 'claude-haiku-3.5', input_per_million: 0.8, output_per_million: 4.0 },\n // OpenAI\n { model_pattern: 'openai/gpt-4o', input_per_million: 2.5, output_per_million: 10.0 },\n { model_pattern: 'gpt-4o', input_per_million: 2.5, output_per_million: 10.0 },\n { model_pattern: 'openai/gpt-4o-mini', input_per_million: 0.15, output_per_million: 0.6 },\n { model_pattern: 'gpt-4o-mini', input_per_million: 0.15, output_per_million: 0.6 },\n // Local models\n { model_pattern: 'local/', input_per_million: 0, output_per_million: 0 },\n];\n\nfunction getStorePath(harnessDir: string): string {\n return join(harnessDir, 'memory', COST_FILE);\n}\n\n/**\n * Load cost entries from disk.\n */\nexport function loadCosts(harnessDir: string): CostStore {\n const storePath = getStorePath(harnessDir);\n if (!existsSync(storePath)) {\n return { entries: [], updated: new Date().toISOString() };\n }\n\n try {\n const content = readFileSync(storePath, 'utf-8');\n const parsed: unknown = JSON.parse(content);\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n 'entries' in parsed &&\n Array.isArray((parsed as CostStore).entries)\n ) {\n return parsed as CostStore;\n }\n return { entries: [], updated: new Date().toISOString() };\n } catch {\n return { entries: [], updated: new Date().toISOString() };\n }\n}\n\n/**\n * Save cost entries to disk. Trims to MAX_ENTRIES.\n */\nexport function saveCosts(harnessDir: string, store: CostStore): void {\n const memoryDir = join(harnessDir, 'memory');\n if (!existsSync(memoryDir)) {\n mkdirSync(memoryDir, { recursive: true });\n }\n\n if (store.entries.length > MAX_ENTRIES) {\n store.entries = store.entries.slice(store.entries.length - MAX_ENTRIES);\n }\n\n store.updated = new Date().toISOString();\n writeFileSync(getStorePath(harnessDir), JSON.stringify(store, null, 2), 'utf-8');\n}\n\n/**\n * Find pricing for a model ID. Uses prefix matching against DEFAULT_PRICING.\n * Custom pricing can be passed to override defaults.\n */\nexport function findPricing(\n modelId: string,\n customPricing?: ModelPricing[],\n): ModelPricing | null {\n const allPricing = [...(customPricing ?? []), ...DEFAULT_PRICING];\n\n for (const pricing of allPricing) {\n if (modelId === pricing.model_pattern || modelId.startsWith(pricing.model_pattern)) {\n return pricing;\n }\n }\n\n return null;\n}\n\n/**\n * Calculate cost in USD for a given usage.\n */\nexport function calculateCost(\n modelId: string,\n inputTokens: number,\n outputTokens: number,\n customPricing?: ModelPricing[],\n): number {\n const pricing = findPricing(modelId, customPricing);\n if (!pricing) return 0;\n\n const inputCost = (inputTokens / 1_000_000) * pricing.input_per_million;\n const outputCost = (outputTokens / 1_000_000) * pricing.output_per_million;\n return Math.round((inputCost + outputCost) * 1_000_000) / 1_000_000;\n}\n\n/**\n * Record a cost entry.\n */\nexport function recordCost(\n harnessDir: string,\n entry: Omit<CostEntry, 'timestamp' | 'cost_usd'> & { cost_usd?: number },\n customPricing?: ModelPricing[],\n): CostEntry {\n const store = loadCosts(harnessDir);\n\n const costUsd = entry.cost_usd ?? calculateCost(\n entry.model_id,\n entry.input_tokens,\n entry.output_tokens,\n customPricing,\n );\n\n const fullEntry: CostEntry = {\n timestamp: new Date().toISOString(),\n model_id: entry.model_id,\n provider: entry.provider,\n input_tokens: entry.input_tokens,\n output_tokens: entry.output_tokens,\n cost_usd: costUsd,\n source: entry.source,\n };\n\n store.entries.push(fullEntry);\n saveCosts(harnessDir, store);\n\n return fullEntry;\n}\n\n/**\n * Get spending summary for a date range.\n * Defaults to today if no range specified.\n */\nexport function getSpending(\n harnessDir: string,\n from?: string,\n to?: string,\n): SpendingSummary {\n const store = loadCosts(harnessDir);\n\n const fromDate = from ?? new Date().toISOString().split('T')[0];\n const toDate = to ?? new Date(Date.now() + 86400000).toISOString().split('T')[0];\n\n const filtered = store.entries.filter(\n (e) => e.timestamp >= fromDate && e.timestamp < toDate + 'T99',\n );\n\n const byModel: SpendingSummary['by_model'] = {};\n const byProvider: SpendingSummary['by_provider'] = {};\n\n let totalCost = 0;\n let totalInput = 0;\n let totalOutput = 0;\n\n for (const entry of filtered) {\n totalCost += entry.cost_usd;\n totalInput += entry.input_tokens;\n totalOutput += entry.output_tokens;\n\n if (!byModel[entry.model_id]) {\n byModel[entry.model_id] = { cost_usd: 0, input_tokens: 0, output_tokens: 0, count: 0 };\n }\n byModel[entry.model_id].cost_usd += entry.cost_usd;\n byModel[entry.model_id].input_tokens += entry.input_tokens;\n byModel[entry.model_id].output_tokens += entry.output_tokens;\n byModel[entry.model_id].count += 1;\n\n if (!byProvider[entry.provider]) {\n byProvider[entry.provider] = { cost_usd: 0, count: 0 };\n }\n byProvider[entry.provider].cost_usd += entry.cost_usd;\n byProvider[entry.provider].count += 1;\n }\n\n return {\n total_cost_usd: Math.round(totalCost * 1_000_000) / 1_000_000,\n total_input_tokens: totalInput,\n total_output_tokens: totalOutput,\n entries: filtered.length,\n by_model: byModel,\n by_provider: byProvider,\n };\n}\n\n/**\n * Check budget status against configured limits.\n */\nexport function checkBudget(\n harnessDir: string,\n budget: BudgetConfig,\n): BudgetStatus {\n const now = new Date();\n const today = now.toISOString().split('T')[0];\n const monthStart = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-01`;\n\n const dailySpending = getSpending(harnessDir, today);\n const monthlySpending = getSpending(harnessDir, monthStart);\n\n const alerts: string[] = [];\n const alertPct = budget.alert_threshold_pct ?? 80;\n\n const dailyLimit = budget.daily_limit_usd ?? null;\n const monthlyLimit = budget.monthly_limit_usd ?? null;\n\n let dailyPct: number | null = null;\n let dailyRemaining: number | null = null;\n\n if (dailyLimit !== null) {\n dailyPct = dailyLimit > 0 ? (dailySpending.total_cost_usd / dailyLimit) * 100 : 0;\n dailyRemaining = Math.max(0, dailyLimit - dailySpending.total_cost_usd);\n\n if (dailySpending.total_cost_usd >= dailyLimit) {\n alerts.push(`Daily budget exceeded: $${dailySpending.total_cost_usd.toFixed(4)} / $${dailyLimit.toFixed(2)}`);\n } else if (dailyPct >= alertPct) {\n alerts.push(`Daily budget at ${dailyPct.toFixed(0)}%: $${dailySpending.total_cost_usd.toFixed(4)} / $${dailyLimit.toFixed(2)}`);\n }\n }\n\n let monthlyPct: number | null = null;\n let monthlyRemaining: number | null = null;\n\n if (monthlyLimit !== null) {\n monthlyPct = monthlyLimit > 0 ? (monthlySpending.total_cost_usd / monthlyLimit) * 100 : 0;\n monthlyRemaining = Math.max(0, monthlyLimit - monthlySpending.total_cost_usd);\n\n if (monthlySpending.total_cost_usd >= monthlyLimit) {\n alerts.push(`Monthly budget exceeded: $${monthlySpending.total_cost_usd.toFixed(4)} / $${monthlyLimit.toFixed(2)}`);\n } else if (monthlyPct >= alertPct) {\n alerts.push(`Monthly budget at ${monthlyPct.toFixed(0)}%: $${monthlySpending.total_cost_usd.toFixed(4)} / $${monthlyLimit.toFixed(2)}`);\n }\n }\n\n return {\n daily_spent_usd: dailySpending.total_cost_usd,\n daily_limit_usd: dailyLimit,\n daily_remaining_usd: dailyRemaining,\n daily_pct: dailyPct,\n monthly_spent_usd: monthlySpending.total_cost_usd,\n monthly_limit_usd: monthlyLimit,\n monthly_remaining_usd: monthlyRemaining,\n monthly_pct: monthlyPct,\n alerts,\n };\n}\n\n/**\n * Clear all cost entries, or entries for a specific model.\n */\nexport function clearCosts(harnessDir: string, modelId?: string): number {\n const store = loadCosts(harnessDir);\n const before = store.entries.length;\n\n if (modelId) {\n store.entries = store.entries.filter((e) => e.model_id !== modelId);\n } else {\n store.entries = [];\n }\n\n saveCosts(harnessDir, store);\n return before - store.entries.length;\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { getSpending } from './cost-tracker.js';\n\n/** Individual health check result */\nexport interface HealthCheck {\n name: string;\n status: 'pass' | 'warn' | 'fail';\n message: string;\n}\n\n/** Persisted health metrics */\nexport interface HealthMetrics {\n lastSuccessfulRun: string | null;\n lastFailedRun: string | null;\n lastError: string | null;\n consecutiveFailures: number;\n totalRuns: number;\n totalSuccesses: number;\n totalFailures: number;\n bootedAt: string | null;\n updatedAt: string;\n}\n\n/** Overall health status */\nexport interface HealthStatus {\n status: 'healthy' | 'degraded' | 'unhealthy';\n checks: HealthCheck[];\n metrics: HealthMetrics;\n costToday: number;\n costThisMonth: number;\n}\n\nconst HEALTH_FILE = 'health.json';\n\nfunction getHealthPath(harnessDir: string): string {\n return join(harnessDir, 'memory', HEALTH_FILE);\n}\n\nfunction defaultMetrics(): HealthMetrics {\n return {\n lastSuccessfulRun: null,\n lastFailedRun: null,\n lastError: null,\n consecutiveFailures: 0,\n totalRuns: 0,\n totalSuccesses: 0,\n totalFailures: 0,\n bootedAt: null,\n updatedAt: new Date().toISOString(),\n };\n}\n\n/**\n * Load health metrics from disk.\n */\nexport function loadHealth(harnessDir: string): HealthMetrics {\n const healthPath = getHealthPath(harnessDir);\n if (!existsSync(healthPath)) {\n return defaultMetrics();\n }\n\n try {\n const content = readFileSync(healthPath, 'utf-8');\n const parsed: unknown = JSON.parse(content);\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n 'totalRuns' in parsed\n ) {\n return parsed as HealthMetrics;\n }\n return defaultMetrics();\n } catch {\n return defaultMetrics();\n }\n}\n\n/**\n * Save health metrics to disk.\n */\nexport function saveHealth(harnessDir: string, metrics: HealthMetrics): void {\n const memoryDir = join(harnessDir, 'memory');\n if (!existsSync(memoryDir)) {\n mkdirSync(memoryDir, { recursive: true });\n }\n\n metrics.updatedAt = new Date().toISOString();\n writeFileSync(getHealthPath(harnessDir), JSON.stringify(metrics, null, 2), 'utf-8');\n}\n\n/**\n * Record a successful run.\n */\nexport function recordSuccess(harnessDir: string): void {\n const metrics = loadHealth(harnessDir);\n metrics.totalRuns++;\n metrics.totalSuccesses++;\n metrics.consecutiveFailures = 0;\n metrics.lastSuccessfulRun = new Date().toISOString();\n saveHealth(harnessDir, metrics);\n}\n\n/**\n * Record a failed run.\n */\nexport function recordFailure(harnessDir: string, error?: string): void {\n const metrics = loadHealth(harnessDir);\n metrics.totalRuns++;\n metrics.totalFailures++;\n metrics.consecutiveFailures++;\n metrics.lastFailedRun = new Date().toISOString();\n metrics.lastError = error ?? null;\n saveHealth(harnessDir, metrics);\n}\n\n/**\n * Record boot time.\n */\nexport function recordBoot(harnessDir: string): void {\n const metrics = loadHealth(harnessDir);\n metrics.bootedAt = new Date().toISOString();\n saveHealth(harnessDir, metrics);\n}\n\n/**\n * Run all health checks and return overall status.\n */\nexport function getHealthStatus(harnessDir: string): HealthStatus {\n const metrics = loadHealth(harnessDir);\n const checks: HealthCheck[] = [];\n\n // Check 1: Required files exist\n const requiredFiles = ['CORE.md', 'config.yaml', 'state.md'];\n const missingFiles = requiredFiles.filter((f) => !existsSync(join(harnessDir, f)));\n if (missingFiles.length === 0) {\n checks.push({ name: 'core-files', status: 'pass', message: 'All core files present' });\n } else {\n checks.push({ name: 'core-files', status: 'fail', message: `Missing: ${missingFiles.join(', ')}` });\n }\n\n // Check 2: Memory directory exists\n const memoryDir = join(harnessDir, 'memory');\n if (existsSync(memoryDir)) {\n checks.push({ name: 'memory-dir', status: 'pass', message: 'Memory directory exists' });\n } else {\n checks.push({ name: 'memory-dir', status: 'fail', message: 'Memory directory missing' });\n }\n\n // Check 3: API key availability\n const apiKeys: Array<{ name: string; envVar: string }> = [\n { name: 'OpenRouter', envVar: 'OPENROUTER_API_KEY' },\n { name: 'Anthropic', envVar: 'ANTHROPIC_API_KEY' },\n { name: 'OpenAI', envVar: 'OPENAI_API_KEY' },\n ];\n const presentKeys = apiKeys.filter((k) => process.env[k.envVar]);\n if (presentKeys.length > 0) {\n checks.push({\n name: 'api-keys',\n status: 'pass',\n message: `API keys: ${presentKeys.map((k) => k.name).join(', ')}`,\n });\n } else {\n checks.push({ name: 'api-keys', status: 'warn', message: 'No API keys found in environment' });\n }\n\n // Check 4: Consecutive failures\n if (metrics.consecutiveFailures === 0) {\n checks.push({ name: 'run-health', status: 'pass', message: 'No consecutive failures' });\n } else if (metrics.consecutiveFailures < 3) {\n checks.push({\n name: 'run-health',\n status: 'warn',\n message: `${metrics.consecutiveFailures} consecutive failure(s)`,\n });\n } else {\n checks.push({\n name: 'run-health',\n status: 'fail',\n message: `${metrics.consecutiveFailures} consecutive failures — last error: ${metrics.lastError ?? 'unknown'}`,\n });\n }\n\n // Check 5: Last run recency (warn if no successful run in 24h when there have been runs)\n if (metrics.lastSuccessfulRun) {\n const hoursSinceSuccess = (Date.now() - new Date(metrics.lastSuccessfulRun).getTime()) / 3600000;\n if (hoursSinceSuccess < 24) {\n checks.push({ name: 'last-success', status: 'pass', message: `Last success: ${metrics.lastSuccessfulRun}` });\n } else {\n checks.push({\n name: 'last-success',\n status: 'warn',\n message: `Last success was ${Math.round(hoursSinceSuccess)}h ago`,\n });\n }\n } else if (metrics.totalRuns > 0) {\n checks.push({ name: 'last-success', status: 'warn', message: 'No successful runs recorded' });\n }\n\n // Cost checks\n let costToday = 0;\n let costThisMonth = 0;\n\n try {\n const today = new Date().toISOString().split('T')[0];\n const monthStart = `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}-01`;\n costToday = getSpending(harnessDir, today).total_cost_usd;\n costThisMonth = getSpending(harnessDir, monthStart).total_cost_usd;\n } catch {\n // Cost data may not exist\n }\n\n // Determine overall status\n const failCount = checks.filter((c) => c.status === 'fail').length;\n const warnCount = checks.filter((c) => c.status === 'warn').length;\n\n let status: HealthStatus['status'];\n if (failCount > 0) {\n status = 'unhealthy';\n } else if (warnCount > 0) {\n status = 'degraded';\n } else {\n status = 'healthy';\n }\n\n return { status, checks, metrics, costToday, costThisMonth };\n}\n\n/**\n * Reset health metrics (for testing or fresh start).\n */\nexport function resetHealth(harnessDir: string): void {\n saveHealth(harnessDir, defaultMetrics());\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';\nimport { join } from 'path';\n\n/** A recorded event in the sliding window */\nexport interface RateEvent {\n key: string;\n timestamp: number;\n}\n\n/** Rate limit rule: max requests per window_ms */\nexport interface RateLimit {\n key: string;\n max_requests: number;\n window_ms: number;\n}\n\n/** Result of a rate limit check */\nexport interface RateLimitCheck {\n allowed: boolean;\n key: string;\n current: number;\n max: number;\n window_ms: number;\n /** ms until oldest event expires (0 if allowed) */\n retry_after_ms: number;\n}\n\n/** Persisted rate limit state */\nexport interface RateLimitStore {\n events: RateEvent[];\n updated: string;\n}\n\nconst RATE_FILE = 'rate-limits.json';\nconst MAX_EVENTS = 10000;\n\nfunction getStorePath(harnessDir: string): string {\n return join(harnessDir, 'memory', RATE_FILE);\n}\n\n/**\n * Load rate limit events from disk.\n * Returns empty store if file doesn't exist or is corrupt.\n */\nexport function loadRateLimits(harnessDir: string): RateLimitStore {\n const storePath = getStorePath(harnessDir);\n if (!existsSync(storePath)) {\n return { events: [], updated: new Date().toISOString() };\n }\n\n try {\n const content = readFileSync(storePath, 'utf-8');\n const parsed: unknown = JSON.parse(content);\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n 'events' in parsed &&\n Array.isArray((parsed as RateLimitStore).events)\n ) {\n return parsed as RateLimitStore;\n }\n return { events: [], updated: new Date().toISOString() };\n } catch {\n return { events: [], updated: new Date().toISOString() };\n }\n}\n\n/**\n * Save rate limit events to disk. Trims to MAX_EVENTS.\n */\nexport function saveRateLimits(harnessDir: string, store: RateLimitStore): void {\n const memoryDir = join(harnessDir, 'memory');\n if (!existsSync(memoryDir)) {\n mkdirSync(memoryDir, { recursive: true });\n }\n\n if (store.events.length > MAX_EVENTS) {\n store.events = store.events.slice(store.events.length - MAX_EVENTS);\n }\n\n store.updated = new Date().toISOString();\n writeFileSync(getStorePath(harnessDir), JSON.stringify(store, null, 2), 'utf-8');\n}\n\n/**\n * Prune expired events from the store (older than the largest known window).\n */\nfunction pruneExpired(store: RateLimitStore, now: number, maxWindowMs: number): void {\n const cutoff = now - maxWindowMs;\n store.events = store.events.filter((e) => e.timestamp > cutoff);\n}\n\n/**\n * Check if a request is allowed under the given rate limit.\n * Does NOT record the event — call recordEvent() separately on success.\n */\nexport function checkRateLimit(\n harnessDir: string,\n limit: RateLimit,\n now?: number,\n): RateLimitCheck {\n const currentTime = now ?? Date.now();\n const store = loadRateLimits(harnessDir);\n\n const windowStart = currentTime - limit.window_ms;\n const eventsInWindow = store.events.filter(\n (e) => e.key === limit.key && e.timestamp > windowStart,\n );\n\n const current = eventsInWindow.length;\n const allowed = current < limit.max_requests;\n\n let retryAfterMs = 0;\n if (!allowed && eventsInWindow.length > 0) {\n // Time until the oldest event in the window expires\n const oldest = eventsInWindow.reduce((min, e) => Math.min(min, e.timestamp), Infinity);\n retryAfterMs = Math.max(0, oldest + limit.window_ms - currentTime);\n }\n\n return {\n allowed,\n key: limit.key,\n current,\n max: limit.max_requests,\n window_ms: limit.window_ms,\n retry_after_ms: retryAfterMs,\n };\n}\n\n/**\n * Record a rate limit event for a key.\n */\nexport function recordEvent(harnessDir: string, key: string, now?: number): void {\n const currentTime = now ?? Date.now();\n const store = loadRateLimits(harnessDir);\n\n store.events.push({ key, timestamp: currentTime });\n\n // Prune events older than 1 hour to keep the store manageable\n pruneExpired(store, currentTime, 3600000);\n\n saveRateLimits(harnessDir, store);\n}\n\n/**\n * Check rate limit AND record the event if allowed.\n * Returns the check result. If not allowed, does NOT record.\n */\nexport function tryAcquire(\n harnessDir: string,\n limit: RateLimit,\n now?: number,\n): RateLimitCheck {\n const currentTime = now ?? Date.now();\n const check = checkRateLimit(harnessDir, limit, currentTime);\n\n if (check.allowed) {\n recordEvent(harnessDir, limit.key, currentTime);\n }\n\n return check;\n}\n\n/**\n * Get current usage for a key within a window.\n */\nexport function getUsage(\n harnessDir: string,\n key: string,\n windowMs: number,\n now?: number,\n): { count: number; oldest: number | null; newest: number | null } {\n const currentTime = now ?? Date.now();\n const store = loadRateLimits(harnessDir);\n\n const windowStart = currentTime - windowMs;\n const eventsInWindow = store.events.filter(\n (e) => e.key === key && e.timestamp > windowStart,\n );\n\n if (eventsInWindow.length === 0) {\n return { count: 0, oldest: null, newest: null };\n }\n\n const timestamps = eventsInWindow.map((e) => e.timestamp);\n return {\n count: eventsInWindow.length,\n oldest: Math.min(...timestamps),\n newest: Math.max(...timestamps),\n };\n}\n\n/**\n * Clear all rate limit events for a key, or all keys.\n */\nexport function clearRateLimits(harnessDir: string, key?: string): number {\n const store = loadRateLimits(harnessDir);\n const before = store.events.length;\n\n if (key) {\n store.events = store.events.filter((e) => e.key !== key);\n } else {\n store.events = [];\n }\n\n saveRateLimits(harnessDir, store);\n return before - store.events.length;\n}\n","import { recordEvent, checkRateLimit } from './rate-limiter.js';\nimport { checkBudget } from './cost-tracker.js';\nimport type { HarnessConfig } from '../core/types.js';\nimport type { RateLimit, RateLimitCheck } from './rate-limiter.js';\nimport type { BudgetStatus } from './cost-tracker.js';\n\n/** Result of a guardrail check before an LLM call. */\nexport interface GuardrailResult {\n allowed: boolean;\n reason: string | null;\n rateLimitCheck: RateLimitCheck | null;\n budgetStatus: BudgetStatus | null;\n /** Suggested wait time in ms if rate-limited (0 otherwise) */\n retryAfterMs: number;\n}\n\nconst RATE_KEY = 'llm-calls';\n\n/**\n * Build rate limit rules from config.\n * Returns an array of limits to check (per-minute, per-hour, per-day).\n */\nexport function buildRateLimits(config: HarnessConfig): RateLimit[] {\n const limits: RateLimit[] = [];\n const rl = config.rate_limits;\n\n if (rl?.per_minute) {\n limits.push({ key: `${RATE_KEY}:minute`, max_requests: rl.per_minute, window_ms: 60_000 });\n }\n if (rl?.per_hour) {\n limits.push({ key: `${RATE_KEY}:hour`, max_requests: rl.per_hour, window_ms: 3_600_000 });\n }\n if (rl?.per_day) {\n limits.push({ key: `${RATE_KEY}:day`, max_requests: rl.per_day, window_ms: 86_400_000 });\n }\n\n return limits;\n}\n\n/**\n * Check all guardrails (rate limits + budget) before an LLM call.\n *\n * Rate limits: Checks all configured limits. If any limit is exceeded,\n * the call is blocked with `retry_after_ms` from the first violated limit.\n *\n * Budget: Checks daily and monthly spending limits. If `budget.enforce` is true\n * and any limit is exceeded, the call is blocked.\n *\n * Returns { allowed: true } if all checks pass.\n */\nexport function checkGuardrails(\n harnessDir: string,\n config: HarnessConfig,\n): GuardrailResult {\n // Check rate limits\n const limits = buildRateLimits(config);\n for (const limit of limits) {\n const check = checkRateLimit(harnessDir, limit);\n if (!check.allowed) {\n const windowLabel = limit.window_ms <= 60_000 ? 'minute' : limit.window_ms <= 3_600_000 ? 'hour' : 'day';\n return {\n allowed: false,\n reason: `Rate limit exceeded: ${check.current}/${check.max} calls per ${windowLabel}. Retry after ${Math.ceil(check.retry_after_ms / 1000)}s.`,\n rateLimitCheck: check,\n budgetStatus: null,\n retryAfterMs: check.retry_after_ms,\n };\n }\n }\n\n // Check budget\n const budgetConfig = config.budget;\n if (budgetConfig?.enforce !== false && (budgetConfig?.daily_limit_usd || budgetConfig?.monthly_limit_usd)) {\n const status = checkBudget(harnessDir, {\n daily_limit_usd: budgetConfig.daily_limit_usd,\n monthly_limit_usd: budgetConfig.monthly_limit_usd,\n });\n\n const exceeded = status.alerts.some((a) => a.includes('exceeded'));\n if (exceeded) {\n return {\n allowed: false,\n reason: status.alerts.filter((a) => a.includes('exceeded')).join('; '),\n rateLimitCheck: null,\n budgetStatus: status,\n retryAfterMs: 0,\n };\n }\n }\n\n // All checks pass — record rate limit events for all configured limits\n const now = Date.now();\n for (const limit of limits) {\n recordEvent(harnessDir, limit.key, now);\n }\n\n return {\n allowed: true,\n reason: null,\n rateLimitCheck: null,\n budgetStatus: null,\n retryAfterMs: 0,\n };\n}\n","import { tool as aiTool, jsonSchema, type ToolSet } from 'ai';\nimport { z } from 'zod';\nimport { loadTools, type ToolDefinition, type ToolOperation } from './tools.js';\nimport type { HarnessConfig } from '../core/types.js';\nimport { log } from '../core/logger.js';\n\n// --- Types ---\n\n/** Result of a single tool execution */\nexport interface ToolCallResult {\n toolName: string;\n input: Record<string, unknown>;\n output: unknown;\n durationMs: number;\n error: string | null;\n}\n\n/** Record of all tool calls in a run (for session recording) */\nexport interface ToolCallRecord {\n calls: ToolCallResult[];\n totalDurationMs: number;\n}\n\n/** A programmatic tool definition (not from markdown) */\nexport interface ProgrammaticTool {\n name: string;\n description: string;\n inputSchema: z.ZodType;\n execute: (input: Record<string, unknown>) => Promise<unknown>;\n}\n\n/** Configuration for tool execution */\nexport interface ToolExecutorConfig {\n /** Maximum tool calls per run (default: 10) */\n maxToolCalls?: number;\n /** Timeout per tool call in ms (default: 30000) */\n toolTimeoutMs?: number;\n /** Whether to allow HTTP tool execution (default: true) */\n allowHttpExecution?: boolean;\n /** Additional programmatic tools */\n tools?: ProgrammaticTool[];\n}\n\n/** AI SDK ToolSet — record of named tool definitions */\nexport type AIToolSet = ToolSet;\n\n// --- HTTP Execution ---\n\n/**\n * Resolve a URL template by replacing `{param}` placeholders with input values.\n * E.g., `/repos/{owner}/{repo}/pulls` with { owner: 'a', repo: 'b' } → `/repos/a/b/pulls`\n */\nexport function resolveEndpoint(endpoint: string, input: Record<string, unknown>): string {\n return endpoint.replace(/\\{(\\w+)\\}/g, (_match, key: string) => {\n const value = input[key];\n if (value === undefined || value === null) {\n return `{${key}}`;\n }\n return encodeURIComponent(String(value));\n });\n}\n\n/**\n * Build a JSON Schema object for a tool operation's URL parameters.\n * Extracts `{param}` patterns from the endpoint URL and creates string properties for each.\n */\nexport function buildOperationSchema(operation: ToolOperation): Record<string, unknown> {\n const params: string[] = [];\n const paramRegex = /\\{(\\w+)\\}/g;\n let match: RegExpExecArray | null;\n while ((match = paramRegex.exec(operation.endpoint)) !== null) {\n params.push(match[1]);\n }\n\n const properties: Record<string, { type: string; description: string }> = {};\n for (const param of params) {\n properties[param] = { type: 'string', description: `Value for ${param}` };\n }\n\n // Add a body property for POST/PUT/PATCH\n if (['POST', 'PUT', 'PATCH'].includes(operation.method)) {\n properties['body'] = { type: 'string', description: 'Request body (JSON string)' };\n }\n\n // Add optional query parameters\n properties['query'] = { type: 'string', description: 'Query parameters (key=value&key2=value2)' };\n\n return {\n type: 'object',\n properties,\n required: params,\n };\n}\n\n/**\n * Execute an HTTP tool operation.\n * Resolves URL parameters, attaches auth headers, and makes the HTTP request.\n */\nexport async function executeHttpOperation(\n operation: ToolOperation,\n baseUrl: string,\n authHeaders: Record<string, string>,\n input: Record<string, unknown>,\n timeoutMs: number,\n): Promise<unknown> {\n const resolvedPath = resolveEndpoint(operation.endpoint, input);\n let url = resolvedPath.startsWith('http') ? resolvedPath : `${baseUrl}${resolvedPath}`;\n\n // Append query parameters if provided\n const query = input['query'];\n if (typeof query === 'string' && query.length > 0) {\n const separator = url.includes('?') ? '&' : '?';\n url = `${url}${separator}${query}`;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n ...authHeaders,\n };\n\n const fetchOptions: RequestInit = {\n method: operation.method,\n headers,\n signal: AbortSignal.timeout(timeoutMs),\n };\n\n // Attach body for methods that support it\n if (['POST', 'PUT', 'PATCH'].includes(operation.method)) {\n const body = input['body'];\n if (typeof body === 'string') {\n fetchOptions.body = body;\n } else if (body !== undefined && body !== null) {\n fetchOptions.body = JSON.stringify(body);\n }\n }\n\n const response = await fetch(url, fetchOptions);\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n throw new Error(`HTTP ${response.status} ${response.statusText}: ${errorText.slice(0, 500)}`);\n }\n\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n return response.json() as Promise<unknown>;\n }\n return response.text();\n}\n\n// --- Tool Conversion ---\n\n/**\n * Sanitize a tool name for the AI SDK.\n * Tool names must be alphanumeric with underscores/hyphens only.\n */\nfunction sanitizeToolName(name: string): string {\n return name\n .replace(/[^a-zA-Z0-9_-]/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_|_$/g, '')\n .slice(0, 64);\n}\n\n/**\n * Extract a base URL from the tool's operations or body.\n * Looks for full URLs in operations, or common API URL patterns in the body.\n */\nfunction extractBaseUrl(toolDef: ToolDefinition): string {\n // Check operations for full URLs\n for (const op of toolDef.operations) {\n if (op.endpoint.startsWith('http')) {\n try {\n const url = new URL(op.endpoint);\n return `${url.protocol}//${url.host}`;\n } catch {\n // not a valid URL\n }\n }\n }\n\n // Try to find API base URL in the document body\n const urlMatch = toolDef.doc.body.match(/(?:base[_ ]?url|api[_ ]?url|endpoint)\\s*[:=]\\s*`?(https?:\\/\\/[^\\s`\"']+)/i);\n if (urlMatch) {\n try {\n const url = new URL(urlMatch[1]);\n return `${url.protocol}//${url.host}`;\n } catch {\n // not a valid URL\n }\n }\n\n return '';\n}\n\n/**\n * Build auth headers from a tool's auth configuration.\n * Maps known env var patterns to standard header formats.\n */\nexport function buildAuthHeaders(toolDef: ToolDefinition): Record<string, string> {\n const headers: Record<string, string> = {};\n\n for (const auth of toolDef.auth) {\n const value = process.env[auth.envVar];\n if (!value) continue;\n\n // Common patterns for auth header mapping (check specific patterns first)\n const envLower = auth.envVar.toLowerCase();\n if (envLower.includes('bot_token')) {\n headers['Authorization'] = `Bot ${value}`;\n } else if (envLower.includes('token') || envLower.includes('api_key') || envLower.includes('apikey')) {\n headers['Authorization'] = `Bearer ${value}`;\n } else {\n // Generic: use as Bearer token\n headers['Authorization'] = `Bearer ${value}`;\n }\n }\n\n return headers;\n}\n\n/**\n * Convert a single ToolDefinition (from markdown) into AI SDK tools.\n * Each operation becomes a separate tool entry.\n */\nexport function convertToolDefinition(\n toolDef: ToolDefinition,\n config: ToolExecutorConfig,\n): AIToolSet {\n const tools: AIToolSet = {};\n const baseUrl = extractBaseUrl(toolDef);\n const allowHttp = config.allowHttpExecution !== false;\n const timeoutMs = config.toolTimeoutMs ?? 30_000;\n\n for (const operation of toolDef.operations) {\n const toolName = sanitizeToolName(`${toolDef.id}_${operation.name}`);\n const opSchema = buildOperationSchema(operation);\n\n tools[toolName] = aiTool({\n description: `[${toolDef.id}] ${operation.method} ${operation.endpoint} — ${toolDef.doc.l0}`,\n inputSchema: jsonSchema<Record<string, unknown>>(opSchema),\n execute: async (input) => {\n const typedInput = input;\n\n if (!allowHttp) {\n return { error: 'HTTP tool execution is disabled' };\n }\n\n // Check auth\n const missingAuth = toolDef.auth.filter((a) => !process.env[a.envVar]);\n if (missingAuth.length > 0) {\n return {\n error: `Missing required auth: ${missingAuth.map((a) => a.envVar).join(', ')}`,\n };\n }\n\n const authHeaders = buildAuthHeaders(toolDef);\n\n try {\n const result = await executeHttpOperation(\n operation,\n baseUrl,\n authHeaders,\n typedInput,\n timeoutMs,\n );\n return result;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n log.error(`Tool ${toolName} execution failed: ${message}`);\n return { error: message };\n }\n },\n });\n }\n\n return tools;\n}\n\n/**\n * Convert a programmatic tool definition into an AI SDK tool.\n */\nfunction convertProgrammaticTool(pt: ProgrammaticTool): AIToolSet {\n const toolName = sanitizeToolName(pt.name);\n\n return {\n [toolName]: aiTool({\n description: pt.description,\n inputSchema: pt.inputSchema,\n execute: async (input: unknown) => {\n try {\n return await pt.execute(input as Record<string, unknown>);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n log.error(`Tool ${toolName} execution failed: ${message}`);\n return { error: message };\n }\n },\n }),\n };\n}\n\n// --- Public API ---\n\n/**\n * Load all tools from the harness directory and convert them to AI SDK format.\n * Includes markdown-defined tools, programmatic tools from config, and MCP tools.\n *\n * Returns an empty object if no tools are configured.\n *\n * @param harnessDir - Path to the harness directory\n * @param config - Tool executor configuration\n * @param mcpTools - Pre-loaded MCP tools to merge (from McpManager.getTools())\n */\nexport function buildToolSet(\n harnessDir: string,\n config?: ToolExecutorConfig,\n mcpTools?: AIToolSet,\n): AIToolSet {\n const executorConfig = config ?? {};\n const tools: AIToolSet = {};\n\n // Load markdown-defined tools\n const toolDefs = loadTools(harnessDir);\n for (const toolDef of toolDefs) {\n // Skip inactive tools\n if (toolDef.status !== 'active') continue;\n\n // Skip tools without operations\n if (toolDef.operations.length === 0) continue;\n\n const converted = convertToolDefinition(toolDef, executorConfig);\n Object.assign(tools, converted);\n }\n\n // Add programmatic tools\n if (executorConfig.tools) {\n for (const pt of executorConfig.tools) {\n const converted = convertProgrammaticTool(pt);\n Object.assign(tools, converted);\n }\n }\n\n // Merge MCP tools (from connected MCP servers)\n if (mcpTools) {\n Object.assign(tools, mcpTools);\n }\n\n return tools;\n}\n\n/**\n * Create a ToolCallRecord tracker for recording tool calls in a run.\n */\nexport function createToolCallTracker(): {\n record: (result: ToolCallResult) => void;\n getRecord: () => ToolCallRecord;\n} {\n const calls: ToolCallResult[] = [];\n let totalDurationMs = 0;\n\n return {\n record(result: ToolCallResult) {\n calls.push(result);\n totalDurationMs += result.durationMs;\n },\n getRecord(): ToolCallRecord {\n return { calls: [...calls], totalDurationMs };\n },\n };\n}\n\n/**\n * Get a human-readable summary of tools available in the harness.\n */\nexport function getToolSetSummary(tools: AIToolSet): string[] {\n return Object.entries(tools).map(([name, t]) => {\n const desc = (t as { description?: string }).description ?? '';\n return `${name}: ${desc}`;\n });\n}\n","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","import { createMCPClient, type MCPClient, type MCPClientConfig } from '@ai-sdk/mcp';\nimport { Experimental_StdioMCPTransport } from '@ai-sdk/mcp/mcp-stdio';\nimport type { ToolSet } from 'ai';\nimport type { HarnessConfig } from '../core/types.js';\nimport { log, getGlobalLogLevel } from '../core/logger.js';\n\n// --- Types ---\n\n/** Single MCP server configuration (mirrors config schema) */\nexport interface McpServerConfig {\n transport: 'stdio' | 'http' | 'sse';\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n url?: string;\n headers?: Record<string, string>;\n enabled?: boolean;\n}\n\n/** Result of connecting to an MCP server */\nexport interface McpServerConnection {\n name: string;\n client: MCPClient;\n toolCount: number;\n tools: ToolSet;\n}\n\n/** Summary of an MCP server for display */\nexport interface McpServerSummary {\n name: string;\n transport: string;\n enabled: boolean;\n connected: boolean;\n toolCount: number;\n toolNames: string[];\n error?: string;\n}\n\n/** Manages all MCP server connections for a harness */\nexport interface McpManager {\n /** Connect to all enabled MCP servers and load their tools */\n connect(): Promise<void>;\n /** Get merged tool set from all connected servers */\n getTools(): ToolSet;\n /** Get summary of all configured servers */\n getSummaries(): McpServerSummary[];\n /** Close all connected clients */\n close(): Promise<void>;\n /** Check if any servers are configured */\n hasServers(): boolean;\n}\n\n// --- Transport Factory ---\n\n/**\n * Build an MCPClientConfig from a server config entry.\n * Maps transport type to the appropriate transport configuration.\n */\nfunction buildClientConfig(name: string, serverConfig: McpServerConfig): MCPClientConfig {\n switch (serverConfig.transport) {\n case 'stdio': {\n if (!serverConfig.command) {\n throw new Error(`MCP server \"${name}\": stdio transport requires \"command\" field`);\n }\n // Suppress MCP server stderr noise unless --verbose (log level debug)\n const stderr = getGlobalLogLevel() === 'debug' ? 'inherit' as const : 'pipe' as const;\n return {\n transport: new Experimental_StdioMCPTransport({\n command: serverConfig.command,\n args: serverConfig.args,\n env: serverConfig.env ? { ...process.env, ...serverConfig.env } as Record<string, string> : undefined,\n cwd: serverConfig.cwd,\n stderr,\n }),\n name: `harness-mcp-${name}`,\n };\n }\n case 'http': {\n if (!serverConfig.url) {\n throw new Error(`MCP server \"${name}\": http transport requires \"url\" field`);\n }\n return {\n transport: {\n type: 'http' as const,\n url: serverConfig.url,\n headers: serverConfig.headers,\n },\n name: `harness-mcp-${name}`,\n };\n }\n case 'sse': {\n if (!serverConfig.url) {\n throw new Error(`MCP server \"${name}\": sse transport requires \"url\" field`);\n }\n return {\n transport: {\n type: 'sse' as const,\n url: serverConfig.url,\n headers: serverConfig.headers,\n },\n name: `harness-mcp-${name}`,\n };\n }\n default:\n throw new Error(`MCP server \"${name}\": unknown transport \"${serverConfig.transport}\"`);\n }\n}\n\n// --- Connection ---\n\n/**\n * Connect to a single MCP server and load its tools.\n * Returns the connection with tool set, or throws on failure.\n */\nasync function connectToServer(name: string, serverConfig: McpServerConfig): Promise<McpServerConnection> {\n const clientConfig = buildClientConfig(name, serverConfig);\n const client = await createMCPClient(clientConfig);\n\n // Load tools with auto-discovery (no schema pre-definition needed)\n const tools = await client.tools();\n const toolCount = Object.keys(tools).length;\n\n return { name, client, toolCount, tools };\n}\n\n// --- Manager ---\n\n/**\n * Create an MCP manager from harness config.\n * Manages lifecycle of all MCP server connections.\n */\nexport function createMcpManager(config: HarnessConfig): McpManager {\n const servers = config.mcp?.servers ?? {};\n const connections: McpServerConnection[] = [];\n const summaries: McpServerSummary[] = [];\n\n return {\n hasServers(): boolean {\n return Object.keys(servers).length > 0;\n },\n\n async connect(): Promise<void> {\n const entries = Object.entries(servers);\n\n if (entries.length === 0) {\n return;\n }\n\n log.info(`Connecting to ${entries.length} MCP server(s)...`);\n\n for (const [name, serverConfig] of entries) {\n const enabled = serverConfig.enabled !== false;\n\n if (!enabled) {\n summaries.push({\n name,\n transport: serverConfig.transport,\n enabled: false,\n connected: false,\n toolCount: 0,\n toolNames: [],\n });\n log.debug(`MCP server \"${name}\" is disabled, skipping`);\n continue;\n }\n\n try {\n const connection = await connectToServer(name, serverConfig);\n connections.push(connection);\n\n const toolNames = Object.keys(connection.tools);\n summaries.push({\n name,\n transport: serverConfig.transport,\n enabled: true,\n connected: true,\n toolCount: connection.toolCount,\n toolNames,\n });\n\n log.info(`MCP \"${name}\": connected, ${connection.toolCount} tool(s) [${toolNames.join(', ')}]`);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n summaries.push({\n name,\n transport: serverConfig.transport,\n enabled: true,\n connected: false,\n toolCount: 0,\n toolNames: [],\n error: message,\n });\n\n log.warn(`MCP \"${name}\": connection failed — ${message}`);\n }\n }\n\n const totalTools = connections.reduce((sum, c) => sum + c.toolCount, 0);\n if (totalTools > 0) {\n log.info(`MCP: ${totalTools} tool(s) loaded from ${connections.length} server(s)`);\n }\n },\n\n getTools(): ToolSet {\n const merged: ToolSet = {};\n for (const connection of connections) {\n Object.assign(merged, connection.tools);\n }\n return merged;\n },\n\n getSummaries(): McpServerSummary[] {\n // Include unchecked servers that haven't been connected yet\n const serverNames = Object.keys(servers);\n const checkedNames = new Set(summaries.map((s) => s.name));\n\n for (const name of serverNames) {\n if (!checkedNames.has(name)) {\n const serverConfig = servers[name];\n summaries.push({\n name,\n transport: serverConfig.transport,\n enabled: serverConfig.enabled !== false,\n connected: false,\n toolCount: 0,\n toolNames: [],\n });\n }\n }\n\n return [...summaries];\n },\n\n async close(): Promise<void> {\n const closePromises = connections.map(async (connection) => {\n try {\n await connection.client.close();\n log.debug(`MCP \"${connection.name}\": closed`);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n log.warn(`MCP \"${connection.name}\": close failed — ${message}`);\n }\n });\n\n await Promise.all(closePromises);\n connections.length = 0;\n },\n };\n}\n\n/**\n * Load MCP tools from all enabled servers in config.\n * Convenience function for one-shot usage (connects, loads, returns tools + close fn).\n */\nexport async function loadMcpTools(config: HarnessConfig): Promise<{\n tools: ToolSet;\n summaries: McpServerSummary[];\n close: () => Promise<void>;\n}> {\n const manager = createMcpManager(config);\n await manager.connect();\n\n return {\n tools: manager.getTools(),\n summaries: manager.getSummaries(),\n close: () => manager.close(),\n };\n}\n\n/**\n * Validate MCP server configurations without connecting.\n * Returns validation errors for each server.\n */\nexport function validateMcpConfig(config: HarnessConfig): Array<{ server: string; error: string }> {\n const errors: Array<{ server: string; error: string }> = [];\n const servers = config.mcp?.servers ?? {};\n\n for (const [name, serverConfig] of Object.entries(servers)) {\n if (serverConfig.transport === 'stdio') {\n if (!serverConfig.command) {\n errors.push({ server: name, error: 'stdio transport requires \"command\" field' });\n }\n } else if (serverConfig.transport === 'http' || serverConfig.transport === 'sse') {\n if (!serverConfig.url) {\n errors.push({ server: name, error: `${serverConfig.transport} transport requires \"url\" field` });\n }\n } else {\n errors.push({ server: name, error: `unknown transport \"${serverConfig.transport}\"` });\n }\n }\n\n return errors;\n}\n"],"mappings":"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","names":["existsSync","readFileSync","existsSync","join","readFileSync","existsSync","join","readFileSync","existsSync","join","join","existsSync","readFileSync","globalLevel","readFileSync","writeFileSync","existsSync","join","readFileSync","existsSync","join","resolve","join","existsSync","readFileSync","writeFileSync","writeFileSync","mkdirSync","existsSync","readdirSync","unlinkSync","join","join","existsSync","mkdirSync","writeFileSync","readdirSync","unlinkSync","readFileSync","writeFileSync","existsSync","mkdirSync","join","readFileSync","writeFileSync","existsSync","mkdirSync","join","join","existsSync","readFileSync","mkdirSync","writeFileSync","readFileSync","writeFileSync","existsSync","mkdirSync","join","getStorePath","existsSync","join","join","existsSync","existsSync"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/types.ts"],"sourcesContent":["import { z } from 'zod';\n\n// --- Frontmatter ---\nexport const FrontmatterSchema = z.object({\n id: z.string(),\n tags: z.array(z.string()).default([]),\n created: z.string().optional(),\n updated: z.string().optional(),\n author: z.enum(['human', 'agent', 'infrastructure']).default('human'),\n status: z.enum(['active', 'archived', 'deprecated', 'draft']).default('active'),\n related: z.array(z.string()).default([]),\n schedule: z.string().optional(),\n with: z.string().optional(),\n channel: z.string().optional(),\n duration_minutes: z.number().optional(),\n max_retries: z.number().int().nonnegative().optional(),\n retry_delay_ms: z.number().int().positive().optional(),\n});\n\nexport type Frontmatter = z.infer<typeof FrontmatterSchema>;\n\n// --- Primitive Document ---\nexport interface HarnessDocument {\n path: string;\n frontmatter: Frontmatter;\n l0: string;\n l1: string;\n body: string;\n raw: string;\n}\n\n// --- Primitive Types ---\nexport type PrimitiveType =\n | 'rule'\n | 'instinct'\n | 'skill'\n | 'playbook'\n | 'workflow'\n | 'tool'\n | 'agent'\n | 'session'\n | 'journal';\n\nexport interface Primitive {\n type: PrimitiveType;\n doc: HarnessDocument;\n}\n\n// --- Config ---\nexport const HarnessConfigSchema = z.object({\n agent: z.object({\n name: z.string().min(1),\n version: z.string().default('0.1.0'),\n }).passthrough(),\n model: z.object({\n provider: z.string().default('openrouter'),\n id: z.string().min(1),\n max_tokens: z.number().int().positive().default(200000),\n max_retries: z.number().int().nonnegative().default(2),\n timeout_ms: z.number().int().positive().optional(),\n /** Cheap model for auto-generating summaries, tags, frontmatter (e.g. 'google/gemini-flash-1.5') */\n summary_model: z.string().optional(),\n /** Fast model for validation, checks, and quick decisions (e.g. 'google/gemini-flash-1.5') */\n fast_model: z.string().optional(),\n }).passthrough(),\n runtime: z.object({\n scratchpad_budget: z.number().int().nonnegative().default(10000),\n /** Reserved: cron expression for periodic heartbeat check (not yet implemented) */\n heartbeat: z.string().optional(),\n /** Reserved: cron expression for daily summary generation (not yet implemented) */\n daily_summary: z.string().optional(),\n /** Auto-process primitives on save: generate frontmatter, L0/L1 summaries (default: true) */\n auto_process: z.boolean().default(true),\n quiet_hours: z.object({\n start: z.number().int().min(0).max(23).default(23),\n end: z.number().int().min(0).max(23).default(6),\n }).passthrough().default({ start: 23, end: 6 }),\n timezone: z.string().default('America/New_York'),\n }).passthrough(),\n memory: z.object({\n session_retention_days: z.number().int().positive().default(7),\n journal_retention_days: z.number().int().positive().default(365),\n }).passthrough(),\n channels: z.object({\n primary: z.string().default('cli'),\n }).passthrough(),\n extensions: z.object({\n directories: z.array(z.string()).default([]),\n }).passthrough().default({ directories: [] }),\n rate_limits: z.object({\n /** Max LLM calls per minute (default: unlimited) */\n per_minute: z.number().int().positive().optional(),\n /** Max LLM calls per hour (default: unlimited) */\n per_hour: z.number().int().positive().optional(),\n /** Max LLM calls per day (default: unlimited) */\n per_day: z.number().int().positive().optional(),\n }).passthrough().default({}),\n budget: z.object({\n /** Max daily spend in USD (default: unlimited) */\n daily_limit_usd: z.number().positive().optional(),\n /** Max monthly spend in USD (default: unlimited) */\n monthly_limit_usd: z.number().positive().optional(),\n /** Block runs when budget exceeded (default: true) */\n enforce: z.boolean().default(true),\n }).passthrough().default({ enforce: true }),\n mcp: z.object({\n /** MCP server definitions keyed by server name */\n servers: z.record(z.string(), z.object({\n /** Transport type: 'stdio' for local processes, 'http' for remote, 'sse' for SSE */\n transport: z.enum(['stdio', 'http', 'sse']),\n /** Command to spawn (stdio transport only) */\n command: z.string().optional(),\n /** Command arguments (stdio transport only) */\n args: z.array(z.string()).optional(),\n /** Environment variables for the spawned process (stdio transport only) */\n env: z.record(z.string(), z.string()).optional(),\n /** Working directory for the spawned process (stdio transport only) */\n cwd: z.string().optional(),\n /** URL endpoint (http/sse transport only) */\n url: z.string().optional(),\n /** Additional HTTP headers (http/sse transport only) */\n headers: z.record(z.string(), z.string()).optional(),\n /** Whether this server is enabled (default: true) */\n enabled: z.boolean().default(true),\n }).passthrough()).default({}),\n }).passthrough().default({ servers: {} }),\n /** Intelligence & continuous learning config */\n intelligence: z.object({\n /** Auto-run journal synthesis on a cron schedule (default: off). Set to cron string e.g. \"0 22 * * *\" or true for default \"0 22 * * *\". */\n auto_journal: z.union([z.boolean(), z.string()]).default(false),\n /** Auto-run instinct learning after journal synthesis (default: off) */\n auto_learn: z.boolean().default(false),\n }).passthrough().default({ auto_journal: false, auto_learn: false }),\n /** Proactive execution config (scheduler rate-limiting) */\n proactive: z.object({\n /** Enable proactive scheduled workflows (default: false) */\n enabled: z.boolean().default(false),\n /** Max proactive workflow executions per hour (default: 5) */\n max_per_hour: z.number().int().positive().default(5),\n /** Cooldown in minutes between proactive runs of the same workflow (default: 30) */\n cooldown_minutes: z.number().int().nonnegative().default(30),\n /** Override quiet hours for proactive execution (start/end hours, inherits runtime.quiet_hours if not set) */\n quiet_hours: z.object({\n start: z.number().int().min(0).max(23).optional(),\n end: z.number().int().min(0).max(23).optional(),\n }).passthrough().optional(),\n }).passthrough().default({ enabled: false, max_per_hour: 5, cooldown_minutes: 30 }),\n /** Primitive bundle registries for search/install */\n registries: z.array(z.object({\n /** Registry URL (HTTPS endpoint) */\n url: z.string().url(),\n /** Optional display name */\n name: z.string().optional(),\n /** Optional auth token for private registries */\n token: z.string().optional(),\n }).passthrough()).default([]),\n}).passthrough();\n\nexport type HarnessConfig = z.infer<typeof HarnessConfigSchema>;\n\nexport const CONFIG_DEFAULTS: HarnessConfig = {\n agent: { name: 'agent', version: '0.1.0' },\n model: { provider: 'openrouter', id: 'anthropic/claude-sonnet-4', max_tokens: 200000, max_retries: 2 },\n runtime: {\n scratchpad_budget: 10000,\n auto_process: true,\n quiet_hours: { start: 23, end: 6 },\n timezone: 'America/New_York',\n },\n memory: { session_retention_days: 7, journal_retention_days: 365 },\n channels: { primary: 'cli' },\n extensions: { directories: [] },\n rate_limits: {},\n budget: { enforce: true },\n intelligence: { auto_journal: false, auto_learn: false },\n proactive: { enabled: false, max_per_hour: 5, cooldown_minutes: 30 },\n mcp: { servers: {} },\n registries: [],\n};\n\nexport const CORE_PRIMITIVE_DIRS = ['rules', 'instincts', 'skills', 'playbooks', 'workflows', 'tools', 'agents'] as const;\n\nexport function getPrimitiveDirs(config?: HarnessConfig): string[] {\n const dirs: string[] = [...CORE_PRIMITIVE_DIRS];\n if (config?.extensions?.directories) {\n for (const dir of config.extensions.directories) {\n if (!dirs.includes(dir)) {\n dirs.push(dir);\n }\n }\n }\n return dirs;\n}\n\n// --- Agent State ---\nexport interface AgentState {\n mode: string;\n goals: string[];\n active_workflows: string[];\n last_interaction: string;\n unfinished_business: string[];\n}\n\n// --- Context Budget ---\nexport interface ContextBudget {\n max_tokens: number;\n used_tokens: number;\n remaining: number;\n loaded_files: string[];\n}\n\n// --- Utility Types ---\nexport type DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];\n};\n\n// --- Lifecycle Hooks ---\nexport interface HarnessHooks {\n /** Called after boot completes (context loaded, state ready) */\n onBoot?: (context: { agent: HarnessAgent; config: HarnessConfig; state: AgentState }) => void | Promise<void>;\n /** Called after each session completes (run or stream) */\n onSessionEnd?: (context: { agent: HarnessAgent; sessionId: string; prompt: string; result: AgentRunResult }) => void | Promise<void>;\n /** Called when an error occurs during run/stream */\n onError?: (context: { agent: HarnessAgent; error: Error; prompt?: string }) => void | Promise<void>;\n /** Called when agent state changes (boot, shutdown, after run) */\n onStateChange?: (context: { agent: HarnessAgent; previous: string; current: string }) => void | Promise<void>;\n /** Called before shutdown completes */\n onShutdown?: (context: { agent: HarnessAgent; state: AgentState }) => void | Promise<void>;\n}\n\n// --- Tool Executor Config (inline to avoid circular deps) ---\nexport interface ToolExecutorOptions {\n /** Maximum tool calls per run (default: 5) */\n maxToolCalls?: number;\n /** Timeout per tool call in ms (default: 30000) */\n toolTimeoutMs?: number;\n /** Whether to allow HTTP tool execution (default: true) */\n allowHttpExecution?: boolean;\n}\n\n// --- Agent Options (programmatic API) ---\nexport interface CreateHarnessOptions {\n dir: string;\n /** Model ID override (e.g., \"claude-sonnet-4-20250514\" or \"gpt-4o\") */\n model?: string;\n /** Provider override (e.g., \"anthropic\", \"openai\", \"openrouter\") */\n provider?: string;\n apiKey?: string;\n config?: DeepPartial<HarnessConfig>;\n /** Lifecycle hooks for agent events */\n hooks?: HarnessHooks;\n /** Tool execution configuration */\n toolExecutor?: ToolExecutorOptions;\n}\n\n/** Record of a single tool call made during a run */\nexport interface ToolCallInfo {\n toolName: string;\n args: Record<string, unknown>;\n result: unknown;\n}\n\n// --- Agent Interface ---\nexport interface AgentRunResult {\n text: string;\n usage: { inputTokens: number; outputTokens: number; totalTokens: number };\n session_id: string;\n steps: number;\n /** Tool calls made during the run (empty array if none) */\n toolCalls: ToolCallInfo[];\n}\n\nexport interface AgentStreamResult {\n /** Async iterable of text chunks — consume with for-await */\n textStream: AsyncIterable<string>;\n /** Resolves after the stream is fully consumed with session metadata */\n result: Promise<AgentRunResult>;\n}\n\nexport interface HarnessAgent {\n name: string;\n config: HarnessConfig;\n boot(): Promise<void>;\n run(prompt: string): Promise<AgentRunResult>;\n stream(prompt: string): AgentStreamResult;\n shutdown(): Promise<void>;\n getSystemPrompt(): string;\n getState(): AgentState;\n}\n\n// --- Index Entry ---\nexport interface IndexEntry {\n id: string;\n path: string;\n tags: string[];\n l0: string;\n created: string;\n status: string;\n}\n"],"mappings":"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","names":[]}
@@ -1,10 +0,0 @@
1
- import {
2
- createHarness
3
- } from "./chunk-GUJTBGVS.js";
4
- import "./chunk-KFX54TQM.js";
5
- import "./chunk-FD55B3IO.js";
6
- import "./chunk-DGUM43GV.js";
7
- export {
8
- createHarness
9
- };
10
- //# sourceMappingURL=harness-LCHA3DWP.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime/universal-installer.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from 'fs';\nimport { join, basename, extname } from 'path';\nimport { tmpdir } from 'os';\nimport { createRequire } from 'module';\nimport matter from 'gray-matter';\nimport { parse as parseYaml } from 'yaml';\nimport { fixCapability, installCapability, downloadCapability } from './intake.js';\nimport { autoProcessFile } from './auto-processor.js';\nimport { discoverSources, loadAllSources } from './sources.js';\nimport type { Source, SourceDiscoveryResult } from './sources.js';\nimport { log } from '../core/logger.js';\n\n// ─── Provenance ──────────────────────────────────────────────────────────────\n\n/**\n * Read the harness's own package.json version for the `installed_by` field.\n *\n * Has to handle three possible runtime layouts because tsup bundles flat:\n * - Dev/test: src/runtime/universal-installer.ts → ../../package.json\n * - Built bin: dist/cli/index.js → ../../package.json\n * - Built lib: dist/<bundle>.js → ../package.json\n *\n * Walks up one directory at a time, requires `package.json`, and returns\n * the version of the FIRST one whose name is `@agntk/agent-harness`. Stops\n * after a few levels so a broken environment never causes an infinite loop.\n * Returns \"unknown\" on any failure so an install never blocks on this.\n */\nfunction getHarnessVersion(): string {\n try {\n const require = createRequire(import.meta.url);\n const candidates = [\n '../package.json',\n '../../package.json',\n '../../../package.json',\n ];\n for (const candidate of candidates) {\n try {\n const pkg = require(candidate) as { name?: string; version?: string };\n if (pkg.name === '@agntk/agent-harness' && pkg.version) {\n return pkg.version;\n }\n } catch {\n // Candidate didn't resolve — try the next one.\n }\n }\n return 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\n/**\n * Resolve a commit SHA for a GitHub raw URL by calling the GitHub Contents API.\n *\n * Input URL shape:\n * https://raw.githubusercontent.com/{owner}/{repo}/{ref}/{path}\n * where {ref} is either a 40-char commit SHA or a branch/tag name.\n *\n * Returns the SHA (either the one already in the URL, or the one resolved from\n * a branch name via the Contents API). Returns `null` on any failure — network\n * error, timeout, 404, non-github host, unparseable URL — so the install can\n * proceed without source_commit.\n */\nasync function resolveGithubCommitSha(url: string): Promise<string | null> {\n // Only handle raw.githubusercontent.com URLs\n const match = url.match(\n /^https?:\\/\\/raw\\.githubusercontent\\.com\\/([^/]+)\\/([^/]+)\\/([^/]+)\\/(.+)$/,\n );\n if (!match) return null;\n const [, owner, repo, ref, path] = match;\n\n // If ref is already a 40-char hex SHA, just return it\n if (/^[0-9a-f]{40}$/i.test(ref)) return ref;\n\n // Otherwise resolve via the Contents API\n const apiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=${ref}`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000);\n try {\n const response = await fetch(apiUrl, {\n signal: controller.signal,\n headers: { 'Accept': 'application/vnd.github+json' },\n });\n if (!response.ok) return null;\n const data = (await response.json()) as { sha?: string };\n if (typeof data.sha === 'string' && /^[0-9a-f]{40}$/i.test(data.sha)) {\n return data.sha;\n }\n return null;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Inject provenance fields into a normalized markdown file's frontmatter.\n *\n * Rules:\n * - `source` and `source_commit` are preserved if already present (idempotent)\n * - `installed_at` and `installed_by` are always updated to reflect the most\n * recent install action\n * - `source_commit` is only written when a SHA could be resolved\n *\n * @param content Normalized markdown content with existing frontmatter\n * @param originalSource The exact URL the user passed to `harness install`\n * @returns The content with provenance fields merged into frontmatter\n */\nexport async function recordProvenance(\n content: string,\n originalSource: string,\n): Promise<string> {\n let parsed: ReturnType<typeof matter>;\n try {\n parsed = matter(content);\n } catch {\n return content;\n }\n\n const data = parsed.data as Record<string, unknown>;\n\n // Preserve existing source — idempotency rule\n if (!data.source) {\n data.source = originalSource;\n }\n\n // Preserve existing source_commit; only resolve if missing AND URL is github raw\n if (!data.source_commit) {\n const sha = await resolveGithubCommitSha(originalSource);\n if (sha) {\n data.source_commit = sha;\n }\n }\n\n // Always update these to reflect the most recent install\n data.installed_at = new Date().toISOString();\n data.installed_by = `agent-harness@${getHarnessVersion()}`;\n\n return matter.stringify(parsed.content, data);\n}\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Detected source format of a file to be installed. */\nexport type SourceFormat =\n | 'harness' // Already harness convention (frontmatter + L0/L1)\n | 'claude-skill' // Claude Code SKILL.md (plain markdown, no frontmatter)\n | 'faf-yaml' // .faf YAML format\n | 'raw-markdown' // Plain markdown with no harness structure\n | 'bash-hook' // Bash/shell script (hook or workflow)\n | 'mcp-config' // MCP server configuration (JSON/YAML)\n | 'unknown';\n\n/** Result of format detection. */\nexport interface FormatDetection {\n /** Detected format */\n format: SourceFormat;\n /** Inferred primitive type (skill, agent, rule, etc.) */\n primitiveType: string | null;\n /** Confidence score (0-1) */\n confidence: number;\n /** Reasons for the detection */\n reasons: string[];\n}\n\n/** Result of a universal install operation. */\nexport interface UniversalInstallResult {\n /** Whether installation succeeded */\n installed: boolean;\n /** Source reference that was resolved */\n source: string;\n /** Detected format */\n format: FormatDetection;\n /** Path where the file was installed */\n destination: string;\n /** Fixes applied during normalization */\n fixes: string[];\n /** Errors encountered */\n errors: string[];\n /** Suggested dependencies to install */\n suggestedDependencies: string[];\n}\n\n/** Options for the universal installer. */\nexport interface UniversalInstallOptions {\n /** Override the detected primitive type (skill, rule, agent, etc.) */\n type?: string;\n /** Override the generated ID */\n id?: string;\n /** Force install even if validation has warnings */\n force?: boolean;\n /** Skip auto-fix (frontmatter, L0/L1 generation) */\n skipFix?: boolean;\n /** Additional tags to add */\n tags?: string[];\n}\n\n// ─── Constants ───────────────────────────────────────────────────────────────\n\nconst VALID_TYPES = ['rule', 'instinct', 'skill', 'playbook', 'workflow', 'tool', 'agent'];\n\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// ─── Format Detection ────────────────────────────────────────────────────────\n\n/**\n * Detect the format of a file based on its content and extension.\n *\n * Detection heuristics:\n * - Has `---` frontmatter with `id:` + `status:` → harness convention\n * - Has `---` frontmatter but missing harness fields → raw-markdown\n * - `.faf` or `.yaml`/`.yml` with `type:` + `content:` keys → faf-yaml\n * - `.sh`/`.bash` or starts with `#!/` → bash-hook\n * - JSON/YAML with `mcpServers` or `servers` → mcp-config\n * - Plain markdown with no frontmatter → claude-skill or raw-markdown\n */\nexport function detectFormat(content: string, filename: string): FormatDetection {\n const ext = extname(filename).toLowerCase();\n const reasons: string[] = [];\n let format: SourceFormat = 'unknown';\n let primitiveType: string | null = null;\n let confidence = 0;\n\n // Check for bash/shell scripts\n if (ext === '.sh' || ext === '.bash' || content.trimStart().startsWith('#!/')) {\n format = 'bash-hook';\n primitiveType = 'workflow';\n confidence = 0.9;\n reasons.push('Shell script detected (shebang or .sh extension)');\n\n // Hooks are typically short scripts with specific patterns\n if (content.includes('hook') || content.includes('pre-commit') || content.includes('post-')) {\n primitiveType = 'workflow';\n reasons.push('Hook pattern detected in content');\n }\n\n return { format, primitiveType, confidence, reasons };\n }\n\n // Check for JSON/YAML MCP configs\n if (ext === '.json') {\n try {\n const parsed = JSON.parse(content) as Record<string, unknown>;\n if (parsed.mcpServers || parsed.servers || parsed.command || parsed.args) {\n format = 'mcp-config';\n primitiveType = 'tool';\n confidence = 0.9;\n reasons.push('MCP configuration JSON detected');\n return { format, primitiveType, confidence, reasons };\n }\n } catch {\n // Not valid JSON, continue\n }\n }\n\n // Check for .faf YAML format\n if (ext === '.faf' || ext === '.yaml' || ext === '.yml') {\n try {\n const parsed = parseYaml(content) as Record<string, unknown>;\n if (parsed.type && parsed.content) {\n format = 'faf-yaml';\n primitiveType = inferTypeFromFafType(String(parsed.type));\n confidence = 0.9;\n reasons.push(`.faf YAML format with type: ${parsed.type}`);\n return { format, primitiveType, confidence, reasons };\n }\n // YAML with mcpServers\n if (parsed.mcpServers || parsed.servers) {\n format = 'mcp-config';\n primitiveType = 'tool';\n confidence = 0.85;\n reasons.push('MCP configuration YAML detected');\n return { format, primitiveType, confidence, reasons };\n }\n } catch {\n // Not valid YAML, continue\n }\n }\n\n // Check for markdown content\n if (ext === '.md' || ext === '' || !ext) {\n // Try to parse frontmatter\n try {\n const parsed = matter(content);\n const data = parsed.data as Record<string, unknown>;\n\n if (data.id && data.status) {\n // Has harness-style frontmatter\n format = 'harness';\n confidence = 0.95;\n reasons.push('Harness frontmatter detected (id + status fields)');\n\n // Detect type from tags\n const tags = Array.isArray(data.tags)\n ? (data.tags as string[]).map((t) => String(t).toLowerCase())\n : [];\n for (const type of VALID_TYPES) {\n if (tags.includes(type)) {\n primitiveType = type;\n break;\n }\n }\n\n return { format, primitiveType, confidence, reasons };\n }\n\n if (Object.keys(data).length > 0) {\n // Has some frontmatter but not harness convention\n format = 'raw-markdown';\n confidence = 0.7;\n reasons.push('Markdown with non-harness frontmatter');\n }\n } catch {\n // No frontmatter or parse error\n }\n\n // Check for Claude Code SKILL.md patterns\n if (format === 'unknown' || format === 'raw-markdown') {\n const isClaudeSkill = detectClaudeSkillPattern(content, filename);\n if (isClaudeSkill) {\n format = 'claude-skill';\n primitiveType = 'skill';\n confidence = 0.8;\n reasons.push('Claude Code SKILL.md pattern detected');\n return { format, primitiveType, confidence, reasons };\n }\n }\n\n // Plain markdown — infer type from content\n if (format === 'unknown') {\n format = 'raw-markdown';\n confidence = 0.5;\n reasons.push('Plain markdown without frontmatter');\n }\n\n // Try to infer type from content/filename\n if (!primitiveType) {\n primitiveType = inferTypeFromContent(content, filename);\n if (primitiveType) {\n reasons.push(`Type inferred from content/filename: ${primitiveType}`);\n }\n }\n\n return { format, primitiveType, confidence, reasons };\n }\n\n return { format, primitiveType, confidence, reasons };\n}\n\n// ─── Format Normalization ────────────────────────────────────────────────────\n\n/**\n * Normalize content from any detected format to harness convention.\n * Returns the normalized markdown content ready for writing.\n */\nexport function normalizeToHarness(\n content: string,\n filename: string,\n detection: FormatDetection,\n options?: UniversalInstallOptions,\n): { content: string; filename: string; fixes: string[] } {\n const fixes: string[] = [];\n const type = options?.type ?? detection.primitiveType;\n\n switch (detection.format) {\n case 'harness':\n // Already in harness format — just pass through\n return { content, filename, fixes: ['Already in harness format'] };\n\n case 'claude-skill':\n return normalizeClaudeSkill(content, filename, type, options, fixes);\n\n case 'faf-yaml':\n return normalizeFafYaml(content, filename, type, options, fixes);\n\n case 'raw-markdown':\n return normalizeRawMarkdown(content, filename, type, options, fixes);\n\n case 'bash-hook':\n return normalizeBashHook(content, filename, type, options, fixes);\n\n case 'mcp-config':\n return normalizeMcpConfig(content, filename, options, fixes);\n\n default:\n return normalizeRawMarkdown(content, filename, type, options, fixes);\n }\n}\n\n/**\n * Convert Claude Code SKILL.md to harness convention.\n * Claude skills are plain markdown — add frontmatter + L0/L1.\n */\nfunction normalizeClaudeSkill(\n content: string,\n filename: string,\n type: string | null,\n options: UniversalInstallOptions | undefined,\n fixes: string[],\n): { content: string; filename: string; fixes: string[] } {\n const id = options?.id ?? deriveId(filename);\n const primitiveType = type ?? 'skill';\n const tags = [primitiveType, ...(options?.tags ?? [])];\n\n // Extract first heading as title\n const headingMatch = content.match(/^#\\s+(.+)$/m);\n const title = headingMatch ? headingMatch[1].trim() : id;\n\n const frontmatter: Record<string, unknown> = {\n id,\n created: new Date().toISOString().split('T')[0],\n author: 'human',\n status: 'active',\n tags,\n };\n\n // Generate L0 from title/first heading\n const l0 = title.length > 120 ? title.slice(0, 117) + '...' : title;\n\n // Generate L1 from first paragraph\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 const l1 = paragraphs.length > 0\n ? paragraphs[0].replace(/\\n/g, ' ').trim().slice(0, 300)\n : '';\n\n let body = `<!-- L0: ${l0} -->\\n`;\n if (l1) {\n body += `<!-- L1: ${l1} -->\\n`;\n }\n body += '\\n' + content;\n\n const result = matter.stringify(body, frontmatter);\n fixes.push('Added harness frontmatter (id, status, tags)');\n fixes.push(`Generated L0 from heading: \"${l0}\"`);\n if (l1) fixes.push('Generated L1 from first paragraph');\n\n const outFilename = ensureMdExtension(filename);\n return { content: result, filename: outFilename, fixes };\n}\n\n/**\n * Convert .faf YAML format to harness markdown.\n */\nfunction normalizeFafYaml(\n content: string,\n filename: string,\n type: string | null,\n options: UniversalInstallOptions | undefined,\n fixes: string[],\n): { content: string; filename: string; fixes: string[] } {\n let parsed: Record<string, unknown>;\n try {\n parsed = parseYaml(content) as Record<string, unknown>;\n } catch {\n fixes.push('Failed to parse YAML — treating as raw markdown');\n return normalizeRawMarkdown(content, filename, type, options, fixes);\n }\n\n const id = options?.id ?? String(parsed.id ?? deriveId(filename));\n const fafType = String(parsed.type ?? 'skill');\n const primitiveType = type ?? inferTypeFromFafType(fafType) ?? 'skill';\n const title = String(parsed.title ?? parsed.name ?? id);\n const description = String(parsed.description ?? '');\n const fafContent = String(parsed.content ?? '');\n const fafTags = Array.isArray(parsed.tags)\n ? (parsed.tags as string[]).map(String)\n : [];\n\n const tags = [primitiveType, ...fafTags, ...(options?.tags ?? [])];\n\n const frontmatter: Record<string, unknown> = {\n id,\n created: new Date().toISOString().split('T')[0],\n author: 'human',\n status: 'active',\n tags: [...new Set(tags)],\n };\n\n const l0 = title.length > 120 ? title.slice(0, 117) + '...' : title;\n const l1 = description.length > 300 ? description.slice(0, 297) + '...' : description;\n\n let body = `<!-- L0: ${l0} -->\\n`;\n if (l1) body += `<!-- L1: ${l1} -->\\n`;\n body += `\\n# ${title}\\n\\n`;\n if (description) body += `${description}\\n\\n`;\n if (fafContent) body += fafContent + '\\n';\n\n const result = matter.stringify(body, frontmatter);\n fixes.push('Converted .faf YAML to harness markdown');\n fixes.push(`Added frontmatter (id: ${id}, type: ${primitiveType})`);\n\n const outFilename = deriveId(filename) + '.md';\n return { content: result, filename: outFilename, fixes };\n}\n\n/**\n * Normalize raw markdown (no frontmatter or non-harness frontmatter).\n */\nfunction normalizeRawMarkdown(\n content: string,\n filename: string,\n type: string | null,\n options: UniversalInstallOptions | undefined,\n fixes: string[],\n): { content: string; filename: string; fixes: string[] } {\n const id = options?.id ?? deriveId(filename);\n const primitiveType = type ?? 'skill';\n const tags = [primitiveType, ...(options?.tags ?? [])];\n\n // Try to preserve any existing frontmatter\n let parsed: ReturnType<typeof matter>;\n try {\n parsed = matter(content);\n } catch {\n parsed = { data: {}, content, orig: '', excerpt: '', language: '', matter: '', stringify: () => '' } as ReturnType<typeof matter>;\n }\n\n const data = parsed.data as Record<string, unknown>;\n\n // Set required harness fields — options override existing values\n if (options?.id || !data.id) {\n data.id = id;\n fixes.push(`Set id: \"${id}\"`);\n }\n if (!data.status) {\n data.status = 'active';\n fixes.push('Added status: \"active\"');\n }\n if (!data.created) {\n data.created = new Date().toISOString().split('T')[0];\n fixes.push('Added created date');\n }\n if (!data.author || !['human', 'agent', 'infrastructure'].includes(String(data.author))) {\n data.author = 'human';\n fixes.push('Added author: \"human\"');\n }\n if (!Array.isArray(data.tags) || data.tags.length === 0) {\n data.tags = [...new Set(tags)];\n fixes.push(`Added tags: [${(data.tags as string[]).join(', ')}]`);\n }\n\n let body = parsed.content;\n\n // Add L0 if missing\n const l0Regex = /<!--\\s*L0:\\s*(.*?)\\s*-->/;\n if (!l0Regex.test(body)) {\n const headingMatch = body.match(/^#\\s+(.+)$/m);\n const firstLine = body.split('\\n').find((line) => line.trim().length > 0);\n const summary = headingMatch ? headingMatch[1].trim() : (firstLine?.trim() ?? id);\n const l0 = summary.length > 120 ? summary.slice(0, 117) + '...' : summary;\n body = `<!-- L0: ${l0} -->\\n${body}`;\n fixes.push(`Generated L0: \"${l0}\"`);\n }\n\n // Add L1 if missing\n const l1Regex = /<!--\\s*L1:\\s*([\\s\\S]*?)\\s*-->/;\n if (!l1Regex.test(body)) {\n const paragraphs = body.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 l1 = para.length > 300 ? para.slice(0, 297) + '...' : para;\n const l0Pos = body.indexOf('-->');\n if (l0Pos !== -1) {\n const insertPos = l0Pos + 3;\n body = body.slice(0, insertPos) + `\\n<!-- L1: ${l1} -->` + body.slice(insertPos);\n } else {\n body = `<!-- L1: ${l1} -->\\n${body}`;\n }\n fixes.push('Generated L1 from first paragraph');\n }\n }\n\n const result = matter.stringify(body, data);\n const outFilename = ensureMdExtension(filename);\n return { content: result, filename: outFilename, fixes };\n}\n\n/**\n * Wrap a bash hook script in harness markdown.\n */\nfunction normalizeBashHook(\n content: string,\n filename: string,\n type: string | null,\n options: UniversalInstallOptions | undefined,\n fixes: string[],\n): { content: string; filename: string; fixes: string[] } {\n const id = options?.id ?? deriveId(filename);\n const primitiveType = type ?? 'workflow';\n const tags = [primitiveType, 'hook', ...(options?.tags ?? [])];\n\n // Extract description from comments at top of script\n const commentLines = content.split('\\n')\n .filter((line) => line.startsWith('#') && !line.startsWith('#!'))\n .map((line) => line.replace(/^#\\s?/, '').trim())\n .filter((line) => line.length > 0);\n\n const description = commentLines.length > 0\n ? commentLines.slice(0, 3).join(' ')\n : `Bash hook: ${id}`;\n\n const frontmatter: Record<string, unknown> = {\n id,\n created: new Date().toISOString().split('T')[0],\n author: 'human',\n status: 'active',\n tags: [...new Set(tags)],\n };\n\n const l0 = description.length > 120 ? description.slice(0, 117) + '...' : description;\n\n let body = `<!-- L0: ${l0} -->\\n\\n`;\n body += `# ${id}\\n\\n`;\n body += `${description}\\n\\n`;\n body += '```bash\\n';\n body += content;\n if (!content.endsWith('\\n')) body += '\\n';\n body += '```\\n';\n\n const result = matter.stringify(body, frontmatter);\n fixes.push('Wrapped bash script in harness markdown');\n fixes.push(`Added frontmatter (id: ${id}, type: ${primitiveType})`);\n\n const outFilename = deriveId(filename) + '.md';\n return { content: result, filename: outFilename, fixes };\n}\n\n/**\n * Convert an MCP config to harness tool documentation.\n */\nfunction normalizeMcpConfig(\n content: string,\n filename: string,\n options: UniversalInstallOptions | undefined,\n fixes: string[],\n): { content: string; filename: string; fixes: string[] } {\n const id = options?.id ?? deriveId(filename);\n const tags = ['tool', 'mcp', ...(options?.tags ?? [])];\n\n // Try to parse config\n let config: Record<string, unknown> = {};\n const ext = extname(filename).toLowerCase();\n try {\n if (ext === '.json') {\n config = JSON.parse(content) as Record<string, unknown>;\n } else {\n config = parseYaml(content) as Record<string, unknown>;\n }\n } catch {\n fixes.push('Failed to parse MCP config');\n }\n\n const serverName = String(config.name ?? config.command ?? id);\n const description = String(config.description ?? `MCP server: ${serverName}`);\n\n const frontmatter: Record<string, unknown> = {\n id,\n created: new Date().toISOString().split('T')[0],\n author: 'human',\n status: 'active',\n tags: [...new Set(tags)],\n };\n\n const l0 = description.length > 120 ? description.slice(0, 117) + '...' : description;\n\n let body = `<!-- L0: ${l0} -->\\n\\n`;\n body += `# MCP Server: ${serverName}\\n\\n`;\n body += `${description}\\n\\n`;\n body += '## Configuration\\n\\n';\n body += '```json\\n';\n body += JSON.stringify(config, null, 2);\n body += '\\n```\\n';\n\n const result = matter.stringify(body, frontmatter);\n fixes.push('Converted MCP config to harness tool documentation');\n fixes.push(`Added frontmatter (id: ${id})`);\n\n const outFilename = deriveId(filename) + '.md';\n return { content: result, filename: outFilename, fixes };\n}\n\n// ─── Source Resolution ───────────────────────────────────────────────────────\n\n/**\n * Resolve a source reference to a local file path.\n *\n * Supports:\n * - Local file paths (absolute or relative)\n * - HTTPS URLs (GitHub raw, any markdown URL)\n * - Source query (searches registered sources)\n *\n * @returns Path to a local file (downloaded if remote)\n */\nexport async function resolveSource(\n source: string,\n harnessDir: string,\n): Promise<{ localPath: string; originalSource: string; error?: string }> {\n // Case 1: Local file path\n if (existsSync(source)) {\n return { localPath: source, originalSource: source };\n }\n\n // Case 2: URL\n if (source.startsWith('https://') || source.startsWith('http://')) {\n // Convert GitHub URL to raw if needed\n const rawUrl = convertToRawUrl(source);\n const result = await downloadCapability(rawUrl);\n if (result.downloaded) {\n return { localPath: result.localPath, originalSource: source };\n }\n return { localPath: '', originalSource: source, error: result.error };\n }\n\n // Case 3: Source registry lookup — search known sources\n const results = discoverSources(harnessDir, source, { maxResults: 1 });\n if (results.length > 0) {\n const hit = results[0];\n // If the source is a GitHub source, construct a raw URL\n if (hit.source.type === 'github') {\n const rawUrl = convertToRawUrl(hit.url);\n const result = await downloadCapability(rawUrl);\n if (result.downloaded) {\n return { localPath: result.localPath, originalSource: source };\n }\n return { localPath: '', originalSource: source, error: result.error };\n }\n return { localPath: '', originalSource: source, error: `Source \"${hit.source.name}\" is type \"${hit.source.type}\" — direct install not yet supported for this type` };\n }\n\n return { localPath: '', originalSource: source, error: `Could not resolve \"${source}\" — not a local file, URL, or known source` };\n}\n\n// ─── Main Install Function ───────────────────────────────────────────────────\n\n/**\n * Universal install: resolve → detect → normalize → fix → install.\n *\n * Accepts a local path, URL, or search query. Detects the format,\n * normalizes to harness convention, applies auto-fixes, and installs\n * to the correct directory.\n *\n * @param harnessDir - Harness directory\n * @param source - File path, URL, or name to install\n * @param options - Installation options\n * @returns Install result with status, fixes, errors, dependency hints\n */\nexport async function universalInstall(\n harnessDir: string,\n source: string,\n options?: UniversalInstallOptions,\n): Promise<UniversalInstallResult> {\n const result: UniversalInstallResult = {\n installed: false,\n source,\n format: { format: 'unknown', primitiveType: null, confidence: 0, reasons: [] },\n destination: '',\n fixes: [],\n errors: [],\n suggestedDependencies: [],\n };\n\n // Step 1: Resolve source to local file\n const resolved = await resolveSource(source, harnessDir);\n if (resolved.error || !resolved.localPath) {\n result.errors.push(resolved.error ?? 'Failed to resolve source');\n return result;\n }\n\n // Step 2: Read content\n let content: string;\n try {\n content = readFileSync(resolved.localPath, 'utf-8');\n } catch (err) {\n result.errors.push(`Failed to read file: ${err instanceof Error ? err.message : String(err)}`);\n return result;\n }\n\n if (content.trim().length === 0) {\n result.errors.push('File is empty');\n return result;\n }\n\n // Step 3: Detect format\n const filename = basename(resolved.localPath);\n const detection = detectFormat(content, filename);\n result.format = detection;\n\n // Step 4: Normalize to harness convention\n const normalized = normalizeToHarness(content, filename, detection, options);\n result.fixes.push(...normalized.fixes);\n\n // Step 4b: Record provenance for URL installs so every installed file is\n // traceable back to its source. Local-path installs are skipped — the path\n // on disk is not a stable identifier.\n let finalContent = normalized.content;\n if (source.startsWith('http://') || source.startsWith('https://')) {\n finalContent = await recordProvenance(finalContent, source);\n result.fixes.push('Recorded provenance (source, installed_at, installed_by)');\n }\n\n // Step 5: Write normalized content to temp file for installation\n const tempDir = join(tmpdir(), 'harness-install');\n mkdirSync(tempDir, { recursive: true });\n const tempPath = join(tempDir, normalized.filename);\n writeFileSync(tempPath, finalContent, 'utf-8');\n\n // Step 6: Apply auto-fix if not skipped\n if (!options?.skipFix) {\n const fixResult = fixCapability(tempPath);\n result.fixes.push(...fixResult.fixes_applied);\n\n if (!fixResult.valid && !options?.force) {\n result.errors.push(...fixResult.errors);\n return result;\n }\n }\n\n // Step 7: Install via existing pipeline\n const installResult = installCapability(harnessDir, tempPath);\n result.installed = installResult.installed;\n result.destination = installResult.destination;\n\n if (!installResult.installed) {\n result.errors.push(...installResult.evalResult.errors);\n // If force mode, try direct copy\n if (options?.force && detection.primitiveType) {\n const targetDir = join(harnessDir, TYPE_DIRS[detection.primitiveType] ?? 'skills');\n if (!existsSync(targetDir)) mkdirSync(targetDir, { recursive: true });\n const dest = join(targetDir, normalized.filename);\n copyFileSync(tempPath, dest);\n result.installed = true;\n result.destination = dest;\n result.fixes.push('Force-installed despite validation errors');\n }\n }\n\n // Step 8: Scan for dependency hints\n result.suggestedDependencies = extractDependencyHints(normalized.content);\n\n return result;\n}\n\n/**\n * Install from a URL (convenience wrapper).\n */\nexport async function installFromUrl(\n harnessDir: string,\n url: string,\n options?: UniversalInstallOptions,\n): Promise<UniversalInstallResult> {\n return universalInstall(harnessDir, url, options);\n}\n\n/**\n * Install from a local file path (convenience wrapper).\n */\nexport async function installFromFile(\n harnessDir: string,\n filePath: string,\n options?: UniversalInstallOptions,\n): Promise<UniversalInstallResult> {\n return universalInstall(harnessDir, filePath, options);\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction deriveId(filename: string): string {\n const base = basename(filename).replace(/\\.(md|faf|yaml|yml|json|sh|bash)$/i, '');\n return base.replace(/[^a-z0-9-]/gi, '-').toLowerCase();\n}\n\nfunction ensureMdExtension(filename: string): string {\n if (filename.endsWith('.md')) return filename;\n return deriveId(filename) + '.md';\n}\n\n/**\n * Convert a GitHub URL to its raw content URL.\n *\n * Handles:\n * - github.com/owner/repo/blob/branch/path → raw.githubusercontent.com/owner/repo/branch/path\n * - Already raw.githubusercontent.com URLs → pass through\n * - Other URLs → pass through\n */\nexport function convertToRawUrl(url: string): string {\n // Already raw\n if (url.includes('raw.githubusercontent.com')) return url;\n\n // GitHub blob URL → raw\n const blobMatch = url.match(\n /^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/blob\\/(.+)$/,\n );\n if (blobMatch) {\n const [, owner, repo, rest] = blobMatch;\n return `https://raw.githubusercontent.com/${owner}/${repo}/${rest}`;\n }\n\n return url;\n}\n\n/**\n * Detect if content matches Claude Code SKILL.md patterns.\n * Claude skills are plain markdown with specific structural patterns.\n */\nfunction detectClaudeSkillPattern(content: string, filename: string): boolean {\n const nameLower = filename.toLowerCase();\n\n // Filename patterns\n if (nameLower === 'skill.md' || nameLower.endsWith('-skill.md') || nameLower.endsWith('_skill.md')) {\n return true;\n }\n\n // Content patterns common in Claude Code skills\n const patterns = [\n /^#\\s+.+skill/im,\n /instructions?\\s+for\\s+/i,\n /when\\s+(the\\s+)?user\\s+(asks?|wants?|needs?|requests?)/i,\n /you\\s+(should|must|will)\\s+/i,\n ];\n\n let matches = 0;\n for (const pattern of patterns) {\n if (pattern.test(content)) matches++;\n }\n\n // Need at least 2 pattern matches to classify as Claude skill\n // (plain markdown + instructional tone)\n return matches >= 2 && !content.startsWith('---');\n}\n\nfunction inferTypeFromFafType(fafType: string): string | null {\n const typeMap: Record<string, string> = {\n skill: 'skill',\n agent: 'agent',\n rule: 'rule',\n playbook: 'playbook',\n workflow: 'workflow',\n tool: 'tool',\n instinct: 'instinct',\n hook: 'workflow',\n template: 'skill',\n plugin: 'skill',\n };\n\n return typeMap[fafType.toLowerCase()] ?? null;\n}\n\nfunction inferTypeFromContent(content: string, filename: string): string | null {\n const lower = content.toLowerCase();\n const nameLower = filename.toLowerCase();\n\n // From filename\n if (nameLower.includes('rule')) return 'rule';\n if (nameLower.includes('agent')) return 'agent';\n if (nameLower.includes('playbook')) return 'playbook';\n if (nameLower.includes('workflow')) return 'workflow';\n if (nameLower.includes('instinct')) return 'instinct';\n if (nameLower.includes('tool')) return 'tool';\n if (nameLower.includes('skill')) return 'skill';\n\n // From content patterns\n if (lower.includes('# rule:') || lower.includes('## rules')) return 'rule';\n if (lower.includes('# agent:') || lower.includes('## agent')) return 'agent';\n if (lower.includes('# playbook:') || lower.includes('## playbook')) return 'playbook';\n if (lower.includes('# skill:') || lower.includes('## skill')) return 'skill';\n if (lower.includes('# workflow:') || lower.includes('## workflow')) return 'workflow';\n if (lower.includes('# tool:') || lower.includes('## tool')) return 'tool';\n\n // Default for markdown without clear type\n return null;\n}\n\n/**\n * Extract dependency hints from content.\n * Looks for references to tools, skills, or other primitives.\n */\nfunction extractDependencyHints(content: string): string[] {\n const hints: string[] = [];\n const seen = new Set<string>();\n\n // Look for \"requires:\" or \"depends:\" in frontmatter\n try {\n const parsed = matter(content);\n const data = parsed.data as Record<string, unknown>;\n if (Array.isArray(data.requires)) {\n for (const dep of data.requires as string[]) {\n if (!seen.has(dep)) {\n hints.push(dep);\n seen.add(dep);\n }\n }\n }\n if (Array.isArray(data.depends)) {\n for (const dep of data.depends as string[]) {\n if (!seen.has(dep)) {\n hints.push(dep);\n seen.add(dep);\n }\n }\n }\n if (Array.isArray(data.related)) {\n for (const dep of data.related as string[]) {\n if (!seen.has(dep)) {\n hints.push(dep);\n seen.add(dep);\n }\n }\n }\n } catch {\n // Ignore parse errors\n }\n\n return hints;\n}\n"],"mappings":"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","names":["require"]}