@ashx-j/lunr 0.2.12 → 0.2.13

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 (43) hide show
  1. package/CHANGELOG.md +7 -1
  2. package/dist/catalog/models.json +1 -1
  3. package/dist/catalog/providers/cloudflare-workers-ai.json +1 -1
  4. package/dist/catalog/providers/fireworks.json +1 -1
  5. package/dist/catalog/providers/opencode-go.json +1 -1
  6. package/dist/catalog/providers/opencode.json +1 -1
  7. package/dist/catalog/providers/openrouter.json +1 -1
  8. package/dist/catalog/providers/together.json +1 -1
  9. package/dist/catalog/publication.json +3 -3
  10. package/dist/core/context-breakdown.d.ts +3 -1
  11. package/dist/core/context-breakdown.d.ts.map +1 -1
  12. package/dist/core/context-breakdown.js +5 -2
  13. package/dist/core/context-breakdown.js.map +1 -1
  14. package/dist/core/settings-manager.d.ts +7 -0
  15. package/dist/core/settings-manager.d.ts.map +1 -1
  16. package/dist/core/settings-manager.js +13 -0
  17. package/dist/core/settings-manager.js.map +1 -1
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  22. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  23. package/dist/modes/interactive/components/settings-selector.js +105 -89
  24. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  25. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  26. package/dist/modes/interactive/interactive-mode.js +16 -3
  27. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  28. package/dist/modes/interactive/skill-tag-autocomplete.d.ts +13 -0
  29. package/dist/modes/interactive/skill-tag-autocomplete.d.ts.map +1 -0
  30. package/dist/modes/interactive/skill-tag-autocomplete.js +72 -0
  31. package/dist/modes/interactive/skill-tag-autocomplete.js.map +1 -0
  32. package/docs/settings.md +1 -0
  33. package/docs/skills.md +10 -0
  34. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  35. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  36. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  37. package/examples/extensions/gondolin/package-lock.json +2 -2
  38. package/examples/extensions/gondolin/package.json +1 -1
  39. package/examples/extensions/sandbox/package-lock.json +2 -2
  40. package/examples/extensions/sandbox/package.json +1 -1
  41. package/examples/extensions/with-deps/package-lock.json +2 -2
  42. package/examples/extensions/with-deps/package.json +1 -1
  43. package/package.json +4 -4
