natureco-cli 5.18.3 → 5.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/package.json +1 -1
  3. package/skills/a-b-testing/SKILL.md +34 -0
  4. package/skills/accessibility-audit/SKILL.md +34 -0
  5. package/skills/agent-memory/SKILL.md +34 -0
  6. package/skills/agent-orchestration/SKILL.md +34 -0
  7. package/skills/airunway-aks-setup/SKILL.md +73 -0
  8. package/skills/algorithmic-art/SKILL.md +405 -0
  9. package/skills/analytics-setup/SKILL.md +34 -0
  10. package/skills/api-design/SKILL.md +34 -0
  11. package/skills/api-versioning/SKILL.md +34 -0
  12. package/skills/appinsights-instrumentation/SKILL.md +76 -0
  13. package/skills/audio-transcription/SKILL.md +34 -0
  14. package/skills/authentication-patterns/SKILL.md +34 -0
  15. package/skills/authorization-rbac/SKILL.md +34 -0
  16. package/skills/azure-ai/SKILL.md +71 -0
  17. package/skills/azure-aigateway/SKILL.md +129 -0
  18. package/skills/azure-cloud-migrate/SKILL.md +52 -0
  19. package/skills/azure-compliance/SKILL.md +108 -0
  20. package/skills/azure-compute/SKILL.md +46 -0
  21. package/skills/azure-cost/SKILL.md +45 -0
  22. package/skills/azure-deploy/SKILL.md +97 -0
  23. package/skills/azure-diagnostics/SKILL.md +151 -0
  24. package/skills/azure-enterprise-infra-planner/SKILL.md +54 -0
  25. package/skills/azure-hosted-copilot-sdk/SKILL.md +89 -0
  26. package/skills/azure-kubernetes/SKILL.md +153 -0
  27. package/skills/azure-kusto/SKILL.md +231 -0
  28. package/skills/azure-messaging/SKILL.md +57 -0
  29. package/skills/azure-prepare/SKILL.md +165 -0
  30. package/skills/azure-quotas/SKILL.md +276 -0
  31. package/skills/azure-rbac/SKILL.md +17 -0
  32. package/skills/azure-reliability/SKILL.md +387 -0
  33. package/skills/azure-resource-lookup/SKILL.md +108 -0
  34. package/skills/azure-resource-visualizer/SKILL.md +183 -0
  35. package/skills/azure-storage/SKILL.md +100 -0
  36. package/skills/azure-upgrade/SKILL.md +91 -0
  37. package/skills/azure-validate/SKILL.md +72 -0
  38. package/skills/backup-strategy/SKILL.md +34 -0
  39. package/skills/bash-scripting/SKILL.md +34 -0
  40. package/skills/batch-api-calls/SKILL.md +34 -0
  41. package/skills/batch-processing/SKILL.md +34 -0
  42. package/skills/brainstorming/SKILL.md +159 -0
  43. package/skills/brand-guidelines/SKILL.md +73 -0
  44. package/skills/brandkit/SKILL.md +798 -0
  45. package/skills/brutalist-skill/SKILL.md +92 -0
  46. package/skills/bulk-file-operations/SKILL.md +34 -0
  47. package/skills/cache-responses/SKILL.md +34 -0
  48. package/skills/caching-strategy/SKILL.md +34 -0
  49. package/skills/calendar-optimization/SKILL.md +34 -0
  50. package/skills/canvas-design/SKILL.md +130 -0
  51. package/skills/cavecrew/SKILL.md +82 -0
  52. package/skills/caveman-commit/SKILL.md +65 -0
  53. package/skills/caveman-help/SKILL.md +63 -0
  54. package/skills/caveman-review/SKILL.md +55 -0
  55. package/skills/caveman-stats/SKILL.md +10 -0
  56. package/skills/changelog-generation/SKILL.md +34 -0
  57. package/skills/chat-bot-design/SKILL.md +34 -0
  58. package/skills/chunking-strategy/SKILL.md +34 -0
  59. package/skills/ci-cd-pipeline/SKILL.md +34 -0
  60. package/skills/classification-pipeline/SKILL.md +34 -0
  61. package/skills/claude-api/SKILL.md +356 -0
  62. package/skills/clipboard-master/SKILL.md +34 -0
  63. package/skills/code-explanation/SKILL.md +34 -0
  64. package/skills/code-generation/SKILL.md +34 -0
  65. package/skills/code-migration/SKILL.md +34 -0
  66. package/skills/code-review-checklist/SKILL.md +34 -0
  67. package/skills/composition-patterns/SKILL.md +89 -0
  68. package/skills/contact-management/SKILL.md +34 -0
  69. package/skills/content-generation/SKILL.md +34 -0
  70. package/skills/context-pruning/SKILL.md +34 -0
  71. package/skills/context-window-management/SKILL.md +34 -0
  72. package/skills/continuous-improvement/SKILL.md +34 -0
  73. package/skills/cron-scheduling/SKILL.md +34 -0
  74. package/skills/cross-platform-compat/SKILL.md +34 -0
  75. package/skills/csv-processing/SKILL.md +34 -0
  76. package/skills/daily-journal/SKILL.md +34 -0
  77. package/skills/data-analysis/SKILL.md +34 -0
  78. package/skills/data-backup/SKILL.md +34 -0
  79. package/skills/data-cleaning/SKILL.md +34 -0
  80. package/skills/data-extraction/SKILL.md +34 -0
  81. package/skills/data-validation/SKILL.md +34 -0
  82. package/skills/database-migrations/SKILL.md +34 -0
  83. package/skills/database-schema-design/SKILL.md +34 -0
  84. package/skills/decision-mapping/SKILL.md +84 -0
  85. package/skills/decision-matrix/SKILL.md +34 -0
  86. package/skills/dependency-management/SKILL.md +34 -0
  87. package/skills/deploy-to-vercel/SKILL.md +296 -0
  88. package/skills/design-an-interface/SKILL.md +94 -0
  89. package/skills/design-doc-mermaid/SKILL.md +498 -0
  90. package/skills/dev-environment-setup/SKILL.md +34 -0
  91. package/skills/develop-userscripts/SKILL.md +84 -0
  92. package/skills/distraction-blocker/SKILL.md +34 -0
  93. package/skills/doc-coauthoring/SKILL.md +375 -0
  94. package/skills/docker-optimization/SKILL.md +34 -0
  95. package/skills/document-template/SKILL.md +34 -0
  96. package/skills/documentation/SKILL.md +109 -0
  97. package/skills/documentation-gen/SKILL.md +34 -0
  98. package/skills/docx/SKILL.md +590 -0
  99. package/skills/edit-article/SKILL.md +15 -0
  100. package/skills/efficient-formatting/SKILL.md +34 -0
  101. package/skills/email-management/SKILL.md +34 -0
  102. package/skills/email-service/SKILL.md +34 -0
  103. package/skills/embedding-generation/SKILL.md +34 -0
  104. package/skills/entity-extraction/SKILL.md +34 -0
  105. package/skills/entra-agent-id/SKILL.md +356 -0
  106. package/skills/entra-app-registration/SKILL.md +191 -0
  107. package/skills/environment-config/SKILL.md +34 -0
  108. package/skills/error-handling/SKILL.md +34 -0
  109. package/skills/estimation-techniques/SKILL.md +34 -0
  110. package/skills/event-driven-architecture/SKILL.md +34 -0
  111. package/skills/excel-automation/SKILL.md +34 -0
  112. package/skills/execution-monitoring/SKILL.md +34 -0
  113. package/skills/expense-tracking/SKILL.md +34 -0
  114. package/skills/faceless-explainer/SKILL.md +202 -0
  115. package/skills/fastify/SKILL.md +75 -0
  116. package/skills/feature-engineering/SKILL.md +34 -0
  117. package/skills/feature-flags/SKILL.md +34 -0
  118. package/skills/file-conversion/SKILL.md +34 -0
  119. package/skills/file-upload-handling/SKILL.md +34 -0
  120. package/skills/fine-tuning-prep/SKILL.md +34 -0
  121. package/skills/focus-mode/SKILL.md +34 -0
  122. package/skills/form-validation/SKILL.md +34 -0
  123. package/skills/function-calling/SKILL.md +34 -0
  124. package/skills/general-video/SKILL.md +143 -0
  125. package/skills/git-guardrails-claude-code/SKILL.md +95 -0
  126. package/skills/git-workflow/SKILL.md +34 -0
  127. package/skills/github-actions-docs/SKILL.md +98 -0
  128. package/skills/goal-setting/SKILL.md +34 -0
  129. package/skills/gpt-tasteskill/SKILL.md +74 -0
  130. package/skills/graphql-design/SKILL.md +34 -0
  131. package/skills/grill-me/SKILL.md +7 -0
  132. package/skills/grilling/SKILL.md +10 -0
  133. package/skills/habit-tracker/SKILL.md +34 -0
  134. package/skills/hallucination-detection/SKILL.md +34 -0
  135. package/skills/handoff/SKILL.md +16 -0
  136. package/skills/hyperframes/SKILL.md +152 -0
  137. package/skills/hyperframes-animation/SKILL.md +82 -0
  138. package/skills/hyperframes-cli/SKILL.md +109 -0
  139. package/skills/hyperframes-core/SKILL.md +78 -0
  140. package/skills/hyperframes-creative/SKILL.md +68 -0
  141. package/skills/hyperframes-media/SKILL.md +97 -0
  142. package/skills/image-processing/SKILL.md +34 -0
  143. package/skills/image-to-code-skill/SKILL.md +1228 -0
  144. package/skills/imagegen-frontend-mobile/SKILL.md +1465 -0
  145. package/skills/imagegen-frontend-web/SKILL.md +987 -0
  146. package/skills/implement/SKILL.md +15 -0
  147. package/skills/init/SKILL.md +91 -0
  148. package/skills/internal-comms/SKILL.md +32 -0
  149. package/skills/json-transformation/SKILL.md +34 -0
  150. package/skills/keyboard-shortcuts/SKILL.md +34 -0
  151. package/skills/knowledge-base/SKILL.md +34 -0
  152. package/skills/knowledge-graph/SKILL.md +34 -0
  153. package/skills/kubernetes-deployment/SKILL.md +34 -0
  154. package/skills/language-translation/SKILL.md +34 -0
  155. package/skills/lark-approval/SKILL.md +56 -0
  156. package/skills/lark-base/SKILL.md +157 -0
  157. package/skills/lark-doc/SKILL.md +81 -0
  158. package/skills/lark-shared/SKILL.md +168 -0
  159. package/skills/lark-workflow-meeting-summary/SKILL.md +122 -0
  160. package/skills/linting-neostandard-eslint9/SKILL.md +64 -0
  161. package/skills/llm-chaining/SKILL.md +34 -0
  162. package/skills/localization-i18n/SKILL.md +34 -0
  163. package/skills/logging-best-practices/SKILL.md +34 -0
  164. package/skills/loop-me/SKILL.md +32 -0
  165. package/skills/machine-learning-pipeline/SKILL.md +34 -0
  166. package/skills/meeting-notes/SKILL.md +34 -0
  167. package/skills/meeting-scheduler/SKILL.md +34 -0
  168. package/skills/message-queues/SKILL.md +34 -0
  169. package/skills/message-summarization/SKILL.md +34 -0
  170. package/skills/microservices-architecture/SKILL.md +34 -0
  171. package/skills/microsoft-foundry/SKILL.md +262 -0
  172. package/skills/migrate-to-shoehorn/SKILL.md +118 -0
  173. package/skills/milestone-tracking/SKILL.md +34 -0
  174. package/skills/minimalist-skill/SKILL.md +85 -0
  175. package/skills/model-deployment/SKILL.md +34 -0
  176. package/skills/model-evaluation/SKILL.md +34 -0
  177. package/skills/monitoring-setup/SKILL.md +34 -0
  178. package/skills/monorepo-setup/SKILL.md +34 -0
  179. package/skills/motion-graphics/SKILL.md +170 -0
  180. package/skills/multi-agent-systems/SKILL.md +34 -0
  181. package/skills/music-to-video/SKILL.md +197 -0
  182. package/skills/network-troubleshooting/SKILL.md +34 -0
  183. package/skills/node/SKILL.md +94 -0
  184. package/skills/nodejs-core/SKILL.md +156 -0
  185. package/skills/note-organization/SKILL.md +34 -0
  186. package/skills/oauth/SKILL.md +186 -0
  187. package/skills/obsidian-vault/SKILL.md +59 -0
  188. package/skills/octocat/SKILL.md +93 -0
  189. package/skills/openclaw-secure-linux-cloud/SKILL.md +157 -0
  190. package/skills/opensource-guide-coach/SKILL.md +218 -0
  191. package/skills/output-skill/SKILL.md +49 -0
  192. package/skills/package-publishing/SKILL.md +34 -0
  193. package/skills/password-generator/SKILL.md +34 -0
  194. package/skills/pdf/SKILL.md +314 -0
  195. package/skills/pdf-processing/SKILL.md +34 -0
  196. package/skills/performance-optimization/SKILL.md +34 -0
  197. package/skills/pomodoro-timer/SKILL.md +34 -0
  198. package/skills/powershell-automation/SKILL.md +34 -0
  199. package/skills/pptx/SKILL.md +232 -0
  200. package/skills/pr-to-video/SKILL.md +235 -0
  201. package/skills/priority-filtering/SKILL.md +34 -0
  202. package/skills/product-launch-video/SKILL.md +205 -0
  203. package/skills/project-tracking/SKILL.md +34 -0
  204. package/skills/prompt-compression/SKILL.md +34 -0
  205. package/skills/prompt-engineering/SKILL.md +34 -0
  206. package/skills/push-notifications/SKILL.md +34 -0
  207. package/skills/python-appservice-deploy/SKILL.md +36 -0
  208. package/skills/qa/SKILL.md +130 -0
  209. package/skills/rag-implementation/SKILL.md +34 -0
  210. package/skills/rate-limiting/SKILL.md +34 -0
  211. package/skills/react-best-practices/SKILL.md +149 -0
  212. package/skills/react-native-skills/SKILL.md +121 -0
  213. package/skills/react-view-transitions/SKILL.md +320 -0
  214. package/skills/readme-i18n/SKILL.md +176 -0
  215. package/skills/real-time-communication/SKILL.md +34 -0
  216. package/skills/redesign-skill/SKILL.md +178 -0
  217. package/skills/refactoring-strategy/SKILL.md +34 -0
  218. package/skills/regex-mastery/SKILL.md +34 -0
  219. package/skills/remotion/SKILL.md +364 -0
  220. package/skills/report-generation/SKILL.md +34 -0
  221. package/skills/request-refactor-plan/SKILL.md +68 -0
  222. package/skills/research-compiler/SKILL.md +34 -0
  223. package/skills/resolving-merge-conflicts/SKILL.md +14 -0
  224. package/skills/responsive-design/SKILL.md +34 -0
  225. package/skills/rest-api-patterns/SKILL.md +34 -0
  226. package/skills/retrospectives/SKILL.md +34 -0
  227. package/skills/risk-assessment/SKILL.md +34 -0
  228. package/skills/roadmap-creation/SKILL.md +34 -0
  229. package/skills/running-claude-code-via-litellm-copilot/SKILL.md +263 -0
  230. package/skills/scaffold-exercises/SKILL.md +106 -0
  231. package/skills/search-implementation/SKILL.md +34 -0
  232. package/skills/secrets-management/SKILL.md +34 -0
  233. package/skills/secure-linux-web-hosting/SKILL.md +162 -0
  234. package/skills/security-audit/SKILL.md +34 -0
  235. package/skills/selective-memory/SKILL.md +34 -0
  236. package/skills/semantic-search/SKILL.md +34 -0
  237. package/skills/semantic-versioning/SKILL.md +34 -0
  238. package/skills/sentiment-analysis/SKILL.md +34 -0
  239. package/skills/seo-optimization/SKILL.md +34 -0
  240. package/skills/setup-pre-commit/SKILL.md +91 -0
  241. package/skills/shadcn/SKILL.md +267 -0
  242. package/skills/simple/SKILL.md +52 -0
  243. package/skills/skill-creator/SKILL.md +485 -0
  244. package/skills/skill-optimizer/SKILL.md +47 -0
  245. package/skills/skills-cli/SKILL.md +281 -0
  246. package/skills/slack-gif-creator/SKILL.md +254 -0
  247. package/skills/snipgrapher/SKILL.md +58 -0
  248. package/skills/snippet-manager/SKILL.md +34 -0
  249. package/skills/soft-skill/SKILL.md +98 -0
  250. package/skills/sprint-planning/SKILL.md +34 -0
  251. package/skills/sql-query-optimization/SKILL.md +34 -0
  252. package/skills/stakeholder-communication/SKILL.md +34 -0
  253. package/skills/state-management/SKILL.md +34 -0
  254. package/skills/statistical-analysis/SKILL.md +34 -0
  255. package/skills/stitch-skill/SKILL.md +184 -0
  256. package/skills/streaming-responses/SKILL.md +34 -0
  257. package/skills/structured-output/SKILL.md +34 -0
  258. package/skills/summarization-techniques/SKILL.md +34 -0
  259. package/skills/supabase/SKILL.md +135 -0
  260. package/skills/supabase-postgres-best-practices/SKILL.md +64 -0
  261. package/skills/system-diagnostics/SKILL.md +34 -0
  262. package/skills/systematic-debugging/SKILL.md +296 -0
  263. package/skills/talking-head-recut/SKILL.md +1191 -0
  264. package/skills/task-decomposition/SKILL.md +34 -0
  265. package/skills/task-prioritization/SKILL.md +34 -0
  266. package/skills/taste-skill/SKILL.md +1206 -0
  267. package/skills/taste-skill-v1/SKILL.md +226 -0
  268. package/skills/tdd/SKILL.md +108 -0
  269. package/skills/teach/SKILL.md +140 -0
  270. package/skills/template-library/SKILL.md +34 -0
  271. package/skills/test-driven-development/SKILL.md +371 -0
  272. package/skills/test-generation/SKILL.md +34 -0
  273. package/skills/testing-strategy/SKILL.md +34 -0
  274. package/skills/text-expansion/SKILL.md +34 -0
  275. package/skills/theme-factory/SKILL.md +59 -0
  276. package/skills/time-blocking/SKILL.md +34 -0
  277. package/skills/to-prd/SKILL.md +75 -0
  278. package/skills/token-budgeting/SKILL.md +34 -0
  279. package/skills/token-optimization/SKILL.md +34 -0
  280. package/skills/tool-calling-patterns/SKILL.md +34 -0
  281. package/skills/typescript-magician/SKILL.md +117 -0
  282. package/skills/tzst/SKILL.md +68 -0
  283. package/skills/ubiquitous-language/SKILL.md +93 -0
  284. package/skills/use-my-browser/SKILL.md +110 -0
  285. package/skills/using-superpowers/SKILL.md +121 -0
  286. package/skills/vector-database-setup/SKILL.md +34 -0
  287. package/skills/vercel-cli-with-tokens/SKILL.md +353 -0
  288. package/skills/vercel-optimize/SKILL.md +322 -0
  289. package/skills/video-editing/SKILL.md +34 -0
  290. package/skills/viral-instagram-reels/SKILL.md +180 -0
  291. package/skills/viral-short-form/SKILL.md +147 -0
  292. package/skills/viral-short-form-ideas/SKILL.md +184 -0
  293. package/skills/viral-tiktok-content/SKILL.md +180 -0
  294. package/skills/visualization-creation/SKILL.md +34 -0
  295. package/skills/web-artifacts-builder/SKILL.md +74 -0
  296. package/skills/web-design-guidelines/SKILL.md +39 -0
  297. package/skills/web-scraping/SKILL.md +34 -0
  298. package/skills/webapp-testing/SKILL.md +96 -0
  299. package/skills/webhook-handling/SKILL.md +34 -0
  300. package/skills/website-to-video/SKILL.md +145 -0
  301. package/skills/weekly-review/SKILL.md +34 -0
  302. package/skills/workflow-automation/SKILL.md +34 -0
  303. package/skills/writing-beats/SKILL.md +67 -0
  304. package/skills/writing-fragments/SKILL.md +79 -0
  305. package/skills/writing-great-skills/SKILL.md +82 -0
  306. package/skills/writing-guidelines/SKILL.md +39 -0
  307. package/skills/writing-plans/SKILL.md +174 -0
  308. package/skills/writing-shape/SKILL.md +79 -0
  309. package/skills/xdrop/SKILL.md +78 -0
  310. package/skills/xget/SKILL.md +87 -0
  311. package/skills/xlsx/SKILL.md +292 -0
  312. package/src/commands/code_v5.js +377 -73
  313. package/src/commands/repl.js +505 -86
  314. package/src/providers/model/anthropic.js +84 -0
  315. package/src/providers/model/gemini.js +49 -0
  316. package/src/providers/model/minimax.js +48 -0
  317. package/src/providers/model/ollama.js +42 -0
  318. package/src/providers/model/openai.js +49 -0
  319. package/src/providers/search/duckduckgo.js +45 -0
  320. package/src/providers/search/exa.js +52 -0
  321. package/src/providers/search/searxng.js +51 -0
  322. package/src/providers/search/tavily.js +47 -0
  323. package/src/tools/model_provider.js +71 -0
  324. package/src/tools/parallel_search.js +40 -49
  325. package/src/tools/search_provider.js +79 -0
  326. package/src/tools/skills_download.js +217 -0
  327. package/src/tools/web_search.js +42 -62
  328. package/src/tools/workflow.js +21 -9
  329. package/src/utils/cron.js +82 -126
  330. package/src/utils/effort-levels.js +42 -0
  331. package/src/utils/fallback-chain.js +72 -0
  332. package/src/utils/file-history.js +78 -0
  333. package/src/utils/model-provider.js +113 -0
  334. package/src/utils/permissions.js +147 -0
  335. package/src/utils/plan-mode.js +164 -0
  336. package/src/utils/provider-detect.js +7 -32
  337. package/src/utils/sandbox.js +60 -0
  338. package/src/utils/search-provider.js +62 -0
  339. package/src/utils/session-search.js +66 -0
  340. package/src/utils/structured-output.js +20 -0
  341. package/src/utils/system-prompt.js +28 -2
  342. package/src/utils/tasks.js +132 -0
  343. package/src/utils/tool-hooks.js +154 -0
  344. package/src/utils/tools.js +18 -2
  345. package/src/utils/ultra-review.js +59 -0
  346. package/src/utils/worktree.js +192 -0