@@ -1 +1 @@
1
- {"MiniMaxAI/MiniMax-M2.7":{"id":"MiniMaxAI/MiniMax-M2.7","name":"MiniMax-M2.7","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":0.3,"output":1.2,"cacheRead":0.06,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":202752,"maxTokens":131072},"MiniMaxAI/MiniMax-M3":{"id":"MiniMaxAI/MiniMax-M3","name":"MiniMax-M3","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":0.3,"output":1.2,"cacheRead":0.06,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":524288,"maxTokens":250000},"Qwen/Qwen2.5-7B-Instruct-Turbo":{"id":"Qwen/Qwen2.5-7B-Instruct-Turbo","name":"Qwen 2.5 7B Instruct Turbo","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":false,"input":["text"],"cost":{"input":0.3,"output":0.3,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":32768,"maxTokens":32768},"Qwen/Qwen3.5-9B":{"id":"Qwen/Qwen3.5-9B","name":"Qwen3.5 9B","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":0.17,"output":0.25,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":262144,"maxTokens":65536},"Qwen/Qwen3.6-Plus":{"id":"Qwen/Qwen3.6-Plus","name":"Qwen3.6 Plus","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":0.5,"output":3,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1000000,"maxTokens":500000},"Qwen/Qwen3.7-Max":{"id":"Qwen/Qwen3.7-Max","name":"Qwen3.7 Max","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":false,"input":["text"],"cost":{"input":1.25,"output":3.75,"cacheRead":0.125,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1000000,"maxTokens":500000},"deepseek-ai/DeepSeek-V4-Flash-0731":{"id":"deepseek-ai/DeepSeek-V4-Flash-0731","name":"DeepSeek V4 Flash 0731","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":0.14,"output":0.28,"cacheRead":0.03,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1000000,"maxTokens":384000},"deepseek-ai/DeepSeek-V4-Pro":{"id":"deepseek-ai/DeepSeek-V4-Pro","name":"DeepSeek V4 Pro","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null,"high":"high","xhigh":null},"input":["text"],"cost":{"input":1.74,"output":3.48,"cacheRead":0.2,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":512000,"maxTokens":384000},"deepseek-ai/DeepSeek-V4-Pro-0813":{"id":"deepseek-ai/DeepSeek-V4-Pro-0813","name":"DeepSeek V4 Pro 0813","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":1.32,"output":3.96,"cacheRead":0.13,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1048576,"maxTokens":384000},"google/gemma-4-31B-it":{"id":"google/gemma-4-31B-it","name":"Gemma 4 31B Instruct","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":0.39,"output":0.97,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":262144,"maxTokens":131072},"meta-llama/Llama-3.3-70B-Instruct-Turbo":{"id":"meta-llama/Llama-3.3-70B-Instruct-Turbo","name":"Llama 3.3 70B","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":false,"input":["text"],"cost":{"input":1.04,"output":1.04,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":131072,"maxTokens":131072},"moonshotai/Kimi-K2.6":{"id":"moonshotai/Kimi-K2.6","name":"Kimi K2.6","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":1.2,"output":4.5,"cacheRead":0.2,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":262144,"maxTokens":131000},"moonshotai/Kimi-K2.7-Code":{"id":"moonshotai/Kimi-K2.7-Code","name":"Kimi K2.7 Code","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":0.95,"output":4,"cacheRead":0.19,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":262144,"maxTokens":131072},"moonshotai/Kimi-K3":{"id":"moonshotai/Kimi-K3","name":"Kimi K3","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":3,"output":15,"cacheRead":0.3,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1048576,"maxTokens":131072},"nvidia/nemotron-3-ultra-550b-a55b":{"id":"nvidia/nemotron-3-ultra-550b-a55b","name":"Nemotron 3 Ultra 550B A55B","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":0.6,"output":3.6,"cacheRead":0.2,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":512300,"maxTokens":512300},"openai/gpt-oss-120b":{"id":"openai/gpt-oss-120b","name":"GPT OSS 120B","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null},"input":["text"],"cost":{"input":0.15,"output":0.6,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"maxTokensField":"max_tokens","thinkingFormat":"openai","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":131072,"maxTokens":131072},"openai/gpt-oss-20b":{"id":"openai/gpt-oss-20b","name":"GPT OSS 20B","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null},"input":["text"],"cost":{"input":0.05,"output":0.2,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"maxTokensField":"max_tokens","thinkingFormat":"openai","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":131072,"maxTokens":131072},"thinkingmachines/Inkling":{"id":"thinkingmachines/Inkling","name":"Inkling","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":1,"output":4.05,"cacheRead":0.17,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":524288,"maxTokens":131072},"zai-org/GLM-5.2":{"id":"zai-org/GLM-5.2","name":"GLM-5.2","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":1.4,"output":4.4,"cacheRead":0.26,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":512000,"maxTokens":164000},"zai-org/GLM-5.3-Flash":{"id":"zai-org/GLM-5.3-Flash","name":"GLM-5.3-Flash","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":0.15,"output":0.5,"cacheRead":0.03,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1048575,"maxTokens":400000}}
1
+ {"MiniMaxAI/MiniMax-M2.7":{"id":"MiniMaxAI/MiniMax-M2.7","name":"MiniMax-M2.7","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":0.3,"output":1.2,"cacheRead":0.06,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":202752,"maxTokens":131072},"MiniMaxAI/MiniMax-M3":{"id":"MiniMaxAI/MiniMax-M3","name":"MiniMax-M3","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":0.3,"output":1.2,"cacheRead":0.06,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":524288,"maxTokens":250000},"Qwen/Qwen2.5-7B-Instruct-Turbo":{"id":"Qwen/Qwen2.5-7B-Instruct-Turbo","name":"Qwen 2.5 7B Instruct Turbo","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":false,"input":["text"],"cost":{"input":0.3,"output":0.3,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":32768,"maxTokens":32768},"Qwen/Qwen3.5-9B":{"id":"Qwen/Qwen3.5-9B","name":"Qwen3.5 9B","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":0.17,"output":0.25,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":262144,"maxTokens":65536},"Qwen/Qwen3.6-Plus":{"id":"Qwen/Qwen3.6-Plus","name":"Qwen3.6 Plus","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":0.5,"output":3,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1000000,"maxTokens":500000},"Qwen/Qwen3.7-Max":{"id":"Qwen/Qwen3.7-Max","name":"Qwen3.7 Max","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":false,"input":["text"],"cost":{"input":1.25,"output":3.75,"cacheRead":0.125,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1000000,"maxTokens":500000},"deepseek-ai/DeepSeek-V4-Flash-0731":{"id":"deepseek-ai/DeepSeek-V4-Flash-0731","name":"DeepSeek V4 Flash 0731","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":0.14,"output":0.28,"cacheRead":0.03,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1000000,"maxTokens":384000},"deepseek-ai/DeepSeek-V4-Pro":{"id":"deepseek-ai/DeepSeek-V4-Pro","name":"DeepSeek V4 Pro","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null,"high":"high","xhigh":null},"input":["text"],"cost":{"input":1.74,"output":3.48,"cacheRead":0.2,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":512000,"maxTokens":384000},"deepseek-ai/DeepSeek-V4-Pro-0813":{"id":"deepseek-ai/DeepSeek-V4-Pro-0813","name":"DeepSeek V4 Pro 0813","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":1.32,"output":3.96,"cacheRead":0.13,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1048576,"maxTokens":384000},"google/gemma-4-31B-it":{"id":"google/gemma-4-31B-it","name":"Gemma 4 31B Instruct","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":0.39,"output":0.97,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":262144,"maxTokens":131072},"meta-llama/Llama-3.3-70B-Instruct-Turbo":{"id":"meta-llama/Llama-3.3-70B-Instruct-Turbo","name":"Llama 3.3 70B","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":false,"input":["text"],"cost":{"input":1.04,"output":1.04,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":131072,"maxTokens":131072},"moonshotai/Kimi-K2.6":{"id":"moonshotai/Kimi-K2.6","name":"Kimi K2.6","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":1.2,"output":4.5,"cacheRead":0.2,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":262144,"maxTokens":131000},"moonshotai/Kimi-K2.7-Code":{"id":"moonshotai/Kimi-K2.7-Code","name":"Kimi K2.7 Code","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":0.95,"output":4,"cacheRead":0.19,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":262144,"maxTokens":131072},"moonshotai/Kimi-K3":{"id":"moonshotai/Kimi-K3","name":"Kimi K3","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":3,"output":15,"cacheRead":0.3,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1048576,"maxTokens":131072},"nvidia/nemotron-3-ultra-550b-a55b":{"id":"nvidia/nemotron-3-ultra-550b-a55b","name":"Nemotron 3 Ultra 550B A55B","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":0.6,"output":3.6,"cacheRead":0.2,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":512300,"maxTokens":512300},"openai/gpt-oss-120b":{"id":"openai/gpt-oss-120b","name":"GPT OSS 120B","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null},"input":["text"],"cost":{"input":0.15,"output":0.6,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"maxTokensField":"max_tokens","thinkingFormat":"openai","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":131072,"maxTokens":131072},"openai/gpt-oss-20b":{"id":"openai/gpt-oss-20b","name":"GPT OSS 20B","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null},"input":["text"],"cost":{"input":0.05,"output":0.2,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"maxTokensField":"max_tokens","thinkingFormat":"openai","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":131072,"maxTokens":131072},"thinkingmachines/Inkling":{"id":"thinkingmachines/Inkling","name":"Inkling","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":1,"output":4.05,"cacheRead":0.17,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":524288,"maxTokens":131072},"zai-org/GLM-5.2":{"id":"zai-org/GLM-5.2","name":"GLM-5.2","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":1.4,"output":4.4,"cacheRead":0.26,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":512000,"maxTokens":164000},"zai-org/GLM-5.3":{"id":"zai-org/GLM-5.3","name":"GLM-5.3","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text"],"cost":{"input":1.4,"output":4.4,"cacheRead":0.26,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1048576,"maxTokens":262144},"zai-org/GLM-5.3-Flash":{"id":"zai-org/GLM-5.3-Flash","name":"GLM-5.3-Flash","api":"openai-completions","provider":"together","baseUrl":"https://api.together.ai/v1","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null},"input":["text","image"],"cost":{"input":0.15,"output":0.5,"cacheRead":0.03,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"together","supportsStrictMode":false,"supportsLongCacheRetention":false},"contextWindow":1048575,"maxTokens":400000}}
@@ -1,6 +1,6 @@
1
1
  {
2
- "generatedAt": "2026-08-29T19:25:04.565Z",
3
- "sourceCommit": "10c801b19c19d6114c15231006a2e8ff0772085d",
2
+ "generatedAt": "2026-08-30T19:19:45.253Z",
3
+ "sourceCommit": "bfb4d26782faa71556e5f401251f7c5c49fa07e8",
4
4
  "providerCount": 39,
5
- "modelCount": 1392
5
+ "modelCount": 1393
6
6
  }
@@ -21,9 +21,11 @@ export interface ContextBreakdownInput {
21
21
  tools: ReadonlyArray<ContextBreakdownTool>;
22
22
  messages: ReadonlyArray<AgentMessage>;
23
23
  contextWindow: number;
24
+ /** Absolute path of the user-level AGENTS.md, used only to distinguish its UI label. */
25
+ globalAgentsPath?: string;
24
26
  }
25
27
  export interface ContextFileBreakdown {
26
- /** Basename of the context file (AGENTS.md, CLAUDE.md, …). */
28
+ /** Display label for the context file (AGENTS.md, Global AGENTS.md, CLAUDE.md, …). */
27
29
  label: string;
28
30
  /** Path from the <project_instructions path="…"> wrapper, when present. */
29
31
  path?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"context-breakdown.d.ts","sourceRoot":"","sources":["../../src/core/context-breakdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAIlE,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IAC3C,QAAQ,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACtC,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACpC,gEAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,6EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAChC,kEAAkE;IAClE,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,eAAe,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,MAAM,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;KAClB,CAAC;CACF;AAmBD,0EAA0E;AAC1E,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,GAAG;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,MAAM,EAAE,MAAM,CAAC;CACf,CAsBA;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,aAAa,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAY/F;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,qBAAqB,GAAG,gBAAgB,CAgGtF","sourcesContent":["/**\n * lunr: Context window breakdown estimation for the /context command.\n *\n * Pure functions that estimate (chars/4, same heuristic as `estimateTokens` in\n * compaction.ts) what consumes the model's context window: the system prompt\n * (project context files are baked into it), the registered tool definitions,\n * and the live session messages split into user / assistant text / thinking /\n * tool calls / tool results / summaries.\n *\n * Pass the same message list the context actually contains (post-compaction,\n * that is `AgentSession.messages`) so the breakdown matches reality.\n */\n\nimport type { AgentMessage } from \"@ashx-j/lunr-agent\";\nimport type { AssistantMessage } from \"@ashx-j/lunr-ai/compat\";\nimport { estimateTokens } from \"./compaction/index.ts\";\n\nexport interface ContextBreakdownTool {\n\tname: string;\n\tdescription: string;\n\tparameters: unknown;\n}\n\nexport interface ContextBreakdownInput {\n\tsystemPrompt: string;\n\ttools: ReadonlyArray<ContextBreakdownTool>;\n\tmessages: ReadonlyArray<AgentMessage>;\n\tcontextWindow: number;\n}\n\nexport interface ContextFileBreakdown {\n\t/** Basename of the context file (AGENTS.md, CLAUDE.md, …). */\n\tlabel: string;\n\t/** Path from the <project_instructions path=\"…\"> wrapper, when present. */\n\tpath?: string;\n\ttokens: number;\n}\n\nexport interface ContextBreakdown {\n\t/** System prompt minus <project_context> and the skills block. */\n\tsystemPrompt: number;\n\t/** Each AGENTS.md / context file from <project_instructions>. */\n\tcontextFiles: ContextFileBreakdown[];\n\t/** formatSkillsForPrompt section, if present. */\n\tskills: number;\n\t/** Serialized tool schemas (name + description + JSON parameter schema). */\n\ttoolDefinitions: number;\n\t/** User and extension (\"custom\") messages. */\n\tuser: number;\n\t/** Assistant text blocks. */\n\tassistantText: number;\n\t/** Assistant thinking blocks. */\n\tthinking: number;\n\t/** Assistant tool call blocks (name + serialized arguments). */\n\ttoolCalls: number;\n\t/** Tool result messages and bash execution output. */\n\ttoolResults: number;\n\t/** Compaction and branch summaries. */\n\tsummaries: number;\n\t/** Sum of all categories above. */\n\ttotal: number;\n\tcontextWindow: number;\n\t/** max(0, contextWindow - total) */\n\tfree: number;\n\t/** Per-category message counts (not token counts). */\n\tcounts: {\n\t\tuser: number;\n\t\tassistantText: number;\n\t\tthinking: number;\n\t\ttoolCalls: number;\n\t\ttoolResults: number;\n\t\tsummaries: number;\n\t};\n}\n\nconst CHARS_PER_TOKEN = 4;\nconst PROJECT_CONTEXT_RE = /<project_context>[\\s\\S]*?<\\/project_context>/;\nconst PROJECT_INSTRUCTIONS_RE = /<project_instructions(?:\\s+path=\"([^\"]*)\")?>([\\s\\S]*?)<\\/project_instructions>/g;\nconst SKILLS_BLOCK_RE =\n\t/\\n\\nThe following skills provide specialized instructions for specific tasks\\.[\\s\\S]*<\\/available_skills>/;\n\nfunction estimateChars(text: string): number {\n\treturn text.length === 0 ? 0 : Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\nfunction contextFileLabel(filePath: string | undefined): string {\n\tif (!filePath) return \"AGENTS.md\";\n\tconst normalized = filePath.replace(/\\\\/g, \"/\");\n\tconst slash = normalized.lastIndexOf(\"/\");\n\treturn slash === -1 ? normalized : normalized.slice(slash + 1);\n}\n\n/** Split a live system prompt into base / context-file / skills parts. */\nexport function splitSystemPromptSections(systemPrompt: string): {\n\tbase: string;\n\tcontextFiles: Array<{ path?: string; content: string }>;\n\tskills: string;\n} {\n\tlet remaining = systemPrompt;\n\tconst contextFiles: Array<{ path?: string; content: string }> = [];\n\tconst contextMatch = remaining.match(PROJECT_CONTEXT_RE);\n\tif (contextMatch) {\n\t\tconst block = contextMatch[0];\n\t\tPROJECT_INSTRUCTIONS_RE.lastIndex = 0;\n\t\tfor (const match of block.matchAll(PROJECT_INSTRUCTIONS_RE)) {\n\t\t\tcontextFiles.push({\n\t\t\t\tpath: match[1],\n\t\t\t\tcontent: match[2] ?? \"\",\n\t\t\t});\n\t\t}\n\t\tremaining = remaining.replace(block, \"\");\n\t}\n\tlet skills = \"\";\n\tconst skillsMatch = remaining.match(SKILLS_BLOCK_RE);\n\tif (skillsMatch) {\n\t\tskills = skillsMatch[0];\n\t\tremaining = remaining.replace(skills, \"\");\n\t}\n\treturn { base: remaining, contextFiles, skills };\n}\n\n/**\n * Estimate the token cost of the tool definitions sent to the model.\n * The wire format is roughly `{ name, description, parameters(JSON schema) }` per tool.\n */\nexport function estimateToolDefinitionTokens(tools: ReadonlyArray<ContextBreakdownTool>): number {\n\tlet chars = 0;\n\tfor (const tool of tools) {\n\t\tchars += tool.name.length + tool.description.length;\n\t\ttry {\n\t\t\tconst schema = JSON.stringify(tool.parameters);\n\t\t\tif (schema) chars += schema.length;\n\t\t} catch {\n\t\t\t// Unserializable schema — skip rather than fail the whole breakdown.\n\t\t}\n\t}\n\treturn Math.ceil(chars / CHARS_PER_TOKEN);\n}\n\n/**\n * Compute the estimated context window breakdown.\n * All numbers are chars/4 estimates, matching `estimateTokens`.\n */\nexport function computeContextBreakdown(input: ContextBreakdownInput): ContextBreakdown {\n\tconst sections = splitSystemPromptSections(input.systemPrompt);\n\tconst systemPrompt = estimateChars(sections.base);\n\tconst contextFiles = sections.contextFiles.map((file) => ({\n\t\tlabel: contextFileLabel(file.path),\n\t\tpath: file.path,\n\t\ttokens: estimateChars(file.content),\n\t}));\n\tconst skills = estimateChars(sections.skills);\n\tconst toolDefinitions = estimateToolDefinitionTokens(input.tools);\n\n\tlet user = 0;\n\tlet assistantText = 0;\n\tlet thinking = 0;\n\tlet toolCalls = 0;\n\tlet toolResults = 0;\n\tlet summaries = 0;\n\n\tconst counts = {\n\t\tuser: 0,\n\t\tassistantText: 0,\n\t\tthinking: 0,\n\t\ttoolCalls: 0,\n\t\ttoolResults: 0,\n\t\tsummaries: 0,\n\t};\n\n\tfor (const message of input.messages) {\n\t\tswitch (message.role) {\n\t\t\tcase \"assistant\": {\n\t\t\t\tlet textChars = 0;\n\t\t\t\tlet thinkingChars = 0;\n\t\t\t\tlet toolCallChars = 0;\n\t\t\t\tfor (const block of (message as AssistantMessage).content) {\n\t\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\t\ttextChars += block.text.length;\n\t\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t\tthinkingChars += block.thinking.length;\n\t\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\t\ttoolCallChars += block.name.length + JSON.stringify(block.arguments).length;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tassistantText += Math.ceil(textChars / CHARS_PER_TOKEN);\n\t\t\t\tthinking += Math.ceil(thinkingChars / CHARS_PER_TOKEN);\n\t\t\t\ttoolCalls += Math.ceil(toolCallChars / CHARS_PER_TOKEN);\n\t\t\t\tif (textChars > 0) counts.assistantText++;\n\t\t\t\tif (thinkingChars > 0) counts.thinking++;\n\t\t\t\tif (toolCallChars > 0) counts.toolCalls++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"user\":\n\t\t\tcase \"custom\":\n\t\t\t\tuser += estimateTokens(message);\n\t\t\t\tcounts.user++;\n\t\t\t\tbreak;\n\t\t\tcase \"toolResult\":\n\t\t\tcase \"bashExecution\":\n\t\t\t\ttoolResults += estimateTokens(message);\n\t\t\t\tcounts.toolResults++;\n\t\t\t\tbreak;\n\t\t\tcase \"branchSummary\":\n\t\t\tcase \"compactionSummary\":\n\t\t\t\tsummaries += estimateTokens(message);\n\t\t\t\tcounts.summaries++;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst contextFileTokens = contextFiles.reduce((sum, file) => sum + file.tokens, 0);\n\tconst total =\n\t\tsystemPrompt +\n\t\tcontextFileTokens +\n\t\tskills +\n\t\ttoolDefinitions +\n\t\tuser +\n\t\tassistantText +\n\t\tthinking +\n\t\ttoolCalls +\n\t\ttoolResults +\n\t\tsummaries;\n\treturn {\n\t\tsystemPrompt,\n\t\tcontextFiles,\n\t\tskills,\n\t\ttoolDefinitions,\n\t\tuser,\n\t\tassistantText,\n\t\tthinking,\n\t\ttoolCalls,\n\t\ttoolResults,\n\t\tsummaries,\n\t\ttotal,\n\t\tcontextWindow: input.contextWindow,\n\t\tfree: Math.max(0, input.contextWindow - total),\n\t\tcounts,\n\t};\n}\n"]}
1
+ {"version":3,"file":"context-breakdown.d.ts","sourceRoot":"","sources":["../../src/core/context-breakdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAIlE,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IAC3C,QAAQ,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,wFAAwF;IACxF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACpC,wFAAsF;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,6EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAChC,kEAAkE;IAClE,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,eAAe,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,MAAM,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;KAClB,CAAC;CACF;AAsBD,0EAA0E;AAC1E,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,GAAG;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,MAAM,EAAE,MAAM,CAAC;CACf,CAsBA;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,aAAa,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAY/F;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,qBAAqB,GAAG,gBAAgB,CAgGtF","sourcesContent":["/**\n * lunr: Context window breakdown estimation for the /context command.\n *\n * Pure functions that estimate (chars/4, same heuristic as `estimateTokens` in\n * compaction.ts) what consumes the model's context window: the system prompt\n * (project context files are baked into it), the registered tool definitions,\n * and the live session messages split into user / assistant text / thinking /\n * tool calls / tool results / summaries.\n *\n * Pass the same message list the context actually contains (post-compaction,\n * that is `AgentSession.messages`) so the breakdown matches reality.\n */\n\nimport type { AgentMessage } from \"@ashx-j/lunr-agent\";\nimport type { AssistantMessage } from \"@ashx-j/lunr-ai/compat\";\nimport { estimateTokens } from \"./compaction/index.ts\";\n\nexport interface ContextBreakdownTool {\n\tname: string;\n\tdescription: string;\n\tparameters: unknown;\n}\n\nexport interface ContextBreakdownInput {\n\tsystemPrompt: string;\n\ttools: ReadonlyArray<ContextBreakdownTool>;\n\tmessages: ReadonlyArray<AgentMessage>;\n\tcontextWindow: number;\n\t/** Absolute path of the user-level AGENTS.md, used only to distinguish its UI label. */\n\tglobalAgentsPath?: string;\n}\n\nexport interface ContextFileBreakdown {\n\t/** Display label for the context file (AGENTS.md, Global AGENTS.md, CLAUDE.md, …). */\n\tlabel: string;\n\t/** Path from the <project_instructions path=\"…\"> wrapper, when present. */\n\tpath?: string;\n\ttokens: number;\n}\n\nexport interface ContextBreakdown {\n\t/** System prompt minus <project_context> and the skills block. */\n\tsystemPrompt: number;\n\t/** Each AGENTS.md / context file from <project_instructions>. */\n\tcontextFiles: ContextFileBreakdown[];\n\t/** formatSkillsForPrompt section, if present. */\n\tskills: number;\n\t/** Serialized tool schemas (name + description + JSON parameter schema). */\n\ttoolDefinitions: number;\n\t/** User and extension (\"custom\") messages. */\n\tuser: number;\n\t/** Assistant text blocks. */\n\tassistantText: number;\n\t/** Assistant thinking blocks. */\n\tthinking: number;\n\t/** Assistant tool call blocks (name + serialized arguments). */\n\ttoolCalls: number;\n\t/** Tool result messages and bash execution output. */\n\ttoolResults: number;\n\t/** Compaction and branch summaries. */\n\tsummaries: number;\n\t/** Sum of all categories above. */\n\ttotal: number;\n\tcontextWindow: number;\n\t/** max(0, contextWindow - total) */\n\tfree: number;\n\t/** Per-category message counts (not token counts). */\n\tcounts: {\n\t\tuser: number;\n\t\tassistantText: number;\n\t\tthinking: number;\n\t\ttoolCalls: number;\n\t\ttoolResults: number;\n\t\tsummaries: number;\n\t};\n}\n\nconst CHARS_PER_TOKEN = 4;\nconst PROJECT_CONTEXT_RE = /<project_context>[\\s\\S]*?<\\/project_context>/;\nconst PROJECT_INSTRUCTIONS_RE = /<project_instructions(?:\\s+path=\"([^\"]*)\")?>([\\s\\S]*?)<\\/project_instructions>/g;\nconst SKILLS_BLOCK_RE =\n\t/\\n\\nThe following skills provide specialized instructions for specific tasks\\.[\\s\\S]*<\\/available_skills>/;\n\nfunction estimateChars(text: string): number {\n\treturn text.length === 0 ? 0 : Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\nfunction contextFileLabel(filePath: string | undefined, globalAgentsPath: string | undefined): string {\n\tif (!filePath) return \"AGENTS.md\";\n\tconst normalized = filePath.replace(/\\\\/g, \"/\");\n\tif (globalAgentsPath && normalized.toLowerCase() === globalAgentsPath.replace(/\\\\/g, \"/\").toLowerCase()) {\n\t\treturn \"Global AGENTS.md\";\n\t}\n\tconst slash = normalized.lastIndexOf(\"/\");\n\treturn slash === -1 ? normalized : normalized.slice(slash + 1);\n}\n\n/** Split a live system prompt into base / context-file / skills parts. */\nexport function splitSystemPromptSections(systemPrompt: string): {\n\tbase: string;\n\tcontextFiles: Array<{ path?: string; content: string }>;\n\tskills: string;\n} {\n\tlet remaining = systemPrompt;\n\tconst contextFiles: Array<{ path?: string; content: string }> = [];\n\tconst contextMatch = remaining.match(PROJECT_CONTEXT_RE);\n\tif (contextMatch) {\n\t\tconst block = contextMatch[0];\n\t\tPROJECT_INSTRUCTIONS_RE.lastIndex = 0;\n\t\tfor (const match of block.matchAll(PROJECT_INSTRUCTIONS_RE)) {\n\t\t\tcontextFiles.push({\n\t\t\t\tpath: match[1],\n\t\t\t\tcontent: match[2] ?? \"\",\n\t\t\t});\n\t\t}\n\t\tremaining = remaining.replace(block, \"\");\n\t}\n\tlet skills = \"\";\n\tconst skillsMatch = remaining.match(SKILLS_BLOCK_RE);\n\tif (skillsMatch) {\n\t\tskills = skillsMatch[0];\n\t\tremaining = remaining.replace(skills, \"\");\n\t}\n\treturn { base: remaining, contextFiles, skills };\n}\n\n/**\n * Estimate the token cost of the tool definitions sent to the model.\n * The wire format is roughly `{ name, description, parameters(JSON schema) }` per tool.\n */\nexport function estimateToolDefinitionTokens(tools: ReadonlyArray<ContextBreakdownTool>): number {\n\tlet chars = 0;\n\tfor (const tool of tools) {\n\t\tchars += tool.name.length + tool.description.length;\n\t\ttry {\n\t\t\tconst schema = JSON.stringify(tool.parameters);\n\t\t\tif (schema) chars += schema.length;\n\t\t} catch {\n\t\t\t// Unserializable schema — skip rather than fail the whole breakdown.\n\t\t}\n\t}\n\treturn Math.ceil(chars / CHARS_PER_TOKEN);\n}\n\n/**\n * Compute the estimated context window breakdown.\n * All numbers are chars/4 estimates, matching `estimateTokens`.\n */\nexport function computeContextBreakdown(input: ContextBreakdownInput): ContextBreakdown {\n\tconst sections = splitSystemPromptSections(input.systemPrompt);\n\tconst systemPrompt = estimateChars(sections.base);\n\tconst contextFiles = sections.contextFiles.map((file) => ({\n\t\tlabel: contextFileLabel(file.path, input.globalAgentsPath),\n\t\tpath: file.path,\n\t\ttokens: estimateChars(file.content),\n\t}));\n\tconst skills = estimateChars(sections.skills);\n\tconst toolDefinitions = estimateToolDefinitionTokens(input.tools);\n\n\tlet user = 0;\n\tlet assistantText = 0;\n\tlet thinking = 0;\n\tlet toolCalls = 0;\n\tlet toolResults = 0;\n\tlet summaries = 0;\n\n\tconst counts = {\n\t\tuser: 0,\n\t\tassistantText: 0,\n\t\tthinking: 0,\n\t\ttoolCalls: 0,\n\t\ttoolResults: 0,\n\t\tsummaries: 0,\n\t};\n\n\tfor (const message of input.messages) {\n\t\tswitch (message.role) {\n\t\t\tcase \"assistant\": {\n\t\t\t\tlet textChars = 0;\n\t\t\t\tlet thinkingChars = 0;\n\t\t\t\tlet toolCallChars = 0;\n\t\t\t\tfor (const block of (message as AssistantMessage).content) {\n\t\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\t\ttextChars += block.text.length;\n\t\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t\tthinkingChars += block.thinking.length;\n\t\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\t\ttoolCallChars += block.name.length + JSON.stringify(block.arguments).length;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tassistantText += Math.ceil(textChars / CHARS_PER_TOKEN);\n\t\t\t\tthinking += Math.ceil(thinkingChars / CHARS_PER_TOKEN);\n\t\t\t\ttoolCalls += Math.ceil(toolCallChars / CHARS_PER_TOKEN);\n\t\t\t\tif (textChars > 0) counts.assistantText++;\n\t\t\t\tif (thinkingChars > 0) counts.thinking++;\n\t\t\t\tif (toolCallChars > 0) counts.toolCalls++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"user\":\n\t\t\tcase \"custom\":\n\t\t\t\tuser += estimateTokens(message);\n\t\t\t\tcounts.user++;\n\t\t\t\tbreak;\n\t\t\tcase \"toolResult\":\n\t\t\tcase \"bashExecution\":\n\t\t\t\ttoolResults += estimateTokens(message);\n\t\t\t\tcounts.toolResults++;\n\t\t\t\tbreak;\n\t\t\tcase \"branchSummary\":\n\t\t\tcase \"compactionSummary\":\n\t\t\t\tsummaries += estimateTokens(message);\n\t\t\t\tcounts.summaries++;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst contextFileTokens = contextFiles.reduce((sum, file) => sum + file.tokens, 0);\n\tconst total =\n\t\tsystemPrompt +\n\t\tcontextFileTokens +\n\t\tskills +\n\t\ttoolDefinitions +\n\t\tuser +\n\t\tassistantText +\n\t\tthinking +\n\t\ttoolCalls +\n\t\ttoolResults +\n\t\tsummaries;\n\treturn {\n\t\tsystemPrompt,\n\t\tcontextFiles,\n\t\tskills,\n\t\ttoolDefinitions,\n\t\tuser,\n\t\tassistantText,\n\t\tthinking,\n\t\ttoolCalls,\n\t\ttoolResults,\n\t\tsummaries,\n\t\ttotal,\n\t\tcontextWindow: input.contextWindow,\n\t\tfree: Math.max(0, input.contextWindow - total),\n\t\tcounts,\n\t};\n}\n"]}
@@ -18,10 +18,13 @@ const SKILLS_BLOCK_RE = /\n\nThe following skills provide specialized instructio
18
18
  function estimateChars(text) {
19
19
  return text.length === 0 ? 0 : Math.ceil(text.length / CHARS_PER_TOKEN);
20
20
  }
21
- function contextFileLabel(filePath) {
21
+ function contextFileLabel(filePath, globalAgentsPath) {
22
22
  if (!filePath)
23
23
  return "AGENTS.md";
24
24
  const normalized = filePath.replace(/\\/g, "/");
25
+ if (globalAgentsPath && normalized.toLowerCase() === globalAgentsPath.replace(/\\/g, "/").toLowerCase()) {
26
+ return "Global AGENTS.md";
27
+ }
25
28
  const slash = normalized.lastIndexOf("/");
26
29
  return slash === -1 ? normalized : normalized.slice(slash + 1);
27
30
  }
@@ -76,7 +79,7 @@ export function computeContextBreakdown(input) {
76
79
  const sections = splitSystemPromptSections(input.systemPrompt);
77
80
  const systemPrompt = estimateChars(sections.base);
78
81
  const contextFiles = sections.contextFiles.map((file) => ({
79
- label: contextFileLabel(file.path),
82
+ label: contextFileLabel(file.path, input.globalAgentsPath),
80
83
  path: file.path,
81
84
  tokens: estimateChars(file.content),
82
85
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"context-breakdown.js","sourceRoot":"","sources":["../../src/core/context-breakdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA4DvD,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B,MAAM,kBAAkB,GAAG,8CAA8C,CAAC;AAC1E,MAAM,uBAAuB,GAAG,iFAAiF,CAAC;AAClH,MAAM,eAAe,GACpB,2GAA2G,CAAC;AAE7G,SAAS,aAAa,CAAC,IAAY,EAAU;IAC5C,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC;AAAA,CACxE;AAED,SAAS,gBAAgB,CAAC,QAA4B,EAAU;IAC/D,IAAI,CAAC,QAAQ;QAAE,OAAO,WAAW,CAAC;IAClC,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1C,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AAAA,CAC/D;AAED,0EAA0E;AAC1E,MAAM,UAAU,yBAAyB,CAAC,YAAoB,EAI5D;IACD,IAAI,SAAS,GAAG,YAAY,CAAC;IAC7B,MAAM,YAAY,GAA8C,EAAE,CAAC;IACnE,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACzD,IAAI,YAAY,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,uBAAuB,CAAC,SAAS,GAAG,CAAC,CAAC;QACtC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;YAC7D,YAAY,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;gBACd,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;aACvB,CAAC,CAAC;QACJ,CAAC;QACD,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,CAAC;IACD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACrD,IAAI,WAAW,EAAE,CAAC;QACjB,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QACxB,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;AAAA,CACjD;AAED;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAAC,KAA0C,EAAU;IAChG,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;QACpD,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/C,IAAI,MAAM;gBAAE,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACR,uEAAqE;QACtE,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,eAAe,CAAC,CAAC;AAAA,CAC1C;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAA4B,EAAoB;IACvF,MAAM,QAAQ,GAAG,yBAAyB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAC/D,MAAM,YAAY,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACzD,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;QAClC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC;KACnC,CAAC,CAAC,CAAC;IACJ,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,eAAe,GAAG,4BAA4B,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAElE,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,MAAM,MAAM,GAAG;QACd,IAAI,EAAE,CAAC;QACP,aAAa,EAAE,CAAC;QAChB,QAAQ,EAAE,CAAC;QACX,SAAS,EAAE,CAAC;QACZ,WAAW,EAAE,CAAC;QACd,SAAS,EAAE,CAAC;KACZ,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACtC,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;YACtB,KAAK,WAAW,EAAE,CAAC;gBAClB,IAAI,SAAS,GAAG,CAAC,CAAC;gBAClB,IAAI,aAAa,GAAG,CAAC,CAAC;gBACtB,IAAI,aAAa,GAAG,CAAC,CAAC;gBACtB,KAAK,MAAM,KAAK,IAAK,OAA4B,CAAC,OAAO,EAAE,CAAC;oBAC3D,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;wBAC3B,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;oBAChC,CAAC;yBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;wBACtC,aAAa,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;oBACxC,CAAC;yBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;wBACtC,aAAa,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;oBAC7E,CAAC;gBACF,CAAC;gBACD,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,eAAe,CAAC,CAAC;gBACxD,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC,CAAC;gBACvD,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC,CAAC;gBACxD,IAAI,SAAS,GAAG,CAAC;oBAAE,MAAM,CAAC,aAAa,EAAE,CAAC;gBAC1C,IAAI,aAAa,GAAG,CAAC;oBAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACzC,IAAI,aAAa,GAAG,CAAC;oBAAE,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC1C,MAAM;YACP,CAAC;YACD,KAAK,MAAM,CAAC;YACZ,KAAK,QAAQ;gBACZ,IAAI,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;gBAChC,MAAM,CAAC,IAAI,EAAE,CAAC;gBACd,MAAM;YACP,KAAK,YAAY,CAAC;YAClB,KAAK,eAAe;gBACnB,WAAW,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;gBACvC,MAAM,CAAC,WAAW,EAAE,CAAC;gBACrB,MAAM;YACP,KAAK,eAAe,CAAC;YACrB,KAAK,mBAAmB;gBACvB,SAAS,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;gBACrC,MAAM,CAAC,SAAS,EAAE,CAAC;gBACnB,MAAM;QACR,CAAC;IACF,CAAC;IAED,MAAM,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACnF,MAAM,KAAK,GACV,YAAY;QACZ,iBAAiB;QACjB,MAAM;QACN,eAAe;QACf,IAAI;QACJ,aAAa;QACb,QAAQ;QACR,SAAS;QACT,WAAW;QACX,SAAS,CAAC;IACX,OAAO;QACN,YAAY;QACZ,YAAY;QACZ,MAAM;QACN,eAAe;QACf,IAAI;QACJ,aAAa;QACb,QAAQ;QACR,SAAS;QACT,WAAW;QACX,SAAS;QACT,KAAK;QACL,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;QAC9C,MAAM;KACN,CAAC;AAAA,CACF","sourcesContent":["/**\n * lunr: Context window breakdown estimation for the /context command.\n *\n * Pure functions that estimate (chars/4, same heuristic as `estimateTokens` in\n * compaction.ts) what consumes the model's context window: the system prompt\n * (project context files are baked into it), the registered tool definitions,\n * and the live session messages split into user / assistant text / thinking /\n * tool calls / tool results / summaries.\n *\n * Pass the same message list the context actually contains (post-compaction,\n * that is `AgentSession.messages`) so the breakdown matches reality.\n */\n\nimport type { AgentMessage } from \"@ashx-j/lunr-agent\";\nimport type { AssistantMessage } from \"@ashx-j/lunr-ai/compat\";\nimport { estimateTokens } from \"./compaction/index.ts\";\n\nexport interface ContextBreakdownTool {\n\tname: string;\n\tdescription: string;\n\tparameters: unknown;\n}\n\nexport interface ContextBreakdownInput {\n\tsystemPrompt: string;\n\ttools: ReadonlyArray<ContextBreakdownTool>;\n\tmessages: ReadonlyArray<AgentMessage>;\n\tcontextWindow: number;\n}\n\nexport interface ContextFileBreakdown {\n\t/** Basename of the context file (AGENTS.md, CLAUDE.md, …). */\n\tlabel: string;\n\t/** Path from the <project_instructions path=\"…\"> wrapper, when present. */\n\tpath?: string;\n\ttokens: number;\n}\n\nexport interface ContextBreakdown {\n\t/** System prompt minus <project_context> and the skills block. */\n\tsystemPrompt: number;\n\t/** Each AGENTS.md / context file from <project_instructions>. */\n\tcontextFiles: ContextFileBreakdown[];\n\t/** formatSkillsForPrompt section, if present. */\n\tskills: number;\n\t/** Serialized tool schemas (name + description + JSON parameter schema). */\n\ttoolDefinitions: number;\n\t/** User and extension (\"custom\") messages. */\n\tuser: number;\n\t/** Assistant text blocks. */\n\tassistantText: number;\n\t/** Assistant thinking blocks. */\n\tthinking: number;\n\t/** Assistant tool call blocks (name + serialized arguments). */\n\ttoolCalls: number;\n\t/** Tool result messages and bash execution output. */\n\ttoolResults: number;\n\t/** Compaction and branch summaries. */\n\tsummaries: number;\n\t/** Sum of all categories above. */\n\ttotal: number;\n\tcontextWindow: number;\n\t/** max(0, contextWindow - total) */\n\tfree: number;\n\t/** Per-category message counts (not token counts). */\n\tcounts: {\n\t\tuser: number;\n\t\tassistantText: number;\n\t\tthinking: number;\n\t\ttoolCalls: number;\n\t\ttoolResults: number;\n\t\tsummaries: number;\n\t};\n}\n\nconst CHARS_PER_TOKEN = 4;\nconst PROJECT_CONTEXT_RE = /<project_context>[\\s\\S]*?<\\/project_context>/;\nconst PROJECT_INSTRUCTIONS_RE = /<project_instructions(?:\\s+path=\"([^\"]*)\")?>([\\s\\S]*?)<\\/project_instructions>/g;\nconst SKILLS_BLOCK_RE =\n\t/\\n\\nThe following skills provide specialized instructions for specific tasks\\.[\\s\\S]*<\\/available_skills>/;\n\nfunction estimateChars(text: string): number {\n\treturn text.length === 0 ? 0 : Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\nfunction contextFileLabel(filePath: string | undefined): string {\n\tif (!filePath) return \"AGENTS.md\";\n\tconst normalized = filePath.replace(/\\\\/g, \"/\");\n\tconst slash = normalized.lastIndexOf(\"/\");\n\treturn slash === -1 ? normalized : normalized.slice(slash + 1);\n}\n\n/** Split a live system prompt into base / context-file / skills parts. */\nexport function splitSystemPromptSections(systemPrompt: string): {\n\tbase: string;\n\tcontextFiles: Array<{ path?: string; content: string }>;\n\tskills: string;\n} {\n\tlet remaining = systemPrompt;\n\tconst contextFiles: Array<{ path?: string; content: string }> = [];\n\tconst contextMatch = remaining.match(PROJECT_CONTEXT_RE);\n\tif (contextMatch) {\n\t\tconst block = contextMatch[0];\n\t\tPROJECT_INSTRUCTIONS_RE.lastIndex = 0;\n\t\tfor (const match of block.matchAll(PROJECT_INSTRUCTIONS_RE)) {\n\t\t\tcontextFiles.push({\n\t\t\t\tpath: match[1],\n\t\t\t\tcontent: match[2] ?? \"\",\n\t\t\t});\n\t\t}\n\t\tremaining = remaining.replace(block, \"\");\n\t}\n\tlet skills = \"\";\n\tconst skillsMatch = remaining.match(SKILLS_BLOCK_RE);\n\tif (skillsMatch) {\n\t\tskills = skillsMatch[0];\n\t\tremaining = remaining.replace(skills, \"\");\n\t}\n\treturn { base: remaining, contextFiles, skills };\n}\n\n/**\n * Estimate the token cost of the tool definitions sent to the model.\n * The wire format is roughly `{ name, description, parameters(JSON schema) }` per tool.\n */\nexport function estimateToolDefinitionTokens(tools: ReadonlyArray<ContextBreakdownTool>): number {\n\tlet chars = 0;\n\tfor (const tool of tools) {\n\t\tchars += tool.name.length + tool.description.length;\n\t\ttry {\n\t\t\tconst schema = JSON.stringify(tool.parameters);\n\t\t\tif (schema) chars += schema.length;\n\t\t} catch {\n\t\t\t// Unserializable schema — skip rather than fail the whole breakdown.\n\t\t}\n\t}\n\treturn Math.ceil(chars / CHARS_PER_TOKEN);\n}\n\n/**\n * Compute the estimated context window breakdown.\n * All numbers are chars/4 estimates, matching `estimateTokens`.\n */\nexport function computeContextBreakdown(input: ContextBreakdownInput): ContextBreakdown {\n\tconst sections = splitSystemPromptSections(input.systemPrompt);\n\tconst systemPrompt = estimateChars(sections.base);\n\tconst contextFiles = sections.contextFiles.map((file) => ({\n\t\tlabel: contextFileLabel(file.path),\n\t\tpath: file.path,\n\t\ttokens: estimateChars(file.content),\n\t}));\n\tconst skills = estimateChars(sections.skills);\n\tconst toolDefinitions = estimateToolDefinitionTokens(input.tools);\n\n\tlet user = 0;\n\tlet assistantText = 0;\n\tlet thinking = 0;\n\tlet toolCalls = 0;\n\tlet toolResults = 0;\n\tlet summaries = 0;\n\n\tconst counts = {\n\t\tuser: 0,\n\t\tassistantText: 0,\n\t\tthinking: 0,\n\t\ttoolCalls: 0,\n\t\ttoolResults: 0,\n\t\tsummaries: 0,\n\t};\n\n\tfor (const message of input.messages) {\n\t\tswitch (message.role) {\n\t\t\tcase \"assistant\": {\n\t\t\t\tlet textChars = 0;\n\t\t\t\tlet thinkingChars = 0;\n\t\t\t\tlet toolCallChars = 0;\n\t\t\t\tfor (const block of (message as AssistantMessage).content) {\n\t\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\t\ttextChars += block.text.length;\n\t\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t\tthinkingChars += block.thinking.length;\n\t\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\t\ttoolCallChars += block.name.length + JSON.stringify(block.arguments).length;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tassistantText += Math.ceil(textChars / CHARS_PER_TOKEN);\n\t\t\t\tthinking += Math.ceil(thinkingChars / CHARS_PER_TOKEN);\n\t\t\t\ttoolCalls += Math.ceil(toolCallChars / CHARS_PER_TOKEN);\n\t\t\t\tif (textChars > 0) counts.assistantText++;\n\t\t\t\tif (thinkingChars > 0) counts.thinking++;\n\t\t\t\tif (toolCallChars > 0) counts.toolCalls++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"user\":\n\t\t\tcase \"custom\":\n\t\t\t\tuser += estimateTokens(message);\n\t\t\t\tcounts.user++;\n\t\t\t\tbreak;\n\t\t\tcase \"toolResult\":\n\t\t\tcase \"bashExecution\":\n\t\t\t\ttoolResults += estimateTokens(message);\n\t\t\t\tcounts.toolResults++;\n\t\t\t\tbreak;\n\t\t\tcase \"branchSummary\":\n\t\t\tcase \"compactionSummary\":\n\t\t\t\tsummaries += estimateTokens(message);\n\t\t\t\tcounts.summaries++;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst contextFileTokens = contextFiles.reduce((sum, file) => sum + file.tokens, 0);\n\tconst total =\n\t\tsystemPrompt +\n\t\tcontextFileTokens +\n\t\tskills +\n\t\ttoolDefinitions +\n\t\tuser +\n\t\tassistantText +\n\t\tthinking +\n\t\ttoolCalls +\n\t\ttoolResults +\n\t\tsummaries;\n\treturn {\n\t\tsystemPrompt,\n\t\tcontextFiles,\n\t\tskills,\n\t\ttoolDefinitions,\n\t\tuser,\n\t\tassistantText,\n\t\tthinking,\n\t\ttoolCalls,\n\t\ttoolResults,\n\t\tsummaries,\n\t\ttotal,\n\t\tcontextWindow: input.contextWindow,\n\t\tfree: Math.max(0, input.contextWindow - total),\n\t\tcounts,\n\t};\n}\n"]}
1
+ {"version":3,"file":"context-breakdown.js","sourceRoot":"","sources":["../../src/core/context-breakdown.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * lunr: Context window breakdown estimation for the /context command.\n *\n * Pure functions that estimate (chars/4, same heuristic as `estimateTokens` in\n * compaction.ts) what consumes the model's context window: the system prompt\n * (project context files are baked into it), the registered tool definitions,\n * and the live session messages split into user / assistant text / thinking /\n * tool calls / tool results / summaries.\n *\n * Pass the same message list the context actually contains (post-compaction,\n * that is `AgentSession.messages`) so the breakdown matches reality.\n */\n\nimport type { AgentMessage } from \"@ashx-j/lunr-agent\";\nimport type { AssistantMessage } from \"@ashx-j/lunr-ai/compat\";\nimport { estimateTokens } from \"./compaction/index.ts\";\n\nexport interface ContextBreakdownTool {\n\tname: string;\n\tdescription: string;\n\tparameters: unknown;\n}\n\nexport interface ContextBreakdownInput {\n\tsystemPrompt: string;\n\ttools: ReadonlyArray<ContextBreakdownTool>;\n\tmessages: ReadonlyArray<AgentMessage>;\n\tcontextWindow: number;\n\t/** Absolute path of the user-level AGENTS.md, used only to distinguish its UI label. */\n\tglobalAgentsPath?: string;\n}\n\nexport interface ContextFileBreakdown {\n\t/** Display label for the context file (AGENTS.md, Global AGENTS.md, CLAUDE.md, …). */\n\tlabel: string;\n\t/** Path from the <project_instructions path=\"…\"> wrapper, when present. */\n\tpath?: string;\n\ttokens: number;\n}\n\nexport interface ContextBreakdown {\n\t/** System prompt minus <project_context> and the skills block. */\n\tsystemPrompt: number;\n\t/** Each AGENTS.md / context file from <project_instructions>. */\n\tcontextFiles: ContextFileBreakdown[];\n\t/** formatSkillsForPrompt section, if present. */\n\tskills: number;\n\t/** Serialized tool schemas (name + description + JSON parameter schema). */\n\ttoolDefinitions: number;\n\t/** User and extension (\"custom\") messages. */\n\tuser: number;\n\t/** Assistant text blocks. */\n\tassistantText: number;\n\t/** Assistant thinking blocks. */\n\tthinking: number;\n\t/** Assistant tool call blocks (name + serialized arguments). */\n\ttoolCalls: number;\n\t/** Tool result messages and bash execution output. */\n\ttoolResults: number;\n\t/** Compaction and branch summaries. */\n\tsummaries: number;\n\t/** Sum of all categories above. */\n\ttotal: number;\n\tcontextWindow: number;\n\t/** max(0, contextWindow - total) */\n\tfree: number;\n\t/** Per-category message counts (not token counts). */\n\tcounts: {\n\t\tuser: number;\n\t\tassistantText: number;\n\t\tthinking: number;\n\t\ttoolCalls: number;\n\t\ttoolResults: number;\n\t\tsummaries: number;\n\t};\n}\n\nconst CHARS_PER_TOKEN = 4;\nconst PROJECT_CONTEXT_RE = /<project_context>[\\s\\S]*?<\\/project_context>/;\nconst PROJECT_INSTRUCTIONS_RE = /<project_instructions(?:\\s+path=\"([^\"]*)\")?>([\\s\\S]*?)<\\/project_instructions>/g;\nconst SKILLS_BLOCK_RE =\n\t/\\n\\nThe following skills provide specialized instructions for specific tasks\\.[\\s\\S]*<\\/available_skills>/;\n\nfunction estimateChars(text: string): number {\n\treturn text.length === 0 ? 0 : Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\nfunction contextFileLabel(filePath: string | undefined, globalAgentsPath: string | undefined): string {\n\tif (!filePath) return \"AGENTS.md\";\n\tconst normalized = filePath.replace(/\\\\/g, \"/\");\n\tif (globalAgentsPath && normalized.toLowerCase() === globalAgentsPath.replace(/\\\\/g, \"/\").toLowerCase()) {\n\t\treturn \"Global AGENTS.md\";\n\t}\n\tconst slash = normalized.lastIndexOf(\"/\");\n\treturn slash === -1 ? normalized : normalized.slice(slash + 1);\n}\n\n/** Split a live system prompt into base / context-file / skills parts. */\nexport function splitSystemPromptSections(systemPrompt: string): {\n\tbase: string;\n\tcontextFiles: Array<{ path?: string; content: string }>;\n\tskills: string;\n} {\n\tlet remaining = systemPrompt;\n\tconst contextFiles: Array<{ path?: string; content: string }> = [];\n\tconst contextMatch = remaining.match(PROJECT_CONTEXT_RE);\n\tif (contextMatch) {\n\t\tconst block = contextMatch[0];\n\t\tPROJECT_INSTRUCTIONS_RE.lastIndex = 0;\n\t\tfor (const match of block.matchAll(PROJECT_INSTRUCTIONS_RE)) {\n\t\t\tcontextFiles.push({\n\t\t\t\tpath: match[1],\n\t\t\t\tcontent: match[2] ?? \"\",\n\t\t\t});\n\t\t}\n\t\tremaining = remaining.replace(block, \"\");\n\t}\n\tlet skills = \"\";\n\tconst skillsMatch = remaining.match(SKILLS_BLOCK_RE);\n\tif (skillsMatch) {\n\t\tskills = skillsMatch[0];\n\t\tremaining = remaining.replace(skills, \"\");\n\t}\n\treturn { base: remaining, contextFiles, skills };\n}\n\n/**\n * Estimate the token cost of the tool definitions sent to the model.\n * The wire format is roughly `{ name, description, parameters(JSON schema) }` per tool.\n */\nexport function estimateToolDefinitionTokens(tools: ReadonlyArray<ContextBreakdownTool>): number {\n\tlet chars = 0;\n\tfor (const tool of tools) {\n\t\tchars += tool.name.length + tool.description.length;\n\t\ttry {\n\t\t\tconst schema = JSON.stringify(tool.parameters);\n\t\t\tif (schema) chars += schema.length;\n\t\t} catch {\n\t\t\t// Unserializable schema — skip rather than fail the whole breakdown.\n\t\t}\n\t}\n\treturn Math.ceil(chars / CHARS_PER_TOKEN);\n}\n\n/**\n * Compute the estimated context window breakdown.\n * All numbers are chars/4 estimates, matching `estimateTokens`.\n */\nexport function computeContextBreakdown(input: ContextBreakdownInput): ContextBreakdown {\n\tconst sections = splitSystemPromptSections(input.systemPrompt);\n\tconst systemPrompt = estimateChars(sections.base);\n\tconst contextFiles = sections.contextFiles.map((file) => ({\n\t\tlabel: contextFileLabel(file.path, input.globalAgentsPath),\n\t\tpath: file.path,\n\t\ttokens: estimateChars(file.content),\n\t}));\n\tconst skills = estimateChars(sections.skills);\n\tconst toolDefinitions = estimateToolDefinitionTokens(input.tools);\n\n\tlet user = 0;\n\tlet assistantText = 0;\n\tlet thinking = 0;\n\tlet toolCalls = 0;\n\tlet toolResults = 0;\n\tlet summaries = 0;\n\n\tconst counts = {\n\t\tuser: 0,\n\t\tassistantText: 0,\n\t\tthinking: 0,\n\t\ttoolCalls: 0,\n\t\ttoolResults: 0,\n\t\tsummaries: 0,\n\t};\n\n\tfor (const message of input.messages) {\n\t\tswitch (message.role) {\n\t\t\tcase \"assistant\": {\n\t\t\t\tlet textChars = 0;\n\t\t\t\tlet thinkingChars = 0;\n\t\t\t\tlet toolCallChars = 0;\n\t\t\t\tfor (const block of (message as AssistantMessage).content) {\n\t\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\t\ttextChars += block.text.length;\n\t\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t\tthinkingChars += block.thinking.length;\n\t\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\t\ttoolCallChars += block.name.length + JSON.stringify(block.arguments).length;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tassistantText += Math.ceil(textChars / CHARS_PER_TOKEN);\n\t\t\t\tthinking += Math.ceil(thinkingChars / CHARS_PER_TOKEN);\n\t\t\t\ttoolCalls += Math.ceil(toolCallChars / CHARS_PER_TOKEN);\n\t\t\t\tif (textChars > 0) counts.assistantText++;\n\t\t\t\tif (thinkingChars > 0) counts.thinking++;\n\t\t\t\tif (toolCallChars > 0) counts.toolCalls++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"user\":\n\t\t\tcase \"custom\":\n\t\t\t\tuser += estimateTokens(message);\n\t\t\t\tcounts.user++;\n\t\t\t\tbreak;\n\t\t\tcase \"toolResult\":\n\t\t\tcase \"bashExecution\":\n\t\t\t\ttoolResults += estimateTokens(message);\n\t\t\t\tcounts.toolResults++;\n\t\t\t\tbreak;\n\t\t\tcase \"branchSummary\":\n\t\t\tcase \"compactionSummary\":\n\t\t\t\tsummaries += estimateTokens(message);\n\t\t\t\tcounts.summaries++;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst contextFileTokens = contextFiles.reduce((sum, file) => sum + file.tokens, 0);\n\tconst total =\n\t\tsystemPrompt +\n\t\tcontextFileTokens +\n\t\tskills +\n\t\ttoolDefinitions +\n\t\tuser +\n\t\tassistantText +\n\t\tthinking +\n\t\ttoolCalls +\n\t\ttoolResults +\n\t\tsummaries;\n\treturn {\n\t\tsystemPrompt,\n\t\tcontextFiles,\n\t\tskills,\n\t\ttoolDefinitions,\n\t\tuser,\n\t\tassistantText,\n\t\tthinking,\n\t\ttoolCalls,\n\t\ttoolResults,\n\t\tsummaries,\n\t\ttotal,\n\t\tcontextWindow: input.contextWindow,\n\t\tfree: Math.max(0, input.contextWindow - total),\n\t\tcounts,\n\t};\n}\n"]}
@@ -52,6 +52,10 @@ export interface MarkdownSettings {
52
52
  }
53
53
  export type DefaultProjectTrust = "ask" | "always" | "never";
54
54
  export type DefaultPermissionMode = "manual" | "yolo" | "plan" | "auto";
55
+ export type SkillTagCharacter = "+" | "~" | "$";
56
+ export declare const SKILL_TAG_CHARACTERS: readonly SkillTagCharacter[];
57
+ export declare const DEFAULT_SKILL_TAG_CHARACTER: SkillTagCharacter;
58
+ export declare function parseSkillTagCharacter(value: unknown): SkillTagCharacter;
55
59
  export type RollbackCapture = "copies" | "shadow-git" | "hybrid";
56
60
  export type RollbackScope = "tools" | "tree";
57
61
  export type TransportSetting = Transport;
@@ -101,6 +105,7 @@ export interface Settings {
101
105
  prompts?: string[];
102
106
  themes?: string[];
103
107
  enableSkillCommands?: boolean;
108
+ skillTagCharacter?: SkillTagCharacter;
104
109
  terminal?: TerminalSettings;
105
110
  images?: ImageSettings;
106
111
  enabledModels?: string[];
@@ -346,6 +351,8 @@ export declare class SettingsManager {
346
351
  setProjectThemePaths(paths: string[]): void;
347
352
  getEnableSkillCommands(): boolean;
348
353
  setEnableSkillCommands(enabled: boolean): void;
354
+ getSkillTagCharacter(): SkillTagCharacter;
355
+ setSkillTagCharacter(character: SkillTagCharacter): void;
349
356
  getThinkingBudgets(): ThinkingBudgetsSettings | undefined;
350
357
  getShowImages(): boolean;
351
358
  setShowImages(show: boolean): void;