@@ -0,0 +1,79 @@
1
+ const loadConfig = () => {
2
+ try { return JSON.parse(require('fs').readFileSync(require('path').join(require('os').homedir(), '.natureco', 'config.json'), 'utf8')); } catch { return {}; }
3
+ };
4
+
5
+ require('../providers/search/tavily');
6
+ require('../providers/search/duckduckgo');
7
+ require('../providers/search/searxng');
8
+ require('../providers/search/exa');
9
+
10
+ const name = 'search_provider';
11
+ const description = 'Unified search backend with pluggable providers. search/status/switch/list. Supports Tavily, DuckDuckGo, SearXNG, Exa. Switch via NATURECO_SEARCH_PROVIDER env or config.searchProvider. Default: tavily (falls back to others if no API key).';
12
+ const parameters = {
13
+ type: 'object',
14
+ properties: {
15
+ action: {
16
+ type: 'string',
17
+ enum: ['search', 'status', 'list', 'switch'],
18
+ description: 'Operation: search, status, list, or switch',
19
+ },
20
+ query: { type: 'string', description: '(search) Search query' },
21
+ maxResults: { type: 'number', description: '(search) Max results (default: 5)' },
22
+ provider: { type: 'string', description: '(search/switch) Provider name to use or switch to' },
23
+ },
24
+ required: ['action'],
25
+ };
26
+
27
+ async function execute(params) {
28
+ const cfg = loadConfig();
29
+ const { getActiveProvider, getProviderNames, resolveProviderConfig, getProvider } = require('../utils/search-provider');
30
+
31
+ switch (params.action) {
32
+ case 'search': {
33
+ if (!params.query) return { success: false, error: 'query gerekli' };
34
+ const providerName = params.provider || process.env.NATURECO_SEARCH_PROVIDER || cfg.searchProvider;
35
+ let Provider;
36
+ if (providerName) Provider = getProvider(providerName);
37
+ if (!Provider) Provider = getActiveProvider(cfg);
38
+ const provider = new Provider(cfg);
39
+ return provider.search(params.query, { maxResults: params.maxResults || 5 });
40
+ }
41
+
42
+ case 'status': {
43
+ const active = resolveProviderConfig(cfg);
44
+ const avail = getProviderNames().sort();
45
+ return {
46
+ active,
47
+ available: avail,
48
+ config: cfg.searchProvider || '(not set, using default)',
49
+ env: process.env.NATURECO_SEARCH_PROVIDER || '(not set)',
50
+ default: 'tavily',
51
+ };
52
+ }
53
+
54
+ case 'list': {
55
+ const avail = getProviderNames().sort();
56
+ return {
57
+ success: true,
58
+ providers: avail.map(name => {
59
+ const Provider = getProvider(name);
60
+ const inst = new Provider(cfg);
61
+ const hasKey = name === 'duckduckgo' || name === 'searxng' || !!(cfg[name + 'ApiKey'] || process.env[name.toUpperCase() + '_API_KEY']);
62
+ return { name, available: hasKey };
63
+ }),
64
+ };
65
+ }
66
+
67
+ case 'switch': {
68
+ if (!params.provider) return { success: false, error: 'provider (name) gerekli' };
69
+ const { setConfigValue } = require('../utils/config');
70
+ setConfigValue('searchProvider', params.provider);
71
+ return { success: true, message: `Search provider switched to: ${params.provider}` };
72
+ }
73
+
74
+ default:
75
+ return { success: false, error: `Unknown action: ${params.action}` };
76
+ }
77
+ }
78
+
79
+ module.exports = { name, description, parameters, execute };
@@ -0,0 +1,217 @@
1
+ /**
2
+ * skills_download — Download skills from skills.sh ecosystem or GitHub repos
3
+ *
4
+ * Bulk-imports Agent Skills from the open ecosystem into natureco's skill system.
5
+ * Skills are SKILL.md files following the Agent Skills standard (agentskills.io).
6
+ *
7
+ * Sources:
8
+ * - GitHub repos (anthropics/skills, vercel-labs/agent-skills, etc.)
9
+ * - skills.sh registry
10
+ * - Direct SKILL.md URLs
11
+ */
12
+
13
+ const https = require('https');
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+ const os = require('os');
17
+
18
+ const BUILTIN_SKILLS_DIR = path.join(__dirname, '..', '..', 'skills');
19
+ const USER_SKILLS_DIR = path.join(os.homedir(), '.natureco', 'skills');
20
+
21
+ // Known skill repos with high-quality skills
22
+ const KNOWN_REPOS = [
23
+ { owner: 'anthropics', repo: 'skills', topic: 'general' },
24
+ { owner: 'mattpocock', repo: 'skills', topic: 'typescript' },
25
+ { owner: 'vercel-labs', repo: 'agent-skills', topic: 'vercel' },
26
+ { owner: 'supabase', repo: 'agent-skills', topic: 'database' },
27
+ { owner: 'xixu-me', repo: 'skills', topic: 'devops' },
28
+ { owner: 'microsoft', repo: 'azure-skills', topic: 'cloud' },
29
+ { owner: 'shadcn', repo: 'ui', topic: 'design' },
30
+ { owner: 'nrwl', repo: 'nx-ai-agents-config', topic: 'nx' },
31
+ { owner: 'remotion-dev', repo: 'skills', topic: 'video' },
32
+ { owner: 'mcollina', repo: 'skills', topic: 'nodejs' },
33
+ { owner: 'spillwavesolutions', repo: 'design-doc-mermaid', topic: 'design' },
34
+ { owner: 'nextlevelbuilder', repo: 'ui-ux-pro-max-skill', topic: 'design' },
35
+ { owner: 'browser-act', repo: 'skills', topic: 'browser' },
36
+ { owner: 'obra', repo: 'superpowers', topic: 'workflow' },
37
+ ];
38
+
39
+ function httpsGet(url) {
40
+ return new Promise((resolve, reject) => {
41
+ https.get(url, { timeout: 15000 }, (res) => {
42
+ let data = '';
43
+ res.on('data', c => data += c);
44
+ res.on('end', () => resolve(data));
45
+ }).on('error', reject).on('timeout', function() { this.destroy(); reject(new Error('Timeout')); });
46
+ });
47
+ }
48
+
49
+ function getGithubContentsUrl(owner, repo, path) {
50
+ return `https://api.github.com/repos/${owner}/${repo}/contents/${path}`;
51
+ }
52
+
53
+ async function listRepos() {
54
+ return KNOWN_REPOS.map(r => ({
55
+ id: `${r.owner}/${r.repo}`,
56
+ owner: r.owner,
57
+ repo: r.repo,
58
+ topic: r.topic,
59
+ }));
60
+ }
61
+
62
+ function parseFrontmatter(content) {
63
+ const m = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
64
+ if (!m) return { metadata: {}, body: content };
65
+ const fm = {};
66
+ for (const line of m[1].split('\n')) {
67
+ const kv = line.match(/^(\w+):\s*(.+)$/);
68
+ if (kv) fm[kv[1]] = kv[2].replace(/^["']|["']$/g, '');
69
+ }
70
+ return { metadata: fm, body: (m[2] || '').trim() };
71
+ }
72
+
73
+ async function fetchGithubRepo(owner, repo) {
74
+ // Use GitHub API to list contents of /skills directory
75
+ const url = `https://api.github.com/repos/${owner}/${repo}/git/trees/HEAD?recursive=1`;
76
+ const data = await httpsGet(url, { headers: { 'User-Agent': 'natureco-cli', 'Accept': 'application/vnd.github.v3+json' } });
77
+ const tree = JSON.parse(data).tree || [];
78
+
79
+ // Find all SKILL.md files
80
+ const skillFiles = tree.filter(f => f.path.endsWith('SKILL.md'));
81
+ const skills = [];
82
+
83
+ for (const file of skillFiles) {
84
+ const skillDir = path.dirname(file.path);
85
+ const skillName = path.basename(skillDir);
86
+
87
+ // Fetch SKILL.md content
88
+ const rawUrl = `https://raw.githubusercontent.com/${owner}/${repo}/main/${file.path}`;
89
+ let content;
90
+ try {
91
+ content = await httpsGet(rawUrl);
92
+ } catch { continue; }
93
+
94
+ const { metadata, body } = parseFrontmatter(content);
95
+ const name = metadata.name || skillName;
96
+ const description = metadata.description || '';
97
+
98
+ // Find additional files in the skill directory
99
+ const additionalFiles = tree
100
+ .filter(f => f.path.startsWith(skillDir + '/') && f.path !== file.path)
101
+ .map(f => ({ path: f.path.replace(skillDir + '/', ''), url: `https://raw.githubusercontent.com/${owner}/${repo}/main/${f.path}` }));
102
+
103
+ skills.push({
104
+ name,
105
+ description: description.length > 200 ? description.slice(0, 200) + '...' : description,
106
+ fullDescription: description,
107
+ content: body,
108
+ source: `${owner}/${repo}/${skillDir}`,
109
+ metadata,
110
+ additionalFiles,
111
+ });
112
+ }
113
+
114
+ return skills;
115
+ }
116
+
117
+ async function downloadSkill(skill, targetDir) {
118
+ const skillDir = path.join(targetDir, skill.name);
119
+ if (fs.existsSync(skillDir)) {
120
+ return { success: false, error: 'Already exists', path: skillDir };
121
+ }
122
+
123
+ fs.mkdirSync(skillDir, { recursive: true });
124
+
125
+ // Write SKILL.md
126
+ const frontmatter = [
127
+ '---',
128
+ `name: ${skill.name}`,
129
+ `description: ${skill.description}`,
130
+ skill.metadata.license ? `license: ${skill.metadata.license}` : null,
131
+ skill.source ? `metadata:\n source: ${skill.source}` : null,
132
+ '---',
133
+ '',
134
+ skill.content,
135
+ ].filter(Boolean).join('\n');
136
+
137
+ fs.writeFileSync(path.join(skillDir, 'SKILL.md'), frontmatter, 'utf8');
138
+
139
+ // Download additional files
140
+ for (const af of (skill.additionalFiles || [])) {
141
+ try {
142
+ const data = await httpsGet(af.url);
143
+ const afDir = path.dirname(path.join(skillDir, af.path));
144
+ fs.mkdirSync(afDir, { recursive: true });
145
+ fs.writeFileSync(path.join(skillDir, af.path), data, 'utf8');
146
+ } catch {}
147
+ }
148
+
149
+ return { success: true, path: skillDir, name: skill.name };
150
+ }
151
+
152
+ async function execute(params) {
153
+ const { action, source, name, target } = params;
154
+ const targetDir = target === 'user' ? USER_SKILLS_DIR : BUILTIN_SKILLS_DIR;
155
+
156
+ if (action === 'list_sources') {
157
+ const repos = await listRepos();
158
+ return JSON.stringify({ success: true, sources: repos });
159
+ }
160
+
161
+ if (action === 'list_skills') {
162
+ const [owner, repo] = (source || '').split('/');
163
+ if (!owner || !repo) return JSON.stringify({ success: false, error: 'source must be owner/repo (e.g. anthropics/skills)' });
164
+ const skills = await fetchGithubRepo(owner, repo);
165
+ return JSON.stringify({ success: true, source, count: skills.length, skills: skills.map(s => ({ name: s.name, description: s.description })) });
166
+ }
167
+
168
+ if (action === 'download') {
169
+ const [owner, repo] = (source || '').split('/');
170
+ if (!owner || !repo) return JSON.stringify({ success: false, error: 'source must be owner/repo' });
171
+ const skills = await fetchGithubRepo(owner, repo);
172
+ const targetSkill = name ? skills.find(s => s.name === name) : null;
173
+ const toDownload = targetSkill ? [targetSkill] : skills;
174
+ const results = [];
175
+ for (const skill of toDownload) {
176
+ const result = await downloadSkill(skill, targetDir);
177
+ results.push({ name: skill.name, ...result });
178
+ }
179
+ const succeeded = results.filter(r => r.success).length;
180
+ return JSON.stringify({ success: true, source, total: results.length, succeeded, failed: results.length - succeeded, results });
181
+ }
182
+
183
+ if (action === 'download_all') {
184
+ const repos = await listRepos();
185
+ const allResults = [];
186
+ for (const repo of repos) {
187
+ try {
188
+ const skills = await fetchGithubRepo(repo.owner, repo.repo);
189
+ for (const skill of skills) {
190
+ const result = await downloadSkill(skill, targetDir);
191
+ allResults.push({ repo: repo.id, name: skill.name, ...result });
192
+ }
193
+ } catch (e) {
194
+ allResults.push({ repo: repo.id, error: e.message });
195
+ }
196
+ }
197
+ const succeeded = allResults.filter(r => r.success).length;
198
+ return JSON.stringify({ success: true, total: allResults.length, succeeded, failed: allResults.length - succeeded, results: allResults });
199
+ }
200
+
201
+ return JSON.stringify({ success: false, error: 'Unknown action. Use: list_sources, list_skills, download, download_all' });
202
+ }
203
+
204
+ const name = 'skills_download';
205
+ const description = 'Download skills from skills.sh ecosystem or GitHub repos. Bulk-import Agent Skills from anthropics/skills, vercel-labs/agent-skills, supabase/agent-skills and more. Actions: list_sources, list_skills, download, download_all.';
206
+ const parameters = {
207
+ type: 'object',
208
+ properties: {
209
+ action: { type: 'string', enum: ['list_sources', 'list_skills', 'download', 'download_all'] },
210
+ source: { type: 'string', description: 'Source repo in owner/repo format (e.g. anthropics/skills)' },
211
+ name: { type: 'string', description: 'Specific skill name to download (optional, downloads all if not set)' },
212
+ target: { type: 'string', enum: ['builtin', 'user'], description: 'Target directory: builtin (project) or user (~/.natureco)' },
213
+ },
214
+ required: ['action'],
215
+ };
216
+
217
+ module.exports = { name, description, parameters, execute };
@@ -1,82 +1,62 @@
1
1
  const { getConfig } = require('../utils/config');
2
+ const { getActiveProvider, getProviderNames, DEFAULT_PROVIDER } = require('../utils/search-provider');
3
+ require('../providers/search/tavily');
4
+ require('../providers/search/duckduckgo');
5
+ require('../providers/search/searxng');
6
+ require('../providers/search/exa');
2
7
 
3
8
  module.exports = {
4
9
  name: 'web_search',
5
- description: 'Search the web for current information using Tavily',
10
+ description: 'Search the web for current information using the configured search provider (Tavily, DuckDuckGo, SearXNG, Exa). Switch via NATURECO_SEARCH_PROVIDER env or config.searchProvider.',
6
11
  inputSchema: {
7
12
  type: 'object',
8
13
  properties: {
9
- query: {
10
- type: 'string',
11
- description: 'Search query'
12
- }
14
+ query: { type: 'string', description: 'Search query' },
15
+ maxResults: { type: 'number', description: 'Maximum results (default: 5)' },
16
+ provider: { type: 'string', description: 'Override provider: tavily, duckduckgo, searxng, exa (default: configured or tavily)' },
13
17
  },
14
18
  required: ['query']
15
19
  },
16
-
20
+
17
21
  async execute(params) {
18
22
  try {
19
23
  const config = getConfig();
20
- const apiKey = config.tavilyApiKey || process.env.TAVILY_API_KEY;
21
-
22
- if (!apiKey) {
23
- return {
24
- success: false,
25
- error: 'Tavily API key gerekli. Kur: natureco config set tavilyApiKey tvly_xxx\nÜcretsiz key: https://tavily.com'
26
- };
27
- }
28
-
29
- const response = await fetch('https://api.tavily.com/search', {
30
- method: 'POST',
31
- headers: { 'Content-Type': 'application/json' },
32
- body: JSON.stringify({
33
- api_key: apiKey,
34
- query: params.query,
35
- search_depth: 'basic',
36
- max_results: 5
37
- })
38
- });
39
-
40
- if (!response.ok) {
41
- return {
42
- success: false,
43
- error: `Tavily API error: ${response.status} ${response.statusText}`
44
- };
24
+ const providerName = params.provider || process.env.NATURECO_SEARCH_PROVIDER || config.searchProvider;
25
+ let Provider;
26
+
27
+ if (providerName) {
28
+ const { getProvider } = require('../utils/search-provider');
29
+ Provider = getProvider(providerName);
45
30
  }
46
-
47
- const data = await response.json();
48
-
49
- if (data.error) {
50
- return {
51
- success: false,
52
- error: data.error
53
- };
31
+ if (!Provider) {
32
+ Provider = getActiveProvider(config);
54
33
  }
55
-
56
- if (!data.results || data.results.length === 0) {
57
- return {
58
- success: true,
59
- message: 'Sonuç bulunamadı',
60
- query: params.query,
61
- results: []
62
- };
34
+
35
+ const provider = new Provider(config);
36
+ const result = await provider.search(params.query, {
37
+ maxResults: params.maxResults || 5,
38
+ });
39
+
40
+ if (!result.success && providerName && !params.provider) {
41
+ const allProviders = getProviderNames();
42
+ for (const name of allProviders) {
43
+ if (name === providerName) continue;
44
+ const { getProvider } = require('../utils/search-provider');
45
+ const FallbackProvider = getProvider(name);
46
+ if (!FallbackProvider) continue;
47
+ const fallback = new FallbackProvider(config);
48
+ const fallbackResult = await fallback.search(params.query, { maxResults: params.maxResults || 5 });
49
+ if (fallbackResult.success) {
50
+ fallbackResult.fallback = true;
51
+ fallbackResult.fallbackReason = result.error;
52
+ return fallbackResult;
53
+ }
54
+ }
63
55
  }
64
-
65
- return {
66
- success: true,
67
- query: params.query,
68
- results: data.results.map(r => ({
69
- title: r.title,
70
- snippet: r.content,
71
- url: r.url
72
- })),
73
- count: data.results.length
74
- };
56
+
57
+ return result;
75
58
  } catch (error) {
76
- return {
77
- success: false,
78
- error: error.message
79
- };
59
+ return { success: false, error: error.message };
80
60
  }
81
61
  }
82
62
  };
@@ -6,6 +6,8 @@ const os = require('os');
6
6
  const WORKFLOW_DIR = path.join(os.homedir(), '.natureco', 'workflows');
7
7
  const WORKFLOW_HISTORY = path.join(os.homedir(), '.natureco', 'workflow-history.json');
8
8
 
9
+ const { buildSkillIndex } = require('../utils/skill-index');
10
+
9
11
  function ensureDir(dir) { try { fs.mkdirSync(dir, { recursive: true }); } catch {} }
10
12
  function loadConfig() {
11
13
  try { return JSON.parse(fs.readFileSync(path.join(os.homedir(), '.natureco', 'config.json'), 'utf8')); } catch { return {}; }
@@ -94,6 +96,8 @@ async function workflow(params) {
94
96
  return { success: false, error: 'Provider ayarli degil. Once: natureco setup' };
95
97
  }
96
98
 
99
+ const skillsIndexBlock = buildSkillIndex();
100
+
97
101
  // ── RUN: Execute a complete workflow ──────────────────────────────────
98
102
  if (action === 'run') {
99
103
  if (!task) return { success: false, error: 'task gerekli' };
@@ -114,7 +118,7 @@ async function workflow(params) {
114
118
  if (isSimple) {
115
119
  // Passthrough: just chat with LLM, no tools — include user memory
116
120
  const memCtx = memoryContext();
117
- const sysMsg = 'Sen yardimci bir asistansin. Kisa ve oz yanit ver.' + (memCtx ? '\n\nKullanici bilgisi:\n' + memCtx : '');
121
+ const sysMsg = 'Sen yardimci bir asistansin. Kisa ve oz yanit ver.' + (memCtx ? '\n\nKullanici bilgisi:\n' + memCtx : '') + '\n\n' + skillsIndexBlock;
118
122
  const chatBody = { model, stream: false, messages: [{ role: 'system', content: sysMsg }, { role: 'user', content: task }], temperature: 0.7, max_tokens: 1000 };
119
123
  try {
120
124
  const chatResult = await apiCall(providerUrl, providerApiKey, chatBody);
@@ -127,12 +131,13 @@ async function workflow(params) {
127
131
 
128
132
  // Phase 1: LLM plans the workflow
129
133
  const memCtx = memoryContext();
130
- const planPrompt = {
131
- role: 'system',
132
- content: 'Sen bir workflow planlama asistanisin. Verilen gorev icin hangi tool\'larin kullanilacagini ve hangi sirayla calisacagini belirle. SADECE JSON formatinda yanit ver, baska bir sey yazma.\n\nKullanilabilir tool\'lar:\n' +
133
- tools.map(t => '- ' + t).join('\n') +
134
- (memCtx ? '\n\nKullanici bilgisi:\n' + memCtx : '') +
135
- '\n\nJSON format:\n{\n "workflowName": "...",\n "description": "...",\n "steps": [\n { "step": 1, "tool": "tool_name", "purpose": "...", "params": { ... } }\n ]\n}\n\nHer adim icin params kismina tool\'un gerektirdigi parametreleri ekle. Adimlar birbirine bagimli olabilir, onceki adimin outputu sonraki adimin inputu olarak kullanilabilir.'
134
+ const planPrompt = {
135
+ role: 'system',
136
+ content: 'Sen bir workflow planlama asistanisin. Verilen gorev icin hangi tool\'larin kullanilacagini ve hangi sirayla calisacagini belirle. SADECE JSON formatinda yanit ver, baska bir sey yazma.\n\nKullanilabilir tool\'lar:\n' +
137
+ tools.map(t => '- ' + t).join('\n') +
138
+ '\n\nKullanilabilir skill\'ler (gorevle ilgili skill varsa plana skill_view adimi olarak ekle):\n' + skillsIndexBlock +
139
+ (memCtx ? '\n\nKullanici bilgisi:\n' + memCtx : '') +
140
+ '\n\nJSON format:\n{\n "workflowName": "...",\n "description": "...",\n "skillsLoaded": ["..."],\n "steps": [\n { "step": 1, "tool": "tool_name", "purpose": "...", "params": { ... } }\n ]\n}\n\nHer adim icin params kismina tool\'un gerektirdigi parametreleri ekle. Adimlar birbirine bagimli olabilir, onceki adimin outputu sonraki adimin inputu olarak kullanilabilir.\n\nGorevle ilgili skill varsa ILK adim olarak skill_view ile yukle, ardindan diger adimlara gec.'
136
141
  };
137
142
  const planBody = {
138
143
  model, stream: false,
@@ -203,7 +208,8 @@ async function workflow(params) {
203
208
  role: 'system',
204
209
  content: 'Bir sonraki adimi calistiriyorsun. Sana verilen tool\'u ve parametreleri kullanarak islemi gerceklestir. Tool cagrisini dogru formatta yap.\n\nTool: ' + step.tool + '\nAmac: ' + (step.purpose || '') + '\nPlanlanan parametreler: ' + JSON.stringify(step.params || {}) +
205
210
  '\n\nOnceki adim sonuclari:\n' + stepResults.map(r => 'Adim ' + r.step + ' (' + r.tool + '): ' + (r.status === 'done' ? JSON.stringify(r.result).slice(0, 300) : r.status)).join('\n') +
206
- '\n\nTek bir tool cagrisi yap ve sonucu bekle. Tool cagrisi yaparken Onceki adim sonuclarindaki gerekli verileri parametre olarak kullan.'
211
+ '\n\nKullanilabilir skill\'ler:\n' + skillsIndexBlock +
212
+ '\n\nTek bir tool cagrisi yap ve sonucu bekle. Tool cagrisi yaparken Onceki adim sonuclarindaki gerekli verileri parametre olarak kullan. Ilgili skill varsa once skill_view ile yukle, sonra asil tool\'u cagir.'
207
213
  };
208
214
  const executeBody = {
209
215
  model, stream: false,
@@ -251,6 +257,10 @@ async function workflow(params) {
251
257
  history.unshift({ id: wfId, name: plan.workflowName || task.slice(0, 50), task, status: wfEntry.status, steps: plan.steps.length, completedAt: wfEntry.completedAt });
252
258
  fs.writeFileSync(WORKFLOW_HISTORY, JSON.stringify(history.slice(0, 50), null, 2));
253
259
 
260
+ const skillsLoaded = stepResults
261
+ .filter(r => r.tool === 'skill_view' && r.status === 'done')
262
+ .map(r => r.args?.name || 'bilinmeyen-skill');
263
+
254
264
  return {
255
265
  success: true,
256
266
  workflowId: wfId,
@@ -260,6 +270,7 @@ async function workflow(params) {
260
270
  completedSteps: stepResults.filter(r => r.status === 'done').length,
261
271
  failedSteps: stepResults.filter(r => r.status === 'error' || r.status === 'skipped').length,
262
272
  status: wfEntry.status,
273
+ skillsLoaded: skillsLoaded.length > 0 ? skillsLoaded : undefined,
263
274
  plan: plan.steps.map(s => ({ step: s.step, tool: s.tool, purpose: s.purpose })),
264
275
  results: stepResults.map(r => ({
265
276
  step: r.step, tool: r.tool, status: r.status,
@@ -276,7 +287,8 @@ async function workflow(params) {
276
287
  const planPrompt = {
277
288
  role: 'system',
278
289
  content: 'Kullanilabilir tool\'lar:\n' + tools.map(t => '- ' + t).join('\n') +
279
- '\n\nGorev icin bir workflow plani JSON formatinda olustur. JSON disinda hicbir sey yazma.\nFormat: { "workflowName": "...", "description": "...", "estimatedSteps": N, "steps": [{ "step": 1, "tool": "...", "purpose": "...", "params": {...}, "expectedOutput": "..." }] }'
290
+ '\n\nKullanilabilir skill\'ler:\n' + skillsIndexBlock +
291
+ '\n\nGorev icin bir workflow plani JSON formatinda olustur. JSON disinda hicbir sey yazma.\nFormat: { "workflowName": "...", "description": "...", "estimatedSteps": N, "skillsLoaded": ["..."], "steps": [{ "step": 1, "tool": "...", "purpose": "...", "params": {...}, "expectedOutput": "..." }] }\n\nGorevle ilgili skill varsa plana skill_view adimi olarak ekle.'
280
292
  };
281
293
  const planBody = {
282
294
  model, stream: false,